Partager via


PIBIO_STORAGE_GET_CURRENT_RECORD_FN fonction de rappel (winbio_adapter.h)

Appelé par l’infrastructure biométrique Windows ou par un adaptateur de moteur pour récupérer le contenu de l’enregistrement actif dans le jeu de résultats du pipeline.

Syntaxe

PIBIO_STORAGE_GET_CURRENT_RECORD_FN PibioStorageGetCurrentRecordFn;

HRESULT PibioStorageGetCurrentRecordFn(
  [in, out] PWINBIO_PIPELINE Pipeline,
  [out]     PWINBIO_STORAGE_RECORD RecordContents
)
{...}

Paramètres

[in, out] Pipeline

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

[out] RecordContents

Pointeur vers une structure WINBIO_STORAGE_RECORD qui recevra le contenu de l’enregistrement.

Valeur retournée

Si la fonction réussit, elle retourne S_OK. Si la fonction échoue, elle doit retourner l’une des valeurs HRESULT suivantes pour indiquer l’erreur.

Code de retour Description
E_OUTOFMEMORY
La mémoire n’a pas pu être allouée pour l’enregistrement.
E_POINTER
Un argument de pointeur obligatoire est NULL.
WINBIO_E_DATABASE_NO_RESULTS
Il n’y a aucun enregistrement dans le jeu de résultats.
WINBIO_E_INVALID_DEVICE_STATE
Le membre StorageContext de l’objet pipeline est NULL ou le membre FileHandle n’est pas valide.

Remarques

Toutes les adresses retournées par cette fonction dans la structure WINBIO_STORAGE_RECORD doivent rester valides jusqu’à ce que l’une des fonctions suivantes soit appelée :

L’appel de la fonction StorageAdapterGetCurrentRecord ne modifie pas le pointeur du jeu de résultats. Si le pointeur se trouve déjà sur le dernier enregistrement du jeu, l’appel répété de cette fonction renvoie le même contenu d’enregistrement et une valeur HRESULT de S_OK.

Exemples

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

/////////////////////////////////////////////////////////////////////////////////////////
//
// StorageAdapterGetCurrentRecord
//
// Purpose:
//      Retrieves the contents of the current record in the pipeline result set.
//
// Parameters:
//      Pipeline       - Pointer to a WINBIO_PIPELINE structure associated with 
//                       the biometric unit performing the operation.
//      RecordContents - Pointer to a WINBIO_STORAGE_RECORD structure that will receive 
//                       the contents of the record.
//
static HRESULT
WINAPI
StorageAdapterGetCurrentRecord(
    __inout PWINBIO_PIPELINE Pipeline,
    __out PWINBIO_STORAGE_RECORD RecordContents
    )
{
    HRESULT hr = S_OK;
    struct _MY_ADAPTER_RECORD_HEADER *recordHeader = NULL;
    LARGE_INTEGER dataOffset = {0};
    SIZE_T allocationSize = 0;

    // Verify that pointer arguments are not NULL.
    if (!ARGUMENT_PRESENT(Pipeline) ||
        !ARGUMENT_PRESENT(RecordContents))
    {
        hr = E_POINTER;
        goto cleanup;
    }

    // Retrieve the context from the pipeline.
    PWINBIO_STORAGE_CONTEXT storageContext = (PWINBIO_STORAGE_CONTEXT)Pipeline->StorageContext;

    // Verify the pipeline state.
    if (storageContext == NULL || storageContext->FileHandle == INVALID_HANDLE_VALUE)
    {
        hr =  WINBIO_E_INVALID_DEVICE_STATE;
        goto cleanup;
    }

    // Call a custom function (_ResultSetGetCurrent) to retrieve the header
    // contents of the current record in the result set. This function should
    // also return the file offset of the template data in the record.
    hr = _ResultSetGetCurrent(
            &storageContext->ResultSet,
            &recordHeader,
            &dataOffset
            );
    if (FAILED(hr))
    {
        goto cleanup;
    }

    RecordContents->Identity = &recordHeader->Identity;
    RecordContents->SubFactor = recordHeader->SubFactor;
    RecordContents->IndexVector = _GetIndexVector(recordHeader);
    RecordContents->IndexElementCount = recordHeader->IndexElementCount;

    // Release any template data buffers created by previous calls to the
    // StorageAdapterGetCurrentRecord function. 
    if (storageContext->RawRecordData != NULL)
    {
        _AdapterRelease(storageContext->RawRecordData);
        storageContext->RawRecordData = NULL;
        storageContext->PayloadBlob = NULL;
    }

    if (storageContext->DecryptedTemplate != NULL)
    {
        // You must call SecureZeroMemory to clear any memory that contains
        // a plaintext version of the template data.
        SecureZeroMemory(
            storageContext->DecryptedTemplate, 
            storageContext->DecryptedTemplateSize
            );
        _AdapterRelease(storageContext->DecryptedTemplate);
        storageContext->DecryptedTemplate = NULL;
        storageContext->DecryptedTemplateSize = 0;
    }

    // Allocate a buffer for the template and payload portions of the record.
    allocationSize = 
        recordHeader->EncryptedTemplateBlobSize + 
        recordHeader->PayloadBlobSize;

    storageContext->RawRecordData = (PUCHAR)_AdapterAlloc(allocationSize);
    if (storageContext->RawRecordData == NULL)
    {
        hr = E_OUTOFMEMORY;
        goto cleanup;
    }

    // Call a custom function (_ReadRecordData) that reads the non-header
    // portion of the record.
    hr = _ReadRecordData(
            Pipeline->StorageHandle,
            dataOffset,
            storageContext->RawRecordData,
            (DWORD)allocationSize,
            (PDWORD)&storageContext->RawRecordDataSize
            );
    if (FAILED(hr))
    {
        goto cleanup;
    }

    // Call a custom function (_DecryptTemplate) that decrypts the template 
    // data and stores a pointer to the plaintext version in the storage context.
    hr = _DecryptTemplate(
            &storageContext->CryptoContext,
            storageContext->RawRecordData,
            recordHeader->EncryptedTemplateBlobSize,
            &storageContext->DecryptedTemplate,
            &storageContext->DecryptedTemplateSize
            );
    if (FAILED(hr))
    {
        goto cleanup;
    }

    // Set up return values for the caller. These values will remain valid until
    // the next query or get operation.
    RecordContents->TemplateBlob = storageContext->DecryptedTemplate;
    RecordContents->TemplateBlobSize = recordHeader->TemplateBlobSize;

    if (recordHeader->PayloadBlobSize != 0)
    {
        RecordContents->PayloadBlob = 
            storageContext->RawRecordData + 
            recordHeader->EncryptedTemplateBlobSize;

        RecordContents->PayloadBlobSize = recordHeader->PayloadBlobSize;
    }
    else
    {
        RecordContents->PayloadBlob = NULL;
        RecordContents->PayloadBlobSize = 0;
    }

cleanup:

    if (FAILED(hr))
    {
        if (storageContext->RawRecordData != NULL)
        {
            // Because the raw record data (including the payload blob) is
            // encrypted, it is not necessary to call SecureZeroMemory.
            _AdapterRelease(storageContext->RawRecordData);
            storageContext->RawRecordData = NULL;
            storageContext->PayloadBlob = NULL;
        }
        if (storageContext->DecryptedTemplate != NULL)
        {
            // You must call SecureZeroMemory to clear the plaintext version 
            // of the template before releasing it.
            SecureZeroMemory(
                storageContext->DecryptedTemplate, 
                storageContext->DecryptedTemplateSize
                );
            _AdapterRelease(storageContext->DecryptedTemplate);
            storageContext->DecryptedTemplate = NULL;
            storageContext->DecryptedTemplateSize = 0;
        }
    }

    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