inline ULONGLONG stable_precision(ULONGLONG value) { static const ULONGLONG precision = 64; ULONGLONG remainder = value % precision; ULONGLONG truncated = value - remainder; ULONGLONG offset = (remainder >= (precision / 2)) ? precision : 0; ULONGLONG stable = truncated + offset; return stable; } inline bool get_last_bootup_time(std::string &stamp) { ULONGLONG t0 = 0; ULONGLONG t1 = 1; SYSTEMTIME st; ZeroMemory(&st, sizeof(st)); static const size_t max_attempts = 113; // Limit number of retries to arbitrary number (not infanite) but suficiently large enough to acomplish timing except in pedantic cases... for (size_t i = 0; (i != max_attempts) && (t0 != t1); ++i) { t0 = GetTickCount64(); GetSystemTime(&st); t1 = GetTickCount64(); } if (t0 != t1) return false; // Presume this is *very* unlikely. // Convert system time (Y/M/D h/m/s/millisec) to file time (100 nanosecond intervals). FILETIME ft; if (SystemTimeToFileTime(&st, &ft) == FALSE) return false; // Presume this will never fail since system time is expected to be valid. ULARGE_INTEGER uli; uli.LowPart = ft.dwLowDateTime; uli.HighPart = ft.dwHighDateTime; // Convert file time to milliseconds. ULONGLONG ft_millisec = uli.QuadPart / 10000; // Round milliseconds to the nearest stable precision (inconsistency/imprecision between system clock & tick count). ULONGLONG time = stable_precision(ft_millisec); ULONGLONG ticks = stable_precision(t0); ULONGLONG boot_time = time - ticks; std::ostringstream oss; oss << boot_time; stamp = oss.str(); return true; }