Unit matrix32;
{*****************************************************************************
  MATRIX32.PAS   MS-WINDOWS W32 (95/98/NT/2K/XP)

  Copyright (C) TDi GmbH

  Include File for Delphi
*****************************************************************************}


Interface

Type
  pLongWord = ^LongWord;

  DNGINFO = packed RECORD
              LPT_Nr  : smallint;
              LPT_Adr : smallint;
              DNG_Cnt : smallint;
            END;

  pDNGINFO  = ^DNGINFO;


FUNCTION Init_MatrixAPI        : smallint; stdcall; external 'matrix32.DLL';

FUNCTION Release_MatrixAPI     : smallint; stdcall; external 'matrix32.DLL';

FUNCTION PausePrinterActivity  : smallint; stdcall; external 'matrix32.DLL';

FUNCTION ResumePrinterActivity : smallint; stdcall; external 'matrix32.DLL';

FUNCTION GetVersionAPI         : LongInt; stdcall; external 'matrix32.DLL';

FUNCTION GetVersionDRV         : LongInt; stdcall; external 'matrix32.DLL';

FUNCTION GetVersionDRV_USB     : LongInt; stdcall; external 'matrix32.DLL';

FUNCTION GetPortAdr (DNG_LPT: smallint) : smallint; stdcall; external 'matrix32.DLL';

FUNCTION Dongle_Find           : smallint; stdcall; external 'matrix32.DLL';

FUNCTION Dongle_FindEx     (xbuffer : pDNGINFO): smallint; stdcall; external 'matrix32.DLL';

FUNCTION Dongle_Version    (DNG_Nr  : smallint;
                            DNG_Port: smallint) : LongInt; stdcall; external 'matrix32.DLL';

FUNCTION Dongle_Model      (DNG_Nr  : smallint;
                            DNG_Port: smallint) : LongInt; stdcall; external 'matrix32.DLL';

FUNCTION Dongle_MemSize    (DNG_Nr  : smallint;
                            DNG_Port: smallint) : smallint; stdcall; external 'matrix32.DLL';

FUNCTION Dongle_Count      (DNG_Port: smallint) : smallint; stdcall; external 'matrix32.DLL';

FUNCTION Dongle_ReadData   (UserCode: LongInt;
                            DataIn  : pLongWord;
                            MaxVar  : smallint;
                            DNG_Nr  : smallint;
                            DNG_Port: smallint) : smallint; stdcall; external 'matrix32.DLL';

FUNCTION Dongle_ReadDataEx (UserCode: LongInt;
                            DataIn  : pLongWord;
                            StartVar: smallint;
                            MaxVar  : smallint;
                            DNG_Nr  : smallint;
                            DNG_Port: smallint) : smallint; stdcall; external 'matrix32.DLL';

FUNCTION Dongle_WriteData  (UserCode: LongInt;
                            DataOut : pLongWord;
                            MaxVar  : smallint;
                            DNG_Nr  : smallint;
                            DNG_Port: smallint) : smallint; stdcall; external 'matrix32.DLL';

FUNCTION Dongle_WriteDataEx(UserCode: LongInt;
                            DataOut : pLongWord;
                            StartVar: smallint;
                            MaxVar  : smallint;
                            DNG_Nr  : smallint;
                            DNG_Port: smallint) : smallint; stdcall; external 'matrix32.DLL';

FUNCTION Dongle_ReadSerNr  (UserCode: LongInt;
                            DNG_Nr  : smallint;
                            DNG_Port: smallint) : LongInt; stdcall; external 'matrix32.DLL';

FUNCTION SetConfig_MatrixNet(NAccess: smallint;
                             NFile  : PChar) : smallint; stdcall; external 'matrix32.DLL';

FUNCTION GetConfig_MatrixNet(Category: smallint) : LongInt; stdcall; external 'matrix32.DLL';

FUNCTION LogIn_MatrixNet   (UserCode: LongInt;
                            AppSlot : smallint;
                            DNG_Nr  : smallint) : smallint; stdcall; external 'matrix32.DLL';

FUNCTION LogOut_MatrixNet  (UserCode: LongInt;
                            AppSlot : smallint;
                            DNG_Nr  : smallint) : smallint; stdcall; external 'matrix32.DLL';

FUNCTION Dongle_WriteKey   (UserCode: LongInt;
                            KeyData : pLongWord;
                            DNG_Nr  : smallint;
                            DNG_Port: smallint) : smallint; stdcall; external 'matrix32.DLL';

FUNCTION Dongle_GetKeyFlag (UserCode: LongInt;
                            DNG_Nr  : smallint;
                            DNG_Port: smallint) : smallint; stdcall; external 'matrix32.DLL';

FUNCTION Dongle_EncryptData(UserCode : LongInt; 
                            DataBlock: pLongWord;
                            DNG_Nr   : smallint;
                            DNG_Port : smallint) : smallint; stdcall; external 'matrix32.DLL';

FUNCTION Dongle_DecryptData(UserCode : LongInt;
                            DataBlock: pLongWord;
                            DNG_Nr   : smallint;
                            DNG_Port : smallint) : smallint; stdcall; external 'matrix32.DLL';

{****************************************************************************}


implementation

end.

-------------------------------------------------------------

unit MatrixExample;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ExtCtrls;

type
  TForm1 = class(TForm)
    Panel1: TPanel;
    RadioGroup1: TRadioGroup;
    GroupBox1: TGroupBox;
    Button1: TButton;
    ComboBox1: TComboBox;
    procedure Button1Click(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

implementation
uses
  mxtea, matrix32;
const
  UserCode = 1234;              (* the demo UserCode 1234 isd used here *)
  cTAB = #9;                    (* Code for Tab *)
  cRET = #13;                   (* Code for Return *)
var
  DNG_Port:     smallint;
  RetCode:      smallint;

{$R *.dfm}

(**********************************************************************)
procedure LPT_Port_Exists;
var
  DNG_LPTADR:   smallint;
begin
  if DNG_Port = 85 then  (* USB *)
    Showmessage('DNG_Port=85 (USB)' + cRET +
                'This function works only with LPT-Ports!')
  else begin
    RetCode := Init_MatrixAPI();
    (***********************************************************)
    (* Check whether the LPT port DNG_Port is available        *)
    (***********************************************************)
    DNG_LPTADR := GetPortAdr(DNG_Port);

    if DNG_LPTADR = 0 then
      Showmessage('LPT' + IntToStr(DNG_Port) + ' not available!')
    else
      Showmessage('The Address of LPT' + IntToStr(DNG_Port) + ' is: ' +
                 '0x' + Format('%x',[DNG_LPTADR]));

    RetCode := Release_MatrixAPI();
  end;
end;
(*--------------------------------------------------------------------*)
procedure Number_of_Dongles;
var
  DNG_Count:    smallint;
begin
  RetCode := Init_MatrixAPI();
  (***********************************************************)
  (* Search for number of Dongles at DNG_Port                *)
  (***********************************************************)
  DNG_Count := Dongle_Count(DNG_Port);
   
  if (DNG_Count <= 0) then
    Showmessage('There is no Dongle at Port ' + IntToStr(DNG_Port) +
                ' available!')
  else
    Showmessage('Found: ' + IntToStr(DNG_Count) +
                ' Dongles at Port ' + IntToStr(DNG_Port));

  RetCode := Release_MatrixAPI();
end;
(*--------------------------------------------------------------------*)
procedure Memory_of_Dongle;
var
  DNG_Nummer:   smallint;
  DNG_Mem:      smallint;
  DNG_MaxVar:   smallint;
begin
  RetCode := Init_MatrixAPI();
  (***********************************************************)
  (* Read memory size of last Dongle at DNG_Port and         *)
  (* calculate the maximum number of data fields             *)
  (***********************************************************)
  DNG_Nummer := Dongle_Count(DNG_Port);
  DNG_Mem := Dongle_MemSize(DNG_Nummer, DNG_Port);

  if (DNG_Mem <= 0) then
    Showmessage('Error while determining Dongle memory!')
  else begin
    DNG_MaxVar := DNG_Mem div 4;
    Showmessage('Number of variables of this Dongle: ' + IntToStr(DNG_MaxVar));
    RetCode := Release_MatrixAPI();
  end;
end;
(*--------------------------------------------------------------------*)
procedure Version_of_Dongle;
var
  DNG_Nummer:   smallint;
  DNG_Version:  LongInt;
  VerMinor:     smallint;
  VerMajor:     smallint;
begin
  RetCode := Init_MatrixAPI();
  (***********************************************************)
  (* Read Dongle version from last Dongle at DNG_Port        *)
  (***********************************************************)
   DNG_Nummer := Dongle_Count(DNG_Port);
   DNG_Version := Dongle_Version(DNG_Nummer, DNG_Port);

   if (DNG_Version <= 0) then
     Showmessage('Error while reading Dongle version!')
   else begin
     VerMinor := (DNG_Version and 65535);
     VerMajor := (DNG_Version shr 16);
     Showmessage('This Dongle has the version number: ' +
                  IntToStr(VerMajor) + '.' + IntToStr(VerMinor));
   end;

   RetCode := Release_MatrixAPI();
end;
(*--------------------------------------------------------------------*)
procedure Read_Dongle_SerNr;
var
  DNG_Nummer:   smallint;
  DNG_SerNr:    LongInt;
begin
  RetCode := Init_MatrixAPI();
  (***********************************************************)
  (* Read the SerialNo. of last Dongle at DNG_Port via       *)
  (* UserCode and display.                                   *)
  (***********************************************************)
  DNG_Nummer := Dongle_Count(DNG_Port);
  DNG_SerNr := Dongle_ReadSerNr(UserCode, DNG_Nummer, DNG_Port);

  if (DNG_SerNr < 0) then
    begin
      Showmessage('Error ' + IntToStr(DNG_SerNr) +
                  ' while reading the Dongle SerialNo.!');
      RetCode := Release_MatrixAPI();
    end
  else
    begin
      Showmessage('SerialNo. of the Dongle:  (dec) ' + IntToStr(DNG_SerNr) +
                  '    (hex) ' + Format('%x',[DNG_SerNr]));
      RetCode := Release_MatrixAPI();
    end;
end;
(*--------------------------------------------------------------------*)
procedure Read_Dongle_Data;
var
  DNG_Nummer:   smallint;
  DataIn:       array[0..255] of longword;
  MessageString: String;
  i:    smallint;
begin
  RetCode := Init_MatrixAPI();
  (***********************************************************)
  (* Read 3 data fields from last Dongle at DNG_Port via     *)
  (* UserCode and display.                                   *)
  (***********************************************************)
  DNG_Nummer := Dongle_Count(DNG_Port);
  RetCode := Dongle_ReadData(UserCode, @DataIn, 3, DNG_Nummer, DNG_Port);

  if (RetCode < 0) then
    begin
      Showmessage('Error ' + IntToStr(RetCode) +
                 ' while reading the Dongle data!');
     RetCode := Release_MatrixAPI();
    end
  else
    begin
      MessageString := 'Content of dongle variables: ' + cRET + cRET;
      for i := 0 to 2 do
        MessageString := MessageString + 'Var' + Format('%.4d',[i + 1]) +
                         ':  ' + IntToStr(DataIn[i]) + cRET;
      Showmessage(MessageString);
      RetCode := Release_MatrixAPI();
    end;
end;
(*--------------------------------------------------------------------*)
procedure Write_Dongle_Data;
var
  DNG_Nummer:   smallint;
  DataOut:      array[0..255] of longword;
  i:    smallint;
begin
  RetCode := 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 := Dongle_Count(DNG_Port);

  for i := 0 to 2 do
    DataOut[i] := 101 + i;

  RetCode := Dongle_WriteData(UserCode, @DataOut, 3, DNG_Nummer, DNG_Port);

  if (RetCode < 0) then
    Showmessage('Error ' + IntToStr(RetCode) + ' while writing Dongle data!')
  else
    Showmessage('The Dongle data have been written successfully!');

  RetCode := Release_MatrixAPI();
end;
(*--------------------------------------------------------------------*)
procedure Dongle_Find_Ex;
var
  xBuffer:      array[0..2] of DNGINFO;
  MessageString: String;
  i:    smallint;
begin
  RetCode := Init_MatrixAPI();
  (***********************************************************)
  (* Search all LPT-Dongles                                  *)
  (***********************************************************)
  RetCode := Dongle_FindEx(@xBuffer);

  if (RetCode <= 0) then
    begin
      Showmessage('No LPT Ports available!');
      RetCode := Release_MatrixAPI();
    end
  else
    begin
      MessageString := 'Found: ' + IntToStr(RetCode) +
                       ' LPT-Ports' + cRET + cRET;
      for i := 1 to RetCode do
        MessageString := MessageString +
          'Address of LPT' + IntToStr(i) +
          ': ' + '0x' + Format('%x',[xBuffer[i - 1].LPT_Adr]) +
          cRET + 'Dongles at LPT' + IntToStr(i) + ': ' +
          IntToStr(xBuffer[i - 1].DNG_Cnt) + cRET + cRET;

      Showmessage(MessageString);
      RetCode := Release_MatrixAPI();
    end;
end;
(*--------------------------------------------------------------------*)
procedure Dongle_Encrypt_Decrypt;
var
  DataBlock:    array[0..1] of Longword;
  MessageString: String;
  DNG_Nummer:   smallint;
begin
  RetCode := Init_MatrixAPI();

  DataBlock[0] := 1234567890;  (* Clear Data *)
  DataBlock[1] := 1234567890;  (* Clear Data *)

  MessageString :=
    'Clear Data: ' + cTAB + '(dec) ' + cTAB +
    IntToStr(DataBlock[0]) + ' ' + cTAB + IntToStr(DataBlock[1]) +
    cRET + cTAB + cTAB + '(hex) ' + cTAB +
    Format('%x',[DataBlock[0]]) + ' ' + cTAB +
    Format('%x',[DataBlock[1]])+ cRET + cRET;

  DNG_Nummer := Dongle_Count(DNG_Port);
  (***********************************************************)
  (* Encrypt DataBlock over the Dongle                       *)
  (***********************************************************)
  RetCode := Dongle_EncryptData(UserCode, @DataBlock, DNG_Nummer, DNG_Port);

  if (RetCode < 0) then
    begin
      Showmessage('Error ' + IntToStr(RetCode));
      RetCode := Release_MatrixAPI();
    end
  else
    begin
      MessageString := MessageString +
        'Encrypted Data: ' + cTAB + '(dec) ' + cTAB +
        IntToStr(DataBlock[0]) + ' ' + cTAB + IntToStr(DataBlock[1]) +
        cRET + cTAB + cTAB + '(hex) ' + cTAB +
        Format('%x',[DataBlock[0]]) + ' ' + cTAB +
        Format('%x',[DataBlock[1]]) + cRET + cRET;
      (***********************************************************)
      (* Decrypt DataBlock over the Dongle                       *)
      (***********************************************************)
      RetCode := Dongle_DecryptData(UserCode, @DataBlock, DNG_Nummer, DNG_Port);

      if (RetCode < 0) then
        begin
          Showmessage('Error ' + IntToStr(RetCode));
          RetCode := Release_MatrixAPI();
        end
      else
        begin
          ShowMessage(MessageString +
          'Decrypted Data: ' + cTAB + '(dec) ' + cTAB +
          IntToStr(DataBlock[0]) + ' ' + cTAB + IntToStr(DataBlock[1]) +
          cRET + cTAB + cTAB + '(hex) ' + cTAB +
          Format('%x',[DataBlock[0]]) + ' ' + cTAB +
          Format('%x',[DataBlock[1]]) + cRET + cRET);
          RetCode := Release_MatrixAPI();
        end;
    end;
end;
(*--------------------------------------------------------------------*)
procedure Version_of_API;
var
  RetVer:       LongInt;
  VerMinor:     smallint;
  VerMajor:     smallint;
begin
  RetCode := Init_MatrixAPI();
  (***********************************************************)
  (* Read the version of the Matrix-API                      *)
  (***********************************************************)
  RetVer := GetVersionAPI();

  if (RetVer = 0) then
    Showmessage('Error while reading API version!')
  else begin
     VerMinor := (RetVer and 65535);
     VerMajor := (RetVer shr 16);
     Showmessage('The Matrix-API has the version: ' +
                  IntToStr(VerMajor) + '.' + IntToStr(VerMinor));
  end;
  RetCode := Release_MatrixAPI();
end;
(*--------------------------------------------------------------------*)
procedure Dongle_Network;
var
  AppSlot:      smallint;
  MxNetFile:    String;
  DNG_Nummer:   smallint;
begin
  (*************************************************************)
  (* Network                                                   *)
  (* Example: the dongle is prepared with the value 7 in       *)
  (*          Var0002, meaning AppSlot=2 and max. Users = 7    *)
  (*************************************************************)
  RetCode := Init_MatrixAPI();

  (*************************************************************)
  (* Max. Users stored in AppSlot 2 (Var0002 of the dongle)    *)
  (*************************************************************)
  AppSlot := 2;

  (*************************************************************)
  (* Activate Network access into the Matrix-API               *)
  (*************************************************************)
  MxNetFile := 'D:\TEMP\MXNET2.DAT';
  RetCode := SetConfig_MatrixNet(1, pChar(MxNetFile));

  (*************************************************************)
  (* Read the Dongle count from MxNetFile                      *)
  (* !! DNG_Port will be ignored in the Network mode !!        *)
  (*************************************************************)
  DNG_Nummer := 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 := LogIn_MatrixNet(UserCode, AppSlot, DNG_Nummer);
  if (RetCode < 0) then
    begin
      if (RetCode = -31) then
         Showmessage('All Users are active!' + cRET +
                     'No more User-Slots free')
      else
         Showmessage('LogIn failed !  ' + IntToStr(RetCode));
    end
  else
    Showmessage(
    'LogIn successfull !  Free User-Slots: ' + IntToStr(RetCode) +
    cRET + cRET +
    'Now you can check the Active Users List in MxNet-Server.' + cRET +
    'After clicking the OK button, the User will be Logged Out and' + cRET +
    '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 := LogOut_MatrixNet(UserCode, AppSlot, DNG_Nummer);
  if (RetCode < 0) then
    Showmessage('LogOut failed !  ' + IntToStr(RetCode))
  else
    Showmessage('LogOut successfull ! Free User-Slots: ' + IntToStr(RetCode));

  (*************************************************************)
  (* Deactivate Network access into the Matrix-API             *)
  (*************************************************************)
  RetCode := SetConfig_MatrixNet(0, '');
  RetCode := Release_MatrixAPI();
end;
(*--------------------------------------------------------------------*)
procedure App_Encrypt;
var
  Key:          array[0..3] of Longword;
  Data:         array[0..1] of Longword;
  MessageString: String;
begin
  Data[0] := $499602D2;
  Data[1] := $499602D2;

  Key[0] := $423A612E;
  Key[1] := $423A8C95;
  Key[2] := $8474C25C;
  Key[3] := $8474EDC3;

  MessageString := 'Clear Data: ' + cTAB + '(dec) ' + cTAB +
  IntToStr(Data[0])      + ' ' + cTAB + IntToStr(Data[1]) +
  cRET + cTAB + cTAB + '(hex) ' + cTAB +
  Format('%x',[Data[0]]) + ' ' + cTAB + Format('%x',[Data[1]]) +
  cRET + cRET +
  'Key: ' + cTAB + cTAB + '(dec) ' + cTAB +
  IntToStr(Key[0])       + ' ' + cTAB + IntToStr(Key[1]) +
  cRET + cTAB + cTAB + cTAB +
  IntToStr(Key[2])       + ' ' + cTAB + IntToStr(Key[3]) +
  cRET +  cTAB + cTAB + '(hex) ' + cTAB +
  Format('%x',[Key[0]]) +  ' ' + cTAB + Format('%x',[Key[1]]) +
  cRET +  cTAB + cTAB + cTAB +
  Format('%x',[Key[2]]) +  ' ' + cTAB + Format('%x',[Key[3]]) +
  cRET + cRET;

  MxApp_Encrypt(@Data, @Key);

  (*** Display Data(0)/Data(1) as Long ***)
  Showmessage(MessageString + 'Encrypted Data:' + cTAB + '(dec) ' + cTAB +
  IntToStr(Data[0])      + ' ' + cTAB + IntToStr(Data[1]) +
  cRET + cTAB + cTAB + '(hex) ' + cTAB +
  Format('%x',[Data[0]]) + ' ' + cTAB + Format('%x',[Data[1]]) +
  cRET + cRET);
end;
(*--------------------------------------------------------------------*)
(**********************************************************************)
procedure SetActivePort(Port: String);
begin
  DNG_Port := 0;
  if Port = 'LPT1' then DNG_Port := 1 else if
     Port = 'LPT2' then DNG_Port := 2 else if
     Port = 'LPT3' then DNG_Port := 3 else if
     Port = 'USB'  then DNG_Port := 85;
end;

procedure CallSelectedItem(ItemIndex : Integer);
begin
  case ItemIndex of
    0: LPT_Port_Exists();
    1: Number_of_Dongles();
    2: Memory_of_Dongle();
    3: Version_of_Dongle();
    4: Read_Dongle_SerNr();
    5: Read_Dongle_Data();
    6: Write_Dongle_Data();
    7: Dongle_Find_Ex();
    8: Dongle_Encrypt_Decrypt();
    9: Version_of_API();
   10: Dongle_Network();
   11: App_Encrypt();
  end;
end;

(**********************************************************************)
procedure TForm1.Button1Click(Sender: TObject);
begin
  SetActivePort(ComboBox1.Text);
  CallSelectedItem(RadioGroup1.ItemIndex);
end;

end.