From 7161dcd42653452a2373a7595a7020d0a59722f4 Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Thu, 25 Jun 2020 12:30:00 +0200 Subject: [PATCH] ntdll: Return the current time and timezone bias in NtQuerySystemInformation(SystemTimeOfDayInformation). Signed-off-by: Alexandre Julliard --- dlls/ntdll/time.c | 50 +++++-------------------------------- dlls/ntdll/unix/system.c | 12 +++++++-- dlls/wbemprox/builtin.c | 2 +- include/winternl.h | 8 +++--- programs/taskmgr/perfdata.c | 4 +-- 5 files changed, 23 insertions(+), 53 deletions(-) diff --git a/dlls/ntdll/time.c b/dlls/ntdll/time.c index 4d3c8afae65..96b8ceab3bc 100644 --- a/dlls/ntdll/time.c +++ b/dlls/ntdll/time.c @@ -228,44 +228,6 @@ BOOLEAN WINAPI RtlTimeFieldsToTime( return TRUE; } -/*********************************************************************** - * TIME_GetBias [internal] - * - * Helper function calculates delta local time from UTC. - * - * PARAMS - * utc [I] The current utc time. - * pdaylight [I] Local daylight. - * - * RETURNS - * The bias for the current timezone. - */ -static LONG TIME_GetBias(void) -{ - static time_t last_utc; - static LONG last_bias; - LONG ret; - time_t utc; - - utc = time( NULL ); - - RtlEnterCriticalSection( &TIME_tz_section ); - if (utc != last_utc) - { - RTL_DYNAMIC_TIME_ZONE_INFORMATION tzi; - int is_dst = init_tz_info( &tzi ); - - last_utc = utc; - last_bias = tzi.Bias; - last_bias += is_dst ? tzi.DaylightBias : tzi.StandardBias; - last_bias *= SECSPERMIN; - } - - ret = last_bias; - - RtlLeaveCriticalSection( &TIME_tz_section ); - return ret; -} /****************************************************************************** * RtlLocalTimeToSystemTime [NTDLL.@] @@ -283,12 +245,12 @@ static LONG TIME_GetBias(void) NTSTATUS WINAPI RtlLocalTimeToSystemTime( const LARGE_INTEGER *LocalTime, PLARGE_INTEGER SystemTime) { - LONG bias; + SYSTEM_TIMEOFDAY_INFORMATION info; TRACE("(%p, %p)\n", LocalTime, SystemTime); - bias = TIME_GetBias(); - SystemTime->QuadPart = LocalTime->QuadPart + bias * (LONGLONG)TICKSPERSEC; + NtQuerySystemInformation( SystemTimeOfDayInformation, &info, sizeof(info), NULL ); + SystemTime->QuadPart = LocalTime->QuadPart + info.TimeZoneBias.QuadPart; return STATUS_SUCCESS; } @@ -308,12 +270,12 @@ NTSTATUS WINAPI RtlLocalTimeToSystemTime( const LARGE_INTEGER *LocalTime, NTSTATUS WINAPI RtlSystemTimeToLocalTime( const LARGE_INTEGER *SystemTime, PLARGE_INTEGER LocalTime ) { - LONG bias; + SYSTEM_TIMEOFDAY_INFORMATION info; TRACE("(%p, %p)\n", SystemTime, LocalTime); - bias = TIME_GetBias(); - LocalTime->QuadPart = SystemTime->QuadPart - bias * (LONGLONG)TICKSPERSEC; + NtQuerySystemInformation( SystemTimeOfDayInformation, &info, sizeof(info), NULL ); + LocalTime->QuadPart = SystemTime->QuadPart - info.TimeZoneBias.QuadPart; return STATUS_SUCCESS; } diff --git a/dlls/ntdll/unix/system.c b/dlls/ntdll/unix/system.c index 68de16b7e5b..1d81e8a04f9 100644 --- a/dlls/ntdll/unix/system.c +++ b/dlls/ntdll/unix/system.c @@ -1690,10 +1690,18 @@ NTSTATUS WINAPI NtQuerySystemInformation( SYSTEM_INFORMATION_CLASS class, case SystemTimeOfDayInformation: { + struct tm *tm; + time_t now; SYSTEM_TIMEOFDAY_INFORMATION sti = {{{ 0 }}}; - /* liKeSystemTime, liExpTimeZoneBias, uCurrentTimeZoneId */ - sti.liKeBootTime.QuadPart = server_start_time; + sti.BootTime.QuadPart = server_start_time; + now = time( NULL ); + tm = gmtime( &now ); + sti.TimeZoneBias.QuadPart = mktime( tm ) - now; + tm = localtime( &now ); + if (tm->tm_isdst) sti.TimeZoneBias.QuadPart -= 3600; + sti.TimeZoneBias.QuadPart *= TICKSPERSEC; + NtQuerySystemTime( &sti.SystemTime ); if (size <= sizeof(sti)) { diff --git a/dlls/wbemprox/builtin.c b/dlls/wbemprox/builtin.c index 466611721ab..2ff3131936d 100644 --- a/dlls/wbemprox/builtin.c +++ b/dlls/wbemprox/builtin.c @@ -3275,7 +3275,7 @@ static WCHAR *get_lastbootuptime(void) if (!(ret = heap_alloc( 26 * sizeof(WCHAR) ))) return NULL; NtQuerySystemInformation( SystemTimeOfDayInformation, &ti, sizeof(ti), NULL ); - RtlTimeToTimeFields( &ti.liKeBootTime, &tf ); + RtlTimeToTimeFields( &ti.BootTime, &tf ); swprintf( ret, 26, L"%04u%02u%02u%02u%02u%02u.%06u+000", tf.Year, tf.Month, tf.Day, tf.Hour, tf.Minute, tf.Second, tf.Milliseconds * 1000 ); return ret; diff --git a/include/winternl.h b/include/winternl.h index 3ff15f28c15..ae41af85b3f 100644 --- a/include/winternl.h +++ b/include/winternl.h @@ -1482,10 +1482,10 @@ typedef struct _SYSTEM_PERFORMANCE_INFORMATION { typedef struct _SYSTEM_TIMEOFDAY_INFORMATION { #ifdef __WINESRC__ - LARGE_INTEGER liKeBootTime; - LARGE_INTEGER liKeSystemTime; - LARGE_INTEGER liExpTimeZoneBias; - ULONG uCurrentTimeZoneId; + LARGE_INTEGER BootTime; + LARGE_INTEGER SystemTime; + LARGE_INTEGER TimeZoneBias; + ULONG TimeZoneId; ULONG Reserved; ULONGLONG BootTimeBias; ULONGLONG SleepTimeBias; diff --git a/programs/taskmgr/perfdata.c b/programs/taskmgr/perfdata.c index 3b5997d759f..d81ab102482 100644 --- a/programs/taskmgr/perfdata.c +++ b/programs/taskmgr/perfdata.c @@ -199,7 +199,7 @@ void PerfDataRefresh(void) /* CurrentValue = NewValue - OldValue */ dbIdleTime = Li2Double(SysPerfInfo.IdleTime) - Li2Double(liOldIdleTime); dbKernelTime = CurrentKernelTime - OldKernelTime; - dbSystemTime = Li2Double(SysTimeInfo.liKeSystemTime) - Li2Double(liOldSystemTime); + dbSystemTime = Li2Double(SysTimeInfo.SystemTime) - Li2Double(liOldSystemTime); /* CurrentCpuIdle = IdleTime / SystemTime */ dbIdleTime = dbIdleTime / dbSystemTime; @@ -212,7 +212,7 @@ void PerfDataRefresh(void) /* Store new CPU's idle and system time */ liOldIdleTime = SysPerfInfo.IdleTime; - liOldSystemTime = SysTimeInfo.liKeSystemTime; + liOldSystemTime = SysTimeInfo.SystemTime; OldKernelTime = CurrentKernelTime; /* Determine the process count