]> git.ipfire.org Git - thirdparty/ntp.git/commitdiff
[Bug 2328] Don't apply small time adjustments on Windows versions which don't support...
authorMartin Burnicki <burnicki@ntp.org>
Wed, 23 Jan 2013 16:50:49 +0000 (17:50 +0100)
committerMartin Burnicki <burnicki@ntp.org>
Wed, 23 Jan 2013 16:50:49 +0000 (17:50 +0100)
bk: 510014e9LVCWTJg3lZDt5DQ6p_dc0Q

ChangeLog
ports/winnt/ntpd/nt_clockstuff.c

index 881455049d3ba16c8f6564ef0b7176995b29bf6c..0244abbfb3e7741c54f50dbf7674c1b290996d73 100644 (file)
--- 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 <stenn@ntp.org>
 * Added sntp/loc/netbsd based on info from Christos Zoulas.
 (4.2.7p349) 2013/01/20 Released by Harlan Stenn <stenn@ntp.org>
index 53c5415aeea73b330943188f001fefd24e8242d0..aaf21b887e9894e7006a125b49d5f7bc97e8f593 100644 (file)
@@ -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
         */