Gestione delle code in un driver WBDI
I driver WBDI devono creare almeno una coda per gestire più richieste simultanee dal servizio. Se si usa UMDF, è possibile sfruttare il supporto per la gestione delle code.
In WudfBioUsbSample la classe CBiometricIoQueue implementa l'interfaccia della coda I/O.
Nel metodo CBiometricIoQueue::Initialize
, in particolare, il driver esegue una query sull'oggetto CBiometricIoQueue proprietario per un puntatore all'interfaccia IQueueCallbackDeviceIoControl usata dal framework per determinare le funzioni di callback degli eventi sottoscritte dal driver nella coda:
if (SUCCEEDED(hr))
{
hr = this->QueryInterface(__uuidof(IUnknown), (void **)&unknown);
}
Il driver chiama quindi IWDFDevice::CreateIoQueue per configurare la coda di I/O predefinita:
hr = FxDevice->CreateIoQueue(unknown,
FALSE,
WdfIoQueueDispatchParallel,
FALSE,
FALSE,
&fxQueue);
BiometricSafeRelease(unknown);
La chiamata specifica WdfIoQueueDispatchParallel in modo che il framework presenterà le richieste alle funzioni di callback della coda di I/O del driver non appena le richieste sono disponibili.
Il driver chiama quindi IWDFDevice::ConfigureRequestDispatching per configurare la coda per filtrare tutte le richieste di I/O del dispositivo:
hr = FxDevice->ConfigureRequestDispatching(fxQueue,
WdfRequestDeviceIoControl,
TRUE);
Poiché il driver specifica WdfRequestDeviceIoControl in questa chiamata, fornisce un gestore OnDeviceIoControl per elaborare le notifiche di I/O dal framework. Questa operazione viene eseguita nel metodo IQueueCallbackDeviceIoControl::OnDeviceIoControl che fa parte del parametro "sconosciuto" nella chiamata a CreateIoQueue in precedenza.
Può essere presente una sola richiesta IOCTL_BIOMETRIC_CAPTURE_DATA in sospeso alla volta. Il driver deve tenere traccia delle richieste IOCTL_BIOMETRIC_CAPTURE_DATA, mantenendo internamente un puntatore alle richieste in sospeso o usando un'altra coda del framework per gestire tali richieste.
Nell'esempio, se è presente una richiesta di I/O in sospeso, l'esempio mantiene un puntatore alla richiesta in un membro della classe CBiometricDevice, come definito in Device.h:
IWDFIoRequest *m_PendingRequest;
Mentre un I/O di raccolta dati del sensore è in sospeso, le chiamate successive ai IOCTL della raccolta dati devono avere esito negativo:
FxRequest->Complete(WINBIO_E_DATA_COLLECTION_IN_PROGRESS);
Quando una richiesta di acquisizione viene completata o annullata, questo valore viene impostato su NULL:
IWDFIoRequest *FxRequest = (IWDFIoRequest *)InterlockedExchangePointer((PVOID *)&m_PendingRequest, NULL);