235 lines
4.5 KiB
C
235 lines
4.5 KiB
C
/*++
|
||
|
||
Copyright (c) 1989 Microsoft Corporation
|
||
|
||
Module Name:
|
||
|
||
smsmapi.c
|
||
|
||
Abstract:
|
||
|
||
Implementation of Session Manager Sm APIs.
|
||
|
||
Author:
|
||
|
||
Mark Lucovsky (markl) 04-Oct-1989
|
||
|
||
Revision History:
|
||
|
||
--*/
|
||
|
||
#include "smsrvp.h"
|
||
|
||
|
||
NTSTATUS
|
||
SmpCreateForeignSession(
|
||
IN PSMAPIMSG SmApiMsg,
|
||
IN PSMP_CLIENT_CONTEXT CallingClient,
|
||
IN HANDLE CallPort
|
||
)
|
||
{
|
||
UNREFERENCED_PARAMETER (SmApiMsg);
|
||
UNREFERENCED_PARAMETER (CallingClient);
|
||
UNREFERENCED_PARAMETER (CallPort);
|
||
|
||
return STATUS_NOT_IMPLEMENTED;
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
NTSTATUS
|
||
SmpSessionComplete(
|
||
IN PSMAPIMSG SmApiMsg,
|
||
IN PSMP_CLIENT_CONTEXT CallingClient,
|
||
IN HANDLE CallPort
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This API is called by a subsystem to report that a session is
|
||
complete. A check is made to ensure that the calling subsystem
|
||
owns the completed session. If so then the session is deleted.
|
||
|
||
Arguments:
|
||
|
||
SmApiMsg - Supplies the API message.
|
||
|
||
CallingClient - Supplies the address of the context block for the calling
|
||
client.
|
||
|
||
CallPort - The port over which the call was received.
|
||
|
||
Return Value:
|
||
|
||
NTSTATUS.
|
||
|
||
--*/
|
||
|
||
{
|
||
PSMPSESSION Session;
|
||
PSMSESSIONCOMPLETE args;
|
||
NTSTATUS st;
|
||
|
||
UNREFERENCED_PARAMETER (CallPort);
|
||
|
||
args = &SmApiMsg->u.SessionComplete;
|
||
|
||
RtlEnterCriticalSection(&SmpSessionListLock);
|
||
|
||
Session = SmpSessionIdToSession(args->SessionId);
|
||
|
||
RtlLeaveCriticalSection(&SmpSessionListLock);
|
||
|
||
//
|
||
// If a session is found, then ensure that calling subsystem is its
|
||
// owner.
|
||
//
|
||
|
||
if ( Session ) {
|
||
|
||
if ( Session->OwningSubsystem == CallingClient->KnownSubSys ) {
|
||
|
||
SmpDeleteSession(args->SessionId);
|
||
st = STATUS_SUCCESS;
|
||
|
||
} else {
|
||
|
||
st = STATUS_INVALID_PARAMETER;
|
||
|
||
}
|
||
|
||
} else {
|
||
|
||
st = STATUS_INVALID_PARAMETER;
|
||
|
||
}
|
||
|
||
return st;
|
||
}
|
||
|
||
|
||
NTSTATUS
|
||
SmpTerminateForeignSession(
|
||
IN PSMAPIMSG SmApiMsg,
|
||
IN PSMP_CLIENT_CONTEXT CallingClient,
|
||
IN HANDLE CallPort
|
||
)
|
||
{
|
||
UNREFERENCED_PARAMETER (SmApiMsg);
|
||
UNREFERENCED_PARAMETER (CallingClient);
|
||
UNREFERENCED_PARAMETER (CallPort);
|
||
|
||
return STATUS_NOT_IMPLEMENTED;
|
||
}
|
||
|
||
|
||
|
||
|
||
NTSTATUS
|
||
SmpExecPgm(
|
||
IN PSMAPIMSG SmApiMsg,
|
||
IN PSMP_CLIENT_CONTEXT CallingClient,
|
||
IN HANDLE CallPort
|
||
)
|
||
{
|
||
NTSTATUS st;
|
||
HANDLE SourceProcess;
|
||
OBJECT_ATTRIBUTES ObjectAttributes;
|
||
PSMEXECPGM args;
|
||
RTL_USER_PROCESS_INFORMATION ProcessInformation;
|
||
PCLIENT_ID DebugUiClientId;
|
||
|
||
UNREFERENCED_PARAMETER (CallingClient);
|
||
UNREFERENCED_PARAMETER (CallPort);
|
||
|
||
//
|
||
// Open a handle to the calling process so the
|
||
// handles that it is passing can be duplicated.
|
||
//
|
||
|
||
InitializeObjectAttributes( &ObjectAttributes, NULL, 0, NULL, NULL );
|
||
st = NtOpenProcess(
|
||
&SourceProcess,
|
||
PROCESS_DUP_HANDLE,
|
||
&ObjectAttributes,
|
||
&SmApiMsg->h.ClientId
|
||
);
|
||
|
||
if (!NT_SUCCESS(st) ) {
|
||
DbgPrint("SmExecPgm: NtOpenProcess Failed %lx\n",st);
|
||
return st;
|
||
}
|
||
|
||
args = &SmApiMsg->u.ExecPgm;
|
||
|
||
ProcessInformation = args->ProcessInformation;
|
||
|
||
//
|
||
// Get all handles in our table.
|
||
//
|
||
|
||
st = NtDuplicateObject(
|
||
SourceProcess,
|
||
args->ProcessInformation.Process,
|
||
NtCurrentProcess(),
|
||
&ProcessInformation.Process,
|
||
PROCESS_ALL_ACCESS,
|
||
0,
|
||
0
|
||
);
|
||
|
||
if ( !NT_SUCCESS(st) ) {
|
||
NtClose(SourceProcess);
|
||
DbgPrint("SmExecPgm: NtDuplicateObject (Process) Failed %lx\n",st);
|
||
return st;
|
||
}
|
||
|
||
st = NtDuplicateObject(
|
||
SourceProcess,
|
||
args->ProcessInformation.Thread,
|
||
NtCurrentProcess(),
|
||
&ProcessInformation.Thread,
|
||
THREAD_ALL_ACCESS,
|
||
0,
|
||
0
|
||
);
|
||
|
||
if ( !NT_SUCCESS(st) ) {
|
||
NtClose(ProcessInformation.Process);
|
||
NtClose(SourceProcess);
|
||
DbgPrint("SmExecPgm: NtDuplicateObject (Thread) Failed %lx\n",st);
|
||
return st;
|
||
}
|
||
|
||
//
|
||
// Done getting the handles, so close our handle to the calling
|
||
// process and call the appropriate subsystem to start the process.
|
||
//
|
||
|
||
NtClose(SourceProcess);
|
||
|
||
//
|
||
// All handles passed are closed by SmpSbCreateSession.
|
||
//
|
||
|
||
if ( args->DebugFlag ) {
|
||
DebugUiClientId = &SmApiMsg->h.ClientId;
|
||
} else {
|
||
DebugUiClientId = NULL;
|
||
}
|
||
|
||
st = SmpSbCreateSession(
|
||
NULL,
|
||
NULL,
|
||
&ProcessInformation,
|
||
0L,
|
||
DebugUiClientId
|
||
);
|
||
|
||
return st;
|
||
}
|