ReactOS  0.4.15-dev-5142-g967f5b9
kill.c
Go to the documentation of this file.
1 /*
2  * PROJECT: ReactOS Kernel
3  * LICENSE: GPL - See COPYING in the top level directory
4  * FILE: ntoskrnl/ps/kill.c
5  * PURPOSE: Process Manager: Process and Thread Termination
6  * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
7  * Filip Navara (xnavara@reactos.org)
8  * Thomas Weidenmueller (w3seek@reactos.org
9  */
10 
11 /* INCLUDES *****************************************************************/
12 
13 #include <ntoskrnl.h>
14 #define NDEBUG
15 #include <debug.h>
16 
17 /* GLOBALS *******************************************************************/
18 
21 LARGE_INTEGER ShortTime = {{-10 * 100 * 1000, -1}};
22 
23 /* PRIVATE FUNCTIONS *********************************************************/
24 
25 VOID
26 NTAPI
28  IN PVOID ProcessOrThread,
30 {
31  CHAR Action[2];
33  PAGED_CODE();
34 
35  /* Check if a debugger is enabled */
37  {
38  /* Print out the message */
39  DbgPrint(Message, ProcessOrThread, ImageName);
40  do
41  {
42  /* If a debugger isn't present, don't prompt */
43  if (KdDebuggerNotPresent) break;
44 
45  /* A debuger is active, prompt for action */
46  DbgPrompt("Break, or Ignore (bi)?", Action, sizeof(Action));
47  switch (Action[0])
48  {
49  /* Break */
50  case 'B': case 'b':
51 
52  /* Do a breakpoint */
53  DbgBreakPoint();
54 
55  /* Ignore */
56  case 'I': case 'i':
57 
58  /* Handle it */
59  Handled = TRUE;
60 
61  /* Unrecognized */
62  default:
63  break;
64  }
65  } while (!Handled);
66  }
67 
68  /* Did we ultimately handle this? */
69  if (!Handled)
70  {
71  /* We didn't, bugcheck */
72  KeBugCheckEx(CRITICAL_OBJECT_TERMINATION,
73  ((PKPROCESS)ProcessOrThread)->Header.Type,
74  (ULONG_PTR)ProcessOrThread,
77  }
78 }
79 
81 NTAPI
84 {
87  PAGED_CODE();
89  "Process: %p ExitStatus: %d\n", Process, ExitStatus);
91 
92  /* Check if this is a Critical Process */
93  if (Process->BreakOnTermination)
94  {
95  /* Break to debugger */
96  PspCatchCriticalBreak("Terminating critical process 0x%p (%s)\n",
97  Process,
98  Process->ImageFileName);
99  }
100 
101  /* Set the delete flag */
103 
104  /* Get the first thread */
106  while (Thread)
107  {
108  /* Kill it */
111 
112  /* We had at least one thread, so termination is OK */
114  }
115 
116  /* Check if there was nothing to terminate or if we have a debug port */
117  if ((Status == STATUS_NOTHING_TO_TERMINATE) || (Process->DebugPort))
118  {
119  /* Clear the handle table anyway */
121  }
122 
123  /* Return status */
124  return Status;
125 }
126 
127 NTSTATUS
128 NTAPI
131 {
132  /* Call the internal API */
134 }
135 
136 VOID
137 NTAPI
139 {
141 
142  /* Loop every process */
144  while (Process)
145  {
146  /* Make sure this isn't the idle or initial process */
148  {
149  /* Kill it */
151  }
152 
153  /* Get the next process */
155  }
156 }
157 
158 VOID
159 NTAPI
161 {
162  PAGED_CODE();
163 
164  /* Free the APC */
165  ExFreePool(Apc);
166 }
167 
168 VOID
169 NTAPI
171 {
172  PSINGLE_LIST_ENTRY NextEntry;
174  PSTRACE(PS_KILL_DEBUG, "Context: %p\n", Context);
175 
176  /* Start main loop */
177  do
178  {
179  /* Write magic value and return the next entry to process */
181  (PVOID)1);
182  ASSERT((NextEntry != NULL) && (NextEntry != (PVOID)1));
183 
184  /* Start inner loop */
185  do
186  {
187  /* Get the first Thread Entry */
188  Thread = CONTAINING_RECORD(NextEntry, ETHREAD, ReaperLink);
189 
190  /* Delete this entry's kernel stack */
192  Thread->Tcb.LargeStack);
194 
195  /* Move to the next entry */
196  NextEntry = NextEntry->Next;
197 
198  /* Dereference this thread */
200  } while ((NextEntry != NULL) && (NextEntry != (PVOID)1));
201 
202  /* Remove magic value, keep looping if it got changed */
204  NULL,
205  (PVOID)1) != (PVOID)1);
206 }
207 
208 #if DBG
209 VOID
210 NTAPI
211 PspCheckProcessList(VOID)
212 {
214 
216  DbgPrint("# checking PsActiveProcessHead @ %p\n", &PsActiveProcessHead);
219  Entry = Entry->Flink)
220  {
221  PEPROCESS Process = CONTAINING_RECORD(Entry, EPROCESS, ActiveProcessLinks);
223  PVOID Info, HeaderLocation;
224 
225  /* Get the header and assume this is what we'll free */
227  HeaderLocation = Header;
228 
229  /* To find the header, walk backwards from how we allocated */
231  {
232  HeaderLocation = Info;
233  }
235  {
236  HeaderLocation = Info;
237  }
239  {
240  HeaderLocation = Info;
241  }
243  {
244  HeaderLocation = Info;
245  }
246 
247  ExpCheckPoolAllocation(HeaderLocation, NonPagedPool, 'corP');
248  }
249 
251 }
252 #endif
253 
254 VOID
255 NTAPI
257 {
258  PEPROCESS Process = (PEPROCESS)ObjectBody;
260  PAGED_CODE();
261  PSTRACE(PS_KILL_DEBUG, "ObjectBody: %p\n", ObjectBody);
263 
264  /* Check if it has an Active Process Link */
265  if (Process->ActiveProcessLinks.Flink)
266  {
267  /* Remove it from the Active List */
269  RemoveEntryList(&Process->ActiveProcessLinks);
270  Process->ActiveProcessLinks.Flink = NULL;
271  Process->ActiveProcessLinks.Blink = NULL;
273  }
274 
275  /* Check for Auditing information */
276  if (Process->SeAuditProcessCreationInfo.ImageFileName)
277  {
278  /* Free it */
279  ExFreePoolWithTag(Process->SeAuditProcessCreationInfo.ImageFileName,
280  TAG_SEPA);
281  Process->SeAuditProcessCreationInfo.ImageFileName = NULL;
282  }
283 
284  /* Check if we have a job */
285  if (Process->Job)
286  {
287  /* Remove the process from the job */
289 
290  /* Dereference it */
292  Process->Job = NULL;
293  }
294 
295  /* Increase the stack count */
296  Process->Pcb.StackCount++;
297 
298  /* Check if we have a debug port */
299  if (Process->DebugPort)
300  {
301  /* Deference the Debug Port */
302  ObDereferenceObject(Process->DebugPort);
303  Process->DebugPort = NULL;
304  }
305 
306  /* Check if we have an exception port */
307  if (Process->ExceptionPort)
308  {
309  /* Deference the Exception Port */
310  ObDereferenceObject(Process->ExceptionPort);
311  Process->ExceptionPort = NULL;
312  }
313 
314  /* Check if we have a section object */
315  if (Process->SectionObject)
316  {
317  /* Deference the Section Object */
318  ObDereferenceObject(Process->SectionObject);
319  Process->SectionObject = NULL;
320  }
321 
322 #if defined(_X86_)
323  /* Clean Ldt and Vdm objects */
326 #endif
327 
328  /* Delete the Object Table */
329  if (Process->ObjectTable)
330  {
331  /* Attach to the process */
333 
334  /* Kill the Object Info */
336 
337  /* Detach */
339  }
340 
341  /* Check if we have an address space, and clean it */
342  if (Process->HasAddressSpace)
343  {
344  /* Attach to the process */
346 
347  /* Clean the Address Space */
349 
350  /* Detach */
352 
353  /* Completely delete the Address Space */
355  }
356 
357  /* See if we have a PID */
358  if (Process->UniqueProcessId)
359  {
360  /* Delete the PID */
361  if (!(ExDestroyHandle(PspCidTable, Process->UniqueProcessId, NULL)))
362  {
363  /* Something wrong happened, bugcheck */
364  KeBugCheck(CID_HANDLE_DELETION);
365  }
366  }
367 
368  /* Cleanup security information */
370 
371  /* Check if we have kept information on the Working Set */
372  if (Process->WorkingSetWatch)
373  {
374  /* Free it */
375  ExFreePool(Process->WorkingSetWatch);
376 
377  /* And return the quota it was taking up */
379  }
380 
381  /* Dereference the Device Map */
383 
384  /*
385  * Dereference the quota block, the function
386  * will invoke a quota block cleanup if the
387  * block itself is no longer used by anybody.
388  */
390 }
391 
392 VOID
393 NTAPI
395 {
396  PETHREAD Thread = (PETHREAD)ObjectBody;
397  PEPROCESS Process = Thread->ThreadsProcess;
398  PAGED_CODE();
399  PSTRACE(PS_KILL_DEBUG, "ObjectBody: %p\n", ObjectBody);
402 
403  /* Check if we have a stack */
404  if (Thread->Tcb.InitialStack)
405  {
406  /* Release it */
408  Thread->Tcb.LargeStack);
409  }
410 
411  /* Check if we have a CID Handle */
412  if (Thread->Cid.UniqueThread)
413  {
414  /* Delete the CID Handle */
416  {
417  /* Something wrong happened, bugcheck */
418  KeBugCheck(CID_HANDLE_DELETION);
419  }
420  }
421 
422  /* Cleanup impersionation information */
424 
425  /* Make sure the thread was inserted, before continuing */
426  if (!Process) return;
427 
428  /* Check if the thread list is valid */
430  {
431  /* Lock the thread's process */
433  ExAcquirePushLockExclusive(&Process->ProcessLock);
434 
435  /* Remove us from the list */
437 
438  /* Release the lock */
439  ExReleasePushLockExclusive(&Process->ProcessLock);
441  }
442 
443  /* Dereference the Process */
445 }
446 
447 /*
448  * FUNCTION: Terminates the current thread
449  * See "Windows Internals" - Chapter 13, Page 50-53
450  */
451 VOID
452 NTAPI
454 {
455  CLIENT_DIED_MSG TerminationMsg;
457  PTEB Teb;
459  PETHREAD Thread, OtherThread, PreviousThread = NULL;
460  PVOID DeallocationStack;
461  SIZE_T Dummy;
462  BOOLEAN Last = FALSE;
463  PTERMINATION_PORT TerminationPort, NextPort;
464  PLIST_ENTRY FirstEntry, CurrentEntry;
465  PKAPC Apc;
466  PTOKEN PrimaryToken;
467  PAGED_CODE();
468  PSTRACE(PS_KILL_DEBUG, "ExitStatus: %d\n", ExitStatus);
469 
470  /* Get the Current Thread and Process */
472  CurrentProcess = Thread->ThreadsProcess;
474 
475  /* Can't terminate a thread if it attached another process */
476  if (KeIsAttachedProcess())
477  {
478  /* Bugcheck */
479  KeBugCheckEx(INVALID_PROCESS_ATTACH_ATTEMPT,
481  (ULONG_PTR)Thread->Tcb.ApcState.Process,
483  (ULONG_PTR)Thread);
484  }
485 
486  /* Lower to Passive Level */
488 
489  /* Can't be a worker thread */
490  if (Thread->ActiveExWorker)
491  {
492  /* Bugcheck */
493  KeBugCheckEx(ACTIVE_EX_WORKER_THREAD_TERMINATION,
494  (ULONG_PTR)Thread,
495  0,
496  0,
497  0);
498  }
499 
500  /* Can't have pending APCs */
501  if (Thread->Tcb.CombinedApcDisable != 0)
502  {
503  /* Bugcheck */
504  KeBugCheckEx(KERNEL_APC_PENDING_DURING_EXIT,
505  0,
507  0,
508  1);
509  }
510 
511  /* Lock the thread */
513 
514  /* Cleanup the power state */
516 
517  /* Call the WMI Callback for Threads */
518  //WmiTraceThread(Thread, NULL, FALSE);
519 
520  /* Run Thread Notify Routines before we desintegrate the thread */
522 
523  /* Lock the Process before we modify its thread entries */
526 
527  /* Decrease the active thread count, and check if it's 0 */
528  if (!(--CurrentProcess->ActiveThreads))
529  {
530  /* Set the delete flag */
532 
533  /* Remember we are last */
534  Last = TRUE;
535 
536  /* Check if this termination is due to the thread dying */
538  {
539  /* Check if the last thread was pending */
540  if (CurrentProcess->ExitStatus == STATUS_PENDING)
541  {
542  /* Use the last exit status */
543  CurrentProcess->ExitStatus = CurrentProcess->
544  LastThreadExitStatus;
545  }
546  }
547  else
548  {
549  /* Just a normal exit, write the code */
550  CurrentProcess->ExitStatus = ExitStatus;
551  }
552 
553  /* Loop all the current threads */
554  FirstEntry = &CurrentProcess->ThreadListHead;
555  CurrentEntry = FirstEntry->Flink;
556  while (FirstEntry != CurrentEntry)
557  {
558  /* Get the thread on the list */
559  OtherThread = CONTAINING_RECORD(CurrentEntry,
560  ETHREAD,
561  ThreadListEntry);
562 
563  /* Check if it's a thread that's still alive */
564  if ((OtherThread != Thread) &&
565  !(KeReadStateThread(&OtherThread->Tcb)) &&
566  (ObReferenceObjectSafe(OtherThread)))
567  {
568  /* It's a live thread and we referenced it, unlock process */
571 
572  /* Wait on the thread */
573  KeWaitForSingleObject(OtherThread,
574  Executive,
575  KernelMode,
576  FALSE,
577  NULL);
578 
579  /* Check if we had a previous thread to dereference */
580  if (PreviousThread) ObDereferenceObject(PreviousThread);
581 
582  /* Remember the thread and re-lock the process */
583  PreviousThread = OtherThread;
586  }
587 
588  /* Go to the next thread */
589  CurrentEntry = CurrentEntry->Flink;
590  }
591  }
593  {
594  /* Write down the exit status of the last thread to get killed */
595  CurrentProcess->LastThreadExitStatus = ExitStatus;
596  }
597 
598  /* Unlock the Process */
601 
602  /* Check if we had a previous thread to dereference */
603  if (PreviousThread) ObDereferenceObject(PreviousThread);
604 
605  /* Check if the process has a debug port and if this is a user thread */
606  if ((CurrentProcess->DebugPort) && !(Thread->SystemThread))
607  {
608  /* Notify the Debug API. */
609  Last ? DbgkExitProcess(CurrentProcess->ExitStatus) :
611  }
612 
613  /* Check if this is a Critical Thread */
615  {
616  /* Break to debugger */
617  PspCatchCriticalBreak("Critical thread 0x%p (in %s) exited\n",
618  Thread,
619  CurrentProcess->ImageFileName);
620  }
621 
622  /* Check if it's the last thread and this is a Critical Process */
623  if ((Last) && (CurrentProcess->BreakOnTermination))
624  {
625  /* Check if a debugger is here to handle this */
626  if (KdDebuggerEnabled)
627  {
628  /* Break to debugger */
629  PspCatchCriticalBreak("Critical process 0x%p (in %s) exited\n",
631  CurrentProcess->ImageFileName);
632  }
633  else
634  {
635  /* Bugcheck, we can't allow this */
636  KeBugCheckEx(CRITICAL_PROCESS_DIED,
638  0,
639  0,
640  0);
641  }
642  }
643 
644  /* Sanity check */
646 
647  /* Process the Termination Ports */
648  TerminationPort = Thread->TerminationPort;
649  if (TerminationPort)
650  {
651  /* Setup the message header */
652  TerminationMsg.h.u2.ZeroInit = 0;
653  TerminationMsg.h.u2.s2.Type = LPC_CLIENT_DIED;
654  TerminationMsg.h.u1.s1.TotalLength = sizeof(TerminationMsg);
655  TerminationMsg.h.u1.s1.DataLength = sizeof(TerminationMsg) -
656  sizeof(PORT_MESSAGE);
657 
658  /* Loop each port */
659  do
660  {
661  /* Save the Create Time */
662  TerminationMsg.CreateTime = Thread->CreateTime;
663 
664  /* Loop trying to send message */
665  while (TRUE)
666  {
667  /* Send the LPC Message */
668  Status = LpcRequestPort(TerminationPort->Port,
669  &TerminationMsg.h);
670  if ((Status == STATUS_NO_MEMORY) ||
672  {
673  /* Wait a bit and try again */
675  continue;
676  }
677  break;
678  }
679 
680  /* Dereference this LPC Port */
681  ObDereferenceObject(TerminationPort->Port);
682 
683  /* Move to the next one */
684  NextPort = TerminationPort->Next;
685 
686  /* Free the Termination Port Object */
687  ExFreePoolWithTag(TerminationPort, '=TsP');
688 
689  /* Keep looping as long as there is a port */
690  TerminationPort = NextPort;
691  } while (TerminationPort);
692  }
693  else if (((ExitStatus == STATUS_THREAD_IS_TERMINATING) &&
694  (Thread->DeadThread)) ||
695  !(Thread->DeadThread))
696  {
697  /*
698  * This case is special and deserves some extra comments. What
699  * basically happens here is that this thread doesn't have a termination
700  * port, which means that it died before being fully created. Since we
701  * still have to notify an LPC Server, we'll use the exception port,
702  * which we know exists. However, we need to know how far the thread
703  * actually got created. We have three possibilities:
704  *
705  * - NtCreateThread returned an error really early: DeadThread is set.
706  * - NtCreateThread managed to create the thread: DeadThread is off.
707  * - NtCreateThread was creating the thread (with DeadThread set,
708  * but the thread got killed prematurely: STATUS_THREAD_IS_TERMINATING
709  * is our exit code.)
710  *
711  * For the 2 & 3rd scenarios, the thread has been created far enough to
712  * warrant notification to the LPC Server.
713  */
714 
715  /* Setup the message header */
716  TerminationMsg.h.u2.ZeroInit = 0;
717  TerminationMsg.h.u2.s2.Type = LPC_CLIENT_DIED;
718  TerminationMsg.h.u1.s1.TotalLength = sizeof(TerminationMsg);
719  TerminationMsg.h.u1.s1.DataLength = sizeof(TerminationMsg) -
720  sizeof(PORT_MESSAGE);
721 
722  /* Make sure the process has an exception port */
723  if (CurrentProcess->ExceptionPort)
724  {
725  /* Save the Create Time */
726  TerminationMsg.CreateTime = Thread->CreateTime;
727 
728  /* Loop trying to send message */
729  while (TRUE)
730  {
731  /* Send the LPC Message */
732  Status = LpcRequestPort(CurrentProcess->ExceptionPort,
733  &TerminationMsg.h);
734  if ((Status == STATUS_NO_MEMORY) ||
736  {
737  /* Wait a bit and try again */
739  continue;
740  }
741  break;
742  }
743  }
744  }
745 
746  /* Rundown Win32 Thread if there is one */
749 
750  /* If we are the last thread and have a W32 Process */
751  if ((Last) && (CurrentProcess->Win32Process))
752  {
753  /* Run it down too */
755  }
756 
757  /* Make sure Stack Swap is enabled */
758  if (!Thread->Tcb.EnableStackSwap)
759  {
760  /* Stack swap really shouldn't be disabled during exit! */
761  KeBugCheckEx(KERNEL_STACK_LOCKED_AT_EXIT, 0, 0, 0, 0);
762  }
763 
764  /* Cancel I/O for the thread. */
766 
767  /* Rundown Timers */
768  ExTimerRundown();
769 
770  /* FIXME: Rundown Registry Notifications (NtChangeNotify)
771  CmNotifyRunDown(Thread); */
772 
773  /* Rundown Mutexes */
774  KeRundownThread();
775 
776  /* Check if we have a TEB */
777  Teb = Thread->Tcb.Teb;
778  if (Teb)
779  {
780  /* Check if the thread is still alive */
781  if (!Thread->DeadThread)
782  {
783  /* Check if we need to free its stack */
784  if (Teb->FreeStackOnTermination)
785  {
786  /* Set the TEB's Deallocation Stack as the Base Address */
787  Dummy = 0;
788  DeallocationStack = Teb->DeallocationStack;
789 
790  /* Free the Thread's Stack */
791  ZwFreeVirtualMemory(NtCurrentProcess(),
792  &DeallocationStack,
793  &Dummy,
794  MEM_RELEASE);
795  }
796 
797  /* Free the debug handle */
798  if (Teb->DbgSsReserved[1]) ObCloseHandle(Teb->DbgSsReserved[1],
799  UserMode);
800  }
801 
802  /* Decommit the TEB */
804  Thread->Tcb.Teb = NULL;
805  }
806 
807  /* Free LPC Data */
809 
810  /* Save the exit status and exit time */
813 
814  /* Sanity check */
816 
817  /* Check if this is the final thread or not */
818  if (Last)
819  {
820  /* Set the process exit time */
821  CurrentProcess->ExitTime = Thread->ExitTime;
822 
823  /* Exit the process */
825 
826  /* Get the process token and check if we need to audit */
827  PrimaryToken = PsReferencePrimaryToken(CurrentProcess);
828  if (SeDetailedAuditingWithToken(PrimaryToken))
829  {
830  /* Audit the exit */
832  }
833 
834  /* Dereference the process token */
835  ObFastDereferenceObject(&CurrentProcess->Token, PrimaryToken);
836 
837  /* Check if this is a VDM Process and rundown the VDM DPCs if so */
838  if (CurrentProcess->VdmObjects) { /* VdmRundownDpcs(CurrentProcess); */ }
839 
840  /* Kill the process in the Object Manager */
842 
843  /* Check if we have a section object */
844  if (CurrentProcess->SectionObject)
845  {
846  /* Dereference and clear the Section Object */
847  ObDereferenceObject(CurrentProcess->SectionObject);
848  CurrentProcess->SectionObject = NULL;
849  }
850 
851  /* Check if the process is part of a job */
852  if (CurrentProcess->Job)
853  {
854  /* Remove the process from the job */
856  }
857  }
858 
859  /* Disable APCs */
861 
862  /* Disable APC queueing, force a resumption */
865 
866  /* Re-enable APCs */
868 
869  /* Flush the User APCs */
870  FirstEntry = KeFlushQueueApc(&Thread->Tcb, UserMode);
871  if (FirstEntry)
872  {
873  /* Start with the first entry */
874  CurrentEntry = FirstEntry;
875  do
876  {
877  /* Get the APC */
878  Apc = CONTAINING_RECORD(CurrentEntry, KAPC, ApcListEntry);
879 
880  /* Move to the next one */
881  CurrentEntry = CurrentEntry->Flink;
882 
883  /* Rundown the APC or de-allocate it */
884  if (Apc->RundownRoutine)
885  {
886  /* Call its own routine */
887  Apc->RundownRoutine(Apc);
888  }
889  else
890  {
891  /* Do it ourselves */
892  ExFreePool(Apc);
893  }
894  }
895  while (CurrentEntry != FirstEntry);
896  }
897 
898  /* Clean address space if this was the last thread */
900 
901  /* Call the Lego routine */
903 
904  /* Flush the APC queue, which should be empty */
905  FirstEntry = KeFlushQueueApc(&Thread->Tcb, KernelMode);
906  if ((FirstEntry) || (Thread->Tcb.CombinedApcDisable != 0))
907  {
908  /* Bugcheck time */
909  KeBugCheckEx(KERNEL_APC_PENDING_DURING_EXIT,
910  (ULONG_PTR)FirstEntry,
913  0);
914  }
915 
916  /* Signal the process if this was the last thread */
917  if (Last) KeSetProcess(&CurrentProcess->Pcb, 0, FALSE);
918 
919  /* Terminate the Thread from the Scheduler */
921 }
922 
923 VOID
924 NTAPI
926  IN OUT PKNORMAL_ROUTINE* NormalRoutine,
927  IN OUT PVOID* NormalContext,
930 {
932  PAGED_CODE();
934  "Apc: %p SystemArgument2: %p\n", Apc, SystemArgument2);
935 
936  /* Don't do anything unless we are in User-Mode */
937  if (Apc->SystemArgument2)
938  {
939  /* Free the APC */
940  Status = PtrToUlong(Apc->NormalContext);
941  PspExitApcRundown(Apc);
942 
943  /* Terminate the Thread */
945  }
946 }
947 
948 VOID
949 NTAPI
950 PspExitNormalApc(IN PVOID NormalContext,
953 {
954  PKAPC Apc = (PKAPC)SystemArgument1;
956  PAGED_CODE();
957  PSTRACE(PS_KILL_DEBUG, "SystemArgument2: %p\n", SystemArgument2);
958 
959  /* This should never happen */
960  ASSERT(!(((ULONG_PTR)SystemArgument2) & 1));
961 
962  /* If we're here, this is not a System Thread, so kill it from User-Mode */
963  KeInitializeApc(Apc,
964  &Thread->Tcb,
969  UserMode,
970  NormalContext);
971 
972  /* Now insert the APC with the User-Mode Flag */
973  if (!(KeInsertQueueApc(Apc,
974  Apc,
976  2)))
977  {
978  /* Failed to insert, free the APC */
979  PspExitApcRundown(Apc);
980  }
981 
982  /* Set the APC Pending flag */
983  Thread->Tcb.ApcState.UserApcPending = TRUE;
984 }
985 
986 /*
987  * See "Windows Internals" - Chapter 13, Page 49
988  */
989 NTSTATUS
990 NTAPI
993  IN BOOLEAN bSelf)
994 {
995  PKAPC Apc;
997  ULONG Flags;
998  PAGED_CODE();
999  PSTRACE(PS_KILL_DEBUG, "Thread: %p ExitStatus: %d\n", Thread, ExitStatus);
1000  PSREFTRACE(Thread);
1001 
1002  /* Check if this is a Critical Thread, and Bugcheck */
1004  {
1005  /* Break to debugger */
1006  PspCatchCriticalBreak("Terminating critical thread 0x%p (%s)\n",
1007  Thread,
1008  Thread->ThreadsProcess->ImageFileName);
1009  }
1010 
1011  /* Check if we are already inside the thread */
1012  if ((bSelf) || (PsGetCurrentThread() == Thread))
1013  {
1014  /* This should only happen at passive */
1016 
1017  /* Mark it as terminated */
1019 
1020  /* Directly terminate the thread */
1022  }
1023 
1024  /* This shouldn't be a system thread */
1026 
1027  /* Allocate the APC */
1029  if (!Apc) return STATUS_INSUFFICIENT_RESOURCES;
1030 
1031  /* Set the Terminated Flag */
1033 
1034  /* Set it, and check if it was already set while we were running */
1037  {
1038  /* Initialize a Kernel Mode APC to Kill the Thread */
1039  KeInitializeApc(Apc,
1040  &Thread->Tcb,
1045  KernelMode,
1047 
1048  /* Insert it into the APC Queue */
1049  if (!KeInsertQueueApc(Apc, Apc, NULL, 2))
1050  {
1051  /* The APC was already in the queue, fail */
1053  }
1054  else
1055  {
1056  /* Forcefully resume the thread and return */
1058  return Status;
1059  }
1060  }
1061 
1062  /* We failed, free the APC */
1064 
1065  /* Return Status */
1066  return Status;
1067 }
1068 
1069 BOOLEAN
1070 NTAPI
1072 {
1073  return Process->Flags & PSF_PROCESS_EXITING_BIT;
1074 }
1075 
1076 VOID
1077 NTAPI
1080 {
1081  ULONG Actual;
1082  PAGED_CODE();
1084  "LastThread: %u Process: %p\n", LastThread, Process);
1086 
1087  /* Set Process Exit flag */
1089 
1090  /* Check if we are the last thread */
1091  if (LastThread)
1092  {
1093  /* Notify the WMI Process Callback */
1094  //WmiTraceProcess(Process, FALSE);
1095 
1096  /* Run the Notification Routines */
1098  }
1099 
1100  /* Cleanup the power state */
1101  PopCleanupPowerState((PPOWER_STATE)&Process->Pcb.PowerState);
1102 
1103  /* Clear the security port */
1104  if (!Process->SecurityPort)
1105  {
1106  /* So we don't double-dereference */
1107  Process->SecurityPort = (PVOID)1;
1108  }
1109  else if (Process->SecurityPort != (PVOID)1)
1110  {
1111  /* Dereference it */
1112  ObDereferenceObject(Process->SecurityPort);
1113  Process->SecurityPort = (PVOID)1;
1114  }
1115 
1116  /* Check if we are the last thread */
1117  if (LastThread)
1118  {
1119  /* Check if we have to set the Timer Resolution */
1120  if (Process->SetTimerResolution)
1121  {
1122  /* Set it to default */
1124  }
1125 
1126  /* Check if we are part of a Job that has a completion port */
1127  if ((Process->Job) && (Process->Job->CompletionPort))
1128  {
1129  /* FIXME: Check job status code and do I/O completion if needed */
1130  }
1131 
1132  /* FIXME: Notify the Prefetcher */
1133  }
1134  else
1135  {
1136  /* Clear process' address space here */
1138  }
1139 }
1140 
1141 /* PUBLIC FUNCTIONS **********************************************************/
1142 
1143 /*
1144  * @implemented
1145  */
1146 NTSTATUS
1147 NTAPI
1149 {
1151 
1152  /* Make sure this is a system thread */
1154 
1155  /* Terminate it for real */
1157 }
1158 
1159 /*
1160  * @implemented
1161  */
1162 NTSTATUS
1163 NTAPI
1166 {
1167  NTSTATUS Status;
1169  PETHREAD Thread, CurrentThread = PsGetCurrentThread();
1170  BOOLEAN KillByHandle;
1171  PAGED_CODE();
1173  "ProcessHandle: %p ExitStatus: %d\n", ProcessHandle, ExitStatus);
1174 
1175  /* Were we passed a process handle? */
1176  if (ProcessHandle)
1177  {
1178  /* Yes we were, use it */
1179  KillByHandle = TRUE;
1180  }
1181  else
1182  {
1183  /* We weren't... we assume this is suicide */
1184  KillByHandle = FALSE;
1186  }
1187 
1188  /* Get the Process Object */
1191  PsProcessType,
1193  (PVOID*)&Process,
1194  NULL);
1195  if (!NT_SUCCESS(Status)) return(Status);
1196 
1197  /* Check if this is a Critical Process, and Bugcheck */
1198  if (Process->BreakOnTermination)
1199  {
1200  /* Break to debugger */
1201  PspCatchCriticalBreak("Terminating critical process 0x%p (%s)\n",
1202  Process,
1203  Process->ImageFileName);
1204  }
1205 
1206  /* Lock the Process */
1207  if (!ExAcquireRundownProtection(&Process->RundownProtect))
1208  {
1209  /* Failed to lock, fail */
1212  }
1213 
1214  /* Set the delete flag, unless the process is comitting suicide */
1215  if (KillByHandle) PspSetProcessFlag(Process, PSF_PROCESS_DELETE_BIT);
1216 
1217  /* Get the first thread */
1220  if (Thread)
1221  {
1222  /* We know we have at least a thread */
1224 
1225  /* Loop and kill the others */
1226  do
1227  {
1228  /* Ensure it's not ours*/
1229  if (Thread != CurrentThread)
1230  {
1231  /* Kill it */
1233  }
1234 
1235  /* Move to the next thread */
1237  } while (Thread);
1238  }
1239 
1240  /* Unlock the process */
1241  ExReleaseRundownProtection(&Process->RundownProtect);
1242 
1243  /* Check if we are killing ourselves */
1244  if (Process == CurrentProcess)
1245  {
1246  /* Also make sure the caller gave us our handle */
1247  if (KillByHandle)
1248  {
1249  /* Dereference the process */
1251 
1252  /* Terminate ourselves */
1253  PspTerminateThreadByPointer(CurrentThread, ExitStatus, TRUE);
1254  }
1255  }
1256  else if (ExitStatus == DBG_TERMINATE_PROCESS)
1257  {
1258  /* Disable debugging on this process */
1260  }
1261 
1262  /* Check if there was nothing to terminate, or if we have a Debug Port */
1264  ((Process->DebugPort) && (KillByHandle)))
1265  {
1266  /* Clear the handle table */
1268 
1269  /* Return status now */
1271  }
1272 
1273  /* Decrease the reference count we added */
1275 
1276  /* Return status */
1277  return Status;
1278 }
1279 
1280 NTSTATUS
1281 NTAPI
1284 {
1285  PETHREAD Thread;
1286  PETHREAD CurrentThread = PsGetCurrentThread();
1287  NTSTATUS Status;
1288  PAGED_CODE();
1290  "ThreadHandle: %p ExitStatus: %d\n", ThreadHandle, ExitStatus);
1291 
1292  /* Handle the special NULL case */
1293  if (!ThreadHandle)
1294  {
1295  /* Check if we're the only thread left */
1296  if (PsGetCurrentProcess()->ActiveThreads == 1)
1297  {
1298  /* This is invalid */
1300  }
1301 
1302  /* Terminate us directly */
1303  goto TerminateSelf;
1304  }
1305  else if (ThreadHandle == NtCurrentThread())
1306  {
1307 TerminateSelf:
1308  /* Terminate this thread */
1309  return PspTerminateThreadByPointer(CurrentThread,
1310  ExitStatus,
1311  TRUE);
1312  }
1313 
1314  /* We are terminating another thread, get the Thread Object */
1315  Status = ObReferenceObjectByHandle(ThreadHandle,
1317  PsThreadType,
1319  (PVOID*)&Thread,
1320  NULL);
1321  if (!NT_SUCCESS(Status)) return Status;
1322 
1323  /* Check to see if we're running in the same thread */
1324  if (Thread != CurrentThread)
1325  {
1326  /* Terminate it */
1328 
1329  /* Dereference the Thread and return */
1331  }
1332  else
1333  {
1334  /* Dereference the thread and terminate ourselves */
1336  goto TerminateSelf;
1337  }
1338 
1339  /* Return status */
1340  return Status;
1341 }
1342 
1343 NTSTATUS
1344 NTAPI
1346 {
1347  NTSTATUS Status;
1348  PTERMINATION_PORT TerminationPort;
1349  PVOID TerminationLpcPort;
1350  PETHREAD Thread;
1351  PAGED_CODE();
1352  PSTRACE(PS_KILL_DEBUG, "PortHandle: %p\n", PortHandle);
1353 
1354  /* Get the Port */
1355  Status = ObReferenceObjectByHandle(PortHandle,
1359  &TerminationLpcPort,
1360  NULL);
1361  if (!NT_SUCCESS(Status)) return(Status);
1362 
1363  /* Allocate the Port and make sure it suceeded */
1364  TerminationPort = ExAllocatePoolWithTag(NonPagedPool,
1365  sizeof(TERMINATION_PORT),
1366  '=TsP');
1367  if(TerminationPort)
1368  {
1369  /* Associate the Port */
1371  TerminationPort->Port = TerminationLpcPort;
1372  TerminationPort->Next = Thread->TerminationPort;
1373  Thread->TerminationPort = TerminationPort;
1374 
1375  /* Return success */
1376  return STATUS_SUCCESS;
1377  }
1378 
1379  /* Dereference and Fail */
1380  ObDereferenceObject(TerminationLpcPort);
1382 }
#define KeQuerySystemTime(t)
Definition: env_spec_w32.h:570
VOID NTAPI ObKillProcess(IN PEPROCESS Process)
Definition: obhandle.c:2160
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
VOID NTAPI KeInitializeApc(IN PKAPC Apc, IN PKTHREAD Thread, IN KAPC_ENVIRONMENT TargetEnvironment, IN PKKERNEL_ROUTINE KernelRoutine, IN PKRUNDOWN_ROUTINE RundownRoutine OPTIONAL, IN PKNORMAL_ROUTINE NormalRoutine, IN KPROCESSOR_MODE Mode, IN PVOID Context)
Definition: apc.c:651
signed char * PCHAR
Definition: retypes.h:7
PLIST_ENTRY NTAPI KeFlushQueueApc(IN PKTHREAD Thread, IN KPROCESSOR_MODE PreviousMode)
Definition: apc.c:793
BOOLEAN KdDebuggerEnabled
Definition: kddata.c:83
ULONG KeMaximumIncrement
Definition: clock.c:20
VOID NTAPI KeRundownThread(VOID)
Definition: thrdobj.c:439
FORCEINLINE VOID ExAcquirePushLockExclusive(PEX_PUSH_LOCK PushLock)
Definition: ex.h:1034
#define IN
Definition: typedefs.h:39
LARGE_INTEGER ExitTime
Definition: pstypes.h:1107
LIST_ENTRY ThreadListEntry
Definition: pstypes.h:1158
NTSTATUS NTAPI NtTerminateThread(IN HANDLE ThreadHandle, IN NTSTATUS ExitStatus)
Definition: kill.c:1282
KAPC_STATE
Definition: ketypes.h:1285
#define DBG_TERMINATE_PROCESS
Definition: ntstatus.h:51
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
VOID NTAPI PspDeleteVdmObjects(PEPROCESS Process)
Definition: psldt.c:27
BOOLEAN NTAPI ExDestroyHandle(IN PHANDLE_TABLE HandleTable, IN HANDLE Handle, IN PHANDLE_TABLE_ENTRY HandleTableEntry OPTIONAL)
Definition: handle.c:984
VOID NTAPI IoCancelThreadIo(IN PETHREAD Thread)
Definition: irp.c:1146
ULONG EnableStackSwap
Definition: ketypes.h:1669
#define DbgPrint
Definition: hal.h:12
struct _Entry Entry
Definition: kefuncs.h:629
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
Definition: ntbasedef.h:628
VOID NTAPI ExTimerRundown(VOID)
Definition: timer.c:43
VOID FASTCALL KeAcquireGuardedMutex(IN PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:42
ULONG CombinedApcDisable
Definition: ketypes.h:1823
NTSYSAPI ULONG NTAPI DbgPrompt(_In_z_ PCCH Prompt, _Out_writes_bytes_(MaximumResponseLength) PCH Response, _In_ ULONG MaximumResponseLength)
LARGE_INTEGER CreateTime
Definition: lpctypes.h:270
NTKERNELAPI VOID FASTCALL ExReleaseRundownProtection(_Inout_ PEX_RUNDOWN_REF RunRef)
#define TRUE
Definition: types.h:120
#define OBJECT_HEADER_TO_HANDLE_INFO(h)
Definition: obtypes.h:118
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define STATUS_THREAD_IS_TERMINATING
Definition: ntstatus.h:311
#define ASSERT_IRQL_EQUAL(x)
Definition: debug.h:43
VOID NTAPI MmDeleteKernelStack(PVOID Stack, BOOLEAN GuiStack)
NTSTATUS NTAPI NtTerminateProcess(IN HANDLE ProcessHandle OPTIONAL, IN NTSTATUS ExitStatus)
Definition: kill.c:1164
char CHAR
Definition: xmlstorage.h:175
LARGE_INTEGER CreateTime
Definition: pstypes.h:1104
#define KeGetPreviousMode()
Definition: ketypes.h:1108
LONG NTSTATUS
Definition: precomp.h:26
EX_RUNDOWN_REF RundownProtect
Definition: pstypes.h:1159
KTHREAD Tcb
Definition: pstypes.h:1103
struct _EPROCESS * PEPROCESS
Definition: nt_native.h:30
#define NtCurrentThread()
#define ExAcquireRundownProtection
Definition: ex.h:133
PKWIN32_PROCESS_CALLOUT PspW32ProcessCallout
Definition: win32.c:18
VOID NTAPI PspCatchCriticalBreak(IN PCHAR Message, IN PVOID ProcessOrThread, IN PCHAR ImageName)
Definition: kill.c:27
#define OBJECT_HEADER_TO_NAME_INFO(h)
Definition: obtypes.h:114
VOID NTAPI PspExitProcess(IN BOOLEAN LastThread, IN PEPROCESS Process)
Definition: kill.c:1078
#define PSF_PROCESS_EXITING_BIT
Definition: pstypes.h:275
PHANDLE_TABLE PspCidTable
Definition: psmgr.c:48
LIST_ENTRY PsActiveProcessHead
Definition: process.c:22
struct _TERMINATION_PORT * Next
Definition: pstypes.h:1080
VOID NTAPI MmDeleteTeb(struct _EPROCESS *Process, PTEB Teb)
BOOLEAN NTAPI PspIsProcessExiting(IN PEPROCESS Process)
Definition: kill.c:1071
NTSTATUS NTAPI KeWaitForSingleObject(IN PVOID Object, IN KWAIT_REASON WaitReason, IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout OPTIONAL)
Definition: wait.c:416
BOOLEAN FASTCALL ObReferenceObjectSafe(IN PVOID Object)
Definition: obref.c:22
uint32_t ULONG_PTR
Definition: typedefs.h:65
_Must_inspect_result_ _In_ WDFCHILDLIST _In_ PWDF_CHILD_LIST_ITERATOR _Out_ WDFDEVICE _Inout_opt_ PWDF_CHILD_RETRIEVE_INFO Info
Definition: wdfchildlist.h:683
#define OBJECT_TO_OBJECT_HEADER(o)
Definition: obtypes.h:111
ULONG NTAPI KeSetProcess(struct _KPROCESS *Process, KPRIORITY Increment, BOOLEAN InWait)
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
BOOLEAN KdDebuggerNotPresent
Definition: kddata.c:82
PEPROCESS PsIdleProcess
Definition: psmgr.c:51
NTSTATUS NTAPI ObReferenceObjectByHandle(IN HANDLE Handle, IN ACCESS_MASK DesiredAccess, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode, OUT PVOID *Object, OUT POBJECT_HANDLE_INFORMATION HandleInformation OPTIONAL)
Definition: obref.c:494
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
#define FALSE
Definition: types.h:117
PEPROCESS PsInitialSystemProcess
Definition: psmgr.c:50
VOID NTAPI KeStackAttachProcess(IN PKPROCESS Process, OUT PRKAPC_STATE ApcState)
Definition: procobj.c:704
VOID NTAPI DbgBreakPoint(VOID)
Definition: Header.h:8
DECLSPEC_NORETURN VOID NTAPI KeBugCheck(ULONG BugCheckCode)
Definition: bug.c:1427
PKWIN32_THREAD_CALLOUT PspW32ThreadCallout
Definition: win32.c:19
KAPC_STATE ApcState
Definition: ketypes.h:1718
VOID NTAPI PspDeleteThread(IN PVOID ObjectBody)
Definition: kill.c:394
ULONG ActiveExWorker
Definition: pstypes.h:1200
#define InterlockedCompareExchangePointer
Definition: interlocked.h:129
NTSTATUS NTAPI KeDelayExecutionThread(IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Interval OPTIONAL)
Definition: wait.c:283
BOOLEAN NTAPI KeIsAttachedProcess(VOID)
Definition: procobj.c:693
BOOLEAN NTAPI KeReadStateThread(IN PKTHREAD Thread)
Definition: thrdobj.c:51
VOID NTAPI PspDereferenceQuotaBlock(_In_opt_ PEPROCESS Process, _In_ PEPROCESS_QUOTA_BLOCK QuotaBlock)
De-references a quota block when quotas have been returned back because of an object de-allocation or...
Definition: quota.c:553
#define PsGetCurrentProcess
Definition: psfuncs.h:17
VOID NTAPI PspExitProcessFromJob(IN PEJOB Job, IN PEPROCESS Process)
Definition: job.c:146
FORCEINLINE VOID ExReleasePushLockExclusive(PEX_PUSH_LOCK PushLock)
Definition: ex.h:1250
#define PSREFTRACE(x)
Definition: ps.h:58
unsigned char BOOLEAN
NTKERNELAPI VOID FASTCALL ExWaitForRundownProtectionRelease(_Inout_ PEX_RUNDOWN_REF RunRef)
void * PVOID
Definition: retypes.h:9
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
#define UlongToPtr(u)
Definition: config.h:106
#define PtrToUlong(u)
Definition: config.h:107
struct _TERMINATION_PORT * TerminationPort
Definition: pstypes.h:1119
#define STATUS_NOTHING_TO_TERMINATE
Definition: ntstatus.h:106
VOID NTAPI PspShutdownProcessManager(VOID)
Definition: kill.c:138
#define NtCurrentProcess()
Definition: nt_native.h:1657
VOID NTAPI KeTerminateThread(IN KPRIORITY Increment)
Definition: thrdobj.c:1375
NTSTATUS NTAPI LpcRequestPort(IN PVOID PortObject, IN PPORT_MESSAGE LpcMessage)
Definition: send.c:22
#define PS_KILL_DEBUG
Definition: ps.h:25
POBJECT_TYPE LpcPortObjectType
Definition: port.c:17
Status
Definition: gdiplustypes.h:24
_In_opt_ PVOID _In_opt_ PVOID SystemArgument1
Definition: ketypes.h:675
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
VOID NTAPI MmCleanProcessAddressSpace(IN PEPROCESS Process)
Definition: procsup.c:1267
NTSYSAPI NTSTATUS NTAPI ZwSetTimerResolution(_In_ ULONG RequestedResolution, _In_ BOOLEAN SetOrUnset, _Out_ PULONG ActualResolution)
#define CT_TERMINATED_BIT
Definition: pstypes.h:238
#define OBJECT_HEADER_TO_QUOTA_INFO(h)
Definition: obtypes.h:122
#define InterlockedExchangePointer(Target, Value)
Definition: dshow.h:45
ULONG CurrentProcess
Definition: shell.c:125
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
LARGE_INTEGER ShortTime
Definition: kill.c:21
#define ASSERT(a)
Definition: mode.c:44
_In_ BOOLEAN Handled
Definition: ketypes.h:337
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
PVOID DeallocationStack
Definition: compat.h:737
#define STATUS_PENDING
Definition: ntstatus.h:82
WORK_QUEUE_ITEM PspReaperWorkItem
Definition: kill.c:20
CLIENT_ID Cid
Definition: pstypes.h:1128
#define STATUS_PROCESS_IS_TERMINATING
Definition: ntstatus.h:502
PVOID DbgSsReserved[2]
Definition: compat.h:742
#define ObDereferenceObject
Definition: obfuncs.h:203
FORCEINLINE VOID PspRunCreateProcessNotifyRoutines(IN PEPROCESS CurrentProcess, IN BOOLEAN Create)
Definition: ps_x.h:62
#define PSF_PROCESS_DELETE_BIT
Definition: pstypes.h:276
_In_opt_ PFILE_OBJECT _In_opt_ PETHREAD Thread
Definition: fltkernel.h:2652
ULONG BreakOnTermination
Definition: pstypes.h:1184
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
VOID NTAPI PspDeleteLdt(PEPROCESS Process)
Definition: psldt.c:19
HANDLE UniqueThread
Definition: compat.h:685
NTSTATUS NTAPI PspTerminateProcess(IN PEPROCESS Process, IN NTSTATUS ExitStatus)
Definition: kill.c:82
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
CHAR Message[80]
Definition: alive.c:5
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
PETHREAD NTAPI PsGetNextProcessThread(IN PEPROCESS Process, IN PETHREAD Thread OPTIONAL)
Definition: process.c:75
VOID NTAPI PopCleanupPowerState(IN PPOWER_STATE PowerState)
Definition: power.c:164
VOID NTAPI DbgkExitProcess(IN NTSTATUS ExitStatus)
Definition: dbgkutil.c:304
struct _SINGLE_LIST_ENTRY * Next
Definition: ntbasedef.h:629
static const char * ImageName
Definition: image.c:34
NTSTATUS NTAPI ObCloseHandle(IN HANDLE Handle, IN KPROCESSOR_MODE AccessMode)
Definition: obhandle.c:3379
POBJECT_TYPE PsThreadType
Definition: thread.c:20
VOID NTAPI PspExitThread(IN NTSTATUS ExitStatus)
Definition: kill.c:453
PORT_MESSAGE h
Definition: lpctypes.h:269
VOID NTAPI PspExitApcRundown(IN PKAPC Apc)
Definition: kill.c:160
ULONG CrossThreadFlags
Definition: pstypes.h:1194
NTSTATUS NTAPI DbgkClearProcessDebugObject(IN PEPROCESS Process, IN PDEBUG_OBJECT SourceDebugObject OPTIONAL)
Definition: dbgkobj.c:1410
#define PspSetCrossThreadFlag(Thread, Flag)
Definition: ps_x.h:25
#define KeEnterCriticalRegion()
Definition: ke_x.h:88
Definition: ketypes.h:535
#define InterlockedOr
Definition: interlocked.h:224
PEPROCESS NTAPI PsGetNextProcess(IN PEPROCESS OldProcess OPTIONAL)
Definition: process.c:128
Definition: typedefs.h:119
PACCESS_TOKEN NTAPI PsReferencePrimaryToken(PEPROCESS Process)
Definition: security.c:440
#define PASSIVE_LEVEL
Definition: env_spec_w32.h:693
VOID NTAPI ObDereferenceDeviceMap(IN PEPROCESS Process)
Definition: devicemap.c:456
VOID NTAPI PspDeleteProcessSecurity(IN PEPROCESS Process)
Definition: security.c:30
ULONG SystemThread
Definition: pstypes.h:1182
#define InterlockedExchange
Definition: armddk.h:54
PETHREAD LastThread
Definition: pinsup.c:109
_In_opt_ PVOID _In_opt_ PVOID _In_opt_ PVOID SystemArgument2
Definition: ketypes.h:675
VOID NTAPI PspDeleteThreadSecurity(IN PETHREAD Thread)
Definition: security.c:46
PVOID StackBase
Definition: ketypes.h:1606
VOID NTAPI PspRemoveProcessFromJob(IN PEPROCESS Process, IN PEJOB Job)
Definition: job.c:138
ULONG_PTR SIZE_T
Definition: typedefs.h:80
#define STATUS_CANT_TERMINATE_SELF
Definition: ntstatus.h:455
VOID NTAPI ObClearProcessHandleTable(IN PEPROCESS Process)
Definition: obhandle.c:2027
Definition: compat.h:694
FORCEINLINE VOID PspRunCreateThreadNotifyRoutines(IN PETHREAD CurrentThread, IN BOOLEAN Create)
Definition: ps_x.h:40
VOID NTAPI PspExitNormalApc(IN PVOID NormalContext, IN PVOID SystemArgument1, IN PVOID SystemArgument2)
Definition: kill.c:950
NTSTATUS ExitStatus
Definition: pstypes.h:1113
#define KeLeaveCriticalRegion()
Definition: ke_x.h:119
#define PROCESS_TERMINATE
Definition: pstypes.h:157
#define TAG_TERMINATE_APC
Definition: tag.h:132
_In_ WDFIOTARGET _In_ _Strict_type_match_ WDF_IO_TARGET_SENT_IO_ACTION Action
Definition: wdfiotarget.h:506
VOID NTAPI KeUnstackDetachProcess(IN PRKAPC_STATE ApcState)
Definition: procobj.c:756
#define OBJECT_HEADER_TO_CREATOR_INFO(h)
Definition: obtypes.h:126
KGUARDED_MUTEX PspActiveProcessMutex
Definition: process.c:23
NTSTATUS NTAPI PsTerminateSystemThread(IN NTSTATUS ExitStatus)
Definition: kill.c:1148
LIST_ENTRY PspReaperListHead
Definition: kill.c:19
#define STATUS_NO_MEMORY
Definition: ntstatus.h:260
_In_ NTSTATUS ExitStatus
Definition: psfuncs.h:859
_Out_ PKAPC_STATE ApcState
Definition: mm.h:1727
#define NULL
Definition: types.h:112
NTSTATUS NTAPI PsTerminateProcess(IN PEPROCESS Process, IN NTSTATUS ExitStatus)
Definition: kill.c:129
FORCEINLINE VOID PspRunLegoRoutine(IN PKTHREAD Thread)
Definition: ps_x.h:103
VOID FASTCALL KeReleaseGuardedMutex(IN OUT PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:53
BOOLEAN NTAPI KeInsertQueueApc(IN PKAPC Apc, IN PVOID SystemArgument1, IN PVOID SystemArgument2, IN KPRIORITY PriorityBoost)
Definition: apc.c:735
PVOID Teb
Definition: ketypes.h:1747
#define THREAD_TERMINATE
Definition: nt_native.h:1336
VOID NTAPI PspDeleteProcess(IN PVOID ObjectBody)
Definition: kill.c:256
VOID FASTCALL ObFastDereferenceObject(IN PEX_FAST_REF FastRef, IN PVOID Object)
Definition: obref.c:167
#define MEM_RELEASE
Definition: nt_native.h:1316
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:219
#define PORT_ALL_ACCESS
Definition: lpctypes.h:47
PVOID LegoData
Definition: ketypes.h:1937
#define OUT
Definition: typedefs.h:40
#define PspSetProcessFlag(Process, Flag)
Definition: ps_x.h:33
VOID NTAPI SeAuditProcessExit(_In_ PEPROCESS Process)
Peforms a security auditing against a process that is about to be terminated.
Definition: audit.c:77
ULONG NTAPI KeForceResumeThread(IN PKTHREAD Thread)
Definition: thrdobj.c:276
PVOID Win32Thread
Definition: ketypes.h:1806
unsigned int ULONG
Definition: retypes.h:1
#define PSTRACE(x, fmt,...)
Definition: ps.h:57
struct _ETHREAD * PETHREAD
Definition: nt_native.h:29
UCHAR ApcStateIndex
Definition: ketypes.h:1882
#define TAG_SEPA
Definition: tag.h:153
VOID NTAPI LpcExitThread(IN PETHREAD Thread)
Definition: close.c:19
#define STATUS_SUCCESS
Definition: shellext.h:65
NTSTATUS NTAPI NtRegisterThreadTerminatePort(IN HANDLE PortHandle)
Definition: kill.c:1345
ULONG ApcQueueable
Definition: ketypes.h:1651
VOID(NTAPI * PKNORMAL_ROUTINE)(IN PVOID NormalContext OPTIONAL, IN PVOID SystemArgument1 OPTIONAL, IN PVOID SystemArgument2 OPTIONAL)
Definition: ketypes.h:684
VOID NTAPI KeLowerIrql(KIRQL NewIrql)
Definition: spinlock.c:39
VOID NTAPI PspReapRoutine(IN PVOID Context)
Definition: kill.c:170
VOID NTAPI ExpCheckPoolAllocation(PVOID P, POOL_TYPE PoolType, ULONG Tag)
Definition: expool.c:296
_In_ HANDLE ProcessHandle
Definition: mmfuncs.h:403
VOID NTAPI PsReturnProcessNonPagedPoolQuota(_In_ PEPROCESS Process, _In_ SIZE_T Amount)
Returns the non paged quota pool that the process was taking up.
Definition: quota.c:938
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
signed int * PLONG
Definition: retypes.h:5
VOID NTAPI MmDeleteProcessAddressSpace(IN PEPROCESS Process)
Definition: procsup.c:1361
PVOID InitialStack
Definition: ketypes.h:1604
VOID NTAPI PsExitSpecialApc(IN PKAPC Apc, IN OUT PKNORMAL_ROUTINE *NormalRoutine, IN OUT PVOID *NormalContext, IN OUT PVOID *SystemArgument1, IN OUT PVOID *SystemArgument2)
Definition: kill.c:925
POBJECT_TYPE PsProcessType
Definition: process.c:20
NTSTATUS NTAPI PspTerminateThreadByPointer(IN PETHREAD Thread, IN NTSTATUS ExitStatus, IN BOOLEAN bSelf)
Definition: kill.c:991
base of all file and directory entries
Definition: entries.h:82
VOID NTAPI DbgkExitThread(IN NTSTATUS ExitStatus)
Definition: dbgkutil.c:340
VOID NTAPI KeBugCheckEx(_In_ ULONG BugCheckCode, _In_ ULONG_PTR BugCheckParameter1, _In_ ULONG_PTR BugCheckParameter2, _In_ ULONG_PTR BugCheckParameter3, _In_ ULONG_PTR BugCheckParameter4)
Definition: rtlcompat.c:108
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
#define STATUS_SYSTEM_SHUTDOWN
Definition: ntstatus.h:855
BOOLEAN NTAPI SeDetailedAuditingWithToken(_In_ PTOKEN Token)
Peforms a detailed security auditing with an access token.
Definition: audit.c:34
struct _KAPC * PKAPC
#define PAGED_CODE()
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68