C++ Windows生物识别服务在调用WinBioCaptureSample时在循环中运行SensorAdapterStartCapture
我正在使用实现Windows生物识别驱动程序。 当我调用WinBioCaptureSample时,下一个插件的方法在循环中运行C++ Windows生物识别服务在调用WinBioCaptureSample时在循环中运行SensorAdapterStartCapture,c++,wdk,umdf,wbdi,wbf,C++,Wdk,Umdf,Wbdi,Wbf,我正在使用实现Windows生物识别驱动程序。 当我调用WinBioCaptureSample时,下一个插件的方法在循环中运行 SensorAdapterClearContext EngineAdapterClearContext SensorAdapterStartCapture SensorAdapterFinishCapture 00000001 driver 352840 439560 1 1 04\05\2018-16:46:13:12 CBiometricDe
SensorAdapterClearContext
EngineAdapterClearContext
SensorAdapterStartCapture
SensorAdapterFinishCapture
00000001 driver 352840 439560 1 1 04\05\2018-16:46:13:12 CBiometricDevice::OnGetSensorStatus Called.
00000002 driver 352840 439560 1 2 04\05\2018-16:46:13:12 CBiometricDevice::OnGetAttributes Called.
00000003 driver 352840 439560 1 3 04\05\2018-16:46:13:12 CBiometricDevice::OnCaptureDataBuffer too small - must be at least 0x18.
00000004 driver 352840 439560 1 4 04\05\2018-16:46:13:12 CBiometricDevice::OnCaptureData Called.
00000005 driver 352840 439560 4 5 04\05\2018-16:46:13:28 CBiometricDevice::OnGetSensorStatus Called.
00000006 driver 352840 439560 1 6 04\05\2018-16:46:13:29 CBiometricDevice::OnCaptureDataBuffer too small - must be at least 0x18.
00000007 driver 352840 439560 1 7 04\05\2018-16:46:13:29 CBiometricDevice::OnCaptureData Called.
00000008 driver 352840 439560 1 8 04\05\2018-16:46:13:30 CBiometricDevice::OnGetSensorStatus Called.
00000009 driver 352840 439560 4 9 04\05\2018-16:46:13:30 CBiometricDevice::OnCaptureDataBuffer too small - must be at least 0x18.
00000010 driver 352840 439560 1 10 04\05\2018-16:46:13:31 CBiometricDevice::OnCaptureData Called.
...
我使用TraceView调试我的驱动程序,当驱动程序陷入循环时,它会显示下一个跟踪消息
SensorAdapterClearContext
EngineAdapterClearContext
SensorAdapterStartCapture
SensorAdapterFinishCapture
00000001 driver 352840 439560 1 1 04\05\2018-16:46:13:12 CBiometricDevice::OnGetSensorStatus Called.
00000002 driver 352840 439560 1 2 04\05\2018-16:46:13:12 CBiometricDevice::OnGetAttributes Called.
00000003 driver 352840 439560 1 3 04\05\2018-16:46:13:12 CBiometricDevice::OnCaptureDataBuffer too small - must be at least 0x18.
00000004 driver 352840 439560 1 4 04\05\2018-16:46:13:12 CBiometricDevice::OnCaptureData Called.
00000005 driver 352840 439560 4 5 04\05\2018-16:46:13:28 CBiometricDevice::OnGetSensorStatus Called.
00000006 driver 352840 439560 1 6 04\05\2018-16:46:13:29 CBiometricDevice::OnCaptureDataBuffer too small - must be at least 0x18.
00000007 driver 352840 439560 1 7 04\05\2018-16:46:13:29 CBiometricDevice::OnCaptureData Called.
00000008 driver 352840 439560 1 8 04\05\2018-16:46:13:30 CBiometricDevice::OnGetSensorStatus Called.
00000009 driver 352840 439560 4 9 04\05\2018-16:46:13:30 CBiometricDevice::OnCaptureDataBuffer too small - must be at least 0x18.
00000010 driver 352840 439560 1 10 04\05\2018-16:46:13:31 CBiometricDevice::OnCaptureData Called.
...
方法CBiometricDevice::OnGetSensorStatus始终返回WINBIO_传感器就绪
diagnostics->WinBioHresult = S_OK;
diagnostics->SensorStatus = WINBIO_SENSOR_READY;
MyRequest.SetInformation(diagnostics->PayloadSize);
MyRequest.SetCompletionHr(S_OK);
接下来是方法CBiometricDevice::OnCaptureData
DWORD WINAPI
CaptureSleepThread(
LPVOID lpParam
)
{
CBiometricDevice *device = (CBiometricDevice *) lpParam;
PCAPTURE_SLEEP_PARAMS sleepParams = device->GetCaptureSleepParams();
if (sleepParams->SleepValue > 60)
{
sleepParams->SleepValue = 60;
}
Sleep(sleepParams->SleepValue * 1000);
UCHAR szBuffer[] = { 0x08, 0x01, 0x00, 0x02 };
ULONG cbRead = 4;
sleepParams->captureData->WinBioHresult = S_OK;
sleepParams->captureData->SensorStatus = WINBIO_SENSOR_ACCEPT;
sleepParams->captureData->RejectDetail = 0;
sleepParams->captureData->CaptureData.Size = cbRead;
RtlCopyMemory(sleepParams->captureData->CaptureData.Data, szBuffer, cbRead);
device->CompletePendingRequest(sleepParams->Hr, sleepParams->Information);
return 0;
}
CBiometricDevice::OnCaptureData(
_Inout_ IWDFIoRequest *FxRequest
)
{
ULONG controlCode = 0;
PWINBIO_CAPTURE_PARAMETERS captureParams = NULL;
SIZE_T inputBufferSize = 0;
PWINBIO_CAPTURE_DATA captureData = NULL;
SIZE_T outputBufferSize = 0;
bool requestPending = false;
EnterCriticalSection(&m_RequestLock);
if (m_PendingRequest == NULL)
{
if (m_SleepThread != INVALID_HANDLE_VALUE)
{
LeaveCriticalSection(&m_RequestLock);
// TODO: Add code to signal thread to exit.
WaitForSingleObject(m_SleepThread, INFINITE);
CloseHandle(m_SleepThread);
m_SleepThread = INVALID_HANDLE_VALUE;
EnterCriticalSection(&m_RequestLock);
}
if (m_PendingRequest == NULL)
{
m_PendingRequest = FxRequest;
m_PendingRequest->MarkCancelable(this);
}
else
{
requestPending = true;
}
}
else
{
requestPending = true;
}
LeaveCriticalSection(&m_RequestLock);
if (requestPending)
{
FxRequest->Complete(WINBIO_E_DATA_COLLECTION_IN_PROGRESS);
return;
}
GetIoRequestParams(FxRequest,
&controlCode,
(PUCHAR *)&captureParams,
&inputBufferSize,
(PUCHAR *)&captureData,
&outputBufferSize);
if (inputBufferSize < sizeof (WINBIO_CAPTURE_PARAMETERS))
{
TraceEvents(TRACE_LEVEL_ERROR,
BIOMETRIC_TRACE_DEVICE,
"%!FUNC!Invalid argument(s).");
CompletePendingRequest(E_INVALIDARG, 0);
return;
}
if (outputBufferSize < sizeof(DWORD))
{
TraceEvents(TRACE_LEVEL_ERROR,
BIOMETRIC_TRACE_DEVICE,
"%!FUNC!Output buffer NULL or too small to return size information.");
CompletePendingRequest(E_INVALIDARG, 0);
return;
}
if (outputBufferSize < sizeof (WINBIO_CAPTURE_DATA))
{
TraceEvents(TRACE_LEVEL_ERROR,
BIOMETRIC_TRACE_DEVICE,
"%!FUNC!Buffer too small - must be at least 0x%x.", sizeof (WINBIO_CAPTURE_DATA));
DWORD cbSize = 262144;//obtained from MAXIMUM_TRANSFER_SIZE policy of WinUsb
captureData->PayloadSize = (DWORD) sizeof(WINBIO_CAPTURE_DATA) + cbSize;
CompletePendingRequest(S_OK, sizeof(DWORD));
return;
}
RtlZeroMemory(captureData, outputBufferSize);
captureData->PayloadSize = (DWORD) outputBufferSize;// (DWORD) sizeof(WINBIO_CAPTURE_DATA);
captureData->WinBioHresult = WINBIO_E_NO_CAPTURE_DATA;
captureData->SensorStatus = WINBIO_SENSOR_FAILURE;
captureData->RejectDetail= 0;
captureData->CaptureData.Size = 0;
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;
}
struct _WINUSB_PIPE_INFORMATION InputPipeInfo, OutputPipeInfo;
m_pIUsbInputPipe->GetInformation(&InputPipeInfo);
m_pIUsbOutputPipe->GetInformation(&OutputPipeInfo);
m_SleepParams.PipeInId = InputPipeInfo.PipeId;
m_SleepParams.PipeOutId = OutputPipeInfo.PipeId;
m_SleepParams.hDeviceHandle = m_pIUsbInterface->GetWinUsbHandle();
m_SleepParams.cbSize = (DWORD) outputBufferSize;
m_SleepParams.SleepValue = 5;
m_SleepParams.Hr = S_OK;
m_SleepParams.Information = captureData->PayloadSize;
m_SleepParams.captureData = captureData;
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
TraceEvents(TRACE_LEVEL_ERROR,
BIOMETRIC_TRACE_DEVICE,
"%!FUNC! Called.");
}
DWORD-WINAPI
捕获睡眠线程(
LPVOID lpParam
)
{
CBiometricDevice*设备=(CBiometricDevice*)lpParam;
PCAPTURE_SLEEP_PARAMS sleepParams=设备->获取捕获睡眠参数();
如果(睡眠参数->睡眠值>60)
{
sleepParams->SleepValue=60;
}
睡眠(睡眠参数->睡眠值*1000);
UCHAR szBuffer[]={0x08,0x01,0x00,0x02};
ULONG cbRead=4;
sleepParams->captureData->WinBioHresult=S_OK;
sleepParams->captureData->SensorStatus=WINBIO\u SENSOR\u ACCEPT;
sleepParams->captureData->RejectDetail=0;
sleepParams->captureData->captureData.Size=cbRead;
RtlCopyMemory(sleepParams->captureData->captureData.Data、szBuffer、cbRead);
设备->完成结束请求(睡眠参数->人力资源,睡眠参数->信息);
返回0;
}
CBiometricDevice::OnCaptureData(
_Inout_uUdForeQuest*FxRequest
)
{
ULONG控制代码=0;
PWINBIO_CAPTURE_PARAMETERS captureParams=NULL;
大小\u T inputBufferSize=0;
PWINBIO_CAPTURE_DATA captureData=NULL;
大小\u T outputBufferSize=0;
bool requestPending=false;
EnterCriticalSection(&m_RequestLock);
if(m_PendingRequest==NULL)
{
if(m_SleepThread!=无效的\u句柄\u值)
{
LeaveCriticalSection(&m_RequestLock);
//TODO:将代码添加到要退出的信号线程。
WaitForSingleObject(m_SleepThread,无限);
闭合手柄(m_SleepThread);
m\u SleepThread=无效的\u句柄\u值;
EnterCriticalSection(&m_RequestLock);
}
if(m_PendingRequest==NULL)
{
m_PendingRequest=FxRequest;
m_PendingRequest->MarkCancelable(此项);
}
其他的
{
requestPending=true;
}
}
其他的
{
requestPending=true;
}
LeaveCriticalSection(&m_RequestLock);
如果(请求待定)
{
FxRequest->Complete(WINBIO数据收集过程中);
返回;
}
GetIoRequestParams(FxRequest,
&控制代码,
(PUCHAR*)和captureParams,
&输入缓冲区大小,
(PUCHAR*)和captureData,
&输出缓冲区大小);
if(inputBufferSizePayloadSize=(DWORD)sizeof(WINBIO_CAPTURE_DATA)+cbSize;
完成结束请求(S_OK,sizeof(DWORD));
返回;
}
RtlZeroMemory(captureData、outputBufferSize);
captureData->PayloadSize=(DWORD)outputBufferSize;/(DWORD)sizeof(WINBIO_CAPTURE_数据);
captureData->WinBioHresult=WINBIO_E_NO_CAPTURE_DATA;
captureData->SensorStatus=WINBIO\u传感器故障;
captureData->RejectDetail=0;
captureData->captureData.Size=0;
如果(captureParams->Purpose==WINBIO\u无\u用途\u可用)
{
captureData->WinBioHresult=WINBIO\u E\u不支持的\u目的;
}
else if((captureParams->Format.Type!=WINBIO\u ANSI\u 381\u Format\u Type)||
(captureParams->Format.Owner!=WINBIO_ANSI_381_Format_Owner))
{
captureData->WinBioHresult=WINBIO\u E\u不支持的\u数据\u格式;
}
else if(captureParams->Flags!=WINBIO_数据_标志_原始)
{
captureData->WinBioHresult=WINBIO\u E\u不支持的\u数据类型;
}
结构WINUSB管道信息输入管道信息,输出管道信息;
m_pIUsbInputPipe->GetInformation(&InputPipeInfo);
m_pIUsbOutputPipe->GetInformation(&OutputPipeInfo);
m_SleepParams.PipeInId=InputPipeInfo.PipeId;
m_SleepParams.PipeOutId=OutputPipeInfo.PipeId;
m_SleepParams.hDeviceHandle=m_pIUsbInterface->GetWinUsbHandle();
m_SleepParams.cbSize=(DWORD)outputBufferSize;
m_SleepParams.SleepValue=5;
m_SleepParams.Hr=S_OK;
m_SleepParams.Information=captureData->PayloadSize;
m_SleepParams.captureData=captureData;
m_SleepThread=CreateThread(NULL,//默认安全属性
0,//使用默认堆栈大小
CaptureSeepThread,//线程函数名
这是线程函数的,//参数
0,//使用默认创建标志
NULL);//返回线程标识符
跟踪事件(跟踪级别错误,
生物特征跟踪装置,
“%!FUNC!已调用。”);
}
方法传感器适配器开始捕获
[DriverPlugInAddReg]
HKR,WinBio\Configurations,DefaultConfiguration,,"0"
HKR,WinBio\Configurations\0,SensorMode,0x10001,2 ; Basic - 1, Advanced - 2
DWORD WINAPI
CaptureSleepThread(
LPVOID lpParam
)
{
CBiometricDevice *device = (CBiometricDevice *) lpParam;
PCAPTURE_SLEEP_PARAMS sleepParams = device->GetCaptureSleepParams();
//
// 1 minute or half a minute delay is the trick.
//
if (sleepParams->SleepValue > 60)
{
sleepParams->SleepValue = 60;
}
Sleep(sleepParams->SleepValue * 1000);
UCHAR szBuffer[] = { 0x08, 0x01, 0x00, 0x02 };
ULONG cbRead = 4;
sleepParams->captureData->WinBioHresult = S_OK;
sleepParams->captureData->SensorStatus = WINBIO_SENSOR_ACCEPT;
sleepParams->captureData->RejectDetail = 0;
sleepParams->captureData->CaptureData.Size = cbRead;
RtlCopyMemory(sleepParams->captureData->CaptureData.Data, szBuffer, cbRead);
device->CompletePendingRequest(sleepParams->Hr, sleepParams->Information);
return 0;
}
//No delay is going to cause a loop
//Sleep(sleepParams->SleepValue * 1000);
//zeroes buffer is considered failed
UCHAR szBuffer[] = { 0x00, 0x00, 0x00, 0x00 };
//zero size is a failed read
ULONG cbRead = 0;
//returning other than S_FALSE or S_OK will cause a loop
sleepParams->captureData->WinBioHresult = S_FALSE;
sleepParams->captureData->SensorStatus = WINBIO_SENSOR_ACCEPT;
sleepParams->captureData->RejectDetail = 0;
sleepParams->captureData->CaptureData.Size = cbRead;
//It is going to fail if CaptureData.Data is empty
//RtlCopyMemory(sleepParams->captureData->CaptureData.Data, szBuffer, cbRead);