Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / desktop / Win32

FingerPrintf: A Small Library for Quick Usage of the Biometric API, Fingerprint and Camera

4.86/5 (22 votes)
18 Jun 2023CPOL2 min read 33.9K   703  
Use your sensors for identification and verification
The article explains the usage of fingerprint, camera and more biometric methods.

Introduction

The biometric API is a bit confusing. Why not have a single class that allows you to use it?
This demo allows an application to use any of the available biometric sensors.

fingerprintf.hpp is all you need to include in your own projects. The repo includes a ready-to-use solution.

Using the Fingerprint Reader with the System Database

C++
FINGERPRINTF fp;

// Enumerate all
fp.Enun();

// Pick the fingerprint
for (size_t i = 0 ; i < fp.GetUnits().size() ; i++)
{
    auto& u = fp.GetUnits()[i];
    if (u.BiometricFactor == WINBIO_TYPE_FINGERPRINT)
    {
         fp.SetType(u.BiometricFactor);
         fp.Open(i);
         break;
    }
}

This opens the fingerprint reader with the system database (the fingerprints already enrolled in Windows Settings).

To have the user touch the device:

C++
WINBIO_UNIT_ID u = 0; 
auto hr = fp.Locate(u); // Accepts a WINBIO_UNIT_ID& and, on success, 
                        // returns the ID of the device touched.

To perform the identification:

C++
AddMessage( L"Please swipe your finger");
auto ide = fp.Identify(Unit);
if (FAILED(std::get<0>(ide)))
    {
    auto str = ConvertRejectDetailToString(std::get<1>(ide));
    }
else
    {
    LastID = std::get<3>(ide);
    LastSub = std::get<2>(ide);
    auto str = displayIdentity(&std::get<3>(ide), std::get<2>(ide));
    }

If successful, you get a WINBIO_IDENTITY structure which, in this case, has a SID.

To verify a fingerprint against a known one, for example, the last identification:

C++
auto e = fp.Verify(LastID, LastSub);
if (FAILED(std::get<0>(e)))
    {
    auto str = ConvertRejectDetailToString(std::get<1>(e));
    }
else
    {
    // OK
    }
}

Using the Library in Async Mode

C++
fp.SetAsync(1);

This time, when you call fp.Open(), you pass a HWND and a message to be posted when something occurs. This message contains a WINBIO_ASYNC_RESULT as the lParam which you can test for return values.

Using a Private Database

If you want, you can install a private database. Files are stored in C:\windows\system32\WinBioDatabase and you must register the database as administrator:

C++
fp.Register(Unit);

With the index of the unit you want to register. This also restarts the Windows Biometric Service so the database is visible. You can use the Unregister() method to remove the registration.

To enroll fingerprints to that private database:

C++
UCHAR s = 0;
if (LW == 230)
    s = WINBIO_ANSI_381_POS_RH_THUMB;
if (LW == 231)
    s = WINBIO_ANSI_381_POS_RH_INDEX_FINGER;
if (LW == 232)
    s = WINBIO_ANSI_381_POS_RH_MIDDLE_FINGER;
if (LW == 233)
    s = WINBIO_ANSI_381_POS_RH_RING_FINGER;
if (LW == 234)
    s = WINBIO_ANSI_381_POS_RH_LITTLE_FINGER;
if (LW == 235)
    s = WINBIO_ANSI_381_POS_LH_THUMB;
if (LW == 236)
    s = WINBIO_ANSI_381_POS_LH_INDEX_FINGER;
if (LW == 237)
    s = WINBIO_ANSI_381_POS_LH_MIDDLE_FINGER;
if (LW == 238)
    s = WINBIO_ANSI_381_POS_LH_RING_FINGER;
if (LW == 239)
    s = WINBIO_ANSI_381_POS_LH_LITTLE_FINGER;

auto cb = [](SIZE_T, HRESULT hrt, WINBIO_REJECT_DETAIL) -> HRESULT
    {
    if (FAILED(hrt))
        return hrt;
    if (SUCCEEDED(hr))
        AddMessage(L"Sample captured");
    if (hrt == WINBIO_I_MORE_DATA)
        AddMessage( L"More data required. Please reswipe");
    return hrt;
    };

AddMessage( L"Please swipe your finger");
auto enr = fp.Enroll(false,s,Unit,cb);
if (fp.IsAsync())
    return 0;
if (FAILED(std::get<0>(enr)))
    {
    AddMessage( L"Enroll failed");
    auto str = ConvertRejectDetailToString(std::get<1>(enr));
    AddMessage( str);
    }
else
    {
    AddMessage( L"Enroll completed");
    auto str = displayIdentity(&std::get<3>(enr),s);
    LastID = std::get<3>(enr);
    LastSub = s;
    AddMessage( str.c_str());
    }

Using the camera

The documentation says that only fingerprint is supported, but camera works too. Opening the library with WINBIO_TYPE_FACIAL_FEATURES automatically sets async mode and can only be used with the system database (you can't create a database yourself). After opening the device, WinBioMonitorPresence is automatically called by the library.

You must have a Windows-hello compatible webcam.

The camera posts WINBIO_ASYNC_RESULT structures that contain a WINBIO_OPERATION_MONITOR_PRESENCE structure of WINBIO_PRESENCE. This structure has info from the camera. When the ChangeType is WINBIO_PRESENCE_CHANGE_TYPE_RECOGNIZE, then you have an array with the SID.

No other functions (Identify, Verify, Enroll, etc.) can be called on the camera.

Using Other Sensors

In my system, there is a "voice" biometric sensor, but I can't use it yet. Stay connected!

History

  • 19th June, 2023: Enhanced the library, added the facial stuff
  • 3rd January, 2018: Added option to use system database
  • 21st November, 2016: First release

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)