//*******************************************************************
// 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

