PIBIO_SENSOR_START_CAPTURE_FN Rückruffunktion (winbio_adapter.h)

Wird vom Windows Biometric Framework aufgerufen, um mit einer asynchronen biometrischen Erfassung zu beginnen.

Syntax

PIBIO_SENSOR_START_CAPTURE_FN PibioSensorStartCaptureFn;

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

Parameter

[in, out] Pipeline

Zeiger auf die WINBIO_PIPELINE Struktur, die der biometrischen Einheit zugeordnet ist, die den Vorgang ausführt.

[in] Purpose

Eine WINBIO_BIR_PURPOSE Bitmaske, die die beabsichtigte Verwendung des Beispiels angibt. Dies kann ein bitweises OR der folgenden Werte sein:

  • WINBIO_PURPOSE_VERIFY
  • WINBIO_PURPOSE_IDENTIFY
  • WINBIO_PURPOSE_ENROLL
  • WINBIO_PURPOSE_ENROLL_FOR_VERIFICATION
  • WINBIO_PURPOSE_ENROLL_FOR_IDENTIFICATION

Einige Sensoren können biometrische Informationen mit mehreren Auflösungen erfassen. Wenn der Purpose-Parameter mehrere Flags angibt, sollte der Adapter das Flag verwenden, das die höchste Auflösung darstellt, um die Auflösung des Erfassungsvorgangs zu bestimmen.

[out] Overlapped

Adresse einer Variablen, die einen Zeiger auf eine OVERLAPPED-Struktur empfängt , die den Status des asynchronen Aufzeichnungsvorgangs nachverfolgt. Diese Struktur wird vom Sensoradapter erstellt und verwaltet, wird aber vom Windows Biometric Framework für die Synchronisierung verwendet. Weitere Informationen finden Sie im Abschnitt mit Hinweisen.

Rückgabewert

Wenn die Funktion erfolgreich ist, wird S_OK zurückgegeben. Wenn die Funktion fehlschlägt, wird ein HRESULT-Wert zurückgegeben, der den Fehler angibt. Die folgenden Werte werden vom Windows Biometric Framework erkannt.

Rückgabecode Beschreibung
E_POINTER
Ein obligatorisches Zeigerargument ist NULL.
E_INVALIDARG
Der Purpose-Parameter ist ungültig.
E_OUTOFMEMORY
Es war nicht genügend Arbeitsspeicher vorhanden, um den Vorgang auszuführen.
WINBIO_E_DEVICE_BUSY
Das Gerät ist nicht bereit, Daten zu erfassen.
WINBIO_E_DEVICE_FAILURE
Es ist ein Gerätefehler aufgetreten.
WINBIO_E_INVALID_DEVICE_STATE
Das SensorContext-Element der WINBIO_PIPELINE-Struktur , auf die das Argument Pipeline verweist, ist NULL , oder das SensorHandle-Element ist auf INVALID_HANDLE_VALUE festgelegt.

Hinweise

Diese Funktion wird nicht blockiert. Wenn der Adapter mehrere Befehle an den Sensor ausgibt, um einen Erfassungsvorgang vorzubereiten, können alle Befehle bis auf den letzten Befehl synchron sein. Der endgültige Befehl, der unmittelbar vor der Rückgabe der Steuerung durch SensorAdapterStartCapture an das Windows Biometric Framework ausgegeben wird, muss asynchron sein und überlappende E/A-Vorgänge verwenden.

Um überlappende E/A zu verwenden, fügen Sie zunächst ein OVERLAPPED-Objekt zur Definition der Kontextstruktur des privaten Sensoradapters hinzu. Diese Struktur steht dem Adapter über das Feld SensorContext des WINBIO_PIPELINE-Objekts zur Verfügung.

Wenn Sie SensorAdapterAttach implementieren, müssen Sie die folgenden Aktionen ausführen, um die OVERLAPPED-Struktur zu initialisieren:

  • Löschen Sie die OVERLAPPED-Struktur , indem Sie die ZeroMemory-Funktion aufrufen.
  • Erstellen Sie mithilfe der CreateEvent-Funktion ein Ereignisobjekt für das manuelle Zurücksetzen. Es ist wichtig, dass das Ereignisobjekt manuell und nicht automatisch zurückgesetzt wird. Die Verwendung von Ereignissen des automatischen Zurücksetzens in überlappenden E/A-Vorgängen kann zu einer nicht wiederherstellbaren Antwort beim E/A-Verarbeitungsvorgang führen.
  • Speichern Sie das Handle dieses Ereignisses im hEvent-Element der OVERLAPPED-Struktur .
Wenn Sie SensorAdapterDetach implementieren, müssen Sie das Ereignisobjekt freigeben, indem Sie die CloseHandle-Funktion aufrufen. Es ist wichtig, dieses Handle erst freizugeben, nachdem alle Eingabe- und Ausgabevorgänge im Zusammenhang mit der Erfassung abgeschlossen oder abgebrochen wurden.

Das Windows Biometric Framework verwendet das OVERLAPPED-Objekt , wenn Betriebssystemfunktionen wie GetOverlappedResult und WaitForMultipleObjects aufgerufen werden, um zu bestimmen, wann der Erfassungsvorgang abgeschlossen ist.

Das Ereignishandle in der OVERLAPPED-Struktur muss sich im nicht signalisierten Zustand befinden, wenn SensorAdapterStartCapture zurückgegeben wird. Wenn DeviceIoControl aufgerufen wird, um einen überlappenden E/A-Vorgang zu starten, wird das Ereignis automatisch zurückgesetzt. Wenn Ihr Adapter einen anderen Mechanismus zum Starten eines E/A-Vorgangs verwendet, müssen Sie das Ereignis selbst zurücksetzen.

Das Windows Biometric Framework garantiert, dass für jede biometrische Einheit jederzeit nur ein asynchroner E/A-Vorgang aussteht. Folglich benötigt der Sensoradapter nur eine OVERLAPPED-Struktur für jede Verarbeitungspipeline.

Das Windows Biometric Framework öffnet und schließt das Sensoradapterhandle und ist dafür verantwortlich, sicherzustellen, dass das Handle für überlappende E/A konfiguriert wurde.

Beispiele

Der folgende Pseudocode zeigt eine mögliche Implementierung dieser Funktion. Das Beispiel wird nicht kompiliert. Sie müssen es an Ihren Zweck anpassen.

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

Anforderungen

Anforderung Wert
Unterstützte Mindestversion (Client) Windows 7 [nur Desktop-Apps]
Unterstützte Mindestversion (Server) Windows Server 2008 R2 [nur Desktop-Apps]
Zielplattform Windows
Kopfzeile winbio_adapter.h (Winbio_adapter.h einschließen)

Weitere Informationen

Plug-In-Funktionen

SensorAdapterFinishCapture