[REACTOS]
[reactos.git] / reactos / deprecated / csr / csrsrv / session.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS CSR Sub System
4 * FILE: subsys/csr/csrsrv/session.c
5 * PURPOSE: CSR Server DLL Session Implementation
6 * PROGRAMMERS: Alex Ionescu (alex@relsoft.net)
7 */
8
9 /* INCLUDES ******************************************************************/
10
11 #include "srv.h"
12
13 #define NDEBUG
14 #include <debug.h>
15
16 /* DATA **********************************************************************/
17
18 RTL_CRITICAL_SECTION CsrNtSessionLock;
19 LIST_ENTRY CsrNtSessionList;
20 HANDLE CsrSmApiPort;
21
22 PSB_API_ROUTINE CsrServerSbApiDispatch[5] =
23 {
24 CsrSbCreateSession,
25 CsrSbTerminateSession,
26 CsrSbForeignSessionComplete,
27 CsrSbCreateProcess,
28 NULL
29 };
30
31 PCHAR CsrServerSbApiName[5] =
32 {
33 "SbCreateSession",
34 "SbTerminateSession",
35 "SbForeignSessionComplete",
36 "SbCreateProcess",
37 "Unknown Csr Sb Api Number"
38 };
39
40 /* PRIVATE FUNCTIONS *********************************************************/
41
42 /*++
43 * @name CsrInitializeNtSessionList
44 *
45 * The CsrInitializeNtSessionList routine sets up support for CSR Sessions.
46 *
47 * @param None
48 *
49 * @return None
50 *
51 * @remarks None.
52 *
53 *--*/
54 NTSTATUS
55 NTAPI
56 CsrInitializeNtSessionList(VOID)
57 {
58 DPRINT("CSRSRV: %s called\n", __FUNCTION__);
59
60 /* Initialize the Session List */
61 InitializeListHead(&CsrNtSessionList);
62
63 /* Initialize the Session Lock */
64 return RtlInitializeCriticalSection(&CsrNtSessionLock);
65 }
66
67 /*++
68 * @name CsrAllocateNtSession
69 *
70 * The CsrAllocateNtSession routine allocates a new CSR NT Session.
71 *
72 * @param SessionId
73 * Session ID of the CSR NT Session to allocate.
74 *
75 * @return Pointer to the newly allocated CSR NT Session.
76 *
77 * @remarks None.
78 *
79 *--*/
80 PCSR_NT_SESSION
81 NTAPI
82 CsrAllocateNtSession(IN ULONG SessionId)
83 {
84 PCSR_NT_SESSION NtSession;
85
86 /* Allocate an NT Session Object */
87 NtSession = RtlAllocateHeap(CsrHeap, 0, sizeof(CSR_NT_SESSION));
88 if (NtSession)
89 {
90 /* Setup the Session Object */
91 NtSession->SessionId = SessionId;
92 NtSession->ReferenceCount = 1;
93
94 /* Insert it into the Session List */
95 CsrAcquireNtSessionLock();
96 InsertHeadList(&CsrNtSessionList, &NtSession->SessionLink);
97 CsrReleaseNtSessionLock();
98 }
99 else
100 {
101 ASSERT(NtSession != NULL);
102 }
103
104 /* Return the Session (or NULL) */
105 return NtSession;
106 }
107
108 /*++
109 * @name CsrReferenceNtSession
110 *
111 * The CsrReferenceNtSession increases the reference count of a CSR NT Session.
112 *
113 * @param Session
114 * Pointer to the CSR NT Session to reference.
115 *
116 * @return None.
117 *
118 * @remarks None.
119 *
120 *--*/
121 VOID
122 NTAPI
123 CsrReferenceNtSession(IN PCSR_NT_SESSION Session)
124 {
125 /* Acquire the lock */
126 CsrAcquireNtSessionLock();
127
128 /* Sanity checks */
129 ASSERT(!IsListEmpty(&Session->SessionLink));
130 ASSERT(Session->SessionId != 0);
131 ASSERT(Session->ReferenceCount != 0);
132
133 /* Increase the reference count */
134 Session->ReferenceCount++;
135
136 /* Release the lock */
137 CsrReleaseNtSessionLock();
138 }
139
140 /*++
141 * @name CsrDereferenceNtSession
142 *
143 * The CsrDereferenceNtSession decreases the reference count of a
144 * CSR NT Session.
145 *
146 * @param Session
147 * Pointer to the CSR NT Session to reference.
148 *
149 * @param ExitStatus
150 * If this is the last reference to the session, this argument
151 * specifies the exit status.
152 *
153 * @return None.
154 *
155 * @remarks CsrDereferenceNtSession will complete the session if
156 * the last reference to it has been closed.
157 *
158 *--*/
159 VOID
160 NTAPI
161 CsrDereferenceNtSession(IN PCSR_NT_SESSION Session,
162 IN NTSTATUS ExitStatus)
163 {
164 /* Acquire the lock */
165 CsrAcquireNtSessionLock();
166
167 /* Sanity checks */
168 ASSERT(!IsListEmpty(&Session->SessionLink));
169 ASSERT(Session->SessionId != 0);
170 ASSERT(Session->ReferenceCount != 0);
171
172 /* Dereference the Session Object */
173 if (!(--Session->ReferenceCount))
174 {
175 /* Remove it from the list */
176 RemoveEntryList(&Session->SessionLink);
177
178 /* Release the lock */
179 CsrReleaseNtSessionLock();
180
181 /* Tell SM that we're done here */
182 SmSessionComplete(CsrSmApiPort, Session->SessionId, ExitStatus);
183
184 /* Free the Session Object */
185 RtlFreeHeap(CsrHeap, 0, Session);
186 }
187 else
188 {
189 /* Release the lock, the Session is still active */
190 CsrReleaseNtSessionLock();
191 }
192 }
193
194
195 /* SESSION MANAGER FUNCTIONS**************************************************/
196
197 /*++
198 * @name CsrSbCreateSession
199 *
200 * The CsrSbCreateSession API is called by the Session Manager whenever a new
201 * session is created.
202 *
203 * @param ApiMessage
204 * Pointer to the Session Manager API Message.
205 *
206 * @return TRUE in case of success, FALSE othwerwise.
207 *
208 * @remarks The CsrSbCreateSession routine will initialize a new CSR NT
209 * Session and allocate a new CSR Process for the subsystem process.
210 *
211 *--*/
212 BOOLEAN
213 NTAPI
214 CsrSbCreateSession(IN PSB_API_MSG ApiMessage)
215 {
216 PSB_CREATE_SESSION_MSG CreateSession = &ApiMessage->CreateSession;
217 HANDLE hProcess, hThread;
218 PCSR_PROCESS CsrProcess;
219 NTSTATUS Status;
220 KERNEL_USER_TIMES KernelTimes;
221 PCSR_THREAD CsrThread;
222 PVOID ProcessData;
223 ULONG i;
224
225 /* Save the Process and Thread Handles */
226 hProcess = CreateSession->ProcessInfo.ProcessHandle;
227 hThread = CreateSession->ProcessInfo.ThreadHandle;
228
229 /* Lock the Processes */
230 CsrAcquireProcessLock();
231
232 /* Allocate a new process */
233 CsrProcess = CsrAllocateProcess();
234 if (!CsrProcess)
235 {
236 /* Fail */
237 ApiMessage->ReturnValue = STATUS_NO_MEMORY;
238 CsrReleaseProcessLock();
239 return TRUE;
240 }
241
242 /* Set the exception port */
243 Status = NtSetInformationProcess(hProcess,
244 ProcessExceptionPort,
245 &CsrApiPort,
246 sizeof(HANDLE));
247
248 /* Check for success */
249 if (!NT_SUCCESS(Status))
250 {
251 /* Fail the request */
252 CsrDeallocateProcess(CsrProcess);
253 CsrReleaseProcessLock();
254
255 /* Strange as it seems, NTSTATUSes are actually returned */
256 return (BOOLEAN)STATUS_NO_MEMORY;
257 }
258
259 /* Get the Create Time */
260 Status = NtQueryInformationThread(hThread,
261 ThreadTimes,
262 &KernelTimes,
263 sizeof(KERNEL_USER_TIMES),
264 NULL);
265
266 /* Check for success */
267 if (!NT_SUCCESS(Status))
268 {
269 /* Fail the request */
270 CsrDeallocateProcess(CsrProcess);
271 CsrReleaseProcessLock();
272
273 /* Strange as it seems, NTSTATUSes are actually returned */
274 return (BOOLEAN)Status;
275 }
276
277 /* Allocate a new Thread */
278 CsrThread = CsrAllocateThread(CsrProcess);
279 if (!CsrThread)
280 {
281 /* Fail the request */
282 CsrDeallocateProcess(CsrProcess);
283 ApiMessage->ReturnValue = STATUS_NO_MEMORY;
284 CsrReleaseProcessLock();
285 return TRUE;
286 }
287
288 /* Setup the Thread Object */
289 CsrThread->CreateTime = KernelTimes.CreateTime;
290 CsrThread->ClientId = CreateSession->ProcessInfo.ClientId;
291 CsrThread->ThreadHandle = hThread;
292 ProtectHandle(hThread);
293 CsrThread->Flags = 0;
294
295 /* Insert it into the Process List */
296 CsrInsertThread(CsrProcess, CsrThread);
297
298 /* Setup Process Data */
299 CsrProcess->ClientId = CreateSession->ProcessInfo.ClientId;
300 CsrProcess->ProcessHandle = hProcess;
301 CsrProcess->NtSession = CsrAllocateNtSession(CreateSession->SessionId);
302
303 /* Set the Process Priority */
304 CsrSetBackgroundPriority(CsrProcess);
305
306 /* Get the first data location */
307 ProcessData = &CsrProcess->ServerData[CSR_SERVER_DLL_MAX];
308
309 /* Loop every DLL */
310 for (i = 0; i < CSR_SERVER_DLL_MAX; i++)
311 {
312 /* Check if the DLL is loaded and has Process Data */
313 if (CsrLoadedServerDll[i] && CsrLoadedServerDll[i]->SizeOfProcessData)
314 {
315 /* Write the pointer to the data */
316 CsrProcess->ServerData[i] = ProcessData;
317
318 /* Move to the next data location */
319 ProcessData = (PVOID)((ULONG_PTR)ProcessData +
320 CsrLoadedServerDll[i]->SizeOfProcessData);
321 }
322 else
323 {
324 /* Nothing for this Process */
325 CsrProcess->ServerData[i] = NULL;
326 }
327 }
328
329 /* Insert the Process */
330 CsrInsertProcess(NULL, NULL, CsrProcess);
331
332 /* Activate the Thread */
333 ApiMessage->ReturnValue = NtResumeThread(hThread, NULL);
334
335 /* Release lock and return */
336 CsrReleaseProcessLock();
337 return TRUE;
338 }
339
340 /*++
341 * @name CsrSbForeignSessionComplete
342 *
343 * The CsrSbForeignSessionComplete API is called by the Session Manager
344 * whenever a foreign session is completed (ie: terminated).
345 *
346 * @param ApiMessage
347 * Pointer to the Session Manager API Message.
348 *
349 * @return TRUE in case of success, FALSE othwerwise.
350 *
351 * @remarks The CsrSbForeignSessionComplete API is not yet implemented.
352 *
353 *--*/
354 BOOLEAN
355 NTAPI
356 CsrSbForeignSessionComplete(IN PSB_API_MSG ApiMessage)
357 {
358 /* Deprecated/Unimplemented in NT */
359 ApiMessage->ReturnValue = STATUS_NOT_IMPLEMENTED;
360 return TRUE;
361 }
362
363 /*++
364 * @name CsrSbTerminateSession
365 *
366 * The CsrSbTerminateSession API is called by the Session Manager
367 * whenever a foreign session should be destroyed.
368 *
369 * @param ApiMessage
370 * Pointer to the Session Manager API Message.
371 *
372 * @return TRUE in case of success, FALSE othwerwise.
373 *
374 * @remarks The CsrSbTerminateSession API is not yet implemented.
375 *
376 *--*/
377 BOOLEAN
378 NTAPI
379 CsrSbTerminateSession(IN PSB_API_MSG ApiMessage)
380 {
381 ApiMessage->ReturnValue = STATUS_NOT_IMPLEMENTED;
382 return TRUE;
383 }
384
385 /*++
386 * @name CsrSbCreateProcess
387 *
388 * The CsrSbCreateProcess API is called by the Session Manager
389 * whenever a foreign session is created and a new process should be started.
390 *
391 * @param ApiMessage
392 * Pointer to the Session Manager API Message.
393 *
394 * @return TRUE in case of success, FALSE othwerwise.
395 *
396 * @remarks The CsrSbCreateProcess API is not yet implemented.
397 *
398 *--*/
399 BOOLEAN
400 NTAPI
401 CsrSbCreateProcess(IN PSB_API_MSG ApiMessage)
402 {
403 ApiMessage->ReturnValue = STATUS_NOT_IMPLEMENTED;
404 return TRUE;
405 }
406
407 /* EOF */