From 9f8dc789cf0b4ef861d8b32927c3c4925d38c374 Mon Sep 17 00:00:00 2001 From: Eric Kohl Date: Thu, 16 Sep 2004 11:47:18 +0000 Subject: [PATCH] Implement NtQueryDefaultUILanguage, NtQueryInstallUILanguage and NtSetDefaultUILanguage. svn path=/trunk/; revision=10873 --- reactos/lib/ntdll/def/ntdll.def | 10 +- reactos/ntoskrnl/ps/locale.c | 274 +++++++++++++++++++++++++------- 2 files changed, 221 insertions(+), 63 deletions(-) diff --git a/reactos/lib/ntdll/def/ntdll.def b/reactos/lib/ntdll/def/ntdll.def index 4ae34329f12..aa3ce721b01 100644 --- a/reactos/lib/ntdll/def/ntdll.def +++ b/reactos/lib/ntdll/def/ntdll.def @@ -1,4 +1,4 @@ -; $Id: ntdll.def,v 1.130 2004/09/16 10:25:15 gvg Exp $ +; $Id: ntdll.def,v 1.131 2004/09/16 11:47:18 ekohl Exp $ ; ; ReactOS Operating System ; @@ -161,6 +161,7 @@ NtProtectVirtualMemory@20 NtPulseEvent@8 NtQueryAttributesFile@8 NtQueryDefaultLocale@8 +NtQueryDefaultUILanguage@4 NtQueryDirectoryFile@44 NtQueryDirectoryObject@28 NtQueryEaFile@36 @@ -172,8 +173,9 @@ NtQueryInformationPort@20 NtQueryInformationProcess@20 NtQueryInformationThread@20 NtQueryInformationToken@20 -NtQueryIoCompletion@20 +NtQueryInstallUILanguage@4 NtQueryIntervalProfile@8 +NtQueryIoCompletion@20 NtQueryKey@20 NtQueryMultipleValueKey@24 NtQueryMutant@20 @@ -219,6 +221,7 @@ NtSetContextChannel@4 NtSetContextThread@8 NtSetDefaultHardErrorPort@4 NtSetDefaultLocale@8 +NtSetDefaultUILanguage@4 NtSetEaFile@16 NtSetEvent@8 NtSetHighEventPair@4 @@ -776,6 +779,7 @@ ZwQueueApcThread@20 ZwQueryInformationAtom@20 ZwQueryAttributesFile@8 ZwQueryDefaultLocale@8 +ZwQueryDefaultUILanguage@4 ZwQueryDirectoryFile@44 ZwQueryDirectoryObject@28 ZwQueryEaFile@36 @@ -786,6 +790,7 @@ ZwQueryInformationPort@20 ZwQueryInformationProcess@20 ZwQueryInformationThread@20 ZwQueryInformationToken@20 +ZwQueryInstallUILanguage@4 ZwQueryIntervalProfile@8 ZwQueryIoCompletion@20 ZwQueryKey@20 @@ -832,6 +837,7 @@ ZwSetContextChannel@4 ZwSetContextThread@8 ZwSetDefaultHardErrorPort@4 ZwSetDefaultLocale@8 +ZwSetDefaultUILanguage@4 ZwSetEaFile@16 ZwSetEvent@8 ZwSetHighEventPair@4 diff --git a/reactos/ntoskrnl/ps/locale.c b/reactos/ntoskrnl/ps/locale.c index 1561b8d54dd..f770f121f56 100644 --- a/reactos/ntoskrnl/ps/locale.c +++ b/reactos/ntoskrnl/ps/locale.c @@ -1,4 +1,4 @@ -/* $Id: locale.c,v 1.10 2004/08/15 16:39:10 chorns Exp $ +/* $Id: locale.c,v 1.11 2004/09/16 11:45:06 ekohl Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -12,6 +12,8 @@ /* INCLUDES *****************************************************************/ #include + +#define NDEBUG #include @@ -24,12 +26,12 @@ LCID PsDefaultThreadLocaleId = 0; LCID PsDefaultSystemLocaleId = 0; BOOL PsDefaultThreadLocaleInitialized = FALSE; +static LANGID PsInstallUILanguageId = 0; + #define VALUE_BUFFER_SIZE 256 /* FUNCTIONS *****************************************************************/ -VOID INIT_FUNCTION -PiInitDefaultLocale(VOID) /* * FUNCTION: * Initializes the default locale. @@ -39,6 +41,8 @@ PiInitDefaultLocale(VOID) * Returns: * None. */ +VOID INIT_FUNCTION +PiInitDefaultLocale(VOID) { OBJECT_ATTRIBUTES ObjectAttributes; UNICODE_STRING KeyName; @@ -48,16 +52,13 @@ PiInitDefaultLocale(VOID) UCHAR ValueBuffer[VALUE_BUFFER_SIZE]; PKEY_VALUE_PARTIAL_INFORMATION ValueInfo; UNICODE_STRING ValueString; - ULONG LocaleValue; + ULONG Value; NTSTATUS Status; ValueInfo = (PKEY_VALUE_PARTIAL_INFORMATION)ValueBuffer; - /* read system locale */ RtlRosInitUnicodeStringFromLiteral(&KeyName, L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Nls\\Language"); - RtlRosInitUnicodeStringFromLiteral(&ValueName, - L"Default"); InitializeObjectAttributes(&ObjectAttributes, &KeyName, @@ -69,6 +70,9 @@ PiInitDefaultLocale(VOID) &ObjectAttributes); if (NT_SUCCESS(Status)) { + /* Read system locale */ + RtlRosInitUnicodeStringFromLiteral(&ValueName, + L"Default"); Status = NtQueryValueKey(KeyHandle, &ValueName, KeyValuePartialInformation, @@ -83,20 +87,44 @@ PiInitDefaultLocale(VOID) Status = RtlUnicodeStringToInteger(&ValueString, 16, - &LocaleValue); + &Value); if (NT_SUCCESS(Status)) { - DPRINT("System locale: %08lu\n", LocaleValue); - PsDefaultSystemLocaleId = (LCID)LocaleValue; + DPRINT("System locale: %08lx\n", Value); + PsDefaultSystemLocaleId = (LCID)Value; } } + + /* Read install language id */ + RtlRosInitUnicodeStringFromLiteral(&ValueName, + L"InstallLanguage"); + Status = NtQueryValueKey(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; + } + } + NtClose(KeyHandle); } } -VOID STDCALL -PiInitThreadLocale(VOID) /* * FUNCTION: * Initializes the default thread locale. @@ -106,6 +134,8 @@ PiInitThreadLocale(VOID) * Returns: * None. */ +VOID STDCALL +PiInitThreadLocale(VOID) { OBJECT_ATTRIBUTES ObjectAttributes; UNICODE_STRING KeyName; @@ -164,9 +194,6 @@ PiInitThreadLocale(VOID) } -NTSTATUS STDCALL -NtQueryDefaultLocale(IN BOOLEAN ThreadOrSystem, - OUT PLCID DefaultLocaleId) /* * FUNCTION: * Returns the default locale. @@ -177,31 +204,33 @@ NtQueryDefaultLocale(IN BOOLEAN ThreadOrSystem, * Returns: * Status. */ +NTSTATUS STDCALL +NtQueryDefaultLocale(IN BOOLEAN ThreadOrSystem, + OUT PLCID DefaultLocaleId) { - if (DefaultLocaleId == NULL) - return STATUS_UNSUCCESSFUL; + if (DefaultLocaleId == NULL) + return STATUS_UNSUCCESSFUL; - if (ThreadOrSystem == TRUE) - { - if (PsDefaultThreadLocaleInitialized == FALSE) - { - PiInitThreadLocale(); - } - /* set thread locale */ - *DefaultLocaleId = PsDefaultThreadLocaleId; - } - else - { - /* set system locale */ - *DefaultLocaleId = PsDefaultSystemLocaleId; - } - return(STATUS_SUCCESS); + if (ThreadOrSystem == TRUE) + { + if (PsDefaultThreadLocaleInitialized == FALSE) + { + PiInitThreadLocale(); + } + + /* set thread locale */ + *DefaultLocaleId = PsDefaultThreadLocaleId; + } + else + { + /* set system locale */ + *DefaultLocaleId = PsDefaultSystemLocaleId; + } + + return STATUS_SUCCESS; } -NTSTATUS STDCALL -NtSetDefaultLocale(IN BOOLEAN ThreadOrSystem, - IN LCID DefaultLocaleId) /* * FUNCTION: * Sets the default locale. @@ -212,6 +241,9 @@ NtSetDefaultLocale(IN BOOLEAN ThreadOrSystem, * Returns: * Status. */ +NTSTATUS STDCALL +NtSetDefaultLocale(IN BOOLEAN ThreadOrSystem, + IN LCID DefaultLocaleId) { OBJECT_ATTRIBUTES ObjectAttributes; UNICODE_STRING KeyName; @@ -261,7 +293,7 @@ NtSetDefaultLocale(IN BOOLEAN ThreadOrSystem, } ValueLength = swprintf(ValueBuffer, - L"%08lu", + L"%08lx", (ULONG)DefaultLocaleId); ValueLength = (ValueLength + 1) * sizeof(WCHAR); @@ -297,44 +329,164 @@ NtSetDefaultLocale(IN BOOLEAN ThreadOrSystem, PsDefaultSystemLocaleId = DefaultLocaleId; } - return(STATUS_SUCCESS); + return STATUS_SUCCESS; } + /* - * @unimplemented + * @implemented */ -NTSTATUS -STDCALL -NtQueryDefaultUILanguage( - PLANGID LanguageId - ) +NTSTATUS STDCALL +NtQueryDefaultUILanguage(OUT PLANGID LanguageId) { - UNIMPLEMENTED; - return STATUS_NOT_IMPLEMENTED; + UCHAR ValueBuffer[VALUE_BUFFER_SIZE]; + PKEY_VALUE_PARTIAL_INFORMATION ValueInfo; + OBJECT_ATTRIBUTES ObjectAttributes; + UNICODE_STRING KeyName; + UNICODE_STRING ValueName; + UNICODE_STRING ValueString; + ULONG ValueLength; + ULONG Value; + HANDLE UserKey; + HANDLE KeyHandle; + NTSTATUS Status; + + Status = RtlOpenCurrentUser(KEY_READ, + &UserKey); + if (!NT_SUCCESS(Status)) + { + *LanguageId = PsInstallUILanguageId; + return STATUS_SUCCESS; + } + + RtlRosInitUnicodeStringFromLiteral(&KeyName, + L"Control Panel\\International"); + RtlRosInitUnicodeStringFromLiteral(&ValueName, + L"MultiUILanguageId"); + + InitializeObjectAttributes(&ObjectAttributes, + &KeyName, + OBJ_CASE_INSENSITIVE, + UserKey, + NULL); + Status = NtOpenKey(&KeyHandle, + KEY_QUERY_VALUE, + &ObjectAttributes); + if (!NT_SUCCESS(Status)) + { + *LanguageId = PsInstallUILanguageId; + return STATUS_SUCCESS; + } + + ValueInfo = (PKEY_VALUE_PARTIAL_INFORMATION)ValueBuffer; + + Status = NtQueryValueKey(KeyHandle, + &ValueName, + KeyValuePartialInformation, + ValueBuffer, + VALUE_BUFFER_SIZE, + &ValueLength); + + NtClose(KeyHandle); + NtClose(UserKey); + + if (!NT_SUCCESS(Status) || ValueInfo->Type != REG_SZ) + { + *LanguageId = PsInstallUILanguageId; + return STATUS_SUCCESS; + } + + ValueString.Length = ValueInfo->DataLength; + ValueString.MaximumLength = ValueInfo->DataLength; + ValueString.Buffer = (PWSTR)ValueInfo->Data; + + Status = RtlUnicodeStringToInteger(&ValueString, + 16, + &Value); + if (!NT_SUCCESS(Status)) + { + *LanguageId = PsInstallUILanguageId; + return STATUS_SUCCESS; + } + + DPRINT("Default language id: %04lx\n", Value); + + *LanguageId = Value; + + return STATUS_SUCCESS; } + + /* - * @unimplemented + * @implemented */ -NTSTATUS -STDCALL -NtQueryInstallUILanguage( - PLANGID LanguageId - ) +NTSTATUS STDCALL +NtQueryInstallUILanguage(OUT PLANGID LanguageId) { - UNIMPLEMENTED; - return STATUS_NOT_IMPLEMENTED; + *LanguageId = PsInstallUILanguageId; + + return STATUS_SUCCESS; } + + /* - * @unimplemented + * @implemented */ -NTSTATUS -STDCALL -NtSetDefaultUILanguage( - LANGID LanguageId - ) +NTSTATUS STDCALL +NtSetDefaultUILanguage(IN LANGID LanguageId) { - UNIMPLEMENTED; - return STATUS_NOT_IMPLEMENTED; + OBJECT_ATTRIBUTES ObjectAttributes; + UNICODE_STRING KeyName; + UNICODE_STRING ValueName; + WCHAR ValueBuffer[8]; + ULONG ValueLength; + HANDLE UserHandle; + HANDLE KeyHandle; + NTSTATUS Status; + + Status = RtlOpenCurrentUser(KEY_WRITE, + &UserHandle); + if (!NT_SUCCESS(Status)) + { + return Status; + } + + RtlRosInitUnicodeStringFromLiteral(&KeyName, + L"Control Panel\\Desktop"); + RtlRosInitUnicodeStringFromLiteral(&ValueName, + L"MultiUILanguageId"); + + InitializeObjectAttributes(&ObjectAttributes, + &KeyName, + OBJ_CASE_INSENSITIVE, + UserHandle, + NULL); + + Status = NtOpenKey(&KeyHandle, + KEY_SET_VALUE, + &ObjectAttributes); + if (!NT_SUCCESS(Status)) + { + NtClose(UserHandle); + return Status; + } + + ValueLength = swprintf(ValueBuffer, + L"%04lX", + (ULONG)LanguageId); + ValueLength = (ValueLength + 1) * sizeof(WCHAR); + + Status = NtSetValueKey(KeyHandle, + &ValueName, + 0, + REG_SZ, + ValueBuffer, + ValueLength); + + NtClose(KeyHandle); + NtClose(UserHandle); + + return Status; } /* EOF */