JcBernack / WinBioNET

Managed wrapper in C#/NET for the Windows Biometric Framework
MIT License
58 stars 14 forks source link

Retrieve fingerprint from device #12

Open owenashurst opened 6 years ago

owenashurst commented 6 years ago

I'm curious as to how I can retrieve the scanned image from the device. Is this implemented? If it's scanned and retrieved as a byte array, that would be fine. @JcBernack

JcBernack commented 6 years ago

This is not currently implemented in this library, but should be possible. See the TODO note on CaptureSample here: https://github.com/JcBernack/WinBioNET/blob/750e6dc8e248e9b441877a374589d44299a735cf/WinBioNET/WinBio.cs#L112

The data at pointer should somehow contain the image. Here is some C-code where the image is retrieved, maybe that will help you: https://github.com/djbozkosz/Windows-Biometric-Framework-FingerPrint-Example/blob/master/FingerPrint/main.cpp#L176

If you get it working in C# I would be happy to accept a pull request 😉

owenashurst commented 6 years ago

Ah, I've been staring at this all day, glad I'm on the right track!

I've come across a thread on the MSDN forums which might give us a clue on how it's done too which references the code you linked: https://social.msdn.microsoft.com/Forums/en-US/f6f09403-e0b6-4977-b697-d5aabeb5b8ff/how-to-convert-winbiobir-data-into-image-using-windows-biometric-framework?forum=wdk

I think this is beyond my level, but I am playing around with it in LINQPad.

Can you explain to me what this does right after that comment, please?

Free(pointer);

I'm not familiar with externs hehe.

owenashurst commented 6 years ago

It seems like every time I try and call CaptureSample I get AccessDenied -

WinBioCaptureSample failed: AccessDenied

WinBioRejectDetail rejectDetail;

WinBio.CaptureSample(_session, WinBioBirPurpose.NoPurposeAvailable, WinBioBirDataFlags.Raw, out int sampleSize, out rejectDetail);

Not entirely sure if I'm calling it right. Any pointers? (excuse the pun)

JcBernack commented 6 years ago

Free(pointer) frees the pointer. (excuse me) The Windows Biometric Framework is an unmanaged C library, that means you have to manually clean up memory allocated by the framework.

As to why you get AccessDenied: Did you check the documentation? https://msdn.microsoft.com/en-us/library/windows/desktop/dd401603(v=vs.85).aspx E_ACCESSDENIED: The caller does not have permission to capture raw samples, or the session was not opened by using the WINBIO_FLAG_RAW flag. You probably need higher privileges to capture raw samples. Try running your program as an administrator.

owenashurst commented 6 years ago

Thanks for you reply.

Thanks for the explanation. I've also tried running the program as an administrator however I'm still getting the same issue.

Judging by what you quoted from the documentation "or the session was not opened by using the WINBIO_FLAG_RAW flag"

Does the method call seem right to you - what I posted earlier?

Also, I came across this that might help, scroll down to "Remarks": https://msdn.microsoft.com/en-us/library/windows/desktop/dd401603(v=vs.85).aspx

JcBernack commented 6 years ago

You didn't show how you opened the session, only your call to CaptureSample. Check the link in my first response for the arguments you need both on OpenSession and CaptureSample, if it still doesn't work I'm out of ideas..

owenashurst commented 6 years ago

I'm opening the session the same way in the sample project...

private void OpenBiometricSession()
{
     _session = WinBio.OpenSession(WinBioBiometricType.Fingerprint, WinBioPoolType.Private, WinBioSessionFlag.Basic, new[] { unit.UnitId }, DatabaseId);

    Console.WriteLine( "Session opened: " + _session.Value);
}

So to sum it up, my main method looks something like this;

void Main()
{
    unit = WinBio.EnumBiometricUnits(WinBioBiometricType.Fingerprint).First();

    InitialStart();

    WinBioRejectDetail rejectDetail;
    int sampleSize;
    WinBio.CaptureSample(_session, WinBioBirPurpose.NoPurposeAvailable, WinBioBirDataFlags.Privacy, out sampleSize, out rejectDetail).Dump();

    rejectDetail.Dump();
    sampleSize.Dump();

    WinBio.CloseSession( _session );
}

If you're not familiar with LINQPad, ".Dump()" dumps the object to a "results" window so you can see what is being returned graphically.