reactos/subsystems/win32/csrsrv/wait.c
Hermès Bélusca-Maïto b75ee7fd14 [CSRSRV]
- Zero-out some allocated memory.
- During my investigations preceding the implementation of AttachConsole (r58166), I wanted (in a first attempt; finally I've found a better way to achieve what I wanted to do) to retrieve the CSR_PROCESS structure of the parent of a given process. I've found the 'Parent' member in the CSR_PROCESS structure, however this member was always initialized to NULL when new processes were created via CsrCreateProcess (and via the call to CsrInsertProcess). After looking at some informating here (http://svn.reactos.org/svn/reactos/trunk/reactos/include/subsys/csr/server.h?r1=17363&r2=17362&pathrev=17363) and there (http://forum.sysinternals.com/csrwalker-processes-detection-from-user-mode_topic15457.html), I became convinced that the 'Parent' member was unexistent starting from Windows Server 2003. Also, after much more investigation, I've found that the CsrInsertProcess function was called with only two parameters starting from Windows Server 2003 (and still continues in Windows 7), the always-NULL paramater being removed.
Therefore, I remove that unneeded parameter from CsrInsertProcess and the corresponding 'Parent' member from CSR_PROCESS.

svn path=/branches/ros-csrss/; revision=58232
2013-01-26 21:23:10 +00:00

452 lines
12 KiB
C

/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS Client/Server Runtime SubSystem
* FILE: subsystems/win32/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 otherwise.
*
* @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, HEAP_ZERO_MEMORY, Size);
if (!WaitBlock)
{
/* Fail */
WaitApiMessage->Status = STATUS_NO_MEMORY;
return FALSE;
}
/* Initialize it */
WaitBlock->Size = Size;
WaitBlock->WaitThread = CsrWaitThread;
CsrWaitThread->WaitBlock = WaitBlock;
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 the 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 succeeded */
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 */
CsrWaitThread->WaitBlock = NULL;
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 dereferences 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 (satisfied wait) */
if (WaitBlock->WaitFunction == NULL)
{
/* 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's no Wait Routine (satisfied wait) */
if (WaitBlock->WaitFunction == NULL)
{
/* 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 otherwise.
*
* @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 Routine */
if (WaitBlock->WaitFunction != NULL)
{
/* 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 */