Do código de exemplo ao driver de produção. O que mudar nos exemplos

Este tópico descreve alterações importantes que precisam ser feitas nos drivers de exemplo do WDK antes de liberar drivers de dispositivo com base no código de exemplo.

Além das alterações descritas aqui, todos os drivers devem usar as práticas recomendadas descritas em Criar drivers confiáveis no modo kernel e em Práticas recomendadas de desenvolvimento de driver de equipe do Surface. Todos os drivers também devem seguir as diretrizes fornecidas nas Diretrizes de Segurança do Driver.

Exemplos de drivers do WDK: identificadores exclusivos

O Kit de driver do Windows (WDK) contém uma grande variedade de drivers de exemplo que demonstram técnicas úteis para o desenvolvimento de drivers. Você pode usar esses exemplos como base para seus próprios drivers, mas antes de liberar o driver, você deve alterar determinados aspectos específicos do dispositivo do exemplo, além do código operacional óbvio, para aplicar exclusivamente ao seu próprio dispositivo e driver. Os escritores de driver às vezes ignoram esses detalhes.

Os itens exatos que você deve alterar variam de um exemplo para outro, mas, em geral, eles identificam um dispositivo, interface ou driver específico. Por exemplo, se o driver de exemplo contiver qualquer um dos seguintes itens, você deverá alterá-los para se aplicarem ao driver e ao dispositivo:

  • Identificadores global exclusivos (GUIDs)

  • Nomes de link simbólicos

  • Nome do objeto do dispositivo

  • Marcas do pool

  • Definições de código de controle de E/S (IOCTL)

  • Nomes de qualquer arquivo copiado para a pasta do sistema

  • ID do dispositivo Plug and Play, ID de hardware e IDs compatíveis

  • Nome do serviço de driver

  • Descrição do dispositivo

  • Arquivo de recurso

Esquecer de fazer essas alterações pode resultar em falha na instalação, conflitos com outros dispositivos e drivers no sistema e dificuldades na depuração, além de outros erros.

Por exemplo, se você receber um erro como ...\toastDrv\kmdf\toastmon\wdftoastmon.inx(18-18): error 1284: Class "Sample" is reserved for use by Microsoft. isso indica que o nome "Exemplo" deve ser alterado para um nome exclusivo para seu driver de exemplo.

GUIDs

Os drivers usam GUIDs para identificar classes de configuração de dispositivos, classes de interface de dispositivos, eventos PnP personalizados, eventos WMI (Instrumentação de Gerenciamento do Windows) personalizados e provedores de rastreamento do Windows PreProcessor (WPP). Alguns GUIDs são definidos pela Microsoft e outros são definidos por fornecedores de dispositivos e drivers.

Os GUIDs de classe de instalação do dispositivo, os GUIDs de classe de interface do dispositivo e os GUIDs WMI para dispositivos comuns e dados WMI são definidos no WDK ou em arquivos de cabeçalho públicos para uso por qualquer driver. Você não deve alterar esses GUIDs.

Por exemplo, se estiver implementando um mouse, você continuará a usar GUID_DEVINTERFACE_MOUSE, que é definido no arquivo de cabeçalho Ntddmou.h do WDK, como a classe de interface do dispositivo. No entanto, se você definir uma nova classe de configuração de dispositivo, deverá gerar um novo GUID de classe de configuração de dispositivo e um nome de classe de configuração e, possivelmente, também um novo GUID de classe de interface de dispositivo. O GUID da classe de instalação e o GUID da classe de interface do dispositivo devem ser valores exclusivos, eles não podem compartilhar um GUID.

Na maioria dos drivers baseados em exemplos, você deve alterar apenas os GUIDs definidos no cabeçalho local ou no arquivo de origem de um exemplo e que, portanto, são específicos do exemplo. Esses GUIDs podem incluir o seguinte:

  • Eventos PnP personalizados

  • Eventos WMI personalizados

  • Classes de interface de dispositivo para dispositivos novos ou personalizados

  • Provedores de rastreamento do WPP

O uso de um GUID que foi definido para outro driver pode causar conflitos se ambos os drivers forem carregados no mesmo sistema. Por exemplo, se dois drivers diferentes usarem o mesmo GUID para registrar uma interface de dispositivo, os clientes que tentarem abrir a interface do dispositivo poderão abrir inadvertidamente o dispositivo errado.

O trecho a seguir é do arquivo Driver.h incluído em todos os exemplos de driver Toaster. Ele define o GUID da interface do dispositivo para dispositivos Toaster:

DEFINE_GUID(GUID_TOASTER_INTERFACE_STANDARD, \
            0xe0b27630, 0x5434, 0x11d3, 0xb8, 0x90, 0x0, 0xc0, \
            0x4f, 0xad, 0x51, 0x71);
// {E0B27630-5434-11d3-B890-00C04FAD5171}

Se você usar esse arquivo em seu próprio driver, substitua o GUID de exemplo (mostrado acima como texto em negrito) pelo GUID da interface para seu próprio dispositivo. Para criar um GUID, use a ferramenta Criar GUID no Microsoft Visual Studio ou Guidgen.exe, ambas incluídas no SDK (Kit de Desenvolvimento de Software) do Microsoft Windows. Em seguida, você pode associar o GUID a uma constante simbólica no arquivo de cabeçalho do driver, como mostra o exemplo.

Você também pode ser solicitado a criar novos GUIDs para os eventos WMI do driver. Os exemplos de driver Toaster definem o seguinte GUID para notificação de chegada do dispositivo de resistência:

DEFINE_GUID (TOASTER_NOTIFY_DEVICE_ARRIVAL_EVENT, \
             0x1cdaff1, 0xc901, 0x45b4, 0xb3, 0x59, 0xb5, 0x54, \
             0x27, 0x25, 0xe2, 0x9c);
// {01CDAFF1-C901-45b4-B359-B5542725E29C}

Você deve criar um novo GUID para cada evento WMI em seu driver.

Se o driver de exemplo usar o rastreamento de software WPP, gere um novo GUID do provedor de rastreamento para todos os drivers que você basear no exemplo. Por exemplo, o arquivo de cabeçalho Trace.h do exemplo Osrusbfx2 em %WinDDK%\Src\Kmdf\Osrusbfx2\Final define um GUID de controle da seguinte maneira:

#define WPP_CONTROL_GUIDS \
    WPP_DEFINE_CONTROL_GUID( \
           OsrUsbFxTraceGuid,(d23a0c5a,d307,4f0e,ae8e,E2A355AD5DAB), \
        WPP_DEFINE_BIT(DBG_INIT)          /* bit  0 = 0x00000001 */ \
        WPP_DEFINE_BIT(DBG_PNP)           /* bit  1 = 0x00000002 */ \
        WPP_DEFINE_BIT(DBG_POWER)         /* bit  2 = 0x00000004 */ \
        WPP_DEFINE_BIT(DBG_WMI)           /* bit  3 = 0x00000008 */ \
        WPP_DEFINE_BIT(DBG_CREATE_CLOSE)  /* bit  4 = 0x00000010 */ \
        WPP_DEFINE_BIT(DBG_IOCTL)         /* bit  5 = 0x00000020 */ \
        WPP_DEFINE_BIT(DBG_WRITE)         /* bit  6 = 0x00000040 */ \
        WPP_DEFINE_BIT(DBG_READ)          /* bit  7 = 0x00000080 */ \
       )

Em seu próprio driver, você substituiria o texto em negrito por um nome específico do driver e o GUID que você criou.

Se o exemplo definir um nome de link simbólico, substitua o nome no exemplo por um nome que se aplique ao seu próprio driver. No entanto, não altere nomes de link conhecidos, como \DosDevices\COM1. Em geral, se o nome do link for muito semelhante ao nome do exemplo (como \DosDevices\CancelSamp), você deverá alterá-lo.

Usar o mesmo link simbólico de outro driver tem o mesmo efeito que usar o GUID errado da interface de dispositivo, pois as interfaces de dispositivo são essencialmente links simbólicos.

O driver KMDF Toaster Filter em %WinDDK\Src\Kmdf\Toaster\Filter cria um nome de link simbólico que usa uma cadeia de caracteres definida da seguinte maneira no arquivo de cabeçalho Filter.h:

#define SYMBOLIC_NAME_STRING     L"\\DosDevices\\ToasterFilter"

Altere a cadeia de caracteres em negrito para descrever com mais precisão seu próprio driver.

Nome do objeto do dispositivo

Se o exemplo criar um nome para o objeto de dispositivo, você deverá alterar o nome ao adaptar o código de exemplo.

O driver KMDF Toaster Filter nomeia seu objeto de dispositivo no arquivo de cabeçalho Filter.h da seguinte maneira:

#define NTDEVICE_NAME_STRING      L\\Device\\ToasterFilter

Assim como acontece com o nome do link simbólico, você deve alterar a cadeia de caracteres para descrever seu driver.

Lembre-se de que os objetos de dispositivo nomeados podem representar um risco de segurança. Os PDOs (objetos de dispositivo físico) devem ter nomes e a maioria desses nomes é gerada pelo sistema em vez de atribuída explicitamente por um driver. Outros objetos de dispositivo devem ser nomeados somente se representarem objetos de dispositivo de controle, que são usados para comunicação de banda lateral entre um aplicativo e um driver. A estrutura de driver de modo kernel (KMDF) e o WDM (Windows Driver Model) habilitam que você permita que o Windows gere o nome. Essa abordagem garante que o nome do objeto do dispositivo seja exclusivo e que usuários sem privilégios não possam acessá-lo. Para obter detalhes, consulte Controlar o acesso ao namespace do dispositivo e Controlar o acesso ao dispositivo em drivers KMDF.

Marcas do pool

Uma marca de pool é um literal de um a quatro caracteres que identifica uma alocação de memória específica e pode ajudar na depuração.

Muitos dos drivers de exemplo definem uma marca de pool no arquivo de cabeçalho do driver, como na seguinte linha de Toaster.h:

#define TOASTER_POOL_TAG (ULONG) 'saoT'

O driver define a marca de trás para frente porque o depurador a exibe na ordem inversa. Assim, essa marca aparece como Toas na saída do depurador. Em vez de usar a marca que o exemplo define, altere a cadeia de caracteres para identificar exclusivamente seu próprio código.

O arquivo Pooltag.txt lista as marcas de pool usadas por componentes e drivers do modo kernel fornecidos com o Windows. Pooltag.txt é instalado com o WDK em %winddk%\Tools\Other<i>platform\Poolmon, onde platform é amd64, i386, ou ia64. Não use nenhuma das marcações que aparecem nesta lista.

Definições de IOCTL

Altere todos os códigos de controle de E/S definidos por exemplo para usar um nome, tipo de dispositivo, código de função, tipo de transferência e tipo de acesso apropriados para seu dispositivo e driver.

Por exemplo, o exemplo Osrusbfx2 inclui a seguinte definição para IOCTL_OSRUSBFX2_READ_SWITCHES:

#define IOCTL_OSRUSBFX2_READ_SWITCHES   
                    CTL_CODE(FILE_DEVICE_OSRUSBFX2, \
                             IOCTL_INDEX + 6, \
                             METHOD_BUFFERED, \
                             FILE_READ_ACCESS)

Um driver baseado em exemplo para um dispositivo diferente exigiria modificações nessa definição.

Nomes de arquivos

No INF ou INX, altere os nomes do driver, do coinstalador fornecido pelo fornecedor e de quaisquer outros arquivos que o procedimento de instalação copie para a pasta do sistema. Esses nomes de arquivo normalmente aparecem nas seções [SourceDisksFiles] e [ClassInstall32] do INF e nas entradas CopyFiles.

O exemplo a seguir é do arquivo INX para o exemplo KMDF Featured Toaster, que está disponível em %WinDDK%\src\kmdf\Toaster\Func\Featured. Os nomes dos arquivos que devem ser alterados são mostrados em negrito:

[ClassInstall32]
Addreg=ToasterClassReg
CopyFiles=ToasterClassInstallerCopyFileshighlight

[ToasterClassReg]
...
HKR,,Installer32,,"tostrcls.dll,ToasterClassInstaller"
...

[ToasterClassInstallerCopyFiles]
tostrcls.dll									    
...

Para adaptar essa parte do arquivo para um driver diferente, você alteraria "tostrcls.dll" para o nome do arquivo do instalador da classe e alteraria a cadeia de caracteres "ToasterClassInstaller" para descrever seu próprio instalador. Essas alterações garantem que o procedimento de instalação copie o arquivo de coinstalador correto e que a chave do Registro registre o nome de arquivo correto.

Não altere o nome dos coinstaladores fornecidos no WDK ou com o Windows, como os coinstaladores KMDF, UMDF e WinUSB.

Alterações adicionais são necessárias posteriormente na seção Instalação do dispositivo do arquivo, conforme mostrado neste exemplo:

[Toaster_Device.NT]
CopyFiles=Toaster_Device.NT.Copy

[Toaster_Device.NT.Copy]
wdffeatured.sys

Neste exemplo, você alteraria o nome do arquivo em negrito para o nome do arquivo de driver gerado.

Quando a Instalação copia os arquivos de catálogo de driver e INF, ela os renomeia, portanto, você não precisa alterar seus nomes no pacote de driver. No entanto, geralmente é uma boa ideia garantir que os nomes de arquivo INF e de catálogo sejam semelhantes ao nome do arquivo de driver.

ID do dispositivo PnP, ID de hardware e IDs compatíveis

A instalação usa a ID do dispositivo junto com IDs de hardware e IDs compatíveis para selecionar o INF a ser usado para a instalação do dispositivo.

A ID do dispositivo é uma cadeia de caracteres definida pelo fornecedor que identifica exclusivamente um dispositivo específico. Cada dispositivo tem exatamente uma ID de dispositivo. O driver de barramento relata a ID do dispositivo durante a enumeração e a Instalação a usa para corresponder o dispositivo ao arquivo INF correto. A ID do dispositivo é definida na seção [Fabricante] do INF.

O exemplo a seguir mostra a ID do dispositivo OSR USB Fx2, conforme especificado no arquivo Osrusbfx2.inx:

[Manufacturer]
%MfgName%=Microsoft,NT$ARCH$

; For Win2K
[Microsoft]
%USB\VID_045E&PID_930A.DeviceDesc%=osrusbfx2.Dev, 
        USB\VID_0547&PID_1002
...

; For XP and later
[Microsoft.NT$ARCH$]
%USB\VID_045E&PID_930A.DeviceDesc%=osrusbfx2.Dev, 
        USB\VID_0547&PID_1002

Para adaptar essa diretiva INF para seu próprio driver, substitua a ID do dispositivo mostrada em negrito pela ID do dispositivo para seu próprio dispositivo. Você também deve alterar o nome do fabricante para o nome da sua empresa.

A ID de hardware e a ID compatível são IDs menos específicas que a Instalação usa se não puder corresponder a ID do dispositivo a um INF. Se o INF puder dar suporte a outros dispositivos, você deverá alterar esses valores além da ID do dispositivo. O exemplo a seguir do driver KMDF Featured Toaster mostra uma ID de hardware:

[Manufacturer]
%StdMfg%=Standard,NT$ARCH$

; For Win2K
[Standard]
; DisplayName                   Section           DeviceId
; -----------                   -------           --------
%ToasterDevice.DeviceDesc%=Toaster_Device, 
         {b85b7c50-6a01-11d2-b841-00c04fad5171}\MsToaster

; For XP and later
[Standard.NT$ARCH$]
%ToasterDevice.DeviceDesc%=Toaster_Device, 
         {b85b7c50-6a01-11d2-b841-00c04fad5171}\MsToaster

Para adaptar essa diretiva INF para seu próprio driver, substitua a ID de hardware pela ID do dispositivo do driver e altere "MsToaster" para uma cadeia de caracteres mais descritiva.

Nome do serviço de driver

Atualize o nome do serviço na diretiva AddService no INF para um valor apropriado para o driver. Se o nome do serviço de driver entrar em conflito com o de outro driver no sistema, o driver não será instalado ou carregado.

O driver KMDF Featured Toaster nomeia seu serviço da seguinte maneira:

[Toaster_Device.NT.Services]
AddService = wdffeatured, %SPSVCINST_ASSOCSERVICE%,
     wdffeatured_Service_Inst
      

O nome do serviço é a primeira entrada na diretiva AddService. Para adaptar o INF do Featured Toaster, você deve alterar a cadeia de caracteres em negrito para uma cadeia de caracteres mais adequada ao seu driver. No exemplo, a entrada wdffeatured_Service_Inst apenas faz referência a uma seção definida por INF, portanto, alterá-la não é essencial.

Descrição do dispositivo

A descrição do dispositivo consiste em várias cadeias de caracteres que normalmente são definidas na seção [Cadeias de Caracteres] do INF e são usadas em vários locais em todo o INF. Por exemplo, o exemplo KMDF Featured Toaster define as seguintes cadeias de caracteres no arquivo WdfFeatured.inx:

[Strings]
SPSVCINST_ASSOCSERVICE   = 0x00000002
MSFT                     = "Microsoft"
StdMfg                   = "(Standard system devices)"
ClassName                = "Toaster"
DiskId1                  = "Toaster Device Installation Disk #1"
ToasterDevice.DeviceDesc = "Microsoft WDF Featured Toaster"
Toaster.SVCDESC          = "Microsoft WDF Toaster Featured Device Driver"

Para modificar esse arquivo para instalar seu próprio driver, você deve alterar as cadeias de caracteres em negrito para refletir informações sobre sua empresa, dispositivo e driver.

Se o nome da empresa também aparecer em uma seção [Fabricante] no INF, você também deverá alterar o nome nessa seção.

Arquivo de recurso

Drivers e outros componentes, como coinstaladores específicos de exemplo, também têm arquivos de recurso (.rc), que definem cadeias de caracteres específicas do driver, incluindo o nome do produto, a versão do arquivo e o nome da empresa. Altere essas cadeias de caracteres para valores apropriados para o pacote de driver.

Resumo: o que você deve fazer?

Antes de liberar um driver baseado em um exemplo do WDK, substitua todas as informações específicas do exemplo nos arquivos de origem, no INF e em quaisquer outros recursos usados para criar seu próprio driver. As alterações necessárias variam de um exemplo para outro, mas geralmente incluem qualquer informação que identifique exclusivamente o driver de exemplo ou seu dispositivo. Os itens seguintes são típicos das alterações que você deve fazer:

  • Gere e use GUIDs específicos para o driver, quando apropriado.

  • Atualizar o nome do link simbólico.

  • Atualize o nome do objeto do dispositivo ou use um nome gerado automaticamente.

  • Use marcas de pool que identifiquem seu driver e não entrem em conflito com nenhuma marca conhecida.

  • Defina códigos IOCTL apropriados para seu driver e dispositivo.

  • Atualize os nomes de todos os arquivos copiados para a pasta do sistema.

  • Insira a ID de dispositivo Plug and Play correta, as IDs de hardware e as IDs compatíveis no INF.

  • Atualize o nome do serviço do driver no INF.

  • Altere a descrição do dispositivo.

  • Modifique todas as cadeias de caracteres específicas do driver no arquivo de recurso.

  • Aderir às práticas recomendadas de segurança e confiabilidade

Informações Adicionais

Manuais

Desenvolver drivers com o Windows Driver Foundation escrito por Penny Orwick e Guy Smith.

Tópicos WDK

Definir e exportar novos GUIDs

Controlar o acesso ao dispositivo em drivers KMDF

Desenvolvimento, teste e implantação de drivers

Criar drivers confiáveis no modo kernel

Práticas recomendadas de desenvolvimento de drivers do Surface Team

Diretrizes de segurança do driver

Escreva seu primeiro driver