Purpose
This class is something I wrote to kill time. But by the time I finished it,
I thought it might be pretty useful for shareware developers. It can be used to
implement limited-number-of-runs and limited-time-period-only programs. Means if
you want to allow only 25 runs, then this class will do that for you. Or if you
want to restrict execution to 15 days from first run, this program will do that
too. By the way, even if the user changes his system date back to the
allowed-time-period after it has expired, he/she won't be able to run
it.
Disclaimer
This is by no means a fool-proof protection scheme, but it serves its purpose
at the intermediate level. And usually crackers manage to actually patch the
executable to disable these checks or they manage to write key generators for
your protected programs. But this class will save some time for you in the
sense, it actually does what you would otherwise have to code on your own.
Protection Mechanism
It uses a combination of registry and file based protection mechanisms. You
should be smart enough to pick the right innocent sounding registry keys and
filenames to prevent the casual user from simply deleting a few odd keys and
break the protection.
How to use the class.
You must instantiate an object of the class as early as possible. You may
declare it as a global object if you would like to. In an SDK program, you might
want to instantiate the class on the first line in your WinMain()
and in an MFC program you might want to put it in your CWinApp
derived class's InitInstance()
.
There are two ways in which you can use the class. In the first way you
specify a specific number of times that the program can be run. In the second
you set a number of days so that the program is active for that many days from
the time of first execution. I shall demonstrate both methods below.
The constructor takes 4 parameters.
CExpire(const char* ProgName,const char* KeyName, UINT Num, UINT ExpireType);
ProgName
- This is a unique value that will be used to create
the unique registry key for protection. It is a good idea to choose a
GUID for this key. It will be placed in a location confusing enough for
most of the average users of your program.
KeyName
- This is again used as part of the unique registry key
as well as in the generation of the special file. You can use a unique, but
natural sounding name like MouseDrv98 or something that would not actually stand
out.
Num
- This is either the number of days from the date of
execution or the total number of runs allowed. This value's interpretation
depends upon the ExpireType
parameter.
ExpireType
- This can be one of two values as shown below
TYPERUNS - This implies run-count based
protection
TYPEDAYS - This implies date-interval based
protection
There are only three public functions that you'll need to call.
bool HasExpired();
It returns true
if your program has expired and
false
if the user is still within his allowed limits.
UINT GetDaysLeft();
This returns the number of days left before the program expires. Use this if
you have chosen ExpireType
as TYPEDAYS
UINT GetRunsLeft();
This returns the number of runs left before the program expires. Use this if
you have chosen ExpireType
as TYPERUNS
Example Usage
SDK example
int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE,LPSTR,int)
{
CExpire Protector("{00000000-0000-0000-8888-00AA006D2EA4}",
"InprocServer32",6,TYPEDAYS);
if(Protector.HasExpired())
{
MessageBox(0,
"This program has expired. Please buy the registered version.",
"Fatal Error",0);
}
else
{
char s[128];
sprintf(s,"you have %d days left",Protector.GetDaysLeft());
MessageBox(0,s,"",0);
StartExecution();
}
return 0;
}
MFC example
BOOL CTest_deleteApp::InitInstance()
{
CExpire expire("JPEG-File-Viewer","FileStore",30,TYPERUNS);
if(expire.HasExpired())
{
AfxMessageBox("This program will not run anymore...");
return FALSE;
}
char s[128];
sprintf(s,"you have %d runs left",expire.GetRunsLeft());
AfxMessageBox(s);
AfxEnableControlContainer();
#ifdef _AFXDLL
Enable3dControls();
#else
Enable3dControlsStatic();
#endif
CTest_deleteDlg dlg;
m_pMainWnd = &dlg;
int nResponse = dlg.DoModal();
return FALSE;
}
Important Warning
DON'T choose a value for the KeyName
parameter that might
already define a file in the Windows System directory. It will be over-written.
The best thing to do is to choose a filename and then add some numbers to the
end like 32_32 or something natural sounding.
Thank you.