xref: /reactos/subsystems/win/basesrv/init.c (revision 222ace7c)
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