ホーム › Devices.BiometricFramework › PIBIO_STORAGE_DELETE_RECORD_FN
PIBIO_STORAGE_DELETE_RECORD_FN
コールバックシグネチャ
HRESULT PIBIO_STORAGE_DELETE_RECORD_FN(
WINBIO_PIPELINE* Pipeline,
WINBIO_IDENTITY* Identity,
BYTE SubFactor
);パラメーター
| フィールド | 型 | 説明 |
|---|---|---|
| Pipeline | WINBIO_PIPELINE* | 操作を実行するバイオメトリック ユニットに関連付けられた WINBIO_PIPELINE 構造体へのポインター。 |
| Identity | WINBIO_IDENTITY* | 削除するテンプレートの GUID または SID を格納する WINBIO_IDENTITY 構造体へのポインター。 |
| SubFactor | BYTE | 削除するテンプレートに関連付けられたサブファクターを指定する WINBIO_BIOMETRIC_SUBTYPE 値。 |
公式ドキュメント
データベースから 1 つ以上のテンプレートを削除するために、Windows Biometric Framework によって呼び出されます。
戻り値
関数が成功した場合は S_OK を返します。関数が失敗した場合は、エラーを示すために次のいずれかの HRESULT 値を返す必要があります。
| 戻り値 | 説明 |
|---|---|
| SubFactor パラメーターで指定された引数が無効であるか、Identity パラメーターで指定された構造体のメンバーが無効です。 | |
| レコード ヘッダー用のメモリを割り当てられませんでした。 | |
| 必須のポインター引数が NULL です。 | |
| データベースに原因不明の問題があります。 | |
| データベース内に一致するレコードが見つかりませんでした。 | |
| パイプライン オブジェクトの StorageContext メンバーが NULL であるか、FileHandle メンバーが無効です。 |
解説(Remarks)
Identity パラメーターが指す WINBIO_IDENTITY 構造体の Type フィールドが WINBIO_IDENTITY_TYPE_WILDCARD に設定されており、かつ SubFactor パラメーターが WINBIO_SUBTYPE_ANY である場合、ストレージ アダプターはデータベースからすべてのレコードを削除する必要があります。
重要
SubFactor パラメーターに指定された値を検証しようとしないでください。Windows Biometrics Service が、指定された値を実装に渡す前に検証します。値が WINBIO_SUBTYPE_NO_INFORMATION または WINBIO_SUBTYPE_ANY の場合は、必要に応じて検証してください。
例
次の擬似コードは、この関数の実装例の 1 つを示しています。この例はそのままではコンパイルできません。目的に合わせて適合させる必要があります。
/////////////////////////////////////////////////////////////////////////////////////////
//
// 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;
}
出典・ライセンス: 上記「公式ドキュメント」の内容は Microsoft の Win32 API ドキュメント(MicrosoftDocs/sdk-api)を日本語に翻訳・改変したものです。© Microsoft Corporation. CC BY 4.0 で提供。
Microsoft 公式リファレンス: 英語 (en-us) · 日本語 (ja-jp) · 原文ソース (GitHub)
Microsoft 公式リファレンス: 英語 (en-us) · 日本語 (ja-jp) · 原文ソース (GitHub)