控制常规 I/O 目标的状态
可以将 I/O 目标对象可视化为具有两个门:入口内和门外。 门外控制框架何时向目标设备对象传递请求,而门内控制何时允许请求进入 I/O 目标。
框架为常规 I/O 目标定义以下状态:
开始
I/O 目标对象的两个门都处于打开状态。 驱动程序可以将 I/O 请求发送到 I/O 目标队列,框架会将请求传送到相应的驱动程序。
停止
I/O 目标的入口处于打开状态,但门外已关闭。 框架停止向相应的驱动程序传递请求。 若要将 I/O 请求发送到 I/O 目标,驱动程序必须在每个请求的WDF_REQUEST_SEND_OPTIONS结构中设置WDF_REQUEST_SEND_OPTION_IGNORE_TARGET_STATE或WDF_REQUEST_SEND_OPTION_SEND_AND_FORGET。
清除
I/O 目标对象的两个门都已关闭。 驱动程序无法将 I/O 请求发送到 I/O 目标,除非设置 WDF_REQUEST_SEND_OPTION_IGNORE_TARGET_STATE 或 WDF_REQUEST_SEND_OPTION_SEND_AND_FORGET。 此外,框架还会取消 I/O 目标对象内部队列中未处理的请求。 此状态从 KMDF 版本 1.11 开始可用。
对于 Query-Remove 关闭
远程 I/O 目标暂时关闭,因为其设备可能很快就会被删除。
WDF_IO_TARGET_STATE枚举定义表示这些状态的值。 驱动程序可以调用 WdfIoTargetGetState 来获取 I/O 目标的状态。
本地 I/O 目标状态
框架会自动打开并启动本地 I/O 目标。
如有必要,驱动程序可以调用 WdfIoTargetStop 以暂时停止本地 I/O 目标,并调用 WdfIoTargetStart 来重启它。 例如,如果驱动程序检测到临时错误条件,则驱动程序可能会停止本地 I/O 目标,如果错误条件得到纠正,则重新启动该 I/O 目标。
在 KMDF 版本 1.11 及更高版本中,驱动程序可以调用 WdfIoTargetPurge ,以暂时阻止 I/O 请求发送到本地 I/O 目标,并取消目标队列中未处理的请求。 例如,作为文件句柄清理的一部分,驱动程序可能会清除本地 I/O 目标,以确保取消发送到驱动程序的所有请求。
如果删除了本地 I/O 目标的设备,框架会自动停止并关闭该 I/O 目标,并 取消 目标队列中的所有 I/O 请求。 框架通过调用设备对象事件回调函数通知驱动程序设备不再可用。 有关这些回调函数的详细信息,请参阅 PnP 和电源管理方案。
远程 I/O 目标状态
驱动程序必须调用 WdfIoTargetOpen 才能打开远程 I/O 目标。 当驱动程序打开远程 I/O 目标时,框架会自动启动 I/O 目标。
如有必要,驱动程序可以调用 WdfIoTargetStop 以暂时停止远程 I/O 目标,并调用 WdfIoTargetStart 来重启它。
在 KMDF 版本 1.11 及更高版本中,驱动程序可以调用 WdfIoTargetPurge ,以暂时阻止将 I/O 请求发送到远程 I/O 目标,并取消目标队列中未处理的请求。
如果删除远程 I/O 目标的设备,框架会自动停止并关闭 I/O 目标,并取消目标队列中的所有 I/O 请求,除非驱动程序注册以下事件回调函数:
EvtIoTargetQueryRemove
通知驱动程序远程 I/O 目标的设备可能已删除。 如果希望驱动程序允许删除设备,驱动程序必须调用 WdfIoTargetCloseForQueryRemove 。
EvtIoTargetRemoveComplete
通知驱动程序远程 I/O 目标的设备已删除。 此回调函数必须调用 WdfIoTargetClose。
EvtIoTargetRemoveCanceled
通知驱动程序删除远程 I/O 目标的设备的尝试已取消。 此回调函数必须调用 WdfIoTargetOpen,驱动程序通常调用 WDF_IO_TARGET_OPEN_PARAMS_INIT_REOPEN 来初始化其WDF_IO_TARGET_OPEN_PARAMS_INIT函数。
如果驱动程序已完成使用远程 I/O 目标,并且不再使用该目标,并且目标没有仍在挂起的子请求对象,则驱动程序可以在不首先调用 WdfIoTargetClose 的情况下调用 WdfObjectDelete。 如果目标具有任何仍在挂起的子请求对象,则驱动程序必须先调用 WdfIoTargetClose ,然后才能安全地调用 WdfObjectDelete。