PIBIO_SENSOR_START_CAPTURE_FN 콜백 함수(winbio_adapter.h)
비동기 생체 인식 캡처를 시작하기 위해 Windows 생체 인식 프레임워크에서 호출됩니다.
구문
PIBIO_SENSOR_START_CAPTURE_FN PibioSensorStartCaptureFn;
HRESULT PibioSensorStartCaptureFn(
[in, out] PWINBIO_PIPELINE Pipeline,
[in] WINBIO_BIR_PURPOSE Purpose,
[out] LPOVERLAPPED *Overlapped
)
{...}
매개 변수
[in, out] Pipeline
작업을 수행하는 생체 인식 단위와 연결된 WINBIO_PIPELINE 구조체에 대한 포인터입니다.
[in] Purpose
샘플의 의도된 사용을 지정하는 WINBIO_BIR_PURPOSE 비트 마스크입니다. 다음 값 중 비트 OR 일 수 있습니다.
- WINBIO_PURPOSE_VERIFY
- WINBIO_PURPOSE_IDENTIFY
- WINBIO_PURPOSE_ENROLL
- WINBIO_PURPOSE_ENROLL_FOR_VERIFICATION
- WINBIO_PURPOSE_ENROLL_FOR_IDENTIFICATION
일부 센서는 여러 해상도로 생체 인식 정보를 캡처할 수 있습니다. Purpose 매개 변수가 둘 이상의 플래그를 지정하는 경우 어댑터는 가장 높은 해상도를 나타내는 플래그를 사용하여 캡처 작업의 해상도를 결정해야 합니다.
[out] Overlapped
비동기 캡처 작업의 상태를 추적하는 OVERLAPPED 구조체에 대한 포인터를 수신하는 변수의 주소입니다. 이 구조체는 센서 어댑터에서 만들고 관리하지만 동기화를 위해 Windows 생체 인식 프레임워크에서 사용됩니다. 자세한 내용은 주의 섹션을 참조하세요.
반환 값
함수가 성공하면 S_OK를 반환합니다. 함수가 실패하면 오류를 나타내는 HRESULT 값을 반환합니다. 다음 값은 Windows 생체 인식 프레임워크에서 인식됩니다.
반환 코드 | 설명 |
---|---|
|
필수 포인터 인수는 NULL입니다. |
|
Purpose 매개 변수가 잘못되었습니다. |
|
작업을 수행하기에 충분한 메모리가 없습니다. |
|
디바이스가 데이터를 캡처할 준비가 되지 않았습니다. |
|
디바이스 오류가 발생했습니다. |
|
Pipeline 인수가 가리키는 WINBIO_PIPELINE 구조체의 SensorContext 멤버가 NULL이거나 SensorHandle 멤버가 INVALID_HANDLE_VALUE 설정됩니다. |
설명
이 함수는 차단하지 않습니다. 어댑터가 센서에 여러 명령을 실행하여 캡처 작업을 준비하는 경우 최종 명령을 제외한 모든 명령이 동기식일 수 있습니다. SensorAdapterStartCapture가 Windows 생체 인식 프레임워크에 컨트롤을 반환하기 직전에 실행된 최종 명령은 비동기여야 하며 겹치는 I/O를 사용해야 합니다.
겹치는 I/O를 사용하려면 먼저 개인 센서 어댑터 컨텍스트 구조의 정의에 OVERLAPPED 개체를 추가합니다. 이 구조체는 WINBIO_PIPELINE 개체의 SensorContext 필드를 통해 어댑터에서 사용할 수 있습니다.
SensorAdapterAttach를 구현하는 경우 다음 작업을 수행하여 OVERLAPPED 구조를 초기화해야 합니다.
- ZeroMemory 함수를 호출하여 OVERLAPPED 구조를 지웁니다.
- CreateEvent 함수를 사용하여 수동 재설정 이벤트 개체를 만듭니다. 이벤트 개체는 자동 재설정이 아닌 수동이어야 합니다. 겹치는 I/O에서 자동 재설정 이벤트를 사용하면 I/O 처리 작업에서 복구할 수 없는 응답이 부족할 수 있습니다.
- 이 이벤트의 핸들을 OVERLAPPED 구조체의 hEvent 멤버에 저장합니다.
Windows 생체 인식 프레임워크는 GetOverlappedResult 및 WaitForMultipleObjects와 같은 운영 체제 함수를 호출하여 캡처 작업이 완료된 시기를 결정할 때 OVERLAPPED 개체를 사용합니다.
OVERLAPPED 구조체의 이벤트 핸들은 SensorAdapterStartCapture가 반환될 때 신호가 없는 상태여야 합니다. DeviceIoControl을 호출하여 겹치는 I/O 작업을 시작하면 이벤트가 자동으로 다시 설정됩니다. 어댑터가 다른 메커니즘을 사용하여 I/O 작업을 시작하는 경우 이벤트를 직접 다시 설정해야 합니다.
Windows 생체 인식 프레임워크는 각 생체 인식 단위에 대해 언제든지 하나의 비동기 I/O 작업만 처리되도록 보장합니다. 따라서 센서 어댑터는 각 처리 파이프라인에 대해 하나의 OVERLAPPED 구조만 필요합니다.
Windows 생체 인식 프레임워크는 센서 어댑터 핸들을 열고 닫으며 핸들이 겹치는 I/O에 대해 구성되었는지 확인합니다.
예제
다음 의사 코드는 이 함수의 가능한 구현 중 하나를 보여 줍니다. 예제는 컴파일되지 않습니다. 목적에 맞게 조정해야 합니다.
//////////////////////////////////////////////////////////////////////////////////////////
//
// 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;
}
}
요구 사항
요구 사항 | 값 |
---|---|
지원되는 최소 클라이언트 | Windows 7 [데스크톱 앱만 해당] |
지원되는 최소 서버 | Windows Server 2008 R2 [데스크톱 앱만 해당] |
대상 플랫폼 | Windows |
헤더 | winbio_adapter.h(Winbio_adapter.h 포함) |