Condividi tramite


PIBIO_SENSOR_START_CAPTURE_FN funzione di callback (winbio_adapter.h)

Chiamato da Windows Biometric Framework per avviare un'acquisizione biometrica asincrona.

Sintassi

PIBIO_SENSOR_START_CAPTURE_FN PibioSensorStartCaptureFn;

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

Parametri

[in, out] Pipeline

Puntatore alla struttura WINBIO_PIPELINE associata all'unità biometrica che esegue l'operazione.

[in] Purpose

Maschera WINBIO_BIR_PURPOSE bit che specifica l'uso previsto dell'esempio. Questo può essere un OR bit per bit dei valori seguenti:

  • WINBIO_PURPOSE_VERIFY
  • WINBIO_PURPOSE_IDENTIFY
  • WINBIO_PURPOSE_ENROLL
  • WINBIO_PURPOSE_ENROLL_FOR_VERIFICATION
  • WINBIO_PURPOSE_ENROLL_FOR_IDENTIFICATION

Alcuni sensori hanno la possibilità di acquisire informazioni biometriche in più risoluzioni. Se il parametro Scopo specifica più flag, l'adattatore deve usare il flag che rappresenta la risoluzione più alta per determinare la risoluzione dell'operazione di acquisizione.

[out] Overlapped

Indirizzo di una variabile che riceve un puntatore a una struttura OVERLAPPED che tiene traccia dello stato dell'operazione di acquisizione asincrona. Questa struttura viene creata e gestita dall'adattatore del sensore, ma viene usata da Windows Biometric Framework per la sincronizzazione. Per altre informazioni, vedere la sezione Osservazioni.

Valore restituito

Se la funzione ha esito positivo, restituisce S_OK. Se la funzione ha esito negativo, restituisce un valore HRESULT che indica l'errore. I valori seguenti verranno riconosciuti da Windows Biometric Framework.

Codice restituito Descrizione
E_POINTER
Un argomento puntatore obbligatorio è NULL.
E_INVALIDARG
Il parametro Purpose non è valido.
E_OUTOFMEMORY
Memoria insufficiente per eseguire l'operazione.
WINBIO_E_DEVICE_BUSY
Il dispositivo non è pronto per acquisire i dati.
WINBIO_E_DEVICE_FAILURE
Si è verificato un errore del dispositivo.
WINBIO_E_INVALID_DEVICE_STATE
Il membro SensorContext della struttura WINBIO_PIPELINE a cui punta l'argomento Pipeline è NULL o il membro SensorHandle è impostato su INVALID_HANDLE_VALUE.

Commenti

Questa funzione non blocca. Se l'adattatore genera più comandi al sensore per preparare un'operazione di acquisizione, tutto ciò che il comando finale può essere sincrono. Il comando finale, rilasciato immediatamente prima che SensorAdapterStartCapture restituisce il controllo a Windows Biometric Framework, deve essere asincrono e deve usare L/O sovrapposto.

Per usare l'I/O sovrapposto, iniziare aggiungendo un oggetto OVERLAPPED alla definizione della struttura del contesto dell'adattatore del sensore privato. Questa struttura è disponibile per l'adattatore tramite il campo SensorContext dell'oggetto WINBIO_PIPELINE .

Quando si implementa SensorAdapterAttach, è necessario eseguire le azioni seguenti per inizializzare la struttura OVERLAPPED :

  • Cancellare la struttura OVERLAPPED chiamando la funzione ZeroMemory .
  • Creare un oggetto evento di reimpostazione manuale usando la funzione CreateEvent . È fondamentale che l'oggetto evento sia manuale anziché reimpostazione automatica. L'uso degli eventi di reimpostazione automatica nelle operazioni di I/O sovrapposte può causare una mancanza di risposta non recuperabile nell'operazione di elaborazione di I/O.
  • Salvare l'handle di questo evento nel membro hEvent della struttura OVERLAPPED .
Quando si implementa SensorAdapterDetach, è necessario rilasciare l'oggetto evento chiamando la funzione CloseHandle . È importante non rilasciare questo handle fino a quando tutte le operazioni di input e output correlate all'acquisizione sono state completate o annullate.

Windows Biometric Framework usa l'oggetto OVERLAPPED quando chiama le funzioni del sistema operativo, ad esempio GetOverlappedResult e WaitForMultipleObjects per determinare quando l'operazione di acquisizione è stata completata.

L'handle eventi nella struttura OVERLAPPED deve trovarsi nello stato non segnalato quando SensorAdapterStartCapture restituisce. La chiamata a DeviceIoControl per avviare un'operazione di I/O sovrapposta reimposta automaticamente l'evento. Se l'adattatore usa un altro meccanismo per avviare un'operazione di I/O, è necessario reimpostare l'evento.

Windows Biometric Framework garantisce che un'operazione di I/O asincrona sia in sospeso in qualsiasi momento per ogni unità biometrica. Di conseguenza, l'adattatore del sensore necessita solo di una struttura OVERLAPPED per ogni pipeline di elaborazione.

Windows Biometric Framework apre e chiude l'handle dell'adattatore del sensore ed è responsabile della configurazione dell'handle per le operazioni di I/O sovrapposte.

Esempio

Lo pseudocode seguente mostra una possibile implementazione di questa funzione. L'esempio non viene compilato. Devi adattarla per adattarti al tuo scopo.

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

Requisiti

Requisito Valore
Client minimo supportato Windows 7 [solo app desktop]
Server minimo supportato Windows Server 2008 R2 [solo app desktop]
Piattaforma di destinazione Windows
Intestazione winbio_adapter.h (includere Winbio_adapter.h)

Vedi anche

Funzioni plug-in

SensorAdapterFinishCapture