Uptime: reads (System|Interrupt)Time directly from SharedUserData

This commit is contained in:
李通洲
2026-03-07 00:09:08 +08:00
parent c7363f904a
commit f924a8bf06
3 changed files with 16 additions and 37 deletions
+3 -12
View File
@@ -4,17 +4,9 @@
#include <stdint.h>
#include <time.h>
#ifdef _WIN32
#include <ntdef.h>
#include <ntstatus.h>
#include "common/windows/nt.h"
#include <profileapi.h>
#include <sysinfoapi.h>
NTSYSCALLAPI
NTSTATUS
NTAPI
NtDelayExecution(
_In_ BOOLEAN Alertable,
_In_ PLARGE_INTEGER DelayInterval);
#elif defined(__HAIKU__)
#include <OS.h>
#endif
@@ -40,8 +32,7 @@ static inline double ffTimeGetTick(void) //In msec
static inline uint64_t ffTimeGetNow(void)
{
#ifdef _WIN32
uint64_t timeNow;
GetSystemTimeAsFileTime((FILETIME*) &timeNow);
uint64_t timeNow = ffKSystemTimeToUInt64(&SharedUserData->SystemTime);
return (timeNow - 116444736000000000ull) / 10000ull;
#elif defined(__HAIKU__)
return (uint64_t) real_time_clock_usecs() / 1000u;
@@ -58,7 +49,7 @@ static inline bool ffTimeSleep(uint32_t msec)
#ifdef _WIN32
LARGE_INTEGER interval;
interval.QuadPart = -(int64_t) msec * 10000; // Relative time in 100-nanosecond intervals
return NtDelayExecution(TRUE, &interval) == STATUS_SUCCESS;
return NT_SUCCESS(NtDelayExecution(TRUE, &interval));
#else
return nanosleep(&(struct timespec){ msec / 1000, (long) (msec % 1000) * 1000000 }, NULL) == 0;
#endif
+4
View File
@@ -2,6 +2,8 @@
#include <winternl.h>
#include <winnt.h>
#include <stdint.h>
#include <assert.h>
enum {
SystemModuleInformation = 11,
@@ -423,6 +425,8 @@ typedef struct _SYSTEM_FIRMWARE_TABLE_INFORMATION
_Field_size_bytes_(TableBufferLength) UCHAR TableBuffer[];
} SYSTEM_FIRMWARE_TABLE_INFORMATION, *PSYSTEM_FIRMWARE_TABLE_INFORMATION;
NTSTATUS NTAPI NtDelayExecution(_In_ BOOLEAN Alertable, _In_ PLARGE_INTEGER DelayInterval);
/**
* The KSYSTEM_TIME structure represents interrupt time, system time, and time zone bias.
*/
+9 -25
View File
@@ -1,34 +1,18 @@
#include "uptime.h"
#include "common/time.h"
#include "common/library.h"
#include <realtimeapiset.h>
#include <sysinfoapi.h>
#include "common/windows/nt.h"
const char* ffDetectUptime(FFUptimeResult* result)
{
#if FF_WIN7_COMPAT
HMODULE hKernelBase = GetModuleHandleW(L"KernelBase.dll");
if (__builtin_expect(!!hKernelBase, true))
{
FF_LIBRARY_LOAD_SYMBOL_LAZY(hKernelBase, QueryInterruptTime);
if (ffQueryInterruptTime) // Windows 10 and later
{
uint64_t uptime;
ffQueryInterruptTime(&uptime);
result->uptime = uptime / 10000; // Convert from 100-nanosecond intervals to milliseconds
goto ok;
}
}
// GetInterruptTime with Win7 support
uint64_t interruptTime = ffKSystemTimeToUInt64(&SharedUserData->InterruptTime);
result->uptime = GetTickCount64();
ok:
#else
uint64_t uptime;
QueryInterruptTime(&uptime);
result->uptime = uptime / 10000; // Convert from 100-nanosecond intervals to milliseconds
#endif
result->uptime = interruptTime / 10000; // Convert from 100-nanosecond intervals to milliseconds
result->bootTime = ffTimeGetNow() - result->uptime;
// Alternatively, `NtQuerySystemInformation(SystemTimeOfDayInformation)` reports the boot time directly,
// whose result exactly equals what WMI `Win32_OperatingSystem` reports
// with much lower accuracy (0.5 seconds)
return NULL;
}