Exécution des demandes d’e/s

Chaque pilote basé sur un Framework doit finaliser toutes les demandes d’e/s qu’il reçoit de l’infrastructure. Les pilotes terminent les demandes en appelant la méthode WdfRequestComplete, WdfRequestCompleteWithInformationou WdfRequestCompleteWithPriorityBoost de l’objet de requête.

Quand effectuer une demande

Un pilote doit effectuer une demande lorsqu’il détermine que l’un des cas suivants est vrai :

  • L’opération d’e/s demandée s’est terminée avec succès.

  • L’opération d’e/s demandée a été démarrée mais a échoué avant la fin.

  • L’opération d’e/s demandée n’est pas prise en charge ou n’est pas valide au moment où elle a été reçue et n’a pas pu être démarrée.

  • L’opération d’e/s demandée a été annulée.

Si le pilote pilote la requête d’e/s en créant une activité d’e/s sur l’appareil, le pilote appelle généralement WdfRequestComplete à partir de sa fonction de rappel EvtInterruptDpc ou EvtDpcFunc .

Si le pilote reçoit une demande non prise en charge ou non valide, il appelle généralement WdfRequestComplete à partir du Gestionnaire de demandes qui a reçu la demande.

Si l’opération d’e/s a été annulée, le pilote appelle généralement WdfRequestComplete à partir de sa fonction de rappel EvtRequestCancel .

Si le pilote transfère la requête d’e/s à une cible d’e/s, le pilote exécute la demande une fois que la cible d’e/s a terminé la demande, comme suit :

  • Si votre pilote transfère la requête d’e/s de façon synchrone à la cible d’e/s, l’appel du pilote à la cible d’e/s retourne uniquement une fois que le pilote de niveau inférieur a terminé la demande (à moins qu’une erreur ne se produise). Une fois la cible d’e/s retournée, votre pilote doit appeler WdfRequestComplete.

  • Si votre pilote transfère la demande d’e/s de façon asynchrone, vous souhaiterez que votre pilote soit averti lorsqu’un pilote de niveau inférieur termine la demande. Si votre pilote inscrit une fonction de rappel CompletionRoutine , l’infrastructure appelle cette fonction de rappel une fois que la cible d’e/s a terminé la demande. La fonction de rappel CompletionRoutine appelle généralement WdfRequestComplete.

Pour inscrire une fonction de rappel CompletionRoutine , le pilote doit appeler WdfRequestSetCompletionRoutine avant de transférer la requête d’e/s à une cible d’e/s.

Si votre pilote n’a pas besoin d’être notifié lorsqu’une cible d’e/s termine une demande d’e/s transférée de manière asynchrone, le pilote n’a pas besoin d’inscrire une fonction de rappel CompletionRoutine . Au lieu de cela, le pilote peut définir l’indicateur WDF_REQUEST_SEND_OPTION_SEND_AND_FORGET lors de l’appel de WdfRequestSend. Dans ce cas, le pilote n’appelle pas WdfRequestComplete.

Un pilote ne termine pas une demande d’e/s qu’il a créée en appelant WdfRequestCreate ou WdfRequestCreateFromIrp. Au lieu de cela, le pilote doit appeler WdfObjectDelete pour supprimer l’objet de requête, généralement après la fin de la demande d’une cible d’e/s.

Par exemple, un pilote peut recevoir une demande de lecture ou d’écriture pour une quantité de données plus volumineuse que les cibles d’e/s du pilote peuvent gérer à la fois. Le pilote doit diviser les données en plusieurs requêtes plus petites et envoyer ces requêtes plus petites à une ou plusieurs cibles d’e/s. Les techniques permettant de gérer cette situation sont les suivantes :

  • Appel de WdfRequestCreate pour créer un objet de requête supplémentaire unique qui représente une demande plus petite.

    Le pilote peut envoyer cette demande de manière synchrone à une cible d’e/s. La fonction de rappel CompletionRoutine de la demande plus petite peut appeler WdfRequestReuse afin que le pilote puisse réutiliser la demande et l’envoyer à nouveau à la cible d’e/s. Une fois que la cible d’e/s a terminé la dernière des demandes les plus petites, la fonction de rappel CompletionRoutine peut appeler WdfObjectDelete pour supprimer l’objet de requête créé par le pilote et le pilote peut appeler WdfRequestComplete pour terminer la demande d’origine.

  • Appel de WdfRequestCreate pour créer plusieurs objets de requête supplémentaires qui représentent les demandes plus petites.

    Les cibles d’e/s du pilote peuvent traiter ces requêtes plus petites de manière asynchrone. Le pilote peut inscrire une fonction de rappel CompletionRoutine pour chacune des plus petites requêtes. Chaque fois que la fonction de rappel CompletionRoutine est appelée, elle peut appeler WdfObjectDelete pour supprimer un objet de requête créé par un pilote. Une fois que la cible d’e/s a terminé toutes les plus petites requêtes, le pilote peut appeler WdfRequestComplete pour terminer la demande d’origine.

Fourniture d’informations sur la saisie semi-automatique

Lorsqu’un pilote termine une demande, il peut éventuellement fournir des informations supplémentaires auxquelles d’autres pilotes peuvent accéder. Par exemple, un pilote peut fournir le nombre d’octets qui ont été transférés pour une demande de lecture ou d’écriture. Pour fournir ces informations, le pilote peut effectuer l’une des opérations suivantes :

Obtention d’informations de saisie semi-automatique

Pour obtenir des informations sur une demande d’e/s terminée par un autre pilote, un pilote peut effectuer les opérations suivantes :

Si un pilote envoie une demande d’e/s de façon synchrone, il appelle généralement WdfRequestGetStatus, WdfRequestGetCompletionParamset WdfRequestGetInformation après le retour de l’appel synchrone. Si un pilote envoie une demande d’e/s de manière asynchrone, il appelle généralement ces méthodes à partir d’une fonction de rappel CompletionRoutine .

Pour plus d’informations sur l’exécution des demandes d’e/s, consultez synchronisation du code d’annulation et de fin.