Add Original SDK
This commit is contained in:
@@ -0,0 +1,299 @@
|
||||
// sample functions for calling DinkeyChange.dll.
|
||||
|
||||
|
||||
// Summary: Displays the error code with a helpful error message. You may want to change the messages.
|
||||
// Syntax:
|
||||
//DisplayChangeError (<ret_code> is int, <ext_err> is int)
|
||||
PROCEDURE DisplayChangeError(ret_code is int, ext_err is int)
|
||||
SWITCH ret_code
|
||||
CASE 401: Info("Error! No dongles detected that meet the search criteria!")
|
||||
CASE 409: Info("Error! The dongle detected has not been programmed by DinkeyAdd.")
|
||||
CASE 758: Info("Error! Cannot open the Update Code file specified.")
|
||||
CASE 759: Info("Error! The file specified is not a valid Update Code file.")
|
||||
CASE 762 TO 764: Info("Error! Update Code is not in a correct format / update code file is corrupt.")
|
||||
CASE 765: Info("Error! The Update Code does not match any dongle attached to your machine.")
|
||||
CASE 766: Info("Error! The update number for this Update Code is too high. You need to first enter an update code that was previously sent to you.")
|
||||
CASE 767: Info("Error! You have already entered this Update Code.")
|
||||
CASE 1905: Info("Error! There is no Software Key available for download.")
|
||||
CASE 1907: Info("Error! The Temporary Software Key has expired. Cannot download it.")
|
||||
CASE 1910: Info("Error! The Software Key has already been downloaded.")
|
||||
CASE 1921: Info("Error! You specified the 'default model' but there is more than one model available. You need to specify a specific dongle model.")
|
||||
CASE 1922: Info("Error! The model you requested is not available.")
|
||||
CASE 1923: Info("Error! The Demo Software Key Template has been disabled.")
|
||||
CASE 1924: Info("Error! You have run out of Demo Software Key activations. You need to order some more.")
|
||||
OTHER CASE: Info("An error occurred updating the dongle.","Error: " + ret_code, "Extended Error: " + ext_err)
|
||||
END
|
||||
|
||||
|
||||
// Summary: gets the product code, dongle number and update number for all dongles attached that meet the specify search criteria
|
||||
// Syntax:
|
||||
//[ <Result> = ] GetDongleInfo ()
|
||||
PROCEDURE GetDongleInfo()
|
||||
hLib, ret_code are system int
|
||||
type, model, update_number are fixed array of MAX_USB_DEVICES int
|
||||
dongle_number is a fixed array of MAX_USB_DEVICES unsigned int
|
||||
prodcode is a fixed array of MAX_USB_DEVICES fixed strings on MAX_PRODCODE_LEN
|
||||
num_found is int
|
||||
sDisplayMsg, sType, sModel are strings
|
||||
|
||||
// Load the DinkeyChange.dll
|
||||
hLib = LoadDLL(changedllname)
|
||||
IF hLib = 0 THEN
|
||||
Info("Cannot load " + changedllname, "This DLL should be in the same folder as this executable")
|
||||
RESULT -1
|
||||
END
|
||||
|
||||
// get dongle information
|
||||
ret_code = CallDLL32(changedllname, "DCGetInfo", TYPE_MASK_ALL, MODEL_MASK_DEFAULT, Null, MAX_USB_DEVICES, &num_found, &type, &model, &prodcode, &dongle_number, &update_number)
|
||||
FreeDLL(hLib)
|
||||
|
||||
IF ret_code <> 0 THEN
|
||||
DisplayChangeError(ret_code, 0)
|
||||
RESULT ret_code
|
||||
END
|
||||
|
||||
// display details on the dongles detected
|
||||
sDisplayMsg = "Dongle Information:" + CR
|
||||
FOR i = 1 TO num_found
|
||||
// get type of dongle
|
||||
IF type[i] = TYPE_PRO THEN
|
||||
sType = "Pro"
|
||||
ELSE
|
||||
sType = "FD"
|
||||
END
|
||||
// get model of dongle
|
||||
IF model[i] = MODEL_LITE THEN
|
||||
sModel = "Lite"
|
||||
ELSE IF model[i] = MODEL_PLUS THEN
|
||||
sModel = "Plus"
|
||||
ELSE
|
||||
sModel = "Net"
|
||||
END
|
||||
sDisplayMsg += i + ". Dinkey " + sType + " " + sModel + " with dongle number " + dongle_number[i] + " product code " + ExtractString(prodcode[i], 1, Charact(0)) + " update number " + update_number[i] + CR
|
||||
END
|
||||
|
||||
Info(sDisplayMsg)
|
||||
|
||||
|
||||
// Summary: collect diagnostic information from the system and write to a file
|
||||
// Syntax:
|
||||
//[ <Result> = ] GetDiagnosticInfo (<sDiagPath> is string)
|
||||
PROCEDURE GetDiagnosticInfo(sDiagPath is string)
|
||||
hLib, ret_code are system int
|
||||
|
||||
// Load the DinkeyChange.dll
|
||||
hLib = LoadDLL(changedllname)
|
||||
IF hLib = 0 THEN
|
||||
Info("Cannot load " + changedllname, "This DLL should be in the same folder as this executable")
|
||||
RESULT -1
|
||||
END
|
||||
|
||||
// get diagnostic info
|
||||
ret_code = CallDLL32(changedllname, "DCGetDiagnosticInfo", sDiagPath)
|
||||
FreeDLL(hLib)
|
||||
|
||||
IF ret_code = 754 THEN
|
||||
Info("Could not create the diagnostic file. Please check that the path exists:" + sDiagPath)
|
||||
RESULT ret_code
|
||||
END
|
||||
|
||||
IF ret_code <> 0 THEN
|
||||
Info("Error " + ret_code + " writing diagnostic information")
|
||||
RESULT ret_code
|
||||
END
|
||||
|
||||
Info("Diagnostic file written successfully")
|
||||
|
||||
|
||||
// Summary: updates the dongle attached using the update code passed
|
||||
// Syntax:
|
||||
//[ <Result> = ] UpdateCodeString (<sUpdateString> is string)
|
||||
//
|
||||
// Parameters:
|
||||
// sUpdateString (string): <specify the role of sUpdateString>
|
||||
|
||||
PROCEDURE UpdateCodeString(sUpdateString is string)
|
||||
hLib, ret_code are system int
|
||||
extended_error, confirmation_code are int
|
||||
|
||||
// Load the DinkeyChange.dll
|
||||
hLib = LoadDLL(changedllname)
|
||||
IF hLib = 0 THEN
|
||||
Info("Cannot load " + changedllname, "This DLL should be in the same folder as this executable")
|
||||
RESULT -1
|
||||
END
|
||||
|
||||
// update dongle
|
||||
ret_code = CallDLL32(changedllname, "DCDoUpdateCodeString", sUpdateString, &confirmation_code, &extended_error)
|
||||
FreeDLL(hLib)
|
||||
|
||||
IF ret_code <> 0 THEN
|
||||
DisplayChangeError(ret_code, extended_error)
|
||||
RESULT ret_code
|
||||
END
|
||||
|
||||
Info("Dongle updated successfully.", "Confirmation Code is " + NumToString(confirmation_code, "04x"))
|
||||
|
||||
|
||||
// Summary: updates the dongle attached using the update code passed
|
||||
// Syntax:
|
||||
//[ <Result> = ] UpdateCodeFromFile (<sUpdateCodeFile> is string)
|
||||
//
|
||||
// Parameters:
|
||||
// sUpdateCodeFile (string)
|
||||
|
||||
PROCEDURE UpdateCodeFromFile(sUpdateCodeFile is string)
|
||||
hLib, ret_code are system int
|
||||
extended_error, confirmation_code are int
|
||||
|
||||
// Load the DinkeyChange.dll
|
||||
hLib = LoadDLL(changedllname)
|
||||
IF hLib = 0 THEN
|
||||
Info("Cannot load " + changedllname, "This DLL should be in the same folder as this executable")
|
||||
RESULT -1
|
||||
END
|
||||
|
||||
// update dongle
|
||||
ret_code = CallDLL32(changedllname, "DCDoUpdateCodeFromFile", sUpdateCodeFile, &confirmation_code, &extended_error)
|
||||
FreeDLL(hLib)
|
||||
|
||||
IF ret_code <> 0 THEN
|
||||
DisplayChangeError(ret_code, extended_error)
|
||||
RESULT ret_code
|
||||
END
|
||||
|
||||
Info("Dongle updated successfully.", "Confirmation Code is " + NumToString(confirmation_code, "04x"))
|
||||
|
||||
|
||||
// Summary: attempts to restore a corrupt Dinkey FD Lite dongle
|
||||
// Syntax:
|
||||
//[ <Result> = ] RestoreDinkeyFDLite ()
|
||||
//
|
||||
// Parameters: none
|
||||
|
||||
PROCEDURE RestoreDinkeyFDLite()
|
||||
hLib, ret_code are system int
|
||||
|
||||
// Load the DinkeyChange.dll
|
||||
hLib = LoadDLL(changedllname)
|
||||
IF hLib = 0 THEN
|
||||
Info("Cannot load " + changedllname, "This DLL should be in the same folder as this executable")
|
||||
RESULT -1
|
||||
END
|
||||
|
||||
ret_code = CallDLL32(changedllname, "DCRetoreDinkeyFDLite")
|
||||
FreeDLL(hLib)
|
||||
|
||||
IF ret_code <> 0 THEN
|
||||
DisplayChangeError(ret_code, extended_error)
|
||||
RESULT ret_code
|
||||
END
|
||||
|
||||
Info("Dinkey FD has been restored successfully.")
|
||||
|
||||
|
||||
// Summary: displays the machine ID of the current computer
|
||||
// Syntax:
|
||||
//[ <Result> = ] GetMachineID ()
|
||||
//
|
||||
|
||||
PROCEDURE GetMachineID()
|
||||
hLib, ret_code are system int
|
||||
extended_error is int
|
||||
machineID is unsigned int
|
||||
|
||||
// Load the DinkeyChange.dll
|
||||
hLib = LoadDLL(changedllname)
|
||||
IF hLib = 0 THEN
|
||||
Info("Cannot load " + changedllname, "This DLL should be in the same folder as this executable")
|
||||
RESULT -1
|
||||
END
|
||||
|
||||
ret_code = CallDLL32(changedllname, "DCGetMachineID", &machineID, &extended_error)
|
||||
FreeDLL(hLib)
|
||||
|
||||
IF ret_code <> 0 THEN
|
||||
DisplayChangeError(ret_code, extended_error)
|
||||
RESULT ret_code
|
||||
END
|
||||
|
||||
Info("Machine ID is: " + NumToString(machineID, "08x"))
|
||||
|
||||
|
||||
// Summary: tries to download an available temporary software key for this machine
|
||||
// Syntax:
|
||||
//[ <Result> = ] DownloadTempSoftwareKey ()
|
||||
//
|
||||
|
||||
PROCEDURE DownloadTempSoftwareKey()
|
||||
hLib, ret_code are system int
|
||||
extended_error is int
|
||||
machineID is unsigned int
|
||||
|
||||
// Load the DinkeyChange module
|
||||
hLib = LoadDLL(changedllname)
|
||||
IF hLib = 0 THEN
|
||||
Info("Cannot load " + changedllname, "This DLL should be in the same folder as this executable")
|
||||
RESULT -1
|
||||
END
|
||||
|
||||
// first call GetMachineID to get the machine ID value
|
||||
ret_code = CallDLL32(changedllname, "DCGetMachineID", &machineID, &extended_error)
|
||||
|
||||
IF ret_code <> 0 THEN
|
||||
DisplayChangeError(ret_code, extended_error)
|
||||
RESULT ret_code
|
||||
END
|
||||
|
||||
// then try to download a temporary software key for that machine ID
|
||||
ret_code = CallDLL32(changedllname, "DCDownloadTempSoftwareKey", machineID, &extended_error)
|
||||
FreeDLL(hLib)
|
||||
|
||||
IF ret_code <> 0 THEN
|
||||
DisplayChangeError(ret_code, extended_error)
|
||||
RESULT ret_code
|
||||
END
|
||||
|
||||
Info("The Temporary Software Key has been downloaded successfully.")
|
||||
|
||||
|
||||
// Summary: tries to download a demo software key for this machine
|
||||
// Syntax:
|
||||
//[ <Result> = ] DownloadDemoSoftwareKey (<sProdCode> is string)
|
||||
//
|
||||
// Parameters:
|
||||
// sProdCode (string)
|
||||
//
|
||||
|
||||
PROCEDURE DownloadDemoSoftwareKey(sProdCode is string)
|
||||
hLib, ret_code are system int
|
||||
extended_error is int
|
||||
machineID is unsigned int
|
||||
|
||||
// Load the DinkeyChange module
|
||||
hLib = LoadDLL(changedllname)
|
||||
IF hLib = 0 THEN
|
||||
Info("Cannot load " + changedllname, "This DLL should be in the same folder as this executable")
|
||||
RESULT -1
|
||||
END
|
||||
|
||||
// first call GetMachineID to get the machine ID value
|
||||
ret_code = CallDLL32(changedllname, "DCGetMachineID", &machineID, &extended_error)
|
||||
|
||||
IF ret_code <> 0 THEN
|
||||
DisplayChangeError(ret_code, extended_error)
|
||||
RESULT ret_code
|
||||
END
|
||||
|
||||
// then try to download a demo software key
|
||||
// (NB we are assuming only one dongle model is set in the Demo Software Template.
|
||||
// If multiple models are set you will also need to specify the exact model)
|
||||
ret_code = CallDLL32(changedllname, "DCDownloadDemoSoftwareKey", machineID, sProdCode, SWKEY_MODEL_DEFAULT, &extended_error)
|
||||
FreeDLL(hLib)
|
||||
|
||||
IF ret_code <> 0 THEN
|
||||
DisplayChangeError(ret_code, extended_error)
|
||||
RESULT ret_code
|
||||
END
|
||||
|
||||
Info("The Demo Software Key has been downloaded successfully.")
|
||||
@@ -0,0 +1,15 @@
|
||||
Calling DinkeyChange.dll from WinDev
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
You should copy all the code in the file "global variables.txt". These data
|
||||
structures and functions are used by the API sample code. Then copy the
|
||||
appropraite function(s) from the "protection check functions.txt" file. These
|
||||
functions implement all the various routines in DinkeyChange.dll
|
||||
|
||||
Note - if you are producing a 64-bit Windows executable you need to use DinkeyChange64.dll
|
||||
(instead of DinkeyChange.dll) and change the "changedllname" to be "DinkeyChange64.dll"
|
||||
(this is found in the global variables and functions.txt).
|
||||
Similarly for Linux you will need to use DinkeyChange.so (32-bit Linux) or
|
||||
DinkeyChange64.so (64-bit Linux).
|
||||
|
||||
Tested under Windev Express v12
|
||||
@@ -0,0 +1,50 @@
|
||||
// DinkeyChange constants
|
||||
|
||||
// maximum number of USB devices that can be attached to a machine at any time
|
||||
CONSTANT
|
||||
MAX_USB_DEVICES = 128 // max number of USB devices that can be attached to the system
|
||||
MAX_PRODCODE_LEN = 9 // one extra character for null-terminated strings
|
||||
END
|
||||
|
||||
// mask values
|
||||
CONSTANT
|
||||
TYPE_MASK_PRO = 1
|
||||
TYPE_MASK_FD = 2
|
||||
TYPE_MASK_ALL = 3
|
||||
|
||||
MODEL_MASK_LITE = 1
|
||||
MODEL_MASK_PLUS = 2
|
||||
MODEL_MASK_NET = 4
|
||||
MODEL_MASK_ALL = 7
|
||||
MODEL_MASK_DEFAULT = 6 // Plus and Net
|
||||
END
|
||||
|
||||
// type values for DCGetInfo (returned in the array)
|
||||
CONSTANT
|
||||
TYPE_PRO = 1
|
||||
TYPE_FD = 2
|
||||
END
|
||||
|
||||
// model values for DCGetInfo (returned in the array)
|
||||
CONSTANT
|
||||
MODEL_LITE = 1
|
||||
MODEL_PLUS = 2
|
||||
MODEL_NET5 = 4
|
||||
MODEL_NETU = 7
|
||||
END
|
||||
|
||||
// model values for DCDownloadDemoSoftwareKey
|
||||
|
||||
CONSTANT
|
||||
SWKEY_MODEL_DEFAULT = -1 // NB this assumes that the Demo Software Key Template was created with only one valid dongle model
|
||||
SWKEY_MODEL_PRO_LITE = 0
|
||||
SWKEY_MODEL_PRO_PLUS = 1
|
||||
SWKEY_MODEL_PRO_NET = 2
|
||||
SWKEY_MODEL_FD_LITE = 3
|
||||
SWKEY_MODEL_FD_PLUS = 4
|
||||
SWKEY_MODEL_FD_NET = 5
|
||||
END
|
||||
|
||||
|
||||
// name for DinkeyChange.dll (you can rename it if you like)
|
||||
changedllname is a string = "DinkeyChange.dll"
|
||||
@@ -0,0 +1,43 @@
|
||||
Protecting Windev applications with Dinkey Dongle
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
You should copy all the code in the file "global variables and functions.txt".
|
||||
These data structures and functions are used by the API sample code. Then copy
|
||||
the appropriate function(s) from the "protection check functions.txt" file. These
|
||||
functions implement all the various features of the DInkey Dongle SDK.
|
||||
|
||||
Note that the sample code is just a guide. You should implement the protection in
|
||||
a stronger way using the techniques described in the "Increasing your Protection"
|
||||
chapter of the manual.
|
||||
|
||||
Code marked with !!!! are places where you should customise the sample code so
|
||||
that it will work properly:
|
||||
|
||||
* Change the MY_SDSN value to the value of your SDSN
|
||||
* Change the MY_PRODCODE value to the value of your Product Code
|
||||
* Change the MyAlgorithm code (if you call a user algorithm)
|
||||
* Change the CryptDRIS code (if you encrypt the DRIS)
|
||||
* Change the CryptApiData (if you encrypt Data you send to our API)
|
||||
* Change the MyRWAlgorithm code (if encrypt Data you send to our API using the R/W algorithm)
|
||||
|
||||
You will also probably want to replace our error messages with your own. However, you should
|
||||
still display or log any error codes returned by the protection check otherwise you will not
|
||||
be able to identify the cause of the error. (You can look up error codes in our knowledge
|
||||
base: microcosm.com/kb).
|
||||
|
||||
Note - you should protect dpwin32.dll and not your program. Because your program
|
||||
is linked to the DLL it is protected. The protected DLL will need to be in the
|
||||
same folder as your compiled program for it to run correctly.
|
||||
|
||||
Note - if you are producing a 64-bit Windows executable you need to protect dpwin64.dll
|
||||
(instead of dpwin32.dll) and change the "protectdllname" to be "dpwin64.dll"
|
||||
(this is found in the global variables and functions.txt).
|
||||
Similarly for Linux you will need to use dplin32.so (32-bit Linux) or dplin64.so (64-bit Linux).
|
||||
|
||||
Note - you can also use the Shell Method of protection on WinDev executables.
|
||||
|
||||
Note - we have had reports of a bug in early releases of Windev 19 which causes the "Length" ("Taille")
|
||||
function to return in incorrect value. This bug has been fixed in the February 2014 release of Windev 19.
|
||||
|
||||
Tested under Windev Express v12
|
||||
|
||||
@@ -0,0 +1,135 @@
|
||||
//*******************************************************************
|
||||
// Dinkey Runtime Information structure (DRIS)
|
||||
|
||||
GLOBAL
|
||||
DRIS is composed of
|
||||
// the first 4 fields are never encrypted
|
||||
header is a fixed string on 4 // should be set to DRIS
|
||||
|
||||
// inputs
|
||||
size is an int on 4 // size of this structure
|
||||
seed1 is an int on 4 // seed for data/dris encryption
|
||||
seed2 is an int on 4 // seed for data/dris encryption
|
||||
// (maybe encrypted from now on)
|
||||
dpfunction is an int on 4 // specify only one function
|
||||
flags is an int on 4 // options for the function selected. To use more than one OR them together: OPTION1 | OPTION2...
|
||||
execs_decrement is an unsigned int on 4 // amount by which to dec execs if we use flag: DEC_MANY_EXECS
|
||||
data_crypt_key_num is an int on 4 // number of the key (1-3) that the dongle uses to encrypt or decrypt user data
|
||||
rw_offset is an unsigned int on 4 // offset in the dongle data area to read or write data
|
||||
rw_length is an unsigned int on 4 // length of data are to read/write/encrypt/decrypt
|
||||
rw_data_ptr is a system int // pointer to data to write / be read
|
||||
alt_licence_name is a fixed string on 256 // protection check for different licence instead of the default one, must be null-terminated
|
||||
var_a is an int on 4 // variable values for user algorithm
|
||||
var_b is an int on 4
|
||||
var_c is an int on 4
|
||||
var_d is an int on 4
|
||||
var_e is an int on 4
|
||||
var_f is an int on 4
|
||||
var_g is an int on 4
|
||||
var_h is an int on 4
|
||||
alg_number is an unsigned int on 4 // the number of the user algorithm that you want to execute
|
||||
|
||||
// outputs
|
||||
ret_code is an int on 4 // return code from the protection check
|
||||
ext_err is an unsigned int on 4 // extended error
|
||||
type is an int on 4 // type of dongle detected. 1 = Pro, 2 = FD
|
||||
model is an int on 4 // model of dongle detected. 1 = Lite, 2 = Plus, 4 = Net 5, 7 = Net Unlimited
|
||||
sdsn is an int on 4 // Software Developer's Serial Number
|
||||
prodcode is a fixed string on 12 // Product Code (null-terminated)
|
||||
dongle_number is an unsigned int on 4
|
||||
update_number is an unsigned int on 4
|
||||
data_area_size is an unsigned int on 4 // size of the data area used in the dongle detected
|
||||
num_algs is an int on 4 // the maximum algorithm number in the dongle detected
|
||||
execs is an int on 4 // executions left: -1 indicates 'no limit'
|
||||
exp_day is an int on 4 // expiry day: -1 indicates 'no limit'
|
||||
exp_month is an int on 4 // expiry month: -1 indicates 'no limit'
|
||||
exp_year is an int on 4 // expiry year: -1 indicates 'no limit'
|
||||
features is an unsigned int on 4 // features value
|
||||
net_users is an int on 4 // maximum number of network users for the dongle detected: -1 indicates 'mo limit'
|
||||
alg_answer is an int on 4 // answer to the user algorithm executed with the given variable values
|
||||
fd_capacity is an unsigned int on 4
|
||||
fd_drive is a fixed string on 128 // drive letter of FD dongle detected e.g. 'f:\'
|
||||
swkey_type is an int on 4 // 0 = no swkey detected, 1 = temporary software key, 2 = demo software
|
||||
swkey_exp_day is an int on 4 // software key expiry date (if software key detected)
|
||||
swkey_exp_month is an int on 4
|
||||
swkey_exp_year is an int on 4
|
||||
END
|
||||
|
||||
// dpwin32.dll - 32-bit Windows protection module !!!! change this module for 64-bit Windows or Linux or Mac
|
||||
protectdllname is a string = "dpwin32.dll"
|
||||
|
||||
// functions - must specify only one
|
||||
CONSTANT
|
||||
PROTECTION_CHECK = 1 // checks for dongle, check program parameters
|
||||
EXECUTE_ALGORITHM = 2 // protection check + calculate answer for specified algorithm with specified inputs
|
||||
WRITE_DATA_AREA =3 // protection check + writes dongle data area
|
||||
READ_DATA_AREA = 4 // protection check + reads dongle data area
|
||||
ENCRYPT_USER_DATA = 5 // protection check + the dongle will encrypt user data
|
||||
DECRYPT_USER_DATA = 6 // protection check + the dongle will decrypt user data
|
||||
FAST_PRESENCE_CHECK = 7 // checks for the presence of the correct dongle only with minimal security, no flags allowed.
|
||||
STOP_NET_USER = 8 // stops a network user (and doesn't do a protection check)
|
||||
END
|
||||
|
||||
// flags - can specify as many as you like
|
||||
CONSTANT
|
||||
DEC_ONE_EXEC = 1 // decrement execs by 1
|
||||
DEC_MANY_EXECS = 2 // decrement execs by number specified in execs_decrement
|
||||
START_NET_USER = 4 // starts a network user
|
||||
USE_FUNCTION_ARGUMENT = 16 // use the extra argument in the function for pointers
|
||||
CHECK_LOCAL_FIRST = 32 // always look in local ports before looking in network ports
|
||||
CHECK_NETWORK_FIRST = 64 // always look on the network before looking in local ports
|
||||
USE_ALT_LICENCE_NAME = 128 // use name specified in alt_licence_name instead of the default one
|
||||
DONT_SET_MAXDAYS_EXPIRY = 256 // if the max days expiry date has not been calculated then do not do it this time
|
||||
MATCH_DONGLE_NUMBER = 512 // restrict the search to match the dongle number specified in the DRIS
|
||||
DONT_RETURN_FD_DRIVE = 1024 // if an FD dongle has been detected then don't return the flash drive/mount name in the DRIS
|
||||
END
|
||||
|
||||
// SDSN (software developer's serial number)
|
||||
CONSTANT
|
||||
MY_SDSN = 10101 // !!!! change this value to be the value of your SDSN (demo = 10101)
|
||||
MY_PRODCODE = "DEMO" // !!!! change thus value to be the value of your Product Code
|
||||
END
|
||||
|
||||
|
||||
// Summary: Sets each element of the DRIS to be a random value. Improves security
|
||||
// Syntax:
|
||||
//RandomSet ()
|
||||
//
|
||||
PROCEDURE RandomSet()
|
||||
DRIS_bytes is array of Length(DRIS) 1-byte unsigned int
|
||||
|
||||
Transfer(&DRIS_bytes, &DRIS, Length(DRIS)) // copy DRIS to a byte array so we can look at each byte
|
||||
InitRandom()
|
||||
FOR i = 1 _TO_ Length(DRIS)
|
||||
DRIS_bytes[i] = Random(0,255) // set each element to a random number
|
||||
END
|
||||
Transfer(&DRIS, &DRIS_bytes, Length(DRIS)) // copy back to DRIS
|
||||
|
||||
|
||||
// Summary: Displays the error code with a helpful error message. You may want to change the messages.
|
||||
// Syntax:
|
||||
//DisplayError (<ret_code> is int, <ext_err> is 4-byte unsigned int)
|
||||
//
|
||||
// Parameters:
|
||||
// ret_code (int): <specify the role of ret_code>
|
||||
// ext_err (4-byte unsigned int): <specify the role of ext_err>
|
||||
// Return Value:
|
||||
// None
|
||||
//
|
||||
//
|
||||
PROCEDURE DisplayError(ret_code is int, ext_err is unsigned int)
|
||||
SWITCH ret_code
|
||||
CASE 401: Info("Error! No dongles detected!")
|
||||
CASE 403: Info("Error! The dongle detected has a different type to the one specified in DinkeyAdd.")
|
||||
CASE 404: Info("Error! The dongle detected has a different model to those specified in DinkeyAdd.")
|
||||
CASE 409: Info("Error! The dongle detected has not been programmed by DinkeyAdd.")
|
||||
CASE 410: Info("Error! The dongle detected has a different Product Code to the one specified in DinkeyAdd.")
|
||||
CASE 411: Info("Error! The dongle detected does not contain the licence associated with this program.")
|
||||
CASE 413: Info("Error! This program has not been protected by DinkeyAdd.","For guidance please read the DinkeyAdd chapter of the Dinkey manual.")
|
||||
CASE 417: Info("Error! One or more of the parameters set in the DRIS is incorrect.","This could be caused if you are encrypting the DRIS in your code but did not specify DRIS encryption in DinkeyAdd - or vice versa.")
|
||||
CASE 423: Info("Error! The number of network users has been exceeded.")
|
||||
CASE 435: Info("Error! DinkeyServer has not been detected on the network.")
|
||||
CASE 922: Info("Error! The Software Key has expired.")
|
||||
OTHER CASE: Info("An error occurred checking the dongle.","Error: " + ret_code, "Extended Error: " + ext_err)
|
||||
END
|
||||
|
||||
@@ -0,0 +1,784 @@
|
||||
// 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:
|
||||
//[ <Result> = ] 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:
|
||||
//[ <Result> = ] 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:
|
||||
//[ <Result> = ] 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)
|
||||
//
|
||||
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:
|
||||
//[ <Result> = ] 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:
|
||||
//[ <Result> = ] 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:
|
||||
//[ <Result> = ] 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: <specify the procedure action>
|
||||
// Syntax:
|
||||
//CryptApiData (<data>, <enc_length> is 4-byte unsigned int, <alg_ans> 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:
|
||||
//[ <Result> = ] 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:
|
||||
//[ <Result> = ] 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:
|
||||
//[ <Result> = ] 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:
|
||||
//[ <Result> = ] 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:
|
||||
//[ <Result> = ] 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)
|
||||
|
||||
Reference in New Issue
Block a user