Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygensmsubsys.c
Go to the documentation of this file.
00001 /* 00002 * PROJECT: ReactOS Windows-Compatible Session Manager 00003 * LICENSE: BSD 2-Clause License 00004 * FILE: base/system/smss/smss.c 00005 * PURPOSE: Main SMSS Code 00006 * PROGRAMMERS: Alex Ionescu 00007 */ 00008 00009 /* INCLUDES *******************************************************************/ 00010 00011 #include "smss.h" 00012 #define NDEBUG 00013 #include "debug.h" 00014 00015 /* GLOBALS ********************************************************************/ 00016 00017 RTL_CRITICAL_SECTION SmpKnownSubSysLock; 00018 LIST_ENTRY SmpKnownSubSysHead; 00019 HANDLE SmpWindowsSubSysProcess; 00020 HANDLE SmpWindowsSubSysProcessId; 00021 BOOLEAN RegPosixSingleInstance; 00022 WCHAR InitialCommandBuffer[256]; 00023 00024 /* FUNCTIONS ******************************************************************/ 00025 00026 NTSTATUS 00027 NTAPI 00028 SmpCallCsrCreateProcess(IN PSB_API_MSG SbApiMsg, 00029 IN USHORT MessageLength, 00030 IN HANDLE PortHandle) 00031 { 00032 NTSTATUS Status; 00033 00034 /* Initialize the header and send the message to CSRSS */ 00035 SbApiMsg->h.u2.ZeroInit = 0; 00036 SbApiMsg->h.u1.s1.DataLength = MessageLength + 8; 00037 SbApiMsg->h.u1.s1.TotalLength = sizeof(SB_API_MSG); 00038 SbApiMsg->ApiNumber = SbpCreateProcess; 00039 Status = NtRequestWaitReplyPort(PortHandle, &SbApiMsg->h, &SbApiMsg->h); 00040 if (NT_SUCCESS(Status)) Status = SbApiMsg->ReturnValue; 00041 return Status; 00042 } 00043 00044 VOID 00045 NTAPI 00046 SmpDereferenceSubsystem(IN PSMP_SUBSYSTEM SubSystem) 00047 { 00048 /* Acquire the database lock while we (potentially) destroy this subsystem */ 00049 RtlEnterCriticalSection(&SmpKnownSubSysLock); 00050 00051 /* Drop the reference and see if it's terminating */ 00052 if (!(--SubSystem->ReferenceCount) && (SubSystem->Terminating)) 00053 { 00054 /* Close all handles and free it */ 00055 if (SubSystem->Event) NtClose(SubSystem->Event); 00056 if (SubSystem->ProcessHandle) NtClose(SubSystem->ProcessHandle); 00057 if (SubSystem->SbApiPort) NtClose(SubSystem->SbApiPort); 00058 RtlFreeHeap(SmpHeap, 0, SubSystem); 00059 } 00060 00061 /* Release the database lock */ 00062 RtlLeaveCriticalSection(&SmpKnownSubSysLock); 00063 } 00064 00065 PSMP_SUBSYSTEM 00066 NTAPI 00067 SmpLocateKnownSubSysByCid(IN PCLIENT_ID ClientId) 00068 { 00069 PSMP_SUBSYSTEM Subsystem = NULL; 00070 PLIST_ENTRY NextEntry; 00071 00072 /* Lock the subsystem database */ 00073 RtlEnterCriticalSection(&SmpKnownSubSysLock); 00074 00075 /* Loop each subsystem in the database */ 00076 NextEntry = SmpKnownSubSysHead.Flink; 00077 while (NextEntry != &SmpKnownSubSysHead) 00078 { 00079 /* Check if this one matches the client ID and is still valid */ 00080 Subsystem = CONTAINING_RECORD(NextEntry, SMP_SUBSYSTEM, Entry); 00081 if ((*(PULONGLONG)&Subsystem->ClientId == *(PULONGLONG)ClientId) && 00082 !(Subsystem->Terminating)) 00083 { 00084 /* Add a reference and return it */ 00085 Subsystem->ReferenceCount++; 00086 break; 00087 } 00088 00089 /* Reset the current pointer and keep earching */ 00090 Subsystem = NULL; 00091 NextEntry = NextEntry->Flink; 00092 } 00093 00094 /* Release the lock and return the subsystem we found */ 00095 RtlLeaveCriticalSection(&SmpKnownSubSysLock); 00096 return Subsystem; 00097 } 00098 00099 PSMP_SUBSYSTEM 00100 NTAPI 00101 SmpLocateKnownSubSysByType(IN ULONG MuSessionId, 00102 IN ULONG ImageType) 00103 { 00104 PSMP_SUBSYSTEM Subsystem = NULL; 00105 PLIST_ENTRY NextEntry; 00106 00107 /* Lock the subsystem database */ 00108 RtlEnterCriticalSection(&SmpKnownSubSysLock); 00109 00110 /* Loop each subsystem in the database */ 00111 NextEntry = SmpKnownSubSysHead.Flink; 00112 while (NextEntry != &SmpKnownSubSysHead) 00113 { 00114 /* Check if this one matches the image and uID, and is still valid */ 00115 Subsystem = CONTAINING_RECORD(NextEntry, SMP_SUBSYSTEM, Entry); 00116 if ((Subsystem->ImageType == ImageType) && 00117 !(Subsystem->Terminating) && 00118 (Subsystem->MuSessionId == MuSessionId)) 00119 { 00120 /* Return it referenced for the caller */ 00121 Subsystem->ReferenceCount++; 00122 break; 00123 } 00124 00125 /* Reset the current pointer and keep earching */ 00126 Subsystem = NULL; 00127 NextEntry = NextEntry->Flink; 00128 } 00129 00130 /* Release the lock and return the subsystem we found */ 00131 RtlLeaveCriticalSection(&SmpKnownSubSysLock); 00132 return Subsystem; 00133 } 00134 00135 NTSTATUS 00136 NTAPI 00137 SmpLoadSubSystem(IN PUNICODE_STRING FileName, 00138 IN PUNICODE_STRING Directory, 00139 IN PUNICODE_STRING CommandLine, 00140 IN ULONG MuSessionId, 00141 OUT PHANDLE ProcessId, 00142 IN ULONG Flags) 00143 { 00144 PSMP_SUBSYSTEM Subsystem, NewSubsystem, KnownSubsystem = NULL; 00145 HANDLE SubSysProcessId; 00146 NTSTATUS Status = STATUS_SUCCESS; 00147 SB_API_MSG SbApiMsg, SbApiMsg2; 00148 RTL_USER_PROCESS_INFORMATION ProcessInformation; 00149 LARGE_INTEGER Timeout; 00150 PVOID State; 00151 PSB_CREATE_PROCESS_MSG CreateProcess = &SbApiMsg.CreateProcess; 00152 PSB_CREATE_SESSION_MSG CreateSession = &SbApiMsg.CreateSession; 00153 00154 /* Make sure this is a found subsystem */ 00155 if (Flags & SMP_INVALID_PATH) 00156 { 00157 DPRINT1("SMSS: Unable to find subsystem - %wZ\n", FileName); 00158 return STATUS_OBJECT_NAME_NOT_FOUND; 00159 } 00160 00161 /* Don't use a session if the flag is set */ 00162 if (Flags & 0x80) MuSessionId = 0; 00163 00164 /* Lock the subsystems while we do a look up */ 00165 RtlEnterCriticalSection(&SmpKnownSubSysLock); 00166 while (TRUE) 00167 { 00168 /* Check if we found a subsystem not yet fully iniitalized */ 00169 Subsystem = SmpLocateKnownSubSysByType(MuSessionId, -1); 00170 if (!Subsystem) break; 00171 RtlLeaveCriticalSection(&SmpKnownSubSysLock); 00172 00173 /* Wait on it to initialize */ 00174 NtWaitForSingleObject(Subsystem->Event, FALSE, NULL); 00175 00176 /* Dereference it and try the next one */ 00177 RtlEnterCriticalSection(&SmpKnownSubSysLock); 00178 SmpDereferenceSubsystem(Subsystem); 00179 } 00180 00181 /* Check if this is a POSIX subsystem */ 00182 if (Flags & SMP_POSIX_FLAG) 00183 { 00184 /* Do we already have it? */ 00185 Subsystem = SmpLocateKnownSubSysByType(MuSessionId, IMAGE_SUBSYSTEM_POSIX_CUI); 00186 } 00187 else if (Flags & SMP_OS2_FLAG) 00188 { 00189 /* This is an OS/2 subsystem, do we we already have it? */ 00190 Subsystem = SmpLocateKnownSubSysByType(MuSessionId, IMAGE_SUBSYSTEM_OS2_CUI); 00191 } 00192 00193 /* Check if we already have one of the optional subsystems for the session */ 00194 if (Subsystem) 00195 { 00196 /* Dereference and return, no work to do */ 00197 SmpDereferenceSubsystem(Subsystem); 00198 RtlLeaveCriticalSection(&SmpKnownSubSysLock); 00199 return STATUS_SUCCESS; 00200 } 00201 00202 /* Allocate a new subsystem! */ 00203 NewSubsystem = RtlAllocateHeap(SmpHeap, SmBaseTag, sizeof(SMP_SUBSYSTEM)); 00204 if (!NewSubsystem) 00205 { 00206 RtlLeaveCriticalSection(&SmpKnownSubSysLock); 00207 return STATUS_NO_MEMORY; 00208 } 00209 00210 /* Initialize its header and reference count */ 00211 NewSubsystem->ReferenceCount = 1; 00212 NewSubsystem->MuSessionId = MuSessionId; 00213 NewSubsystem->ImageType = -1; 00214 00215 /* Clear out all the other data for now */ 00216 NewSubsystem->Terminating = FALSE; 00217 NewSubsystem->ProcessHandle = NULL; 00218 NewSubsystem->Event = NULL; 00219 NewSubsystem->PortHandle = NULL; 00220 NewSubsystem->SbApiPort = NULL; 00221 00222 /* Create the event we'll be wating on for initialization */ 00223 Status = NtCreateEvent(&NewSubsystem->Event, 00224 EVENT_ALL_ACCESS, 00225 NULL, 00226 NotificationEvent, 00227 FALSE); 00228 if (!NT_SUCCESS(Status)) 00229 { 00230 /* This failed, bail out */ 00231 RtlFreeHeap(SmpHeap, 0, NewSubsystem); 00232 RtlLeaveCriticalSection(&SmpKnownSubSysLock); 00233 return STATUS_NO_MEMORY; 00234 } 00235 00236 /* Insert the subsystem and release the lock. It can now be found */ 00237 InsertTailList(&SmpKnownSubSysHead, &NewSubsystem->Entry); 00238 RtlLeaveCriticalSection(&SmpKnownSubSysLock); 00239 00240 /* The OS/2 and POSIX subsystems are actually Windows applications! */ 00241 if (Flags & (SMP_POSIX_FLAG | SMP_OS2_FLAG)) 00242 { 00243 /* Locate the Windows subsystem for this session */ 00244 KnownSubsystem = SmpLocateKnownSubSysByType(MuSessionId, 00245 IMAGE_SUBSYSTEM_WINDOWS_GUI); 00246 if (!KnownSubsystem) 00247 { 00248 DPRINT1("SMSS: SmpLoadSubSystem - SmpLocateKnownSubSysByType Failed\n"); 00249 goto Quickie2; 00250 } 00251 00252 /* Fill out all the process details and call CSRSS to launch it */ 00253 CreateProcess->In.ImageName = FileName; 00254 CreateProcess->In.CurrentDirectory = Directory; 00255 CreateProcess->In.CommandLine = CommandLine; 00256 CreateProcess->In.DllPath = SmpDefaultLibPath.Length ? 00257 &SmpDefaultLibPath : NULL; 00258 CreateProcess->In.Flags = Flags | SMP_DEFERRED_FLAG; 00259 CreateProcess->In.DebugFlags = SmpDebug; 00260 Status = SmpCallCsrCreateProcess(&SbApiMsg, 00261 sizeof(*CreateProcess), 00262 KnownSubsystem->SbApiPort); 00263 if (!NT_SUCCESS(Status)) 00264 { 00265 /* Handle failures */ 00266 DPRINT1("SMSS: SmpLoadSubSystem - SmpCallCsrCreateProcess Failed with Status %lx\n", 00267 Status); 00268 goto Quickie2; 00269 } 00270 00271 /* Save the process information we'll need for the create session */ 00272 ProcessInformation.ProcessHandle = CreateProcess->Out.ProcessHandle; 00273 ProcessInformation.ThreadHandle = CreateProcess->Out.ThreadHandle; 00274 ProcessInformation.ClientId = CreateProcess->Out.ClientId; 00275 ProcessInformation.ImageInformation.SubSystemType = CreateProcess->Out.SubsystemType; 00276 } 00277 else 00278 { 00279 /* This must be CSRSS itself, so just launch it and that's it */ 00280 Status = SmpExecuteImage(FileName, 00281 Directory, 00282 CommandLine, 00283 MuSessionId, 00284 Flags | SMP_DEFERRED_FLAG, 00285 &ProcessInformation); 00286 if (!NT_SUCCESS(Status)) 00287 { 00288 /* Handle failures */ 00289 DPRINT1("SMSS: SmpLoadSubSystem - SmpExecuteImage Failed with Status %lx\n", 00290 Status); 00291 goto Quickie2; 00292 } 00293 } 00294 00295 /* Fill out the handle and client ID in the subsystem structure now */ 00296 NewSubsystem->ProcessHandle = ProcessInformation.ProcessHandle; 00297 NewSubsystem->ClientId = ProcessInformation.ClientId; 00298 00299 /* Check if we launched a native image or a subsystem-backed image */ 00300 if (ProcessInformation.ImageInformation.SubSystemType == IMAGE_SUBSYSTEM_NATIVE) 00301 { 00302 /* This must be CSRSS itself, since it's a native subsystem image */ 00303 SubSysProcessId = ProcessInformation.ClientId.UniqueProcess; 00304 if ((ProcessId) && !(*ProcessId)) *ProcessId = SubSysProcessId; 00305 00306 /* Was this the initial CSRSS on Session 0? */ 00307 if (!MuSessionId) 00308 { 00309 /* Then save it in the global variables */ 00310 SmpWindowsSubSysProcessId = SubSysProcessId; 00311 SmpWindowsSubSysProcess = ProcessInformation.ProcessHandle; 00312 } 00313 ASSERT(NT_SUCCESS(Status)); 00314 } 00315 else 00316 { 00317 /* This is the POSIX or OS/2 subsystem process, copy its information */ 00318 RtlCopyMemory(&CreateSession->ProcessInfo, 00319 &ProcessInformation, 00320 sizeof(CreateSession->ProcessInfo)); 00321 00322 /* Not sure these field mean what I think they do -- but clear them */ 00323 *(PULONGLONG)&CreateSession->ClientId = 0; 00324 CreateSession->MuSessionId = 0; 00325 00326 /* This should find CSRSS because they are POSIX or OS/2 subsystems */ 00327 Subsystem = SmpLocateKnownSubSysByType(MuSessionId, 00328 ProcessInformation.ImageInformation.SubSystemType); 00329 if (!Subsystem) 00330 { 00331 /* Odd failure -- but handle it anyway */ 00332 Status = STATUS_NO_SUCH_PACKAGE; 00333 DPRINT1("SMSS: SmpLoadSubSystem - SmpLocateKnownSubSysByType Failed with Status %lx for sessionid %ld\n", 00334 Status, 00335 MuSessionId); 00336 goto Quickie; 00337 } 00338 00339 /* Duplicate the parent process handle for the subsystem to have */ 00340 Status = NtDuplicateObject(NtCurrentProcess(), 00341 ProcessInformation.ProcessHandle, 00342 Subsystem->ProcessHandle, 00343 &CreateSession->ProcessInfo.ProcessHandle, 00344 PROCESS_ALL_ACCESS, 00345 0, 00346 0); 00347 if (!NT_SUCCESS(Status)) 00348 { 00349 /* Fail since this is critical */ 00350 DPRINT1("SMSS: SmpLoadSubSystem - NtDuplicateObject Failed with Status %lx for sessionid %ld\n", 00351 Status, 00352 MuSessionId); 00353 goto Quickie; 00354 } 00355 00356 /* Duplicate the initial thread handle for the subsystem to have */ 00357 Status = NtDuplicateObject(NtCurrentProcess(), 00358 ProcessInformation.ThreadHandle, 00359 Subsystem->ProcessHandle, 00360 &CreateSession->ProcessInfo.ThreadHandle, 00361 THREAD_ALL_ACCESS, 00362 0, 00363 0); 00364 if (!NT_SUCCESS(Status)) 00365 { 00366 /* Fail since this is critical */ 00367 DPRINT1("SMSS: SmpLoadSubSystem - NtDuplicateObject Failed with Status %lx for sessionid %ld\n", 00368 Status, 00369 MuSessionId); 00370 goto Quickie; 00371 } 00372 00373 /* Allocate an internal Session ID for this subsystem */ 00374 MuSessionId = SmpAllocateSessionId(Subsystem, 0); 00375 CreateSession->SessionId = MuSessionId; 00376 00377 /* Send the create session message to the subsystem */ 00378 SbApiMsg2.ReturnValue = STATUS_SUCCESS; 00379 SbApiMsg2.h.u2.ZeroInit = 0; 00380 SbApiMsg2.h.u1.s1.DataLength = sizeof(SB_CREATE_SESSION_MSG) + 8; 00381 SbApiMsg2.h.u1.s1.TotalLength = sizeof(SB_API_MSG); 00382 Status = NtRequestWaitReplyPort(Subsystem->SbApiPort, 00383 &SbApiMsg2.h, 00384 &SbApiMsg2.h); 00385 if (NT_SUCCESS(Status)) Status = SbApiMsg2.ReturnValue; 00386 if (!NT_SUCCESS(Status)) 00387 { 00388 /* Delete the session and handle failure if the LPC call failed */ 00389 SmpDeleteSession(CreateSession->SessionId); 00390 DPRINT1("SMSS: SmpLoadSubSystem - NtRequestWaitReplyPort Failed with Status %lx for sessionid %ld\n", 00391 Status, 00392 CreateSession->SessionId); 00393 goto Quickie; 00394 } 00395 } 00396 00397 /* Okay, everything looks good to go, initialize this subsystem now! */ 00398 Status = NtResumeThread(ProcessInformation.ThreadHandle, NULL); 00399 if (!NT_SUCCESS(Status)) 00400 { 00401 /* That didn't work -- back out of everything */ 00402 DPRINT1("SMSS: SmpLoadSubSystem - NtResumeThread failed Status %lx\n", Status); 00403 goto Quickie; 00404 } 00405 00406 /* Check if this was the subsystem for a different session */ 00407 if (MuSessionId) 00408 { 00409 /* Wait up to 60 seconds for it to initialize */ 00410 Timeout.QuadPart = -600000000; 00411 Status = NtWaitForSingleObject(NewSubsystem->Event, FALSE, &Timeout); 00412 00413 /* Timeout is done -- does this session still exist? */ 00414 if (!SmpCheckDuplicateMuSessionId(MuSessionId)) 00415 { 00416 /* Nope, it died. Cleanup should've ocurred in a different path. */ 00417 DPRINT1("SMSS: SmpLoadSubSystem - session deleted\n"); 00418 return STATUS_DELETE_PENDING; 00419 } 00420 00421 /* Check if we timed our or there was another error with the wait */ 00422 if (Status != STATUS_WAIT_0) 00423 { 00424 /* Something is wrong with the subsystem, so back out of everything */ 00425 DPRINT1("SMSS: SmpLoadSubSystem - Timeout waiting for subsystem connect with Status %lx for sessionid %ld\n", 00426 Status, 00427 MuSessionId); 00428 goto Quickie; 00429 } 00430 } 00431 else 00432 { 00433 /* This a session 0 subsystem, just wait for it to initialize */ 00434 NtWaitForSingleObject(NewSubsystem->Event, FALSE, NULL); 00435 } 00436 00437 /* Subsystem is created, resumed, and initialized. Close handles and exit */ 00438 NtClose(ProcessInformation.ThreadHandle); 00439 Status = STATUS_SUCCESS; 00440 goto Quickie2; 00441 00442 Quickie: 00443 /* This is the failure path. First check if we need to detach from session */ 00444 if ((AttachedSessionId == -1) || (Flags & (SMP_POSIX_FLAG | SMP_OS2_FLAG))) 00445 { 00446 /* We were not attached, or did not launch subsystems that required it */ 00447 DPRINT1("SMSS: Did not detach from Session Space: SessionId=%x Flags=%x Status=%x\n", 00448 AttachedSessionId, 00449 Flags | SMP_DEFERRED_FLAG, 00450 Status); 00451 } 00452 else 00453 { 00454 /* Get the privilege we need for detachment */ 00455 Status = SmpAcquirePrivilege(SE_LOAD_DRIVER_PRIVILEGE, &State); 00456 if (!NT_SUCCESS(Status)) 00457 { 00458 /* We can't detach without it */ 00459 DPRINT1("SMSS: Did not detach from Session Space: SessionId=%x Flags=%x Status=%x\n", 00460 AttachedSessionId, 00461 Flags | SMP_DEFERRED_FLAG, 00462 Status); 00463 } 00464 else 00465 { 00466 /* Now detach from the session */ 00467 Status = NtSetSystemInformation(SystemSessionDetach, 00468 &AttachedSessionId, 00469 sizeof(AttachedSessionId)); 00470 if (!NT_SUCCESS(Status)) 00471 { 00472 /* Failed to detach. Note the DPRINT1 has a typo in Windows */ 00473 DPRINT1("SMSS: SmpStartCsr, Couldn't Detach from Session Space. Status=%x\n", Status); 00474 ASSERT(NT_SUCCESS(Status)); 00475 } 00476 else 00477 { 00478 /* Detachment worked, reset our attached session ID */ 00479 AttachedSessionId = -1; 00480 } 00481 00482 /* And release the privilege we acquired */ 00483 SmpReleasePrivilege(State); 00484 } 00485 } 00486 00487 /* Since this is the failure path, terminate the subsystem process */ 00488 NtTerminateProcess(ProcessInformation.ProcessHandle, Status); 00489 NtClose(ProcessInformation.ThreadHandle); 00490 00491 Quickie2: 00492 /* This is the cleanup path -- first dereference our subsystems */ 00493 RtlEnterCriticalSection(&SmpKnownSubSysLock); 00494 if (Subsystem) SmpDereferenceSubsystem(Subsystem); 00495 if (KnownSubsystem) SmpDereferenceSubsystem(KnownSubsystem); 00496 00497 /* In the failure case, destroy the new subsystem we just created */ 00498 if (!NT_SUCCESS(Status)) 00499 { 00500 RemoveEntryList(&NewSubsystem->Entry); 00501 NtSetEvent(NewSubsystem->Event, 0); 00502 if (NewSubsystem) SmpDereferenceSubsystem(NewSubsystem); 00503 } 00504 00505 /* Finally, we're all done! */ 00506 RtlLeaveCriticalSection(&SmpKnownSubSysLock); 00507 return Status; 00508 } 00509 00510 NTSTATUS 00511 NTAPI 00512 SmpLoadSubSystemsForMuSession(IN PULONG MuSessionId, 00513 OUT PHANDLE ProcessId, 00514 IN PUNICODE_STRING InitialCommand) 00515 { 00516 NTSTATUS Status = STATUS_SUCCESS, Status2; 00517 PSMP_REGISTRY_VALUE RegEntry; 00518 UNICODE_STRING DestinationString, NtPath; 00519 PLIST_ENTRY NextEntry; 00520 LARGE_INTEGER Timeout; 00521 PVOID State; 00522 00523 /* Write a few last registry keys with the boot partition information */ 00524 SmpTranslateSystemPartitionInformation(); 00525 00526 /* Process "SetupExecute" values */ 00527 NextEntry = SmpSetupExecuteList.Flink; 00528 while (NextEntry != &SmpSetupExecuteList) 00529 { 00530 /* Execute each one and move on */ 00531 RegEntry = CONTAINING_RECORD(NextEntry, SMP_REGISTRY_VALUE, Entry); 00532 SmpExecuteCommand(&RegEntry->Name, 0, NULL, 0); 00533 NextEntry = NextEntry->Flink; 00534 } 00535 00536 /* Now process the subsystems */ 00537 NextEntry = SmpSubSystemList.Flink; 00538 while (NextEntry != &SmpSubSystemList) 00539 { 00540 /* Get the entry and check if this is the special Win32k entry */ 00541 RegEntry = CONTAINING_RECORD(NextEntry, SMP_REGISTRY_VALUE, Entry); 00542 if (!_wcsicmp(RegEntry->Name.Buffer, L"Kmode")) 00543 { 00544 /* Translate it */ 00545 if (!RtlDosPathNameToNtPathName_U(RegEntry->Value.Buffer, 00546 &NtPath, 00547 NULL, 00548 NULL)) 00549 { 00550 Status = STATUS_OBJECT_PATH_SYNTAX_BAD; 00551 DPRINT1("Failed: %lx\n", Status); 00552 } 00553 else 00554 { 00555 /* Get the driver privilege */ 00556 Status = SmpAcquirePrivilege(SE_LOAD_DRIVER_PRIVILEGE, &State); 00557 if (NT_SUCCESS(Status)) 00558 { 00559 /* Create the new session */ 00560 ASSERT(AttachedSessionId == -1); 00561 Status = NtSetSystemInformation(SystemSessionCreate, 00562 MuSessionId, 00563 sizeof(*MuSessionId)); 00564 if (!NT_SUCCESS(Status)) 00565 { 00566 DPRINT1("SMSS: Session space creation failed\n"); 00567 SmpReleasePrivilege(State); 00568 RtlFreeHeap(RtlGetProcessHeap(), 0, NtPath.Buffer); 00569 return Status; 00570 } 00571 AttachedSessionId = *MuSessionId; 00572 00573 /* Start Win32k.sys on this session */ 00574 RtlInitUnicodeString(&DestinationString, 00575 L"\\SystemRoot\\System32\\win32k.sys"); 00576 Status = NtSetSystemInformation(SystemExtendServiceTableInformation, 00577 &DestinationString, 00578 sizeof(DestinationString)); 00579 RtlFreeHeap(RtlGetProcessHeap(), 0, NtPath.Buffer); 00580 SmpReleasePrivilege(State); 00581 if (!NT_SUCCESS(Status)) 00582 { 00583 DPRINT1("SMSS: Load of WIN32K failed.\n"); 00584 return Status; 00585 } 00586 } 00587 } 00588 } 00589 00590 /* Next entry */ 00591 NextEntry = NextEntry->Flink; 00592 } 00593 00594 /* Now parse the required subsystem list */ 00595 NextEntry = SmpSubSystemsToLoad.Flink; 00596 while (NextEntry != &SmpSubSystemsToLoad) 00597 { 00598 /* Get each entry and check if it's the internal debug or not */ 00599 RegEntry = CONTAINING_RECORD(NextEntry, SMP_REGISTRY_VALUE, Entry); 00600 if (_wcsicmp(RegEntry->Name.Buffer, L"debug")) 00601 { 00602 /* Load the required subsystem */ 00603 Status = SmpExecuteCommand(&RegEntry->Value, 00604 *MuSessionId, 00605 ProcessId, 00606 SMP_SUBSYSTEM_FLAG); 00607 } 00608 else 00609 { 00610 /* Load the internal debug system */ 00611 Status = SmpExecuteCommand(&RegEntry->Value, 00612 *MuSessionId, 00613 ProcessId, 00614 SMP_DEBUG_FLAG | SMP_SUBSYSTEM_FLAG); 00615 } 00616 if (!NT_SUCCESS(Status)) 00617 { 00618 DbgPrint("SMSS: Subsystem execute failed (%WZ)\n", &RegEntry->Value); 00619 return Status; 00620 } 00621 00622 /* Move to the next entry */ 00623 NextEntry = NextEntry->Flink; 00624 } 00625 00626 /* Process the "Execute" list now */ 00627 NextEntry = SmpExecuteList.Blink; 00628 if (NextEntry != &SmpExecuteList) 00629 { 00630 /* Get the custom initial command */ 00631 RegEntry = CONTAINING_RECORD(NextEntry, SMP_REGISTRY_VALUE, Entry); 00632 00633 /* Write the initial command and wait for 5 seconds (why??!) */ 00634 *InitialCommand = RegEntry->Name; 00635 Timeout.QuadPart = -50000000; 00636 NtDelayExecution(FALSE, &Timeout); 00637 } 00638 else 00639 { 00640 /* Use the default Winlogon initial command */ 00641 RtlInitUnicodeString(InitialCommand, L"winlogon.exe"); 00642 InitialCommandBuffer[0] = UNICODE_NULL; 00643 00644 /* Check if there's a debugger for Winlogon */ 00645 Status2 = LdrQueryImageFileExecutionOptions(InitialCommand, 00646 L"Debugger", 00647 REG_SZ, 00648 InitialCommandBuffer, 00649 sizeof(InitialCommandBuffer) - 00650 InitialCommand->Length, 00651 NULL); 00652 if ((NT_SUCCESS(Status2)) && (InitialCommandBuffer[0])) 00653 { 00654 /* Put the debugger string with the Winlogon string */ 00655 wcscat(InitialCommandBuffer, L" "); 00656 wcscat(InitialCommandBuffer, InitialCommand->Buffer); 00657 RtlInitUnicodeString(InitialCommand, InitialCommandBuffer); 00658 } 00659 } 00660 00661 /* Finally check if there was a custom initial command */ 00662 NextEntry = SmpExecuteList.Flink; 00663 while (NextEntry != &SmpExecuteList) 00664 { 00665 /* Execute each one */ 00666 RegEntry = CONTAINING_RECORD(NextEntry, SMP_REGISTRY_VALUE, Entry); 00667 SmpExecuteCommand(&RegEntry->Name, *MuSessionId, NULL, 0); 00668 NextEntry = NextEntry->Flink; 00669 } 00670 00671 /* Return status */ 00672 return Status; 00673 } 00674 Generated on Sun May 27 2012 04:18:53 for ReactOS by
1.7.6.1
|