1 /* 2 * COPYRIGHT: See COPYING in the top level directory 3 * PROJECT: ReactOS Base API Server DLL 4 * FILE: subsystems/win/basesrv/init.c 5 * PURPOSE: Initialization 6 * PROGRAMMERS: Hermes Belusca-Maito (hermes.belusca@sfr.fr) 7 */ 8 9 /* INCLUDES *******************************************************************/ 10 11 #include "basesrv.h" 12 #include "vdm.h" 13 14 #include <winreg.h> 15 16 #define NDEBUG 17 #include <debug.h> 18 19 #include "api.h" 20 21 /* GLOBALS ********************************************************************/ 22 23 HANDLE BaseSrvDllInstance = NULL; 24 extern UNICODE_STRING BaseSrvKernel32DllPath; 25 26 /* Memory */ 27 HANDLE BaseSrvHeap = NULL; // Our own heap. 28 HANDLE BaseSrvSharedHeap = NULL; // Shared heap with CSR. (CsrSrvSharedSectionHeap) 29 PBASE_STATIC_SERVER_DATA BaseStaticServerData = NULL; // Data that we can share amongst processes. Initialized inside BaseSrvSharedHeap. 30 31 PINIFILE_MAPPING BaseSrvIniFileMapping; 32 33 // Windows Server 2003 table from http://j00ru.vexillium.org/csrss_list/api_list.html#Windows_2k3 34 PCSR_API_ROUTINE BaseServerApiDispatchTable[BasepMaxApiNumber - BASESRV_FIRST_API_NUMBER] = 35 { 36 BaseSrvCreateProcess, 37 BaseSrvCreateThread, 38 BaseSrvGetTempFile, 39 BaseSrvExitProcess, 40 BaseSrvDebugProcess, 41 BaseSrvCheckVDM, 42 BaseSrvUpdateVDMEntry, 43 BaseSrvGetNextVDMCommand, 44 BaseSrvExitVDM, 45 BaseSrvIsFirstVDM, 46 BaseSrvGetVDMExitCode, 47 BaseSrvSetReenterCount, 48 BaseSrvSetProcessShutdownParam, 49 BaseSrvGetProcessShutdownParam, 50 BaseSrvNlsSetUserInfo, 51 BaseSrvNlsSetMultipleUserInfo, 52 BaseSrvNlsCreateSection, 53 BaseSrvSetVDMCurDirs, 54 BaseSrvGetVDMCurDirs, 55 BaseSrvBatNotification, 56 BaseSrvRegisterWowExec, 57 BaseSrvSoundSentryNotification, 58 BaseSrvRefreshIniFileMapping, 59 BaseSrvDefineDosDevice, 60 BaseSrvSetTermsrvAppInstallMode, 61 BaseSrvNlsUpdateCacheCount, 62 BaseSrvSetTermsrvClientTimeZone, 63 BaseSrvSxsCreateActivationContext, 64 BaseSrvUnknown, 65 BaseSrvRegisterThread, 66 BaseSrvNlsGetUserInfo, 67 }; 68 69 BOOLEAN BaseServerApiServerValidTable[BasepMaxApiNumber - BASESRV_FIRST_API_NUMBER] = 70 { 71 TRUE, // BaseSrvCreateProcess 72 TRUE, // BaseSrvCreateThread 73 TRUE, // BaseSrvGetTempFile 74 FALSE, // BaseSrvExitProcess 75 FALSE, // BaseSrvDebugProcess 76 TRUE, // BaseSrvCheckVDM 77 TRUE, // BaseSrvUpdateVDMEntry 78 TRUE, // BaseSrvGetNextVDMCommand 79 TRUE, // BaseSrvExitVDM 80 TRUE, // BaseSrvIsFirstVDM 81 TRUE, // BaseSrvGetVDMExitCode 82 TRUE, // BaseSrvSetReenterCount 83 TRUE, // BaseSrvSetProcessShutdownParam 84 TRUE, // BaseSrvGetProcessShutdownParam 85 TRUE, // BaseSrvNlsSetUserInfo 86 TRUE, // BaseSrvNlsSetMultipleUserInfo 87 TRUE, // BaseSrvNlsCreateSection 88 TRUE, // BaseSrvSetVDMCurDirs 89 TRUE, // BaseSrvGetVDMCurDirs 90 TRUE, // BaseSrvBatNotification 91 TRUE, // BaseSrvRegisterWowExec 92 TRUE, // BaseSrvSoundSentryNotification 93 TRUE, // BaseSrvRefreshIniFileMapping 94 TRUE, // BaseSrvDefineDosDevice 95 TRUE, // BaseSrvSetTermsrvAppInstallMode 96 TRUE, // BaseSrvNlsUpdateCacheCount 97 TRUE, // BaseSrvSetTermsrvClientTimeZone 98 TRUE, // BaseSrvSxsCreateActivationContext 99 TRUE, // BaseSrvUnknown 100 TRUE, // BaseSrvRegisterThread 101 TRUE, // BaseSrvNlsGetUserInfo 102 }; 103 104 /* 105 * On Windows Server 2003, CSR Servers contain 106 * the API Names Table only in Debug Builds. 107 */ 108 #ifdef CSR_DBG 109 PCHAR BaseServerApiNameTable[BasepMaxApiNumber - BASESRV_FIRST_API_NUMBER] = 110 { 111 "BaseCreateProcess", 112 "BaseCreateThread", 113 "BaseGetTempFile", 114 "BaseExitProcess", 115 "BaseDebugProcess", 116 "BaseCheckVDM", 117 "BaseUpdateVDMEntry", 118 "BaseGetNextVDMCommand", 119 "BaseExitVDM", 120 "BaseIsFirstVDM", 121 "BaseGetVDMExitCode", 122 "BaseSetReenterCount", 123 "BaseSetProcessShutdownParam", 124 "BaseGetProcessShutdownParam", 125 "BaseNlsSetUserInfo", 126 "BaseNlsSetMultipleUserInfo", 127 "BaseNlsCreateSection", 128 "BaseSetVDMCurDirs", 129 "BaseGetVDMCurDirs", 130 "BaseBatNotification", 131 "BaseRegisterWowExec", 132 "BaseSoundSentryNotification", 133 "BaseRefreshIniFileMapping", 134 "BaseDefineDosDevice", 135 "BaseSetTermsrvAppInstallMode", 136 "BaseNlsUpdateCacheCount", 137 "BaseSetTermsrvClientTimeZone", 138 "BaseSxsCreateActivationContext", 139 "BaseUnknown", 140 "BaseRegisterThread", 141 "BaseNlsGetUserInfo", 142 }; 143 #endif 144 145 /* FUNCTIONS ******************************************************************/ 146 147 NTSTATUS 148 NTAPI 149 BaseSrvInitializeIniFileMappings(IN PBASE_STATIC_SERVER_DATA StaticServerData) 150 { 151 /* Allocate the mapping blob */ 152 BaseSrvIniFileMapping = RtlAllocateHeap(BaseSrvSharedHeap, 153 HEAP_ZERO_MEMORY, 154 sizeof(*BaseSrvIniFileMapping)); 155 if (BaseSrvIniFileMapping == NULL) 156 { 157 DPRINT1("BASESRV: Unable to allocate memory in shared heap for IniFileMapping\n"); 158 return STATUS_NO_MEMORY; 159 } 160 161 /* Set it*/ 162 StaticServerData->IniFileMapping = BaseSrvIniFileMapping; 163 164 /* FIXME: Do the work to initialize the mappings */ 165 return STATUS_SUCCESS; 166 } 167 168 NTSTATUS 169 NTAPI 170 CreateBaseAcls(OUT PACL* Dacl, 171 OUT PACL* RestrictedDacl) 172 { 173 PSID SystemSid, WorldSid, RestrictedSid; 174 SID_IDENTIFIER_AUTHORITY NtAuthority = {SECURITY_NT_AUTHORITY}; 175 SID_IDENTIFIER_AUTHORITY WorldAuthority = {SECURITY_WORLD_SID_AUTHORITY}; 176 NTSTATUS Status; 177 #if 0 // Unused code 178 UCHAR KeyValueBuffer[0x40]; 179 PKEY_VALUE_PARTIAL_INFORMATION KeyValuePartialInfo; 180 UNICODE_STRING KeyName; 181 ULONG ProtectionMode = 0; 182 #endif 183 ULONG AclLength; 184 #if 0 // Unused code 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 #endif 221 222 /* Allocate the System SID */ 223 Status = RtlAllocateAndInitializeSid(&NtAuthority, 224 1, SECURITY_LOCAL_SYSTEM_RID, 225 0, 0, 0, 0, 0, 0, 0, 226 &SystemSid); 227 ASSERT(NT_SUCCESS(Status)); 228 229 /* Allocate the World SID */ 230 Status = RtlAllocateAndInitializeSid(&WorldAuthority, 231 1, SECURITY_WORLD_RID, 232 0, 0, 0, 0, 0, 0, 0, 233 &WorldSid); 234 ASSERT(NT_SUCCESS(Status)); 235 236 /* Allocate the restricted SID */ 237 Status = RtlAllocateAndInitializeSid(&NtAuthority, 238 1, SECURITY_RESTRICTED_CODE_RID, 239 0, 0, 0, 0, 0, 0, 0, 240 &RestrictedSid); 241 ASSERT(NT_SUCCESS(Status)); 242 243 /* Allocate one ACL with 3 ACEs each for one SID */ 244 AclLength = sizeof(ACL) + 3 * sizeof(ACCESS_ALLOWED_ACE) + 245 RtlLengthSid(SystemSid) + 246 RtlLengthSid(WorldSid) + 247 RtlLengthSid(RestrictedSid); 248 *Dacl = RtlAllocateHeap(BaseSrvHeap, 0, AclLength); 249 ASSERT(*Dacl != NULL); 250 251 /* Set the correct header fields */ 252 Status = RtlCreateAcl(*Dacl, AclLength, ACL_REVISION2); 253 ASSERT(NT_SUCCESS(Status)); 254 255 /* Give the appropriate rights to each SID */ 256 /* FIXME: Should check SessionId/ProtectionMode */ 257 Status = RtlAddAccessAllowedAce(*Dacl, ACL_REVISION2, DIRECTORY_QUERY | DIRECTORY_TRAVERSE | DIRECTORY_CREATE_OBJECT | DIRECTORY_CREATE_SUBDIRECTORY | READ_CONTROL, WorldSid); 258 ASSERT(NT_SUCCESS(Status)); 259 Status = RtlAddAccessAllowedAce(*Dacl, ACL_REVISION2, DIRECTORY_ALL_ACCESS, SystemSid); 260 ASSERT(NT_SUCCESS(Status)); 261 Status = RtlAddAccessAllowedAce(*Dacl, ACL_REVISION2, DIRECTORY_TRAVERSE, RestrictedSid); 262 ASSERT(NT_SUCCESS(Status)); 263 264 /* Now allocate the restricted DACL */ 265 *RestrictedDacl = RtlAllocateHeap(BaseSrvHeap, 0, AclLength); 266 ASSERT(*RestrictedDacl != NULL); 267 268 /* Initialize it */ 269 Status = RtlCreateAcl(*RestrictedDacl, AclLength, ACL_REVISION2); 270 ASSERT(NT_SUCCESS(Status)); 271 272 /* And add the same ACEs as before */ 273 /* FIXME: Not really fully correct */ 274 Status = RtlAddAccessAllowedAce(*RestrictedDacl, ACL_REVISION2, DIRECTORY_QUERY | DIRECTORY_TRAVERSE | DIRECTORY_CREATE_OBJECT | DIRECTORY_CREATE_SUBDIRECTORY | READ_CONTROL, WorldSid); 275 ASSERT(NT_SUCCESS(Status)); 276 Status = RtlAddAccessAllowedAce(*RestrictedDacl, ACL_REVISION2, DIRECTORY_ALL_ACCESS, SystemSid); 277 ASSERT(NT_SUCCESS(Status)); 278 Status = RtlAddAccessAllowedAce(*RestrictedDacl, ACL_REVISION2, DIRECTORY_TRAVERSE, RestrictedSid); 279 ASSERT(NT_SUCCESS(Status)); 280 281 /* The SIDs are captured, can free them now */ 282 RtlFreeSid(RestrictedSid); 283 RtlFreeSid(WorldSid); 284 RtlFreeSid(SystemSid); 285 return Status; 286 } 287 288 VOID 289 NTAPI 290 BaseInitializeStaticServerData(IN PCSR_SERVER_DLL LoadedServerDll) 291 { 292 NTSTATUS Status; 293 BOOLEAN Success; 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 ULONG SessionId; 304 HANDLE BaseSrvNamedObjectDirectory; 305 HANDLE BaseSrvRestrictedObjectDirectory; 306 PACL BnoDacl, BnoRestrictedDacl; 307 PSECURITY_DESCRIPTOR BnoSd; 308 HANDLE SymHandle; 309 UNICODE_STRING DirectoryName, SymlinkName; 310 ULONG LuidEnabled; 311 RTL_QUERY_REGISTRY_TABLE BaseServerRegistryConfigurationTable[2] = 312 { 313 { 314 NULL, 315 RTL_QUERY_REGISTRY_DIRECT, 316 L"CSDVersion", 317 &BaseSrvCSDString, 318 REG_NONE, NULL, 0 319 }, 320 321 {0} 322 }; 323 324 /* Initialize the memory */ 325 BaseSrvHeap = RtlGetProcessHeap(); // Initialize our own heap. 326 BaseSrvSharedHeap = LoadedServerDll->SharedSection; // Get the CSR shared heap. 327 328 /* Get the session ID */ 329 SessionId = NtCurrentPeb()->SessionId; 330 331 /* Get the Windows directory */ 332 RtlInitEmptyUnicodeString(&SystemRootString, Buffer, sizeof(Buffer)); 333 Status = RtlExpandEnvironmentStrings_U(NULL, 334 &UnexpandedSystemRootString, 335 &SystemRootString, 336 NULL); 337 ASSERT(NT_SUCCESS(Status)); 338 339 /* Create the base directory */ 340 Buffer[SystemRootString.Length / sizeof(WCHAR)] = UNICODE_NULL; 341 Success = RtlCreateUnicodeString(&BaseSrvWindowsDirectory, 342 SystemRootString.Buffer); 343 ASSERT(Success); 344 345 /* Create the system directory */ 346 wcscat(SystemRootString.Buffer, L"\\System32"); 347 Success = RtlCreateUnicodeString(&BaseSrvWindowsSystemDirectory, 348 SystemRootString.Buffer); 349 ASSERT(Success); 350 351 /* Create the kernel32 path */ 352 wcscat(SystemRootString.Buffer, L"\\kernel32.dll"); 353 Success = RtlCreateUnicodeString(&BaseSrvKernel32DllPath, 354 SystemRootString.Buffer); 355 ASSERT(Success); 356 357 /* FIXME: Check Session ID */ 358 wcscpy(Buffer, L"\\BaseNamedObjects"); 359 RtlInitUnicodeString(&BnoString, Buffer); 360 361 /* Allocate the server data */ 362 BaseStaticServerData = RtlAllocateHeap(BaseSrvSharedHeap, 363 HEAP_ZERO_MEMORY, 364 sizeof(BASE_STATIC_SERVER_DATA)); 365 ASSERT(BaseStaticServerData != NULL); 366 367 /* Process timezone information */ 368 BaseStaticServerData->TermsrvClientTimeZoneId = TIME_ZONE_ID_INVALID; 369 BaseStaticServerData->TermsrvClientTimeZoneChangeNum = 0; 370 Status = NtQuerySystemInformation(SystemTimeOfDayInformation, 371 &BaseStaticServerData->TimeOfDay, 372 sizeof(BaseStaticServerData->TimeOfDay), 373 NULL); 374 ASSERT(NT_SUCCESS(Status)); 375 376 /* Make a shared heap copy of the Windows directory */ 377 BaseStaticServerData->WindowsDirectory = BaseSrvWindowsDirectory; 378 HeapBuffer = RtlAllocateHeap(BaseSrvSharedHeap, 379 0, 380 BaseSrvWindowsDirectory.MaximumLength); 381 ASSERT(HeapBuffer); 382 RtlCopyMemory(HeapBuffer, 383 BaseStaticServerData->WindowsDirectory.Buffer, 384 BaseSrvWindowsDirectory.MaximumLength); 385 BaseStaticServerData->WindowsDirectory.Buffer = HeapBuffer; 386 387 /* Make a shared heap copy of the System directory */ 388 BaseStaticServerData->WindowsSystemDirectory = BaseSrvWindowsSystemDirectory; 389 HeapBuffer = RtlAllocateHeap(BaseSrvSharedHeap, 390 0, 391 BaseSrvWindowsSystemDirectory.MaximumLength); 392 ASSERT(HeapBuffer); 393 RtlCopyMemory(HeapBuffer, 394 BaseStaticServerData->WindowsSystemDirectory.Buffer, 395 BaseSrvWindowsSystemDirectory.MaximumLength); 396 BaseStaticServerData->WindowsSystemDirectory.Buffer = HeapBuffer; 397 398 /* This string is not used */ 399 RtlInitEmptyUnicodeString(&BaseStaticServerData->WindowsSys32x86Directory, 400 NULL, 401 0); 402 403 /* Make a shared heap copy of the BNO directory */ 404 BaseStaticServerData->NamedObjectDirectory = BnoString; 405 BaseStaticServerData->NamedObjectDirectory.MaximumLength = BnoString.Length + 406 sizeof(UNICODE_NULL); 407 HeapBuffer = RtlAllocateHeap(BaseSrvSharedHeap, 408 0, 409 BaseStaticServerData->NamedObjectDirectory.MaximumLength); 410 ASSERT(HeapBuffer); 411 RtlCopyMemory(HeapBuffer, 412 BaseStaticServerData->NamedObjectDirectory.Buffer, 413 BaseStaticServerData->NamedObjectDirectory.MaximumLength); 414 BaseStaticServerData->NamedObjectDirectory.Buffer = HeapBuffer; 415 416 /* 417 * Confirmed that in Windows, CSDNumber and RCNumber are actually Length 418 * and MaximumLength of the CSD String, since the same UNICODE_STRING is 419 * being queried twice, the first time as a ULONG! 420 * 421 * Somehow, in Windows this doesn't cause a buffer overflow, but it might 422 * in ReactOS, so this code is disabled until someone figures out WTF. 423 */ 424 BaseStaticServerData->CSDNumber = 0; 425 BaseStaticServerData->RCNumber = 0; 426 427 /* Initialize the CSD string and query its value from the registry */ 428 RtlInitEmptyUnicodeString(&BaseSrvCSDString, Buffer, sizeof(Buffer)); 429 Status = RtlQueryRegistryValues(RTL_REGISTRY_WINDOWS_NT, 430 L"", 431 BaseServerRegistryConfigurationTable, 432 NULL, 433 NULL); 434 if (NT_SUCCESS(Status)) 435 { 436 /* Copy into the shared buffer */ 437 wcsncpy(BaseStaticServerData->CSDVersion, 438 BaseSrvCSDString.Buffer, 439 BaseSrvCSDString.Length / sizeof(WCHAR)); 440 } 441 else 442 { 443 /* NULL-terminate to indicate nothing is there */ 444 BaseStaticServerData->CSDVersion[0] = UNICODE_NULL; 445 } 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 VOID 574 NTAPI 575 BaseSrvDisconnect(PCSR_PROCESS Process) 576 { 577 /* Cleanup the VDM console records */ 578 BaseSrvCleanupVdmRecords(HandleToUlong(Process->ClientId.UniqueProcess)); 579 } 580 581 CSR_SERVER_DLL_INIT(ServerDllInitialization) 582 { 583 /* Setup the DLL Object */ 584 LoadedServerDll->ApiBase = BASESRV_FIRST_API_NUMBER; 585 LoadedServerDll->HighestApiSupported = BasepMaxApiNumber; 586 LoadedServerDll->DispatchTable = BaseServerApiDispatchTable; 587 LoadedServerDll->ValidTable = BaseServerApiServerValidTable; 588 #ifdef CSR_DBG 589 LoadedServerDll->NameTable = BaseServerApiNameTable; 590 #endif 591 LoadedServerDll->SizeOfProcessData = 0; 592 LoadedServerDll->ConnectCallback = NULL; 593 LoadedServerDll->DisconnectCallback = BaseSrvDisconnect; 594 LoadedServerDll->ShutdownProcessCallback = NULL; 595 596 BaseSrvDllInstance = LoadedServerDll->ServerHandle; 597 598 BaseInitializeStaticServerData(LoadedServerDll); 599 600 /* Initialize DOS devices management */ 601 BaseInitDefineDosDevice(); 602 603 /* Initialize VDM support */ 604 BaseInitializeVDM(); 605 606 /* All done */ 607 return STATUS_SUCCESS; 608 } 609 610 BOOL 611 NTAPI 612 DllMain(IN HINSTANCE hInstanceDll, 613 IN DWORD dwReason, 614 IN LPVOID lpReserved) 615 { 616 UNREFERENCED_PARAMETER(hInstanceDll); 617 UNREFERENCED_PARAMETER(dwReason); 618 UNREFERENCED_PARAMETER(lpReserved); 619 620 if (DLL_PROCESS_DETACH == dwReason) 621 { 622 BaseCleanupDefineDosDevice(); 623 } 624 625 return TRUE; 626 } 627 628 /* EOF */ 629