Start source tree (final, I hope!) restructuration. Part 1/X
[reactos.git] / reactos / subsystems / win32 / csrsrv / procsup.c
diff --git a/reactos/subsystems/win32/csrsrv/procsup.c b/reactos/subsystems/win32/csrsrv/procsup.c
deleted file mode 100644 (file)
index e2ae6ce..0000000
+++ /dev/null
@@ -1,1408 +0,0 @@
-/*
- * COPYRIGHT:       See COPYING in the top level directory
- * PROJECT:         ReactOS Client/Server Runtime SubSystem
- * FILE:            subsystems/win32/csrsrv/procsup.c
- * PURPOSE:         CSR Server DLL Process Management
- * PROGRAMMERS:     ReactOS Portable Systems Group
- *                  Alex Ionescu (alex@relsoft.net)
- */
-
-/* INCLUDES *******************************************************************/
-
-#include <srv.h>
-
-#include <winuser.h>
-
-#define NDEBUG
-#include <debug.h>
-
-/* GLOBALS ********************************************************************/
-
-RTL_CRITICAL_SECTION CsrProcessLock;
-PCSR_PROCESS CsrRootProcess = NULL;
-SECURITY_QUALITY_OF_SERVICE CsrSecurityQos =
-{
-    sizeof(SECURITY_QUALITY_OF_SERVICE),
-    SecurityImpersonation,
-    SECURITY_STATIC_TRACKING,
-    FALSE
-};
-ULONG CsrProcessSequenceCount = 5;
-extern ULONG CsrTotalPerProcessDataLength;
-
-
-/* PRIVATE FUNCTIONS **********************************************************/
-
-/*++
- * @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 Foreground
- *          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 Foreground
- *          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 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)
-{
-    ASSERT(ProcessStructureListLocked());
-
-    /* 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 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)
-{
-    LONG LockCount;
-
-    /* Decrease reference count */
-    LockCount = --CsrProcess->ReferenceCount;
-    ASSERT(LockCount >= 0);
-    if (LockCount == 0)
-    {
-        /* Call the generic cleanup code */
-        DPRINT1("Should kill process: %p\n", CsrProcess);
-        CsrAcquireProcessLock();
-        CsrProcessRefcountZero(CsrProcess);
-    }
-}
-
-/*++
- * @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 and protect against overflow */
-    CsrProcess->SequenceNumber = CsrProcessSequenceCount++;
-    if (CsrProcessSequenceCount < 5) CsrProcessSequenceCount = 5;
-
-    /* Increase the reference count */
-    CsrLockedReferenceProcess(CsrProcess);
-
-    /* Initialize the Thread List */
-    InitializeListHead(&CsrProcess->ThreadList);
-
-    /* Return the Process */
-    return CsrProcess;
-}
-
-/*++
- * @name CsrLockedReferenceProcess
- *
- * The CsrLockedReferenceProcess references a CSR Process while the
- * Process Lock is already being held.
- *
- * @param CsrProcess
- *        Pointer to the CSR Process to be referenced.
- *
- * @return None.
- *
- * @remarks This routine will return with the Process Lock held.
- *
- *--*/
-VOID
-NTAPI
-CsrLockedReferenceProcess(IN PCSR_PROCESS CsrProcess)
-{
-    /* Increment the reference count */
-    ++CsrProcess->ReferenceCount;
-}
-
-/*++
- * @name CsrInitializeProcessStructure
- * @implemented NT4
- *
- * The CsrInitializeProcessStructure routine sets up support for CSR Processes
- * and CSR Threads by initializing our own CSR Root Process.
- *
- * @param None.
- *
- * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL otherwise.
- *
- * @remarks None.
- *
- *--*/
-NTSTATUS
-NTAPI
-CsrInitializeProcessStructure(VOID)
-{
-    NTSTATUS Status;
-    ULONG i;
-
-    /* Initialize the Lock */
-    Status = RtlInitializeCriticalSection(&CsrProcessLock);
-    if (!NT_SUCCESS(Status)) return Status;
-
-    /* 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()->ClientId;
-
-    /* Initialize the Thread Hash List */
-    for (i = 0; i < NUMBER_THREAD_HASH_BUCKETS; i++) InitializeListHead(&CsrThreadHashTable[i]);
-
-    /* Initialize the Wait Lock */
-    return RtlInitializeCriticalSection(&CsrWaitListsLock);
-}
-
-/*++
- * @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 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;
-    ASSERT(ProcessStructureListLocked());
-
-    /* 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 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 ParentProcess
- *        Optional pointer to the Parent Process creating this CSR Process.
- *
- * @param CsrProcess
- *        Pointer to the CSR Process which is to be inserted.
- *
- * @return None.
- *
- * @remarks None.
- *
- *--*/
-VOID
-NTAPI
-CsrInsertProcess(IN PCSR_PROCESS ParentProcess OPTIONAL,
-                 IN PCSR_PROCESS CsrProcess)
-{
-    PCSR_SERVER_DLL ServerDll;
-    ULONG i;
-    ASSERT(ProcessStructureListLocked());
-
-    /* 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(ParentProcess, CsrProcess);
-        }
-    }
-}
-
-
-/* PUBLIC FUNCTIONS ***********************************************************/
-
-/*++
- * @name CsrCreateProcess
- * @implemented NT4
- *
- * The CsrCreateProcess routine creates a CSR Process object for an NT Process.
- *
- * @param hProcess
- *        Handle to an existing NT Process to which to associate this
- *        CSR Process.
- *
- * @param hThread
- *        Handle to an existing NT Thread to which to create its
- *        corresponding CSR Thread for this CSR Process.
- *
- * @param ClientId
- *        Pointer to the Client ID structure of the NT Process to associate
- *        with this CSR Process.
- *
- * @param NtSession
- * @param Flags
- * @param DebugCid
- *
- * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL otherwise.
- *
- * @remarks None.
- *
- *--*/
-NTSTATUS
-NTAPI
-CsrCreateProcess(IN HANDLE hProcess,
-                 IN HANDLE hThread,
-                 IN PCLIENT_ID ClientId,
-                 IN PCSR_NT_SESSION NtSession,
-                 IN ULONG Flags,
-                 IN PCLIENT_ID DebugCid)
-{
-    PCSR_THREAD CurrentThread = CsrGetClientThread();
-    CLIENT_ID CurrentCid;
-    PCSR_PROCESS CurrentProcess;
-    PCSR_SERVER_DLL ServerDll;
-    PVOID ProcessData;
-    ULONG i;
-    PCSR_PROCESS CsrProcess;
-    NTSTATUS Status;
-    PCSR_THREAD CsrThread;
-    KERNEL_USER_TIMES KernelTimes;
-
-    /* Get the current CID and lock Processes */
-    CurrentCid = CurrentThread->ClientId;
-    CsrAcquireProcessLock();
-
-    /* Get the current CSR Thread */
-    CurrentThread = CsrLocateThreadByClientId(&CurrentProcess, &CurrentCid);
-    if (!CurrentThread)
-    {
-        /* We've failed to locate the thread */
-        CsrReleaseProcessLock();
-        return STATUS_THREAD_IS_TERMINATING;
-    }
-
-    /* Allocate a new Process Object */
-    CsrProcess = CsrAllocateProcess();
-    if (!CsrProcess)
-    {
-        /* Couldn't allocate Process */
-        CsrReleaseProcessLock();
-        return STATUS_NO_MEMORY;
-    }
-
-    /* Inherit the Process Data */
-    CurrentProcess = CurrentThread->Process;
-    ProcessData = &CsrProcess->ServerData[CSR_SERVER_DLL_MAX];
-    for (i = 0; i < CSR_SERVER_DLL_MAX; i++)
-    {
-        /* Get the current Server */
-        ServerDll = CsrLoadedServerDll[i];
-
-        /* Check if the DLL is Loaded and has Per Process Data */
-        if (ServerDll && ServerDll->SizeOfProcessData)
-        {
-            /* Set the pointer */
-            CsrProcess->ServerData[i] = ProcessData;
-
-            /* Copy the Data */
-            RtlMoveMemory(ProcessData,
-                          CurrentProcess->ServerData[i],
-                          ServerDll->SizeOfProcessData);
-
-            /* Update next data pointer */
-            ProcessData = (PVOID)((ULONG_PTR)ProcessData +
-                                  ServerDll->SizeOfProcessData);
-        }
-        else
-        {
-            /* No data for this Server */
-            CsrProcess->ServerData[i] = NULL;
-        }
-    }
-
-    /* Set the Exception port for us */
-    Status = NtSetInformationProcess(hProcess,
-                                     ProcessExceptionPort,
-                                     &CsrApiPort,
-                                     sizeof(HANDLE));
-    if (!NT_SUCCESS(Status))
-    {
-        /* Failed */
-        CsrDeallocateProcess(CsrProcess);
-        CsrReleaseProcessLock();
-        return STATUS_NO_MEMORY;
-    }
-
-    /* Check if CreateProcess got CREATE_NEW_PROCESS_GROUP */
-    if (Flags & CsrProcessCreateNewGroup)
-    {
-        /*
-         * We create the process group leader of a new process group, therefore
-         * its process group ID and sequence number are its own ones.
-         */
-        CsrProcess->ProcessGroupId = HandleToUlong(ClientId->UniqueProcess);
-        CsrProcess->ProcessGroupSequence = CsrProcess->SequenceNumber;
-    }
-    else
-    {
-        /* Inherit the process group ID and sequence number from the current process */
-        CsrProcess->ProcessGroupId = CurrentProcess->ProcessGroupId;
-        CsrProcess->ProcessGroupSequence = CurrentProcess->ProcessGroupSequence;
-    }
-
-    /* Check if this is a console process */
-    if (Flags & CsrProcessIsConsoleApp) CsrProcess->Flags |= CsrProcessIsConsoleApp;
-
-    /* Mask out non-debug flags */
-    Flags &= ~(CsrProcessIsConsoleApp | CsrProcessCreateNewGroup | CsrProcessPriorityFlags);
-
-    /* Check if every process will be debugged */
-    if (!(Flags) && (CurrentProcess->DebugFlags & CsrDebugProcessChildren))
-    {
-        /* Pass it on to the current process */
-        CsrProcess->DebugFlags = CsrDebugProcessChildren;
-        CsrProcess->DebugCid = CurrentProcess->DebugCid;
-    }
-
-    /* Check if Debugging was used on this process */
-    if ((Flags & (CsrDebugOnlyThisProcess | CsrDebugProcessChildren)) && (DebugCid))
-    {
-        /* Save the debug flag used */
-        CsrProcess->DebugFlags = Flags;
-
-        /* Save the CID */
-        CsrProcess->DebugCid = *DebugCid;
-    }
-
-    /* Check if Debugging is enabled */
-    if (CsrProcess->DebugFlags)
-    {
-        /* Set the Debug Port for us */
-        Status = NtSetInformationProcess(hProcess,
-                                         ProcessDebugPort,
-                                         &CsrApiPort,
-                                         sizeof(HANDLE));
-        ASSERT(NT_SUCCESS(Status));
-        if (!NT_SUCCESS(Status))
-        {
-            /* Failed */
-            CsrDeallocateProcess(CsrProcess);
-            CsrReleaseProcessLock();
-            return STATUS_NO_MEMORY;
-        }
-    }
-
-    /* Get the Thread Create Time */
-    Status = NtQueryInformationThread(hThread,
-                                      ThreadTimes,
-                                      (PVOID)&KernelTimes,
-                                      sizeof(KernelTimes),
-                                      NULL);
-    if (!NT_SUCCESS(Status))
-    {
-        /* Failed */
-        CsrDeallocateProcess(CsrProcess);
-        CsrReleaseProcessLock();
-        return STATUS_NO_MEMORY;
-    }
-
-    /* Allocate a CSR Thread Structure */
-    CsrThread = CsrAllocateThread(CsrProcess);
-    if (!CsrThread)
-    {
-        /* Failed */
-        CsrDeallocateProcess(CsrProcess);
-        CsrReleaseProcessLock();
-        return STATUS_NO_MEMORY;
-    }
-
-    /* Save the data we have */
-    CsrThread->CreateTime = KernelTimes.CreateTime;
-    CsrThread->ClientId = *ClientId;
-    CsrThread->ThreadHandle = hThread;
-    ProtectHandle(hThread);
-    CsrThread->Flags = 0;
-
-    /* Insert the Thread into the Process */
-    Status = CsrInsertThread(CsrProcess, CsrThread);
-    if (!NT_SUCCESS(Status))
-    {
-        /* Bail out */
-        CsrDeallocateProcess(CsrProcess);
-        CsrDeallocateThread(CsrThread);
-        CsrReleaseProcessLock();
-        return Status;
-    }
-
-    /* Reference the session */
-    CsrReferenceNtSession(NtSession);
-    CsrProcess->NtSession = NtSession;
-
-    /* Setup Process Data */
-    CsrProcess->ClientId = *ClientId;
-    CsrProcess->ProcessHandle = hProcess;
-    CsrProcess->ShutdownLevel = 0x280;
-
-    /* Set the Priority to Background */
-    CsrSetBackgroundPriority(CsrProcess);
-
-    /* Insert the Process */
-    CsrInsertProcess(CurrentProcess, CsrProcess);
-
-    /* Release lock and return */
-    CsrReleaseProcessLock();
-    return Status;
-}
-
-/*++
- * @name CsrDebugProcess
- * @implemented NT4
- *
- * The CsrDebugProcess routine is deprecated in NT 5.1 and higher. It is
- * exported only for compatibility with older CSR Server DLLs.
- *
- * @param CsrProcess
- *        Deprecated.
- *
- * @return Deprecated
- *
- * @remarks Deprecated.
- *
- *--*/
-NTSTATUS
-NTAPI
-CsrDebugProcess(IN PCSR_PROCESS CsrProcess)
-{
-    /* CSR does not handle debugging anymore */
-    DPRINT("CSRSRV: %s(0x%p) called\n", __FUNCTION__, CsrProcess);
-    return STATUS_UNSUCCESSFUL;
-}
-
-/*++
- * @name CsrDebugProcessStop
- * @implemented NT4
- *
- * The CsrDebugProcessStop routine is deprecated in NT 5.1 and higher. It is
- * exported only for compatibility with older CSR Server DLLs.
- *
- * @param CsrProcess
- *        Deprecated.
- *
- * @return Deprecated
- *
- * @remarks Deprecated.
- *
- *--*/
-NTSTATUS
-NTAPI
-CsrDebugProcessStop(IN PCSR_PROCESS CsrProcess)
-{
-    /* CSR does not handle debugging anymore */
-    DPRINT("CSRSRV: %s(0x%p) called\n", __FUNCTION__, CsrProcess);
-    return STATUS_UNSUCCESSFUL;
-}
-
-/*++
- * @name CsrDereferenceProcess
- * @implemented NT4
- *
- * The CsrDereferenceProcess routine removes a reference from a CSR Process.
- *
- * @param CsrThread
- *        Pointer to the CSR Process to dereference.
- *
- * @return None.
- *
- * @remarks If the reference count has reached zero (ie: the CSR Process has
- *          no more active references), it will be deleted.
- *
- *--*/
-VOID
-NTAPI
-CsrDereferenceProcess(IN PCSR_PROCESS CsrProcess)
-{
-    LONG LockCount;
-
-    /* Acquire process lock */
-    CsrAcquireProcessLock();
-
-    /* Decrease reference count */
-    LockCount = --CsrProcess->ReferenceCount;
-    ASSERT(LockCount >= 0);
-    if (LockCount == 0)
-    {
-        /* Call the generic cleanup code */
-        CsrProcessRefcountZero(CsrProcess);
-    }
-    else
-    {
-        /* Just release the lock */
-        CsrReleaseProcessLock();
-    }
-}
-
-/*++
- * @name CsrDestroyProcess
- * @implemented NT4
- *
- * The CsrDestroyProcess routine destroys the CSR Process corresponding to
- * a given Client ID.
- *
- * @param Cid
- *        Pointer to the Client ID Structure corresponding to the CSR
- *        Process which is about to be destroyed.
- *
- * @param ExitStatus
- *        Unused.
- *
- * @return STATUS_SUCCESS in case of success, STATUS_THREAD_IS_TERMINATING
- *         if the CSR Process is already terminating.
- *
- * @remarks None.
- *
- *--*/
-NTSTATUS
-NTAPI
-CsrDestroyProcess(IN PCLIENT_ID Cid,
-                  IN NTSTATUS ExitStatus)
-{
-    PCSR_THREAD CsrThread;
-    PCSR_PROCESS CsrProcess;
-    CLIENT_ID ClientId = *Cid;
-    PLIST_ENTRY NextEntry;
-
-    /* Acquire lock */
-    CsrAcquireProcessLock();
-
-    /* Find the thread */
-    CsrThread = CsrLocateThreadByClientId(&CsrProcess, &ClientId);
-
-    /* Make sure we got one back, and that it's not already gone */
-    if (!(CsrThread) || (CsrProcess->Flags & CsrProcessTerminating))
-    {
-        /* Release the lock and return failure */
-        CsrReleaseProcessLock();
-        return STATUS_THREAD_IS_TERMINATING;
-    }
-
-    /* Set the terminated flag */
-    CsrProcess->Flags |= CsrProcessTerminating;
-
-    /* Get the List Pointers */
-    NextEntry = CsrProcess->ThreadList.Flink;
-    while (NextEntry != &CsrProcess->ThreadList)
-    {
-        /* Get the current thread entry */
-        CsrThread = CONTAINING_RECORD(NextEntry, CSR_THREAD, Link);
-
-        /* Move to the next entry */
-        NextEntry = NextEntry->Flink;
-
-        /* Make sure the thread isn't already dead */
-        if (CsrThread->Flags & CsrThreadTerminated)
-        {
-            /* Go the the next thread */
-            continue;
-        }
-
-        /* Set the Terminated flag */
-        CsrThread->Flags |= CsrThreadTerminated;
-
-        /* Acquire the Wait Lock */
-        CsrAcquireWaitLock();
-
-        /* Do we have an active wait block? */
-        if (CsrThread->WaitBlock)
-        {
-            /* Notify waiters of termination */
-            CsrNotifyWaitBlock(CsrThread->WaitBlock,
-                               NULL,
-                               NULL,
-                               NULL,
-                               CsrProcessTerminating,
-                               TRUE);
-        }
-
-        /* Release the Wait Lock */
-        CsrReleaseWaitLock();
-
-        /* Dereference the thread */
-        CsrLockedDereferenceThread(CsrThread);
-    }
-
-    /* Release the Process Lock and return success */
-    CsrReleaseProcessLock();
-    return STATUS_SUCCESS;
-}
-
-/*++
- * @name CsrGetProcessLuid
- * @implemented NT4
- *
- * The CsrGetProcessLuid routine gets the LUID of the given process.
- *
- * @param hProcess
- *        Optional handle to the process whose LUID should be returned.
- *
- * @param Luid
- *        Pointer to a LUID Pointer which will receive the CSR Process' LUID.
- *
- * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL otherwise.
- *
- * @remarks If hProcess is not supplied, then the current thread's token will
- *          be used. If that too is missing, then the current process' token
- *          will be used.
- *
- *--*/
-NTSTATUS
-NTAPI
-CsrGetProcessLuid(IN HANDLE hProcess OPTIONAL,
-                  OUT PLUID Luid)
-{
-    HANDLE hToken = NULL;
-    NTSTATUS Status;
-    ULONG Length;
-    PTOKEN_STATISTICS TokenStats;
-
-    /* Check if we have a handle to a CSR Process */
-    if (!hProcess)
-    {
-        /* We don't, so try opening the Thread's Token */
-        Status = NtOpenThreadToken(NtCurrentThread(),
-                                   TOKEN_QUERY,
-                                   FALSE,
-                                   &hToken);
-
-        /* Check for success */
-        if (!NT_SUCCESS(Status))
-        {
-            /* If we got some other failure, then return and quit */
-            if (Status != STATUS_NO_TOKEN) return Status;
-
-            /* We don't have a Thread Token, use a Process Token */
-            hProcess = NtCurrentProcess();
-            hToken = NULL;
-        }
-    }
-
-    /* Check if we have a token by now */
-    if (!hToken)
-    {
-        /* No token yet, so open the Process Token */
-        Status = NtOpenProcessToken(hProcess,
-                                    TOKEN_QUERY,
-                                    &hToken);
-        if (!NT_SUCCESS(Status))
-        {
-            /* Still no token, return the error */
-            return Status;
-        }
-    }
-
-    /* Now get the size we'll need for the Token Information */
-    Status = NtQueryInformationToken(hToken,
-                                     TokenStatistics,
-                                     NULL,
-                                     0,
-                                     &Length);
-
-    /* Allocate memory for the Token Info */
-    if (!(TokenStats = RtlAllocateHeap(CsrHeap, 0, Length)))
-    {
-        /* Fail and close the token */
-        NtClose(hToken);
-        return STATUS_NO_MEMORY;
-    }
-
-    /* Now query the information */
-    Status = NtQueryInformationToken(hToken,
-                                     TokenStatistics,
-                                     TokenStats,
-                                     Length,
-                                     &Length);
-
-    /* Close the handle */
-    NtClose(hToken);
-
-    /* Check for success */
-    if (NT_SUCCESS(Status))
-    {
-        /* Return the LUID */
-        *Luid = TokenStats->AuthenticationId;
-    }
-
-    /* Free the query information */
-    RtlFreeHeap(CsrHeap, 0, TokenStats);
-
-    /* Return the Status */
-    return Status;
-}
-
-/*++
- * @name CsrImpersonateClient
- * @implemented NT4
- *
- * The CsrImpersonateClient will impersonate the given CSR Thread.
- *
- * @param CsrThread
- *        Pointer to the CSR Thread to impersonate.
- *
- * @return TRUE if impersonation succeeded, FALSE otherwise.
- *
- * @remarks Impersonation can be recursive.
- *
- *--*/
-BOOLEAN
-NTAPI
-CsrImpersonateClient(IN PCSR_THREAD CsrThread)
-{
-    NTSTATUS Status;
-    PCSR_THREAD CurrentThread = CsrGetClientThread();
-
-    /* Use the current thread if none given */
-    if (!CsrThread) CsrThread = CurrentThread;
-
-    /* Still no thread, something is wrong */
-    if (!CsrThread)
-    {
-        /* Failure */
-        return FALSE;
-    }
-
-    /* Make the call */
-    Status = NtImpersonateThread(NtCurrentThread(),
-                                 CsrThread->ThreadHandle,
-                                 &CsrSecurityQos);
-
-    if (!NT_SUCCESS(Status))
-    {
-        /* Failure */
-        DPRINT1("CSRSS: Can't impersonate client thread - Status = %lx\n", Status);
-        // if (Status != STATUS_BAD_IMPERSONATION_LEVEL) DbgBreakPoint();
-        return FALSE;
-    }
-
-    /* Increase the impersonation count for the current thread */
-    if (CurrentThread) ++CurrentThread->ImpersonationCount;
-
-    /* Return Success */
-    return TRUE;
-}
-
-/*++
- * @name CsrLockProcessByClientId
- * @implemented NT4
- *
- * The CsrLockProcessByClientId routine locks the CSR Process corresponding
- * to the given Process ID and optionally returns it.
- *
- * @param Pid
- *        Process ID corresponding to the CSR Process which will be locked.
- *
- * @param CsrProcess
- *        Optional pointer to a CSR Process pointer which will hold the
- *        CSR Process corresponding to the given Process ID.
- *
- * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL otherwise.
- *
- * @remarks Locking a CSR Process is defined as acquiring an extra
- *          reference to it and returning with the Process Lock held.
- *
- *--*/
-NTSTATUS
-NTAPI
-CsrLockProcessByClientId(IN HANDLE Pid,
-                         OUT PCSR_PROCESS *CsrProcess)
-{
-    PLIST_ENTRY NextEntry;
-    PCSR_PROCESS CurrentProcess = NULL;
-    NTSTATUS Status = STATUS_UNSUCCESSFUL;
-
-    /* Acquire the lock */
-    CsrAcquireProcessLock();
-
-    /* Assume failure */
-    ASSERT(CsrProcess != NULL);
-    *CsrProcess = NULL;
-
-    /* Setup the List Pointers */
-    NextEntry = &CsrRootProcess->ListLink;
-    do
-    {
-        /* Get the Process */
-        CurrentProcess = CONTAINING_RECORD(NextEntry, CSR_PROCESS, ListLink);
-
-        /* Check for PID Match */
-        if (CurrentProcess->ClientId.UniqueProcess == Pid)
-        {
-            Status = STATUS_SUCCESS;
-            break;
-        }
-
-        /* Move to the next entry */
-        NextEntry = NextEntry->Flink;
-    } while (NextEntry != &CsrRootProcess->ListLink);
-
-    /* Check if we didn't find it in the list */
-    if (!NT_SUCCESS(Status))
-    {
-        /* Nothing found, release the lock */
-        CsrReleaseProcessLock();
-    }
-    else
-    {
-        /* Lock the found process and return it */
-        CsrLockedReferenceProcess(CurrentProcess);
-        *CsrProcess = CurrentProcess;
-    }
-
-    /* Return the result */
-    return Status;
-}
-
-/*++
- * @name CsrRevertToSelf
- * @implemented NT4
- *
- * The CsrRevertToSelf routine will attempt to remove an active impersonation.
- *
- * @param None.
- *
- * @return TRUE if the reversion was succesful, FALSE otherwise.
- *
- * @remarks Impersonation can be recursive; as such, the impersonation token
- *          will only be deleted once the CSR Thread's impersonaton count
- *          has reached zero.
- *
- *--*/
-BOOLEAN
-NTAPI
-CsrRevertToSelf(VOID)
-{
-    NTSTATUS Status;
-    PCSR_THREAD CurrentThread = CsrGetClientThread();
-    HANDLE ImpersonationToken = NULL;
-
-    /* Check if we have a Current Thread */
-    if (CurrentThread)
-    {
-        /* Make sure impersonation is on */
-        if (!CurrentThread->ImpersonationCount)
-        {
-            DPRINT1("CSRSS: CsrRevertToSelf called while not impersonating\n");
-            // DbgBreakPoint();
-            return FALSE;
-        }
-        else if ((--CurrentThread->ImpersonationCount) > 0)
-        {
-            /* Success; impersonation count decreased but still not zero */
-            return TRUE;
-        }
-    }
-
-    /* Impersonation has been totally removed, revert to ourselves */
-    Status = NtSetInformationThread(NtCurrentThread(),
-                                    ThreadImpersonationToken,
-                                    &ImpersonationToken,
-                                    sizeof(HANDLE));
-
-    /* Return TRUE or FALSE */
-    return NT_SUCCESS(Status);
-}
-
-/*++
- * @name CsrSetBackgroundPriority
- * @implemented NT4
- *
- * The CsrSetBackgroundPriority routine sets the priority for the given CSR
- * Process as a Background priority.
- *
- * @param CsrProcess
- *        Pointer to the CSR Process whose priority will be modified.
- *
- * @return None.
- *
- * @remarks None.
- *
- *--*/
-VOID
-NTAPI
-CsrSetBackgroundPriority(IN PCSR_PROCESS CsrProcess)
-{
-    PROCESS_PRIORITY_CLASS PriorityClass;
-
-    /* Set the Foreground bit off */
-    PriorityClass.Foreground = FALSE;
-
-    /* Set the new Priority */
-    NtSetInformationProcess(CsrProcess->ProcessHandle,
-                            ProcessPriorityClass,
-                            &PriorityClass,
-                            sizeof(PriorityClass));
-}
-
-/*++
- * @name CsrSetForegroundPriority
- * @implemented NT4
- *
- * The CsrSetForegroundPriority routine sets the priority for the given CSR
- * Process as a Foreground priority.
- *
- * @param CsrProcess
- *        Pointer to the CSR Process whose priority will be modified.
- *
- * @return None.
- *
- * @remarks None.
- *
- *--*/
-VOID
-NTAPI
-CsrSetForegroundPriority(IN PCSR_PROCESS CsrProcess)
-{
-    PROCESS_PRIORITY_CLASS PriorityClass;
-
-    /* Set the Foreground bit on */
-    PriorityClass.Foreground = TRUE;
-
-    /* Set the new Priority */
-    NtSetInformationProcess(CsrProcess->ProcessHandle,
-                            ProcessPriorityClass,
-                            &PriorityClass,
-                            sizeof(PriorityClass));
-}
-
-/*++
- * @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(IN PLUID CallerLuid)
-{
-    PCSR_PROCESS CsrProcess, ReturnCsrProcess = NULL;
-    PCSR_THREAD CsrThread;
-    NTSTATUS Status;
-    ULONG Level = 0;
-    LUID ProcessLuid;
-    LUID SystemLuid = SYSTEM_LUID;
-    PLIST_ENTRY NextEntry;
-
-    /* Set the List Pointers */
-    NextEntry = CsrRootProcess->ListLink.Flink;
-    while (NextEntry != &CsrRootProcess->ListLink)
-    {
-        /* 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);
-                if (CsrImpersonateClient(CsrThread))
-                {
-                    Status = CsrGetProcessLuid(NULL, &ProcessLuid);
-                    CsrRevertToSelf();
-                }
-                else
-                {
-                    Status = STATUS_BAD_IMPERSONATION_LEVEL;
-                }
-            }
-        }
-
-        if (!NT_SUCCESS(Status))
-        {
-            /* We didn't have access, so skip it */
-            CsrProcess->Flags |= CsrProcessSkipShutdown;
-            continue;
-        }
-
-        /* Check if this is the System LUID */
-        if (RtlEqualLuid(&ProcessLuid, &SystemLuid))
-        {
-            /* Mark this process */
-            CsrProcess->ShutdownFlags |= CsrShutdownSystem;
-        }
-        else if (!RtlEqualLuid(&ProcessLuid, CallerLuid))
-        {
-            /* Our LUID doesn't match with the caller's */
-            CsrProcess->ShutdownFlags |= CsrShutdownOther;
-        }
-
-        /* Check if we're past the previous level */
-        if ((CsrProcess->ShutdownLevel > Level) || !ReturnCsrProcess)
-        {
-            /* Update the level */
-            Level = CsrProcess->ShutdownLevel;
-
-            /* Set the final process */
-            ReturnCsrProcess = CsrProcess;
-        }
-    }
-
-    /* Check if we found a process */
-    if (ReturnCsrProcess)
-    {
-        /* Skip this one next time */
-        ReturnCsrProcess->Flags |= CsrProcessSkipShutdown;
-    }
-
-    return ReturnCsrProcess;
-}
-
-/*++
- * @name CsrShutdownProcesses
- * @implemented NT4
- *
- * The CsrShutdownProcesses routine shuts down every CSR Process possible
- * and calls each Server DLL's shutdown notification.
- *
- * @param CallerLuid
- *        Pointer to the LUID of the CSR Process that is ordering the
- *        shutdown.
- *
- * @param Flags
- *        Flags to send to the shutdown notification routine.
- *
- * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL otherwise.
- *
- * @remarks None.
- *
- *--*/
-NTSTATUS
-NTAPI
-CsrShutdownProcesses(IN PLUID CallerLuid,
-                     IN ULONG Flags)
-{
-    PLIST_ENTRY NextEntry;
-    PCSR_PROCESS CsrProcess;
-    NTSTATUS Status;
-    BOOLEAN FirstTry;
-    ULONG i;
-    PCSR_SERVER_DLL ServerDll;
-    ULONG Result = 0;
-
-    /* Acquire process lock */
-    CsrAcquireProcessLock();
-
-    /* Add shutdown flag */
-    CsrRootProcess->ShutdownFlags |= CsrShutdownSystem;
-
-    /* Get the list pointers */
-    NextEntry = CsrRootProcess->ListLink.Flink;
-    while (NextEntry != &CsrRootProcess->ListLink)
-    {
-        /* Get the Process */
-        CsrProcess = CONTAINING_RECORD(NextEntry, CSR_PROCESS, ListLink);
-
-        /* Move to the next entry */
-        NextEntry = NextEntry->Flink;
-
-        /* Remove the skip flag, set shutdown flags to 0 */
-        CsrProcess->Flags &= ~CsrProcessSkipShutdown;
-        CsrProcess->ShutdownFlags = 0;
-    }
-
-    /* Set shutdown Priority */
-    CsrSetToShutdownPriority();
-
-    /* Start looping */
-    while (TRUE)
-    {
-        /* Find the next process to shutdown */
-        CsrProcess = FindProcessForShutdown(CallerLuid);
-        if (!CsrProcess) break;
-
-        /* Increase reference to process */
-        CsrLockedReferenceProcess(CsrProcess);
-
-        FirstTry = TRUE;
-        while (TRUE)
-        {
-            /* Loop all the servers */
-            for (i = 0; i < CSR_SERVER_DLL_MAX; i++)
-            {
-                /* Get the current server */
-                ServerDll = CsrLoadedServerDll[i];
-
-                /* Check if it's valid and if it has a Shutdown Process Callback */
-                if (ServerDll && ServerDll->ShutdownProcessCallback)
-                {
-                    /* Release the lock, make the callback, and acquire it back */
-                    CsrReleaseProcessLock();
-                    Result = ServerDll->ShutdownProcessCallback(CsrProcess,
-                                                                Flags,
-                                                                FirstTry);
-                    CsrAcquireProcessLock();
-
-                    /* Check the result */
-                    if (Result == CsrShutdownCsrProcess)
-                    {
-                        /* The callback unlocked the process */
-                        break;
-                    }
-                    else if (Result == CsrShutdownCancelled)
-                    {
-                        /* Check if this was a forced shutdown */
-                        if (Flags & EWX_FORCE)
-                        {
-                            DPRINT1("Process %x cancelled forced shutdown (Dll = %d)\n",
-                                     CsrProcess->ClientId.UniqueProcess, i);
-                            DbgBreakPoint();
-                        }
-
-                        /* Shutdown was cancelled, unlock and exit */
-                        CsrReleaseProcessLock();
-                        Status = STATUS_CANCELLED;
-                        goto Quickie;
-                    }
-                }
-            }
-
-            /* No matches during the first try, so loop again */
-            if (FirstTry && (Result == CsrShutdownNonCsrProcess))
-            {
-                FirstTry = FALSE;
-                continue;
-            }
-
-            /* Second try, break out */
-            break;
-        }
-
-        /* We've reached the final loop here, so dereference */
-        if (i == CSR_SERVER_DLL_MAX) CsrLockedDereferenceProcess(CsrProcess);
-    }
-
-    /* Success path */
-    CsrReleaseProcessLock();
-    Status = STATUS_SUCCESS;
-
-Quickie:
-    /* Return to normal priority */
-    CsrSetToNormalPriority();
-
-    return Status;
-}
-
-/*++
- * @name CsrUnlockProcess
- * @implemented NT4
- *
- * The CsrUnlockProcess undoes a previous CsrLockProcessByClientId operation.
- *
- * @param CsrProcess
- *        Pointer to a previously locked CSR Process.
- *
- * @return STATUS_SUCCESS.
- *
- * @remarks This routine must be called with the Process Lock held.
- *
- *--*/
-NTSTATUS
-NTAPI
-CsrUnlockProcess(IN PCSR_PROCESS CsrProcess)
-{
-    /* Dereference the process */
-    CsrLockedDereferenceProcess(CsrProcess);
-
-    /* Release the lock and return */
-    CsrReleaseProcessLock();
-    return STATUS_SUCCESS;
-}
-
-/* EOF */