Répartition des IRPs vers les files d’attente d’E/S
[S’applique à KMDF et UMDF]
Un pilote basé sur l’infrastructure peut spécifier dynamiquement une file d’attente cible pour un IRP entrant. Pour distribuer un IRP à une file d’attente spécifique, un pilote doit appeler la méthode WdfDeviceWdmDispatchIrpToIoQueue .
En règle générale, un pilote appelle WdfDeviceWdmDispatchIrpToIoQueue à partir de sa fonction de rappel EvtDeviceWdmIrpPreprocess ou EvtDeviceWdmIrpDispatch . Pour de meilleures performances, la plupart des pilotes ne fournissent pas les deux fonctions de rappel.
Note Un pilote UMDF peut fournir une fonction de rappel EvtDeviceWdmIrpDispatch , mais seuls les pilotes KMDF peuvent fournir EvtDeviceWdmIrpPreprocess.
Si votre pilote fournit déjà EvtDeviceWdmIrpPreprocess, vous pouvez l’utiliser pour sélectionner dynamiquement une file d’attente. Si ce n’est pas le cas, fournissez EvtDeviceWdmIrpDispatch et appelez WdfDeviceWdmDispatchIrpToIoQueue à partir de cette fonction de rappel.
En outre, vous devez être conscient des éléments suivants :
Une autre méthode pour distribuer un IRP dans une file d’attente d’E/S consiste à créer une file d’attente par défaut , puis à partir du gestionnaire de la file d’attente, appelez WdfRequestForwardToIoQueue. Cette technique est disponible à partir de KMDF 1.0, mais elle ne fonctionne pas bien avec les files d’attente de progression et est généralement plus lente. Envisagez plutôt d’utiliser WdfDeviceWdmDispatchIrpToIoQueue .
Lorsque vous appelez WdfDeviceConfigureWdmIrpDispatchCallback pour inscrire une fonction de rappel EvtDeviceWdmIrpDispatch , le pilote doit définir le paramètre MajorFunction sur l’un des éléments suivants : IRP_MJ_DEVICE_CONTROL, IRP_MJ_INTERNAL_DEVICE_CONTROL, IRP_MJ_READ, IRP_MJ_WRITE. Bien que cette exigence ne s’applique pas à EvtDeviceWdmIrpPreprocess, seuls les IRP de ces types peuvent être distribués dynamiquement dans des files d’attente spécifiées.
Les irPs qui vont à EvtDeviceWdmIrpPreprocess ont un emplacement de pile supplémentaire. Les irPs qui vont à EvtDeviceWdmIrpDispatch (sans appel précédent d’EvtDeviceWdmIrpPreprocess) ne le font pas.
EvtDeviceWdmIrpPreprocess ne facilite pas l’envoi d’informations de contexte définies par le pilote, contrairement à EvtDeviceWdmIrpDispatch .
Répartition des irps non prétraités
Pour distribuer des IRPs à partir de la fonction de rappel EvtDeviceWdmIrpDispatch d’un pilote, procédez comme suit :
À partir de sa fonction de rappel EvtDriverDeviceAdd , le pilote appelle WdfDeviceConfigureWdmIrpDispatchCallback pour inscrire une fonction de rappel EvtDeviceWdmIrpDispatch .
Si la cible est la file d’E/S de l’appareil parent, un pilote KMDF doit appeler WdfPdoInitAllowForwardingRequestToParent avant d’appeler WdfDeviceCreate. Si un pilote KMDF a également fourni une fonction de rappel EvtDeviceWdmIrpPreprocess , l’infrastructure appelle d’abord cette fonction lorsqu’un IRP arrive. Une fois que la fonction de rappel a prétraité la demande, elle appelle WdfDeviceWdmDispatchPreprocessedIrp pour renvoyer l’IRP à l’infrastructure.
L’infrastructure appelle la fonction de rappel EvtDeviceWdmIrpDispatch du pilote.
À partir d’EvtDeviceWdmIrpDispatch, le pilote peut appeler WdfDeviceWdmDispatchIrpToIoQueue ou WdfDeviceWdmDispatchIrp, mais pas les deux. Un pilote KMDF a la possibilité supplémentaire d’appeler l’une ou l’autre de ces méthodes et de terminer l’IRP ou de la marquer en attente.
Si un pilote KMDF a défini l’indicateur WDF_DISPATCH_IRP_TO_IO_QUEUE_INVOKE_INCALLERCTX_CALLBACK et n’a pas activé la progression vers l’avant garantie pour la file d’attente d’E/S cible, l’infrastructure appelle le evtIoInCallerContext du pilote, s’il est fourni. Après le prétraitement de la demande, la fonction de rappel doit la mettre en file d’attente en appelant WdfDeviceEnqueueRequest ou la terminer en appelant WdfRequestComplete.
Répartition des irps prétraités
Pour distribuer des IRPs à partir de la fonction de rappel EvtDeviceWdmIrpPreprocess d’un pilote vers une file d’E/S spécifique, procédez comme suit :
- Le pilote inscrit une fonction de rappel EvtDeviceWdmIrpPreprocess en appelant WdfDeviceInitAssignWdmIrpPreprocessCallback.
- Le pilote appelle WdfPdoInitAllowForwardingRequestToParent si la cible est la file d’E/S de l’appareil parent.
- À partir d’EvtDeviceWdmIrpPreprocess, appelez WdfDeviceWdmDispatchIrpToIoQueue avec flags définis sur WDF_DISPATCH_IRP_TO_IO_QUEUE_PREPROCESSED_IRP.
- Si le pilote a défini l’indicateur WDF_DISPATCH_IRP_TO_IO_QUEUE_INVOKE_INCALLERCTX_CALLBACK et n’a pas activé la progression vers l’avant garantie pour la file d’attente d’E/S cible, l’infrastructure appelle le evtIoInCallerContext du pilote, s’il est fourni. Une fois que la fonction de rappel a terminé le prétraitement de la demande, elle doit la mettre en file d’attente en appelant WdfDeviceEnqueueRequest ou la terminer en appelant WdfRequestComplete.