Implement NtQueryDefaultUILanguage, NtQueryInstallUILanguage and NtSetDefaultUILanguage.
authorEric Kohl <eric.kohl@reactos.org>
Thu, 16 Sep 2004 11:47:18 +0000 (11:47 +0000)
committerEric Kohl <eric.kohl@reactos.org>
Thu, 16 Sep 2004 11:47:18 +0000 (11:47 +0000)
svn path=/trunk/; revision=10873

reactos/lib/ntdll/def/ntdll.def
reactos/ntoskrnl/ps/locale.c

index 4ae3432..aa3ce72 100644 (file)
@@ -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
index 1561b8d..f770f12 100644 (file)
@@ -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 <ntoskrnl.h>
+
+#define NDEBUG
 #include <internal/debug.h>
 
 
@@ -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 (ThreadOrSystem == TRUE)
-     {
-        if (PsDefaultThreadLocaleInitialized == FALSE)
-          {
-             PiInitThreadLocale();
-          }
-       /* set thread locale */
-       *DefaultLocaleId = PsDefaultThreadLocaleId;
-     }
-   else
-     {
-       /* set system locale */
-       *DefaultLocaleId = PsDefaultSystemLocaleId;
-     }
-   return(STATUS_SUCCESS);
+  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;
 }
 
 
-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 */