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
44 PiInitDefaultLocale(VOID
)
46 OBJECT_ATTRIBUTES ObjectAttributes
;
47 UNICODE_STRING KeyName
;
48 UNICODE_STRING ValueName
;
51 UCHAR ValueBuffer
[VALUE_BUFFER_SIZE
];
52 PKEY_VALUE_PARTIAL_INFORMATION ValueInfo
;
53 UNICODE_STRING ValueString
;
57 ValueInfo
= (PKEY_VALUE_PARTIAL_INFORMATION
)ValueBuffer
;
59 RtlRosInitUnicodeStringFromLiteral(&KeyName
,
60 L
"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Nls\\Language");
62 InitializeObjectAttributes(&ObjectAttributes
,
67 Status
= ZwOpenKey(&KeyHandle
,
70 if (NT_SUCCESS(Status
))
72 /* Read system locale */
73 RtlRosInitUnicodeStringFromLiteral(&ValueName
,
75 Status
= ZwQueryValueKey(KeyHandle
,
77 KeyValuePartialInformation
,
81 if ((NT_SUCCESS(Status
)) && (ValueInfo
->Type
== REG_SZ
))
83 ValueString
.Length
= ValueInfo
->DataLength
;
84 ValueString
.MaximumLength
= ValueInfo
->DataLength
;
85 ValueString
.Buffer
= (PWSTR
)ValueInfo
->Data
;
87 Status
= RtlUnicodeStringToInteger(&ValueString
,
90 if (NT_SUCCESS(Status
))
92 DPRINT("System locale: %08lx\n", Value
);
93 PsDefaultSystemLocaleId
= (LCID
)Value
;
97 /* Read install language id */
98 RtlRosInitUnicodeStringFromLiteral(&ValueName
,
100 Status
= ZwQueryValueKey(KeyHandle
,
102 KeyValuePartialInformation
,
106 if ((NT_SUCCESS(Status
)) && (ValueInfo
->Type
== REG_SZ
))
108 ValueString
.Length
= ValueInfo
->DataLength
;
109 ValueString
.MaximumLength
= ValueInfo
->DataLength
;
110 ValueString
.Buffer
= (PWSTR
)ValueInfo
->Data
;
112 Status
= RtlUnicodeStringToInteger(&ValueString
,
115 if (NT_SUCCESS(Status
))
117 DPRINT("Install language id: %04lx\n", Value
);
118 PsInstallUILanguageId
= (LANGID
)Value
;
129 * Initializes the default thread locale.
130 * Reads default locale from registry, if available
137 PiInitThreadLocale(VOID
)
139 OBJECT_ATTRIBUTES ObjectAttributes
;
140 UNICODE_STRING KeyName
;
141 UNICODE_STRING ValueName
;
144 UCHAR ValueBuffer
[VALUE_BUFFER_SIZE
];
145 PKEY_VALUE_PARTIAL_INFORMATION ValueInfo
;
146 UNICODE_STRING ValueString
;
150 ValueInfo
= (PKEY_VALUE_PARTIAL_INFORMATION
)ValueBuffer
;
152 /* read default thread locale */
153 RtlRosInitUnicodeStringFromLiteral(&KeyName
,
154 L
"\\Registry\\User\\.Default\\Control Panel\\International");
155 RtlRosInitUnicodeStringFromLiteral(&ValueName
,
158 InitializeObjectAttributes(&ObjectAttributes
,
160 OBJ_CASE_INSENSITIVE
,
163 Status
= ZwOpenKey(&KeyHandle
,
166 if (NT_SUCCESS(Status
))
168 Status
= ZwQueryValueKey(KeyHandle
,
170 KeyValuePartialInformation
,
174 if ((NT_SUCCESS(Status
)) && (ValueInfo
->Type
== REG_SZ
))
176 ValueString
.Length
= ValueInfo
->DataLength
;
177 ValueString
.MaximumLength
= ValueInfo
->DataLength
;
178 ValueString
.Buffer
= (PWSTR
)ValueInfo
->Data
;
180 Status
= RtlUnicodeStringToInteger(&ValueString
,
183 if (NT_SUCCESS(Status
))
185 DPRINT("Thread locale: %08lu\n", LocaleValue
);
186 PsDefaultThreadLocaleId
= (LCID
)LocaleValue
;
192 PsDefaultThreadLocaleInitialized
= TRUE
;
198 * Returns the default locale.
200 * UserProfile = If TRUE then the locale for this thread is returned,
201 * otherwise the locale for the system is returned.
202 * DefaultLocaleId = Points to a variable that receives the locale id.
207 NtQueryDefaultLocale(IN BOOLEAN UserProfile
,
208 OUT PLCID DefaultLocaleId
)
210 if (DefaultLocaleId
== NULL
)
211 return STATUS_UNSUCCESSFUL
;
215 if (!PsDefaultThreadLocaleInitialized
)
217 PiInitThreadLocale();
220 /* set thread locale */
221 *DefaultLocaleId
= PsDefaultThreadLocaleId
;
225 /* set system locale */
226 *DefaultLocaleId
= PsDefaultSystemLocaleId
;
229 return STATUS_SUCCESS
;
235 * Sets the default locale.
237 * ThreadOrSystem = If TRUE then the locale for this thread is set,
238 * otherwise the locale for the system is set.
239 * DefaultLocaleId = The locale id to be set.
244 NtSetDefaultLocale(IN BOOLEAN UserProfile
,
245 IN LCID DefaultLocaleId
)
247 OBJECT_ATTRIBUTES ObjectAttributes
;
248 UNICODE_STRING KeyName
;
249 UNICODE_STRING ValueName
;
252 WCHAR ValueBuffer
[20];
253 HANDLE UserKey
= NULL
;
259 Status
= RtlOpenCurrentUser(KEY_WRITE
,
261 if (!NT_SUCCESS(Status
))
263 RtlRosInitUnicodeStringFromLiteral(&KeyName
,
264 L
"Control Panel\\International");
265 RtlRosInitUnicodeStringFromLiteral(&ValueName
,
271 RtlRosInitUnicodeStringFromLiteral(&KeyName
,
272 L
"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Nls\\Language");
273 RtlRosInitUnicodeStringFromLiteral(&ValueName
,
277 InitializeObjectAttributes(&ObjectAttributes
,
279 OBJ_CASE_INSENSITIVE
,
282 Status
= ZwOpenKey(&KeyHandle
,
285 if (!NT_SUCCESS(Status
))
296 ValueLength
= swprintf(ValueBuffer
,
298 (ULONG
)DefaultLocaleId
);
302 ValueLength
= swprintf(ValueBuffer
,
304 (ULONG
)DefaultLocaleId
& 0xFFFF);
306 ValueLength
= (ValueLength
+ 1) * sizeof(WCHAR
);
308 Status
= ZwSetValueKey(KeyHandle
,
321 if (!NT_SUCCESS(Status
))
328 /* set thread locale */
329 DPRINT("Thread locale: %08lu\n", DefaultLocaleId
);
330 PsDefaultThreadLocaleId
= DefaultLocaleId
;
331 PsDefaultThreadLocaleInitialized
= TRUE
;
335 /* set system locale */
336 DPRINT("System locale: %08lu\n", DefaultLocaleId
);
337 PsDefaultSystemLocaleId
= DefaultLocaleId
;
340 return STATUS_SUCCESS
;
348 NtQueryDefaultUILanguage(OUT PLANGID LanguageId
)
350 UCHAR ValueBuffer
[VALUE_BUFFER_SIZE
];
351 PKEY_VALUE_PARTIAL_INFORMATION ValueInfo
;
352 OBJECT_ATTRIBUTES ObjectAttributes
;
353 UNICODE_STRING KeyName
;
354 UNICODE_STRING ValueName
;
355 UNICODE_STRING ValueString
;
362 Status
= RtlOpenCurrentUser(KEY_READ
,
364 if (!NT_SUCCESS(Status
))
366 *LanguageId
= PsInstallUILanguageId
;
367 return STATUS_SUCCESS
;
370 RtlRosInitUnicodeStringFromLiteral(&KeyName
,
371 L
"Control Panel\\International");
372 RtlRosInitUnicodeStringFromLiteral(&ValueName
,
373 L
"MultiUILanguageId");
375 InitializeObjectAttributes(&ObjectAttributes
,
377 OBJ_CASE_INSENSITIVE
,
380 Status
= ZwOpenKey(&KeyHandle
,
383 if (!NT_SUCCESS(Status
))
385 *LanguageId
= PsInstallUILanguageId
;
386 return STATUS_SUCCESS
;
389 ValueInfo
= (PKEY_VALUE_PARTIAL_INFORMATION
)ValueBuffer
;
391 Status
= ZwQueryValueKey(KeyHandle
,
393 KeyValuePartialInformation
,
401 if (!NT_SUCCESS(Status
) || ValueInfo
->Type
!= REG_SZ
)
403 *LanguageId
= PsInstallUILanguageId
;
404 return STATUS_SUCCESS
;
407 ValueString
.Length
= ValueInfo
->DataLength
;
408 ValueString
.MaximumLength
= ValueInfo
->DataLength
;
409 ValueString
.Buffer
= (PWSTR
)ValueInfo
->Data
;
411 Status
= RtlUnicodeStringToInteger(&ValueString
,
414 if (!NT_SUCCESS(Status
))
416 *LanguageId
= PsInstallUILanguageId
;
417 return STATUS_SUCCESS
;
420 DPRINT("Default language id: %04lx\n", Value
);
424 return STATUS_SUCCESS
;
432 NtQueryInstallUILanguage(OUT PLANGID LanguageId
)
434 *LanguageId
= PsInstallUILanguageId
;
436 return STATUS_SUCCESS
;
444 NtSetDefaultUILanguage(IN LANGID LanguageId
)
446 OBJECT_ATTRIBUTES ObjectAttributes
;
447 UNICODE_STRING KeyName
;
448 UNICODE_STRING ValueName
;
449 WCHAR ValueBuffer
[8];
455 Status
= RtlOpenCurrentUser(KEY_WRITE
,
457 if (!NT_SUCCESS(Status
))
462 RtlRosInitUnicodeStringFromLiteral(&KeyName
,
463 L
"Control Panel\\Desktop");
464 RtlRosInitUnicodeStringFromLiteral(&ValueName
,
465 L
"MultiUILanguageId");
467 InitializeObjectAttributes(&ObjectAttributes
,
469 OBJ_CASE_INSENSITIVE
,
473 Status
= ZwOpenKey(&KeyHandle
,
476 if (!NT_SUCCESS(Status
))
482 ValueLength
= swprintf(ValueBuffer
,
485 ValueLength
= (ValueLength
+ 1) * sizeof(WCHAR
);
487 Status
= ZwSetValueKey(KeyHandle
,