控制常规 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_STATEWDF_REQUEST_SEND_OPTION_SEND_AND_FORGET。 此外,框架还会取消 I/O 目标对象内部队列中未处理的请求。 此状态从 KMDF 版本 1.11 开始可用。

对于 Query-Remove 关闭
远程 I/O 目标暂时关闭,因为其设备可能很快就会被删除。

关闭
I/O 目标已关闭,无法启动或停止。

删除
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