Annulation d’un IRP d’attente/veille
Seul le pilote qui a envoyé une IRP d’attente/veille peut annuler cette IRP.
Un pilote peut avoir besoin d’annuler une IRP d’attente/veille en attente dans les circonstances suivantes :
Le pilote reçoit une demande pnP IRP_MN_STOP_DEVICE, IRP_MN_QUERY_REMOVE_DEVICE, IRP_MN_REMOVE_DEVICE ou IRP_MN_SURPRISE_REMOVAL pour l’appareil. Le pilote doit réémettre l’IRP d’attente/éveil (PoRequestPowerIrp) après le redémarrage de l’appareil.
Le système est en veille, mais l’appareil ne doit pas être activé pour sortir le système.
Par exemple, le pilote du hub USB peut envoyer une demande de IRP_MN_WAIT_WAKE au démarrage de l’appareil au cas où l’un de ses périphériques d’entrée serait ensuite mis en veille. Lorsque le système est dans l’état de fonctionnement, un signal de veille de l’appareil retourne l’appareil à l’état de fonctionnement (mais n’a aucun effet sur l’état d’alimentation du système). Lorsque le système se prépare à s’arrêter, le pilote du hub USB annule cette IRP si l’appareil ne doit pas être autorisé à réveiller le système.
Le système entre dans un état de veille à partir duquel l’appareil ne peut pas le réveiller. Autrement dit, il entre dans un état moins alimenté que la valeur SystemWake spécifiée dans sa structure de DEVICE_CAPABILITIES .
L’appareil entre dans un état d’alimentation à partir duquel il ne peut pas répondre à un signal de sortie de veille. Autrement dit, il entre dans un état moins alimenté que la valeur DeviceWake spécifiée dans sa structure de DEVICE_CAPABILITIES .
Pour annuler une IRP d’attente/sortie de veille, le pilote qui a envoyé l’IRP appelle IoCancelIrp, en passant le pointeur vers l’IRP qui a été précédemment retourné lorsque le pilote a appelé PoRequestPowerIrp.
Un pilote ne doit pas annuler un IRP d’attente/veille qu’il n’a pas envoyé.
Annuler des routines pour les irps d’attente/éveil
De nombreux pilotes de fonction et de bus doivent définir des routines d’annulation pour les irps d’attente/éveil en attente ; Les types de pilotes suivants doivent définir ces routines :
Pilotes qui modifient les paramètres de l’appareil pour activer ou désactiver la mise en éveil.
Pilotes qui envoient des requêtes IRP_MN_WAIT_WAKE aux pilotes d’appareils parents.
Une routine d’annulation permet à un pilote de désactiver la mise en éveil de son appareil et de propre toutes les données liées à l’IRP d’attente/éveil en attente. Les pilotes qui demandent des irps d’attente/éveil pour les appareils parents peuvent également annuler ces irps.
Dans sa routine d’annulation d’attente/veille, un pilote doit effectuer les étapes suivantes :
Appelez IoSetCancelRoutine pour réinitialiser la routine Annuler pour l’IRP sur NULL.
Appelez IoReleaseCancelSpinLock, en passant le CancelIRQL spécifié dans l’IRP pour libérer le verrou de rotation d’annulation pour l’IRP.
Réinitialisez tous les champs pertinents dans l’extension d’appareil. Par exemple, lorsqu’un IRP d’attente/veille est en attente, la plupart des pilotes définissent un indicateur et conservent un pointeur vers l’IRP dans l’extension de périphérique.
Notez qu’il est possible pour un pilote de recevoir un IRP d’attente/éveil pendant qu’il annule un autre IRP de ce type. Le pilote doit case activée pour voir s’il dispose déjà d’une IRP sous protection de verrouillage de rotation (ou son équivalent). Si c’est le cas, le pilote doit synchroniser soigneusement sa gestion pour s’assurer qu’il annule le bon IRP. Pour plus d’informations sur l’utilisation de verrous de rotation dans Annuler les routines, consultez Annulation des irps.
Modifiez les paramètres d’appareil requis. Par exemple, un pilote de modem désactive le paramètre de sortie de veille de l’appareil.
Définissez Irp-IoStatus.Status> sur STATUS_CANCELLED.
Appelez IoCompleteRequest pour terminer l’IRP d’attente/veille, en spécifiant IO_NO_INCREMENT.
Si le pilote a précédemment demandé un IRP_MN_WAIT_WAKE associé pour un appareil parent, il doit annuler cette IRP à partir de sa routine Cancel . Le pilote doit relâcher le verrou d’annulation de rotation avant d’annuler l’IRP du parent.
Par exemple, un pilote qui agit en tant que pilote de bus pour un appareil et possède un pilote de stratégie d’alimentation pour son parent doit annuler une IRP d’attente/veille associée qu’il a précédemment envoyée à son parent. L’appel d’IoCancelIrp appelle la routine Cancel du parent, et ainsi de suite dans la pile de l’appareil.