Copyright: Copywrite © 1997 - Concept Software, Inc.


INTRODUCTION

Congratulations! You have selected the Protection Plus Professional (PPP) system, a powerful software licensing and application control package to add to your application development toolbox.

Many developers specialize in one programming language. For this reason, the PPP system offers add-on libraries. You can purchase these separately for the CA-Clipper, "C"/DOS, FoxPro/DOS, FoxPro/Win, Win16 DLL, and Win32 DLL languages.

This manual contains information on all libraries available for the PPP system. All libraries share common functionality. Any exceptions are noted as well as any syntax differences between the various libraries.

The entire documentation for the PPP system is available via a Windows Help file. It is installed with this package.

Last updated October 1997.


HOW TO USE THIS MANUAL

This manual has several chapters that cover everything you need to know to use the PPP system. See Summary of Contents for a brief explanation of each chapter.

Use the << and >> buttons on the WinHelp button bar to move forward and backward in the manual.

We encourage you to read this manual in its entirety. This will help you gain a thorough understanding of the full power and functions that the PPP system offers.  Also work with the sample(s) supplied before jumping right in and coding your first application working with PPP.  Remember that there will be a learning curve, and some time will be needed to get a "good feeling" as to how everything comes together.  Please be patient.

For quick and easy reference in the printed manual, each page header contains the chapter number, page number, and chapter title (e.g. 2-2 GETTING STARTED) on the outer corner edge and the last section title on that page (e.g. FILENAME DESCRIPTIONS) on its inner corner edge. Main sections within chapters begin with an uppercase, bold, underscored title.

There are two types of notes used throughout this manual.

Key notes contain information that assists you in understanding the information contained in this manual.

CAUTION

Caution notes contain information that unless followed, could lead to improper operation of the PPP system.


SUMMARY OF CONTENTS

This manual contains several chapters. The following briefly describes, in order of appearance, the content of these chapters.

INTRODUCTION - Reviews some important information you should be familiar with, such as how to contact technical support, changes since Version 3.0 and the PPP system licensing agreement.

GETTING STARTED - Includes installation procedures, filename descriptions, and a Quick Start section.

PROTECTION PLUS PROFESSIONAL OVERVIEW - Provides an overview of the capabilities of this toolkit along with system requirements.

SOFTWARE LICENSING - Supplies you with an explanation of application control and copy protection concepts, and recommended implementation techniques. Contained is a glossary of common terminology used throughout this manual.

LICENSE FILE EDITOR - Explains the broad use and functions of the License File Editing facility. Information varies from navigation to License File generation and utilities.

FUNCTION LIBRARY - KEYLIB - Reference material documenting all KeyLib library functions supported by the PPP system. Includes detailed descriptions, syntax, return codes, and comprehensive examples for the language-specific functions purchased (i.e. CA-Clipper, FoxPro, "C"/DOS, or Windows DLL).

FUNCTION LIBRARY - TRIGLIB - Reference material documenting all TrigLib library functions supported by the PPP system. Includes detailed descriptions, syntax, return codes, and comprehensive examples for the language-specific functions purchased (i.e. CA-Clipper, FoxPro, "C"/DOS, or Windows DLL).

SAMPLE APPLICATIONS OVERVIEW  - Contains documentation about the sample code included with the software.

QUESTIONS AND ANSWERS - Contains most frequently asked questions by our clients. Please refer to this section before contacting Concept Software's Technical Support staff.


LICENSE AGREEMENT

LICENSE GRANT

Concept Software, Inc. hereby grants you a non-exclusive, non-transferable license to use this software product as described in the user manual on one (1) Central Processing Unit only.  You may not adapt, translate, reverse engineer, decompile or disassemble the software.  You are not acquiring any rights of ownership in the software, manuals, documentation or other materials.

By opening the sealed diskette packaging and using the diskette you agree to be bound by the terms and conditions of this License Agreement.  If you do not agree with the terms of this License Agreement, promptly return the software, manuals, documentation or other materials to the place you obtained them for a full refund.

IMPORTANT - The License Grant for the Standard Edition is different from the Enterprise Edition of Protection Plus Professional.  Refer to the diskette label or invoice to determine whether the Standard Edition or Enterprise Edition was purchased.

STANDARD EDITION

Static Library Version (*.LIB)

The object code of the library may be distributed while bound or linked into an .EXE format of one (1) application without payment of an additional license fee.

Dynamic Link Library Version (*.DLL, *.PLB, *.FLL)

The entire dynamic link library may be distributed in conjunction with one (1) application without payment of an additional license fee.

Licenses for additional copies of Licensed File Editing Facility ("LFEdit.EXE") or for more protected products may be purchased separately from Concept Software, Inc.

ENTERPRISE EDITION

Static Library Version (*.LIB)

The object code of the library may be distributed while bound or linked into an .EXE format of an unlimited number of applications without payment of an additional license fee.

Dynamic Link Library Version (*.DLL, *.PLB, *.FLL)

The entire dynamic link library may be distributed in conjunction with an unlimited number of applications without payment of an additional license fee.

Additional copies of LFEdit.EXE may be installed on your machines without payment of an additional license fee.

U.S. GOVERNMENT LICENSE GRANT - RESTRICTED RIGHTS

The software, manuals, documentation and other materials were developed at private expense by Concept Software, Inc., 1017 Woodall Drive, Altamonte Springs, FL  32714-7225.  Use, duplication, or disclosure by the U.S. Government is subject to restrictions as set forth in the Federal Acquisition Regulations (FARS - 49 CFR Ch. 1 Subpart 52.2) and other U.S. Government agency acquisition regulations such as Department of Defense Federal Acquisition Regulations (DFARS - 49 CFR Ch. 2 Subpart 227.72), as applicable.  The license grant to the U.S. Government shall be the same as that customarily provided to the public unless inconsistent with Federal procurement law.

OWNERSHIP

The Protection Plus Professional logo, product names, software, manuals, documentation and other materials and all copyright rights are owned by Concept Software, Inc.  Any copyright or trademark notices, product identification marking or description or notices of proprietary restrictions may not be removed.

COPYING PROHIBITED

The software, manuals and documentation are protected by U.S. copyright laws and international treaty provisions.  They may not be copied, except that one (1) copy of the software may be made for backup or archival purposes.  Any other copying is prohibited.

LIMITED WARRANTY

Concept Software, Inc. warrants for a period of ninety (90) days from the date of purchase that the magnetic media is free from defects in materials and workmanship under normal use and that the computer program will perform substantially in accordance with the user manual.

Any defective item must be returned, shipping prepaid, with proof of date of purchase such as receipt or invoice, during the warranty period to Concept Software, Inc., 1017 Woodall Drive, Altamonte Springs, FL  32714-7225.  The defective item must be received by Concept Software, Inc. no later than thirty (30) days after the end of the warranty period.

CONCEPT SOFTWARE, INC. MAKES NO OTHER WARRANTY, EXPRESS OR IMPLIED OF ANY KIND OR NATURE WHATSOEVER INCLUDING, WITHOUT LIMITATION, WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  THIS LIMITED WARRANTY GIVES YOU SPECIFIC LEGAL RIGHTS.  YOU MAY HAVE OTHERS, BECAUSE SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION OR LIMITATION OF IMPLIED WARRANTIES.

LIMITATION OF LIABILITY

Concept Software, Inc.'s liability for damages resulting from use of the computer program shall not exceed the amount of license fees paid by you to Concept Software, Inc. under this License Agreement.

Concept Software, Inc. shall not in any case be liable for damages incurred by third party users of applications which incorporate Concept Software, Inc.'s Protection Plus Professional copy protection or software licensing functions. Your implementation of Protection Plus Professional copy protection or software licensing functions is in no way influenced by Concept Software, Inc. its officers, employees or agents.

CONCEPT SOFTWARE, INC. SHALL NOT IN ANY CASE BE LIABLE FOR SPECIAL, INCIDENTAL, CONSEQUENTIAL, INDIRECT OR OTHER SIMILAR DAMAGES (INCLUDING WITHOUT LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS, BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION, OR ANY OTHER PECUNIARY LOSS) ARISING FROM THE USE OR INABILITY TO USE THE SOFTWARE, MANUAL, DOCUMENTATION OR OTHER MATERIALS, EVEN IF CONCEPT SOFTWARE, INC. HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.  BECAUSE SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION OR LIMITATION OF LIABILITY FOR CONSEQUENTIAL DAMAGES, THE ABOVE LIMITATION MAY NOT APPLY TO YOU.

BREACH OF AGREEMENT - TERMINATION

Any breach of one or more of the provisions of this License Agreement shall result in immediate termination of the License.  You shall then immediately discontinue use and return all copies of the software, manuals and documentation to Concept Software, Inc. or supply a certificate of destruction of all copies.  All provisions of this License Agreement which protect the rights of Concept Software, Inc. shall survive termination.

GENERAL

You are responsible for compliance with all laws and regulations governing export outside the United States of any product containing the software, such as obtaining and renewing licenses or permits and financial reporting obligations.

The headings used are for convenience only.

This agreement shall be governed by the laws of the State of Florida.


SOFTWARE PROBLEM REPORTING

This manual contains a description of the features and capabilities of the PPP system. However, if you have any questions left unanswered, or if you discover problems with any part of this package or its documentation, please contact your Account Manager, Customer Service Representative, or Technical Support Representative at (407) 786-4457, 9:00 AM to 5:00 PM EST Monday through Friday. FAX support is available at (407) 786-4458.

Concept Software, Inc. receives messages via E-Mail on the Internet at support@consoft.com. In most cases, messages will be acknowledged within 48 hours. Each acknowledgment will include an answer or an estimate of when an answer will be forthcoming. Be sure to visit our World Wide Web home page. This could include an update list of questions and answers and some helpful hints for using the PPP system. The URL is http://www.consoft.com/support.

For most efficient service, contact us electronically.  International users are requested to communicate with us electronically.

Concept Software, Inc. is not in the business of writing other company’s application code around the PPP system, so please do not call expecting this type of support.

SHORT TEST PROGRAMS

There could be some situations where your application will not work no matter what you do. The first thing to do is stop and think, what did I add last? Build your application block by block, getting each block to work before going on to the next.

By detecting the general area that you added when the problem occurred, you can back that part of the program out, see if the rest of it still works, and then try to get the offending routines to function. Try to break it down to the simplest form. If you are using a function or data structure you're not familiar with or have never used, check the documentation. Are you using it correctly? Are the arguments correct?

By creating short test programs that check the area that you are not sure of, you are isolating the problem and seeking to fix it. If you just received a compiler update and suddenly things stop working, incompatibility could be the suspect.

If you can supply Concept Software, Inc. with a stand-alone program of 25 lines or less, you will be able to obtain help much faster. Twenty page sample programs are difficult to use as diagnostic tools.

Be sure to read the Questions And Answers section before contacting Technical Support.


FEEDBACK/COMMENTS/SUGGESTIONS

Your feedback, comments, and suggestions regarding the PPP system, its manual, and our support is greatly appreciated. Feedback from our clients has resulted in modifications to the PPP system and its documentation providing a higher quality product. Thank you for your contributions.


TRADEMARK ACKNOWLEDGEMENTS

Protection Plus Professional

Concept Software, Inc.

CA-Clipper, CA-VO, ExoSpace

Computer Associates

Blinker

Blink, Inc.

Windows, FoxPro, Visual Basic, Visual C++

Microsoft Corporation

Crypto-Box

Marx International

Other brand and product names used in this manual may be registered trademarks of their respective owners. Their use in this manual is for identification purposes only.


CHANGES SINCE VERSION 3.0

The following is an overview of most of the changes of the Protection Plus Professional (PPP) system since Version 3.0 (V3).  It is very worthwhile to also read the section Software Licensing to learn about the features of the product.

LICENSE FILE REPLACES CONTROL FILE

The concept of a Control File and a Copy Protection file have merged into one License File.  This file contains all of the existing data contained in the Control File and Copy Protection file plus room for more user-defined fields.  The function pp_convertv3() was added in order to provide a one-way conversion from the two old files to the new License File format.

A License File can be stored in different locations, depending on the library used and the operating system currently running.  Refer to pp_lfcreate() for syntax and usage.

The License File can now accommodate the System, Hidden, and Read-Only file attributes.  These attributes along with the time/date stamp of the file are kept the same even after writing to the file.

Reading and writing variables contained in the License File is easier to accomplish and is enhanced for multi-user environments.

TRIGGER CODES REPLACE UNLOCK CODES

Unlock Codes have been replaced by Trigger Codes.  The concept behind Trigger Codes is exactly like Unlock Codes, except now there can be up to 50 different events per Trigger Code screen.

The Trigger Code generating functions are no longer located in the distributed DLL.  This adds extra security.

LIBRARY CHANGES

The PPP system libraries are no longer serialized.  In place of this security, the user chooses a string password for encrypting all data in the License File and chooses a seed number for the Trigger Code mechanism.  This allows multiple users and multiple applications to share the library and choose their own passwords. Because of this, renaming of the DLL is no longer necessary.

The Trigger Code generating functions are no longer located in the distributed DLL.  This adds extra security.  These functions are located in another library named TrgLib, purchased separately and included in the Enterprise version of PPP.

A version number is now stamped inside the DLL.  Strict version stamping and history will be kept and since the libraries are no longer serialized, updates for everyone can be posted on our Internet support page at http://www.consoft.com/support.

Replacing the Client Tracking System, a Windows-based License File Editing facility (LFEdit) is included to provide live editing of License Files and generation of Trigger Codes.

The security of pp_password() was enhanced.

LIBRARY IMPROVEMENTS / ADDITIONS

For Win32, a pp_compno() algorithm to retrieve the unique (MAC) address of any installed Ethernet LAN adapter was added.  This is a great resource for LAN-based applications.

We've added the functions pp_ndecrypt() and pp_nencrypt() to send numbers to remote applications via larger, encrypted numbers - e.g. When giving the user a Trigger Code to increase the number of allowed users, you can give them one code for the Trigger Mechanism and another number (approx. 6-8 digits) which tells PPP the new number of allowed users.  The user will have a difficult time forging the encryption algorithm.

It is possible to let the customer transfer a software license from one computer to another using a unique mechanism of PPP library function calls.  Although using Trigger Codes to transfer software license is the most secure, this new transfer mechanism is documented in the section Implementing Unsupervised License Transfers.

A 32-bit static library is available for Visual C++ users.  This provides greater security since the protection becomes bound to your executable file.

There are now two integrated expiration dates in the package - soft and hard expiration.  Hard expiration is similar to the way V3 operated.  Now, you can specify a soft expiration date of say, 30 days from the date of installation (you ship the license file with 0/0/0 in the soft expiration date field), but you mandate a hard expiration date of say, 12/31/97.  This way, the user can have a 30 day demo, but if they figure out how to re-install the package and gain 30 more days, they will never be able to run the software past the hard expiration date.

New sample code is provided with the package, showing off more features of the library.  These samples are also documented in the manual under Sample Applications Overview.

The function pp_upddate() now can be told when to force the update of the last used date/time fields rather than blindly performing this action.  In a Trigger Code routine, the function will be called with the flag set to force the date/time to be updated.  When the application exits, the flag is not set.  This eliminates the need to call pp_valdate() before calling pp_upddate().

The functions pp_timerstart() and pp_timercheck() were added to facilitate demo applications that only should run for a certain number of minutes.  The function pp_timerstart() is called at the beginning of the application and then pp_timercheck() is called at a key point in the application.  When the timer is expired, your application can display a message and stop working.

NETWORK SUPPORT

Simultaneous users can be counted accurately on most networks by using the new functions pp_semcount(), pp_semopen() and pp_semclose().

HARDWARE KEY INTEGRATION

It is now possible to easily store software licensing information in a Marx International Crypto-Box.  Basically, a portion of a License File structure is stored in the RAM area of either the Crypto-Box Versa or Crypto-Box 560.  This can be used to store critical information such as number of installations allowed or number of executions left.  By the very nature of the hardware key, this data is tamper-proof.

The integration allows temporary or permanent storage of licensing data in the key.  A neat new feature is the ability to program number of installations or other information, ship the key to the customer and let your application copy the software license information into its own License File for future use.  The key can then be move to another computer or removed completely.  This can be used to perform secure unsupervised transfers or allow a bulk number of installations without the requirement of the customer contacting you.  The licensing data in the key may be modified through the use of Trigger Codes.

OTHER THINGS YOU SHOULD KNOW

All applications must call pp_lfclose() before exiting to free resources used by pp_lfopen() .

We fixed the bug in pp_adddays() when adding more than 90 days and fixed the flaw in pp_npdate() that didn’t advance month because values were not passed by reference.

Removed Hard Drive Type algorithm in pp_compno() due to incompatibilities with compressed drives, etc.

Removed all references to Single Entry External and Multiple Entry External form of copy protection (all one now).  Instead, refer to the sections Network Fixed Licensing and Network Floating Licensing.

pp_upddate() will only update the last date / time used if the current time is greater than the last used time.  This makes it more difficult for the user to get around the timed expiration of applications.

Third parameter of pp_compno() now a string data type rather than a number.

The functions pp_setbit(), pp_clearbit(), and pp_testbit() renamed to pp_bitset(), pp_bitclear(), and pp_bittest().

pp_hdlockwr() has been replaced by pp_lfcreate().

pp_getdate() now has a day of week parameter.

pp_killprot() has been replaced by pp_filedelete().

pp_ucode() has been replaced by pp_tcode().

pp_initcf() has been replaced by pp_lfopen().

pp_advect() and pp_lanincr() have been replaced by pp_countinc().

pp_landecr() has been replaced by pp_countdec().

The following functions were removed since their functionality is duplicated in other functions:

•	pp_exect()

•	pp_exelimit()

•	pp_expdate()

•	pp_exptype()

•	pp_getregchar() - from V3 Win32 DLL

•	pp_setregchar() - from V3 Win32 DLL

•	pp_writecf()

•	pp_lanlimit()

•	pp_lanminus()

•	pp_lanplus()

•	pp_lanusers()

•	pp_nexect()

•	pp_nexelim()

•	pp_nexptype()

•	pp_nlanct()

•	pp_nlanlim()

•	pp_serial()

•	pp_unlock()


PREPARATION

The Protection Plus Professional (PPP) system is supplied on 3.5-inch diskettes. Please be sure to read the README.TXT file on the first diskette. The README.TXT file contains changes and/or corrections not reflected in this manual since the last printing. This file will be displayed when you install the software; however, you can also view this file using any ASCII text editor such as Notepad or display it at the DOS prompt by typing:

C:\>TYPE A:README.TXT | MORE  [ENTER]

If the file is too large to fit in one screen, the MORE pipe breaks the text into pages and prompts for a keypress between each page. Information in the README.TXT file, which may include modifications to the installation procedures of this product, takes precedence over information in this manual.

If you are upgrading from a previous version of the PPP system, be sure to read the section on Changes Since Version 3.0 .


INSTALLATION

For your convenience, the first diskette contains an Installation Executable File (SETUP.EXE). To install the PPP system, simply run SETUP.EXE by Using File Manager or Program Manager in Windows 3.X or Explorer or Start/Run from the Windows® 95 Taskbar.

License File Editor (LFEdit) requires Win32s to be installed on your computer if you are running Windows 3.x or Windows for Workgroups 3.x.  If you do not have the latest version of Win32s, they can be found at http://www.consoft.com/win32s or by contacting Technical Support.

Read and follow the procedure in Initial Setup in the LFEdit chapter. When completed with the initial setup, the PPP system is ready for use.

To get started quickly, refer to the Quick Start section.

Concept Software strongly encourages you to read and understand the Software Licensing and Questions and Answers chapters. Doing so helps you gain complete confidence in your use of the PPP system.


Upgrading from PPP Version 3.0
UPGRADING FROM VERSION 3.0

If you currently have a set of Client Tracking System (CTS) data from a previous version of the PPP system, you will be unable to use this data in Version 4.0 (V4).  This is because the CTS has been replaced by LFEdit - a License File Editing facility which does not contain databases like the V3 CTS.  A Windows-based CTS may be made available in the future.

An overview of the changes in the product can be found in the section Changes Since Version 3.0.

IMPORTANT

Be sure to read the Software Licensing chapter for a complete explanation of modifications since V3. More than likely, you will need to make changes to your source code.


FILENAME DESCRIPTIONS

SETUP.EXE installs the PPP system files in different directories on the destination hard drive.

MAIN DIRECTORY

The following table lists the contents of the Installation Root Directory (in alphabetical order) and includes a short description of each file.  The default Installation Root Directory is C:\PPP4 or C:\PROGRAM FILES\PPP4 depending on your current operating system.

Table 1 - Installation Root Directory

File	Description
LFEDIT.EXE	Win32 / Win32s Application used to create and edit License Files as well as generate Trigger Codes.
PPPV4.CNT	WinHelp Contents File for Table of Contents.
PPPV4.HLP	WinHelp help file for Windows. Contains the entire text from this manual, including the Table of Contents, Index, and full text searching capabilities.
README.TXT	Contains modifications and/or corrections to the PPP system. This information supersedes any information documented in this manual.
UNWISE.EXE	Un-install program.

LIBRARY (LIB) DIRECTORY

The following table lists the files in the Lib Directory (in alphabetical order) and includes a short description of each file.

Only the libraries ordered will appear in this directory.

Table 2 - Install\Library Directory

File	Description
KEYBL.LIB	Borland large-model C library Standard
KEYBLE.LIB	Borland large-model C library Enterprise
KEYCLP.LIB	CA-Clipper library - Summer ’87 Standard
KEYCLPE.LIB	CA-Clipper library - Summer ’87 Enterprise
KEYLBE16.DLL	Windows 16-bit Dynamic Link Library Enterprise
KEYLBE16.LIB	Visual C++ Import Library for KEYLBE16.DLL
KEYLBE32.DLL	Windows 32-bit Dynamic Link Library Enterprise
KEYLBE32.LIB	Visual C++ Import Library for KEYLBE32.DLL
KEYLIB.FLL	FoxPro/Win 2.5/2.6 library Standard
KEYLIB.PLB	FoxPro/DOS 2.5/2.6 library Standard
KEYLIB16.DLL	Windows 16-bit Dynamic Link Library Standard
KEYLIB16.LIB	Visual C++ Import Library for KEYLIB16.DLL
KEYLIB32.DLL	Windows 32-bit Dynamic Link Library Standard
KEYLIB32.LIB	Visual C++ Import Library for KEYLIB32.DLL
KEYLIBE.FLL	FoxPro/Win 2.5/2.6 library Enterprise
KEYLIBE.PLB	FoxPro/DOS 2.5/2.6 library Enterprise
KEYMSL.LIB	Microsoft large-model C library Standard
MACHNM1.EXE	KeyLib Win32 DLL required driver program
PPPMSLE.LIB	Microsoft large-model C library Enterprise
SKEYLE32.LIB	Visual C++ 32-bit Static Library Enterprise
SKEYLI32.LIB	Visual C++ 32-bit Static Library Standard
STRIGL32.LIB	Visual C++ 32-bit Static Library TrigLib
TRGLIB16.DLL	Windows 16-bit Dynamic Link Library TrigLib
TRGLIB16.LIB	Visual C++ Import Library for TRGLIB16.DLL
TRGLIB32.DLL	Windows 32-bit Dynamic Link Library TrigLib
TRGLIB32.LIB	Visual C++ Import Library for TRGLIB32.DLL

INCLUDE DIRECTORY

The following table lists the files in the Include Directory (in alphabetical order) and includes a short description of each file.

Table 4 - Install\Include Directory

File	Description
KEYLIB.CH	CA-Clipper 5.x include file. Contains several #define statements specific to the PPP system library.
KEYLIB.H	"C" include file. Contains prototypes and several #define statements specific to the PPP system library.

SAMPLES DIRECTORY

The following table lists the files in the Samples Directory (in alphabetical order) and includes a short description of each file.

Table 5 - Install\Samples Directory

File	Description
Access_2	Microsoft Access 2.0 sample code
Access_7	Microsoft Access 95 sample code
Clipper	CA-Clipper sample code
Delphi_1	Borland Delphi 1.0 sample code
Delphi_2	Borland Delphi 2.0 sample code
Fox_2x	FoxPro 2.5/2.6 sample code
VB3	Microsoft Visual Basic 3.0 sample code
VB4	Microsoft Visual Basic 4.0 sample code 16/32
VFox_3	Visual FoxPro 3.0 sample code (when available)

The above directories contain sub-directories which contain various sample applications.  These applications should be self-contained projects.  The sample applications included in the package are discussed in Sample Applications.


QUICK START

There are several key places in the manual which are listed here to help a new user get started using Protection Plus Professional (PPP).  Unfortunately, PPP can be used for both very simple and complex software licensing applications.  There will be some form of learning curve, so please be patient.

If you are unfamiliar with the features and components of PPP, read the Product Overview section.

Important information about the way PPP is licensed is found in the Software Licensing Methods and License Agreement sections.

If you are upgrading from Version 3 of PPP, refer to the Changes Since Version 3.0 section.

The Software Licensing section should be read in its entirety since it defines key concepts used throughout the product as well as illustrates how to accommodate different software licensing requirements.

The LFEdit Tutorial section contains step-by-step instructions on how to create a Product Definition, create a License File, and how to generate Trigger Codes using the License File Editing Facility (LFEdit).

The Sample Applications section describes the various source code installed with PPP that demonstrates how to implement different types of PPP features.  In some cases, you can copy this source code and paste it into your own application source code.

Finally, the Questions and Answers section answers many of the Frequently Asked Questions of our customers.


OVERVIEW - KEYLIB

This chapter has several sections dealing with including the KeyLib library in your applications using the Software Licensing functions of the Protection Plus Professional (PPP) system as well as the detailed syntax required for each function. This chapter is documented for all of the available PPP system library modules: CA-Clipper, FoxPro, "C"/DOS, and both 16- and 32-bit versions of the Windows Dynamic Link Library (DLL) and Static Libraries.

KeyLib is a function library used to implement the majority of the software licensing functionality of the PPP system.


COMPILING, LINKING, AND DISTRIBUTING YOUR APPLICATION

This section indicates any specific requirements that need to be followed when developing under the various compiler environments.

CAUTION

In order to complete the protection of an application, function calls to the PPP system library must be placed in the beginning of the source code of your application. This product does not protect anything without these function calls.

All function names used in the PPP system are preceded with a "pp_" prefix. This is to easily distinguish a name so that it is associated with the PPP system, and to keep application function names from conflicting.

WINDOWS DLL

The Windows DLL versions of the PPP system should be compatible with any Windows-based development environments that can call Windows DLLs. Care was taken to make sure the data types passed between the functions and the applications are basic as opposed to complex "C" style structures.

Due to the nature of the various Windows-based development environments having different ways of calling DLLs, consult the documentation of the language you are using or use the provided declaration files in the Sample Applications.

It is necessary to distribute the PPP system KeyLib 16- and/or 32-bit DLL with any application you send out. Be aware of any PPP licensing issues described in Software Licensing Methods.

All "C" application source files that make calls to functions in the PPP system library need to include one header file:

#include <keylib.h>

All Visual Basic projects should have the module PPP4.BAS added to them since this file contains the necessary "Declare" and Global Const statements necessary to interface with the library.

CAUTION

When using the Win32 DLL or Win32 Static Library, the driver file MACHNM1.EXE is required to be place on the user’s windows system directory.

The Win32 DLL communicates with this file when using the function pp_compno() .  This file should be copied to the windows system directory at the same time as the DLL itself.  The MACHNM1.EXE file used with the 32-bit version of the DLL cannot be renamed.

Any 16-bit "C" or C++ application calling KeyLib or TrigLib must use the Large memory model.

The Win32 DLL is dependent on the NETAPI32.DLL file which is distributed with Win95 and WinNT.  Make sure the proper NETAPI32.DLL version is loaded on the system in the event an error message is presented by Windows.

The following table indicates the various Windows DLLs and which ones are distributed:

KeyLib Standard	Distribute if you are not using the EZ Key™ features
KEYLIB16.DLL	Windows 16-bit Dynamic Link Library Standard
KEYLIB32.DLL	Windows 32-bit Dynamic Link Library Standard
MACHNM1.EXE	KeyLib Win32 DLL required driver program
	Import Libraries only used to link Visual C++ with above DLLs
KEYLIB32.LIB	Visual C++ Import Library for KEYLIB32.DLL
KEYLIB16.LIB	Visual C++ Import Library for KEYLIB16.DLL
KeyLib Enterprise	Distribute if you are using EZ Key™ features
KEYLBE16.DLL	Windows 16-bit Dynamic Link Library Enterprise
KEYLBE32.DLL	Windows 32-bit Dynamic Link Library Enterprise
MACHNM1.EXE	KeyLib Win32 DLL required driver program
	Import Libraries only used to link Visual C++ with above DLLs
KEYLBE16.LIB	Visual C++ Import Library for KEYLBE16.DLL
KEYLBE32.LIB	Visual C++ Import Library for KEYLBE32.DLL
TrigLib	NEVER DISTRIBUTED
STRIGL32.LIB	Visual C++ 32-bit Static Library TrigLib
TRGLIB16.DLL	Windows 16-bit Dynamic Link Library TrigLib
TRGLIB16.LIB	Visual C++ Import Library for TRGLIB16.DLL
TRGLIB32.DLL	Windows 32-bit Dynamic Link Library TrigLib
TRGLIB32.LIB	Visual C++ Import Library for TRGLIB32.DLL
WIN32 STATIC LIBRARY

It is required to call pp_initlib() before calling any other PPP system function.  It is also required to link in the library MPR.LIB and NETAPI32.LIB to avoid unresolved external errors when linking.  As noted above, you must also distribute MACHNM1.EXE.  When statically linking, you may need to tell Visual C++ to ignore the default LIBC.LIB.

Static Link	Use with Visual C++ 4.x
SKEYLE32.LIB	Visual C++ 32-bit Static Library Enterprise
SKEYLI32.LIB	Visual C++ 32-bit Static Library Standard
CA-CLIPPER

There are no special compilation instructions when using the PPP system with CA-Clipper. When using CA-Clipper 5.X, you can include the file KEYLIB.CH using the #include preprocessor directive. This defines several constants used by the functions in the library.

To include the PPP system library functions in your application, modify its linking procedures. To do so, add the KEYCLP.LIB file to the include library list. This file works with both CA-Clipper 5.X and Summer '87.

This library is compatible with ExoSpace and Blinker 3.X protected modes. The function pp_compnox() is used in place of pp_compno() when using ExoSpace, and pp_compnob() is used in place of pp_compno() when using Blinker 3.X protected mode. The documentation for pp_compnob() and pp_compnox() is identical to pp_compno(). When using the DUAL mode feature of Blinker 3.X, it is necessary to use the Blinker internal function to determine the current runtime environment (protected or real mode) and call the appropriate function (pp_compno() for real mode or pp_compnob() for protected mode).

Sample code is provided in the Samples\xBase directory.

FOXPRO 2.X FOR DOS/WIN AND VISUAL FOXPRO

The FoxPro documentation covers the FoxPro/DOS and FoxPro/Win libraries transparently. Visual FoxPro uses the Win32 DLL.  Sample code is provided in the Samples\xBase and Samples\VFox directories.  It is necessary to distribute the KeyFOXW.PLB with your FoxPro/DOS or KeyFOXW.FLL with your FoxPro/Win application.  For Visual FoxPro, it is necessary to distribute both the 32-bit KeyLib DLL and MACHNM1.EXE.


PARAMETER AND RETURN VALUE SYNTAX

The syntax listed in the Function Reference section specifies "C" style and Microsoft Visual Basic style parameters. For those unfamiliar with the "C" language, the following is a short explanation to help in the mapping procedure. The data types used in the function calls are from the standard Windows SDK Data Type format.

The following table lists the six types of parameter values.

Table 1 -  Parameter Data Types

Parameter	Description
LPSTR	Null-terminated character string or pointer to a string
INT	Signed integer
LPINT	Pointer to a signed integer
LONG	Signed long integer
LPDWORD	Pointer to unsigned doubleword (32 bits)
VOID	Function takes no parameters
The following table lists the four types of return values.

Table 2 - Return Data Types

Return Value	Description
LONG	Signed long integer
VOID	No return value. Also known as a procedure or subroutine as opposed to a function.
The following subsections provide translations of the parameters and return values for each of the libraries.

CA-CLIPPER, FOXPRO

A LPSTR data type is a character string enclosed in quotation marks. INT and LONG data types are numeric values. LPINT and LPDWORD data types are numeric values passed by reference, with the @ operator.  This is also symbolized with a ByRef keyword in the Syntax-VB prototypes.

When the return data type is a BOOL, TRUE refers to a logical value of .T., and FALSE refers to a logical value of .F.. When the return data type is INT or LONG, the data returned is a numeric value.

WINDOWS DLL

Sometimes, when it is necessary to return a complex piece of data (such as an expiration date), values are returned from functions through the parameters passed. This requires higher-level applications to pass a parameter value by reference as opposed to by value so that the function called can return the requested data in the variable passed by reference. In "C" terms, this is also known as passing a pointer to a variable. For example, the function pp_getvardate() is defined as follows:

VOID pp_getvardate(LONG handle, LONG var_no, LPLONG month, LPLONG day, LPLONG year)

This function retrieves the value of a date from one of the License File fields. The actual value is returned through the third, fourth and fifth parameters. When calling this function from a higher-level language, it is important to pass three numeric variables by reference so that this function can modify their contents with the date requested. Those variables can then be referenced in source code after calling this function.

All strings are considered to be passed by reference. This means that a pointer to the beginning of the screen is passed to a function rather than the entire string itself. Strings can be dealt with in two different ways. When they are inputs to the function being called, they can be variables or literal strings. For example, the function pp_lfopen() is defined as follows:

LONG pp_lfopen(LPSTR filename, LONG lftype, LPSTR password, LPLONG handle)

This returns a number indicating success/failure condition (refer to pp_errorstr() for a list of result codes) and has four parameters. The first is a string filename, the second is a numeric type, the third is a string password, and the fourth is a pointer to a number or a number variable passed by reference. In this example, filename is only an input to this function, so it is possible to call this function from a higher application with "progname.drv". However, when a function that is returning a string is called, enough space must be allocated in the variable to fit the entire length of the result returned. For example, the function pp_getvarchar() is defined as follows:

LONG pp_getvarchar(LONG handle, LONG var_no, LPSTR buffer)

This function, similar to pp_getvardate(), retrieves the value of a parameter in the License File and places it in the variable passed by reference as the third parameter. It is imperative that the string variable passed by reference is filled with enough spaces to fit the string being returned since the library function cannot make the string longer than what it was before the function was called.

All buffer string variables that are going to be used to retrieve data from this library should initialize the variable to 55 spaces before calling the function.

OTHER INFORMATION

The reference that follows lists both the manifest constants (in all uppercase) and their numeric equivalent (in brackets). The manifest constants are defined in the header file KEYLIB.H in the case of "C" language, KEYLIB.CH for CA-Clipper 5.X language, or PPP4.BAS for Visual Basic language. If you do not use one of these include files, the numeric equivalents are required.

In some cases it is important to check the return value from PPP system functions.  For example, when your application is in a demo mode and is cleaning up and exiting, it will normally call the function pp_upddate().  If for some reason, the library is not able to update the date and time in the file, the user could then continuously turn the date and time back to gain access to the application.  If you do not check the return value of pp_upddate(), your application will have no idea that anything went wrong with the date and time update.

CA-CLIPPER, FOXPRO

Both CA-Clipper and FoxPro are high-level languages. In both of these cases, strict data type checking is not enforced by the compiler when passing parameters to PPP system functions. Therefore, a value of -1 will be returned from all function calls that have parameters of the wrong data type or missing parameters.

•	Any function that has optional parameters, if required parameters are missing, the function will return a -1. Also, if the wrong data type is passed through any of the parameters, a -1 result occurs.

•	If incorrect parameters are passed to pp_hdserial(), although the documentation states that it will return a logical .T. or .F., a -1 will be returned. A logical true or false will only be returned when the parameters can be processed.

When you are debugging your code and data type mismatch errors occur, try printing the result of the function call to the screen to see if it is returning a -1. This error occurs when you have code such as the following:

if !pp_hdserial()

? "Error obtaining drive serial number"

endif

Since you did not pass pp_hdserial() the correct number of parameters, it will return -1. CA-Clipper and FoxPro do not like when you put an operator like the ! in front of a numeric piece of data. This generates a runtime error. Use the debugger or add a line of code like the following to help find the problem:

? pp_hdserial()

if !pp_hdserial()

? "Error hard coding serial number"

endif

When you get to this line of code, a -1 displayed on the screen. This clues you in immediately that you should check the syntax of the function you are calling.


FUNCTION REFERENCE

The following pages contain a list of PPP system library functions. They are listed in alphabetical order. Each function definition has the same format. The Applies to designation shows which libraries contain the listed function (“C”/DOS, CA-Clipper, FoxPro, Win16, or Win32). The syntax designation defines the use of each function, both in a "C" format (for Windows DLLs) and in a high-level format (for Visual Basic, CA-Clipper and FoxPro).

Most functions have a numeric return value and reference a list of error codes defined in pp_errorstr().  This function contains a table of error numbers and their text description.  The function pp_errorstr() can also be used to convert the number into text during program execution.

It is to your benefit to read the Software Licensing section before attempting to understand the library functions.

The following functions are available in the KeyLib library.

Function Name	Description
pp_adddays()	Adds or subtracts number of days from a given date
pp_bitclear()	Clears a bit in a bit field
pp_bitset()	Sets a bit in a bit field
pp_bittest()	Determines if a bit is set in a bit field
pp_cenum()	Returns a valid code entry number for trigger screen
pp_checksum()	Determines the checksum of the License File or any other file
pp_compno()	Returns the machine-identifying Computer ID Number
pp_convertv3()	Converts Version 3.0 CF / CPF to Version 4.0 LF
pp_copyadd()	Adds the current computer to the list of valid computers
pp_copycheck()	Determines if the current computer is in the list of authorized computers
pp_copydelete()	Removes the current computer from the list of valid computers
pp_copyget()	Gets the computer ID from the given slot, if filled
pp_countdec()	Decrements a number variable stored in License File
pp_countinc()	Increments a number variable stored in License File
pp_decrypt()	Decrypts a string given a password
pp_encrypt()	Encrypts a string given a password
pp_errorstr()	Converts a return value error code into a string
pp_expired()	Determines if an application has expired
pp_filedelete()	Unconditionally erases a file
pp_getcode()	Displays generic Trigger Code dialog box and returns Trigger Code number
pp_getdate()	Gets the current date from the system clock
pp_gettime()	Gets the current time from the system clock
pp_getvarchar()	Gets a character-type License File variable
pp_getvardate()	Gets a date-type License File variable
pp_getvarnum()	Gets a numeric-type License File variable
pp_hdserial()	Gets the DOS 4 or higher disk serial number
pp_initlib()	Initializes static library
pp_lanactive()	Determines if License File indicates multiple users are allowed
pp_lancheck()	Determines if workstation count is less than workstation limit
pp_lastday()	Determines the last date of the given month
pp_lfclose()	Closes the License File
pp_lfcopy()	Copies a License File to another location
pp_lfcreate()	Creates a file with the requested attributes
pp_lflock()	Locks the License File from other users
pp_lfopen()	Opens the License File and returns a handle
pp_lfunlock()	Unlocks the License File
pp_libtest()	Determines if the valid PPP system library has been altered or replaced
pp_ndecrypt()	Decrypts a number given a seed number
pp_ndecryptx()	Decrypts four numbers from string given a seed number
pp_nencrypt()	Encrypts a number given a seed number
pp_nencrypxt()	Encrypts four numbers into string given a seed number
pp_npdate()	Determines payment expiration date of next month
pp_password()	Encrypts a string that cannot be decrypted
pp_redir()	Determines if given drive letter is a redirected (network) drive
pp_semclose()	Closes the Network Semaphore File
pp_semcount()	Counts the number of available workstation licenses
pp_semopen()	Opens the Network Semaphore File in exclusive mode
pp_setvarchar()	Sets a character-type License File variable
pp_setvardate()	Sets a date-type License File variable
pp_setvarnum()	Sets a numeric-type License File variable
pp_tcode()	Decode which Trigger Code number was entered
pp_timercheck()	Determines if application timer has expired
pp_timerstart()	Starts application timer to expire in given number of minutes
pp_transfer()	Assists in transferring license from one machine to another
pp_upddate()	Updates the last date and time used fields in License File
pp_valdate()	Verifies current date / time > last used date / time fields


PP_ADDDAYS()

Adds or subtracts number of days from a given date

Applies to:

"C"/DOS, Win16, Win32

Syntax-VB:

Declare Sub pp_adddays(ByRef month As Long, ByRef day As Long, ByRef year As Long, ByVal days As Long)

Syntax-C:

VOID pp_adddays(LPLONG month, LPLONG day, LPLONG year, LONG days)

Arguments:

<month> is the begin date month

<day>   is the begin date day

<year>  is the begin date year

<days>  is the number of days to adjust the beginning date

Returns:

VOID - nothing. The end date is returned via the <month> <day> and <year> parameters.

Description:

Use this function to perform simple date arithmetic. Generally you would use it when setting the expiration date to a certain number of days from a given date. If you are using the PPP system to send out demo copies of your application and would like to have the ability to extend the demo expiration by a certain number of days, use this function to determine the new expiration date. This is true when you want to have the demo expire a certain number of days from today.

Example:

Dim month As Long, day As Long, year As Long, dow As Long

' first, get today's date

pp_getdate month, day, year, dow

' now, add 25 days to this date

pp_adddays month, day, year, 25

' finally, change the expiration type to "Demo" and set

' the new expiration date

Dim result As Long

result = pp_setvarchar(lfhandle, VAR_EXPIRE_TYPE, "D")

' make sure the variable was set

If result <> PP_SUCCESS Then

MsgBox "Authorization failed - Error #" & Str(result), 0, "Application Licensing Error"

End

End If

' set the expiration date. NOTE: we could have also set

' VAR_EXP_DATE_SOFT since the function pp_expire will

' check both the hard and soft date fields in determining

' if the application has expired.

result = pp_setvardate(lfhandle, VAR_EXP_DATE_HARD, month, day, year)

If result = PP_SUCCESS Then

MsgBox "Demo set to 25 days from today", 0, "Success!"

Else

  MsgBox "Authorization failed - Error #" & Str(result),

0, "Application Licensing Error"

End If

See Also:

PP_NPDATE(), PP_LASTDAY(), PP_GETDATE(), PP_SETVARDATE(), and PP_SETVARCHAR()


PP_BITCLEAR()

Clears a bit in a bit field

Applies to:

"C"/DOS, CA-Clipper, FoxPro, Win16, Win32

Syntax-VB:

Declare Function pp_bitclear(ByRef bit_field As Long, ByVal bit_number As Long) As Long

Syntax-C:

LONG pp_bitclear(LPDWORD bit_field, LONG bit_number)

Arguments:

<bit_field>  is a bit field variable to work on, passed by reference

<bit_number> is the bit number in the bit field to clear, 1 to 32

Returns:

The new value of the bit field with the selected bit cleared.

Description:

There are several long integers in the License File which may be used as bit-fields. A bit field contains 32 bits that can be used to store the state of binary attributes. The state of those attributes are either enabled or disabled.  This is typically used to license various modules or features on a pay-per-module basis.

This function along with pp_bittest() and pp_bitset() work together to provide you with total bit field manipulation capability.

Example:

' use a Trigger Code to disable a particular menu option

' assigns bit 5 to menu option 1

Global Const MENUOPTION_1 = 5

Sub get_code()

Dim month As Long, day As Long, year As Long

Dim ce_num As Long, unlock_code As Long

Dim result As Long, comp_no As Long

Dim bit_field As Long

' Get a valid code entry and computer number

ce_num = pp_cenum

comp_no = pp_compno COMPNO_BIOS, "", ""

print "Code entry number:  " & Str( ce_num )

print "Computer ID:  " & Str( comp_no )

print "Enter a code:  "

input unlock_code

' decode the number entered and see if it is valid

result = pp_tcode( unlock_code, ce_num, comp_no )

'  now, see if a correct code was entered and process it

Select Case result

Case 1

' disable the menu option #1

pp_getvarnum lfhandle, VAR_USER_DEF_2, bit_field

pp_bitclear bit_field, MENUOPTION_1

pp_setvarnum lfhandle, VAR_USER_DEF_2, bit_field

case 2

' enable the menu option #1

pp_getvarnum lfhandle, VAR_USER_DEF_2, bit_field

pp_bitset bit_field, MENUOPTION_1

pp_setvarnum lfhandle, VAR_USER_DEF_2, bit_field

Case 3

.. .. ..

Case Else

MsgBox "Invalid Code Entered", 0, "Trigger Codes"

End Select

See Also:

PP_BITTEST(), and PP_BITSET()


PP_BITSET()

Sets a bit in a bit field

Applies to:

"C"/DOS, CA-Clipper, FoxPro, Win16, Win32

Syntax-VB:

Declare Function pp_bitset(ByRef bit_field As Long, ByVal bit_number As Long) As Long

Syntax-C:

LONG pp_bitset(LPDWORD bit_field, LONG bit_number)

Arguments:

<bit_field>  is a pointer to the bit field variable on which to work.

<bit_number> is the bit number in the bit field to set, 1 to 32.

Returns:

The new value of the bit field with the selected bit set.

Description:

There are several long integers in the License File that may be used as bit-fields. A bit field contains 32 bits that can be used to store the state of multiple binary attributes. The state of those attributes are either enabled or disabled.  This is typically used to license various modules or features on a pay-per-module basis.

This function along with pp_bitclear() and pp_bittest() work together to provide you with total bit field manipulation capability.

Example:

Refer to pp_bitclear for an example of setting and clearing bitfields.

See Also:

PP_BITTEST() and PP_BITCLEAR()


PP_BITTEST()

Determines if a bit is set in a bit field

Applies to:

"C"/DOS, CA-Clipper, FoxPro, Win16, Win32

Syntax-VB:

Declare Function pp_bittest(ByVal bit_field As Long, ByVal bit_number As Long) As Long

Syntax-C:

LONG pp_bittest(DWORD bit_field, LONG bit_number)

Arguments:

<bit_field>  is a bit field on which to work

<bit_number> is the bit number in the bit field to test, 1 to 32

Returns:

PP_FALSE [0] (bit not set) or PP_TRUE [1] (bit set)

Description:

There are several long integers in the License File that may be used as bit-fields. A bit field contains 32 bits that can be used to store the state of multiple binary or on/off attributes. The state of those attributes are either enabled or disabled.  This is typically used to license various modules or features on a pay-per-module basis.

This function along with pp_bitclear() and pp_bitset() work together to provide you with total bit field manipulation capability.

Example:

' This application allows various options to be purchased.

' The user's purchased configuration is stored in one of

' the user-defined numerics.  We will check to see which

' options should be enabled.

Global Const DATAMODULE_1 = 1

Global Const DATAMODULE_2 = 2

Global Const FEATURE_1 = 3

Global Const FEATURE_2 = 4

Dim options As Long

pp_getvarnum lfhandle, VAR_USER_DEF_2, options

If pp_bittest options, DATAMODULE_1 Then

' Enable access to Data Module #1

Else If pp_bittest options, DATAMODULE_2 Then

' Enable access to Data Module #2

Else If pp_bittest options, FEATURE_1 Then

' Enable Feature #1

Else If pp_bittest options, FEATURE _2 Then

' Enable Feature #2

End If

See Also:

PP_BITSET() and PP_BITCLEAR()


PP_CENUM()

Returns a valid code entry number for trigger screen

Applies to:

"C"/DOS, CA-Clipper, FoxPro, Win16, Win32

Syntax-VB:

Declare Function pp_cenum As Long

Syntax-C:

LONG pp_cenum( VOID )

Returns:

The current code entry number

Description:

Generates a random number for the Trigger Code system. This function along with pp_tcode() is the backbone to the PPP trigger system library package.

It is this random number that makes each Trigger Code session unique.

Example:

Refer to pp_bitclear() for an example of the use of this function.

See Also:

PP_TCODE() and PP_CTCODES()


PP_CHECKSUM()

Determines the checksum of the License File or any other file

Applies to:

"C"/DOS, CA-Clipper, FoxPro, Win16, Win32

Syntax-VB:

Declare Function pp_checksum(ByVal filename As String, ByRef checksum As Long) As Long

Syntax-C:

LONG pp_checksum(LPSTR filename, LPLONG checksum)

Arguments:

<filename> is the name of the file to calculate the checksum

<checksum> is the buffer to place the checksum of the License File

Returns:

Refer to pp_errorstr() for a table of possible return codes and their meaning.  The checksum is returned in <checksum> if the function is successful.

Description:

Calculates a checksum for the License File referenced by the <filename>.  This can be used if you want to store this checksum of a file or DLL in a remote place so you can determine if the License File has been replaced or altered since the application was last executed.

When using this function on a License file, the return value will not be the same value as pp_getvarnum() with VAR_LF_CHECKSUM.

Example:

' *** Assume that oldchecksum is the checksum of the

' license file when we last exited the application.

' It should have been saved in a remote place to make

' sure the user hasn't restored the License File from

' a backup.

Dim checksum As Long, result As Long

result = pp_checksum(App.Path & "\example.lf", checksum)

If ((result<>PP_SUCCESS) Or (checksum<>oldchecksum)) Then

' Deny program access to the client since the License

' File has been altered.

MsgBox "Access denied", 0, "Application Error"

End If


PP_COMPNO()

Return the machine-identifying Computer ID Number

Applies to:

"C"/DOS, CA-Clipper, FoxPro, Win16, Win32

Syntax-VB:

Declare Function pp_compno(ByVal type As Long, ByVal filename As String, ByVal hard_drive As String) As Long

Syntax-C:

LONG pp_compno(LONG type, LPSTR filename, LPSTR hard_drive)

Arguments:

<type>      is a bit field containing which parameters to use to ID computer. The following types can be used in any combination:

COMPNO_BIOS     [1]- uses the ROM BIOS (keyed to motherboard)

COMPNO_HDSERIAL [2]- uses the DOS 4.0 or higher hard drive serial number

COMPNO_HDLOCK   [4]- uses a "non-moveable" file approach to detect copies

COMPNO_HDTYPE   [8]- reserved

COMPNO_NETNAME [16]- uses network file server name and volume path of drive <cHardDrive>.  Also accepts Universal Naming Convention (UNC) network path names (e.g. \\SERVER\SHARE\PATH)

COMPNO_MACADDR [32]- uses Ethernet (MAC) address of any installed Ethernet (LAN) adapter

<filename>   is a parameter used only when using COMPNO_HDLOCK type. Otherwise, pass a NULL string ( "" ). When this is passed, it must be the name of an existing file in the CURRENT directory. It must be in the form of NNNNNNNN.EEE which is the name and extension padded with spaces if necessary. This string MUST be 12 characters long and MAY NOT contain a path.

<hard_drive> is a parameter needed only if you are using either the COMPNO_HDSERIAL, or COMPNO_NETNAME types. It is the character of the drive to use. This character string MUST be uppercase.  For Windows libraries, if a ZERO string ( "0" ) is passed, the drive Windows is installed on will be used, otherwise the current drive will be used.

Returns:

The computer number or ID generated from the specified algorithm(s) of the machine or network.

Description:

The pp_compno() function is used to produce a computer "number" or ID.  This number is a way of identifying a particular machine or network for functions such as pp_copyadd() and pp_copycheck().  It is also used in generating trigger codes. The PPP system has the ability to use the ROM BIOS, DOS 4.0 or higher disk serial number, a hard drive security lock, and/or the network drive number.

In DOS applications, in order to use "0" for hard_drive with the COMPNO_HDSERIAL or to use COMPNO_HDLOCK, an application cannot run in the DOS path. This restriction exists when an application can be executed from a different drive or directory than where it resides.

CAUTION

COMPNO_HDSERIAL and COMPNO_HDLOCK will not work on network drives since they are not File Allocation Table (FAT) based.

When using COMPNO_HDLOCK, the function pp_lfcreate() can be used to create a blank file for this algorithm to track.

Refer to the Operating System Compatibility matrix for compatibility issues with various operating systems.

Example:

' The application may run on either a network server or an

' individual workstation.  We will get the drive letter of

' the application path and check to see if it is a network

' drive using the pp_redir function. If it is a network

' drive then we will use a computer number generated with

' the NETNAME algorithm.  Otherwise it must be local

' workstation in which case we will use a computer number

' generated with a combination of the ROM BIOS and Hard

' Drive serial number to "lock" the application to this

' computer.

Dim compno As Long, result As Long

Dim AppDrive As String

AppDrive = Mid(App.Path, 1, 1)	 ' Get the drive letter

AppDrive = UCase(AppDrive)	 ' Make it uppercase

If pp_redir(AppDrive) Then

compno = pp_compno(COMPNO_NETNAME, "", AppDrive)

  result = pp_copyadd(lfhandle, 0, compno)

Else

compno = pp_compno(COMPNO_BIOS + COMPNO_HDSERIAL, "", AppDrive)

  result = pp_copyadd(lfhandle, COPYADD_ERASEALL, compno)

End If

See Also:

PP_COPYADD(), PP_TCODE(), and PP_CTCODES()


PP_CONVERTV3()

Converts Version 3.0 CF / CPF to Version 4.0 LF

Applies to:

"C"/DOS, CA-Clipper, FoxPro, Win16, Win32

Syntax-VB:

Declare Function pp_convertv3(ByVal handle As Long, ByVal v3_cf As String, ByVal v3_cpf As String, ByVal v3_sn As Long) As Long

Syntax-C:

LONG pp_convertv3(LONG handle, LPSTR v3_cf, LPSTR v3_cpf, LONG v3_sn)

Arguments:

<handle> is the handle to the License File given by pp_lfopen()

<v3_cf>  is the path and filename of the Version 3.0 control file

<v3_cpf> is the path and filename of the Version 3.0 copy protection file

<v3_sn>  is the serial number of your Version 3.0 library

Returns:

Refer to pp_errorstr() for a table of possible return codes and their meaning.  Typically, PP_SUCCESS [1] (file was converted) is returned.

Description:

This function performs a one-way conversion of the Version 3.0 control file and copy protection file to the Version 4.0 format.  It is not possible to write to Version 3.0 control files or copy protection files.  If you only wish to convert a control file or copy protection file, fill in the appropriate name and leave the other parameter with a null string "".

Some of the fields used in the V3 Control File have been deleted in the License File format.  These fields are automatically copied into the user-defined fields in the License File.  The following table shows where the fields are moved:

V3 Field	V4 Field
Product Name	User-defined character 2
Distributor	User-defined character 3
PP Company	User-defined character 4
PP Address 1	User-defined character 5
PP Address 2	User-defined character 6
PP Address 3	User-defined character 7
PP Phone	User-defined character 8
PP Fax	User-defined character 9
User-defined 2	User-defined number 1
User-defined 3	User-defined number 2
User-defined 4	User-defined date 1
Example:

' Open a new license file.  Then convert the old

' control file and and copy protection file.  The

' converted data  will be copied to new license

' file.

Dim result As Long, lfhandle As Long

result = pp_lfopen(App.Path & "\example.lf", , LF_FILE, "password", lfhandle)

result = pp_convertv3(lfhandle, App.Path & "\sample.ini", App.Path & "\sample.ppp", 9505)

If result <> PP_SUCCESS Then

MsgBox "Encountered error number " & Str(result)

End

End If


PP_COPYADD()

Adds the current computer to the list of valid computers

Applies to:

"C"/DOS, CA-Clipper, FoxPro, Win16, Win32

Syntax-VB:

Declare Function pp_copyadd(ByVal handle As Long, ByVal flags As Long, ByVal comp_num As Long) As Long

Syntax-C:

LONG pp_copyadd(LONG handle, LONG flags, LONG comp_num)

Arguments:

<handle>   is the handle to the License File given by pp_lfopen()

<flags>    sets miscellaneous options, defined as:

COPYADD_ADDDUPE  [1] - adds the given <comp_num> even if number is in list of authorized computers already

COPYADD_ERASEALL [2] - deletes all entries in the list of authorized computers before adding this one

<comp_num> is the identifying number of this computer.  Under most conditions, the function pp_compno() will be used to generate this number.

Returns:

Refer to pp_errorstr() for a table of possible return codes and their meaning.  Typically, PP_SUCCESS [1] (ID was added) is returned.

Description:

Adds the current computer to the list of valid computers.  If the current computer ID is already in the list and COPYADD_ADDDUPE is not set in the <flags> parameter, an error code is returned.  The variable VAR_AUTHORIZED_COMPS returns the number of authorized computers. Up to 500 computer IDs can be stored in one License File.

Changes to the list of valid computers will affect the variable VAR_AUTHORIZED_COMPS which reflects the number of authorized computers.

Example:

' Authorize only this computer. Delete any other

' authorized computers

Dim result As Long, compno As Long

compno = pp_compno(1,"","")

result = pp_copyadd(lfhandle, COPYADD_ERASEALL, compno)

If result = PP_SUCCESS Then

' This computer is now authorized which means that a

' call to pp_copycheck will return PP_SUCCESS

End If

See Also:

PP_LFOPEN(), PP_COPYCHECK(), PP_COPYDELETE(), and PP_COMPNO()


PP_COPYCHECK()

Determines if the current computer is in the list of authorized computers

Applies to:

"C"/DOS, CA-Clipper, FoxPro, Win16, Win32

Syntax-VB:

Declare Function pp_copycheck(ByVal handle As Long, ByVal action As Long, ByVal comp_num As Long) As Long

Syntax-C:

LONG pp_copycheck(LONG handle, LONG action, LONG comp_num)

Arguments:

<handle>   is the handle to the License File given by pp_lfopen()

<action>   is one of the following types:

ACTION_MANUAL  [0] - unlicensed workstations denied access

ACTION_AUTOADD [1] - additional workstations licensed automatically

<comp_num> is the identifying number of this computer.  Under most conditions, the function pp_compno() will be used to generate this number.

Returns:

Refer to pp_errorstr() for a table of possible return codes and their meaning. Typically, only PP_FALSE [0] (not authorized) or PP_TRUE [1] (authorized), is returned.

Description:

Determines if the current computer is in the list of authorized computers.  If the value of <comp_num> is located in the list of authorized computers, this function returns PP_TRUE [1].  If <comp_num> is not located in the list of authorized computers and <action> is set to COPY_ADD_MANUAL, an error condition will be returned.  If <action> is set to COPY_ADD_AUTO instead and if the number of current users is less than the number of allowed LAN users, <comp_num> will be added to the list of authorized computers and the number of current LAN users will be incremented.

Refer to the explanations of Fixed Licensing and Floating Licensing in the Software Licensing section for more information on the use of the <action> flag.

Changes to the list of valid computers will affect the variables VAR_AUTHORIZED_COMPS and VAR_LAN_COUNT which reflect the number of authorized computers and number of current computers respectively.

Example:

' Check if this computer is authorized.

Dim result As Long, compno As Long

compno = pp_compno(1,"","")

result = pp_copycheck(lfhandle, COPY_ADD_MANUAL, compno)

If (result <> PP_TRUE) Then

MsgBox "This computer is not authorized!"

Unload Me

End If

See Also:

PP_LFOPEN(), PP_COPYADD(), PP_COPYDELETE(), and PP_COMPNO()


PP_COPYDELETE()

Removes the current computer from the list of valid computers

Applies to:

"C"/DOS, CA-Clipper, FoxPro, Win16, and Win32

Syntax-VB:

Declare Function pp_copydelete(ByVal handle As Long, ByVal comp_num As Long) As Long

Syntax-C:

LONG pp_copydelete(LONG handle, LONG comp_num)

Arguments:

<handle>   is the handle to the License File given by pp_lfopen()

<comp_num> is the identifying number of this computer.  Under most conditions, the function pp_compno() will be used to generate this number.  If -1 is passed to this function, all authorized computer IDs will be deleted and the number of authorized computers (variable VAR_AUTHORIZED_COMPS) will be set to 0.

Returns:

Refer to pp_errorstr() for a table of possible return codes and their meaning. Typically, only PP_SUCCESS [1] (ID was removed) or ERR_COMPNO_NOT_FOUND [24], is returned.

Description:

Deletes the current computer from the list of authorized computers.  If the current computer is not in the list of authorized computers, an error code will be returned. Note that when a Computer ID is deleted in the middle of the list, the computer number slots are automatically renumbered.

Example:

Refer to pp_copyget() for an example of deleting authorized computers.

See Also:

PP_LFOPEN(), PP_COPYCHECK(), PP_COPYADD(), PP_COMPNO(), and PP_COPYGET()


PP_COPYGET()

Gets the Computer ID from the given slot, if filled

Applies to:

"C"/DOS, CA-Clipper, FoxPro, Win16, Win32

Syntax-VB:

Declare Function pp_copyget(ByVal handle As Long, ByVal slot As Long, ByRef comp_num As Long) As Long

Syntax-C:

LONG pp_copyget(LONG handle, LONG slot, LPLONG comp_num)

Arguments:

<handle>   is the handle to the License File given by pp_lfopen()

<slot>     is the authorized computer ID to return, between 1 and 500

<comp_num> is the location to place the variable data

Returns:

Refer to pp_errorstr() for a table of possible return codes and their meaning.  Typically, PP_SUCCESS [1] (ID was retrieved) is returned.

Description:

Retrieves the Computer ID stored in the given <slot>.  This function is typically used when you want to build a list of valid Computer IDs.  Note that when a Computer ID is deleted in the middle of the list with pp_copydelete(), the computer number slots are automatically renumbered.

Example:

Dim result As Long, NumComps As Long, compno As Long

' See how many authorized computers we have

result = pp_getvarnum(lfhandle, VAR_AUTHORIZED_COMPS, NumComps)

' Delete all comuters

result = pp_copydelete(lfhandle, -1)

result = pp_getvarnum(lfhandle, VAR_AUTHORIZED_COMPS, NumComps)	' NumComps = 0

' Add some computers

result = pp_copyadd(lfhandle, COPYADD_ADDDUPE, 111)

result = pp_copyadd(lfhandle, COPYADD_ADDDUPE, 222)

result = pp_copyadd(lfhandle, COPYADD_ADDDUPE, 333)

result = pp_getvarnum(lfhandle, VAR_AUTHORIZED_COMPS, numComps)	' NumComps = 3

' Delete the computer at slot 2

result = pp_copyget(lfhandle, 2, compno) ' compno = 222

result = pp_copydelete( lfhandle, compno)

' The computer at slot 3 has moved down to slot 2

result = pp_copyget(lfhandle, 2, compno) ' compno = 333

result = pp_getvarnum(lfhandle, VAR_AUTHORIZED_COMPS, numComps)	' NumComps = 2

result = pp_copyget(lfhandle, 3, compno)

' ERROR: result = ERR_SLOT_EMPTY

See Also:

PP_LFOPEN(), PP_COPYADD(), PP_COPYDELETE(), and PP_COPYCHECK()


PP_COUNTDEC()

Decrements a number variable stored in License File

Applies to:

"C"/DOS, CA-Clipper, FoxPro, Win16, Win32

Syntax-VB:

Declare Function pp_countdec(ByVal handle As Long, ByVal var_no As Long) As Long

Syntax-C:

LONG pp_countdec(LONG handle, LONG var_no)

Arguments:

<handle> is the handle to the License File given by pp_lfopen()

<var_no> is the variable number inside the License File to be decremented

Returns:

Refer to pp_errorstr() for a table of possible return codes and their meaning.  Typically, PP_SUCCESS [1] (value was decremented) is returned.

Description:

Decrements a numeric value stored in the License File.  There are several different numeric values in the License File.  The variable numbers are listed in the function description for pp_getvarnum().

Typically, this function is used to decrement the number of active workstations or current number of licensed workstations.

This function will not allow the counter to go below zero.

Example:

Refer to the pp_countinc()example.

See Also:

PP_COUNTINC() and PP_GETVARNUM()


PP_COUNTINC()

Increments a number variable stored in License File

Applies to:

"C"/DOS, CA-Clipper, FoxPro, Win16, Win32

Syntax-VB:

Declare Function pp_countinc(ByVal handle As Long, ByVal var_no As Long) As Long

Syntax-C:

LONG pp_countinc(LONG handle, LONG var_no)

Arguments:

<handle> is the handle to the License File given by pp_lfopen()

<var_no> is the variable number inside the License File to be incremented

Returns:

Refer to pp_errorstr() for a table of possible return codes and their meaning. Typically, PP_SUCCESS [1] (value was incremented) is returned.

Description:

Increments a numeric value stored in the License File.  There are several different numeric values in the License File.

Typically, this function is used to increment the execution counter, number of active workstations, or current number of licensed workstations.

The execution counter is typically incremented once just before the main screen of an application is executed.  For applications that limit features other than executions (such as printing a limited number of reports), this function could be called whenever the function to be limited is called.

Example:

' This example assumes that the expiration type is “E”.

' We will check to see if the execution limit has been

' reached otherwise we will increment the expiration count

' and continue on with the application.

If pp_expired() Then

' Execution limit has been exceeded.

  MsgBox "Demo has expired!", 0, "Application Error"

  Unload Me	' Exit program

Else

' Continue on with the application.

    result = pp_countinc(lfhandle, VAR_EXP_COUNT)

End If

See Also:

PP_EXPIRED() and PP_COUNTDEC()


PP_DECRYPT()

Decrypts a string given a password

Applies to:

"C"/DOS, CA-Clipper, FoxPro, Win16, and Win32

Syntax-VB:

Declare Sub pp_decrypt(ByVal instring As String, ByVal pwstring As String, ByVal retstring As String)

Syntax-C:

VOID pp_decrypt(LPSTR instring, LPSTR pwstring, LPSTR retstring)

Arguments:

<instring>  is a character string to be decrypted. The buffer limit is 500 characters.

<pwstring>  is a character string of the password used during the encryption process. The password must match to have valid data. The password must be at least 3 characters long.

<retstring> is a buffer to place the decrypted string.

Returns:

Blank string - unsuccessful, Decrypted data - successful

Description:

This function will decrypt a given string using a password for security. The data will not be retrievable unless the same password is used as was used during the pp_encrypt() function.

Note that <retstring> must be initialized to a length of at least 20 characters longer than <instring> before calling this function.

CAUTION

If an encrypted string is stored in a database or any other kind of field that might right-pad the string with spaces, it is critical to remove trailing spaces before passing the string to pp_decrypt() or the decrypted string will be corrupted.

Example:

Refer to pp_encrypt() for an example of both pp_encrypt() and pp_decrypt().

See Also:

PP_ENCRYPT() and PP_PASSWORD()


PP_ENCRYPT()

Encrypts a string given a password

Applies to:

"C"/DOS, CA-Clipper, FoxPro, Win16, Win32

Syntax-VB:

Declare Sub pp_encrypt(ByVal instring As String, ByVal pwstring As String, ByVal retstring As String)

Syntax-C:

VOID pp_encrypt(LPSTR instring, LPSTR pwstring, LPSTR retstring)

Arguments:

<instring>  is a character pointer to the string to be encrypted. Up to 500 characters.

<pwstring>  is a character pointer to the password used.  The password must be used in the decryption process to have valid data. The password must be at least three characters long.

<retstring> is a buffer to place the decrypted string.

Returns:

Blank string - unsuccessful, Encrypted data - successful

Description:

This function will encrypt a given string using a password for security. The data will not be retrievable unless the same password is used to decrypt the data that was used during this function.

Example:

' Encrypt the data then decrypt it. Remember that the

' same password used for encryption must be used for

' decryption.

Dim encryptedStr As String * 50	   'Make strings big enough

Dim decryptedStr As String * 50

' Encrypt a test string into encryptedStr using "abc"

' as a password.  Note that the size of encryptedStr is

' more than 20 char larger than the test string

pp_encrypt “encryption test data”, "abc", encryptedStr

' Now decrypt the encrypted string using the same "abc"

' as a password.

pp_decrypt encryptedStr, "abc", decryptedStr

' Now decryptedStr equals “encryption test data”.

See Also:

PP_DECRYPT() and PP_PASSWORD()


PP_ERRORSTR()

Converts a return value error code into a string

Applies to:

"C"/DOS, CA-Clipper, FoxPro, Win16, Win32

Syntax-VB:

Declare Sub pp_errorstr(ByVal number As Long, ByVal buffer As String)

Syntax-C:

VOID pp_errorstr(LONG number, LPSTR buffer)

Arguments:

<number> is the number that was returned from a PPP function

<buffer> is the buffer to place the error message

Returns:

VOID - nothing. The error string is returned in the buffer.

Description:

This function is used for debugging. When a PPP system function returns a condition other than PP_SUCCESS [0], this function can be used to retrieve an error message for printing purposes.

Note that there are two types of functions in the PPP system - ones that a return code of PP_SUCCESS [1] is expected and ones that either a PP_TRUE [1] or PP_FALSE [0] is expected.  In either case, a number other than one or zero indicates that the function could not be completed.

Note that <buffer> must be initialized to a length of at least 50 characters before calling this function.

The following table is an exhaustive list of all of the possible error codes that may be returned from the PPP library.

ERROR NUMBER	DEFINE
0	PP_FALSE
1	PP_TRUE or PP_SUCCESS
2	ERR_INVALID_ATTRIBUTES
3	ERR_CANNOT_CHANGE_ATTRIBS
4	ERR_HFILE_ERROR
5	ERR_CANNOT_WRITE_FILE
6	ERR_CANNOT_CLOSE_FILE
7	ERR_CANNOT_OPEN_FILE
8	ERR_CANNOT_READ_FILE
9	ERR_CANNOT_CREATE_FILE
10	ERR_CANNOT_DELETE_FILE
11	ERR_FILE_WAS_CREATED
12	ERR_INVALID_PASSWORD
13	ERR_WRONG_PASSWORD
14	ERR_INCORRECT_PARAMETERS
15	ERR_FILE_MISSING
16	ERR_MEMORY_ALLOCATION
17	ERR_MEMORY_FREE
18	ERR_MEMORY_LOCK (invalid LF handle given)
19	ERR_SLOT_NUM_INVALID
20	ERR_SLOT_EMPTY
21	ERR_SLOTS_FULL
22	ERR_SLOT_ALREADY_ASSIGNED
23	ERR_NET_LIC_FULL
24	ERR_COMPNO_NOT_FOUND
25	ERR_VAR_NO_INVALID
26	ERR_SOFT_EXPIRATION
27	ERR_EXPTYPE_INVALID
28	ERR_EXP_DATE_EMPTY
29	ERR_STRING_TOO_LONG
30	ERR_CURRENT_DATE_OLDER
31	ERR_CANNOT_LOCK_FILE
32	ERR_WRONG_LF_VERSION
33	ERR_CORRUPT_LICENSE_FILE
34	ERR_SEM_FILE_LOCKED
35	ERR_CORRUPT_CONTROL_FILE
36	ERR_WRONG_CF_SERIAL_NUM
37	ERR_LF_LOCKED
38	ERR_LF_CHECKSUM_INVALID
39	ERR_NOT_APPLICABLE
40	ERR_NOT_IMPLEMENTED_YET
41	ERR_FILE_EXISTS
42	ERR_REGISTRY_OPEN
43	ERR_REGISTRY_QUERY
44	ERR_REGISTRY_CLOSE
45	ERR_REGISTRY_READ
46	ERR_REGISTRY_SET
47	ERR_CBOX_NOT_PRESENT
48	ERR_CBOX_WRONG_TYPE
49	ERR_CBOX_READ_RAM1_ERROR
50	ERR_CBOX_READ_RAM2_ERROR
51	ERR_CBOX_WRITE_RAM1_ERROR
52	ERR_CBOX_WRITE_RAM2_ERROR
53	ERR_CBOX_ID1_ERROR
54	ERR_CBOX_ID2_ERROR
55	ERR_CBOX_ID3_ERROR
56	ERR_VAR_NOT_AVAILABLE
Example:

Dim result as Long

Dim errBuf As String * 50

' Set the expiration type

result = pp_setvarchar( lfhandle, VAR_EXPIRE_TYPE, “D” )

If (result <> PP_SUCCESS) Then

' Something went wrong - display an error message

pp_errorstr result, errBuf

MsgBox errBuf, 0, "Application Error"

End If


PP_EXPIRED()

Determines if an application has expired

Applies to:

"C"/DOS, CA-Clipper, FoxPro, Win16, Win32

Syntax-VB:

Declare Function pp_expired(ByVal handle As Long) As Long

Syntax-C:

LONG pp_expired(LONG handle)

Arguments:

<handle> is the handle to the License File given by pp_lfopen()

Returns:

Refer to pp_errorstr() for a table of possible return codes and their meaning.  Typically, only PP_FALSE [0] (not expired), PP_TRUE [1] (expired), or ERR_SOFT_EXPIRATION is returned.

Description:

This function performs one of two tests, depending on the value of the product expiration type stored in the License File . If the expiration type is "N" the product is automatically not expired.  For an expiration type of "E" a numeric test is performed.  If the expiration type is anything else, a date comparison is performed.  There are two expiration dates available in the License File - a soft expiration and a hard expiration.  The hard expiration date is tested first.  If the current date is past the hard expiration date, the function automatically returns 1.  If not, if the current date is past the soft expiration date, ERR_SOFT_EXPIRATION is returned.  Refer to soft versus hard expiration for information on the use of these two expiration dates.  The following types of expiration are allowed:

NO_EXPIRATION  "N" - 0 is returned always

EXE_LIMIT      "E" - 1 is returned if the execution count has reached the execution limit

SHAREWARE_VER, PAYMENT_LIMIT, or DEMO_VERSION "S", "P", "D" - 1 is returned if the current system date has exceeded the hard expiration date, ERR_SOFT_EXPIRATION if the current system date has exceeded the soft expiration date, or 0 otherwise.

Note that if you only have one expiration date, you should always use the HARD expiration date and leave the SOFT expiration date 0/0/0.

CAUTION

If an application has expired (by date), it is important to perform a pp_upddate(). This is so that the combination of date checking and expiration date checking prohibits unauthorized use of your application. This avoids a client attempting to back up the system date of a computer allowing the client to back into the application. If the application calls pp_upddate() and a client attempts to back up a system date before the expiration date, the program will fail the pp_valdate() check.

Example:

Dim str As String

If pp_expired(lfhandle) Then

str = "Sorry, the demo for this product has expired!"

  str = str + “ Please call and order from Concept”

str = str + “Software at (407) 786-4457”

MsgBox str, 0, "Application Error"

  ' Update the last used date & time so the user won’t be

' able to set the system date back

  pp_upddate lfhandle, 0

End If

See Also:

PP_UPDDATE()


PP_FILEDELETE()

Unconditionally erases a file

Applies to:

"C"/DOS, CA-Clipper, FoxPro, Win16, Win32

Syntax-VB:

Declare Function pp_filedelete(ByVal file As String) As Long

Syntax-C:

LONG pp_filedelete(LPSTR file)

Arguments:

<file> is the name of the file to be deleted

Returns:

Refer to pp_errorstr() for a table of possible return codes and their meaning.  Typically, PP_SUCCESS [1] (file was deleted) is returned.

Description:

This function is used to unconditionally delete a file.  It can be used to delete a License File, network semaphore file, COMPNO_HDLOCK file, or any other file.

Example:

Dim result As Long

result = pp_filedelete(App.Path & "\product.lf")

If (result = PP_SUCCESS) Then

MsgBox "File erased!", 0, ""

End If

See Also:

PP_LFCREATE()


PP_GETCODE()

Displays generic Trigger Code dialog box and returns Trigger Code number

Applies to:

Win32

Syntax-VB:

Declare Function pp_getcode(ByVal str_title As String, ByVal str_cenum As String, ByVal str_comp As String, ByVal str_code As String) As Long

Syntax-C:

LONG pp_getcode(LPSTR str_title, LPSTR str_cenum, LPSTR str_comp, LPSTR str_code)

Arguments:

<str_title> is the string to display on the title of the dialog box

<str_cenum> is the string to display next to the code entry number

<str_comp>  is the string to display next to the computer number

<str_code>  is the string to display next to the user-entered number

Returns:

1 through 50 - (representing sequence number for Trigger Codes), 0 - ERROR

Description:

Displays a Trigger Code dialog box consisting of the code entry number (see pp_cenum()), computer ID number (see pp_compno()), and asks the user to enter a number.  All of the strings on the dialog box are user-definable.  Once the user types in a number and clicks the Ok button, pp_tcode() is evaluated to see if a valid Trigger Code was entered.  This result is then returned.  The computer number is generated using the COMPNO_BIOS algorithm. The computer number used for this dialog is independent of  the computer number passed to other functions such as pp_copyadd(). This function is typically used to help quickly implement a Trigger Code screen.

Example:

' Allow the user to enter a trigger code.  We will only

' look for trigger code 1.  We could have used any of the

' 50 possible trigger codes

Dim tcode As Long

tcode = pp_getcode(Me.hwnd, "Application Registration",

"Regestration No:", "Client ID:", "Authorization No:")

If (tcode = 1) Then

MsgBox "Authorization Successful!", 0, ""

End If

See Also:

PP_CENUM(), PP_COMPNO(), and PP_TCODE()


PP_GETDATE()

Gets the current date from the system clock

Applies to:

"C"/DOS, Win16, Win32

Syntax-VB:

Declare Sub pp_getdate(ByRef month As Long, ByRef day As Long, ByRef year As Long, ByRef dow As Long)

Syntax-C:

VOID pp_getdate(LPLONG month, LPLONG day, LPLONG year, LPLONG dow)

Arguments:

<month> is a buffer in which to place the month

<day>   is a buffer in which to place the day

<year>  is a buffer in which to place the year

<dow>   is a buffer in which to place the day of the week

Returns:

VOID - nothing. The current system date is placed into the variables passed.

Description:

This function is used to determine the current system date. It is returned through the variable buffers passed as parameters to this function.

The <dow> parameter returns the current day of the week using 0 as Sunday through 6 as Saturday.

Example:

' print out the current date

Dim month As Long, day As Long, year As Long, dow As Long

pp_getdate month, day, year, dow

print "Date: " & Str(month) & "/" & Str(day) & "/" &

Str(year)

See Also:

PP_GETTIME()


PP_GETTIME()

Gets the current time from the system clock

Applies to:

"C"/DOS, Win16, Win32

Syntax-VB:

Declare Sub pp_gettime(ByRef hours As Long, ByRef minutes As Long, ByRef seconds As Long, ByRef hseconds As Long)

Syntax-C:

VOID pp_gettime(LPLONG hours, LPLONG minutes, LPLONG seconds, LPLONG hseconds)

Arguments:

<hours>    is a buffer in which to place the hours

<minutes>  is a buffer in which to place the minutes

<seconds>  is a buffer in which to place the seconds

<hseconds> is a buffer in which to place the hundred seconds

Returns:

VOID - nothing. The current system time is placed into the variables passed.

Description:

This function is used to determine the current system time. It is returned through the variable buffers passed as parameters to this function.

Example:

' print out the current time

Dim hours As Long, minutes As Long, seconds As Long, hseconds As Long

pp_gettime hours, minutes, seconds, hseconds

print "Time:  " & Str(hours) & ":" & Str(minutes) & ":" & Str(seconds)

See Also:

PP_GETDATE()


PP_GETVARCHAR()

Gets a character-type License File variable

Applies to:

"C"/DOS, Win16, Win32

Syntax-VB:

Declare Function pp_getvarchar(ByVal handle As Long, ByVal var_no As Long, ByVal buffer As String) As Long

Syntax-C:

LONG pp_getvarchar(LONG handle, LONG var_no, LPSTR buffer)

Arguments:

<handle> is the handle to the License File given by pp_lfopen()

<var_no> determines which variable is being retrieved

<buffer> is the location in which to place the variable data

Returns:

Refer to pp_errorstr() for a table of possible return codes and their meaning. Typically, PP_SUCCESS [1] is returned and the value of the variable is returned through the parameter <buffer>.

Description:

Use this function to obtain the character values of the variables stored in the License File. The function pp_lfopen() opens the License File and returns a handle. Then, pp_getvarchar() is used to retrieve the character values one by one.

Note that <buffer> must first be initialized to a length of at least five characters longer than the length of the field being retrieved.

Refer to the following table for a list of character fields and their appropriate sizes.  Any field that has "Yes" in the CB-Versa or CB-560 columns field may be stored in a License File contained in that model of Hardware Key.

NAME	SIZE	CB-VERSA	CB-560	VAR#	DEFINE
Company name	CHAR[51]			1	VAR_COMPANY
User name	CHAR[51]			2	VAR_NAME
User address 1	CHAR[51]			3	VAR_ADDRESS1
User address 2	CHAR[51]			4	VAR_ADDRESS2
User address 3	CHAR[51]			5	VAR_ADDRESS3
User phone 1	CHAR[21]			6	VAR_PHONE1
User phone 2	CHAR[21]			7	VAR_PHONE2
Product serial number (text)	CHAR[21]			8	VAR_SERIAL_TEXT
Expiration type	CHAR[2]	Yes	Yes	9	VAR_EXPIRE_TYPE
User-defined character field 1	CHAR[51]			10	VAR_UDEF_CHAR_1
User-defined character field 2	CHAR[51]			11	VAR_UDEF_CHAR_2
User-defined character field 3	CHAR[51]			12	VAR_UDEF_CHAR_3
User-defined character field 4	CHAR[51]			13	VAR_UDEF_CHAR_4
User-defined character field 5	CHAR[51]			14	VAR_UDEF_CHAR_5
User-defined character field 6	CHAR[51]			15	VAR_UDEF_CHAR_6
User-defined character field 7	CHAR[51]			16	VAR_UDEF_CHAR_7
User-defined character field 8	CHAR[51]			17	VAR_UDEF_CHAR_8
User-defined character field 9	CHAR[51]			18	VAR_UDEF_CHAR_9
User-defined character field 10	CHAR[51]			19	VAR_UDEF_CHAR_10
Example:

' Get some of the user information from the license file

' and store it in text boxes on a form

Dim result As Long

Dim buffer As String * 60	  	' Make buffer big enough

result = pp_getvarchar(lfhandle, VAR_COMPANY, buffer)

Company.Text = buffer

result = pp_getvarchar(lfhandle, VAR_NAME, buffer)

UserName.Text = buffer

result = pp_getvarchar(lfhandle, VAR_ADDRESS1, buffer)

Address(0).Text = buffer

result = pp_getvarchar(lfhandle, VAR_ADDRESS2, buffer)

Address(1).Text = buffer

result = pp_getvarchar(lfhandle, VAR_ADDRESS3, buffer)

Address(2).Text = buffer

See Also:

PP_LFOPEN(), PP_SETVARCHAR(), PP_GETVARDATE(), and PP_GETVARNUM()


PP_GETVARDATE()

Gets a date-type License File variable

Applies to:

"C"/DOS, Win16, Win32

Syntax-VB:

Declare Function pp_getvardate(ByVal handle As Long, ByVal var_no As Long, ByRef month_hours As Long, ByRef day_minutes As Long, ByRef year_secs As Long) As Long

Syntax-C:

LONG pp_getvardate(LONG handle, LONG var_no, LPLONG month_hours, LPLONG day_minutes, LPLONG year_secs )

Arguments:

<handle>      is the handle to the License File given pp_lfopen()

<var_no>      determines which variable is being retrieved

<month_hours> returns the month or hours of the variable

<day_minutes> returns the day or minutes of the variable

<year_secs>   returns the year or seconds of the variable

Returns:

Refer to pp_errorstr() for a table of possible return codes and their meaning. Typically, PP_SUCCESS [1] is returned and the value of the variable is returned through the parameters <month_hours>, <day_minutes>, and <year_secs>.

Description:

Use this function to obtain the values of the date and time variables stored in the License File. The function pp_lfopen() opens the License File and returns a handle. Then, pp_getvardate() is used to retrieve the date and time values one by one.

Refer to the following table for a list of date and time fields. Any field that has "Yes" in the CB-Versa or CB-560 columns field may be stored in a License File contained in that model of Hardware Key.

NAME	SIZE	CB-VERSA	CB-560	VAR #	DEFINE
Expiration date (soft)	3 INTs		Yes	1	VAR_EXP_DATE_SOFT
Expiration date (hard)	3 INTs	Yes	Yes	2	VAR_EXP_DATE_HARD
Last used date	3 INTs		Yes	3	VAR_LAST_DATE
Last used time	3 INTs		Yes	4	VAR_LAST_TIME
User-defined date field 1	3 INTs		Yes	5	VAR_UDEF_DATE_1
User-defined date field 2	3 INTs			6	VAR_UDEF_DATE_2
User-defined date field 3	3 INTs			7	VAR_UDEF_DATE_3
User-defined date field 4	3 INTs			8	VAR_UDEF_DATE_4
User-defined date field 5	3 INTs			9	VAR_UDEF_DATE_5
Example:

Refer to pp_getvarchar() for an example of the concept of getting variables from the License File.

See Also:

PP_LFOPEN(), PP_GETVARCHAR(), PP_GETVARNUM(), and PP_SETVARDATE()


PP_GETVARNUM()

Gets a numeric-type License File variable

Applies to:

"C"/DOS, Win16, Win32

Syntax-VB:

Declare Function pp_getvarnum(ByVal handle As Long, ByVal var_no As Long, ByRef value As Long) As Long

Syntax-C:

LONG pp_getvarnum(LONG handle, LONG var_no, LPLONG value)

Arguments:

<handle> is the handle to the License File given by pp_lfopen()

<var_no> determines which variable is being retrieved

<value>  is the location in which to place the variable data

Returns:

Refer to pp_errorstr() for a table of possible return codes and their meaning. Typically, PP_SUCCESS [1] is returned and the value of the variable is returned through the parameter <value>.

Description:

Use this function to obtain the values of the numeric variables stored in the License File. The function pp_lfopen() opens the License File and returns a handle. Then, pp_getvarnum() is used to retrieve the numeric values one by one.

Refer to the following table for a list of numeric and bit fields and their appropriate sizes. Any field that has "Yes" in the CB-Versa or CB-560 columns field may be stored in a License File contained in that model of Hardware Key.

NAME	SIZE	CB-VERSA	CB-560	VAR#	DEFINE
Product serial number (numeric)	LONG		Yes	1	VAR_SERIAL_NUM
Expiration count	INT	Yes	Yes	2	VAR_EXP_COUNT
Expiration limit	INT	Yes	Yes	3	VAR_EXP_LIMIT
Number of current users	INT		Yes	4	VAR_LAN_COUNT
Number of allowed users	INT		Yes	5	VAR_LAN_LIMIT
Number of used installations	INT	Yes	Yes	6	VAR_INSTALL_COUNT
Number of allowed installations	INT	Yes	Yes	7	VAR_INSTALL_LIMIT
Number of computer IDs authorized	LONG			8	VAR_AUTHORIZED_COMPS
User-defined numeric/bit field 1	LONG	Yes	Yes	9	VAR_UDEF_NUM_1
User-defined numeric/bit field 2	LONG	Yes	Yes	10	VAR_UDEF_NUM_2
User-defined numeric/bit field 3	LONG	Yes	Yes	11	VAR_UDEF_NUM_3
User-defined numeric/bit field 4	LONG		Yes	12	VAR_UDEF_NUM_4
User-defined numeric/bit field 5	LONG		Yes	13	VAR_UDEF_NUM_5
License File Checksum	LONG			14	VAR_LF_CHECKSUM
The value from VAR_LF_CHECKSUM will not be the same as when using pp_password() on a License File.

Example:

Refer to pp_getvarchar() for an example of the concept of getting variables from the License File.

See Also:

PP_LFOPEN(), PP_GETVARCHAR(), PP_GETVARDATE(), and PP_SETVARNUM()


PP_HDSERIAL()

Gets the DOS 4 or higher disk serial number

Applies to:

"C"/DOS, CA-Clipper, FoxPro, Win16, Win32

Syntax-VB:

Declare Function pp_hdserial(ByVal drive As String) As Long

Syntax-C:

LONG pp_hdserial(LPSTR drive)

Arguments:

<drive> is the drive to report the serial number. For Windows libraries, if a NULL string ("") is passed, the drive Windows is installed on will be used, otherwise the current drive will be used.

Returns:

A number representing the disk serial number, or 1 when the disk was not formatted with DOS 4 or higher.

Description:

This function determines the serial number of any fixed or floppy disk that was formatted with DOS 4 or higher.  A single upper-case character passed in a string designates on which drive to find the serial number.

Example:

' print out the serial number of the C drive

Dim serial_number As Long

serial_number = pp_hdserial( "C" )

print "Serial number:  " & Str(serial_number)

See Also:

PP_COMPNO()


PP_INITLIB()

Initializes static library

Applies to:

"C"/DOS, CA-Clipper, Win16 (static), Win32 (static)

Syntax-C (Windows):

VOID pp_initlib(HINSTANCE hInstance)

Syntax-C (DOS):

VOID pp_initlib(VOID)

Syntax-Clipper:

pp_initlib()

Returns:

VOID - nothing.

Description:

This function is required to be called from within any application using the Static library versions.  It initializes memory variables used in the library.  The Windows static library requires the handle to the instance of the application being executed.

Example:

int PASCAL WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow )

{

pp_initlib( hInstance );

  /* put your application code here */

}


PP_LANACTIVE()

Determines if License File indicates multiple users are allowed

Applies to:

"C"/DOS, CA-Clipper, FoxPro, Win16, Win32

Syntax-VB:

Declare Function pp_lanactive(ByVal handle As Long) As Long

Syntax-C:

LONG pp_lanactive(LONG handle)

Arguments:

<handle> is the handle to the License File given by pp_lfopen()

Returns:

Refer to pp_errorstr() for a table of possible return codes and their meaning.  Typically, only PP_FALSE [0] (single-user) or PP_TRUE [1] (multi-user) is returned.

Description:

This function will determine if the LAN Limit field in the License File is greater than zero. Once the LAN Limit field is greater than zero, an application becomes "LAN-active."

Typically this function is used to display a message stating that the application is licensed as a network version or to switch copy protection algorithms dynamically.  This way, an application can behave differently depending on the LAN Limit field that can be set when the disks are shipped or remotely through a Trigger Code.

Example:

' Display a special message when this is a network version

' the variable handle is global and was initialized

' earlier in the application

Dim result As Long, user_no As Long, user_limit As Long

Dim buffer As String*50

result = pp_lanactive( handle )

Select Case result

Case 0:

Case 1:

pp_getvarnum handle, VAR_LAN_LIMIT, user_limit

pp_getvarnum handle, VAR_LAN_COUNT, user_no

MsgBox "You are network user " & Str(user_no) & "/"

& Str(user_limit), 0, "Network Version"

Case Else:

' An error has occured

pp_errorstr( result, buffer )

End Select

See Also:

PP_LANCHECK()


PP_LANCHECK()

Determines if workstation count is less than workstation limit

Applies to:

"C"/DOS, CA-Clipper, FoxPro, Win16, Win32

Syntax-VB:

Declare Function pp_lancheck(ByVal handle As Long) As Long

Syntax-C:

LONG pp_lancheck(LONG handle)

Arguments:

<handle> is the handle to the License File given by pp_lfopen()

Returns:

Refer to pp_errorstr() for a table of possible return codes and their meaning.  Typically, only PP_FALSE [0] (no licenses available) or PP_TRUE [1] (license available) is returned.

Description:

If the current workstation count is less than the workstation limit, this function returns 1.

Example:

' Check to see if we have reached our user limit.  If not

' then increment our count. Otherwise deny program access.

Dim result As Long

result = pp_lancheck( lfhandle )

If (result = PP_TRUE) Then

result = pp_countinc( lfhandle, VAR_LAN_COUNT )

Else

MsgBox "Workstation Limit Exceeded!", 0, ""

Unload Me

End If

See Also:

PP_LANACTIVE() and PP_COUNTINC()


PP_LASTDAY()

Determines the last date of the given month

Applies to:

"C"/DOS, CA-Clipper, FoxPro, Win16, Win32

Syntax-VB:

Declare Sub pp_lastday(ByVal month As Long, ByRef day As Long, ByVal year As Long)

Syntax-C:

VOID pp_lastday(LONG month, LPLONG day, LONG year)

Arguments:

<month> is the value of the month

<day>   is a buffer in which to place the last day

<year>  is the value of the year

Returns:

VOID - the last day of the month is placed into <day> buffer location

Description:

This function is used to determine the last date of a particular month. It is used by other PPP system library functions such as pp_npdate() to help determine the next payment date. It is possible to use this function in conjunction with pp_getdate() to determine the last day of the current month.

Example:

' Get the last day of the current month by first getting

' the current date

Dim month As Long, day As Long, year As Long, dow As Long

pp_getdate month, day, year, dow

pp_lastday month, day, year

' day should now be the last day of the current month

See Also:

PP_NPDATE() and PP_GETDATE()


PP_LFCLOSE()

Closes the License File

Applies to:

"C"/DOS, CA-Clipper, FoxPro, Win16, Win32

Syntax-VB:

Declare Function pp_lfclose(ByVal handle As Long) As Long

Syntax-C:

LONG pp_lfclose(LONG handle)

Arguments:

<handle> is the handle to the License File given by pp_lfopen()

Returns:

Refer to pp_errorstr() for a table of possible return codes and their meaning.  Typically, PP_SUCCESS [1] (file was closed) is returned.

Description:

Closes the License File and releases internal memory allocated by the pp_lfopen() function. The handle used by this function is not to be confused with a file handle that implies that the License File is kept in the open state.

CAUTION

This function must be called in order for all PPP memory allocation to be released.

Example:

' The variable lfhandle was initialized earlier with

' pp_lfopen()

Dim result As Long

result = pp_lfclose(lfhandle)	' close the handle

See Also:

PP_LFOPEN()


PP_LFCOPY()

Copies a License File to another location

Applies to:

"C"/DOS, CA-Clipper, FoxPro, Win16, Win32

Syntax-VB:

Declare Function pp_lfcopy(ByVal handle As Long, ByVal filename As String, ByVal type As Long) As Long

Syntax-C:

LONG pp_lfcopy(LONG handle, LPSTR filename, LONG type)

Arguments:

<handle>   is the handle to the License File given by pp_lfopen()

<filename> is the complete path and filename of the License File to create.  In the case of LF_REGISTRY, a unique string to identify the encrypted registry key. For Crypto-Box, defined as one byte:

1  - Start automatic search at LPT1

2  - Start automatic search at LPT2

3  - Start automatic search at LPT3

11 - Dedicated port search at LPT1

12 - Dedicated port search at LPT2

13 - Dedicated port search at LPT3

<type>     is the location where the License File is to be located, defined as:

LF_FILE             [1] - normal filesystem

LF_REGISTRY         [2] - Windows registry

LF_CRYPTO_BOX_VERSA [3] - Marx International Versa

LF_CRYPTO_BOX_560   [4] - Marx International 560

Returns:

Refer to pp_errorstr() for a table of possible return codes and their meaning.  Typically, PP_SUCCESS [1] (file was copied) is returned.

Description:

Copies the contents of the initialized License File into another location.  The <handle> then will refer to the new License File.  The old License File may be deleted with pp_filedelete().

Example:

' Open local License File and copy it

' to a floppy disk

Dim rc As Long

rc = pp_lfopen(App.Path & "\sample.ini", 0, LF_FILE, "password", lfhandle)

rc = pp_lfcopy(lfhandle, "a:\sample.ini", LF_FILE)

rc = pp_lfclose(lfhandle)

See Also:

PP_FILEDELETE() and PP_LFOPEN()


PP_LFCREATE()

Creates a file with the requested attributes

Applies to:

"C"/DOS, CA-Clipper, FoxPro, Win16, Win32

Syntax-VB:

Declare Function pp_lfcreate(ByVal file As String, ByVal flags As Long, ByVal lftype As Long, ByVal password As String, ByVal attrib As Long) As Long

Syntax-C:

LONG pp_lfcreate(LPSTR file, LONG flags, LONG lftype, LPSTR password, LONG attrib)

Arguments:

<file>     is the complete path and filename of the License File to be created. In the case of LF_REGISTRY, a unique string to identify the encrypted registry key.  For Crypto-Box, defined as one byte:

1  - Start automatic search at LPT1

2  - Start automatic search at LPT2

3  - Start automatic search at LPT3

11 - Dedicated port search at LPT1

12 - Dedicated port search at LPT2

13 - Dedicated port search at LPT3

<flags>    sets miscellaneous options, defined as:

LFCREATE_OVERWRITE [1] - unconditionally overwrites any existing License File

<lftype>   is the location where the License File is located, defined as:

LF_FILE             [1] - normal filesystem

LF_REGISTRY         [2] - Windows registry

LF_CRYPTO_BOX_VERSA [3] - Marx International Versa

LF_CRYPTO_BOX_560   [4] - Marx International 560

<password> is your unique password to use with this file.  For Crypto-Box Versa the password is defined as:

     AAAAAABBBBCCCCCCDDDDGGGGGGHHHHHHHH

For Crypto-Box 560, the password is defined as:

     AAAAAABBBBCCCCCCDDDDEEEEEEFFFFGGGGGGHHHHHHHHIIIIIIII

AAAAAA - SCodeID1, BBBB - ID1

CCCCCC - SCodeID2, DDDD - ID2

EEEEEE - SCodeID3, FFFF - ID3

GGGGGG - SerNum

HHHHHHHH - Ram1Password

IIIIIIII - Ram2Password

Note that the above values are in binary format and NOT in ASCII.  This means that if SCodeID1 is A4 21 59, you would concatenate these three bytes together.  In Visual Basic, this would look like chr(&HA4)+chr(&H21)+chr(&H59).  Therefore, for the Crypto-Box VERSA, the password consists of 17 bytes.

<attrib>   is a bit field with other attributes to be added:

PP_NORMAL  [0] - use the default attribute only

PP_RDONLY  [1] - read only attribute

PP_HIDDEN  [2] - hidden file

PP_SYSTEM  [4] - system file

Returns:

Refer to pp_errorstr() for a table of possible return codes and their meaning. Typically, PP_SUCCESS [1] (file was created) is returned.

Description:

This function is used to create an empty License File.  This file can then be opened with pp_lfopen().  This empty file can also be used with the COMPNO_HDLOCK feature of pp_compno().  In this case, it is tracked by pp_compno() by watching the cluster number of the file to make sure it never changes.

Note that a License File created in the Windows Registry with the Win16 DLL cannot be read by an application using the Win32 DLL and vice versa.

Example:

' Create a new License File with the hidden attrib.

' Overwrite any existing file. We will have to open the

' file after creating it to get the handle.

Dim result As Long

result = pp_lfcreate(App.Path & "\example.lf", LF_FILE, LFCREATE_OVERWRITE, "password", PP_RDONLY)

result = pp_lfopen(App.Path & "\example.lf", 0, LF_FILE, "password", lfhandle)

' We could have used pp_lfopen() to do the above step if

' the file didn't already exist.  If the file does exist then we

' have to call pp_lfcreate() in order to change the

' attributes or use a new password.

result = pp_lfopen(App.Path & "\example.lf", LF_CREATE_MISSING + LF_CREATE_HIDDEN, LF_FILE, "password", lfhandle)

See Also:

PP_LFOPEN() and PP_COMPNO()


PP_LFLOCK()

Locks the License File from other users

Applies to:

"C"/DOS, CA-Clipper, FoxPro, Win16, Win32

Syntax-VB:

Declare Function pp_lflock(ByVal handle As Long) As Long

Syntax-C:

LONG pp_lflock(LONG handle)

Arguments:

<handle> is the handle to the License File given by pp_lfopen()

Returns:

Refer to pp_errorstr() for a table of possible return codes and their meaning. Typically, PP_SUCCESS [1] (file was locked) is returned.

Description:

Locks the License File for exclusive use.  No other accesses to the License File are granted.  This function is typically used in a network environment where you want to update several fields in the License File while keeping time coherency.  This function will only work with License Files of type LF_FILE (physical disk files).  It is only necessary under network environments where multiple client stations may be sharing the same License File.

Example:

' Set some new application options but we don't want

' anyone to look at the new values until we have updated

' all of the options.

Dim result As Long

result = pp_lflock lfhandle

If result = PP_SUCCESS Then

' Set some new options

pp_setvarnum lfhandle, VAR_UDEF_NUM1, NewValue1

pp_setvarnum lfhandle, VAR_UDEF_NUM2, NewValue2

pp_setvarnum lfhandle, VAR_UDEF_NUM3, NewValue3

pp_unlock lfhandle	' Release the License File

End If

See Also:

PP_LFOPEN() and PP_LFUNLOCK()


PP_LFOPEN()

Opens the License File and returns a handle

Applies to:

"C"/DOS, CA-Clipper, FoxPro, Win16, Win32

Syntax-VB:

Declare Function pp_lfopen(ByVal filename As String, ByVal flags As Long, ByVal lftype As Long, ByVal password As String, ByRef handle As Long) As Long

Syntax-C:

LONG pp_lfopen(LPSTR filename, LONG flags, LONG lftype, LPSTR password, LPLONG handle)

Arguments:

<filename> is the complete path and filename of the License File. In the case of LF_REGISTRY, a unique string to identify the encrypted registry key.  For Crypto-Box, defined as one byte:

1  - Start automatic search at LPT1

2  - Start automatic search at LPT2

3  - Start automatic search at LPT3

11 - Dedicated port search at LPT1

12 - Dedicated port search at LPT2

13 - Dedicated port search at LPT3

<flags>    is a parameter with available options, defined as:

LF_CREATE_MISSING [8] - causes License File to be created if it is missing

LF_CREATE_NORMAL  [0] - attribute used if License File is created

LF_CREATE_RDONLY  [1] - attribute used if License File is created

LF_CREATE_HIDDEN  [2] - attribute used if License File is created

LF_CREATE_SYSTEM  [4] - attribute used if License File is created

<lftype>   is the location where the License File is located, defined as:

LF_FILE             [1] - normal filesystem

LF_REGISTRY         [2] - Windows registry

LF_CRYPTO_BOX_VERSA [3] - Marx International Versa

LF_CRYPTO_BOX_560   [4] - Marx International 560

<password> is your unique password to use with this file.  For Crypto-Box Versa the password is defined as:

     AAAAAABBBBCCCCCCDDDDGGGGGGHHHHHHHH

For Crypto-Box 560, the password is defined as:

     AAAAAABBBBCCCCCCDDDDEEEEEEFFFFGGGGGGHHHHHHHHIIIIIIII

AAAAAA - SCodeID1, BBBB - ID1

CCCCCC - SCodeID2, DDDD - ID2

EEEEEE - SCodeID3, FFFF - ID3

GGGGGG - SerNum

HHHHHHHH - Ram1Password

IIIIIIII - Ram2Password

Note that the above values are in binary format and NOT in ASCII.  This means that if SCodeID1 is A4 21 59, you would concatenate these three bytes together.  In Visual Basic, this would look like chr(&HA4)+chr(&H21)+chr(&H59).  Therefore, for the Crypto-Box VERSA, the password consists of 17 bytes.

<handle>   is the buffer to place the License File handle

Returns:

Refer to pp_errorstr() for a table of possible return codes and their meaning. Typically, PP_SUCCESS [1] (file initialized) is returned.  A numeric value which represents a handle to this License File is returned in <handle>.  This handle is used with many of the other library functions in order to access the defined License File.

Description:

This function opens the file <filename> and verifies integrity.  The <filename> must exist and be a valid License File.  This function must be run before most other PPP library functions since the handle returned by this function is used in the other functions.  Be sure not to modify the value of the handle or unpredictable results may occur.

The handle returned by this function is not to be confused with a file handle which implies that the License File is kept in the open state.

Note that a License Files created in the Windows Registry with the Win16 DLL cannot be read by an application using the Win32 DLL and vice versa.

Example:

Dim lfhandle As Long, result As Long

result = pp_lfopen( App.Path & "\example.lf", 0, LF_FILE,

"password", lfhandle )

See Also:

PP_LFCLOSE(), PP_LFCOPY(), PP_GETVARNUM(), PP_GETVARCHAR() and PP_GETVARDATE()


PP_LFUNLOCK()

Unlocks the License File

Applies to:

"C"/DOS, CA-Clipper, FoxPro, Win16, Win32

Syntax-VB:

Declare Function pp_lfunlock(ByVal handle As Long) As Long

Syntax-C:

LONG pp_lfunlock(LONG handle)

Arguments:

<handle> is the handle to the License File given by pp_lfopen()

Returns:

Refer to pp_errorstr() for a table of possible return codes and their meaning. Typically, PP_SUCCESS [1] (file was unlocked) is returned.

Description:

Unlocks the License File that was previously locked by pp_lflock().

Example:

Refer to pp_lflock() for an example of locking and unlocking a License File.

See Also:

PP_LFOPEN() and PP_LFLOCK()


PP_LIBTEST()

Determines if the valid PPP system library has been altered or replaced

Applies to:

Win16, Win32

Syntax-VB:

Declare Function pp_libtest(ByVal testnum As Long) As Long

Syntax-C:

LONG pp_libtest(LONG testnum)

Arguments:

<testnum> is the Validation Code

Returns:

The Validation Result for the given Validation Code.

Description:

This function was included to prevent anyone from replacing the PPP DLL with one that returns dummy results.  Enclosed with your package should have been three secret Validation Codes and matching Validation Result Values.  When you send this function the secret Validation Code provided with your package, it should return with the Validation Result provided with your package.  Each PPP customer will receive unique Validation Codes and Validation Result values.

A secret algorithm will be used to generate valid lib test seeds by Concept Software.  If this function receives a non-valid lib test seed, it will return a random number.  This will help prevent someone from reverse-engineering this function so they can replace the PPP DLL with a fake one.

This function is typically executed before any other PPP functions are called, for security reasons.

Example:

' See if our library returns the correct Validation

' Response Value

If pp_libtest(1518238629) <> 4178757 Then

MsgBox "Invalid Library"

  End	' Exit program

End If


PP_NDECRYPT()

Decrypts a number given a seed number

Applies to:

"C"/DOS, CA-Clipper, FoxPro, Win16, Win32

Syntax-VB:

Declare Function pp_ndecrypt(ByRef number As Long, ByVal seed As Long) As Long

Syntax-C:

LONG pp_ndecrypt(LONG number, LONG seed)

Arguments:

<number> is the number to be decrypted

<seed>   is the seed number used when the number was encrypted, between 0 and 255

Returns:

A value representing the decrypted number. -1 is returned if an invalid encrypted number is passed.  Any <seed> passed greater than 255 will be truncated automatically to the first hexadecimal byte of the number.  This is handy when the computer ID number algorithm is used as the seed.  This makes each installation of your application use a different seed for encrypting numbers.

Description:

Used to decrypt a number that was previously encrypted with pp_nencrypt().  Refer to pp_nencrypt() for typical usage.

Example:

Refer to pp_nencrypt() for an example of encrypting and decrypting a number.

See Also:

PP_NENCRYPT()


PP_NDECRYPTX()

Decrypts four numbers from string given a seed number

Applies to:

"C"/DOS, CA-Clipper, FoxPro, Win16, Win32

Syntax-VB:

Declare Function pp_ndecryptx(ByVal buffer As String, ByRef number1 As Long, ByRef number2 As Long, ByRef number3 As Long, ByRef number4 As Long, ByVal seed As Long) As Long

Syntax-C:

LONG pp_ndecryptx(LPSTR buffer, LPLONG number1, LPLONG number2, LPLONG number3, LPLONG number4, LONG seed)

Arguments:

<buffer> is the string to be decrypted

<number1> is the buffer to place the first decrypted number

<number2> is the buffer to place the second decrypted number

<number3> is the buffer to place the third decrypted number

<number4> is the buffer to place the fourth decrypted number

<seed>   is the seed number used when the numbers were encrypted

Returns:

PP_SUCCESS if successful or PP_FAILURE if the string buffer or seed is invalid.  If PP_FAILURE is returned, all number buffers should be set to zero.

Description:

Used to decrypt numbers that were previously encrypted with pp_nencryptx().  Refer to pp_nencryptx() for typical usage.

Example:

Refer to pp_nencryptx() for an example of encrypting and decrypting multiple numbers.

See Also:

PP_NENCRYPTX()


PP_NENCRYPT()

Encrypts a number given a seed number

Applies to:

"C"/DOS, CA-Clipper, FoxPro, Win16, Win32

Syntax-VB:

Declare Func pp_nencrypt(ByVal number As Long, ByVal seed As Long) As Long

Syntax-C:

LONG pp_nencrypt(LONG number, LONG seed)

Arguments:

<number> is the number to be encrypted, between 0 and 16,383 (14 bits)

<seed>   is the seed number used to encrypt the number, between 0 and 255

Returns:

A value representing the encrypted number.  -1 is returned if a <number> greater than 16,383 is passed.  Any <seed> passed greater than 255 will be truncated automatically to the first hexadecimal byte of the number.  This is handy when the computer ID number algorithm is used as the seed.  This makes each installation of your application use a different seed for encrypting numbers.

Description:

Used to encrypt a number based upon a given user-definable <seed> number.  This function is typically used when it is necessary to send a given number to a remote workstation such as a new number of allowed workstations.  It is possible to give the user a several digit number that represents the encrypted number.  The user is not able to determine the algorithm used to change the decrypted value used by the application.

Example:

' We will encrypt a number using the computer number

' as a seed.  Even though the computer number is greater

' than 255 it will be truncated.

Dim EncryptedNum As Long, DecryptedNum As Long

Dim compno As Long

compno = pp_compno(1, "", "")

EncryptedNum = pp_nencrypt(25,compno)

DecryptedNum = pp_ndecrypt(EncryptedNum, compno)

' DecryptedNum now equals 25

See Also:

PP_DECRYPT()


PP_NENCRYPTX()

Encrypts four numbers into string given a seed number

Applies to:

"C"/DOS, CA-Clipper, FoxPro, Win16, Win32

Syntax-VB:

Declare Sub pp_nencryptx(ByVal buffer As String, ByVal number1 As Long, ByVal number2 As Long, ByVal number3 As Long, ByVal number4 As Long, ByVal seed As Long)

Syntax-C:

VOID pp_nencryptx(LPSTR buffer, LONG number1, LONG number2, LONG number3, LONG number4, LONG seed)

Arguments:

<buffer> is a 35 character buffer to place the resulting string

<number1> is one of the numbers to be encrypted

<number2> is one of the numbers to be encrypted

<number3> is one of the numbers to be encrypted

<number4> is one of the numbers to be encrypted

<seed>   is the seed number used to encrypt the numbers

Returns:

VOID - nothing.  The encrypted string is returned through <buffer>.

Description:

Used to encrypt up to four numbers based upon a given user-definable <seed> number.  This function is typically used when it is necessary to send a given number to a remote workstation such as a new number of allowed workstations.  It is possible to give the user a several character string that represents the encrypted numbers.  The user is not able to determine the algorithm used to change the decrypted values used by the application.

Example:

' We will encrypt 4 numbers using the computer number

' as a seed.

Dim Result As Long, buffer as String*35

Dim compno As Long, n1 As Long, n2 As Long, n3 As Long, n4 As Long

compno = pp_compno(1, "", "")

pp_nencryptx(buffer, 1, 2, 3, 4, compno)

Result = pp_ndecryptx(buffer, n1, n2, n3, n4, compno)

' n1 through n4 now equal 1 through 4, respectively

See Also:

PP_DECRYPTX()


PP_NPDATE()

Determines payment expiration date of next month

Applies to:

"C"/DOS, CA-Clipper, FoxPro, Win16, Win32

Syntax-VB:

Declare Sub pp_npdate(ByRef month As Long, ByRef day As Long, ByRef year As Long, ByVal dop As Long)

Syntax-C:

VOID pp_npdate(LPLONG month, LPLONG day, LPLONG year, LONG dop )

Arguments:

<month> is the value of the current month (or month before payment is due)

<day>   is the value of a day in the current month

<year>  is the value of the current year

<dop>   is the day of the month that payment is due

Returns:

VOID - nothing.  The payment date is returned through <month>, <day>, and <year> buffers.

Description:

The <dop>th day in the month after the month of <month>/<day>/<year> is returned. If this day lies on a weekend, the next Monday date is returned.

This function is most commonly used when setting a new expiration date, especially when the user is on a payment or lease schedule. When a monthly / bimonthly / etc. payment arrangement has been made, and you only want to let the program run until a client makes their next payment, this function helps determine the next payment date by finding a weekday in the month after the date you specify.

Example:

' In the examples below 12/18 & 12/19 fall on Sat & Sun

Dim month As Long, day As Long, year As Long, dop As Long

' Set month, day, year, dop to 12, 16, 1996, 17

pp_npdate month, day, year, dop

' month, day, year now equal 1, 17, 1997

' Set month, day, year, dop to 12, 16, 1996, 18

pp_npdate month, day, year, dop

' month, day, year now equal 1, 20, 1997

' Set month, day, year, dop to 12, 16, 1996, 19

pp_npdate month, day, year, dop

' month, day, year now equal 1, 20, 1997

' Set month, day, year, dop to 12, 16, 1996, 20

pp_npdate month, day, year, dop

' month, day, year now equal 1, 20, 1997

See Also:

PP_GETDATE()


PP_PASSWORD()

Encrypts a string that cannot be decrypted

Applies to:

"C"/DOS, CA-Clipper, FoxPro, Win16, Win32

Syntax-VB:

Declare Function pp_password(ByVal instring As String) As Long

Syntax-C:

LONG pp_password(LPSTR instring)

Arguments:

<instring> is a character string to be encrypted, three characters minimum

Returns:

A number designating the encrypted version of the passed string.

Description:

This function is a one way encryption technique used when decrypting the data is not necessary.

Example:

' Encrypt the user's password and store

' it in one of the user-defined fields

' lfhandle contains the License File

' handle which was initialized earlier.

Dim pw As Long, rc As Long

pw = pp_password("secretpassword")

rc = pp_setvarnum(lfhandle, VAR_UDEF_NUM_1, pw)

If rc <> PP_SUCCESS Then

MsgBox "Encountered error number " & Str(rc)

End If

See Also:

PP_ENCRYPT(), PP_SETVARNUM(), and PP_DECRYPT()


PP_REDIR()

Determines if given drive letter is a redirected (network) drive

Applies to:

"C"/DOS, CA-Clipper, FoxPro, Win16, Win32

Syntax-VB:

Declare Function pp_redir(ByVal drive As String) As Long

Syntax-C:

LONG pp_redir(LPSTR drive)

Arguments:

<drive> is the drive to resolve possible network redirection. For Windows libraries, if a NULL string ( "" ) is passed, the drive Windows is installed on will be used, otherwise the current drive will be used.

Returns:

Refer to pp_errorstr() for a table of possible return codes and their meaning.  Typically, only PP_FALSE [0] (not redirected) or PP_TRUE [1] (redirected drive) is returned.

Description:

This function determines if a DOS drive is actually redirected to a network file server or some other remote drive. If a drive letter actually points to another machine via a peer-to-peer network, pp_redir() will return TRUE.  If the current machine is a peer server, meaning that the physical hard drive is located in this machine but other machines access the same data via the network, pp_redir() will return FALSE.

A single upper-case character passed in a string designates on which drive to check.

Example:

Refer to pp_compno() for an example of checking for a network drive.


PP_SEMCLOSE()

Closes the Network Semaphore File

Applies to:

"C"/DOS, CA-Clipper, FoxPro, Win16, Win32

Syntax-VB:

Declare Function pp_semclose(ByVal semhandle As Long) As Long

Syntax-C:

LONG pp_semclose(LONG semhandle)

Arguments:

<semhandle> is the handle to the License File given by pp_semopen()

Returns:

Refer to pp_errorstr() for a table of possible return codes and their meaning. Typically, PP_SUCCESS [1] (file was closed) is returned.

Description:

Closes the Network Semaphore File previously opened with pp_semopen().

Example:

Refer to pp_semopen() for an example of using this function.

See Also:

PP_SEMOPEN() and PP_SEMCOUNT()


PP_SEMCOUNT()

Counts the number of available workstation licenses

Applies to:

"C"/DOS, CA-Clipper, FoxPro, Win16, Win32

Syntax-VB:

Declare Function pp_semcount(ByVal handle As Long, ByVal semtype As Long, ByVal prefix_server As String, ByVal name As String, ByRef number As Long) As Long

Syntax-C:

LONG pp_semcount(LONG handle, LONG semtype, LPSTR prefix_server, LPSTR name, LPLONG number)

Arguments:

<handle> is the handle to the License File given by pp_lfopen()

<semtype>       is the semaphore locking type, defined as:

SEM_FILE   [0] - normal filesystem

SEM_TCPIP  [1] - Network server via TCP/IP - reserved

<prefix_server> is the complete path to the Network Semaphore Files or the TCP/IP address of the server counting the number of simultaneous users

<name>          is a 4-character identifier to use to count the workstations.

<number>        is the location to place the count data

Returns:

Refer to pp_errorstr() for a table of possible return codes and their meaning. Typically, PP_SUCCESS [1] (count successful) is returned.

Description:

This function calculates the number of locked workstation licenses and returns the number of allowed licenses MINUS the number of locked licenses (and hence, the number of available licenses). Currently, only the type of SEM_FILE counting is available.  The parameter <prefix_server> contains the complete path to the network semaphore files, INCLUDING a trailing backslash (\) character.  The <name> parameter contains the first four characters of the semaphore files.  The locked semaphore files will be counted and the number will be returned.

The semaphore files are named by the path and prefix you choose.  The files are numbered starting at 0 through 9999 with an extension of .net.  An example list of files using "f:\appname\data\" for <prefix_server> and "sema" for <name> is:

f:\appname\data\sema0.net

f:\appname\data\sema1.net

f:\appname\data\sema2.net

.

.

f:\appname\data\sema9999.net

This function will attempt to open and lock the semaphore files in the given path for the number of workstations that is in the License File field "number of allowed users."  It ignores the field "number of current users" when calculating the result.

Note that in large network installations, the time delay for each workstation will increase as the semaphore files are scanned for the next available license.

Example:

' Calculate the number of available users

' lfhandle contains the License File

' handle which was initialized earlier.

Dim rc As Long, count As Long

rc = pp_semcount(lfhandle, SEM_FILE, "m:\appname\data\", "sema", count)

If rc <> PP_SUCCESS Then

MsgBox "Encountered error number " & Str(rc)

End

End If

If count = 0 Then

MsgBox "There are no more licenses available"

End

End If

See Also:

PP_SEMOPEN() and PP_SEMCLOSE()


PP_SEMOPEN()

Opens the Network Semaphore File in exclusive mode

Applies to:

"C"/DOS, CA-Clipper, FoxPro, Win16, Win32

Syntax-VB:

Declare Function pp_semopen(ByVal handle As Long, ByVal semtype As Long, ByVal prefix_server As String, ByVal name As String, ByRef semhandle As Long) As Long

Syntax-C:

LONG pp_semopen(LONG handle, LONG semtype, LPSTR prefix_server, LPSTR name, LPLONG semhandle)

Arguments:

<handle> is the handle to the License File given by pp_lfopen()

<semtype>        is the semaphore locking type, defined as:

SEM_FILE  [0] - normal filesystem

SEM_TCPIP [1] - Network server via TCP/IP - reserved

<prefix_server> is the complete path to the Network Semaphore Files or the TCP/IP address of the server counting the number of simultaneous users

<name>          is a four-character identifier to use to count the workstations.

<semhandle>     is the buffer in which to place the Network Semaphore File handle

Returns:

Refer to pp_errorstr() for a table of possible return codes and their meaning. Typically, PP_SUCCESS [1] (file was opened) is returned.  A numeric value that represents a handle to this Network Semaphore File is returned in <semhandle>.  This handle is used with pp_semclose() to close the defined file.

Description:

This function attempts to secure the next available workstation license.  Currently, only the type of SEM_FILE counting is available.  The parameter <prefix_server> contains the complete path to the network semaphore files, INCLUDING a trailing backslash (\) character.  The <name> parameter contains the first 4 characters of the semaphore files.  The semaphore files will be created as necessary until the workstation limit has been reached.  Be sure not to modify the value of the <semhandle> or unpredictable results may occur.

The handle returned by this function is not to be confused with the handle used by the License File.  Unlike the License File, this file is kept open in the exclusive mode until it is closed.

The semaphore files are named by the path and prefix you choose.  The files are numbered starting at 0 through 9999 with an extension of .net.  An example list of files using "f:\appname\data\" for <prefix_server> and "sema" for <name> is:

f:\appname\data\sema0.net

f:\appname\data\sema1.net

f:\appname\data\sema2.net

.

.

f:\appname\data\sema9999.net

This function will attempt to open and secure a license from the semaphore files in the given path for the number of workstations that is in the License File field "number of allowed users."  It ignores the field "number of current users" when determining ERR_NET_LIC_FULL.

Note that in large network installations, the time delay for each workstation will increase as the semaphore files are scanned for the next available license.

Example:

' Attempt to open a network semaphore file

' lfhandle contains the License File

' handle which was initialized earlier.

Dim rc As Long, semhandle As Long

rc = pp_semopen(lfhandle, SEM_FILE, "m:\appname\data\", "sema", semhandle)

If rc = ERR_NET_LIC_FULL Then

MsgBox "No more licenses available, try later"

End

ElseIf rc <> PP_SUCCESS Then

MsgBox "Encountered error number " & Str(rc)

End

End If

' Continue with program execution

. . .

' At the end of your program

rc = pp_semclose(semhandle)

If rc <> PP_SUCCESS Then

MsgBox "Encountered error number " & Str(rc)

End

End If

See Also:

PP_SEMCLOSE() and PP_SEMCOUNT()


PP_SETVARCHAR()

Sets a character-type License File variable

Applies to:

"C"/DOS, Win16, Win32

Syntax-VB:

Declare Function pp_setvarchar(ByVal handle As Long, ByVal var_no As Long, ByVal buffer As String) As Long

Syntax-C:

LONG pp_setvarchar(LONG handle, LONG var_no, LPSTR buffer)

Arguments:

<handle> is the handle to the License File given by pp_lfopen()

<var_no> determines which variable is being changed

<buffer> is the value to which to set the License File variable

Returns:

Refer to pp_errorstr() for a table of possible return codes and their meaning. Typically, PP_SUCCESS [1] (variable was updated) is returned.

Description:

This function is used to set the character values of the variables stored in the License File. The function pp_lfopen() opens the License File and returns a handle. Then, pp_setvarchar() is used to set the character values one-by-one. The values are written to the License File automatically.

Refer to the table described in pp_getvarchar() for a list of character fields and their appropriate sizes.

CAUTION

All character fields have a limit to the number of characters that they can store. If you plan to use this function to change the License File variables, you must make sure the length of the string you pass is not longer than the limit. Limited checking on the length is done by the library. If you fail to limit the characters, unpredictable results may occur.

Example:

' Get some of the user information from the user and store

' it in the License File. lfhandle contains the License

' File handle which was initialized earlier.

Dim rc As Long

rc = pp_setvarchar(lfhandle, VAR_COMPANY, Company.Text)

rc = pp_setvarchar(lfhandle, VAR_NAME, UserName.Text)

rc = pp_setvarchar(lfhandle, VAR_ADDRESS1,Address(0).Text)

rc = pp_setvarchar(lfhandle, VAR_ADDRESS2,Address(1).Text)

rc = pp_setvarchar(lfhandle, VAR_ADDRESS3,Address(2).Text)

See Also:

PP_LFOPEN(), PP_SETVARDATE(), PP_SETVARNUM(), and PP_GETVARCHAR()


PP_SETVARDATE()

Sets a date-type License File variable

Applies to:

"C"/DOS, Win16, Win32

Syntax-VB:

Declare Function pp_setvardate(ByVal handle As Long, ByVal var_no As Long, ByVal month_hours As Long, ByVal day_minutes As Long, ByVal year_secs As Long) As Long

Syntax-C:

LONG pp_setvardate(LONG handle, LONG var_no, LONG month_hours, LONG day_minutes, LONG year_secs )

Arguments:

<handle>      is the handle to the License File given pp_lfopen()

<var_no> determines which variable is being set

<month_hours> the month or hours of the variable to set

<day_minutes> the day or minutes of the variable to set

<year_secs>   the year or seconds of the variable to set

Returns:

Refer to pp_errorstr() for a table of possible return codes and their meaning. Typically, PP_SUCCESS [1] (variable was updated) is returned.

Description:

This function is used to change the date and time values of the variables stored in the License File. The function pp_lfopen() opens the License File and returns a handle. Then, pp_setvardate() is used to set the date and time values one-by-one. The values are then written to the License File automatically.

Refer to the table described in pp_getvardate() for a list of date and time fields.

CAUTION

Failure to use the full four-digit year with this function will cause unpredictable results.

Example:

Refer to pp_setvarchar() for an example of the concept of writing variables in a License File.

See Also:

PP_LFOPEN(), PP_SETVARCHAR(), PP_SETVARNUM(), and PP_GETVARDATE()


PP_SETVARNUM()

Sets a numeric-type License File variable

Applies to:

"C"/DOS, Win16, Win32

Syntax-VB:

Declare Function pp_setvarnum(ByVal handle As Long, ByVal var_no As Long, ByVal number As Long)

Syntax-C:

LONG pp_setvarnum(LONG handle, LONG var_no, LONG number)

Arguments:

<handle> is the handle to the License File given by pp_lfopen()

<var_no> determines which variable is being set

<number> the value to write into the variable

Returns:

Refer to pp_errorstr() for a table of possible return codes and their meaning. Typically, PP_SUCCESS [1] (variable was updated) is returned.

Description:

This function is used to change the numeric values of the variables stored in the License File. The function pp_lfopen() opens the License File and returns a handle. Then, pp_setvarnum() is used to change the numeric values one-by-one. The values are then written to the License File automatically.

Refer to the table described in pp_getvarnum() for a list of numeric and bit fields.

Example:

Refer to pp_setvarchar() for an example of the concept of getting variables from the License File.

See Also:

PP_LFOPEN(), PP_SETVARCHAR(), PP_SETVARDATE(), and PP_GETVARNUM()


PP_TCODE()

Decodes which Trigger Code number was entered

Applies to:

"C"/DOS, CA-Clipper, FoxPro, Win16, Win32

Syntax-VB:

Declare Function pp_tcode(ByVal number As Long, ByVal cenum As Long, ByVal computer As Long, ByVal seed As Long) As Long

Syntax-C:

LONG pp_tcode(LONG number, LONG cenum, LONG computer, LONG seed)

Arguments:

<number>   is the number input from the user

<cenum>    is the code entry number given by pp_cenum()

<computer> is the computer ID number given by pp_compno()

<seed>     is a number used to randomize the algorithm

Returns:

1 through 50 - (representing sequence number for Trigger Codes ), 0 - Invalid code entered

Description:

Compares the <number> entered by the user to the other three parameters to see if there is a match to one of the current Trigger Codes. If the value is correct, it returns a number from 1 to 50 to represent the function to be executed. Otherwise, a zero is returned indicating an invalid code was entered by the user.

Example:

' See if a valid trigger code was entered

' The client was just given a trigger code. We will grab

' this trigger code from the form into the pp_tcode()

' function to determine which trigger code it was. It is

' important that the same values used for cenum, compno

' and seed are the same values that were used to generate

' the trigger code. We have arbitrarily defined code 1 to

' trigger a demo extension and code 2 to give the user

' full functionality.  Since we are not using any of the

' other codes any else will be considered an error.

Dim result As Long

result = pp_tcode(Val(txtCodeEntered.Text), cenum, compno, 400)

Select Case result

Case 1

  	' Extend demo 30 days

  Case 2

       ' Allow full functionality

  Case Else

       MsgBox "Invalid Code entered!"

End Select

See Also:

PP_CENUM(), PP_COMPNO(), and PP_CTCODES()


PP_TIMERCHECK()

Determines if application timer has expired

Applies to:

"C"/DOS, CA-Clipper, FoxPro, Win16, Win32

Syntax-VB:

Declare Function pp_timercheck(ByVal timestamp As Long, ByVal minutes) As Long

Syntax-C:

LONG pp_timercheck(LONG timestamp, LONG minutes)

Arguments:

<timestamp> is the timestamp of the start of the application

<minutes>   is the number of minutes to let this application execute

Returns:

Refer to pp_errorstr() for a table of possible return codes and their meaning.  Typically, only PP_FALSE [0] (timer not expired) or PP_TRUE [1] (timer expired) is returned.

Description:

Calculates the amount of time between the start of the application and now.  The return code determines if the application should expire immediately or not.

Example:

' Start the timer at the beginning of the application and

' save the time stamp

Dim StartTime As Long

StartTime = pp_timerstart

.

.

.

' Now periodically check the timer.  We only want the

' program to run for 15 minutes

Dim result As Long

result = pp_timercheck(StartTime, 15)

If (result = PP_SUCCESS) Then

MsgBox "Expired"

End If

See Also:

PP_TIMERSTART()


PP_TIMERSTART()

Starts application timer to expire in given number of minutes

Applies to:

"C"/DOS, CA-Clipper, FoxPro, Win16, Win32

Syntax-VB:

Declare Function pp_timerstart As Long

Syntax-C:

LONG pp_timerstart(VOID)

Returns:

A timestamp used in the pp_timercheck() function.

Description:

Sets up the automatic timer to let the application run for a specified number of minutes.  It is required to check periodically for expiration via pp_timercheck() function.

Example:

Refer to pp_timercheck() for an example of starting and checking the timer.

See Also:

PP_TIMERCHECK()


PP_TRANSFER()

Assists in transferring license from one machine to another

Applies to:

"C"/DOS, CA-Clipper, FoxPro, Win16, Win32

Syntax-VB:

Declare Function pp_transfer(ByVal handle As Long, ByVal filename As String, ByVal password As String, ByVal comp_num As Long) As Long

Syntax-C:

LONG pp_transfer(LONG handle, LPSTR filename, LPSTR password, LONG comp_num)

Arguments:

From the computer to transfer the license TO:

<handle>   always 0

<filename> is the name of the temporary License File to create

<password> is password to use when creating this License File

<comp_num> is the computer ID number of the new computer

From the computer to transfer the license FROM:

<handle>   is the handle previously returned from pp_lfopen()

<filename> is the name of the temporary License File that was created

<password> is ignored

<comp_num> is the computer number of the previous license

Returns:

Refer to pp_errorstr() for a table of possible return codes and their meaning. Typically, PP_SUCCESS [1] (transfer step completed) is returned.

Description:

This function is used to transfer the license from one computer to another using a pure software mechanism.  It is also possible to use a Marx International Crypto-Box hardware key to securely transfer the software license as well.  Refer to Implementing License Transfers Using Hardware Key.  Using strictly software - to transfer a license from one computer to another, have the user install the software on the second machine.  When the software fails the copy protection test, you can give them an option to start the license transfer process.  This option will call pp_transfer() with parameters of 0 for the <handle>, the path and name of a license file on a floppy and the computer ID of the current computer (using the same algorithm that you wish to use in the copy protection mechanism).

The client will then need to run the software on the licensed computer.  They will need to have a mechanism to transfer this license to the diskette that was created in the previous step.  When this option is executed, call pp_transfer() and pass the handle to the current license file, the path and filename of the license file created by the other computer, and the computer ID of the current computer (as stored in the current license file).

When the unauthorized computer receives the command to initiate a license transfer, the computer number for this computer is written to the license file created on the floppy.  When the licensed computer is told to transfer its license to the floppy, it deletes its computer ID from the license file pointed to by <handle>, adds the computer ID stored in the <filename>, and copies the license file from the current computer to <filename>.  It is then necessary to have the new computer simply move the updated License File from the floppy and move it to its normal name and location.

This three-step process is required to help reduce the number of ways the user can end up transferring the software to multiple machines illegally.

Refer to Implementing Unsupervised License Transfers for more information.

CAUTION

If the user totally backs up the application directory, completes the transfer of the license to a new computer and restores the directory, the first application may run.  It is recommended to use pp_checksum() to monitor the checksum of the file and store this information in a separate directory so that if the user restores their application directory after a license transfer, the application will detect the attempt of tampering.

Example:

Refer to Sample Code Single User Copy Protection for an example of using this function.

See Also:

PP_LFOPEN(), PP_LFCOPY(), and PP_CHECKSUM()


PP_UPDDATE()

Updates the last date and time used fields in License File

Applies to:

"C"/DOS, CA-Clipper, FoxPro, Win16, Win32

Syntax-VB:

Declare Function pp_update(ByVal handle As Long, ByVal flag As Long) As Long

Syntax-C:

LONG pp_upddate(LONG handle, LONG flag)

Arguments:

<handle> is the handle to the License File given by pp_lfopen()

<flag>   is used to force date to be updated

Returns:

Refer to pp_errorstr() for a table of possible return codes and their meaning. Typically, PP_SUCCESS [1] (variables were updated) is returned.

Description:

Stores the current value of the system date and time in the License File, provided the current date and time is later than the one already stored in the License File.  If <flag> is set to a nonzero number, the current value of the system date and time will always be stored in the License File.

There are several techniques to implementing this approach. The first is to call this function prior to exiting an application. The second is to call this function prior to executing the main logic of an application. This prevents a client from exiting the application via rebooting to avoid updating the last time the application was used. The third is to call this function after the pp_expired() function has returned TRUE.

Generally, one of the Trigger Codes are reserved to calling this function so that if the user accidentally turns their date forward, runs your program, then turns the date to the proper value, when they get locked out of your system, you can reset the last used date and time.  This is the only place where <flag> should be set to a value of one.

Example:

Refer to pp_expired() for an example of this function.

See Also:

PP_VALDATE(), PP_EXPIRED(), PP_GETDATE(), and PP_GETTIME()


PP_VALDATE()

Verifies current date / time is greater than last used date / time fields

Applies to:

"C"/DOS, CA-Clipper, FoxPro, Win16, Win32

Syntax-VB:

Declare Function pp_valdate(ByVal handle As Long) As Long

Syntax-C::

LONG pp_valdate(LONG handle)

Arguments:

<handle> is the handle to the License File given by pp_lfopen()

Returns:

Refer to pp_errorstr() for a table of possible return codes and their meaning. Typically, only PP_FALSE [0] (clock was turned back) or PP_TRUE [1] (clock was not turned back) is returned.

Description:

Makes sure that the last date and time used, stored in the License File, is less than the current date and time.  If this is the case, the value returned is PP_TRUE [1].

The last used system date and time are available via pp_getvardate().

Example:

If pp_valdate(lfhandle) = PP_FALSE Then

MsgBox "Your clock has been turned back.  Please

correct and re-run application"

End If

See Also:

PP_UPDDATE(), PP_GETDATE(), PP_GETTIME(), and PP_GETVARDATE()


LFEDIT OVERVIEW

The Protection Plus Professional (PPP) system includes a License File Editing Facility (LFEdit).  This Windows-based application is used to edit License Files and generate Trigger Codes.

LFEdit can be used to edit existing License Files and to create new ones.  Multiple License Files can be open at one time, in standard Windows Multiple Document Interface format.

LFEdit keeps profiles on different Products you sell.  Each product can have its own Product Definition properties in LFEdit that describes items such as Trigger Code descriptions, default License File name and location, next serial number, etc.


INITIAL SETUP

During installation, LFEdit is installed in the chosen directory and icons are created in the chosen program group.  Note that LFEdit is a Win32 application that must be run on Windows 95 or later, Windows NT 3.51 or later, or Windows / Windows for Workgroups 3.1 or later IF the free Microsoft Win32s driver is installed.  You must be using Win32s version 1.3 or later.  If you are not sure if you have the latest version of Win32s or any version of Win32s installed, you may download the necessary files from http://www.consoft.com/win32s or by contacting Technical Support.

There are no special instructions to setup and start using LFEdit.

The Product Definitions used in LFEdit are stored in a file called PRODUCT.PD that will be created automatically if it does not exist in the LFEdit application directory.

EVALUATION COPY OF LFEDIT

Evaluation copies of LFEdit will have limited functionality.  First, this copy forces on the Load Sample Data option.  Refer to the LFEdit Options Dialog Box for more information on this feature.  Also, the Product Definitions can be edited while running LFEdit, but they are not saved upon exit.


PRODUCT DEFINITION

LFEdit contains a set of properties for each of the products you sell.  All of these properties together are called a Product Definition.  The list of active Product Definitions can be found by selecting the Product Definition / Setup menu option.


DATE FIELD SHORTCUTS

There are several date fields used throughout LFEdit.  To enter today's date, simply enter a period (.).  To enter the second of the current month, enter the number two.  To enter the fifth of March, enter 3 / 5.  When the field loses focus, the full date will be updated.


LFEDIT TUTORIAL SECTION

This section will walk you step-by-step from the creation of a Product Definition through the License File creation process.  You may also find a reference of menu options and form controls in the LFEdit Reference Section.

LFEdit is a very easy application to use.  There are three main tutorial sections describing the various features of the product.

Creating a Product Definition

Creating a License File

Generating Trigger Codes


CREATING A PRODUCT DEFINITION

A Product Definition stores default information about a product that you sell.  If you sell multiple products that have similar protection needs, you can modify the default Product Definition and use it throughout this tutorial.

Click Product Definition menu then Setup.  The following dialog box appears.

Click on the <default> Product Definition then click the Properties button.  The Product Definition Properties dialog box appears.

Notice that on the default Product Definition, you may edit the Product Description but not the Product Name.  If you wish to change the starting serial number, you may enter the numeric and any alphanumeric portions of the serial number now.  Once finished, click the License File tab.  The following screen appears.

You may change the name of the License File and the path to where it should be saved by default.  In our example, the License File named PRODUCT.INI will be placed automatically on the A: drive in File format.  Notice how you can store the License File in different locations such as the Windows registry or in a Marx International Crypto-Box (hardware key).  You may also choose a password that will be required to edit the License File from within your application.  Note that evaluation copies of LFEdit will not be able to edit the password field.  Click the Trigger Codes tab to continue.

There is a seed number that is used to randomize the Trigger Code mechanism for your products so that it is difficult for other PPP system users to duplicate your Trigger Codes.  Enter a seed number at the top of the form. Note that evaluation copies of LFEdit will not be able to edit the seed field. You may program up to 50 Trigger Code signals to remotely send to your application.  This form allows you to describe what each of the codes do.  Either double click the code number or click the code number and click the Modify button to pull up the details.

We will have Trigger Code 1 extend a demo of our application by seven days.  Let's make Trigger Code 5 increase the number of allowed users on a network.  Notice how we are taking advantage of the additional number feature.  This means that when the user calls for authorization, we will give them two numbers.  The first number is the Trigger Code that tells the application we are setting the number of allowed LAN users.  The second number will be a numerically-encrypted number telling the application to what value to set the LAN users field.

We then have taken the liberty to set up some other Trigger Codes descriptions.  This is what the resulting list looks like.

There are several user-defined fields stored in the License File.  There is a group of character fields, numeric fields, and date fields.  Descriptions may be entered for these fields to help you remember their purpose. Click the User-Defined Variables tab.  To modify a field label, double-click the entry in the list and type in the description.  We have entered a few below.

We have successfully set up the default Product Definition record.  Any new Product Definitions created will be based upon this record.  As a good exercise, you should repeat the last steps and create a Product Definition for one of your products.

Now we are ready to create a License File.

Creating a License File


CREATING A LICENSE FILE

A License File contains several pieces of information in one location that is encrypted and stored in binary format so that the user cannot view the data in clear text.  Creating a License File is rather easy.

Click File/New and select the desired product.  The following dialog box appears.

Select the <default> Product Definition or any other one you created and Click Ok. A window similar to the following appears.

Fill in the fields as appropriate.  The data in these fields, as all fields in this series of tabs, will be available to your application at runtime.  The actual purpose of the data is all user-defined, meaning that if you don't know or don't care about the user's name, you can leave it blank or use the space for another purpose.

Click the Expiration Fields tab.  The data stored on this tab can also be used by your application.  The actual purpose of each of the fields will not be covered by this tutorial.  The field descriptions are described in the sections LFEdit Reference Section and in the Software Licensing chapter under License File Read/Write Functions .

You may enter data into the user-defined fields should you have the need.  There are several user-defined character fields, numeric fields, and date fields.  The labels for these fields can be found in the Product Definition setup.  You may quickly go to the Product Definition Properties by clicking on the properties button of the main toolbar or by selecting the menu option Product Definition/Properties.  Note that the properties of the currently selected Product Definition will be edited.  The currently selected Product Definition can be found in the list box of the main toolbar.  The following is the User-Defined Strings tab box.

The following is the User-Defined Numbers/Dates tab.  Notice how the numbers can be easily encoded as bit fields.  The numbers can be displayed in both decimal and hexadecimal notations.

To save the License File, choose from the menu File/Save As.   The following dialog box appears.

Make sure the Storage Location is set to File and that the path and filename are valid.  Click Save.  The License File has now been created.


GENERATING TRIGGER CODES

Generating Trigger Codes is a very easy task in LFEdit.  Simply select the appropriate Product Definition from the list on the main toolbar and click the Trigger Codes button on the toolbar or choose Tools/Trigger Codes from the menu.  The following dialog box appears.

Notice how the Trigger Code descriptions that we entered in the Product Definition are now showing.  Those descriptions became associated with the product that we are now attempting to remotely control.  Select Code 2 and click the Select button.  We are then prompted to enter the Code Entry and Computer ID Numbers that the Client has on their screen.

Once we enter the numbers and click the Generate button we are informed of the resulting code that we should read the Client.  We can then choose to automatically generate another Trigger Code or stop.

Let us generate another code.  Click the Trigger Codes button on the toolbar or choose Tools/Trigger Codes from the menu.  Remember that Code 5 was a little different in that we wanted to send an additional number to our remote application.  If we sold the user a network version and they want to purchase more seats, we could give them Code 5.  Click Code 5 and click the Select button.

We can enter the Code Entry and Computer ID numbers again, but notice how we can enter yet another number - the number of Allowed LAN users.  When the remote application sees that we are giving it Trigger Code number 5, it will also be waiting to decode the additional number so it knows what value to put in the License File for the field VAR_LAN_LIMIT.  When we click the Generate button, we see the following dialog box.

This dialog box now has the value for Trigger Code 5 to read the Client as well as the additional number so it knows the new value for VAR_LAN_LIMIT.

The section Sample Code Network Floating Licensing describes the included sample application that demonstrates what the remote application needs to do to process both numbers.

This concludes the tour of LFEdit.  The next page begins the LFEdit reference portion of the manual.


LFEDIT REFERENCE SECTION

The following topics cover each of the forms available in LFEdit and a description of each of the fields or other controls on the form.  You may also find a step-by-step tutorial of the features of LFEdit in the LFEdit Tutorial Section.


MAIN WINDOW

The following menus are available:

FILE

Allows you to create new License Files, open existing files, close open files, print the contents of a License File, and exit the application.

EDIT

Allows you to Cut, Copy, and Paste data in text fields.

VIEW

Allows you to enable or disable the toolbar and status bar.

PRODUCT DEFINITION

Allows you to edit the list of Product Definitions and to view the properties of the currently-selected Product Definition.

TOOLS

Allows you to generate Trigger Codes.

WINDOW

Allows you to manipulate the currently open MDI Child windows.

HELP

Allows you to access online Help.


LICENSE FILE DIALOG BOXES

The next several sections describe the various tabs that make up the License File view.  Each of the fields on the tab contain data that is stored in the License File Fields.


LICENSE FILE NEW

OVERVIEW

When creating a new License File, select an available Product Definition from the list so that LFEdit can set the necessary default fields.


LICENSE FILE GENERAL TAB

PRODUCT SERIAL NUMBER - TEXT

If your product serial numbers are broken down into a static alphanumeric portion and an incrementing portion, this is the static portion.  You may enter anything in this field or leave it blank.

PRODUCT SERIAL NUMBER - NUMERIC

If your product serial numbers are broken down into a static alphanumeric portion and an incrementing portion, this is the incrementing portion. Upon creation of a new License File an "<auto>"  is shown in this field.  When the License File is saved, if the "<auto>" is in this field, then the current value in the Next Serial Number field in the Product Definition is copied to the License File field and the Next Serial Number field is incremented by one.  If a number is entered in this field, then that number is saved and no change to Next Serial Number field is made.  Deleting the number in this field restores the "<auto>".

COMPANY NAME THROUGH PHONE 2:

These are character fields that can contain the registered user information.  All of the fields shown are available to your application at runtime.  You may enter anything in these fields or leave them blank.


LICENSE FILE EXPIRATION FIELDS TAB

This tab contains most of the expiration related variables.  Refer to the License File Fields section for a description of each variable.  Upon creation of a new License File the last used date and time fields are updated with the current system date and time.

There are several date field shortcuts described in the Date Field Shortcuts section.


LICENSE FILE UDEF STRINGS TAB

STRING 1 THROUGH STRING 10

These string fields are completely user-defined.  Each field can hold 50 characters.  All of the fields shown are stored in the License File and available to your application at runtime.  You may enter anything in these fields or leave them blank.  You can modify the label displayed for each of the user-defined strings in the Product Definition properties.


LICENSE FILE UDEF NUMBERS/DATES TAB

NUMBER 1 THROUGH NUMBER 5

These fields are completely user-defined.  Each field holds up to the value of a LONG integer (2147483647) or can hold up to 31 bits of a bit field.  The button to the right of the number value brings up a dialog box that allows you to edit the state of the individual bits in the bit field. These values are stored in the License File and are available to your application during runtime. You may enter anything in these fields or leave them blank. You can modify the label displayed for each of the user-defined numbers in the Product Definition properties.

DATE 1 THROUGH DATE 5

These fields are completely user-defined.  Each can hold a date value.  There are several shortcuts for entering dates as described in the section Date Field Shortcuts.  These values are stored in the License File and are available to your application during runtime. You may enter anything in these fields or leave them 0/0/0. You can modify the label displayed for each of the user-defined numbers in the Product Definition properties.

HEXADECIMAL

When this box is checked, the values in the Number fields are displayed in Hexadecimal format.  This format is commonly used by "C" language programmers.  When the box is not checked, the values are listed in normal decimal format. These values are stored in the License File and are available to your application during runtime. You may enter anything in these fields or leave them blank. You can modify the label displayed for each of the user-defined dates in the Product Definition properties.


LICENSE FILE BIT FIELD DIALOG BOX

BIT 32 THROUGH BIT 1

Use this dialog to modify the user-defined number by setting and clearing bits.  Each check represents a binary one for the specified bit.

NUMBER

This read-only field displays the user-defined number in decimal or hexadecimal format.


LICENSE FILE AUTHORIZED COMPUTERS TAB

AUTHORIZED LIST

All authorized Computer ID Numbers are listed here in slot number order.

TOTAL AUTHORIZED COMPUTERS

Displays the total number of authorized computers.

ADD

Adds the Computer ID Number displayed in the new Computer ID field to the list of authorized computers.  No duplicates are allowed.

NEW COMPUTER ID FIELD

Enter the desired Computer ID Number to add here then select "Add".

DELETE

Deletes all Computer ID Numbers currently selected in the Authorized list.


PRODUCT DEFINITION DIALOG BOXES

The next several sections describe the various tabs that make up the Product Definition.


PRODUCT DEFINITION SETUP

OVERVIEW

This dialog box is used to manage the list of available Product Definitions.  Note that depending on the PPP system Software Licensing Method you chose, you may or may not be able to add more than one Product Definition.  If you are using the PPP system with more than one application, you may purchase the license for more products directly from Concept Software, Inc.

ADD

Adds a new Product Definition.

PROPERTIES

Edits the selected Product Definition.

COPY

Copies the selected Product Definition into a new Product Definition.

REMOVE

Removes the selected Product Definition.


PRODUCT DEFINITION GENERAL TAB

PRODUCT

This is the name used to identify a Product Definition.  It is used when selecting a Product Definition for a License File.  You can use a maximum of 16 characters with no duplicate names.  The name of the default production definition (<default>) may not be modified.  However, You can modify any other Product Definition name at any time.

DESCRIPTION

This field is used to describe the product represented by the Product Definition.  It is informational only and is not used in any of the License File tabs or Trigger Code dialogs.  You can use a maximum of  50 characters.

NEXT SERIAL NUMBER TEXT

This is the alphanumeric portion of the serial number corresponding to the same serial number field in the General tab of the License File.  Upon creation of a new License File this string is copied to the License File field.  This value will not automatically change as with the Next Serial Number Numeric description that follows.

NEXT SERIAL NUMBER NUMERIC

This is the numeric portion of the serial number corresponding to the same serial number field in the General tab of the License File.  Upon creation of a new License File an "<auto>"  will be shown in the License File field.  When the License File is saved, if the "<auto>" is in the License File field, then the current value in this field is copied to the License File field and this field is incremented by one.  If a number is entered in the License File field then that number is saved and no change to this field is made.  Deleting the number in the License File field restores the "<auto>".


PRODUCT DEFINITION LICENSE FILE TAB AND SAVE AS DIALOG BOX

OVERVIEW

This tab sets the default storage information for a License File.  When saving a new License File these defaults will be used.  The storage for any License File may always be modified using the "Save As" command.  Anytime a License File has been saved using storage settings that are different from the defaults in this tab then a "(s)" will be appended to the name of the License File to remind the user that the current License File is using "special" storage.   Additionally if a License File is opened with storage settings different from the defaults it maintains "special" storage status for any saves.  When opening a License File the user is able to select a different Product Definition in the Open dialog.

STORAGE LOCATION

This field lists the possible License File Types that determine where the License File is stored.  The remaining fields change depending on this selection.

FILE NAME

The file path for a "File" type License File.   The Browse button may be used to select a path.

WINDOWS REGISTRY

The Registry key for a "Registry" type License File.

PASSWORD

The password for either a "File" or "Registry" type License File.  This field is not accessible in Evaluation Copies of LFEdit.

IMPORTANT

A License File cannot be edited without the correct password.

SCODEID1-3

Used for Marx CRYPTO-BOX type License Files.  Six hexadecimal digits each.  SCodeID3 is used for 560 only.

ID1-3

Used for Marx CRYPTO-BOX type License Files.  Four hexadecimal digits each. ID3 is used for 560 only.

SCODESER

Used for Marx CRYPTO-BOX type License Files.  Four hexadecimal digits.

SERNUM

Used for Marx CRYPTO-BOX type License Files.  Six hexadecimal digits.

RAM1-2PASSWORD

Used for Marx CRYPTO-BOX type License Files.  Eight hexadecimal digits. RAM2Password is used for 560 only.

OPTIONAL ATTRIBUTES

The "File" type License File is saved with these attributes.  Not available when opening the License File.

PORT

Selects the port with the Marx CRYPTO-BOX key attached.

UPDATE PRODUCT DEFINITION

When performing a "Save As" on a License File, if the storage settings of the file differ from the current Product Definition, this option may be checked.  If checked, upon saving the License File, the storage settings for the current Product Definition are updated to reflect the new settings.


PRODUCT DEFINITION TRIGGER CODES TAB

OVERVIEW

The information in this tab is used only in the Trigger Code Generation dialogs and does not affect any License Files.  It allows the user to set up labels and seeds to be used when generating Trigger Codes.

SEED

This is the seed used to further randomize all of the Trigger Codes. Note that evaluation copies of LFEdit will not be able to edit this field.

DETAILS

Selecting this button allows modification of the currently selected Trigger Code through the Trigger Code Properties dialog shown.

CODE

The Trigger Code number 1-50.

DESCRIPTION

This field is used to describe each Trigger Code and is shown when generating Trigger Codes.  It may be  modified by using the Trigger Code Properties dialog.

ADDITIONAL NUMBER

This field is used to describe any additional number that is sent with the Trigger Code and is shown when generating Trigger Codes.  It may be modified in the Trigger Code Properties dialog.


PRODUCT DEFINITION TRIGGER CODE PROPERTIES

OVERVIEW

This dialog allows modification of the data shown in the Product Definition Trigger Code tab.  The information set here appears during generation of this trigger code.  The seeds are defaults and may be changed during generation.

DESCRIPTION

This field is used to describe the purpose of a Trigger Code during Trigger Code generation.  A maximum of 50 characters may be used.

SEND AN ADDITIONAL NUMBER (NENCRYPT)

If this option is checked, then an additional field is shown during Trigger Code generation that allows a number to be encrypted and sent to the client along with the Trigger Code.  This functionality uses the function pp_nencrypt().  Your application decodes this number with pp_ndecrypt().

ADDITIONAL NUMBER DESCRIPTION

This field is used to describe an additional number (if any) during Trigger Code generation. A maximum of 20 characters may be used.

AUTO-GENERATE SEED

If this option is checked, then the Computer ID Number is used as the seed for encryption of the additional number (if any).  Since the seed may not be greater than 255 the Computer ID Number will be truncated.  This would be used in a situation where you do not want to use a fixed seed for the number encrypted with pp_nencrypt().

SEED

The seed for encryption of the additional number (if any) will be set here.  The seed must be between 0 and 255.   This field is disabled if the auto-generate seed option is checked.


PRODUCT DEFINITION USER-DEFINED VARIABLES TAB

OVERVIEW

The labels used for the License File user-defined variables may be modified here.  A maximum of 20 characters may be used.


GENERATE TRIGGER CODE DIALOG BOXES

The next several sections describe the three dialog boxes encountered while generating Trigger Codes.


TRIGGER CODE SELECT DIALOG BOX

OVERVIEW

This dialog allows you to select which Trigger Code to generate.  The labels and default seeds may be setup in the Product Definition Trigger Codes tab.

CODE

The Trigger Code (1-50) to generate.

DESCRIPTION

The description of the Trigger Code.

ADDITIONAL NUMBER

The description of the additional number to send (if any).  If there is no additional number this field will be blank even if a description has been set.

TRIGGER CODE COUNTER USED

Each time a Trigger Code is generated this counter is incremented. A Trigger Code is not considered "generated" until the Generate command is issued in the Trigger Code Enter dialog box.

TRIGGER CODE COUNTER REMAINING

This field displays the number of Trigger Codes that may be generated.  When this number reaches zero the Select button is disabled.

SELECT

Selects the currently highlighted Trigger Code and begins the generation process.


TRIGGER CODE ENTER DATA DIALOG BOX

OVERVIEW

This dialog is used to gather all of the data needed to generate a Trigger Code for the client.

CUSTOMER'S CODE ENTRY NUMBER

Enter the Code Entry Number from the client.

CUSTOMERS COMPUTER ID

Enter the Computer ID Number from the client.

ADDITIONAL NUMBER DESCRIPTION

The frame shows the description of  the additional number to send (if any); otherwise, it is disabled

ADDITIONAL NUMBER VALUE

Additional number to send to the client (if any); otherwise, it is disabled.

ADDITIONAL NUMBER SEED

Seed used to encrypt the additional number (if any); otherwise, it is disabled.

GENERATE

Starts the Trigger Code generation.  The Trigger Code counter is incremented regardless of whether or not the Trigger Code is used.


TRIGGER CODE RESULT DIALOG BOX

OVERVIEW

This dialog displays the results of the Trigger Code generation.

TRIGGER CODE TO GIVE CUSTOMER

Displays the generated Trigger Code that should be given to the client.

ADDITIONAL NUMBER TO GIVE

Displays the encrypted additional number (if any) to give to the client.

GENERATE ANOTHER TRIGGER CODE

If this option is checked, clicking OK causes it to go back to the Trigger Code selection dialog; otherwise, the dialog is closed.


ONE WAY ENCRYPTION DIALOG BOX

OVERVIEW

This is a useful dialog box for using the one-way encryption feature of the PPP system by using the function pp_password().

STRING TO ENCRYPT

Enter the string to be one-way encrypted using pp_password().

ENCRYPTED VALUE

The encrypted value result from pp_password().


LFEDIT OPTIONS DIALOG BOX

USE THIS PRODUCT DEFINITION

When LFEdit is loaded, the selected Product Definition will be loaded.  It is also possible to select the <last used> Product Definition.

GENERATE TRIGGER CODES

When LFEdit is loaded and this option is checked, a Trigger Code session is automatically started for the selected Product Definition.

USE PROGRAM DATA

Use this option when you are ready to use LFEdit in a production mode, with your own Product Definitions loaded at startup.

USE SAMPLE DATA

Use this option if you want to load the Product Definitions of the Sample Applications that are shipped with the PPP system.  This is useful while learning to use the PPP system through the sample applications.  These sample Product Definitions have all of the Trigger Codes descriptions appropriately defined.  This option is forced active on Evaluation Copies of LFEdit.


UPDATE THE LICENSE FILE STORAGE SETTINGS WARNING

If you change the current Product Definition for the active License File you will receive the following warning asking whether of not you wish to "Update the License File storage settings?"

Answering Yes causes the current storage settings for the active License File to be updated with the default storage settings for the newly selected Product Definition.  A No keeps the current License File storage settings and an "(s)" is appended to the title to indicate "special storage".  Neither answer causes the License File to be saved.


PROTECTION PLUS PROFESSIONAL OVERVIEW

A lot  of time, effort, and dollars are spent in application development. The Protection Plus Professional (PPP) system is an advanced software licensing toolkit that insures proprietary security and control. There are several fundamental capabilities provided by the PPP system:

•	Copy protection / network licensing.

•	Remote control.

•	Demo / timed expiration.

•	Soft (number of days) and hard (specific date) expiration types.

•	Convert illegal copies to live demos.

•	Periodic suspensions guarantee payments.

•	Hardware key integration using EZ Key™.

•	Live editing of License Files with LFEdit.

These capabilities allow developers to "get a grip" on who uses their software.

•	Great for Marketing Your Products. Create fully/partially functional demos of your applications.

•	Insures Payment from Demo or Lease Clients. Incorporate periodic or permanent disabling logic in your applications.

•	Dynamically Establish Workstation Parameters. Limit/restrict network client/server access of your applications.

•	No Unauthorized Computers. Prohibit your applications from being copied onto unauthorized computers.

The PPP system has many features that distinguish it from other copy protection packages.

PPP SYSTEM DESCRIPTION

This section describes the various functions available with the PPP system. The PPP system is comprised of two parts. Part one is the License File Editing facility (LFEdit). This creates encrypted, binary License Files and generates Trigger Codes.  Part two is the language-specific library. This contains functions for implementing the software licensing features in your application.

License Files

License Files contain many data fields that allow you to store information to control the flow of execution in your application.  The fields can be initialized before sending your application using LFEdit and/or can be manipulated by the application remotely using Trigger Codes.  License Files may be stored in a file, the Windows registry, or in a Marx International Crypto-Box® Hardware Key.

Trigger Codes

The PPP system has a mechanism to send remote signals to your application while running on the Client's computer.  The user contacts you and gives you two six- to eight-digit numbers that are displayed on a dialog box on their computer.  These numbers can be sent by phone, FAX, e-mail, etc.  In LFEdit, these two numbers are entered; and, depending on what function you want to perform on their application, you return them one of 50 six- to eight-digit numbers.

Copy Protection

When copy protecting your application, the PPP system allows you to authorize a particular computer using different Computer ID number algorithms provided in the library. The PPP system includes library functions that detect illegal copies of your application. Upon detection, you may convert to a demo, abort the program, etc. Unknowingly, illegal copies converted into demos become a distribution channel for your application.

Payment Option

For leased applications or technical support clients, the PPP system allows you to enforce periodic suspensions. This guarantees collection of payments due. If desired you can use the PPP system to release your application from future expirations.

Demo Creation

Now you can distribute demo copies of your application. Using the PPP system, you can cause your application to stop working after a specified date or number of executions. The PPP system will not allow more use of your application by back-dating the system date or reinstalling the demo. You decide whether to enable all or just some of the features of your application during the demo period.

What happens when the demo expires? The prospective client calls you for a Trigger Code to extend the demo period, or you can unlock it forever. This allows you to distribute demos, take credit card orders over the phone, and unlock the application without having to send another set of diskettes.

This is great for your 30 day money back guarantees. If your client decides to purchase your software, you can unlock it. If your client decides to return it, you can prohibit the making of illegal copies for future use.

Network Protection

The PPP system allows you to prohibit the copying of your software from the server hard drive, limit the number of simultaneous workstations, or assign the application to specific workstations. To authorize additional workstations, your client simply contacts you for a Trigger Code.  In most cases, the PPP system can detect when any of the client stations terminated prematurely and automatically free up the license that was being used.

Hardware Key Integration

Using a Marx International Crypto-Box® to store software license information can be a very powerful tool.  There is a predefined amount of RAM available in these keys where we store a subset of the License File fields.  This is the most secure method to license software based upon number of executions.  Also, LFEdit for Distributors is available for those applications that are sold through distributors.  You now have total control over the number of copies these distributors license.  Also, the easiest way manage an unsupervised software license transfer is to use the number of allowed installations and the number of used installations fields along with a Hardware Key.

EZ Key™

Would it not be nice to have the best of both the software- and hardware-based protection worlds?  Use a Hardware Key to store the number of installations allowed, install the applications on the desired computers and use the Hardware Key as the authorization mechanism.  Simply place the Hardware Key on the back of the computer, run the application, and remove the Hardware Key.  This is great for large companies or educational institutions who purchase many copies of your application or for notebook users who will not tolerate constantly having a Hardware Key attached to their parallel port.  It is possible to use Trigger Codes to remotely change all License File fields stored in the Hardware Key.

Additional Info

You can use the PPP system to:

•	Create hidden procedures.

•	Remotely enable/disable modules.

•	Personalize/serialize applications without requiring unnecessary recompiling.

And that’s not all. Once you start using the PPP system, you will discover its full power and functionality.  Purchasing PPP does not end with receiving the product itself.  It begins a relationship of sharing Software Licensing tips and tricks.


LIBRARY DESCRIPTIONS

The Protection Plus Professional system is available in several library formats.

CA-CLIPPER

A static library that works with all versions of CA-Clipper, from Summer '87 to CA-Clipper 5.3.  It is compatible with both ExoSpace as well as Blinker 3.X Extended and Dual modes.

"C"/DOS

A static library that works with the DOS modes of the Borland and Microsoft family of compilers.  We supply a large memory model library only.

FOXPRO/DOS

A dynamic link library (PLB format) developed with the FoxPro Library Construction Kit.  It works with FoxPro for DOS 2.5 or higher.

FOXPRO/WIN

A dynamic link library (FLL format) developed with the FoxPro Library Construction Kit.  It works with all versions of FoxPro for Windows 2.x.

WIN16 DLL

A dynamic link library (DLL) that works with any programming language that can call a DLL.  This DLL runs in both 16-bit (Windows and Windows for Workgroups) and 32-bit (Windows 95 and Windows NT) operating systems when you are using a 16-bit development environment.  You can use this with Microsoft Visual Basic 3.0 and 4.0, C, C++, Microsoft Access 2.0, Visual Objects 1.0, PowerBuilder, Delphi 1.0, Paradox, etc.

WIN32 DLL

A dynamic link library (DLL) that works with any programming language that can call a DLL.  This DLL runs in both Windows 95 and Windows NT when you are using a 32-bit development environment. You can use this with any 32-bit development environment such as Microsoft Visual Basic 4.0, C, C++, Visual FoxPro, Delphi 2.0, Visual Objects 2.0, and Microsoft Access 95 or later.


SOFTWARE LICENSING METHODS

There are two software licensing methods available for Version 4 of the Protection Plus Professional (PPP) system.  They are designed to provide various levels of functionality and flexibility depending on what is needed by the developer. Upgrades from previous versions of PPP are processed directly from Concept Software, Inc.

Refer to the License Agreement for details.

STANDARD EDITION

Available in either Single platform library or CA-Clipper, FoxPro, or DLL Bundle

Single-user license of LFEdit system is included. The KeyLib/KeyCtrl are royalty-free for one product only.

The following options are available:

•	Unlimited LFEdit license

•	Convert to Enterprise edition

•	Extra platform library

•	Extra product license

ENTERPRISE EDITION

Win16/Win32 Combo is included.  Additional installs of the LFEdit system are provided for no additional license fee. The KeyLib/KeyCtrl are royalty-free for all products.  A separate library TrigLib is included that will allow for the generation of Trigger Codes as well as "LFEdit for Distributors" that can be given to distributors to generate Trigger Codes on a limited basis.  EZ Key™ Crypto-Box® (Hardware key) functionality included in libraries.  One year of product support is included.

PRODUCT SUPPORT PLANS

The Standard Edition includes 60 days of product support from their first contact with a technical support representative.  The Enterprise edition includes 1 year of product support.  Support incidents may be purchased when needed, or an annual plan is available.  The annual support plan allows access to a private Internet web product support page that includes the latest version of the library and utilities plus the PPP system online knowledgebase.

SOURCE CODE

Both a PPP C++ Class Library and a License File C++ Class Library are available for purchase.  The LFEdit source code is also available for purchase.  Contact your Sales Representative for more information.


SYSTEM REQUIREMENTS

The following hardware and software equipment is required to properly implement the PPP system.

LFEDIT

•	Intel x86 compatible computer.

•	Windows 3.1 with Win32s 1.3 or later (Win32s drivers included).

•	Windows® 95, NT 3.51 or later (INTEL Processor).

•	Hard drive with at least 3.5 Mb disk space free.

•	3.5-inch floppy disk drive.

LFEDIT FOR DISTRIBUTORS

•	Intel x86 compatible computer.

•	Windows 3.1 with Win32s 1.3 or later (Win32s drivers included).

•	Windows® 95, NT 3.51 or later (INTEL Processor).

•	Hard drive with at least 3.5 Mb disk space free.

•	3.5-inch floppy disk drive.

•	Parallel Port for Hardware Key

•	Marx International device driver if running on Windows 95 or Windows NT.

APPLICATION DEVELOPMENT

•	Application development language/compiler.

•	Refer to Operating System Compatibility section for library compatibility issues.


QUESTIONS AND ANSWERS - INTRODUCTION

The following questions are typically asked by first time users of the Protection Plus Professional (PPP) system. The GENERAL section discusses common questions about the capabilities of the PPP system. The TECHNICAL section deals with more specific technical issues concerning implementation and problem resolutions. MICROSOFT ACCESS discusses the possibility of clients editing out the protection code using Microsoft Access. Finally, the HINTS section gives tips on implementing the PPP system under various circumstances.  Please read this entire chapter before contacting your Technical Support Representative.


GENERAL

Once authorized, what prevents a client from copying the authorized, copy protected files to another computer?

Since the copy protection algorithms lock the application to the hardware of the authorized computer, any application files copied to another computer trigger a copy protection test failure.

How does the PPP system insure that a backed-up and/or restored copy protected application is not placed on another computer?

If ROM BIOS is the only algorithm used in the Computer ID Number, an application can be backed-up and restored on the same computer. In this case it functions normally. All other Computer ID Number algorithms cause the copy protection test to fail.

How will the PPP system handle a copy protected application in the event of the reformatting, repartitioning, or the installation of a new hard drive on a client’s computer?

If ROM BIOS is the only algorithm used in the Computer ID Number, an application can be backed-up and restored on the same computer. In this case it functions normally. All other Computer ID Number algorithms cause the copy protection test to fail.

Clients routinely upgrade their computer hardware. What happens to a copy protected application that is migrated to a new computer?

You have two choices. One is to require the authorization of a copy protected application on the new computer. The other is to develop a procedure that disables an application on the old computer and enables it on the new computer using the Trigger Code mechanism.

What prevents one of my customers from purchasing the PPP system and using it to unlock my software on their machine?

Since you choose a License File password and a Trigger Code seed, any other user of PPP cannot access your application unless you give them your password and/or seed number.

When I try to read strings from the control file, my application exits with a GPF.

It is necessary to initialize the buffer to spaces before calling the pp_getvarchar() function.  Refer to the pp_getvarchar() function for an example of how to read character fields from the License File.

I've noticed that some computers will return identical computer numbers (generated from the BIOS).  Is this normal?

Depending on the BIOS manufacturer, the BIOS's are serialized.  For identical computers that have non-serialized BIOS, the number will be the same.  We suggest that you use the BIOS number along with the drive serial number for the most unique number.

If a client needs to move my application to a new a computer I can give him an unlock code for the new machine but how can I force him to de-install my application from the original computer?

When the user types in the code to de-install the software, after running pp_copydelete(), display a message that the user will have to read to you.  Something like "CODE - ABC123 OK"... If the user doesn't execute the function, he won't know what to read to you.

Why do weird things happen within the Visual Basic debug environment?

Visual Basic does not unload DLLs when you break.  Sometimes this causes variables to not be updated as expected.  Before raising an alarm, simply build an Executable file and see if the problem goes away.

What is the best way to ship a date-relative timed demo?

It is best to ship a License File with a SOFT expiration date of 0/0/0 and a HARD expiration of a fixed date, say the end of the current year or at least several months from today’s date.  At the start of your application, retrieve the value from the SOFT expiration date.  If it is 0/0/0, reset the SOFT expiration date to 30 days (or your desired number of days) from today.


TECHNICAL

Is it possible to find out why a function is failing to perform?

Most all PPP system functions that fail will return an error condition.  The error conditions are all documented under pp_errorstr().  You may also use pp_errorstr() to convert the number to a string for display purposes in a message box.

What mechanism does the PPP system use to prevent a copy protected application from being duplicated via the DISKCOPY command?

Your application protected by the PPP system can be copied via the DISKCOPY command. However, to complete the application installation procedure, you or your distributor would need to supply a Trigger Code. This Trigger Code is unique for every installation; therefore, it prevents installation on unauthorized computers.

Will my clients need additional Trigger Codes upon distribution of an upgraded version of my copy protected application?

No Trigger Codes are necessary for upgraded or replaced .EXE files unless you so desire.  In order to do this, change the password or store a flag in the License File indicating which version the software is allowed to run.

My company has its own client tracking system. Can this system be used instead of LFEdit provided with the PPP system?

Yes. You may use the PPP library functions to create a License File.  However, LFEdit or TrigLib library is required to generate Trigger Codes.  The TrigLib library is only shipped with the Enterprise version of PPP.  You might be able to integrate the Trigger Code generation right into your own client tracking system.

How can I determine why an authorized application reverted to a locked mode?

Since the Computer ID Number can be composed of several different hardware algorithms, you can design a screen to show the value of each component used in it. If you keep a record of these numbers on file, then you or your distributor can determine which number changed. This enables you to see what algorithm is generating a different number.

Will PPP work with QEMM in both "Mapping" and "Frame" modes?

We have special hooks in our DOS libraries to work with QEMM and for the most part they work with both Frame and Mapping modes.  Unfortunately, when windows runs, it takes over the memory management and we lose our ability to talk directly to QEMM.  In a few cases there have been some problems with BIOS.  You might want to make your software able to remotely switch from BIOS + HDSERIAL to just HDSERIAL when you run into problem.  You can also try disabling the STEALTH option.

One of my customers keeps contacting me for a new Trigger Code because the Copy Protection test keeps failing.  Is there a problem with the library or with the Client's computer?

We only know of three reasons why the Computer ID Number when using the BIOS algorithm will change.  One is when the user changes their hard drive configuration.  On a few computers, this could cause their Computer ID Number to change one time but then remain consistent.  A one-time re-authorization can fix this problem.  On notebook computers with docking stations, one Computer ID Number is generated when in the docked state and another one is generated while not docked.  Simply adding a second valid Computer ID Number using pp_copyadd() will work around this problem.  Finally, on a few computers, the QEMM Stealth feature when used under Windows can cause the Computer ID Number to change every time the computer is rebooted.  This is a rare occurrence.  Refer to the previous question for a workaround.


MICROSOFT ACCESS

How do I protect my .MDB file from clients who own a full-blown copy of Microsoft Access?  Can't they just edit out the protection code?

It is common to place the calls to the PPP system library in an AUTOEXEC macro. To prevent a client from bypassing this macro, declare a global variable in this macro and verify its existence and proper value in another critical macro. If the client bypasses the AUTOEXEC macro, the global variable is not set and the other macro indicates a message telling the client not to tamper with your application.


HINTS

If the user installs the software on a weekend, can I let the software run until Monday?

By using pp_getdate(), you can determine the current day of the week.  This can be used to allow your software to run.  Be sure to prevent the user from backdating their system using pp_upddate() and pp_valdate().

How can I insure that a demo client does not repeatedly re-install a copy protected application, defined as a 10-day Demo, to gain additional execution time?

There are several ways to handle this situation.  One is to have the application only run for a limited time and have the user contact you for an evaluation Trigger Code which gives them a 30 day evaluation.  Another common technique is to add a function to the application that destroys all required data files during installation. Each time the application is installed, the potential client would lose all data entered during the prior demo period.

Another way to prevent demo applications from being constantly re-installed is to ship with a License File with a date set to 0/0/0.  When executing the application and the expiration date is set to 0/0/0, reset the expiration date to 30 days from today’s date and write that same date into a key data file with which the user would not mess.  When opening the data file, verify that date in data file matches expiration date.  If not, don’t open the data file.  This will prohibit anyone from reinstalling the program and copying over the old data file.  They will have to start with empty data files every time!

Yet another approach similar to the redundant date field in a data file is to have redundant License Files - one stored in a file and one stored in the Windows registry.  You could synchronize the two using pp_lfcopy() and use the checksum field from pp_getvarnum() to verify consistency.  The user can delete the files from one installation and install a fresh set.  When the application runs for the first time and finds an existing License File in the registry, the program can display an error message and exit.

Demos with data - verify key fields haven’t changed

Another method to prevent re-installing is to save the value of a few records in a database field into the License File upon exiting.  When starting the application over, verify that the fields match.  This is another method to prohibit the user from continuously re-installing an application to get more use.  The PPP system function pp_password() converts a string over to a number for easy storage into one of the user-defined numeric fields of the License File.

How do I coordinate giving Trigger Codes to someone who is hard to reach?

A simple mechanism can be implemented to coordinate a Trigger Code session with someone via FAX, voice mail, or e-mail, where you do not have direct telephone contact. The Trigger Code keys change every time the Trigger Screen is called up, so the only alternative to this is to leave the computer untouched on the Trigger Screen while waiting for an authorization code.  On the dialog box, have a way for the user to "save state" of the unlock session.  Simply write the code entry number to the user defined numeric field of the License File.  The next time when the user calls up the Trigger Code screen, see if the user defined numeric field is blank.  If there is a number present, use this number in the unlock session for the code entry number, otherwise use a fresh code entry number.  In both cases, do not store the Computer ID Number in a user-defined numeric field or the user could back up the license file and use it to unlock multiple machines.  Don’t forget to zero out the user defined numeric field when the Trigger Code session is complete.

How do I prevent execution counters from being restored?

The most secure way to use execution counters is to store the License File in a Hardware Key.  Otherwise, when an execution counter is reset remotely, the user can simply back up the License File, use the allotted number of executions, restore the previous License File, and repeat forever, making the product essentially unprotected.  This is, of course, assuming that the user knows which file contains the protection information.  The easiest way around this is to calculate the checksum of the License File using pp_checksum() or pp_getvarnum() upon exiting the software and verifying that it has not changed the next time the software is entered. Every time the License File is changed, the checksum will be different.  If the file changed between the last time and the next time the software is executed, an error message can be displayed.  It is easiest to store the checksum of the License File in another data file that is required to use the program - one that will probably not be restored along with the License File by the user.

How do I prevent a user from installing a network version of my product on multiple directories on the same server to gain more concurrent users?

When unlocking the initial copy of your software on a server, store the current install directory in a user defined string field.  Whenever the application is started again, compare the current directory to the one stored in the user-defined string field.  If they do not match, alert the user that the installation is corrupt.


SAMPLE APPLICATIONS OVERVIEW

The Protection Plus Professional (PPP) system ships with several sample applications in various application development languages.  These include Microsoft Visual Basic, Microsoft Access, Microsoft Visual C++, and Borland Delphi.  More examples may be included in the package in the future and will be made available through our Internet support page of http://www.consoft.com/support.

All of the applications demonstrate the exact same functionality with the different syntax required by the different development languages.  There are several types of samples:

Single User Copy Protection

Single User Copy Protection and Demo Expiration

Sample Network Floating Licensing Implementation

Marx International Crypto-Box® Integration

Advanced Features Not In Sample Code

It is recommended that you read and understand the section Software Licensing  before attempting to experiment with the Sample Applications

TIPS AND TRICKS

When testing the various Trigger Code routines, it can be tedious to actually generate valid Trigger Codes to enter into your application.  To make things easier, modify the Trigger Code screen so that instead of using the result from pp_tcode(), you use the value entered into the input box as the algorithm to enter.  That is, instead of typing in the value of 6885479 which happens to be code 1 for the code entry and computer ID numbers on the Trigger Code screen, simply enter 1 and click Ok.  Don't forget to remove this before releasing your final code.


SAMPLE CODE SINGLE USER COPY PROTECTION

For applications that just require basic single-user copy protection, the sample application called BasicCP is included.  This is a small "Hello World" application that demonstrates:

•	Opening a License File

•	Generating a Computer ID Number

•	Checking for Copy Protection - Single User  validation

•	Disabling menu options when current computer is not authorized

•	Displaying a Trigger Code screen

•	Allowing Unsupervised License Transfers

Before the application displays the main form, the copy protection test is run.  If the test fails, a Message Box appears informing the user that this is an unlicensed copy that needs to be registered before continuing.  The following Trigger Codes are implemented in this application:

•	Code 1 - Copy Protection Authorization

•	Code 2 - Copy Protection De-Authorization

The License File password used in this application is "password" and the Trigger Code seed is 400.

This sample application will create the License File automatically if it doesn't already exist.


SAMPLE CODE SINGLE USER COPY PROTECTION AND DEMO EXPIRATION

For applications that require single-user copy protection and demo expiration, the sample application called AdvLic is included.  This is a "Hello World" application that demonstrates:

•	Implementing basic PPP library security

•	Opening a License File

•	Generating a Computer ID Number

•	Checking for Copy Protection - Single User  validation

•	Checking for Demo Expiration

•	Disabling menu options when demo is expired

•	Displaying a Trigger Code screen

Before the application displays the main form, the copy protection test and demo expiration test is run.  If the copy protection test passes and the expiration type is set to "P" for Payments, the expiration test is executed because the application is in the Payment mode (the software license must be renewed quarterly).  If the copy protection test fails and the expiration type is set to "D" for Demo, the expiration test is also executed.  Different messages are displayed depending on the mode of the application.

The following Trigger Codes are implemented in this application:

•	Code 1 - Copy Protection Authorization - payment due next quarter

•	Code 2 - Copy Protection Authorization - no payments

•	Code 3 - Copy Protection De-Authorization

•	Code 4 - Set Demo Expiration to 20 days from today

•	Code 5 - Extend Payment Expiration for 90 days (one quarter)

•	Code 6 - Release from Payment Expiration

•	Code 7 - Force update of last used date/time fields in case user artificially set date ahead

The License File password used in this application is "password" and the Trigger Code seed is 400.

This sample application will NOT create the License File automatically if it doesn't exist.  This is because we will ship a License File with a hard expiration date embedded in it and we don't want to allow the user to keep deleting the License File to gain 20 more days usage of the product.


SAMPLE CODE NETWORK FLOATING LICENSING

For applications that require network protection where the number of simultaneous users is counted, the sample application called NetFloat is included.  This is a "Hello World" application that demonstrates:

•	Implementing basic PPP library security

•	Opening a License File

•	Determining if application is running across the network using pp_redir()

•	Generating a Computer ID Number

•	Checking for Copy Protection - Network validation

•	Counting simultaneous users using Floating Network Licensing

•	Disabling menu options when license is not valid

•	Displaying a Trigger Code screen

•	Remotely increasing / decreasing the number of allowed users

•	Remotely setting the number of allowed users using pp_ndecrypt()

Before the application displays the main form, the copy protection test is run.  If the test fails, a Message Box appears informing the user that this is an unlicensed copy that needs to be registered before continuing.  If the copy protection test passes but the number of allowed users has been reached, a different message is displayed indicating that all licenses have been used.  The following Trigger Codes are implemented in this application:

•	Code 1 - Copy Protection Authorization - overwrite all entries

•	Code 2 - Copy Protection Authorization - add this computer to list of valid entries

•	Code 3 - Copy Protection De-Authorization

•	Code 4 - Increment number of allowed users

•	Code 5 - Decrement number of allowed users

•	Code 6 - Set number of allowed users using pp_ndecrypt() - seed used is 129.

The License File password used in this application is "password" and the Trigger Code seed is 400.


MARX INTERNATIONAL CRYPTO-BOX® INTEGRATION

For applications that require integration with a Crypto-Box Hardware Key, the sample application called CBox is included.  The PPP system fully integrates the data storage abilities of the Crypto-Box and allows an application to store several License File fields in the Hardware Key itself. Either a permanent or temporary Crypto-Box attachment can be used.  In the permanent environment, the Crypto-Box is always attached in order for the application to run.  The Key will store various counters, bit fields or expiration dates.  The Crypto-Box can also be attached temporarily to transfer software licenses easily and securely.  Also, a customer can be granted a set number of installs through a counter stored in the Key.  The customer simply installs the software on his workstations and attaches the Crypto-Box to each of the workstations long enough to transfer one of the licenses to the workstation's hard drive. The Crypto-Box can then be stored for future use.  Remotely, it is possible to change the counters in the Crypto-Box using the Trigger Code mechanism.

The Cbox sample is a "Hello World" application that demonstrates:

•	Opening a License File that is stored in a disk file

•	Using a Crypto-Box to limit the number of application installations

•	Checking for Copy Protection - Single User validation

•	Disabling menu options when license is not valid

•	Displaying a Trigger Code screen

•	Remotely increasing the number of application installations allowed

•	Remotely setting the number of allowed users using pp_ndecrypt()

Before the application displays the main form, the copy protection test is run.  If the test fails, the application looks for a Crypto-Box to see if there are any installations left.  If none are left, a Message Box appears informing the user that this is an unlicensed copy that needs to be registered before continuing.  If there are installation counts left, this application is automatically licensed on this individual's workstation. The following Trigger Codes are implemented in this application:

•	Code 1 - Copy Protection Authorization - overwrite all entries

•	Code 2 - Copy Protection Authorization - add this computer to list of valid entries

•	Code 3 - Copy Protection De-Authorization

•	Code 4 - Increment number of allowed installations

•	Code 5 - Decrement number of allowed installations

•	Code 6 - Set number of allowed installations using pp_ndecrypt() - seed used is 129.

The file-based License File password for this application is "password" and the Trigger Code seed is 400.  The Crypto-Box-based License File password is that of the Crypto-Box demo kit (listed in the demo kit manual).  For this application, a Crypto-Box Versa or 560 may be used.


ADVANCED FEATURES NOT IN SAMPLE CODE

Every application including Protection Plus Professional can use the library in different ways.  There are some functions included in the library that are not utilized in any of the included sample application.  The following are powerful features of the library that are not documented:

•	The License File can be stored in the Windows registry.  See pp_lfcreate().

•	Utilizing Bit Fields and the User-defined License File Fields, Modular Applications can be built where the entire application set can be distributed to the customer and each of the modules can be licensed through Trigger Codes.


DESCRIPTION OF ACCESS SAMPLES

There are two forms used in each of the database programs, the main form called FORM1 and the unlock form called UNLOCK_FORM.  Each form has an Event Procedure that is run when the form is loaded.  FORM1 also has a routine that is called when the form is unloaded.  The Event procedures can be edited by viewing the On Load and On Unload property in each of the form’s properties menu.  The menu bar used on FORM1 is called “main menu”.  The menu can be edited by running the menu wizard from the Menu Bar property in FORM1’s properties menu .  All of the functions called by the menu bar are located in Module1.  All of the PPP function declarations and other global variables are defined in the declarations portion of Module1.  The main function called Protect_test is also located in Module1.  Protect_test is used to determine the protection status of the program.  The SetMenuItem function is used to gray and ungray the menu items depending of the state of the protected program.


SOFTWARE LICENSING INTRODUCTION

This chapter contains the instructions and examples you need to incorporate the Protection Plus Professional (PPP) system into your application. The information in this chapter is invaluable to you the developer. The Concepts section is a high-level discussion about the use of each of the software licensing mechanisms. The Implementation section follows that gives several techniques to help you get started. In essence, this chapter contains the instructions and examples you need to incorporate the PPP system into your applications.

The Questions And Answers chapter contains many hints and tricks that may be beneficial to anyone implementing the PPP system.

In another chapter, you can find out about the Sample Applications that come with this package; however, we recommend reading and understanding this chapter first.

If you are unfamiliar with the capabilities of PPP, refer to Protection Plus Professional Overview for a description.


CONCEPTS

This section attempts to define all of the terms and theories in the Protection Plus Professional (PPP) system.


LICENSE FILE

An encrypted binary data file that stores license, protection, user, and application-specific information and can be retrieved and modified by the application.  The file size of a License File is 3120 bytes.  The creation and editing of License Files occurs with LFEdit  Once the file is created, it is read and manipulated with the PPP library License File Read/Write Functions from within your application.

License Files can be stored as a file, in the Windows registry, or in a Hardware Key. Refer to Operating System Compatibility to see which options are available.


LICENSE FILE

An encrypted binary data file which stores license, protection, user, and application-specific information and can be retrieved and modified by the application.  The file size of a License File is 3120 bytes.  The creation and editing of License Files occurs with LFEdit  Once the file is created, it is read and manipulated with the PPP library License File Read/Write Functions from within your application.

License Files can be stored as a file, in the Windows registry, or in a Hardware Key.  Refer to Operating System Compatibility to see which options are available.


LICENSE FILE FIELDS

There are several fields reserved in the License File where you can store information that can be referenced by your application.  Access these fields using LFEdit and the License File Read/Write Functions.  Several predefined fields and several user-defined fields are contained in the License File.

A list of the fields available as well as their storage capacity can be found in License File Fields.


LICENSE FILE FIELDS

There are several fields reserved in the License File where you can store information that can be referenced by your application.  Access these fields using a GUI interface LFEdit or through the library via the License File Read/Write Functions.  Several pre-defined fields and several user-defined fields are contained in the License File.

CHAR - 1 byte

LONG - 4 bytes

INT - 2 bytes

COMPANY NAME, CHAR[51]

The name of the company licensed to use the application is generally stored in this field.  This field may be used for other purposes as well.

USER NAME, CHAR[51]

The name of any individual licensed to use the application is generally stored in this field.  This field may be used for other purposes as well.

USER ADDRESS 1 THROUGH USER ADDRESS 3, EACH CHAR[51]

The address of the individual or company licensed to use the application is generally stored in these fields.  These fields may be used for other purposes as well.

USER PHONE 1 THROUGH USER PHONE 2, EACH CHAR[21]

The telephone numbers of the individual or company licensed to use the application are generally stored in these fields.  These fields may be used for other purposes as well.

PRODUCT SERIAL NUMBER (TEXT), CHAR[21]

Product serial numbers are generally broken down into a static alphanumeric portion and an incrementing numeric portion.  This is the alphanumeric portion.

EXPIRATION TYPE, CHAR[2]

This field contains a one-character flag representing the state in which the application should run.  Refer to Expiration Types for a list of the types and their meaning.

USER-DEFINED CHARACTER FIELDS 1 THROUGH 10, CHAR[51]

There are ten user-defined character fields in the License File.

EXPIRATION DATE (SOFT), 3 INTS

The soft expiration date is generally used when a demo should be set to expire a specified number of days after installation.  Refer to Soft Versus Hard Expiration for more information.  This field is only used when the Expiration Type field is "D", "P", or "S".

EXPIRATION DATE (HARD), 3 INTS

The hard expiration date is generally used as a hard limit expiration date where the software will NOT run after this date with no exceptions. This field is only used when the Expiration Type field is "D", "P", or "S".

LAST USED DATE AND LAST USED TIME, EACH 3 INTS

The last used date and time should be stored by pp_upddate() when your application exits.  By running pp_valdate() at the start of your application, you can verify if the user has turned their date back since the last time the application was executed, in an attempt to gain more runtime out of a demo.

USER-DEFINED DATE FIELDS 1 THROUGH 5, EACH 3 INTS

There are five user-defined date fields in the License File.

PRODUCT SERIAL NUMBER (NUMERIC), LONG

Product serial numbers are generally broken down into a static alphanumeric portion and an incrementing numeric portion.  This is the numeric portion.

EXPIRATION COUNT, INT

When the Expiration Type field is "E", the Expiration count and Expiration limit fields are used as counters to gauge when the application has exceeded its demo functionality.  The Expiration count is incremented using pp_countinc() whenever the application has been executed or has performed whatever action is being counted.

EXPIRATION LIMIT, INT

When the Expiration Type field is "E", the Expiration count and Expiration limit fields are used as counters to gauge when the application has exceeded its demo functionality.  The Expiration limit field is generally set by LFEdit before shipping the software or can be remotely changed using Trigger Codes and/or pp_setvarnum().

NUMBER OF CURRENT USERS, INT

Used when limiting the number of LAN users in at network-based application.  This field is generally used in Network Floating Licensing.  In this case, this value is manually incremented and decremented using pp_countinc() and pp_countdec() respectively.  When using this field in Network Fixed Licensing, the value is incremented automatically when a new user has been registered by pp_copycheck() when using the COPY_ADD_AUTO flag.

NUMBER OF ALLOWED USERS, INT

Used when limiting the number of LAN users in at network-based application.  This field is generally used in Network Floating Licensing.  In this case, this value is manually incremented and decremented using pp_countinc() and pp_countdec() respectively.

NUMBER OF USED INSTALLATIONS, INT

This counter along with the Number of allowed installations can be used to restrict how many times a particular application can be installed.  This is typically used when Implementing License Transfers Using Hardware Key.

NUMBER OF ALLOWED INSTALLATIONS, INT

This counter along with the Number of used installations can be used to restrict how many times a particular application can be installed.  This is typically used when Implementing License Transfers Using Hardware Key.

NUMBER OF COMPUTER IDS AUTHORIZED, LONG

Each License File can store up to 500 Computer ID Numbers.  This field contains the actual number of Computer IDs stored in the License File.  It is automatically incremented when new Computer IDs are added by other functions.  This is a read-only variable.

USER-DEFINED NUMERIC/BIT FIELDS 1 THROUGH 5, EACH LONG

There are five user-defined numeric/bit fields stored in the License File.


LICENSE FILE EDITOR (LFEDIT)

The License File Editing Facility (LFEdit) is a Windows-based application that edits and creates License Files. If you have an existing client tracking application that integrates with the PPP system library, you might be able to use the library to create License Files from within this application.  LFEdit also generates Trigger Codes to send remote control commands to your application.


LICENSE FILE EDITOR (LFEDIT)

The License File Editing Facility (LFEdit) is a Windows-based application that edits and creates License Files. If you have an existing client tracking application that integrates with the PPP system library, you might be able to use the library to create License Files from within this application.  LFEdit also generates Trigger Codes to send remote control commands to your application.


LFEDIT FOR DISTRIBUTORS

Similar to LFEdit, LFEdit for Distributors is a Windows-based application that edits and creates License Files. LFEdit for Distributors also generates Trigger Codes to send remote control commands to your application.  This version of LFEdit is intended to be given to distributors of your application who create License Files and/or generate Trigger Codes for your application.  It is protected by a Hardware Key, can only be executed from one computer, and the number of Trigger Codes can be remotely controlled so that you can prevent distributors from authorizing an unlimited number of applications.

LFEdit for Distributors is available to people who licensed the Enterprise Version of PPP.  Contact Marx International to purchase the necessary Hardware Keys and to receive LFEdit for Distributors.


LFEDIT FOR DISTRIBUTORS

Similar to LFEdit, LFEdit for Distributors is a Windows-based application that edits and creates License Files. LFEdit for Distributors also generates Trigger Codes to send remote control commands to your application.  This version of LFEdit is intended to be given to distributors of your application who create License Files and/or generate Trigger Codes for your application.  It is protected by a Hardware Key, can only be executed from one computer, and the number of Trigger Codes can be remotely controlled so that you can prevent distributors from authorizing an unlimited number of applications.

LFEdit for Distributors is available to people who licensed the Enterprise Version of PPP.  Contact Marx International to purchase the necessary Hardware Keys and to receive LFEdit for Distributors.


COMPUTER ID NUMBER

A number generated based upon the computer hardware.  There are several algorithms available to generate this number.  The user of the library can decide which algorithms to use.  The algorithms included involve motherboard, hard drive, and network server identification.  The available algorithms depend on the operating system that is currently running and the current hard drive file system being used (DOS/FAT or NTFS).

For more information, see Generating Computer ID Numbers.


COMPUTER ID NUMBER

A number generated based upon the computer hardware.  There are several algorithms available to generate this number.  The user of the library can decide which algorithms to use.  The algorithms included involve motherboard, hard drive, and network server identification.  The available algorithms depend on the operating system that is currently running and the current hard drive file system being used (DOS/FAT or NTFS).

For more information, see Generating Computer ID Numbers.


TRIGGER CODE

Up to 50 events can be fired in your application remotely by exchanging a series of numbers with the end-user.  The end-user is presented with a dialog box with two numbers on it and is asked to enter a number.  These two numbers are sent to you via phone, FAX, e-mail, etc.

Once your application is installed, your client will probably need to contact you for one or more Trigger Codes to partially or fully activate the application. You can even use Trigger Codes to remotely access or activate special functions that your client does not know exist.

The generation of Trigger Codes is possible by using either LFEdit or TrigLib. Either method generates the exact same results.

Refer to Sending Trigger Codes To An Application for more information.


TRIGGER CODES

Up to 50 events can be fired in your application remotely by exchanging a series of numbers with the end-user.  The end-user is presented with a dialog box with two numbers on it and is asked to enter a number.  These two numbers are sent to you via phone, FAX, e-mail, etc.

Once your application is installed, your client will probably need to contact you for one or more Trigger Codes to partially or fully activate the application. You can even use Trigger Codes to remotely access or activate special functions that your client does not know exist.

The generation of Trigger Codes is possible by using either LFEdit or TrigLib. Either method generates the exact same results.

Refer to Sending Trigger Codes To An Application for more information.


COPY PROTECTION - SINGLE USER

Copy Protection is a method of securing and controlling the distribution of your applications by prohibiting unauthorized duplication.  In the single user environment, the user will install the application and contact someone for an appropriate Trigger Code. When a valid Trigger Code is entered, the Computer ID Number is generated on the computer and then written to the License File.  When the software is executed from then on, the Computer ID Number on the current computer must match the one in the License File.


COPY PROTECTION - NETWORK

Copy Protection is a method of securing and controlling the distribution of your applications by prohibiting unauthorized duplication.  In a network environment, the user will install the application and contact someone for an appropriate Trigger Code.  When a valid Trigger Code is entered, the Computer ID Number is generated on the computer or network and then written to the License File.  When the software is executed from then on, the Computer ID Number on the current computer or network must match one stored in the License File.

There are two types of Network Copy Protection:

•	Network Fixed Licensing

•	Network Floating Licensing


NETWORK FIXED LICENSING

A limited number of workstations may access the networked application.  The first licensed number of workstations will be the only ones that can access the software.  The software will run from the network server, but the Computer ID Number will be generated on the local hardware.  Therefore, the application will be permanently licensed to the first licensed number of workstations.

Refer to Implementing Fixed Network Licensing for more information.


NETWORK FLOATING LICENSING

Any workstation on the network that has access to the networked application may execute it provided that the number of simultaneous users has not reached its predefined limit.

Refer to Implementing Floating Network Licensing  for more information.


NETWORK SEMAPHORE FILE

A separate file that contains no useful data is used to assist in a network floating license application.

See Network Semaphore File for a deeper overview.


NETWORK SEMAPHORE FILE

A separate file that contains no useful data is used to assist in a network floating license application.

Counting the number of simultaneous users can be accomplished in several different ways.  One way includes incrementing a counter when the application is started and decrementing the counter when the application closes, making sure that the number of licensed users is not exceeded before allowing the application to run.

This technique is good until the application does not exit properly - either because the power went out, the application crashed uncontrollably, or the user rebooted their computer.  This is where a network semaphore file comes in.  You designate a common network directory in which to place meaningless semaphore files and, through exclusive file locking techniques, PPP can accurately count the number of simultaneous users.  A file is created for each workstation.  When the workstation exits (even improperly), a simple reboot of their computer will almost guarantee that the license they were using will be freed up to be used by someone else.

Refer to Implementing Floating Network Licensing for more information.


EXPIRATION TYPES

The Expiration Type is an indicator stored in the License File. There are three Expiration Types that have a date associated with them: Demo, Payments, and Shareware. Another type of expiration, Execution Count, is invoked when a numeric counter exceeds a predetermined value. Finally, for applications with no expiration, use an Expiration Type of None.

There is no significance between the Demo, Payment, and Shareware Expiration Types.  They all let the application expire on a given date.  Having three different date Expiration Types allow you to programmatically manage your application in up to three different modes that expire on a given date.  Refer to the example below.

For example, if your software is leased, you can send out a demo to a prospective customer.  The demo will expire after 30 days, using the Demo Expiration Type.  You define Demo mode to not allow more than 10 records in your main database.  If the customer purchases the software, you can remotely convert the software to a Payment Expiration Type and set the expiration date to 1 year from today which is when the lease is renewed.  Since the application is in Payment mode, it will still check for expiration but will no longer limit the main database to 10 records.

The indicator stored in the License File is the first character of the above-mentioned Expiration Types.  E.g. "D", "S", "P", "E", or "N".

DEMO

Use the Demo Expiration Type when you want to disable your application on a selected date. This approach uses an absolute date that is independent of the day of the week.

PAYMENTS

Use the Payment Expiration Type when you want to disable your application on a particular business day of the month. If a selected date falls on a weekend, the next Monday becomes the disable date. This avoids your application from becoming disabled during a weekend when you or your distributor may not be available to supply Trigger Codes.

This approach allows you to disable your application at any predetermined interval (every week, month, two months, year, etc.).

SHAREWARE

Use the Shareware Expiration Type when you distribute your application as a Demo product through Shareware networks. Like the Demo Expiration Type, Shareware allows you to disable your application on a particular date.

Additionally, Shareware allows you to disable specific functions in your application. This promotes the purchase of your application. You can even develop your application for sale as fully functioning demo copies for one client and use the same application for Shareware distribution with limited functionality for another client.

EXECUTION COUNT

Use the Execution Count Expiration Type to disable your application after a predetermined number of executions.

Additionally, use this type of expiration to limit the use of the features in your application.

NONE

The None Expiration Type allows your application to execute without any expiration logic. This is useful for setting your application for no further expiration processing.

Refer to Implementing Product Expiration for more information.

Applications may also be limited to run only for a specified amount of time each execution.  Refer to Implementing Minute Expiration.


SOFT VERSUS HARD EXPIRATION

There are two integrated expiration dates in the PPP system - soft and hard expiration.  You can specify a soft expiration date of say, 30 days from the date of installation (you ship the license file with 0/0/0 in the soft expiration date field), but you mandate a hard expiration date of say, 12/31/97.  This way, the user can have a 30 day demo, but if they figure out how to re-install the package and gain 30 more days, they will never be able to run the software past the hard expiration date.

Refer to pp_expired() for more information.


SOFT VERSUS HARD EXPIRATION

There are two integrated expiration dates in the PPP system - soft and hard expiration.  You can specify a soft expiration date of say, 30 days from the date of installation (you ship the license file with 0/0/0 in the soft expiration date field), but you mandate a hard expiration date of say, 12/31/97.  This way, the user can have a 30 day demo, but if they figure out how to re-install the package and gain 30 more days, they will never be able to run the software past the hard expiration date.

Note that if you only have one expiration date, you should always use the HARD expiration date and leave the SOFT expiration date 0/0/0.

Refer to pp_expired() for more information.


MODULAR APPLICATION

A Modular Application is one that contains several components that can be independently licensed.  An example of this is an accounting package.  The general ledge, payroll, accounts payable, and accounts receivable modules may be shipped to the end user, but only the modules purchased will be active upon execution.  Later, a Trigger Code can be given to a Client to change the licensing information after payment arrangements have been made.


MODULAR APPLICATIONS

A Modular Application is one which contains several components, which can be independently licensed.  An example of this is an accounting package.  The general ledge, payroll, accounts payable, and accounts receivable modules may be shipped to the end user, but only the modules purchased will be active upon execution.  Later, a Trigger Code can be given to a Client to change the licensing information after payment arrangements have been made.

Refer to Implementing Modular Applications for more information.


HARDWARE KEY

A small hardware device that attaches between a computer and a printer on a parallel port.  This device can store a License File for an application to use and can be used for a copy protection test as well.  The PPP system has been certified to work with two Hardware Keys from Marx International - the Crypto-Box Versa and Crypto-Box 560.  For further information contact Marx International at:

USA:

(800) MARX-INT, (+1) 404 321-3020 (international)

E-mail: info@marx.com

Web: http://www.marx.com

Fax   :  (+1) 404 321-0760

FRANCE:

CRYPTO-BOX S.A.R.L.

BP 127, F-67303 Schiltigheim-Strasbourg CEDEX

Phone :  (+33) 88 81 40 31

Fax   :  (+33) 88 81 20 28

GERMANY:

MARX DATENTECHNIK GmbH

D-85104 WACKERSTEIN

Phone :  (+49) 8403 1555

Fax   :  (+49) 8403 1500


LIBRARY SECURITY

Due to the architecture of Windows, Dynamic Link Libraries (DLLs) are modular and replaceable.  This means, that provided someone knows all of the functions and syntax of the PPP system, they could write their own DLL that looks like the PPP library and returns fake values that allow your application to continue execution, even though it should not.  There are various levels of protection you can add to your application to prevent this.  This concept only applies to the DLL versions of PPP.  The static libraries are much more difficult to defeat.

Refer to Implementing Library Security for more information.


ACTIVEX

Microsoft's new term for OLE controls targeted at Internet control functionality.


BIT FIELD

A method of storing several on / off states in one numeric value.  The bits are encoded using binary value manipulation.  Several PPP functions help in managing Bit Fields.


CLIENT

Purchaser of your application.


CODE ENTRY NUMBER

A pseudo-random number based upon a random number and the computer’s system date.  It is this random number that makes each Trigger Code session unique.


CTS

Client Tracking System - a Windows-based application that stores protection, version, and customer information about the products you sell.


DISTRIBUTOR

Company or person that distributes your products or services to a Client.


FILE ATTRIBUTES

Normal DOS file system attributes consist of Archive, System, Read-only, and Hidden.  This is also true of NTFS file systems.  Each file has its own set of attributes.  Several PPP functions allow for the manipulation of these attributes.


KEYLIB

Function library used to implement the majority of the software licensing functionality of Protection Plus Professional.


OLE

Microsoft’s Object Linking and Embedding design specification.


PASSWORD (LICENSE FILE)

A user-defined string password used during the encryption of License File.  This string must be at least 3 characters.  At least a 10 character password is recommended.


PPP

Protection Plus Professional.


SEED NUMBER

A user-defined number used in the Trigger Code and number encryption routines.  The Trigger Code mechanism generates unique numbers for each unique Seed Number.


TRIGLIB

Function library used to generate Trigger Codes.  This library can be used by any programming language to generate Trigger Codes.  Also, TrigLib can be used to create a limited unlocking utility with counter restrictions, which can be used to track the number of codes generated by a distributor.


V3

PPP Version 3.0


V4

PPP Version 4.0


VALIDATION CODE

Secret number used by the pp_libtest() algorithm to verify PPP library integrity.  Each library ships with three Validation Codes and matching Validation Results.  This mechanism is used to help verify the integrity of the DLL.  You call pp_libtest() with a Validation Code and it should return the matching Validation Response.  If the response does not match, no further calls to the PPP library should be made.


VALIDATION RESULT

Result code returned by pp_libtest() given a particular Validation Code.


OTHER TERMINOLOGY AND DEFINITIONS

The following contains the terminology and definitions commonly used throughout this manual.

ACTIVEX(TM)

Microsoft’s new term for OLE controls (OCX).

BIT FIELD

A method of storing several on / off states in one numeric value.  The bits are encoded using binary value manipulation.  Several PPP functions help in managing Bit Fields.  Up to 32 bits can be stored in a PPP bit field.

CLIENT

Purchaser of your application.

CODE ENTRY NUMBER

A pseudo-random number based upon a random number and the system date of the computer.

COMPUTER NUMBER

A number generated based upon the computer hardware.  There are several algorithms available to generate this number.  The user of the library can decide which algorithms to use.  The algorithms included involve motherboard, hard drive, and network server identification.  The available algorithms depend on the operating system that is currently running and the current hard drive file system being used (DOS/FAT or NTFS).

COPY PROTECTION

Method of securing and controlling the distribution of your applications by prohibiting unauthorized duplication.

CTS

Client Tracking System - a Windows-based application that stores protection, version, and customer information about the products you sell.

DISTRIBUTOR

Company or person that distributes your products or services to a Client.

OLE

Microsoft’s Object Linking and Embedding design specification.

PASSWORD (LICENSE FILE)

A user-defined string password used during the encryption of a License File.  This string must be at least three characters.  At least a ten character password is recommended.

PPP

Protection Plus Professional.

SEED NUMBER

A user-defined number used in the Trigger Code and number encryption routines.  The Trigger Code mechanism generates unique numbers for each unique Seed Number.

V3

PPP Version 3.0

V4

PPP Version 4.0

VALIDATION CODE

Secret number used by the pp_libtest() algorithm to verify the PPP system library integrity.  Each library ships with three Validation Codes and matching Validation Result.  This mechanism is used to help verify the integrity of the DLL.  You call pp_libtest() with a Validation Code and it should return the matching Validation Result.  If the result does not match, no further calls to the PPP system library should be made.

VALIDATION RESULT

Result code returned by pp_libtest() given a particular Validation Code.


IMPLEMENTATION

The remainder of this chapter demonstrates various ways to use the power and versatility of the PPP system. There are several Sample Applications installed with the package. These files are ready to compile and run. Each sample source file contains a reference to applicable files as well as a detailed description.

To optimize experimentation with Trigger Codes, use a multitasking environment (e.g. Windows) allowing for generation of Trigger Codes.  Run your application in one window and LFEdit in another window.

Please refer to the text in Overview - KeyLib for function syntax and descriptions.

If this section leaves you with unanswered questions, refer to the Questions And Answers section before seeking Technical Support.


DETERMINING APPLICATION REQUIREMENTS

Before implementing the software licensing capabilities of the PPP system, there are several issues to resolve. For instance, your application needs to reference a License File in order to implement various levels of software licensing. Your application needs to receive Trigger Codes from its user in order to activate your application. Finally you need to determine what types of software licensing (e.g. expiration versus copy protection, etc.) you require to secure your application.

CAUTION

In order to disable your application, it must have the appropriate source code to check the License File.  Shipping a License File will not disable your application automatically.

The following sections discuss:

•	License File Read/Write Functions

•	Sending Trigger Codes To An Application

•	Generating Computer ID Numbers

•	Implementing Product Expiration

•	Implementing Single User Copy Protection

•	Implementing Fixed Network Licensing

•	Implementing Floating Network Licensing

•	Implementing Modular Applications

•	Implementing Library Security

•	Implementing Minute Expiration

•	Implementing Unsupervised License Transfers

•	Implementing License Transfers Using Hardware Key

It is important to understand that these techniques show you some of the possible ways to implement the PPP system in your application.

The most powerful asset of the PPP system is that the application is only limited by your imagination.


LICENSE FILE READ/WRITE FUNCTIONS

The License File Fields contained inside a License File can be read and written to from within your application.  A majority of the PPP system library functions rely on the data stored in this file. This file is generally stored on the application installation diskette and copied by the installation program.  There are three functions that read and three functions that write the data.

pp_getvarchar()	Gets a character-type License File variable
pp_getvardate()	Gets a date-type License File variable
pp_getvarnum()	Gets a numeric-type License File variable
pp_setvarchar()	Sets a character-type License File variable
pp_setvardate()	Sets a date-type License File variable
pp_setvarnum()	Sets a numeric-type License File variable

The License File is opened with pp_lfopen().  This function returns a handle that is required by the six read and write functions.  These functions directly read and write to/from the License File stored on disk as they are called. Before exiting the application, the function pp_lfclose() should be called to free up all resources initialized with pp_lfopen().

In a network environment where several fields should be updated in time coherency, the functions pp_lflock() and pp_lfunlock() can be used.

There is a core set of functions in the PPP system library to access the License File. Those functions provide for the following capabilities:

•	Initialize a License File Handle used by the majority of the PPP system functions:  pp_lfopen()

•	Read the values from the License File: pp_getvarchar(), pp_getvardate(), and pp_getvarnum().

•	Modify the values in the License File: pp_setvarchar(), pp_setvardate(), and pp_setvarnum().

•	Close the handle opened with pp_lfopen():  pp_lfclose()

There are several other functions that allow the License File to be manipulated:

•	Increment or decrement a counter value:  pp_countinc() and pp_countdec()

•	And several more…

When your application requires the creation of a License File, it must create a blank file with pp_lfcreate(), open the file with pp_lfopen() and set the value of each of the variables stored in the file.

The list of fields contained in the License File are listed in the descriptions of the functions pp_getvarchar(), pp_getvardate(), and pp_getvarnum().

The License File can now accommodate the System, Hidden, and Read-Only file attributes.  These attributes along with the time/date stamp of the file are kept the same even after writing to the file.


SENDING TRIGGER CODES TO AN APPLICATION

Trigger Codes are based on the system date of your client's computer, a randomly generated number, and your client's Computer ID Number.

Use Trigger Codes as the primary method of activating your entire application or functions within it. You can program an application to stimulate the request for Trigger Codes in a way that is not apparent to the client. For instance, a particular function key (e.g. [F5]) could display the critical information needed to generate the Trigger Codes. Once displayed, this information prompts the client to contact you or your distributor via phone, fax, postal service, or E-Mail to request an appropriate Trigger Code.

To implement this concept, establish a function to invoke a special unlock code source procedure. This procedure should accomplish the following tasks:

•	Generate the Computer ID Number and the Code Entry Number by invoking pp_compno() and pp_cenum(), respectively.

•	Display a message with the Computer ID Number and Code Entry Number that the client supplies to you or your distributor.

•	Prompt the client to enter the Trigger Code received by you or your distributor.

•	Decode the number entered by the client by calling the pp_tcode() function that passes a return code value between 0 and 50.

•	Activate the appropriate application functions depending on the return code value.

If during this task the client contacts you, you will ask them for the Computer ID Number and Code Entry Number. You would then supply the client with the appropriate Trigger Code depending on the desired function requiring activation.

In certain libraries, the function pp_getcode() is available to automate the creation of a dialog box as described in the above steps.


GENERATING COMPUTER ID NUMBERS

The primary purpose of the Computer ID Number is to identify a specific computer. Any one of the several algorithms listed in pp_compno() allow you to generate a Computer ID Number.  In most cases, this number is unique.

Refer to pp_compno() for a detailed explanation and use of each these algorithms.

Computer ID Algorithms

ID TYPE	DESCRIPTION
ROM BIOS	Sufficient security for most applications. Every different model of computer should indicate unique data in its ROM BIOS.  Some models are also serialized, generating a different number for identical machines.
HD Serial	DOS 4.0 or higher operating systems generate a random serial number for a drive during formatting.
HD Lock	Highest security available. Creates a nonmovable file and records its location. It is very unlikely for two computers to store this file in the same location.
Net Name	Server profile generated by determining the network server name and volume for a given drive letter.
MAC Address	Calculates a number based upon the Ethernet (MAC) address of an installed Ethernet LAN adapter.
CAUTION

Due to network limitations, it is only possible to use the Net Name algorithm on a network server.  It is not possible to use any of the other algorithms in this situation unless referencing local hardware in the function call.

Refer to Operating System Compatibility to see which options are available.

In the case that you find your own mechanism for generating a Computer ID Number, this number can be used throughout the PPP system in place of any Computer ID Number generated by pp_compno().


IMPLEMENTING SINGLE USER COPY PROTECTION

The copy protection functions of the PPP system library allow significant flexibility in controlling the illegal distribution of your applications. The following outlines the necessary source code to copy protect an application:

•	Decide what type of hardware identification to use for the Computer ID Number - refer to Generating Computer ID Numbers.

•	Determine how your application should react when an illegal copy is detected. Your application can take any of the following actions if the copy protection test fails:

1	Display an error message and exit.

2	Disable any number of critical functions.

3	Convert the Expiration Type to Demo - Say you decide that when your application is executed on an unauthorized computer, it will be converted into a 14-day demo notifying the client that such an event has taken place. The client would then be prompted to contact you or your distributor for a Trigger Code to remove the demo Expiration Types and allow full use.

Keep in mind that the first time your application is executed on the client's computer, it will not have been unlocked. Therefore, it will fail the copy protection test.

•	Implement Trigger Code procedure as described in Sending Trigger Codes To An Application.

•	Assign a Trigger Code procedure to authorize the host computer: pp_copyadd().

•	Determine if your application is authorized on the host computer: pp_copycheck().

Typically, a developer passes the Computer ID Number from pp_compno() to pp_copycheck() and pp_copyadd() to authorize and verify the host computer. It is possible for you to create a home grown algorithm to create a Computer ID Number.


IMPLEMENTING UNSUPERVISED LICENSE TRANSFERS

From time to time, clients need to move licensed software from one machine to another.  The most secure way of implementing this is through the Trigger Code mechanism.  In this case, the user will (optionally) call for a code to de-authorize their current computer and then call for a code to authorize the new computer.  In the single user environment; however, this license transfer scheme can be accomplished without having the user call for Trigger Codes.

To transfer a license from one computer to another, have the user install the software on the second machine.  When the software fails the copy protection test, you can give them an option to start the license transfer process.  This menu option will call pp_transfer() to create a License File on a floppy diskette with the Computer ID Number of this machine in a special location in the file.  The Computer ID Number is obtained from pp_compno().

The client will then need to run the software on the licensed computer.  They will need to have a mechanism to transfer this license to the diskette that was created in the previous step.  This transfer process also takes place with pp_transfer().  During this step, pp_transfer() moves the new ID number of the new computer from the special location to the list of authorized computers on the License File on the floppy and then removes the current computer from the list of authorized ones in the License File stored on the local computer.  The last step is to simply move the License File from the floppy disk onto the new computer to be licensed.

There are different parameters passed to pp_transfer() between these two steps so it knows which part of the license transfer procedure it should be executing.  This three-step process is required to help reduce the number of ways the user can end up illegally transferring the software to multiple machines.

CAUTION

If the user totally backs up the application directory, completes the transfer of the license to a new computer and restores the directory, the first application may run.  It is recommended to use pp_checksum() to monitor the checksum of the file and store this information in a separate directory so that if the user restores their application directory after a license transfer, the application will detect the attempt of tampering.

Also refer to Implementing License Transfers Using Hardware Key


IMPLEMENTING FIXED NETWORK LICENSING

In Fixed Network Licensing, a License File on the server drive stores the Computer ID Number of each authorized computer on the LAN, using an algorithm that generates a number based upon the local client hardware.  The first licensed number of workstations to access the application will be the only ones licensed.

Let’s assume you agree to authorize the execution of your client’s server copy on seven workstations.

1	Set the License File LAN Limit field to seven.

2	As each of the seven workstations executes your application, the function pp_copycheck() will see if the current computer is authorized.  If not, and if pp_copycheck() is told to automatically add the new license, the server copy is updated with the Computer ID Number of this workstation.

3	When the number of authorized workstations reaches seven, the PPP system prevents all other workstations from executing a copy of your application.  There will then be seven Computer ID Numbers stored in the License File.

You optionally set the number of workstations allowed in one of the user-defined fields in the License File (represented here by X). The client calls you or your distributor and receives a Trigger Code for any computer on the LAN. The Trigger Code causes the LAN Limit field to be set to the number of allowed users.  From that point on, your application is armed and X number of workstations can execute it. The first X number of workstations have their Computer ID Number placed into the License File. Only those workstations can use the program. Any additional workstations attempting to execute the application will return a failure from pp_copycheck().

CAUTION

A drawback to this technique is that you must set the LAN limit to the exact number of workstations allowed. In the event the limit was set to ten workstations and only eight workstations were logged, the application files could be copied to another network and the system would work. This is provided that the License File is copied with your application.

When pp_copycheck() is used in the automatic-add mode it will perform these steps:

1	Is this Computer ID Number already licensed?

2	If yes, return success value.

3	If no, are there any open workstations left in the limit?

4	If yes, enter the Computer ID Number in the License File; return success value.

5	If no, return failure value.


IMPLEMENTING FLOATING NETWORK LICENSING

This type of network restriction allows you to regulate the number of concurrent users executing the application at one time. You decide the maximum number of workstations using your application simultaneously. Set the number of workstations allowed in the LAN Limit field in the License File .

When copy protection is desired in a Network Floating Licensing scheme, it is similar to the single user form of copy protection. In most cases, the License File has only one entry with the Computer ID Number generated on the information derived from the server drive letter.  To implement copy protection tying the software to a network drive, follow the same instructions under Implementing Single User Copy Protection. Instead of using a Computer ID Number from the client machine, use one of the algorithms that generate a number from the server.  If your software may be installed on a Peer-to-Peer network such as Novell Lite, Lantastic, or Windows Networking, be sure to read about Special Notes on Peer-to-Peer Networks.

UP / DOWN COUNTER

There are two ways to implement the simultaneous user counting.  The first involves manipulating an encrypted up/down counter stored in the License File.

•	In the beginning of an application, implement a test to identify when the limit has been reached, using pp_lanactive() and pp_lancheck().

•	Using the library functions, you can manipulate the maximum number of allowable workstations and the current number of workstations through the functions pp_setvarnum(), pp_countinc(), and pp_countdec().

In the case where the limit has not been reached, your application can increment the number of current workstations and continue. If the limit has been reached, your application would typically display a message and exit.

A Trigger Code procedure can be used to dynamically alter the workstation parameters.  Using pp_nencrypt() along with the Trigger Code procedure, you can set the number of allowed users to a predefined number by having the user enter a larger number (the actual number is encrypted through a larger number).

CAUTION

Using the above technique, your application must incorporate the PPP system decrement workstation functions in its error recovery routines to reset the workstation counter when a run-time error occurs.

NETWORK SEMAPHORE FILES

Using an exclusive file locking technique, Network Semaphore Files can be used to accurately count the number of current users of an application.  You specify the path and file prefix to be used for the semaphore files.  One file is created per workstation using the path and prefix you specified, while appending a sequential number.

•	Optionally count the number of used licenses using pp_semcount().

•	Attempt to obtain license using pp_semopen().  This will keep the semaphore file open on the network exclusively.

•	When exiting your application, close the file using pp_semclose().

If for some reason, your application does not execute pp_semclose(), rebooting the machine should free up the license by letting the network close the exclusive lock on the file.  On older network operating systems, it may be necessary for the station that exited improperly to run the application and exit safely for the license to be freed up.

NETWORK SERVER COUNTING

In the future, a network server component can be used to track the licenses of a client/server application.  A piece of software will be running in a network server waiting for connections.  Client machines requesting a license token can contact a server.  If a license is available, the client machine will run, otherwise it will not.  The license counting is managed by the server component.


SPECIAL NOTES ON PEER-TO-PEER NETWORKS

When using Network Fixed Licensing scheme on a peer network such as Lantastic, Netware Lite, Windows Networking, etc., there are no special notes.  There is one Computer ID Number stored in the License File for each workstation since the algorithm used is generating the number based upon the local hardware.

When using Network Floating Licensing, where you don't want to lock the authorization to the individual workstations, there is a trick that must be played in order to get the software to become authorized.  Two computer ID numbers need to be stored - one for the server using a piece of server hardware (BIOS, Hard drive, etc.), and one for the server as seen by all the workstations (Net name).

The function pp_redir() must be used to determine if the software is currently running from the peer server or from across a network.  When executing pp_copycheck(), switch the algorithm used in pp_compno() depending on from which hardware you are running.  Use computer number from server COMPNO_BIOS, HDSERIAL, or HDLOCK.  Use the computer number from COMPNO_NETNAME for all workstations.

You can either give two Trigger Codes to the customer - one to store the Computer ID Number for the server with pp_copyadd() and one to store the Computer ID Number for the set of workstations with the same function.  Or, you can set the number of allowed users to two, and use pp_copyadd() with the automatic add parameter specified so that both numbers get stored automatically just by executing the application.

If the software is then copied after this procedure is complete, it will not run.


IMPLEMENTING PRODUCT EXPIRATION

The Expiration Type is an indicator stored in the License File.  Expiration Types allow for another approach to software licensing. Implement Expiration Types as follows:

•	Choose the type or types of expiration processing to incorporate in your application.

•	Implement Trigger Code procedure as described in Sending Trigger Codes To An Application.

•	Be sure you understand how to Read and Write License File Variables.

•	Optionally at runtime, determine the current Expiration Type: pp_getvarchar().

•	Determine if your application has expired: pp_expired().

•	Insure that the system clock has not been reset: pp_valdate() and pp_upddate().

•	Optionally disable features when running in a demo mode.

After your application determines the Expiration Type, it can then execute various functions based upon the type. For example, if the Expiration Type was Shareware, your application could restrict all vital functions. This would still allow your client to review your application. Supplying the interested client with a Trigger Code allows the same application to automatically convert from Shareware to Commercial use by releasing all suspended functions.

In addition, your application can achieve monthly payment arrangements by changing the expiration parameters from within a Trigger Code procedure while using the License File Read/Write Functions.

CAUTION

If your application initially goes out as an executable limit demo and becomes unlocked, you might want to destroy (overwrite, not just erase) the License File from the floppy disk upon initialization. This is so that the smart client cannot copy it and have more time with the demo than desired.

Storing Execution limit and other counters in the License File are most secure when stored in a Hardware Key License File.


IMPLEMENTING MODULAR APPLICATIONS

Implementing a Modular Application can be done in two different ways.  A separate License File can be created for each application, keeping track of Expiration Types and dates, copy protection information, etc. on a module to module basis.  This method gives the most flexibility.

In another approach, a single License File can be used for all applications.  Bit Fields and user-defined License File Fields can be set up to store the state of the various modules.  Bit Fields are manipulated with pp_bitclear(), pp_bitset(), and pp_bittest().


IMPLEMENTING LIBRARY SECURITY

The Library Security functions of PPP allow you to help eliminate the possibility of a user replacing the PPP DLL with another dummy DLL that returns success to all of the functions.

PARTIAL SECURITY

Use the function pp_libtest() along with the Validation Code and Validation Result pairs of numbers that you should have received with your library.  Simply pass the Validation Code to pp_libtest() and the return value should be the Validation Result.  If the numbers do not match, your application should abort processing immediately to avoid having your password stolen.  The Sample Applications demonstrate this type of security.

ADVANCED SECURITY

Find the actual DLL that your application will be using when it calls the DLL functions and perform some form of checksum on the DLL file itself.  Make sure that the calculated checksum of the file is consistent.  If it ever changes between executions, your application should abort processing immediately to avoid having your password stolen.

A simple checksum routine will open the file for read in binary mode, read each byte of the file one byte at a time and then sum the bytes together.  The summation of the bytes should always be the same.

Be sure to use the same DLL search procedure that the running operating system has in order to find the same DLL that will be loaded by your application.

DLLs can be stored in the application directory or in the Windows System directory.  When Windows searches for the DLL to load, it follows different searching techniques in order to find the DLL.  In the event your computer has multiple copies of the PPP DLL, it is important to know the different searching rules abided by the version of Windows running.


IMPLEMENTING MINUTE EXPIRATION

Creating a demo which only runs for a specified number of minutes is very simple to accomplish. The function pp_timerstart() is called at the beginning of the application and returns a number that indicates the current date and time.  Periodically, the function pp_timercheck() is called to verify the number of minutes has not expired.  When the timer is expired, your application can display a message and stop working.


IMPLEMENTING LICENSE TRANSFERS USING HARDWARE KEY

Using a Marx International Crypto-Box® to store software license information can be a very powerful tool.  There is a pre-defined amount of RAM available in these keys which we store a subset of the License File fields.  The function definitions for pp_getvarchar(), pp_getvardate(), and pp_getvarnum() list the available fields.  The easiest way manage a software license transfer is to use the number of allowed installations and the number of used installations fields.  Simply use pp_lfcreate(), pp_lfopen(), and pp_lfclose() to manage the License File stored in the key, then manipulate the License File Fields.  PPP will make sure the key is attached and valid before allowing any transfers to take place.


OPERATING SYSTEM COMPATIBILITY

This section contains the various library and operating system compatibility matrix.

LICENSE FILE STORAGE

Library	LF_FILE	LF_REGISTRY	CRYPTO-BOX
Win16 DLL	X	X	X
Win32 DLL/OCX	X	X	X
CA-Clipper	X
FoxPro/DOS	X
FoxPro/Win	X
"C"/DOS	X
Note that the file modification date/time is not updated during writes to help hide the fact that this file is being modified.  With the exception of the Win32 DLL, the date can not be changed by the library on License Files located on a network drive.  This is a documented Microsoft problem.

COMPUTER ID NUMBER GENERATION

Library	BIOS	HDSERIAL	HDLOCK	NETNAME	MAC ADDR	CRYPTO-BOX
Win16 DLL	All	2,3,4,5	1-4	All	N/A	7
Win32 DLL/OCX	All	2,3,6	1-4	All	All, 9	7
CA-Clipper	All	2,3,4,5	1-4	All	N/A	N/A
FoxPro/DOS	All	2,3,4,5	1-4	All	N/A	N/A
FoxPro/Win	All	2,3,4,5	1-4	All	N/A	7

1 = DOS (any version)

2 = DOS 4.0 or higher

3 = Windows 3.x / Windows for Workgroups 3.11

4 = Windows NT (drive formatted as FAT)

5 = Windows NT (user running application must be in local group Administrators)

6 = Windows NT (FAT or NTFS - no restrictions on Administrator privileges)

7 = Requires Marx International device driver on Windows 95 or Windows NT

8 = Does not support FAT32 partitions

9 = Does not support Win32s

FAT = File Allocation Table (as opposed to NTFS or HPFS)


TRIGLIB OVERVIEW

Function library used to generate Trigger Codes.  Normally, Trigger Codes are generated with LFEdit.  In addition, this library can be used by any programming language to generate Trigger Codes.  Also, TrigLib can be used to create a limited unlocking utility with counter restrictions, that can be used to track the number of codes generated by a distributor.  TrigLib functions are available only in the extra library supplied with the Enterprise Edition version of the PPP system.  These functions are used to generate Trigger Codes in any application necessary.

pp_cedate()	Determines a client’s system date from a code entry number
pp_ctcodes()	Determines a valid Trigger Code for given parameters


PP_CEDATE()

Determine a client's system date from a code entry number

Applies to:

"C"/DOS, CA-Clipper, FoxPro, Win16, Win32   (Enterprise Edition)

Syntax-VB:

Declare Sub pp_cedate(ByVal cenum As Long, ByRef month As Long, ByRef day As Long, ByRef year As Long)

Syntax-C:

VOID pp_cedate(LONG cenum, LPLONG month, LPLONG day, LPLONG year)

Arguments:

<cenum> is a code entry number given by pp_cenum()

<month> is a buffer in which to place the month

<day>   is a buffer in which to place the day

<year>  is a buffer in which to place the year

Returns:

VOID - nothing

Description:

The Trigger Codes are based upon the client’s system date. The value of the client's system date is passed to you or your distributor's computer via the code entry number.  This function allows you or your distributor to determine the actual value of the client's system date using the code entry number displayed on their Trigger Code screen.

This is typically used when the software is leased or in demo mode and you want to inspect your customer’s system date before giving them a Trigger Code that might set an expiration date that is relative to today’s date.

This function is located in TrigLib, not KeyLib.  Before attempting to access this function, be sure you purchased it.

Example:

While there is no practical example for this function, a typical use would be to verify a client's system date before producing Trigger Codes.

See Also:

PP_CENUM()


PP_CTCODES()

Determine Trigger Codes

Applies to:

"C"/DOS, CA-Clipper, FoxPro, Win16, Win32     (Enterprise Edition)

Syntax-VB:

Declare Function pp_ctcodes(ByVal code As Long, ByVal cenum As Long, ByVal computer As Long, ByVal seed As Long) As Long

Syntax-C:

LONG pp_ctcodes(LONG code, LONG cenum, LONG computer, LONG seed)

Arguments:

<code>      is the Trigger Code desired, valid 1 to 50

<cenum>     is the code entry number given by pp_cenum()

<computer>  is the computer ID number given by pp_compno()

<seed>      is a number used to randomize the algorithm

Returns:

The valid Trigger Code for the specified parameters passed.

Description:

This function returns the sequence number of the corresponding Trigger Code based upon the number passed. The number passed must be between 1 and 50. If it is not within this range, a zero is returned. This function is used in a client tracking type of application where a list of Trigger Codes is needed based upon the code entry number and computer number of the client to be unlocked.

This function is located in TrigLib, not KeyLib.  Before attempting to access this function, be sure you purchased it.

Example:

' generate Trigger Code number 5

' given the user's code entry number of 12345,

' computer ID number of 45678, and seed of

' 44558877

Dim result As Long

result = pp_ctcodes(5, 12345, 45678, 44558877)

MsgBox 'The authorization code is' & Str(result)

See Also:

PP_TCODE(), PP_CENUM(), and PP_COMPNO()