This commit is contained in:
138
HookMsg/UtilClass/BackgroundUtil.cpp
Normal file
138
HookMsg/UtilClass/BackgroundUtil.cpp
Normal file
@@ -0,0 +1,138 @@
|
|||||||
|
#include "stdafx.h"
|
||||||
|
#include "BackgroundUtil.h"
|
||||||
|
|
||||||
|
#ifdef _DEBUG
|
||||||
|
#undef THIS_FILE
|
||||||
|
static char THIS_FILE[]=__FILE__;
|
||||||
|
#define new DEBUG_NEW
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// Construction/Destruction
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
CBackgroundUtil::CBackgroundUtil()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
CBackgroundUtil::~CBackgroundUtil()
|
||||||
|
{
|
||||||
|
m_BmpPattern.Detach();
|
||||||
|
m_BmpPalette.Detach();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BOOL CBackgroundUtil::SetBitmap(UINT uResourceID)
|
||||||
|
{
|
||||||
|
BITMAP bm;
|
||||||
|
BOOL bRet;
|
||||||
|
|
||||||
|
// Detach previous resources
|
||||||
|
m_BmpPattern.Detach();
|
||||||
|
m_BmpPalette.Detach();
|
||||||
|
|
||||||
|
// Default return value
|
||||||
|
bRet = TRUE;
|
||||||
|
|
||||||
|
// Load new bitmap
|
||||||
|
if (uResourceID != 0)
|
||||||
|
{
|
||||||
|
bRet = GetBitmapAndPalette(uResourceID, m_BmpPattern, m_BmpPalette);
|
||||||
|
// If all ok
|
||||||
|
if (bRet == TRUE)
|
||||||
|
{
|
||||||
|
// Get dimension
|
||||||
|
m_BmpPattern.GetBitmap(&bm);
|
||||||
|
// Width of the bitmap
|
||||||
|
m_nBmpWidth = bm.bmWidth;
|
||||||
|
// Height of the bitmap
|
||||||
|
m_nBmpHeight = bm.bmHeight;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return bRet;
|
||||||
|
} // End of SetBitmap
|
||||||
|
|
||||||
|
|
||||||
|
BOOL CBackgroundUtil::GetBitmapAndPalette(UINT nIDResource, CBitmap & bitmap, CPalette & pal)
|
||||||
|
{
|
||||||
|
LPCTSTR lpszResourceName = (LPCTSTR)nIDResource;
|
||||||
|
|
||||||
|
HBITMAP hBmp = (HBITMAP)::LoadImage( AfxGetInstanceHandle(),
|
||||||
|
lpszResourceName, IMAGE_BITMAP, 0,0, LR_CREATEDIBSECTION);
|
||||||
|
|
||||||
|
if (hBmp == NULL) return FALSE;
|
||||||
|
|
||||||
|
bitmap.Attach(hBmp);
|
||||||
|
|
||||||
|
// Create a logical palette for the bitmap
|
||||||
|
DIBSECTION ds;
|
||||||
|
BITMAPINFOHEADER &bmInfo = ds.dsBmih;
|
||||||
|
bitmap.GetObject(sizeof(ds), &ds);
|
||||||
|
|
||||||
|
int nColors = bmInfo.biClrUsed ? bmInfo.biClrUsed : 1 << bmInfo.biBitCount;
|
||||||
|
|
||||||
|
// Create a halftone palette if colors > 256.
|
||||||
|
CClientDC dc(NULL); // Desktop DC
|
||||||
|
|
||||||
|
if(nColors > 256)
|
||||||
|
pal.CreateHalftonePalette(&dc);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Create the palette
|
||||||
|
RGBQUAD *pRGB = new RGBQUAD[nColors];
|
||||||
|
CDC memDC;
|
||||||
|
memDC.CreateCompatibleDC(&dc);
|
||||||
|
memDC.SelectObject( &bitmap );
|
||||||
|
::GetDIBColorTable( memDC, 0, nColors, pRGB );
|
||||||
|
UINT nSize = sizeof(LOGPALETTE) + (sizeof(PALETTEENTRY) * nColors);
|
||||||
|
LOGPALETTE *pLP = (LOGPALETTE *) new BYTE[nSize];
|
||||||
|
pLP->palVersion = 0x300;
|
||||||
|
pLP->palNumEntries = nColors;
|
||||||
|
for (int i=0; i < nColors; i++)
|
||||||
|
{
|
||||||
|
pLP->palPalEntry[i].peRed = pRGB[i].rgbRed;
|
||||||
|
pLP->palPalEntry[i].peGreen = pRGB[i].rgbGreen;
|
||||||
|
pLP->palPalEntry[i].peBlue = pRGB[i].rgbBlue;
|
||||||
|
pLP->palPalEntry[i].peFlags = 0;
|
||||||
|
}
|
||||||
|
pal.CreatePalette( pLP );
|
||||||
|
delete[] pLP;
|
||||||
|
delete[] pRGB;
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
} // End of GetBitmapAndPalette
|
||||||
|
|
||||||
|
|
||||||
|
BOOL CBackgroundUtil::TileBitmap(CDC* pDC, CRect rc)
|
||||||
|
{
|
||||||
|
CDC MemDC;
|
||||||
|
|
||||||
|
int x = 0, y = 0;
|
||||||
|
|
||||||
|
// If there is a bitmap loaded
|
||||||
|
if (m_BmpPattern.m_hObject != NULL)
|
||||||
|
{
|
||||||
|
MemDC.CreateCompatibleDC(pDC);
|
||||||
|
CBitmap* pOldBitmap = MemDC.SelectObject(&m_BmpPattern);
|
||||||
|
|
||||||
|
// Tile the bitmap
|
||||||
|
while (y < rc.Height())
|
||||||
|
{
|
||||||
|
while(x < rc.Width())
|
||||||
|
{
|
||||||
|
pDC->BitBlt(x, y, m_nBmpWidth, m_nBmpHeight, &MemDC, 0, 0, SRCCOPY);
|
||||||
|
x += m_nBmpWidth;
|
||||||
|
}
|
||||||
|
x = 0;
|
||||||
|
y += m_nBmpHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
MemDC.SelectObject(pOldBitmap);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE; // Normal behaviour
|
||||||
|
} // End of TileBitmap
|
||||||
25
HookMsg/UtilClass/BackgroundUtil.h
Normal file
25
HookMsg/UtilClass/BackgroundUtil.h
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
#ifndef _BACKGROUNDUTIL_H_
|
||||||
|
#define _BACKGROUNDUTIL_H_
|
||||||
|
|
||||||
|
#if _MSC_VER >= 1000
|
||||||
|
#pragma once
|
||||||
|
#endif // _MSC_VER >= 1000
|
||||||
|
|
||||||
|
class CBackgroundUtil
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
BOOL SetBitmap(UINT uResourceID = 0);
|
||||||
|
CBackgroundUtil();
|
||||||
|
virtual ~CBackgroundUtil();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
BOOL TileBitmap(CDC* pDC, CRect rc);
|
||||||
|
BOOL GetBitmapAndPalette(UINT nIDResource, CBitmap& bitmap, CPalette& pal);
|
||||||
|
// For background bitmap
|
||||||
|
CBitmap m_BmpPattern;
|
||||||
|
CPalette m_BmpPalette;
|
||||||
|
int m_nBmpWidth;
|
||||||
|
int m_nBmpHeight;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
66
HookMsg/UtilClass/BkDialog.cpp
Normal file
66
HookMsg/UtilClass/BkDialog.cpp
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
// BkDialog.cpp : Defines the class behaviors for the application.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "stdafx.h"
|
||||||
|
#include "BkDialog.h"
|
||||||
|
|
||||||
|
#ifdef _DEBUG
|
||||||
|
#define new DEBUG_NEW
|
||||||
|
#undef THIS_FILE
|
||||||
|
static char THIS_FILE[] = __FILE__;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
CBkDialog::CBkDialog(CWnd* pParent /*=NULL*/)
|
||||||
|
{
|
||||||
|
//{{AFX_DATA_INIT(CBkDialog)
|
||||||
|
// NOTE: the ClassWizard will add member initialization here
|
||||||
|
//}}AFX_DATA_INIT
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
CBkDialog::CBkDialog(UINT uResourceID, CWnd* pParent)
|
||||||
|
: CDialog(uResourceID, pParent)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
CBkDialog::CBkDialog(LPCTSTR pszResourceID, CWnd* pParent)
|
||||||
|
: CDialog(pszResourceID, pParent)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
CBkDialog::~CBkDialog()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void CBkDialog::DoDataExchange(CDataExchange* pDX)
|
||||||
|
{
|
||||||
|
CDialog::DoDataExchange(pDX);
|
||||||
|
//{{AFX_DATA_MAP(CBkDialog)
|
||||||
|
// NOTE: the ClassWizard will add DDX and DDV calls here
|
||||||
|
//}}AFX_DATA_MAP
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BEGIN_MESSAGE_MAP(CBkDialog, CDialog)
|
||||||
|
//{{AFX_MSG_MAP(CBkDialog)
|
||||||
|
ON_WM_ERASEBKGND()
|
||||||
|
//}}AFX_MSG_MAP
|
||||||
|
END_MESSAGE_MAP()
|
||||||
|
|
||||||
|
|
||||||
|
BOOL CBkDialog::OnEraseBkgnd(CDC* pDC)
|
||||||
|
{
|
||||||
|
CRect rc;
|
||||||
|
|
||||||
|
GetClientRect(rc);
|
||||||
|
|
||||||
|
m_pDC = pDC;
|
||||||
|
|
||||||
|
if (TileBitmap(pDC, rc) == TRUE)
|
||||||
|
return TRUE;
|
||||||
|
else
|
||||||
|
return CDialog::OnEraseBkgnd(pDC);
|
||||||
|
} // End of OnEraseBkgnd
|
||||||
50
HookMsg/UtilClass/BkDialog.h
Normal file
50
HookMsg/UtilClass/BkDialog.h
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
#ifndef _BKDIALOG_H_
|
||||||
|
#define _BKDIALOG_H_
|
||||||
|
|
||||||
|
#include "BackgroundUtil.h"
|
||||||
|
|
||||||
|
#if _MSC_VER >= 1000
|
||||||
|
#pragma once
|
||||||
|
#endif // _MSC_VER >= 1000
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
// CBkDialog dialog
|
||||||
|
|
||||||
|
class CBkDialog : public CDialog, public CBackgroundUtil
|
||||||
|
{
|
||||||
|
// Construction
|
||||||
|
public:
|
||||||
|
CDC* m_pDC;
|
||||||
|
~CBkDialog();
|
||||||
|
CBkDialog(LPCTSTR pszResourceID, CWnd* pParent = NULL);
|
||||||
|
CBkDialog(UINT uResourceID, CWnd* pParent = NULL);
|
||||||
|
CBkDialog(CWnd* pParent = NULL); // standard constructor
|
||||||
|
|
||||||
|
// Dialog Data
|
||||||
|
//{{AFX_DATA(CBkDialog)
|
||||||
|
// NOTE: the ClassWizard will add data members here
|
||||||
|
//}}AFX_DATA
|
||||||
|
|
||||||
|
|
||||||
|
// Overrides
|
||||||
|
// ClassWizard generated virtual function overrides
|
||||||
|
//{{AFX_VIRTUAL(CBkDialog)
|
||||||
|
protected:
|
||||||
|
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
|
||||||
|
//}}AFX_VIRTUAL
|
||||||
|
|
||||||
|
// Implementation
|
||||||
|
protected:
|
||||||
|
|
||||||
|
// Generated message map functions
|
||||||
|
//{{AFX_MSG(CBkDialog)
|
||||||
|
afx_msg BOOL OnEraseBkgnd(CDC* pDC);
|
||||||
|
//}}AFX_MSG
|
||||||
|
DECLARE_MESSAGE_MAP()
|
||||||
|
};
|
||||||
|
//{{AFX_INSERT_LOCATION}}
|
||||||
|
// Microsoft Developer Studio will insert additional declarations immediately before the previous line.
|
||||||
|
|
||||||
|
#endif
|
||||||
38
HookMsg/UtilClass/LimitSingleInstance.h
Normal file
38
HookMsg/UtilClass/LimitSingleInstance.h
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
#ifndef LimitSingleInstance_H
|
||||||
|
#define LimitSingleInstance_H
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
//this code is from Q243953 in case you lose the article and wonder
|
||||||
|
//where this code came from...
|
||||||
|
class CLimitSingleInstance
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
DWORD m_dwLastError;
|
||||||
|
HANDLE m_hMutex;
|
||||||
|
|
||||||
|
public:
|
||||||
|
CLimitSingleInstance(TCHAR *strMutexName)
|
||||||
|
{
|
||||||
|
//be sure to use a name that is unique for this application otherwise
|
||||||
|
//two apps may think they are the same if they are using same name for
|
||||||
|
//3rd parm to CreateMutex
|
||||||
|
m_hMutex = CreateMutex(NULL, FALSE, strMutexName); //do early
|
||||||
|
m_dwLastError = GetLastError(); //save for use later...
|
||||||
|
}
|
||||||
|
|
||||||
|
~CLimitSingleInstance()
|
||||||
|
{
|
||||||
|
if (m_hMutex) //don't forget to close handles...
|
||||||
|
{
|
||||||
|
CloseHandle(m_hMutex); //do as late as possible
|
||||||
|
m_hMutex = NULL; //good habit to be in
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL IsAnotherInstanceRunning()
|
||||||
|
{
|
||||||
|
return (ERROR_ALREADY_EXISTS == m_dwLastError);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
#endif
|
||||||
726
HookMsg/UtilClass/Sntp.cpp
Normal file
726
HookMsg/UtilClass/Sntp.cpp
Normal file
@@ -0,0 +1,726 @@
|
|||||||
|
/*
|
||||||
|
Module : SNTP.CPP
|
||||||
|
Purpose: implementation for a MFC class to encapsulate the SNTP protocol
|
||||||
|
Created: PJN / 05-08-1998
|
||||||
|
History: PJN / 16-11-1998 1. m_nOriginateTime was getting set incorrectly in the SNTP response
|
||||||
|
2. GetLastError now works when a timeout occurs.
|
||||||
|
|
||||||
|
Copyright (c) 1998 by PJ Naughter.
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
///////////////////////////////// Includes //////////////////////////////////
|
||||||
|
#include "stdafx.h"
|
||||||
|
#include <math.h>
|
||||||
|
#include "sntp.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////// Macros / Locals ///////////////////////////
|
||||||
|
|
||||||
|
#ifdef _DEBUG
|
||||||
|
#define new DEBUG_NEW
|
||||||
|
#undef THIS_FILE
|
||||||
|
static char THIS_FILE[] = __FILE__;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
const double NTP_FRACTIONAL_TO_MS = (((double)1000.0)/0xFFFFFFFF);
|
||||||
|
const double NTP_TO_SECOND = (((double)1.0)/0xFFFFFFFF);
|
||||||
|
const long JAN_1ST_1900 = 2415021;
|
||||||
|
|
||||||
|
//Lookup table to convert from Milliseconds (hence 1000 Entries)
|
||||||
|
//to fractions of a second expressed as a DWORD
|
||||||
|
DWORD CNtpTime::m_MsToNTP[1000] =
|
||||||
|
{
|
||||||
|
0x00000000, 0x00418937, 0x0083126f, 0x00c49ba6, 0x010624dd, 0x0147ae14,
|
||||||
|
0x0189374c, 0x01cac083, 0x020c49ba, 0x024dd2f2, 0x028f5c29, 0x02d0e560,
|
||||||
|
0x03126e98, 0x0353f7cf, 0x03958106, 0x03d70a3d, 0x04189375, 0x045a1cac,
|
||||||
|
0x049ba5e3, 0x04dd2f1b, 0x051eb852, 0x05604189, 0x05a1cac1, 0x05e353f8,
|
||||||
|
0x0624dd2f, 0x06666666, 0x06a7ef9e, 0x06e978d5, 0x072b020c, 0x076c8b44,
|
||||||
|
0x07ae147b, 0x07ef9db2, 0x083126e9, 0x0872b021, 0x08b43958, 0x08f5c28f,
|
||||||
|
0x09374bc7, 0x0978d4fe, 0x09ba5e35, 0x09fbe76d, 0x0a3d70a4, 0x0a7ef9db,
|
||||||
|
0x0ac08312, 0x0b020c4a, 0x0b439581, 0x0b851eb8, 0x0bc6a7f0, 0x0c083127,
|
||||||
|
0x0c49ba5e, 0x0c8b4396, 0x0ccccccd, 0x0d0e5604, 0x0d4fdf3b, 0x0d916873,
|
||||||
|
0x0dd2f1aa, 0x0e147ae1, 0x0e560419, 0x0e978d50, 0x0ed91687, 0x0f1a9fbe,
|
||||||
|
0x0f5c28f6, 0x0f9db22d, 0x0fdf3b64, 0x1020c49c, 0x10624dd3, 0x10a3d70a,
|
||||||
|
0x10e56042, 0x1126e979, 0x116872b0, 0x11a9fbe7, 0x11eb851f, 0x122d0e56,
|
||||||
|
0x126e978d, 0x12b020c5, 0x12f1a9fc, 0x13333333, 0x1374bc6a, 0x13b645a2,
|
||||||
|
0x13f7ced9, 0x14395810, 0x147ae148, 0x14bc6a7f, 0x14fdf3b6, 0x153f7cee,
|
||||||
|
0x15810625, 0x15c28f5c, 0x16041893, 0x1645a1cb, 0x16872b02, 0x16c8b439,
|
||||||
|
0x170a3d71, 0x174bc6a8, 0x178d4fdf, 0x17ced917, 0x1810624e, 0x1851eb85,
|
||||||
|
0x189374bc, 0x18d4fdf4, 0x1916872b, 0x19581062, 0x1999999a, 0x19db22d1,
|
||||||
|
0x1a1cac08, 0x1a5e353f, 0x1a9fbe77, 0x1ae147ae, 0x1b22d0e5, 0x1b645a1d,
|
||||||
|
0x1ba5e354, 0x1be76c8b, 0x1c28f5c3, 0x1c6a7efa, 0x1cac0831, 0x1ced9168,
|
||||||
|
0x1d2f1aa0, 0x1d70a3d7, 0x1db22d0e, 0x1df3b646, 0x1e353f7d, 0x1e76c8b4,
|
||||||
|
0x1eb851ec, 0x1ef9db23, 0x1f3b645a, 0x1f7ced91, 0x1fbe76c9, 0x20000000,
|
||||||
|
0x20418937, 0x2083126f, 0x20c49ba6, 0x210624dd, 0x2147ae14, 0x2189374c,
|
||||||
|
0x21cac083, 0x220c49ba, 0x224dd2f2, 0x228f5c29, 0x22d0e560, 0x23126e98,
|
||||||
|
0x2353f7cf, 0x23958106, 0x23d70a3d, 0x24189375, 0x245a1cac, 0x249ba5e3,
|
||||||
|
0x24dd2f1b, 0x251eb852, 0x25604189, 0x25a1cac1, 0x25e353f8, 0x2624dd2f,
|
||||||
|
0x26666666, 0x26a7ef9e, 0x26e978d5, 0x272b020c, 0x276c8b44, 0x27ae147b,
|
||||||
|
0x27ef9db2, 0x283126e9, 0x2872b021, 0x28b43958, 0x28f5c28f, 0x29374bc7,
|
||||||
|
0x2978d4fe, 0x29ba5e35, 0x29fbe76d, 0x2a3d70a4, 0x2a7ef9db, 0x2ac08312,
|
||||||
|
0x2b020c4a, 0x2b439581, 0x2b851eb8, 0x2bc6a7f0, 0x2c083127, 0x2c49ba5e,
|
||||||
|
0x2c8b4396, 0x2ccccccd, 0x2d0e5604, 0x2d4fdf3b, 0x2d916873, 0x2dd2f1aa,
|
||||||
|
0x2e147ae1, 0x2e560419, 0x2e978d50, 0x2ed91687, 0x2f1a9fbe, 0x2f5c28f6,
|
||||||
|
0x2f9db22d, 0x2fdf3b64, 0x3020c49c, 0x30624dd3, 0x30a3d70a, 0x30e56042,
|
||||||
|
0x3126e979, 0x316872b0, 0x31a9fbe7, 0x31eb851f, 0x322d0e56, 0x326e978d,
|
||||||
|
0x32b020c5, 0x32f1a9fc, 0x33333333, 0x3374bc6a, 0x33b645a2, 0x33f7ced9,
|
||||||
|
0x34395810, 0x347ae148, 0x34bc6a7f, 0x34fdf3b6, 0x353f7cee, 0x35810625,
|
||||||
|
0x35c28f5c, 0x36041893, 0x3645a1cb, 0x36872b02, 0x36c8b439, 0x370a3d71,
|
||||||
|
0x374bc6a8, 0x378d4fdf, 0x37ced917, 0x3810624e, 0x3851eb85, 0x389374bc,
|
||||||
|
0x38d4fdf4, 0x3916872b, 0x39581062, 0x3999999a, 0x39db22d1, 0x3a1cac08,
|
||||||
|
0x3a5e353f, 0x3a9fbe77, 0x3ae147ae, 0x3b22d0e5, 0x3b645a1d, 0x3ba5e354,
|
||||||
|
0x3be76c8b, 0x3c28f5c3, 0x3c6a7efa, 0x3cac0831, 0x3ced9168, 0x3d2f1aa0,
|
||||||
|
0x3d70a3d7, 0x3db22d0e, 0x3df3b646, 0x3e353f7d, 0x3e76c8b4, 0x3eb851ec,
|
||||||
|
0x3ef9db23, 0x3f3b645a, 0x3f7ced91, 0x3fbe76c9, 0x40000000, 0x40418937,
|
||||||
|
0x4083126f, 0x40c49ba6, 0x410624dd, 0x4147ae14, 0x4189374c, 0x41cac083,
|
||||||
|
0x420c49ba, 0x424dd2f2, 0x428f5c29, 0x42d0e560, 0x43126e98, 0x4353f7cf,
|
||||||
|
0x43958106, 0x43d70a3d, 0x44189375, 0x445a1cac, 0x449ba5e3, 0x44dd2f1b,
|
||||||
|
0x451eb852, 0x45604189, 0x45a1cac1, 0x45e353f8, 0x4624dd2f, 0x46666666,
|
||||||
|
0x46a7ef9e, 0x46e978d5, 0x472b020c, 0x476c8b44, 0x47ae147b, 0x47ef9db2,
|
||||||
|
0x483126e9, 0x4872b021, 0x48b43958, 0x48f5c28f, 0x49374bc7, 0x4978d4fe,
|
||||||
|
0x49ba5e35, 0x49fbe76d, 0x4a3d70a4, 0x4a7ef9db, 0x4ac08312, 0x4b020c4a,
|
||||||
|
0x4b439581, 0x4b851eb8, 0x4bc6a7f0, 0x4c083127, 0x4c49ba5e, 0x4c8b4396,
|
||||||
|
0x4ccccccd, 0x4d0e5604, 0x4d4fdf3b, 0x4d916873, 0x4dd2f1aa, 0x4e147ae1,
|
||||||
|
0x4e560419, 0x4e978d50, 0x4ed91687, 0x4f1a9fbe, 0x4f5c28f6, 0x4f9db22d,
|
||||||
|
0x4fdf3b64, 0x5020c49c, 0x50624dd3, 0x50a3d70a, 0x50e56042, 0x5126e979,
|
||||||
|
0x516872b0, 0x51a9fbe7, 0x51eb851f, 0x522d0e56, 0x526e978d, 0x52b020c5,
|
||||||
|
0x52f1a9fc, 0x53333333, 0x5374bc6a, 0x53b645a2, 0x53f7ced9, 0x54395810,
|
||||||
|
0x547ae148, 0x54bc6a7f, 0x54fdf3b6, 0x553f7cee, 0x55810625, 0x55c28f5c,
|
||||||
|
0x56041893, 0x5645a1cb, 0x56872b02, 0x56c8b439, 0x570a3d71, 0x574bc6a8,
|
||||||
|
0x578d4fdf, 0x57ced917, 0x5810624e, 0x5851eb85, 0x589374bc, 0x58d4fdf4,
|
||||||
|
0x5916872b, 0x59581062, 0x5999999a, 0x59db22d1, 0x5a1cac08, 0x5a5e353f,
|
||||||
|
0x5a9fbe77, 0x5ae147ae, 0x5b22d0e5, 0x5b645a1d, 0x5ba5e354, 0x5be76c8b,
|
||||||
|
0x5c28f5c3, 0x5c6a7efa, 0x5cac0831, 0x5ced9168, 0x5d2f1aa0, 0x5d70a3d7,
|
||||||
|
0x5db22d0e, 0x5df3b646, 0x5e353f7d, 0x5e76c8b4, 0x5eb851ec, 0x5ef9db23,
|
||||||
|
0x5f3b645a, 0x5f7ced91, 0x5fbe76c9, 0x60000000, 0x60418937, 0x6083126f,
|
||||||
|
0x60c49ba6, 0x610624dd, 0x6147ae14, 0x6189374c, 0x61cac083, 0x620c49ba,
|
||||||
|
0x624dd2f2, 0x628f5c29, 0x62d0e560, 0x63126e98, 0x6353f7cf, 0x63958106,
|
||||||
|
0x63d70a3d, 0x64189375, 0x645a1cac, 0x649ba5e3, 0x64dd2f1b, 0x651eb852,
|
||||||
|
0x65604189, 0x65a1cac1, 0x65e353f8, 0x6624dd2f, 0x66666666, 0x66a7ef9e,
|
||||||
|
0x66e978d5, 0x672b020c, 0x676c8b44, 0x67ae147b, 0x67ef9db2, 0x683126e9,
|
||||||
|
0x6872b021, 0x68b43958, 0x68f5c28f, 0x69374bc7, 0x6978d4fe, 0x69ba5e35,
|
||||||
|
0x69fbe76d, 0x6a3d70a4, 0x6a7ef9db, 0x6ac08312, 0x6b020c4a, 0x6b439581,
|
||||||
|
0x6b851eb8, 0x6bc6a7f0, 0x6c083127, 0x6c49ba5e, 0x6c8b4396, 0x6ccccccd,
|
||||||
|
0x6d0e5604, 0x6d4fdf3b, 0x6d916873, 0x6dd2f1aa, 0x6e147ae1, 0x6e560419,
|
||||||
|
0x6e978d50, 0x6ed91687, 0x6f1a9fbe, 0x6f5c28f6, 0x6f9db22d, 0x6fdf3b64,
|
||||||
|
0x7020c49c, 0x70624dd3, 0x70a3d70a, 0x70e56042, 0x7126e979, 0x716872b0,
|
||||||
|
0x71a9fbe7, 0x71eb851f, 0x722d0e56, 0x726e978d, 0x72b020c5, 0x72f1a9fc,
|
||||||
|
0x73333333, 0x7374bc6a, 0x73b645a2, 0x73f7ced9, 0x74395810, 0x747ae148,
|
||||||
|
0x74bc6a7f, 0x74fdf3b6, 0x753f7cee, 0x75810625, 0x75c28f5c, 0x76041893,
|
||||||
|
0x7645a1cb, 0x76872b02, 0x76c8b439, 0x770a3d71, 0x774bc6a8, 0x778d4fdf,
|
||||||
|
0x77ced917, 0x7810624e, 0x7851eb85, 0x789374bc, 0x78d4fdf4, 0x7916872b,
|
||||||
|
0x79581062, 0x7999999a, 0x79db22d1, 0x7a1cac08, 0x7a5e353f, 0x7a9fbe77,
|
||||||
|
0x7ae147ae, 0x7b22d0e5, 0x7b645a1d, 0x7ba5e354, 0x7be76c8b, 0x7c28f5c3,
|
||||||
|
0x7c6a7efa, 0x7cac0831, 0x7ced9168, 0x7d2f1aa0, 0x7d70a3d7, 0x7db22d0e,
|
||||||
|
0x7df3b646, 0x7e353f7d, 0x7e76c8b4, 0x7eb851ec, 0x7ef9db23, 0x7f3b645a,
|
||||||
|
0x7f7ced91, 0x7fbe76c9, 0x80000000, 0x80418937, 0x8083126f, 0x80c49ba6,
|
||||||
|
0x810624dd, 0x8147ae14, 0x8189374c, 0x81cac083, 0x820c49ba, 0x824dd2f2,
|
||||||
|
0x828f5c29, 0x82d0e560, 0x83126e98, 0x8353f7cf, 0x83958106, 0x83d70a3d,
|
||||||
|
0x84189375, 0x845a1cac, 0x849ba5e3, 0x84dd2f1b, 0x851eb852, 0x85604189,
|
||||||
|
0x85a1cac1, 0x85e353f8, 0x8624dd2f, 0x86666666, 0x86a7ef9e, 0x86e978d5,
|
||||||
|
0x872b020c, 0x876c8b44, 0x87ae147b, 0x87ef9db2, 0x883126e9, 0x8872b021,
|
||||||
|
0x88b43958, 0x88f5c28f, 0x89374bc7, 0x8978d4fe, 0x89ba5e35, 0x89fbe76d,
|
||||||
|
0x8a3d70a4, 0x8a7ef9db, 0x8ac08312, 0x8b020c4a, 0x8b439581, 0x8b851eb8,
|
||||||
|
0x8bc6a7f0, 0x8c083127, 0x8c49ba5e, 0x8c8b4396, 0x8ccccccd, 0x8d0e5604,
|
||||||
|
0x8d4fdf3b, 0x8d916873, 0x8dd2f1aa, 0x8e147ae1, 0x8e560419, 0x8e978d50,
|
||||||
|
0x8ed91687, 0x8f1a9fbe, 0x8f5c28f6, 0x8f9db22d, 0x8fdf3b64, 0x9020c49c,
|
||||||
|
0x90624dd3, 0x90a3d70a, 0x90e56042, 0x9126e979, 0x916872b0, 0x91a9fbe7,
|
||||||
|
0x91eb851f, 0x922d0e56, 0x926e978d, 0x92b020c5, 0x92f1a9fc, 0x93333333,
|
||||||
|
0x9374bc6a, 0x93b645a2, 0x93f7ced9, 0x94395810, 0x947ae148, 0x94bc6a7f,
|
||||||
|
0x94fdf3b6, 0x953f7cee, 0x95810625, 0x95c28f5c, 0x96041893, 0x9645a1cb,
|
||||||
|
0x96872b02, 0x96c8b439, 0x970a3d71, 0x974bc6a8, 0x978d4fdf, 0x97ced917,
|
||||||
|
0x9810624e, 0x9851eb85, 0x989374bc, 0x98d4fdf4, 0x9916872b, 0x99581062,
|
||||||
|
0x9999999a, 0x99db22d1, 0x9a1cac08, 0x9a5e353f, 0x9a9fbe77, 0x9ae147ae,
|
||||||
|
0x9b22d0e5, 0x9b645a1d, 0x9ba5e354, 0x9be76c8b, 0x9c28f5c3, 0x9c6a7efa,
|
||||||
|
0x9cac0831, 0x9ced9168, 0x9d2f1aa0, 0x9d70a3d7, 0x9db22d0e, 0x9df3b646,
|
||||||
|
0x9e353f7d, 0x9e76c8b4, 0x9eb851ec, 0x9ef9db23, 0x9f3b645a, 0x9f7ced91,
|
||||||
|
0x9fbe76c9, 0xa0000000, 0xa0418937, 0xa083126f, 0xa0c49ba6, 0xa10624dd,
|
||||||
|
0xa147ae14, 0xa189374c, 0xa1cac083, 0xa20c49ba, 0xa24dd2f2, 0xa28f5c29,
|
||||||
|
0xa2d0e560, 0xa3126e98, 0xa353f7cf, 0xa3958106, 0xa3d70a3d, 0xa4189375,
|
||||||
|
0xa45a1cac, 0xa49ba5e3, 0xa4dd2f1b, 0xa51eb852, 0xa5604189, 0xa5a1cac1,
|
||||||
|
0xa5e353f8, 0xa624dd2f, 0xa6666666, 0xa6a7ef9e, 0xa6e978d5, 0xa72b020c,
|
||||||
|
0xa76c8b44, 0xa7ae147b, 0xa7ef9db2, 0xa83126e9, 0xa872b021, 0xa8b43958,
|
||||||
|
0xa8f5c28f, 0xa9374bc7, 0xa978d4fe, 0xa9ba5e35, 0xa9fbe76d, 0xaa3d70a4,
|
||||||
|
0xaa7ef9db, 0xaac08312, 0xab020c4a, 0xab439581, 0xab851eb8, 0xabc6a7f0,
|
||||||
|
0xac083127, 0xac49ba5e, 0xac8b4396, 0xaccccccd, 0xad0e5604, 0xad4fdf3b,
|
||||||
|
0xad916873, 0xadd2f1aa, 0xae147ae1, 0xae560419, 0xae978d50, 0xaed91687,
|
||||||
|
0xaf1a9fbe, 0xaf5c28f6, 0xaf9db22d, 0xafdf3b64, 0xb020c49c, 0xb0624dd3,
|
||||||
|
0xb0a3d70a, 0xb0e56042, 0xb126e979, 0xb16872b0, 0xb1a9fbe7, 0xb1eb851f,
|
||||||
|
0xb22d0e56, 0xb26e978d, 0xb2b020c5, 0xb2f1a9fc, 0xb3333333, 0xb374bc6a,
|
||||||
|
0xb3b645a2, 0xb3f7ced9, 0xb4395810, 0xb47ae148, 0xb4bc6a7f, 0xb4fdf3b6,
|
||||||
|
0xb53f7cee, 0xb5810625, 0xb5c28f5c, 0xb6041893, 0xb645a1cb, 0xb6872b02,
|
||||||
|
0xb6c8b439, 0xb70a3d71, 0xb74bc6a8, 0xb78d4fdf, 0xb7ced917, 0xb810624e,
|
||||||
|
0xb851eb85, 0xb89374bc, 0xb8d4fdf4, 0xb916872b, 0xb9581062, 0xb999999a,
|
||||||
|
0xb9db22d1, 0xba1cac08, 0xba5e353f, 0xba9fbe77, 0xbae147ae, 0xbb22d0e5,
|
||||||
|
0xbb645a1d, 0xbba5e354, 0xbbe76c8b, 0xbc28f5c3, 0xbc6a7efa, 0xbcac0831,
|
||||||
|
0xbced9168, 0xbd2f1aa0, 0xbd70a3d7, 0xbdb22d0e, 0xbdf3b646, 0xbe353f7d,
|
||||||
|
0xbe76c8b4, 0xbeb851ec, 0xbef9db23, 0xbf3b645a, 0xbf7ced91, 0xbfbe76c9,
|
||||||
|
0xc0000000, 0xc0418937, 0xc083126f, 0xc0c49ba6, 0xc10624dd, 0xc147ae14,
|
||||||
|
0xc189374c, 0xc1cac083, 0xc20c49ba, 0xc24dd2f2, 0xc28f5c29, 0xc2d0e560,
|
||||||
|
0xc3126e98, 0xc353f7cf, 0xc3958106, 0xc3d70a3d, 0xc4189375, 0xc45a1cac,
|
||||||
|
0xc49ba5e3, 0xc4dd2f1b, 0xc51eb852, 0xc5604189, 0xc5a1cac1, 0xc5e353f8,
|
||||||
|
0xc624dd2f, 0xc6666666, 0xc6a7ef9e, 0xc6e978d5, 0xc72b020c, 0xc76c8b44,
|
||||||
|
0xc7ae147b, 0xc7ef9db2, 0xc83126e9, 0xc872b021, 0xc8b43958, 0xc8f5c28f,
|
||||||
|
0xc9374bc7, 0xc978d4fe, 0xc9ba5e35, 0xc9fbe76d, 0xca3d70a4, 0xca7ef9db,
|
||||||
|
0xcac08312, 0xcb020c4a, 0xcb439581, 0xcb851eb8, 0xcbc6a7f0, 0xcc083127,
|
||||||
|
0xcc49ba5e, 0xcc8b4396, 0xcccccccd, 0xcd0e5604, 0xcd4fdf3b, 0xcd916873,
|
||||||
|
0xcdd2f1aa, 0xce147ae1, 0xce560419, 0xce978d50, 0xced91687, 0xcf1a9fbe,
|
||||||
|
0xcf5c28f6, 0xcf9db22d, 0xcfdf3b64, 0xd020c49c, 0xd0624dd3, 0xd0a3d70a,
|
||||||
|
0xd0e56042, 0xd126e979, 0xd16872b0, 0xd1a9fbe7, 0xd1eb851f, 0xd22d0e56,
|
||||||
|
0xd26e978d, 0xd2b020c5, 0xd2f1a9fc, 0xd3333333, 0xd374bc6a, 0xd3b645a2,
|
||||||
|
0xd3f7ced9, 0xd4395810, 0xd47ae148, 0xd4bc6a7f, 0xd4fdf3b6, 0xd53f7cee,
|
||||||
|
0xd5810625, 0xd5c28f5c, 0xd6041893, 0xd645a1cb, 0xd6872b02, 0xd6c8b439,
|
||||||
|
0xd70a3d71, 0xd74bc6a8, 0xd78d4fdf, 0xd7ced917, 0xd810624e, 0xd851eb85,
|
||||||
|
0xd89374bc, 0xd8d4fdf4, 0xd916872b, 0xd9581062, 0xd999999a, 0xd9db22d1,
|
||||||
|
0xda1cac08, 0xda5e353f, 0xda9fbe77, 0xdae147ae, 0xdb22d0e5, 0xdb645a1d,
|
||||||
|
0xdba5e354, 0xdbe76c8b, 0xdc28f5c3, 0xdc6a7efa, 0xdcac0831, 0xdced9168,
|
||||||
|
0xdd2f1aa0, 0xdd70a3d7, 0xddb22d0e, 0xddf3b646, 0xde353f7d, 0xde76c8b4,
|
||||||
|
0xdeb851ec, 0xdef9db23, 0xdf3b645a, 0xdf7ced91, 0xdfbe76c9, 0xe0000000,
|
||||||
|
0xe0418937, 0xe083126f, 0xe0c49ba6, 0xe10624dd, 0xe147ae14, 0xe189374c,
|
||||||
|
0xe1cac083, 0xe20c49ba, 0xe24dd2f2, 0xe28f5c29, 0xe2d0e560, 0xe3126e98,
|
||||||
|
0xe353f7cf, 0xe3958106, 0xe3d70a3d, 0xe4189375, 0xe45a1cac, 0xe49ba5e3,
|
||||||
|
0xe4dd2f1b, 0xe51eb852, 0xe5604189, 0xe5a1cac1, 0xe5e353f8, 0xe624dd2f,
|
||||||
|
0xe6666666, 0xe6a7ef9e, 0xe6e978d5, 0xe72b020c, 0xe76c8b44, 0xe7ae147b,
|
||||||
|
0xe7ef9db2, 0xe83126e9, 0xe872b021, 0xe8b43958, 0xe8f5c28f, 0xe9374bc7,
|
||||||
|
0xe978d4fe, 0xe9ba5e35, 0xe9fbe76d, 0xea3d70a4, 0xea7ef9db, 0xeac08312,
|
||||||
|
0xeb020c4a, 0xeb439581, 0xeb851eb8, 0xebc6a7f0, 0xec083127, 0xec49ba5e,
|
||||||
|
0xec8b4396, 0xeccccccd, 0xed0e5604, 0xed4fdf3b, 0xed916873, 0xedd2f1aa,
|
||||||
|
0xee147ae1, 0xee560419, 0xee978d50, 0xeed91687, 0xef1a9fbe, 0xef5c28f6,
|
||||||
|
0xef9db22d, 0xefdf3b64, 0xf020c49c, 0xf0624dd3, 0xf0a3d70a, 0xf0e56042,
|
||||||
|
0xf126e979, 0xf16872b0, 0xf1a9fbe7, 0xf1eb851f, 0xf22d0e56, 0xf26e978d,
|
||||||
|
0xf2b020c5, 0xf2f1a9fc, 0xf3333333, 0xf374bc6a, 0xf3b645a2, 0xf3f7ced9,
|
||||||
|
0xf4395810, 0xf47ae148, 0xf4bc6a7f, 0xf4fdf3b6, 0xf53f7cee, 0xf5810625,
|
||||||
|
0xf5c28f5c, 0xf6041893, 0xf645a1cb, 0xf6872b02, 0xf6c8b439, 0xf70a3d71,
|
||||||
|
0xf74bc6a8, 0xf78d4fdf, 0xf7ced917, 0xf810624e, 0xf851eb85, 0xf89374bc,
|
||||||
|
0xf8d4fdf4, 0xf916872b, 0xf9581062, 0xf999999a, 0xf9db22d1, 0xfa1cac08,
|
||||||
|
0xfa5e353f, 0xfa9fbe77, 0xfae147ae, 0xfb22d0e5, 0xfb645a1d, 0xfba5e354,
|
||||||
|
0xfbe76c8b, 0xfc28f5c3, 0xfc6a7efa, 0xfcac0831, 0xfced9168, 0xfd2f1aa0,
|
||||||
|
0xfd70a3d7, 0xfdb22d0e, 0xfdf3b646, 0xfe353f7d, 0xfe76c8b4, 0xfeb851ec,
|
||||||
|
0xfef9db23, 0xff3b645a, 0xff7ced91, 0xffbe76c9
|
||||||
|
};
|
||||||
|
|
||||||
|
//The mandatory part of an NTP packet
|
||||||
|
struct NtpBasicInfo
|
||||||
|
{
|
||||||
|
BYTE m_LiVnMode;
|
||||||
|
BYTE m_Stratum;
|
||||||
|
char m_Poll;
|
||||||
|
char m_Precision;
|
||||||
|
long m_RootDelay;
|
||||||
|
long m_RootDispersion;
|
||||||
|
char m_ReferenceID[4];
|
||||||
|
CNtpTimePacket m_ReferenceTimestamp;
|
||||||
|
CNtpTimePacket m_OriginateTimestamp;
|
||||||
|
CNtpTimePacket m_ReceiveTimestamp;
|
||||||
|
CNtpTimePacket m_TransmitTimestamp;
|
||||||
|
};
|
||||||
|
|
||||||
|
//The optional part of an NTP packet
|
||||||
|
struct NtpAuthenticationInfo
|
||||||
|
{
|
||||||
|
unsigned long m_KeyID;
|
||||||
|
BYTE m_MessageDigest[16];
|
||||||
|
};
|
||||||
|
|
||||||
|
//The Full NTP packet
|
||||||
|
struct NtpFullPacket
|
||||||
|
{
|
||||||
|
NtpBasicInfo m_Basic;
|
||||||
|
NtpAuthenticationInfo m_Auth;
|
||||||
|
};
|
||||||
|
|
||||||
|
//Simple wrapper class for an Ntp socket
|
||||||
|
class CNtpSocket
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
//Constructors / Destructors
|
||||||
|
CNtpSocket();
|
||||||
|
~CNtpSocket();
|
||||||
|
|
||||||
|
//General functions
|
||||||
|
BOOL Create();
|
||||||
|
BOOL Connect(LPCTSTR pszHostAddress, int nPort);
|
||||||
|
BOOL Send(LPCSTR pszBuf, int nBuf);
|
||||||
|
int Receive(LPSTR pszBuf, int nBuf);
|
||||||
|
void Close();
|
||||||
|
BOOL IsReadible(BOOL& bReadible, DWORD dwTimeout);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
BOOL Connect(const SOCKADDR* lpSockAddr, int nSockAddrLen);
|
||||||
|
SOCKET m_hSocket;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////// Implementation //////////////////////////////
|
||||||
|
|
||||||
|
CNtpTime::CNtpTime()
|
||||||
|
{
|
||||||
|
m_Time = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
CNtpTime::CNtpTime(const CNtpTime& time)
|
||||||
|
{
|
||||||
|
*this = time;
|
||||||
|
}
|
||||||
|
|
||||||
|
CNtpTime::CNtpTime(CNtpTimePacket& packet)
|
||||||
|
{
|
||||||
|
DWORD dwLow = ntohl(packet.m_dwFractional);
|
||||||
|
DWORD dwHigh = ntohl(packet.m_dwInteger);
|
||||||
|
m_Time = ((unsigned __int64) dwHigh) << 32;
|
||||||
|
m_Time += dwLow;
|
||||||
|
}
|
||||||
|
|
||||||
|
CNtpTime::CNtpTime(const SYSTEMTIME& st)
|
||||||
|
{
|
||||||
|
//Currently this function only operates correctly in
|
||||||
|
//the 1900 - 2036 primary epoch defined by NTP
|
||||||
|
|
||||||
|
long JD = GetJulianDay(st.wYear, st.wMonth, st.wDay);
|
||||||
|
JD -= JAN_1ST_1900;
|
||||||
|
|
||||||
|
ASSERT(JD >= 0); //NTP only supports dates greater than 1900
|
||||||
|
unsigned __int64 Seconds = JD;
|
||||||
|
Seconds = (Seconds * 24) + st.wHour;
|
||||||
|
Seconds = (Seconds * 60) + st.wMinute;
|
||||||
|
Seconds = (Seconds * 60) + st.wSecond;
|
||||||
|
ASSERT(Seconds <= 0xFFFFFFFF); //NTP Only supports up to 2036
|
||||||
|
m_Time = (Seconds << 32) + MsToNtpFraction(st.wMilliseconds);
|
||||||
|
}
|
||||||
|
|
||||||
|
long CNtpTime::GetJulianDay(WORD Year, WORD Month, WORD Day)
|
||||||
|
{
|
||||||
|
long y = (long) Year;
|
||||||
|
long m = (long) Month;
|
||||||
|
long d = (long) Day;
|
||||||
|
if (m > 2)
|
||||||
|
m = m - 3;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m = m + 9;
|
||||||
|
y = y - 1;
|
||||||
|
}
|
||||||
|
long c = y / 100;
|
||||||
|
long ya = y - 100 * c;
|
||||||
|
long j = (146097L * c) / 4 + (1461L * ya) / 4 + (153L * m + 2) / 5 + d + 1721119L;
|
||||||
|
return j;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CNtpTime::GetGregorianDate(long JD, WORD& Year, WORD& Month, WORD& Day)
|
||||||
|
{
|
||||||
|
long j = JD - 1721119;
|
||||||
|
long y = (4 * j - 1) / 146097;
|
||||||
|
j = 4 * j - 1 - 146097 * y;
|
||||||
|
long d = j / 4;
|
||||||
|
j = (4 * d + 3) / 1461;
|
||||||
|
d = 4 * d + 3 - 1461 * j;
|
||||||
|
d = (d + 4) / 4;
|
||||||
|
long m = (5 * d - 3) / 153;
|
||||||
|
d = 5 * d - 3 - 153 * m;
|
||||||
|
d = (d + 5) / 5;
|
||||||
|
y = 100 * y + j;
|
||||||
|
if (m < 10)
|
||||||
|
m = m + 3;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m = m - 9;
|
||||||
|
y = y + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
Year = (WORD) y;
|
||||||
|
Month = (WORD) m;
|
||||||
|
Day = (WORD) d;
|
||||||
|
}
|
||||||
|
|
||||||
|
CNtpTime& CNtpTime::operator=(const CNtpTime& time)
|
||||||
|
{
|
||||||
|
m_Time = time.m_Time;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
double CNtpTime::operator-(const CNtpTime& time) const
|
||||||
|
{
|
||||||
|
if (m_Time >= time.m_Time)
|
||||||
|
{
|
||||||
|
CNtpTime diff;
|
||||||
|
diff.m_Time = m_Time - time.m_Time;
|
||||||
|
return diff.Seconds() + NtpFractionToSecond(diff.Fraction());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CNtpTime diff;
|
||||||
|
diff.m_Time = time.m_Time - m_Time;
|
||||||
|
return -(diff.Seconds() + NtpFractionToSecond(diff.Fraction()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CNtpTime CNtpTime::operator+(const double& timespan) const
|
||||||
|
{
|
||||||
|
CNtpTime rVal;
|
||||||
|
rVal.m_Time = m_Time;
|
||||||
|
|
||||||
|
if (timespan >= 0)
|
||||||
|
{
|
||||||
|
unsigned __int64 diff = ((unsigned __int64) timespan) << 32;
|
||||||
|
double intpart;
|
||||||
|
double frac = modf(timespan, &intpart);
|
||||||
|
diff += (unsigned __int64) (frac * 0xFFFFFFFF);
|
||||||
|
|
||||||
|
rVal.m_Time += diff;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
double d = -timespan;
|
||||||
|
unsigned __int64 diff = ((unsigned __int64) d) << 32;
|
||||||
|
double intpart;
|
||||||
|
double frac = modf(d, &intpart);
|
||||||
|
diff += (unsigned __int64) (frac * 0xFFFFFFFF);
|
||||||
|
|
||||||
|
rVal.m_Time -= diff;
|
||||||
|
}
|
||||||
|
|
||||||
|
return rVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
CNtpTime::operator SYSTEMTIME() const
|
||||||
|
{
|
||||||
|
//Currently this function only operates correctly in
|
||||||
|
//the 1900 - 2036 primary epoch defined by NTP
|
||||||
|
|
||||||
|
SYSTEMTIME st;
|
||||||
|
DWORD s = Seconds();
|
||||||
|
st.wSecond = (WORD)(s % 60);
|
||||||
|
s /= 60;
|
||||||
|
st.wMinute = (WORD)(s % 60);
|
||||||
|
s /= 60;
|
||||||
|
st.wHour = (WORD)(s % 24);
|
||||||
|
s /= 24;
|
||||||
|
long JD = s + JAN_1ST_1900;
|
||||||
|
st.wDayOfWeek = (WORD)((JD + 1) % 7);
|
||||||
|
GetGregorianDate(JD, st.wYear, st.wMonth, st.wDay);
|
||||||
|
st.wMilliseconds = NtpFractionToMs(Fraction());
|
||||||
|
|
||||||
|
return st;
|
||||||
|
}
|
||||||
|
|
||||||
|
DWORD CNtpTime::Seconds() const
|
||||||
|
{
|
||||||
|
return (DWORD) ((m_Time & 0xFFFFFFFF00000000) >> 32);
|
||||||
|
}
|
||||||
|
|
||||||
|
DWORD CNtpTime::Fraction() const
|
||||||
|
{
|
||||||
|
return (DWORD) (m_Time & 0xFFFFFFFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
CNtpTime::operator CNtpTimePacket() const
|
||||||
|
{
|
||||||
|
CNtpTimePacket ntp;
|
||||||
|
ntp.m_dwInteger = htonl(Seconds());
|
||||||
|
ntp.m_dwFractional = htonl(Fraction());
|
||||||
|
return ntp;
|
||||||
|
}
|
||||||
|
|
||||||
|
CNtpTime CNtpTime::GetCurrentTime()
|
||||||
|
{
|
||||||
|
SYSTEMTIME st;
|
||||||
|
GetSystemTime(&st);
|
||||||
|
CNtpTime t(st);
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
|
||||||
|
DWORD CNtpTime::MsToNtpFraction(WORD wMilliSeconds)
|
||||||
|
{
|
||||||
|
ASSERT(wMilliSeconds < 1000);
|
||||||
|
return m_MsToNTP[wMilliSeconds];
|
||||||
|
}
|
||||||
|
|
||||||
|
WORD CNtpTime::NtpFractionToMs(DWORD dwFraction)
|
||||||
|
{
|
||||||
|
return (WORD)((((double)dwFraction) * NTP_FRACTIONAL_TO_MS) + 0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
double CNtpTime::NtpFractionToSecond(DWORD dwFraction)
|
||||||
|
{
|
||||||
|
double d = (double)dwFraction;
|
||||||
|
d *= NTP_TO_SECOND;
|
||||||
|
return ((double)dwFraction) * NTP_TO_SECOND;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
CNtpSocket::CNtpSocket()
|
||||||
|
{
|
||||||
|
m_hSocket = INVALID_SOCKET; //default to an invalid scoket descriptor
|
||||||
|
}
|
||||||
|
|
||||||
|
CNtpSocket::~CNtpSocket()
|
||||||
|
{
|
||||||
|
Close();
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL CNtpSocket::Create()
|
||||||
|
{
|
||||||
|
//NTP Uses UDP instead of the usual TCP
|
||||||
|
m_hSocket = socket(AF_INET, SOCK_DGRAM, 0);
|
||||||
|
return (m_hSocket != INVALID_SOCKET);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL CNtpSocket::Connect(LPCTSTR pszHostAddress, int nPort)
|
||||||
|
{
|
||||||
|
//For correct operation of the T2A macro, see MFC Tech Note 59
|
||||||
|
USES_CONVERSION;
|
||||||
|
|
||||||
|
//must have been created first
|
||||||
|
ASSERT(m_hSocket != INVALID_SOCKET);
|
||||||
|
|
||||||
|
LPSTR lpszAscii = T2A((LPTSTR)pszHostAddress);
|
||||||
|
|
||||||
|
//Determine if the address is in dotted notation
|
||||||
|
SOCKADDR_IN sockAddr;
|
||||||
|
ZeroMemory(&sockAddr, sizeof(sockAddr));
|
||||||
|
sockAddr.sin_family = AF_INET;
|
||||||
|
sockAddr.sin_port = htons((u_short)nPort);
|
||||||
|
sockAddr.sin_addr.s_addr = inet_addr(lpszAscii);
|
||||||
|
|
||||||
|
//If the address is not dotted notation, then do a DNS
|
||||||
|
//lookup of it.
|
||||||
|
if (sockAddr.sin_addr.s_addr == INADDR_NONE)
|
||||||
|
{
|
||||||
|
LPHOSTENT lphost;
|
||||||
|
lphost = gethostbyname(lpszAscii);
|
||||||
|
if (lphost != NULL)
|
||||||
|
sockAddr.sin_addr.s_addr = ((LPIN_ADDR)lphost->h_addr)->s_addr;
|
||||||
|
else
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Call the protected version which takes an address
|
||||||
|
//in the form of a standard C style struct.
|
||||||
|
return Connect((SOCKADDR*)&sockAddr, sizeof(sockAddr));
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL CNtpSocket::Connect(const SOCKADDR* lpSockAddr, int nSockAddrLen)
|
||||||
|
{
|
||||||
|
int nConnect = connect(m_hSocket, lpSockAddr, nSockAddrLen);
|
||||||
|
return (nConnect == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL CNtpSocket::Send(LPCSTR pszBuf, int nBuf)
|
||||||
|
{
|
||||||
|
//must have been created first
|
||||||
|
ASSERT(m_hSocket != INVALID_SOCKET);
|
||||||
|
|
||||||
|
return (send(m_hSocket, pszBuf, nBuf, 0) != SOCKET_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
|
int CNtpSocket::Receive(LPSTR pszBuf, int nBuf)
|
||||||
|
{
|
||||||
|
//must have been created first
|
||||||
|
ASSERT(m_hSocket != INVALID_SOCKET);
|
||||||
|
|
||||||
|
return recv(m_hSocket, pszBuf, nBuf, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CNtpSocket::Close()
|
||||||
|
{
|
||||||
|
if (m_hSocket != INVALID_SOCKET)
|
||||||
|
{
|
||||||
|
VERIFY(SOCKET_ERROR != closesocket(m_hSocket));
|
||||||
|
m_hSocket = INVALID_SOCKET;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL CNtpSocket::IsReadible(BOOL& bReadible, DWORD dwTimeout)
|
||||||
|
{
|
||||||
|
timeval timeout;
|
||||||
|
timeout.tv_sec = dwTimeout / 1000;
|
||||||
|
timeout.tv_usec = dwTimeout % 1000;
|
||||||
|
fd_set fds;
|
||||||
|
FD_ZERO(&fds);
|
||||||
|
FD_SET(m_hSocket, &fds);
|
||||||
|
int nStatus = select(0, &fds, NULL, NULL, &timeout);
|
||||||
|
if (nStatus == SOCKET_ERROR)
|
||||||
|
return FALSE;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bReadible = !(nStatus == 0);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
CSNTPClient::CSNTPClient()
|
||||||
|
{
|
||||||
|
m_dwTimeout = 5000; //Default timeout of 5 seconds
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL CSNTPClient::GetServerTime(LPCTSTR pszHostName, NtpServerResponse& response, int nPort)
|
||||||
|
{
|
||||||
|
//For correct operation of the T2A macro, see MFC Tech Note 59
|
||||||
|
USES_CONVERSION;
|
||||||
|
|
||||||
|
//paramater validity checking
|
||||||
|
ASSERT(pszHostName);
|
||||||
|
|
||||||
|
//Create the socket, Allocated of the heap so we can control
|
||||||
|
//the time when it's destructor is called. This means that
|
||||||
|
//we can call SetLastError after its destructor
|
||||||
|
CNtpSocket* pSocket = new CNtpSocket();
|
||||||
|
if (!pSocket->Create())
|
||||||
|
{
|
||||||
|
TRACE(_T("Failed to create client socket, GetLastError returns: %d\n"), GetLastError());
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Connect to the SNTP server
|
||||||
|
if (!pSocket->Connect(pszHostName, nPort))
|
||||||
|
{
|
||||||
|
TRACE(_T("Could not connect to the SNTP server %s on port %d, GetLastError returns: %d\n"), pszHostName, nPort, GetLastError());
|
||||||
|
|
||||||
|
//Tidy up prior to returning
|
||||||
|
DWORD dwError = GetLastError();
|
||||||
|
delete pSocket;
|
||||||
|
SetLastError(dwError);
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//Initialise the NtpBasicInfo packet
|
||||||
|
NtpBasicInfo nbi;
|
||||||
|
int nSendSize = sizeof(NtpBasicInfo);
|
||||||
|
ZeroMemory(&nbi, nSendSize);
|
||||||
|
nbi.m_LiVnMode = 27; //Encoded representation which represents NTP Client Request & NTP version 3.0
|
||||||
|
nbi.m_TransmitTimestamp = CNtpTime::GetCurrentTime();
|
||||||
|
|
||||||
|
//Send off the NtpBasicInfo packet
|
||||||
|
if (!pSocket->Send((LPCSTR) &nbi, nSendSize))
|
||||||
|
{
|
||||||
|
TRACE(_T("Failed in call to send NTP request to the SNTP server, GetLastError returns %d\n"), GetLastError());
|
||||||
|
|
||||||
|
//Tidy up prior to returning
|
||||||
|
DWORD dwError = GetLastError();
|
||||||
|
delete pSocket;
|
||||||
|
SetLastError(dwError);
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Need to use select to determine readibilty of socket
|
||||||
|
BOOL bReadable;
|
||||||
|
if (!pSocket->IsReadible(bReadable, m_dwTimeout) || !bReadable)
|
||||||
|
{
|
||||||
|
TRACE(_T("Unable to wait for NTP reply from the SNTP server, GetLastError returns %d\n"), WSAETIMEDOUT);
|
||||||
|
|
||||||
|
//Tidy up prior to returning
|
||||||
|
delete pSocket;
|
||||||
|
SetLastError(WSAETIMEDOUT);
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
response.m_DestinationTime = CNtpTime::GetCurrentTime();
|
||||||
|
|
||||||
|
//read back the response into the NtpFullPacket struct
|
||||||
|
NtpFullPacket nfp;
|
||||||
|
int nReceiveSize = sizeof(NtpFullPacket);
|
||||||
|
ZeroMemory(&nfp, nReceiveSize);
|
||||||
|
if (!pSocket->Receive((LPSTR) &nfp, nReceiveSize))
|
||||||
|
{
|
||||||
|
TRACE(_T("Unable to read reply from the SNTP server, GetLastError returns %d\n"), GetLastError());
|
||||||
|
|
||||||
|
//Tidy up prior to returning
|
||||||
|
DWORD dwError = GetLastError();
|
||||||
|
delete pSocket;
|
||||||
|
SetLastError(dwError);
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Transfer all the useful info into the response structure
|
||||||
|
response.m_nStratum = nfp.m_Basic.m_Stratum;
|
||||||
|
response.m_nLeapIndicator = (nfp.m_Basic.m_LiVnMode & 0xC0) >> 6;
|
||||||
|
response.m_OriginateTime = nfp.m_Basic.m_OriginateTimestamp;
|
||||||
|
response.m_ReceiveTime = nfp.m_Basic.m_ReceiveTimestamp;
|
||||||
|
response.m_TransmitTime = nfp.m_Basic.m_TransmitTimestamp;
|
||||||
|
response.m_RoundTripDelay = (response.m_DestinationTime - response.m_OriginateTime) - (response.m_ReceiveTime - response.m_TransmitTime);
|
||||||
|
response.m_LocalClockOffset = ((response.m_ReceiveTime - response.m_OriginateTime) + (response.m_TransmitTime - response.m_DestinationTime)) / 2;
|
||||||
|
|
||||||
|
//Tidy up prior to returning
|
||||||
|
delete pSocket;
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL CSNTPClient::EnableSetTimePriviledge()
|
||||||
|
{
|
||||||
|
BOOL bOpenToken = OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES |
|
||||||
|
TOKEN_QUERY, &m_hToken);
|
||||||
|
|
||||||
|
m_bTakenPriviledge = FALSE;
|
||||||
|
if (!bOpenToken)
|
||||||
|
{
|
||||||
|
if (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
|
||||||
|
{
|
||||||
|
//Must be running on 95 or 98 not NT. In that case just ignore the error
|
||||||
|
SetLastError(ERROR_SUCCESS);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
TRACE(_T("Failed to get Adjust priviledge token\n"));
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
ZeroMemory(&m_TokenPriv, sizeof(TOKEN_PRIVILEGES));
|
||||||
|
if (!LookupPrivilegeValue(NULL, SE_SYSTEMTIME_NAME, &m_TokenPriv.Privileges[0].Luid))
|
||||||
|
{
|
||||||
|
TRACE(_T("Failed in callup to lookup priviledge\n"));
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
m_TokenPriv.PrivilegeCount = 1;
|
||||||
|
m_TokenPriv.Privileges[0].Attributes |= SE_PRIVILEGE_ENABLED;
|
||||||
|
m_bTakenPriviledge = TRUE;
|
||||||
|
|
||||||
|
BOOL bSuccess = AdjustTokenPrivileges(m_hToken, FALSE, &m_TokenPriv, 0, NULL, 0);
|
||||||
|
if (!bSuccess)
|
||||||
|
TRACE(_T("Failed to adjust SetTime priviledge\n"));
|
||||||
|
|
||||||
|
return bSuccess;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSNTPClient::RevertSetTimePriviledge()
|
||||||
|
{
|
||||||
|
if (m_bTakenPriviledge)
|
||||||
|
{
|
||||||
|
m_TokenPriv.Privileges[0].Attributes &= (~SE_PRIVILEGE_ENABLED);
|
||||||
|
if (!AdjustTokenPrivileges(m_hToken, FALSE, &m_TokenPriv, 0, NULL, 0))
|
||||||
|
TRACE(_T("Failed to reset SetTime priviledge\n"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL CSNTPClient::SetClientTime(const CNtpTime& NewTime)
|
||||||
|
{
|
||||||
|
BOOL bSuccess = FALSE;
|
||||||
|
if (EnableSetTimePriviledge())
|
||||||
|
{
|
||||||
|
SYSTEMTIME st = NewTime;
|
||||||
|
bSuccess = SetSystemTime(&st);
|
||||||
|
if (!bSuccess)
|
||||||
|
TRACE(_T("Failed in call to set the system time\n"));
|
||||||
|
}
|
||||||
|
RevertSetTimePriviledge();
|
||||||
|
|
||||||
|
return bSuccess;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
107
HookMsg/UtilClass/Sntp.h
Normal file
107
HookMsg/UtilClass/Sntp.h
Normal file
@@ -0,0 +1,107 @@
|
|||||||
|
/*
|
||||||
|
Module : SNTP.H
|
||||||
|
Purpose: Interface for a MFC class to encapsulate the SNTP protocol
|
||||||
|
Created: PJN / 05-08-1998
|
||||||
|
History: PJN / None
|
||||||
|
|
||||||
|
|
||||||
|
Copyright (c) 1998 by PJ Naughter.
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __SNTP_H__
|
||||||
|
#define __SNTP_H__
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////// Classes //////////////////////////////
|
||||||
|
|
||||||
|
//Representation of an NTP timestamp
|
||||||
|
struct CNtpTimePacket
|
||||||
|
{
|
||||||
|
DWORD m_dwInteger;
|
||||||
|
DWORD m_dwFractional;
|
||||||
|
};
|
||||||
|
|
||||||
|
//Helper class to encapulate NTP time stamps
|
||||||
|
class CNtpTime
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
//Constructors / Destructors
|
||||||
|
CNtpTime();
|
||||||
|
CNtpTime(const CNtpTime& time);
|
||||||
|
CNtpTime(CNtpTimePacket& packet);
|
||||||
|
CNtpTime(const SYSTEMTIME& st);
|
||||||
|
|
||||||
|
//General functions
|
||||||
|
CNtpTime& operator=(const CNtpTime& time);
|
||||||
|
double operator-(const CNtpTime& time) const;
|
||||||
|
CNtpTime operator+(const double& timespan) const;
|
||||||
|
operator SYSTEMTIME() const;
|
||||||
|
operator CNtpTimePacket() const;
|
||||||
|
operator unsigned __int64() const { return m_Time; };
|
||||||
|
DWORD Seconds() const;
|
||||||
|
DWORD Fraction() const;
|
||||||
|
|
||||||
|
//Static functions
|
||||||
|
static CNtpTime GetCurrentTime();
|
||||||
|
static DWORD MsToNtpFraction(WORD wMilliSeconds);
|
||||||
|
static WORD NtpFractionToMs(DWORD dwFraction);
|
||||||
|
static double NtpFractionToSecond(DWORD dwFraction);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
//Internal static functions and data
|
||||||
|
static long GetJulianDay(WORD Year, WORD Month, WORD Day);
|
||||||
|
static void GetGregorianDate(long JD, WORD& Year, WORD& Month, WORD& Day);
|
||||||
|
static DWORD m_MsToNTP[1000];
|
||||||
|
|
||||||
|
//The actual data
|
||||||
|
unsigned __int64 m_Time;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct NtpServerResponse
|
||||||
|
{
|
||||||
|
int m_nLeapIndicator; //0: no warning
|
||||||
|
//1: last minute in day has 61 seconds
|
||||||
|
//2: last minute has 59 seconds
|
||||||
|
//3: clock not synchronized
|
||||||
|
|
||||||
|
int m_nStratum; //0: unspecified or unavailable
|
||||||
|
//1: primary reference (e.g., radio clock)
|
||||||
|
//2-15: secondary reference (via NTP or SNTP)
|
||||||
|
//16-255: reserved
|
||||||
|
|
||||||
|
CNtpTime m_OriginateTime; //Time when the request was sent from the client to the SNTP server
|
||||||
|
CNtpTime m_ReceiveTime; //Time when the request was received by the server
|
||||||
|
CNtpTime m_TransmitTime; //Time when the server sent the request back to the client
|
||||||
|
CNtpTime m_DestinationTime; //Time when the reply was received by the client
|
||||||
|
double m_RoundTripDelay; //Round trip time in seconds
|
||||||
|
double m_LocalClockOffset; //Local clock offset relative to the server
|
||||||
|
};
|
||||||
|
|
||||||
|
//The actual SNTP class
|
||||||
|
class CSNTPClient : public CObject
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
//Constructors / Destructors
|
||||||
|
CSNTPClient();
|
||||||
|
|
||||||
|
//General functions
|
||||||
|
BOOL GetServerTime(LPCTSTR pszHostName, NtpServerResponse& response, int nPort = 123);
|
||||||
|
DWORD GetTimeout() const { return m_dwTimeout; };
|
||||||
|
void SetTimeout(DWORD dwTimeout) { m_dwTimeout = dwTimeout; };
|
||||||
|
BOOL SetClientTime(const CNtpTime& NewTime);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
BOOL EnableSetTimePriviledge();
|
||||||
|
void RevertSetTimePriviledge();
|
||||||
|
|
||||||
|
DWORD m_dwTimeout;
|
||||||
|
HANDLE m_hToken;
|
||||||
|
TOKEN_PRIVILEGES m_TokenPriv;
|
||||||
|
BOOL m_bTakenPriviledge;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif //__SNTP_H__
|
||||||
122
HookMsg/UtilClass/ThinThread.cpp
Normal file
122
HookMsg/UtilClass/ThinThread.cpp
Normal file
@@ -0,0 +1,122 @@
|
|||||||
|
// ThinThread.cpp : implementation file
|
||||||
|
// Copyright (C) 1997 by The Windward Group, All Rights Reserved
|
||||||
|
|
||||||
|
#include "stdafx.h"
|
||||||
|
#include "ThinThread.h"
|
||||||
|
#include <process.h> /* _beginthread, _endthread */
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
// ThinThread
|
||||||
|
CThinThread::CThinThread()
|
||||||
|
: m_b2ndThread(FALSE)
|
||||||
|
{
|
||||||
|
// Create a signaled, manual-reset event to synchronize destruction
|
||||||
|
m_pExitEvent = new CEvent();//TRUE, TRUE);
|
||||||
|
ASSERT(m_pExitEvent);
|
||||||
|
|
||||||
|
// Create a non-signaled, auto-reset event to wait on for work cycle
|
||||||
|
m_pWorkEvent = new CEvent();
|
||||||
|
ASSERT(m_pWorkEvent);
|
||||||
|
m_pWorkEvent2 = new CEvent();
|
||||||
|
ASSERT(m_pWorkEvent2);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL CThinThread::CreateThread(DWORD dwCreateFlags,
|
||||||
|
UINT nStackSize,
|
||||||
|
LPSECURITY_ATTRIBUTES lpSecurityAttrs,
|
||||||
|
UINT nMilliSecs,
|
||||||
|
UINT Type)
|
||||||
|
{
|
||||||
|
m_bEndThread = FALSE;
|
||||||
|
m_nCycleTime = nMilliSecs;
|
||||||
|
m_pExitEvent->ResetEvent(); // exit event is reset until we're done
|
||||||
|
|
||||||
|
// Start second thread
|
||||||
|
ULONG usThreadAddr;
|
||||||
|
// m_hThread2 = reinterpret_cast<HANDLE> (_beginthreadex(lpSecurityAttrs, nStackSize, Start, this, 1, &usThreadAddr));
|
||||||
|
// return reinterpret_cast<unsigned long> (m_hThread2);
|
||||||
|
if(WORD_THREAD_WITH_HOGA == Type) {
|
||||||
|
m_b2ndThread = TRUE;
|
||||||
|
m_hThread2 = ::CreateThread(lpSecurityAttrs,nStackSize,Start,this,0,&usThreadAddr);
|
||||||
|
} else {
|
||||||
|
m_b3rdThread = TRUE;
|
||||||
|
m_hThread3 = ::CreateThread(lpSecurityAttrs,nStackSize,Start2,this,0,&usThreadAddr);
|
||||||
|
}
|
||||||
|
return reinterpret_cast<unsigned long> (m_hThread2);
|
||||||
|
}
|
||||||
|
|
||||||
|
CThinThread::~CThinThread()
|
||||||
|
{
|
||||||
|
delete m_pWorkEvent; m_pWorkEvent = NULL;
|
||||||
|
delete m_pWorkEvent2; m_pWorkEvent2 = NULL;
|
||||||
|
delete m_pExitEvent; m_pExitEvent = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CThinThread::KillThread2()
|
||||||
|
{
|
||||||
|
// Start up the other thread so it can complete.
|
||||||
|
// When it does, it will set the exit event and the object can be destructed.
|
||||||
|
m_bEndThread = TRUE;
|
||||||
|
m_pWorkEvent->SetEvent();
|
||||||
|
m_pWorkEvent2->SetEvent();
|
||||||
|
|
||||||
|
Sleep(0);
|
||||||
|
|
||||||
|
CSingleLock csl(m_pExitEvent);
|
||||||
|
csl.Lock(); // wait for 2nd thread to finish
|
||||||
|
csl.Unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CThinThread::Finalize()
|
||||||
|
{
|
||||||
|
KillThread2();
|
||||||
|
}
|
||||||
|
|
||||||
|
int CThinThread::Run(UINT ThreadType)
|
||||||
|
{
|
||||||
|
CSingleLock *pcsl;
|
||||||
|
if(WORD_THREAD_WITH_HOGA == ThreadType)
|
||||||
|
pcsl = new CSingleLock(m_pWorkEvent); // synch on the work event
|
||||||
|
else if(WORD_THREAD_WITHOUT_HOGA == ThreadType)
|
||||||
|
pcsl = new CSingleLock(m_pWorkEvent2); // synch on the work event2
|
||||||
|
else
|
||||||
|
ASSERT(FALSE);
|
||||||
|
|
||||||
|
StartWork(); // do derived startup
|
||||||
|
|
||||||
|
while (!m_bEndThread) // loop until we're done
|
||||||
|
{
|
||||||
|
pcsl->Lock(m_nCycleTime); // wait for event or timeout
|
||||||
|
pcsl->Unlock();
|
||||||
|
if (!m_bEndThread)
|
||||||
|
DoWork(ThreadType); // then do derived work
|
||||||
|
}
|
||||||
|
|
||||||
|
m_pExitEvent->SetEvent(); // set not waiting signal
|
||||||
|
|
||||||
|
if(WORD_THREAD_WITH_HOGA == ThreadType)
|
||||||
|
m_b2ndThread = FALSE;
|
||||||
|
else
|
||||||
|
m_b3rdThread = FALSE;
|
||||||
|
|
||||||
|
delete pcsl;
|
||||||
|
EndWork(); // do derived shutdown
|
||||||
|
|
||||||
|
// _endthreadex(0);
|
||||||
|
// ExitThread(0);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//unsigned int __stdcall CThinThread::Start(void* pv)
|
||||||
|
DWORD WINAPI CThinThread::Start(LPVOID pv)
|
||||||
|
{
|
||||||
|
CThinThread* pMT = static_cast<CThinThread*> (pv);
|
||||||
|
return pMT->Run(WORD_THREAD_WITH_HOGA);
|
||||||
|
}
|
||||||
|
|
||||||
|
DWORD WINAPI CThinThread::Start2(LPVOID pv)
|
||||||
|
{
|
||||||
|
CThinThread* pMT = static_cast<CThinThread*> (pv);
|
||||||
|
return pMT->Run(WORD_THREAD_WITHOUT_HOGA);
|
||||||
|
}
|
||||||
60
HookMsg/UtilClass/ThinThread.h
Normal file
60
HookMsg/UtilClass/ThinThread.h
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
// ThinThread.h : header file
|
||||||
|
// Copyright (C) 1997 by The Windward Group, All Rights Reserved
|
||||||
|
|
||||||
|
#ifndef THINTHREAD_H
|
||||||
|
#define THINTHREAD_H
|
||||||
|
|
||||||
|
#ifndef __AFXWIN_H__
|
||||||
|
#error include 'stdafx.h' before including this file for PCH
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <afxmt.h>
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
class CThinThread
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CThinThread();
|
||||||
|
virtual ~CThinThread();
|
||||||
|
|
||||||
|
BOOL CreateThread(DWORD dwCreateFlags = 0,
|
||||||
|
UINT nStackSize = 0,
|
||||||
|
LPSECURITY_ATTRIBUTES lpSecurityAttrs = NULL,
|
||||||
|
UINT nMilliSecs = INFINITE, // upper time limit to wait
|
||||||
|
UINT Type = 0);
|
||||||
|
|
||||||
|
HANDLE GetHandle() {return m_hThread2;}
|
||||||
|
BOOL IsBusy() {return m_b2ndThread;}
|
||||||
|
void Stop() {m_bEndThread = TRUE;}
|
||||||
|
|
||||||
|
void Finalize();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
int m_nCycleTime; // do work cycle time
|
||||||
|
|
||||||
|
CEvent* m_pWorkEvent; // do work event
|
||||||
|
CEvent* m_pExitEvent; // used to synchronize destruction
|
||||||
|
BOOL m_bEndThread; // end the thread ?
|
||||||
|
BOOL m_b2ndThread; // 2nd thread active?
|
||||||
|
|
||||||
|
CEvent* m_pWorkEvent2; // do work event
|
||||||
|
HANDLE m_hThread2; // 2nd thread handle
|
||||||
|
BOOL m_b3rdThread; // 3rd thread active?
|
||||||
|
HANDLE m_hThread3; // 3rd thread handle
|
||||||
|
|
||||||
|
virtual void StartWork() {} // override to do startup
|
||||||
|
virtual void DoWork(UINT ThreadType) {}; // override to do work
|
||||||
|
virtual void EndWork() {} // override to do shutdown
|
||||||
|
|
||||||
|
CEvent* GetEvent() const {return m_pWorkEvent;} // cycle control event
|
||||||
|
int GetCycleTime() const {return m_nCycleTime;}
|
||||||
|
void KillThread2();
|
||||||
|
int Run(UINT ThreadType);
|
||||||
|
void SetCycleTime(int nMilliSecs) {m_nCycleTime = nMilliSecs;}
|
||||||
|
|
||||||
|
// static unsigned int __stdcall Start(void* pv);
|
||||||
|
static DWORD WINAPI Start(LPVOID pv);
|
||||||
|
static DWORD WINAPI Start2(LPVOID pv);
|
||||||
|
|
||||||
|
};
|
||||||
|
#endif
|
||||||
244
HookMsg/UtilClass/Thread.h
Normal file
244
HookMsg/UtilClass/Thread.h
Normal file
@@ -0,0 +1,244 @@
|
|||||||
|
#ifndef __THREAD_H__
|
||||||
|
#define __THREAD_H__
|
||||||
|
|
||||||
|
class CThread
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/*
|
||||||
|
* Info: Default Constructor
|
||||||
|
*/
|
||||||
|
CThread()
|
||||||
|
{
|
||||||
|
m_pThreadFunc = CThread::EntryPoint; // Can call Detach() also.
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Info: Plug Constructor
|
||||||
|
*
|
||||||
|
* Use this to migrate/port existing worker threads to objects immediately
|
||||||
|
* Although you lose the benefits of ThreadCTOR and ThreadDTOR.
|
||||||
|
*/
|
||||||
|
CThread(LPTHREAD_START_ROUTINE lpExternalRoutine)
|
||||||
|
{
|
||||||
|
Thread_Attach(lpExternalRoutine);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Info: Default Destructor
|
||||||
|
*
|
||||||
|
* I think it is wise to destroy the thread even if it is running,
|
||||||
|
* when the main thread reaches here.
|
||||||
|
*/
|
||||||
|
~CThread()
|
||||||
|
{
|
||||||
|
if ( m_ThreadCtx.m_hThread )
|
||||||
|
Thread_Stop(true);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Info: Starts the thread.
|
||||||
|
*
|
||||||
|
* This function starts the thread pointed by m_pThreadFunc with default attributes
|
||||||
|
*/
|
||||||
|
DWORD Thread_Start( void* arg = NULL )
|
||||||
|
{
|
||||||
|
m_ThreadCtx.m_bThreadRun = TRUE;
|
||||||
|
|
||||||
|
m_ThreadCtx.m_pUserData = arg;
|
||||||
|
m_ThreadCtx.m_hThread = CreateThread(NULL, 0, m_pThreadFunc, this, 0, &m_ThreadCtx.m_dwTID);
|
||||||
|
m_ThreadCtx.m_dwExitCode = (DWORD)-1;
|
||||||
|
|
||||||
|
return GetLastError();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Info: Stops the thread.
|
||||||
|
*
|
||||||
|
* This function stops the current thread.
|
||||||
|
* We can force kill a thread which results in a TerminateThread.
|
||||||
|
*/
|
||||||
|
DWORD Thread_Stop ( bool bForceKill = false )
|
||||||
|
{
|
||||||
|
m_ThreadCtx.m_bThreadRun = FALSE;
|
||||||
|
|
||||||
|
if ( m_ThreadCtx.m_hThread )
|
||||||
|
{
|
||||||
|
if(::WaitForSingleObject(m_ThreadCtx.m_hThread,0) == WAIT_OBJECT_0)
|
||||||
|
{
|
||||||
|
// the thread is done running.
|
||||||
|
GetExitCodeThread(m_ThreadCtx.m_hThread, &m_ThreadCtx.m_dwExitCode);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// the thread is still running.
|
||||||
|
if(::WaitForSingleObject(m_ThreadCtx.m_hCloseEvent,INFINITE) == WAIT_OBJECT_0)
|
||||||
|
{
|
||||||
|
GetExitCodeThread(m_ThreadCtx.m_hThread, &m_ThreadCtx.m_dwExitCode);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// smooth close failed.
|
||||||
|
GetExitCodeThread(m_ThreadCtx.m_hThread, &m_ThreadCtx.m_dwExitCode);
|
||||||
|
if ( m_ThreadCtx.m_dwExitCode == STILL_ACTIVE && bForceKill )
|
||||||
|
TerminateThread(m_ThreadCtx.m_hThread, DWORD(-1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_ThreadCtx.m_hThread = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return m_ThreadCtx.m_dwExitCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
DWORD Thread_Suspend()
|
||||||
|
{
|
||||||
|
return ::SuspendThread(m_ThreadCtx.m_hThread);
|
||||||
|
}
|
||||||
|
|
||||||
|
DWORD Thread_Resume()
|
||||||
|
{
|
||||||
|
return ::ResumeThread(m_ThreadCtx.m_hThread);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL Thread_SetPriority( int nPriority=THREAD_PRIORITY_NORMAL )
|
||||||
|
{
|
||||||
|
return ::SetThreadPriority(m_ThreadCtx.m_hThread, nPriority );
|
||||||
|
}
|
||||||
|
|
||||||
|
int Thread_GetPriority()
|
||||||
|
{
|
||||||
|
return ::GetThreadPriority(m_ThreadCtx.m_hThread);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Info: Starts the thread.
|
||||||
|
*
|
||||||
|
* This function starts the thread pointed by m_pThreadFunc with default attributes
|
||||||
|
*/
|
||||||
|
DWORD Thread_GetExitCode() const
|
||||||
|
{
|
||||||
|
if ( m_ThreadCtx.m_hThread )
|
||||||
|
GetExitCodeThread(m_ThreadCtx.m_hThread, (LPDWORD)&m_ThreadCtx.m_dwExitCode);
|
||||||
|
return m_ThreadCtx.m_dwExitCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Info: Attaches a Thread Function
|
||||||
|
*
|
||||||
|
* Used primarily for porting but can serve in developing generic thread objects
|
||||||
|
*/
|
||||||
|
void Thread_Attach( LPTHREAD_START_ROUTINE lpThreadFunc ){
|
||||||
|
m_pThreadFunc = lpThreadFunc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Info: Detaches the Attached Thread Function
|
||||||
|
*
|
||||||
|
* Detaches the Attached Thread Function, If any.
|
||||||
|
* by resetting the thread function pointer to EntryPoint1
|
||||||
|
*/
|
||||||
|
void Thread_Detach( void ){
|
||||||
|
m_pThreadFunc = CThread::EntryPoint;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Info: DONT override this method.
|
||||||
|
*
|
||||||
|
* This function is like a standard template.
|
||||||
|
* Override if you are sure of what you are doing.
|
||||||
|
*/
|
||||||
|
static DWORD WINAPI EntryPoint( LPVOID pArg )
|
||||||
|
{
|
||||||
|
CThread *pParent = reinterpret_cast<CThread*>(pArg);
|
||||||
|
|
||||||
|
pParent->ThreadCtor();
|
||||||
|
|
||||||
|
pParent->Run( pParent->m_ThreadCtx.m_pUserData );
|
||||||
|
|
||||||
|
pParent->ThreadDtor();
|
||||||
|
|
||||||
|
return STILL_ACTIVE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Info: Override this method.
|
||||||
|
*
|
||||||
|
* This function should contain the body/code of your thread.
|
||||||
|
* Notice the signature is similar to that of any worker thread function
|
||||||
|
* except for the calling convention.
|
||||||
|
*/
|
||||||
|
virtual DWORD Run( LPVOID /* arg */ )
|
||||||
|
{ return m_ThreadCtx.m_dwExitCode; }
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Info: Constructor-like function.
|
||||||
|
*
|
||||||
|
* Will be called by EntryPoint before executing the thread body.
|
||||||
|
* Override this function to provide your extra initialization.
|
||||||
|
*
|
||||||
|
* NOTE: do not confuse it with the classes constructor
|
||||||
|
*/
|
||||||
|
virtual void ThreadCtor(){ TRACE("constructor...\n"); }
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Info: Destructor-like function.
|
||||||
|
*
|
||||||
|
* Will be called by EntryPoint after executing the thread body.
|
||||||
|
* Override this function to provide your extra destruction.
|
||||||
|
*
|
||||||
|
* NOTE: do not confuse it with the classes constructor
|
||||||
|
*/
|
||||||
|
virtual void ThreadDtor(){ TRACE("destructor...\n"); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
/*
|
||||||
|
* Info: Thread Context Inner Class
|
||||||
|
*
|
||||||
|
* Every thread object needs to be associated with a set of values.
|
||||||
|
* like UserData Pointer, Handle, Thread ID etc.
|
||||||
|
*
|
||||||
|
* NOTE: This class can be enhanced to varying functionalities
|
||||||
|
* eg.,
|
||||||
|
* * Members to hold StackSize
|
||||||
|
* * SECURITY_ATTRIBUTES member.
|
||||||
|
*/
|
||||||
|
class CThreadContext
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CThreadContext(){
|
||||||
|
memset(this, 0, sizeof(this));
|
||||||
|
m_hCloseEvent = ::CreateEvent( NULL, FALSE, FALSE, NULL );
|
||||||
|
m_bThreadRun = FALSE;
|
||||||
|
}
|
||||||
|
~CThreadContext(){
|
||||||
|
::CloseHandle( m_hCloseEvent );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Attributes Section
|
||||||
|
*/
|
||||||
|
public:
|
||||||
|
HANDLE m_hThread; // The Thread Handle
|
||||||
|
DWORD m_dwTID; // The Thread ID
|
||||||
|
LPVOID m_pUserData; // The user data pointer
|
||||||
|
LPVOID m_pParent; // The this pointer of the parent CThread object
|
||||||
|
DWORD m_dwExitCode; // The Exit Code of the thread
|
||||||
|
HANDLE m_hCloseEvent; // Thread close check event.
|
||||||
|
BOOL m_bThreadRun; // Thread exit condition.
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Attributes Section
|
||||||
|
*/
|
||||||
|
public:
|
||||||
|
/*
|
||||||
|
* Info: Members of CThread
|
||||||
|
*/
|
||||||
|
CThreadContext m_ThreadCtx; // The Thread Context member
|
||||||
|
protected:
|
||||||
|
LPTHREAD_START_ROUTINE m_pThreadFunc; // The Worker Thread Function Pointer
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif //__THREAD_H__
|
||||||
160
HookMsg/UtilClass/TrayIcon.cpp
Normal file
160
HookMsg/UtilClass/TrayIcon.cpp
Normal file
@@ -0,0 +1,160 @@
|
|||||||
|
// TrayIcon.cpp: implementation of the CTrayIcon class.
|
||||||
|
//
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#include "stdafx.h"
|
||||||
|
#include "./../HookMsg.h"
|
||||||
|
#include "TrayIcon.h"
|
||||||
|
|
||||||
|
#ifdef _DEBUG
|
||||||
|
#undef THIS_FILE
|
||||||
|
static char THIS_FILE[]=__FILE__;
|
||||||
|
#define new DEBUG_NEW
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// Construction/Destruction
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
CTrayIcon::CTrayIcon()
|
||||||
|
{
|
||||||
|
memset(&m_tnd, 0, sizeof(m_tnd));
|
||||||
|
}
|
||||||
|
|
||||||
|
CTrayIcon::CTrayIcon(CWnd* pWnd, UINT uCallbackMessage, LPCTSTR szToolTip,
|
||||||
|
HICON icon, UINT uID)
|
||||||
|
{
|
||||||
|
Create(pWnd, uCallbackMessage, szToolTip, icon, uID);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL CTrayIcon::Create(CWnd* pWnd, UINT uCallbackMessage, LPCTSTR szToolTip,
|
||||||
|
HICON icon, UINT uID)
|
||||||
|
{
|
||||||
|
//Make sure we avoid conflict with other messages
|
||||||
|
ASSERT(uCallbackMessage >= WM_USER);
|
||||||
|
|
||||||
|
//Tray only supports tooltip text up to 64 characters
|
||||||
|
ASSERT(_tcslen(szToolTip) <= 64);
|
||||||
|
|
||||||
|
// NOTIFYICONDATA 구조체의 값 설정
|
||||||
|
m_tnd.cbSize = sizeof(NOTIFYICONDATA);
|
||||||
|
m_tnd.hWnd = pWnd->GetSafeHwnd();
|
||||||
|
m_tnd.uID = uID;
|
||||||
|
m_tnd.hIcon = icon;
|
||||||
|
m_tnd.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP;
|
||||||
|
m_tnd.uCallbackMessage = uCallbackMessage;
|
||||||
|
strcpy (m_tnd.szTip, szToolTip);
|
||||||
|
|
||||||
|
// 트레이 아이콘 추가
|
||||||
|
return Shell_NotifyIcon(NIM_ADD, &m_tnd);
|
||||||
|
}
|
||||||
|
|
||||||
|
CTrayIcon::~CTrayIcon()
|
||||||
|
{
|
||||||
|
RemoveIcon();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
// CTrayIcon icon manipulation
|
||||||
|
|
||||||
|
void CTrayIcon::RemoveIcon()
|
||||||
|
{
|
||||||
|
m_tnd.uFlags = 0;
|
||||||
|
Shell_NotifyIcon(NIM_DELETE, &m_tnd);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BOOL CTrayIcon::SetIcon(HICON hIcon)
|
||||||
|
{
|
||||||
|
m_tnd.uFlags = NIF_ICON;
|
||||||
|
m_tnd.hIcon = hIcon;
|
||||||
|
|
||||||
|
return Shell_NotifyIcon(NIM_MODIFY, &m_tnd);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL CTrayIcon::SetIcon(LPCTSTR lpszIconName)
|
||||||
|
{
|
||||||
|
HICON hIcon = AfxGetApp()->LoadIcon(lpszIconName);
|
||||||
|
|
||||||
|
return SetIcon(hIcon);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL CTrayIcon::SetIcon(UINT nIDResource)
|
||||||
|
{
|
||||||
|
HICON hIcon = AfxGetApp()->LoadIcon(nIDResource);
|
||||||
|
|
||||||
|
return SetIcon(hIcon);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL CTrayIcon::SetStandardIcon(LPCTSTR lpIconName)
|
||||||
|
{
|
||||||
|
HICON hIcon = LoadIcon(NULL, lpIconName);
|
||||||
|
|
||||||
|
return SetIcon(hIcon);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL CTrayIcon::SetStandardIcon(UINT nIDResource)
|
||||||
|
{
|
||||||
|
HICON hIcon = LoadIcon(NULL, MAKEINTRESOURCE(nIDResource));
|
||||||
|
|
||||||
|
return SetIcon(hIcon);
|
||||||
|
}
|
||||||
|
|
||||||
|
HICON CTrayIcon::GetIcon() const
|
||||||
|
{
|
||||||
|
HICON hIcon = NULL;
|
||||||
|
hIcon = m_tnd.hIcon;
|
||||||
|
|
||||||
|
return hIcon;
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
// CTrayIcon tooltip text manipulation
|
||||||
|
|
||||||
|
BOOL CTrayIcon::SetTooltipText(LPCTSTR pszTip)
|
||||||
|
{
|
||||||
|
m_tnd.uFlags = NIF_TIP;
|
||||||
|
_tcscpy(m_tnd.szTip, pszTip);
|
||||||
|
|
||||||
|
return Shell_NotifyIcon(NIM_MODIFY, &m_tnd);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL CTrayIcon::SetTooltipText(UINT nID)
|
||||||
|
{
|
||||||
|
CString strText;
|
||||||
|
VERIFY(strText.LoadString(nID));
|
||||||
|
|
||||||
|
return SetTooltipText(strText);
|
||||||
|
}
|
||||||
|
|
||||||
|
CString CTrayIcon::GetTooltipText() const
|
||||||
|
{
|
||||||
|
CString strText;
|
||||||
|
strText = m_tnd.szTip;
|
||||||
|
|
||||||
|
return strText;
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
// CTrayIcon notification window stuff
|
||||||
|
|
||||||
|
BOOL CTrayIcon::SetNotificationWnd(CWnd* pWnd)
|
||||||
|
{
|
||||||
|
//Make sure Notification window is valid
|
||||||
|
ASSERT(pWnd && ::IsWindow(pWnd->GetSafeHwnd()));
|
||||||
|
|
||||||
|
m_tnd.hWnd = pWnd->GetSafeHwnd();
|
||||||
|
m_tnd.uFlags = 0;
|
||||||
|
|
||||||
|
return Shell_NotifyIcon(NIM_MODIFY, &m_tnd);
|
||||||
|
}
|
||||||
|
|
||||||
|
CWnd* CTrayIcon::GetNotificationWnd() const
|
||||||
|
{
|
||||||
|
return CWnd::FromHandle(m_tnd.hWnd);
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
// CTrayIcon implentation of OnTrayNotification
|
||||||
|
|
||||||
47
HookMsg/UtilClass/TrayIcon.h
Normal file
47
HookMsg/UtilClass/TrayIcon.h
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
// TrayIcon.h: interface for the CTrayIcon class.
|
||||||
|
//
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#if !defined(AFX_TRAYICON_H__776BD1A9_F764_11D1_994B_444553540000__INCLUDED_)
|
||||||
|
#define AFX_TRAYICON_H__776BD1A9_F764_11D1_994B_444553540000__INCLUDED_
|
||||||
|
|
||||||
|
#if _MSC_VER >= 1000
|
||||||
|
#pragma once
|
||||||
|
#endif // _MSC_VER >= 1000
|
||||||
|
|
||||||
|
class CTrayIcon
|
||||||
|
{
|
||||||
|
// Construction/destruction
|
||||||
|
public:
|
||||||
|
CTrayIcon();
|
||||||
|
CTrayIcon(CWnd* pWnd, UINT uCallbackMessage, LPCTSTR szTip, HICON icon, UINT uID);
|
||||||
|
virtual ~CTrayIcon();
|
||||||
|
|
||||||
|
//Create the tray icon
|
||||||
|
BOOL Create(CWnd* pWnd, UINT uCallbackMessage, LPCTSTR szTip, HICON icon, UINT uID);
|
||||||
|
|
||||||
|
//Change or retrieve the Tooltip text
|
||||||
|
BOOL SetTooltipText(LPCTSTR pszTooltipText);
|
||||||
|
BOOL SetTooltipText(UINT nID);
|
||||||
|
CString GetTooltipText() const;
|
||||||
|
|
||||||
|
//Change or retrieve the icon displayed
|
||||||
|
BOOL SetIcon(HICON hIcon);
|
||||||
|
BOOL SetIcon(LPCTSTR lpIconName);
|
||||||
|
BOOL SetIcon(UINT nIDResource);
|
||||||
|
BOOL SetStandardIcon(LPCTSTR lpIconName);
|
||||||
|
BOOL SetStandardIcon(UINT nIDResource);
|
||||||
|
HICON GetIcon() const;
|
||||||
|
void RemoveIcon();
|
||||||
|
|
||||||
|
//Change or retrieve the window to send notification messages to
|
||||||
|
BOOL SetNotificationWnd(CWnd* pNotifyWnd);
|
||||||
|
CWnd* GetNotificationWnd() const;
|
||||||
|
|
||||||
|
// Implementation
|
||||||
|
protected:
|
||||||
|
NOTIFYICONDATA m_tnd;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif // !defined(AFX_TRAYICON_H__776BD1A9_F764_11D1_994B_444553540000__INCLUDED_)
|
||||||
Reference in New Issue
Block a user