Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

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_)