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 *******************************************************************/
16 /* GLOBALS ********************************************************************/
18 PCHAR SmpSubSystemNames
[] =
27 /* FUNCTIONS ******************************************************************/
31 SmpSbCreateSession(IN PVOID Reserved
,
32 IN PSMP_SUBSYSTEM OtherSubsystem
,
33 IN PRTL_USER_PROCESS_INFORMATION ProcessInformation
,
35 IN PCLIENT_ID DbgClientId
)
38 PSMP_SUBSYSTEM KnownSubsys
;
41 PSB_CREATE_SESSION_MSG CreateSessionMsg
;
43 /* Write out the create session message including its initial process */
44 CreateSessionMsg
= &SbApiMsg
.CreateSession
;
45 CreateSessionMsg
->ProcessInfo
= *ProcessInformation
;
46 CreateSessionMsg
->MuSessionId
= MuSessionId
;
49 CreateSessionMsg
->ClientId
= *DbgClientId
;
53 CreateSessionMsg
->ClientId
.UniqueThread
= NULL
;
54 CreateSessionMsg
->ClientId
.UniqueProcess
= NULL
;
57 /* Find a subsystem responsible for this session */
58 SmpGetProcessMuSessionId(ProcessInformation
->ProcessHandle
, &MuSessionId
);
59 if (!SmpCheckDuplicateMuSessionId(MuSessionId
))
61 NtClose(ProcessInformation
->ProcessHandle
);
62 NtClose(ProcessInformation
->ThreadHandle
);
63 DPRINT1("SMSS: CreateSession status=%x\n", STATUS_OBJECT_NAME_NOT_FOUND
);
64 return STATUS_OBJECT_NAME_NOT_FOUND
;
67 /* Find the subsystem we have for this initial process */
68 KnownSubsys
= SmpLocateKnownSubSysByType(MuSessionId
,
70 ImageInformation
.SubSystemType
);
73 /* Duplicate the process handle into the message */
74 Status
= NtDuplicateObject(NtCurrentProcess(),
75 ProcessInformation
->ProcessHandle
,
76 KnownSubsys
->ProcessHandle
,
77 &CreateSessionMsg
->ProcessInfo
.ProcessHandle
,
81 if (NT_SUCCESS(Status
))
83 /* Duplicate the thread handle into the message */
84 Status
= NtDuplicateObject(NtCurrentProcess(),
85 ProcessInformation
->ThreadHandle
,
86 KnownSubsys
->ProcessHandle
,
87 &CreateSessionMsg
->ProcessInfo
.ThreadHandle
,
91 if (!NT_SUCCESS(Status
))
93 /* Close everything on failure */
94 NtClose(ProcessInformation
->ProcessHandle
);
95 NtClose(ProcessInformation
->ThreadHandle
);
96 SmpDereferenceSubsystem(KnownSubsys
);
97 DbgPrint("SmpSbCreateSession: NtDuplicateObject (Thread) Failed %lx\n", Status
);
101 /* Close the original handles as they are no longer needed */
102 NtClose(ProcessInformation
->ProcessHandle
);
103 NtClose(ProcessInformation
->ThreadHandle
);
105 /* Finally, allocate a new SMSS session ID for this session */
106 SessionId
= SmpAllocateSessionId(KnownSubsys
, OtherSubsystem
);
107 CreateSessionMsg
->SessionId
= SessionId
;
109 /* Fill out the LPC message header and send it to the client! */
110 SbApiMsg
.ApiNumber
= SbpCreateSession
;
111 SbApiMsg
.h
.u2
.ZeroInit
= 0;
112 SbApiMsg
.h
.u1
.s1
.DataLength
= sizeof(SB_CREATE_SESSION_MSG
) + 8;
113 SbApiMsg
.h
.u1
.s1
.TotalLength
= sizeof(SbApiMsg
);
114 Status
= NtRequestWaitReplyPort(KnownSubsys
->SbApiPort
,
117 if (!NT_SUCCESS(Status
))
120 DPRINT1("SmpSbCreateSession: NtRequestWaitReply Failed %lx\n", Status
);
124 /* If the API succeeded, get the result value from the LPC */
125 Status
= SbApiMsg
.ReturnValue
;
128 /* Delete the session on any kind of failure */
129 if (!NT_SUCCESS(Status
)) SmpDeleteSession(SessionId
);
133 /* Close the handles on failure */
134 DPRINT1("SmpSbCreateSession: NtDuplicateObject (Process) Failed %lx\n", Status
);
135 NtClose(ProcessInformation
->ProcessHandle
);
136 NtClose(ProcessInformation
->ThreadHandle
);
139 /* Dereference the subsystem and return the status of the LPC call */
140 SmpDereferenceSubsystem(KnownSubsys
);
144 /* If we don't yet have a subsystem, only native images can be launched */
145 if (ProcessInformation
->ImageInformation
.SubSystemType
!= IMAGE_SUBSYSTEM_NATIVE
)
148 DPRINT1("SMSS: %s SubSystem has not been started.\n",
149 SmpSubSystemNames
[ProcessInformation
->ImageInformation
.SubSystemType
]);
150 Status
= STATUS_UNSUCCESSFUL
;
151 NtClose(ProcessInformation
->ProcessHandle
);
152 NtClose(ProcessInformation
->ThreadHandle
);
157 /* This code handles debug applications, but it seems vestigial... */
158 if ((*(ULONGLONG
)&CreateSessionMsg
.ClientId
) && (SmpDbgSsLoaded
))
160 Process
= RtlAllocateHeap(SmpHeap
, SmBaseTag
, sizeof(SMP_PROCESS
));
163 DPRINT1("Unable to initialize debugging for Native App %lx.%lx -- out of memory\n",
164 ProcessInformation
->ClientId
.UniqueProcess
,
165 ProcessInformation
->ClientId
.UniqueThread
);
166 NtClose(ProcessInformation
->ProcessHandle
);
167 NtClose(ProcessInformation
->ThreadHandle
);
168 return STATUS_NO_MEMORY
;
171 Process
->DbgClientId
= CreateSessionMsg
->ClientId
;
172 Process
->ClientId
= ProcessInformation
->ClientId
;
173 InsertHeadList(&NativeProcessList
, &Process
->Entry
);
174 DPRINT1("Native Debug App %lx.%lx\n", Process
->ClientId
.UniqueProcess
, Process
->ClientId
.UniqueThread
);
176 Status
= NtSetInformationProcess(ProcessInformation
->ProcessHandle
, 7, &SmpDebugPort
, 4);
177 ASSERT(NT_SUCCESS(Status
));
181 /* This is a native application being started as the initial command */
182 DPRINT1("Subsystem active, starting thread\n");
183 NtClose(ProcessInformation
->ProcessHandle
);
184 NtResumeThread(ProcessInformation
->ThreadHandle
, NULL
);
185 NtClose(ProcessInformation
->ThreadHandle
);
186 return STATUS_SUCCESS
;