Win32 API 日本語リファレンス
ホーム › Devices.BiometricFramework › PIBIO_STORAGE_QUERY_BY_CONTENT_FN

PIBIO_STORAGE_QUERY_BY_CONTENT_FN

コールバック

シグネチャ

HRESULT PIBIO_STORAGE_QUERY_BY_CONTENT_FN(
    WINBIO_PIPELINE* Pipeline,
    BYTE SubFactor,
    DWORD* IndexVector,
    UINT_PTR IndexElementCount
);

パラメーター

フィールド型説明
PipelineWINBIO_PIPELINE*操作を実行するバイオメトリックユニットに関連付けられた WINBIO_PIPELINE 構造体へのポインター。
SubFactorBYTEテンプレートに関連付けられたサブファクターを指定する WINBIO_BIOMETRIC_SUBTYPE 値。
IndexVectorDWORD*
IndexElementCountUINT_PTR

インデックスベクター配列内の要素数を格納する値。これは、データベースの作成時に指定されたサイズと一致している必要があります。データベースが長さ 0 のインデックスで作成された場合、このパラメーターは 0 でなければなりません。

- IndexVector [in]

ULONG 型のインデックス値の配列へのポインター。一致するインデックスを持つテンプレートがすべて返されます。データベースが長さ 0 のインデックスで作成された場合、このパラメーターは NULL でなければなりません。

公式ドキュメント

指定されたインデックスベクターに一致するテンプレートを探すために、エンジンアダプターから呼び出されます。

戻り値

関数が成功した場合は S_OK を返します。失敗した場合は、エラーを示す次のいずれかの HRESULT 値を返す必要があります。

戻り値 説明
E_INVALIDARG
SubFactor パラメーターで指定された引数が無効です。
E_POINTER
必須のポインター引数が NULL です。
E_OUTOFMEMORY
レコードヘッダー用のメモリを割り当てられませんでした。
WINBIO_E_DATABASE_BAD_INDEX_VECTOR
インデックスベクターのサイズが、データベースの作成時に指定されたインデックスサイズと一致しません。
WINBIO_E_DATABASE_NO_RESULTS
クエリは成功しましたが、一致するレコードが見つかりませんでした。
WINBIO_E_DATABASE_LOCKED
データベースがロックされています。
WINBIO_E_DATABASE_READ_ERROR
原因不明の問題が発生しました。
WINBIO_E_INVALID_DEVICE_STATE
パイプラインオブジェクトの StorageContext メンバーが NULL であるか、FileHandle メンバーが無効です。

解説(Remarks)

このメソッドが正常に返された場合、クエリが空のセットを返したときでも、パイプライン内の結果セットはクエリの結果で置き換えられます。

データベースが長さ 0 のインデックスベクターで作成されている場合、結果セットには、テンプレートのサブファクターが SubFactor パラメーターと一致するすべてのレコードが含まれます。この場合、呼び出し元が SubFactor パラメーターに WINBIO_SUBTYPE_ANY を渡すと、この関数はデータベース内のすべてのレコードを返します。

この関数の呼び出しに成功した後、結果セットのカーソルはセット内の最初のレコードに位置付けられている必要があります。

重要

SubFactor パラメーターに指定された値を検証しようとしないでください。Windows Biometric Service は、指定された値を実装に渡す前に検証します。値が WINBIO_SUBTYPE_NO_INFORMATION または WINBIO_SUBTYPE_ANY の場合は、必要に応じて検証してください。

例

次の擬似コードは、この関数の実装例の 1 つを示しています。この例はコンパイルできません。目的に合わせて適用してください。

/////////////////////////////////////////////////////////////////////////////////////////
//
// StorageAdapterQueryByContent
//
// Purpose:
//      Locates templates that match a specified index vector.
//
// Parameters:
//      Pipeline          - Pointer to a WINBIO_PIPELINE structure associated with 
//                          the biometric unit performing the operation.
//      SubFactor         - A WINBIO_BIOMETRIC_SUBTYPE value that specifies the sub-factor 
//                          associated with the template.
//      IndexVector       - Pointer to an array of ULONG index values.
//      IndexElementCount - A value that contains the number of elements in the index 
//                          vector array.
//
static HRESULT
WINAPI
StorageAdapterQueryByContent(
    __inout PWINBIO_PIPELINE Pipeline,
    __in WINBIO_BIOMETRIC_SUBTYPE SubFactor,
    __in ULONG IndexVector[],
    __in SIZE_T IndexElementCount
    )
{
    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;

    // Verify that the Pipeline parameter is not NULL.
    if (!ARGUMENT_PRESENT(Pipeline) ||
        !ARGUMENT_PRESENT(IndexVector))
    {
        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;
    }

    // WINBIO_SUBTYPE_ANY is a valid sub-factor.
    // WINBIO_SUBTYPE_NO_INFORMATION is not a valid sub-factor.
    if (SubFactor == WINBIO_SUBTYPE_NO_INFORMATION)
    {
        hr = E_INVALIDARG;
        goto cleanup;
    }

    // Validate the IndexElementCount argument.
    if (IndexElementCount != storageContext->IndexElementCount)
    {
        hr = WINBIO_E_DATABASE_BAD_INDEX_VECTOR;
        goto cleanup;
    }
    if (storageContext->IndexElementCount > 0 &&
        !ARGUMENT_PRESENT(IndexVector))
    {
        hr = E_POINTER;
        goto cleanup;
    }

    // Clear the result set.
    hr = StorageAdapterClearContext(Pipeline);
    if (FAILED(hr))
    {
        goto cleanup;
    }

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

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

    // Scan through all records looking for index vector matches.
    recordHeaderSize = 
        sizeof(struct _MY_ADAPTER_RECORD_HEADER) +
        (SIZE_T)fileHeader.IndexElementCount * sizeof(ULONG);

    currentRecordOffset = _MY_ADAPTER_FIRST_RECORD_OFFSET;
    remainingRecords = fileHeader.TotalRecordCount;

    while (remainingRecords > 0)
    {
        SIZE_T recordSize = 0;
        BOOLEAN match = FALSE;
        LARGE_INTEGER dataOffset = {0};

        // If you did not give up the current header during the previous 
        // iteration of the loop, reuse it.
        if (recordHeader == NULL)
        {
            recordHeader = (struct _MY_ADAPTER_RECORD_HEADER*)_AdapterAlloc( recordHeaderSize );
            if (recordHeader == NULL)
            {
                hr = E_OUTOFMEMORY;
                goto cleanup;
            }
        }
        else
        {
            ZeroMemory(recordHeader, recordHeaderSize);
        }

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

        recordSize = recordHeader->RecordSize;

        // Skip records marked for deletion.
        if ((recordHeader->Flags & _MY_ADAPTER_FLAG_RECORD_DELETED) == 0)
        {
            // Call a custom function (_MatchIndexVector) that compares the index
            // vector of the current record with the input index vector.
            hr = _MatchIndexVector(
                    SubFactor,
                    IndexVector,
                    IndexElementCount,
                    recordHeader->SubFactor,
                    _GetIndexVector(recordHeader),
                    storageContext->IndexElementCount,
                    &match
                    );
            if (FAILED(hr))
            {
                goto cleanup;
            }

            if (match == TRUE)
            {
                // Calculate the file offset of this record's data area.
                dataOffset.QuadPart = 
                    currentRecordOffset.QuadPart + 
                    recordHeader->RecordHeaderSize;

                // Add the matching record to the result set in the pipeline.
                hr = _ResultSetAddElement( 
                        &storageContext->ResultSet, 
                        recordHeader, 
                        dataOffset
                        );
                if (FAILED(hr))
                {
                    goto cleanup;
                }
                // The result set now owns the record header. Set the pointer
                // to NULL.
                recordHeader = NULL;
            }
        }

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

    // If the search was successful, but the result set is empty, return 
    // WINBIO_E_DATABASE_NO_RESULTS
    if (SUCCEEDED(hr))
    {
        SIZE_T elementCount = 0;
        hr = _ResultSetGetCount(&storageContext->ResultSet, &elementCount);
    }

cleanup:

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

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

    if (FAILED(hr))
    {
        // Clear any partial result set from the pipeline.
        StorageAdapterClearContext(Pipeline);
    }

    return hr;
}
出典・ライセンス: 上記「公式ドキュメント」の内容は Microsoft の Win32 API ドキュメント(MicrosoftDocs/sdk-api)を日本語に翻訳・改変したものです。© Microsoft Corporation. CC BY 4.0 で提供。
Microsoft 公式リファレンス: 英語 (en-us) · 日本語 (ja-jp) · 原文ソース (GitHub)