https://git.reactos.org/?p=reactos.git;a=commitdiff;h=9f48c6923173808c9f2184a22fc01a98defb5a5b

commit 9f48c6923173808c9f2184a22fc01a98defb5a5b
Author:     Hermès Bélusca-Maïto <[email protected]>
AuthorDate: Wed Oct 26 17:35:03 2022 +0200
Commit:     Hermès Bélusca-Maïto <[email protected]>
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

Reply via email to