The Protection Interface is a critical component of the SOFPRO software protection suite, acting as the communication layer between a protected application and the embedded protection code. It enables the application to query its own license status, retrieve detailed licensing data, and interact dynamically with the protection layer. This allows developers to implement highly customized licensing models and application behaviors based on the license state.
The interface is available in three distinct implementations:
- Standard Protection Interface: Provides read-only access to a wide range of license data, such as activation status, demo mode details, user information, and custom features. This data can be accessed easily by calling the
GetInterfaceData()function or, more simply, by reading system environment variables. - Advanced Protection Interface: Facilitates dynamic, two-way communication between the application and the protection code. It offers a library of functions that allow the application to perform actions like activating the product, removing or transferring a license, updating custom counters, and checking for specific hardware, enabling complex, custom protection scenarios. This interface is designed for native Windows 32/64 bit applications.
- Alternate Protection Interface: An alternative implementation of the advanced interface, specifically designed for Microsoft .NET Framework, .NET Core, and .NET (Windows) managed applications. It is also available for native Windows applications that cannot use the default advanced implementation. This method relies on an interface DLL to bridge communication between the application and the embedded protection code.
Core Concepts of the Protection Interface
The Protection Interface establishes a formal link between the developer's application code and SOFPRO's protection code, which is embedded into the application during the protection process.
When a protected application starts, the protection code gains control first. It performs a series of critical checks, including:
- Verifying the license status
- Enforcing demo limitations
- Checking application integrity
After these checks, the protection code initializes necessary data, decrypts the application, and passes control to the application's entry point. By default, the protection code does not affect application execution beyond this initial startup phase unless features like run-time encryption (RTE) are used. The Protection Interface provides the mechanism for the application to continue to query and interact with this protection code throughout its execution.
Levels of Protection Interface Implementation
1. Standard Protection Interface
The Standard interface is designed for obtaining important license data. It offers two primary methods for accessing this information.
- Function Call: By calling the
GetInterfaceData()advanced protection interface function. This method is supported by most programming languages, including C/C++, VB, and Delphi for both 32-bit and 64-bit Windows applications. .NET applications can call this function via the alternate protection interface. - Environment Variables: By enabling the "Set environment variables" option in the interface settings. This allows the application to query standard environment variables, which is a straightforward method compatible with nearly any application type.
The following table details the comprehensive list of data points available through the Standard Protection Interface.
| Name | Type | Description |
| PCGI_ApplicationName | string | Application name as set in application info settings. |
| PCGI_ProtectionMethod | ulong int | Protection method (0 - REMOTE, 1 - NETWORK, 2 - PLAIN, 3 - USB) |
| PCGI_ApplicationStatus | long int | Application status value (0 - locked, 1 - activated) |
| PCGI_ProtectionTime | FILETIME | Time of protection in FILETIME format (UTC) |
| Remote protection information | ||
| PCGI_SiteCode | ulong int | Current Site code value (xxxxxxxx) |
| PCGI_MachineID | word[4] | Current Machine ID value (xxxx-xxxx-xxxx-xxxx) |
| PCGI_NextSiteCode | ulong int | Next Site code value (xxxxxxxx) |
| PCGI_NextMachineID | word[4] | Next Machine ID value (xxxx-xxxx-xxxx-xxxx) |
| PCGI_ActivationCode | string | Activation code |
| Updates policy information | ||
| PCGI_UpdateID | ulong int | Latest valid Update ID value |
| PCGI_FailedUpdateID | ulong int | Latest failed Update ID value when PCGI_UpdatesPolicyError = 1 |
| PCGI_UpdatesPolicyError | ulong int | 0 - update allowed, 1 - update not allowed (based on updates policy) |
| PCGI_UpdatesPolicyDays | ulong int | Updates validity period (in days from activation) (0 - no policy) |
| PCGI_UpdatesPolicyStart | string | Updates policy: fixed period: start date in DDMMYYYY format |
| PCGI_UpdatesPolicyEnd | string | Updates policy: fixed period: end date in DDMMYYYY format |
| PCGI_UpdatesPolicyRangeStart | ulong int | Updates policy allowed update id range start (0 - no limit) |
| PCGI_UpdatesPolicyRangeEnd | ulong int | Updates policy allowed update id range end (0 - no limit) |
| PCGI_UpdatesPolicyRangeFromStart | ulong int | Updates policy: allowed "upgrade from" update id range start (0 - no limit) |
| PCGI_UpdatesPolicyRangeFromEnd | ulong int | Updates policy: allowed "upgrade from" update id range end (0 - no limit) |
| Serial numbers | ||
| PCGI_SerialNumbersEnabled | ulong int | Serial numbers feature status (0 - off, 1 - on) |
| PCGI_SerialNumberSet | ulong int | Valid serial number set? (0 - no, 1 - yes) |
| PCGI_SerialNumber | string | Serial number string (XXXX-XXXX-XX-XXXX-XXXX) |
| PCGI_SerialNumberFeatures | byte array | Serial number features 1-16 (0 - feature disabled, 1 - feature enabled) |
| Custom data information | ||
| PCGI_Features | byte array | Custom features 1-16 (0 - feature disabled, 1 - feature enabled) |
| PCGI_Counters | long array | Custom counters 1-10 |
| User information | ||
| PCGI_UserName | string | User name |
| PCGI_UserAddress | string | User address |
| PCGI_UserCompany | string | User company |
| PCGI_UserCustomInfo1 | string | User custom info 1 |
| PCGI_UserCustomInfo2 | string | User custom info 2 |
| PCGI_UserCustomInfo3 | string | User custom info 3 |
| Demo mode information | ||
| PCGI_DemoModeActive | ulong int | Demo mode status. (0 - demo mode off, 1 - demo mode on) |
| PCGI_DemoDaysLeft | ulong int | Demo mode: number of days left. (-1 means date limitation is not enabled) |
| PCGI_DemoUsesLeft | ulong int | Demo mode: number of uses left. (-1 means exec limitation is not enabled) |
| PCGI_DemoFixedStartDate | string | Demo mode: Fixed date limitation: start date in DDMMYYYY format |
| PCGI_DemoFixedExpDate | string | Demo mode: Fixed date limitation: end date in DDMMYYYY format |
| PCGI_DemoTimer | ulong int | Demo mode: Cumulative timer: number of minutes of usage since first run |
| PCGI_DemoTimerLimit | ulong int | Demo mode: Cumulative timer: total allowed time of usage |
| License information | ||
| PCGI_LicenseTransfers | ulong int | Number of license transfers made since first activation (REMOTE) |
| PCGI_LimitedLicenseActive | ulong int | Limited license status. (0 - off, 1 - on) |
| PCGI_LimitedLicenseDaysLeft | ulong int | Limited license: number of days left. (-1 means date limitation is disabled) |
| PCGI_LimitedLicenseUsesLeft | ulong int | Limited license: number of uses left. (-1 means exec limitation is disabled) |
| PCGI_LimLicFixedStartDate | string | Limited license: Fixed date limitation: start date in DDMMYYYY format |
| PCGI_LimLicFixedExpDate | string | Limited license: Fixed date limitation: expiration date in DDMMYYYY format |
| PCGI_LimLicDayOfMonth | ulong int | Limited license, day of the month value (1 - 31, 0 means limitation is off) |
| PCGI_ActivationTime | FILETIME | Time of license activation on remote computer in FILETIME format (UTC). |
| PCGI_LicenseExtensionTime | FILETIME | Time of last recorded license extension on remote computer in FILETIME format (UTC). |
| ACEN Licensing | ||
| PCGI_ACEN_WebLicensing | byte | ACEN licensing enabled flag (0 - OFF, 1 - ON). |
| PCGI_ACEN_Status | ulong int | Last status code received from ACEN server. |
| PCGI_ACEN_WebLicenseID | ulong int | ACEN Web License ID value. (WEB licensing model) |
| PCGI_ACEN_LicenseID | ulong int | ACEN License ID value (Standard licensing model) |
| PCGI_ACEN_OrderID | ulong int | ACEN Order ID value. |
| PCGI_ACEN_ProductID | ulong int | ACEN Product ID value as set in project settings. |
| PCGI_ACEN_ClientID | string | ACEN Client ID value |
| Network protection information | ||
| PCGI_MaxNetworkSeats | ulong int | Max number of workstations allowed to access protected application (0 - not set) |
| PCGI_NetCfgFileLoaded | ulong int | Network configuration file loaded (0 - no, 1 - yes) |
| PCGI_NetCfgStartDate | string | Network configuration file start date in DDMMYYYY format |
| PCGI_NetCfgExpDate | string | Network configuration file expiration date in DDMMYYYY format |
| Misc information | ||
| PCGI_MaxAppInstances | ulong int | Max number of application instances (0 - not set) |
| PCGI_VirtualMachineFlag | ulong int | Virtual machine flag (0 - VM not detected, 1 - VM detected) |
Important Notes on Standard Interface Variables:
- Custom features and counters have specific environment variable names:
PCGI_Feature01toPCGI_Feature16andPCGI_Counter01toPCGI_Counter10. - The following values are not available as environment variables:
PCGI_SerialNumberFeatures,PCGI_ProtectionTime,PCGI_ActivationTime, andPCGI_LicenseExtensionTime. - For the REMOTE protection method,
PCGI_ApplicationStatusis 0 before activation and 1 after. For other methods, it is always 1. PCGI_DemoModeActiveis 1 during the evaluation period. After activation (for REMOTE protection) or expiration (for other methods), it is set to 0.
2. Advanced Protection Interface
This interface enables dynamic, two-way communication, allowing an application to actively manage its license state and implement custom protection scenarios. It is intended for direct use by native Windows 32/64 bit applications. Licensed versions of PC Guard include sample source code projects demonstrating its use for:
- Visual Studio 2022 C/C++
- Delphi (32/64 bit)
- C++ Builder (32/64 bit)
- Visual Basic (VB6)
3. Alternate Protection Interface
This is an alternative implementation for accessing the advanced protection interface functions. It is specifically intended for environments that cannot use the default advanced interface, including:
- Microsoft .NET Framework
- Microsoft .NET Core
- Microsoft .NET (Windows) managed applications
- Any native Windows application unable to use the default implementation
Implementation Steps and Requirements
- Mandatory Options: The "Enable protection interface" and "Enable alternate protection interface" options must be enabled.
- Custom UI Handling: To use custom dialogs (e.g., for activation), developers must enable demo mode with a date or execution limit and also enable the "Protected application will handle expired demo option."
- Custom License Management: To manage license removal, updates, or transfers, the "Protected application will handle license management" option must be set. To manage an expired limited license, the "Protected application will handle expired license" option should be set.
- Interface DLL: This implementation requires the presence of an interface DLL, which acts as a link between the application and the embedded protection code. A 32-bit DLL must be used for 32-bit applications, and a 64-bit DLL for 64-bit applications. The default name of this DLL can be changed in project settings.
Available Sample Code
Full-featured versions include sample Visual Studio 2022 projects:
- altpcgi_cpp_sample: C/C++ console application.
- altpcgi_csharp_sample: C# .NET Framework console application.
- altpcgi_wpf_csharp_sample: C# WPF .NET Framework application with a customized activation dialog.
- altpcgi_netcore_csharp_sample: C# .NET Core and .NET 5+ console application.
- altpcgi_vbnet_sample: VB.NET .NET Framework console application.
Advanced Protection Interface Functions
The following functions are available through the Advanced and Alternate Protection Interfaces, enabling deep integration with the protection system.
- GetInterfaceData(): Retrieves a data structure containing all relevant information about the current license.
- UnlockApplication(): Processes an activation code to activate the application or extend its evaluation period.
- LoadActivationFile(): Loads and processes an activation file to activate or extend the application.
- RemoveLicense(): Removes the current license and returns a valid Removal Code.
- TransferLicense(): Transfers an active license to another computer by generating a new activation code based on a new Site Code and removing the current license.
- ExtendLicense(): Updates an existing license before it expires, allowing changes to features, counters, and limitations.
- SetLicenseValidityPeriod(): Sets a new validity period for the license.
- CheckLimitedLicense(): Checks the expiration status of a limited license.
- CheckDemoLimitations(): Checks demo limitations related to date and fixed date.
- UpdateCustomCounters(): Saves updated values for custom counters.
- UpdateUserInfo(): Updates the current user's information.
- FreeAppInstance(): Frees an application instance from the list of currently active instances (relevant for network protection).
- CountActiveInstances(): Returns the number of currently active application instances.
- CountActiveNetworkSeats(): Returns the number of currently active network seats.
- SetSerialNumber(): Validates and sets a serial number for the application.
- InvalidateSerialNumber(): Invalidates an existing serial number and resets the license.
- CheckForUsbDrive(): Checks if a required USB device is attached to the computer.
- ValidateWebLicense(): Executes an ACEN web licensing validation task.
- IsVirtualMachine(): Checks if the application is running on a virtual machine (VM).