Synchronisation du code d’annulation et d’achèvement

Si votre pilote appelle WdfRequestMarkCancelable ou WdfRequestMarkCancelableEx pour rendre une demande d’E/S annulable, il existe un problème de synchronisation potentiel. Par exemple, votre pilote et votre appareil peuvent effectuer des opérations d’E/S de périphérique de manière asynchrone au moyen des fonctions de rappel EvtInterruptIsr et EvtInterruptDpc , et les fonctions de rappel EvtInterruptDpc et EvtRequestCancel peuvent contenir des appels à WdfRequestComplete.

Le pilote ne doit appeler WdfRequestComplete qu’une seule fois pour terminer ou annuler la demande. Toutefois, si les fonctions de rappel EvtInterruptDpc et EvtRequestCancel ne sont pas synchronisées les unes avec les autres, le framework peut en appeler une pendant l’exécution de l’autre.

Il est facile d’éviter ce problème si votre pilote utilise la synchronisation automatique de l’infrastructure, car la synchronisation automatique garantit que les fonctions de rappel sont appelées une par une.

Si votre pilote n’utilise pas la synchronisation automatique de l’infrastructure, il peut utiliser des verrous d’infrastructure pour synchroniser le code d’annulation et d’achèvement.

Que le pilote utilise la synchronisation automatique de l’infrastructure ou fournisse sa propre synchronisation, la fonction de rappel EvtRequestCancel du pilote doit appeler WdfRequestComplete pour annuler une demande. La fonction de rappel EvtInterruptDpc du pilote doit appeler WdfRequestUnmarkCancelable comme suit :

Status = WdfRequestUnmarkCancelable(Request);
if( Status != STATUS_CANCELLED ) {
    WdfRequestComplete(Request, RequestStatus);
    }

Ce code garantit que le pilote n’appelle pas WdfRequestComplete pour terminer la demande si le pilote l’a déjà appelée pour annuler la demande.

Pour plus d’informations sur les règles que votre pilote doit suivre lorsqu’il appelle WdfRequestUnmarkCancelable, consultez WdfRequestUnmarkCancelable.