mirror of
https://github.com/reactos/reactos.git
synced 2025-08-06 16:32:57 +00:00
- Move ps/locale.c to ex/locale.c, since it has nothing to do with Process/Thread management (locale settings are part of the executive).
- Cleanup formatting in the file and add proper credits (Thomas and Eric). - Create internal Exp* functions for Setting/Getting the user langid, since they need to be called 2, 3 times by other code and thus shared. - Remove some deprecated code, make the functions themselves initialize the default ID when called for the first time (which should be done by winlogon --> it seems this isn't done yet?). - Set default locale to 0x409 instead of 0x0. svn path=/trunk/; revision=23133
This commit is contained in:
parent
26331352ea
commit
6cf95d5263
5 changed files with 406 additions and 563 deletions
|
@ -653,9 +653,6 @@ ExpInitializeExecutive(VOID)
|
||||||
/* Load the System DLL and its Entrypoints */
|
/* Load the System DLL and its Entrypoints */
|
||||||
PsLocateSystemDll();
|
PsLocateSystemDll();
|
||||||
|
|
||||||
/* Initialize the Default Locale */
|
|
||||||
PiInitDefaultLocale();
|
|
||||||
|
|
||||||
/* Initialize shared user page. Set dos system path, dos device map, etc. */
|
/* Initialize shared user page. Set dos system path, dos device map, etc. */
|
||||||
InitSystemSharedUserPage ((PCHAR)KeLoaderBlock.CommandLine);
|
InitSystemSharedUserPage ((PCHAR)KeLoaderBlock.CommandLine);
|
||||||
|
|
||||||
|
|
405
reactos/ntoskrnl/ex/locale.c
Normal file
405
reactos/ntoskrnl/ex/locale.c
Normal file
|
@ -0,0 +1,405 @@
|
||||||
|
/*
|
||||||
|
* PROJECT: ReactOS Kernel
|
||||||
|
* LICENSE: GPL - See COPYING in the top level directory
|
||||||
|
* FILE: ntoskrnl/ex/locale.c
|
||||||
|
* PURPOSE: Locale (Language) Support for the Executive
|
||||||
|
* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
|
||||||
|
* Eric Kohl
|
||||||
|
* Thomas Weidenmueller (w3seek@reactos.org
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* INCLUDES ******************************************************************/
|
||||||
|
|
||||||
|
#include <ntoskrnl.h>
|
||||||
|
#define NDEBUG
|
||||||
|
#include <internal/debug.h>
|
||||||
|
|
||||||
|
/* GLOBALS *******************************************************************/
|
||||||
|
|
||||||
|
/* System IDs: EN_US */
|
||||||
|
LCID PsDefaultSystemLocaleId = 0x00000409;
|
||||||
|
LANGID PsInstallUILanguageId = LANGIDFROMLCID(0x00000409);
|
||||||
|
|
||||||
|
/* UI/Thread IDs: Same as system */
|
||||||
|
LANGID PsDefaultUILanguageId = 0x00000409;
|
||||||
|
LCID PsDefaultThreadLocaleId = LANGIDFROMLCID(0x00000409);
|
||||||
|
|
||||||
|
/* PRIVATE FUNCTIONS *********************************************************/
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
ExpGetCurrentUserUILanguage(IN PWSTR MuiName,
|
||||||
|
OUT PLANGID LanguageId)
|
||||||
|
{
|
||||||
|
UCHAR ValueBuffer[256];
|
||||||
|
PKEY_VALUE_PARTIAL_INFORMATION ValueInfo;
|
||||||
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||||
|
UNICODE_STRING KeyName =
|
||||||
|
RTL_CONSTANT_STRING(L"Control Panel\\International");
|
||||||
|
UNICODE_STRING ValueName;
|
||||||
|
UNICODE_STRING ValueString;
|
||||||
|
ULONG ValueLength;
|
||||||
|
ULONG Value;
|
||||||
|
HANDLE UserKey;
|
||||||
|
HANDLE KeyHandle;
|
||||||
|
NTSTATUS Status;
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
|
/* Setup the key name */
|
||||||
|
RtlInitUnicodeString(&ValueName, MuiName);
|
||||||
|
|
||||||
|
/* Open the use key */
|
||||||
|
Status = RtlOpenCurrentUser(KEY_READ, &UserKey);
|
||||||
|
if (!NT_SUCCESS(Status)) return Status;
|
||||||
|
|
||||||
|
/* Initialize the attributes and open the key */
|
||||||
|
InitializeObjectAttributes(&ObjectAttributes,
|
||||||
|
&KeyName,
|
||||||
|
OBJ_CASE_INSENSITIVE,
|
||||||
|
UserKey,
|
||||||
|
NULL);
|
||||||
|
Status = ZwOpenKey(&KeyHandle, KEY_QUERY_VALUE,&ObjectAttributes);
|
||||||
|
if (NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
/* Set buffer and query the current value */
|
||||||
|
ValueInfo = (PKEY_VALUE_PARTIAL_INFORMATION)ValueBuffer;
|
||||||
|
Status = ZwQueryValueKey(KeyHandle,
|
||||||
|
&ValueName,
|
||||||
|
KeyValuePartialInformation,
|
||||||
|
ValueBuffer,
|
||||||
|
sizeof(ValueBuffer),
|
||||||
|
&ValueLength);
|
||||||
|
if (NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
/* Success, is the value the right type? */
|
||||||
|
if (ValueInfo->Type == REG_SZ)
|
||||||
|
{
|
||||||
|
/* It is. Initailize the data and convert it */
|
||||||
|
RtlInitUnicodeString(&ValueString, (PWSTR)ValueInfo->Data);
|
||||||
|
Status = RtlUnicodeStringToInteger(&ValueString, 16, &Value);
|
||||||
|
if (NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
/* Return the language */
|
||||||
|
*LanguageId = Value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Fail */
|
||||||
|
Status = STATUS_UNSUCCESSFUL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Close the key */
|
||||||
|
ZwClose(KeyHandle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Close the user key and return */
|
||||||
|
ZwClose(UserKey);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
ExpSetCurrentUserUILanguage(IN PWSTR MuiName,
|
||||||
|
IN LANGID LanguageId)
|
||||||
|
{
|
||||||
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||||
|
UNICODE_STRING KeyName = RTL_CONSTANT_STRING(L"Control Panel\\Desktop");
|
||||||
|
UNICODE_STRING ValueName;
|
||||||
|
WCHAR ValueBuffer[8];
|
||||||
|
ULONG ValueLength;
|
||||||
|
HANDLE UserHandle;
|
||||||
|
HANDLE KeyHandle;
|
||||||
|
NTSTATUS Status;
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
|
/* Setup the key name */
|
||||||
|
RtlInitUnicodeString(&ValueName, MuiName);
|
||||||
|
|
||||||
|
/* Open the use key */
|
||||||
|
Status = RtlOpenCurrentUser(KEY_WRITE, &UserHandle);
|
||||||
|
if (!NT_SUCCESS(Status)) return Status;
|
||||||
|
|
||||||
|
/* Initialize the attributes */
|
||||||
|
InitializeObjectAttributes(&ObjectAttributes,
|
||||||
|
&KeyName,
|
||||||
|
OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
|
||||||
|
UserHandle,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
/* Open the key */
|
||||||
|
Status = ZwOpenKey(&KeyHandle, KEY_SET_VALUE, &ObjectAttributes);
|
||||||
|
if (NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
/* Setup the value name */
|
||||||
|
ValueLength = swprintf(ValueBuffer,
|
||||||
|
L"%04lX",
|
||||||
|
(ULONG)LanguageId);
|
||||||
|
|
||||||
|
/* Set the length for the call and set the value */
|
||||||
|
ValueLength = (ValueLength + 1) * sizeof(WCHAR);
|
||||||
|
Status = ZwSetValueKey(KeyHandle,
|
||||||
|
&ValueName,
|
||||||
|
0,
|
||||||
|
REG_SZ,
|
||||||
|
ValueBuffer,
|
||||||
|
ValueLength);
|
||||||
|
|
||||||
|
/* Close the handle for this key */
|
||||||
|
ZwClose(KeyHandle);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Close the user key and return status */
|
||||||
|
ZwClose(UserHandle);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* PUBLIC FUNCTIONS **********************************************************/
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
NtQueryDefaultLocale(IN BOOLEAN UserProfile,
|
||||||
|
OUT PLCID DefaultLocaleId)
|
||||||
|
{
|
||||||
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
|
/* Enter SEH for probing */
|
||||||
|
_SEH_TRY
|
||||||
|
{
|
||||||
|
/* Check if we came from user mode */
|
||||||
|
if (KeGetPreviousMode() != KernelMode)
|
||||||
|
{
|
||||||
|
/* Probe the language ID */
|
||||||
|
ProbeForWriteLangid(DefaultLocaleId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check if we have a user profile */
|
||||||
|
if (UserProfile)
|
||||||
|
{
|
||||||
|
/* Return thread locale */
|
||||||
|
*DefaultLocaleId = PsDefaultThreadLocaleId;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Return system locale */
|
||||||
|
*DefaultLocaleId = PsDefaultSystemLocaleId;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_SEH_EXCEPT(_SEH_ExSystemExceptionFilter)
|
||||||
|
{
|
||||||
|
/* Get exception code */
|
||||||
|
Status = _SEH_GetExceptionCode();
|
||||||
|
}
|
||||||
|
_SEH_END;
|
||||||
|
|
||||||
|
/* Return status */
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
NtSetDefaultLocale(IN BOOLEAN UserProfile,
|
||||||
|
IN LCID DefaultLocaleId)
|
||||||
|
{
|
||||||
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||||
|
UNICODE_STRING KeyName;
|
||||||
|
UNICODE_STRING ValueName;
|
||||||
|
HANDLE KeyHandle;
|
||||||
|
ULONG ValueLength;
|
||||||
|
WCHAR ValueBuffer[20];
|
||||||
|
HANDLE UserKey = NULL;
|
||||||
|
NTSTATUS Status;
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
|
/* Check if we have a profile */
|
||||||
|
if (UserProfile)
|
||||||
|
{
|
||||||
|
/* Open the user's key */
|
||||||
|
Status = RtlOpenCurrentUser(KEY_WRITE, &UserKey);
|
||||||
|
if (!NT_SUCCESS(Status)) return(Status);
|
||||||
|
|
||||||
|
/* Initialize the registry location */
|
||||||
|
RtlInitUnicodeString(&KeyName, L"Control Panel\\International");
|
||||||
|
RtlInitUnicodeString(&ValueName, L"Locale");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Initialize the system registry location */
|
||||||
|
RtlInitUnicodeString(&KeyName,
|
||||||
|
L"\\Registry\\Machine\\System\\CurrentControlSet"
|
||||||
|
"\\Control\\Nls\\Language");
|
||||||
|
RtlInitUnicodeString(&ValueName, L"Default");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Initailize the object attributes */
|
||||||
|
InitializeObjectAttributes(&ObjectAttributes,
|
||||||
|
&KeyName,
|
||||||
|
OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
|
||||||
|
UserKey,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
/* Check if we don' thave a default locale yet */
|
||||||
|
if (!DefaultLocaleId)
|
||||||
|
{
|
||||||
|
DPRINT1("TODO\n");
|
||||||
|
Status = STATUS_SUCCESS;
|
||||||
|
KEBUGCHECK(0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Otherwise, open the key */
|
||||||
|
Status = ZwOpenKey(&KeyHandle, KEY_SET_VALUE, &ObjectAttributes);
|
||||||
|
if (NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
/* Check if we had a profile */
|
||||||
|
if (UserProfile)
|
||||||
|
{
|
||||||
|
/* Fill in the buffer */
|
||||||
|
ValueLength = swprintf(ValueBuffer,
|
||||||
|
L"%08lx",
|
||||||
|
(ULONG)DefaultLocaleId);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Fill in the buffer */
|
||||||
|
ValueLength = swprintf(ValueBuffer,
|
||||||
|
L"%04lx",
|
||||||
|
(ULONG)DefaultLocaleId & 0xFFFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set the length for the registry call */
|
||||||
|
ValueLength = (ValueLength + 1) * sizeof(WCHAR);
|
||||||
|
|
||||||
|
/* Now write the actual value */
|
||||||
|
Status = ZwSetValueKey(KeyHandle,
|
||||||
|
&ValueName,
|
||||||
|
0,
|
||||||
|
REG_SZ,
|
||||||
|
ValueBuffer,
|
||||||
|
ValueLength);
|
||||||
|
|
||||||
|
/* And close the key */
|
||||||
|
ZwClose(KeyHandle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Close the user key */
|
||||||
|
ZwClose(UserKey);
|
||||||
|
|
||||||
|
/* Check for success */
|
||||||
|
if (NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
/* Check if it was for a user */
|
||||||
|
if (UserProfile)
|
||||||
|
{
|
||||||
|
/* Set thread locale */
|
||||||
|
PsDefaultThreadLocaleId = DefaultLocaleId;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Set system locale */
|
||||||
|
PsDefaultSystemLocaleId = DefaultLocaleId;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return status */
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @implemented
|
||||||
|
*/
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
NtQueryInstallUILanguage(OUT PLANGID LanguageId)
|
||||||
|
{
|
||||||
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
|
/* Enter SEH for probing */
|
||||||
|
_SEH_TRY
|
||||||
|
{
|
||||||
|
/* Check if we came from user mode */
|
||||||
|
if (KeGetPreviousMode() != KernelMode)
|
||||||
|
{
|
||||||
|
/* Probe the Language ID */
|
||||||
|
ProbeForWriteLangid(LanguageId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return it */
|
||||||
|
*LanguageId = PsInstallUILanguageId;
|
||||||
|
}
|
||||||
|
_SEH_EXCEPT(_SEH_ExSystemExceptionFilter)
|
||||||
|
{
|
||||||
|
/* Get exception code */
|
||||||
|
Status = _SEH_GetExceptionCode();
|
||||||
|
}
|
||||||
|
_SEH_END;
|
||||||
|
|
||||||
|
/* Return status */
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @implemented
|
||||||
|
*/
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
NtQueryDefaultUILanguage(OUT PLANGID LanguageId)
|
||||||
|
{
|
||||||
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
|
/* Enter SEH for probing */
|
||||||
|
_SEH_TRY
|
||||||
|
{
|
||||||
|
/* Check if we came from user mode */
|
||||||
|
if (KeGetPreviousMode() != KernelMode)
|
||||||
|
{
|
||||||
|
/* Probe the Language ID */
|
||||||
|
ProbeForWriteLangid(LanguageId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Call the executive helper routine */
|
||||||
|
Status = ExpGetCurrentUserUILanguage(L"MultiUILanguageId", LanguageId);
|
||||||
|
if (NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
/* Success, return the language */
|
||||||
|
*LanguageId = PsInstallUILanguageId;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_SEH_EXCEPT(_SEH_ExSystemExceptionFilter)
|
||||||
|
{
|
||||||
|
/* Get exception code */
|
||||||
|
Status = _SEH_GetExceptionCode();
|
||||||
|
}
|
||||||
|
_SEH_END;
|
||||||
|
|
||||||
|
/* Return status */
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @implemented
|
||||||
|
*/
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
NtSetDefaultUILanguage(IN LANGID LanguageId)
|
||||||
|
{
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
|
/* Check if we don't have a default yet */
|
||||||
|
if (!LanguageId)
|
||||||
|
{
|
||||||
|
/* FIXME */
|
||||||
|
DPRINT1("TODO\n");
|
||||||
|
KEBUGCHECK(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Otherwise, call the internal routine */
|
||||||
|
return ExpSetCurrentUserUILanguage(L"MUILanguagePending", LanguageId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* EOF */
|
|
@ -19,10 +19,6 @@ struct _EJOB;
|
||||||
#define PSP_MAX_LOAD_IMAGE_NOTIFY 8
|
#define PSP_MAX_LOAD_IMAGE_NOTIFY 8
|
||||||
#define PSP_MAX_CREATE_PROCESS_NOTIFY 8
|
#define PSP_MAX_CREATE_PROCESS_NOTIFY 8
|
||||||
|
|
||||||
VOID
|
|
||||||
NTAPI
|
|
||||||
PiInitDefaultLocale(VOID);
|
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
NTAPI
|
NTAPI
|
||||||
PiInitProcessManager(VOID);
|
PiInitProcessManager(VOID);
|
||||||
|
|
|
@ -129,6 +129,7 @@
|
||||||
<file>fmutex.c</file>
|
<file>fmutex.c</file>
|
||||||
<file>handle.c</file>
|
<file>handle.c</file>
|
||||||
<file>init.c</file>
|
<file>init.c</file>
|
||||||
|
<file>locale.c</file>
|
||||||
<file>lookas.c</file>
|
<file>lookas.c</file>
|
||||||
<file>mutant.c</file>
|
<file>mutant.c</file>
|
||||||
<file>power.c</file>
|
<file>power.c</file>
|
||||||
|
@ -288,7 +289,6 @@
|
||||||
<file>idle.c</file>
|
<file>idle.c</file>
|
||||||
<file>job.c</file>
|
<file>job.c</file>
|
||||||
<file>kill.c</file>
|
<file>kill.c</file>
|
||||||
<file>locale.c</file>
|
|
||||||
<file>notify.c</file>
|
<file>notify.c</file>
|
||||||
<file>process.c</file>
|
<file>process.c</file>
|
||||||
<file>psmgr.c</file>
|
<file>psmgr.c</file>
|
||||||
|
|
|
@ -1,555 +0,0 @@
|
||||||
/* $Id$
|
|
||||||
*
|
|
||||||
* COPYRIGHT: See COPYING in the top level directory
|
|
||||||
* PROJECT: ReactOS kernel
|
|
||||||
* FILE: ntoskrnl/ps/locale.c
|
|
||||||
* PURPOSE: Locale support
|
|
||||||
*
|
|
||||||
* PROGRAMMERS: David Welch (welch@cwcom.net)
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* INCLUDES *****************************************************************/
|
|
||||||
|
|
||||||
#include <ntoskrnl.h>
|
|
||||||
|
|
||||||
#define NDEBUG
|
|
||||||
#include <internal/debug.h>
|
|
||||||
|
|
||||||
#if defined (ALLOC_PRAGMA)
|
|
||||||
#pragma alloc_text(INIT, PiInitDefaultLocale)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/* GLOBALS *******************************************************************/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Default setting: LANG_NEUTRAL, SUBLANG_NEUTRAL, SORT_DEFAULT
|
|
||||||
*/
|
|
||||||
LCID PsDefaultThreadLocaleId = 0;
|
|
||||||
LCID PsDefaultSystemLocaleId = 0;
|
|
||||||
BOOL PsDefaultThreadLocaleInitialized = FALSE;
|
|
||||||
|
|
||||||
static LANGID PsInstallUILanguageId = 0;
|
|
||||||
|
|
||||||
#define VALUE_BUFFER_SIZE 256
|
|
||||||
|
|
||||||
/* FUNCTIONS *****************************************************************/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* FUNCTION:
|
|
||||||
* Initializes the default locale.
|
|
||||||
* Reads default locale from registry, if available
|
|
||||||
* ARGUMENTS:
|
|
||||||
* None.
|
|
||||||
* Returns:
|
|
||||||
* None.
|
|
||||||
*/
|
|
||||||
VOID
|
|
||||||
INIT_FUNCTION
|
|
||||||
NTAPI
|
|
||||||
PiInitDefaultLocale(VOID)
|
|
||||||
{
|
|
||||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
|
||||||
UNICODE_STRING KeyName = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Nls\\Language");
|
|
||||||
UNICODE_STRING ValueName;
|
|
||||||
HANDLE KeyHandle;
|
|
||||||
ULONG ValueLength;
|
|
||||||
UCHAR ValueBuffer[VALUE_BUFFER_SIZE];
|
|
||||||
PKEY_VALUE_PARTIAL_INFORMATION ValueInfo;
|
|
||||||
UNICODE_STRING ValueString;
|
|
||||||
ULONG Value;
|
|
||||||
NTSTATUS Status;
|
|
||||||
|
|
||||||
ValueInfo = (PKEY_VALUE_PARTIAL_INFORMATION)ValueBuffer;
|
|
||||||
|
|
||||||
InitializeObjectAttributes(&ObjectAttributes,
|
|
||||||
&KeyName,
|
|
||||||
OBJ_CASE_INSENSITIVE,
|
|
||||||
NULL,
|
|
||||||
NULL);
|
|
||||||
Status = ZwOpenKey(&KeyHandle,
|
|
||||||
KEY_QUERY_VALUE,
|
|
||||||
&ObjectAttributes);
|
|
||||||
if (NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
/* Read system locale */
|
|
||||||
RtlInitUnicodeString(&ValueName,
|
|
||||||
L"Default");
|
|
||||||
Status = ZwQueryValueKey(KeyHandle,
|
|
||||||
&ValueName,
|
|
||||||
KeyValuePartialInformation,
|
|
||||||
ValueBuffer,
|
|
||||||
VALUE_BUFFER_SIZE,
|
|
||||||
&ValueLength);
|
|
||||||
if ((NT_SUCCESS(Status)) && (ValueInfo->Type == REG_SZ))
|
|
||||||
{
|
|
||||||
ValueString.Length = ValueInfo->DataLength;
|
|
||||||
ValueString.MaximumLength = ValueInfo->DataLength;
|
|
||||||
ValueString.Buffer = (PWSTR)ValueInfo->Data;
|
|
||||||
|
|
||||||
Status = RtlUnicodeStringToInteger(&ValueString,
|
|
||||||
16,
|
|
||||||
&Value);
|
|
||||||
if (NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
DPRINT("System locale: %08lx\n", Value);
|
|
||||||
PsDefaultSystemLocaleId = (LCID)Value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Read install language id */
|
|
||||||
RtlInitUnicodeString(&ValueName,
|
|
||||||
L"InstallLanguage");
|
|
||||||
Status = ZwQueryValueKey(KeyHandle,
|
|
||||||
&ValueName,
|
|
||||||
KeyValuePartialInformation,
|
|
||||||
ValueBuffer,
|
|
||||||
VALUE_BUFFER_SIZE,
|
|
||||||
&ValueLength);
|
|
||||||
if ((NT_SUCCESS(Status)) && (ValueInfo->Type == REG_SZ))
|
|
||||||
{
|
|
||||||
ValueString.Length = ValueInfo->DataLength;
|
|
||||||
ValueString.MaximumLength = ValueInfo->DataLength;
|
|
||||||
ValueString.Buffer = (PWSTR)ValueInfo->Data;
|
|
||||||
|
|
||||||
Status = RtlUnicodeStringToInteger(&ValueString,
|
|
||||||
16,
|
|
||||||
&Value);
|
|
||||||
if (NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
DPRINT("Install language id: %04lx\n", Value);
|
|
||||||
PsInstallUILanguageId = (LANGID)Value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ZwClose(KeyHandle);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* FUNCTION:
|
|
||||||
* Initializes the default thread locale.
|
|
||||||
* Reads default locale from registry, if available
|
|
||||||
* ARGUMENTS:
|
|
||||||
* None.
|
|
||||||
* Returns:
|
|
||||||
* None.
|
|
||||||
*/
|
|
||||||
VOID STDCALL
|
|
||||||
PiInitThreadLocale(VOID)
|
|
||||||
{
|
|
||||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
|
||||||
UNICODE_STRING KeyName = RTL_CONSTANT_STRING(L"\\Registry\\User\\.Default\\Control Panel\\International");
|
|
||||||
UNICODE_STRING ValueName = RTL_CONSTANT_STRING(L"Locale");
|
|
||||||
HANDLE KeyHandle;
|
|
||||||
ULONG ValueLength;
|
|
||||||
UCHAR ValueBuffer[VALUE_BUFFER_SIZE];
|
|
||||||
PKEY_VALUE_PARTIAL_INFORMATION ValueInfo;
|
|
||||||
UNICODE_STRING ValueString;
|
|
||||||
ULONG LocaleValue;
|
|
||||||
NTSTATUS Status;
|
|
||||||
|
|
||||||
ValueInfo = (PKEY_VALUE_PARTIAL_INFORMATION)ValueBuffer;
|
|
||||||
|
|
||||||
/* read default thread locale */
|
|
||||||
InitializeObjectAttributes(&ObjectAttributes,
|
|
||||||
&KeyName,
|
|
||||||
OBJ_CASE_INSENSITIVE,
|
|
||||||
NULL,
|
|
||||||
NULL);
|
|
||||||
Status = ZwOpenKey(&KeyHandle,
|
|
||||||
KEY_QUERY_VALUE,
|
|
||||||
&ObjectAttributes);
|
|
||||||
if (NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
Status = ZwQueryValueKey(KeyHandle,
|
|
||||||
&ValueName,
|
|
||||||
KeyValuePartialInformation,
|
|
||||||
ValueBuffer,
|
|
||||||
VALUE_BUFFER_SIZE,
|
|
||||||
&ValueLength);
|
|
||||||
if ((NT_SUCCESS(Status)) && (ValueInfo->Type == REG_SZ))
|
|
||||||
{
|
|
||||||
ValueString.Length = ValueInfo->DataLength;
|
|
||||||
ValueString.MaximumLength = ValueInfo->DataLength;
|
|
||||||
ValueString.Buffer = (PWSTR)ValueInfo->Data;
|
|
||||||
|
|
||||||
Status = RtlUnicodeStringToInteger(&ValueString,
|
|
||||||
16,
|
|
||||||
&LocaleValue);
|
|
||||||
if (NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
DPRINT("Thread locale: %08lu\n", LocaleValue);
|
|
||||||
PsDefaultThreadLocaleId = (LCID)LocaleValue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ZwClose(KeyHandle);
|
|
||||||
}
|
|
||||||
|
|
||||||
PsDefaultThreadLocaleInitialized = TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* FUNCTION:
|
|
||||||
* Returns the default locale.
|
|
||||||
* ARGUMENTS:
|
|
||||||
* UserProfile = If TRUE then the locale for this thread is returned,
|
|
||||||
* otherwise the locale for the system is returned.
|
|
||||||
* DefaultLocaleId = Points to a variable that receives the locale id.
|
|
||||||
* Returns:
|
|
||||||
* Status.
|
|
||||||
*/
|
|
||||||
NTSTATUS STDCALL
|
|
||||||
NtQueryDefaultLocale(IN BOOLEAN UserProfile,
|
|
||||||
OUT PLCID DefaultLocaleId)
|
|
||||||
{
|
|
||||||
NTSTATUS Status = STATUS_SUCCESS;
|
|
||||||
|
|
||||||
PAGED_CODE();
|
|
||||||
|
|
||||||
_SEH_TRY
|
|
||||||
{
|
|
||||||
if (KeGetPreviousMode() != KernelMode)
|
|
||||||
{
|
|
||||||
ProbeForWriteLangid(DefaultLocaleId);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (UserProfile)
|
|
||||||
{
|
|
||||||
if (!PsDefaultThreadLocaleInitialized)
|
|
||||||
{
|
|
||||||
PiInitThreadLocale();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* set thread locale */
|
|
||||||
*DefaultLocaleId = PsDefaultThreadLocaleId;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* set system locale */
|
|
||||||
*DefaultLocaleId = PsDefaultSystemLocaleId;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_SEH_EXCEPT(_SEH_ExSystemExceptionFilter)
|
|
||||||
{
|
|
||||||
Status = _SEH_GetExceptionCode();
|
|
||||||
}
|
|
||||||
_SEH_END;
|
|
||||||
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* FUNCTION:
|
|
||||||
* Sets the default locale.
|
|
||||||
* ARGUMENTS:
|
|
||||||
* ThreadOrSystem = If TRUE then the locale for this thread is set,
|
|
||||||
* otherwise the locale for the system is set.
|
|
||||||
* DefaultLocaleId = The locale id to be set.
|
|
||||||
* Returns:
|
|
||||||
* Status.
|
|
||||||
*/
|
|
||||||
NTSTATUS STDCALL
|
|
||||||
NtSetDefaultLocale(IN BOOLEAN UserProfile,
|
|
||||||
IN LCID DefaultLocaleId)
|
|
||||||
{
|
|
||||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
|
||||||
UNICODE_STRING KeyName;
|
|
||||||
UNICODE_STRING ValueName;
|
|
||||||
HANDLE KeyHandle;
|
|
||||||
ULONG ValueLength;
|
|
||||||
WCHAR ValueBuffer[20];
|
|
||||||
HANDLE UserKey = NULL;
|
|
||||||
NTSTATUS Status;
|
|
||||||
|
|
||||||
PAGED_CODE();
|
|
||||||
|
|
||||||
if (UserProfile)
|
|
||||||
{
|
|
||||||
/* thread locale */
|
|
||||||
Status = RtlOpenCurrentUser(KEY_WRITE,
|
|
||||||
&UserKey);
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
return(Status);
|
|
||||||
RtlInitUnicodeString(&KeyName,
|
|
||||||
L"Control Panel\\International");
|
|
||||||
RtlInitUnicodeString(&ValueName,
|
|
||||||
L"Locale");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* system locale */
|
|
||||||
RtlInitUnicodeString(&KeyName,
|
|
||||||
L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Nls\\Language");
|
|
||||||
RtlInitUnicodeString(&ValueName,
|
|
||||||
L"Default");
|
|
||||||
}
|
|
||||||
|
|
||||||
InitializeObjectAttributes(&ObjectAttributes,
|
|
||||||
&KeyName,
|
|
||||||
OBJ_CASE_INSENSITIVE,
|
|
||||||
UserKey,
|
|
||||||
NULL);
|
|
||||||
Status = ZwOpenKey(&KeyHandle,
|
|
||||||
KEY_SET_VALUE,
|
|
||||||
&ObjectAttributes);
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
if (UserKey != NULL)
|
|
||||||
{
|
|
||||||
ZwClose(UserKey);
|
|
||||||
}
|
|
||||||
return(Status);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (UserProfile)
|
|
||||||
{
|
|
||||||
ValueLength = swprintf(ValueBuffer,
|
|
||||||
L"%08lx",
|
|
||||||
(ULONG)DefaultLocaleId);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ValueLength = swprintf(ValueBuffer,
|
|
||||||
L"%04lx",
|
|
||||||
(ULONG)DefaultLocaleId & 0xFFFF);
|
|
||||||
}
|
|
||||||
ValueLength = (ValueLength + 1) * sizeof(WCHAR);
|
|
||||||
|
|
||||||
Status = ZwSetValueKey(KeyHandle,
|
|
||||||
&ValueName,
|
|
||||||
0,
|
|
||||||
REG_SZ,
|
|
||||||
ValueBuffer,
|
|
||||||
ValueLength);
|
|
||||||
|
|
||||||
ZwClose(KeyHandle);
|
|
||||||
if (UserKey != NULL)
|
|
||||||
{
|
|
||||||
ZwClose(UserKey);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
return(Status);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (UserProfile)
|
|
||||||
{
|
|
||||||
/* set thread locale */
|
|
||||||
DPRINT("Thread locale: %08lu\n", DefaultLocaleId);
|
|
||||||
PsDefaultThreadLocaleId = DefaultLocaleId;
|
|
||||||
PsDefaultThreadLocaleInitialized = TRUE;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* set system locale */
|
|
||||||
DPRINT("System locale: %08lu\n", DefaultLocaleId);
|
|
||||||
PsDefaultSystemLocaleId = DefaultLocaleId;
|
|
||||||
}
|
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* @implemented
|
|
||||||
*/
|
|
||||||
NTSTATUS STDCALL
|
|
||||||
NtQueryDefaultUILanguage(OUT PLANGID LanguageId)
|
|
||||||
{
|
|
||||||
UCHAR ValueBuffer[VALUE_BUFFER_SIZE];
|
|
||||||
PKEY_VALUE_PARTIAL_INFORMATION ValueInfo;
|
|
||||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
|
||||||
UNICODE_STRING KeyName = RTL_CONSTANT_STRING(L"Control Panel\\International");
|
|
||||||
UNICODE_STRING ValueName = RTL_CONSTANT_STRING(L"MultiUILanguageId");
|
|
||||||
UNICODE_STRING ValueString;
|
|
||||||
ULONG ValueLength;
|
|
||||||
ULONG Value;
|
|
||||||
HANDLE UserKey;
|
|
||||||
HANDLE KeyHandle;
|
|
||||||
NTSTATUS Status = STATUS_SUCCESS;
|
|
||||||
|
|
||||||
PAGED_CODE();
|
|
||||||
|
|
||||||
_SEH_TRY
|
|
||||||
{
|
|
||||||
if (KeGetPreviousMode() != KernelMode)
|
|
||||||
{
|
|
||||||
ProbeForWriteLangid(LanguageId);
|
|
||||||
}
|
|
||||||
|
|
||||||
*LanguageId = PsInstallUILanguageId;
|
|
||||||
}
|
|
||||||
_SEH_EXCEPT(_SEH_ExSystemExceptionFilter)
|
|
||||||
{
|
|
||||||
Status = _SEH_GetExceptionCode();
|
|
||||||
}
|
|
||||||
_SEH_END;
|
|
||||||
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
Status = RtlOpenCurrentUser(KEY_READ,
|
|
||||||
&UserKey);
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
Value = PsInstallUILanguageId;
|
|
||||||
goto ReturnSuccess;
|
|
||||||
}
|
|
||||||
|
|
||||||
InitializeObjectAttributes(&ObjectAttributes,
|
|
||||||
&KeyName,
|
|
||||||
OBJ_CASE_INSENSITIVE,
|
|
||||||
UserKey,
|
|
||||||
NULL);
|
|
||||||
Status = ZwOpenKey(&KeyHandle,
|
|
||||||
KEY_QUERY_VALUE,
|
|
||||||
&ObjectAttributes);
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
Value = PsInstallUILanguageId;
|
|
||||||
goto ReturnSuccess;
|
|
||||||
}
|
|
||||||
|
|
||||||
ValueInfo = (PKEY_VALUE_PARTIAL_INFORMATION)ValueBuffer;
|
|
||||||
|
|
||||||
Status = ZwQueryValueKey(KeyHandle,
|
|
||||||
&ValueName,
|
|
||||||
KeyValuePartialInformation,
|
|
||||||
ValueBuffer,
|
|
||||||
VALUE_BUFFER_SIZE,
|
|
||||||
&ValueLength);
|
|
||||||
|
|
||||||
ZwClose(KeyHandle);
|
|
||||||
ZwClose(UserKey);
|
|
||||||
|
|
||||||
if (!NT_SUCCESS(Status) || ValueInfo->Type != REG_SZ)
|
|
||||||
{
|
|
||||||
Value = PsInstallUILanguageId;
|
|
||||||
goto ReturnSuccess;
|
|
||||||
}
|
|
||||||
|
|
||||||
ValueString.Length = ValueInfo->DataLength;
|
|
||||||
ValueString.MaximumLength = ValueInfo->DataLength;
|
|
||||||
ValueString.Buffer = (PWSTR)ValueInfo->Data;
|
|
||||||
|
|
||||||
Status = RtlUnicodeStringToInteger(&ValueString,
|
|
||||||
16,
|
|
||||||
&Value);
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
Value = PsInstallUILanguageId;
|
|
||||||
goto ReturnSuccess;
|
|
||||||
}
|
|
||||||
|
|
||||||
DPRINT("Default language id: %04lx\n", Value);
|
|
||||||
|
|
||||||
ReturnSuccess:
|
|
||||||
_SEH_TRY
|
|
||||||
{
|
|
||||||
*LanguageId = Value;
|
|
||||||
Status = STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
_SEH_EXCEPT(_SEH_ExSystemExceptionFilter)
|
|
||||||
{
|
|
||||||
Status = _SEH_GetExceptionCode();
|
|
||||||
}
|
|
||||||
_SEH_END;
|
|
||||||
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* @implemented
|
|
||||||
*/
|
|
||||||
NTSTATUS STDCALL
|
|
||||||
NtQueryInstallUILanguage(OUT PLANGID LanguageId)
|
|
||||||
{
|
|
||||||
NTSTATUS Status = STATUS_SUCCESS;
|
|
||||||
|
|
||||||
PAGED_CODE();
|
|
||||||
|
|
||||||
_SEH_TRY
|
|
||||||
{
|
|
||||||
if (KeGetPreviousMode() != KernelMode)
|
|
||||||
{
|
|
||||||
ProbeForWriteLangid(LanguageId);
|
|
||||||
}
|
|
||||||
|
|
||||||
*LanguageId = PsInstallUILanguageId;
|
|
||||||
}
|
|
||||||
_SEH_EXCEPT(_SEH_ExSystemExceptionFilter)
|
|
||||||
{
|
|
||||||
Status = _SEH_GetExceptionCode();
|
|
||||||
}
|
|
||||||
_SEH_END;
|
|
||||||
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* @implemented
|
|
||||||
*/
|
|
||||||
NTSTATUS STDCALL
|
|
||||||
NtSetDefaultUILanguage(IN LANGID LanguageId)
|
|
||||||
{
|
|
||||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
|
||||||
UNICODE_STRING KeyName = RTL_CONSTANT_STRING(L"Control Panel\\Desktop");
|
|
||||||
UNICODE_STRING ValueName = RTL_CONSTANT_STRING(L"MultiUILanguageId");
|
|
||||||
WCHAR ValueBuffer[8];
|
|
||||||
ULONG ValueLength;
|
|
||||||
HANDLE UserHandle;
|
|
||||||
HANDLE KeyHandle;
|
|
||||||
NTSTATUS Status;
|
|
||||||
|
|
||||||
PAGED_CODE();
|
|
||||||
|
|
||||||
Status = RtlOpenCurrentUser(KEY_WRITE,
|
|
||||||
&UserHandle);
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
InitializeObjectAttributes(&ObjectAttributes,
|
|
||||||
&KeyName,
|
|
||||||
OBJ_CASE_INSENSITIVE,
|
|
||||||
UserHandle,
|
|
||||||
NULL);
|
|
||||||
|
|
||||||
Status = ZwOpenKey(&KeyHandle,
|
|
||||||
KEY_SET_VALUE,
|
|
||||||
&ObjectAttributes);
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
ZwClose(UserHandle);
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
ValueLength = swprintf(ValueBuffer,
|
|
||||||
L"%04lX",
|
|
||||||
(ULONG)LanguageId);
|
|
||||||
ValueLength = (ValueLength + 1) * sizeof(WCHAR);
|
|
||||||
|
|
||||||
Status = ZwSetValueKey(KeyHandle,
|
|
||||||
&ValueName,
|
|
||||||
0,
|
|
||||||
REG_SZ,
|
|
||||||
ValueBuffer,
|
|
||||||
ValueLength);
|
|
||||||
|
|
||||||
ZwClose(KeyHandle);
|
|
||||||
ZwClose(UserHandle);
|
|
||||||
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* EOF */
|
|
Loading…
Add table
Add a link
Reference in a new issue