Files
2023-02-23 13:55:39 +00:00

233 lines
6.8 KiB
ObjectPascal

(*
This example shows how to generate a machine modifier at run time
while using the TOgSerialNumber component. This means the program
will run only on the machine being used to run the application.
If the program is being run the first time (as determined by the
existance of an INI file, a dialog box is displayed showing the
modifier value along with two entry fields: one for the serial
number, the other for the release code. The user enters the
values that you give him for these two items. The values are
stored in the INI file and the program is allowed to run.
The release code you give the user can be generated by the CODEGEN
example program. Be sure to select the same type component, the
key used to compile the application (the one returned in the
OnGetKey event), and enter the machine modifier the user gives
you - not the one automatically generated when you click the
MachineModifier radio button. Also, if used, make sure the
Expires date is the same.
*)
unit Exdmodu1;
interface
uses
SysUtils,Classes,Controls,
Forms, Dialogs, StdCtrls, Buttons,
OgUtil,OnGuard,IniFiles;
const
CKey : TKey = ($E5,$8F,$84,$D6,$92,$C9,$A4,$D8,
$1A,$FA,$6F,$8D,$AB,$FC,$DF,$B4);
type
{ TfrmMain }
TfrmMain = class(TForm)
CloseBtn: TBitBtn;
Label1: TLabel;
Memo1: TLabel;
OgSerialNumberCode1: TOgSerialNumberCode;
procedure FormActivate(Sender: TObject);
procedure OgSerialNumberCode1GetKey(Sender: TObject; var Key: TKey);
procedure OgSerialNumberCode1GetCode(Sender: TObject; var Code: TCode);
procedure OgSerialNumberCode1Checked(Sender: TObject; Status: TCodeStatus);
procedure OgSerialNumberCode1GetModifier(Sender: TObject; var Value: Longint);
private
{ Private declarations }
FExpired : Boolean;
public
{ Public declarations }
TheDir : string;
IniSNVal : longint;
IniFile : TIniFile;
function GetSNData(var S : string) : integer;
end;
var
frmMain: TfrmMain;
implementation
{$R *.lfm}
uses
Exdmodu2;
procedure TfrmMain.OgSerialNumberCode1GetKey(Sender: TObject; var Key: TKey);
begin
Key := CKey;
end;
procedure TfrmMain.FormActivate(Sender: TObject);
begin
if FExpired then Application.Terminate;
end;
procedure TfrmMain.OgSerialNumberCode1GetModifier(Sender: TObject;
var Value: Longint);
begin
{Generate the value unique to this machine}
Value := GenerateMachineModifierPrim;
end;
procedure TfrmMain.OgSerialNumberCode1GetCode(Sender: TObject; var Code: TCode);
var
S1 : string;
{%H-}L : integer;
begin
{force the INI file to be in the same directory as the application}
TheDir := ExtractFilePath(ParamStr(0));
{
L := Length(TheDir);
if (L > 3) and (TheDir[L] <> '\') then
TheDir := TheDir + '\';
}
(*
this check helps prevent an empty INI file. For the combination of
this component and using the MachineModifier, an empty or
incomplete INI file can cause problems, i.e., if something goes wrong
during the initial input of the SN and ReleaseCode, the program could
not be run again without deleting the INI file. In a "real world"
application, you would probably be hiding these values some how and
would either have to tell the user where to delete things or have a
utility program to do so.
*)
if not (FileExists(TheDir + 'snwmod.ini')) then
Exit;
{open Ini File}
IniFile := TIniFile.Create(TheDir + 'snwmod.ini');
try
{try to read release code}
S1 := IniFile.ReadString('Codes', 'SNCode', '');
(*
set a global variable to the value of the serial number.
Since, by design, the TOgSerialNumber component does not
confirm that the SN and ReleaseCode retrieved from the INI
file are compatible, this value will be used later to
see if the user has attempted to change the contents of
the INI file
*)
IniSNVal := IniFile.ReadInteger('Codes', 'SN', 0);
{convert retrieved string to a code}
HexToBuffer(S1, Code, SizeOf(Code));
finally
IniFile.Free;
end;
end;
function TfrmMain.GetSNData(var S : string) : integer;
{method used to ask for user input of serial number and release code}
var
TC : TCode;
SNC : string;
L : longint = 0;
Key : TKey;
begin
Application.CreateForm(TSNEntryDlg, SNEntryDlg);
try
{Display new SN and ask for release code}
SNEntryDlg.SNText.Text := '';
SNEntryDlg.CodeText.Text := '';
Result := SNEntryDlg.ShowModal;
if (SNEntryDlg.CodeText.Text = '') or
(SNEntryDlg.SNText.Text = '') then
Result := mrCancel;
if (Result = mrCancel) then begin
S := 'Invalid Code or Cancelled';
Exit;
end;
{Check that Release Code was entered correctly}
Key := CKey;
OgSerialNumberCode1.Modifier := SNEntryDlg.ModString.Text;
HexToBuffer(SNEntryDlg.ModString.Text, L, SizeOf(L));
HexToBuffer(SNEntryDlg.CodeText.Text, TC{%H-}, SizeOf(TCode));
ApplyModifierToKeyPrim(L, Key, SizeOf(TKey));
if not (IsSerialNumberCodeValid(Key, TC)) then begin
S := 'Release code not entered correctly';
Result := mrCancel;
end else begin
IniFile := TIniFile.Create(TheDir + 'snwmod.ini');
try
{write SN to IniFile}
IniSNVal := StrToInt(SNEntryDlg.SNText.Text);
SNC := SNEntryDlg.CodeText.Text;
IniFile.WriteInteger('Codes', 'SN', IniSNVal);
IniFile.WriteString('Codes', 'SNCode', SNC);
finally
IniFile.Free;
end;
end;
finally
SNEntryDlg.Free;
end;
end;
procedure TfrmMain.OgSerialNumberCode1Checked(Sender: TObject; Status: TCodeStatus);
var
LI : longint;
S : string;
begin
FExpired := false;
//Status := ogValidCode; // just to check the form
case Status of
ogValidCode : begin
{check if retrieved Serial Number matches Code}
LI := OgSerialNumberCode1.GetValue;
if (LI <> IniSNVal) then begin
S := 'The serial number has been changed';
end else begin
Label1.Caption := 'Serial #: ' + IntToStr(IniSNVal);
Exit;
end;
end;
ogInvalidCode : begin
{if INI file doesn't exist, presume this is first run}
if not (FileExists(TheDir + 'snwmod.ini')) then begin
if not (GetSNData(S) = mrCancel) then begin
{Check the SN/ReleaseCode}
OgSerialNumberCode1.CheckCode(True);
{must Exit since line above began a recursive call}
Exit;
end;
end else
S := 'Invalid Code';
end;
ogCodeExpired : S := 'Evaluation period expired';
end;
ShowMessage(S);
FExpired := true;
end;
end.