Synchronisation de l’annulation des demandes envoyées

Lorsqu’un pilote tente d’annuler une demande d’E/S qu’il a transférée à une cible d’E/S, il doit s’assurer qu’il transmet un handle de requête valide à la méthode WdfRequestCancelSentRequest . Le handle de requête devient non valide si la cible d’E/S termine la demande, car la fonction de rappel CompletionRoutine du pilote appelle WdfRequestComplete (qui tente de supprimer l’objet de requête).

Pour éviter ce problème, le pilote peut effectuer le suivi des demandes qu’il a envoyées à la cible d’E/S, par exemple en créant une collection d’objets de requête. Le pilote peut appeler WdfSpinLockAcquire pour synchroniser l’accès à la collection.

Lorsque la fonction de rappel CompletionRoutine du pilote est appelée, elle acquiert le verrou, supprime le handle de la requête terminée de la collection et appelle WdfSpinLockRelease pour libérer le verrou.

Avant de tenter d’annuler une demande que le pilote a transférée à une cible d’E/S, le pilote peut :

  1. Appelez WdfSpinLockAcquire pour acquérir un verrou de rotation.

  2. Recherchez le handle de l’objet de requête dans la collection pour vous assurer que la routine d’achèvement du pilote n’a pas terminé la demande et supprimé le handle de la collection.

  3. Appelez WdfObjectReference pour incrémenter le nombre de références de l’objet de requête afin que l’objet ne puisse pas être supprimé.

  4. Appelez WdfSpinLockRelease pour libérer le verrou de rotation.

  5. Appelez WdfRequestCancelsentRequest.

  6. Appelez WdfObjectDereference pour décrémenter le nombre de références de l’objet.

Cette séquence garantit que si la cible d’E/S termine la requête avant que le pilote appelle WdfRequestCancelSentRequest, le handle de la requête est toujours valide (en raison du nombre de références incrémentées), même si la fonction de rappel CompletionRoutine du pilote appelle WdfRequestComplete.