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