Поделиться через


Управление очередями в драйвере 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;

Пока ожидается завершение операции ввода-вывода по сбору данных одного датчика, последующие вызовы IOCTLs для сбора данных должны завершиться ошибкой.

FxRequest->Complete(WINBIO_E_DATA_COLLECTION_IN_PROGRESS);

После завершения или отмены запроса записи это значение имеет значение NULL:

IWDFIoRequest *FxRequest = (IWDFIoRequest *)InterlockedExchangePointer((PVOID *)&m_PendingRequest, NULL);