Here too ;)
[reactos.git] / reactos / subsystems / win / basesrv / init.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Base API Server DLL
4 * FILE: subsystems/win/basesrv/init.c
5 * PURPOSE: Initialization
6 * PROGRAMMERS: Hermes Belusca-Maito (hermes.belusca@sfr.fr)
7 */
8
9 /* INCLUDES *******************************************************************/
10
11 #include "basesrv.h"
12 #include "api.h"
13
14 #define NDEBUG
15 #include <debug.h>
16
17 /* GLOBALS ********************************************************************/
18
19 HANDLE BaseSrvDllInstance = NULL;
20 extern UNICODE_STRING BaseSrvKernel32DllPath;
21
22 /* Memory */
23 HANDLE BaseSrvHeap = NULL; // Our own heap.
24 HANDLE BaseSrvSharedHeap = NULL; // Shared heap with CSR. (CsrSrvSharedSectionHeap)
25 PBASE_STATIC_SERVER_DATA BaseStaticServerData = NULL; // Data that we can share amongst processes. Initialized inside BaseSrvSharedHeap.
26
27 // Windows Server 2003 table from http://j00ru.vexillium.org/csrss_list/api_list.html#Windows_2k3
28 PCSR_API_ROUTINE BaseServerApiDispatchTable[BasepMaxApiNumber - BASESRV_FIRST_API_NUMBER] =
29 {
30 BaseSrvCreateProcess,
31 BaseSrvCreateThread,
32 BaseSrvGetTempFile,
33 BaseSrvExitProcess,
34 BaseSrvDebugProcess,
35 BaseSrvCheckVDM,
36 BaseSrvUpdateVDMEntry,
37 BaseSrvGetNextVDMCommand,
38 BaseSrvExitVDM,
39 BaseSrvIsFirstVDM,
40 BaseSrvGetVDMExitCode,
41 BaseSrvSetReenterCount,
42 BaseSrvSetProcessShutdownParam,
43 BaseSrvGetProcessShutdownParam,
44 BaseSrvNlsSetUserInfo,
45 BaseSrvNlsSetMultipleUserInfo,
46 BaseSrvNlsCreateSection,
47 BaseSrvSetVDMCurDirs,
48 BaseSrvGetVDMCurDirs,
49 BaseSrvBatNotification,
50 BaseSrvRegisterWowExec,
51 BaseSrvSoundSentryNotification,
52 BaseSrvRefreshIniFileMapping,
53 BaseSrvDefineDosDevice,
54 BaseSrvSetTermsrvAppInstallMode,
55 BaseSrvNlsUpdateCacheCount,
56 BaseSrvSetTermsrvClientTimeZone,
57 BaseSrvSxsCreateActivationContext,
58 BaseSrvUnknown,
59 BaseSrvRegisterThread,
60 BaseSrvNlsGetUserInfo,
61 };
62
63 BOOLEAN BaseServerApiServerValidTable[BasepMaxApiNumber - BASESRV_FIRST_API_NUMBER] =
64 {
65 TRUE, // BaseSrvCreateProcess
66 TRUE, // BaseSrvCreateThread
67 TRUE, // BaseSrvGetTempFile
68 FALSE, // BaseSrvExitProcess
69 FALSE, // BaseSrvDebugProcess
70 TRUE, // BaseSrvCheckVDM
71 TRUE, // BaseSrvUpdateVDMEntry
72 TRUE, // BaseSrvGetNextVDMCommand
73 TRUE, // BaseSrvExitVDM
74 TRUE, // BaseSrvIsFirstVDM
75 TRUE, // BaseSrvGetVDMExitCode
76 TRUE, // BaseSrvSetReenterCount
77 TRUE, // BaseSrvSetProcessShutdownParam
78 TRUE, // BaseSrvGetProcessShutdownParam
79 TRUE, // BaseSrvNlsSetUserInfo
80 TRUE, // BaseSrvNlsSetMultipleUserInfo
81 TRUE, // BaseSrvNlsCreateSection
82 TRUE, // BaseSrvSetVDMCurDirs
83 TRUE, // BaseSrvGetVDMCurDirs
84 TRUE, // BaseSrvBatNotification
85 TRUE, // BaseSrvRegisterWowExec
86 TRUE, // BaseSrvSoundSentryNotification
87 TRUE, // BaseSrvRefreshIniFileMapping
88 TRUE, // BaseSrvDefineDosDevice
89 TRUE, // BaseSrvSetTermsrvAppInstallMode
90 TRUE, // BaseSrvNlsUpdateCacheCount
91 TRUE, // BaseSrvSetTermsrvClientTimeZone
92 TRUE, // BaseSrvSxsCreateActivationContext
93 TRUE, // BaseSrvUnknown
94 TRUE, // BaseSrvRegisterThread
95 TRUE, // BaseSrvNlsGetUserInfo
96 };
97
98 PCHAR BaseServerApiNameTable[BasepMaxApiNumber - BASESRV_FIRST_API_NUMBER] =
99 {
100 "BaseCreateProcess",
101 "BaseCreateThread",
102 "BaseGetTempFile",
103 "BaseExitProcess",
104 "BaseDebugProcess",
105 "BaseCheckVDM",
106 "BaseUpdateVDMEntry",
107 "BaseGetNextVDMCommand",
108 "BaseExitVDM",
109 "BaseIsFirstVDM",
110 "BaseGetVDMExitCode",
111 "BaseSetReenterCount",
112 "BaseSetProcessShutdownParam",
113 "BaseGetProcessShutdownParam",
114 "BaseNlsSetUserInfo",
115 "BaseNlsSetMultipleUserInfo",
116 "BaseNlsCreateSection",
117 "BaseSetVDMCurDirs",
118 "BaseGetVDMCurDirs",
119 "BaseBatNotification",
120 "BaseRegisterWowExec",
121 "BaseSoundSentryNotification",
122 "BaseRefreshIniFileMapping",
123 "BaseDefineDosDevice",
124 "BaseSetTermsrvAppInstallMode",
125 "BaseNlsUpdateCacheCount",
126 "BaseSetTermsrvClientTimeZone",
127 "BaseSxsCreateActivationContext",
128 "BaseUnknown",
129 "BaseRegisterThread",
130 "BaseNlsGetUserInfo",
131 };
132
133
134 /* FUNCTIONS ******************************************************************/
135
136 NTSTATUS
137 NTAPI
138 CreateBaseAcls(OUT PACL* Dacl,
139 OUT PACL* RestrictedDacl)
140 {
141 PSID SystemSid, WorldSid, RestrictedSid;
142 SID_IDENTIFIER_AUTHORITY NtAuthority = {SECURITY_NT_AUTHORITY};
143 SID_IDENTIFIER_AUTHORITY WorldAuthority = {SECURITY_WORLD_SID_AUTHORITY};
144 NTSTATUS Status;
145 #if 0 // Unused code
146 UCHAR KeyValueBuffer[0x40];
147 PKEY_VALUE_PARTIAL_INFORMATION KeyValuePartialInfo;
148 UNICODE_STRING KeyName;
149 ULONG ProtectionMode = 0;
150 #endif
151 ULONG AclLength;
152 #if 0 // Unused code
153 ULONG ResultLength;
154 HANDLE hKey;
155 OBJECT_ATTRIBUTES ObjectAttributes;
156
157 /* Open the Session Manager Key */
158 RtlInitUnicodeString(&KeyName, SM_REG_KEY);
159 InitializeObjectAttributes(&ObjectAttributes,
160 &KeyName,
161 OBJ_CASE_INSENSITIVE,
162 NULL,
163 NULL);
164 Status = NtOpenKey(&hKey, KEY_READ, &ObjectAttributes);
165 if (NT_SUCCESS(Status))
166 {
167 /* Read the key value */
168 RtlInitUnicodeString(&KeyName, L"ProtectionMode");
169 Status = NtQueryValueKey(hKey,
170 &KeyName,
171 KeyValuePartialInformation,
172 KeyValueBuffer,
173 sizeof(KeyValueBuffer),
174 &ResultLength);
175
176 /* Make sure it's what we expect it to be */
177 KeyValuePartialInfo = (PKEY_VALUE_PARTIAL_INFORMATION)KeyValueBuffer;
178 if ((NT_SUCCESS(Status)) && (KeyValuePartialInfo->Type == REG_DWORD) &&
179 (*(PULONG)KeyValuePartialInfo->Data))
180 {
181 /* Save the Protection Mode */
182 ProtectionMode = *(PULONG)KeyValuePartialInfo->Data;
183 }
184
185 /* Close the handle */
186 NtClose(hKey);
187 }
188 #endif
189
190 /* Allocate the System SID */
191 Status = RtlAllocateAndInitializeSid(&NtAuthority,
192 1, SECURITY_LOCAL_SYSTEM_RID,
193 0, 0, 0, 0, 0, 0, 0,
194 &SystemSid);
195 ASSERT(NT_SUCCESS(Status));
196
197 /* Allocate the World SID */
198 Status = RtlAllocateAndInitializeSid(&WorldAuthority,
199 1, SECURITY_WORLD_RID,
200 0, 0, 0, 0, 0, 0, 0,
201 &WorldSid);
202 ASSERT(NT_SUCCESS(Status));
203
204 /* Allocate the restricted SID */
205 Status = RtlAllocateAndInitializeSid(&NtAuthority,
206 1, SECURITY_RESTRICTED_CODE_RID,
207 0, 0, 0, 0, 0, 0, 0,
208 &RestrictedSid);
209 ASSERT(NT_SUCCESS(Status));
210
211 /* Allocate one ACL with 3 ACEs each for one SID */
212 AclLength = sizeof(ACL) + 3 * sizeof(ACCESS_ALLOWED_ACE) +
213 RtlLengthSid(SystemSid) +
214 RtlLengthSid(WorldSid) +
215 RtlLengthSid(RestrictedSid);
216 *Dacl = RtlAllocateHeap(BaseSrvHeap, 0, AclLength);
217 ASSERT(*Dacl != NULL);
218
219 /* Set the correct header fields */
220 Status = RtlCreateAcl(*Dacl, AclLength, ACL_REVISION2);
221 ASSERT(NT_SUCCESS(Status));
222
223 /* Give the appropriate rights to each SID */
224 /* FIXME: Should check SessionId/ProtectionMode */
225 Status = RtlAddAccessAllowedAce(*Dacl, ACL_REVISION2, DIRECTORY_QUERY | DIRECTORY_TRAVERSE | DIRECTORY_CREATE_OBJECT | DIRECTORY_CREATE_SUBDIRECTORY | READ_CONTROL, WorldSid);
226 ASSERT(NT_SUCCESS(Status));
227 Status = RtlAddAccessAllowedAce(*Dacl, ACL_REVISION2, DIRECTORY_ALL_ACCESS, SystemSid);
228 ASSERT(NT_SUCCESS(Status));
229 Status = RtlAddAccessAllowedAce(*Dacl, ACL_REVISION2, DIRECTORY_TRAVERSE, RestrictedSid);
230 ASSERT(NT_SUCCESS(Status));
231
232 /* Now allocate the restricted DACL */
233 *RestrictedDacl = RtlAllocateHeap(BaseSrvHeap, 0, AclLength);
234 ASSERT(*RestrictedDacl != NULL);
235
236 /* Initialize it */
237 Status = RtlCreateAcl(*RestrictedDacl, AclLength, ACL_REVISION2);
238 ASSERT(NT_SUCCESS(Status));
239
240 /* And add the same ACEs as before */
241 /* FIXME: Not really fully correct */
242 Status = RtlAddAccessAllowedAce(*RestrictedDacl, ACL_REVISION2, DIRECTORY_QUERY | DIRECTORY_TRAVERSE | DIRECTORY_CREATE_OBJECT | DIRECTORY_CREATE_SUBDIRECTORY | READ_CONTROL, WorldSid);
243 ASSERT(NT_SUCCESS(Status));
244 Status = RtlAddAccessAllowedAce(*RestrictedDacl, ACL_REVISION2, DIRECTORY_ALL_ACCESS, SystemSid);
245 ASSERT(NT_SUCCESS(Status));
246 Status = RtlAddAccessAllowedAce(*RestrictedDacl, ACL_REVISION2, DIRECTORY_TRAVERSE, RestrictedSid);
247 ASSERT(NT_SUCCESS(Status));
248
249 /* The SIDs are captured, can free them now */
250 RtlFreeSid(RestrictedSid);
251 RtlFreeSid(WorldSid);
252 RtlFreeSid(SystemSid);
253 return Status;
254 }
255
256 VOID
257 NTAPI
258 BaseInitializeStaticServerData(IN PCSR_SERVER_DLL LoadedServerDll)
259 {
260 NTSTATUS Status;
261 WCHAR Buffer[MAX_PATH];
262 PWCHAR HeapBuffer;
263 UNICODE_STRING SystemRootString;
264 UNICODE_STRING UnexpandedSystemRootString = RTL_CONSTANT_STRING(L"%SystemRoot%");
265 UNICODE_STRING BaseSrvCSDString;
266 UNICODE_STRING BaseSrvWindowsDirectory;
267 UNICODE_STRING BaseSrvWindowsSystemDirectory;
268 UNICODE_STRING BnoString;
269 OBJECT_ATTRIBUTES ObjectAttributes;
270 ULONG SessionId;
271 HANDLE BaseSrvNamedObjectDirectory;
272 HANDLE BaseSrvRestrictedObjectDirectory;
273 PACL BnoDacl, BnoRestrictedDacl;
274 PSECURITY_DESCRIPTOR BnoSd;
275 HANDLE SymHandle;
276 UNICODE_STRING DirectoryName, SymlinkName;
277 ULONG LuidEnabled;
278 RTL_QUERY_REGISTRY_TABLE BaseServerRegistryConfigurationTable[2] =
279 {
280 {
281 NULL,
282 RTL_QUERY_REGISTRY_DIRECT,
283 L"CSDVersion",
284 &BaseSrvCSDString,
285 REG_NONE, NULL, 0
286 },
287
288 {0}
289 };
290
291 /* Initialize the memory */
292 BaseSrvHeap = RtlGetProcessHeap(); // Initialize our own heap.
293 BaseSrvSharedHeap = LoadedServerDll->SharedSection; // Get the CSR shared heap.
294
295 /* Get the session ID */
296 SessionId = NtCurrentPeb()->SessionId;
297
298 /* Get the Windows directory */
299 RtlInitEmptyUnicodeString(&SystemRootString, Buffer, sizeof(Buffer));
300 Status = RtlExpandEnvironmentStrings_U(NULL,
301 &UnexpandedSystemRootString,
302 &SystemRootString,
303 NULL);
304 ASSERT(NT_SUCCESS(Status));
305
306 /* Create the base directory */
307 Buffer[SystemRootString.Length / sizeof(WCHAR)] = UNICODE_NULL;
308 Status = RtlCreateUnicodeString(&BaseSrvWindowsDirectory,
309 SystemRootString.Buffer);
310 ASSERT(NT_SUCCESS(Status));
311
312 /* Create the system directory */
313 wcscat(SystemRootString.Buffer, L"\\System32");
314 Status = RtlCreateUnicodeString(&BaseSrvWindowsSystemDirectory,
315 SystemRootString.Buffer);
316 ASSERT(NT_SUCCESS(Status));
317
318 /* Create the kernel32 path */
319 wcscat(SystemRootString.Buffer, L"\\kernel32.dll");
320 Status = RtlCreateUnicodeString(&BaseSrvKernel32DllPath,
321 SystemRootString.Buffer);
322 ASSERT(NT_SUCCESS(Status));
323
324 /* FIXME: Check Session ID */
325 wcscpy(Buffer, L"\\BaseNamedObjects");
326 RtlInitUnicodeString(&BnoString, Buffer);
327
328 /* Allocate the server data */
329 BaseStaticServerData = RtlAllocateHeap(BaseSrvSharedHeap,
330 HEAP_ZERO_MEMORY,
331 sizeof(BASE_STATIC_SERVER_DATA));
332 ASSERT(BaseStaticServerData != NULL);
333
334 /* Process timezone information */
335 BaseStaticServerData->TermsrvClientTimeZoneId = TIME_ZONE_ID_INVALID;
336 BaseStaticServerData->TermsrvClientTimeZoneChangeNum = 0;
337 Status = NtQuerySystemInformation(SystemTimeOfDayInformation,
338 &BaseStaticServerData->TimeOfDay,
339 sizeof(BaseStaticServerData->TimeOfDay),
340 NULL);
341 ASSERT(NT_SUCCESS(Status));
342
343 /* Make a shared heap copy of the Windows directory */
344 BaseStaticServerData->WindowsDirectory = BaseSrvWindowsDirectory;
345 HeapBuffer = RtlAllocateHeap(BaseSrvSharedHeap,
346 0,
347 BaseSrvWindowsDirectory.MaximumLength);
348 ASSERT(HeapBuffer);
349 RtlCopyMemory(HeapBuffer,
350 BaseStaticServerData->WindowsDirectory.Buffer,
351 BaseSrvWindowsDirectory.MaximumLength);
352 BaseStaticServerData->WindowsDirectory.Buffer = HeapBuffer;
353
354 /* Make a shared heap copy of the System directory */
355 BaseStaticServerData->WindowsSystemDirectory = BaseSrvWindowsSystemDirectory;
356 HeapBuffer = RtlAllocateHeap(BaseSrvSharedHeap,
357 0,
358 BaseSrvWindowsSystemDirectory.MaximumLength);
359 ASSERT(HeapBuffer);
360 RtlCopyMemory(HeapBuffer,
361 BaseStaticServerData->WindowsSystemDirectory.Buffer,
362 BaseSrvWindowsSystemDirectory.MaximumLength);
363 BaseStaticServerData->WindowsSystemDirectory.Buffer = HeapBuffer;
364
365 /* This string is not used */
366 RtlInitEmptyUnicodeString(&BaseStaticServerData->WindowsSys32x86Directory,
367 NULL,
368 0);
369
370 /* Make a shared heap copy of the BNO directory */
371 BaseStaticServerData->NamedObjectDirectory = BnoString;
372 BaseStaticServerData->NamedObjectDirectory.MaximumLength = BnoString.Length +
373 sizeof(UNICODE_NULL);
374 HeapBuffer = RtlAllocateHeap(BaseSrvSharedHeap,
375 0,
376 BaseStaticServerData->NamedObjectDirectory.MaximumLength);
377 ASSERT(HeapBuffer);
378 RtlCopyMemory(HeapBuffer,
379 BaseStaticServerData->NamedObjectDirectory.Buffer,
380 BaseStaticServerData->NamedObjectDirectory.MaximumLength);
381 BaseStaticServerData->NamedObjectDirectory.Buffer = HeapBuffer;
382
383 /*
384 * Confirmed that in Windows, CSDNumber and RCNumber are actually Length
385 * and MaximumLength of the CSD String, since the same UNICODE_STRING is
386 * being queried twice, the first time as a ULONG!
387 *
388 * Somehow, in Windows this doesn't cause a buffer overflow, but it might
389 * in ReactOS, so this code is disabled until someone figures out WTF.
390 */
391 BaseStaticServerData->CSDNumber = 0;
392 BaseStaticServerData->RCNumber = 0;
393
394 /* Initialize the CSD string and query its value from the registry */
395 RtlInitEmptyUnicodeString(&BaseSrvCSDString, Buffer, sizeof(Buffer));
396 Status = RtlQueryRegistryValues(RTL_REGISTRY_WINDOWS_NT,
397 L"",
398 BaseServerRegistryConfigurationTable,
399 NULL,
400 NULL);
401 if (NT_SUCCESS(Status))
402 {
403 /* Copy into the shared buffer */
404 wcsncpy(BaseStaticServerData->CSDVersion,
405 BaseSrvCSDString.Buffer,
406 BaseSrvCSDString.Length / sizeof(WCHAR));
407 }
408 else
409 {
410 /* NULL-terminate to indicate nothing is there */
411 BaseStaticServerData->CSDVersion[0] = UNICODE_NULL;
412 }
413
414 /* Cache the system information */
415 Status = NtQuerySystemInformation(SystemBasicInformation,
416 &BaseStaticServerData->SysInfo,
417 sizeof(BaseStaticServerData->SysInfo),
418 NULL);
419 ASSERT(NT_SUCCESS(Status));
420
421 /* FIXME: Should query the registry for these */
422 BaseStaticServerData->DefaultSeparateVDM = FALSE;
423 BaseStaticServerData->IsWowTaskReady = FALSE;
424
425 /* Allocate a security descriptor and create it */
426 BnoSd = RtlAllocateHeap(BaseSrvHeap, 0, 1024);
427 ASSERT(BnoSd);
428 Status = RtlCreateSecurityDescriptor(BnoSd, SECURITY_DESCRIPTOR_REVISION);
429 ASSERT(NT_SUCCESS(Status));
430
431 /* Create the BNO and \Restricted DACLs */
432 Status = CreateBaseAcls(&BnoDacl, &BnoRestrictedDacl);
433 ASSERT(NT_SUCCESS(Status));
434
435 /* Set the BNO DACL as active for now */
436 Status = RtlSetDaclSecurityDescriptor(BnoSd, TRUE, BnoDacl, FALSE);
437 ASSERT(NT_SUCCESS(Status));
438
439 /* Create the BNO directory */
440 RtlInitUnicodeString(&BnoString, L"\\BaseNamedObjects");
441 InitializeObjectAttributes(&ObjectAttributes,
442 &BnoString,
443 OBJ_OPENIF | OBJ_PERMANENT | OBJ_CASE_INSENSITIVE,
444 NULL,
445 BnoSd);
446 Status = NtCreateDirectoryObject(&BaseSrvNamedObjectDirectory,
447 DIRECTORY_ALL_ACCESS,
448 &ObjectAttributes);
449 ASSERT(NT_SUCCESS(Status));
450
451 /* Check if we are session 0 */
452 if (SessionId == 0)
453 {
454 /* Mark this as a session 0 directory */
455 Status = NtSetInformationObject(BaseSrvNamedObjectDirectory,
456 ObjectSessionInformation,
457 NULL,
458 0);
459 ASSERT(NT_SUCCESS(Status));
460 }
461
462 /* Check if LUID device maps are enabled */
463 Status = NtQueryInformationProcess(NtCurrentProcess(),
464 ProcessLUIDDeviceMapsEnabled,
465 &LuidEnabled,
466 sizeof(LuidEnabled),
467 NULL);
468 ASSERT(NT_SUCCESS(Status));
469 BaseStaticServerData->LUIDDeviceMapsEnabled = (BOOLEAN)LuidEnabled;
470 if (!BaseStaticServerData->LUIDDeviceMapsEnabled)
471 {
472 /* Make Global point back to BNO */
473 RtlInitUnicodeString(&DirectoryName, L"Global");
474 RtlInitUnicodeString(&SymlinkName, L"\\BaseNamedObjects");
475 InitializeObjectAttributes(&ObjectAttributes,
476 &DirectoryName,
477 OBJ_OPENIF | OBJ_PERMANENT | OBJ_CASE_INSENSITIVE,
478 BaseSrvNamedObjectDirectory,
479 BnoSd);
480 Status = NtCreateSymbolicLinkObject(&SymHandle,
481 SYMBOLIC_LINK_ALL_ACCESS,
482 &ObjectAttributes,
483 &SymlinkName);
484 if ((NT_SUCCESS(Status)) && SessionId == 0) NtClose(SymHandle);
485
486 /* Make local point back to \Sessions\x\BNO */
487 RtlInitUnicodeString(&DirectoryName, L"Local");
488 ASSERT(SessionId == 0);
489 InitializeObjectAttributes(&ObjectAttributes,
490 &DirectoryName,
491 OBJ_OPENIF | OBJ_PERMANENT | OBJ_CASE_INSENSITIVE,
492 BaseSrvNamedObjectDirectory,
493 BnoSd);
494 Status = NtCreateSymbolicLinkObject(&SymHandle,
495 SYMBOLIC_LINK_ALL_ACCESS,
496 &ObjectAttributes,
497 &SymlinkName);
498 if ((NT_SUCCESS(Status)) && SessionId == 0) NtClose(SymHandle);
499
500 /* Make Session point back to BNOLINKS */
501 RtlInitUnicodeString(&DirectoryName, L"Session");
502 RtlInitUnicodeString(&SymlinkName, L"\\Sessions\\BNOLINKS");
503 InitializeObjectAttributes(&ObjectAttributes,
504 &DirectoryName,
505 OBJ_OPENIF | OBJ_PERMANENT | OBJ_CASE_INSENSITIVE,
506 BaseSrvNamedObjectDirectory,
507 BnoSd);
508 Status = NtCreateSymbolicLinkObject(&SymHandle,
509 SYMBOLIC_LINK_ALL_ACCESS,
510 &ObjectAttributes,
511 &SymlinkName);
512 if ((NT_SUCCESS(Status)) && SessionId == 0) NtClose(SymHandle);
513
514 /* Create the BNO\Restricted directory and set the restricted DACL */
515 RtlInitUnicodeString(&DirectoryName, L"Restricted");
516 Status = RtlSetDaclSecurityDescriptor(BnoSd, TRUE, BnoRestrictedDacl, FALSE);
517 ASSERT(NT_SUCCESS(Status));
518 InitializeObjectAttributes(&ObjectAttributes,
519 &DirectoryName,
520 OBJ_OPENIF | OBJ_PERMANENT | OBJ_CASE_INSENSITIVE,
521 BaseSrvNamedObjectDirectory,
522 BnoSd);
523 Status = NtCreateDirectoryObject(&BaseSrvRestrictedObjectDirectory,
524 DIRECTORY_ALL_ACCESS,
525 &ObjectAttributes);
526 ASSERT(NT_SUCCESS(Status));
527 }
528
529 /* Initialize NLS */
530 BaseSrvNLSInit(BaseStaticServerData);
531
532 /* Finally, set the pointer */
533 LoadedServerDll->SharedSection = BaseStaticServerData;
534 }
535
536 CSR_SERVER_DLL_INIT(ServerDllInitialization)
537 {
538 /* Setup the DLL Object */
539 LoadedServerDll->ApiBase = BASESRV_FIRST_API_NUMBER;
540 LoadedServerDll->HighestApiSupported = BasepMaxApiNumber;
541 LoadedServerDll->DispatchTable = BaseServerApiDispatchTable;
542 LoadedServerDll->ValidTable = BaseServerApiServerValidTable;
543 LoadedServerDll->NameTable = BaseServerApiNameTable;
544 LoadedServerDll->SizeOfProcessData = 0;
545 LoadedServerDll->ConnectCallback = NULL;
546 LoadedServerDll->DisconnectCallback = NULL;
547 LoadedServerDll->ShutdownProcessCallback = NULL;
548
549 BaseSrvDllInstance = LoadedServerDll->ServerHandle;
550
551 BaseInitializeStaticServerData(LoadedServerDll);
552
553 /* Initialize DOS devices management */
554 BaseInitDefineDosDevice();
555
556 /* All done */
557 return STATUS_SUCCESS;
558 }
559
560 BOOL
561 NTAPI
562 DllMain(IN HINSTANCE hInstanceDll,
563 IN DWORD dwReason,
564 IN LPVOID lpReserved)
565 {
566 UNREFERENCED_PARAMETER(hInstanceDll);
567 UNREFERENCED_PARAMETER(dwReason);
568 UNREFERENCED_PARAMETER(lpReserved);
569
570 if (DLL_PROCESS_DETACH == dwReason)
571 {
572 BaseCleanupDefineDosDevice();
573 }
574
575 return TRUE;
576 }
577
578 /* EOF */