[CSRSRV] Only when CSRSRV is compiled in debugging mode, should we display debugging...
[reactos.git] / subsystems / win32 / csrsrv / procsup.c
index c79fdee..30cde8a 100644 (file)
@@ -11,6 +11,8 @@
 
 #include <srv.h>
 
+#include <winuser.h>
+
 #define NDEBUG
 #include <debug.h>
 
@@ -41,7 +43,7 @@ extern ULONG CsrTotalPerProcessDataLength;
  *
  * @return None.
  *
- * @remarks The "Normal" Priority corresponds to the Normal Forground
+ * @remarks The "Normal" Priority corresponds to the Normal Foreground
  *          Priority (9) plus a boost of 4.
  *
  *--*/
@@ -55,7 +57,7 @@ CsrSetToNormalPriority(VOID)
     NtSetInformationProcess(NtCurrentProcess(),
                             ProcessBasePriority,
                             &BasePriority,
-                            sizeof(KPRIORITY));
+                            sizeof(BasePriority));
 }
 
 /*++
@@ -69,7 +71,7 @@ CsrSetToNormalPriority(VOID)
  *
  * @return None.
  *
- * @remarks The "Shutdown" Priority corresponds to the Normal Forground
+ * @remarks The "Shutdown" Priority corresponds to the Normal Foreground
  *          Priority (9) plus a boost of 6.
  *
  *--*/
@@ -77,7 +79,7 @@ VOID
 NTAPI
 CsrSetToShutdownPriority(VOID)
 {
-    KPRIORITY SetBasePriority = (8 + 1) + 6;
+    KPRIORITY BasePriority = (8 + 1) + 6;
     BOOLEAN Old;
 
     /* Get the shutdown privilege */
@@ -89,114 +91,11 @@ CsrSetToShutdownPriority(VOID)
         /* Set the Priority */
         NtSetInformationProcess(NtCurrentProcess(),
                                 ProcessBasePriority,
-                                &SetBasePriority,
-                                sizeof(KPRIORITY));
+                                &BasePriority,
+                                sizeof(BasePriority));
     }
 }
 
-/*++
- * @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;
-    // BOOLEAN IsSystemLuid = FALSE, IsOurLuid = FALSE;
-    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)
-        {
-            /* FIXME: Check if we have any threads */
-/*
-            /\* 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);
-                CsrImpersonateClient(CsrThread);
-                Status = CsrGetProcessLuid(NULL, &ProcessLuid);
-                CsrRevertToSelf();
-            }
-*/
-        }
-
-        if (!NT_SUCCESS(Status))
-        {
-            /* We didn't have access, so skip it */
-            CsrProcess->Flags |= CsrProcessSkipShutdown;
-            continue;
-        }
-
-        /* Check if this is the System LUID */
-        if ((/*IsSystemLuid =*/ RtlEqualLuid(&ProcessLuid, &SystemLuid)))
-        {
-            /* Mark this process */
-            CsrProcess->ShutdownFlags |= CsrShutdownSystem;
-        }
-        else if (!(/*IsOurLuid =*/ RtlEqualLuid(&ProcessLuid, CallerLuid)))
-        {
-            /* Our LUID doesn't match with the caller's */
-            CsrProcess->ShutdownFlags |= CsrShutdownOther;
-        }
-
-        /* Check if we're past the previous level */
-        // FIXME: if ((CsrProcess->ShutdownLevel > Level) || !(ReturnCsrProcess))
-        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 CsrProcessRefcountZero
  *
@@ -264,12 +163,12 @@ CsrLockedDereferenceProcess(PCSR_PROCESS CsrProcess)
     /* Decrease reference count */
     LockCount = --CsrProcess->ReferenceCount;
     ASSERT(LockCount >= 0);
-    if (!LockCount)
+    if (LockCount == 0)
     {
         /* Call the generic cleanup code */
         DPRINT1("Should kill process: %p\n", CsrProcess);
-        CsrProcessRefcountZero(CsrProcess);
         CsrAcquireProcessLock();
+        CsrProcessRefcountZero(CsrProcess);
     }
 }
 
@@ -305,7 +204,7 @@ CsrAllocateProcess(VOID)
     if (CsrProcessSequenceCount < 5) CsrProcessSequenceCount = 5;
 
     /* Increase the reference count */
-    CsrProcess->ReferenceCount++;
+    CsrLockedReferenceProcess(CsrProcess);
 
     /* Initialize the Thread List */
     InitializeListHead(&CsrProcess->ThreadList);
@@ -345,8 +244,7 @@ CsrLockedReferenceProcess(IN PCSR_PROCESS CsrProcess)
  *
  * @param None.
  *
- * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
- *         otherwise.
+ * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL otherwise.
  *
  * @remarks None.
  *
@@ -372,7 +270,7 @@ CsrInitializeProcessStructure(VOID)
     CsrRootProcess->ClientId = NtCurrentTeb()->ClientId;
 
     /* Initialize the Thread Hash List */
-    for (i = 0; i < 256; i++) InitializeListHead(&CsrThreadHashTable[i]);
+    for (i = 0; i < NUMBER_THREAD_HASH_BUCKETS; i++) InitializeListHead(&CsrThreadHashTable[i]);
 
     /* Initialize the Wait Lock */
     return RtlInitializeCriticalSection(&CsrWaitListsLock);
@@ -451,11 +349,8 @@ CsrRemoveProcess(IN PCSR_PROCESS CsrProcess)
  * 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 ParentProcess
+ *        Optional pointer to the Parent Process creating this CSR Process.
  *
  * @param CsrProcess
  *        Pointer to the CSR Process which is to be inserted.
@@ -467,17 +362,13 @@ CsrRemoveProcess(IN PCSR_PROCESS CsrProcess)
  *--*/
 VOID
 NTAPI
-CsrInsertProcess(IN PCSR_PROCESS Parent OPTIONAL,   // ParentProcess
-                 IN PCSR_PROCESS CurrentProcess OPTIONAL,   // CallingProcess
-                 IN PCSR_PROCESS CsrProcess)    // Process
+CsrInsertProcess(IN PCSR_PROCESS ParentProcess OPTIONAL,
+                 IN PCSR_PROCESS CsrProcess)
 {
     PCSR_SERVER_DLL ServerDll;
     ULONG i;
     ASSERT(ProcessStructureListLocked());
 
-    /* Set the parent */
-    CsrProcess->Parent = Parent;
-
     /* Insert it into the Root List */
     InsertTailList(&CsrRootProcess->ListLink, &CsrProcess->ListLink);
 
@@ -490,7 +381,7 @@ CsrInsertProcess(IN PCSR_PROCESS Parent OPTIONAL,   // ParentProcess
         /* Make sure it's valid and that it has callback */
         if (ServerDll && ServerDll->NewProcessCallback)
         {
-            ServerDll->NewProcessCallback(CurrentProcess, CsrProcess);
+            ServerDll->NewProcessCallback(ParentProcess, CsrProcess);
         }
     }
 }
@@ -502,18 +393,25 @@ CsrInsertProcess(IN PCSR_PROCESS Parent OPTIONAL,   // ParentProcess
  * @name CsrCreateProcess
  * @implemented NT4
  *
- * Do nothing for 500ms.
+ * 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 ArgumentCount
- *        Description of the parameter. Wrapped to more lines on ~70th
- *        column.
+ * @param ClientId
+ *        Pointer to the Client ID structure of the NT Process to associate
+ *        with this CSR Process.
  *
- * @param Arguments
- *        Description of the parameter. Wrapped to more lines on ~70th
- *        column.
+ * @param NtSession
+ * @param Flags
+ * @param DebugCid
  *
- * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
- *         otherwise.
+ * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL otherwise.
  *
  * @remarks None.
  *
@@ -590,11 +488,11 @@ CsrCreateProcess(IN HANDLE hProcess,
         }
     }
 
-    /* Set the Exception port for us */
+    /* Set the Exception Port for us */
     Status = NtSetInformationProcess(hProcess,
                                      ProcessExceptionPort,
                                      &CsrApiPort,
-                                     sizeof(HANDLE));
+                                     sizeof(CsrApiPort));
     if (!NT_SUCCESS(Status))
     {
         /* Failed */
@@ -604,15 +502,18 @@ CsrCreateProcess(IN HANDLE hProcess,
     }
 
     /* Check if CreateProcess got CREATE_NEW_PROCESS_GROUP */
-    if (!(Flags & CsrProcessCreateNewGroup))
+    if (Flags & CsrProcessCreateNewGroup)
     {
-        /* Create new data */
+        /*
+         * 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
     {
-        /* Copy it from the current process */
+        /* Inherit the process group ID and sequence number from the current process */
         CsrProcess->ProcessGroupId = CurrentProcess->ProcessGroupId;
         CsrProcess->ProcessGroupSequence = CurrentProcess->ProcessGroupSequence;
     }
@@ -648,7 +549,7 @@ CsrCreateProcess(IN HANDLE hProcess,
         Status = NtSetInformationProcess(hProcess,
                                          ProcessDebugPort,
                                          &CsrApiPort,
-                                         sizeof(HANDLE));
+                                         sizeof(CsrApiPort));
         ASSERT(NT_SUCCESS(Status));
         if (!NT_SUCCESS(Status))
         {
@@ -662,7 +563,7 @@ CsrCreateProcess(IN HANDLE hProcess,
     /* Get the Thread Create Time */
     Status = NtQueryInformationThread(hThread,
                                       ThreadTimes,
-                                      (PVOID)&KernelTimes,
+                                      &KernelTimes,
                                       sizeof(KernelTimes),
                                       NULL);
     if (!NT_SUCCESS(Status))
@@ -691,7 +592,15 @@ CsrCreateProcess(IN HANDLE hProcess,
     CsrThread->Flags = 0;
 
     /* Insert the Thread into the Process */
-    CsrInsertThread(CsrProcess, CsrThread);
+    Status = CsrInsertThread(CsrProcess, CsrThread);
+    if (!NT_SUCCESS(Status))
+    {
+        /* Bail out */
+        CsrDeallocateProcess(CsrProcess);
+        CsrDeallocateThread(CsrThread);
+        CsrReleaseProcessLock();
+        return Status;
+    }
 
     /* Reference the session */
     CsrReferenceNtSession(NtSession);
@@ -706,7 +615,7 @@ CsrCreateProcess(IN HANDLE hProcess,
     CsrSetBackgroundPriority(CsrProcess);
 
     /* Insert the Process */
-    CsrInsertProcess(NULL, CurrentProcess, CsrProcess);
+    CsrInsertProcess(CurrentProcess, CsrProcess);
 
     /* Release lock and return */
     CsrReleaseProcessLock();
@@ -733,7 +642,7 @@ NTAPI
 CsrDebugProcess(IN PCSR_PROCESS CsrProcess)
 {
     /* CSR does not handle debugging anymore */
-    DPRINT("CSRSRV: %s(%08lx) called\n", __FUNCTION__, CsrProcess);
+    DPRINT("CSRSRV: %s(0x%p) called\n", __FUNCTION__, CsrProcess);
     return STATUS_UNSUCCESSFUL;
 }
 
@@ -757,7 +666,7 @@ NTAPI
 CsrDebugProcessStop(IN PCSR_PROCESS CsrProcess)
 {
     /* CSR does not handle debugging anymore */
-    DPRINT("CSRSRV: %s(%08lx) called\n", __FUNCTION__, CsrProcess);
+    DPRINT("CSRSRV: %s(0x%p) called\n", __FUNCTION__, CsrProcess);
     return STATUS_UNSUCCESSFUL;
 }
 
@@ -788,7 +697,7 @@ CsrDereferenceProcess(IN PCSR_PROCESS CsrProcess)
     /* Decrease reference count */
     LockCount = --CsrProcess->ReferenceCount;
     ASSERT(LockCount >= 0);
-    if (!LockCount)
+    if (LockCount == 0)
     {
         /* Call the generic cleanup code */
         CsrProcessRefcountZero(CsrProcess);
@@ -898,16 +807,15 @@ CsrDestroyProcess(IN PCLIENT_ID Cid,
  * @name CsrGetProcessLuid
  * @implemented NT4
  *
- * Do nothing for 500ms.
+ * 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
+ *        Pointer to a LUID Pointer which will receive the CSR Process' LUID.
  *
- * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
- *         otherwise.
+ * @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
@@ -1007,7 +915,7 @@ CsrGetProcessLuid(IN HANDLE hProcess OPTIONAL,
  * @param CsrThread
  *        Pointer to the CSR Thread to impersonate.
  *
- * @return TRUE if impersionation suceeded, false otherwise.
+ * @return TRUE if impersonation succeeded, FALSE otherwise.
  *
  * @remarks Impersonation can be recursive.
  *
@@ -1037,10 +945,10 @@ CsrImpersonateClient(IN PCSR_THREAD CsrThread)
     if (!NT_SUCCESS(Status))
     {
         /* Failure */
-/*
+#ifdef CSR_DBG
         DPRINT1("CSRSS: Can't impersonate client thread - Status = %lx\n", Status);
-        if (Status != STATUS_BAD_IMPERSONATION_LEVEL) DbgBreakPoint();
-*/
+        // if (Status != STATUS_BAD_IMPERSONATION_LEVEL) DbgBreakPoint();
+#endif
         return FALSE;
     }
 
@@ -1065,8 +973,7 @@ CsrImpersonateClient(IN PCSR_THREAD CsrThread)
  *        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.
+ * @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.
@@ -1079,7 +986,7 @@ CsrLockProcessByClientId(IN HANDLE Pid,
 {
     PLIST_ENTRY NextEntry;
     PCSR_PROCESS CurrentProcess = NULL;
-    NTSTATUS Status;
+    NTSTATUS Status = STATUS_UNSUCCESSFUL;
 
     /* Acquire the lock */
     CsrAcquireProcessLock();
@@ -1118,7 +1025,7 @@ CsrLockProcessByClientId(IN HANDLE Pid,
         CsrLockedReferenceProcess(CurrentProcess);
         *CsrProcess = CurrentProcess;
     }
-    
+
     /* Return the result */
     return Status;
 }
@@ -1131,7 +1038,7 @@ CsrLockProcessByClientId(IN HANDLE Pid,
  *
  * @param None.
  *
- * @return TRUE if the reversion was succesful, false otherwise.
+ * @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
@@ -1152,11 +1059,11 @@ CsrRevertToSelf(VOID)
         /* Make sure impersonation is on */
         if (!CurrentThread->ImpersonationCount)
         {
-            // DPRINT1("CSRSS: CsrRevertToSelf called while not impersonating\n");
+            DPRINT1("CSRSS: CsrRevertToSelf called while not impersonating\n");
             // DbgBreakPoint();
             return FALSE;
         }
-        else if (--CurrentThread->ImpersonationCount > 0)
+        else if ((--CurrentThread->ImpersonationCount) > 0)
         {
             /* Success; impersonation count decreased but still not zero */
             return TRUE;
@@ -1167,7 +1074,7 @@ CsrRevertToSelf(VOID)
     Status = NtSetInformationThread(NtCurrentThread(),
                                     ThreadImpersonationToken,
                                     &ImpersonationToken,
-                                    sizeof(HANDLE));
+                                    sizeof(ImpersonationToken));
 
     /* Return TRUE or FALSE */
     return NT_SUCCESS(Status);
@@ -1192,16 +1099,16 @@ VOID
 NTAPI
 CsrSetBackgroundPriority(IN PCSR_PROCESS CsrProcess)
 {
-    PROCESS_PRIORITY_CLASS PriorityClass;
+    PROCESS_FOREGROUND_BACKGROUND ProcessPriority;
 
     /* Set the Foreground bit off */
-    PriorityClass.Foreground = FALSE;
+    ProcessPriority.Foreground = FALSE;
 
-    /* Set the new Priority */
+    /* Set the new priority */
     NtSetInformationProcess(CsrProcess->ProcessHandle,
-                            ProcessPriorityClass,
-                            &PriorityClass,
-                            sizeof(PriorityClass));
+                            ProcessForegroundInformation,
+                            &ProcessPriority,
+                            sizeof(ProcessPriority));
 }
 
 /*++
@@ -1223,16 +1130,120 @@ VOID
 NTAPI
 CsrSetForegroundPriority(IN PCSR_PROCESS CsrProcess)
 {
-    PROCESS_PRIORITY_CLASS PriorityClass;
+    PROCESS_FOREGROUND_BACKGROUND ProcessPriority;
 
     /* Set the Foreground bit on */
-    PriorityClass.Foreground = TRUE;
+    ProcessPriority.Foreground = TRUE;
 
-    /* Set the new Priority */
+    /* Set the new priority */
     NtSetInformationProcess(CsrProcess->ProcessHandle,
-                            ProcessPriorityClass,
-                            &PriorityClass,
-                            sizeof(PriorityClass));
+                            ProcessForegroundInformation,
+                            &ProcessPriority,
+                            sizeof(ProcessPriority));
+}
+
+/*++
+ * @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;
 }
 
 /*++
@@ -1249,8 +1260,7 @@ CsrSetForegroundPriority(IN PCSR_PROCESS CsrProcess)
  * @param Flags
  *        Flags to send to the shutdown notification routine.
  *
- * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
- *         otherwise.
+ * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL otherwise.
  *
  * @remarks None.
  *
@@ -1266,7 +1276,7 @@ CsrShutdownProcesses(IN PLUID CallerLuid,
     BOOLEAN FirstTry;
     ULONG i;
     PCSR_SERVER_DLL ServerDll;
-    ULONG Result = 0; /* Intentionally invalid enumeratee to silence compiler warning */
+    ULONG Result = 0;
 
     /* Acquire process lock */
     CsrAcquireProcessLock();
@@ -1289,7 +1299,7 @@ CsrShutdownProcesses(IN PLUID CallerLuid,
         CsrProcess->ShutdownFlags = 0;
     }
 
-    /* Set shudown Priority */
+    /* Set shutdown Priority */
     CsrSetToShutdownPriority();
 
     /* Start looping */
@@ -1300,7 +1310,7 @@ CsrShutdownProcesses(IN PLUID CallerLuid,
         if (!CsrProcess) break;
 
         /* Increase reference to process */
-        CsrProcess->ReferenceCount++;
+        CsrLockedReferenceProcess(CsrProcess);
 
         FirstTry = TRUE;
         while (TRUE)
@@ -1329,6 +1339,7 @@ CsrShutdownProcesses(IN PLUID CallerLuid,
                     }
                     else if (Result == CsrShutdownCancelled)
                     {
+#ifdef CSR_DBG
                         /* Check if this was a forced shutdown */
                         if (Flags & EWX_FORCE)
                         {
@@ -1336,6 +1347,7 @@ CsrShutdownProcesses(IN PLUID CallerLuid,
                                      CsrProcess->ClientId.UniqueProcess, i);
                             DbgBreakPoint();
                         }
+#endif
 
                         /* Shutdown was cancelled, unlock and exit */
                         CsrReleaseProcessLock();
@@ -1346,7 +1358,7 @@ CsrShutdownProcesses(IN PLUID CallerLuid,
             }
 
             /* No matches during the first try, so loop again */
-            if ((FirstTry) && (Result == CsrShutdownNonCsrProcess))
+            if (FirstTry && (Result == CsrShutdownNonCsrProcess))
             {
                 FirstTry = FALSE;
                 continue;
@@ -1357,7 +1369,8 @@ CsrShutdownProcesses(IN PLUID CallerLuid,
         }
 
         /* We've reached the final loop here, so dereference */
-        if (i == CSR_SERVER_DLL_MAX) CsrLockedDereferenceProcess(CsrProcess);
+        if (i == CSR_SERVER_DLL_MAX)
+            CsrLockedDereferenceProcess(CsrProcess);
     }
 
     /* Success path */
@@ -1371,100 +1384,6 @@ Quickie:
     return Status;
 }
 
-/* FIXME: Temporary hack. This is really "CsrShutdownProcess", mostly. Used by winsrv */
-#if 0
-NTSTATUS
-WINAPI
-CsrEnumProcesses(IN CSRSS_ENUM_PROCESS_PROC EnumProc,
-                 IN PVOID Context)
-{
-    PVOID* RealContext = (PVOID*)Context;
-    PLUID CallerLuid = RealContext[0];
-    PCSR_PROCESS CsrProcess = NULL;
-    NTSTATUS Status = STATUS_UNSUCCESSFUL;
-    BOOLEAN FirstTry;
-    PLIST_ENTRY NextEntry;
-    ULONG Result = 0;
-
-    /* Acquire process lock */
-    CsrAcquireProcessLock();
-    
-    /* 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 shudown Priority */
-    CsrSetToShutdownPriority();
-
-    /* Loop all processes */
-    //DPRINT1("Enumerating for LUID: %lx %lx\n", CallerLuid->HighPart, CallerLuid->LowPart);
-    
-    /* Start looping */
-    while (TRUE)
-    {
-        /* Find the next process to shutdown */
-        FirstTry = TRUE;
-        if (!(CsrProcess = FindProcessForShutdown(CallerLuid)))
-        {
-            /* Done, quit */
-            CsrReleaseProcessLock();
-            Status = STATUS_SUCCESS;
-            goto Quickie;
-        }
-
-LoopAgain:
-        /* Release the lock, make the callback, and acquire it back */
-        //DPRINT1("Found process: %lx\n", CsrProcess->ClientId.UniqueProcess);
-        CsrReleaseProcessLock();
-        Result = (ULONG)EnumProc(CsrProcess, (PVOID)((ULONG_PTR)Context | FirstTry));
-        CsrAcquireProcessLock();
-
-        /* Check the result */
-        //DPRINT1("Result: %d\n", Result);
-        if (Result == CsrShutdownCsrProcess)
-        {
-            /* The callback unlocked the process */
-            break;
-        }
-        else if (Result == CsrShutdownNonCsrProcess)
-        {
-            /* A non-CSR process, the callback didn't touch it */
-            //continue;
-        }
-        else if (Result == CsrShutdownCancelled)
-        {
-            /* 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;
-            goto LoopAgain;
-        }
-    }
-
-Quickie:
-    /* Return to normal priority */
-    CsrSetToNormalPriority();
-    return Status;
-}
-#endif
-
 /*++
  * @name CsrUnlockProcess
  * @implemented NT4