Compartilhar via


Criando drivers de exportação

Um driver de exportação é uma DLL no modo kernel que pode ser carregada por uma variedade de outros componentes específicos do hardware ou da pilha do dispositivo, mas não tem algumas das características de um driver completo do modo kernel. Especificamente, um driver de exportação não tem uma tabela de expedição, não tem um lugar na pilha de driver e não tem uma entrada no banco de dados do gerenciador de controle de serviço que a define como um serviço do sistema. Embora um driver de exportação não tenha uma tabela de expedição, ele pode fornecer rotinas de expedição para um driver padrão. O driver padrão insere as rotinas de expedição em sua própria tabela de expedição. Um driver de exportação tem uma rotina driverEntry stub que nunca é chamada.

Os drivers de exportação no modo kernel são especialmente adequados para implementar a parte de um par de driver independente das características de pilha e hardware subjacentes.

O Windows inclui vários drivers de exportação carregados por outros drivers, por exemplo:

  • Driver de porta SCSI
  • Driver de classe de fita
  • O driver do controlador IDE são todos drivers de exportação fornecidos pelo sistema

Os drivers padrão também podem funcionar como drivers de exportação. Para que um driver funcione de ambas as maneiras, ele deve ser criado como um driver de exportação e carregado como um driver regular.

Criando um driver de exportação

Para criar um driver de exportação no Visual Studio, use o seguinte procedimento:

  1. Crie um novo projeto a partir de um modelo, como Driver WDM Vazio.
  2. Adicione um arquivo de definição de módulo ao projeto, por exemplo:
LIBRARY mydriver.sys
EXPORTS
  DllInitialize PRIVATE
  DllUnload PRIVATE

O ponto de entrada para uma DLL no modo kernel é sempre DllInitialize. O sistema chama uma rotina DllInitialize do modo kernel imediatamente após o carregamento da DLL. Os drivers de exportação devem fornecer rotinas DllInitialize . Você pode usar a rotina DllInitialize para adquirir ou inicializar recursos exigidos por outras rotinas na DLL.

Não é possível especificar o ponto de entrada usando a macro DLLENTRY .

NTSTATUS DllInitialize(
  _In_ PUNICODE_STRING RegistryPath
);

RegistryPath é um ponteiro para uma cadeia de caracteres Unicode contada que especifica o caminho para a chave do Registro da DLL, HKEY_LOCAL_MACHINE\CurrentControlSet\Services\DllName. As rotinas de DLL podem usar essa chave para armazenar informações específicas da DLL. O buffer apontado por RegistryPath é liberado quando DllInitialize é encerrado. Portanto, se a DLL usar a chave, DllInitialize deverá duplicar o nome da chave.

O processo de build gera uma biblioteca de exportação com uma extensão .lib e um driver de exportação com uma extensão .sys.

Importando funções de um driver de exportação

Para importar funções exportadas por um driver de exportação, você deve declarar as funções usando a macro DECLSPEC_IMPORT, que é definida em Ntdef.h. Por exemplo:

DECLSPEC_IMPORT int LoadPrinterDriver (int arg1); 

Essa macro é resolvida para uma declaração de classe de armazenamento __declspec(dllimport) nessas plataformas onde necessário e para nada nessas plataformas onde não for necessário.

No driver de exportação, a função a ser exportada deve ser declarada com a macro DECLSPEC_EXPORT. Essa macro é resolvida para uma declaração de classe de armazenamento __declspec(dllexport) nessas plataformas onde necessário e para nada nessas plataformas onde não for necessário. Se um driver de exportação fornecer uma rotina de expedição para um driver padrão, essa rotina não precisará ser exportada.

Carregando e descarregando um driver de exportação

Os drivers de exportação devem ser instalados no diretório %Windir%\System32\Drivers. A partir do Windows 2000, o sistema operacional mantém uma contagem de referência que indica o número de vezes que as funções do driver de exportação foram importadas por outros drivers. O sistema diminui essa contagem sempre que um dos drivers de importação descarrega. Quando a contagem de referência cai para zero, o sistema descarrega o driver de exportação. No entanto, o driver de exportação deve conter o ponto de entrada padrão e as rotinas de descarregamento, DllInitialize e DllUnload ou o sistema operacional não ativará esse mecanismo de contagem de referência.

O sistema chama a rotina DllUnload de uma DLL do modo kernel quando descarrega a DLL.

NTSTATUS DllUnload(void);

Os drivers de exportação devem fornecer rotinas DllUnload. Você pode usar a rotina DllUnload para liberar todos os recursos usados pelas rotinas na DLL.