2012-01-30 02:10:39 +00:00
|
|
|
/*
|
|
|
|
* PROJECT: ReactOS Windows-Compatible Session Manager
|
|
|
|
* LICENSE: BSD 2-Clause License
|
2015-09-18 10:13:50 +00:00
|
|
|
* FILE: base/system/smss/smsbapi.c
|
2012-01-30 02:10:39 +00:00
|
|
|
* PURPOSE: Main SMSS Code
|
|
|
|
* PROGRAMMERS: Alex Ionescu
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* INCLUDES *******************************************************************/
|
|
|
|
|
|
|
|
#include "smss.h"
|
2014-01-13 13:16:07 +00:00
|
|
|
|
2012-01-30 02:10:39 +00:00
|
|
|
#define NDEBUG
|
2013-01-24 23:00:42 +00:00
|
|
|
#include <debug.h>
|
2012-01-30 02:10:39 +00:00
|
|
|
|
|
|
|
/* GLOBALS ********************************************************************/
|
|
|
|
|
2022-10-23 17:59:08 +00:00
|
|
|
#if DBG
|
|
|
|
const PCSTR SmpSubSystemNames[] =
|
2012-02-09 00:07:36 +00:00
|
|
|
{
|
|
|
|
"Unknown",
|
|
|
|
"Native",
|
2022-10-23 17:59:08 +00:00
|
|
|
"Windows GUI",
|
|
|
|
"Windows CUI",
|
|
|
|
NULL,
|
2022-11-08 23:05:13 +00:00
|
|
|
"OS/2 CUI",
|
2022-10-23 17:59:08 +00:00
|
|
|
NULL,
|
|
|
|
"Posix CUI"
|
2012-02-09 00:07:36 +00:00
|
|
|
};
|
2022-10-23 17:59:08 +00:00
|
|
|
#endif
|
2012-02-09 00:07:36 +00:00
|
|
|
|
2012-01-30 02:10:39 +00:00
|
|
|
/* FUNCTIONS ******************************************************************/
|
2012-02-09 00:07:36 +00:00
|
|
|
|
|
|
|
NTSTATUS
|
|
|
|
NTAPI
|
|
|
|
SmpSbCreateSession(IN PVOID Reserved,
|
|
|
|
IN PSMP_SUBSYSTEM OtherSubsystem,
|
|
|
|
IN PRTL_USER_PROCESS_INFORMATION ProcessInformation,
|
2022-11-13 00:47:26 +00:00
|
|
|
IN ULONG DbgSessionId,
|
|
|
|
IN PCLIENT_ID DbgUiClientId)
|
2012-02-09 00:07:36 +00:00
|
|
|
{
|
|
|
|
NTSTATUS Status;
|
2022-10-23 17:59:08 +00:00
|
|
|
ULONG SubSystemType = ProcessInformation->ImageInformation.SubSystemType;
|
2022-11-13 00:47:26 +00:00
|
|
|
ULONG MuSessionId;
|
2012-02-09 00:07:36 +00:00
|
|
|
ULONG SessionId;
|
2022-11-13 00:47:26 +00:00
|
|
|
PSMP_SUBSYSTEM KnownSubsys;
|
|
|
|
SB_API_MSG SbApiMsg = {0};
|
|
|
|
PSB_CREATE_SESSION_MSG CreateSessionMsg = &SbApiMsg.u.CreateSession;
|
2012-02-09 00:07:36 +00:00
|
|
|
|
|
|
|
/* Write out the create session message including its initial process */
|
|
|
|
CreateSessionMsg->ProcessInfo = *ProcessInformation;
|
2022-11-13 00:47:26 +00:00
|
|
|
CreateSessionMsg->DbgSessionId = DbgSessionId;
|
|
|
|
if (DbgUiClientId)
|
2012-02-09 00:07:36 +00:00
|
|
|
{
|
2022-11-13 00:47:26 +00:00
|
|
|
CreateSessionMsg->DbgUiClientId = *DbgUiClientId;
|
2012-02-09 00:07:36 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2022-11-13 00:47:26 +00:00
|
|
|
CreateSessionMsg->DbgUiClientId.UniqueThread = NULL;
|
|
|
|
CreateSessionMsg->DbgUiClientId.UniqueProcess = NULL;
|
2012-02-09 00:07:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Find a subsystem responsible for this session */
|
|
|
|
SmpGetProcessMuSessionId(ProcessInformation->ProcessHandle, &MuSessionId);
|
|
|
|
if (!SmpCheckDuplicateMuSessionId(MuSessionId))
|
|
|
|
{
|
|
|
|
NtClose(ProcessInformation->ProcessHandle);
|
|
|
|
NtClose(ProcessInformation->ThreadHandle);
|
|
|
|
DPRINT1("SMSS: CreateSession status=%x\n", STATUS_OBJECT_NAME_NOT_FOUND);
|
|
|
|
return STATUS_OBJECT_NAME_NOT_FOUND;
|
|
|
|
}
|
|
|
|
|
2022-11-13 00:47:26 +00:00
|
|
|
/* Find the subsystem suitable for this initial process */
|
2022-10-23 17:59:08 +00:00
|
|
|
KnownSubsys = SmpLocateKnownSubSysByType(MuSessionId, SubSystemType);
|
2012-02-09 00:07:36 +00:00
|
|
|
if (KnownSubsys)
|
|
|
|
{
|
|
|
|
/* Duplicate the process handle into the message */
|
|
|
|
Status = NtDuplicateObject(NtCurrentProcess(),
|
|
|
|
ProcessInformation->ProcessHandle,
|
|
|
|
KnownSubsys->ProcessHandle,
|
|
|
|
&CreateSessionMsg->ProcessInfo.ProcessHandle,
|
|
|
|
PROCESS_ALL_ACCESS,
|
|
|
|
0,
|
|
|
|
0);
|
|
|
|
if (NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
/* Duplicate the thread handle into the message */
|
|
|
|
Status = NtDuplicateObject(NtCurrentProcess(),
|
|
|
|
ProcessInformation->ThreadHandle,
|
|
|
|
KnownSubsys->ProcessHandle,
|
|
|
|
&CreateSessionMsg->ProcessInfo.ThreadHandle,
|
|
|
|
THREAD_ALL_ACCESS,
|
|
|
|
0,
|
|
|
|
0);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
/* Close everything on failure */
|
|
|
|
NtClose(ProcessInformation->ProcessHandle);
|
|
|
|
NtClose(ProcessInformation->ThreadHandle);
|
|
|
|
SmpDereferenceSubsystem(KnownSubsys);
|
2020-04-30 16:42:16 +00:00
|
|
|
DPRINT1("SmpSbCreateSession: NtDuplicateObject (Thread) Failed %lx\n", Status);
|
2012-02-09 00:07:36 +00:00
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Close the original handles as they are no longer needed */
|
|
|
|
NtClose(ProcessInformation->ProcessHandle);
|
|
|
|
NtClose(ProcessInformation->ThreadHandle);
|
|
|
|
|
|
|
|
/* Finally, allocate a new SMSS session ID for this session */
|
|
|
|
SessionId = SmpAllocateSessionId(KnownSubsys, OtherSubsystem);
|
|
|
|
CreateSessionMsg->SessionId = SessionId;
|
|
|
|
|
|
|
|
/* Fill out the LPC message header and send it to the client! */
|
|
|
|
SbApiMsg.ApiNumber = SbpCreateSession;
|
|
|
|
SbApiMsg.h.u2.ZeroInit = 0;
|
|
|
|
SbApiMsg.h.u1.s1.DataLength = sizeof(SB_CREATE_SESSION_MSG) + 8;
|
|
|
|
SbApiMsg.h.u1.s1.TotalLength = sizeof(SbApiMsg);
|
|
|
|
Status = NtRequestWaitReplyPort(KnownSubsys->SbApiPort,
|
|
|
|
&SbApiMsg.h,
|
|
|
|
&SbApiMsg.h);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
/* Bail out */
|
|
|
|
DPRINT1("SmpSbCreateSession: NtRequestWaitReply Failed %lx\n", Status);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* If the API succeeded, get the result value from the LPC */
|
|
|
|
Status = SbApiMsg.ReturnValue;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Delete the session on any kind of failure */
|
|
|
|
if (!NT_SUCCESS(Status)) SmpDeleteSession(SessionId);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Close the handles on failure */
|
|
|
|
DPRINT1("SmpSbCreateSession: NtDuplicateObject (Process) Failed %lx\n", Status);
|
|
|
|
NtClose(ProcessInformation->ProcessHandle);
|
|
|
|
NtClose(ProcessInformation->ThreadHandle);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Dereference the subsystem and return the status of the LPC call */
|
|
|
|
SmpDereferenceSubsystem(KnownSubsys);
|
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* If we don't yet have a subsystem, only native images can be launched */
|
2022-10-23 17:59:08 +00:00
|
|
|
if (SubSystemType != IMAGE_SUBSYSTEM_NATIVE)
|
2012-02-09 00:07:36 +00:00
|
|
|
{
|
|
|
|
/* Fail */
|
2022-10-23 17:59:08 +00:00
|
|
|
#if DBG
|
|
|
|
PCSTR SubSysName = NULL;
|
|
|
|
CHAR SubSysTypeName[sizeof("Type 0x")+8];
|
|
|
|
|
|
|
|
if (SubSystemType < RTL_NUMBER_OF(SmpSubSystemNames))
|
|
|
|
SubSysName = SmpSubSystemNames[SubSystemType];
|
|
|
|
if (!SubSysName)
|
|
|
|
{
|
|
|
|
SubSysName = SubSysTypeName;
|
2022-11-08 23:05:13 +00:00
|
|
|
sprintf(SubSysTypeName, "Type 0x%08lx", SubSystemType);
|
2022-10-23 17:59:08 +00:00
|
|
|
}
|
|
|
|
DPRINT1("SMSS: %s SubSystem not found (either not started or destroyed).\n", SubSysName);
|
|
|
|
#endif
|
2012-02-09 00:07:36 +00:00
|
|
|
Status = STATUS_UNSUCCESSFUL;
|
|
|
|
NtClose(ProcessInformation->ProcessHandle);
|
|
|
|
NtClose(ProcessInformation->ThreadHandle);
|
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
|
|
|
|
#if 0
|
2022-11-13 00:47:26 +00:00
|
|
|
/*
|
|
|
|
* This code is part of the LPC-based legacy debugging support for native
|
|
|
|
* applications, implemented with the debug client interface (DbgUi) and
|
|
|
|
* debug subsystem (DbgSs). It is now vestigial since WinXP+ and is here
|
|
|
|
* for informational purposes only.
|
|
|
|
*/
|
|
|
|
if ((*(ULONGLONG)&CreateSessionMsg.DbgUiClientId) && SmpDbgSsLoaded)
|
2012-02-09 00:07:36 +00:00
|
|
|
{
|
|
|
|
Process = RtlAllocateHeap(SmpHeap, SmBaseTag, sizeof(SMP_PROCESS));
|
|
|
|
if (!Process)
|
|
|
|
{
|
|
|
|
DPRINT1("Unable to initialize debugging for Native App %lx.%lx -- out of memory\n",
|
|
|
|
ProcessInformation->ClientId.UniqueProcess,
|
|
|
|
ProcessInformation->ClientId.UniqueThread);
|
|
|
|
NtClose(ProcessInformation->ProcessHandle);
|
|
|
|
NtClose(ProcessInformation->ThreadHandle);
|
|
|
|
return STATUS_NO_MEMORY;
|
|
|
|
}
|
|
|
|
|
2022-11-13 00:47:26 +00:00
|
|
|
Process->DbgUiClientId = CreateSessionMsg->DbgUiClientId;
|
2012-02-09 00:07:36 +00:00
|
|
|
Process->ClientId = ProcessInformation->ClientId;
|
|
|
|
InsertHeadList(&NativeProcessList, &Process->Entry);
|
2022-11-13 00:47:26 +00:00
|
|
|
DPRINT1("Native Debug App %lx.%lx\n",
|
|
|
|
Process->ClientId.UniqueProcess,
|
|
|
|
Process->ClientId.UniqueThread);
|
|
|
|
|
|
|
|
Status = NtSetInformationProcess(ProcessInformation->ProcessHandle,
|
|
|
|
ProcessDebugPort,
|
|
|
|
&SmpDebugPort,
|
|
|
|
sizeof(SmpDebugPort));
|
2012-02-09 00:07:36 +00:00
|
|
|
ASSERT(NT_SUCCESS(Status));
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/* This is a native application being started as the initial command */
|
2016-03-22 18:34:18 +00:00
|
|
|
DPRINT("Subsystem active, starting thread\n");
|
2012-02-09 00:07:36 +00:00
|
|
|
NtClose(ProcessInformation->ProcessHandle);
|
|
|
|
NtResumeThread(ProcessInformation->ThreadHandle, NULL);
|
|
|
|
NtClose(ProcessInformation->ThreadHandle);
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
}
|