📄 process.c
字号:
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS CSR Sub System
* FILE: subsys/csr/csrsrv/process.c
* PURPOSE: CSR Server DLL Process Implementation
* PROGRAMMERS: Alex Ionescu (alex@relsoft.net)
*/
/* INCLUDES ******************************************************************/
#include "srv.h"
#define NDEBUG
#include <debug.h>
/* DATA **********************************************************************/
PCSR_PROCESS CsrRootProcess = NULL;
RTL_CRITICAL_SECTION CsrProcessLock;
ULONG CsrProcessSequenceCount = 5;
ULONG CsrTotalPerProcessDataLength;
/* PRIVATE FUNCTIONS *********************************************************/
/*++
* @name CsrAllocateProcess
* @implemented NT4
*
* The CsrAllocateProcess routine allocates a new CSR Process object.
*
* @return Pointer to the newly allocated CSR Process.
*
* @remarks None.
*
*--*/
PCSR_PROCESS
NTAPI
CsrAllocateProcess(VOID)
{
PCSR_PROCESS CsrProcess;
ULONG TotalSize;
/* Calculate the amount of memory this should take */
TotalSize = sizeof(CSR_PROCESS) +
(CSR_SERVER_DLL_MAX * sizeof(PVOID)) +
CsrTotalPerProcessDataLength;
/* Allocate a Process */
CsrProcess = RtlAllocateHeap(CsrHeap, HEAP_ZERO_MEMORY, TotalSize);
if (!CsrProcess) return NULL;
/* Handle the Sequence Number */
CsrProcess->SequenceNumber = CsrProcessSequenceCount++;
/* Increase the reference count */
CsrProcess->ReferenceCount++;
/* Initialize the Thread List */
InitializeListHead(&CsrProcess->ThreadList);
/* Return the Process */
return CsrProcess;
}
/*++
* @name CsrServerInitialization
* @implemented NT4
*
* The CsrInitializeProcesses routine sets up support for CSR Processes
* and CSR Threads.
*
* @param None.
*
* @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
* othwerwise.
*
* @remarks None.
*
*--*/
NTSTATUS
NTAPI
CsrInitializeProcesses(VOID)
{
NTSTATUS Status;
ULONG i;
/* Initialize the Lock */
Status = RtlInitializeCriticalSection(&CsrProcessLock);
/* Set up the Root Process */
CsrRootProcess = CsrAllocateProcess();
if (!CsrRootProcess) return STATUS_NO_MEMORY;
/* Set up the minimal information for it */
InitializeListHead(&CsrRootProcess->ListLink);
CsrRootProcess->ProcessHandle = (HANDLE)-1;
CsrRootProcess->ClientId = NtCurrentTeb()->Cid;
/* Initialize the Thread Hash List */
for (i = 0; i < 256; i++) InitializeListHead(&CsrThreadHashTable[i]);
/* Initialize the Wait Lock */
Status = RtlInitializeCriticalSection(&CsrWaitListsLock);
return Status;
}
/*++
* @name CsrDeallocateProcess
*
* The CsrDeallocateProcess frees the memory associated with a CSR Process.
*
* @param CsrProcess
* Pointer to the CSR Process to be freed.
*
* @return None.
*
* @remarks Do not call this routine. It is reserved for the internal
* thread management routines when a CSR Process has been cleanly
* dereferenced and killed.
*
*--*/
VOID
NTAPI
CsrDeallocateProcess(IN PCSR_PROCESS CsrProcess)
{
/* Free the process object from the heap */
RtlFreeHeap(CsrHeap, 0, CsrProcess);
}
/*++
* @name CsrInsertProcess
*
* The CsrInsertProcess routine inserts a CSR Process into the Process List
* and notifies Server DLLs of the creation of a new CSR Process.
*
* @param Parent
* Optional pointer to the CSR Process creating this CSR Process.
*
* @param CurrentProcess
* Optional pointer to the current CSR Process.
*
* @param CsrProcess
* Pointer to the CSR Process which is to be inserted.
*
* @return None.
*
* @remarks None.
*
*--*/
VOID
NTAPI
CsrInsertProcess(IN PCSR_PROCESS Parent OPTIONAL,
IN PCSR_PROCESS CurrentProcess OPTIONAL,
IN PCSR_PROCESS CsrProcess)
{
PCSR_SERVER_DLL ServerDll;
ULONG i;
/* Set the parent */
CsrProcess->Parent = Parent;
/* Insert it into the Root List */
InsertTailList(&CsrRootProcess->ListLink, &CsrProcess->ListLink);
/* Notify the Server DLLs */
for (i = 0; i < CSR_SERVER_DLL_MAX; i++)
{
/* Get the current Server DLL */
ServerDll = CsrLoadedServerDll[i];
/* Make sure it's valid and that it has callback */
if (ServerDll && ServerDll->NewProcessCallback)
{
(*ServerDll->NewProcessCallback)(CurrentProcess, CsrProcess);
}
}
}
/*++
* @name CsrLockedDereferenceProcess
*
* The CsrLockedDereferenceProcess dereferences a CSR Process while the
* Process Lock is already being held.
*
* @param CsrProcess
* Pointer to the CSR Process to be dereferenced.
*
* @return None.
*
* @remarks This routine will return with the Process Lock held.
*
*--*/
VOID
NTAPI
CsrLockedDereferenceProcess(PCSR_PROCESS CsrProcess)
{
/* Decrease reference count */
if (!(--CsrProcess->ReferenceCount))
{
/* Call the generic cleanup code */
CsrAcquireProcessLock();
CsrProcessRefcountZero(CsrProcess);
}
}
/*++
* @name CsrRemoveProcess
*
* The CsrRemoveProcess function undoes a CsrInsertProcess operation and
* removes the CSR Process from the Process List and notifies Server DLLs
* of this removal.
*
* @param CsrProcess
* Pointer to the CSR Process to remove.
*
* @return None.
*
* @remarks None.
*
*--*/
VOID
NTAPI
CsrRemoveProcess(IN PCSR_PROCESS CsrProcess)
{
PCSR_SERVER_DLL ServerDll;
ULONG i;
/* Remove us from the Process List */
RemoveEntryList(&CsrProcess->ListLink);
/* Release the lock */
CsrReleaseProcessLock();
/* Loop every Server DLL */
for (i = 0; i < CSR_SERVER_DLL_MAX; i++)
{
/* Get the Server DLL */
ServerDll = CsrLoadedServerDll[i];
/* Check if it's valid and if it has a Disconnect Callback */
if (ServerDll && ServerDll->DisconnectCallback)
{
/* Call it */
(ServerDll->DisconnectCallback)(CsrProcess);
}
}
}
/*++
* @name CsrProcessRefcountZero
*
* The CsrProcessRefcountZero routine is executed when a CSR Process has lost
* all its active references. It removes and de-allocates the CSR Process.
*
* @param CsrProcess
* Pointer to the CSR Process that is to be deleted.
*
* @return None.
*
* @remarks Do not call this routine. It is reserved for the internal
* thread management routines when a CSR Process has lost all
* its references.
*
* This routine is called with the Process Lock held.
*
*--*/
VOID
NTAPI
CsrProcessRefcountZero(IN PCSR_PROCESS CsrProcess)
{
/* Remove the Process from the list */
CsrRemoveProcess(CsrProcess);
/* Check if there's a session */
if (CsrProcess->NtSession)
{
/* Dereference the Session */
CsrDereferenceNtSession(CsrProcess->NtSession, 0);
}
/* Close the Client Port if there is one */
if (CsrProcess->ClientPort ) NtClose(CsrProcess->ClientPort);
/* Close the process handle */
NtClose(CsrProcess->ProcessHandle);
/* Free the Proces Object */
CsrDeallocateProcess(CsrProcess);
}
/*++
* @name CsrSetToNormalPriority
*
* The CsrSetToNormalPriority routine sets the current NT Process'
* priority to the normal priority for CSR Processes.
*
* @param None.
*
* @return None.
*
* @remarks The "Normal" Priority corresponds to the Normal Forground
* Priority (9) plus a boost of 4.
*
*--*/
VOID
NTAPI
CsrSetToNormalPriority(VOID)
{
KPRIORITY BasePriority = (8 + 1) + 4;
/* Set the Priority */
NtSetInformationProcess(NtCurrentProcess(),
ProcessBasePriority,
&BasePriority,
sizeof(KPRIORITY));
}
/*++
* @name CsrSetToShutdownPriority
*
* The CsrSetToShutdownPriority routine sets the current NT Process'
* priority to the boosted priority for CSR Processes doing shutdown.
* Additonally, it acquires the Shutdown Privilege required for shutdown.
*
* @param None.
*
* @return None.
*
* @remarks The "Shutdown" Priority corresponds to the Normal Forground
* Priority (9) plus a boost of 6.
*
*--*/
VOID
NTAPI
CsrSetToShutdownPriority(VOID)
{
KPRIORITY SetBasePriority = (8 + 1) + 6;
BOOLEAN Old;
/* Get the shutdown privilege */
if (NT_SUCCESS(RtlAdjustPrivilege(SE_SHUTDOWN_PRIVILEGE,
TRUE,
FALSE,
&Old)))
{
/* Set the Priority */
NtSetInformationProcess(NtCurrentProcess(),
ProcessBasePriority,
&SetBasePriority,
sizeof(KPRIORITY));
}
}
/*++
* @name FindProcessForShutdown
*
* The FindProcessForShutdown routine returns a CSR Process which is ready
* to be shutdown, and sets the appropriate shutdown flags for it.
*
* @param CallerLuid
* Pointer to the LUID of the CSR Process calling this routine.
*
* @return Pointer to a CSR Process which is ready to be shutdown.
*
* @remarks None.
*
*--*/
PCSR_PROCESS
NTAPI
FindProcessForShutdown(PLUID CallerLuid)
{
PLIST_ENTRY ListHead, NextEntry;
LUID ProcessLuid;
NTSTATUS Status;
LUID SystemLuid = SYSTEM_LUID;
PCSR_PROCESS CsrProcess;
PCSR_THREAD CsrThread;
BOOLEAN IsSystemLuid = FALSE, IsOurLuid = FALSE;
PCSR_PROCESS ReturnCsrProcess = NULL;
ULONG Level = 0;
/* Set the List Pointers */
ListHead = &CsrRootProcess->ListLink;
NextEntry = ListHead->Flink;
/* Start looping */
while (NextEntry != ListHead)
{
/* Get the process */
CsrProcess = CONTAINING_RECORD(NextEntry, CSR_PROCESS, ListLink);
/* Move to the next entry */
NextEntry = NextEntry->Flink;
/* Skip this process if it's already been processed*/
if (CsrProcess->Flags & CsrProcessSkipShutdown) continue;
/* Get the LUID of this Process */
Status = CsrGetProcessLuid(CsrProcess->ProcessHandle, &ProcessLuid);
/* Check if we didn't get access to the LUID */
if (Status == STATUS_ACCESS_DENIED)
{
/* Check if we have any threads */
if (CsrProcess->ThreadCount)
{
/* Impersonate one of the threads and retry */
CsrThread = CONTAINING_RECORD(CsrProcess->ThreadList.Flink,
CSR_THREAD,
Link);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -