3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * FILE: ntoskrnl/ps/locale.c
6 * PURPOSE: Locale support
8 * PROGRAMMERS: David Welch (welch@cwcom.net)
11 /* INCLUDES *****************************************************************/
16 #include <internal/debug.h>
19 /* GLOBALS *******************************************************************/
22 * Default setting: LANG_NEUTRAL, SUBLANG_NEUTRAL, SORT_DEFAULT
24 LCID PsDefaultThreadLocaleId
= 0;
25 LCID PsDefaultSystemLocaleId
= 0;
26 BOOL PsDefaultThreadLocaleInitialized
= FALSE
;
28 static LANGID PsInstallUILanguageId
= 0;
30 #define VALUE_BUFFER_SIZE 256
32 /* FUNCTIONS *****************************************************************/
36 * Initializes the default locale.
37 * Reads default locale from registry, if available
46 PiInitDefaultLocale(VOID
)
48 OBJECT_ATTRIBUTES ObjectAttributes
;
49 UNICODE_STRING KeyName
= RTL_CONSTANT_STRING(L
"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Nls\\Language");
50 UNICODE_STRING ValueName
;
53 UCHAR ValueBuffer
[VALUE_BUFFER_SIZE
];
54 PKEY_VALUE_PARTIAL_INFORMATION ValueInfo
;
55 UNICODE_STRING ValueString
;
59 ValueInfo
= (PKEY_VALUE_PARTIAL_INFORMATION
)ValueBuffer
;
61 InitializeObjectAttributes(&ObjectAttributes
,
66 Status
= ZwOpenKey(&KeyHandle
,
69 if (NT_SUCCESS(Status
))
71 /* Read system locale */
72 RtlInitUnicodeString(&ValueName
,
74 Status
= ZwQueryValueKey(KeyHandle
,
76 KeyValuePartialInformation
,
80 if ((NT_SUCCESS(Status
)) && (ValueInfo
->Type
== REG_SZ
))
82 ValueString
.Length
= ValueInfo
->DataLength
;
83 ValueString
.MaximumLength
= ValueInfo
->DataLength
;
84 ValueString
.Buffer
= (PWSTR
)ValueInfo
->Data
;
86 Status
= RtlUnicodeStringToInteger(&ValueString
,
89 if (NT_SUCCESS(Status
))
91 DPRINT("System locale: %08lx\n", Value
);
92 PsDefaultSystemLocaleId
= (LCID
)Value
;
96 /* Read install language id */
97 RtlInitUnicodeString(&ValueName
,
99 Status
= ZwQueryValueKey(KeyHandle
,
101 KeyValuePartialInformation
,
105 if ((NT_SUCCESS(Status
)) && (ValueInfo
->Type
== REG_SZ
))
107 ValueString
.Length
= ValueInfo
->DataLength
;
108 ValueString
.MaximumLength
= ValueInfo
->DataLength
;
109 ValueString
.Buffer
= (PWSTR
)ValueInfo
->Data
;
111 Status
= RtlUnicodeStringToInteger(&ValueString
,
114 if (NT_SUCCESS(Status
))
116 DPRINT("Install language id: %04lx\n", Value
);
117 PsInstallUILanguageId
= (LANGID
)Value
;
128 * Initializes the default thread locale.
129 * Reads default locale from registry, if available
136 PiInitThreadLocale(VOID
)
138 OBJECT_ATTRIBUTES ObjectAttributes
;
139 UNICODE_STRING KeyName
= RTL_CONSTANT_STRING(L
"\\Registry\\User\\.Default\\Control Panel\\International");
140 UNICODE_STRING ValueName
= RTL_CONSTANT_STRING(L
"Locale");
143 UCHAR ValueBuffer
[VALUE_BUFFER_SIZE
];
144 PKEY_VALUE_PARTIAL_INFORMATION ValueInfo
;
145 UNICODE_STRING ValueString
;
149 ValueInfo
= (PKEY_VALUE_PARTIAL_INFORMATION
)ValueBuffer
;
151 /* read default thread locale */
152 InitializeObjectAttributes(&ObjectAttributes
,
154 OBJ_CASE_INSENSITIVE
,
157 Status
= ZwOpenKey(&KeyHandle
,
160 if (NT_SUCCESS(Status
))
162 Status
= ZwQueryValueKey(KeyHandle
,
164 KeyValuePartialInformation
,
168 if ((NT_SUCCESS(Status
)) && (ValueInfo
->Type
== REG_SZ
))
170 ValueString
.Length
= ValueInfo
->DataLength
;
171 ValueString
.MaximumLength
= ValueInfo
->DataLength
;
172 ValueString
.Buffer
= (PWSTR
)ValueInfo
->Data
;
174 Status
= RtlUnicodeStringToInteger(&ValueString
,
177 if (NT_SUCCESS(Status
))
179 DPRINT("Thread locale: %08lu\n", LocaleValue
);
180 PsDefaultThreadLocaleId
= (LCID
)LocaleValue
;
186 PsDefaultThreadLocaleInitialized
= TRUE
;
192 * Returns the default locale.
194 * UserProfile = If TRUE then the locale for this thread is returned,
195 * otherwise the locale for the system is returned.
196 * DefaultLocaleId = Points to a variable that receives the locale id.
201 NtQueryDefaultLocale(IN BOOLEAN UserProfile
,
202 OUT PLCID DefaultLocaleId
)
204 NTSTATUS Status
= STATUS_SUCCESS
;
210 if (KeGetPreviousMode() != KernelMode
)
212 ProbeForWriteLangid(DefaultLocaleId
);
217 if (!PsDefaultThreadLocaleInitialized
)
219 PiInitThreadLocale();
222 /* set thread locale */
223 *DefaultLocaleId
= PsDefaultThreadLocaleId
;
227 /* set system locale */
228 *DefaultLocaleId
= PsDefaultSystemLocaleId
;
231 _SEH_EXCEPT(_SEH_ExSystemExceptionFilter
)
233 Status
= _SEH_GetExceptionCode();
243 * Sets the default locale.
245 * ThreadOrSystem = If TRUE then the locale for this thread is set,
246 * otherwise the locale for the system is set.
247 * DefaultLocaleId = The locale id to be set.
252 NtSetDefaultLocale(IN BOOLEAN UserProfile
,
253 IN LCID DefaultLocaleId
)
255 OBJECT_ATTRIBUTES ObjectAttributes
;
256 UNICODE_STRING KeyName
;
257 UNICODE_STRING ValueName
;
260 WCHAR ValueBuffer
[20];
261 HANDLE UserKey
= NULL
;
269 Status
= RtlOpenCurrentUser(KEY_WRITE
,
271 if (!NT_SUCCESS(Status
))
273 RtlInitUnicodeString(&KeyName
,
274 L
"Control Panel\\International");
275 RtlInitUnicodeString(&ValueName
,
281 RtlInitUnicodeString(&KeyName
,
282 L
"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Nls\\Language");
283 RtlInitUnicodeString(&ValueName
,
287 InitializeObjectAttributes(&ObjectAttributes
,
289 OBJ_CASE_INSENSITIVE
,
292 Status
= ZwOpenKey(&KeyHandle
,
295 if (!NT_SUCCESS(Status
))
306 ValueLength
= swprintf(ValueBuffer
,
308 (ULONG
)DefaultLocaleId
);
312 ValueLength
= swprintf(ValueBuffer
,
314 (ULONG
)DefaultLocaleId
& 0xFFFF);
316 ValueLength
= (ValueLength
+ 1) * sizeof(WCHAR
);
318 Status
= ZwSetValueKey(KeyHandle
,
331 if (!NT_SUCCESS(Status
))
338 /* set thread locale */
339 DPRINT("Thread locale: %08lu\n", DefaultLocaleId
);
340 PsDefaultThreadLocaleId
= DefaultLocaleId
;
341 PsDefaultThreadLocaleInitialized
= TRUE
;
345 /* set system locale */
346 DPRINT("System locale: %08lu\n", DefaultLocaleId
);
347 PsDefaultSystemLocaleId
= DefaultLocaleId
;
350 return STATUS_SUCCESS
;
358 NtQueryDefaultUILanguage(OUT PLANGID LanguageId
)
360 UCHAR ValueBuffer
[VALUE_BUFFER_SIZE
];
361 PKEY_VALUE_PARTIAL_INFORMATION ValueInfo
;
362 OBJECT_ATTRIBUTES ObjectAttributes
;
363 UNICODE_STRING KeyName
= RTL_CONSTANT_STRING(L
"Control Panel\\International");
364 UNICODE_STRING ValueName
= RTL_CONSTANT_STRING(L
"MultiUILanguageId");
365 UNICODE_STRING ValueString
;
370 NTSTATUS Status
= STATUS_SUCCESS
;
376 if (KeGetPreviousMode() != KernelMode
)
378 ProbeForWriteLangid(LanguageId
);
381 *LanguageId
= PsInstallUILanguageId
;
383 _SEH_EXCEPT(_SEH_ExSystemExceptionFilter
)
385 Status
= _SEH_GetExceptionCode();
389 if (!NT_SUCCESS(Status
))
394 Status
= RtlOpenCurrentUser(KEY_READ
,
396 if (!NT_SUCCESS(Status
))
398 Value
= PsInstallUILanguageId
;
402 InitializeObjectAttributes(&ObjectAttributes
,
404 OBJ_CASE_INSENSITIVE
,
407 Status
= ZwOpenKey(&KeyHandle
,
410 if (!NT_SUCCESS(Status
))
412 Value
= PsInstallUILanguageId
;
416 ValueInfo
= (PKEY_VALUE_PARTIAL_INFORMATION
)ValueBuffer
;
418 Status
= ZwQueryValueKey(KeyHandle
,
420 KeyValuePartialInformation
,
428 if (!NT_SUCCESS(Status
) || ValueInfo
->Type
!= REG_SZ
)
430 Value
= PsInstallUILanguageId
;
434 ValueString
.Length
= ValueInfo
->DataLength
;
435 ValueString
.MaximumLength
= ValueInfo
->DataLength
;
436 ValueString
.Buffer
= (PWSTR
)ValueInfo
->Data
;
438 Status
= RtlUnicodeStringToInteger(&ValueString
,
441 if (!NT_SUCCESS(Status
))
443 Value
= PsInstallUILanguageId
;
447 DPRINT("Default language id: %04lx\n", Value
);
453 Status
= STATUS_SUCCESS
;
455 _SEH_EXCEPT(_SEH_ExSystemExceptionFilter
)
457 Status
= _SEH_GetExceptionCode();
469 NtQueryInstallUILanguage(OUT PLANGID LanguageId
)
471 NTSTATUS Status
= STATUS_SUCCESS
;
477 if (KeGetPreviousMode() != KernelMode
)
479 ProbeForWriteLangid(LanguageId
);
482 *LanguageId
= PsInstallUILanguageId
;
484 _SEH_EXCEPT(_SEH_ExSystemExceptionFilter
)
486 Status
= _SEH_GetExceptionCode();
498 NtSetDefaultUILanguage(IN LANGID LanguageId
)
500 OBJECT_ATTRIBUTES ObjectAttributes
;
501 UNICODE_STRING KeyName
= RTL_CONSTANT_STRING(L
"Control Panel\\Desktop");
502 UNICODE_STRING ValueName
= RTL_CONSTANT_STRING(L
"MultiUILanguageId");
503 WCHAR ValueBuffer
[8];
511 Status
= RtlOpenCurrentUser(KEY_WRITE
,
513 if (!NT_SUCCESS(Status
))
518 InitializeObjectAttributes(&ObjectAttributes
,
520 OBJ_CASE_INSENSITIVE
,
524 Status
= ZwOpenKey(&KeyHandle
,
527 if (!NT_SUCCESS(Status
))
533 ValueLength
= swprintf(ValueBuffer
,
536 ValueLength
= (ValueLength
+ 1) * sizeof(WCHAR
);
538 Status
= ZwSetValueKey(KeyHandle
,