Control de IRP_MN_QUERY_POWER para estados de energía del dispositivo
Un IRP de consulta de dispositivo consulta sobre un cambio de estado para un único dispositivo y se envía a todos los controladores de la pila del dispositivo. Este tipo de IRP especifica DevicePowerState en el miembro Power.Type de la ubicación de pila de E/S.
Los controladores controlan los IRP de alimentación de consultas a medida que se desplazan por la pila.
Una función o un controlador de filtro pueden producir un error en una solicitud de IRP_MN_QUERY_POWER si se cumple alguna de las siguientes condiciones:
El dispositivo está habilitado para reactivación y el estado de energía solicitado está por debajo del estado desde el que el dispositivo puede reactivar el sistema. Por ejemplo, un dispositivo que puede reactivar el sistema desde D2 pero no desde D3 produciría un error en una consulta para D3, pero que se realiza correctamente en una consulta para D2.
Al escribir el estado solicitado, el controlador abandonaría una operación que perdería datos, como una conexión de módem abierta. Un controlador rara vez producirá un error en una consulta por este motivo; en la mayoría de las circunstancias, la aplicación controla estos casos.
Para producir un error en una solicitud de IRP_MN_QUERY_POWER , un controlador realiza los pasos siguientes:
Llame a PoStartNextPowerIrp para indicar que el controlador está preparado para controlar el siguiente IRP de energía. (Solo Windows Server 2003, Windows XP y Windows 2000).
Establezca Irp-IoStatus.Status> en un estado de error y llame a IoCompleteRequest y especifique IO_NO_INCREMENT. El controlador no pasa el IRP más abajo de la pila del dispositivo.
Devuelve un estado de error de su rutina DispatchPower .
Si el controlador se realiza correctamente el IRP de alimentación de consultas, no debe iniciar ninguna operación ni realizar ninguna otra acción que impida que se complete correctamente una solicitud de IRP_MN_SET_POWER posterior al estado de energía consultado.
Un controlador que realice correctamente el IRP debe prepararse para un IRP de energía establecida para el estado consultado y pasar el IRP de consulta, como se indica a continuación:
Finalice las operaciones de E/S pendientes.
Poner en cola las solicitudes de E/S entrantes.
Evite iniciar otras actividades nuevas que interferirían con una transición al estado de energía especificado. Sin embargo, el controlador no debe guardar el contexto del dispositivo ni seguir otros pasos hacia el apagado.
Llame a IoCopyCurrentIrpStackLocationToNext para establecer la ubicación de la pila irP para el controlador siguiente inferior.
Establezca una rutina de IoCompletion . En la rutina IoCompletion , llame a PoStartNextPowerIrp (Solo Windows Server 2003, Windows XP y Windows 2000) para indicar la preparación del controlador para controlar el siguiente IRP de energía.
Llame a IoCallDriver (en Windows 7 y Windows Vista) o PoCallDriver (en Windows Server 2003, Windows XP y Windows 2000) para pasar la consulta IRP al controlador inferior siguiente. No complete el IRP.
Devuelve STATUS_PENDING. El controlador no debe cambiar el valor en Irp-IoStatus.Status>.
Cuando el IRP de alimentación de consulta llega al controlador de bus, el controlador de bus llama a PoStartNextPowerIrp (Solo Windows Server 2003, Windows XP y Windows 2000) y establece Irp-IoStatus.Status> en STATUS_SUCCESS si el controlador puede cambiar al estado de energía especificado o establece un estado de error si no lo puede. A continuación, el controlador de bus llama a IoCompleteRequest, especificando IO_NO_INCREMENT.
Los controladores de una pila de dispositivos típica controlan un IRP de consulta de dispositivo de la siguiente manera:
La mayoría de los controladores de filtro simplemente deben pasar el IRP al controlador inferior siguiente (consulte Pasar IRP de Power) y devolver STATUS_PENDING. Sin embargo, es posible que algunos controladores de filtro tengan que realizar tareas específicas del dispositivo, como poner en cola los IRP entrantes o guardar el estado de energía del dispositivo.
Un controlador de función realiza tareas específicas del dispositivo (por ejemplo, completar solicitudes de E/S pendientes, poner en cola solicitudes de E/S entrantes, guardar el contexto del dispositivo o cambiar la energía del dispositivo), establece una rutina de IoCompletion y pasa el IRP de energía del dispositivo al controlador inferior siguiente (consulte Paso de IRP de Power). Devuelve STATUS_PENDING de su rutina DispatchPower .
El controlador de autobús llama a PoStartNextPowerIrp (solo Windows Server 2003, Windows XP y Windows 2000) para iniciar el siguiente IRP de energía. A continuación, completa el IRP, especificando IO_NO_INCREMENT. Si el controlador no puede completar el IRP inmediatamente, llama a IoMarkIrpPending, devuelve STATUS_PENDING de su rutina DispatchPower y completa el IRP más adelante.
Incluso si el dispositivo de destino ya está en estado de alimentación consultado, cada función o controlador de filtro debe poner en cola E/S y pasar el IRP al controlador inferior siguiente. El IRP debe viajar hasta la pila del dispositivo hasta el controlador de autobús, que lo completa.
Al controlar una solicitud de IRP_MN_QUERY_POWER , un controlador debe volver de la rutina DispatchPower lo antes posible. Un controlador no debe esperar en su rutina DispatchPower para un evento de kernel señalado por código que controla el mismo IRP. Dado que los IRP de energía se sincronizan en todo el sistema, puede producirse un interbloqueo.