├── Readme.md ├── WinBioNET ├── Enums │ ├── WinBioBiometricType.cs │ ├── WinBioDatabaseId.cs │ ├── WinBioSensorSubType.cs │ ├── WinBioSettingSourceType.cs │ ├── WinBioSensorMode.cs │ ├── WinBioBirDataFlags.cs │ ├── WinBioBirPurpose.cs │ ├── WinBioPoolType.cs │ ├── WinBioCapabilitySensor.cs │ ├── WinBioRejectDetail.cs │ ├── WinBioBiometricSubType.cs │ ├── WinBioIdentityType.cs │ ├── WinBioSessionFlag.cs │ ├── WinBioDatabaseFlag.cs │ └── WinBioErrorCode.cs ├── WinBioBirData.cs ├── WinBioRegisteredFormat.cs ├── App.config ├── WinBioBir.cs ├── WinBioVersion.cs ├── LargeInteger.cs ├── WinBioBdbAnsi381Record.cs ├── Configuration │ ├── WinBioSensorKey.cs │ ├── WinBioDatabaseKey.cs │ └── WinBioRegistryKeyBase.cs ├── WinBioBspSchema.cs ├── Unused │ ├── WinBioResource.cs │ ├── WinBioDatabase.cs │ ├── WinBioObject.cs │ ├── WinBioUnit.cs │ └── WinBioSession.cs ├── WinBioStorageSchema.cs ├── WinBioBirHeader.cs ├── WinBioBdbAnsi381Header.cs ├── WinBioSessionHandle.cs ├── WinBioUnitSchema.cs ├── WinBioException.cs ├── Properties │ └── AssemblyInfo.cs ├── WinBioIdentity.cs ├── WinBioNET.csproj ├── WinBioConfiguration.cs └── WinBio.cs ├── ConsoleTest ├── App.config ├── Properties │ └── AssemblyInfo.cs ├── ConsoleTest.csproj └── Program.cs ├── WindowsFormsTest ├── App.config ├── Program.cs ├── Properties │ └── AssemblyInfo.cs ├── WindowsFormsTest.csproj ├── WinBioForm.resx ├── WinBioForm.Designer.cs └── WinBioForm.cs ├── .gitignore ├── LICENSE.txt ├── ApiInformation.txt ├── .gitattributes └── WinBioNET.sln /Readme.md: -------------------------------------------------------------------------------- 1 | # WinBioNET 2 | Managed wrapper in C#/NET for the Windows Biometric Framework. -------------------------------------------------------------------------------- /WinBioNET/Enums/WinBioBiometricType.cs: -------------------------------------------------------------------------------- 1 | namespace WinBioNET.Enums 2 | { 3 | public enum WinBioBiometricType 4 | { 5 | Fingerprint = 8 6 | } 7 | } -------------------------------------------------------------------------------- /WinBioNET/WinBioBirData.cs: -------------------------------------------------------------------------------- 1 | namespace WinBioNET 2 | { 3 | public struct WinBioBirData 4 | { 5 | public int Size; 6 | public int Offset; 7 | } 8 | } -------------------------------------------------------------------------------- /WinBioNET/WinBioRegisteredFormat.cs: -------------------------------------------------------------------------------- 1 | namespace WinBioNET 2 | { 3 | public struct WinBioRegisteredFormat 4 | { 5 | public ushort Owner; 6 | public ushort Type; 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /WinBioNET/Enums/WinBioDatabaseId.cs: -------------------------------------------------------------------------------- 1 | namespace WinBioNET.Enums 2 | { 3 | public enum WinBioDatabaseId 4 | { 5 | Default = 1, 6 | Bootstrap = 2, 7 | OnChip = 3 8 | } 9 | } -------------------------------------------------------------------------------- /WinBioNET/Enums/WinBioSensorSubType.cs: -------------------------------------------------------------------------------- 1 | namespace WinBioNET.Enums 2 | { 3 | public enum WinBioSensorSubType 4 | { 5 | Unknown = 0, 6 | FpSwipe = 1, 7 | FpTouch = 2 8 | } 9 | } -------------------------------------------------------------------------------- /ConsoleTest/App.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /WinBioNET/App.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /WindowsFormsTest/App.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /WinBioNET/Enums/WinBioSettingSourceType.cs: -------------------------------------------------------------------------------- 1 | namespace WinBioNET.Enums 2 | { 3 | public enum WinBioSettingSourceType 4 | { 5 | Invalid = 0, 6 | Default = 1, 7 | Policy = 2, 8 | Local = 3 9 | } 10 | } -------------------------------------------------------------------------------- /WinBioNET/Enums/WinBioSensorMode.cs: -------------------------------------------------------------------------------- 1 | namespace WinBioNET.Enums 2 | { 3 | public enum WinBioSensorMode 4 | { 5 | Unknown = 0, 6 | Basic = 1, 7 | Advanced = 2, 8 | Navigation = 3, 9 | Sleep = 4 10 | } 11 | } -------------------------------------------------------------------------------- /WinBioNET/WinBioBir.cs: -------------------------------------------------------------------------------- 1 | namespace WinBioNET 2 | { 3 | public struct WinBioBir 4 | { 5 | public WinBioBirData HeaderBlock; 6 | public WinBioBirData StandardDataBlock; 7 | public WinBioBirData VendorDataBlock; 8 | public WinBioBirData SignatureBlock; 9 | } 10 | } -------------------------------------------------------------------------------- /WinBioNET/WinBioVersion.cs: -------------------------------------------------------------------------------- 1 | namespace WinBioNET 2 | { 3 | public struct WinBioVersion 4 | { 5 | public int MajorVersion; 6 | public int MinorVersion; 7 | 8 | public override string ToString() 9 | { 10 | return string.Format("{0}.{1}", MajorVersion, MinorVersion); 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /WinBioNET/Enums/WinBioBirDataFlags.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace WinBioNET.Enums 4 | { 5 | [Flags] 6 | public enum WinBioBirDataFlags 7 | { 8 | Integrity = 0x01, 9 | Privacy = 0x02, 10 | Signed = 0x04, 11 | 12 | Raw = 0x20, 13 | Intermediate = 0x40, 14 | Processed = 0x80, 15 | } 16 | } -------------------------------------------------------------------------------- /WinBioNET/Enums/WinBioBirPurpose.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace WinBioNET.Enums 4 | { 5 | [Flags] 6 | public enum WinBioBirPurpose 7 | { 8 | NoPurposeAvailable = 0, 9 | Verify = 1, 10 | Identify = 2, 11 | Enroll = 4, 12 | EnrollForVerification = 8, 13 | EnrollForIdentification = 16 14 | } 15 | } -------------------------------------------------------------------------------- /WinBioNET/Enums/WinBioPoolType.cs: -------------------------------------------------------------------------------- 1 | namespace WinBioNET.Enums 2 | { 3 | public enum WinBioPoolType 4 | { 5 | 6 | Unknown = 0, 7 | 8 | System = 1, 9 | 10 | Private = 2, 11 | 12 | /// 13 | /// Reserved for Microsoft - do not use. 14 | /// 15 | Unassigned = 3 16 | } 17 | } -------------------------------------------------------------------------------- /WinBioNET/LargeInteger.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.InteropServices; 2 | 3 | namespace WinBioNET 4 | { 5 | [StructLayout(LayoutKind.Explicit, Size = 8)] 6 | public struct LargeInteger 7 | { 8 | [FieldOffset(0)] public long QuadPart; 9 | [FieldOffset(0)] public uint LowPart; 10 | [FieldOffset(4)] public int HighPart; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /WinBioNET/Enums/WinBioCapabilitySensor.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace WinBioNET.Enums 4 | { 5 | [Flags] 6 | public enum WinBioCapabilitySensor 7 | { 8 | Sensor = 0x00000001, 9 | Matching = 0x00000002, 10 | Database = 0x00000004, 11 | Processing = 0x00000008, 12 | Encryption = 0x00000010, 13 | Navigation = 0x00000020, 14 | Indicator = 0x00000040 15 | } 16 | } -------------------------------------------------------------------------------- /WinBioNET/Enums/WinBioRejectDetail.cs: -------------------------------------------------------------------------------- 1 | namespace WinBioNET.Enums 2 | { 3 | public enum WinBioRejectDetail 4 | { 5 | None = 0, 6 | FpTooHigh = 1, 7 | FpTooLow = 2, 8 | FpTooLeft = 3, 9 | FpTooRight = 4, 10 | FpTooFast = 5, 11 | FpTooSlow = 6, 12 | FpPoorQuality = 7, 13 | FpTooSkewed = 8, 14 | FpTooShort = 9, 15 | FpMergeFailure = 10 16 | } 17 | } -------------------------------------------------------------------------------- /WinBioNET/WinBioBdbAnsi381Record.cs: -------------------------------------------------------------------------------- 1 | namespace WinBioNET 2 | { 3 | public struct WinBioBdbAnsi381Record 4 | { 5 | public uint BlockLength; 6 | public ushort HorizontalLineLength; 7 | public ushort VerticalLineLength; 8 | public byte Position; 9 | public byte CountOfViews; 10 | public byte ViewNumber; 11 | public byte ImageQuality; 12 | public byte ImpressionType; 13 | public byte Reserved; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /WinBioNET/Configuration/WinBioSensorKey.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using WinBioNET.Enums; 3 | 4 | namespace WinBioNET.Configuration 5 | { 6 | public class WinBioSensorKey 7 | : WinBioRegistryKeyBase 8 | { 9 | public WinBioSensorMode SensorMode; 10 | public int SystemSensor; 11 | public Guid DatabaseId; 12 | public string SensorAdapterBinary; 13 | public string EngineAdapterBinary; 14 | public string StorageAdapterBinary; 15 | } 16 | } -------------------------------------------------------------------------------- /WinBioNET/Enums/WinBioBiometricSubType.cs: -------------------------------------------------------------------------------- 1 | namespace WinBioNET.Enums 2 | { 3 | public enum WinBioBiometricSubType 4 | : byte 5 | { 6 | Unknown = 0, 7 | RhThumb = 1, 8 | RhIndexFinger = 2, 9 | RhMiddleFinger = 3, 10 | RhRingFinger = 4, 11 | RhLittleFinger = 5, 12 | LhThumb = 6, 13 | LhIndexFinger = 7, 14 | LhMiddleFinger = 8, 15 | LhRingFinger = 9, 16 | LhLittleFinger = 10, 17 | Any = 255 18 | } 19 | } -------------------------------------------------------------------------------- /WindowsFormsTest/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Windows.Forms; 3 | 4 | namespace WindowsFormsTest 5 | { 6 | static class Program 7 | { 8 | /// 9 | /// The main entry point for the application. 10 | /// 11 | [STAThread] 12 | static void Main() 13 | { 14 | Application.EnableVisualStyles(); 15 | Application.SetCompatibleTextRenderingDefault(false); 16 | Application.Run(new WinBioForm()); 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /WinBioNET/WinBioBspSchema.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.InteropServices; 3 | using WinBioNET.Enums; 4 | 5 | namespace WinBioNET 6 | { 7 | [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] 8 | public struct WinBioBspSchema 9 | { 10 | public WinBioBiometricType BiometricFactor; 11 | public Guid BspId; 12 | [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)] 13 | public string Description; 14 | [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)] 15 | public string Vendor; 16 | public WinBioVersion Version; 17 | } 18 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | #Specific files 2 | DownloadCloo.html 3 | SAQ.txt 4 | 5 | #Folders 6 | Documentation/Reference/* 7 | Documentation/Tutorials/* 8 | ipch/ 9 | 10 | #File types 11 | *.pdf 12 | *.zip 13 | 14 | 15 | #Ignore thumbnails created by windows 16 | Thumbs.db 17 | #Ignore files build by Visual Studio 18 | *.obj 19 | *.exe 20 | *.pdb 21 | *.user 22 | *.aps 23 | *.pch 24 | *.vspscc 25 | *_i.c 26 | *_p.c 27 | *.ncb 28 | *.suo 29 | *.tlb 30 | *.tlh 31 | *.bak 32 | *.cache 33 | *.ilk 34 | *.log 35 | [Bb]in 36 | [Dd]ebug*/ 37 | *.lib 38 | *.sbr 39 | obj/ 40 | [Rr]elease*/ 41 | _ReSharper*/ 42 | [Tt]est[Rr]esult* 43 | /.vs 44 | -------------------------------------------------------------------------------- /WinBioNET/Unused/WinBioResource.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Diagnostics; 3 | 4 | namespace WinBioNET.Unused 5 | { 6 | public abstract class WinBioResource 7 | : WinBioObject 8 | , IDisposable 9 | { 10 | public void Dispose() 11 | { 12 | Dispose(true); 13 | GC.SuppressFinalize(this); 14 | GC.KeepAlive(this); 15 | } 16 | 17 | ~WinBioResource() 18 | { 19 | Trace.TraceWarning(ToString() + " leaked!"); 20 | Dispose(false); 21 | } 22 | 23 | protected abstract void Dispose(bool manual); 24 | } 25 | } -------------------------------------------------------------------------------- /WinBioNET/WinBioStorageSchema.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.InteropServices; 3 | using WinBioNET.Enums; 4 | 5 | namespace WinBioNET 6 | { 7 | [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] 8 | public struct WinBioStorageSchema 9 | { 10 | public WinBioBiometricType Factor; 11 | public Guid DatabaseId; 12 | public Guid DataFormat; 13 | public WinBioDatabaseFlag Attributes; 14 | [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)] 15 | public string FilePath; 16 | [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)] 17 | public string ConnectionString; 18 | } 19 | } -------------------------------------------------------------------------------- /WinBioNET/Enums/WinBioIdentityType.cs: -------------------------------------------------------------------------------- 1 | namespace WinBioNET.Enums 2 | { 3 | public enum WinBioIdentityType 4 | { 5 | /// 6 | /// The Identity structure is empty. 7 | /// 8 | Null = 0, 9 | 10 | /// 11 | /// The Identity matches "all identities" 12 | /// 13 | Wildcard = 1, 14 | 15 | /// 16 | /// A GUID identifies the template. 17 | /// 18 | GUID = 2, 19 | 20 | /// 21 | /// An account SID identifies the template. 22 | /// 23 | SID = 3 24 | } 25 | } -------------------------------------------------------------------------------- /WinBioNET/Unused/WinBioDatabase.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using WinBioNET.Enums; 3 | 4 | namespace WinBioNET.Unused 5 | { 6 | public class WinBioDatabase 7 | { 8 | public static void EnumDatabases() 9 | { 10 | var schemaArray = WinBio.EnumDatabases(WinBioBiometricType.Fingerprint); 11 | Console.WriteLine("Databases found: {0}", schemaArray.Length); 12 | for (var i = 0; i < schemaArray.Length; i++) 13 | { 14 | Console.WriteLine("Database {0}", i); 15 | var id = schemaArray[i].DatabaseId; 16 | Console.WriteLine("Id: {0}", id); 17 | } 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /WinBioNET/WinBioBirHeader.cs: -------------------------------------------------------------------------------- 1 | namespace WinBioNET 2 | { 3 | public struct WinBioBirHeader 4 | { 5 | public ushort ValidFields; 6 | public byte HeaderVersion; 7 | public byte PatronHeaderVersion; 8 | public byte DataFlags; 9 | public uint Type; 10 | public byte Subtype; 11 | public byte Purpose; 12 | public sbyte DataQuality; 13 | public LargeInteger CreationDate; 14 | public Period ValidityPeriod; 15 | public WinBioRegisteredFormat BiometricDataFormat; 16 | public WinBioRegisteredFormat ProductId; 17 | } 18 | 19 | public struct Period 20 | { 21 | public LargeInteger BeginDate; 22 | public LargeInteger EndDate; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /WinBioNET/WinBioBdbAnsi381Header.cs: -------------------------------------------------------------------------------- 1 | namespace WinBioNET 2 | { 3 | public struct WinBioBdbAnsi381Header 4 | { 5 | public ulong RecordLength; 6 | public uint FormatIdentifier; 7 | public uint VersionNumber; 8 | public WinBioRegisteredFormat ProductId; 9 | public ushort CaptureDeviceId; 10 | public ushort ImageAcquisitionLevel; 11 | public ushort HorizontalScanResolution; 12 | public ushort VerticalScanResolution; 13 | public ushort HorizontalImageResolution; 14 | public ushort VerticalImageResolution; 15 | public byte ElementCount; 16 | public byte ScaleUnits; 17 | public byte PixelDepth; 18 | public byte ImageCompressionAlg; 19 | public ushort Reserved; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /WinBioNET/WinBioSessionHandle.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Diagnostics; 3 | 4 | namespace WinBioNET 5 | { 6 | public struct WinBioSessionHandle 7 | { 8 | [DebuggerBrowsable(DebuggerBrowsableState.Never)] 9 | IntPtr _value; 10 | 11 | /// 12 | /// Gets a logic value indicating whether the handle is valid. 13 | /// 14 | public bool IsValid 15 | { 16 | get { return _value != IntPtr.Zero; } 17 | } 18 | 19 | /// 20 | /// Gets the value of the handle. 21 | /// 22 | public IntPtr Value 23 | { 24 | get { return _value; } 25 | } 26 | 27 | /// 28 | /// Invalidates the handle. 29 | /// 30 | public void Invalidate() 31 | { 32 | _value = IntPtr.Zero; 33 | } 34 | } 35 | } -------------------------------------------------------------------------------- /WinBioNET/Unused/WinBioObject.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace WinBioNET.Unused 4 | { 5 | public class WinBioObject 6 | : IEquatable 7 | { 8 | private IntPtr _handle; 9 | 10 | protected void SetID(IntPtr handle) 11 | { 12 | _handle = handle; 13 | } 14 | 15 | public override bool Equals(object other) 16 | { 17 | if (!(other is WinBioObject)) return false; 18 | return Equals((WinBioObject) other); 19 | } 20 | 21 | public bool Equals(WinBioObject other) 22 | { 23 | if (other == null) return false; 24 | return _handle.Equals(other._handle); 25 | } 26 | 27 | public override int GetHashCode() 28 | { 29 | return _handle.GetHashCode(); 30 | } 31 | 32 | public override string ToString() 33 | { 34 | return string.Format("{0}({1})", GetType().Name, _handle); 35 | } 36 | } 37 | } -------------------------------------------------------------------------------- /WinBioNET/WinBioUnitSchema.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.InteropServices; 2 | using WinBioNET.Enums; 3 | 4 | namespace WinBioNET 5 | { 6 | [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] 7 | public struct WinBioUnitSchema 8 | { 9 | public int UnitId; 10 | public WinBioPoolType PoolType; 11 | public WinBioBiometricType BiometricFactor; 12 | public WinBioSensorSubType SensorSubType; 13 | public WinBioCapabilitySensor Capabilities; 14 | [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)] 15 | public string DeviceInstanceId; 16 | [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)] 17 | public string Description; 18 | [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)] 19 | public string Manufacturer; 20 | [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)] 21 | public string Model; 22 | [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)] 23 | public string SerialNumber; 24 | public WinBioVersion FirmwareVersion; 25 | } 26 | } -------------------------------------------------------------------------------- /WinBioNET/Enums/WinBioSessionFlag.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace WinBioNET.Enums 4 | { 5 | /// 6 | /// Configuration flags specify the general configuration of units in the session. 7 | /// Access flags specify how the application will use the biometric units. 8 | /// You must specify one configuration flag but you can combine that flag with any access flag. 9 | /// 10 | [Flags] 11 | public enum WinBioSessionFlag 12 | { 13 | /// 14 | /// Group: configuration 15 | /// 16 | Default = 0, 17 | 18 | /// 19 | /// Group: configuration 20 | /// 21 | Basic = 1 << 16, 22 | 23 | /// 24 | /// Group: configuration 25 | /// 26 | Advanced = 2 << 16, 27 | 28 | /// 29 | /// Group: access 30 | /// 31 | Raw = 1, 32 | 33 | /// 34 | /// Group: access 35 | /// 36 | Maintenance = 2 37 | } 38 | } -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 J.C.Bernack 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. -------------------------------------------------------------------------------- /WinBioNET/Unused/WinBioUnit.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using WinBioNET.Enums; 3 | 4 | namespace WinBioNET.Unused 5 | { 6 | public class WinBioUnit 7 | { 8 | public static void EnumUnitIds() 9 | { 10 | var units = WinBio.EnumBiometricUnits(WinBioBiometricType.Fingerprint); 11 | Console.WriteLine("Biometric units found: {0}", units.Length); 12 | for (var i = 0; i < units.Length; i++) 13 | { 14 | Console.WriteLine(units[i].UnitId); 15 | Console.WriteLine(units[i].PoolType); 16 | Console.WriteLine(units[i].BiometricFactor); 17 | Console.WriteLine(units[i].SensorSubType); 18 | Console.WriteLine(units[i].Capabilities); 19 | Console.WriteLine(units[i].DeviceInstanceId); 20 | Console.WriteLine(units[i].Description); 21 | Console.WriteLine(units[i].Manufacturer); 22 | Console.WriteLine(units[i].Model); 23 | Console.WriteLine(units[i].SerialNumber); 24 | Console.WriteLine(units[i].FirmwareVersion); 25 | } 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /WinBioNET/Configuration/WinBioDatabaseKey.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using WinBioNET.Enums; 3 | 4 | namespace WinBioNET.Configuration 5 | { 6 | public class WinBioDatabaseKey 7 | : WinBioRegistryKeyBase 8 | { 9 | public WinBioBiometricType BiometricType; 10 | public WinBioDatabaseFlag Attributes; 11 | public int AutoCreate; //bool? 12 | public int AutoName; //bool? 13 | public int InitialSize; //bool? 14 | public Guid Format; 15 | public string FilePath; 16 | public string ConnectionString; 17 | 18 | public WinBioDatabaseKey() 19 | { 20 | } 21 | 22 | public WinBioDatabaseKey(WinBioStorageSchema database) 23 | { 24 | Attributes = database.Attributes; 25 | Format = database.DataFormat; 26 | BiometricType = WinBioBiometricType.Fingerprint; 27 | AutoCreate = 1; 28 | AutoName = 1; 29 | InitialSize = 32; 30 | FilePath = Environment.SystemDirectory + string.Format(@"\WINBIODATABASE\{0}.DAT", database.DatabaseId.ToString().ToUpper()); 31 | ConnectionString = ""; 32 | } 33 | } 34 | } -------------------------------------------------------------------------------- /WinBioNET/WinBioException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using WinBioNET.Enums; 3 | 4 | namespace WinBioNET 5 | { 6 | public class WinBioException 7 | : Exception 8 | { 9 | public WinBioErrorCode ErrorCode { get; private set; } 10 | 11 | public WinBioException(string message) 12 | : base(message) 13 | { 14 | } 15 | 16 | public WinBioException(WinBioErrorCode errorCode) 17 | : base(errorCode.ToString()) 18 | { 19 | ErrorCode = errorCode; 20 | } 21 | 22 | public WinBioException(WinBioErrorCode errorCode, string message) 23 | : base(string.Format("{0}: {1}", message, errorCode)) 24 | { 25 | HResult = (int) errorCode; 26 | ErrorCode = errorCode; 27 | } 28 | 29 | public static void ThrowOnError(WinBioErrorCode errorCode, string message) 30 | { 31 | if (errorCode == WinBioErrorCode.Ok) return; 32 | throw new WinBioException(errorCode, message); 33 | } 34 | 35 | public static void ThrowOnError(WinBioErrorCode errorCode) 36 | { 37 | if (errorCode == WinBioErrorCode.Ok) return; 38 | throw new WinBioException(errorCode); 39 | } 40 | } 41 | } -------------------------------------------------------------------------------- /WinBioNET/Enums/WinBioDatabaseFlag.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace WinBioNET.Enums 4 | { 5 | [Flags] 6 | public enum WinBioDatabaseFlag 7 | { 8 | /// 9 | /// Represents a mask for the flag bits. 10 | /// 11 | //FlagMask = 0xFFFF0000, 12 | 13 | /// 14 | /// The database resides on a removable drive. 15 | /// 16 | FlagRemovable = 0x00010000, 17 | 18 | /// 19 | /// The database resides on a remote computer. 20 | /// 21 | FlagRemote = 0x00020000, 22 | 23 | /// 24 | /// Represents a mask for the type bits. 25 | /// 26 | //TypeMask = 0x0000FFFF, 27 | 28 | /// 29 | /// The database is contained in a file. 30 | /// 31 | TypeFile = 0x00000001, 32 | 33 | /// 34 | /// The database is managed by a database management system. 35 | /// 36 | TypeDbms = 0x00000002, 37 | 38 | /// 39 | /// The database resides on the biometric sensor. 40 | /// 41 | TypeOnchip = 0x00000003, 42 | 43 | /// 44 | /// The database resides on a smart card. 45 | /// 46 | TypeSmartcard = 0x00000004, 47 | } 48 | } -------------------------------------------------------------------------------- /WinBioNET/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.InteropServices; 3 | 4 | // General Information about an assembly is controlled through the following 5 | // set of attributes. Change these attribute values to modify the information 6 | // associated with an assembly. 7 | [assembly: AssemblyTitle("WinBioNET")] 8 | [assembly: AssemblyDescription("")] 9 | [assembly: AssemblyConfiguration("")] 10 | [assembly: AssemblyCompany("JcBernack")] 11 | [assembly: AssemblyProduct("WinBioNET")] 12 | [assembly: AssemblyCopyright("Copyright © 2015")] 13 | [assembly: AssemblyTrademark("")] 14 | [assembly: AssemblyCulture("")] 15 | 16 | // Setting ComVisible to false makes the types in this assembly not visible 17 | // to COM components. If you need to access a type in this assembly from 18 | // COM, set the ComVisible attribute to true on that type. 19 | [assembly: ComVisible(false)] 20 | 21 | // The following GUID is for the ID of the typelib if this project is exposed to COM 22 | [assembly: Guid("2f47d36b-7de1-456c-9c70-6a242d766974")] 23 | 24 | // Version information for an assembly consists of the following four values: 25 | // 26 | // Major Version 27 | // Minor Version 28 | // Build Number 29 | // Revision 30 | // 31 | // You can specify all the values or you can default the Build and Revision Numbers 32 | // by using the '*' as shown below: 33 | // [assembly: AssemblyVersion("1.0.*")] 34 | [assembly: AssemblyVersion("1.0.*")] 35 | -------------------------------------------------------------------------------- /ConsoleTest/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.InteropServices; 3 | 4 | // General Information about an assembly is controlled through the following 5 | // set of attributes. Change these attribute values to modify the information 6 | // associated with an assembly. 7 | [assembly: AssemblyTitle("ConsoleTest for WinBioNET")] 8 | [assembly: AssemblyDescription("")] 9 | [assembly: AssemblyConfiguration("")] 10 | [assembly: AssemblyCompany("JcBernack")] 11 | [assembly: AssemblyProduct("ConsoleTest for WinBioNET")] 12 | [assembly: AssemblyCopyright("Copyright © 2015")] 13 | [assembly: AssemblyTrademark("")] 14 | [assembly: AssemblyCulture("")] 15 | 16 | // Setting ComVisible to false makes the types in this assembly not visible 17 | // to COM components. If you need to access a type in this assembly from 18 | // COM, set the ComVisible attribute to true on that type. 19 | [assembly: ComVisible(false)] 20 | 21 | // The following GUID is for the ID of the typelib if this project is exposed to COM 22 | [assembly: Guid("7f26c990-b4e9-46b3-8e5f-e6c9b271b690")] 23 | 24 | // Version information for an assembly consists of the following four values: 25 | // 26 | // Major Version 27 | // Minor Version 28 | // Build Number 29 | // Revision 30 | // 31 | // You can specify all the values or you can default the Build and Revision Numbers 32 | // by using the '*' as shown below: 33 | // [assembly: AssemblyVersion("1.0.*")] 34 | [assembly: AssemblyVersion("1.0.0.0")] 35 | [assembly: AssemblyFileVersion("1.0.0.0")] 36 | -------------------------------------------------------------------------------- /WindowsFormsTest/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.InteropServices; 3 | 4 | // General Information about an assembly is controlled through the following 5 | // set of attributes. Change these attribute values to modify the information 6 | // associated with an assembly. 7 | [assembly: AssemblyTitle("WindowsFormsTest For WinBioNET")] 8 | [assembly: AssemblyDescription("")] 9 | [assembly: AssemblyConfiguration("")] 10 | [assembly: AssemblyCompany("JcBernack")] 11 | [assembly: AssemblyProduct("WindowsFormsTest For WinBioNET")] 12 | [assembly: AssemblyCopyright("Copyright © 2015")] 13 | [assembly: AssemblyTrademark("")] 14 | [assembly: AssemblyCulture("")] 15 | 16 | // Setting ComVisible to false makes the types in this assembly not visible 17 | // to COM components. If you need to access a type in this assembly from 18 | // COM, set the ComVisible attribute to true on that type. 19 | [assembly: ComVisible(false)] 20 | 21 | // The following GUID is for the ID of the typelib if this project is exposed to COM 22 | [assembly: Guid("4ab667c7-a143-451c-834e-bf6c99afdfb0")] 23 | 24 | // Version information for an assembly consists of the following four values: 25 | // 26 | // Major Version 27 | // Minor Version 28 | // Build Number 29 | // Revision 30 | // 31 | // You can specify all the values or you can default the Build and Revision Numbers 32 | // by using the '*' as shown below: 33 | // [assembly: AssemblyVersion("1.0.*")] 34 | [assembly: AssemblyVersion("1.0.0.0")] 35 | [assembly: AssemblyFileVersion("1.0.0.0")] 36 | -------------------------------------------------------------------------------- /WinBioNET/Unused/WinBioSession.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Drawing; 3 | using WinBioNET.Enums; 4 | 5 | namespace WinBioNET.Unused 6 | { 7 | public class WinBioSession 8 | : WinBioResource 9 | { 10 | private readonly WinBioSessionHandle _handle; 11 | 12 | public WinBioSession() 13 | { 14 | _handle = WinBio.OpenSession(WinBioBiometricType.Fingerprint); 15 | SetID(_handle.Value); 16 | Console.WriteLine("WinBioSession opened: " + _handle.Value); 17 | } 18 | 19 | protected override void Dispose(bool manual) 20 | { 21 | WinBio.CloseSession(_handle); 22 | Console.WriteLine("WinBioSession closed"); 23 | } 24 | 25 | public int LocateSensor() 26 | { 27 | return WinBio.LocateSensor(_handle); 28 | } 29 | 30 | public void Identify() 31 | { 32 | WinBioIdentity identity; 33 | WinBioBiometricSubType subFactor; 34 | WinBioRejectDetail rejectDetail; 35 | var unitId = WinBio.Identify(_handle, out identity, out subFactor, out rejectDetail); 36 | Console.WriteLine("Unit Id: {0}", unitId); 37 | Console.WriteLine("Identity: {0}", identity); 38 | Console.WriteLine("Sub factor: {0}", subFactor); 39 | Console.WriteLine("Reject details: {0}", rejectDetail); 40 | } 41 | 42 | public void CaptureSample(WinBioBirPurpose purpose, WinBioBirDataFlags dataFlags) 43 | { 44 | Bitmap image; 45 | WinBioRejectDetail rejectDetail; 46 | var unitId = WinBio.CaptureSample(_handle, purpose, dataFlags, out rejectDetail, out image); 47 | Console.WriteLine("Unit id: {0}", unitId); 48 | Console.WriteLine("Captured sample size: {0}x{1}", image.Width, image.Height); 49 | Console.WriteLine("Reject details: {0}", rejectDetail); 50 | } 51 | } 52 | } -------------------------------------------------------------------------------- /WinBioNET/Configuration/WinBioRegistryKeyBase.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.Reflection; 5 | using System.Text; 6 | using Microsoft.Win32; 7 | 8 | namespace WinBioNET.Configuration 9 | { 10 | public class WinBioRegistryKeyBase 11 | { 12 | private IEnumerable GetFields() 13 | { 14 | return GetType().GetFields(BindingFlags.Public | BindingFlags.Instance); 15 | } 16 | 17 | public void Read(RegistryKey key) 18 | { 19 | foreach (var field in GetFields()) 20 | { 21 | var value = key.GetValue(field.Name); 22 | if (field.FieldType == typeof (Guid)) 23 | { 24 | var converter = TypeDescriptor.GetConverter(field.FieldType); 25 | value = converter.ConvertFrom(value); 26 | } 27 | field.SetValue(this, value); 28 | } 29 | } 30 | 31 | public void Write(RegistryKey key) 32 | { 33 | foreach (var field in GetFields()) 34 | { 35 | var value = field.GetValue(this); 36 | if (field.FieldType.IsEnum) 37 | { 38 | value = Convert.ChangeType(value, field.FieldType.GetEnumUnderlyingType()); 39 | } 40 | if (field.FieldType == typeof (Guid)) 41 | { 42 | value = ((Guid) value).ToString("D").ToUpperInvariant(); 43 | } 44 | key.SetValue(field.Name, value); 45 | } 46 | } 47 | 48 | public override string ToString() 49 | { 50 | var builder = new StringBuilder(); 51 | foreach (var field in GetFields()) 52 | { 53 | builder.AppendFormat("{0}: {1}\n", field.Name, field.GetValue(this)); 54 | } 55 | return builder.ToString(); 56 | } 57 | } 58 | } -------------------------------------------------------------------------------- /ApiInformation.txt: -------------------------------------------------------------------------------- 1 | ## About sensor pools 2 | 3 | # Using a system pool 4 | Identities are using the windows account SID. 5 | An identity can hold one unique template for each sub-factor. 6 | New templates are always enrolled for the identity of the current windows user. 7 | 8 | # Using a private pool 9 | Identities are using unique GUIDs. 10 | An identity always holds a single unique template for one sub-factor. 11 | New templates always create a new identity. 12 | 13 | ## Registry structure 14 | 15 | # Device configurations are stored at: 16 | HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ + unit.DeviceInstanceId + \Device Parameters\WinBio\Configurations\ + number 17 | where number is a zero-based increasing index 18 | and unit.DeviceInstanceId is something like: USB\VID_1C7A&PID_0603\6&efec896&0&3 19 | 20 | # Databases are stored at: 21 | HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\WbioSrvc\Databases\{ + DatabaseId + } 22 | where DatabaseId is a Guid 23 | 24 | # Device configuration fields are: 25 | DWORD SensorMode Insert 1 or 2 for WinBioSensorMode.Basic and Advanced. 26 | DWORD SystemSensor Insert 0, a value of 1 corresponds to the system pool. 27 | SZ DatabaseId Insert Guid of corresponding database (without braces). 28 | SZ SensorAdapterBinary Insert path to dll, copy from default configuration. 29 | SZ EngineAdapterBinary Insert path to dll, copy from default configuration. 30 | SZ StorageAdapterBinary Insert path to dll, copy from default configuration. 31 | 32 | # Database fields are: 33 | DWORD Attributes Insert 1 for WinBioDatabaseFlag.TypeFile. Probably can contain any value of WinBioDatabaseFlag. 34 | DWORD AutoCreate Insert 1. 35 | DWORD AutoName Insert 1, will be set to 0 upon database creation. 36 | DWORD BiometricType Insert 8 for WinBioBiometricType.Fingerprint. 37 | SZ ConnectionString Insert empty string. Probably used if something other than WinBioDatabaseFlag.TypeFile is used. 38 | SZ FilePath Insert empty string, will be set by the storage adapter to the path of the database file on creation. 39 | SZ Format Insert an empty Guid: "00000000-0000-0000-0000-000000000000". No idea what it means. 40 | DWORD InitialSize Insert (int)32. No idea what it actually means. Size of what? I what unit? 41 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | 6 | ############################################################################### 7 | # Set default behavior for command prompt diff. 8 | # 9 | # This is need for earlier builds of msysgit that does not have it on by 10 | # default for csharp files. 11 | # Note: This is only used by command line 12 | ############################################################################### 13 | #*.cs diff=csharp 14 | 15 | ############################################################################### 16 | # Set the merge driver for project and solution files 17 | # 18 | # Merging from the command prompt will add diff markers to the files if there 19 | # are conflicts (Merging from VS is not affected by the settings below, in VS 20 | # the diff markers are never inserted). Diff markers may cause the following 21 | # file extensions to fail to load in VS. An alternative would be to treat 22 | # these files as binary and thus will always conflict and require user 23 | # intervention with every merge. To do so, just uncomment the entries below 24 | ############################################################################### 25 | #*.sln merge=binary 26 | #*.csproj merge=binary 27 | #*.vbproj merge=binary 28 | #*.vcxproj merge=binary 29 | #*.vcproj merge=binary 30 | #*.dbproj merge=binary 31 | #*.fsproj merge=binary 32 | #*.lsproj merge=binary 33 | #*.wixproj merge=binary 34 | #*.modelproj merge=binary 35 | #*.sqlproj merge=binary 36 | #*.wwaproj merge=binary 37 | 38 | ############################################################################### 39 | # behavior for image files 40 | # 41 | # image files are treated as binary by default. 42 | ############################################################################### 43 | #*.jpg binary 44 | #*.png binary 45 | #*.gif binary 46 | 47 | ############################################################################### 48 | # diff behavior for common document formats 49 | # 50 | # Convert binary document formats to text before diffing them. This feature 51 | # is only available from the command line. Turn it on by uncommenting the 52 | # entries below. 53 | ############################################################################### 54 | #*.doc diff=astextplain 55 | #*.DOC diff=astextplain 56 | #*.docx diff=astextplain 57 | #*.DOCX diff=astextplain 58 | #*.dot diff=astextplain 59 | #*.DOT diff=astextplain 60 | #*.pdf diff=astextplain 61 | #*.PDF diff=astextplain 62 | #*.rtf diff=astextplain 63 | #*.RTF diff=astextplain 64 | -------------------------------------------------------------------------------- /ConsoleTest/ConsoleTest.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {039F7D3B-BD11-47B6-98CB-E7A6008FA47E} 8 | Exe 9 | Properties 10 | ConsoleTest 11 | ConsoleTest 12 | v4.5 13 | 512 14 | 15 | 16 | true 17 | bin\x86\Debug\ 18 | DEBUG;TRACE 19 | full 20 | x86 21 | prompt 22 | MinimumRecommendedRules.ruleset 23 | true 24 | 25 | 26 | bin\x86\Release\ 27 | TRACE 28 | true 29 | pdbonly 30 | x86 31 | prompt 32 | MinimumRecommendedRules.ruleset 33 | true 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | {6D7EBD5F-56DA-4D8B-81C6-95C980F3D6F5} 54 | WinBioNET 55 | 56 | 57 | 58 | 65 | -------------------------------------------------------------------------------- /WindowsFormsTest/WindowsFormsTest.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {2D4D1B7F-7D58-41F9-AD07-AC56154D6E7A} 8 | WinExe 9 | Properties 10 | WindowsFormsTest 11 | WindowsFormsTest 12 | v4.5 13 | 512 14 | 15 | 16 | true 17 | bin\x86\Debug\ 18 | DEBUG;TRACE 19 | full 20 | x86 21 | prompt 22 | MinimumRecommendedRules.ruleset 23 | true 24 | 25 | 26 | bin\x86\Release\ 27 | TRACE 28 | true 29 | pdbonly 30 | x86 31 | prompt 32 | MinimumRecommendedRules.ruleset 33 | true 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | Form 45 | 46 | 47 | WinBioForm.cs 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | {6D7EBD5F-56DA-4D8B-81C6-95C980F3D6F5} 58 | WinBioNET 59 | 60 | 61 | 62 | 63 | WinBioForm.cs 64 | 65 | 66 | 67 | 74 | -------------------------------------------------------------------------------- /WinBioNET/WinBioIdentity.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Security.Principal; 4 | using WinBioNET.Enums; 5 | 6 | namespace WinBioNET 7 | { 8 | public class WinBioIdentity 9 | { 10 | public const int Size = 76; 11 | 12 | public WinBioIdentityType Type; 13 | public int Null; 14 | public int Wildcard; 15 | public Guid TemplateGuid; 16 | public int AccountSidSize; 17 | public SecurityIdentifier AccountSid; 18 | 19 | public WinBioIdentity(byte[] bytes) 20 | { 21 | FromBytes(bytes); 22 | } 23 | 24 | public void FromBytes(byte[] bytes) 25 | { 26 | using (var stream = new MemoryStream(bytes, false)) 27 | using (var reader = new BinaryReader(stream)) 28 | { 29 | Type = (WinBioIdentityType)reader.ReadInt32(); 30 | switch (Type) 31 | { 32 | case WinBioIdentityType.Null: 33 | Null = reader.ReadInt32(); 34 | break; 35 | case WinBioIdentityType.Wildcard: 36 | Wildcard = reader.ReadInt32(); 37 | break; 38 | case WinBioIdentityType.GUID: 39 | TemplateGuid = new Guid(reader.ReadBytes(16)); 40 | break; 41 | case WinBioIdentityType.SID: 42 | AccountSidSize = reader.ReadInt32(); 43 | AccountSid = new SecurityIdentifier(reader.ReadBytes(AccountSidSize), 0); 44 | break; 45 | default: 46 | throw new ArgumentOutOfRangeException(); 47 | } 48 | } 49 | } 50 | 51 | public byte[] GetBytes() 52 | { 53 | var bytes = new byte[Size]; 54 | using (var stream = new MemoryStream(bytes, true)) 55 | using (var writer = new BinaryWriter(stream)) 56 | { 57 | writer.Write((int) Type); 58 | switch (Type) 59 | { 60 | case WinBioIdentityType.Null: 61 | writer.Write(Null); 62 | break; 63 | case WinBioIdentityType.Wildcard: 64 | writer.Write(Wildcard); 65 | break; 66 | case WinBioIdentityType.GUID: 67 | writer.Write(TemplateGuid.ToByteArray()); 68 | break; 69 | case WinBioIdentityType.SID: 70 | writer.Write(AccountSidSize); 71 | AccountSid.GetBinaryForm(bytes, (int)stream.Position); 72 | break; 73 | default: 74 | throw new ArgumentOutOfRangeException(); 75 | } 76 | } 77 | return bytes; 78 | } 79 | 80 | public override string ToString() 81 | { 82 | switch (Type) 83 | { 84 | case WinBioIdentityType.Null: return string.Format("Null ({0})", Null); 85 | case WinBioIdentityType.Wildcard: return string.Format("Wildcard ({0})", Wildcard); 86 | case WinBioIdentityType.GUID: return string.Format("GUID ({0})", TemplateGuid); 87 | case WinBioIdentityType.SID: return string.Format("SID ({0})", AccountSid); 88 | default: throw new ArgumentOutOfRangeException(); 89 | } 90 | } 91 | } 92 | } -------------------------------------------------------------------------------- /WinBioNET.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 15 4 | VisualStudioVersion = 15.0.26403.3 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WinBioNET", "WinBioNET\WinBioNET.csproj", "{6D7EBD5F-56DA-4D8B-81C6-95C980F3D6F5}" 7 | EndProject 8 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{3C009ABF-7391-433D-AE46-4AE4DA3B8BD8}" 9 | ProjectSection(SolutionItems) = preProject 10 | ApiInformation.txt = ApiInformation.txt 11 | EndProjectSection 12 | EndProject 13 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ConsoleTest", "ConsoleTest\ConsoleTest.csproj", "{039F7D3B-BD11-47B6-98CB-E7A6008FA47E}" 14 | EndProject 15 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WindowsFormsTest", "WindowsFormsTest\WindowsFormsTest.csproj", "{2D4D1B7F-7D58-41F9-AD07-AC56154D6E7A}" 16 | EndProject 17 | Global 18 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 19 | Debug|Any CPU = Debug|Any CPU 20 | Debug|Mixed Platforms = Debug|Mixed Platforms 21 | Debug|x86 = Debug|x86 22 | Release|Any CPU = Release|Any CPU 23 | Release|Mixed Platforms = Release|Mixed Platforms 24 | Release|x86 = Release|x86 25 | EndGlobalSection 26 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 27 | {6D7EBD5F-56DA-4D8B-81C6-95C980F3D6F5}.Debug|Any CPU.ActiveCfg = Debug|x86 28 | {6D7EBD5F-56DA-4D8B-81C6-95C980F3D6F5}.Debug|Any CPU.Build.0 = Debug|x86 29 | {6D7EBD5F-56DA-4D8B-81C6-95C980F3D6F5}.Debug|Mixed Platforms.ActiveCfg = Debug|x86 30 | {6D7EBD5F-56DA-4D8B-81C6-95C980F3D6F5}.Debug|Mixed Platforms.Build.0 = Debug|x86 31 | {6D7EBD5F-56DA-4D8B-81C6-95C980F3D6F5}.Debug|x86.ActiveCfg = Debug|x86 32 | {6D7EBD5F-56DA-4D8B-81C6-95C980F3D6F5}.Debug|x86.Build.0 = Debug|x86 33 | {6D7EBD5F-56DA-4D8B-81C6-95C980F3D6F5}.Release|Any CPU.ActiveCfg = Release|x86 34 | {6D7EBD5F-56DA-4D8B-81C6-95C980F3D6F5}.Release|Any CPU.Build.0 = Release|x86 35 | {6D7EBD5F-56DA-4D8B-81C6-95C980F3D6F5}.Release|Mixed Platforms.ActiveCfg = Release|x86 36 | {6D7EBD5F-56DA-4D8B-81C6-95C980F3D6F5}.Release|Mixed Platforms.Build.0 = Release|x86 37 | {6D7EBD5F-56DA-4D8B-81C6-95C980F3D6F5}.Release|x86.ActiveCfg = Release|x86 38 | {6D7EBD5F-56DA-4D8B-81C6-95C980F3D6F5}.Release|x86.Build.0 = Release|x86 39 | {039F7D3B-BD11-47B6-98CB-E7A6008FA47E}.Debug|Any CPU.ActiveCfg = Debug|x86 40 | {039F7D3B-BD11-47B6-98CB-E7A6008FA47E}.Debug|Any CPU.Build.0 = Debug|x86 41 | {039F7D3B-BD11-47B6-98CB-E7A6008FA47E}.Debug|Mixed Platforms.ActiveCfg = Debug|x86 42 | {039F7D3B-BD11-47B6-98CB-E7A6008FA47E}.Debug|Mixed Platforms.Build.0 = Debug|x86 43 | {039F7D3B-BD11-47B6-98CB-E7A6008FA47E}.Debug|x86.ActiveCfg = Debug|x86 44 | {039F7D3B-BD11-47B6-98CB-E7A6008FA47E}.Debug|x86.Build.0 = Debug|x86 45 | {039F7D3B-BD11-47B6-98CB-E7A6008FA47E}.Release|Any CPU.ActiveCfg = Release|x86 46 | {039F7D3B-BD11-47B6-98CB-E7A6008FA47E}.Release|Any CPU.Build.0 = Release|x86 47 | {039F7D3B-BD11-47B6-98CB-E7A6008FA47E}.Release|Mixed Platforms.ActiveCfg = Release|x86 48 | {039F7D3B-BD11-47B6-98CB-E7A6008FA47E}.Release|Mixed Platforms.Build.0 = Release|x86 49 | {039F7D3B-BD11-47B6-98CB-E7A6008FA47E}.Release|x86.ActiveCfg = Release|x86 50 | {039F7D3B-BD11-47B6-98CB-E7A6008FA47E}.Release|x86.Build.0 = Release|x86 51 | {2D4D1B7F-7D58-41F9-AD07-AC56154D6E7A}.Debug|Any CPU.ActiveCfg = Debug|x86 52 | {2D4D1B7F-7D58-41F9-AD07-AC56154D6E7A}.Debug|Any CPU.Build.0 = Debug|x86 53 | {2D4D1B7F-7D58-41F9-AD07-AC56154D6E7A}.Debug|Mixed Platforms.ActiveCfg = Debug|x86 54 | {2D4D1B7F-7D58-41F9-AD07-AC56154D6E7A}.Debug|Mixed Platforms.Build.0 = Debug|x86 55 | {2D4D1B7F-7D58-41F9-AD07-AC56154D6E7A}.Debug|x86.ActiveCfg = Debug|x86 56 | {2D4D1B7F-7D58-41F9-AD07-AC56154D6E7A}.Debug|x86.Build.0 = Debug|x86 57 | {2D4D1B7F-7D58-41F9-AD07-AC56154D6E7A}.Release|Any CPU.ActiveCfg = Release|x86 58 | {2D4D1B7F-7D58-41F9-AD07-AC56154D6E7A}.Release|Any CPU.Build.0 = Release|x86 59 | {2D4D1B7F-7D58-41F9-AD07-AC56154D6E7A}.Release|Mixed Platforms.ActiveCfg = Release|x86 60 | {2D4D1B7F-7D58-41F9-AD07-AC56154D6E7A}.Release|Mixed Platforms.Build.0 = Release|x86 61 | {2D4D1B7F-7D58-41F9-AD07-AC56154D6E7A}.Release|x86.ActiveCfg = Release|x86 62 | {2D4D1B7F-7D58-41F9-AD07-AC56154D6E7A}.Release|x86.Build.0 = Release|x86 63 | EndGlobalSection 64 | GlobalSection(SolutionProperties) = preSolution 65 | HideSolutionNode = FALSE 66 | EndGlobalSection 67 | EndGlobal 68 | -------------------------------------------------------------------------------- /WinBioNET/WinBioNET.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {6D7EBD5F-56DA-4D8B-81C6-95C980F3D6F5} 8 | Library 9 | Properties 10 | WinBioNET 11 | WinBioNET 12 | v4.5 13 | 512 14 | 15 | 16 | 17 | 18 | 19 | true 20 | bin\x86\Debug\ 21 | DEBUG;TRACE 22 | full 23 | x86 24 | prompt 25 | MinimumRecommendedRules.ruleset 26 | true 27 | 28 | 29 | bin\x86\Release\ 30 | TRACE 31 | true 32 | pdbonly 33 | x86 34 | prompt 35 | MinimumRecommendedRules.ruleset 36 | true 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 96 | -------------------------------------------------------------------------------- /ConsoleTest/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using WinBioNET; 3 | using WinBioNET.Enums; 4 | 5 | namespace ConsoleTest 6 | { 7 | public static class Program 8 | { 9 | private static readonly Guid DatabaseId = Guid.Parse("BC7263C3-A7CE-49F3-8EBF-D47D74863CC6"); 10 | 11 | public static void Main() 12 | { 13 | try 14 | { 15 | var units = WinBio.EnumBiometricUnits(WinBioBiometricType.Fingerprint); 16 | Console.WriteLine("Found {0} units", units.Length); 17 | if (units.Length == 0) return; 18 | var unit = units[0]; 19 | var unitId = unit.UnitId; 20 | Console.WriteLine("Using unit id: {0}", unitId); 21 | Console.WriteLine("Device instance id: {0}", unit.DeviceInstanceId); 22 | var databases = WinBio.EnumDatabases(WinBioBiometricType.Fingerprint); 23 | Console.WriteLine("Found {0} databases", databases.Length); 24 | for (var i = 0; i < databases.Length; i++) 25 | { 26 | Console.WriteLine("DatabaseId {0}: {1}", i, databases[i].DatabaseId); 27 | } 28 | if (WinBioConfiguration.DatabaseExists(DatabaseId)) 29 | { 30 | Console.WriteLine("Removing database: {0}", DatabaseId); 31 | WinBioConfiguration.RemoveDatabase(DatabaseId); 32 | } 33 | Console.WriteLine("Creating database: {0}", DatabaseId); 34 | WinBioConfiguration.AddDatabase(DatabaseId, unitId); 35 | Console.WriteLine("Adding sensor to the pool: {0}", unitId); 36 | WinBioConfiguration.AddUnit(DatabaseId, unitId); 37 | Console.WriteLine("Opening biometric session"); 38 | var session = WinBio.OpenSession(WinBioBiometricType.Fingerprint, WinBioPoolType.Private, WinBioSessionFlag.Basic, new[] { unitId }, DatabaseId); 39 | try 40 | { 41 | Console.WriteLine("Type sub type and press enter:"); 42 | WinBioBiometricSubType subType; 43 | if (!Enum.TryParse(Console.ReadLine(), true, out subType)) 44 | { 45 | Console.WriteLine("Invalid sub type"); 46 | return; 47 | } 48 | var identity = AddEnrollment(session, unitId, subType); 49 | Console.WriteLine("Identity: {0}", identity); 50 | Console.WriteLine(); 51 | var enrollments = WinBio.EnumEnrollments(session, unitId, identity); 52 | Console.WriteLine("Found {0} enrollments for that identity:", enrollments.Length); 53 | foreach (var enrollment in enrollments) 54 | { 55 | Console.WriteLine(enrollment); 56 | } 57 | Console.WriteLine(); 58 | Console.WriteLine("Verify identity with any finger:"); 59 | WinBioRejectDetail rejectDetail; 60 | WinBio.Verify(session, identity, WinBioBiometricSubType.Any, out unitId, out rejectDetail); 61 | Console.WriteLine("Success"); 62 | } 63 | finally 64 | { 65 | Console.WriteLine("Closing biometric session"); 66 | WinBio.CloseSession(session); 67 | } 68 | } 69 | catch (Exception ex) 70 | { 71 | Console.WriteLine("Exception: " + ex.GetType().Name); 72 | Console.WriteLine(ex.Message); 73 | Console.WriteLine(ex.StackTrace); 74 | } 75 | } 76 | 77 | public static WinBioIdentity AddEnrollment(WinBioSessionHandle session, int unitId, WinBioBiometricSubType subType) 78 | { 79 | Console.WriteLine("Beginning enrollment of {0}:", subType); 80 | WinBio.EnrollBegin(session, subType, unitId); 81 | var code = WinBioErrorCode.MoreData; 82 | for (var swipes = 1; code != WinBioErrorCode.Ok; swipes++) 83 | { 84 | WinBioRejectDetail rejectDetail; 85 | code = WinBio.EnrollCapture(session, out rejectDetail); 86 | switch (code) 87 | { 88 | case WinBioErrorCode.MoreData: 89 | Console.WriteLine("Swipe {0} was good", swipes); 90 | break; 91 | case WinBioErrorCode.BadCapture: 92 | Console.WriteLine("Swipe {0} was bad: {1}", swipes, rejectDetail); 93 | break; 94 | case WinBioErrorCode.Ok: 95 | Console.WriteLine("Enrollment complete with {0} swipes", swipes); 96 | break; 97 | default: 98 | throw new WinBioException(code, "WinBioEnrollCapture failed"); 99 | } 100 | } 101 | Console.WriteLine("Committing enrollment.."); 102 | WinBioIdentity identity; 103 | var isNewTemplate = WinBio.EnrollCommit(session, out identity); 104 | Console.WriteLine(isNewTemplate ? "New template committed." : "Template already existing."); 105 | return identity; 106 | } 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /WindowsFormsTest/WinBioForm.resx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | -------------------------------------------------------------------------------- /WindowsFormsTest/WinBioForm.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace WindowsFormsTest 2 | { 3 | partial class WinBioForm 4 | { 5 | /// 6 | /// Required designer variable. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Clean up any resources being used. 12 | /// 13 | /// true if managed resources should be disposed; otherwise, false. 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Windows Form Designer generated code 24 | 25 | /// 26 | /// Required method for Designer support - do not modify 27 | /// the contents of this method with the code editor. 28 | /// 29 | private void InitializeComponent() 30 | { 31 | this.buttonIdentify = new System.Windows.Forms.Button(); 32 | this.buttonLocateSensor = new System.Windows.Forms.Button(); 33 | this.richTextBox = new System.Windows.Forms.RichTextBox(); 34 | this.buttonCancel = new System.Windows.Forms.Button(); 35 | this.buttonEnroll = new System.Windows.Forms.Button(); 36 | this.btnRebuildDatabase = new System.Windows.Forms.Button(); 37 | this.fingerprintPictureBox = new System.Windows.Forms.PictureBox(); 38 | this.buttonCaptureSample = new System.Windows.Forms.Button(); 39 | ((System.ComponentModel.ISupportInitialize)(this.fingerprintPictureBox)).BeginInit(); 40 | this.SuspendLayout(); 41 | // 42 | // buttonIdentify 43 | // 44 | this.buttonIdentify.Location = new System.Drawing.Point(122, 12); 45 | this.buttonIdentify.Name = "buttonIdentify"; 46 | this.buttonIdentify.Size = new System.Drawing.Size(104, 23); 47 | this.buttonIdentify.TabIndex = 0; 48 | this.buttonIdentify.Text = "Identify"; 49 | this.buttonIdentify.UseVisualStyleBackColor = true; 50 | this.buttonIdentify.Click += new System.EventHandler(this.buttonIdentify_Click); 51 | // 52 | // buttonLocateSensor 53 | // 54 | this.buttonLocateSensor.Location = new System.Drawing.Point(12, 12); 55 | this.buttonLocateSensor.Name = "buttonLocateSensor"; 56 | this.buttonLocateSensor.Size = new System.Drawing.Size(104, 23); 57 | this.buttonLocateSensor.TabIndex = 1; 58 | this.buttonLocateSensor.Text = "LocateSensor"; 59 | this.buttonLocateSensor.UseVisualStyleBackColor = true; 60 | this.buttonLocateSensor.Click += new System.EventHandler(this.buttonLocateSensor_Click); 61 | // 62 | // richTextBox 63 | // 64 | this.richTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 65 | | System.Windows.Forms.AnchorStyles.Left) 66 | | System.Windows.Forms.AnchorStyles.Right))); 67 | this.richTextBox.Location = new System.Drawing.Point(12, 41); 68 | this.richTextBox.Name = "richTextBox"; 69 | this.richTextBox.Size = new System.Drawing.Size(488, 283); 70 | this.richTextBox.TabIndex = 2; 71 | this.richTextBox.Text = ""; 72 | this.richTextBox.TextChanged += new System.EventHandler(this.richTextBox_TextChanged); 73 | // 74 | // buttonCancel 75 | // 76 | this.buttonCancel.Location = new System.Drawing.Point(568, 12); 77 | this.buttonCancel.Name = "buttonCancel"; 78 | this.buttonCancel.Size = new System.Drawing.Size(75, 23); 79 | this.buttonCancel.TabIndex = 3; 80 | this.buttonCancel.Text = "Cancel"; 81 | this.buttonCancel.UseVisualStyleBackColor = true; 82 | this.buttonCancel.Click += new System.EventHandler(this.buttonCancel_Click); 83 | // 84 | // buttonEnroll 85 | // 86 | this.buttonEnroll.Location = new System.Drawing.Point(232, 12); 87 | this.buttonEnroll.Name = "buttonEnroll"; 88 | this.buttonEnroll.Size = new System.Drawing.Size(75, 23); 89 | this.buttonEnroll.TabIndex = 4; 90 | this.buttonEnroll.Text = "Enroll"; 91 | this.buttonEnroll.UseVisualStyleBackColor = true; 92 | this.buttonEnroll.Click += new System.EventHandler(this.buttonEnroll_Click); 93 | // 94 | // btnRebuildDatabase 95 | // 96 | this.btnRebuildDatabase.Location = new System.Drawing.Point(312, 12); 97 | this.btnRebuildDatabase.Name = "btnRebuildDatabase"; 98 | this.btnRebuildDatabase.Size = new System.Drawing.Size(107, 23); 99 | this.btnRebuildDatabase.TabIndex = 7; 100 | this.btnRebuildDatabase.Text = "Rebuild Database"; 101 | this.btnRebuildDatabase.UseVisualStyleBackColor = true; 102 | this.btnRebuildDatabase.Click += new System.EventHandler(this.btnRebuildDatabase_Click); 103 | // 104 | // fingerprintPictureBox 105 | // 106 | this.fingerprintPictureBox.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Zoom; 107 | this.fingerprintPictureBox.Location = new System.Drawing.Point(506, 41); 108 | this.fingerprintPictureBox.Name = "fingerprintPictureBox"; 109 | this.fingerprintPictureBox.Size = new System.Drawing.Size(137, 283); 110 | this.fingerprintPictureBox.TabIndex = 8; 111 | this.fingerprintPictureBox.TabStop = false; 112 | // 113 | // buttonCaptureSample 114 | // 115 | this.buttonCaptureSample.Location = new System.Drawing.Point(425, 12); 116 | this.buttonCaptureSample.Name = "buttonCaptureSample"; 117 | this.buttonCaptureSample.Size = new System.Drawing.Size(101, 23); 118 | this.buttonCaptureSample.TabIndex = 9; 119 | this.buttonCaptureSample.Text = "CaptureSample"; 120 | this.buttonCaptureSample.UseVisualStyleBackColor = true; 121 | this.buttonCaptureSample.Click += new System.EventHandler(this.buttonCaptureSample_Click); 122 | // 123 | // WinBioForm 124 | // 125 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); 126 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 127 | this.ClientSize = new System.Drawing.Size(655, 336); 128 | this.Controls.Add(this.buttonCaptureSample); 129 | this.Controls.Add(this.fingerprintPictureBox); 130 | this.Controls.Add(this.btnRebuildDatabase); 131 | this.Controls.Add(this.buttonEnroll); 132 | this.Controls.Add(this.buttonCancel); 133 | this.Controls.Add(this.richTextBox); 134 | this.Controls.Add(this.buttonLocateSensor); 135 | this.Controls.Add(this.buttonIdentify); 136 | this.Name = "WinBioForm"; 137 | this.Text = "WinBioForm"; 138 | this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.WinBioForm_FormClosing); 139 | ((System.ComponentModel.ISupportInitialize)(this.fingerprintPictureBox)).EndInit(); 140 | this.ResumeLayout(false); 141 | 142 | } 143 | 144 | #endregion 145 | 146 | private System.Windows.Forms.Button buttonIdentify; 147 | private System.Windows.Forms.Button buttonLocateSensor; 148 | private System.Windows.Forms.RichTextBox richTextBox; 149 | private System.Windows.Forms.Button buttonCancel; 150 | private System.Windows.Forms.Button buttonEnroll; 151 | private System.Windows.Forms.Button btnRebuildDatabase; 152 | private System.Windows.Forms.PictureBox fingerprintPictureBox; 153 | private System.Windows.Forms.Button buttonCaptureSample; 154 | } 155 | } 156 | 157 | -------------------------------------------------------------------------------- /WinBioNET/WinBioConfiguration.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Linq; 4 | using Microsoft.Win32; 5 | using WinBioNET.Configuration; 6 | using WinBioNET.Enums; 7 | 8 | namespace WinBioNET 9 | { 10 | public class WinBioConfiguration 11 | { 12 | private const string DatabaseKeyName = @"SYSTEM\CurrentControlSet\Services\WbioSrvc\Databases"; 13 | private const string UnitKeyName = @"System\CurrentControlSet\Enum\{0}\Device Parameters\WinBio\Configurations"; 14 | 15 | private static string KeyGuid(Guid guid) 16 | { 17 | return guid.ToString("B").ToUpperInvariant(); 18 | } 19 | 20 | /// 21 | /// Determines whether the given database exists. 22 | /// 23 | public static bool DatabaseExists(Guid databaseId) 24 | { 25 | return WinBio.EnumDatabases(WinBioBiometricType.Fingerprint).Any(_ => _.DatabaseId == databaseId); 26 | } 27 | 28 | /// 29 | /// Adds a new biometric database compatible to the given unit. 30 | /// Throws an exception if the database already exists. 31 | /// 32 | public static void AddDatabase(Guid databaseId, int unitId) 33 | { 34 | // throw exception if the database already exists 35 | var databases = WinBio.EnumDatabases(WinBioBiometricType.Fingerprint); 36 | if (databases.Any(_ => _.DatabaseId == databaseId)) 37 | { 38 | throw new WinBioException(string.Format("Database already exists: {0}", databaseId)); 39 | } 40 | // get first system sensor config for the given unitId 41 | var unitSchema = WinBio.EnumBiometricUnits(WinBioBiometricType.Fingerprint).Single(_ => _.UnitId == unitId); 42 | var unitName = string.Format(UnitKeyName, unitSchema.DeviceInstanceId); 43 | WinBioSensorKey systemSensorConfig = null; 44 | using (var unitKey = Registry.LocalMachine.OpenSubKey(unitName, true)) 45 | { 46 | if (unitKey == null) throw new Exception("wtf"); 47 | foreach (var confName in unitKey.GetSubKeyNames()) 48 | { 49 | int number; 50 | if (!int.TryParse(confName, out number)) continue; 51 | var config = new WinBioSensorKey(); 52 | using (var confKey = unitKey.OpenSubKey(confName)) 53 | { 54 | config.Read(confKey); 55 | } 56 | if (config.SystemSensor == 1) 57 | { 58 | systemSensorConfig = config; 59 | break; 60 | } 61 | } 62 | } 63 | if (systemSensorConfig == null) throw new Exception("dafuq"); 64 | // get the corresponding database 65 | var database = databases.Single(_ => _.DatabaseId == systemSensorConfig.DatabaseId); 66 | // create new compatible database 67 | var newDatabase = new WinBioDatabaseKey(database); 68 | // write database configuration to registry 69 | using (var databasesKey = Registry.LocalMachine.OpenSubKey(DatabaseKeyName, true)) 70 | { 71 | if (databasesKey == null) throw new Exception("wat?"); 72 | using (var newKey = databasesKey.CreateSubKey(KeyGuid(databaseId))) 73 | { 74 | newDatabase.Write(newKey); 75 | } 76 | } 77 | } 78 | 79 | /// 80 | /// Removes the given biometric database and all its data. 81 | /// Also removes all units from the corresponding sensor pool. 82 | /// 83 | public static void RemoveDatabase(Guid databaseId) 84 | { 85 | // find database, throws if not found 86 | var database = WinBio.EnumDatabases(WinBioBiometricType.Fingerprint).Single(_ => _.DatabaseId == databaseId); 87 | 88 | // delete template file, throws if not authorized 89 | // make sure to grant permissions to folder C:\WINDOWS\SYSTEM32\WINBIODATABASE or similar in your machine 90 | // get ownership of the folder WINBIODATABASE then grant full control for your user 91 | if (File.Exists(database.FilePath)) 92 | { 93 | File.Delete(database.FilePath); 94 | } 95 | else 96 | { 97 | // For 32-bits process running in 64 bits OS 98 | string windowsPath = Environment.GetFolderPath(Environment.SpecialFolder.Windows); 99 | string filePath = string.Format(@"{0}\SYSTEM32", windowsPath); 100 | string filePathSysNative = string.Format(@"{0}\SysNative", windowsPath); 101 | 102 | if (File.Exists(database.FilePath.Replace(filePath, filePathSysNative))) 103 | { 104 | File.Delete(database.FilePath.Replace(filePath, filePathSysNative)); 105 | } 106 | } 107 | // erase sensor configurations for this database 108 | foreach (var unitSchema in WinBio.EnumBiometricUnits(WinBioBiometricType.Fingerprint)) 109 | { 110 | var unitName = string.Format(UnitKeyName, unitSchema.DeviceInstanceId); 111 | using (var unitKey = Registry.LocalMachine.OpenSubKey(unitName, true)) 112 | { 113 | if (unitKey == null) continue; 114 | foreach (var confName in unitKey.GetSubKeyNames()) 115 | { 116 | int number; 117 | if (!int.TryParse(confName, out number)) continue; 118 | var config = new WinBioSensorKey(); 119 | using (var confKey = unitKey.OpenSubKey(confName)) 120 | { 121 | config.Read(confKey); 122 | } 123 | if (config.DatabaseId == databaseId) 124 | { 125 | unitKey.DeleteSubKey(confName); 126 | } 127 | } 128 | } 129 | } 130 | // erase database configuration from registry 131 | using (var databasesKey = Registry.LocalMachine.OpenSubKey(DatabaseKeyName, true)) 132 | { 133 | if (databasesKey == null) throw new Exception("wat?"); 134 | databasesKey.DeleteSubKey(KeyGuid(databaseId)); 135 | } 136 | } 137 | 138 | /// 139 | /// Adds a unit to the sensor pool related to the given biometric database. 140 | /// 141 | public static void AddUnit(Guid databaseId, int unitId) 142 | { 143 | var unitSchema = WinBio.EnumBiometricUnits(WinBioBiometricType.Fingerprint).Single(_ => _.UnitId == unitId); 144 | var unitName = string.Format(UnitKeyName, unitSchema.DeviceInstanceId); 145 | var highest = -1; 146 | WinBioSensorKey newConfig = null; 147 | using (var unitKey = Registry.LocalMachine.OpenSubKey(unitName, true)) 148 | { 149 | if (unitKey == null) throw new Exception("wtf"); 150 | foreach (var confName in unitKey.GetSubKeyNames()) 151 | { 152 | int number; 153 | if (!int.TryParse(confName, out number)) continue; 154 | if (number > highest) highest = number; 155 | if (newConfig != null) continue; 156 | var config = new WinBioSensorKey(); 157 | using (var confKey = unitKey.OpenSubKey(confName)) 158 | { 159 | config.Read(confKey); 160 | } 161 | if (config.SystemSensor == 1) 162 | { 163 | newConfig = config; 164 | } 165 | } 166 | if (newConfig == null || highest < 0) throw new Exception("dafuq"); 167 | // write to registry at the next highest free number 168 | highest++; 169 | newConfig.DatabaseId = databaseId; 170 | newConfig.SystemSensor = 0; 171 | using (var confKey = unitKey.CreateSubKey(highest.ToString())) 172 | { 173 | newConfig.Write(confKey); 174 | } 175 | } 176 | } 177 | 178 | /// 179 | /// Adds a unit to the sensor pool related to the given biometric database. 180 | /// 181 | public static void RemoveUnit(Guid databaseId, int unitId) 182 | { 183 | var unitSchema = WinBio.EnumBiometricUnits(WinBioBiometricType.Fingerprint).Single(_ => _.UnitId == unitId); 184 | var unitName = string.Format(UnitKeyName, unitSchema.DeviceInstanceId); 185 | using (var unitKey = Registry.LocalMachine.OpenSubKey(unitName, true)) 186 | { 187 | if (unitKey == null) throw new Exception("wtf"); 188 | foreach (var confName in unitKey.GetSubKeyNames()) 189 | { 190 | int number; 191 | if (!int.TryParse(confName, out number)) continue; 192 | var config = new WinBioSensorKey(); 193 | using (var confKey = unitKey.OpenSubKey(confName)) 194 | { 195 | config.Read(confKey); 196 | } 197 | // there should be only one but we will remove all anyway 198 | if (config.DatabaseId == databaseId) 199 | { 200 | unitKey.DeleteSubKey(confName); 201 | } 202 | } 203 | } 204 | } 205 | } 206 | } 207 | -------------------------------------------------------------------------------- /WindowsFormsTest/WinBioForm.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Drawing; 3 | using System.Threading; 4 | using System.Windows.Forms; 5 | using System.ServiceProcess; 6 | using WinBioNET; 7 | using WinBioNET.Enums; 8 | 9 | namespace WindowsFormsTest 10 | { 11 | public partial class WinBioForm 12 | : Form 13 | { 14 | private static readonly Guid DatabaseId = Guid.Parse("BC7263C3-A7CE-49F3-8EBF-D47D74863CC6"); 15 | private WinBioSessionHandle _session; 16 | private int _unitId; 17 | 18 | public WinBioForm() 19 | { 20 | InitializeComponent(); 21 | } 22 | 23 | protected void Log(string message) 24 | { 25 | if (richTextBox.InvokeRequired) 26 | { 27 | richTextBox.Invoke(new Action(Log), message); 28 | return; 29 | } 30 | richTextBox.AppendText(message + "\n"); 31 | } 32 | 33 | protected void Log(WinBioException exception) 34 | { 35 | Log(exception.Message); 36 | } 37 | 38 | protected override void OnLoad(EventArgs e) 39 | { 40 | var units = WinBio.EnumBiometricUnits(WinBioBiometricType.Fingerprint); 41 | Log(string.Format("Found {0} units", units.Length)); 42 | 43 | // Check if we have a connected fingerprint sensor 44 | if (units.Length == 0) 45 | { 46 | MessageBox.Show("Error: Fingerprint sensor not found! Exiting...", "Error", MessageBoxButtons.OK); 47 | Application.Exit(); 48 | return; 49 | } 50 | 51 | var unit = units[0]; 52 | _unitId = unit.UnitId; 53 | Log(string.Format("Using unit id: {0}", _unitId)); 54 | Log(string.Format("Device instance id: {0}", unit.DeviceInstanceId)); 55 | Log(string.Format("Using database: {0}", DatabaseId)); 56 | 57 | // Check if we need to create a new database 58 | if (WinBioConfiguration.DatabaseExists(DatabaseId) == false) 59 | { 60 | InitialStart(); 61 | } 62 | else 63 | { 64 | OpenBiometricSession(); 65 | } 66 | } 67 | 68 | private void OpenBiometricSession() 69 | { 70 | _session = WinBio.OpenSession(WinBioBiometricType.Fingerprint, WinBioPoolType.System, WinBioSessionFlag.Raw, null, WinBioDatabaseId.Default); 71 | Log("Session opened: " + _session.Value); 72 | } 73 | 74 | private void WinBioForm_FormClosing(object sender, FormClosingEventArgs e) 75 | { 76 | if (!_session.IsValid) return; 77 | WinBio.CloseSession(_session); 78 | _session.Invalidate(); 79 | Log("Session closed"); 80 | } 81 | 82 | private void buttonLocateSensor_Click(object sender, EventArgs e) 83 | { 84 | ThreadPool.QueueUserWorkItem(delegate 85 | { 86 | Log("Locating sensor..."); 87 | try 88 | { 89 | var unitId = WinBio.LocateSensor(_session); 90 | Log(string.Format("Sensor located: unit id {0}", unitId)); 91 | } 92 | catch (WinBioException ex) 93 | { 94 | Log(ex); 95 | } 96 | }); 97 | } 98 | 99 | private void buttonIdentify_Click(object sender, EventArgs e) 100 | { 101 | ThreadPool.QueueUserWorkItem(delegate 102 | { 103 | Log("Identifying user..."); 104 | try 105 | { 106 | WinBioIdentity identity; 107 | WinBioBiometricSubType subFactor; 108 | WinBioRejectDetail rejectDetail; 109 | WinBio.Identify(_session, out identity, out subFactor, out rejectDetail); 110 | Log(string.Format("Identity: {0}", identity)); 111 | } 112 | catch (WinBioException ex) 113 | { 114 | Log(ex); 115 | } 116 | }); 117 | } 118 | 119 | private void buttonEnroll_Click(object sender, EventArgs e) 120 | { 121 | ThreadPool.QueueUserWorkItem(delegate 122 | { 123 | try 124 | { 125 | var identity = AddEnrollment(_session, _unitId, WinBioBiometricSubType.RhIndexFinger); 126 | Log(string.Format("Identity: {0}", identity)); 127 | } 128 | catch (WinBioException ex) 129 | { 130 | Log(ex); 131 | } 132 | }); 133 | } 134 | 135 | private void buttonCancel_Click(object sender, EventArgs e) 136 | { 137 | WinBio.Cancel(_session); 138 | } 139 | 140 | private WinBioIdentity AddEnrollment(WinBioSessionHandle session, int unitId, WinBioBiometricSubType subType) 141 | { 142 | Log(string.Format("Beginning enrollment of {0}:", subType)); 143 | WinBio.EnrollBegin(session, subType, unitId); 144 | var code = WinBioErrorCode.MoreData; 145 | for (var swipes = 1; code != WinBioErrorCode.Ok; swipes++) 146 | { 147 | WinBioRejectDetail rejectDetail; 148 | code = WinBio.EnrollCapture(session, out rejectDetail); 149 | switch (code) 150 | { 151 | case WinBioErrorCode.MoreData: 152 | Log(string.Format("Swipe {0} was good", swipes)); 153 | break; 154 | case WinBioErrorCode.BadCapture: 155 | Log(string.Format("Swipe {0} was bad: {1}", swipes, rejectDetail)); 156 | break; 157 | case WinBioErrorCode.Ok: 158 | Log(string.Format("Enrollment complete with {0} swipes", swipes)); 159 | break; 160 | default: 161 | throw new WinBioException(code, "WinBioEnrollCapture failed"); 162 | } 163 | } 164 | Log(string.Format("Committing enrollment..")); 165 | WinBioIdentity identity; 166 | var isNewTemplate = WinBio.EnrollCommit(session, out identity); 167 | Log(string.Format(isNewTemplate ? "New template committed." : "Template already existing.")); 168 | return identity; 169 | } 170 | 171 | private void btnRebuildDatabase_Click(object sender, EventArgs e) 172 | { 173 | // Close existing session 174 | if (_session.IsValid) 175 | { 176 | WinBio.Cancel(_session); 177 | } 178 | 179 | InitialStart(); 180 | } 181 | 182 | private void InitialStart() 183 | { 184 | // Stop Windows Biometric Service to apply changes 185 | RestartService("WbioSrvc", 5000, ServiceMode.Stop); 186 | 187 | var databases = WinBio.EnumDatabases(WinBioBiometricType.Fingerprint); 188 | Console.WriteLine("Found {0} databases", databases.Length); 189 | for (var i = 0; i < databases.Length; i++) 190 | { 191 | Console.WriteLine("DatabaseId {0}: {1}", i, databases[i].DatabaseId); 192 | } 193 | if (WinBioConfiguration.DatabaseExists(DatabaseId)) 194 | { 195 | Console.WriteLine("Removing database: {0}", DatabaseId); 196 | WinBioConfiguration.RemoveDatabase(DatabaseId); 197 | } 198 | 199 | // Start Windows Biometric Service to apply changes 200 | RestartService("WbioSrvc", 5000, ServiceMode.Start); 201 | 202 | Console.WriteLine("Creating database: {0}", DatabaseId); 203 | WinBioConfiguration.AddDatabase(DatabaseId, _unitId); 204 | Console.WriteLine("Adding sensor to the pool: {0}", _unitId); 205 | WinBioConfiguration.AddUnit(DatabaseId, _unitId); 206 | 207 | // Restart Windows Biometric Service to apply changes 208 | RestartService("WbioSrvc", 5000, ServiceMode.Restart); 209 | 210 | Log("Successfully recreated database."); 211 | 212 | OpenBiometricSession(); 213 | } 214 | 215 | public enum ServiceMode 216 | { 217 | Restart, 218 | Stop, 219 | Start 220 | } 221 | 222 | private void RestartService(string serviceName, int timeoutMilliseconds, ServiceMode serviceMode) 223 | { 224 | ServiceController service = new ServiceController(serviceName); 225 | try 226 | { 227 | int millisec1 = Environment.TickCount; 228 | TimeSpan timeout = TimeSpan.FromMilliseconds(timeoutMilliseconds); 229 | 230 | if (serviceMode == ServiceMode.Start) 231 | goto start; 232 | 233 | service.Stop(); 234 | service.WaitForStatus(ServiceControllerStatus.Stopped, timeout); 235 | 236 | if (serviceMode == ServiceMode.Stop) 237 | return; 238 | 239 | service.Start(); 240 | 241 | start: 242 | // count the rest of the timeout 243 | int millisec2 = Environment.TickCount; 244 | timeout = TimeSpan.FromMilliseconds(timeoutMilliseconds - (millisec2 - millisec1)); 245 | 246 | service.WaitForStatus(ServiceControllerStatus.Running, timeout); 247 | } 248 | catch 249 | { 250 | MessageBox.Show("Error restarting Windows Biometric Service", "Error", MessageBoxButtons.OK); 251 | } 252 | } 253 | 254 | private void richTextBox_TextChanged(object sender, EventArgs e) 255 | { 256 | // set the current caret position to the end 257 | richTextBox.SelectionStart = richTextBox.Text.Length; 258 | 259 | // scroll it automatically 260 | richTextBox.ScrollToCaret(); 261 | } 262 | 263 | private void buttonCaptureSample_Click(object sender, EventArgs e) 264 | { 265 | ThreadPool.QueueUserWorkItem(delegate 266 | { 267 | Bitmap image; 268 | WinBioRejectDetail rejectDetail; 269 | Log("Capturing sample..."); 270 | try 271 | { 272 | WinBio.CaptureSample(_session, WinBioBirPurpose.NoPurposeAvailable, WinBioBirDataFlags.Raw, out rejectDetail, out image); 273 | if (rejectDetail != WinBioRejectDetail.None) 274 | { 275 | Log(string.Format("CaptureSample failed! Reject detail: {0}", rejectDetail)); 276 | } 277 | else 278 | { 279 | Log("Captured sample successfully!"); 280 | this.fingerprintPictureBox.BackgroundImage = image; 281 | } 282 | } 283 | catch (WinBioException ex) 284 | { 285 | Log(ex); 286 | } 287 | }); 288 | } 289 | } 290 | } 291 | -------------------------------------------------------------------------------- /WinBioNET/Enums/WinBioErrorCode.cs: -------------------------------------------------------------------------------- 1 | namespace WinBioNET.Enums 2 | { 3 | /// 4 | /// Error conditions -- values are in the range: 0x8001 - 0xFFFF 5 | /// Informational messages -- values are in the range: 0x0001 - 0x7FFF 6 | /// TODO: WinError.h contains more errors which are missing here 7 | /// 8 | public enum WinBioErrorCode 9 | : uint 10 | { 11 | /// 12 | /// Ok 13 | /// 14 | Ok = 0, 15 | 16 | /// 17 | /// False 18 | /// 19 | False = 1, 20 | 21 | /// 22 | /// General access denied error 23 | /// 24 | AccessDenied = 0x80070005, 25 | 26 | /// 27 | /// Not implemented 28 | /// 29 | NotImplemented = 0x80004001, 30 | 31 | /// 32 | /// Invalid arguments 33 | /// 34 | InvalidArguments = 0x80070057, 35 | 36 | /// 37 | /// Invalid pointer 38 | /// 39 | InvalidPointer = 0x80004003, 40 | 41 | /// 42 | /// Invalid handle 43 | /// 44 | InvalidHandle = 0x80070006, 45 | 46 | /// 47 | /// Windows Biometric Service doesn't support the specified biometric factor. 48 | /// 49 | UnsupportedFactor = 0x80098001, 50 | 51 | /// 52 | /// The unit ID number doesn't correspond to a valid biometric device. 53 | /// 54 | InvalidUnit = 0x80098002, 55 | 56 | /// 57 | /// The biometric sample doesn't match any known identity. 58 | /// 59 | UnknownID = 0x80098003, 60 | 61 | /// 62 | /// The biometric operation was canceled before it could complete. 63 | /// 64 | Canceled = 0x80098004, 65 | 66 | /// 67 | /// The biometric sample doesn't match the specified identity or sub-factor. 68 | /// 69 | NoMatch = 0x80098005, 70 | 71 | /// 72 | /// A biometric sample could not be captured because the operation was aborted. 73 | /// 74 | CaptureAborted = 0x80098006, 75 | 76 | /// 77 | /// An enrollment transaction could not be started because another enrollment is already in progress. 78 | /// 79 | EnrollmentInProgress = 0x80098007, 80 | 81 | /// 82 | /// The captured sample cannot be used for any further biometric operations. 83 | /// 84 | BadCapture = 0x80098008, 85 | 86 | /// 87 | /// The biometric unit doesn't support the specified unit control code. 88 | /// 89 | InvalidControlCode = 0x80098009, 90 | 91 | /// 92 | /// The driver already has a pending data collection operation in progress. 93 | /// 94 | DataCollectionInProgress = 0x8009800B, 95 | 96 | /// 97 | /// The biometric sensor driver does not support the requested data format. 98 | /// 99 | UnsupportedDataFormat = 0x8009800C, 100 | 101 | /// 102 | /// The biometric sensor driver does not support the requested data type. 103 | /// 104 | UnsupportedDataType = 0x8009800D, 105 | 106 | /// 107 | /// The biometric sensor driver does not support the requested data purpose. 108 | /// 109 | UnsupportedPurpose = 0x8009800E, 110 | 111 | /// 112 | /// The biometric unit is not in the proper state to perform the specified operation. 113 | /// 114 | InvalidDeviceState = 0x8009800F, 115 | 116 | /// 117 | /// The operation could not be performed because the sensor device was busy. 118 | /// 119 | DeviceBusy = 0x80098010, 120 | 121 | /// 122 | /// The biometric unit's storage adapter was unable to create a new database. 123 | /// 124 | DatabaseCantCreate = 0x80098011, 125 | 126 | /// 127 | /// The biometric unit's storage adapter was unable to open an existing database. 128 | /// 129 | DatabaseCantOpen = 0x80098012, 130 | 131 | /// 132 | /// The biometric unit's storage adapter was unable to close a database. 133 | /// 134 | DatabaseCantClose = 0x80098013, 135 | 136 | /// 137 | /// The biometric unit's storage adapter was unable to erase a database. 138 | /// 139 | DatabaseCantErase = 0x80098014, 140 | 141 | /// 142 | /// The biometric unit's storage adapter was unable to find a database. 143 | /// 144 | DatabaseCantFind = 0x80098015, 145 | 146 | /// 147 | /// The biometric unit's storage adapter was unable to create a database because that database already exists. 148 | /// 149 | DatabaseAlreadyExists = 0x80098016, 150 | 151 | /// 152 | /// The biometric unit's storage adapter was unable to add a record to the database because the database is full. 153 | /// 154 | DatabaseFull = 0x80098018, 155 | 156 | /// 157 | /// The database is locked and its contents are inaccessible. 158 | /// 159 | DatabaseLocked = 0x80098019, 160 | 161 | /// 162 | /// The contents of the database have become corrupted and are inaccessible. 163 | /// 164 | DatabaseCorrupted = 0x8009801A, 165 | 166 | /// 167 | /// No records were deleted because the specified identity and sub-factor are not present in the database. 168 | /// 169 | DatabaseNoSuchRecord = 0x8009801B, 170 | 171 | /// 172 | /// The specified identity and sub-factor are already enrolled in the database. 173 | /// 174 | DuplicateEnrollment = 0x8009801C, 175 | 176 | /// 177 | /// An error occurred while trying to read from the database. 178 | /// 179 | DatabaseReadError = 0x8009801D, 180 | 181 | /// 182 | /// An error occurred while trying to write to the database. 183 | /// 184 | DatabaseWriteError = 0x8009801E, 185 | 186 | /// 187 | /// No records in the database matched the query. 188 | /// 189 | DatabaseNoResults = 0x8009801F, 190 | 191 | /// 192 | /// All records from the most recent database query have been viewed. 193 | /// 194 | DatabaseNoMoreRecords = 0x80098020, 195 | 196 | /// 197 | /// A database operation unexpectedly encountered the end of the file. 198 | /// 199 | DatabaseEof = 0x80098021, 200 | 201 | /// 202 | /// A database operation failed due to a malformed index vector. 203 | /// 204 | DatabaseBadIndexVector = 0x80098022, 205 | 206 | /// 207 | /// The biometric unit doesn't belong to the specified service provider. 208 | /// 209 | IncorrectBsp = 0x80098024, 210 | 211 | /// 212 | /// The biometric unit doesn't belong to the specified sensor pool. 213 | /// 214 | IncorrectSensorPool = 0x80098025, 215 | 216 | /// 217 | /// The sensor adapter's capture buffer is empty. 218 | /// 219 | NoCaptureData = 0x80098026, 220 | 221 | /// 222 | /// The sensor adapter doesn't support the sensor mode specified in the configuration. 223 | /// 224 | InvalidSensorMode = 0x80098027, 225 | 226 | /// 227 | /// The requested operation cannot be performed due to a locking conflict. 228 | /// 229 | LockViolation = 0x8009802A, 230 | 231 | /// 232 | /// The data in a biometric template matches another template already in the database. 233 | /// 234 | DuplicateTemplate = 0x8009802B, 235 | 236 | /// 237 | /// The requested operation is not valid for the current state of the session or biometric unit. 238 | /// 239 | InvalidOperation = 0x8009802C, 240 | 241 | /// 242 | /// The session cannot begin a new operation because another operation is already in progress. 243 | /// 244 | SessionBusy = 0x8009802D, 245 | 246 | /// 247 | /// System policy settings have disabled the Windows biometric credential provider. 248 | /// 249 | CredProvDisabled = 0x80098030, 250 | 251 | /// 252 | /// The requested credential was not found. 253 | /// 254 | CredProvNoCredential = 0x80098031, 255 | 256 | /// 257 | /// System policy settings have disabled the Windows biometric service. 258 | /// 259 | Disabled = 0x80098032, 260 | 261 | /// 262 | /// The biometric unit could not be configured. 263 | /// 264 | ConfigurationFailure = 0x80098033, 265 | 266 | /// 267 | /// A private pool cannot be created because one or more biometric units are not available. 268 | /// 269 | SensorUnavailable = 0x80098034, 270 | 271 | /// 272 | /// A secure attention sequence (CTRL-ALT-DEL) is required for logon. 273 | /// 274 | SasEnabled = 0x80098035, 275 | 276 | /// 277 | /// A biometric sensor has failed. 278 | /// 279 | DeviceFailure = 0x80098036, 280 | 281 | /// 282 | /// Fast user switching is disabled. 283 | /// 284 | FastUserSwitchDisabled = 0x80098037, 285 | 286 | /// 287 | /// The System sensor pool cannot be opened from Terminal Server client sessions. 288 | /// 289 | NotActiveConsole = 0x80098038, 290 | 291 | /// 292 | /// There is already an active event monitor associated with the specified session. 293 | /// 294 | EventMonitorActive = 0x80098039, 295 | 296 | /// 297 | /// The value specified is not a valid property type. 298 | /// 299 | InvalidPropertyType = 0x8009803A, 300 | 301 | /// 302 | /// The value specified is not a valid property ID. 303 | /// 304 | InvalidPropertyID = 0x8009803B, 305 | 306 | /// 307 | /// The biometric unit doesn't support the specified property. 308 | /// 309 | UnsupportedProperty = 0x8009803C, 310 | 311 | /// 312 | /// The adapter binary did not pass its integrity check. 313 | /// 314 | AdapterIntegrityFailure = 0x8009803D, 315 | 316 | /// 317 | /// Informational messages: 318 | /// Another sample is needed for the current enrollment template. 319 | /// 320 | MoreData = 0x00090001, 321 | } 322 | } -------------------------------------------------------------------------------- /WinBioNET/WinBio.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Drawing; 3 | using System.Drawing.Imaging; 4 | using System.IO; 5 | using System.Runtime.InteropServices; 6 | using WinBioNET.Enums; 7 | 8 | namespace WinBioNET 9 | { 10 | //[SuppressUnmanagedCodeSecurity] 11 | public class WinBio 12 | { 13 | protected const string LibName = "winbio.dll"; 14 | 15 | [DllImport(LibName, EntryPoint = "WinBioOpenSession")] 16 | private extern static WinBioErrorCode OpenSession( 17 | WinBioBiometricType factor, 18 | WinBioPoolType poolType, 19 | WinBioSessionFlag flags, 20 | int[] unitArray, 21 | int unitCount, 22 | IntPtr databaseId, 23 | out WinBioSessionHandle sessionHandle); 24 | 25 | [DllImport(LibName, EntryPoint = "WinBioOpenSession")] 26 | private extern static WinBioErrorCode OpenSession( 27 | WinBioBiometricType factor, 28 | WinBioPoolType poolType, 29 | WinBioSessionFlag flags, 30 | int[] unitArray, 31 | int unitCount, 32 | [MarshalAs(UnmanagedType.LPStruct)] 33 | Guid databaseId, 34 | out WinBioSessionHandle sessionHandle); 35 | 36 | private static WinBioSessionHandle OpenSession(WinBioBiometricType factor, WinBioPoolType poolType, WinBioSessionFlag flags, int[] unitArray, IntPtr databaseId) 37 | { 38 | WinBioSessionHandle sessionHandle; 39 | var code = OpenSession(factor, poolType, flags, unitArray, unitArray == null ? 0 : unitArray.Length, databaseId, out sessionHandle); 40 | WinBioException.ThrowOnError(code, "WinBioOpenSession failed"); 41 | return sessionHandle; 42 | } 43 | 44 | public static WinBioSessionHandle OpenSession(WinBioBiometricType factor, WinBioPoolType poolType, WinBioSessionFlag flags, int[] unitArray, Guid databaseId) 45 | { 46 | WinBioSessionHandle sessionHandle; 47 | var code = OpenSession(factor, poolType, flags, unitArray, unitArray.Length, databaseId, out sessionHandle); 48 | WinBioException.ThrowOnError(code, "WinBioOpenSession failed"); 49 | return sessionHandle; 50 | } 51 | 52 | public static WinBioSessionHandle OpenSession(WinBioBiometricType factor, WinBioPoolType poolType, WinBioSessionFlag flags, int[] unitArray, WinBioDatabaseId databaseId) 53 | { 54 | return OpenSession(factor, poolType, flags, unitArray, (IntPtr)databaseId); 55 | } 56 | 57 | public static WinBioSessionHandle OpenSession(WinBioBiometricType factor) 58 | { 59 | return OpenSession(factor, WinBioPoolType.System, WinBioSessionFlag.Default, null, WinBioDatabaseId.Default); 60 | } 61 | 62 | [DllImport(LibName, EntryPoint = "WinBioCloseSession")] 63 | private extern static WinBioErrorCode WinBioCloseSession(WinBioSessionHandle sessionHandle); 64 | 65 | public static void CloseSession(WinBioSessionHandle sessionHandle) 66 | { 67 | if (!sessionHandle.IsValid) return; 68 | var code = WinBioCloseSession(sessionHandle); 69 | WinBioException.ThrowOnError(code, "WinBioOpenSession failed"); 70 | sessionHandle.Invalidate(); 71 | } 72 | 73 | [DllImport(LibName, EntryPoint = "WinBioCancel")] 74 | private extern static WinBioErrorCode WinBioCancel(WinBioSessionHandle sessionHandle); 75 | 76 | public static void Cancel(WinBioSessionHandle sessionHandle) 77 | { 78 | var code = WinBioCancel(sessionHandle); 79 | WinBioException.ThrowOnError(code, "WinBioCancel failed"); 80 | } 81 | 82 | [DllImport(LibName, EntryPoint = "WinBioEnumDatabases")] 83 | private extern static WinBioErrorCode EnumDatabases(WinBioBiometricType factor, out IntPtr storageSchemaArray, out int storageCount); 84 | 85 | public static WinBioStorageSchema[] EnumDatabases(WinBioBiometricType factor) 86 | { 87 | IntPtr pointer; 88 | int count; 89 | var code = EnumDatabases(factor, out pointer, out count); 90 | WinBioException.ThrowOnError(code, "WinBioEnumDatabases failed"); 91 | return MarshalArray(pointer, count); 92 | } 93 | 94 | [DllImport(LibName, EntryPoint = "WinBioCaptureSample")] 95 | private extern static WinBioErrorCode CaptureSample( 96 | WinBioSessionHandle sessionHandle, 97 | WinBioBirPurpose purpose, 98 | WinBioBirDataFlags flags, 99 | out int unitId, 100 | out IntPtr sample, 101 | out int sampleSize, 102 | out WinBioRejectDetail rejectDetail); 103 | 104 | public static int CaptureSample( 105 | WinBioSessionHandle sessionHandle, 106 | WinBioBirPurpose purpose, 107 | WinBioBirDataFlags flags, 108 | out WinBioRejectDetail rejectDetail, 109 | out Bitmap fingerprintImage) 110 | { 111 | int unitId; 112 | int sampleSize; 113 | IntPtr samplePointer; 114 | var code = CaptureSample(sessionHandle, purpose, flags, out unitId, out samplePointer, out sampleSize, out rejectDetail); 115 | WinBioException.ThrowOnError(code, "WinBioCaptureSample failed"); 116 | WinBioBir sample = (WinBioBir)Marshal.PtrToStructure(samplePointer, typeof(WinBioBir)); 117 | 118 | if (sample.StandardDataBlock.Size == 0) 119 | { 120 | throw new WinBioException("Your fingerprint sensor doesn't support StandardDataBlock"); 121 | } 122 | 123 | IntPtr birHeaderPointer = samplePointer + sample.HeaderBlock.Offset; 124 | IntPtr ansiHeaderPointer = samplePointer + sample.StandardDataBlock.Offset; 125 | IntPtr ansiRecordPointer = ansiHeaderPointer + Marshal.SizeOf(typeof(WinBioBdbAnsi381Header)); 126 | 127 | WinBioBdbAnsi381Record ansiRecord = (WinBioBdbAnsi381Record)Marshal.PtrToStructure( 128 | ansiRecordPointer, typeof(WinBioBdbAnsi381Record)); 129 | 130 | Size imageSize = new Size(ansiRecord.HorizontalLineLength, ansiRecord.VerticalLineLength); 131 | IntPtr firstPixelPointer = ansiRecordPointer + Marshal.SizeOf(typeof(WinBioBdbAnsi381Record)); 132 | 133 | fingerprintImage = new Bitmap(imageSize.Width, imageSize.Height, 1 * imageSize.Width, PixelFormat.Format8bppIndexed, firstPixelPointer); 134 | ColorPalette palette = fingerprintImage.Palette; 135 | for (int i = 0; i <= 255; i++) 136 | { 137 | palette.Entries[i] = Color.FromArgb(i, i, i); 138 | } 139 | fingerprintImage.Palette = palette; 140 | 141 | Free(samplePointer); 142 | 143 | return unitId; 144 | } 145 | 146 | [DllImport(LibName, EntryPoint = "WinBioLocateSensor")] 147 | private extern static WinBioErrorCode LocateSensor(WinBioSessionHandle sessionHandle, out int unitId); 148 | 149 | public static int LocateSensor(WinBioSessionHandle sessionHandle) 150 | { 151 | int unitId; 152 | var code = LocateSensor(sessionHandle, out unitId); 153 | WinBioException.ThrowOnError(code, "WinBioLocateSensor failed"); 154 | return unitId; 155 | } 156 | 157 | [DllImport(LibName, EntryPoint = "WinBioEnumBiometricUnits")] 158 | private extern static WinBioErrorCode EnumBiometricUnits(WinBioBiometricType factor, out IntPtr unitSchemaArray, out int unitCount); 159 | 160 | public static WinBioUnitSchema[] EnumBiometricUnits(WinBioBiometricType factor) 161 | { 162 | IntPtr pointer; 163 | int count; 164 | var code = EnumBiometricUnits(factor, out pointer, out count); 165 | WinBioException.ThrowOnError(code, "WinBioEnumBiometricUnits failed"); 166 | return MarshalArray(pointer, count); 167 | } 168 | 169 | [DllImport(LibName, EntryPoint = "WinBioIdentify")] 170 | private extern static WinBioErrorCode Identify( 171 | WinBioSessionHandle sessionHandle, 172 | out int unitId, 173 | IntPtr identity, 174 | out WinBioBiometricSubType subFactor, 175 | out WinBioRejectDetail rejectDetail); 176 | 177 | public static int Identify( 178 | WinBioSessionHandle sessionHandle, 179 | out WinBioIdentity identity, 180 | out WinBioBiometricSubType subFactor, 181 | out WinBioRejectDetail rejectDetail) 182 | { 183 | int unitId; 184 | var bytes = new byte[WinBioIdentity.Size]; 185 | var handle = GCHandle.Alloc(bytes, GCHandleType.Pinned); 186 | try 187 | { 188 | var code = Identify(sessionHandle, out unitId, handle.AddrOfPinnedObject(), out subFactor, out rejectDetail); 189 | WinBioException.ThrowOnError(code, "WinBioIdentify failed"); 190 | } 191 | finally 192 | { 193 | handle.Free(); 194 | } 195 | identity = new WinBioIdentity(bytes); 196 | return unitId; 197 | } 198 | 199 | [DllImport(LibName, EntryPoint = "WinBioEnumEnrollments")] 200 | private extern static WinBioErrorCode EnumEnrollments( 201 | WinBioSessionHandle sessionHandle, 202 | int unitId, 203 | IntPtr identity, 204 | out IntPtr subFactorArray, 205 | out int subFactorCount); 206 | 207 | public static WinBioBiometricSubType[] EnumEnrollments(WinBioSessionHandle sessionHandle, int unitId, WinBioIdentity identity) 208 | { 209 | var handle = GCHandle.Alloc(identity.GetBytes(), GCHandleType.Pinned); 210 | try 211 | { 212 | IntPtr subFactorArray; 213 | int subFactorCount; 214 | var code = EnumEnrollments(sessionHandle, unitId, handle.AddrOfPinnedObject(), out subFactorArray, out subFactorCount); 215 | WinBioException.ThrowOnError(code, "WinBioEnumEnrollments failed"); 216 | return MarshalArray(subFactorArray, subFactorCount); 217 | } 218 | finally 219 | { 220 | handle.Free(); 221 | } 222 | } 223 | 224 | [DllImport(LibName, EntryPoint = "WinBioEnrollBegin")] 225 | private extern static WinBioErrorCode WinBioEnrollBegin(WinBioSessionHandle sessionHandle, WinBioBiometricSubType subType, int unitId); 226 | 227 | public static void EnrollBegin(WinBioSessionHandle sessionHandle, WinBioBiometricSubType subType, int unitId) 228 | { 229 | var code = WinBioEnrollBegin(sessionHandle, subType, unitId); 230 | WinBioException.ThrowOnError(code, "WinBioEnrollBegin failed"); 231 | } 232 | 233 | [DllImport(LibName, EntryPoint = "WinBioEnrollCapture")] 234 | public extern static WinBioErrorCode EnrollCapture(WinBioSessionHandle sessionHandle, out WinBioRejectDetail rejectDetail); 235 | 236 | [DllImport(LibName, EntryPoint = "WinBioEnrollCommit")] 237 | private extern static WinBioErrorCode EnrollCommit(WinBioSessionHandle sessionHandle, IntPtr identity, out bool isNewTemplate); 238 | 239 | public static bool EnrollCommit(WinBioSessionHandle sessionHandle, out WinBioIdentity identity) 240 | { 241 | bool isNewTemplate; 242 | var bytes = new byte[WinBioIdentity.Size]; 243 | var handle = GCHandle.Alloc(bytes, GCHandleType.Pinned); 244 | try 245 | { 246 | var code = EnrollCommit(sessionHandle, handle.AddrOfPinnedObject(), out isNewTemplate); 247 | WinBioException.ThrowOnError(code, "WinBioEnrollCommit failed"); 248 | } 249 | finally 250 | { 251 | handle.Free(); 252 | } 253 | identity = new WinBioIdentity(bytes); 254 | return isNewTemplate; 255 | } 256 | 257 | [DllImport(LibName, EntryPoint = "WinBioEnrollDiscard")] 258 | private extern static WinBioErrorCode WinBioEnrollDiscard(WinBioSessionHandle sessionHandle); 259 | 260 | public static void EnrollDiscard(WinBioSessionHandle sessionHandle) 261 | { 262 | var code = WinBioEnrollDiscard(sessionHandle); 263 | WinBioException.ThrowOnError(code, "WinBioEnrollDiscard failed"); 264 | } 265 | 266 | [DllImport(LibName, EntryPoint = "WinBioVerify")] 267 | private static extern WinBioErrorCode Verify( 268 | WinBioSessionHandle sessionHandle, 269 | IntPtr identity, 270 | WinBioBiometricSubType subFactor, 271 | out int unitId, 272 | out bool match, 273 | out WinBioRejectDetail rejectDetail); 274 | 275 | public static bool Verify( 276 | WinBioSessionHandle sessionHandle, 277 | WinBioIdentity identity, 278 | WinBioBiometricSubType subFactor, 279 | out int unitId, 280 | out WinBioRejectDetail rejectDetail) 281 | { 282 | bool match; 283 | var handle = GCHandle.Alloc(identity.GetBytes(), GCHandleType.Pinned); 284 | try 285 | { 286 | var code = Verify(sessionHandle, handle.AddrOfPinnedObject(), subFactor, out unitId, out match, out rejectDetail); 287 | WinBioException.ThrowOnError(code, "WinBioVerify failed"); 288 | } 289 | finally 290 | { 291 | handle.Free(); 292 | } 293 | return match; 294 | } 295 | 296 | [DllImport(LibName, EntryPoint = "WinBioDeleteTemplate")] 297 | private static extern WinBioErrorCode DeleteTemplate( 298 | WinBioSessionHandle sessionHandle, 299 | int unitId, 300 | IntPtr identity, 301 | WinBioBiometricSubType subFactor); 302 | 303 | public static void DeleteTemplate( 304 | WinBioSessionHandle sessionHandle, 305 | int unitId, 306 | WinBioIdentity identity, 307 | WinBioBiometricSubType subFactor) 308 | { 309 | var handle = GCHandle.Alloc(identity.GetBytes(), GCHandleType.Pinned); 310 | try 311 | { 312 | var code = DeleteTemplate(sessionHandle, unitId, handle.AddrOfPinnedObject(), subFactor); 313 | WinBioException.ThrowOnError(code, "WinBioDeleteTemplate failed"); 314 | } 315 | finally 316 | { 317 | handle.Free(); 318 | } 319 | } 320 | 321 | [DllImport(LibName, EntryPoint = "WinBioEnumServiceProviders")] 322 | private static extern WinBioErrorCode EnumServiceProviders( 323 | WinBioBiometricType factor, 324 | out IntPtr bspSchemaArray, 325 | out int bspCount); 326 | 327 | public static WinBioBspSchema[] EnumServiceProviders(WinBioBiometricType factor) 328 | { 329 | IntPtr bspSchemaArray; 330 | int bspCount; 331 | var code = EnumServiceProviders(factor, out bspSchemaArray, out bspCount); 332 | WinBioException.ThrowOnError(code, "WinBioEnumServiceProviders failed"); 333 | return MarshalArray(bspSchemaArray, bspCount); 334 | } 335 | 336 | [DllImport(LibName, EntryPoint = "WinBioGetLogonSetting")] 337 | private extern static WinBioErrorCode GetLogonSetting(out bool value, out WinBioSettingSourceType source); 338 | 339 | public static bool GetLogonSetting(out WinBioSettingSourceType source) 340 | { 341 | bool value; 342 | //BUG: does not seem to work 343 | var code = GetLogonSetting(out value, out source); 344 | //WinBioException.ThrowOnError(code, "WinBioGetLogonSetting failed"); 345 | return value; 346 | } 347 | 348 | [DllImport(LibName, EntryPoint = "WinBioGetEnabledSetting")] 349 | private extern static WinBioErrorCode GetEnabledSetting(out bool value, out WinBioSettingSourceType source); 350 | 351 | public static bool GetEnabledSetting(out WinBioSettingSourceType source) 352 | { 353 | bool value; 354 | //BUG: does not seem to work 355 | var code = GetEnabledSetting(out value, out source); 356 | //WinBioException.ThrowOnError(code, "WinBioGetEnabledSetting failed"); 357 | return value; 358 | } 359 | 360 | [DllImport(LibName, EntryPoint = "WinBioLogonIdentifiedUser")] 361 | public static extern WinBioErrorCode LogonIdentifiedUser(WinBioSessionHandle sessionHandle); 362 | 363 | [DllImport(LibName, EntryPoint = "WinBioAcquireFocus")] 364 | public static extern WinBioErrorCode AcquireFocus(WinBioSessionHandle sessionHandle); 365 | 366 | [DllImport(LibName, EntryPoint = "WinBioReleaseFocus")] 367 | public static extern WinBioErrorCode ReleaseFocus(WinBioSessionHandle sessionHandle); 368 | 369 | [DllImport(LibName, EntryPoint = "WinBioFree")] 370 | private extern static WinBioErrorCode Free(IntPtr address); 371 | 372 | /// 373 | /// Marshals an array of type T at the given address and frees the unmanaged memory afterwards. 374 | /// Supports primitive types, structures and enums. 375 | /// 376 | /// Type of the array elements. 377 | /// Address of the array in unmanaged memory. 378 | /// Number of elements in the array. 379 | /// Managed array of the given type. 380 | private static T[] MarshalArray(IntPtr pointer, int count) 381 | { 382 | if (pointer == IntPtr.Zero) return null; 383 | try 384 | { 385 | var offset = pointer; 386 | var data = new T[count]; 387 | var type = typeof (T); 388 | if (type.IsEnum) type = type.GetEnumUnderlyingType(); 389 | for (var i = 0; i < count; i++) 390 | { 391 | data[i] = (T) Marshal.PtrToStructure(offset, type); 392 | offset += Marshal.SizeOf(type); 393 | } 394 | return data; 395 | } 396 | finally 397 | { 398 | Free(pointer); 399 | } 400 | } 401 | } 402 | } --------------------------------------------------------------------------------