Archive for July, 2007

ExAllocatePool with Tagging

19 de July de 2007

Meu amigo Lesma sempre me foi uma excelente referência sobre uma maneira diferente de ver as coisas. Ele normalmente tem um ponto de vista diferente do meu, e sempre aprendo com estes outros pontos de vista. Este post será diferente do que estão acostumados a ver por aqui. Wanderley introduziu o assunto “Como ser um melhor programador nos próximos seis meses” e nos trouxe este novo ponto de vista (pelo menos para mim) de ver os blogs, conhecido como Tagging. Aqui segue a minha resposta.

Não posso dizer que nos próximos seis meses tudo vai ser diferente, que eu realmente vou me esforçar ao máximo para me tornar um programador melhor. Creio que minha resposta seja parecida com a resposta que o Strauss nos deu, mas não igual.

Como alguns de vocês sabem, além jornada de trabalho na Open, ainda enfrento a Universidade para concluir minha formação em Engenharia da Computação. Este curso tem me trazido assuntos novos com relação a micro processamento, sistemas embutidos, arquitetura de computadores e outros assuntos diferentes de programação Windows em C/C++. Posso dizer que isso tem aberto um pouco meu leque de oportunidades para aprender coisas novas. Desenvolver drivers é, além de programar, estabelecer a comunicação entre dois universos próximos, mas praticamente desconhecidos entre si. Normalmente que faz muito bem um lado, não consegue fazer o outro tão bem. Isso é natural. Já conheço um pouco de software, e a cada seis meses que se passam, vou conhecendo algumas coisas novas sobre hardware. Conhecendo melhor o hardware, creio poder entender e programar melhor o sistema operacional que interage com ele.

Por falar em coisas novas, este mês me peguei comprando um livro sobre device drivers para Linux. Tenho sido Microsoft desde sempre. Obviamente estou me referindo ao aspecto profissional. Meus tempos de MSX e CP200 exercem a mesma influência que meu jardim de infância excerce sobre meu cirrículo. O livro ainda não chegou, mas com certeza vai alimentar minha base de dados sobre interação Software/Hardware e me permitir traçar um paralelo entre as duas plataformas de desenvolvimento Windows/Linux, e assim, poder entender melhor o que eles tem em comum, tanto com relação à interação Software/Hardware quanto aos conceitos de sistemas operacionais.

Um amigo uma vez me disse que uma das melhores maneiras de aprender é ensinando. Já escrevo este blog a quase 1 ano e tenho aprendido bastante com ele. Escrever sobre algumas coisas que eu considerava simples me fez dar mais uma olhada e ver que ainda existem mais e mais detalhes sobre o assunto. Desta forma, acabo aprendendo os detalhes que foram perdidos à primeira vista. Algumas palestras que tenho dado na empresa e o curso de device drivers são um Boost para esta maneira de aprender. Confesso que estou gostando disso.

Concluindo e resumindo, vou continuar estudando para terminar minha faculdade, ler sobre Linux e continuar blogando e sendo questionado sobre os assuntos. Esse assunto é muito divertido para programadores, mas não podemos nos esquecer que também somos maridos, filhos, irmãos, amigos e assim por diante. Este post pode lhe oferecer aquele ânimo para sair estudando tudo e dedicar todo o seu tempo disponível em prol de ser um programador exemplar. Andar de bicicleta e ir à praia também fazem parte da formação de programadores excelentes.

Aprecie com moderação. 😉
Até mais…

Bug em meu driver de Boot. Já posso formatar?

16 de July de 2007

Escrever drivers é uma tarefa que deve ser feita com um pouco de cuidado. Afinal, qualquer situação mal resolvida entre o seu código e o sistema operacional resultará em uma bela tela azul. Mas para tudo tem remédio nessa vida e felizmente Deus criou o depurador para enfrentar essas situações. Encontrando o problema, é só trocar o arquivo .sys e pronto. Só trocar o arquivo significa esperar que a máquina fique em um estado estável, substituir ao arquivo no sistema e reiniciar a máquina. Mas a vida é uma caixinha de surpresas e por encreça que parível, a maioria dos drivers que escrevemos é iniciado automagicamente. Bom, nesse caso é só torcer então para que o erro não aconteça até que o driver seja substituído. Caso contrário teríamos que utilizar recursos como colocar a HD da máquina vítima em outro sistema e substituir o driver doente, ou na falta de outro sistema, utilizar o console de recuperação do XP para evitar do seu driver subir. Então é só torcer para que ele não seja um filtro para algo importante como disco, vídeo ou File System. Sabe como é, se o filtro não sobe, o driver principal também não. Resumindo, existe uma série de malabarismos que você pode inventar para substituir um driver de carga automática que esteja com bug. Mas será que não existe algo que não dependa tanto da sorte ou mesmo da criatividade de cada um? Hoje vou falar um pouco sobre o sistema de substituição de drivers com WinDbg.

Mapeando arquivos de drivers

Você pode mapear os arquivos de drivers para que o WinDbg substitua o driver no momento em que este for carregado. Isso não é lindo? Para que isso ocorra, você precisa utilizar o comando .kdfiles. Com este comando, você faz um vínculo entre o driver que roda na máquina Target e o driver que foi corrigido. Uma das maneiras de fazer isso é inicialmente criando um arquivo que relacione estes dois drivers. Este arquivo deve ser um arquivo texto simples onde a sintaxe é a mostrada abaixo. Este arquivo pode ter qualquer nome e extensão.

map 
\??\C:\Windows\System32\drivers\MeuDriver.sys 
C:\Pasta_Do_Driver_Novo\MeuDriver.sys

A palavra map marca o início de um mapeamento, isso não muda. A linha seguinte é o caminho do arquivo do driver que deve ser substituído. Esta linha deve ter o mesmo formato do utilizado no valor ImagePath na chave do driver que fica no registro. A última linha é o caminho do driver novo. Este caminho pode ser na própria máquina Host ou mesmo na rede.

Este mapeamento funciona apenas no Windows XP ou superior, na máquina Target obviamente. Se você ainda não está acostumado com termos Host e Target, dê uma olhada neste post.

Depois de criado o arquivo, você utiliza o WinDbg para lançar o seguinte comando:

kd>.kdfiles C:\Pasta\MeuMap.txt

A partir desse momento, toda vez que o driver for carregado pelo sistema, o Kernel verifica se este arquivo está mapeado no depurador, e se estiver, o WinDbg envia o novo driver pelo meio de conexão entre eles, seja serial, firewire ou USB. Para arquivos grandes, recomenda-se utilizar firewire. Entenda que o arquivo é substituído no disco da máquina Target pela versão nova. Isso significa que nas próximas inicializações nosso driver novo ainda será carregado, mesmo que não tenhamos o debugger atachado ao sistema.

Será que funciona mesmo?

Para tornar as coisas um pouco mais claras, vamos ver um exemplo prático. Para isso vamos precisar de um fonte de driver bem simples, para não dizer inútil, que pode ser encontrado aqui. Vamos alterar a função DriverEntry de forma que fique como abaixo:

NTSTATUS DriverEntry(IN PDRIVER_OBJECT  pDriverObject,
                     IN PUNICODE_STRING pusRegistryPath)
{
    //-f--> Vamos utilizar __DATE__ e __TIME__ para que tenhamos
    //      uma versão nova de driver a cada rebuild
    DbgPrint("Este driver foi compilado em "__DATE__" "__TIME__"\n");
 
...

Compilamos uma versão inicial e o instalamos na maquina Target da maneira que você achar melhor, mas vamos admitir que depois de instalado teremos o registro como na figura abaixo.

Se iniciarmos o driver, teremos algo parecido com a string abaixo na saída do depurador:

Este driver foi compilado em Jul 16 2007 00:04:03

Agora vamos criar nosso arquivo de mapeamento. Aqui vou salvá-lo como Z:\Sources\DriverEntry\Useless\map.txt. Seguindo o formado de como o driver foi registrado no registro, nosso arquivo de mapeamento deveria ter o seguinte conteúdo:

map
\??\C:\Windows\System32\drivers\Useless.sys
Z:\Sources\DriverEntry\Useless\objchk_wxp_x86\i386\Useless.sys

Notem que a pasta onde salvei o meu arquivo map.txt é o mesmo onde os fontes do driver estão. Isso é apenas por uma questão de organização. O arquivo de mapeamento poderia estar em qualquer pasta. Em seguida utilizamos o comando .kdfiles como mostra abaixo. Notem que listamos os mapeamentos existentes simplesmente utilizando o mesmo comando sem qualquer parâmetro.

kd> .kdfiles Z:\Sources\DriverEntry\Useless\map.txt
KD file assocations loaded from 'Z:\Sources\DriverEntry\Useless\map.txt'
 
kd> .kdfiles
KD file assocations loaded from 'Z:\Sources\DriverEntry\Useless\map.txt'
\??\C:\Windows\System32\drivers\Useless.sys ->
Z:\Sources\DriverEntry\Useless\objchk_wxp_x86\i386\Useless.sys

Na seqüência, vamos dar um Rebuild no driver (isso deveria mudar aquele time stamp) e vamos reiniciar o driver. Se tudo estiver certo aí do seu lado, você deveria ter uma saída com um time stamp diferente do que tínhamos antes.

kd> g
Mas já? Eu nem fiz nada...
KD: Accessing 'Z:\Sources\DriverEntry\Useless\objchk_wxp_x86\i386\Useless.sys'
 (\??\C:\Windows\system32\drivers\Useless.sys)
  File size 2K.
MmLoadSystemImage: Pulled \??\C:\Windows\system32\drivers\Useless.sys from kd
Este driver foi compilado em Jul 16 2007 00:17:04

Bom, se isso funciona em um driver com start manual, então com o automático também deveria funcionar. Para vermos isso, mude o start do seu driver para System ou Automatic, dê um Rebuild mais uma vêz no driver, e por fim vamos reiniciar a máquina. Quando o driver for carregado, deveremos ter a substituição automática de sua imagem na sua carga. No WinDbg teremos o seguinte:

Connected to Windows XP 2600 x86 compatible target, ptr64 FALSE
Kernel Debugger connection established.
Symbol search path is: SRV*c:\websymbols*http://msdl.microsoft.com/download/symbols
Executable search path is: 
Windows XP Kernel Version 2600 UP Free x86 compatible
Built by: 2600.xpsp_sp2_gdr.070227-2254
Kernel base = 0x804d7000 PsLoadedModuleList = 0x805533a0
System Uptime: not available
KD: Accessing 'Z:\Sources\DriverEntry\Useless\objchk_wxp_x86\i386\Useless.sys'
 (\??\C:\Windows\system32\drivers\Useless.sys)
  File size 2K.
MmLoadSystemImage: Pulled \??\C:\Windows\system32\drivers\Useless.sys from kd
Este driver foi compilado em Jul 16 2007 00:25:38

E não é que funciona mesmo! Mas e se meu driver for um driver com start do tipo Boot? Isso significa que a imagem do driver vai ser carregada antes mesmo da conexão com o WinDbg ser estabelecida. Vocês já ouviram falar que o que não tem remédio, remediado está? Felizmente isso não se aplica aqui ainda. Existe uma maneira de fazer com que mesmo os drivers de Boot sejam mapeados e substituídos.

Mapeando drivers de Boot

Para estabelecer uma conexão com o WinDbg, precisaremos substituir o loader do sistema por uma versão especial. Esta versão faz esta conexão com o Kernel Debugger antes mesmo que arquivo Boot.ini seja lido. Por esta razão, os parâmetros de conexão são fixos com porta COM1 e baudrate de 115200. Esta versão do loader é encontrada no diretório C:\WinDDk\3790\debug do DDK com o nome de ntldr_dbg. Este arquivo deve substituir a versão original do loader do sistema que fica no raiz do drive de boot com o nome ntldr. A versão debug deve ficar com o mesmo nome do loader original.

Antes de reiniciar o sistema, devemos mudar o start do driver para Boot e remover o valor ImagePath do registro. Como vocês devem saber, drivers de boot não têm esse luxo de utilizar caminhos que tenham letras de unidades e outras frescuras. Ao final das alterações, deveríamos ter o registro como mostra abaixo.


Como falei anteriormente, o formato do caminho do arquivo do driver deve ser o mesmo de como está no registro, mas sabendo que agora não há mais caminho no registro, devemos adotar o mesmo formado adotado pelo sistema. Ah tá! O mesmo formato. E qual seria? Para ver este formato basta reiniciar o sistema com o loader debug, o que deve nos dar a seguinte tela no boot do sistema.

Este é o momento de conectar com o Windbg utilizando os parâmetros pré-determinados de conexão. Isso deveria nos resultar a seguinte saída no depurador:

Microsoft (R) Windows Debugger  Version 6.7.0005.1
Copyright (c) Microsoft Corporation. All rights reserved.
 
Opened \\.\pipe\com_1
Waiting to reconnect...
BD: Boot Debugger Initialized
BD: osloader.exe base address 00400000
Connected to Windows Boot Debugger 3790 x86 compatible target, ptr64 FALSE
Kernel Debugger connection established.
Symbol search path is: SRV*c:\websymbols*http://msdl.microsoft.com/download/symbols
Executable search path is: 
Windows Boot Debugger Kernel Version 3790 UP Checked x86 compatible
Primary image base = 0x00000000 Loaded module list = 0x00000000
System Uptime: not available
The call to LoadLibrary(bootext) failed, Win32 error 0n2
    "The system cannot find the file specified."
Please check your debugger configuration and/or network access.

Agora é apresentado o menu de seleção do Boot.ini. Selecione sua opção e continue carregando o sistema. Deve ser apresentada a lista de drivers de Boot, que são os drivers que são carregados antes do primeiro breakpoint que o debugger pode parar.

BD: \WINDOWS\system32\ntoskrnl.exe base address 804EA000
BD: \WINDOWS\system32\hal.dll base address 806FF000
BD: \WINDOWS\system32\KDCOM.DLL base address 80720000
BD: \WINDOWS\system32\BOOTVID.dll base address 80010000
BD: \WINDOWS\system32\DRIVERS\ACPI.sys base address 80124000
BD: \WINDOWS\system32\DRIVERS\WMILIB.SYS base address 80001000
BD: \WINDOWS\system32\DRIVERS\pci.sys base address 80062000
BD: \WINDOWS\system32\DRIVERS\isapnp.sys base address 80003000
BD: \WINDOWS\system32\DRIVERS\compbatt.sys base address 8000C000
BD: \WINDOWS\system32\DRIVERS\BATTC.SYS base address 80013000
BD: \WINDOWS\system32\DRIVERS\intelide.sys base address 80017000
BD: \WINDOWS\system32\DRIVERS\PCIIDEX.SYS base address 80019000
BD: \WINDOWS\System32\Drivers\MountMgr.sys base address 80152000
BD: \WINDOWS\system32\DRIVERS\ftdisk.sys base address 8015D000
BD: \WINDOWS\System32\drivers\dmload.sys base address 80073000
BD: \WINDOWS\System32\drivers\dmio.sys base address 8017C000
BD: \WINDOWS\System32\Drivers\PartMgr.sys base address 801A2000
BD: \WINDOWS\System32\Drivers\VolSnap.sys base address 801A7000
BD: \WINDOWS\system32\DRIVERS\atapi.sys base address 801B4000
BD: \WINDOWS\system32\DRIVERS\vmscsi.sys base address 801CC000
BD: \WINDOWS\system32\DRIVERS\SCSIPORT.SYS base address 801CF000
BD: \WINDOWS\system32\DRIVERS\disk.sys base address 801E7000
BD: \WINDOWS\system32\DRIVERS\CLASSPNP.SYS base address 801F0000
BD: \WINDOWS\system32\DRIVERS\fltMgr.sys base address 801FD000
BD: \WINDOWS\system32\DRIVERS\sr.sys base address 8021D000
BD: \WINDOWS\System32\Drivers\KSecDD.sys base address 8022F000
BD: \WINDOWS\System32\Drivers\Ntfs.sys base address 80246000
BD: \WINDOWS\System32\Drivers\NDIS.sys base address 802D3000
BD: \WINDOWS\System32\Drivers\Useless.sys base address 8000F000
BD: \WINDOWS\System32\Drivers\Mup.sys base address 80300000
BD: \WINDOWS\system32\DRIVERS\agp440.sys base address 8031B000
Shutdown occurred...unloading all symbol tables.
Waiting to reconnect...

Aqui a conexão com o loader é encerrada. Uma nova conexão seria estabelecida caso você tivesse selecionado a entrada de Debug do Boot.ini, mas o que temos que notar aqui é o formato utilizado para a carga dos drivers de boot pelo sistema. Notem que entre os drivers da lista acima está o nosso driver de teste. Vamos adotar este mesmo formato em nosso arquivo de mapeamento.

map
\WINDOWS\System32\Drivers\Useless.sys
Z:\Sources\DriverEntry\Useless\objchk_wxp_x86\i386\Useless.sys

Depois de modificar o arquivo de mapeamento e salvar seu conteúdo em disco, devemos atualizar o WinDbg para que ele pegue esta mudança. Em seguida vamos reiniciar o sistema.

kd> .kdfiles Z:\Sources\DriverEntry\Useless\map.txt
KD file assocations loaded from 'Z:\Sources\DriverEntry\Useless\map.txt'
 
kd> .reboot
Shutdown occurred...unloading all symbol tables.
Waiting to reconnect...
BD: Boot Debugger Initialized
Connected to Windows Boot Debugger 3790 x86 compatible target, ptr64 FALSE
Kernel Debugger connection established.  (Initial Breakpoint requested)
Symbol search path is: SRV*c:\websymbols*http://msdl.microsoft.com/download/symbols
Executable search path is: 
Module List address is NULL - debugger not initialized properly.
WARNING: .reload failed, module list may be incomplete
KdDebuggerData.KernBase < SystemRangeStart
Windows Boot Debugger Kernel Version 3790 UP Checked x86 compatible
Primary image base = 0x00000000 Loaded module list = 0x00000000
System Uptime: not available
The call to LoadLibrary(bootext) failed, Win32 error 0n2
    "The system cannot find the file specified."
Please check your debugger configuration and/or network access.

A mesma seqüência de mensagens acontece, mas desta vez, o mapeamento está feito como se deve e teremos a seguinte saída quando os drivers de boot forem carregados.

BD: osloader.exe base address 00400000
BD: \WINDOWS\system32\ntoskrnl.exe base address 804EA000
BD: \WINDOWS\system32\hal.dll base address 806FF000
BD: \WINDOWS\system32\KDCOM.DLL base address 80720000
BD: \WINDOWS\system32\BOOTVID.dll base address 80010000
BD: \WINDOWS\system32\DRIVERS\ACPI.sys base address 80124000
BD: \WINDOWS\system32\DRIVERS\WMILIB.SYS base address 80001000
BD: \WINDOWS\system32\DRIVERS\pci.sys base address 80062000
BD: \WINDOWS\system32\DRIVERS\isapnp.sys base address 80003000
BD: \WINDOWS\system32\DRIVERS\compbatt.sys base address 8000C000
BD: \WINDOWS\system32\DRIVERS\BATTC.SYS base address 80013000
BD: \WINDOWS\system32\DRIVERS\intelide.sys base address 80017000
BD: \WINDOWS\system32\DRIVERS\PCIIDEX.SYS base address 80019000
BD: \WINDOWS\System32\Drivers\MountMgr.sys base address 80152000
BD: \WINDOWS\system32\DRIVERS\ftdisk.sys base address 8015D000
BD: \WINDOWS\System32\drivers\dmload.sys base address 80073000
BD: \WINDOWS\System32\drivers\dmio.sys base address 8017C000
BD: \WINDOWS\System32\Drivers\PartMgr.sys base address 801A2000
BD: \WINDOWS\System32\Drivers\VolSnap.sys base address 801A7000
BD: \WINDOWS\system32\DRIVERS\atapi.sys base address 801B4000
BD: \WINDOWS\system32\DRIVERS\vmscsi.sys base address 801CC000
BD: \WINDOWS\system32\DRIVERS\SCSIPORT.SYS base address 801CF000
BD: \WINDOWS\system32\DRIVERS\disk.sys base address 801E7000
BD: \WINDOWS\system32\DRIVERS\CLASSPNP.SYS base address 801F0000
BD: \WINDOWS\system32\DRIVERS\fltMgr.sys base address 801FD000
BD: \WINDOWS\system32\DRIVERS\sr.sys base address 8021D000
BD: \WINDOWS\System32\Drivers\KSecDD.sys base address 8022F000
BD: \WINDOWS\System32\Drivers\Ntfs.sys base address 80246000
BD: \WINDOWS\System32\Drivers\NDIS.sys base address 802D3000
KD: Accessing 'Z:\Sources\DriverEntry\Useless\objchk_wxp_x86\i386\Useless.sys'
 (\WINDOWS\System32\Drivers\Useless.sys)
  File size 2K.BD: Loaded remote file \WINDOWS\System32\Drivers\Useless.sys
 
BlLoadImageEx: Pulled \WINDOWS\System32\Drivers\Useless.sys from Kernel Debugger
BD: \WINDOWS\System32\Drivers\Useless.sys base address 8000F000
BD: \WINDOWS\System32\Drivers\Mup.sys base address 80300000
BD: \WINDOWS\system32\DRIVERS\agp440.sys base address 8031B000
Shutdown occurred...unloading all symbol tables.
Waiting to reconnect...

E mais tarde, nossa prova de que o arquivo foi substituído com sucesso.

Connected to Windows XP 2600 x86 compatible target, ptr64 FALSE
Kernel Debugger connection established.  (Initial Breakpoint requested)
Symbol search path is: SRV*c:\websymbols*http://msdl.microsoft.com/download/symbols
Executable search path is: 
Windows XP Kernel Version 2600 UP Free x86 compatible
Built by: 2600.xpsp_sp2_gdr.070227-2254
Kernel base = 0x804ea000 PsLoadedModuleList = 0x8056d620
System Uptime: not available
Este driver foi compilado em Jul 16 2007 01:18:53

Eu lhe garanto que isso ainda poderia salvar sua vida se você tivesse um filtro de File System com um bug na DriverEntry em uma máquina de cliente. A expressão de pânico do cliente quando vê a máquina dele reiniciando em um loop infinito é interessante, mas manter seu emprego é um pouco mais interessante.

Até mais,
[]s.

Quem não tem cão caça com DSF

10 de July de 2007

Vocês já devem estar cansados de ler que a OSR tem kits de hardware para treinamento de construção de drivers para USB e PCI. É realmente muito frustrante querer aprender a desenvolver drivers que controlam placas sem ao menos ter uma por perto. Mas sou pobre pobre pobre de marré marré marré e não tenho grana pra ficar comprando estes brinquedinhos importados. Na verdade eu também engoli meio quadrado quando tive que ir até a agência dos correios buscar os dois kits que comprei e pagar uma tributação simbólica de R$ 319,46 sem contar com o custo dos kits. Bem, este é um ponto.

Admitindo que você já é um programador experiente e que já sabe fazer drivers para dispositivos USB com um olho amarrado nas costas, imagine que você tenha que escrever um driver para um dispositivo USB que ainda não está pronto. Ou seja, você tem a especificação, conhece as características dele, mas de fato o dispositivo ainda não está pronto para você fazer os testes que você precisa. Neste caso, o kit de treinamento também não ajudaria muito. Este é outro ponto.

Unindo estes pontos vemos que estamos perdidos mesmo e que o negócio é vender água de coco na praia.

Uma alternativa considerável

Pesando nestes mesmos pontos, a Microsoft desenvolveu o Device Simulation Framework for USB Devices. Este framework é composto de, entre outros componentes, um driver que é instalado em sua máquina de teste e que passa a simular uma controladora USB. Este driver é um Lower Filter dos drivers de controladores USB do Windows. Ele intercepta as interações que o Windows faz com o verdadeiro hardware e simula interrupções de hardware. Do ponto de vista do driver, não há nenhuma diferença entre o DSF e dispositivos reais.

Mas como o framework simularia um dispositivo USB que ele não conhece? Na verdade, o framework redireciona estas interações para componentes em User Mode que podem ser escritos por você em qualquer linguagem que possa usar COM. Desta forma, você pode controlar o comportameto do dispositivo que está sendo simulado. Observem a figura que peguei emprestado da página do MSDN para que vocês tenham uma visão mais clara de como estes componentes estão organizados.

Instalando o DSF

O DSF vem no ISO do WDK que você baixa da Microsoft e só pode ser instalado em Windows XP SP2 ou superior (incluindo plataformas x64). Quando você instala o WDK em sua máquina, o DSF não é instalado. Você precisa instalá-lo a parte. Os arquivos dsfx86runtime.msi e dsfx64runtime.msi, responsáveis pela instalação, são encontrados na pasta \dsf do ISO de instalação. A instalação do framework é extremamente simples, mas você só consegue ver alguma coisa quando, depois de instalado, você roda a linha de comando softehcicfg /install na pasta \Program Files\dsf\softehci, como mostra abaixo.


Esta linha de comando cria a controladora USB virtual na sua arvore de dispositivos do Device Manager. Seu sistema pode pedir os drivers do novo hardware que foi adicionado. Caso isso aconteça, indique o diretório do sistema (C:\Windows) para que seja feita a busca pelos drivers. Instalados os drivers, você deveria ganhar dois novos dispositivos, sendo eles, Microsoft USB 2.0 EHCI Host Controler Simulator e um USB Root Hub, como mostra abaixo.

Escrevendo disposivos em VBScript

Para simular os dispositivos, o DSF instala um grupo de componentes COM que implementam objetos tais como: Devices, Configurations, Interfaces, EndPoints, Descriptors e por aí vai. Quem já desenvolveu para USB sabe bem do que estou falando. Com estes objetos, você pode escrever componentes que podem simular qualquer dispositivo USB. Junto do framework, são instalados três exemplos de dispositivos que podem ser simulados. Os fontes destes dispositivos estão juntos dos exemplos que vêm no WDK na pasta \WinDDK\6000\src\Test\DSF\USB. Para utilizar um destes exemplos, precisamos apenas de uma liguagem de script, ou qualquer linguagem que faça interface COM.

Vamos dar uma olhada no exemplo de teclado e dar uma fuçada nas IRPs do teclado criado. Para colocar o teclado para funcionar, vá até a pasta \Program Files\dsf\usbhid e rode a seguinte linha de comando cscript Create1.1Kbd.wsf e siga os passos indicados. Se for a primeira vez que você estiver fazendo isso, o Windows pode pedir os drivers dos dispositivos novos que serão criados. O script criará um Generic USB Hub e um Microsoft USB Natural Keyboard conforme mostra abaixo.


Antes de remover estes dispositivos, vamos dar uma olhada com o IRP Tracker, software que já comentei em um outro post, e observar as IRPs deste teclado que está sendo simulado. Inicie o IRP Tracker e selecione todo o driver KbdClass. O KbdClass é o driver responsável por centralizar e implementar as interfaces para os dispositivos a classe Teclado. As IRPs de todos os teclados passam por aqui.

Enquanto o primeiro prompt de comando está parado, inicie mais um prompt de comando e, no mesmo diretório do exemplo do teclado, execute a seguinte linha de comando: cscript Use1.1Kbd.wsf. Este script simula o pressionar das teclas do teclado simulado escrevendo a frase “Hello World!”. Para cada tecla que o sistema obtém, são gerados os registros das IRPs monitoradas. Desta forma, o IRP Tracker deve ficar como mostra abaixo.


Esta é uma excelente ferramenta para utilizar com máquinas virtuais e pode lhe adiantar um bom montante de testes até que o hardware real esteja pronto. Nos casos onde o hardware é novo e o driver também, esse pode ser um divisor de águas para saber quem é que está gerando a tela azul. Afinal, hardware também tem bug. Ou mesmo no caso de você ser um estudante e não ter nenhum hardware para treinar seu aprendizado. Pelo menos você não vai queimar nada.

Até mais,
[]s.