summaryrefslogtreecommitdiff
path: root/biometrics/driver/Device.cpp
diff options
context:
space:
mode:
authorAdonais Romero González <[email protected]>2024-05-06 16:21:31 -0700
committerGitHub <[email protected]>2024-05-06 16:21:31 -0700
commita74a241c664c4e1d7c0838287b34076c19d9858a (patch)
tree6ff7562612967b122acf8acf8a69c4dcfd5905db /biometrics/driver/Device.cpp
parentdef8e8e34ed2b7b1deb2fc9112ac4255f1a0f2ba (diff)
parent15477ce52bbb6b42ca591ecdfb484cac089f89ab (diff)
Merge develop changes prior to upcoming WDK release (May 2024)
Diffstat (limited to 'biometrics/driver/Device.cpp')
-rw-r--r--biometrics/driver/Device.cpp1834
1 files changed, 0 insertions, 1834 deletions
diff --git a/biometrics/driver/Device.cpp b/biometrics/driver/Device.cpp
deleted file mode 100644
index 8f8dd6b4..00000000
--- a/biometrics/driver/Device.cpp
+++ /dev/null
@@ -1,1834 +0,0 @@
-/*++
-
- THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
- ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
- PARTICULAR PURPOSE.
-
- Copyright (c) Microsoft Corporation. All rights reserved
-
-Module Name:
-
- Device.cpp
-
-Abstract:
-
- This module contains the implementation of the Biometric
- device driver.
-
-Environment:
-
- Windows User-Mode Driver Framework (WUDF)
-
---*/
-#include "internal.h"
-#include "device.tmh"
-
-#pragma warning(disable : 4189)
-
-DWORD WINAPI
-CaptureSleepThread(
- LPVOID lpParam
- )
-{
- CBiometricDevice *device = (CBiometricDevice *) lpParam;
- PCAPTURE_SLEEP_PARAMS sleepParams = device->GetCaptureSleepParams();
-
- //
- // Make sure it is less than or equal to 1 minute.
- //
- if (sleepParams->SleepValue > 60)
- {
- sleepParams->SleepValue = 60;
- }
-
- Sleep(sleepParams->SleepValue * 1000);
-
- device->CompletePendingRequest(sleepParams->Hr, sleepParams->Information);
-
- return 0;
-}
-
-
-HRESULT
-CBiometricDevice::CreateInstanceAndInitialize(
- _In_ IWDFDriver *FxDriver,
- _In_ IWDFDeviceInitialize * FxDeviceInit,
- _Out_ CBiometricDevice **Device
- )
-/*++
-
- Routine Description:
-
- This method creates and initializs an instance of the skeleton driver's
- device callback object.
-
- Arguments:
-
- FxDeviceInit - the settings for the device.
-
- Device - a location to store the referenced pointer to the device object.
-
- Return Value:
-
- Status
-
---*/
-{
- //
- // Create a new instance of the device class
- //
- CComObject<CBiometricDevice> *pMyDevice = NULL;
- HRESULT hr = CComObject<CBiometricDevice>::CreateInstance( &pMyDevice );
-
- if (SUCCEEDED(hr))
- {
-
- //
- // Initialize the instance. This calls the WUDF framework,
- // which keeps a reference to the device interface for the lifespan
- // of the device.
- //
- if (NULL != pMyDevice)
- {
- hr = pMyDevice->Initialize(FxDriver, FxDeviceInit);
-
- if (FAILED(hr))
- {
- BiometricSafeRelease(pMyDevice);
- }
-
- }
-
- *Device = pMyDevice;
-
- }
-
- return hr;
-}
-
-HRESULT
-CBiometricDevice::Initialize(
- _In_ IWDFDriver * FxDriver,
- _In_ IWDFDeviceInitialize * FxDeviceInit
- )
-/*++
-
- Routine Description:
-
- This method initializes the device callback object and creates the
- partner device object.
-
- The method should perform any device-specific configuration that:
- * could fail (these can't be done in the constructor)
- * must be done before the partner object is created -or-
- * can be done after the partner object is created and which aren't
- influenced by any device-level parameters the parent (the driver
- in this case) might set.
-
- Arguments:
-
- FxDeviceInit - the settings for this device.
-
- Return Value:
-
- status.
-
---*/
-{
- IWDFDevice *fxDevice = NULL;
- HRESULT hr = S_OK;
- IUnknown *unknown = NULL;
-
- //
- // Configure things like the locking model before we go to create our
- // partner device.
- //
-
- //
- // Set the locking model.
- //
-
- FxDeviceInit->SetLockingConstraint(WdfDeviceLevel);
-
- //
- // Any per-device initialization which must be done before
- // creating the partner object.
- //
-
- //
- // Create a new FX device object and assign the new callback object to
- // handle any device level events that occur.
- //
-
- //
- // We pass an IUnknown reference to CreateDevice, which takes its own
- // reference if everything works.
- //
-
- if (SUCCEEDED(hr))
- {
- hr = this->QueryInterface(__uuidof(IUnknown), (void **)&unknown);
-
- }
-
- if (SUCCEEDED(hr))
- {
-
- hr = FxDriver->CreateDevice(FxDeviceInit, unknown, &fxDevice);
- BiometricSafeRelease(unknown);
- }
-
- //
- // If that succeeded then set our FxDevice member variable.
- //
-
- if (SUCCEEDED(hr))
- {
- m_FxDevice = fxDevice;
-
- //
- // Drop the reference we got from CreateDevice. Since this object
- // is partnered with the framework object they have the same
- // lifespan - there is no need for an additional reference.
- //
-
- BiometricSafeRelease(fxDevice);
- }
-
- return hr;
-}
-
-HRESULT
-CBiometricDevice::Configure(
- VOID
- )
-/*++
-
- Routine Description:
-
- This method is called after the device callback object has been initialized
- and returned to the driver. It would setup the device's queues and their
- corresponding callback objects.
-
- Arguments:
-
- FxDevice - the framework device object for which we're handling events.
-
- Return Value:
-
- status
-
---*/
-{
-
- HRESULT hr = S_OK;
-
- //
- // Create the I/O queue
- //
-
- if (SUCCEEDED(hr))
- {
- hr = CBiometricIoQueue::CreateInstanceAndInitialize(m_FxDevice, this, &m_IoQueue);
-
- if (SUCCEEDED(hr))
- {
- hr = m_IoQueue->Configure();
- }
- }
-
- //
- // Create Device Interface
- //
-
- if (SUCCEEDED(hr))
- {
- hr = m_FxDevice->CreateDeviceInterface(&GUID_DEVINTERFACE_BIOMETRIC_READER,
- NULL);
- }
-
- if (SUCCEEDED(hr))
- {
- hr = m_FxDevice->AssignDeviceInterfaceState(&GUID_DEVINTERFACE_BIOMETRIC_READER,
- NULL,
- TRUE);
- }
-
- //
- // TODO - this is where additional interfaces can be exposed.
- //
-
- return hr;
-}
-
-HRESULT
-CBiometricDevice::OnPrepareHardware(
- _In_ IWDFDevice * /* FxDevice */
- )
-/*++
-
-Routine Description:
-
- This routine is invoked to ready the driver
- to talk to hardware. It opens the handle to the
- device and talks to it using the WINUSB interface.
- It invokes WINUSB to discver the interfaces and stores
- the information related to bulk endpoints.
-
-Arguments:
-
- FxDevice : Pointer to the WDF device interface
-
-Return Value:
-
- HRESULT
-
---*/
-{
- PWSTR deviceName = NULL;
- DWORD deviceNameCch = 0;
-
- HRESULT hr;
-
- //
- // Get the device name.
- // Get the length to allocate first
- //
-
- hr = m_FxDevice->RetrieveDeviceName(NULL, &deviceNameCch);
-
- if (FAILED(hr))
- {
- TraceEvents(TRACE_LEVEL_ERROR,
- BIOMETRIC_TRACE_DEVICE,
- "%!FUNC! Cannot get device name %!hresult!",
- hr
- );
- }
-
- //
- // Allocate the buffer
- //
-
- if (SUCCEEDED(hr))
- {
- deviceName = (PWSTR) malloc(deviceNameCch * sizeof (WCHAR));
-
- if (deviceName == NULL)
- {
- hr = E_OUTOFMEMORY;
- }
- }
-
- //
- // Get the actual name
- //
-
- if (SUCCEEDED(hr))
- {
- hr = m_FxDevice->RetrieveDeviceName(deviceName, &deviceNameCch);
-
- if (FAILED(hr))
- {
- TraceEvents(TRACE_LEVEL_ERROR,
- BIOMETRIC_TRACE_DEVICE,
- "%!FUNC! Cannot get device name %!hresult!",
- hr
- );
- }
- }
-
- if (SUCCEEDED(hr))
- {
- TraceEvents(TRACE_LEVEL_INFORMATION,
- BIOMETRIC_TRACE_DEVICE,
- "%!FUNC! Device name %S",
- deviceName
- );
- }
-
- //
- // Create USB I/O Targets and configure them
- //
-
- if (SUCCEEDED(hr))
- {
- hr = CreateUsbIoTargets();
- }
-
- if (SUCCEEDED(hr))
- {
- ULONG length = sizeof(m_Speed);
-
- hr = m_pIUsbTargetDevice->RetrieveDeviceInformation(DEVICE_SPEED,
- &length,
- &m_Speed);
- if (FAILED(hr))
- {
- TraceEvents(TRACE_LEVEL_ERROR,
- BIOMETRIC_TRACE_DEVICE,
- "%!FUNC! Cannot get usb device speed information %!HRESULT!",
- hr
- );
- }
- }
-
- if (SUCCEEDED(hr))
- {
- TraceEvents(TRACE_LEVEL_INFORMATION,
- BIOMETRIC_TRACE_DEVICE,
- "%!FUNC! Speed - %x\n",
- m_Speed
- );
- }
-
- //
- // Setup power-management settings on the device.
- //
-
- if (SUCCEEDED(hr))
- {
- hr = SetPowerManagement();
- }
-
- //
- // We have non-power managed queues so we Stop them in OnReleaseHardware
- // and start them in OnPrepareHardware
- //
-
- if (SUCCEEDED(hr))
- {
- m_IoQueue->Start();
- }
-
- if (SUCCEEDED(hr))
- {
- //
- // If the device stack allows read to remain pending across power-down
- // and up, it can be initiated during OnPrepareHardware
- //
- // If the device stack doesn't allow the read to remain pending (i.e. it
- // cancels the pending read during power transition) driver will have to
- // stop sending pending read during D0Exit and re-initiate it during
- // D0Entry
- //
- // USB core actually doesn't allow read to remain pending across power
- // transition but WinUSB does. Since we are layered above WinUSB we don't
- // need to manage pending read across power transitions.
- //
-
- hr = InitiatePendingRead();
- }
-
- if (deviceName)
- {
- free(deviceName);
- deviceName = NULL;
- }
-
- return hr;
-}
-
-HRESULT
-CBiometricDevice::OnReleaseHardware(
- _In_ IWDFDevice * /* FxDevice */
- )
-/*++
-
-Routine Description:
-
- This routine is invoked when the device is being removed or stopped
- It releases all resources allocated for this device.
-
-Arguments:
-
- FxDevice - Pointer to the Device object.
-
-Return Value:
-
- HRESULT - Always succeeds.
-
---*/
-{
- //
- // Cancel the pending data collection I/O, if one exists.
- //
- CompletePendingRequest(HRESULT_FROM_WIN32(ERROR_CANCELLED), 0);
-
- //
- // Since we have non-power managed queues, we need to Stop them
- // explicitly
- //
- // We need to stop them before deleting I/O targets otherwise we
- // will continue to get I/O and our I/O processing will try to access
- // freed I/O targets
- //
- // We initialize queues in CMyDevice::Initialize so we can't get
- // here with queues being NULL and don't need to guard against that
- //
-
- m_IoQueue->StopSynchronously();
-
- //
- // Delete USB Target Device WDF Object, this will in turn
- // delete all the children - interface and the pipe objects
- //
- // This makes sure that
- // 1. We drain the I/O before releasing the targets
- // a. We always need to do that for the pending read which does
- // not come from an I/O queue
- // b. We need to do this even for I/O coming from I/O queues because
- // we set them to non-power managed queues (to leverage wait/wake
- // from WinUsb.sys)
- // 2. We remove USB target objects from object tree (and thereby free them)
- // before any potential subsequent OnPrepareHardware creates new ones
- //
- // m_pIUsbTargetDevice could be NULL if OnPrepareHardware failed so we need
- // to guard against that
- //
-
- if (m_pIUsbTargetDevice)
- {
- m_pIUsbTargetDevice->DeleteWdfObject();
- }
-
- //
- // This sample has a thread that will sleep for 5 seconds before
- // completing a capture request.
- //
- if (m_SleepThread != INVALID_HANDLE_VALUE)
- {
- WaitForSingleObject(m_SleepThread, INFINITE);
- CloseHandle(m_SleepThread);
- m_SleepThread = INVALID_HANDLE_VALUE;
- }
-
- return S_OK;
-}
-
-HRESULT
-CBiometricDevice::CreateUsbIoTargets(
- )
-/*++
-
-Routine Description:
-
- This routine creates Usb device, interface and pipe objects
-
-Arguments:
-
- None
-
-Return Value:
-
- HRESULT
---*/
-{
- HRESULT hr;
- UCHAR NumEndPoints = 0;
- IWDFUsbTargetFactory * pIUsbTargetFactory = NULL;
- IWDFUsbTargetDevice * pIUsbTargetDevice = NULL;
- IWDFUsbInterface * pIUsbInterface = NULL;
- IWDFUsbTargetPipe * pIUsbPipe = NULL;
-
- hr = m_FxDevice->QueryInterface(IID_PPV_ARGS(&pIUsbTargetFactory));
-
- if (FAILED(hr))
- {
- TraceEvents(TRACE_LEVEL_ERROR,
- BIOMETRIC_TRACE_DEVICE,
- "%!FUNC! Cannot get usb target factory %!HRESULT!",
- hr
- );
- }
-
- if (SUCCEEDED(hr))
- {
- hr = pIUsbTargetFactory->CreateUsbTargetDevice(
- &pIUsbTargetDevice);
- if (FAILED(hr))
- {
- TraceEvents(TRACE_LEVEL_ERROR,
- BIOMETRIC_TRACE_DEVICE,
- "%!FUNC! Unable to create USB Device I/O Target %!HRESULT!",
- hr
- );
- }
- else
- {
- m_pIUsbTargetDevice = pIUsbTargetDevice;
-
- //
- // Release the creation reference as object tree will maintain a reference
- //
-
- BiometricSafeRelease(pIUsbTargetDevice);
- }
- }
-
- if (SUCCEEDED(hr))
- {
- UCHAR NumInterfaces = pIUsbTargetDevice->GetNumInterfaces();
- TraceEvents(TRACE_LEVEL_INFORMATION,
- BIOMETRIC_TRACE_DEVICE,
- "%!FUNC! Found %u interfaces",
- NumInterfaces
- );
-
- hr = pIUsbTargetDevice->RetrieveUsbInterface(0, &pIUsbInterface);
- if (FAILED(hr))
- {
- TraceEvents(TRACE_LEVEL_ERROR,
- BIOMETRIC_TRACE_DEVICE,
- "%!FUNC! Unable to retrieve USB interface from USB Device I/O Target %!HRESULT!",
- hr
- );
- }
- else
- {
- m_pIUsbInterface = pIUsbInterface;
-
- BiometricSafeRelease(pIUsbInterface); // release creation reference
- }
- }
-
- if (SUCCEEDED(hr))
- {
- NumEndPoints = pIUsbInterface->GetNumEndPoints();
-
- if (NumEndPoints != NUM_WBDI_ENDPOINTS)
- {
- hr = E_UNEXPECTED;
- TraceEvents(TRACE_LEVEL_ERROR,
- BIOMETRIC_TRACE_DEVICE,
- "%!FUNC! Has %d endpoints, expected %d, returning %!HRESULT! ",
- NumEndPoints,
- NUM_WBDI_ENDPOINTS,
- hr
- );
- }
- }
-
- if (SUCCEEDED(hr))
- {
- for (UCHAR PipeIndex = 0; PipeIndex < NumEndPoints; PipeIndex++)
- {
- hr = pIUsbInterface->RetrieveUsbPipeObject(PipeIndex,
- &pIUsbPipe);
-
- if (FAILED(hr))
- {
- TraceEvents(TRACE_LEVEL_ERROR,
- BIOMETRIC_TRACE_DEVICE,
- "%!FUNC! Unable to retrieve USB Pipe for PipeIndex %d, %!HRESULT!",
- PipeIndex,
- hr
- );
- }
- else
- {
- if ( pIUsbPipe->IsInEndPoint() )
- {
- if ( UsbdPipeTypeInterrupt == pIUsbPipe->GetType() )
- {
- m_pIUsbInterruptPipe = pIUsbPipe;
- }
- else if ( UsbdPipeTypeBulk == pIUsbPipe->GetType() )
- {
- m_pIUsbInputPipe = pIUsbPipe;
- }
- else
- {
- pIUsbPipe->DeleteWdfObject();
- }
- }
- else if ( pIUsbPipe->IsOutEndPoint() && (UsbdPipeTypeBulk == pIUsbPipe->GetType()) )
- {
- m_pIUsbOutputPipe = pIUsbPipe;
- }
- else
- {
- pIUsbPipe->DeleteWdfObject();
- }
-
- BiometricSafeRelease(pIUsbPipe); //release creation reference
- }
- }
-
- if (NULL == m_pIUsbInputPipe || NULL == m_pIUsbOutputPipe)
- {
- hr = E_UNEXPECTED;
- TraceEvents(TRACE_LEVEL_ERROR,
- BIOMETRIC_TRACE_DEVICE,
- "%!FUNC! Input or output pipe not found, returning %!HRESULT!",
- hr
- );
- }
- }
-
- BiometricSafeRelease(pIUsbTargetFactory);
-
- return hr;
-}
-
-HRESULT
-CBiometricDevice::SetPowerManagement(
- VOID
- )
-/*++
-
- Routine Description:
-
- This method enables the WinUSB driver to power the device down when it is
- idle.
-
- Arguments:
-
- None
-
- Return Value:
-
- Status
-
---*/
-{
-
- HRESULT hr = S_OK;
- ULONG value = WBDI_SUSPEND_DELAY;
-
- hr = m_pIUsbTargetDevice->SetPowerPolicy( SUSPEND_DELAY,
- sizeof(ULONG),
- (PVOID) &value );
-
- if (FAILED(hr))
- {
- TraceEvents(TRACE_LEVEL_ERROR,
- BIOMETRIC_TRACE_DEVICE,
- "%!FUNC! Unable to set power policy (SUSPEND_DELAY) for the device %!HRESULT!",
- hr
- );
- }
-
-
- //
- // Finally enable auto-suspend.
- //
-
- if (SUCCEEDED(hr))
- {
- BOOL AutoSuspsend = TRUE;
-
- hr = m_pIUsbTargetDevice->SetPowerPolicy( AUTO_SUSPEND,
- sizeof(BOOL),
- (PVOID) &AutoSuspsend );
- }
-
- if (FAILED(hr))
- {
- TraceEvents(TRACE_LEVEL_ERROR,
- BIOMETRIC_TRACE_DEVICE,
- "%!FUNC! Unable to set power policy (AUTO_SUSPEND) for the device %!HRESULT!",
- hr
- );
- }
-
- return hr;
-}
-
-HRESULT
-CBiometricDevice::SendControlTransferSynchronously(
- _In_ PWINUSB_SETUP_PACKET SetupPacket,
- _Inout_updates_(BufferLength) PBYTE Buffer,
- _In_ ULONG BufferLength,
- _Out_ PULONG LengthTransferred
- )
-/*++
-
- Routine Description:
-
- This method synchronously sends a control transfer request to
- the USB I/O target.
-
- Arguments:
-
- SetupPacket - The command parameter structure
-
- Buffer - The data to transfer
-
- BufferLength - The size of the data buffer to transfer
-
- LengthTransferred - Contains the actual number of bytes transferred.
-
- Return Value:
-
- HRESULT
-
---*/
-{
- HRESULT hr = S_OK;
- IWDFIoRequest *pWdfRequest = NULL;
- IWDFDriver * FxDriver = NULL;
- IWDFMemory * FxMemory = NULL;
- IWDFRequestCompletionParams * FxComplParams = NULL;
- IWDFUsbRequestCompletionParams * FxUsbComplParams = NULL;
-
- *LengthTransferred = 0;
-
- hr = m_FxDevice->CreateRequest( NULL, //pCallbackInterface
- NULL, //pParentObject
- &pWdfRequest);
-
- if (SUCCEEDED(hr))
- {
- m_FxDevice->GetDriver(&FxDriver);
-
- hr = FxDriver->CreatePreallocatedWdfMemory( Buffer,
- BufferLength,
- NULL, //pCallbackInterface
- pWdfRequest, //pParetObject
- &FxMemory );
- }
-
- if (SUCCEEDED(hr))
- {
- hr = m_pIUsbTargetDevice->FormatRequestForControlTransfer( pWdfRequest,
- SetupPacket,
- FxMemory,
- NULL); //TransferOffset
- }
-
- if (SUCCEEDED(hr))
- {
- hr = pWdfRequest->Send( m_pIUsbTargetDevice,
- WDF_REQUEST_SEND_OPTION_SYNCHRONOUS,
- 0); //Timeout
- }
-
- if (SUCCEEDED(hr))
- {
- pWdfRequest->GetCompletionParams(&FxComplParams);
-
- hr = FxComplParams->GetCompletionStatus();
- }
-
- if (SUCCEEDED(hr))
- {
- HRESULT hrQI = FxComplParams->QueryInterface(IID_PPV_ARGS(&FxUsbComplParams));
- if (SUCCEEDED(hrQI))
- {
- FxUsbComplParams->GetDeviceControlTransferParameters( NULL,
- LengthTransferred,
- NULL,
- NULL );
- }
- }
-
- BiometricSafeRelease(FxUsbComplParams);
- BiometricSafeRelease(FxComplParams);
- BiometricSafeRelease(FxMemory);
-
- pWdfRequest->DeleteWdfObject();
- BiometricSafeRelease(pWdfRequest);
-
- BiometricSafeRelease(FxDriver);
-
- return hr;
-}
-
-WDF_IO_TARGET_STATE
-CBiometricDevice::GetTargetState(
- IWDFIoTarget * pTarget
- )
-/*++
-
- Routine Description:
-
- This method gets the state of the I/O target
-
- Arguments:
-
- pTarget - A pointer to the I/O target
-
- Return Value:
-
- WDF_IO_TARGET_STATE
-
---*/
-{
- IWDFIoTargetStateManagement * pStateMgmt = NULL;
- WDF_IO_TARGET_STATE state = WdfIoTargetStateUndefined;
-
- HRESULT hrQI = pTarget->QueryInterface(IID_PPV_ARGS(&pStateMgmt));
- if (FAILED(hrQI))
- {
- TraceEvents(TRACE_LEVEL_ERROR,
- BIOMETRIC_TRACE_DEVICE,
- "%!FUNC! Cannot query interface %!HRESULT!",
- hrQI
- );
-
- return state;
- }
-
- state = pStateMgmt->GetState();
-
- BiometricSafeRelease(pStateMgmt);
-
- return state;
-}
-
-HRESULT
-CBiometricDevice::InitiatePendingRead(
- VOID
- )
-/*++
-
- Routine Description:
-
- This routine starts up a cycling read on the interrupt pipe. As each
- read completes it will start up the next one.
-
- Arguments:
-
- None
-
- Return Value:
-
- Status
-
---*/
-{
- HRESULT hr = S_OK;
- IWDFIoRequest * FxRequest = NULL;
- IWDFMemory * FxMemory = NULL;
- IWDFDriver * FxDriver = NULL;
- IRequestCallbackRequestCompletion * FxComplCallback = NULL;
-
- hr = m_FxDevice->CreateRequest(NULL, NULL, &FxRequest);
-
- if (SUCCEEDED(hr))
- {
- m_FxDevice->GetDriver(&FxDriver);
-
- hr = FxDriver->CreatePreallocatedWdfMemory( (PBYTE) &m_InterruptMessage,
- sizeof(m_InterruptMessage),
- NULL, //pCallbackInterface
- FxRequest, //pParetObject
- &FxMemory );
- }
-
- if (SUCCEEDED(hr))
- {
- hr = m_pIUsbInterruptPipe->FormatRequestForRead(FxRequest,
- NULL, //pFile - IoTarget would apply its file
- FxMemory,
- NULL, //Memory offset
- NULL); //Device offset
- }
-
- if (SUCCEEDED(hr))
- {
- hr = this->QueryInterface(IID_PPV_ARGS(&FxComplCallback));
- if (SUCCEEDED(hr))
- {
- FxRequest->SetCompletionCallback(FxComplCallback, NULL);
-
- hr = FxRequest->Send(m_pIUsbInterruptPipe, 0, 0);
- }
- }
-
- if (FAILED(hr))
- {
- m_InterruptReadProblem = hr;
-
- if (FxRequest)
- {
- FxRequest->DeleteWdfObject();
- }
- }
-
- BiometricSafeRelease(FxRequest);
- BiometricSafeRelease(FxMemory);
- BiometricSafeRelease(FxDriver);
- BiometricSafeRelease(FxComplCallback);
-
- return hr;
-}
-
-VOID
-CBiometricDevice::OnCompletion(
- _In_ IWDFIoRequest* FxRequest,
- _In_ IWDFIoTarget* pIoTarget,
- _In_ IWDFRequestCompletionParams* pParams,
- _In_ PVOID pContext
- )
-/*++
-
- Routine Description:
-
- This method is called when the asynchronous pending
- read on the interrupt pipe completes.
-
- Arguments:
-
- FxRequest - The request object
-
- pIoTarget - The I/O target for the request
-
- pParams - The completion parameters
-
- pContext - Optional context
-
- Return Value:
-
- None
-
---*/
-{
- UNREFERENCED_PARAMETER(pIoTarget);
- UNREFERENCED_PARAMETER(pContext);
-
- IWDFUsbRequestCompletionParams * pUsbComplParams = NULL;
- IWDFMemory * FxMemory = NULL;
- SIZE_T bytesRead = 0;
- HRESULT hrCompletion = pParams->GetCompletionStatus();
-
- TraceEvents(TRACE_LEVEL_INFORMATION,
- BIOMETRIC_TRACE_DEVICE,
- "%!FUNC! Pending read completed with %!hresult!",
- hrCompletion
- );
-
- if (FAILED(hrCompletion))
- {
- m_InterruptReadProblem = hrCompletion;
- }
- else
- {
- //
- // Get the interrupt message
- //
-
- HRESULT hrQI = pParams->QueryInterface(IID_PPV_ARGS(&pUsbComplParams));
- if (SUCCEEDED(hrQI))
- {
- pUsbComplParams->GetPipeReadParameters(&FxMemory, &bytesRead, NULL);
- if (bytesRead == sizeof(INTERRUPT_MESSAGE))
- {
-
- PVOID pBuff = FxMemory->GetDataBuffer(NULL);
- CopyMemory(&m_InterruptMessage, pBuff, sizeof(m_InterruptMessage));
-
- //
- // TODO: Parse m_InterruptMessage
- //
- }
- }
- }
-
- //
- // Don't complete the request since we created it, just delete it.
- //
-
- FxRequest->DeleteWdfObject();
-
- //
- // Re-initiate pending read if I/O Target is not stopped/removed
- //
-
- if (WdfIoTargetStarted == GetTargetState(m_pIUsbInterruptPipe))
- {
- int numRetries = 0;
- HRESULT hr = InitiatePendingRead();
-
- //
- // If we fail here, the device will become unresponsive.
- // Re-issue the request until it succeeds.
- //
- for (numRetries = 0; FAILED(hr) && numRetries < 3; ++numRetries)
- {
- hr = InitiatePendingRead();
- }
- }
-
- BiometricSafeRelease(pUsbComplParams);
- BiometricSafeRelease(FxMemory);
-}
-
-
-//
-// I/O handlers
-//
-
-void
-CBiometricDevice::GetIoRequestParams(
- _In_ IWDFIoRequest *FxRequest,
- _Out_ ULONG *MajorControlCode,
- _Outptr_result_bytebuffer_(*InputBufferSizeInBytes) PUCHAR *InputBuffer,
- _Out_ SIZE_T *InputBufferSizeInBytes,
- _Outptr_result_bytebuffer_(*OutputBufferSizeInBytes) PUCHAR *OutputBuffer,
- _Out_ SIZE_T *OutputBufferSizeInBytes
- )
-/*++
-
- Routine Description:
-
- This method retrieves the input and output buffers associated with the request.
-
- Arguments:
-
- FxRequest - The WDF request oject
-
- MajorControlCode - Contains the control code for the I/O request
-
- InputBuffer - Contains the input buffer pointer
-
- InputBufferSizeInBytes - Contains the size of the input buffer
-
- OutputBuffer - Contains the output buffer pointer
-
- OutputBufferSizeInBytes - Contains the size of the output buffer
-
- Return Value:
-
- None
-
---*/
-{
- //
- // Get main parameters
- //
- FxRequest->GetDeviceIoControlParameters(MajorControlCode,
- InputBufferSizeInBytes,
- OutputBufferSizeInBytes);
-
- // Get pointer to input buffer
- IWDFMemory *fxMemory = NULL;
- FxRequest->GetInputMemory(&fxMemory);
- if (fxMemory)
- {
- *InputBuffer = (PUCHAR) fxMemory->GetDataBuffer(InputBufferSizeInBytes);
- BiometricSafeRelease(fxMemory);
- }
-
- // Save pointer to reply buffer
- fxMemory = NULL;
- FxRequest->GetOutputMemory(&fxMemory);
- if (fxMemory)
- {
- *OutputBuffer = (PUCHAR) fxMemory->GetDataBuffer(OutputBufferSizeInBytes);
- BiometricSafeRelease(fxMemory);
- }
-}
-
-void
-CBiometricDevice::OnGetAttributes(
- _Inout_ IWDFIoRequest *FxRequest
- )
-/*++
-
- Routine Description:
-
- This method is invoked when the IOCTL_BIOMETRIC_GET_ATTRIBUTES command is called.
-
- Arguments:
-
- FxRequest - The output for this request is a PWINBIO_SENSOR_ATTRIBUTES.
-
- Return Value:
-
- None
-
---*/
-{
- CRequestHelper MyRequest(FxRequest); // RAII helper class
- ULONG controlCode = 0;
- PUCHAR inputBuffer= NULL;
- SIZE_T inputBufferSize = 0;
- PWINBIO_SENSOR_ATTRIBUTES sensorAttributes = NULL;
- SIZE_T outputBufferSize;
-
- //
- // Get the request parameters
- //
- GetIoRequestParams(FxRequest,
- &controlCode,
- &inputBuffer,
- &inputBufferSize,
- (PUCHAR *)&sensorAttributes,
- &outputBufferSize);
-
- //
- // Make sure we have an output buffer big enough
- //
- if (sensorAttributes == NULL || outputBufferSize < sizeof(DWORD))
- {
- // We cannot return size information.
- TraceEvents(TRACE_LEVEL_ERROR,
- BIOMETRIC_TRACE_DEVICE,
- "%!FUNC!Output buffer NULL or too small to return size information.");
- MyRequest.SetCompletionHr(E_INVALIDARG);
- return;
- }
-
- // We only have one supported format, so sizeof (WINBIO_SENSOR_ATTRIBUTES) is sufficient.
- if (outputBufferSize < sizeof(WINBIO_SENSOR_ATTRIBUTES))
- {
- // Buffer too small.
- TraceEvents(TRACE_LEVEL_ERROR,
- BIOMETRIC_TRACE_DEVICE,
- "%!FUNC!Buffer too small - return size necessary in PayloadSize - 0x%x.", sizeof(WINBIO_SENSOR_ATTRIBUTES));
- sensorAttributes->PayloadSize = (DWORD) sizeof(WINBIO_SENSOR_ATTRIBUTES);
- MyRequest.SetInformation(sizeof(DWORD));
- MyRequest.SetCompletionHr(S_OK);
- return;
- }
-
- //
- // Fill in the attribute payload structure
- //
- RtlZeroMemory(sensorAttributes, outputBufferSize);
- sensorAttributes->PayloadSize = (DWORD) sizeof(WINBIO_SENSOR_ATTRIBUTES);
- sensorAttributes->WinBioHresult = S_OK;
- sensorAttributes->WinBioVersion.MajorVersion = WINBIO_WBDI_MAJOR_VERSION;
- sensorAttributes->WinBioVersion.MinorVersion = WINBIO_WBDI_MINOR_VERSION;
- sensorAttributes->SensorType = WINBIO_TYPE_FINGERPRINT;
- sensorAttributes->SensorSubType = WINBIO_FP_SENSOR_SUBTYPE_SWIPE;
- sensorAttributes->Capabilities = WINBIO_CAPABILITY_SENSOR;
- sensorAttributes->SupportedFormatEntries = 1;
- sensorAttributes->SupportedFormat[0].Owner = WINBIO_ANSI_381_FORMAT_OWNER;
- sensorAttributes->SupportedFormat[0].Type= WINBIO_ANSI_381_FORMAT_TYPE;
- RtlCopyMemory(sensorAttributes->ManufacturerName, SAMPLE_MANUFACTURER_NAME, (wcslen(SAMPLE_MANUFACTURER_NAME)+1)*sizeof(WCHAR));
- RtlCopyMemory(sensorAttributes->ModelName, SAMPLE_MODEL_NAME, (wcslen(SAMPLE_MODEL_NAME)+1)*sizeof(WCHAR));
- RtlCopyMemory(sensorAttributes->SerialNumber, SAMPLE_SERIAL_NUMBER, (wcslen(SAMPLE_SERIAL_NUMBER)+1)*sizeof(WCHAR));
- sensorAttributes->FirmwareVersion.MajorVersion = 1;
- sensorAttributes->FirmwareVersion.MinorVersion = 0;
-
- MyRequest.SetInformation(sensorAttributes->PayloadSize);
- MyRequest.SetCompletionHr(S_OK);
-}
-
-
-void
-CBiometricDevice::OnReset(
- _Inout_ IWDFIoRequest *FxRequest
- )
-/*++
-
- Routine Description:
-
- This method is invoked when the IOCTL_BIOMETRIC_RESET command is called.
-
- Arguments:
-
- FxRequest -
-
- Return Value:
-
- None
-
---*/
-{
- CRequestHelper MyRequest(FxRequest); // RAII helper class
- ULONG controlCode = 0;
- PUCHAR inputBuffer= NULL;
- SIZE_T inputBufferSize = 0;
- PWINBIO_BLANK_PAYLOAD blankPayload = NULL;
- SIZE_T outputBufferSize;
-
- //
- // Get the request parameters
- //
- GetIoRequestParams(FxRequest,
- &controlCode,
- &inputBuffer,
- &inputBufferSize,
- (PUCHAR *)&blankPayload,
- &outputBufferSize);
-
- //
- // Make sure we have an output buffer big enough
- //
- if (blankPayload== NULL || outputBufferSize < sizeof(DWORD))
- {
- // We cannot return size information.
- TraceEvents(TRACE_LEVEL_ERROR,
- BIOMETRIC_TRACE_DEVICE,
- "%!FUNC!Output buffer NULL or too small to return size information.");
- MyRequest.SetInformation(sizeof(DWORD));
- MyRequest.SetCompletionHr(S_OK);
- MyRequest.SetCompletionHr(E_INVALIDARG);
- return;
- }
-
- if (outputBufferSize < sizeof(WINBIO_BLANK_PAYLOAD))
- {
- // Buffer too small.
- TraceEvents(TRACE_LEVEL_ERROR,
- BIOMETRIC_TRACE_DEVICE,
- "%!FUNC!Buffer too small - return size necessary in PayloadSize - 0x%x.", sizeof(WINBIO_DIAGNOSTICS));
- MyRequest.SetInformation(sizeof(DWORD));
- MyRequest.SetCompletionHr(S_OK);
- return;
- }
-
- //
- // This is a simulated device. Nothing to do here except cancel the pending data
- // collection I/O, if one exists.
- //
- CompletePendingRequest(HRESULT_FROM_WIN32(ERROR_CANCELLED), 0);
-
- //
- // Fill in the OUT payload structure
- //
- RtlZeroMemory(blankPayload, outputBufferSize);
- blankPayload->PayloadSize = (DWORD) sizeof(WINBIO_BLANK_PAYLOAD);
- blankPayload->WinBioHresult = S_OK;
-
- FxRequest->SetInformation(blankPayload->PayloadSize);
- MyRequest.SetCompletionHr(S_OK);
-
-}
-
-void
-CBiometricDevice::OnCalibrate(
- _Inout_ IWDFIoRequest *FxRequest
- )
-/*++
-
- Routine Description:
-
- This method is invoked when the IOCTL_BIOMETRIC_CALIBRATE command is called.
-
- Arguments:
-
- FxRequest -
- IN - blank payload
- OUT - PWINBIO_CALIBRATION_INFO
-
- Return Value:
-
- None
-
---*/
-{
- CRequestHelper MyRequest(FxRequest); // RAII helper class
- ULONG controlCode = 0;
- PUCHAR inputBuffer= NULL;
- SIZE_T inputBufferSize = 0;
- PWINBIO_CALIBRATION_INFO calibrationInfo = NULL;
- SIZE_T outputBufferSize;
-
- //
- // Get the request parameters
- //
- GetIoRequestParams(FxRequest,
- &controlCode,
- &inputBuffer,
- &inputBufferSize,
- (PUCHAR *)&calibrationInfo,
- &outputBufferSize);
-
- //
- // Make sure we have an output buffer big enough
- //
- if (calibrationInfo == NULL || outputBufferSize < sizeof(DWORD))
- {
- // We cannot return size information.
- TraceEvents(TRACE_LEVEL_ERROR,
- BIOMETRIC_TRACE_DEVICE,
- "%!FUNC!Output buffer NULL or too small to return size information.");
- MyRequest.SetCompletionHr(E_INVALIDARG);
- return;
- }
-
- if (outputBufferSize < sizeof(WINBIO_CALIBRATION_INFO))
- {
- // Buffer too small.
- TraceEvents(TRACE_LEVEL_ERROR,
- BIOMETRIC_TRACE_DEVICE,
- "%!FUNC!Buffer too small - return size necessary in PayloadSize - 0x%x.", sizeof(WINBIO_DIAGNOSTICS));
- calibrationInfo->PayloadSize = (DWORD) sizeof(WINBIO_CALIBRATION_INFO);
- MyRequest.SetInformation(sizeof(DWORD));
- MyRequest.SetCompletionHr(S_OK);
- return;
- }
-
- //
- // This is where code to calibrate the device goes.
- //
-
- //
- // Fill in the OUT payload structure
- //
- RtlZeroMemory(calibrationInfo, outputBufferSize);
- calibrationInfo->PayloadSize = (DWORD) sizeof(WINBIO_CALIBRATION_INFO);
- calibrationInfo->WinBioHresult = S_OK;
-
- MyRequest.SetInformation(calibrationInfo->PayloadSize);
- MyRequest.SetCompletionHr(S_OK);
-}
-
-
-void
-CBiometricDevice::OnGetSensorStatus(
- _Inout_ IWDFIoRequest *FxRequest
- )
-/*++
-
- Routine Description:
-
- This method is invoked when the IOCTL_BIOMETRIC_GET_SENSOR_STATUS command is called.
-
- Arguments:
-
- FxRequest -
- IN payload: none
- OUT payload: PWINBIO_DIAGNOSTICS
-
- Return Value:
-
- None
-
---*/
-{
- CRequestHelper MyRequest(FxRequest); // RAII helper class
- ULONG controlCode = 0;
- PUCHAR inputBuffer= NULL;
- SIZE_T inputBufferSize = 0;
- PWINBIO_DIAGNOSTICS diagnostics = NULL;
- SIZE_T outputBufferSize;
-
- //
- // Get the request parameters
- //
- GetIoRequestParams(FxRequest,
- &controlCode,
- &inputBuffer,
- &inputBufferSize,
- (PUCHAR *)&diagnostics,
- &outputBufferSize);
-
- //
- // Make sure we have an output buffer big enough
- //
- if (diagnostics == NULL || outputBufferSize < sizeof(DWORD))
- {
- // We cannot return size information.
- TraceEvents(TRACE_LEVEL_ERROR,
- BIOMETRIC_TRACE_DEVICE,
- "%!FUNC!Output buffer NULL or too small to return size information.");
- MyRequest.SetCompletionHr(E_INVALIDARG);
- return;
- }
-
- if (outputBufferSize < sizeof(WINBIO_DIAGNOSTICS))
- {
- // Buffer too small.
- TraceEvents(TRACE_LEVEL_ERROR,
- BIOMETRIC_TRACE_DEVICE,
- "%!FUNC!Buffer too small - return size necessary in PayloadSize - 0x%x.", sizeof(WINBIO_DIAGNOSTICS));
- diagnostics->PayloadSize = (DWORD) sizeof(WINBIO_DIAGNOSTICS);
- MyRequest.SetInformation(sizeof(DWORD));
- MyRequest.SetCompletionHr(S_OK);
- return;
- }
-
- //
- // Fill in the OUT payload structure
- //
- RtlZeroMemory(diagnostics, outputBufferSize);
- diagnostics->PayloadSize = (DWORD) sizeof(WINBIO_DIAGNOSTICS);
- diagnostics->WinBioHresult = S_OK;
- diagnostics->SensorStatus = WINBIO_SENSOR_READY;
-
- MyRequest.SetInformation(diagnostics->PayloadSize);
- MyRequest.SetCompletionHr(S_OK);
-}
-
-
-void
-CBiometricDevice::OnCaptureData(
- _Inout_ IWDFIoRequest *FxRequest
- )
-/*++
-
- Routine Description:
-
- This method is invoked when the IOCTL_BIOMETRIC_CAPTURE_DATA command is called.
-
- Arguments:
-
- FxRequest -
- IN payload: PWINBIO_CAPTURE_PARAMETERS
- OUT payload: PWINBIO_CAPTURE_DATA
-
- Return Value:
-
- None
-
---*/
-{
- ULONG controlCode = 0;
- PWINBIO_CAPTURE_PARAMETERS captureParams = NULL;
- SIZE_T inputBufferSize = 0;
- PWINBIO_CAPTURE_DATA captureData = NULL;
- SIZE_T outputBufferSize = 0;
-
- //
- // We can only have one outstanding data capture request at a time.
- // Check to see if we have a request pending.
- //
- bool requestPending = false;
-
- EnterCriticalSection(&m_RequestLock);
-
- if (m_PendingRequest == NULL)
- {
- //
- // See if we have an active sleep thread.
- // If so, tell it to exit.
- // Wait for it to exit.
- //
- if (m_SleepThread != INVALID_HANDLE_VALUE)
- {
- LeaveCriticalSection(&m_RequestLock);
-
- // TODO: Add code to signal thread to exit.
-
- // NOTE: Sleeping for INFINITE time is dangerous. A real driver
- // should be able to handle the case where the thread does
- // not exit.
- WaitForSingleObject(m_SleepThread, INFINITE);
- CloseHandle(m_SleepThread);
- m_SleepThread = INVALID_HANDLE_VALUE;
-
- EnterCriticalSection(&m_RequestLock);
- }
-
- //
- // We might have had to leave the CS to wait for the sleep thread.
- // Double check that the pending request is still NULL.
- //
- if (m_PendingRequest == NULL)
- {
- // Save the request.
- m_PendingRequest = FxRequest;
-
- // Mark the request as cancellable.
- m_PendingRequest->MarkCancelable(this);
- }
- else
- {
- requestPending = true;
- }
-
- }
- else
- {
- requestPending = true;
- }
-
- LeaveCriticalSection(&m_RequestLock);
-
- if (requestPending)
- {
- // Complete the request to tell the app that there is already
- // a pending data collection request.
- FxRequest->Complete(WINBIO_E_DATA_COLLECTION_IN_PROGRESS);
- return;
- }
-
- //
- // Get the request parameters
- //
- GetIoRequestParams(FxRequest,
- &controlCode,
- (PUCHAR *)&captureParams,
- &inputBufferSize,
- (PUCHAR *)&captureData,
- &outputBufferSize);
-
- //
- // Check input parameters.
- //
- if (inputBufferSize < sizeof (WINBIO_CAPTURE_PARAMETERS))
- {
- // Invalid arguments
- TraceEvents(TRACE_LEVEL_ERROR,
- BIOMETRIC_TRACE_DEVICE,
- "%!FUNC!Invalid argument(s).");
- CompletePendingRequest(E_INVALIDARG, 0);
- return;
- }
-
- //
- // Make sure we have an output buffer big enough
- //
- if (outputBufferSize < sizeof(DWORD))
- {
- // We cannot return size information.
- TraceEvents(TRACE_LEVEL_ERROR,
- BIOMETRIC_TRACE_DEVICE,
- "%!FUNC!Output buffer NULL or too small to return size information.");
- CompletePendingRequest(E_INVALIDARG, 0);
- return;
- }
-
- //
- // Check output buffer size.
- //
- if (outputBufferSize < sizeof (WINBIO_CAPTURE_DATA))
- {
- // Buffer too small.
- TraceEvents(TRACE_LEVEL_ERROR,
- BIOMETRIC_TRACE_DEVICE,
- "%!FUNC!Buffer too small - must be at least 0x%x.", sizeof (WINBIO_CAPTURE_DATA));
- //
- // NOTE: The output buffer size necessary for this sample is sizeof(WINBIO_CAPTURE_DATA).
- // Real devices will need additional space to handle a typical capture.
- // The value that should be returned here is sizeof(WINBIO_CAPTURE_DATA) + CaptureBufferSize.
- //
- captureData->PayloadSize = (DWORD) sizeof(WINBIO_CAPTURE_DATA);
- CompletePendingRequest(S_OK, sizeof(DWORD));
- return;
- }
-
- //
- // NOTE: This call always fails in this sample since it is not
- // written for a real device.
- //
-
- //
- // Set default values in output buffer.
- //
- captureData->PayloadSize = (DWORD) sizeof (WINBIO_CAPTURE_DATA);
- captureData->WinBioHresult = WINBIO_E_NO_CAPTURE_DATA;
- captureData->SensorStatus = WINBIO_SENSOR_FAILURE;
- captureData->RejectDetail= 0;
- captureData->CaptureData.Size = 0;
-
- //
- // Check purpose, format and type.
- //
- if (captureParams->Purpose == WINBIO_NO_PURPOSE_AVAILABLE)
- {
- captureData->WinBioHresult = WINBIO_E_UNSUPPORTED_PURPOSE;
- }
- else if ((captureParams->Format.Type != WINBIO_ANSI_381_FORMAT_TYPE) ||
- (captureParams->Format.Owner != WINBIO_ANSI_381_FORMAT_OWNER))
- {
- captureData->WinBioHresult = WINBIO_E_UNSUPPORTED_DATA_FORMAT;
- }
- else if (captureParams->Flags != WINBIO_DATA_FLAG_RAW)
- {
- captureData->WinBioHresult = WINBIO_E_UNSUPPORTED_DATA_TYPE;
- }
-
- //
- // NOTE: This sample completes the request after
- // sleeping for 5 seconds. A real driver would
- // program the device for capture mode, and then
- // return from this callback. The request would
- // remain pending until cancelled, or until the
- // driver detects a capture is complete.
- //
- // The construct of m_PendingRequest will allow
- // a driver to have only one pending request at any
- // time, which can be cancelled in a Reset IOCTL, or
- // by calling CancelIoEx.
- //
-
- //
- // Create thread to sleep 5 seconds before completing the request.
- //
- m_SleepParams.SleepValue = 5;
- m_SleepParams.Hr = S_OK;
- m_SleepParams.Information = captureData->PayloadSize;
- m_SleepThread = CreateThread(NULL, // default security attributes
- 0, // use default stack size
- CaptureSleepThread, // thread function name
- this, // argument to thread function
- 0, // use default creation flags
- NULL); // returns the thread identifier
-}
-
-
-void
-CBiometricDevice::OnUpdateFirmware(
- _Inout_ IWDFIoRequest *FxRequest
- )
-/*++
-
- Routine Description:
-
- This method is invoked when the IOCTL_BIOMETRIC_UPDATE_FIRMWARE command is called.
-
- Arguments:
-
- FxRequest -
-
- Return Value:
-
- None
-
---*/
-{
- FxRequest->Complete(E_NOTIMPL);
-}
-
-void
-CBiometricDevice::OnGetSupportedAlgorithms(
- _Inout_ IWDFIoRequest *FxRequest
- )
-/*++
-
- Routine Description:
-
- This method is invoked when the IOCTL_BIOMETRIC_GET_SUPPORTED_ALGORITHMS command is called.
-
- Arguments:
-
- FxRequest -
-
- Return Value:
-
- None
-
---*/
-{
- FxRequest->Complete(E_NOTIMPL);
-}
-
-void
-CBiometricDevice::OnGetIndicator(
- _Inout_ IWDFIoRequest *FxRequest
- )
-/*++
-
- Routine Description:
-
- This method is invoked when the IOCTL_BIOMETRIC_GET_INDICATOR command is called.
-
- Arguments:
-
- FxRequest -
-
- Return Value:
-
- None
-
---*/
-{
- FxRequest->Complete(E_NOTIMPL);
-}
-
-
-void
-CBiometricDevice::OnSetIndicator(
- _Inout_ IWDFIoRequest *FxRequest
- )
-/*++
-
- Routine Description:
-
- This method is invoked when the IOCTL_BIOMETRIC_SET_INDICATOR command is called.
-
- Arguments:
-
- FxRequest -
-
- Return Value:
-
- None
-
---*/
-{
- FxRequest->Complete(E_NOTIMPL);
-}
-
-void
-CBiometricDevice::OnControlUnit(
- _Inout_ IWDFIoRequest *FxRequest
- )
-/*++
-
- Routine Description:
-
- This method is invoked when the IOCTL_BIOMETRIC_CONTROL_UNIT command is called.
-
- Arguments:
-
- FxRequest -
-
- Return Value:
-
- None
-
---*/
-{
- FxRequest->Complete(E_NOTIMPL);
-}
-
-
-VOID
-CBiometricDevice::CompletePendingRequest(
- HRESULT hr,
- DWORD information
- )
-{
- EnterCriticalSection(&m_RequestLock);
-
- if (m_PendingRequest)
- {
- //
- // Only complete the request if we weren't cancelled. Otherwise, the
- // OnCancel callback will complete the request.
- //
- HRESULT hrUnmark = m_PendingRequest->UnmarkCancelable();
- if (HRESULT_FROM_WIN32(ERROR_OPERATION_ABORTED) != hrUnmark)
- {
- m_PendingRequest->SetInformation(information);
- m_PendingRequest->Complete(hr);
- m_PendingRequest = NULL;
- }
- }
-
- LeaveCriticalSection(&m_RequestLock);
-}
-
-VOID
-STDMETHODCALLTYPE
-CBiometricDevice::OnCancel(
- _In_ IWDFIoRequest *pWdfRequest
- )
-{
- EnterCriticalSection(&m_RequestLock);
-
- if (m_PendingRequest != pWdfRequest)
- {
- TraceEvents(TRACE_LEVEL_ERROR,
- BIOMETRIC_TRACE_DEVICE,
- "%!FUNC! Cancelled request does not match pending request.");
- }
-
- //
- // TODO: In a real driver, the device would be reset so that it is no longer in capture mode.
- // Add your code to do so here.
- //
-
- if (m_PendingRequest == NULL)
- {
- TraceEvents(TRACE_LEVEL_ERROR,
- BIOMETRIC_TRACE_DEVICE,
- "%!FUNC! Pending request is NULL.");
- }
- else
- {
- m_PendingRequest->Complete(HRESULT_FROM_WIN32(ERROR_OPERATION_ABORTED));
- m_PendingRequest = NULL;
- }
-
- LeaveCriticalSection(&m_RequestLock);
-}