Partager via


PIBIO_SENSOR_START_CAPTURE_FN fonction de rappel (winbio_adapter.h)

Appelé par l’infrastructure biométrique Windows pour commencer une capture biométrique asynchrone.

Syntaxe

PIBIO_SENSOR_START_CAPTURE_FN PibioSensorStartCaptureFn;

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

Paramètres

[in, out] Pipeline

Pointeur vers la structure WINBIO_PIPELINE associée à l’unité biométrique effectuant l’opération.

[in] Purpose

Masque de bits WINBIO_BIR_PURPOSE qui spécifie l’utilisation prévue de l’exemple. Il peut s’agir d’un OR au niveau du bit des valeurs suivantes :

  • WINBIO_PURPOSE_VERIFY
  • WINBIO_PURPOSE_IDENTIFY
  • WINBIO_PURPOSE_ENROLL
  • WINBIO_PURPOSE_ENROLL_FOR_VERIFICATION
  • WINBIO_PURPOSE_ENROLL_FOR_IDENTIFICATION

Certains capteurs ont la possibilité de capturer des informations biométriques à plusieurs résolutions. Si le paramètre Purpose spécifie plusieurs indicateurs, votre adaptateur doit utiliser l’indicateur qui représente la résolution la plus élevée pour déterminer la résolution de l’opération de capture.

[out] Overlapped

Adresse d’une variable qui reçoit un pointeur vers une structure CHEVAUCHEMENT QUI suit l’état de l’opération de capture asynchrone. Cette structure est créée et gérée par l’adaptateur de capteur, mais elle est utilisée par l’infrastructure biométrique Windows pour la synchronisation. Pour plus d'informations, consultez la section Notes.

Valeur retournée

Si la fonction réussit, elle retourne S_OK. Si la fonction échoue, elle retourne une valeur HRESULT qui indique l’erreur. Les valeurs suivantes seront reconnues par l’infrastructure biométrique Windows.

Code de retour Description
E_POINTER
Un argument de pointeur obligatoire est NULL.
E_INVALIDARG
Le paramètre Purpose n’est pas valide.
E_OUTOFMEMORY
Il n’y avait pas assez de mémoire pour effectuer l’opération.
WINBIO_E_DEVICE_BUSY
L’appareil n’est pas prêt à capturer des données.
WINBIO_E_DEVICE_FAILURE
Il y a eu une défaillance de l’appareil.
WINBIO_E_INVALID_DEVICE_STATE
Le membre SensorContext de la structure WINBIO_PIPELINE pointée par l’argument Pipeline a la valeur NULL ou le membre SensorHandle est défini sur INVALID_HANDLE_VALUE.

Remarques

Cette fonction ne bloque pas. Si l’adaptateur émet plusieurs commandes au capteur pour préparer une opération de capture, toutes les commandes, sauf la dernière, peuvent être synchrones. La commande finale, émise immédiatement avant que SensorAdapterStartCapture ne retourne le contrôle à Windows Biometric Framework, doit être asynchrone et doit utiliser des E/S qui se chevauchent.

Pour utiliser les E/S qui se chevauchent, commencez par ajouter un objet OVERLAPPED à la définition de la structure de contexte de l’adaptateur de capteur privé. Cette structure est disponible pour l’adaptateur via le champ SensorContext de l’objet WINBIO_PIPELINE .

Lorsque vous implémentez SensorAdapterAttach, vous devez effectuer les actions suivantes pour initialiser la structure CHEVAUCHEMENT :

  • Effacez la structure CHEVAUCHEMENT EN appelant la fonction ZeroMemory .
  • Créez un objet d’événement de réinitialisation manuelle à l’aide de la fonction CreateEvent . Il est essentiel que l’objet événement soit manuel plutôt que réinitialisé automatiquement. L’utilisation d’événements de réinitialisation automatique dans les E/S qui se chevauchent peut entraîner un manque de réponse irrécupérable dans l’opération de traitement des E/S.
  • Enregistrez le handle de cet événement dans le membre hEvent de la structure CHEVAUCHEMENT .
Lorsque vous implémentez SensorAdapterDetach, vous devez libérer l’objet d’événement en appelant la fonction CloseHandle . Il est important de ne pas libérer ce handle tant que toutes les opérations d’entrée et de sortie liées à la capture n’ont pas été terminées ou annulées.

L’infrastructure biométrique Windows utilise l’objet OVERLAPPED lorsqu’il appelle des fonctions du système d’exploitation telles que GetOverlappedResult et WaitForMultipleObjects pour déterminer quand l’opération de capture est terminée.

Le handle d’événement dans la structure OVERLAPPED doit être à l’état non signalé lorsque SensorAdapterStartCapture est retourné. L’appel de DeviceIoControl pour démarrer une opération d’E/S qui se chevauche réinitialise automatiquement l’événement. Si votre adaptateur utilise un autre mécanisme pour démarrer une opération d’E/S, vous devez réinitialiser l’événement vous-même.

Windows Biometric Framework garantit qu’une seule opération d’E/S asynchrone est en suspens à tout moment pour chaque unité biométrique. Par conséquent, l’adaptateur de capteur n’a besoin que d’une seule structure CHEVAUCHÉE pour chaque pipeline de traitement.

Le Framework biométrique Windows ouvre et ferme le handle de l’adaptateur de capteur et est chargé de s’assurer que le handle a été configuré pour les E/S qui se chevauchent.

Exemples

Le pseudocode suivant montre une implémentation possible de cette fonction. L’exemple ne se compile pas. Vous devez l’adapter à votre objectif.

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

Configuration requise

Condition requise Valeur
Client minimal pris en charge Windows 7 [applications de bureau uniquement]
Serveur minimal pris en charge Windows Server 2008 R2 [applications de bureau uniquement]
Plateforme cible Windows
En-tête winbio_adapter.h (include Winbio_adapter.h)

Voir aussi

Fonctions de plug-in

SensorAdapterFinishCapture