613 lines
26 KiB
Java
613 lines
26 KiB
Java
// Example use of the Dinkey Pro/FD API in Java.
|
|
// Copyright 2018 Microcosm Ltd.
|
|
|
|
import uk.microcosm.dinkeydongle.DinkeyPro;
|
|
import java.util.Arrays; // For Arrays.toString()
|
|
|
|
class DPSample
|
|
{
|
|
static final String MY_PRODCODE = "DEMO"; // !!!! Replace "DEMO" with the product code that you specify when adding protection with DinkeyAdd.
|
|
static final int MY_SDSN = 10101; // !!!! "10101" is the SDSN used by the demo SDK and demo dongles.
|
|
// If not using a demo, replace "10101" with your own SDSN here.
|
|
|
|
static final int DRIS_ENCRYPTION_PARAMETER_1 = 123; // !!!! If you enable DRIS encryption when adding protection with DinkeyAdd,
|
|
static final int DRIS_ENCRYPTION_PARAMETER_2 = 212; // replace these values with the encryption parameters that you specify.
|
|
static final int DRIS_ENCRYPTION_PARAMETER_3 = 97;
|
|
|
|
public static void main(String[] args)
|
|
{
|
|
// Each of the methods below demonstrates different API functionality.
|
|
// Uncomment the appropriate methods to execute the examples.
|
|
// See the comments in each method for more details about the features that they demonstrate.
|
|
|
|
protCheck();
|
|
// protCheckWithAlg();
|
|
// writeDataArea();
|
|
// readDataArea();
|
|
// encryptUserData();
|
|
// protCheckEnc();
|
|
// writeDataAreaEnc();
|
|
// readDataAreaEnc();
|
|
// encryptUserDataEnc();
|
|
// displayNetUsers();
|
|
}
|
|
|
|
// An example of a basic protection check
|
|
static void protCheck()
|
|
{
|
|
int retCode;
|
|
|
|
// Create a DinkeyPro instance that uses the default library name, DPJava.
|
|
// All DRIS fields are initialised to random values.
|
|
DinkeyPro ddpro = new DinkeyPro();
|
|
|
|
// You can use an alternative library name like this:
|
|
// DinkeyPro ddpro = new DinkeyPro("MyName");
|
|
// The manner in which the library name is mapped to the actual system library is system dependent,
|
|
// but common behaviour is that Java will attempt to locate and load MyName.dll on Windows, libMyName.dylib on macOS,
|
|
// or libMyName.so on Linux.
|
|
|
|
// You can also specify the full path to the library, if it is not located in one of the paths specified by java.library.path,
|
|
// or uses a non-standard filename:
|
|
// Dinkey ddpro = new DinkeyPro("~/Unusual Folder For Libraries/nonstandardname.jnilib");
|
|
|
|
// Initialise the DRIS
|
|
ddpro.function = DinkeyPro.PROTECTION_CHECK;
|
|
ddpro.flags = DinkeyPro.DEC_ONE_EXEC | DinkeyPro.START_NET_USER;
|
|
|
|
// Call the API
|
|
retCode = ddpro.checkProtection();
|
|
|
|
// Check the return value
|
|
if (retCode != 0)
|
|
{
|
|
displayError(retCode, ddpro.ext_err);
|
|
return;
|
|
}
|
|
|
|
// ...
|
|
|
|
// You can check other values from the DRIS in other parts of your program to improve security.
|
|
// For example:
|
|
|
|
// Check the SDSN
|
|
if (ddpro.sdsn != MY_SDSN)
|
|
{
|
|
System.out.println("Incorrect SDSN! Have you replaced '10101' with your SDSN in the sample code?");
|
|
return;
|
|
}
|
|
|
|
// Check the product code
|
|
if (!(ddpro.getProdCode().equals(MY_PRODCODE)))
|
|
{
|
|
System.out.println("Incorrect Product Code! Please modify your source code so that MY_PRODCODE is set to be the Product Code in the dongle.");
|
|
return;
|
|
}
|
|
|
|
System.out.println("Protection check successful.");
|
|
return;
|
|
}
|
|
|
|
// An example of a protection check that also executes an algorithm stored in the dongle.
|
|
// The best way to use this feature is to identify lines of code in your program
|
|
// that can be represented by algorithms stored in the dongle,
|
|
// and replace these lines with calls to the API.
|
|
// Lite dongle users cannot change the algorithm stored in the dongles,
|
|
// so should calculate the algorithm in their own code and compare the result with the one returned by the API,
|
|
// as in this example.
|
|
static void protCheckWithAlg()
|
|
{
|
|
int retCode;
|
|
DinkeyPro ddpro = new DinkeyPro();
|
|
|
|
// Initialise the DRIS
|
|
ddpro.function = DinkeyPro.EXECUTE_ALGORITHM;
|
|
ddpro.flags = 0;
|
|
ddpro.alg_number = 1; // The algorithm to execute. Lite dongles ignore this field, as they contain only 1 algorithm
|
|
ddpro.var_a = 1; // The input variables to use in the algorithm
|
|
ddpro.var_b = 2;
|
|
ddpro.var_c = 3;
|
|
ddpro.var_d = 4;
|
|
ddpro.var_e = 5;
|
|
ddpro.var_f = 6;
|
|
ddpro.var_g = 7;
|
|
ddpro.var_h = 8;
|
|
|
|
// Call the API
|
|
retCode = ddpro.checkProtection();
|
|
|
|
// Check the return value
|
|
if (retCode != 0)
|
|
{
|
|
displayError(retCode, ddpro.ext_err);
|
|
return;
|
|
}
|
|
|
|
// ...
|
|
|
|
// Check the algorithm result in another part of your program to improve security.
|
|
// !!!! Ensure the myAlgorithm() method matches the algorithm that was executed by the protection check!
|
|
if (myAlgorithm(ddpro.var_a, ddpro.var_b, ddpro.var_c, ddpro.var_d, ddpro.var_e, ddpro.var_f, ddpro.var_g, ddpro.var_h) != ddpro.alg_answer)
|
|
{
|
|
System.out.println("Error! The algorithm result was not as expected.");
|
|
return;
|
|
}
|
|
|
|
System.out.println("Protection check with algorithm successful.");
|
|
return;
|
|
}
|
|
|
|
// An example of a protection check that also writes data to the dongle's secure data area.
|
|
// This feature is not supported by Lite dongles.
|
|
// Make sure you specify a large enough data area size when adding protection with DinkeyAdd!
|
|
static void writeDataArea()
|
|
{
|
|
int retCode;
|
|
DinkeyPro ddpro = new DinkeyPro();
|
|
byte[] data = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; // Data to write
|
|
|
|
// Initialise the DRIS
|
|
ddpro.function = DinkeyPro.WRITE_DATA_AREA;
|
|
ddpro.flags = DinkeyPro.USE_FUNCTION_ARGUMENT; // Java uses DDProtCheck()'s data parameter, so this flag must be set
|
|
ddpro.rw_offset = 0; // Index to start writing at. Indices start at zero
|
|
ddpro.rw_length = data.length; // The number of bytes to be written
|
|
|
|
// Call the API
|
|
retCode = ddpro.checkProtection(data);
|
|
|
|
// Check the return value
|
|
if (retCode != 0)
|
|
{
|
|
displayError(retCode, ddpro.ext_err);
|
|
return;
|
|
}
|
|
|
|
// You can inspect the dongle with DinkeyLook to see that the data has been written to the dongle
|
|
|
|
System.out.println("Writing data successful.");
|
|
return;
|
|
}
|
|
|
|
// An example of a protection check that also reads data from the dongle's secure data area.
|
|
// This feature is not supported by Lite dongles.
|
|
// Make sure you specify a large enough data area size when adding protection with DinkeyAdd!
|
|
static void readDataArea()
|
|
{
|
|
int retCode;
|
|
DinkeyPro ddpro = new DinkeyPro();
|
|
byte[] data = new byte[10];
|
|
|
|
// Initialise the DRIS
|
|
ddpro.function = DinkeyPro.READ_DATA_AREA;
|
|
ddpro.flags = DinkeyPro.USE_FUNCTION_ARGUMENT; // Java uses DDProtCheck()'s data parameter, so this flag must be set
|
|
ddpro.rw_offset = 0; // Index to start reading from. Indices start at zero
|
|
ddpro.rw_length = data.length; // The number of bytes to read
|
|
|
|
// Call the API
|
|
retCode = ddpro.checkProtection(data);
|
|
|
|
// Check the return value
|
|
if (retCode != 0)
|
|
{
|
|
displayError(retCode, ddpro.ext_err);
|
|
return;
|
|
}
|
|
|
|
System.out.println("Reading data successful: " + Arrays.toString(data));
|
|
return;
|
|
}
|
|
|
|
// An example of protection checks that encrypt/decrypt your data.
|
|
// This feature is not supported by Lite dongles.
|
|
static void encryptUserData()
|
|
{
|
|
int retCode;
|
|
DinkeyPro ddpro = new DinkeyPro();
|
|
byte[] data = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; // The data to be encrypted
|
|
byte[] originalData = data.clone(); // A copy of the data for displaying later
|
|
byte[] encryptedData;
|
|
|
|
// Initialise the DRIS
|
|
ddpro.function = DinkeyPro.ENCRYPT_USER_DATA;
|
|
ddpro.flags = DinkeyPro.USE_FUNCTION_ARGUMENT; // Java uses DDProtCheck()'s data parameter, so this flag must be set
|
|
ddpro.rw_length = data.length; // The number of bytes to be encrypted
|
|
ddpro.data_crypt_key_num = 1; // The encryption key to use
|
|
|
|
// Call the API
|
|
retCode = ddpro.checkProtection(data);
|
|
|
|
// Check the return value
|
|
if (retCode != 0)
|
|
{
|
|
displayError(retCode, ddpro.ext_err);
|
|
return;
|
|
}
|
|
|
|
encryptedData = data.clone(); // A copy of the encrypted data for displaying later
|
|
|
|
// Initialise the DRIS
|
|
ddpro.reset(); // Reset the DRIS fields with random values
|
|
ddpro.function = DinkeyPro.DECRYPT_USER_DATA;
|
|
ddpro.flags = DinkeyPro.USE_FUNCTION_ARGUMENT; // Java uses DDProtCheck()'s data parameter, so this flag must be set
|
|
ddpro.rw_length = data.length;
|
|
ddpro.data_crypt_key_num = 1; // This must be the same key used to encrypt the data
|
|
|
|
// Call the API
|
|
retCode = ddpro.checkProtection(data);
|
|
|
|
// Check the return value
|
|
if (retCode != 0)
|
|
{
|
|
displayError(retCode, ddpro.ext_err);
|
|
return;
|
|
}
|
|
|
|
System.out.println("Data encryption successful.");
|
|
System.out.println("Original data: " + Arrays.toString(originalData));
|
|
System.out.println("Encrypted data: " + Arrays.toString(encryptedData));
|
|
System.out.println("Decrypted data: " + Arrays.toString(data));
|
|
return;
|
|
}
|
|
|
|
// An example of a protection check that uses DRIS encryption for extra security.
|
|
static void protCheckEnc()
|
|
{
|
|
int retCode;
|
|
DinkeyPro ddpro = new DinkeyPro();
|
|
|
|
// Initialise the DRIS
|
|
ddpro.function = DinkeyPro.PROTECTION_CHECK;
|
|
ddpro.flags = 0;
|
|
|
|
// Encrypt the DRIS
|
|
ddpro.cryptDris(DRIS_ENCRYPTION_PARAMETER_1, DRIS_ENCRYPTION_PARAMETER_2, DRIS_ENCRYPTION_PARAMETER_3);
|
|
|
|
// Call the API
|
|
retCode = ddpro.checkProtection();
|
|
|
|
// Decrypt the DRIS
|
|
ddpro.cryptDris(DRIS_ENCRYPTION_PARAMETER_1, DRIS_ENCRYPTION_PARAMETER_2, DRIS_ENCRYPTION_PARAMETER_3);
|
|
|
|
// Check the return value
|
|
if (retCode != 0)
|
|
{
|
|
displayError(retCode, ddpro.ext_err);
|
|
return;
|
|
}
|
|
|
|
// ...
|
|
|
|
// You can check other values from the DRIS in other parts of your program to improve security.
|
|
// For example:
|
|
|
|
// Check the SDSN
|
|
if (ddpro.sdsn != MY_SDSN)
|
|
{
|
|
System.out.println("Incorrect SDSN! Have you replaced '10101' with your SDSN in the sample code?");
|
|
return;
|
|
}
|
|
|
|
// Check the product code
|
|
if (!(ddpro.getProdCode().equals(MY_PRODCODE)))
|
|
{
|
|
System.out.println("Incorrect Product Code! Please modify your source code so that MY_PRODCODE is set to be the Product Code in the dongle.");
|
|
return;
|
|
}
|
|
|
|
System.out.println("Protection check successful.");
|
|
return;
|
|
}
|
|
|
|
// An example of a protection check that also writes data to the dongle's secure data area.
|
|
// This feature is not supported by Lite dongles.
|
|
// Make sure you specify a large enough data area size when adding protection with DinkeyAdd!
|
|
// This method also uses DRIS encryption and data encryption for extra security.
|
|
// You must select these options on the Extra Security tab of DinkeyAdd for this method to work correctly!
|
|
static void writeDataAreaEnc()
|
|
{
|
|
int retCode, algAnswer;
|
|
DinkeyPro ddpro = new DinkeyPro();
|
|
byte[] data = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; // The data to be written
|
|
|
|
// Initialise the DRIS
|
|
ddpro.function = DinkeyPro.WRITE_DATA_AREA;
|
|
ddpro.flags = DinkeyPro.USE_FUNCTION_ARGUMENT; // Java uses DDProtCheck()'s data parameter, so this flag must be set
|
|
ddpro.rw_offset = 0; // Index to start writing at. Indices start at zero
|
|
ddpro.rw_length = data.length; // The number of bytes to write
|
|
|
|
// If taking data encryption parameters from the R/W algorithm:
|
|
// Calculate the R/W algorithm result
|
|
// The input variables were initialised to random values when ddpro was created
|
|
algAnswer = myRwAlgorithm(ddpro.var_a, ddpro.var_b, ddpro.var_c, ddpro.var_d, ddpro.var_e, ddpro.var_f, ddpro.var_g, ddpro.var_h);
|
|
|
|
// Use the algorithm result to encrypt the data to be written to the dongle
|
|
ddpro.cryptApiData(data, algAnswer);
|
|
|
|
// If using constant data encryption parameters:
|
|
// ddpro.cryptApiData(data, DATA_ENCRYPTION_PARAMETER_1, DATA_ENCRYPTION_PARAMETER_2, DATA_ENCRYPTION_PARAMETER_3);
|
|
|
|
// Encrypt the DRIS
|
|
ddpro.cryptDris(DRIS_ENCRYPTION_PARAMETER_1, DRIS_ENCRYPTION_PARAMETER_2, DRIS_ENCRYPTION_PARAMETER_3);
|
|
|
|
// Call the API
|
|
retCode = ddpro.checkProtection(data);
|
|
|
|
// Decrypt the DRIS
|
|
ddpro.cryptDris(DRIS_ENCRYPTION_PARAMETER_1, DRIS_ENCRYPTION_PARAMETER_2, DRIS_ENCRYPTION_PARAMETER_3);
|
|
|
|
// Check the return value
|
|
if (retCode != 0)
|
|
{
|
|
displayError(retCode, ddpro.ext_err);
|
|
return;
|
|
}
|
|
|
|
System.out.println("Writing data successful.");
|
|
return;
|
|
}
|
|
|
|
// An example of a protection check that also reads data from the dongle's secure data area.
|
|
// This feature is not supported by Lite dongles.
|
|
// Make sure you specify a large enough data area size when adding protection with DinkeyAdd!
|
|
// This method also uses DRIS encryption and data encryption for extra security.
|
|
// You must select these options on the Extra Security tab of DinkeyAdd for this method to work correctly!
|
|
static void readDataAreaEnc()
|
|
{
|
|
int retCode, algAnswer;
|
|
DinkeyPro ddpro = new DinkeyPro();
|
|
byte[] data = new byte[10];
|
|
|
|
// Initialise the DRIS
|
|
ddpro.function = DinkeyPro.READ_DATA_AREA;
|
|
ddpro.flags = DinkeyPro.USE_FUNCTION_ARGUMENT; // Java uses DDProtCheck()'s data parameter, so this flag must be set
|
|
ddpro.rw_offset = 0; // Index to start reading from. Indices start at zero
|
|
ddpro.rw_length = data.length; // The number of bytes to read
|
|
|
|
// Encrypt the DRIS
|
|
ddpro.cryptDris(DRIS_ENCRYPTION_PARAMETER_1, DRIS_ENCRYPTION_PARAMETER_2, DRIS_ENCRYPTION_PARAMETER_3);
|
|
|
|
// Call the API
|
|
retCode = ddpro.checkProtection(data);
|
|
|
|
// Decrypt the DRIS
|
|
ddpro.cryptDris(DRIS_ENCRYPTION_PARAMETER_1, DRIS_ENCRYPTION_PARAMETER_2, DRIS_ENCRYPTION_PARAMETER_3);
|
|
|
|
// Check the return value
|
|
if (retCode != 0)
|
|
{
|
|
displayError(retCode, ddpro.ext_err);
|
|
return;
|
|
}
|
|
|
|
// If taking data encryption parameters from the R/W algorithm:
|
|
// Calculate the R/W algorithm result
|
|
// The input variables were initialised to random values when ddpro was created
|
|
algAnswer = myRwAlgorithm(ddpro.var_a, ddpro.var_b, ddpro.var_c, ddpro.var_d, ddpro.var_e, ddpro.var_f, ddpro.var_g, ddpro.var_h);
|
|
|
|
// Use the algorithm result to decrypt the data read from the dongle
|
|
ddpro.cryptApiData(data, algAnswer);
|
|
|
|
// If using constant data encryption parameters:
|
|
// ddpro.cryptApiData(data, DATA_ENCRYPTION_PARAMETER_1, DATA_ENCRYPTION_PARAMETER_2, DATA_ENCRYPTION_PARAMETER_3);
|
|
|
|
System.out.println("Reading data successful: " + Arrays.toString(data));
|
|
return;
|
|
}
|
|
|
|
// An example of protection checks that encrypt/decrypt your data.
|
|
// This feature is not supported by Lite dongles.
|
|
// This method also uses DRIS encryption and data encryption for extra security.
|
|
// You must select these options on the Extra Security tab of DinkeyAdd for this method to work correctly!
|
|
static void encryptUserDataEnc()
|
|
{
|
|
int retCode, algAnswer;
|
|
DinkeyPro ddpro = new DinkeyPro();
|
|
byte[] data = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; // The data to be encrypted
|
|
byte[] originalData = data.clone(); // A copy of the data for displaying later
|
|
byte[] encryptedData;
|
|
|
|
// Initialise the DRIS
|
|
ddpro.function = DinkeyPro.ENCRYPT_USER_DATA;
|
|
ddpro.flags = DinkeyPro.USE_FUNCTION_ARGUMENT; // Java uses DDProtCheck()'s data parameter, so this flag must be set
|
|
ddpro.rw_length = data.length; // The number of bytes to be encrypted
|
|
ddpro.data_crypt_key_num = 1; // The encryption key to use
|
|
|
|
// If taking data encryption parameters from the R/W algorithm:
|
|
// Calculate the R/W algorithm result
|
|
// The input variables were initialised to random values when ddpro was created
|
|
algAnswer = myRwAlgorithm(ddpro.var_a, ddpro.var_b, ddpro.var_c, ddpro.var_d, ddpro.var_e, ddpro.var_f, ddpro.var_g, ddpro.var_h);
|
|
|
|
// Use the algorithm result to encrypt the data passed to the API
|
|
ddpro.cryptApiData(data, algAnswer);
|
|
|
|
// If using constant data encryption parameters:
|
|
// ddpro.cryptApiData(data, DATA_ENCRYPTION_PARAMETER_1, DATA_ENCRYPTION_PARAMETER_2, DATA_ENCRYPTION_PARAMETER_3);
|
|
|
|
// Encrypt the DRIS
|
|
ddpro.cryptDris(DRIS_ENCRYPTION_PARAMETER_1, DRIS_ENCRYPTION_PARAMETER_2, DRIS_ENCRYPTION_PARAMETER_3);
|
|
|
|
// Call the API
|
|
retCode = ddpro.checkProtection(data);
|
|
|
|
// Decrypt the DRIS
|
|
ddpro.cryptDris(DRIS_ENCRYPTION_PARAMETER_1, DRIS_ENCRYPTION_PARAMETER_2, DRIS_ENCRYPTION_PARAMETER_3);
|
|
|
|
// Do not call cryptApiData() here to decrypt the data received from the API!
|
|
// The data has been encrypted by the dongle hardware, so the API will not apply an unnecessary second layer of encryption
|
|
|
|
// Check the return value
|
|
if (retCode != 0)
|
|
{
|
|
displayError(retCode, ddpro.ext_err);
|
|
return;
|
|
}
|
|
|
|
encryptedData = data.clone(); // A copy of the encrypted data for displaying later
|
|
|
|
// Initialise the DRIS
|
|
ddpro.reset(); // Reset the DRIS fields with random values
|
|
ddpro.function = DinkeyPro.DECRYPT_USER_DATA;
|
|
ddpro.flags = DinkeyPro.USE_FUNCTION_ARGUMENT; // Java uses DDProtCheck()'s data parameter, so this flag must be set
|
|
ddpro.rw_length = data.length;
|
|
ddpro.data_crypt_key_num = 1; // This must be the same key used to encrypt the data
|
|
|
|
// Encrypt the DRIS
|
|
ddpro.cryptDris(DRIS_ENCRYPTION_PARAMETER_1, DRIS_ENCRYPTION_PARAMETER_2, DRIS_ENCRYPTION_PARAMETER_3);
|
|
|
|
// Do not call cryptApiData() here to encrypt the data passed to the API!
|
|
// The data is already encrypted, so the API does not expect an unnecessary second layer of encryption
|
|
|
|
// Call the API
|
|
retCode = ddpro.checkProtection(data);
|
|
|
|
// Decrypt the DRIS
|
|
ddpro.cryptDris(DRIS_ENCRYPTION_PARAMETER_1, DRIS_ENCRYPTION_PARAMETER_2, DRIS_ENCRYPTION_PARAMETER_3);
|
|
|
|
// Check the return value
|
|
if (retCode != 0)
|
|
{
|
|
displayError(retCode, ddpro.ext_err);
|
|
return;
|
|
}
|
|
|
|
// If taking data encryption parameters from the R/W algorithm:
|
|
// Calculate the R/W algorithm result
|
|
// The input variables were initialised to random values when ddpro was created
|
|
algAnswer = myRwAlgorithm(ddpro.var_a, ddpro.var_b, ddpro.var_c, ddpro.var_d, ddpro.var_e, ddpro.var_f, ddpro.var_g, ddpro.var_h);
|
|
|
|
// Use the algorithm result to decrypt the data received from the API
|
|
ddpro.cryptApiData(data, algAnswer);
|
|
|
|
// If using constant data encryption parameters:
|
|
// ddpro.cryptApiData(data, DATA_ENCRYPTION_PARAMETER_1, DATA_ENCRYPTION_PARAMETER_2, DATA_ENCRYPTION_PARAMETER_3);
|
|
|
|
System.out.println("Data encryption successful.");
|
|
System.out.println("Original data: " + Arrays.toString(originalData));
|
|
System.out.println("Encrypted data: " + Arrays.toString(encryptedData));
|
|
System.out.println("Decrypted data: " + Arrays.toString(data));
|
|
return;
|
|
}
|
|
|
|
// An example of a simple protection check and displaying information about the current users of a network dongle.
|
|
// This feature is supported by Dinkey Pro Net and Dinkey FD Net dongles only.
|
|
// queryNetUsers() will only work following a call to checkProtection() that established a connection to DinkeyServer.
|
|
static void displayNetUsers()
|
|
{
|
|
int retCode, maxNetUsersToQuery;
|
|
|
|
DinkeyPro ddpro = new DinkeyPro(); // Create a DinkeyPro instance. All DRIS fields are initialised to random values
|
|
|
|
// Initialise the DRIS
|
|
ddpro.function = DinkeyPro.PROTECTION_CHECK;
|
|
ddpro.flags = DinkeyPro.START_NET_USER;
|
|
|
|
// Call the API
|
|
retCode = ddpro.checkProtection();
|
|
|
|
// Check the return value
|
|
if (retCode != 0)
|
|
{
|
|
displayError(retCode, ddpro.ext_err);
|
|
return;
|
|
}
|
|
|
|
// If you lock your software to multiple dongle models,
|
|
// you might want to check that a network dongle was found before trying to get network user information
|
|
if ((ddpro.model == DinkeyPro.MODEL_LITE) || (ddpro.model == DinkeyPro.MODEL_PLUS))
|
|
{
|
|
System.out.println("Local dongle found. No network user information to display.");
|
|
return;
|
|
}
|
|
|
|
// Set maxNetUsersToQuery to a sensible value!
|
|
// This example requests information about 10 users if there is no limit to the number of users supported by the dongle
|
|
if (ddpro.net_users == DinkeyPro.UNLIMITED_NET_USERS)
|
|
maxNetUsersToQuery = 10;
|
|
else
|
|
maxNetUsersToQuery = ddpro.net_users;
|
|
|
|
// Call the API
|
|
retCode = ddpro.queryNetUsers(maxNetUsersToQuery);
|
|
|
|
// Check the return value
|
|
if (retCode != 0)
|
|
{
|
|
System.out.println("An error occurred getting network user information.");
|
|
System.out.println("Error: " + retCode + "\nExtended Error: " + ddpro.queryNetUsersExtErr);
|
|
return;
|
|
}
|
|
|
|
System.out.println(ddpro.numNetUsers + " current network users:\n");
|
|
for (int i = 0; i < ddpro.num_net_users; i++)
|
|
{
|
|
System.out.println((i+1) + ") " + ddpro.userNames[i] + " @ " + ddpro.computerNames[i] + " (" + ddpro.ipAddresses[i] + ") using licence '" + ddpro.licenceNames[i] + "'");
|
|
}
|
|
return;
|
|
}
|
|
|
|
|
|
// !!!! This method must match one stored in the dongle for protCheckWithAlg() to work correctly.
|
|
// For Lite dongles, use DinkeyLook to see the algorithm pre-programmed into the dongle.
|
|
// For Plus and Net dongles, ensure this algorithm matches one you specified in DinkeyAdd when adding protection.
|
|
static int myAlgorithm(int a, int b, int c, int d, int e, int f, int g, int h)
|
|
{
|
|
return a + b + c + d + e + f + g + h;
|
|
}
|
|
|
|
// !!!! This method must match the R/W algorithm stored in the dongle for
|
|
// writeDataAreaEnc() and readDataAreaEnc() to work correctly.
|
|
static int myRwAlgorithm(int a, int b, int c, int d, int e, int f, int g, int h)
|
|
{
|
|
return a ^ b ^ c ^ d ^ e ^ f;
|
|
}
|
|
|
|
|
|
// An example of error reporting. Displays descriptions for some common error codes.
|
|
// IMPORTANT - THE MESSAGES DISPLAYED ARE TO HELP DEVELOPERS IMPLEMENT THE DINKEY PRO/FD API.
|
|
// THEY ARE NOT SUITABLE FOR DISPLAYING TO USERS!
|
|
static void displayError(int retCode, int extErr)
|
|
{
|
|
switch (retCode)
|
|
{
|
|
case 401:
|
|
System.out.println("Error! No dongles detected!");
|
|
break;
|
|
case 403:
|
|
System.out.println("Error! The dongle is a different type to the one specified in DinkeyAdd.");
|
|
break;
|
|
case 404:
|
|
System.out.println("Error! The dongle is a different model to those specified in DinkeyAdd.");
|
|
break;
|
|
case 409:
|
|
System.out.println("Error! The dongle has not been programmed by DinkeyAdd.");
|
|
break;
|
|
case 410:
|
|
System.out.println("Error! The dongle has a different product code to the one specified in DinkeyAdd.");
|
|
break;
|
|
case 411:
|
|
System.out.println("Error! This software's licence was not found in the dongle.");
|
|
break;
|
|
case 413:
|
|
System.out.println("Error! This software has not been locked by DinkeyAdd. For guidance please read the DinkeyAdd chapter of the user manual.");
|
|
break;
|
|
case 417:
|
|
System.out.println("Error! One or more of the parameters set in the DRIS is incorrect.\nCheck if you are encrypting the DRIS in your code but did not specify DRIS encryption in DinkeyAdd - or vice versa.");
|
|
break;
|
|
case 423:
|
|
System.out.println("Error! The number of network users has been exceeded.");
|
|
break;
|
|
case 435:
|
|
System.out.println("Error! DinkeyServer has not been detected on the network.");
|
|
break;
|
|
case 922:
|
|
System.out.println("Error! The Software Key has expired.");
|
|
break;
|
|
default:
|
|
System.out.println("An error occurred checking the dongle.\nError: " + retCode + "\nExtended Error: " + extErr);
|
|
break;
|
|
}
|
|
return;
|
|
}
|
|
|
|
}
|