mirror of
https://github.com/reactos/reactos.git
synced 2025-02-24 17:34:57 +00:00
[CSRSRV]: Port the CsrWait* and CsrSession* APIs from CSRSRV2. Not yet used, so no real functional change. Fixup a few structures where needed. Initalize session support during CSRSRV initialization. We have a pretty good hybrid now, some few more changes here and there and we can perhaps start having the beginnings our own "basesrv.dll",
svn path=/trunk/; revision=55626
This commit is contained in:
parent
0f20fb2587
commit
8bd17c0446
9 changed files with 794 additions and 2 deletions
|
@ -11,6 +11,8 @@ list(APPEND SOURCE
|
||||||
procsup.c
|
procsup.c
|
||||||
thredsup.c
|
thredsup.c
|
||||||
init.c
|
init.c
|
||||||
|
wait.c
|
||||||
|
session.c
|
||||||
${CMAKE_CURRENT_BINARY_DIR}/csrsrv.def)
|
${CMAKE_CURRENT_BINARY_DIR}/csrsrv.def)
|
||||||
|
|
||||||
add_library(csrsrv SHARED ${SOURCE})
|
add_library(csrsrv SHARED ${SOURCE})
|
||||||
|
|
|
@ -986,6 +986,70 @@ ClientConnectionThread(HANDLE ServerPort)
|
||||||
RtlExitUserThread(STATUS_SUCCESS);
|
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**************************************************/
|
/* SESSION MANAGER FUNCTIONS**************************************************/
|
||||||
|
|
||||||
/*++
|
/*++
|
||||||
|
|
|
@ -18,5 +18,7 @@
|
||||||
<file>procsup.c</file>
|
<file>procsup.c</file>
|
||||||
<file>thredsup.c</file>
|
<file>thredsup.c</file>
|
||||||
<file>init.c</file>
|
<file>init.c</file>
|
||||||
|
<file>wait.c</file>
|
||||||
|
<file>session.c</file
|
||||||
<pch>srv.h</pch>
|
<pch>srv.h</pch>
|
||||||
</module>
|
</module>
|
||||||
|
|
|
@ -1117,6 +1117,15 @@ CsrServerInitialization(IN ULONG ArgumentCount,
|
||||||
return 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 */
|
/* Set up Process Support */
|
||||||
Status = CsrInitializeProcessStructure();
|
Status = CsrInitializeProcessStructure();
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
|
|
||||||
/* GLOBALS ********************************************************************/
|
/* GLOBALS ********************************************************************/
|
||||||
|
|
||||||
RTL_CRITICAL_SECTION ProcessDataLock, CsrWaitListsLock;
|
RTL_CRITICAL_SECTION ProcessDataLock;
|
||||||
PCSR_PROCESS CsrRootProcess;
|
PCSR_PROCESS CsrRootProcess;
|
||||||
SECURITY_QUALITY_OF_SERVICE CsrSecurityQos =
|
SECURITY_QUALITY_OF_SERVICE CsrSecurityQos =
|
||||||
{
|
{
|
||||||
|
|
175
reactos/subsystems/win32/csrss/csrsrv/session.c
Normal file
175
reactos/subsystems/win32/csrss/csrsrv/session.c
Normal file
|
@ -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 <debug.h>
|
||||||
|
|
||||||
|
/* 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 */
|
|
@ -407,4 +407,40 @@ CsrAddStaticServerThread(IN HANDLE hThread,
|
||||||
return CsrThread;
|
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 */
|
/* EOF */
|
||||||
|
|
449
reactos/subsystems/win32/csrss/csrsrv/wait.c
Normal file
449
reactos/subsystems/win32/csrss/csrsrv/wait.c
Normal file
|
@ -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 <debug.h>
|
||||||
|
|
||||||
|
/* 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 */
|
|
@ -22,6 +22,18 @@
|
||||||
#define ProcessStructureListLocked() \
|
#define ProcessStructureListLocked() \
|
||||||
(ProcessDataLock.OwningThread == NtCurrentTeb()->ClientId.UniqueThread)
|
(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
|
typedef enum _CSR_THREAD_FLAGS
|
||||||
{
|
{
|
||||||
CsrThreadAltertable = 0x1,
|
CsrThreadAltertable = 0x1,
|
||||||
|
@ -66,6 +78,13 @@ typedef struct _CSRSS_CON_PROCESS_DATA
|
||||||
LIST_ENTRY ConsoleLink;
|
LIST_ENTRY ConsoleLink;
|
||||||
} CSRSS_CON_PROCESS_DATA, *PCSRSS_CON_PROCESS_DATA;
|
} 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
|
typedef struct _CSR_PROCESS
|
||||||
{
|
{
|
||||||
CLIENT_ID ClientId;
|
CLIENT_ID ClientId;
|
||||||
|
@ -102,13 +121,36 @@ typedef struct _CSR_THREAD
|
||||||
LIST_ENTRY HashLinks;
|
LIST_ENTRY HashLinks;
|
||||||
CLIENT_ID ClientId;
|
CLIENT_ID ClientId;
|
||||||
PCSR_PROCESS Process;
|
PCSR_PROCESS Process;
|
||||||
//struct _CSR_WAIT_BLOCK *WaitBlock;
|
struct _CSR_WAIT_BLOCK *WaitBlock;
|
||||||
HANDLE ThreadHandle;
|
HANDLE ThreadHandle;
|
||||||
ULONG Flags;
|
ULONG Flags;
|
||||||
ULONG ReferenceCount;
|
ULONG ReferenceCount;
|
||||||
ULONG ImpersonationCount;
|
ULONG ImpersonationCount;
|
||||||
} CSR_THREAD, *PCSR_THREAD;
|
} 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,
|
typedef NTSTATUS (WINAPI *CSRSS_API_PROC)(PCSR_PROCESS ProcessData,
|
||||||
PCSR_API_MESSAGE Request);
|
PCSR_API_MESSAGE Request);
|
||||||
|
|
||||||
|
@ -165,6 +207,10 @@ VOID
|
||||||
NTAPI
|
NTAPI
|
||||||
CsrRemoveProcess(IN PCSR_PROCESS CsrProcess);
|
CsrRemoveProcess(IN PCSR_PROCESS CsrProcess);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
NTAPI
|
||||||
|
CsrDereferenceThread(IN PCSR_THREAD CsrThread);
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
NTAPI
|
NTAPI
|
||||||
CsrInsertProcess(IN PCSR_PROCESS Parent OPTIONAL,
|
CsrInsertProcess(IN PCSR_PROCESS Parent OPTIONAL,
|
||||||
|
@ -179,6 +225,11 @@ VOID FASTCALL CsrApiCallHandler(PCSR_PROCESS ProcessData,
|
||||||
VOID WINAPI CsrSbApiRequestThread (PVOID PortHandle);
|
VOID WINAPI CsrSbApiRequestThread (PVOID PortHandle);
|
||||||
VOID NTAPI ClientConnectionThread(HANDLE ServerPort);
|
VOID NTAPI ClientConnectionThread(HANDLE ServerPort);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
NTAPI
|
||||||
|
CsrReleaseCapturedArguments(IN PCSR_API_MESSAGE ApiMessage);
|
||||||
|
|
||||||
|
extern HANDLE CsrSmApiPort;
|
||||||
extern HANDLE CsrSbApiPort;
|
extern HANDLE CsrSbApiPort;
|
||||||
extern LIST_ENTRY CsrThreadHashTable[256];
|
extern LIST_ENTRY CsrThreadHashTable[256];
|
||||||
extern PCSR_PROCESS CsrRootProcess;
|
extern PCSR_PROCESS CsrRootProcess;
|
||||||
|
@ -211,6 +262,10 @@ NTSTATUS NTAPI CsrUnlockProcess(IN PCSR_PROCESS CsrProcess);
|
||||||
//hack
|
//hack
|
||||||
VOID NTAPI CsrThreadRefcountZero(IN PCSR_THREAD CsrThread);
|
VOID NTAPI CsrThreadRefcountZero(IN PCSR_THREAD CsrThread);
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
CsrInitializeNtSessionList(VOID);
|
||||||
|
|
||||||
/* api/user.c */
|
/* api/user.c */
|
||||||
CSR_API(CsrRegisterServicesProcess);
|
CSR_API(CsrRegisterServicesProcess);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue