xref: /reactos/subsystems/win/basesrv/nls.c (revision d8cc88ca)
1c2c66affSColin Finck /*
2c2c66affSColin Finck  * COPYRIGHT:       See COPYING in the top level directory
3c2c66affSColin Finck  * PROJECT:         ReactOS Base API Server DLL
4c2c66affSColin Finck  * FILE:            subsystems/win/basesrv/nls.c
5c2c66affSColin Finck  * PURPOSE:         National Language Support (NLS)
6c2c66affSColin Finck  * PROGRAMMERS:     Alex Ionescu (alex.ionescu@reactos.org)
7c2c66affSColin Finck  */
8c2c66affSColin Finck 
9c2c66affSColin Finck /* INCLUDES *******************************************************************/
10c2c66affSColin Finck 
11c2c66affSColin Finck #include "basesrv.h"
12c2c66affSColin Finck 
13c2c66affSColin Finck #include <ndk/mmfuncs.h>
14c2c66affSColin Finck 
15c2c66affSColin Finck #define NDEBUG
16c2c66affSColin Finck #include <debug.h>
17c2c66affSColin Finck 
18c2c66affSColin Finck /* GLOBALS ********************************************************************/
19c2c66affSColin Finck 
20c2c66affSColin Finck RTL_CRITICAL_SECTION NlsCacheCriticalSection;
21c2c66affSColin Finck PNLS_USER_INFO pNlsRegUserInfo;
22c2c66affSColin Finck 
23c2c66affSColin Finck BOOLEAN BaseSrvKernel32DelayLoadComplete;
24c2c66affSColin Finck HANDLE BaseSrvKernel32DllHandle;
25c2c66affSColin Finck UNICODE_STRING BaseSrvKernel32DllPath;
26c2c66affSColin Finck 
27c2c66affSColin Finck POPEN_DATA_FILE pOpenDataFile;
28c2c66affSColin Finck PVOID /*PGET_DEFAULT_SORTKEY_SIZE */ pGetDefaultSortkeySize;
29c2c66affSColin Finck PVOID /*PGET_LINGUIST_LANG_SIZE*/ pGetLinguistLangSize;
30c2c66affSColin Finck PVOID /*PNLS_CONVERT_INTEGER_TO_STRING*/ pNlsConvertIntegerToString;
31c2c66affSColin Finck PVOID /*PVALIDATE_LCTYPE*/ pValidateLCType;
32c2c66affSColin Finck PVALIDATE_LOCALE pValidateLocale;
33c2c66affSColin Finck PGET_NLS_SECTION_NAME pGetNlsSectionName;
34c2c66affSColin Finck PVOID /*PGET_USER_DEFAULT_LANGID*/ pGetUserDefaultLangID;
35c2c66affSColin Finck PGET_CP_FILE_NAME_FROM_REGISTRY pGetCPFileNameFromRegistry;
36*d8cc88caSHermès Bélusca-Maïto 
37*d8cc88caSHermès Bélusca-Maïto NTSTATUS
38*d8cc88caSHermès Bélusca-Maïto (WINAPI *pCreateNlsSecurityDescriptor)(
39*d8cc88caSHermès Bélusca-Maïto     _Out_ PSECURITY_DESCRIPTOR SecurityDescriptor,
40*d8cc88caSHermès Bélusca-Maïto     _In_ SIZE_T DescriptorSize,
41*d8cc88caSHermès Bélusca-Maïto     _In_ ULONG AccessMask);
42c2c66affSColin Finck 
43c2c66affSColin Finck BASESRV_KERNEL_IMPORTS BaseSrvKernel32Imports[10] =
44c2c66affSColin Finck {
45c2c66affSColin Finck     { "OpenDataFile", (PVOID*) &pOpenDataFile },
46c2c66affSColin Finck     { "GetDefaultSortkeySize", (PVOID*) &pGetDefaultSortkeySize },
47c2c66affSColin Finck     { "GetLinguistLangSize", (PVOID*) &pGetLinguistLangSize },
48c2c66affSColin Finck     { "NlsConvertIntegerToString", (PVOID*) &pNlsConvertIntegerToString },
49c2c66affSColin Finck     { "ValidateLCType", (PVOID*) &pValidateLCType },
50c2c66affSColin Finck     { "ValidateLocale", (PVOID*) &pValidateLocale },
51c2c66affSColin Finck     { "GetNlsSectionName", (PVOID*) &pGetNlsSectionName },
52c2c66affSColin Finck     { "GetUserDefaultLangID", (PVOID*) &pGetUserDefaultLangID },
53c2c66affSColin Finck     { "GetCPFileNameFromRegistry", (PVOID*) &pGetCPFileNameFromRegistry },
54c2c66affSColin Finck     { "CreateNlsSecurityDescriptor", (PVOID*) &pCreateNlsSecurityDescriptor },
55c2c66affSColin Finck };
56c2c66affSColin Finck 
57c2c66affSColin Finck /* FUNCTIONS *****************************************************************/
58c2c66affSColin Finck 
59c2c66affSColin Finck NTSTATUS
60c2c66affSColin Finck NTAPI
BaseSrvDelayLoadKernel32(VOID)61c2c66affSColin Finck BaseSrvDelayLoadKernel32(VOID)
62c2c66affSColin Finck {
63c2c66affSColin Finck     NTSTATUS Status;
64c2c66affSColin Finck     ULONG i;
65c2c66affSColin Finck     ANSI_STRING ProcedureName;
66c2c66affSColin Finck 
67c2c66affSColin Finck     /* Only do this once */
68c2c66affSColin Finck     if (BaseSrvKernel32DelayLoadComplete) return STATUS_SUCCESS;
69c2c66affSColin Finck 
70c2c66affSColin Finck     /* Loop all imports */
71c2c66affSColin Finck     for (i = 0; i < RTL_NUMBER_OF(BaseSrvKernel32Imports); i++)
72c2c66affSColin Finck     {
73c2c66affSColin Finck         /* Only look them up once */
74c2c66affSColin Finck         if (!*BaseSrvKernel32Imports[i].FunctionPointer)
75c2c66affSColin Finck         {
76c2c66affSColin Finck             /* If we haven't loaded the DLL yet, do it now */
77c2c66affSColin Finck             if (!BaseSrvKernel32DllHandle)
78c2c66affSColin Finck             {
79c2c66affSColin Finck                 Status = LdrLoadDll(0,
80c2c66affSColin Finck                                     0,
81c2c66affSColin Finck                                     &BaseSrvKernel32DllPath,
82c2c66affSColin Finck                                     &BaseSrvKernel32DllHandle);
83c2c66affSColin Finck                 if (!NT_SUCCESS(Status))
84c2c66affSColin Finck                 {
85c2c66affSColin Finck                     DPRINT1("Failed to load %wZ\n", &BaseSrvKernel32DllPath);
86c2c66affSColin Finck                     return Status;
87c2c66affSColin Finck                 }
88c2c66affSColin Finck             }
89c2c66affSColin Finck 
90c2c66affSColin Finck             /* Get the address of the routine being looked up*/
91c2c66affSColin Finck             RtlInitAnsiString(&ProcedureName, BaseSrvKernel32Imports[i].FunctionName);
92c2c66affSColin Finck             Status = LdrGetProcedureAddress(BaseSrvKernel32DllHandle,
93c2c66affSColin Finck                                             &ProcedureName,
94c2c66affSColin Finck                                             0,
95c2c66affSColin Finck                                             BaseSrvKernel32Imports[i].FunctionPointer);
96c2c66affSColin Finck             DPRINT1("NLS: Found %Z at 0x%p\n",
97c2c66affSColin Finck                     &ProcedureName,
98c2c66affSColin Finck                     BaseSrvKernel32Imports[i].FunctionPointer);
99c2c66affSColin Finck             if (!NT_SUCCESS(Status)) break;
100c2c66affSColin Finck         }
101c2c66affSColin Finck     }
102c2c66affSColin Finck 
103c2c66affSColin Finck     /* Did we find them all? */
104c2c66affSColin Finck     if (i == RTL_NUMBER_OF(BaseSrvKernel32Imports))
105c2c66affSColin Finck     {
106c2c66affSColin Finck         /* Excellent */
107c2c66affSColin Finck         BaseSrvKernel32DelayLoadComplete = TRUE;
108c2c66affSColin Finck         return STATUS_SUCCESS;
109c2c66affSColin Finck     }
110c2c66affSColin Finck 
111c2c66affSColin Finck     /* Nope, fail */
112c2c66affSColin Finck     return Status;
113c2c66affSColin Finck }
114c2c66affSColin Finck 
115c2c66affSColin Finck VOID
116c2c66affSColin Finck NTAPI
BaseSrvNLSInit(IN PBASE_STATIC_SERVER_DATA StaticData)117c2c66affSColin Finck BaseSrvNLSInit(IN PBASE_STATIC_SERVER_DATA StaticData)
118c2c66affSColin Finck {
119c2c66affSColin Finck     /* Initialize the lock */
120c2c66affSColin Finck     RtlInitializeCriticalSection(&NlsCacheCriticalSection);
121c2c66affSColin Finck 
122c2c66affSColin Finck     /* Initialize the data with all F's */
123c2c66affSColin Finck     pNlsRegUserInfo = &StaticData->NlsUserInfo;
124c2c66affSColin Finck     RtlFillMemory(&StaticData->NlsUserInfo, sizeof(StaticData->NlsUserInfo), 0xFF);
125c2c66affSColin Finck 
126c2c66affSColin Finck     /* Set empty LCID */
127c2c66affSColin Finck     pNlsRegUserInfo->UserLocaleId = 0;
128c2c66affSColin Finck 
129c2c66affSColin Finck     /* Reset the cache update counter */
130c2c66affSColin Finck     RtlEnterCriticalSection(&NlsCacheCriticalSection);
131c2c66affSColin Finck     pNlsRegUserInfo->ulCacheUpdateCount = 0;
132c2c66affSColin Finck     RtlLeaveCriticalSection(&NlsCacheCriticalSection);
133c2c66affSColin Finck 
134c2c66affSColin Finck     /* Get the LCID */
135c2c66affSColin Finck     NtQueryDefaultLocale(0, &pNlsRegUserInfo->UserLocaleId);
136c2c66affSColin Finck }
137c2c66affSColin Finck 
138c2c66affSColin Finck NTSTATUS
139c2c66affSColin Finck NTAPI
BaseSrvNlsConnect(IN PCSR_PROCESS CsrProcess,IN OUT PVOID ConnectionInfo,IN OUT PULONG ConnectionInfoLength)140c2c66affSColin Finck BaseSrvNlsConnect(IN PCSR_PROCESS CsrProcess,
141c2c66affSColin Finck                   IN OUT PVOID  ConnectionInfo,
142c2c66affSColin Finck                   IN OUT PULONG ConnectionInfoLength)
143c2c66affSColin Finck {
144c2c66affSColin Finck     /* Does nothing */
145c2c66affSColin Finck     return STATUS_SUCCESS;
146c2c66affSColin Finck }
147c2c66affSColin Finck 
148c2c66affSColin Finck /* PUBLIC SERVER APIS *********************************************************/
149c2c66affSColin Finck 
CSR_API(BaseSrvNlsSetUserInfo)150c2c66affSColin Finck CSR_API(BaseSrvNlsSetUserInfo)
151c2c66affSColin Finck {
152c2c66affSColin Finck     DPRINT1("%s not yet implemented\n", __FUNCTION__);
153c2c66affSColin Finck     return STATUS_NOT_IMPLEMENTED;
154c2c66affSColin Finck }
155c2c66affSColin Finck 
CSR_API(BaseSrvNlsSetMultipleUserInfo)156c2c66affSColin Finck CSR_API(BaseSrvNlsSetMultipleUserInfo)
157c2c66affSColin Finck {
158c2c66affSColin Finck     DPRINT1("%s not yet implemented\n", __FUNCTION__);
159c2c66affSColin Finck     return STATUS_NOT_IMPLEMENTED;
160c2c66affSColin Finck }
161c2c66affSColin Finck 
CSR_API(BaseSrvNlsCreateSection)162c2c66affSColin Finck CSR_API(BaseSrvNlsCreateSection)
163c2c66affSColin Finck {
164c2c66affSColin Finck     NTSTATUS Status;
165c2c66affSColin Finck     HANDLE SectionHandle, ProcessHandle, FileHandle;
166c2c66affSColin Finck     ULONG LocaleId;
167c2c66affSColin Finck     UNICODE_STRING NlsSectionName;
168c2c66affSColin Finck     PWCHAR NlsFileName;
169*d8cc88caSHermès Bélusca-Maïto     UCHAR SecurityDescriptor[NLS_SECTION_SECURITY_DESCRIPTOR_SIZE];
170c2c66affSColin Finck     OBJECT_ATTRIBUTES ObjectAttributes;
171c2c66affSColin Finck     WCHAR FileNameBuffer[32];
172c2c66affSColin Finck     WCHAR NlsSectionNameBuffer[32];
173c2c66affSColin Finck     PBASE_NLS_CREATE_SECTION NlsMsg = &((PBASE_API_MESSAGE)ApiMessage)->Data.NlsCreateSection;
174c2c66affSColin Finck 
175c2c66affSColin Finck     /* Load kernel32 first and import the NLS routines */
176c2c66affSColin Finck     Status = BaseSrvDelayLoadKernel32();
177c2c66affSColin Finck     if (!NT_SUCCESS(Status)) return Status;
178c2c66affSColin Finck 
179c2c66affSColin Finck     /* Assume failure */
180c2c66affSColin Finck     NlsMsg->SectionHandle = NULL;
181c2c66affSColin Finck 
182c2c66affSColin Finck     /* Check and validate the locale ID, if one is present */
183c2c66affSColin Finck     LocaleId = NlsMsg->LocaleId;
184c2c66affSColin Finck     DPRINT1("NLS: Create Section with LCID: %lx for Type: %d\n", LocaleId, NlsMsg->Type);
185c2c66affSColin Finck     if (LocaleId)
186c2c66affSColin Finck     {
187c2c66affSColin Finck         if (!pValidateLocale(LocaleId)) return STATUS_INVALID_PARAMETER;
188c2c66affSColin Finck     }
189c2c66affSColin Finck 
190c2c66affSColin Finck     /* Check which NLS section is being created */
191c2c66affSColin Finck     switch (NlsMsg->Type)
192c2c66affSColin Finck     {
193c2c66affSColin Finck         /* For each one, set the correct filename and object name */
194c2c66affSColin Finck         case 1:
195c2c66affSColin Finck             RtlInitUnicodeString(&NlsSectionName, L"\\NLS\\NlsSectionUnicode");
196c2c66affSColin Finck             NlsFileName = L"unicode.nls";
197c2c66affSColin Finck             break;
198c2c66affSColin Finck         case 2:
199c2c66affSColin Finck             RtlInitUnicodeString(&NlsSectionName, L"\\NLS\\NlsSectionLocale");
200c2c66affSColin Finck             NlsFileName =  L"locale.nls";
201c2c66affSColin Finck             break;
202c2c66affSColin Finck         case 3:
203c2c66affSColin Finck             RtlInitUnicodeString(&NlsSectionName, L"\\NLS\\NlsSectionCType");
204c2c66affSColin Finck             NlsFileName = L"ctype.nls";
205c2c66affSColin Finck             break;
206c2c66affSColin Finck         case 4:
207c2c66affSColin Finck             RtlInitUnicodeString(&NlsSectionName, L"\\NLS\\NlsSectionSortkey");
208c2c66affSColin Finck             NlsFileName = L"sortkey.nls";
209c2c66affSColin Finck             break;
210c2c66affSColin Finck         case 5:
211c2c66affSColin Finck             RtlInitUnicodeString(&NlsSectionName, L"\\NLS\\NlsSectionSortTbls");
212c2c66affSColin Finck             NlsFileName = L"sorttbls.nls";
213c2c66affSColin Finck             break;
214c2c66affSColin Finck         case 6:
215c2c66affSColin Finck             RtlInitUnicodeString(&NlsSectionName, L"\\NLS\\NlsSectionCP437");
216c2c66affSColin Finck             NlsFileName = L"c_437.nls";
217c2c66affSColin Finck             break;
218c2c66affSColin Finck         case 7:
219c2c66affSColin Finck             RtlInitUnicodeString(&NlsSectionName, L"\\NLS\\NlsSectionCP1252");
220c2c66affSColin Finck             NlsFileName = L"c_1252.nls";
221c2c66affSColin Finck             break;
222c2c66affSColin Finck         case 8:
223c2c66affSColin Finck             RtlInitUnicodeString(&NlsSectionName, L"\\NLS\\NlsSectionLANG_EXCEPT");
224c2c66affSColin Finck             NlsFileName = L"l_except.nls";
225c2c66affSColin Finck             break;
226c2c66affSColin Finck         case 9:
227c2c66affSColin Finck             DPRINT1("This type not yet supported\n");
228c2c66affSColin Finck             return STATUS_NOT_IMPLEMENTED;
229c2c66affSColin Finck         case 10:
230c2c66affSColin Finck             DPRINT1("This type not yet supported\n");
231c2c66affSColin Finck             return STATUS_NOT_IMPLEMENTED;
232c2c66affSColin Finck         case 11:
233c2c66affSColin Finck             /* Get the filename for this locale */
234c2c66affSColin Finck             if (!pGetCPFileNameFromRegistry(NlsMsg->LocaleId,
235c2c66affSColin Finck                                             FileNameBuffer,
236c2c66affSColin Finck                                             RTL_NUMBER_OF(FileNameBuffer)))
237c2c66affSColin Finck             {
238c2c66affSColin Finck                 DPRINT1("File name query failed\n");
239c2c66affSColin Finck                 return STATUS_INVALID_PARAMETER;
240c2c66affSColin Finck             }
241c2c66affSColin Finck 
242c2c66affSColin Finck             /* Get the name of the section for this locale */
243c2c66affSColin Finck             DPRINT1("File name: %S\n", FileNameBuffer);
244c2c66affSColin Finck             Status = pGetNlsSectionName(NlsMsg->LocaleId,
245c2c66affSColin Finck                                         10,
246c2c66affSColin Finck                                         0,
247c2c66affSColin Finck                                         L"\\NLS\\NlsSectionCP",
248c2c66affSColin Finck                                         NlsSectionNameBuffer,
249c2c66affSColin Finck                                         RTL_NUMBER_OF(NlsSectionNameBuffer));
250c2c66affSColin Finck             if (!NT_SUCCESS(Status))
251c2c66affSColin Finck             {
252c2c66affSColin Finck                 DPRINT1("Section name query failed: %lx\n", Status);
253c2c66affSColin Finck                 return Status;
254c2c66affSColin Finck             }
255c2c66affSColin Finck 
256c2c66affSColin Finck             /* Setup the name and go open it */
257c2c66affSColin Finck             NlsFileName = FileNameBuffer;
258c2c66affSColin Finck             DPRINT1("Section name: %S\n", NlsSectionNameBuffer);
259c2c66affSColin Finck             RtlInitUnicodeString(&NlsSectionName, NlsSectionNameBuffer);
260c2c66affSColin Finck             break;
261c2c66affSColin Finck         case 12:
262c2c66affSColin Finck             RtlInitUnicodeString(&NlsSectionName, L"\\NLS\\NlsSectionGeo");
263c2c66affSColin Finck             NlsFileName = L"geo.nls";
264c2c66affSColin Finck             break;
265c2c66affSColin Finck         default:
266c2c66affSColin Finck             DPRINT1("NLS: Invalid NLS type!\n");
267c2c66affSColin Finck             return STATUS_INVALID_PARAMETER;
268c2c66affSColin Finck     }
269c2c66affSColin Finck 
270c2c66affSColin Finck     /* Open the specified NLS file */
271c2c66affSColin Finck     Status = pOpenDataFile(&FileHandle, NlsFileName);
272c2c66affSColin Finck     if (Status != STATUS_SUCCESS)
273c2c66affSColin Finck     {
274c2c66affSColin Finck         DPRINT1("NLS: Failed to open file: %lx\n", Status);
275c2c66affSColin Finck         return Status;
276c2c66affSColin Finck     }
277c2c66affSColin Finck 
278c2c66affSColin Finck     /* Create an SD for the section object */
279*d8cc88caSHermès Bélusca-Maïto     Status = pCreateNlsSecurityDescriptor(&SecurityDescriptor,
280*d8cc88caSHermès Bélusca-Maïto                                           sizeof(SecurityDescriptor),
2815696e4baSGeorge Bișoc                                           SECTION_MAP_READ);
282c2c66affSColin Finck     if (!NT_SUCCESS(Status))
283c2c66affSColin Finck     {
284c2c66affSColin Finck         DPRINT1("NLS: CreateNlsSecurityDescriptor FAILED!: %lx\n", Status);
285c2c66affSColin Finck         NtClose(FileHandle);
286c2c66affSColin Finck         return Status;
287c2c66affSColin Finck     }
288c2c66affSColin Finck 
289c2c66affSColin Finck     /* Create the section object proper */
290c2c66affSColin Finck     InitializeObjectAttributes(&ObjectAttributes,
291c2c66affSColin Finck                                &NlsSectionName,
292c2c66affSColin Finck                                OBJ_CASE_INSENSITIVE | OBJ_PERMANENT | OBJ_OPENIF,
293c2c66affSColin Finck                                NULL,
294*d8cc88caSHermès Bélusca-Maïto                                &SecurityDescriptor);
295c2c66affSColin Finck     Status = NtCreateSection(&SectionHandle,
296c2c66affSColin Finck                              SECTION_MAP_READ,
297c2c66affSColin Finck                              &ObjectAttributes,
298c2c66affSColin Finck                              0,
299c2c66affSColin Finck                              PAGE_READONLY,
300c2c66affSColin Finck                              SEC_COMMIT,
301c2c66affSColin Finck                              FileHandle);
302c2c66affSColin Finck     NtClose(FileHandle);
303c2c66affSColin Finck     if (!NT_SUCCESS(Status))
304c2c66affSColin Finck     {
305c2c66affSColin Finck         DPRINT1("NLS: Failed to create section! %lx\n", Status);
306c2c66affSColin Finck         return Status;
307c2c66affSColin Finck     }
308c2c66affSColin Finck 
309c2c66affSColin Finck     /* Open a handle to the calling process */
310c2c66affSColin Finck     InitializeObjectAttributes(&ObjectAttributes, NULL, 0, NULL, NULL);
311c2c66affSColin Finck     Status = NtOpenProcess(&ProcessHandle,
312c2c66affSColin Finck                            PROCESS_DUP_HANDLE,
313c2c66affSColin Finck                            &ObjectAttributes,
314c2c66affSColin Finck                            &ApiMessage->Header.ClientId);
315c2c66affSColin Finck     if (!NT_SUCCESS(Status))
316c2c66affSColin Finck     {
317c2c66affSColin Finck         DPRINT1("NLS: Failed to open process! %lx\n", Status);
318c2c66affSColin Finck         NtClose(SectionHandle);
319c2c66affSColin Finck         return Status;
320c2c66affSColin Finck     }
321c2c66affSColin Finck 
322c2c66affSColin Finck     /* Duplicate the handle to the section object into it */
323c2c66affSColin Finck     Status = NtDuplicateObject(NtCurrentProcess(),
324c2c66affSColin Finck                                SectionHandle,
325c2c66affSColin Finck                                ProcessHandle,
326c2c66affSColin Finck                                &NlsMsg->SectionHandle,
327c2c66affSColin Finck                                0,
328c2c66affSColin Finck                                0,
329c2c66affSColin Finck                                3);
330c2c66affSColin Finck     NtClose(ProcessHandle);
331c2c66affSColin Finck     return Status;
332c2c66affSColin Finck }
333c2c66affSColin Finck 
CSR_API(BaseSrvNlsUpdateCacheCount)334c2c66affSColin Finck CSR_API(BaseSrvNlsUpdateCacheCount)
335c2c66affSColin Finck {
336c2c66affSColin Finck     DPRINT1("%s not yet implemented\n", __FUNCTION__);
337c2c66affSColin Finck     return STATUS_NOT_IMPLEMENTED;
338c2c66affSColin Finck }
339c2c66affSColin Finck 
CSR_API(BaseSrvNlsGetUserInfo)340c2c66affSColin Finck CSR_API(BaseSrvNlsGetUserInfo)
341c2c66affSColin Finck {
342c2c66affSColin Finck     NTSTATUS Status;
343c2c66affSColin Finck     PBASE_NLS_GET_USER_INFO NlsMsg = &((PBASE_API_MESSAGE)ApiMessage)->Data.NlsGetUserInfo;
344c2c66affSColin Finck 
345c2c66affSColin Finck     /* Make sure the buffer is valid and of the right size */
346c7c0b09eSHermès Bélusca-Maïto     if ((CsrValidateMessageBuffer(ApiMessage, &NlsMsg->NlsUserInfo, NlsMsg->Size, sizeof(BYTE))) &&
347c2c66affSColin Finck         (NlsMsg->Size == sizeof(NLS_USER_INFO)))
348c2c66affSColin Finck     {
349c2c66affSColin Finck         /* Acquire the lock to prevent updates while we copy */
350c2c66affSColin Finck         Status = RtlEnterCriticalSection(&NlsCacheCriticalSection);
351c2c66affSColin Finck         if (NT_SUCCESS(Status))
352c2c66affSColin Finck         {
353c2c66affSColin Finck             /* Do the copy now, then drop the lock */
354c2c66affSColin Finck             RtlCopyMemory(NlsMsg->NlsUserInfo, pNlsRegUserInfo, NlsMsg->Size);
355c2c66affSColin Finck             DPRINT1("NLS Data copy complete\n");
356c2c66affSColin Finck             RtlLeaveCriticalSection(&NlsCacheCriticalSection);
357c2c66affSColin Finck         }
358c2c66affSColin Finck     }
359c2c66affSColin Finck     else
360c2c66affSColin Finck     {
361c2c66affSColin Finck         /* The data was invalid, bail out */
362c2c66affSColin Finck         DPRINT1("NLS: Size of info is invalid: %lx vs %lx\n", NlsMsg->Size, sizeof(NLS_USER_INFO));
363c2c66affSColin Finck         Status = STATUS_INVALID_PARAMETER;
364c2c66affSColin Finck     }
365c2c66affSColin Finck 
366c2c66affSColin Finck     /* All done */
367c2c66affSColin Finck     return Status;
368c2c66affSColin Finck }
369c2c66affSColin Finck 
370c2c66affSColin Finck /* PUBLIC APIS ****************************************************************/
371c2c66affSColin Finck 
372c2c66affSColin Finck NTSTATUS
373c2c66affSColin Finck NTAPI
BaseSrvNlsLogon(DWORD Unknown)374c2c66affSColin Finck BaseSrvNlsLogon(DWORD Unknown)
375c2c66affSColin Finck {
376c2c66affSColin Finck     DPRINT1("%s(%lu) not yet implemented\n", __FUNCTION__, Unknown);
377c2c66affSColin Finck     return STATUS_NOT_IMPLEMENTED;
378c2c66affSColin Finck }
379c2c66affSColin Finck 
380c2c66affSColin Finck NTSTATUS
381c2c66affSColin Finck NTAPI
BaseSrvNlsUpdateRegistryCache(DWORD Unknown1,DWORD Unknown2)382c2c66affSColin Finck BaseSrvNlsUpdateRegistryCache(DWORD Unknown1,
383c2c66affSColin Finck                               DWORD Unknown2)
384c2c66affSColin Finck {
385c2c66affSColin Finck     DPRINT1("%s(%lu, %lu) not yet implemented\n", __FUNCTION__, Unknown1, Unknown2);
386c2c66affSColin Finck     return STATUS_NOT_IMPLEMENTED;
387c2c66affSColin Finck }
388c2c66affSColin Finck 
389c2c66affSColin Finck /* EOF */
390