9db5886ef1d5deabaf1aa1f1b697a131e1e3b040
[reactos.git] / reactos / subsystems / win / basesrv / nls.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Base API Server DLL
4 * FILE: subsystems/win/basesrv/vdm.c
5 * PURPOSE: Virtual DOS Machines (VDM) Support
6 * PROGRAMMERS: Hermes Belusca-Maito (hermes.belusca@sfr.fr)
7 */
8
9 /* INCLUDES *******************************************************************/
10
11 #include "basesrv.h"
12
13 #define NDEBUG
14 #include <debug.h>
15
16 /* GLOBALS ********************************************************************/
17
18 BOOLEAN BaseSrvKernel32DelayLoadComplete;
19 HANDLE BaseSrvKernel32DllHandle;
20 UNICODE_STRING BaseSrvKernel32DllPath;
21
22 POPEN_DATA_FILE pOpenDataFile;
23 PVOID /*PGET_DEFAULT_SORTKEY_SIZE */ pGetDefaultSortkeySize;
24 PVOID /*PGET_LINGUIST_LANG_SIZE*/ pGetLinguistLangSize;
25 PVOID /*PNLS_CONVERT_INTEGER_TO_STRING*/ pNlsConvertIntegerToString;
26 PVOID /*PVALIDATE_LCTYPE*/ pValidateLCType;
27 PVALIDATE_LOCALE pValidateLocale;
28 PGET_NLS_SECTION_NAME pGetNlsSectionName;
29 PVOID /*PGET_USER_DEFAULT_LANGID*/ pGetUserDefaultLangID;
30 PGET_CP_FILE_NAME_FROM_REGISTRY pGetCPFileNameFromRegistry;
31 PCREATE_NLS_SECURTY_DESCRIPTOR pCreateNlsSecurityDescriptor;
32
33 BASESRV_KERNEL_IMPORTS BaseSrvKernel32Imports[10] =
34 {
35 { "OpenDataFile", (PVOID*) &pOpenDataFile },
36 { "GetDefaultSortkeySize", (PVOID*) &pGetDefaultSortkeySize },
37 { "GetLinguistLangSize", (PVOID*) &pGetLinguistLangSize },
38 { "NlsConvertIntegerToString", (PVOID*) &pNlsConvertIntegerToString },
39 { "ValidateLCType", (PVOID*) &pValidateLCType },
40 { "ValidateLocale", (PVOID*) &pValidateLocale },
41 { "GetNlsSectionName", (PVOID*) &pGetNlsSectionName },
42 { "GetUserDefaultLangID", (PVOID*) &pGetUserDefaultLangID },
43 { "GetCPFileNameFromRegistry", (PVOID*) &pGetCPFileNameFromRegistry },
44 { "CreateNlsSecurityDescriptor", (PVOID*) &pCreateNlsSecurityDescriptor },
45 };
46
47 /* FUNCTIONS *****************************************************************/
48
49 NTSTATUS
50 NTAPI
51 BaseSrvDelayLoadKernel32(VOID)
52 {
53 NTSTATUS Status;
54 ULONG i;
55 ANSI_STRING ProcedureName;
56
57 /* Only do this once */
58 if (BaseSrvKernel32DelayLoadComplete) return STATUS_SUCCESS;
59
60 /* Loop all imports */
61 for (i = 0; i < RTL_NUMBER_OF(BaseSrvKernel32Imports); i++)
62 {
63 /* Only look them up once */
64 if (!*BaseSrvKernel32Imports[i].FunctionPointer)
65 {
66 /* If we haven't loaded the DLL yet, do it now */
67 if (!BaseSrvKernel32DllHandle)
68 {
69 Status = LdrLoadDll(0,
70 0,
71 &BaseSrvKernel32DllPath,
72 &BaseSrvKernel32DllHandle);
73 if (!NT_SUCCESS(Status))
74 {
75 DPRINT1("Failed to load %wZ\n", &BaseSrvKernel32DllPath);
76 return Status;
77 }
78 }
79
80 /* Get the address of the routine being looked up*/
81 RtlInitAnsiString(&ProcedureName, BaseSrvKernel32Imports[i].FunctionName);
82 Status = LdrGetProcedureAddress(BaseSrvKernel32DllHandle,
83 &ProcedureName,
84 0,
85 BaseSrvKernel32Imports[i].FunctionPointer);
86 DPRINT1("NLS: Found %Z at 0x%p\n",
87 &ProcedureName,
88 BaseSrvKernel32Imports[i].FunctionPointer);
89 if (!NT_SUCCESS(Status)) break;
90 }
91 }
92
93 /* Did we find them all? */
94 if (i == RTL_NUMBER_OF(BaseSrvKernel32Imports))
95 {
96 /* Excellent */
97 BaseSrvKernel32DelayLoadComplete = TRUE;
98 return STATUS_SUCCESS;
99 }
100
101 /* Nope, fail */
102 return Status;
103 }
104
105 /* PUBLIC SERVER APIS *********************************************************/
106
107 CSR_API(BaseSrvNlsSetUserInfo)
108 {
109 DPRINT1("%s not yet implemented\n", __FUNCTION__);
110 return STATUS_NOT_IMPLEMENTED;
111 }
112
113 CSR_API(BaseSrvNlsSetMultipleUserInfo)
114 {
115 DPRINT1("%s not yet implemented\n", __FUNCTION__);
116 return STATUS_NOT_IMPLEMENTED;
117 }
118
119 CSR_API(BaseSrvNlsCreateSection)
120 {
121 NTSTATUS Status;
122 HANDLE SectionHandle, ProcessHandle, FileHandle;
123 ULONG LocaleId;
124 UNICODE_STRING NlsSectionName;
125 PWCHAR NlsFileName;
126 UCHAR SecurityDescriptor[52];
127 OBJECT_ATTRIBUTES ObjectAttributes;
128 PBASE_NLS_CREATE_SECTION NlsMsg = &((PBASE_API_MESSAGE)ApiMessage)->Data.NlsCreateSection;
129
130 /* Load kernel32 first and import the NLS routines */
131 Status = BaseSrvDelayLoadKernel32();
132 if (!NT_SUCCESS(Status)) return Status;
133
134 /* Assume failure */
135 NlsMsg->SectionHandle = NULL;
136
137 /* Check and validate the locale ID, if one is present */
138 LocaleId = NlsMsg->LocaleId;
139 DPRINT1("NLS: Create Section with LCID: %lx for Type: %d\n", LocaleId, NlsMsg->Type);
140 if (LocaleId)
141 {
142 if (!pValidateLocale(LocaleId)) return STATUS_INVALID_PARAMETER;
143 }
144
145 /* Check which NLS section is being created */
146 switch (NlsMsg->Type)
147 {
148 /* For each one, set the correct filename and object name */
149 case 1:
150 RtlInitUnicodeString(&NlsSectionName, L"\\NLS\\NlsSectionUnicode");
151 NlsFileName = L"unicode.nls";
152 break;
153 case 2:
154 RtlInitUnicodeString(&NlsSectionName, L"\\NLS\\NlsSectionLocale");
155 NlsFileName = L"locale.nls";
156 break;
157 case 3:
158 RtlInitUnicodeString(&NlsSectionName, L"\\NLS\\NlsSectionCType");
159 NlsFileName = L"ctype.nls";
160 break;
161 case 4:
162 RtlInitUnicodeString(&NlsSectionName, L"\\NLS\\NlsSectionSortkey");
163 NlsFileName = L"sortkey.nls";
164 break;
165 case 5:
166 RtlInitUnicodeString(&NlsSectionName, L"\\NLS\\NlsSectionSortTbls");
167 NlsFileName = L"sorttbls.nls";
168 break;
169 case 6:
170 RtlInitUnicodeString(&NlsSectionName, L"\\NLS\\NlsSectionCP437");
171 NlsFileName = L"c_437.nls";
172 break;
173 case 7:
174 RtlInitUnicodeString(&NlsSectionName, L"\\NLS\\NlsSectionCP1252");
175 NlsFileName = L"c_1252.nls";
176 break;
177 case 8:
178 RtlInitUnicodeString(&NlsSectionName, L"\\NLS\\NlsSectionLANG_EXCEPT");
179 NlsFileName = L"l_except.nls";
180 break;
181 case 9:
182 DPRINT1("This type not yet supported\n");
183 return STATUS_NOT_IMPLEMENTED;
184 case 10:
185 DPRINT1("This type not yet supported\n");
186 return STATUS_NOT_IMPLEMENTED;
187 case 11:
188 DPRINT1("This type not yet supported\n");
189 return STATUS_NOT_IMPLEMENTED;
190 case 12:
191 RtlInitUnicodeString(&NlsSectionName, L"\\NLS\\NlsSectionGeo");
192 NlsFileName = L"geo.nls";
193 break;
194 default:
195 DPRINT1("NLS: Invalid NLS type!\n");
196 return STATUS_INVALID_PARAMETER;
197 }
198
199 /* Open the specified NLS file */
200 Status = pOpenDataFile(&FileHandle, NlsFileName);
201 if (Status != STATUS_SUCCESS)
202 {
203 DPRINT1("NLS: Failed to open file: %lx\n", Status);
204 return Status;
205 }
206
207 /* Create an SD for the section object */
208 Status = pCreateNlsSecurityDescriptor(&SecurityDescriptor,
209 sizeof(SecurityDescriptor),
210 0x80000000);
211 if (!NT_SUCCESS(Status))
212 {
213 DPRINT1("NLS: CreateNlsSecurityDescriptor FAILED!: %lx\n", Status);
214 NtClose(FileHandle);
215 return Status;
216 }
217
218 /* Create the section object proper */
219 InitializeObjectAttributes(&ObjectAttributes,
220 &NlsSectionName,
221 OBJ_CASE_INSENSITIVE | OBJ_PERMANENT | OBJ_OPENIF,
222 NULL,
223 &SecurityDescriptor);
224 Status = NtCreateSection(&SectionHandle,
225 SECTION_MAP_READ,
226 &ObjectAttributes,
227 0,
228 PAGE_READONLY,
229 SEC_COMMIT,
230 FileHandle);
231 NtClose(FileHandle);
232 if (!NT_SUCCESS(Status))
233 {
234 DPRINT1("NLS: Failed to create section! %lx\n", Status);
235 return Status;
236 }
237
238 /* Open a handle to the calling process */
239 InitializeObjectAttributes(&ObjectAttributes, NULL, 0, NULL, NULL);
240 Status = NtOpenProcess(&ProcessHandle,
241 PROCESS_DUP_HANDLE,
242 &ObjectAttributes,
243 &ApiMessage->Header.ClientId);
244 if (!NT_SUCCESS(Status))
245 {
246 DPRINT1("NLS: Failed to open process! %lx\n", Status);
247 NtClose(SectionHandle);
248 return Status;
249 }
250
251 /* Duplicate the handle to the section object into it */
252 Status = NtDuplicateObject(NtCurrentProcess(),
253 SectionHandle,
254 ProcessHandle,
255 &NlsMsg->SectionHandle,
256 0,
257 0,
258 3);
259 NtClose(ProcessHandle);
260 return Status;
261 }
262
263 CSR_API(BaseSrvNlsUpdateCacheCount)
264 {
265 DPRINT1("%s not yet implemented\n", __FUNCTION__);
266 return STATUS_NOT_IMPLEMENTED;
267 }
268
269 CSR_API(BaseSrvNlsGetUserInfo)
270 {
271 DPRINT1("%s not yet implemented\n", __FUNCTION__);
272 return STATUS_NOT_IMPLEMENTED;
273 }
274
275 /* EOF */