<?xml version="1.0" encoding="UTF-8"?>
<!-- generator="wordpress/2.2" -->
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	>

<channel>
	<title>Caloni.com.br</title>
	<link>http://www.caloni.com.br/blog</link>
	<description>C++, Windows, Programação, Depuração e Transpiração</description>
	<pubDate>Thu, 24 Jul 2008 11:26:41 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.2</generator>
	<language>en</language>
			<item>
		<title>Entrevista com o Caloni no &#8220;Do ZERO ao MESTRE&#8221;</title>
		<link>http://www.caloni.com.br/blog/archives/entrevista-com-o-caloni-no-do-zero-ao-mestre</link>
		<comments>http://www.caloni.com.br/blog/archives/entrevista-com-o-caloni-no-do-zero-ao-mestre#comments</comments>
		<pubDate>Thu, 24 Jul 2008 09:00:08 +0000</pubDate>
		<dc:creator>Wanderley Caloni</dc:creator>
		
		<category><![CDATA[Sites]]></category>

		<guid isPermaLink="false">http://www.caloni.com.br/blog/archives/entrevista-com-o-caloni-no-do-zero-ao-mestre</guid>
		<description><![CDATA[Há muito pouco tempo atrás surgiu um blogue de um programador com o desejo de aprender C++ em seis meses. Ele entrou em contato comigo para divulgar seu trabalho, e lhe disse que na internet seu trabalho se divulga por si só. E é verdade. No entanto, não contente, ele me pediu para responder um [...]]]></description>
			<content:encoded><![CDATA[<p>Há muito pouco tempo atrás surgiu um blogue de um programador com o desejo de aprender C++ em seis meses. Ele entrou em contato comigo para divulgar seu trabalho, e lhe disse que na internet seu trabalho se divulga por si só. E é verdade. No entanto, não contente, ele me pediu para responder um questionário no estilo entrevista. Não sei se o resultado foi satisfatório, mas pelo menos foi curioso. Foram perguntas simples e respostas mais simples ainda.</p>
<p>Para os que quiserem ler a entrevista e/ou acompanhar as desventuras de um programador com pressa, dê uma olhada no "<a href="http://dozeroaomestre.blogspot.com/2008/07/entrevista-wanderlei-caloni.html">Do ZERO ao MESTRE em 6 meses</a>", um blogue recém-nascido.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.caloni.com.br/blog/archives/entrevista-com-o-caloni-no-do-zero-ao-mestre/feed</wfw:commentRss>
		</item>
		<item>
		<title>Aprenda a usar sua API</title>
		<link>http://www.caloni.com.br/blog/archives/aprenda-a-usar-sua-api</link>
		<comments>http://www.caloni.com.br/blog/archives/aprenda-a-usar-sua-api#comments</comments>
		<pubDate>Tue, 22 Jul 2008 20:09:24 +0000</pubDate>
		<dc:creator>Wanderley Caloni</dc:creator>
		
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://www.caloni.com.br/blog/archives/aprenda-a-usar-sua-api</guid>
		<description><![CDATA[É conhecido que uma das desvantagens de se programar diretamente em Win32 API é a dificuldade de se entender os parâmetros e o retorno das funções. Concordo em parte. Constituída de boa documentação, parte da culpa dos programas mal-feitos reside na preguiça do programador em olhar a documentação por completo.
A Win32 API está longe de [...]]]></description>
			<content:encoded><![CDATA[<p>É conhecido que uma das desvantagens de se programar diretamente em Win32 API é a dificuldade de se entender os parâmetros e o retorno das funções. Concordo em parte. Constituída de <a href="http://msdn.microsoft.com">boa documentação</a>, parte da culpa dos programas mal-feitos reside na preguiça do programador em olhar a documentação por completo.</p>
<p>A Win32 API está longe de ser perfeita, mas pelo menos está razoavelmente documentada, e é na leitura atenta da documentação que iremos encontrar as respostas que precisamos para que o programa funcione.</p>
<p>Vejamos alguns exemplos.</p>
<h4>1. CreateFile</h4>
<p>O código abaixo parece bem razoável:</p>
<p><pre><span style="color: #006600;">#include &lt;windows.h&gt;</span>
&nbsp;
<span style="color: #0000ff;">int</span> main<span style="color: #000000; font-weight: bold;">&#40;</span><span style="color: #000000; font-weight: bold;">&#41;</span>
<span style="color: #000000; font-weight: bold;">&#123;</span>
	HANDLE hFile = CreateFile<span style="color: #000000; font-weight: bold;">&#40;</span><span style="color: #666666;">"c:<span style="color: #666666;">\\</span>tests<span style="color: #666666;">\\</span>myfile.txt"</span>, GENERIC_READ, 
		FILE_SHARE_READ, <span style="color: #000000;">NULL</span>, OPEN_EXISTING, <span style="color: #000000;">0</span>, <span style="color: #000000;">NULL</span><span style="color: #000000; font-weight: bold;">&#41;</span>;
&nbsp;
	<span style="color: #0000ff;">if</span><span style="color: #000000; font-weight: bold;">&#40;</span> hFile <span style="color: #000000; font-weight: bold;">&#41;</span>
	<span style="color: #000000; font-weight: bold;">&#123;</span>
		DWORD read = <span style="color: #000000;">0</span>;
		<span style="color: #0000ff;">CHAR</span> buffer<span style="color: #000000; font-weight: bold;">&#91;</span><span style="color: #000000;">100</span><span style="color: #000000; font-weight: bold;">&#93;</span>;
&nbsp;
		<span style="color: #0000ff;">if</span><span style="color: #000000; font-weight: bold;">&#40;</span> ReadFile<span style="color: #000000; font-weight: bold;">&#40;</span>hFile, buffer, <span style="color: #0000ff;">sizeof</span><span style="color: #000000; font-weight: bold;">&#40;</span>buffer<span style="color: #000000; font-weight: bold;">&#41;</span>, &amp;read, <span style="color: #000000;">NULL</span><span style="color: #000000; font-weight: bold;">&#41;</span> <span style="color: #000000; font-weight: bold;">&#41;</span>
		<span style="color: #000000; font-weight: bold;">&#123;</span>
			WriteBuffer<span style="color: #000000; font-weight: bold;">&#40;</span>buffer<span style="color: #000000; font-weight: bold;">&#41;</span>;
		<span style="color: #000000; font-weight: bold;">&#125;</span>
&nbsp;
		CloseHandle<span style="color: #000000; font-weight: bold;">&#40;</span>hFile<span style="color: #000000; font-weight: bold;">&#41;</span>;
	<span style="color: #000000; font-weight: bold;">&#125;</span>
<span style="color: #000000; font-weight: bold;">&#125;</span>
&nbsp;</pre></p>
<p>No entanto, está errado.</p>
<p>É fato que a maioria das funções que retornam <em>handles</em> retornam NULL para indicar o erro na tentativa de obter o recurso. Ao comparar o retorno com NULL, o programador geralmente faz uma chamada a <a href="http://msdn.microsoft.com/en-us/library/ms679360(VS.85).aspx">GetLastError</a> para saber o que aconteceu. No entanto, uma das funções mais usadas, a CreateFile, não retorna NULL, mas INVALID_HANDLE_VALUE.</p>
<p>Sendo assim, o código acima deveria ser:</p>
<pre>if( hFile != INVALID_HANDLE_VALUE )</pre>
<h4>2. GetVersion</h4>
<p>Taí uma função que muitos erraram. Erraram tanto que eles fizeram uma nova versão menos complicada. Como está escrito no <a href="http://msdn.microsoft.com/en-us/library/ms724439(VS.85).aspx">MSDN</a>:</p>
<blockquote><p>"<em>The GetVersionEx function was developed because many existing applications err when examining the packed DWORD value returned by GetVersion, transposing the major and minor version numbers.</em>"</p></blockquote>
<p>O motivo de tantos erro pode ter sido o fato que o valor retornado é uma estrutura de bits dentro de um DWORD, coisa que nem todos programadores C sabem lidar muito bem, e o fato de ser uma função muito utilizada por todos (pegar a versão do sistema operacional).</p>
<p>Eis a tabela de campos do retorno de GetVersion:</p>
<pre>Platform                                High-order bit   Next 7 bits     Low-order byte
-------------------------------------   --------------   ------------    --------------
Windows NT 3.51                         0                Build number    3
Windows NT 4.0                          0                Build number    4
Windows 2000 or Windows XP              0                Build number    5
Windows 95, Windows 98, or Windows Me   1                Reserved        4
Win32s with Windows 3.1                 1                Build number    3</pre>
<p>Mesmo que não seja tão difícil, pode ser ambíguo. Por exemplo, como saber se o Windows é 95, 98 ou ME?</p>
<p>O código abaixo, muito usado por todos que suportam ainda o Windows mais velhinhos, verifica se estamos rodando em plataforma NT ou 9x.</p>
<p><pre><span style="color: #006600;">#include &lt;windows.h&gt;</span>
<span style="color: #006600;">#include &lt;stdio.h&gt;</span>
&nbsp;
<span style="color: #0000ff;">int</span> main<span style="color: #000000; font-weight: bold;">&#40;</span><span style="color: #000000; font-weight: bold;">&#41;</span>
<span style="color: #000000; font-weight: bold;">&#123;</span>
	DWORD winVer = GetVersion<span style="color: #000000; font-weight: bold;">&#40;</span><span style="color: #000000; font-weight: bold;">&#41;</span>;
	BOOL isPlatformNT = winVer &gt;= 0x80000000 ? <span style="color: #000000;">FALSE</span> : <span style="color: #000000;">TRUE</span>;
&nbsp;
	<span style="color: #0000ff;">if</span><span style="color: #000000; font-weight: bold;">&#40;</span> isPlatformNT <span style="color: #000000; font-weight: bold;">&#41;</span>
		<span style="color: #0000ff;">printf</span><span style="color: #000000; font-weight: bold;">&#40;</span><span style="color: #666666;">"Plataforma NT<span style="color: #666666;">\n</span>"</span><span style="color: #000000; font-weight: bold;">&#41;</span>;
	<span style="color: #0000ff;">else</span>
		<span style="color: #0000ff;">printf</span><span style="color: #000000; font-weight: bold;">&#40;</span><span style="color: #666666;">"Bem-vindo ao parque dos dinossauros!<span style="color: #666666;">\n</span>"</span><span style="color: #000000; font-weight: bold;">&#41;</span>;
&nbsp;
	<span style="color: #0000ff;">return</span> isPlatformNT ? <span style="color: #000000;">1</span> : <span style="color: #000000;">0</span>;
<span style="color: #000000; font-weight: bold;">&#125;</span>
&nbsp;</pre></p>
<p><img src="http://www.caloni.com.br/blog/wp-content/uploads/jurassicpark.PNG" alt="jurassicpark.PNG" /></p>
<h4>3. CloseHandle. Mesmo??</h4>
<p>Nem sempre o handle que obtemos é fechado com CloseHandle. As funções abaixo retornam handles que devem ser desalocados com as funções à direita:</p>
<pre>Função que obtém recurso         Função que libera recurso
------------------------         -------------------------
LoadLibrary                      FreeLibrary
RegOpenKey                       RegCloseKey
GetDC                            ReleaseDC
BeginPaint                       EndPaint</pre>
<h4>4. Tem mais?</h4>
<p>Sempre tem. Algumas dicas úteis para o dia-a-dia de um programador Win32 API são:</p>
<ul>
<li>Leia a documentação</li>
<li>Se atente aos valores de retorno em caso de sucesso e erro</li>
<li>Leia sempre a seção remarks pelo menos uma vez; ela explica como desalocar recursos</li>
<li>Releia a documentação</li>
</ul>
<p>Às vezes uma singela chamada de uma função de autenticação pode nos fazer preencher uma estrutura de 20 membros, sendo que seis deles são obtidos com mais sete chamadas de funções, todas com direito a desalocar recursos no final. O importante é sempre manter a calma, o espírito de aprendizado e aventura. Afinal, quem mandou não fazer software de telinha?</p>
]]></content:encoded>
			<wfw:commentRss>http://www.caloni.com.br/blog/archives/aprenda-a-usar-sua-api/feed</wfw:commentRss>
		</item>
		<item>
		<title>O conhecido unresolved external</title>
		<link>http://www.caloni.com.br/blog/archives/o-conhecido-unresolved-external</link>
		<comments>http://www.caloni.com.br/blog/archives/o-conhecido-unresolved-external#comments</comments>
		<pubDate>Fri, 18 Jul 2008 09:00:53 +0000</pubDate>
		<dc:creator>Wanderley Caloni</dc:creator>
		
		<category><![CDATA[Debugging]]></category>

		<guid isPermaLink="false">http://www.caloni.com.br/blog/archives/o-conhecido-unresolved-external</guid>
		<description><![CDATA[O artigo anterior mostrou que nem sempre as coisas são simples de resolver, mas que sempre existe um caminho a seguir e que, eventualmente, todos os problemas se solucionarão.
Porém, resolver um problema por si só não basta: é preciso rapidez. E como conseguimos rapidez para resolver problemas? Um jeito que eu, meu cérebro e o [...]]]></description>
			<content:encoded><![CDATA[<p>O <a href="http://www.caloni.com.br/blog/archives/o-caso-da-funcao-de-delay-load-desaparecida">artigo anterior</a> mostrou que nem sempre as coisas são simples de resolver, mas que sempre existe um caminho a seguir e que, eventualmente, todos os problemas se solucionarão.</p>
<p>Porém, resolver um problema por si só não basta: é preciso <strong>rapidez</strong>. E como conseguimos rapidez para resolver problemas? Um jeito que eu, meu cérebro e o <a href="http://www.dumpanalysis.org/blog/">Dmitry Vostokov</a> conhecem é <strong>montando padrões</strong>.</p>
<p>Um padrão nos ajuda a não pensar novamente em coisas que sabemos a resposta, de tantas vezes que já fizemos. Só precisamos saber o caminho para resolver determinado problema.</p>
<p>Mesmo assim, existem diversos caminhos a percorrer. Até mesmo para um singelo e batidíssimo "<strong>unresolved external</strong>".</p>
<h4>Primeiro passo: você está usando a LIB correta?</h4>
<p>O erro mais comum é usar uma LIB onde não está a função que estamos usando, ou usar uma versão diferente da mesma LIB que não contém a função, ou contém, mas com assinatura (parâmetros da função) diferentes. Isso pode ser verificado no código-fonte da LIB, se disponível, ou então pelo uso do <strong>dumpbin</strong>, como já vimos anteriormente.</p>
<blockquote><p>Dica extra: às vezes você pensa que está usando uma LIB em um determinado caminho, mas o linker achou a LIB primeiro em outro lugar. Para se certificar que está verificando a mesma LIB que o linker achou, use o Process Monitor.</p></blockquote>
<p>Às vezes, porém, não estamos usando a função diretamente e não conhecemos quem a usaria. Para isso que hoje em dia os compiladores mais espertos nos dizem em que parte do código foi referenciado a tal função:</p>
<pre>test.obj : error LNK2019: unresolved external symbol _func referenced in function _main</pre>
<p>É sábio primeiro inspecionar a função que referencia, para depois entender porque ela não foi encontrada. Mesmo parecendo diferente, essa operação faz parte do primeiro passo, que é <strong>identificar a origem</strong>.</p>
<h4>Segundo passo: você digitou direito?</h4>
<p>Parece estúpido, mas às vezes é esse o caso. Essa é a segunda coisa a fazer porque não é tão comum quanto a primeira, visto que hoje em dia é rotina colocarmos as funções em um <em>header </em>e incluirmos esse cabeçalho em nosso código-fonte (em C++, praticamente obrigatório). Se houvesse discrepância entre o nome da função chamada e o nome da função existente, provavelmente teríamos um <strong>erro de compilação</strong> ("função não encontrada") antes do erro de <em>linking</em>.</p>
<h4>Terceiro passo: tente incluir a função diretamente no seu código</h4>
<p>Se a LIB não está cooperando, e der pouco trabalho, experimente incluir a função inteira (ou o cpp) dentro do seu projeto, para linkar diretamente. Se funcionar, então existe alguma diferença de compilação entre os dois projetos (o seu e o da LIB) para que haja uma divergência no nome procurado. Procure nas opções de projeto.</p>
<h4>Quarto passo: comece de novo!</h4>
<p>Sempre que nos deparamos com um problema que aos poucos vai consumindo o nosso tempo, tendemos a gastar mais tempo fazendo coisas inúteis que sabemos que não irá adiantar de nada. Às vezes fazer <em>brute force</em> pode dar certo. Outras vezes, seria melhor recomeçar a pesquisa e tentar entender de fato o que está acontecendo na compilação. Em outras palavras: gastar o seu tempo <strong>pensando</strong> pode ser mais produtivo do que agir instintivamente.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.caloni.com.br/blog/archives/o-conhecido-unresolved-external/feed</wfw:commentRss>
		</item>
		<item>
		<title>O caso da função de Delay Load desaparecida</title>
		<link>http://www.caloni.com.br/blog/archives/o-caso-da-funcao-de-delay-load-desaparecida</link>
		<comments>http://www.caloni.com.br/blog/archives/o-caso-da-funcao-de-delay-load-desaparecida#comments</comments>
		<pubDate>Wed, 16 Jul 2008 09:00:55 +0000</pubDate>
		<dc:creator>Wanderley Caloni</dc:creator>
		
		<category><![CDATA[Debugging]]></category>

		<guid isPermaLink="false">http://www.caloni.com.br/blog/archives/o-caso-da-funcao-de-delay-load-desaparecida</guid>
		<description><![CDATA[Todos os projetos do Visual Studio 6 estavam compilando normalmente com a nova modificação do código-fonte, uma singela chamada a uma função da DLL iphlpapi.dll. No entanto, ainda restava a compilação para Windows 95, um legado que não era permitido esquecer devido ao parque antigo de máquinas e sistemas operacionais de nossos clientes.
Ora, acontece que [...]]]></description>
			<content:encoded><![CDATA[<p>Todos os projetos do Visual Studio 6 estavam compilando normalmente com a nova modificação do código-fonte, uma singela chamada a uma <a href="http://msdn.microsoft.com/en-us/library/aa366012(VS.85).aspx">função</a> da DLL <strong>iphlpapi.dll</strong>. No entanto, ainda restava a compilação para Windows 95, um legado que não era permitido esquecer devido ao parque antigo de máquinas e sistemas operacionais de nossos clientes.</p>
<p>Ora, acontece que a função em questão não existe em Windows 95! O que fazer?</p>
<p>Essa é uma situação comum e controlada, que chega a ser quase um padrão de projeto: <strong>funções novas demais</strong>. A saída? Não chamar a função quando o sistema não for novo o suficiente. Isso pode ser resolvido facilmente com uma chamada a <a href="http://msdn.microsoft.com/en-us/library/ms724439(VS.85).aspx">GetVersion</a>.</p>
<p>Porém, um outro problema decorrente dessa situação é que a função chamada estaticamente cria um <em>link</em> de importação da DLL para o executável. Ou seja, uma <strong>dependência estática</strong>. Dependências estáticas necessitam ser resolvidas antes que o programa execute, e o carregador (<em>loader</em>) de programas do sistema é responsável por essa verificação.</p>
<p>Para verificar a existência de todas as DLLs e funções necessárias para nosso programa podemos utilizar o mundialmente conhecido <a href="http://www.dependencywalker.com/">Dependency Walker</a>:</p>
<pre>depends meu_executa<strike></strike>vel.exe</pre>
<p><img src="http://www.caloni.com.br/blog/wp-content/uploads/depends_meu_executavel.PNG" alt="depends_meu_executavel.PNG" /></p>
<p>Se a função ou DLL não existe no sistema, o seguinte erro costuma ocorrer (isso depende da versão do Sistema Operacional):</p>
<p><img src="http://www.caloni.com.br/blog/wp-content/uploads/loader_erro.PNG" alt="loader_erro.PNG" /></p>
<p>Mas nem tudo está perdido!</p>
<h4>Visual Studio Delay Load DLL</h4>
<p>Existe uma LIB no Visual Studio que serve para substituir a dependência estática de uma DLL pela verificação dinâmica da existência de suas funções quando, e se, for executada a função no programa.</p>
<p>Essa LIB contém algumas funções-chave que o Visual Studio utiliza ser for usado o seguinte parâmetro de compilação:</p>
<pre>/delayload:iphlpapi.dll</pre>
<p>A função principal se chama "__delayLoadHelper@8", ou seja, é uma função com convenção de chamada WINAPI (stdcall) que recebe dois parâmetros.</p>
<p>Isso costuma sempre funcionar, sendo que tive uma grande surpresa com os seguintes erros de compilação na versão do programa que deve ser executada em Windows 95:</p>
<pre>--------------------Configuration: Project - Win32 Win95 Release--------------------
Linking...
iphlpapi.lib(iphlpapi.dll) : error LNK2001: unresolved external symbol ___delayLoadHelper@8
iphlpapi.lib(iphlpapi.dll) : error LNK2001: unresolved external symbol ___delayLoadHelper@8
release/meu_executavel.exe : fatal error LNK1120: 1 unresolved externals
Error executing link.exe.

meu_executavel.exe - 3 error(s), 0 warning(s)</pre>
<p>Isso, é claro, depois de ter checado e rechecado a existência da LIB de Delay Load na lista de LIBs a serem lincadas:</p>
<p><img src="http://www.caloni.com.br/blog/wp-content/uploads/delayimp.PNG" alt="delayimp.PNG" /></p>
<h4>E agora, José?</h4>
<p>Acontece que eu conheço algumas ferramentas que podem sempre me ajudar em situações de compilação e linque: <a href="http://technet.microsoft.com/en-us/sysinternals/bb896645.aspx?PHPSESSID=d926">Process Monitor</a> e <a href="http://support.microsoft.com/kb/177429">dumpbin</a>.</p>
<p>O Process Monitor pode ser usado para obter exatamente a localização da LIB que estamos tentando verificar:</p>
<p><img src="http://www.caloni.com.br/blog/wp-content/uploads/delayimpprocmon.PNG" alt="delayimpprocmon.PNG" /></p>
<p>Após localizar o local, podemos listar seus símbolos, mais precisamente a função "delayLoadHelper":</p>
<pre>C:\DDK\3790\lib\w2k\i386&gt;dumpbin /symbols delayimp.lib | grep delayLoadHelper
108 00000000 SECT3C notype ()    External     | ___delayLoadHelper2@8</pre>
<p>A análise mostra que a função possui um "2" no final de seu nome, causando o erro de linque.</p>
<h4>Mudanças na função__delayLoadHelper</h4>
<p>Essa função, <a href="http://msdn.microsoft.com/en-us/library/2b054ds4.aspx">pelo visto</a>, tem mudado de nome desde o Visual C++ 6, o que fez com que LIBs mais novas não funcionassem com essa versão do Visual Studio.</p>
<p>Para sanar o problema, existem duas coisas que podem ser feitas:</p>
<ol>
<li>Usar a delayimp.lib antiga. Isso não exige nenhuma mudança no código.</li>
<li>Criar uma função delayLoadHelper como wrapper. Isso exige a escrita de código. O código-fonte dessa função está disponível no diretório Include do Visual Studio, e pode ser adaptada para versões antigas.</li>
</ol>
<p>Nessa sessão de depuração você aprendeu como usar o Process Monitor para rastrear arquivos usados na compilação e como listar símbolos de LIBs que são usadas para lincar o programa.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.caloni.com.br/blog/archives/o-caso-da-funcao-de-delay-load-desaparecida/feed</wfw:commentRss>
		</item>
		<item>
		<title>Segunda versão do Houaiss2Babylon</title>
		<link>http://www.caloni.com.br/blog/archives/segunda-versao-do-houaiss2babylon</link>
		<comments>http://www.caloni.com.br/blog/archives/segunda-versao-do-houaiss2babylon#comments</comments>
		<pubDate>Mon, 14 Jul 2008 09:00:20 +0000</pubDate>
		<dc:creator>Wanderley Caloni</dc:creator>
		
		<category><![CDATA[Code]]></category>

		<guid isPermaLink="false">http://www.caloni.com.br/blog/archives/segunda-versao-do-houaiss2babylon</guid>
		<description><![CDATA[

Depois de vários comentários de pessoas tendo problemas em converter seus dicionários Houaiss para o formato Babylon, resolvi criar vergonha na cara e dar uma pequena melhora na versão beta do conversor.
Agora a maioria dos erros que houver será descrita por uma mensagem no seguinte formato:

O primeiro erro acima ocorre principalmente se não houver algum [...]]]></description>
			<content:encoded><![CDATA[

<p>Depois de <a href="http://www.caloni.com.br/blog/archives/conversor-de-houaiss-para-babylon-parte-2#comment-757">vários comentários</a> de pessoas tendo problemas em converter seus dicionários Houaiss para o formato Babylon, resolvi criar vergonha na cara e dar uma pequena melhora na versão beta do conversor.</p>
<p>Agora a maioria dos erros que houver será descrita por uma mensagem no seguinte formato:</p>
<p><img src="http://www.caloni.com.br/blog/wp-content/uploads/houaiss2babylonerror.PNG" alt="houaiss2babylonerror.PNG" /></p>
<p>O primeiro erro acima ocorre principalmente se não houver algum Houaiss instalado que o programa possa detectar. Resolva este problema <a href="http://compare.buscape.com.br/categoria?id=30&amp;lkout=1&amp;kw=Dicionario+Houaiss&amp;site_origem=1293522">fazendo uma busca no Buscapé</a>.</p>
<p>Abaixo segue a função criada para exibir essas mensagens:</p>
<p><pre><span style="color: #0000ff;">void</span> MessageError<span style="color: #000000; font-weight: bold;">&#40;</span>DWORD err, PCSTR msg, ...<span style="color: #000000; font-weight: bold;">&#41;</span>
<span style="color: #000000; font-weight: bold;">&#123;</span>
	<span style="color: #0000ff;">CHAR</span> errBuffer<span style="color: #000000; font-weight: bold;">&#91;</span><span style="color: #000000;">100</span><span style="color: #000000; font-weight: bold;">&#93;</span>;
	<span style="color: #0000ff;">CHAR</span> msgBuffer<span style="color: #000000; font-weight: bold;">&#91;</span>ERR_STR_BUF_SIZE<span style="color: #000000; font-weight: bold;">&#93;</span>;
	<span style="color: #0000ff;">va_list</span> vaList;
&nbsp;
	<span style="color: #0000ff;">va_start</span><span style="color: #000000; font-weight: bold;">&#40;</span>vaList, msg<span style="color: #000000; font-weight: bold;">&#41;</span>;
	<span style="color: #0000ff;">vsprintf</span><span style="color: #000000; font-weight: bold;">&#40;</span>msgBuffer, msg, vaList<span style="color: #000000; font-weight: bold;">&#41;</span>;
	<span style="color: #0000ff;">va_end</span><span style="color: #000000; font-weight: bold;">&#40;</span>vaList<span style="color: #000000; font-weight: bold;">&#41;</span>;
&nbsp;
	<span style="color: #0000ff;">sprintf</span><span style="color: #000000; font-weight: bold;">&#40;</span>errBuffer, <span style="color: #666666;">" Erro de sistema n&uacute;mero %d."</span>, <span style="color: #000000; font-weight: bold;">&#40;</span><span style="color: #0000ff;">int</span><span style="color: #000000; font-weight: bold;">&#41;</span> err<span style="color: #000000; font-weight: bold;">&#41;</span>;
	<span style="color: #0000ff;">strcat</span><span style="color: #000000; font-weight: bold;">&#40;</span>msgBuffer, errBuffer<span style="color: #000000; font-weight: bold;">&#41;</span>;
&nbsp;
	MessageBox<span style="color: #000000; font-weight: bold;">&#40;</span><span style="color: #0000ff;">NULL</span>, msgBuffer, STR_PROJECT_NAME, MB_OK | MB_ICONERROR<span style="color: #000000; font-weight: bold;">&#41;</span>;
<span style="color: #000000; font-weight: bold;">&#125;</span>
&nbsp;</pre></p>
<h4>Um pouco sobre argumentos variáveis</h4>
<p>Se você notou, a função acima pode receber um número de argumentos variáveis para formatar a string da mensagem principal do erro, além de exibir seu código. Essa mágica pode ser feita usando-se o cabeçalho padrão "stdarg.h". Através dele temos acesso ao tipo va_list, que representa uma lista de argumentos variáveis.</p>
<p>Pela convenção de chamada da linguagem C (e C++), quem desmonta a pilha é o chamador. Sendo assim, a função chamada não precisa conhecer o número de argumentos com que foi chamado.</p>
<p>A função de formatação de string é uma variante do conhecidíssimo printf, na versão que recebe um tipo va_list. Muito útil para formatação de logs.</p>
<h4>Voltando ao Projeto</h4>
<p>O fonte, como sempre, está disponível no <a href="https://launchpad.net/">LaunchPad</a>, e pode ser obtido com o seguinte comando do Bazaar:</p>
<pre>bzr get lp:houaiss2babylon</pre>
<p>Existe uma <a href="http://www.caloni.com.br/tools/Houaiss2Babylon.exe">versão compilada</a> no meu saite, para que os leigos não precisem aprender programação antes de usar este programa.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.caloni.com.br/blog/archives/segunda-versao-do-houaiss2babylon/feed</wfw:commentRss>
		</item>
		<item>
		<title>Primeiros passos no VMware Workstation</title>
		<link>http://www.caloni.com.br/blog/archives/primeiros-passos-no-vmware-workstation</link>
		<comments>http://www.caloni.com.br/blog/archives/primeiros-passos-no-vmware-workstation#comments</comments>
		<pubDate>Thu, 10 Jul 2008 09:00:47 +0000</pubDate>
		<dc:creator>Wanderley Caloni</dc:creator>
		
		<category><![CDATA[Testing]]></category>

		<guid isPermaLink="false">http://www.caloni.com.br/blog/archives/primeiros-passos-no-vmware-workstation</guid>
		<description><![CDATA[Como uma ferramenta essencial que uso todos os dias da minha vida de programador, sou obrigado a falar neste blogue sobre a VMware, ferramenta que tem me salvado algumas centenas de horas de depuração, testes e alguns cabelos brancos (a mais).
Para os que não sabem, o VMware é um software de virtualização que permite rodar [...]]]></description>
			<content:encoded><![CDATA[<p>Como uma ferramenta essencial que uso todos os dias da minha vida de programador, sou obrigado a falar neste blogue sobre a <a href="http://www.vmware.com">VMware</a>, ferramenta que tem me salvado algumas centenas de horas de depuração, testes e alguns cabelos brancos (a mais).</p>
<p>Para os que não sabem, o VMware é um <em>software </em>de virtualização que permite rodar diversos sistemas operacionais secundários (chamados de convidados, ou <em>guests</em>) em cima do sistema operacional primário (chamado de hospedeiro, ou <em>host</em>). Para isso ele utiliza uma técnica muito interessante conhecida como <a href="http://en.wikipedia.org/wiki/Virtualization">virtualização</a>, onde o desempenho da máquina virtual chega bem próximo da máquina nativa em que estamos rodando, ainda mais se instalados os apetrechos de otimização (vide VMware Tools) dentro dos sistemas operacionais convidados.</p>
<h4>Primeiro passo: instalar (ou seria comprar?)</h4>
<p>O VMware, diferente de <a href="http://www.microsoft.com/windows/downloads/virtualpc/default.mspx">alguns</a> <a href="http://www.caloni.com.br/blog/archives/virtualbox">outros</a> <a href="http://www.cl.cam.ac.uk/research/srg/netos/xen/">programas de virtualização</a>, não é gratuito. No entanto, o tempo despendido pela equipe da VMware em tornar esta a solução a de melhor qualidade (opinião pessoal de quem já mexeu com Virtual PC e pouco de VirtualBox) está bem cotado, sendo que seu preço é acessível pelo desenvolvedor médio. Pior que o preço da VMware com certeza será o dos sistemas operacionais convidados, se estes forem da Microsoft, que obriga cada instância do Windows, seja hospedeiro ou convidado, a possuir uma licença separada. Se rodar um Windows XP como hospedeiro e um Vista e 2000 como convidados vai desembolsar pelo menos o quíntuplo da licença da VMware.</p>
<p>No entanto, não entremos em mais detalhes financeiros. Os detalhes técnicos são mais interessantes.</p>
<h4>Segundo passo: instalar (agora sim!)</h4>
<p><img src="http://www.caloni.com.br/blog/wp-content/uploads/newvm.PNG" alt="newvm.PNG" /></p>
<p>A instalação é simples e indolor, sendo constituída de cinco ou seis botões de <em>next</em>. O resto, e mais importante, é a instalação de um sistema operacional dentro de sua primeira máquina virtual. Outro assistente existe nessa fase para guiá-lo através de suas escolhas que irão configurar sua futura máquina.</p>
<blockquote><p>Um pouco sobre redes</p>
<p><strong>Use bridged networking</strong>. É criada uma conexão real através de uma ponte feita em cima de uma placa de rede da máquina real. É usado um IP diferente da máquina real e se comporta como uma outra máquina qualquer na rede.</p>
<p><strong>Use NAT</strong>. As conexões são criadas usando o IP do sistema operacional hospedeiro. Para isto acontecer é usado o conhecido esquema de NAT, onde um único IP externo pode representar n IPs internos de uma rede (nesse caso, a rede virtual formada pelas máquinas virtuais de uma mesma máquina real).</p>
<p><strong>Use host-only networking</strong>. O IP usado nessa conexão é diferente da máquina real, mas só é enxergada por ela e por outras VMs localizadas na mesma máquina hospedeira. Muito útil para isolar um teste de vírus, quando se precisa de uma rede mas não podemos usar a rede da empresa inteira.</p></blockquote>
<p>Imagine uma VM (Virtual Machine) como uma máquina de verdade, onde podemos dar <em>boot</em>, formatar HDs (virtuais ou reais), colocar e remover dispositivos. Tendo isso em mente, fica simples entender o que funciona por dentro de sua console, ou seja, a tela onde vemos a saída da virtualização.</p>
<blockquote><p>Um pouco sobre discos virtuais</p>
<p>Os HDs que criamos para nossas VMs são arquivos lógicos localizados em nosso HD real. A mágica em que o sistema operacional virtual acessa o disco virtual como se fosse de verdade é feita pela VMware, inclusive a doce ilusão que ele cotém 80 GB, enquanto seu arquivo-repositório ocupa meros 5 GB no disco. Nas edições novas do software, é possível mapear um HD virtual e exibi-lo na máquina real.</p></blockquote>
<p>Se você dispõe do CD de instalação de um sistema operacional, por exemplo, Windows XP, basta inseri-lo no CD virtual de sua VM. Ela aceita também imagens ISO, se for o caso. Lembre-se apenas que ele terá que ser "bootável", do contrário é necessário um disquete de <em>boot</em>.</p>
<p><img src="http://www.caloni.com.br/blog/wp-content/uploads/vmdevices.PNG" alt="vmdevices.PNG" /></p>
<blockquote><p>Um pouco sobre BIOS</p></blockquote>
<blockquote><p>A sua VM emula todo o comportamento de uma máquina real. Ela, portanto, contém uma BIOS, feita pela VMware. Essa BIOS possui as mesmas opções interessantes de ordem de <em>boot </em>(primeiro o disquete, depois o HD, etc) e escolha de dispositivo de <em>boot </em>(tecla ESC).</p></blockquote>
<p>A instalação do sistema operacional segue os mesmos passos que a instalação do sistema operacional de qualquer máquina de verdade.</p>
<p><a href="http://www.caloni.com.br/blog/wp-content/uploads/xpinstall.PNG" title="xpinstall.PNG"><img src="http://www.caloni.com.br/blog/wp-content/uploads/xpinstall.PNG" alt="xpinstall.PNG" /></a></p>
<blockquote><p>As teclas mágicas</p>
<p><strong>Entrar o foco na VM. Digite <font color="#ff0000">Ctrl + G</font>.</strong> Todos seus movimentos de teclado e mouse só irão funcionar dentro da máquina virtual, exceto o Ctrl + Alt + Del, exclusividade do <a href="http://www.caloni.com.br/blog/archives/gina-x-credential-provider">sistema de autenticação do Windows</a>.</p>
<p><strong>Tirar o foco da VM. Digite <font color="#ff0000">Ctrl + Alt</font>.</strong> Todos seus movimentos de teclado e mouse passam a ser do SO hospedeiro.</p>
<p><strong>Ctrl + Alt + Del dentro da VM. Use <font color="#ff0000">Ctrl + Alt + Insert</font>.</strong> Ele terá o mesmo efeito que um CAD, independente em que tela estiver em sua VM.</p></blockquote>
<p>Após feita a instalação, você terá um sistema operacional rodando dentro de um sistema operacional. Isso não é legal?</p>
<p><a href="http://www.caloni.com.br/blog/wp-content/uploads/xpvm.PNG" title="xpvm.PNG"><img src="http://www.caloni.com.br/blog/wp-content/uploads/xpvm.PNG" alt="xpvm.PNG" /></a></p>
<blockquote><p><em>Snapshots</em></p>
<p>A primeira coisa a fazer em sua VM com SO recém-instalado é criar um <em>snapshot</em>, ou seja, salvar o estado atual de sua máquina virtual. Ao fazer isso, se fizer alguma coisa dentro da VM que possa se arrepender depois, basta voltar para o estado que salvou anteriormente. A VMware permite criar quantos <em>snapshots </em>precisar (basta ter espaço em disco). Ela permite que você crie novas máquinas virtuais a partir de um estado de uma VM já criada, o que pode economizar todo o tempo de montar do zero outra VM ou copiar o disco virtual.</p></blockquote>
<h4>Dois usos muito úteis para uma VM</h4>
<ul>
<li>Abrir os seus e-mails suspeitos. Não tenha mais medo de sujar seu computador com e-mails de conteúdo duvidoso. Crie um estado seguro em sua VM através de um snapshot (fotografia de estado da máquina virtual) e execute os anexos mais absurdos. Depois basta voltar para o estado seguro.</li>
<li>Testes que costumam alterar o estado da máquina. Driver, <a href="http://www.caloni.com.br/blog/archives/gina-x-credential-provider">GINA</a> ou <a href="http://www.caloni.com.br/blog/archives/como-rodar-qualquer-coisa-como-servico">serviço</a> novo? Que tal usar uma VM para fazer os testes iniciais e parar de reformatar o Windows?</li>
</ul>
<p>As VMs possibilitam um mundo de utilidades que o mundo ainda está descobrindo. Para nós, desenvolvedores, a maior vantagem de tudo isso é termos nossos ambientes de testes mais bizarros facilmente configurados no conforto de uma caixinha de areia.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.caloni.com.br/blog/archives/primeiros-passos-no-vmware-workstation/feed</wfw:commentRss>
		</item>
		<item>
		<title>Projeto-modelo</title>
		<link>http://www.caloni.com.br/blog/archives/projeto-modelo</link>
		<comments>http://www.caloni.com.br/blog/archives/projeto-modelo#comments</comments>
		<pubDate>Tue, 08 Jul 2008 09:00:01 +0000</pubDate>
		<dc:creator>Wanderley Caloni</dc:creator>
		
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://www.caloni.com.br/blog/archives/projeto-modelo</guid>
		<description><![CDATA[É muito difícil construir um modelo de pastas que sirva para a maioria dos projetos que tivermos que colocar na fôrma. Ainda mais se esses projetos tiverem que futuramente fazer parte da mesma ramificação. Foi pensando em várias coisas que chegamos a uma versão beta que pode ajudar aqueles que ficam pensando durantes dias antes [...]]]></description>
			<content:encoded><![CDATA[<p>É muito difícil construir um modelo de pastas que sirva para a maioria dos projetos que tivermos que colocar na fôrma. Ainda mais se esses projetos tiverem que futuramente fazer parte da mesma ramificação. Foi pensando em várias coisas que chegamos a uma versão beta que pode ajudar aqueles que ficam pensando durantes dias antes mesmo de colocar as mãos no código.</p>
<h4>Primeira coisa: controle de código</h4>
<p>Antes de começar a pensar em como as pastas estarão alinhadas, é importante saber como funcionará o controle de código do seu projeto. Como <a href="http://www.caloni.com.br/blog/archives/como-estou-trabalhando-com-o-bazaar">eu disse sobre o Bazaar</a>, a estrutura inicial permitirá a junção de dois projetos distintos se estes compartilharem do mesmo commit no começo de suas vidas.</p>
<p>Portanto, trate de iniciar a estruturação em um projeto-modelo que já contenha pelo menos um commit: o das pastas vazias já estruturadas.</p>
<pre>bzr init _Template
cd _Template
bzr mkdir Docs
bzr mkdir Interface
bzr ...
bzr ci -m "Projeto-modelo. Herde desse projeto sua estrutura inicial"</pre>
<h4>Estruturação proposta</h4>
<p><img src="http://www.caloni.com.br/blog/wp-content/uploads/projeto-modelo2.png" title="projeto-modelo2.png" alt="projeto-modelo2.png" align="left" /></p>
<p><span style="font-weight: bold">Build</span>. Essa pasta contém tudo que é necessário para compilar e testar o projeto como um todo. Idealmente a execução da batch build.bat deve executar todo o processo. Após a compilação, é de competência dos componentes na subpasta Tests fazer os testes básicos do projeto para se certificar de que tudo está funcionando como deveria.</p>
<p><span style="font-weight: bold">Common</span>. Aqui devem ser colocados aqueles includes que servem para vários pontos do projeto. Está exemplificado pelo arquivo de versão (Version.h), pois todos os arquivos devem referenciar uma única versão do produto. Podem existir Outras definições básicas, como nome do produto, dos arquivos, etc. É aqui que são gravadas as interfaces que permitem dependência circular entre os componentes (e.g. Interface de componentes COM).</p>
<p><span style="font-weight: bold">Docs</span>. Aqui deve ser colocada toda a documentação que diz respeito ao projeto. A organização interna ainda não foi definida, pois imagina-se ser possível usar diversas fontes, como doxygen, casos de uso, bugs, arquivos de projeto e UML. Foi exemplificado com o arquivo todo.txt e changes.txt, que deve ter sempre a lista de coisas a fazer e a lista de coisas já feitas, respectivamente, tendo, portanto, que ser sempre atualizados.</p>
<p><span style="font-weight: bold">Drivers</span>. Essa é a parte onde ficam todos os componentes que rodam em kernel mode. Por se tratar de um domínio específico e muitas vezes compartilhar código-fonte de maneira não-heterodoxa (e.g. sem uso de LIBs), faz sentido existir uma pasta que agrupe esses elementos. Dentro da pasta existem subpastas para cada driver, exemplificados em Driver1 e Driver2.</p>
<p><span style="font-weight: bold">Install</span>. Todas as coisas relacionadas com instalação, desinstalação e atualização do software deve vir nessa pasta. Foi reservada uma subpasta para cada item, não sendo obrigatória sua divisão. Também existe uma pasta de DLLs, onde possivelmente existam telas personalizadas e biblioteca de uso comum pelos instaladores (o desinstalador conversa com o instalador e assim por diante).</p>
<p><span style="font-weight: bold">Interface</span>. Todas as telas de um programa devem ser colocadas nessa pasta. Essa é uma divisão que deve ser seguida conceitualmente. Por exemplo, se existir um gerenciador de alguma coisa no produto, as telas do gerenciador e o comportamento da interface ficam nessa pasta, mas o comportamento intrínseco do sistema (regras de negócio) devem ficar em Libraries. Para exemplificar o uso, foram criadas as Interface1 e Interface2.</p>
<p><span style="font-weight: bold">Libraries</span>. O ponto central do projeto, deve conter o código mais importante. Imagine a pasta Libraries como a inteligência de um projeto, de onde todos os outros componentes se utilizam para que a lógica do software seja sempre a mesma. As outras partes do projeto lidam com aspectos técnicos, enquanto o Libraries contém as regras abstratas de funcionamento. Opcionalmente ela pode ser estática ou dinâmica, caso onde foi criada a subpasta DLLs. Porém, elas devem ser divididas por função em bibliotecas estáticas, como foi exemplificado em Library1 e Library2.</p>
<p><span style="font-weight: bold">Resources</span>. A origem de todas as imagens, sons, cursores, etc de um projeto devem residir primeiramente na pasta Resources. A divisão interna desse item fica a critério do designer responsável, pois ele pode dividir tanto por função (Install, Interface) quanto por elementos (Images, Sounds).</p>
<p><span style="font-weight: bold">Services</span>. Além dos drivers e das interfaces alguns projetos necessitam de processos "invisíveis" que devem fazer algo no sistema. Isso inclui serviços do Windows, GINAs, componentes COM e coisas do gênero. Devem ser colocados nessa pasta e distribuídos como no exemplo, em Service1 e Service2.</p>
<p><span style="font-weight: bold">Tools</span>. Além dos componentes essenciais para o funcionamento do software também existem aqueles componentes que fornecem mais poder ao usuário, ao pessoal do suporte ou ao próprio time de desenvolvimento. Essas são as ferramentas de suporte que permitem a fácil identificação de erros no programa ou a configuração mais avançada de um item que a Interface não cobre. Adicionalmente foi colocada a subpasta Develop, que deve conter ferramentas usadas estritamente durante a fase de desenvolvimento.</p>
<h4>Testes</h4>
<p>Todos os componentes que disponibilizarem unidades de testes devem conter uma pasta Tests dentro de si. Essa padronização permite facilmente a localização de testes internos aos componentes. Além disso, os arquivos executáveis de testes devem sempre terminar seu nome com Test, o que permite a automatização do processo de teste durante o build.</p>
<p>Acredito que este esboço esteja muito bom. É o modelo inicial que estou utilizando nos projetos da empresa e de casa. Deixo disponível <a href="http://www.caloni.com.br/blog/wp-content/uploads/_template.7z" title="_Template.7z">aqui</a> para <span style="font-style: italic">download</span>. Críticas e sugestões são bem-vindas.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.caloni.com.br/blog/archives/projeto-modelo/feed</wfw:commentRss>
		</item>
		<item>
		<title>VirtualBox</title>
		<link>http://www.caloni.com.br/blog/archives/virtualbox</link>
		<comments>http://www.caloni.com.br/blog/archives/virtualbox#comments</comments>
		<pubDate>Fri, 04 Jul 2008 21:17:47 +0000</pubDate>
		<dc:creator>Wanderley Caloni</dc:creator>
		
		<category><![CDATA[Testing]]></category>

		<guid isPermaLink="false">http://www.caloni.com.br/blog/archives/virtualbox</guid>
		<description><![CDATA[O VirtualBox parece ser o concorrente mais próximo atualmente da VMWare. Descobrimos ele essa semana e resolvemos fazer alguns testes. O resultado foi bem animador.
Desenvolvido pela Sun Microsystems, as características do VirtualBox impressionam pelo cuidado que houve em torná-lo muito parecido com sua concorrente paga. Apenas para começar, ela suporta dispositivos USB, possui múltiplos snapshots [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://en.wikipedia.org/wiki/VirtualBox" title="virtualbox_about_screen.png"><img src="http://www.caloni.com.br/blog/wp-content/uploads/virtualbox_about_screen.png" title="virtualbox_about_screen.png" alt="virtualbox_about_screen.png" align="left" /></a>O <a href="http://www.virtualbox.org">VirtualBox</a> parece ser o concorrente mais próximo atualmente da <a href="http://www.vmware.com">VMWare</a>. Descobrimos ele essa semana e resolvemos fazer alguns testes. O resultado foi bem animador.</p>
<p>Desenvolvido pela Sun Microsystems, as características do VirtualBox impressionam pelo cuidado que houve em torná-lo muito parecido com sua concorrente paga. Apenas para começar, ela suporta dispositivos USB, possui múltiplos snapshots e já suporta o modo do <a href="www.vmware.com/download/fusion">VMWare Fusion</a> - chamado de <em>"seamless mode</em>" - , que estará integrado na versão 7 da VMWare.</p>
<p>No entanto, entre as coisas que testamos (instalado em um Windows Vista SP1 como host), o que não funcionou já não agradou tanto. A lista de prós e contras ainda confirma a liderança da VMWare, pelo menos em qualidade:</p>
<pre>Funcionalidade          VMWare             VirtualBox</pre>
<pre>Snapshots               Sim                Sim. Mesma velocidade.
USB                     Sim                Sim. Não funcionou.
Seamless Mode           Não                Sim.
Clipboard               Sim                Sim. Não funcionou.
Shared Folders          Sim                Sim. Erros de acesso.
Ferramentas Guest       Sim                Sim.
Pause Momentâneo        Não                Sim.</pre>
<p>Além da tabela de testes acima, é necessário notar que por mas três vezes a VM simplesmente parou de responder, sendo necessário reiniciar o programa Host.</p>
<p>Em suma, o VirtualBox tem tudo para arrasar em futuras versões. Se, é claro, conseguir competir em qualidade com a VMWare que, no momento, é a líder em soluções de virtualização. Talvez por isso sua solução não seja tão barata.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.caloni.com.br/blog/archives/virtualbox/feed</wfw:commentRss>
		</item>
		<item>
		<title>Pesquisas sobre a GINA</title>
		<link>http://www.caloni.com.br/blog/archives/pesquisas-sobre-a-gina</link>
		<comments>http://www.caloni.com.br/blog/archives/pesquisas-sobre-a-gina#comments</comments>
		<pubDate>Wed, 02 Jul 2008 21:08:15 +0000</pubDate>
		<dc:creator>Wanderley Caloni</dc:creator>
		
		<category><![CDATA[OperatingSystem]]></category>

		<guid isPermaLink="false">http://www.caloni.com.br/blog/archives/pesquisas-sobre-a-gina</guid>
		<description><![CDATA[Já sabemos o que é uma GINA. Afinal, todo mundo já viu uma antes. E sabemos que hoje em dia ela está morta.
No entanto, algumas pequenas mudanças foram feitas nela no Windows XP que ainda almaldiçoam o código de quem tenta reproduzir a famosa GINA da Microsoft. Nem todos chegam no final e morrem tentando.
Eu [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.caloni.com.br/blog/wp-content/uploads/250px-xp_windows_security.png" title="250px-xp_windows_security.png"><img src="http://www.caloni.com.br/blog/wp-content/uploads/250px-xp_windows_security.thumbnail.png" title="250px-xp_windows_security.png" alt="250px-xp_windows_security.png" align="left" height="77" width="105" /></a>Já sabemos o que é uma <a href="http://www.caloni.com.br/blog/archives/gina-x-credential-provider">GINA</a>. Afinal, todo mundo já viu uma antes. E sabemos que hoje em dia ela está morta.</p>
<p>No entanto, algumas pequenas mudanças foram feitas nela no Windows XP que ainda almaldiçoam o código de quem tenta reproduzir a famosa GINA da Microsoft. Nem todos chegam no final e morrem tentando.</p>
<p>Eu sou um deles.</p>
<h4>Para os que investem em uma nova GINA</h4>
<p>Uma explicação sobre como funciona o processo de logon (local e remoto) e os componentes envolvidos está no artigo "<a href="http://technet2.microsoft.com/windowsserver/en/library/779885d9-e5e9-4f27-9c14-5bbe77b056ba1033.mspx?mfr=true">How Interactive Logon Works</a>" da Technet. Esse artigo irá abrir os olhos para mais detalhes que você gostaria de saber sobre nossa velha e querida amiga. Os desenhos explicativos estão ótimos!</p>
<p>Após essa leitura picante, podemos voltar ao feijão com arroz e começar de novo lendo a descrição de como funciona a <a href="http://en.wikipedia.org/wiki/Graphical_identification_and_authentication">GINA na Wikipedia</a>, que nos remete a vários linques interessantes, entre os quais:</p>
<ul>
<li>A explicação documentada <a href="http://msdn.microsoft.com/en-us/library/aa380543.aspx">do MSDN</a> de como funciona a interação entre Winlogon e GINA.</li>
<li>Um ótimo artigo dividido em <a href="http://msdn.microsoft.com/en-us/magazine/cc163803.aspx">duas</a> <a href="http://msdn.microsoft.com/en-us/magazine/cc163786.aspx">partes</a> que explica como fazer sua própria customização de GINA. Foi nele que encontrei o retorno que precisava para emular a execução do Gerenciador de Tarefas baseado na digitação do Ctrl + Alt + Del. De brinde ainda vem uma GINA de exemplo para <em>download</em>.</li>
</ul>
<p>A partir de mais algumas buscas e execuções do Process Monitor podemos encontrar os valores no registro que habilitam o <a href="http://www.pctools.com/guides/registry/detail/973/">Fast User Switching</a> e a <a href="http://www.pctools.com/guides/registry/detail/972/">Tela de Boas Vindas</a> do Windows XP. O valor da Tela de Boas Vindas é que habilita e desabilita a execução do Gerenciador de Tarefas baseado em Ctrl + Alt + Del. Esses itens são essenciais para os que quiserem criar uma réplica perfeita da GINA da Microsoft no Windows XP. Isso finaliza a minha busca.</p>
<h4>Será mesmo?</h4>
<p>Sempre tem mais. Se a máquina estiver no domínio essa opção não funciona. Porém, o <strong>WinLogon</strong> verifica se existe um valor chamado <strong>ForceFriendlyUi</strong>, que descobri graças ao <a href="technet.microsoft.com/en-us/sysinternals/bb896645.aspx">Process Monitor</a>. Aliado ao <strong>LogonType</strong>, sendo igual a 1, a Tela de Boas-Vindas é habilitada, mesmo em um ambiente com servidor de domínio.</p>
<p>Por último, claro, salvo se não existir o valor <strong>GinaDll</strong> dentro da chave do WinLogon. Se esse for o caso, o ForceFriendlyUi também não funciona. E é exatamente aí que uma GINA é instalada.</p>
<p>E eis que surge uma nova GINA.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.caloni.com.br/blog/archives/pesquisas-sobre-a-gina/feed</wfw:commentRss>
		</item>
		<item>
		<title>Reflexão em C++</title>
		<link>http://www.caloni.com.br/blog/archives/reflexao-em-c</link>
		<comments>http://www.caloni.com.br/blog/archives/reflexao-em-c#comments</comments>
		<pubDate>Mon, 30 Jun 2008 04:02:38 +0000</pubDate>
		<dc:creator>Wanderley Caloni</dc:creator>
		
		<category><![CDATA[C++]]></category>

		<guid isPermaLink="false">http://www.caloni.com.br/blog/archives/reflexao-em-c</guid>
		<description><![CDATA[





O termo e conceito de "reflection" (reflexão), muito usado em linguagens modernas, é a capacidade de um programa de observar e até de alterar sua própria estrutura. Bom, isso você pode ler na Wikipédia. O interessante é o que podemos usar desse conceito na linguagem C++.
Infelizmente não muito.
O sistema de RTTI (Run Time Type Identification), [...]]]></description>
			<content:encoded><![CDATA[





<p>O termo e conceito de "<a href="http://en.wikipedia.org/wiki/Reflection_(computer_science)"><em>reflection</em></a>" (<a href="http://pt.wikipedia.org/wiki/Reflex%C3%A3o_%28programa%C3%A7%C3%A3o%29">reflexão</a>), muito usado em linguagens modernas, é a capacidade de um programa de observar e até de alterar sua própria estrutura. Bom, isso você pode ler na Wikipédia. O interessante é o que podemos usar desse conceito na linguagem C++.</p>
<p>Infelizmente não muito.</p>
<p>O sistema de <strong>RTTI</strong> (<em>Run Time Type Identification</em>), a identificação de tipos em tempo de execução, seria o começo do <em>reflection </em>em C++. Foi um começo que não teve meio nem fim, mas existe na linguagem. Dessa forma podemos tirar algum proveito disso.</p>
<p>Um leitor pediu para que eu falasse um pouco sobre essas coisas, especificamente como se faz para obter o nome da classe de onde estamos executando um determinado método. Para esse tipo de construção podemos usar o operado <strong>typeid</strong>, que retorna informações básicas sobre um tipo de acordo com um tipo, instância ou expressão:</p>
<p><pre><span style="color: #006600;">#include &lt;iostream&gt;</span>
&nbsp;
<span style="color: #0000ff;">using</span> <span style="color: #0000ff;">namespace</span> std;
&nbsp;
<span style="color: #0000ff;">int</span> main<span style="color: #000000; font-weight: bold;">&#40;</span><span style="color: #000000; font-weight: bold;">&#41;</span>
<span style="color: #000000; font-weight: bold;">&#123;</span>
	<span style="color: #0000ff;">cout</span> &lt;&lt; <span style="color: #0000ff;">typeid</span><span style="color: #000000; font-weight: bold;">&#40;</span> <span style="color: #0000ff;">int</span> <span style="color: #000000; font-weight: bold;">&#41;</span>.<span style="color: #000000;">name</span><span style="color: #000000; font-weight: bold;">&#40;</span><span style="color: #000000; font-weight: bold;">&#41;</span> &lt;&lt; endl;
&nbsp;
	<span style="color: #0000ff;">int</span> x;
	<span style="color: #0000ff;">cout</span> &lt;&lt; <span style="color: #0000ff;">typeid</span><span style="color: #000000; font-weight: bold;">&#40;</span> x <span style="color: #000000; font-weight: bold;">&#41;</span>.<span style="color: #000000;">name</span><span style="color: #000000; font-weight: bold;">&#40;</span><span style="color: #000000; font-weight: bold;">&#41;</span> &lt;&lt; endl;
&nbsp;
	<span style="color: #0000ff;">cout</span> &lt;&lt; <span style="color: #0000ff;">typeid</span><span style="color: #000000; font-weight: bold;">&#40;</span> <span style="color: #000000;">2</span> + <span style="color: #000000;">2</span> <span style="color: #000000; font-weight: bold;">&#41;</span>.<span style="color: #000000;">name</span><span style="color: #000000; font-weight: bold;">&#40;</span><span style="color: #000000; font-weight: bold;">&#41;</span> &lt;&lt; endl;
<span style="color: #000000; font-weight: bold;">&#125;</span>
&nbsp;</pre></p>
<pre>C:\Tests&gt;cl typeid.cpp
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 15.00.21022.08 for 80x86
Copyright (C) Microsoft Corporation.  All rights reserved.

/out:typeid.exe
typeid.obj

C:\Tests&gt;typeid.exe
int
int
int</pre>
<p>Dessa forma, podemos nos aproveitar do fato que todo método não-estático possui a variável implícita <strong>this</strong>, do tipo "ponteiro constante para T", onde T é o tipo da classe que contém o método sendo chamado.</p>
<p><pre><span style="color: #006600;">#include &lt;iostream&gt;</span>
&nbsp;
<span style="color: #0000ff;">using</span> <span style="color: #0000ff;">namespace</span> std;
&nbsp;
class MyClass
<span style="color: #000000; font-weight: bold;">&#123;</span>
	<span style="color: #0000ff;">public</span>:
		<span style="color: #0000ff;">void</span> MyMethod<span style="color: #000000; font-weight: bold;">&#40;</span><span style="color: #000000; font-weight: bold;">&#41;</span>
		<span style="color: #000000; font-weight: bold;">&#123;</span>
			<span style="color: #0000ff;">cout</span> &lt;&lt; <span style="color: #0000ff;">typeid</span><span style="color: #000000; font-weight: bold;">&#40;</span>*<span style="color: #0000ff;">this</span><span style="color: #000000; font-weight: bold;">&#41;</span>.<span style="color: #000000;">name</span><span style="color: #000000; font-weight: bold;">&#40;</span><span style="color: #000000; font-weight: bold;">&#41;</span> &lt;&lt; <span style="color: #666666;">"::MyMethod"</span> &lt;&lt; endl;
		<span style="color: #000000; font-weight: bold;">&#125;</span>
<span style="color: #000000; font-weight: bold;">&#125;</span>;
&nbsp;
<span style="color: #0000ff;">int</span> main<span style="color: #000000; font-weight: bold;">&#40;</span><span style="color: #000000; font-weight: bold;">&#41;</span>
<span style="color: #000000; font-weight: bold;">&#123;</span>
	MyClass myc;
&nbsp;
	myc.<span style="color: #000000;">MyMethod</span><span style="color: #000000; font-weight: bold;">&#40;</span><span style="color: #000000; font-weight: bold;">&#41;</span>;
<span style="color: #000000; font-weight: bold;">&#125;</span>
&nbsp;</pre></p>
<pre>C:\Tests&gt;cl typeid-class.cpp
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 15.00.21022.08 for 80x86
Copyright (C) Microsoft Corporation.  All rights reserved.

/out:typeid-class.exe
typeid-class.obj

C:\Tests&gt;typeid-class.exe
<font color="#ff0000">class MyClass::MyMethod</font></pre>
<p>Com classes não-polimórficas a coisa parece não ter muita utilidade. No entanto, essa mesma técnica pode ser aplicada em classes derivadas, uma vez que o operador typeid pode trabalhar em tempo de execução:</p>
<p><pre><span style="color: #006600;">#include &lt;iostream&gt;</span>
&nbsp;
<span style="color: #0000ff;">using</span> <span style="color: #0000ff;">namespace</span> std;
&nbsp;
class MyClass
<span style="color: #000000; font-weight: bold;">&#123;</span>
	<span style="color: #0000ff;">public</span>:
		<span style="color: #0000ff;">virtual</span> <span style="color: #0000ff;">void</span> MyMethod<span style="color: #000000; font-weight: bold;">&#40;</span><span style="color: #000000; font-weight: bold;">&#41;</span>
		<span style="color: #000000; font-weight: bold;">&#123;</span>
			<span style="color: #0000ff;">cout</span> &lt;&lt; <span style="color: #0000ff;">typeid</span><span style="color: #000000; font-weight: bold;">&#40;</span>*<span style="color: #0000ff;">this</span><span style="color: #000000; font-weight: bold;">&#41;</span>.<span style="color: #000000;">name</span><span style="color: #000000; font-weight: bold;">&#40;</span><span style="color: #000000; font-weight: bold;">&#41;</span> &lt;&lt; <span style="color: #666666;">"::MyMethod"</span> &lt;&lt; endl;
		<span style="color: #000000; font-weight: bold;">&#125;</span>
<span style="color: #000000; font-weight: bold;">&#125;</span>;
&nbsp;
class MyDerivatedClass1 : <span style="color: #0000ff;">public</span> MyClass <span style="color: #000000; font-weight: bold;">&#123;</span> <span style="color: #000000; font-weight: bold;">&#125;</span>;
&nbsp;
class MyDerivatedClass2 : <span style="color: #0000ff;">public</span> MyClass <span style="color: #000000; font-weight: bold;">&#123;</span> <span style="color: #000000; font-weight: bold;">&#125;</span>;
&nbsp;
<span style="color: #0000ff;">int</span> main<span style="color: #000000; font-weight: bold;">&#40;</span><span style="color: #000000; font-weight: bold;">&#41;</span>
<span style="color: #000000; font-weight: bold;">&#123;</span>
	MyClass* myc1 = <span style="color: #0000ff;">new</span> MyDerivatedClass1;
	MyClass* myc2 = <span style="color: #0000ff;">new</span> MyDerivatedClass2;
&nbsp;
	myc1-&gt;MyMethod<span style="color: #000000; font-weight: bold;">&#40;</span><span style="color: #000000; font-weight: bold;">&#41;</span>;
	myc2-&gt;MyMethod<span style="color: #000000; font-weight: bold;">&#40;</span><span style="color: #000000; font-weight: bold;">&#41;</span>;
<span style="color: #000000; font-weight: bold;">&#125;</span>
&nbsp;</pre></p>
<pre>C:\Tests&gt;cl typeid-class2.cpp
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 15.00.21022.08 for 80x86
Copyright (C) Microsoft Corporation.  All rights reserved.

/out:typeid-class2.exe
typeid-class2.obj

C:\Tests&gt;typeid-class2.exe
<font color="#ff0000">class MyDerivatedClass1::MyMethod
class MyDerivatedClass2::MyMethod</font></pre>
<p>Apenas se lembre de ter de fato uma classe polimórfica (eu consegui isso tornando MyMethod uma função virtual). Do contrário você pode <a href="http://www.caloni.com.br/blog/archives/typeid-e-os-perigos-do-nao-polimorfismo">ter problemas</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.caloni.com.br/blog/archives/reflexao-em-c/feed</wfw:commentRss>
		</item>
	</channel>
</rss>
