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