在 WBDI 驱动程序中管理队列
WBDI 驱动程序应至少创建一个队列来处理来自服务的多个并发请求。 如果使用 UMDF,则可以利用其队列管理支持。
在 WudfBioUsbSample 中,CBiometricIoQueue 类将实现 I/O 队列接口。
具体而言,在方法 CBiometricIoQueue::Initialize
中,驱动程序查询拥有的 CBiometricIoQueue 对象,以获取指向框架用于确定驱动程序在队列上订阅的事件回调函数的 IQueueCallbackDeviceIoControl 接口的指针:
if (SUCCEEDED(hr))
{
hr = this->QueryInterface(__uuidof(IUnknown), (void **)&unknown);
}
然后驱动程序调用 IWDFDevice::CreateIoQueue 来配置默认 I/O 队列:
hr = FxDevice->CreateIoQueue(unknown,
FALSE,
WdfIoQueueDispatchParallel,
FALSE,
FALSE,
&fxQueue);
BiometricSafeRelease(unknown);
该调用将指定 WdfIoQueueDispatchParallel,以便框架在请求可用后立即向驱动程序的 I/O 队列回调函数提供请求。
接下来,驱动程序调用 IWDFDevice::ConfigureRequestDispatching,以来配置队列来筛选所有设备 I/O 请求:
hr = FxDevice->ConfigureRequestDispatching(fxQueue,
WdfRequestDeviceIoControl,
TRUE);
由于驱动程序在此调用中指定 WdfRequestDeviceIoControl,因此它提供 OnDeviceIoControl 处理程序来处理框架中的 I/O 通知。 在之前对 CreateIoQueue 的调用中,它在 IQueueCallbackDeviceIoControl::OnDeviceIoControl 方法中执行此操作,该方法是“unknown”参数的一部分。
一次只能有一个未完成的 IOCTL_BIOMETRIC_CAPTURE_DATA 请求。 驱动程序应通过内部保留指向挂起请求的指针,或使用另一个框架队列来处理这些请求,以便跟踪 IOCTL_BIOMETRIC_CAPTURE_DATA 请求。
在示例中,如果有挂起的 I/O 请求,该示例将维护指向 CBiometricDevice 类成员中请求的指针,如 Device.h 中定义:
IWDFIoRequest *m_PendingRequest;
当一个传感器数据收集 I/O 挂起时,对数据收集 IOCTL 的后续调用应会失败:
FxRequest->Complete(WINBIO_E_DATA_COLLECTION_IN_PROGRESS);
捕获请求已完成或被取消时,会将此值设置为 NULL:
IWDFIoRequest *FxRequest = (IWDFIoRequest *)InterlockedExchangePointer((PVOID *)&m_PendingRequest, NULL);