3 * smapi.c - \SmApiPort LPC port message management
5 * Reactos Session Manager
10 #include <rosrtl/string.h>
15 /* GLOBAL VARIABLES *********************************************************/
17 static HANDLE SmApiPort
= INVALID_HANDLE_VALUE
;
19 /* SM API *******************************************************************/
23 DPRINT("SM: %s called\n",__FUNCTION__
);
24 Request
->Status
= STATUS_NOT_IMPLEMENTED
;
25 return STATUS_SUCCESS
;
29 typedef NTSTATUS (FASTCALL
* SM_PORT_API
)(PSM_PORT_MESSAGE
);
31 SM_PORT_API SmApi
[] =
33 SmInvalid
, /* unused */
34 SmCompSes
, /* smapicomp.c */
35 SmInvalid
, /* obsolete */
36 SmInvalid
, /* unknown */
37 SmExecPgm
/* smapiexec.c */
40 #if !defined(__USE_NT_LPC__)
42 SmpHandleConnectionRequest (PSM_PORT_MESSAGE Request
);
46 /**********************************************************************
48 * SmpApiConnectedThread/1
51 * Entry point for the listener thread of LPC port "\SmApiPort".
54 SmpApiConnectedThread(PVOID dummy
)
56 NTSTATUS Status
= STATUS_SUCCESS
;
58 PLPC_MESSAGE Reply
= NULL
;
59 SM_PORT_MESSAGE Request
= {{0}};
61 DPRINT("SM: %s running\n",__FUNCTION__
);
65 DPRINT("SM: %s: waiting for message\n",__FUNCTION__
);
67 Status
= NtReplyWaitReceivePort(SmApiPort
,
70 (PLPC_MESSAGE
) & Request
);
71 if (NT_SUCCESS(Status
))
73 DPRINT("SM: %s: message received (type=%d)\n",
75 PORT_MESSAGE_TYPE(Request
));
77 switch (Request
.Header
.MessageType
)
79 case LPC_CONNECTION_REQUEST
:
80 SmpHandleConnectionRequest (&Request
);
84 // DbgSsHandleKmApiMsg (&Request, 0);
91 if ((Request
.ApiIndex
) &&
92 (Request
.ApiIndex
< (sizeof SmApi
/ sizeof SmApi
[0])))
94 Status
= SmApi
[Request
.ApiIndex
](&Request
);
95 Reply
= (PLPC_MESSAGE
) & Request
;
97 Request
.Status
= STATUS_NOT_IMPLEMENTED
;
98 Reply
= (PLPC_MESSAGE
) & Request
;
105 /**********************************************************************
107 * SmpHandleConnectionRequest/1
110 * Request: LPC connection request message
113 * Quoted in http://support.microsoft.com/kb/258060/EN-US/
116 SmpHandleConnectionRequest (PSM_PORT_MESSAGE Request
)
118 #if defined(__USE_NT_LPC__)
119 NTSTATUS Status
= STATUS_SUCCESS
;
120 PSM_CLIENT_DATA ClientData
= NULL
;
121 PVOID Context
= NULL
;
123 DPRINT("SM: %s called\n",__FUNCTION__
);
126 * SmCreateClient/2 is called here explicitly to *fail*.
127 * If it succeeds, there is something wrong in the
128 * connection request. An environment subsystem *never*
129 * registers twice. (Security issue: maybe we will
130 * write this event into the security log).
132 Status
= SmCreateClient (Request
, & ClientData
);
133 if(STATUS_SUCCESS
== Status
)
135 /* OK: the client is an environment subsystem
136 * willing to manage a free image type.
139 Status
= NtAcceptConnectPort (& ClientData
->ApiPort
,
141 (PLPC_MESSAGE
) Request
,
145 if(NT_SUCCESS(Status
))
147 Status
= NtCompleteConnectPort(ClientData
->ApiPort
);
149 return STATUS_SUCCESS
;
151 /* Reject the subsystem */
152 Status
= NtAcceptConnectPort (& ClientData
->ApiPort
,
154 (PLPC_MESSAGE
) Request
,
159 #else /* ReactOS LPC */
160 NTSTATUS Status
= STATUS_SUCCESS
;
161 PSM_CLIENT_DATA ClientData
= NULL
;
163 DPRINT("SM: %s called\n",__FUNCTION__
);
165 Status
= SmCreateClient (Request
, & ClientData
);
166 if(STATUS_SUCCESS
== Status
)
168 Status
= NtAcceptConnectPort (& ClientData
->ApiPort
,
174 if (!NT_SUCCESS(Status
))
176 DPRINT1("SM: %s: NtAcceptConnectPort() failed (Status=0x%08lx)\n",
177 __FUNCTION__
, Status
);
180 Status
= NtCompleteConnectPort(ClientData
->ApiPort
);
181 if (!NT_SUCCESS(Status
))
183 DPRINT1("SM: %s: NtCompleteConnectPort() failed (Status=0x%08lx)\n",
184 __FUNCTION__
, Status
);
187 Status
= RtlCreateUserThread(NtCurrentProcess(),
193 (PTHREAD_START_ROUTINE
) SmpApiConnectedThread
,
195 & ClientData
->ApiPortThread
,
197 if (!NT_SUCCESS(Status
))
199 DPRINT1("SM: %s: Unable to create server thread (Status=0x%08lx)\n",
200 __FUNCTION__
, Status
);
204 return STATUS_SUCCESS
;
206 /* Reject the subsystem */
207 Status
= NtAcceptConnectPort (& ClientData
->ApiPort
,
214 #endif /* defined __USE_NT_LPC__ */
218 /**********************************************************************
223 * Due to differences in LPC implementation between NT and ROS,
224 * we need a thread to listen for connection request that
225 * creates a new thread for each connected port. This is not
226 * necessary in NT LPC, because server side connected ports are
227 * never used to receive requests.
230 SmpApiThread (HANDLE ListeningPort
)
232 NTSTATUS Status
= STATUS_SUCCESS
;
233 LPC_MAX_MESSAGE Request
= {{0}};
237 Status
= NtListenPort (ListeningPort
, & Request
.Header
);
238 if (!NT_SUCCESS(Status
))
240 DPRINT1("SM: %s: NtListenPort() failed! (Status==x%08lx)\n", __FUNCTION__
, Status
);
243 Status
= SmpHandleConnectionRequest ((PSM_PORT_MESSAGE
) & Request
);
244 if(!NT_SUCCESS(Status
))
246 DPRINT1("SM: %s: SmpHandleConnectionRequest failed (Status=0x%08lx)\n",
247 __FUNCTION__
, Status
);
252 NtClose(ListeningPort
);
254 NtTerminateThread(NtCurrentThread(), Status
);
258 /* LPC PORT INITIALIZATION **************************************************/
261 /**********************************************************************
268 SmCreateApiPort(VOID
)
270 OBJECT_ATTRIBUTES ObjectAttributes
= {0};
271 UNICODE_STRING UnicodeString
= {0};
272 NTSTATUS Status
= STATUS_SUCCESS
;
274 RtlRosInitUnicodeStringFromLiteral(&UnicodeString
,
276 InitializeObjectAttributes(&ObjectAttributes
,
282 Status
= NtCreatePort(&SmApiPort
,
287 if (!NT_SUCCESS(Status
))
292 * Create one thread for the named LPC
295 RtlCreateUserThread(NtCurrentProcess(),
301 (PTHREAD_START_ROUTINE
)SmpApiThread
,