Add Original SDK

This commit is contained in:
2026-05-06 07:47:36 +02:00
parent 2915e04380
commit 0ed627517a
674 changed files with 89334 additions and 0 deletions

View File

@@ -0,0 +1,273 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Using the DinkeyChange API with MATLAB</title>
<style>
body {
color: black;
font-family: Verdana, Arial, Helvetica, sans-serif;
font-size: 13px;
margin: 25px auto;
max-width: 800px;
}
p, ul, ol, table {
margin-top: 0;
margin-bottom: 15px;
}
ul.contents a {
text-decoration: none;
}
h1,h2,h3,h4,h5,h6 {
margin-top: 25px;
margin-bottom: 15px;
}
h2 {
border-top: 1px solid gray;
}
table {
margin-left: auto;
margin-right: auto;
border-collapse: collapse;
}
th, td {
border: 1px solid black;
padding: 0.5em;
text-align: left;
}
.ui_element
{ /* Use for things like program options and menu items */
color: #008000;
font-style: italic;
}
.filepath
{ /* Use for paths and filenames */
font-family: monospace;
font-size: 13px;
font-weight: bold;
}
.manual
{ /* Use when referring to user manual sections/chapters */
font-style: italic;
}
.alert
{
border: 1px solid black;
padding: 15px 15px 15px 58px;
font-weight: bold;
background-repeat: no-repeat;
background-position: 5px 15px;
margin-bottom: 15px;
}
.important
{
background-color: #FFFDD0;
background-image: url('data:image/png;base64,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');
}
.information
{
background-color: #EBF8FF;
background-image: url('data:image/png;base64,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');
}
.alert > p:last-child, .alert > ul:last-child, .alert > ol:last-child
{
/* Cancel double space at bottom of alert caused by above rule */
margin-bottom: 0;
}
.important .filepath, .information .filepath {
/* Make filepaths stand out in sections that are already bold */
font-weight: normal;
}
div.col_wrapper
{
clear: both;
overflow: hidden;
}
div.two_col
{
width: 50%;
float: left;
}
code {
color: gray;
white-space: nowrap;
}
pre {
padding: 15px;
background-color: #EEEEEE;
}
pre > code { /* Block level code snippets */
white-space: pre; /* Override nowrap used for inline code */
color: inherit;
}
code .comment
{
color: green;
}
code .keyword
{
font-weight: bold;
color: blue;
}
code .string
{
color: #A00000;
}
code .constant
{
font-weight: bold;
}
</style>
</head>
<body>
<h1>Using the DinkeyChange API with MATLAB</h1>
<p>
If you are not already familiar with calling shared libraries from MATLAB code,
it is strongly recommended that you read the MATLAB documentation on this topic.
Depending on your version of MATLAB, you may need to install a C compiler and configure MATLAB to use it with the command <code>mex -setup</code>.
Again, refer to the MATLAB documentation for further information.
</p>
<p>
See <span class="manual">Remote Parameter Changing &gt; DinkeyChange &gt; DinkeyChange.dll</span> in the user manual for information on using the DinkeyChange API.
Use the <code>help</code> command to see overviews of how each M-file interface to the DinkeyChange API is used in MATLAB.
Most of the DinkeyChange M-files are simple MATLAB wrappers for the shared library functions.
<span class="filepath">dcgetinfo.m</span> however is quite different to the <code>DCGetInfo()</code> function described in the user manual:
</p>
<pre><code>[retCode, dongleArray] = dcgetinfo(libName, typeMask, modelMask, prodcodeMask)</code></pre>
<p>
The inputs <code>typeMask</code>, <code>modelMask</code> and <code>prodcodeMask</code>
are used in the same way as the inputs of <code>DCGetInfo()</code>, as <span class="filepath">dcsample.m</span> illustrates.
The outputs however are grouped together as <code>dongleArray</code>, a 1-by-N vector of MATLAB structures.
Each structure represents a dongle found by <code>dcgetinfo</code>'s search, and each structure has the following fields:
</p>
<table>
<tr>
<th>Field</th>
<th>Data Type</th>
<th>Description</th>
</tr>
<tr>
<td>type</td>
<td>int32</td>
<td>
The dongle's type as a numeric value. Possible values:
<ul>
<li>1 for Dinkey Pro dongles</li>
<li>2 for Dinkey FD dongles</li>
</ul>
</td>
</tr>
<tr>
<td>type_as_string</td>
<td>char</td>
<td>
The dongle's type as a string. Possible values:
<ul>
<li>"Pro"</li>
<li>"FD"</li>
</ul>
</td>
</tr>
<tr>
<td>model</td>
<td>int32</td>
<td>
The dongle's model as a numeric value. Possible values:
<ul>
<li>1 for Lite dongles</li>
<li>2 for Plus dongles</li>
<li>4 for Net dongles (5 users)</li>
<li>7 for Net dongles (unlimited users)</li>
</ul>
</td>
</tr>
<tr>
<td>model_as_string</td>
<td>char</td>
<td>
The dongle's model as a string. Possible values:
<ul>
<li>"Lite"</li>
<li>"Plus"</li>
<li>"Net (5 users)"</li>
<li>"Net (unlimited users)"</li>
</ul>
</td>
</tr>
<tr>
<td>product_code</td>
<td>char</td>
<td>The dongle's product code</td>
</tr>
<tr>
<td>dongle_number</td>
<td>uint32</td>
<td>The dongle's serial number (dongle number)</td>
</tr>
<tr>
<td>update_number</td>
<td>int32</td>
<td>The dongle's update number</td>
</tr>
</table>
<h2>MATLAB Example Files</h2>
<ul>
<li><span class="filepath">dcgetinfo.m</span> - an M-file that provides a MATLAB interface to the <code>DCGetInfo()</code> API function.</li>
<li><span class="filepath">dcgetdiagnosticinfo.m</span> - a MATLAB interface to the <code>DCGetDiagnosticInfo()</code> API function.</li>
<li><span class="filepath">dcdoupdatecodestring.m</span> - a MATLAB interface to the <code>DCDoUpdateCodeString()</code> API function.</li>
<li><span class="filepath">dcdoupdatecodefromfile.m</span> - a MATLAB interface to the <code>DCDoUpdateCodeFromFile()</code> API function.</li>
<li><span class="filepath">dcrestoredinkeyfdlite.m</span> - a MATLAB interface to the <code>DCRestoreDinkeyFDLite()</code> API function.</li>
<li><span class="filepath">dcgetmachineid.m</span> - a MATLAB interface to the <code>DCGetMachineID()</code> API function.</li>
<li><span class="filepath">dcdownloadtempsoftwarekey.m</span> - a MATLAB interface to the <code>DCDownloadTempSoftwareKey()</code> API function.</li>
<li><span class="filepath">dcdownloaddemosoftwarekey.m</span> - a MATLAB interface to the <code>DCDownloadDemoSoftwareKey()</code> API function.</li>
<li><span class="filepath">dcsample.m</span> - examples of using these M-files.</li>
<li><span class="filepath">dinkeychangewin32proto.p</span> - a prototype P-file that defines the signatures of the API functions for 32-bit MATLAB on Windows.</li>
<li><span class="filepath">dinkeychange32proto.p</span> - a prototype P-file that defines the signatures of the API functions for 32-bit MATLAB on all other supported platforms.</li>
<li><span class="filepath">dinkeychange64proto.p</span> - a prototype P-file that defines the signatures of the API functions for 64-bit MATLAB on all supported platforms.</li>
<li><span class="filepath">DinkeyChange64_thunk_pcwin64.dll</span> - a compatibility layer required by 64-bit MATLAB to use <span class="filepath">DinkeyChange64.dll</span>.</li>
</ul>
<p>
The appropriate prototype P-file and any M-files that you call should be included, <strong>without modification</strong>, in your own project.
If you are using 64-bit MATLAB on Windows, you should also include <span class="filepath">DinkeyChange64_thunk_pcwin64.dll</span>.
If you rename <span class="filepath">DinkeyChange64.dll</span>,
you must change the <em>DinkeyChange64</em> part of the thunking DLL's filename accordingly.
</p>
<p>
Our M-files and P-files are compatible with MATLAB on macOS and Linux.
However, we do not currently provide the thunk files required by 64-bit MATLAB on these platforms.
If you want to use the DinkeyChange API on 64-bit macOS and/or 64-bit Linux,
please contact us with full details of the platform(s) and MATLAB versions that you want to use,
and we can provide compatible thunk files or instruct you on how to produce these files yourself.
</p>
<h2>Supported Versions</h2>
<p>
The MATLAB sample code provided with the Dinkey Pro/FD SDK was written and tested using MATLAB R2013a.
All newer versions should be backwards compatible. The sample code may also work with older versions,
but no guarantees can be made, and support for older versions is likely to be very limited.
</p>
<h2>Try It Yourself</h2>
<p>
<span class="filepath">dcsample.m</span> gives a simple example of calling each of the API functions.
To run <span class="filepath">dcsample.m</span> you will need a copy of the appropriate shared library for your platform
(<span class="filepath">DinkeyChange.dll</span> for 32-bit Windows, <span class="filepath">DinkeyChange64.so</span> for 64-bit Linux etc.).
Place the library in the same folder as the example files and change MATLAB's current directory to this folder.
Browse the examples in <span class="filepath">dcsample.m</span> to see how different features can be used.
</p>
<p>
Uncomment the function calls at the top of <span class="filepath">dcsample.m</span>
to enable the examples of different features, then enter <code>dcsample</code> in the Command Window to run the examples.
</p>
<p>
<span class="filepath">dcsample.m</span> also demonstrates loading and unloading the appropriate shared library for your platform.
</p>
<p>
Parts of the sample code marked with <code>!!!!</code> 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.
</p>
</body>
</html>

View File

@@ -0,0 +1,17 @@
function [retCode, confirmationCode, extErr] = dcdoupdatecodefromfile(libName, filename)
%DCDOUPDATECODEFROMFILE Update a dongle attached to this computer using a
%strongly encrypted update code.
% [RETCODE,CONFIRMATIONCODE,EXTERR] =
% DCDOUPDATECODEFROMFILE(LIBNAME,FILENAME) calls the API via the external
% library LIBNAME. FILENAME is a file containing the update code to be
% applied. RETCODE is the return code of the API call. If the update
% succeeded, CONFIRMATIONCODE contains the update's confirmation code. If
% the update failed, EXTERR contains an additional error code that
% provides more information.
% Copyright Microcosm Ltd. DO NOT MODIFY THIS FILE.
confirmationCode = int32(0);
extErr = int32(0);
[retCode, filename, confirmationCode, extErr] = calllib(libName, 'DCDoUpdateCodeFromFile', filename, confirmationCode, extErr);
end

View File

@@ -0,0 +1,17 @@
function [retCode, confirmationCode, extErr] = dcdoupdatecodestring(libName, updateCode)
%%DCDOUPDATECODESTRING Update a dongle attached to this computer using a
%short update code.
% [RETCODE,CONFIRMATIONCODE,EXTERR] =
% DCDOUPDATECODESTRING(LIBNAME,UPDATECODE) calls the API via the external
% library LIBNAME. UPDATECODE is the short update code to be applied.
% RETCODE is the return code of the API call. If the update succeeded,
% CONFIRMATIONCODE contains the update's confirmation code. If the update
% failed, EXTERR contains an additional error code that provides more
% information.
% Copyright Microcosm Ltd. DO NOT MODIFY THIS FILE.
confirmationCode = int32(0);
extErr = int32(0);
[retCode, updateCode, confirmationCode, extErr] = calllib(libName, 'DCDoUpdateCodeString', updateCode, confirmationCode, extErr);
end

View File

@@ -0,0 +1,15 @@
function [retCode, extErr] = dcdownloaddemosoftwarekey(libName, machineId, productCode, model)
%DCDOWNLOADDEMOSOFTWAREKEY Download and install a demo software key.
% [RETCODE,EXTERR] = DCDOWNLOADDEMOSOFTWAREKEY(LIBNAME,MACHINEID,PRODUCTCODE,MODEL)
% calls the API via the external library LIBNAME. MACHINEID is the machine
% ID of this computer (you can obtain this by calling the API function
% DCGETMACHINEID). PRODUCTCODE and MODEL specify the product code and dongle
% model of the demo software key to be installed. RETCODE is the return code
% of the API call. If the update failed, EXTERR contains an additional error
% code that provides more information.
% Copyright Microcosm Ltd. DO NOT MODIFY THIS FILE.
extErr = int32(0);
[retCode, productCode, extErr] = calllib(libName, 'DCDownloadDemoSoftwareKey', machineId, productCode, model, extErr);
end

View File

@@ -0,0 +1,14 @@
function [retCode, extErr] = dcdownloadtempsoftwarekey(libName, machineId)
%DCDOWNLOADTEMPSOFTWAREKEY Download and install a temporary software key.
% [RETCODE,EXTERR] = DCDOWNLOADTEMPSOFTWAREKEY(LIBNAME,MACHINEID) calls the
% API via the external library LIBNAME. MACHINEID is the machine ID of
% this computer (you can obtain this by calling the API function
% DCGETMACHINEID). RETCODE is the return code of the API call. If the
% update failed, EXTERR contains an additional error code that provides
% more information.
% Copyright Microcosm Ltd. DO NOT MODIFY THIS FILE.
extErr = int32(0);
[retCode, extErr] = calllib(libName, 'DCDownloadTempSoftwareKey', machineId, extErr);
end

View File

@@ -0,0 +1,13 @@
function retCode = dcgetdiagnosticinfo(libName, filename)
%DCGETDIAGNOSTICINFO Call the DinkeyChange API to write diagnostic
%information to a file.
% RETCODE = DCGETDIAGNOSTICINFO(LIBNAME,FILENAME) calls the API via the
% external library LIBNAME, writing diagnostic information to the file
% specified in FILENAME. FILENAME can be an absolute or relative path. If
% FILENAME does not end in '.dlpf', it will be appended automatically.
% RETCODE is the return code of the API call.
% Copyright Microcosm Ltd. DO NOT MODIFY THIS FILE.
retCode = calllib(libName, 'DCGetDiagnosticInfo', filename);
end

View File

@@ -0,0 +1,72 @@
function [retCode, dongleArray] = dcgetinfo(libName, typeMask, modelMask, prodcodeMask)
%DCGETINFO Get information about Dinkey Pro/FD dongles attached to this
%computer.
% [RETCODE,DONGLEARRAY] =
% DCGETINFO(LIBNAME,TYPEMASK,MODELMASK,PRODCODEMASK) calls the API via
% the external library LIBNAME. TYPEMASK, MODELMASK and PRODCODEMASK can
% be used to restrict the search to dongles with specific
% characteristics. DONGLEARRAY is a vector of structures; each structure
% contains information about a dongle attached to this computer. RETCODE
% is the return code of the API call.
% Copyright Microcosm Ltd. DO NOT MODIFY THIS FILE.
MAX_USB_DEVICES = 128;
MAX_PRODCODE_LEN = 9;
dongleArray = [];
numberFound = int32(0);
typeArray = zeros(1, MAX_USB_DEVICES, 'int32');
modelArray = zeros(1, MAX_USB_DEVICES, 'int32');
productCodeArray = zeros(1, MAX_USB_DEVICES * MAX_PRODCODE_LEN, 'uint8');
dongleNumberArray = zeros(1, MAX_USB_DEVICES, 'uint32');
updateNumberArray = zeros(1, MAX_USB_DEVICES, 'int32');
[retCode, prodcodeMask, numberFound, typeArray, modelArray, productCodeArray, dongleNumberArray, updateNumberArray] = ...
calllib(libName, 'DCGetInfo', typeMask, modelMask, prodcodeMask, MAX_USB_DEVICES, numberFound, typeArray, modelArray, productCodeArray, dongleNumberArray, updateNumberArray);
for (i = 1:numberFound)
productCode = productCodeArray(((i-1)*MAX_PRODCODE_LEN)+1 : i*MAX_PRODCODE_LEN); % Get product codes out of array of bytes, 9 bytes at a time
productCode = deblank(char(productCode)); % Convert to string and remove any trailing NULLs
newDongle = createdonglestructure(typeArray(i), modelArray(i), productCode, dongleNumberArray(i), updateNumberArray(i));
dongleArray = [dongleArray newDongle];
end
end
function dongle = createdonglestructure(type, model, productCode, dongleNumber, updateNumber)
% Create a structure representing a dongle detected by dcgetinfo()
dongle.type = type;
switch type
case 1
dongle.type_as_string = 'Pro';
case 2
dongle.type_as_string = 'FD';
otherwise
dongle.type_as_string = ''; % Should never happen!
end
dongle.model = model;
switch model
case 1
dongle.model_as_string = 'Lite';
case 2
dongle.model_as_string = 'Plus';
case 3
dongle.model_as_string = 'Net (1 user)';
case 4
dongle.model_as_string = 'Net (5 users)';
case 5
dongle.model_as_string = 'Net (10 users)';
case 6
dongle.model_as_string = 'Net (50 users)';
case 7
dongle.model_as_string = 'Net (unlimited users)';
otherwise
dongle.model_as_string = ''; % Should never happen!
end
dongle.product_code = char(productCode);
dongle.dongle_number = uint32(dongleNumber);
dongle.update_number = int32(updateNumber);
end

View File

@@ -0,0 +1,14 @@
function [retCode, machineId, extErr] = dcgetmachineid(libName)
%DCGETMACHINEID Get the machine ID for this computer
% [RETCODE,MACHINEID,EXTERR] = DCGETMACHINEID(LIBNAME) calls the API via
% the external library LIBNAME. RETCODE is the return code of the API
% call. If the update succeeded, MACHINEID is the machine ID of the
% computer. If this call failed, EXTERR contains an additional error code
% that provides more information.
% Copyright Microcosm Ltd. DO NOT MODIFY THIS FILE.
machineId = uint32(0);
extErr = int32(0);
[retCode, machineId, extErr] = calllib(libName, 'DCGetMachineID', machineId, extErr);
end

View File

@@ -0,0 +1,10 @@
function retCode = dcrestorefdlite(libName)
%DCRESTOREFDLITE Restore the required hidden file on all Dinkey FD Lite
%dongles attached to this computer.
% RETCODE = DCRESTOREFDLITE(LIBNAME) calls the API via the external
% library LIBNAME. RETCODE is the return code of the API call.
% Copyright Microcosm Ltd. DO NOT MODIFY THIS FILE.
retCode = calllib(libName, 'DCRestoreDinkeyFDLite');
end

View File

@@ -0,0 +1,249 @@
function dcsample
%DCSAMPLE Example use of the DinkeyChange API in MATLAB.
% Copyright Microcosm Ltd.
% Load the correct library for this platform
switch computer()
case 'PCWIN64' % 64-bit Windows
loadlibrary('DinkeyChange64.dll', @dinkeychange64proto, 'alias', 'dinkeychange');
case 'PCWIN' % 32-bit Windows
loadlibrary('DinkeyChange.dll', @dinkeychangewin32proto, 'alias', 'dinkeychange');
case 'GLNXA64' % 64-bit Linux
loadlibrary('DinkeyChange64.so', @dinkeychange64proto, 'alias', 'dinkeychange');
case 'GLNX86' % 32-bit Linux
loadlibrary('DinkeyChange.so', @dinkeychange32proto, 'alias', 'dinkeychange');
case 'MACI64' % 64-bit Mac OS X
loadlibrary('DinkeyChange64.dylib', @dinkeychange64proto, 'alias', 'dinkeychange');
case 'MAC' % 32-bit Mac OS X
loadlibrary('DinkeyChange32.dylib', @dinkeychange32proto, 'alias', 'dinkeychange');
otherwise
disp('Error! Platform not supported!');
return
end
% Each of the functions below demonstrates different API functionality.
% Uncomment the appropriate functions to execute the examples.
% See the comments in each function for more details about the features
% that they demonstrate.
getdongleinfo('dinkeychange');
%writediagnosticfile('dinkeychange');
%applyshortupdatecode('dinkeychange');
%applystronglyencryptedupdatecode('dinkeychange');
%restorefdlite('dinkeychange');
%getmachineid('dinkeychange');
%downloadtempsoftwarekey('dinkeychange');
%downloaddemosoftwarekey('dinkeychange');
unloadlibrary('dinkeychange');
end
function getdongleinfo(libName)
% Display information about the dongles attached to this computer
% Possible values for dcgetinfo's typeMask parameter
TYPE_MASK_PRO = 1;
TYPE_MASK_FD = 2;
TYPE_MASK_ALL = bitor(TYPE_MASK_PRO, TYPE_MASK_FD);
% Possible values for dcgetinfo's modelMask parameter
MODEL_MASK_LITE = 1;
MODEL_MASK_PLUS = 2;
MODEL_MASK_NET = 4;
MODEL_MASK_ALL = bitor(bitor(MODEL_MASK_LITE, MODEL_MASK_PLUS), MODEL_MASK_NET);
MODEL_MASK_DEFAULT = bitor(MODEL_MASK_PLUS, MODEL_MASK_NET);
% Call the DinkeyChange API
[retCode, dongleArray] = dcgetinfo(libName, TYPE_MASK_ALL, MODEL_MASK_ALL, '');
% Check the return value
if (retCode ~= 0)
displayerror(retCode, 0);
return
end
for (i = 1:length(dongleArray))
disp(sprintf('%3d) Dinkey %s %s', i, dongleArray(i).type_as_string, dongleArray(i).model_as_string));
disp(sprintf(' Product code : %s', dongleArray(i).product_code));
disp(sprintf(' Dongle number: %u', dongleArray(i).dongle_number));
disp(sprintf(' Update number: %u', dongleArray(i).update_number));
disp(sprintf('\n'));
end
end
function writediagnosticfile(libName)
% Write diagnostic information about the dongles attached to this computer
% to an encrypted file.
filename = '!!!! REPLACE THIS WITH THE NAME OF THE FILE TO WRITE TO';
% Call the DinkeyChange API
retCode = dcgetdiagnosticinfo(libName, filename);
% Check the return value
if (retCode ~= 0)
displayerror(retCode, 0);
return
end
disp(['Successfully wrote diagnostic information to ' filename]);
end
function applyshortupdatecode(libName)
% Update a dongle attached to this computer using a short update code
% Call the DinkeyChange API
[retCode, confirmationCode, extErr] = dcdoupdatecodestring(libName, '!!!! REPLACE THIS WITH A VALID UPDATE CODE STRING');
% Check the return value
if (retCode ~= 0)
displayerror(retCode, extErr);
return
end
disp('Successfully updated dongle');
disp(['Confirmation code: ' sprintf('%X', confirmationCode)]);
end
function applystronglyencryptedupdatecode(libName)
% Update a dongle attached to this computer using a strongly encrypted
% update code file
% Call the DinkeyChange API
[retCode, confirmationCode, extErr] = dcdoupdatecodefromfile(libName, '!!!! REPLACE THIS WITH A VALID UPDATE CODE FILENAME');
% Check the return value
if (retCode ~= 0)
displayerror(retCode, extErr);
return
end
disp('Successfully updated dongle');
disp(['Confirmation code: ' sprintf('%X', confirmationCode)]);
end
function restorefdlite(libName)
% Restore the required hidden file on a Dinkey FD Lite dongle.
% Call the DinkeyChange API
retCode = dcrestorefdlite(libName);
% Check the return value
if (retCode ~= 0)
displayerror(retCode, 0);
return
end
disp('Successfully restored FD Lite dongle');
end
function getmachineid(libName)
% Display this computer's machine ID
% Call the DinkeyChange API
[retCode, machineId, extErr] = dcgetmachineid(libName);
% Check the return value
if (retCode ~= 0)
displayerror(retCode, extErr);
return
end
disp(['The machine ID for this computer is: ' sprintf('%X', machineId)]);
end
function downloadtempsoftwarekey(libName)
% Download and install a temporary software key on this computer
% First call the DinkeyChange API to get the machine ID
[retCode, machineId, extErr] = dcgetmachineid(libName);
% Check the return value
if (retCode ~= 0)
displayerror(retCode, extErr);
return
end
% Then call the API again to install the software key
[retCode, extErr] = dcdownloadtempsoftwarekey(libName, machineId);
% Check the return value
if (retCode ~= 0)
displayerror(retCode, extErr);
return
end
disp('The temporary software key has been succesfully installed.');
end
function downloaddemosoftwarekey(libName)
% Download and install a demo software key on this computer
% Possible values for dcdownloaddemosoftwarekey's model parameter
SWKEY_MODEL_DEFAULT = -1;
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;
% First call the DinkeyChange API to get the machine ID
[retCode, machineId, extErr] = dcgetmachineid(libName);
% Check the return value
if (retCode ~= 0)
displayerror(retCode, extErr);
return
end
% Then call the API again to install the software key
[retCode, extErr] = dcdownloaddemosoftwarekey(libName, machineId, '!!!! REPLACE THIS WITH THE PRODUCT CODE OF THE KEY', SWKEY_MODEL_DEFAULT);
% Check the return value
if (retCode ~= 0)
displayerror(retCode, extErr);
return
end
disp('The demo software key has been succesfully installed.');
end
% An example of error reporting
% Displays descriptions for some common error codes
function displayerror(retCode, extErr)
switch retCode
case 401
disp('Error! No dongles detected that meet the search criteria.');
case 409
disp('Error! The dongle detected has not been programmed by DinkeyAdd.');
case 754
disp('Error! The specified output file could not be written to.');
case 758
disp('Error! Cannot open the file specified.');
case 759
disp('Error! The file specified is not a valid update code file.');
case 762
disp('Error! The update code contains invalid characters.');
case 763
disp('Error! Invalid update code.');
case 764
disp('Error! The update code was entered incorrectly, or the update code file is corrupt.');
case 765
disp('Error! The update code does not match any dongle attached to your computer.');
case 766
disp('Error! The update number for this update code is too high. If you have more than one update code, ensure that you apply them in the correct order.');
case 767
disp('Error! You have already entered this update code.');
case 1905
disp('Error! There is no temporary software key available for download.');
case 1907
disp('Error! The temporary software key has expired. Cannot download it.');
case 1910
disp('Error! The temporary software key has already been downloaded.');
otherwise
str = sprintf('An error occurred checking the dongle. Error: %d, Extended Error: %d', retCode, extErr);
disp(str);
end
end

View File

@@ -0,0 +1,343 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Using Dinkey Pro/FD with MATLAB</title>
<style>
body {
color: black;
font-family: Verdana, Arial, Helvetica, sans-serif;
font-size: 13px;
margin: 25px auto;
max-width: 800px;
}
p, ul, ol, table {
margin-top: 0;
margin-bottom: 15px;
}
ul.contents a {
text-decoration: none;
}
h1,h2,h3,h4,h5,h6 {
margin-top: 25px;
margin-bottom: 15px;
}
h2 {
border-top: 1px solid gray;
}
table {
margin-left: auto;
margin-right: auto;
border-collapse: collapse;
}
th, td {
border: 1px solid black;
padding: 0.5em;
text-align: left;
}
.ui_element
{ /* Use for things like program options and menu items */
color: #008000;
font-style: italic;
}
.filepath
{ /* Use for paths and filenames */
font-family: monospace;
font-size: 13px;
font-weight: bold;
}
.manual
{ /* Use when referring to user manual sections/chapters */
font-style: italic;
}
.alert
{
border: 1px solid black;
padding: 15px 15px 15px 58px;
font-weight: bold;
background-repeat: no-repeat;
background-position: 5px 15px;
margin-bottom: 15px;
}
.important
{
background-color: #FFFDD0;
background-image: url('data:image/png;base64,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');
}
.information
{
background-color: #EBF8FF;
background-image: url('data:image/png;base64,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');
}
.alert > p:last-child, .alert > ul:last-child, .alert > ol:last-child
{
/* Cancel double space at bottom of alert caused by above rule */
margin-bottom: 0;
}
.important .filepath, .information .filepath {
/* Make filepaths stand out in sections that are already bold */
font-weight: normal;
}
div.col_wrapper
{
clear: both;
overflow: hidden;
}
div.two_col
{
width: 50%;
float: left;
}
code {
color: gray;
white-space: nowrap;
}
pre {
padding: 15px;
background-color: #EEEEEE;
}
pre > code { /* Block level code snippets */
white-space: pre; /* Override nowrap used for inline code */
color: inherit;
}
code .comment
{
color: green;
}
code .keyword
{
font-weight: bold;
color: blue;
}
code .string
{
color: #A00000;
}
code .constant
{
font-weight: bold;
}
</style>
</head>
<body>
<h1>Using Dinkey Pro/FD with MATLAB</h1>
<div class="alert information">
<p>
The Shell protection method supports Windows executables produced by the MATLAB Compiler.
</p>
<p>
API protection checks in MATLAB are implemented using the M-file <span class="filepath">ddprotcheck.p</span> to communicate with the dongle via the appropriate shared library
(<span class="filepath">dpwin32.dll</span> on 32-bit Windows, <span class="filepath">dplin64.so</span> on 64-bit Linux, etc.).
You should lock these shared libraries with the API method using DinkeyAdd as described in the user manual, and distribute the locked libraries with your software.
</p>
</div>
<p>
If you are not already familiar with calling shared libraries from MATLAB code,
it is strongly recommended that you read the MATLAB documentation on this topic.
Depending on your version of MATLAB, you may need to install a C compiler and configure MATLAB to use it with the command <code>mex -setup</code>.
Again, refer to the MATLAB documentation for more information.
</p>
<p>
See <span class="manual">Modifying Your Code</span> in the user manual for information on using the API.
Below is an overview of how the <code>ddprotcheck</code> function is used in MATLAB.
</p>
<pre><code>ddprotcheck Call the Dinkey Pro/FD API.
[RETCODE,DRIS] = ddprotcheck(LIBNAME,DRIS) calls the API via the
external library LIBNAME. DRIS is a struct used to pass inputs to the
API and receive outputs. RETCODE is the return code of the API call.
[RETCODE,DRIS] = ddprotcheck(LIBNAME,DRIS,@CRYPTFUNCTION) additionally
provides an extra layer of security. The function CRYPTFUNCTION
is used to encrypt the DRIS before it is passed between MATLAB and the
external library.</code></pre>
<p>
In MATLAB, the <code>DRIS</code> is a MATLAB structure with some slight differences to the <code>DRIS</code>
documented in <span class="manual">Structures &gt; DRIS Structure</span> in the user manual.
These differences are:
</p>
<ul>
<li>
The fields <code>header</code> and <code>size</code> are set automatically by <span class="filepath">ddprotcheck.p</span>.
You do not need to set these fields in your code.
</li>
<li>
The <code>seed1</code> and <code>seed2</code> fields must be 1-by-4 vectors of type <code>uint8</code>, not integers.
</li>
<li>
<code>rw_data_ptr</code> is replaced by <code>rw_data</code>.
This field is the actual data read from/to be written to the dongle (rather than a pointer to it).
It should be a 1-by-N vector of type <code>uint8</code>.
</li>
<li>
When using the functions <code>WRITE_DATA_AREA</code>, <code>ENCRYPT_USER_DATA</code> and <code>DECRYPT_USER_DATA</code>,
<code>rw_length</code> is automatically set to be the length of the vector <code>rw_data</code>.
</li>
<li>
The fields <code>var_a</code> to <code>var_h</code> are replaced by <code>alg_vars</code>.
<code>alg_vars</code> must be a 1-by-N vector. The first 8 elements will be used for <code>var_a</code> to <code>var_h</code>.
If <code>alg_vars</code> has fewer than 8 elements, it will be padded with zeros.
</li>
</ul>
<p>
<code>DRIS</code> fields are automatically converted to the data types specified in <span class="manual">Structures &gt; DRIS Structure</span>.
When casting, MATLAB truncates values that cannot fit into a variable of the new data type.
This can lead to loss of data.
</p>
<p>
Indices for the secure data area of Plus and Net dongles start at <strong>zero</strong>.
To read the first ten bytes for example, set <code>rw_length = 10</code> and <code>rw_offset = 0</code>.
</p>
<p>
In the user manual, possible values for the <code>function</code> and <code>flags</code> fields are referred to by the
symbolic names used in other programming languages. Their literal values are provided here for your reference:
</p>
<div class="col_wrapper">
<div class="two_col">
<table>
<tr>
<th>Function</th><th>Value</th>
</tr>
<tr>
<td>PROTECTION_CHECK</td><td>1</td>
</tr>
<tr>
<td>EXECUTE_ALGORITHM</td><td>2</td>
</tr>
<tr>
<td>WRITE_DATA_AREA</td><td>3</td>
</tr>
<tr>
<td>READ_DATA_AREA</td><td>4</td>
</tr>
<tr>
<td>ENCRYPT_USER_DATA</td><td>5</td>
</tr>
<tr>
<td>DECRYPT_USER_DATA</td><td>6</td>
</tr>
<tr>
<td>FAST_PRESENCE_CHECK</td><td>7</td>
</tr>
<tr>
<td>STOP_NET_USER</td><td>8</td>
</tr>
</table>
</div>
<div class="two_col">
<table>
<tr>
<th>Flag</th><th>Value</th>
</tr>
<tr>
<td>DEC_ONE_EXEC</td><td>1</td>
</tr>
<tr>
<td>DEC_MANY_EXECS</td><td>2</td>
</tr>
<tr>
<td>START_NET_USER</td><td>4</td>
</tr>
<tr>
<td>USE_FUNCTION_ARGUMENT</td><td>16</td>
</tr>
<tr>
<td>CHECK_LOCAL_FIRST</td><td>32</td>
</tr>
<tr>
<td>CHECK_NETWORK_FIRST</td><td>64</td>
</tr>
<tr>
<td>USE_ALT_LICENCE_NAME</td><td>128</td>
</tr>
<tr>
<td>DONT_SET_MAXDAYS_EXPIRY</td><td>256</td>
</tr>
<tr>
<td>MATCH_DONGLE_NUMBER</td><td>512</td>
</tr>
<tr>
<td>DONT_RETURN_FD_DRIVE</td><td>1024</td>
</tr>
</table>
</div>
</div>
<div class="alert important">
<p>
Before you distribute your application, you must protect it from modification.
In general, it is best to use the MATLAB Compiler to create a standalone application that can be run outside of MATLAB.
It is also possible to convert your source files to P-code, which protects the code from modification,
but still allows it to be run inside the MATLAB environment.
However, MathWorks do not recommend P-coding files to protect your intellectual property,
as P-code files are obfuscated, not encrypted.
See the MATLAB documentation for more information.
</p>
</div>
<h2>MATLAB Example Files</h2>
<ul>
<li><span class="filepath">ddprotcheck.p</span> - a P-file that provides a MATLAB interface to the Dinkey Pro/FD API.</li>
<li><span class="filepath">dpsample.m</span> - various examples of using <span class="filepath">ddprotcheck.p</span>.</li>
<li><span class="filepath">dinkeyprowin32proto.p</span> - a prototype P-file that defines the signatures of the API functions for 32-bit MATLAB on Windows.</li>
<li><span class="filepath">dinkeypro32proto.p</span> - a prototype P-file that defines the signatures of the API functions for 32-bit MATLAB on all other supported platforms.</li>
<li><span class="filepath">dinkeypro64proto.p</span> - a prototype P-file that defines the signatures of the API functions for 64-bit MATLAB on all supported platforms.</li>
<li><span class="filepath">dp64_thunk.dll</span> - a compatibility layer required by 64-bit MATLAB to use <span class="filepath">dpwin64.dll</span>.</li>
<li><span class="filepath">dp64_thunk.dylib</span> - a compatibility layer required by 64-bit MATLAB to use <span class="filepath">dpmac64.dylib</span>.</li>
<li><span class="filepath">dp64_thunk.so</span> - a compatibility layer required by 64-bit MATLAB to use <span class="filepath">dplin64.so</span>.</li>
</ul>
<p>
<span class="filepath">ddprotcheck.p</span> and the appropriate prototype P-file(s) should be used in your own project.
If you are using 64-bit MATLAB, you should also include the appropriate thunk file(s) for the platform(s) that you support.
</p>
<h2>Supported Versions</h2>
<p>
The MATLAB sample code provided with the Dinkey Pro/FD SDK was written using MATLAB 7 (R14) for Windows,
and tested using MATLAB 7 on 32-bit Windows and MATLAB R2013a on 64-bit Windows.
All newer versions should be backwards compatible. The sample code may also work with older versions,
but no guarantees can be made, and support for older versions is likely to be very limited.
</p>
<p>
<span class="filepath">dp64_thunk.dylib</span> and <span class="filepath">dp64_thunk.so</span> may not be compatible with all versions of MATLAB
on all versions of macOS and/or all Linux distributions. If you have problems calling our API on 64-bit macOS or 64-bit Linux,
please contact us with full details of the platform and MATLAB version that you are using.
</p>
<h2>Try It Yourself</h2>
<div class="alert important">
<p>
The sample code is designed to teach you how to use the Dinkey Pro/FD API in MATLAB 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 <span class="manual">Increasing Your Protection</span> in the user manual for many suggestions on how to
make the best use of the API features.
</p>
</div>
<p>
<span class="filepath">dpsample.m</span> gives simple examples of performing a protection check,
as well as using various other features of Dinkey Pro/FD.
To run <span class="filepath">dpsample.m</span> you will first need to use DinkeyAdd to produce a locked copy of the shared library for your platform,
and program a dongle (if you are using Plus or Net dongles).
Place the locked library in the same folder as the example files and change MATLAB's current directory to this folder.
Browse the examples in <span class="filepath">dpsample.m</span> to see how different features can be used.
All the examples follow the same basic pattern:
</p>
<ol>
<li>Set up the <code>DRIS</code> structure with the relevant information.</li>
<li>Call the API.</li>
<li>Use the information returned in the <code>DRIS</code>.</li>
</ol>
<p>
Uncomment the function calls at the top of <span class="filepath">dpsample.m</span>
to enable the examples of different features, then enter <code>dpsample</code> in the Command Window to run the examples.
</p>
<p>
<span class="filepath">dpsample.m</span> also demonstrates loading and unloading the appropriate shared library for your platform.
</p>
<p>
Parts of the sample code marked with <code>!!!!</code> 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.
</p>
</body>
</html>

View File

@@ -0,0 +1,502 @@
function dpsample
%DPSAMPLE Example use of the Dinkey Pro/FD API in MATLAB.
% Copyright 2015 Microcosm Ltd.
% Load the correct library for this platform
% !!!! If you rename the libraries as recommended in the user manual,
% !!!! you need to modify the lines below to use the new names.
switch computer()
case 'PCWIN64' % 64-bit Windows
loadlibrary('dpwin64.dll', @dinkeypro64proto, 'alias', 'dinkeypro');
case 'PCWIN' % 32-bit Windows
loadlibrary('dpwin32.dll', @dinkeyprowin32proto, 'alias', 'dinkeypro');
case 'GLNXA64' % 64-bit Linux
loadlibrary('dplin64.so', @dinkeypro64proto, 'alias', 'dinkeypro');
case 'GLNX86' % 32-bit Linux
loadlibrary('dplin32.so', @dinkeypro32proto, 'alias', 'dinkeypro');
case 'MACI64' % 64-bit Mac OS X
loadlibrary('dpmac64.dylib', @dinkeypro64proto, 'alias', 'dinkeypro');
case 'MAC' % 32-bit Mac OS X
loadlibrary('dpmac32.dylib', @dinkeypro32proto, 'alias', 'dinkeypro');
otherwise
disp('Error! Platform not supported!');
return
end
% Each of the functions below demonstrates different API functionality.
% Uncomment the appropriate functions to execute the examples.
% See the comments in each function for more details about the features
% that they demonstrate.
protcheck('dinkeypro');
%protcheckwithalg('dinkeypro');
%writedataarea('dinkeypro');
%readdataarea('dinkeypro');
%encryptuserdata('dinkeypro');
%protcheckenc('dinkeypro');
%writedataareaenc('dinkeypro');
%readdataareaenc('dinkeypro');
% Unload the library
unloadlibrary('dinkeypro');
end
function protcheck(libName)
% An example of a basic protection check
PROTECTION_CHECK = 1;
DEC_ONE_EXEC = 1;
START_NET_USER = 4;
% Initialise the DRIS
dris.function = PROTECTION_CHECK;
dris.flags = bitor(DEC_ONE_EXEC, START_NET_USER);
% Call the API
[retCode, dris] = ddprotcheck(libName, dris);
% Check the return value
if (retCode ~= 0)
displayerror(retCode, dris.ext_err);
return
end
% ...
% You can check other values from the DRIS in other parts of your
% program to improve security. For example:
% Check the SDSN
% !!!! "10101" is the SDSN used by the demo SDK and demo dongles
% !!!! If not using a demo, replace "10101" with your own SDSN here
if (dris.sdsn ~= 10101)
disp('Incorrect SDSN! Have you replaced "10101" with your SDSN in the sample code?');
return
end
% Check the product code
% !!!! Replace "DEMO" with the product code you specify when adding
% protection with DinkeyAdd
if (~strcmp(dris.prodcode, 'DEMO'))
disp('Incorrect product code! Have you replaced "DEMO" with your product code in the sample code?');
return
end
disp('Protection check successful');
end
function protcheckwithalg(libName)
% 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.
EXECUTE_ALGORITHM = 2;
% Initialise the DRIS
dris.function = EXECUTE_ALGORITHM;
dris.alg_vars = [1 2 3 4 5 6 7 8]; % The input variables to use in the algorithm
dris.alg_number = 1; % The algorithm to execute. Lite dongles ignore this field, as they contain only 1 algorithm
% Call the API
[retCode, dris] = ddprotcheck(libName, dris);
% Check the return value
if (retCode ~= 0)
displayerror(retCode, dris.ext_err);
return
end
% Check the algorithm result in another part of your program to improve
% security. !!!! Ensure the myalgorithm() function matches the
% algorithm that was executed by the protection check!
if (dris.alg_answer ~= myalgorithm(dris.alg_vars))
disp('Error! The algorithm result was not as expected.');
return
end
disp('Protection check with algorithm successful');
end
function writedataarea(libName)
% 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!
WRITE_DATA_AREA = 3;
% Initialise the DRIS
dris.function = WRITE_DATA_AREA;
dris.rw_data = 'Hello, World!'; % Data to write
dris.rw_offset = 0; % Index to start writing at. Note indices start at zero!
% Call the API
[retCode, dris] = ddprotcheck(libName, dris);
% Check the return value
if (retCode ~= 0)
displayerror(retCode, dris.ext_err);
return
end
disp('Writing data successful');
end
function readdataarea(libName)
% 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!
READ_DATA_AREA = 4;
% Initialise the DRIS
dris.function = READ_DATA_AREA;
dris.rw_offset = 0; % Index to start reading at. Note indices start at zero!
dris.rw_length = 13; % How many bytes to read
% Call the API
[retCode, dris] = ddprotcheck(libName, dris);
% Check the return value
if (retCode ~= 0)
displayerror(retCode, dris.ext_err);
return
end
disp(['Reading data successful: ' char(dris.rw_data)]);
end
function encryptuserdata(libName)
% An example of protection checks that encrypt/decrypt your data.
% This feature is not supported by Lite dongles.
ENCRYPT_USER_DATA = 5;
DECRYPT_USER_DATA = 6;
originalData = uint8(255 * rand(1, 10));
% Initialise the DRIS
dris.function = ENCRYPT_USER_DATA;
dris.rw_data = originalData;
dris.data_crypt_key_num = 1;
% Call the API
[retCode, dris] = ddprotcheck(libName, dris);
% Check the return value
if (retCode ~= 0)
displayerror(retCode, dris.ext_err);
return
end
encryptedData = dris.rw_data;
% Initialise the DRIS
dris.function = DECRYPT_USER_DATA;
% Call the API
[retCode, dris] = ddprotcheck(libName, dris);
% Check the return value
if (retCode ~= 0)
displayerror(retCode, dris.ext_err);
return
end
decryptedData = dris.rw_data;
disp('Data encryption successful');
disp('Original data:');
disp(originalData);
disp('Encrypted data:');
disp(encryptedData);
disp('Decrypted data:');
disp(decryptedData);
end
function protcheckenc(libName)
% An example of a protection check that uses DRIS encryption for extra
% security.
PROTECTION_CHECK = 1;
% Initialise the DRIS
dris.function = PROTECTION_CHECK;
dris.seed1 = uint8(255 * rand(1, 4)); % 4 random bytes
dris.seed2 = uint8(255 * rand(1, 4)); % 4 random bytes
% Call the API
[retCode, dris] = ddprotcheck(libName, dris, @cryptdris);
% Check the return value
if (retCode ~= 0)
displayerror(retCode, dris.ext_err);
return
end
% You can check other values from the DRIS in other parts of your
% program to improve security. For example:
% Check the SDSN
% !!!! "10101" is the SDSN used by the demo SDK and demo dongles
% !!!! If not using a demo, replace "10101" with your own SDSN here
if (dris.sdsn ~= 10101)
disp('Incorrect SDSN! Have you replaced "10101" with your SDSN in the sample code?');
return
end
% Check the product code
% !!!! Replace "DEMO" with the product code you specify when adding
% protection with DinkeyAdd
if (~strcmp(dris.prodcode, 'DEMO'))
disp('Incorrect product code! Have you replaced "DEMO" with your product code in the sample code?');
return
end
disp('Protection check successful');
end
function writedataareaenc(libName)
% 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 function also uses DRIS encryption and
% encrypts the rw_data field for extra security. You must select these
% options in DinkeyAdd for this function to work correctly!
WRITE_DATA_AREA = 3;
% Initialise the DRIS
dris.function = WRITE_DATA_AREA;
dris.rw_offset = 0;
dris.seed1 = uint8(255 * rand(1, 4)); % 4 random bytes
dris.seed2 = uint8(255 * rand(1, 4)); % 4 random bytes
dris.alg_vars = randint(1 , 8, double([intmin intmax])); % 8 random signed 32-bit integers
rwAlgAnswer = myrwalgorithm(dris.alg_vars);
% Encrypt the data to be written to the dongle
dataToWrite = uint8('ABCDEFGHIJKLMNOPQRSTUVWXYZ');
dris.rw_data = cryptapidata(dataToWrite, dris.seed1, dris.seed2, rwAlgAnswer);
% Call the API
[retCode, dris] = ddprotcheck(libName, dris, @cryptdris);
% Check the return value
if (retCode ~= 0)
displayerror(retCode, dris.ext_err);
return
end
disp('Writing data successful');
end
function readdataareaenc(libName)
% 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 function also uses DRIS encryption and
% encrypts the rw_data field for extra security. You must select these
% options in DinkeyAdd for this function to work correctly!
READ_DATA_AREA = 4;
% Initialise the DRIS
dris.function = READ_DATA_AREA;
dris.rw_offset = 0;
dris.rw_length = 10;
dris.seed1 = uint8(255 * rand(1, 4)); % 4 random bytes
dris.seed2 = uint8(255 * rand(1, 4)); % 4 random bytes
dris.alg_vars = randint(1 , 8, double([intmin intmax])); % 8 random signed 32-bit integers
% Call the API
[retCode, dris] = ddprotcheck(libName, dris, @cryptdris);
% Check the return value
if (retCode ~= 0)
displayerror(retCode, dris.ext_err);
return
end
% Decrypt the data read from the dongle
rwAlgAnswer = myrwalgorithm(dris.alg_vars);
dataRead = cryptapidata(dris.rw_data, dris.seed1, dris.seed2, rwAlgAnswer);
disp(['Reading data successful: ' char(dataRead)]);
end
function ret = myalgorithm(algVars)
% !!!! This function 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.
ret = algVars(1) - algVars(2) - algVars(3) - algVars(4) - algVars(5) - algVars(6) - algVars(7);
end
function ret = myrwalgorithm(algVars)
% !!!! This function must match the R/W algorithm stored in the dongle for
% writedataareaenc() and readdataareaenc() to work correctly.
ret = algVars(1) - algVars(2) - algVars(3) - algVars(4) - algVars(5) - algVars(6);
end
function dris = cryptdris(dris)
% This function can be used to encrypt/decrypt the DRIS. If using DRIS
% encryption in your own program, copy this function exactly. Modify only
% the parts indicated by !!!!
% !!!! Overwrite the encryption parameters with those chosen in
% DinkeyAdd. This example uses 123, 212, 97.
DRIS_ENCRYPTION_PARAMETERS = [123 212 97];
S = 0:255;
bigseed = zeros(256, 1);
for i = 1:8:256
for j = 0:3
bigseed(i+j) = dris(9+j);
bigseed(i+j+4) = dris(13+j);
end
end
j = 0;
for i = 0:255
j = bitand((j + S(i+1) + bigseed(i+1) + DRIS_ENCRYPTION_PARAMETERS(1)), 255);
temp = S(i+1);
S(i+1) = S(j+1);
S(j+1) = temp;
end
i = 0;
j = 0;
for k = 17:length(dris)
i = bitand((i + 1), 255);
j = bitand((j + S(i+1) + DRIS_ENCRYPTION_PARAMETERS(2)), 255);
temp = S(i+1);
S(i+1) = S(j+1);
S(j+1) = temp;
t = bitand((S(i+1) + S(j+1) + DRIS_ENCRYPTION_PARAMETERS(3)), 255);
dris(k) = bitxor(dris(k), S(t+1));
end
end
function data = cryptapidata(data, seed1, seed2, algAnswer)
% This function is used to encrypt/decrypt data passed in the rw_data DRIS
% field (applies to Plus and Net dongles only). If using this feature in
% your own program, copy this function exactly. Modify only the parts
% indicated by !!!!
% !!!! If you are using constant encryption parameters, define them
% like this:
% DATA_ENCRYPTION_PARAMETERS = [X Y Z];
% !!!! If you are using the R/W algorithm, derive the encryption
% parameters from the algorithm result like this:
% 1. Convert algAnswer to uint32 without changing underlying data
if (algAnswer < 0)
algAnswer = uint32(double(algAnswer) + hex2dec('FFFFFFFF') + 1);
else
algAnswer = uint32(algAnswer);
end
% 2. Now algAnswer is a uint32 we can use bitwise operations to derive
% the encryption parameters
DATA_ENCRYPTION_PARAMETERS = [bitand(algAnswer, 255), bitand(bitshift(algAnswer,-8), 255), bitand(bitshift(algAnswer,-16), 255)];
% The rest of the function should not be modified!
S = 0:255;
bigseed = zeros(256, 1);
for i = 1:8:256
for j = 0:3
bigseed(i+j) = seed1(j+1);
bigseed(i+j+4) = seed2(j+1);
end
end
j = 0;
for i = 0:255
j = bitand((j + S(i+1) + bigseed(i+1) + DATA_ENCRYPTION_PARAMETERS(1)), 255);
temp = S(i+1);
S(i+1) = S(j+1);
S(j+1) = temp;
end
i = 0;
j = 0;
for k = 1:length(data)
i = bitand((i + 1), 255);
j = bitand((j + S(i+1) + DATA_ENCRYPTION_PARAMETERS(2)), 255);
temp = S(i+1);
S(i+1) = S(j+1);
S(j+1) = temp;
t = bitand((S(i+1) + S(j+1) + DATA_ENCRYPTION_PARAMETERS(3)), 255);
data(k) = bitxor(data(k), S(t+1));
end
end
% 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!
function displayerror(retCode, extErr)
switch retCode
case 401
disp('Error! No dongles detected!');
case 403
disp('Error! The dongle is a different type to the one specified in DinkeyAdd.');
case 404
disp('Error! The dongle is a different model to those specified in DinkeyAdd.');
case 409
disp('Error! The dongle has not been programmed by DinkeyAdd.');
case 410
disp('Error! The dongle has a different product code to the one specified in DinkeyAdd.');
case 411
disp('Error! This program''s licence was not found in the dongle.');
case 413
disp('Error! This program has not been locked by DinkeyAdd. For guidance please read the DinkeyAdd chapter of the user manual.');
case 417
disp('Error! One or more of the parameters set in the DRIS is incorrect.');
disp('Check that you have defined the necessary input fields in the DRIS struct.');
disp('Also check if you are encrypting the DRIS in your code but did not specify DRIS encryption in DinkeyAdd - or vice versa.');
case 423
disp('Error! The number of network users has been exceeded.');
case 435
disp('Error! DinkeyServer has not been detected on the network.');
case 922
disp('Error! The Software Key has expired.');
otherwise
str = sprintf('An error occurred checking the dongle. Error: %d, Extended Error: %d', retCode, extErr);
disp(str);
end
end