ReactOS 0.4.15-dev-7961-gdcf9eb0
smclient.c
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS NT-Compatible Session Manager
3 * LICENSE: BSD 2-Clause License (https://spdx.org/licenses/BSD-2-Clause)
4 * PURPOSE: SMSS Client Library (SMLIB) Client Stubs
5 * COPYRIGHT: Copyright 2012-2013 Alex Ionescu <alex.ionescu@reactos.org>
6 * Copyright 2021 Hervé Poussineau <hpoussin@reactos.org>
7 * Copyright 2022 Hermès Bélusca-Maïto <hermes.belusca-maito@reactos.org>
8 */
9
10/* INCLUDES *******************************************************************/
11
12#include "precomp.h"
13
14#define NDEBUG
15#include <debug.h>
16
17/* FUNCTIONS ******************************************************************/
18
58 _In_opt_ PUNICODE_STRING SbApiPortName,
59 _In_opt_ HANDLE SbApiPort,
62{
66 SB_CONNECTION_INFO ConnectInfo = {0};
67 ULONG ConnectInfoLength = sizeof(ConnectInfo);
68
69 /* Setup the QoS structure */
72 SecurityQos.EffectiveOnly = TRUE;
73
74 /* Set the SM API port name */
75 RtlInitUnicodeString(&PortName, L"\\SmApiPort"); // SM_API_PORT_NAME
76
77 /* Check if this is a client connecting to SMSS, or SMSS to itself */
78 if (SbApiPortName)
79 {
80 /* A client SB port as well as an image type must be present */
81 if (!SbApiPort || (ImageType == IMAGE_SUBSYSTEM_UNKNOWN))
83
84 /* Validate SbApiPortName's length */
85 if (SbApiPortName->Length >= sizeof(ConnectInfo.SbApiPortName))
87
88 /* Copy the client port name, and NULL-terminate it */
89 RtlCopyMemory(ConnectInfo.SbApiPortName,
90 SbApiPortName->Buffer,
91 SbApiPortName->Length);
92 ConnectInfo.SbApiPortName[SbApiPortName->Length / sizeof(WCHAR)] = UNICODE_NULL;
93
94 /* Save the subsystem type */
95 ConnectInfo.SubsystemType = ImageType;
96 }
97 else
98 {
99 /* No client port, and the subsystem type is not set */
100 ConnectInfo.SbApiPortName[0] = UNICODE_NULL;
102 }
103
104 /* Connect to SMSS and exchange connection information */
106 &PortName,
107 &SecurityQos,
108 NULL,
109 NULL,
110 NULL,
111 &ConnectInfo,
112 &ConnectInfoLength);
113 if (!NT_SUCCESS(Status))
114 {
115 DPRINT1("SmConnectToSm: Connect to Sm failed %lx\n", Status);
116 }
117#if (NTDDI_VERSION < NTDDI_VISTA)
118 else
119 {
120 /* Treat a warning or informational status as success */
122 }
123#endif
124
125 /* Return if the connection was successful or not */
126 return Status;
127}
128
148NTAPI
151 _Inout_ PSM_API_MSG SmApiMsg)
152{
153 static ULONG RtlpSmMessageInfo[SmpMaxApiNumber] =
154 {
155 0 /*sizeof(SM_CREATE_FOREIGN_SESSION_MSG)*/,
157 0 /*sizeof(SM_TERMINATE_FOREIGN_SESSION_MSG)*/,
158 sizeof(SM_EXEC_PGM_MSG),
160 sizeof(SM_START_CSR_MSG),
161 sizeof(SM_STOP_CSR_MSG),
162 };
163
166
167 if (SmApiMsg->ApiNumber >= SmpMaxApiNumber)
169
170 /* Obtain the necessary data length for this API */
171 DataLength = RtlpSmMessageInfo[SmApiMsg->ApiNumber];
172
173 /* Fill out the Port Message Header */
174 // RtlZeroMemory(&SmApiMsg->h, sizeof(SmApiMsg->h));
175 SmApiMsg->h.u2.ZeroInit = 0;
176 /* DataLength = user_data_size + anything between
177 * header and data, including intermediate padding */
178 SmApiMsg->h.u1.s1.DataLength = (CSHORT)DataLength +
179 FIELD_OFFSET(SM_API_MSG, u) - sizeof(SmApiMsg->h);
180 /* TotalLength = sizeof(*SmApiMsg) on <= NT5.2, otherwise:
181 * DataLength + header_size == user_data_size + FIELD_OFFSET(SM_API_MSG, u)
182 * without structure trailing padding */
183 SmApiMsg->h.u1.s1.TotalLength = SmApiMsg->h.u1.s1.DataLength + sizeof(SmApiMsg->h);
184
185 /* Send the LPC message and wait for a reply */
186 Status = NtRequestWaitReplyPort(SmApiPort, &SmApiMsg->h, &SmApiMsg->h);
187 if (!NT_SUCCESS(Status))
188 {
189 DPRINT1("SmSendMsgToSm: NtRequestWaitReplyPort failed, Status: 0x%08lx\n", Status);
190 }
191 else
192 {
193 /* Return the real status */
194 Status = SmApiMsg->ReturnValue;
195 }
196
197 return Status;
198}
199
219NTAPI
223 _In_ NTSTATUS SessionStatus)
224{
225 SM_API_MSG SmApiMsg = {0};
226 PSM_SESSION_COMPLETE_MSG SessionComplete = &SmApiMsg.u.SessionComplete;
227
228#if 0 //def _WIN64
229 /* 64-bit SMSS needs to talk to 32-bit processes so do the LPC conversion */
230 if (SmpIsWow64Process())
231 {
232 return SmpWow64SessionComplete(SmApiPort, SessionId, SessionStatus);
233 }
234#endif
235
236 /* Set the message data */
237 SessionComplete->SessionId = SessionId;
238 SessionComplete->SessionStatus = SessionStatus;
239
240 /* Send the message and wait for a reply */
242 return SmSendMsgToSm(SmApiPort, &SmApiMsg);
243}
244
264NTAPI
267 _In_ PRTL_USER_PROCESS_INFORMATION ProcessInformation,
269{
271 SM_API_MSG SmApiMsg = {0};
272 PSM_EXEC_PGM_MSG ExecPgm = &SmApiMsg.u.ExecPgm;
273
274#if 0 //def _WIN64
275 /* 64-bit SMSS needs to talk to 32-bit processes so do the LPC conversion */
276 if (SmpIsWow64Process())
277 {
278 return SmpWow64ExecPgm(SmApiPort, ProcessInformation, DebugFlag);
279 }
280#endif
281
282 /* Set the message data */
283 ExecPgm->ProcessInformation = *ProcessInformation;
284 ExecPgm->DebugFlag = DebugFlag;
285
286 /* Send the message and wait for a reply */
287 SmApiMsg.ApiNumber = SmpExecPgmApi;
288 Status = SmSendMsgToSm(SmApiPort, &SmApiMsg);
289
290 /* Close the handles that the parent passed in and return status */
291 NtClose(ProcessInformation->ProcessHandle);
292 NtClose(ProcessInformation->ThreadHandle);
293 return Status;
294}
295
316NTAPI
319 _In_ PUNICODE_STRING DeferedSubsystem)
320{
321 SM_API_MSG SmApiMsg = {0};
322 PSM_LOAD_DEFERED_SUBSYSTEM_MSG LoadDefered = &SmApiMsg.u.LoadDefered;
323
324#if 0 //def _WIN64
325 /* 64-bit SMSS needs to talk to 32-bit processes so do the LPC conversion */
326 if (SmpIsWow64Process())
327 {
328 return SmpWow64LoadDeferedSubsystem(SmApiPort, DeferedSubsystem);
329 }
330#endif
331
332 /* Validate DeferedSubsystem's length */
333 if (DeferedSubsystem->Length > sizeof(LoadDefered->Buffer))
335
336 /* Set the message data */
337 /* Buffer stores a counted non-NULL-terminated UNICODE string */
338 LoadDefered->Length = DeferedSubsystem->Length;
339 RtlCopyMemory(LoadDefered->Buffer,
340 DeferedSubsystem->Buffer,
341 DeferedSubsystem->Length);
342
343 /* Send the message and wait for a reply */
345 return SmSendMsgToSm(SmApiPort, &SmApiMsg);
346}
347
375NTAPI
378 _Out_ PULONG pMuSessionId,
379 _In_opt_ PUNICODE_STRING CommandLine,
380 _Out_ PHANDLE pWindowsSubSysProcessId,
381 _Out_ PHANDLE pInitialCommandProcessId)
382{
384 SM_API_MSG SmApiMsg = {0};
385 PSM_START_CSR_MSG StartCsr = &SmApiMsg.u.StartCsr;
386
387#if 0 //def _WIN64
388 /* 64-bit SMSS needs to talk to 32-bit processes so do the LPC conversion */
389 if (SmpIsWow64Process())
390 {
391 return SmpWow64StartCsr(SmApiPort,
392 pMuSessionId,
393 CommandLine,
394 pWindowsSubSysProcessId,
395 pInitialCommandProcessId);
396 }
397#endif
398
399 /* Set the message data */
400 if (CommandLine)
401 {
402 /* Validate CommandLine's length */
403 if (CommandLine->Length > sizeof(StartCsr->Buffer))
405
406 /* Buffer stores a counted non-NULL-terminated UNICODE string */
407 StartCsr->Length = CommandLine->Length;
408 RtlCopyMemory(StartCsr->Buffer,
409 CommandLine->Buffer,
410 CommandLine->Length);
411 }
412 else
413 {
414 StartCsr->Length = 0;
415 }
416
417 /* Send the message and wait for a reply */
418 SmApiMsg.ApiNumber = SmpStartCsrApi;
419 Status = SmSendMsgToSm(SmApiPort, &SmApiMsg);
420
421 /* Give back information to caller */
422 *pMuSessionId = StartCsr->MuSessionId;
423 *pWindowsSubSysProcessId = StartCsr->WindowsSubSysProcessId;
424 *pInitialCommandProcessId = StartCsr->SmpInitialCommandProcessId;
425
426 return Status;
427}
428
444NTAPI
447 _In_ ULONG MuSessionId)
448{
449 SM_API_MSG SmApiMsg = {0};
450
451#if 0 //def _WIN64
452 /* 64-bit SMSS needs to talk to 32-bit processes so do the LPC conversion */
453 if (SmpIsWow64Process())
454 {
455 return SmpWow64StopCsr(SmApiPort, MuSessionId);
456 }
457#endif
458
459 /* Set the message data */
460 SmApiMsg.u.StopCsr.MuSessionId = MuSessionId;
461
462 /* Send the message and wait for a reply */
463 SmApiMsg.ApiNumber = SmpStopCsrApi;
464 return SmSendMsgToSm(SmApiPort, &SmApiMsg);
465}
static UNICODE_STRING PortName
unsigned char BOOLEAN
LONG NTSTATUS
Definition: precomp.h:26
#define DPRINT1
Definition: precomp.h:8
_In_ ULONG _In_opt_ WDFREQUEST _In_opt_ PVOID _In_ size_t _In_ PVOID _In_ size_t _Out_ size_t * DataLength
Definition: cdrom.h:1444
ULONG DebugFlag
Definition: fxobject.cpp:44
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
ULONG SessionId
Definition: dllmain.c:28
ImageType
Definition: gdiplusenums.h:193
Status
Definition: gdiplustypes.h:25
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble * u
Definition: glfuncs.h:240
@ SecurityIdentification
Definition: lsa.idl:56
#define _Inout_
Definition: ms_sal.h:378
#define _Out_
Definition: ms_sal.h:345
#define _In_
Definition: ms_sal.h:308
#define _In_opt_
Definition: ms_sal.h:309
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3402
#define UNICODE_NULL
#define IMAGE_SUBSYSTEM_UNKNOWN
Definition: ntimage.h:435
NTSTATUS NTAPI NtConnectPort(OUT PHANDLE PortHandle, IN PUNICODE_STRING PortName, IN PSECURITY_QUALITY_OF_SERVICE SecurityQos, IN OUT PPORT_VIEW ClientView OPTIONAL, IN OUT PREMOTE_PORT_VIEW ServerView OPTIONAL, OUT PULONG MaxMessageLength OPTIONAL, IN OUT PVOID ConnectionInformation OPTIONAL, IN OUT PULONG ConnectionInformationLength OPTIONAL)
Definition: connect.c:777
NTSTATUS NTAPI NtRequestWaitReplyPort(IN HANDLE PortHandle, IN PPORT_MESSAGE LpcRequest, IN OUT PPORT_MESSAGE LpcReply)
Definition: send.c:696
PVOID *typedef PHANDLE
Definition: ntsecpkg.h:455
#define STATUS_INVALID_PARAMETER_MIX
Definition: ntstatus.h:285
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:239
#define L(x)
Definition: ntvdm.h:50
#define STATUS_SUCCESS
Definition: shellext.h:65
NTSTATUS NTAPI SmLoadDeferedSubsystem(_In_ HANDLE SmApiPort, _In_ PUNICODE_STRING DeferedSubsystem)
This function is used to make the SM start an environment subsystem server process.
Definition: smclient.c:317
NTSTATUS NTAPI SmSessionComplete(_In_ HANDLE SmApiPort, _In_ ULONG SessionId, _In_ NTSTATUS SessionStatus)
This function is called by an environment subsystem server to tell the SM it has terminated the sessi...
Definition: smclient.c:220
NTSTATUS NTAPI SmStartCsr(_In_ HANDLE SmApiPort, _Out_ PULONG pMuSessionId, _In_opt_ PUNICODE_STRING CommandLine, _Out_ PHANDLE pWindowsSubSysProcessId, _Out_ PHANDLE pInitialCommandProcessId)
Requests the SM to create a new Terminal Services session and start an initial command.
Definition: smclient.c:376
NTSTATUS NTAPI SmConnectToSm(_In_opt_ PUNICODE_STRING SbApiPortName, _In_opt_ HANDLE SbApiPort, _In_opt_ ULONG ImageType, _Out_ PHANDLE SmApiPort)
Connects to the SM API port for registering a session callback port (Sb) associated to a subsystem,...
Definition: smclient.c:57
NTSTATUS NTAPI SmSendMsgToSm(_In_ HANDLE SmApiPort, _Inout_ PSM_API_MSG SmApiMsg)
Sends a message to the SM via the SM API port.
Definition: smclient.c:149
NTSTATUS NTAPI SmStopCsr(_In_ HANDLE SmApiPort, _In_ ULONG MuSessionId)
Requests the SM to terminate a Terminal Services session.
Definition: smclient.c:445
NTSTATUS NTAPI SmExecPgm(_In_ HANDLE SmApiPort, _In_ PRTL_USER_PROCESS_INFORMATION ProcessInformation, _In_ BOOLEAN DebugFlag)
Requests the SM to start a process under a new environment session.
Definition: smclient.c:265
struct _SM_STOP_CSR_MSG SM_STOP_CSR_MSG
struct _SM_SESSION_COMPLETE_MSG SM_SESSION_COMPLETE_MSG
@ SmpLoadDeferedSubsystemApi
Definition: smmsg.h:32
@ SmpStartCsrApi
Definition: smmsg.h:33
@ SmpStopCsrApi
Definition: smmsg.h:34
@ SmpSessionCompleteApi
Definition: smmsg.h:29
@ SmpExecPgmApi
Definition: smmsg.h:31
@ SmpMaxApiNumber
Definition: smmsg.h:36
struct _SM_LOAD_DEFERED_SUBSYSTEM_MSG SM_LOAD_DEFERED_SUBSYSTEM_MSG
HANDLE SmApiPort
Definition: smss.c:23
WCHAR SbApiPortName[120]
Definition: smmsg.h:224
ULONG SubsystemType
Definition: smmsg.h:223
SECURITY_CONTEXT_TRACKING_MODE ContextTrackingMode
Definition: lsa.idl:66
SECURITY_IMPERSONATION_LEVEL ImpersonationLevel
Definition: lsa.idl:65
SM_SESSION_COMPLETE_MSG SessionComplete
Definition: smmsg.h:110
SM_STOP_CSR_MSG StopCsr
Definition: smmsg.h:115
SM_START_CSR_MSG StartCsr
Definition: smmsg.h:114
union _SM_API_MSG::@3525 u
SM_EXEC_PGM_MSG ExecPgm
Definition: smmsg.h:112
SMSRV_API_NUMBER ApiNumber
Definition: smmsg.h:105
SM_LOAD_DEFERED_SUBSYSTEM_MSG LoadDefered
Definition: smmsg.h:113
BOOLEAN DebugFlag
Definition: smmsg.h:62
RTL_USER_PROCESS_INFORMATION ProcessInformation
Definition: smmsg.h:61
NTSTATUS SessionStatus
Definition: smmsg.h:51
WCHAR Buffer[128]
Definition: smmsg.h:80
HANDLE SmpInitialCommandProcessId
Definition: smmsg.h:82
HANDLE WindowsSubSysProcessId
Definition: smmsg.h:81
ULONG Length
Definition: smmsg.h:79
ULONG MuSessionId
Definition: smmsg.h:78
ULONG MuSessionId
Definition: smmsg.h:92
uint32_t * PULONG
Definition: typedefs.h:59
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
#define NTAPI
Definition: typedefs.h:36
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
uint32_t ULONG
Definition: typedefs.h:59
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
short CSHORT
Definition: umtypes.h:127
#define SECURITY_DYNAMIC_TRACKING
Definition: setypes.h:103
__wchar_t WCHAR
Definition: xmlstorage.h:180