https://git.reactos.org/?p=reactos.git;a=commitdiff;h=9f48c6923173808c9f2184...
commit 9f48c6923173808c9f2184a22fc01a98defb5a5b Author: Hermès Bélusca-Maïto hermes.belusca-maito@reactos.org AuthorDate: Wed Oct 26 17:35:03 2022 +0200 Commit: Hermès Bélusca-Maïto hermes.belusca-maito@reactos.org CommitDate: Tue Nov 8 17:41:02 2022 +0100
[SMLIB][SMSS] Implement SmLoadDeferedSubsystem() client and server-side. (#4821)
Loosely based on the deprecated ReactOS-specific SmExecuteProgram(). On server-side, we lookup into the list of deferred subsystems that has been initialized at init time.
Dedicated to Justin Miller (The_DarkFire) work on reviving the POSIX subsystem! --- base/system/smss/smloop.c | 70 ++++++++++++++++++++++++++++++----- base/system/smss/smss.h | 3 +- sdk/include/reactos/subsys/sm/smmsg.h | 6 +++ sdk/lib/smlib/smclient.c | 52 ++++++++++++++++++++++++++ 4 files changed, 121 insertions(+), 10 deletions(-)
diff --git a/base/system/smss/smloop.c b/base/system/smss/smloop.c index d44b6f026bc..ce5707bff73 100644 --- a/base/system/smss/smloop.c +++ b/base/system/smss/smloop.c @@ -26,10 +26,9 @@ typedef struct _SMP_CLIENT_CONTEXT typedef NTSTATUS (NTAPI *PSM_API_HANDLER)( - IN PSM_API_MSG SmApiMsg, - IN PSMP_CLIENT_CONTEXT ClientContext, - IN HANDLE SmApiPort -); + _In_ PSM_API_MSG SmApiMsg, + _In_ PSMP_CLIENT_CONTEXT ClientContext, + _In_ HANDLE SmApiPort);
volatile LONG SmTotalApiThreads; HANDLE SmUniqueProcessId; @@ -139,12 +138,65 @@ SmpExecPgm(IN PSM_API_MSG SmApiMsg,
NTSTATUS NTAPI -SmpLoadDeferedSubsystem(IN PSM_API_MSG SmApiMsg, - IN PSMP_CLIENT_CONTEXT ClientContext, - IN HANDLE SmApiPort) +SmpLoadDeferedSubsystem( + _In_ PSM_API_MSG SmApiMsg, + _In_ PSMP_CLIENT_CONTEXT ClientContext, + _In_ HANDLE SmApiPort) { - DPRINT1("%s is not yet implemented\n", __FUNCTION__); - return STATUS_NOT_IMPLEMENTED; + NTSTATUS Status = STATUS_OBJECT_NAME_NOT_FOUND; + PSM_LOAD_DEFERED_SUBSYSTEM_MSG SmLoadDefered = &SmApiMsg->u.LoadDefered; + UNICODE_STRING DeferedSubsystem; + ULONG MuSessionId; + PLIST_ENTRY NextEntry; + PSMP_REGISTRY_VALUE RegEntry; + + /* Validate DeferedSubsystem's length */ + if ((SmLoadDefered->Length <= 0) || + (SmLoadDefered->Length > sizeof(SmLoadDefered->Buffer))) + { + return STATUS_INVALID_PARAMETER; + } + + /* Get the name of the subsystem to start */ + DeferedSubsystem.Length = (USHORT)SmLoadDefered->Length; + DeferedSubsystem.MaximumLength = DeferedSubsystem.Length; + DeferedSubsystem.Buffer = SmLoadDefered->Buffer; + + /* Find a subsystem responsible for this session */ + SmpGetProcessMuSessionId(ClientContext->ProcessHandle, &MuSessionId); + if (!SmpCheckDuplicateMuSessionId(MuSessionId)) + { + DPRINT1("SMSS: Deferred subsystem load (%wZ) for MuSessionId %u, status=0x%x\n", + &DeferedSubsystem, MuSessionId, Status); + return Status; + } + + /* Now process the deferred subsystems list */ + for (NextEntry = SmpSubSystemsToDefer.Flink; + NextEntry != &SmpSubSystemsToDefer; + NextEntry = NextEntry->Flink) + { + /* Get each entry and check if it's the subsystem we are looking for */ + RegEntry = CONTAINING_RECORD(NextEntry, SMP_REGISTRY_VALUE, Entry); + if (RtlEqualUnicodeString(&RegEntry->Name, &DeferedSubsystem, TRUE)) + { + // TODO: One may want to extra-flag the command for + // specific POSIX or OS2 processing... + + /* Load the deferred subsystem */ + Status = SmpExecuteCommand(&RegEntry->Value, + MuSessionId, + NULL, + SMP_SUBSYSTEM_FLAG); + if (!NT_SUCCESS(Status)) + DPRINT1("SMSS: Subsystem execute failed (%wZ)\n", &RegEntry->Value); + + break; + } + } + + /* Return status */ + return Status; }
NTSTATUS diff --git a/base/system/smss/smss.h b/base/system/smss/smss.h index 7b2ad99e670..46f8dd18f87 100644 --- a/base/system/smss/smss.h +++ b/base/system/smss/smss.h @@ -91,9 +91,10 @@ extern UNICODE_STRING SmpSystemRoot; extern PWCHAR SmpDefaultEnvironment; extern UNICODE_STRING SmpDefaultLibPath; extern LIST_ENTRY SmpSetupExecuteList; +extern LIST_ENTRY SmpSubSystemList; extern LIST_ENTRY SmpSubSystemsToLoad; +extern LIST_ENTRY SmpSubSystemsToDefer; extern LIST_ENTRY SmpExecuteList; -extern LIST_ENTRY SmpSubSystemList; extern ULONG AttachedSessionId; extern BOOLEAN SmpDebug;
diff --git a/sdk/include/reactos/subsys/sm/smmsg.h b/sdk/include/reactos/subsys/sm/smmsg.h index e8f15b5a1a1..e72f0917fb2 100644 --- a/sdk/include/reactos/subsys/sm/smmsg.h +++ b/sdk/include/reactos/subsys/sm/smmsg.h @@ -295,6 +295,12 @@ SmExecPgm( _In_ PRTL_USER_PROCESS_INFORMATION ProcessInformation, _In_ BOOLEAN DebugFlag);
+NTSTATUS +NTAPI +SmLoadDeferedSubsystem( + _In_ HANDLE SmApiPort, + _In_ PUNICODE_STRING DeferedSubsystem); + NTSTATUS NTAPI SmStartCsr( diff --git a/sdk/lib/smlib/smclient.c b/sdk/lib/smlib/smclient.c index 58768f197bb..440ff4fe2e0 100644 --- a/sdk/lib/smlib/smclient.c +++ b/sdk/lib/smlib/smclient.c @@ -295,6 +295,58 @@ SmExecPgm( return Status; }
+/** + * @brief + * This function is used to make the SM start an environment + * subsystem server process. + * + * @param[in] SmApiPort + * Port handle returned by SmConnectToSm(). + * + * @param[in] DeferedSubsystem + * Name of the subsystem to start. This must be one of the subsystems + * listed by value's name in the SM registry key + * \Registry\SYSTEM\CurrentControlSet\Control\Session Manager\SubSystems + * (used by the SM to lookup the corresponding image name). + * Default valid names are: "Debug", "Windows", "Posix", "Os2". + * + * @return + * Success status as handed by the SM reply; otherwise a failure + * status code. + **/ +NTSTATUS +NTAPI +SmLoadDeferedSubsystem( + _In_ HANDLE SmApiPort, + _In_ PUNICODE_STRING DeferedSubsystem) +{ + SM_API_MSG SmApiMsg = {0}; + PSM_LOAD_DEFERED_SUBSYSTEM_MSG LoadDefered = &SmApiMsg.u.LoadDefered; + +#if 0 //def _WIN64 + /* 64-bit SMSS needs to talk to 32-bit processes so do the LPC conversion */ + if (SmpIsWow64Process()) + { + return SmpWow64LoadDeferedSubsystem(SmApiPort, DeferedSubsystem); + } +#endif + + /* Validate DeferedSubsystem's length */ + if (DeferedSubsystem->Length > sizeof(LoadDefered->Buffer)) + return STATUS_INVALID_PARAMETER; + + /* Set the message data */ + /* Buffer stores a counted non-NULL-terminated UNICODE string */ + LoadDefered->Length = DeferedSubsystem->Length; + RtlCopyMemory(LoadDefered->Buffer, + DeferedSubsystem->Buffer, + DeferedSubsystem->Length); + + /* Send the message and wait for a reply */ + SmApiMsg.ApiNumber = SmpLoadDeferedSubsystemApi; + return SmSendMsgToSm(SmApiPort, &SmApiMsg); +} + /** * @brief * Requests the SM to create a new Terminal Services session