다음을 통해 공유


PIBIO_STORAGE_QUERY_BY_CONTENT_FN 콜백 함수(winbio_adapter.h)

엔진 어댑터에서 지정된 인덱스 벡터와 일치하는 템플릿을 찾기 위해 호출됩니다.

구문

PIBIO_STORAGE_QUERY_BY_CONTENT_FN PibioStorageQueryByContentFn;

HRESULT PibioStorageQueryByContentFn(
  [in, out] PWINBIO_PIPELINE Pipeline,
  [in]      WINBIO_BIOMETRIC_SUBTYPE SubFactor,
            ULONG IndexVector[],
  [in]      SIZE_T IndexElementCount
)
{...}

매개 변수

[in, out] Pipeline

작업을 수행하는 생체 인식 단위와 연결된 WINBIO_PIPELINE 구조체에 대한 포인터입니다.

[in] SubFactor

템플릿과 연결된 하위 요소를 지정하는 WINBIO_BIOMETRIC_SUBTYPE 값입니다.

IndexVector[]

[in] IndexElementCount

인덱스 벡터 배열의 요소 수를 포함하는 값입니다. 데이터베이스를 만들 때 지정한 크기와 일치해야 합니다. 길이가 0인 인덱스로 데이터베이스를 만든 경우 이 매개 변수는 0이어야 합니다.

반환 값

함수가 성공하면 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 멤버가 잘못되었습니다.

설명

이 메서드가 성공적으로 반환되면 쿼리가 빈 집합을 반환하더라도 파이프라인의 결과 집합이 쿼리의 결과로 대체됩니다.

길이가 0인 인덱스 벡터를 사용하여 데이터베이스를 만든 경우 결과 집합에는 템플릿 하위 요소가 SubFactor 매개 변수와 일치하는 모든 레코드가 포함됩니다. 이 경우 호출자가 SubFactor 매개 변수에 대한 WINBIO_SUBTYPE_ANY 전달하는 경우 이 함수는 데이터베이스의 모든 레코드를 반환합니다.

이 함수를 성공적으로 호출한 후에는 결과 집합 커서가 집합의 첫 번째 레코드에 배치되어야 합니다.

중요  

SubFactor 매개 변수에 제공된 값의 유효성을 검사하지 마세요. Windows 생체 인식 서비스는 제공된 값을 구현에 전달하기 전에 유효성을 검사합니다. 값이 WINBIO_SUBTYPE_NO_INFORMATION 또는 WINBIO_SUBTYPE_ANY 경우 적절한 경우 유효성을 검사합니다.

 

예제

다음 의사 코드는 이 함수의 가능한 구현 중 하나를 보여 줍니다. 예제는 컴파일되지 않습니다. 목적에 맞게 조정해야 합니다.

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

요구 사항

   
지원되는 최소 클라이언트 Windows 7 [데스크톱 앱만 해당]
지원되는 최소 서버 Windows Server 2008 R2 [데스크톱 앱만 해당]
대상 플랫폼 Windows
헤더 winbio_adapter.h(Winbio_adapter.h 포함)

추가 정보

플러그 인 함수

StorageAdapterFirstRecord

StorageAdapterGetCurrentRecord

StorageAdapterGetRecordCount

StorageAdapterNextRecord

StorageAdapterQueryBySubject