Declarando funções usando tipos de função para drivers WDM

Observação

A partir do Windows 10 versão 2004, o SDV (Verificador de Driver Estático) não requer mais anotações para identificar tipos de função de rotinas de expedição para drivers WDM. Siga as diretrizes na seção Inicializações Básicas e Avançadas desta página.

Para informar o SDV sobre os pontos de entrada do driver ao analisar um driver WDM, você deve declarar funções usando declarações de tipo de função. Os tipos de função de função são definidos em Wdm.h. Cada ponto de entrada na rotina DriverEntry no driver WDM deve ser declarado especificando o tipo de função correspondente. Os tipos de função são typedefs predefinidos que correspondem aos pontos de entrada reconhecidos em um driver WDM.

Por exemplo, para criar uma declaração de tipo de função de função para a rotina Unload de um driver chamada CsampUnload, use o typedef predefinido DRIVER_UNLOAD declaração de tipo de função. A declaração de tipo de função de função deve aparecer antes da definição da função.

DRIVER_UNLOAD CsampUnload;

A definição da função CsampUnload permanece inalterada:

VOID
CsampUnload(
    IN PDRIVER_OBJECT DriverObject
    )
{
    ...
}

O SDV reconhece os tipos de pontos de entrada mostrados na tabela a seguir.

Tipo de função WDM Rotina do WDM

DRIVER_INITIALIZE

DriverEntry

DRIVER_STARTIO

StartIO

DRIVER_UNLOAD

Descarregar

DRIVER_ADD_DEVICE

AddDevice

Dispatch_type(tipo) DRIVER_DISPATCH

As rotinas de expedição usadas pelo driver. Consulte Escrevendo rotinas de expedição.

IO_COMPLETION_ROUTINE

IoCompletion

A rotina IoCompletion é definida chamando IoSetCompletionRoutine ou IoSetCompletionRoutineEx e passando o ponteiro da função para a rotina IoCompletion como o segundo parâmetro.

DRIVER_CANCEL

Cancelar

A rotina Cancel é definida chamando IoSetCancelRoutine e passando o ponteiro de função para a rotina de cancelamento do IRP como o segundo parâmetro para a função.

IO_DPC_ROUTINE

DpcForIsr

A rotina DpcForIsr é registrada chamando IoInitializeDpcRequest e passando o ponteiro da função para a rotina DpcForIsr como o segundo parâmetro. Para enfileirar o DPC, chame IoQueueDpc da rotina ISR usando o mesmo objeto DPC.

KDEFERRED_ROUTINE

CustomDpc

A rotina CustomDpc é definida chamando KeInitializeDpc e passando o ponteiro da função para CustomDpc como o segundo parâmetro. Para enfileirar o CustomDpc para o driver, chame KeInsertQueueDpc da rotina ISR usando o mesmo objeto DPC.

KSERVICE_ROUTINE

InterruptService

A rotina InterruptService (ISR) atende a uma interrupção de dispositivo e agenda o processamento pós-interrupção de dados recebidos, se necessário.

REQUEST_POWER_COMPLETE

A rotina de retorno de chamada do PowerCompletion conclui o processamento de um IRP de energia. Se o driver precisar executar tarefas adicionais depois que todos os outros drivers tiverem concluído o IRP, o driver registrará uma rotina de retorno de chamada do PowerCompletion durante a chamada para a rotina PoRequestPowerIrp que aloca o IRP.

WORKER_THREAD_ROUTINE

Rotina

Rotina é a rotina de retorno de chamada especificada no segundo parâmetro para a função ExInitializeWorkItem .

A Rotina só deverá ser declarada dessa forma se o driver chamar ExQueueWorkItem para adicionar o item de trabalho a uma fila do sistema.

Declarando rotinas de expedição de driver

A partir Windows 10 versão 2004, as declarações de tipo de função de função para rotinas de expedição são refinadas com sua categoria IRP automaticamente com base na inicialização da tabela DriverObject-MajorFunction> na rotina DriverEntry de um driver WDM.

Um driver Foo deve realizar declarações de função usando o estilo básico ou avançado de declaração para estar em conformidade com o SDV.

Inicializações Básicas e Avançadas

O estilo básico pode ser visto no exemplo abaixo (observe que os nomes de rotina de expedição FooCreate e FooCleanup são apenas exemplos, qualquer nome apropriado pode ser usado):

DriverObject->MajorFunction[IRP_MJ_CREATE] = FooCreate; //Basic style
DriverObject->MajorFunction[IRP_MJ_CLEANUP] = FooCleanup;

É possível usar uma abordagem mais avançada para reduzir a lista necessária. Embora a mesma rotina de expedição seja usada para mais de uma categoria IRP, um driver pode codificar duas inicializações dessa maneira:

DriverObject->MajorFunction[IRP_MJ_CREATE] = 
DriverObject->MajorFunction[IRP_MJ_CLEANUP] = FooCreateCleanup; // Advanced style for a multi-role dispatch routine 

Para que um driver possa executar o SDV corretamente, o driver só deve usar o estilo básico ou avançado mostrado acima. A verficiação de SDV no driver não funcionará conforme o esperado se um desses dois métodos não for usado.

Parâmetros de função e tipos de função

Conforme necessário na linguagem de programação C, os tipos de parâmetro que você usa na definição de função devem corresponder aos tipos de parâmetro do protótipo de função ou, nesse caso, ao tipo de função de função. O SDV depende das assinaturas de função para análise e ignora funções cujas assinaturas não correspondem.

Por exemplo, você deve declarar uma rotina IoCompletion usando o tipo de função IO_COMPLETION_ROUTINE função:

IO_COMPLETION_ROUTINE myCompletionRoutine;

Quando você implementa myCompletionRoutine, os tipos de parâmetro devem corresponder aos usados por IO_COMPLETION_ROUTINE, ou seja, PDEVICE_OBJECT, PIRP e PVOID (consulte Rotina IoCompletion para sintaxe).

NTSTATUS
myCompletionRoutine(
 PDEVICE_OBJECT  DeviceObject,
 PIRP  Irp,
 PVOID  Context
 )
{
}

Executando a Análise de Código para Drivers para verificar as declarações de função

Para ajudá-lo a determinar se o código-fonte está preparado, execute a Análise de Código para Drivers. A Análise de Código para Drivers verifica se há declarações de tipo de função de função e pode ajudar a identificar declarações de função que podem ter sido perdidas ou avisar quando os parâmetros da definição de função não corresponderem àqueles no tipo de função de função.