Using Dinkey Pro/FD with Java

Protection checks in Java are implemented using DinkeyPro.class to communicate with the dongle via the appropriate native library (DPJava.dll on 32-bit Windows, libDPJava64.so on 64-bit Linux, etc.). You should lock these native libraries with the API method using DinkeyAdd as described in the user manual, and distribute the locked libraries with your software.

The DinkeyPro class provides a Java wrapper around the Dinkey Pro/FD API, which is implemented by native libraries. If you are not familiar with calling native libraries, it is recommended that you read the Java documentation on the subject, especially the documentation for System.loadLibrary() and System.load(), and how Java uses the system property java.library.path to locate native libraries.

The native libraries and the DinkeyPro class are part of the uk.microcosm.dinkeydongle package. See the documentation for your development environment for details of how to include and reference this package in your project. dinkeydongle.jar provides all of the Java classes in the uk.microcosm.dinkeydongle package in a single JAR file. This allows you to import the package much more easily in many Java IDEs. Note that the native libraries are not included in the JAR file. You will need to distribute with your software locked copies of the native libraries for every platform that your software supports.

Do not specify a calling program when locking the native libraries. The calling program for Java software is the user's JVM, which will be different for different users.

Java bytecode is more easily decompiled than native code. For maximum security, it is recommended that you obfuscate your Java code using a third-party tool.

The DinkeyPro Class

Instances of DinkeyPro contain an internal DRIS. Most of this structure's members are exposed as public fields that can be directly accessed. Others must be accessed via get...() and set...() methods: see below for details. As Java does not have unsigned types, DRIS members that are documented as unsigned integers in the user manual are represented by long fields in the DinkeyPro class.

The header and size DRIS members are set automatically. You do not need to set these fields in your code.

rw_data_ptr is not used in Java. To use an API function that passes data to/from the dongle, you must use the checkProtection(byte[] data) method and also set the USE_FUNCTION_ARGUMENT flag.

Fields

Possible values for the function DRIS field, as documented in the user manual:

Possible values for the flags DRIS field, as documented in the user manual:

Possible values for the type DRIS field, as documented in the user manual:

Possible values for the model DRIS field, as documented in the user manual:

Possible values for the net_users DRIS field, as documented in the user manual:

Directly accessible DRIS fields, as documented in the user manual:

Fields used to access information returned by DDGetNetUserList():

The string arrays should be used in combination, i.e. licenceNames[0], userNames[0], computerNames[0] and ipAddresses[0] together describe a single network user.

Constructors

These constructors can throw any exception thrown by System.loadLibrary() and System.load(). See the documentation for those methods for details.

DinkeyPro()

Creates a new DinkeyPro instance and calls System.loadLibrary() to load the native library using the default filename. The library must be located in one of the paths specified in the java.library.path system property. The exact filename is implementation-dependent, but the most common names are:

The members of the instance's internal DRIS are initialised to random values.

DinkeyPro(String libName)

Creates a new DinkeyPro instance and calls System.loadLibrary(libName) to load the native library. The library must be located in one of the paths specified in the java.library.path system property. If System.loadLibrary(libName) fails, it then calls System.load(libName). Use this version of the constructor if you rename the native libraries (recommended), or if you need to specify the absolute path to the library.

The members of the instance's internal DRIS are initialised to random values.

Methods

int checkProtection()

Calls DDProtCheck() in the native library using the internal DRIS. Returns zero on success, or a value indicating the cause of the error on failure.

int checkProtection(byte[] data)

Calls DDProtCheck() in the native library using the internal DRIS. data is passed to the API (e.g. when writing to the dongle data area), or acts as a buffer filled by the API (e.g. when reading from the dongle data area). When using this method you must also set the USE_FUNCTION_ARGUMENT flag. Returns zero on success, or a value indicating the cause of the error on failure.

int queryNetUsers(int maxUsersToQuery)

Calls DDGetNetUserList() in the native library. maxNetUsersToQuery specifies the maximum number of current network users to return information about. Use this version of this method to get information about the current network users for the protected software's licence (if protected with the per licence network users option), or all licences in the dongle (if protected with the per product network users option). Returns zero on success, or a value indicating the cause of the error on failure.

int queryNetUsers(String licenceName, int maxUsersToQuery)

Calls DDGetNetUserList() in the native library. maxNetUsersToQuery specifies the maximum number of current network users to return information about. Use this version of this method to get information about the current network users for the licence specified by licenceName. Returns zero on success, or a value indicating the cause of the error on failure.

void reset()

Set all members of the internal DRIS to random values.

String getProdCode()

Return the prodcode member of the internal DRIS as a Java string.

String getFdDrive()

Return the fd_drive member of the internal DRIS as a Java string.

void setAltLicenceName(String altLicenceName)

Assign the value of altLicenceName to the alt_licence_name member of the internal DRIS.

void cryptDris(int encryptionParameter1, int encryptionParameter2, int encryptionParameter3)

Encrypt/decrypt the internal DRIS. encryptionParameter1, encryptionParameter2 and encryptionParameter3 must match the parameters specified for DRIS encryption in DinkeyAdd.

void cryptApiData(byte[] data, int algAnswer)

Encrypt/decrypt checkProtection()'s data parameter using the result of the R/W algorithm. The option to take data encryption parameters from the R/W algorithm must also be selected in DinkeyAdd when adding protection, and algAnswer must be the result of an algorithm that matches the R/W algorithm specified there.

void cryptApiData(byte[] data, int encryptionParameter1, int encryptionParameter2, int encryptionParameter3)

Encrypt/decrypt checkProtection()'s data parameter using constant parameters. The option to use constant data encryption parameters must be selected in DinkeyAdd when adding protection, and encryptionParameter1, encryptionParameter2 and encryptionParameter3 must match the parameters specified there.

Java Example Files

Supported Versions

All parts of the uk.microcosm.dinkeydongle package support Java platforms version 5 and newer.

Try It Yourself

The sample code is designed to teach you how to use the Dinkey Pro/FD API in Java programs. Do not copy the examples verbatim into your own code. Experiment with the sample code to understand how the API works, and read the chapter Increasing Your Protection in the user manual for many suggestions on how to make the best use of the API features.

DPSample.java gives simple examples of performing a protection check, as well as using various other features of Dinkey Pro/FD. To run the DPSample program you will first need to use DinkeyAdd to produce a locked copy of the native library for your platform, and program a dongle (if you are using Plus or Net dongles). Place the locked library in one of the paths specified by your Java environment's java.library.path system property. Browse the examples in DPSample.java to see how different features can be used. All the examples follow the same basic pattern:

  1. Create a DinkeyPro instance and set up its internal DRIS with the relevant information.
  2. Call the API.
  3. Use the information returned in the internal DRIS.

Uncomment the calls at the top of the main() method in DPSample.java to enable the examples of different features, then recompile and run DPSample to run the examples.

Parts of the sample code marked with !!!! must be customised with your own functions or values for some features to work correctly. Not all features are supported by all dongle models. See the user manual for more information.