Click here to Skip to main content
15,897,891 members
Articles / Desktop Programming / MFC

How to Register a Program

Rate me:
Please Sign up or sign in to vote.
3.95/5 (9 votes)
28 Jan 2009CPOL8 min read 61.9K   2K   61  
How to register a program on end-user machine only and without end-user interference.
// ------------------------------------------------------------------------------------------------------------------------------------------------------
// - This file are split up in two parts:																												-
// -																																					-
// - 1. CLASSES/FUNCTIONS ETC. NEEDED FOR THE TEST PROJ'S ONLY.																							-
// - 2. CLASSES/FUNCTIONS ETC. NEEDED FOR THE LOCAL-MACHINE-REG. TO WORK AS DESCRIBED IN THE CP ARTICLE.												-
// -																																					-
// - Michael Mogensen, Copenhagen DK january 2009, michael-mogensen-danmark@hotmail.com.																-
// ------------------------------------------------------------------------------------------------------------------------------------------------------

// ------------------------------------------------------------------------------------------------------------------------------------------------------
// -																																					-
// -																																					-
// - 1. CLASSES/FUNCTIONS ETC. NEEDED FOR THE TEST PROJ'S ONLY.																							-
// -																																					-
// -																																					-
// ------------------------------------------------------------------------------------------------------------------------------------------------------

// ------------------------------------------------------------------------------------------------------------------------------------------------------
// - Miscellaneous.																																		-
// ------------------------------------------------------------------------------------------------------------------------------------------------------
#pragma once

// ------------------------------------------------------------------------------------------------------------------------------------------------------
// - Header(s).																																			-
// ------------------------------------------------------------------------------------------------------------------------------------------------------
#define _USE_MATH_DEFINES
#include <math.h>
#include <winsock2.h>

// ------------------------------------------------------------------------------------------------------------------------------------------------------
// - Miscellaneous.																																		-
// ------------------------------------------------------------------------------------------------------------------------------------------------------
#ifndef _MFCUTIL_H
	#define _MFCUTIL_H
#endif

// ------------------------------------------------------------------------------------------------------------------------------------------------------
// - Pre.decls.	of global fct's.																														-
// ------------------------------------------------------------------------------------------------------------------------------------------------------
inline const CString GetRandomSymbol();
inline const CString GetRandomSequence(const int);
inline const CString GetRandomSerialTuple(const int, const int, const CString&);
inline unsigned int Random(const unsigned int, const unsigned int);
inline const bool GetInternetTime(COleDateTime&, const CString&);
inline const COleDateTimeSpan GetTimeDiff(const COleDateTime&, const COleDateTime&);
inline const LONG GetTimeDiffInDays(const COleDateTime&, const COleDateTime&);

// ------------------------------------------------------------------------------------------------------------------------------------------------------
// - Macros.																																			-
// ------------------------------------------------------------------------------------------------------------------------------------------------------
#define COUNTOF(a) \
	(sizeof(a) / sizeof(a[0]))

#define DELETE_AND_DESTROY(p) \
	if(p) \
	{ \
		delete p; \
		p = NULL; \
	}

#define NEWLINE										_T("\n")
#define EDIT_NEWLINE								_T("\r\n")

#define KEY_FULL_ACCESS \
	(STANDARD_RIGHTS_REQUIRED | \
	 KEY_READ | \
	 KEY_WRITE | \
	 KEY_CREATE_LINK)

#define MAX_KEY_LENGTH								512 // 255 is max. length for a normal (non-hidden) key and >255 is needed for a hidden key.
#define MAX_VALUE_LENGTH							16383
#define MAX_NAME_LENGTH								16383

#define WNDTRACEEXCEPTION(s_cla, s_met_or_fct, s_info) \
	{ \
		TRACE("Exception in method or function!"); \
		TRACE(NEWLINE); \
		TRACE1("Class: %s", s_cla); \
		TRACE(NEWLINE); \
		TRACE1("Method or function: %s(...)", s_met_or_fct); \
		TRACE(NEWLINE); \
		TRACE1("Info: %s", s_info); \
		TRACE(NEWLINE); \
	}

#ifdef _DEBUG
// Show trace in DEBUG. 
#define WNDTRACEEXCEPTION_USERDLG(s_cla, s_met_or_fct, s_info, e) \
	{ \
		WNDTRACEEXCEPTION(s_cla, s_met_or_fct, s_info) \
	}
#else
// Show dlg. in RELEASE. 
#define WNDTRACEEXCEPTION_USERDLG(s_cla, s_met_or_fct, s_info, e) \
	{ \
		if(e) \
			e->ReportError(); \
	}
#endif

#define IMPL_ADD_TEXT_METHOD() \
		inline void AddText(CString cstrMoreText) \
		{ \
			CString cstrText(_T("")); \
			GetWindowText(cstrText); \
			cstrMoreText = cstrMoreText.Trim(NEWLINE); \
			cstrText += cstrMoreText; \
			cstrText += EDIT_NEWLINE; \
			SetWindowText(cstrText); \
			Scroll2LastLine(); \
			GetParent()->SendMessage(WM_COMMAND, MAKEWPARAM(GetDlgCtrlID(), EN_CHANGE), (LPARAM)GetSafeHwnd()); \
		} \

#define IMPL_GET_TEXT_METHOD() \
		inline CString GetText() \
		{ \
			CString cstrText(_T("")); \
			GetWindowText(cstrText); \
			return cstrText; \
		} \

#define IMPL_SET_TEXT_METHOD() \
		inline void SetText(const CString &cstrText) \
		{ \
			SetWindowText(cstrText); \
			GetParent()->SendMessage(WM_COMMAND, MAKEWPARAM(GetDlgCtrlID(), EN_CHANGE), (LPARAM)GetSafeHwnd()); \
		} \

#define IMPL_GET_INT_METHOD() \
		inline int GetInt() \
		{ \
			CString cstrText(_T("")); \
			GetWindowText(cstrText); \
			int iNo = ::_wtoi((LPCTSTR)cstrText); \
			return iNo; \
		} \

#define IMPL_SET_INT_METHOD() \
		inline void SetInt(const int iNo) \
		{ \
			CString cstrText(_T("")); \
			cstrText.Format(TEXT("%d"), iNo); \
			SetWindowText(cstrText); \
			GetParent()->SendMessage(WM_COMMAND, MAKEWPARAM(GetDlgCtrlID(), EN_CHANGE), (LPARAM)GetSafeHwnd()); \
		} \

#define IMPL_IS_CHECKED_METHOD() \
		inline bool IsChecked() \
		{ return(GetCheck() == BST_CHECKED); } \

#define IMPL_CHECK_METHOD() \
		inline void Check() \
		{ SetCheck(BST_CHECKED); } \

// ------------------------------------------------------------------------------------------------------------------------------------------------------
// - CEditEx.																																			-
// ------------------------------------------------------------------------------------------------------------------------------------------------------
class CEditEx : public CEdit
{
	public:
		// 1. Constructors. (alphabetical).
		CEditEx();
		// 3. Methods inlined. (alphabetical).
		IMPL_ADD_TEXT_METHOD();
		IMPL_GET_TEXT_METHOD();
		IMPL_SET_TEXT_METHOD();
		IMPL_GET_INT_METHOD();
		IMPL_SET_INT_METHOD();
		inline const void Scroll2LastLine()
		{
			const int iLastVisibleIndex = GetLineCount();
			if(iLastVisibleIndex > 0)
				LineScroll(iLastVisibleIndex, 0);
		}
};

// ------------------------------------------------------------------------------------------------------------------------------------------------------
// - CRadioButtonEx.																																	-
// ------------------------------------------------------------------------------------------------------------------------------------------------------
class CRadioButtonEx : public CButton
{
	public:
		// 3. Methods inlined. (alphabetical).
		IMPL_CHECK_METHOD();
		IMPL_IS_CHECKED_METHOD();
};

// ------------------------------------------------------------------------------------------------------------------------------------------------------
// - CCheckBoxEx.																																		-
// ------------------------------------------------------------------------------------------------------------------------------------------------------
class CCheckBoxEx : public CButton
{
	public:
		// 3. Methods inlined. (alphabetical).
		IMPL_IS_CHECKED_METHOD();
};

// ------------------------------------------------------------------------------------------------------------------------------------------------------
// - Impl. of global fct's.	(part 1/2)																													-
// ------------------------------------------------------------------------------------------------------------------------------------------------------
inline const CString GetRandomSymbol()
// Return random char. in list of chars.
{
	static const CString cstrSymbols(_T("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"));
	static const int iRandLow = 0;
	static const int iRandHigh = cstrSymbols.GetAllocLength() - 1;
	CString cstrSymbol(cstrSymbols.GetAt(::Random(iRandLow, iRandHigh)));
	return cstrSymbol;
}

inline const CString GetRandomSequence(const int iTubleSize)
// Return random char. sequence.
{
	CString cstrTuble(_T(""));
	for(int iId = 0; iId < iTubleSize; iId++)
		cstrTuble += GetRandomSymbol();
	return cstrTuble;
}

inline const CString GetRandomSerialTuple(const int iSNSize, const int iTubleSize, const CString &cstrSep = _T("-"))
// Return random SN formattet like "NUD6U-GQM38-6LEJ6-0J6TE-V0UNK-J49FK".
{
	CString cstrSN(_T(""));
	for(int iId = 0; iId < iSNSize; iId++)
		cstrSN += ((iId > 0 ? cstrSep : _T("")) + GetRandomSequence(iTubleSize));
	return cstrSN;
}

inline unsigned int Random(const unsigned int uix1, const unsigned int uix2)
// Return pseudo random number between x1 and x2.
//
// Note: The rand_s function requires that constant _CRT_RAND_S be defined prior to the inclusion statement 
// in order for the function to be declared, such as in the example below:
//
// #define _CRT_RAND_S
// #include <stdlib.h> (Z:\Program Files\Microsoft Visual Studio 9.0\VC\atlmfc\src\mfc\stdafx.h)
//
{
	unsigned int uix = 0;
	errno_t err = rand_s(&uix);
	unsigned int uiRandomNumber = 0;
	if(err == 0)
		// OK.
		uiRandomNumber = (unsigned int)(((double)uix / (double)UINT_MAX * ((unsigned int)abs((long)(uix2 - uix1)) + 1)) + min(uix1, uix2));
	return uiRandomNumber;
}

inline const CString GetDateAsNiceHumanReadableString(const COleDateTime &t, const bool bCompactFormat = false)
{
	CString cstrDate(_T(""));
	if(bCompactFormat)
		// Format like "090521".
		cstrDate.Format(TEXT("%0.2d%0.2d%0.2d"), t.GetYear() % 10, t.GetMonth(), t.GetDay());
	else
		// Format like "09.05.21".
		cstrDate.Format(TEXT("%0.2d.%0.2d.%0.2d"), t.GetYear() % 10, t.GetMonth(), t.GetDay());
	return cstrDate;
}

inline const COleDateTimeSpan GetTimeDiff(const COleDateTime &ta, const COleDateTime &tb)
{
	COleDateTimeSpan tsDelta(tb - ta);
	return tsDelta;
}

inline const LONG GetTimeDiffInDays(const COleDateTime &ta, const COleDateTime &tb)
{ return (LONG)GetTimeDiff(ta, tb).GetTotalDays(); }

// ------------------------------------------------------------------------------------------------------------------------------------------------------
// -																																					-
// -																																					-
// - 2. CLASSES/FUNCTIONS ETC. NEEDED FOR THE LOCAL-MACHINE-REG. TO WORK AS DESCRIBED IN THE CP ARTICLE.												-
// -																																					-
// -																																					-
// ------------------------------------------------------------------------------------------------------------------------------------------------------

// ------------------------------------------------------------------------------------------------------------------------------------------------------
// - SNTPTimePacket.																																	-
// ------------------------------------------------------------------------------------------------------------------------------------------------------
typedef struct tagSNTPTimePacket
{
	// 0. Properties. (alphabetical).
	DWORD m_dwInteger;
	DWORD m_dwFractional;
} SNTPTimePacket;

// ------------------------------------------------------------------------------------------------------------------------------------------------------
// - CNTPTime.																																			-
// ------------------------------------------------------------------------------------------------------------------------------------------------------
class CNTPTime
{
	public:
		// 1. Constructors. (alphabetical).
		CNTPTime();
		CNTPTime(const CNTPTime&);
		CNTPTime(SNTPTimePacket&);
		// 3. Methods. (alphabetical).
		CNTPTime& operator=(const CNTPTime&);
		operator SYSTEMTIME() const;
		operator SNTPTimePacket() const;
		inline operator unsigned __int64() const
		{ return m_Time; };
		inline const DWORD Seconds() const
		{ return((DWORD)((m_Time & 0xFFFFFFFF00000000) >> 32)); }
		inline const DWORD Fraction() const
		{ return((DWORD)(m_Time & 0xFFFFFFFF)); }
	protected:
		// 3. Methods. (alphabetical).
		static void GetGregorianDate(long, WORD&, WORD&, WORD&);
	private:
		// 0. Properties. (alphabetical).
		static const long sm_lJan1St_1900;
		unsigned __int64 m_Time;
};

// ------------------------------------------------------------------------------------------------------------------------------------------------------
// - CRegistryAccess.																																	-
// ------------------------------------------------------------------------------------------------------------------------------------------------------
class CRegistryAccess
{
	private:
		// 0. Properties. (alphabetical).
		bool m_bHiddenName;
		HKEY m_hKey;
		CString m_cstrMainKey, 
				m_cstrSubKey;
	protected:
		// 3. Methods. (alphabetical).
		static const bool 
			CloseKey(HKEY);
		static HKEY 
			CreateKey(const CString&);
		static BOOL WINAPI 
			EnableProcessPrivilege(LPCTSTR, BOOL);
		static const CString 
			FormatKey(const CString&, const CString&);
		const bool 
			GetDataDWORD(const CString&, DWORD&);
		const bool 
			GetDataSZ(const CString&, CString&);
		static const CString 
			GetLongName(const CString&);
		static HKEY 
			OpenKey(const CString&);
		const bool 
			SetDataDWORD(const CString&, CONST DWORD&);
		const bool 
			SetDataSZ(const CString&, const CString&);
	public:
		// 0. Properties. (alphabetical).
		struct SNameTypeData
		{
			CString m_cstrName;
			CString m_cstrType;
			CString m_cstrData;
		};
		// 1. Constructors. (alphabetical).
		CRegistryAccess(const CString&, const CString &cstrSubKey = _T(""), const bool bHiddenKeyEx = false);
		~CRegistryAccess();
		// 3. Methods. (alphabetical).
		const bool 
			DataExist(const CString&);
		const bool 
			DeleteData(const CString&);
		const bool 
			DeleteData();
		const bool 
			DeleteKey();
		const void 
			GetAll(CArray<SNameTypeData, SNameTypeData>&);
		const void 
			GetAllNames(CStringArray&);
		const void 
			GetAllTypes(CStringArray&);
		const void 
			GetAllDatas(CStringArray&);
		const bool 
			GetData(const CString&, DWORD&);
		const bool 
			GetData(const CString&, CString&);
		const bool 
			GetData(const CString&, int&);
		const bool 
			GetData(const CString&, bool&);
		const bool 
			SetData(const CString&, CONST DWORD&);
		const bool 
			SetData(const CString&, const CString&);
		const bool 
			SetData(const CString&, const int&);
		const bool 
			SetData(const CString&, const bool&);
};

// ------------------------------------------------------------------------------------------------------------------------------------------------------
// - SNTPServerResponse.																																-
// ------------------------------------------------------------------------------------------------------------------------------------------------------
typedef struct tagSNTPServerResponse
{
	// 0. Properties. (alphabetical).
	CNTPTime m_ReceiveTime;
} SNTPServerResponse;

// ------------------------------------------------------------------------------------------------------------------------------------------------------
// - CNTPClient.																																		-
// ------------------------------------------------------------------------------------------------------------------------------------------------------
class CNTPClient : public CObject
{
	public:
		// 1. Constructors. (alphabetical).
		CNTPClient();
		// 3. Methods. (alphabetical).
		const bool GetServerTime(const CString&, SNTPServerResponse&, const int iPort = 123);
	protected:
		// 0. Properties. (alphabetical).
		DWORD m_dwTimeout;
};

// ------------------------------------------------------------------------------------------------------------------------------------------------------
// - CNTPSocket.																																		-
// ------------------------------------------------------------------------------------------------------------------------------------------------------
class CNTPSocket
{
	public:
		// 1. Constructors. (alphabetical).
		CNTPSocket();
		~CNTPSocket();
		// 3. Methods. (alphabetical).
		const void Close();
		const bool Connect(const CString&, const int);
		const bool Create();
		const bool IsReadable(const DWORD);
		const int Receive(LPSTR, const int);
		const bool Send(LPCSTR, const int);
	protected:
		// 3. Methods. (alphabetical).
		const bool Connect(const SOCKADDR*, int);
	private:
		// 0. Properties. (alphabetical).
		SOCKET m_hSocket;
};

// ------------------------------------------------------------------------------------------------------------------------------------------------------
// - CProgramRegistration.																																-
// ------------------------------------------------------------------------------------------------------------------------------------------------------
class CProgramRegistration
{
	private:
		// 0. Properties. (alphabetical).
		static const CString sm_cstrSNDummy;
		static const CString sm_cstrFirstRunRegKeyPostfix;
		static const CString sm_cstrSNRegKeyPostfix;
		int m_iDays2UseFreeOfCharge;
		CString m_cstrAppName;
		COleDateTime 
			m_dtNow, 
			m_dtExpire, 
			m_dtFirstRun;
		CRegistryAccess *m_pregAccess;
	protected:
		// 3. Methods. (alphabetical).
		inline const CString GetFirstRunRegName()
		{ return(m_cstrAppName + sm_cstrFirstRunRegKeyPostfix); }
		inline const CString GetSNRegName()
		{ return(m_cstrAppName + sm_cstrSNRegKeyPostfix); }
		const bool 
			SetFirstRunDate(const COleDateTime&);
	public:
		// 1. Constructors. (alphabetical).
		CProgramRegistration(const CString&, const int, const bool bHiddenEx = true);
		~CProgramRegistration();
		// 3. Methods. (alphabetical).
		const int 
			GetDaysLeft();
		static inline const CString&
			GetDummySerialNumber()
		{ return sm_cstrSNDummy; }
		const bool  
			GetFirstRunDate(COleDateTime&);
		const bool 
			GetSerialNumber(CString&);
		const bool 
			IsLegalCopy();
		const bool 
			IsRegistred();
		const bool 
			Register(const CString&);
		const void 
			RemoveRegistration();
		const bool 
			UnRegister();
};

// ------------------------------------------------------------------------------------------------------------------------------------------------------
// - SNTPBasicInfo (the mandatory part of an NTP packet).																								-
// ------------------------------------------------------------------------------------------------------------------------------------------------------
typedef struct tagSNTPBasicInfo
{
	// 0. Properties. (alphabetical).
	BYTE m_LiVnMode;
	BYTE m_Stratum;
	char m_Poll;
	char m_Precision;
	long m_RootDelay;
	long m_RootDispersion;
	char m_ReferenceID[4];
	SNTPTimePacket m_ReferenceTimestamp;
	SNTPTimePacket m_OriginateTimestamp;
	SNTPTimePacket m_ReceiveTimestamp;
	SNTPTimePacket m_TransmitTimestamp;
} SNTPBasicInfo;

// ------------------------------------------------------------------------------------------------------------------------------------------------------
// - SNTPAuthenticationInfo (The optional part of an NTP packet).																						-
// ------------------------------------------------------------------------------------------------------------------------------------------------------
typedef struct tagSNTPAuthenticationInfo
{
	// 0. Properties. (alphabetical).
	unsigned long m_KeyID;
	BYTE m_MessageDigest[16];
} SNTPAuthenticationInfo;

// ------------------------------------------------------------------------------------------------------------------------------------------------------
// - SNTPFullPacket (The full packet).																													-
// ------------------------------------------------------------------------------------------------------------------------------------------------------
typedef struct tagSNTPFullPacket
{
	// 0. Properties. (alphabetical).
	SNTPBasicInfo m_Basic;
	SNTPAuthenticationInfo m_Auth;
} SNTPFullPacket;

// ------------------------------------------------------------------------------------------------------------------------------------------------------
// - Impl. of global fct's.	(part 2/2)																													-
// ------------------------------------------------------------------------------------------------------------------------------------------------------
inline const bool GetInternetTime(COleDateTime &tNTP, const CString &cstrNTPServer = _T(""))
// Retrieves the current UTC time from a NTP server. Return T if retrieved and F if not.
//
// +---------------+---------------------------------------+
// | Area          | HostName                              |
// +---------------+---------------------------------------+
// | Worldwide     | pool.ntp.org                          |
// | Europe        | europe.pool.ntp.org                   |
// | Asia          | asia.pool.ntp.org                     |
// | North America | north-america.pool.ntp.org            |
// | Oceania       | oceania.pool.ntp.org                  |
// | South America | south-america.pool.ntp.org            |
// +---------------+---------------------------------------+
//
{
	WSADATA wsaData;
	BYTE wsMajorVersion = 1;
	BYTE wsMinorVersion = 1;
	WORD wVersionRequested = MAKEWORD(wsMinorVersion, wsMajorVersion);   
	if(::WSAStartup(wVersionRequested, &wsaData) != 0) 
	{
		return false;
	}
	if(LOBYTE(wsaData.wVersion) != wsMajorVersion || HIBYTE(wsaData.wVersion) != wsMinorVersion)
	{
		::WSACleanup();
		return false;
	}
	CNTPClient ntpClient;
	SNTPServerResponse response;
	// Check servers for the UTC time until first one gives us an answer.
	CString cstrNTPServers[] =
	{
		_T("pool.ntp.org"), 
		_T("europe.pool.ntp.org"), 
		_T("asia.pool.ntp.org"), 
		_T("north-america.pool.ntp.org"), 
		_T("oceania.pool.ntp.org"), 
		_T("south-america.pool.ntp.org")
	};
	int iId = 0;
	for(iId = 0; iId < COUNTOF(cstrNTPServers); iId++)
	{
		if(ntpClient.GetServerTime(cstrNTPServers[iId], response))
		{
			// Success.
			SYSTEMTIME stReceiveTime = response.m_ReceiveTime;
			tNTP = COleDateTime(stReceiveTime.wYear, stReceiveTime.wMonth, stReceiveTime.wDay, stReceiveTime.wHour, stReceiveTime.wMinute, stReceiveTime.wSecond);
			break;
		}
	}
	// In the unlikely event that all servers are down we loose
	if(iId == COUNTOF(cstrNTPServers))
	{
		// Failure.
		return false;
	}
	// Normal exit.
	::WSACleanup();
	return true;
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior)
Denmark Denmark
c/c++/c# -developer.

Comments and Discussions