PIBIO_STORAGE_DELETE_RECORD_FN Rückruffunktion (winbio_adapter.h)

Wird vom Windows Biometric Framework aufgerufen, um eine oder mehrere Vorlagen aus der Datenbank zu löschen.

Syntax

PIBIO_STORAGE_DELETE_RECORD_FN PibioStorageDeleteRecordFn;

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

Parameter

[in, out] Pipeline

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

[in] Identity

Zeiger auf eine WINBIO_IDENTITY Struktur, die die GUID oder SID der zu löschenden Vorlage enthält.

[in] SubFactor

Ein WINBIO_BIOMETRIC_SUBTYPE Wert, der den Der zu löschenden Vorlage zugeordneten Unterfaktor angibt.

Rückgabewert

Wenn die Funktion erfolgreich ist, wird S_OK zurückgegeben. Wenn die Funktion fehlschlägt, muss sie einen der folgenden HRESULT-Werte zurückgeben, um den Fehler anzugeben.

Rückgabecode Beschreibung
E_INVALIDARG
Das durch den SubFactor-Parameter angegebene Argument ist ungültig, oder ein Element der struktur, die durch den Identity-Parameter angegeben wird, ist ungültig.
E_OUTOFMEMORY
Der Speicher konnte für den Datensatzheader nicht zugeordnet werden.
E_POINTER
Ein obligatorisches Zeigerargument ist NULL.
WINBIO_E_DATABASE_CORRUPTED
Es liegt ein nicht angegebenes Problem mit der Datenbank vor.
WINBIO_E_DATABASE_NO_SUCH_RECORD
In der Datenbank wurde kein übereinstimmenden Datensatz gefunden.
WINBIO_E_INVALID_DEVICE_STATE
Der StorageContext-Member des Pipelineobjekts ist NULL , oder der FileHandle-Member ist ungültig.

Hinweise

Wenn das Feld Typ der WINBIO_IDENTITY Struktur, auf die der Identity-Parameter verweist, auf WINBIO_IDENTITY_TYPE_WILDCARD festgelegt ist und der SubFactor-Parametergleich WINBIO_SUBTYPE_ANY ist, sollte der Speicheradapter alle Datensätze aus der Datenbank löschen.

Wichtig  

Versuchen Sie nicht, den für den SubFactor-Parameter angegebenen Wert zu überprüfen. Der Windows-Biometriedienst überprüft den angegebenen Wert, bevor er an Ihre Implementierung übergeben wird. Wenn der Wert WINBIO_SUBTYPE_NO_INFORMATION oder WINBIO_SUBTYPE_ANY ist, überprüfen Sie ggf..

 

Beispiele

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

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

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

StorageAdapterAddRecord