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);