PIBIO_SENSOR_START_CAPTURE_FN回调函数 (winbio_adapter.h)

由 Windows 生物识别框架调用以开始异步生物识别捕获。

语法

PIBIO_SENSOR_START_CAPTURE_FN PibioSensorStartCaptureFn;

HRESULT PibioSensorStartCaptureFn(
  [in, out] PWINBIO_PIPELINE Pipeline,
  [in]      WINBIO_BIR_PURPOSE Purpose,
  [out]     LPOVERLAPPED *Overlapped
)
{...}

参数

[in, out] Pipeline

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

[in] Purpose

指定示例的预期用途 的WINBIO_BIR_PURPOSE 位掩码。 这可以是以下值的按位 OR

  • WINBIO_PURPOSE_VERIFY
  • WINBIO_PURPOSE_IDENTIFY
  • WINBIO_PURPOSE_ENROLL
  • WINBIO_PURPOSE_ENROLL_FOR_VERIFICATION
  • WINBIO_PURPOSE_ENROLL_FOR_IDENTIFICATION

某些传感器能够以多种分辨率捕获生物识别信息。 如果 Purpose 参数指定多个标志,则适配器应使用表示最高分辨率的标志来确定捕获操作的分辨率。

[out] Overlapped

变量的地址,该变量接收指向跟踪异步捕获操作状态的 OVERLAPPED 结构的指针。 此结构由传感器适配器创建和管理,但由 Windows 生物识别框架用于同步。 有关详细信息,请参见“备注”部分。

返回值

如果函数成功,则返回S_OK。 如果函数失败,它将返回指示错误的 HRESULT 值。 Windows 生物识别框架将识别以下值。

返回代码 说明
E_POINTER
强制指针参数为 NULL
E_INVALIDARG
Purpose 参数无效。
E_OUTOFMEMORY
内存不足,无法执行操作。
WINBIO_E_DEVICE_BUSY
设备尚未准备好捕获数据。
WINBIO_E_DEVICE_FAILURE
设备发生故障。
WINBIO_E_INVALID_DEVICE_STATE
Pipeline 参数指向的 WINBIO_PIPELINE 结构的 SensorContext 成员为 NULL,或者 SensorHandle 成员设置为 INVALID_HANDLE_VALUE

注解

此函数不会阻止。 如果适配器向传感器发出多个命令以准备捕获操作,则除最终命令之外的所有命令都可以同步。 在 SensorAdapterStartCapture 将控制权返回到 Windows 生物识别框架之前立即发出的最后一个命令必须是异步的,并且必须使用重叠的 I/O。

若要使用重叠 I/O,请首先将 OVERLAPPED 对象添加到专用传感器适配器上下文结构的定义。 此结构通过 WINBIO_PIPELINE 对象的 SensorContext 字段可供适配器使用。

实现 SensorAdapterAttach 时,必须执行以下操作来初始化 OVERLAPPED 结构:

  • 通过调用 ZeroMemory 函数清除 OVERLAPPED 结构。
  • 使用 CreateEvent 函数创建手动重置事件对象。 事件对象必须是手动的,而不是自动重置,这一点至关重要。 在重叠的 I/O 中使用自动重置事件可能会导致 I/O 处理操作中无法恢复的缺少响应。
  • 将此事件的句柄保存在 OVERLAPPED 结构的 hEvent 成员中。
实现 SensorAdapterDetach 时,必须通过调用 CloseHandle 函数释放事件对象。 在完成或取消与捕获相关的所有输入和输出操作之前,不要释放此句柄。

Windows 生物识别框架在调用操作系统函数(如 GetOverlappedResultWaitForMultipleObjects)时使用 OVERLAPPED 对象来确定捕获操作何时完成。

当 SensorAdapterStartCapture 返回时,OVERLAPPED 结构中的事件句柄必须处于非信号状态。 调用 DeviceIoControl 以启动重叠的 I/O 操作会自动重置事件。 如果适配器使用其他某种机制启动 I/O 操作,则必须自行重置事件。

Windows 生物识别框架保证每个生物识别单元在任何时候只有一个异步 I/O 操作未完成。 因此,对于每个处理管道,传感器适配器只需要一个 OVERLAPPED 结构。

Windows 生物识别框架打开和关闭传感器适配器句柄,并负责确保已为重叠 I/O 配置句柄。

示例

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

//////////////////////////////////////////////////////////////////////////////////////////
//
// SensorAdapterStartCapture
//
// Purpose:
//      Begins an asynchronous biometric capture.
//      
// Parameters:
//      Pipeline   -  Pointer to a WINBIO_PIPELINE structure associated with 
//                    the biometric unit.
//      Purpose    -  A WINBIO_BIR_PURPOSE bitmask that specifies the intended
//                    use of the sample.
//      Overlapped -  Receives a pointer to an OVERLAPPED structure.
//
static HRESULT 
WINAPI
SensorAdapterStartCapture(
    __inout PWINBIO_PIPELINE Pipeline,
    __in WINBIO_BIR_PURPOSE Purpose,
    __out LPOVERLAPPED *Overlapped
    )
{
    HRESULT hr = S_OK;
    WINBIO_SENSOR_STATUS sensorStatus = WINBIO_SENSOR_FAILURE;
    WINBIO_CAPTURE_PARAMETERS captureParameters = {0};
    BOOL result = TRUE;
    DWORD bytesReturned = 0;

    // Verify that pointer arguments are not NULL.
    if (!ARGUMENT_PRESENT(Pipeline) ||
        !ARGUMENT_PRESENT(Purpose)  ||
        !ARGUMENT_PRESENT(Overlapped))
    {
        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)
    {
        return WINBIO_E_INVALID_DEVICE_STATE;
    }

    *Overlapped = NULL;

    //  Synchronously retrieve the status.
    hr = SensorAdapterQueryStatus(Pipeline, &sensorStatus);
    if (FAILED(hr))
    {
        return hr;
    }

    // Determine whether the sensor requires calibration.
    if (sensorStatus == WINBIO_SENSOR_NOT_CALIBRATED)
    {
        // Call a custom function that sends IOCTLs to
        // the sensor to calibrate it. This operation is
        // synchronous.
        hr = _SensorAdapterCalibrate(Pipeline);

        // Retrieve the status again to determine whether the 
        // sensor is ready.
        if (SUCCEEDED(hr))
        {
            hr = SensorAdapterQueryStatus(Pipeline, &sensorStatus);
        }

        if (FAILED(hr))
        {
            return hr;
        }
    }
    if (sensorStatus == WINBIO_SENSOR_BUSY)
    {
        return WINBIO_E_DEVICE_BUSY;
    }

    if (sensorStatus != WINBIO_SENSOR_READY)
    {
        return WINBIO_E_INVALID_DEVICE_STATE;
    }

    // Determine whether the data format has been previously determined.
    // If it has not, find a format supported by both the engine and 
    // the sensor.
    if ((sensorContext->Format.Owner == 0) &&
        (sensorContext->Format.Type == 0))
    {

        // Retrieve the format preferred by the engine.
        hr = Pipeline->EngineInterface->QueryPreferredFormat(
                                            Pipeline,
                                            &sensorContext->Format,
                                            &sensorContext->VendorFormat
                                            );
        if (SUCCEEDED(hr))
        {
            // Call a private function that queries the sensor driver
            // and attaches an attribute array to the sensor context.
            // This operation is synchronous.
            hr = _SensorAdapterGetAttributes(Pipeline);
        }

        if (SUCCEEDED(hr))
        {
            // Search the sensor attributes array for the format
            // preferred by the engine adapter.
            DWORD i = 0;
            for (i = 0; i < sensorContext->AttributesBuffer->SupportedFormatEntries; i++)
            {
                if ((sensorContext->AttributesBuffer->SupportedFormat[i].Owner == sensorContext->Format.Owner) &&
                    (sensorContext->AttributesBuffer->SupportedFormat[i].Type == sensorContext->Format.Type))
                {
                    break;
                }
            }

            if (i == sensorContext->AttributesBuffer->SupportedFormatEntries)
            {
                // No match was found. Use the default.
                sensorContext->Format.Owner = WINBIO_ANSI_381_FORMAT_OWNER;
                sensorContext->Format.Type = WINBIO_ANSI_381_FORMAT_TYPE;
            }
        }
        else
        {
            return hr;
        }
    }

    // Set up the parameter-input block needed for the IOCTL.
    captureParameters.PayloadSize = sizeof(WINBIO_CAPTURE_PARAMETERS);
    captureParameters.Purpose = Purpose;
    captureParameters.Format.Owner = sensorContext->Format.Owner;
    captureParameters.Format.Type = sensorContext->Format.Type;
    CopyMemory(&captureParameters.VendorFormat, &sensorContext->VendorFormat, sizeof (WINBIO_UUID));
    captureParameters.Flags = WINBIO_DATA_FLAG_RAW;

    // Determine whether a buffer has already been allocated for this sensor.
    if (sensorContext->CaptureBuffer == NULL)
    {
        DWORD allocationSize = 0;

        sensorContext->CaptureBufferSize = 0;

        // This sample assumes that the sensor driver returns
        // a fixed-size DWORD buffer containing the required
        // size of the capture buffer if it receives a buffer
        // that is smaller than sizeof(WINBIO_CAPTURE_DATA).
        //
        // Call the driver with a small buffer to get the 
        // allocation size required for this sensor.
        //
        // Because this operation is asynchronous, you must block 
        // and wait for it to complete.
        result = DeviceIoControl(
                    Pipeline->SensorHandle,
                    IOCTL_VENDOR_PRIVATE_CMD_CAPTURE_DATA,
                    &captureParameters,
                    sizeof(WINBIO_CAPTURE_PARAMETERS),
                    &allocationSize,
                    sizeof(DWORD),
                    &bytesReturned,
                    &sensorContext->Overlapped
                    );
        if (!result && GetLastError() == ERROR_IO_PENDING)
        {
            SetLastError(ERROR_SUCCESS);

            result = GetOverlappedResult(
                        Pipeline->SensorHandle,
                        &sensorContext->Overlapped,
                        &bytesReturned,
                        TRUE
                        );
        }

        if (!result || bytesReturned != sizeof (DWORD))
        {
            // An error occurred.
            hr = _AdapterGetHresultFromWin32(GetLastError());
            return hr;
        }

        // Make sure that you allocate at least the minimum buffer 
        // size needed to get the payload structure.
        if (allocationSize < sizeof(WINBIO_CAPTURE_DATA))
        {
            allocationSize = sizeof(WINBIO_CAPTURE_DATA);
        }

        // Allocate the buffer.
        sensorContext->CaptureBuffer = (PWINBIO_CAPTURE_DATA)_AdapterAlloc(allocationSize);
        if (!sensorContext->CaptureBuffer)
        {
            sensorContext->CaptureBufferSize = 0;
            return E_OUTOFMEMORY;
        }
        sensorContext->CaptureBufferSize = allocationSize;
    }
    else
    {
        // The buffer has already been allocated. Clear the buffer contents. 
        SensorAdapterClearContext(Pipeline);
    }

    // Send the capture request. Because this is an asynchronous operation,
    // the IOCTL call will return immediately regardless of 
    // whether the I/O has completed.
    result = DeviceIoControl(
                Pipeline->SensorHandle,
                IOCTL_VENDOR_PRIVATE_CMD_CAPTURE_DATA,
                &captureParameters,
                sizeof (WINBIO_CAPTURE_PARAMETERS),
                sensorContext->CaptureBuffer,
                sensorContext->CaptureBufferSize,
                &bytesReturned,
                &sensorContext->Overlapped
                );

    if (result ||
        (!result && GetLastError() == ERROR_IO_PENDING))
    {
        *Overlapped = &sensorContext->Overlapped;
        return S_OK;
    }
    else
    {
        hr = _AdapterGetHresultFromWin32(GetLastError());
        return hr;
    }
}

要求

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

另请参阅

插件函数

SensorAdapterFinishCapture