PIBIO_STORAGE_QUERY_BY_CONTENT_FN fonction de rappel (winbio_adapter.h)
Appelé par l’adaptateur de moteur pour localiser les modèles qui correspondent à un vecteur d’index spécifié.
Syntaxe
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
)
{...}
Paramètres
[in, out] Pipeline
Pointeur vers la structure WINBIO_PIPELINE associée à l’unité biométrique effectuant l’opération.
[in] SubFactor
Valeur WINBIO_BIOMETRIC_SUBTYPE qui spécifie le sous-facteur associé au modèle.
IndexVector[]
[in] IndexElementCount
Valeur qui contient le nombre d’éléments dans le tableau de vecteurs d’index. Cela doit correspondre à la taille spécifiée lors de la création de la base de données. Si la base de données a été créée avec un index de longueur nulle, ce paramètre doit être égal à zéro.
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 |
---|---|
|
L’argument spécifié par le paramètre SubFactor n’est pas valide. |
|
Un argument pointeur obligatoire est NULL. |
|
Impossible d’allouer de la mémoire à l’en-tête d’enregistrement. |
|
La taille du vecteur d’index ne correspond pas à la taille d’index spécifiée lors de la création de la base de données. |
|
La requête a réussi, mais aucun enregistrement correspondant n’a pu être trouvé. |
|
La base de données est verrouillée. |
|
Un problème non spécifié s’est produit. |
|
Le membre StorageContext de l’objet pipeline est NULL ou le membre FileHandle n’est pas valide. |
Remarques
Si cette méthode retourne correctement, le jeu de résultats dans le pipeline est remplacé par les résultats de la requête, même si la requête retourne un jeu vide.
Si la base de données a été créée avec un vecteur d’index de longueur nulle, le jeu de résultats contient chaque enregistrement pour lequel le sous-facteur de modèle correspond au paramètre SubFactor . Dans ce cas, si l’appelant transmet WINBIO_SUBTYPE_ANY pour le paramètre SubFactor , cette fonction retourne tous les enregistrements de la base de données.
Après un appel réussi à cette fonction, le curseur du jeu de résultats doit être positionné sur le premier enregistrement du jeu.
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 pseudo-code suivant montre une implémentation possible de cette fonction. L’exemple ne se compile pas. Vous devez l’adapter à votre objectif.
/////////////////////////////////////////////////////////////////////////////////////////
//
// 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;
}
Configuration requise
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) |