Implémentation d’une routine d’annulation
Le gestionnaire d’E/S appelle une routine Cancel fournie par le pilote avec un IRP d’entrée à annuler et un pointeur DeviceObject qui représente l’appareil cible pour la demande d’E/S.
L’IRP peut être celui que la routine DispatchReadWrite du pilote a mis en file d’attente au moment où l’application Win32 actuelle est fermée par l’utilisateur. L’IRP peut également être celui qu’un pilote de niveau supérieur a explicitement annulé, en fonction de la nature de l’appareil sous-jacent.
Lorsque la routine Cancel est appelée, l’IRP d’entrée est peut-être déjà currentIrp dans l’objet d’appareil cible ou peut-être déjà dans la file d’attente d’appareil associée à l’objet d’appareil cible si le pilote a une routine StartIo . Si le pilote n’a pas de routine StartIo , l’IRP peut se trouver dans une file d’attente interne d’IRP gérée par le pilote lorsque sa routine d’annulation est appelée. Dans tous les cas, avant que le gestionnaire d’E/S appelle la routine Cancel pour l’IRP entrante, le gestionnaire d’E/S définit le membre Cancel dans cette IRP sur TRUE et définit le membre CancelRoutine dans l’IRP sur NULL.
La routine d’annulation d’une master IRP associée à des IRP est chargée d’appeler IoCancelIrp pour annuler ces irps associés.
Toutes les routines Cancel doivent suivre ces instructions :
Appelez IoReleaseCancelSpinLock pour libérer le verrouillage de rotation d’annulation du système.
Définissez le membre Status du bloc d’E/S status sur STATUS_CANCELLED et définissez son membre Information sur zéro.
Terminez l’IRP spécifié en appelant IoCompleteRequest.
Étant donné qu’une routine Cancel est toujours appelée avec le verrouillage de rotation d’annulation du système maintenu, cette routine ne doit pas appeler IoAcquireCancelSpinLock , sauf si elle appelle IoReleaseCancelSpinLock en premier.
Une routine Cancel ne peut pas contenir le verrou d’annulation de rotation système lorsqu’elle retourne le contrôle. Autrement dit, chaque routine Cancel doit appeler IoReleaseCancelSpinLock au moins une fois avant de retourner le contrôle.
Si elle appelle IoAcquireCancelSpinLock, une routine Cancel doit effectuer l’appel réciproque à IoReleaseCancelSpinLock aussi rapidement que possible.
N’appelez jamais IoCompleteRequest avec un IRP tout en maintenant un verrou de rotation. La tentative d’effectuer une IRP tout en tenant un verrou de rotation peut entraîner des interblocages.