Gestion d’un IRP Query-Power système dans un propriétaire de stratégie d’alimentation d’appareil
Lorsqu’un propriétaire de stratégie d’alimentation d’appareil reçoit un IRP_MN_QUERY_POWER pour un état d’alimentation du système, il répond en transmettant la requête et, dans une routine IoCompletion , en envoyant un IRP_MN_QUERY_POWER pour l’état d’alimentation d’un appareil. Lorsque tous les pilotes de la pile ont terminé la requête d’appareil, le propriétaire de la stratégie d’alimentation de l’appareil termine la requête système.
Un propriétaire de stratégie d’alimentation d’appareil doit effectuer les étapes suivantes dans sa routine DispatchPower pour répondre à une requête système :
Appelez IoAcquireRemoveLock, en passant l’IRP actuel, pour vous assurer que le pilote ne reçoit pas de demande de IRP_MN_REMOVE_DEVICE PnP lors de la gestion de l’IRP d’alimentation.
Si IoAcquireRemoveLock retourne un échec status, le pilote ne doit pas continuer à traiter l’IRP. Au lieu de cela, à compter de Windows Vista, le pilote doit appeler IoCompleteRequest pour terminer l’IRP et retourner l’échec status. Dans Windows Server 2003, Windows XP et Windows 2000, le pilote doit appeler PoStartNextPowerIrp, appeler IoCompleteRequest pour terminer l’IRP et retourner l’échec status.
Vérifiez que le pilote peut prendre en charge l’état d’alimentation du système interrogé, comme décrit dans Échec d’un Query-Power IRP système dans un filtre ou un pilote de fonction. Si ce n’est pas le cas, terminez l’IRP avec un échec status comme décrit dans cette section.
Toutefois, un pilote ne doit pas faire échouer une requête pour S4 (PowerSystemHibernate) si son appareil est activé pour la mise en éveil, mais qu’il ne peut pas sortir le système de l’état de veille prolongée. Dans ce cas, le propriétaire de la stratégie d’alimentation du pilote (qui a envoyé le IRP_MN_WAIT_WAKE) doit annuler l’IRP d’attente/veille et réussir la requête système. Pour plus d’informations, consultez Annulation d’un IRP d’attente/éveil.
Si le pilote peut prendre en charge l’état d’alimentation du système interrogé, appelez IoMarkIrpPending.
Configurez l’emplacement de la pile IRP pour le pilote inférieur suivant en appelant IoCopyCurrentIrpStackLocationToNext.
Définissez une routine IoCompletion dans l’IRP de la requête système.
Appelez IoCallDriver (dans Windows 7 et Windows Vista) ou PoCallDriver (dans Windows Server 2003, Windows XP et Windows 2000) pour passer l’IRP au pilote inférieur suivant.
Retourne STATUS_PENDING.
La routine IoCompletion doit effectuer les opérations suivantes :
Vérifiez Irp-IoStatus.Status> pour vous assurer que les pilotes inférieurs ont correctement effectué l’IRP. Si un pilote inférieur a spécifié une valeur NTSTATUS non réussie, la routine IoCompletion doit retourner la valeur NTSTATUS.
Si les pilotes inférieurs ont réussi l’IRP, appelez PoRequestPowerIrp pour envoyer un IRP d’alimentation de requête d’appareil pour un état d’alimentation du périphérique valide pour l’état d’alimentation du système interrogé. Si nécessaire, consultez le tableau DEVICE_STATE dans la structure DEVICE_CAPABILITIES pour déterminer quels états d’alimentation de l’appareil sont valides pour l’état d’alimentation du système interrogé.
Spécifiez une routine de rappel (paramètre CompletionFunction ) dans l’appel à PoRequestPowerIrp et transmettez l’IRP système dans la zone Contexte .
Retournez STATUS_MORE_PROCESSING_REQUIRED afin que le pilote puisse terminer le traitement de l’IRP de requête système dans la routine de rappel.
Une fois l’IRP terminée et toutes les routines IoCompletion définies pendant le traitement IRP ont été exécutées, le gestionnaire d’alimentation, via le gestionnaire d’E/S, appelle la routine de rappel du gestionnaire de stratégie d’alimentation (le paramètre CompletionFunction à PoRequestPowerIrp). La routine de rappel, à son tour, doit effectuer les opérations suivantes :
Appelez PoStartNextPowerIrp pour démarrer le IRP d’alimentation suivant. (Windows Server 2003, Windows XP et Windows 2000 uniquement.)
Effectuez l’IRP de puissance de requête du système (appelez IoCompleteRequest) avec la status retournée pour l’IRP de requête-alimentation de l’appareil.
Appelez IoReleaseRemoveLock pour libérer le verrou précédemment acquis.
N’oubliez pas que le propriétaire de la stratégie d’alimentation de l’appareil non seulement envoie la requête de l’appareil, mais qu’il doit également la gérer sur son chemin vers le bas de la pile de l’appareil. Pour plus d’informations, consultez Gestion des IRP_MN_QUERY_POWER pour les états d’alimentation des appareils.