341 lines
13 KiB
ObjectPascal
341 lines
13 KiB
ObjectPascal
unit Change;
|
|
|
|
interface
|
|
|
|
uses
|
|
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
|
|
Dialogs, StdCtrls;
|
|
|
|
type
|
|
TChangeForm = class(TForm)
|
|
DiagInfo: TButton;
|
|
Label1: TLabel;
|
|
DiagFilename: TEdit;
|
|
WriteDiags: TButton;
|
|
UpdateCodeString: TEdit;
|
|
Label2: TLabel;
|
|
DoUpdateCodeString: TButton;
|
|
UpdateCodeFile: TEdit;
|
|
Label3: TLabel;
|
|
DoUpdateCodeFile: TButton;
|
|
RestoreFDLite: TButton;
|
|
GetMachineID: TButton;
|
|
DownloadTempSWKey: TButton;
|
|
ShowMachineID: TEdit;
|
|
DownloadDemoSWKey: TButton;
|
|
SwkeyProdCode: TEdit;
|
|
Label4: TLabel;
|
|
procedure DiagInfoClick(Sender: TObject);
|
|
procedure WriteDiagsClick(Sender: TObject);
|
|
procedure DoUpdateCodeStringClick(Sender: TObject);
|
|
procedure DoUpdateCodeFileClick(Sender: TObject);
|
|
procedure DoRestoreFDLiteClick(Sender: TObject);
|
|
procedure DoGetMachineIDClick(Sender: TObject);
|
|
procedure DoDownloadTempSWKeyClick(Sender: TObject);
|
|
procedure DoDownloadDemoSWKeyClick(Sender: TObject);
|
|
private
|
|
{ Private declarations }
|
|
public
|
|
{ Public declarations }
|
|
end;
|
|
|
|
var
|
|
ChangeForm: TChangeForm;
|
|
|
|
{ constants }
|
|
const MAX_USB_DEVICES = 128; { maximum number of USB devices that can be attached to the system at one time }
|
|
const MAX_PRODCODE_LEN = 8; { maximum length of a Product Code }
|
|
|
|
{ mask values }
|
|
const TYPE_MASK_PRO = 1;
|
|
const TYPE_MASK_FD = 2;
|
|
const TYPE_MASK_ALL = TYPE_MASK_PRO or TYPE_MASK_FD;
|
|
|
|
const MODEL_MASK_LITE = 1;
|
|
const MODEL_MASK_PLUS = 2;
|
|
const MODEL_MASK_NET = 4;
|
|
const MODEL_MASK_ALL = MODEL_MASK_LITE or MODEL_MASK_PLUS or MODEL_MASK_NET;
|
|
const MODEL_MASK_DEFAULT = MODEL_MASK_PLUS or MODEL_MASK_NET;
|
|
|
|
{ type values for DCGetInfo (returned in the array) }
|
|
const TYPE_PRO = 1;
|
|
const TYPE_FD = 2;
|
|
|
|
{ model values for DCGetInfo (returned in the array) }
|
|
const MODEL_LITE = 1;
|
|
const MODEL_PLUS = 2;
|
|
const MODEL_NET5 = 4;
|
|
const MODEL_NETU = 7;
|
|
|
|
{ model values for DCDownloadDemoSoftwareKey }
|
|
const SWKEY_MODEL_DEFAULT = -1; { NB this assumes that the Demo Software Key Template was created with only one valid dongle model }
|
|
const SWKEY_MODEL_PRO_LITE = 0;
|
|
const SWKEY_MODEL_PRO_PLUS = 1;
|
|
const SWKEY_MODEL_PRO_NET = 2;
|
|
const SWKEY_MODEL_FD_LITE = 3;
|
|
const SWKEY_MODEL_FD_PLUS = 4;
|
|
const SWKEY_MODEL_FD_NET = 5;
|
|
|
|
{ functions exported by DinkeyChange.dll }
|
|
{$IFDEF WIN32}
|
|
function DCGetInfo(type_mask, model_mask:LongInt; prodcode_mask:PAnsiChar; array_length:LongInt; num_found:PLongInt; type_array,model_array:pointer; prodcode_array:pointer; dongle_number_array:pointer; update_number_array: pointer) : LongInt; stdcall; external 'DinkeyChange.dll';
|
|
function DCGetDiagnosticInfo(filename: PAnsiChar): LongInt; stdcall; external 'DinkeyChange.dll';
|
|
function DCDoUpdateCodeString(UpdateCodeString: PAnsiChar; confirmation_code, extended_error: PLongInt): LongInt; stdcall; external 'DinkeyChange.dll';
|
|
function DCDoUpdateCodeFromFile(filename: PAnsiChar; confirmation_code, extended_error: PLongInt): LongInt; stdcall; external 'DinkeyChange.dll';
|
|
function DCRestoreDinkeyFDLite(): LongInt; stdcall; external 'DinkeyChange.dll';
|
|
function DCGetMachineID(machineID:PLongWord; extended_error:PLongInt): LongInt; stdcall; external 'DinkeyChange.dll';
|
|
function DCDownloadTempSoftwareKey(machineID:LongWord; extended_error:PLongInt): LongInt; stdcall; external 'DinkeyChange.dll';
|
|
function DCDownloadDemoSoftwareKey(machineID:LongWord; prodcode: PAnsiChar; model: LongInt; extended_error:PLongInt): LongInt; stdcall; external 'DinkeyChange.dll';
|
|
{$ELSE}
|
|
function DCGetInfo(type_mask, model_mask:LongInt; prodcode_mask:PAnsiChar; array_length:LongInt; num_found:PLongInt; type_array,model_array:pointer; prodcode_array:pointer; dongle_number_array:pointer; update_number_array: pointer) : LongInt; stdcall; external 'DinkeyChange64.dll';
|
|
function DCGetDiagnosticInfo(filename: PAnsiChar): LongInt; stdcall; external 'DinkeyChange64.dll';
|
|
function DCDoUpdateCodeString(UpdateCodeString: PAnsiChar; confirmation_code, extended_error: PLongInt): LongInt; stdcall; external 'DinkeyChange64.dll';
|
|
function DCDoUpdateCodeFromFile(filename: PAnsiChar; confirmation_code, extended_error: PLongInt): LongInt; stdcall; external 'DinkeyChange64.dll';
|
|
function DCRestoreDinkeyFDLite(): LongInt; stdcall; external 'DinkeyChange64.dll';
|
|
function DCGetMachineID(machineID:PLongWord; extended_error:PLongInt): LongInt; stdcall; external 'DinkeyChange64.dll';
|
|
function DCDownloadTempSoftwareKey(machineID:LongWord; extended_error:PLongInt): LongInt; stdcall; external 'DinkeyChange64.dll';
|
|
function DCDownloadDemoSoftwareKey(machineID:LongWord; prodcode: PAnsiChar; model: LongInt; extended_error:PLongInt): LongInt; stdcall; external 'DinkeyChange64.dll';
|
|
{$ENDIF}
|
|
|
|
implementation
|
|
|
|
{$R *.dfm}
|
|
|
|
{ displays messages for the most common errors when updating the code.
|
|
You will want to change this for your code }
|
|
procedure DisplayError(ret_code, extended_error:integer);
|
|
var
|
|
display : string;
|
|
begin
|
|
case ret_code of
|
|
401: display := 'Error! No dongles detected that meet the search criteria.';
|
|
409: display := 'Error! The dongle detected has not been programmed by DinkeyAdd.';
|
|
758: display := 'Error! Cannot open the Update Code file specified.';
|
|
759: display := 'Error! The file specified is not a valid Update Code file.';
|
|
762..764: display := 'Error! Update Code is not in a correct format / update code file is corrupt.';
|
|
765: display := 'Error! The Update Code does not match any dongle attached to your machine.';
|
|
766: display := 'Error! The update number for this Update Code is too high. You need to first enter an update code that was previously sent to you.';
|
|
767: display := 'Error! You have already entered this Update Code.';
|
|
1905: display := 'Error! There is no Software Key available for download.';
|
|
1907: display := 'Error! The Temporary Software Key has expired. Cannot download it.';
|
|
1910: display := 'Error! The Software Key has already been downloaded.';
|
|
1921: display := 'Error! You specified the default model but there is more than one model available. You need to specify a specific dongle model.';
|
|
1922: display := 'Error! The model you requested is not available.';
|
|
1923: display := 'Error! The Demo Software Key Template has been disabled.';
|
|
1924: display := 'Error! You have run out of Demo Software Key activations. You need to order some more.';
|
|
else
|
|
display := 'An error occurred checking the dongle. Error: ' + IntToStr(ret_code) + '. Extended Error code: ' + IntToStr(extended_error);
|
|
end;
|
|
messagedlg(display, mtError, [mbok], 0);
|
|
end;
|
|
|
|
procedure TChangeForm.DiagInfoClick(Sender: TObject);
|
|
var
|
|
i : Integer;
|
|
sType, sModel, sProdCode, display : string;
|
|
ret_code, num_found : LongInt;
|
|
type_array, model_array, update_number_array: packed array[0..(MAX_USB_DEVICES-1)] of LongInt;
|
|
dongle_number_array: packed array[0..(MAX_USB_DEVICES-1)] of LongWord;
|
|
prodcode_array: packed array[0..(MAX_USB_DEVICES-1)] of packed array[0..MAX_PRODCODE_LEN] of AnsiChar;
|
|
begin
|
|
|
|
{ find dongle information for all dongle types, Plus & Net models, for all product codes
|
|
NB In practice you will probably want to set the prodcode_mask to the value of your product code }
|
|
|
|
ret_code := DCGetInfo(TYPE_MASK_ALL, MODEL_MASK_DEFAULT, nil, MAX_USB_DEVICES, @num_found, @type_array, @model_array, @prodcode_array, @dongle_number_array, @update_number_array);
|
|
|
|
{ check error code and display error if an error occurs }
|
|
if (ret_code = 401) then
|
|
begin
|
|
messagedlg('No dongles detected matching the search criteria specified', mtError, [mbok], 0);
|
|
exit;
|
|
end
|
|
else if (ret_code <> 0) then
|
|
begin
|
|
messagedlg('Error ' + IntToStr(ret_code) + ' getting dongle information', mtError, [mbok], 0);
|
|
exit;
|
|
end;
|
|
|
|
{ display info from the dongle detected }
|
|
display := '';
|
|
for i := 0 to num_found-1 do
|
|
begin
|
|
{ get type of dongle }
|
|
if (type_array[i] = TYPE_PRO) then
|
|
sType := 'Pro'
|
|
else
|
|
sType := 'FD';
|
|
|
|
{ get model of dongle }
|
|
if (model_array[i] = MODEL_LITE) then
|
|
sModel := 'Lite'
|
|
else if (model_array[i] = MODEL_PLUS) then
|
|
sModel := 'Plus'
|
|
else
|
|
sModel := 'Net';
|
|
|
|
sProdCode := String(prodcode_array[i]);
|
|
|
|
display := display + IntToStr(i+1) + '. Dinkey ' + sType + ' ' + sModel + ' with dongle number: ' + IntToStr(dongle_number_array[i]) +
|
|
', product code: ' + sProdCode + ', update number: ' + IntToStr(update_number_array[i]) + #13#10;
|
|
end;
|
|
messagedlg(display, mtInformation, [mbok], 0);
|
|
|
|
end;
|
|
|
|
{ write dongle diagnostics to file }
|
|
procedure TChangeForm.WriteDiagsClick(Sender: TObject);
|
|
var
|
|
ret_code: longInt;
|
|
diag_file : array[0..255] of AnsiChar;
|
|
|
|
begin
|
|
StrPCopy(diag_file, AnsiString(DiagFilename.Text)); { to get a null-terminated string }
|
|
ret_code := DCGetDiagnosticInfo(@diag_file);
|
|
|
|
{ check error code and display error if an error occurs }
|
|
if (ret_code = 754) then
|
|
begin
|
|
messagedlg('Could not create the diagnostic file. Please check that the path exists: ' + DiagFileName.Text, mtError, [mbok], 0);
|
|
exit;
|
|
end
|
|
else if (ret_code <> 0) then
|
|
begin
|
|
messagedlg('Error ' + IntToStr(ret_code) + 'writing diagnostic file.', mtError, [mbok], 0);
|
|
exit;
|
|
end;
|
|
|
|
{ display success }
|
|
messagedlg('Diagnostic file written successfully.', mtInformation, [mbok], 0);
|
|
end;
|
|
|
|
{ update dongle with short update code string typed-in }
|
|
procedure TChangeForm.DoUpdateCodeStringClick(Sender: TObject);
|
|
var
|
|
ret_code, confirmation_code, extended_error: LongInt;
|
|
update_code : array[0..255] of AnsiChar;
|
|
begin
|
|
StrPCopy(update_code, AnsiString(UpdateCodeString.Text)); { to get a null-terminated string }
|
|
ret_code := DCDoUpdateCodeString(@update_code, @confirmation_code, @extended_error);
|
|
|
|
if (ret_code <> 0) then
|
|
begin
|
|
DisplayError(ret_code, extended_error);
|
|
exit;
|
|
end;
|
|
|
|
messagedlg('Dongle updated successfully!' + #13#10 + 'Confirmation code is : ' + IntToHex(confirmation_code, 4), mtInformation, [mbok], 0);
|
|
end;
|
|
|
|
{ update dongle with update code in file specified }
|
|
procedure TChangeForm.DoUpdateCodeFileClick(Sender: TObject);
|
|
var
|
|
ret_code, confirmation_code, extended_error: LongInt;
|
|
update_code_file : array[0..255] of AnsiChar;
|
|
begin
|
|
StrPCopy(update_code_file, AnsiString(UpdateCodeFile.Text)); { to get a null-terminated string }
|
|
ret_code := DCDoUpdateCodeFromFile(@update_code_file, @confirmation_code, @extended_error);
|
|
|
|
if (ret_code <> 0) then
|
|
begin
|
|
DisplayError(ret_code, extended_error);
|
|
exit;
|
|
end;
|
|
|
|
messagedlg('Dongle updated successfully!' + #13#10 + 'Confirmation code is : ' + IntToHex(confirmation_code, 4), mtInformation, [mbok], 0);
|
|
end;
|
|
|
|
{ attempt to restore Dinkey FD Lite dongle }
|
|
procedure TChangeForm.DoRestoreFDLiteClick(Sender: TObject);
|
|
var
|
|
ret_code: LongInt;
|
|
begin
|
|
ret_code := DCRestoreDinkeyFDlite();
|
|
|
|
if (ret_code <> 0) then
|
|
begin
|
|
DisplayError(ret_code, 0);
|
|
exit;
|
|
end;
|
|
|
|
messagedlg('Dinkey FD Lite dongle restored successfully!', mtInformation, [mbok], 0);
|
|
end;
|
|
|
|
{ Get Machine ID (for use with Temporary Software Key) }
|
|
procedure TChangeForm.DoGetMachineIDClick(Sender: TObject);
|
|
var
|
|
ret_code, extended_error: LongInt;
|
|
machineID: LongWord;
|
|
begin
|
|
ret_code := DCGetMachineID(@machineID, @extended_error);
|
|
|
|
if (ret_code <> 0) then
|
|
begin
|
|
DisplayError(ret_code, extended_error);
|
|
exit;
|
|
end;
|
|
{don't display mesage, just display the Machine ID }
|
|
ShowMachineID.Text := IntToHex(machineID, 8);
|
|
end;
|
|
|
|
{ Download Temporary Software Key }
|
|
procedure TChangeForm.DoDownloadTempSWKeyClick(Sender: TObject);
|
|
var
|
|
ret_code, extended_error: LongInt;
|
|
machineID: LongWord;
|
|
begin
|
|
{ first get the machine ID... }
|
|
ret_code := DCGetMachineID(@machineID, @extended_error);
|
|
|
|
if (ret_code <> 0) then
|
|
begin
|
|
DisplayError(ret_code, extended_error);
|
|
exit;
|
|
end;
|
|
|
|
{ ... then try to download the temporary software key }
|
|
ret_code := DCDownloadTempSoftwareKey(machineID, @extended_error);
|
|
|
|
if (ret_code <> 0) then
|
|
begin
|
|
DisplayError(ret_code, extended_error);
|
|
exit;
|
|
end;
|
|
|
|
messagedlg('Temporary Software Key Downloaded Successfully!', mtInformation, [mbok], 0);
|
|
end;
|
|
|
|
{ Download Demo Software Key }
|
|
procedure TChangeForm.DoDownloadDemoSWKeyClick(Sender: TObject);
|
|
var
|
|
ret_code, extended_error: LongInt;
|
|
machineID: LongWord;
|
|
prodcode : array[0..9] of AnsiChar;
|
|
begin
|
|
{ first get the machine ID... }
|
|
ret_code := DCGetMachineID(@machineID, @extended_error);
|
|
|
|
if (ret_code <> 0) then
|
|
begin
|
|
DisplayError(ret_code, extended_error);
|
|
exit;
|
|
end;
|
|
|
|
{ ... then try to download the demo software key }
|
|
{ NB we are assuming only one dongle model is set in the Demo Software Template. }
|
|
{ If multiple models are set you will also need to specify the exact model }
|
|
StrPCopy(prodcode, AnsiString(SwkeyProdCode.Text)); { to get a null-terminated string }
|
|
ret_code := DCDownloadDemoSoftwareKey(machineID, @prodcode, SWKEY_MODEL_DEFAULT, @extended_error);
|
|
|
|
if (ret_code <> 0) then
|
|
begin
|
|
DisplayError(ret_code, extended_error);
|
|
exit;
|
|
end;
|
|
|
|
messagedlg('Demo Software Key Downloaded Successfully!', mtInformation, [mbok], 0);
|
|
end;
|
|
|
|
end.
|
|
|