C and C++ Sample Code
=====================

The source files in this folder are common to all C/C++ implementations:

apitest.c		examples of calling the runtime protection API, e.g. protection checks, reading/writing the dongle secure data area.
dris.h			defines structures, constants and function prototypes for the runtime protection API.

changetest.c	examples of calling the DinkeyChange API.
changetest.h    defines structures, constants and function prototypes for the DinkeyChange API.

dapftest.c      examples of calling the DinkeyAdd API.
dapf.h          defines structures, constants and function prototypes for the DinkeyAdd API.

drpftest.c      examples of calling the DinkeyRemote API.
drpf.h          defines structures, constants and function prototypes for the DinkeyRemote API.

In order for the projects to compile without modification we have also included the folders:

import_libs     import libraries that contain the function definitions for the dynamic API libraries (e.g. dpwin32.dll).
object_modules  static API libraries:
                    Use dpwin32_coff.obj for Visual Studio, MinGW and other compilers that expect the COFF object module format.
                    Use dpwin32_omf.obj for C++ Builder and other compilers that expects an OMF object module.
                    There is only one 64-bit object module because in 64-bit Windows only the COFF format exists.

The subfolders contain projects for different IDEs and/or compilers:

Visual Studio 2008      for all version of Visual Studio from 2008 onwards. 32-bit and 64-bit.
Visual Studio 5         for earlier versions of Visual Studio. 32-bit only.

C++ Builder XE3         for versions of C++ Builder from XE3 onwards.
C++ Builder             for versions of C++ Builder from 2007 to XE2. If you are using a version earlier than this then please read the README.txt file in that folder.

Within the subfolders are different projects:

The ObjTest project checks the dongle by calling the appropriate static library (object module).

The DllTest project checks the dongle by calling the dynamic library dpwin32.dll (or dpwin64.dll for 64-bit code).

The ChangeTest project calls the DinkeyChange API which accepts update codes generated by DinkeyRemote.

The dapfTest project calls the DinkeyAdd API to program dongles and lock your software.

The drpfTest project calls the DinkeyRemote API to generate remote update codes.


Notes concerning Debug Modules
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

The debug modules are:

dpwin32_coff_debug.obj   dpwin32_omf_debug.obj   dpwin64debug.obj
dpwin32debug.dll   dpwin64debug.dll
DinkeyChangeDebug.dll   DinkeyChange64Debug.dll

Note - the DinkeyAdd and DinkeyRemote modules have no debug versions.

When you use a normal runtime module (e.g. dpwin32.dll) to protect your software the anti-debug code is
so strong that if you are debugging your code after the call DDProtCheck then it will crash. If you want to
be able to debug your code then you can setup your project so that your code calls one of the debug modules
when you are producing your debug code and one of the standard runtime modules when you produce your release
code. The Runtime debug module has the following restrictions:

1) It will not correctly start a network user (network dongles only). However, other than that the protection check
   will function correctly and return success.
2) You will not be able to encrypt the DRIS. (If you do encrypt the DRIS in your release build then you should make
   sure that CryptDRIS does not get called in your debug build).
3) The protection check will take slightly longer than normal.
4) The DDGetNetUserList function will return error 428 (not implemented).
5) A temporary subprocess is created which may be (falsely) detected as malicious by anti-virus programs.

Note: the debug DinkeyChange modules have no restrictions (except for number 5 above).


Loading Runtime module using LoadLibrary
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

If you want to control when the DLL is loaded / unloaded or you want to rename dpwin32.dll
(but cannot change the import library, e.g. with Microsoft Visual Studio),
then you should use LoadLibrary / GetProcAddress to load our library instead of linking the relevant import library.
The DLL is normally placed in the same folder as the program that is calling it.
This code snippet shows how you can do this:

#include "dris.h"

// declare function type
typedef int (__stdcall * TypeDDProtCheck)(DRIS*, BYTE *);

HMODULE           hProtLib;
TypeDDProtCheck   DDProtCheck;

hProtLib = LoadLibrary("dpwin32.dll");						// if you have renamed the dll then you should use the new name.

DDProtCheck = (TypeDDProtCheck)GetProcAddress(hProtLib, "DDProtCheck");

// use function as normal (see sample code)

// free handle when you no longer need to call the DLL (typically the end of your program)
FreeLibrary(hProtLib);


Unresolved External Symbol Errors
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

If you using a static runtime module (e.g. dpwin64.obj) then in rare cases you can receive errors like this:
dpwin64.obj : error LNK2019: unresolved external symbol __imp_SetSecurityDescriptorDacl referenced in function 
fatal error LNK1120: 6 unresolved externals

To fix this problem you need to make sure the following libraries are included in your project:
User32.lib
Advapi32.lib
ws2_32.lib

Normally these libraries are included as standard by your C/C++ IDE (e.g Visual Studio). However, in rare cases,
such as using the Qt platform or if you are using a C/C++ compiler/linker on the command line, these
libraries may not be included by default so you have include them yourself.
 