Sending a Device Set-Power IRP in Response to a System Set-Power IRP
The device power policy owner should take the following steps to respond to a system set-power IRP:
Call IoAcquireRemoveLock, passing the current IRP as the Tag parameter, to ensure that the driver does not receive a Plug and Play IRP_MN_REMOVE_DEVICE request while handling the power IRP.
If IoAcquireRemoveLock returns a failure status, the driver should not continue processing the IRP. Instead, starting with Windows Vista, the driver should call IoCompleteRequest to complete the request and then return the failure status. In Windows Server 2003, Windows XP, and Windows 2000, the driver should first call PoStartNextPowerIrp, call IoCompleteRequest to complete the IRP, and then return the failure status.
Set up the IRP stack location for the next-lower driver by calling IoCopyCurrentIrpStackLocationToNext.
Set an IoCompletion routine in the system set-power IRP.
Call IoMarkIrpPending to mark the system set-power IRP as pending.
Call IoCallDriver (starting with Windows Vista) or PoCallDriver (in Windows Server 2003, Windows XP, and Windows 2000) to pass the system set-power IRP to the next-lower driver.
Return STATUS_PENDING from its DispatchPower routine.
In the IoCompletion routine (see Step 3 in the preceding list), the device power policy owner sends a device set-power IRP as follows:
Inspect the system set-power IRP to get the requested system power state. Choose an appropriate device power state for that system power state. For further information, see Determining the Correct Device Power State.
Call PoRequestPowerIrp to send an IRP_MN_SET_POWER for the device power state determined in Step 1. The power policy owner must send the device set-power request even if the device is already in that state.
Specify a power-completion callback routine (CompletionFunction) in the call to PoRequestPowerIrp and pass the system set-power IRP in the Context buffer.
Return STATUS_MORE_PROCESSING_REQUIRED from the IoCompletion routine, so that the driver can finish processing the system set-power IRP in the power-completion callback routine.
Remember that the device power policy owner not only sends the device set-power IRP but also must handle this IRP as it travels through the device stack. Consequently, a device power policy owner might have not only a power-completion callback routine associated with the device set-power IRP and an IoCompletion routine for the system set-power IRP, but also an IoCompletion routine for the device set-power IRP. For further information, see Handling IRP_MN_SET_POWER for Device Power States.
After the I/O manager calls all the IoCompletion routines that were set as the device set-power IRP traveled down the device stack, the I/O manager calls the power-completion callback routine. By this time, all drivers in the stack have completed the device set-power IRP and the device power transition is complete.
The power-completion callback routine must do the following:
Call PoStartNextPowerIrp to start the next power IRP. (Windows Server 2003, Windows XP, and Windows 2000 only.)
Complete the system set-power IRP (IoCompleteRequest) with the status returned for the device set-power IRP.
Call IoReleaseRemoveLock to free the previously acquired lock.
Return the status with which the set-power IRPs completed.