处理 IRP_MN_STOP_DEVICE 请求(Windows 2000 和更高版本)

IRP_MN_STOP_DEVICE请求首先由设备堆栈中的顶部驱动程序处理,然后由下一个较低的驱动程序处理。 驱动程序在其 DispatchPnP 例程中处理停止 IRP。

驱动程序使用如下过程处理 IRP_MN_STOP_DEVICE 请求:

  1. 确保设备已暂停。

    如果驱动程序没有完全暂停设备以响应 IRP_MN_QUERY_STOP_DEVICE 请求,则必须立即暂停设备。 在设备扩展中设置HOLD_NEW_REQUESTS标志,并执行任何其他必要的操作来暂停设备。

    设备可能会在资源重新均衡操作期间断电,因此可能会丢失设备状态。 设备的驱动程序应保存任何设备状态信息,并在收到后续 IRP_MN_START_DEVICE 请求时还原它。

  2. 释放设备的硬件资源。

    在函数驱动程序中,确切的操作取决于设备和驱动程序,但可能包括使用 IoDisconnectInterrupt 断开中断、使用 MmUnmapIoSpace 释放物理地址范围以及释放 I/O 端口。

    如果筛选器或总线驱动程序获取了设备的任何硬件资源,该驱动程序必须释放资源以响应 IRP_MN_STOP_DEVICE 请求。

  3. Irp-IoStatus.Status> 设置为 STATUS_SUCCESS。

  4. 将 IRP 传递到下一个较低的驱动程序或完成 IRP。

    • 在函数或筛选器驱动程序中,使用 IoSkipCurrentIrpStackLocation 设置下一个堆栈位置,使用 IoCallDriver 将 IRP 传递给下一个较低的驱动程序,并将 IoCallDriver 的状态作为 DispatchPnP 例程中的返回状态返回。 不要完成 IRP。

    • 在总线驱动程序中,使用 IoCompleteRequest 和 IO_NO_INCREMENT 完成 IRP,并从 DispatchPnP 例程返回。

停止设备以重新平衡资源时,驱动程序无法启动访问该设备的任何 IRP。 如 设备暂停时保留传入 IRP 中所述,驱动程序必须将此类 IRP 排队;如果驱动程序未实现 IRP 保留队列且不得删除 I/O 请求,则驱动程序必须将其排入队列。