// This code contains the following functions. Please choose the one that matches your needs: // ProtCheck // ProtCheckWithAlg (the function also depends on the function MyAlgorithm) // WriteString // ReadString // EncryptUserData // or the same functions but using DRIS and API data encryption // (these functions also require the functions CryptDRIS and possibly CryptApiData and MyRWAlgorithm) // ProtCheckEnc // ProtCheckWithAlgEnc // WriteStringEnc // ReadStringEnc // EncryptUserDataEnc // Summary: does a standard protection check // Syntax: //[ = ] ProtCheck () // return value is 0 (success) or an error code PROCEDURE ProtCheck() hLib, ret_code are system int // set the DRIS to have random values RandomSet() // then set the values we want to use DRIS.header = "DRIS" DRIS.size = Length(DRIS) DRIS.dpfunction = PROTECTION_CHECK // standard protection check DRIS.flags = 0 // no extra flags, but you may want to specify some if you want to start a network user or decrement execs... // Load the protection DLL. hLib = LoadDLL(protectdllname) IF hLib = 0 THEN Info("Cannot load " + protectdllname, "This DLL should be in the same folder as this executable") RESULT -1 END //do a protection check ret_code = CallDLL32(protectdllname, "DDProtCheck", &DRIS, 0) FreeDLL(hLib) IF ret_code <> 0 THEN // an error occured so display an appropriate error message DisplayError(ret_code, DRIS.ext_err) RESULT ret_code END // later in your code you can check other values in the DRIS... IF (DRIS.sdsn <> MY_SDSN) THEN Info("Incorrect SDSN! Please modify your source code so that MY_SDSN is set to be your SDSN.") RESULT -1 END IF (ExtractString(DRIS.prodcode, 1, Charact(0)) <> MY_PRODCODE) THEN Info("Incorrect Product Code. Please modify your source code so that MY_PRODCODE is set to be your Product Code.") RESULT -1 END // later on in your program you can check the return code again IF (DRIS.ret_code <> 0) THEN Info("Dinkey Dongle protection error") RESULT -1 END Info("It worked!") // Summary: does a standard protection check and executes an algorithm // NB for this to work you must program at least "user algorithm" into the dongle // NB We have used a very simple algorithm here (in the MyAlgorithm function). You must patch this with the // sample code generated by DinkeyAdd for the algorithm that you are using. For Lite models copy the sample // code from DinkeyLook // Syntax: //[ = ] ProtCheckWithAlg () // return value is 0 (success) or an error code PROCEDURE ProtCheckWithAlg() hLib, ret_code are system int // set the DRIS to have random values RandomSet() // then set the values we want to use DRIS.header = "DRIS" DRIS.size = Length(DRIS) DRIS.dpfunction = EXECUTE_ALGORITHM // protection check and execute specified algorithm DRIS.flags = 0 // no extra flags, but you may want to specify some if you want to start a network user or decrement execs... DRIS.alg_number = 1 // !!!! you should remove these entries if you are using Dinkey Lite so that algorithm arguments are random DRIS.var_a = 1 // sample values DRIS.var_b = 2 DRIS.var_c = 3 DRIS.var_d = 4 DRIS.var_e = 5 DRIS.var_f = 6 DRIS.var_g = 7 DRIS.var_h = 8 // Load the protection DLL. hLib = LoadDLL(protectdllname) IF hLib = 0 THEN DelayBeforeClosing(1000) Info("Cannot load " + protectdllname, "This DLL should be in the same folder as this executable") RESULT -1 END //do a protection check ret_code = CallDLL32(protectdllname, "DDProtCheck", &DRIS, 0) FreeDLL(hLib) IF ret_code <> 0 THEN // an error occured so display an appropriate error message DisplayError(ret_code, DRIS.ext_err) RESULT ret_code END // later in your code you can check other values in the DRIS... IF (DRIS.sdsn <> MY_SDSN) THEN Info("Incorrect SDSN! Please modify your source code so that MY_SDSN is set to be your SDSN.") RESULT -1 END IF (ExtractString(DRIS.prodcode, 1, Charact(0)) <> MY_PRODCODE) THEN Info("Incorrect Product Code. Please modify your source code so that MY_PRODCODE is set to be your Product Code.") RESULT -1 END // later on in your program you can check the return code again IF (DRIS.ret_code <> 0) THEN Info("Dinkey Dongle protection error") RESULT -1 END // if you want you can check the algorithm answer - however if algorithm is from your code then best to just use the answer in your code // !!!! Make sure you have replaced the MyAlgorithm routine with the algorithm you have specified in DinkeyAdd IF (MyAlgorithm(DRIS.var_a, DRIS.var_b, DRIS.var_c, DRIS.var_d, DRIS.var_e, DRIS.var_f, DRIS.var_g, DRIS.var_h) <> DRIS.alg_answer) THEN Info("Dinkey protection error!", "You have not patched your algorithm in the MyAlgorithm routine") RESULT -1 END Info("It worked!") // Summary: // !!!! You should replace this function with the one generated by the // "generate source code" button in Algorithm tab for DinkeyAdd (if you have specified an algorithm) // or from DinkeyLook if you are using a Dinkey Lite dongle. You can modify the C code to make it compatiable with Windev. // Syntax: //[ = ] MyAlgorithm ( is int, is int, is int, is int, is int, is int, is int, is int) // PROCEDURE MyAlgorithm(var_a is int, var_b is int, var_c is int, var_d is int, var_e is int, var_f is int, var_g is int, var_h is int) RESULT var_a + var_b + var_c + var_d + var_e + var_f + var_g + var_h // Summary: This function does a protection check and writes the string "Hello, World!" to the data area at offset 7 // In order for this function to work you will need to have a data area in your dongle that is at least 21 bytes long. // NB you can easily modify the code to write a byte array instead of a string // Syntax: //[ = ] WriteString () // return value is 0 (success) or an error code // PROCEDURE WriteString() hLib, ret_code are system int OurString is fixed string on 1024 = "Hello, World!" // NB max. data write is 1K // set the DRIS to have random values RandomSet() // then set the values we want to use DRIS.header = "DRIS" DRIS.size = Length(DRIS) DRIS.dpfunction = WRITE_DATA_AREA // protection check and write specified data DRIS.flags = 0 // no extra flags, but you may want to specify some if you want to start a network user or decrement execs... DRIS.rw_offset = 7 DRIS.rw_length = Length(Left(OurString)) // the length of the string (in this case 13 bytes) DRIS.rw_data_ptr = &OurString // Load the protection DLL. hLib = LoadDLL(protectdllname) IF hLib = 0 THEN Info("Cannot load " + protectdllname, "This DLL should be in the same folder as this executable") RESULT -1 END //do a protection check ret_code = CallDLL32(protectdllname, "DDProtCheck", &DRIS, 0) FreeDLL(hLib) IF ret_code <> 0 THEN // an error occured so display an appropriate error message DisplayError(ret_code, DRIS.ext_err) RESULT ret_code END // later in your code you can check other values in the DRIS... IF (DRIS.sdsn <> MY_SDSN) THEN Info("Incorrect SDSN! Please modify your source code so that MY_SDSN is set to be your SDSN.") RESULT -1 END IF (ExtractString(DRIS.prodcode, 1, Charact(0)) <> MY_PRODCODE) THEN Info("Incorrect Product Code. Please modify your source code so that MY_PRODCODE is set to be your Product Code.") RESULT -1 END // later on in your program you can check the return code again IF (DRIS.ret_code <> 0) THEN Info("Dinkey Dongle protection error") RESULT -1 END Info("It worked!") // Summary: This function does a protection check and reads 13 bytes of data from the data area at offset 7 // In order for this function to work you will need to have a data area in your dongle that is at least 21 bytes long. // NB you can amend this code to read a byte array instead of a string if you prefer. // Syntax: //[ = ] ReadString () // return value is 0 (success) or an error code // PROCEDURE ReadString() hLib, ret_code are system int OurString is fixed string on 1024 // NB max. data read is 1K // set the DRIS to have random values RandomSet() // then set the values we want to use DRIS.header = "DRIS" DRIS.size = Length(DRIS) DRIS.dpfunction = READ_DATA_AREA // protection check and read data DRIS.flags = 0 // no extra flags, but you may want to specify some if you want to start a network user or decrement execs... DRIS.rw_offset = 7 DRIS.rw_length = 13 DRIS.rw_data_ptr = &OurString // Load the protection DLL. hLib = LoadDLL(protectdllname) IF hLib = 0 THEN Info("Cannot load " + protectdllname, "This DLL should be in the same folder as this executable") RESULT -1 END //do a protection check ret_code = CallDLL32(protectdllname, "DDProtCheck", &DRIS, 0) FreeDLL(hLib) IF ret_code <> 0 THEN // an error occured so display an appropriate error message DisplayError(ret_code, DRIS.ext_err) RESULT ret_code END // later in your code you can check other values in the DRIS... IF (DRIS.sdsn <> MY_SDSN) THEN Info("Incorrect SDSN! Please modify your source code so that MY_SDSN is set to be your SDSN.") RESULT -1 END IF (ExtractString(DRIS.prodcode, 1, Charact(0)) <> MY_PRODCODE) THEN Info("Incorrect Product Code. Please modify your source code so that MY_PRODCODE is set to be your Product Code.") RESULT -1 END // later on in your program you can check the return code again IF (DRIS.ret_code <> 0) THEN Info("Dinkey Dongle protection error") RESULT -1 END Info("It worked! Dinkey Dongle data area at offset 7 is:", OurString) // Summary: this function will do a protection check and ask the dongle to encrypt some data using encryption key 1 // It will then do another protection check & decrypt the data. NB you can modify the code to encrypt byte arrays instead of strings // NB you can amend this code to read a byte array instead of a string if you prefer. // Syntax: //[ = ] EncryptUserData () // return value is 0 (success) or an error code // PROCEDURE EncryptUserData() hLib, ret_code are system int OurString is fixed string on 1024 = "Hello, World!" // NB max. data we can encrypt is 1K // set the DRIS to have random values RandomSet() // then set the values we want to use DRIS.header = "DRIS" DRIS.size = Length(DRIS) DRIS.dpfunction = ENCRYPT_USER_DATA // protection check and encrypt specified data DRIS.flags = 0 // no extra flags, but you may want to specify some if you want to start a network user or decrement execs... DRIS.data_crypt_key_num = 1 DRIS.rw_length = Length(Left(OurString)) // the length of the string (in this case 13 bytes) DRIS.rw_data_ptr = &OurString // Load the protection DLL. hLib = LoadDLL(protectdllname) IF hLib = 0 THEN Info("Cannot load " + protectdllname, "This DLL should be in the same folder as this executable") RESULT -1 END //do a protection check ret_code = CallDLL32(protectdllname, "DDProtCheck", &DRIS, 0) IF ret_code <> 0 THEN // an error occured so display an appropriate error message DisplayError(ret_code, DRIS.ext_err) FreeDLL(hLib) RESULT ret_code END // NB can add code to check other elements of the DRIS e.g. SDSN, ProductCode (see ProtCheck function) // Now decrypt the same data to get the original values RandomSet() // then set the values we want to use DRIS.header = "DRIS" DRIS.size = Length(DRIS) DRIS.dpfunction = DECRYPT_USER_DATA // protection check and decrypt specified data DRIS.flags = 0 // no extra flags, but you may want to specify some if you want to start a network user or decrement execs... DRIS.data_crypt_key_num = 1 DRIS.rw_length = 13 // the length of the string (in this case 13 bytes) DRIS.rw_data_ptr = &OurString // NB the data is encrypted at this point ret_code = CallDLL32(protectdllname, "DDProtCheck", &DRIS, 0) FreeDLL(hLib) IF ret_code <> 0 THEN // an error occured so display an appropriate error message DisplayError(ret_code, DRIS.ext_err) RESULT ret_code END // NB can add code to check other elements of the DRIS e.g. SDSN, ProductCode (see ProtCheck function) Info("It worked! Dinkey Dongle data area at offset 7 is:", OurString) // !!!!!!!!!!! all the functions listed below encrypt all parameters to our API !!!!!!!!!!!!!!!!!!!!! // In order for them to work properly you need to choose "Encrypt DRIS" and "Encrypt Data passed to API" // in the Extra Security tab of DinkeyAdd. In this example, for Data Encryption I use the r/w algorithm // but the code can be modified easily to use the 3 encryption parameters. // !!!! please overwrite this function with the one generated by DinkeyAdd for R/W Algorithm (you will have to adapt the C code generated by DinkeyAdd) PROCEDURE MyRWAlgorithm(var_a is int, var_b is int, var_c is int, var_d is int, var_e is int, var_f is int, nVar_g is int, nVar_h is int) RESULT BinaryXOR(BinaryXOR(BinaryXOR(BinaryXOR(BinaryXOR(var_a, var_b), var_c), var_d), var_e), var_f) // !!!! please overwrite this function with the one generated by DinkeyAdd // (just modify the parameters specified in DinkeyAdd in the positiions indicated below): // Note arrays in Windev are 1-base which makes it a real pain PROCEDURE CryptDRIS() i, j, k are int bigseed, S are array of 256 1-byte unsigned int DRIS_bytes is an array of Length(DRIS) 1-byte unsigned int temp, t are 1-byte unsigned int FOR i = 1 _TO_ 256 STEP 8 Transfer(&bigseed[i], &DRIS.seed1, 4) Transfer(&bigseed[i+4], &DRIS.seed2, 4) END FOR i = 0 _TO_ 255 S[i+1] = i END j = 0 FOR i = 0 _TO_ 255 j = (j + S[i+1] + bigseed[i+1] + 123) modulo 256 // parameter 1, modify 123 temp = S[i+1] S[i+1] = S[j+1] S[j+1] = temp END Transfer(&DRIS_bytes, &DRIS, Length(DRIS)) // convert DRIS to bytes i = 0 j = 0 FOR k = 17 _TO_ Length(DRIS) i = (i + 1) modulo 256 j = (j + S[i+1] + 212) modulo 256 // parameter 2, modify 212 temp = S[i+1] S[i+1] = S[j+1] S[j+1] = temp t = (S[i+1] + S[j+1] + 97) modulo 256 // parameter 3, modify 97 DRIS_bytes[k] = BinaryXOR(DRIS_bytes[k], S[t+1]) END Transfer(&DRIS, &DRIS_bytes, Length(DRIS)) // convert back again // Note arrays in Windev are 1-base which makes it a real pain // Summary: // Syntax: //CryptApiData (, is 4-byte unsigned int, is int) PROCEDURE CryptApiData(data, enc_length is unsigned int, alg_ans is int) i, j, k are int bigseed, S are array of 256 1-byte unsigned int temp, t are 1-byte unsigned int FOR i = 1 _TO_ 256 STEP 8 Transfer(&bigseed[i], &DRIS.seed1, 4) Transfer(&bigseed[i+4], &DRIS.seed2, 4) END FOR i = 0 _TO_ 255 S[i+1] = i END j = 0 FOR i = 0 _TO_ 255 j = (j + S[i+1] + bigseed[i+1] + BinaryAND(alg_ans, 0xff)) modulo 256 temp = S[i+1] S[i+1] = S[j+1] S[j+1] = temp END i = 0 j = 0 FOR k = 1 _TO_ enc_length i = (i + 1) modulo 256 j = (j + S[i+1] + (BinaryAND(alg_ans, 0xff00))/256) modulo 256 temp = S[i+1] S[i+1] = S[j+1] S[j+1] = temp t = (S[i+1] + S[j+1] + (BinaryAND(alg_ans, 0xff0000))/65536) modulo 256 data[k] = BinaryXOR(data[k], S[t+1]) END // Summary: does a standard protection check and encrypt the DRIS we pass and from the API. // We encrypt the DRIS passed to the API. !!!! Patch the CryptDRIS function in this file from source code generated by DinkeyAdd. // Syntax: //[ = ] ProtCheckEnc () // return value is 0 (success) or an error code PROCEDURE ProtCheckEnc() hLib, ret_code are system int // set the DRIS to have random values RandomSet() // then set the values we want to use DRIS.header = "DRIS" DRIS.size = Length(DRIS) DRIS.dpfunction = PROTECTION_CHECK // standard protection check DRIS.flags = 0 // no extra flags, but you may want to specify some if you want to start a network user or decrement execs... // Load the protection DLL. hLib = LoadDLL(protectdllname) IF hLib = 0 THEN Info("Cannot load " + protectdllname, "This DLL should be in the same folder as this executable") RESULT -1 END CryptDRIS() // encrypt DRIS (!!!!you should separate from DDProtCheck for greater security) //do a protection check ret_code = CallDLL32(protectdllname, "DDProtCheck", &DRIS, 0) FreeDLL(hLib) CryptDRIS() // decrypt DRIS (!!!!you should separate from DDProtCheck for greater security) IF ret_code <> 0 THEN // an error occured so display an appropriate error message DisplayError(ret_code, DRIS.ext_err) RESULT ret_code END // later in your code you can check other values in the DRIS... IF (DRIS.sdsn <> MY_SDSN) THEN Info("Incorrect SDSN! Please modify your source code so that MY_SDSN is set to be your SDSN.") RESULT -1 END IF (ExtractString(DRIS.prodcode, 1, Charact(0)) <> MY_PRODCODE) THEN Info("Incorrect Product Code. Please modify your source code so that MY_PRODCODE is set to be your Product Code.") RESULT -1 END // later on in your program you can check the return code again IF (DRIS.ret_code <> 0) THEN Info("Dinkey Dongle protection error") RESULT -1 END Info("It worked!") // Summary: does a standard protection check and executes an algorithm and encrypts the DRIS // NB for this to work you must program at least one "user algorithm" into the dongle // NB We have used a very simple algorithm here (in the MyAlgorithm function). You must patch this with the // sample code generated by DinkeyAdd for the algorithm that you are using. For Lite models copy the sample // code from DinkeyLook. // We encrypt the DRIS passed to the API. !!!! Patch the CryptDRIS function in this file from source code generated by DinkeyAdd. // Syntax: //[ = ] ProtCheckWithAlgEnc () // return value is 0 (success) or an error code PROCEDURE ProtCheckWithAlgEnc() hLib, ret_code are system int // set the DRIS to have random values RandomSet() // then set the values we want to use DRIS.header = "DRIS" DRIS.size = Length(DRIS) DRIS.dpfunction = EXECUTE_ALGORITHM // protection check and execute specified algorithm DRIS.flags = 0 // no extra flags, but you may want to specify some if you want to start a network user or decrement execs... DRIS.alg_number = 1 // !!!! you should remove these entries if you are using Dinkey Lite so that algorithm arguments are random DRIS.var_a = 1 // sample values DRIS.var_b = 2 DRIS.var_c = 3 DRIS.var_d = 4 DRIS.var_e = 5 DRIS.var_f = 6 DRIS.var_g = 7 DRIS.var_h = 8 // Load the protection DLL. hLib = LoadDLL(protectdllname) IF hLib = 0 THEN DelayBeforeClosing(1000) Info("Cannot load " + protectdllname, "This DLL should be in the same folder as this executable") RESULT -1 END CryptDRIS() // encrypt DRIS (!!!!you should separate from DDProtCheck for greater security) //do a protection check ret_code = CallDLL32(protectdllname, "DDProtCheck", &DRIS, 0) FreeDLL(hLib) CryptDRIS() // decrypt DRIS (!!!!you should separate from DDProtCheck for greater security) IF ret_code <> 0 THEN // an error occured so display an appropriate error message DisplayError(ret_code, DRIS.ext_err) RESULT ret_code END // later in your code you can check other values in the DRIS... IF (DRIS.sdsn <> MY_SDSN) THEN Info("Incorrect SDSN! Please modify your source code so that MY_SDSN is set to be your SDSN.") RESULT -1 END IF (ExtractString(DRIS.prodcode, 1, Charact(0)) <> MY_PRODCODE) THEN Info("Incorrect Product Code. Please modify your source code so that MY_PRODCODE is set to be your Product Code.") RESULT -1 END // later on in your program you can check the return code again IF (DRIS.ret_code <> 0) THEN Info("Dinkey Dongle protection error") RESULT -1 END // if you want you can check the algorithm answer - however if algorithm is from your code then best to just use the answer in your code // !!!! Make sure you have replaced the MyAlgorithm routine with the algorithm you have specified in DinkeyAdd IF (MyAlgorithm(DRIS.var_a, DRIS.var_b, DRIS.var_c, DRIS.var_d, DRIS.var_e, DRIS.var_f, DRIS.var_g, DRIS.var_h) <> DRIS.alg_answer) THEN Info("Dinkey protection error!", "You have not patched your algorithm in the MyAlgorithm routine") RESULT -1 END Info("It worked!") // Summary: This function does a protection check and writes the string "Hello, World!" to the data area at offset 7 // In order for this function to work you will need to have a data area in your dongle that is at least 21 bytes long. // NB you can easily modify the code to write a byte array instead of a string // We encrypt the DRIS and Data passed to the API. !!!! Patch the CryptDRIS, CryptApiData and MyRWAlgorithm functions in this file from source code generated by DinkeyAdd. // Syntax: //[ = ] WriteStringEnc () // return value is 0 (success) or an error code // PROCEDURE WriteStringEnc() hLib, ret_code are system int alg_ans are int OurString is fixed string on 1024 = "Hello, World!" // NB max. data write is 1K OurString_bytes is array of 1024 1-byte unsigned int // byte-array of the encrypted string // set the DRIS to have random values RandomSet() // then set the values we want to use DRIS.header = "DRIS" DRIS.size = Length(DRIS) DRIS.dpfunction = WRITE_DATA_AREA // protection check and write specified data DRIS.flags = 0 // no extra flags, but you may want to specify some if you want to start a network user or decrement execs... DRIS.rw_offset = 7 DRIS.rw_length = Length(Left(OurString)) // the length of the string (in this case 13 bytes) DRIS.rw_data_ptr = &OurString_bytes // we convert the string to write to a byte array (so we can encrypt it) and then we pass that value to our API // Load the protection DLL. hLib = LoadDLL(protectdllname) IF hLib = 0 THEN Info("Cannot load " + protectdllname, "This DLL should be in the same folder as this executable") RESULT -1 END // calculate r/w algorithm answer - NB need to replace MyRWAlgorithm code with code generated by DinkeyAdd alg_ans = MyRWAlgorithm(DRIS.var_a, DRIS.var_b, DRIS.var_c, DRIS.var_d, DRIS.var_e, DRIS.var_f, DRIS.var_g, DRIS.var_h) // encrypt data we want to write (we must first convert it to a byte array so we can encrypt) Transfer(&OurString_bytes, &OurString, DRIS.rw_length) CryptApiData(OurString_bytes, DRIS.rw_length, alg_ans) CryptDRIS() // encrypt DRIS (!!!!you should separate from DDProtCheck for greater security) //do a protection check ret_code = CallDLL32(protectdllname, "DDProtCheck", &DRIS, 0) FreeDLL(hLib) CryptDRIS() // decrypt DRIS (!!!!you should separate from DDProtCheck for greater security) IF ret_code <> 0 THEN // an error occured so display an appropriate error message DisplayError(ret_code, DRIS.ext_err) RESULT ret_code END // later in your code you can check other values in the DRIS... IF (DRIS.sdsn <> MY_SDSN) THEN Info("Incorrect SDSN! Please modify your source code so that MY_SDSN is set to be your SDSN.") RESULT -1 END IF (ExtractString(DRIS.prodcode, 1, Charact(0)) <> MY_PRODCODE) THEN Info("Incorrect Product Code. Please modify your source code so that MY_PRODCODE is set to be your Product Code.") RESULT -1 END // later on in your program you can check the return code again IF (DRIS.ret_code <> 0) THEN Info("Dinkey Dongle protection error") RESULT -1 END Info("It worked!") // Summary: This function does a protection check and reads 13 bytes of data from the data area at offset 7 // In order for this function to work you will need to have a data area in your dongle that is at least 21 bytes long. // NB you can amend this code to read a byte array instead of a string if you prefer. // We encrypt the DRIS and Data passed to the API. !!!! Patch the CryptDRIS, CryptApiData and MyRWAlgorithm functions in this file from source code generated by DinkeyAdd. // Syntax: //[ = ] ReadStringEnc () // return value is 0 (success) or an error code // PROCEDURE ReadStringEnc() hLib, ret_code are system int alg_ans are int OurString is fixed string on 1024 // NB max. data read is 1K OurString_bytes is array of 1024 1-byte unsigned int // byte-array of the encrypted string // set the DRIS to have random values RandomSet() // then set the values we want to use DRIS.header = "DRIS" DRIS.size = Length(DRIS) DRIS.dpfunction = READ_DATA_AREA // protection check and read data DRIS.flags = 0 // no extra flags, but you may want to specify some if you want to start a network user or decrement execs... DRIS.rw_offset = 7 DRIS.rw_length = 13 DRIS.rw_data_ptr = &OurString_bytes // read it to our byte array first and then convert to a string // Load the protection DLL. hLib = LoadDLL(protectdllname) IF hLib = 0 THEN Info("Cannot load " + protectdllname, "This DLL should be in the same folder as this executable") RESULT -1 END // calculate r/w algorithm answer - NB need to replace MyRWAlgorithm code with code generated by DinkeyAdd alg_ans = MyRWAlgorithm(DRIS.var_a, DRIS.var_b, DRIS.var_c, DRIS.var_d, DRIS.var_e, DRIS.var_f, DRIS.var_g, DRIS.var_h) CryptDRIS() // encrypt DRIS (!!!!you should separate from DDProtCheck for greater security) //do a protection check ret_code = CallDLL32(protectdllname, "DDProtCheck", &DRIS, 0) FreeDLL(hLib) CryptDRIS() // decrypt DRIS (!!!!you should separate from DDProtCheck for greater security) IF ret_code <> 0 THEN // an error occured so display an appropriate error message DisplayError(ret_code, DRIS.ext_err) RESULT ret_code END // later in your code you can check other values in the DRIS... IF (DRIS.sdsn <> MY_SDSN) THEN Info("Incorrect SDSN! Please modify your source code so that MY_SDSN is set to be your SDSN.") RESULT -1 END IF (ExtractString(DRIS.prodcode, 1, Charact(0)) <> MY_PRODCODE) THEN Info("Incorrect Product Code. Please modify your source code so that MY_PRODCODE is set to be your Product Code.") RESULT -1 END // later on in your program you can check the return code again IF (DRIS.ret_code <> 0) THEN Info("Dinkey Dongle protection error") RESULT -1 END // decrypt data we have just read (then convert to string) CryptApiData(OurString_bytes, DRIS.rw_length, alg_ans) Transfer(&OurString, &OurString_bytes, DRIS.rw_length) Info("It worked! Dinkey Dongle data area at offset 7 is:", OurString) // Summary: this function will do a protection check and ask the dongle to encrypt some data using encryption key 1 // It will then do another protection check & decrypt the data. NB you can modify the code to encrypt byte arrays instead of strings // NB you can amend this code to read a byte array instead of a string if you prefer. // We encrypt the DRIS and Data passed to the API. !!!! Patch the CryptDRIS, CryptApiData and MyRWAlgorithm functions in this file from source code generated by DinkeyAdd. // Syntax: //[ = ] EncryptUserDataEnc () // return value is 0 (success) or an error code // PROCEDURE EncryptUserDataEnc() hLib, ret_code are system int alg_ans is int OurString is fixed string on 1024 = "Hello, World!" // NB max. data we can encrypt is 1K OurString_bytes is array of 1024 1-byte unsigned int // byte-array of the encrypted string // set the DRIS to have random values RandomSet() // then set the values we want to use DRIS.header = "DRIS" DRIS.size = Length(DRIS) DRIS.dpfunction = ENCRYPT_USER_DATA // protection check and encrypt specified data DRIS.flags = 0 // no extra flags, but you may want to specify some if you want to start a network user or decrement execs... DRIS.data_crypt_key_num = 1 DRIS.rw_length = Length(Left(OurString)) // the length of the string (in this case 13 bytes) DRIS.rw_data_ptr = &OurString_bytes // we convert the string to encrypt to a byte array (so we can encrypt it) and then we pass that to the API // Load the protection DLL. hLib = LoadDLL(protectdllname) IF hLib = 0 THEN Info("Cannot load " + protectdllname, "This DLL should be in the same folder as this executable") RESULT -1 END // calculate r/w algorithm answer - NB need to replace MyRWAlgorithm code with code generated by DinkeyAdd alg_ans = MyRWAlgorithm(DRIS.var_a, DRIS.var_b, DRIS.var_c, DRIS.var_d, DRIS.var_e, DRIS.var_f, DRIS.var_g, DRIS.var_h) // encrypt data we want to write (we must first convert it to a byte array so we can encrypt) Transfer(&OurString_bytes, &OurString, DRIS.rw_length) CryptApiData(OurString_bytes, DRIS.rw_length, alg_ans) CryptDRIS() // encrypt DRIS (!!!!you should separate from DDProtCheck for greater security) //do a protection check ret_code = CallDLL32(protectdllname, "DDProtCheck", &DRIS, 0) CryptDRIS() // decrypt DRIS (!!!!you should separate from DDProtCheck for greater security) IF ret_code <> 0 THEN // an error occured so display an appropriate error message DisplayError(ret_code, DRIS.ext_err) FreeDLL(hLib) RESULT ret_code END // NB can add code to check other elements of the DRIS e.g. SDSN, ProductCode (see ProtCheck function) // Now decrypt the same data to get the original values RandomSet() // then set the values we want to use DRIS.header = "DRIS" DRIS.size = Length(DRIS) DRIS.dpfunction = DECRYPT_USER_DATA // protection check and decrypt specified data DRIS.flags = 0 // no extra flags, but you may want to specify some if you want to start a network user or decrement execs... DRIS.data_crypt_key_num = 1 DRIS.rw_length = 13 // the length of the string (in this case 13 bytes) DRIS.rw_data_ptr = &OurString_bytes // NB this wil still be the encrypted data at this point alg_ans = MyRWAlgorithm(DRIS.var_a, DRIS.var_b, DRIS.var_c, DRIS.var_d, DRIS.var_e, DRIS.var_f, DRIS.var_g, DRIS.var_h) CryptDRIS() // encrypt DRIS (!!!!you should separate from DDProtCheck for greater security) ret_code = CallDLL32(protectdllname, "DDProtCheck", &DRIS, 0) FreeDLL(hLib) CryptDRIS() // decrypt DRIS (!!!!you should separate from DDProtCheck for greater security) IF ret_code <> 0 THEN // an error occured so display an appropriate error message DisplayError(ret_code, DRIS.ext_err) RESULT ret_code END // NB can add code to check other elements of the DRIS e.g. SDSN, ProductCode (see ProtCheck function) // decrypt the returned value and convert to a string CryptApiData(OurString_bytes, DRIS.rw_length, alg_ans) Transfer(&OurString, &OurString_bytes, DRIS.rw_length) Info("It worked! Dinkey Dongle data area at offset 7 is:", OurString)