kernel32: set sLanguage to LOCALE_SABBREVLANGUAGE to match Windows behavior
Jeff Zaroyko
jeffzaroyko at gmail.com
Sat Aug 22 22:09:40 CDT 2009
This fixes bug 15181, test included - passes on Windows 95, 2003, XP,
2008, Vista and Windows 7 beta that I've tested.
-------------- next part --------------
From 52ff2d29ba9fbffbe8da46a7523338e8b946bbcd Mon Sep 17 00:00:00 2001
From: Jeff Zaroyko <jeffz at jeffz.name>
Date: Sun, 23 Aug 2009 12:38:17 +1000
Subject: kernel32: set sLanguage to LOCALE_SABBREVLANGUAGE to match Windows behavior
As a Profile entry and under Control Panel\International sLanguage is not
LOCALE_SLANGUAGE but instead appears to be LOCALE_SABBREVLANGNAME.
I've verified this is the case for 95, XP, 2003, 2008, Vista and Win 7.
With the sLanguage override set GetLocaleInfo for LOCALE_SLANGUAGE still
returns the LOCALE_SLANGUAGE string and not the "override", which suggests
that the Control Panel\International sLanguage override should be ignored
by GetLocaleInfo for LOCALE_SLANGUAGE.
---
dlls/kernel32/locale.c | 11 +++++++++++
dlls/kernel32/tests/locale.c | 16 ++++++++++++++++
2 files changed, 27 insertions(+), 0 deletions(-)
diff --git a/dlls/kernel32/locale.c b/dlls/kernel32/locale.c
index fa17689..169485b 100644
--- a/dlls/kernel32/locale.c
+++ b/dlls/kernel32/locale.c
@@ -62,6 +62,7 @@ static const union cptable *mac_cptable;
static const union cptable *unix_cptable; /* NULL if UTF8 */
static HANDLE NLS_RegOpenKey(HANDLE hRootKey, LPCWSTR szKeyName);
+static const WCHAR *get_locale_value_name( DWORD lctype );
static const WCHAR szNlsKeyName[] = {
'M','a','c','h','i','n','e','\\','S','y','s','t','e','m','\\',
@@ -663,6 +664,7 @@ void LOCALE_InitRegistry(void)
static const WCHAR lc_measurementW[] = { 'L','C','_','M','E','A','S','U','R','E','M','E','N','T',0 };
static const WCHAR lc_telephoneW[] = { 'L','C','_','T','E','L','E','P','H','O','N','E',0 };
static const WCHAR lc_paperW[] = { 'L','C','_','P','A','P','E','R',0};
+ static const WCHAR intlW[] = {'i','n','t','l',0 };
static const struct
{
LPCWSTR name;
@@ -753,6 +755,14 @@ void LOCALE_InitRegistry(void)
NtClose( nls_key );
}
+ /* As a Profile entry and under Control Panel\International sLanguage is not LOCALE_SLANGUAGE
+ but instead appears to be LOCALE_SABBREVLANGNAME, yet GetLocaleInfo for LOCALE_SLANGUAGE
+ should indeed return the LOCALE_SLANGUAGE string. */
+ count = GetLocaleInfoW( lcid, LOCALE_SABBREVLANGNAME, bufferW, sizeof bufferW / sizeof(WCHAR) );
+ RtlInitUnicodeString( &nameW, get_locale_value_name( LOCALE_SLANGUAGE ));
+ NtSetValueKey( hkey, &nameW, 0, REG_SZ, bufferW, count * sizeof(WCHAR) );
+ GetLocaleInfoW( lcid, LOCALE_SABBREVLANGNAME, bufferW, sizeof bufferW / sizeof(WCHAR) );
+ WriteProfileStringW( intlW, get_locale_value_name( LOCALE_SLANGUAGE ), bufferW );
NtClose( hkey );
}
@@ -1233,6 +1243,7 @@ INT WINAPI GetLocaleInfoW( LCID lcid, LCTYPE lctype, LPWSTR buffer, INT len )
/* first check for overrides in the registry */
if (!(lcflags & LOCALE_NOUSEROVERRIDE) &&
+ (lctype != LOCALE_SLANGUAGE) &&
lcid == convert_default_lcid( LOCALE_USER_DEFAULT, lctype ))
{
const WCHAR *value = get_locale_value_name(lctype);
diff --git a/dlls/kernel32/tests/locale.c b/dlls/kernel32/tests/locale.c
index 8a56100..fa0ff8e 100644
--- a/dlls/kernel32/tests/locale.c
+++ b/dlls/kernel32/tests/locale.c
@@ -34,6 +34,7 @@
#include "winbase.h"
#include "winerror.h"
#include "winnls.h"
+#include "winreg.h"
static inline unsigned int strlenW( const WCHAR *str )
{
@@ -119,6 +120,7 @@ static void test_GetLocaleInfoA(void)
{
int ret;
int len;
+ HKEY cpl;
LCID lcid = MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT);
char buffer[BUFFER_SIZE];
char expected[BUFFER_SIZE];
@@ -192,6 +194,20 @@ static void test_GetLocaleInfoA(void)
ret = GetLocaleInfoA(lcid, NUO|LOCALE_SDAYNAME1, buffer, 10);
ok(ret == 7, "Expected ret == 7, got %d, error %d\n", ret, GetLastError());
ok(!strcmp(buffer, "Monday"), "Expected 'Monday', got '%s'\n", buffer);
+
+ /* Test that ControlPanel/sLanguage does not override LOCALE_SLANGUAGE */
+ memset(buffer, 0, COUNTOF(buffer));
+ ret = RegOpenKeyExA(HKEY_CURRENT_USER, "Control Panel\\International", 0, KEY_ALL_ACCESS, &cpl);
+ ok(ret == ERROR_SUCCESS, "Couldn't get required access to Control Panel\\International\n");
+ if (ret == ERROR_SUCCESS) {
+ BYTE current_sLanguage[BUFFER_SIZE];
+ DWORD length;
+ RegQueryValueExA(cpl, "sLanguage", NULL, NULL, current_sLanguage, &length);
+ RegSetValueExA(cpl, "sLanguage", 0, REG_SZ, (LPBYTE)"foo", 4);
+ GetLocaleInfoA(GetSystemDefaultLCID(), LOCALE_SLANGUAGE, buffer, COUNTOF(buffer));
+ ok(0 != strcmp(buffer, "foo"), "sLanguage should not override LOCALE_SLANGUAGE!\n");
+ RegSetValueExA(cpl, "sLanguage", 0, REG_SZ, current_sLanguage, length);
+ }
}
static void test_GetTimeFormatA(void)
--
1.5.4.3
More information about the wine-patches
mailing list