Поделиться через


функция обратного вызова 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, указывающая предполагаемое использование образца. Это может быть побитовое ИЛИ следующих значений:

  • 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
Элемент SensorContext структуры WINBIO_PIPELINE , на который указывает аргумент Pipeline, имеет значение NULL или элемент SensorHandle имеет значение INVALID_HANDLE_VALUE.

Комментарии

Эта функция не блокирует. Если адаптер выдает датчику несколько команд для подготовки к операции записи, все команды, кроме последней, могут быть синхронными. Последняя команда, выданная непосредственно перед тем, как SensorAdapterStartCapture возвращает управление в Windows Biometric Framework, должна быть асинхронной и использовать перекрывающийся ввод-вывод.

Чтобы использовать перекрывающийся ввод-вывод, начните с добавления объекта OVERLAPPED в определение структуры контекста адаптера частного датчика. Эта структура доступна адаптеру через поле SensorContext объекта WINBIO_PIPELINE .

При реализации SensorAdapterAttach необходимо выполнить следующие действия для инициализации структуры OVERLAPPED :

  • Очистите структуру OVERLAPPED , вызвав функцию ZeroMemory .
  • Создайте объект события сброса вручную с помощью функции CreateEvent . Очень важно, чтобы объект события был ручным, а не автоматическим сбросом. Использование событий автоматического сброса в перекрывающихся операциях ввода-вывода может привести к неустранимому отсутствию отклика в операции обработки ввода-вывода.
  • Сохраните дескриптор этого события в элементе hEvent структуры OVERLAPPED .
При реализации SensorAdapterDetach необходимо освободить объект события, вызвав функцию CloseHandle . Важно не освобождать этот дескриптор до тех пор, пока не будут завершены или отменены все операции ввода и вывода, связанные с записью.

Windows Biometric Framework использует объект OVERLAPPED при вызове функций операционной системы, таких как GetOverlappedResult и WaitForMultipleObjects , чтобы определить, когда операция захвата завершена.

При возврате SensorAdapterStartCapture дескриптор событий в структуре OVERLAPPED должен находиться в состоянии без сигнала. Вызов DeviceIoControl для запуска перекрывающейся операции ввода-вывода автоматически сбрасывает событие. Если адаптер использует другой механизм для запуска операции ввода-вывода, необходимо сбросить событие самостоятельно.

Windows Biometric Framework гарантирует, что для каждой биометрической единицы в любое время выполняется только одна асинхронная операция ввода-вывода. Следовательно, адаптеру датчика требуется только одна структура OVERLAPPED для каждого конвейера обработки.

Windows Biometric Framework открывает и закрывает дескриптор адаптера датчика и отвечает за настройку дескриптора для перекрывающихся операций ввода-вывода.

Примеры

В следующем псевдокоде показана одна из возможных реализаций этой функции. Пример не компилируется. Вы должны адаптировать его в соответствии с вашей целью.

//////////////////////////////////////////////////////////////////////////////////////////
//
// 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
Header winbio_adapter.h (включая Winbio_adapter.h)

См. также раздел

Функции подключаемого модуля

SensorAdapterFinishCapture