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


Управление очередями в драйвере 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 , который является частью параметра unknown в вызове CreateIoQueue ранее.

Одновременно может существовать только один незаполненные запрос IOCTL_BIOMETRIC_CAPTURE_DATA . Драйвер должен отслеживать IOCTL_BIOMETRIC_CAPTURE_DATA запросы, сохраняя внутренний указатель на ожидающие запросы или используя другую очередь платформы для обработки этих запросов.

При наличии ожидающего запроса ввода-вывода в примере сохраняется указатель на запрос в члене класса CBiometricDevice, как определено в Device.h:

IWDFIoRequest *m_PendingRequest;

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

FxRequest->Complete(WINBIO_E_DATA_COLLECTION_IN_PROGRESS);

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

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