https://git.reactos.org/?p=reactos.git;a=commitdiff;h=7c3e96a26a15de8930cdd…
commit 7c3e96a26a15de8930cddf670d43bbf50c16bfad
Author: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
AuthorDate: Sun Apr 19 17:48:25 2020 +0200
Commit: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
CommitDate: Wed Apr 22 00:58:32 2020 +0200
[TIMEDATE.CPL][SYSSETUP][TZLIB] Introduce a small static library "tzlib":
"TimeZone Utilities Library", and use it in timedate.cpl and syssetup.dll.
This small win32 library provides time-zone utility wrappers around
Win32 functions, that are used by different ReactOS modules such as
timedate.cpl, syssetup.dll, and a possible future 'tzutil' tool.
The code has been extracted from the common code found in both
timedate.cpl and syssetup.dll.
---
dll/cpl/timedate/CMakeLists.txt | 3 +
dll/cpl/timedate/timezone.c | 296 ++++++----------------
dll/win32/syssetup/CMakeLists.txt | 4 +-
dll/win32/syssetup/wizard.c | 362 +++++++--------------------
sdk/include/reactos/libs/syssetup/syssetup.h | 25 +-
sdk/lib/CMakeLists.txt | 1 +
sdk/lib/tzlib/CMakeLists.txt | 3 +
sdk/lib/tzlib/tzlib.c | 352 ++++++++++++++++++++++++++
sdk/lib/tzlib/tzlib.h | 56 +++++
9 files changed, 584 insertions(+), 518 deletions(-)
diff --git a/dll/cpl/timedate/CMakeLists.txt b/dll/cpl/timedate/CMakeLists.txt
index 20f0d62d59c..fcf2fd2d03b 100644
--- a/dll/cpl/timedate/CMakeLists.txt
+++ b/dll/cpl/timedate/CMakeLists.txt
@@ -1,4 +1,6 @@
+include_directories(${REACTOS_SOURCE_DIR}/sdk/lib/tzlib)
+
spec2def(timedate.cpl timedate.spec)
list(APPEND SOURCE
@@ -19,6 +21,7 @@ add_library(timedate MODULE
${CMAKE_CURRENT_BINARY_DIR}/timedate.def)
set_module_type(timedate cpl UNICODE)
+target_link_libraries(timedate tzlib)
add_importlibs(timedate w32time advapi32 user32 gdi32 comctl32 ws2_32 iphlpapi msvcrt
kernel32 ntdll)
add_pch(timedate timedate.h SOURCE)
add_cd_file(TARGET timedate DESTINATION reactos/system32 FOR all)
diff --git a/dll/cpl/timedate/timezone.c b/dll/cpl/timedate/timezone.c
index 95a4e33220e..9dd79e1d01a 100644
--- a/dll/cpl/timedate/timezone.c
+++ b/dll/cpl/timedate/timezone.c
@@ -10,25 +10,16 @@
*/
#include "timedate.h"
-
-// See also sdk/include/reactos/libs/syssetup/syssetup.h
-typedef struct _TZ_INFO
-{
- LONG Bias;
- LONG StandardBias;
- LONG DaylightBias;
- SYSTEMTIME StandardDate;
- SYSTEMTIME DaylightDate;
-} TZ_INFO, *PTZ_INFO;
+#include <tzlib.h>
typedef struct _TIMEZONE_ENTRY
{
struct _TIMEZONE_ENTRY *Prev;
struct _TIMEZONE_ENTRY *Next;
- WCHAR Description[128]; /* 'Display' */
- WCHAR StandardName[33]; /* 'Std' */
- WCHAR DaylightName[33]; /* 'Dlt' */
- TZ_INFO TimezoneInfo; /* 'TZI' */
+ WCHAR Description[128]; /* 'Display' */
+ WCHAR StandardName[33]; /* 'Std' */
+ WCHAR DaylightName[33]; /* 'Dlt' */
+ REG_TZI_FORMAT TimezoneInfo; /* 'TZI' */
} TIMEZONE_ENTRY, *PTIMEZONE_ENTRY;
@@ -64,159 +55,91 @@ GetLargerTimeZoneEntry(
return NULL;
}
-
-static
-LONG
-QueryTimezoneData(
- HKEY hZoneKey,
- PTIMEZONE_ENTRY Entry)
-{
- DWORD dwValueSize;
- LONG lError;
-
- dwValueSize = sizeof(Entry->Description);
- lError = RegQueryValueExW(hZoneKey,
- L"Display",
- NULL,
- NULL,
- (LPBYTE)&Entry->Description,
- &dwValueSize);
- if (lError != ERROR_SUCCESS)
- return lError;
-
- dwValueSize = sizeof(Entry->StandardName);
- lError = RegQueryValueExW(hZoneKey,
- L"Std",
- NULL,
- NULL,
- (LPBYTE)&Entry->StandardName,
- &dwValueSize);
- if (lError != ERROR_SUCCESS)
- return lError;
-
- dwValueSize = sizeof(Entry->DaylightName);
- lError = RegQueryValueExW(hZoneKey,
- L"Dlt",
- NULL,
- NULL,
- (LPBYTE)&Entry->DaylightName,
- &dwValueSize);
- if (lError != ERROR_SUCCESS)
- return lError;
-
- dwValueSize = sizeof(Entry->TimezoneInfo);
- lError = RegQueryValueExW(hZoneKey,
- L"TZI",
- NULL,
- NULL,
- (LPBYTE)&Entry->TimezoneInfo,
- &dwValueSize);
- return lError;
-}
-
-
-static VOID
-CreateTimeZoneList(VOID)
+static LONG
+RetrieveTimeZone(
+ IN HKEY hZoneKey,
+ IN PVOID Context)
{
- WCHAR szKeyName[256];
- DWORD dwIndex;
- DWORD dwNameSize;
LONG lError;
- HKEY hZonesKey;
- HKEY hZoneKey;
PTIMEZONE_ENTRY Entry;
PTIMEZONE_ENTRY Current;
+ ULONG DescriptionSize;
+ ULONG StandardNameSize;
+ ULONG DaylightNameSize;
- if (RegOpenKeyExW(HKEY_LOCAL_MACHINE,
- L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Time
Zones",
- 0,
- KEY_ENUMERATE_SUB_KEYS,
- &hZonesKey))
- return;
-
- for (dwIndex = 0; ; dwIndex++)
+ Entry = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(TIMEZONE_ENTRY));
+ if (Entry == NULL)
{
- dwNameSize = sizeof(szKeyName);
- lError = RegEnumKeyExW(hZonesKey,
- dwIndex,
- szKeyName,
- &dwNameSize,
- NULL,
- NULL,
- NULL,
- NULL);
- if (lError == ERROR_NO_MORE_ITEMS)
- break;
-
- if (RegOpenKeyEx (hZonesKey,
- szKeyName,
- 0,
- KEY_QUERY_VALUE,
- &hZoneKey))
- break;
-
- Entry = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(TIMEZONE_ENTRY));
- if (Entry == NULL)
- {
- RegCloseKey(hZoneKey);
- break;
- }
-
- lError = QueryTimezoneData(hZoneKey,
- Entry);
+ return ERROR_NOT_ENOUGH_MEMORY;
+ }
- RegCloseKey(hZoneKey);
+ DescriptionSize = sizeof(Entry->Description);
+ StandardNameSize = sizeof(Entry->StandardName);
+ DaylightNameSize = sizeof(Entry->DaylightName);
- if (lError != ERROR_SUCCESS)
- {
- HeapFree(GetProcessHeap(), 0, Entry);
- break;
- }
+ lError = QueryTimeZoneData(hZoneKey,
+ NULL,
+ &Entry->TimezoneInfo,
+ Entry->Description,
+ &DescriptionSize,
+ Entry->StandardName,
+ &StandardNameSize,
+ Entry->DaylightName,
+ &DaylightNameSize);
+ if (lError != ERROR_SUCCESS)
+ {
+ HeapFree(GetProcessHeap(), 0, Entry);
+ return lError;
+ }
- if (TimeZoneListHead == NULL &&
- TimeZoneListTail == NULL)
- {
- Entry->Prev = NULL;
- Entry->Next = NULL;
- TimeZoneListHead = Entry;
- TimeZoneListTail = Entry;
- }
- else
+ if (TimeZoneListHead == NULL &&
+ TimeZoneListTail == NULL)
+ {
+ Entry->Prev = NULL;
+ Entry->Next = NULL;
+ TimeZoneListHead = Entry;
+ TimeZoneListTail = Entry;
+ }
+ else
+ {
+ Current = GetLargerTimeZoneEntry(Entry->TimezoneInfo.Bias,
Entry->Description);
+ if (Current != NULL)
{
- Current = GetLargerTimeZoneEntry(Entry->TimezoneInfo.Bias,
Entry->Description);
- if (Current != NULL)
+ if (Current == TimeZoneListHead)
{
- if (Current == TimeZoneListHead)
- {
- /* Prepend to head */
- Entry->Prev = NULL;
- Entry->Next = TimeZoneListHead;
- TimeZoneListHead->Prev = Entry;
- TimeZoneListHead = Entry;
- }
- else
- {
- /* Insert before current */
- Entry->Prev = Current->Prev;
- Entry->Next = Current;
- Current->Prev->Next = Entry;
- Current->Prev = Entry;
- }
+ /* Prepend to head */
+ Entry->Prev = NULL;
+ Entry->Next = TimeZoneListHead;
+ TimeZoneListHead->Prev = Entry;
+ TimeZoneListHead = Entry;
}
else
{
- /* Append to tail */
- Entry->Prev = TimeZoneListTail;
- Entry->Next = NULL;
- TimeZoneListTail->Next = Entry;
- TimeZoneListTail = Entry;
+ /* Insert before current */
+ Entry->Prev = Current->Prev;
+ Entry->Next = Current;
+ Current->Prev->Next = Entry;
+ Current->Prev = Entry;
}
}
+ else
+ {
+ /* Append to tail */
+ Entry->Prev = TimeZoneListTail;
+ Entry->Next = NULL;
+ TimeZoneListTail->Next = Entry;
+ TimeZoneListTail = Entry;
+ }
}
- RegCloseKey(hZonesKey);
+ return ERROR_SUCCESS;
}
+static VOID
+CreateTimeZoneList(VOID)
+{
+ EnumerateTimeZoneList(RetrieveTimeZone, NULL);
+}
static VOID
DestroyTimeZoneList(VOID)
@@ -299,9 +222,9 @@ SetLocalTimeZone(HWND hwnd)
}
wcscpy(TimeZoneInformation.StandardName,
- Entry->StandardName);
+ Entry->StandardName);
wcscpy(TimeZoneInformation.DaylightName,
- Entry->DaylightName);
+ Entry->DaylightName);
TimeZoneInformation.Bias = Entry->TimezoneInfo.Bias;
TimeZoneInformation.StandardBias = Entry->TimezoneInfo.StandardBias;
@@ -319,71 +242,6 @@ SetLocalTimeZone(HWND hwnd)
}
-static VOID
-GetAutoDaylightInfo(HWND hwnd)
-{
- HKEY hKey;
-
- if (RegOpenKeyExW(HKEY_LOCAL_MACHINE,
-
L"SYSTEM\\CurrentControlSet\\Control\\TimeZoneInformation",
- 0,
- KEY_QUERY_VALUE,
- &hKey))
- return;
-
- /* If the call fails (non zero), the reg value isn't available,
- * which means it shouldn't be disabled, so we should check the button.
- */
- if (RegQueryValueExW(hKey,
- L"DisableAutoDaylightTimeSet",
- NULL,
- NULL,
- NULL,
- NULL))
- {
- SendMessageW(hwnd, BM_SETCHECK, (WPARAM)BST_CHECKED, 0);
- }
- else
- {
- SendMessageW(hwnd, BM_SETCHECK, (WPARAM)BST_UNCHECKED, 0);
- }
-
- RegCloseKey(hKey);
-}
-
-
-static VOID
-SetAutoDaylightInfo(HWND hwnd)
-{
- HKEY hKey;
- DWORD dwValue = 1;
-
- if (RegOpenKeyExW(HKEY_LOCAL_MACHINE,
-
L"SYSTEM\\CurrentControlSet\\Control\\TimeZoneInformation",
- 0,
- KEY_SET_VALUE,
- &hKey))
- return;
-
- if (SendMessageW(hwnd, BM_GETCHECK, 0, 0) == BST_UNCHECKED)
- {
- RegSetValueExW(hKey,
- L"DisableAutoDaylightTimeSet",
- 0,
- REG_DWORD,
- (LPBYTE)&dwValue,
- sizeof(dwValue));
- }
- else
- {
- RegDeleteValueW(hKey,
- L"DisableAutoDaylightTimeSet");
- }
-
- RegCloseKey(hKey);
-}
-
-
/* Property page dialog callback */
INT_PTR CALLBACK
TimeZonePageProc(HWND hwndDlg,
@@ -396,9 +254,13 @@ TimeZonePageProc(HWND hwndDlg,
switch (uMsg)
{
case WM_INITDIALOG:
+ {
CreateTimeZoneList();
ShowTimeZoneList(GetDlgItem(hwndDlg, IDC_TIMEZONELIST));
- GetAutoDaylightInfo(GetDlgItem(hwndDlg, IDC_AUTODAYLIGHT));
+
+ SendDlgItemMessage(hwndDlg, IDC_AUTODAYLIGHT, BM_SETCHECK,
+ (WPARAM)(GetAutoDaylight() ? BST_CHECKED : BST_UNCHECKED),
0);
+
hBitmap = LoadImageW(hApplet, MAKEINTRESOURCEW(IDC_WORLD), IMAGE_BITMAP, 0,
0, LR_DEFAULTCOLOR);
if (hBitmap != NULL)
{
@@ -408,6 +270,7 @@ TimeZonePageProc(HWND hwndDlg,
cySource = bitmap.bmHeight;
}
break;
+ }
case WM_DRAWITEM:
{
@@ -452,7 +315,8 @@ TimeZonePageProc(HWND hwndDlg,
{
case PSN_APPLY:
{
- SetAutoDaylightInfo(GetDlgItem(hwndDlg, IDC_AUTODAYLIGHT));
+ SetAutoDaylight(SendDlgItemMessage(hwndDlg, IDC_AUTODAYLIGHT,
+ BM_GETCHECK, 0, 0) !=
BST_UNCHECKED);
SetLocalTimeZone(GetDlgItem(hwndDlg, IDC_TIMEZONELIST));
SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, PSNRET_NOERROR);
return TRUE;
diff --git a/dll/win32/syssetup/CMakeLists.txt b/dll/win32/syssetup/CMakeLists.txt
index e3b44d1e6b7..703c1d411c6 100644
--- a/dll/win32/syssetup/CMakeLists.txt
+++ b/dll/win32/syssetup/CMakeLists.txt
@@ -1,4 +1,6 @@
+include_directories(${REACTOS_SOURCE_DIR}/sdk/lib/tzlib)
+
spec2def(syssetup.dll syssetup.spec)
list(APPEND SOURCE
@@ -20,6 +22,6 @@ add_library(syssetup MODULE
add_pch(syssetup precomp.h SOURCE)
set_module_type(syssetup win32dll UNICODE)
-target_link_libraries(syssetup uuid wine ${PSEH_LIB})
+target_link_libraries(syssetup uuid wine tzlib ${PSEH_LIB})
add_importlibs(syssetup advapi32 gdi32 user32 samlib userenv comctl32 setupapi rpcrt4
ole32 shell32 shlwapi msvcrt kernel32 ntdll)
add_cd_file(TARGET syssetup DESTINATION reactos/system32 FOR all)
diff --git a/dll/win32/syssetup/wizard.c b/dll/win32/syssetup/wizard.c
index 589a6101ab6..386b04bf356 100644
--- a/dll/win32/syssetup/wizard.c
+++ b/dll/win32/syssetup/wizard.c
@@ -19,6 +19,8 @@
#include <wincon.h>
#include <shlobj.h>
+#include <tzlib.h>
+
#define NDEBUG
#include <debug.h>
@@ -45,6 +47,17 @@ typedef struct _REGISTRATIONDATA
PVOID DefaultContext;
} REGISTRATIONDATA, *PREGISTRATIONDATA;
+typedef struct _TIMEZONE_ENTRY
+{
+ struct _TIMEZONE_ENTRY *Prev;
+ struct _TIMEZONE_ENTRY *Next;
+ WCHAR Description[128]; /* 'Display' */
+ WCHAR StandardName[32]; /* 'Std' */
+ WCHAR DaylightName[32]; /* 'Dlt' */
+ REG_TZI_FORMAT TimezoneInfo; /* 'TZI' */
+ ULONG Index;
+} TIMEZONE_ENTRY, *PTIMEZONE_ENTRY;
+
/* FUNCTIONS ****************************************************************/
@@ -1237,165 +1250,92 @@ GetLargerTimeZoneEntry(PSETUPDATA SetupData, DWORD Index)
return NULL;
}
-
-static VOID
-CreateTimeZoneList(PSETUPDATA SetupData)
+static LONG
+RetrieveTimeZone(
+ IN HKEY hZoneKey,
+ IN PVOID Context)
{
- WCHAR szKeyName[256];
- DWORD dwIndex;
- DWORD dwNameSize;
- DWORD dwValueSize;
LONG lError;
- HKEY hZonesKey;
- HKEY hZoneKey;
-
+ PSETUPDATA SetupData = (PSETUPDATA)Context;
PTIMEZONE_ENTRY Entry;
PTIMEZONE_ENTRY Current;
+ ULONG DescriptionSize;
+ ULONG StandardNameSize;
+ ULONG DaylightNameSize;
- if (RegOpenKeyExW(HKEY_LOCAL_MACHINE,
- L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Time
Zones",
- 0,
- KEY_ALL_ACCESS,
- &hZonesKey))
- return;
-
- dwIndex = 0;
- while (TRUE)
- {
- dwNameSize = 256 * sizeof(WCHAR);
- lError = RegEnumKeyExW(hZonesKey,
- dwIndex,
- szKeyName,
- &dwNameSize,
- NULL,
- NULL,
- NULL,
- NULL);
- if (lError != ERROR_SUCCESS && lError != ERROR_MORE_DATA)
- break;
-
- if (RegOpenKeyExW(hZonesKey,
- szKeyName,
- 0,
- KEY_ALL_ACCESS,
- &hZoneKey))
- break;
-
- Entry = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(TIMEZONE_ENTRY));
- if (Entry == NULL)
- {
- RegCloseKey(hZoneKey);
- break;
- }
-
- dwValueSize = 64 * sizeof(WCHAR);
- if (RegQueryValueExW(hZoneKey,
- L"Display",
- NULL,
- NULL,
- (LPBYTE)&Entry->Description,
- &dwValueSize))
- {
- RegCloseKey(hZoneKey);
- break;
- }
-
- dwValueSize = 32 * sizeof(WCHAR);
- if (RegQueryValueExW(hZoneKey,
- L"Std",
- NULL,
- NULL,
- (LPBYTE)&Entry->StandardName,
- &dwValueSize))
- {
- RegCloseKey(hZoneKey);
- break;
- }
-
- dwValueSize = 32 * sizeof(WCHAR);
- if (RegQueryValueExW(hZoneKey,
- L"Dlt",
- NULL,
- NULL,
- (LPBYTE)&Entry->DaylightName,
- &dwValueSize))
- {
- RegCloseKey(hZoneKey);
- break;
- }
+ Entry = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(TIMEZONE_ENTRY));
+ if (Entry == NULL)
+ {
+ return ERROR_NOT_ENOUGH_MEMORY;
+ }
- dwValueSize = sizeof(DWORD);
- if (RegQueryValueExW(hZoneKey,
- L"Index",
- NULL,
- NULL,
- (LPBYTE)&Entry->Index,
- &dwValueSize))
- {
- RegCloseKey(hZoneKey);
- break;
- }
+ DescriptionSize = sizeof(Entry->Description);
+ StandardNameSize = sizeof(Entry->StandardName);
+ DaylightNameSize = sizeof(Entry->DaylightName);
- dwValueSize = sizeof(TZ_INFO);
- if (RegQueryValueExW(hZoneKey,
- L"TZI",
- NULL,
- NULL,
- (LPBYTE)&Entry->TimezoneInfo,
- &dwValueSize))
- {
- RegCloseKey(hZoneKey);
- break;
- }
-
- RegCloseKey(hZoneKey);
+ lError = QueryTimeZoneData(hZoneKey,
+ &Entry->Index,
+ &Entry->TimezoneInfo,
+ Entry->Description,
+ &DescriptionSize,
+ Entry->StandardName,
+ &StandardNameSize,
+ Entry->DaylightName,
+ &DaylightNameSize);
+ if (lError != ERROR_SUCCESS)
+ {
+ HeapFree(GetProcessHeap(), 0, Entry);
+ return lError;
+ }
- if (SetupData->TimeZoneListHead == NULL &&
- SetupData->TimeZoneListTail == NULL)
- {
- Entry->Prev = NULL;
- Entry->Next = NULL;
- SetupData->TimeZoneListHead = Entry;
- SetupData->TimeZoneListTail = Entry;
- }
- else
+ if (SetupData->TimeZoneListHead == NULL &&
+ SetupData->TimeZoneListTail == NULL)
+ {
+ Entry->Prev = NULL;
+ Entry->Next = NULL;
+ SetupData->TimeZoneListHead = Entry;
+ SetupData->TimeZoneListTail = Entry;
+ }
+ else
+ {
+ Current = GetLargerTimeZoneEntry(SetupData, Entry->Index);
+ if (Current != NULL)
{
- Current = GetLargerTimeZoneEntry(SetupData, Entry->Index);
- if (Current != NULL)
+ if (Current == SetupData->TimeZoneListHead)
{
- if (Current == SetupData->TimeZoneListHead)
- {
- /* Prepend to head */
- Entry->Prev = NULL;
- Entry->Next = SetupData->TimeZoneListHead;
- SetupData->TimeZoneListHead->Prev = Entry;
- SetupData->TimeZoneListHead = Entry;
- }
- else
- {
- /* Insert before current */
- Entry->Prev = Current->Prev;
- Entry->Next = Current;
- Current->Prev->Next = Entry;
- Current->Prev = Entry;
- }
+ /* Prepend to head */
+ Entry->Prev = NULL;
+ Entry->Next = SetupData->TimeZoneListHead;
+ SetupData->TimeZoneListHead->Prev = Entry;
+ SetupData->TimeZoneListHead = Entry;
}
else
{
- /* Append to tail */
- Entry->Prev = SetupData->TimeZoneListTail;
- Entry->Next = NULL;
- SetupData->TimeZoneListTail->Next = Entry;
- SetupData->TimeZoneListTail = Entry;
+ /* Insert before current */
+ Entry->Prev = Current->Prev;
+ Entry->Next = Current;
+ Current->Prev->Next = Entry;
+ Current->Prev = Entry;
}
}
-
- dwIndex++;
+ else
+ {
+ /* Append to tail */
+ Entry->Prev = SetupData->TimeZoneListTail;
+ Entry->Next = NULL;
+ SetupData->TimeZoneListTail->Next = Entry;
+ SetupData->TimeZoneListTail = Entry;
+ }
}
- RegCloseKey(hZonesKey);
+ return ERROR_SUCCESS;
}
+static VOID
+CreateTimeZoneList(PSETUPDATA SetupData)
+{
+ EnumerateTimeZoneList(RetrieveTimeZone, SetupData);
+}
static VOID
DestroyTimeZoneList(PSETUPDATA SetupData)
@@ -1418,117 +1358,6 @@ DestroyTimeZoneList(PSETUPDATA SetupData)
SetupData->TimeZoneListTail = NULL;
}
-static BOOL
-GetTimeZoneListIndex(LPDWORD lpIndex)
-{
- WCHAR szLanguageIdString[9];
- HKEY hKey;
- DWORD dwValueSize;
- DWORD Length;
- LPWSTR Buffer;
- LPWSTR Ptr;
- LPWSTR End;
- BOOL bFound = FALSE;
- unsigned long iLanguageID;
-
- if (*lpIndex == -1)
- {
- *lpIndex = 85; /* fallback to GMT time zone */
-
- if (RegOpenKeyExW(HKEY_LOCAL_MACHINE,
-
L"SYSTEM\\CurrentControlSet\\Control\\NLS\\Language",
- 0,
- KEY_ALL_ACCESS,
- &hKey))
- return FALSE;
-
- dwValueSize = 9 * sizeof(WCHAR);
- if (RegQueryValueExW(hKey,
- L"Default",
- NULL,
- NULL,
- (LPBYTE)szLanguageIdString,
- &dwValueSize))
- {
- RegCloseKey(hKey);
- return FALSE;
- }
-
- iLanguageID = wcstoul(szLanguageIdString, NULL, 16);
- RegCloseKey(hKey);
- }
- else
- {
- iLanguageID = *lpIndex;
- }
-
- if (RegOpenKeyExW(HKEY_LOCAL_MACHINE,
- L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Time
Zones",
- 0,
- KEY_ALL_ACCESS,
- &hKey))
- return FALSE;
-
- dwValueSize = 0;
- if (RegQueryValueExW(hKey,
- L"IndexMapping",
- NULL,
- NULL,
- NULL,
- &dwValueSize))
- {
- RegCloseKey(hKey);
- return FALSE;
- }
-
- Buffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwValueSize);
- if (Buffer == NULL)
- {
- RegCloseKey(hKey);
- return FALSE;
- }
-
- if (RegQueryValueExW(hKey,
- L"IndexMapping",
- NULL,
- NULL,
- (LPBYTE)Buffer,
- &dwValueSize))
- {
- HeapFree(GetProcessHeap(), 0, Buffer);
- RegCloseKey(hKey);
- return FALSE;
- }
-
- RegCloseKey(hKey);
-
- Ptr = Buffer;
- while (*Ptr != 0)
- {
- Length = wcslen(Ptr);
- if (wcstoul(Ptr, NULL, 16) == iLanguageID)
- bFound = TRUE;
-
- Ptr = Ptr + Length + 1;
- if (*Ptr == 0)
- break;
-
- if (bFound)
- {
- *lpIndex = wcstoul(Ptr, &End, 10);
- HeapFree(GetProcessHeap(), 0, Buffer);
- return TRUE;
- }
-
- Length = wcslen(Ptr);
- Ptr = Ptr + Length + 1;
- }
-
- HeapFree(GetProcessHeap(), 0, Buffer);
-
- return FALSE;
-}
-
static VOID
ShowTimeZoneList(HWND hwnd, PSETUPDATA SetupData, DWORD dwEntryIndex)
@@ -1634,32 +1463,6 @@ GetLocalSystemTime(HWND hwnd, PSETUPDATA SetupData)
}
-static VOID
-SetAutoDaylightInfo(HWND hwnd)
-{
- HKEY hKey;
- DWORD dwValue = 1;
-
- if (SendMessage(hwnd, BM_GETCHECK, 0, 0) == BST_UNCHECKED)
- {
- if (RegOpenKeyExW(HKEY_LOCAL_MACHINE,
-
L"SYSTEM\\CurrentControlSet\\Control\\TimeZoneInformation",
- 0,
- KEY_SET_VALUE,
- &hKey))
- return;
-
- RegSetValueExW(hKey,
- L"DisableAutoDaylightTimeSet",
- 0,
- REG_DWORD,
- (LPBYTE)&dwValue,
- sizeof(DWORD));
- RegCloseKey(hKey);
- }
-}
-
-
static BOOL
SetSystemLocalTime(HWND hwnd, PSETUPDATA SetupData)
{
@@ -1696,7 +1499,8 @@ WriteDateTimeSettings(HWND hwndDlg, PSETUPDATA SetupData)
SetLocalTimeZone(GetDlgItem(hwndDlg, IDC_TIMEZONELIST),
SetupData);
- SetAutoDaylightInfo(GetDlgItem(hwndDlg, IDC_AUTODAYLIGHT));
+ SetAutoDaylight(SendDlgItemMessage(hwndDlg, IDC_AUTODAYLIGHT,
+ BM_GETCHECK, 0, 0) != BST_UNCHECKED);
if (!SetSystemLocalTime(hwndDlg, SetupData))
{
if (0 == LoadStringW(hDllInstance, IDS_REACTOS_SETUP, Title, ARRAYSIZE(Title)))
@@ -1730,6 +1534,7 @@ DateTimePageDlgProc(HWND hwndDlg,
switch (uMsg)
{
case WM_INITDIALOG:
+ {
/* Save pointer to the global setup data */
SetupData = (PSETUPDATA)((LPPROPSHEETPAGE)lParam)->lParam;
SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (DWORD_PTR)SetupData);
@@ -1754,6 +1559,7 @@ DateTimePageDlgProc(HWND hwndDlg,
SendDlgItemMessage(hwndDlg, IDC_AUTODAYLIGHT, BM_SETCHECK,
(WPARAM)BST_CHECKED, 0);
}
break;
+ }
case WM_TIMER:
UpdateLocalSystemTime(hwndDlg);
diff --git a/sdk/include/reactos/libs/syssetup/syssetup.h
b/sdk/include/reactos/libs/syssetup/syssetup.h
index d22ad08ac79..adb924e390d 100644
--- a/sdk/include/reactos/libs/syssetup/syssetup.h
+++ b/sdk/include/reactos/libs/syssetup/syssetup.h
@@ -23,27 +23,6 @@
#ifndef __SYSSETUP_H_INCLUDED__
#define __SYSSETUP_H_INCLUDED__
-// See also dll/cpl/timedate/timezone.c
-typedef struct _TZ_INFO
-{
- LONG Bias;
- LONG StandardBias;
- LONG DaylightBias;
- SYSTEMTIME StandardDate;
- SYSTEMTIME DaylightDate;
-} TZ_INFO, *PTZ_INFO;
-
-typedef struct _TIMEZONE_ENTRY
-{
- struct _TIMEZONE_ENTRY *Prev;
- struct _TIMEZONE_ENTRY *Next;
- WCHAR Description[64]; /* 'Display' */
- WCHAR StandardName[32]; /* 'Std' */
- WCHAR DaylightName[32]; /* 'Dlt' */
- TZ_INFO TimezoneInfo; /* 'TZI' */
- ULONG Index;
-} TIMEZONE_ENTRY, *PTIMEZONE_ENTRY;
-
typedef enum _PRODUCT_OPTION
{
PRODUCT_OPTION_SERVER,
@@ -67,8 +46,8 @@ typedef struct _SETUPDATA
BOOL DisableGeckoInst;
SYSTEMTIME SystemTime;
- PTIMEZONE_ENTRY TimeZoneListHead;
- PTIMEZONE_ENTRY TimeZoneListTail;
+ struct _TIMEZONE_ENTRY* TimeZoneListHead;
+ struct _TIMEZONE_ENTRY* TimeZoneListTail;
DWORD TimeZoneIndex;
DWORD DisableAutoDaylightTimeSet;
LCID LocaleID;
diff --git a/sdk/lib/CMakeLists.txt b/sdk/lib/CMakeLists.txt
index c9f4e396049..60b2844566b 100644
--- a/sdk/lib/CMakeLists.txt
+++ b/sdk/lib/CMakeLists.txt
@@ -46,6 +46,7 @@ add_subdirectory(skiplist)
add_subdirectory(strmiids)
add_subdirectory(smlib)
add_subdirectory(tdilib)
+add_subdirectory(tzlib)
add_subdirectory(udmihelp)
add_subdirectory(uuid)
add_subdirectory(wdmguid)
diff --git a/sdk/lib/tzlib/CMakeLists.txt b/sdk/lib/tzlib/CMakeLists.txt
new file mode 100644
index 00000000000..a4606afe5df
--- /dev/null
+++ b/sdk/lib/tzlib/CMakeLists.txt
@@ -0,0 +1,3 @@
+
+add_library(tzlib tzlib.c)
+add_dependencies(tzlib xdk)
diff --git a/sdk/lib/tzlib/tzlib.c b/sdk/lib/tzlib/tzlib.c
new file mode 100644
index 00000000000..93c33a3fb3a
--- /dev/null
+++ b/sdk/lib/tzlib/tzlib.c
@@ -0,0 +1,352 @@
+/*
+ * PROJECT: ReactOS TimeZone Utilities Library
+ * LICENSE: GPL-2.0 (
https://spdx.org/licenses/GPL-2.0)
+ * PURPOSE: Provides time-zone utility wrappers around Win32 functions,
+ * that are used by different ReactOS modules such as
+ * timedate.cpl, syssetup.dll.
+ * COPYRIGHT: Copyright 2004-2005 Eric Kohl
+ * Copyright 2016 Carlo Bramini
+ * Copyright 2020 Hermes Belusca-Maito
+ */
+
+#include <stdlib.h>
+#include <windef.h>
+#include <winbase.h>
+#include <winreg.h>
+
+#include "tzlib.h"
+
+BOOL
+GetTimeZoneListIndex(
+ IN OUT PULONG pIndex)
+{
+ LONG lError;
+ HKEY hKey;
+ DWORD dwType;
+ DWORD dwValueSize;
+ DWORD Length;
+ LPWSTR Buffer;
+ LPWSTR Ptr, End;
+ BOOL bFound = FALSE;
+ unsigned long iLanguageID;
+ WCHAR szLanguageIdString[9];
+
+ if (*pIndex == -1)
+ {
+ *pIndex = 85; /* fallback to GMT time zone */
+
+ lError = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
+
L"SYSTEM\\CurrentControlSet\\Control\\NLS\\Language",
+ 0,
+ KEY_QUERY_VALUE,
+ &hKey);
+ if (lError != ERROR_SUCCESS)
+ {
+ return FALSE;
+ }
+
+ dwValueSize = sizeof(szLanguageIdString);
+ lError = RegQueryValueExW(hKey,
+ L"Default",
+ NULL,
+ NULL,
+ (LPBYTE)szLanguageIdString,
+ &dwValueSize);
+ if (lError != ERROR_SUCCESS)
+ {
+ RegCloseKey(hKey);
+ return FALSE;
+ }
+
+ iLanguageID = wcstoul(szLanguageIdString, NULL, 16);
+ RegCloseKey(hKey);
+ }
+ else
+ {
+ iLanguageID = *pIndex;
+ }
+
+ lError = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
+ L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Time
Zones",
+ 0,
+ KEY_QUERY_VALUE,
+ &hKey);
+ if (lError != ERROR_SUCCESS)
+ {
+ return FALSE;
+ }
+
+ dwValueSize = 0;
+ lError = RegQueryValueExW(hKey,
+ L"IndexMapping",
+ NULL,
+ &dwType,
+ NULL,
+ &dwValueSize);
+ if ((lError != ERROR_SUCCESS) || (dwType != REG_MULTI_SZ))
+ {
+ RegCloseKey(hKey);
+ return FALSE;
+ }
+
+ Buffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwValueSize);
+ if (Buffer == NULL)
+ {
+ RegCloseKey(hKey);
+ return FALSE;
+ }
+
+ lError = RegQueryValueExW(hKey,
+ L"IndexMapping",
+ NULL,
+ &dwType,
+ (LPBYTE)Buffer,
+ &dwValueSize);
+
+ RegCloseKey(hKey);
+
+ if ((lError != ERROR_SUCCESS) || (dwType != REG_MULTI_SZ))
+ {
+ HeapFree(GetProcessHeap(), 0, Buffer);
+ return FALSE;
+ }
+
+ Ptr = Buffer;
+ while (*Ptr != 0)
+ {
+ Length = wcslen(Ptr);
+ if (wcstoul(Ptr, NULL, 16) == iLanguageID)
+ bFound = TRUE;
+
+ Ptr = Ptr + Length + 1;
+ if (*Ptr == 0)
+ break;
+
+ if (bFound)
+ {
+ *pIndex = wcstoul(Ptr, &End, 10);
+ HeapFree(GetProcessHeap(), 0, Buffer);
+ return TRUE;
+ }
+
+ Length = wcslen(Ptr);
+ Ptr = Ptr + Length + 1;
+ }
+
+ HeapFree(GetProcessHeap(), 0, Buffer);
+ return FALSE;
+}
+
+LONG
+QueryTimeZoneData(
+ IN HKEY hZoneKey,
+ OUT PULONG Index OPTIONAL,
+ OUT PREG_TZI_FORMAT TimeZoneInfo,
+ OUT PWCHAR Description OPTIONAL,
+ IN OUT PULONG DescriptionSize OPTIONAL,
+ OUT PWCHAR StandardName OPTIONAL,
+ IN OUT PULONG StandardNameSize OPTIONAL,
+ OUT PWCHAR DaylightName OPTIONAL,
+ IN OUT PULONG DaylightNameSize OPTIONAL)
+{
+ LONG lError;
+ DWORD dwValueSize;
+
+ if (Description && DescriptionSize && *DescriptionSize > 0)
+ {
+ lError = RegQueryValueExW(hZoneKey,
+ L"Display",
+ NULL,
+ NULL,
+ (LPBYTE)Description,
+ DescriptionSize);
+ if (lError != ERROR_SUCCESS)
+ return lError;
+ }
+
+ if (StandardName && StandardNameSize && *StandardNameSize > 0)
+ {
+ lError = RegQueryValueExW(hZoneKey,
+ L"Std",
+ NULL,
+ NULL,
+ (LPBYTE)StandardName,
+ StandardNameSize);
+ if (lError != ERROR_SUCCESS)
+ return lError;
+ }
+
+ if (DaylightName && DaylightNameSize && *DaylightNameSize > 0)
+ {
+ lError = RegQueryValueExW(hZoneKey,
+ L"Dlt",
+ NULL,
+ NULL,
+ (LPBYTE)DaylightName,
+ DaylightNameSize);
+ if (lError != ERROR_SUCCESS)
+ return lError;
+ }
+
+ if (Index)
+ {
+ dwValueSize = sizeof(*Index);
+ lError = RegQueryValueExW(hZoneKey,
+ L"Index",
+ NULL,
+ NULL,
+ (LPBYTE)Index,
+ &dwValueSize);
+ if (lError != ERROR_SUCCESS)
+ return lError;
+ }
+
+ dwValueSize = sizeof(*TimeZoneInfo);
+ lError = RegQueryValueExW(hZoneKey,
+ L"TZI",
+ NULL,
+ NULL,
+ (LPBYTE)TimeZoneInfo,
+ &dwValueSize);
+ return lError;
+}
+
+//
+// NOTE: Very similar to the EnumDynamicTimeZoneInformation() function
+// introduced in Windows 8.
+//
+VOID
+EnumerateTimeZoneList(
+ IN PENUM_TIMEZONE_CALLBACK Callback,
+ IN PVOID Context OPTIONAL)
+{
+ LONG lError;
+ HKEY hZonesKey;
+ HKEY hZoneKey;
+ DWORD dwIndex;
+ DWORD dwNameSize;
+ WCHAR szKeyName[256];
+
+ /* Open the registry key containing the list of time zones */
+ lError = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
+ L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Time
Zones",
+ 0,
+ KEY_ENUMERATE_SUB_KEYS,
+ &hZonesKey);
+ if (lError != ERROR_SUCCESS)
+ return;
+
+ /* Enumerate it */
+ for (dwIndex = 0; ; dwIndex++)
+ {
+ dwNameSize = sizeof(szKeyName);
+ lError = RegEnumKeyExW(hZonesKey,
+ dwIndex,
+ szKeyName,
+ &dwNameSize,
+ NULL,
+ NULL,
+ NULL,
+ NULL);
+ // if (lError != ERROR_SUCCESS && lError != ERROR_MORE_DATA)
+ if (lError == ERROR_NO_MORE_ITEMS)
+ break;
+
+ /* Open the time zone sub-key */
+ if (RegOpenKeyExW(hZonesKey,
+ szKeyName,
+ 0,
+ KEY_QUERY_VALUE,
+ &hZoneKey))
+ {
+ /* We failed, continue with another sub-key */
+ continue;
+ }
+
+ /* Call the user-provided callback */
+ lError = Callback(hZoneKey, Context);
+ // lError = QueryTimeZoneData(hZoneKey, Context);
+
+ RegCloseKey(hZoneKey);
+ }
+
+ RegCloseKey(hZonesKey);
+}
+
+// Returns TRUE if AutoDaylight is ON.
+// Returns FALSE if AutoDaylight is OFF.
+BOOL
+GetAutoDaylight(VOID)
+{
+ LONG lError;
+ HKEY hKey;
+ DWORD dwType;
+ DWORD dwDisabled;
+ DWORD dwValueSize;
+
+ lError = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
+
L"SYSTEM\\CurrentControlSet\\Control\\TimeZoneInformation",
+ 0,
+ KEY_QUERY_VALUE,
+ &hKey);
+ if (lError != ERROR_SUCCESS)
+ return FALSE;
+
+ // NOTE: On Vista+: REG_DWORD "DynamicDaylightTimeDisabled"
+ dwValueSize = sizeof(dwDisabled);
+ lError = RegQueryValueExW(hKey,
+ L"DisableAutoDaylightTimeSet",
+ NULL,
+ &dwType,
+ (LPBYTE)&dwDisabled,
+ &dwValueSize);
+
+ RegCloseKey(hKey);
+
+ if ((lError != ERROR_SUCCESS) || (dwType != REG_DWORD) || (dwValueSize !=
sizeof(dwDisabled)))
+ {
+ /*
+ * The call failed (non zero) because the registry value isn't available,
+ * which means auto-daylight shouldn't be disabled.
+ */
+ dwDisabled = FALSE;
+ }
+
+ return !dwDisabled;
+}
+
+VOID
+SetAutoDaylight(
+ IN BOOL EnableAutoDaylightTime)
+{
+ LONG lError;
+ HKEY hKey;
+ DWORD dwDisabled = TRUE;
+
+ lError = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
+
L"SYSTEM\\CurrentControlSet\\Control\\TimeZoneInformation",
+ 0,
+ KEY_SET_VALUE,
+ &hKey);
+ if (lError != ERROR_SUCCESS)
+ return;
+
+ if (!EnableAutoDaylightTime)
+ {
+ /* Auto-Daylight disabled: set the value to TRUE */
+ // NOTE: On Vista+: REG_DWORD "DynamicDaylightTimeDisabled"
+ RegSetValueExW(hKey,
+ L"DisableAutoDaylightTimeSet",
+ 0,
+ REG_DWORD,
+ (LPBYTE)&dwDisabled,
+ sizeof(dwDisabled));
+ }
+ else
+ {
+ /* Auto-Daylight enabled: just delete the value */
+ RegDeleteValueW(hKey, L"DisableAutoDaylightTimeSet");
+ }
+
+ RegCloseKey(hKey);
+}
diff --git a/sdk/lib/tzlib/tzlib.h b/sdk/lib/tzlib/tzlib.h
new file mode 100644
index 00000000000..9938c5ab473
--- /dev/null
+++ b/sdk/lib/tzlib/tzlib.h
@@ -0,0 +1,56 @@
+/*
+ * PROJECT: ReactOS TimeZone Utilities Library
+ * LICENSE: GPL-2.0 (
https://spdx.org/licenses/GPL-2.0)
+ * PURPOSE: Provides time-zone utility wrappers around Win32 functions,
+ * that are used by different ReactOS modules such as
+ * timedate.cpl, syssetup.dll.
+ * COPYRIGHT: Copyright 2004-2005 Eric Kohl
+ * Copyright 2016 Carlo Bramini
+ * Copyright 2020 Hermes Belusca-Maito
+ */
+
+#pragma once
+
+typedef struct _REG_TZI_FORMAT
+{
+ LONG Bias;
+ LONG StandardBias;
+ LONG DaylightBias;
+ SYSTEMTIME StandardDate;
+ SYSTEMTIME DaylightDate;
+} REG_TZI_FORMAT, *PREG_TZI_FORMAT;
+
+typedef LONG
+(*PENUM_TIMEZONE_CALLBACK)(
+ IN HKEY hZoneKey,
+ IN PVOID Context OPTIONAL);
+
+BOOL
+GetTimeZoneListIndex(
+ IN OUT PULONG pIndex);
+
+LONG
+QueryTimeZoneData(
+ IN HKEY hZoneKey,
+ OUT PULONG Index OPTIONAL,
+ OUT PREG_TZI_FORMAT TimeZoneInfo,
+ OUT PWCHAR Description OPTIONAL,
+ IN OUT PULONG DescriptionSize OPTIONAL,
+ OUT PWCHAR StandardName OPTIONAL,
+ IN OUT PULONG StandardNameSize OPTIONAL,
+ OUT PWCHAR DaylightName OPTIONAL,
+ IN OUT PULONG DaylightNameSize OPTIONAL);
+
+VOID
+EnumerateTimeZoneList(
+ IN PENUM_TIMEZONE_CALLBACK Callback,
+ IN PVOID Context OPTIONAL);
+
+// Returns TRUE if AutoDaylight is ON.
+// Returns FALSE if AutoDaylight is OFF.
+BOOL
+GetAutoDaylight(VOID);
+
+VOID
+SetAutoDaylight(
+ IN BOOL EnableAutoDaylightTime);