David Dong

David Dong

Java/C/C#/Python

Java/C/C#/Python

POST

Fingerprint driver development in Windows(3)

Following the last two articles…

7. Managing Queues in a WBDI Driver

WBDI drivers should create at least one queue to handle multiple concurrent requests from the service. If you are using UMDF, you can take advantage of its queue management support.

In WudfBioUsbSample, the CBiometricIoQueue class implements the I/O queue interface.

In the method CBiometricIoQueue::Initialize, specifically, the driver queries the owning CBiometricIoQueue object for a pointer to the IQueueCallbackDeviceIoControl interface that the framework uses to determine the event callback functions that the driver subscribes to on the queue:

if (SUCCEEDED(hr)) 
{
    hr = this->QueryInterface(__uuidof(IUnknown), (void **)&unknown);
}

Then the driver calls IWDFDevice::CreateIoQueue to configure the default I/O queue:

hr = FxDevice->CreateIoQueue(unknown,FALSE,WdfIoQueueDispatchParallel,FALSE,FALSE,&fxQueue);
BiometricSafeRelease(unknown);

The call specifies WdfIoQueueDispatchParallel so that the framework will present requests to the driver’s I/O queue callback functions as soon as the requests are available.

Next, the driver calls IWDFDevice::ConfigureRequestDispatching to configure the queue to filter all Device I/O requests:

hr = FxDevice->ConfigureRequestDispatching(fxQueue,WdfRequestDeviceIoControl,TRUE);

Because the driver specifies WdfRequestDeviceIoControl in this call, it provides an OnDeviceIoControl handler to process I/O notifications from the framework. It does this in the IQueueCallbackDeviceIoControl::OnDeviceIoControl method that is part of the “unknown” parameter in the call to CreateIoQueue previously.

There can only be one outstanding IOCTL_BIOMETRIC_CAPTURE_DATA request at a time. The driver should track IOCTL_BIOMETRIC_CAPTURE_DATA requests, either by internally keeping a pointer to the pending requests or by using another framework queue to handle those requests.

In the sample, if there is a pending I/O request, the sample maintains a pointer to the request in a member of the CBiometricDevice class, as defined in Device.h:

IWDFIoRequest *m_PendingRequest;

While one sensor data collection I/O is pending, subsequent calls to the data collection IOCTLs should fail:

FxRequest->Complete(WINBIO_E_DATA_COLLECTION_IN_PROGRESS);

When a capture request is completed or canceled, this value is set to NULL:

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

8. Installing a Biometric Driver

Vendors can provide an INF file to install a WBDI driver.

The following is a list of guidelines for biometric device installation. The code examples in this topic are taken from the WudfBioUsbSample.inx file of the WudfBioUsbSample:

  • WBDI drivers should specify a class of “Biometric.” Set ClassGuid equal to the value that corresponds to GUID_DEVCLASS_BIOMETRIC in Devguid.h:
[Version]
Signature="$Windows NT$"
Class=Biometric
ClassGuid={53D29EF7-377C-4D14-864B-EB3A85769359}
  • In your .HW section, provide AddReg directives to specify three sections that contain entries to be added to the registry:
[Biometric_Install.NT.hw]
AddReg=Biometric_Device_AddReg
AddReg=DriverPlugInAddReg, DatabaseAddReg
  • Provide the named sections referred to in the.HW section. The [Biometric_Device_AddReg] section sets values for the biometric device, including the exclusive flag and system wake/device idle. To be recognized by Windows Biometric Framework, UMDF-based WBDI drivers must set the “Exclusive” value to 1. The first two lines of the [Biometric_Device_AddReg] section specify access control list (ACL) rights so that the device can only be opened by an administrator or the local system account. When you specify these ACL rights, third-party applications cannot open the device and capture fingerprint data when the WinBio service is not running. For example:
[Biometric_Device_AddReg]
HKR,,"DeviceCharacteristics",0x10001,0x0100     ; Use same security checks on relative opens
HKR,,"Security",,"D:P(A;;GA;;;BA)(A;;GA;;;SY)"  ; Allow generic-all access to Built-in administrators and Local system
HKR,,"LowerFilters",0x00010008,"WinUsb" ; FLG_ADDREG_TYPE_MULTI_SZ | FLG_ADDREG_APPEND
HKR,,"Exclusive",0x10001,1
HKR,,"SystemWakeEnabled",0x00010001,1
HKR,,"DeviceIdleEnabled",0x00010001,1
HKR,,"UserSetDeviceIdleEnabled",0x00010001,1
HKR,,"DefaultIdleState",0x00010001,1
HKR,,"DefaultIdleTimeout",0x00010001,5000

A WBDI driver that exposes functionality to a legacy (non-WBDI) biometric stack should set the Exclusive value to zero. If this value is set to zero, the Windows Biometric Framework does not attempt to control the device and the device is not exposed through WBF.

Vendors can have a single driver binary that can work with legacy stacks and WBF, but the two cannot operate simultaneously. WBF will only operate if the device can be opened with exclusive access.

  • The second named section contains registry values for the plug-in adapters. The sample uses the Microsoft-provided sensor adapter and storage adapter. This section also enables Windows log-in support by setting the SystemSensor value:
[DriverPlugInAddReg]
HKR,WinBio\Configurations,DefaultConfiguration,,"0"
HKR,WinBio\Configurations\0,SensorMode,0x10001,1                                ; Basic - 1, Advanced - 2
HKR,WinBio\Configurations\0,SystemSensor,0x10001,1                              ; UAC/Winlogon - 1
HKR,WinBio\Configurations\0,SensorAdapterBinary,,"WinBioSensorAdapter.DLL"      ; Windows built-in WBDI sensor adapter.
HKR,WinBio\Configurations\0,EngineAdapterBinary,,"EngineAdapter.DLL"            ; Vendor engine
HKR,WinBio\Configurations\0,StorageAdapterBinary,,"WinBioStorageAdapter.DLL"    ; Windows built-in storage adapter
HKR,WinBio\Configurations\0,DatabaseId,,"6E9D4C5A-55B4-4c52-90B7-DDDC75CA4D50"  ; Unique database GUID
  • Finally, the third section sets the following registry values for the database service. The identifying GUID must be unique for each vendor database of a certain format. For instance, in this code example from the sample, change 6E9D4C5A-55B4-4c52-90B7-DDDC75CA4D50 to your own unique GUID in your INF file.
[DatabaseAddReg]
HKLM,System\CurrentControlSet\Services\WbioSrvc\Databases\{6E9D4C5A-55B4-4c52-90B7-DDDC75CA4D50},BiometricType,0x00010001,0x00000008
HKLM,System\CurrentControlSet\Services\WbioSrvc\Databases\{6E9D4C5A-55B4-4c52-90B7-DDDC75CA4D50},Attributes,0x00010001,0x00000001
HKLM,System\CurrentControlSet\Services\WbioSrvc\Databases\{6E9D4C5A-55B4-4c52-90B7-DDDC75CA4D50},Format,,"00000000-0000-0000-0000-000000000000"
HKLM,System\CurrentControlSet\Services\WbioSrvc\Databases\{6E9D4C5A-55B4-4c52-90B7-DDDC75CA4D50},InitialSize,0x00010001,0x00000020
HKLM,System\CurrentControlSet\Services\WbioSrvc\Databases\{6E9D4C5A-55B4-4c52-90B7-DDDC75CA4D50},AutoCreate,0x00010001,0x00000001
HKLM,System\CurrentControlSet\Services\WbioSrvc\Databases\{6E9D4C5A-55B4-4c52-90B7-DDDC75CA4D50},AutoName,0x00010001,0x00000001
HKLM,System\CurrentControlSet\Services\WbioSrvc\Databases\{6E9D4C5A-55B4-4c52-90B7-DDDC75CA4D50},FilePath,,""
HKLM,System\CurrentControlSet\Services\WbioSrvc\Databases\{6E9D4C5A-55B4-4c52-90B7-DDDC75CA4D50},ConnectionString,,""

For information about INX files and how they differ from INF files, see Using INX Files to Create INF Files.

9. Creating a Device Interface for a WBDI Driver

After the device callback object has been initialized and returned to the driver, at the time of queue setup, the driver should create a device interface instance for the biometric device.

Specifically, WBDI drivers must expose the GUID_DEVINTERFACE_BIOMETRIC_READER device interface by calling IWDFDevice::CreateDeviceInterface:

hr = m_FxDevice->CreateDeviceInterface(&GUID_DEVINTERFACE_BIOMETRIC_READER, NULL);

This call is followed by a call to IWDFDevice::AssignDeviceInterfaceState:

hr = m_FxDevice->AssignDeviceInterfaceState(&GUID_DEVINTERFACE_BIOMETRIC_READER,NULL,TRUE);

A WBDI driver that wants to expose functionality to a legacy (non-WBDI) biometric stack should expose another device interface for legacy applications and make sure that the Exclusive value is set to zero in the INX file that installs the legacy stack.

Exposing the GUID_DEVINTERFACE_BIOMETRIC_READER device interface causes the WBF service to enumerate the driver only. If Exclusive mode is not set, WBF does not attempt to open and control the device.

Alternatively, the driver could detect internally that it is in legacy mode and then not expose the GUID_DEVINTERFACE_BIOMETRIC_READER device interface.


C++FingerprintWindows

You may also like

further reading