496 lines
12 KiB
496 lines
12 KiB
/*++
|
|
|
|
Copyright (c) 1989 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
sm6432.c
|
|
|
|
Abstract:
|
|
|
|
Session Manager Client Support APIs for Wow64 executable (32-bit images running
|
|
on Win64)
|
|
|
|
Author:
|
|
|
|
Samer Arafeh (samera) 20-Sep-2001
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
#if defined(_X86_)
|
|
|
|
/*
|
|
* Enable LPC port-messages to have compatible layout between the 32-bit and 64-bit worlds.
|
|
*/
|
|
#define USE_LPC6432 1
|
|
#define BUILD_WOW6432 1
|
|
|
|
#include "smdllp.h"
|
|
#include "smp6432.h"
|
|
#include <string.h>
|
|
|
|
|
|
|
|
NTSTATUS
|
|
SmpThunkUserProcessInfoTo64 (
|
|
IN PRTL_USER_PROCESS_INFORMATION UserProcessInformation32,
|
|
OUT PRTL_USER_PROCESS_INFORMATION64 UserProcessInformation64
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine thunks RTL_PROCESS_USER_INFORMATION structure from 32-bit
|
|
structure offsets in Win64 structure offsets.
|
|
|
|
Arguments:
|
|
|
|
UserProcessInformation32 - 32-bit Input structure.
|
|
|
|
UserProcessInformation64 - 64-bit Output structure allocated by the caller.
|
|
|
|
Return Value:
|
|
|
|
NTSTATUS.
|
|
|
|
--*/
|
|
|
|
{
|
|
NTSTATUS NtStatus = STATUS_SUCCESS;
|
|
|
|
if (ARGUMENT_PRESENT (UserProcessInformation32)) {
|
|
|
|
try {
|
|
|
|
UserProcessInformation64->Length = sizeof (RTL_USER_PROCESS_INFORMATION64);
|
|
UserProcessInformation64->Process = (LONGLONG)UserProcessInformation32->Process;
|
|
UserProcessInformation64->Thread = (LONGLONG)UserProcessInformation32->Thread;
|
|
UserProcessInformation64->ClientId.UniqueProcess = (ULONGLONG)UserProcessInformation32->ClientId.UniqueProcess;
|
|
UserProcessInformation64->ClientId.UniqueThread = (ULONGLONG)UserProcessInformation32->ClientId.UniqueThread;
|
|
|
|
UserProcessInformation64->ImageInformation.TransferAddress = (ULONGLONG)UserProcessInformation32->ImageInformation.TransferAddress;
|
|
UserProcessInformation64->ImageInformation.ZeroBits = UserProcessInformation32->ImageInformation.ZeroBits;
|
|
UserProcessInformation64->ImageInformation.MaximumStackSize = UserProcessInformation32->ImageInformation.MaximumStackSize;
|
|
UserProcessInformation64->ImageInformation.CommittedStackSize = UserProcessInformation32->ImageInformation.CommittedStackSize;
|
|
UserProcessInformation64->ImageInformation.SubSystemType = UserProcessInformation32->ImageInformation.SubSystemType;
|
|
UserProcessInformation64->ImageInformation.SubSystemVersion = UserProcessInformation32->ImageInformation.SubSystemVersion;
|
|
UserProcessInformation64->ImageInformation.GpValue = UserProcessInformation32->ImageInformation.GpValue;
|
|
UserProcessInformation64->ImageInformation.ImageCharacteristics = UserProcessInformation32->ImageInformation.ImageCharacteristics;
|
|
UserProcessInformation64->ImageInformation.DllCharacteristics = UserProcessInformation32->ImageInformation.DllCharacteristics;
|
|
UserProcessInformation64->ImageInformation.Machine = UserProcessInformation32->ImageInformation.Machine;
|
|
UserProcessInformation64->ImageInformation.ImageContainsCode = UserProcessInformation32->ImageInformation.ImageContainsCode;
|
|
UserProcessInformation64->ImageInformation.Spare1 = UserProcessInformation32->ImageInformation.Spare1;
|
|
UserProcessInformation64->ImageInformation.LoaderFlags = UserProcessInformation32->ImageInformation.LoaderFlags;
|
|
RtlCopyMemory (&UserProcessInformation64->ImageInformation.Reserved,
|
|
&UserProcessInformation32->ImageInformation.Reserved,
|
|
sizeof (UserProcessInformation32->ImageInformation.Reserved));
|
|
|
|
} except (EXCEPTION_EXECUTE_HANDLER) {
|
|
NtStatus = GetExceptionCode ();
|
|
}
|
|
} else {
|
|
|
|
UserProcessInformation64 = (PRTL_USER_PROCESS_INFORMATION64)UserProcessInformation32;
|
|
}
|
|
|
|
return NtStatus;
|
|
}
|
|
|
|
|
|
BOOLEAN
|
|
SmpIsWow64Process (
|
|
VOID
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine detects whether the currently executing process is running inside
|
|
Wow64. The routine caches the result.
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Value:
|
|
|
|
BOOLEAN.
|
|
|
|
--*/
|
|
|
|
{
|
|
NTSTATUS NtStatus;
|
|
PVOID Peb32;
|
|
static BOOLEAN RunningInsideWow64 = -1;
|
|
|
|
if (RunningInsideWow64 == (BOOLEAN)-1) {
|
|
|
|
NtStatus = NtQueryInformationProcess (
|
|
NtCurrentProcess (),
|
|
ProcessWow64Information,
|
|
&Peb32,
|
|
sizeof (Peb32),
|
|
NULL
|
|
);
|
|
|
|
if (NT_SUCCESS (NtStatus)) {
|
|
if (Peb32 != NULL) {
|
|
RunningInsideWow64 = TRUE;
|
|
} else {
|
|
RunningInsideWow64 = FALSE;
|
|
}
|
|
} else {
|
|
RunningInsideWow64 = FALSE;
|
|
}
|
|
}
|
|
|
|
return RunningInsideWow64;
|
|
}
|
|
|
|
|
|
|
|
NTSTATUS
|
|
SmpWow64ExecPgm(
|
|
IN HANDLE SmApiPort,
|
|
IN PRTL_USER_PROCESS_INFORMATION ProcessInformation32,
|
|
IN BOOLEAN DebugFlag
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine allows a process to start a process using the
|
|
facilities provided by the NT Session manager.
|
|
|
|
This function closes all handles passed to it.
|
|
|
|
Arguments:
|
|
|
|
SmApiPort - Supplies a handle to a communications port connected
|
|
to the Session Manager.
|
|
|
|
ProcessInformation32 - Supplies a process description as returned
|
|
by RtlCreateUserProcess.
|
|
|
|
DebugFlag - Supplies and optional parameter which if set indicates
|
|
that the caller wants to debug this process and act as its
|
|
debug user interface.
|
|
|
|
Return Value:
|
|
|
|
NSTATUS.
|
|
|
|
--*/
|
|
|
|
{
|
|
NTSTATUS st;
|
|
|
|
SMAPIMSG64 SmApiMsg;
|
|
PSMEXECPGM64 args;
|
|
RTL_USER_PROCESS_INFORMATION64 ProcessInformation64;
|
|
|
|
|
|
args = &SmApiMsg.u.ExecPgm;
|
|
|
|
st = SmpThunkUserProcessInfoTo64 (ProcessInformation32,
|
|
&ProcessInformation64);
|
|
if (NT_SUCCESS (st)) {
|
|
|
|
args->DebugFlag = DebugFlag;
|
|
|
|
SmApiMsg.ApiNumber = SmExecPgmApi;
|
|
SmApiMsg.h.u1.s1.DataLength = sizeof(*args) + 8;
|
|
SmApiMsg.h.u1.s1.TotalLength = sizeof(SmApiMsg);
|
|
SmApiMsg.h.u2.ZeroInit = 0L;
|
|
|
|
st = NtRequestWaitReplyPort(
|
|
SmApiPort,
|
|
(PPORT_MESSAGE) &SmApiMsg,
|
|
(PPORT_MESSAGE) &SmApiMsg
|
|
);
|
|
|
|
if ( NT_SUCCESS(st) ) {
|
|
st = SmApiMsg.ReturnedStatus;
|
|
} else {
|
|
KdPrint(("SmExecPgm: NtRequestWaitReply Failed %lx\n",st));
|
|
}
|
|
|
|
NtClose(ProcessInformation32->Process);
|
|
NtClose(ProcessInformation32->Thread);
|
|
}
|
|
|
|
return st;
|
|
}
|
|
|
|
|
|
NTSTATUS
|
|
SmpWow64LoadDeferedSubsystem(
|
|
IN HANDLE SmApiPort,
|
|
IN PUNICODE_STRING DeferedSubsystem
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine allows a process to start a defered subsystem.
|
|
|
|
Arguments:
|
|
|
|
SmApiPort - Supplies a handle to a communications port connected
|
|
to the Session Manager.
|
|
|
|
DeferedSubsystem - Supplies the name of the defered subsystem to load.
|
|
|
|
Return Value:
|
|
|
|
NSTATUS.
|
|
|
|
--*/
|
|
|
|
{
|
|
NTSTATUS st;
|
|
|
|
SMAPIMSG64 SmApiMsg;
|
|
PSMLOADDEFERED args;
|
|
|
|
if ( DeferedSubsystem->Length >> 1 > SMP_MAXIMUM_SUBSYSTEM_NAME ) {
|
|
return STATUS_INVALID_PARAMETER;
|
|
}
|
|
|
|
args = &SmApiMsg.u.LoadDefered;
|
|
args->SubsystemNameLength = DeferedSubsystem->Length;
|
|
|
|
RtlZeroMemory(args->SubsystemName, sizeof (args->SubsystemName));
|
|
RtlCopyMemory(args->SubsystemName,DeferedSubsystem->Buffer,DeferedSubsystem->Length);
|
|
|
|
SmApiMsg.ApiNumber = SmLoadDeferedSubsystemApi;
|
|
SmApiMsg.h.u1.s1.DataLength = sizeof(*args) + 8;
|
|
SmApiMsg.h.u1.s1.TotalLength = sizeof(SmApiMsg);
|
|
SmApiMsg.h.u2.ZeroInit = 0L;
|
|
|
|
st = NtRequestWaitReplyPort(
|
|
SmApiPort,
|
|
(PPORT_MESSAGE) &SmApiMsg,
|
|
(PPORT_MESSAGE) &SmApiMsg
|
|
);
|
|
|
|
if ( NT_SUCCESS(st) ) {
|
|
st = SmApiMsg.ReturnedStatus;
|
|
} else {
|
|
KdPrint(("SmExecPgm: NtRequestWaitReply Failed %lx\n",st));
|
|
}
|
|
|
|
return st;
|
|
|
|
}
|
|
|
|
|
|
NTSTATUS
|
|
SmpWow64SessionComplete(
|
|
IN HANDLE SmApiPort,
|
|
IN ULONG SessionId,
|
|
IN NTSTATUS CompletionStatus
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine is used to report completion of a session to
|
|
the NT Session manager.
|
|
|
|
Arguments:
|
|
|
|
SmApiPort - Supplies a handle to a communications port connected
|
|
to the Session Manager.
|
|
|
|
SessionId - Supplies the session id of the session which is now completed.
|
|
|
|
CompletionStatus - Supplies the completion status of the session.
|
|
|
|
Return Value:
|
|
|
|
NSTATUS.
|
|
|
|
--*/
|
|
|
|
{
|
|
NTSTATUS st;
|
|
|
|
SMAPIMSG64 SmApiMsg;
|
|
PSMSESSIONCOMPLETE args;
|
|
|
|
args = &SmApiMsg.u.SessionComplete;
|
|
|
|
args->SessionId = SessionId;
|
|
args->CompletionStatus = CompletionStatus;
|
|
|
|
SmApiMsg.ApiNumber = SmSessionCompleteApi;
|
|
SmApiMsg.h.u1.s1.DataLength = sizeof(*args) + 8;
|
|
SmApiMsg.h.u1.s1.TotalLength = sizeof(SmApiMsg);
|
|
SmApiMsg.h.u2.ZeroInit = 0L;
|
|
|
|
st = NtRequestWaitReplyPort(
|
|
SmApiPort,
|
|
(PPORT_MESSAGE) &SmApiMsg,
|
|
(PPORT_MESSAGE) &SmApiMsg
|
|
);
|
|
|
|
if ( NT_SUCCESS(st) ) {
|
|
st = SmApiMsg.ReturnedStatus;
|
|
} else {
|
|
KdPrint(("SmCompleteSession: NtRequestWaitReply Failed %lx\n",st));
|
|
}
|
|
|
|
return st;
|
|
}
|
|
|
|
|
|
NTSTATUS
|
|
SmpWow64StartCsr(
|
|
IN HANDLE SmApiPort,
|
|
OUT PULONG pMuSessionId,
|
|
IN PUNICODE_STRING InitialCommand,
|
|
OUT PULONG_PTR pInitialCommandProcessId,
|
|
OUT PULONG_PTR pWindowsSubSysProcessId
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine allows TERMSRV to start a new CSR.
|
|
|
|
Arguments:
|
|
|
|
SmApiPort - Supplies a handle to a communications port connected
|
|
to the Session Manager.
|
|
|
|
MuSessionId - Hydra Terminal Session Id to start CSR in.
|
|
|
|
InitialCommand - String for Initial Command (for debug)
|
|
|
|
pInitialCommandProcessId - pointer to Process Id of initial command.
|
|
|
|
pWindowsSubSysProcessId - pointer to Process Id of Windows subsystem.
|
|
|
|
Return Value:
|
|
|
|
NSTATUS.
|
|
|
|
--*/
|
|
|
|
{
|
|
NTSTATUS st;
|
|
|
|
SMAPIMSG64 SmApiMsg;
|
|
PSMSTARTCSR64 args;
|
|
|
|
args = &SmApiMsg.u.StartCsr;
|
|
|
|
args->MuSessionId = *pMuSessionId; //Sm will reassign the actuall sessionID
|
|
|
|
if ( InitialCommand &&
|
|
( InitialCommand->Length >> 1 > SMP_MAXIMUM_INITIAL_COMMAND ) ) {
|
|
return STATUS_INVALID_PARAMETER;
|
|
}
|
|
|
|
if ( !InitialCommand ) {
|
|
args->InitialCommandLength = 0;
|
|
}
|
|
else {
|
|
args->InitialCommandLength = InitialCommand->Length;
|
|
|
|
RtlZeroMemory(args->InitialCommand, sizeof (args->InitialCommand));
|
|
RtlCopyMemory(args->InitialCommand,InitialCommand->Buffer,InitialCommand->Length);
|
|
}
|
|
|
|
SmApiMsg.ApiNumber = SmStartCsrApi;
|
|
SmApiMsg.h.u1.s1.DataLength = sizeof(*args) + 8;
|
|
SmApiMsg.h.u1.s1.TotalLength = sizeof(SmApiMsg);
|
|
SmApiMsg.h.u2.ZeroInit = 0L;
|
|
|
|
st = NtRequestWaitReplyPort(
|
|
SmApiPort,
|
|
(PPORT_MESSAGE) &SmApiMsg,
|
|
(PPORT_MESSAGE) &SmApiMsg
|
|
);
|
|
|
|
if ( NT_SUCCESS(st) ) {
|
|
st = SmApiMsg.ReturnedStatus;
|
|
} else {
|
|
DbgPrint("SmStartCsr: NtRequestWaitReply Failed %lx\n",st);
|
|
}
|
|
|
|
*pInitialCommandProcessId = (ULONG)args->InitialCommandProcessId;
|
|
*pWindowsSubSysProcessId = (ULONG)args->WindowsSubSysProcessId;
|
|
*pMuSessionId = args->MuSessionId;
|
|
|
|
return st;
|
|
|
|
}
|
|
|
|
|
|
NTSTATUS
|
|
SmpWow64StopCsr(
|
|
IN HANDLE SmApiPort,
|
|
IN ULONG MuSessionId
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine allows TERMSRV to stop a CSR.
|
|
|
|
Arguments:
|
|
|
|
SmApiPort - Supplies a handle to a communications port connected
|
|
to the Session Manager.
|
|
|
|
MuSessionId - Terminal Server Session Id to stop
|
|
|
|
Return Value:
|
|
|
|
NSTATUS.
|
|
|
|
--*/
|
|
|
|
{
|
|
NTSTATUS st;
|
|
|
|
SMAPIMSG64 SmApiMsg;
|
|
PSMSTOPCSR args;
|
|
|
|
args = &SmApiMsg.u.StopCsr;
|
|
|
|
args->MuSessionId = MuSessionId;
|
|
|
|
SmApiMsg.ApiNumber = SmStopCsrApi;
|
|
SmApiMsg.h.u1.s1.DataLength = sizeof(*args) + 8;
|
|
SmApiMsg.h.u1.s1.TotalLength = sizeof(SmApiMsg);
|
|
SmApiMsg.h.u2.ZeroInit = 0L;
|
|
|
|
st = NtRequestWaitReplyPort(
|
|
SmApiPort,
|
|
(PPORT_MESSAGE) &SmApiMsg,
|
|
(PPORT_MESSAGE) &SmApiMsg
|
|
);
|
|
|
|
if ( NT_SUCCESS(st) ) {
|
|
st = SmApiMsg.ReturnedStatus;
|
|
} else {
|
|
DbgPrint("SmStopCsr: NtRequestWaitReply Failed %lx\n",st);
|
|
}
|
|
|
|
return st;
|
|
|
|
}
|
|
|
|
#endif // #if defined(_X86_)
|