Fixed prototype for MmSetAddressRangeModified().
[reactos.git] / ntoskrnl / ps / locale.c
1 /* $Id$
2  *
3  * COPYRIGHT:       See COPYING in the top level directory
4  * PROJECT:         ReactOS kernel
5  * FILE:            ntoskrnl/ps/locale.c
6  * PURPOSE:         Locale support
7  * PROGRAMMER:      David Welch (welch@cwcom.net)
8  * UPDATE HISTORY:
9  *                  Created 22/05/98
10  */
11
12 /* INCLUDES *****************************************************************/
13
14 #include <ddk/ntddk.h>
15 #include <internal/ps.h>
16
17 #define NDEBUG
18 #include <internal/debug.h>
19
20
21 /* GLOBALS *******************************************************************/
22
23 /*
24  * Default setting: LANG_NEUTRAL, SUBLANG_NEUTRAL, SORT_DEFAULT
25  */
26 LCID PsDefaultThreadLocaleId = 0;
27 LCID PsDefaultSystemLocaleId = 0;
28
29
30 #define VALUE_BUFFER_SIZE 256
31
32 /* FUNCTIONS *****************************************************************/
33
34 VOID
35 PiInitDefaultLocale(VOID)
36 /*
37  * FUNCTION:
38  *    Initializes the default locale.
39  *    Reads default locale from registry, if available
40  * ARGUMENTS:
41  *    None.
42  * Returns:
43  *    None.
44  */
45 {
46    OBJECT_ATTRIBUTES ObjectAttributes;
47    UNICODE_STRING KeyName;
48    UNICODE_STRING ValueName;
49    HANDLE KeyHandle;
50    ULONG ValueLength;
51    UCHAR ValueBuffer[VALUE_BUFFER_SIZE];
52    PKEY_VALUE_PARTIAL_INFORMATION ValueInfo;
53    UNICODE_STRING ValueString;
54    ULONG LocaleValue;
55    NTSTATUS Status;
56
57    ValueInfo = (PKEY_VALUE_PARTIAL_INFORMATION)ValueBuffer;
58
59    /* read system locale */
60    RtlInitUnicodeStringFromLiteral(&KeyName,
61                         L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Nls\\Language");
62    RtlInitUnicodeStringFromLiteral(&ValueName,
63                         L"Default");
64
65    InitializeObjectAttributes(&ObjectAttributes,
66                               &KeyName,
67                               OBJ_CASE_INSENSITIVE,
68                               NULL,
69                               NULL);
70    Status = NtOpenKey(&KeyHandle,
71                       KEY_QUERY_VALUE,
72                       &ObjectAttributes);
73    if (NT_SUCCESS(Status))
74      {
75         Status = NtQueryValueKey(KeyHandle,
76                                  &ValueName,
77                                  KeyValuePartialInformation,
78                                  ValueBuffer,
79                                  VALUE_BUFFER_SIZE,
80                                  &ValueLength);
81         if ((NT_SUCCESS(Status)) && (ValueInfo->Type == REG_SZ))
82           {
83              ValueString.Length = ValueInfo->DataLength;
84              ValueString.MaximumLength = ValueInfo->DataLength;
85              ValueString.Buffer = (PWSTR)ValueInfo->Data;
86
87              Status = RtlUnicodeStringToInteger(&ValueString,
88                                                 10,
89                                                 &LocaleValue);
90              if (NT_SUCCESS(Status))
91                {
92                   DPRINT("System locale: %08lu\n", LocaleValue);
93                   PsDefaultSystemLocaleId = (LCID)LocaleValue;
94                }
95           }
96         NtClose(KeyHandle);
97      }
98
99    /* read default thread locale */
100    RtlInitUnicodeStringFromLiteral(&KeyName,
101                         L"\\Registry\\User\\.Default\\Control Panel\\International");
102    RtlInitUnicodeStringFromLiteral(&ValueName,
103                         L"Locale");
104
105    InitializeObjectAttributes(&ObjectAttributes,
106                               &KeyName,
107                               OBJ_CASE_INSENSITIVE,
108                               NULL,
109                               NULL);
110    Status = NtOpenKey(&KeyHandle,
111                       KEY_QUERY_VALUE,
112                       &ObjectAttributes);
113    if (NT_SUCCESS(Status))
114      {
115         Status = NtQueryValueKey(KeyHandle,
116                                  &ValueName,
117                                  KeyValuePartialInformation,
118                                  ValueBuffer,
119                                  VALUE_BUFFER_SIZE,
120                                  &ValueLength);
121         if ((NT_SUCCESS(Status)) && (ValueInfo->Type == REG_SZ))
122           {
123              ValueString.Length = ValueInfo->DataLength;
124              ValueString.MaximumLength = ValueInfo->DataLength;
125              ValueString.Buffer = (PWSTR)ValueInfo->Data;
126
127              Status = RtlUnicodeStringToInteger(&ValueString,
128                                                 10,
129                                                 &LocaleValue);
130              if (NT_SUCCESS(Status))
131                {
132                   DPRINT("Thread locale: %08lu\n", LocaleValue);
133                   PsDefaultThreadLocaleId = (LCID)LocaleValue;
134                }
135           }
136         NtClose(KeyHandle);
137      }
138 }
139
140
141 NTSTATUS STDCALL
142 NtQueryDefaultLocale(IN BOOLEAN ThreadOrSystem,
143                      OUT PLCID DefaultLocaleId)
144 /*
145  * FUNCTION:
146  *    Returns the default locale.
147  * ARGUMENTS:
148  *    ThreadOrSystem = If TRUE then the locale for this thread is returned,
149  *                     otherwise the locale for the system is returned.
150  *    DefaultLocaleId = Points to a variable that receives the locale id.
151  * Returns:
152  *    Status.
153  */
154 {
155    if (DefaultLocaleId == NULL)
156      return STATUS_UNSUCCESSFUL;
157
158    if (ThreadOrSystem == TRUE)
159      {
160         /* set thread locale */
161         *DefaultLocaleId = PsDefaultThreadLocaleId;
162      }
163    else
164      {
165         /* set system locale */
166         *DefaultLocaleId = PsDefaultSystemLocaleId;
167      }
168    return(STATUS_SUCCESS);
169 }
170
171
172 NTSTATUS STDCALL
173 NtSetDefaultLocale(IN BOOLEAN ThreadOrSystem,
174                    IN LCID DefaultLocaleId)
175 /*
176  * FUNCTION:
177  *    Sets the default locale.
178  * ARGUMENTS:
179  *    ThreadOrSystem = If TRUE then the locale for this thread is set,
180  *                     otherwise the locale for the system is set.
181  *    DefaultLocaleId = The locale id to be set.
182  * Returns:
183  *    Status.
184  */
185 {
186    OBJECT_ATTRIBUTES ObjectAttributes;
187    UNICODE_STRING KeyName;
188    UNICODE_STRING ValueName;
189    HANDLE KeyHandle;
190    ULONG ValueLength;
191    WCHAR ValueBuffer[20];
192    HANDLE UserKey = NULL;
193    NTSTATUS Status;
194
195    if (ThreadOrSystem == TRUE)
196      {
197         /* thread locale */
198         Status = RtlOpenCurrentUser(KEY_WRITE,
199                                     &UserKey);
200         if (!NT_SUCCESS(Status))
201           return(Status);
202         RtlInitUnicodeStringFromLiteral(&KeyName,
203                              L"Control Panel\\International");
204         RtlInitUnicodeStringFromLiteral(&ValueName,
205                              L"Locale");
206      }
207    else
208      {
209         /* system locale */
210         RtlInitUnicodeStringFromLiteral(&KeyName,
211                              L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Nls\\Language");
212         RtlInitUnicodeStringFromLiteral(&ValueName,
213                              L"Default");
214      }
215
216    InitializeObjectAttributes(&ObjectAttributes,
217                               &KeyName,
218                               OBJ_CASE_INSENSITIVE,
219                               UserKey,
220                               NULL);
221    Status = NtOpenKey(&KeyHandle,
222                       KEY_SET_VALUE,
223                       &ObjectAttributes);
224    if (!NT_SUCCESS(Status))
225      {
226         if (UserKey != NULL)
227           {
228              NtClose(UserKey);
229           }
230         return(Status);
231      }
232
233    ValueLength = swprintf(ValueBuffer,
234                           L"%08lu",
235                           (ULONG)DefaultLocaleId);
236    ValueLength = (ValueLength + 1) * sizeof(WCHAR);
237
238    Status = NtSetValueKey(KeyHandle,
239                           &ValueName,
240                           0,
241                           REG_SZ,
242                           ValueBuffer,
243                           ValueLength);
244
245    NtClose(KeyHandle);
246    if (UserKey != NULL)
247      {
248         NtClose(UserKey);
249      }
250
251    if (!NT_SUCCESS(Status))
252      {
253         return(Status);
254      }
255
256    if (ThreadOrSystem == TRUE)
257      {
258         /* set thread locale */
259         DPRINT("Thread locale: %08lu\n", DefaultLocaleId);
260         PsDefaultThreadLocaleId = DefaultLocaleId;
261      }
262    else
263      {
264         /* set system locale */
265         DPRINT("System locale: %08lu\n", DefaultLocaleId);
266         PsDefaultSystemLocaleId = DefaultLocaleId;
267      }
268
269    return(STATUS_SUCCESS);
270 }
271
272 /* EOF */