From: Martin Burnicki Date: Wed, 23 Jan 2013 16:50:49 +0000 (+0100) Subject: [Bug 2328] Don't apply small time adjustments on Windows versions which don't support... X-Git-Tag: NTP_4_2_7P351~1 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=68941c6e2c140ad3c238d97cd82f24bc6b5d38e8;p=thirdparty%2Fntp.git [Bug 2328] Don't apply small time adjustments on Windows versions which don't support this. bk: 510014e9LVCWTJg3lZDt5DQ6p_dc0Q --- diff --git a/ChangeLog b/ChangeLog index 881455049..0244abbfb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,5 @@ +* [Bug 2328] Don't apply small time adjustments on Windows versions + which don't support this. (4.2.7p350) 2013/01/21 Released by Harlan Stenn * Added sntp/loc/netbsd based on info from Christos Zoulas. (4.2.7p349) 2013/01/20 Released by Harlan Stenn diff --git a/ports/winnt/ntpd/nt_clockstuff.c b/ports/winnt/ntpd/nt_clockstuff.c index 53c5415ae..aaf21b887 100644 --- a/ports/winnt/ntpd/nt_clockstuff.c +++ b/ports/winnt/ntpd/nt_clockstuff.c @@ -129,6 +129,14 @@ static LONGLONG baseline_times[BASELINES_TOT] = {0}; static ULONGLONG clock_backward_max = CLOCK_BACK_THRESHOLD; static int clock_backward_count; +/** + * A flag set on Windows versions which ignore small time adjustments. + * + * Windows Vista and Windows 7 ignore TimeAdjustment less than 16. + * @note Has to be checked for Windows Server 2008/2012 and Windows 8. + * Ref: http://support.microsoft.com/kb/2537623, bug #2328 + */ +static BOOL os_ignores_small_adjustment; /* * clockperiod is the period used for SetSystemTimeAdjustment @@ -268,6 +276,42 @@ perf_ctr(void) } +/* + * init_small_adjustment + * + * Set variable os_ignores_small_adjustment + * + */ +static void init_small_adjustment(void) +{ + OSVERSIONINFO vi; + memset(&vi, 0, sizeof(vi)); + vi.dwOSVersionInfoSize = sizeof(vi); + + if (!GetVersionEx(&vi)) { + msyslog(LOG_WARNING, "GetVersionEx failed with error code %d.", GetLastError()); + os_ignores_small_adjustment = FALSE; + return; + } + + if (vi.dwMajorVersion == 6 && vi.dwMinorVersion == 1) { + // Windows 7 and Windows Server 2008 R2 + // + // Windows 7 is documented as affected. + // Windows Server 2008 R2 is assumed affected. + os_ignores_small_adjustment = TRUE; + } else if (vi.dwMajorVersion == 6 && vi.dwMinorVersion == 0) { + // Windows Vista and Windows Server 2008 + // + // Windows Vista is documented as affected. + // Windows Server 2008 is assumed affected. + os_ignores_small_adjustment = TRUE; + } else { + os_ignores_small_adjustment = FALSE; + } +} + + /* * choose_interp_counter - select between QueryPerformanceCounter and * the x86 processor cycle counter (TSC). @@ -468,6 +512,18 @@ adj_systime( ((isneg) ? -0.5 : 0.5)); + + if (os_ignores_small_adjustment) { + /* + * As the OS ignores adjustments smaller than 16, we need to + * leave these small adjustments in sys_residual, causing + * the small values to be averaged over time. + */ + if (TimeAdjustment > -16 && TimeAdjustment < 16) { + TimeAdjustment = 0; + } + } + dtemp -= TimeAdjustment * ppm_per_adjust_unit; @@ -639,6 +695,8 @@ init_winnt_time(void) #pragma warning(pop) + init_small_adjustment(); + /* * Get privileges needed for fiddling with the clock */