ReactOS 0.4.17-dev-116-ga4b6fe9
locale.c File Reference
#include <ntoskrnl.h>
#include <debug.h>
Include dependency graph for locale.c:

Go to the source code of this file.

Macros

#define NDEBUG
 
#define BOGUS_LOCALE_ID   0xFFFF0000
 

Functions

static __inline BOOLEAN ExpValidateNlsLocaleData (_In_ PKEY_VALUE_PARTIAL_INFORMATION LocaleData)
 Validates the registry data of a NLS locale.
 
static NTSTATUS ExpValidateNlsLocaleId (_In_ LCID LocaleId)
 Validates a NLS locale. Whether a locale is valid or not depends on the following conditions:
 
NTSTATUS NTAPI ExpGetCurrentUserUILanguage (IN PCWSTR MuiName, OUT LANGID *LanguageId)
 
NTSTATUS NTAPI ExpSetCurrentUserUILanguage (IN PCWSTR MuiName, IN LANGID LanguageId)
 
NTSTATUS NTAPI NtQueryDefaultLocale (IN BOOLEAN UserProfile, OUT PLCID DefaultLocaleId)
 
NTSTATUS NTAPI NtSetDefaultLocale (IN BOOLEAN UserProfile, IN LCID DefaultLocaleId)
 
NTSTATUS NTAPI NtQueryInstallUILanguage (OUT LANGID *LanguageId)
 
NTSTATUS NTAPI NtQueryDefaultUILanguage (OUT LANGID *LanguageId)
 
NTSTATUS NTAPI NtSetDefaultUILanguage (IN LANGID LanguageId)
 

Variables

LCID PsDefaultSystemLocaleId = 0x00000409
 
LANGID PsInstallUILanguageId = LANGIDFROMLCID(0x00000409)
 
LCID PsDefaultThreadLocaleId = 0x00000409
 
LANGID PsDefaultUILanguageId = LANGIDFROMLCID(0x00000409)
 

Macro Definition Documentation

◆ BOGUS_LOCALE_ID

#define BOGUS_LOCALE_ID   0xFFFF0000

Definition at line 29 of file locale.c.

◆ NDEBUG

#define NDEBUG

Definition at line 14 of file locale.c.

Function Documentation

◆ ExpGetCurrentUserUILanguage()

NTSTATUS NTAPI ExpGetCurrentUserUILanguage ( IN PCWSTR  MuiName,
OUT LANGID LanguageId 
)

Definition at line 252 of file locale.c.

254{
255 UCHAR ValueBuffer[256];
259 RTL_CONSTANT_STRING(L"Control Panel\\Desktop");
261 UNICODE_STRING ValueString;
263 ULONG Value;
264 HANDLE UserKey;
267 PAGED_CODE();
268
269 /* Setup the key name */
271
272 /* Open the use key */
274 if (!NT_SUCCESS(Status)) return Status;
275
276 /* Initialize the attributes and open the key */
278 &KeyName,
280 UserKey,
281 NULL);
283 if (NT_SUCCESS(Status))
284 {
285 /* Set buffer and query the current value */
286 ValueInfo = (PKEY_VALUE_PARTIAL_INFORMATION)ValueBuffer;
287 Status = ZwQueryValueKey(KeyHandle,
288 &ValueName,
290 ValueBuffer,
291 sizeof(ValueBuffer),
292 &ValueLength);
293 if (NT_SUCCESS(Status))
294 {
295 /* Success, is the value the right type? */
296 if (ValueInfo->Type == REG_SZ)
297 {
298 /* It is. Initialize the data and convert it */
299 RtlInitUnicodeString(&ValueString, (PWSTR)ValueInfo->Data);
300 Status = RtlUnicodeStringToInteger(&ValueString, 16, &Value);
301 if (NT_SUCCESS(Status))
302 {
303 /* Return the language */
304 *LanguageId = (USHORT)Value;
305 }
306 }
307 else
308 {
309 /* Fail */
311 }
312 }
313
314 /* Close the key */
316 }
317
318 /* Close the user key and return */
319 ZwClose(UserKey);
320 return Status;
321}
#define PAGED_CODE()
LONG NTSTATUS
Definition: precomp.h:26
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:36
#define NULL
Definition: types.h:112
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
#define RTL_CONSTANT_STRING(s)
Definition: combase.c:35
#define REG_SZ
Definition: locale.c:45
#define L(x)
Definition: resources.c:13
Status
Definition: gdiplustypes.h:25
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:115
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ ULONG _Out_ PNDIS_STRING _Out_ PNDIS_HANDLE KeyHandle
Definition: ndis.h:4715
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
NTSYSAPI NTSTATUS NTAPI RtlOpenCurrentUser(_In_ ACCESS_MASK DesiredAccess, _Out_ PHANDLE KeyHandle)
@ KeyValuePartialInformation
Definition: nt_native.h:1185
#define KEY_READ
Definition: nt_native.h:1026
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
NTSYSAPI NTSTATUS NTAPI RtlUnicodeStringToInteger(PUNICODE_STRING String, ULONG Base, PULONG Value)
#define KEY_QUERY_VALUE
Definition: nt_native.h:1019
struct _KEY_VALUE_PARTIAL_INFORMATION * PKEY_VALUE_PARTIAL_INFORMATION
unsigned short USHORT
Definition: pedump.c:61
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
uint16_t * PWSTR
Definition: typedefs.h:56
unsigned char UCHAR
Definition: typedefs.h:53
uint32_t ULONG
Definition: typedefs.h:59
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
_Must_inspect_result_ _In_ WDFDEVICE _In_ PCUNICODE_STRING KeyName
Definition: wdfdevice.h:2705
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING ValueName
Definition: wdfregistry.h:243
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _In_ ULONG ValueLength
Definition: wdfregistry.h:275
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _Out_opt_ PUSHORT _Inout_opt_ PUNICODE_STRING Value
Definition: wdfregistry.h:413

Referenced by NtQueryDefaultUILanguage(), and NtSetDefaultUILanguage().

◆ ExpSetCurrentUserUILanguage()

NTSTATUS NTAPI ExpSetCurrentUserUILanguage ( IN PCWSTR  MuiName,
IN LANGID  LanguageId 
)

Definition at line 325 of file locale.c.

327{
329 UNICODE_STRING KeyName = RTL_CONSTANT_STRING(L"Control Panel\\Desktop");
331 WCHAR ValueBuffer[8];
333 HANDLE UserHandle;
336 PAGED_CODE();
337
338 /* Check that the passed language ID is not bogus */
339 if (LanguageId & BOGUS_LOCALE_ID)
340 {
342 }
343
344 /* Setup the key name */
346
347 /* Open the use key */
348 Status = RtlOpenCurrentUser(KEY_WRITE, &UserHandle);
349 if (!NT_SUCCESS(Status)) return Status;
350
351 /* Initialize the attributes */
353 &KeyName,
355 UserHandle,
356 NULL);
357
358 /* Validate the language ID */
360 if (NT_SUCCESS(Status))
361 {
362 /* Open the key */
364 if (NT_SUCCESS(Status))
365 {
366 /* Setup the value name */
367 ValueLength = _swprintf(ValueBuffer, L"%04lX", (ULONG)LanguageId);
368
369 /* Set the length for the call and set the value */
370 ValueLength = (ValueLength + 1) * sizeof(WCHAR);
371 Status = ZwSetValueKey(KeyHandle,
372 &ValueName,
373 0,
374 REG_SZ,
375 ValueBuffer,
377
378 /* Close the handle for this key */
380 }
381 }
382
383 /* Close the user key and return status */
384 ZwClose(UserHandle);
385 return Status;
386}
#define _swprintf(buf, format,...)
Definition: sprintf.c:56
#define KEY_WRITE
Definition: nt_native.h:1034
#define KEY_SET_VALUE
Definition: nt_native.h:1020
#define SORT_DEFAULT
#define MAKELCID(lgid, srtid)
static NTSTATUS ExpValidateNlsLocaleId(_In_ LCID LocaleId)
Validates a NLS locale. Whether a locale is valid or not depends on the following conditions:
Definition: locale.c:103
#define BOGUS_LOCALE_ID
Definition: locale.c:29
short WCHAR
Definition: pedump.c:58
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135

Referenced by NtSetDefaultUILanguage().

◆ ExpValidateNlsLocaleData()

static __inline BOOLEAN ExpValidateNlsLocaleData ( _In_ PKEY_VALUE_PARTIAL_INFORMATION  LocaleData)
static

Validates the registry data of a NLS locale.

Parameters
[in]LocaleDataA pointer to partial information that contains the NLS locale data.
Returns
Returns TRUE if the following conditions are met, otherwise FALSE is returned.

Definition at line 48 of file locale.c.

50{
52
53 /* Is this a null-terminated string type? */
54 if (LocaleData->Type != REG_SZ)
55 {
56 return FALSE;
57 }
58
59 /* Does it have a consistent length? */
60 if (LocaleData->DataLength < sizeof(WCHAR))
61 {
62 return FALSE;
63 }
64
65 /* Is the locale set and null-terminated? */
66 Data = (PWSTR)LocaleData->Data;
67 if (Data[0] != L'1' || Data[1] != UNICODE_NULL)
68 {
69 return FALSE;
70 }
71
72 /* All of the conditions above are met */
73 return TRUE;
74}
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
if(dx< 0)
Definition: linetemp.h:194
#define UNICODE_NULL
Data(int index, int value)
Definition: sort_test.cpp:78
uint16_t * PWCHAR
Definition: typedefs.h:56

Referenced by ExpValidateNlsLocaleId().

◆ ExpValidateNlsLocaleId()

static NTSTATUS ExpValidateNlsLocaleId ( _In_ LCID  LocaleId)
static

Validates a NLS locale. Whether a locale is valid or not depends on the following conditions:

  • The locale must exist in the Locale key, otherwise in the Alternate Sorts key;
  • The locale must exist in the Language Groups key, and the queried value must be readable;
  • The locale registry data must be of REG_SIZE type, has a consistent length and the locale belongs to a supported language group that is set.
Parameters
[in]LocaleIdA locale identifier that corresponds to a specific locale to be validated.
Returns
Returns STATUS_SUCCESS if the function has successfully validated the locale and it is valid. STATUS_OBJECT_NAME_NOT_FOUND is returned if the following locale does not exist on the system. A failure NTSTATUS code is returned otherwise.

Definition at line 103 of file locale.c.

105{
107 HANDLE NlsLocaleKey = NULL, AltSortKey = NULL, LangGroupKey = NULL;
108 OBJECT_ATTRIBUTES NlsLocalKeyAttrs, AltSortKeyAttrs, LangGroupKeyAttrs;
110 WCHAR ValueBuffer[20], LocaleIdBuffer[20];
112 UNICODE_STRING LocaleIdString;
113 static UNICODE_STRING NlsLocaleKeyPath = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\Nls\\Locale");
114 static UNICODE_STRING AltSortKeyPath = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\Nls\\Locale\\Alternate Sorts");
115 static UNICODE_STRING LangGroupPath = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\Nls\\Language Groups");
116
117 /* Initialize the registry path attributes */
118 InitializeObjectAttributes(&NlsLocalKeyAttrs,
119 &NlsLocaleKeyPath,
121 NULL,
122 NULL);
123
124 InitializeObjectAttributes(&AltSortKeyAttrs,
125 &AltSortKeyPath,
127 NULL,
128 NULL);
129
130 InitializeObjectAttributes(&LangGroupKeyAttrs,
131 &LangGroupPath,
133 NULL,
134 NULL);
135
136 /* Copy the locale ID into a buffer */
137 _swprintf(LocaleIdBuffer, L"%08lx", (ULONG)LocaleId);
138
139 /* And build the LCID string */
140 RtlInitUnicodeString(&LocaleIdString, LocaleIdBuffer);
141
142 /* Open the NLS locale key */
143 Status = ZwOpenKey(&NlsLocaleKey,
145 &NlsLocalKeyAttrs);
146 if (!NT_SUCCESS(Status))
147 {
148 DPRINT1("Failed to open %wZ (Status 0x%lx)\n", NlsLocaleKeyPath, Status);
149 return Status;
150 }
151
152 /* Open the NLS alternate sort locales key */
153 Status = ZwOpenKey(&AltSortKey,
155 &AltSortKeyAttrs);
156 if (!NT_SUCCESS(Status))
157 {
158 DPRINT1("Failed to open %wZ (Status 0x%lx)\n", AltSortKeyPath, Status);
159 goto Quit;
160 }
161
162 /* Open the NLS language groups key */
163 Status = ZwOpenKey(&LangGroupKey,
165 &LangGroupKeyAttrs);
166 if (!NT_SUCCESS(Status))
167 {
168 DPRINT1("Failed to open %wZ (Status 0x%lx)\n", LangGroupPath, Status);
169 goto Quit;
170 }
171
172 /* Check if the captured locale ID exists in the list of other locales */
173 BufferKey = (PKEY_VALUE_PARTIAL_INFORMATION)ValueBuffer;
174 Status = ZwQueryValueKey(NlsLocaleKey,
175 &LocaleIdString,
177 BufferKey,
178 sizeof(ValueBuffer),
180 if (!NT_SUCCESS(Status))
181 {
182 /* We failed, retry by looking at the alternate sorts locales */
183 Status = ZwQueryValueKey(AltSortKey,
184 &LocaleIdString,
186 BufferKey,
187 sizeof(ValueBuffer),
189 if (!NT_SUCCESS(Status))
190 {
191 DPRINT1("Failed to query value from Alternate Sorts key (Status 0x%lx)\n", Status);
192 goto Quit;
193 }
194 }
195
196 /* Ensure the queried locale is of the right key type with a sane length */
197 if (BufferKey->Type != REG_SZ ||
198 BufferKey->DataLength < sizeof(WCHAR))
199 {
200 DPRINT1("The queried locale is of bad value type or length (Type %lu, DataLength %lu)\n",
201 BufferKey->Type, BufferKey->DataLength);
203 goto Quit;
204 }
205
206 /* We got what we need, now query the locale from the language groups */
207 RtlInitUnicodeString(&LocaleIdString, (PWSTR)BufferKey->Data);
208 Status = ZwQueryValueKey(LangGroupKey,
209 &LocaleIdString,
211 BufferKey,
212 sizeof(ValueBuffer),
214 if (!NT_SUCCESS(Status))
215 {
216 DPRINT1("Failed to query value from Language Groups key (Status 0x%lx)\n", Status);
217 goto Quit;
218 }
219
220 /*
221 * We have queried the locale with its data. However we are not finished here yet,
222 * because the locale data could be malformed or the locale itself was not set
223 * so ensure all of these conditions are met.
224 */
225 if (!ExpValidateNlsLocaleData(BufferKey))
226 {
227 DPRINT1("The locale data is not valid!\n");
229 }
230
231Quit:
232 if (LangGroupKey != NULL)
233 {
234 ZwClose(LangGroupKey);
235 }
236
237 if (AltSortKey != NULL)
238 {
239 ZwClose(AltSortKey);
240 }
241
242 if (NlsLocaleKey != NULL)
243 {
244 ZwClose(NlsLocaleKey);
245 }
246
247 return Status;
248}
#define DPRINT1
Definition: precomp.h:8
_In_ ULONG _In_ BATTERY_QUERY_INFORMATION_LEVEL _In_ LONG _In_ ULONG _Out_ PULONG ReturnedLength
Definition: batclass.h:188
static __inline BOOLEAN ExpValidateNlsLocaleData(_In_ PKEY_VALUE_PARTIAL_INFORMATION LocaleData)
Validates the registry data of a NLS locale.
Definition: locale.c:48
#define STATUS_OBJECT_NAME_NOT_FOUND
Definition: udferr_usr.h:149
_Must_inspect_result_ _In_ PWDFDEVICE_INIT _In_ PCUNICODE_STRING _In_ PCUNICODE_STRING _In_ LCID LocaleId
Definition: wdfpdo.h:437

Referenced by ExpSetCurrentUserUILanguage(), and NtSetDefaultLocale().

◆ NtQueryDefaultLocale()

NTSTATUS NTAPI NtQueryDefaultLocale ( IN BOOLEAN  UserProfile,
OUT PLCID  DefaultLocaleId 
)

Definition at line 392 of file locale.c.

394{
396 PAGED_CODE();
397
398 /* Enter SEH for probing */
400 {
401 /* Check if we came from user mode */
403 {
404 /* Probe the language ID */
405 ProbeForWriteLangId(DefaultLocaleId);
406 }
407
408 /* Check if we have a user profile */
409 if (UserProfile)
410 {
411 /* Return session wide thread locale */
412 *DefaultLocaleId = MmGetSessionLocaleId();
413 }
414 else
415 {
416 /* Return system locale */
417 *DefaultLocaleId = PsDefaultSystemLocaleId;
418 }
419 }
421 {
422 /* Get exception code */
424 }
425 _SEH2_END;
426
427 /* Return status */
428 return Status;
429}
LONG NTAPI ExSystemExceptionFilter(VOID)
Definition: harderr.c:349
#define KeGetPreviousMode()
Definition: ketypes.h:1115
#define KernelMode
Definition: asm.h:38
LCID PsDefaultSystemLocaleId
Definition: locale.c:20
ULONG NTAPI MmGetSessionLocaleId(VOID)
Definition: session.c:56
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:204
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:104
#define _SEH2_END
Definition: pseh2_64.h:194
#define _SEH2_TRY
Definition: pseh2_64.h:93
#define ProbeForWriteLangId(Ptr)
Definition: probe.h:44
#define STATUS_SUCCESS
Definition: shellext.h:65

Referenced by BaseSrvNLSInit(), find_entry(), GetSystemDefaultLCID(), GetUserDefaultLCID(), init_locale(), RtlpInitializeLocaleTable(), and UserInitHardErrorsCache().

◆ NtQueryDefaultUILanguage()

NTSTATUS NTAPI NtQueryDefaultUILanguage ( OUT LANGID LanguageId)

Definition at line 641 of file locale.c.

642{
644 LANGID SafeLanguageId;
645 PAGED_CODE();
646
647 /* Call the executive helper routine */
648 Status = ExpGetCurrentUserUILanguage(L"MultiUILanguageId", &SafeLanguageId);
649
650 /* Enter SEH for probing */
652 {
653 /* Check if we came from user mode */
655 {
656 /* Probe the Language ID */
657 ProbeForWriteLangId(LanguageId);
658 }
659
660 if (NT_SUCCESS(Status))
661 {
662 /* Success, return the language */
663 *LanguageId = SafeLanguageId;
664 }
665 else
666 {
667 /* Failed, use fallback value */
668 // NOTE: Windows doesn't use PsDefaultUILanguageId.
669 *LanguageId = PsInstallUILanguageId;
670 }
671 }
673 {
674 /* Return exception code */
676 }
677 _SEH2_END;
678
679 /* Return success */
680 return STATUS_SUCCESS;
681}
USHORT LANGID
Definition: mui.h:9
LANGID PsInstallUILanguageId
Definition: locale.c:21
NTSTATUS NTAPI ExpGetCurrentUserUILanguage(IN PCWSTR MuiName, OUT LANGID *LanguageId)
Definition: locale.c:252
#define _SEH2_YIELD(__stmt)
Definition: pseh2_64.h:207

Referenced by GetThreadUILanguage(), and GetUserDefaultUILanguage().

◆ NtQueryInstallUILanguage()

NTSTATUS NTAPI NtQueryInstallUILanguage ( OUT LANGID LanguageId)

Definition at line 607 of file locale.c.

608{
610 PAGED_CODE();
611
612 /* Enter SEH for probing */
614 {
615 /* Check if we came from user mode */
617 {
618 /* Probe the Language ID */
619 ProbeForWriteLangId(LanguageId);
620 }
621
622 /* Return it */
623 *LanguageId = PsInstallUILanguageId;
624 }
626 {
627 /* Get exception code */
629 }
630 _SEH2_END;
631
632 /* Return status */
633 return Status;
634}

Referenced by GetSystemDefaultUILanguage().

◆ NtSetDefaultLocale()

NTSTATUS NTAPI NtSetDefaultLocale ( IN BOOLEAN  UserProfile,
IN LCID  DefaultLocaleId 
)

Definition at line 433 of file locale.c.

435{
439 UNICODE_STRING LocaleString;
442 WCHAR ValueBuffer[20];
443 HANDLE UserKey = NULL;
445 UCHAR KeyValueBuffer[256];
446 PKEY_VALUE_PARTIAL_INFORMATION KeyValueInformation;
447 PAGED_CODE();
448
449 /* Check that the passed locale ID is not bogus */
450 if (DefaultLocaleId & BOGUS_LOCALE_ID)
451 {
453 }
454
455 /* Check if we have a profile */
456 if (UserProfile)
457 {
458 /* Open the user's key */
460 if (!NT_SUCCESS(Status)) return Status;
461
462 /* Initialize the registry location */
463 RtlInitUnicodeString(&KeyName, L"Control Panel\\International");
465 }
466 else
467 {
468 /* Initialize the system registry location */
470 L"\\Registry\\Machine\\System\\CurrentControlSet"
471 L"\\Control\\Nls\\Language");
472 RtlInitUnicodeString(&ValueName, L"Default");
473 }
474
475 /* Initialize the object attributes */
477 &KeyName,
479 UserKey,
480 NULL);
481
482 /* Check if we don't have a default locale yet */
483 if (!DefaultLocaleId)
484 {
485 /* Open the key for reading */
487 if (!NT_SUCCESS(Status))
488 {
489 goto Cleanup;
490 }
491
492 /* Query the key value */
493 KeyValueInformation = (PKEY_VALUE_PARTIAL_INFORMATION)KeyValueBuffer;
494 Status = ZwQueryValueKey(KeyHandle,
495 &ValueName,
497 KeyValueInformation,
498 sizeof(KeyValueBuffer),
499 &ValueLength);
500 if (!NT_SUCCESS(Status))
501 {
502 goto Cleanup;
503 }
504
505 /* Check if this is a REG_DWORD */
506 if ((KeyValueInformation->Type == REG_DWORD) &&
507 (KeyValueInformation->DataLength == sizeof(ULONG)))
508 {
509 /* It contains the LCID as a DWORD */
510 DefaultLocaleId = *((ULONG*)KeyValueInformation->Data);
511 }
512 /* Otherwise check for a REG_SZ */
513 else if (KeyValueInformation->Type == REG_SZ)
514 {
515 /* Initialize a unicode string from the value data */
516 LocaleString.Buffer = (PWCHAR)KeyValueInformation->Data;
517 LocaleString.Length = (USHORT)KeyValueInformation->DataLength;
518 LocaleString.MaximumLength = LocaleString.Length;
519
520 /* Convert the hex string to a number */
521 RtlUnicodeStringToInteger(&LocaleString, 16, &DefaultLocaleId);
522 }
523 else
524 {
526 }
527 }
528 else
529 {
530 /* We have a locale, validate it */
531 Status = ExpValidateNlsLocaleId(DefaultLocaleId);
532 if (NT_SUCCESS(Status))
533 {
534 /* Open the key now */
536 if (NT_SUCCESS(Status))
537 {
538 /* Check if we had a profile */
539 if (UserProfile)
540 {
541 /* Fill in the buffer */
542 ValueLength = _swprintf(ValueBuffer,
543 L"%08lx",
544 (ULONG)DefaultLocaleId);
545 }
546 else
547 {
548 /* Fill in the buffer */
549 ValueLength = _swprintf(ValueBuffer,
550 L"%04lx",
551 (ULONG)DefaultLocaleId & 0xFFFF);
552 }
553
554 /* Set the length for the registry call */
555 ValueLength = (ValueLength + 1) * sizeof(WCHAR);
556
557 /* Now write the actual value */
558 Status = ZwSetValueKey(KeyHandle,
559 &ValueName,
560 0,
561 REG_SZ,
562 ValueBuffer,
564 }
565 }
566 }
567
568Cleanup:
569
570 /* Close the locale key */
571 if (KeyHandle)
572 {
574 }
575
576 /* Close the user key */
577 if (UserKey)
578 {
579 ObCloseHandle(UserKey, KernelMode);
580 }
581
582 /* Check for success */
583 if (NT_SUCCESS(Status))
584 {
585 /* Check if it was for a user */
586 if (UserProfile)
587 {
588 /* Set the session wide thread locale */
589 MmSetSessionLocaleId(DefaultLocaleId);
590 }
591 else
592 {
593 /* Set system locale */
594 PsDefaultSystemLocaleId = DefaultLocaleId;
595 }
596 }
597
598 /* Return status */
599 return Status;
600}
static const WCHAR Cleanup[]
Definition: register.c:80
NTSTATUS NTAPI ObCloseHandle(IN HANDLE Handle, IN KPROCESSOR_MODE AccessMode)
Definition: obhandle.c:3379
#define REG_DWORD
Definition: sdbapi.c:615
USHORT MaximumLength
Definition: env_spec_w32.h:370

Referenced by LOCALE_Init(), LocaleDlgProc(), SaveCurrentLocale(), SetDefaultLanguage(), and START_TEST().

◆ NtSetDefaultUILanguage()

NTSTATUS NTAPI NtSetDefaultUILanguage ( IN LANGID  LanguageId)

Definition at line 688 of file locale.c.

689{
691 PAGED_CODE();
692
693 /* Check if the caller specified a language id */
694 if (LanguageId)
695 {
696 /* Set the pending MUI language id */
697 Status = ExpSetCurrentUserUILanguage(L"MUILanguagePending", LanguageId);
698 }
699 else
700 {
701 /* Otherwise get the pending MUI language id */
702 Status = ExpGetCurrentUserUILanguage(L"MUILanguagePending", &LanguageId);
703 if (!NT_SUCCESS(Status))
704 {
705 return Status;
706 }
707
708 /* And apply it as actual */
709 Status = ExpSetCurrentUserUILanguage(L"MultiUILanguageId", LanguageId);
710 }
711
712 return Status;
713}
NTSTATUS NTAPI ExpSetCurrentUserUILanguage(IN PCWSTR MuiName, IN LANGID LanguageId)
Definition: locale.c:325

Referenced by LOCALE_Init().

Variable Documentation

◆ PsDefaultSystemLocaleId

LCID PsDefaultSystemLocaleId = 0x00000409

◆ PsDefaultThreadLocaleId

LCID PsDefaultThreadLocaleId = 0x00000409

◆ PsDefaultUILanguageId

LANGID PsDefaultUILanguageId = LANGIDFROMLCID(0x00000409)

Definition at line 25 of file locale.c.

Referenced by CmGetSystemControlValues().

◆ PsInstallUILanguageId

LANGID PsInstallUILanguageId = LANGIDFROMLCID(0x00000409)