Foundation 6

9. Licensing your application

Fnd_Reg lets your application run as a time-limited demo and unlock with a code you issue. It licenses your application; Foundation itself has no licence enforcement and never did since version 6. Fnd_RegG is the other half, the code generator, which you run in your own customer database.

Keep the limits in mind before you build on it: the codes are MD5-based and the generator ships in Foundation's source, so the scheme deters casual copying and nothing more. Its strength is your secret key, which never leaves your code.

The table

Fnd_Reg keeps its state in a [Fnd_Reg] table in your structure:

FieldType
IDLongint, indexed
Feature_CodeAlpha 80, indexed
Demo_DaysInteger
Demo_Start_DateDate
Unlock_CodeAlpha 40
User_NameAlpha 80
License_InfoAlpha 80
ChecksumAlpha 40

The first Fnd_Reg call of a session checks for it. In an interpreted host Foundation offers to create it and asks you to restart; compiled, it reports and Fnd_Reg stays inactive, with no alert and no abort. Because the demo start date and the unlock code are records, a new data file starts a new demo.

Quick start

In Fnd_Hook_Shell_Startup, or anywhere that runs once after Fnd_Shell_OnStartup:

Fnd_Reg_SetSecretKey("a phrase nobody will guess")
Fnd_Reg_DemoDays(""; 30)
Fnd_Reg_BuyNowURL(""; "https://www.example.com/buy")
Fnd_Reg_DemoDialog

Then ask the state wherever a feature is gated:

Case of
	: (Fnd_Reg_RegistrationState=Fnd_Reg_Registered)
		// full function
	: (Fnd_Reg_RegistrationState=Fnd_Reg_Demo)
		// trial, days remaining in Fnd_Reg_GetDemoDaysRemaining
	: (Fnd_Reg_RegistrationState=Fnd_Reg_Expired)
		Fnd_Reg_DemoDialog
	: (Fnd_Reg_RegistrationState=Fnd_Reg_PreDemo)
		// never started
End case

Issuing a code

In your customer database, with the same secret key:

$code_t:=Fnd_RegG_GenerateUnlockCode("a phrase nobody will guess"; ""; [Customer]Company)

The customer enters that code and the same name in the Registration dialog (Fnd_Reg_RegistrationDialog), or your code calls Fnd_Reg_Register(featureCode; unlockCode; userName), which sets OK to 1 on success. The optional fourth argument of the generator, licence information (a seat count, an edition), is bound into the code and readable afterwards with Fnd_Reg_GetLicenseInfo.

Feature codes

Every Fnd_Reg call takes an optional feature code, so one application can license several features separately, each with its own demo period, message and Buy Now URL: Fnd_Reg_FeatureName("REPORTS"; "Reporting module"), Fnd_Reg_DemoMessage("REPORTS"; "…"). The empty code is the application.

Dialogs

The demo and registration dialogs are Foundation's, localised through Fnd_Loc, and show your DatabaseName. Fnd_Reg_Reset(featureCode) clears a feature's registration and demo start for testing.

Testing

The module was exercised before release with a 127-assertion test of every call that opens no dialog. The one fact from it a host needs: the [Fnd_Reg] table must exist when 4D starts, so a table created by Fnd_Reg_CreateTable needs a restart before the first real run.