1 /* 2 * PROJECT: ReactOS Windows-Compatible Session Manager 3 * LICENSE: BSD 2-Clause License 4 * FILE: lib/smlib/smclient.c 5 * PURPOSE: SMSS Client Library Stubs for calling SM APIs from a client 6 * PROGRAMMERS: Alex Ionescu 7 */ 8 9 /* INCLUDES *******************************************************************/ 10 11 #include "precomp.h" 12 #include <sm/smmsg.h> // To go in precomp.h after 13 14 #define NDEBUG 15 #include <debug.h> 16 17 /* FUNCTIONS ******************************************************************/ 18 19 NTSTATUS 20 NTAPI 21 SmExecPgm(IN HANDLE SmApiPort, 22 IN PRTL_USER_PROCESS_INFORMATION ProcessInformation, 23 IN BOOLEAN DebugFlag) 24 { 25 NTSTATUS Status; 26 SM_API_MSG SmApiMsg; 27 28 #if 0 //def _WIN64 // You can take care of this Timo 29 /* 64-bit SMSS needs to talk to 32-bit processes so do the LPC conversion */ 30 if (SmpIsWow64Process()) 31 { 32 return SmpWow64ExecPgm(SmApiPort, ProcessInformation, DebugFlag); 33 } 34 #endif 35 36 /* Initialize the generic LPC header */ 37 SmApiMsg.h.u2.ZeroInit = 0; 38 SmApiMsg.h.u1.s1.DataLength = sizeof(SM_EXEC_PGM_MSG) + 8; 39 SmApiMsg.h.u1.s1.TotalLength = sizeof(SmApiMsg); 40 41 /* Initialize this specific API's parameters */ 42 SmApiMsg.ApiNumber = SmpExecPgmApi; 43 RtlCopyMemory(&SmApiMsg.u.ExecPgm.ProcessInformation, 44 ProcessInformation, 45 sizeof(SmApiMsg.u.ExecPgm.ProcessInformation)); 46 SmApiMsg.u.ExecPgm.DebugFlag = DebugFlag; 47 48 /* Send the message to SMSS */ 49 Status = NtRequestWaitReplyPort(SmApiPort, &SmApiMsg.h, &SmApiMsg.h); 50 if (!NT_SUCCESS(Status)) 51 { 52 DPRINT1("SmExecPgm: NtRequestWaitReply Failed %lx\n", Status); 53 } 54 else 55 { 56 /* Upon success, we use the API's return value */ 57 Status = SmApiMsg.ReturnValue; 58 } 59 60 /* Close the handles that the parent passed in and return status */ 61 NtClose(ProcessInformation->ProcessHandle); 62 NtClose(ProcessInformation->ThreadHandle); 63 return Status; 64 } 65 66 NTSTATUS 67 NTAPI 68 SmConnectToSm(IN PUNICODE_STRING SbApiPortName, 69 IN HANDLE SbApiPort, 70 IN ULONG ImageType, 71 OUT PHANDLE SmApiPort) 72 { 73 NTSTATUS Status; 74 SB_CONNECTION_INFO ConnectInfo; 75 UNICODE_STRING PortName; 76 SECURITY_QUALITY_OF_SERVICE SecurityQos; 77 ULONG ConnectInfoLength = sizeof(ConnectInfo); 78 79 /* Setup the QoS structure */ 80 SecurityQos.ImpersonationLevel = SecurityIdentification; 81 SecurityQos.ContextTrackingMode = SECURITY_DYNAMIC_TRACKING; 82 SecurityQos.EffectiveOnly = TRUE; 83 84 /* Set the SM API port name */ 85 RtlInitUnicodeString(&PortName, L"\\SmApiPort"); 86 87 /* Check if this is a client connecting to SMSS, or SMSS to itself */ 88 if (SbApiPortName) 89 { 90 /* A client SB port as well as an image type must be present */ 91 if (!(SbApiPort) || !(ImageType)) return STATUS_INVALID_PARAMETER_MIX; 92 93 /* Copy the client port name, and NULL-terminate it */ 94 RtlCopyMemory(ConnectInfo.SbApiPortName, 95 SbApiPortName->Buffer, 96 SbApiPortName->Length); 97 ConnectInfo.SbApiPortName[SbApiPortName->Length / 98 sizeof(WCHAR)] = UNICODE_NULL; 99 100 /* Save the subsystem type */ 101 ConnectInfo.SubsystemType = ImageType; 102 } 103 else 104 { 105 /* No client port, and the subsystem type is not set */ 106 ConnectInfo.SbApiPortName[0] = UNICODE_NULL; 107 ConnectInfo.SubsystemType = IMAGE_SUBSYSTEM_UNKNOWN; 108 } 109 110 /* Connect to SMSS and exchange connection information */ 111 Status = NtConnectPort(SmApiPort, 112 &PortName, 113 &SecurityQos, 114 NULL, 115 NULL, 116 NULL, 117 &ConnectInfo, 118 &ConnectInfoLength); 119 if (!NT_SUCCESS(Status)) 120 { 121 DPRINT1("SmConnectToSm: Connect to Sm failed %lx\n", Status); 122 } 123 else 124 { 125 /* Treat a warning or informational status as success */ 126 Status = STATUS_SUCCESS; 127 } 128 129 /* Return if the connection was successful or not */ 130 return Status; 131 } 132 133 NTSTATUS 134 NTAPI 135 SmSessionComplete(IN HANDLE SmApiPort, 136 IN ULONG SessionId, 137 IN NTSTATUS SessionStatus) 138 { 139 NTSTATUS Status; 140 SM_API_MSG ApiMessage; 141 PSM_SESSION_COMPLETE_MSG SessionComplete = &ApiMessage.u.SessionComplete; 142 143 /* Set the message data */ 144 SessionComplete->SessionId = SessionId; 145 SessionComplete->SessionStatus = SessionStatus; 146 147 /* Set the API Message Port Message header */ 148 ApiMessage.ApiNumber = SmpSessionCompleteApi; 149 ApiMessage.h.u1.s1.DataLength = sizeof(SM_SESSION_COMPLETE_MSG) + 8; 150 ApiMessage.h.u1.s1.TotalLength = sizeof(SM_API_MSG); 151 ApiMessage.h.u2.ZeroInit = 0; 152 153 /* Sent the message and wait for a reply */ 154 Status = NtRequestWaitReplyPort(SmApiPort, 155 &ApiMessage.h, 156 &ApiMessage.h); 157 if (NT_SUCCESS(Status)) 158 { 159 /* Return the real status */ 160 Status = ApiMessage.ReturnValue; 161 } 162 else 163 { 164 DPRINT1("SmCompleteSession: NtRequestWaitReply failed\n"); 165 } 166 167 /* Return status */ 168 return Status; 169 } 170