Kernel + Visual Studio 2005

16 de November de 2006 - Fernando Roberto

Programador de driver ou software de baixo nível está acostumado a compilar seus projetos na linha de comando, utilizar editores de texto como o Notepad ou mesmo o Norton Editor para codificar seus drivers. É como meu amigo Thiago diz: “Faca nos dentes e sangue nos olhos”. Utilizar o comando TYPE | MORE para ver os arquivos de erros de compilação, mostra o quanto somos seres superiores, dominates da tecnologia, que não sub-utilizamos nosso cérebro, que não precisamos de ferramentas supérfluas como interface gráfica, sintaxe colorida, intellisence ou mesmo o auto-complete e que estamos no topo da cadeia alimentar.

Se você realmente acredita nisso, então é melhor abandonar este post por aqui mesmo. Hoje vou defender o uso das ferramentas que ajudam, e muito, na hora de codificar um driver e ter que lidar com funções com grande número de parâmetros e intermináveis estruturas.

Utilizar ou não o compilador do Visual Studio para gerar drivers é mais uma das discussões que tendem ao infinito, tal como o uso de C++ no desenvolvimento para Kernel Mode. De um lado estão aqueles que defendem que o ambiente quase nunca está perfeitamente configurado para compilar drivers. Já li posts de verdadeiras autoridades no assunto falando sobre quantos dias foram necessários para encontrar um bug que foi gerado por uma otimização do compilador ou mesmo um define incorreto que foi gerado pelo Wizard. Estes que dizem que utilizar o Visual Studio como ambiente de desenvolvimento requer um conhecimento mínimo de cada parâmetro utilizado na chamada para o cl.exe, que o ideal mesmo é utilizar o bom e velho Build que trata os arquivos sources, dirs e makefile e ter a absoluta certeza de que o ambiente configurado pelos atalhos do DDK está correto. Do outo lado estão os que não abrem mão da comodidade de ter um ambiente integrado, de poder pressionar apenas uma tecla para cair na linha do arquivo em que o erro foi detectado, de utilizar sintaxe colorida, intellisence, auto-complete e outras tantas vantagens que o Visual Studio oferece.

Já faço isso a algum tempo e lembro-me de quando o DDK resolveu trazer um compilador embitudo no Kit a partir do Windows XP. O principal objetivo desta mudança no DDK foi tentar separar o ambiente de desenvolvimento de drivers do ambiente de aplicações. Esse vínculo já criou muitos problemas. O DDK do Windows NT 4.0 era baseado no VC 4.2, mas com o surgimento do VC 5.0 e posteriormente do VC 6.0, o formato da tabela de símbolos foi alterado e o Windbg parou de funcionar. Nesta época eu utilizava muito mais o SoftIce que o WinDbg para depurar drivers e continuei utilizando o compilador do Visual Studio sem nem perceber este problema. Só tive problemas com símbolos quando o Visual Studio passou para a versão 7.0. O VToolsD até hoje não oferece suporte ao novo formato de símbolos. Conclusão, até hoje eu utilizo VC 6.0 para compilar VXDs. Não que seja impossível utilizar o VC 7.0 para isso, só não conseguiremos depura-lo.

Mas foi quando fizemos o upgrade do VS2003 para o VS2005 que mudanças mais drásticas fizeram com que minha vida se tornasse um pouco mais azul. Foi a partir dessa época que comecei a utilizar o melhor dos dois mundos, ou seja, a confiança de ter um ambiente corretamente configurado e toda a comodidade das ferramentas que o editor do VS2005 nos oferece.

Como fazer isso? Ok, vamos utilizar o projeto criado no post Getting Started como ponto de partida. Inicialmente precisaremos baixar o arquivo DDKBUILD.CMD da OSR Online e grave-o em um diretório que esteja no PATH da sua máquina. Este CMD irá precisar da variavel de ambiente WNETBASE configurada com o diretório base da sua instalação do DDK. Este arquivo é um meio de fazer um build externo com o Visual Studio. Para fazer isso, crie um projeto de Makefile no Visual Studio como mostra a seguir.







Depois de entrar com o nome do seu novo projeto e a pasta onde ele será criado, é só clicar em “OK”. Mesmo sem configurar nada, clique em “Finish” da janela seguinte. Criado o projeto, adicione os arquivos no Solution Explorer. Em seguida, vamos editar as propriedades do projeto de forma que fique como ilustrado abaixo. Note que no campo “Include Search Path” estou assumindo que a instalação do DDK foi realizada no diretório C:\WINDDK\3790. Este campo não tem nenhuma influência sobre o processo de compilação, ele apenas informa ao intellisence quais os diretórios devem ser utilizados para servirem de fontes para sua base de dados.

A partir deste ponto, já podemos compilar o projeto como se fosse um projeto qualquer de User Mode. As imagens abaixo dispensam comentários. Imagino que não é necessário dizer que não é possível depurar drivers utilizando o ambiente do Visual Studio. Lembre-se que depuração de Kernel exige depuradores especiais para isso como comentei em meu último post.

Uma janela especialmente interessante que foi adicionada ao Visual Studio 2005, foi a “Code Definition Window”, que exibe o lugar onde os símbolos foram definidos conforme você os escreve na janela de código. Veja o exemplo disso quando escrevo uma chamada para IoSetCompletionRoutine.

Enfim, dêem uma olhada nas opções oferecidas pelo DDKBUILD. Você pode listar suas opções simplesmente abrindo uma janela de prompt e executando-o sem qualquer parâmetro. Observe que podemos compilar drivers utilizando inclusive o PREfast.

É isso aê… Have fun ! 😉

8 Responses to “Kernel + Visual Studio 2005”

  1. Marcelo says:

    Fala Fernando,

    Sou iniciante no desenvolvimento de drivers. Estou tentando debugar o driver Useless que vc criou usando o Windbg sem sucesso. Isso já está me tomando muito tempo, já que não encontro uma boa referência na internet. Aí vão algumas informações. Se puder me ajudar, agradeço muito!

    – A criação do driver foi feita na mesma máquina em que estou tentando debugar.

    – Já executei o comando bootcfg /debug ON ID 1

    Boot entry ID: 1
    Friendly Name: “Microsoft Windows XP Professional”
    Path: multi(0)disk(0)rdisk(0)partition(3)\WINDOWS
    OS Load Options: /fastdetect /NoExecute=OptIn /debug

    – Ao abrir o Windbg eu coloco “D:\Useless” como source path e “SRV*downstream_store*http://msdl.microsoft.com/download/symbols” como symbol path

    – Seleciono “Kernel Debug…”, aba “Local” e OK

    Mas no final parece que Useless.sys não foi carregado:

    lkd>lm

    f9974000 f9974800 Useless (deferred)

    Teria alguma sugestão?

    Muito obrigado e abraços!

  2. Marcelo says:

    Ah, esqueci de mencionar que executei o net start Useless…

    Abraços!

    • Vamos lá Marcelo,

      A conexão Local de Kernel serve apenas para que possamos ver o conteúdo de algumas estruturas e variaveis globais do sistema. Não podemos utilizar esse tipo de conexão para realizar o Debug de Kernel (com breakpoint e etc) na própria máquina.

      A depuração de drivers exige dois computadores que devem se comunicar basicamente via porta serial. Uma das máquinas será onde o novo driver será depurado, e a outra será onde teremos o WinDbg instalado. O WinDbg lança comandos para a máquina depurada através desse cabo serial a fim de preencher todas as janelas de Watch, Memory, Registers e etc.

      Depois de modificar os parâmetros no Boot ini na máquina a ser depurada, esta deve ser reiniciada e durante o processo de boot você deve selecionar a opção com [debugger enabled] na descrição. Selecionada esta opção, você precisa solicitar a conexão a partir da máquina que está rodando o WinDbg selecionando a Opção “Kernel Debug…” do menu “File”. A conexão deve ser realizada na pasta “COM”. Este é um processo que fica simples depois que se faz algumas vezes, na primeira vez tudo parece meio enrolado.

      Existem meios de depurar drivers com apenas uma máquina, mas teriamos que utilizar uma máquina virtual ou ainda utilizar o SoftIce.

      Pretendo criar um post que vai lhes dar todos os passos de como depurar o kernel utilizando o cabo serial ou utilzando uma máquina virtual.

      []s.

      • Marcelo says:

        Muito Obrigado Fernando!
        Eu tenho utilizado o DebugView para ver pelo menos os DbgPrint’s. Mas agora vou retornar ao WinDbg e tentar novamente configurá-lo com as suas dicas!
        Mais uma vez valeu pela atenção e ajuda!
        Um grande abraço!

  3. Diego Roriz says:

    Sou iniciante também no desenvolvimento de drivers. Gostaria de estudar mais sobre isso e desenvolvimentos de serviços, para q eu pudesse realizar coletas mais baixo nivel tipo nível de memória utilizada dentre outros!!

    Gostei muito do q vc escreveu e se pudesse me passar algum material de referência, lhe seria muito grato.

    Diego Roriz

    • Olá Diego,

      Alguns livros são realmente muito bons neste assunto e considero indispensáveis.
      Entretanto, Isso vai depender um pouco da sua necessidade inicial, e para qual plataforma você pretende desenvolver.

      Se sua necessidade é apenas coletar informações da máquina, eu diria que você ficaria impressionado com a quantidade de informações que podemos obter a partir de um simples executável rodando em conta administrativa ou de sistema. Dê uma olhada este site de SMBIOS. Tente também olhar alguma coisa de WMI.

      Bom, para desenvolvimento de drivers os livros são…

      Se você quer realmente ter uma base sólida, este livro é excelente.
      Microsoft Windows Internals, Fourth Edition.

      Se você está com pressa e prefere procurar os detalhes quando a necessidade aparecer, este é um livro muito bom para iniciantes. Ele dá o conteúdo de forma simples com exemplos de drivers que não fazem nada e que depois vão tomando forma e exploranado vários assuntos.
      The Windows 2000 Device Driver Book: A Guide for Programmers.

      Este livro é muito bom também, entretanto recomendo a segunda edição que está mais simples de entender que a primeira. Não sei de este seria a melhor opção como primeiro livro.
      Programming the Microsoft Windows Driver Model, Second Edition.

      Existem outros livros que cobrem plataforma 9x e Legacy drivres para Windows NT 4.
      Embora estes livros apresentem um angulo mais antiquado, seu conteúdo é muito bom, tendo em mente que muitos dos conceitos ainda são utilizados nas versões mais recentes do Windows. Mas recomendo este tipo de literatura para quando você já tiver alguma experiência. Senão você acabará se perdendo nos detalhes.

      Minha opinião é suspeita, sou meio viciado em livros…
      Existe também alguns papers no site da Microsoft que dão um quick start.
      What Every Driver Writer Needs to Know.

      Have fun! 🙂

  4. Anonymous says:

    Tentei e deu o erro (no final do texto)

    Esse sources fica aonde? em Resource Files? Eu tentei e não consegui.

    Bom artigo! Show de bola \o/

    Performing Makefile project actions
    OSR DDKBUILD.BAT V6.10 – OSR, Open Systems Resources, Inc.
    WXP BUILD using WNET DDK

    ERROR: target directory must contain a SOURCES or DIRS file


    usage: ddkbuild [-W2K] “checked | free | chk | fre” “directory-to-build” [flags] [-WDF] [-PREFAST]
    -W2K indicates development system uses W2KBASE environment variable
    to locate the win2000 ddk
    -W2K64 indicates development sytsem uses W2KBASE environment variable
    to locate the win2000 IA64 ddk
    -WXP to indicate WXP Build uses WXPBASE enviornment variable.
    -WXP64 to indicate WXP IA64 bit build, uses WXPBASE
    -WXP2K to indicate Windows 2000 build using WXP ddk
    -WNET to indicate Windows .Net builds using WNET ddk
    -WNET64 to indicate Windows .Net 64 bit builds using WNET DDK
    -WNETXP to indicate Windows XP builds suing WNET DDK
    -WNETXP64 to indicate Windows XP 64 bit builds suing WNET DDK
    -WNETAMD64 to indicate Windows .NET build for AMD64 using WNET DDK
    -WNET2K to indicate Windows 2000 builds using WNET DDK
    -NT4 to indicate NT4 build using NT4 DDK.
    -WLH to indicate Windows LH builds using WLH DDK
    -WLH2K to indicate Windows 2K builds using WLH DDK
    -WLHXP to indicate Windows XP builds using WLH DDK
    -WLHNET to indicate Windows NET builds using WLH DDK
    -WLHNETX64 to indicate Windows NET X64 builds using WLH DDK
    -WLHNETI64 to indicate Windows NET IA64 builds using WLH DDK
    -WLHX64 to indicate Windows LH X64 builds using WLH DDK
    -WLHI64 to indicate Windows LH IA64 builds using WLH DDK
    checked indicates a checked build
    free indicates a free build
    chk indicates a checked build
    fre indicates a free build
    directory path to build directory, try . (cwd)
    flags any random flags you think should be passed to build (try /a for clean)
    -WDF performs a WDF build
    -PREFAST preforms a PREFAST build

    ex: ddkbuild -NT4 checked . (for NT4 BUILD)
    ex: ddkbuild -WXP64 chk .
    ex: ddkbuild -WXP chk c:\projects\myproject
    ex: ddkbuild -WNET64 chk . (IA64 bit build)
    ex: ddkbuild -WNETAMD64 chk . (AMD64/EM64T bit build)
    ex: ddkbuild -WNETXP chk . -cZ -WDF
    ex: ddkbuild -WNETXP chk . -cZ -PREFAST

    In order for this procedure to work correctly for each platform, it requires
    an environment variable to be set up for certain platforms. The environment
    variables are as follows:

    NT4BASE – You must set this up to do -NT4 builds
    W2KBASE – You must set this up to do -W2K and -W2K64 builds
    WXPBASE – You must set this up to do -WXP, -WXP64, -WXP2K builds
    WNETBASE – You must set this up to do -WNET, -WNET64, -WNETXP, -WNETXP64,
    -WNETAMD64, and -WNET2K builds
    WLHBASE – You must set this to do any -WLH* builds

    WDF_ROOT must be set if attempting to do a WDF Build.


    OSR DDKBUILD.BAT V6.10 – OSR, Open Systems Resources, Inc.
    report any problems found to info@osr.com

Deixe um comentário