PIBIO_SENSOR_CONTROL_UNIT_FN回调函数 (winbio_adapter.h)

由 Windows 生物识别框架调用,以执行供应商定义的不需要提升特权的控制操作。 调用 SensorAdapterControlUnitPrivileged 函数以执行供应商定义的需要提升特权的控制操作。

语法

PIBIO_SENSOR_CONTROL_UNIT_FN PibioSensorControlUnitFn;

HRESULT PibioSensorControlUnitFn(
  [in, out] PWINBIO_PIPELINE Pipeline,
  [in]      ULONG ControlCode,
  [in]      PUCHAR SendBuffer,
  [in]      SIZE_T SendBufferSize,
  [in]      PUCHAR ReceiveBuffer,
  [in]      SIZE_T ReceiveBufferSize,
  [out]     PSIZE_T ReceiveDataSize,
  [out]     PULONG OperationStatus
)
{...}

参数

[in, out] Pipeline

指向与执行操作的生物识别单元关联的 WINBIO_PIPELINE 结构的指针。

[in] ControlCode

一个 ULONG 值,该值指定要执行的供应商定义的操作。

[in] SendBuffer

指向缓冲区的指针,该缓冲区包含要发送到传感器适配器的控制信息。 缓冲区的格式和内容由供应商定义。

[in] SendBufferSize

SendBuffer 参数指定的缓冲区的大小(以字节为单位)。

[in] ReceiveBuffer

指向接收传感器适配器发送的信息的缓冲区的指针。 缓冲区的格式由供应商定义。

[in] ReceiveBufferSize

ReceiveBuffer 参数指定的缓冲区的大小(以字节为单位)。

[out] ReceiveDataSize

指向一个变量的指针,该变量接收写入 ReceiveBuffer 参数指定的缓冲区的数据的大小(以字节为单位)。

[out] OperationStatus

指向一个变量的指针,该变量接收供应商定义的状态代码,该代码指定控制操作的结果。

返回值

如果函数成功,则返回S_OK。 如果函数失败,它必须返回以下 HRESULT 值之一来指示错误。

返回代码 说明
E_POINTER
强制指针参数为 NULL
E_INVALIDARG
SendBuffer 参数指定的缓冲区的大小或格式不正确,或者适配器无法识别 ControlCode 参数中指定的值。
E_NOT_SUFFICIENT_BUFFER
ReceiveBuffer 参数指定的缓冲区太小。
WINBIO_E_CANCELED
该操作已取消。
WINBIO_E_DEVICE_FAILURE
存在硬件故障。
WINBIO_E_INVALID_CONTROL_CODE
适配器无法识别 ControlCode 参数中指定的值。
注意从Windows 8开始,仅使用E_INVALIDARG来发出此情况的信号。
 

注解

此函数的实现应与 SensorAdapterControlUnitPrivileged 函数的实现相同,只是不需要提升的权限来执行 ControlCode 参数指定的操作。 你负责定义操作,并决定哪些操作不需要提升的权限。

此函数必须检查 ReceiveBufferSize 参数的值,以确保 ReceiveBuffer 参数指定的缓冲区足够大,足以保存返回的数据。

示例

以下伪代码演示了此函数的一种可能实现。 该示例不编译。 必须根据自己的目的调整它。

//////////////////////////////////////////////////////////////////////////////////////////
//
// SensorAdapterControlUnit
//
// Purpose:
//      Performs a vendor-defined control operation that does not require 
//      elevated privilege.
//
// Parameters:
//      Pipeline            - Pointer to a WINBIO_PIPELINE structure associated 
//                            with the biometric unit performing the operation.
//      ControlCode         - Specifies the vendor-defined operation to perform.
//      SendBuffer          - Contains the control information sent to the 
//                            sensor adapter.
//      SendBufferSize      - Size, in bytes, of the buffer specified by the 
//                            SendBuffer parameter.
//      ReceiveBuffer       - Receives information returned by the sensor adapter
//                            in response to the control operation.
//      ReceiveBufferSize   - Size, in bytes, of the buffer specified by the 
//                            ReceiveBuffer parameter.
//      ReceiveDataSize     - Receives the size, in bytes, of the data written to 
//                            the buffer specified by the ReceiveBuffer parameter.
//      OperationStatus     - Receives a vendor-defined status code that specifies 
//                            the outcome of the control operation.
//
static HRESULT
WINAPI
SensorAdapterControlUnit(
    __inout PWINBIO_PIPELINE Pipeline,
    __in ULONG ControlCode,
    __in_bcount(SendBufferSize) PUCHAR SendBuffer,
    __in SIZE_T SendBufferSize,
    __in_bcount(ReceiveBufferSize) PUCHAR ReceiveBuffer,
    __in SIZE_T ReceiveBufferSize,
    __out SIZE_T *ReceiveDataSize,
    __out ULONG *OperationStatus
    )
{
    HRESULT hr = S_OK;
    BOOL result = TRUE;

    // Verify that pointer arguments are not NULL.
    if (!ARGUMENT_PRESENT(Pipeline) ||
        !ARGUMENT_PRESENT(SendBuffer) ||
        !ARGUMENT_PRESENT(ReceiveBuffer) ||
        !ARGUMENT_PRESENT(ReceiveDataSize) ||
        !ARGUMENT_PRESENT(OperationStatus))
    {
        hr = E_POINTER;
        goto cleanup;
    }

    // Retrieve the context from the pipeline.
    PWINBIO_SENSOR_CONTEXT sensorContext = 
                 (PWINBIO_SENSOR_CONTEXT)Pipeline->SensorContext;

    // Verify the state of the pipeline.
    if (sensorContext == NULL || 
        Pipeline->SensorHandle == INVALID_HANDLE_VALUE)
    {
        hr = WINBIO_E_INVALID_DEVICE_STATE;
        goto cleanup;
    }

    switch (ControlCode)
    {
    case MY_NONPRIVILEGED_CTRL_CODE_NP1:
        {
            CTRL_CODE_NP1_SEND_BUFFER *sendBuffer = (CTRL_CODE_NP1_SEND_BUFFER*)SendBuffer;

            // Verify the size of the send buffer.
            if (SendBufferSize < sizeof(CTRL_CODE_NP1_SEND_BUFFER))
            {
                hr = E_INVALIDARG;
                break;
            }

            // Perform any other checks that may be required on the buffer 
            // contents. Return E_INVALIDARG if any of the checks fail.
            if (sendBuffer->SomeField != SomeSpecialValue ||
                sendBuffer->SomeOtherField != SomeOtherSpecialValue)
            {
                hr = E_INVALIDARG;
                break;
            }

            if (ReceiveBufferSize < sizeof(CTRL_CODE_NP1_RECEIVE_BUFFER))
            {
                hr = E_NOT_SUFFICIENT_BUFFER;
                break;
            }
        }

        // Fall through and perform the control operation after the switch
        // statement. Alternatively, depending on your requirements, you can 
        // perform the control operation here.
        break;

    case MY_NONPRIVILEGED_CTRL_CODE_NP2:
        // Continue testing for other non-privileged control codes that your
        // adapter supports.
        {
            CTRL_CODE_NP2_SEND_BUFFER *sendBuffer = (CTRL_CODE_NP2_SEND_BUFFER*)SendBuffer;

            // Verify the size of the send buffer.
            if (SendBufferSize < sizeof(CTRL_CODE_NP2_SEND_BUFFER))
            {
                hr = E_INVALIDARG;
                break;
            }

            // Perform any other checks that may be required on the buffer 
            // contents. Return E_INVALIDARG if any of the checks fail.
            if (sendBuffer->SomeField != SomeSpecialValue ||
                sendBuffer->SomeOtherField != SomeOtherSpecialValue)
            {
                hr = E_INVALIDARG;
                break;
            }

            if (ReceiveBufferSize < sizeof(CTRL_CODE_NP2_RECEIVE_BUFFER))
            {
                hr = E_NOT_SUFFICIENT_BUFFER;
                break;
            }
        }
        break;

    default:
        // All unrecognized control code values should return an error.
        hr = WINBIO_E_INVALID_CONTROL_CODE;
        break;
    }
    if (FAILED(hr))
    {
        goto cleanup;
    }

    // If control code validation succeeds, perform the control operation. This
    // example assumes that the driver performs overlapped I/O and that a properly 
    // initialized OVERLAPPED structure is contained in the sensor context.
    result = DeviceIoControl(
                Pipeline->SensorHandle,
                ControlCode,
                SendBuffer,
                (DWORD)SendBufferSize,
                ReceiveBuffer,
                (DWORD)ReceiveBufferSize,
                (LPDWORD)ReceiveDataSize,
                &sensorContext->Overlapped
                );
    if (result == FALSE && GetLastError() == ERROR_IO_PENDING)
    {
        SetLastError(ERROR_SUCCESS);

        result = GetOverlappedResult(
                    Pipeline->SensorHandle,
                    &sensorContext->Overlapped,
                    (LPDWORD)ReceiveDataSize,
                    TRUE
                    );
    }
    *OperationStatus = GetLastError();

    if (!result)
    {
        hr = _AdapterGetHresultFromWin32(*OperationStatus);
    }

cleanup:

    return hr;
}

要求

要求
最低受支持的客户端 Windows 7 [仅限桌面应用]
最低受支持的服务器 Windows Server 2008 R2 [仅限桌面应用]
目标平台 Windows
标头 winbio_adapter.h (包括 Winbio_adapter.h)

另请参阅

插件函数

SensorAdapterControlUnitPrivileged

WinBioControlUnit