[BASESRV] Make Buffer MAX_PATH big again
[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 BnoBuffer[100];
294 WCHAR Buffer[MAX_PATH];
295 PWCHAR HeapBuffer;
296 UNICODE_STRING SystemRootString;
297 UNICODE_STRING UnexpandedSystemRootString = RTL_CONSTANT_STRING(L"%SystemRoot%");
298 UNICODE_STRING BaseSrvCSDString;
299 UNICODE_STRING BaseSrvWindowsDirectory;
300 UNICODE_STRING BaseSrvWindowsSystemDirectory;
301 UNICODE_STRING BnoString;
302 OBJECT_ATTRIBUTES ObjectAttributes;
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 if (SessionId != 0)
357 {
358 swprintf(BnoBuffer, L"\\Sessions\\%ld\\BaseNamedObjects", SessionId);
359 }
360 else
361 {
362 wcscpy(BnoBuffer, L"\\BaseNamedObjects");
363 }
364 RtlInitUnicodeString(&BnoString, BnoBuffer);
365
366 /* Allocate the server data */
367 BaseStaticServerData = RtlAllocateHeap(BaseSrvSharedHeap,
368 HEAP_ZERO_MEMORY,
369 sizeof(BASE_STATIC_SERVER_DATA));
370 ASSERT(BaseStaticServerData != NULL);
371
372 /* Process timezone information */
373 BaseStaticServerData->TermsrvClientTimeZoneId = TIME_ZONE_ID_INVALID;
374 BaseStaticServerData->TermsrvClientTimeZoneChangeNum = 0;
375 Status = NtQuerySystemInformation(SystemTimeOfDayInformation,
376 &BaseStaticServerData->TimeOfDay,
377 sizeof(BaseStaticServerData->TimeOfDay),
378 NULL);
379 ASSERT(NT_SUCCESS(Status));
380
381 /* Make a shared heap copy of the Windows directory */
382 BaseStaticServerData->WindowsDirectory = BaseSrvWindowsDirectory;
383 HeapBuffer = RtlAllocateHeap(BaseSrvSharedHeap,
384 0,
385 BaseSrvWindowsDirectory.MaximumLength);
386 ASSERT(HeapBuffer);
387 RtlCopyMemory(HeapBuffer,
388 BaseStaticServerData->WindowsDirectory.Buffer,
389 BaseSrvWindowsDirectory.MaximumLength);
390 BaseStaticServerData->WindowsDirectory.Buffer = HeapBuffer;
391
392 /* Make a shared heap copy of the System directory */
393 BaseStaticServerData->WindowsSystemDirectory = BaseSrvWindowsSystemDirectory;
394 HeapBuffer = RtlAllocateHeap(BaseSrvSharedHeap,
395 0,
396 BaseSrvWindowsSystemDirectory.MaximumLength);
397 ASSERT(HeapBuffer);
398 RtlCopyMemory(HeapBuffer,
399 BaseStaticServerData->WindowsSystemDirectory.Buffer,
400 BaseSrvWindowsSystemDirectory.MaximumLength);
401 BaseStaticServerData->WindowsSystemDirectory.Buffer = HeapBuffer;
402
403 /* This string is not used */
404 RtlInitEmptyUnicodeString(&BaseStaticServerData->WindowsSys32x86Directory,
405 NULL,
406 0);
407
408 /* Make a shared heap copy of the BNO directory */
409 BaseStaticServerData->NamedObjectDirectory = BnoString;
410 BaseStaticServerData->NamedObjectDirectory.MaximumLength = BnoString.Length +
411 sizeof(UNICODE_NULL);
412 HeapBuffer = RtlAllocateHeap(BaseSrvSharedHeap,
413 0,
414 BaseStaticServerData->NamedObjectDirectory.MaximumLength);
415 ASSERT(HeapBuffer);
416 RtlCopyMemory(HeapBuffer,
417 BaseStaticServerData->NamedObjectDirectory.Buffer,
418 BaseStaticServerData->NamedObjectDirectory.MaximumLength);
419 BaseStaticServerData->NamedObjectDirectory.Buffer = HeapBuffer;
420
421 /*
422 * Confirmed that in Windows, CSDNumber and RCNumber are actually Length
423 * and MaximumLength of the CSD String, since the same UNICODE_STRING is
424 * being queried twice, the first time as a ULONG!
425 *
426 * Somehow, in Windows this doesn't cause a buffer overflow, but it might
427 * in ReactOS, so this code is disabled until someone figures out WTF.
428 */
429 BaseStaticServerData->CSDNumber = 0;
430 BaseStaticServerData->RCNumber = 0;
431
432 /* Initialize the CSD string and query its value from the registry */
433 RtlInitEmptyUnicodeString(&BaseSrvCSDString, Buffer, sizeof(Buffer));
434 Status = RtlQueryRegistryValues(RTL_REGISTRY_WINDOWS_NT,
435 L"",
436 BaseServerRegistryConfigurationTable,
437 NULL,
438 NULL);
439 if (NT_SUCCESS(Status))
440 {
441 /* Copy into the shared buffer */
442 wcsncpy(BaseStaticServerData->CSDVersion,
443 BaseSrvCSDString.Buffer,
444 BaseSrvCSDString.Length / sizeof(WCHAR));
445 }
446 else
447 {
448 /* Indicate nothing is there */
449 BaseSrvCSDString.Length = 0;
450 }
451 /* NULL-terminate */
452 BaseStaticServerData->CSDVersion[BaseSrvCSDString.Length / sizeof(WCHAR)] = UNICODE_NULL;
453
454 /* Cache the system information */
455 Status = NtQuerySystemInformation(SystemBasicInformation,
456 &BaseStaticServerData->SysInfo,
457 sizeof(BaseStaticServerData->SysInfo),
458 NULL);
459 ASSERT(NT_SUCCESS(Status));
460
461 /* Setup the ini file mappings */
462 Status = BaseSrvInitializeIniFileMappings(BaseStaticServerData);
463 ASSERT(NT_SUCCESS(Status));
464
465 /* FIXME: Should query the registry for these */
466 BaseStaticServerData->DefaultSeparateVDM = FALSE;
467 BaseStaticServerData->IsWowTaskReady = FALSE;
468
469 /* Allocate a security descriptor and create it */
470 BnoSd = RtlAllocateHeap(BaseSrvHeap, 0, 1024);
471 ASSERT(BnoSd);
472 Status = RtlCreateSecurityDescriptor(BnoSd, SECURITY_DESCRIPTOR_REVISION);
473 ASSERT(NT_SUCCESS(Status));
474
475 /* Create the BNO and \Restricted DACLs */
476 Status = CreateBaseAcls(&BnoDacl, &BnoRestrictedDacl);
477 ASSERT(NT_SUCCESS(Status));
478
479 /* Set the BNO DACL as active for now */
480 Status = RtlSetDaclSecurityDescriptor(BnoSd, TRUE, BnoDacl, FALSE);
481 ASSERT(NT_SUCCESS(Status));
482
483 /* Create the BNO directory */
484 InitializeObjectAttributes(&ObjectAttributes,
485 &BnoString,
486 OBJ_OPENIF | OBJ_PERMANENT | OBJ_CASE_INSENSITIVE,
487 NULL,
488 BnoSd);
489 Status = NtCreateDirectoryObject(&BaseSrvNamedObjectDirectory,
490 DIRECTORY_ALL_ACCESS,
491 &ObjectAttributes);
492 ASSERT(NT_SUCCESS(Status));
493
494 /* Check if we are session 0 */
495 if (SessionId == 0)
496 {
497 /* Mark this as a session 0 directory */
498 Status = NtSetInformationObject(BaseSrvNamedObjectDirectory,
499 ObjectSessionInformation,
500 NULL,
501 0);
502 ASSERT(NT_SUCCESS(Status));
503 }
504
505 /* Check if LUID device maps are enabled */
506 Status = NtQueryInformationProcess(NtCurrentProcess(),
507 ProcessLUIDDeviceMapsEnabled,
508 &LuidEnabled,
509 sizeof(LuidEnabled),
510 NULL);
511 ASSERT(NT_SUCCESS(Status));
512 BaseStaticServerData->LUIDDeviceMapsEnabled = (BOOLEAN)LuidEnabled;
513 if (!BaseStaticServerData->LUIDDeviceMapsEnabled)
514 {
515 /* Make Global point back to BNO */
516 RtlInitUnicodeString(&DirectoryName, L"Global");
517 RtlInitUnicodeString(&SymlinkName, L"\\BaseNamedObjects");
518 InitializeObjectAttributes(&ObjectAttributes,
519 &DirectoryName,
520 OBJ_OPENIF | OBJ_PERMANENT | OBJ_CASE_INSENSITIVE,
521 BaseSrvNamedObjectDirectory,
522 BnoSd);
523 Status = NtCreateSymbolicLinkObject(&SymHandle,
524 SYMBOLIC_LINK_ALL_ACCESS,
525 &ObjectAttributes,
526 &SymlinkName);
527 if ((NT_SUCCESS(Status)) && SessionId == 0) NtClose(SymHandle);
528
529 /* Make local point back to \Sessions\x\BNO */
530 RtlInitUnicodeString(&DirectoryName, L"Local");
531 ASSERT(SessionId == 0);
532 InitializeObjectAttributes(&ObjectAttributes,
533 &DirectoryName,
534 OBJ_OPENIF | OBJ_PERMANENT | OBJ_CASE_INSENSITIVE,
535 BaseSrvNamedObjectDirectory,
536 BnoSd);
537 Status = NtCreateSymbolicLinkObject(&SymHandle,
538 SYMBOLIC_LINK_ALL_ACCESS,
539 &ObjectAttributes,
540 &BnoString);
541 if ((NT_SUCCESS(Status)) && SessionId == 0) NtClose(SymHandle);
542
543 /* Make Session point back to BNOLINKS */
544 RtlInitUnicodeString(&DirectoryName, L"Session");
545 RtlInitUnicodeString(&SymlinkName, L"\\Sessions\\BNOLINKS");
546 InitializeObjectAttributes(&ObjectAttributes,
547 &DirectoryName,
548 OBJ_OPENIF | OBJ_PERMANENT | OBJ_CASE_INSENSITIVE,
549 BaseSrvNamedObjectDirectory,
550 BnoSd);
551 Status = NtCreateSymbolicLinkObject(&SymHandle,
552 SYMBOLIC_LINK_ALL_ACCESS,
553 &ObjectAttributes,
554 &SymlinkName);
555 if ((NT_SUCCESS(Status)) && SessionId == 0) NtClose(SymHandle);
556
557 /* Create the BNO\Restricted directory and set the restricted DACL */
558 RtlInitUnicodeString(&DirectoryName, L"Restricted");
559 Status = RtlSetDaclSecurityDescriptor(BnoSd, TRUE, BnoRestrictedDacl, FALSE);
560 ASSERT(NT_SUCCESS(Status));
561 InitializeObjectAttributes(&ObjectAttributes,
562 &DirectoryName,
563 OBJ_OPENIF | OBJ_PERMANENT | OBJ_CASE_INSENSITIVE,
564 BaseSrvNamedObjectDirectory,
565 BnoSd);
566 Status = NtCreateDirectoryObject(&BaseSrvRestrictedObjectDirectory,
567 DIRECTORY_ALL_ACCESS,
568 &ObjectAttributes);
569 ASSERT(NT_SUCCESS(Status));
570 }
571
572 /* Initialize NLS */
573 BaseSrvNLSInit(BaseStaticServerData);
574
575 /* Finally, set the pointer */
576 LoadedServerDll->SharedSection = BaseStaticServerData;
577 }
578
579 NTSTATUS
580 NTAPI
581 BaseClientConnectRoutine(IN PCSR_PROCESS CsrProcess,
582 IN OUT PVOID ConnectionInfo,
583 IN OUT PULONG ConnectionInfoLength)
584 {
585 PBASESRV_API_CONNECTINFO ConnectInfo = (PBASESRV_API_CONNECTINFO)ConnectionInfo;
586
587 if ( ConnectionInfo == NULL ||
588 ConnectionInfoLength == NULL ||
589 *ConnectionInfoLength != sizeof(*ConnectInfo) )
590 {
591 DPRINT1("BASESRV: Connection failed - ConnectionInfo = 0x%p ; ConnectionInfoLength = 0x%p (%lu), expected %lu\n",
592 ConnectionInfo,
593 ConnectionInfoLength,
594 ConnectionInfoLength ? *ConnectionInfoLength : (ULONG)-1,
595 sizeof(*ConnectInfo));
596
597 return STATUS_INVALID_PARAMETER;
598 }
599
600 /* Do the NLS connection */
601 return BaseSrvNlsConnect(CsrProcess, ConnectionInfo, ConnectionInfoLength);
602 }
603
604 VOID
605 NTAPI
606 BaseClientDisconnectRoutine(IN PCSR_PROCESS CsrProcess)
607 {
608 /* Cleanup VDM resources */
609 BaseSrvCleanupVDMResources(CsrProcess);
610 }
611
612 CSR_SERVER_DLL_INIT(ServerDllInitialization)
613 {
614 /* Setup the DLL Object */
615 LoadedServerDll->ApiBase = BASESRV_FIRST_API_NUMBER;
616 LoadedServerDll->HighestApiSupported = BasepMaxApiNumber;
617 LoadedServerDll->DispatchTable = BaseServerApiDispatchTable;
618 LoadedServerDll->ValidTable = BaseServerApiServerValidTable;
619 #ifdef CSR_DBG
620 LoadedServerDll->NameTable = BaseServerApiNameTable;
621 #endif
622 LoadedServerDll->SizeOfProcessData = 0;
623 LoadedServerDll->ConnectCallback = BaseClientConnectRoutine;
624 LoadedServerDll->DisconnectCallback = BaseClientDisconnectRoutine;
625 LoadedServerDll->ShutdownProcessCallback = NULL;
626
627 BaseSrvDllInstance = LoadedServerDll->ServerHandle;
628
629 BaseInitializeStaticServerData(LoadedServerDll);
630
631 /* Initialize DOS devices management */
632 BaseInitDefineDosDevice();
633
634 /* Initialize VDM support */
635 BaseInitializeVDM();
636
637 /* All done */
638 return STATUS_SUCCESS;
639 }
640
641 BOOL
642 NTAPI
643 DllMain(IN HINSTANCE hInstanceDll,
644 IN DWORD dwReason,
645 IN LPVOID lpReserved)
646 {
647 UNREFERENCED_PARAMETER(hInstanceDll);
648 UNREFERENCED_PARAMETER(dwReason);
649 UNREFERENCED_PARAMETER(lpReserved);
650
651 if (DLL_PROCESS_DETACH == dwReason)
652 {
653 BaseCleanupDefineDosDevice();
654 }
655
656 return TRUE;
657 }
658
659 /* EOF */