/*****************************************************************************/
/*  MATRIXDEMO.CS   MS-WINDOWS Win32 (95/98/ME/NT/2K/XP)                     */
/*                                                                           */
/*  (C) TDi GmbH                                                             */
/*                                                                           */
/*  Example for C#                                                           */
/*****************************************************************************/

using System;
using System.Windows.Forms; // MessageBox
using System.Runtime.InteropServices; // Marshalling
using MXAPI;

namespace matrix
{
	/// 
	/// Summary description for MatrixDemo.
	/// 
	public class MatrixDemo
	{
		private short RetCode;
		private DNGINFO[] xBuffer;
		private int[] DataIn;
		private int[] DataOut;
		private int[] KeyData;
		private int[] DataBlock;
		private short DNG_LPTADR;
		private short DNG_Count;
		private short DNG_Nummer;
		private short DNG_Mem;
		private short DNG_MaxVar;
		private int DNG_Version;
		private int DNG_SerNr;
		private short VerMajor;
		private short VerMinor;
		private short AppSlot;
	
		// ***********************************************************
		// * In this example we use the demo UserCode 1234.          *
		// ***********************************************************
		const short UserCode = 1234;
		short DNG_Port;

		public MatrixDemo()
		{
			xBuffer = new DNGINFO[3];
			DataIn = new int[256];
			DataOut = new int[256];
			KeyData = new int[4];
			DataBlock = new int[2];
		}


		public void SetActivePort(string Port)
		{
			DNG_Port = 0;
			switch(Port)
			{
				case "LPT1":
					DNG_Port = 1;
					break;
				case "LPT2":
					DNG_Port = 2;
					break;

				case "LPT3":
					DNG_Port = 3;
					break;
				case "USB":
					DNG_Port = 85;
					break;
			}    
		}

		public void LPT_Port_Exists()
		{
			if(DNG_Port == 85)
			{
				// USB 
				MessageBox.Show("DNG_Port=85 (USB) \n" + "This function works only with LPT-Ports!");
				return;
			}	
	
			RetCode = Matrix.Init_MatrixAPI();
		
			// ***********************************************************
			// * Check whether the LPT port DNG_Port is available        *
			// ***********************************************************
			DNG_LPTADR = Matrix.GetPortAdr(DNG_Port);
		
			if(DNG_LPTADR == 0)
				MessageBox.Show("LPT" + DNG_Port.ToString() +  " not available!");
			else
				MessageBox.Show("The Address of LPT" + DNG_Port.ToString() + " is: x" + DNG_LPTADR.ToString("X"));
			
			RetCode = Matrix.Release_MatrixAPI();
		}
	
		public void Number_of_Dongles()
		{
			RetCode = Matrix.Init_MatrixAPI();
		
			// ***********************************************************
			// * Search for number of Dongles at DNG_Port                *
			// ***********************************************************
			DNG_Count = Matrix.Dongle_Count(DNG_Port);
		
			if(DNG_Count <= 0)
				MessageBox.Show("There is no Dongle at Port " + DNG_Port.ToString() + " available!");
			else
				MessageBox.Show("Found: " + DNG_Count.ToString() + " Dongles at Port " + DNG_Port.ToString() + " gefunden");
		
			RetCode = Matrix.Release_MatrixAPI();
		}

		public void Dongle_Find_Ex()
		{
			string MessageString;
			short  i;
		
			RetCode = Matrix.Init_MatrixAPI();
		
			// ***********************************************************
			// * Search all LPT-Dongles                                  *
			// ***********************************************************
		
			unsafe
			{
				fixed(DNGINFO* buffer = xBuffer)
				{
					RetCode = Matrix.Dongle_FindEx(buffer);
				}
			}

			if(RetCode <= 0)
			{
				MessageBox.Show("No LPT Ports available!");
				RetCode = Matrix.Release_MatrixAPI();
				return;
			}
			else
			{
				MessageString = "Found: " + RetCode.ToString() + " LPT-Ports\n\n";
			
				for(i = 1; i <= RetCode; i++)
				{
					MessageString = MessageString + "Address of LPT" + i.ToString() + ": 0x" + xBuffer[i - 1].LPT_Adr.ToString("X") 
                                                                      + "\nDongles at LPT" + i.ToString() + "  : " + xBuffer[i - 1].DNG_Cnt.ToString() + "\n\n";
				}
			}
		
			MessageBox.Show(MessageString);
		
			RetCode = Matrix.Release_MatrixAPI();
		}

		public void Memory_of_Dongle()
		{
			RetCode = Matrix.Init_MatrixAPI();
		
			// ***********************************************************
			// * Read memory size of last Dongle at DNG_Port and         *
			// * calculate the maximum number of data fields             *
			// ***********************************************************
			DNG_Nummer = Matrix.Dongle_Count(DNG_Port);
		
			DNG_Mem = Matrix.Dongle_MemSize(DNG_Nummer, DNG_Port);
		
			if(DNG_Mem <= 0)
			{
				MessageBox.Show("Error while determining Dongle memory!");
				return;
			}
		
			DNG_MaxVar = (short)(DNG_Mem / 4);
		
			MessageBox.Show("Number of variables of this Dongle: " + DNG_MaxVar.ToString());	
			
			RetCode = Matrix.Release_MatrixAPI();
		}
		
		public void Version_of_Dongle()
		{
			RetCode = Matrix.Init_MatrixAPI();
		
			// ***********************************************************
			// * Read Dongle version from last Dongle at DNG_Port        *
			// ***********************************************************
			DNG_Nummer = Matrix.Dongle_Count(DNG_Port);
		
			DNG_Version = Matrix.Dongle_Version(DNG_Nummer, DNG_Port);
		
			if(DNG_Version <= 0)
			{
				MessageBox.Show("Error while reading Dongle version!");
			}
			else
			{
				VerMinor = (short)(DNG_Version & 0xffff);
				VerMajor = (short)(DNG_Version >> 16);
				MessageBox.Show("This Dongle has the version number: " + VerMajor.ToString() + "." + VerMinor.ToString());
			}

			RetCode = Matrix.Release_MatrixAPI();		
		}
	
		public void Read_Dongle_SerNr()
		{
			RetCode = Matrix.Init_MatrixAPI();
		
			// ***********************************************************
			// * Read the SerialNo. of last Dongle at DNG_Port via       *
			// * UserCode and display.                                   *
			// ***********************************************************
			DNG_Nummer = Matrix.Dongle_Count(DNG_Port);
		
			DNG_SerNr = Matrix.Dongle_ReadSerNr(UserCode, DNG_Nummer, DNG_Port);
		
			if(DNG_SerNr < 0)
			{
				MessageBox.Show("Error " + DNG_SerNr.ToString() + " while reading the Dongle SerialNo.!");
				RetCode = Matrix.Release_MatrixAPI();
				return;
			}
			MessageBox.Show("SerialNo. of the Dongle:  (dec) " + DNG_SerNr.ToString() + "    (hex) " + DNG_SerNr.ToString("X"));
		
			RetCode = Matrix.Release_MatrixAPI();
		
		}
	
		public void Read_Dongle_Data()
		{
			string MessageString;
			short  i;
		
			RetCode = Matrix.Init_MatrixAPI();
		
			// ***********************************************************
			// * Read 3 data fields from last Dongle at DNG_Port via     *
			// * UserCode and display.                                   *
			// ***********************************************************
			DNG_Nummer = Matrix.Dongle_Count(DNG_Port);
		
			RetCode = Matrix.Dongle_ReadData(UserCode, ref DataIn[0], 3, DNG_Nummer, DNG_Port);
		
			if(RetCode < 0)
			{

				MessageBox.Show("Error " + RetCode.ToString() + " while reading the Dongle data!");
				RetCode = Matrix.Release_MatrixAPI();
				return;
			}
		
			MessageString = "Content of dongle variables: \n\n";
			for(i = 0; i <= 2; i++)
			{
				MessageString = MessageString + "Var" + (i + 1).ToString("D4") + ":  " + DataIn[i].ToString() + "\n";
			}
			MessageBox.Show(MessageString);
		
			RetCode = Matrix.Release_MatrixAPI();
		
		}
	
		public void Write_Dongle_Data()
		{
			short  i;

			RetCode = Matrix.Init_MatrixAPI();
		
			// ***********************************************************
			// * Save 3 data fields in last Dongle at DNG_Port via       *
			// * UserCode. The values 101,102,103 are saved as example.  *
			// ***********************************************************
			DNG_Nummer = Matrix.Dongle_Count(DNG_Port);
		
			for(i = 0; i <= 2; i++)
			{
				DataOut[i] = 101 + i;
			}

			RetCode = Matrix.Dongle_WriteData(UserCode, ref DataOut[0], 3, DNG_Nummer, DNG_Port);
		
			if(RetCode < 0)
				MessageBox.Show("Error " + RetCode.ToString() + " while writing Dongle data!");
			else
				MessageBox.Show("The Dongle data have been written successfully!");
		
			RetCode = Matrix.Release_MatrixAPI();		
		}	

		public void Dongle_Encrypt_Decrypt()
		{
			string MessageString;
		
			RetCode = Matrix.Init_MatrixAPI();
		
			DataBlock[0] = 1234567890; // Clear Data
			DataBlock[1] = 1234567890; // Clear Data
		
			MessageString = "Clear Data:   \t" + "(dec)  " + DataBlock[0].ToString() + "\t   " + DataBlock[1].ToString() + "\n\t\t(hex)  " + DataBlock[0].ToString("X") + "\t   " + DataBlock[1].ToString("X") + "\n\n";
		
			DNG_Nummer = Matrix.Dongle_Count(DNG_Port);
		
			// ***********************************************************
			// * Encrypt DataBlock over the Dongle                       *
			// ***********************************************************
			RetCode = Matrix.Dongle_EncryptData(UserCode, ref DataBlock[0], DNG_Nummer, DNG_Port);
		
			if(RetCode < 0)
			{
				MessageBox.Show("Error " + RetCode.ToString());
				RetCode = Matrix.Release_MatrixAPI();
				return;
			}
		
			MessageString = MessageString + "Encrypted Data: \t(dec)  " + DataBlock[0].ToString() + "\t   " + DataBlock[1].ToString() + "\n\t\t(hex)  " + DataBlock[0].ToString("X") + "\t   " + DataBlock[1].ToString("X") + "\n\n";
		
			// ***********************************************************
			// * Decrypt DataBlock over the Dongle                       *
			// ***********************************************************
			RetCode = Matrix.Dongle_DecryptData(UserCode, ref DataBlock[0], DNG_Nummer, DNG_Port);
		
			if(RetCode < 0)
			{
				MessageBox.Show("Error " + RetCode.ToString());
				RetCode = Matrix.Release_MatrixAPI();
			}
		
			MessageBox.Show(MessageString + "Decrypted Data: \t(dec)  " + DataBlock[0].ToString() + "\t   " + DataBlock[1].ToString() + "\n\t\t(hex)  " + DataBlock[0].ToString("X") + "\t   " + DataBlock[1].ToString("X") + "\n\n");
	
			RetCode = Matrix.Release_MatrixAPI();
		}
	
		public void Version_of_API()
		{
			int RetVer;
		
			RetCode = Matrix.Init_MatrixAPI();
		
			// ***********************************************************
			// * Read the version of the Matrix-API                      *
			// ***********************************************************
			RetVer = Matrix.GetVersionAPI();
		
			if(RetVer == 0)
				MessageBox.Show("Error while reading API version!");
			else
			{
				VerMinor = (short)(RetVer & 0xffff);
				VerMajor = (short)(RetVer >> 16);
				MessageBox.Show("The Matrix-API have the version: " + VerMajor.ToString() + "." + VerMinor.ToString());
			}		
		
			RetCode = Matrix.Release_MatrixAPI();
		
		}
	
		public void Dongle_Network()
		{

			// *************************************************************
			// * Network                                                   *
			// * Example: the dongle is prepared with the value 7 in       *
			// *          Var0002, meaning AppSlot=2 and max. Users = 7    *
			// *          (AppSlot2 = max. 7 Users)                        *
			// *************************************************************
		
			RetCode = Matrix.Init_MatrixAPI();
		
			// *************************************************************
			// * Max. Users stored in AppSlot 2 (Var0002 of the dongle)    *
			// *************************************************************
			AppSlot = 2;
		
			// *************************************************************
			// * Activate Network access into the Matrix-API               *
			// *************************************************************
			string MxNetFile;
			MxNetFile = "D:\\TEMP\\MXNET2.DAT";

			unsafe
			{
				fixed(char* buffer = MxNetFile)
				{
					RetCode = Matrix.SetConfig_MatrixNet(1, buffer);
				}
			}
		
			// *************************************************************
			// * Read the Dongle count from MxNetFile                      *
			// * !! DNG_Port will be ignored in the Network mode !!        *
			// *************************************************************
			DNG_Nummer = Matrix.Dongle_Count(DNG_Port);
		
			// *************************************************************
			// * LogIn will lock one User-Slot and the returned value is   *
			// * the remaining free User-Slots (for our Example RetCode=6) *
			// *************************************************************
			RetCode = Matrix.LogIn_MatrixNet(UserCode, AppSlot, DNG_Nummer);
			if(RetCode < 0)
			{
				if(RetCode == -31)
					MessageBox.Show("All Users are active!\nNo more User-Slots free.");
				else
					MessageBox.Show("LogIn failed !  " + RetCode.ToString());
			}	
			else
				MessageBox.Show("LogIn successfull !  Free User-Slots: " + RetCode.ToString() + "\n\n" +
				                "Now you can check the Active Users List in MxNet-Server.\n" +
				                "After clicking the  button, the User will be Logged Out\n" +
				                "and removed from the Active Users List in MxNet-Server.");
		
			// *************************************************************
			// * LogOut will free the User-Slot and the returned value is  *
			// * the remaining free User-Slots (for our Example RetCode=7) *
			// *************************************************************
			RetCode = Matrix.LogOut_MatrixNet(UserCode, AppSlot, DNG_Nummer);
			if(RetCode < 0)
				MessageBox.Show("LogOut failed !  " + RetCode.ToString());
			else
				MessageBox.Show("LogOut successfull ! Free User-Slots: " + RetCode.ToString());
		
			// *************************************************************
			// * Deactivate Network access into the Matrix-API             *
			// *************************************************************
			unsafe
			{
				RetCode = Matrix.SetConfig_MatrixNet(0, null);
			}
		
			RetCode = Matrix.Release_MatrixAPI();
		
		}
	
		public void App_Encrypt()
		{
			string MessageString;
			uint[] Key = new uint[4];
			uint[] Data = new uint[2];
		
			Data[0] = 0x499602D2;   // dec: 1234567890
			Data[1] = 0x499602D2;   // dec: 1234567890
		
			Key[0] = 0x423A612E;    // dec: 1111122222
			Key[1] = 0x423A8C95;    // dec: 1111133333
			Key[2] = 0x8474C25C;    // dec: 2222244444
			Key[3] = 0x8474EDC3;    // dec: 2222255555
		
			MessageString = "Clear Data:   \t(dec)  " + Data[0].ToString() + "\t      " + Data[1].ToString() + 
			                          "\n\t\t(hex)  " + Data[0].ToString("X") + "\t      " + Data[1].ToString("X") + 
			                          "\n\n" + 
			                "Key:          \t(dec)  " + Key[0].ToString() + "\t      " + Key[1].ToString() + "\t  " + Key[2].ToString() + "\t" + Key[3].ToString() + 
			                          "\n\t\t(hex)  " + Key[0].ToString("X") + "\t      " + Key[1].ToString() + "\t  " + Key[2].ToString() + "\t" + Key[3].ToString("X") + "\n\n";

			MATRIX_ENCRYPT.MxCrypt.MxApp_Encrypt(Data, Key);
		
			// *** Display Data[0]/Data[1] as long ***
			MessageBox.Show(MessageString + "Encrypted Data: \t(dec)  " + Data[0].ToString() + "\t      " + Data[1].ToString() + 
			                                            "\n\t\t(hex)  " + Data[0].ToString("X") + "\t      " + Data[1].ToString("X") + "\n\n");
		}

	} // end class
} // end namespace


/*****************************************************************************/
/*  MXAPI.CS   MS-WINDOWS Win32 (95/98/ME/NT/2K/XP)                          */
/*                                                                           */
/*  (C) TDi GmbH                                                             */
/*                                                                           */
/*  Defines to acces the Matrix API in C#                                    */
/*****************************************************************************/

namespace MXAPI
{
    using System;
    using System.Runtime.InteropServices;   /* Required namespace for the DllImport method */

	public struct DNGINFO
	{
		public short LPT_Nr;
		public short LPT_Adr;
		public short DNG_Cnt;
	};

	public class Matrix
	{
		/* This c#-class will import the Matrix API classes */	
		
		[DllImport("MATRIX32.DLL", EntryPoint="Init_MatrixAPI", CallingConvention = CallingConvention.StdCall)]
		public static extern short Init_MatrixAPI();

		[DllImport("MATRIX32.DLL", EntryPoint="Release_MatrixAPI", CallingConvention = CallingConvention.StdCall)]
		public static extern short Release_MatrixAPI();

		[DllImport("MATRIX32.DLL", EntryPoint="GetVersionAPI", CallingConvention = CallingConvention.StdCall)]
		public static extern int GetVersionAPI();

		[DllImport("MATRIX32.DLL", EntryPoint="GetVersionDRV", CallingConvention = CallingConvention.StdCall)]
		public static extern int GetVersionDRV();

		[DllImport("MATRIX32.DLL", EntryPoint="GetVersionDRV_USB", CallingConvention = CallingConvention.StdCall)]
		public static extern int GetVersionDRV_USB();

		[DllImport("MATRIX32.DLL", EntryPoint="GetVersionDRV_USB", CallingConvention = CallingConvention.StdCall)]
		public static extern void SetW95Access(short Mode);

		[DllImport("MATRIX32.DLL", EntryPoint="GetPortAdr", CallingConvention = CallingConvention.StdCall)]
		public static extern short GetPortAdr(short Port);

		[DllImport("MATRIX32.DLL", EntryPoint="PausePrinterActivity", CallingConvention = CallingConvention.StdCall)]
		public static extern short PausePrinterActivity();

		[DllImport("MATRIX32.DLL", EntryPoint="ResumePrinterActivity", CallingConvention = CallingConvention.StdCall)]
		public static extern short ResumePrinterActivity();

		[DllImport("MATRIX32.DLL", EntryPoint="Dongle_Find", CallingConvention = CallingConvention.StdCall)]
		public static extern short Dongle_Find();

		[DllImport("MATRIX32.DLL", EntryPoint="Dongle_FindEx", CallingConvention = CallingConvention.StdCall)]
		unsafe public static extern short Dongle_FindEx(DNGINFO* DngInfo);

		[DllImport("MATRIX32.DLL", EntryPoint="Dongle_Version", CallingConvention = CallingConvention.StdCall)]
		public static extern int Dongle_Version(short DngNr, short Port);

		[DllImport("MATRIX32.DLL", EntryPoint="Dongle_Model", CallingConvention = CallingConvention.StdCall)]
		public static extern int Dongle_Model(short DngNr, short Port);

		[DllImport("MATRIX32.DLL", EntryPoint="Dongle_MemSize", CallingConvention = CallingConvention.StdCall)]
		public static extern short Dongle_MemSize(short DngNr, short Port);

		[DllImport("MATRIX32.DLL", EntryPoint="Dongle_Count", CallingConvention = CallingConvention.StdCall)]
		public static extern short Dongle_Count(short Port);

		[DllImport("MATRIX32.DLL", EntryPoint="Dongle_ReadData", CallingConvention = CallingConvention.StdCall)]
		public static extern short Dongle_ReadData(int UserCode, ref int Data, short Count, short DngNr, short Port);

		[DllImport("MATRIX32.DLL", EntryPoint="Dongle_ReadDataEx", CallingConvention = CallingConvention.StdCall)]
		public static extern short Dongle_ReadDataEx(int UserCode, ref int Data, short Fpos, short Count, short DngNr, short Port);

		[DllImport("MATRIX32.DLL", EntryPoint="Dongle_ReadSerNr", CallingConvention = CallingConvention.StdCall)]
		public static extern int Dongle_ReadSerNr(int UserCode, short DngNr, short Port);

		[DllImport("MATRIX32.DLL", EntryPoint="Dongle_WriteData", CallingConvention = CallingConvention.StdCall)]
		public static extern short Dongle_WriteData(int UserCode, ref int Data, short Count, short DngNr, short Port);

		[DllImport("MATRIX32.DLL", EntryPoint="Dongle_WriteDataEx", CallingConvention = CallingConvention.StdCall)]
		public static extern short Dongle_WriteDataEx(int UserCode, ref int Data, short Fpos, short Count, short DngNr, short Port);

		[DllImport("MATRIX32.DLL", EntryPoint="Dongle_WriteKey", CallingConvention = CallingConvention.StdCall)]
		public static extern short Dongle_WriteKey(int UserCode, ref int KeyData, short DngNr, short Port);

		[DllImport("MATRIX32.DLL", EntryPoint="Dongle_GetKeyFlag", CallingConvention = CallingConvention.StdCall)]
		public static extern short Dongle_GetKeyFlag(int UserCode, short DngNr, short Port);

		[DllImport("MATRIX32.DLL", EntryPoint="Dongle_Exit", CallingConvention = CallingConvention.StdCall)]
		public static extern short Dongle_Exit();

		[DllImport("MATRIX32.DLL", EntryPoint="SetConfig_MatrixNet", CallingConvention = CallingConvention.StdCall)]
		unsafe public static extern short SetConfig_MatrixNet(short nAccess, char* nFile);
		// public static extern short SetConfig_MatrixNet(short nAccess, ref char nFile);

		[DllImport("MATRIX32.DLL", EntryPoint="GetConfig_MatrixNet", CallingConvention = CallingConvention.StdCall)]
		public static extern int GetConfig_MatrixNet(short Category);

		[DllImport("MATRIX32.DLL", EntryPoint="LogIn_MatrixNet", CallingConvention = CallingConvention.StdCall)]
		public static extern short LogIn_MatrixNet(int UserCode, short AppSlot, short DngNr);

		[DllImport("MATRIX32.DLL", EntryPoint="LogOut_MatrixNet", CallingConvention = CallingConvention.StdCall)]
		public static extern short LogOut_MatrixNet(int UserCode, short AppSlot, short DngNr);

		[DllImport("MATRIX32.DLL", EntryPoint="Dongle_EncryptData", CallingConvention = CallingConvention.StdCall)]
		public static extern short Dongle_EncryptData(int UserCode, ref int DataBlock, short DngNr, short Port);

		[DllImport("MATRIX32.DLL", EntryPoint="Dongle_DecryptData", CallingConvention = CallingConvention.StdCall)]
		public static extern short Dongle_DecryptData(int UserCode, ref int DataBlock, short DngNr, short Port);
	}
}