//#define BioAPI_MEMTRACK_ON
#define _DEBUG
#define WIN32

using System;
using System.Runtime.InteropServices;

namespace BioAPI.include.bioapi_type
{
	public enum Consts 
	{ 
		MDSU_MAX_VALUE_COUNT				= 16, 
		MAX_PATH							= 260,
		BioAPI_MAJOR						= 1,
		BioAPI_MINOR						= 10,
		BioAPI_MAX_STR_LEN					= 255
	};

	public enum BioAPI_BOOL :uint {BioAPI_FALSE = 0, BioAPI_TRUE = 1};
	public enum BioAPI_DEVICE_ID :uint {};

	public enum BioAPI_HANDLE :uint {BioAPI_INVALID_HANDLE	= 0}; 
	public enum BioAPI_DB_HANDLE : int {BioAPI_DB_INVALID_HANDLE = -1};
	public enum BioAPI_DB_CURSOR : uint {};
	public enum BioAPI_BIR_HANDLE : int 
	{	BioAPI_INVALID_BIR_HANDLE = -1, 
		BioAPI_UNSUPPORTED_BIR_HANDLE = -2
	};
	
	public enum BioAPI_BIR_PURPOSE :byte 
	{
		BioAPI_PURPOSE_VERIFY						  = 1,
		BioAPI_PURPOSE_IDENTIFY						  = 2,
		BioAPI_PURPOSE_ENROLL						  = 3,
		BioAPI_PURPOSE_ENROLL_FOR_VERIFICATION_ONLY	  = 4,
		BioAPI_PURPOSE_ENROLL_FOR_IDENTIFICATION_ONLY = 5,
		BioAPI_PURPOSE_AUDIT						  = 6
	};
	public enum BioAPI_MODULE_EVENT :uint 
	{
		BioAPI_NOTIFY_INSERT			= 1,
		BioAPI_NOTIFY_REMOVE			= 2,
		BioAPI_NOTIFY_FAULT				= 3,
		BioAPI_NOTIFY_SOURCE_PRESENT	= 4,
		BioAPI_NOTIFY_SOURCE_REMOVED	= 5
	};
	public enum BioAPI_MODULE_EVENT_MASK :uint 
	{
		BioAPI_NOTIFY_INSERT_BIT			=(0x0001),		
		BioAPI_NOTIFY_REMOVE_BIT			=(0x0002),
		BioAPI_NOTIFY_FAULT_BIT				=(0x0004),
		BioAPI_NOTIFY_SOURCE_PRESENT_BIT	=(0x0008),
		BioAPI_NOTIFY_SOURCE_REMOVED_BIT	=(0x0010)
	};
	public enum BioAPI_GUI_MESSAGE :uint {};
	public enum BioAPI_GUI_PROGRESS :byte {};
	public enum BioAPI_GUI_RESPONSE :byte {
		BioAPI_CAPTURE_SAMPLE		= 1,
		BioAPI_CANCEL				= 2,
		BioAPI_CONTINUE				= 3,
		BioAPI_VALID_SAMPLE			= 4,
		BioAPI_INVALID_SAMPLE		= 5
	};
	public enum BioAPI_GUI_STATE :uint 
	{ 
		BioAPI_SAMPLE_AVAILABLE		= 0x0001,
		BioAPI_MESSAGE_PROVIDED		= 0x0002,
		BioAPI_PROGRESS_PROVIDED	= 0x0004
	};
	public enum BioAPI_BIR_AUTH_FACTORS :uint 
	{ 
		BioAPI_FACTOR_MULTIPLE						  = 0x00000001,
		BioAPI_FACTOR_FACIAL_FEATURES				  = 0x00000002,
		BioAPI_FACTOR_VOICE							  = 0x00000004,
		BioAPI_FACTOR_FINGERPRINT					  = 0x00000008,
		BioAPI_FACTOR_IRIS							  = 0x00000010,
		BioAPI_FACTOR_RETINA						  = 0x00000020,
		BioAPI_FACTOR_HAND_GEOMETRY					  = 0x00000040,
		BioAPI_FACTOR_SIGNATURE_DYNAMICS			  = 0x00000080,
		BioAPI_FACTOR_KEYSTOKE_DYNAMICS				  = 0x00000100,
		BioAPI_FACTOR_LIP_MOVEMENT					  = 0x00000200,
		BioAPI_FACTOR_THERMAL_FACE_IMAGE			  = 0x00000400,
		BioAPI_FACTOR_THERMAL_HAND_IMAGE			  = 0x00000800,
		BioAPI_FACTOR_GAIT							  = 0x00001000,
		BioAPI_FACTOR_PASSWORD						  = 0x80000000
	};

	public enum BioAPI_BIR_DATA_TYPE :byte 
	{ 
		BioAPI_BIR_DATA_TYPE_RAW					  = 0x01, 
		BioAPI_BIR_DATA_TYPE_INTERMEDIATE			  = 0x02, 
		BioAPI_BIR_DATA_TYPE_PROCESSED				  = 0x04, 
		BioAPI_BIR_DATA_TYPE_ENCRYPTED				  = 0x10, 
		BioAPI_BIR_DATA_TYPE_SIGNED					  = 0x20
	};
	public enum BioAPI_DB_ACCESS_TYPE :uint 
	{ 
		BioAPI_DB_ACCESS_READ						  = 0x1,
		BioAPI_DB_ACCESS_WRITE						  = 0x2
	};
	public enum BioAPI_IDENTIFY_POPULATION_TYPE :byte 
	{ 
		BioAPI_DB_TYPE				  = 1, 
		BioAPI_ARRAY_TYPE			  = 2
	};
	public enum BioAPI_INPUT_BIR_FORM :byte 
	{ 
		BioAPI_DATABASE_ID_INPUT		  = 1, 
		BioAPI_BIR_HANDLE_INPUT			  = 2,
		BioAPI_FULLBIR_INPUT			  = 3
	};
	public enum BioAPI_POWER_MODE :uint 
	{ 
		BioAPI_POWER_NORMAL		  = 1, 
		BioAPI_POWER_DETECT		  = 2,
		BioAPI_POWER_SLEEP		  = 3
	};
	public enum BioAPI_FAR :int { BioAPI_NOT_SET  = -1	};
	public enum BioAPI_FRR :int { BioAPI_NOT_SET  = -1, BioAPI_NOT_SUPPORTED  = -2	};
	public enum BioAPI_BIR_BIOMETRIC_DATA :byte { };
	public enum BioAPI_BIR_VERSION :byte { };
	public enum BioAPI_QUALITY :sbyte { };

	public enum BioAPI_OPERATIONS_MASK :uint 
	{ 
		BioAPI_CAPTURE							  = 0x0001,
		BioAPI_CREATETEMPLATE					  = 0x0002,
		BioAPI_PROCESS							  = 0x0004,
		BioAPI_VERIFYMATCH						  = 0x0008,
		BioAPI_IDENTIFYMATCH					  = 0x0010,
		BioAPI_ENROLL							  = 0x0020,
		BioAPI_VERIFY							  = 0x0040,
		BioAPI_IDENTIFY							  = 0x0080,
		BioAPI_IMPORT							  = 0x0100,
		BioAPI_SETPOWERMODE						  = 0x0200,
		BioAPI_DATABASEOPERATIONS				  = 0x0400
	}
	public enum BioAPI_OPTIONS_MASK :uint 
	{ 
		BioAPI_RAW								  = 0x00000001,
		BioAPI_QUALITY_RAW						  = 0x00000002,
		BioAPI_QUALITY_INTERMEDIATE				  = 0x00000004,
		BioAPI_QUALITY_PROCESSED				  = 0x00000008,
		BioAPI_APP_GUI							  = 0x00000010,
		BioAPI_STREAMINGDATA					  = 0x00000020,
		BioAPI_USERVALIDATESSAMPLES				  = 0x00000040,
		BioAPI_VERIFYSAMPLES					  = 0x00000080,
		BioAPI_SOURCEPRESENT					  = 0x00000100,
		BioAPI_PAYLOAD							  = 0x00001000,
		BioAPI_BIR_SIGN							  = 0x00002000,
		BioAPI_BIR_ENCRYPT						  = 0x00004000,
		BioAPI_FRR_SUPPORTED					  = 0x00010000,
		BioAPI_ADAPTATION						  = 0x00020000,
		BioAPI_BINNING							  = 0x00040000,
		BioAPI_DEFAULTDATABASE					  = 0x00080000,
		BioAPI_LOCAL_BSP						  = 0x01000000,
		BioAPI_CLIENT_BSP						  = 0x02000000,
		BioAPI_SERVER_BSP						  = 0x04000000,
		BioAPI_STREAMINGCALLBACK				  = 0x08000000,
		BioAPI_PROGRESS							  = 0x10000000,
		BioAPI_SELFCONTAINEDDEVICE				  = 0x20000000
	}




//		typedef struct bioapi_data
//		{
//			uint32 Length; /* in bytes */
//			uint8 *Data;
//		} BioAPI_DATA;
	[Serializable]
	[StructLayout(LayoutKind.Sequential)]
	public class BioAPI_DATA 
	{
		public uint Length = 0;
		public byte[] Data = null;
		public BioAPI_DATA() {}
		public BioAPI_DATA(uint length, byte[] data) { Length = length; Data = data; }

		public IntPtr DoMarshal(ref int size)
		{
			IntPtr ptr;
			IntPtr ptrData = IntPtr.Zero;
			int ofs = 0;

			size = Marshal.SizeOf(Type.GetType("System.Int32")) + 
				   Marshal.SizeOf(Type.GetType("System.IntPtr"));
			
			ptr = Marshal.AllocCoTaskMem( size );
			Marshal.WriteInt32(ptr, ofs, (int) Length);
			ofs += Marshal.SizeOf(Type.GetType("System.Int32"));
			if (Data != null) 
			{
				ptrData = Marshal.AllocCoTaskMem( Data.Length );
				Marshal.Copy(Data, 0, ptrData, Data.Length);
			}
			Marshal.WriteIntPtr(ptr, ofs, ptrData);
			return ptr;
		}

		public void DoUnmarshal(IntPtr ptr, ref int size, bool fDeleteOld)
		{
			int ofs = 0;
			size = Marshal.SizeOf(Type.GetType("System.Int32")) + 
				   Marshal.SizeOf(Type.GetType("System.IntPtr"));
			Length =  (uint) Marshal.ReadInt32( ptr, ofs );
			ofs += Marshal.SizeOf(Type.GetType("System.Int32"));

			if (Length == 0) 
			{
				if (Data != null) Data = null;
				return;
			}
		
			IntPtr ptr2 = Marshal.ReadIntPtr(ptr, ofs);

			if (Data == null || Data.Length != Length) Data = new byte[Length];
			Marshal.Copy(ptr2, Data, 0, (int) Length);
			if (fDeleteOld)  { if (ptr != IntPtr.Zero) Marshal.FreeCoTaskMem( ptr ); }
		}
	} 

//		typedef uint8 BioAPI_UUID[16];
	[StructLayout(LayoutKind.Sequential)]
	public class BioAPI_UUID
	{
		[MarshalAs(UnmanagedType.ByValArray, SizeConst=16)]
		private byte[] data;
		private const int size = 16;
		public BioAPI_UUID() { data = new byte[16];}
		public BioAPI_UUID(BioAPI_UUID val)
		{
			data = new byte[size];
			for (int i = 0; i < size; i++) data[i] = (byte) val[i];
		}
		public BioAPI_UUID(byte[] val)
		{
			data = new byte[16];
			for (int i = 0; i < size; i++) data[i] = (byte) val[i];
		}
		public int Length { get { return data.Length; } }
		public byte[] Bytes { get { return this.data; }}
		public byte this[int index]   
		{
			get { return data[index]; }
			set { data[index] = value; }
		}
		public void Assign(byte [] val) 
		{
			if (val.Length != size) return;
			for (int i = 0; i < size; i++)
				data[i] = val[i];
		}
		public void Assign(BioAPI_UUID val) 
		{
			for (int i = 0; i < size; i++)
				data[i] = val[i];		
		}
		public IntPtr DoMarshal(ref int size) 
		{
			size = BioAPI_UUID.size;
			IntPtr ptr = Marshal.AllocCoTaskMem( size );
			Marshal.Copy( data, 0, ptr, size );
			return ptr;
		}
		public void DoUnmarshal(IntPtr ptr, ref int size, bool fDeleteOld)
		{
			size = BioAPI_UUID.size;
			Marshal.Copy( ptr, data, 0, size );
			if (fDeleteOld)  { if (ptr != IntPtr.Zero) Marshal.FreeCoTaskMem( ptr ); }
		}
	}

//		typedef struct bioapi_version
//		{
//			uint32 Major;
//			uint32 Minor;
//		} BioAPI_VERSION;
	[StructLayout(LayoutKind.Sequential)]
	public class BioAPI_VERSION 
	{
		public int Major = (int) Consts.BioAPI_MAJOR;
		public int Minor = (int) Consts.BioAPI_MINOR;
		public BioAPI_VERSION() { }
		public BioAPI_VERSION(int major, int minor) { Major=major; Minor=minor;}
	} 

//		typedef struct bioapi_uuid
//		{
//			BioAPI_UUID Uuid;
//			BioAPI_VERSION Version;
//			BioAPI_DEVICE_ID DeviceId;
//			uint32 Reserved;
//		} BioAPI_SERVICE_UID;
	[StructLayout(LayoutKind.Sequential)]
	public class BioAPI_SERVICE_UID 
	{
		public BioAPI_UUID Uuid = new BioAPI_UUID();
		public BioAPI_VERSION Version = new BioAPI_VERSION();
		public BioAPI_DEVICE_ID DeviceId = 0;
		public uint Reserved = 0;
	} 

//		typedef struct bioapi_gui_bitmap
//		{
//			uint32 Width;
//			uint32 Height;
//			BioAPI_DATA_PTR Bitmap;
//		} BioAPI_GUI_BITMAP;
	[StructLayout(LayoutKind.Sequential)]
	public class BioAPI_GUI_BITMAP 
	{
		public uint Width = 0;
		public uint Height = 0;
		public BioAPI_DATA Bitmap = new BioAPI_DATA();

		public IntPtr DoMarshal(ref int size)
		{
			IntPtr ptr;
			IntPtr ptrBitmap = IntPtr.Zero;
			int ofs = 0;
			int DataLen =0;

			size = 2* Marshal.SizeOf(Type.GetType("System.Int32")) + 
				   Marshal.SizeOf(Type.GetType("System.IntPtr"));		
			ptr = Marshal.AllocCoTaskMem( size );
			
			Marshal.WriteInt32(ptr, ofs, (int) Width);
			ofs += Marshal.SizeOf(Type.GetType("System.Int32"));
			Marshal.WriteInt32(ptr, ofs, (int) Height);
			ofs += Marshal.SizeOf(Type.GetType("System.Int32"));

			if (Bitmap != null)
			{
				ptrBitmap = Bitmap.DoMarshal(ref DataLen);
				Marshal.WriteIntPtr(ptr, ofs, ptrBitmap);
				ofs += Marshal.SizeOf(Type.GetType("System.IntPtr"));
			}
			return ptr;
		}

		public void DoUnmarshal(IntPtr ptr, ref int size, bool fDeleteOld)
		{
			int ofs = 0;
			IntPtr ptrBitmap = IntPtr.Zero;
			int DataLen = 0;

			size = 2* Marshal.SizeOf(Type.GetType("System.Int32")) + 
				Marshal.SizeOf(Type.GetType("System.IntPtr"));		

			Width = (uint) Marshal.ReadInt32(ptr, ofs);
			ofs += Marshal.SizeOf(Type.GetType("System.Int32")); 
			Height = (uint) Marshal.ReadInt32(ptr, ofs);
			ofs += Marshal.SizeOf(Type.GetType("System.Int32")); 

			ptrBitmap = Marshal.ReadIntPtr(ptr, ofs);
			ofs += Marshal.SizeOf(Type.GetType("System.IntPtr")); 
			if (ptrBitmap != IntPtr.Zero)
			{
				if (Bitmap == null) Bitmap = new BioAPI_DATA();
				Bitmap.DoUnmarshal(ptrBitmap, ref DataLen, fDeleteOld);
			}
			else
				Bitmap = null;

			if (fDeleteOld)  { if (ptr != IntPtr.Zero) Marshal.FreeCoTaskMem( ptr ); }
		}
	} 

	[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi)]
	public class BioAPI_STRING 
	{
		[ MarshalAs( UnmanagedType.ByValTStr, SizeConst=68 )]
		private string data;
		public BioAPI_STRING() { data = String.Empty; }
		public BioAPI_STRING(string s) 
		{   if (s == null)
				data = new String(' ', 68);
			else if (s.Length > 68) 
				data = String.Copy(s.Substring(0, 68));
			else
				data = String.Copy(s); 
		}

		public string StringData   
		{
			get { return data; }
			set { 
				  if (value == null)
					  data = String.Empty;
				  else if (value.Length > 68) 
					  data = String.Copy(value.Substring(0, 68));
				  else
					  data = String.Copy(value); 
				}
		}
	}

//		typedef struct bioapi_bir_biometric_data_format
//			{
//				uint16 FormatOwner;
//				uint16 FormatID;
//			} BioAPI_BIR_BIOMETRIC_DATA_FORMAT;
	[Serializable()]
	[StructLayout(LayoutKind.Sequential)]
	public class BioAPI_BIR_BIOMETRIC_DATA_FORMAT
	{
		public ushort FormatOwner = 0;
		public ushort FormatID = 0;

		public BioAPI_BIR_BIOMETRIC_DATA_FORMAT() {}
		public BioAPI_BIR_BIOMETRIC_DATA_FORMAT(ushort owner, ushort id) 
		{
			FormatOwner = owner;
			FormatID = id;
		}
		public void Assign (ushort owner, ushort id)
		{
			FormatOwner = owner;
			FormatID = id;
		}
		public IntPtr DoMarshal(ref int size)
		{
			IntPtr ptr = new IntPtr(0);
			int ofs = 0;
			size = 2 * Marshal.SizeOf (Type.GetType("System.Int16"));
			
			ptr = Marshal.AllocCoTaskMem( size );
			Marshal.WriteInt16(ptr, ofs, (short) FormatOwner);
			ofs += 2;
			Marshal.WriteInt16(ptr, ofs, (short) FormatID);
			return ptr;
		}
		public void DoUnmarshal(IntPtr ptr, ref int size, bool fDeleteOld)
		{
			int ofs = 0;
			size = 2 * Marshal.SizeOf (Type.GetType("System.Int16"));
			FormatOwner =  (ushort) Marshal.ReadInt16( ptr, ofs );
			ofs += 2;
			FormatID =  (ushort) Marshal.ReadInt16( ptr, ofs );
			if (fDeleteOld)  { if (ptr != IntPtr.Zero) Marshal.FreeCoTaskMem( ptr ); }
		}
	}



//		typedef struct bioapi_bir_header
//			{
//				uint32 Length;	 /* Length of Header + Opaque Data */
//				BioAPI_BIR_VERSION HeaderVersion;
//				BioAPI_BIR_DATA_TYPE Type;
//				BioAPI_BIR_BIOMETRIC_DATA_FORMAT Format;
//				BioAPI_QUALITY Quality;
//				BioAPI_BIR_PURPOSE PurposeMask;
//				BioAPI_BIR_AUTH_FACTORS FactorsMask;
//			} BioAPI_BIR_HEADER;
	[Serializable()]
	[StructLayout(LayoutKind.Sequential)]
	public class BioAPI_BIR_HEADER
	{
		public uint Length;	 /* Length of Header + Opaque Data */
		public BioAPI_BIR_VERSION HeaderVersion;
		public BioAPI_BIR_DATA_TYPE Type;
		public BioAPI_BIR_BIOMETRIC_DATA_FORMAT Format = new BioAPI_BIR_BIOMETRIC_DATA_FORMAT();
		public BioAPI_QUALITY Quality;
		public BioAPI_BIR_PURPOSE PurposeMask;
		public BioAPI_BIR_AUTH_FACTORS FactorsMask;

		public IntPtr DoMarshal(ref int size)
		{
			IntPtr ptr, ptrFormat;
			int FormatLen = 0;
			int ofs = 0;

			ptrFormat = Format.DoMarshal(ref FormatLen);
			size = Marshal.SizeOf(System.Type.GetType("System.Int32")) + 
				2 * Marshal.SizeOf(System.Type.GetType("System.Byte")) + FormatLen + 
				2 * Marshal.SizeOf(System.Type.GetType("System.Byte")) + 
				Marshal.SizeOf(System.Type.GetType("System.Int32"));
			ptr = Marshal.AllocCoTaskMem( size );
			Marshal.WriteInt32(ptr, ofs, (int) Length);
			ofs += Marshal.SizeOf (System.Type.GetType("System.Int32"));

			Marshal.WriteByte(ptr, ofs, (byte) HeaderVersion);
			ofs += Marshal.SizeOf (System.Type.GetType("System.Byte"));
			
			Marshal.WriteByte(ptr, ofs, (byte) Type);
			ofs += Marshal.SizeOf (System.Type.GetType("System.Byte"));

			for (int i = 0; i < FormatLen; i++)
			{
				byte val;
				val = Marshal.ReadByte(ptrFormat, i);
				Marshal.WriteByte(ptr, ofs++, val);
			}
			Marshal.FreeCoTaskMem( ptrFormat );

			Marshal.WriteByte(ptr, ofs, (byte) Quality);
			ofs += 1;
			Marshal.WriteByte(ptr, ofs, (byte) PurposeMask);
			ofs += 1;
			Marshal.WriteInt32(ptr, ofs, (int) FactorsMask);

			return ptr;
		}
		public void DoUnmarshal(IntPtr ptr, ref int size, bool fDeleteOld)
		{
			int ofs = 0;
			int FormatLen = 0;
			IntPtr ptr2;


			Length =  (uint) Marshal.ReadInt32( ptr, ofs );
			ofs += Marshal.SizeOf (System.Type.GetType("System.Int32"));

			HeaderVersion =  (BioAPI_BIR_VERSION) Marshal.ReadByte( ptr, ofs );
			ofs += Marshal.SizeOf (System.Type.GetType("System.Byte"));

			Type =  (BioAPI_BIR_DATA_TYPE) Marshal.ReadByte( ptr, ofs );
			ofs += Marshal.SizeOf (System.Type.GetType("System.Byte"));

			ptr2 = new IntPtr(ptr.ToInt32() + ofs );
			Format.DoUnmarshal(ptr2, ref FormatLen, fDeleteOld);
			ofs += FormatLen;

			Quality =  (BioAPI_QUALITY) Marshal.ReadByte( ptr, ofs );
			ofs += 1;
			PurposeMask =  (BioAPI_BIR_PURPOSE) Marshal.ReadByte( ptr, ofs );
			ofs += 1;
			FactorsMask =  (BioAPI_BIR_AUTH_FACTORS) Marshal.ReadInt32( ptr, ofs );

			size = Marshal.SizeOf(System.Type.GetType("System.Int32")) + 
				   2 * Marshal.SizeOf(System.Type.GetType("System.Byte")) + FormatLen + 
				   2 * Marshal.SizeOf(System.Type.GetType("System.Byte")) + 
				   Marshal.SizeOf(System.Type.GetType("System.Int32"));
			if (fDeleteOld)  { if (ptr != IntPtr.Zero) Marshal.FreeCoTaskMem( ptr ); }
		}
	}


	
//		typedef struct bioapi_hrs_bir
//			{
//				BioAPI_BIR_HEADER  Header;
//				BioAPI_BIR_BIOMETRIC_DATA_PTR BiometricData; /* length indicated in */
//				/* header			  */
//				BioAPI_DATA_PTR Signature;	/* NULL if no signature; length is inherent */
//				/* in this type							  */
//			} BioAPI_BIR;
	[StructLayout(LayoutKind.Sequential)]
	[Serializable()]
	public class BioAPI_BIR
	{
		public BioAPI_BIR_HEADER  Header = new BioAPI_BIR_HEADER();
		public BioAPI_BIR_BIOMETRIC_DATA [] BiometricData;  // length indicated in header
		public BioAPI_DATA Signature;

		public IntPtr DoMarshal(ref int size)
		{
			IntPtr ptr;
			IntPtr ptrHeader, ptrBiometricData = IntPtr.Zero, ptrSignature = IntPtr.Zero;
			int ofs = 0;
			int HeaderLen = 0, DataLen =0, SignatureLen = 0;

			ptrHeader = Header.DoMarshal(ref HeaderLen);
			size = HeaderLen + 2* Marshal.SizeOf(Type.GetType("System.IntPtr"));
						
			ptr = Marshal.AllocCoTaskMem( size );

			for (int i = 0; i < HeaderLen; i++)
			{
				byte val;
				val = Marshal.ReadByte(ptrHeader, i);
				Marshal.WriteByte(ptr, ofs++, val);
			}
			Marshal.FreeCoTaskMem( ptrHeader );

			if (BiometricData != null)
			{
				DataLen = BiometricData.Length;
				ptrBiometricData = Marshal.AllocCoTaskMem( DataLen );
				for (int i = 0; i < DataLen; i++)
				{ Marshal.WriteByte(ptrBiometricData, i, (byte) BiometricData[i]); }
			}
			Marshal.WriteIntPtr(ptr, ofs, ptrBiometricData);
			ofs += Marshal.SizeOf(Type.GetType("System.IntPtr"));

			if (Signature != null)
			{
				ptrSignature = Signature.DoMarshal(ref SignatureLen);
			}
			Marshal.WriteIntPtr(ptr, ofs, ptrSignature);
			ofs += Marshal.SizeOf(Type.GetType("System.IntPtr"));

			return ptr;
		}

		public void DoUnmarshal(IntPtr ptr, ref int size, bool fDeleteOld)
		{
			int ofs = 0;
			IntPtr ptrBiometricData = IntPtr.Zero, ptrSignature = IntPtr.Zero;
			int HeaderLen = 0, DataLen;

			Console.WriteLine("BIR.DoUnmarshal " );

			Header.DoUnmarshal(ptr, ref HeaderLen, fDeleteOld);
			ofs += HeaderLen; 

			size = HeaderLen + 2* Marshal.SizeOf(Type.GetType("System.IntPtr"));

			ptrBiometricData = Marshal.ReadIntPtr(ptr, ofs);
			ofs += Marshal.SizeOf(Type.GetType("System.IntPtr")); 

			DataLen = (int) Header.Length - HeaderLen;
			if (DataLen > 0 && ptrBiometricData != IntPtr.Zero)
			{
				if (BiometricData == null || BiometricData.Length != DataLen)
				{	BiometricData = new BioAPI_BIR_BIOMETRIC_DATA[DataLen]; }
				//string str = "";
				for (int i = 0; i < DataLen; i++)
				{ 
					BiometricData[i] = 
						(BioAPI_BIR_BIOMETRIC_DATA) Marshal.ReadByte(ptrBiometricData, i);
					//str += BiometricData[i].ToString()+ " ";
				}
				//Console.WriteLine("unmarshaled BiometricData = " + str );
			}

			ptrSignature = Marshal.ReadIntPtr(ptr, ofs);
			ofs += Marshal.SizeOf(Type.GetType("System.IntPtr")); 
			int SignatureLen = 0;
			if (ptrSignature != IntPtr.Zero)
			{
				if (Signature == null) Signature = new BioAPI_DATA();
				Signature.DoUnmarshal(ptrSignature, ref SignatureLen, fDeleteOld);
			}
			else
			{
				Signature = null;
			}

			if (fDeleteOld)  { if (ptr != IntPtr.Zero) Marshal.FreeCoTaskMem( ptr ); }
		}
	}

//		typedef struct bioapi_bir_array_population
//			{
//				uint32 NumberOfMembers;
//				BioAPI_BIR_PTR *Members;	/* A pointer to an array of BIR pointers */
//			} BioAPI_BIR_ARRAY_POPULATION;
	[StructLayout(LayoutKind.Sequential)]
	public class BioAPI_BIR_ARRAY_POPULATION
	{
		public uint NumberOfMembers = 0;
		public BioAPI_BIR [] Members = null;  

		public IntPtr DoMarshal(ref int size)
		{
			IntPtr ptr;
			IntPtr ptrMembers = IntPtr.Zero;
			int ofs = 0;

			size = Marshal.SizeOf(Type.GetType("System.Int32")) + 
				   Marshal.SizeOf(Type.GetType("System.IntPtr"));
			
			ptr = Marshal.AllocCoTaskMem( size );
			Marshal.WriteInt32(ptr, ofs, (int) NumberOfMembers);
			ofs += Marshal.SizeOf(Type.GetType("System.Int32"));

			if (Members != null) 
			{
				int arraylen = Members.Length;
				int totalsize = 0;
				IntPtr [] ptrMember = new IntPtr [arraylen];
				int [] DataLen = new int [arraylen];
				for (int i = 0; i < Members.Length; i++)
				{
					DataLen[i] = 0;
					ptrMember[i] = Members[i].DoMarshal(ref DataLen[i]);
					totalsize += DataLen[i];
				}
				ptrMembers = Marshal.AllocCoTaskMem( totalsize );
				int ofsMembers = 0;
				for (int i=0; i < Members.Length; i++)
				{
					for (int j=0; j < DataLen[i]; j++)
					{
						byte val;
						val = Marshal.ReadByte(ptrMember[i], j);
						Marshal.WriteByte(ptrMembers, ofsMembers++, val);
					}
					Marshal.FreeCoTaskMem( ptrMember[i] );
				}
				DataLen = null;
			}
			
			Marshal.WriteIntPtr(ptr, ofs, ptrMembers);
			return ptr;
		}

		public void DoUnmarshal(IntPtr ptr, ref int size, bool fDeleteOld)
		{
			int ofs = 0;
			size = Marshal.SizeOf(Type.GetType("System.Int32")) + 
				Marshal.SizeOf(Type.GetType("System.IntPtr"));
			NumberOfMembers =  (uint) Marshal.ReadInt32( ptr, ofs );
			ofs += Marshal.SizeOf(Type.GetType("System.Int32"));

			if (NumberOfMembers <= 0) 
			{
				if (Members != null) Members = null;
				return;
			}
		
			IntPtr ptrMembers = Marshal.ReadIntPtr(ptr, ofs);
			if (Members == null || Members.Length != NumberOfMembers) 
				Members = new BioAPI_BIR[NumberOfMembers];
			int len = 0;
			int accumulen = 0;
			IntPtr ptrMember = new IntPtr(ptrMembers.ToInt32());
			for (int i = 0; i < NumberOfMembers; i++)
			{
				ptrMember = new IntPtr(ptrMembers.ToInt32() + accumulen);
				Members[i].DoUnmarshal(ptrMember, ref len, false);
				accumulen += len;
			}
			if (fDeleteOld)  { if (ptrMembers != IntPtr.Zero) Marshal.FreeCoTaskMem( ptrMembers ); }
			if (fDeleteOld)  { if (ptr != IntPtr.Zero) Marshal.FreeCoTaskMem( ptr ); }
		}
	}

//		typedef struct bioapi_candidate
//			{
//				BioAPI_IDENTIFY_POPULATION_TYPE Type;
//				union
//				{
//				BioAPI_UUID_PTR BIRInDataBase;
//				uint32 *BIRInArray;
//				} BIR;
//				BioAPI_FAR FARAchieved;
//				BioAPI_FRR FRRAchieved;
//			} BioAPI_CANDIDATE;
	[StructLayout(LayoutKind.Sequential)]
	public class BioAPI_CANDIDATE
	{
		public BioAPI_IDENTIFY_POPULATION_TYPE Type;
		public class unionBIR
		{
			public BioAPI_UUID BIRInDataBase = new BioAPI_UUID();
			public uint BIRInArray; 
		}
		public unionBIR BIR = new unionBIR();
		public BioAPI_FAR FARAchieved; 
		public BioAPI_FRR FRRAchieved; 

	}


//		typedef struct bioapi_identify_population
//			{
//				BioAPI_IDENTIFY_POPULATION_TYPE Type;
//				union
//				{
//				BioAPI_DB_HANDLE_PTR BIRDataBase;
//				BioAPI_BIR_ARRAY_POPULATION_PTR BIRArray;
//				} BIRs;
//			} BioAPI_IDENTIFY_POPULATION;
	[StructLayout(LayoutKind.Sequential)]
	public class BioAPI_IDENTIFY_POPULATION
	{
		public BioAPI_IDENTIFY_POPULATION_TYPE Type;
		public class unionBIRs
		{
			public BioAPI_DB_HANDLE BIRDataBase;
			public BioAPI_BIR_ARRAY_POPULATION BIRArray; 
		}
		public unionBIRs BIRs = new unionBIRs();
	}


//		typedef struct bioapi_func_name_addr
//		{
//			char Name[BioAPI_MAX_STR_LEN];
//			BioAPI_PROC_ADDR Address;
//		}BioAPI_FUNC_NAME_ADDR;
	[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi)]
	public class BioAPI_FUNC_NAME_ADDR 
	{
		[ MarshalAs( UnmanagedType.ByValTStr, SizeConst=(int) Consts.BioAPI_MAX_STR_LEN )]
		public string Name;
		public BioAPI_PROC_ADDR Address;
	}

//		typedef struct bioapi_input_bir
//		{
//			BioAPI_INPUT_BIR_FORM Form;
//			union
//			{
//				BioAPI_DBBIR_ID_PTR BIRinDb;
//				BioAPI_BIR_HANDLE_PTR BIRinBSP;
//				BioAPI_BIR_PTR BIR;
//			} InputBIR;
//		} BioAPI_INPUT_BIR;
	[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi)]
	public class BioAPI_INPUT_BIR
	{
		public BioAPI_INPUT_BIR_FORM Form;
		public class Input_BIR
		{
			public BioAPI_DBBIR_ID BIRinDb;
			public BioAPI_BIR_HANDLE BIRinBSP;
			public BioAPI_BIR BIR;
		};
		public Input_BIR InputBIR = new Input_BIR();
	}


//		typedef struct bioapi_hrs_dbbir_id
//		{
//			BioAPI_DB_HANDLE DbHandle;
//			BioAPI_UUID KeyValue;
//		} BioAPI_DBBIR_ID;
	[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi)]
	public class BioAPI_DBBIR_ID
	{
		public BioAPI_DB_HANDLE DbHandle = BioAPI_DB_HANDLE.BioAPI_DB_INVALID_HANDLE;
		[MarshalAs(UnmanagedType.ByValArray, SizeConst=16)]
		public BioAPI_UUID KeyValue = new BioAPI_UUID();

		public IntPtr DoMarshal(ref int size) 
		{
			IntPtr ptr;
			IntPtr ptrInputBir = IntPtr.Zero;
			int ofs = 0;
			int uuidLen = 16;

			size = Marshal.SizeOf(Type.GetType("System.Int32")) + uuidLen;
			ptr = Marshal.AllocCoTaskMem( size );

			Marshal.WriteInt32(ptr, ofs, (int) DbHandle);
			ofs += Marshal.SizeOf(Type.GetType("System.Int32"));
			for (int i = 0; i < uuidLen; i++)
			{
				Marshal.WriteInt32(ptr, ofs++, (Byte) KeyValue.Bytes[i]);
			}
			return ptr;
		}
		public void DoUnmarshal(IntPtr ptr, ref int size, bool fDeleteOld)
		{
			IntPtr ptrInputBir = IntPtr.Zero;
			int ofs = 0;
			int uuidLen = 16;

			size = Marshal.SizeOf(Type.GetType("System.Int32")) + uuidLen;

			DbHandle =  (BioAPI_DB_HANDLE) Marshal.ReadInt32( ptr, ofs );
			ofs += Marshal.SizeOf(Type.GetType("System.Int32"));
			IntPtr ptrKeyValue = new IntPtr(ptr.ToInt32() + ofs);
			KeyValue.DoUnmarshal(ptrKeyValue, ref uuidLen, false);

			if (fDeleteOld)  { if (ptr != IntPtr.Zero) Marshal.FreeCoTaskMem( ptr ); }
		}
	}


//		typedef BioAPI_RETURN (BioAPI *BioAPI_ModuleEventHandler)
//			(const BioAPI_UUID *BSPUuid,
//				void* AppNotifyCallbackCtx,
//				BioAPI_DEVICE_ID DeviceID,
//				uint32 Reserved,
//				BioAPI_MODULE_EVENT EventType);
	public delegate BioAPI_RETURN BioAPI_ModuleEventHandler(
		BioAPI_UUID BSPUuid,
		IntPtr AppNotifyCallbackCtx,
		BioAPI_DEVICE_ID DeviceID,
		uint Reserved,
		BioAPI_MODULE_EVENT EventType);

#if (!BioAPI_MEMTRACK_ON)
	public delegate IntPtr BioAPI_MALLOC(uint size, IntPtr Allocref);
	public delegate void BioAPI_FREE(IntPtr memblock, IntPtr Allocref);
	public delegate IntPtr BioAPI_REALLOC(IntPtr memblock, uint size, IntPtr Allocref);
	public delegate IntPtr BioAPI_CALLOC(uint Num, uint size, IntPtr Allocref);
#else
	public delegate IntPtr BioAPI_MALLOC(uint size, IntPtr Allocref, string File, uint Line);
	public delegate void BioAPI_FREE(IntPtr memblock, IntPtr Allocref, string File, uint Line);
	public delegate IntPtr BioAPI_REALLOC(IntPtr memblock, uint size, IntPtr Allocref, string File, uint Line);
	public delegate IntPtr BioAPI_CALLOC(uint Num, uint size, IntPtr Allocref, string File, uint Line);
#endif 


	//	typedef struct bioapi_memory_funcs
	//			{
	//				BioAPI_MALLOC Malloc_func;
	//				BioAPI_FREE Free_func;
	//				BioAPI_REALLOC Realloc_func;
	//				BioAPI_CALLOC Calloc_func;
	//				void *AllocRef;
	//			} BioAPI_MEMORY_FUNCS, *BioAPI_MEMORY_FUNCS_PTR;
	[StructLayout(LayoutKind.Sequential)]
	public class BioAPI_MEMORY_FUNCS
	{
		[MarshalAs(UnmanagedType.FunctionPtr)]
		public BioAPI_MALLOC Malloc_func;
		[MarshalAs(UnmanagedType.FunctionPtr)]
		public BioAPI_FREE Free_func;
		[MarshalAs(UnmanagedType.FunctionPtr)]
		public BioAPI_REALLOC Realloc_func;
		[MarshalAs(UnmanagedType.FunctionPtr)]
		public BioAPI_CALLOC Calloc_func;
		public object AllocRef;
		public BioAPI_MEMORY_FUNCS(
			BioAPI_MALLOC malloc_func,
			BioAPI_FREE free_func,
			BioAPI_REALLOC realloc_func,
			BioAPI_CALLOC calloc_func,
			object alloc)
		{
			Malloc_func = malloc_func;
			Free_func = free_func;
			Realloc_func = realloc_func;
			Calloc_func = calloc_func;
			AllocRef = alloc;
		}
	}


#if (WIN32)
	public delegate int BioAPI_PROC_ADDR();
#else
	public delegate void BioAPI_PROC_ADDR();
#endif 

//		typedef BioAPI_RETURN (BioAPI *BioAPI_GUI_STATE_CALLBACK)
//			(void *GuiStateCallbackCtx,
//			BioAPI_GUI_STATE GuiState,
//			BioAPI_GUI_RESPONSE Response,
//			BioAPI_GUI_MESSAGE Message,
//			BioAPI_GUI_PROGRESS Progress,
//			BioAPI_GUI_BITMAP_PTR SampleBuffer);
	public delegate int BioAPI_GUI_STATE_CALLBACK(
			IntPtr GuiStateCallbackCtx,			// [in]
			BioAPI_GUI_STATE GuiState,			// [in]
			// **rjm** ref BioAPI_GUI_RESPONSE Response,		// [out]
			IntPtr ResponsePtr, 
			BioAPI_GUI_MESSAGE Message,			// [in/optional]
			BioAPI_GUI_PROGRESS Progress,		// [in/optional]
			IntPtr SampleBuffer);				// [in/optional]

//		typedef BioAPI_RETURN (BioAPI *BioAPI_GUI_STREAMING_CALLBACK)
//			(void *GuiStreamingCallbackCtx,
//			BioAPI_GUI_BITMAP_PTR Bitmap);
	public delegate BioAPI_RETURN BioAPI_GUI_STREAMING_CALLBACK(
			IntPtr GuiStreamingCallbackCtx,		// [in]
			IntPtr Bitmap);						// [in]

//		typedef BioAPI_RETURN (BioAPI *BioAPI_STREAM_CALLBACK)
//			(void *StreamCallbackCtx,			// [in]
//			BioAPI_DATA_PTR OutMessage,			// [in]
//			BioAPI_DATA_PTR InMessage);			// [out/optional]
	public delegate BioAPI_RETURN BioAPI_STREAM_CALLBACK(
				IntPtr StreamCallbackCtx,
				IntPtr OutMessage,
				IntPtr InMessage);

	public enum BioAPI_RETURN :uint 
	{
		BioAPI_OK = 0,
		BioAPI_BASE_ERROR = 0x00000000,
		/* The configurable BioAPI error code base value. */
		BioAPI_ERRORCODE_COMPONENT_EXTENT =0x00001000,
		/* The configurable number of error codes allocated for each component type.
		 * This number must be greater than BioAPI_ERRORCODE_COMMON_EXTENT, and
		 * should allow at least half the space for specification-defined error codes.
		 */
		BioAPI_ERRORCODE_COMMON_EXTENT = 0x100,
		/* The number of error codes allocated to indicate "common" errors. */
		BioAPI_ERRORCODE_CUSTOM_OFFSET = 0x00000800,
		/* The configurable offset at which custom error codes are allocated. Must be
		 * greater than BioAPI_ERRCODE_COMMON_EXTENT and less than
		 * BioAPI_ERRORCODE_COMPONENT_EXTENT.  A BSP with "custom" error codes simply
		 * starts assigning them from this offset (without regard to any other BSPs.)
		 */

		/* BioAPI Error Code Constants */
		BioAPI_H_FRAMEWORK_BASE_ERROR = BioAPI_BASE_ERROR,
		BioAPI_H_FRAMEWORK_PRIVATE_ERROR = BioAPI_H_FRAMEWORK_BASE_ERROR + BioAPI_ERRORCODE_CUSTOM_OFFSET,
		BioAPI_BSP_BASE_ERROR = BioAPI_H_FRAMEWORK_BASE_ERROR + BioAPI_ERRORCODE_COMPONENT_EXTENT,
		BioAPI_BSP_PRIVATE_ERROR = BioAPI_BSP_BASE_ERROR + BioAPI_ERRORCODE_CUSTOM_OFFSET,
		BioAPI_D_FRAMEWORK_BASE_ERROR = BioAPI_BSP_BASE_ERROR + BioAPI_ERRORCODE_COMPONENT_EXTENT,
		BioAPI_D_FRAMEWORK_PRIVATE_ERROR = BioAPI_D_FRAMEWORK_BASE_ERROR + BioAPI_ERRORCODE_CUSTOM_OFFSET,
		BioAPI_DEVICE_BASE_ERROR = BioAPI_D_FRAMEWORK_BASE_ERROR + BioAPI_ERRORCODE_COMPONENT_EXTENT,
		BioAPI_DEVICE_PRIVATE_ERROR	= BioAPI_DEVICE_BASE_ERROR + BioAPI_ERRORCODE_CUSTOM_OFFSET,

		/*
			General Error Values
			The following error values can be returned by the H-Framework for any BioAPI function.
		*/
		BioAPIERR_H_FRAMEWORK_INVALID_MODULE_HANDLE = BioAPI_H_FRAMEWORK_BASE_ERROR + BioAPI_ERRORCODE_COMMON_EXTENT + 1,
		/* The given service provider handle is not valid */
		BioAPIERR_H_FRAMEWORK_NOT_INITIALIZED = BioAPI_H_FRAMEWORK_BASE_ERROR + BioAPI_ERRORCODE_COMMON_EXTENT + 2,
		/* A function is called without initializing the BioAPI */


		/*
			Common Error Codes For All Module Types
			The following codes can be returned by multiple components.
		*/
		BioAPI_ERRCODE_INTERNAL_ERROR= 0x0001,
		/* General system error; indicates that an operating system or internal state
		* error has occurred and the system may not be in a known state.
		*/

		BioAPI_ERRCODE_MEMORY_ERROR = 0x0002,
		/* A memory error occurred. */
		BioAPI_ERRCODE_REGISTRY_ERROR = 0x0003,
		/* The registry could not be accessed to complete the operation */
		BioAPI_ERRCODE_INVALID_POINTER = 0x0004,
		/* An input/output function parameter or input/output field inside of a data
		* structure is an invalid pointer.
		*/
		BioAPI_ERRCODE_INVALID_INPUT_POINTER = 0x0005,
		/* An input function parameter or input field in a data structure is an
		* invalid pointer.
		*/
		BioAPI_ERRCODE_INVALID_OUTPUT_POINTER = 0x0006,
		/* An output function parameter or output field in a data structure is an
		* invalid pointer.
		*/
		BioAPI_ERRCODE_FUNCTION_NOT_IMPLEMENTED = 0x0007,
		/* The function is not implemented by the service provider. */
		BioAPI_ERRCODE_OS_ACCESS_DENIED = 0x0009,
		/* The operating system denied access to a required resource. */
		BioAPI_ERRCODE_FUNCTION_FAILED = 0x000A,
		/* The function failed for an unknown reason. */
		BioAPI_ERRCODE_INVALID_UUID = 0x000C,
		/* Invalid UUID */
		BioAPI_ERRCODE_INCOMPATIBLE_VERSION = 0x0041,
		/* Version is not compatible with the current version. */

		/* Error values with the following code enumeration values may be returned
		* from any function that takes as input a BioAPI_DATA.
		*/
		BioAPI_ERRCODE_INVALID_DATA = 0x0046,
		/* The data in an input parameter is invalid. */

		/* Error values with the following code enumeration values may be returned
		* from any function that takes as input a DB handle.
		*/
		BioAPI_ERRCODE_INVALID_DB_HANDLE = 0x004A,
		/* Invalid database handle */

		/*
			H-Framework Error Values derived from the Common Error Codes
		*/
		BioAPIERR_H_FRAMEWORK_INTERNAL_ERROR = BioAPI_H_FRAMEWORK_BASE_ERROR+BioAPI_ERRCODE_INTERNAL_ERROR,
		BioAPIERR_H_FRAMEWORK_MEMORY_ERROR = BioAPI_H_FRAMEWORK_BASE_ERROR+BioAPI_ERRCODE_MEMORY_ERROR,
		BioAPIERR_H_FRAMEWORK_REGISTRY_ERROR = BioAPI_H_FRAMEWORK_BASE_ERROR+BioAPI_ERRCODE_REGISTRY_ERROR,
		BioAPIERR_H_FRAMEWORK_INVALID_POINTER = BioAPI_H_FRAMEWORK_BASE_ERROR+BioAPI_ERRCODE_INVALID_POINTER,
		BioAPIERR_H_FRAMEWORK_INVALID_INPUT_POINTER	= BioAPI_H_FRAMEWORK_BASE_ERROR+BioAPI_ERRCODE_INVALID_INPUT_POINTER,
		BioAPIERR_H_FRAMEWORK_INVALID_OUTPUT_POINTER = BioAPI_H_FRAMEWORK_BASE_ERROR+BioAPI_ERRCODE_INVALID_OUTPUT_POINTER,
		BioAPIERR_H_FRAMEWORK_FUNCTION_NOT_IMPLEMENTED = BioAPI_H_FRAMEWORK_BASE_ERROR+BioAPI_ERRCODE_FUNCTION_NOT_IMPLEMENTED,
		BioAPIERR_H_FRAMEWORK_OS_ACCESS_DENIED = BioAPI_H_FRAMEWORK_BASE_ERROR+BioAPI_ERRCODE_OS_ACCESS_DENIED,
		BioAPIERR_H_FRAMEWORK_FUNCTION_FAILED = BioAPI_H_FRAMEWORK_BASE_ERROR+BioAPI_ERRCODE_FUNCTION_FAILED,
		BioAPIERR_H_FRAMEWORK_INVALID_UUID = BioAPI_H_FRAMEWORK_BASE_ERROR+BioAPI_ERRCODE_INVALID_UUID,
		BioAPIERR_H_FRAMEWORK_INCOMPATIBLE_VERSION = BioAPI_H_FRAMEWORK_BASE_ERROR+BioAPI_ERRCODE_INCOMPATIBLE_VERSION,

		/*
			H-Framework-specific Error Values
			Reserve first 16 H-FRAMEWORK Error Codes for general errors
		*/
		BioAPI_H_FRAMEWORK_BASE_H_FRAMEWORK_ERROR = BioAPI_H_FRAMEWORK_BASE_ERROR+BioAPI_ERRORCODE_COMMON_EXTENT+0x10,
		BioAPIERR_H_FRAMEWORK_MODULE_LOAD_FAILED = BioAPI_H_FRAMEWORK_BASE_H_FRAMEWORK_ERROR+6,
		/* BSP Module Load function failed */
		BioAPIERR_H_FRAMEWORK_MODULE_UNLOAD_FAILED = BioAPI_H_FRAMEWORK_BASE_H_FRAMEWORK_ERROR+8,
		/* BSP Module Unload function failed */
		BioAPIERR_H_FRAMEWORK_LIB_REF_NOT_FOUND	= BioAPI_H_FRAMEWORK_BASE_H_FRAMEWORK_ERROR+9,
		/* A reference to the loaded library cannot be obtained */
		BioAPIERR_H_FRAMEWORK_INVALID_MODULE_FUNCTION_TABLE = BioAPI_H_FRAMEWORK_BASE_H_FRAMEWORK_ERROR+10,
		/* BSP Module function table registered with CSSM is invalid */
		BioAPIERR_H_FRAMEWORK_MODULE_NOT_LOADED	= BioAPI_H_FRAMEWORK_BASE_H_FRAMEWORK_ERROR+14,
		/* Module was not loaded */
		BioAPIERR_H_FRAMEWORK_INVALID_DEVICE_ID	= BioAPI_H_FRAMEWORK_BASE_H_FRAMEWORK_ERROR+15,
		/* Invalid DeviceId was requested */

		/*
			BSP Error Values derived from the Common Error Codes
		*/
		BioAPIERR_BSP_INTERNAL_ERROR = BioAPI_BSP_BASE_ERROR+BioAPI_ERRCODE_INTERNAL_ERROR,
		BioAPIERR_BSP_MEMORY_ERROR	= BioAPI_BSP_BASE_ERROR+BioAPI_ERRCODE_MEMORY_ERROR,
		BioAPIERR_BSP_REGISTRY_ERROR = BioAPI_BSP_BASE_ERROR+BioAPI_ERRCODE_REGISTRY_ERROR,
		BioAPIERR_BSP_INVALID_POINTER = BioAPI_BSP_BASE_ERROR+BioAPI_ERRCODE_INVALID_POINTER,
		BioAPIERR_BSP_INVALID_INPUT_POINTER	= BioAPI_BSP_BASE_ERROR+BioAPI_ERRCODE_INVALID_INPUT_POINTER,
		BioAPIERR_BSP_INVALID_OUTPUT_POINTER = BioAPI_BSP_BASE_ERROR+BioAPI_ERRCODE_INVALID_OUTPUT_POINTER,
		BioAPIERR_BSP_FUNCTION_NOT_IMPLEMENTED = BioAPI_BSP_BASE_ERROR+BioAPI_ERRCODE_FUNCTION_NOT_IMPLEMENTED,
		BioAPIERR_BSP_OS_ACCESS_DENIED = BioAPI_BSP_BASE_ERROR+BioAPI_ERRCODE_OS_ACCESS_DENIED,
		BioAPIERR_BSP_FUNCTION_FAILED = BioAPI_BSP_BASE_ERROR+BioAPI_ERRCODE_FUNCTION_FAILED,
		BioAPIERR_BSP_INVALID_DATA	= BioAPI_BSP_BASE_ERROR+BioAPI_ERRCODE_INVALID_DATA,
		BioAPIERR_BSP_INVALID_DB_HANDLE	= BioAPI_BSP_BASE_ERROR+BioAPI_ERRCODE_INVALID_DB_HANDLE,

		/*
			BSP-specific Error Values
		*/
		BioAPI_BSP_BASE_BSP_ERROR = BioAPI_BSP_BASE_ERROR+BioAPI_ERRORCODE_COMMON_EXTENT,
		BioAPIERR_BSP_UNABLE_TO_CAPTURE	= BioAPI_BSP_BASE_BSP_ERROR+1,
		/* BSP is unable to capture raw samples from the device */
		BioAPIERR_BSP_TOO_MANY_HANDLES = BioAPI_BSP_BASE_BSP_ERROR+2,
		/* The BSP has no more space to allocate BIR handles */
		BioAPIERR_BSP_TIMEOUT_EXPIRED = BioAPI_BSP_BASE_BSP_ERROR+3,
		/* The Function has been terminated because the timeout value has expired */
		BioAPIERR_BSP_INVALID_BIR = BioAPI_BSP_BASE_BSP_ERROR+4,
		/* The input BIR is invalid for the purpose required */
		BioAPIERR_BSP_BIR_SIGNATURE_FAILURE	= BioAPI_BSP_BASE_BSP_ERROR+5,
		/* The BSP could not validate the signature on the BIR */
		BioAPIERR_BSP_UNABLE_TO_WRAP_PAYLOAD = BioAPI_BSP_BASE_BSP_ERROR+6,
		/* The BSP is unable to include the payload in the new BIR */
		BioAPIERR_BSP_NO_INPUT_BIRS	= BioAPI_BSP_BASE_BSP_ERROR+8,
		/* The identify population is NULL */
		BioAPIERR_BSP_UNSUPPORTED_FORMAT = BioAPI_BSP_BASE_BSP_ERROR+9,
		/* The BSP does not support the data form for the Import function */
		BioAPIERR_BSP_UNABLE_TO_IMPORT = BioAPI_BSP_BASE_BSP_ERROR+10,
		/* The BSP was unable to construct a BIR from the input data */		
		BioAPIERR_BSP_FUNCTION_NOT_SUPPORTED = BioAPI_BSP_BASE_BSP_ERROR+12,
		/* The BSP does not support this operation. */
		BioAPIERR_BSP_INCONSISTENT_PURPOSE = BioAPI_BSP_BASE_BSP_ERROR+13,

		/* The purpose recorded in the BIR, and the requested purpose are inconsistent
		* with the function being performed.
		*/
		BioAPIERR_BSP_BIR_NOT_FULLY_PROCESSED = BioAPI_BSP_BASE_BSP_ERROR+14,
		/* The function requires a fully-processed BIR. */
		BioAPIERR_BSP_PURPOSE_NOT_SUPPORTED	= BioAPI_BSP_BASE_BSP_ERROR+15,
		/* The BSP does not support the requested purpose. */
		BioAPIERR_BSP_UNABLE_TO_OPEN_DATABASE = BioAPI_BSP_BASE_BSP_ERROR+256,
		/* BSP is unable to open specified database */
		BioAPIERR_BSP_DATABASE_IS_LOCKED = BioAPI_BSP_BASE_BSP_ERROR+257,
		/* Database cannot be opened for the access requested because it is locked */
		BioAPIERR_BSP_DATABASE_DOES_NOT_EXIST = BioAPI_BSP_BASE_BSP_ERROR+258,
		/* The specified database name does not exist */
		BioAPIERR_BSP_DATABASE_ALREADY_EXISTS = BioAPI_BSP_BASE_BSP_ERROR+259,
		/* Create failed because the database already exists */
		BioAPIERR_BSP_INVALID_DATABASE_NAME	= BioAPI_BSP_BASE_BSP_ERROR+260,
		/* Invalid database name */
		BioAPIERR_BSP_RECORD_NOT_FOUND = BioAPI_BSP_BASE_BSP_ERROR+261,
		/* No record exists with the requested key */
		BioAPIERR_BSP_CURSOR_IS_INVALID	= BioAPI_BSP_BASE_BSP_ERROR+262,
		/* The specified cursor is invalid */
		BioAPIERR_BSP_DATABASE_IS_OPEN = BioAPI_BSP_BASE_BSP_ERROR+263,
		/* Database is already open */
		BioAPIERR_BSP_INVALID_ACCESS_REQUEST = BioAPI_BSP_BASE_BSP_ERROR+264,
		/* Unrecognized access type */
		BioAPIERR_BSP_END_OF_DATABASE = BioAPI_BSP_BASE_BSP_ERROR+265,
		/* End of database has been reached. */
		BioAPIERR_BSP_UNABLE_TO_CREATE_DATABASE	= BioAPI_BSP_BASE_BSP_ERROR+266,
		/* BSP cannot create the database. */
		BioAPIERR_BSP_UNABLE_TO_CLOSE_DATABASE = BioAPI_BSP_BASE_BSP_ERROR+267,
		/* BSP cannot close the database. */
		BioAPIERR_BSP_UNABLE_TO_DELETE_DATABASE	= BioAPI_BSP_BASE_BSP_ERROR+268
		/* BSP cannot delete the database. */
	};
}