// ------------------------------------------------------------------------------------------------------------------------------------------------------
// - 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;
}