Example 1 |
Top Previous Next |
Items In this example you will learn to Control the number of concurrent instances Brief practice with example 1a Deleting the existing registration Registering the application using Keys Synchronize the data and renew the license from the OLM Control the computer system date
In this example you will learn to: 1. Use the component in a basic protection scheme (Scheme A). 2. Control the number of concurrent instances 3. Use two different methods to start the trial period: offline and online using the basic OLM. 4. Check and automatically correct the date of your computer. 5. Remove the local registration data and from the web server (OLM). 6. Using the KeyGen utility to generate registration keys.
Versions on this example
The version (1a) is the development version which have added utility buttons to start the trial period and delete the registration data to take back the application in original condition. The version (1b) is the final version where the trial period starts automatically and utility buttons were removed.
The examples 1a and 1b shows all possible configurations for the ADVANCED_OLM, BASIC_OLM and NO_OLM, all together. Perhaps it may seem confusing to have all options at once, so, in order to clarify the code we included a separate example for each implementation: "advancedolm", "basicolm" and "noolm".
Protection scheme This example uses the scheme A
Scheme A
It is implemented as shown in the following flowchart:
Flowchart
Sources for Unit1 (Form1)
procedure TForm1.FormCreate(Sender: TObject); begin DoRegister(False); if (keydata.TooManyInstances) then begin showmessage('Too many instances'); application.Terminate; end; if not AVLock.IsLocal and (AVLockS51.activeinstances.count < 2) then begin showmessage('This application must be run first from the server.'); application.Terminate; end; end;
procedure TForm1.DoRegister(force:boolean); var F : TRegForm; begin F:=TRegForm.Create(nil); //Create the registration Form try if AVLock.IsLocal and (force or (keydata.DaysLeft < 15)) then F.ShowModal; finally FreeAndNil(F); end; if (keydata.Status <> Registered) then begin showmessage('Not Registered'); application.Terminate; end; end;
The parameter "force" into the DoRegister procedure determine its behavior:
procedure TForm1.DoRegister(force:boolean);
Also, consider the following line:
if force or (F.keydata.DaysLeft < 15) then F.ShowModal;
When you run the procedure: 1) When (force = true): the registration form is always displayed. 2) When (force = false): only shows the form if the missing days to expire are under 15. Let's see what happens under different circumstances; a) when not registered: the registration form shown because (daysleft = 0). b) the registered status is trial or temporary: - When the remaining days are greater than or equal to 15, the form not shown (daysleft >= 15). - When the remaining days are under 15, the form is shown (daysleft < 15). c) the registered status is permanent: the form is not shown because daysleft is greater than 15 (daysleft = 65535).
From FormCreate DoRegister is called with (force = false), so that the form is not displayed when not needed because the application is already registered or have much time to expiry of the period allowed, but since the [Registration Form] runs with (force = true) DoRegister (True) to force the form is always displayed regardless of registration status.
The Registration Form (RegForm)
This form, called "Registration Form" allows us to separate from the rest of the application, the functions related to AVLock SIMPLE. From here we carry out several functions, namely:
1. Get the registration status. 2. Allow the user to enter personal data and save them in OLM database and locally. 3. Start the evaluation period (trial) 4. Register the application.
Get the Registration Status
The first thing into this unit are defining two compiler directives in order to configure the application:
{$DEFINE SAN} //Options are NAS, SAN, REMOV // NAS = Network Attached Storage // SAN = Storage Area Network // REMOV = Removable Disk
{$DEFINE BASIC_OLM} //Options are BASIC_OLM, ADVANCED_OLM, NO_OLM
The method GetRegStatus() into the Regist unit allow to get the current registration status of the component. Below you can see the source code. The first thing you do is assign the properties of the component according with the defined directives. Properties have its own default values (see it in a table below). It would only be necessary to assign values that do not match the preset, in our case, for the most complete example are assigned all properties.
There we use the method GetKeyData() to read the local registration data and assign the 'keydata' record of TKeyData type. Then assigns the 'EdIcode' edit box with the Installcode value obtained from the machine, then in a case statement is prepared the message for the registration status to be shown in the top of the registration form and assigned to the caption of the lstatus label.
This method GetRegStatus, is called into the OnCreate event and at the end of each section of code that makes changes in the registration status, such as in BtnRegClick (), BtnRemoveClick (), BtnTrialClick () and BtnTrialOlmClick ().
procedure TRegForm.GetRegStatus; var s:string; begin with Form1 do begin AVLock.InstallCodeSources := Machine_Data; AVLock.MachineSources := [System_UUID, BaseBoard_SN, Reg_File]; {$IFDEF NAS} AVLock.RegPath := CommonDocuments; AVLock.RegFolder := 'example1'; AVLock.InstancesCtrl := False; {$ENDIF}
{$IFDEF SAN} AVLock.RegPath := ExeDir; AVLock.RegFolder := ''; AVLock.InstancesCtrl := True; {$ENDIF}
{$IFDEF REMOV} AVLock.RegPath := ExeDir; AVLock.RegFolder := ''; AVLock.InstancesCtrl := False; AVLock.RemovableDisk := True; {$ENDIF}
AVLock.EncryptionKey := 'abc123'; AVLock.EncryptionKey2 := 'xyz321'; AVLock.AppID := 12301; AVLock.AppName := 'MyApp'; AVLock.AppVersion := '1.0.0'; AVLock.WebHost := 'www.av-soft.com'; AVLock.TimeHost:= 'time-a.nist.gov'; AVLock.OlmPath := '/olm5'; AVLock.OlmBasicScript := 'basicolm.php'; AVLock.OlmAdvScript := 'advancedolm.php'; AVLock.GetKeyData(0,keydata); EdIcode.Text := AVLock.InstallCode; EdName.Text := AVLock.UserName; EdCompany.Text := AVLock.Company; EdEmail.Text := AVLock.Email; EdOther.Text := AVLock.OtherCode; s:=''; case keydata.Status of Unregistered: s:='Not registered'; Moved : s:='Moved to another computer'; Expired : s:='Expired'; Registered : begin s:=''; case keydata.KeyType of Trial : s:=s+'Trial '+inttostr(keydata.Days)+' days - '+inttostr(keydata.DaysLeft)+' days left.'; Temporal : s:=s+'Temporal '+inttostr(keydata.Days)+' days - '+inttostr(keydata.DaysLeft)+' days left.'; Permanent : s:=s+'Permanent, no time limit.'; end; end; end; end; lstatus.caption:=s; end;
procedure TRegForm.FormCreate(Sender: TObject); begin GetRegStatus; testfields0:=testfields; Changed:=False; end;
In the OnCreate event is called the GetRegStatus method in order to get the registration status and also to get the value for testfields0 which is a number between 0 and 4 representing the progress in the introduction of the user data, for example if testfields0 is 4 indicates that there is no data entered and if it is 0 all data has been entered. This value is later compared with new values calculated with testfields in order to determine if it is necessary to save the user data. In the next topic you will learn more about this matter.
Allow the user to enter personal data and save them in OLM database and locally.
In this form through various edit boxes allow the user to enter the following data: User Name, Company, Email Address and Postal Address. The goal is to get the user to enter their data without forcing you to do, therefore, the trial period is started with no requirement, then every time the user leave the registration form with the button [Continue>>], then if the user did not filled all data fields, he is encouraged to stay without going out and take a few moments to fill out the data. When the user leave the registration form, the user data are saved. Finally to perform the registration, the user must have all fields entries filled. The code for this functionality is as follow:
function TRegForm.testfields:integer; begin if (trim(edname.Text)='') then result:=4 else if (trim(edcompany.Text)='') then result:=3 else if (trim(edemail.Text)='') then result:=2 else if (trim(edother.Text)='') then result:=1 else result:=0; end;
//Este código se utiliza para "NO_OLM y "BASIC_OLM" para guardar los datos localmente //Para "ADVANCED_OLM" se utiliza OnlineSaveUserData que guarda los datos en el OLM y //localmente procedure TRegForm.writeData; begin with Form1 do begin AVLock.UserName := EdName.Text; AVLock.Company := EdCompany.Text; AVLock.Email := EdEmail.Text; AVLock.OtherCode := EdOther.Text; AVLock.WriteAppData; //write user data into the registration data AVLock.restart; end; end;
procedure TRegForm.BtnContinueClick(Sender: TObject); var n:integer; begin n:=testfields; if (n<>0) then begin if (messagedlg('Please click Ok and take a few moments to fill out your user data.', mtConfirmation, [mbOk, mbIgnore], 0) = mrOk) then exit; end; if (n<=testfields0) and changed then begin {$IFDEF ADVANCED_OLM} Form1.AVLock.OnlineSaveUserData(edname.Text, edcompany.Text, edemail.Text, edother.Text,0); {$ELSE} writedata; {$ENDIF} end; modalresult:=mrOk; end;
Start the trial period.
In the example 1a the trial period is started manually with the [Start Trial] button in the utility area for developer, with the following code:
procedure TRegForm.BtnTrialClick(Sender: TObject); begin if starttrial then showmessage('Trial started or synchronized successfully.') else showmessage('Failed to start the trial period.'); end;
function TRegForm.StartTrial:boolean; var res:string; err:integer; begin res:='00'; {$IFDEF NO_OLM} //(index,users,inst,startdate,days,values) err:=Form1.AVLock.MakeTrial(0,1,2,date,30,'000'); if (err=0) then res:='00'; {$ENDIF}
{$IFDEF BASIC_OLM} //values, kind, Index, days, inst) res := Form1.AVLock.OnlineGetKeyB('000',0,0,30,1);
{$ENDIF}
{$IFDEF ADVANCED_OLM} if (keydata.Status = Unregistered) then begin res := Form1.AVLock.OnlineSynch(0); if (res='00') then GetRegStatus; if (keydata.Status = Unregistered) then //(index,users,inst,days,values) res := Form1.AVLock.OnlineStartTrial(0,1,1,30,'000'); end else res:='00'; {$ENDIF} result:= (res='00'); if result then GetRegStatus; end;
In the example 1b the trial is started automatically by inserting the call to StartTrial in the OnCreate event.
procedure TRegForm.FormCreate(Sender: TObject); begin . . . StartTrial; . . . end;
We have three options for starting the trial period: a) Method offline. Using the method MakeTrial (). b) Method online. Using the basic OLM. The example is configured to access the script basicolm.php from the www.av-soft.com site, which you can use for testings. c) Method online. Using advanced OLM. The example is configured to access the script advancedolm.php www.av-soft.com Site which you can use for testings.
Register the Application
In the registration form we can see the "Register Now" section with two buttons and a TEdit that allow the user to enter the registration key and activate it with the [Register] button. The first button on the left [Load from file] lets enter a key from a file. The code associated with the button [Register] is as follows:
procedure TRegForm.BtnRegClick(Sender: TObject); var s: string; err, n :integer; olm :boolean; begin n:=testfields; if (n>0) then begin showmessage('Please fill out your user data then try again.'); exit; end; olm:=False; s:=''; {$IFDEF ADVANCED_OLM} olm:= connected; {$ENDIF} if olm then begin //Save Uuser data into the OLM and locally Form1.AVLock.OnlineSaveUserData(edname.Text, edcompany.Text, edemail.Text, edother.Text,0); //register KEY into the OLM and locally s:=Form1.AVLock.OnlineRegisterKey(trim(EdKey.Text)); if (s='50') then begin showmessage('Key registered successfully'); GetRegStatus; end else showmessage('Process fail, error: '+s); end else begin //Save Uuser data locally writedata; //register KEY locally err := Form1.AVLock.RegisterKey(trim(EdKey.Text)); case err of 0: s:= 'Key registered successfully'; 1: s:= 'Key Length mismatch'; 2: s:= 'Your system date is incorrect'; 3: s:= 'Key unregistered'; 4: s:= 'Key not valid'; end; if (err=0) then GetRegStatus; if (s<>'') then showmessage(s); end; end;
Control the number of concurrent instances The Instances field determines the number of simultaneous instances allowed into the computer. To allow it you must set (InstancesControl=True). Optionally this will manage the number of instances into the network using (RegFolder='') and (RegPath=Other), so the *.avr file for the registration data and the *.avc file to control instances will be saved into the
procedure TForm1.BtnUsersClick(Sender: TObject); var s:string; i:integer; begin AVLock.Refresh; s:='There are active '+inttostr(AVLock.activeinstances.count)+' of '+ inttostr(keydata.Instances)+' Instances allowed'+#13#10 +'----------------------------------------------------------'+#13#10; for i:=0 to AVLock.activeinstances.count -1 do s:=s+AVLock.activeinstances[i]+#13#10; s:=s+'----------------------------------------------------------'; showmessage(s); end;
There you will see a brief information about the instances currently running. Also consider the following code from the OnPaint event:
This code terminate the application when it is not registered.
if (keydata.Status <> Registered) then begin showmessage('Not Registered'); application.Terminate; end;
This code terminate the application when the current number of instances surpassed the allowed number.
if (keydata.TooManyInstances) then begin showmessage('Too many instances'); application.Terminate; end;
This code terminates the application when trying to launch it from a terminal as the first instance. This limitation is for security reasons.
if not AVLock.IsLocal and (AVLock.activeinstances.count < 2) then begin showmessage('This application must be run first from the server.'); application.Terminate; end;
Brief practice with example 1a
From the Delphi IDE open the example 1a (\Examples\1\a)
Run the application Hit the button or click F9 to start the program. In moments you will see the registration form:
Note that the current registration status is "Not registered". This is because it is first executed the program and for "a" versions, the trial period is not started automatically.
If the status is not registered then when clicking the [Continue >>] button, the application will terminate, so the main form will be inaccessible.
Start the trial period
Related items: The registration process
For now we will see how to do it manually using the buttons provided for this purpose, after with the version (b) we will see how to do it automatically when you start the application. Click on the [Start Trial] button. The code associated with this button has been shown above in the topic Start the trial period
Changing the following compiler directive {$DEFINE ADVANCED_OLM} //Options are BASIC_OLM, ADVANCED_OLM, NO_OLM you could test the three options. We suggest you that before try with a new configuration, remove all registration data with the [Remove Registration] button.
After pressing the [Start Trial] button you will receive the message "Trial Started or synchronized successfully".
For this example we configured the application to calculate the InstallCode based on values obtained from the computer (InstallCodeSources = Machine_Data), so, the user data are optional, you may omit it entirely and could be a good alternative if you use the basic OLM. But if you use the advanced OLM, it is likely that you want to have the user data in the OLM database.
Once you start the trial period, you will see changed the "Current Registration Status", as shown below:
Clicking on the [Continue>>] button we exit the registration form, then if the application is registered you will go directly to the main form of the application. See the associated code in the topic Enter the user data.
So, the following dialog will bring up when you click the [Continue >>] button.
If you answer [Ok] will not come out the registration form and have the chance to enter the user data, but if you click [Ignore] then will leave the form even if no user data entered.
Finally will go to the main application form:
There is the button [Registration Form], which allows you to access the registration form. This form is not displayed automatically on startup, so you should use this button to display it. Close the application and open it again and you'll see.
Deleting the existing registration
The registration data are always stored on the computer where the application is registered (local data), but if the user has an Internet connection may also be stored on the website (Online Data). As we saw in the previous section, the way as the registration is done depends on the value of the following directive:
{$DEFINE ADVANCED_OLM} //Options are BASIC_OLM, ADVANCED_OLM, NO_OLM
for this case defined to use the Advanced OLM.
If you started the trial period with the directive {$DEFINE NO_OLM} the MakeTrial method would have used to start the trial period and the data would be stored only in the computer, but if you started with the directive {$DEFINE BASIC_OLM}, the key should be saved in both places but user data only locally, and if you had defined {$DEFINE ADVANCED_OLM}, the key data and the user data should be saved in both places, on the computer and the website. See below the code that runs depending on the directive defined:
procedure TRegForm.BtnRemoveClick(Sender: TObject); var ok:boolean; s,msg:string; begin if AVLock.EraseReg then msg:= 'Local registration data removed'+#13#10 else msg:= 'Could not remove Local registration data'+#13#10; ok:=False; {$IFDEF BASIC_OLM} ok:= AVLock.OnlineRemoveKey(0); //remove regitration data from the Basic OLM {$ENDIF} {$IFDEF ADVANCED_OLM} s:= AVLock.OnlineRemoveReg(0); //remove regitration data from the Advanced OLM ok:= ((s='00') or (s='11')); {$ENDIF} if ok then msg:=msg+'Online registration data removed' else msg:=msg+'Could not remove Online registration data'; showmessage(msg); GetRegStatus; end;
Go to the registration form with [Registration Form] and delete the registration with [Remove Local Registration Data]. You will see a message informing you of the result of the operation:
Now when you click on [Continue>>] the application stops the execution. The program returned to its initial status "unregistered".
If you defined {$DEFINE NO_OLM}, only will have local registration data, and the Erasereg method all it does is delete the *. avr file which can also be removed manually.
With the other options {$DEFINE BASIC_OLM} and {$DEFINE ADVANCED_OLM} the data is deleted from the website. In the first case a file is deleted with the OnlineRemoveKey method and for the second case a database record is deleted using the method OnlineRemoveReg.
The methods OnlineRemoveKey and OnlineRemoveReg removes the registration data on the website, so you should not allow the user to access these utilities on the final version of your application if you are using in your application a panel of utilities like this example, remove it from the final version as we do in version 1b.
Do not worry, thinking that perhaps an user can download the package AVLock SIMPLE and taking the source code of the examples may come to use these methods to pass over your protection, this is not possible because to do so should know the AppID and encryption keys that you are using.
See below how the registration data is saved into the web site using the basic OLM.
Registering the application using Keys
Every time you started the trial period was generated internally a registration key. Normally the trial period is started with the two methods already seen, with MakeTrial() or with the OLM, but can also be done using a registration key.
Let's assume you do not want the trial period starts automatically and prompts users to send you InstallCode code to generate a key which would allow the trial period. This method is very safe and does not require that you use the OLM.
To generate the key we use the keygen.exe utility
Generate an 50-day trial key as shown below:
Enter the generated key into the registration form and click on [Register].
if no mistakes should receive a message like the one shown below, with the state of registration to 50 days.
You can generate different types of keys: Permanent: Never expire. Temporary: Same as the trial keys but used to rent your application by month, year, etc. Trial: Used for the initial trial period. Unregister Key: Deletes local registration data corresponding to the Index used to generate the key. Unregister All: Deletes all local registration data.
Synchronize the data and renew the license from the OLM
In this example we have the following three buttons: [Synchronize] [Renew and Synchronize] and [Full Synchronize]. Here we use three alternative methods to perform the task of synchronizing data with the server. Let we explain each of them:
Synchronize: Uses the following code:
procedure TRegForm.BtnSynchClick(Sender: TObject); var res:string; begin {$IFDEF BASIC_OLM} showmessage('Not allowed from the Basic OLM'); {$ENDIF} {$IFDEF ADVANCED_OLM} res := AVLock.OnlineSynch(0); if (res='00') then begin GetRegStatus; showmessage('User and Key data Synchronized'); else showmessage('ERROR: '+res); {$ENDIF} end;
The method OnlineSynch() works for primary and secondary records. This read from the Advanced OLM database the user data and key data and store them into the local registration data (*.avr file). If the operation was successful return '00', otherwise it returns an error code.
Renew and Synchronize: Uses the following code:
procedure TRegForm.BtnRenewClick(Sender: TObject); var res, msg:string; begin {$IFDEF BASIC_OLM} showmessage('Not allowed from the Basic OLM'); {$ENDIF} {$IFDEF ADVANCED_OLM} res := AVLock.OnlineRenew(0); if (res='00') or (res='') then GetRegStatus; if (res='00') then msg:='User Data synchronized and Renewal Applied' else if (res='') then msg:='User Data synchronized' else msg:='ERROR: '+res; showmessage(msg); {$ENDIF} end;
The OnlineRenew() method works only for primary records. Performs two operations: 1) Synchronize user data. Read from the proper record in the OLM the user data and stores it into the local registration data (*.avr file). 2) Renew the registration key. If the Paid field is 'Y' (paid for a new key) generates a new registration key based on the fields users, values, instances, and days, then stores the new key into the OLM and also saves it into the local registration data (*.avr file). Could be used to register a new time period or to upgrade the license enabling new features in the application through a new field values. If the method returns '00 'means that both operations have been performed and if it returns an empty string '' means only have synchronized user data because the Paid field had the value' N '.
Full Synchronize: Uses the following code:
procedure TRegForm.BtnFullClick(Sender: TObject); var res, msg:string; begin {$IFDEF BASIC_OLM} showmessage('Not allowed from the Basic OLM'); {$ENDIF} {$IFDEF ADVANCED_OLM} res := AVLock.OnlineFullSynch(0); if (res='00') or (res='') then GetRegStatus; if (res='00') then msg:='User and Key data synchronized and/or renewal applied and/or Trial Started' else if (res='') then msg:='Synchronized User data only' else msg :='ERROR: '+res; showmessage(msg); {$ENDIF} end;
The OnlineFullsynch() method could be used in place of the following methods already discussed above:
1) OnlineStartTrial () 2) OnlineSynch () 3) OnlineRenew () 4) OnlineExtendTrial ()
In this way with a single function would be covered almost all the necessary functions of online registration. Depending on the situation makes one or other of the actions listed above:
1) If the Paid field is 'Y' performs the functionality of OnlineRenew () generating a new registration key and storing it in the OLM and locally. 2) If the field Extend is 'Y' performs the functionality of OnlineExtendTrial () generating a new registration key of trial type to extend the trial period and storing it in the OLM and locally. 3) If the record in the OLM does not exist, indicating that the application is running for the first time, performs the functionality of OnlineStartTrial () creating a new record with a key based on the default values for trial periods, values can be changed by editing the php scripts of the OLM. 4) If the record exists, then reads the user data and stores them locally, as well as it does OnlineSynch ().
This method works for primary and secondary records.
Control the computer system date
During the trial period and periods of temporary keys there is the potential risk that the user attempts to set back the date of the computer to use the application for more time than the authorized period. To avoid this we added the following methods:
GetOnlineDate(): Gets the current date from the internet. FixSystemDate(): Changes the computer system date using the date given as parameter. OnlineCheckDate(): Internally uses the two above methods to obtain the correct date and assign it to the computer. Also saves the latest date reached by the computer (LastDate) along with the registration data.
Then, each time you get the registration status with GetKeyData() also reads the LastDate field and compares it with the date of the computer and if LastDate is higher than the computer date it assumes that the user turned back the computer date, then the DateBacked field within the key data is changed to True.
With the button [Check System Date] is used the GetOnlineDate() method to get the date from Internet and then compares it to the local date, if not matches then ask the user permission to change it. If he agree then uses FixSystemDate() to fix the computer date.
With the button [Check and Fix System Date] is used OnlineCheckDate() to do the same but without giving the user the ability to approve the transaction. This method takes a Boolean parameter "fix", if true then the date is fixed otherwise it is not changed. This option can only be applied if exists the local registration data from where LastDate could reads the date saved, so in the example executes only if the application is already registered.
The example 1b
Example 1b is the definitive version of the program. The utilitarian section was eliminated as these are tools that serve the programmer to see that the registration mechanism is working properly but should not be in the final version. see below the registration form as is on the Delphi IDE.
In addition to removing all the utilitarian buttons, did the following changes to the code:
In the OnCreate event is added a verification of the system date with automatic correction. A call to StartTrial to start the trial period and a call to OnlineRenew to automatically renew the registration through the OLM.
procedure TRegForm.FormCreate(Sender: TObject); begin if (keydata.Status = registered) and connected then Form1.AVLock.OnlineCheckDate(true); //fix system date GetRegStatus; testfields0:=testfields; Changed:=False; StartTrial; Form1.AVLock.OnlineRenew(0); end;
|