处理函数 (FDO) 或筛选器驱动程序(筛选器 DO)中的等待/唤醒 IRP

当创建 FDO 或筛选器 DO 的驱动程序收到关联 PDO 的IRP_MN_WAIT_WAKE 请求时,它可以直接将 IRP 向下传递到下一个较低级别的驱动程序,或者在传递 IRP 之前执行某些操作。

对于支持Wake-Up的设备

收到等待/唤醒 IRP 后,函数或筛选器驱动程序应执行以下步骤:

  1. 调用 IoAcquireRemoveLock,传递当前 IRP,以确保驱动程序在处理等待/唤醒 IRP 时不会收到 PnP IRP_MN_REMOVE_DEVICE 请求。

    如果 IoAcquireRemoveLock 返回失败状态,驱动程序不应继续处理 IRP。 相反,它会完成 IRP (IoCompleteRequest) ,并返回失败状态。

  2. 检查 Irp-Parameters.WaitWake.PowerState> 处的值,并将当前设备电源状态与DEVICE_CAPABILITIES结构中的 DeviceState[SystemWake] 进行比较。

    如果设备支持唤醒,但不支持从指定的 SystemWake 状态或不是从当前设备电源状态唤醒,则驱动程序应使 IRP 失败,如下所示:

    • Irp-IoStatus.Status> 中设置STATUS_INVALID_DEVICE_STATE。
    • 完成 IRP (IoCompleteRequest) ,将优先级提升指定为IO_NO_INCREMENT。
    • DispatchPower 例程返回 Irp-IoStatus.Status> 中设置的状态。
  3. 否则,请使用 IoSetCompletionRoutine 为 IRP 设置 IoCompletion 例程IoCompletion 例程应执行驱动程序要求将设备恢复到工作状态所需的任何任务。

    如果取消 IRP,还将调用 IoCompletion 例程。

  4. 将驱动程序可能需要的任何信息保存在其 IoCompletion 例程中。

  5. 在 Windows 7 和 Windows Vista) 中调用 IoCallDriver (,或在 Windows Server 003、Windows XP 和 Windows 2000) 中调用 PoCallDriver (,将等待/唤醒 IRP 传递给下一个较低的驱动程序。

  6. 调用 IoReleaseRemoveLock 以释放以前获取的锁。

  7. DispatchPower 例程返回STATUS_PENDING。 驱动程序在保存 IRP 时不得更改 Irp-IoStatus.Status> 中的值。

对于不支持 Wake-Up

如果函数或筛选器驱动程序收到不支持唤醒的设备的等待/唤醒 IRP,则驱动程序应使 IRP 失败,如下所示:

  1. 完成 IRP (IoCompleteRequest) ,将优先级提升指定为IO_NO_INCREMENT。

  2. DispatchPower 例程返回 Irp-IoStatus.Status> 中设置的状态。