kernel32: Move the locale registry setup to kernelbase.

Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Alexandre Julliard 2019-11-20 22:46:44 +01:00
parent ed09f37cef
commit 35ea9cd99a
6 changed files with 130 additions and 175 deletions

View File

@ -85,9 +85,6 @@ static BOOL process_attach( HMODULE module )
NtQuerySystemInformation( SystemBasicInformation, &system_info, sizeof(system_info), NULL );
/* Setup registry locale information */
LOCALE_InitRegistry();
/* Setup registry timezone information */
TIMEZONE_InitRegistry();

View File

@ -74,7 +74,6 @@ extern void COMPUTERNAME_Init(void) DECLSPEC_HIDDEN;
/* locale.c */
extern void LOCALE_Init(void) DECLSPEC_HIDDEN;
extern void LOCALE_InitRegistry(void) DECLSPEC_HIDDEN;
/* time.c */
extern void TIMEZONE_InitRegistry(void) DECLSPEC_HIDDEN;

View File

@ -311,153 +311,6 @@ static inline HANDLE create_registry_key(void)
}
/* update the registry settings for a given locale parameter */
/* return TRUE if an update was needed */
static BOOL locale_update_registry( HKEY hkey, const WCHAR *name, LCID lcid,
const LCTYPE *values, UINT nb_values )
{
static const WCHAR formatW[] = { '%','0','8','x',0 };
WCHAR bufferW[40];
UNICODE_STRING nameW;
DWORD count, i;
RtlInitUnicodeString( &nameW, name );
count = sizeof(bufferW);
if (!NtQueryValueKey(hkey, &nameW, KeyValuePartialInformation, bufferW, count, &count))
{
const KEY_VALUE_PARTIAL_INFORMATION *info = (KEY_VALUE_PARTIAL_INFORMATION *)bufferW;
LPCWSTR text = (LPCWSTR)info->Data;
if (strtoulW( text, NULL, 16 ) == lcid) return FALSE; /* already set correctly */
TRACE( "updating registry, locale %s changed %s -> %08x\n",
debugstr_w(name), debugstr_w(text), lcid );
}
else TRACE( "updating registry, locale %s changed none -> %08x\n", debugstr_w(name), lcid );
sprintfW( bufferW, formatW, lcid );
NtSetValueKey( hkey, &nameW, 0, REG_SZ, bufferW, (strlenW(bufferW) + 1) * sizeof(WCHAR) );
for (i = 0; i < nb_values; i++)
{
GetLocaleInfoW( lcid, values[i] | LOCALE_NOUSEROVERRIDE, bufferW, ARRAY_SIZE( bufferW ));
SetLocaleInfoW( lcid, values[i], bufferW );
}
return TRUE;
}
/***********************************************************************
* LOCALE_InitRegistry
*
* Update registry contents on startup if the user locale has changed.
* This simulates the action of the Windows control panel.
*/
void LOCALE_InitRegistry(void)
{
static const WCHAR acpW[] = {'A','C','P',0};
static const WCHAR oemcpW[] = {'O','E','M','C','P',0};
static const WCHAR maccpW[] = {'M','A','C','C','P',0};
static const WCHAR localeW[] = {'L','o','c','a','l','e',0};
static const WCHAR lc_ctypeW[] = { 'L','C','_','C','T','Y','P','E',0 };
static const struct
{
LPCWSTR name;
USHORT value;
} update_cp_values[] = {
{ acpW, LOCALE_IDEFAULTANSICODEPAGE },
{ oemcpW, LOCALE_IDEFAULTCODEPAGE },
{ maccpW, LOCALE_IDEFAULTMACCODEPAGE }
};
static const LCTYPE lc_messages_values[] = {
LOCALE_SABBREVLANGNAME,
LOCALE_SCOUNTRY,
LOCALE_SLIST,
LOCALE_SCURRENCY,
LOCALE_ICURRENCY,
LOCALE_INEGCURR,
LOCALE_ICURRDIGITS,
LOCALE_ILZERO,
LOCALE_SMONDECIMALSEP,
LOCALE_SMONGROUPING,
LOCALE_SMONTHOUSANDSEP,
LOCALE_SDECIMAL,
LOCALE_STHOUSAND,
LOCALE_IDIGITS,
LOCALE_IDIGITSUBSTITUTION,
LOCALE_SNATIVEDIGITS,
LOCALE_INEGNUMBER,
LOCALE_SNEGATIVESIGN,
LOCALE_SPOSITIVESIGN,
LOCALE_SGROUPING,
LOCALE_S1159,
LOCALE_S2359,
LOCALE_STIME,
LOCALE_ITIME,
LOCALE_ITLZERO,
LOCALE_SSHORTDATE,
LOCALE_SLONGDATE,
LOCALE_SDATE,
LOCALE_ITIMEMARKPOSN,
LOCALE_ICALENDARTYPE,
LOCALE_IFIRSTDAYOFWEEK,
LOCALE_IFIRSTWEEKOFYEAR,
LOCALE_STIMEFORMAT,
LOCALE_SYEARMONTH,
LOCALE_IDATE,
LOCALE_IMEASURE,
LOCALE_ICOUNTRY,
LOCALE_IPAPERSIZE };
UNICODE_STRING nameW;
WCHAR bufferW[80];
DWORD count, i;
HANDLE hkey;
LCID lcid = GetUserDefaultLCID();
if (!(hkey = create_registry_key()))
return; /* don't do anything if we can't create the registry key */
locale_update_registry( hkey, localeW, lcid, lc_messages_values,
ARRAY_SIZE( lc_messages_values ));
if (locale_update_registry( hkey, lc_ctypeW, GetSystemDefaultLCID(), NULL, 0 ))
{
static const WCHAR codepageW[] =
{'\\','R','e','g','i','s','t','r','y','\\','M','a','c','h','i','n','e','\\','S','y','s','t','e','m','\\',
'C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\',
'C','o','n','t','r','o','l','\\','N','l','s','\\','C','o','d','e','p','a','g','e',0};
OBJECT_ATTRIBUTES attr;
HANDLE nls_key;
DWORD len = 14;
RtlInitUnicodeString( &nameW, codepageW );
InitializeObjectAttributes( &attr, &nameW, 0, 0, NULL );
while (codepageW[len])
{
nameW.Length = len * sizeof(WCHAR);
if (NtCreateKey( &nls_key, KEY_ALL_ACCESS, &attr, 0, NULL, 0, NULL )) break;
NtClose( nls_key );
len++;
while (codepageW[len] && codepageW[len] != '\\') len++;
}
nameW.Length = len * sizeof(WCHAR);
if (!NtCreateKey( &nls_key, KEY_ALL_ACCESS, &attr, 0, NULL, 0, NULL ))
{
for (i = 0; i < ARRAY_SIZE( update_cp_values ); i++)
{
count = GetLocaleInfoW( lcid, update_cp_values[i].value | LOCALE_NOUSEROVERRIDE,
bufferW, ARRAY_SIZE( bufferW ));
RtlInitUnicodeString( &nameW, update_cp_values[i].name );
NtSetValueKey( nls_key, &nameW, 0, REG_SZ, bufferW, count * sizeof(WCHAR) );
}
NtClose( nls_key );
}
}
NtClose( hkey );
}
static BOOL get_dummy_preferred_ui_language( DWORD flags, ULONG *count, WCHAR *buffer, ULONG *size )
{
LCTYPE type;

View File

@ -27,13 +27,13 @@
extern WCHAR *file_name_AtoW( LPCSTR name, BOOL alloc ) DECLSPEC_HIDDEN;
extern DWORD file_name_WtoA( LPCWSTR src, INT srclen, LPSTR dest, INT destlen ) DECLSPEC_HIDDEN;
extern void init_startup_info( RTL_USER_PROCESS_PARAMETERS *params ) DECLSPEC_HIDDEN;
extern void init_locale(void) DECLSPEC_HIDDEN;
extern const WCHAR windows_dir[] DECLSPEC_HIDDEN;
extern const WCHAR system_dir[] DECLSPEC_HIDDEN;
static const BOOL is_win64 = (sizeof(void *) > sizeof(int));
extern BOOL is_wow64 DECLSPEC_HIDDEN;
extern HANDLE kernel32_handle DECLSPEC_HIDDEN;
static inline BOOL is_console_handle(HANDLE h)
{

View File

@ -41,17 +41,124 @@ WINE_DEFAULT_DEBUG_CHANNEL(nls);
#define CALINFO_MAX_YEAR 2029
static const WCHAR codepages_key[] =
{ 'S','y','s','t','e','m','\\','C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t',
'\\','C','o','n','t','r','o','l','\\','N','l','s','\\','C','o','d','e','P','a','g','e',0};
static const WCHAR language_groups_key[] =
{ 'S','y','s','t','e','m','\\','C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t',
'\\','C','o','n','t','r','o','l','\\','N','l','s',
'\\','L','a','n','g','u','a','g','e',' ','G','r','o','u','p','s',0 };
static const WCHAR locales_key[] =
{ 'S','y','s','t','e','m','\\','C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t',
'\\','C','o','n','t','r','o','l','\\','N','l','s','\\','L','o','c','a','l','e',0};
static const WCHAR altsort_key[] = {'A','l','t','e','r','n','a','t','e',' ','S','o','r','t','s',0};
static HANDLE kernel32_handle;
static const struct registry_value
{
DWORD lctype;
const WCHAR *name;
} registry_values[] =
{
{ LOCALE_ICALENDARTYPE, L"iCalendarType" },
{ LOCALE_ICURRDIGITS, L"iCurrDigits" },
{ LOCALE_ICURRENCY, L"iCurrency" },
{ LOCALE_IDIGITS, L"iDigits" },
{ LOCALE_IFIRSTDAYOFWEEK, L"iFirstDayOfWeek" },
{ LOCALE_IFIRSTWEEKOFYEAR, L"iFirstWeekOfYear" },
{ LOCALE_ILZERO, L"iLZero" },
{ LOCALE_IMEASURE, L"iMeasure" },
{ LOCALE_INEGCURR, L"iNegCurr" },
{ LOCALE_INEGNUMBER, L"iNegNumber" },
{ LOCALE_IPAPERSIZE, L"iPaperSize" },
{ LOCALE_ITIME, L"iTime" },
{ LOCALE_S1159, L"s1159" },
{ LOCALE_S2359, L"s2359" },
{ LOCALE_SCURRENCY, L"sCurrency" },
{ LOCALE_SDATE, L"sDate" },
{ LOCALE_SDECIMAL, L"sDecimal" },
{ LOCALE_SGROUPING, L"sGrouping" },
{ LOCALE_SLIST, L"sList" },
{ LOCALE_SLONGDATE, L"sLongDate" },
{ LOCALE_SMONDECIMALSEP, L"sMonDecimalSep" },
{ LOCALE_SMONGROUPING, L"sMonGrouping" },
{ LOCALE_SMONTHOUSANDSEP, L"sMonThousandSep" },
{ LOCALE_SNEGATIVESIGN, L"sNegativeSign" },
{ LOCALE_SPOSITIVESIGN, L"sPositiveSign" },
{ LOCALE_SSHORTDATE, L"sShortDate" },
{ LOCALE_STHOUSAND, L"sThousand" },
{ LOCALE_STIME, L"sTime" },
{ LOCALE_STIMEFORMAT, L"sTimeFormat" },
{ LOCALE_SYEARMONTH, L"sYearMonth" },
/* The following are not listed under MSDN as supported,
* but seem to be used and also stored in the registry.
*/
{ LOCALE_SNAME, L"LocaleName" },
{ LOCALE_ICOUNTRY, L"iCountry" },
{ LOCALE_IDATE, L"iDate" },
{ LOCALE_ILDATE, L"iLDate" },
{ LOCALE_ITLZERO, L"iTLZero" },
{ LOCALE_SCOUNTRY, L"sCountry" },
{ LOCALE_SABBREVLANGNAME, L"sLanguage" },
{ LOCALE_IDIGITSUBSTITUTION, L"Numshape" },
{ LOCALE_SNATIVEDIGITS, L"sNativeDigits" },
{ LOCALE_ITIMEMARKPOSN, L"iTimePrefix" },
};
static UINT ansi_cp = 1252;
static UINT oem_cp = 437;
static UINT mac_cp = 10000;
static HKEY intl_key;
static HKEY nls_key;
/***********************************************************************
* init_locale
*/
void init_locale(void)
{
LCID lcid = GetUserDefaultLCID();
WCHAR bufferW[80];
DWORD count, i;
HKEY hkey;
kernel32_handle = GetModuleHandleW( L"kernel32.dll" );
GetLocaleInfoW( LOCALE_SYSTEM_DEFAULT, LOCALE_IDEFAULTANSICODEPAGE | LOCALE_RETURN_NUMBER,
(WCHAR *)&ansi_cp, sizeof(ansi_cp)/sizeof(WCHAR) );
GetLocaleInfoW( LOCALE_SYSTEM_DEFAULT, LOCALE_IDEFAULTMACCODEPAGE | LOCALE_RETURN_NUMBER,
(WCHAR *)&mac_cp, sizeof(mac_cp)/sizeof(WCHAR) );
GetLocaleInfoW( LOCALE_SYSTEM_DEFAULT, LOCALE_IDEFAULTCODEPAGE | LOCALE_RETURN_NUMBER,
(WCHAR *)&oem_cp, sizeof(oem_cp)/sizeof(WCHAR) );
RegCreateKeyExW( HKEY_LOCAL_MACHINE, L"System\\CurrentControlSet\\Control\\Nls",
0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &nls_key, NULL );
RegCreateKeyExW( HKEY_CURRENT_USER, L"Control Panel\\International",
0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &intl_key, NULL );
/* Update registry contents if the user locale has changed.
* This simulates the action of the Windows control panel. */
count = sizeof(bufferW);
if (!RegQueryValueExW( intl_key, L"Locale", NULL, NULL, (BYTE *)bufferW, &count ))
{
if (wcstoul( bufferW, NULL, 16 ) == lcid) return; /* already set correctly */
TRACE( "updating registry, locale changed %s -> %08x\n", debugstr_w(bufferW), lcid );
}
else TRACE( "updating registry, locale changed none -> %08x\n", lcid );
swprintf( bufferW, ARRAY_SIZE(bufferW), L"%08x", lcid );
RegSetValueExW( intl_key, L"Locale", 0, REG_SZ,
(BYTE *)bufferW, (lstrlenW(bufferW) + 1) * sizeof(WCHAR) );
for (i = 0; i < ARRAY_SIZE(registry_values); i++)
{
GetLocaleInfoW( LOCALE_USER_DEFAULT, registry_values[i].lctype | LOCALE_NOUSEROVERRIDE,
bufferW, ARRAY_SIZE( bufferW ));
RegSetValueExW( intl_key, registry_values[i].name, 0, REG_SZ,
(BYTE *)bufferW, (lstrlenW(bufferW) + 1) * sizeof(WCHAR) );
}
if (!RegCreateKeyExW( nls_key, L"Codepage",
0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hkey, NULL ))
{
count = swprintf( bufferW, ARRAY_SIZE(bufferW), L"%03d", ansi_cp );
RegSetValueExW( hkey, L"ACP", 0, REG_SZ, (BYTE *)bufferW, (count + 1) * sizeof(WCHAR) );
count = swprintf( bufferW, ARRAY_SIZE(bufferW), L"%03d", oem_cp );
RegSetValueExW( hkey, L"OEMCP", 0, REG_SZ, (BYTE *)bufferW, (count + 1) * sizeof(WCHAR) );
count = swprintf( bufferW, ARRAY_SIZE(bufferW), L"%03d", mac_cp );
RegSetValueExW( hkey, L"MACCP", 0, REG_SZ, (BYTE *)bufferW, (count + 1) * sizeof(WCHAR) );
RegCloseKey( hkey );
}
}
/* Note: the Internal_ functions are not documented. The number of parameters
@ -181,8 +288,8 @@ BOOL WINAPI DECLSPEC_HOTPATCH Internal_EnumLanguageGroupLocales( LANGGROUPLOCALE
return FALSE;
}
if (RegOpenKeyExW( HKEY_LOCAL_MACHINE, locales_key, 0, KEY_READ, &key )) return FALSE;
if (RegOpenKeyExW( key, altsort_key, 0, KEY_READ, &altkey )) altkey = 0;
if (RegOpenKeyExW( nls_key, L"Locale", 0, KEY_READ, &key )) return FALSE;
if (RegOpenKeyExW( key, L"Alternate Sorts", 0, KEY_READ, &altkey )) altkey = 0;
for (;;)
{
@ -222,7 +329,7 @@ BOOL WINAPI DECLSPEC_HOTPATCH Internal_EnumSystemCodePages( CODEPAGE_ENUMPROCW p
DWORD name_len, type, index = 0;
HKEY key;
if (RegOpenKeyExW( HKEY_LOCAL_MACHINE, codepages_key, 0, KEY_READ, &key )) return FALSE;
if (RegOpenKeyExW( nls_key, L"Codepage", 0, KEY_READ, &key )) return FALSE;
for (;;)
{
@ -273,7 +380,7 @@ BOOL WINAPI DECLSPEC_HOTPATCH Internal_EnumSystemLanguageGroups( LANGUAGEGROUP_E
return FALSE;
}
if (RegOpenKeyExW( HKEY_LOCAL_MACHINE, language_groups_key, 0, KEY_READ, &key )) return FALSE;
if (RegOpenKeyExW( nls_key, L"Language Groups", 0, KEY_READ, &key )) return FALSE;
for (;;)
{
@ -366,7 +473,7 @@ BOOL WINAPI DECLSPEC_HOTPATCH Internal_EnumUILanguages( UILANGUAGE_ENUMPROCW pro
return FALSE;
}
if (RegOpenKeyExW( HKEY_LOCAL_MACHINE, locales_key, 0, KEY_READ, &key )) return FALSE;
if (RegOpenKeyExW( nls_key, L"Locale", 0, KEY_READ, &key )) return FALSE;
for (;;)
{
@ -516,7 +623,7 @@ BOOL WINAPI DECLSPEC_HOTPATCH EnumSystemLocalesA( LOCALE_ENUMPROCA proc, DWORD f
DWORD name_len, type, index = 0;
HKEY key;
if (RegOpenKeyExW( HKEY_LOCAL_MACHINE, locales_key, 0, KEY_READ, &key )) return FALSE;
if (RegOpenKeyExW( nls_key, L"Locale", 0, KEY_READ, &key )) return FALSE;
for (;;)
{
@ -540,7 +647,7 @@ BOOL WINAPI DECLSPEC_HOTPATCH EnumSystemLocalesW( LOCALE_ENUMPROCW proc, DWORD f
DWORD name_len, type, index = 0;
HKEY key;
if (RegOpenKeyExW( HKEY_LOCAL_MACHINE, locales_key, 0, KEY_READ, &key )) return FALSE;
if (RegOpenKeyExW( nls_key, L"Locale", 0, KEY_READ, &key )) return FALSE;
for (;;)
{
@ -572,8 +679,8 @@ BOOL WINAPI DECLSPEC_HOTPATCH EnumSystemLocalesEx( LOCALE_ENUMPROCEX proc, DWORD
return FALSE;
}
if (RegOpenKeyExW( HKEY_LOCAL_MACHINE, locales_key, 0, KEY_READ, &key )) return FALSE;
if (RegOpenKeyExW( key, altsort_key, 0, KEY_READ, &altkey )) altkey = 0;
if (RegOpenKeyExW( nls_key, L"Locale", 0, KEY_READ, &key )) return FALSE;
if (RegOpenKeyExW( key, L"Alternate Sorts", 0, KEY_READ, &altkey )) altkey = 0;
for (;;)
{
@ -680,7 +787,7 @@ BOOL WINAPI DECLSPEC_HOTPATCH IsValidLanguageGroup( LGRPID id, DWORD flags )
BOOL ret = FALSE;
HKEY key;
if (RegOpenKeyExW( HKEY_LOCAL_MACHINE, language_groups_key, 0, KEY_READ, &key )) return FALSE;
if (RegOpenKeyExW( nls_key, L"Language Groups", 0, KEY_READ, &key )) return FALSE;
swprintf( name, ARRAY_SIZE(name), format, id );
if (!RegQueryValueExW( key, name, NULL, &type, (BYTE *)value, &value_len ) && type == REG_SZ)

View File

@ -34,7 +34,6 @@
WINE_DEFAULT_DEBUG_CHANNEL(kernelbase);
HANDLE kernel32_handle = 0;
BOOL is_wow64 = FALSE;
/***********************************************************************
@ -46,7 +45,7 @@ BOOL WINAPI DllMain( HINSTANCE hinst, DWORD reason, LPVOID reserved )
{
DisableThreadLibraryCalls( hinst );
IsWow64Process( GetCurrentProcess(), &is_wow64 );
kernel32_handle = GetModuleHandleA( "kernel32.dll" );
init_locale();
init_startup_info( NtCurrentTeb()->Peb->ProcessParameters );
}
return TRUE;