release the keep-alive reference of the process object
[reactos.git] / reactos / ntoskrnl / ps / kill.c
index a4f2e7b..6e4b8a7 100644 (file)
@@ -214,7 +214,7 @@ PspExitThread(NTSTATUS ExitStatus)
     PTERMINATION_PORT TerminationPort;
     PTEB Teb;
     KIRQL oldIrql;
-    PLIST_ENTRY ApcEntry;
+    PLIST_ENTRY FirstEntry, CurrentEntry;
     PKAPC Apc;
 
     DPRINT("PspExitThread(ExitStatus %x), Current: 0x%x\n", ExitStatus, PsGetCurrentThread());
@@ -261,6 +261,7 @@ PspExitThread(NTSTATUS ExitStatus)
           happens when the last thread just terminates without explicitly
           terminating the process. */
        CurrentProcess->ExitTime = CurrentThread->ExitTime;
+       CurrentProcess->ExitStatus = ExitStatus;
     }
 
     /* Check if the process has a debug port */
@@ -280,6 +281,7 @@ PspExitThread(NTSTATUS ExitStatus)
 
         /* Send the LPC Message */
         LpcSendTerminationPort(TerminationPort->Port, CurrentThread->CreateTime);
+        ObDereferenceObject(TerminationPort->Port);
 
         /* Free the Port */
         ExFreePool(TerminationPort);
@@ -339,37 +341,42 @@ PspExitThread(NTSTATUS ExitStatus)
     KeDisableThreadApcQueueing(&CurrentThread->Tcb);
 
     /* Flush the User APCs */
-    ApcEntry = KeFlushQueueApc(&CurrentThread->Tcb, UserMode);
-    while(ApcEntry)
+    FirstEntry = KeFlushQueueApc(&CurrentThread->Tcb, UserMode);
+    if (FirstEntry != NULL)
     {
-       /* Get the APC */
-       Apc = CONTAINING_RECORD(ApcEntry, KAPC, ApcListEntry);
-
-       /* Move to the next one */
-       ApcEntry = ApcEntry->Flink;
-
-       /* Rundown the APC or de-allocate it */
-       if (Apc->RundownRoutine)
-       {
-          /* Call its own routine */
-          (Apc->RundownRoutine)(Apc);
-       }
-       else
-       {
-          /* Do it ourselves */
-          ExFreePool(Apc);
-       }
+        CurrentEntry = FirstEntry;
+        do
+        {
+           /* Get the APC */
+           Apc = CONTAINING_RECORD(CurrentEntry, KAPC, ApcListEntry);
+
+           /* Move to the next one */
+           CurrentEntry = CurrentEntry->Flink;
+
+           /* Rundown the APC or de-allocate it */
+           if (Apc->RundownRoutine)
+           {
+              /* Call its own routine */
+              (Apc->RundownRoutine)(Apc);
+           }
+           else
+           {
+              /* Do it ourselves */
+              ExFreePool(Apc);
+           }
+        }
+        while (CurrentEntry != FirstEntry);
     }
 
     /* Call the Lego routine */
     if (CurrentThread->Tcb.LegoData) PspRunLegoRoutine(&CurrentThread->Tcb);
 
     /* Flush the APC queue, which should be empty */
-    if ((ApcEntry = KeFlushQueueApc(&CurrentThread->Tcb, KernelMode)))
+    if ((FirstEntry = KeFlushQueueApc(&CurrentThread->Tcb, KernelMode)))
     {
         /* Bugcheck time */
         KEBUGCHECKEX(KERNEL_APC_PENDING_DURING_EXIT,
-                     (ULONG_PTR)ApcEntry,
+                     (ULONG_PTR)FirstEntry,
                      CurrentThread->Tcb.KernelApcDisable,
                      oldIrql,
                      0);
@@ -389,8 +396,8 @@ PsExitSpecialApc(PKAPC Apc,
                  PVOID* SystemArgument1,
                  PVOID* SystemArguemnt2)
 {
-    DPRINT1("PsExitSpecialApc called: 0x%x (proc: 0x%x, '%.16s')\n", 
-            PsGetCurrentThread(), PsGetCurrentProcess(), PsGetCurrentProcess()->ImageFileName);
+    DPRINT("PsExitSpecialApc called: 0x%x (proc: 0x%x, '%.16s')\n", 
+           PsGetCurrentThread(), PsGetCurrentProcess(), PsGetCurrentProcess()->ImageFileName);
 
     /* Don't do anything unless we are in User-Mode */
     if (Apc->SystemArgument2)
@@ -418,8 +425,8 @@ PspExitNormalApc(PVOID NormalContext,
     PETHREAD Thread = PsGetCurrentThread();
     NTSTATUS ExitStatus;
         
-    DPRINT1("PspExitNormalApc called: 0x%x (proc: 0x%x, '%.16s')\n", 
-            PsGetCurrentThread(), PsGetCurrentProcess(), PsGetCurrentProcess()->ImageFileName);
+    DPRINT("PspExitNormalApc called: 0x%x (proc: 0x%x, '%.16s')\n", 
+           PsGetCurrentThread(), PsGetCurrentProcess(), PsGetCurrentProcess()->ImageFileName);
 
     /* This should never happen */
     ASSERT(!SystemArgument2);
@@ -439,7 +446,7 @@ PspExitNormalApc(PVOID NormalContext,
     }
 
     /* If we're here, this is not a System Thread, so kill it from User-Mode */
-    DPRINT1("Initializing User-Mode APC\n");
+    DPRINT("Initializing User-Mode APC\n");
     KeInitializeApc(Apc,
                     &Thread->Tcb,
                     OriginalApcEnvironment,
@@ -517,6 +524,9 @@ PspExitProcess(PEPROCESS Process)
     ObKillProcess(Process);
 
     KeSetProcess(&Process->Pcb, IO_NO_INCREMENT);
+    
+    /* release the keep-alive reference of the process object */
+    ObDereferenceObject(Process);
 
     return(STATUS_SUCCESS);
 }
@@ -573,6 +583,7 @@ NtTerminateProcess(IN HANDLE ProcessHandle  OPTIONAL,
            we kill ourselves to prevent threads outside of our process trying
            to kill us */
         KeQuerySystemTime(&Process->ExitTime);
+        Process->ExitStatus = ExitStatus;
 
         /* Only master thread remains... kill it off */
         if (CurrentThread->ThreadsProcess == Process) {