Déclaration de fonctions à l’aide de types de rôles de fonction pour les pilotes WDM
Remarque
À partir de la version 2004 de Windows 10, Static Driver Verifier (SDV) n’exige plus d’annotations pour identifier les types de rôles des routines de dispatch pour les pilotes WDM. Veuillez suivre les instructions dans la section Initialisations de base et avancées de cette page.
Pour informer SDV des points d’entrée du pilote lors de l’analyse d’un pilote WDM, vous devez déclarer les fonctions en utilisant des déclarations de type de rôle de fonction. Les types de rôle de fonction sont définis dans Wdm.h. Chaque point d’entrée dans la routine DriverEntry de votre pilote WDM doit être déclaré en spécifiant le type de rôle correspondant. Les types de rôle sont des typedefs prédéfinis qui correspondent aux points d’entrée reconnus dans un pilote WDM.
Par exemple, pour créer une déclaration de type de rôle de fonction pour la routine Unload d’un pilote appelée CsampUnload, utilisez la déclaration de type de rôle prédéfinie DRIVER_UNLOAD. La déclaration de type de rôle de fonction doit apparaître avant la définition de la fonction.
DRIVER_UNLOAD CsampUnload;
La définition de la fonction CsampUnload reste inchangée :
VOID
CsampUnload(
IN PDRIVER_OBJECT DriverObject
)
{
...
}
SDV reconnaît les types de points d’entrée présentés dans le tableau suivant.
Type de rôle de fonction WDM | Routine WDM |
---|---|
DRIVER_INITIALIZE |
|
DRIVER_STARTIO |
|
DRIVER_UNLOAD |
|
DRIVER_ADD_DEVICE |
|
Dispatch_type( type ) DRIVER_DISPATCH | La ou les routines de dispatch utilisées par le pilote. Voir Écriture de routines de dispatch. |
IO_COMPLETION_ROUTINE |
La routine IoCompletion est définie en appelant IoSetCompletionRoutine ou IoSetCompletionRoutineEx et en passant le pointeur de fonction à la routine IoCompletion comme deuxième paramètre. |
DRIVER_CANCEL |
La routine Cancel est définie en appelant IoSetCancelRoutine et en passant le pointeur de fonction à la routine d’annulation pour l’IRP en tant que deuxième paramètre à la fonction. |
IO_DPC_ROUTINE |
La routine DpcForIsr est inscrite en appelant IoInitializeDpcRequest et en passant le pointeur de fonction à la routine DpcForIsr en tant que deuxième paramètre. Pour mettre en file d’attente le DPC, appelez IoQueueDpc depuis la routine ISR en utilisant le même objet DPC. |
KDEFERRED_ROUTINE |
La routine CustomDpc est définie en appelant KeInitializeDpc et en passant le pointeur de fonction à CustomDpc comme deuxième paramètre. Pour mettre en file d’attente le CustomDpc pour le pilote, appelez KeInsertQueueDpc depuis la routine ISR en utilisant le même objet DPC. |
KSERVICE_ROUTINE |
La routine InterruptService (ISR) gère une interruption de périphérique et planifie le traitement post-interruption des données reçues, si nécessaire. |
REQUEST_POWER_COMPLETE |
La routine de rappel PowerCompletion termine le traitement d’un IRP de puissance. Si le pilote doit effectuer des tâches supplémentaires après que tous les autres pilotes ont terminé l’IRP, il enregistre une routine de rappel PowerCompletion lors de l’appel à la routine PoRequestPowerIrp qui alloue l’IRP. |
WORKER_THREAD_ROUTINE |
Routine La Routine est la routine de rappel spécifiée dans le deuxième paramètre de la fonction ExInitializeWorkItem. La Routine ne doit être déclarée de cette manière que si le pilote appelle ExQueueWorkItem pour ajouter l’élément de travail à une file d’attente système. |
Déclaration des routines de dispatch de pilote
À partir de la version 2004 de Windows 10, les déclarations de type de rôle de fonction pour les routines de dispatch sont affinées avec leur catégorie IRP automatiquement en fonction de l’initialisation de la table DriverObject->MajorFunction dans la routine DriverEntry d’un pilote WDM.
Un pilote Foo doit accomplir les déclarations de rôle en utilisant soit le style basique soit le style avancé de déclaration afin d’être conforme avec SDV.
Initialisations de base et avancées
Le style basique peut être vu dans l’exemple ci-dessous (notez que les noms de routines de dispatch FooCreate et FooCleanup ne sont que des exemples, tout nom approprié peut être utilisé) :
DriverObject->MajorFunction[IRP_MJ_CREATE] = FooCreate; //Basic style
DriverObject->MajorFunction[IRP_MJ_CLEANUP] = FooCleanup;
Une approche plus avancée peut être adoptée pour raccourcir la liste requise. Alors que la même routine de dispatch est utilisée pour plus d’une catégorie IRP, un pilote peut encoder deux initialisations de cette manière :
DriverObject->MajorFunction[IRP_MJ_CREATE] =
DriverObject->MajorFunction[IRP_MJ_CLEANUP] = FooCreateCleanup; // Advanced style for a multi-role dispatch routine
Pour qu’un pilote puisse exécuter correctement SDV, le pilote ne doit utiliser que le style basique ou avancé montré ci-dessus. La vérification SDV sur le pilote ne fonctionnera pas comme prévu si l’une de ces deux méthodes n’est pas utilisée.
Paramètres de fonction et types de rôle de fonction
Comme requis dans le langage de programmation C, les types de paramètres que vous utilisez dans la définition de la fonction doivent correspondre aux types de paramètres du prototype de fonction, ou dans ce cas, du type de rôle de fonction. SDV dépend des signatures des fonctions pour l’analyse et ignore les fonctions dont les signatures ne correspondent pas.
Par exemple, vous devez déclarer une routine IoCompletion en utilisant le type de rôle de fonction IO_COMPLETION_ROUTINE :
IO_COMPLETION_ROUTINE myCompletionRoutine;
Lorsque vous implémentez myCompletionRoutine, les types de paramètres doivent correspondre à ceux utilisés par IO_COMPLETION_ROUTINE, à savoir PDEVICE_OBJECT, PIRP et PVOID (voir routine IoCompletion pour la syntaxe).
NTSTATUS
myCompletionRoutine(
PDEVICE_OBJECT DeviceObject,
PIRP Irp,
PVOID Context
)
{
}
Exécution de l’analyse de code pour les pilotes afin de vérifier les déclarations de fonctions
Pour vous aider à déterminer si le code source est prêt, exécutez Analyse de code pour les pilotes. L’Analyse de code pour les pilotes vérifie les déclarations de type de rôle de fonction et peut aider à identifier les déclarations de fonctions qui pourraient avoir été manquées ou vous avertir lorsque les paramètres de la définition de la fonction ne correspondent pas à ceux du type de rôle de fonction.