Управление очередями в драйвере WBDI
Драйверы WBDI должны создавать по крайней мере одну очередь для обработки нескольких одновременных запросов из службы. Если вы используете UMDF, вы можете воспользоваться поддержкой управления очередями.
В WudfBioUsbSample класс CBiometricIoQueue реализует интерфейс очереди ввода-вывода.
В методе CBiometricIoQueue::Initialize
, в частности, драйвер запрашивает объект CBiometricIoQueue для указателя на интерфейс IQueueCallbackDeviceIoControl , который платформа использует для определения функций обратного вызова событий, которые драйвер подписывается на очередь:
if (SUCCEEDED(hr))
{
hr = this->QueryInterface(__uuidof(IUnknown), (void **)&unknown);
}
Затем драйвер вызывает IWDFDevice::CreateIoQueue , чтобы настроить очередь ввода-вывода по умолчанию:
hr = FxDevice->CreateIoQueue(unknown,
FALSE,
WdfIoQueueDispatchParallel,
FALSE,
FALSE,
&fxQueue);
BiometricSafeRelease(unknown);
Вызов указывает WdfIoQueueDispatchParallel, чтобы платформа отображала запросы к функциям обратного вызова очереди ввода-вывода драйвера, как только запросы будут доступны.
Затем драйвер вызывает IWDFDevice::ConfigureRequestDispatching , чтобы настроить очередь для фильтрации всех запросов ввода-вывода устройства:
hr = FxDevice->ConfigureRequestDispatching(fxQueue,
WdfRequestDeviceIoControl,
TRUE);
Так как драйвер задает WdfRequestDeviceIoControl в этом вызове, он предоставляет обработчик OnDeviceIoControl для обработки уведомлений ввода-вывода из платформы. Это делается в методе IQueueCallbackDeviceIoControl::OnDeviceIoControl , который является частью параметра "неизвестно" в вызове CreateIoQueue ранее.
Одновременно может быть только один невыполненные запросы IOCTL_BIOMETRIC_CAPTURE_DATA . Драйвер должен отслеживать IOCTL_BIOMETRIC_CAPTURE_DATA запросы, сохраняя указатель на ожидающие запросы или используя другую очередь платформы для обработки этих запросов.
В примере, если есть ожидающий запрос ввода-вывода, пример сохраняет указатель на запрос в члене класса CBiometricDevice, как определено в Device.h:
IWDFIoRequest *m_PendingRequest;
Хотя ожидается сбор данных одного датчика, последующие вызовы операций ввода-вывода коллекции данных должны завершиться ошибкой:
FxRequest->Complete(WINBIO_E_DATA_COLLECTION_IN_PROGRESS);
После завершения или отмены запроса записи это значение имеет значение NULL:
IWDFIoRequest *FxRequest = (IWDFIoRequest *)InterlockedExchangePointer((PVOID *)&m_PendingRequest, NULL);