Dichiarazione di funzioni tramite tipi di ruolo di funzione per i driver WDM

Nota

A partire da Windows 10 versione 2004, static driver Verifier (SDV) non richiede più annotazioni per identificare i tipi di ruolo delle routine dispatch per i driver WDM. Seguire le indicazioni nella sezione Inizializzazioni di base e avanzate di questa pagina.

Per informare SDV sui punti di ingresso del driver quando si analizza un driver WDM, è necessario dichiarare le funzioni usando le dichiarazioni del tipo di ruolo della funzione. I tipi di ruolo della funzione sono definiti in Wdm.h. Ogni punto di ingresso nella routine DriverEntry nel driver WDM deve essere dichiarato specificando il tipo di ruolo corrispondente. I tipi di ruolo sono typedef predefiniti che corrispondono ai punti di ingresso riconosciuti in un driver WDM.

Ad esempio, per creare una dichiarazione di tipo di ruolo funzione per la routine Unload di un driver denominata CsampUnload, usare il typedef predefinito DRIVER_UNLOAD dichiarazione del tipo di ruolo. La dichiarazione del tipo di ruolo funzione deve essere visualizzata prima della definizione della funzione.

DRIVER_UNLOAD CsampUnload;

La definizione della funzione CsampUnload rimane invariata:

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

SDV riconosce i tipi di punti di ingresso illustrati nella tabella seguente.

Tipo di ruolo della funzione WDM Routine WDM

DRIVER_INITIALIZE

DriverEntry

DRIVER_STARTIO

StartIO

DRIVER_UNLOAD

Scaricare

DRIVER_ADD_DEVICE

AddDevice

Dispatch_type(tipo DRIVER_DISPATCH)

Routine di invio utilizzate dal driver. Vedere Scrittura di routine dispatch.

IO_COMPLETION_ROUTINE

IoCompletion

La routine IoCompletion viene impostata chiamando IoSetCompletionRoutine o IoSetCompletionRoutineEx e passando il puntatore della funzione alla routine IoCompletion come secondo parametro.

DRIVER_CANCEL

Annulla

La routine Cancel viene impostata chiamando IoSetCancelRoutine e passando il puntatore della funzione alla routine di annullamento per IRP come secondo parametro alla funzione.

IO_DPC_ROUTINE

DpcForIsr

La routine DpcForIsr viene registrata chiamando IoInitializeDpcRequest e passando il puntatore della funzione alla routine DpcForIsr come secondo parametro. Per accodare il DPC, chiamare IoQueueDpc dalla routine ISR usando lo stesso oggetto DPC.

KDEFERRED_ROUTINE

CustomDpc

La routine CustomDpc viene impostata chiamando KeInitializeDpc e passando il puntatore della funzione a CustomDpc come secondo parametro. Per accodare CustomDpc per il driver, chiamare KeInsertQueueDpc dalla routine ISR usando lo stesso oggetto DPC.

KSERVICE_ROUTINE

InterruptService

La routine InterruptService (ISR) esegue un'interruzione del dispositivo e pianifica l'elaborazione post-interrupt dei dati ricevuti, se necessario.

REQUEST_POWER_COMPLETE

La routine di callback di PowerCompletion completa l'elaborazione di un IRP di alimentazione. Se il driver deve eseguire attività aggiuntive dopo che tutti gli altri driver hanno completato l'IRP, il driver registra una routine di callback di PowerCompletion durante la chiamata alla routine PoRequestPowerIrp che alloca l'IRP.

WORKER_THREAD_ROUTINE

Routine

Routine è la routine di callback specificata nel secondo parametro per la funzione ExInitializeWorkItem .

La routine deve essere dichiarata in questo modo solo se il driver chiama ExQueueWorkItem per aggiungere l'elemento di lavoro a una coda di sistema.

Dichiarazione di routine dispatch driver

A partire da Windows 10 versione 2004, le dichiarazioni del tipo di ruolo della funzione per le routine dispatch vengono perfezionate automaticamente con la relativa categoria IRP in base all'inizializzazione della tabella DriverObject-MajorFunction> nella routine DriverEntry di un driver WDM.

Un driver Foo deve eseguire dichiarazioni di ruolo usando lo stile di dichiarazione di base o avanzato per essere conforme a SDV.

Inizializzazione di base e avanzata

Lo stile di base è visibile nell'esempio seguente (si noti che i nomi di routine dispatch FooCreate e FooCleanup sono solo esempi, è possibile usare qualsiasi nome appropriato):

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

È possibile adottare un approccio più avanzato per abbreviare l'elenco richiesto. Mentre la stessa routine dispatch viene usata per più di una categoria IRP, un driver può codificare due inizializzazioni in questo modo:

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

Affinché un driver sia in grado di eseguire correttamente SDV, il driver deve usare solo lo stile di base o avanzato illustrato in precedenza. La verifica SDV sul driver non funzionerà come previsto se uno di questi due metodi non viene usato.

Parametri di funzione e tipi di ruolo di funzione

Come richiesto nel linguaggio di programmazione C, i tipi di parametro usati nella definizione della funzione devono corrispondere ai tipi di parametro del prototipo di funzione o, in questo caso, al tipo di ruolo della funzione. SDV dipende dalle firme di funzione per l'analisi e ignora le funzioni le cui firme non corrispondono.

Ad esempio, è necessario dichiarare una routine IoCompletion usando il tipo di ruolo della funzione IO_COMPLETION_ROUTINE:

IO_COMPLETION_ROUTINE myCompletionRoutine;

Quando si implementa myCompletionRoutine, i tipi di parametro devono corrispondere a quelli usati da IO_COMPLETION_ROUTINE, vale a dire PDEVICE_OBJECT, PIRP e PVOID (vedere Routine IoCompletion per la sintassi).

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

Esecuzione dell'analisi del codice per i driver per verificare le dichiarazioni di funzione

Per determinare se il codice sorgente è preparato, eseguire l'analisi del codice per i driver. L'analisi del codice per i driver verifica la presenza di dichiarazioni di tipi di ruolo funzione e consente di identificare le dichiarazioni di funzione che potrebbero essere state perse o avvisare quando i parametri della definizione della funzione non corrispondono a quelli nel tipo di ruolo della funzione.