Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygeninit.c
Go to the documentation of this file.
00001 /* 00002 * COPYRIGHT: See COPYING in the top level directory 00003 * PROJECT: ReactOS CSR Sub System 00004 * FILE: subsystems/win32/csrss/csrsrv/init.c 00005 * PURPOSE: CSR Server DLL Initialization 00006 * PROGRAMMERS: ReactOS Portable Systems Group 00007 */ 00008 00009 /* INCLUDES *******************************************************************/ 00010 00011 #include "srv.h" 00012 #define NDEBUG 00013 #include <debug.h> 00014 00015 /* DATA ***********************************************************************/ 00016 00017 HANDLE CsrHeap = (HANDLE) 0; 00018 HANDLE CsrObjectDirectory = (HANDLE) 0; 00019 UNICODE_STRING CsrDirectoryName; 00020 UNICODE_STRING CsrSbApiPortName; 00021 HANDLE CsrSbApiPort = 0; 00022 PCSR_THREAD CsrSbApiRequestThreadPtr; 00023 HANDLE CsrSmApiPort; 00024 HANDLE hSbApiPort = (HANDLE) 0; 00025 HANDLE CsrApiPort = (HANDLE) 0; 00026 ULONG CsrDebug = 0;//0xFFFFFFFF; 00027 ULONG CsrMaxApiRequestThreads; 00028 ULONG CsrTotalPerProcessDataLength; 00029 ULONG SessionId; 00030 HANDLE BNOLinksDirectory; 00031 HANDLE SessionObjectDirectory; 00032 HANDLE DosDevicesDirectory; 00033 HANDLE CsrInitializationEvent; 00034 SYSTEM_BASIC_INFORMATION CsrNtSysInfo; 00035 00036 /* PRIVATE FUNCTIONS **********************************************************/ 00037 00038 VOID 00039 CallHardError(IN PCSR_THREAD ThreadData, 00040 IN PHARDERROR_MSG HardErrorMessage) 00041 { 00042 unsigned i; 00043 PCSR_SERVER_DLL ServerDll; 00044 00045 DPRINT("CSR: %s called\n", __FUNCTION__); 00046 00047 /* Notify the Server DLLs */ 00048 for (i = 0; i < CSR_SERVER_DLL_MAX; i++) 00049 { 00050 /* Get the current Server DLL */ 00051 ServerDll = CsrLoadedServerDll[i]; 00052 00053 /* Make sure it's valid and that it has callback */ 00054 if ((ServerDll) && (ServerDll->HardErrorCallback)) 00055 { 00056 ServerDll->HardErrorCallback(ThreadData, HardErrorMessage); 00057 } 00058 } 00059 } 00060 00061 NTSTATUS 00062 CallProcessCreated(IN PCSR_PROCESS SourceProcessData, 00063 IN PCSR_PROCESS TargetProcessData) 00064 { 00065 NTSTATUS Status = STATUS_SUCCESS; 00066 unsigned i; 00067 PCSR_SERVER_DLL ServerDll; 00068 00069 DPRINT("CSR: %s called\n", __FUNCTION__); 00070 00071 /* Notify the Server DLLs */ 00072 for (i = 0; i < CSR_SERVER_DLL_MAX; i++) 00073 { 00074 /* Get the current Server DLL */ 00075 ServerDll = CsrLoadedServerDll[i]; 00076 00077 /* Make sure it's valid and that it has callback */ 00078 if ((ServerDll) && (ServerDll->NewProcessCallback)) 00079 { 00080 Status = ServerDll->NewProcessCallback(SourceProcessData, TargetProcessData); 00081 } 00082 } 00083 00084 return Status; 00085 } 00086 00087 CSRSS_API_DEFINITION NativeDefinitions[] = 00088 { 00089 CSRSS_DEFINE_API(CREATE_PROCESS, CsrSrvCreateProcess), 00090 CSRSS_DEFINE_API(CREATE_THREAD, CsrSrvCreateThread), 00091 CSRSS_DEFINE_API(TERMINATE_PROCESS, CsrTerminateProcess), 00092 CSRSS_DEFINE_API(CONNECT_PROCESS, CsrConnectProcess), 00093 CSRSS_DEFINE_API(REGISTER_SERVICES_PROCESS, CsrRegisterServicesProcess), 00094 CSRSS_DEFINE_API(GET_SHUTDOWN_PARAMETERS, CsrGetShutdownParameters), 00095 CSRSS_DEFINE_API(SET_SHUTDOWN_PARAMETERS, CsrSetShutdownParameters), 00096 { 0, 0, NULL } 00097 }; 00098 00099 /* === INIT ROUTINES === */ 00100 00101 VOID 00102 WINAPI 00103 BasepFakeStaticServerData(VOID); 00104 00105 /*++ 00106 * @name CsrSetProcessSecurity 00107 * 00108 * The CsrSetProcessSecurity routine protects access to the CSRSS process 00109 * from unauthorized tampering. 00110 * 00111 * @param None. 00112 * 00113 * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL 00114 * othwerwise. 00115 * 00116 * @remarks None. 00117 * 00118 *--*/ 00119 NTSTATUS 00120 NTAPI 00121 CsrSetProcessSecurity(VOID) 00122 { 00123 NTSTATUS Status; 00124 HANDLE hToken, hProcess = NtCurrentProcess(); 00125 ULONG Length; 00126 PTOKEN_USER TokenInfo = NULL; 00127 PSECURITY_DESCRIPTOR ProcSd = NULL; 00128 PACL Dacl; 00129 PSID UserSid; 00130 00131 /* Open our token */ 00132 Status = NtOpenProcessToken(hProcess, TOKEN_QUERY, &hToken); 00133 if (!NT_SUCCESS(Status)) goto Quickie; 00134 00135 /* Get the Token User Length */ 00136 NtQueryInformationToken(hToken, TokenUser, NULL, 0, &Length); 00137 00138 /* Allocate space for it */ 00139 TokenInfo = RtlAllocateHeap(CsrHeap, HEAP_ZERO_MEMORY, Length); 00140 if (!TokenInfo) 00141 { 00142 Status = STATUS_NO_MEMORY; 00143 goto Quickie; 00144 } 00145 00146 /* Now query the data */ 00147 Status = NtQueryInformationToken(hToken, TokenUser, TokenInfo, Length, &Length); 00148 NtClose(hToken); 00149 if (!NT_SUCCESS(Status)) goto Quickie; 00150 00151 /* Now check the SID Length */ 00152 UserSid = TokenInfo->User.Sid; 00153 Length = RtlLengthSid(UserSid) + sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE); 00154 00155 /* Allocate a buffer for the Security Descriptor, with SID and DACL */ 00156 ProcSd = RtlAllocateHeap(CsrHeap, HEAP_ZERO_MEMORY, SECURITY_DESCRIPTOR_MIN_LENGTH + Length); 00157 if (!ProcSd) 00158 { 00159 Status = STATUS_NO_MEMORY; 00160 goto Quickie; 00161 } 00162 00163 /* Set the pointer to the DACL */ 00164 Dacl = (PACL)((ULONG_PTR)ProcSd + SECURITY_DESCRIPTOR_MIN_LENGTH); 00165 00166 /* Now create the SD itself */ 00167 Status = RtlCreateSecurityDescriptor(ProcSd, SECURITY_DESCRIPTOR_REVISION); 00168 if (!NT_SUCCESS(Status)) 00169 { 00170 DPRINT1("CSRSS: SD creation failed - status = %lx\n", Status); 00171 goto Quickie; 00172 } 00173 00174 /* Create the DACL for it*/ 00175 Status = RtlCreateAcl(Dacl, Length, ACL_REVISION2); 00176 if (!NT_SUCCESS(Status)) 00177 { 00178 DPRINT1("CSRSS: DACL creation failed - status = %lx\n", Status); 00179 goto Quickie; 00180 } 00181 00182 /* Create the ACE */ 00183 Status = RtlAddAccessAllowedAce(Dacl, 00184 ACL_REVISION, 00185 PROCESS_VM_READ | PROCESS_VM_WRITE | 00186 PROCESS_VM_OPERATION | PROCESS_DUP_HANDLE | 00187 PROCESS_TERMINATE | PROCESS_SUSPEND_RESUME | 00188 PROCESS_QUERY_INFORMATION | READ_CONTROL, 00189 UserSid); 00190 if (!NT_SUCCESS(Status)) 00191 { 00192 DPRINT1("CSRSS: ACE creation failed - status = %lx\n", Status); 00193 goto Quickie; 00194 } 00195 00196 /* Clear the DACL in the SD */ 00197 Status = RtlSetDaclSecurityDescriptor(ProcSd, TRUE, Dacl, FALSE); 00198 if (!NT_SUCCESS(Status)) 00199 { 00200 DPRINT1("CSRSS: set DACL failed - status = %lx\n", Status); 00201 goto Quickie; 00202 } 00203 00204 /* Write the SD into the Process */ 00205 Status = NtSetSecurityObject(hProcess, DACL_SECURITY_INFORMATION, ProcSd); 00206 if (!NT_SUCCESS(Status)) 00207 { 00208 DPRINT1("CSRSS: set process DACL failed - status = %lx\n", Status); 00209 goto Quickie; 00210 } 00211 00212 /* Free the memory and return */ 00213 Quickie: 00214 if (ProcSd) RtlFreeHeap(CsrHeap, 0, ProcSd); 00215 RtlFreeHeap(CsrHeap, 0, TokenInfo); 00216 return Status; 00217 } 00218 00219 /*++ 00220 * @name CsrSetDirectorySecurity 00221 * 00222 * The CsrSetDirectorySecurity routine sets the security descriptor for the 00223 * specified Object Directory. 00224 * 00225 * @param ObjectDirectory 00226 * Handle fo the Object Directory to protect. 00227 * 00228 * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL 00229 * othwerwise. 00230 * 00231 * @remarks None. 00232 * 00233 *--*/ 00234 NTSTATUS 00235 NTAPI 00236 CsrSetDirectorySecurity(IN HANDLE ObjectDirectory) 00237 { 00238 /* FIXME: Implement */ 00239 return STATUS_SUCCESS; 00240 } 00241 00242 /*++ 00243 * @name GetDosDevicesProtection 00244 * 00245 * The GetDosDevicesProtection creates a security descriptor for the DOS Devices 00246 * Object Directory. 00247 * 00248 * @param DosDevicesSd 00249 * Pointer to the Security Descriptor to return. 00250 * 00251 * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL 00252 * othwerwise. 00253 * 00254 * @remarks Depending on the DOS Devices Protection Mode (set in the registry), 00255 * regular users may or may not have full access to the directory. 00256 * 00257 *--*/ 00258 NTSTATUS 00259 NTAPI 00260 GetDosDevicesProtection(OUT PSECURITY_DESCRIPTOR DosDevicesSd) 00261 { 00262 SID_IDENTIFIER_AUTHORITY WorldAuthority = {SECURITY_WORLD_SID_AUTHORITY}; 00263 SID_IDENTIFIER_AUTHORITY CreatorAuthority = {SECURITY_CREATOR_SID_AUTHORITY}; 00264 SID_IDENTIFIER_AUTHORITY NtSidAuthority = {SECURITY_NT_AUTHORITY}; 00265 PSID WorldSid, CreatorSid, AdminSid, SystemSid; 00266 UCHAR KeyValueBuffer[0x40]; 00267 PKEY_VALUE_PARTIAL_INFORMATION KeyValuePartialInfo; 00268 UNICODE_STRING KeyName; 00269 ULONG ProtectionMode = 0; 00270 OBJECT_ATTRIBUTES ObjectAttributes; 00271 PACL Dacl; 00272 PACCESS_ALLOWED_ACE Ace; 00273 HANDLE hKey; 00274 NTSTATUS Status; 00275 ULONG ResultLength, SidLength, AclLength; 00276 00277 /* Create the SD */ 00278 Status = RtlCreateSecurityDescriptor(DosDevicesSd, SECURITY_DESCRIPTOR_REVISION); 00279 ASSERT(NT_SUCCESS(Status)); 00280 00281 /* Initialize the System SID */ 00282 Status = RtlAllocateAndInitializeSid(&NtSidAuthority, 1, 00283 SECURITY_LOCAL_SYSTEM_RID, 00284 0, 0, 0, 0, 0, 0, 0, 00285 &SystemSid); 00286 ASSERT(NT_SUCCESS(Status)); 00287 00288 /* Initialize the World SID */ 00289 Status = RtlAllocateAndInitializeSid(&WorldAuthority, 1, 00290 SECURITY_WORLD_RID, 00291 0, 0, 0, 0, 0, 0, 0, 00292 &WorldSid); 00293 ASSERT(NT_SUCCESS(Status)); 00294 00295 /* Initialize the Admin SID */ 00296 Status = RtlAllocateAndInitializeSid(&NtSidAuthority, 2, 00297 SECURITY_BUILTIN_DOMAIN_RID, 00298 DOMAIN_ALIAS_RID_ADMINS, 00299 0, 0, 0, 0, 0, 0, 00300 &AdminSid); 00301 ASSERT(NT_SUCCESS(Status)); 00302 00303 /* Initialize the Creator SID */ 00304 Status = RtlAllocateAndInitializeSid(&CreatorAuthority, 1, 00305 SECURITY_CREATOR_OWNER_RID, 00306 0, 0, 0, 0, 0, 0, 0, 00307 &CreatorSid); 00308 ASSERT(NT_SUCCESS(Status)); 00309 00310 /* Open the Session Manager Key */ 00311 RtlInitUnicodeString(&KeyName, SM_REG_KEY); 00312 InitializeObjectAttributes(&ObjectAttributes, 00313 &KeyName, 00314 OBJ_CASE_INSENSITIVE, 00315 NULL, 00316 NULL); 00317 Status = NtOpenKey(&hKey, KEY_READ, &ObjectAttributes); 00318 if (NT_SUCCESS(Status)) 00319 { 00320 /* Read the key value */ 00321 RtlInitUnicodeString(&KeyName, L"ProtectionMode"); 00322 Status = NtQueryValueKey(hKey, 00323 &KeyName, 00324 KeyValuePartialInformation, 00325 KeyValueBuffer, 00326 sizeof(KeyValueBuffer), 00327 &ResultLength); 00328 00329 /* Make sure it's what we expect it to be */ 00330 KeyValuePartialInfo = (PKEY_VALUE_PARTIAL_INFORMATION)KeyValueBuffer; 00331 if ((NT_SUCCESS(Status)) && (KeyValuePartialInfo->Type == REG_DWORD) && 00332 (*(PULONG)KeyValuePartialInfo->Data)) 00333 { 00334 /* Save the Protection Mode */ 00335 ProtectionMode = *(PULONG)KeyValuePartialInfo->Data; 00336 } 00337 00338 /* Close the handle */ 00339 NtClose(hKey); 00340 } 00341 00342 /* Check the Protection Mode */ 00343 if (ProtectionMode & 3) 00344 { 00345 /* Calculate SID Lengths */ 00346 SidLength = RtlLengthSid(CreatorSid) + RtlLengthSid(SystemSid) + 00347 RtlLengthSid(AdminSid); 00348 AclLength = sizeof(ACL) + 3 * sizeof(ACCESS_ALLOWED_ACE) + SidLength; 00349 00350 /* Allocate memory for the DACL */ 00351 Dacl = RtlAllocateHeap(CsrHeap, HEAP_ZERO_MEMORY, AclLength); 00352 ASSERT(Dacl != NULL); 00353 00354 /* Build the ACL and add 3 ACEs */ 00355 Status = RtlCreateAcl(Dacl, AclLength, ACL_REVISION2); 00356 ASSERT(NT_SUCCESS(Status)); 00357 Status = RtlAddAccessAllowedAce(Dacl, ACL_REVISION, GENERIC_ALL, SystemSid); 00358 ASSERT(NT_SUCCESS(Status)); 00359 Status = RtlAddAccessAllowedAce(Dacl, ACL_REVISION, GENERIC_ALL, AdminSid); 00360 ASSERT(NT_SUCCESS(Status)); 00361 Status = RtlAddAccessAllowedAce(Dacl, ACL_REVISION, GENERIC_ALL, CreatorSid); 00362 ASSERT(NT_SUCCESS(Status)); 00363 00364 /* Edit the ACEs to make them inheritable */ 00365 Status = RtlGetAce(Dacl, 0, (PVOID*)&Ace); 00366 ASSERT(NT_SUCCESS(Status)); 00367 Ace->Header.AceFlags |= OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE; 00368 Status = RtlGetAce(Dacl, 1, (PVOID*)&Ace); 00369 ASSERT(NT_SUCCESS(Status)); 00370 Ace->Header.AceFlags |= OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE; 00371 Status = RtlGetAce(Dacl, 2, (PVOID*)&Ace); 00372 ASSERT(NT_SUCCESS(Status)); 00373 Ace->Header.AceFlags |= OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE | INHERIT_ONLY_ACE; 00374 00375 /* Set this DACL with the SD */ 00376 Status = RtlSetDaclSecurityDescriptor(DosDevicesSd, TRUE, Dacl, FALSE); 00377 ASSERT(NT_SUCCESS(Status)); 00378 goto Quickie; 00379 } 00380 else 00381 { 00382 /* Calculate SID Lengths */ 00383 SidLength = RtlLengthSid(WorldSid) + RtlLengthSid(SystemSid); 00384 AclLength = sizeof(ACL) + 3 * sizeof(ACCESS_ALLOWED_ACE) + SidLength; 00385 00386 /* Allocate memory for the DACL */ 00387 Dacl = RtlAllocateHeap(CsrHeap, HEAP_ZERO_MEMORY, AclLength); 00388 ASSERT(Dacl != NULL); 00389 00390 /* Build the ACL and add 3 ACEs */ 00391 Status = RtlCreateAcl(Dacl, AclLength, ACL_REVISION2); 00392 ASSERT(NT_SUCCESS(Status)); 00393 Status = RtlAddAccessAllowedAce(Dacl, ACL_REVISION, GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE, WorldSid); 00394 ASSERT(NT_SUCCESS(Status)); 00395 Status = RtlAddAccessAllowedAce(Dacl, ACL_REVISION, GENERIC_ALL, SystemSid); 00396 ASSERT(NT_SUCCESS(Status)); 00397 Status = RtlAddAccessAllowedAce(Dacl, ACL_REVISION, GENERIC_ALL, WorldSid); 00398 ASSERT(NT_SUCCESS(Status)); 00399 00400 /* Edit the last ACE to make it inheritable */ 00401 Status = RtlGetAce(Dacl, 2, (PVOID*)&Ace); 00402 ASSERT(NT_SUCCESS(Status)); 00403 Ace->Header.AceFlags |= OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE | INHERIT_ONLY_ACE; 00404 00405 /* Set this DACL with the SD */ 00406 Status = RtlSetDaclSecurityDescriptor(DosDevicesSd, TRUE, Dacl, FALSE); 00407 ASSERT(NT_SUCCESS(Status)); 00408 goto Quickie; 00409 } 00410 00411 /* FIXME: failure cases! Fail: */ 00412 /* Free the memory */ 00413 RtlFreeHeap(CsrHeap, 0, Dacl); 00414 00415 /* FIXME: semi-failure cases! Quickie: */ 00416 Quickie: 00417 /* Free the SIDs */ 00418 RtlFreeSid(SystemSid); 00419 RtlFreeSid(WorldSid); 00420 RtlFreeSid(AdminSid); 00421 RtlFreeSid(CreatorSid); 00422 00423 /* Return */ 00424 return Status; 00425 } 00426 00427 /*++ 00428 * @name FreeDosDevicesProtection 00429 * 00430 * The FreeDosDevicesProtection frees the security descriptor that was created 00431 * by GetDosDevicesProtection 00432 * 00433 * @param DosDevicesSd 00434 * Pointer to the security descriptor to free. 00435 00436 * @return None. 00437 * 00438 * @remarks None. 00439 * 00440 *--*/ 00441 VOID 00442 NTAPI 00443 FreeDosDevicesProtection(IN PSECURITY_DESCRIPTOR DosDevicesSd) 00444 { 00445 PACL Dacl; 00446 BOOLEAN Present, Default; 00447 NTSTATUS Status; 00448 00449 /* Get the DACL corresponding to this SD */ 00450 Status = RtlGetDaclSecurityDescriptor(DosDevicesSd, &Present, &Dacl, &Default); 00451 ASSERT(NT_SUCCESS(Status)); 00452 ASSERT(Present); 00453 ASSERT(Dacl != NULL); 00454 00455 /* Free it */ 00456 if ((NT_SUCCESS(Status)) && (Dacl)) RtlFreeHeap(CsrHeap, 0, Dacl); 00457 } 00458 00459 /*++ 00460 * @name CsrCreateSessionObjectDirectory 00461 * 00462 * The CsrCreateSessionObjectDirectory routine creates the BaseNamedObjects, 00463 * Session and Dos Devices directories for the specified session. 00464 * 00465 * @param Session 00466 * Session ID for which to create the directories. 00467 * 00468 * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL 00469 * othwerwise. 00470 * 00471 * @remarks None. 00472 * 00473 *--*/ 00474 NTSTATUS 00475 NTAPI 00476 CsrCreateSessionObjectDirectory(IN ULONG Session) 00477 { 00478 WCHAR SessionBuffer[512], BnoBuffer[512]; 00479 UNICODE_STRING SessionString, BnoString; 00480 OBJECT_ATTRIBUTES ObjectAttributes; 00481 HANDLE BnoHandle; 00482 SECURITY_DESCRIPTOR DosDevicesSd; 00483 NTSTATUS Status; 00484 00485 /* Generate the Session BNOLINKS Directory name */ 00486 swprintf(SessionBuffer, L"%ws\\BNOLINKS", SESSION_ROOT); 00487 RtlInitUnicodeString(&SessionString, SessionBuffer); 00488 00489 /* Create it */ 00490 InitializeObjectAttributes(&ObjectAttributes, 00491 &SessionString, 00492 OBJ_OPENIF | OBJ_CASE_INSENSITIVE, 00493 NULL, 00494 NULL); 00495 Status = NtCreateDirectoryObject(&BNOLinksDirectory, 00496 DIRECTORY_ALL_ACCESS, 00497 &ObjectAttributes); 00498 if (!NT_SUCCESS(Status)) 00499 { 00500 DPRINT1("CSRSS: NtCreateDirectoryObject failed in " 00501 "CsrCreateSessionObjectDirectory - status = %lx\n", Status); 00502 return Status; 00503 } 00504 00505 /* Now add the Session ID */ 00506 swprintf(SessionBuffer, L"%ld", Session); 00507 RtlInitUnicodeString(&SessionString, SessionBuffer); 00508 00509 /* Check if this is the first Session */ 00510 if (Session) 00511 { 00512 /* Not the first, so the name will be slighly more complex */ 00513 swprintf(BnoBuffer, L"%ws\\%ld\\BaseNamedObjects", SESSION_ROOT, Session); 00514 RtlInitUnicodeString(&BnoString, BnoBuffer); 00515 } 00516 else 00517 { 00518 /* Use the direct name */ 00519 RtlInitUnicodeString(&BnoString, L"\\BaseNamedObjects"); 00520 } 00521 00522 /* Create the symlink */ 00523 InitializeObjectAttributes(&ObjectAttributes, 00524 &SessionString, 00525 OBJ_OPENIF | OBJ_CASE_INSENSITIVE, 00526 BNOLinksDirectory, 00527 NULL); 00528 Status = NtCreateSymbolicLinkObject(&BnoHandle, 00529 SYMBOLIC_LINK_ALL_ACCESS, 00530 &ObjectAttributes, 00531 &BnoString); 00532 if (!NT_SUCCESS(Status)) 00533 { 00534 DPRINT1("CSRSS: NtCreateSymbolicLinkObject failed in " 00535 "CsrCreateSessionObjectDirectory - status = %lx\n", Status); 00536 return Status; 00537 } 00538 00539 /* Create the \DosDevices Security Descriptor */ 00540 Status = GetDosDevicesProtection(&DosDevicesSd); 00541 if (!NT_SUCCESS(Status)) return Status; 00542 00543 /* Now create a directory for this session */ 00544 swprintf(SessionBuffer, L"%ws\\%ld", SESSION_ROOT, Session); 00545 RtlInitUnicodeString(&SessionString, SessionBuffer); 00546 00547 /* Create the directory */ 00548 InitializeObjectAttributes(&ObjectAttributes, 00549 &SessionString, 00550 OBJ_OPENIF | OBJ_CASE_INSENSITIVE, 00551 0, 00552 &DosDevicesSd); 00553 Status = NtCreateDirectoryObject(&SessionObjectDirectory, 00554 DIRECTORY_ALL_ACCESS, 00555 &ObjectAttributes); 00556 if (!NT_SUCCESS(Status)) 00557 { 00558 DPRINT1("CSRSS: NtCreateDirectoryObject failed in " 00559 "CsrCreateSessionObjectDirectory - status = %lx\n", Status); 00560 FreeDosDevicesProtection(&DosDevicesSd); 00561 return Status; 00562 } 00563 00564 /* Next, create a directory for this session's DOS Devices */ 00565 RtlInitUnicodeString(&SessionString, L"DosDevices"); 00566 InitializeObjectAttributes(&ObjectAttributes, 00567 &SessionString, 00568 OBJ_CASE_INSENSITIVE, 00569 SessionObjectDirectory, 00570 &DosDevicesSd); 00571 Status = NtCreateDirectoryObject(&DosDevicesDirectory, 00572 DIRECTORY_ALL_ACCESS, 00573 &ObjectAttributes); 00574 if (!NT_SUCCESS(Status)) 00575 { 00576 DPRINT1("CSRSS: NtCreateDirectoryObject failed in " 00577 "CsrCreateSessionObjectDirectory - status = %lx\n", Status); 00578 } 00579 00580 /* Release the Security Descriptor */ 00581 FreeDosDevicesProtection(&DosDevicesSd); 00582 00583 /* Return */ 00584 return Status; 00585 } 00586 00587 /*++ 00588 * @name CsrParseServerCommandLine 00589 * 00590 * The CsrParseServerCommandLine routine parses the CSRSS command-line in the 00591 * registry and performs operations for each entry found. 00592 * 00593 * @param ArgumentCount 00594 * Number of arguments on the command line. 00595 * 00596 * @param Arguments 00597 * Array of arguments. 00598 * 00599 * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL 00600 * othwerwise. 00601 * 00602 * @remarks None. 00603 * 00604 *--*/ 00605 NTSTATUS 00606 FASTCALL 00607 CsrParseServerCommandLine(IN ULONG ArgumentCount, 00608 IN PCHAR Arguments[]) 00609 { 00610 NTSTATUS Status; 00611 PCHAR ParameterName = NULL, ParameterValue = NULL, EntryPoint, ServerString; 00612 ULONG i, DllIndex; 00613 ANSI_STRING AnsiString; 00614 OBJECT_ATTRIBUTES ObjectAttributes; 00615 00616 /* Set the Defaults */ 00617 CsrTotalPerProcessDataLength = 0; 00618 CsrObjectDirectory = NULL; 00619 CsrMaxApiRequestThreads = 16; 00620 00621 /* Save our Session ID, and create a Directory for it */ 00622 SessionId = NtCurrentPeb()->SessionId; 00623 Status = CsrCreateSessionObjectDirectory(SessionId); 00624 if (!NT_SUCCESS(Status)) 00625 { 00626 DPRINT1("CSRSS: CsrCreateSessionObjectDirectory failed (%lx)\n", 00627 Status); 00628 00629 /* It's not fatal if the session ID isn't zero */ 00630 if (SessionId) return Status; 00631 ASSERT(NT_SUCCESS(Status)); 00632 } 00633 00634 /* Loop through every argument */ 00635 for (i = 1; i < ArgumentCount; i++) 00636 { 00637 /* Split Name and Value */ 00638 ParameterName = Arguments[i]; 00639 ParameterValue = NULL; 00640 ParameterValue = strchr(ParameterName, '='); 00641 if (ParameterValue) *ParameterValue++ = ANSI_NULL; 00642 00643 /* Check for Object Directory */ 00644 if (!_stricmp(ParameterName, "ObjectDirectory")) 00645 { 00646 /* Check if a session ID is specified */ 00647 if (SessionId) 00648 { 00649 DPRINT1("Sessions not yet implemented\n"); 00650 ASSERT(SessionId); 00651 } 00652 00653 /* Initialize the directory name */ 00654 RtlInitAnsiString(&AnsiString, ParameterValue); 00655 Status = RtlAnsiStringToUnicodeString(&CsrDirectoryName, 00656 &AnsiString, 00657 TRUE); 00658 ASSERT(NT_SUCCESS(Status) || SessionId != 0); 00659 if (!NT_SUCCESS(Status)) return Status; 00660 00661 /* Create it */ 00662 InitializeObjectAttributes(&ObjectAttributes, 00663 &CsrDirectoryName, 00664 OBJ_OPENIF | OBJ_CASE_INSENSITIVE | OBJ_PERMANENT, 00665 NULL, 00666 NULL); 00667 Status = NtCreateDirectoryObject(&CsrObjectDirectory, 00668 DIRECTORY_ALL_ACCESS, 00669 &ObjectAttributes); 00670 if (!NT_SUCCESS(Status)) return Status; 00671 00672 /* Secure it */ 00673 Status = CsrSetDirectorySecurity(CsrObjectDirectory); 00674 if (!NT_SUCCESS(Status)) return Status; 00675 } 00676 else if (!_stricmp(ParameterName, "SubSystemType")) 00677 { 00678 /* Ignored */ 00679 } 00680 else if (!_stricmp(ParameterName, "MaxRequestThreads")) 00681 { 00682 Status = RtlCharToInteger(ParameterValue, 00683 0, 00684 &CsrMaxApiRequestThreads); 00685 } 00686 else if (!_stricmp(ParameterName, "RequestThreads")) 00687 { 00688 /* Ignored */ 00689 Status = STATUS_SUCCESS; 00690 } 00691 else if (!_stricmp(ParameterName, "ProfileControl")) 00692 { 00693 /* Ignored */ 00694 } 00695 else if (!_stricmp(ParameterName, "SharedSection")) 00696 { 00697 /* Create the Section */ 00698 Status = CsrSrvCreateSharedSection(ParameterValue); 00699 if (!NT_SUCCESS(Status)) 00700 { 00701 DPRINT1("CSRSS: *** Invalid syntax for %s=%s (Status == %X)\n", 00702 ParameterName, ParameterValue, Status); 00703 return Status; 00704 } 00705 00706 /* Load us */ 00707 Status = CsrLoadServerDll("CSRSS", NULL, CSR_SRV_SERVER); 00708 } 00709 else if (!_stricmp(ParameterName, "ServerDLL")) 00710 { 00711 /* Loop the command line */ 00712 EntryPoint = NULL; 00713 Status = STATUS_INVALID_PARAMETER; 00714 ServerString = ParameterValue; 00715 while (*ServerString) 00716 { 00717 /* Check for the Entry Point */ 00718 if ((*ServerString == ':') && (!EntryPoint)) 00719 { 00720 /* Found it. Add a nullchar and save it */ 00721 *ServerString++ = ANSI_NULL; 00722 EntryPoint = ServerString; 00723 } 00724 00725 /* Check for the Dll Index */ 00726 if (*ServerString++ == ',') break; 00727 } 00728 00729 /* Did we find something to load? */ 00730 if (!*ServerString) 00731 { 00732 DPRINT1("CSRSS: *** Invalid syntax for ServerDll=%s (Status == %X)\n", 00733 ParameterValue, Status); 00734 return Status; 00735 } 00736 00737 /* Convert it to a ULONG */ 00738 Status = RtlCharToInteger(ServerString, 10, &DllIndex); 00739 00740 /* Add a null char if it was valid */ 00741 if (NT_SUCCESS(Status)) ServerString[-1] = ANSI_NULL; 00742 00743 /* Load it */ 00744 if (CsrDebug & 1) DPRINT1("CSRSS: Loading ServerDll=%s:%s\n", ParameterValue, EntryPoint); 00745 00746 /* Hackito ergo sum */ 00747 Status = STATUS_SUCCESS; 00748 if (strstr(ParameterValue, "basesrv")) 00749 { 00750 DPRINT1("Fake basesrv init\n"); 00751 BasepFakeStaticServerData(); 00752 } 00753 // else 00754 // { 00755 // Status = CsrLoadServerDll(ParameterValue, EntryPoint, 2); 00756 // } 00757 if (!NT_SUCCESS(Status)) 00758 { 00759 DPRINT1("CSRSS: *** Failed loading ServerDll=%s (Status == 0x%x)\n", 00760 ParameterValue, Status); 00761 return Status; 00762 } 00763 } 00764 else if (!_stricmp(ParameterName, "Windows")) 00765 { 00766 /* Ignored */ 00767 } 00768 else 00769 { 00770 /* Invalid parameter on the command line */ 00771 Status = STATUS_INVALID_PARAMETER; 00772 } 00773 } 00774 00775 /* Return status */ 00776 return Status; 00777 } 00778 00779 /*++ 00780 * @name CsrCreateLocalSystemSD 00781 * 00782 * The CsrCreateLocalSystemSD routine creates a Security Descriptor for 00783 * the local account with PORT_ALL_ACCESS. 00784 * 00785 * @param LocalSystemSd 00786 * Pointer to a pointer to the security descriptor to create. 00787 * 00788 * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL 00789 * othwerwise. 00790 * 00791 * @remarks None. 00792 * 00793 *--*/ 00794 NTSTATUS 00795 NTAPI 00796 CsrCreateLocalSystemSD(OUT PSECURITY_DESCRIPTOR *LocalSystemSd) 00797 { 00798 SID_IDENTIFIER_AUTHORITY NtSidAuthority = {SECURITY_NT_AUTHORITY}; 00799 PSID SystemSid; 00800 ULONG Length; 00801 PSECURITY_DESCRIPTOR SystemSd; 00802 PACL Dacl; 00803 NTSTATUS Status; 00804 00805 /* Initialize the System SID */ 00806 RtlAllocateAndInitializeSid(&NtSidAuthority, 1, 00807 SECURITY_LOCAL_SYSTEM_RID, 00808 0, 0, 0, 0, 0, 0, 0, 00809 &SystemSid); 00810 00811 /* Get the length of the SID */ 00812 Length = RtlLengthSid(SystemSid) + sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE); 00813 00814 /* Allocate a buffer for the Security Descriptor, with SID and DACL */ 00815 SystemSd = RtlAllocateHeap(CsrHeap, 0, SECURITY_DESCRIPTOR_MIN_LENGTH + Length); 00816 00817 /* Set the pointer to the DACL */ 00818 Dacl = (PACL)((ULONG_PTR)SystemSd + SECURITY_DESCRIPTOR_MIN_LENGTH); 00819 00820 /* Now create the SD itself */ 00821 Status = RtlCreateSecurityDescriptor(SystemSd, SECURITY_DESCRIPTOR_REVISION); 00822 if (!NT_SUCCESS(Status)) 00823 { 00824 /* Fail */ 00825 RtlFreeHeap(CsrHeap, 0, SystemSd); 00826 return Status; 00827 } 00828 00829 /* Create the DACL for it*/ 00830 RtlCreateAcl(Dacl, Length, ACL_REVISION2); 00831 00832 /* Create the ACE */ 00833 Status = RtlAddAccessAllowedAce(Dacl, ACL_REVISION, PORT_ALL_ACCESS, SystemSid); 00834 if (!NT_SUCCESS(Status)) 00835 { 00836 /* Fail */ 00837 RtlFreeHeap(CsrHeap, 0, SystemSd); 00838 return Status; 00839 } 00840 00841 /* Clear the DACL in the SD */ 00842 Status = RtlSetDaclSecurityDescriptor(SystemSd, TRUE, Dacl, FALSE); 00843 if (!NT_SUCCESS(Status)) 00844 { 00845 /* Fail */ 00846 RtlFreeHeap(CsrHeap, 0, SystemSd); 00847 return Status; 00848 } 00849 00850 /* Free the SID and return*/ 00851 RtlFreeSid(SystemSid); 00852 *LocalSystemSd = SystemSd; 00853 return Status; 00854 } 00855 00856 /*++ 00857 * @name CsrSbApiPortInitialize 00858 * 00859 * The CsrSbApiPortInitialize routine initializes the LPC Port used for 00860 * communications with the Session Manager (SM) and initializes the static 00861 * thread that will handle connection requests and APIs. 00862 * 00863 * @param None 00864 * 00865 * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL 00866 * othwerwise. 00867 * 00868 * @remarks None. 00869 * 00870 *--*/ 00871 NTSTATUS 00872 NTAPI 00873 CsrSbApiPortInitialize(VOID) 00874 { 00875 ULONG Size; 00876 PSECURITY_DESCRIPTOR PortSd; 00877 OBJECT_ATTRIBUTES ObjectAttributes; 00878 NTSTATUS Status; 00879 HANDLE hRequestThread; 00880 CLIENT_ID ClientId; 00881 00882 /* Calculate how much space we'll need for the Port Name */ 00883 Size = CsrDirectoryName.Length + sizeof(SB_PORT_NAME) + sizeof(WCHAR); 00884 00885 /* Create the buffer for it */ 00886 CsrSbApiPortName.Buffer = RtlAllocateHeap(CsrHeap, 0, Size); 00887 if (!CsrSbApiPortName.Buffer) return STATUS_NO_MEMORY; 00888 00889 /* Setup the rest of the empty string */ 00890 CsrSbApiPortName.Length = 0; 00891 CsrSbApiPortName.MaximumLength = (USHORT)Size; 00892 00893 /* Now append the full port name */ 00894 RtlAppendUnicodeStringToString(&CsrSbApiPortName, &CsrDirectoryName); 00895 RtlAppendUnicodeToString(&CsrSbApiPortName, UNICODE_PATH_SEP); 00896 RtlAppendUnicodeToString(&CsrSbApiPortName, SB_PORT_NAME); 00897 if (CsrDebug & 2) DPRINT1("CSRSS: Creating %wZ port and associated thread\n", &CsrSbApiPortName); 00898 00899 /* Create Security Descriptor for this Port */ 00900 Status = CsrCreateLocalSystemSD(&PortSd); 00901 if (!NT_SUCCESS(Status)) return Status; 00902 00903 /* Initialize the Attributes */ 00904 InitializeObjectAttributes(&ObjectAttributes, 00905 &CsrSbApiPortName, 00906 0, 00907 NULL, 00908 PortSd); 00909 00910 /* Create the Port Object */ 00911 Status = NtCreatePort(&CsrSbApiPort, 00912 &ObjectAttributes, 00913 sizeof(SB_CONNECTION_INFO), 00914 sizeof(SB_API_MSG), 00915 32 * sizeof(SB_API_MSG)); 00916 if (PortSd) RtlFreeHeap(CsrHeap, 0, PortSd); 00917 00918 if (NT_SUCCESS(Status)) 00919 { 00920 /* Create the Thread to handle the API Requests */ 00921 Status = RtlCreateUserThread(NtCurrentProcess(), 00922 NULL, 00923 TRUE, 00924 0, 00925 0, 00926 0, 00927 (PVOID)CsrSbApiRequestThread, 00928 NULL, 00929 &hRequestThread, 00930 &ClientId); 00931 if (NT_SUCCESS(Status)) 00932 { 00933 /* Add it as a Static Server Thread */ 00934 CsrSbApiRequestThreadPtr = CsrAddStaticServerThread(hRequestThread, 00935 &ClientId, 00936 0); 00937 00938 /* Activate it */ 00939 Status = NtResumeThread(hRequestThread, NULL); 00940 } 00941 } 00942 00943 return Status; 00944 } 00945 00946 /* PUBLIC FUNCTIONS ***********************************************************/ 00947 00948 NTSTATUS 00949 NTAPI 00950 CsrServerInitialization(IN ULONG ArgumentCount, 00951 IN PCHAR Arguments[]) 00952 { 00953 NTSTATUS Status = STATUS_SUCCESS; 00954 DPRINT("CSRSRV: %s called\n", __FUNCTION__); 00955 00956 /* Create the Init Event */ 00957 Status = NtCreateEvent(&CsrInitializationEvent, 00958 EVENT_ALL_ACCESS, 00959 NULL, 00960 SynchronizationEvent, 00961 FALSE); 00962 if (!NT_SUCCESS(Status)) 00963 { 00964 DPRINT1("CSRSRV:%s: NtCreateEvent failed (Status=%08lx)\n", 00965 __FUNCTION__, Status); 00966 return Status; 00967 } 00968 00969 /* Cache System Basic Information so we don't always request it */ 00970 Status = NtQuerySystemInformation(SystemBasicInformation, 00971 &CsrNtSysInfo, 00972 sizeof(SYSTEM_BASIC_INFORMATION), 00973 NULL); 00974 if (!NT_SUCCESS(Status)) 00975 { 00976 DPRINT1("CSRSRV:%s: NtQuerySystemInformation failed (Status=%08lx)\n", 00977 __FUNCTION__, Status); 00978 return Status; 00979 } 00980 00981 /* Save our Heap */ 00982 CsrHeap = RtlGetProcessHeap(); 00983 00984 /* Set our Security Descriptor to protect the process */ 00985 Status = CsrSetProcessSecurity(); 00986 if (!NT_SUCCESS(Status)) 00987 { 00988 DPRINT1("CSRSRV:%s: CsrSetProcessSecurity failed (Status=%08lx)\n", 00989 __FUNCTION__, Status); 00990 return Status; 00991 } 00992 00993 /* Set up Session Support */ 00994 Status = CsrInitializeNtSessionList(); 00995 if (!NT_SUCCESS(Status)) 00996 { 00997 DPRINT1("CSRSRV:%s: CsrInitializeSessions failed (Status=%08lx)\n", 00998 __FUNCTION__, Status); 00999 return Status; 01000 } 01001 01002 /* Set up Process Support */ 01003 Status = CsrInitializeProcessStructure(); 01004 if (!NT_SUCCESS(Status)) 01005 { 01006 DPRINT1("CSRSRV:%s: CsrInitializeProcessStructure failed (Status=%08lx)\n", 01007 __FUNCTION__, Status); 01008 return Status; 01009 } 01010 01011 /* Parse the command line */ 01012 Status = CsrParseServerCommandLine(ArgumentCount, Arguments); 01013 if (!NT_SUCCESS(Status)) 01014 { 01015 DPRINT1("CSRSRV:%s: CsrParseServerCommandLine failed (Status=%08lx)\n", 01016 __FUNCTION__, Status); 01017 return Status; 01018 } 01019 01020 Status = CsrApiRegisterDefinitions(NativeDefinitions); 01021 if (!NT_SUCCESS(Status)) 01022 { 01023 DPRINT1("CSRSRV failed in %s with status %lx\n", "CsrApiRegisterDefinitions", Status); 01024 } 01025 01026 /* Now initialize our API Port */ 01027 Status = CsrApiPortInitialize(); 01028 if (!NT_SUCCESS(Status)) 01029 { 01030 DPRINT1("CSRSRV:%s: CsrApiPortInitialize failed (Status=%08lx)\n", 01031 __FUNCTION__, Status); 01032 return Status; 01033 } 01034 01035 /* Initialize Win32csr */ 01036 Status = CsrLoadServerDll("win32csr", "Win32CsrInitialization", 2); 01037 if (!NT_SUCCESS(Status)) 01038 { 01039 DPRINT1("CSRSRV failed in %s with status %lx\n", "CsrLoadServerDll", Status); 01040 } 01041 01042 /* Initialize the API Port for SM communication */ 01043 Status = CsrSbApiPortInitialize(); 01044 if (!NT_SUCCESS(Status)) 01045 { 01046 DPRINT1("CSRSRV:%s: CsrSbApiPortInitialize failed (Status=%08lx)\n", 01047 __FUNCTION__, Status); 01048 return Status; 01049 } 01050 01051 /* We're all set! Connect to SM! */ 01052 Status = SmConnectToSm(&CsrSbApiPortName, 01053 CsrSbApiPort, 01054 IMAGE_SUBSYSTEM_WINDOWS_GUI, 01055 &CsrSmApiPort); 01056 if (!NT_SUCCESS(Status)) 01057 { 01058 DPRINT1("CSRSRV:%s: SmConnectToSm failed (Status=%08lx)\n", 01059 __FUNCTION__, Status); 01060 return Status; 01061 } 01062 01063 /* Finito! Signal the event */ 01064 Status = NtSetEvent(CsrInitializationEvent, NULL); 01065 if (!NT_SUCCESS(Status)) 01066 { 01067 DPRINT1("CSRSRV:%s: NtSetEvent failed (Status=%08lx)\n", 01068 __FUNCTION__, Status); 01069 return Status; 01070 } 01071 01072 /* Close the event handle now */ 01073 NtClose(CsrInitializationEvent); 01074 01075 /* Have us handle Hard Errors */ 01076 Status = NtSetDefaultHardErrorPort(CsrApiPort); 01077 if (!NT_SUCCESS(Status)) 01078 { 01079 DPRINT1("CSRSRV:%s: NtSetDefaultHardErrorPort failed (Status=%08lx)\n", 01080 __FUNCTION__, Status); 01081 return Status; 01082 } 01083 01084 /* Return status */ 01085 return Status; 01086 } 01087 01088 BOOL 01089 NTAPI 01090 DllMain(HANDLE hDll, 01091 DWORD dwReason, 01092 LPVOID lpReserved) 01093 { 01094 /* We don't do much */ 01095 UNREFERENCED_PARAMETER(hDll); 01096 UNREFERENCED_PARAMETER(dwReason); 01097 UNREFERENCED_PARAMETER(lpReserved); 01098 return TRUE; 01099 } 01100 01101 /* EOF */ Generated on Sun May 27 2012 04:23:32 for ReactOS by
1.7.6.1
|