From c449929fefde11e5ff8ff5308f0db29b8132dee4 Mon Sep 17 00:00:00 2001 From: Eric Kohl Date: Sat, 3 Apr 2021 09:38:07 +0200 Subject: [PATCH] [NTOS:EX] Use RtlCutoverTimeToSystemTime to determine the current time zone id CORE-14658 --- ntoskrnl/ex/time.c | 77 ++++++++++++++++++++++++++++++++------ sdk/include/ndk/rtlfuncs.h | 9 +++++ 2 files changed, 75 insertions(+), 11 deletions(-) diff --git a/ntoskrnl/ex/time.c b/ntoskrnl/ex/time.c index 44ce39d9ad9..ad971773a8d 100644 --- a/ntoskrnl/ex/time.c +++ b/ntoskrnl/ex/time.c @@ -225,6 +225,8 @@ BOOLEAN NTAPI ExRefreshTimeZoneInformation(IN PLARGE_INTEGER CurrentBootTime) { + LARGE_INTEGER StandardTime; + LARGE_INTEGER DaylightTime; LARGE_INTEGER CurrentTime; NTSTATUS Status; @@ -232,20 +234,73 @@ ExRefreshTimeZoneInformation(IN PLARGE_INTEGER CurrentBootTime) Status = RtlQueryTimeZoneInformation(&ExpTimeZoneInfo); if (!NT_SUCCESS(Status)) { - /* Failed, clear all data */ - RtlZeroMemory(&ExpTimeZoneInfo, sizeof(RTL_TIME_ZONE_INFORMATION)); - ExpTimeZoneBias.QuadPart = (LONGLONG)0; - ExpTimeZoneId = TIME_ZONE_ID_UNKNOWN; + DPRINT1("RtlQueryTimeZoneInformation() failed (Status 0x%08lx)\n", Status); + return FALSE; + } + + /* Get the default bias */ + ExpTimeZoneBias.QuadPart = (LONGLONG)ExpTimeZoneInfo.Bias * TICKSPERMINUTE; + + if (ExpTimeZoneInfo.StandardDate.Month != 0 && + ExpTimeZoneInfo.DaylightDate.Month != 0) + { + /* Get this years standard start time */ + if (!RtlCutoverTimeToSystemTime(&ExpTimeZoneInfo.StandardDate, + &StandardTime, + CurrentBootTime, + TRUE)) + { + DPRINT1("RtlCutoverTimeToSystemTime() for StandardDate failed!\n"); + return FALSE; + } + + /* Get this years daylight start time */ + if (!RtlCutoverTimeToSystemTime(&ExpTimeZoneInfo.DaylightDate, + &DaylightTime, + CurrentBootTime, + TRUE)) + { + DPRINT1("RtlCutoverTimeToSystemTime() for DaylightDate failed!\n"); + return FALSE; + } + + /* Determine the time zone id and update the time zone bias */ + if (DaylightTime.QuadPart < StandardTime.QuadPart) + { + if ((CurrentBootTime->QuadPart >= DaylightTime.QuadPart) && + (CurrentBootTime->QuadPart < StandardTime.QuadPart)) + { + DPRINT("Daylight time!\n"); + ExpTimeZoneId = TIME_ZONE_ID_DAYLIGHT; + ExpTimeZoneBias.QuadPart += (LONGLONG)ExpTimeZoneInfo.DaylightBias * TICKSPERMINUTE; + } + else + { + DPRINT("Standard time!\n"); + ExpTimeZoneId = TIME_ZONE_ID_STANDARD; + ExpTimeZoneBias.QuadPart += (LONGLONG)ExpTimeZoneInfo.StandardBias * TICKSPERMINUTE; + } + } + else + { + if ((CurrentBootTime->QuadPart >= StandardTime.QuadPart) && + (CurrentBootTime->QuadPart < DaylightTime.QuadPart)) + { + DPRINT("Standard time!\n"); + ExpTimeZoneId = TIME_ZONE_ID_STANDARD; + ExpTimeZoneBias.QuadPart += (LONGLONG)ExpTimeZoneInfo.StandardBias * TICKSPERMINUTE; + } + else + { + DPRINT("Daylight time!\n"); + ExpTimeZoneId = TIME_ZONE_ID_DAYLIGHT; + ExpTimeZoneBias.QuadPart += (LONGLONG)ExpTimeZoneInfo.DaylightBias * TICKSPERMINUTE; + } + } } else { - /* FIXME: Calculate transition dates */ - - /* Set bias and ID */ - ExpTimeZoneBias.QuadPart = ((LONGLONG)(ExpTimeZoneInfo.Bias + - ExpTimeZoneInfo.StandardBias)) * - TICKSPERMINUTE; - ExpTimeZoneId = TIME_ZONE_ID_STANDARD; + ExpTimeZoneId = TIME_ZONE_ID_UNKNOWN; } /* Change it for user-mode applications */ diff --git a/sdk/include/ndk/rtlfuncs.h b/sdk/include/ndk/rtlfuncs.h index 7817278a17f..513fc195b5f 100644 --- a/sdk/include/ndk/rtlfuncs.h +++ b/sdk/include/ndk/rtlfuncs.h @@ -4533,6 +4533,15 @@ RtlIpv6StringToAddressExW( // // Time Functions // +NTSYSAPI +BOOLEAN +NTAPI +RtlCutoverTimeToSystemTime( + _In_ PTIME_FIELDS CutoverTimeFields, + _Out_ PLARGE_INTEGER SystemTime, + _In_ PLARGE_INTEGER CurrentTime, + _In_ BOOLEAN ThisYearsCutoverOnly); + NTSYSAPI NTSTATUS NTAPI