处理设备通电 IRP
设备通电 IRP 指定 IRP_MN_SET_POWER 和需要比当前设备电源状态更多的电源的设备电源状态。 通常,上电 IRP 指定设备工作状态 PowerDeviceD0。
启动设备的请求必须首先由设备的基础总线驱动程序处理,然后由每个连续的驱动程序处理,以备份堆栈。
下图显示了处理启动 IRP 所涉及的步骤。
处理 IRP_MN_SET_POWER 启动请求时,函数或筛选器驱动程序必须:
调用 IoAcquireRemoveLock 以确保驱动程序在处理启动 IRP 时不会收到 IRP_MN_REMOVE_DEVICE 请求。
如果 IoAcquireRemoveLock 返回失败状态,驱动程序不应继续处理 IRP。 相反,从 Windows Vista 开始,驱动程序应调用 IoCompleteRequest 来完成 IRP,然后返回失败状态。 在 Windows Server 2003、Windows XP 和 Windows 2000 中,驱动程序应调用 IoCompleteRequest 以完成 IRP,然后调用 PoStartNextPowerIrp 以启动下一个电源 IRP,然后返回失败状态。
调用 IoMarkIrpPending 以将 IRP 标记为挂起。
调用 IoCopyCurrentIrpStackLocationToNext 以设置 IRP 堆栈位置。 如果驱动程序设置了 IoCompletion 例程,则不得调用 IoSkipCurrentIrpStackLocation。
调用 IoSetCompletionRoutine 以设置启动 IoCompletion 例程。
处理设备通电 IRP 时,驱动程序应设置 IoCompletion 例程,以还原上下文、释放删除锁,并在 IRP 完成后执行其他所需任务,并且设备通电。 在 IRP 完成之前,驱动程序不应还原上下文。 有关详细信息,请参阅 设备电源 IRP 的 IoCompletion 例程。
在 Windows 7 和 Windows Vista) 或 PoCallDriver (Windows Server 2003、Windows XP 和 Windows 2000) 调用 IoCallDriver (,将 IRP 传递到下一个较低的驱动程序。 IRP 必须一直沿着设备堆栈到达总线驱动程序。 仅允许总线驱动程序完成 IRP。
返回STATUS_PENDING。
当总线驱动程序收到 IRP 时,它应首先检查,以确保设备仍然存在,并且未在睡眠时被移除或更换。 如果设备不再存在,总线驱动程序应在父设备上调用 IoInvalidateDeviceRelations,以通知即插即用管理器设备已消失。 在这种情况下,总线驱动程序可能会使设备启动 IRP 失败。
如果设备仍然存在,则总线驱动程序将执行将设备恢复到运行条件所需的任务,调用 PoSetPowerState 以通知电源管理器新的设备电源状态,并完成 IRP (IoCompleteRequest) 。 如果驱动程序在设备处于睡眠状态时已排队 I/O,或者设备需要浪涌电源,则总线驱动程序会将电源应用于设备。 否则,总线驱动程序在必须与设备通信时立即通电。
有关实现从关机、待机和休眠状态快速启动的最佳做法列表,请参阅 提高系统启动性能。