/*++ 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; }