www.pudn.com > ntp.zip > ntp.cpp


// ntp.cpp : Defines the entry point for the console application. 
// 
 
#include "stdafx.h" 
 
#include  
#include "ntp.h" 
 
#define TIME_OUT 5000 
#define LogFile "ntp.log" 
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; 
char str[256]; 
char str1[256]; 
#define CONFIGFILE "ntp.cfg" 
void LogToFile(LPCSTR str); 
 
//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;//Leap indicator(2),version(3),mode(3) 
  BYTE m_Stratum;//stratum  
  char m_Poll;//poll interval 
  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 Full NTP packet 
struct NtpFullPacket 
{ 
  NtpBasicInfo          m_Basic; 
}; 
 
 
 
 
///////////////////////////////// Implementation ////////////////////////////// 
 
//constructor of CNtpTime 
CNtpTime::CNtpTime() 
{ 
  m_Time = 0; 
} 
 
//constructor of CNtpTime 
CNtpTime::CNtpTime(const CNtpTime& time) 
{ 
  *this = time; 
} 
 
//constructor  
//set seconds and fraction to 64 bits int from ntp packet 
// 
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; 
} 
 
//constructor of CNtpTime 
//convert system time to seconds 
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); 
} 
// 
// Calculate Julian Day from UTC 
// 
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; 
} 
// 
// Calculate Gregorian Date from Julian Day 
// 
void CNtpTime::GetGregorianDate(long JD, WORD& Year, WORD& Month, WORD& Day) 
{ 
  long j = JD - 1721119;		//Number of days from 4712 B.C. 
  long y = (4 * j - 1) / 146097;//Number of century  
  j = 4 * j - 1 - 146097 * y;	//Nuber of days*4 in this century 
  long d = j / 4;				//Nnmber of days in this century 
  j = (4 * d + 3) / 1461;		//Nuber of years in this century 
  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;				//Date of today 
  y = 100 * y + j;				 
  if (m < 10)  
    m = m + 3; 
  else  
  { 
    m = m - 9; 
    y = y + 1; 
  } 
 
  Year = (WORD) y;				//This year 
  Month = (WORD) m;				//This month 
  Day = (WORD) d;				//Today 
} 
//Set time to new object 
CNtpTime& CNtpTime::operator=(const CNtpTime& time) 
{ 
  m_Time = time.m_Time; 
  return *this; 
} 
//Define minus operator of CNtpTime 
// 
double CNtpTime::operator-(const CNtpTime& time) const 
{ 
  if (m_Time >= time.m_Time) 
	{//timespan is positive 
    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())); 
	} 
} 
//Define plus operator of CNtpTime 
// 
CNtpTime CNtpTime::operator+(const double& timespan) const 
{ 
  CNtpTime rVal; 
	rVal.m_Time = m_Time; 
 
 
if (timespan >= 0) 
	{ 
	//timespan is positive 
	  unsigned __int64 diff = ((unsigned __int64) timespan) << 32;//get integer whitch shift left 32 
      double intpart; 
	  double frac = modf(timespan, &intpart);//get fraction 
	  diff += (unsigned __int64) (frac * 0xFFFFFFFF);//*-1 
 
		rVal.m_Time += diff;//modify time 
	} 
	else 
	{//if timespan is negative 
      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; 
} 
 
//Change total seconds to year/month/day/hour/minute/second/ms 
CNtpTime::operator SYSTEMTIME() const 
{ 
  //Currently this function only operates correctly in  
  //the 1900 - 2036 primary epoch defined by NTP 
 
  SYSTEMTIME st; 
  DWORD s = Seconds();//get seconds from ntp 
  st.wSecond = (WORD)(s % 60);//second 
  s /= 60; 
  st.wMinute = (WORD)(s % 60);//minute 
  s /= 60; 
  st.wHour = (WORD)(s % 24);//hour 
  s /= 24;//day 
  long JD = s + JAN_1ST_1900;//Julian day 
  st.wDayOfWeek = (WORD)((JD + 1) % 7);//day of week 
  GetGregorianDate(JD, st.wYear, st.wMonth, st.wDay);//to Greorian date 
  st.wMilliseconds = NtpFractionToMs(Fraction());//to MS 
 
  return st; 
} 
 
//Get total seconds from NTP format 
DWORD CNtpTime::Seconds() const 
{ 
  return (DWORD) ((m_Time & 0xFFFFFFFF00000000) >> 32); 
} 
 
//Get fraction from NTP format 
DWORD CNtpTime::Fraction() const 
{ 
  return (DWORD) (m_Time & 0xFFFFFFFF); 
} 
 
//Set time to ntp packet 
CNtpTime::operator CNtpTimePacket() const 
{ 
  CNtpTimePacket ntp; 
  ntp.m_dwInteger = htonl(Seconds()); 
  ntp.m_dwFractional = htonl(Fraction()); 
	return ntp; 
} 
 
//Get local time 
CNtpTime CNtpTime::GetCurrentTime() 
{ 
  SYSTEMTIME st; 
  GetSystemTime(&st); 
	CNtpTime t(st); 
  return t; 
} 
 
// 
// Fraction to MilliSeconds 
// 
DWORD CNtpTime::MsToNtpFraction(WORD wMilliSeconds) 
{ 
  ASSERT(wMilliSeconds < 1000); 
 
//  unsigned __int64 second; 
//	second=wMilliSeconds; 
//	second=(second<<32)/1000; 
	//more fast then above  
	return m_MsToNTP[wMilliSeconds]; 
} 
 
// 
// MilliSeconds to Fraction 
// 
WORD CNtpTime::NtpFractionToMs(DWORD dwFraction) 
{ 
//unsigned __int64 s; 
//	s=dwFraction; 
//	s=(s*1000); 
//	s=s>>32; 
	//more fast then above 
	return (WORD)((((double)dwFraction) * NTP_FRACTIONAL_TO_MS) + 0.5); 
} 
 
// 
// Fraction to Seconds 
// 
double CNtpTime::NtpFractionToSecond(DWORD dwFraction) 
{ 
  double d = (double)dwFraction; 
	d *= NTP_TO_SECOND; 
	return ((double)dwFraction) * NTP_TO_SECOND; 
} 
 
//  
// set timeout to 5 seconds when receive packet from time server 
// 
CNTPClient::CNTPClient() 
{ 
  m_dwTimeout =5000; //Default timeout of 5 seconds 
} 
// 
// Get time from NTP server 
// Parameters: 
// pszHostName: server name 
// response:structure of response witch save time fom server 
// nport:NTP port(137) 
// if ok return true other return false 
BOOL CNTPClient::GetServerTime(LPCTSTR pszHostName, NtpServerResponse& response, int nPort) 
{ 
 
	//paramater validity checking 
  ASSERT(pszHostName); 
 
  //Create the socket using UTP 
  m_hSocket = socket(AF_INET, SOCK_DGRAM, 0); 
  if(m_hSocket == INVALID_SOCKET)	 
  { 
	wsprintf(str,"Failed to create client socket, GetLastError returns: %d\n", GetLastError()); 
	LogToFile(str); 
    //TRACE(_T("Failed to create client socket, GetLastError returns: %d\n"), GetLastError()); 
    return FALSE; 
  } 
  //Connect to the NTP server 
	LPSTR lpszAscii = (LPSTR)pszHostName; 
	wsprintf(str,"Begin to connect to the NTP server <%s> on port <%d>.\n", pszHostName, nPort); 
	LogToFile(str); 
	//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{ 
			LogToFile("NTP server was not found out.Meybe name was wrong.\n"); 
			return FALSE; 
		} 
	} 
	SetTimeout(TIME_OUT);//Set timeout 
	//Call the protected version which takes an address  
	//in the form of a standard C style struct. 
	 int IsOK=connect( m_hSocket, (SOCKADDR*)&sockAddr, sizeof(sockAddr)); 
	 if(IsOK!=0){ 
		 wsprintf(str,"Could not connect to the NTP server <%s> on  %d, GetLastError returns: %d\n", pszHostName, nPort, GetLastError()); 
		 LogToFile(str); 
		 //TRACE(_T("Could not connect to the NTP server %s on port %d, GetLastError returns: %d\n"), pszHostName, nPort, GetLastError()); 
		return FALSE; 
	 } 
    //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 
	IsOK=send(m_hSocket,(LPCSTR) &nbi,nSendSize,MSG_DONTROUTE); 
	if(IsOK!=nSendSize) 
	{ 
		 wsprintf(str,"Failed in call to send NTP request to the NTP server, GetLastError returns %d.\n", GetLastError()); 
		 LogToFile(str); 
//      TRACE(_T("Failed in call to send NTP request to the NTP server, GetLastError returns %d\n"), GetLastError()); 
		return FALSE; 
	} 
	 wsprintf(str,"NTP packet was sent to <%s> succesfully.\n", lpszAscii); 
	LogToFile(str); 
 
    //Need to use select to determine readibilty of socket 
    BOOL bReadable; 
	 wsprintf(str,"Waitting response from <%s>.\n", lpszAscii); 
	LogToFile(str); 
 
    if (!IsReadible(bReadable, m_dwTimeout) || !bReadable) 
    { 
		 wsprintf(str,"Time out waitting for NTP reply from the NTP server, GetLastError returns %d.\n", GetLastError()); 
		 LogToFile(str); 
//      TRACE(_T("Unable to wait for NTP reply from the NTP server, GetLastError returns %d\n"), WSAETIMEDOUT); 
 
      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); 
	//get ntp packet to ntp packet structure 
    if (!recv(m_hSocket,(LPSTR) &nfp, nReceiveSize,0)) 
    { 
		 wsprintf(str,"Unable to read reply from the NTP server, GetLastError returns %d.\n", GetLastError()); 
		 LogToFile(str); 
//      TRACE(_T("Unable to read reply from the NTP server, GetLastError returns %d\n"), GetLastError()); 
 
      //Tidy up prior to returning 
      //DWORD dwError = GetLastError(); 
      //SetLastError(dwError); 
 
      return FALSE; 
    } 
	 wsprintf(str,"NTP packet was received from <%s> succesfully.\n", lpszAscii); 
	LogToFile(str); 
    //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; 
	//Calculate tip delay  
    response.m_RoundTripDelay = (response.m_DestinationTime - response.m_OriginateTime) - (response.m_ReceiveTime - response.m_TransmitTime); 
	//calculate offset of time 
    response.m_LocalClockOffset = ((response.m_ReceiveTime - response.m_OriginateTime) + (response.m_TransmitTime - response.m_DestinationTime)) / 2; 
    return TRUE; 
   
} 
 
BOOL CNTPClient::EnableSetTimePriviledge() 
{ 
	//opens the access token associated with a process.  
	//Required to change the privileges specified in an access token 
	//and required to query the contents of an access token. 
  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)); 
  //retrieves the locally unique identifier (LUID) used on a specified system to locally 
  //represent the specified privilege name.  
 
  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;//Specifies the number of entries in the Privileges array. 
  m_TokenPriv.Privileges[0].Attributes |= SE_PRIVILEGE_ENABLED;//The privilege is enabled. 
  m_bTakenPriviledge = TRUE; 
//Enables privileges in the specified access token.  
  BOOL bSuccess = AdjustTokenPrivileges(m_hToken, FALSE, &m_TokenPriv, 0, NULL, 0); 
	if (!bSuccess) 
	  TRACE(_T("Failed to adjust SetTime priviledge\n")); 
 
	return bSuccess; 
} 
//Disables privileges in the specified access token.  
void CNTPClient::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")); 
  } 
} 
//Set new time to local system time 
BOOL CNTPClient::SetClientTime(const CNtpTime& NewTime) 
{ 
  BOOL bSuccess = FALSE; 
  //The SetSystemTime function enables the SE_SYSTEMTIME_NAME privilege  
  //before changing the system time. This privilege is disabled by default.  
  //so,we must set the privilege to SE_SYSTEMTIME_NAME. 
  if (EnableSetTimePriviledge()) 
  { 
	//set systemtime 
    SYSTEMTIME st = NewTime; 
    bSuccess = SetSystemTime(&st); 
    if (!bSuccess) 
		LogToFile("Failed in call to set the system time\n"); 
      //TRACE(_T("Failed in call to set the system time\n")); 
  } 
  //restore original privilege 
  RevertSetTimePriviledge(); 
 
  return bSuccess; 
} 
// 
// Is packet arrived,if packet is arrived return true, 
// when timeout then return false. 
// 
 
BOOL CNTPClient::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; 
  } 
} 
 
void LogToFile(LPCSTR str){ 
	FILE* f;  
	SYSTEMTIME SystemTime; 
	char tmpbuf[128]; 
//	char buf[128]; 
//  GetSystemTime(&SystemTime); 
	GetLocalTime( &SystemTime   ); 
	wsprintf(tmpbuf,"[%d-%02d-%02d %02d:%02d:%02d] %s",SystemTime.wYear, 
				SystemTime.wMonth,SystemTime.wDay,SystemTime.wHour, 
				SystemTime.wMinute, SystemTime.wSecond,str); 
	 
	f=fopen(LogFile,"a+"); 
//fwrite("New LogToFile\n",1,15,f); 
	fwrite(tmpbuf,1,strlen(tmpbuf),f); 
	 
//	fwrite(str,1,Len,f); 
	fclose(f); 
	 
} 
 
//main process 
 
//char str[1600]; 
//#define CONFIGFILE "ntp.cfg" 
int main(int argc, char* argv[]) 
{ 
	char buff[500]; 
	char HostName[50][50]; 
	unsigned int i,flag; 
	FILE* f; 
	size_t count; 
	unsigned int HostNum,Num; 
 
	LogToFile("Start working.\n"); 
	//open config file 
	f=fopen(CONFIGFILE,"r"); 
	if(f==0){ 
			LogToFile("Can not open config file \n");		 
		return 0; 
	} 
	LogToFile("Config file was successfully opened.\n");		 
	HostNum=0; 
	Num=0; 
	ZeroMemory(HostName, sizeof(HostName)); 
	flag=0; 
	//read config file and skip LF 
	while(!feof(f)){ 
		count=fread(buff,sizeof(char),500,f); 
		for( i=0;i0){ 
					HostNum++; 
					flag=1; //is null line 
				} 
				Num=0; 
			}else{ 
				//get server name 
				HostName[HostNum][Num++]=buff[i]; 
				flag=0; 
			} 
		} 
	} 
	fclose(f); 
 
	if(HostNum==0){ 
		LogToFile("No NTP server is specified.\n");		 
		return 0; 
	} 
	if(flag==0) 
		HostNum++; 
 
	wsprintf(str,"Read %d NTP server names from config file.\n",HostNum); 
	LogToFile(str);		 
	LogToFile("They are:\n");		 
	for(i=0;i are:\n",HostName[i]); 
			LogToFile(str);		 
			wsprintf(str,"                              DD/MM/YYYY  HH:MM:SS.MS\n"); 
			LogToFile(str);		 
			wsprintf(str,"Client Originate Date was  :  %02d/%02d/%04d, %02d:%02d:%02d.%03d\n", st1.wDay, st1.wMonth, st1.wYear, st1.wHour, st1.wMinute, st1.wSecond, st1.wMilliseconds); 
			LogToFile(str);		 
			wsprintf(str,"Server Receive Date was    :  %02d/%02d/%04d, %02d:%02d:%02d.%03d\n", st2.wDay, st2.wMonth, st2.wYear, st2.wHour, st2.wMinute, st2.wSecond, st2.wMilliseconds); 
			LogToFile(str);		 
			wsprintf(str,"Server Transmit Date was   :  %02d/%02d/%04d, %02d:%02d:%02d.%03d\n", st3.wDay, st3.wMonth, st3.wYear, st3.wHour, st3.wMinute, st3.wSecond, st3.wMilliseconds); 
			LogToFile(str);		 
			wsprintf(str,"Client Destination Date was: %02d/%02d/%04d, %02d:%02d:%02d.%03d\n", st4.wDay, st4.wMonth, st4.wYear, st4.wHour, st4.wMinute, st4.wSecond, st4.wMilliseconds); 
			LogToFile(str);		 
			CNtpTime newTime(CNtpTime::GetCurrentTime() + response.m_LocalClockOffset); 
			SYSTEMTIME st; 
			GetLocalTime( &st   ); 
			wsprintf(str,"Set local time from %d-%02d-%02d %02d:%02d:%02d:%d to ", 
				st.wYear,st.wMonth,st.wDay, 
				st.wHour,st.wMinute, st.wSecond,st.wMilliseconds); 
			//LogToFile(str);		 
 
			if (ntp.SetClientTime(newTime)){ 
				GetLocalTime( &st   ); 
				wsprintf(str1,"%d-%02d-%02d %02d:%02d:%02d:%d.\n", 
				st.wYear,st.wMonth,st.wDay, 
				st.wHour,st.wMinute, st.wSecond,st.wMilliseconds); 
				strcat(str,str1); 
				LogToFile(str);		 
				LogToFile("time was successfully synchronised.\n"); 
				LogToFile("Exit successfully.\n"); 
				goto End; 
			}else 
				LogToFile("Failed to set the local time.\n"); 
			}  
			break; 
		} 
		else 
			LogToFile("Next NTP server will be tried.\n"); 
	} 
		//Don't forget to release out use of the winsock stack 
	LogToFile("Sleeping 10 minutes.\n"); 
	Sleep(600000); 
	goto Begin; 
End: 
	WSACleanup(); 
 
	return 0; 
}