- 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:
Alex Ionescu 2006-07-18 01:58:10 +00:00
parent 26331352ea
commit 6cf95d5263
5 changed files with 406 additions and 563 deletions

View file

@ -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);

View 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 */

View file

@ -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);

View file

@ -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>

View 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 */