MFC ActiveX Controls: Licensing an ActiveX Control
Licensing support, an optional feature of ActiveX controls, allows you to control who is able to use or distribute the control. (For additional discussion of licensing issues, see Licensing Issues in Upgrading an Existing ActiveX Control.)
This article discusses the following topics:
Overview of ActiveX Control Licensing
Creating a Licensed Control
Licensing Support
Customizing the Licensing of an ActiveX Control
ActiveX controls that implement licensing allow you, as the control developer, to determine how other people will use the ActiveX control. You provide the control purchaser with the control and .LIC file, with the agreement that the purchaser may distribute the control, but not the .LIC file, with an application that uses the control. This prevents users of that application from writing new applications that use the control, without first licensing the control from you.
Overview of ActiveX Control Licensing
To provide licensing support for ActiveX controls, the COleObjectFactory class provides an implementation for several functions in the IClassFactory2 interface: IClassFactory2::RequestLicKey, IClassFactory2::GetLicInfo, and IClassFactory2::CreateInstanceLic. When the container application developer makes a request to create an instance of the control, a call to GetLicInfo is made to verify that the control .LIC file is present. If the control is licensed, an instance of the control can be created and placed in the container. After the developer has finished constructing the container application, another function call, this time to RequestLicKey, is made. This function returns a license key (a simple character string) to the container application. The returned key is then embedded in the application.
The figure below demonstrates the license verification of an ActiveX control that will be used during the development of a container application. As mentioned previously, the container application developer must have the proper .LIC file installed on the development machine to create an instance of the control.
Verification of a Licensed ActiveX Control During Development
The next process, shown in the following figure, occurs when the end user runs the container application.
When the application is started, an instance of the control usually needs to be created. The container accomplishes this by making a call to CreateInstanceLic, passing the embedded license key as a parameter. A string comparison is then made between the embedded license key and the control's own copy of the license key. If the match is successful, an instance of the control is created and the application continues to execute normally. Note that the .LIC file need not be present on the control user's machine.
Verification of a Licensed ActiveX Control During Execution
Control licensing consists of two basic components: specific code in the control implementation DLL and the license file. The code is composed of two (or possibly three) function calls and a character string, hereafter referred to as a "license string", containing a copyright notice. These calls and the license string are found in the control implementation (.CPP) file. The license file, generated by the ActiveX Control Wizard, is a text file with a copyright statement. It is named using the project name with an .LIC extension, for example SAMPLE.LIC. A licensed control must be accompanied by the license file if design-time use is needed.
Creating a Licensed Control
When you use the ActiveX Control Wizard to create the control framework, it is easy to include licensing support. When you specify that the control should have a run-time license, the ActiveX Control Wizard adds code to the control class to support licensing. The code consists of functions that use a key and license file for license verification. These functions also can be modified to customize the control licensing. For more information on license customization, see Customizing the Licensing of an ActiveX Control later in this article.
To add support for licensing with the ActiveX Control Wizard when you create your control project
- Use the instructions in Creating an MFC ActiveX Control. The Application Settings page of the ActiveX Control Wizard contains the option to create the control with the run-time license.
The ActiveX Control Wizard now generates an ActiveX control framework that includes basic licensing support. For a detailed explanation of the licensing code, see the next topic.
Licensing Support
When you use the ActiveX Control Wizard to add licensing support to an ActiveX control, the ActiveX Control Wizard adds code that declares and implements the licensing capability is added to the control header and implementation files. This code is composed of a VerifyUserLicense member function and a GetLicenseKey member function, which override the default implementations found in COleObjectFactory . These functions retrieve and verify the control license.
Notes
A third member function, VerifyLicenseKey is not generated by the ActiveX Control Wizard, but can be overridden to customize the license key verification behavior.
These member functions are:
-
Verifies that the control allows design-time usage by checking the system for the presence of the control license file. This function is called by the framework as part of processing IClassFactory2::GetLicInfo and IClassFactory::CreateInstanceLic.
-
Requests a unique key from the control DLL. This key is embedded in the container application and used later, in conjunction with VerifyLicenseKey, to create an instance of the control. This function is called by the framework as part of processing IClassFactory2::RequestLicKey.
-
Verifies that the embedded key and the control's unique key are the same. This allows the container to create an instance of the control for its use. This function is called by the framework as part of processing IClassFactory2::CreateInstanceLic and can be overridden to provide customized verification of the license key. The default implementation performs a string comparison. For more information, see Customizing the Licensing of an ActiveX Control, later in this article.
Header File Modifications
The ActiveX Control Wizard places the following code in the control header file. In this example, two member functions of CSampleCtrl's object factory are declared, one that verifies the presence of the control .LIC file and another that retrieves the license key to be used in the application containing the control:
BEGIN_OLEFACTORY(CMyAxUICtrl) // Class factory and guid
virtual BOOL VerifyUserLicense();
virtual BOOL GetLicenseKey(DWORD, BSTR FAR*);
END_OLEFACTORY(CMyAxUICtrl)
Implementation File Modifications
The ActiveX Control Wizard places the following two statements in the control implementation file to declare the license filename and license string:
static const TCHAR BASED_CODE _szLicFileName[] = _T("NVC_MFC_AxUI.lic");
static const WCHAR BASED_CODE _szLicString[] = L"Copyright (c) 2006 ";
Notes
If you modify szLicString in any way, you must also modify the first line in the control .LIC file or licensing will not function properly.
The ActiveX Control Wizard places the following code in the control implementation file to define the control class' VerifyUserLicense and GetLicenseKey functions:
// CMyAxUICtrl::CMyAxUICtrlFactory::VerifyUserLicense -
// Checks for existence of a user license
BOOL CMyAxUICtrl::CMyAxUICtrlFactory::VerifyUserLicense()
{
return AfxVerifyLicFile(AfxGetInstanceHandle(), _szLicFileName, _szLicString);
}
// CMyAxUICtrl::CMyAxUICtrlFactory::GetLicenseKey -
// Returns a runtime licensing key
BOOL CMyAxUICtrl::CMyAxUICtrlFactory::GetLicenseKey(DWORD /*dwReserved*/,
BSTR FAR* pbstrKey)
{
if (pbstrKey == NULL)
return FALSE;
*pbstrKey = SysAllocString(_szLicString);
return (*pbstrKey != NULL);
}
Finally, the ActiveX Control Wizard modifies the control project .IDL file. The licensed keyword is added to the coclass declaration of the control, as in the following example:
[ uuid(913E450B-E720-4C71-BCDF-71C96EE98FEB), licensed,
helpstring("MyAxUI Control"), control ]
coclass NVC_MFC_AxUI
Customizing the Licensing of an ActiveX Control
Because VerifyUserLicense, GetLicenseKey, and VerifyLicenseKey are declared as virtual member functions of the control factory class, you can customize the control's licensing behavior.
For example, you can provide several levels of licensing for the control by overriding the VerifyUserLicense or VerifyLicenseKey member functions. Inside this function you could adjust which properties or methods are exposed to the user according to the license level you detected.
You can also add code to the VerifyLicenseKey function that provides a customized method for informing the user that control creation has failed. For instance, in your VerifyLicenseKey member function you could display a message box stating that the control failed to initialize and why.
Notes
Another way to customize ActiveX control license verification is to check the registration database for a specific registry key, instead of calling AfxVerifyLicFile. For an example of the default implementation, see the Implementation File Modifications section of this article.
For additional discussion of licensing issues, see Licensing Issues in Upgrading an Existing ActiveX Control.