ReactOS  0.4.14-dev-854-gb9426a3
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 
28 PVOID /*PGET_DEFAULT_SORTKEY_SIZE */ pGetDefaultSortkeySize;
29 PVOID /*PGET_LINGUIST_LANG_SIZE*/ pGetLinguistLangSize;
30 PVOID /*PNLS_CONVERT_INTEGER_TO_STRING*/ pNlsConvertIntegerToString;
31 PVOID /*PVALIDATE_LCTYPE*/ pValidateLCType;
34 PVOID /*PGET_USER_DEFAULT_LANGID*/ pGetUserDefaultLangID;
37 
39 {
40  { "OpenDataFile", (PVOID*) &pOpenDataFile },
41  { "GetDefaultSortkeySize", (PVOID*) &pGetDefaultSortkeySize },
42  { "GetLinguistLangSize", (PVOID*) &pGetLinguistLangSize },
43  { "NlsConvertIntegerToString", (PVOID*) &pNlsConvertIntegerToString },
44  { "ValidateLCType", (PVOID*) &pValidateLCType },
45  { "ValidateLocale", (PVOID*) &pValidateLocale },
46  { "GetNlsSectionName", (PVOID*) &pGetNlsSectionName },
47  { "GetUserDefaultLangID", (PVOID*) &pGetUserDefaultLangID },
48  { "GetCPFileNameFromRegistry", (PVOID*) &pGetCPFileNameFromRegistry },
49  { "CreateNlsSecurityDescriptor", (PVOID*) &pCreateNlsSecurityDescriptor },
50 };
51 
52 /* FUNCTIONS *****************************************************************/
53 
55 NTAPI
57 {
59  ULONG i;
60  ANSI_STRING ProcedureName;
61 
62  /* Only do this once */
64 
65  /* Loop all imports */
66  for (i = 0; i < RTL_NUMBER_OF(BaseSrvKernel32Imports); i++)
67  {
68  /* Only look them up once */
69  if (!*BaseSrvKernel32Imports[i].FunctionPointer)
70  {
71  /* If we haven't loaded the DLL yet, do it now */
73  {
74  Status = LdrLoadDll(0,
75  0,
78  if (!NT_SUCCESS(Status))
79  {
80  DPRINT1("Failed to load %wZ\n", &BaseSrvKernel32DllPath);
81  return Status;
82  }
83  }
84 
85  /* Get the address of the routine being looked up*/
88  &ProcedureName,
89  0,
90  BaseSrvKernel32Imports[i].FunctionPointer);
91  DPRINT1("NLS: Found %Z at 0x%p\n",
92  &ProcedureName,
93  BaseSrvKernel32Imports[i].FunctionPointer);
94  if (!NT_SUCCESS(Status)) break;
95  }
96  }
97 
98  /* Did we find them all? */
100  {
101  /* Excellent */
103  return STATUS_SUCCESS;
104  }
105 
106  /* Nope, fail */
107  return Status;
108 }
109 
110 VOID
111 NTAPI
113 {
114  /* Initialize the lock */
116 
117  /* Initialize the data with all F's */
118  pNlsRegUserInfo = &StaticData->NlsUserInfo;
119  RtlFillMemory(&StaticData->NlsUserInfo, sizeof(StaticData->NlsUserInfo), 0xFF);
120 
121  /* Set empty LCID */
123 
124  /* Reset the cache update counter */
128 
129  /* Get the LCID */
131 }
132 
133 NTSTATUS
134 NTAPI
136  IN OUT PVOID ConnectionInfo,
137  IN OUT PULONG ConnectionInfoLength)
138 {
139  /* Does nothing */
140  return STATUS_SUCCESS;
141 }
142 
143 /* PUBLIC SERVER APIS *********************************************************/
144 
145 CSR_API(BaseSrvNlsSetUserInfo)
146 {
147  DPRINT1("%s not yet implemented\n", __FUNCTION__);
148  return STATUS_NOT_IMPLEMENTED;
149 }
150 
151 CSR_API(BaseSrvNlsSetMultipleUserInfo)
152 {
153  DPRINT1("%s not yet implemented\n", __FUNCTION__);
154  return STATUS_NOT_IMPLEMENTED;
155 }
156 
157 CSR_API(BaseSrvNlsCreateSection)
158 {
160  HANDLE SectionHandle, ProcessHandle, FileHandle;
161  ULONG LocaleId;
162  UNICODE_STRING NlsSectionName;
163  PWCHAR NlsFileName;
166  WCHAR FileNameBuffer[32];
167  WCHAR NlsSectionNameBuffer[32];
168  PBASE_NLS_CREATE_SECTION NlsMsg = &((PBASE_API_MESSAGE)ApiMessage)->Data.NlsCreateSection;
169 
170  /* Load kernel32 first and import the NLS routines */
172  if (!NT_SUCCESS(Status)) return Status;
173 
174  /* Assume failure */
175  NlsMsg->SectionHandle = NULL;
176 
177  /* Check and validate the locale ID, if one is present */
178  LocaleId = NlsMsg->LocaleId;
179  DPRINT1("NLS: Create Section with LCID: %lx for Type: %d\n", LocaleId, NlsMsg->Type);
180  if (LocaleId)
181  {
182  if (!pValidateLocale(LocaleId)) return STATUS_INVALID_PARAMETER;
183  }
184 
185  /* Check which NLS section is being created */
186  switch (NlsMsg->Type)
187  {
188  /* For each one, set the correct filename and object name */
189  case 1:
190  RtlInitUnicodeString(&NlsSectionName, L"\\NLS\\NlsSectionUnicode");
191  NlsFileName = L"unicode.nls";
192  break;
193  case 2:
194  RtlInitUnicodeString(&NlsSectionName, L"\\NLS\\NlsSectionLocale");
195  NlsFileName = L"locale.nls";
196  break;
197  case 3:
198  RtlInitUnicodeString(&NlsSectionName, L"\\NLS\\NlsSectionCType");
199  NlsFileName = L"ctype.nls";
200  break;
201  case 4:
202  RtlInitUnicodeString(&NlsSectionName, L"\\NLS\\NlsSectionSortkey");
203  NlsFileName = L"sortkey.nls";
204  break;
205  case 5:
206  RtlInitUnicodeString(&NlsSectionName, L"\\NLS\\NlsSectionSortTbls");
207  NlsFileName = L"sorttbls.nls";
208  break;
209  case 6:
210  RtlInitUnicodeString(&NlsSectionName, L"\\NLS\\NlsSectionCP437");
211  NlsFileName = L"c_437.nls";
212  break;
213  case 7:
214  RtlInitUnicodeString(&NlsSectionName, L"\\NLS\\NlsSectionCP1252");
215  NlsFileName = L"c_1252.nls";
216  break;
217  case 8:
218  RtlInitUnicodeString(&NlsSectionName, L"\\NLS\\NlsSectionLANG_EXCEPT");
219  NlsFileName = L"l_except.nls";
220  break;
221  case 9:
222  DPRINT1("This type not yet supported\n");
223  return STATUS_NOT_IMPLEMENTED;
224  case 10:
225  DPRINT1("This type not yet supported\n");
226  return STATUS_NOT_IMPLEMENTED;
227  case 11:
228  /* Get the filename for this locale */
232  {
233  DPRINT1("File name query failed\n");
235  }
236 
237  /* Get the name of the section for this locale */
238  DPRINT1("File name: %S\n", FileNameBuffer);
240  10,
241  0,
242  L"\\NLS\\NlsSectionCP",
243  NlsSectionNameBuffer,
244  RTL_NUMBER_OF(NlsSectionNameBuffer));
245  if (!NT_SUCCESS(Status))
246  {
247  DPRINT1("Section name query failed: %lx\n", Status);
248  return Status;
249  }
250 
251  /* Setup the name and go open it */
252  NlsFileName = FileNameBuffer;
253  DPRINT1("Section name: %S\n", NlsSectionNameBuffer);
254  RtlInitUnicodeString(&NlsSectionName, NlsSectionNameBuffer);
255  break;
256  case 12:
257  RtlInitUnicodeString(&NlsSectionName, L"\\NLS\\NlsSectionGeo");
258  NlsFileName = L"geo.nls";
259  break;
260  default:
261  DPRINT1("NLS: Invalid NLS type!\n");
263  }
264 
265  /* Open the specified NLS file */
266  Status = pOpenDataFile(&FileHandle, NlsFileName);
267  if (Status != STATUS_SUCCESS)
268  {
269  DPRINT1("NLS: Failed to open file: %lx\n", Status);
270  return Status;
271  }
272 
273  /* Create an SD for the section object */
275  sizeof(SecurityDescriptor),
276  0x80000000);
277  if (!NT_SUCCESS(Status))
278  {
279  DPRINT1("NLS: CreateNlsSecurityDescriptor FAILED!: %lx\n", Status);
281  return Status;
282  }
283 
284  /* Create the section object proper */
286  &NlsSectionName,
288  NULL,
290  Status = NtCreateSection(&SectionHandle,
293  0,
295  SEC_COMMIT,
296  FileHandle);
298  if (!NT_SUCCESS(Status))
299  {
300  DPRINT1("NLS: Failed to create section! %lx\n", Status);
301  return Status;
302  }
303 
304  /* Open a handle to the calling process */
309  &ApiMessage->Header.ClientId);
310  if (!NT_SUCCESS(Status))
311  {
312  DPRINT1("NLS: Failed to open process! %lx\n", Status);
313  NtClose(SectionHandle);
314  return Status;
315  }
316 
317  /* Duplicate the handle to the section object into it */
319  SectionHandle,
321  &NlsMsg->SectionHandle,
322  0,
323  0,
324  3);
326  return Status;
327 }
328 
329 CSR_API(BaseSrvNlsUpdateCacheCount)
330 {
331  DPRINT1("%s not yet implemented\n", __FUNCTION__);
332  return STATUS_NOT_IMPLEMENTED;
333 }
334 
335 CSR_API(BaseSrvNlsGetUserInfo)
336 {
338  PBASE_NLS_GET_USER_INFO NlsMsg = &((PBASE_API_MESSAGE)ApiMessage)->Data.NlsGetUserInfo;
339 
340  /* Make sure the buffer is valid and of the right size */
341  if ((CsrValidateMessageBuffer(ApiMessage, &NlsMsg->NlsUserInfo, NlsMsg->Size, TRUE)) &&
342  (NlsMsg->Size == sizeof(NLS_USER_INFO)))
343  {
344  /* Acquire the lock to prevent updates while we copy */
346  if (NT_SUCCESS(Status))
347  {
348  /* Do the copy now, then drop the lock */
349  RtlCopyMemory(NlsMsg->NlsUserInfo, pNlsRegUserInfo, NlsMsg->Size);
350  DPRINT1("NLS Data copy complete\n");
352  }
353  }
354  else
355  {
356  /* The data was invalid, bail out */
357  DPRINT1("NLS: Size of info is invalid: %lx vs %lx\n", NlsMsg->Size, sizeof(NLS_USER_INFO));
359  }
360 
361  /* All done */
362  return Status;
363 }
364 
365 /* PUBLIC APIS ****************************************************************/
366 
367 NTSTATUS
368 NTAPI
370 {
371  DPRINT1("%s(%lu) not yet implemented\n", __FUNCTION__, Unknown);
372  return STATUS_NOT_IMPLEMENTED;
373 }
374 
375 NTSTATUS
376 NTAPI
378  DWORD Unknown2)
379 {
380  DPRINT1("%s(%lu, %lu) not yet implemented\n", __FUNCTION__, Unknown1, Unknown2);
381  return STATUS_NOT_IMPLEMENTED;
382 }
383 
384 /* EOF */
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
#define IN
Definition: typedefs.h:38
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
PGET_NLS_SECTION_NAME pGetNlsSectionName
Definition: nls.c:33
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:3373
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:225
_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:182
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
UNICODE_STRING BaseSrvKernel32DllPath
Definition: nls.c:25
ULONG ulCacheUpdateCount
Definition: base.h:69
LONG NTSTATUS
Definition: precomp.h:26
BOOLEAN NTAPI CsrValidateMessageBuffer(IN PCSR_API_MESSAGE ApiMessage, IN PVOID *Buffer, IN ULONG ElementCount, IN ULONG ElementSize)
Definition: api.c:1315
BOOL(WINAPI * PGET_CP_FILE_NAME_FROM_REGISTRY)(UINT CodePage, LPWSTR FileName, ULONG FileNameSize)
Definition: basesrv.h:49
BASESRV_KERNEL_IMPORTS BaseSrvKernel32Imports[10]
Definition: nls.c:38
PCREATE_NLS_SECURTY_DESCRIPTOR pCreateNlsSecurityDescriptor
Definition: nls.c:36
NTSYSAPI NTSTATUS NTAPI RtlEnterCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)
#define OBJ_PERMANENT
Definition: winternl.h:226
HANDLE BaseSrvKernel32DllHandle
Definition: nls.c:24
PKPROCESS CsrProcess
Definition: videoprt.c:37
uint16_t * PWCHAR
Definition: typedefs.h:54
NTSTATUS NTAPI NtOpenProcess(OUT PHANDLE ProcessHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, IN PCLIENT_ID ClientId)
Definition: process.c:1440
VOID NTAPI BaseSrvNLSInit(IN PBASE_STATIC_SERVER_DATA StaticData)
Definition: nls.c:112
NTSYSAPI VOID NTAPI RtlInitAnsiString(PANSI_STRING DestinationString, PCSZ SourceString)
NTSTATUS NTAPI BaseSrvDelayLoadKernel32(VOID)
Definition: nls.c:56
NTSTATUS NTAPI BaseSrvNlsLogon(DWORD Unknown)
Definition: nls.c:369
#define OBJ_OPENIF
Definition: winternl.h:229
HANDLE FileHandle
Definition: stats.c:38
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
BOOL(WINAPI * PVALIDATE_LOCALE)(IN ULONG LocaleId)
Definition: basesrv.h:60
#define SEC_COMMIT
Definition: mmtypes.h:99
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
PVOID pGetDefaultSortkeySize
Definition: nls.c:28
NTSTATUS(WINAPI * PCREATE_NLS_SECURTY_DESCRIPTOR)(IN PVOID Buffer, IN ULONG BufferSize, IN ULONG AceType)
Definition: basesrv.h:61
NTSYSAPI NTSTATUS NTAPI RtlLeaveCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)
#define PROCESS_DUP_HANDLE
struct _BASE_API_MESSAGE * PBASE_API_MESSAGE
NTSTATUS NTAPI LdrGetProcedureAddress(IN PVOID BaseAddress, IN PANSI_STRING Name, IN ULONG Ordinal, OUT PVOID *ProcedureAddress)
Definition: ldrapi.c:823
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
PVOID pGetLinguistLangSize
Definition: nls.c:29
NTSTATUS NTAPI BaseSrvNlsUpdateRegistryCache(DWORD Unknown1, DWORD Unknown2)
Definition: nls.c:377
RTL_CRITICAL_SECTION NlsCacheCriticalSection
Definition: nls.c:20
PVOID pNlsConvertIntegerToString
Definition: nls.c:30
BOOLEAN BaseSrvKernel32DelayLoadComplete
Definition: nls.c:23
#define NtCurrentProcess()
Definition: nt_native.h:1657
NTSTATUS(WINAPI * POPEN_DATA_FILE)(HANDLE hFile, PWCHAR FileName)
Definition: basesrv.h:46
PVOID pValidateLCType
Definition: nls.c:31
LCID UserLocaleId
Definition: base.h:67
__wchar_t WCHAR
Definition: xmlstorage.h:180
NTSYSAPI NTSTATUS NTAPI RtlInitializeCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
PNLS_USER_INFO pNlsRegUserInfo
Definition: nls.c:21
BOOL(WINAPI * PGET_NLS_SECTION_NAME)(UINT CodePage, UINT Base, ULONG Unknown, LPWSTR BaseName, LPWSTR Result, ULONG ResultSize)
Definition: basesrv.h:53
unsigned long DWORD
Definition: ntddk_ex.h:95
PVOID pGetUserDefaultLangID
Definition: nls.c:34
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3399
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
unsigned char UCHAR
Definition: xmlstorage.h:181
CSR_API(BaseSrvNlsSetUserInfo)
Definition: nls.c:145
static const WCHAR L[]
Definition: oid.c:1250
#define SECTION_MAP_READ
Definition: compat.h:128
NTSTATUS NTAPI DECLSPEC_HOTPATCH LdrLoadDll(IN PWSTR SearchPath OPTIONAL, IN PULONG DllCharacteristics OPTIONAL, IN PUNICODE_STRING DllName, OUT PVOID *BaseAddress)
Definition: ldrapi.c:310
Status
Definition: gdiplustypes.h:24
#define RTL_NUMBER_OF(x)
Definition: RtlRegistry.c:12
NTSTATUS NTAPI BaseSrvNlsConnect(IN PCSR_PROCESS CsrProcess, IN OUT PVOID ConnectionInfo, IN OUT PULONG ConnectionInfoLength)
Definition: nls.c:135
NTSTATUS NTAPI NtQueryDefaultLocale(IN BOOLEAN UserProfile, OUT PLCID DefaultLocaleId)
Definition: locale.c:162
unsigned int * PULONG
Definition: retypes.h:1
#define PAGE_READONLY
Definition: compat.h:127
POPEN_DATA_FILE pOpenDataFile
Definition: nls.c:27
PVALIDATE_LOCALE pValidateLocale
Definition: nls.c:32
#define DPRINT1
Definition: precomp.h:8
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:1270
WCHAR FileNameBuffer[_MAX_PATH]
Definition: framewnd.c:239
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:3407
#define OUT
Definition: typedefs.h:39
PGET_CP_FILE_NAME_FROM_REGISTRY pGetCPFileNameFromRegistry
Definition: nls.c:35
unsigned int ULONG
Definition: retypes.h:1
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
_In_ HANDLE ProcessHandle
Definition: mmfuncs.h:403
return STATUS_SUCCESS
Definition: btrfs.c:2938
#define __FUNCTION__
Definition: types.h:112
#define RtlFillMemory(Dest, Length, Fill)
Definition: winternl.h:593