https://git.reactos.org/?p=reactos.git;a=commitdiff;h=7c3e96a26a15de8930cddf...
commit 7c3e96a26a15de8930cddf670d43bbf50c16bfad Author: Hermès Bélusca-Maïto hermes.belusca-maito@reactos.org AuthorDate: Sun Apr 19 17:48:25 2020 +0200 Commit: Hermès Bélusca-Maïto hermes.belusca-maito@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);