mirror of
https://github.com/reactos/reactos.git
synced 2025-04-27 09:00:27 +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 */
|
||||
PsLocateSystemDll();
|
||||
|
||||
/* Initialize the Default Locale */
|
||||
PiInitDefaultLocale();
|
||||
|
||||
/* Initialize shared user page. Set dos system path, dos device map, etc. */
|
||||
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_CREATE_PROCESS_NOTIFY 8
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
PiInitDefaultLocale(VOID);
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
PiInitProcessManager(VOID);
|
||||
|
|
|
@ -129,6 +129,7 @@
|
|||
<file>fmutex.c</file>
|
||||
<file>handle.c</file>
|
||||
<file>init.c</file>
|
||||
<file>locale.c</file>
|
||||
<file>lookas.c</file>
|
||||
<file>mutant.c</file>
|
||||
<file>power.c</file>
|
||||
|
@ -288,7 +289,6 @@
|
|||
<file>idle.c</file>
|
||||
<file>job.c</file>
|
||||
<file>kill.c</file>
|
||||
<file>locale.c</file>
|
||||
<file>notify.c</file>
|
||||
<file>process.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…
Reference in a new issue