Vanara/PInvoke/WinBio/WinBio.cs

7734 lines
470 KiB
C#

using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Security.Cryptography;
using Vanara.Extensions;
using Vanara.InteropServices;
using WINBIO_UNIT_ID = System.UInt32;
namespace Vanara.PInvoke
{
/// <summary>Items from the WinBio.dll</summary>
public static partial class WinBio
{
/// <summary>
/// Can be used for scenarios prior to starting Windows. Typically, the database is part of the sensor chip or is part of the BIOS
/// and can only be used for template enrollment and deletion.
/// </summary>
public static readonly GuidPtr WINBIO_DB_BOOTSTRAP = (IntPtr)2;
/// <summary>Each biometric unit in the sensor pool uses the default database specified in the default biometric unit configuration.</summary>
public static readonly GuidPtr WINBIO_DB_DEFAULT = (IntPtr)1;
/// <summary>The database resides on the sensor chip.</summary>
public static readonly GuidPtr WINBIO_DB_ONCHIP = (IntPtr)3;
private const string Lib_Winbio = "winbio.dll";
/// <summary>
/// Called by the Windows Biometric Framework to notify the client application that an asynchronous operation has completed. The
/// callback is defined by the client application and called by the Windows Biometric Framework.
/// </summary>
/// <param name="AsyncResult">
/// Pointer to a WINBIO_ASYNC_RESULT structure that contains information about the completed operation. The structure is created by
/// the Windows Biometric Framework. You must call WinBioFree to release the structure.
/// </param>
/// <returns>None</returns>
/// <remarks>
/// <para>
/// You must create this callback if you open a biometric session by using the WinBioAsyncOpenSession function or the
/// WinBioAsyncOpenFramework function and you set <c>WINBIO_ASYNC_NOTIFY_CALLBACK</c> in the NotificationMethod parameter of either function.
/// </para>
/// <para>
/// <c>Important</c> The WINBIO_ASYNC_RESULT structure is allocated internally by the Windows Biometric Framework. Therefore, when
/// you are through using it, call WinBioFree to release the allocated memory and avoid leaks. Because this also releases all nested
/// data structures, you should not keep a copy of any pointers returned in the <c>WINBIO_ASYNC_RESULT</c> structure. If you want to
/// save any data returned in a nested structure, make a private copy of that data before calling <c>WinBioFree</c>.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winbio/nc-winbio-pwinbio_async_completion_callback
// PWINBIO_ASYNC_COMPLETION_CALLBACK PwinbioAsyncCompletionCallback; void PwinbioAsyncCompletionCallback( PWINBIO_ASYNC_RESULT
// AsyncResult ) {...}
[UnmanagedFunctionPointer(CallingConvention.ThisCall)]
[PInvokeData("winbio.h", MSDNShortId = "NC:winbio.PWINBIO_ASYNC_COMPLETION_CALLBACK")]
public delegate void PWINBIO_ASYNC_COMPLETION_CALLBACK(/*in WINBIO_ASYNC_RESULT*/ [In] IntPtr AsyncResult);
/// <summary>
/// <para>
/// Called by the Windows Biometric Framework to return results from the asynchronous WinBioCaptureSampleWithCallback function. The
/// client application must implement this function.
/// </para>
/// <para>
/// <c>Important</c> We recommend that, beginning with Windows 8, you no longer use the <c>PWINBIO_CAPTURE_CALLBACK</c>/
/// <c>WinBioCaptureSampleWithCallback</c> combination. Instead, do the following:
/// </para>
/// </summary>
/// <param name="CaptureCallbackContext">
/// Pointer to a buffer defined by the application and passed to the CaptureCallbackContext parameter of the
/// WinBioCaptureSampleWithCallback function. The buffer is not modified by the framework or the biometric unit. Your application
/// can use the data to help it determine what actions to perform or to maintain additional information about the biometric capture.
/// </param>
/// <param name="OperationStatus">Error code returned by the capture operation.</param>
/// <param name="UnitId">Biometric unit ID number.</param>
/// <param name="Sample">Pointer to the sample data.</param>
/// <param name="SampleSize">Size, in bytes, of the sample data pointed to by the Sample parameter.</param>
/// <param name="RejectDetail">
/// Additional information about the failure, if any, to perform the operation. For more information, see Remarks.
/// </param>
/// <returns>None</returns>
/// <remarks>
/// <para>
/// Currently, the Windows Biometric Framework supports only fingerprint readers. Therefore, if an operation fails and returns
/// additional information in a <c>WINBIO_REJECT_DETAIL</c> constant, it will be one of the following values:
/// </para>
/// <list type="bullet">
/// <item>
/// <term>WINBIO_FP_TOO_HIGH</term>
/// </item>
/// <item>
/// <term>WINBIO_FP_TOO_LOW</term>
/// </item>
/// <item>
/// <term>WINBIO_FP_TOO_LEFT</term>
/// </item>
/// <item>
/// <term>WINBIO_FP_TOO_RIGHT</term>
/// </item>
/// <item>
/// <term>WINBIO_FP_TOO_FAST</term>
/// </item>
/// <item>
/// <term>WINBIO_FP_TOO_SLOW</term>
/// </item>
/// <item>
/// <term>WINBIO_FP_POOR_QUALITY</term>
/// </item>
/// <item>
/// <term>WINBIO_FP_TOO_SKEWED</term>
/// </item>
/// <item>
/// <term>WINBIO_FP_TOO_SHORT</term>
/// </item>
/// <item>
/// <term>WINBIO_FP_MERGE_FAILURE</term>
/// </item>
/// </list>
/// <para>Examples</para>
/// <para>
/// The following code example captures a sample asynchronously by calling WinBioCaptureSampleWithCallback and passing a pointer to
/// a custom callback function, CaptureSampleCallback. Link to the Winbio.lib static library and include the following header files:
/// </para>
/// <list type="bullet">
/// <item>
/// <term>Windows.h</term>
/// </item>
/// <item>
/// <term>Stdio.h</term>
/// </item>
/// <item>
/// <term>Conio.h</term>
/// </item>
/// <item>
/// <term>Winbio.h</term>
/// </item>
/// </list>
/// <para>
/// <code>HRESULT CaptureSampleWithCallback(BOOL bCancel) { HRESULT hr = S_OK; WINBIO_SESSION_HANDLE sessionHandle = NULL; // Connect to the system pool. hr = WinBioOpenSession( WINBIO_TYPE_FINGERPRINT, // Service provider WINBIO_POOL_SYSTEM, // Pool type WINBIO_FLAG_RAW, // Raw access NULL, // Array of biometric unit IDs 0, // Count of biometric unit IDs WINBIO_DB_DEFAULT, // Default database &amp;sessionHandle // [out] Session handle ); if (FAILED(hr)) { wprintf_s(L"\n WinBioOpenSession failed. hr = 0x%x\n", hr); goto e_Exit; } // Capture a biometric sample asynchronously. wprintf_s(L"\n Calling WinBioCaptureSampleWithCallback "); hr = WinBioCaptureSampleWithCallback( sessionHandle, // Open session handle WINBIO_NO_PURPOSE_AVAILABLE, // Intended use of the sample WINBIO_DATA_FLAG_RAW, // Sample format CaptureSampleCallback, // Callback function NULL // Optional context ); if (FAILED(hr)) { wprintf_s(L"\n WinBioCaptureSampleWithCallback failed. "); wprintf_s(L"hr = 0x%x\n", hr); goto e_Exit; } wprintf_s(L"\n Swipe the sensor ...\n"); // Cancel the capture process if the bCancel flag is set. if (bCancel) { wprintf_s(L"\n Starting CANCEL timer..."); Sleep( 7000 ); wprintf_s(L"\n Calling WinBioCancel\n"); hr = WinBioCancel( sessionHandle ); if (FAILED(hr)) { wprintf_s(L"\n WinBioCancel failed. hr = 0x%x\n", hr); goto e_Exit; } } // Wait for the asynchronous capture process to complete // or be canceled. hr = WinBioWait( sessionHandle ); if (FAILED(hr)) { wprintf_s(L"\n WinBioWait failed. hr = 0x%x\n", hr); } e_Exit: if (sessionHandle != NULL) { WinBioCloseSession(sessionHandle); sessionHandle = NULL; } wprintf_s(L"\n Press any key to exit..."); _getch(); return hr; } //------------------------------------------------------------------------ // The following function is the callback for WinBioCaptureSampleWithCallback. // The function filters the response from the biometric subsystem and // writes a result to the console window. // VOID CALLBACK CaptureSampleCallback( __in_opt PVOID CaptureCallbackContext, __in HRESULT OperationStatus, __in WINBIO_UNIT_ID UnitId, __in_bcount(SampleSize) PWINBIO_BIR Sample, __in SIZE_T SampleSize, __in WINBIO_REJECT_DETAIL RejectDetail ) { UNREFERENCED_PARAMETER(CaptureCallbackContext); wprintf_s(L"\n CaptureSampleCallback executing"); wprintf_s(L"\n Swipe processed - Unit ID: %d", UnitId); if (FAILED(OperationStatus)) { if (OperationStatus == WINBIO_E_BAD_CAPTURE) { wprintf_s(L"\n Bad capture; reason: %d\n", RejectDetail); } else { wprintf_s(L"\n WinBioCaptureSampleWithCallback failed. "); wprintf_s(L" OperationStatus = 0x%x\n", OperationStatus); } goto e_Exit; } wprintf_s(L"\n Captured %d bytes.\n", SampleSize); e_Exit: if (Sample != NULL) { WinBioFree(Sample); Sample = NULL; } }</code>
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winbio/nc-winbio-pwinbio_capture_callback PWINBIO_CAPTURE_CALLBACK
// PwinbioCaptureCallback; void PwinbioCaptureCallback( PVOID CaptureCallbackContext, HRESULT OperationStatus, WINBIO_UNIT_ID
// UnitId, PWINBIO_BIR Sample, SIZE_T SampleSize, WINBIO_REJECT_DETAIL RejectDetail ) {...}
[UnmanagedFunctionPointer(CallingConvention.Winapi)]
[PInvokeData("winbio.h", MSDNShortId = "NC:winbio.PWINBIO_CAPTURE_CALLBACK")]
public delegate void PWINBIO_CAPTURE_CALLBACK([In, Optional] IntPtr CaptureCallbackContext, [In] HRESULT OperationStatus, uint UnitId, [In] IntPtr Sample, SizeT SampleSize, WINBIO_REJECT_DETAIL RejectDetail);
/// <summary>
/// <para>
/// The <c>PWINBIO_ENROLL_CAPTURE_CALLBACK</c> function is called by the Windows Biometric Framework to return results from the
/// asynchronous WinBioEnrollCaptureWithCallback function. The client application must implement this function.
/// </para>
/// <para>
/// <c>Important</c> We recommend that, beginning with Windows 8, you no longer use the <c>PWINBIO_ENROLL_CAPTURE_CALLBACK</c>/
/// <c>WinBioEnrollCaptureWithCallback</c> combination. Instead, do the following:
/// </para>
/// </summary>
/// <param name="EnrollCallbackContext">
/// Pointer to a buffer defined by the application and passed to the EnrollCallback parameter of the WinBioEnrollCaptureWithCallback
/// function. The buffer is not modified by the framework or the biometric unit. Your application can use the data to help it
/// determine what actions to perform or to maintain additional information about the biometric capture.
/// </param>
/// <param name="OperationStatus">Error code returned by the capture operation.</param>
/// <param name="RejectDetail">
/// Additional information about the failure, if any, to perform the operation. For more information, see Remarks.
/// </param>
/// <returns>None</returns>
/// <remarks>
/// <para>
/// Currently, the Windows Biometric Framework supports only fingerprint readers. Therefore, if an operation fails and returns
/// additional information in a <c>WINBIO_REJECT_DETAIL</c> constant, it will be one of the following values:
/// </para>
/// <list type="bullet">
/// <item>
/// <term>WINBIO_FP_TOO_HIGH</term>
/// </item>
/// <item>
/// <term>WINBIO_FP_TOO_LOW</term>
/// </item>
/// <item>
/// <term>WINBIO_FP_TOO_LEFT</term>
/// </item>
/// <item>
/// <term>WINBIO_FP_TOO_RIGHT</term>
/// </item>
/// <item>
/// <term>WINBIO_FP_TOO_FAST</term>
/// </item>
/// <item>
/// <term>WINBIO_FP_TOO_SLOW</term>
/// </item>
/// <item>
/// <term>WINBIO_FP_POOR_QUALITY</term>
/// </item>
/// <item>
/// <term>WINBIO_FP_TOO_SKEWED</term>
/// </item>
/// <item>
/// <term>WINBIO_FP_TOO_SHORT</term>
/// </item>
/// <item>
/// <term>WINBIO_FP_MERGE_FAILURE</term>
/// </item>
/// </list>
/// <para>Examples</para>
/// <para>
/// The following code example enrolls a fingerprint asynchronously by calling WinBioEnrollCaptureWithCallback and passing a pointer
/// to a custom callback function, EnrollCaptureCallback. Link to the Winbio.lib static library.
/// </para>
/// <para>
/// <code>//------------------------------------------------------------------------ // EnrollSystemPoolWithCallback.cpp : console application entry point. // #include &lt;windows.h&gt; #include &lt;stdio.h&gt; #include &lt;conio.h&gt; #include &lt;winbio.h&gt; //------------------------------------------------------------------------ // Forward declarations. // HRESULT EnrollSysPoolWithCallback( BOOL bCancel, BOOL bDiscard, WINBIO_BIOMETRIC_SUBTYPE subFactor); VOID CALLBACK EnrollCaptureCallback( __in_opt PVOID EnrollCallbackContext, __in HRESULT OperationStatus, __in WINBIO_REJECT_DETAIL RejectDetail); typedef struct _ENROLL_CALLBACK_CONTEXT { WINBIO_SESSION_HANDLE SessionHandle; WINBIO_UNIT_ID UnitId; WINBIO_BIOMETRIC_SUBTYPE SubFactor; } ENROLL_CALLBACK_CONTEXT, *PENROLL_CALLBACK_CONTEXT; //------------------------------------------------------------------------ int wmain() { HRESULT hr = S_OK; hr = EnrollSysPoolWithCallback( FALSE, FALSE, WINBIO_ANSI_381_POS_RH_INDEX_FINGER); return 0; } //------------------------------------------------------------------------ // The following function enrolls a user's fingerprint in the system pool. // The function calls WinBioEnrollCaptureWithCallback and waits for the // asynchronous enrollment process to be completed or canceled. // HRESULT EnrollSysPoolWithCallback( BOOL bCancel, BOOL bDiscard, WINBIO_BIOMETRIC_SUBTYPE subFactor) { // Declare variables HRESULT hr = S_OK; WINBIO_IDENTITY identity = {0}; WINBIO_SESSION_HANDLE sessionHandle = NULL; WINBIO_UNIT_ID unitId = 0; BOOLEAN isNewTemplate = TRUE; ENROLL_CALLBACK_CONTEXT callbackContext = {0}; // Connect to the system pool. hr = WinBioOpenSession( WINBIO_TYPE_FINGERPRINT, // Service provider WINBIO_POOL_SYSTEM, // Pool type WINBIO_FLAG_DEFAULT, // Configuration and access NULL, // Array of biometric unit IDs 0, // Count of biometric unit IDs NULL, // Database ID &amp;sessionHandle // [out] Session handle ); if (FAILED(hr)) { wprintf_s(L"\n WinBioEnumBiometricUnits failed. "); wprintf_s(L"hr = 0x%x\n", hr); goto e_Exit; } // Locate the sensor. wprintf_s(L"\n Swipe your finger to locate the sensor...\n"); hr = WinBioLocateSensor( sessionHandle, &amp;unitId); if (FAILED(hr)) { wprintf_s(L"\n WinBioLocateSensor failed. hr = 0x%x\n", hr); goto e_Exit; } // Begin the enrollment sequence. hr = WinBioEnrollBegin( sessionHandle, // Handle to open biometric session subFactor, // Finger to create template for unitId // Biometric unit ID ); if (FAILED(hr)) { wprintf_s(L"\n WinBioEnrollBegin failed. hr = 0x%x\n", hr); goto e_Exit; } // Set up the custom callback context structure. callbackContext.SessionHandle = sessionHandle; callbackContext.UnitId = unitId; callbackContext.SubFactor = subFactor; // Call WinBioEnrollCaptureWithCallback. This is an asynchronous // method that returns immediately. hr = WinBioEnrollCaptureWithCallback( sessionHandle, // Handle to open biometric session EnrollCaptureCallback, // Callback function &amp;callbackContext // Pointer to the custom context ); if (FAILED(hr)) { wprintf_s(L"\n WinBioEnrollCaptureWithCallback failed. "); wprintf_s(L"hr = 0x%x\n", hr); goto e_Exit; } wprintf_s(L"\n Swipe the sensor with the appropriate finger...\n"); // Cancel the enrollment if the bCancel flag is set. if (bCancel) { wprintf_s(L"\n Starting CANCEL timer...\n"); Sleep( 7000 ); wprintf_s(L"\n Calling WinBioCancel\n"); hr = WinBioCancel( sessionHandle ); if (FAILED(hr)) { wprintf_s(L"\n WinBioCancel failed. hr = 0x%x\n", hr); goto e_Exit; } } // Wait for the asynchronous enrollment process to complete // or be canceled. hr = WinBioWait( sessionHandle ); if (FAILED(hr)) { wprintf_s(L"\n WinBioWait failed. hr = 0x%x\n", hr); } // Discard the enrollment if the bDiscard flag is set. // Commit the enrollment if the flag is not set. if (bDiscard) { wprintf_s(L"\n Discarding enrollment...\n"); hr = WinBioEnrollDiscard( sessionHandle ); if (FAILED(hr)) { wprintf_s(L"\n WinBioLocateSensor failed. "); wprintf_s(L"hr = 0x%x\n", hr); } goto e_Exit; } else { wprintf_s(L"\n Committing enrollment...\n"); hr = WinBioEnrollCommit( sessionHandle, // Handle to open biometric session &amp;identity, // WINBIO_IDENTITY object for the user &amp;isNewTemplate); // Is this a new template if (FAILED(hr)) { wprintf_s(L"\n WinBioEnrollCommit failed. hr = 0x%x\n", hr); goto e_Exit; } } e_Exit: if (sessionHandle != NULL) { WinBioCloseSession(sessionHandle); sessionHandle = NULL; } wprintf_s(L"\n Press any key to exit..."); _getch(); return hr; } //------------------------------------------------------------------------ // The following function is the callback for the Windows Biometric // Framework WinBioEnrollCaptureWithCallback() function. // VOID CALLBACK EnrollCaptureCallback( __in_opt PVOID EnrollCallbackContext, __in HRESULT OperationStatus, __in WINBIO_REJECT_DETAIL RejectDetail ) { // Declare variables. HRESULT hr = S_OK; static SIZE_T swipeCount = 1; PENROLL_CALLBACK_CONTEXT callbackContext = (PENROLL_CALLBACK_CONTEXT)EnrollCallbackContext; wprintf_s(L"\n EnrollCaptureCallback executing\n"); wprintf_s(L"\n Sample %d captured", swipeCount++); // The capture was not acceptable or the enrollment operation // failed. if (FAILED(OperationStatus)) { if (OperationStatus == WINBIO_E_BAD_CAPTURE) { wprintf_s(L"\n Bad capture; reason: %d\n", RejectDetail); wprintf_s(L"\n Swipe your finger to capture another sample.\n"); // Try again. hr = WinBioEnrollCaptureWithCallback( callbackContext-&gt;SessionHandle, // Open session handle EnrollCaptureCallback, // Callback function EnrollCallbackContext // Callback context ); if (FAILED(hr)) { wprintf_s(L"WinBioEnrollCaptureWithCallback failed."); wprintf_s(L"hr = 0x%x\n", hr); } } else { wprintf_s(L"EnrollCaptureCallback failed."); wprintf_s(L"OperationStatus = 0x%x\n", OperationStatus); } goto e_Exit; } // The enrollment operation requires more fingerprint swipes. // This is normal and depends on your hardware. Typically, at least // three swipes are required. if (OperationStatus == WINBIO_I_MORE_DATA) { wprintf_s(L"\n More data required."); wprintf_s(L"\n Swipe your finger on the sensor again."); hr = WinBioEnrollCaptureWithCallback( callbackContext-&gt;SessionHandle, EnrollCaptureCallback, EnrollCallbackContext ); if (FAILED(hr)) { wprintf_s(L"WinBioEnrollCaptureWithCallback failed. "); wprintf_s(L"hr = 0x%x\n", hr); } goto e_Exit; } wprintf_s(L"\n Template completed\n"); e_Exit: return; }</code>
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winbio/nc-winbio-pwinbio_enroll_capture_callback
// PWINBIO_ENROLL_CAPTURE_CALLBACK PwinbioEnrollCaptureCallback; void PwinbioEnrollCaptureCallback( PVOID EnrollCallbackContext,
// HRESULT OperationStatus, WINBIO_REJECT_DETAIL RejectDetail ) {...}
[UnmanagedFunctionPointer(CallingConvention.Winapi)]
[PInvokeData("winbio.h", MSDNShortId = "NC:winbio.PWINBIO_ENROLL_CAPTURE_CALLBACK")]
public delegate void PWINBIO_ENROLL_CAPTURE_CALLBACK([In, Optional] IntPtr EnrollCallbackContext, [In] HRESULT OperationStatus, WINBIO_REJECT_DETAIL RejectDetail);
/// <summary>
/// Called by the Windows Biometric Framework to return results from the asynchronous WinBioRegisterEventMonitor function. The
/// client application must implement this function.
/// </summary>
/// <param name="EventCallbackContext">
/// Pointer to a buffer defined by the application and passed to the EventCallbackContext parameter of the
/// WinBioRegisterEventMonitor function. The buffer is not modified by the framework or the biometric unit. Your application can use
/// the data to help it determine what actions to perform or to maintain additional information about the biometric capture.
/// </param>
/// <param name="OperationStatus">Error code returned by the capture operation.</param>
/// <param name="Event">Pointer to a WINBIO_EVENT value. For more information, see WINBIO_EVENT Constants.</param>
/// <returns>None</returns>
// https://docs.microsoft.com/en-us/windows/win32/api/winbio/nc-winbio-pwinbio_event_callback PWINBIO_EVENT_CALLBACK
// PwinbioEventCallback; void PwinbioEventCallback( PVOID EventCallbackContext, HRESULT OperationStatus, PWINBIO_EVENT Event ) {...}
[UnmanagedFunctionPointer(CallingConvention.Winapi)]
[PInvokeData("winbio.h", MSDNShortId = "NC:winbio.PWINBIO_EVENT_CALLBACK")]
public delegate void PWINBIO_EVENT_CALLBACK([In, Optional] IntPtr EventCallbackContext, [In] HRESULT OperationStatus, in WINBIO_EVENT Event);
/// <summary>
/// <para>
/// The <c>PWINBIO_IDENTIFY_CALLBACK</c> function is called by the Windows Biometric Framework to return results from the
/// asynchronous WinBioIdentifyWithCallback function. The client application must implement this function.
/// </para>
/// <para>
/// <c>Important</c> We recommend that, beginning with Windows 8, you no longer use the <c>PWINBIO_IDENTIFY_CALLBACK</c>/
/// <c>WinBioIdentifyWithCallback</c> combination. Instead, do the following:
/// </para>
/// </summary>
/// <param name="IdentifyCallbackContext">
/// Pointer to a buffer defined by the application and passed to the IdentifyCallbackContext parameter of the
/// WinBioIdentifyWithCallback function. The buffer is not modified by the framework or the biometric unit. Your application can use
/// the data to help it determine what actions to perform or to maintain additional information about the biometric capture.
/// </param>
/// <param name="OperationStatus">Error code returned by the capture operation.</param>
/// <param name="UnitId">Biometric unit ID number.</param>
/// <param name="Identity">A WINBIO_IDENTITY structure that receives the GUID or SID of the user providing the biometric sample.</param>
/// <param name="SubFactor">
/// A <c>WINBIO_BIOMETRIC_SUBTYPE</c> value that receives the sub-factor associated with the biometric sample. See the Remarks
/// section for more details.
/// </param>
/// <param name="RejectDetail">
/// Additional information about the failure, if any, to perform the operation. For more information, see Remarks.
/// </param>
/// <returns>None</returns>
/// <remarks>
/// <para>
/// Currently, the Windows Biometric Framework supports only fingerprint readers. Therefore, if an operation fails and returns
/// additional information in a <c>WINBIO_REJECT_DETAIL</c> constant, it will be one of the following values:
/// </para>
/// <list type="bullet">
/// <item>
/// <term>WINBIO_FP_TOO_HIGH</term>
/// </item>
/// <item>
/// <term>WINBIO_FP_TOO_LOW</term>
/// </item>
/// <item>
/// <term>WINBIO_FP_TOO_LEFT</term>
/// </item>
/// <item>
/// <term>WINBIO_FP_TOO_RIGHT</term>
/// </item>
/// <item>
/// <term>WINBIO_FP_TOO_FAST</term>
/// </item>
/// <item>
/// <term>WINBIO_FP_TOO_SLOW</term>
/// </item>
/// <item>
/// <term>WINBIO_FP_POOR_QUALITY</term>
/// </item>
/// <item>
/// <term>WINBIO_FP_TOO_SKEWED</term>
/// </item>
/// <item>
/// <term>WINBIO_FP_TOO_SHORT</term>
/// </item>
/// <item>
/// <term>WINBIO_FP_MERGE_FAILURE</term>
/// </item>
/// </list>
/// <para>Examples</para>
/// <para>
/// The following code example calls WinBioIdentifyWithCallback to identify a user from a biometric scan.
/// <c>WinBioIdentifyWithCallback</c> is an asynchronous function that configures the biometric subsystem to process biometric input
/// on another thread. Output from the biometric subsystem is then sent to a custom callback function named IdentifyCallback. Link
/// to the Winbio.lib static library and include the following header files:
/// </para>
/// <list type="bullet">
/// <item>
/// <term>Windows.h</term>
/// </item>
/// <item>
/// <term>Stdio.h</term>
/// </item>
/// <item>
/// <term>Conio.h</term>
/// </item>
/// <item>
/// <term>Winbio.h</term>
/// </item>
/// </list>
/// <para>
/// <code>HRESULT IdentifyWithCallback(BOOL bCancel) { // Declare variables. HRESULT hr = S_OK; WINBIO_SESSION_HANDLE sessionHandle = NULL; // Connect to the system pool. hr = WinBioOpenSession( WINBIO_TYPE_FINGERPRINT, // Service provider WINBIO_POOL_SYSTEM, // Pool type WINBIO_FLAG_DEFAULT, // Configuration and access NULL, // Array of biometric unit IDs 0, // Count of biometric unit IDs WINBIO_DB_DEFAULT, // Database ID &amp;sessionHandle // [out] Session handle ); if (FAILED(hr)) { wprintf_s(L"\n WinBioOpenSession failed. hr = 0x%x\n", hr); goto e_Exit; } // Call WinBioIdentifyWithCallback. The method is asynchronous // and returns immediately. wprintf_s(L"\n Calling WinBioIdentifyWithCallback"); wprintf_s(L"\n Swipe the sensor ...\n"); hr = WinBioIdentifyWithCallback( sessionHandle, // Open biometric session IdentifyCallback, // Callback function NULL // Optional context ); if (FAILED(hr)) { wprintf_s(L"\n WinBioIdentifyWithCallback failed. hr = 0x%x\n", hr); goto e_Exit; } // Cancel user identification if the bCancel flag is set. if (bCancel) { wprintf_s(L"\n Starting CANCEL timer...\n"); Sleep( 7000 ); wprintf_s(L"\n Calling WinBioCancel\n"); hr = WinBioCancel( sessionHandle ); if (FAILED(hr)) { wprintf_s(L"\n WinBioCancel failed. hr = 0x%x\n", hr); goto e_Exit; } } // Wait for the asynchronous identification process to complete // or be canceled. hr = WinBioWait( sessionHandle ); if (FAILED(hr)) { wprintf_s(L"\n WinBioWait failed. hr = 0x%x\n", hr); } e_Exit: if (sessionHandle != NULL) { wprintf_s(L"\n Closing the session.\n"); hr = WinBioCloseSession(sessionHandle); if (FAILED(hr)) { wprintf_s(L"\n WinBioCloseSession failed. hr = 0x%x\n", hr); } sessionHandle = NULL; } wprintf_s(L"\n Hit any key to exit..."); _getch(); return hr; } //------------------------------------------------------------------------ // The following function is the callback for WinBioIdentifyWithCallback. // The function filters the response from the biometric subsystem and // writes a result to the console window. // VOID CALLBACK IdentifyCallback( __in_opt PVOID IdentifyCallbackContext, __in HRESULT OperationStatus, __in WINBIO_UNIT_ID UnitId, __in WINBIO_IDENTITY *Identity, __in WINBIO_BIOMETRIC_SUBTYPE SubFactor, __in WINBIO_REJECT_DETAIL RejectDetail ) { UNREFERENCED_PARAMETER(IdentifyCallbackContext); UNREFERENCED_PARAMETER(Identity); wprintf_s(L"\n IdentifyCallback executing"); wprintf_s(L"\n Swipe processed for unit ID %d\n", UnitId); // The attempt to process the fingerprint failed. if (FAILED(OperationStatus)) { if (OperationStatus == WINBIO_E_UNKNOWN_ID) { wprintf_s(L"\n Unknown identity.\n"); } else if (OperationStatus == WINBIO_E_BAD_CAPTURE) { wprintf_s(L"\n Bad capture; reason: %d\n", RejectDetail); } else { wprintf_s(L"IdentifyCallback failed."); wprintf_s(L"OperationStatus = 0x%x\n", OperationStatus); } } // Processing succeeded and the finger swiped is written // to the console window. else { wprintf_s(L"\n The following finger was used:"); switch (SubFactor) { case WINBIO_SUBTYPE_NO_INFORMATION: wprintf_s(L"\n No information\n"); break; case WINBIO_ANSI_381_POS_RH_THUMB: wprintf_s(L"\n RH thumb\n"); break; case WINBIO_ANSI_381_POS_RH_INDEX_FINGER: wprintf_s(L"\n RH index finger\n"); break; case WINBIO_ANSI_381_POS_RH_MIDDLE_FINGER: wprintf_s(L"\n RH middle finger\n"); break; case WINBIO_ANSI_381_POS_RH_RING_FINGER: wprintf_s(L"\n RH ring finger\n"); break; case WINBIO_ANSI_381_POS_RH_LITTLE_FINGER: wprintf_s(L"\n RH little finger\n"); break; case WINBIO_ANSI_381_POS_LH_THUMB: wprintf_s(L"\n LH thumb\n"); break; case WINBIO_ANSI_381_POS_LH_INDEX_FINGER: wprintf_s(L"\n LH index finger\n"); break; case WINBIO_ANSI_381_POS_LH_MIDDLE_FINGER: wprintf_s(L"\n LH middle finger\n"); break; case WINBIO_ANSI_381_POS_LH_RING_FINGER: wprintf_s(L"\n LH ring finger\n"); break; case WINBIO_ANSI_381_POS_LH_LITTLE_FINGER: wprintf_s(L"\n LH little finger\n"); break; case WINBIO_SUBTYPE_ANY: wprintf_s(L"\n Any finger\n"); break; default: break; } } }</code>
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winbio/nc-winbio-pwinbio_identify_callback PWINBIO_IDENTIFY_CALLBACK
// PwinbioIdentifyCallback; void PwinbioIdentifyCallback( PVOID IdentifyCallbackContext, HRESULT OperationStatus, WINBIO_UNIT_ID
// UnitId, WINBIO_IDENTITY *Identity, WINBIO_BIOMETRIC_SUBTYPE SubFactor, WINBIO_REJECT_DETAIL RejectDetail ) {...}
[UnmanagedFunctionPointer(CallingConvention.Winapi)]
[PInvokeData("winbio.h", MSDNShortId = "NC:winbio.PWINBIO_IDENTIFY_CALLBACK")]
public delegate void PWINBIO_IDENTIFY_CALLBACK([In, Optional] IntPtr IdentifyCallbackContext, HRESULT OperationStatus, uint UnitId, in WINBIO_IDENTITY Identity, WINBIO_BIOMETRIC_SUBTYPE SubFactor, WINBIO_REJECT_DETAIL RejectDetail);
/// <summary>
/// <para>
/// Called by the Windows Biometric Framework to return results from the asynchronous WinBioLocateSensorWithCallback function. The
/// client application must implement this function.
/// </para>
/// <para>
/// <c>Important</c> We recommend that, beginning with Windows 8, you no longer use the <c>PWINBIO_LOCATE_SENSOR_CALLBACK</c>/
/// <c>WinBioLocateSensorWithCallback</c> combination. Instead, do the following:
/// </para>
/// </summary>
/// <param name="LocateCallbackContext">
/// Pointer to a buffer defined by the application and passed to the LocateCallbackContext parameter of the
/// WinBioLocateSensorWithCallback function. The buffer is not modified by the framework or the biometric unit. Your application can
/// use the data to help it determine what actions to perform or to maintain additional information about the biometric capture.
/// </param>
/// <param name="OperationStatus">Error code returned by the capture operation.</param>
/// <param name="UnitId">Biometric unit ID number.</param>
/// <returns>None</returns>
// https://docs.microsoft.com/en-us/windows/win32/api/winbio/nc-winbio-pwinbio_locate_sensor_callback PWINBIO_LOCATE_SENSOR_CALLBACK
// PwinbioLocateSensorCallback; void PwinbioLocateSensorCallback( PVOID LocateCallbackContext, HRESULT OperationStatus,
// WINBIO_UNIT_ID UnitId ) {...}
[UnmanagedFunctionPointer(CallingConvention.Winapi)]
[PInvokeData("winbio.h", MSDNShortId = "NC:winbio.PWINBIO_LOCATE_SENSOR_CALLBACK")]
public delegate void PWINBIO_LOCATE_SENSOR_CALLBACK([In, Optional] IntPtr LocateCallbackContext, HRESULT OperationStatus, uint UnitId);
/// <summary>
/// <para>
/// Called by the Windows Biometric Framework to return results from the asynchronous WinBioVerifyWithCallback function. The client
/// application must implement this function.
/// </para>
/// <para>
/// <c>Important</c> We recommend that, beginning with Windows 8, you no longer use the <c>PWINBIO_VERIFY_CALLBACK</c>/
/// <c>WinBioVerifyWithCallback</c> combination. Instead, do the following:
/// </para>
/// </summary>
/// <param name="VerifyCallbackContext">
/// Pointer to a buffer defined by the application and passed to the VerifyCallbackContext parameter of the WinBioVerifyWithCallback
/// function. The buffer is not modified by the framework or the biometric unit. Your application can use the data to help it
/// determine what actions to perform or to maintain additional information about the biometric capture.
/// </param>
/// <param name="OperationStatus">Error code returned by the capture operation.</param>
/// <param name="UnitId">Biometric unit ID number.</param>
/// <param name="Match">
/// A Boolean value that specifies whether the captured sample matched the user identity specified by the Identity parameter.
/// </param>
/// <param name="RejectDetail">
/// Additional information about the failure, if any, to perform the operation. For more information, see Remarks.
/// </param>
/// <returns>None</returns>
/// <remarks>
/// <para>
/// Currently, the Windows Biometric Framework supports only fingerprint readers. Therefore, if an operation fails and returns
/// additional information in a <c>WINBIO_REJECT_DETAIL</c> constant, it will be one of the following values:
/// </para>
/// <list type="bullet">
/// <item>
/// <term>WINBIO_FP_TOO_HIGH</term>
/// </item>
/// <item>
/// <term>WINBIO_FP_TOO_LOW</term>
/// </item>
/// <item>
/// <term>WINBIO_FP_TOO_LEFT</term>
/// </item>
/// <item>
/// <term>WINBIO_FP_TOO_RIGHT</term>
/// </item>
/// <item>
/// <term>WINBIO_FP_TOO_FAST</term>
/// </item>
/// <item>
/// <term>WINBIO_FP_TOO_SLOW</term>
/// </item>
/// <item>
/// <term>WINBIO_FP_POOR_QUALITY</term>
/// </item>
/// <item>
/// <term>WINBIO_FP_TOO_SKEWED</term>
/// </item>
/// <item>
/// <term>WINBIO_FP_TOO_SHORT</term>
/// </item>
/// <item>
/// <term>WINBIO_FP_MERGE_FAILURE</term>
/// </item>
/// </list>
/// <para>Examples</para>
/// <para>
/// The following function calls WinBioVerifyWithCallback to asynchronously determine whether a biometric sample matches the logged
/// on identity of the current user. The callback routine, VerifyCallback, and a helper function, GetCurrentUserIdentity, are also
/// included. Link to the Winbio.lib static library and include the following header files:
/// </para>
/// <list type="bullet">
/// <item>
/// <term>Windows.h</term>
/// </item>
/// <item>
/// <term>Stdio.h</term>
/// </item>
/// <item>
/// <term>Conio.h</term>
/// </item>
/// <item>
/// <term>Winbio.h</term>
/// </item>
/// </list>
/// <para>
/// <code>HRESULT VerifyWithCallback(BOOL bCancel, WINBIO_BIOMETRIC_SUBTYPE subFactor) { // Declare variables. HRESULT hr = S_OK; WINBIO_SESSION_HANDLE sessionHandle = NULL; WINBIO_UNIT_ID unitId = 0; WINBIO_REJECT_DETAIL rejectDetail = 0; WINBIO_IDENTITY identity = {0}; // Find the identity of the user. hr = GetCurrentUserIdentity( &amp;identity ); if (FAILED(hr)) { wprintf_s(L"\n User identity not found. hr = 0x%x\n", hr); goto e_Exit; } // Connect to the system pool. hr = WinBioOpenSession( WINBIO_TYPE_FINGERPRINT, // Service provider WINBIO_POOL_SYSTEM, // Pool type WINBIO_FLAG_DEFAULT, // Configuration and access NULL, // Array of biometric unit IDs 0, // Count of biometric unit IDs NULL, // Database ID &amp;sessionHandle // [out] Session handle ); if (FAILED(hr)) { wprintf_s(L"\n WinBioOpenSession failed. hr = 0x%x\n", hr); goto e_Exit; } // Verify a biometric sample asynchronously. wprintf_s(L"\n Calling WinBioVerifyWithCallback.\n"); hr = WinBioVerifyWithCallback( sessionHandle, // Open session handle &amp;identity, // User SID or GUID subFactor, // Sample sub-factor VerifyCallback, // Callback function NULL // Optional context ); if (FAILED(hr)) { wprintf_s(L"\n WinBioVerifyWithCallback failed. hr = 0x%x\n", hr); goto e_Exit; } wprintf_s(L"\n Swipe the sensor ...\n"); // Cancel the identification if the bCancel flag is set. if (bCancel) { wprintf_s(L"\n Starting CANCEL timer...\n"); Sleep( 7000 ); wprintf_s(L"\n Calling WinBioCancel\n"); hr = WinBioCancel( sessionHandle ); if (FAILED(hr)) { wprintf_s(L"\n WinBioCancel failed. hr = 0x%x\n", hr); goto e_Exit; } } // Wait for the asynchronous identification process to complete // or be canceled. hr = WinBioWait( sessionHandle ); if (FAILED(hr)) { wprintf_s(L"\n WinBioWait failed. hr = 0x%x\n", hr); } e_Exit: if (sessionHandle != NULL) { WinBioCloseSession(sessionHandle); sessionHandle = NULL; } wprintf_s(L"\n Hit any key to continue..."); _getch(); return hr; } //------------------------------------------------------------------------ // The following function is the callback for WinBioVerifyWithCallback. // The function filters the response from the biometric subsystem and // writes a result to the console window. // VOID CALLBACK VerifyCallback( __in_opt PVOID VerifyCallbackContext, __in HRESULT OperationStatus, __in WINBIO_UNIT_ID UnitId, __in BOOLEAN Match, __in WINBIO_REJECT_DETAIL RejectDetail ) { UNREFERENCED_PARAMETER(VerifyCallbackContext); UNREFERENCED_PARAMETER(Match); wprintf_s(L"\n VerifyCallback executing"); wprintf_s(L"\n Swipe processed for unit ID %d\n", UnitId); // The identity could not be verified. if (FAILED(OperationStatus)) { wprintf_s(L"\n Verification failed for the following reason:"); if (OperationStatus == WINBIO_E_NO_MATCH) { wprintf_s(L"\n No match.\n"); } else if (OperationStatus == WINBIO_E_BAD_CAPTURE) { wprintf_s(L"\n Bad capture.\n "); wprintf_s(L"\n Bad capture; reason: %d\n", RejectDetail); } else { wprintf_s(L"VerifyCallback failed."); wprintf_s(L"OperationStatus = 0x%x\n", OperationStatus); } goto e_Exit; } // The user identity was verified. wprintf_s(L"\n Fingerprint verified:\n"); e_Exit: return; } //------------------------------------------------------------------------ // The following function retrieves the identity of the current user. // This is a helper function and is not part of the Windows Biometric // Framework API. // HRESULT GetCurrentUserIdentity(__inout PWINBIO_IDENTITY Identity) { // Declare variables. HRESULT hr = S_OK; HANDLE tokenHandle = NULL; DWORD bytesReturned = 0; struct{ TOKEN_USER tokenUser; BYTE buffer[SECURITY_MAX_SID_SIZE]; } tokenInfoBuffer; // Zero the input identity and specify the type. ZeroMemory( Identity, sizeof(WINBIO_IDENTITY)); Identity-&gt;Type = WINBIO_ID_TYPE_NULL; // Open the access token associated with the // current process if (!OpenProcessToken( GetCurrentProcess(), // Process handle TOKEN_READ, // Read access only &amp;tokenHandle)) // Access token handle { DWORD win32Status = GetLastError(); wprintf_s(L"Cannot open token handle: %d\n", win32Status); hr = HRESULT_FROM_WIN32(win32Status); goto e_Exit; } // Zero the tokenInfoBuffer structure. ZeroMemory(&amp;tokenInfoBuffer, sizeof(tokenInfoBuffer)); // Retrieve information about the access token. In this case, // retrieve a SID. if (!GetTokenInformation( tokenHandle, // Access token handle TokenUser, // User for the token &amp;tokenInfoBuffer.tokenUser, // Buffer to fill sizeof(tokenInfoBuffer), // Size of the buffer &amp;bytesReturned)) // Size needed { DWORD win32Status = GetLastError(); wprintf_s(L"Cannot query token information: %d\n", win32Status); hr = HRESULT_FROM_WIN32(win32Status); goto e_Exit; } // Copy the SID from the tokenInfoBuffer structure to the // WINBIO_IDENTITY structure. CopySid( SECURITY_MAX_SID_SIZE, Identity-&gt;Value.AccountSid.Data, tokenInfoBuffer.tokenUser.User.Sid ); // Specify the size of the SID and assign WINBIO_ID_TYPE_SID // to the type member of the WINBIO_IDENTITY structure. Identity-&gt;Value.AccountSid.Size = GetLengthSid(tokenInfoBuffer.tokenUser.User.Sid); Identity-&gt;Type = WINBIO_ID_TYPE_SID; e_Exit: if (tokenHandle != NULL) { CloseHandle(tokenHandle); } return hr; }</code>
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winbio/nc-winbio-pwinbio_verify_callback PWINBIO_VERIFY_CALLBACK
// PwinbioVerifyCallback; void PwinbioVerifyCallback( PVOID VerifyCallbackContext, HRESULT OperationStatus, WINBIO_UNIT_ID UnitId,
// BOOLEAN Match, WINBIO_REJECT_DETAIL RejectDetail ) {...}
[UnmanagedFunctionPointer(CallingConvention.Winapi)]
[PInvokeData("winbio.h", MSDNShortId = "NC:winbio.PWINBIO_VERIFY_CALLBACK")]
public delegate void PWINBIO_VERIFY_CALLBACK([In, Optional] IntPtr VerifyCallbackContext, HRESULT OperationStatus, uint UnitId, [MarshalAs(UnmanagedType.U1)] bool Match, WINBIO_REJECT_DETAIL RejectDetail);
private delegate HRESULT EnumFunc(WINBIO_BIOMETRIC_TYPE Factor, out SafeWinBioMemory array, out SizeT count);
/// <summary>
/// Defines constants that specify how completion notifications for asynchronous operations are to be delivered to the client
/// application. This enumeration is used by the WinBioAsyncOpenFramework and WinBioAsyncOpenSession functions.
/// </summary>
[PInvokeData("winbio.h")]
public enum WINBIO_ASYNC_NOTIFICATION_METHOD
{
/// <summary>The operation is synchronous.</summary>
WINBIO_ASYNC_NOTIFY_NONE = 0, // Operation is synchronous
/// <summary>The client-implemented PWINBIO_ASYNC_COMPLETION_CALLBACK function is called by the framework.</summary>
WINBIO_ASYNC_NOTIFY_CALLBACK, // Caller receives a new-style callback
/// <summary>The framework sends completion notices to the client application window message queue.</summary>
WINBIO_ASYNC_NOTIFY_MESSAGE, // Caller receives a window message
}
/// <summary>Acquires window focus.</summary>
/// <returns>
/// <para>
/// If the function succeeds, it returns <c>S_OK</c>. If the function fails, it returns an <c>HRESULT</c> value that indicates the
/// error. Possible values include, but are not limited to, those in the following table. For a list of common error codes, see
/// Common HRESULT Values.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>E_ACCESSDENIED</term>
/// <term>The calling process must be running under the Local System account.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>The Windows Biometric Framework uses window focus to arbitrate among multiple sessions connected to the system pool.</para>
/// <para>
/// The manner in which you acquire focus depends on the type of application you are writing. For example, if you are creating a GUI
/// application you can implement a message handler that captures a WM_ACTIVATE, WM_SETFOCUS, or other appropriate message. If you
/// are writing a CUI application, call <c>GetConsoleWindow</c> to retrieve a handle to the console window and pass that handle to
/// the <c>SetForegroundWindow</c> function to force the console window into the foreground and assign it focus. If your application
/// is running in a detached process or is a Windows service and has no window, use <c>WinBioAcquireFocus</c> and WinBioReleaseFocus
/// to manually control focus.
/// </para>
/// <para>The following list summarizes the major points to consider before calling this function.</para>
/// <list type="bullet">
/// <item>
/// <term>The calling process must be running under the Local System account.</term>
/// </item>
/// <item>
/// <term>
/// A process that directly displays a user interface should not call this function. See the preceding discussion to determine how
/// to acquire focus for GUI and CUI applications.
/// </term>
/// </item>
/// <item>
/// <term>
/// Only a service or a detached process that does not directly display a user interface during biometric API calls should call this function.
/// </term>
/// </item>
/// <item>
/// <term>If the function succeeds, you must call WinBioReleaseFocus to release focus.</term>
/// </item>
/// </list>
/// <para>If you do not acquire focus when calling the following functions, they will behave in unexpected ways:</para>
/// <list type="bullet">
/// <item>
/// <term>WinBioEnrollBegin</term>
/// </item>
/// <item>
/// <term>WinBioEnrollCapture</term>
/// </item>
/// <item>
/// <term>WinBioEnrollCaptureWithCallback</term>
/// </item>
/// </list>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winbio/nf-winbio-winbioacquirefocus HRESULT WinBioAcquireFocus();
[DllImport(Lib_Winbio, SetLastError = false, ExactSpelling = true)]
[PInvokeData("winbio.h", MSDNShortId = "NF:winbio.WinBioAcquireFocus")]
public static extern HRESULT WinBioAcquireFocus();
/// <summary>
/// Asynchronously enumerates all attached biometric units that match the input factor type. For a synchronous version of this
/// function, see WinBioEnumBiometricUnits. Starting with Windows 10, build 1607, this function is available to use with a mobile image.
/// </summary>
/// <param name="FrameworkHandle">Handle to the framework session opened by calling WinBioAsyncOpenFramework.</param>
/// <param name="Factor">
/// A bitmask of WINBIO_BIOMETRIC_TYPE flags that specifies the biometric unit types to be enumerated. Only
/// <c>WINBIO_TYPE_FINGERPRINT</c> is currently supported.
/// </param>
/// <returns>
/// <para>
/// The function returns an <c>HRESULT</c> indicating success or failure. Note that success indicates only that the arguments were
/// valid. Failures encountered during the execution of the operation will be returned asynchronously to a WINBIO_ASYNC_RESULT
/// structure using the notification method specified in the call to WinBioAsyncOpenFramework.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>E_HANDLE</term>
/// <term>You must set the FrameworkHandle argument.</term>
/// </item>
/// <item>
/// <term>E_INVALIDARG</term>
/// <term>The bitmask contained in the Factor parameter contains one or more an invalid type bits.</term>
/// </item>
/// <item>
/// <term>E_OUTOFMEMORY</term>
/// <term>There was insufficient memory to complete the request.</term>
/// </item>
/// <item>
/// <term>WINBIO_E_DISABLED</term>
/// <term>Current administrative policy prohibits use of the Windows Biometric Framework API.</term>
/// </item>
/// <item>
/// <term>WINBIO_E_INCORRECT_SESSION_TYPE</term>
/// <term>The FrameworkHandle argument must represent an asynchronous framework session.</term>
/// </item>
/// <item>
/// <term>WINBIO_E_SESSION_HANDLE_CLOSED</term>
/// <term>The session handle has been marked for closure.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// The <c>WinBioAsyncEnumBiometricUnits</c> function uses a handle to the framework session opened by calling
/// WinBioAsyncOpenFramework. The framework allocates a WINBIO_ASYNC_RESULT structure and uses it to return information about
/// operation success or failure. If the enumeration operation is successful, the framework returns an array of schemas that include
/// information about each enumerated biometric unit. If the operation is unsuccessful, the framework uses the
/// <c>WINBIO_ASYNC_RESULT</c> structure to return error information. The structure is returned to the application callback or to
/// the application message queue, depending on the value you set in the NotificationMethod parameter of the
/// <c>WinBioAsyncOpenFramework</c> function.
/// </para>
/// <list type="bullet">
/// <item>
/// <term>
/// If you choose to receive completion notices by using a callback, you must implement a PWINBIO_ASYNC_COMPLETION_CALLBACK function
/// and set the NotificationMethod parameter to <c>WINBIO_ASYNC_NOTIFY_CALLBACK</c>.
/// </term>
/// </item>
/// <item>
/// <term>
/// If you choose to receive completion notices by using the application message queue, you must set the NotificationMethod
/// parameter to <c>WINBIO_ASYNC_NOTIFY_MESSAGE</c>. The framework returns a WINBIO_ASYNC_RESULT pointer to the <c>LPARAM</c> field
/// of the window message.
/// </term>
/// </item>
/// </list>
/// <para>
/// The array of schemas is returned in an <c>EnumBiometricUnits</c> structure nested inside the WINBIO_ASYNC_RESULT structure. You
/// must call WinBioFree to release the <c>WINBIO_ASYNC_RESULT</c> structure after you have finished using it.
/// </para>
/// <para>Calling <c>WinBioAsyncEnumBiometricUnits</c> causes a single notification to be sent to the client application.</para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winbio/nf-winbio-winbioasyncenumbiometricunits HRESULT
// WinBioAsyncEnumBiometricUnits( WINBIO_FRAMEWORK_HANDLE FrameworkHandle, WINBIO_BIOMETRIC_TYPE Factor );
[DllImport(Lib_Winbio, SetLastError = false, ExactSpelling = true)]
[PInvokeData("winbio.h", MSDNShortId = "NF:winbio.WinBioAsyncEnumBiometricUnits")]
public static extern HRESULT WinBioAsyncEnumBiometricUnits(WINBIO_FRAMEWORK_HANDLE FrameworkHandle, WINBIO_BIOMETRIC_TYPE Factor);
/// <summary>
/// Asynchronously enumerates all registered databases that match a specified type. For a synchronous version of this function, see WinBioEnumDatabases.
/// </summary>
/// <param name="FrameworkHandle">Handle to the framework session opened by calling WinBioAsyncOpenFramework.</param>
/// <param name="Factor">
/// A bitmask of WINBIO_BIOMETRIC_TYPE flags that specifies the biometric database types to be enumerated. Only
/// <c>WINBIO_TYPE_FINGERPRINT</c> is currently supported.
/// </param>
/// <returns>
/// <para>
/// The function returns an <c>HRESULT</c> indicating success or failure. Note that success indicates only that the function's
/// arguments were valid. Failures encountered during the execution of the operation will be returned asynchronously to a
/// WINBIO_ASYNC_RESULT structure using the notification method specified in the call to WinBioAsyncOpenFramework.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>E_HANDLE</term>
/// <term>You must set the FrameworkHandle argument.</term>
/// </item>
/// <item>
/// <term>E_INVALIDARG</term>
/// <term>The bitmask contained in the Factor parameter contains one or more an invalid type bits.</term>
/// </item>
/// <item>
/// <term>E_OUTOFMEMORY</term>
/// <term>There was insufficient memory to complete the request.</term>
/// </item>
/// <item>
/// <term>WINBIO_E_INCORRECT_SESSION_TYPE</term>
/// <term>The FrameworkHandle argument must represent an asynchronous framework session.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// The <c>WinBioAsyncEnumDatabases</c> function uses a handle to the framework session opened by calling WinBioAsyncOpenFramework.
/// The framework allocates a WINBIO_ASYNC_RESULT structure and uses it to return information about operation success or failure. If
/// the enumeration operation is successful, the framework returns an array of schemas that include information about each
/// enumerated database. If the operation is unsuccessful, the framework uses the <c>WINBIO_ASYNC_RESULT</c> structure to return
/// error information. The structure is returned to the application callback or to the application message queue, depending on the
/// value you set in the NotificationMethod parameter of the <c>WinBioAsyncOpenFramework</c> function.
/// </para>
/// <list type="bullet">
/// <item>
/// <term>
/// If you choose to receive completion notices by using a callback, you must implement a PWINBIO_ASYNC_COMPLETION_CALLBACK function
/// and set the NotificationMethod parameter to <c>WINBIO_ASYNC_NOTIFY_CALLBACK</c>.
/// </term>
/// </item>
/// <item>
/// <term>
/// If you choose to receive completion notices by using the application message queue, you must set the NotificationMethod
/// parameter to <c>WINBIO_ASYNC_NOTIFY_MESSAGE</c>. The framework returns a WINBIO_ASYNC_RESULT pointer to the <c>LPARAM</c> field
/// of the window message.
/// </term>
/// </item>
/// </list>
/// <para>
/// The array of schemas is returned in an <c>EnumDatabases</c> structure nested inside the WINBIO_ASYNC_RESULT structure. You must
/// call WinBioFree to release the <c>WINBIO_ASYNC_RESULT</c> structure after you have finished using it.
/// </para>
/// <para>Calling <c>WinBioAsyncEnumDatabases</c> causes a single notification to be sent to the client application.</para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winbio/nf-winbio-winbioasyncenumdatabases HRESULT WinBioAsyncEnumDatabases(
// WINBIO_FRAMEWORK_HANDLE FrameworkHandle, WINBIO_BIOMETRIC_TYPE Factor );
[DllImport(Lib_Winbio, SetLastError = false, ExactSpelling = true)]
[PInvokeData("winbio.h", MSDNShortId = "NF:winbio.WinBioAsyncEnumDatabases")]
public static extern HRESULT WinBioAsyncEnumDatabases(WINBIO_FRAMEWORK_HANDLE FrameworkHandle, WINBIO_BIOMETRIC_TYPE Factor);
/// <summary>
/// Asynchronously returns information about installed biometric service providers. Starting with Windows 10, build 1607, this
/// function is available to use with a mobile image. For a synchronous version of this function, see WinBioEnumServiceProviders.
/// </summary>
/// <param name="FrameworkHandle">Handle to the framework session opened by calling WinBioAsyncOpenFramework.</param>
/// <param name="Factor">
/// A bitmask of WINBIO_BIOMETRIC_TYPE flags that specifies the biometric service provider types to be enumerated. For Windows 8,
/// only <c>WINBIO_TYPE_FINGERPRINT</c> is supported.
/// </param>
/// <returns>
/// <para>
/// The function returns an <c>HRESULT</c> indicating success or failure. Note that success indicates only that the function's
/// arguments were valid. Failures encountered during the execution of the operation will be returned asynchronously to a
/// WINBIO_ASYNC_RESULT structure using the notification method specified in the call to WinBioAsyncOpenFramework.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>E_HANDLE</term>
/// <term>You must set the FrameworkHandle argument.</term>
/// </item>
/// <item>
/// <term>E_INVALIDARG</term>
/// <term>The bitmask contained in the Factor parameter contains one or more an invalid type bits.</term>
/// </item>
/// <item>
/// <term>E_OUTOFMEMORY</term>
/// <term>There was insufficient memory to complete the request.</term>
/// </item>
/// <item>
/// <term>WINBIO_E_INCORRECT_SESSION_TYPE</term>
/// <term>The FrameworkHandle argument must represent an asynchronous framework session.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// The <c>WinBioAsyncEnumServiceProviders</c> function uses a handle to the framework session opened by calling
/// WinBioAsyncOpenFramework. The framework allocates a WINBIO_ASYNC_RESULT structure and uses it to return information about
/// operation success or failure. If the enumeration operation is successful, the framework returns an array of schemas that include
/// information about each enumerated provider. If the operation is unsuccessful, the framework uses the <c>WINBIO_ASYNC_RESULT</c>
/// structure to return error information. The structure is returned to the application callback or to the application message
/// queue, depending on the value you set in the NotificationMethod parameter of the <c>WinBioAsyncOpenFramework</c> function.
/// </para>
/// <list type="bullet">
/// <item>
/// <term>
/// If you choose to receive completion notices by using a callback, you must implement a PWINBIO_ASYNC_COMPLETION_CALLBACK function
/// and set the NotificationMethod parameter to <c>WINBIO_ASYNC_NOTIFY_CALLBACK</c>.
/// </term>
/// </item>
/// <item>
/// <term>
/// If you choose to receive completion notices by using the application message queue, you must set the NotificationMethod
/// parameter to <c>WINBIO_ASYNC_NOTIFY_MESSAGE</c>. The framework returns a WINBIO_ASYNC_RESULT pointer to the <c>LPARAM</c> field
/// of the window message.
/// </term>
/// </item>
/// </list>
/// <para>
/// The array of schemas is returned in an <c>EnumServiceProviders</c> structure nested inside the WINBIO_ASYNC_RESULT structure.
/// You must call WinBioFree to release the <c>WINBIO_ASYNC_RESULT</c> structure after you have finished using it.
/// </para>
/// <para>Calling <c>WinBioAsyncEnumServiceProviders</c> causes a single notification to be sent to the client application.</para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winbio/nf-winbio-winbioasyncenumserviceproviders HRESULT
// WinBioAsyncEnumServiceProviders( WINBIO_FRAMEWORK_HANDLE FrameworkHandle, WINBIO_BIOMETRIC_TYPE Factor );
[DllImport(Lib_Winbio, SetLastError = false, ExactSpelling = true)]
[PInvokeData("winbio.h", MSDNShortId = "NF:winbio.WinBioAsyncEnumServiceProviders")]
public static extern HRESULT WinBioAsyncEnumServiceProviders(WINBIO_FRAMEWORK_HANDLE FrameworkHandle, WINBIO_BIOMETRIC_TYPE Factor);
/// <summary>
/// Starts an asynchronous monitor of changes to the biometric framework. Currently, the only monitored changes that are supported
/// occur when a biometric unit is attached to or detached from the computer.
/// </summary>
/// <param name="FrameworkHandle">Handle to the framework session opened by calling WinBioAsyncOpenFramework.</param>
/// <param name="ChangeTypes">
/// <para>
/// A bitmask of type <c>WINBIO_FRAMEWORK_CHANGE_TYPE</c> flags that indicates the types of events that should generate asynchronous
/// notifications. Beginning with Windows 8, the following flag is available:
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>WINBIO_FRAMEWORK_CHANGE_UNIT</term>
/// <term>A biometric unit has been attached to or detached from the computer.</term>
/// </item>
/// </list>
/// </param>
/// <returns>
/// <para>
/// The function returns an <c>HRESULT</c> indicating success or failure. Note that success indicates only that the function
/// arguments were valid. Failures encountered during the execution of the operation will be returned asynchronously to a
/// WINBIO_ASYNC_RESULT structure using the notification method specified in WinBioAsyncOpenFramework.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>E_HANDLE</term>
/// <term>You must set the FrameworkHandle argument.</term>
/// </item>
/// <item>
/// <term>E_INVALIDARG</term>
/// <term>
/// The bitmask contained in the ChangeTypes parameter contains one or more an invalid type bits. Currently, the only available
/// value is WINBIO_FRAMEWORK_CHANGE_UNIT.
/// </term>
/// </item>
/// <item>
/// <term>WINBIO_E_INCORRECT_SESSION_TYPE</term>
/// <term>The FrameworkHandle argument must represent an asynchronous framework session.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// Once started, this monitor will continue generating events until the client application calls WinBioCancel or
/// WinBioCloseFramework. Creating a monitor for <c>WINBIO_FRAMEWORK_CHANGE_UNIT</c> events will generate two types of asynchronous notifications:
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>WINBIO_OPERATION_UNIT_ARRIVAL</term>
/// <term>A biometric unit is attached.</term>
/// </item>
/// <item>
/// <term>WINBIO_OPERATION_UNIT_REMOVAL</term>
/// <term>A biometric unit is detached.</term>
/// </item>
/// </list>
/// <para>
/// The <c>WinBioAsyncMonitorFrameworkChanges</c> function uses a handle to the framework session opened by calling
/// WinBioAsyncOpenFramework. The framework allocates a WINBIO_ASYNC_RESULT structure and uses it to return information about
/// operation success or failure. If a biometric unit is attached to or detached from the computer, the framework sets the
/// <c>Operation</c> member of the structure. If a problem is encountered during the operation, the framework uses the
/// <c>WINBIO_ASYNC_RESULT</c> structure to return error information. The structure is returned to the application callback or to
/// the application message queue, depending on the value you set in the NotificationMethod parameter of the
/// <c>WinBioAsyncOpenFramework</c> function.
/// </para>
/// <list type="bullet">
/// <item>
/// <term>
/// If you choose to receive completion notices by using a callback, you must implement a PWINBIO_ASYNC_COMPLETION_CALLBACK function
/// and set the NotificationMethod parameter to <c>WINBIO_ASYNC_NOTIFY_CALLBACK</c>.
/// </term>
/// </item>
/// <item>
/// <term>
/// If you choose to receive completion notices by using the application message queue, you must set the NotificationMethod
/// parameter to <c>WINBIO_ASYNC_NOTIFY_MESSAGE</c>. The framework returns a WINBIO_ASYNC_RESULT pointer to the <c>LPARAM</c> field
/// of the window message.
/// </term>
/// </item>
/// </list>
/// <para>
/// Notifications are returned in an <c>EnumServiceProviders</c> structure nested inside the WINBIO_ASYNC_RESULT structure. You must
/// call WinBioFree to release the <c>WINBIO_ASYNC_RESULT</c> structure after you have finished using it.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winbio/nf-winbio-winbioasyncmonitorframeworkchanges HRESULT
// WinBioAsyncMonitorFrameworkChanges( WINBIO_FRAMEWORK_HANDLE FrameworkHandle, WINBIO_FRAMEWORK_CHANGE_TYPE ChangeTypes );
[DllImport(Lib_Winbio, SetLastError = false, ExactSpelling = true)]
[PInvokeData("winbio.h", MSDNShortId = "NF:winbio.WinBioAsyncMonitorFrameworkChanges")]
public static extern HRESULT WinBioAsyncMonitorFrameworkChanges(WINBIO_FRAMEWORK_HANDLE FrameworkHandle, WINBIO_FRAMEWORK_CHANGE_TYPE ChangeTypes);
/// <summary>
/// Opens a handle to the biometric framework. Starting with Windows 10, build 1607, this function is available to use with a mobile
/// image. You can use this handle to asynchronously enumerate biometric units, databases, and service providers and to receive
/// asynchronous notification when biometric units are attached to the computer or removed.
/// </summary>
/// <param name="NotificationMethod">
/// <para>
/// Specifies how completion notifications for asynchronous operations in this framework session are to be delivered to the client
/// application. This must be one of the following values.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>WINBIO_ASYNC_NOTIFY_CALLBACK</term>
/// <term>The framework invokes the callback function defined by the application.</term>
/// </item>
/// <item>
/// <term>WINBIO_ASYNC_NOTIFY_MESSAGE</term>
/// <term>The framework posts a window message to the application's message queue.</term>
/// </item>
/// </list>
/// </param>
/// <param name="TargetWindow">
/// Handle of the window that will receive the completion notices. This value is ignored unless the NotificationMethod parameter is
/// set to <c>WINBIO_ASYNC_NOTIFY_MESSAGE</c>.
/// </param>
/// <param name="MessageCode">
/// <para>
/// Window message code the framework must send to signify completion notices. This value is ignored unless the NotificationMethod
/// parameter is set to <c>WINBIO_ASYNC_NOTIFY_MESSAGE</c>. The value must be within the range WM_APP (0x8000) to 0xBFFF.
/// </para>
/// <para>
/// The Windows Biometric Framework sets the <c>LPARAM</c> value of the message to the address of the WINBIO_ASYNC_RESULT structure
/// that contains the results of the operation. You must call WinBioFree to release the structure after you have finished using it.
/// </para>
/// </param>
/// <param name="CallbackRoutine">
/// Address of the callback routine to be invoked for completion notices. This value is ignored unless the NotificationMethod
/// parameter is set to <c>WINBIO_ASYNC_NOTIFY_CALLBACK</c>.
/// </param>
/// <param name="UserData">
/// Address of a buffer supplied by the caller. The buffer is not modified by the framework or the biometric unit. It is returned in
/// the WINBIO_ASYNC_RESULT structure. Your application can use the data to help it determine what actions to perform upon receipt
/// of the completion notice or to maintain additional information about the requested operation.
/// </param>
/// <param name="AsynchronousOpen">
/// <para>
/// Specifies whether to block until the framework session has been opened. Specifying <c>FALSE</c> causes the process to block.
/// Specifying <c>TRUE</c> causes the session to be opened asynchronously.
/// </para>
/// <para>
/// If you specify <c>FALSE</c> to open the framework session synchronously, success or failure is returned to the caller directly
/// by this function in the <c>HRESULT</c> return value. If the session is opened successfully, the first asynchronous completion
/// event your application receives will be for an asynchronous operation requested after the framework has been open.
/// </para>
/// <para>
/// If you specify <c>TRUE</c> to open the framework session asynchronously, the first asynchronous completion notice received will
/// be for opening the framework. If the NotificationMethod parameter is set to <c>WINBIO_ASYNC_NOTIFY_CALLBACK</c>, operation
/// results are delivered to the WINBIO_ASYNC_RESULT structure in the callback function specified by the CallbackRoutine parameter.
/// If the NotificationMethod parameter is set to <c>WINBIO_ASYNC_NOTIFY_MESSAGE</c>, operation results are delivered to the
/// <c>WINBIO_ASYNC_RESULT</c> structure pointed to by the <c>LPARAM</c> field of the window message.
/// </para>
/// </param>
/// <param name="FrameworkHandle">
/// <para>If the function does not succeed, this parameter will be <c>NULL</c>.</para>
/// <para>If the session is opened synchronously and successfully, this parameter will contain a pointer to the session handle.</para>
/// <para>
/// If you specify that the session be opened asynchronously, this method returns immediately, the session handle will be
/// <c>NULL</c>, and you must examine the WINBIO_ASYNC_RESULT structure to determine whether the session was successfully opened.
/// </para>
/// </param>
/// <returns>
/// <para>
/// If the function succeeds, it returns <c>S_OK</c>. If the function fails, it returns an <c>HRESULT</c> value that indicates the
/// error. Possible values include, but are not limited to, those in the following table. For a list of common error codes, see
/// Common HRESULT Values.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>E_OUTOFMEMORY</term>
/// <term>There is not enough memory available to create the framework session.</term>
/// </item>
/// <item>
/// <term>E_INVALIDARG</term>
/// <term>
/// If you set the notification method to WINBIO_ASYNC_NOTIFY_MESSAGE, the TargetWindow parameter cannot be NULL or HWND_BROADCAST
/// and the MessageCode parameter cannot be zero (0).
/// </term>
/// </item>
/// <item>
/// <term>E_POINTER</term>
/// <term>
/// The FrameworkHandle parameter and the AsynchronousOpen parameter must be set. If you set the notification method to
/// WINBIO_ASYNC_NOTIFY_CALLBACK, you must also specify the address of a callback function in the CallbackRoutine parameter.
/// </term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// The framework handle returned by the <c>WinBioAsyncOpenFramework</c> function can be used to generate asynchronous completion
/// notifications for the following functions:
/// </para>
/// <list type="bullet">
/// <item>
/// <term>WinBioAsyncEnumBiometricUnits</term>
/// </item>
/// <item>
/// <term>WinBioAsyncEnumDatabases</term>
/// </item>
/// <item>
/// <term>WinBioAsyncEnumServiceProviders</term>
/// </item>
/// <item>
/// <term>WinBioAsyncMonitorFrameworkChanges</term>
/// </item>
/// </list>
/// <para>
/// The AsynchronousOpen parameter determines only whether the open operation will block. This parameter has no effect on the
/// completion behavior of subsequent calls that use the session handle.
/// </para>
/// <para>
/// If you set the AsynchronousOpen parameter to <c>TRUE</c>, this function will return <c>S_OK</c> as soon as it has performed an
/// initial validation of the arguments. Any errors detected beyond that point will be reported to the caller using the method
/// specified by the NotificationMethod parameter. That is, a successful return value indicates only that the
/// <c>WinBioAsyncOpenFramework</c> parameters were fine and not that the open operation succeeded. To determine whether the open
/// operation succeeded, you must examine the WINBIO_ASYNC_RESULT structure.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winbio/nf-winbio-winbioasyncopenframework HRESULT WinBioAsyncOpenFramework(
// WINBIO_ASYNC_NOTIFICATION_METHOD NotificationMethod, HWND TargetWindow, UINT MessageCode, PWINBIO_ASYNC_COMPLETION_CALLBACK
// CallbackRoutine, PVOID UserData, BOOL AsynchronousOpen, WINBIO_FRAMEWORK_HANDLE *FrameworkHandle );
[DllImport(Lib_Winbio, SetLastError = false, ExactSpelling = true, CallingConvention = CallingConvention.Winapi)]
[PInvokeData("winbio.h", MSDNShortId = "NF:winbio.WinBioAsyncOpenFramework")]
public static extern HRESULT WinBioAsyncOpenFramework(WINBIO_ASYNC_NOTIFICATION_METHOD NotificationMethod, [In, Optional] HWND TargetWindow, [In, Optional] uint MessageCode,
/*[In, Optional, MarshalAs(UnmanagedType.FunctionPtr)] PWINBIO_ASYNC_COMPLETION_CALLBACK*/ [In, Optional] IntPtr CallbackRoutine, [In, Optional] IntPtr UserData,
[MarshalAs(UnmanagedType.Bool)] bool AsynchronousOpen, out WINBIO_FRAMEWORK_HANDLE FrameworkHandle);
/// <summary>
/// <para>
/// Asynchronously connects to a biometric service provider and one or more biometric units. Starting with Windows 10, build 1607,
/// this function is available to use with a mobile image. If successful, the function returns a biometric session handle. Every
/// operation performed by using this handle will be completed asynchronously, including WinBioCloseSession, and the results will be
/// returned to the client application by using the method specified in the NotificationMethod parameter.
/// </para>
/// <para>For a synchronous version of this function, see WinBioOpenSession.</para>
/// </summary>
/// <param name="Factor">
/// A bitmask of WINBIO_BIOMETRIC_TYPE flags that specifies the biometric unit types to be enumerated. Only
/// <c>WINBIO_TYPE_FINGERPRINT</c> is currently supported.
/// </param>
/// <param name="PoolType">
/// <para>
/// A <c>ULONG</c> value that specifies the type of the biometric units that will be used in the session. This can be one of the
/// following values:
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>WINBIO_POOL_SYSTEM</term>
/// <term>The session connects to a shared collection of biometric units managed by the service provider.</term>
/// </item>
/// <item>
/// <term>WINBIO_POOL_PRIVATE</term>
/// <term>The session connects to a collection of biometric units that are managed by the caller.</term>
/// </item>
/// </list>
/// </param>
/// <param name="Flags">
/// <para>
/// A <c>ULONG</c> value that specifies biometric unit configuration and access characteristics for the new session. Configuration
/// flags specify the general configuration of units in the session. Access flags specify how the application will use the biometric
/// units. You must specify one configuration flag but you can combine that flag with any access flag.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>WINBIO_FLAG_DEFAULT</term>
/// <term>
/// Group: configuration The biometric units operate in the manner specified during installation. You must use this value when the
/// PoolType parameter is WINBIO_POOL_SYSTEM.
/// </term>
/// </item>
/// <item>
/// <term>WINBIO_FLAG_BASIC</term>
/// <term>
/// Group: configuration The biometric units operate only as basic capture devices. All processing, matching, and storage operations
/// is performed by software plug-ins.
/// </term>
/// </item>
/// <item>
/// <term>WINBIO_FLAG_ADVANCED</term>
/// <term>Group: configuration The biometric units use internal processing and storage capabilities.</term>
/// </item>
/// <item>
/// <term>WINBIO_FLAG_RAW</term>
/// <term>Group: access The client application captures raw biometric data using WinBioCaptureSample.</term>
/// </item>
/// <item>
/// <term>WINBIO_FLAG_MAINTENANCE</term>
/// <term>Group: access The client performs vendor-defined control operations on a biometric unit by calling WinBioControlUnitPrivileged.</term>
/// </item>
/// </list>
/// </param>
/// <param name="UnitArray">
/// Pointer to an array of biometric unit identifiers to be included in the session. You can call WinBioEnumBiometricUnits to
/// enumerate the biometric units. Set this value to <c>NULL</c> if the PoolType parameter is <c>WINBIO_POOL_SYSTEM</c>.
/// </param>
/// <param name="UnitCount">
/// A value that specifies the number of elements in the array pointed to by the UnitArray parameter. Set this value to zero if the
/// PoolType parameter is <c>WINBIO_POOL_SYSTEM</c>.
/// </param>
/// <param name="DatabaseId">
/// <para>
/// A value that specifies the database(s) to be used by the session. If the PoolType parameter is <c>WINBIO_POOL_PRIVATE</c>, you
/// must specify the GUID of an installed database. If the PoolType parameter is not <c>WINBIO_POOL_PRIVATE</c>, you can specify one
/// of the following common values.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>WINBIO_DB_DEFAULT</term>
/// <term>
/// Each biometric unit in the sensor pool uses the default database specified in the default biometric unit configuration. You must
/// specify this value if the PoolType parameter is WINBIO_POOL_SYSTEM. You cannot use this value if the PoolType parameter is WINBIO_POOL_PRIVATE
/// </term>
/// </item>
/// <item>
/// <term>WINBIO_DB_BOOTSTRAP</term>
/// <term>
/// You can specify this value to be used for scenarios prior to starting Windows. Typically, the database is part of the sensor
/// chip or is part of the BIOS and can only be used for template enrollment and deletion.
/// </term>
/// </item>
/// <item>
/// <term>WINBIO_DB_ONCHIP</term>
/// <term>The database is on the sensor chip and is available for enrollment and matching.</term>
/// </item>
/// </list>
/// </param>
/// <param name="NotificationMethod">
/// <para>
/// Specifies how completion notifications for asynchronous operations in this biometric session are to be delivered to the client
/// application. This must be one of the following values.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>WINBIO_ASYNC_NOTIFY_CALLBACK</term>
/// <term>The session invokes the callback function defined by the application.</term>
/// </item>
/// <item>
/// <term>WINBIO_ASYNC_NOTIFY_MESSAGE</term>
/// <term>The session posts a window message to the application's message queue.</term>
/// </item>
/// </list>
/// </param>
/// <param name="TargetWindow">
/// Handle of the window that will receive the completion notices. This value is ignored unless the NotificationMethod parameter is
/// set to <c>WINBIO_ASYNC_NOTIFY_MESSAGE</c>.
/// </param>
/// <param name="MessageCode">
/// <para>
/// Window message code the framework must send to signify completion notices. This value is ignored unless the NotificationMethod
/// parameter is set to <c>WINBIO_ASYNC_NOTIFY_MESSAGE</c>. The value must be within the range WM_APP(0x8000) to 0xBFFF.
/// </para>
/// <para>
/// The Windows Biometric Framework sets the <c>LPARAM</c> value of the message to the address of the WINBIO_ASYNC_RESULT structure
/// that contains the results of the operation. You must call WinBioFree to release the structure after you have finished using it.
/// </para>
/// </param>
/// <param name="CallbackRoutine">
/// Address of callback routine to be invoked when the operation started by using the session handle completes. This value is
/// ignored unless the NotificationMethod parameter is set to <c>WINBIO_ASYNC_NOTIFY_CALLBACK</c>.
/// </param>
/// <param name="UserData">
/// Address of a buffer supplied by the caller. The buffer is not modified by the framework or the biometric unit. It is returned in
/// the WINBIO_ASYNC_RESULT structure. Your application can use the data to help it determine what actions to perform upon receipt
/// of the completion notice or to maintain additional information about the requested operation.
/// </param>
/// <param name="AsynchronousOpen">
/// <para>
/// Specifies whether to block until the framework session has been opened. Specifying <c>FALSE</c> causes the process to block.
/// Specifying <c>TRUE</c> causes the session to be opened asynchronously.
/// </para>
/// <para>
/// If you specify <c>FALSE</c> to open the framework session synchronously, success or failure is returned to the caller directly
/// by this function in the <c>HRESULT</c> return value. If the session is opened successfully, the first asynchronous completion
/// event your application receives will be for an asynchronous operation requested after the framework has been open.
/// </para>
/// <para>
/// If you specify <c>TRUE</c> to open the framework session asynchronously, the first asynchronous completion notice received will
/// be for opening the framework. If the NotificationMethod parameter is set to <c>WINBIO_ASYNC_NOTIFY_CALLBACK</c>, operation
/// results are delivered to the WINBIO_ASYNC_RESULT structure in the callback function specified by the CallbackRoutine parameter.
/// If the NotificationMethod parameter is set to <c>WINBIO_ASYNC_NOTIFY_MESSAGE</c>, operation results are delivered to the
/// <c>WINBIO_ASYNC_RESULT</c> structure pointed to by the LPARAM field of the window message.
/// </para>
/// </param>
/// <param name="SessionHandle">
/// <para>If the function does not succeed, this parameter will be <c>NULL</c>.</para>
/// <para>If the session is opened synchronously and successfully, this parameter will contain a pointer to the session handle.</para>
/// <para>
/// If you specify that the session be opened asynchronously, this method returns immediately, the session handle will be
/// <c>NULL</c>, and you must examine the WINBIO_ASYNC_RESULT structure to determine whether the session was successfully opened.
/// </para>
/// </param>
/// <returns>
/// <para>
/// If the function succeeds, it returns <c>S_OK</c>. If the function fails, it returns an <c>HRESULT</c> value that indicates the
/// error. Possible values include, but are not limited to, those in the following table. For a list of common error codes, see
/// Common HRESULT Values.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>E_OUTOFMEMORY</term>
/// <term>There is not enough memory available to create the biometric session.</term>
/// </item>
/// <item>
/// <term>E_INVALIDARG</term>
/// <term>
/// If you set the notification method to WINBIO_ASYNC_NOTIFY_MESSAGE, the TargetWindow parameter cannot be NULL or HWND_BROADCAST
/// and the MessageCode parameter cannot be zero (0).
/// </term>
/// </item>
/// <item>
/// <term>E_POINTER</term>
/// <term>
/// The SessionHandle parameter and the AsynchronousOpen parameter must be set. If you set the notification method to
/// WINBIO_ASYNC_NOTIFY_CALLBACK, you must also specify the address of a callback function in the CallbackRoutine parameter.
/// </term>
/// </item>
/// <item>
/// <term>E_ACCESSDENIED</term>
/// <term>
/// The Flags parameter contains the WINBIO_FLAG_RAW or the WINBIO_FLAG_MAINTENANCE flag and the caller has not been granted either
/// access permission.
/// </term>
/// </item>
/// <item>
/// <term>WINBIO_E_INVALID_UNIT</term>
/// <term>One or more of the biometric unit numbers specified in the UnitArray parameter is not valid.</term>
/// </item>
/// <item>
/// <term>WINBIO_E_NOT_ACTIVE_CONSOLE</term>
/// <term>The client application is running on a remote desktop client and is attempting to open a system pool session.</term>
/// </item>
/// <item>
/// <term>WINBIO_E_SENSOR_UNAVAILABLE</term>
/// <term>The PoolType parameter is set to WINBIO_POOL_PRIVATE and one or more of the requested sensors in that pool is not available.</term>
/// </item>
/// <item>
/// <term>WINBIO_E_DISABLED</term>
/// <term>Current administrative policy prohibits use of the Windows Biometric Framework API.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// The session handle returned by the <c>WinBioAsyncOpenSession</c> function can be used to generate asynchronous completion
/// notifications for any of the following functions:
/// </para>
/// <list type="bullet">
/// <item>
/// <term>WinBioCancel</term>
/// </item>
/// <item>
/// <term>WinBioCaptureSample</term>
/// </item>
/// <item>
/// <term>WinBioCloseSession</term>
/// </item>
/// <item>
/// <term>WinBioControlUnit</term>
/// </item>
/// <item>
/// <term>WinBioControlUnitPrivileged</term>
/// </item>
/// <item>
/// <term>WinBioDeleteTemplate</term>
/// </item>
/// <item>
/// <term>WinBioEnrollBegin</term>
/// </item>
/// <item>
/// <term>WinBioEnrollCapture</term>
/// </item>
/// <item>
/// <term>WinBioEnrollCommit</term>
/// </item>
/// <item>
/// <term>WinBioEnrollDiscard</term>
/// </item>
/// <item>
/// <term>WinBioEnumEnrollments</term>
/// </item>
/// <item>
/// <term>WinBioGetProperty</term>
/// </item>
/// <item>
/// <term>WinBioIdentify</term>
/// </item>
/// <item>
/// <term>WinBioLocateSensor</term>
/// </item>
/// <item>
/// <term>WinBioLockUnit</term>
/// </item>
/// <item>
/// <term>WinBioLogonIdentifiedUser</term>
/// </item>
/// <item>
/// <term>WinBioRegisterEventMonitor</term>
/// </item>
/// <item>
/// <term>WinBioUnlockUnit</term>
/// </item>
/// <item>
/// <term>WinBioUnregisterEventMonitor</term>
/// </item>
/// <item>
/// <term>WinBioVerify</term>
/// </item>
/// <item>
/// <term>WinBioWait</term>
/// </item>
/// </list>
/// <para>The session handle returned by <c>WinBioAsyncOpenSession</c> cannot be used with the following functions:</para>
/// <list type="bullet">
/// <item>
/// <term>WinBioCaptureSampleWithCallback</term>
/// </item>
/// <item>
/// <term>WinBioEnrollCaptureWithCallback</term>
/// </item>
/// <item>
/// <term>WinBioIdentifyWithCallback</term>
/// </item>
/// <item>
/// <term>WinBioIdentifyWithCallback</term>
/// </item>
/// </list>
/// <para>
/// These functions, first available in Windows 7, have an incompatible callback signature, and their use in new applications is
/// discouraged. Developers who want asynchronous callbacks should instead use <c>WinBioAsyncOpenSession</c> with a
/// NotificationMethod of <c>WINBIO_ASYNC_NOTIFY_CALLBACK</c>.
/// </para>
/// <para>
/// The AsynchronousOpen parameter determines only whether the open operation will block. This parameter has no effect on the
/// completion behavior of subsequent calls that use the session handle.
/// </para>
/// <para>
/// If you set the AsynchronousOpen parameter to <c>TRUE</c>, this function will return <c>S_OK</c> as soon as it has performed an
/// initial validation of the arguments. Any errors detected beyond that point will be reported to the caller using the method
/// specified by the NotificationMethod parameter. That is, a successful return value indicates only that the
/// <c>WinBioAsyncOpenSession</c> parameters were fine and not that the open operation succeeded. To determine whether the open
/// operation succeeded, you must examine the WINBIO_ASYNC_RESULT structure.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winbio/nf-winbio-winbioasyncopensession HRESULT WinBioAsyncOpenSession(
// WINBIO_BIOMETRIC_TYPE Factor, WINBIO_POOL_TYPE PoolType, WINBIO_SESSION_FLAGS Flags, WINBIO_UNIT_ID *UnitArray, SIZE_T UnitCount,
// GUID *DatabaseId, WINBIO_ASYNC_NOTIFICATION_METHOD NotificationMethod, HWND TargetWindow, UINT MessageCode,
// PWINBIO_ASYNC_COMPLETION_CALLBACK CallbackRoutine, PVOID UserData, BOOL AsynchronousOpen, WINBIO_SESSION_HANDLE *SessionHandle );
[DllImport(Lib_Winbio, SetLastError = false, ExactSpelling = true)]
[PInvokeData("winbio.h", MSDNShortId = "NF:winbio.WinBioAsyncOpenSession")]
public static extern HRESULT WinBioAsyncOpenSession(WINBIO_BIOMETRIC_TYPE Factor, WINBIO_POOL_TYPE PoolType, WINBIO_SESSION_FLAGS Flags,
[In, Optional, MarshalAs(UnmanagedType.LPArray)] uint[] UnitArray, [Optional] SizeT UnitCount, in Guid DatabaseId,
WINBIO_ASYNC_NOTIFICATION_METHOD NotificationMethod, [In, Optional] HWND TargetWindow,
[In, Optional] uint MessageCode, [In, Optional] PWINBIO_ASYNC_COMPLETION_CALLBACK CallbackRoutine,
[In, Optional] IntPtr UserData, [MarshalAs(UnmanagedType.Bool)] bool AsynchronousOpen,
out WINBIO_SESSION_HANDLE SessionHandle);
/// <summary>
/// <para>
/// Asynchronously connects to a biometric service provider and one or more biometric units. Starting with Windows 10, build 1607,
/// this function is available to use with a mobile image. If successful, the function returns a biometric session handle. Every
/// operation performed by using this handle will be completed asynchronously, including WinBioCloseSession, and the results will be
/// returned to the client application by using the method specified in the NotificationMethod parameter.
/// </para>
/// <para>For a synchronous version of this function, see WinBioOpenSession.</para>
/// </summary>
/// <param name="Factor">
/// A bitmask of WINBIO_BIOMETRIC_TYPE flags that specifies the biometric unit types to be enumerated. Only
/// <c>WINBIO_TYPE_FINGERPRINT</c> is currently supported.
/// </param>
/// <param name="PoolType">
/// <para>
/// A <c>ULONG</c> value that specifies the type of the biometric units that will be used in the session. This can be one of the
/// following values:
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>WINBIO_POOL_SYSTEM</term>
/// <term>The session connects to a shared collection of biometric units managed by the service provider.</term>
/// </item>
/// <item>
/// <term>WINBIO_POOL_PRIVATE</term>
/// <term>The session connects to a collection of biometric units that are managed by the caller.</term>
/// </item>
/// </list>
/// </param>
/// <param name="Flags">
/// <para>
/// A <c>ULONG</c> value that specifies biometric unit configuration and access characteristics for the new session. Configuration
/// flags specify the general configuration of units in the session. Access flags specify how the application will use the biometric
/// units. You must specify one configuration flag but you can combine that flag with any access flag.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>WINBIO_FLAG_DEFAULT</term>
/// <term>
/// Group: configuration The biometric units operate in the manner specified during installation. You must use this value when the
/// PoolType parameter is WINBIO_POOL_SYSTEM.
/// </term>
/// </item>
/// <item>
/// <term>WINBIO_FLAG_BASIC</term>
/// <term>
/// Group: configuration The biometric units operate only as basic capture devices. All processing, matching, and storage operations
/// is performed by software plug-ins.
/// </term>
/// </item>
/// <item>
/// <term>WINBIO_FLAG_ADVANCED</term>
/// <term>Group: configuration The biometric units use internal processing and storage capabilities.</term>
/// </item>
/// <item>
/// <term>WINBIO_FLAG_RAW</term>
/// <term>Group: access The client application captures raw biometric data using WinBioCaptureSample.</term>
/// </item>
/// <item>
/// <term>WINBIO_FLAG_MAINTENANCE</term>
/// <term>Group: access The client performs vendor-defined control operations on a biometric unit by calling WinBioControlUnitPrivileged.</term>
/// </item>
/// </list>
/// </param>
/// <param name="UnitArray">
/// Pointer to an array of biometric unit identifiers to be included in the session. You can call WinBioEnumBiometricUnits to
/// enumerate the biometric units. Set this value to <c>NULL</c> if the PoolType parameter is <c>WINBIO_POOL_SYSTEM</c>.
/// </param>
/// <param name="UnitCount">
/// A value that specifies the number of elements in the array pointed to by the UnitArray parameter. Set this value to zero if the
/// PoolType parameter is <c>WINBIO_POOL_SYSTEM</c>.
/// </param>
/// <param name="DatabaseId">
/// <para>
/// A value that specifies the database(s) to be used by the session. If the PoolType parameter is <c>WINBIO_POOL_PRIVATE</c>, you
/// must specify the GUID of an installed database. If the PoolType parameter is not <c>WINBIO_POOL_PRIVATE</c>, you can specify one
/// of the following common values.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>WINBIO_DB_DEFAULT</term>
/// <term>
/// Each biometric unit in the sensor pool uses the default database specified in the default biometric unit configuration. You must
/// specify this value if the PoolType parameter is WINBIO_POOL_SYSTEM. You cannot use this value if the PoolType parameter is WINBIO_POOL_PRIVATE
/// </term>
/// </item>
/// <item>
/// <term>WINBIO_DB_BOOTSTRAP</term>
/// <term>
/// You can specify this value to be used for scenarios prior to starting Windows. Typically, the database is part of the sensor
/// chip or is part of the BIOS and can only be used for template enrollment and deletion.
/// </term>
/// </item>
/// <item>
/// <term>WINBIO_DB_ONCHIP</term>
/// <term>The database is on the sensor chip and is available for enrollment and matching.</term>
/// </item>
/// </list>
/// </param>
/// <param name="NotificationMethod">
/// <para>
/// Specifies how completion notifications for asynchronous operations in this biometric session are to be delivered to the client
/// application. This must be one of the following values.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>WINBIO_ASYNC_NOTIFY_CALLBACK</term>
/// <term>The session invokes the callback function defined by the application.</term>
/// </item>
/// <item>
/// <term>WINBIO_ASYNC_NOTIFY_MESSAGE</term>
/// <term>The session posts a window message to the application's message queue.</term>
/// </item>
/// </list>
/// </param>
/// <param name="TargetWindow">
/// Handle of the window that will receive the completion notices. This value is ignored unless the NotificationMethod parameter is
/// set to <c>WINBIO_ASYNC_NOTIFY_MESSAGE</c>.
/// </param>
/// <param name="MessageCode">
/// <para>
/// Window message code the framework must send to signify completion notices. This value is ignored unless the NotificationMethod
/// parameter is set to <c>WINBIO_ASYNC_NOTIFY_MESSAGE</c>. The value must be within the range WM_APP(0x8000) to 0xBFFF.
/// </para>
/// <para>
/// The Windows Biometric Framework sets the <c>LPARAM</c> value of the message to the address of the WINBIO_ASYNC_RESULT structure
/// that contains the results of the operation. You must call WinBioFree to release the structure after you have finished using it.
/// </para>
/// </param>
/// <param name="CallbackRoutine">
/// Address of callback routine to be invoked when the operation started by using the session handle completes. This value is
/// ignored unless the NotificationMethod parameter is set to <c>WINBIO_ASYNC_NOTIFY_CALLBACK</c>.
/// </param>
/// <param name="UserData">
/// Address of a buffer supplied by the caller. The buffer is not modified by the framework or the biometric unit. It is returned in
/// the WINBIO_ASYNC_RESULT structure. Your application can use the data to help it determine what actions to perform upon receipt
/// of the completion notice or to maintain additional information about the requested operation.
/// </param>
/// <param name="AsynchronousOpen">
/// <para>
/// Specifies whether to block until the framework session has been opened. Specifying <c>FALSE</c> causes the process to block.
/// Specifying <c>TRUE</c> causes the session to be opened asynchronously.
/// </para>
/// <para>
/// If you specify <c>FALSE</c> to open the framework session synchronously, success or failure is returned to the caller directly
/// by this function in the <c>HRESULT</c> return value. If the session is opened successfully, the first asynchronous completion
/// event your application receives will be for an asynchronous operation requested after the framework has been open.
/// </para>
/// <para>
/// If you specify <c>TRUE</c> to open the framework session asynchronously, the first asynchronous completion notice received will
/// be for opening the framework. If the NotificationMethod parameter is set to <c>WINBIO_ASYNC_NOTIFY_CALLBACK</c>, operation
/// results are delivered to the WINBIO_ASYNC_RESULT structure in the callback function specified by the CallbackRoutine parameter.
/// If the NotificationMethod parameter is set to <c>WINBIO_ASYNC_NOTIFY_MESSAGE</c>, operation results are delivered to the
/// <c>WINBIO_ASYNC_RESULT</c> structure pointed to by the LPARAM field of the window message.
/// </para>
/// </param>
/// <param name="SessionHandle">
/// <para>If the function does not succeed, this parameter will be <c>NULL</c>.</para>
/// <para>If the session is opened synchronously and successfully, this parameter will contain a pointer to the session handle.</para>
/// <para>
/// If you specify that the session be opened asynchronously, this method returns immediately, the session handle will be
/// <c>NULL</c>, and you must examine the WINBIO_ASYNC_RESULT structure to determine whether the session was successfully opened.
/// </para>
/// </param>
/// <returns>
/// <para>
/// If the function succeeds, it returns <c>S_OK</c>. If the function fails, it returns an <c>HRESULT</c> value that indicates the
/// error. Possible values include, but are not limited to, those in the following table. For a list of common error codes, see
/// Common HRESULT Values.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>E_OUTOFMEMORY</term>
/// <term>There is not enough memory available to create the biometric session.</term>
/// </item>
/// <item>
/// <term>E_INVALIDARG</term>
/// <term>
/// If you set the notification method to WINBIO_ASYNC_NOTIFY_MESSAGE, the TargetWindow parameter cannot be NULL or HWND_BROADCAST
/// and the MessageCode parameter cannot be zero (0).
/// </term>
/// </item>
/// <item>
/// <term>E_POINTER</term>
/// <term>
/// The SessionHandle parameter and the AsynchronousOpen parameter must be set. If you set the notification method to
/// WINBIO_ASYNC_NOTIFY_CALLBACK, you must also specify the address of a callback function in the CallbackRoutine parameter.
/// </term>
/// </item>
/// <item>
/// <term>E_ACCESSDENIED</term>
/// <term>
/// The Flags parameter contains the WINBIO_FLAG_RAW or the WINBIO_FLAG_MAINTENANCE flag and the caller has not been granted either
/// access permission.
/// </term>
/// </item>
/// <item>
/// <term>WINBIO_E_INVALID_UNIT</term>
/// <term>One or more of the biometric unit numbers specified in the UnitArray parameter is not valid.</term>
/// </item>
/// <item>
/// <term>WINBIO_E_NOT_ACTIVE_CONSOLE</term>
/// <term>The client application is running on a remote desktop client and is attempting to open a system pool session.</term>
/// </item>
/// <item>
/// <term>WINBIO_E_SENSOR_UNAVAILABLE</term>
/// <term>The PoolType parameter is set to WINBIO_POOL_PRIVATE and one or more of the requested sensors in that pool is not available.</term>
/// </item>
/// <item>
/// <term>WINBIO_E_DISABLED</term>
/// <term>Current administrative policy prohibits use of the Windows Biometric Framework API.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// The session handle returned by the <c>WinBioAsyncOpenSession</c> function can be used to generate asynchronous completion
/// notifications for any of the following functions:
/// </para>
/// <list type="bullet">
/// <item>
/// <term>WinBioCancel</term>
/// </item>
/// <item>
/// <term>WinBioCaptureSample</term>
/// </item>
/// <item>
/// <term>WinBioCloseSession</term>
/// </item>
/// <item>
/// <term>WinBioControlUnit</term>
/// </item>
/// <item>
/// <term>WinBioControlUnitPrivileged</term>
/// </item>
/// <item>
/// <term>WinBioDeleteTemplate</term>
/// </item>
/// <item>
/// <term>WinBioEnrollBegin</term>
/// </item>
/// <item>
/// <term>WinBioEnrollCapture</term>
/// </item>
/// <item>
/// <term>WinBioEnrollCommit</term>
/// </item>
/// <item>
/// <term>WinBioEnrollDiscard</term>
/// </item>
/// <item>
/// <term>WinBioEnumEnrollments</term>
/// </item>
/// <item>
/// <term>WinBioGetProperty</term>
/// </item>
/// <item>
/// <term>WinBioIdentify</term>
/// </item>
/// <item>
/// <term>WinBioLocateSensor</term>
/// </item>
/// <item>
/// <term>WinBioLockUnit</term>
/// </item>
/// <item>
/// <term>WinBioLogonIdentifiedUser</term>
/// </item>
/// <item>
/// <term>WinBioRegisterEventMonitor</term>
/// </item>
/// <item>
/// <term>WinBioUnlockUnit</term>
/// </item>
/// <item>
/// <term>WinBioUnregisterEventMonitor</term>
/// </item>
/// <item>
/// <term>WinBioVerify</term>
/// </item>
/// <item>
/// <term>WinBioWait</term>
/// </item>
/// </list>
/// <para>The session handle returned by <c>WinBioAsyncOpenSession</c> cannot be used with the following functions:</para>
/// <list type="bullet">
/// <item>
/// <term>WinBioCaptureSampleWithCallback</term>
/// </item>
/// <item>
/// <term>WinBioEnrollCaptureWithCallback</term>
/// </item>
/// <item>
/// <term>WinBioIdentifyWithCallback</term>
/// </item>
/// <item>
/// <term>WinBioIdentifyWithCallback</term>
/// </item>
/// </list>
/// <para>
/// These functions, first available in Windows 7, have an incompatible callback signature, and their use in new applications is
/// discouraged. Developers who want asynchronous callbacks should instead use <c>WinBioAsyncOpenSession</c> with a
/// NotificationMethod of <c>WINBIO_ASYNC_NOTIFY_CALLBACK</c>.
/// </para>
/// <para>
/// The AsynchronousOpen parameter determines only whether the open operation will block. This parameter has no effect on the
/// completion behavior of subsequent calls that use the session handle.
/// </para>
/// <para>
/// If you set the AsynchronousOpen parameter to <c>TRUE</c>, this function will return <c>S_OK</c> as soon as it has performed an
/// initial validation of the arguments. Any errors detected beyond that point will be reported to the caller using the method
/// specified by the NotificationMethod parameter. That is, a successful return value indicates only that the
/// <c>WinBioAsyncOpenSession</c> parameters were fine and not that the open operation succeeded. To determine whether the open
/// operation succeeded, you must examine the WINBIO_ASYNC_RESULT structure.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winbio/nf-winbio-winbioasyncopensession HRESULT WinBioAsyncOpenSession(
// WINBIO_BIOMETRIC_TYPE Factor, WINBIO_POOL_TYPE PoolType, WINBIO_SESSION_FLAGS Flags, WINBIO_UNIT_ID *UnitArray, SIZE_T UnitCount,
// GUID *DatabaseId, WINBIO_ASYNC_NOTIFICATION_METHOD NotificationMethod, HWND TargetWindow, UINT MessageCode,
// PWINBIO_ASYNC_COMPLETION_CALLBACK CallbackRoutine, PVOID UserData, BOOL AsynchronousOpen, WINBIO_SESSION_HANDLE *SessionHandle );
[DllImport(Lib_Winbio, SetLastError = false, ExactSpelling = true)]
[PInvokeData("winbio.h", MSDNShortId = "NF:winbio.WinBioAsyncOpenSession")]
public static extern HRESULT WinBioAsyncOpenSession(WINBIO_BIOMETRIC_TYPE Factor, WINBIO_POOL_TYPE PoolType, WINBIO_SESSION_FLAGS Flags,
[In, Optional, MarshalAs(UnmanagedType.LPArray)] uint[] UnitArray, [Optional] SizeT UnitCount, [In, Optional] GuidPtr DatabaseId,
WINBIO_ASYNC_NOTIFICATION_METHOD NotificationMethod, [In, Optional] HWND TargetWindow,
[In, Optional] uint MessageCode, [In, Optional] PWINBIO_ASYNC_COMPLETION_CALLBACK CallbackRoutine,
[In, Optional] IntPtr UserData, [MarshalAs(UnmanagedType.Bool)] bool AsynchronousOpen,
out WINBIO_SESSION_HANDLE SessionHandle);
/// <summary>
/// Cancels all pending biometric operations for a specified session. Starting with Windows 10, build 1607, this function is
/// available to use with a mobile image.
/// </summary>
/// <param name="SessionHandle">
/// A <c>WINBIO_SESSION_HANDLE</c> value that identifies an open biometric session. Open a synchronous session handle by calling
/// WinBioOpenSession. Open an asynchronous session handle by calling WinBioAsyncOpenSession.
/// </param>
/// <returns>
/// <para>
/// If the function succeeds, it returns S_OK. If the function fails, it returns an <c>HRESULT</c> value that indicates the error.
/// Possible values include, but are not limited to, those in the following table. For a list of common error codes, see Common
/// HRESULT Values.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>E_HANDLE</term>
/// <term>The session handle is not valid.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// To use <c>WinBioCancel</c> synchronously, call the function with a session handle created by calling WinBioOpenSession. When you
/// call the function by using a synchronous session handle:
/// </para>
/// <list type="bullet">
/// <item>
/// <term>If there are no pending operations, the function returns S_OK and performs no other actions.</term>
/// </item>
/// <item>
/// <term>Pending asynchronous operations receive a callback notification for which the OperationStatus parameter is set to <c>WINBIO_E_CANCELED</c>.</term>
/// </item>
/// <item>
/// <term>Blocked asynchronous operations started by other threads in the process return <c>WINBIO_E_CANCELED</c>.</term>
/// </item>
/// </list>
/// <para>
/// To use <c>WinBioCancel</c> asynchronously, call the function with a session handle created by calling WinBioAsyncOpenSession.
/// When you call the function with an asynchronous session handle:
/// </para>
/// <list type="bullet">
/// <item>
/// <term>The function verifies the input parameter and returns immediately with either S_OK or an error code.</term>
/// </item>
/// <item>
/// <term>
/// Pending asynchronous operations receive a completion notification that sets the <c>ApiStatus</c> member of their respective
/// WINBIO_ASYNC_RESULT structures to <c>WINBIO_E_CANCELED</c>.
/// </term>
/// </item>
/// </list>
/// <para>
/// The framework also allocates a WINBIO_ASYNC_RESULT structure for <c>WinBioCancel</c> and uses it to return information about
/// cancellation success or failure. The <c>WINBIO_ASYNC_RESULT</c> structure is returned to the application callback or to the
/// application message queue, depending on the value you set in the NotificationMethod parameter of the WinBioAsyncOpenSession function:
/// </para>
/// <list type="bullet">
/// <item>
/// <term>
/// If you choose to receive completion notices by using a callback, you must implement a PWINBIO_ASYNC_COMPLETION_CALLBACK function
/// and set the NotificationMethod parameter to <c>WINBIO_ASYNC_NOTIFY_CALLBACK</c>.
/// </term>
/// </item>
/// <item>
/// <term>
/// If you choose to receive completion notices by using the application message queue, you must set the NotificationMethod
/// parameter to <c>WINBIO_ASYNC_NOTIFY_MESSAGE</c>. The framework returns a WINBIO_ASYNC_RESULT pointer to the <c>LPARAM</c> field
/// of the window message.
/// </term>
/// </item>
/// </list>
/// <para>
/// To prevent memory leaks, you must call WinBioFree to release the WINBIO_ASYNC_RESULT structure after you have finished using it.
/// </para>
/// <para>Examples</para>
/// <para>
/// The following code example captures a sample asynchronously by calling WinBioCaptureSampleWithCallback. You can pass a Boolean
/// value to the function that will, if set to <c>TRUE</c>, cancel the capture operation. Link to the Winbio.lib static library and
/// include the following header files:
/// </para>
/// <list type="bullet">
/// <item>
/// <term>Windows.h</term>
/// </item>
/// <item>
/// <term>Stdio.h</term>
/// </item>
/// <item>
/// <term>Conio.h</term>
/// </item>
/// <item>
/// <term>Winbio.h</term>
/// </item>
/// </list>
/// <para>
/// <code>HRESULT CaptureSampleWithCallback(BOOL bCancel) { HRESULT hr = S_OK; WINBIO_SESSION_HANDLE sessionHandle = NULL; // Connect to the system pool. hr = WinBioOpenSession( WINBIO_TYPE_FINGERPRINT, // Service provider WINBIO_POOL_SYSTEM, // Pool type WINBIO_FLAG_RAW, // Raw access NULL, // Array of biometric unit IDs 0, // Count of biometric unit IDs WINBIO_DB_DEFAULT, // Default database &amp;sessionHandle // [out] Session handle ); if (FAILED(hr)) { wprintf_s(L"\n WinBioOpenSession failed. hr = 0x%x\n", hr); goto e_Exit; } // Capture a biometric sample asynchronously. wprintf_s(L"\n Calling WinBioCaptureSampleWithCallback "); hr = WinBioCaptureSampleWithCallback( sessionHandle, // Open session handle WINBIO_NO_PURPOSE_AVAILABLE, // Intended use of the sample WINBIO_DATA_FLAG_RAW, // Sample format CaptureSampleCallback, // Callback function NULL // Optional context ); if (FAILED(hr)) { wprintf_s(L"\n WinBioCaptureSampleWithCallback failed. "); wprintf_s(L"hr = 0x%x\n", hr); goto e_Exit; } wprintf_s(L"\n Swipe the sensor ...\n"); // Cancel the capture operation if the bCancel flag is set. if (bCancel) { wprintf_s(L"\n Starting CANCEL timer..."); Sleep( 7000 ); wprintf_s(L"\n Calling WinBioCancel\n"); hr = WinBioCancel( sessionHandle ); if (FAILED(hr)) { wprintf_s(L"\n WinBioCancel failed. hr = 0x%x\n", hr); goto e_Exit; } } // Wait for the asynchronous capture process to complete // or be canceled. hr = WinBioWait( sessionHandle ); if (FAILED(hr)) { wprintf_s(L"\n WinBioWait failed. hr = 0x%x\n", hr); } e_Exit: if (sessionHandle != NULL) { WinBioCloseSession(sessionHandle); sessionHandle = NULL; } wprintf_s(L"\n Press any key to exit..."); _getch(); return hr; } //------------------------------------------------------------------------ // The following function is the callback for WinBioCaptureSampleWithCallback. // The function filters the response from the biometric subsystem and // writes a result to the console window. // VOID CALLBACK CaptureSampleCallback( __in_opt PVOID CaptureCallbackContext, __in HRESULT OperationStatus, __in WINBIO_UNIT_ID UnitId, __in_bcount(SampleSize) PWINBIO_BIR Sample, __in SIZE_T SampleSize, __in WINBIO_REJECT_DETAIL RejectDetail ) { UNREFERENCED_PARAMETER(CaptureCallbackContext); wprintf_s(L"\n CaptureSampleCallback executing"); wprintf_s(L"\n Swipe processed - Unit ID: %d", UnitId); if (FAILED(OperationStatus)) { if (OperationStatus == WINBIO_E_BAD_CAPTURE) { wprintf_s(L"\n Bad capture; reason: %d\n", RejectDetail); } else { wprintf_s(L"\n WinBioCaptureSampleWithCallback failed. "); wprintf_s(L" OperationStatus = 0x%x\n", OperationStatus); } goto e_Exit; } wprintf_s(L"\n Captured %d bytes.\n", SampleSize); e_Exit: if (Sample != NULL) { WinBioFree(Sample); Sample = NULL; } }</code>
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winbio/nf-winbio-winbiocancel HRESULT WinBioCancel( WINBIO_SESSION_HANDLE
// SessionHandle );
[DllImport(Lib_Winbio, SetLastError = false, ExactSpelling = true)]
[PInvokeData("winbio.h", MSDNShortId = "NF:winbio.WinBioCancel")]
public static extern HRESULT WinBioCancel(WINBIO_SESSION_HANDLE SessionHandle);
/// <summary>Captures a biometric sample and fills a biometric information record (BIR) with the raw or processed data.</summary>
/// <param name="SessionHandle">
/// A <c>WINBIO_SESSION_HANDLE</c> value that identifies an open biometric session. Open a synchronous session handle by calling
/// WinBioOpenSession. Open an asynchronous session handle by calling WinBioAsyncOpenSession.
/// </param>
/// <param name="Purpose">
/// <para>
/// A <c>WINBIO_BIR_PURPOSE</c> bitmask that specifies the intended use of the sample. This can be a bitwise <c>OR</c> of the
/// following values:
/// </para>
/// <list type="bullet">
/// <item>
/// <term><c>WINBIO_PURPOSE_VERIFY</c></term>
/// </item>
/// <item>
/// <term><c>WINBIO_PURPOSE_IDENTIFY</c></term>
/// </item>
/// <item>
/// <term><c>WINBIO_PURPOSE_ENROLL</c></term>
/// </item>
/// <item>
/// <term><c>WINBIO_PURPOSE_ENROLL_FOR_VERIFICATION</c></term>
/// </item>
/// <item>
/// <term><c>WINBIO_PURPOSE_ENROLL_FOR_IDENTIFICATION</c></term>
/// </item>
/// </list>
/// </param>
/// <param name="Flags">
/// <para>
/// A value that specifies the type of processing to be applied to the captured sample. This can be a bitwise <c>OR</c> of the
/// following security and processing level flags:
/// </para>
/// <list type="bullet">
/// <item>
/// <term><c>WINBIO_DATA_FLAG_PRIVACY</c></term>
/// </item>
/// </list>
/// <para>Encrypt the sample.</para>
/// <list type="bullet">
/// <item>
/// <term><c>WINBIO_DATA_FLAG_INTEGRITY</c></term>
/// </item>
/// </list>
/// <para>Sign the sample or protect it by using a message authentication code (MAC)</para>
/// <list type="bullet">
/// <item>
/// <term><c>WINBIO_DATA_FLAG_SIGNED</c></term>
/// </item>
/// </list>
/// <para>
/// If this flag and the WINBIO_DATA_FLAG_INTEGRITY flag are set, sign the sample. If this flag is not set but the
/// WINBIO_DATA_FLAG_INTEGRITY flag is set, compute a MAC.
/// </para>
/// <list type="bullet">
/// <item>
/// <term><c>WINBIO_DATA_FLAG_RAW</c></term>
/// </item>
/// </list>
/// <para>Return the sample exactly as it was captured by the sensor.</para>
/// <list type="bullet">
/// <item>
/// <term><c>WINBIO_DATA_FLAG_INTERMEDIATE</c></term>
/// </item>
/// </list>
/// <para>Return the sample after it has been cleaned and filtered.</para>
/// <list type="bullet">
/// <item>
/// <term><c>WINBIO_DATA_FLAG_PROCESSED</c></term>
/// </item>
/// </list>
/// <para>Return the sample after it is ready to be used for the purpose specified by the Purpose parameter.</para>
/// </param>
/// <param name="UnitId">
/// A pointer to a <c>WINBIO_UNIT_ID</c> value that contains the ID of the biometric unit that generated the sample.
/// </param>
/// <param name="Sample">
/// Address of a variable that receives a pointer to a WINBIO_BIR structure that contains the sample. When you have finished using
/// the structure, you must pass the pointer to WinBioFree to release the memory allocated for the sample.
/// </param>
/// <param name="SampleSize">
/// A pointer to a <c>SIZE_T</c> value that contains the size, in bytes, of the WINBIO_BIR structure returned in the Sample parameter.
/// </param>
/// <param name="RejectDetail">
/// <para>
/// A pointer to a <c>WINBIO_REJECT_DETAIL</c> value that contains additional information about the failure to capture a biometric
/// sample. If the capture succeeded, this parameter is set to zero. The following values are defined for fingerprint capture:
/// </para>
/// <list type="bullet">
/// <item>
/// <term><c>WINBIO_FP_TOO_HIGH</c></term>
/// </item>
/// <item>
/// <term><c>WINBIO_FP_TOO_LOW</c></term>
/// </item>
/// <item>
/// <term><c>WINBIO_FP_TOO_LEFT</c></term>
/// </item>
/// <item>
/// <term><c>WINBIO_FP_TOO_RIGHT</c></term>
/// </item>
/// <item>
/// <term><c>WINBIO_FP_TOO_FAST</c></term>
/// </item>
/// <item>
/// <term><c>WINBIO_FP_TOO_SLOW</c></term>
/// </item>
/// <item>
/// <term><c>WINBIO_FP_POOR_QUALITY</c></term>
/// </item>
/// <item>
/// <term><c>WINBIO_FP_TOO_SKEWED</c></term>
/// </item>
/// <item>
/// <term><c>WINBIO_FP_TOO_SHORT</c></term>
/// </item>
/// <item>
/// <term><c>WINBIO_FP_MERGE_FAILURE</c></term>
/// </item>
/// </list>
/// </param>
/// <returns>
/// <para>
/// If the function succeeds, it returns <c>S_OK</c>. If the function fails, it returns an <c>HRESULT</c> value that indicates the
/// error. Possible values include, but are not limited to, those in the following table. For a list of common error codes, see
/// Common HRESULT Values.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>E_ACCESSDENIED</term>
/// <term>
/// The caller does not have permission to capture raw samples, or the session was not opened by using the WINBIO_FLAG_RAW flag.
/// </term>
/// </item>
/// <item>
/// <term>E_HANDLE</term>
/// <term>The session handle is not valid.</term>
/// </item>
/// <item>
/// <term>E_NOTIMPL</term>
/// <term>The biometric unit does not support the requested operation.</term>
/// </item>
/// <item>
/// <term>E_POINTER</term>
/// <term>The UnitId, Sample, SampleSize, and RejectDetail pointers cannot be NULL.</term>
/// </item>
/// <item>
/// <term>WINBIO_E_ENROLLMENT_IN_PROGRESS</term>
/// <term>
/// The operation could not be completed because the biometric unit is currently being used for an enrollment transaction (system
/// pool only).
/// </term>
/// </item>
/// <item>
/// <term>WINBIO_E_INVALID_OPERATION</term>
/// <term>The operation could not be completed because a secure sensor is present in the sensor pool.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// To call this function successfully, you must open the session handle by specifying <c>WINBIO_FLAG_RAW</c> in the Flags parameter
/// of the WinBioOpenSession or WinBioAsyncOpenSession functions. Currently, only applications running under the Administrators and
/// Local System accounts have the necessary privileges.
/// </para>
/// <para>
/// Valid combinations of the Purpose and Flags parameters depend on the capabilities of the biometric unit being used. Consult the
/// vendor's sensor documentation to determine which combinations of valid Purpose and Flags values are supported and how they
/// affect the captured data. After you are finished using the sample, your application must call WinBioFree to release the memory
/// allocated for it by the <c>WinBioCaptureSample</c> function.
/// </para>
/// <para>
/// To use <c>WinBioCaptureSample</c> synchronously, call the function with a session handle created by calling WinBioOpenSession.
/// The function blocks until a sample has been captured or an error is encountered. Calls to <c>WinBioCaptureSample</c> using the
/// system pool will block until the calling application has window focus and the user provides a sample to one of the sensors in
/// the pool. If the sensor chosen by the user is already being used for an enrollment transaction, the function fails and returns <c>WINBIO_E_ENROLLMENT_IN_PROGRESS</c>.
/// </para>
/// <para>
/// To use <c>WinBioCaptureSample</c> asynchronously, call the function with a session handle created by calling
/// WinBioAsyncOpenSession. The framework allocates a WINBIO_ASYNC_RESULT structure and uses it to return information about
/// operation success or failure. If the capture operation is successful, the framework returns information about the sample in a
/// nested <c>CaptureSample</c> structure. If the operation is unsuccessful, the framework returns error information. The
/// <c>WINBIO_ASYNC_RESULT</c> structure is returned to the application callback or to the application message queue, depending on
/// the value you set in the NotificationMethod parameter of the <c>WinBioAsyncOpenSession</c> function:
/// </para>
/// <list type="bullet">
/// <item>
/// <term>
/// If you choose to receive completion notices by using a callback, you must implement a PWINBIO_ASYNC_COMPLETION_CALLBACK function
/// and set the NotificationMethod parameter to <c>WINBIO_ASYNC_NOTIFY_CALLBACK</c>.
/// </term>
/// </item>
/// <item>
/// <term>
/// If you choose to receive completion notices by using the application message queue, you must set the NotificationMethod
/// parameter to <c>WINBIO_ASYNC_NOTIFY_MESSAGE</c>. The framework returns a WINBIO_ASYNC_RESULT pointer to the <c>LPARAM</c> field
/// of the window message.
/// </term>
/// </item>
/// </list>
/// <para>
/// To prevent memory leaks, you must call WinBioFree to release the WINBIO_ASYNC_RESULT structure after you have finished using it.
/// </para>
/// <para>
/// <c>Windows 7:</c> You can perform this operation asynchronously by using the WinBioCaptureSampleWithCallback function. The
/// function verifies the input arguments and returns immediately. If the input arguments are not valid, the function returns an
/// error code. Otherwise, the framework starts the operation on another thread. When the asynchronous operation completes or
/// encounters an error, the framework sends the results to the PWINBIO_CAPTURE_CALLBACK function implemented by your application.
/// </para>
/// <para>Examples</para>
/// <para>
/// The following function calls <c>WinBioCaptureSample</c> to capture a biometric sample from a user. Link to the Winbio.lib static
/// library and include the following header files:
/// </para>
/// <list type="bullet">
/// <item>
/// <term>Windows.h</term>
/// </item>
/// <item>
/// <term>Stdio.h</term>
/// </item>
/// <item>
/// <term>Conio.h</term>
/// </item>
/// <item>
/// <term>Winbio.h</term>
/// </item>
/// </list>
/// <para>
/// <code>HRESULT CaptureSample() { HRESULT hr = S_OK; WINBIO_SESSION_HANDLE sessionHandle = NULL; WINBIO_UNIT_ID unitId = 0; WINBIO_REJECT_DETAIL rejectDetail = 0; PWINBIO_BIR sample = NULL; SIZE_T sampleSize = 0; // Connect to the system pool. hr = WinBioOpenSession( WINBIO_TYPE_FINGERPRINT, // Service provider WINBIO_POOL_SYSTEM, // Pool type WINBIO_FLAG_RAW, // Access: Capture raw data NULL, // Array of biometric unit IDs 0, // Count of biometric unit IDs WINBIO_DB_DEFAULT, // Default database &amp;sessionHandle // [out] Session handle ); if (FAILED(hr)) { wprintf_s(L"\n WinBioOpenSession failed. hr = 0x%x\n", hr); goto e_Exit; } // Capture a biometric sample. wprintf_s(L"\n Calling WinBioCaptureSample - Swipe sensor...\n"); hr = WinBioCaptureSample( sessionHandle, WINBIO_NO_PURPOSE_AVAILABLE, WINBIO_DATA_FLAG_RAW, &amp;unitId, &amp;sample, &amp;sampleSize, &amp;rejectDetail ); if (FAILED(hr)) { if (hr == WINBIO_E_BAD_CAPTURE) { wprintf_s(L"\n Bad capture; reason: %d\n", rejectDetail); } else { wprintf_s(L"\n WinBioCaptureSample failed. hr = 0x%x\n", hr); } goto e_Exit; } wprintf_s(L"\n Swipe processed - Unit ID: %d\n", unitId); wprintf_s(L"\n Captured %d bytes.\n", sampleSize); e_Exit: if (sample != NULL) { WinBioFree(sample); sample = NULL; } if (sessionHandle != NULL) { WinBioCloseSession(sessionHandle); sessionHandle = NULL; } wprintf_s(L"\n Press any key to exit..."); _getch(); return hr; }</code>
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winbio/nf-winbio-winbiocapturesample HRESULT WinBioCaptureSample(
// WINBIO_SESSION_HANDLE SessionHandle, WINBIO_BIR_PURPOSE Purpose, WINBIO_BIR_DATA_FLAGS Flags, WINBIO_UNIT_ID *UnitId, PWINBIO_BIR
// *Sample, SIZE_T *SampleSize, WINBIO_REJECT_DETAIL *RejectDetail );
[DllImport(Lib_Winbio, SetLastError = false, ExactSpelling = true)]
[PInvokeData("winbio.h", MSDNShortId = "NF:winbio.WinBioCaptureSample")]
public static extern HRESULT WinBioCaptureSample(WINBIO_SESSION_HANDLE SessionHandle, WINBIO_BIR_PURPOSE Purpose, WINBIO_BIR_DATA_FLAGS Flags,
out uint UnitId, out SafeWinBioMemory Sample, out SizeT SampleSize, out WINBIO_REJECT_DETAIL RejectDetail);
/// <summary>
/// <para>
/// Captures a biometric sample asynchronously and returns the raw or processed data in a biometric information record (BIR). The
/// function returns immediately to the caller, captures the sample on a separate thread, and calls into an application-defined
/// callback function to update operation status.
/// </para>
/// <para><c>Important</c>
/// <para></para>
/// We recommend that, beginning with Windows 8, you no longer use this function to start an asynchronous operation. Instead, do the following:
/// </para>
/// </summary>
/// <param name="SessionHandle">A <c>WINBIO_SESSION_HANDLE</c> value that identifies an open biometric session.</param>
/// <param name="Purpose">
/// <para>
/// A <c>WINBIO_BIR_PURPOSE</c> bitmask that specifies the intended use of the sample. This can be a bitwise <c>OR</c> of the
/// following values:
/// </para>
/// <list type="bullet">
/// <item>
/// <term><c>WINBIO_PURPOSE_VERIFY</c></term>
/// </item>
/// <item>
/// <term><c>WINBIO_PURPOSE_IDENTIFY</c></term>
/// </item>
/// <item>
/// <term><c>WINBIO_PURPOSE_ENROLL</c></term>
/// </item>
/// <item>
/// <term><c>WINBIO_PURPOSE_ENROLL_FOR_VERIFICATION</c></term>
/// </item>
/// <item>
/// <term><c>WINBIO_PURPOSE_ENROLL_FOR_IDENTIFICATION</c></term>
/// </item>
/// </list>
/// </param>
/// <param name="Flags">
/// <para>
/// A value that specifies the type of processing to be applied to the captured sample. This can be a bitwise <c>OR</c> of the
/// following security and processing level flags:
/// </para>
/// <list type="bullet">
/// <item>
/// <term><c>WINBIO_DATA_FLAG_PRIVACY</c></term>
/// </item>
/// </list>
/// <para>Encrypt the sample.</para>
/// <list type="bullet">
/// <item>
/// <term><c>WINBIO_DATA_FLAG_INTEGRITY</c></term>
/// </item>
/// </list>
/// <para>Sign the sample or protect it by using a message authentication code (MAC).</para>
/// <list type="bullet">
/// <item>
/// <term><c>WINBIO_DATA_FLAG_SIGNED</c></term>
/// </item>
/// </list>
/// <para>
/// If this flag and the WINBIO_DATA_FLAG_INTEGRITYflag are set, sign the sample. If this flag is not set but the
/// WINBIO_DATA_FLAG_INTEGRITY flag is set, compute a MAC.
/// </para>
/// <list type="bullet">
/// <item>
/// <term><c>WINBIO_DATA_FLAG_RAW</c></term>
/// </item>
/// </list>
/// <para>Return the sample exactly as it was captured by the sensor.</para>
/// <list type="bullet">
/// <item>
/// <term><c>WINBIO_DATA_FLAG_INTERMEDIATE</c></term>
/// </item>
/// </list>
/// <para>Return the sample after it has been cleaned and filtered.</para>
/// <list type="bullet">
/// <item>
/// <term><c>WINBIO_DATA_FLAG_PROCESSED</c></term>
/// </item>
/// </list>
/// <para>Return the sample after it is ready to be used for the purpose specified by the parameter.</para>
/// </param>
/// <param name="CaptureCallback">
/// Address of a callback function that will be called by the <c>WinBioCaptureSampleWithCallback</c> function when the capture
/// operation succeeds or fails. You must create the callback.
/// </param>
/// <param name="CaptureCallbackContext">
/// Address of an application-defined data structure that is passed to the callback function in its CaptureCallbackContext
/// parameter. This structure can contain any data that the custom callback function is designed to handle.
/// </param>
/// <returns>
/// <para>
/// If the function succeeds, it returns <c>S_OK</c>. If the function fails, it returns an <c>HRESULT</c> value that indicates the
/// error. Possible values include, but are not limited to, those in the following table. For a list of common error codes, see
/// Common HRESULT Values.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>E_ACCESSDENIED</term>
/// <term>
/// The caller does not have permission to capture raw samples, or the session was not opened by using the WINBIO_FLAG_RAW flag.
/// </term>
/// </item>
/// <item>
/// <term>E_HANDLE</term>
/// <term>The session handle is not valid.</term>
/// </item>
/// <item>
/// <term>E_NOTIMPL</term>
/// <term>The biometric unit does not support the requested operation.</term>
/// </item>
/// <item>
/// <term>E_POINTER</term>
/// <term>The UnitId, Sample, SampleSize, and RejectDetail pointers cannot be NULL.</term>
/// </item>
/// <item>
/// <term>WINBIO_E_ENROLLMENT_IN_PROGRESS</term>
/// <term>
/// The operation could not be completed because the biometric unit is currently being used for an enrollment transaction (system
/// pool only).
/// </term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// The <c>WinBioCaptureSampleWithCallback</c> function captures samples asynchronously. To call this function successfully, the
/// session handle must have been opened by specifying <c>WINBIO_FLAG_RAW</c>. Only the Administrators and Local System accounts
/// have the necessary privileges.
/// </para>
/// <para>
/// Valid combinations of the Purpose and Flags parameters depend on the capabilities of the biometric unit being used. Consult the
/// vendor sensor documentation to determine what combinations are supported and how they affect the captured data.
/// </para>
/// <para>Callers are responsible for releasing the WINBIO_BIR structure returned by the Sample parameter.</para>
/// <para>The callback routine must have the following signature:</para>
/// <para>
/// <code>VOID CALLBACK CaptureCallback( __in_opt PVOID CaptureCallbackContext, __in HRESULT OperationStatus, __in WINBIO_UNIT_ID UnitId, __in_bcount(SampleSize) PWINBIO_BIR Sample, __in SIZE_T SampleSize, __in WINBIO_REJECT_DETAIL RejectDetail );</code>
/// </para>
/// <para>Examples</para>
/// <para>
/// The following code example captures a sample asynchronously by calling <c>WinBioCaptureSampleWithCallback</c> and passing a
/// pointer to a custom callback function. The callback function, CaptureSampleCallback, is also shown. Link to the Winbio.lib
/// static library and include the following header files:
/// </para>
/// <list type="bullet">
/// <item>
/// <term>Windows.h</term>
/// </item>
/// <item>
/// <term>Stdio.h</term>
/// </item>
/// <item>
/// <term>Conio.h</term>
/// </item>
/// <item>
/// <term>Winbio.h</term>
/// </item>
/// </list>
/// <para>
/// <code>HRESULT CaptureSampleWithCallback(BOOL bCancel) { HRESULT hr = S_OK; WINBIO_SESSION_HANDLE sessionHandle = NULL; // Connect to the system pool. hr = WinBioOpenSession( WINBIO_TYPE_FINGERPRINT, // Service provider WINBIO_POOL_SYSTEM, // Pool type WINBIO_FLAG_RAW, // Raw access NULL, // Array of biometric unit IDs 0, // Count of biometric unit IDs WINBIO_DB_DEFAULT, // Default database &amp;sessionHandle // [out] Session handle ); if (FAILED(hr)) { wprintf_s(L"\n WinBioOpenSession failed. hr = 0x%x\n", hr); goto e_Exit; } // Capture a biometric sample asynchronously. wprintf_s(L"\n Calling WinBioCaptureSampleWithCallback "); hr = WinBioCaptureSampleWithCallback( sessionHandle, // Open session handle WINBIO_NO_PURPOSE_AVAILABLE, // Intended use of the sample WINBIO_DATA_FLAG_RAW, // Sample format CaptureSampleCallback, // Callback function NULL // Optional context ); if (FAILED(hr)) { wprintf_s(L"\n WinBioCaptureSampleWithCallback failed. "); wprintf_s(L"hr = 0x%x\n", hr); goto e_Exit; } wprintf_s(L"\n Swipe the sensor ...\n"); // Cancel the capture process if the bCancel flag is set. if (bCancel) { wprintf_s(L"\n Starting CANCEL timer..."); Sleep( 7000 ); wprintf_s(L"\n Calling WinBioCancel\n"); hr = WinBioCancel( sessionHandle ); if (FAILED(hr)) { wprintf_s(L"\n WinBioCancel failed. hr = 0x%x\n", hr); goto e_Exit; } } // Wait for the asynchronous capture process to complete // or be canceled. hr = WinBioWait( sessionHandle ); if (FAILED(hr)) { wprintf_s(L"\n WinBioWait failed. hr = 0x%x\n", hr); } e_Exit: if (sessionHandle != NULL) { WinBioCloseSession(sessionHandle); sessionHandle = NULL; } wprintf_s(L"\n Press any key to exit..."); _getch(); return hr; } //------------------------------------------------------------------------ // The following function is the callback for WinBioCaptureSampleWithCallback. // The function filters the response from the biometric subsystem and // writes a result to the console window. // VOID CALLBACK CaptureSampleCallback( __in_opt PVOID CaptureCallbackContext, __in HRESULT OperationStatus, __in WINBIO_UNIT_ID UnitId, __in_bcount(SampleSize) PWINBIO_BIR Sample, __in SIZE_T SampleSize, __in WINBIO_REJECT_DETAIL RejectDetail ) { UNREFERENCED_PARAMETER(CaptureCallbackContext); wprintf_s(L"\n CaptureSampleCallback executing"); wprintf_s(L"\n Swipe processed - Unit ID: %d", UnitId); if (FAILED(OperationStatus)) { if (OperationStatus == WINBIO_E_BAD_CAPTURE) { wprintf_s(L"\n Bad capture; reason: %d\n", RejectDetail); } else { wprintf_s(L"\n WinBioCaptureSampleWithCallback failed. "); wprintf_s(L" OperationStatus = 0x%x\n", OperationStatus); } goto e_Exit; } wprintf_s(L"\n Captured %d bytes.\n", SampleSize); e_Exit: if (Sample != NULL) { WinBioFree(Sample); Sample = NULL; } }</code>
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winbio/nf-winbio-winbiocapturesamplewithcallback HRESULT
// WinBioCaptureSampleWithCallback( WINBIO_SESSION_HANDLE SessionHandle, WINBIO_BIR_PURPOSE Purpose, WINBIO_BIR_DATA_FLAGS Flags,
// PWINBIO_CAPTURE_CALLBACK CaptureCallback, PVOID CaptureCallbackContext );
[DllImport(Lib_Winbio, SetLastError = false, ExactSpelling = true)]
[PInvokeData("winbio.h", MSDNShortId = "NF:winbio.WinBioCaptureSampleWithCallback")]
public static extern HRESULT WinBioCaptureSampleWithCallback(WINBIO_SESSION_HANDLE SessionHandle, WINBIO_BIR_PURPOSE Purpose, WINBIO_BIR_DATA_FLAGS Flags,
[In] PWINBIO_CAPTURE_CALLBACK CaptureCallback, [In, Optional] IntPtr CaptureCallbackContext);
/// <summary>
/// Closes a framework handle previously opened with WinBioAsyncOpenFramework. Starting with Windows 10, build 1607, this function
/// is available to use with a mobile image.
/// </summary>
/// <param name="FrameworkHandle">Handle to the framework session that will be closed.</param>
/// <returns>
/// If the function succeeds, it returns <c>S_OK</c>. If the function fails, it returns an <c>HRESULT</c> value that indicates the error.
/// </returns>
/// <remarks>This function never blocks.</remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winbio/nf-winbio-winbiocloseframework HRESULT WinBioCloseFramework(
// WINBIO_FRAMEWORK_HANDLE FrameworkHandle );
[DllImport(Lib_Winbio, SetLastError = false, ExactSpelling = true)]
[PInvokeData("winbio.h", MSDNShortId = "NF:winbio.WinBioCloseFramework")]
public static extern HRESULT WinBioCloseFramework(WINBIO_FRAMEWORK_HANDLE FrameworkHandle);
/// <summary>
/// Closes a biometric session and releases associated resources. Starting with Windows 10, build 1607, this function is available
/// to use with a mobile image.
/// </summary>
/// <param name="SessionHandle">
/// A <c>WINBIO_SESSION_HANDLE</c> value that identifies an open biometric session. Open a synchronous session handle by calling
/// WinBioOpenSession. Open an asynchronous session handle by calling WinBioAsyncOpenSession.
/// </param>
/// <returns>
/// <para>
/// If the function succeeds, it returns S_OK. If the function fails, it returns an <c>HRESULT</c> value that indicates the error.
/// Possible values include, but are not limited to, those in the following table. For a list of common error codes, see Common
/// HRESULT Values.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>E_HANDLE</term>
/// <term>The session handle is not valid.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// To use <c>WinBioCloseSession</c> synchronously, call the function with a session handle created by calling WinBioOpenSession.
/// The function blocks until the operation completes or an error is encountered.
/// </para>
/// <para>
/// To use <c>WinBioCloseSession</c> asynchronously, call the function with a session handle created by calling
/// WinBioAsyncOpenSession. The framework allocates a WINBIO_ASYNC_RESULT structure and uses it to return information about
/// operation success or failure. The <c>WINBIO_ASYNC_RESULT</c> structure is returned to the application callback or to the
/// application message queue, depending on the value you set in the NotificationMethod parameter of the
/// <c>WinBioAsyncOpenSession</c> function.
/// </para>
/// <list type="bullet">
/// <item>
/// <term>
/// If you choose to receive completion notices by using a callback, you must implement a PWINBIO_ASYNC_COMPLETION_CALLBACK function
/// and set the NotificationMethod parameter to <c>WINBIO_ASYNC_NOTIFY_CALLBACK</c>.
/// </term>
/// </item>
/// <item>
/// <term>
/// If you choose to receive completion notices by using the application message queue, you must set the NotificationMethod
/// parameter to <c>WINBIO_ASYNC_NOTIFY_MESSAGE</c>. The framework returns a WINBIO_ASYNC_RESULT pointer to the <c>LPARAM</c> field
/// of the window message.
/// </term>
/// </item>
/// </list>
/// <para>
/// To prevent memory leaks, you must call WinBioFree from your callback implementation to release the WINBIO_ASYNC_RESULT structure
/// after you have finished using it.
/// </para>
/// <para>Examples</para>
/// <para>
/// The following function shows how to enumerate the biometric sub-factors enrolled for a template. The sample creates a connection
/// to the system pool and keeps the connection open until calling <c>WinBioCloseSession</c> during cleanup. Link to the Winbio.lib
/// static library and include the following header files:
/// </para>
/// <list type="bullet">
/// <item>
/// <term>Windows.h</term>
/// </item>
/// <item>
/// <term>Stdio.h</term>
/// </item>
/// <item>
/// <term>Conio.h</term>
/// </item>
/// <item>
/// <term>Winbio.h</term>
/// </item>
/// </list>
/// <para>
/// <code>HRESULT EnumEnrollments( ) { // Declare variables. HRESULT hr = S_OK; WINBIO_IDENTITY identity = {0}; WINBIO_SESSION_HANDLE sessionHandle = NULL; WINBIO_UNIT_ID unitId = 0; PWINBIO_BIOMETRIC_SUBTYPE subFactorArray = NULL; WINBIO_BIOMETRIC_SUBTYPE SubFactor = 0; SIZE_T subFactorCount = 0; WINBIO_REJECT_DETAIL rejectDetail = 0; WINBIO_BIOMETRIC_SUBTYPE subFactor = WINBIO_SUBTYPE_NO_INFORMATION; // Connect to the system pool. hr = WinBioOpenSession( WINBIO_TYPE_FINGERPRINT, // Service provider WINBIO_POOL_SYSTEM, // Pool type WINBIO_FLAG_DEFAULT, // Configuration and access NULL, // Array of biometric unit IDs 0, // Count of biometric unit IDs NULL, // Database ID &amp;sessionHandle // [out] Session handle ); if (FAILED(hr)) { wprintf_s(L"\n WinBioOpenSession failed. hr = 0x%x\n", hr); goto e_Exit; } // Locate the biometric sensor and retrieve a WINBIO_IDENTITY object. wprintf_s(L"\n Calling WinBioIdentify - Swipe finger on sensor...\n"); hr = WinBioIdentify( sessionHandle, // Session handle &amp;unitId, // Biometric unit ID &amp;identity, // User SID &amp;subFactor, // Finger sub factor &amp;rejectDetail // Rejection information ); wprintf_s(L"\n Swipe processed - Unit ID: %d\n", unitId); if (FAILED(hr)) { if (hr == WINBIO_E_UNKNOWN_ID) { wprintf_s(L"\n Unknown identity.\n"); } else if (hr == WINBIO_E_BAD_CAPTURE) { wprintf_s(L"\n Bad capture; reason: %d\n", rejectDetail); } else { wprintf_s(L"\n WinBioEnumBiometricUnits failed. hr = 0x%x\n", hr); } goto e_Exit; } // Retrieve the biometric sub-factors for the template. hr = WinBioEnumEnrollments( sessionHandle, // Session handle unitId, // Biometric unit ID &amp;identity, // Template ID &amp;subFactorArray, // Subfactors &amp;subFactorCount // Count of subfactors ); if (FAILED(hr)) { wprintf_s(L"\n WinBioEnumEnrollments failed. hr = 0x%x\n", hr); goto e_Exit; } // Print the sub-factor(s) to the console. wprintf_s(L"\n Enrollments for this user on Unit ID %d:", unitId); for (SIZE_T index = 0; index &lt; subFactorCount; ++index) { SubFactor = subFactorArray[index]; switch (SubFactor) { case WINBIO_ANSI_381_POS_RH_THUMB: wprintf_s(L"\n RH thumb\n"); break; case WINBIO_ANSI_381_POS_RH_INDEX_FINGER: wprintf_s(L"\n RH index finger\n"); break; case WINBIO_ANSI_381_POS_RH_MIDDLE_FINGER: wprintf_s(L"\n RH middle finger\n"); break; case WINBIO_ANSI_381_POS_RH_RING_FINGER: wprintf_s(L"\n RH ring finger\n"); break; case WINBIO_ANSI_381_POS_RH_LITTLE_FINGER: wprintf_s(L"\n RH little finger\n"); break; case WINBIO_ANSI_381_POS_LH_THUMB: wprintf_s(L"\n LH thumb\n"); break; case WINBIO_ANSI_381_POS_LH_INDEX_FINGER: wprintf_s(L"\n LH index finger\n"); break; case WINBIO_ANSI_381_POS_LH_MIDDLE_FINGER: wprintf_s(L"\n LH middle finger\n"); break; case WINBIO_ANSI_381_POS_LH_RING_FINGER: wprintf_s(L"\n LH ring finger\n"); break; case WINBIO_ANSI_381_POS_LH_LITTLE_FINGER: wprintf_s(L"\n LH little finger\n"); break; default: wprintf_s(L"\n The sub-factor is not correct\n"); break; } } e_Exit: if (subFactorArray!= NULL) { WinBioFree(subFactorArray); subFactorArray = NULL; } if (sessionHandle != NULL) { WinBioCloseSession(sessionHandle); sessionHandle = NULL; } wprintf_s(L"\n Press any key to exit..."); _getch(); return hr; }</code>
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winbio/nf-winbio-winbioclosesession HRESULT WinBioCloseSession(
// WINBIO_SESSION_HANDLE SessionHandle );
[DllImport(Lib_Winbio, SetLastError = false, ExactSpelling = true)]
[PInvokeData("winbio.h", MSDNShortId = "NF:winbio.WinBioCloseSession")]
public static extern HRESULT WinBioCloseSession(WINBIO_SESSION_HANDLE SessionHandle);
/// <summary>
/// Allows the caller to perform vendor-defined control operations on a biometric unit. Starting with Windows 10, build 1607, this
/// function is available to use with a mobile image. This function is provided for access to extended vendor operations for which
/// elevated privileges are not required. If access rights are required, call the WinBioControlUnitPrivileged function.
/// </summary>
/// <param name="SessionHandle">
/// A <c>WINBIO_SESSION_HANDLE</c> value that identifies an open biometric session. Open a synchronous session handle by calling
/// WinBioOpenSession. Open an asynchronous session handle by calling WinBioAsyncOpenSession.
/// </param>
/// <param name="UnitId">
/// A <c>WINBIO_UNIT_ID</c> value that identifies the biometric unit. This value must correspond to the unit ID used previously in
/// the WinBioLockUnit function.
/// </param>
/// <param name="Component">
/// <para>
/// A <c>WINBIO_COMPONENT</c> value that specifies the component within the biometric unit that should perform the operation. This
/// can be one of the following values.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>WINBIO_COMPONENT_SENSOR</term>
/// <term>Send the command to the sensor adapter.</term>
/// </item>
/// <item>
/// <term>WINBIO_COMPONENT_ENGINE</term>
/// <term>Send the command to the engine adapter.</term>
/// </item>
/// <item>
/// <term>WINBIO_COMPONENT_STORAGE</term>
/// <term>Send the command to the storage adapter.</term>
/// </item>
/// </list>
/// </param>
/// <param name="ControlCode">
/// A vendor-defined code recognized by the biometric unit specified by the UnitId parameter and the adapter specified by the
/// Component parameter.
/// </param>
/// <param name="SendBuffer">
/// Address of the buffer that contains the control information to be sent to the adapter specified by the Component parameter. The
/// format and content of the buffer is vendor-defined.
/// </param>
/// <param name="SendBufferSize">Size, in bytes, of the buffer specified by the SendBuffer parameter.</param>
/// <param name="ReceiveBuffer">
/// Address of the buffer that receives information sent by the adapter specified by the Component parameter. The format and content
/// of the buffer is vendor-defined.
/// </param>
/// <param name="ReceiveBufferSize">Size, in bytes, of the buffer specified by the ReceiveBuffer parameter.</param>
/// <param name="ReceiveDataSize">
/// Pointer to a <c>SIZE_T</c> value that contains the size, in bytes, of the data written to the buffer specified by the
/// ReceiveBuffer parameter.
/// </param>
/// <param name="OperationStatus">
/// Pointer to an integer that contains a vendor-defined status code that specifies the outcome of the control operation.
/// </param>
/// <returns>
/// <para>
/// If the function succeeds, it returns S_OK. If the function fails, it returns an <c>HRESULT</c> value that indicates the error.
/// Possible values include, but are not limited to, those in the following table. For a list of common error codes, see Common
/// HRESULT Values.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>E_HANDLE</term>
/// <term>The session handle is not valid.</term>
/// </item>
/// <item>
/// <term>E_INVALIDARG</term>
/// <term>The value specified in the ControlCode parameter is not recognized.</term>
/// </item>
/// <item>
/// <term>E_POINTER</term>
/// <term>The SendBuffer, ReceiveBuffer, ReceiveDataSize, OperationStatus parameters cannot be NULL.</term>
/// </item>
/// <item>
/// <term>WINBIO_E_INVALID_CONTROL_CODE</term>
/// <term>The value specified in the ControlCode parameter is not recognized.</term>
/// </item>
/// <item>
/// <term>WINBIO_E_LOCK_VIOLATION</term>
/// <term>The biometric unit specified by the UnitId parameter must be locked before any control operations can be performed.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// You must call WinBioLockUnit before calling <c>WinBioControlUnit</c>. The <c>WinBioLockUnit</c> function creates a locked region
/// in which vendor-defined operations can be securely performed.
/// </para>
/// <para>
/// Vendors who create plug-ins must decide which extended operations are privileged and which are available to all clients. To
/// perform a privileged operation, the client application must call the WinBioControlUnitPrivileged function. The Windows Biometric
/// Framework allows only clients that have the appropriate access rights to call <c>WinBioControlUnitPrivileged</c>.
/// </para>
/// <para>
/// To use <c>WinBioControlUnit</c> synchronously, call the function with a session handle created by calling WinBioOpenSession. The
/// function blocks until the operation completes or an error is encountered.
/// </para>
/// <para>
/// To use <c>WinBioControlUnit</c> asynchronously, call the function with a session handle created by calling
/// WinBioAsyncOpenSession. The framework allocates a WINBIO_ASYNC_RESULT structure and uses it to return information about
/// operation success or failure. The <c>WINBIO_ASYNC_RESULT</c> structure is returned to the application callback or to the
/// application message queue, depending on the value you set in the NotificationMethod parameter of the
/// <c>WinBioAsyncOpenSession</c> function.
/// </para>
/// <list type="bullet">
/// <item>
/// <term>
/// If you choose to receive completion notices by using a callback, you must implement a PWINBIO_ASYNC_COMPLETION_CALLBACK function
/// and set the NotificationMethod parameter to <c>WINBIO_ASYNC_NOTIFY_CALLBACK</c>.
/// </term>
/// </item>
/// <item>
/// <term>
/// If you choose to receive completion notices by using the application message queue, you must set the NotificationMethod
/// parameter to <c>WINBIO_ASYNC_NOTIFY_MESSAGE</c>. The framework returns a WINBIO_ASYNC_RESULT pointer to the <c>LPARAM</c> field
/// of the window message.
/// </term>
/// </item>
/// </list>
/// <para>
/// To prevent memory leaks, you must call WinBioFree to release the WINBIO_ASYNC_RESULT structure after you have finished using it.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winbio/nf-winbio-winbiocontrolunit HRESULT WinBioControlUnit(
// WINBIO_SESSION_HANDLE SessionHandle, WINBIO_UNIT_ID UnitId, WINBIO_COMPONENT Component, ULONG ControlCode, PUCHAR SendBuffer,
// SIZE_T SendBufferSize, PUCHAR ReceiveBuffer, SIZE_T ReceiveBufferSize, SIZE_T *ReceiveDataSize, ULONG *OperationStatus );
[DllImport(Lib_Winbio, SetLastError = false, ExactSpelling = true)]
[PInvokeData("winbio.h", MSDNShortId = "NF:winbio.WinBioControlUnit")]
public static extern HRESULT WinBioControlUnit(WINBIO_SESSION_HANDLE SessionHandle, WINBIO_UNIT_ID UnitId, WINBIO_COMPONENT Component, uint ControlCode,
[In] IntPtr SendBuffer, SizeT SendBufferSize, [Out] IntPtr ReceiveBuffer, SizeT ReceiveBufferSize,
out SizeT ReceiveDataSize, out uint OperationStatus);
/// <summary>
/// Allows the caller to perform privileged vendor-defined control operations on a biometric unit. Starting with Windows 10, build
/// 1607, this function is available to use with a mobile image. The client must call this function to perform extended vendor
/// operations that require elevated access rights. If no privileges are required, the client can call the WinBioControlUnit function.
/// </summary>
/// <param name="SessionHandle">
/// A <c>WINBIO_SESSION_HANDLE</c> value that identifies an open biometric session. Open a synchronous session handle by calling
/// WinBioOpenSession. Open an asynchronous session handle by calling WinBioAsyncOpenSession.
/// </param>
/// <param name="UnitId">
/// A <c>WINBIO_UNIT_ID</c> value that identifies the biometric unit. This value must correspond to the unit ID used previously in
/// the WinBioLockUnit function.
/// </param>
/// <param name="Component">
/// <para>
/// A <c>WINBIO_COMPONENT</c> value that specifies the component within the biometric unit that should perform the operation. This
/// can be one of the following values.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>WINBIO_COMPONENT_SENSOR</term>
/// <term>Send the command to the sensor adapter.</term>
/// </item>
/// <item>
/// <term>WINBIO_COMPONENT_ENGINE</term>
/// <term>Send the command to the engine adapter.</term>
/// </item>
/// <item>
/// <term>WINBIO_COMPONENT_STORAGE</term>
/// <term>Send the command to the storage adapter.</term>
/// </item>
/// </list>
/// </param>
/// <param name="ControlCode">
/// A vendor-defined code recognized by the biometric unit specified by the UnitId parameter and the adapter specified by the
/// Component parameter.
/// </param>
/// <param name="SendBuffer">
/// Address of the buffer that contains the control information to be sent to the adapter specified by the Component parameter. The
/// format and content of the buffer is vendor-defined.
/// </param>
/// <param name="SendBufferSize">Size, in bytes, of the buffer specified by the SendBuffer parameter.</param>
/// <param name="ReceiveBuffer">
/// Address of the buffer that receives information sent by the adapter specified by the Component parameter. The format and content
/// of the buffer is vendor-defined.
/// </param>
/// <param name="ReceiveBufferSize">Size, in bytes, of the buffer specified by the ReceiveBuffer parameter.</param>
/// <param name="ReceiveDataSize">
/// Pointer to a <c>SIZE_T</c> value that contains the size, in bytes, of the data written to the buffer specified by the
/// ReceiveBuffer parameter.
/// </param>
/// <param name="OperationStatus">
/// Pointer to an integer that contains a vendor-defined status code that specifies the outcome of the control operation.
/// </param>
/// <returns>
/// <para>
/// If the function succeeds, it returns S_OK. If the function fails, it returns an <c>HRESULT</c> value that indicates the error.
/// Possible values include, but are not limited to, those in the following table. For a list of common error codes, see Common
/// HRESULT Values.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>E_HANDLE</term>
/// <term>The session handle is not valid.</term>
/// </item>
/// <item>
/// <term>E_INVALIDARG</term>
/// <term>The value specified in the ControlCode parameter is not recognized.</term>
/// </item>
/// <item>
/// <term>E_POINTER</term>
/// <term>The SendBuffer, ReceiveBuffer, ReceiveDataSize, OperationStatus parameters cannot be NULL.</term>
/// </item>
/// <item>
/// <term>E_ACCESSDENIED</term>
/// <term>The caller does not have permission to perform the operation, or the session was not opened by using WINBIO_FLAG_MAINTENANCE.</term>
/// </item>
/// <item>
/// <term>E_INVALIDARG</term>
/// <term>The value specified in the ControlCode parameter is not recognized.</term>
/// </item>
/// <item>
/// <term>WINBIO_E_LOCK_VIOLATION</term>
/// <term>The biometric unit specified by the UnitId parameter must be locked before any control operations can be performed.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// Vendors who create plug-ins must decide which extended operations are privileged and which are available to all clients. To
/// perform a privileged operation, the client application must call the <c>WinBioControlUnitPrivileged</c> function. The Windows
/// Biometric Framework allows only clients that have the appropriate access rights to call this function. To perform an operation
/// that does not require privileges, the client should call the WinBioControlUnit function.
/// </para>
/// <para>
/// You must call WinBioLockUnit before calling <c>WinBioControlUnitPrivileged</c>. The <c>WinBioLockUnit</c> function creates a
/// locked region in which vendor-defined operations can be securely performed.
/// </para>
/// <para>
/// To call this function successfully, the session handle must have been opened by specifying <c>WINBIO_FLAG_MAINTENANCE</c>. Only
/// the Administrators and Local System accounts have the necessary privileges.
/// </para>
/// <para>
/// To use <c>WinBioControlUnitPrivileged</c> synchronously, call the function with a session handle created by calling
/// WinBioOpenSession. The function blocks until the operation completes or an error is encountered.
/// </para>
/// <para>
/// To use <c>WinBioControlUnitPrivileged</c> asynchronously, call the function with a session handle created by calling
/// WinBioAsyncOpenSession. The framework allocates a WINBIO_ASYNC_RESULT structure and uses it to return information about
/// operation success or failure. The <c>WINBIO_ASYNC_RESULT</c> structure is returned to the application callback or to the
/// application message queue, depending on the value you set in the NotificationMethod parameter of the
/// <c>WinBioAsyncOpenSession</c> function.
/// </para>
/// <list type="bullet">
/// <item>
/// <term>
/// If you choose to receive completion notices by using a callback, you must implement a PWINBIO_ASYNC_COMPLETION_CALLBACK function
/// and set the NotificationMethod parameter to <c>WINBIO_ASYNC_NOTIFY_CALLBACK</c>.
/// </term>
/// </item>
/// <item>
/// <term>
/// If you choose to receive completion notices by using the application message queue, you must set the NotificationMethod
/// parameter to <c>WINBIO_ASYNC_NOTIFY_MESSAGE</c>. The framework returns a WINBIO_ASYNC_RESULT pointer to the <c>LPARAM</c> field
/// of the window message.
/// </term>
/// </item>
/// </list>
/// <para>
/// To prevent memory leaks, you must call WinBioFree to release the WINBIO_ASYNC_RESULT structure after you have finished using it.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winbio/nf-winbio-winbiocontrolunitprivileged HRESULT
// WinBioControlUnitPrivileged( WINBIO_SESSION_HANDLE SessionHandle, WINBIO_UNIT_ID UnitId, WINBIO_COMPONENT Component, ULONG
// ControlCode, PUCHAR SendBuffer, SIZE_T SendBufferSize, PUCHAR ReceiveBuffer, SIZE_T ReceiveBufferSize, SIZE_T *ReceiveDataSize,
// ULONG *OperationStatus );
[DllImport(Lib_Winbio, SetLastError = false, ExactSpelling = true)]
[PInvokeData("winbio.h", MSDNShortId = "NF:winbio.WinBioControlUnitPrivileged")]
public static extern HRESULT WinBioControlUnitPrivileged(WINBIO_SESSION_HANDLE SessionHandle, WINBIO_UNIT_ID UnitId, WINBIO_COMPONENT Component,
uint ControlCode, [In] IntPtr SendBuffer, SizeT SendBufferSize, [Out] IntPtr ReceiveBuffer, SizeT ReceiveBufferSize,
out SizeT ReceiveDataSize, out uint OperationStatus);
/// <summary>
/// Deletes a biometric template from the template store. Starting with Windows 10, build 1607, this function is available to use
/// with a mobile image.
/// </summary>
/// <param name="SessionHandle">
/// A <c>WINBIO_SESSION_HANDLE</c> value that identifies an open biometric session. Open a synchronous session handle by calling
/// WinBioOpenSession. Open an asynchronous session handle by calling WinBioAsyncOpenSession.
/// </param>
/// <param name="UnitId">A <c>WINBIO_UNIT_ID</c> value that identifies the biometric unit where the template is located.</param>
/// <param name="Identity">
/// Pointer to a WINBIO_IDENTITY structure that contains the GUID or SID of the template to be deleted. If the <c>Type</c> member of
/// the <c>WINBIO_IDENTITY</c> structure is <c>WINBIO_ID_TYPE_WILDCARD</c>, templates matching the SubFactor parameter will be
/// deleted for all identities. Only administrators can perform wildcard identity deletion.
/// </param>
/// <param name="SubFactor">
/// A <c>WINBIO_BIOMETRIC_SUBTYPE</c> value that provides additional information about the template to be deleted. If you specify
/// WINBIO_SUBTYPE_ANY, all templates for the biometric unit specified by the UnitId parameter are deleted.
/// </param>
/// <returns>
/// <para>
/// If the function succeeds, it returns S_OK. If the function fails, it returns an <c>HRESULT</c> value that indicates the error.
/// Possible values include, but are not limited to, those in the following table. For a list of common error codes, see Common
/// HRESULT Values.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>E_HANDLE</term>
/// <term>The session handle is not valid.</term>
/// </item>
/// <item>
/// <term>E_INVALIDARG</term>
/// <term>The UnitId parameter contains zero or the SubFactor contains WINBIO_SUBTYPE_NO_INFORMATION.</term>
/// </item>
/// <item>
/// <term>E_POINTER</term>
/// <term>The pointer specified in the Identity parameter cannot be NULL.</term>
/// </item>
/// <item>
/// <term>WINBIO_E_ENROLLMENT_IN_PROGRESS</term>
/// <term>The operation could not be completed because the biometric unit is currently being used for an enrollment transaction.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// To use <c>WinBioDeleteTemplate</c> synchronously, call the function with a session handle created by calling WinBioOpenSession.
/// The function blocks until the operation completes or an error is encountered.
/// </para>
/// <para>
/// To use <c>WinBioDeleteTemplate</c> asynchronously, call the function with a session handle created by calling
/// WinBioAsyncOpenSession. The framework allocates a WINBIO_ASYNC_RESULT structure and uses it to return information about
/// operation success or failure. If the deletion operation is successful, the framework returns <c>WINBIO_IDENTITY</c> and
/// <c>WINBIO_BIOMETRIC_SUBTYPE</c> information in a nested <c>DeleteTemplate</c> structure. If the operation is unsuccessful, the
/// framework returns error information. The <c>WINBIO_ASYNC_RESULT</c> structure is returned to the application callback or to the
/// application message queue, depending on the value you set in the NotificationMethod parameter of the
/// <c>WinBioAsyncOpenSession</c> function:
/// </para>
/// <list type="bullet">
/// <item>
/// <term>
/// If you choose to receive completion notices by using a callback, you must implement a PWINBIO_ASYNC_COMPLETION_CALLBACK function
/// and set the NotificationMethod parameter to <c>WINBIO_ASYNC_NOTIFY_CALLBACK</c>.
/// </term>
/// </item>
/// <item>
/// <term>
/// If you choose to receive completion notices by using the application message queue, you must set the NotificationMethod
/// parameter to <c>WINBIO_ASYNC_NOTIFY_MESSAGE</c>. The framework returns a WINBIO_ASYNC_RESULT pointer to the <c>LPARAM</c> field
/// of the window message.
/// </term>
/// </item>
/// </list>
/// <para>
/// To prevent memory leaks, you must call WinBioFree to release the WINBIO_ASYNC_RESULT structure after you have finished using it.
/// </para>
/// <para>Examples</para>
/// <para>
/// The following code example calls <c>WinBioDeleteTemplate</c> to delete a specific biometric template. Link to the Winbio.lib
/// static library and include the following header files:
/// </para>
/// <list type="bullet">
/// <item>
/// <term>Windows.h</term>
/// </item>
/// <item>
/// <term>Stdio.h</term>
/// </item>
/// <item>
/// <term>Conio.h</term>
/// </item>
/// <item>
/// <term>Winbio.h</term>
/// </item>
/// </list>
/// <para>
/// <code>HRESULT DeleteTemplate(WINBIO_BIOMETRIC_SUBTYPE subFactor) { HRESULT hr = S_OK; WINBIO_IDENTITY identity = {0}; WINBIO_SESSION_HANDLE sessionHandle = NULL; WINBIO_UNIT_ID unitId = 0; // Find the identity of the user. hr = GetCurrentUserIdentity( &amp;identity ); if (FAILED(hr)) { wprintf_s(L"\n User identity not found. hr = 0x%x\n", hr); goto e_Exit; } // Connect to the system pool. // hr = WinBioOpenSession( WINBIO_TYPE_FINGERPRINT, // Service provider WINBIO_POOL_SYSTEM, // Pool type WINBIO_FLAG_DEFAULT, // Configuration and access NULL, // Array of biometric unit IDs 0, // Count of biometric unit IDs NULL, // Database ID &amp;sessionHandle // [out] Session handle ); if (FAILED(hr)) { wprintf_s(L"\n WinBioEnumBiometricUnits failed. hr = 0x%x\n", hr); goto e_Exit; } // Locate the sensor. // wprintf_s(L"\n Swipe your finger on the sensor...\n"); hr = WinBioLocateSensor( sessionHandle, &amp;unitId); if (FAILED(hr)) { wprintf_s(L"\n WinBioLocateSensor failed. hr = 0x%x\n", hr); goto e_Exit; } // Delete the template identified by the subFactor argument. // hr = WinBioDeleteTemplate( sessionHandle, unitId, &amp;identity, subFactor ); if (FAILED(hr)) { wprintf_s(L"\n WinBioDeleteTemplate failed. hr = 0x%x\n", hr); goto e_Exit; } e_Exit: if (sessionHandle != NULL) { WinBioCloseSession(sessionHandle); sessionHandle = NULL; } wprintf_s(L"Press any key to exit..."); _getch(); return hr; } //------------------------------------------------------------------------ // The following function retrieves the identity of the current user. // This is a helper function and is not part of the Windows Biometric // Framework API. // HRESULT GetCurrentUserIdentity(__inout PWINBIO_IDENTITY Identity) { // Declare variables. HRESULT hr = S_OK; HANDLE tokenHandle = NULL; DWORD bytesReturned = 0; struct{ TOKEN_USER tokenUser; BYTE buffer[SECURITY_MAX_SID_SIZE]; } tokenInfoBuffer; // Zero the input identity and specify the type. ZeroMemory( Identity, sizeof(WINBIO_IDENTITY)); Identity-&gt;Type = WINBIO_ID_TYPE_NULL; // Open the access token associated with the // current process if (!OpenProcessToken( GetCurrentProcess(), // Process handle TOKEN_READ, // Read access only &amp;tokenHandle)) // Access token handle { DWORD win32Status = GetLastError(); wprintf_s(L"Cannot open token handle: %d\n", win32Status); hr = HRESULT_FROM_WIN32(win32Status); goto e_Exit; } // Zero the tokenInfoBuffer structure. ZeroMemory(&amp;tokenInfoBuffer, sizeof(tokenInfoBuffer)); // Retrieve information about the access token. In this case, // retrieve a SID. if (!GetTokenInformation( tokenHandle, // Access token handle TokenUser, // User for the token &amp;tokenInfoBuffer.tokenUser, // Buffer to fill sizeof(tokenInfoBuffer), // Size of the buffer &amp;bytesReturned)) // Size needed { DWORD win32Status = GetLastError(); wprintf_s(L"Cannot query token information: %d\n", win32Status); hr = HRESULT_FROM_WIN32(win32Status); goto e_Exit; } // Copy the SID from the tokenInfoBuffer structure to the // WINBIO_IDENTITY structure. CopySid( SECURITY_MAX_SID_SIZE, Identity-&gt;Value.AccountSid.Data, tokenInfoBuffer.tokenUser.User.Sid ); // Specify the size of the SID and assign WINBIO_ID_TYPE_SID // to the type member of the WINBIO_IDENTITY structure. Identity-&gt;Value.AccountSid.Size = GetLengthSid(tokenInfoBuffer.tokenUser.User.Sid); Identity-&gt;Type = WINBIO_ID_TYPE_SID; e_Exit: if (tokenHandle != NULL) { CloseHandle(tokenHandle); } return hr; }</code>
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winbio/nf-winbio-winbiodeletetemplate HRESULT WinBioDeleteTemplate(
// WINBIO_SESSION_HANDLE SessionHandle, WINBIO_UNIT_ID UnitId, WINBIO_IDENTITY *Identity, WINBIO_BIOMETRIC_SUBTYPE SubFactor );
[DllImport(Lib_Winbio, SetLastError = true, ExactSpelling = true)]
[PInvokeData("winbio.h", MSDNShortId = "NF:winbio.WinBioDeleteTemplate")]
public static extern HRESULT WinBioDeleteTemplate(WINBIO_SESSION_HANDLE SessionHandle, WINBIO_UNIT_ID UnitId, in WINBIO_IDENTITY Identity, WINBIO_BIOMETRIC_SUBTYPE SubFactor);
/// <summary>
/// Initiates a biometric enrollment sequence and creates an empty biometric template. Starting with Windows 10, build 1607, this
/// function is available to use with a mobile image.
/// </summary>
/// <param name="SessionHandle">
/// A <c>WINBIO_SESSION_HANDLE</c> value that identifies an open biometric session. Open a synchronous session handle by calling
/// WinBioOpenSession. Open an asynchronous session handle by calling WinBioAsyncOpenSession.
/// </param>
/// <param name="SubFactor">
/// <para>
/// A <c>WINBIO_BIOMETRIC_SUBTYPE</c> value that provides additional information about the enrollment. This must be one of the
/// following values:
/// </para>
/// <list type="bullet">
/// <item>
/// <term>WINBIO_ANSI_381_POS_RH_THUMB</term>
/// </item>
/// <item>
/// <term>WINBIO_ANSI_381_POS_RH_INDEX_FINGER</term>
/// </item>
/// <item>
/// <term>WINBIO_ANSI_381_POS_RH_MIDDLE_FINGER</term>
/// </item>
/// <item>
/// <term>WINBIO_ANSI_381_POS_RH_RING_FINGER</term>
/// </item>
/// <item>
/// <term>WINBIO_ANSI_381_POS_RH_LITTLE_FINGER</term>
/// </item>
/// <item>
/// <term>WINBIO_ANSI_381_POS_LH_THUMB</term>
/// </item>
/// <item>
/// <term>WINBIO_ANSI_381_POS_LH_INDEX_FINGER</term>
/// </item>
/// <item>
/// <term>WINBIO_ANSI_381_POS_LH_MIDDLE_FINGER</term>
/// </item>
/// <item>
/// <term>WINBIO_ANSI_381_POS_LH_RING_FINGER</term>
/// </item>
/// <item>
/// <term>WINBIO_ANSI_381_POS_LH_LITTLE_FINGER</term>
/// </item>
/// <item>
/// <term>WINBIO_ANSI_381_POS_RH_FOUR_FINGERS</term>
/// </item>
/// <item>
/// <term>WINBIO_ANSI_381_POS_LH_FOUR_FINGERS</term>
/// </item>
/// </list>
/// </param>
/// <param name="UnitId">
/// A <c>WINBIO_UNIT_ID</c> value that identifies the biometric unit. This value cannot be zero. You can find a unit ID by calling
/// the WinBioEnumBiometricUnits or WinBioLocateSensor functions.
/// </param>
/// <returns>
/// <para>
/// If the function succeeds, it returns S_OK. If the function fails, it returns an <c>HRESULT</c> value that indicates the error.
/// Possible values include, but are not limited to, those in the following table. For a list of common error codes, see Common
/// HRESULT Values.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>E_ACCESSDENIED</term>
/// <term>The caller does not have permission to enroll.</term>
/// </item>
/// <item>
/// <term>E_HANDLE</term>
/// <term>The session handle is not valid.</term>
/// </item>
/// <item>
/// <term>E_INVALIDARG</term>
/// <term>
/// The SubFactor parameter cannot equal WINBIO_SUBTYPE_NO_INFORMATION or WINBIO_SUBTYPE_ANY, and the UnitId parameter cannot equal zero.
/// </term>
/// </item>
/// <item>
/// <term>WINBIO_E_ENROLLMENT_IN_PROGRESS</term>
/// <term>An enrollment operation is already in progress, and only one enrollment can occur at a given time.</term>
/// </item>
/// <item>
/// <term>WINBIO_E_LOCK_VIOLATION</term>
/// <term>The biometric unit is in use and is locked.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// A single biometric enrollment requires the collection of multiple samples from a user. Only one enrollment operation can take
/// place at any time, and all of the biometric samples that apply to a single enrollment must be generated by the same sensor. This
/// sensor is specified by the UnitId parameter.
/// </para>
/// <para>
/// Any application that enrolls by using a biometric unit in the system pool must have window focus when it calls
/// <c>WinBioEnrollBegin</c>. If it does not, the call blocks until the application acquires window focus and the user has provided
/// a biometric sample. We recommend, therefore, that your application not call <c>WinBioEnrollBegin</c> until it has acquired
/// focus. The manner in which you acquire focus depends on the type of application you are writing. For example, if you are
/// creating a GUI application you can implement a message handler that captures a WM_ACTIVATE, WM_SETFOCUS, or other appropriate
/// message. If you are writing a CUI application, call <c>GetConsoleWindow</c> to retrieve a handle to the console window and pass
/// that handle to the <c>SetForegroundWindow</c> function to force the console window into the foreground and assign it focus. If
/// your application is running in a detached process and has no window or is a Windows service, use WinBioAcquireFocus and
/// WinBioReleaseFocus to manually control focus.
/// </para>
/// <para>
/// To use <c>WinBioEnrollBegin</c> synchronously, call the function with a session handle created by calling WinBioOpenSession. The
/// function blocks until the operation completes or an error is encountered.
/// </para>
/// <para>
/// To use <c>WinBioEnrollBegin</c> asynchronously, call the function with a session handle created by calling
/// WinBioAsyncOpenSession. The framework allocates a WINBIO_ASYNC_RESULT structure and uses it to return information about
/// operation success or failure. If the operation is successful, the framework returns <c>WINBIO_BIOMETRIC_SUBTYPE</c> information
/// in a nested <c>EnrollBegin</c> structure. If the operation is unsuccessful, the framework returns error information. The
/// <c>WINBIO_ASYNC_RESULT</c> structure is returned to the application callback or to the application message queue, depending on
/// the value you set in the NotificationMethod parameter of the <c>WinBioAsyncOpenSession</c> function:
/// </para>
/// <list type="bullet">
/// <item>
/// <term>
/// If you choose to receive completion notices by using a callback, you must implement a PWINBIO_ASYNC_COMPLETION_CALLBACK function
/// and set the NotificationMethod parameter to <c>WINBIO_ASYNC_NOTIFY_CALLBACK</c>.
/// </term>
/// </item>
/// <item>
/// <term>
/// If you choose to receive completion notices by using the application message queue, you must set the NotificationMethod
/// parameter to <c>WINBIO_ASYNC_NOTIFY_MESSAGE</c>. The framework returns a WINBIO_ASYNC_RESULT pointer to the <c>LPARAM</c> field
/// of the window message.
/// </term>
/// </item>
/// </list>
/// <para>
/// To prevent memory leaks, you must call WinBioFree to release the WINBIO_ASYNC_RESULT structure after you have finished using it.
/// </para>
/// <para>Examples</para>
/// <para>
/// The following function enrolls a biometric template in the system pool. It calls <c>WinBioEnrollBegin</c> to start the
/// enrollment sequence. Link to the Winbio.lib static library and include the following header files:
/// </para>
/// <list type="bullet">
/// <item>
/// <term>Windows.h</term>
/// </item>
/// <item>
/// <term>Stdio.h</term>
/// </item>
/// <item>
/// <term>Conio.h</term>
/// </item>
/// <item>
/// <term>Winbio.h</term>
/// </item>
/// </list>
/// <para>
/// <code>HRESULT EnrollSysPool( BOOL discardEnrollment, WINBIO_BIOMETRIC_SUBTYPE subFactor) { HRESULT hr = S_OK; WINBIO_IDENTITY identity = {0}; WINBIO_SESSION_HANDLE sessionHandle = NULL; WINBIO_UNIT_ID unitId = 0; WINBIO_REJECT_DETAIL rejectDetail = 0; BOOLEAN isNewTemplate = TRUE; // Connect to the system pool. hr = WinBioOpenSession( WINBIO_TYPE_FINGERPRINT, // Service provider WINBIO_POOL_SYSTEM, // Pool type WINBIO_FLAG_DEFAULT, // Configuration and access NULL, // Array of biometric unit IDs 0, // Count of biometric unit IDs NULL, // Database ID &amp;sessionHandle // [out] Session handle ); if (FAILED(hr)) { wprintf_s(L"\n WinBioOpenSession failed. "); wprintf_s(L"hr = 0x%x\n", hr); goto e_Exit; } // Locate a sensor. wprintf_s(L"\n Swipe your finger on the sensor...\n"); hr = WinBioLocateSensor( sessionHandle, &amp;unitId); if (FAILED(hr)) { wprintf_s(L"\n WinBioLocateSensor failed. hr = 0x%x\n", hr); goto e_Exit; } // Begin the enrollment sequence. wprintf_s(L"\n Starting enrollment sequence...\n"); hr = WinBioEnrollBegin( sessionHandle, // Handle to open biometric session subFactor, // Finger to create template for unitId // Biometric unit ID ); if (FAILED(hr)) { wprintf_s(L"\n WinBioEnrollBegin failed. hr = 0x%x\n", hr); goto e_Exit; } // Capture enrollment information by swiping the sensor with // the finger identified by the subFactor argument in the // WinBioEnrollBegin function. for (int swipeCount = 1;; ++swipeCount) { wprintf_s(L"\n Swipe the sensor to capture %s sample.", (swipeCount == 1)?L"the first":L"another"); hr = WinBioEnrollCapture( sessionHandle, // Handle to open biometric session &amp;rejectDetail // [out] Failure information ); wprintf_s(L"\n Sample %d captured from unit number %d.", swipeCount, unitId); if (hr == WINBIO_I_MORE_DATA) { wprintf_s(L"\n More data required.\n"); continue; } if (FAILED(hr)) { if (hr == WINBIO_E_BAD_CAPTURE) { wprintf_s(L"\n Error: Bad capture; reason: %d", rejectDetail); continue; } else { wprintf_s(L"\n WinBioEnrollCapture failed. hr = 0x%x", hr); goto e_Exit; } } else { wprintf_s(L"\n Template completed.\n"); break; } } // Discard the enrollment if the appropriate flag is set. // Commit the enrollment if it is not discarded. if (discardEnrollment == TRUE) { wprintf_s(L"\n Discarding enrollment...\n\n"); hr = WinBioEnrollDiscard( sessionHandle ); if (FAILED(hr)) { wprintf_s(L"\n WinBioLocateSensor failed. hr = 0x%x\n", hr); } goto e_Exit; } else { wprintf_s(L"\n Committing enrollment...\n"); hr = WinBioEnrollCommit( sessionHandle, // Handle to open biometric session &amp;identity, // WINBIO_IDENTITY object for the user &amp;isNewTemplate); // Is this a new template if (FAILED(hr)) { wprintf_s(L"\n WinBioEnrollCommit failed. hr = 0x%x\n", hr); goto e_Exit; } } e_Exit: if (sessionHandle != NULL) { WinBioCloseSession(sessionHandle); sessionHandle = NULL; } wprintf_s(L" Press any key to continue..."); _getch(); return hr; }</code>
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winbio/nf-winbio-winbioenrollbegin HRESULT WinBioEnrollBegin(
// WINBIO_SESSION_HANDLE SessionHandle, WINBIO_BIOMETRIC_SUBTYPE SubFactor, WINBIO_UNIT_ID UnitId );
[DllImport(Lib_Winbio, SetLastError = false, ExactSpelling = true)]
[PInvokeData("winbio.h", MSDNShortId = "NF:winbio.WinBioEnrollBegin")]
public static extern HRESULT WinBioEnrollBegin(WINBIO_SESSION_HANDLE SessionHandle, WINBIO_BIOMETRIC_SUBTYPE SubFactor, WINBIO_UNIT_ID UnitId);
/// <summary>
/// Captures a biometric sample and adds it to a template. Starting with Windows 10, build 1607, this function is available to use
/// with a mobile image.
/// </summary>
/// <param name="SessionHandle">
/// A <c>WINBIO_SESSION_HANDLE</c> value that identifies an open biometric session. Open a synchronous session handle by calling
/// WinBioOpenSession. Open an asynchronous session handle by calling WinBioAsyncOpenSession.
/// </param>
/// <param name="RejectDetail">
/// <para>
/// A pointer to a <c>ULONG</c> value that contains additional information the failure to capture a biometric sample. If the capture
/// succeeded, this parameter is set to zero. The following values are defined for fingerprint capture:
/// </para>
/// <list type="bullet">
/// <item>
/// <term>WINBIO_FP_TOO_HIGH</term>
/// </item>
/// <item>
/// <term>WINBIO_FP_TOO_LOW</term>
/// </item>
/// <item>
/// <term>WINBIO_FP_TOO_LEFT</term>
/// </item>
/// <item>
/// <term>WINBIO_FP_TOO_RIGHT</term>
/// </item>
/// <item>
/// <term>WINBIO_FP_TOO_FAST</term>
/// </item>
/// <item>
/// <term>WINBIO_FP_TOO_SLOW</term>
/// </item>
/// <item>
/// <term>WINBIO_FP_POOR_QUALITY</term>
/// </item>
/// <item>
/// <term>WINBIO_FP_TOO_SKEWED</term>
/// </item>
/// <item>
/// <term>WINBIO_FP_TOO_SHORT</term>
/// </item>
/// <item>
/// <term>WINBIO_FP_MERGE_FAILURE</term>
/// </item>
/// </list>
/// </param>
/// <returns>
/// <para>
/// If the function succeeds, it returns S_OK. If the function fails, it returns an <c>HRESULT</c> value that indicates the error.
/// Possible values include, but are not limited to, those in the following table. For a list of common error codes, see Common
/// HRESULT Values.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>E_ACCESSDENIED</term>
/// <term>The calling account is not allowed to perform enrollment.</term>
/// </item>
/// <item>
/// <term>E_HANDLE</term>
/// <term>The session handle is not valid.</term>
/// </item>
/// <item>
/// <term>E_POINTER</term>
/// <term>The pointer specified by the RejectDetail parameter cannot be NULL.</term>
/// </item>
/// <item>
/// <term>WINBIO_E_BAD_CAPTURE</term>
/// <term>The sample could not be captured. Use the RejectDetail value for more information.</term>
/// </item>
/// <item>
/// <term>WINBIO_E_LOCK_VIOLATION</term>
/// <term>The biometric unit is in use and is locked.</term>
/// </item>
/// <item>
/// <term>WINBIO_I_MORE_DATA</term>
/// <term>
/// The matching engine requires one or more additional samples to generate a reliable template. You should update instructions to
/// the user to submit more samples and call WinBioEnrollCapture again.
/// </term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// Any application that enrolls by using a biometric unit in the system pool must have window focus when it calls
/// WinBioEnrollBegin. If it does not, the call blocks until the application acquires window focus and the user has provided a
/// biometric sample. We recommend, therefore, that your application not call <c>WinBioEnrollBegin</c> until it has acquired focus.
/// The manner in which you acquire focus depends on the type of application you are writing. For example, if you are creating a GUI
/// application you can implement a message handler that captures a WM_ACTIVATE, WM_SETFOCUS, or other appropriate message. If you
/// are writing a CUI application, call <c>GetConsoleWindow</c> to retrieve a handle to the console window and pass that handle to
/// the <c>SetForegroundWindow</c> function to force the console window into the foreground and assign it focus. If your application
/// is running in a detached process and has no window or is a Windows service, use WinBioAcquireFocus and WinBioReleaseFocus to
/// manually control focus.
/// </para>
/// <para>
/// To use <c>WinBioEnrollCapture</c> synchronously, call the function with a session handle created by calling WinBioOpenSession.
/// The function blocks until the operation completes or an error is encountered.
/// </para>
/// <para>
/// To use <c>WinBioEnrollCapture</c> asynchronously, call the function with a session handle created by calling
/// WinBioAsyncOpenSession. The framework allocates a WINBIO_ASYNC_RESULT structure and uses it to return information about
/// operation success or failure. If the operation is unsuccessful, the framework returns <c>WINBIO_REJECT_DETAIL</c> information in
/// a nested <c>EnrollCapture</c> structure. The <c>WINBIO_ASYNC_RESULT</c> structure is returned to the application callback or to
/// the application message queue, depending on the value you set in the NotificationMethod parameter of the
/// <c>WinBioAsyncOpenSession</c> function:
/// </para>
/// <list type="bullet">
/// <item>
/// <term>
/// If you choose to receive completion notices by using a callback, you must implement a PWINBIO_ASYNC_COMPLETION_CALLBACK function
/// and set the NotificationMethod parameter to <c>WINBIO_ASYNC_NOTIFY_CALLBACK</c>.
/// </term>
/// </item>
/// <item>
/// <term>
/// If you choose to receive completion notices by using the application message queue, you must set the NotificationMethod
/// parameter to <c>WINBIO_ASYNC_NOTIFY_MESSAGE</c>. The framework returns a WINBIO_ASYNC_RESULT pointer to the <c>LPARAM</c> field
/// of the window message.
/// </term>
/// </item>
/// </list>
/// <para>
/// To prevent memory leaks, you must call WinBioFree from your callback implementation to release the WINBIO_ASYNC_RESULT structure
/// after you have finished using it.
/// </para>
/// <para>
/// <c>Windows 7:</c> You can perform this operation asynchronously by using the WinBioEnrollCaptureWithCallback function. The
/// function verifies the input arguments and returns immediately. If the input arguments are not valid, the function returns an
/// error code. Otherwise, the framework starts the operation on another thread. When the asynchronous operation completes or
/// encounters an error, the framework sends the results to the PWINBIO_ENROLL_CAPTURE_CALLBACK function implemented by your application.
/// </para>
/// <para>Examples</para>
/// <para>
/// The following function enrolls a biometric template in the system pool by calling <c>WinBioEnrollCapture</c>. Link to the
/// Winbio.lib static library and include the following header files:
/// </para>
/// <list type="bullet">
/// <item>
/// <term>Windows.h</term>
/// </item>
/// <item>
/// <term>Stdio.h</term>
/// </item>
/// <item>
/// <term>Conio.h</term>
/// </item>
/// <item>
/// <term>Winbio.h</term>
/// </item>
/// </list>
/// <para>
/// <code>HRESULT EnrollSysPool( BOOL discardEnrollment, WINBIO_BIOMETRIC_SUBTYPE subFactor) { HRESULT hr = S_OK; WINBIO_IDENTITY identity = {0}; WINBIO_SESSION_HANDLE sessionHandle = NULL; WINBIO_UNIT_ID unitId = 0; WINBIO_REJECT_DETAIL rejectDetail = 0; BOOLEAN isNewTemplate = TRUE; // Connect to the system pool. hr = WinBioOpenSession( WINBIO_TYPE_FINGERPRINT, // Service provider WINBIO_POOL_SYSTEM, // Pool type WINBIO_FLAG_DEFAULT, // Configuration and access NULL, // Array of biometric unit IDs 0, // Count of biometric unit IDs NULL, // Database ID &amp;sessionHandle // [out] Session handle ); if (FAILED(hr)) { wprintf_s(L"\n WinBioOpenSession failed. "); wprintf_s(L"hr = 0x%x\n", hr); goto e_Exit; } // Locate a sensor. wprintf_s(L"\n Swipe your finger on the sensor...\n"); hr = WinBioLocateSensor( sessionHandle, &amp;unitId); if (FAILED(hr)) { wprintf_s(L"\n WinBioLocateSensor failed. hr = 0x%x\n", hr); goto e_Exit; } // Begin the enrollment sequence. wprintf_s(L"\n Starting enrollment sequence...\n"); hr = WinBioEnrollBegin( sessionHandle, // Handle to open biometric session subFactor, // Finger to create template for unitId // Biometric unit ID ); if (FAILED(hr)) { wprintf_s(L"\n WinBioEnrollBegin failed. hr = 0x%x\n", hr); goto e_Exit; } // Capture enrollment information by swiping the sensor with // the finger identified by the subFactor argument in the // WinBioEnrollBegin function. for (int swipeCount = 1;; ++swipeCount) { wprintf_s(L"\n Swipe the sensor to capture %s sample.", (swipeCount == 1)?L"the first":L"another"); hr = WinBioEnrollCapture( sessionHandle, // Handle to open biometric session &amp;rejectDetail // [out] Failure information ); wprintf_s(L"\n Sample %d captured from unit number %d.", swipeCount, unitId); if (hr == WINBIO_I_MORE_DATA) { wprintf_s(L"\n More data required.\n"); continue; } if (FAILED(hr)) { if (hr == WINBIO_E_BAD_CAPTURE) { wprintf_s(L"\n Error: Bad capture; reason: %d", rejectDetail); continue; } else { wprintf_s(L"\n WinBioEnrollCapture failed. hr = 0x%x", hr); goto e_Exit; } } else { wprintf_s(L"\n Template completed.\n"); break; } } // Discard the enrollment if the appropriate flag is set. // Commit the enrollment if it is not discarded. if (discardEnrollment == TRUE) { wprintf_s(L"\n Discarding enrollment...\n\n"); hr = WinBioEnrollDiscard( sessionHandle ); if (FAILED(hr)) { wprintf_s(L"\n WinBioLocateSensor failed. hr = 0x%x\n", hr); } goto e_Exit; } else { wprintf_s(L"\n Committing enrollment...\n"); hr = WinBioEnrollCommit( sessionHandle, // Handle to open biometric session &amp;identity, // WINBIO_IDENTITY object for the user &amp;isNewTemplate); // Is this a new template if (FAILED(hr)) { wprintf_s(L"\n WinBioEnrollCommit failed. hr = 0x%x\n", hr); goto e_Exit; } } e_Exit: if (sessionHandle != NULL) { WinBioCloseSession(sessionHandle); sessionHandle = NULL; } wprintf_s(L" Press any key to continue..."); _getch(); return hr; }</code>
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winbio/nf-winbio-winbioenrollcapture HRESULT WinBioEnrollCapture(
// WINBIO_SESSION_HANDLE SessionHandle, WINBIO_REJECT_DETAIL *RejectDetail );
[DllImport(Lib_Winbio, SetLastError = false, ExactSpelling = true)]
[PInvokeData("winbio.h", MSDNShortId = "NF:winbio.WinBioEnrollCapture")]
public static extern HRESULT WinBioEnrollCapture(WINBIO_SESSION_HANDLE SessionHandle, out WINBIO_REJECT_DETAIL RejectDetail);
/// <summary>
/// <para>
/// Asynchronously captures a biometric sample and adds it to a template. The function returns immediately to the caller, performs
/// enrollment on a separate thread, and calls into an application-defined callback function to update operation status.
/// </para>
/// <para><c>Important</c>
/// <para></para>
/// We recommend that, beginning with Windows 8, you no longer use this function to start an asynchronous operation. Instead, do the following:
/// </para>
/// </summary>
/// <param name="SessionHandle">A <c>WINBIO_SESSION_HANDLE</c> value that identifies an open biometric session.</param>
/// <param name="EnrollCallback">
/// Address of a callback function that will be called by the <c>WinBioEnrollCaptureWithCallback</c> function when the capture
/// operation succeeds or fails. You must create the callback.
/// </param>
/// <param name="EnrollCallbackContext">
/// Pointer to an optional application-defined structure that is passed to the EnrollCallbackContext parameter of the callback
/// function. This structure can contain any data that the custom callback function is designed to handle.
/// </param>
/// <returns>
/// <para>
/// If the function succeeds, it returns <c>S_OK</c>. If the function fails, it returns an <c>HRESULT</c> value that indicates the
/// error. Possible values include, but are not limited to, those in the following table. For a list of common error codes, see
/// Common HRESULT Values.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>E_ACCESSDENIED</term>
/// <term>The calling account is not allowed to perform enrollment.</term>
/// </item>
/// <item>
/// <term>E_HANDLE</term>
/// <term>The session handle is not valid.</term>
/// </item>
/// <item>
/// <term>E_POINTER</term>
/// <term>The pointer specified by the EnrollCallback parameter cannot be NULL.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// If the SessionHandle parameter refers to the system sensor pool, the callback function will not be called until the application
/// acquires window focus and the user has provided a biometric sample. The manner in which you acquire focus depends on the type of
/// application you are writing. For example, if you are creating a GUI application you can implement a message handler that
/// captures a WM_ACTIVATE, WM_SETFOCUS, or other appropriate message. If you are writing a CUI application, call
/// <c>GetConsoleWindow</c> to retrieve a handle to the console window and pass that handle to the <c>SetForegroundWindow</c>
/// function to force the console window into the foreground and assign it focus. If your application is running in a detached
/// process and has no window or is a Windows service, use WinBioAcquireFocus and WinBioReleaseFocus to manually control focus.
/// </para>
/// <para>Examples</para>
/// <para>
/// The following code example enrolls a fingerprint asynchronously by calling <c>WinBioEnrollCaptureWithCallback</c> and passing a
/// pointer to a custom callback function. The callback function, EnrollCaptureCallback, is also shown. Link to the Winbio.lib
/// static library.
/// </para>
/// <para>
/// <code>//------------------------------------------------------------------------ // EnrollSystemPoolWithCallback.cpp : console application entry point. // #include &lt;windows.h&gt; #include &lt;stdio.h&gt; #include &lt;conio.h&gt; #include &lt;winbio.h&gt; //------------------------------------------------------------------------ // Forward declarations. // HRESULT EnrollSysPoolWithCallback( BOOL bCancel, BOOL bDiscard, WINBIO_BIOMETRIC_SUBTYPE subFactor); VOID CALLBACK EnrollCaptureCallback( __in_opt PVOID EnrollCallbackContext, __in HRESULT OperationStatus, __in WINBIO_REJECT_DETAIL RejectDetail); typedef struct _ENROLL_CALLBACK_CONTEXT { WINBIO_SESSION_HANDLE SessionHandle; WINBIO_UNIT_ID UnitId; WINBIO_BIOMETRIC_SUBTYPE SubFactor; } ENROLL_CALLBACK_CONTEXT, *PENROLL_CALLBACK_CONTEXT; //------------------------------------------------------------------------ int wmain() { HRESULT hr = S_OK; hr = EnrollSysPoolWithCallback( FALSE, FALSE, WINBIO_ANSI_381_POS_RH_INDEX_FINGER); return 0; } //------------------------------------------------------------------------ // The following function enrolls a user's fingerprint in the system pool. // The function calls WinBioEnrollCaptureWithCallback and waits for the // asynchronous enrollment process to be completed or canceled. // HRESULT EnrollSysPoolWithCallback( BOOL bCancel, BOOL bDiscard, WINBIO_BIOMETRIC_SUBTYPE subFactor) { // Declare variables HRESULT hr = S_OK; WINBIO_IDENTITY identity = {0}; WINBIO_SESSION_HANDLE sessionHandle = NULL; WINBIO_UNIT_ID unitId = 0; BOOLEAN isNewTemplate = TRUE; ENROLL_CALLBACK_CONTEXT callbackContext = {0}; // Connect to the system pool. hr = WinBioOpenSession( WINBIO_TYPE_FINGERPRINT, // Service provider WINBIO_POOL_SYSTEM, // Pool type WINBIO_FLAG_DEFAULT, // Configuration and access NULL, // Array of biometric unit IDs 0, // Count of biometric unit IDs NULL, // Database ID &amp;sessionHandle // [out] Session handle ); if (FAILED(hr)) { wprintf_s(L"\n WinBioEnumBiometricUnits failed. "); wprintf_s(L"hr = 0x%x\n", hr); goto e_Exit; } // Locate the sensor. wprintf_s(L"\n Swipe your finger to locate the sensor...\n"); hr = WinBioLocateSensor( sessionHandle, &amp;unitId); if (FAILED(hr)) { wprintf_s(L"\n WinBioLocateSensor failed. hr = 0x%x\n", hr); goto e_Exit; } // Begin the enrollment sequence. hr = WinBioEnrollBegin( sessionHandle, // Handle to open biometric session subFactor, // Finger to create template for unitId // Biometric unit ID ); if (FAILED(hr)) { wprintf_s(L"\n WinBioEnrollBegin failed. hr = 0x%x\n", hr); goto e_Exit; } // Set up the custom callback context structure. callbackContext.SessionHandle = sessionHandle; callbackContext.UnitId = unitId; callbackContext.SubFactor = subFactor; // Call WinBioEnrollCaptureWithCallback. This is an asynchronous // method that returns immediately. hr = WinBioEnrollCaptureWithCallback( sessionHandle, // Handle to open biometric session EnrollCaptureCallback, // Callback function &amp;callbackContext // Pointer to the custom context ); if (FAILED(hr)) { wprintf_s(L"\n WinBioEnrollCaptureWithCallback failed. "); wprintf_s(L"hr = 0x%x\n", hr); goto e_Exit; } wprintf_s(L"\n Swipe the sensor with the appropriate finger...\n"); // Cancel the enrollment if the bCancel flag is set. if (bCancel) { wprintf_s(L"\n Starting CANCEL timer...\n"); Sleep( 7000 ); wprintf_s(L"\n Calling WinBioCancel\n"); hr = WinBioCancel( sessionHandle ); if (FAILED(hr)) { wprintf_s(L"\n WinBioCancel failed. hr = 0x%x\n", hr); goto e_Exit; } } // Wait for the asynchronous enrollment process to complete // or be canceled. hr = WinBioWait( sessionHandle ); if (FAILED(hr)) { wprintf_s(L"\n WinBioWait failed. hr = 0x%x\n", hr); } // Discard the enrollment if the bDiscard flag is set. // Commit the enrollment if the flag is not set. if (bDiscard) { wprintf_s(L"\n Discarding enrollment...\n"); hr = WinBioEnrollDiscard( sessionHandle ); if (FAILED(hr)) { wprintf_s(L"\n WinBioLocateSensor failed. "); wprintf_s(L"hr = 0x%x\n", hr); } goto e_Exit; } else { wprintf_s(L"\n Committing enrollment...\n"); hr = WinBioEnrollCommit( sessionHandle, // Handle to open biometric session &amp;identity, // WINBIO_IDENTITY object for the user &amp;isNewTemplate); // Is this a new template if (FAILED(hr)) { wprintf_s(L"\n WinBioEnrollCommit failed. hr = 0x%x\n", hr); goto e_Exit; } } e_Exit: if (sessionHandle != NULL) { WinBioCloseSession(sessionHandle); sessionHandle = NULL; } wprintf_s(L"\n Press any key to exit..."); _getch(); return hr; } //------------------------------------------------------------------------ // The following function is the callback for the Windows Biometric // Framework WinBioEnrollCaptureWithCallback() function. // VOID CALLBACK EnrollCaptureCallback( __in_opt PVOID EnrollCallbackContext, __in HRESULT OperationStatus, __in WINBIO_REJECT_DETAIL RejectDetail ) { // Declare variables. HRESULT hr = S_OK; static SIZE_T swipeCount = 1; PENROLL_CALLBACK_CONTEXT callbackContext = (PENROLL_CALLBACK_CONTEXT)EnrollCallbackContext; wprintf_s(L"\n EnrollCaptureCallback executing\n"); wprintf_s(L"\n Sample %d captured", swipeCount++); // The capture was not acceptable or the enrollment operation // failed. if (FAILED(OperationStatus)) { if (OperationStatus == WINBIO_E_BAD_CAPTURE) { wprintf_s(L"\n Bad capture; reason: %d\n", RejectDetail); wprintf_s(L"\n Swipe your finger to capture another sample.\n"); // Try again. hr = WinBioEnrollCaptureWithCallback( callbackContext-&gt;SessionHandle, // Open session handle EnrollCaptureCallback, // Callback function EnrollCallbackContext // Callback context ); if (FAILED(hr)) { wprintf_s(L"WinBioEnrollCaptureWithCallback failed."); wprintf_s(L"hr = 0x%x\n", hr); } } else { wprintf_s(L"EnrollCaptureCallback failed."); wprintf_s(L"OperationStatus = 0x%x\n", OperationStatus); } goto e_Exit; } // The enrollment operation requires more fingerprint swipes. // This is normal and depends on your hardware. Typically, at least // three swipes are required. if (OperationStatus == WINBIO_I_MORE_DATA) { wprintf_s(L"\n More data required."); wprintf_s(L"\n Swipe your finger on the sensor again."); hr = WinBioEnrollCaptureWithCallback( callbackContext-&gt;SessionHandle, EnrollCaptureCallback, EnrollCallbackContext ); if (FAILED(hr)) { wprintf_s(L"WinBioEnrollCaptureWithCallback failed. "); wprintf_s(L"hr = 0x%x\n", hr); } goto e_Exit; } wprintf_s(L"\n Template completed\n"); e_Exit: return; }</code>
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winbio/nf-winbio-winbioenrollcapturewithcallback HRESULT
// WinBioEnrollCaptureWithCallback( WINBIO_SESSION_HANDLE SessionHandle, PWINBIO_ENROLL_CAPTURE_CALLBACK EnrollCallback, PVOID
// EnrollCallbackContext );
[DllImport(Lib_Winbio, SetLastError = false, ExactSpelling = true)]
[PInvokeData("winbio.h", MSDNShortId = "NF:winbio.WinBioEnrollCaptureWithCallback")]
public static extern HRESULT WinBioEnrollCaptureWithCallback(WINBIO_SESSION_HANDLE SessionHandle, [In] PWINBIO_ENROLL_CAPTURE_CALLBACK EnrollCallback, [In, Optional] IntPtr EnrollCallbackContext);
/// <summary>
/// Finalizes a pending biometric template and saves it to the database associated with the biometric unit used for enrollment.
/// Starting with Windows 10, build 1607, this function is available to use with a mobile image.
/// </summary>
/// <param name="SessionHandle">
/// A <c>WINBIO_SESSION_HANDLE</c> value that identifies an open biometric session. Open a synchronous session handle by calling
/// WinBioOpenSession. Open an asynchronous session handle by calling WinBioAsyncOpenSession.
/// </param>
/// <param name="Identity">Pointer to a WINBIO_IDENTITY structure that receives the identifier (GUID or SID) of the template.</param>
/// <param name="IsNewTemplate">Pointer to a Boolean value that specifies whether the template being added to the database is new.</param>
/// <returns>
/// <para>
/// If the function succeeds, it returns S_OK. If the function fails, it returns an <c>HRESULT</c> value that indicates the error.
/// Possible values include, but are not limited to, those in the following table. For a list of common error codes, see Common
/// HRESULT Values.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>E_HANDLE</term>
/// <term>The session handle is not valid.</term>
/// </item>
/// <item>
/// <term>E_POINTER</term>
/// <term>The pointers specified by the Identity and IsNewTemplate parameters cannot be NULL.</term>
/// </item>
/// <item>
/// <term>WINBIO_E_DATABASE_FULL</term>
/// <term>There is no space available in the database for the template.</term>
/// </item>
/// <item>
/// <term>WINBIO_E_DUPLICATE_TEMPLATE</term>
/// <term>The template matches one already saved in the database with a different identity or sub-factor (system pool only).</term>
/// </item>
/// <item>
/// <term>WINBIO_E_LOCK_VIOLATION</term>
/// <term>The biometric unit is in use and is locked.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// If the pending template is a duplicate of one that already exists in the database, the Identity parameter will point to the
/// existing template and the value pointed to by the IsNewTemplate parameter will be <c>FALSE</c>.
/// </para>
/// <para>If the <c>WinBioEnrollCommit</c> function succeeds, the following registry value is set to 0x01.</para>
/// <para><c>HKEY_LOCAL_MACHINE</c><c>System</c><c>CurrentControlSet</c><c>Services</c><c>WbioSrvc</c><c>Parameters</c><c>EnrollmentCommitted</c></para>
/// <para><c>Note</c> This registry value is never deleted by the Windows Biometric Framework (WBF).</para>
/// <para>
/// To use <c>WinBioEnrollCommit</c> synchronously, call the function with a session handle created by calling WinBioOpenSession.
/// The function blocks until the operation completes or an error is encountered.
/// </para>
/// <para>
/// To use <c>WinBioEnrollCommit</c> asynchronously, call the function with a session handle created by calling
/// WinBioAsyncOpenSession. The framework allocates a WINBIO_ASYNC_RESULT structure and uses it to return information about
/// operation success or failure. If the operation is successful, the framework returns <c>WINBIO_IDENTITY</c> information and a
/// flag indicating whether the template is new in a nested <c>EnrollCommit</c> structure. If the operation is unsuccessful, the
/// framework returns error information. The <c>WINBIO_ASYNC_RESULT</c> structure is returned to the application callback or to the
/// application message queue, depending on the value you set in the NotificationMethod parameter of the
/// <c>WinBioAsyncOpenSession</c> function:
/// </para>
/// <list type="bullet">
/// <item>
/// <term>
/// If you choose to receive completion notices by using a callback, you must implement a PWINBIO_ASYNC_COMPLETION_CALLBACK function
/// and set the NotificationMethod parameter to <c>WINBIO_ASYNC_NOTIFY_CALLBACK</c>.
/// </term>
/// </item>
/// <item>
/// <term>
/// If you choose to receive completion notices by using the application message queue, you must set the NotificationMethod
/// parameter to <c>WINBIO_ASYNC_NOTIFY_MESSAGE</c>. The framework returns a WINBIO_ASYNC_RESULT pointer to the <c>LPARAM</c> field
/// of the window message.
/// </term>
/// </item>
/// </list>
/// <para>
/// To prevent memory leaks, you must call WinBioFree to release the WINBIO_ASYNC_RESULT structure after you have finished using it.
/// </para>
/// <para>Examples</para>
/// <para>
/// The following function calls <c>WinBioEnrollCommit</c> to commit a biometric enrollment to system pool. Link to the Winbio.lib
/// static library and include the following header files:
/// </para>
/// <list type="bullet">
/// <item>
/// <term>Windows.h</term>
/// </item>
/// <item>
/// <term>Stdio.h</term>
/// </item>
/// <item>
/// <term>Conio.h</term>
/// </item>
/// <item>
/// <term>Winbio.h</term>
/// </item>
/// </list>
/// <para>
/// <code>HRESULT EnrollSysPool( BOOL discardEnrollment, WINBIO_BIOMETRIC_SUBTYPE subFactor) { HRESULT hr = S_OK; WINBIO_IDENTITY identity = {0}; WINBIO_SESSION_HANDLE sessionHandle = NULL; WINBIO_UNIT_ID unitId = 0; WINBIO_REJECT_DETAIL rejectDetail = 0; BOOLEAN isNewTemplate = TRUE; // Connect to the system pool. hr = WinBioOpenSession( WINBIO_TYPE_FINGERPRINT, // Service provider WINBIO_POOL_SYSTEM, // Pool type WINBIO_FLAG_DEFAULT, // Configuration and access NULL, // Array of biometric unit IDs 0, // Count of biometric unit IDs NULL, // Database ID &amp;sessionHandle // [out] Session handle ); if (FAILED(hr)) { wprintf_s(L"\n WinBioOpenSession failed. "); wprintf_s(L"hr = 0x%x\n", hr); goto e_Exit; } // Locate a sensor. wprintf_s(L"\n Swipe your finger on the sensor...\n"); hr = WinBioLocateSensor( sessionHandle, &amp;unitId); if (FAILED(hr)) { wprintf_s(L"\n WinBioLocateSensor failed. hr = 0x%x\n", hr); goto e_Exit; } // Begin the enrollment sequence. wprintf_s(L"\n Starting enrollment sequence...\n"); hr = WinBioEnrollBegin( sessionHandle, // Handle to open biometric session subFactor, // Finger to create template for unitId // Biometric unit ID ); if (FAILED(hr)) { wprintf_s(L"\n WinBioEnrollBegin failed. hr = 0x%x\n", hr); goto e_Exit; } // Capture enrollment information by swiping the sensor with // the finger identified by the subFactor argument in the // WinBioEnrollBegin function. for (int swipeCount = 1;; ++swipeCount) { wprintf_s(L"\n Swipe the sensor to capture %s sample.", (swipeCount == 1)?L"the first":L"another"); hr = WinBioEnrollCapture( sessionHandle, // Handle to open biometric session &amp;rejectDetail // [out] Failure information ); wprintf_s(L"\n Sample %d captured from unit number %d.", swipeCount, unitId); if (hr == WINBIO_I_MORE_DATA) { wprintf_s(L"\n More data required.\n"); continue; } if (FAILED(hr)) { if (hr == WINBIO_E_BAD_CAPTURE) { wprintf_s(L"\n Error: Bad capture; reason: %d", rejectDetail); continue; } else { wprintf_s(L"\n WinBioEnrollCapture failed. hr = 0x%x", hr); goto e_Exit; } } else { wprintf_s(L"\n Template completed.\n"); break; } } // Discard the enrollment if the appropriate flag is set. // Commit the enrollment if it is not discarded. if (discardEnrollment == TRUE) { wprintf_s(L"\n Discarding enrollment...\n\n"); hr = WinBioEnrollDiscard( sessionHandle ); if (FAILED(hr)) { wprintf_s(L"\n WinBioLocateSensor failed. hr = 0x%x\n", hr); } goto e_Exit; } else { wprintf_s(L"\n Committing enrollment...\n"); hr = WinBioEnrollCommit( sessionHandle, // Handle to open biometric session &amp;identity, // WINBIO_IDENTITY object for the user &amp;isNewTemplate); // Is this a new template if (FAILED(hr)) { wprintf_s(L"\n WinBioEnrollCommit failed. hr = 0x%x\n", hr); goto e_Exit; } } e_Exit: if (sessionHandle != NULL) { WinBioCloseSession(sessionHandle); sessionHandle = NULL; } wprintf_s(L" Press any key to continue..."); _getch(); return hr; }</code>
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winbio/nf-winbio-winbioenrollcommit HRESULT WinBioEnrollCommit(
// WINBIO_SESSION_HANDLE SessionHandle, WINBIO_IDENTITY *Identity, BOOLEAN *IsNewTemplate );
[DllImport(Lib_Winbio, SetLastError = false, ExactSpelling = true)]
[PInvokeData("winbio.h", MSDNShortId = "NF:winbio.WinBioEnrollCommit")]
public static extern HRESULT WinBioEnrollCommit(WINBIO_SESSION_HANDLE SessionHandle, out WINBIO_IDENTITY Identity, [MarshalAs(UnmanagedType.U1)] out bool IsNewTemplate);
/// <summary>
/// Ends the enrollment sequence and discards a pending biometric template. Starting with Windows 10, build 1607, this function is
/// available to use with a mobile image.
/// </summary>
/// <param name="SessionHandle">
/// A <c>WINBIO_SESSION_HANDLE</c> value that identifies an open biometric session. Open a synchronous session handle by calling
/// WinBioOpenSession. Open an asynchronous session handle by calling WinBioAsyncOpenSession.
/// </param>
/// <returns>
/// <para>
/// If the function succeeds, it returns S_OK. If the function fails, it returns an <c>HRESULT</c> value that indicates the error.
/// Possible values include, but are not limited to, those in the following table. For a list of common error codes, see Common
/// HRESULT Values.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>E_ACCESSDENIED</term>
/// <term>The caller does not have permission to enroll.</term>
/// </item>
/// <item>
/// <term>E_HANDLE</term>
/// <term>The session handle is not valid.</term>
/// </item>
/// <item>
/// <term>WINBIO_E_LOCK_VIOLATION</term>
/// <term>The biometric unit is in use and is locked.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// You can use this function to allow a user to stop an enrollment sequence before saving a biometric template to the template database.
/// </para>
/// <para>
/// To use <c>WinBioEnrollDiscard</c> synchronously, call the function with a session handle created by calling WinBioOpenSession.
/// The function blocks until the operation completes or an error is encountered.
/// </para>
/// <para>
/// To use <c>WinBioEnrollDiscard</c> asynchronously, call the function with a session handle created by calling
/// WinBioAsyncOpenSession. The framework allocates a WINBIO_ASYNC_RESULT structure and uses it to return information about
/// operation success or failure. The <c>WINBIO_ASYNC_RESULT</c> structure is returned to the application callback or to the
/// application message queue, depending on the value you set in the NotificationMethod parameter of the
/// <c>WinBioAsyncOpenSession</c> function:
/// </para>
/// <list type="bullet">
/// <item>
/// <term>
/// If you choose to receive completion notices by using a callback, you must implement a PWINBIO_ASYNC_COMPLETION_CALLBACK function
/// and set the NotificationMethod parameter to <c>WINBIO_ASYNC_NOTIFY_CALLBACK</c>.
/// </term>
/// </item>
/// <item>
/// <term>
/// If you choose to receive completion notices by using the application message queue, you must set the NotificationMethod
/// parameter to <c>WINBIO_ASYNC_NOTIFY_MESSAGE</c>. The framework returns a WINBIO_ASYNC_RESULT pointer to the <c>LPARAM</c> field
/// of the window message.
/// </term>
/// </item>
/// </list>
/// <para>
/// To prevent memory leaks, you must call WinBioFree to release the WINBIO_ASYNC_RESULT structure after you have finished using it.
/// </para>
/// <para>Examples</para>
/// <para>
/// The following function enrolls a biometric template in the system pool. You can pass a Boolean value to the function which
/// enables you to discard an enrollment by calling <c>WinBioEnrollDiscard</c>. Link to the Winbio.lib static library and include
/// the following header files:
/// </para>
/// <list type="bullet">
/// <item>
/// <term>Windows.h</term>
/// </item>
/// <item>
/// <term>Stdio.h</term>
/// </item>
/// <item>
/// <term>Conio.h</term>
/// </item>
/// <item>
/// <term>Winbio.h</term>
/// </item>
/// </list>
/// <para>
/// <code>HRESULT EnrollSysPool( BOOL discardEnrollment, WINBIO_BIOMETRIC_SUBTYPE subFactor) { HRESULT hr = S_OK; WINBIO_IDENTITY identity = {0}; WINBIO_SESSION_HANDLE sessionHandle = NULL; WINBIO_UNIT_ID unitId = 0; WINBIO_REJECT_DETAIL rejectDetail = 0; BOOLEAN isNewTemplate = TRUE; // Connect to the system pool. hr = WinBioOpenSession( WINBIO_TYPE_FINGERPRINT, // Service provider WINBIO_POOL_SYSTEM, // Pool type WINBIO_FLAG_DEFAULT, // Configuration and access NULL, // Array of biometric unit IDs 0, // Count of biometric unit IDs NULL, // Database ID &amp;sessionHandle // [out] Session handle ); if (FAILED(hr)) { wprintf_s(L"\n WinBioOpenSession failed. "); wprintf_s(L"hr = 0x%x\n", hr); goto e_Exit; } // Locate a sensor. wprintf_s(L"\n Swipe your finger on the sensor...\n"); hr = WinBioLocateSensor( sessionHandle, &amp;unitId); if (FAILED(hr)) { wprintf_s(L"\n WinBioLocateSensor failed. hr = 0x%x\n", hr); goto e_Exit; } // Begin the enrollment sequence. wprintf_s(L"\n Starting enrollment sequence...\n"); hr = WinBioEnrollBegin( sessionHandle, // Handle to open biometric session subFactor, // Finger to create template for unitId // Biometric unit ID ); if (FAILED(hr)) { wprintf_s(L"\n WinBioEnrollBegin failed. hr = 0x%x\n", hr); goto e_Exit; } // Capture enrollment information by swiping the sensor with // the finger identified by the subFactor argument in the // WinBioEnrollBegin function. for (int swipeCount = 1;; ++swipeCount) { wprintf_s(L"\n Swipe the sensor to capture %s sample.", (swipeCount == 1)?L"the first":L"another"); hr = WinBioEnrollCapture( sessionHandle, // Handle to open biometric session &amp;rejectDetail // [out] Failure information ); wprintf_s(L"\n Sample %d captured from unit number %d.", swipeCount, unitId); if (hr == WINBIO_I_MORE_DATA) { wprintf_s(L"\n More data required.\n"); continue; } if (FAILED(hr)) { if (hr == WINBIO_E_BAD_CAPTURE) { wprintf_s(L"\n Error: Bad capture; reason: %d", rejectDetail); continue; } else { wprintf_s(L"\n WinBioEnrollCapture failed. hr = 0x%x", hr); goto e_Exit; } } else { wprintf_s(L"\n Template completed.\n"); break; } } // Discard the enrollment if the appropriate flag is set. // Commit the enrollment if it is not discarded. if (discardEnrollment == TRUE) { wprintf_s(L"\n Discarding enrollment...\n\n"); hr = WinBioEnrollDiscard( sessionHandle ); if (FAILED(hr)) { wprintf_s(L"\n WinBioLocateSensor failed. hr = 0x%x\n", hr); } goto e_Exit; } else { wprintf_s(L"\n Committing enrollment...\n"); hr = WinBioEnrollCommit( sessionHandle, // Handle to open biometric session &amp;identity, // WINBIO_IDENTITY object for the user &amp;isNewTemplate); // Is this a new template if (FAILED(hr)) { wprintf_s(L"\n WinBioEnrollCommit failed. hr = 0x%x\n", hr); goto e_Exit; } } e_Exit: if (sessionHandle != NULL) { WinBioCloseSession(sessionHandle); sessionHandle = NULL; } wprintf_s(L" Press any key to continue..."); _getch(); return hr; }</code>
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winbio/nf-winbio-winbioenrolldiscard HRESULT WinBioEnrollDiscard(
// WINBIO_SESSION_HANDLE SessionHandle );
[DllImport(Lib_Winbio, SetLastError = false, ExactSpelling = true)]
[PInvokeData("winbio.h", MSDNShortId = "NF:winbio.WinBioEnrollDiscard")]
public static extern HRESULT WinBioEnrollDiscard(WINBIO_SESSION_HANDLE SessionHandle);
/// <summary>
/// Specifies the individual that you want to enroll when data that represents multiple individuals is present in the sample buffer.
/// Starting with Windows 10, build 1607, this function is available to use with a mobile image.
/// </summary>
/// <param name="SessionHandle">
/// <para>
/// A <c>WINBIO_SESSION_HANDLE</c> value that identifies an open biometric session. Open a synchronous session handle by calling
/// WinBioOpenSession. Open an asynchronous session handle by calling WinBioAsyncOpenSession.
/// </para>
/// <para>
/// For enrollment in facial recognition, use WinBioAsyncOpenSession with the PoolType parameter set to <c>WINBIO_POOL_SYSTEM</c> to
/// get the handle.
/// </para>
/// </param>
/// <param name="SelectorValue">A value that identifies that individual that you want to select for enrollment.</param>
/// <returns>
/// <para>
/// If the function succeeds, it returns S_OK. If the function fails, it returns an <c>HRESULT</c> value that indicates the error.
/// Possible values include, but are not limited to, those in the following table. For a list of common error codes, see Common
/// HRESULT Values.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>E_HANDLE</term>
/// <term>The session handle is not valid.</term>
/// </item>
/// <item>
/// <term>E_INVALIDARG</term>
/// <term>The SelectorValue parameter cannot equal zero.</term>
/// </item>
/// <item>
/// <term>WINBIO_E_INCORRECT_SESSION_TYPE</term>
/// <term>The session handle does not correspond to a biometric session.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>For enrollment in facial recognition, you can find the correct selector value in either of two ways:</para>
/// <list type="bullet">
/// <item>
/// <term>The value of the <c>Id</c> member of one of the WINBIO_PRESENCE structures previously sent.</term>
/// </item>
/// <item>
/// <term>The data produced by the NUI face-tracking APIs.</term>
/// </item>
/// </list>
/// <para>
/// Call <c>WinBioEnrollSelect</c> to set the selector value after you call WinBioEnrollBegin to start an enrollment sequence. The
/// selector value applies to all subsequent WinBioEnrollCapture calls. The selection setting is temporary and is automatically
/// cleared when you finish the enrollment sequence by calling WinBioEnrollCommit or WinBioEnrollDiscard.
/// </para>
/// <para>
/// If you call <c>WinBioEnrollSelect</c> for biometric factors that do not require disambiguation, such as fingerprints, the return
/// value for the function indicates success, but function ignores the selector value.
/// </para>
/// <para>
/// If you do not call <c>WinBioEnrollSelect</c> for a biometric factor that requires you to call the function, subsequent calls to
/// WinBioEnrollCapture fail with the <c>WINBIO_E_SELECTION_REQUIRED</c> error.
/// </para>
/// <para>For Windows 10, the factors that require you to call <c>WinBioEnrollSelect</c> are facial features and iris.</para>
/// <para>
/// You can call <c>WinBioEnrollSelect</c> by using either a synchronous or asynchronous session handle. As with other calls to
/// Windows Biometric Framework API functions, when you call <c>WinBioEnrollSelect</c> with an asynchronous session handle, the
/// return value indicates only that the function parameters were acceptable. The actual success or failure of the operation itself
/// will be returned to your notification routine in a WINBIO_ASYNC_RESULT structure.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winbio/nf-winbio-winbioenrollselect HRESULT WinBioEnrollSelect(
// WINBIO_SESSION_HANDLE SessionHandle, ULONGLONG SelectorValue );
[DllImport(Lib_Winbio, SetLastError = false, ExactSpelling = true)]
[PInvokeData("winbio.h", MSDNShortId = "NF:winbio.WinBioEnrollSelect")]
public static extern HRESULT WinBioEnrollSelect(WINBIO_SESSION_HANDLE SessionHandle, ulong SelectorValue);
/// <summary>Enumerates all attached biometric units that match the input type.</summary>
/// <param name="Factor">
/// A bitmask of WINBIO_BIOMETRIC_TYPE flags that specifies the biometric unit types to be enumerated. Only
/// <c>WINBIO_TYPE_FINGERPRINT</c> is currently supported.
/// </param>
/// <param name="UnitSchemaArray">
/// Address of a variable that receives a pointer to an array of WINBIO_UNIT_SCHEMA structures that contain information about each
/// enumerated biometric unit. If the function does not succeed, the pointer is set to <c>NULL</c>. If the function succeeds, you
/// must pass the pointer to WinBioFree to release memory allocated internally for the array.
/// </param>
/// <param name="UnitCount">Pointer to a value that specifies the number of structures pointed to by the UnitSchemaArray parameter.</param>
/// <returns>
/// <para>
/// If the function succeeds, it returns S_OK. If the function fails, it returns an <c>HRESULT</c> value that indicates the error.
/// Possible values include, but are not limited to, those in the following table. For a list of common error codes, see Common
/// HRESULT Values.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>E_INVALIDARG</term>
/// <term>The bitmask contained in the Factor parameter contains one or more an invalid type bits.</term>
/// </item>
/// <item>
/// <term>E_OUTOFMEMORY</term>
/// <term>There was insufficient memory to complete the request.</term>
/// </item>
/// <item>
/// <term>E_POINTER</term>
/// <term>The UnitSchemaArray and UnitCount parameters cannot be NULL.</term>
/// </item>
/// <item>
/// <term>WINBIO_E_DISABLED</term>
/// <term>Current administrative policy prohibits use of the Windows Biometric Framework API.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>Only <c>WINBIO_TYPE_FINGERPRINT</c> is currently supported in the Factor parameter.</para>
/// <para>
/// If information about multiple installed biometric units is returned in the array of structures pointed to by the UnitSchemaArray
/// parameter, the units are not guaranteed to be in any particular order.
/// </para>
/// <para>
/// After you are finished using the structures returned to the UnitSchemaArray parameter, you must call WinBioFree to release the
/// memory allocated internally for the array.
/// </para>
/// <para>
/// If all of the factor bits in the Factor bitmask refer to unsupported biometric types, the function returns S_OK but the value
/// pointed to by the UnitSchemaArray parameter will be NULL and the UnitCount parameter will contain zero. Although it is not an
/// error to inquire about unsupported biometric factors, the result of the query will be an empty set.
/// </para>
/// <para>Examples</para>
/// <para>
/// The following function calls <c>WinBioEnumBiometricUnits</c> to enumerate the installed biometric units. Link to the Winbio.lib
/// static library and include the following header files:
/// </para>
/// <list type="bullet">
/// <item>
/// <term>Windows.h</term>
/// </item>
/// <item>
/// <term>Stdio.h</term>
/// </item>
/// <item>
/// <term>Conio.h</term>
/// </item>
/// <item>
/// <term>Winbio.h</term>
/// </item>
/// </list>
/// <para>
/// <code>HRESULT EnumerateSensors( ) { // Declare variables. HRESULT hr = S_OK; PWINBIO_UNIT_SCHEMA unitSchema = NULL; SIZE_T unitCount = 0; SIZE_T index = 0; // Enumerate the installed biometric units. hr = WinBioEnumBiometricUnits( WINBIO_TYPE_FINGERPRINT, // Type of biometric unit &amp;unitSchema, // Array of unit schemas &amp;unitCount ); // Count of unit schemas if (FAILED(hr)) { wprintf_s(L"\n WinBioEnumBiometricUnits failed. hr = 0x%x\n", hr); goto e_Exit; } // Display information for each installed biometric unit. wprintf_s(L"\nSensors: \n"); for (index = 0; index &lt; unitCount; ++index) { wprintf_s(L"\n[%d]: \tUnit ID: %d\n", index, unitSchema[index].UnitId ); wprintf_s(L"\tDevice instance ID: %s\n", unitSchema[index].DeviceInstanceId ); wprintf_s(L"\tPool type: %d\n", unitSchema[index].PoolType ); wprintf_s(L"\tBiometric factor: %d\n", unitSchema[index].BiometricFactor ); wprintf_s(L"\tSensor subtype: %d\n", unitSchema[index].SensorSubType ); wprintf_s(L"\tSensor capabilities: 0x%08x\n", unitSchema[index].Capabilities ); wprintf_s(L"\tDescription: %s\n", unitSchema[index].Description ); wprintf_s(L"\tManufacturer: %s\n", unitSchema[index].Manufacturer ); wprintf_s(L"\tModel: %s\n", unitSchema[index].Model ); wprintf_s(L"\tSerial no: %s\n", unitSchema[index].SerialNumber ); wprintf_s(L"\tFirmware version: [%d.%d]\n", unitSchema[index].FirmwareVersion.MajorVersion, unitSchema[index].FirmwareVersion.MinorVersion); } e_Exit: if (unitSchema != NULL) { WinBioFree(unitSchema); unitSchema = NULL; } wprintf_s(L"\nPress any key to exit..."); _getch(); return hr; }</code>
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winbio/nf-winbio-winbioenumbiometricunits HRESULT WinBioEnumBiometricUnits(
// WINBIO_BIOMETRIC_TYPE Factor, WINBIO_UNIT_SCHEMA **UnitSchemaArray, SIZE_T *UnitCount );
[DllImport(Lib_Winbio, SetLastError = false, ExactSpelling = true)]
[PInvokeData("winbio.h", MSDNShortId = "NF:winbio.WinBioEnumBiometricUnits")]
public static extern HRESULT WinBioEnumBiometricUnits(WINBIO_BIOMETRIC_TYPE Factor, out SafeWinBioMemory UnitSchemaArray, out SizeT UnitCount);
/// <summary>Enumerates all attached biometric units that match the input type.</summary>
/// <param name="Factor">
/// A bitmask of WINBIO_BIOMETRIC_TYPE flags that specifies the biometric unit types to be enumerated. Only
/// <c>WINBIO_TYPE_FINGERPRINT</c> is currently supported.
/// </param>
/// <param name="UnitSchemaArray">
/// Address of a variable that receives a pointer to an array of WINBIO_UNIT_SCHEMA structures that contain information about each
/// enumerated biometric unit.
/// </param>
/// <returns>
/// <para>
/// If the function succeeds, it returns S_OK. If the function fails, it returns an <c>HRESULT</c> value that indicates the error.
/// Possible values include, but are not limited to, those in the following table. For a list of common error codes, see Common
/// HRESULT Values.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>E_INVALIDARG</term>
/// <term>The bitmask contained in the Factor parameter contains one or more an invalid type bits.</term>
/// </item>
/// <item>
/// <term>E_OUTOFMEMORY</term>
/// <term>There was insufficient memory to complete the request.</term>
/// </item>
/// <item>
/// <term>E_POINTER</term>
/// <term>The UnitSchemaArray and UnitCount parameters cannot be NULL.</term>
/// </item>
/// <item>
/// <term>WINBIO_E_DISABLED</term>
/// <term>Current administrative policy prohibits use of the Windows Biometric Framework API.</term>
/// </item>
/// </list>
/// </returns>
[PInvokeData("winbio.h", MSDNShortId = "NF:winbio.WinBioEnumBiometricUnits")]
public static HRESULT WinBioEnumBiometricUnits(WINBIO_BIOMETRIC_TYPE Factor, out WINBIO_UNIT_SCHEMA[] UnitSchemaArray) => GetEnum(WinBioEnumBiometricUnits, Factor, out UnitSchemaArray);
/// <summary>Enumerates all registered databases that match a specified type.</summary>
/// <param name="Factor">
/// A bitmask of WINBIO_BIOMETRIC_TYPE flags that specifies the biometric unit types to be enumerated. Only
/// <c>WINBIO_TYPE_FINGERPRINT</c> is currently supported.
/// </param>
/// <param name="StorageSchemaArray">
/// Address of a variable that receives a pointer to an array of WINBIO_STORAGE_SCHEMA structures that contain information about
/// each database. If the function does not succeed, the pointer is set to <c>NULL</c>. If the function succeeds, you must pass the
/// pointer to WinBioFree to release memory allocated internally for the array.
/// </param>
/// <param name="StorageCount">
/// Pointer to a value that specifies the number of structures pointed to by the StorageSchemaArray parameter.
/// </param>
/// <returns>
/// <para>
/// If the function succeeds, it returns S_OK. If the function fails, it returns an <c>HRESULT</c> value that indicates the error.
/// Possible values include, but are not limited to, those in the following table. For a list of common error codes, see Common
/// HRESULT Values.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>E_INVALIDARG</term>
/// <term>The bitmask contained in the Factor parameter contains one or more an invalid type bits.</term>
/// </item>
/// <item>
/// <term>E_OUTOFMEMORY</term>
/// <term>There was insufficient memory to complete the request.</term>
/// </item>
/// <item>
/// <term>E_POINTER</term>
/// <term>The StorageSchemaArray and StorageCount parameters cannot be NULL.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>Only <c>WINBIO_TYPE_FINGERPRINT</c> is currently supported in the Factor parameter.</para>
/// <para>
/// If information about multiple databases is returned in the array of structures pointed to by the StorageSchemaArray parameter,
/// the databases are not guaranteed to be in any particular order.
/// </para>
/// <para>
/// After you are finished using the structures returned to the StorageSchemaArray parameter, you must call WinBioFree to release
/// the memory allocated internally for the array.
/// </para>
/// <para>Examples</para>
/// <para>
/// The following code example calls <c>WinBioEnumDatabases</c> to enumerate the biometric databases on the system. The example also
/// includes a function, DisplayGuid, to display the database ID. Link to the Winbio.lib static library and include the following
/// header files:
/// </para>
/// <list type="bullet">
/// <item>
/// <term>Windows.h</term>
/// </item>
/// <item>
/// <term>Stdio.h</term>
/// </item>
/// <item>
/// <term>Conio.h</term>
/// </item>
/// <item>
/// <term>Winbio.h</term>
/// </item>
/// </list>
/// <para>
/// <code>HRESULT EnumDatabases( ) { // Declare variables. HRESULT hr = S_OK; PWINBIO_STORAGE_SCHEMA storageSchemaArray = NULL; SIZE_T storageCount = 0; SIZE_T index = 0; // Enumerate the databases. hr = WinBioEnumDatabases( WINBIO_TYPE_FINGERPRINT, // Type of biometric unit &amp;storageSchemaArray, // Array of database schemas &amp;storageCount ); // Number of database schemas if (FAILED(hr)) { wprintf_s(L"\nWinBioEnumDatabases failed. hr = 0x%x\n", hr); goto e_Exit; } // Display information for each database. wprintf_s(L"\nDatabases:\n"); for (index = 0; index &lt; storageCount; ++index) { wprintf_s(L"\n[%d]: \tBiometric factor: 0x%08x\n", index, storageSchemaArray[index].BiometricFactor ); wprintf_s(L"\tDatabase ID: "); DisplayGuid(&amp;storageSchemaArray[index].DatabaseId); wprintf_s(L"\n"); wprintf_s(L"\tData format: "); DisplayGuid(&amp;storageSchemaArray[index].DataFormat); wprintf_s(L"\n"); wprintf_s(L"\tAttributes: 0x%08x\n", storageSchemaArray[index].Attributes); wprintf_s(L"\tFile path: %ws\n", storageSchemaArray[index].FilePath ); wprintf_s(L"\tCnx string: %ws\n", storageSchemaArray[index].ConnectionString ); wprintf_s(L"\n"); } e_Exit: if (storageSchemaArray != NULL) { WinBioFree(storageSchemaArray); storageSchemaArray = NULL; } wprintf_s(L"\nPress any key to exit..."); _getch(); return hr; } //------------------------------------------------------------------------ // The following function displays a GUID to the console window. // VOID DisplayGuid( __in PWINBIO_UUID Guid ) { wprintf_s( L"{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}", Guid-&gt;Data1, Guid-&gt;Data2, Guid-&gt;Data3, Guid-&gt;Data4[0], Guid-&gt;Data4[1], Guid-&gt;Data4[2], Guid-&gt;Data4[3], Guid-&gt;Data4[4], Guid-&gt;Data4[5], Guid-&gt;Data4[6], Guid-&gt;Data4[7] ); }</code>
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winbio/nf-winbio-winbioenumdatabases HRESULT WinBioEnumDatabases(
// WINBIO_BIOMETRIC_TYPE Factor, WINBIO_STORAGE_SCHEMA **StorageSchemaArray, SIZE_T *StorageCount );
[DllImport(Lib_Winbio, SetLastError = false, ExactSpelling = true)]
[PInvokeData("winbio.h", MSDNShortId = "NF:winbio.WinBioEnumDatabases")]
public static extern HRESULT WinBioEnumDatabases(WINBIO_BIOMETRIC_TYPE Factor, out SafeWinBioMemory StorageSchemaArray, out SizeT StorageCount);
/// <summary>Enumerates all registered databases that match a specified type.</summary>
/// <param name="Factor">
/// A bitmask of WINBIO_BIOMETRIC_TYPE flags that specifies the biometric unit types to be enumerated. Only
/// <c>WINBIO_TYPE_FINGERPRINT</c> is currently supported.
/// </param>
/// <param name="StorageSchemaArray">
/// Address of a variable that receives a pointer to an array of WINBIO_STORAGE_SCHEMA structures that contain information about
/// each database. If the function does not succeed, the pointer is set to <c>NULL</c>. If the function succeeds, you must pass the
/// pointer to WinBioFree to release memory allocated internally for the array.
/// </param>
/// <returns>
/// <para>
/// If the function succeeds, it returns S_OK. If the function fails, it returns an <c>HRESULT</c> value that indicates the error.
/// Possible values include, but are not limited to, those in the following table. For a list of common error codes, see Common
/// HRESULT Values.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>E_INVALIDARG</term>
/// <term>The bitmask contained in the Factor parameter contains one or more an invalid type bits.</term>
/// </item>
/// <item>
/// <term>E_OUTOFMEMORY</term>
/// <term>There was insufficient memory to complete the request.</term>
/// </item>
/// <item>
/// <term>E_POINTER</term>
/// <term>The StorageSchemaArray and StorageCount parameters cannot be NULL.</term>
/// </item>
/// </list>
/// </returns>
// https://docs.microsoft.com/en-us/windows/win32/api/winbio/nf-winbio-winbioenumdatabases HRESULT WinBioEnumDatabases(
// WINBIO_BIOMETRIC_TYPE Factor, WINBIO_STORAGE_SCHEMA **StorageSchemaArray, SIZE_T *StorageCount );
[PInvokeData("winbio.h", MSDNShortId = "NF:winbio.WinBioEnumDatabases")]
public static HRESULT WinBioEnumDatabases(WINBIO_BIOMETRIC_TYPE Factor, out WINBIO_STORAGE_SCHEMA[] StorageSchemaArray) => GetEnum(WinBioEnumDatabases, Factor, out StorageSchemaArray);
/// <summary>
/// Retrieves the biometric sub-factors enrolled for a specified identity and biometric unit. Starting with Windows 10, build 1607,
/// this function is available to use with a mobile image.
/// </summary>
/// <param name="SessionHandle">
/// A <c>WINBIO_SESSION_HANDLE</c> value that identifies an open biometric session. Open a synchronous session handle by calling
/// WinBioOpenSession. Open an asynchronous session handle by calling WinBioAsyncOpenSession.
/// </param>
/// <param name="UnitId">A <c>WINBIO_UNIT_ID</c> value that specifies the biometric unit.</param>
/// <param name="Identity">
/// Pointer to a WINBIO_IDENTITY structure that contains the GUID or SID of the template from which the sub-factors are to be retrieved.
/// </param>
/// <param name="SubFactorArray">
/// Address of a variable that receives a pointer to an array of sub-factors. If the function does not succeed, the pointer is set
/// to <c>NULL</c>. If the function succeeds, you must pass the pointer to WinBioFree to release memory allocated internally for the array.
/// </param>
/// <param name="SubFactorCount">
/// Pointer to a value that specifies the number of elements in the array pointed to by the SubFactorArray parameter. If the
/// function does not succeed, this value is set to zero.
/// </param>
/// <returns>
/// <para>
/// If the function succeeds, it returns S_OK. If the function fails, it returns an <c>HRESULT</c> value that indicates the error.
/// Possible values include, but are not limited to, those in the following table. For a list of common error codes, see Common
/// HRESULT Values.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>E_HANDLE</term>
/// <term>The session handle is not valid.</term>
/// </item>
/// <item>
/// <term>E_INVALIDARG</term>
/// <term>The UnitId parameter cannot be zero.</term>
/// </item>
/// <item>
/// <term>E_POINTER</term>
/// <term>The Identity, SubFactorArray, and SubFactorCount parameters cannot be NULL.</term>
/// </item>
/// <item>
/// <term>WINBIO_E_ENROLLMENT_IN_PROGRESS</term>
/// <term>
/// The operation could not be completed because the biometric unit specified by the UnitId parameter is currently being used for an
/// enrollment transaction.
/// </term>
/// </item>
/// <item>
/// <term>WINBIO_E_UNKNOWN_ID</term>
/// <term>The GUID or SID specified by the Identity parameter cannot be found.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// The <c>WinBioEnumEnrollments</c> function is supplied primarily so that the applications can provide user feedback. For example,
/// your application can call this function to tell the user which fingerprints are already enrolled on a specific fingerprint reader.
/// </para>
/// <para>
/// After you are finished using the structures returned to the SubFactorArray parameter, you must call WinBioFree to release the
/// memory allocated internally for the array.
/// </para>
/// <para>
/// To use <c>WinBioEnumEnrollments</c> synchronously, call the function with a session handle created by calling WinBioOpenSession.
/// The function blocks until the operation completes or an error is encountered.
/// </para>
/// <para>
/// To use <c>WinBioEnumEnrollments</c> asynchronously, call the function with a session handle created by calling
/// WinBioAsyncOpenSession. The framework allocates a WINBIO_ASYNC_RESULT structure and uses it to return information about
/// operation success or failure. If the operation is successful, the framework returns <c>WINBIO_IDENTITY</c> and
/// <c>WINBIO_BIOMETRIC_SUBTYPE</c> information in a nested <c>EnumEnrollments</c> structure. If the operation is unsuccessful, the
/// framework returns error information. The <c>WINBIO_ASYNC_RESULT</c> structure is returned to the application callback or to the
/// application message queue, depending on the value you set in the NotificationMethod parameter of the
/// <c>WinBioAsyncOpenSession</c> function:
/// </para>
/// <list type="bullet">
/// <item>
/// <term>
/// If you choose to receive completion notices by using a callback, you must implement a PWINBIO_ASYNC_COMPLETION_CALLBACK function
/// and set the NotificationMethod parameter to <c>WINBIO_ASYNC_NOTIFY_CALLBACK</c>.
/// </term>
/// </item>
/// <item>
/// <term>
/// If you choose to receive completion notices by using the application message queue, you must set the NotificationMethod
/// parameter to <c>WINBIO_ASYNC_NOTIFY_MESSAGE</c>. The framework returns a WINBIO_ASYNC_RESULT pointer to the <c>LPARAM</c> field
/// of the window message.
/// </term>
/// </item>
/// </list>
/// <para>
/// To prevent memory leaks, you must call WinBioFree to release the WINBIO_ASYNC_RESULT structure after you have finished using it.
/// </para>
/// <para>Examples</para>
/// <para>
/// The following function calls <c>WinBioEnumEnrollments</c> to enumerate the biometric sub-factors enrolled for a template. Link
/// to the Winbio.lib static library and include the following header files:
/// </para>
/// <list type="bullet">
/// <item>
/// <term>Windows.h</term>
/// </item>
/// <item>
/// <term>Stdio.h</term>
/// </item>
/// <item>
/// <term>Conio.h</term>
/// </item>
/// <item>
/// <term>Winbio.h</term>
/// </item>
/// </list>
/// <para>
/// <code>HRESULT EnumEnrollments( ) { // Declare variables. HRESULT hr = S_OK; WINBIO_IDENTITY identity = {0}; WINBIO_SESSION_HANDLE sessionHandle = NULL; WINBIO_UNIT_ID unitId = 0; PWINBIO_BIOMETRIC_SUBTYPE subFactorArray = NULL; WINBIO_BIOMETRIC_SUBTYPE SubFactor = 0; SIZE_T subFactorCount = 0; WINBIO_REJECT_DETAIL rejectDetail = 0; WINBIO_BIOMETRIC_SUBTYPE subFactor = WINBIO_SUBTYPE_NO_INFORMATION; // Connect to the system pool. hr = WinBioOpenSession( WINBIO_TYPE_FINGERPRINT, // Service provider WINBIO_POOL_SYSTEM, // Pool type WINBIO_FLAG_DEFAULT, // Configuration and access NULL, // Array of biometric unit IDs 0, // Count of biometric unit IDs NULL, // Database ID &amp;sessionHandle // [out] Session handle ); if (FAILED(hr)) { wprintf_s(L"\n WinBioOpenSession failed. hr = 0x%x\n", hr); goto e_Exit; } // Locate the biometric sensor and retrieve a WINBIO_IDENTITY object. wprintf_s(L"\n Calling WinBioIdentify - Swipe finger on sensor...\n"); hr = WinBioIdentify( sessionHandle, // Session handle &amp;unitId, // Biometric unit ID &amp;identity, // User SID &amp;subFactor, // Finger sub factor &amp;rejectDetail // Rejection information ); wprintf_s(L"\n Swipe processed - Unit ID: %d\n", unitId); if (FAILED(hr)) { if (hr == WINBIO_E_UNKNOWN_ID) { wprintf_s(L"\n Unknown identity.\n"); } else if (hr == WINBIO_E_BAD_CAPTURE) { wprintf_s(L"\n Bad capture; reason: %d\n", rejectDetail); } else { wprintf_s(L"\n WinBioEnumBiometricUnits failed. hr = 0x%x\n", hr); } goto e_Exit; } // Retrieve the biometric sub-factors for the template. hr = WinBioEnumEnrollments( sessionHandle, // Session handle unitId, // Biometric unit ID &amp;identity, // Template ID &amp;subFactorArray, // Subfactors &amp;subFactorCount // Count of subfactors ); if (FAILED(hr)) { wprintf_s(L"\n WinBioEnumEnrollments failed. hr = 0x%x\n", hr); goto e_Exit; } // Print the sub-factor(s) to the console. wprintf_s(L"\n Enrollments for this user on Unit ID %d:", unitId); for (SIZE_T index = 0; index &lt; subFactorCount; ++index) { SubFactor = subFactorArray[index]; switch (SubFactor) { case WINBIO_ANSI_381_POS_RH_THUMB: wprintf_s(L"\n RH thumb\n"); break; case WINBIO_ANSI_381_POS_RH_INDEX_FINGER: wprintf_s(L"\n RH index finger\n"); break; case WINBIO_ANSI_381_POS_RH_MIDDLE_FINGER: wprintf_s(L"\n RH middle finger\n"); break; case WINBIO_ANSI_381_POS_RH_RING_FINGER: wprintf_s(L"\n RH ring finger\n"); break; case WINBIO_ANSI_381_POS_RH_LITTLE_FINGER: wprintf_s(L"\n RH little finger\n"); break; case WINBIO_ANSI_381_POS_LH_THUMB: wprintf_s(L"\n LH thumb\n"); break; case WINBIO_ANSI_381_POS_LH_INDEX_FINGER: wprintf_s(L"\n LH index finger\n"); break; case WINBIO_ANSI_381_POS_LH_MIDDLE_FINGER: wprintf_s(L"\n LH middle finger\n"); break; case WINBIO_ANSI_381_POS_LH_RING_FINGER: wprintf_s(L"\n LH ring finger\n"); break; case WINBIO_ANSI_381_POS_LH_LITTLE_FINGER: wprintf_s(L"\n LH little finger\n"); break; default: wprintf_s(L"\n The sub-factor is not correct\n"); break; } } e_Exit: if (subFactorArray!= NULL) { WinBioFree(subFactorArray); subFactorArray = NULL; } if (sessionHandle != NULL) { WinBioCloseSession(sessionHandle); sessionHandle = NULL; } wprintf_s(L"\n Press any key to exit..."); _getch(); return hr; }</code>
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winbio/nf-winbio-winbioenumenrollments HRESULT WinBioEnumEnrollments(
// WINBIO_SESSION_HANDLE SessionHandle, WINBIO_UNIT_ID UnitId, WINBIO_IDENTITY *Identity, WINBIO_BIOMETRIC_SUBTYPE **SubFactorArray,
// SIZE_T *SubFactorCount );
[DllImport(Lib_Winbio, SetLastError = false, ExactSpelling = true)]
[PInvokeData("winbio.h", MSDNShortId = "NF:winbio.WinBioEnumEnrollments")]
public static extern HRESULT WinBioEnumEnrollments(WINBIO_SESSION_HANDLE SessionHandle, WINBIO_UNIT_ID UnitId, in WINBIO_IDENTITY Identity, out SafeWinBioMemory SubFactorArray, out SizeT SubFactorCount);
/// <summary>
/// Retrieves the biometric sub-factors enrolled for a specified identity and biometric unit. Starting with Windows 10, build 1607,
/// this function is available to use with a mobile image.
/// </summary>
/// <param name="SessionHandle">
/// A <c>WINBIO_SESSION_HANDLE</c> value that identifies an open biometric session. Open a synchronous session handle by calling
/// WinBioOpenSession. Open an asynchronous session handle by calling WinBioAsyncOpenSession.
/// </param>
/// <param name="UnitId">A <c>WINBIO_UNIT_ID</c> value that specifies the biometric unit.</param>
/// <param name="Identity">
/// Pointer to a WINBIO_IDENTITY structure that contains the GUID or SID of the template from which the sub-factors are to be retrieved.
/// </param>
/// <param name="SubFactorArray">
/// Address of a variable that receives a pointer to an array of sub-factors. If the function does not succeed, the pointer is set
/// to <c>NULL</c>. If the function succeeds, you must pass the pointer to WinBioFree to release memory allocated internally for the array.
/// </param>
/// <returns>
/// <para>
/// If the function succeeds, it returns S_OK. If the function fails, it returns an <c>HRESULT</c> value that indicates the error.
/// Possible values include, but are not limited to, those in the following table. For a list of common error codes, see Common
/// HRESULT Values.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>E_HANDLE</term>
/// <term>The session handle is not valid.</term>
/// </item>
/// <item>
/// <term>E_INVALIDARG</term>
/// <term>The UnitId parameter cannot be zero.</term>
/// </item>
/// <item>
/// <term>E_POINTER</term>
/// <term>The Identity, SubFactorArray, and SubFactorCount parameters cannot be NULL.</term>
/// </item>
/// <item>
/// <term>WINBIO_E_ENROLLMENT_IN_PROGRESS</term>
/// <term>
/// The operation could not be completed because the biometric unit specified by the UnitId parameter is currently being used for an
/// enrollment transaction.
/// </term>
/// </item>
/// <item>
/// <term>WINBIO_E_UNKNOWN_ID</term>
/// <term>The GUID or SID specified by the Identity parameter cannot be found.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// The <c>WinBioEnumEnrollments</c> function is supplied primarily so that the applications can provide user feedback. For example,
/// your application can call this function to tell the user which fingerprints are already enrolled on a specific fingerprint reader.
/// </para>
/// <para>
/// After you are finished using the structures returned to the SubFactorArray parameter, you must call WinBioFree to release the
/// memory allocated internally for the array.
/// </para>
/// <para>
/// To use <c>WinBioEnumEnrollments</c> synchronously, call the function with a session handle created by calling WinBioOpenSession.
/// The function blocks until the operation completes or an error is encountered.
/// </para>
/// <para>
/// To use <c>WinBioEnumEnrollments</c> asynchronously, call the function with a session handle created by calling
/// WinBioAsyncOpenSession. The framework allocates a WINBIO_ASYNC_RESULT structure and uses it to return information about
/// operation success or failure. If the operation is successful, the framework returns <c>WINBIO_IDENTITY</c> and
/// <c>WINBIO_BIOMETRIC_SUBTYPE</c> information in a nested <c>EnumEnrollments</c> structure. If the operation is unsuccessful, the
/// framework returns error information. The <c>WINBIO_ASYNC_RESULT</c> structure is returned to the application callback or to the
/// application message queue, depending on the value you set in the NotificationMethod parameter of the
/// <c>WinBioAsyncOpenSession</c> function:
/// </para>
/// <list type="bullet">
/// <item>
/// <term>
/// If you choose to receive completion notices by using a callback, you must implement a PWINBIO_ASYNC_COMPLETION_CALLBACK function
/// and set the NotificationMethod parameter to <c>WINBIO_ASYNC_NOTIFY_CALLBACK</c>.
/// </term>
/// </item>
/// <item>
/// <term>
/// If you choose to receive completion notices by using the application message queue, you must set the NotificationMethod
/// parameter to <c>WINBIO_ASYNC_NOTIFY_MESSAGE</c>. The framework returns a WINBIO_ASYNC_RESULT pointer to the <c>LPARAM</c> field
/// of the window message.
/// </term>
/// </item>
/// </list>
/// <para>
/// To prevent memory leaks, you must call WinBioFree to release the WINBIO_ASYNC_RESULT structure after you have finished using it.
/// </para>
/// <para>Examples</para>
/// <para>
/// The following function calls <c>WinBioEnumEnrollments</c> to enumerate the biometric sub-factors enrolled for a template. Link
/// to the Winbio.lib static library and include the following header files:
/// </para>
/// <list type="bullet">
/// <item>
/// <term>Windows.h</term>
/// </item>
/// <item>
/// <term>Stdio.h</term>
/// </item>
/// <item>
/// <term>Conio.h</term>
/// </item>
/// <item>
/// <term>Winbio.h</term>
/// </item>
/// </list>
/// <para>
/// <code>HRESULT EnumEnrollments( ) { // Declare variables. HRESULT hr = S_OK; WINBIO_IDENTITY identity = {0}; WINBIO_SESSION_HANDLE sessionHandle = NULL; WINBIO_UNIT_ID unitId = 0; PWINBIO_BIOMETRIC_SUBTYPE subFactorArray = NULL; WINBIO_BIOMETRIC_SUBTYPE SubFactor = 0; SIZE_T subFactorCount = 0; WINBIO_REJECT_DETAIL rejectDetail = 0; WINBIO_BIOMETRIC_SUBTYPE subFactor = WINBIO_SUBTYPE_NO_INFORMATION; // Connect to the system pool. hr = WinBioOpenSession( WINBIO_TYPE_FINGERPRINT, // Service provider WINBIO_POOL_SYSTEM, // Pool type WINBIO_FLAG_DEFAULT, // Configuration and access NULL, // Array of biometric unit IDs 0, // Count of biometric unit IDs NULL, // Database ID &amp;sessionHandle // [out] Session handle ); if (FAILED(hr)) { wprintf_s(L"\n WinBioOpenSession failed. hr = 0x%x\n", hr); goto e_Exit; } // Locate the biometric sensor and retrieve a WINBIO_IDENTITY object. wprintf_s(L"\n Calling WinBioIdentify - Swipe finger on sensor...\n"); hr = WinBioIdentify( sessionHandle, // Session handle &amp;unitId, // Biometric unit ID &amp;identity, // User SID &amp;subFactor, // Finger sub factor &amp;rejectDetail // Rejection information ); wprintf_s(L"\n Swipe processed - Unit ID: %d\n", unitId); if (FAILED(hr)) { if (hr == WINBIO_E_UNKNOWN_ID) { wprintf_s(L"\n Unknown identity.\n"); } else if (hr == WINBIO_E_BAD_CAPTURE) { wprintf_s(L"\n Bad capture; reason: %d\n", rejectDetail); } else { wprintf_s(L"\n WinBioEnumBiometricUnits failed. hr = 0x%x\n", hr); } goto e_Exit; } // Retrieve the biometric sub-factors for the template. hr = WinBioEnumEnrollments( sessionHandle, // Session handle unitId, // Biometric unit ID &amp;identity, // Template ID &amp;subFactorArray, // Subfactors &amp;subFactorCount // Count of subfactors ); if (FAILED(hr)) { wprintf_s(L"\n WinBioEnumEnrollments failed. hr = 0x%x\n", hr); goto e_Exit; } // Print the sub-factor(s) to the console. wprintf_s(L"\n Enrollments for this user on Unit ID %d:", unitId); for (SIZE_T index = 0; index &lt; subFactorCount; ++index) { SubFactor = subFactorArray[index]; switch (SubFactor) { case WINBIO_ANSI_381_POS_RH_THUMB: wprintf_s(L"\n RH thumb\n"); break; case WINBIO_ANSI_381_POS_RH_INDEX_FINGER: wprintf_s(L"\n RH index finger\n"); break; case WINBIO_ANSI_381_POS_RH_MIDDLE_FINGER: wprintf_s(L"\n RH middle finger\n"); break; case WINBIO_ANSI_381_POS_RH_RING_FINGER: wprintf_s(L"\n RH ring finger\n"); break; case WINBIO_ANSI_381_POS_RH_LITTLE_FINGER: wprintf_s(L"\n RH little finger\n"); break; case WINBIO_ANSI_381_POS_LH_THUMB: wprintf_s(L"\n LH thumb\n"); break; case WINBIO_ANSI_381_POS_LH_INDEX_FINGER: wprintf_s(L"\n LH index finger\n"); break; case WINBIO_ANSI_381_POS_LH_MIDDLE_FINGER: wprintf_s(L"\n LH middle finger\n"); break; case WINBIO_ANSI_381_POS_LH_RING_FINGER: wprintf_s(L"\n LH ring finger\n"); break; case WINBIO_ANSI_381_POS_LH_LITTLE_FINGER: wprintf_s(L"\n LH little finger\n"); break; default: wprintf_s(L"\n The sub-factor is not correct\n"); break; } } e_Exit: if (subFactorArray!= NULL) { WinBioFree(subFactorArray); subFactorArray = NULL; } if (sessionHandle != NULL) { WinBioCloseSession(sessionHandle); sessionHandle = NULL; } wprintf_s(L"\n Press any key to exit..."); _getch(); return hr; }</code>
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winbio/nf-winbio-winbioenumenrollments HRESULT WinBioEnumEnrollments(
// WINBIO_SESSION_HANDLE SessionHandle, WINBIO_UNIT_ID UnitId, WINBIO_IDENTITY *Identity, WINBIO_BIOMETRIC_SUBTYPE **SubFactorArray,
// SIZE_T *SubFactorCount );
[PInvokeData("winbio.h", MSDNShortId = "NF:winbio.WinBioEnumEnrollments")]
public static HRESULT WinBioEnumEnrollments(WINBIO_SESSION_HANDLE SessionHandle, WINBIO_UNIT_ID UnitId, in WINBIO_IDENTITY Identity, out WINBIO_BIOMETRIC_SUBTYPE[] SubFactorArray)
{
var ret = WinBioEnumEnrollments(SessionHandle, UnitId, Identity, out var a, out var c);
SubFactorArray = ret.Succeeded ? a.DangerousGetHandle().ToArray<WINBIO_BIOMETRIC_SUBTYPE>(c) : null;
return ret;
}
/// <summary>
/// Retrieves information about installed biometric service providers. Starting with Windows 10, build 1607, this function is
/// available to use with a mobile image.
/// </summary>
/// <param name="Factor">
/// A bitmask of WINBIO_BIOMETRIC_TYPE flags that specifies the biometric unit types to be enumerated. Only
/// <c>WINBIO_TYPE_FINGERPRINT</c> is currently supported.
/// </param>
/// <param name="BspSchemaArray">
/// Address of a variable that receives a pointer to an array of WINBIO_BSP_SCHEMA structures that contain information about each of
/// the available service providers. If the function does not succeed, the pointer is set to <c>NULL</c>. If the function succeeds,
/// you must pass the pointer to WinBioFree to release memory allocated internally for the array.
/// </param>
/// <param name="BspCount">Pointer to a value that specifies the number of structures pointed to by the BspSchemaArray parameter.</param>
/// <returns>
/// <para>
/// If the function succeeds, it returns S_OK. If the function fails, it returns an <c>HRESULT</c> value that indicates the error.
/// Possible values include, but are not limited to, those in the following table. For a list of common error codes, see Common
/// HRESULT Values.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>E_INVALIDARG</term>
/// <term>The bitmask contained in the Factor parameter contains one or more an invalid type bits.</term>
/// </item>
/// <item>
/// <term>E_OUTOFMEMORY</term>
/// <term>There was insufficient memory to complete the request.</term>
/// </item>
/// <item>
/// <term>E_POINTER</term>
/// <term>The BspSchemaArray and BspCount parameters cannot be NULL.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>Only <c>WINBIO_TYPE_FINGERPRINT</c> is currently supported in the Factor parameter.</para>
/// <para>
/// After you are finished using the structures returned to the BspSchemaArray parameter, you must call WinBioFree to release the
/// memory allocated internally for the array.
/// </para>
/// <para>
/// If all of the factor bits in the Factor bitmask refer to unsupported biometric types, the function returns S_OK but the value
/// pointed to by the BspSchemaArray parameter will be <c>NULL</c> and the BspCount parameter will contain zero. Although it is not
/// an error to inquire about unsupported biometric factors, the result of the query will be an empty set.
/// </para>
/// <para>Examples</para>
/// <para>
/// The following code example calls <c>WinBioEnumServiceProviders</c> to enumerate the installed service providers. The example
/// also includes a function, DisplayGuid, to display the provider ID. Link to the Winbio.lib static library and include the
/// following header files:
/// </para>
/// <list type="bullet">
/// <item>
/// <term>Windows.h</term>
/// </item>
/// <item>
/// <term>Stdio.h</term>
/// </item>
/// <item>
/// <term>Conio.h</term>
/// </item>
/// <item>
/// <term>Winbio.h</term>
/// </item>
/// </list>
/// <para>
/// <code>HRESULT EnumSvcProviders( ) { // Declare variables. HRESULT hr = S_OK; PWINBIO_BSP_SCHEMA bspSchemaArray = NULL; SIZE_T bspCount = 0; SIZE_T index = 0; // Enumerate the service providers. hr = WinBioEnumServiceProviders( WINBIO_TYPE_FINGERPRINT, // Provider to enumerate &amp;bspSchemaArray, // Provider schema array &amp;bspCount ); // Number of schemas returned if (FAILED(hr)) { wprintf_s(L"\n WinBioEnumServiceProviders failed. hr = 0x%x\n", hr); goto e_Exit; } // Display the schema information. wprintf_s(L"\nService providers: \n"); for (index = 0; index &lt; bspCount; ++index) { wprintf_s(L"\n[%d]: \tBiometric factor: 0x%08x\n", index, bspSchemaArray[index].BiometricFactor ); wprintf_s(L"\tBspId: "); DisplayGuid(&amp;bspSchemaArray[index].BspId); wprintf_s(L"\n"); wprintf_s(L"\tDescription: %ws\n", bspSchemaArray[index].Description); wprintf_s(L"\tVendor: %ws\n", bspSchemaArray[index].Vendor ); wprintf_s(L"\tVersion: %d.%d\n", bspSchemaArray[index].Version.MajorVersion, bspSchemaArray[index].Version.MinorVersion); wprintf_s(L"\n"); } e_Exit: if (bspSchemaArray != NULL) { WinBioFree(bspSchemaArray); bspSchemaArray = NULL; } wprintf_s(L"\nPress any key to exit..."); _getch(); return hr; } //------------------------------------------------------------------------ // The following function displays a GUID to the console window. // VOID DisplayGuid( __in PWINBIO_UUID Guid ) { wprintf_s( L"{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}", Guid-&gt;Data1, Guid-&gt;Data2, Guid-&gt;Data3, Guid-&gt;Data4[0], Guid-&gt;Data4[1], Guid-&gt;Data4[2], Guid-&gt;Data4[3], Guid-&gt;Data4[4], Guid-&gt;Data4[5], Guid-&gt;Data4[6], Guid-&gt;Data4[7] ); }</code>
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winbio/nf-winbio-winbioenumserviceproviders HRESULT
// WinBioEnumServiceProviders( WINBIO_BIOMETRIC_TYPE Factor, WINBIO_BSP_SCHEMA **BspSchemaArray, SIZE_T *BspCount );
[DllImport(Lib_Winbio, SetLastError = false, ExactSpelling = true)]
[PInvokeData("winbio.h", MSDNShortId = "NF:winbio.WinBioEnumServiceProviders")]
public static extern HRESULT WinBioEnumServiceProviders(WINBIO_BIOMETRIC_TYPE Factor, out SafeWinBioMemory BspSchemaArray, out SizeT BspCount);
/// <summary>
/// Retrieves information about installed biometric service providers. Starting with Windows 10, build 1607, this function is
/// available to use with a mobile image.
/// </summary>
/// <param name="Factor">
/// A bitmask of WINBIO_BIOMETRIC_TYPE flags that specifies the biometric unit types to be enumerated. Only
/// <c>WINBIO_TYPE_FINGERPRINT</c> is currently supported.
/// </param>
/// <param name="BspSchemaArray">
/// Address of a variable that receives a pointer to an array of WINBIO_BSP_SCHEMA structures that contain information about each of
/// the available service providers. If the function does not succeed, the pointer is set to <c>NULL</c>. If the function succeeds,
/// you must pass the pointer to WinBioFree to release memory allocated internally for the array.
/// </param>
/// <returns>
/// <para>
/// If the function succeeds, it returns S_OK. If the function fails, it returns an <c>HRESULT</c> value that indicates the error.
/// Possible values include, but are not limited to, those in the following table. For a list of common error codes, see Common
/// HRESULT Values.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>E_INVALIDARG</term>
/// <term>The bitmask contained in the Factor parameter contains one or more an invalid type bits.</term>
/// </item>
/// <item>
/// <term>E_OUTOFMEMORY</term>
/// <term>There was insufficient memory to complete the request.</term>
/// </item>
/// <item>
/// <term>E_POINTER</term>
/// <term>The BspSchemaArray and BspCount parameters cannot be NULL.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>Only <c>WINBIO_TYPE_FINGERPRINT</c> is currently supported in the Factor parameter.</para>
/// <para>
/// After you are finished using the structures returned to the BspSchemaArray parameter, you must call WinBioFree to release the
/// memory allocated internally for the array.
/// </para>
/// <para>
/// If all of the factor bits in the Factor bitmask refer to unsupported biometric types, the function returns S_OK but the value
/// pointed to by the BspSchemaArray parameter will be <c>NULL</c> and the BspCount parameter will contain zero. Although it is not
/// an error to inquire about unsupported biometric factors, the result of the query will be an empty set.
/// </para>
/// <para>Examples</para>
/// <para>
/// The following code example calls <c>WinBioEnumServiceProviders</c> to enumerate the installed service providers. The example
/// also includes a function, DisplayGuid, to display the provider ID. Link to the Winbio.lib static library and include the
/// following header files:
/// </para>
/// <list type="bullet">
/// <item>
/// <term>Windows.h</term>
/// </item>
/// <item>
/// <term>Stdio.h</term>
/// </item>
/// <item>
/// <term>Conio.h</term>
/// </item>
/// <item>
/// <term>Winbio.h</term>
/// </item>
/// </list>
/// <para>
/// <code>HRESULT EnumSvcProviders( ) { // Declare variables. HRESULT hr = S_OK; PWINBIO_BSP_SCHEMA bspSchemaArray = NULL; SIZE_T bspCount = 0; SIZE_T index = 0; // Enumerate the service providers. hr = WinBioEnumServiceProviders( WINBIO_TYPE_FINGERPRINT, // Provider to enumerate &amp;bspSchemaArray, // Provider schema array &amp;bspCount ); // Number of schemas returned if (FAILED(hr)) { wprintf_s(L"\n WinBioEnumServiceProviders failed. hr = 0x%x\n", hr); goto e_Exit; } // Display the schema information. wprintf_s(L"\nService providers: \n"); for (index = 0; index &lt; bspCount; ++index) { wprintf_s(L"\n[%d]: \tBiometric factor: 0x%08x\n", index, bspSchemaArray[index].BiometricFactor ); wprintf_s(L"\tBspId: "); DisplayGuid(&amp;bspSchemaArray[index].BspId); wprintf_s(L"\n"); wprintf_s(L"\tDescription: %ws\n", bspSchemaArray[index].Description); wprintf_s(L"\tVendor: %ws\n", bspSchemaArray[index].Vendor ); wprintf_s(L"\tVersion: %d.%d\n", bspSchemaArray[index].Version.MajorVersion, bspSchemaArray[index].Version.MinorVersion); wprintf_s(L"\n"); } e_Exit: if (bspSchemaArray != NULL) { WinBioFree(bspSchemaArray); bspSchemaArray = NULL; } wprintf_s(L"\nPress any key to exit..."); _getch(); return hr; } //------------------------------------------------------------------------ // The following function displays a GUID to the console window. // VOID DisplayGuid( __in PWINBIO_UUID Guid ) { wprintf_s( L"{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}", Guid-&gt;Data1, Guid-&gt;Data2, Guid-&gt;Data3, Guid-&gt;Data4[0], Guid-&gt;Data4[1], Guid-&gt;Data4[2], Guid-&gt;Data4[3], Guid-&gt;Data4[4], Guid-&gt;Data4[5], Guid-&gt;Data4[6], Guid-&gt;Data4[7] ); }</code>
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winbio/nf-winbio-winbioenumserviceproviders HRESULT
// WinBioEnumServiceProviders( WINBIO_BIOMETRIC_TYPE Factor, WINBIO_BSP_SCHEMA **BspSchemaArray, SIZE_T *BspCount );
[PInvokeData("winbio.h", MSDNShortId = "NF:winbio.WinBioEnumServiceProviders")]
public static HRESULT WinBioEnumServiceProviders(WINBIO_BIOMETRIC_TYPE Factor, out WINBIO_BSP_SCHEMA[] BspSchemaArray) => GetEnum(WinBioEnumServiceProviders, Factor, out BspSchemaArray);
/// <summary>
/// Releases memory allocated for the client application by an earlier call to a Windows Biometric Framework API function. Starting
/// with Windows 10, build 1607, this function is available to use with a mobile image.
/// </summary>
/// <param name="Address">Address of the memory block to delete.</param>
/// <returns>
/// <para>
/// If the function succeeds, it returns S_OK. If the function fails, it returns an <c>HRESULT</c> value that indicates the error.
/// Possible values include, but are not limited to, those in the following table. For a list of common error codes, see Common
/// HRESULT Values.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>E_POINTER</term>
/// <term>The Address parameter cannot be NULL.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// Multiple functions in the Windows Biometric Framework API allocate memory for the client application and pass the address of
/// that memory to the client. To prevent memory leaks, you must call <c>WinBioFree</c> to delete the block when you are done using
/// the information it contains. You delete the memory by passing its address to <c>WinBioFree</c>. You can find the address by
/// de-referencing the pointer specified by the appropriate parameter in each of the following functions.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Function</term>
/// <term>Parameter</term>
/// <term>Type of block allocated</term>
/// </listheader>
/// <item>
/// <term>WinBioCaptureSample</term>
/// <term>Sample</term>
/// <term>Structure</term>
/// </item>
/// <item>
/// <term>WinBioEnumBiometricUnits</term>
/// <term>UnitSchemaArray</term>
/// <term>Array of structures</term>
/// </item>
/// <item>
/// <term>WinBioEnumDatabases</term>
/// <term>StorageSchemaArray</term>
/// <term>Array of structures</term>
/// </item>
/// <item>
/// <term>WinBioEnumEnrollments</term>
/// <term>SubFactorArray</term>
/// <term>Array of integers</term>
/// </item>
/// <item>
/// <term>WinBioEnumServiceProviders</term>
/// <term>BspSchemaArray</term>
/// <term>Array of structures</term>
/// </item>
/// <item>
/// <term>EventCallBack</term>
/// <term>Event</term>
/// <term>Structure</term>
/// </item>
/// <item>
/// <term>CaptureCallback</term>
/// <term>Sample</term>
/// <term>Structure</term>
/// </item>
/// </list>
/// <para>Examples</para>
/// <para>
/// The following function calls WinBioEnumBiometricUnits to enumerate the installed biometric sensors, and it calls
/// <c>WinBioFree</c> to release the memory created by <c>WinBioEnumBiometricUnits</c>. Link to the Winbio.lib static library and
/// include the following header files:
/// </para>
/// <list type="bullet">
/// <item>
/// <term>Windows.h</term>
/// </item>
/// <item>
/// <term>Stdio.h</term>
/// </item>
/// <item>
/// <term>Conio.h</term>
/// </item>
/// <item>
/// <term>Winbio.h</term>
/// </item>
/// </list>
/// <para>
/// <code>HRESULT EnumerateSensors( ) { HRESULT hr = S_OK; PWINBIO_UNIT_SCHEMA unitSchema = NULL; SIZE_T unitCount = 0; // Enumerate the installed biometric units. hr = WinBioEnumBiometricUnits( WINBIO_TYPE_FINGERPRINT, // Type of biometric unit &amp;unitSchema, // Array of unit schemas &amp;unitCount ); // Count of unit schemas if (FAILED(hr)) { wprintf_s(L"\nWinBioEnumBiometricUnits failed. hr = 0x%x\n", hr); goto e_Exit; } e_Exit: // Free memory. if (unitSchema != NULL) { WinBioFree(unitSchema); unitSchema = NULL; } return hr; }</code>
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winbio/nf-winbio-winbiofree HRESULT WinBioFree( PVOID Address );
[DllImport(Lib_Winbio, SetLastError = false, ExactSpelling = true)]
[PInvokeData("winbio.h", MSDNShortId = "NF:winbio.WinBioFree")]
public static extern HRESULT WinBioFree(IntPtr Address);
/// <summary>
/// Retrieves a value that specifies whether credentials have been set for the specified user. Starting with Windows 10, build 1607,
/// this function is available to use with a mobile image.
/// </summary>
/// <param name="Identity">
/// A WINBIO_IDENTITY structure that contains the SID of the user account for which the credential is being queried.
/// </param>
/// <param name="Type">
/// <para>A WINBIO_CREDENTIAL_TYPE value that specifies the credential type. This can be one of the following values:</para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>WINBIO_CREDENTIAL_PASSWORD</term>
/// <term>The password-based credential is checked.</term>
/// </item>
/// </list>
/// </param>
/// <param name="CredentialState">
/// <para>
/// Pointer to a WINBIO_CREDENTIAL_STATE enumeration value that specifies whether user credentials have been set. This can be one of
/// the following values:
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>WINBIO_CREDENTIAL_NOT_SET</term>
/// <term>A credential has not been specified.</term>
/// </item>
/// <item>
/// <term>WINBIO_CREDENTIAL_SET</term>
/// <term>A credential has been specified.</term>
/// </item>
/// </list>
/// </param>
/// <returns>
/// <para>
/// If the function succeeds, it returns S_OK. If the function fails, it returns an <c>HRESULT</c> value that indicates the error.
/// Possible values include, but are not limited to, those in the following table. For a list of common error codes, see Common
/// HRESULT Values.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>E_ACCESSDENIED</term>
/// <term>The caller does not have permission to retrieve the credential state.</term>
/// </item>
/// <item>
/// <term>WINBIO_E_UNKNOWN_ID</term>
/// <term>The specified identity does not exist.</term>
/// </item>
/// <item>
/// <term>WINBIO_E_CRED_PROV_DISABLED</term>
/// <term>Current administrative policy prohibits use of the credential provider.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// The <c>WinBioGetCredentialState</c> is typically used to provide feedback about credential state in a user interface. For
/// example, an enrollment application might query credential state before prompting a user for credentials.
/// </para>
/// <para>Call the WinBioSetCredential function to associate credentials with a user.</para>
/// <para>
/// Users who do not have elevated privileges can retrieve information about only their own credentials. Elevated users can retrieve
/// information for any credential.
/// </para>
/// <para>Examples</para>
/// <para>
/// The following function calls <c>WinBioGetCredentialState</c> to retrieve the credential state for a user. Link to the Winbio.lib
/// static library and include the following header files:
/// </para>
/// <list type="bullet">
/// <item>
/// <term>Windows.h</term>
/// </item>
/// <item>
/// <term>Stdio.h</term>
/// </item>
/// <item>
/// <term>Conio.h</term>
/// </item>
/// <item>
/// <term>Winbio.h</term>
/// </item>
/// </list>
/// <para>
/// <code>HRESULT GetCredentialState() { // Declare variables. HRESULT hr = S_OK; WINBIO_IDENTITY identity; WINBIO_CREDENTIAL_STATE credState; // Find the identity of the user. wprintf_s(L"\n Finding user identity.\n"); hr = GetCurrentUserIdentity( &amp;identity ); if (FAILED(hr)) { wprintf_s(L"\n User identity not found. hr = 0x%x\n", hr); return hr; } // Find the credential state for the user. wprintf_s(L"\n Calling WinBioGetCredentialState.\n"); hr = WinBioGetCredentialState( identity, // User GUID or SID WINBIO_CREDENTIAL_PASSWORD, // Credential type &amp;credState // [out] Credential state ); if (FAILED(hr)) { wprintf_s(L"\n WinBioGetCredentialState failed. hr = 0x%x\n", hr); goto e_Exit; } // Print the credential state. switch(credState) { case WINBIO_CREDENTIAL_SET: wprintf_s(L"\n Credential set.\n"); break; case WINBIO_CREDENTIAL_NOT_SET: wprintf_s(L"\n Credential NOT set.\n"); break; default: wprintf_s(L"\n ERROR: Invalid credential state.\n"); hr = E_FAIL; } e_Exit: wprintf_s(L"\n Press any key to exit..."); _getch(); return hr; } //------------------------------------------------------------------------ // The following function retrieves the identity of the current user. // This is a helper function and is not part of the Windows Biometric // Framework API. // HRESULT GetCurrentUserIdentity(__inout PWINBIO_IDENTITY Identity) { // Declare variables. HRESULT hr = S_OK; HANDLE tokenHandle = NULL; DWORD bytesReturned = 0; struct{ TOKEN_USER tokenUser; BYTE buffer[SECURITY_MAX_SID_SIZE]; } tokenInfoBuffer; // Zero the input identity and specify the type. ZeroMemory( Identity, sizeof(WINBIO_IDENTITY)); Identity-&gt;Type = WINBIO_ID_TYPE_NULL; // Open the access token associated with the // current process if (!OpenProcessToken( GetCurrentProcess(), // Process handle TOKEN_READ, // Read access only &amp;tokenHandle)) // Access token handle { DWORD win32Status = GetLastError(); wprintf_s(L"Cannot open token handle: %d\n", win32Status); hr = HRESULT_FROM_WIN32(win32Status); goto e_Exit; } // Zero the tokenInfoBuffer structure. ZeroMemory(&amp;tokenInfoBuffer, sizeof(tokenInfoBuffer)); // Retrieve information about the access token. In this case, // retrieve a SID. if (!GetTokenInformation( tokenHandle, // Access token handle TokenUser, // User for the token &amp;tokenInfoBuffer.tokenUser, // Buffer to fill sizeof(tokenInfoBuffer), // Size of the buffer &amp;bytesReturned)) // Size needed { DWORD win32Status = GetLastError(); wprintf_s(L"Cannot query token information: %d\n", win32Status); hr = HRESULT_FROM_WIN32(win32Status); goto e_Exit; } // Copy the SID from the tokenInfoBuffer structure to the // WINBIO_IDENTITY structure. CopySid( SECURITY_MAX_SID_SIZE, Identity-&gt;Value.AccountSid.Data, tokenInfoBuffer.tokenUser.User.Sid ); // Specify the size of the SID and assign WINBIO_ID_TYPE_SID // to the type member of the WINBIO_IDENTITY structure. Identity-&gt;Value.AccountSid.Size = GetLengthSid(tokenInfoBuffer.tokenUser.User.Sid); Identity-&gt;Type = WINBIO_ID_TYPE_SID; e_Exit: if (tokenHandle != NULL) { CloseHandle(tokenHandle); } return hr; }</code>
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winbio/nf-winbio-winbiogetcredentialstate HRESULT WinBioGetCredentialState(
// WINBIO_IDENTITY Identity, WINBIO_CREDENTIAL_TYPE Type, WINBIO_CREDENTIAL_STATE *CredentialState );
[DllImport(Lib_Winbio, SetLastError = true, ExactSpelling = true)]
[PInvokeData("winbio.h", MSDNShortId = "NF:winbio.WinBioGetCredentialState")]
public static extern HRESULT WinBioGetCredentialState(WINBIO_IDENTITY Identity, WINBIO_CREDENTIAL_TYPE Type, out WINBIO_CREDENTIAL_STATE CredentialState);
/// <summary>Retrieves a value that specifies whether users can log on to a domain by using biometric information.</summary>
/// <param name="Value">Pointer to a Boolean value that specifies whether biometric domain logons are enabled.</param>
/// <param name="Source">
/// <para>
/// Pointer to a <c>WINBIO_SETTING_SOURCE_TYPE</c> value that specifies the setting source. This can be one of the following values:
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>WINBIO_SETTING_SOURCE_INVALID</term>
/// <term>The setting is not valid.</term>
/// </item>
/// <item>
/// <term>WINBIO_SETTING_SOURCE_DEFAULT</term>
/// <term>The setting originated from built-in policy.</term>
/// </item>
/// <item>
/// <term>WINBIO_SETTING_SOURCE_LOCAL</term>
/// <term>The setting originated in the local computer registry.</term>
/// </item>
/// <item>
/// <term>WINBIO_SETTING_SOURCE_POLICY</term>
/// <term>The setting was created by Group Policy.</term>
/// </item>
/// </list>
/// </param>
/// <returns>
/// If the function succeeds, it returns S_OK. If the function fails, it returns an <c>HRESULT</c> value that indicates the error.
/// For a list of common error codes, see Common HRESULT Values.
/// </returns>
// https://docs.microsoft.com/en-us/windows/win32/api/winbio/nf-winbio-winbiogetdomainlogonsetting void WinBioGetDomainLogonSetting(
// BOOLEAN *Value, PWINBIO_SETTING_SOURCE_TYPE Source );
[DllImport(Lib_Winbio, SetLastError = false, ExactSpelling = true)]
[PInvokeData("winbio.h", MSDNShortId = "NF:winbio.WinBioGetDomainLogonSetting")]
public static extern void WinBioGetDomainLogonSetting([MarshalAs(UnmanagedType.U1)] out bool Value, out WINBIO_SETTING_SOURCE_TYPE Source);
/// <summary>Retrieves a value that specifies whether the Windows Biometric Framework is currently enabled.</summary>
/// <param name="Value">Pointer to a Boolean value that specifies whether the Windows Biometric Framework is currently enabled.</param>
/// <param name="Source">
/// <para>
/// Pointer to a <c>WINBIO_SETTING_SOURCE_TYPE</c> value that specifics the setting source. This can be one of the following values:
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>WINBIO_SETTING_SOURCE_INVALID</term>
/// <term>The setting is not valid.</term>
/// </item>
/// <item>
/// <term>WINBIO_SETTING_SOURCE_DEFAULT</term>
/// <term>The setting originated from built-in policy.</term>
/// </item>
/// <item>
/// <term>WINBIO_SETTING_SOURCE_LOCAL</term>
/// <term>The setting originated in the local computer registry.</term>
/// </item>
/// <item>
/// <term>WINBIO_SETTING_SOURCE_POLICY</term>
/// <term>The setting was created by Group Policy.</term>
/// </item>
/// </list>
/// </param>
/// <returns>
/// If the function succeeds, it returns S_OK. If the function fails, it returns an <c>HRESULT</c> value that indicates the error.
/// For a list of common error codes, see Common HRESULT Values.
/// </returns>
// https://docs.microsoft.com/en-us/windows/win32/api/winbio/nf-winbio-winbiogetenabledsetting void WinBioGetEnabledSetting( BOOLEAN
// *Value, PWINBIO_SETTING_SOURCE_TYPE Source );
[DllImport(Lib_Winbio, SetLastError = false, ExactSpelling = true)]
[PInvokeData("winbio.h", MSDNShortId = "NF:winbio.WinBioGetEnabledSetting")]
public static extern void WinBioGetEnabledSetting([MarshalAs(UnmanagedType.U1)] out bool Value, out WINBIO_SETTING_SOURCE_TYPE Source);
/// <summary>
/// Gets information about the biometric enrollments that the specified user has on the computer. Biometric enrollments include
/// enrollments for facial recognition, fingerprint scanning, iris scanning, and so on.
/// </summary>
/// <param name="AccountOwner"><para>A WINBIO_IDENTITY structure for the user whose biometric enrollments you want to get. For example:</para>
/// <para><code>WINBIO_IDENTITY identity = {};
/// identity.Type = WINBIO_ID_TYPE_SID;
/// // Move an account SID into identity.Value.AccountSid.Data.
/// // For example, CopySid(...)</code></para>
/// <para>To see the enrollments for every user on the computer, specify the <c>WINBIO_ID_TYPE_WILDCARD</c> identity type for the
/// WINBIO_IDENTITY structure that you specify for the AccountOwner parameter. For example:</para>
/// <para><code>WINBIO_IDENTITY identity = {};
/// identity.Type = WINBIO_ID_TYPE_WILDCARD;</code></para></param>
/// <param name="EnrolledFactors">
/// <para>
/// A set of WINBIO_BIOMETRIC_TYPE flags that indicate the biometric enrollments that the specified user has on the computer. A
/// value of 0 indicates that the user has no biometric enrollments.
/// </para>
/// <para>
/// These enrollments represent system pool enrollments only, such as enrollments that you can use to authenticate a user for
/// sign-in, unlock, and so on. This value does not include private pool enrollments.
/// </para>
/// <para>
/// If you specify the wildcard identity type for the WINBIO_IDENTITY structure that you use for the AccountOwner parameter, this
/// set of flags represents the combined set of enrollments for all users with accounts on the computer.
/// </para>
/// </param>
/// <returns>
/// <para>
/// If the function succeeds, it returns <c>S_OK</c>. If the function fails, it returns an <c>HRESULT</c> value that indicates the
/// error. Possible values include, but are not limited to, those in the following table. For a list of common error codes, see
/// Common HRESULT Values.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>E_POINTER</term>
/// <term>The AccountOwner and EnrolledFactors parameters cannot be NULL.</term>
/// </item>
/// <item>
/// <term>E_INVALIDARG</term>
/// <term>
/// The Type member of the WINBIO_IDENTITY structure that the AccountOnwer parameter specified was not WINBIO_ID_TYPE_SID or
/// WINBIO_ID_TYPE_WILDCARD, or the AccountSid member of the WINBIO_IDENTITY structure was not valid.
/// </term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// <c>WinBioGetEnrolledFactors</c> does not require a biometric session handle and does not activate the biometric service.
/// Consequently, <c>WinBioGetEnrolledFactors</c> runs quickly and is useful when your code needs to make quick decisions about how
/// to proceed when time is critical for the set of operations you need to perform.
/// </para>
/// <para>
/// <c>WinBioGetEnrolledFactors</c> provides credential providers with a way to tailor their UI appropriately. For example, the
/// login screen calls <c>WinBioGetEnrolledFactors</c> to determine whether to display the option to login with a fingerprint.
/// </para>
/// <para>Examples</para>
/// <para>
/// <code>WINBIO_BIOMETRIC_TYPE enrolledFactors = WINBIO_NO_TYPE_AVAILABLE;
/// WINBIO_IDENTITY identity = {};
/// identity.Type = WINBIO_ID_TYPE_SID;
/// // Move an account SID into identity.Value.AccountSid.Data.
/// // e.g., CopySid(...)
/// HRESULT hr = WinBioGetEnrolledFactors(&amp;identity, &amp;enrolledFactors);</code>
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winbio/nf-winbio-winbiogetenrolledfactors HRESULT WinBioGetEnrolledFactors(
// WINBIO_IDENTITY *AccountOwner, WINBIO_BIOMETRIC_TYPE *EnrolledFactors );
[DllImport(Lib_Winbio, SetLastError = false, ExactSpelling = true)]
[PInvokeData("winbio.h", MSDNShortId = "NF:winbio.WinBioGetEnrolledFactors")]
public static extern HRESULT WinBioGetEnrolledFactors(in WINBIO_IDENTITY AccountOwner, out WINBIO_BIOMETRIC_TYPE EnrolledFactors);
/// <summary>Retrieves a value that indicates whether users can log on by using biometric information.</summary>
/// <param name="Value">Pointer to a Boolean value that specifies whether biometric logons are enabled.</param>
/// <param name="Source">
/// <para>
/// Pointer to a <c>WINBIO_SETTING_SOURCE_TYPE</c> value that specifics the setting source. This can be one of the following values:
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>WINBIO_SETTING_SOURCE_INVALID</term>
/// <term>The setting is not valid.</term>
/// </item>
/// <item>
/// <term>WINBIO_SETTING_SOURCE_DEFAULT</term>
/// <term>The setting originated from built-in policy.</term>
/// </item>
/// <item>
/// <term>WINBIO_SETTING_SOURCE_LOCAL</term>
/// <term>The setting originated in the local computer registry.</term>
/// </item>
/// <item>
/// <term>WINBIO_SETTING_SOURCE_POLICY</term>
/// <term>The setting was created by Group Policy.</term>
/// </item>
/// </list>
/// </param>
/// <returns>
/// If the function succeeds, it returns S_OK. If the function fails, it returns an <c>HRESULT</c> value that indicates the error.
/// For a list of common error codes, see Common HRESULT Values.
/// </returns>
// https://docs.microsoft.com/en-us/windows/win32/api/winbio/nf-winbio-winbiogetlogonsetting void WinBioGetLogonSetting( BOOLEAN
// *Value, PWINBIO_SETTING_SOURCE_TYPE Source );
[DllImport(Lib_Winbio, SetLastError = false, ExactSpelling = true)]
[PInvokeData("winbio.h", MSDNShortId = "NF:winbio.WinBioGetLogonSetting")]
public static extern void WinBioGetLogonSetting([MarshalAs(UnmanagedType.U1)] out bool Value, out WINBIO_SETTING_SOURCE_TYPE Source);
/// <summary>
/// Retrieves a session, unit, or template property. Starting with Windows 10, build 1607, this function is available to use with a
/// mobile image.
/// </summary>
/// <param name="SessionHandle">
/// A WINBIO_SESSION_HANDLE value that identifies an open biometric session. Open a synchronous session handle by calling
/// WinBioOpenSession. Open an asynchronous session handle by calling WinBioAsyncOpenSession.
/// </param>
/// <param name="PropertyType">
/// A WINBIO_PROPERTY_TYPE value that specifies the source of the property information. Currently this must be
/// WINBIO_PROPERTY_TYPE_UNIT or WINBIO_PROPERTY_TYPE_ACCOUNT. For more information about property types, see WINBIO_PROPERTY_TYPE Constants.
/// <para>The WINBIO_PROPERTY_TYPE_ACCOUNT value is supported starting in Windows 10.</para>
/// </param>
/// <param name="PropertyId">A WINBIO_PROPERTY_ID value that specifies the property that you want to query.</param>
/// <param name="UnitId">
/// A WINBIO_UNIT_ID value that identifies the biometric unit. You can find a unit identifier by calling the
/// WinBioEnumBiometricUnits or WinBioLocateSensor functions.
/// <para>
/// If you specify WINBIO_PROPERTY_ANTI_SPOOF_POLICY as the value for the PropertyId parameter, specify 0 for the UnitId
/// parameter.If you specify any other property with the PropertyId parameter, you cannot specify 0 for the UnitId parameter.
/// </para>
/// </param>
/// <param name="Identity">
/// A WINBIO_IDENTITY structure that provides the SID of the account for which you want to get the antispoofing policy, if you
/// specify WINBIO_PROPERTY_ANTI_SPOOF_POLICY as the value of the PropertyId parameter.
/// <para>If you specify any other value for the PropertyId parameter, the Identity parameter must be NULL.</para>
/// </param>
/// <param name="SubFactor">Reserved. This must be WINBIO_SUBTYPE_NO_INFORMATION.</param>
/// <param name="PropertyBuffer">
/// Address of a pointer to a buffer that receives the property value. For information about the contents of this buffer for
/// different properties, see the descriptions of the property values for the PropertyId parameter.
/// </param>
/// <param name="PropertyBufferSize">
/// Pointer to a variable that receives the size, in bytes, of the buffer pointed to by the PropertyBuffer parameter.
/// </param>
/// <returns>
/// If the function succeeds, it returns S_OK. If the function fails, it returns an HRESULT value that indicates the error. Possible
/// values include, but are not limited to, those in the following table. For a list of common error codes, see Common HRESULT Values.
/// </returns>
/// <remarks>
/// <para>
/// To use WinBioGetProperty synchronously, call the function with a session handle created by calling WinBioOpenSession. The
/// function blocks until the operation completes or an error is encountered. To prevent memory leaks when you use WinBioGetProperty
/// synchronously, you must call WinBioFree to release the memory pointed to by the PropertyBuffer parameter when you are finished
/// using the data contained in the buffer.
/// </para>
/// <para>
/// To use WinBioGetProperty asynchronously, call the function with a session handle created by calling WinBioAsyncOpenSession. The
/// framework allocates a WINBIO_ASYNC_RESULT structure and uses it to return information about operation success or failure. If the
/// operation is successful, the framework returns information in a nested GetProperty structure. The WINBIO_ASYNC_RESULT structure
/// is returned to the application callback or to the application message queue, depending on the value you set in the
/// NotificationMethod parameter of the WinBioAsyncOpenSession function:
/// </para>
/// <list type="bullet">
/// <item>
/// If you choose to receive completion notices by using a callback, you must implement a PWINBIO_ASYNC_COMPLETION_CALLBACK function
/// and set the NotificationMethod parameter to WINBIO_ASYNC_NOTIFY_CALLBACK.
/// </item>
/// <item>
/// If you choose to receive completion notices by using the application message queue, you must set the NotificationMethod
/// parameter to WINBIO_ASYNC_NOTIFY_MESSAGE. The framework returns a WINBIO_ASYNC_RESULT pointer to the LPARAM field of the window message.
/// </item>
/// </list>
/// <para>
/// To prevent memory leaks when you use WinBioGetProperty asynchronously, you must call WinBioFree to release the
/// WINBIO_ASYNC_RESULT structure after you have finished using it. The WINBIO_ASYNC_RESULT structure and the property buffer occupy
/// a single block of memory, so your application only needs to pass the address of the WINBIO_ASYNC_RESULT structure to WinBioFree.
/// When you call WinBioFree this way, WinBioFree automatically releases both the WINBIO_ASYNC_RESULT structure and the property
/// buffer. If you try to release the property buffer separately in this case, the application stops responding.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winbio/nf-winbio-winbiogetproperty
[DllImport(Lib_Winbio, SetLastError = false, ExactSpelling = true)]
[PInvokeData("winbio.h", MSDNShortId = "NF:winbio.WinBioGetProperty")]
public static extern HRESULT WinBioGetProperty(WINBIO_SESSION_HANDLE SessionHandle, WINBIO_PROPERTY_TYPE PropertyType, WINBIO_PROPERTY_ID PropertyId,
[In, Optional] WINBIO_UNIT_ID UnitId, [In, Optional] IntPtr Identity, [In, Optional] WINBIO_BIOMETRIC_SUBTYPE SubFactor,
out SafeWinBioMemory PropertyBuffer, out SizeT PropertyBufferSize);
/// <summary>
/// Retrieves a session, unit, or template property. Starting with Windows 10, build 1607, this function is available to use with a
/// mobile image.
/// </summary>
/// <param name="SessionHandle">
/// A WINBIO_SESSION_HANDLE value that identifies an open biometric session. Open a synchronous session handle by calling
/// WinBioOpenSession. Open an asynchronous session handle by calling WinBioAsyncOpenSession.
/// </param>
/// <param name="PropertyType">
/// A WINBIO_PROPERTY_TYPE value that specifies the source of the property information. Currently this must be
/// WINBIO_PROPERTY_TYPE_UNIT or WINBIO_PROPERTY_TYPE_ACCOUNT. For more information about property types, see WINBIO_PROPERTY_TYPE Constants.
/// <para>The WINBIO_PROPERTY_TYPE_ACCOUNT value is supported starting in Windows 10.</para>
/// </param>
/// <param name="PropertyId">A WINBIO_PROPERTY_ID value that specifies the property that you want to query.</param>
/// <param name="UnitId">
/// A WINBIO_UNIT_ID value that identifies the biometric unit. You can find a unit identifier by calling the
/// WinBioEnumBiometricUnits or WinBioLocateSensor functions.
/// <para>
/// If you specify WINBIO_PROPERTY_ANTI_SPOOF_POLICY as the value for the PropertyId parameter, specify 0 for the UnitId
/// parameter.If you specify any other property with the PropertyId parameter, you cannot specify 0 for the UnitId parameter.
/// </para>
/// </param>
/// <param name="Identity">
/// A WINBIO_IDENTITY structure that provides the SID of the account for which you want to get the antispoofing policy, if you
/// specify WINBIO_PROPERTY_ANTI_SPOOF_POLICY as the value of the PropertyId parameter.
/// <para>If you specify any other value for the PropertyId parameter, the Identity parameter must be NULL.</para>
/// </param>
/// <param name="SubFactor">Reserved. This must be WINBIO_SUBTYPE_NO_INFORMATION.</param>
/// <param name="PropertyBuffer">
/// Address of a pointer to a buffer that receives the property value. For information about the contents of this buffer for
/// different properties, see the descriptions of the property values for the PropertyId parameter.
/// </param>
/// <param name="PropertyBufferSize">
/// Pointer to a variable that receives the size, in bytes, of the buffer pointed to by the PropertyBuffer parameter.
/// </param>
/// <returns>
/// If the function succeeds, it returns S_OK. If the function fails, it returns an HRESULT value that indicates the error. Possible
/// values include, but are not limited to, those in the following table. For a list of common error codes, see Common HRESULT Values.
/// </returns>
/// <remarks>
/// <para>
/// To use WinBioGetProperty synchronously, call the function with a session handle created by calling WinBioOpenSession. The
/// function blocks until the operation completes or an error is encountered. To prevent memory leaks when you use WinBioGetProperty
/// synchronously, you must call WinBioFree to release the memory pointed to by the PropertyBuffer parameter when you are finished
/// using the data contained in the buffer.
/// </para>
/// <para>
/// To use WinBioGetProperty asynchronously, call the function with a session handle created by calling WinBioAsyncOpenSession. The
/// framework allocates a WINBIO_ASYNC_RESULT structure and uses it to return information about operation success or failure. If the
/// operation is successful, the framework returns information in a nested GetProperty structure. The WINBIO_ASYNC_RESULT structure
/// is returned to the application callback or to the application message queue, depending on the value you set in the
/// NotificationMethod parameter of the WinBioAsyncOpenSession function:
/// </para>
/// <list type="bullet">
/// <item>
/// If you choose to receive completion notices by using a callback, you must implement a PWINBIO_ASYNC_COMPLETION_CALLBACK function
/// and set the NotificationMethod parameter to WINBIO_ASYNC_NOTIFY_CALLBACK.
/// </item>
/// <item>
/// If you choose to receive completion notices by using the application message queue, you must set the NotificationMethod
/// parameter to WINBIO_ASYNC_NOTIFY_MESSAGE. The framework returns a WINBIO_ASYNC_RESULT pointer to the LPARAM field of the window message.
/// </item>
/// </list>
/// <para>
/// To prevent memory leaks when you use WinBioGetProperty asynchronously, you must call WinBioFree to release the
/// WINBIO_ASYNC_RESULT structure after you have finished using it. The WINBIO_ASYNC_RESULT structure and the property buffer occupy
/// a single block of memory, so your application only needs to pass the address of the WINBIO_ASYNC_RESULT structure to WinBioFree.
/// When you call WinBioFree this way, WinBioFree automatically releases both the WINBIO_ASYNC_RESULT structure and the property
/// buffer. If you try to release the property buffer separately in this case, the application stops responding.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winbio/nf-winbio-winbiogetproperty
[DllImport(Lib_Winbio, SetLastError = false, ExactSpelling = true)]
[PInvokeData("winbio.h", MSDNShortId = "NF:winbio.WinBioGetProperty")]
public static extern HRESULT WinBioGetProperty(WINBIO_SESSION_HANDLE SessionHandle, WINBIO_PROPERTY_TYPE PropertyType, WINBIO_PROPERTY_ID PropertyId,
[In, Optional] WINBIO_UNIT_ID UnitId, in WINBIO_IDENTITY Identity, [In, Optional] WINBIO_BIOMETRIC_SUBTYPE SubFactor,
out SafeWinBioMemory PropertyBuffer, out SizeT PropertyBufferSize);
/// <summary>
/// Captures a biometric sample and determines whether it matches an existing biometric template. Starting with Windows 10, build
/// 1607, this function is available to use with a mobile image.
/// </summary>
/// <param name="SessionHandle">
/// A <c>WINBIO_SESSION_HANDLE</c> value that identifies an open biometric session. Open a synchronous session handle by calling
/// WinBioOpenSession. Open an asynchronous session handle by calling WinBioAsyncOpenSession.
/// </param>
/// <param name="UnitId">A pointer to a <c>ULONG</c> value that specifies the biometric unit used to perform the identification.</param>
/// <param name="Identity">
/// Pointer to a WINBIO_IDENTITY structure that receives the GUID or SID of the user providing the biometric sample.
/// </param>
/// <param name="SubFactor">
/// Pointer to a <c>WINBIO_BIOMETRIC_SUBTYPE</c> value that receives the sub-factor associated with the biometric sample. See the
/// Remarks section for more details.
/// </param>
/// <param name="RejectDetail">
/// <para>
/// A pointer to a <c>ULONG</c> value that contains additional information about the failure, if any, to capture a biometric sample.
/// If the capture succeeded, this parameter is set to zero. The following values are defined for fingerprint capture:
/// </para>
/// <list type="bullet">
/// <item>
/// <term>WINBIO_FP_TOO_HIGH</term>
/// </item>
/// <item>
/// <term>WINBIO_FP_TOO_LOW</term>
/// </item>
/// <item>
/// <term>WINBIO_FP_TOO_LEFT</term>
/// </item>
/// <item>
/// <term>WINBIO_FP_TOO_RIGHT</term>
/// </item>
/// <item>
/// <term>WINBIO_FP_TOO_FAST</term>
/// </item>
/// <item>
/// <term>WINBIO_FP_TOO_SLOW</term>
/// </item>
/// <item>
/// <term>WINBIO_FP_POOR_QUALITY</term>
/// </item>
/// <item>
/// <term>WINBIO_FP_TOO_SKEWED</term>
/// </item>
/// <item>
/// <term>WINBIO_FP_TOO_SHORT</term>
/// </item>
/// <item>
/// <term>WINBIO_FP_MERGE_FAILURE</term>
/// </item>
/// </list>
/// </param>
/// <returns>
/// <para>
/// If the function succeeds, it returns S_OK. If the function fails, it returns an <c>HRESULT</c> value that indicates the error.
/// Possible values include, but are not limited to, those in the following table. For a list of common error codes, see Common
/// HRESULT Values.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>E_HANDLE</term>
/// <term>The session handle is not valid.</term>
/// </item>
/// <item>
/// <term>E_POINTER</term>
/// <term>The pointer specified by the UnitId, Identity, SubFactor, or RejectDetail parameters cannot be NULL.</term>
/// </item>
/// <item>
/// <term>WINBIO_E_BAD_CAPTURE</term>
/// <term>The sample could not be captured. Use the RejectDetail value for more information.</term>
/// </item>
/// <item>
/// <term>WINBIO_E_ENROLLMENT_IN_PROGRESS</term>
/// <term>
/// The operation could not be completed because the biometric unit is currently being used for an enrollment transaction (system
/// pool only).
/// </term>
/// </item>
/// <item>
/// <term>WINBIO_E_UNKNOWN_ID</term>
/// <term>The biometric sample does not match any saved in the database.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// The value returned in the SubFactor parameter specifies the sub-factor associated with the biometric sample. The Windows
/// Biometric Framework (WBF) currently supports only fingerprint capture and uses the following constants to represent sub-type information.
/// </para>
/// <list type="bullet">
/// <item>
/// <term>WINBIO_ANSI_381_POS_RH_THUMB</term>
/// </item>
/// <item>
/// <term>WINBIO_ANSI_381_POS_RH_INDEX_FINGER</term>
/// </item>
/// <item>
/// <term>WINBIO_ANSI_381_POS_RH_MIDDLE_FINGER</term>
/// </item>
/// <item>
/// <term>WINBIO_ANSI_381_POS_RH_RING_FINGER</term>
/// </item>
/// <item>
/// <term>WINBIO_ANSI_381_POS_RH_LITTLE_FINGER</term>
/// </item>
/// <item>
/// <term>WINBIO_ANSI_381_POS_LH_THUMB</term>
/// </item>
/// <item>
/// <term>WINBIO_ANSI_381_POS_LH_INDEX_FINGER</term>
/// </item>
/// <item>
/// <term>WINBIO_ANSI_381_POS_LH_MIDDLE_FINGER</term>
/// </item>
/// <item>
/// <term>WINBIO_ANSI_381_POS_LH_RING_FINGER</term>
/// </item>
/// <item>
/// <term>WINBIO_ANSI_381_POS_LH_LITTLE_FINGER</term>
/// </item>
/// <item>
/// <term>WINBIO_ANSI_381_POS_RH_FOUR_FINGERS</term>
/// </item>
/// <item>
/// <term>WINBIO_ANSI_381_POS_LH_FOUR_FINGERS</term>
/// </item>
/// </list>
/// <para>
/// To use <c>WinBioIdentify</c> synchronously, call the function with a session handle created by calling WinBioOpenSession. The
/// function blocks until the operation completes or an error is encountered.
/// </para>
/// <para>
/// To use <c>WinBioIdentify</c> asynchronously, call the function with a session handle created by calling WinBioAsyncOpenSession.
/// The framework allocates a WINBIO_ASYNC_RESULT structure and uses it to return information about operation success or failure. If
/// the operation is successful, the framework returns <c>WINBIO_IDENTITY</c> and <c>WINBIO_BIOMETRIC_SUBTYPE</c> information in a
/// nested <c>Identify</c> structure. If the operation is unsuccessful, the framework returns <c>WINBIO_REJECT_DETAIL</c>
/// information in the <c>Identify</c> structure. The <c>WINBIO_ASYNC_RESULT</c> structure is returned to the application callback
/// or to the application message queue, depending on the value you set in the NotificationMethod parameter of the
/// <c>WinBioAsyncOpenSession</c> function:
/// </para>
/// <list type="bullet">
/// <item>
/// <term>
/// If you choose to receive completion notices by using a callback, you must implement a PWINBIO_ASYNC_COMPLETION_CALLBACK function
/// and set the NotificationMethod parameter to <c>WINBIO_ASYNC_NOTIFY_CALLBACK</c>.
/// </term>
/// </item>
/// <item>
/// <term>
/// If you choose to receive completion notices by using the application message queue, you must set the NotificationMethod
/// parameter to <c>WINBIO_ASYNC_NOTIFY_MESSAGE</c>. The framework returns a WINBIO_ASYNC_RESULT pointer to the <c>LPARAM</c> field
/// of the window message.
/// </term>
/// </item>
/// </list>
/// <para>
/// To prevent memory leaks, you must call WinBioFree to release the WINBIO_ASYNC_RESULT structure after you have finished using it.
/// </para>
/// <para>
/// <c>Windows 7:</c> You can perform this operation asynchronously by using the WinBioIdentifyWithCallback function. The function
/// verifies the input arguments and returns immediately. If the input arguments are not valid, the function returns an error code.
/// Otherwise, the framework starts the operation on another thread. When the asynchronous operation completes or encounters an
/// error, the framework sends the results to the PWINBIO_IDENTIFY_CALLBACK function implemented by your application.
/// </para>
/// <para>Examples</para>
/// <para>
/// The following function calls WinBioEnumEnrollments to enumerate the biometric sub-factors enrolled for a template, and it calls
/// <c>WinBioIdentify</c> to retrieve a WINBIO_IDENTITY object that identifies the user. Link to the Winbio.lib static library and
/// include the following header files:
/// </para>
/// <list type="bullet">
/// <item>
/// <term>Windows.h</term>
/// </item>
/// <item>
/// <term>Stdio.h</term>
/// </item>
/// <item>
/// <term>Conio.h</term>
/// </item>
/// <item>
/// <term>Winbio.h</term>
/// </item>
/// </list>
/// <para>
/// <code>HRESULT EnumEnrollments( ) { // Declare variables. HRESULT hr = S_OK; WINBIO_IDENTITY identity = {0}; WINBIO_SESSION_HANDLE sessionHandle = NULL; WINBIO_UNIT_ID unitId = 0; PWINBIO_BIOMETRIC_SUBTYPE subFactorArray = NULL; WINBIO_BIOMETRIC_SUBTYPE SubFactor = 0; SIZE_T subFactorCount = 0; WINBIO_REJECT_DETAIL rejectDetail = 0; WINBIO_BIOMETRIC_SUBTYPE subFactor = WINBIO_SUBTYPE_NO_INFORMATION; // Connect to the system pool. hr = WinBioOpenSession( WINBIO_TYPE_FINGERPRINT, // Service provider WINBIO_POOL_SYSTEM, // Pool type WINBIO_FLAG_DEFAULT, // Configuration and access NULL, // Array of biometric unit IDs 0, // Count of biometric unit IDs NULL, // Database ID &amp;sessionHandle // [out] Session handle ); if (FAILED(hr)) { wprintf_s(L"\n WinBioOpenSession failed. hr = 0x%x\n", hr); goto e_Exit; } // Locate the biometric sensor and retrieve a WINBIO_IDENTITY object. wprintf_s(L"\n Calling WinBioIdentify - Swipe finger on sensor...\n"); hr = WinBioIdentify( sessionHandle, // Session handle &amp;unitId, // Biometric unit ID &amp;identity, // User SID &amp;subFactor, // Finger sub factor &amp;rejectDetail // Rejection information ); wprintf_s(L"\n Swipe processed - Unit ID: %d\n", unitId); if (FAILED(hr)) { if (hr == WINBIO_E_UNKNOWN_ID) { wprintf_s(L"\n Unknown identity.\n"); } else if (hr == WINBIO_E_BAD_CAPTURE) { wprintf_s(L"\n Bad capture; reason: %d\n", rejectDetail); } else { wprintf_s(L"\n WinBioEnumBiometricUnits failed. hr = 0x%x\n", hr); } goto e_Exit; } // Retrieve the biometric sub-factors for the template. hr = WinBioEnumEnrollments( sessionHandle, // Session handle unitId, // Biometric unit ID &amp;identity, // Template ID &amp;subFactorArray, // Subfactors &amp;subFactorCount // Count of subfactors ); if (FAILED(hr)) { wprintf_s(L"\n WinBioEnumEnrollments failed. hr = 0x%x\n", hr); goto e_Exit; } // Print the sub-factor(s) to the console. wprintf_s(L"\n Enrollments for this user on Unit ID %d:", unitId); for (SIZE_T index = 0; index &lt; subFactorCount; ++index) { SubFactor = subFactorArray[index]; switch (SubFactor) { case WINBIO_ANSI_381_POS_RH_THUMB: wprintf_s(L"\n RH thumb\n"); break; case WINBIO_ANSI_381_POS_RH_INDEX_FINGER: wprintf_s(L"\n RH index finger\n"); break; case WINBIO_ANSI_381_POS_RH_MIDDLE_FINGER: wprintf_s(L"\n RH middle finger\n"); break; case WINBIO_ANSI_381_POS_RH_RING_FINGER: wprintf_s(L"\n RH ring finger\n"); break; case WINBIO_ANSI_381_POS_RH_LITTLE_FINGER: wprintf_s(L"\n RH little finger\n"); break; case WINBIO_ANSI_381_POS_LH_THUMB: wprintf_s(L"\n LH thumb\n"); break; case WINBIO_ANSI_381_POS_LH_INDEX_FINGER: wprintf_s(L"\n LH index finger\n"); break; case WINBIO_ANSI_381_POS_LH_MIDDLE_FINGER: wprintf_s(L"\n LH middle finger\n"); break; case WINBIO_ANSI_381_POS_LH_RING_FINGER: wprintf_s(L"\n LH ring finger\n"); break; case WINBIO_ANSI_381_POS_LH_LITTLE_FINGER: wprintf_s(L"\n LH little finger\n"); break; default: wprintf_s(L"\n The sub-factor is not correct\n"); break; } } e_Exit: if (subFactorArray!= NULL) { WinBioFree(subFactorArray); subFactorArray = NULL; } if (sessionHandle != NULL) { WinBioCloseSession(sessionHandle); sessionHandle = NULL; } wprintf_s(L"\n Press any key to exit..."); _getch(); return hr; }</code>
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winbio/nf-winbio-winbioidentify HRESULT WinBioIdentify( WINBIO_SESSION_HANDLE
// SessionHandle, WINBIO_UNIT_ID *UnitId, WINBIO_IDENTITY *Identity, WINBIO_BIOMETRIC_SUBTYPE *SubFactor, WINBIO_REJECT_DETAIL
// *RejectDetail );
[DllImport(Lib_Winbio, SetLastError = false, ExactSpelling = true)]
[PInvokeData("winbio.h", MSDNShortId = "NF:winbio.WinBioIdentify")]
public static extern HRESULT WinBioIdentify(WINBIO_SESSION_HANDLE SessionHandle, out WINBIO_UNIT_ID UnitId,
out WINBIO_IDENTITY Identity, out WINBIO_BIOMETRIC_SUBTYPE SubFactor, out WINBIO_REJECT_DETAIL RejectDetail);
/// <summary>
/// <para>
/// Asynchronously captures a biometric sample and determines whether it matches an existing biometric template. The function
/// returns immediately to the caller, performs capture and identification on a separate thread, and calls into an
/// application-defined callback function to update operation status.
/// </para>
/// <para><c>Important</c>
/// <para></para>
/// We recommend that, beginning with Windows 8, you no longer use this function to start an asynchronous operation. Instead, do the following:
/// </para>
/// </summary>
/// <param name="SessionHandle">A <c>WINBIO_SESSION_HANDLE</c> value that identifies an open biometric session.</param>
/// <param name="IdentifyCallback">
/// Address of a callback function that will be called by the <c>WinBioIdentifyWithCallback</c> function when identification
/// succeeds or fails. You must create the callback.
/// </param>
/// <param name="IdentifyCallbackContext">
/// Pointer to an application-defined data structure that is passed to the callback function in its IdentifyCallbackContext
/// parameter. This structure can contain any data that the custom callback function is designed to handle.
/// </param>
/// <returns>
/// <para>
/// If the function succeeds, it returns <c>S_OK</c>. If the function fails, it returns an <c>HRESULT</c> value that indicates the
/// error. Possible values include, but are not limited to, those in the following table. For a list of common error codes, see
/// Common HRESULT Values.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>E_HANDLE</term>
/// <term>The session handle is not valid.</term>
/// </item>
/// <item>
/// <term>E_POINTER</term>
/// <term>The SessionHandle and IdentifyCallback parameters cannot be NULL.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>The callback routine must have the following signature:</para>
/// <para>
/// <code>VOID CALLBACK IdentifyCallback( __in_opt PVOID IdentifyCallbackContext, __in HRESULT OperationStatus, __in WINBIO_UNIT_ID UnitId, __in WINBIO_IDENTITY *Identity, __in WINBIO_BIOMETRIC_SUBTYPE SubFactor, __in WINBIO_REJECT_DETAIL RejectDetail );</code>
/// </para>
/// <para>Examples</para>
/// <para>
/// The following code example calls <c>WinBioIdentifyWithCallback</c> to identify a user from a biometric scan.
/// <c>WinBioIdentifyWithCallback</c> is an asynchronous function that configures the biometric subsystem to process biometric input
/// on another thread. Output from the biometric subsystem is then sent to a custom callback function named IdentifyCallback. Link
/// to the Winbio.lib static library and include the following header files:
/// </para>
/// <list type="bullet">
/// <item>
/// <term>Windows.h</term>
/// </item>
/// <item>
/// <term>Stdio.h</term>
/// </item>
/// <item>
/// <term>Conio.h</term>
/// </item>
/// <item>
/// <term>Winbio.h</term>
/// </item>
/// </list>
/// <para>
/// <code>HRESULT IdentifyWithCallback(BOOL bCancel) { // Declare variables. HRESULT hr = S_OK; WINBIO_SESSION_HANDLE sessionHandle = NULL; // Connect to the system pool. hr = WinBioOpenSession( WINBIO_TYPE_FINGERPRINT, // Service provider WINBIO_POOL_SYSTEM, // Pool type WINBIO_FLAG_DEFAULT, // Configuration and access NULL, // Array of biometric unit IDs 0, // Count of biometric unit IDs WINBIO_DB_DEFAULT, // Database ID &amp;sessionHandle // [out] Session handle ); if (FAILED(hr)) { wprintf_s(L"\n WinBioOpenSession failed. hr = 0x%x\n", hr); goto e_Exit; } // Call WinBioIdentifyWithCallback. The method is asynchronous // and returns immediately. wprintf_s(L"\n Calling WinBioIdentifyWithCallback"); wprintf_s(L"\n Swipe the sensor ...\n"); hr = WinBioIdentifyWithCallback( sessionHandle, // Open biometric session IdentifyCallback, // Callback function NULL // Optional context ); if (FAILED(hr)) { wprintf_s(L"\n WinBioIdentifyWithCallback failed. hr = 0x%x\n", hr); goto e_Exit; } // Cancel user identification if the bCancel flag is set. if (bCancel) { wprintf_s(L"\n Starting CANCEL timer...\n"); Sleep( 7000 ); wprintf_s(L"\n Calling WinBioCancel\n"); hr = WinBioCancel( sessionHandle ); if (FAILED(hr)) { wprintf_s(L"\n WinBioCancel failed. hr = 0x%x\n", hr); goto e_Exit; } } // Wait for the asynchronous identification process to complete // or be canceled. hr = WinBioWait( sessionHandle ); if (FAILED(hr)) { wprintf_s(L"\n WinBioWait failed. hr = 0x%x\n", hr); } e_Exit: if (sessionHandle != NULL) { wprintf_s(L"\n Closing the session.\n"); hr = WinBioCloseSession(sessionHandle); if (FAILED(hr)) { wprintf_s(L"\n WinBioCloseSession failed. hr = 0x%x\n", hr); } sessionHandle = NULL; } wprintf_s(L"\n Hit any key to exit..."); _getch(); return hr; } //------------------------------------------------------------------------ // The following function is the callback for WinBioIdentifyWithCallback. // The function filters the response from the biometric subsystem and // writes a result to the console window. // VOID CALLBACK IdentifyCallback( __in_opt PVOID IdentifyCallbackContext, __in HRESULT OperationStatus, __in WINBIO_UNIT_ID UnitId, __in WINBIO_IDENTITY *Identity, __in WINBIO_BIOMETRIC_SUBTYPE SubFactor, __in WINBIO_REJECT_DETAIL RejectDetail ) { UNREFERENCED_PARAMETER(IdentifyCallbackContext); UNREFERENCED_PARAMETER(Identity); wprintf_s(L"\n IdentifyCallback executing"); wprintf_s(L"\n Swipe processed for unit ID %d\n", UnitId); // The attempt to process the fingerprint failed. if (FAILED(OperationStatus)) { if (OperationStatus == WINBIO_E_UNKNOWN_ID) { wprintf_s(L"\n Unknown identity.\n"); } else if (OperationStatus == WINBIO_E_BAD_CAPTURE) { wprintf_s(L"\n Bad capture; reason: %d\n", RejectDetail); } else { wprintf_s(L"IdentifyCallback failed."); wprintf_s(L"OperationStatus = 0x%x\n", OperationStatus); } } // Processing succeeded and the finger swiped is written // to the console window. else { wprintf_s(L"\n The following finger was used:"); switch (SubFactor) { case WINBIO_SUBTYPE_NO_INFORMATION: wprintf_s(L"\n No information\n"); break; case WINBIO_ANSI_381_POS_RH_THUMB: wprintf_s(L"\n RH thumb\n"); break; case WINBIO_ANSI_381_POS_RH_INDEX_FINGER: wprintf_s(L"\n RH index finger\n"); break; case WINBIO_ANSI_381_POS_RH_MIDDLE_FINGER: wprintf_s(L"\n RH middle finger\n"); break; case WINBIO_ANSI_381_POS_RH_RING_FINGER: wprintf_s(L"\n RH ring finger\n"); break; case WINBIO_ANSI_381_POS_RH_LITTLE_FINGER: wprintf_s(L"\n RH little finger\n"); break; case WINBIO_ANSI_381_POS_LH_THUMB: wprintf_s(L"\n LH thumb\n"); break; case WINBIO_ANSI_381_POS_LH_INDEX_FINGER: wprintf_s(L"\n LH index finger\n"); break; case WINBIO_ANSI_381_POS_LH_MIDDLE_FINGER: wprintf_s(L"\n LH middle finger\n"); break; case WINBIO_ANSI_381_POS_LH_RING_FINGER: wprintf_s(L"\n LH ring finger\n"); break; case WINBIO_ANSI_381_POS_LH_LITTLE_FINGER: wprintf_s(L"\n LH little finger\n"); break; case WINBIO_SUBTYPE_ANY: wprintf_s(L"\n Any finger\n"); break; default: break; } } }</code>
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winbio/nf-winbio-winbioidentifywithcallback HRESULT
// WinBioIdentifyWithCallback( WINBIO_SESSION_HANDLE SessionHandle, PWINBIO_IDENTIFY_CALLBACK IdentifyCallback, PVOID
// IdentifyCallbackContext );
[DllImport(Lib_Winbio, SetLastError = false, ExactSpelling = true)]
[PInvokeData("winbio.h", MSDNShortId = "NF:winbio.WinBioIdentifyWithCallback")]
public static extern HRESULT WinBioIdentifyWithCallback(WINBIO_SESSION_HANDLE SessionHandle, [In] PWINBIO_IDENTIFY_CALLBACK IdentifyCallback, [In, Optional] IntPtr IdentifyCallbackContext);
/// <summary>Retrieves the ID number of a biometric unit selected interactively by a user.</summary>
/// <param name="SessionHandle">
/// A <c>WINBIO_SESSION_HANDLE</c> value that identifies an open biometric session. Open a synchronous session handle by calling
/// WinBioOpenSession. Open an asynchronous session handle by calling WinBioAsyncOpenSession.
/// </param>
/// <param name="UnitId">A pointer to a <c>ULONG</c> value that specifies the biometric unit.</param>
/// <returns>
/// <para>
/// If the function succeeds, it returns S_OK. If the function fails, it returns an <c>HRESULT</c> value that indicates the error.
/// Possible values include, but are not limited to, those in the following table. For a list of common error codes, see Common
/// HRESULT Values.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>E_HANDLE</term>
/// <term>The session handle is not valid.</term>
/// </item>
/// <item>
/// <term>E_POINTER</term>
/// <term>The pointer specified by the UnitId parameter cannot be NULL.</term>
/// </item>
/// <item>
/// <term>WINBIO_E_ENROLLMENT_IN_PROGRESS</term>
/// <term>
/// The operation could not be completed because the biometric unit is currently being used for an enrollment transaction (system
/// pool only).
/// </term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// You can use this function on systems with multiple sensors to determine which sensor is preferred for enrollment by the user. No
/// identification information is returned by this function. It is provided only to indicate user sensor selection.
/// </para>
/// <para>
/// Calls to this function using the system pool will block until the application acquires window focus and the user has provided a
/// biometric sample. We recommend, therefore, that your application not call <c>WinBioLocateSensor</c> until it has acquired focus.
/// The manner in which you acquire focus depends on the type of application you are writing. For example, if you are creating a GUI
/// application you can implement a message handler that captures a WM_ACTIVATE, WM_SETFOCUS, or other appropriate message. If you
/// are writing a CUI application, call <c>GetConsoleWindow</c> to retrieve a handle to the console window and pass that handle to
/// the <c>SetForegroundWindow</c> function to force the console window into the foreground and assign it focus. If your application
/// is running in a detached process and has no window or is a Windows service, use WinBioAcquireFocus and WinBioReleaseFocus to
/// manually control focus.
/// </para>
/// <para>
/// To use <c>WinBioLocateSensor</c> synchronously, call the function with a session handle created by calling WinBioOpenSession.
/// The function blocks until the operation completes or an error is encountered.
/// </para>
/// <para>
/// To use <c>WinBioLocateSensor</c> asynchronously, call the function with a session handle created by calling
/// WinBioAsyncOpenSession. The framework allocates a WINBIO_ASYNC_RESULT structure and uses it to return information about
/// operation success or failure. The <c>WINBIO_ASYNC_RESULT</c> structure is returned to the application callback or to the
/// application message queue, depending on the value you set in the NotificationMethod parameter of the
/// <c>WinBioAsyncOpenSession</c> function:
/// </para>
/// <list type="bullet">
/// <item>
/// <term>
/// If you choose to receive completion notices by using a callback, you must implement a PWINBIO_ASYNC_COMPLETION_CALLBACK function
/// and set the NotificationMethod parameter to <c>WINBIO_ASYNC_NOTIFY_CALLBACK</c>.
/// </term>
/// </item>
/// <item>
/// <term>
/// If you choose to receive completion notices by using the application message queue, you must set the NotificationMethod
/// parameter to <c>WINBIO_ASYNC_NOTIFY_MESSAGE</c>. The framework returns a WINBIO_ASYNC_RESULT pointer to the <c>LPARAM</c> field
/// of the window message.
/// </term>
/// </item>
/// </list>
/// <para>
/// To prevent memory leaks, you must call WinBioFree to release the WINBIO_ASYNC_RESULT structure after you have finished using it.
/// </para>
/// <para>
/// <c>Windows 7:</c> You can perform this operation asynchronously by using the WinBioLocateSensorWithCallback function. The
/// function verifies the input arguments and returns immediately. If the input arguments are not valid, the function returns an
/// error code. Otherwise, the framework starts the operation on another thread. When the asynchronous operation completes or
/// encounters an error, the framework sends the results to the PWINBIO_LOCATE_SENSOR_CALLBACK function implemented by your application.
/// </para>
/// <para>Examples</para>
/// <para>
/// The following function calls <c>WinBioLocateSensor</c> to locate an installed biometric sensor. Link to the Winbio.lib static
/// library and include the following header files:
/// </para>
/// <list type="bullet">
/// <item>
/// <term>Windows.h</term>
/// </item>
/// <item>
/// <term>Stdio.h</term>
/// </item>
/// <item>
/// <term>Conio.h</term>
/// </item>
/// <item>
/// <term>Winbio.h</term>
/// </item>
/// </list>
/// <para>
/// <code>HRESULT LocateSensor( ) { HRESULT hr = S_OK; WINBIO_SESSION_HANDLE sessionHandle = NULL; WINBIO_UNIT_ID unitId = 0; // Connect to the system pool. hr = WinBioOpenSession( WINBIO_TYPE_FINGERPRINT, // Service provider WINBIO_POOL_SYSTEM, // Pool type WINBIO_FLAG_DEFAULT, // Configuration and access NULL, // Array of biometric unit IDs 0, // Count of biometric unit IDs NULL, // Database ID &amp;sessionHandle // [out] Session handle ); if (FAILED(hr)) { wprintf_s(L"\n WinBioEnumBiometricUnits failed. hr = 0x%x\n", hr); goto e_Exit; } // Locate the sensor. wprintf_s(L"\n Tap the sensor once...\n"); hr = WinBioLocateSensor( sessionHandle, &amp;unitId); if (FAILED(hr)) { wprintf_s(L"\n WinBioLocateSensor failed. hr = 0x%x\n", hr); goto e_Exit; } wprintf_s(L"\n Sensor located successfully. "); wprintf_s(L"\n Unit ID = %d \n", unitId); e_Exit: if (sessionHandle != NULL) { WinBioCloseSession(sessionHandle); sessionHandle = NULL; } wprintf_s(L"\n Hit any key to exit..."); _getch(); return hr; }</code>
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winbio/nf-winbio-winbiolocatesensor HRESULT WinBioLocateSensor(
// WINBIO_SESSION_HANDLE SessionHandle, WINBIO_UNIT_ID *UnitId );
[DllImport(Lib_Winbio, SetLastError = false, ExactSpelling = true)]
[PInvokeData("winbio.h", MSDNShortId = "NF:winbio.WinBioLocateSensor")]
public static extern HRESULT WinBioLocateSensor(WINBIO_SESSION_HANDLE SessionHandle, out WINBIO_UNIT_ID UnitId);
/// <summary>
/// <para>
/// Asynchronously retrieves the ID number of the biometric unit selected interactively by a user. The function returns immediately
/// to the caller, processes on a separate thread, and reports the selected biometric unit by calling an application-defined
/// callback function.
/// </para>
/// <para><c>Important</c>
/// <para></para>
/// We recommend that, beginning with Windows 8, you no longer use this function to start an asynchronous operation. Instead, do the following:
/// </para>
/// </summary>
/// <param name="SessionHandle">A <c>WINBIO_SESSION_HANDLE</c> value that identifies an open biometric session.</param>
/// <param name="LocateCallback">
/// Address of a callback function that will be called by the <c>WinBioLocateSensorWithCallback</c> function when sensor location
/// succeeds or fails. You must create the callback.
/// </param>
/// <param name="LocateCallbackContext">
/// Address of an application-defined data structure that is passed to the callback function in its LocateCallbackContext parameter.
/// This structure can contain any data that the custom callback function is designed to handle.
/// </param>
/// <returns>
/// <para>
/// If the function succeeds, it returns <c>S_OK</c>. If the function fails, it returns an <c>HRESULT</c> value that indicates the
/// error. Possible values include, but are not limited to, those in the following table. For a list of common error codes, see
/// Common HRESULT Values.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>E_HANDLE</term>
/// <term>The session handle is not valid.</term>
/// </item>
/// <item>
/// <term>E_POINTER</term>
/// <term>The address specified by the LocateCallback parameter cannot be NULL.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// You can use this function on systems with multiple sensors to determine which sensor is preferred for enrollment by the user. No
/// identification information is returned by this function. It is provided only to indicate user sensor selection.
/// </para>
/// <para>
/// If the SessionHandle parameter refers to the system sensor pool, the callback function will not be called until the application
/// acquires window focus and the user has provided a biometric sample. The manner in which you acquire focus depends on the type of
/// application you are writing. For example, if you are creating a GUI application you can implement a message handler that
/// captures a WM_ACTIVATE, WM_SETFOCUS, or other appropriate message. If you are writing a CUI application, call
/// <c>GetConsoleWindow</c> to retrieve a handle to the console window and pass that handle to the <c>SetForegroundWindow</c>
/// function to force the console window into the foreground and assign it focus. If your application is running in a detached
/// process and has no window or is a Windows service, use WinBioAcquireFocus and WinBioReleaseFocus to manually control focus.
/// </para>
/// <para>The callback routine must have the following signature:</para>
/// <para>
/// <code> VOID CALLBACK LocateCallback( __in_opt PVOID LocateCallbackContext, __in HRESULT OperationStatus, __in WINBIO_UNIT_ID UnitId );</code>
/// </para>
/// <para>Examples</para>
/// <para>
/// The following function calls <c>WinBioLocateSensorWithCallback</c> to locate biometric sensor. The
/// <c>WinBioLocateSensorWithCallback</c> is an asynchronous function that configures the biometric subsystem to locate the sensor
/// on another thread. Output from the biometric subsystem is sent to a custom callback function named LocateSensorCallback. Link to
/// the Winbio.lib static library and include the following header files:
/// </para>
/// <list type="bullet">
/// <item>
/// <term>Windows.h</term>
/// </item>
/// <item>
/// <term>Stdio.h</term>
/// </item>
/// <item>
/// <term>Conio.h</term>
/// </item>
/// <item>
/// <term>Winbio.h</term>
/// </item>
/// </list>
/// <para>
/// <code>HRESULT LocateSensorWithCallback(BOOL bCancel) { HRESULT hr = S_OK; WINBIO_SESSION_HANDLE sessionHandle = NULL; WINBIO_UNIT_ID unitId = 0; // Connect to the system pool. hr = WinBioOpenSession( WINBIO_TYPE_FINGERPRINT, // Service provider WINBIO_POOL_SYSTEM, // Pool type WINBIO_FLAG_DEFAULT, // Configuration and access NULL, // Array of biometric unit IDs 0, // Count of biometric unit IDs NULL, // Database ID &amp;sessionHandle // [out] Session handle ); if (FAILED(hr)) { wprintf_s(L"\n WinBioOpenSession failed. hr = 0x%x\n", hr); goto e_Exit; } wprintf_s(L"\n Calling WinBioLocateSensorWithCallback."); hr = WinBioLocateSensorWithCallback( sessionHandle, // Open biometric session LocateSensorCallback, // Callback function NULL // Optional context ); if (FAILED(hr)) { wprintf_s(L"\n WinBioLocateSensorWithCallback failed."); wprintf_s(L"hr = 0x%x\n", hr); goto e_Exit; } wprintf_s(L"\n Swipe the sensor ...\n"); // Cancel the identification if the bCancel flag is set. if (bCancel) { wprintf_s(L"\n Starting CANCEL timer...\n"); Sleep( 7000 ); wprintf_s(L"\n Calling WinBioCancel\n"); hr = WinBioCancel( sessionHandle ); if (FAILED(hr)) { wprintf_s(L"\n WinBioCancel failed. hr = 0x%x\n", hr); goto e_Exit; } } // Wait for the asynchronous identification process to complete // or be canceled. hr = WinBioWait( sessionHandle ); if (FAILED(hr)) { wprintf_s(L"\n WinBioWait failed. hr = 0x%x\n", hr); } e_Exit: if (sessionHandle != NULL) { wprintf_s(L"\n Closing the session.\n"); hr = WinBioCloseSession(sessionHandle); if (FAILED(hr)) { wprintf_s(L"\n WinBioCloseSession failed. hr = 0x%x\n", hr); } sessionHandle = NULL; } wprintf_s(L"\n Hit any key to exit..."); _getch(); return hr; } //------------------------------------------------------------------------ // The following function is the callback for // WinBioLocateSensorWithCallback. The function filters the response // from the biometric subsystem and writes a result to the console window. // VOID CALLBACK LocateSensorCallback( __in_opt PVOID LocateCallbackContext, __in HRESULT OperationStatus, __in WINBIO_UNIT_ID UnitId ) { UNREFERENCED_PARAMETER(LocateCallbackContext); wprintf_s(L"\n LocateSensorCallback executing."); // A sensor could not be located. if (FAILED(OperationStatus)) { wprintf_s(L"\n LocateSensorCallback failed."); wprintf_s(L"OperationStatus = 0x%x\n", OperationStatus); } // A sensor was located. else { wprintf_s(L"\n Selected unit ID: %d\n", UnitId); } }</code>
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winbio/nf-winbio-winbiolocatesensorwithcallback HRESULT
// WinBioLocateSensorWithCallback( WINBIO_SESSION_HANDLE SessionHandle, PWINBIO_LOCATE_SENSOR_CALLBACK LocateCallback, PVOID
// LocateCallbackContext );
[DllImport(Lib_Winbio, SetLastError = false, ExactSpelling = true)]
[PInvokeData("winbio.h", MSDNShortId = "NF:winbio.WinBioLocateSensorWithCallback")]
public static extern HRESULT WinBioLocateSensorWithCallback(WINBIO_SESSION_HANDLE SessionHandle, [In] PWINBIO_LOCATE_SENSOR_CALLBACK LocateCallback, [In, Optional] IntPtr LocateCallbackContext);
/// <summary>
/// Locks a biometric unit for exclusive use by a single session. Starting with Windows 10, build 1607, this function is available
/// to use with a mobile image.
/// </summary>
/// <param name="SessionHandle">
/// A <c>WINBIO_SESSION_HANDLE</c> value that identifies an open biometric session. Open a synchronous session handle by calling
/// WinBioOpenSession. Open an asynchronous session handle by calling WinBioAsyncOpenSession.
/// </param>
/// <param name="UnitId">A <c>WINBIO_UNIT_ID</c> value that specifies the biometric unit to be locked.</param>
/// <returns>
/// <para>
/// If the function succeeds, it returns S_OK. If the function fails, it returns an <c>HRESULT</c> value that indicates the error.
/// Possible values include, but are not limited to, those in the following table. For a list of common error codes, see Common
/// HRESULT Values.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>E_HANDLE</term>
/// <term>The session handle is not valid.</term>
/// </item>
/// <item>
/// <term>E_INVALIDARG</term>
/// <term>The UnitId parameter cannot contain zero.</term>
/// </item>
/// <item>
/// <term>WINBIO_E_ENROLLMENT_IN_PROGRESS</term>
/// <term>
/// The operation could not be completed because the specified biometric unit is currently being used for an enrollment transaction
/// (system pool only).
/// </term>
/// </item>
/// <item>
/// <term>WINBIO_E_LOCK_VIOLATION</term>
/// <term>The biometric unit cannot be locked because the specified session already has another unit locked.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// If the specified biometric unit is locked by another session, <c>WinBioLockUnit</c> will block the calling thread until the
/// session that owns the biometric unit releases its lock.
/// </para>
/// <para>Call the WinBioUnlockUnit function to cancel any pending lock request and release all locks held by the session.</para>
/// <para>
/// To use <c>WinBioLockUnit</c> synchronously, call the function with a session handle created by calling WinBioOpenSession. The
/// function blocks until the operation completes or an error is encountered.
/// </para>
/// <para>
/// To use <c>WinBioLockUnit</c> asynchronously, call the function with a session handle created by calling WinBioAsyncOpenSession.
/// The framework allocates a WINBIO_ASYNC_RESULT structure and uses it to return information about operation success or failure.
/// The <c>WINBIO_ASYNC_RESULT</c> structure is returned to the application callback or to the application message queue, depending
/// on the value you set in the NotificationMethod parameter of the <c>WinBioAsyncOpenSession</c> function:
/// </para>
/// <list type="bullet">
/// <item>
/// <term>
/// If you choose to receive completion notices by using a callback, you must implement a PWINBIO_ASYNC_COMPLETION_CALLBACK function
/// and set the NotificationMethod parameter to <c>WINBIO_ASYNC_NOTIFY_CALLBACK</c>.
/// </term>
/// </item>
/// <item>
/// <term>
/// If you choose to receive completion notices by using the application message queue, you must set the NotificationMethod
/// parameter to <c>WINBIO_ASYNC_NOTIFY_MESSAGE</c>. The framework returns a WINBIO_ASYNC_RESULT pointer to the <c>LPARAM</c> field
/// of the window message.
/// </term>
/// </item>
/// </list>
/// <para>
/// To prevent memory leaks, you must call WinBioFree to release the WINBIO_ASYNC_RESULT structure after you have finished using it.
/// </para>
/// <para>Examples</para>
/// <para>
/// The following function calls <c>WinBioLockUnit</c> to lock the biometric unit before calling WinBioIdentify to identify the
/// user. Link to the Winbio.lib static library and include the following header files:
/// </para>
/// <list type="bullet">
/// <item>
/// <term>Windows.h</term>
/// </item>
/// <item>
/// <term>Stdio.h</term>
/// </item>
/// <item>
/// <term>Conio.h</term>
/// </item>
/// <item>
/// <term>Winbio.h</term>
/// </item>
/// </list>
/// <para>
/// <code>HRESULT LockUnlock( ) { // Declare variables. HRESULT hr = S_OK; WINBIO_IDENTITY identity = {0}; WINBIO_SESSION_HANDLE sessionHandle = NULL; WINBIO_UNIT_ID unitId = 0; WINBIO_REJECT_DETAIL rejectDetail = 0; WINBIO_BIOMETRIC_SUBTYPE subFactor = WINBIO_SUBTYPE_NO_INFORMATION; BOOL lockAcquired = FALSE; // Connect to the system pool. hr = WinBioOpenSession( WINBIO_TYPE_FINGERPRINT, // Service provider WINBIO_POOL_SYSTEM, // Pool type WINBIO_FLAG_DEFAULT, // Configuration and access NULL, // Array of biometric unit IDs 0, // Count of biometric unit IDs NULL, // Database ID &amp;sessionHandle // [out] Session handle ); if (FAILED(hr)) { wprintf_s(L"\n WinBioEnumBiometricUnits failed. hr = 0x%x\n", hr); goto e_Exit; } // Lock the session. The Biometric unit ID (1) is hard coded in // this example. hr = WinBioLockUnit( sessionHandle, 1 ); if (FAILED(hr)) { wprintf_s(L"\n WinBioLockUnit failed. hr = 0x%x\n", hr); goto e_Exit; } wprintf_s(L"\n Biometric unit #1 is locked.\n"); lockAcquired = TRUE; // Locate the biometric sensor and retrieve a WINBIO_IDENTITY object. // You must swipe your finger on the sensor. wprintf_s(L"\n Calling WinBioIdentify - Swipe finger on sensor...\n"); hr = WinBioIdentify( sessionHandle, &amp;unitId, &amp;identity, &amp;subFactor, &amp;rejectDetail ); wprintf_s(L"\n Swipe processed - Unit ID: %d\n", unitId); if (FAILED(hr)) { wprintf_s(L"\n WinBioIdentify failed. hr = 0x%x\n", hr); goto e_Exit; } e_Exit: // Unlock the biometric unit if it is locked. if (lockAcquired == TRUE) { hr = WinBioUnlockUnit( sessionHandle, 1 ); if (FAILED(hr)) { wprintf_s(L"\n WinBioUnlockUnit failed. hr = 0x%x\n", hr); } wprintf_s(L"\n Biometric unit #1 is unlocked.\n"); lockAcquired = FALSE; } if (sessionHandle != NULL) { WinBioCloseSession(sessionHandle); sessionHandle = NULL; } wprintf_s(L"\n Press any key to exit..."); _getch(); return hr; }</code>
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winbio/nf-winbio-winbiolockunit HRESULT WinBioLockUnit( WINBIO_SESSION_HANDLE
// SessionHandle, WINBIO_UNIT_ID UnitId );
[DllImport(Lib_Winbio, SetLastError = false, ExactSpelling = true)]
[PInvokeData("winbio.h", MSDNShortId = "NF:winbio.WinBioLockUnit")]
public static extern HRESULT WinBioLockUnit(WINBIO_SESSION_HANDLE SessionHandle, WINBIO_UNIT_ID UnitId);
/// <summary>
/// The <c>WinBioLogonIdentifiedUser</c> function causes a fast user switch to the account associated with the last successful
/// identification operation performed by the biometric session.
/// </summary>
/// <param name="SessionHandle">
/// A <c>WINBIO_SESSION_HANDLE</c> value that identifies the biometric session that has recently performed a successful
/// identification operation. Open the session handle by calling WinBioOpenSession.
/// </param>
/// <returns>
/// <para>
/// If the function succeeds, it returns <c>S_OK</c>. If the function fails, it returns an <c>HRESULT</c> value that indicates the
/// error. Possible values include, but are not limited to, those in the following table. For a list of common error codes, see
/// Common HRESULT Values.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>E_ACCESSDENIED</term>
/// <term>The caller does not have permission to switch users or the biometric session is out of date.</term>
/// </item>
/// <item>
/// <term>E_HANDLE</term>
/// <term>The session handle is not valid.</term>
/// </item>
/// <item>
/// <term>S_FALSE</term>
/// <term>The user identified by the SessionHandle parameter is the same as the current user.</term>
/// </item>
/// <item>
/// <term>SEC_E_LOGON_DENIED</term>
/// <term>The user could not be logged on.</term>
/// </item>
/// <item>
/// <term>WINBIO_E_CRED_PROV_DISABLED</term>
/// <term>Current administrative policy prohibits use of the credential provider.</term>
/// </item>
/// <item>
/// <term>WINBIO_E_FAST_USER_SWITCH_DISABLED</term>
/// <term>Fast user switching is not enabled.</term>
/// </item>
/// <item>
/// <term>WINBIO_E_SAS_ENABLED</term>
/// <term>Fast user switching cannot be performed because secure logon (CTRL+ALT+DELETE) is currently enabled.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// The <c>WinBioLogonIdentifiedUser</c> function is typically called by applications that support fast user switching when they
/// identify a user other than the one who is currently logged on.
/// </para>
/// <para>
/// The fast user switch attempt can leave a logon event in the security log, but the identity is not automatically stored when the
/// credential manager terminates.
/// </para>
/// <para>
/// The biometric session specified by the SessionHandle parameter controls the target account for the fast user switch event. If
/// that handle has been used recently to perform an identification operation, the resulting identity will be logged in after the
/// fast user switch.
/// </para>
/// <para>
/// For security reasons, the Windows Biometric Framework requires that the identification operation and the call to
/// <c>WinBioLogonIdentifiedUser</c> happen within a short period of time. After that period, the identification is considered to be
/// out of date and the call to <c>WinBioLogonIdentifiedUser</c> will fail. The default timeout interval is five seconds, but an
/// administrator can make it as large as 60 seconds.
/// </para>
/// <para>
/// Calling this function when the target user is the same as the current user returns <c>S_FALSE</c> and the fast user switch
/// attempt is ignored.
/// </para>
/// <para>Examples</para>
/// <para>
/// The following function calls WinBioLogonIdentifiedUser to log on a previously identified user. For this function to work
/// correctly, secure logon must not be enabled. Link to the Winbio.lib static library and include the following header files:
/// </para>
/// <list type="bullet">
/// <item>
/// <term>Windows.h</term>
/// </item>
/// <item>
/// <term>Stdio.h</term>
/// </item>
/// <item>
/// <term>Conio.h</term>
/// </item>
/// <item>
/// <term>Winbio.h</term>
/// </item>
/// </list>
/// <para>
/// <code>HRESULT LogonIdentifiedUser() { // Declare variables. HRESULT hr; WINBIO_SESSION_HANDLE sessionHandle = NULL; WINBIO_UNIT_ID UnitId; WINBIO_IDENTITY Identity; WINBIO_BIOMETRIC_SUBTYPE SubFactor; WINBIO_REJECT_DETAIL RejectDetail; BOOL bContinue = TRUE; // Connect to the system pool. hr = WinBioOpenSession( WINBIO_TYPE_FINGERPRINT, // Service provider WINBIO_POOL_SYSTEM, // Pool type WINBIO_FLAG_DEFAULT, // Configuration and access NULL, // Array of biometric unit IDs 0, // Count of biometric unit IDs WINBIO_DB_DEFAULT, // Database ID &amp;sessionHandle // [out] Session handle ); if (FAILED(hr)) { wprintf_s(L"\n WinBioOpenSession failed. hr = 0x%x\n", hr); goto e_Exit; } // Locate the biometric sensor and retrieve a WINBIO_IDENTITY object. // You must swipe your finger on the sensor. wprintf_s(L"\n Calling WinBioIdentify - Swipe finger on sensor...\n"); while(bContinue) { hr = WinBioIdentify( sessionHandle, // Session handle &amp;UnitId, // Biometric unit ID &amp;Identity, // User SID or GUID &amp;SubFactor, // Finger sub factor &amp;RejectDetail // rejection information ); switch(hr) { case S_OK: bContinue = FALSE; break; default: wprintf_s(L"\n WinBioIdentify failed. hr = 0x%x\n", hr); break; } } if (SUCCEEDED(hr)) { // Switch to the target after receiving a good identity. hr = WinBioLogonIdentifiedUser(sessionHandle); switch(hr) { case S_FALSE: printf("\n Target is the logged on user. No action taken.\n"); break; case S_OK: printf("\n Fast user switch initiated.\n"); break; default: wprintf_s(L"\n WinBioLogonIdentifiedUser failed. hr = 0x%x\n", hr); break; } } e_Exit: if (sessionHandle != NULL) { WinBioCloseSession(sessionHandle); sessionHandle = NULL; } wprintf_s(L"\n Press any key to exit..."); _getch(); return hr; }</code>
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winbio/nf-winbio-winbiologonidentifieduser HRESULT WinBioLogonIdentifiedUser(
// WINBIO_SESSION_HANDLE SessionHandle );
[DllImport(Lib_Winbio, SetLastError = false, ExactSpelling = true)]
[PInvokeData("winbio.h", MSDNShortId = "NF:winbio.WinBioLogonIdentifiedUser")]
public static extern HRESULT WinBioLogonIdentifiedUser(WINBIO_SESSION_HANDLE SessionHandle);
/// <summary>
/// Turns on the face-recognition or iris-monitoring mechanism for the specified biometric unit. Starting with Windows 10, build
/// 1607, this function is available to use with a mobile image.
/// </summary>
/// <param name="SessionHandle">
/// An asynchronous handle for the biometric session that you obtained by calling the WinBioAsyncOpenSession function with the
/// PoolType parameter set to <c>WINBIO_POOL_SYSTEM</c>.
/// </param>
/// <param name="UnitId">
/// The identifier of the biometric unit for which you want to turn on the face-recognition or iris-monitoring mechanism.
/// </param>
/// <returns>
/// <para>
/// If the function parameters are acceptable, it returns <c>S_OK</c>. If the function parameters are not acceptable, it returns an
/// <c>HRESULT</c> value that indicates the error. Possible values include, but are not limited to, those in the following table.
/// For a list of common error codes, see Common HRESULT Values.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>E_HANDLE</term>
/// <term>The session handle is not valid.</term>
/// </item>
/// <item>
/// <term>E_INVALIDARG</term>
/// <term>The UnitId parameter cannot equal zero.</term>
/// </item>
/// <item>
/// <term>WINBIO_E_INCORRECT_SESSION_TYPE</term>
/// <term>The session handle does not correspond to an asynchronous biometric session.</term>
/// </item>
/// </list>
/// <para>
/// The actual success or failure of the operation itself is returned to the your notification function in a WINBIO_ASYNC_RESULT structure.
/// </para>
/// </returns>
/// <remarks>
/// <para>A single biometric session can have only one active presence monitor at any point in time.</para>
/// <para>
/// After you successfully call <c>WinBioMonitorPresence</c>, your notification function receives notifications in the form of a
/// WINBIO_ASYNC_RESULT structure with an <c>Operation</c> member equal to <c>WINBIO_OPERATION_MONITOR_PRESENCE</c>. You should then
/// examine the <c>Parameters.MonitorPresence</c> member of the <c>WINBIO_ASYNC_RESULT</c> structure for more information.
/// </para>
/// <para>
/// To stop receiving notifications, call either WinBioCancel or WinBioCloseSession with the original asynchronous handle value.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winbio/nf-winbio-winbiomonitorpresence HRESULT WinBioMonitorPresence(
// WINBIO_SESSION_HANDLE SessionHandle, WINBIO_UNIT_ID UnitId );
[DllImport(Lib_Winbio, SetLastError = false, ExactSpelling = true)]
[PInvokeData("winbio.h", MSDNShortId = "NF:winbio.WinBioMonitorPresence")]
public static extern HRESULT WinBioMonitorPresence(WINBIO_SESSION_HANDLE SessionHandle, WINBIO_UNIT_ID UnitId);
/// <summary>Connects to a biometric service provider and one or more biometric units.</summary>
/// <param name="Factor">
/// A bitmask of WINBIO_BIOMETRIC_TYPE flags that specifies the biometric unit types to be enumerated. Only
/// <c>WINBIO_TYPE_FINGERPRINT</c> is currently supported.
/// </param>
/// <param name="PoolType">
/// <para>
/// A <c>ULONG</c> value that specifies the type of the biometric units that will be used in the session. This can be one of the
/// following values:
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>WINBIO_POOL_SYSTEM</term>
/// <term>The session connects to a shared collection of biometric units managed by the service provider.</term>
/// </item>
/// <item>
/// <term>WINBIO_POOL_PRIVATE</term>
/// <term>The session connects to a collection of biometric units that are managed by the caller.</term>
/// </item>
/// </list>
/// </param>
/// <param name="Flags">
/// <para>
/// A <c>ULONG</c> value that specifies biometric unit configuration and access characteristics for the new session. Configuration
/// flags specify the general configuration of units in the session. Access flags specify how the application will use the biometric
/// units. You must specify one configuration flag but you can combine that flag with any access flag.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>WINBIO_FLAG_DEFAULT</term>
/// <term>
/// Group: configuration The biometric units operate in the manner specified during installation. You must use this value when the
/// PoolType parameter is WINBIO_POOL_SYSTEM.
/// </term>
/// </item>
/// <item>
/// <term>WINBIO_FLAG_BASIC</term>
/// <term>
/// Group: configuration The biometric units operate only as basic capture devices. All processing, matching, and storage operations
/// is performed by software plug-ins.
/// </term>
/// </item>
/// <item>
/// <term>WINBIO_FLAG_ADVANCED</term>
/// <term>Group: configuration The biometric units use internal processing and storage capabilities.</term>
/// </item>
/// <item>
/// <term>WINBIO_FLAG_RAW</term>
/// <term>Group: access The client application captures raw biometric data using WinBioCaptureSample.</term>
/// </item>
/// <item>
/// <term>WINBIO_FLAG_MAINTENANCE</term>
/// <term>Group: access The client performs vendor-defined control operations on a biometric unit by calling WinBioControlUnitPrivileged.</term>
/// </item>
/// </list>
/// </param>
/// <param name="UnitArray">
/// Pointer to an array of biometric unit identifiers to be included in the session. You can call WinBioEnumBiometricUnits to
/// enumerate the biometric units. Set this value to <c>NULL</c> if the PoolType parameter is <c>WINBIO_POOL_SYSTEM</c>.
/// </param>
/// <param name="UnitCount">
/// A value that specifies the number of elements in the array pointed to by the UnitArray parameter. Set this value to zero if the
/// PoolType parameter is <c>WINBIO_POOL_SYSTEM</c>.
/// </param>
/// <param name="DatabaseId">
/// <para>
/// A value that specifies the database(s) to be used by the session. If the PoolType parameter is <c>WINBIO_POOL_PRIVATE</c>, you
/// must specify the GUID of an installed database. If the PoolType parameter is not <c>WINBIO_POOL_PRIVATE</c>, you can specify one
/// of the following common values.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>WINBIO_DB_DEFAULT</term>
/// <term>
/// Each biometric unit in the sensor pool uses the default database specified in the default biometric unit configuration. You must
/// specify this value if the PoolType parameter is WINBIO_POOL_SYSTEM. You cannot use this value if the PoolType parameter is WINBIO_POOL_PRIVATE
/// </term>
/// </item>
/// <item>
/// <term>WINBIO_DB_BOOTSTRAP</term>
/// <term>
/// You can specify this value to be used for scenarios prior to starting Windows. Typically, the database is part of the sensor
/// chip or is part of the BIOS and can only be used for template enrollment and deletion.
/// </term>
/// </item>
/// <item>
/// <term>WINBIO_DB_ONCHIP</term>
/// <term>The database is on the sensor chip and is available for enrollment and matching.</term>
/// </item>
/// </list>
/// </param>
/// <param name="SessionHandle">Pointer to the new session handle. If the function does not succeed, the handle is set to zero.</param>
/// <returns>
/// <para>
/// If the function succeeds, it returns S_OK. If the function fails, it returns an <c>HRESULT</c> value that indicates the error.
/// Possible values include, but are not limited to, those in the following table. For a list of common error codes, see Common
/// HRESULT Values.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>E_INVALIDARG</term>
/// <term>One or more arguments have incorrect values or are incompatible with other arguments.</term>
/// </item>
/// <item>
/// <term>E_POINTER</term>
/// <term>The session handle pointer in the SessionHandle parameter cannot be NULL.</term>
/// </item>
/// <item>
/// <term>E_ACCESSDENIED</term>
/// <term>
/// The Flags parameter contains the WINBIO_FLAG_RAW or the WINBIO_FLAG_MAINTENANCE flag and the caller has not been granted either
/// access permission.
/// </term>
/// </item>
/// <item>
/// <term>WINBIO_E_INVALID_UNIT</term>
/// <term>One or more of the biometric unit numbers specified in the UnitArray parameter is not valid.</term>
/// </item>
/// <item>
/// <term>WINBIO_E_NOT_ACTIVE_CONSOLE</term>
/// <term>The client application is running on a remote desktop client and is attempting to open a system pool session.</term>
/// </item>
/// <item>
/// <term>WINBIO_E_SENSOR_UNAVAILABLE</term>
/// <term>The PoolType parameter is set to WINBIO_POOL_PRIVATE and one or more of the requested sensors in that pool is not available.</term>
/// </item>
/// <item>
/// <term>WINBIO_E_DISABLED</term>
/// <term>Current administrative policy prohibits use of the Windows Biometric Framework API.</term>
/// </item>
/// </list>
/// </returns>
// https://docs.microsoft.com/en-us/windows/win32/api/winbio/nf-winbio-winbioopensession HRESULT WinBioOpenSession(
// WINBIO_BIOMETRIC_TYPE Factor, WINBIO_POOL_TYPE PoolType, WINBIO_SESSION_FLAGS Flags, WINBIO_UNIT_ID *UnitArray, SIZE_T UnitCount,
// GUID *DatabaseId, WINBIO_SESSION_HANDLE *SessionHandle );
[DllImport(Lib_Winbio, SetLastError = false, ExactSpelling = true)]
[PInvokeData("winbio.h", MSDNShortId = "NF:winbio.WinBioOpenSession")]
public static extern HRESULT WinBioOpenSession(WINBIO_BIOMETRIC_TYPE Factor, WINBIO_POOL_TYPE PoolType, WINBIO_SESSION_FLAGS Flags,
[In, Optional, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 4)] WINBIO_UNIT_ID[] UnitArray, [In, Optional] SizeT UnitCount,
in Guid DatabaseId, out WINBIO_SESSION_HANDLE SessionHandle);
/// <summary>Connects to a biometric service provider and one or more biometric units.</summary>
/// <param name="Factor">
/// A bitmask of WINBIO_BIOMETRIC_TYPE flags that specifies the biometric unit types to be enumerated. Only
/// <c>WINBIO_TYPE_FINGERPRINT</c> is currently supported.
/// </param>
/// <param name="PoolType">
/// <para>
/// A <c>ULONG</c> value that specifies the type of the biometric units that will be used in the session. This can be one of the
/// following values:
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>WINBIO_POOL_SYSTEM</term>
/// <term>The session connects to a shared collection of biometric units managed by the service provider.</term>
/// </item>
/// <item>
/// <term>WINBIO_POOL_PRIVATE</term>
/// <term>The session connects to a collection of biometric units that are managed by the caller.</term>
/// </item>
/// </list>
/// </param>
/// <param name="Flags">
/// <para>
/// A <c>ULONG</c> value that specifies biometric unit configuration and access characteristics for the new session. Configuration
/// flags specify the general configuration of units in the session. Access flags specify how the application will use the biometric
/// units. You must specify one configuration flag but you can combine that flag with any access flag.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>WINBIO_FLAG_DEFAULT</term>
/// <term>
/// Group: configuration The biometric units operate in the manner specified during installation. You must use this value when the
/// PoolType parameter is WINBIO_POOL_SYSTEM.
/// </term>
/// </item>
/// <item>
/// <term>WINBIO_FLAG_BASIC</term>
/// <term>
/// Group: configuration The biometric units operate only as basic capture devices. All processing, matching, and storage operations
/// is performed by software plug-ins.
/// </term>
/// </item>
/// <item>
/// <term>WINBIO_FLAG_ADVANCED</term>
/// <term>Group: configuration The biometric units use internal processing and storage capabilities.</term>
/// </item>
/// <item>
/// <term>WINBIO_FLAG_RAW</term>
/// <term>Group: access The client application captures raw biometric data using WinBioCaptureSample.</term>
/// </item>
/// <item>
/// <term>WINBIO_FLAG_MAINTENANCE</term>
/// <term>Group: access The client performs vendor-defined control operations on a biometric unit by calling WinBioControlUnitPrivileged.</term>
/// </item>
/// </list>
/// </param>
/// <param name="UnitArray">
/// Pointer to an array of biometric unit identifiers to be included in the session. You can call WinBioEnumBiometricUnits to
/// enumerate the biometric units. Set this value to <c>NULL</c> if the PoolType parameter is <c>WINBIO_POOL_SYSTEM</c>.
/// </param>
/// <param name="UnitCount">
/// A value that specifies the number of elements in the array pointed to by the UnitArray parameter. Set this value to zero if the
/// PoolType parameter is <c>WINBIO_POOL_SYSTEM</c>.
/// </param>
/// <param name="DatabaseId">
/// <para>
/// A value that specifies the database(s) to be used by the session. If the PoolType parameter is <c>WINBIO_POOL_PRIVATE</c>, you
/// must specify the GUID of an installed database. If the PoolType parameter is not <c>WINBIO_POOL_PRIVATE</c>, you can specify one
/// of the following common values.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>WINBIO_DB_DEFAULT</term>
/// <term>
/// Each biometric unit in the sensor pool uses the default database specified in the default biometric unit configuration. You must
/// specify this value if the PoolType parameter is WINBIO_POOL_SYSTEM. You cannot use this value if the PoolType parameter is WINBIO_POOL_PRIVATE
/// </term>
/// </item>
/// <item>
/// <term>WINBIO_DB_BOOTSTRAP</term>
/// <term>
/// You can specify this value to be used for scenarios prior to starting Windows. Typically, the database is part of the sensor
/// chip or is part of the BIOS and can only be used for template enrollment and deletion.
/// </term>
/// </item>
/// <item>
/// <term>WINBIO_DB_ONCHIP</term>
/// <term>The database is on the sensor chip and is available for enrollment and matching.</term>
/// </item>
/// </list>
/// </param>
/// <param name="SessionHandle">Pointer to the new session handle. If the function does not succeed, the handle is set to zero.</param>
/// <returns>
/// <para>
/// If the function succeeds, it returns S_OK. If the function fails, it returns an <c>HRESULT</c> value that indicates the error.
/// Possible values include, but are not limited to, those in the following table. For a list of common error codes, see Common
/// HRESULT Values.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>E_INVALIDARG</term>
/// <term>One or more arguments have incorrect values or are incompatible with other arguments.</term>
/// </item>
/// <item>
/// <term>E_POINTER</term>
/// <term>The session handle pointer in the SessionHandle parameter cannot be NULL.</term>
/// </item>
/// <item>
/// <term>E_ACCESSDENIED</term>
/// <term>
/// The Flags parameter contains the WINBIO_FLAG_RAW or the WINBIO_FLAG_MAINTENANCE flag and the caller has not been granted either
/// access permission.
/// </term>
/// </item>
/// <item>
/// <term>WINBIO_E_INVALID_UNIT</term>
/// <term>One or more of the biometric unit numbers specified in the UnitArray parameter is not valid.</term>
/// </item>
/// <item>
/// <term>WINBIO_E_NOT_ACTIVE_CONSOLE</term>
/// <term>The client application is running on a remote desktop client and is attempting to open a system pool session.</term>
/// </item>
/// <item>
/// <term>WINBIO_E_SENSOR_UNAVAILABLE</term>
/// <term>The PoolType parameter is set to WINBIO_POOL_PRIVATE and one or more of the requested sensors in that pool is not available.</term>
/// </item>
/// <item>
/// <term>WINBIO_E_DISABLED</term>
/// <term>Current administrative policy prohibits use of the Windows Biometric Framework API.</term>
/// </item>
/// </list>
/// </returns>
// https://docs.microsoft.com/en-us/windows/win32/api/winbio/nf-winbio-winbioopensession HRESULT WinBioOpenSession(
// WINBIO_BIOMETRIC_TYPE Factor, WINBIO_POOL_TYPE PoolType, WINBIO_SESSION_FLAGS Flags, WINBIO_UNIT_ID *UnitArray, SIZE_T UnitCount,
// GUID *DatabaseId, WINBIO_SESSION_HANDLE *SessionHandle );
[DllImport(Lib_Winbio, SetLastError = false, ExactSpelling = true)]
[PInvokeData("winbio.h", MSDNShortId = "NF:winbio.WinBioOpenSession")]
public static extern HRESULT WinBioOpenSession(WINBIO_BIOMETRIC_TYPE Factor, WINBIO_POOL_TYPE PoolType, WINBIO_SESSION_FLAGS Flags,
[In, Optional, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 4)] WINBIO_UNIT_ID[] UnitArray, [In, Optional] SizeT UnitCount,
[In, Optional] GuidPtr DatabaseId, out WINBIO_SESSION_HANDLE SessionHandle);
/// <summary>
/// The <c>WinBioRegisterEventMonitor</c> function Registers a callback function to receive event notifications from the service
/// provider associated with an open session.
/// </summary>
/// <param name="SessionHandle">
/// A <c>WINBIO_SESSION_HANDLE</c> value that identifies the open biometric session. Open the session handle by calling WinBioOpenSession.
/// </param>
/// <param name="EventMask">
/// <para>
/// A value that specifies the types of events to monitor. Only the fingerprint provider is currently supported. You must specify
/// one of the following flags.
/// </para>
/// <list type="bullet">
/// <item>
/// <term><c>WINBIO_EVENT_FP_UNCLAIMED</c></term>
/// </item>
/// </list>
/// <para>
/// The sensor detected a finger swipe that was not requested by the application, or the requesting application does not have window
/// focus. The Windows Biometric Framework calls into your callback function to indicate that a finger swipe has occurred but does
/// not try to identify the fingerprint.
/// </para>
/// <list type="bullet">
/// <item>
/// <term><c>WINBIO_EVENT_FP_UNCLAIMED_IDENTIFY</c></term>
/// </item>
/// </list>
/// <para>
/// The sensor detected a finger swipe that was not requested by the application, or the requesting application does not have window
/// focus. The Windows Biometric Framework attempts to identify the fingerprint and passes the result of that process to your
/// callback function.
/// </para>
/// </param>
/// <param name="EventCallback">
/// Address of a callback function that receives the event notifications sent by the Windows Biometric Framework. You must define
/// this function.
/// </param>
/// <param name="EventCallbackContext">
/// An optional application-defined value that is returned in the pvContext parameter of the callback function. This value can
/// contain any data that the custom callback function is designed to handle.
/// </param>
/// <returns>
/// <para>
/// If the function succeeds, it returns S_OK. If the function fails, it returns an <c>HRESULT</c> value that indicates the error.
/// Possible values include, but are not limited to, those in the following table. For a list of common error codes, see Common
/// HRESULT Values.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>E_HANDLE</term>
/// <term>The session handle is not valid.</term>
/// </item>
/// <item>
/// <term>E_POINTER</term>
/// <term>The address of the callback function specified by the EventCallback parameter cannot be NULL.</term>
/// </item>
/// <item>
/// <term>E_INVALIDARG</term>
/// <term>
/// The EventMask parameter cannot be zero and you cannot specify both WINBIO_EVENT_FP_UNCLAIMED and
/// WINBIO_EVENT_FP_UNCLAIMED_IDENTIFY at the same time.
/// </term>
/// </item>
/// <item>
/// <term>WINBIO_E_EVENT_MONITOR_ACTIVE</term>
/// <term>An active event monitor has already been registered.</term>
/// </item>
/// <item>
/// <term>WINBIO_E_INVALID_OPERATION</term>
/// <term>The service provider does not support event notification.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>This function is only valid for sessions connected to a System sensor pool.</para>
/// <para>
/// Event callbacks are delivered to the client application serially. Therefore, subsequent event notifications will not be
/// delivered until the client returns from the current callback. Events that occur while a callback is still executing may be
/// discarded by the system. To avoid losing events, you should not perform any time-consuming work in your callback routine.
/// </para>
/// <para>
/// The client application should be prepared to receive events as soon as <c>WinBioRegisterEventMonitor</c> is called. The
/// application must call WinBioFree to release the structure returned in the Event argument of the callback. Failure to do so will
/// result in a memory leak in the calling process.
/// </para>
/// <para>
/// After an event monitor has been started, the session with which the monitor is associated will not be able to process other
/// Windows Biometric Framework API calls until the event monitor has been stopped. If your application needs to perform other API
/// calls while still receiving event monitor notifications, you should open two sessions - one for the event monitor and another
/// for other operations.
/// </para>
/// <para>Call WinBioUnregisterEventMonitor to stop sending event notifications to your callback function.</para>
/// <para>
/// If an application registers a <c>WinBio</c> event monitor and leaves that monitor active during a sleep/wake cycle, systems that
/// implement biometric pre-boot authentication (PBA)/single sign-on features may not always work. The problem is that the PBA
/// biometric call is intercepted by the event monitor before the system's biometric credential provider has a chance to perform its
/// first WinBioIdentify operation. Apps that use the <c>WinBio</c> event monitoring feature should unregister their monitors before
/// the system sleeps, and re-register them after system wakeup. For more information on handling events during power state changes,
/// see About Power Management.
/// </para>
/// <para>The callback routine must have the following signature:</para>
/// <para>
/// <code> VOID CALLBACK EventCallback( __in_opt PVOID EventCallbackContext, __in HRESULT OperationStatus, __in PWINBIO_EVENT Event );</code>
/// </para>
/// <para>Examples</para>
/// <para>
/// The following function registers an event monitor by calling the <c>WinBioRegisterEventMonitor</c> function and passing the
/// address of a callback routine. The callback, also included, receives event notifications from the Windows biometric framework.
/// Link to the Winbio.lib static library and include the following header files:
/// </para>
/// <list type="bullet">
/// <item>
/// <term>Windows.h</term>
/// </item>
/// <item>
/// <term>Stdio.h</term>
/// </item>
/// <item>
/// <term>Conio.h</term>
/// </item>
/// <item>
/// <term>Winbio.h</term>
/// </item>
/// </list>
/// <para>
/// <code>HRESULT RegisterSystemEventMonitor(BOOL bCancel) { HRESULT hr = S_OK; WINBIO_SESSION_HANDLE sessionHandle = NULL; WINBIO_UNIT_ID unitId = 0; // Connect to the system pool. hr = WinBioOpenSession( WINBIO_TYPE_FINGERPRINT, // Service provider WINBIO_POOL_SYSTEM, // Pool type WINBIO_FLAG_DEFAULT, // Configuration and access NULL, // Array of biometric unit IDs 0, // Count of biometric unit IDs NULL, // Database ID &amp;sessionHandle // [out] Session handle ); if (FAILED(hr)) { wprintf_s(L"\n WinBioOpenSession failed. hr = 0x%x\n", hr); goto e_Exit; } // Call the WinBioRegisterEventMonitor function. wprintf_s(L"\n Calling WinBioRegisterEventMonitor.\n"); hr = WinBioRegisterEventMonitor( sessionHandle, // Open session handle WINBIO_EVENT_FP_UNCLAIMED, // Events to monitor EventMonitorCallback, // Callback function NULL // Optional context. ); if (FAILED(hr)) { wprintf_s(L"\n WinBioRegisterEventMonitor failed."); wprintf_s(L"hr = 0x%x\n", hr); goto e_Exit; } wprintf_s(L"\n Waiting for an event.\n"); // Cancel the identification if the bCancel flag is set. if (bCancel) { wprintf_s(L"\n Starting CANCEL timer...\n"); Sleep( 7000 ); wprintf_s(L"\n Calling WinBioCancel\n"); hr = WinBioCancel( sessionHandle ); if (FAILED(hr)) { wprintf_s(L"\n WinBioCancel failed. hr = 0x%x\n", hr); goto e_Exit; } } // Wait for an event to happen. //wprintf_s(L"\n Swipe the sensor to receive an event notice "); //wprintf_s(L"\n or press any key to stop waiting...\n"); wprintf_s(L"\n Swipe the sensor one or more times "); wprintf_s(L"to generate events."); wprintf_s(L"\n When done, press a key to exit...\n"); _getch(); // Unregister the event monitor. wprintf_s(L"\n Calling WinBioUnregisterEventMonitor\n"); hr = WinBioUnregisterEventMonitor( sessionHandle); if (FAILED(hr)) { wprintf_s(L"\n WinBioUnregisterEventMonitor failed."); wprintf_s(L"hr = 0x%x\n", hr); } e_Exit: if (sessionHandle != NULL) { wprintf_s(L"\n Closing the session.\n"); hr = WinBioCloseSession(sessionHandle); if (FAILED(hr)) { wprintf_s(L"\n WinBioCloseSession failed. hr = 0x%x\n", hr); } sessionHandle = NULL; } wprintf_s(L"\n Press any key to exit..."); _getch(); return hr; } //------------------------------------------------------------------------ // The following function is the callback for WinBioRegisterEventMonitor. // The function filters any event notice from the biometric subsystem and // writes a result to the console window. // VOID CALLBACK EventMonitorCallback( __in_opt PVOID EventCallbackContext, __in HRESULT OperationStatus, __in PWINBIO_EVENT Event ) { UNREFERENCED_PARAMETER(EventCallbackContext); wprintf_s(L"\n EventMonitorCallback executing."); // Failure. if (FAILED(OperationStatus)) { wprintf_s(L"\n EventMonitorCallback failed. "); wprintf_s(L" OperationStatus = 0x%x\n", OperationStatus); goto e_Exit; } // An event notice was received. if (Event != NULL) { wprintf_s(L"\n MonitorEvent: "); switch (Event-&gt;Type) { case WINBIO_EVENT_FP_UNCLAIMED: wprintf_s(L"WINBIO_EVENT_FP_UNCLAIMED"); wprintf_s(L"\n Unit ID: %d", Event-&gt;Parameters.Unclaimed.UnitId); wprintf_s(L"\n Reject detail: %d\n", Event-&gt;Parameters.Unclaimed.RejectDetail); break; case WINBIO_EVENT_FP_UNCLAIMED_IDENTIFY: wprintf_s(L"WINBIO_EVENT_FP_UNCLAIMED_IDENTIFY"); wprintf_s(L"\n Unit ID: %d", Event-&gt;Parameters.UnclaimedIdentify.UnitId); wprintf_s(L"\n Reject detail: %d\n", Event-&gt;Parameters.UnclaimedIdentify.RejectDetail); break; case WINBIO_EVENT_ERROR: wprintf_s(L"WINBIO_EVENT_ERROR\n"); break; default: wprintf_s(L"(0x%08x - Invalid type)\n", Event-&gt;Type); break; } } e_Exit: if (Event != NULL) { //wprintf_s(L"\n Press any key to continue...\n"); WinBioFree(Event); Event = NULL; } }</code>
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winbio/nf-winbio-winbioregistereventmonitor HRESULT
// WinBioRegisterEventMonitor( WINBIO_SESSION_HANDLE SessionHandle, WINBIO_EVENT_TYPE EventMask, PWINBIO_EVENT_CALLBACK
// EventCallback, PVOID EventCallbackContext );
[DllImport(Lib_Winbio, SetLastError = false, ExactSpelling = true)]
[PInvokeData("winbio.h", MSDNShortId = "NF:winbio.WinBioRegisterEventMonitor")]
public static extern HRESULT WinBioRegisterEventMonitor(WINBIO_SESSION_HANDLE SessionHandle, WINBIO_EVENT_TYPE EventMask, PWINBIO_EVENT_CALLBACK EventCallback, [In, Optional] IntPtr EventCallbackContext);
/// <summary>Releases window focus.</summary>
/// <returns>
/// <para>
/// If the function succeeds, it returns <c>S_OK</c>. If the function fails, it returns an <c>HRESULT</c> value that indicates the
/// error. Possible values include, but are not limited to, those in the following table. For a list of common error codes, see
/// Common HRESULT Values.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>E_ACCESSDENIED</term>
/// <term>The calling process must be running under the Local System account.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>The Windows Biometric Framework uses window focus to arbitrate among multiple sessions connected to the system pool.</para>
/// <para>
/// The manner in which you acquire focus depends on the type of application you are writing. For example, if you are creating a GUI
/// application you can implement a message handler that captures a WM_ACTIVATE, WM_SETFOCUS, or other appropriate message. If you
/// are writing a CUI application, call <c>GetConsoleWindow</c> to retrieve a handle to the console window and pass that handle to
/// the <c>SetForegroundWindow</c> function to force the console window into the foreground and assign it focus. If your application
/// is running in a detached process or is a Windows service and has no window, use WinBioAcquireFocus and <c>WinBioReleaseFocus</c>
/// to manually control focus.
/// </para>
/// <para>The following list summarizes the major points to consider before calling WinBioAcquireFocus and <c>WinBioReleaseFocus</c>.</para>
/// <list type="bullet">
/// <item>
/// <term>The calling process must be running under the Local System account.</term>
/// </item>
/// <item>
/// <term>
/// A process that directly displays a user interface should not call WinBioAcquireFocus. See the preceding discussion to determine
/// how to acquire focus for GUI and CUI applications.
/// </term>
/// </item>
/// <item>
/// <term>
/// Only a service or a detached process that does not directly display a user interface during biometric API calls should call this function.
/// </term>
/// </item>
/// </list>
/// <para>If you do not acquire focus when calling the following functions, they will behave in unexpected ways:</para>
/// <list type="bullet">
/// <item>
/// <term>WinBioEnrollBegin</term>
/// </item>
/// <item>
/// <term>WinBioEnrollCapture</term>
/// </item>
/// <item>
/// <term>WinBioEnrollCaptureWithCallback</term>
/// </item>
/// </list>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winbio/nf-winbio-winbioreleasefocus HRESULT WinBioReleaseFocus();
[DllImport(Lib_Winbio, SetLastError = false, ExactSpelling = true)]
[PInvokeData("winbio.h", MSDNShortId = "NF:winbio.WinBioReleaseFocus")]
public static extern HRESULT WinBioReleaseFocus();
/// <summary>
/// Removes all credentials from the store. Starting with Windows 10, build 1607, this function is available to use with a mobile image.
/// </summary>
/// <returns>
/// If the function succeeds, it returns S_OK. If the function fails, it returns an <c>HRESULT</c> value that indicates the error.
/// For a list of common error codes, see Common HRESULT Values.
/// </returns>
// https://docs.microsoft.com/en-us/windows/win32/api/winbio/nf-winbio-winbioremoveallcredentials HRESULT WinBioRemoveAllCredentials();
[DllImport(Lib_Winbio, SetLastError = false, ExactSpelling = true)]
[PInvokeData("winbio.h", MSDNShortId = "NF:winbio.WinBioRemoveAllCredentials")]
public static extern HRESULT WinBioRemoveAllCredentials();
/// <summary>
/// Removes all user credentials for the current domain from the store. Starting with Windows 10, build 1607, this function is
/// available to use with a mobile image.
/// </summary>
/// <returns>
/// If the function succeeds, it returns S_OK. If the function fails, it returns an <c>HRESULT</c> value that indicates the error.
/// For a list of common error codes, see Common HRESULT Values.
/// </returns>
// https://docs.microsoft.com/en-us/windows/win32/api/winbio/nf-winbio-winbioremovealldomaincredentials HRESULT WinBioRemoveAllDomainCredentials();
[DllImport(Lib_Winbio, SetLastError = false, ExactSpelling = true)]
[PInvokeData("winbio.h", MSDNShortId = "NF:winbio.WinBioRemoveAllDomainCredentials")]
public static extern HRESULT WinBioRemoveAllDomainCredentials();
/// <summary>
/// Deletes a biometric logon credential for a specified user. Starting with Windows 10, build 1607, this function is available to
/// use with a mobile image.
/// </summary>
/// <param name="Identity">
/// A WINBIO_IDENTITY structure that contains the SID of the user account for which the logon credential will be removed.
/// </param>
/// <param name="Type">
/// <para>A WINBIO_CREDENTIAL_TYPE value that specifies the credential type. This can be one of the following values:</para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>WINBIO_CREDENTIAL_PASSWORD</term>
/// <term>The password-based credential will be deleted.</term>
/// </item>
/// <item>
/// <term>WINBIO_CREDENTIAL_ALL</term>
/// <term>All logon credentials for the user will be deleted.</term>
/// </item>
/// </list>
/// </param>
/// <returns>
/// <para>
/// If the function succeeds, it returns S_OK. If the function fails, it returns an <c>HRESULT</c> value that indicates the error.
/// Possible values include, but are not limited to, those in the following table. For a list of common error codes, see Common
/// HRESULT Values.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>E_ACCESSDENIED</term>
/// <term>The caller does not have permission to delete the credential.</term>
/// </item>
/// <item>
/// <term>WINBIO_E_CRED_PROV_NO_CREDENTIAL</term>
/// <term>The specified identity does not exist or does not have any related records in the credential store.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// Users who do not have elevated privileges can delete only their own credentials. Elevated users can remove credentials for any
/// user account. Deleting a credential does not affect any biometric enrollments for that user. Deleting a biometric credential
/// does not prevent the user from logging on by using a password. Only medium and higher integrity processes can delete
/// credentials. If a lower integrity process attempts to delete credentials, the function returns E_ACCESSDENIED.
/// </para>
/// <para>Examples</para>
/// <para>
/// The following function shows how to call <c>WinBioRemoveCredential</c> to remove credentials for a specific user. The helper
/// function GetCurrentUserIdentity is also included. Link to the Winbio.lib static library and include the following header files:
/// </para>
/// <list type="bullet">
/// <item>
/// <term>Windows.h</term>
/// </item>
/// <item>
/// <term>Stdio.h</term>
/// </item>
/// <item>
/// <term>Conio.h</term>
/// </item>
/// <item>
/// <term>Winbio.h</term>
/// </item>
/// </list>
/// <para>
/// <code>HRESULT RemoveCredential() { HRESULT hr = S_OK; WINBIO_IDENTITY identity; // Find the identity of the user. wprintf_s(L"\n Finding user identity.\n"); hr = GetCurrentUserIdentity( &amp;identity ); if (FAILED(hr)) { wprintf(L"\n User identity not found. hr = 0x%x\n", hr); goto e_Exit; } // Remove the user credentials. hr = WinBioRemoveCredential(identity, WINBIO_CREDENTIAL_PASSWORD); if (FAILED(hr)) { wprintf(L"\n WinBioRemoveCredential failed. hr = 0x%x\n", hr); goto e_Exit; } wprintf_s(L"\n User credentials successfully removed.\n"); e_Exit: wprintf_s(L"\n Press any key to exit..."); _getch(); return hr; } //------------------------------------------------------------------------ // The following function retrieves the identity of the current user. // This is a helper function and is not part of the Windows Biometric // Framework API. // HRESULT GetCurrentUserIdentity(__inout PWINBIO_IDENTITY Identity) { // Declare variables. HRESULT hr = S_OK; HANDLE tokenHandle = NULL; DWORD bytesReturned = 0; struct{ TOKEN_USER tokenUser; BYTE buffer[SECURITY_MAX_SID_SIZE]; } tokenInfoBuffer; // Zero the input identity and specify the type. ZeroMemory( Identity, sizeof(WINBIO_IDENTITY)); Identity-&gt;Type = WINBIO_ID_TYPE_NULL; // Open the access token associated with the // current process if (!OpenProcessToken( GetCurrentProcess(), // Process handle TOKEN_READ, // Read access only &amp;tokenHandle)) // Access token handle { DWORD win32Status = GetLastError(); wprintf_s(L"Cannot open token handle: %d\n", win32Status); hr = HRESULT_FROM_WIN32(win32Status); goto e_Exit; } // Zero the tokenInfoBuffer structure. ZeroMemory(&amp;tokenInfoBuffer, sizeof(tokenInfoBuffer)); // Retrieve information about the access token. In this case, // retrieve a SID. if (!GetTokenInformation( tokenHandle, // Access token handle TokenUser, // User for the token &amp;tokenInfoBuffer.tokenUser, // Buffer to fill sizeof(tokenInfoBuffer), // Size of the buffer &amp;bytesReturned)) // Size needed { DWORD win32Status = GetLastError(); wprintf_s(L"Cannot query token information: %d\n", win32Status); hr = HRESULT_FROM_WIN32(win32Status); goto e_Exit; } // Copy the SID from the tokenInfoBuffer structure to the // WINBIO_IDENTITY structure. CopySid( SECURITY_MAX_SID_SIZE, Identity-&gt;Value.AccountSid.Data, tokenInfoBuffer.tokenUser.User.Sid ); // Specify the size of the SID and assign WINBIO_ID_TYPE_SID // to the type member of the WINBIO_IDENTITY structure. Identity-&gt;Value.AccountSid.Size = GetLengthSid(tokenInfoBuffer.tokenUser.User.Sid); Identity-&gt;Type = WINBIO_ID_TYPE_SID; e_Exit: if (tokenHandle != NULL) { CloseHandle(tokenHandle); } return hr; }</code>
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winbio/nf-winbio-winbioremovecredential HRESULT WinBioRemoveCredential(
// WINBIO_IDENTITY Identity, WINBIO_CREDENTIAL_TYPE Type );
[DllImport(Lib_Winbio, SetLastError = true, ExactSpelling = true)]
[PInvokeData("winbio.h", MSDNShortId = "NF:winbio.WinBioRemoveCredential")]
public static extern HRESULT WinBioRemoveCredential(WINBIO_IDENTITY Identity, WINBIO_CREDENTIAL_TYPE Type);
/// <summary>
/// Saves a biometric logon credential for the current user. Starting with Windows 10, build 1607, this function is available to use
/// with a mobile image.
/// </summary>
/// <param name="Type">A WINBIO_CREDENTIAL_TYPE value that specifies the credential type. Currently, this can be WINBIO_CREDENTIAL_PASSWORD.</param>
/// <param name="Credential">
/// A pointer to a variable length array of bytes that contains the credential. The format depends on the Type and Format parameters.
/// </param>
/// <param name="CredentialSize">Size, in bytes, of the value specified by the Credential parameter.</param>
/// <param name="Format">
/// <para>
/// A WINBIO_CREDENTIAL_FORMAT enumeration value that specifies the format of the credential. If the Type parameter is
/// <c>WINBIO_CREDENTIAL_PASSWORD</c>, this can be one of the following:
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>WINBIO_PASSWORD_GENERIC</term>
/// <term>The credential is a plaintext NULL-terminated Unicode string.</term>
/// </item>
/// <item>
/// <term>WINBIO_PASSWORD_PACKED</term>
/// <term>
/// The credential was wrapped by using the CredProtect function and packed by using the CredPackAuthenticationBuffer function. This
/// is recommended.
/// </term>
/// </item>
/// <item>
/// <term>WINBIO_PASSWORD_PROTECTED</term>
/// <term>The password credential was wrapped with CredProtect.</term>
/// </item>
/// </list>
/// </param>
/// <returns>
/// <para>
/// If the function succeeds, it returns S_OK. If the function fails, it returns an <c>HRESULT</c> value that indicates the error.
/// Possible values include, but are not limited to, those in the following table. For a list of common error codes, see Common
/// HRESULT Values.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>E_ACCESSDENIED</term>
/// <term>The caller does not have permission to set the credential.</term>
/// </item>
/// <item>
/// <term>WINBIO_E_UNKNOWN_ID</term>
/// <term>The user has not enrolled a biometric sample.</term>
/// </item>
/// <item>
/// <term>SEC_E_LOGON_DENIED</term>
/// <term>The credential was not valid for the current user.</term>
/// </item>
/// <item>
/// <term>WINBIO_E_CRED_PROV_DISABLED</term>
/// <term>Current administrative policy prohibits use of the credential provider.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// If the current user has an existing logon credential of the specified type, <c>WinBioSetCredential</c> will overwrite it. The
/// function verifies both the user credential and interactive logon privileges and fails if verification fails. An event related to
/// the logon attempt is placed in the event log. Credentials for domain accounts can be saved only if permitted by Group Policy.
/// </para>
/// <para>
/// You should call SecureZeroMemory to securely zero the credential if you pass <c>WINBIO_PASSWORD_PACKED</c> in the Format parameter.
/// </para>
/// <para>
/// Only medium and higher integrity processes can set credentials. If a lower integrity process attempts to set credentials, the
/// function returns E_ACCESSDENIED.
/// </para>
/// <para>Examples</para>
/// <para>
/// The following function retrieves the identity and credentials of the current user and then calls <c>WinBioSetCredential</c> to
/// set the credentials. Two helper functions, GetCredentials and GetCurrentUserIdentity, are also included. Link to the Winbio.lib
/// static library and include the following header files:
/// </para>
/// <list type="bullet">
/// <item>
/// <term>Windows.h</term>
/// </item>
/// <item>
/// <term>Wincred.h</term>
/// </item>
/// <item>
/// <term>Stdio.h</term>
/// </item>
/// <item>
/// <term>Conio.h</term>
/// </item>
/// <item>
/// <term>Winbio.h</term>
/// </item>
/// </list>
/// <para>
/// <code>HRESULT SetCredential() { // Declare variables. HRESULT hr = S_OK; PVOID pvAuthBlob = NULL; ULONG cbAuthBlob = 0; WINBIO_IDENTITY identity; PSID pSid = NULL; // Find the identity of the user. wprintf_s(L"\n Finding user identity.\n"); hr = GetCurrentUserIdentity( &amp;identity ); if (FAILED(hr)) { wprintf_s(L"\n User identity not found. hr = 0x%x\n", hr); return hr; } // Set a pointer to the security descriptor for the user. pSid = identity.Value.AccountSid.Data; // Retrieve a byte array that contains credential information. hr = GetCredentials(pSid, &amp;pvAuthBlob, &amp;cbAuthBlob); if (FAILED(hr)) { wprintf_s(L"\n GetCredentials failed. hr = 0x%x\n", hr); goto e_Exit; } // Set the credentials. hr = WinBioSetCredential( WINBIO_CREDENTIAL_PASSWORD, // Type of credential. (PUCHAR)pvAuthBlob, // Credentials byte array cbAuthBlob, // Size of credentials WINBIO_PASSWORD_PACKED); // Credentials format if (FAILED(hr)) { wprintf_s(L"\n WinBioSetCredential failed. hr = 0x%x\n", hr); goto e_Exit; } wprintf_s(L"\n Credentials successfully set.\n"); e_Exit: // Delete the authentication byte array. if (NULL != pvAuthBlob) { SecureZeroMemory(pvAuthBlob, cbAuthBlob); CoTaskMemFree(pvAuthBlob); pvAuthBlob = NULL; } wprintf_s(L"\n Press any key to exit..."); _getch(); return hr; } //------------------------------------------------------------------------ // The following function displays a dialog box to prompt a user // for credentials. // HRESULT GetCredentials(PSID pSid, PVOID* ppvAuthBlob, ULONG* pcbAuthBlob) { HRESULT hr = S_OK; DWORD dwResult; WCHAR szUsername[MAX_PATH] = {0}; DWORD cchUsername = ARRAYSIZE(szUsername); WCHAR szPassword[MAX_PATH] = {0}; WCHAR szDomain[MAX_PATH] = {0}; DWORD cchDomain = ARRAYSIZE(szDomain); WCHAR szDomainAndUser[MAX_PATH] = {0}; DWORD cchDomainAndUser = ARRAYSIZE(szDomainAndUser); PVOID pvInAuthBlob = NULL; ULONG cbInAuthBlob = 0; PVOID pvAuthBlob = NULL; ULONG cbAuthBlob = 0; CREDUI_INFOW ui; ULONG ulAuthPackage = 0; BOOL fSave = FALSE; static const WCHAR WINBIO_CREDPROV_TEST_PASSWORD_PROMPT_MESSAGE[] = L"Enter your current password to enable biometric logon."; static const WCHAR WINBIO_CREDPROV_TEST_PASSWORD_PROMPT_CAPTION[] = L"Biometric Log On Enrollment"; if (NULL == pSid || NULL == ppvAuthBlob || NULL == pcbAuthBlob) { return E_INVALIDARG; } // Retrieve the user name and domain name. SID_NAME_USE SidUse; DWORD cchTmpUsername = cchUsername; DWORD cchTmpDomain = cchDomain; if (!LookupAccountSidW( NULL, // Local computer pSid, // Security identifier for user szUsername, // User name &amp;cchTmpUsername, // Size of user name szDomain, // Domain name &amp;cchTmpDomain, // Size of domain name &amp;SidUse)) // Account type { dwResult = GetLastError(); hr = HRESULT_FROM_WIN32(dwResult); wprintf_s(L"\n LookupAccountSidLocalW failed: hr = 0x%x\n", hr); return hr; } // Combine the domain and user names. swprintf_s( szDomainAndUser, cchDomainAndUser, L"%s\\%s", szDomain, szUsername); // Call CredPackAuthenticationBufferW once to determine the size, // in bytes, of the authentication buffer. if (!CredPackAuthenticationBufferW( 0, // Reserved szDomainAndUser, // Domain\User name szPassword, // User Password NULL, // Packed credentials &amp;cbInAuthBlob) // Size, in bytes, of credentials &amp;&amp; GetLastError() != ERROR_INSUFFICIENT_BUFFER) { dwResult = GetLastError(); hr = HRESULT_FROM_WIN32(dwResult); wprintf_s(L"\n CredPackAuthenticationBufferW (1) failed: "); wprintf_s(L"hr = 0x%x\n", hr); } // Allocate memory for the input buffer. pvInAuthBlob = CoTaskMemAlloc(cbInAuthBlob); if (!pvInAuthBlob) { cbInAuthBlob = 0; wprintf_s(L"\n CoTaskMemAlloc() Out of memory %d\n"); return HRESULT_FROM_WIN32(ERROR_OUTOFMEMORY); } // Call CredPackAuthenticationBufferW again to retrieve the // authentication buffer. if (!CredPackAuthenticationBufferW( 0, szDomainAndUser, szPassword, (PBYTE)pvInAuthBlob, &amp;cbInAuthBlob)) { dwResult = GetLastError(); hr = HRESULT_FROM_WIN32(dwResult); wprintf_s(L"\n CredPackAuthenticationBufferW (2) failed: "); wprintf_s(L"hr = 0x%x\n", hr); goto e_Exit; } // Display a dialog box to request credentials. ui.cbSize = sizeof(ui); ui.hwndParent = GetConsoleWindow(); ui.pszMessageText = WINBIO_CREDPROV_TEST_PASSWORD_PROMPT_MESSAGE; ui.pszCaptionText = WINBIO_CREDPROV_TEST_PASSWORD_PROMPT_CAPTION; ui.hbmBanner = NULL; dwResult = CredUIPromptForWindowsCredentialsW( &amp;ui, // Customizing information 0, // Error code to display &amp;ulAuthPackage, // Authorization package pvInAuthBlob, // Credential byte array cbInAuthBlob, // Size of credential input buffer &amp;pvAuthBlob, // Output credential byte array &amp;cbAuthBlob, // Size of credential byte array &amp;fSave, // Select the save check box. CREDUIWIN_IN_CRED_ONLY | CREDUIWIN_ENUMERATE_CURRENT_USER ); if (dwResult != NO_ERROR) { hr = HRESULT_FROM_WIN32(dwResult); wprintf_s(L"\n CredUIPromptForWindowsCredentials failed: "); wprintf_s(L"0x%08x\n", dwResult); goto e_Exit; } *ppvAuthBlob = pvAuthBlob; *pcbAuthBlob = cbAuthBlob; e_Exit: // Delete the input authentication byte array. if (pvInAuthBlob) { SecureZeroMemory(pvInAuthBlob, cbInAuthBlob); CoTaskMemFree(pvInAuthBlob); pvInAuthBlob = NULL; }; return hr; } //------------------------------------------------------------------------ // The following function retrieves the identity of the current user. // This is a helper function and is not part of the Windows Biometric // Framework API. // HRESULT GetCurrentUserIdentity(__inout PWINBIO_IDENTITY Identity) { // Declare variables. HRESULT hr = S_OK; HANDLE tokenHandle = NULL; DWORD bytesReturned = 0; struct{ TOKEN_USER tokenUser; BYTE buffer[SECURITY_MAX_SID_SIZE]; } tokenInfoBuffer; // Zero the input identity and specify the type. ZeroMemory( Identity, sizeof(WINBIO_IDENTITY)); Identity-&gt;Type = WINBIO_ID_TYPE_NULL; // Open the access token associated with the // current process if (!OpenProcessToken( GetCurrentProcess(), // Process handle TOKEN_READ, // Read access only &amp;tokenHandle)) // Access token handle { DWORD win32Status = GetLastError(); wprintf_s(L"Cannot open token handle: %d\n", win32Status); hr = HRESULT_FROM_WIN32(win32Status); goto e_Exit; } // Zero the tokenInfoBuffer structure. ZeroMemory(&amp;tokenInfoBuffer, sizeof(tokenInfoBuffer)); // Retrieve information about the access token. In this case, // retrieve a SID. if (!GetTokenInformation( tokenHandle, // Access token handle TokenUser, // User for the token &amp;tokenInfoBuffer.tokenUser, // Buffer to fill sizeof(tokenInfoBuffer), // Size of the buffer &amp;bytesReturned)) // Size needed { DWORD win32Status = GetLastError(); wprintf_s(L"Cannot query token information: %d\n", win32Status); hr = HRESULT_FROM_WIN32(win32Status); goto e_Exit; } // Copy the SID from the tokenInfoBuffer structure to the // WINBIO_IDENTITY structure. CopySid( SECURITY_MAX_SID_SIZE, Identity-&gt;Value.AccountSid.Data, tokenInfoBuffer.tokenUser.User.Sid ); // Specify the size of the SID and assign WINBIO_ID_TYPE_SID // to the type member of the WINBIO_IDENTITY structure. Identity-&gt;Value.AccountSid.Size = GetLengthSid(tokenInfoBuffer.tokenUser.User.Sid); Identity-&gt;Type = WINBIO_ID_TYPE_SID; e_Exit: if (tokenHandle != NULL) { CloseHandle(tokenHandle); } return hr; }</code>
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winbio/nf-winbio-winbiosetcredential HRESULT WinBioSetCredential(
// WINBIO_CREDENTIAL_TYPE Type, PUCHAR Credential, SIZE_T CredentialSize, WINBIO_CREDENTIAL_FORMAT Format );
[DllImport(Lib_Winbio, SetLastError = true, ExactSpelling = true)]
[PInvokeData("winbio.h", MSDNShortId = "NF:winbio.WinBioSetCredential")]
public static extern HRESULT WinBioSetCredential(WINBIO_CREDENTIAL_TYPE Type, [In] IntPtr Credential, SizeT CredentialSize, WINBIO_CREDENTIAL_FORMAT Format);
/// <summary>
/// Sets the value of a standard property associated with a biometric session, unit, template, or account. Starting with Windows 10,
/// build 1607, this function is available to use with a mobile image.
/// </summary>
/// <param name="SessionHandle">
/// A <c>WINBIO_SESSION_HANDLE</c> value that identifies an open biometric session. Open a synchronous session handle by calling
/// WinBioOpenSession. Open an asynchronous session handle by calling WinBioAsyncOpenSession.
/// </param>
/// <param name="PropertyType">
/// A <c>WINBIO_PROPERTY_TYPE</c> value that specifies the type of the property that you want to set. Currently this must be <c>WINBIO_PROPERTY_TYPE_ACCOUNT</c>.
/// </param>
/// <param name="PropertyId">
/// A <c>WINBIO_PROPERTY_ID</c> value that specifies the property to set. Currently this must be
/// <c>WINBIO_PROPERTY_ANTI_SPOOF_POLICY</c>. All other properties are read-only.
/// </param>
/// <param name="UnitId">
/// A <c>WINBIO_UNIT_ID</c> value that identifies the biometric unit. For the <c>WINBIO_PROPERTY_ANTI_SPOOF_POLICY</c> property,
/// this value must be 0.
/// </param>
/// <param name="Identity">Address of a WINBIO_IDENTITY structure that specifies the account for which you want to set the property.</param>
/// <param name="SubFactor">Reserved. This must be <c>WINBIO_SUBTYPE_NO_INFORMATION</c>.</param>
/// <param name="PropertyBuffer">
/// A pointer to a structure that specifies the new value for the property. This value cannot be NULL. For setting the
/// <c>WINBIO_PROPERTY_ANTI_SPOOF_POLICY</c> property, the structure must be a WINBIO_ANTI_SPOOF_POLICY structure.
/// </param>
/// <param name="PropertyBufferSize">
/// The size, in bytes, of the structure to which the PropertyBuffer parameter points. This value cannot be 0.
/// </param>
/// <returns>
/// <para>
/// If the function succeeds, it returns <c>S_OK</c>. If the function fails, it returns an <c>HRESULT</c> value that indicates the
/// error. Possible values include, but are not limited to, those in the following table. For a list of common error codes, see
/// Common HRESULT Values.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>E_HANDLE</term>
/// <term>The session handle specified by the SessionHandle parameter is not valid.</term>
/// </item>
/// <item>
/// <term>E_POINTER</term>
/// <term>The Identity and PropertyBuffer parameters cannot be NULL.</term>
/// </item>
/// <item>
/// <term>E_INVALIDARG</term>
/// <term>The PropertyType, PropertyId, or PropertyBufferSize parameter cannot be 0.</term>
/// </item>
/// <item>
/// <term>WINBIO_E_INVALID_PROPERTY_TYPE</term>
/// <term>The value of the PropertyType argument is incorrect.</term>
/// </item>
/// <item>
/// <term>WINBIO_E_INVALID_PROPERTY_ID</term>
/// <term>The value of the PropertyId argument is incorrect.</term>
/// </item>
/// <item>
/// <term>WINBIO_E_LOCK_VIOLATION</term>
/// <term>The caller attempted to set a property that resides inside of a locked region.</term>
/// </item>
/// <item>
/// <term>WINBIO_E_UNSUPPORTED_PROPERTY</term>
/// <term>The object does not support the specified property.</term>
/// </item>
/// <item>
/// <term>WINBIO_E_ENROLLMENT_IN_PROGRESS</term>
/// <term>
/// The operation could not be completed because the specified biometric unit is currently being used for an enrollment transaction
/// (system pool only).
/// </term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// To use <c>WinBioSetProperty</c> synchronously, call the function with a session handle created by calling WinBioOpenSession. The
/// function blocks until the operation completes or an error is encountered. To prevent memory leaks, you must call WinBioFree to
/// release the memory pointed to by the PropertyBuffer parameter when you are finished using the data contained in the buffer.
/// </para>
/// <para>
/// To use <c>WinBioSetProperty</c> asynchronously, call the function with a session handle created by calling
/// WinBioAsyncOpenSession. The framework allocates a WINBIO_ASYNC_RESULT structure and uses it to return information about
/// operation success or failure. The <c>WINBIO_ASYNC_RESULT</c> structure is returned to the application callback or to the
/// application message queue, depending on the value you set in the NotificationMethod parameter of the
/// <c>WinBioAsyncOpenSession</c> function:
/// </para>
/// <list type="bullet">
/// <item>
/// <term>
/// If you choose to receive completion notices by using a callback, you must implement a PWINBIO_ASYNC_COMPLETION_CALLBACK function
/// and set the NotificationMethod parameter to <c>WINBIO_ASYNC_NOTIFY_CALLBACK</c>.
/// </term>
/// </item>
/// <item>
/// <term>
/// If you choose to receive completion notices by using the application message queue, you must set the NotificationMethod
/// parameter to <c>WINBIO_ASYNC_NOTIFY_MESSAGE</c>. The framework returns a WINBIO_ASYNC_RESULT pointer to the <c>LPARAM</c> field
/// of the window message.
/// </term>
/// </item>
/// </list>
/// <para>
/// To prevent memory leaks, you must call WinBioFree to release the WINBIO_ASYNC_RESULT structure after you have finished using it.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winbio/nf-winbio-winbiosetproperty HRESULT WinBioSetProperty(
// WINBIO_SESSION_HANDLE SessionHandle, WINBIO_PROPERTY_TYPE PropertyType, WINBIO_PROPERTY_ID PropertyId, WINBIO_UNIT_ID UnitId,
// WINBIO_IDENTITY *Identity, WINBIO_BIOMETRIC_SUBTYPE SubFactor, PVOID PropertyBuffer, SIZE_T PropertyBufferSize );
[DllImport(Lib_Winbio, SetLastError = false, ExactSpelling = true)]
[PInvokeData("winbio.h", MSDNShortId = "NF:winbio.WinBioSetProperty")]
public static extern HRESULT WinBioSetProperty(WINBIO_SESSION_HANDLE SessionHandle, WINBIO_PROPERTY_TYPE PropertyType, WINBIO_PROPERTY_ID PropertyId,
[Optional] WINBIO_UNIT_ID UnitId, in WINBIO_IDENTITY Identity, [Optional] WINBIO_BIOMETRIC_SUBTYPE SubFactor, [In] IntPtr PropertyBuffer, SizeT PropertyBufferSize);
/// <summary>
/// Sets the value of a standard property associated with a biometric session, unit, template, or account. Starting with Windows 10,
/// build 1607, this function is available to use with a mobile image.
/// </summary>
/// <param name="SessionHandle">
/// A <c>WINBIO_SESSION_HANDLE</c> value that identifies an open biometric session. Open a synchronous session handle by calling
/// WinBioOpenSession. Open an asynchronous session handle by calling WinBioAsyncOpenSession.
/// </param>
/// <param name="PropertyType">
/// A <c>WINBIO_PROPERTY_TYPE</c> value that specifies the type of the property that you want to set. Currently this must be <c>WINBIO_PROPERTY_TYPE_ACCOUNT</c>.
/// </param>
/// <param name="PropertyId">
/// A <c>WINBIO_PROPERTY_ID</c> value that specifies the property to set. Currently this must be
/// <c>WINBIO_PROPERTY_ANTI_SPOOF_POLICY</c>. All other properties are read-only.
/// </param>
/// <param name="UnitId">
/// A <c>WINBIO_UNIT_ID</c> value that identifies the biometric unit. For the <c>WINBIO_PROPERTY_ANTI_SPOOF_POLICY</c> property,
/// this value must be 0.
/// </param>
/// <param name="Identity">Address of a WINBIO_IDENTITY structure that specifies the account for which you want to set the property.</param>
/// <param name="SubFactor">Reserved. This must be <c>WINBIO_SUBTYPE_NO_INFORMATION</c>.</param>
/// <param name="PropertyBuffer">
/// A pointer to a structure that specifies the new value for the property. This value cannot be NULL. For setting the
/// <c>WINBIO_PROPERTY_ANTI_SPOOF_POLICY</c> property, the structure must be a WINBIO_ANTI_SPOOF_POLICY structure.
/// </param>
/// <param name="PropertyBufferSize">
/// The size, in bytes, of the structure to which the PropertyBuffer parameter points. This value cannot be 0.
/// </param>
/// <returns>
/// <para>
/// If the function succeeds, it returns <c>S_OK</c>. If the function fails, it returns an <c>HRESULT</c> value that indicates the
/// error. Possible values include, but are not limited to, those in the following table. For a list of common error codes, see
/// Common HRESULT Values.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>E_HANDLE</term>
/// <term>The session handle specified by the SessionHandle parameter is not valid.</term>
/// </item>
/// <item>
/// <term>E_POINTER</term>
/// <term>The Identity and PropertyBuffer parameters cannot be NULL.</term>
/// </item>
/// <item>
/// <term>E_INVALIDARG</term>
/// <term>The PropertyType, PropertyId, or PropertyBufferSize parameter cannot be 0.</term>
/// </item>
/// <item>
/// <term>WINBIO_E_INVALID_PROPERTY_TYPE</term>
/// <term>The value of the PropertyType argument is incorrect.</term>
/// </item>
/// <item>
/// <term>WINBIO_E_INVALID_PROPERTY_ID</term>
/// <term>The value of the PropertyId argument is incorrect.</term>
/// </item>
/// <item>
/// <term>WINBIO_E_LOCK_VIOLATION</term>
/// <term>The caller attempted to set a property that resides inside of a locked region.</term>
/// </item>
/// <item>
/// <term>WINBIO_E_UNSUPPORTED_PROPERTY</term>
/// <term>The object does not support the specified property.</term>
/// </item>
/// <item>
/// <term>WINBIO_E_ENROLLMENT_IN_PROGRESS</term>
/// <term>
/// The operation could not be completed because the specified biometric unit is currently being used for an enrollment transaction
/// (system pool only).
/// </term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// To use <c>WinBioSetProperty</c> synchronously, call the function with a session handle created by calling WinBioOpenSession. The
/// function blocks until the operation completes or an error is encountered. To prevent memory leaks, you must call WinBioFree to
/// release the memory pointed to by the PropertyBuffer parameter when you are finished using the data contained in the buffer.
/// </para>
/// <para>
/// To use <c>WinBioSetProperty</c> asynchronously, call the function with a session handle created by calling
/// WinBioAsyncOpenSession. The framework allocates a WINBIO_ASYNC_RESULT structure and uses it to return information about
/// operation success or failure. The <c>WINBIO_ASYNC_RESULT</c> structure is returned to the application callback or to the
/// application message queue, depending on the value you set in the NotificationMethod parameter of the
/// <c>WinBioAsyncOpenSession</c> function:
/// </para>
/// <list type="bullet">
/// <item>
/// <term>
/// If you choose to receive completion notices by using a callback, you must implement a PWINBIO_ASYNC_COMPLETION_CALLBACK function
/// and set the NotificationMethod parameter to <c>WINBIO_ASYNC_NOTIFY_CALLBACK</c>.
/// </term>
/// </item>
/// <item>
/// <term>
/// If you choose to receive completion notices by using the application message queue, you must set the NotificationMethod
/// parameter to <c>WINBIO_ASYNC_NOTIFY_MESSAGE</c>. The framework returns a WINBIO_ASYNC_RESULT pointer to the <c>LPARAM</c> field
/// of the window message.
/// </term>
/// </item>
/// </list>
/// <para>
/// To prevent memory leaks, you must call WinBioFree to release the WINBIO_ASYNC_RESULT structure after you have finished using it.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winbio/nf-winbio-winbiosetproperty HRESULT WinBioSetProperty(
// WINBIO_SESSION_HANDLE SessionHandle, WINBIO_PROPERTY_TYPE PropertyType, WINBIO_PROPERTY_ID PropertyId, WINBIO_UNIT_ID UnitId,
// WINBIO_IDENTITY *Identity, WINBIO_BIOMETRIC_SUBTYPE SubFactor, PVOID PropertyBuffer, SIZE_T PropertyBufferSize );
[DllImport(Lib_Winbio, SetLastError = false, ExactSpelling = true)]
[PInvokeData("winbio.h", MSDNShortId = "NF:winbio.WinBioSetProperty")]
public static extern HRESULT WinBioSetProperty(WINBIO_SESSION_HANDLE SessionHandle, WINBIO_PROPERTY_TYPE PropertyType, WINBIO_PROPERTY_ID PropertyId,
[Optional] WINBIO_UNIT_ID UnitId, [In, Optional] IntPtr Identity, [Optional] WINBIO_BIOMETRIC_SUBTYPE SubFactor, [In] IntPtr PropertyBuffer, SizeT PropertyBufferSize);
/// <summary>Releases the session lock on the specified biometric unit.</summary>
/// <param name="SessionHandle">
/// A <c>WINBIO_SESSION_HANDLE</c> value that identifies an open biometric session. Open a synchronous session handle by calling
/// WinBioOpenSession. Open an asynchronous session handle by calling WinBioAsyncOpenSession.
/// </param>
/// <param name="UnitId">A <c>WINBIO_UNIT_ID</c> value that specifies the biometric unit to unlock.</param>
/// <returns>
/// <para>
/// If the function succeeds, it returns S_OK. If the function fails, it returns an <c>HRESULT</c> value that indicates the error.
/// Possible values include, but are not limited to, those in the following table. For a list of common error codes, see Common
/// HRESULT Values.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>E_HANDLE</term>
/// <term>The session handle is not valid.</term>
/// </item>
/// <item>
/// <term>E_INVALIDARG</term>
/// <term>The UnitId parameter cannot contain zero.</term>
/// </item>
/// <item>
/// <term>WINBIO_E_LOCK_VIOLATION</term>
/// <term>The biometric unit specified by the UnitId parameter is not currently locked by the session.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// Calling <c>WinBioUnlockUnit</c> automatically releases any locks held by the session. This function will fail if the biometric
/// unit specified by the UnitId has not been previously locked by calling the WinBioLockUnit function.
/// </para>
/// <para>
/// To use <c>WinBioUnlockUnit</c> synchronously, call the function with a session handle created by calling WinBioOpenSession. The
/// function blocks until the operation completes or an error is encountered.
/// </para>
/// <para>
/// To use <c>WinBioUnlockUnit</c> asynchronously, call the function with a session handle created by calling
/// WinBioAsyncOpenSession. The framework allocates a WINBIO_ASYNC_RESULT structure and uses it to return information about
/// operation success or failure. The <c>WINBIO_ASYNC_RESULT</c> structure is returned to the application callback or to the
/// application message queue, depending on the value you set in the NotificationMethod parameter of the
/// <c>WinBioAsyncOpenSession</c> function:
/// </para>
/// <list type="bullet">
/// <item>
/// <term>
/// If you choose to receive completion notices by using a callback, you must implement a PWINBIO_ASYNC_COMPLETION_CALLBACK function
/// and set the NotificationMethod parameter to <c>WINBIO_ASYNC_NOTIFY_CALLBACK</c>.
/// </term>
/// </item>
/// <item>
/// <term>
/// If you choose to receive completion notices by using the application message queue, you must set the NotificationMethod
/// parameter to <c>WINBIO_ASYNC_NOTIFY_MESSAGE</c>. The framework returns a WINBIO_ASYNC_RESULT pointer to the <c>LPARAM</c> field
/// of the window message.
/// </term>
/// </item>
/// </list>
/// <para>
/// To prevent memory leaks, you must call WinBioFree to release the WINBIO_ASYNC_RESULT structure after you have finished using it.
/// </para>
/// <para>Examples</para>
/// <para>
/// The following function calls WinBioLockUnit to lock the biometric unit before calling WinBioIdentify to identify the user. It
/// calls <c>WinBioUnlockUnit</c> to unlock the biometric union before closing the open session. Link to the Winbio.lib static
/// library and include the following header files:
/// </para>
/// <list type="bullet">
/// <item>
/// <term>Windows.h</term>
/// </item>
/// <item>
/// <term>Stdio.h</term>
/// </item>
/// <item>
/// <term>Conio.h</term>
/// </item>
/// <item>
/// <term>Winbio.h</term>
/// </item>
/// </list>
/// <para>
/// <code>HRESULT LockUnlock( ) { // Declare variables. HRESULT hr = S_OK; WINBIO_IDENTITY identity = {0}; WINBIO_SESSION_HANDLE sessionHandle = NULL; WINBIO_UNIT_ID unitId = 0; WINBIO_REJECT_DETAIL rejectDetail = 0; WINBIO_BIOMETRIC_SUBTYPE subFactor = WINBIO_SUBTYPE_NO_INFORMATION; BOOL lockAcquired = FALSE; // Connect to the system pool. hr = WinBioOpenSession( WINBIO_TYPE_FINGERPRINT, // Service provider WINBIO_POOL_SYSTEM, // Pool type WINBIO_FLAG_DEFAULT, // Configuration and access NULL, // Array of biometric unit IDs 0, // Count of biometric unit IDs NULL, // Database ID &amp;sessionHandle // [out] Session handle ); if (FAILED(hr)) { wprintf_s(L"\n WinBioEnumBiometricUnits failed. hr = 0x%x\n", hr); goto e_Exit; } // Lock the session. The Biometric unit ID (1) is hard coded in // this example. hr = WinBioLockUnit( sessionHandle, 1 ); if (FAILED(hr)) { wprintf_s(L"\n WinBioLockUnit failed. hr = 0x%x\n", hr); goto e_Exit; } wprintf_s(L"\n Biometric unit #1 is locked.\n"); lockAcquired = TRUE; // Locate the biometric sensor and retrieve a WINBIO_IDENTITY object. // You must swipe your finger on the sensor. wprintf_s(L"\n Calling WinBioIdentify - Swipe finger on sensor...\n"); hr = WinBioIdentify( sessionHandle, &amp;unitId, &amp;identity, &amp;subFactor, &amp;rejectDetail ); wprintf_s(L"\n Swipe processed - Unit ID: %d\n", unitId); if (FAILED(hr)) { wprintf_s(L"\n WinBioIdentify failed. hr = 0x%x\n", hr); goto e_Exit; } e_Exit: // Unlock the biometric unit if it is locked. if (lockAcquired == TRUE) { hr = WinBioUnlockUnit( sessionHandle, 1 ); if (FAILED(hr)) { wprintf_s(L"\n WinBioUnlockUnit failed. hr = 0x%x\n", hr); } wprintf_s(L"\n Biometric unit #1 is unlocked.\n"); lockAcquired = FALSE; } if (sessionHandle != NULL) { WinBioCloseSession(sessionHandle); sessionHandle = NULL; } wprintf_s(L"\n Press any key to exit..."); _getch(); return hr; }</code>
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winbio/nf-winbio-winbiounlockunit HRESULT WinBioUnlockUnit(
// WINBIO_SESSION_HANDLE SessionHandle, WINBIO_UNIT_ID UnitId );
[DllImport(Lib_Winbio, SetLastError = false, ExactSpelling = true)]
[PInvokeData("winbio.h", MSDNShortId = "NF:winbio.WinBioUnlockUnit")]
public static extern HRESULT WinBioUnlockUnit(WINBIO_SESSION_HANDLE SessionHandle, WINBIO_UNIT_ID UnitId);
/// <summary>
/// The <c>WinBioUnregisterEventMonitor</c> function cancels event notifications from the service provider associated with an open
/// biometric session.
/// </summary>
/// <param name="SessionHandle">
/// A <c>WINBIO_SESSION_HANDLE</c> value that identifies the open biometric session. Open the session handle by calling WinBioOpenSession.
/// </param>
/// <returns>
/// <para>
/// If the function succeeds, it returns S_OK. If the function fails, it returns an <c>HRESULT</c> value that indicates the error.
/// Possible values include, but are not limited to, those in the following table. For a list of common error codes, see Common
/// HRESULT Values.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>E_HANDLE</term>
/// <term>The session handle is not valid.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>Call the WinBioRegisterEventMonitor function to begin receiving event notifications.</para>
/// <para>
/// If an application registers a <c>WinBio</c> event monitor and leaves that monitor active during a sleep/wake cycle, systems that
/// implement biometric pre-boot authentication (PBA)/single sign-on features may not always work. The problem is that the PBA
/// biometric call is intercepted by the event monitor before the system's biometric credential provider has a chance to perform its
/// first WinBioIdentify operation. Apps that use the <c>WinBio</c> event monitoring feature should unregister their monitors before
/// the system sleeps, and re-register them after system wakeup. For more information on handling events during power state changes,
/// see About Power Management.
/// </para>
/// <para>Examples</para>
/// <para>
/// The following function registers an event monitor by calling the WinBioRegisterEventMonitor function and passing the address of
/// a callback routine. The callback, also included, receives event notifications from the Windows biometric framework. The function
/// also calls <c>WinBioUnregisterEventMonitor</c> before closing the biometric session. Link to the Winbio.lib static library and
/// include the following header files:
/// </para>
/// <list type="bullet">
/// <item>
/// <term>Windows.h</term>
/// </item>
/// <item>
/// <term>Stdio.h</term>
/// </item>
/// <item>
/// <term>Conio.h</term>
/// </item>
/// <item>
/// <term>Winbio.h</term>
/// </item>
/// </list>
/// <para>
/// <code>HRESULT RegisterSystemEventMonitor(BOOL bCancel) { HRESULT hr = S_OK; WINBIO_SESSION_HANDLE sessionHandle = NULL; WINBIO_UNIT_ID unitId = 0; // Connect to the system pool. hr = WinBioOpenSession( WINBIO_TYPE_FINGERPRINT, // Service provider WINBIO_POOL_SYSTEM, // Pool type WINBIO_FLAG_DEFAULT, // Configuration and access NULL, // Array of biometric unit IDs 0, // Count of biometric unit IDs NULL, // Database ID &amp;sessionHandle // [out] Session handle ); if (FAILED(hr)) { wprintf_s(L"\n WinBioOpenSession failed. hr = 0x%x\n", hr); goto e_Exit; } // Call the WinBioRegisterEventMonitor function. wprintf_s(L"\n Calling WinBioRegisterEventMonitor.\n"); hr = WinBioRegisterEventMonitor( sessionHandle, // Open session handle WINBIO_EVENT_FP_UNCLAIMED, // Events to monitor EventMonitorCallback, // Callback function NULL // Optional context. ); if (FAILED(hr)) { wprintf_s(L"\n WinBioRegisterEventMonitor failed."); wprintf_s(L"hr = 0x%x\n", hr); goto e_Exit; } wprintf_s(L"\n Waiting for an event.\n"); // Cancel the identification if the bCancel flag is set. if (bCancel) { wprintf_s(L"\n Starting CANCEL timer...\n"); Sleep( 7000 ); wprintf_s(L"\n Calling WinBioCancel\n"); hr = WinBioCancel( sessionHandle ); if (FAILED(hr)) { wprintf_s(L"\n WinBioCancel failed. hr = 0x%x\n", hr); goto e_Exit; } } // Wait for an event to happen. //wprintf_s(L"\n Swipe the sensor to receive an event notice "); //wprintf_s(L"\n or press any key to stop waiting...\n"); wprintf_s(L"\n Swipe the sensor one or more times "); wprintf_s(L"to generate events."); wprintf_s(L"\n When done, press a key to exit...\n"); _getch(); // Unregister the event monitor. wprintf_s(L"\n Calling WinBioUnregisterEventMonitor\n"); hr = WinBioUnregisterEventMonitor( sessionHandle); if (FAILED(hr)) { wprintf_s(L"\n WinBioUnregisterEventMonitor failed."); wprintf_s(L"hr = 0x%x\n", hr); } e_Exit: if (sessionHandle != NULL) { wprintf_s(L"\n Closing the session.\n"); hr = WinBioCloseSession(sessionHandle); if (FAILED(hr)) { wprintf_s(L"\n WinBioCloseSession failed. hr = 0x%x\n", hr); } sessionHandle = NULL; } wprintf_s(L"\n Press any key to exit..."); _getch(); return hr; } //------------------------------------------------------------------------ // The following function is the callback for WinBioRegisterEventMonitor. // The function filters any event notice from the biometric subsystem and // writes a result to the console window. // VOID CALLBACK EventMonitorCallback( __in_opt PVOID EventCallbackContext, __in HRESULT OperationStatus, __in PWINBIO_EVENT Event ) { UNREFERENCED_PARAMETER(EventCallbackContext); wprintf_s(L"\n EventMonitorCallback executing."); // Failure. if (FAILED(OperationStatus)) { wprintf_s(L"\n EventMonitorCallback failed. "); wprintf_s(L" OperationStatus = 0x%x\n", OperationStatus); goto e_Exit; } // An event notice was received. if (Event != NULL) { wprintf_s(L"\n MonitorEvent: "); switch (Event-&gt;Type) { case WINBIO_EVENT_FP_UNCLAIMED: wprintf_s(L"WINBIO_EVENT_FP_UNCLAIMED"); wprintf_s(L"\n Unit ID: %d", Event-&gt;Parameters.Unclaimed.UnitId); wprintf_s(L"\n Reject detail: %d\n", Event-&gt;Parameters.Unclaimed.RejectDetail); break; case WINBIO_EVENT_FP_UNCLAIMED_IDENTIFY: wprintf_s(L"WINBIO_EVENT_FP_UNCLAIMED_IDENTIFY"); wprintf_s(L"\n Unit ID: %d", Event-&gt;Parameters.UnclaimedIdentify.UnitId); wprintf_s(L"\n Reject detail: %d\n", Event-&gt;Parameters.UnclaimedIdentify.RejectDetail); break; case WINBIO_EVENT_ERROR: wprintf_s(L"WINBIO_EVENT_ERROR\n"); break; default: wprintf_s(L"(0x%08x - Invalid type)\n", Event-&gt;Type); break; } } e_Exit: if (Event != NULL) { //wprintf_s(L"\n Press any key to continue...\n"); WinBioFree(Event); Event = NULL; } }</code>
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winbio/nf-winbio-winbiounregistereventmonitor HRESULT
// WinBioUnregisterEventMonitor( WINBIO_SESSION_HANDLE SessionHandle );
[DllImport(Lib_Winbio, SetLastError = false, ExactSpelling = true)]
[PInvokeData("winbio.h", MSDNShortId = "NF:winbio.WinBioUnregisterEventMonitor")]
public static extern HRESULT WinBioUnregisterEventMonitor(WINBIO_SESSION_HANDLE SessionHandle);
/// <summary>
/// Captures a biometric sample and determines whether the sample corresponds to the specified user identity. Starting with Windows
/// 10, build 1607, this function is available to use with a mobile image.
/// </summary>
/// <param name="SessionHandle">
/// A <c>WINBIO_SESSION_HANDLE</c> value that identifies an open biometric session. Open a synchronous session handle by calling
/// WinBioOpenSession. Open an asynchronous session handle by calling WinBioAsyncOpenSession.
/// </param>
/// <param name="Identity">
/// Pointer to a WINBIO_IDENTITY structure that contains the GUID or SID of the user providing the biometric sample.
/// </param>
/// <param name="SubFactor">
/// <para>
/// A <c>WINBIO_BIOMETRIC_SUBTYPE</c> value that specifies the sub-factor associated with the biometric sample. The Windows
/// Biometric Framework (WBF) currently supports only fingerprint capture and can use the following constants to represent sub-type information.
/// </para>
/// <list type="bullet">
/// <item>
/// <term>WINBIO_ANSI_381_POS_RH_THUMB</term>
/// </item>
/// <item>
/// <term>WINBIO_ANSI_381_POS_RH_INDEX_FINGER</term>
/// </item>
/// <item>
/// <term>WINBIO_ANSI_381_POS_RH_MIDDLE_FINGER</term>
/// </item>
/// <item>
/// <term>WINBIO_ANSI_381_POS_RH_RING_FINGER</term>
/// </item>
/// <item>
/// <term>WINBIO_ANSI_381_POS_RH_LITTLE_FINGER</term>
/// </item>
/// <item>
/// <term>WINBIO_ANSI_381_POS_LH_THUMB</term>
/// </item>
/// <item>
/// <term>WINBIO_ANSI_381_POS_LH_INDEX_FINGER</term>
/// </item>
/// <item>
/// <term>WINBIO_ANSI_381_POS_LH_MIDDLE_FINGER</term>
/// </item>
/// <item>
/// <term>WINBIO_ANSI_381_POS_LH_RING_FINGER</term>
/// </item>
/// <item>
/// <term>WINBIO_ANSI_381_POS_LH_LITTLE_FINGER</term>
/// </item>
/// <item>
/// <term>WINBIO_ANSI_381_POS_RH_FOUR_FINGERS</term>
/// </item>
/// <item>
/// <term>WINBIO_ANSI_381_POS_LH_FOUR_FINGERS</term>
/// </item>
/// <item>
/// <term>WINBIO_SUBTYPE_ANY</term>
/// </item>
/// </list>
/// </param>
/// <param name="UnitId">A pointer to a <c>WINBIO_UNIT_ID</c> value that specifies the biometric unit that performed the verification.</param>
/// <param name="Match">
/// Pointer to a Boolean value that specifies whether the captured sample matched the user identity specified by the Identity parameter.
/// </param>
/// <param name="RejectDetail">
/// <para>
/// A pointer to a <c>ULONG</c> value that contains additional information about the failure to capture a biometric sample. If the
/// capture succeeded, this parameter is set to zero. The following values are defined for fingerprint capture:
/// </para>
/// <list type="bullet">
/// <item>
/// <term>WINBIO_FP_TOO_HIGH</term>
/// </item>
/// <item>
/// <term>WINBIO_FP_TOO_LOW</term>
/// </item>
/// <item>
/// <term>WINBIO_FP_TOO_LEFT</term>
/// </item>
/// <item>
/// <term>WINBIO_FP_TOO_RIGHT</term>
/// </item>
/// <item>
/// <term>WINBIO_FP_TOO_FAST</term>
/// </item>
/// <item>
/// <term>WINBIO_FP_TOO_SLOW</term>
/// </item>
/// <item>
/// <term>WINBIO_FP_POOR_QUALITY</term>
/// </item>
/// <item>
/// <term>WINBIO_FP_TOO_SKEWED</term>
/// </item>
/// <item>
/// <term>WINBIO_FP_TOO_SHORT</term>
/// </item>
/// <item>
/// <term>WINBIO_FP_MERGE_FAILURE</term>
/// </item>
/// </list>
/// </param>
/// <returns>
/// <para>
/// If the function succeeds, it returns S_OK. If the function fails, it returns an <c>HRESULT</c> value that indicates the error.
/// Possible values include, but are not limited to, those in the following table. For a list of common error codes, see Common
/// HRESULT Values.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>E_HANDLE</term>
/// <term>The session handle is not valid.</term>
/// </item>
/// <item>
/// <term>E_INVALIDARG</term>
/// <term>The SubFactor argument is incorrect.</term>
/// </item>
/// <item>
/// <term>E_POINTER</term>
/// <term>The pointer specified by the UnitId, Identity, SubFactor, or RejectDetail parameters cannot be NULL.</term>
/// </item>
/// <item>
/// <term>WINBIO_E_BAD_CAPTURE</term>
/// <term>The biometric sample could not be captured. Use the RejectDetail value for more information.</term>
/// </item>
/// <item>
/// <term>WINBIO_E_ENROLLMENT_IN_PROGRESS</term>
/// <term>
/// The operation could not be completed because the specified biometric unit is currently being used for an enrollment transaction
/// (system pool only).
/// </term>
/// </item>
/// <item>
/// <term>WINBIO_E_NO_MATCH</term>
/// <term>The biometric sample does not correspond to the specified Identity and SubFactor combination.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// If capture of the biometric sample fails, the UnitId parameter will contain the unit number of the sensor that attempted to
/// perform the capture.
/// </para>
/// <para>
/// Calls to this function using the system pool will block until the application acquires window focus and the user has provided a
/// biometric sample. We recommend, therefore, that your application not call <c>WinBioVerify</c> until it has acquired focus. The
/// manner in which you acquire focus depends on the type of application you are writing. For example, if you are creating a GUI
/// application you can implement a message handler that captures a WM_ACTIVATE, WM_SETFOCUS, or other appropriate message. If you
/// are writing a CUI application, call <c>GetConsoleWindow</c> to retrieve a handle to the console window and pass that handle to
/// the <c>SetForegroundWindow</c> function to force the console window into the foreground and assign it focus. If your application
/// is running in a detached process and has no window or is a Windows service, use WinBioAcquireFocus and WinBioReleaseFocus to
/// manually control focus.
/// </para>
/// <para>
/// To use <c>WinBioVerify</c> synchronously, call the function with a session handle created by calling WinBioOpenSession. The
/// function blocks until the operation completes or an error is encountered.
/// </para>
/// <para>
/// To use <c>WinBioVerify</c> asynchronously, call the function with a session handle created by calling WinBioAsyncOpenSession.
/// The framework allocates a WINBIO_ASYNC_RESULT structure and uses it to return information about operation success or failure. If
/// the operation is successful, the framework returns a <c>BOOLEAN</c> match value in a nested <c>Verify</c> structure. If the
/// operation is unsuccessful, the framework returns <c>WINBIO_REJECT_DETAIL</c> information in the <c>Verify</c> structure. The
/// <c>WINBIO_ASYNC_RESULT</c> structure is returned to the application callback or to the application message queue, depending on
/// the value you set in the NotificationMethod parameter of the <c>WinBioAsyncOpenSession</c> function:
/// </para>
/// <list type="bullet">
/// <item>
/// <term>
/// If you choose to receive completion notices by using a callback, you must implement a PWINBIO_ASYNC_COMPLETION_CALLBACK function
/// and set the NotificationMethod parameter to <c>WINBIO_ASYNC_NOTIFY_CALLBACK</c>.
/// </term>
/// </item>
/// <item>
/// <term>
/// If you choose to receive completion notices by using the application message queue, you must set the NotificationMethod
/// parameter to <c>WINBIO_ASYNC_NOTIFY_MESSAGE</c>. The framework returns a WINBIO_ASYNC_RESULT pointer to the <c>LPARAM</c> field
/// of the window message.
/// </term>
/// </item>
/// </list>
/// <para>
/// To prevent memory leaks, you must call WinBioFree to release the WINBIO_ASYNC_RESULT structure after you have finished using it.
/// </para>
/// <para>
/// <c>Windows 7:</c> You can perform this operation asynchronously by using the WinBioVerifyWithCallback function. The function
/// verifies the input arguments and returns immediately. If the input arguments are not valid, the function returns an error code.
/// Otherwise, the framework starts the operation on another thread. When the asynchronous operation completes or encounters an
/// error, the framework sends the results to the PWINBIO_VERIFY_CALLBACK function implemented by your application.
/// </para>
/// <para>Examples</para>
/// <para>
/// The following function calls <c>WinBioVerify</c> to determine whether a biometric sample matches the logged on identity of the
/// current user. The helper function GetCurrentUserIdentity is also included. Link to the Winbio.lib static library and include the
/// following header files:
/// </para>
/// <list type="bullet">
/// <item>
/// <term>Windows.h</term>
/// </item>
/// <item>
/// <term>Stdio.h</term>
/// </item>
/// <item>
/// <term>Conio.h</term>
/// </item>
/// <item>
/// <term>Winbio.h</term>
/// </item>
/// </list>
/// <para>
/// <code>HRESULT Verify(WINBIO_BIOMETRIC_SUBTYPE subFactor) { HRESULT hr = S_OK; WINBIO_SESSION_HANDLE sessionHandle = NULL; WINBIO_UNIT_ID unitId = 0; WINBIO_REJECT_DETAIL rejectDetail = 0; WINBIO_IDENTITY identity = {0}; BOOLEAN match = FALSE; // Find the identity of the user. hr = GetCurrentUserIdentity( &amp;identity ); if (FAILED(hr)) { wprintf_s(L"\n User identity not found. hr = 0x%x\n", hr); goto e_Exit; } // Connect to the system pool. hr = WinBioOpenSession( WINBIO_TYPE_FINGERPRINT, // Service provider WINBIO_POOL_SYSTEM, // Pool type WINBIO_FLAG_DEFAULT, // Configuration and access NULL, // Array of biometric unit IDs 0, // Count of biometric unit IDs NULL, // Database ID &amp;sessionHandle // [out] Session handle ); if (FAILED(hr)) { wprintf_s(L"\n WinBioOpenSession failed. hr = 0x%x\n", hr); goto e_Exit; } // Verify a biometric sample. wprintf_s(L"\n Calling WinBioVerify - Swipe finger on sensor...\n"); hr = WinBioVerify( sessionHandle, &amp;identity, subFactor, &amp;unitId, &amp;match, &amp;rejectDetail ); wprintf_s(L"\n Swipe processed - Unit ID: %d\n", unitId); if (FAILED(hr)) { if (hr == WINBIO_E_NO_MATCH) { wprintf_s(L"\n- NO MATCH - identity verification failed.\n"); } else if (hr == WINBIO_E_BAD_CAPTURE) { wprintf_s(L"\n- Bad capture; reason: %d\n", rejectDetail); } else { wprintf_s(L"\n WinBioVerify failed. hr = 0x%x\n", hr); } goto e_Exit; } wprintf_s(L"\n Fingerprint verified:\n", unitId); e_Exit: if (sessionHandle != NULL) { WinBioCloseSession(sessionHandle); sessionHandle = NULL; } wprintf_s(L"\n Press any key to exit..."); _getch(); return hr; } //------------------------------------------------------------------------ // The following function retrieves the identity of the current user. // This is a helper function and is not part of the Windows Biometric // Framework API. // HRESULT GetCurrentUserIdentity(__inout PWINBIO_IDENTITY Identity) { // Declare variables. HRESULT hr = S_OK; HANDLE tokenHandle = NULL; DWORD bytesReturned = 0; struct{ TOKEN_USER tokenUser; BYTE buffer[SECURITY_MAX_SID_SIZE]; } tokenInfoBuffer; // Zero the input identity and specify the type. ZeroMemory( Identity, sizeof(WINBIO_IDENTITY)); Identity-&gt;Type = WINBIO_ID_TYPE_NULL; // Open the access token associated with the // current process if (!OpenProcessToken( GetCurrentProcess(), // Process handle TOKEN_READ, // Read access only &amp;tokenHandle)) // Access token handle { DWORD win32Status = GetLastError(); wprintf_s(L"Cannot open token handle: %d\n", win32Status); hr = HRESULT_FROM_WIN32(win32Status); goto e_Exit; } // Zero the tokenInfoBuffer structure. ZeroMemory(&amp;tokenInfoBuffer, sizeof(tokenInfoBuffer)); // Retrieve information about the access token. In this case, // retrieve a SID. if (!GetTokenInformation( tokenHandle, // Access token handle TokenUser, // User for the token &amp;tokenInfoBuffer.tokenUser, // Buffer to fill sizeof(tokenInfoBuffer), // Size of the buffer &amp;bytesReturned)) // Size needed { DWORD win32Status = GetLastError(); wprintf_s(L"Cannot query token information: %d\n", win32Status); hr = HRESULT_FROM_WIN32(win32Status); goto e_Exit; } // Copy the SID from the tokenInfoBuffer structure to the // WINBIO_IDENTITY structure. CopySid( SECURITY_MAX_SID_SIZE, Identity-&gt;Value.AccountSid.Data, tokenInfoBuffer.tokenUser.User.Sid ); // Specify the size of the SID and assign WINBIO_ID_TYPE_SID // to the type member of the WINBIO_IDENTITY structure. Identity-&gt;Value.AccountSid.Size = GetLengthSid(tokenInfoBuffer.tokenUser.User.Sid); Identity-&gt;Type = WINBIO_ID_TYPE_SID; e_Exit: if (tokenHandle != NULL) { CloseHandle(tokenHandle); } return hr; }</code>
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winbio/nf-winbio-winbioverify HRESULT WinBioVerify( WINBIO_SESSION_HANDLE
// SessionHandle, WINBIO_IDENTITY *Identity, WINBIO_BIOMETRIC_SUBTYPE SubFactor, WINBIO_UNIT_ID *UnitId, BOOLEAN *Match,
// WINBIO_REJECT_DETAIL *RejectDetail );
[DllImport(Lib_Winbio, SetLastError = true, ExactSpelling = true)]
[PInvokeData("winbio.h", MSDNShortId = "NF:winbio.WinBioVerify")]
public static extern HRESULT WinBioVerify(WINBIO_SESSION_HANDLE SessionHandle, in WINBIO_IDENTITY Identity, WINBIO_BIOMETRIC_SUBTYPE SubFactor,
out WINBIO_UNIT_ID UnitId, [MarshalAs(UnmanagedType.U1)] out bool Match, out WINBIO_REJECT_DETAIL RejectDetail);
/// <summary>
/// <para>
/// Asynchronously captures a biometric sample and determines whether the sample corresponds to the specified user identity. The
/// function returns immediately to the caller, performs capture and verification on a separate thread, and calls into an
/// application-defined callback function to update operation status.
/// </para>
/// <para><c>Important</c>
/// <para></para>
/// We recommend that, beginning with Windows 8, you no longer use this function to start an asynchronous operation. Instead, do the following:
/// </para>
/// </summary>
/// <param name="SessionHandle">A <c>WINBIO_SESSION_HANDLE</c> value that identifies an open biometric session.</param>
/// <param name="Identity">
/// Pointer to a WINBIO_IDENTITY structure that contains the GUID or SID of the user providing the biometric sample.
/// </param>
/// <param name="SubFactor">
/// A <c>WINBIO_BIOMETRIC_SUBTYPE</c> value that specifies the sub-factor associated with the biometric sample. See the Remarks
/// section for more details.
/// </param>
/// <param name="VerifyCallback">
/// Address of a callback function that will be called by the <c>WinBioVerifyWithCallback</c> function when verification succeeds or
/// fails. You must create the callback.
/// </param>
/// <param name="VerifyCallbackContext">
/// An optional application-defined structure that is returned in the VerifyCallbackContext parameter of the callback function. This
/// structure can contain any data that the custom callback function is designed to handle.
/// </param>
/// <returns>
/// <para>
/// If the function succeeds, it returns <c>S_OK</c>. If the function fails, it returns an <c>HRESULT</c> value that indicates the
/// error. Possible values include, but are not limited to, those in the following table. For a list of common error codes, see
/// Common HRESULT Values.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>E_HANDLE</term>
/// <term>The session handle is not valid.</term>
/// </item>
/// <item>
/// <term>E_INVALIDARG</term>
/// <term>The SubFactor argument is incorrect.</term>
/// </item>
/// <item>
/// <term>E_POINTER</term>
/// <term>The pointer specified by the Identity and VerifyCallback parameters cannot be NULL.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// The SubFactor parameter specifies the sub-factor associated with the biometric sample. The Windows Biometric Framework (WBF)
/// currently supports only fingerprint capture and uses the following constants to represent sub-type information.
/// </para>
/// <list type="bullet">
/// <item>
/// <term><c>WINBIO_ANSI_381_POS_RH_THUMB</c></term>
/// </item>
/// <item>
/// <term><c>WINBIO_ANSI_381_POS_RH_INDEX_FINGER</c></term>
/// </item>
/// <item>
/// <term><c>WINBIO_ANSI_381_POS_RH_MIDDLE_FINGER</c></term>
/// </item>
/// <item>
/// <term><c>WINBIO_ANSI_381_POS_RH_RING_FINGER</c></term>
/// </item>
/// <item>
/// <term><c>WINBIO_ANSI_381_POS_RH_LITTLE_FINGER</c></term>
/// </item>
/// <item>
/// <term><c>WINBIO_ANSI_381_POS_LH_THUMB</c></term>
/// </item>
/// <item>
/// <term><c>WINBIO_ANSI_381_POS_LH_INDEX_FINGER</c></term>
/// </item>
/// <item>
/// <term><c>WINBIO_ANSI_381_POS_LH_MIDDLE_FINGER</c></term>
/// </item>
/// <item>
/// <term><c>WINBIO_ANSI_381_POS_LH_RING_FINGER</c></term>
/// </item>
/// <item>
/// <term><c>WINBIO_ANSI_381_POS_LH_LITTLE_FINGER</c></term>
/// </item>
/// <item>
/// <term><c>WINBIO_ANSI_381_POS_RH_FOUR_FINGERS</c></term>
/// </item>
/// <item>
/// <term><c>WINBIO_ANSI_381_POS_LH_FOUR_FINGERS</c></term>
/// </item>
/// </list>
/// <para>
/// The callback routine executes in the context of an arbitrary thread in the calling process. The caller is responsible for
/// synchronizing access to any memory that may be shared between the callback and other parts of the application.
/// </para>
/// <para>
/// The <c>WinBioVerifyWithCallback</c> function returns immediately and passes S_OK to the caller. To determine the status of the
/// capture and verification process, you must examine the OperationStatus parameter in your callback function.
/// </para>
/// <para>
/// You can call the WinBioCancel function to cancel a pending callback operation. Closing a session also implicitly cancels
/// callbacks for that session.
/// </para>
/// <para>The callback routine must have the following signature:</para>
/// <para>
/// <code> VOID CALLBACK VerifyCallback( __in_opt PVOID VerifyCallbackContext, __in HRESULT OperationStatus, __in WINBIO_UNIT_ID UnitId, __in BOOLEAN Match, __in WINBIO_REJECT_DETAIL RejectDetail );</code>
/// </para>
/// <para>Examples</para>
/// <para>
/// The following function calls <c>WinBioVerifyWithCallback</c> to asynchronously determine whether a biometric sample matches the
/// logged on identity of the current user. The callback routine, VerifyCallback, and a helper function, GetCurrentUserIdentity, are
/// also included. Link to the Winbio.lib static library and include the following header files:
/// </para>
/// <list type="bullet">
/// <item>
/// <term>Windows.h</term>
/// </item>
/// <item>
/// <term>Stdio.h</term>
/// </item>
/// <item>
/// <term>Conio.h</term>
/// </item>
/// <item>
/// <term>Winbio.h</term>
/// </item>
/// </list>
/// <para>
/// <code>HRESULT VerifyWithCallback(BOOL bCancel, WINBIO_BIOMETRIC_SUBTYPE subFactor) { // Declare variables. HRESULT hr = S_OK; WINBIO_SESSION_HANDLE sessionHandle = NULL; WINBIO_UNIT_ID unitId = 0; WINBIO_REJECT_DETAIL rejectDetail = 0; WINBIO_IDENTITY identity = {0}; // Find the identity of the user. hr = GetCurrentUserIdentity( &amp;identity ); if (FAILED(hr)) { wprintf_s(L"\n User identity not found. hr = 0x%x\n", hr); goto e_Exit; } // Connect to the system pool. hr = WinBioOpenSession( WINBIO_TYPE_FINGERPRINT, // Service provider WINBIO_POOL_SYSTEM, // Pool type WINBIO_FLAG_DEFAULT, // Configuration and access NULL, // Array of biometric unit IDs 0, // Count of biometric unit IDs NULL, // Database ID &amp;sessionHandle // [out] Session handle ); if (FAILED(hr)) { wprintf_s(L"\n WinBioOpenSession failed. hr = 0x%x\n", hr); goto e_Exit; } // Verify a biometric sample asynchronously. wprintf_s(L"\n Calling WinBioVerifyWithCallback.\n"); hr = WinBioVerifyWithCallback( sessionHandle, // Open session handle &amp;identity, // User SID or GUID subFactor, // Sample sub-factor VerifyCallback, // Callback function NULL // Optional context ); if (FAILED(hr)) { wprintf_s(L"\n WinBioVerifyWithCallback failed. hr = 0x%x\n", hr); goto e_Exit; } wprintf_s(L"\n Swipe the sensor ...\n"); // Cancel the identification if the bCancel flag is set. if (bCancel) { wprintf_s(L"\n Starting CANCEL timer...\n"); Sleep( 7000 ); wprintf_s(L"\n Calling WinBioCancel\n"); hr = WinBioCancel( sessionHandle ); if (FAILED(hr)) { wprintf_s(L"\n WinBioCancel failed. hr = 0x%x\n", hr); goto e_Exit; } } // Wait for the asynchronous identification process to complete // or be canceled. hr = WinBioWait( sessionHandle ); if (FAILED(hr)) { wprintf_s(L"\n WinBioWait failed. hr = 0x%x\n", hr); } e_Exit: if (sessionHandle != NULL) { WinBioCloseSession(sessionHandle); sessionHandle = NULL; } wprintf_s(L"\n Hit any key to continue..."); _getch(); return hr; } //------------------------------------------------------------------------ // The following function is the callback for WinBioVerifyWithCallback. // The function filters the response from the biometric subsystem and // writes a result to the console window. // VOID CALLBACK VerifyCallback( __in_opt PVOID VerifyCallbackContext, __in HRESULT OperationStatus, __in WINBIO_UNIT_ID UnitId, __in BOOLEAN Match, __in WINBIO_REJECT_DETAIL RejectDetail ) { UNREFERENCED_PARAMETER(VerifyCallbackContext); UNREFERENCED_PARAMETER(Match); wprintf_s(L"\n VerifyCallback executing"); wprintf_s(L"\n Swipe processed for unit ID %d\n", UnitId); // The identity could not be verified. if (FAILED(OperationStatus)) { wprintf_s(L"\n Verification failed for the following reason:"); if (OperationStatus == WINBIO_E_NO_MATCH) { wprintf_s(L"\n No match.\n"); } else if (OperationStatus == WINBIO_E_BAD_CAPTURE) { wprintf_s(L"\n Bad capture.\n "); wprintf_s(L"\n Bad capture; reason: %d\n", RejectDetail); } else { wprintf_s(L"VerifyCallback failed."); wprintf_s(L"OperationStatus = 0x%x\n", OperationStatus); } goto e_Exit; } // The user identity was verified. wprintf_s(L"\n Fingerprint verified:\n"); e_Exit: return; } //------------------------------------------------------------------------ // The following function retrieves the identity of the current user. // This is a helper function and is not part of the Windows Biometric // Framework API. // HRESULT GetCurrentUserIdentity(__inout PWINBIO_IDENTITY Identity) { // Declare variables. HRESULT hr = S_OK; HANDLE tokenHandle = NULL; DWORD bytesReturned = 0; struct{ TOKEN_USER tokenUser; BYTE buffer[SECURITY_MAX_SID_SIZE]; } tokenInfoBuffer; // Zero the input identity and specify the type. ZeroMemory( Identity, sizeof(WINBIO_IDENTITY)); Identity-&gt;Type = WINBIO_ID_TYPE_NULL; // Open the access token associated with the // current process if (!OpenProcessToken( GetCurrentProcess(), // Process handle TOKEN_READ, // Read access only &amp;tokenHandle)) // Access token handle { DWORD win32Status = GetLastError(); wprintf_s(L"Cannot open token handle: %d\n", win32Status); hr = HRESULT_FROM_WIN32(win32Status); goto e_Exit; } // Zero the tokenInfoBuffer structure. ZeroMemory(&amp;tokenInfoBuffer, sizeof(tokenInfoBuffer)); // Retrieve information about the access token. In this case, // retrieve a SID. if (!GetTokenInformation( tokenHandle, // Access token handle TokenUser, // User for the token &amp;tokenInfoBuffer.tokenUser, // Buffer to fill sizeof(tokenInfoBuffer), // Size of the buffer &amp;bytesReturned)) // Size needed { DWORD win32Status = GetLastError(); wprintf_s(L"Cannot query token information: %d\n", win32Status); hr = HRESULT_FROM_WIN32(win32Status); goto e_Exit; } // Copy the SID from the tokenInfoBuffer structure to the // WINBIO_IDENTITY structure. CopySid( SECURITY_MAX_SID_SIZE, Identity-&gt;Value.AccountSid.Data, tokenInfoBuffer.tokenUser.User.Sid ); // Specify the size of the SID and assign WINBIO_ID_TYPE_SID // to the type member of the WINBIO_IDENTITY structure. Identity-&gt;Value.AccountSid.Size = GetLengthSid(tokenInfoBuffer.tokenUser.User.Sid); Identity-&gt;Type = WINBIO_ID_TYPE_SID; e_Exit: if (tokenHandle != NULL) { CloseHandle(tokenHandle); } return hr; }</code>
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winbio/nf-winbio-winbioverifywithcallback HRESULT WinBioVerifyWithCallback(
// WINBIO_SESSION_HANDLE SessionHandle, WINBIO_IDENTITY *Identity, WINBIO_BIOMETRIC_SUBTYPE SubFactor, PWINBIO_VERIFY_CALLBACK
// VerifyCallback, PVOID VerifyCallbackContext );
[DllImport(Lib_Winbio, SetLastError = true, ExactSpelling = true)]
[PInvokeData("winbio.h", MSDNShortId = "NF:winbio.WinBioVerifyWithCallback")]
public static extern HRESULT WinBioVerifyWithCallback(WINBIO_SESSION_HANDLE SessionHandle, in WINBIO_IDENTITY Identity,
WINBIO_BIOMETRIC_SUBTYPE SubFactor, [In] PWINBIO_VERIFY_CALLBACK VerifyCallback, [In, Optional] IntPtr VerifyCallbackContext);
/// <summary>
/// Blocks caller execution until all pending biometric operations for a session have been completed or canceled. Starting with
/// Windows 10, build 1607, this function is available to use with a mobile image.
/// </summary>
/// <param name="SessionHandle">
/// A <c>WINBIO_SESSION_HANDLE</c> value that identifies an open biometric session. Open a synchronous session handle by calling
/// WinBioOpenSession. Open an asynchronous session handle by calling WinBioAsyncOpenSession.
/// </param>
/// <returns>
/// <para>
/// If the function succeeds, it returns S_OK. If the function fails, it returns an <c>HRESULT</c> value that indicates the error.
/// Possible values include, but are not limited to, those in the following table. For a list of common error codes, see Common
/// HRESULT Values.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>E_HANDLE</term>
/// <term>The session handle is not valid.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// <c>WinBioWait</c> blocks the caller's thread regardless of whether you pass a synchronous or an asynchronous session handle to
/// the SessionHandle parameter.
/// </para>
/// <para>
/// Unlike all other functions that can be called by using an asynchronous session handle, the framework does not create a
/// WINBIO_ASYNC_RESULT structure for the <c>WinBioWait</c> function.
/// </para>
/// <para>
/// Do not call <c>WinBioWait</c> from the context of a callback routine or from any function that can be called indirectly from a
/// callback routine. Doing so will cause a permanent deadlock.
/// </para>
/// <para>
/// Do not call <c>WinBioWait</c> from a window procedure. Doing so will cause the user interface to freeze until the event
/// notification arrives.
/// </para>
/// <para>
/// If you call <c>WinBioWait</c> from an asynchronous session that generates window messages, there is no guarantee of the order in
/// which the window message and the wake-from-wait message will arrive. We recommend that you not write any code that depends on
/// the order of these events.
/// </para>
/// <para>Examples</para>
/// <para>
/// The following code example shows how to call the <c>WinBioWait</c> function to block execution and wait for an asynchronous
/// thread to finish processing. Link to the Winbio.lib static library and include the following header files:
/// </para>
/// <list type="bullet">
/// <item>
/// <term>Windows.h</term>
/// </item>
/// <item>
/// <term>Stdio.h</term>
/// </item>
/// <item>
/// <term>Conio.h</term>
/// </item>
/// <item>
/// <term>Winbio.h</term>
/// </item>
/// </list>
/// <para>
/// <code>HRESULT CaptureSampleWithCallback(BOOL bCancel) { HRESULT hr = S_OK; WINBIO_SESSION_HANDLE sessionHandle = NULL; // Connect to the system pool. hr = WinBioOpenSession( WINBIO_TYPE_FINGERPRINT, // Service provider WINBIO_POOL_SYSTEM, // Pool type WINBIO_FLAG_RAW, // Raw access NULL, // Array of biometric unit IDs 0, // Count of biometric unit IDs WINBIO_DB_DEFAULT, // Default database &amp;sessionHandle // [out] Session handle ); if (FAILED(hr)) { wprintf_s(L"\n WinBioOpenSession failed. hr = 0x%x\n", hr); goto e_Exit; } // Capture a biometric sample asynchronously. wprintf_s(L"\n Calling WinBioCaptureSampleWithCallback "); hr = WinBioCaptureSampleWithCallback( sessionHandle, // Open session handle WINBIO_NO_PURPOSE_AVAILABLE, // Intended use of the sample WINBIO_DATA_FLAG_RAW, // Sample format CaptureSampleCallback, // Callback function NULL // Optional context ); if (FAILED(hr)) { wprintf_s(L"\n WinBioCaptureSampleWithCallback failed. "); wprintf_s(L"hr = 0x%x\n", hr); goto e_Exit; } wprintf_s(L"\n Swipe the sensor ...\n"); // Cancel the identification if the bCancel flag is set. if (bCancel) { wprintf_s(L"\n Starting CANCEL timer..."); Sleep( 7000 ); wprintf_s(L"\n Calling WinBioCancel\n"); hr = WinBioCancel( sessionHandle ); if (FAILED(hr)) { wprintf_s(L"\n WinBioCancel failed. hr = 0x%x\n", hr); goto e_Exit; } } // Wait for the asynchronous identification process to complete // or be canceled. hr = WinBioWait( sessionHandle ); if (FAILED(hr)) { wprintf_s(L"\n WinBioWait failed. hr = 0x%x\n", hr); } e_Exit: if (sessionHandle != NULL) { WinBioCloseSession(sessionHandle); sessionHandle = NULL; } wprintf_s(L"\n Press any key to exit..."); _getch(); return hr; } //------------------------------------------------------------------------ // The following function is the callback for WinBioCaptureSampleWithCallback. // The function filters the response from the biometric subsystem and // writes a result to the console window. // VOID CALLBACK CaptureSampleCallback( __in_opt PVOID CaptureCallbackContext, __in HRESULT OperationStatus, __in WINBIO_UNIT_ID UnitId, __in_bcount(SampleSize) PWINBIO_BIR Sample, __in SIZE_T SampleSize, __in WINBIO_REJECT_DETAIL RejectDetail ) { UNREFERENCED_PARAMETER(CaptureCallbackContext); wprintf_s(L"\n CaptureSampleCallback executing"); wprintf_s(L"\n Swipe processed - Unit ID: %d", UnitId); if (FAILED(OperationStatus)) { if (OperationStatus == WINBIO_E_BAD_CAPTURE) { wprintf_s(L"\n Bad capture; reason: %d\n", RejectDetail); } else { wprintf_s(L"\n WinBioCaptureSampleWithCallback failed. "); wprintf_s(L" OperationStatus = 0x%x\n", OperationStatus); } goto e_Exit; } wprintf_s(L"\n Captured %d bytes.\n", SampleSize); e_Exit: if (Sample != NULL) { WinBioFree(Sample); Sample = NULL; } }</code>
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winbio/nf-winbio-winbiowait HRESULT WinBioWait( WINBIO_SESSION_HANDLE
// SessionHandle );
[DllImport(Lib_Winbio, SetLastError = false, ExactSpelling = true)]
[PInvokeData("winbio.h", MSDNShortId = "NF:winbio.WinBioWait")]
public static extern HRESULT WinBioWait(WINBIO_SESSION_HANDLE SessionHandle);
private static HRESULT GetEnum<T>(EnumFunc f, WINBIO_BIOMETRIC_TYPE Factor, out T[] array)
{
var ret = f(Factor, out var a, out var c);
array = ret.Succeeded ? a.DangerousGetHandle().ToArray<T>(c) : null;
return ret;
}
/// <summary>The <c>WINBIO_ASYNC_RESULT</c> structure contains the results of an asynchronous operation.</summary>
/// <remarks>
/// <para>
/// Asynchronous operations are begun by opening a biometric session or a framework session. Call WinBioAsyncOpenSession to open a
/// biometric session. Call WinBioAsyncOpenFramework to open a framework session.
/// </para>
/// <para>You can use an asynchronous biometric session handle to call any of the following operations asynchronously:</para>
/// <list type="bullet">
/// <item>
/// <term>WinBioCancel</term>
/// </item>
/// <item>
/// <term>WinBioCaptureSample</term>
/// </item>
/// <item>
/// <term>WinBioCloseSession</term>
/// </item>
/// <item>
/// <term>WinBioControlUnit</term>
/// </item>
/// <item>
/// <term>WinBioControlUnitPrivileged</term>
/// </item>
/// <item>
/// <term>WinBioDeleteTemplate</term>
/// </item>
/// <item>
/// <term>WinBioEnrollBegin</term>
/// </item>
/// <item>
/// <term>WinBioEnrollCapture</term>
/// </item>
/// <item>
/// <term>WinBioEnrollCommit</term>
/// </item>
/// <item>
/// <term>WinBioEnrollDiscard</term>
/// </item>
/// <item>
/// <term>WinBioEnumEnrollments</term>
/// </item>
/// <item>
/// <term>WinBioGetProperty</term>
/// </item>
/// <item>
/// <term>WinBioIdentify</term>
/// </item>
/// <item>
/// <term>WinBioLocateSensor</term>
/// </item>
/// <item>
/// <term>WinBioLockUnit</term>
/// </item>
/// <item>
/// <term>WinBioLogonIdentifiedUser</term>
/// </item>
/// <item>
/// <term>WinBioRegisterEventMonitor</term>
/// </item>
/// <item>
/// <term>WinBioUnlockUnit</term>
/// </item>
/// <item>
/// <term>WinBioUnregisterEventMonitor</term>
/// </item>
/// <item>
/// <term>WinBioVerify</term>
/// </item>
/// <item>
/// <term>WinBioWait</term>
/// </item>
/// <item>
/// <term>WinBioSetProperty</term>
/// </item>
/// <item>
/// <term>WinBioEnrollSelect</term>
/// </item>
/// <item>
/// <term>WinBioMonitorPresence</term>
/// </item>
/// </list>
/// <para>You can use an asynchronous framework handle to call the following operations asynchronously:</para>
/// <list type="bullet">
/// <item>
/// <term>WinBioAsyncEnumBiometricUnits</term>
/// </item>
/// <item>
/// <term>WinBioAsyncEnumDatabases</term>
/// </item>
/// <item>
/// <term>WinBioAsyncOpenFramework</term>
/// </item>
/// <item>
/// <term>WinBioAsyncEnumServiceProviders</term>
/// </item>
/// <item>
/// <term>WinBioAsyncMonitorFrameworkChanges</term>
/// </item>
/// </list>
/// <para>
/// The <c>WINBIO_ASYNC_RESULT</c> structure is allocated internally by the Windows Biometric Framework. Therefore, when you are
/// through using it, call WinBioFree to release the allocated memory and avoid leaks. Because this also releases all nested data
/// structures, you should not keep a copy of any pointers returned in the <c>WINBIO_ASYNC_RESULT</c> structure. If you want to save
/// any data returned in a nested structure, make a private copy of that data before calling <c>WinBioFree</c>.
/// </para>
/// <para>
/// <c>Windows 8, Windows Server 2012, Windows 8.1 and Windows Server 2012 R2:</c> The Windows Biometric Framework supports only
/// fingerprint readers. Therefore, if an operation fails and returns additional information in a <c>WINBIO_REJECT_DETAIL</c>
/// constant, it will be one of the following values:
/// </para>
/// <list type="bullet">
/// <item>
/// <term>WINBIO_FP_TOO_HIGH</term>
/// </item>
/// <item>
/// <term>WINBIO_FP_TOO_LOW</term>
/// </item>
/// <item>
/// <term>WINBIO_FP_TOO_LEFT</term>
/// </item>
/// <item>
/// <term>WINBIO_FP_TOO_RIGHT</term>
/// </item>
/// <item>
/// <term>WINBIO_FP_TOO_FAST</term>
/// </item>
/// <item>
/// <term>WINBIO_FP_TOO_SLOW</term>
/// </item>
/// <item>
/// <term>WINBIO_FP_POOR_QUALITY</term>
/// </item>
/// <item>
/// <term>WINBIO_FP_TOO_SKEWED</term>
/// </item>
/// <item>
/// <term>WINBIO_FP_TOO_SHORT</term>
/// </item>
/// <item>
/// <term>WINBIO_FP_MERGE_FAILURE</term>
/// </item>
/// </list>
/// <para>Further, if an operation uses a <c>WINBIO_BIOMETRIC_SUBTYPE</c> data type, it will be one of the following values:</para>
/// <list type="bullet">
/// <item>
/// <term>WINBIO_ANSI_381_POS_UNKNOWN</term>
/// </item>
/// <item>
/// <term>WINBIO_ANSI_381_POS_RH_THUMB</term>
/// </item>
/// <item>
/// <term>WINBIO_ANSI_381_POS_RH_INDEX_FINGER</term>
/// </item>
/// <item>
/// <term>WINBIO_ANSI_381_POS_RH_MIDDLE_FINGER</term>
/// </item>
/// <item>
/// <term>WINBIO_ANSI_381_POS_RH_RING_FINGER</term>
/// </item>
/// <item>
/// <term>WINBIO_ANSI_381_POS_RH_LITTLE_FINGER</term>
/// </item>
/// <item>
/// <term>WINBIO_ANSI_381_POS_LH_THUMB</term>
/// </item>
/// <item>
/// <term>WINBIO_ANSI_381_POS_LH_INDEX_FINGER</term>
/// </item>
/// <item>
/// <term>WINBIO_ANSI_381_POS_LH_MIDDLE_FINGER</term>
/// </item>
/// <item>
/// <term>WINBIO_ANSI_381_POS_LH_RING_FINGER</term>
/// </item>
/// <item>
/// <term>WINBIO_ANSI_381_POS_LH_LITTLE_FINGER</term>
/// </item>
/// <item>
/// <term>WINBIO_ANSI_381_POS_RH_FOUR_FINGERS</term>
/// </item>
/// <item>
/// <term>WINBIO_ANSI_381_POS_LH_FOUR_FINGERS</term>
/// </item>
/// <item>
/// <term>WINBIO_ANSI_381_POS_TWO_THUMBS</term>
/// </item>
/// </list>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winbio/ns-winbio-winbio_async_result typedef struct _WINBIO_ASYNC_RESULT {
// WINBIO_SESSION_HANDLE SessionHandle; WINBIO_OPERATION_TYPE Operation; ULONGLONG SequenceNumber; LONGLONG TimeStamp; HRESULT
// ApiStatus; WINBIO_UNIT_ID UnitId; PVOID UserData; union { struct { BOOLEAN Match; WINBIO_REJECT_DETAIL RejectDetail; } Verify;
// struct { WINBIO_IDENTITY Identity; WINBIO_BIOMETRIC_SUBTYPE SubFactor; WINBIO_REJECT_DETAIL RejectDetail; } Identify; struct {
// WINBIO_BIOMETRIC_SUBTYPE SubFactor; } EnrollBegin; struct { WINBIO_REJECT_DETAIL RejectDetail; } EnrollCapture; struct {
// WINBIO_IDENTITY Identity; BOOLEAN IsNewTemplate; } EnrollCommit; struct { WINBIO_IDENTITY Identity; SIZE_T SubFactorCount;
// WINBIO_BIOMETRIC_SUBTYPE *SubFactorArray; } EnumEnrollments; struct { PWINBIO_BIR Sample; SIZE_T SampleSize; WINBIO_REJECT_DETAIL
// RejectDetail; } CaptureSample; struct { WINBIO_IDENTITY Identity; WINBIO_BIOMETRIC_SUBTYPE SubFactor; } DeleteTemplate; struct {
// WINBIO_PROPERTY_TYPE PropertyType; WINBIO_PROPERTY_ID PropertyId; WINBIO_IDENTITY Identity; WINBIO_BIOMETRIC_SUBTYPE SubFactor;
// SIZE_T PropertyBufferSize; PVOID PropertyBuffer; } GetProperty; struct { WINBIO_PROPERTY_TYPE PropertyType; WINBIO_PROPERTY_ID
// PropertyId; WINBIO_IDENTITY Identity; WINBIO_BIOMETRIC_SUBTYPE SubFactor; SIZE_T PropertyBufferSize; PVOID PropertyBuffer; }
// SetProperty; struct { WINBIO_EVENT Event; } GetEvent; struct { WINBIO_COMPONENT Component; ULONG ControlCode; ULONG
// OperationStatus; PUCHAR SendBuffer; SIZE_T SendBufferSize; PUCHAR ReceiveBuffer; SIZE_T ReceiveBufferSize; SIZE_T
// ReceiveDataSize; } ControlUnit; struct { SIZE_T BspCount; WINBIO_BSP_SCHEMA *BspSchemaArray; } EnumServiceProviders; struct {
// SIZE_T UnitCount; WINBIO_UNIT_SCHEMA *UnitSchemaArray; } EnumBiometricUnits; struct { SIZE_T StorageCount; WINBIO_STORAGE_SCHEMA
// *StorageSchemaArray; } EnumDatabases; struct { BOOLEAN Match; WINBIO_REJECT_DETAIL RejectDetail; WINBIO_PROTECTION_TICKET Ticket;
// } VerifyAndReleaseTicket; struct { WINBIO_IDENTITY Identity; WINBIO_BIOMETRIC_SUBTYPE SubFactor; WINBIO_REJECT_DETAIL
// RejectDetail; WINBIO_PROTECTION_TICKET Ticket; } IdentifyAndReleaseTicket; struct { ULONGLONG SelectorValue; } EnrollSelect;
// struct { WINBIO_PRESENCE_CHANGE ChangeType; SIZE_T PresenceCount; WINBIO_PRESENCE *PresenceArray; } MonitorPresence; struct {
// WINBIO_IDENTITY Identity; WINBIO_PROTECTION_POLICY Policy; } GetProtectionPolicy; struct { WINBIO_EXTENDED_UNIT_STATUS
// ExtendedStatus; } NotifyUnitStatusChange; } Parameters; } WINBIO_ASYNC_RESULT, *PWINBIO_ASYNC_RESULT;
[PInvokeData("winbio.h", MSDNShortId = "NS:winbio._WINBIO_ASYNC_RESULT")]
[StructLayout(LayoutKind.Sequential, Pack = 4)]
public struct WINBIO_ASYNC_RESULT
{
/// <summary>
/// Handle of an asynchronous session started by calling the WinBioAsyncOpenSession function or the WinBioAsyncOpenFramework function.
/// </summary>
public uint SessionHandle;
/// <summary>Type of the asynchronous operation. For more information, see WINBIO_OPERATION_TYPE Constants.</summary>
public WINBIO_OPERATION_TYPE Operation;
/// <summary>
/// Sequence number of the asynchronous operation. The integers are assigned sequentially for each operation in a biometric
/// session, starting at one (1). For any session, the open operation is always assigned the first sequence number and the close
/// operation is assigned the last sequence number. If your application queues multiple operations, you can use sequence numbers
/// to perform error handling. For example, you can ignore operation results until a specific sequence number is sent to the application.
/// </summary>
public ulong SequenceNumber;
/// <summary>
/// System date and time at which the biometric operation began. For more information, see the <c>GetSystemTimeAsFileTime</c> function.
/// </summary>
public long TimeStamp;
/// <summary>Error code returned by the operation.</summary>
public HRESULT ApiStatus;
/// <summary>The numeric unit identifier of the biometric unit that performed the operation.</summary>
public uint UnitId;
/// <summary>
/// Address of an optional buffer supplied by the caller. The buffer is not modified by the framework or the biometric unit.
/// Your application can use the data to help it determine what actions to perform upon receipt of the completion notice or to
/// maintain additional information about the requested operation.
/// </summary>
public IntPtr UserData;
private readonly uint pad1;
/// <summary>
/// Union that encloses nested structures that contain additional information about the success or failure of asynchronous
/// operations begun by the client application.
/// </summary>
public PARAMETERS Parameters;
/// <summary>
/// Union that encloses nested structures that contain additional information about the success or failure of asynchronous
/// operations begun by the client application.
/// </summary>
[StructLayout(LayoutKind.Explicit)]
public struct PARAMETERS
{
/// <summary>Contains the results of an asynchronous call to WinBioVerify.</summary>
[FieldOffset(0)]
public VERIFY Verify;
/// <summary>Contains the results of an asynchronous call to WinBioVerify.</summary>
[StructLayout(LayoutKind.Sequential, Pack = 4)]
public struct VERIFY
{
/// <summary>Specifies whether the captured sample matched the user identity.</summary>
[MarshalAs(UnmanagedType.U1)]
public bool Match;
/// <summary>Additional information about verification failure. For more information, see Remarks.</summary>
public WINBIO_REJECT_DETAIL RejectDetail;
}
/// <summary>Contains the results of an asynchronous call to WinBioIdentify.</summary>
[FieldOffset(0)]
public IDENTIFY Identify;
/// <summary>Contains the results of an asynchronous call to WinBioIdentify.</summary>
[StructLayout(LayoutKind.Sequential, Pack = 4)]
public struct IDENTIFY
{
/// <summary>GUID or SID of the user providing the biometric sample.</summary>
public WINBIO_IDENTITY Identity;
/// <summary>Sub-factor associated with the biometric sample. For more information, see Remarks.</summary>
public WINBIO_BIOMETRIC_SUBTYPE SubFactor;
/// <summary>
/// Additional information about the failure, if any, to capture and identify a biometric sample. For more information,
/// see Remarks.
/// </summary>
public WINBIO_REJECT_DETAIL RejectDetail;
}
/// <summary>Contains the results of an asynchronous call to WinBioEnrollBegin.</summary>
[FieldOffset(0)]
public ENROLLBEGIN EnrollBegin;
/// <summary>Contains the results of an asynchronous call to WinBioEnrollBegin.</summary>
[StructLayout(LayoutKind.Sequential)]
public struct ENROLLBEGIN
{
/// <summary>Additional information about the enrollment. For more information, see Remarks.</summary>
public WINBIO_BIOMETRIC_SUBTYPE SubFactor;
}
/// <summary>Contains the results of an asynchronous call to WinBioEnrollCapture.</summary>
[FieldOffset(0)]
public ENROLLCAPTURE EnrollCapture;
/// <summary>Contains the results of an asynchronous call to WinBioEnrollCapture.</summary>
[StructLayout(LayoutKind.Sequential)]
public struct ENROLLCAPTURE
{
/// <summary>Additional information about the failure to capture a biometric sample. For more information, see Remarks.</summary>
public WINBIO_REJECT_DETAIL RejectDetail;
}
/// <summary>Contains the results of an asynchronous call to WinBioEnrollCommit.</summary>
[FieldOffset(0)]
public ENROLLCOMMIT EnrollCommit;
/// <summary>Contains the results of an asynchronous call to WinBioEnrollCommit.</summary>
[StructLayout(LayoutKind.Sequential)]
public struct ENROLLCOMMIT
{
/// <summary>GUID or SID of the template to be saved.</summary>
public WINBIO_IDENTITY Identity;
/// <summary>Specifies whether the template being added to the database is new.</summary>
[MarshalAs(UnmanagedType.U1)]
public bool IsNewTemplate;
}
/// <summary>Contains the results of an asynchronous call to WinBioEnumEnrollments.</summary>
[FieldOffset(0)]
public ENUMENROLLMENTS EnumEnrollments;
/// <summary>Contains the results of an asynchronous call to WinBioEnumEnrollments.</summary>
[StructLayout(LayoutKind.Sequential)]
public struct ENUMENROLLMENTS
{
/// <summary>GUID or SID of the template from which the sub-factors were retrieved.</summary>
public WINBIO_IDENTITY Identity;
/// <summary>Number of elements in the array pointed to by the <c>SubFactorArray</c> member.</summary>
public SizeT SubFactorCount;
/// <summary>Pointer to an array of sub-factors. For more information, see Remarks.</summary>
public IntPtr _SubFactorArray;
/// <summary>Pointer to an array of sub-factors. For more information, see Remarks.</summary>
public WINBIO_BIOMETRIC_SUBTYPE[] SubFactorArray => _SubFactorArray.ToArray<WINBIO_BIOMETRIC_SUBTYPE>(SubFactorCount);
}
/// <summary>Contains the results of an asynchronous call to WinBioCaptureSample.</summary>
[FieldOffset(0)]
public CAPTURESAMPLE CaptureSample;
/// <summary>Contains the results of an asynchronous call to WinBioCaptureSample.</summary>
[StructLayout(LayoutKind.Sequential)]
public struct CAPTURESAMPLE
{
/// <summary>Pointer to a WINBIO_BIR structure that contains the sample.</summary>
public IntPtr Sample;
/// <summary>Size, in bytes, of the WINBIO_BIR structure returned in the <c>Sample</c> member.</summary>
public SizeT SampleSize;
/// <summary>Additional information about the failure to capture a biometric sample. For more information, see Remarks.</summary>
public WINBIO_REJECT_DETAIL RejectDetail;
}
/// <summary>Contains the results of an asynchronous call to WinBioDeleteTemplate.</summary>
[FieldOffset(0)]
public DELETETEMPLATE DeleteTemplate;
/// <summary>Contains the results of an asynchronous call to WinBioDeleteTemplate.</summary>
[StructLayout(LayoutKind.Sequential)]
public struct DELETETEMPLATE
{
/// <summary>GUID or SID of the template that was deleted.</summary>
public WINBIO_IDENTITY Identity;
/// <summary>Additional information about the template.</summary>
public WINBIO_BIOMETRIC_SUBTYPE SubFactor;
}
/// <summary>Contains the results of an asynchronous call to WinBioGetProperty.</summary>
[FieldOffset(0)]
public GETPROPERTY GetProperty;
/// <summary>Contains the results of an asynchronous call to WinBioGetProperty.</summary>
[StructLayout(LayoutKind.Sequential)]
public struct GETPROPERTY
{
/// <summary>Source of the property information. Currently this will be <c>WINBIO_PROPERTY_TYPE_UNIT</c>.</summary>
public WINBIO_PROPERTY_TYPE PropertyType;
/// <summary>The property that was queried. Currently this will be <c>WINBIO_PROPERTY_SAMPLE_HINT</c>.</summary>
public WINBIO_PROPERTY_ID PropertyId;
/// <summary>This is a reserved value and will be <c>NULL</c>.</summary>
public WINBIO_IDENTITY Identity;
/// <summary>This is reserved and will be <c>WINBIO_SUBTYPE_NO_INFORMATION</c>.</summary>
public WINBIO_BIOMETRIC_SUBTYPE SubFactor;
/// <summary>Size, in bytes, of the property value pointed to by the <c>PropertyBuffer</c> member.</summary>
public SizeT PropertyBufferSize;
/// <summary>Pointer to the property value.</summary>
public IntPtr PropertyBuffer;
}
/// <summary>
/// <para>
/// Contains the results of an asynchronous call to WinBioSetProperty. This member is supported starting in Windows 10.
/// </para>
/// <para>SetProperty.PropretyBufferSize</para>
/// <para>The size, in bytes, of the structure to which the PropertyBuffer parameter points.</para>
/// </summary>
[FieldOffset(0)]
public SETPROPERTY SetProperty;
/// <summary>
/// <para>
/// Contains the results of an asynchronous call to WinBioSetProperty. This member is supported starting in Windows 10.
/// </para>
/// <para>SetProperty.PropretyBufferSize</para>
/// <para>The size, in bytes, of the structure to which the PropertyBuffer parameter points.</para>
/// </summary>
[StructLayout(LayoutKind.Sequential)]
public struct SETPROPERTY
{
/// <summary>
/// A <c>WINBIO_PROPERTY_TYPE</c> value that specifies the type of the property that was set. Currently this can only be <c>WINBIO_PROPERTY_TYPE_ACCOUNT</c>.
/// </summary>
public WINBIO_PROPERTY_TYPE PropertyType;
/// <summary>
/// A <c>WINBIO_PROPERTY_ID</c> value that specifies the property that was set. Currently this value can only be
/// <c>WINBIO_PROPERTY_ANTI_SPOOF_POLICY</c>. All other properties are read-only.
/// </summary>
public WINBIO_PROPERTY_ID PropertyId;
/// <summary>A WINBIO_IDENTITY structure that specifies the account for which the property was set.</summary>
public WINBIO_IDENTITY Identity;
/// <summary>Reserved. Currently, this value will always be <c>WINBIO_SUBTYPE_NO_INFORMATION</c>.</summary>
public WINBIO_BIOMETRIC_SUBTYPE SubFactor;
/// <summary/>
public SizeT PropertyBufferSize;
/// <summary>
/// A pointer to a structure that specifies the value to which the property was set. For the
/// <c>WINBIO_PROPERTY_ANTI_SPOOF_POLICY</c> property, the structure is a WINBIO_ANTI_SPOOF_POLICY structure.
/// </summary>
public IntPtr PropertyBuffer;
}
/// <summary>Contains status information about the event that was raised.</summary>
[FieldOffset(0)]
public GETEVENT GetEvent;
/// <summary>Contains status information about the event that was raised.</summary>
[StructLayout(LayoutKind.Sequential)]
public struct GETEVENT
{
/// <summary>Contains event information.</summary>
public WINBIO_EVENT Event;
}
/// <summary>Contains the results of an asynchronous call to WinBioControlUnit or WinBioControlUnitPrivileged.</summary>
[FieldOffset(0)]
public CONTROLUNIT ControlUnit;
/// <summary>Contains the results of an asynchronous call to WinBioControlUnit or WinBioControlUnitPrivileged.</summary>
[StructLayout(LayoutKind.Sequential)]
public struct CONTROLUNIT
{
/// <summary>The component within the biometric unit that performed the operation.</summary>
public WINBIO_COMPONENT Component;
/// <summary>
/// Vendor-defined code recognized by the biometric unit specified by the UnitId parameter of the WinBioControlUnit or
/// WinBioControlUnitPrivileged function and the adapter specified by the Component parameter.
/// </summary>
public uint ControlCode;
/// <summary>Vendor-defined status code that specifies the outcome of the control operation.</summary>
public uint OperationStatus;
/// <summary>
/// Pointer to a buffer that contains the control information sent to the adapter by the component. The format and
/// content of the buffer is vendor-defined.
/// </summary>
public IntPtr SendBuffer;
/// <summary>Size, in bytes, of the buffer specified by the <c>SendBuffer</c> member.</summary>
public SizeT SendBufferSize;
/// <summary>
/// Pointer to a buffer that receives information sent by the adapter specified by the <c>Component</c> member. The
/// format and content of the buffer is vendor-defined.
/// </summary>
public IntPtr ReceiveBuffer;
/// <summary>Size, in bytes, of the buffer specified by the <c>ReceiveBuffer</c> member.</summary>
public SizeT ReceiveBufferSize;
/// <summary>Size, in bytes, of the data written to the buffer specified by the <c>ReceiveBuffer</c> member.</summary>
public SizeT ReceiveDataSize;
}
/// <summary>Contains the results of an asynchronous call to WinBioEnumServiceProviders or WinBioAsyncEnumServiceProviders.</summary>
[FieldOffset(0)]
public ENUMSERVICEPROVIDERS EnumServiceProviders;
/// <summary>Contains the results of an asynchronous call to WinBioEnumServiceProviders or WinBioAsyncEnumServiceProviders.</summary>
[StructLayout(LayoutKind.Sequential)]
public struct ENUMSERVICEPROVIDERS
{
/// <summary>The number of structures pointed to by the <c>BspSchemaArray</c> member.</summary>
public SizeT BspCount;
/// <summary>
/// Pointer to an array of WINBIO_BSP_SCHEMA structures that contain information about each of the available service providers.
/// </summary>
public IntPtr _BspSchemaArray;
/// <summary>
/// An array of WINBIO_BSP_SCHEMA structures that contain information about each of the available service providers.
/// </summary>
public WINBIO_BSP_SCHEMA[] BspSchemaArray => _BspSchemaArray.ToArray<WINBIO_BSP_SCHEMA>(BspCount);
}
/// <summary>Contains the results of an asynchronous call to WinBioEnumBiometricUnits or WinBioAsyncEnumBiometricUnits.</summary>
[FieldOffset(0)]
public ENUMBIOMETRICUNITS EnumBiometricUnits;
/// <summary>Contains the results of an asynchronous call to WinBioEnumBiometricUnits or WinBioAsyncEnumBiometricUnits.</summary>
[StructLayout(LayoutKind.Sequential)]
public struct ENUMBIOMETRICUNITS
{
/// <summary>Number of structures pointed to by the <c>UnitSchemaArray</c> member.</summary>
public SizeT UnitCount;
/// <summary>An array of WINBIO_UNIT_SCHEMA structures that contain information about each enumerated biometric unit.</summary>
public IntPtr _UnitSchemaArray;
/// <summary>An array of WINBIO_UNIT_SCHEMA structures that contain information about each enumerated biometric unit.</summary>
public WINBIO_UNIT_SCHEMA[] UnitSchemaArray => _UnitSchemaArray.ToArray<WINBIO_UNIT_SCHEMA>(UnitCount);
}
/// <summary>Contains the results of an asynchronous call to WinBioEnumDatabases or WinBioAsyncEnumDatabases.</summary>
[FieldOffset(0)]
public ENUMDATABASES EnumDatabases;
/// <summary>Contains the results of an asynchronous call to WinBioEnumDatabases or WinBioAsyncEnumDatabases.</summary>
[StructLayout(LayoutKind.Sequential)]
public struct ENUMDATABASES
{
/// <summary>Number of structures pointed to by the <c>StorageSchemaArray</c> member.</summary>
public SizeT StorageCount;
/// <summary>Array of WINBIO_STORAGE_SCHEMA structures that contain information about each database.</summary>
public IntPtr _StorageSchemaArray;
/// <summary>Array of WINBIO_STORAGE_SCHEMA structures that contain information about each database.</summary>
public WINBIO_STORAGE_SCHEMA[] StorageSchemaArray => _StorageSchemaArray.ToArray<WINBIO_STORAGE_SCHEMA>(StorageCount);
}
/// <summary>Reserved. This member is supported starting in Windows 10.</summary>
[FieldOffset(0)]
public VERIFYANDRELEASETICKET VerifyAndReleaseTicket;
/// <summary>Reserved. This member is supported starting in Windows 10.</summary>
[StructLayout(LayoutKind.Sequential)]
public struct VERIFYANDRELEASETICKET
{
/// <summary>Reserved.</summary>
[MarshalAs(UnmanagedType.U1)]
public bool Match;
/// <summary>Reserved.</summary>
public WINBIO_REJECT_DETAIL RejectDetail;
/// <summary>Reserved.</summary>
public ulong Ticket;
}
/// <summary>Reserved. This member is supported starting in Windows 10.</summary>
[FieldOffset(0)]
public IDENTIFYANDRELEASETICKET IdentifyAndReleaseTicket;
/// <summary>Reserved. This member is supported starting in Windows 10.</summary>
[StructLayout(LayoutKind.Sequential)]
public struct IDENTIFYANDRELEASETICKET
{
/// <summary>Reserved.</summary>
public WINBIO_IDENTITY Identity;
/// <summary>Reserved.</summary>
public WINBIO_BIOMETRIC_SUBTYPE SubFactor;
/// <summary>Reserved.</summary>
public WINBIO_REJECT_DETAIL RejectDetail;
/// <summary>Reserved.</summary>
public ulong Ticket;
}
/// <summary>
/// Contains the results of an asynchronous call to WinBioEnrollSelect. This member is supported starting in Windows 10.
/// </summary>
[FieldOffset(0)]
public ENROLLSELECT EnrollSelect;
/// <summary>
/// Contains the results of an asynchronous call to WinBioEnrollSelect. This member is supported starting in Windows 10.
/// </summary>
[StructLayout(LayoutKind.Sequential)]
public struct ENROLLSELECT
{
/// <summary>A value that identifies that individual that was selected for enrollment.</summary>
public ulong SelectorValue;
}
/// <summary>
/// Contains the results of an asynchronous call to WinBioMonitorPresence. This member is supported starting in Windows 10.
/// </summary>
[FieldOffset(0)]
public MONITORPRESENCE MonitorPresence;
/// <summary>
/// Contains the results of an asynchronous call to WinBioMonitorPresence. This member is supported starting in Windows 10.
/// </summary>
[StructLayout(LayoutKind.Sequential)]
public struct MONITORPRESENCE
{
/// <summary>A <c>WINBIO_PRESENCE_CHANGE</c> value that indicates the type of event that occurred.</summary>
public WINBIO_PRESENCE_CHANGE ChangeType;
/// <summary>The size of the array that the <c>MonitorPresence.PresenceArray</c> member points to.</summary>
public SizeT PresenceCount;
/// <summary>Address of the array of WINBIO_PRESENCE structures, one for each individual monitored.</summary>
public IntPtr _PresenceArray;
/// <summary>Address of the array of WINBIO_PRESENCE structures, one for each individual monitored.</summary>
public WINBIO_PRESENCE[] PresenceArray => _PresenceArray.ToArray<WINBIO_PRESENCE>(PresenceCount);
}
/// <summary/>
[FieldOffset(0)]
public GETPROTECTIONPOLICY GetProtectionPolicy;
/// <summary/>
[StructLayout(LayoutKind.Sequential)]
public struct GETPROTECTIONPOLICY
{
/// <summary/>
public WINBIO_IDENTITY Identity;
/// <summary/>
public WINBIO_PROTECTION_POLICY Policy;
}
/// <summary/>
[FieldOffset(0)]
public NOTIFYUNITSTATUSCHANGE NotifyUnitStatusChange;
/// <summary/>
[StructLayout(LayoutKind.Sequential)]
public struct NOTIFYUNITSTATUSCHANGE
{
/// <summary/>
public WINBIO_EXTENDED_UNIT_STATUS ExtendedStatus;
}
}
}
/// <summary>An unsigned long integer that contains the handle for an open framework session.</summary>
[PInvokeData("winbio.h")]
[DebuggerDisplay("{value}")]
[StructLayout(LayoutKind.Sequential, Size = 4)]
public struct WINBIO_FRAMEWORK_HANDLE
{
private readonly uint value;
/// <summary>Performs an implicit conversion from <see cref="WINBIO_FRAMEWORK_HANDLE"/> to <see cref="System.UInt32"/>.</summary>
/// <param name="handle">The handle.</param>
/// <returns>The resulting <see cref="System.UInt32"/> instance from the conversion.</returns>
public static implicit operator uint(WINBIO_FRAMEWORK_HANDLE handle) => handle.value;
}
/// <summary>An unsigned long integer that contains the handle for an open biometric session.</summary>
[PInvokeData("winbio.h")]
[DebuggerDisplay("{value}")]
[StructLayout(LayoutKind.Sequential, Size = 4)]
public struct WINBIO_SESSION_HANDLE
{
private readonly uint value;
/// <summary>Performs an implicit conversion from <see cref="WINBIO_SESSION_HANDLE"/> to <see cref="System.UInt32"/>.</summary>
/// <param name="handle">The handle.</param>
/// <returns>The resulting <see cref="System.UInt32"/> instance from the conversion.</returns>
public static implicit operator uint(WINBIO_SESSION_HANDLE handle) => handle.value;
}
/// <summary>A safe handle for memory allocated by WinBio methods and freed using <see cref="WinBioFree"/>.</summary>
/// <seealso cref="SafeHANDLE"/>
public class SafeWinBioMemory : SafeHANDLE
{
private SafeWinBioMemory() : base(IntPtr.Zero, true) { }
/// <summary>Performs an implicit conversion from <see cref="SafeWinBioMemory"/> to <see cref="IntPtr"/>.</summary>
/// <param name="m">The <see cref="SafeWinBioMemory"/> instance.</param>
/// <returns>The resulting <see cref="IntPtr"/> instance from the conversion.</returns>
public static implicit operator IntPtr(SafeWinBioMemory m) => m.DangerousGetHandle();
/// <summary>
/// Marshals data from an unmanaged block of memory to a newly allocated managed object of the type specified by a generic type parameter.
/// </summary>
/// <typeparam name="T">The type of the object to which the data is to be copied. This must be a structure.</typeparam>
/// <param name="allocatedBytes">If known, the total number of bytes allocated to the native memory in this handle.</param>
/// <param name="offset">The number of bytes to skip before reading the element.</param>
/// <returns>A managed object that contains the data pointed to by this safe handle.</returns>
public T ToStructure<T>(SizeT allocatedBytes, uint offset = 0) where T : struct => handle.ToStructure<T>(allocatedBytes, (int)offset);
/// <summary>
/// Internal method that actually releases the handle. This is called by <see cref="M:Vanara.PInvoke.SafeHANDLE.ReleaseHandle"/>
/// for valid handles and afterwards zeros the handle.
/// </summary>
/// <returns><c>true</c> to indicate successful release of the handle; <c>false</c> otherwise.</returns>
protected override bool InternalReleaseHandle() => WinBioFree(handle).Succeeded;
}
/// <summary>A structure handler based on unmanaged memory allocated by AllocCoTaskMem.</summary>
/// <typeparam name="TStruct">The type of the structure.</typeparam>
/// <seealso cref="SafeMemStruct{TStruct, TMem}"/>
public class SafeWinBioStruct<TStruct> : SafeMemStruct<TStruct, WinBioMemoryMethods> where TStruct : struct
{
/// <summary>Represents the <see langword="null"/> equivalent of this class instances.</summary>
public static readonly SafeWinBioStruct<TStruct> Null = new SafeWinBioStruct<TStruct>(IntPtr.Zero, false);
/// <summary>Initializes a new instance of the <see cref="SafeWinBioStruct{TStruct}"/> class.</summary>
/// <param name="s">The TStruct value.</param>
/// <param name="capacity">The capacity of the buffer, in bytes.</param>
public SafeWinBioStruct(in TStruct s, SizeT capacity = default) : base(s, capacity) { }
/// <summary>Initializes a new instance of the <see cref="SafeWinBioStruct{TStruct}"/> class.</summary>
/// <param name="capacity">The capacity of the buffer, in bytes.</param>
public SafeWinBioStruct(SizeT capacity = default) : base(capacity) { }
/// <summary>Initializes a new instance of the <see cref="SafeWinBioStruct{TStruct}"/> class.</summary>
/// <param name="ptr">The PTR.</param>
/// <param name="ownsHandle"><c>true</c> to reliably release the handle during finalization; <c>false</c> to prevent it.</param>
/// <param name="allocatedBytes">The number of bytes allocated to <paramref name="ptr"/>.</param>
[System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
public SafeWinBioStruct(IntPtr ptr, bool ownsHandle = true, SizeT allocatedBytes = default) : base(ptr, ownsHandle, allocatedBytes) { }
/// <summary>Performs an implicit conversion from <see cref="Nullable{TStruct}"/> to <see cref="SafeCoTaskMemStruct{TStruct}"/>.</summary>
/// <param name="s">The value of the <typeparamref name="TStruct"/> instance or <see langword="null"/>.</param>
/// <returns>The resulting <see cref="SafeWinBioStruct{TStruct}"/> instance from the conversion.</returns>
public static implicit operator SafeWinBioStruct<TStruct>(TStruct? s) => s.HasValue ? new SafeWinBioStruct<TStruct>(s.Value) : new SafeWinBioStruct<TStruct>(IntPtr.Zero);
}
/// <summary>Internal use only.</summary>
/// <seealso cref="MemoryMethodsBase"/>
public sealed class WinBioMemoryMethods : MemoryMethodsBase
{
/// <summary>Gets a handle to a memory allocation of the specified size.</summary>
/// <param name="size">The size, in bytes, of memory to allocate.</param>
/// <returns>A memory handle.</returns>
/// <exception cref="NotImplementedException"></exception>
public override IntPtr AllocMem(int size) => throw new NotImplementedException();
/// <summary>Frees the memory associated with a handle.</summary>
/// <param name="hMem">A memory handle.</param>
public override void FreeMem(IntPtr hMem) => WinBioFree(hMem);
}
}
}