Partager via


PIBIO_STORAGE_DELETE_RECORD_FN fonction de rappel (winbio_adapter.h)

Appelé par l’infrastructure biométrique Windows pour supprimer un ou plusieurs modèles de la base de données.

Syntaxe

PIBIO_STORAGE_DELETE_RECORD_FN PibioStorageDeleteRecordFn;

HRESULT PibioStorageDeleteRecordFn(
  [in, out] PWINBIO_PIPELINE Pipeline,
  [in]      PWINBIO_IDENTITY Identity,
  [in]      WINBIO_BIOMETRIC_SUBTYPE SubFactor
)
{...}

Paramètres

[in, out] Pipeline

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

[in] Identity

Pointeur vers une structure WINBIO_IDENTITY qui contient le GUID ou le SID du modèle à supprimer.

[in] SubFactor

Valeur WINBIO_BIOMETRIC_SUBTYPE qui spécifie le sous-facteur associé au modèle à supprimer.

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_INVALIDARG
L’argument spécifié par le paramètre SubFactor n’est pas valide ou un membre de la structure spécifiée par le paramètre Identity n’est pas valide.
E_OUTOFMEMORY
La mémoire n’a pas pu être allouée pour l’en-tête d’enregistrement.
E_POINTER
Un argument de pointeur obligatoire est NULL.
WINBIO_E_DATABASE_CORRUPTED
Il existe un problème non spécifié avec la base de données.
WINBIO_E_DATABASE_NO_SUCH_RECORD
Aucun enregistrement correspondant n’est disponible dans la base de données.
WINBIO_E_INVALID_DEVICE_STATE
Le membre StorageContext de l’objet pipeline est NULL ou le membre FileHandle n’est pas valide.

Remarques

Si le champ Type de la structure WINBIO_IDENTITY pointée vers le paramètre Identity est défini sur WINBIO_IDENTITY_TYPE_WILDCARD et que le paramètre SubFactor est égal à WINBIO_SUBTYPE_ANY, l’adaptateur de stockage doit supprimer tous les enregistrements de la base de données.

Important  

N’essayez pas de valider la valeur fournie pour le paramètre SubFactor . Le service de biométrie Windows valide la valeur fournie avant de la transmettre à votre implémentation. Si la valeur est WINBIO_SUBTYPE_NO_INFORMATION ou WINBIO_SUBTYPE_ANY, validez le cas échéant.

 

Exemples

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

/////////////////////////////////////////////////////////////////////////////////////////
//
// StorageAdapterDeleteRecord
//
// Purpose:
//      Deletes one or more templates from the database.
//
// Parameters:
//      Pipeline  -  Pointer to a WINBIO_PIPELINE structure associated with 
//                   the biometric unit performing the operation.
//      Identity  -  Pointer to a WINBIO_IDENTITY structure that contains the GUID or 
//                   SID of the template to delete.
//      SubFactor -  A WINBIO_BIOMETRIC_SUBTYPE value that specifies the sub-factor 
//                   associated with the template to delete.
//
static HRESULT
WINAPI
StorageAdapterDeleteRecord(
    __inout PWINBIO_PIPELINE Pipeline,
    __in PWINBIO_IDENTITY Identity,
    __in WINBIO_BIOMETRIC_SUBTYPE SubFactor
    )
{
    HRESULT hr = S_OK;
    BOOL lockAcquired = FALSE;
    struct _MY_ADAPTER_FILE_HEADER fileHeader = {0};
    SIZE_T remainingRecords = 0;
    LARGE_INTEGER currentRecordOffset = {0};
    struct _MY_ADAPTER_RECORD_HEADER *recordHeader = NULL;
    SIZE_T recordHeaderSize = 0;
    struct _MY_ADAPTER_DPAPI_DATA protectedData = {0};
    SIZE_T deletedRecordCount = 0;

    // Check that pointer arguments are not NULL.
    if (!ARGUMENT_PRESENT(Pipeline) ||
        !ARGUMENT_PRESENT(Identity))
    {
        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;
    }

    // Check the identity type.
    if (Identity->Type != WINBIO_ID_TYPE_GUID &&
        Identity->Type != WINBIO_ID_TYPE_SID &&
        Identity->Type != WINBIO_ID_TYPE_WILDCARD)
    {
        hr = E_INVALIDARG;
        goto cleanup;
    }

    if (Identity->Type == WINBIO_ID_TYPE_WILDCARD &&
        Identity->Value.Wildcard != WINBIO_IDENTITY_WILDCARD)
    {
        hr = E_INVALIDARG;
        goto cleanup;
    }

    // Some kind of sub-factor information is mandatory, even if it's
    // just a wildcard.
    if (SubFactor == WINBIO_SUBTYPE_NO_INFORMATION)
    {
        hr = E_INVALIDARG;
        goto cleanup;
    }

    // Lock the database for writing (EXCLUSIVE ownership).
    hr = _LockDatabase( Pipeline->StorageHandle, TRUE);
    if (FAILED(hr))
    {
        goto cleanup;
    }
    lockAcquired = TRUE;

    // Read the database header block into memory.
    hr = _ReadFileHeader( Pipeline->StorageHandle, &fileHeader );
    if (FAILED(hr))
    {
        goto cleanup;
    }

    // For this operation, you need to update only the record header 
    // area, not the index vector area.
    recordHeaderSize = sizeof(struct _MY_ADAPTER_RECORD_HEADER);

    recordHeader = (struct _MY_ADAPTER_RECORD_HEADER*)_AdapterAlloc( recordHeaderSize );
    if (recordHeader == NULL)
    {
        hr = E_OUTOFMEMORY;
        goto cleanup;
    }

    currentRecordOffset = _MY_ADAPTER_FIRST_RECORD_OFFSET;
    remainingRecords = fileHeader.TotalRecordCount;

    // Scan through all records looking for identity matches.
    while (remainingRecords > 0)
    {
        SIZE_T recordSize = 0;
        BOOLEAN match = FALSE;

        hr = _ReadRecordHeader(
                Pipeline->StorageHandle,
                currentRecordOffset,
                recordHeader,
                recordHeaderSize
                );
        if (FAILED(hr))
        {
            goto cleanup;
        }

        recordSize = recordHeader->RecordSize;

        // Ignore records already marked for deletion.
        if ((recordHeader->Flags & _MY_ADAPTER_FLAG_RECORD_DELETED) == 0)
        {
            hr = _MatchIdentity( 
                    Identity, 
                    SubFactor, 
                    &recordHeader->Identity, 
                    recordHeader->SubFactor, 
                    &match
                    );
            if (FAILED(hr))
            {
                goto cleanup;
            }

            if (match == TRUE)
            {
                // Mark the record as deleted and call a custom function 
                // (_WriteRecordHeader) to write the record header to disk. Space 
                // occupied by deleted records should be reclaimed when the last
                // thread that is using the database closes the file. Delaying 
                // reclamation until the last thread closes is necessary because 
                // there could be other threads whose result sets contain references 
                // to the deleted records.
                recordHeader->Flags |= _MY_ADAPTER_FLAG_RECORD_DELETED;
                hr = _WriteRecordHeader(
                        Pipeline->StorageHandle,
                        currentRecordOffset,
                        recordHeader,
                        recordHeaderSize
                        );
                if (FAILED(hr))
                {
                    goto cleanup;
                }
                ++fileHeader.DeletedRecordCount;
                ++deletedRecordCount;
            }
        }

        currentRecordOffset.QuadPart += recordSize;
        --remainingRecords;
    }

    // Write the updated file header to disk.
    hr = _WriteFileHeader( 
            Pipeline->StorageHandle, 
            &fileHeader
            );
    if (FAILED(hr))
    {
        hr = WINBIO_E_DATABASE_CORRUPTED;
        goto cleanup;
    }

    //  Recompute the file hash and write it to the protected data area.
    hr = _ReadProtectedData(
            Pipeline->StorageHandle,
            &protectedData
            );
    if (FAILED(hr))
    {
        goto cleanup;
    }

    hr = _ComputeFileHash(
            Pipeline->StorageHandle,
            _MY_ADAPTER_DPAPI_BLOCK_OFFSET,
            (SIZE_T)(fileHeader.FirstFreeByte.QuadPart - 
                     _MY_ADAPTER_DPAPI_BLOCK_SIZE),
            protectedData.FileHash,
            _MY_ADAPTER_FILE_HASH_LENGTH,
            (PSIZE_T)&protectedData.FileHashLength
            );
    if (FAILED(hr))
    {
        hr = WINBIO_E_DATABASE_CORRUPTED;
        goto cleanup;
    }

    hr = _WriteProtectedData(
                Pipeline->StorageHandle,
                &protectedData
                );
    if (FAILED(hr))
    {
        hr = WINBIO_E_DATABASE_CORRUPTED;
        goto cleanup;
    }

cleanup:

    // Call the SecureZeroMemory function to overwrite the template encryption key 
    // on the stack.
    SecureZeroMemory( &protectedData, sizeof(struct _MY_ADAPTER_DPAPI_DATA));

    if (recordHeader != NULL)
    {
        _AdapterRelease(recordHeader);
        recordHeader = NULL;
    }

    if (lockAcquired == TRUE)
    {
        _UnlockDatabase( Pipeline->StorageHandle);
        lockAcquired = FALSE;
    }

    if (SUCCEEDED(hr))
    {
        if (deletedRecordCount == 0)
        {
            hr = WINBIO_E_DATABASE_NO_SUCH_RECORD;
        }
    }

    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

StorageAdapterAddRecord