An Interest In:
Web News this Week
- March 22, 2024
- March 21, 2024
- March 20, 2024
- March 19, 2024
- March 18, 2024
- March 17, 2024
- March 16, 2024
April 18, 2022 05:01 am GMT
Original Link: https://dev.to/medsaid2001/morphotop-library-3057
Morphotop Library
A while ago, I got my hands on the executable file of the morphotop. The morphotop is a fingerprint reader that can read all of the fingerprints in your hand. After playing with it for a while, I managed to build a C++ library that can communicate with the device.
#include "BDS_Common.h"#include "BDS_OS.h"#include "BDS_Interface_XCS.h";#include <iostream>extern "C" __declspec(dllexport) int LoadLib(TCHAR *file, void ** o_pp_handle){ HINSTANCE h_lib = LoadLibrary(file); *o_pp_handle = NULL; if(h_lib == NULL) return ERROR_LOADLIBRARY; *o_pp_handle = h_lib; return 0;}extern "C" __declspec(dllexport) int GProcAddress(void * i_p_handle,char * i_pc_method, void ** o_pp_procaddress) { void * l_p_proc; l_p_proc = GetProcAddress((HINSTANCE)i_p_handle,i_pc_method); if(l_p_proc == NULL) return ERROR_GETPROCADDRESS; *o_pp_procaddress = l_p_proc; return 0;}extern "C" __declspec(dllexport) int resolveInterface (TCHAR * i_pc_fullpath, int i_i_dllType, interfaceFunction ** o_p_interfaceTable, int * o_i_interfaceTable_count, int * o_i_dllVersion) { void * l_p_handle = 0; int l_i_result; int l_i_dllType; void * l_pf_getInterface; l_i_result = LoadLib(i_pc_fullpath,&l_p_handle); if(l_i_result == 0) { l_i_result = GProcAddress(l_p_handle,"getInterface", &l_pf_getInterface); if(l_i_result == 0) { l_i_result = ((pf_getInterface)l_pf_getInterface) (&l_i_dllType, o_i_dllVersion, o_p_interfaceTable, o_i_interfaceTable_count); if (i_i_dllType != l_i_dllType) { return ERROR_DLL_TYPE; } } }; return l_i_result;}extern "C" __declspec(dllexport) int EnumerateUsableBiometricDevices (void * l_p_handle, int * const o_p_deviceCount) { int l_i_result; void * l_pf_getInterface; l_i_result = GProcAddress(l_p_handle,"BDS_EnumerateUsableBiometricDevices", &l_pf_getInterface); if(l_i_result == 0) { l_i_result = ((pf_BDS_EnumerateUsableBiometricDevices)l_pf_getInterface) (o_p_deviceCount); } return l_i_result;}extern "C" __declspec(dllexport) int OpenBioDevice (void * l_p_handle, const int i_i_deviceIndex, int * o_p_deviceHandle, void * const i_p_userData) { int l_i_result; void * l_pf_getInterface; l_i_result = GProcAddress(l_p_handle,"BDS_OpenBiometricDevice", &l_pf_getInterface); if(l_i_result == 0) { l_i_result = ((pf_BDS_OpenBiometricDevice)l_pf_getInterface) (i_i_deviceIndex,o_p_deviceHandle,i_p_userData); } return l_i_result;}extern "C" __declspec(dllexport) int CloseBioDevice (void * l_p_handle, const int i_i_deviceHandle) { int l_i_result; void * l_pf_getInterface; l_i_result = GProcAddress(l_p_handle,"BDS_CloseBiometricDevice", &l_pf_getInterface); if(l_i_result == 0) { l_i_result = ((pf_BDS_CloseBiometricDevice)l_pf_getInterface) (i_i_deviceHandle); } return l_i_result;}extern "C" __declspec(dllexport) int SetDetectionMode (void * l_p_handle, const int i_i_deviceHandle, const int i_i_detectionMode, const int i_i_fingerNumber) { int l_i_result; void * l_pf_getInterface; l_i_result = GProcAddress(l_p_handle,"BDS_SetParametersForDetectionMode", &l_pf_getInterface); if(l_i_result == 0) { l_i_result = ((pf_BDS_SetParametersForDetectionMode)l_pf_getInterface) (i_i_deviceHandle, i_i_detectionMode, i_i_fingerNumber); } return l_i_result;}extern "C" __declspec(dllexport) int GetDetectedImage (void * l_p_handle, const int i_i_deviceHandle, const unsigned long i_l_timeout, BDS_Image * const o_p_outputImage, BDS_DetectionResults * const o_p_results) { int l_i_result; void * l_pf_getInterface; l_i_result = GProcAddress(l_p_handle,"BDS_GetDetectedImage", &l_pf_getInterface); if(l_i_result == 0) { l_i_result = ((pf_BDS_GetDetectedImage)l_pf_getInterface) (i_i_deviceHandle, i_l_timeout, o_p_outputImage,o_p_results); } return l_i_result;}extern "C" __declspec(dllexport) BDS_Image * BDS_GetDirectImage (void * l_p_handle,const int i_i_deviceHandle,const unsigned long i_l_timeout ,BDS_Image * o_p_outputImage) { int l_i_result; //o_p_outputImage=(BDS_Image*) new BDS_Image(); BDS_Image * o_p_outputImage2=(BDS_Image *) new BDS_Image(); void * l_pf_getInterface; l_i_result = GProcAddress(l_p_handle,"BDS_GetDirectImage", &l_pf_getInterface); if(l_i_result == 0) { l_i_result = ((pf_BDS_GetDirectImage)l_pf_getInterface) (i_i_deviceHandle, i_l_timeout, o_p_outputImage2); } return o_p_outputImage2; }extern "C" __declspec(dllexport) int BDS_SetParametersForDirectMode (void * l_p_handle,const int i_i_deviceHandle,const int i_i_samplingMode) { int l_i_result; void * l_pf_getInterface; l_i_result = GProcAddress(l_p_handle,"BDS_SetParametersForDirectMode", &l_pf_getInterface); if(l_i_result == 0) { l_i_result = ((pf_BDS_SetParametersForDirectMode)l_pf_getInterface) (i_i_deviceHandle,i_i_samplingMode ); } return l_i_result;}extern "C" __declspec(dllexport) int AutoTest (void * l_p_handle,const int i_i_deviceIndex, const BDS_TestParameters * const i_p_testParameters, BDS_TestResults * const o_p_testResults) { int l_i_result; void * l_pf_getInterface; l_i_result = GProcAddress(l_p_handle,"BDS_Autotest", &l_pf_getInterface); if(l_i_result == 0) { l_i_result = ((pf_BDS_Autotest)l_pf_getInterface) (i_i_deviceIndex, i_p_testParameters, o_p_testResults); } return l_i_result;}extern "C" __declspec(dllexport) int BDS_SetParametersForLiveMode (void * l_p_handle,const int i_i_deviceHandle,const int i_i_samplingMode) { int l_i_result; void * l_pf_getInterface; l_i_result = GProcAddress(l_p_handle,"BDS_SetParametersForLiveMode", &l_pf_getInterface); if(l_i_result == 0) { l_i_result = ((pf_BDS_SetParametersForLiveMode)l_pf_getInterface) (i_i_deviceHandle, i_i_samplingMode); } return l_i_result;}int ApplicationCallback(const int i_i_deviceHandle,BDS_Image * const i_p_currentImage,const unsigned char * const i_p_inputData, unsigned char * const o_p_outputData,void * const o_p_userData){ return 0; }extern "C" __declspec(dllexport) int BDS_DefineLiveProcess (void * l_p_handle, const int i_i_deviceHandle,BDS_Callback c) { int l_i_result; void * l_pf_getInterface=(void*)new int(20); //o_p_outputImage2=ApplicationCallback; l_i_result = GProcAddress(l_p_handle,"BDS_DefineLiveProcess", &l_pf_getInterface); std::cout<<l_i_result; if(l_i_result == 0) { l_i_result = ((pf_BDS_DefineLiveProcess)l_pf_getInterface) (0, c); } //free(l_pf_getInterface); return l_i_result;}extern "C" __declspec(dllexport) int BDS_GetBiometricDeviceDescriptor (void * l_p_handle,const int i_i_deviceIndex,char * pointer){ int l_i_result; BDS_DeviceDescriptor * o_p_deviceDescriptor =NULL; void * l_pf_getInterface; l_i_result = GProcAddress(l_p_handle,"BDS_GetBiometricDeviceDescriptor", &l_pf_getInterface); if(l_i_result == 0) { l_i_result = ((pf_BDS_GetBiometricDeviceDescriptor)l_pf_getInterface) (i_i_deviceIndex, o_p_deviceDescriptor); pointer =o_p_deviceDescriptor->m_deviceSerial; } return l_i_result;}
This code is outdated and I am sharing it in hopes that someone can benefit from it.
a also biult a c# wrapper that use the c++ library
using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using System.Drawing;using System.Drawing.Imaging;using System.IO;using System.Linq;using System.Runtime.InteropServices;using System.Text;using System.Threading;using System.Threading.Tasks;using System.Windows.Forms;namespace Morphotop{ public unsafe partial class Form1 : Form { public Form1() { InitializeComponent(); //BDS_Callback callback = Callback; } [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)] public struct BDS_Image { public unsafe uint m_magic; public unsafe uint m_version; public unsafe uint m_width; public unsafe uint m_height; public unsafe uint m_flags; public IntPtr m_image; public unsafe uint m_count; public unsafe uint m_checksum; public unsafe fixed byte m_rfu[25]; } [UnmanagedFunctionPointer(CallingConvention.Cdecl)] public unsafe delegate int BDS_Callback(IntPtr i_i_deviceHandle, BDS_Image* i_p_currentImage, IntPtr i_p_inputData, IntPtr o_p_outputData, IntPtr i_p_userData); public unsafe int CallbackPointer(IntPtr i_i_deviceHandle, BDS_Image* i_p_currentImage, IntPtr i_p_inputData, IntPtr o_p_outputData, IntPtr i_p_userData) { try { uint size = i_p_currentImage->m_width * i_p_currentImage->m_height; byte[] data = new byte[size]; byte[] height = new byte[i_p_currentImage->m_height]; byte[] width = new byte[i_p_currentImage->m_width]; IntPtr pointer = Marshal.AllocHGlobal(data.Length); Marshal.Copy(i_p_currentImage->m_image, data, 0, data.Length); Marshal.FreeHGlobal(pointer); SetPicture(pictureBox1, ConvertToBitmap(data, width.Length, height.Length)); } catch { } return 0; } private void SetPicture(PictureBox img, Bitmap bmp) { try { if (img.InvokeRequired) { img.Invoke(new MethodInvoker( delegate() { pictureBox1.Image = bmp; })); } else { pictureBox1.Image = bmp; } } catch { } } public void Initialize() { // int res5 = OpenBioDevice(i_p_handle, 0, out device_handle, user_data); } private void Capture_Click(object sender, EventArgs e) { int p = BDS_SetParametersForDirectMode(i_p_handle, 1); BDS_Image* resdet = BDS_GetDirectImage(i_p_handle, 0, 5000); uint size = resdet->m_width * resdet->m_height; byte[] data = new byte[size]; byte[] height = new byte[resdet->m_height]; byte[] width = new byte[resdet->m_width]; if (data.Length != null) { IntPtr pointer = Marshal.AllocHGlobal(data.Length); try { Marshal.Copy(resdet->m_image, data, 0, data.Length); Marshal.FreeHGlobal(pointer); File.WriteAllBytes("test",data); Bitmap bmp =ConvertToBitmap(data, width.Length, height.Length); bmp.Save(Directory.GetCurrentDirectory()+"\est.jpg"); pictureBox2.Image = bmp; } catch { } } } private Bitmap ConvertToBitmap(byte[] image_data,int width,int height) { try { int Width = width; int Height = height; var b = new Bitmap(Width, Height, PixelFormat.Format8bppIndexed); ColorPalette ncp = b.Palette; for (int i = 0; i < 256; i++) ncp.Entries[i] = Color.FromArgb(255, i, i, i); b.Palette = ncp; var BoundsRect = new Rectangle(0, 0, Width, Height); BitmapData bmpData = b.LockBits(BoundsRect, ImageLockMode.WriteOnly, b.PixelFormat); IntPtr ptr = bmpData.Scan0; int bytes = width * b.Height; var rgbValues = new byte[bytes]; Marshal.Copy(image_data, 0, ptr, bytes); b.UnlockBits(bmpData); return b; } catch { return null; } } private void Form1_Load(object sender, EventArgs e) { Initialize(textBox1); } private IntPtr i_p_handle; public void Initialize(TextBox result) { i_p_handle = IntPtr.Zero; IntPtr o_pp_procaddress = IntPtr.Zero; IntPtr o_p_interfaceTable = IntPtr.Zero; IntPtr o_i_interfaceTable_count = IntPtr.Zero; IntPtr o_i_dllVersion = IntPtr.Zero; IntPtr o_p_deviceCount = IntPtr.Zero; IntPtr device_handle = IntPtr.Zero; IntPtr img2 = IntPtr.Zero; IntPtr r = IntPtr.Zero; int user_data = 300; int re = 0; result.AppendText("Loading Library......." + Environment.NewLine); re = LoadLib(Directory.GetCurrentDirectory() + "\\SDKServices.dll", out i_p_handle); if (re == 0) { result.AppendText("Library Loaded No ERRORS" + Environment.NewLine); result.AppendText("Resolving interface" + Environment.NewLine); re = resolveInterface(Directory.GetCurrentDirectory() + "\\SDKServices.dll", o_pp_procaddress, out o_p_interfaceTable, out o_i_interfaceTable_count, out o_i_dllVersion); if (re == 0) { result.AppendText("Interface resolved" + Environment.NewLine); result.AppendText("Enumerating devices" + Environment.NewLine); re = EnumerateUsableBiometricDevices(i_p_handle, out o_p_deviceCount); OpenBioDevice(i_p_handle,0,out r,user_data); SetupLiveMode(0,i_p_handle); if (re == 0) { result.ForeColor = Color.Black; result.AppendText("device enumerated" + Environment.NewLine); } else { result.AppendText("device could not be enumerated" + Environment.NewLine); } } else { result.AppendText("Interface could not be resolved" + Environment.NewLine); } } else { result.ForeColor = Color.Black; result.AppendText("could not load library" + Environment.NewLine); } } public void OpenDevice(TextBox result, IntPtr i_p_handle, IntPtr o_p_deviceHandle, int i_p_userData) { int resu = OpenBioDevice(i_p_handle, 0, out o_p_deviceHandle, i_p_userData); if (resu == 0) { result.AppendText("Biometric Device Opened" + Environment.NewLine); } else { result.AppendText("Could not open Biometric device" + Environment.NewLine); } } public void CloseDevice(TextBox result, IntPtr i_p_handle, int o_p_deviceHandle) { int resu = CloseBioDevice(i_p_handle, o_p_deviceHandle); if (resu == 0) { result.ForeColor = Color.Black; result.AppendText("Biometric Device Closed" + Environment.NewLine); } else { result.ForeColor = Color.Red; result.AppendText("Could not close Biometric device" + Environment.NewLine); } } public BDS_Callback callback1; public void SetupLiveMode(int SamplingMode, IntPtr i_p_handle) { callback1 = new BDS_Callback(CallbackPointer); int res = BDS_DefineLiveProcess(i_p_handle, SamplingMode, callback1); } [DllImport("SSB.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode)] public extern static int LoadLib(String path, out IntPtr i_p_handle); [DllImport("SSB.dll", CallingConvention = CallingConvention.Cdecl)] public extern static int GProcAddress(IntPtr i_p_handle, string i_pc_method, out IntPtr o_pp_procaddress); [DllImport("SSB.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode)] public extern static int resolveInterface(String path, IntPtr i_i_dllType, out IntPtr o_p_interfaceTable, out IntPtr o_i_interfaceTable_count, out IntPtr o_i_dllVersion); [DllImport("SSB.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode)] public extern static int EnumerateUsableBiometricDevices(IntPtr path, out IntPtr o_p_deviceCount); [DllImport("SSB.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode)] public extern static int OpenBioDevice(IntPtr path, int i_i_deviceIndex, out IntPtr o_p_deviceHandle, int i_p_userData); [DllImport("SSB.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode)] public extern static int CloseBioDevice(IntPtr path, int i_i_deviceHandle); [DllImport("SSB.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode)] public extern static int SetDetectionMode(IntPtr path, IntPtr i_i_deviceHandle, int i_i_detectionMode, int i_i_fingerNumber); [DllImport("SSB.dll", CallingConvention = CallingConvention.Cdecl)] public extern unsafe static BDS_Image* BDS_GetDirectImage(IntPtr path, int i_i_deviceHandle, ulong i_l_timeout); [DllImport("SSB.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode)] public extern static int BDS_SetParametersForDirectMode(IntPtr hadle, int sample); [DllImport("SSB.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode)] public extern static int BDS_SetParametersForDirectMode(IntPtr path, IntPtr i_i_deviceHandle, int i_i_samplingMode); [DllImport("SSB.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode)] public extern static int BDS_DefineLiveProcess(IntPtr l_p_handle, int a, BDS_Callback c); [DllImport("SSB.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode)] public extern static int BDS_DefineLiveProcess(int l_p_handle, BDS_Callback bds); private void Close_Click(object sender, EventArgs e) { CloseDevice(textBox1, i_p_handle, 0); } IEnumerable<Rectangle> FindImageTiles(Bitmap compositeImage) { var result = new List<Rectangle>(); // Scan for a non-empty region that hasn't already been "captured" for (var x = 0; x < compositeImage.Width; x++) { for (var y = 0; y < compositeImage.Height; y++) { // Only process the pixel if we don't have a rectangle that // already contains this and if it's not empty if (!result.Any(r => r.Contains(x, y)) && compositeImage.GetPixel(x, y).A != 0) { // Now that we've found a point, create a rectangle // surrounding that point, then expand outward until // we have a bounding rectangle that doesn't intersect // with the tile var rect = new Rectangle(x - 1, y - 1, 2, 2); bool foundBounds = false; while (!foundBounds) { var xRange = Enumerable.Range(rect.Left, rect.Right) .Where(px => px >= 0 && px < compositeImage.Width); var yRange = Enumerable.Range(rect.Top, rect.Bottom) .Where(py => py >= 0 && py < compositeImage.Height); // Adjust the top if (rect.Top >= 0 && xRange .Select(bx => compositeImage.GetPixel(bx, rect.Top)) .Any(p => p.A != 0)) { rect.Y--; rect.Height++; } else if (rect.Bottom < compositeImage.Height && xRange .Select(bx => compositeImage.GetPixel(bx, rect.Bottom)) .Any(p => p.A != 0)) { rect.Height++; } else if (rect.Left >= 0 && yRange .Select(by => compositeImage.GetPixel(rect.Left, by)) .Any(p => p.A != 0)) { rect.X--; rect.Width++; } else if (rect.Right < compositeImage.Width && yRange .Select(by => compositeImage.GetPixel(rect.Right, by)) .Any(p => p.A != 0)) { rect.Width++; } else { foundBounds = true; } } result.Add(rect); } } } return result; } private void button1_Click(object sender, EventArgs e) { IEnumerable<Rectangle> rec = FindImageTiles((Bitmap)pictureBox2.Image); Image img = pictureBox2.Image; Graphics newGraphics = Graphics.FromImage(img); foreach(Rectangle r in rec){ newGraphics.DrawRectangle(new Pen(Color.Black, 2), r); } } }}
you can find the entire project in here https://github.com/medsaid2001/morphotop-library
Original Link: https://dev.to/medsaid2001/morphotop-library-3057
Share this article:
Tweet
View Full Article
Dev To
An online community for sharing and discovering great ideas, having debates, and making friendsMore About this Source Visit Dev To