Compartilhar via


função de retorno de chamada PIBIO_SENSOR_START_CAPTURE_FN (winbio_adapter.h)

Chamado pela Estrutura Biométrica do Windows para iniciar uma captura biométrica assíncrona.

Sintaxe

PIBIO_SENSOR_START_CAPTURE_FN PibioSensorStartCaptureFn;

HRESULT PibioSensorStartCaptureFn(
  [in, out] PWINBIO_PIPELINE Pipeline,
  [in]      WINBIO_BIR_PURPOSE Purpose,
  [out]     LPOVERLAPPED *Overlapped
)
{...}

Parâmetros

[in, out] Pipeline

Ponteiro para a estrutura de WINBIO_PIPELINE associada à unidade biométrica que executa a operação.

[in] Purpose

Uma máscara de bits WINBIO_BIR_PURPOSE que especifica o uso pretendido do exemplo. Isso pode ser um OR bit a bit dos seguintes valores:

  • WINBIO_PURPOSE_VERIFY
  • WINBIO_PURPOSE_IDENTIFY
  • WINBIO_PURPOSE_ENROLL
  • WINBIO_PURPOSE_ENROLL_FOR_VERIFICATION
  • WINBIO_PURPOSE_ENROLL_FOR_IDENTIFICATION

Alguns sensores têm a capacidade de capturar informações biométricas em várias resoluções. Se o parâmetro Purpose especificar mais de um sinalizador, o adaptador deverá usar o sinalizador que representa a resolução mais alta para determinar a resolução da operação de captura.

[out] Overlapped

Endereço de uma variável que recebe um ponteiro para uma estrutura OVERLAPPED que rastreia o estado da operação de captura assíncrona. Essa estrutura é criada e gerenciada pelo adaptador do sensor, mas é usada pela Estrutura Biométrica do Windows para sincronização. Para obter mais informações, consulte a seção Comentários.

Retornar valor

Se a função for bem-sucedida, ela retornará S_OK. Se a função falhar, ela retornará um valor HRESULT que indica o erro. Os valores a seguir serão reconhecidos pela Estrutura Biométrica do Windows.

Código de retorno Descrição
E_POINTER
Um argumento de ponteiro obrigatório é NULL.
E_INVALIDARG
O parâmetro Purpose não é válido.
E_OUTOFMEMORY
Não havia memória suficiente para executar a operação.
WINBIO_E_DEVICE_BUSY
O dispositivo não está pronto para capturar dados.
WINBIO_E_DEVICE_FAILURE
Houve uma falha no dispositivo.
WINBIO_E_INVALID_DEVICE_STATE
O membro SensorContext da estrutura WINBIO_PIPELINE apontada pelo argumento Pipeline é NULL ou o membro SensorHandle é definido como INVALID_HANDLE_VALUE.

Comentários

Essa função não bloqueia. Se o adaptador emitir vários comandos para o sensor para se preparar para uma operação de captura, todos, exceto o comando final, poderão ser síncronos. O comando final, emitido imediatamente antes de SensorAdapterStartCapture retornar o controle para o Windows Biometric Framework, deve ser assíncrono e deve usar E/S sobreposta.

Para usar e/S sobrepostas, comece adicionando um objeto OVERLAPPED à definição da estrutura de contexto do adaptador de sensor privado. Essa estrutura está disponível para o adaptador por meio do campo SensorContext do objeto WINBIO_PIPELINE .

Ao implementar SensorAdapterAttach, você deve executar as seguintes ações para inicializar a estrutura OVERLAPPED :

  • Limpe a estrutura OVERLAPPED chamando a função ZeroMemory .
  • Crie um objeto de evento de redefinição manual usando a função CreateEvent . É fundamental que o objeto de evento seja manual em vez de redefinição automática. O uso de eventos de redefinição automática em E/S sobrepostas pode levar a uma falta irrecuperável de resposta na operação de processamento de E/S.
  • Salve o identificador desse evento no membro hEvent da estrutura OVERLAPPED .
Ao implementar SensorAdapterDetach, você deve liberar o objeto de evento chamando a função CloseHandle . É importante não liberar esse identificador até que todas as operações de entrada e saída relacionadas à captura tenham sido concluídas ou canceladas.

O Windows Biometric Framework usa o objeto OVERLAPPED quando chama funções do sistema operacional como GetOverlappedResult e WaitForMultipleObjects para determinar quando a operação de captura foi concluída.

O identificador de evento na estrutura OVERLAPPED deve estar no estado não sinalizado quando SensorAdapterStartCapture retornar. Chamar DeviceIoControl para iniciar uma operação de E/S sobreposta redefine automaticamente o evento. Se o adaptador usar algum outro mecanismo para iniciar uma operação de E/S, você deverá redefinir o evento por conta própria.

A Estrutura Biométrica do Windows garante que apenas uma operação de E/S assíncrona esteja pendente a qualquer momento para cada unidade biométrica. Consequentemente, o adaptador do sensor precisa apenas de uma estrutura OVERLAPPED para cada pipeline de processamento.

A Estrutura Biométrica do Windows abre e fecha o identificador do adaptador do sensor e é responsável por garantir que o identificador tenha sido configurado para E/S sobreposta.

Exemplos

O pseudocódigo a seguir mostra uma possível implementação dessa função. O exemplo não é compilado. Você deve adaptá-lo para se adequar à sua finalidade.

//////////////////////////////////////////////////////////////////////////////////////////
//
// SensorAdapterStartCapture
//
// Purpose:
//      Begins an asynchronous biometric capture.
//      
// Parameters:
//      Pipeline   -  Pointer to a WINBIO_PIPELINE structure associated with 
//                    the biometric unit.
//      Purpose    -  A WINBIO_BIR_PURPOSE bitmask that specifies the intended
//                    use of the sample.
//      Overlapped -  Receives a pointer to an OVERLAPPED structure.
//
static HRESULT 
WINAPI
SensorAdapterStartCapture(
    __inout PWINBIO_PIPELINE Pipeline,
    __in WINBIO_BIR_PURPOSE Purpose,
    __out LPOVERLAPPED *Overlapped
    )
{
    HRESULT hr = S_OK;
    WINBIO_SENSOR_STATUS sensorStatus = WINBIO_SENSOR_FAILURE;
    WINBIO_CAPTURE_PARAMETERS captureParameters = {0};
    BOOL result = TRUE;
    DWORD bytesReturned = 0;

    // Verify that pointer arguments are not NULL.
    if (!ARGUMENT_PRESENT(Pipeline) ||
        !ARGUMENT_PRESENT(Purpose)  ||
        !ARGUMENT_PRESENT(Overlapped))
    {
        hr = E_POINTER;
        goto cleanup;
    }

    // Retrieve the context from the pipeline.
    PWINBIO_SENSOR_CONTEXT sensorContext = 
                       (PWINBIO_SENSOR_CONTEXT)Pipeline->SensorContext;

    // Verify the state of the pipeline.
    if (sensorContext == NULL || 
        Pipeline->SensorHandle == INVALID_HANDLE_VALUE)
    {
        return WINBIO_E_INVALID_DEVICE_STATE;
    }

    *Overlapped = NULL;

    //  Synchronously retrieve the status.
    hr = SensorAdapterQueryStatus(Pipeline, &sensorStatus);
    if (FAILED(hr))
    {
        return hr;
    }

    // Determine whether the sensor requires calibration.
    if (sensorStatus == WINBIO_SENSOR_NOT_CALIBRATED)
    {
        // Call a custom function that sends IOCTLs to
        // the sensor to calibrate it. This operation is
        // synchronous.
        hr = _SensorAdapterCalibrate(Pipeline);

        // Retrieve the status again to determine whether the 
        // sensor is ready.
        if (SUCCEEDED(hr))
        {
            hr = SensorAdapterQueryStatus(Pipeline, &sensorStatus);
        }

        if (FAILED(hr))
        {
            return hr;
        }
    }
    if (sensorStatus == WINBIO_SENSOR_BUSY)
    {
        return WINBIO_E_DEVICE_BUSY;
    }

    if (sensorStatus != WINBIO_SENSOR_READY)
    {
        return WINBIO_E_INVALID_DEVICE_STATE;
    }

    // Determine whether the data format has been previously determined.
    // If it has not, find a format supported by both the engine and 
    // the sensor.
    if ((sensorContext->Format.Owner == 0) &&
        (sensorContext->Format.Type == 0))
    {

        // Retrieve the format preferred by the engine.
        hr = Pipeline->EngineInterface->QueryPreferredFormat(
                                            Pipeline,
                                            &sensorContext->Format,
                                            &sensorContext->VendorFormat
                                            );
        if (SUCCEEDED(hr))
        {
            // Call a private function that queries the sensor driver
            // and attaches an attribute array to the sensor context.
            // This operation is synchronous.
            hr = _SensorAdapterGetAttributes(Pipeline);
        }

        if (SUCCEEDED(hr))
        {
            // Search the sensor attributes array for the format
            // preferred by the engine adapter.
            DWORD i = 0;
            for (i = 0; i < sensorContext->AttributesBuffer->SupportedFormatEntries; i++)
            {
                if ((sensorContext->AttributesBuffer->SupportedFormat[i].Owner == sensorContext->Format.Owner) &&
                    (sensorContext->AttributesBuffer->SupportedFormat[i].Type == sensorContext->Format.Type))
                {
                    break;
                }
            }

            if (i == sensorContext->AttributesBuffer->SupportedFormatEntries)
            {
                // No match was found. Use the default.
                sensorContext->Format.Owner = WINBIO_ANSI_381_FORMAT_OWNER;
                sensorContext->Format.Type = WINBIO_ANSI_381_FORMAT_TYPE;
            }
        }
        else
        {
            return hr;
        }
    }

    // Set up the parameter-input block needed for the IOCTL.
    captureParameters.PayloadSize = sizeof(WINBIO_CAPTURE_PARAMETERS);
    captureParameters.Purpose = Purpose;
    captureParameters.Format.Owner = sensorContext->Format.Owner;
    captureParameters.Format.Type = sensorContext->Format.Type;
    CopyMemory(&captureParameters.VendorFormat, &sensorContext->VendorFormat, sizeof (WINBIO_UUID));
    captureParameters.Flags = WINBIO_DATA_FLAG_RAW;

    // Determine whether a buffer has already been allocated for this sensor.
    if (sensorContext->CaptureBuffer == NULL)
    {
        DWORD allocationSize = 0;

        sensorContext->CaptureBufferSize = 0;

        // This sample assumes that the sensor driver returns
        // a fixed-size DWORD buffer containing the required
        // size of the capture buffer if it receives a buffer
        // that is smaller than sizeof(WINBIO_CAPTURE_DATA).
        //
        // Call the driver with a small buffer to get the 
        // allocation size required for this sensor.
        //
        // Because this operation is asynchronous, you must block 
        // and wait for it to complete.
        result = DeviceIoControl(
                    Pipeline->SensorHandle,
                    IOCTL_VENDOR_PRIVATE_CMD_CAPTURE_DATA,
                    &captureParameters,
                    sizeof(WINBIO_CAPTURE_PARAMETERS),
                    &allocationSize,
                    sizeof(DWORD),
                    &bytesReturned,
                    &sensorContext->Overlapped
                    );
        if (!result && GetLastError() == ERROR_IO_PENDING)
        {
            SetLastError(ERROR_SUCCESS);

            result = GetOverlappedResult(
                        Pipeline->SensorHandle,
                        &sensorContext->Overlapped,
                        &bytesReturned,
                        TRUE
                        );
        }

        if (!result || bytesReturned != sizeof (DWORD))
        {
            // An error occurred.
            hr = _AdapterGetHresultFromWin32(GetLastError());
            return hr;
        }

        // Make sure that you allocate at least the minimum buffer 
        // size needed to get the payload structure.
        if (allocationSize < sizeof(WINBIO_CAPTURE_DATA))
        {
            allocationSize = sizeof(WINBIO_CAPTURE_DATA);
        }

        // Allocate the buffer.
        sensorContext->CaptureBuffer = (PWINBIO_CAPTURE_DATA)_AdapterAlloc(allocationSize);
        if (!sensorContext->CaptureBuffer)
        {
            sensorContext->CaptureBufferSize = 0;
            return E_OUTOFMEMORY;
        }
        sensorContext->CaptureBufferSize = allocationSize;
    }
    else
    {
        // The buffer has already been allocated. Clear the buffer contents. 
        SensorAdapterClearContext(Pipeline);
    }

    // Send the capture request. Because this is an asynchronous operation,
    // the IOCTL call will return immediately regardless of 
    // whether the I/O has completed.
    result = DeviceIoControl(
                Pipeline->SensorHandle,
                IOCTL_VENDOR_PRIVATE_CMD_CAPTURE_DATA,
                &captureParameters,
                sizeof (WINBIO_CAPTURE_PARAMETERS),
                sensorContext->CaptureBuffer,
                sensorContext->CaptureBufferSize,
                &bytesReturned,
                &sensorContext->Overlapped
                );

    if (result ||
        (!result && GetLastError() == ERROR_IO_PENDING))
    {
        *Overlapped = &sensorContext->Overlapped;
        return S_OK;
    }
    else
    {
        hr = _AdapterGetHresultFromWin32(GetLastError());
        return hr;
    }
}

Requisitos

Requisito Valor
Cliente mínimo com suporte Windows 7 [somente aplicativos da área de trabalho]
Servidor mínimo com suporte Windows Server 2008 R2 [somente aplicativos da área de trabalho]
Plataforma de Destino Windows
Cabeçalho winbio_adapter.h (inclua Winbio_adapter.h)

Confira também

Funções de plug-in

SensorAdapterFinishCapture