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