mirror of
https://github.com/reactos/reactos.git
synced 2025-01-12 09:07:54 +00:00
c424146e2c
svn path=/branches/cmake-bringup/; revision=48236
351 lines
8.8 KiB
C
351 lines
8.8 KiB
C
/*
|
|
* COPYRIGHT: See COPYING in the top level directory
|
|
* PROJECT: ReactOS CSR Sub System
|
|
* FILE: subsys/csr/csrsrv/session.c
|
|
* PURPOSE: CSR Server DLL Session Implementation
|
|
* PROGRAMMERS: Alex Ionescu (alex@relsoft.net)
|
|
*/
|
|
|
|
/* INCLUDES ******************************************************************/
|
|
|
|
#include "srv.h"
|
|
|
|
#define NDEBUG
|
|
#include <debug.h>
|
|
|
|
/* DATA **********************************************************************/
|
|
RTL_CRITICAL_SECTION CsrNtSessionLock;
|
|
LIST_ENTRY CsrNtSessionList;
|
|
HANDLE CsrSmApiPort;
|
|
|
|
PSB_API_ROUTINE CsrServerSbApiDispatch[5] =
|
|
{
|
|
CsrSbCreateSession,
|
|
CsrSbTerminateSession,
|
|
CsrSbForeignSessionComplete,
|
|
CsrSbCreateProcess,
|
|
NULL
|
|
};
|
|
|
|
PCHAR CsrServerSbApiName[5] =
|
|
{
|
|
"SbCreateSession",
|
|
"SbTerminateSession",
|
|
"SbForeignSessionComplete",
|
|
"SbCreateProcess",
|
|
"Unknown Csr Sb Api Number"
|
|
};
|
|
|
|
/* PRIVATE FUNCTIONS *********************************************************/
|
|
|
|
/*++
|
|
* @name CsrInitializeNtSessions
|
|
*
|
|
* The CsrInitializeNtSessions routine sets up support for CSR Sessions.
|
|
*
|
|
* @param None
|
|
*
|
|
* @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
|
|
* othwerwise.
|
|
*
|
|
* @remarks None.
|
|
*
|
|
*--*/
|
|
NTSTATUS
|
|
NTAPI
|
|
CsrInitializeNtSessions(VOID)
|
|
{
|
|
NTSTATUS Status;
|
|
DPRINT("CSRSRV: %s called\n", __FUNCTION__);
|
|
|
|
/* Initialize the Session List */
|
|
InitializeListHead(&CsrNtSessionList);
|
|
|
|
/* Initialize the Session Lock */
|
|
Status = RtlInitializeCriticalSection(&CsrNtSessionLock);
|
|
return Status;
|
|
}
|
|
|
|
/*++
|
|
* @name CsrAllocateNtSession
|
|
*
|
|
* The CsrAllocateNtSession routine allocates a new CSR NT Session.
|
|
*
|
|
* @param SessionId
|
|
* Session ID of the CSR NT Session to allocate.
|
|
*
|
|
* @return Pointer to the newly allocated CSR NT Session.
|
|
*
|
|
* @remarks None.
|
|
*
|
|
*--*/
|
|
PCSR_NT_SESSION
|
|
NTAPI
|
|
CsrAllocateNtSession(ULONG SessionId)
|
|
{
|
|
PCSR_NT_SESSION NtSession;
|
|
|
|
/* Allocate an NT Session Object */
|
|
NtSession = RtlAllocateHeap(CsrHeap,
|
|
0,
|
|
sizeof(CSR_NT_SESSION));
|
|
|
|
/* Setup the Session Object */
|
|
if (NtSession)
|
|
{
|
|
NtSession->SessionId = SessionId;
|
|
NtSession->ReferenceCount = 1;
|
|
|
|
/* Insert it into the Session List */
|
|
CsrAcquireNtSessionLock();
|
|
InsertHeadList(&CsrNtSessionList, &NtSession->SessionList);
|
|
CsrReleaseNtSessionLock();
|
|
}
|
|
|
|
/* Return the Session (or NULL) */
|
|
return NtSession;
|
|
}
|
|
|
|
/*++
|
|
* @name CsrReferenceNtSession
|
|
*
|
|
* The CsrReferenceNtSession increases the reference count of a CSR NT Session.
|
|
*
|
|
* @param Session
|
|
* Pointer to the CSR NT Session to reference.
|
|
*
|
|
* @return None.
|
|
*
|
|
* @remarks None.
|
|
*
|
|
*--*/
|
|
VOID
|
|
NTAPI
|
|
CsrReferenceNtSession(PCSR_NT_SESSION Session)
|
|
{
|
|
/* Acquire the lock */
|
|
CsrAcquireNtSessionLock();
|
|
|
|
/* Increase the reference count */
|
|
Session->ReferenceCount++;
|
|
|
|
/* Release the lock */
|
|
CsrReleaseNtSessionLock();
|
|
}
|
|
|
|
/*++
|
|
* @name CsrDereferenceNtSession
|
|
*
|
|
* The CsrDereferenceNtSession decreases the reference count of a
|
|
* CSR NT Session.
|
|
*
|
|
* @param Session
|
|
* Pointer to the CSR NT Session to reference.
|
|
*
|
|
* @param ExitStatus
|
|
* If this is the last reference to the session, this argument
|
|
* specifies the exit status.
|
|
*
|
|
* @return None.
|
|
*
|
|
* @remarks CsrDereferenceNtSession will complete the session if
|
|
* the last reference to it has been closed.
|
|
*
|
|
*--*/
|
|
VOID
|
|
NTAPI
|
|
CsrDereferenceNtSession(PCSR_NT_SESSION Session,
|
|
NTSTATUS ExitStatus)
|
|
{
|
|
/* Acquire the lock */
|
|
CsrAcquireNtSessionLock();
|
|
|
|
/* Dereference the Session Object */
|
|
if (!(--Session->ReferenceCount))
|
|
{
|
|
/* Remove it from the list */
|
|
RemoveEntryList(&Session->SessionList);
|
|
|
|
/* Release the lock */
|
|
CsrReleaseNtSessionLock();
|
|
|
|
/* Tell SM that we're done here */
|
|
SmSessionComplete(CsrSmApiPort, Session->SessionId, ExitStatus);
|
|
|
|
/* Free the Session Object */
|
|
RtlFreeHeap(CsrHeap, 0, Session);
|
|
}
|
|
else
|
|
{
|
|
/* Release the lock, the Session is still active */
|
|
CsrReleaseNtSessionLock();
|
|
}
|
|
}
|
|
|
|
|
|
/* SESSION MANAGER FUNCTIONS**************************************************/
|
|
|
|
/*++
|
|
* @name CsrSbCreateSession
|
|
*
|
|
* The CsrSbCreateSession API is called by the Session Manager whenever a new
|
|
* session is created.
|
|
*
|
|
* @param ApiMessage
|
|
* Pointer to the Session Manager API Message.
|
|
*
|
|
* @return TRUE in case of success, FALSE othwerwise.
|
|
*
|
|
* @remarks The CsrSbCreateSession routine will initialize a new CSR NT
|
|
* Session and allocate a new CSR Process for the subsystem process.
|
|
*
|
|
*--*/
|
|
BOOLEAN
|
|
NTAPI
|
|
CsrSbCreateSession(IN PSB_API_MESSAGE ApiMessage)
|
|
{
|
|
PSB_CREATE_SESSION CreateSession = &ApiMessage->SbCreateSession;
|
|
HANDLE hProcess, hThread;
|
|
PCSR_PROCESS CsrProcess;
|
|
NTSTATUS Status;
|
|
KERNEL_USER_TIMES KernelTimes;
|
|
PCSR_THREAD CsrThread;
|
|
PVOID ProcessData;
|
|
ULONG i;
|
|
|
|
/* Save the Process and Thread Handles */
|
|
hProcess = CreateSession->ProcessInfo.ProcessHandle;
|
|
hThread = CreateSession->ProcessInfo.ThreadHandle;
|
|
|
|
/* Lock the Processes */
|
|
CsrAcquireProcessLock();
|
|
|
|
/* Allocate a new process */
|
|
if (!(CsrProcess = CsrAllocateProcess()))
|
|
{
|
|
/* Fail */
|
|
ApiMessage->Status = STATUS_NO_MEMORY;
|
|
CsrReleaseProcessLock();
|
|
return TRUE;
|
|
}
|
|
|
|
/* Setup Process Data */
|
|
CsrProcess->ClientId = CreateSession->ProcessInfo.ClientId;
|
|
CsrProcess->ProcessHandle = hProcess;
|
|
|
|
/* Set the exception port */
|
|
Status = NtSetInformationProcess(hProcess,
|
|
ProcessExceptionPort,
|
|
&CsrApiPort,
|
|
sizeof(HANDLE));
|
|
|
|
/* Check for success */
|
|
if (!NT_SUCCESS(Status))
|
|
{
|
|
/* Fail the request */
|
|
CsrDeallocateProcess(CsrProcess);
|
|
CsrReleaseProcessLock();
|
|
|
|
/* Strange as it seems, NTSTATUSes are actually returned */
|
|
return (BOOLEAN)STATUS_NO_MEMORY;
|
|
}
|
|
|
|
/* Get the Create Time */
|
|
Status = NtQueryInformationThread(hThread,
|
|
ThreadTimes,
|
|
&KernelTimes,
|
|
sizeof(KERNEL_USER_TIMES),
|
|
NULL);
|
|
|
|
/* Check for success */
|
|
if (!NT_SUCCESS(Status))
|
|
{
|
|
/* Fail the request */
|
|
CsrDeallocateProcess(CsrProcess);
|
|
CsrReleaseProcessLock();
|
|
|
|
return (BOOLEAN)Status;
|
|
}
|
|
|
|
/* Allocate a new Thread */
|
|
if (!(CsrThread = CsrAllocateThread(CsrProcess)))
|
|
{
|
|
/* Fail the request */
|
|
CsrDeallocateProcess(CsrProcess);
|
|
ApiMessage->Status = STATUS_NO_MEMORY;
|
|
CsrReleaseProcessLock();
|
|
return TRUE;
|
|
}
|
|
|
|
/* Setup the Thread Object */
|
|
CsrThread->CreateTime = KernelTimes.CreateTime;
|
|
CsrThread->ClientId = CreateSession->ProcessInfo.ClientId;
|
|
CsrThread->ThreadHandle = hThread;
|
|
CsrThread->Flags = 0;
|
|
|
|
/* Insert it into the Process List */
|
|
CsrInsertThread(CsrProcess, CsrThread);
|
|
|
|
/* Allocate a new Session */
|
|
CsrProcess->NtSession = CsrAllocateNtSession(CreateSession->SessionId);
|
|
|
|
/* Set the Process Priority */
|
|
CsrSetBackgroundPriority(CsrProcess);
|
|
|
|
/* Get the first data location */
|
|
ProcessData = &CsrProcess->ServerData[CSR_SERVER_DLL_MAX];
|
|
|
|
/* Loop every DLL */
|
|
for (i = 0; i < CSR_SERVER_DLL_MAX; i++)
|
|
{
|
|
/* Check if the DLL is loaded and has Process Data */
|
|
if (CsrLoadedServerDll[i] && CsrLoadedServerDll[i]->SizeOfProcessData)
|
|
{
|
|
/* Write the pointer to the data */
|
|
CsrProcess->ServerData[i] = ProcessData;
|
|
|
|
/* Move to the next data location */
|
|
ProcessData = (PVOID)((ULONG_PTR)ProcessData +
|
|
CsrLoadedServerDll[i]->SizeOfProcessData);
|
|
}
|
|
else
|
|
{
|
|
/* Nothing for this Process */
|
|
CsrProcess->ServerData[i] = NULL;
|
|
}
|
|
}
|
|
|
|
/* Insert the Process */
|
|
CsrInsertProcess(NULL, NULL, CsrProcess);
|
|
|
|
/* Activate the Thread */
|
|
ApiMessage->Status = NtResumeThread(hThread, NULL);
|
|
|
|
/* Release lock and return */
|
|
CsrReleaseProcessLock();
|
|
return TRUE;
|
|
}
|
|
|
|
/*++
|
|
* @name CsrSbForeignSessionComplete
|
|
*
|
|
* The CsrSbForeignSessionComplete API is called by the Session Manager
|
|
* whenever a foreign session is completed (ie: terminated).
|
|
*
|
|
* @param ApiMessage
|
|
* Pointer to the Session Manager API Message.
|
|
*
|
|
* @return TRUE in case of success, FALSE othwerwise.
|
|
*
|
|
* @remarks The CsrSbForeignSessionComplete API is not yet implemented.
|
|
*
|
|
*--*/
|
|
BOOLEAN
|
|
NTAPI
|
|
CsrSbForeignSessionComplete(IN PSB_API_MESSAGE ApiMessage)
|
|
{
|
|
/* Deprecated/Unimplemented in NT */
|
|
ApiMessage->Status = STATUS_NOT_IMPLEMENTED;
|
|
return TRUE;
|
|
}
|
|
/* EOF */
|