[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!
This commit is contained in:
Hermès Bélusca-Maïto 2022-10-26 17:35:03 +02:00
parent 8fea507d9b
commit 9f48c69231
No known key found for this signature in database
GPG key ID: 3B2539C65E7B93D0
4 changed files with 122 additions and 11 deletions

View file

@ -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