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