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
接收 重疊 結構指標的變數位址,該結構會追蹤異步擷取作業的狀態。 此結構是由感測器配接器所建立和管理,但由 Windows 生物特徵辨識架構用於同步處理。 如需詳細資訊,請參閱<備註>一節。
傳回值
如果函式成功,它會傳回S_OK。 如果函式失敗,它會傳回 HRESULT 值,指出錯誤。 Windows 生物特徵辨識架構會辨識下列值。
傳回碼 | Description |
---|---|
|
強制指標自變數為 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 處理作業中無法復原的回應不足。
- 將這個事件的句柄儲存在重疊結構的 hEvent 成員中。
Windows 生物特徵辨識架構會在呼叫 GetOverlappedResult 和 WaitForMultipleObjects 等操作系統函式時使用 OVERLAPPED 物件,以判斷擷取作業何時完成。
當 SensorAdapterStartCapture 傳回時,OVERLAPPED 結構中的事件句柄必須處於非訊號狀態。 呼叫 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) |