Hello all,
Here comes V2. Learning from my previous mistakes, I now took extra care with my coding style, and made sure no unused code was left in any of the patches.
This patchset improves Wine both by increasing convenience and preventing bugs from happening. Windows doesn't allow GeoIDs to _not_ be set, and at least one app is crashing because of this; this bug cannot be reproduced on Windows. (Win10 tries really hard to make sure a GeoID is always set!)
But before we can do that, we must bring the relevant infrastructure up to spec. (It's currently rather subpar...)
Patches 1 through 5 bring important functions up to spec; Patch 6 implements the autoconfigure; Patch 7 are the conformance tests.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=46196 Signed-off-by: João Diogo Craveiro Ferreira devilj@outlook.pt --- Supersedes: 171821
João Diogo Craveiro Ferreira (7): kernel32: Move Get/SetUserGeoID() to after the geoinfo struct. kernel32: Handle GEOCLASS_REGION in Get/SetUserGeoID. kernel32: Implement SetUserGeoName() and clean-up locale.c. kernel32: Implement GetUserDefaultGeoName(). kernel32: Make GetUserGeoID() pretend we set a GeoID even if we didn't. kernel32: Autoinitialize geographic values when launching any program. kernel32/tests: Test GetUserGeoID(), GetUserDefaultGeoName().
dlls/kernel32/kernel32.spec | 2 + dlls/kernel32/kernel_main.c | 3 + dlls/kernel32/kernel_private.h | 1 + dlls/kernel32/locale.c | 621 ++++++++++++++++++++++++++------- dlls/kernel32/tests/locale.c | 110 ++++++ include/winnls.h | 2 + 6 files changed, 612 insertions(+), 127 deletions(-)
Necessary for proper implementation of next patches in series.
Changed style to follow new rules because copy-and-pasting. No changes to data or behaviour were made.
Signed-off-by: João Diogo Craveiro Ferreira devilj@outlook.pt --- Supersedes: 170932, 171822 V2: Change coding style in addition to copy-pasting. --- dlls/kernel32/locale.c | 149 ++++++++++++++++++++--------------------- 1 file changed, 74 insertions(+), 75 deletions(-)
diff --git a/dlls/kernel32/locale.c b/dlls/kernel32/locale.c index c690aa8d5e..7c97915199 100644 --- a/dlls/kernel32/locale.c +++ b/dlls/kernel32/locale.c @@ -3643,81 +3643,6 @@ BOOL WINAPI InvalidateNLSCache(void) return FALSE; }
-/****************************************************************************** - * GetUserGeoID (KERNEL32.@) - */ -GEOID WINAPI GetUserGeoID( GEOCLASS GeoClass ) -{ - GEOID ret = GEOID_NOT_AVAILABLE; - static const WCHAR geoW[] = {'G','e','o',0}; - static const WCHAR nationW[] = {'N','a','t','i','o','n',0}; - WCHAR bufferW[40], *end; - DWORD count; - HANDLE hkey, hSubkey = 0; - UNICODE_STRING keyW; - const KEY_VALUE_PARTIAL_INFORMATION *info = (KEY_VALUE_PARTIAL_INFORMATION *)bufferW; - RtlInitUnicodeString( &keyW, nationW ); - count = sizeof(bufferW); - - if(!(hkey = create_registry_key())) return ret; - - switch( GeoClass ){ - case GEOCLASS_NATION: - if ((hSubkey = NLS_RegOpenKey(hkey, geoW))) - { - if((NtQueryValueKey(hSubkey, &keyW, KeyValuePartialInformation, - bufferW, count, &count) == STATUS_SUCCESS ) && info->DataLength) - ret = strtolW((LPCWSTR)info->Data, &end, 10); - } - break; - case GEOCLASS_REGION: - FIXME("GEOCLASS_REGION not handled yet\n"); - break; - } - - NtClose(hkey); - if (hSubkey) NtClose(hSubkey); - return ret; -} - -/****************************************************************************** - * SetUserGeoID (KERNEL32.@) - */ -BOOL WINAPI SetUserGeoID( GEOID GeoID ) -{ - static const WCHAR geoW[] = {'G','e','o',0}; - static const WCHAR nationW[] = {'N','a','t','i','o','n',0}; - static const WCHAR formatW[] = {'%','i',0}; - UNICODE_STRING nameW,keyW; - WCHAR bufferW[10]; - OBJECT_ATTRIBUTES attr; - HANDLE hkey; - - if(!(hkey = create_registry_key())) return FALSE; - - attr.Length = sizeof(attr); - attr.RootDirectory = hkey; - attr.ObjectName = &nameW; - attr.Attributes = 0; - attr.SecurityDescriptor = NULL; - attr.SecurityQualityOfService = NULL; - RtlInitUnicodeString( &nameW, geoW ); - RtlInitUnicodeString( &keyW, nationW ); - - if (NtCreateKey( &hkey, KEY_ALL_ACCESS, &attr, 0, NULL, 0, NULL ) != STATUS_SUCCESS) - - { - NtClose(attr.RootDirectory); - return FALSE; - } - - sprintfW(bufferW, formatW, GeoID); - NtSetValueKey(hkey, &keyW, 0, REG_SZ, bufferW, (strlenW(bufferW) + 1) * sizeof(WCHAR)); - NtClose(attr.RootDirectory); - NtClose(hkey); - return TRUE; -} - /****************************************************************************** * EnumUILanguagesA (KERNEL32.@) */ @@ -4069,6 +3994,80 @@ static const struct geoinfo_t *get_geoinfo_dataptr(GEOID geoid) return NULL; }
+/****************************************************************************** + * GetUserGeoID (KERNEL32.@) + */ +GEOID WINAPI GetUserGeoID(GEOCLASS geoclass) +{ + GEOID ret = GEOID_NOT_AVAILABLE; + static const WCHAR geoW[] = {'G','e','o',0}; + static const WCHAR nationW[] = {'N','a','t','i','o','n',0}; + WCHAR bufferW[40], *end; + HANDLE hkey, hsubkey = 0; + UNICODE_STRING keyW; + const KEY_VALUE_PARTIAL_INFORMATION *info = (KEY_VALUE_PARTIAL_INFORMATION *)bufferW; + DWORD count = sizeof(bufferW); + RtlInitUnicodeString(&keyW, nationW); + + if (!(hkey = create_registry_key())) return ret; + + switch (geoclass) { + case GEOCLASS_NATION: + if ((hsubkey = NLS_RegOpenKey(hkey, geoW))) + { + if ((NtQueryValueKey(hsubkey, &keyW, KeyValuePartialInformation, + bufferW, count, &count) == STATUS_SUCCESS ) && info->DataLength) + ret = strtolW((const WCHAR*)info->Data, &end, 10); + } + break; + case GEOCLASS_REGION: + FIXME("GEOCLASS_REGION not handled yet\n"); + break; + } + + NtClose(hkey); + if (hsubkey) NtClose(hsubkey); + return ret; +} + +/****************************************************************************** + * SetUserGeoID (KERNEL32.@) + */ +BOOL WINAPI SetUserGeoID(GEOID geoid) +{ + static const WCHAR geoW[] = {'G','e','o',0}; + static const WCHAR nationW[] = {'N','a','t','i','o','n',0}; + static const WCHAR formatW[] = {'%','i',0}; + UNICODE_STRING nameW, keyW; + WCHAR bufferW[10]; + OBJECT_ATTRIBUTES attr; + HANDLE hkey; + + if(!(hkey = create_registry_key())) return FALSE; + + attr.Length = sizeof(attr); + attr.RootDirectory = hkey; + attr.ObjectName = &nameW; + attr.Attributes = 0; + attr.SecurityDescriptor = NULL; + attr.SecurityQualityOfService = NULL; + RtlInitUnicodeString(&nameW, geoW); + RtlInitUnicodeString(&keyW, nationW); + + if (NtCreateKey(&hkey, KEY_ALL_ACCESS, &attr, 0, NULL, 0, NULL) != STATUS_SUCCESS) + + { + NtClose(attr.RootDirectory); + return FALSE; + } + + sprintfW(bufferW, formatW, geoid); + NtSetValueKey(hkey, &keyW, 0, REG_SZ, bufferW, (strlenW(bufferW) + 1) * sizeof(WCHAR)); + NtClose(attr.RootDirectory); + NtClose(hkey); + return TRUE; +} + /****************************************************************************** * GetGeoInfoW (KERNEL32.@) */
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=58693
Your paranoid android.
=== debian10 (32 bit Chinese:China report) ===
kernel32: comm.c:919: Test failed: OutQueue should not be empty debugger.c:320: Test failed: GetThreadContext failed: 5
=== debian10 (64 bit WoW report) ===
kernel32: debugger.c:320: Test failed: GetThreadContext failed: 5