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