Gerenciando filas em um driver WBDI
Os drivers WBDI devem criar pelo menos uma fila para lidar com várias solicitações simultâneas do serviço. Se você estiver usando UMDF, poderá aproveitar seu suporte ao gerenciamento de filas.
No WudfBioUsbSample, a classe CBiometricIoQueue implementa a interface de fila de E/S.
No método CBiometricIoQueue::Initialize
, especificamente, o driver consulta o objeto CBiometricIoQueue proprietário para obter um ponteiro para a interface IQueueCallbackDeviceIoControl que a estrutura usa para determinar as funções de retorno de chamada de evento que o driver assina na fila:
if (SUCCEEDED(hr))
{
hr = this->QueryInterface(__uuidof(IUnknown), (void **)&unknown);
}
Em seguida, o driver chama IWDFDevice::CreateIoQueue para configurar a fila de E/S padrão:
hr = FxDevice->CreateIoQueue(unknown,
FALSE,
WdfIoQueueDispatchParallel,
FALSE,
FALSE,
&fxQueue);
BiometricSafeRelease(unknown);
A chamada especifica WdfIoQueueDispatchParallel para que a estrutura apresente solicitações às funções de retorno de chamada da fila de E/S do driver assim que as solicitações estiverem disponíveis.
Em seguida, o driver chama IWDFDevice::ConfigureRequestDispatching para configurar a fila para filtrar todas as solicitações de E/S do dispositivo:
hr = FxDevice->ConfigureRequestDispatching(fxQueue,
WdfRequestDeviceIoControl,
TRUE);
Como o driver especifica WdfRequestDeviceIoControl nesta chamada, ele fornece um manipulador OnDeviceIoControl para processar notificações de E/S da estrutura. Ele faz isso no método IQueueCallbackDeviceIoControl::OnDeviceIoControl que faz parte do parâmetro "unknown" na chamada para CreateIoQueue anteriormente.
Só pode haver um pedido de IOCTL_BIOMETRIC_CAPTURE_DATA pendente de cada vez. O driver deve controlar IOCTL_BIOMETRIC_CAPTURE_DATA solicitações, mantendo internamente um ponteiro para as solicitações pendentes ou usando outra fila de estrutura para lidar com essas solicitações.
No exemplo, se houver uma solicitação de E/S pendente, o exemplo manterá um ponteiro para a solicitação em um membro da classe CBiometricDevice, conforme definido em Device.h:
IWDFIoRequest *m_PendingRequest;
Enquanto uma E/S de coleta de dados do sensor estiver pendente, as chamadas subsequentes para as IOCTLs de coleta de dados devem falhar:
FxRequest->Complete(WINBIO_E_DATA_COLLECTION_IN_PROGRESS);
Quando uma solicitação de captura é concluída ou cancelada, esse valor é definido como NULL:
IWDFIoRequest *FxRequest = (IWDFIoRequest *)InterlockedExchangePointer((PVOID *)&m_PendingRequest, NULL);