2 * PROJECT: ReactOS Windows-Compatible Session Manager
3 * LICENSE: BSD 2-Clause License
4 * FILE: base/system/smss/smss.c
5 * PURPOSE: Main SMSS Code
6 * PROGRAMMERS: Alex Ionescu
9 /* INCLUDES *******************************************************************/
15 /* GLOBALS ********************************************************************/
17 PCHAR SmpSubSystemNames
[] =
26 /* FUNCTIONS ******************************************************************/
30 SmpSbCreateSession(IN PVOID Reserved
,
31 IN PSMP_SUBSYSTEM OtherSubsystem
,
32 IN PRTL_USER_PROCESS_INFORMATION ProcessInformation
,
34 IN PCLIENT_ID DbgClientId
)
37 PSMP_SUBSYSTEM KnownSubsys
;
40 PSB_CREATE_SESSION_MSG CreateSessionMsg
;
42 /* Write out the create session message including its initial process */
43 CreateSessionMsg
= &SbApiMsg
.CreateSession
;
44 CreateSessionMsg
->ProcessInfo
= *ProcessInformation
;
45 CreateSessionMsg
->MuSessionId
= MuSessionId
;
48 CreateSessionMsg
->ClientId
= *DbgClientId
;
52 CreateSessionMsg
->ClientId
.UniqueThread
= NULL
;
53 CreateSessionMsg
->ClientId
.UniqueProcess
= NULL
;
56 /* Find a subsystem responsible for this session */
57 SmpGetProcessMuSessionId(ProcessInformation
->ProcessHandle
, &MuSessionId
);
58 if (!SmpCheckDuplicateMuSessionId(MuSessionId
))
60 NtClose(ProcessInformation
->ProcessHandle
);
61 NtClose(ProcessInformation
->ThreadHandle
);
62 DPRINT1("SMSS: CreateSession status=%x\n", STATUS_OBJECT_NAME_NOT_FOUND
);
63 return STATUS_OBJECT_NAME_NOT_FOUND
;
66 /* Find the subsystem we have for this initial process */
67 KnownSubsys
= SmpLocateKnownSubSysByType(MuSessionId
,
69 ImageInformation
.SubSystemType
);
72 /* Duplicate the process handle into the message */
73 Status
= NtDuplicateObject(NtCurrentProcess(),
74 ProcessInformation
->ProcessHandle
,
75 KnownSubsys
->ProcessHandle
,
76 &CreateSessionMsg
->ProcessInfo
.ProcessHandle
,
80 if (NT_SUCCESS(Status
))
82 /* Duplicate the thread handle into the message */
83 Status
= NtDuplicateObject(NtCurrentProcess(),
84 ProcessInformation
->ThreadHandle
,
85 KnownSubsys
->ProcessHandle
,
86 &CreateSessionMsg
->ProcessInfo
.ThreadHandle
,
90 if (!NT_SUCCESS(Status
))
92 /* Close everything on failure */
93 NtClose(ProcessInformation
->ProcessHandle
);
94 NtClose(ProcessInformation
->ThreadHandle
);
95 SmpDereferenceSubsystem(KnownSubsys
);
96 DbgPrint("SmpSbCreateSession: NtDuplicateObject (Thread) Failed %lx\n", Status
);
100 /* Close the original handles as they are no longer needed */
101 NtClose(ProcessInformation
->ProcessHandle
);
102 NtClose(ProcessInformation
->ThreadHandle
);
104 /* Finally, allocate a new SMSS session ID for this session */
105 SessionId
= SmpAllocateSessionId(KnownSubsys
, OtherSubsystem
);
106 CreateSessionMsg
->SessionId
= SessionId
;
108 /* Fill out the LPC message header and send it to the client! */
109 SbApiMsg
.ApiNumber
= SbpCreateSession
;
110 SbApiMsg
.h
.u2
.ZeroInit
= 0;
111 SbApiMsg
.h
.u1
.s1
.DataLength
= sizeof(SB_CREATE_SESSION_MSG
) + 8;
112 SbApiMsg
.h
.u1
.s1
.TotalLength
= sizeof(SbApiMsg
);
113 Status
= NtRequestWaitReplyPort(KnownSubsys
->SbApiPort
,
116 if (!NT_SUCCESS(Status
))
119 DPRINT1("SmpSbCreateSession: NtRequestWaitReply Failed %lx\n", Status
);
123 /* If the API succeeded, get the result value from the LPC */
124 Status
= SbApiMsg
.ReturnValue
;
127 /* Delete the session on any kind of failure */
128 if (!NT_SUCCESS(Status
)) SmpDeleteSession(SessionId
);
132 /* Close the handles on failure */
133 DPRINT1("SmpSbCreateSession: NtDuplicateObject (Process) Failed %lx\n", Status
);
134 NtClose(ProcessInformation
->ProcessHandle
);
135 NtClose(ProcessInformation
->ThreadHandle
);
138 /* Dereference the subsystem and return the status of the LPC call */
139 SmpDereferenceSubsystem(KnownSubsys
);
143 /* If we don't yet have a subsystem, only native images can be launched */
144 if (ProcessInformation
->ImageInformation
.SubSystemType
!= IMAGE_SUBSYSTEM_NATIVE
)
147 DPRINT1("SMSS: %s SubSystem has not been started.\n",
148 SmpSubSystemNames
[ProcessInformation
->ImageInformation
.SubSystemType
]);
149 Status
= STATUS_UNSUCCESSFUL
;
150 NtClose(ProcessInformation
->ProcessHandle
);
151 NtClose(ProcessInformation
->ThreadHandle
);
156 /* This code handles debug applications, but it seems vestigial... */
157 if ((*(ULONGLONG
)&CreateSessionMsg
.ClientId
) && (SmpDbgSsLoaded
))
159 Process
= RtlAllocateHeap(SmpHeap
, SmBaseTag
, sizeof(SMP_PROCESS
));
162 DPRINT1("Unable to initialize debugging for Native App %lx.%lx -- out of memory\n",
163 ProcessInformation
->ClientId
.UniqueProcess
,
164 ProcessInformation
->ClientId
.UniqueThread
);
165 NtClose(ProcessInformation
->ProcessHandle
);
166 NtClose(ProcessInformation
->ThreadHandle
);
167 return STATUS_NO_MEMORY
;
170 Process
->DbgClientId
= CreateSessionMsg
->ClientId
;
171 Process
->ClientId
= ProcessInformation
->ClientId
;
172 InsertHeadList(&NativeProcessList
, &Process
->Entry
);
173 DPRINT1("Native Debug App %lx.%lx\n", Process
->ClientId
.UniqueProcess
, Process
->ClientId
.UniqueThread
);
175 Status
= NtSetInformationProcess(ProcessInformation
->ProcessHandle
, 7, &SmpDebugPort
, 4);
176 ASSERT(NT_SUCCESS(Status
));
180 /* This is a native application being started as the initial command */
181 DPRINT1("Subsystem active, starting thread\n");
182 NtClose(ProcessInformation
->ProcessHandle
);
183 NtResumeThread(ProcessInformation
->ThreadHandle
, NULL
);
184 NtClose(ProcessInformation
->ThreadHandle
);
185 return STATUS_SUCCESS
;