ReactOS 0.4.15-dev-5669-g09dde2c
nls.c
Go to the documentation of this file.
1/*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Base API Server DLL
4 * FILE: subsystems/win/basesrv/nls.c
5 * PURPOSE: National Language Support (NLS)
6 * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
7 */
8
9/* INCLUDES *******************************************************************/
10
11#include "basesrv.h"
12
13#include <ndk/mmfuncs.h>
14
15#define NDEBUG
16#include <debug.h>
17
18/* GLOBALS ********************************************************************/
19
22
26
28PVOID /*PGET_DEFAULT_SORTKEY_SIZE */ pGetDefaultSortkeySize;
29PVOID /*PGET_LINGUIST_LANG_SIZE*/ pGetLinguistLangSize;
30PVOID /*PNLS_CONVERT_INTEGER_TO_STRING*/ pNlsConvertIntegerToString;
31PVOID /*PVALIDATE_LCTYPE*/ pValidateLCType;
34PVOID /*PGET_USER_DEFAULT_LANGID*/ pGetUserDefaultLangID;
36
38(WINAPI *pCreateNlsSecurityDescriptor)(
42
44{
45 { "OpenDataFile", (PVOID*) &pOpenDataFile },
46 { "GetDefaultSortkeySize", (PVOID*) &pGetDefaultSortkeySize },
47 { "GetLinguistLangSize", (PVOID*) &pGetLinguistLangSize },
48 { "NlsConvertIntegerToString", (PVOID*) &pNlsConvertIntegerToString },
49 { "ValidateLCType", (PVOID*) &pValidateLCType },
50 { "ValidateLocale", (PVOID*) &pValidateLocale },
51 { "GetNlsSectionName", (PVOID*) &pGetNlsSectionName },
52 { "GetUserDefaultLangID", (PVOID*) &pGetUserDefaultLangID },
53 { "GetCPFileNameFromRegistry", (PVOID*) &pGetCPFileNameFromRegistry },
54 { "CreateNlsSecurityDescriptor", (PVOID*) &pCreateNlsSecurityDescriptor },
55};
56
57/* FUNCTIONS *****************************************************************/
58
62{
64 ULONG i;
65 ANSI_STRING ProcedureName;
66
67 /* Only do this once */
69
70 /* Loop all imports */
72 {
73 /* Only look them up once */
74 if (!*BaseSrvKernel32Imports[i].FunctionPointer)
75 {
76 /* If we haven't loaded the DLL yet, do it now */
78 {
80 0,
83 if (!NT_SUCCESS(Status))
84 {
85 DPRINT1("Failed to load %wZ\n", &BaseSrvKernel32DllPath);
86 return Status;
87 }
88 }
89
90 /* Get the address of the routine being looked up*/
93 &ProcedureName,
94 0,
95 BaseSrvKernel32Imports[i].FunctionPointer);
96 DPRINT1("NLS: Found %Z at 0x%p\n",
97 &ProcedureName,
98 BaseSrvKernel32Imports[i].FunctionPointer);
99 if (!NT_SUCCESS(Status)) break;
100 }
101 }
102
103 /* Did we find them all? */
105 {
106 /* Excellent */
108 return STATUS_SUCCESS;
109 }
110
111 /* Nope, fail */
112 return Status;
113}
114
115VOID
116NTAPI
118{
119 /* Initialize the lock */
121
122 /* Initialize the data with all F's */
123 pNlsRegUserInfo = &StaticData->NlsUserInfo;
124 RtlFillMemory(&StaticData->NlsUserInfo, sizeof(StaticData->NlsUserInfo), 0xFF);
125
126 /* Set empty LCID */
128
129 /* Reset the cache update counter */
133
134 /* Get the LCID */
136}
137
139NTAPI
141 IN OUT PVOID ConnectionInfo,
142 IN OUT PULONG ConnectionInfoLength)
143{
144 /* Does nothing */
145 return STATUS_SUCCESS;
146}
147
148/* PUBLIC SERVER APIS *********************************************************/
149
150CSR_API(BaseSrvNlsSetUserInfo)
151{
152 DPRINT1("%s not yet implemented\n", __FUNCTION__);
154}
155
156CSR_API(BaseSrvNlsSetMultipleUserInfo)
157{
158 DPRINT1("%s not yet implemented\n", __FUNCTION__);
160}
161
162CSR_API(BaseSrvNlsCreateSection)
163{
165 HANDLE SectionHandle, ProcessHandle, FileHandle;
167 UNICODE_STRING NlsSectionName;
168 PWCHAR NlsFileName;
172 WCHAR NlsSectionNameBuffer[32];
173 PBASE_NLS_CREATE_SECTION NlsMsg = &((PBASE_API_MESSAGE)ApiMessage)->Data.NlsCreateSection;
174
175 /* Load kernel32 first and import the NLS routines */
177 if (!NT_SUCCESS(Status)) return Status;
178
179 /* Assume failure */
180 NlsMsg->SectionHandle = NULL;
181
182 /* Check and validate the locale ID, if one is present */
183 LocaleId = NlsMsg->LocaleId;
184 DPRINT1("NLS: Create Section with LCID: %lx for Type: %d\n", LocaleId, NlsMsg->Type);
185 if (LocaleId)
186 {
188 }
189
190 /* Check which NLS section is being created */
191 switch (NlsMsg->Type)
192 {
193 /* For each one, set the correct filename and object name */
194 case 1:
195 RtlInitUnicodeString(&NlsSectionName, L"\\NLS\\NlsSectionUnicode");
196 NlsFileName = L"unicode.nls";
197 break;
198 case 2:
199 RtlInitUnicodeString(&NlsSectionName, L"\\NLS\\NlsSectionLocale");
200 NlsFileName = L"locale.nls";
201 break;
202 case 3:
203 RtlInitUnicodeString(&NlsSectionName, L"\\NLS\\NlsSectionCType");
204 NlsFileName = L"ctype.nls";
205 break;
206 case 4:
207 RtlInitUnicodeString(&NlsSectionName, L"\\NLS\\NlsSectionSortkey");
208 NlsFileName = L"sortkey.nls";
209 break;
210 case 5:
211 RtlInitUnicodeString(&NlsSectionName, L"\\NLS\\NlsSectionSortTbls");
212 NlsFileName = L"sorttbls.nls";
213 break;
214 case 6:
215 RtlInitUnicodeString(&NlsSectionName, L"\\NLS\\NlsSectionCP437");
216 NlsFileName = L"c_437.nls";
217 break;
218 case 7:
219 RtlInitUnicodeString(&NlsSectionName, L"\\NLS\\NlsSectionCP1252");
220 NlsFileName = L"c_1252.nls";
221 break;
222 case 8:
223 RtlInitUnicodeString(&NlsSectionName, L"\\NLS\\NlsSectionLANG_EXCEPT");
224 NlsFileName = L"l_except.nls";
225 break;
226 case 9:
227 DPRINT1("This type not yet supported\n");
229 case 10:
230 DPRINT1("This type not yet supported\n");
232 case 11:
233 /* Get the filename for this locale */
237 {
238 DPRINT1("File name query failed\n");
240 }
241
242 /* Get the name of the section for this locale */
243 DPRINT1("File name: %S\n", FileNameBuffer);
245 10,
246 0,
247 L"\\NLS\\NlsSectionCP",
248 NlsSectionNameBuffer,
249 RTL_NUMBER_OF(NlsSectionNameBuffer));
250 if (!NT_SUCCESS(Status))
251 {
252 DPRINT1("Section name query failed: %lx\n", Status);
253 return Status;
254 }
255
256 /* Setup the name and go open it */
257 NlsFileName = FileNameBuffer;
258 DPRINT1("Section name: %S\n", NlsSectionNameBuffer);
259 RtlInitUnicodeString(&NlsSectionName, NlsSectionNameBuffer);
260 break;
261 case 12:
262 RtlInitUnicodeString(&NlsSectionName, L"\\NLS\\NlsSectionGeo");
263 NlsFileName = L"geo.nls";
264 break;
265 default:
266 DPRINT1("NLS: Invalid NLS type!\n");
268 }
269
270 /* Open the specified NLS file */
271 Status = pOpenDataFile(&FileHandle, NlsFileName);
272 if (Status != STATUS_SUCCESS)
273 {
274 DPRINT1("NLS: Failed to open file: %lx\n", Status);
275 return Status;
276 }
277
278 /* Create an SD for the section object */
279 Status = pCreateNlsSecurityDescriptor(&SecurityDescriptor,
280 sizeof(SecurityDescriptor),
282 if (!NT_SUCCESS(Status))
283 {
284 DPRINT1("NLS: CreateNlsSecurityDescriptor FAILED!: %lx\n", Status);
286 return Status;
287 }
288
289 /* Create the section object proper */
291 &NlsSectionName,
293 NULL,
295 Status = NtCreateSection(&SectionHandle,
298 0,
301 FileHandle);
303 if (!NT_SUCCESS(Status))
304 {
305 DPRINT1("NLS: Failed to create section! %lx\n", Status);
306 return Status;
307 }
308
309 /* Open a handle to the calling process */
314 &ApiMessage->Header.ClientId);
315 if (!NT_SUCCESS(Status))
316 {
317 DPRINT1("NLS: Failed to open process! %lx\n", Status);
318 NtClose(SectionHandle);
319 return Status;
320 }
321
322 /* Duplicate the handle to the section object into it */
324 SectionHandle,
326 &NlsMsg->SectionHandle,
327 0,
328 0,
329 3);
331 return Status;
332}
333
334CSR_API(BaseSrvNlsUpdateCacheCount)
335{
336 DPRINT1("%s not yet implemented\n", __FUNCTION__);
338}
339
340CSR_API(BaseSrvNlsGetUserInfo)
341{
343 PBASE_NLS_GET_USER_INFO NlsMsg = &((PBASE_API_MESSAGE)ApiMessage)->Data.NlsGetUserInfo;
344
345 /* Make sure the buffer is valid and of the right size */
346 if ((CsrValidateMessageBuffer(ApiMessage, &NlsMsg->NlsUserInfo, NlsMsg->Size, sizeof(BYTE))) &&
347 (NlsMsg->Size == sizeof(NLS_USER_INFO)))
348 {
349 /* Acquire the lock to prevent updates while we copy */
351 if (NT_SUCCESS(Status))
352 {
353 /* Do the copy now, then drop the lock */
355 DPRINT1("NLS Data copy complete\n");
357 }
358 }
359 else
360 {
361 /* The data was invalid, bail out */
362 DPRINT1("NLS: Size of info is invalid: %lx vs %lx\n", NlsMsg->Size, sizeof(NLS_USER_INFO));
364 }
365
366 /* All done */
367 return Status;
368}
369
370/* PUBLIC APIS ****************************************************************/
371
373NTAPI
375{
376 DPRINT1("%s(%lu) not yet implemented\n", __FUNCTION__, Unknown);
378}
379
381NTAPI
383 DWORD Unknown2)
384{
385 DPRINT1("%s(%lu, %lu) not yet implemented\n", __FUNCTION__, Unknown1, Unknown2);
387}
388
389/* EOF */
NTSTATUS NTAPI NtCreateSection(OUT PHANDLE SectionHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, IN PLARGE_INTEGER MaximumSize OPTIONAL, IN ULONG SectionPageProtection OPTIONAL, IN ULONG AllocationAttributes, IN HANDLE FileHandle OPTIONAL)
Definition: section.c:3441
unsigned char BOOLEAN
#define RTL_NUMBER_OF(x)
Definition: RtlRegistry.c:12
ACPI_BUFFER *RetBuffer ACPI_BUFFER *RetBuffer char ACPI_WALK_RESOURCE_CALLBACK void *Context ACPI_BUFFER *RetBuffer UINT16 ACPI_RESOURCE **ResourcePtr ACPI_GENERIC_ADDRESS *Reg UINT32 *ReturnValue UINT8 UINT8 *Slp_TypB ACPI_PHYSICAL_ADDRESS PhysicalAddress64 UINT32 UINT32 *TimeElapsed UINT32 ACPI_STATUS const char UINT32 ACPI_STATUS const char UINT32 const char * FunctionName
Definition: acpixf.h:1279
LONG NTSTATUS
Definition: precomp.h:26
#define DPRINT1
Definition: precomp.h:8
WCHAR FileNameBuffer[_MAX_PATH]
Definition: framewnd.c:233
#define NLS_SECTION_SECURITY_DESCRIPTOR_SIZE
Definition: base.h:31
struct _BASE_API_MESSAGE * PBASE_API_MESSAGE
BOOL(WINAPI * PGET_NLS_SECTION_NAME)(UINT CodePage, UINT Base, ULONG Unknown, LPWSTR BaseName, LPWSTR Result, ULONG ResultSize)
Definition: basesrv.h:53
BOOL(WINAPI * PVALIDATE_LOCALE)(IN ULONG LocaleId)
Definition: basesrv.h:60
BOOL(WINAPI * PGET_CP_FILE_NAME_FROM_REGISTRY)(UINT CodePage, LPWSTR FileName, ULONG FileNameSize)
Definition: basesrv.h:49
NTSTATUS(WINAPI * POPEN_DATA_FILE)(HANDLE hFile, PWCHAR FileName)
Definition: basesrv.h:46
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:36
BOOLEAN NTAPI CsrValidateMessageBuffer(IN PCSR_API_MESSAGE ApiMessage, IN PVOID *Buffer, IN ULONG ElementCount, IN ULONG ElementSize)
Definition: api.c:1430
#define CSR_API(n)
Definition: csrsrv.h:176
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define NTSTATUS
Definition: precomp.h:20
#define PAGE_READONLY
Definition: compat.h:138
#define SECTION_MAP_READ
Definition: compat.h:139
#define __FUNCTION__
Definition: types.h:112
unsigned long DWORD
Definition: ntddk_ex.h:95
_Must_inspect_result_ _In_opt_ PFLT_INSTANCE _Out_ PHANDLE FileHandle
Definition: fltkernel.h:1231
Status
Definition: gdiplustypes.h:25
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
@ Unknown
Definition: i8042prt.h:114
#define OBJ_OPENIF
Definition: winternl.h:229
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
#define RtlFillMemory(Dest, Length, Fill)
Definition: winternl.h:593
#define OBJ_PERMANENT
Definition: winternl.h:226
#define PROCESS_DUP_HANDLE
NTSTATUS NTAPI LdrGetProcedureAddress(IN PVOID BaseAddress, IN PANSI_STRING Name, IN ULONG Ordinal, OUT PVOID *ProcedureAddress)
Definition: ldrapi.c:823
NTSTATUS NTAPI DECLSPEC_HOTPATCH LdrLoadDll(IN PWSTR SearchPath OPTIONAL, IN PULONG DllCharacteristics OPTIONAL, IN PUNICODE_STRING DllName, OUT PVOID *BaseAddress)
Definition: ldrapi.c:310
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
#define _Out_
Definition: ms_sal.h:345
#define _In_
Definition: ms_sal.h:308
_In_ ACCESS_MASK AccessMask
Definition: exfuncs.h:186
_In_ HANDLE ProcessHandle
Definition: mmfuncs.h:403
#define SEC_COMMIT
Definition: mmtypes.h:99
NTSYSAPI NTSTATUS NTAPI RtlEnterCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)
NTSYSAPI NTSTATUS NTAPI RtlLeaveCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)
NTSYSAPI NTSTATUS NTAPI RtlInitializeCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define NtCurrentProcess()
Definition: nt_native.h:1657
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3402
NTSYSAPI VOID NTAPI RtlInitAnsiString(PANSI_STRING DestinationString, PCSZ SourceString)
NTSTATUS NTAPI NtQueryDefaultLocale(IN BOOLEAN UserProfile, OUT PLCID DefaultLocaleId)
Definition: locale.c:162
NTSTATUS NTAPI NtOpenProcess(OUT PHANDLE ProcessHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, IN PCLIENT_ID ClientId)
Definition: process.c:1440
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:239
#define L(x)
Definition: ntvdm.h:50
NTSTATUS NTAPI NtDuplicateObject(IN HANDLE SourceProcessHandle, IN HANDLE SourceHandle, IN HANDLE TargetProcessHandle OPTIONAL, OUT PHANDLE TargetHandle OPTIONAL, IN ACCESS_MASK DesiredAccess, IN ULONG HandleAttributes, IN ULONG Options)
Definition: obhandle.c:3410
#define STATUS_SUCCESS
Definition: shellext.h:65
LCID UserLocaleId
Definition: base.h:75
ULONG ulCacheUpdateCount
Definition: base.h:77
PGET_NLS_SECTION_NAME pGetNlsSectionName
Definition: nls.c:33
_In_ SIZE_T DescriptorSize
Definition: nls.c:40
HANDLE BaseSrvKernel32DllHandle
Definition: nls.c:24
PVOID pValidateLCType
Definition: nls.c:31
POPEN_DATA_FILE pOpenDataFile
Definition: nls.c:27
RTL_CRITICAL_SECTION NlsCacheCriticalSection
Definition: nls.c:20
UNICODE_STRING BaseSrvKernel32DllPath
Definition: nls.c:25
PVOID pNlsConvertIntegerToString
Definition: nls.c:30
PVOID pGetDefaultSortkeySize
Definition: nls.c:28
VOID NTAPI BaseSrvNLSInit(IN PBASE_STATIC_SERVER_DATA StaticData)
Definition: nls.c:117
PNLS_USER_INFO pNlsRegUserInfo
Definition: nls.c:21
BOOLEAN BaseSrvKernel32DelayLoadComplete
Definition: nls.c:23
BASESRV_KERNEL_IMPORTS BaseSrvKernel32Imports[10]
Definition: nls.c:43
NTSTATUS NTAPI BaseSrvNlsLogon(DWORD Unknown)
Definition: nls.c:374
PVALIDATE_LOCALE pValidateLocale
Definition: nls.c:32
NTSTATUS NTAPI BaseSrvDelayLoadKernel32(VOID)
Definition: nls.c:61
NTSTATUS NTAPI BaseSrvNlsUpdateRegistryCache(DWORD Unknown1, DWORD Unknown2)
Definition: nls.c:382
PGET_CP_FILE_NAME_FROM_REGISTRY pGetCPFileNameFromRegistry
Definition: nls.c:35
PVOID pGetUserDefaultLangID
Definition: nls.c:34
PVOID pGetLinguistLangSize
Definition: nls.c:29
NTSTATUS NTAPI BaseSrvNlsConnect(IN PCSR_PROCESS CsrProcess, IN OUT PVOID ConnectionInfo, IN OUT PULONG ConnectionInfoLength)
Definition: nls.c:140
uint32_t * PULONG
Definition: typedefs.h:59
#define NTAPI
Definition: typedefs.h:36
ULONG_PTR SIZE_T
Definition: typedefs.h:80
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define IN
Definition: typedefs.h:39
uint16_t * PWCHAR
Definition: typedefs.h:56
uint32_t ULONG
Definition: typedefs.h:59
#define OUT
Definition: typedefs.h:40
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
PKPROCESS CsrProcess
Definition: videoprt.c:39
_Must_inspect_result_ _In_ PWDFDEVICE_INIT _In_ PCUNICODE_STRING _In_ PCUNICODE_STRING _In_ LCID LocaleId
Definition: wdfpdo.h:437
#define WINAPI
Definition: msvc.h:6
_In_ USHORT _In_ ULONG _In_ PSOCKADDR _In_ PSOCKADDR _Reserved_ ULONG _In_opt_ PVOID _In_opt_ const WSK_CLIENT_CONNECTION_DISPATCH _In_opt_ PEPROCESS _In_opt_ PETHREAD _In_opt_ PSECURITY_DESCRIPTOR SecurityDescriptor
Definition: wsk.h:191
unsigned char UCHAR
Definition: xmlstorage.h:181
__wchar_t WCHAR
Definition: xmlstorage.h:180
unsigned char BYTE
Definition: xxhash.c:193