Electronic Software Distribution
by Jeremy Soref and Sheridan Adjei


Listing One

#include "PLClient.h"           //Supplied by Privilege DK
#include "DevConst.h"           //Supplied by Privilege Developer SK
int     LoadApplication() 
{
        /*  Load Application 
            ...
        */
        return (0) ;
}
int main(int argc, char* argv[])
{
        PL_APIERR               Err ;
        PL_API_HANDLE           DevHandle ;
        PL_API_SESSION_ID       SessionId ;
        int                     AppExitCode ;

// Initialize the Privilege Client API
/* _PL_DEVELOPER_ID is an input parameter. It is your unique developer ID 
  declared in your  DevConst.h file.  _PL_DEV_COMM_PUBLIC_KEY is an input 
  parameter. It is your unique developer key declared in your DevConst.h file.
  CM_Network is an input parameter. Enables the application to search for 
  the Privilege Server both in the stand-alone machine and in entire network.
  DevHandle is an output parameter. The developer context handle created.
*/
        Err = PLC_DeveloperInit(_PL_DEVELOPER_ID,_PL_DEV_COMM_PUBLIC_KEY,
              CM_Network,&DevHandle);
/* Error, failed to initialize licensing API */
/* exit with an error code and do not load the application */
        if ( Err != PL_APIERR_OK )
                return (-1) ;   
/* Try to login to your license. Login operation will automatically search for
  a Privilege Server that can locate your license and log in to it.
  DevHandle is an input parameter. It is the developer context handle returned
  above. We define a feature name as an input parameter for which we will 
  request a login. SessionId is an output parameter. It is the session 
  ID for an instance of using the defined feature name.
*/
        Err = PLC_Login(DevHandle, "MyFeatureName", &SessionId);
/* Error, failed to login to the appropriate license, either it does not 
   exist or it is invalid for some reason. exit with an error code and 
   do not load the application */
        if ( Err != PL_APIERR_OK )
                return (-2) ; 
/* CONTINUE TO LOAD APPLICATION:
   If you got here, it means you have successfully logged into your license 
   and the license is valid.
*/  
        AppExitCode = LoadApplication() ;
/* APPLICATION EXITS: After your application terminates normally, execution 
   returns to this point. Just before it really exits you have some 
   small cleanup operations to do: 
*/
/* Close the established license session: */
Err = PLC_Logout( SessionId ) ;
/* Error, failed to close the license session. */
/* Just report the error when application exits */
        if ( Err != PL_APIERR_OK )
                return (-3) ; 
/* Uninitialize the Privilege Client API: */
/* The developer handle returned by previous call 
   to function PLC_DeveloperInit.*/
        Err = PLC_DeveloperUnInit( DevHandle ); 
/* Error, failed to uninitialize the Privilege Client API. */
/* Just report the error when application exits */
if ( Err != PL_APIERR_OK )
                return (-4) ; 
/* If you here, report the application exit code: */
        return (AppExitCode) ;
}

Listing Two
#include "PLClient.h"           //Supplied by Privilege DK
#include "DevConst.h"           //Supplied by Privilege Developer SK

/* Assume you want to protect three internal features of your application 
   with three different licenses based on three different licensing models.
   The three features are: Print, Save and NewDocument operations.
   Assume that your application calls one of the appropriate functions 
   described here when the user engages the feature. 
*/
/* DevHandle, is developer context handle returned upon initializing the API.  
   Declare this developer handle as a global variable.
*/
PL_API_HANDLE           DevHandle ;
int     LoadApplication() 
{
    /* Load Application */
    /* ... When needed call app_print/app_save/app_newdocument functions. */
        return (0) ;
}
int app_print( char* pFileNameToPrint , char* pDeviceName )
{
        PL_APIERR               Err ;
        PL_API_SESSION_ID       SessionId ;
        Err = PLC_Login(DevHandle,"Print",&SessionId);
 /* Error, failed to login to appropriate license, either it does not 
   exist or it is invalid for some reason. 
   Deny the print operation and exit function with an error code 
*/
        if ( Err != PL_APIERR_OK )
                return (-1) ;
        /************************************************/
        /*   Insert code for Printing here...
        /************************************************/
/* Close the established licesne session: */
        Err = PLC_Logout( SessionId ) ;                 
        if ( Err != PL_APIERR_OK )
                return (-2) ; 
        return (0) ;
}
int app_save( char* pFileNameToSave , char* pDeviceName )
{
        PL_APIERR               Err ;
        PL_API_SESSION_ID       SessionId ;
        Err = PLC_Login(DevHandle,"Save",&SessionId);
/* Error, failed to login to appropriate license, either it does not 
  exist or it is invalid for some reason. 
  Deny the save operation and exit function with an error code 
*/
        if ( Err != PL_APIERR_OK )
                return (-1) ; 
        /************************************************/
        /*   Insert Code here for the Save operation ...
        /************************************************/
/* Close the established license session. */
        Err = PLC_Logout( SessionId ) ;                 
        if ( Err != PL_APIERR_OK )
                return (-2) ; 
        return (0) ;
}
int app_new_document( char* pFileNameToSave , char* pDeviceName )
{
        PL_APIERR                        Err ;
        PL_API_SESSION_ID          SessionId ;
        Err = PLC_Login(DevHandle,"NewDocument",&SessionId);
/* Error, failed to login to appropiate license, it either does not exist or 
   is invalid for some reason. 
   Deny the new document operation and exit function with an error code.
*/
        if ( Err != PL_APIERR_OK )
                return (-1) ; 
        /************************************************/
        /*   Insert to do code for New document operation ...
        /************************************************/
        /* Close the established licesne session: */
        Err = PLC_Logout( SessionId ) ;                 
        if ( Err != PL_APIERR_OK )
                return (-2) ; 
        return (0) ;
}
int main(int argc, char* argv[])
{
        PL_APIERR       Err ;
        int             AppExitCode ;
/* In the main function just initialize/uninitialize the licensing API */ 
// Initialize the Privilege Client API
        Err = PLC_DeveloperInit(_PL_DEVELOPER_ID,_PL_DEV_COMM_PUBLIC_KEY,      
                                  CM_Network,&DevHandle);
        if ( Err != PL_APIERR_OK )
                return (-1) ;
        /* Insert code for Load operation ... */  
        AppExitCode = LoadApplication() ;
/* APPLICATION EXITS:
   After application terminates normally, execution returns to this point. 
   Just before it really exits you have some small cleanup operations to do: 
*/
/* Uninitialize the Privilege Client API: */
        Err = PLC_DeveloperUnInit( DevHandle ); 
        if ( Err != PL_APIERR_OK )
                return (-2) ; 
/* If you are here, report the application exit code: */
        return (AppExitCode) ;
}

Listing Three
#include "PLClient.h"           //Supplied by Privilege DK
#include "DevConst.h"           //Supplied by Privilege Developer SK

int func_print( int Resolution, char* FileToPrint )
{
        PL_APIERR               Err ;
        PL_API_HANDLE           DevHandle ;
        PL_API_SESSION_ID       SessionId ;
        int                     UnitsToConsume ;
// Initialize the Privilege Client API
/* _PL_DEVELOPER_ID is an input parameter. It is your unique developer 
      ID declared in your DevConst.h file. 
  _PL_DEV_COMM_PUBLIC_KEY is an input parameter. It is your unique developer 
     key declared in your DevConst.h file.
  CM_Network is an input parameter. Enables application to search for 
     Privilege Server both in stand-alone machine and entire network.   
  DevHandle is an output parameter. The developer context handle created.
*/
        Err = PLC_DeveloperInit(_PL_DEVELOPER_ID,_PL_DEV_COMM_PUBLIC_KEY, 
                                CM_Network, &DevHandle );
        if ( Err != PL_APIERR_OK )
                return -1 ;
// Try to perform login to name "Print" representing component to be licensed. 
/* DevHandle is an input parameter. It is developer context handle 
   returned above */ 
/* We define a feature name "Print" as an input parameter for which 
   we will request a login. */
/* SessionId is an output parameter. It is session ID for an 
   instance of using the defined feature name.*/
        Err = PLC_Login( DevHandle,"Print", &SessionId );
// Error, failed to login to appropriate license, either it does not 
// exist or it is invalid for some reason. 
        if ( Err != PL_APIERR_OK )
                return -2 ;
// Decide how many units to consume from the license
/* Each time user prints a document at a resolution of 300 dpi, 
   20 units must be deducted from counter, at 600 dpi 50 units must 
   be deducted and at the default resolution 40 units must be deducted.
*/
switch ( Resolution )
{
                case    300 :
                        UnitsToConsume = 20 ;
                break ;
                case    600 :
                        UnitsToConsume = 50 ;
break ;
               default :
                        UnitsToConsume = 40 ;
break ;
        } ;
/* The session ID is an input parameter, it is returned from previous call 
   to PLC_Login */
/* UnitsToConsume is an input parameter to number of units to be deducted 
   from the counter */
        Err = PLC_ConsumeUnits( SessionId,UnitsToConsume );
        if ( Err != PL_APIERR_OK )
                return -3 ; 
/* If you got here, it means license was checked and updated and you can 
  go on with printing, but first you have some small cleanup operations to do:
*/      
// Close the established license session.
/* The session ID is an input parameter, returned by previous call to 
   PLC_Login */
        Err = PLC_Logout( SessionId ) ; 
// Error, failed to close license session. 
        if ( Err != PL_APIERR_OK )
                return -4 ; 
// Uninitialize the Privilege Client API
/* DevHandle is an input parameter, it is the handle returned by 
   previous call to PLC_DeveloperInit */
        Err = PLC_DeveloperUnInit( DevHandle );
// Error, failed to uninitialize the Privilege Client API. 
        if ( Err != PL_APIERR_OK )
                return -4 ; 
// Insert your actual printing code...
}

Listing Four
<HTML>
<HEAD>
<TITLE>LGCom Sample</TITLE>
</HEAD>
<%
'
'   This sample shows how to use the Privilege License Generator COM object
'   (LGCom) from within an ASP page (VBScript) to create a simple license.
'       GenLicense():
'   A function that creates a simple license file.
'   License will be locked to a specific machine (strLockID), it will 
'   be identified by a specific feature name, it will have a descriptive 
'   license name and will be saved to a required file path (no license 
'   terms are specified). If the function is successful, it returns a new 
'   license ID and a license signature that allows regenerating the same 
'   license file again.
'       parameters:
'        strLicenseName - [in] license name
'        strFeatureName - [in] license's feature name
'        strLockID              - [in] locking ID (host ID)
'    strLicFilePath - [in] new license file path 
'        nLicID             - [out] license ID
'        strLicSignature- [out] license signature
'       return value:
'        either 0 (everything is OK) or an error code
function GenLicense( strLicenseName, _strFeatureName, _strLockID, 
         _strLicFilePath, _ByRef nLicID, _ByRef strLicSignature )
        on error resume next
        Err.Clear
        ' Create an instance of the LGCom object
        ' LGCom.dll must be registered on the server
        set LG = Server.CreateObject( "LGComAx.LGCom" )
        ' set LG properties for LoginToAccount
        LG.DevId = &hFFFFFFF1   ' demo developer ID (required)
        LG.sDevName = "DevName" ' developer name    (optional)
        ' login to the Privilege developer account 
        ' keys file of the developer must be installed on the machine
        nRet = LG.LoginToAccount()
        if Err.number <> 0 then
                GenLicense = Err.number
                exit function
        end if
        if nRet <> 0 then
                GenLicense = nRet
                exit function
        end if
        ' set LG properties for CreateLicense
        LG.sLicenseName     = strLicenseName ' license name (optional)
        LG.sFeatureName     = strFeatureName ' feature name (required)
        LG.sHostId          = strLockID      ' host id (optional)
    ' other license terms can be set here 
    ' for example: expiration date, units to consume, max concurrency, etc.
        LG.sLicenseFilePath = strLicFilePath ' output file path (required)
        ' create the license
        nRet = LG.CreateLicense()
        if Err.number <> 0 then
                GenLicense = Err.number
                LG.LogoutFromAccount()
                exit function
        end if
        if nRet <> 0 then
                GenLicense = nRet
                LG.LogoutFromAccount()
                exit function
        end if
        ' get output parameters to be returned
        nLicID          = LG.LicenseId ' created license ID
        strLicSignature = LG.Signature ' license signature  
        LG.LogoutFromAccount()
        set LG = nothing
        GenLicense = 0
end function
%>
<BODY>
<h2>Privilege LGCom Test</h2>
<%
   strLicenseName = "License Name"
   strFeatureName = "Test Feature"
   strHostId      = "013ae2ef5fc77588284f5f18"
   strOutputDir   = "C:\Temp\"     ' path should exist on the server
   strFileName    = "License1.plf"
%>
<b>Input Parameters</b>:<br>
License Name - <i><%= strLicenseName %></i><br>
Feature Name - <i><%= strFeatureName %></i><br>
Host Id -      <i><%= strHostId %></i><br>
Output Path -  <i><%= strOutputDir + strFileName %></i><br> 
<br>
<%   
   nRet = GenLicense( strLicenseName, _strFeatureName, _strHostId, 
               _strOutputDir + strFileName, _nLicenseId, _strSignature )
%>
<% if nRet = 0 then %>
<b>License created successfully</b><br>
License Id: <i><%= Hex( nLicenseId ) %></i><br>
<% else %>
<b>Can not create license</b><br>
Error: <i><%= Hex( nRet ) %></i><br>
<% end if %>
</BODY>
</HTML>



Table 1:

Function             Description

PLC_ConsumeUnits      Allows creation of variable usage charges based on consumption of units (See Listing 3)  

PLC_GetSessionData    Allows the license to control the application or feature by sessions

PLC_LoginTBYB         Enables setting up of a trial (try-before-you-buy) dialog

PLC_SetIdleTime       Allows specification of an application or feature timeout

PLC_StartHeartBeat/PLC_StopHeartBeat     Allows for intermittent checking that license terms are still being met



Example 1: 

#-----------------------------------------------------------------------------
#                                  Privilege Licenser (R)  
#-----------------------------------------------------------------------------

PL_CERTIFICATE_TYPE = NORMAL
PL_COMMENT = This is a license for the 'Print' feature
PL_CONCURRENCY = UNLIMITED
PL_CONCURRENCY_TYPE = SESSIONS
PL_CREATION_DATE = Jan-27-2000
PL_DEVELOPER_ID = FFFFFFF1
PL_DEVELOPER_NAME = Demo 1
PL_EXPIRATION_DATE = Jan-01-2001
PL_FEATURE_NAME = Print
PL_HOST_ID = 1234567890aabbccddeeffff
PL_LICENSE_ID = 1A2425CD
PL_LICENSE_NAME = Sample License
PL_LOCKING_TYPE = HOST_ID
PL_SERVER_TYPE = ANY
PL_SIGNATURE = /bs/000000524_   __   $  @   ` '{_GFx
PMR~$T1/2U0d%F^_3K1
               ?le:BS`@DrUQ_"(tm) Y(d]8^-lv\r:Q4kK&
PL_UNITS_TO_CONSUME = 10000
PL_VERSION = 01.52

#-----------------------------------------------------------------------------
#                                  Privilege Licenser (R)  
#-----------------------------------------------------------------------------




