Compartir a través de


PIBIO_SENSOR_START_CAPTURE_FN función de devolución de llamada (winbio_adapter.h)

Llamado por Windows Biometric Framework para comenzar una captura biométrica asincrónica.

Sintaxis

PIBIO_SENSOR_START_CAPTURE_FN PibioSensorStartCaptureFn;

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

Parámetros

[in, out] Pipeline

Puntero a la estructura WINBIO_PIPELINE asociada a la unidad biométrica que realiza la operación.

[in] Purpose

Máscara de bits WINBIO_BIR_PURPOSE que especifica el uso previsto del ejemplo. Puede ser un OR bit a bit de los siguientes valores:

  • WINBIO_PURPOSE_VERIFY
  • WINBIO_PURPOSE_IDENTIFY
  • WINBIO_PURPOSE_ENROLL
  • WINBIO_PURPOSE_ENROLL_FOR_VERIFICATION
  • WINBIO_PURPOSE_ENROLL_FOR_IDENTIFICATION

Algunos sensores tienen la capacidad de capturar información biométrica en varias resoluciones. Si el parámetro Purpose especifica más de una marca, el adaptador debe usar la marca que representa la resolución más alta para determinar la resolución de la operación de captura.

[out] Overlapped

Dirección de una variable que recibe un puntero a una estructura SUPERPUESTA que realiza un seguimiento del estado de la operación de captura asincrónica. El adaptador del sensor crea y administra esta estructura, pero la usa Windows Biometric Framework para la sincronización. Para obtener más información, vea la sección Comentarios.

Valor devuelto

Si la función se realiza correctamente, devuelve S_OK. Si se produce un error en la función, devuelve un valor HRESULT que indica el error. El marco biométrico de Windows reconocerá los siguientes valores.

Código devuelto Descripción
E_POINTER
Un argumento de puntero obligatorio es NULL.
E_INVALIDARG
El parámetro Purpose no es válido.
E_OUTOFMEMORY
No había suficiente memoria para realizar la operación.
WINBIO_E_DEVICE_BUSY
El dispositivo no está listo para capturar datos.
WINBIO_E_DEVICE_FAILURE
Se produjo un error en el dispositivo.
WINBIO_E_INVALID_DEVICE_STATE
El miembro SensorContext de la estructura WINBIO_PIPELINE a la que apunta el argumento Pipeline es NULL o el miembro SensorHandle se establece en INVALID_HANDLE_VALUE.

Comentarios

Esta función no se bloquea. Si el adaptador emite varios comandos al sensor para prepararse para una operación de captura, todo menos el comando final puede ser sincrónico. El comando final, emitido inmediatamente antes de que SensorAdapterStartCapture devuelva el control a Windows Biometric Framework, debe ser asincrónico y debe usar E/S superpuesta.

Para usar la E/S superpuesta, comience agregando un objeto SUPERPUESTA a la definición de la estructura de contexto del adaptador de sensor privado. Esta estructura está disponible para el adaptador a través del campo SensorContext del objeto WINBIO_PIPELINE .

Al implementar SensorAdapterAttach, debe realizar las siguientes acciones para inicializar la estructura SUPERPUESTA :

  • Borre la estructura SUPERPUESTA llamando a la función ZeroMemory .
  • Cree un objeto de evento de restablecimiento manual mediante la función CreateEvent . Es fundamental que el objeto de evento sea manual en lugar de restablecerse automáticamente. El uso de eventos de restablecimiento automático en E/S superpuesta puede provocar una falta de respuesta irrecuperable en la operación de procesamiento de E/S.
  • Guarde el identificador de este evento en el miembro hEvent de la estructura SUPERPUESTA .
Al implementar SensorAdapterDetach, debe liberar el objeto de evento llamando a la función CloseHandle . Es importante no liberar este identificador hasta que se hayan completado o cancelado todas las operaciones de entrada y salida relacionadas con la captura.

Windows Biometric Framework usa el objeto OVERLAPPED cuando llama a funciones del sistema operativo como GetOverlappedResult y WaitForMultipleObjects para determinar cuándo se ha completado la operación de captura.

El identificador de eventos de la estructura SUPERPUESTA debe estar en estado no señalizado cuando se devuelve SensorAdapterStartCapture . Al llamar a DeviceIoControl para iniciar una operación de E/S superpuesta, se restablece automáticamente el evento. Si el adaptador usa algún otro mecanismo para iniciar una operación de E/S, debe restablecer el evento usted mismo.

Windows Biometric Framework garantiza que solo hay una operación asincrónica de E/S pendiente en cualquier momento para cada unidad biométrica. Por lo tanto, el adaptador del sensor solo necesita una estructura SUPERPUESTA para cada canalización de procesamiento.

Windows Biometric Framework abre y cierra el controlador del adaptador del sensor y es responsable de garantizar que el identificador se haya configurado para E/S superpuesta.

Ejemplos

El pseudocódigo siguiente muestra una posible implementación de esta función. El ejemplo no se compila. Debes adaptarlo para adaptarlo a tu propósito.

//////////////////////////////////////////////////////////////////////////////////////////
//
// 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;
    }
}

Requisitos

Requisito Value
Cliente mínimo compatible Windows 7 [solo aplicaciones de escritorio]
Servidor mínimo compatible Windows Server 2008 R2 [solo aplicaciones de escritorio]
Plataforma de destino Windows
Encabezado winbio_adapter.h (incluya Winbio_adapter.h)

Consulte también

Funciones de complemento

SensorAdapterFinishCapture