ReactOS 0.4.16-dev-297-gc569aee
smclient.c File Reference
#include "precomp.h"
#include <debug.h>
Include dependency graph for smclient.c:

Go to the source code of this file.

Macros

#define NDEBUG
 

Functions

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, or for issuing API requests to the SM API port.
 
NTSTATUS NTAPI SmSendMsgToSm (_In_ HANDLE SmApiPort, _Inout_ PSM_API_MSG SmApiMsg)
 Sends a message to the SM via the SM API port.
 
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 session it managed.
 
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.
 
NTSTATUS NTAPI SmLoadDeferedSubsystem (_In_ HANDLE SmApiPort, _In_ PUNICODE_STRING DeferedSubsystem)
 This function is used to make the SM start an environment subsystem server process.
 
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.
 
NTSTATUS NTAPI SmStopCsr (_In_ HANDLE SmApiPort, _In_ ULONG MuSessionId)
 Requests the SM to terminate a Terminal Services session.
 

Macro Definition Documentation

◆ NDEBUG

#define NDEBUG

Definition at line 14 of file smclient.c.

Function Documentation

◆ SmConnectToSm()

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, or for issuing API requests to the SM API port.

There are only two ways to call this API: a) subsystems willing to register with SM will use it with full parameters (the function checks them); b) regular SM clients, will set to 0 the 1st, the 2nd, and the 3rd parameters.

Parameters
[in]SbApiPortNameName of the Sb port the calling subsystem server already created in the system namespace.
[in]SbApiPortLPC port handle (checked, but not used: the subsystem is required to have already created the callback port before it connects to the SM).
[in]ImageTypeA valid IMAGE_SUBSYSTEM_xxx value. PE images having this subsystem value will be handled by the current subsystem.
[out]SmApiPortPointer to a HANDLE, which will be filled with a valid client-side LPC communication port.
Returns
If all three optional values are omitted, an LPC status. STATUS_INVALID_PARAMETER_MIX if PortName is defined and both SbApiPort and ImageType are 0.
Remarks
Exported on Vista+ by NTDLL and called RtlConnectToSm().

Definition at line 57 of file smclient.c.

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}
static UNICODE_STRING PortName
LONG NTSTATUS
Definition: precomp.h:26
#define DPRINT1
Definition: precomp.h:8
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
ImageType
Definition: gdiplusenums.h:193
Status
Definition: gdiplustypes.h:25
@ SecurityIdentification
Definition: lsa.idl:56
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#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
#define STATUS_INVALID_PARAMETER_MIX
Definition: ntstatus.h:285
#define L(x)
Definition: ntvdm.h:50
#define STATUS_SUCCESS
Definition: shellext.h:65
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
#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
#define SECURITY_DYNAMIC_TRACKING
Definition: setypes.h:103
__wchar_t WCHAR
Definition: xmlstorage.h:180

Referenced by CsrServerInitialization(), and SmpExecuteInitialCommand().

◆ SmExecPgm()

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.

Parameters
[in]SmApiPortPort handle returned by SmConnectToSm().
[in]ProcessInformationA process description as returned by RtlCreateUserProcess().
[in]DebugFlagIf set, indicates that the caller wants to debug this process and act as its debug user interface.
Returns
Success status as handed by the SM reply; otherwise a failure status code.

Definition at line 265 of file smclient.c.

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}
ULONG DebugFlag
Definition: fxobject.cpp:44
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3402
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
@ SmpExecPgmApi
Definition: smmsg.h:31
SM_EXEC_PGM_MSG ExecPgm
Definition: smmsg.h:112
SMSRV_API_NUMBER ApiNumber
Definition: smmsg.h:105
union _SM_API_MSG::@3524 u
BOOLEAN DebugFlag
Definition: smmsg.h:62
RTL_USER_PROCESS_INFORMATION ProcessInformation
Definition: smmsg.h:61

Referenced by SmExecuteProgram(), SmpExecPgm(), and SmpExecuteInitialCommand().

◆ SmLoadDeferedSubsystem()

NTSTATUS NTAPI SmLoadDeferedSubsystem ( _In_ HANDLE  SmApiPort,
_In_ PUNICODE_STRING  DeferedSubsystem 
)

This function is used to make the SM start an environment subsystem server process.

Parameters
[in]SmApiPortPort handle returned by SmConnectToSm().
[in]DeferedSubsystemName of the subsystem to start. This must be one of the subsystems listed by value's name in the SM registry key \Registry\SYSTEM\CurrentControlSet\Control\Session Manager\SubSystems (used by the SM to lookup the corresponding image name). Default valid names are: "Debug", "Windows", "Posix", "Os2".
Returns
Success status as handed by the SM reply; otherwise a failure status code.

Definition at line 317 of file smclient.c.

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}
@ SmpLoadDeferedSubsystemApi
Definition: smmsg.h:32
SM_LOAD_DEFERED_SUBSYSTEM_MSG LoadDefered
Definition: smmsg.h:113

◆ SmSendMsgToSm()

NTSTATUS NTAPI SmSendMsgToSm ( _In_ HANDLE  SmApiPort,
_Inout_ PSM_API_MSG  SmApiMsg 
)

Sends a message to the SM via the SM API port.

Parameters
[in]SmApiPortPort handle returned by SmConnectToSm().
[in,out]SmApiMsgMessage to send to the SM. The API-specific data must be initialized, and the SmApiMsg->ApiNumber must be specified accordingly.
Returns
Success status as handed by the SM reply; otherwise a failure status code.
Remarks
Exported on Vista+ by NTDLL and called RtlSendMsgToSm().

Definition at line 149 of file smclient.c.

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}
_In_ ULONG _In_opt_ WDFREQUEST _In_opt_ PVOID _In_ size_t _In_ PVOID _In_ size_t _Out_ size_t * DataLength
Definition: cdrom.h:1444
#define STATUS_NOT_IMPLEMENTED
Definition: d3dkmdt.h:42
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
NTSTATUS NTAPI NtRequestWaitReplyPort(IN HANDLE PortHandle, IN PPORT_MESSAGE LpcRequest, IN OUT PPORT_MESSAGE LpcReply)
Definition: send.c:696
struct _SM_STOP_CSR_MSG SM_STOP_CSR_MSG
struct _SM_SESSION_COMPLETE_MSG SM_SESSION_COMPLETE_MSG
@ SmpMaxApiNumber
Definition: smmsg.h:36
struct _SM_LOAD_DEFERED_SUBSYSTEM_MSG SM_LOAD_DEFERED_SUBSYSTEM_MSG
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
short CSHORT
Definition: umtypes.h:127

Referenced by SmExecPgm(), SmLoadDeferedSubsystem(), SmSessionComplete(), SmStartCsr(), and SmStopCsr().

◆ SmSessionComplete()

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 session it managed.

Parameters
[in]SmApiPortPort handle returned by SmConnectToSm().
[in]SessionIdThe session ID of the session being terminated.
[in]SessionStatusAn NT status code for the termination.
Returns
Success status as handed by the SM reply; otherwise a failure status code.

Definition at line 220 of file smclient.c.

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}
ULONG SessionId
Definition: dllmain.c:28
@ SmpSessionCompleteApi
Definition: smmsg.h:29
SM_SESSION_COMPLETE_MSG SessionComplete
Definition: smmsg.h:110
NTSTATUS SessionStatus
Definition: smmsg.h:51

Referenced by CsrDereferenceNtSession().

◆ SmStartCsr()

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.

Parameters
[in]SmApiPortPort handle returned by SmConnectToSm().
[out]pMuSessionIdPointer to a variable that receives the session ID of the new Terminal Services session that has been created.
[in]CommandLineFull path to the image to be used as the initial command.
[out]pWindowsSubSysProcessIdPointer to a variable that receives the process ID of the environment subsystem that has been started in the new session.
[out]pInitialCommandProcessIdPointer to a variable that receives the process ID of the initial command.
Returns
Success status as handed by the SM reply; otherwise a failure status code.

Definition at line 376 of file smclient.c.

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}
@ SmpStartCsrApi
Definition: smmsg.h:33
SM_START_CSR_MSG StartCsr
Definition: smmsg.h:114
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

Referenced by SmpStartCsr().

◆ SmStopCsr()

NTSTATUS NTAPI SmStopCsr ( _In_ HANDLE  SmApiPort,
_In_ ULONG  MuSessionId 
)

Requests the SM to terminate a Terminal Services session.

Parameters
[in]SmApiPortPort handle returned by SmConnectToSm().
[in]MuSessionIdThe Terminal Services session ID, returned by SmStartCsr().
Returns
Success status as handed by the SM reply; otherwise a failure status code.

Definition at line 445 of file smclient.c.

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}
@ SmpStopCsrApi
Definition: smmsg.h:34
SM_STOP_CSR_MSG StopCsr
Definition: smmsg.h:115
ULONG MuSessionId
Definition: smmsg.h:92