<?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>Tue, 07 Oct 2008 16:57:05 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.2</generator>
	<language>en</language>
			<item>
		<title>Impressões do quinto encontro de CCPP</title>
		<link>http://www.caloni.com.br/blog/archives/impressoes-do-quinto-encontro-de-ccpp</link>
		<comments>http://www.caloni.com.br/blog/archives/impressoes-do-quinto-encontro-de-ccpp#comments</comments>
		<pubDate>Tue, 07 Oct 2008 16:57:05 +0000</pubDate>
		<dc:creator>Wanderley Caloni</dc:creator>
		
		<category><![CDATA[CcppBrazil]]></category>

		<guid isPermaLink="false">http://www.caloni.com.br/blog/archives/impressoes-do-quinto-encontro-de-ccpp</guid>
		<description><![CDATA[Pois é, passou, acabou... e foi muito bom!
E dessa vez me abstenho de fazer os comentários de sempre, visto que já está rolando uma discussão muito produtiva sobre o resultado desse último encontro, opiniões que, sinceramente, já refletem os pensamentos de todos que participaram desse magnânimo encontro de usuários.
]]></description>
			<content:encoded><![CDATA[<p>Pois é, <a href="http://www.caloni.com.br/blog/archives/v" title="Quinto encontro de usuários CCPP">passou</a>, acabou... e foi muito bom!</p>
<p>E dessa vez me abstenho de fazer os comentários de sempre, visto que já está rolando uma <a href="http://groups.google.com/group/ccppbrasil/browse_thread/thread/f088e1833564f756/5ea38098b1828b7f?show_docid=5ea38098b1828b7f#" title="Google Groups">discussão muito produtiva</a> sobre o resultado desse último encontro, opiniões que, sinceramente, já refletem os pensamentos de todos que participaram desse magnânimo encontro de usuários.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.caloni.com.br/blog/archives/impressoes-do-quinto-encontro-de-ccpp/feed</wfw:commentRss>
		</item>
		<item>
		<title>O que acontece com um programador com pressa</title>
		<link>http://www.caloni.com.br/blog/archives/o-que-acontece-com-um-programador-com-pressa</link>
		<comments>http://www.caloni.com.br/blog/archives/o-que-acontece-com-um-programador-com-pressa#comments</comments>
		<pubDate>Sun, 05 Oct 2008 16:00:53 +0000</pubDate>
		<dc:creator>Wanderley Caloni</dc:creator>
		
		<category><![CDATA[Nothing]]></category>

		<guid isPermaLink="false">http://www.caloni.com.br/blog/archives/o-que-acontece-com-um-programador-com-pressa</guid>
		<description><![CDATA[Eu já sabia, mas é lógico que não ia falar.
Há um tempo atrás um rapaz me pediu para responder uma série de questões sobre a carreira de programador C++. Era um rapaz empolgado com a idéia de aprender a linguagem em seis meses, com um roteiro, cronograma e um blogue recém-criados.
Como quase toda uma geração [...]]]></description>
			<content:encoded><![CDATA[<p>Eu já sabia, mas é lógico que não ia falar.</p>
<p>Há um tempo atrás um <a href="http://www.caloni.com.br/blog/archives/entrevista-com-o-caloni-no-do-zero-ao-mestre">rapaz me pediu</a> para responder <a href="http://dozeroaomestre.blogspot.com/2008/07/entrevista-wanderlei-caloni.html" title="Entrevista com Caloni">uma série de questões</a> sobre a carreira de programador C++. Era um rapaz empolgado com a idéia de aprender a linguagem em seis meses, com um roteiro, cronograma e um <a href="http://dozeroaomestre.blogspot.com/" title="Do zero ao mestre">blogue</a> recém-criados.</p>
<p>Como quase toda uma geração do imediatismo, aconteceu o inevitável: o blogue já não é atualizado há quase dois meses e toda aquela empolgação do começo deve ter virado fumaça assim que a pessoa vira a esquina e aparece uma coisa nova para fazer. E daí surgem as desculpas, o blá-blá-blá de todos aqueles que nunca têm tempo.</p>
<p>Eu sou um deles, mas de vez em quando atualizo esse meu espacinho =)</p>
<h4>Os projetos que nunca acabam</h4>
<p>Na experiência de vida que tenho com todas aquelas idéias mirabolantes que as pessoas possuem de fazer alguma coisa, seja um software, aprender algo novo, ou até criar uma rotina qualquer, eu diria que quase todas, se não todas, falharam.</p>
<p>É natural que no começo, quando a idéia brota, e mais idéias formentam a idéia original, o empolgamento nos dá a falsa impressão que podemos fazer isso facilmente, e que é só planejar, ter vontade e ir em frente que conseguimos. É claro que toda essa impressão muda com o passar do tempo, principalmente para aquelas pessoas que possuem muitas idéias em muito pouco tempo, algo que acontece bastante com programadores, mas que em geral afeta todo mundo.</p>
<p>Em se tratando de software, a primeira coisa que deve ser feita, sempre, é <strong>planejar as tarefas visíveis</strong> a serem feitas para esboçar um <strong>panorama possível</strong> para o futuro do projeto. Eu disse <strong>possível</strong> no sentido de <strong>realizável</strong>.</p>
<p>O segundo passo é esquecer esse negócio de realizável, cair na real e encarar os fatos: o mundo não é perfeito. Comece a colocar <strong>defeitos no cronograma</strong>, tentar imaginar o que <strong>vai sair errado</strong> e, principalmente, conhecer você mesmo e as pessoas envolvidas para ter a real expectativa do que pode ser feito em quanto tempo.</p>
<h4>Porque em um cronograma a única certeza que temos é que tudo vai dar errado</h4>
<p>Após jogar água fria o suficiente (às vezes são necessários muitos baldes) sobre suas idéias novas e excitantes, temos um panorama um pouco mais preciso, mais realista e, agora sim, passível de ser feito e <strong>acontecer de verdade</strong>.</p>
<p>Só que ainda não acabou.</p>
<p>É claro que isso tudo é o <strong>começo do projeto</strong>. Após a primeira semana, o primeiro mês, o segundo mês e o segundo semestre as atividades devem ser <strong>revistas e reprojetadas</strong>. Mais uma vez entra a regrinha da água fria. Não é porque deu errado no começo que não pode <a href="http://pt.wikipedia.org/wiki/Acidente_nuclear_de_Chernobil" title="Chernobil"><strong>dar mais errado ainda</strong></a> no final.</p>
<p>Esse pequeno chamado foi apenas um reforço do apelo que <a href="http://www.1bit.com.br" title="1Bit.com.br">Rodrigo Strauss</a> fez em nosso último encontro de C++. Nosso grupo precisa de mais pessoas que escrevam algo. Portanto, façam blogues, mas não os deixem desgarrados!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.caloni.com.br/blog/archives/o-que-acontece-com-um-programador-com-pressa/feed</wfw:commentRss>
		</item>
		<item>
		<title>Cnasi, geração Y e seus gastos em TI</title>
		<link>http://www.caloni.com.br/blog/archives/cnasi-geracao-y-e-seus-gastos-em-ti</link>
		<comments>http://www.caloni.com.br/blog/archives/cnasi-geracao-y-e-seus-gastos-em-ti#comments</comments>
		<pubDate>Thu, 25 Sep 2008 03:40:02 +0000</pubDate>
		<dc:creator>Wanderley Caloni</dc:creator>
		
		<category><![CDATA[Nothing]]></category>

		<guid isPermaLink="false">http://www.caloni.com.br/blog/archives/cnasi-geracao-y-e-seus-gastos-em-ti</guid>
		<description><![CDATA[Hoje descemos a rua para almoçar no shopping e aproveitamos para dar uma passada no último dia da feirinha de empresas de segurança, vulgo Cnasi, para "prestigiar" a nossa participação nesse evento singular.
Nosso crachá de visitantes dava direito a uma palestra. E haviam muitas. Porém, logo após a hora do almoço, das disponíveis uma era [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.caloni.com.br/blog/wp-content/uploads/cnasi-2008.jpg" title="cnasi-2008.jpg"><img src="http://www.caloni.com.br/blog/wp-content/uploads/cnasi-2008.jpg" title="Eu invadindo o sistema da Cnasi e me auto-promovendo gerente!" alt="Eu invadindo o sistema da Cnasi e me auto-promovendo gerente!" align="right" /></a>Hoje descemos a rua para almoçar no shopping e aproveitamos para dar uma passada no último dia da feirinha de empresas de segurança, vulgo <a href="http://www.cnasi.com.br/" title="Cnasi">Cnasi</a>, para "prestigiar" a nossa participação nesse evento singular.</p>
<p>Nosso crachá de visitantes dava direito a uma palestra. E haviam muitas. Porém, logo após a hora do almoço, das disponíveis uma era particularmente interessante, pois citava uma expressão que eu e minha colega nunca havíamos escutado: um senhor iria nos falar sobre como lidar com essas novas pessoas que estão cada vez mais invadindo nossas casas e nossos escritórios, pertencentes a esse grupinho, a tão famosa chamada <strong>geração Y</strong>.</p>
<p>Agora não sei se a culpa foi dessa tal geração Y, mas o fato é que o folhetim estava errado e caímos em uma outra palestra, essa falando sobre um tema que aí sim nós nunca tínhamos ouvido falar: como <strong>gerenciar as finanças</strong> na parte de TI da empresa.</p>
<p>O homem discursou por uma hora falando de como todos os principais <em>frameworks </em>de gerenciamento de custos, projetos e todas aquelas coisas, poderiam ser integrados para facilitar a vida do gestor de projetos que tem como tarefa saber o que irá continuar fazendo e o que irá cortar devido à lucratividade/risco perigosos.</p>
<p>A grande questão dessa discussão, pelo que eu pude entender, foi que os custos de um projeto e manutenção são difíceis de mensurar se não existir alguém no meio daquele bando de nerds que consiga dizer quais são os recursos usados (quem), para que (tarefa) e por quê (vantagem). Sem contar que é necessário transformar isso em dado contábil. Além de que, como bem disse nosso palestrante, a maioria das empresas ainda considera o departamento de nerds uma despesa sem vantagens. E uma despesa bem cara, se estivermos falando dos salários atualmente pagos para esse pessoal.</p>
<p>Mas vou parar por aqui antes que alguém levante a bandeira e queira discursar a respeito da justeza com que são pagas nossas mentes, um assunto muito precoce nos dias atuais. (Bom, talvez seja precoce para sempre, do jeito que a economia é ciência aberta.)</p>
<p>O fato é que acabamos subindo a rua novamente sem saber que tal de geração Y é essa que nos fez entrar na palestra errada. Como sempre, nada que uma boa "googada" não resolva.</p>
<blockquote><p><em>Parênteses. Descobri recentemente que os seguidores do <a href="http://www.microsoft.com" title="O outro lado da busca">outro lado</a> agora inventaram um novo "termo": <a href="http://www.google.com.br/search?q=%22windows-live-searched%22" title="Windows-live-searched no Google">Windows-Live-procurada</a>. Um de seus <a href="http://blogs.technet.com/markrussinovich/archive/2008/09/24/3126858.aspx">representantes</a>, anteriormente um homem de respeito e opiniões fortes e imparciais, acredita este ser um termo de uso corrente no dia-a-dia. </em></p></blockquote>
<h4>E essa tal de geração Y?</h4>
<p>Pelo que pudemos <a href="http://www.google.com.br/search?q=gera%C3%A7%C3%A3o+y" title="Geração Y no Google">encontrar</a>, a tal da geração Y somos nós mesmo. Que espanto! E eu pensei que estávamos falando de uma raça alienígena ou algo assim. Talvez até seja, mas temos todos os genes da espécie humana.</p>
<p>Aparentemente existem estudos "sérios" nos EUA que dividem as gerações usando letras e encontrando as principais diferenças entre nós mesmos e nossos pais e avós. Como essa última geração recebeu elogios de diversas partes do estudo, a nominação de geração Y foi se estendendo ao resto do mundo, principalmente nos novos mercados de tecnologia.</p>
<p>A conclusão a que chego é que existem rótulos demais para as pessoas hoje em dia. As pessoas não podem mais ser simplesmente pessoas. Precisam ser nerds, geeks, ráquers ou geração Y. Se você não é, está de fora. Se está dentro, é antenado. Que é outro rótulo.</p>
<p>Fim de passeio. Voltamos à empresa e falamos com um outro colega sobre o que havíamos aprendido sobre o uso dos recursos no gerenciamento dos projetos no departamento de TI de uma empresa. Ele disse: "TI pra quê? Só traz despesa esse negócio."</p>
<p>E viva a geração Y!</p>
<blockquote><p><em>Adendum. A palestra que participamos foi a <strong>"Por que implementar a gestão financeira de TI? Uma abordagem baseada no ITIL, COBIT/VAL IT, e PMBOK"</strong>, e queríamos ter visto a palestra <strong>"Desafio: Como Gerenciar a Geração Y"</strong>, que como pudemos ver não é tarefa fácil, já que essa geração não consegue nem entrar na palestra certa. Veja a <a href="http://www.cnasi.com.br/palestras.php" title="Grade de palestras da Cnasi">grade do evento</a> para mais informações. </em></p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://www.caloni.com.br/blog/archives/cnasi-geracao-y-e-seus-gastos-em-ti/feed</wfw:commentRss>
		</item>
		<item>
		<title>Windows Jobs com Completion Port</title>
		<link>http://www.caloni.com.br/blog/archives/windows-jobs-com-completion-port</link>
		<comments>http://www.caloni.com.br/blog/archives/windows-jobs-com-completion-port#comments</comments>
		<pubDate>Tue, 23 Sep 2008 09:00:25 +0000</pubDate>
		<dc:creator>Wanderley Caloni</dc:creator>
		
		<category><![CDATA[OperatingSystem]]></category>

		<guid isPermaLink="false">http://www.caloni.com.br/blog/archives/windows-jobs-com-completion-port</guid>
		<description><![CDATA[

Ou "Como esperar o término de todos os processos-filho criados a partir de um conjunto de processos".
Dessa vez confesso que esperava um pouco mais de documentação do MSDN, ou pelo menos um sistema de referências cruzadas eficiente. Outro dia demorei cerca de duas horas para conseguir criar um job, anexar o processo desejado e, a [...]]]></description>
			<content:encoded><![CDATA[

<p>Ou "Como esperar o término de todos os processos-filho criados a partir de um conjunto de processos".</p>
<p>Dessa vez confesso que esperava um pouco mais de documentação do MSDN, ou pelo menos um sistema de referências cruzadas eficiente. Outro dia demorei cerca de duas horas para conseguir <a href="http://msdn.microsoft.com/en-us/library/ms682409(VS.85).aspx" title="Como criar um job no MSDN">criar um <em><strong>job</strong></em></a>, anexar o processo desejado e, a pior parte, esperar que todos os processos (o principal e seus filhos e netos) terminassem.</p>
<p>Além da <a href="http://msdn.microsoft.com/en-us/library/ms684161(VS.85).aspx" title="O que são jobs de acordo com o MSDN">pouca documentação</a>, parece que não são muitas as pessoas que fazem isso e publicam na web, ou eu <a href="http://www.google.com.br/search?q=wait+all+processes+inside+job+object" title="Procurando por jobs no google">não sei procurar direito</a>.</p>
<p>Mas, pra início de conversa, o que é um job mesmo?</p>
<h4>Leve introdução sobre o conceito de jobs</h4>
<p>Um job é um objeto "novo" no kernel do Windows 2000 em diante, e se prontifica a suprir a carência que havia anteriormente de <strong>controle sobre o que os processos podem fazer e por quanto tempo</strong>.</p>
<p>A abstração mais coerente que eu consigo tirar de um job é como <strong>um trabalho a ser executada por um ou mais processos</strong>. O objeto job controla a criação, o término e as exceções que ocorrem dentro dele mesmo.</p>
<p><a href="http://www.caloni.com.br/blog/wp-content/uploads/job.gif" title="job.gif"><img src="http://www.caloni.com.br/blog/wp-content/uploads/job.gif" alt="job.gif" /></a></p>
<p>Entre as funções mais úteis de um job estão limitar o tempo de execução do conjunto de processos, o número de handles/arquivos/outros objetos abertos, limite de memória RAM ocupada e a possibilidade de terminar todos os processos de uma só vez.</p>
<p>Para informações básicas de como criar um job e anexar processos recomendo o ótimo artigo de <a href="http://www.microsoft.com/msj/0399/jobkernelobj/jobkernelobj.aspx">Jeffrey Richter</a>.</p>
<p>No final desse artigo ele chega a citar o controle mais refinado dos processos através de uma <a href="http://msdn.microsoft.com/en-us/library/aa365198(VS.85).aspx" title="I/O Completion Ports no MSDN"><strong>completion port</strong></a>, que permitirá receber eventos que ocorrem dentro de um job durante sua vida útil. Apesar de citar, não há código de exemplo que faça isso.</p>
<p>Bom, agora há:</p>
<p><pre><span style="color: #006600;">#define _WIN32_WINNT 0x0500 // Jobs s&oacute; existem do 2000 em diante</span>
<span style="color: #006600;">#include &lt;windows.h&gt;</span>
&nbsp;
&nbsp;
<span style="color: #006600;">/** @brief Fun&ccedil;&atilde;o que cria um processo a partir de cmdLine
 * e coloca-o dentro de um job. A fun&ccedil;&atilde;o aguarda o t&eacute;rmino
 * do processo e de qualquer subprocesso criado por este.
 */</span>
DWORD CreateJobAndWait<span style="color: #000000; font-weight: bold;">&#40;</span>LPSTR cmdLine<span style="color: #000000; font-weight: bold;">&#41;</span>
<span style="color: #000000; font-weight: bold;">&#123;</span>
   <span style="color: #006600;">// primeiro, criamos um job sem nome</span>
   HANDLE job = CreateJobObject<span style="color: #000000; font-weight: bold;">&#40;</span><span style="color: #0000ff;">NULL</span>, <span style="color: #0000ff;">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> job <span style="color: #000000; font-weight: bold;">&#41;</span>
   <span style="color: #000000; font-weight: bold;">&#123;</span>
      STARTUPINFO si = <span style="color: #000000; font-weight: bold;">&#123;</span> <span style="color: #0000ff;">sizeof</span><span style="color: #000000; font-weight: bold;">&#40;</span>si<span style="color: #000000; font-weight: bold;">&#41;</span> <span style="color: #000000; font-weight: bold;">&#125;</span>;
      PROCESS_INFORMATION pi;
&nbsp;
      <span style="color: #006600;">// depois, criamos um processo suspenso (travado)</span>
      <span style="color: #0000ff;">if</span><span style="color: #000000; font-weight: bold;">&#40;</span> CreateProcess<span style="color: #000000; font-weight: bold;">&#40;</span><span style="color: #0000ff;">NULL</span>, cmdLine, <span style="color: #0000ff;">NULL</span>, <span style="color: #0000ff;">NULL</span>, <span style="color: #0000ff;">FALSE</span>, 
         CREATE_SUSPENDED | CREATE_NEW_CONSOLE, <span style="color: #0000ff;">NULL</span>, <span style="color: #0000ff;">NULL</span>, &amp;si, &amp;pi<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>
         <span style="color: #006600;">// atribu&iacute;mos esse processo ao nosso jobo</span>
         AssignProcessToJobObject<span style="color: #000000; font-weight: bold;">&#40;</span>job, pi.<span style="color: #000000;">hProcess</span><span style="color: #000000; font-weight: bold;">&#41;</span>;
&nbsp;
         <span style="color: #006600;">// rodamos o processo</span>
         ResumeThread<span style="color: #000000; font-weight: bold;">&#40;</span>pi.<span style="color: #000000;">hThread</span><span style="color: #000000; font-weight: bold;">&#41;</span>;
&nbsp;
         <span style="color: #006600;">// essa &eacute; uma completion i/o port gen&eacute;rica</span>
         <span style="color: #006600;">// (ou seja, n&atilde;o relacionada com nenhum arquivo</span>
         <span style="color: #006600;">// ou outra completion port)</span>
         HANDLE port = CreateIoCompletionPort<span style="color: #000000; font-weight: bold;">&#40;</span>INVALID_HANDLE_VALUE, 
                 <span style="color: #0000ff;">NULL</span>, <span style="color: #000000;">0</span>, <span style="color: #000000;">0</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> port <span style="color: #000000; font-weight: bold;">&#41;</span>
         <span style="color: #000000; font-weight: bold;">&#123;</span>
            JOBOBJECT_ASSOCIATE_COMPLETION_PORT jobPort;
&nbsp;
            jobPort.<span style="color: #000000;">CompletionKey</span> = <span style="color: #000000;">0</span>; <span style="color: #006600;">// ver vari&aacute;vel key abaixo</span>
            jobPort.<span style="color: #000000;">CompletionPort</span> = port; <span style="color: #006600;">// nossa completion port vai aqui!</span>
&nbsp;
            <span style="color: #006600;">// definimos a c.p. em nosso job</span>
            <span style="color: #0000ff;">if</span><span style="color: #000000; font-weight: bold;">&#40;</span> SetInformationJobObject<span style="color: #000000; font-weight: bold;">&#40;</span>job, 
                        JobObjectAssociateCompletionPortInformation, 
                        &amp;jobPort, <span style="color: #0000ff;">sizeof</span><span style="color: #000000; font-weight: bold;">&#40;</span>jobPort<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;">&#41;</span>
            <span style="color: #000000; font-weight: bold;">&#123;</span>
               ULONG_PTR key = <span style="color: #000000;">0</span>; <span style="color: #006600;">// ver membro CompletionKey acima</span>
               LPOVERLAPPED overlap = <span style="color: #000000;">0</span>;
               DWORD tranferred = <span style="color: #000000;">0</span>;
&nbsp;
               <span style="color: #006600;">// nosso loop de mensagens com completion port</span>
               <span style="color: #0000ff;">while</span><span style="color: #000000; font-weight: bold;">&#40;</span> GetQueuedCompletionStatus<span style="color: #000000; font-weight: bold;">&#40;</span>port, &amp;tranferred, 
                  &amp;key, &amp;overlap, INFINITE<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>
                  <span style="color: #006600;">// transferred especifica a mensagem</span>
                  DWORD msg = *<span style="color: #000000; font-weight: bold;">&#40;</span>LPDWORD<span style="color: #000000; font-weight: bold;">&#41;</span> &amp;tranferred;
&nbsp;
                  <span style="color: #006600;">// significa que n&atilde;o existem mais processos rodando</span>
                  <span style="color: #0000ff;">if</span><span style="color: #000000; font-weight: bold;">&#40;</span> msg == JOB_OBJECT_MSG_ACTIVE_PROCESS_ZERO <span style="color: #000000; font-weight: bold;">&#41;</span>
                     <span style="color: #0000ff;">break</span>; <span style="color: #006600;">// sa&iacute;mos fora</span>
               <span style="color: #000000; font-weight: bold;">&#125;</span>
            <span style="color: #000000; font-weight: bold;">&#125;</span>
&nbsp;
            CloseHandle<span style="color: #000000; font-weight: bold;">&#40;</span>port<span style="color: #000000; font-weight: bold;">&#41;</span>; <span style="color: #006600;">// fecha tudo</span>
         <span style="color: #000000; font-weight: bold;">&#125;</span>
&nbsp;
         CloseHandle<span style="color: #000000; font-weight: bold;">&#40;</span>pi.<span style="color: #000000;">hThread</span><span style="color: #000000; font-weight: bold;">&#41;</span>; <span style="color: #006600;">// fecha tudo</span>
         CloseHandle<span style="color: #000000; font-weight: bold;">&#40;</span>pi.<span style="color: #000000;">hProcess</span><span style="color: #000000; font-weight: bold;">&#41;</span>; <span style="color: #006600;">// fecha tudo</span>
      <span style="color: #000000; font-weight: bold;">&#125;</span>
&nbsp;
      CloseHandle<span style="color: #000000; font-weight: bold;">&#40;</span>job<span style="color: #000000; font-weight: bold;">&#41;</span>; <span style="color: #006600;">// fecha tudo</span>
   <span style="color: #000000; font-weight: bold;">&#125;</span>
&nbsp;
   <span style="color: #0000ff;">return</span> <span style="color: #000000;">0</span>;
<span style="color: #000000; font-weight: bold;">&#125;</span>
&nbsp;
&nbsp;
<span style="color: #0000ff;">int</span> main<span style="color: #000000; font-weight: bold;">&#40;</span><span style="color: #0000ff;">int</span> argc, <span style="color: #0000ff;">char</span>* argv<span style="color: #000000; font-weight: bold;">&#91;</span><span style="color: #000000; font-weight: bold;">&#93;</span><span style="color: #000000; font-weight: bold;">&#41;</span>
<span style="color: #000000; font-weight: bold;">&#123;</span>
   <span style="color: #0000ff;">if</span><span style="color: #000000; font-weight: bold;">&#40;</span> argc == <span style="color: #000000;">2</span> <span style="color: #000000; font-weight: bold;">&#41;</span>
      CreateJobAndWait<span style="color: #000000; font-weight: bold;">&#40;</span>argv<span style="color: #000000; font-weight: bold;">&#91;</span><span style="color: #000000;">1</span><span style="color: #000000; font-weight: bold;">&#93;</span><span style="color: #000000; font-weight: bold;">&#41;</span>;
<span style="color: #000000; font-weight: bold;">&#125;</span>
&nbsp;</pre></p>
<p>O exemplo acima cria um processo baseado em uma linha de comando e espera pelo término do processo criado e de todos os subprocessos criados a partir do primeiro processo. Note que mesmo que o primeiro processo termine, a Completion Port só receberá o evento que todos os processos acabaram depois que o último subprocesso terminar.</p>
<p>Dessa forma, ao compilarmos o código:</p>
<pre>C:\Tests\CreateJob&gt;cl Createjob.cpp
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 15.00.21022.08 for 80x86
Copyright (C) Microsoft Corporation.  All rights reserved.

Createjob.cpp
Microsoft (R) Incremental Linker Version 9.00.21022.08
Copyright (C) Microsoft Corporation.  All rights reserved.

/out:Createjob.exe
Createjob.obj</pre>
<p>E rodarmos mais um prompt de comando através de nosso programa (o texto em azul significa nossa nova janela de prompt):</p>
<pre>C:\Tests\CreateJob&gt;Createjob.exe cmd        (travado)</pre>
<pre><font color="#0000ff">Microsoft Windows XP [versão 5.1.2600]
(C) Copyright 1985-2001 Microsoft Corp.

C:\Tests\CreateJob&gt;notepad
C:\Tests\CreateJob&gt;exit</font></pre>
<pre>C:\Tests\CreateJob&gt;                         (continua travado)
                                            (fechando notepad)</pre>
<pre>C:\Tests\CreateJob&gt;                         (deve destravar)</pre>
<p>Mesmo ao fecharmos o prompt criado, o programa só será finalizado ao fecharmos o Bloco de Notas iniciado pelo segundo prompt.</p>
<p>Além desse evento, que era o que eu estava procurando, esse método permite obter outros eventos bem interessantes:</p>
<ul>
<li><strong>JOB_OBJECT_MSG_NEW_PROCESS</strong>. Um novo processo foi criado dentro do job.</li>
<li><strong> JOB_OBJECT_MSG_EXIT_PROCESS</strong>. Um processo existente dentro do job foi terminado.</li>
<li><strong>JOB_OBJECT_MSG_PROCESS_MEMORY_LIMIT</strong>. O limite de memória de um processo já foi alcançado.</li>
<li><strong>JOB_OBJECT_MSG_END_OF_PROCESS_TIME</strong>. O limite de tempo de processamento de um processo já foi alcançado.</li>
</ul>
<p>Enfim, jobs não terminam por aí. Dê mais uma olhada no MSDN e veja se encontra mais alguma utilidade interessante para o nosso amigo job. Eu encontrei e fiquei feliz.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.caloni.com.br/blog/archives/windows-jobs-com-completion-port/feed</wfw:commentRss>
		</item>
		<item>
		<title>V</title>
		<link>http://www.caloni.com.br/blog/archives/v</link>
		<comments>http://www.caloni.com.br/blog/archives/v#comments</comments>
		<pubDate>Tue, 23 Sep 2008 03:12:21 +0000</pubDate>
		<dc:creator>Wanderley Caloni</dc:creator>
		
		<category><![CDATA[CcppBrazil]]></category>

		<category><![CDATA[C++]]></category>

		<guid isPermaLink="false">http://www.caloni.com.br/blog/archives/v</guid>
		<description><![CDATA[Parabéns a todos que participaram e ajudaram para que todos nós chegássemos ao quinto encontro de programadores/aficionados C/C++. Parece mentira, mas hoje temos capacidade para lotar um auditório razoável, e temos a ousadia de sempre poder contar com uma grade de palestras pra lá de avançadas. Vejamos o que foi visto até hoje nesses últimos [...]]]></description>
			<content:encoded><![CDATA[<p>Parabéns a todos que participaram e ajudaram para que todos nós chegássemos ao quinto encontro de programadores/aficionados C/C++. Parece mentira, mas hoje temos capacidade para lotar um auditório razoável, e temos a ousadia de sempre poder contar com uma grade de palestras pra lá de avançadas. Vejamos o que foi visto até hoje nesses últimos três encontros (<a href="http://www.caloni.com.br/blog/archives/cppcon-iii">III</a>, <a href="http://www.caloni.com.br/blog/archives/quarto-encontro-c">IV</a> e o <a href="http://www.caloni.com.br/blog/archives/seminario-ccpp-portabilidade-e-performance">seminário</a>):</p>
<ul>
<li>C++ com WxWidgets</li>
<li>O novo padrão C++0x</li>
<li>Threads no C++ ISO</li>
<li>C e microcontroladores</li>
<li>Drivers para Windows</li>
<li>TCP/IP via Boost.Asio</li>
<li>C++ com Qt</li>
<li>Dicas de portabilidade</li>
<li>Programação concorrente</li>
<li>C++ com STL/Boost</li>
<li>Otimização de código</li>
</ul>
<p>E esse é só o começo.</p>
<h4><a href="http://www.ccppbrasil.org/wiki/Grupo:Encontro_V" title="C++ Brasil">Grade para o Quinto Encontro CCPP</a></h4>
<p><font color="#ff0000">04 de outubro de 2008, São Paulo, Brasil</font></p>
<ul>
<li>Ferramentas para programação C++ para Windows por Rodrigo Strauss</li>
<li>Programando com Conceitos no novo C++ por Leandro Melo</li>
<li>Arquivos de memória mapeada no Windows com C++ por Basílio Miranda</li>
<li>Explorando o Windows (Vista &amp; Server 2008) com C++ por Fábio Galuppo</li>
<li>Criando Linguagens Embutidas para Otimização por Felipe Almeida</li>
</ul>
<h4><a href="http://www.temporealeventos.com.br/?area=118&amp;tipo=1&amp;id=2295" title="Tempo Real">Grade para o Evento C &amp; C++ Para Sistemas Embarcados</a></h4>
<p><font color="#ff0000">08 de novembro de 2008, São Paulo, Brasil</font></p>
<ul>
<li>Técnicas de Programação em C para Sistemas Embarcados por Daniel Quadros</li>
<li>Utilização de C++ em Microcontroladores por Luiz Barros</li>
<li>Explorando os 16 bits da Microchip e as ferramentas de trabalho por Daniel Rodrigues</li>
<li>Otimização de código C para sistemas embarcados por Fábio Pereira</li>
<li>Desenvolvimento Embedded no Mundo da eLua por Dado Sutter</li>
</ul>
<p>Se repararam, o número de palestras foi acrescido de um (palestras++) e o tempo para cada uma delas foi ligeiramente encolhido. Espero que esse não seja um empecilho para o desenvolver dos assuntos, pois existem alguns bem delicados acima (como a linguagem embutida e memória mapeada) para serem explicados em cerca de uma hora.</p>
<p>É isso aí. Vida longa ao C++! (e ao C! e ao COBOL! e ao FORTRAN!)</p>
]]></content:encoded>
			<wfw:commentRss>http://www.caloni.com.br/blog/archives/v/feed</wfw:commentRss>
		</item>
		<item>
		<title>Reúna seus comandos mais usados no WinDbg com .cmdtree</title>
		<link>http://www.caloni.com.br/blog/archives/reuna-seus-comandos-mais-usados-no-windbg-com-cmdtree</link>
		<comments>http://www.caloni.com.br/blog/archives/reuna-seus-comandos-mais-usados-no-windbg-com-cmdtree#comments</comments>
		<pubDate>Fri, 19 Sep 2008 01:30:48 +0000</pubDate>
		<dc:creator>Wanderley Caloni</dc:creator>
		
		<category><![CDATA[Debugging]]></category>

		<guid isPermaLink="false">http://www.caloni.com.br/blog/archives/reuna-seus-comandos-mais-usados-no-windbg-com-cmdtrees</guid>
		<description><![CDATA[Tudo começou com o artigo de Roberto Farah sobre o comando "escondido" do WinDbg .cmdtree. Logo depois meus outros colegas do fã-clube do WinDbg Volker von Einem e Dmitry Vostokov comentaram sobre a imensa utilidade desse comando.
E não é pra menos. É de longe o melhor comando não-documentado do ano. Tão bom que sou obrigado [...]]]></description>
			<content:encoded><![CDATA[<p>Tudo começou com o <a href="http://blogs.msdn.com/debuggingtoolbox/archive/2008/09/17/special-command-execute-commands-from-a-customized-user-interface-with-cmdtree.aspx" title="Special Command—Execute Commands from a Customized User Interface with .cmdtree ">artigo de Roberto Farah</a> sobre o comando "escondido" do WinDbg <a href="http://www.microsoft.com/whdc/devtools/debugging/whatsnew.mspx" title="What's new in WinDbg">.cmdtree</a>. Logo depois meus outros colegas do fã-clube do WinDbg <a href="http://voneinem-windbg.blogspot.com/2008/09/amazing-helper-cmdtree.html" title="Amazing helper .cmdtree">Volker von Einem</a> e <a href="http://www.dumpanalysis.org/blog/index.php/2008/09/18/cmdtreetxt-for-cda-checklist/" title="CMDTREE.TXT for CDA Checklist">Dmitry Vostokov</a> comentaram sobre a imensa utilidade desse comando.</p>
<p>E não é pra menos. É de longe o melhor comando não-documentado do ano. Tão bom que sou obrigado a comentar em português sobre ele, apesar dos três artigos já citados.</p>
<h4>Comandos repetitivos</h4>
<p>E eu estava justamente falando sobre essa <a href="http://www.caloni.com.br/blog/archives/todo-programador-e-um-filosofo-em-potencial" title="Todo programador é um filósofo em potencial">mania dos programadores</a> sempre acharem soluções para tarefas repetitivas e monótonas que o computador possa fazer sozinho.O comando .<strong>cmdtree </strong>é uma dessas soluções, pois possibilita ao depurador profissional juntar em uma só guia o conjunto de comandos mais usados por ele no dia-a-dia, por mais bizarros e com mais parâmetros que eles sejam, já que é possível representá-los por um <em>alias</em> (apelido):</p>
<pre>windbg ANSI Command Tree 1.0
title {"Meus Comandos Comuns"}
body
{"Comandos Comuns"}
 {"Subsecao"}
  {"Breakpoint no inicio do programa"} {"bp @$exentry"}
  {"GetLastError"} {"!gle"}</pre>
<p>O resultado:</p>
<p><img src="http://www.caloni.com.br/blog/wp-content/uploads/cmdtree.png" alt="cmdtree.png" /></p>
<p>E podemos usar essa janela no nosso WinDbg, cada vez mais bonitinho e cada vez mais <a href="http://pt.wikipedia.org/wiki/Wysiwyg" title="WYSIWYG na Wikipédia">WYSIWYG</a>:</p>
<p><a href="http://www.caloni.com.br/blog/wp-content/uploads/cmdtree2.png" title="cmdtree2.png"><img src="http://www.caloni.com.br/blog/wp-content/uploads/cmdtree2.png" alt="cmdtree2.png" height="351" width="481" /></a></p>
<p>Realmente não há segredos em seu uso. Esse artigo foi apenas um patrocínio do clube do WinDbg.</p>
<blockquote><p>PS: Interessantemente o suficiente, durante minha navegação em busca das referências encontrei mais dois artigos de duas figurinhas carimbadas no mundo de <em>debugging</em>: <a href="http://www.wintellect.com/CS/blogs/jrobbins/archive/2008/09/17/windbg-cmdtree-file-that-eases-some-sos-pain.aspx" title="WinDBG .cmdtree File That Eases Some SOS Pain ">John Robbins</a> e a <a href="http://blogs.msdn.com/tess/archive/2008/09/18/making-it-easier-to-debug-net-dumps-in-windbg-using-cmdtree.aspx" title="Making it easier to debug .net dumps in windbg using .cmdtree">Tess</a>. Pois é, se o mundo de informática já é pequeno, imagine o mundo de WinDbg =)</p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://www.caloni.com.br/blog/archives/reuna-seus-comandos-mais-usados-no-windbg-com-cmdtree/feed</wfw:commentRss>
		</item>
		<item>
		<title>Todo programador é um filósofo em potencial</title>
		<link>http://www.caloni.com.br/blog/archives/todo-programador-e-um-filosofo-em-potencial</link>
		<comments>http://www.caloni.com.br/blog/archives/todo-programador-e-um-filosofo-em-potencial#comments</comments>
		<pubDate>Fri, 12 Sep 2008 04:08:46 +0000</pubDate>
		<dc:creator>Wanderley Caloni</dc:creator>
		
		<category><![CDATA[Nothing]]></category>

		<guid isPermaLink="false">http://www.caloni.com.br/blog/archives/todo-programador-e-um-filosofo-em-potencial</guid>
		<description><![CDATA[Tivemos uma conversa muito frutífera hoje durante o almoço ao conhecer uma professora que sentava ao nosso lado, exímia conhecedora da mente humana e amante das artes nobres como a filosofia e a lógica.
O importante dessa colóquio foi ter encontrado um motivo muito mais forte para gostar de programação do que qualquer outro que já [...]]]></description>
			<content:encoded><![CDATA[<p>Tivemos uma conversa muito frutífera hoje durante o almoço ao conhecer uma professora que sentava ao nosso lado, exímia conhecedora da mente humana e amante das artes nobres como a <a href="http://pt.wikipedia.org/wiki/Filosofia">filosofia </a>e a <a href="http://pt.wikipedia.org/wiki/L%C3%B3gica">lógica</a>.</p>
<p>O importante dessa colóquio foi ter encontrado um motivo muito mais forte para gostar de programação do que <a href="http://www.1bit.com.br/content.1bit/weblog/why_do_you_code_">qualquer outro</a> que já me surgira na cabeça desde que mexo com essas coisas:</p>
<blockquote><p><em>O computador não deve dar ordens ao homem e este repeti-las como uma máquina. O homem, como ser pensante, deve dizer ao computador o que fazer, e este responder-lhe diligentemente.</em></p></blockquote>
<p>Para resumir desde o começo essa conclusão, um exemplo paupável: quando fazemos um curso de treinamento, uma especialização, uma faculdadeZINHA ou qualquer outro evento de "aprendizado" que nos propõe a digitar comandos sem fim, repetidamente para um computador, para no final ganharmos um comprovante de que sabemos digitar aqueles comandos decorados e repetitivos como ninguém, isso quer dizer que as coisas vão mal, <strong>se</strong> e <strong>quando </strong>tudo se resume a isso.</p>
<p>Por outro lado, ao aprendermos, por nós mesmos ou pelos outros, a usar o computador como a ferramenta que vai fazer de nossas idéias realidade, e nossas criações se materializam de uma forma inimitável, então, somos criadores e comandantes da máquina, e não uma cópia de uma máquina que repete comandos. Então, nesse caso, temos um motivo para viver: criar sempre coisas novas e interessantes que surgem em nossas cabeças.</p>
<p>E ser feliz é isso: achar significado para o que fazemos. É <strong>criar</strong>. Pura e simplesmente. Quem está sempre criando está sempre satisfeito com sua vida. Pois dá sentido a ela todo santo dia. Isso vale para qualquer profissão interessante o suficiente. Não precisa fazer código. Pode construir móveis, ensinar pessoas ou desenhar uma nova peça de roupa.</p>
<p>Criar é pensar. Programadores pensam em coisas novas todos os dias e as executam. Quando encontram algo repetitivo, organizam o código para não terem que repetir mais a mesma baboseira e voltam a fazer coisas interessantes e originais. Se existe um processo enfadonho e chato, o programador inventa um jeito para o computador fazê-lo, e não ele. E a vida do programador sempre gira em torno desse ciclo: dispensa as coisas chatas mandando o computador fazer e se dedica a fazer coisas novas.</p>
<p style="text-align: center"><img src="http://www.caloni.com.br/blog/wp-content/uploads/programmer-cicle.gif" alt="programmer-cicle.gif" /></p>
<h4>Livros, livros e mais livros?</h4>
<p>A discussão não parou por aí, pois me levou a entender o vazio que eu sinto ao estudar coisas que não uso nunca. Porque aprender por aprender não vai me levar a lugar algum. Pode até ser perigoso ler coisas que não servem para nada. Me faz parecer inútil.</p>
<p><img src="http://www.caloni.com.br/blog/wp-content/uploads/c-programming-language-cover.jpg" title="c-programming-language-cover.jpg" alt="c-programming-language-cover.jpg" align="left" />E é por isso que eu gosto de livros curtos, simples e claros.</p>
<p>E não livros longos, ricos em detalhes e que fazem perder o fio da meada ao terminá-lo.</p>
<p>Também me mostra que mais vale a pena aprender a pensar, ou pensar melhor, do que aprender uma nova tecnologia em um livro recém-lançado de 1500 páginas. Quando aprendemos a pensar resolvemos os problemas por nós mesmos, e não por uma formulazinha mágica tirada do saite favorito de bricabraques.</p>
<p>Ser programador é criar. Criar é bom. Criar nos faz felizes.</p>
<p>E é por isso, realmente, que amo o que eu faço.</p>
<h4>Para pensar</h4>
<ul>
<li><a href="http://webinsider.uol.com.br/index.php/2008/05/06/informacao-demais-e-anti-informacao/" title="Webinsider">Informação demais é anti-informação?</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.caloni.com.br/blog/archives/todo-programador-e-um-filosofo-em-potencial/feed</wfw:commentRss>
		</item>
		<item>
		<title>Retorno do PathIsDirectory</title>
		<link>http://www.caloni.com.br/blog/archives/retorno-do-pathisdirectory</link>
		<comments>http://www.caloni.com.br/blog/archives/retorno-do-pathisdirectory#comments</comments>
		<pubDate>Wed, 10 Sep 2008 04:04:39 +0000</pubDate>
		<dc:creator>Wanderley Caloni</dc:creator>
		
		<category><![CDATA[Debugging]]></category>

		<guid isPermaLink="false">http://www.caloni.com.br/blog/archives/retorno-do-pathisdirectory</guid>
		<description><![CDATA[Estava eu outro dia programando aquele código esperto "para ontem" quando me deparei com uma situação no mínimo inusitada. Ao testar se um caminho recebido era de fato um diretório me foi retornado pela API um valor diferente de TRUE. E diferente de FALSE!
De acordo com a documentação, o retorno deveria ser TRUE caso o [...]]]></description>
			<content:encoded><![CDATA[<p>Estava eu outro dia programando aquele código esperto "para ontem" quando me deparei com uma situação no mínimo inusitada. Ao testar se <a href="http://msdn.microsoft.com/en-us/library/bb773621(VS.85).aspx" title="MSDN">um caminho recebido era de fato um diretório</a> me foi retornado pela API um valor diferente de TRUE. E diferente de FALSE!</p>
<p>De acordo com a documentação, o retorno deveria ser TRUE caso o caminho enviado à função fosse de fato um diretório. Caso contrário, o retorno deveria ser FALSE.</p>
<p>Note que existem apenas dois valores possíveis para essa função. Porém, o valor retornado não é 1, o equivalente ao define TRUE, mas sim 0x10 (16 em hexadecimal). O simples exemplo abaixo deve conseguir reproduzir a situação (Windows XP Service Pack 3):</p>
<pre>Setting environment for using Microsoft Visual Studio 2008 x86 tools.

C:\Tests&gt;copy con IsPathDir.cpp
#include &lt;shlwapi.h&gt;
#include &lt;windows.h&gt;
#include &lt;stdio.h&gt;

#pragma comment(lib, "shlwapi.lib")

int main()
{
        BOOL isDir = PathIsDirectory("C:\\Tests"); // obs.: diretorio TEM que existir
        printf("Resultado: %d.\n", isDir);
}^Z
        1 arquivo(s) copiado(s).

C:\Tests&gt;cl IsPathDir.cpp
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 15.00.21022.08 for 80x86
Copyright (C) Microsoft Corporation.  All rights reserved.

IsPathDir.cpp
Microsoft (R) Incremental Linker Version 9.00.21022.08
Copyright (C) Microsoft Corporation.  All rights reserved.

/out:IsPathDir.exe
IsPathDir.obj

C:\Tests&gt;IsPathDir.exe
<font color="#ff0000">Resultado: 16.</font></pre>
<p>Isso quer dizer apenas que o código abaixo vai funcionar,</p>
<pre>if( PathIsDirectory(path) ) // legal: qualquer coisa diferente de zero</pre>
<p>o código abaixo vai funcionar</p>
<pre>if( ! PathIsDirectory(path) ) // legal: se der zero (FALSE), OK</pre>
<p>e o código abaixo <strong>não vai funcionar</strong>:</p>
<pre>if( PathIsDirectory(path) == TRUE ) // vixi: TRUE nem sempre é o resultado</pre>
<p>E, pior, o código abaixo <strong>também não vai funcionar</strong>!</p>
<pre>if( PathIsDirectory(path) != TRUE ) // aff... é bom rever os seus conceitos</pre>
<p>Pesquisando um pouco descobri <a href="http://www.microsoft.com/communities/newsgroups/en-us/default.aspx?dg=microsoft.public.win32.programmer.kernel&amp;tid=15f6c3fd-a57e-4c27-91ea-2ddd49aaf2a6&amp;cat=&amp;lang=&amp;cr=&amp;sloc=&amp;p=1" title="MS Fórum">uma boa discussão sobre o tema</a>, e inclusive que outras pessoas descobriram o <a href="http://svn.haxx.se/tsvn/archive-2004-10/0425.shtml">interessante detalhe</a> que para pastas normais o retorno é 0x10, mas para compartilhamentos o retorno é 0x1.</p>
<h4>O bug atrás dos documentos</h4>
<p>O problema ocorre por causa da maneira que a função determina se o caminho é um diretório ou não. Uma simples vistoria sobre a função nos revela o detalhe crucial:</p>
<pre>C:\Tests&gt;cl /Zi IsPathDir.cpp
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 15.00.21022.08 for 80x86
Copyright (C) Microsoft Corporation.  All rights reserved.

IsPathDir.cpp
Microsoft (R) Incremental Linker Version 9.00.21022.08
Copyright (C) Microsoft Corporation.  All rights reserved.

/out:IsPathDir.exe
/debug
IsPathDir.obj

C:\Tests&gt;cdb IsPathDir.exe

Microsoft (R) Windows Debugger Version 6.8.0004.0 X86
Copyright (c) Microsoft Corporation. All rights reserved.

CommandLine: IsPathDir.exe
Symbol search path is: SRV*c:\symbols*http://msdl.microsoft.com/download/symbols
Executable search path is:
ModLoad: 00400000 00426000   IsPathDir.exe
ModLoad: 7c900000 7c9b4000   ntdll.dll
ModLoad: 7c800000 7c8ff000   C:\WINDOWS\system32\kernel32.dll
ModLoad: 77ea0000 77f16000   C:\WINDOWS\system32\SHLWAPI.dll
ModLoad: 77f50000 77ffb000   C:\WINDOWS\system32\ADVAPI32.dll
ModLoad: 77db0000 77e41000   C:\WINDOWS\system32\RPCRT4.dll
ModLoad: 77e50000 77e97000   C:\WINDOWS\system32\GDI32.dll
ModLoad: 7e360000 7e3f0000   C:\WINDOWS\system32\USER32.dll
ModLoad: 77bf0000 77c48000   C:\WINDOWS\system32\msvcrt.dll
(ea0.de0): Break instruction exception - code 80000003 (first chance)
eax=00241eb4 ebx=7ffde000 ecx=00000004 edx=00000010 esi=00241f48 edi=00241eb4
eip=7c901230 esp=0012fb20 ebp=0012fc94 iopl=0         nv up ei pl nz na po nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000202
ntdll!DbgBreakPoint:
7c901230 cc              int     3
0:000&gt; <font color="#ff0000">g shlwapi!PathIsDirectoryA</font>
ModLoad: 76360000 7637d000   C:\WINDOWS\system32\IMM32.DLL
ModLoad: 62e80000 62e89000   C:\WINDOWS\system32\LPK.DLL
ModLoad: 74d50000 74dbb000   C:\WINDOWS\system32\USP10.dll
eax=009836e0 ebx=7ffde000 ecx=00000001 edx=00422828 esi=0006f4cc edi=7c911970
eip=77ee7538 esp=0012ff6c ebp=0012ff78 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
SHLWAPI!PathIsDirectoryA:
77ee7538 8bff            mov     edi,edi
0:000&gt; p
eax=009836e0 ebx=7ffde000 ecx=00000001 edx=00422828 esi=0006f4cc edi=7c911970
eip=77ee753a esp=0012ff6c ebp=0012ff78 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
SHLWAPI!PathIsDirectoryA+0x2:
77ee753a 55              push    ebp
0:000&gt;
eax=009836e0 ebx=7ffde000 ecx=00000001 edx=00422828 esi=0006f4cc edi=7c911970
eip=77ee753b esp=0012ff68 ebp=0012ff78 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
SHLWAPI!PathIsDirectoryA+0x3:
77ee753b 8bec            mov     ebp,esp
0:000&gt;
eax=009836e0 ebx=7ffde000 ecx=00000001 edx=00422828 esi=0006f4cc edi=7c911970
eip=77ee753d esp=0012ff68 ebp=0012ff68 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
SHLWAPI!PathIsDirectoryA+0x5:
77ee753d 81ec0c020000    sub     esp,20Ch
0:000&gt;
eax=009836e0 ebx=7ffde000 ecx=00000001 edx=00422828 esi=0006f4cc edi=7c911970
eip=77ee7543 esp=0012fd5c ebp=0012ff68 iopl=0         nv up ei pl nz ac pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000216
SHLWAPI!PathIsDirectoryA+0xb:
77ee7543 a180d2f077      mov     eax,dword ptr [SHLWAPI!__security_cookie
0:000&gt;
eax=00007a43 ebx=7ffde000 ecx=00000001 edx=00422828 esi=0006f4cc edi=7c911970
eip=77ee7548 esp=0012fd5c ebp=0012ff68 iopl=0         nv up ei pl nz ac pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000216
SHLWAPI!PathIsDirectoryA+0x10:
77ee7548 56              push    esi
0:000&gt;
eax=00007a43 ebx=7ffde000 ecx=00000001 edx=00422828 esi=0006f4cc edi=7c911970
eip=77ee7549 esp=0012fd58 ebp=0012ff68 iopl=0         nv up ei pl nz ac pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000216
SHLWAPI!PathIsDirectoryA+0x11:
*** WARNING: Unable to verify checksum for IsPathDir.exe
77ee7549 8b7508          mov     esi,dword ptr [ebp+8] ss:0023:0012ff70=0041dc5c
0:000&gt;
eax=00007a43 ebx=7ffde000 ecx=00000001 edx=00422828 esi=0041dc5c edi=7c911970
eip=77ee754c esp=0012fd58 ebp=0012ff68 iopl=0         nv up ei pl nz ac pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000216
SHLWAPI!PathIsDirectoryA+0x14:
77ee754c 85f6            test    esi,esi
0:000&gt;
eax=00007a43 ebx=7ffde000 ecx=00000001 edx=00422828 esi=0041dc5c edi=7c911970
eip=77ee754e esp=0012fd58 ebp=0012ff68 iopl=0         nv up ei pl nz na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000206
SHLWAPI!PathIsDirectoryA+0x16:
77ee754e 8945fc          mov     dword ptr [ebp-4],eax ss:0023:0012ff64=fffffffe
0:000&gt;
eax=00007a43 ebx=7ffde000 ecx=00000001 edx=00422828 esi=0041dc5c edi=7c911970
eip=77ee7551 esp=0012fd58 ebp=0012ff68 iopl=0         nv up ei pl nz na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000206
SHLWAPI!PathIsDirectoryA+0x19:
77ee7551 0f8493000000    je      SHLWAPI!PathIsDirectoryA+0xb2 (77ee75ea) [br=0]
0:000&gt;
eax=00007a43 ebx=7ffde000 ecx=00000001 edx=00422828 esi=0041dc5c edi=7c911970
eip=77ee7557 esp=0012fd58 ebp=0012ff68 iopl=0         nv up ei pl nz na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000206
SHLWAPI!PathIsDirectoryA+0x1f:
77ee7557 56              push    esi
0:000&gt;
eax=00007a43 ebx=7ffde000 ecx=00000001 edx=00422828 esi=0041dc5c edi=7c911970
eip=77ee7558 esp=0012fd54 ebp=0012ff68 iopl=0         nv up ei pl nz na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000206
SHLWAPI!PathIsDirectoryA+0x20:
77ee7558 e85cc0fdff      call    SHLWAPI!PathIsUNCServerA (77ec35b9)
0:000&gt;
eax=00000000 ebx=7ffde000 ecx=00000001 edx=00422828 esi=0041dc5c edi=7c911970
eip=77ee755d esp=0012fd58 ebp=0012ff68 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
SHLWAPI!PathIsDirectoryA+0x25:
77ee755d 85c0            test    eax,eax
0:000&gt;
eax=00000000 ebx=7ffde000 ecx=00000001 edx=00422828 esi=0041dc5c edi=7c911970
eip=77ee755f esp=0012fd58 ebp=0012ff68 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
SHLWAPI!PathIsDirectoryA+0x27:
77ee755f 0f8585000000    jne     SHLWAPI!PathIsDirectoryA+0xb2 (77ee75ea) [br=0]
0:000&gt;
eax=00000000 ebx=7ffde000 ecx=00000001 edx=00422828 esi=0041dc5c edi=7c911970
eip=77ee7565 esp=0012fd58 ebp=0012ff68 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
SHLWAPI!PathIsDirectoryA+0x2d:
77ee7565 56              push    esi
0:000&gt;
eax=00000000 ebx=7ffde000 ecx=00000001 edx=00422828 esi=0041dc5c edi=7c911970
eip=77ee7566 esp=0012fd54 ebp=0012ff68 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
SHLWAPI!PathIsDirectoryA+0x2e:
77ee7566 e812feffff      call    SHLWAPI!PathIsUNCServerShareA (77ee737d)
0:000&gt;
eax=00000000 ebx=7ffde000 ecx=00000001 edx=00422828 esi=0041dc5c edi=7c911970
eip=77ee756b esp=0012fd58 ebp=0012ff68 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
SHLWAPI!PathIsDirectoryA+0x33:
77ee756b 85c0            test    eax,eax
0:000&gt;
eax=00000000 ebx=7ffde000 ecx=00000001 edx=00422828 esi=0041dc5c edi=7c911970
eip=77ee756d esp=0012fd58 ebp=0012ff68 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
SHLWAPI!PathIsDirectoryA+0x35:
77ee756d 0f8486000000    je      SHLWAPI!PathIsDirectoryA+0xc1 (77ee75f9) [br=1]
0:000&gt;
eax=00000000 ebx=7ffde000 ecx=00000001 edx=00422828 esi=0041dc5c edi=7c911970
eip=77ee75f9 esp=0012fd58 ebp=0012ff68 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
SHLWAPI!PathIsDirectoryA+0xc1:
77ee75f9 56              push    esi
0:000&gt;
eax=00000000 ebx=7ffde000 ecx=00000001 edx=00422828 esi=0041dc5c edi=7c911970
eip=77ee75f9 esp=0012fd58 ebp=0012ff68 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
SHLWAPI!PathIsDirectoryA+0xc1:
77ee75f9 56              push    esi
0:000&gt;
eax=00000000 ebx=7ffde000 ecx=00000001 edx=00422828 esi=0041dc5c edi=7c911970
eip=77ee75fa esp=0012fd54 ebp=0012ff68 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
SHLWAPI!PathIsDirectoryA+0xc2:
77ee75fa ff15d411ea77    <font color="#ff0000">call    dword ptr [SHLWAPI!_imp__GetFileAttributesA (77ea11d4)]</font>
0:000&gt;
eax=00000011 ebx=7ffde000 ecx=7c91056d edx=00140608 esi=0041dc5c edi=7c911970
eip=77ee7600 esp=0012fd58 ebp=0012ff68 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
SHLWAPI!PathIsDirectoryA+0xc8:
77ee7600 83f8ff          cmp     eax,0FFFFFFFFh
0:000&gt;
eax=00000011 ebx=7ffde000 ecx=7c91056d edx=00140608 esi=0041dc5c edi=7c911970
eip=77ee7603 esp=0012fd58 ebp=0012ff68 iopl=0         nv up ei pl nz ac pe cy
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000217
SHLWAPI!PathIsDirectoryA+0xcb:
77ee7603 74e5            je      SHLWAPI!PathIsDirectoryA+0xb2 (77ee75ea) [br=0]
0:000&gt;
eax=00000011 ebx=7ffde000 ecx=7c91056d edx=00140608 esi=0041dc5c edi=7c911970
eip=77ee7605 esp=0012fd58 ebp=0012ff68 iopl=0         nv up ei pl nz ac pe cy
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000217
SHLWAPI!PathIsDirectoryA+0xcd:
77ee7605 83e010          <font color="#ff0000">and     eax,10h</font>
0:000&gt;
eax=00000010 ebx=7ffde000 ecx=7c91056d edx=00140608 esi=0041dc5c edi=7c911970
eip=77ee7608 esp=0012fd58 ebp=0012ff68 iopl=0         nv up ei pl nz na po nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000202
SHLWAPI!PathIsDirectoryA+0xd0:
77ee7608 ebe2            jmp     SHLWAPI!PathIsDirectoryA+0xb4 (77ee75ec)
0:000&gt;
eax=00000010 ebx=7ffde000 ecx=7c91056d edx=00140608 esi=0041dc5c edi=7c911970
eip=77ee75ec esp=0012fd58 ebp=0012ff68 iopl=0         nv up ei pl nz na po nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000202
SHLWAPI!PathIsDirectoryA+0xb4:
77ee75ec 8b4dfc          mov     ecx,dword ptr [ebp-4] ss:0023:0012ff64=00007a43
0:000&gt;
eax=00000010 ebx=7ffde000 ecx=00007a43 edx=00140608 esi=0041dc5c edi=7c911970
eip=77ee75ef esp=0012fd58 ebp=0012ff68 iopl=0         nv up ei pl nz na po nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000202
SHLWAPI!PathIsDirectoryA+0xb7:
77ee75ef 5e              pop     esi
0:000&gt;
eax=00000010 ebx=7ffde000 ecx=00007a43 edx=00140608 esi=0006f4cc edi=7c911970
eip=77ee75f0 esp=0012fd5c ebp=0012ff68 iopl=0         nv up ei pl nz na po nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000202
SHLWAPI!PathIsDirectoryA+0xb8:
77ee75f0 e82bcafbff      call    SHLWAPI!__security_check_cookie (77ea4020)
0:000&gt;
eax=00000010 ebx=7ffde000 ecx=00007a43 edx=00140608 esi=0006f4cc edi=7c911970
eip=77ee75f5 esp=0012fd5c ebp=0012ff68 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
SHLWAPI!PathIsDirectoryA+0xbd:
77ee75f5 c9              leave
0:000&gt;
<font color="#ff0000">eax=00000010</font> ebx=7ffde000 ecx=00007a43 edx=00140608 esi=0006f4cc edi=7c911970
eip=77ee75f6 esp=0012ff6c ebp=0012ff78 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
SHLWAPI!PathIsDirectoryA+0xbe:
77ee75f6 c20400          ret     4
0:000&gt;
eax=00000010 ebx=7ffde000 ecx=00007a43 edx=00140608 esi=0006f4cc edi=7c911970
eip=0040101f esp=0012ff74 ebp=0012ff78 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
IsPathDir!main+0xf:
0040101f 8945fc          mov     dword ptr [ebp-4],eax ss:0023:0012ff74=00000001
0:000&gt;
eax=00000010 ebx=7ffde000 ecx=00007a43 edx=00140608 esi=0006f4cc edi=7c911970
eip=00401022 esp=0012ff74 ebp=0012ff78 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
IsPathDir!main+0x12:
00401022 8b45fc          mov     eax,dword ptr [ebp-4] ss:0023:0012ff74=00000010
0:000&gt;
eax=00000010 ebx=7ffde000 ecx=00007a43 edx=00140608 esi=0006f4cc edi=7c911970
eip=00401025 esp=0012ff74 ebp=0012ff78 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
IsPathDir!main+0x15:
00401025 50              push    eax
0:000&gt;
eax=00000010 ebx=7ffde000 ecx=00007a43 edx=00140608 esi=0006f4cc edi=7c911970
eip=00401026 esp=0012ff70 ebp=0012ff78 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
IsPathDir!main+0x16:
00401026 6868dc4100      push    offset IsPathDir!__xt_z+0x12c (0041dc68)
0:000&gt;
eax=00000010 ebx=7ffde000 ecx=00007a43 edx=00140608 esi=0006f4cc edi=7c911970
eip=0040102b esp=0012ff6c ebp=0012ff78 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
IsPathDir!main+0x1b:
0040102b e81a000000      call    IsPathDir!printf (0040104a)
0:000&gt;
<font color="#ff0000">Resultado: 16.</font>
eax=0000000f ebx=7ffde000 ecx=004010e5 edx=004228b8 esi=0006f4cc edi=7c911970
eip=00401030 esp=0012ff6c ebp=0012ff78 iopl=0         nv up ei ng nz ac pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000296
IsPathDir!main+0x20:
00401030 83c408          add     esp,8
0:000&gt;</pre>
<p>Ou seja, para pastas locais a função simplesmente usa a conhecidíssima <a href="http://msdn.microsoft.com/en-us/library/aa364944(VS.85).aspx" title="MSDN">GetFileAttributes</a>, que retorna o flag 0x10 setado caso se trate de uma pasta, de acordo com a documentação:</p>
<p>"The attributes can be one or more of the following values.</p>
<pre>Return code/value              Description</pre>
<pre>
FILE_ATTRIBUTE_ARCHIVE         A file or directory that is an archive file or directory.
32
0x20</pre>
<pre>FILE_ATTRIBUTE_COMPRESSED      A file or directory that is compressed.
2048
0x800
...

<font color="#ff0000">FILE_ATTRIBUTE_DIRECTORY       The handle that identifies a directory.
16
0x10"</font></pre>
<p>Aqui termina nossa dúvida sobre o pequenino bug na documentação. E isso nos lembra também que é sempre bom comparar as coisas da melhor maneira possível. E essa melhor maneira em se tratando de ifs é supor apenas dois valores binário: ou é zero ou é não-zero.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.caloni.com.br/blog/archives/retorno-do-pathisdirectory/feed</wfw:commentRss>
		</item>
		<item>
		<title>De volta à tona</title>
		<link>http://www.caloni.com.br/blog/archives/de-volta-a-tona</link>
		<comments>http://www.caloni.com.br/blog/archives/de-volta-a-tona#comments</comments>
		<pubDate>Sun, 07 Sep 2008 21:00:14 +0000</pubDate>
		<dc:creator>Wanderley Caloni</dc:creator>
		
		<category><![CDATA[Nothing]]></category>

		<guid isPermaLink="false">http://www.caloni.com.br/blog/archives/de-volta-a-tona</guid>
		<description><![CDATA[Depois dessas duas semanas de férias forçadas volto a escrever-vos neste humilde blogue. Houve um pequeno problema com o script que insere um arquivo de código-fonte dentro da página e ele comeu todos os meus bits disponíveis por mês na hospedagem do saite.
Entre os próximos artigos estão um bug na função PathIsDirectory, algumas traduções não-ortodoxas [...]]]></description>
			<content:encoded><![CDATA[<p>Depois dessas duas semanas de férias forçadas volto a escrever-vos neste humilde blogue. Houve um pequeno problema com o script que insere um arquivo de código-fonte dentro da página e ele comeu todos os meus bits disponíveis por mês na hospedagem do saite.</p>
<p>Entre os próximos artigos estão um bug na função <a href="http://msdn.microsoft.com/en-us/library/bb773621(VS.85).aspx" title="MSDN">PathIsDirectory</a>, algumas traduções não-ortodoxas para <em>handle</em>, <em>thread</em> e <em>dead lock</em>, a estrutura dos códigos de erro do Windows e algumas ruminações sobre como fazer um script de <em>build</em>.</p>
<p>Até lá.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.caloni.com.br/blog/archives/de-volta-a-tona/feed</wfw:commentRss>
		</item>
		<item>
		<title>ProcessLeaker</title>
		<link>http://www.caloni.com.br/blog/archives/processleaker</link>
		<comments>http://www.caloni.com.br/blog/archives/processleaker#comments</comments>
		<pubDate>Thu, 21 Aug 2008 09:00:16 +0000</pubDate>
		<dc:creator>Wanderley Caloni</dc:creator>
		
		<category><![CDATA[Debugging]]></category>

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

O artigo anterior mostrava como detectar o leak de um processo gerado pela retenção e não-liberação de handles para o Windows Explorer. O problema fora causado por um serviço malcriado. No entanto, a título de demonstração, criei um pequeno programinha sem-vergonha para fazer as coisas parecerem difíceis. No entanto o programa é bem fácil:
#include &#60;windows.h&#62;
#include [...]]]></description>
			<content:encoded><![CDATA[

<p>O <a href="http://www.caloni.com.br/blog/archives/os-processos-fantasma">artigo anterior</a> mostrava como detectar o leak de um processo gerado pela retenção e não-liberação de handles para o Windows Explorer. O problema fora causado por um serviço malcriado. No entanto, a título de demonstração, criei um pequeno programinha sem-vergonha para fazer as coisas parecerem difíceis. No entanto o programa é bem fácil:</p>
<p><pre><span style="color: #006600;">#include &lt;windows.h&gt;</span>
<span style="color: #006600;">#include &lt;stdio.h&gt;</span>
&nbsp;
&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 pid;
&nbsp;
	<span style="color: #0000ff;">while</span><span style="color: #000000; font-weight: bold;">&#40;</span> <span style="color: #0000ff;">scanf</span><span style="color: #000000; font-weight: bold;">&#40;</span><span style="color: #666666;">"%d"</span>, &amp;pid<span style="color: #000000; font-weight: bold;">&#41;</span> == <span style="color: #000000;">1</span> <span style="color: #000000; font-weight: bold;">&#41;</span>
	<span style="color: #000000; font-weight: bold;">&#123;</span>
		HANDLE proc = OpenProcess<span style="color: #000000; font-weight: bold;">&#40;</span>SYNCHRONIZE, <span style="color: #0000ff;">FALSE</span>, pid<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>Para usá-lo, basta abrir um Gerenciador de Tarefas com opção de exibir o PID dos processos.</p>
<p><a href="http://www.caloni.com.br/blog/wp-content/uploads/taskmanagerpid.PNG" title="taskmanagerpid.PNG"><img src="http://www.caloni.com.br/blog/wp-content/uploads/taskmanagerpid.PNG" alt="taskmanagerpid.PNG" /></a></p>
<p>A partir daí, é só criar e matar várias instâncias do explorer.exe. Antes de matar um, digite o PID do novo processo no ProcessLeaker.</p>
<p><img src="http://www.caloni.com.br/blog/wp-content/uploads/processleaker.PNG" alt="processleaker.PNG" /></p>
<p>Para listar os processos perdidos, basta usar o comando "!process 0 0" no WinDbg depurando em kernel. O resto você já sabe.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.caloni.com.br/blog/archives/processleaker/feed</wfw:commentRss>
		</item>
	</channel>
</rss>
