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