2 * PROJECT: ReactOS Kernel
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: ntoskrnl/ex/locale.c
5 * PURPOSE: Locale (Language) Support for the Executive
6 * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
8 * Thomas Weidenmueller (w3seek@reactos.org
11 /* INCLUDES ******************************************************************/
17 /* GLOBALS *******************************************************************/
19 /* System IDs: EN_US */
20 LCID PsDefaultSystemLocaleId
= 0x00000409;
21 LANGID PsInstallUILanguageId
= LANGIDFROMLCID(0x00000409);
23 /* UI/Thread IDs: Same as system */
24 LANGID PsDefaultUILanguageId
= 0x00000409;
25 LCID PsDefaultThreadLocaleId
= LANGIDFROMLCID(0x00000409);
27 /* PRIVATE FUNCTIONS *********************************************************/
31 ExpGetCurrentUserUILanguage(IN PWSTR MuiName
,
32 OUT LANGID
* LanguageId
)
34 UCHAR ValueBuffer
[256];
35 PKEY_VALUE_PARTIAL_INFORMATION ValueInfo
;
36 OBJECT_ATTRIBUTES ObjectAttributes
;
37 UNICODE_STRING KeyName
=
38 RTL_CONSTANT_STRING(L
"Control Panel\\International");
39 UNICODE_STRING ValueName
;
40 UNICODE_STRING ValueString
;
48 /* Setup the key name */
49 RtlInitUnicodeString(&ValueName
, MuiName
);
51 /* Open the use key */
52 Status
= RtlOpenCurrentUser(KEY_READ
, &UserKey
);
53 if (!NT_SUCCESS(Status
)) return Status
;
55 /* Initialize the attributes and open the key */
56 InitializeObjectAttributes(&ObjectAttributes
,
61 Status
= ZwOpenKey(&KeyHandle
, KEY_QUERY_VALUE
,&ObjectAttributes
);
62 if (NT_SUCCESS(Status
))
64 /* Set buffer and query the current value */
65 ValueInfo
= (PKEY_VALUE_PARTIAL_INFORMATION
)ValueBuffer
;
66 Status
= ZwQueryValueKey(KeyHandle
,
68 KeyValuePartialInformation
,
72 if (NT_SUCCESS(Status
))
74 /* Success, is the value the right type? */
75 if (ValueInfo
->Type
== REG_SZ
)
77 /* It is. Initialize the data and convert it */
78 RtlInitUnicodeString(&ValueString
, (PWSTR
)ValueInfo
->Data
);
79 Status
= RtlUnicodeStringToInteger(&ValueString
, 16, &Value
);
80 if (NT_SUCCESS(Status
))
82 /* Return the language */
83 *LanguageId
= (USHORT
)Value
;
89 Status
= STATUS_UNSUCCESSFUL
;
97 /* Close the user key and return */
104 ExpSetCurrentUserUILanguage(IN PWSTR MuiName
,
105 IN LANGID LanguageId
)
107 OBJECT_ATTRIBUTES ObjectAttributes
;
108 UNICODE_STRING KeyName
= RTL_CONSTANT_STRING(L
"Control Panel\\Desktop");
109 UNICODE_STRING ValueName
;
110 WCHAR ValueBuffer
[8];
117 /* Setup the key name */
118 RtlInitUnicodeString(&ValueName
, MuiName
);
120 /* Open the use key */
121 Status
= RtlOpenCurrentUser(KEY_WRITE
, &UserHandle
);
122 if (!NT_SUCCESS(Status
)) return Status
;
124 /* Initialize the attributes */
125 InitializeObjectAttributes(&ObjectAttributes
,
127 OBJ_CASE_INSENSITIVE
| OBJ_KERNEL_HANDLE
,
132 Status
= ZwOpenKey(&KeyHandle
, KEY_SET_VALUE
, &ObjectAttributes
);
133 if (NT_SUCCESS(Status
))
135 /* Setup the value name */
136 ValueLength
= swprintf(ValueBuffer
,
140 /* Set the length for the call and set the value */
141 ValueLength
= (ValueLength
+ 1) * sizeof(WCHAR
);
142 Status
= ZwSetValueKey(KeyHandle
,
149 /* Close the handle for this key */
153 /* Close the user key and return status */
158 /* PUBLIC FUNCTIONS **********************************************************/
162 NtQueryDefaultLocale(IN BOOLEAN UserProfile
,
163 OUT PLCID DefaultLocaleId
)
165 NTSTATUS Status
= STATUS_SUCCESS
;
168 /* Enter SEH for probing */
171 /* Check if we came from user mode */
172 if (KeGetPreviousMode() != KernelMode
)
174 /* Probe the language ID */
175 ProbeForWriteLangid(DefaultLocaleId
);
178 /* Check if we have a user profile */
181 /* Return thread locale */
182 *DefaultLocaleId
= PsDefaultThreadLocaleId
;
186 /* Return system locale */
187 *DefaultLocaleId
= PsDefaultSystemLocaleId
;
190 _SEH2_EXCEPT(ExSystemExceptionFilter())
192 /* Get exception code */
193 Status
= _SEH2_GetExceptionCode();
203 NtSetDefaultLocale(IN BOOLEAN UserProfile
,
204 IN LCID DefaultLocaleId
)
206 OBJECT_ATTRIBUTES ObjectAttributes
;
207 UNICODE_STRING KeyName
;
208 UNICODE_STRING ValueName
;
211 WCHAR ValueBuffer
[20];
212 HANDLE UserKey
= NULL
;
216 /* Check if we have a profile */
219 /* Open the user's key */
220 Status
= RtlOpenCurrentUser(KEY_WRITE
, &UserKey
);
221 if (!NT_SUCCESS(Status
)) return(Status
);
223 /* Initialize the registry location */
224 RtlInitUnicodeString(&KeyName
, L
"Control Panel\\International");
225 RtlInitUnicodeString(&ValueName
, L
"Locale");
229 /* Initialize the system registry location */
230 RtlInitUnicodeString(&KeyName
,
231 L
"\\Registry\\Machine\\System\\CurrentControlSet"
232 L
"\\Control\\Nls\\Language");
233 RtlInitUnicodeString(&ValueName
, L
"Default");
236 /* Initailize the object attributes */
237 InitializeObjectAttributes(&ObjectAttributes
,
239 OBJ_CASE_INSENSITIVE
| OBJ_KERNEL_HANDLE
,
243 /* Check if we don' thave a default locale yet */
244 if (!DefaultLocaleId
)
247 Status
= STATUS_SUCCESS
;
252 /* Otherwise, open the key */
253 Status
= ZwOpenKey(&KeyHandle
, KEY_SET_VALUE
, &ObjectAttributes
);
254 if (NT_SUCCESS(Status
))
256 /* Check if we had a profile */
259 /* Fill in the buffer */
260 ValueLength
= swprintf(ValueBuffer
,
262 (ULONG
)DefaultLocaleId
);
266 /* Fill in the buffer */
267 ValueLength
= swprintf(ValueBuffer
,
269 (ULONG
)DefaultLocaleId
& 0xFFFF);
272 /* Set the length for the registry call */
273 ValueLength
= (ValueLength
+ 1) * sizeof(WCHAR
);
275 /* Now write the actual value */
276 Status
= ZwSetValueKey(KeyHandle
,
283 /* And close the key */
288 /* Close the user key */
291 /* Check for success */
292 if (NT_SUCCESS(Status
))
294 /* Check if it was for a user */
297 /* Set thread locale */
298 PsDefaultThreadLocaleId
= DefaultLocaleId
;
302 /* Set system locale */
303 PsDefaultSystemLocaleId
= DefaultLocaleId
;
316 NtQueryInstallUILanguage(OUT LANGID
* LanguageId
)
318 NTSTATUS Status
= STATUS_SUCCESS
;
321 /* Enter SEH for probing */
324 /* Check if we came from user mode */
325 if (KeGetPreviousMode() != KernelMode
)
327 /* Probe the Language ID */
328 ProbeForWriteLangid(LanguageId
);
332 *LanguageId
= PsInstallUILanguageId
;
334 _SEH2_EXCEPT(ExSystemExceptionFilter())
336 /* Get exception code */
337 Status
= _SEH2_GetExceptionCode();
350 NtQueryDefaultUILanguage(OUT LANGID
* LanguageId
)
352 NTSTATUS Status
= STATUS_SUCCESS
;
355 /* Enter SEH for probing */
358 /* Check if we came from user mode */
359 if (KeGetPreviousMode() != KernelMode
)
361 /* Probe the Language ID */
362 ProbeForWriteLangid(LanguageId
);
365 /* Call the executive helper routine */
366 Status
= ExpGetCurrentUserUILanguage(L
"MultiUILanguageId", LanguageId
);
367 if (NT_SUCCESS(Status
))
369 /* Success, return the language */
370 *LanguageId
= PsInstallUILanguageId
;
373 _SEH2_EXCEPT(ExSystemExceptionFilter())
375 /* Get exception code */
376 Status
= _SEH2_GetExceptionCode();
389 NtSetDefaultUILanguage(IN LANGID LanguageId
)
393 /* Check if we don't have a default yet */
401 /* Otherwise, call the internal routine */
402 return ExpSetCurrentUserUILanguage(L
"MUILanguagePending", LanguageId
);