windows生物识别设备驱动IOCTL问题

meat2008 2017-09-25 11:18:09
参考微软在github上的biometric示例代码(https://github.com/Microsoft/Windows-driver-samples/tree/master/biometrics)写了个生物识别设备的驱动。现在usb通讯的驱动已经完成,测试在win10和win7上都能正确加载驱动。
按照MSDN(https://docs.microsoft.com/zh-cn/windows-hardware/drivers/biometric/supporting-biometric-ioctl-calling-sequence)的说法,WBS会先发送IOCTL_BIOMETRIC_GET_ATTRIBUTES和IOCTL_BIOMETRIC_GET_SENSOR_STATUS等。现在我的设备插到电脑上后,只会收到第一条IOCTL_BIOMETRIC_GET_ATTRIBUTES,隔几秒后就重新加载驱动再收到IOCTL_BIOMETRIC_GET_ATTRIBUTES,如此反复。不知道是不是对IOCTL_BIOMETRIC_GET_ATTRIBUTES的应答有问题,求大神指点,谢谢!

代码基本都是gihub上的示例代码,没怎么改动。

VOID
STDMETHODCALLTYPE
CBiometricIoQueue::OnDeviceIoControl(
_In_ IWDFIoQueue *FxQueue,
_In_ IWDFIoRequest *FxRequest,
_In_ ULONG ControlCode,
_In_ SIZE_T InputBufferSizeInBytes,
_In_ SIZE_T OutputBufferSizeInBytes
)
/*++

Routine Description:


DeviceIoControl dispatch routine

Aruments:

FxQueue - Framework Queue instance
FxRequest - Framework Request instance
ControlCode - IO Control Code
InputBufferSizeInBytes - Lenth of input buffer
OutputBufferSizeInBytes - Lenth of output buffer

Always succeeds DeviceIoIoctl
Return Value:

VOID

--*/
{
UNREFERENCED_PARAMETER(FxQueue);
UNREFERENCED_PARAMETER(InputBufferSizeInBytes);
UNREFERENCED_PARAMETER(OutputBufferSizeInBytes);

TraceEvents(TRACE_LEVEL_INFORMATION,
BIOMETRIC_TRACE_QUEUE,
"%!FUNC! ---> Entry");

if (m_BiometricDevice == NULL) {
// We don't have pointer to device object
TraceEvents(TRACE_LEVEL_ERROR,
BIOMETRIC_TRACE_QUEUE,
"%!FUNC!NULL pointer to device object.");
FxRequest->Complete(E_POINTER);
return;
}

//
// Process the IOCTLs
//
TraceEvents(TRACE_LEVEL_INFORMATION,
BIOMETRIC_TRACE_QUEUE,
"%!FUNC!IOCTL code: 0x%x.",
ControlCode);

switch (ControlCode) {

//
// Mandatory IOCTLs
//
case IOCTL_BIOMETRIC_GET_ATTRIBUTES:
m_BiometricDevice->OnGetAttributes(FxRequest);
break;

case IOCTL_BIOMETRIC_RESET:
m_BiometricDevice->OnReset(FxRequest);
break;

case IOCTL_BIOMETRIC_CALIBRATE:
m_BiometricDevice->OnCalibrate(FxRequest);
break;

case IOCTL_BIOMETRIC_GET_SENSOR_STATUS:
m_BiometricDevice->OnGetSensorStatus(FxRequest);
break;

case IOCTL_BIOMETRIC_CAPTURE_DATA:
m_BiometricDevice->OnCaptureData(FxRequest);
break;

//
// Optional IOCTLs
//
case IOCTL_BIOMETRIC_UPDATE_FIRMWARE:
m_BiometricDevice->OnUpdateFirmware(FxRequest);
break;

case IOCTL_BIOMETRIC_GET_SUPPORTED_ALGORITHMS:
m_BiometricDevice->OnGetSupportedAlgorithms(FxRequest);
break;

case IOCTL_BIOMETRIC_GET_INDICATOR:
m_BiometricDevice->OnGetIndicator(FxRequest);
break;

case IOCTL_BIOMETRIC_SET_INDICATOR:
m_BiometricDevice->OnSetIndicator(FxRequest);
break;

default:

//
// First check to see if this is for a BIOMETRIC file.
//
if ((ControlCode & CTL_CODE(0xFFFFFFFF, 0, 0, 0)) == CTL_CODE(FILE_DEVICE_BIOMETRIC, 0, 0, 0)) {

if ((ControlCode & IOCTL_BIOMETRIC_VENDOR) == IOCTL_BIOMETRIC_VENDOR) {
// This is a vendor IOCTL.
m_BiometricDevice->OnControlUnit(FxRequest);
break;
}

} else {

// This is a legacy IOCTL - non-Windows Biometric Framework
TraceEvents(TRACE_LEVEL_ERROR,
BIOMETRIC_TRACE_QUEUE,
"%!FUNC!Legacy control units not supported by the driver.");

}

//
// Didn't match any of the above.
//
TraceEvents(TRACE_LEVEL_ERROR,
BIOMETRIC_TRACE_QUEUE,
"%!FUNC! Unsupported IOCTL - 0x%x.",
ControlCode);
FxRequest->Complete(HRESULT_FROM_WIN32(ERROR_INVALID_FUNCTION));
break;

}

return;

}


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;

TraceEvents(TRACE_LEVEL_INFORMATION,
BIOMETRIC_TRACE_DEVICE,
"%!FUNC! IOCTL_BIOMETRIC_GET_ATTRIBUTES ---> entry.");

//
// 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_TOUCH;
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);

TraceEvents(TRACE_LEVEL_INFORMATION,
BIOMETRIC_TRACE_DEVICE,
"%!FUNC! IOCTL_BIOMETRIC_GET_ATTRIBUTES <--- exit.");
}
...全文
484 1 打赏 收藏 转发到动态 举报
写回复
用AI写文章
1 条回复
切换为时间正序
请发表友善的回复…
发表回复

21,595

社区成员

发帖
与我相关
我的任务
社区描述
硬件/嵌入开发 驱动开发/核心开发
社区管理员
  • 驱动开发/核心开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧