diff --git a/reactos/subsystems/win32/csrss/csrsrv/CMakeLists.txt b/reactos/subsystems/win32/csrss/csrsrv/CMakeLists.txt index 148f6e64633..4ccfb650d93 100644 --- a/reactos/subsystems/win32/csrss/csrsrv/CMakeLists.txt +++ b/reactos/subsystems/win32/csrss/csrsrv/CMakeLists.txt @@ -11,6 +11,8 @@ list(APPEND SOURCE procsup.c thredsup.c init.c + wait.c + session.c ${CMAKE_CURRENT_BINARY_DIR}/csrsrv.def) add_library(csrsrv SHARED ${SOURCE}) diff --git a/reactos/subsystems/win32/csrss/csrsrv/api/wapi.c b/reactos/subsystems/win32/csrss/csrsrv/api/wapi.c index c1dd60e19e1..b4068e68caa 100644 --- a/reactos/subsystems/win32/csrss/csrsrv/api/wapi.c +++ b/reactos/subsystems/win32/csrss/csrsrv/api/wapi.c @@ -986,6 +986,70 @@ ClientConnectionThread(HANDLE ServerPort) RtlExitUserThread(STATUS_SUCCESS); } +/*++ + * @name CsrReleaseCapturedArguments + * @implemented NT5.1 + * + * The CsrReleaseCapturedArguments routine releases a Capture Buffer + * that was previously captured with CsrCaptureArguments. + * + * @param ApiMessage + * Pointer to the CSR API Message containing the Capture Buffer + * that needs to be released. + * + * @return None. + * + * @remarks None. + * + *--*/ +VOID +NTAPI +CsrReleaseCapturedArguments(IN PCSR_API_MESSAGE ApiMessage) +{ + PCSR_CAPTURE_BUFFER RemoteCaptureBuffer, LocalCaptureBuffer; + SIZE_T BufferDistance; + ULONG PointerCount; + ULONG_PTR **PointerOffsets, *CurrentPointer; + + /* Get the capture buffers */ + RemoteCaptureBuffer = ApiMessage->CsrCaptureData; + LocalCaptureBuffer = RemoteCaptureBuffer->PreviousCaptureBuffer; + + /* Free the previous one */ + RemoteCaptureBuffer->PreviousCaptureBuffer = NULL; + + /* Find out the difference between the two buffers */ + BufferDistance = (ULONG_PTR)LocalCaptureBuffer - (ULONG_PTR)RemoteCaptureBuffer; + + /* Save the pointer count and offset pointer */ + PointerCount = RemoteCaptureBuffer->PointerCount; + PointerOffsets = (ULONG_PTR**)(RemoteCaptureBuffer + 1); + + /* Start the loop */ + while (PointerCount) + { + /* Get the current pointer */ + CurrentPointer = *PointerOffsets++; + if (CurrentPointer) + { + /* Add it to the CSR Message structure */ + CurrentPointer += (ULONG_PTR)ApiMessage; + + /* Modify the pointer to take into account its new position */ + *CurrentPointer += BufferDistance; + } + + /* Move to the next Pointer */ + PointerCount--; + } + + /* Copy the data back */ + RtlMoveMemory(LocalCaptureBuffer, RemoteCaptureBuffer, RemoteCaptureBuffer->Size); + + /* Free our allocated buffer */ + RtlFreeHeap(CsrHeap, 0, RemoteCaptureBuffer); +} + /* SESSION MANAGER FUNCTIONS**************************************************/ /*++ diff --git a/reactos/subsystems/win32/csrss/csrsrv/csrsrv.rbuild b/reactos/subsystems/win32/csrss/csrsrv/csrsrv.rbuild index 49ff4de115c..606f3d35c1c 100644 --- a/reactos/subsystems/win32/csrss/csrsrv/csrsrv.rbuild +++ b/reactos/subsystems/win32/csrss/csrsrv/csrsrv.rbuild @@ -18,5 +18,7 @@ procsup.c thredsup.c init.c + wait.c + session.csrv.h diff --git a/reactos/subsystems/win32/csrss/csrsrv/init.c b/reactos/subsystems/win32/csrss/csrsrv/init.c index eaee0a97445..3bdedb3b52a 100644 --- a/reactos/subsystems/win32/csrss/csrsrv/init.c +++ b/reactos/subsystems/win32/csrss/csrsrv/init.c @@ -1116,6 +1116,15 @@ CsrServerInitialization(IN ULONG ArgumentCount, __FUNCTION__, Status); return Status; } + + /* Set up Session Support */ + Status = CsrInitializeNtSessionList(); + if (!NT_SUCCESS(Status)) + { + DPRINT1("CSRSRV:%s: CsrInitializeSessions failed (Status=%08lx)\n", + __FUNCTION__, Status); + return Status; + } /* Set up Process Support */ Status = CsrInitializeProcessStructure(); diff --git a/reactos/subsystems/win32/csrss/csrsrv/procsup.c b/reactos/subsystems/win32/csrss/csrsrv/procsup.c index 3c3283841af..66efec33beb 100644 --- a/reactos/subsystems/win32/csrss/csrsrv/procsup.c +++ b/reactos/subsystems/win32/csrss/csrsrv/procsup.c @@ -16,7 +16,7 @@ /* GLOBALS ********************************************************************/ -RTL_CRITICAL_SECTION ProcessDataLock, CsrWaitListsLock; +RTL_CRITICAL_SECTION ProcessDataLock; PCSR_PROCESS CsrRootProcess; SECURITY_QUALITY_OF_SERVICE CsrSecurityQos = { diff --git a/reactos/subsystems/win32/csrss/csrsrv/session.c b/reactos/subsystems/win32/csrss/csrsrv/session.c new file mode 100644 index 00000000000..3da0e869335 --- /dev/null +++ b/reactos/subsystems/win32/csrss/csrsrv/session.c @@ -0,0 +1,175 @@ +/* + * 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 + +/* DATA **********************************************************************/ + +RTL_CRITICAL_SECTION CsrNtSessionLock; +LIST_ENTRY CsrNtSessionList; + +/* PRIVATE FUNCTIONS *********************************************************/ + +/*++ + * @name CsrInitializeNtSessionList + * + * The CsrInitializeNtSessionList routine sets up support for CSR Sessions. + * + * @param None + * + * @return None + * + * @remarks None. + * + *--*/ +NTSTATUS +NTAPI +CsrInitializeNtSessionList(VOID) +{ + DPRINT("CSRSRV: %s called\n", __FUNCTION__); + + /* Initialize the Session List */ + InitializeListHead(&CsrNtSessionList); + + /* Initialize the Session Lock */ + return RtlInitializeCriticalSection(&CsrNtSessionLock); +} + +/*++ + * @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(IN ULONG SessionId) +{ + PCSR_NT_SESSION NtSession; + + /* Allocate an NT Session Object */ + NtSession = RtlAllocateHeap(CsrHeap, 0, sizeof(CSR_NT_SESSION)); + if (NtSession) + { + /* Setup the Session Object */ + NtSession->SessionId = SessionId; + NtSession->ReferenceCount = 1; + + /* Insert it into the Session List */ + CsrAcquireNtSessionLock(); + InsertHeadList(&CsrNtSessionList, &NtSession->SessionLink); + CsrReleaseNtSessionLock(); + } + else + { + ASSERT(NtSession != NULL); + } + + /* 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(IN PCSR_NT_SESSION Session) +{ + /* Acquire the lock */ + CsrAcquireNtSessionLock(); + + /* Sanity checks */ + ASSERT(!IsListEmpty(&Session->SessionLink)); + ASSERT(Session->SessionId != 0); + ASSERT(Session->ReferenceCount != 0); + + /* 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(IN PCSR_NT_SESSION Session, + IN NTSTATUS ExitStatus) +{ + /* Acquire the lock */ + CsrAcquireNtSessionLock(); + + /* Sanity checks */ + ASSERT(!IsListEmpty(&Session->SessionLink)); + ASSERT(Session->SessionId != 0); + ASSERT(Session->ReferenceCount != 0); + + /* Dereference the Session Object */ + if (!(--Session->ReferenceCount)) + { + /* Remove it from the list */ + RemoveEntryList(&Session->SessionLink); + + /* 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(); + } +} + +/* EOF */ diff --git a/reactos/subsystems/win32/csrss/csrsrv/thredsup.c b/reactos/subsystems/win32/csrss/csrsrv/thredsup.c index 249eb9dd68f..471c8a98e60 100644 --- a/reactos/subsystems/win32/csrss/csrsrv/thredsup.c +++ b/reactos/subsystems/win32/csrss/csrsrv/thredsup.c @@ -407,4 +407,40 @@ CsrAddStaticServerThread(IN HANDLE hThread, return CsrThread; } +/*++ + * @name CsrDereferenceThread + * @implemented NT4 + * + * The CsrDereferenceThread routine removes a reference from a CSR Thread. + * + * @param CsrThread + * Pointer to the CSR Thread to dereference. + * + * @return None. + * + * @remarks If the reference count has reached zero (ie: the CSR Thread has + * no more active references), it will be deleted. + * + *--*/ +VOID +NTAPI +CsrDereferenceThread(IN PCSR_THREAD CsrThread) +{ + /* Acquire process lock */ + CsrAcquireProcessLock(); + + /* Decrease reference count */ + ASSERT(CsrThread->ReferenceCount > 0); + if (!(--CsrThread->ReferenceCount)) + { + /* Call the generic cleanup code */ + CsrThreadRefcountZero(CsrThread); + } + else + { + /* Just release the lock */ + CsrReleaseProcessLock(); + } +} + /* EOF */ diff --git a/reactos/subsystems/win32/csrss/csrsrv/wait.c b/reactos/subsystems/win32/csrss/csrsrv/wait.c new file mode 100644 index 00000000000..00d0bdf3108 --- /dev/null +++ b/reactos/subsystems/win32/csrss/csrsrv/wait.c @@ -0,0 +1,449 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS CSR Sub System + * FILE: subsys/csr/csrsrv/wait.c + * PURPOSE: CSR Server DLL Wait Implementation + * PROGRAMMERS: Emanuele Aliberti + * Alex Ionescu (alex@relsoft.net) + */ + +/* INCLUDES ******************************************************************/ + +#include "srv.h" + +#define NDEBUG +#include + +/* DATA **********************************************************************/ + +RTL_CRITICAL_SECTION CsrWaitListsLock; + +/* PRIVATE FUNCTIONS *********************************************************/ + +/*++ + * @name CsrInitializeWait + * + * The CsrInitializeWait routine initializes a CSR Wait Object. + * + * @param WaitFunction + * Pointer to the function that will handle this wait. + * + * @param CsrWaitThread + * Pointer to the CSR Thread that will perform the wait. + * + * @param WaitApiMessage + * Pointer to the CSR API Message associated to this wait. + * + * @param WaitContext + * Pointer to a user-defined parameter associated to this wait. + * + * @param NewWaitBlock + * Pointed to the initialized CSR Wait Block for this wait. + * + * @return TRUE in case of success, FALSE othwerwise. + * + * @remarks None. + * + *--*/ +BOOLEAN +NTAPI +CsrInitializeWait(IN CSR_WAIT_FUNCTION WaitFunction, + IN PCSR_THREAD CsrWaitThread, + IN OUT PCSR_API_MESSAGE WaitApiMessage, + IN PVOID WaitContext, + OUT PCSR_WAIT_BLOCK *NewWaitBlock) +{ + ULONG Size; + PCSR_WAIT_BLOCK WaitBlock; + + /* Calculate the size of the wait block */ + Size = sizeof(CSR_WAIT_BLOCK) - + sizeof(WaitBlock->WaitApiMessage) + + WaitApiMessage->Header.u1.s1.TotalLength; + + /* Allocate the Wait Block */ + WaitBlock = RtlAllocateHeap(CsrHeap, 0, Size); + if (!WaitBlock) + { + /* Fail */ + WaitApiMessage->Status = STATUS_NO_MEMORY; + return FALSE; + } + + /* Initialize it */ + WaitBlock->Size = Size; + WaitBlock->WaitThread = CsrWaitThread; + WaitBlock->WaitContext = WaitContext; + WaitBlock->WaitFunction = WaitFunction; + WaitBlock->UserWaitList.Flink = NULL; + WaitBlock->UserWaitList.Blink = NULL; + WaitBlock->WaitList = WaitBlock->UserWaitList; + + /* Copy the message */ + RtlMoveMemory(&WaitBlock->WaitApiMessage, + WaitApiMessage, + WaitApiMessage->Header.u1.s1.TotalLength); + + /* Return the block */ + *NewWaitBlock = WaitBlock; + return TRUE; +} + +/*++ + * @name CsrNotifyWaitBlock + * + * The CsrNotifyWaitBlock routine calls the wait function for a registered + * CSR Wait Block, and replies to the attached CSR API Message, if any. + * + * @param WaitBlock + * Pointer to the CSR Wait Block + * + * @param WaitList + * Pointer to the wait list for this wait. + * + * @param WaitArgument[1-2] + * User-defined values to pass to the wait function. + * + * @param WaitFlags + * Wait flags for this wait. + * + * @param DereferenceThread + * Specifies whether the CSR Thread should be dereferenced at the + * end of this wait. + * + * @return TRUE in case of success, FALSE otherwise. + * + * @remarks After a wait block is notified, the wait function becomes invalid. + * + *--*/ +BOOLEAN +NTAPI +CsrNotifyWaitBlock(IN PCSR_WAIT_BLOCK WaitBlock, + IN PLIST_ENTRY WaitList, + IN PVOID WaitArgument1, + IN PVOID WaitArgument2, + IN ULONG WaitFlags, + IN BOOLEAN DereferenceThread) +{ + /* Call the wait function */ + if ((WaitBlock->WaitFunction)(WaitList, + WaitBlock->WaitThread, + &WaitBlock->WaitApiMessage, + WaitBlock->WaitContext, + WaitArgument1, + WaitArgument2, + WaitFlags)) + { + /* The wait is done, clear the block */ + WaitBlock->WaitThread->WaitBlock = NULL; + + /* Check for captured arguments */ + if (WaitBlock->WaitApiMessage.CsrCaptureData) + { + /* Release them */ + CsrReleaseCapturedArguments(&WaitBlock->WaitApiMessage); + } + + /* Reply to the port */ + NtReplyPort(WaitBlock->WaitThread->Process->ClientPort, + (PPORT_MESSAGE)&WaitBlock->WaitApiMessage); + + /* Check if we should dereference the thread */ + if (DereferenceThread) + { + /* Remove it from the Wait List */ + if (WaitBlock->WaitList.Flink) + { + RemoveEntryList(&WaitBlock->WaitList); + } + + /* Remove it from the User Wait List */ + if (WaitBlock->UserWaitList.Flink) + { + RemoveEntryList(&WaitBlock->UserWaitList); + } + + /* Dereference teh thread */ + CsrDereferenceThread(WaitBlock->WaitThread); + + /* Free the wait block */ + RtlFreeHeap(CsrHeap, 0, WaitBlock); + } + else + { + /* The wait is complete, but the thread is being kept alive */ + WaitBlock->WaitFunction = NULL; + } + + /* The wait suceeded */ + return TRUE; + } + + /* The wait failed */ + return FALSE; +} + +/* PUBLIC FUNCTIONS **********************************************************/ + +/*++ + * @name CsrCreateWait + * @implemented NT4 + * + * The CsrCreateWait routine creates a CSR Wait. + * + * @param WaitList + * Pointer to a list entry of the waits to associate. + * + * @param WaitFunction + * Pointer to the function that will handle this wait. + * + * @param CsrWaitThread + * Pointer to the CSR Thread that will perform the wait. + * + * @param WaitApiMessage + * Pointer to the CSR API Message associated to this wait. + * + * @param WaitContext + * Pointer to a user-defined parameter associated to this wait. + * + * @param UserWaitList + * Pointer to a list entry of the user-defined waits to associate. + * + * @return TRUE in case of success, FALSE otherwise. + * + * @remarks None. + * + *--*/ +BOOLEAN +NTAPI +CsrCreateWait(IN PLIST_ENTRY WaitList, + IN CSR_WAIT_FUNCTION WaitFunction, + IN PCSR_THREAD CsrWaitThread, + IN OUT PCSR_API_MESSAGE WaitApiMessage, + IN PVOID WaitContext, + IN PLIST_ENTRY UserWaitList OPTIONAL) +{ + PCSR_WAIT_BLOCK WaitBlock; + + /* Initialize the wait */ + if (!CsrInitializeWait(WaitFunction, + CsrWaitThread, + WaitApiMessage, + WaitContext, + &WaitBlock)) + { + return FALSE; + } + + /* Acquire the Wait Lock */ + CsrAcquireWaitLock(); + + /* Make sure the thread wasn't destroyed */ + if (CsrWaitThread->Flags & CsrThreadTerminated) + { + /* Fail the wait */ + RtlFreeHeap(CsrHeap, 0, WaitBlock); + CsrReleaseWaitLock(); + return FALSE; + } + + /* Insert the wait in the queue */ + InsertTailList(WaitList, &WaitBlock->WaitList); + + /* Insert the User Wait too, if one was given */ + if (UserWaitList) InsertTailList(UserWaitList, &WaitBlock->UserWaitList); + + /* Return */ + CsrReleaseWaitLock(); + return TRUE; +} + +/*++ + * @name CsrDereferenceWait + * @implemented NT4 + * + * The CsrDereferenceWait routine derefences a CSR Wait Block. + * + * @param WaitList + * Pointer to the Wait List associated to the wait. + + * @return None. + * + * @remarks None. + * + *--*/ +VOID +NTAPI +CsrDereferenceWait(IN PLIST_ENTRY WaitList) +{ + PLIST_ENTRY NextEntry; + PCSR_WAIT_BLOCK WaitBlock; + + /* Acquire the Process and Wait Locks */ + CsrAcquireProcessLock(); + CsrAcquireWaitLock(); + + /* Set the list pointers */ + NextEntry = WaitList->Flink; + + /* Start the loop */ + while (NextEntry != WaitList) + { + /* Get the wait block */ + WaitBlock = CONTAINING_RECORD(NextEntry, CSR_WAIT_BLOCK, WaitList); + + /* Move to the next entry */ + NextEntry = NextEntry->Flink; + + /* Check if there's no Wait Routine */ + if (!WaitBlock->WaitFunction) + { + /* Remove it from the Wait List */ + if (WaitBlock->WaitList.Flink) + { + RemoveEntryList(&WaitBlock->WaitList); + } + + /* Remove it from the User Wait List */ + if (WaitBlock->UserWaitList.Flink) + { + RemoveEntryList(&WaitBlock->UserWaitList); + } + + /* Dereference the thread waiting on it */ + CsrDereferenceThread(WaitBlock->WaitThread); + + /* Free the block */ + RtlFreeHeap(CsrHeap, 0, WaitBlock); + } + } + + /* Release the locks */ + CsrReleaseWaitLock(); + CsrReleaseProcessLock(); +} + +/*++ + * @name CsrMoveSatisfiedWait + * @implemented NT5 + * + * The CsrMoveSatisfiedWait routine moves satisfied waits from a wait list + * to another list entry. + * + * @param NewEntry + * Pointer to a list entry where the satisfied waits will be added. + * + * @param WaitList + * Pointer to a list entry to analyze for satisfied waits. + * + * @return None. + * + * @remarks None. + * + *--*/ +VOID +NTAPI +CsrMoveSatisfiedWait(IN PLIST_ENTRY NewEntry, + IN PLIST_ENTRY WaitList) +{ + PLIST_ENTRY NextEntry; + PCSR_WAIT_BLOCK WaitBlock; + + /* Acquire the Wait Lock */ + CsrAcquireWaitLock(); + + /* Set the List pointers */ + NextEntry = WaitList->Flink; + + /* Start looping */ + while (NextEntry != WaitList) + { + /* Get the Wait block */ + WaitBlock = CONTAINING_RECORD(NextEntry, CSR_WAIT_BLOCK, WaitList); + + /* Go to the next entry */ + NextEntry = NextEntry->Flink; + + /* Check if there is a Wait Callback */ + if (WaitBlock->WaitFunction) + { + /* Remove it from the Wait Block Queue */ + RemoveEntryList(&WaitBlock->WaitList); + + /* Insert the new entry */ + InsertTailList(&WaitBlock->WaitList, NewEntry); + } + } + + /* Release the wait lock */ + CsrReleaseWaitLock(); +} + +/*++ + * @name CsrNotifyWait + * @implemented NT4 + * + * The CsrNotifyWait notifies a CSR Wait Block. + * + * @param WaitList + * Pointer to the list entry for this wait. + * + * @param WaitType + * Type of the wait to perform, either WaitAny or WaitAll. + * + * @param WaitArgument[1-2] + * User-defined argument to pass on to the wait function. + * + * @return TRUE in case of success, FALSE othwerwise. + * + * @remarks None. + * + *--*/ +BOOLEAN +NTAPI +CsrNotifyWait(IN PLIST_ENTRY WaitList, + IN ULONG WaitType, + IN PVOID WaitArgument1, + IN PVOID WaitArgument2) +{ + PLIST_ENTRY NextEntry; + PCSR_WAIT_BLOCK WaitBlock; + BOOLEAN NotifySuccess = FALSE; + + /* Acquire the Wait Lock */ + CsrAcquireWaitLock(); + + /* Set the List pointers */ + NextEntry = WaitList->Flink; + + /* Start looping */ + while (NextEntry != WaitList) + { + /* Get the Wait block */ + WaitBlock = CONTAINING_RECORD(NextEntry, CSR_WAIT_BLOCK, WaitList); + + /* Go to the next entry */ + NextEntry = NextEntry->Flink; + + /* Check if there is a Wait Callback */ + if (WaitBlock->WaitFunction) + { + /* Notify the Waiter */ + NotifySuccess |= CsrNotifyWaitBlock(WaitBlock, + WaitList, + WaitArgument1, + WaitArgument2, + 0, + FALSE); + + /* We've already done a wait, so leave unless this is a Wait All */ + if (WaitType != WaitAll) break; + } + } + + /* Release the wait lock and return */ + CsrReleaseWaitLock(); + return NotifySuccess; +} + +/* EOF */ diff --git a/reactos/subsystems/win32/csrss/include/api.h b/reactos/subsystems/win32/csrss/include/api.h index 8b3ba1acf7a..d13b3051ca5 100644 --- a/reactos/subsystems/win32/csrss/include/api.h +++ b/reactos/subsystems/win32/csrss/include/api.h @@ -22,6 +22,18 @@ #define ProcessStructureListLocked() \ (ProcessDataLock.OwningThread == NtCurrentTeb()->ClientId.UniqueThread) +#define CsrAcquireWaitLock() \ + RtlEnterCriticalSection(&CsrWaitListsLock); + +#define CsrReleaseWaitLock() \ + RtlLeaveCriticalSection(&CsrWaitListsLock); + +#define CsrAcquireNtSessionLock() \ + RtlEnterCriticalSection(&CsrNtSessionLock); + +#define CsrReleaseNtSessionLock() \ + RtlLeaveCriticalSection(&CsrNtSessionLock); + typedef enum _CSR_THREAD_FLAGS { CsrThreadAltertable = 0x1, @@ -66,6 +78,13 @@ typedef struct _CSRSS_CON_PROCESS_DATA LIST_ENTRY ConsoleLink; } CSRSS_CON_PROCESS_DATA, *PCSRSS_CON_PROCESS_DATA; +typedef struct _CSR_NT_SESSION +{ + ULONG ReferenceCount; + LIST_ENTRY SessionLink; + ULONG SessionId; +} CSR_NT_SESSION, *PCSR_NT_SESSION; + typedef struct _CSR_PROCESS { CLIENT_ID ClientId; @@ -102,13 +121,36 @@ typedef struct _CSR_THREAD LIST_ENTRY HashLinks; CLIENT_ID ClientId; PCSR_PROCESS Process; - //struct _CSR_WAIT_BLOCK *WaitBlock; + struct _CSR_WAIT_BLOCK *WaitBlock; HANDLE ThreadHandle; ULONG Flags; ULONG ReferenceCount; ULONG ImpersonationCount; } CSR_THREAD, *PCSR_THREAD; +typedef +BOOLEAN +(*CSR_WAIT_FUNCTION)( + IN PLIST_ENTRY WaitList, + IN PCSR_THREAD WaitThread, + IN PCSR_API_MESSAGE WaitApiMessage, + IN PVOID WaitContext, + IN PVOID WaitArgument1, + IN PVOID WaitArgument2, + IN ULONG WaitFlags +); + +typedef struct _CSR_WAIT_BLOCK +{ + ULONG Size; + LIST_ENTRY WaitList; + LIST_ENTRY UserWaitList; + PVOID WaitContext; + PCSR_THREAD WaitThread; + CSR_WAIT_FUNCTION WaitFunction; + CSR_API_MESSAGE WaitApiMessage; +} CSR_WAIT_BLOCK, *PCSR_WAIT_BLOCK; + typedef NTSTATUS (WINAPI *CSRSS_API_PROC)(PCSR_PROCESS ProcessData, PCSR_API_MESSAGE Request); @@ -165,6 +207,10 @@ VOID NTAPI CsrRemoveProcess(IN PCSR_PROCESS CsrProcess); +VOID +NTAPI +CsrDereferenceThread(IN PCSR_THREAD CsrThread); + VOID NTAPI CsrInsertProcess(IN PCSR_PROCESS Parent OPTIONAL, @@ -179,6 +225,11 @@ VOID FASTCALL CsrApiCallHandler(PCSR_PROCESS ProcessData, VOID WINAPI CsrSbApiRequestThread (PVOID PortHandle); VOID NTAPI ClientConnectionThread(HANDLE ServerPort); +VOID +NTAPI +CsrReleaseCapturedArguments(IN PCSR_API_MESSAGE ApiMessage); + +extern HANDLE CsrSmApiPort; extern HANDLE CsrSbApiPort; extern LIST_ENTRY CsrThreadHashTable[256]; extern PCSR_PROCESS CsrRootProcess; @@ -211,6 +262,10 @@ NTSTATUS NTAPI CsrUnlockProcess(IN PCSR_PROCESS CsrProcess); //hack VOID NTAPI CsrThreadRefcountZero(IN PCSR_THREAD CsrThread); +NTSTATUS +NTAPI +CsrInitializeNtSessionList(VOID); + /* api/user.c */ CSR_API(CsrRegisterServicesProcess);