******************************************************************
* MX-DEMO.PRG
* Example for Visual FoxPro
*
* Copyright (C) TDi GmbH
*
* This file includes a sample for the implementation of the
* Matrix Dongle, and the implemantation of the TEA encryption
* algorithm.
******************************************************************
SET TALK OFF
SET CONFIRM ON
CLEAR
*******************************************************************************
**************************** MATRIX-API FUNCTIONS *****************************
*******************************************************************************
DECLARE SHORT Init_MatrixAPI IN matrix32.dll
DECLARE SHORT Release_MatrixAPI IN matrix32.dll
DECLARE SHORT Dongle_Find IN matrix32.dll
DECLARE LONG GetVersionAPI IN matrix32.dll
DECLARE SHORT GetPortAdr IN matrix32.dll SHORT
DECLARE SHORT Dongle_Count IN matrix32.dll SHORT
DECLARE LONG Dongle_Version IN matrix32.dll SHORT, SHORT
DECLARE SHORT Dongle_MemSize IN matrix32.dll SHORT, SHORT
DECLARE SHORT Dongle_ReadData IN matrix32.dll LONG, STRING, SHORT, SHORT, SHORT
DECLARE SHORT Dongle_ReadDataEx IN matrix32.dll LONG, STRING, SHORT, SHORT, SHORT, SHORT
DECLARE LONG Dongle_ReadSerNr IN matrix32.dll LONG, SHORT, SHORT
DECLARE SHORT Dongle_WriteData IN matrix32.dll LONG, STRING, SHORT, SHORT, SHORT
DECLARE SHORT Dongle_WriteDataEx IN matrix32.dll LONG, STRING, SHORT, SHORT, SHORT, SHORT
DECLARE SHORT Dongle_EncryptData IN matrix32.dll LONG, STRING, SHORT, SHORT
DECLARE SHORT Dongle_DecryptData IN matrix32.dll LONG, STRING, SHORT, SHORT
******************************************
*** !!! Set your own UserCode here !!! ***
******************************************
lngUserCode = 1234
******************************************
*** !!! Set the Port to scan !!! ***
******************************************
DNG_Port = 85 && 1-3 = LPT1-LPT3
&& 85 = USB
****************************************************************
* Init the Matrix API
****************************************************************
nRetCode = Init_MatrixAPI()
cMsg = "Init_MatrixAPI Return-Code: "+LTRIM(RTRIM(STR(nRetCode)))
MESSAGEBOX(cMsg, "Init the Matrix-API")
****************************************************************
* Search the number of connected dongles at 'DNG_Port'
****************************************************************
DNG_Count = Dongle_Count(DNG_Port)
IF DNG_Count < 0
MESSAGEBOX("Error Code: " + DNG_Count, "DONGLE COUNT")
nRetCode = Release_MatrixAPI()
RETURN
ENDIF
cMsg = LTRIM(RTRIM(STR(DNG_Count))) + " Dongles found"
IF DNG_Port = 85
cMsg = cMsg + " at Port: " + LTRIM(RTRIM(STR(DNG_Port))) + " (USB)"
ENDIF
IF DNG_Port >= 1 AND DNG_Port <= 3
cMsg = cMsg + " at Port: " + LTRIM(RTRIM(STR(DNG_Port))) + " (LPT)"
ENDIF
MESSAGEBOX(cMsg, "DONGLE COUNT")
IF DNG_Count = 0
nRetCode = Release_MatrixAPI()
RETURN
ENDIF
****************************************************************
* Read the version and memory siize of the Dongle at 'DNG_Port'
****************************************************************
nVersion = Dongle_Version(DNG_Count, DNG_Port)
IF nVersion <= 0
cMsg = "Version Error Code: " + STR(nVersion)
ELSE
nVerMinor = INT(BITAND(nVersion, 65535))
nVerMajor = INT(BITRSHIFT(nVersion ,16))
cMsg = "Dongle Version : " + ALLTRIM(STR(nVerMajor)) + "." + ALLTRIM(STR(nVerMinor))
ENDIF
DNG_Mem = Dongle_MemSize(DNG_Count, DNG_Port)
IF DNG_Mem <= 0
cMsg = cMsg + CHR(10) + CHR(10)
cMsg = cMsg + "MemSize Error Code: " + STR(DNG_Mem)
ELSE
DNG_MaxVars = INT(DNG_Mem / 4)
cMsg = cMsg + CHR(10) + CHR(10)
cMsg = cMsg + "Dongle MemSize : " + ALLTRIM(STR(DNG_Mem)) + " Bytes = " +;
ALLTRIM(STR(DNG_MaxVars)) + " Variables"
ENDIF
MESSAGEBOX(cMsg, "DONGLE VERSION AND MEM-SIZE")
****************************************************************
* Dongle_ReadData: Read Vars from Dongle connected at 'DNG_Port'
* Each Variable = 4 Bytes
* 'xvars' is the count of Variables to be read
****************************************************************
xpos = 2 && Variable-No. where to start reading
xvars = 14 && Count of Variables to be read from Dongle
cBuffer = SPACE(xvars*4) && Alloc space for the Variables to be read
***** Read the values from Dongle *****
nRetCode = Dongle_ReadDataEx(lngUserCode, @cBuffer, xpos, xvars, DNG_Count, DNG_Port)
IF nRetCode <= 0
cMsg = "Read Error Code: " + STR(nRetCode)
ELSE
*** Extract the 'xvars' Variables (each 4 Bytes) form ***
*** cBuffer, convert this in DEC and HEX form and display ***
DECLARE DataIn(xvars)
STORE 0 TO DataIn
cMsg = ""
FOR i = 1 TO xvars
DataIn(i) = Convert_BinStr_To_Integer(cBuffer, i)
cMsg = cMsg + " Var000" + ALLTRIM(STR(i+xpos-1)) + ": " + CHR(9) + ;
"(dec) " + ALLTRIM(STR(DataIn(i),11)) + CHR(9) + ;
" (hex) " + Convert_BinStr_To_HexStr(cBuffer, i) + CHR(10)
NEXT
ENDIF
MESSAGEBOX(cMsg, "DONGLE READ DATA")
****************************************************************
* Dongle_WriteData: Write Vars to the Dongle at 'DNG_Port'
* Each Variable = 4 Bytes
* 'xvars' is the count of Vars to be write
****************************************************************
xpos = 1 && Variable-No. where to start writing
xvars = 15 && Count of Variables to be write in Dongle
cBuffer = ""
DECLARE DataOut(xvars)
FOR i = 1 TO xvars && Fill the 'cBuffer' with Values
DataOut(i) = 200 + i && Integer Value
cBuffer = cBuffer + Convert_Integer_To_BinStr(DataOut(i)) && move DataOut to cBuffer
NEXT
***** Write the values to Dongle *****
nRetCode = Dongle_WriteDataEx(lngUserCode, @cBuffer, xpos, xvars, DNG_Count, DNG_Port)
IF nRetCode <= 0
cMsg = "Write Error Code: " + STR(nRetCode)
ELSE
cMsg = "Write successfull:" + CHR(10)
FOR i = 1 TO xvars
cMsg = cMsg + " Var000" + ALLTRIM(STR(i+xpos-1)) + ": " + CHR(9) + ;
"(dec) " + ALLTRIM(STR(DataOut[i],11)) + CHR(9) + ;
" (hex) " + Convert_Integer_To_HexStr(DataOut[i]) + CHR(10)
NEXT
ENDIF
MESSAGEBOX(cMsg, "DONGLE WRITE DATA")
****************************************************************
* Dongle_ReadSerNr: Read and display the SerialNo of the Dongle
****************************************************************
nSerNr = Dongle_ReadSerNr(lngUserCode, DNG_Count, DNG_Port)
IF nSerNr <= 0
cMsg = "Error Code: " + STR(nSerNr)
ELSE
cMsg = "SerialNo. (DEC): " + STR(nSerNr)
ENDIF
MESSAGEBOX(cMsg, "DONGLE SERIAL-NO.")
****************************************************************
* TEST 1: Encrypt/Decrypt a 8 Bytes Text-Buffer
* over the Dongle
****************************************************************
cBuffer = "My Crypt" && 8 Bytes DataBlock
cMsg = "Clear Data (STR): " + CHR(9) + cBuffer
**** Encrypt the 8 Bytes Text-Buffer ***
nRetCode = Dongle_EncryptData(lngUserCode, @cBuffer, DNG_Count, DNG_Port)
IF nRetCode <= 0
cMsg = "Error Code: " + STR(nRetCode)
ELSE
*** convert the encrypted 'cBuffer' in two HEX strings and display ***
cMsg = cMsg + CHR(10) + CHR(10)
cMsg = cMsg + "Encrypted Data (HEX):" + CHR(9)
cMsg = cMsg + Convert_BinStr_To_HexStr(cBuffer, 1)
cMsg = cMsg + " : "
cMsg = cMsg + Convert_BinStr_To_HexStr(cBuffer, 2)
ENDIF
**** Decrypt the 8 Bytes encrypted Buffer ***
nRetCode = Dongle_DecryptData(lngUserCode, @cBuffer, DNG_Count, DNG_Port)
IF nRetCode <= 0
cMsg = "Error Code: " + STR(nRetCode)
ELSE
cMsg = cMsg + CHR(10) + CHR(10)
cMsg = cMsg + "Decrypted Data (STR):" + CHR(9) + cBuffer
ENDIF
MESSAGEBOX(cMsg, "ENCRYPT / DECRYPT OVER DONGLE - TEST 1")
****************************************************************
* TEST 2: Encrypt/Decrypt two LongIntegers (2 x 4 Bytes)
* over the Dongle
****************************************************************
DECLARE DataBlock(2)
DataBlock(1) = 1234567890
DataBlock(2) = 1234567890
cBuffer = Convert_Integer_To_BinStr(DataBlock(1)) +;
Convert_Integer_To_BinStr(DataBlock(2))
*** convert 'cBuffer' in two DEC/HEX strings and display ***
cMsg = "Clear Data: " + CHR(9) + "(dec) "
cMsg = cMsg + ALLTRIM(STR(DataBlock(1), 11)) + CHR(9) + " : " + ALLTRIM(STR(DataBlock(2), 11))
cMsg = cMsg + CHR(10)
cMsg = cMsg + CHR(9) + CHR(9) + "(hex) "
cMsg = cMsg + Convert_BinStr_To_HexStr(cBuffer, 1)
cMsg = cMsg + CHR(9) + " : "
cMsg = cMsg + Convert_BinStr_To_HexStr(cBuffer, 2)
**** Encrypt the 8 Bytes Buffer ***
nRetCode = Dongle_EncryptData(lngUserCode, @cBuffer, DNG_Count, DNG_Port)
IF nRetCode <= 0
cMsg = "Error Code: " + STR(nRetCode)
ELSE
*** convert the encrypted 'cBuffer' in two DEC/HEX strings and display ***
DataBlock(1) = Convert_BinStr_To_Integer(cBuffer, 1)
DataBlock(2) = Convert_BinStr_To_Integer(cBuffer, 2)
cMsg = cMsg + CHR(10) + CHR(10)
cMsg = cMsg + "Encrypted Data:" + CHR(9) + "(dec) "
cMsg = cMsg + ALLTRIM(STR(DataBlock(1), 11)) + CHR(9) + " : " + ALLTRIM(STR(DataBlock(2), 11))
cMsg = cMsg + CHR(10)
cMsg = cMsg + CHR(9) + CHR(9) + "(hex) "
cMsg = cMsg + Convert_BinStr_To_HexStr(cBuffer, 1)
cMsg = cMsg + CHR(9) + " : "
cMsg = cMsg + Convert_BinStr_To_HexStr(cBuffer, 2)
ENDIF
**** Decrypt the 8 Bytes encrypted Buffer ***
nRetCode = Dongle_DecryptData(lngUserCode, @cBuffer, DNG_Count, DNG_Port)
IF nRetCode <= 0
cMsg = "Error Code: " + STR(nRetCode)
ELSE
*** convert the 'cBuffer' in two DEC/HEX strings and display ***
DataBlock(1) = Convert_BinStr_To_Integer(cBuffer, 1)
DataBlock(2) = Convert_BinStr_To_Integer(cBuffer, 2)
cMsg = cMsg + CHR(10) + CHR(10)
cMsg = cMsg + "Decrypted Data:" + CHR(9) + "(dec) "
cMsg = cMsg + ALLTRIM(STR(DataBlock(1), 11)) + CHR(9) + " : " + ALLTRIM(STR(DataBlock(2), 11))
cMsg = cMsg + CHR(10)
cMsg = cMsg + CHR(9) + CHR(9) + "(hex) "
cMsg = cMsg + Convert_BinStr_To_HexStr(cBuffer, 1)
cMsg = cMsg + CHR(9) + " : "
cMsg = cMsg + Convert_BinStr_To_HexStr(cBuffer, 2)
ENDIF
MESSAGEBOX(cMsg, "ENCRYPT / DECRYPT OVER DONGLE - TEST 2")
nRetCode = Release_MatrixAPI()
****************************************************************
* Encrypt in the application with MxApp_Encrypt
****************************************************************
SET PROCEDURE TO "mxtea.prg"
DECLARE nData(2)
nData[1] = 1234567890
nData[2] = 1234567890
DECLARE nKey(4)
nKey[1] = 1111122222
nKey[2] = 1111133333
nKey[3] = 2222244444
nKey[4] = 2222255555
cMsg = "Key: " + CHR(9) + CHR(9) + " (dec) " + ALLTRIM(STR(nKey[1], 11)) + CHR(9) + ;
": " + ALLTRIM(STR(nKey[2], 11)) + CHR(9) + ;
": " + ALLTRIM(STR(nKey[3], 11)) + CHR(9) + ;
": " + ALLTRIM(STR(nKey[4], 11)) + CHR(10) + ;
CHR(9) + CHR(9) + " (hex) " + Convert_Integer_To_HexStr(nKey[1]) + CHR(9) + ;
": " + Convert_Integer_To_HexStr(nKey[2]) + CHR(9) + ;
": " + Convert_Integer_To_HexStr(nKey[3]) + CHR(9) + ;
": " + Convert_Integer_To_HexStr(nKey[4]) + CHR(9) + ;
CHR(10) + CHR(10) + ;
"Clear Data: " + CHR(9) + " (dec) " + ALLTRIM(STR(nData[1], 11)) + CHR(9) + ;
": " + ALLTRIM(STR(nData[2], 11)) + CHR(10) + ;
CHR(9) + CHR(9) + " (hex) " + Convert_Integer_To_HexStr(nData[1]) + CHR(9) + ;
": " + Convert_Integer_To_HexStr(nData[2]) + ;
CHR(10) + CHR(10)
MxApp_Encrypt(@nData, @nKey)
cMsg = cMsg + "Encrypted Data: " + CHR(9) + " (dec) " + ALLTRIM(STR(nData[1], 11)) + CHR(9) + ;
": " + ALLTRIM(STR(nData[2], 11)) + CHR(10) + ;
CHR(9) + CHR(9) + " (hex) " + Convert_Integer_To_HexStr(nData[1]) + CHR(9) + ;
": " + Convert_Integer_To_HexStr(nData[2])
MESSAGEBOX(cMsg, "MX-APP-ENCRYPT")
RELEASE PROCEDURE "mxtea.prg"
RETURN
*******************************************************************************
******************** STRING/INTEGER CONVERSION FUNCTIONS **********************
*******************************************************************************
*-----------------------------------------------------------------------------*
FUNCTION Convert_BinStr_To_HexStr && Convert a Block of 4 Bytes to a HEX-String
*-----------------------------------------------------------------------------*
PARAMETER cStr, nBlock
LOCAL i, nFx, nZe, cHexStr, lnNum, nTmp
nFx = ABS(4 - 4*nBlock)
cHexStr = ""
FOR nZe = 1 To 4
lnNum = ASC(SUBSTR(cStr, nZe+nFx, 1))
FOR b = 1 To 2
nTmp = lnNum - INT(lnNum /16)*16
DO CASE
CASE nTmp = 10
cHexStr = "A" + cHexStr
CASE nTmp = 11
cHexStr = "B" + cHexStr
CASE nTmp = 12
cHexStr = "C" + cHexStr
CASE nTmp = 13
cHexStr = "D" + cHexStr
CASE nTmp = 14
cHexStr = "E" + cHexStr
CASE nTmp = 15
cHexStr = "F" + cHexStr
OTHERWISE
cHexStr = ALLTRIM(STR(nTmp)) + cHexStr
ENDCASE
lnNum = INT(lnNum /16)
NEXT
NEXT
RETURN (cHexStr)
*-----------------------------------------------------------------------------*
FUNCTION Convert_BinStr_To_Integer && Convert a Block of 4 Bytes to Integer
*-----------------------------------------------------------------------------*
PARAMETER cStr, nVar
LOCAL i, nFx, IntValue, lnNum
nFx = ABS(4 - 4*nVar)
IntValue = 0
FOR i = 1 To 4
lnNum = ASC(SUBSTR(cStr, i+nFx, 1))
lnNum = BITLSHIFT(lnNum, 8*(i-1))
IntValue = BITOR(IntValue, lnNum)
NEXT
RETURN (IntValue)
*-----------------------------------------------------------------------------*
FUNCTION Convert_Integer_To_BinStr && Convert a Integer of 4 Bytes to Bin-String
*-----------------------------------------------------------------------------*
PARAMETER nValue
LOCAL cBuf
cBuf = ""
cBuf = cBuf + CHR(BITAND(nValue, 255))
cBuf = cBuf + CHR(BITAND(BITRSHIFT(nValue, 8), 255))
cBuf = cBuf + CHR(BITAND(BITRSHIFT(nValue, 16), 255))
cBuf = cBuf + CHR(BITAND(BITRSHIFT(nValue, 24), 255))
RETURN (cBuf)
*-----------------------------------------------------------------------------*
FUNCTION Convert_Integer_To_HexStr && Convert a Integer of 4 Bytes to HEX-String
*-----------------------------------------------------------------------------*
PARAMETER nValue
LOCAL cBuf
cBuf = Convert_Integer_To_BinStr(nValue)
cBuf = Convert_BinStr_To_HexStr(cBuf, 1)
RETURN (cBuf)