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)
9 /* INCLUDES ******************************************************************/
16 /* DATA **********************************************************************/
17 RTL_CRITICAL_SECTION CsrNtSessionLock
;
18 LIST_ENTRY CsrNtSessionList
;
21 PSB_API_ROUTINE CsrServerSbApiDispatch
[5] =
24 CsrSbForeignSessionComplete
,
25 CsrSbForeignSessionComplete
,
30 PCHAR CsrServerSbApiName
[5] =
34 "SbForeignSessionComplete",
36 "Unknown Csr Sb Api Number"
39 /* PRIVATE FUNCTIONS *********************************************************/
42 * @name CsrInitializeNtSessions
44 * The CsrInitializeNtSessions routine sets up support for CSR Sessions.
48 * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
56 CsrInitializeNtSessions(VOID
)
59 DPRINT("CSRSRV: %s called\n", __FUNCTION__
);
61 /* Initialize the Session List */
62 InitializeListHead(&CsrNtSessionList
);
64 /* Initialize the Session Lock */
65 Status
= RtlInitializeCriticalSection(&CsrNtSessionLock
);
70 * @name CsrAllocateNtSession
72 * The CsrAllocateNtSession routine allocates a new CSR NT Session.
75 * Session ID of the CSR NT Session to allocate.
77 * @return Pointer to the newly allocated CSR NT Session.
84 CsrAllocateNtSession(ULONG SessionId
)
86 PCSR_NT_SESSION NtSession
;
88 /* Allocate an NT Session Object */
89 NtSession
= RtlAllocateHeap(CsrHeap
,
91 sizeof(CSR_NT_SESSION
));
93 /* Setup the Session Object */
96 NtSession
->SessionId
= SessionId
;
97 NtSession
->ReferenceCount
= 1;
99 /* Insert it into the Session List */
100 CsrAcquireNtSessionLock();
101 InsertHeadList(&CsrNtSessionList
, &NtSession
->SessionList
);
102 CsrReleaseNtSessionLock();
105 /* Return the Session (or NULL) */
110 * @name CsrReferenceNtSession
112 * The CsrReferenceNtSession increases the reference count of a CSR NT Session.
115 * Pointer to the CSR NT Session to reference.
124 CsrReferenceNtSession(PCSR_NT_SESSION Session
)
126 /* Acquire the lock */
127 CsrAcquireNtSessionLock();
129 /* Increase the reference count */
130 Session
->ReferenceCount
++;
132 /* Release the lock */
133 CsrReleaseNtSessionLock();
137 * @name CsrDereferenceNtSession
139 * The CsrDereferenceNtSession decreases the reference count of a
143 * Pointer to the CSR NT Session to reference.
146 * If this is the last reference to the session, this argument
147 * specifies the exit status.
151 * @remarks CsrDereferenceNtSession will complete the session if
152 * the last reference to it has been closed.
157 CsrDereferenceNtSession(PCSR_NT_SESSION Session
,
160 /* Acquire the lock */
161 CsrAcquireNtSessionLock();
163 /* Dereference the Session Object */
164 if (!(--Session
->ReferenceCount
))
166 /* Remove it from the list */
167 RemoveEntryList(&Session
->SessionList
);
169 /* Release the lock */
170 CsrReleaseNtSessionLock();
172 /* Tell SM that we're done here */
173 SmSessionComplete(CsrSmApiPort
, Session
->SessionId
, ExitStatus
);
175 /* Free the Session Object */
176 RtlFreeHeap(CsrHeap
, 0, Session
);
180 /* Release the lock, the Session is still active */
181 CsrReleaseNtSessionLock();
186 /* SESSION MANAGER FUNCTIONS**************************************************/
189 * @name CsrSbCreateSession
191 * The CsrSbCreateSession API is called by the Session Manager whenever a new
192 * session is created.
195 * Pointer to the Session Manager API Message.
197 * @return TRUE in case of success, FALSE othwerwise.
199 * @remarks The CsrSbCreateSession routine will initialize a new CSR NT
200 * Session and allocate a new CSR Process for the subsystem process.
205 CsrSbCreateSession(IN PSB_API_MESSAGE ApiMessage
)
207 PSB_CREATE_SESSION CreateSession
= &ApiMessage
->SbCreateSession
;
208 HANDLE hProcess
, hThread
;
209 PCSR_PROCESS CsrProcess
;
211 KERNEL_USER_TIMES KernelTimes
;
212 PCSR_THREAD CsrThread
;
216 /* Save the Process and Thread Handles */
217 hProcess
= CreateSession
->ProcessInfo
.ProcessHandle
;
218 hThread
= CreateSession
->ProcessInfo
.ThreadHandle
;
220 /* Lock the Processes */
221 CsrAcquireProcessLock();
223 /* Allocate a new process */
224 if (!(CsrProcess
= CsrAllocateProcess()))
227 ApiMessage
->Status
= STATUS_NO_MEMORY
;
228 CsrReleaseProcessLock();
232 /* Setup Process Data */
233 CsrProcess
->ClientId
= CreateSession
->ProcessInfo
.ClientId
;
234 CsrProcess
->ProcessHandle
= hProcess
;
236 /* Set the exception port */
237 Status
= NtSetInformationProcess(hProcess
,
238 ProcessExceptionPort
,
242 /* Check for success */
243 if (!NT_SUCCESS(Status
))
245 /* Fail the request */
246 CsrDeallocateProcess(CsrProcess
);
247 CsrReleaseProcessLock();
249 /* Strange as it seems, NTSTATUSes are actually returned */
250 return (BOOLEAN
)STATUS_NO_MEMORY
;
253 /* Get the Create Time */
254 Status
= NtQueryInformationThread(hThread
,
257 sizeof(KERNEL_USER_TIMES
),
260 /* Check for success */
261 if (!NT_SUCCESS(Status
))
263 /* Fail the request */
264 CsrDeallocateProcess(CsrProcess
);
265 CsrReleaseProcessLock();
267 return (BOOLEAN
)Status
;
270 /* Allocate a new Thread */
271 if (!(CsrThread
= CsrAllocateThread(CsrProcess
)))
273 /* Fail the request */
274 CsrDeallocateProcess(CsrProcess
);
275 ApiMessage
->Status
= STATUS_NO_MEMORY
;
276 CsrReleaseProcessLock();
280 /* Setup the Thread Object */
281 CsrThread
->CreateTime
= KernelTimes
.CreateTime
;
282 CsrThread
->ClientId
= CreateSession
->ProcessInfo
.ClientId
;
283 CsrThread
->ThreadHandle
= hThread
;
284 CsrThread
->Flags
= 0;
286 /* Insert it into the Process List */
287 CsrInsertThread(CsrProcess
, CsrThread
);
289 /* Allocate a new Session */
290 CsrProcess
->NtSession
= CsrAllocateNtSession(CreateSession
->SessionId
);
292 /* Set the Process Priority */
293 CsrSetBackgroundPriority(CsrProcess
);
295 /* Get the first data location */
296 ProcessData
= &CsrProcess
->ServerData
[CSR_SERVER_DLL_MAX
];
299 for (i
= 0; i
< CSR_SERVER_DLL_MAX
; i
++)
301 /* Check if the DLL is loaded and has Process Data */
302 if (CsrLoadedServerDll
[i
] && CsrLoadedServerDll
[i
]->SizeOfProcessData
)
304 /* Write the pointer to the data */
305 CsrProcess
->ServerData
[i
] = ProcessData
;
307 /* Move to the next data location */
308 ProcessData
= (PVOID
)((ULONG_PTR
)ProcessData
+
309 CsrLoadedServerDll
[i
]->SizeOfProcessData
);
313 /* Nothing for this Process */
314 CsrProcess
->ServerData
[i
] = NULL
;
318 /* Insert the Process */
319 CsrInsertProcess(NULL
, NULL
, CsrProcess
);
321 /* Activate the Thread */
322 ApiMessage
->Status
= NtResumeThread(hThread
, NULL
);
324 /* Release lock and return */
325 CsrReleaseProcessLock();
330 * @name CsrSbForeignSessionComplete
332 * The CsrSbForeignSessionComplete API is called by the Session Manager
333 * whenever a foreign session is completed (ie: terminated).
336 * Pointer to the Session Manager API Message.
338 * @return TRUE in case of success, FALSE othwerwise.
340 * @remarks The CsrSbForeignSessionComplete API is not yet implemented.
345 CsrSbForeignSessionComplete(IN PSB_API_MESSAGE ApiMessage
)
347 /* Deprecated/Unimplemented in NT */
348 ApiMessage
->Status
= STATUS_NOT_IMPLEMENTED
;