From 6cf95d5263f3550d59c0cd7e86fa2e98995f0ebb Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Tue, 18 Jul 2006 01:58:10 +0000 Subject: [PATCH] - 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 --- reactos/ntoskrnl/ex/init.c | 3 - reactos/ntoskrnl/ex/locale.c | 405 ++++++++++++++++++ reactos/ntoskrnl/include/internal/ps.h | 4 - reactos/ntoskrnl/ntoskrnl.rbuild | 2 +- reactos/ntoskrnl/ps/locale.c | 555 ------------------------- 5 files changed, 406 insertions(+), 563 deletions(-) create mode 100644 reactos/ntoskrnl/ex/locale.c delete mode 100644 reactos/ntoskrnl/ps/locale.c diff --git a/reactos/ntoskrnl/ex/init.c b/reactos/ntoskrnl/ex/init.c index f9c1e11f275..2e3da6baf89 100644 --- a/reactos/ntoskrnl/ex/init.c +++ b/reactos/ntoskrnl/ex/init.c @@ -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); diff --git a/reactos/ntoskrnl/ex/locale.c b/reactos/ntoskrnl/ex/locale.c new file mode 100644 index 00000000000..d969a04a92f --- /dev/null +++ b/reactos/ntoskrnl/ex/locale.c @@ -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 +#define NDEBUG +#include + +/* 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 */ diff --git a/reactos/ntoskrnl/include/internal/ps.h b/reactos/ntoskrnl/include/internal/ps.h index 33cfaaa1153..12031c4836b 100644 --- a/reactos/ntoskrnl/include/internal/ps.h +++ b/reactos/ntoskrnl/include/internal/ps.h @@ -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); diff --git a/reactos/ntoskrnl/ntoskrnl.rbuild b/reactos/ntoskrnl/ntoskrnl.rbuild index 604d3568b6a..3daae508c59 100644 --- a/reactos/ntoskrnl/ntoskrnl.rbuild +++ b/reactos/ntoskrnl/ntoskrnl.rbuild @@ -129,6 +129,7 @@ fmutex.c handle.c init.c + locale.c lookas.c mutant.c power.c @@ -288,7 +289,6 @@ idle.c job.c kill.c - locale.c notify.c process.c psmgr.c diff --git a/reactos/ntoskrnl/ps/locale.c b/reactos/ntoskrnl/ps/locale.c deleted file mode 100644 index 50ae019509b..00000000000 --- a/reactos/ntoskrnl/ps/locale.c +++ /dev/null @@ -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 - -#define NDEBUG -#include - -#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 */