https://git.reactos.org/?p=reactos.git;a=commitdiff;h=9f48c6923173808c9f218…
commit 9f48c6923173808c9f2184a22fc01a98defb5a5b
Author: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
AuthorDate: Wed Oct 26 17:35:03 2022 +0200
Commit: Hermès Bélusca-Maïto <hermes.belusca-maito(a)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