在 UMDF 1.x 驱动程序中使用 USB 管道
警告
UMDF 2 是 UMDF 的最新版本,取代了 UMDF 1。 所有新的 UMDF 驱动程序都应使用 UMDF 2 编写。 不会向 UMDF 1 添加任何新功能,并且较新版本的 Windows 10 上对 UMDF 1 的支持有限。 通用 Windows 驱动程序必须使用 UMDF 2。
存档的 UMDF 1 示例可在 Windows 11 版本 22H2 - 2022 年 5 月驱动程序示例更新中找到。
有关详细信息,请参阅使用 UMDF 入门。
框架将 USB 接口中的每个管道表示为框架 USB 管道对象。 当驱动程序配置 USB 设备时,框架会为每个所选接口中的每个管道创建一个框架 USB 管道对象。 管道对象方法使驱动程序能够:
获取 UMDF-USB 管道信息
在 UMDF 驱动程序调用 IWDFUsbInterface::RetrieveUsbPipeObject 方法以获取指向 USB 管道对象的 IWDFUsbTargetPipe 接口的指针后,驱动程序可以调用 USB 管道对象为获取有关 USB 管道的信息而定义的以下方法:
IWDFUsbTargetPipe::GetInformation
检索有关 USB 管道及其终结点的信息。
IWDFUsbTargetPipe::GetType
返回 USB 管道的类型。
IWDFUsbTargetPipe::IsInEndPoint
确定 USB 管道是否连接到输入终结点。
IWDFUsbTargetPipe::IsOutEndPoint
确定 USB 管道是否连接到输出终结点。
IWDFUsbTargetPipe::RetrievePipePolicy
检索 WinUsb 管道策略。
从 UMDF-USB 管道读取
若要从 USB 输入管道读取数据,驱动程序可以使用 (或两者) 以下技术:
同步读取数据。
若要从 USB 输入管道同步读取数据,UMDF 驱动程序首先调用 IWDFIoTarget::FormatRequestForRead 方法来生成读取请求。 然后,驱动程序调用 IWDFIoRequest::Send 方法(指定WDF_REQUEST_SEND_OPTION_SYNCHRONOUS标志)以同步发送请求。
异步读取数据。
若要从 USB 输入管道异步读取数据,UMDF 驱动程序首先调用 IWDFIoTarget::FormatRequestForRead 方法来生成读取请求。 然后,驱动程序调用 IWDFIoRequest::Send 方法,而不指定 WDF_REQUEST_SEND_OPTION_SYNCHRONOUS 标志。
以同步和连续方式读取数据。
连续读取器是一种框架提供的机制,可确保读取请求始终可用于 USB 管道。 此机制保证驱动程序始终准备好从提供异步、未经请求的输入流的设备接收数据。 例如,网络接口卡 (NIC) 的驱动程序可能使用连续读取器来接收输入数据。
若要为输入管道配置连续读取器,驱动程序的 IPnpCallbackHardware::OnPrepareHardware 回调函数必须调用 IWDFUsbTargetPipe2::ConfigureContinuousReader 方法。 此方法将一组读取请求排队到设备的 I/O 目标。
此外,驱动程序的 IPnpCallback::OnD0Entry 回调 函数必须调用 IWDFIoTargetStateManagement::Start 来启动连续读取器,驱动程序的 IPnpCallback::OnD0Exit 回调函数必须调用 IWDFIoTargetStateManagement::Stop 来停止连续读取器。
每次从设备获取数据时, I/O 目标将完成读取请求,框架将调用两个回调函数之一: IUsbTargetPipeContinuousReaderCallbackReadComplete::OnReaderCompletion (如果 I/O 目标成功读取数据),或 IUsbTargetPipeContinuousReaderCallbackReadersFailed::OnReaderFailure (如果 I/O 目标报告错误)。
驱动程序调用 IWDFUsbTargetPipe2::ConfigureContinuousReader 后,驱动程序无法使用 IWDFIoRequest::Send 将 I/O 请求发送到管道,除非调用驱动程序的 IUsbTargetPipeContinuousReaderCallbackReadersFailed::OnReaderFailure 回调函数并返回 FALSE。
UMDF 1.9 及更高版本支持连续读取器。
写入 UMDF-USB 管道
若要将数据写入 USB 输出管道,UMDF 驱动程序可以首先调用 IWDFIoTarget::FormatRequestForWrite 方法来生成写入请求。 然后,驱动程序可以调用 IWDFIoRequest::Send 方法以异步方式发送请求。
停止、刷新和重置 UMDF-USB 管道
UMDF 驱动程序可以调用以下方法来停止、刷新或重置 USB 管道:
IWDFUsbTargetPipe::Abort
同步发送停止 USB 管道上所有挂起的传输的请求。
IWDFUsbTargetPipe::Flush
同步发送一个请求,以放弃当设备返回的数据多于客户端请求的数据时 WinUsb 保存的任何数据。
IWDFUsbTargetPipe::Reset
同步发送重置 USB 管道的请求。
设置 UMDF-USB 管道的策略
UMDF 驱动程序可以调用 IWDFUsbTargetPipe::SetPipePolicy 方法来控制 WinUsb 用于 USB 管道的行为, (例如超时、处理短数据包以及) 的其他行为。
处理管道错误
如果驱动程序的 USB 目标通过错误状态值 完成 I/O 请求,则驱动程序应执行以下操作:
调用 IWDFIoTargetStateManagement::Stop 并设置 WdfIoTargetCancelSentIo 标志。 如果目标尚未完成请求,此调用会停止管道并取消驱动程序已发送到 USB 目标的任何其他 I/O 请求。
调用 IWDFUsbTargetPipe::Abort 将中止请求发送到管道。
调用 IWDFUsbTargetPipe::Reset 将重置请求发送到管道。
调用 IWDFIoTargetStateManagement::Start 以重启管道。
重新发送失败的 I/O 请求,以及失败请求后的所有 I/O 请求。