Rebase against f91f4348356285ede39915f0d10ffae11c4871e5.

This commit is contained in:
Alistair Leslie-Hughes 2022-05-03 09:02:07 +10:00
parent d7507fbe00
commit cd7567fdc1
4 changed files with 2 additions and 214 deletions

View File

@ -1,189 +0,0 @@
From 7d98d6ba865369f37ea7641a82aaab74e804165c Mon Sep 17 00:00:00 2001
From: David Curtiss <david.curtiss@ni.com>
Date: Tue, 10 Aug 2021 17:16:08 -0500
Subject: [PATCH] kernelbase: Implement ResolveLocaleName
---
dlls/kernel32/tests/locale.c | 88 ++++++++++++++++++++++++++++++++++++
dlls/kernelbase/locale.c | 44 ++++++++++++++++--
2 files changed, 129 insertions(+), 3 deletions(-)
diff --git a/dlls/kernel32/tests/locale.c b/dlls/kernel32/tests/locale.c
index 65687313fbb..9202513ef07 100644
--- a/dlls/kernel32/tests/locale.c
+++ b/dlls/kernel32/tests/locale.c
@@ -90,6 +90,7 @@ static void * (WINAPI *pNlsValidateLocale)(LCID*,ULONG);
static LANGID (WINAPI *pSetThreadUILanguage)(LANGID);
static LANGID (WINAPI *pGetThreadUILanguage)(VOID);
static INT (WINAPI *pNormalizeString)(NORM_FORM, LPCWSTR, INT, LPWSTR, INT);
+static INT (WINAPI *pResolveLocaleName)(LPCWSTR, LPWSTR, INT);
static INT (WINAPI *pFindStringOrdinal)(DWORD, LPCWSTR lpStringSource, INT, LPCWSTR, INT, BOOL);
static BOOL (WINAPI *pGetNLSVersion)(NLS_FUNCTION,LCID,NLSVERSIONINFO*);
static BOOL (WINAPI *pGetNLSVersionEx)(NLS_FUNCTION,LPCWSTR,NLSVERSIONINFOEX*);
@@ -140,6 +141,7 @@ static void InitFunctionPointers(void)
X(SetThreadUILanguage);
X(GetThreadUILanguage);
X(NormalizeString);
+ X(ResolveLocaleName);
X(FindStringOrdinal);
X(GetNLSVersion);
X(GetNLSVersionEx);
@@ -6810,6 +6812,91 @@ static void test_NormalizeString(void)
}
}
+static void test_ResolveLocaleName(void)
+{
+ INT ret;
+ WCHAR buffer[BUFFER_SIZE];
+ INT buffer_size = BUFFER_SIZE;
+
+ if (!pResolveLocaleName)
+ {
+ win_skip( "ResolveLocaleName not available\n" );
+ return;
+ }
+
+ /* already-valid cases */
+ ret = pResolveLocaleName(L"fr-FR", buffer, buffer_size);
+ ok(ret == lstrlenW(L"fr-FR")+1, "Expected Len %d, got %d\n", lstrlenW(L"fr-FR")+1, ret);
+ ok(wcsncmp(buffer, L"fr-FR", lstrlenW(L"fr-FR")) == 0, "Bad conversion\n");
+
+ ret = pResolveLocaleName(L"fr-BE", buffer, buffer_size);
+ ok(ret == lstrlenW(L"fr-BE")+1, "Expected Len %d, got %d\n", lstrlenW(L"fr-BE")+1, ret);
+ ok(wcsncmp(buffer, L"fr-BE", lstrlenW(L"fr-BE")) == 0, "Bad conversion\n");
+
+ /* just-resolve cases */
+ ret = pResolveLocaleName(L"fr", buffer, buffer_size);
+ ok(ret == lstrlenW(L"fr-FR")+1, "Expected Len %d, got %d\n", lstrlenW(L"fr-FR")+1, ret);
+ ok(wcsncmp(buffer, L"fr-FR", lstrlenW(L"fr-FR")) == 0, "Bad conversion\n");
+
+ /* truncate-and-resolve cases */
+ ret = pResolveLocaleName(L"fr-aaa-BE", buffer, buffer_size);
+ ok(ret == lstrlenW(L"fr-FR")+1, "Expected Len %d, got %d\n", lstrlenW(L"fr-FR")+1, ret);
+ ok(wcsncmp(buffer, L"fr-FR", lstrlenW(L"fr-FR")) == 0, "Bad conversion\n");
+
+ ret = pResolveLocaleName(L"fr-aaa-BE", buffer, buffer_size);
+ ok(ret == lstrlenW(L"fr-BE")+1, "Expected Len %d, got %d\n", lstrlenW(L"fr-BE")+1, ret);
+ ok(wcsncmp(buffer, L"fr-BE", lstrlenW(L"fr-BE")) == 0
+ || wcsncmp(buffer, L"fr-FR", lstrlenW(L"fr-FR")) == 0, "Bad conversion\n");
+
+ ret = pResolveLocaleName(L"fr-BE-x-y-z", buffer, buffer_size);
+ ok(ret == lstrlenW(L"fr-BE")+1, "Expected Len %d, got %d\n", lstrlenW(L"fr-BE")+1, ret);
+ ok(wcsncmp(buffer, L"fr-BE", lstrlenW(L"fr-BE")) == 0, "Bad conversion\n");
+
+ /* just-big-enough buffer size */
+ buffer_size = lstrlenW(L"fr-FR") + 1;
+ ret = pResolveLocaleName(L"fr", buffer, buffer_size);
+ ok(ret == lstrlenW(L"fr-FR")+1, "Expected Len %d, got %d\n", lstrlenW(L"fr-FR")+1, ret);
+ ok(wcsncmp(buffer, L"fr-FR", lstrlenW(L"fr-FR")) == 0, "Bad conversion\n");
+
+ buffer_size = BUFFER_SIZE; /* restore normal value */
+
+ /* unknown locales return empty string */
+ ret = pResolveLocaleName(L"xx-XX", buffer, buffer_size);
+ ok(ret == lstrlenW(L"")+1, "Expected Len %d, got %d\n", lstrlenW(L"")+1, ret);
+ ok(wcsncmp(buffer, L"", lstrlenW(L"")) == 0, "Bad conversion\n");
+
+ ret = pResolveLocaleName(L"xx", buffer, buffer_size);
+ ok(ret == lstrlenW(L"")+1, "Expected Len %d, got %d\n", lstrlenW(L"")+1, ret);
+ ok(wcsncmp(buffer, L"", lstrlenW(L"")) == 0, "Bad conversion\n");
+
+ /* string is empty after truncated */
+ ret = pResolveLocaleName(L"-en-US", buffer, buffer_size);
+ ok(ret == lstrlenW(L"")+1, "Expected Len %d, got %d\n", lstrlenW(L"")+1, ret);
+ ok(wcsncmp(buffer, L"", lstrlenW(L"")) == 0, "Bad conversion\n");
+
+ /* when no output buffer, returns required buffer size */
+ ret = pResolveLocaleName(L"en-US", NULL, buffer_size);
+ ok(ret == lstrlenW(L"en-US")+1, "Expected Len %d, got %d\n", lstrlenW(L"en-US")+1, ret);
+
+ ret = pResolveLocaleName(L"en-US-x-y-z", NULL, buffer_size);
+ ok(ret == lstrlenW(L"en-US")+1, "Expected Len %d, got %d\n", lstrlenW(L"en-US")+1, ret);
+
+ /* buffer-size error cases */
+ SetLastError(0xdeadbeef);
+ buffer_size = 5; /* too small to hold "fr-FR\0" */
+ ret = pResolveLocaleName(L"fr", buffer, buffer_size);
+ ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER,
+ "Expected ret == 0 w/ error %d, got %d (%s), error %ld\n",
+ ERROR_INSUFFICIENT_BUFFER, ret, wine_dbgstr_w(buffer), GetLastError());
+
+ /* null-input error cases */
+ SetLastError(0xdeadbeef);
+ ret = pResolveLocaleName(NULL, buffer, buffer_size);
+ ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER,
+ "Expected ret == 0 w/ error %d, got %d (%s), error %ld\n",
+ ERROR_INSUFFICIENT_BUFFER, ret, wine_dbgstr_w(buffer), GetLastError());
+}
+
static void test_SpecialCasing(void)
{
int ret, i;
@@ -7646,6 +7733,7 @@ START_TEST(locale)
test_FindStringOrdinal();
test_SetThreadUILanguage();
test_NormalizeString();
+ test_ResolveLocaleName();
test_SpecialCasing();
test_NLSVersion();
test_locale_nls();
diff --git a/dlls/kernelbase/locale.c b/dlls/kernelbase/locale.c
index 25ccfc5f010..a1da1398e06 100644
--- a/dlls/kernelbase/locale.c
+++ b/dlls/kernelbase/locale.c
@@ -6057,10 +6057,48 @@ INT WINAPI DECLSPEC_HOTPATCH NormalizeString(NORM_FORM form, const WCHAR *src, I
*/
INT WINAPI DECLSPEC_HOTPATCH ResolveLocaleName( LPCWSTR name, LPWSTR buffer, INT len )
{
- FIXME( "stub: %s, %p, %d\n", wine_dbgstr_w(name), buffer, len );
+ LCID lcid;
+ WCHAR local_buffer[LOCALE_NAME_MAX_LENGTH];
+ WCHAR *output_buffer = buffer ? buffer : local_buffer;
+ WCHAR *p = 0;
+ INT new_len;
- SetLastError( ERROR_CALL_NOT_IMPLEMENTED );
- return 0;
+ if (!name)
+ {
+ SetLastError( ERROR_INSUFFICIENT_BUFFER );
+ return 0;
+ }
+
+ TRACE( "(%s, %p, %d)\n", debugstr_w(name), buffer, len );
+
+ for (;;)
+ {
+ lcid = LocaleNameToLCID( p ? local_buffer : name, 0 );
+ if (lcid) break;
+
+ if (!p) /* first loop iteration */
+ {
+ lstrcpynW( local_buffer, name, LOCALE_NAME_MAX_LENGTH );
+ local_buffer[LOCALE_NAME_MAX_LENGTH - 1] = L'\0';
+ p = local_buffer + lstrlenW( local_buffer );
+ }
+ if (p == local_buffer)
+ {
+ /* fail-safe in case LocaleNameToLCID doesn't recognize "" */
+ SetLastError( ERROR_INVALID_PARAMETER );
+ return 0;
+ }
+
+ for (--p; p > local_buffer; --p)
+ {
+ if (*p == L'-' || *p == L'_') break;
+ }
+ *p = L'\0';
+ }
+ new_len = LCIDToLocaleName( lcid, output_buffer, len, 0 );
+
+ TRACE( "(%s, %p, %d) returning %d %s\n", debugstr_w(name), buffer, len, new_len, debugstr_w(output_buffer) );
+ return new_len;
}
--
2.35.1

View File

@ -1,6 +0,0 @@
Fixes: [52407] kernelbase: Improve stub for ResolveLocaleName
Fixes: [52867] System.Globalization.CultureInfo.GetCultureInfo fails for 'en' value
# Reference.
#https://www.winehq.org/pipermail/wine-devel/2021-August/192359.html
#https://www.winehq.org/pipermail/wine-devel/2022-January/205189.html

View File

@ -51,7 +51,7 @@ usage()
# Get the upstream commit sha
upstream_commit()
{
echo "64b96eec7d0aea470f897a3ed0ac9e1b3a680cc5"
echo "f91f4348356285ede39915f0d10ffae11c4871e5"
}
# Show version information
@ -122,7 +122,6 @@ patch_enable_all ()
enable_kernel32_Debugger="$1"
enable_kernel32_Job_Tests="$1"
enable_kernel32_Processor_Group="$1"
enable_kernelbase_ResolveLocaleName="$1"
enable_krnl386_exe16_GDT_LDT_Emulation="$1"
enable_krnl386_exe16_Invalid_Console_Handles="$1"
enable_libs_Unicode_Collation="$1"
@ -393,9 +392,6 @@ patch_enable ()
kernel32-Processor_Group)
enable_kernel32_Processor_Group="$2"
;;
kernelbase-ResolveLocaleName)
enable_kernelbase_ResolveLocaleName="$2"
;;
krnl386.exe16-GDT_LDT_Emulation)
enable_krnl386_exe16_GDT_LDT_Emulation="$2"
;;
@ -2101,19 +2097,6 @@ if test "$enable_kernel32_Processor_Group" -eq 1; then
patch_apply kernel32-Processor_Group/0002-kernel32-Add-stub-for-SetThreadIdealProcessorEx.patch
fi
# Patchset kernelbase-ResolveLocaleName
# |
# | This patchset fixes the following Wine bugs:
# | * [#52407] kernelbase: Improve stub for ResolveLocaleName
# | * [#52867] System.Globalization.CultureInfo.GetCultureInfo fails for 'en' value
# |
# | Modified files:
# | * dlls/kernel32/tests/locale.c, dlls/kernelbase/locale.c
# |
if test "$enable_kernelbase_ResolveLocaleName" -eq 1; then
patch_apply kernelbase-ResolveLocaleName/0001-kernelbase-Implement-ResolveLocaleName.patch
fi
# Patchset krnl386.exe16-GDT_LDT_Emulation
# |
# | This patchset fixes the following Wine bugs:

View File

@ -1 +1 @@
64b96eec7d0aea470f897a3ed0ac9e1b3a680cc5
f91f4348356285ede39915f0d10ffae11c4871e5