Tel: +44(0)1865 300 579
Fax: +44(0)1865 300 232
Polyhedron Licensing System (PLS) is a simple but flexible package for controlling the use of licensed software without the expense or inconvenience of "dongle" or licence server systems.
When using PLS, the vendor may distribute the software freely, but users will find it inoperative (or restricted) unless a special "licence file" is also installed. This is a plain text file, which normally contains the name of the user, details of the licensed application, and of any restrictions on its use. PLS detects any attempts to tamper with this file and optionally enforces restrictions on the date of the run and the serial number of the primary disk on the host machine.
An example licence file is shown below:
|
Licensor |
: Sausage Software plc : Sausage Simulation Environment 2.4 : John Jones, Newton Sausage Manufacturing Company : Anything you like : AABFQAAA : 11/08/2006 : 2868-12f5 : KHNMDKOJLPGOLBAJ |
The first 2 lines of the file contain the names of the licensor, and the licensed software. The software vendor has defined the keywords and values on the next 3 lines. There may be as many such lines as required, and the application may access and use them in many different ways. For example, the "Licensee" name could be displayed on the initial screen, or the "About" page to discourage illegal copying, and the "Facility Code" could be used to enable and disable facilities within the application.
The next two lines contain keywords that are recognised by PLS. ; "Expiry M/D/Y" is used to specify a licence expiry date (Expiry D/M/Y may also be used if you prefer European style dates), and "Disk Serial" is used to specify the serial number of the primary hard disk. PLS will report to the application if the expiry date has passed, or the disk serial is not as specified. The application may then display a message, or take whatever other action is required. These lines are optional, and if they are omitted, the corresponding check is not done. A full list of keywords that are recognised by PLS may be found in the next section.
The last line contains an authorization code, which depends on the other lines in the file, and can be checked by the licensed application as required. Any attempt to alter any part of the licence file (for example to extend a trial period, or change the name of the licensee) can be spotted, allowing the application to halt with an appropriate message. The user might then contact the vendor, and be sent a new licence file. Because the file is plain text, it can easily be sent by email or fax, or even dictated over the telephone.
From the end user's viewpoint, the system is very unobtrusive, and comes into play only when action is required. Extending or changing a licence involves extracting a small file from an email, or typing a few lines with a text editor.
From the vendor’s viewpoint, the process is quite simple. The first step is to produce a base file containing the information to be protected. The file may consist of up 50 lines each containing a keyword, followed by a colon, followed by a value. The following example shows the base file which was used to create the above license file.
|
Licensee |
: John Jones, Newton Sausage Manufacturing Company : Anything you like : AABFQAAA : 11/08/2006 : 2868-12f5 |
The base file may be created manually, using a text editor, or using purpose built software. Keywords are not case-sensitive, and spaces are ignored. Colons are not permitted within keywords. Certain keywords are reserved, because they have a special meaning. These are:-
|
Licensor |
The name of the software licensor The name of the licensed program (not reserved in multi-program PLS installations) used to specify that PLS should check the system drive disk serial number. used to specify a licence expiry date (US format) used to specify a licence expiry date (European format) used by PLS to specify the authorization code synonym for Authorization |
If you wish to use the disk serial number check, you will have to ask the end-user for the disk serial number of the system drive on the target machine, so that it can be included in the file. Generally, the system drive is C:, but could be different if Windows is installed on a differnet disk. The serial number can be found by typing "dir %systemdrive%:" at a command prompt.
|
C:\-->dir %systemdrive%|more |
Note that the Serial Number of the system drive is required, even if the program is not installed on that drive.
Once the base file is ready, it can be converted to a licence file by running PLS_SEAL from a command prompt. PLS_SEAL uses standard input for the base file, and standard output for the protected license file
|
PLS_SEAL <original.fig >protected.fig |
The protected licence file is identical to the original base file, but with Licensor, Program Name and Authorization lines added (Program Name is not added if you have a multi-program PLS installation).
|
Licensor |
: Sausage Software plc : Sausage Simulation Environment 2.4 : John Jones, Newton Sausage Manufacturing Company : Anything you like : AABFQAAA : 11/08/2006 : 2868-12f5 : KHNMDKOJLPGOLBAJ |
When this file is installed on the end-user’s machine, it activates the otherwise non-functional application.
PLS_SEAL is itself protected by a license file called PLS_SEAL.FIG. It is very important to keep this file secure, as it is the key which could allow anyone to generate valid license files for your program.
The current version of PLS includes versions for Intel Fortran, Compaq Visual Fortran, Salford FTN95 and Lahey LF95. The corresponding object files are named PLS_INTEL.OBJ, PLS_CVF.OBJ, PLS_SALF.OBJ and PLS_LF95.OBJ. Simply include the appropriate object file when you link your program.
|
e.g. |
lf95 MYPROG.F90 PLS_LF95.OBJ |
A simple test program called PLS_TEST.FOR is included with the distribution. We suggest that you compile and link this sample program to familiarise yourself with PLS.
In addition to these object files, a DLL (dynamic link library) version of PLS is included. This version can be called from Visual Basic, Delphi, Excel, or any other application that can call 32 bit DLLs. Example projects written using Delphi (PLS_DELPHI) and Visual Basic (PLS_VB) are included with the package.
API Specification (Fortran)
In order to use PLS, the licensed application should first call PLS_READFIG to read the contents of the licence file. After that, PLS_CHECKCODE may be called to validate the authorization code, expiry date, disk serial etc., and PLS_GETVALUE to retrieve values corresponding to specified keywords.
PLS_READFIG Subroutine
Interface
|
SUBROUTINE PLS_READFIG(Zfig,Code) |
Description
Reads the content of the specified configuration file. If the configuration file is in the same directory as the program executable, you can use PLS_GETHOMEDIRECTORY to help construct Zfig.
Arguments
|
Zfig |
The name of the configuration file to be read The return code |
|
|
0 ; ; ; ; |
No errors. the unit on which Zfig was to be opened is in use. unable to open Zfig. Unable to parse a line in Zfig. too many values (the limit is 100). |
|
PLS_CHECKCODE Subroutine
Interface
|
SUBROUTINE PLS_CHECKCODE(Code) |
Description
Checks the authorization code, and other keywords recognised by PLS
Arguments
|
Code |
The return code | |
|
0 |
No errors. there is no "AUTHORIZATION" line. the Authorization code is the wrong length. the disk serial number is incorrect. the licence expiry date has passed the Authorization code is incorrect. |
|
Notes
The disk serial number is specified in the licence file using the "DISKSERIAL" keyword. Note that case and spacing are ignored
|
e.g. |
Disk Serial : 2868-12f5 |
The expiry date is specified using either "EXPIRY D/M/Y" or "EXPIRY M/D/Y". In both cases the day moth and year are separated by ‘/’ characters. In the former, the order is day/month/year (European format), whereas the latter uses month/day/year (US format).
|
e.g. |
Expiry D/M/Y : 31/12/2003 Expiry M/D/Y : 12/31/2003 |
PLS_GETVALUE Subroutine
Interface
|
SUBROUTINE PLS_GETVALUE(Name,Value,Code) |
Description
Returns the value corresponding to a specified keyword in the configuration file.
Arguments
|
Name |
The name of the keyword to be queried Returned with the value associated with the specified keyword. The return code |
|
|
0 |
No errors The keyword could not be found |
|
Notes
If the length of Value differs from the length of the string being returned, it is padded with trailing spaces or truncated as necessary.
PLS_GETENV Subroutine
Interface
|
SUBROUTINE PLS_GETENV(Name,Value) |
Description
Returns the value corresponding to a specified system environment variable.
Arguments
|
Name |
The name of the environment variable to be queried Returned with the value associated with the specified environment variable. |
|
Notes
If the length of Value differs from the length of the string being returned, it is padded with trailing spaces or truncated as necessary.
PLS_GETVOLSER Subroutine
Interface
|
SUBROUTINE PLS_GETVOLSER(VolSer) |
Description
Returns the volume serial number of the system drive on the current computer.
Arguments
VolSer the volume serial number.
Notes
In general the volume serial number is displayed as 2 sets of 4 hexadecimal digits, separated by a hyphen.
PLS_GETHOMEDIRECTORY Subroutine
Interface
|
SUBROUTINE PLS_GETHOMEDIRECTORY(Home) |
Description
Returns the name of the directory containing the current program.
Arguments
Home returned with the name of the directory containing the current program, including a trailing ‘\’.
Notes
The licence file is normally installed into the same directory as the program it applies to. This routine gives the programmer a simple way to find the directory containing the executable, and hence the licence file.
PLS_CHECKPOSTDATED Subroutine
Interface
|
SUBROUTINE PLS_CHECKPOSTDATED(Directory,Filename,PostDated) |
Description
Scans the specified directory for postdated files (i.e. files with a creation, modification or last access time which is in the future (or after the date specified using PLS_SETPOSTDATE).
Arguments
|
Directory |
The name of the directory to be scanned Returned with name of the first postdated file (if any). .TRUE. if there is a postdated file |
|
Notes
The existence of post-dated files suggests, but does not prove, that the end-user may have tampered with his/her clock, possibly with a view to bypassing license expiry conditions. It is recommended that the licensor treads carefully when using this check to enforce a license expiry date. There are many valid reasons why a user might alter the clock on his/her computer!
PLS_SETPOSTDATE Subroutine
Interface
|
SUBROUTINE PLS_SETPOSTDATE(Year,Month,Day,Hour,Minute,Second) |
Description
Specifies the date and time beyond which PLS_CHECKPOSTDATED will regard a file as post-dated
Arguments
|
Year |
4 digits 1-12 1-31 0-23 0-59 0-59 |
|
Notes
If PLS_SETPOSTDATE is not called, PLS_CHECKPOSTDATED will use the current date and time for its checks.
| PROGRAM PLS_TEST IMPLICIT NONE INTEGER icode , volser CHARACTER zval*60 , zhome*260 , zfile*260 LOGICAL PostDated ! Find location of .EXE file - configuration file assumed to ! be in the same directory CALL PLS_GetHomeDirectory(zhome) print * , 'Home Directory '//Trim(zhome) print * , 'Reading Authorization file '//Trim(Zhome)//'test.fig' print * CALL PLS_READFIG(Trim(Zhome)//'test.fig',icode) PRINT * , 'Authorization file read - return code ' , icode PRINT * CALL PLS_GETVALUE('Licensor',zval,icode) IF ( icode.EQ.0 ) THEN print * , 'Licensor = ' , zval ELSE print * , 'Licensor not found' ENDIF CALL PLS_GETVALUE('Program Name',zval,icode) IF ( icode.EQ.0 ) THEN print * , 'Program Name = ' , zval ELSE print * , 'Program Name not found' ENDIF CALL PLS_GETVALUE('Disk Serial',zval,icode) IF ( icode.EQ.0 ) THEN print * , 'Disk Serial = ' , zval ELSE print * , 'Disk Serial not found' ENDIF CALL PLS_WAIT(2000) CALL PLS_GETVALUE('Grandfather',zval,icode) IF ( icode.EQ.0 ) THEN print * , 'Grandfather = ' , zval ELSE print * , 'Grandfather not found' ENDIF CALL PLS_GETVALUE('expirym/d /Y',zval,icode) IF ( icode.EQ.0 ) THEN print * , 'Expiry M/D/Y = ' , zval ELSE print * , 'Expiry M/D/Y not found' ENDIF CALL PLS_GETVALUE('expiry D/M/Y',zval,icode) IF ( icode.EQ.0 ) THEN print * , 'Expiry D/M/Y = ' , zval ELSE print * , 'Expiry D/M/Y not found' ENDIF CALL PLS_GETVALUE('LICENSEE',zval,icode) IF ( icode.EQ.0 ) THEN print * , 'Licensee = ' , zval ELSE print * , 'Licensee not found' ENDIF CALL PLS_GETVALUE('Authorization',zval,icode) IF ( icode.EQ.0 ) THEN print * , 'Authorization = ' , zval ELSE print * , 'Authorization not found' ENDIF print * ! check that code is valid CALL PLS_CHECKCODE(icode) IF ( icode.EQ.90 ) then print * , 'Authorization not found' ELSEIF ( icode.EQ.91 ) then print * , 'Authorisation Code is incorrect length' ELSEIF ( icode.EQ.97 ) then print * , 'Incorrect Disk Serial Number' CALL PLS_GETVALUE('DISKSERIAL',zval,icode) print *, ' Expected value ' , zval(1:4)//'-'//zval(5:8) CALL PLS_GETVOLSER(volser) WRITE(zval,'(Z8.8)') volser print *, ' Actual value ' , zval(1:4)//'-'//zval(5:8) ELSEIF ( icode.EQ.98 ) then print * , 'Licence Expiry Date has Passed' ELSEIF ( icode.EQ.99 ) then print * , 'Incorrect Authorization Code' ELSE print * , 'Authorization Successful' ENDIF ! Check for PostDated files in TEMP and Home directories CALL PLS_GetEnv('TEMP',zhome) CALL PLS_CheckForPostDated(TRIM(zhome)//'\*.*',zfile,postdated) IF ( postdated ) THEN print *,'Post-dated file ('//TRIM(Zfile)//') in '//trim(zhome) ELSE print *,'No post-dated files in '//TRIM(zhome) ENDIF CALL PLS_GetHomeDirectory(zhome) CALL PLS_CheckForPostDated(TRIM(zhome)//'*.*',zfile,postdated) IF ( postdated ) THEN print *,'Post-dated file ('//TRIM(Zfile)//') in '//trim(zhome) ELSE print *,'No post-dated files in '//trim(zhome) ENDIF END
|
for further information or to place an order
(C) Polyhedron Software Ltd. (2000-2004)