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