⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 nt_clockstuff.c

📁 基于ntp协议的网络时间服务程序
💻 C
📖 第 1 页 / 共 2 页
字号:
	}	  /* get the LUID for system-time privilege. */	LookupPrivilegeValue(NULL, SE_SYSTEMTIME_NAME, &tkp.Privileges[0].Luid);	tkp.PrivilegeCount = 1;  /* one privilege to set */	tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;	/* get set-time privilege for this process. */	AdjustTokenPrivileges(hToken, FALSE, &tkp, 0,	 	(PTOKEN_PRIVILEGES) NULL, 0);	/* cannot use return value of AdjustTokenPrivileges. */	/* (success does not indicate all privileges were set) */	if (GetLastError() != ERROR_SUCCESS) 	{		msyslog(LOG_ERR, "AdjustTokenPrivileges failed: %m");	 	/* later set time call will probably fail */	}	/* Reset the Clock to a reasonable increment */	if (!GetSystemTimeAdjustment(&initial_units_per_tick, &every,&noslew))	{		msyslog(LOG_ERR, "GetSystemTimeAdjustment failed: %m\n");		exit(-1);	}	units_per_tick = initial_units_per_tick;	/* Calculate the time adjustment resulting from incrementing	 * units per tick by 1 unit for 1 second */	ppm_per_adjust_unit = 1000000.0 / (double) every;#ifdef DEBUG	msyslog(LOG_INFO, "Initial Clock increment %7.1f us",			(float) (units_per_tick / 10));	msyslog(LOG_INFO, "Adjustment rate %5.3f ppm/s", ppm_per_adjust_unit);#endif	StartClockThread();	/* Set up the Console Handler */	if (!SetConsoleCtrlHandler(OnConsoleEvent, TRUE))	{		msyslog(LOG_ERR, "Can't set console control handler: %m");	}}void reset_winnt_time(void){	/* restore the clock frequency back to its original value */	if (!SetSystemTimeAdjustment(0, TRUE)) 	{		msyslog(LOG_ERR, "Failed to reset clock state, SetSystemTimeAdjustment(): %m");	}  	/* read the current system time, and write it back to           force CMOS update: */      /************ Added back in 2003-01-26 *****************/	{		SYSTEMTIME st;		GetSystemTime(&st);		SetSystemTime(&st);	}}intgettimeofday(	struct timeval *tv	){	/*  Use the system time (roughly synchronised to the tick, and	 *  extrapolated using the system performance counter.	 */	ULONGLONG Count;	LARGE_INTEGER LargeIntNowCount;	ULONGLONG Time;	ULONGLONG NowCount;	ULONGLONG PreCount;                                                  /*FIX*/	LONGLONG TicksElapsed;	LONG time_adjustment;	/*  Mark a mark ASAP. The latency to here should	 *  be reasonably deterministic	 */	PreCount = LastTimerCount;                                           /*FIX*/	if (!QueryPerformanceCounter(&LargeIntNowCount)) {		msyslog(LOG_ERR, "QueryPeformanceCounter failed: %m");		exit(1);	}	NowCount = LargeIntNowCount.QuadPart;	/*  Get base time we are going to extrapolate from	 */		EnterCriticalSection(&TimerCritialSection);	Count = LastTimerCount;	Time = LastTimerTime;	LeaveCriticalSection(&TimerCritialSection);	/*  Calculate when now is.	 *	 *  Result = LastTimerTime +  (NowCount - LastTimerCount) / PerfFrequency	 */	if (NowCount >= Count)	{		TicksElapsed = NowCount - Count; /* linear progression of ticks */	}	else	{	/************************************************************************/	/* Differentiate between real rollover and the case of taking a         */	/* perfcount then the APC coming in.                                    */	/************************************************************************/		if (Count > PreCount)                                           /*FIX*/		{								/*FIX*/			TicksElapsed = 0;                                       /*FIX*/		}                                                               /*FIX*/		else                                                            /*FIX*/		{                                                               /*FIX*/			TicksElapsed = NowCount + (RollOverCount - Count);	/*FIX*/		}                                                               /*FIX*/	}	/*  Calculate the new time (in 100's of nano-seconds)	 */	time_adjustment = (long) ((TicksElapsed * HECTONANOSECONDS) / PerfFrequency);	Time += time_adjustment;	/* Convert the hecto-nano second time to tv format	 */	Time -= FILETIME_1970;	tv->tv_sec = (LONG) ( Time / 10000000ui64);	tv->tv_usec = (LONG) (( Time % 10000000ui64) / 10);	return 0;}static void CALLBACKTimerApcFunction(	LPVOID lpArgToCompletionRoutine,	DWORD dwTimerLowValue,	DWORD dwTimerHighValue	){	LARGE_INTEGER LargeIntNowCount;	(void) lpArgToCompletionRoutine; /* not used */	if (dwTimerLowValue == lastLowTimer) return;		/* Grab the counter first of all */	QueryPerformanceCounter(&LargeIntNowCount);	/* Save this for next time */	lastLowTimer = dwTimerLowValue;	/* Check to see if the counter has rolled. This happens	   more often on Multi-CPU systems */	if ((ULONGLONG) LargeIntNowCount.QuadPart < LastTimerCount) {		/* Counter Rolled - try and estimate the rollover point using		  the nominal counter frequency divided by an estimate of the		  OS frequency */		RollOverCount = LastTimerCount + PerfFrequency * every /  HECTONANOSECONDS -			(ULONGLONG) LargeIntNowCount.QuadPart;#ifdef DEBUG		msyslog(LOG_INFO,			"Performance Counter Rollover %I64u:\rLast Timer Count %I64u\rCurrent Count %I64u",				RollOverCount, LastTimerCount, LargeIntNowCount.QuadPart);#endif	}	/* Now we can hang out and wait for the critical section to free up;	   we will get the CPU this timeslice. Meanwhile other tasks can use	   the last value of LastTimerCount */			EnterCriticalSection(&TimerCritialSection);	LastTimerCount = (ULONGLONG) LargeIntNowCount.QuadPart;	LastTimerTime = ((ULONGLONG) dwTimerHighValue << 32) +			 (ULONGLONG) dwTimerLowValue;	LeaveCriticalSection(&TimerCritialSection);}DWORD WINAPI ClockThread(void *arg){	LARGE_INTEGER DueTime;	HANDLE WaitableTimerHandle = CreateWaitableTimer(NULL, FALSE, NULL);	(void) arg; /* not used */	/*++++ Gerhard Junker	* see Platform SDK for QueryPerformanceCounter	* On a multiprocessor machine, it should not matter which processor is called. 	* However, you can get different results on different processors due to bugs in the BIOS or the HAL. 	* To specify processor affinity for a thread, use the SetThreadAffinityMask function. 	* ... we will hope, the apc routine will run on the same processor	*/	SetThreadAffinityMask(GetCurrentThread(), 1L);	/*---- Gerhard Junker */	if (WaitableTimerHandle != NULL) {		DueTime.QuadPart = 0i64;		if (SetWaitableTimer(WaitableTimerHandle, &DueTime, 1L /* ms */, TimerApcFunction, &WaitableTimerHandle, FALSE) != NO_ERROR) {			for(;;) {				if (WaitForSingleObjectEx(TimerThreadExitRequest, INFINITE, TRUE) == WAIT_OBJECT_0) {					break; /* we've been asked to exit */				}			}		}		CloseHandle(WaitableTimerHandle);		WaitableTimerHandle = NULL;	}	return 0;}static void StartClockThread(void){	DWORD tid;	FILETIME StartTime;	LARGE_INTEGER Freq = { 0, 0 };		/* get the performance counter freq */	if (!QueryPerformanceFrequency(&Freq))	{		msyslog(LOG_ERR, "QueryPerformanceFrequency failed: %m\n");		exit (-1);	}	PerfFrequency = Freq.QuadPart;	if ( modify_mm_timer != 0)	{		if (timeGetDevCaps( &tc, sizeof( tc ) ) == TIMERR_NOERROR ) 		{			wTimerRes = min( max( tc.wPeriodMin, MM_TIMER_INTV ), tc.wPeriodMax );			timeBeginPeriod( wTimerRes );#ifdef DEBUG			msyslog( LOG_INFO, "MM timer resolution: %u..%u ms, set to %u ms\n",			         tc.wPeriodMin, tc.wPeriodMax, wTimerRes );#endif		}		else			msyslog( LOG_ERR, "Failed to get MM timer caps\n" );	}	/* init variables with the time now */	GetSystemTimeAsFileTime(&StartTime);	LastTimerTime = (((ULONGLONG) StartTime.dwHighDateTime) << 32) +			  (ULONGLONG) StartTime.dwLowDateTime;	/* init sync objects */	InitializeCriticalSection(&TimerCritialSection);	TimerThreadExitRequest = CreateEvent(NULL, FALSE, FALSE, "TimerThreadExitRequest");	ClockThreadHandle = CreateThread(NULL, 0, ClockThread, NULL, 0, &tid);	if (ClockThreadHandle != NULL)	{		/* remember the thread priority is only within the process class */		if (!SetThreadPriority(ClockThreadHandle, THREAD_PRIORITY_TIME_CRITICAL)) 		{#ifdef DEBUG			printf("Error setting thread priority\n");#endif		  }	}	atexit( StopClockThread );}static void StopClockThread(void){		if ( wTimerRes )  /* if not 0 then the MM timer has been modified at startup */	{		timeEndPeriod( wTimerRes ); 		wTimerRes = 0;#ifdef DEBUG		msyslog( LOG_INFO, "MM timer set to default\n" );#endif	}	if (SetEvent(TimerThreadExitRequest) &&	    WaitForSingleObject(ClockThreadHandle, 10000L) == 0)	{		CloseHandle(TimerThreadExitRequest);		TimerThreadExitRequest = NULL;		CloseHandle(ClockThreadHandle);		ClockThreadHandle = NULL;		DeleteCriticalSection(&TimerCritialSection);	}	else	{		msyslog(LOG_ERR, "Failed to stop clock thread.");		Sleep( 100 );	}}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -