ReactOS 0.4.17-dev-1133-gc25e4fd
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
21LARGE_INTEGER ShortTime = {{-10 * 100 * 1000, -1}};
22
23/* PRIVATE FUNCTIONS *********************************************************/
24
25VOID
28 IN PVOID ProcessOrThread,
29 IN PCHAR ImageName)
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 debugger 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':
52 /* Fall through */
53
54 /* Ignore: Handle it */
55 case 'I': case 'i':
56 Handled = TRUE;
57
58 /* Unrecognized: Prompt again */
59 default:
60 break;
61 }
62 } while (!Handled);
63 }
64
65 /* Did we ultimately handle this? */
66 if (!Handled)
67 {
68 /* We didn't, bugcheck */
69 KeBugCheckEx(CRITICAL_OBJECT_TERMINATION,
70 ((PKPROCESS)ProcessOrThread)->Header.Type,
71 (ULONG_PTR)ProcessOrThread,
72 (ULONG_PTR)ImageName,
74 }
75}
76
81{
84 PAGED_CODE();
86 "Process: %p ExitStatus: %d\n", Process, ExitStatus);
88
89 /* Check if this is a Critical Process */
90 if (Process->BreakOnTermination)
91 {
92 /* Break to debugger */
93 PspCatchCriticalBreak("Terminating critical process 0x%p (%s)\n",
94 Process,
95 Process->ImageFileName);
96 }
97
98 /* Set the delete flag */
100
101 /* Get the first thread */
103 while (Thread)
104 {
105 /* Kill it */
108
109 /* We had at least one thread, so termination is OK */
111 }
112
113 /* Check if there was nothing to terminate or if we have a debug port */
114 if ((Status == STATUS_NOTHING_TO_TERMINATE) || (Process->DebugPort))
115 {
116 /* Clear the handle table anyway */
118 }
119
120 /* Return status */
121 return Status;
122}
123
125NTAPI
128{
129 /* Call the internal API */
131}
132
133VOID
134NTAPI
136{
138
139 /* Loop every process */
141 while (Process)
142 {
143 /* Make sure this isn't the idle or initial process */
145 {
146 /* Kill it */
148 }
149
150 /* Get the next process */
152 }
153}
154
155VOID
156NTAPI
158{
159 PAGED_CODE();
160
161 /* Free the APC */
162 ExFreePool(Apc);
163}
164
165VOID
166NTAPI
168{
169 PSINGLE_LIST_ENTRY NextEntry;
171 PSTRACE(PS_KILL_DEBUG, "Context: %p\n", Context);
172
173 /* Start main loop */
174 do
175 {
176 /* Write magic value and return the next entry to process */
178 (PVOID)1);
179 ASSERT((NextEntry != NULL) && (NextEntry != (PVOID)1));
180
181 /* Start inner loop */
182 do
183 {
184 /* Get the first Thread Entry */
185 Thread = CONTAINING_RECORD(NextEntry, ETHREAD, ReaperLink);
186
187 /* Delete this entry's kernel stack */
189 Thread->Tcb.LargeStack);
191
192 /* Move to the next entry */
193 NextEntry = NextEntry->Next;
194
195 /* Dereference this thread */
197 } while ((NextEntry != NULL) && (NextEntry != (PVOID)1));
198
199 /* Remove magic value, keep looping if it got changed */
201 NULL,
202 (PVOID)1) != (PVOID)1);
203}
204
205#if DBG
206VOID
207NTAPI
208PspCheckProcessList(VOID)
209{
211
213 DbgPrint("# checking PsActiveProcessHead @ %p\n", &PsActiveProcessHead);
216 Entry = Entry->Flink)
217 {
218 PEPROCESS Process = CONTAINING_RECORD(Entry, EPROCESS, ActiveProcessLinks);
220 PVOID Info, HeaderLocation;
221
222 /* Get the header and assume this is what we'll free */
224 HeaderLocation = Header;
225
226 /* To find the header, walk backwards from how we allocated */
228 {
229 HeaderLocation = Info;
230 }
232 {
233 HeaderLocation = Info;
234 }
236 {
237 HeaderLocation = Info;
238 }
240 {
241 HeaderLocation = Info;
242 }
243
244 ExpCheckPoolAllocation(HeaderLocation, NonPagedPool, 'corP');
245 }
246
248}
249#endif
250
251VOID
252NTAPI
254{
255 PEPROCESS Process = (PEPROCESS)ObjectBody;
257 PAGED_CODE();
258 PSTRACE(PS_KILL_DEBUG, "ObjectBody: %p\n", ObjectBody);
260
261 /* Check if it has an Active Process Link */
262 if (Process->ActiveProcessLinks.Flink)
263 {
264 /* Remove it from the Active List */
266 RemoveEntryList(&Process->ActiveProcessLinks);
267 Process->ActiveProcessLinks.Flink = NULL;
268 Process->ActiveProcessLinks.Blink = NULL;
270 }
271
272 /* Check for Auditing information */
273 if (Process->SeAuditProcessCreationInfo.ImageFileName)
274 {
275 /* Free it */
276 ExFreePoolWithTag(Process->SeAuditProcessCreationInfo.ImageFileName,
277 TAG_SEPA);
278 Process->SeAuditProcessCreationInfo.ImageFileName = NULL;
279 }
280
281 /* Check if we have a job */
282 if (Process->Job)
283 {
284 /* Remove the process from the job */
286
287 /* Dereference it */
289 Process->Job = NULL;
290 }
291
292 /* Increase the stack count */
293 Process->Pcb.StackCount++;
294
295 /* Check if we have a debug port */
296 if (Process->DebugPort)
297 {
298 /* Deference the Debug Port */
299 ObDereferenceObject(Process->DebugPort);
300 Process->DebugPort = NULL;
301 }
302
303 /* Check if we have an exception port */
304 if (Process->ExceptionPort)
305 {
306 /* Deference the Exception Port */
307 ObDereferenceObject(Process->ExceptionPort);
308 Process->ExceptionPort = NULL;
309 }
310
311 /* Check if we have a section object */
312 if (Process->SectionObject)
313 {
314 /* Deference the Section Object */
315 ObDereferenceObject(Process->SectionObject);
316 Process->SectionObject = NULL;
317 }
318
319#if defined(_X86_)
320 /* Clean Ldt and Vdm objects */
323#endif
324
325 /* Delete the Object Table */
326 if (Process->ObjectTable)
327 {
328 /* Attach to the process */
330
331 /* Kill the Object Info */
333
334 /* Detach */
336 }
337
338 /* Check if we have an address space, and clean it */
339 if (Process->HasAddressSpace)
340 {
341 /* Attach to the process */
343
344 /* Clean the Address Space */
346
347 /* Detach */
349
350 /* Completely delete the Address Space */
352 }
353
354 /* See if we have a PID */
355 if (Process->UniqueProcessId)
356 {
357 /* Delete the PID */
358 if (!(ExDestroyHandle(PspCidTable, Process->UniqueProcessId, NULL)))
359 {
360 /* Something wrong happened, bugcheck */
361 KeBugCheck(CID_HANDLE_DELETION);
362 }
363 }
364
365 /* Cleanup security information */
367
368 /* Check if we have kept information on the Working Set */
369 if (Process->WorkingSetWatch)
370 {
371 /* Free it */
372 ExFreePool(Process->WorkingSetWatch);
373
374 /* And return the quota it was taking up */
376 }
377
378 /* Dereference the Device Map */
380
381#if defined(_WIN64) && defined(BUILD_WOW64_ENABLED)
382 /* Check if this is a WOW64 process */
383 if (Process->Wow64Process && !IS_WOW64_PROCESS_INITIALIZING(Process))
384 {
385 /* Free WOW64_PROCESS structure */
386 ExFreePoolWithTag(Process->Wow64Process, TAG_PS_WOW64);
387
389 }
390#endif
391
392 /*
393 * Dereference the quota block, the function
394 * will invoke a quota block cleanup if the
395 * block itself is no longer used by anybody.
396 */
398}
399
400VOID
401NTAPI
403{
404 PETHREAD Thread = (PETHREAD)ObjectBody;
405 PEPROCESS Process = Thread->ThreadsProcess;
406 PAGED_CODE();
407 PSTRACE(PS_KILL_DEBUG, "ObjectBody: %p\n", ObjectBody);
410
411 /* Check if we have a stack */
413 {
414 /* Release it */
416 Thread->Tcb.LargeStack);
417 }
418
419 /* Check if we have a CID Handle */
421 {
422 /* Delete the CID Handle */
424 {
425 /* Something wrong happened, bugcheck */
426 KeBugCheck(CID_HANDLE_DELETION);
427 }
428 }
429
430 /* Cleanup impersonation information */
432
433 /* Free the thread name if set */
434 if (Thread->ThreadName)
435 {
438 }
439
440 /* Make sure the thread was inserted, before continuing */
441 if (!Process)
442 return;
443
444 /* Check if the thread list is valid */
446 {
447 /* Lock the thread's process */
449 ExAcquirePushLockExclusive(&Process->ProcessLock);
450
451 /* Remove us from the list */
453
454 /* Release the lock */
455 ExReleasePushLockExclusive(&Process->ProcessLock);
457 }
458
459 /* Dereference the Process */
461}
462
463/*
464 * FUNCTION: Terminates the current thread
465 * See "Windows Internals" - Chapter 13, Page 50-53
466 */
467VOID
468NTAPI
470{
471 CLIENT_DIED_MSG TerminationMsg;
473 PTEB Teb;
474 PEPROCESS CurrentProcess;
475 PETHREAD Thread, OtherThread, PreviousThread = NULL;
476 PVOID DeallocationStack;
477 SIZE_T Dummy;
478 BOOLEAN Last = FALSE;
479 PTERMINATION_PORT TerminationPort, NextPort;
480 PLIST_ENTRY FirstEntry, CurrentEntry;
481 PKAPC Apc;
482 PTOKEN PrimaryToken;
483 PAGED_CODE();
484 PSTRACE(PS_KILL_DEBUG, "ExitStatus: %d\n", ExitStatus);
485
486 /* Get the Current Thread and Process */
488 CurrentProcess = Thread->ThreadsProcess;
490
491 /* Can't terminate a thread if it attached another process */
493 {
494 /* Bugcheck */
495 KeBugCheckEx(INVALID_PROCESS_ATTACH_ATTEMPT,
496 (ULONG_PTR)CurrentProcess,
497 (ULONG_PTR)Thread->Tcb.ApcState.Process,
500 }
501
502 /* Lower to Passive Level */
504
505 /* Can't be a worker thread */
507 {
508 /* Bugcheck */
509 KeBugCheckEx(ACTIVE_EX_WORKER_THREAD_TERMINATION,
511 0,
512 0,
513 0);
514 }
515
516 /* Can't have pending APCs */
517 if (Thread->Tcb.CombinedApcDisable != 0)
518 {
519 /* Bugcheck */
520 KeBugCheckEx(KERNEL_APC_PENDING_DURING_EXIT,
521 0,
523 0,
524 1);
525 }
526
527 /* Lock the thread */
529
530 /* Cleanup the power state */
532
533 /* Call the WMI Callback for Threads */
534 //WmiTraceThread(Thread, NULL, FALSE);
535
536 /* Run Thread Notify Routines before we desintegrate the thread */
538
539 /* Lock the Process before we modify its thread entries */
541 ExAcquirePushLockExclusive(&CurrentProcess->ProcessLock);
542
543 /* Decrease the active thread count, and check if it's 0 */
544 if (!(--CurrentProcess->ActiveThreads))
545 {
546 /* Set the delete flag */
548
549 /* Remember we are last */
550 Last = TRUE;
551
552 /* Check if this termination is due to the thread dying */
554 {
555 /* Check if the last thread was pending */
556 if (CurrentProcess->ExitStatus == STATUS_PENDING)
557 {
558 /* Use the last exit status */
559 CurrentProcess->ExitStatus = CurrentProcess->
560 LastThreadExitStatus;
561 }
562 }
563 else
564 {
565 /* Just a normal exit, write the code */
566 CurrentProcess->ExitStatus = ExitStatus;
567 }
568
569 /* Loop all the current threads */
570 FirstEntry = &CurrentProcess->ThreadListHead;
571 CurrentEntry = FirstEntry->Flink;
572 while (FirstEntry != CurrentEntry)
573 {
574 /* Get the thread on the list */
575 OtherThread = CONTAINING_RECORD(CurrentEntry,
576 ETHREAD,
577 ThreadListEntry);
578
579 /* Check if it's a thread that's still alive */
580 if ((OtherThread != Thread) &&
581 !(KeReadStateThread(&OtherThread->Tcb)) &&
582 (ObReferenceObjectSafe(OtherThread)))
583 {
584 /* It's a live thread and we referenced it, unlock process */
585 ExReleasePushLockExclusive(&CurrentProcess->ProcessLock);
587
588 /* Wait on the thread */
589 KeWaitForSingleObject(OtherThread,
590 Executive,
592 FALSE,
593 NULL);
594
595 /* Check if we had a previous thread to dereference */
596 if (PreviousThread) ObDereferenceObject(PreviousThread);
597
598 /* Remember the thread and re-lock the process */
599 PreviousThread = OtherThread;
601 ExAcquirePushLockExclusive(&CurrentProcess->ProcessLock);
602 }
603
604 /* Go to the next thread */
605 CurrentEntry = CurrentEntry->Flink;
606 }
607 }
609 {
610 /* Write down the exit status of the last thread to get killed */
611 CurrentProcess->LastThreadExitStatus = ExitStatus;
612 }
613
614 /* Unlock the Process */
615 ExReleasePushLockExclusive(&CurrentProcess->ProcessLock);
617
618 /* Check if we had a previous thread to dereference */
619 if (PreviousThread) ObDereferenceObject(PreviousThread);
620
621 /* Check if the process has a debug port and if this is a user thread */
622 if ((CurrentProcess->DebugPort) && !(Thread->SystemThread))
623 {
624 /* Notify the Debug API. */
625 Last ? DbgkExitProcess(CurrentProcess->ExitStatus) :
627 }
628
629 /* Check if this is a Critical Thread */
631 {
632 /* Break to debugger */
633 PspCatchCriticalBreak("Critical thread 0x%p (in %s) exited\n",
634 Thread,
635 CurrentProcess->ImageFileName);
636 }
637
638 /* Check if it's the last thread and this is a Critical Process */
639 if ((Last) && (CurrentProcess->BreakOnTermination))
640 {
641 /* Check if a debugger is here to handle this */
643 {
644 /* Break to debugger */
645 PspCatchCriticalBreak("Critical process 0x%p (%s) exited\n",
646 CurrentProcess,
647 CurrentProcess->ImageFileName);
648 }
649 else
650 {
651 /* Bugcheck, we can't allow this */
652 KeBugCheckEx(CRITICAL_PROCESS_DIED,
653 (ULONG_PTR)CurrentProcess,
654 0,
655 0,
656 0);
657 }
658 }
659
660 /* Sanity check */
662
663 /* Process the Termination Ports */
664 TerminationPort = Thread->TerminationPort;
665 if (TerminationPort)
666 {
667 /* Setup the message header */
668 TerminationMsg.h.u2.ZeroInit = 0;
669 TerminationMsg.h.u2.s2.Type = LPC_CLIENT_DIED;
670 TerminationMsg.h.u1.s1.TotalLength = sizeof(TerminationMsg);
671 TerminationMsg.h.u1.s1.DataLength = sizeof(TerminationMsg) -
672 sizeof(PORT_MESSAGE);
673
674 /* Loop each port */
675 do
676 {
677 /* Save the Create Time */
678 TerminationMsg.CreateTime = Thread->CreateTime;
679
680 /* Loop trying to send message */
681 while (TRUE)
682 {
683 /* Send the LPC Message */
684 Status = LpcRequestPort(TerminationPort->Port,
685 &TerminationMsg.h);
686 if ((Status == STATUS_NO_MEMORY) ||
688 {
689 /* Wait a bit and try again */
691 continue;
692 }
693 break;
694 }
695
696 /* Dereference this LPC Port */
697 ObDereferenceObject(TerminationPort->Port);
698
699 /* Move to the next one */
700 NextPort = TerminationPort->Next;
701
702 /* Free the Termination Port Object */
703 ExFreePoolWithTag(TerminationPort, '=TsP');
704
705 /* Keep looping as long as there is a port */
706 TerminationPort = NextPort;
707 } while (TerminationPort);
708 }
710 (Thread->DeadThread)) ||
711 !(Thread->DeadThread))
712 {
713 /*
714 * This case is special and deserves some extra comments. What
715 * basically happens here is that this thread doesn't have a termination
716 * port, which means that it died before being fully created. Since we
717 * still have to notify an LPC Server, we'll use the exception port,
718 * which we know exists. However, we need to know how far the thread
719 * actually got created. We have three possibilities:
720 *
721 * - NtCreateThread returned an error really early: DeadThread is set.
722 * - NtCreateThread managed to create the thread: DeadThread is off.
723 * - NtCreateThread was creating the thread (with DeadThread set,
724 * but the thread got killed prematurely: STATUS_THREAD_IS_TERMINATING
725 * is our exit code.)
726 *
727 * For the 2 & 3rd scenarios, the thread has been created far enough to
728 * warrant notification to the LPC Server.
729 */
730
731 /* Setup the message header */
732 TerminationMsg.h.u2.ZeroInit = 0;
733 TerminationMsg.h.u2.s2.Type = LPC_CLIENT_DIED;
734 TerminationMsg.h.u1.s1.TotalLength = sizeof(TerminationMsg);
735 TerminationMsg.h.u1.s1.DataLength = sizeof(TerminationMsg) -
736 sizeof(PORT_MESSAGE);
737
738 /* Make sure the process has an exception port */
739 if (CurrentProcess->ExceptionPort)
740 {
741 /* Save the Create Time */
742 TerminationMsg.CreateTime = Thread->CreateTime;
743
744 /* Loop trying to send message */
745 while (TRUE)
746 {
747 /* Send the LPC Message */
748 Status = LpcRequestPort(CurrentProcess->ExceptionPort,
749 &TerminationMsg.h);
750 if ((Status == STATUS_NO_MEMORY) ||
752 {
753 /* Wait a bit and try again */
755 continue;
756 }
757 break;
758 }
759 }
760 }
761
762 /* Rundown Win32 Thread if there is one */
765
766 /* If we are the last thread and have a W32 Process */
767 if ((Last) && (CurrentProcess->Win32Process))
768 {
769 /* Run it down too */
770 PspW32ProcessCallout(CurrentProcess, FALSE);
771 }
772
773 /* Make sure Stack Swap is enabled */
775 {
776 /* Stack swap really shouldn't be disabled during exit! */
777 KeBugCheckEx(KERNEL_STACK_LOCKED_AT_EXIT, 0, 0, 0, 0);
778 }
779
780 /* Cancel I/O for the thread. */
782
783 /* Rundown Timers */
785
786 /* FIXME: Rundown Registry Notifications (NtChangeNotify)
787 CmNotifyRunDown(Thread); */
788
789 /* Rundown Mutexes */
791
792 /* Check if we have a TEB */
793 Teb = Thread->Tcb.Teb;
794 if (Teb)
795 {
796 /* Check if the thread is still alive */
797 if (!Thread->DeadThread)
798 {
799#if (NTDDI_VERSION < NTDDI_LONGHORN)
800 /*
801 * See Geoff's comment on FreeStackOnTermination here.
802 * https://www.geoffchappell.com/studies/windows/km/ntoskrnl/inc/api/pebteb/teb/index.htm
803 */
804 /* Check if we need to free its stack */
805 if (Teb->FreeStackOnTermination)
806 {
807 /* Set the TEB's Deallocation Stack as the Base Address */
808 Dummy = 0;
809 DeallocationStack = Teb->DeallocationStack;
810
811 /* Free the Thread's Stack */
812 ZwFreeVirtualMemory(NtCurrentProcess(),
813 &DeallocationStack,
814 &Dummy,
816 }
817#endif
818 /* Free the debug handle */
819 if (Teb->DbgSsReserved[1]) ObCloseHandle(Teb->DbgSsReserved[1],
820 UserMode);
821 }
822
823 /* Decommit the TEB */
824 MmDeleteTeb(CurrentProcess, Teb);
825 Thread->Tcb.Teb = NULL;
826 }
827
828 /* Free LPC Data */
830
831 /* Save the exit status and exit time */
834
835 /* Sanity check */
837
838 /* Check if this is the final thread or not */
839 if (Last)
840 {
841 /* Set the process exit time */
842 CurrentProcess->ExitTime = Thread->ExitTime;
843
844 /* Exit the process */
845 PspExitProcess(TRUE, CurrentProcess);
846
847 /* Get the process token and check if we need to audit */
848 PrimaryToken = PsReferencePrimaryToken(CurrentProcess);
849 if (SeDetailedAuditingWithToken(PrimaryToken))
850 {
851 /* Audit the exit */
852 SeAuditProcessExit(CurrentProcess);
853 }
854
855 /* Dereference the process token */
856 ObFastDereferenceObject(&CurrentProcess->Token, PrimaryToken);
857
858 /* Check if this is a VDM Process and rundown the VDM DPCs if so */
859 if (CurrentProcess->VdmObjects) { /* VdmRundownDpcs(CurrentProcess); */ }
860
861 /* Kill the process in the Object Manager */
862 ObKillProcess(CurrentProcess);
863
864 /* Check if we have a section object */
865 if (CurrentProcess->SectionObject)
866 {
867 /* Dereference and clear the Section Object */
868 ObDereferenceObject(CurrentProcess->SectionObject);
869 CurrentProcess->SectionObject = NULL;
870 }
871
872 /* Check if the process is part of a job */
873 if (CurrentProcess->Job)
874 {
875 /* Remove the process from the job */
876 PspExitProcessFromJob(CurrentProcess);
877 }
878 }
879
880 /* Disable APCs */
882
883 /* Disable APC queueing, force a resumption */
886
887 /* Re-enable APCs */
889
890 /* Flush the User APCs */
891 FirstEntry = KeFlushQueueApc(&Thread->Tcb, UserMode);
892 if (FirstEntry)
893 {
894 /* Start with the first entry */
895 CurrentEntry = FirstEntry;
896 do
897 {
898 /* Get the APC */
899 Apc = CONTAINING_RECORD(CurrentEntry, KAPC, ApcListEntry);
900
901 /* Move to the next one */
902 CurrentEntry = CurrentEntry->Flink;
903
904 /* Rundown the APC or de-allocate it */
905 if (Apc->RundownRoutine)
906 {
907 /* Call its own routine */
908 Apc->RundownRoutine(Apc);
909 }
910 else
911 {
912 /* Do it ourselves */
913 ExFreePool(Apc);
914 }
915 }
916 while (CurrentEntry != FirstEntry);
917 }
918
919 /* Clean address space if this was the last thread */
920 if (Last) MmCleanProcessAddressSpace(CurrentProcess);
921
922 /* Call the Lego routine */
924
925 /* Flush the APC queue, which should be empty */
926 FirstEntry = KeFlushQueueApc(&Thread->Tcb, KernelMode);
927 if ((FirstEntry) || (Thread->Tcb.CombinedApcDisable != 0))
928 {
929 /* Bugcheck time */
930 KeBugCheckEx(KERNEL_APC_PENDING_DURING_EXIT,
931 (ULONG_PTR)FirstEntry,
934 0);
935 }
936
937 /* Signal the process if this was the last thread */
938 if (Last) KeSetProcess(&CurrentProcess->Pcb, 0, FALSE);
939
940 /* Terminate the Thread from the Scheduler */
942}
943
944VOID
945NTAPI
947 IN OUT PKNORMAL_ROUTINE* NormalRoutine,
948 IN OUT PVOID* NormalContext,
951{
953 PAGED_CODE();
955 "Apc: %p SystemArgument2: %p\n", Apc, SystemArgument2);
956
957 /* Don't do anything unless we are in User-Mode */
958 if (Apc->SystemArgument2)
959 {
960 /* Free the APC */
961 Status = PtrToUlong(Apc->NormalContext);
963
964 /* Terminate the Thread */
966 }
967}
968
969VOID
970NTAPI
974{
977 PAGED_CODE();
978 PSTRACE(PS_KILL_DEBUG, "SystemArgument2: %p\n", SystemArgument2);
979
980 /* This should never happen */
982
983 /* If we're here, this is not a System Thread, so kill it from User-Mode */
984 KeInitializeApc(Apc,
985 &Thread->Tcb,
990 UserMode,
991 NormalContext);
992
993 /* Now insert the APC with the User-Mode Flag */
994 if (!(KeInsertQueueApc(Apc,
995 Apc,
997 2)))
998 {
999 /* Failed to insert, free the APC */
1000 PspExitApcRundown(Apc);
1001 }
1002
1003 /* Set the APC Pending flag */
1004 Thread->Tcb.ApcState.UserApcPending = TRUE;
1005}
1006
1007/*
1008 * See "Windows Internals" - Chapter 13, Page 49
1009 */
1011NTAPI
1014 IN BOOLEAN bSelf)
1015{
1016 PKAPC Apc;
1018 ULONG Flags;
1019 PAGED_CODE();
1020 PSTRACE(PS_KILL_DEBUG, "Thread: %p ExitStatus: %d\n", Thread, ExitStatus);
1022
1023 /* Check if this is a Critical Thread, and Bugcheck */
1025 {
1026 /* Break to debugger */
1027 PspCatchCriticalBreak("Terminating critical thread 0x%p (in %s)\n",
1028 Thread,
1029 Thread->ThreadsProcess->ImageFileName);
1030 }
1031
1032 /* Check if we are already inside the thread */
1033 if ((bSelf) || (PsGetCurrentThread() == Thread))
1034 {
1035 /* This should only happen at passive */
1037
1038 /* Mark it as terminated */
1040
1041 /* Directly terminate the thread */
1043 }
1044
1045 /* This shouldn't be a system thread */
1047
1048 /* Allocate the APC */
1050 if (!Apc) return STATUS_INSUFFICIENT_RESOURCES;
1051
1052 /* Set the Terminated Flag */
1054
1055 /* Set it, and check if it was already set while we were running */
1058 {
1059 /* Initialize a Kernel Mode APC to Kill the Thread */
1060 KeInitializeApc(Apc,
1061 &Thread->Tcb,
1066 KernelMode,
1068
1069 /* Insert it into the APC Queue */
1070 if (!KeInsertQueueApc(Apc, Apc, NULL, 2))
1071 {
1072 /* The APC was already in the queue, fail */
1074 }
1075 else
1076 {
1077 /* Forcefully resume the thread and return */
1079 return Status;
1080 }
1081 }
1082
1083 /* We failed, free the APC */
1085
1086 /* Return Status */
1087 return Status;
1088}
1089
1090BOOLEAN
1091NTAPI
1093{
1094 return Process->Flags & PSF_PROCESS_EXITING_BIT;
1095}
1096
1097VOID
1098NTAPI
1101{
1102 ULONG Actual;
1103 PAGED_CODE();
1105 "LastThread: %u Process: %p\n", LastThread, Process);
1107
1108 /* Set Process Exit flag */
1110
1111 /* Check if we are the last thread */
1112 if (LastThread)
1113 {
1114 /* Notify the WMI Process Callback */
1115 //WmiTraceProcess(Process, FALSE);
1116
1117 /* Run the Notification Routines */
1119 }
1120
1121 /* Cleanup the power state */
1122 PopCleanupPowerState((PPOWER_STATE)&Process->Pcb.PowerState);
1123
1124 /* Clear the security port */
1125 if (!Process->SecurityPort)
1126 {
1127 /* So we don't double-dereference */
1128 Process->SecurityPort = (PVOID)1;
1129 }
1130 else if (Process->SecurityPort != (PVOID)1)
1131 {
1132 /* Dereference it */
1133 ObDereferenceObject(Process->SecurityPort);
1134 Process->SecurityPort = (PVOID)1;
1135 }
1136
1137 /* Check if we are the last thread */
1138 if (LastThread)
1139 {
1140 /* Check if we have to set the Timer Resolution */
1141 if (Process->SetTimerResolution)
1142 {
1143 /* Set it to default */
1145 }
1146
1147 if (Process->Job)
1148 {
1150
1151 /* Check if we are part of a job that has a completion port
1152 and do I/O completion if needed */
1153 if (Process->Job->CompletionPort &&
1155 {
1158 Process->UniqueProcessId,
1159 FALSE);
1160 }
1161
1163 }
1164
1165 /* FIXME: Notify the Prefetcher */
1166 }
1167 else
1168 {
1169 /* Clear process' address space here */
1171 }
1172}
1173
1174/* PUBLIC FUNCTIONS **********************************************************/
1175
1176/*
1177 * @implemented
1178 */
1180NTAPI
1182{
1184
1185 /* Make sure this is a system thread */
1187
1188 /* Terminate it for real */
1190}
1191
1192/*
1193 * @implemented
1194 */
1196NTAPI
1199{
1201 PEPROCESS Process, CurrentProcess = PsGetCurrentProcess();
1202 PETHREAD Thread, CurrentThread = PsGetCurrentThread();
1203 BOOLEAN KillByHandle;
1204 PAGED_CODE();
1206 "ProcessHandle: %p ExitStatus: %d\n", ProcessHandle, ExitStatus);
1207
1208 /* Were we passed a process handle? */
1209 if (ProcessHandle)
1210 {
1211 /* Yes we were, use it */
1212 KillByHandle = TRUE;
1213 }
1214 else
1215 {
1216 /* We weren't... we assume this is suicide */
1217 KillByHandle = FALSE;
1219 }
1220
1221 /* Get the Process Object */
1226 (PVOID*)&Process,
1227 NULL);
1228 if (!NT_SUCCESS(Status)) return(Status);
1229
1230 /* Check if this is a Critical Process, and Bugcheck */
1231 if (Process->BreakOnTermination)
1232 {
1233 /* Break to debugger */
1234 PspCatchCriticalBreak("Terminating critical process 0x%p (%s)\n",
1235 Process,
1236 Process->ImageFileName);
1237 }
1238
1239 /* Lock the Process */
1240 if (!ExAcquireRundownProtection(&Process->RundownProtect))
1241 {
1242 /* Failed to lock, fail */
1245 }
1246
1247 /* Set the delete flag, unless the process is comitting suicide */
1249
1250 /* Get the first thread */
1253 if (Thread)
1254 {
1255 /* We know we have at least a thread */
1257
1258 /* Loop and kill the others */
1259 do
1260 {
1261 /* Ensure it's not ours*/
1262 if (Thread != CurrentThread)
1263 {
1264 /* Kill it */
1266 }
1267
1268 /* Move to the next thread */
1270 } while (Thread);
1271 }
1272
1273 /* Unlock the process */
1274 ExReleaseRundownProtection(&Process->RundownProtect);
1275
1276 /* Check if we are killing ourselves */
1277 if (Process == CurrentProcess)
1278 {
1279 /* Also make sure the caller gave us our handle */
1280 if (KillByHandle)
1281 {
1282 /* Dereference the process */
1284
1285 /* Terminate ourselves */
1287 }
1288 }
1290 {
1291 /* Disable debugging on this process */
1293 }
1294
1295 /* Check if there was nothing to terminate, or if we have a Debug Port */
1297 ((Process->DebugPort) && (KillByHandle)))
1298 {
1299 /* Clear the handle table */
1301
1302 /* Return status now */
1304 }
1305
1306 /* Decrease the reference count we added */
1308
1309 /* Return status */
1310 return Status;
1311}
1312
1314NTAPI
1317{
1319 PETHREAD CurrentThread = PsGetCurrentThread();
1321 PAGED_CODE();
1323 "ThreadHandle: %p ExitStatus: %d\n", ThreadHandle, ExitStatus);
1324
1325 /* Handle the special NULL case */
1326 if (!ThreadHandle)
1327 {
1328 /* Check if we're the only thread left */
1329 if (PsGetCurrentProcess()->ActiveThreads == 1)
1330 {
1331 /* This is invalid */
1333 }
1334
1335 /* Terminate us directly */
1336 goto TerminateSelf;
1337 }
1338 else if (ThreadHandle == NtCurrentThread())
1339 {
1340TerminateSelf:
1341 /* Terminate this thread */
1342 return PspTerminateThreadByPointer(CurrentThread,
1343 ExitStatus,
1344 TRUE);
1345 }
1346
1347 /* We are terminating another thread, get the Thread Object */
1348 Status = ObReferenceObjectByHandle(ThreadHandle,
1352 (PVOID*)&Thread,
1353 NULL);
1354 if (!NT_SUCCESS(Status)) return Status;
1355
1356 /* Check to see if we're running in the same thread */
1357 if (Thread != CurrentThread)
1358 {
1359 /* Terminate it */
1361
1362 /* Dereference the Thread and return */
1364 }
1365 else
1366 {
1367 /* Dereference the thread and terminate ourselves */
1369 goto TerminateSelf;
1370 }
1371
1372 /* Return status */
1373 return Status;
1374}
1375
1377NTAPI
1379{
1381 PTERMINATION_PORT TerminationPort;
1382 PVOID TerminationLpcPort;
1384 PAGED_CODE();
1385 PSTRACE(PS_KILL_DEBUG, "PortHandle: %p\n", PortHandle);
1386
1387 /* Get the Port */
1388 Status = ObReferenceObjectByHandle(PortHandle,
1392 &TerminationLpcPort,
1393 NULL);
1394 if (!NT_SUCCESS(Status)) return(Status);
1395
1396 /* Allocate the Port and make sure it suceeded */
1397 TerminationPort = ExAllocatePoolWithTag(NonPagedPool,
1398 sizeof(TERMINATION_PORT),
1399 '=TsP');
1400 if(TerminationPort)
1401 {
1402 /* Associate the Port */
1404 TerminationPort->Port = TerminationLpcPort;
1405 TerminationPort->Next = Thread->TerminationPort;
1406 Thread->TerminationPort = TerminationPort;
1407
1408 /* Return success */
1409 return STATUS_SUCCESS;
1410 }
1411
1412 /* Dereference and Fail */
1413 ObDereferenceObject(TerminationLpcPort);
1415}
#define PAGED_CODE()
#define VOID
Definition: acefi.h:82
unsigned char BOOLEAN
Definition: actypes.h:127
#define InterlockedExchange
Definition: armddk.h:54
LONG NTSTATUS
Definition: precomp.h:26
DECLSPEC_NORETURN VOID NTAPI KeBugCheckEx(IN ULONG BugCheckCode, IN ULONG_PTR BugCheckParameter1, IN ULONG_PTR BugCheckParameter2, IN ULONG_PTR BugCheckParameter3, IN ULONG_PTR BugCheckParameter4)
Definition: debug.c:485
DECLSPEC_NORETURN VOID NTAPI KeBugCheck(ULONG BugCheckCode)
Definition: bug.c:1434
Definition: Header.h:9
#define STATUS_NO_MEMORY
Definition: d3dkmdt.h:51
NTSTATUS NTAPI DbgkClearProcessDebugObject(IN PEPROCESS Process, IN PDEBUG_OBJECT SourceDebugObject OPTIONAL)
Definition: dbgkobj.c:1410
VOID NTAPI DbgkExitThread(IN NTSTATUS ExitStatus)
Definition: dbgkutil.c:340
VOID NTAPI DbgkExitProcess(IN NTSTATUS ExitStatus)
Definition: dbgkutil.c:304
_In_ D3DDDI_VIDEO_PRESENT_TARGET_ID _In_ ULONG _In_ ULONG Flags
Definition: dispmprt.h:245
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
static const WCHAR Message[]
Definition: register.c:74
#define ASSERT_IRQL_EQUAL(x)
Definition: debug.h:43
#define UlongToPtr(u)
Definition: config.h:106
#define PtrToUlong(u)
Definition: config.h:107
#define InterlockedExchangePointer(Target, Value)
Definition: dshow.h:45
#define RemoveEntryList(Entry)
Definition: env_spec_w32.h:986
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define PASSIVE_LEVEL
Definition: env_spec_w32.h:693
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
#define KeWaitForSingleObject(pEvt, foo, a, b, c)
Definition: env_spec_w32.h:478
#define KeLowerIrql(oldIrql)
Definition: env_spec_w32.h:602
#define KeQuerySystemTime(t)
Definition: env_spec_w32.h:570
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
#define NonPagedPool
Definition: env_spec_w32.h:307
#define KeDelayExecutionThread(mode, foo, t)
Definition: env_spec_w32.h:484
#define ExWaitForRundownProtectionRelease
Definition: ex.h:141
#define ExReleaseRundownProtection
Definition: ex.h:139
FORCEINLINE VOID ExAcquirePushLockExclusive(PEX_PUSH_LOCK PushLock)
Definition: ex.h:1039
FORCEINLINE VOID ExReleasePushLockExclusive(PEX_PUSH_LOCK PushLock)
Definition: ex.h:1255
#define ExAcquireRundownProtection
Definition: ex.h:138
#define FlagOn(_F, _SF)
Definition: ext2fs.h:179
_In_opt_ PFILE_OBJECT _In_opt_ PETHREAD Thread
Definition: fltkernel.h:2653
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:223
Status
Definition: gdiplustypes.h:24
VOID FASTCALL KeReleaseGuardedMutex(IN OUT PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:53
VOID FASTCALL KeAcquireGuardedMutex(IN PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:42
#define DbgPrint
Definition: hal.h:12
#define PROCESS_TERMINATE
Definition: pstypes.h:153
#define PSF_PROCESS_DELETE_BIT
Definition: pstypes.h:302
#define PSF_PROCESS_EXITING_BIT
Definition: pstypes.h:301
#define JOB_OBJECT_MSG_EXIT_PROCESS
Definition: pstypes.h:254
#define CT_TERMINATED_BIT
Definition: pstypes.h:264
@ PsW32ThreadCalloutExit
Definition: pstypes.h:564
#define InterlockedOr
Definition: interlocked.h:239
#define InterlockedCompareExchangePointer
Definition: interlocked.h:144
BOOLEAN KdDebuggerNotPresent
Definition: kddata.c:81
BOOLEAN KdDebuggerEnabled
Definition: kddata.c:82
#define KeLeaveCriticalRegion()
Definition: ke_x.h:119
#define KeEnterCriticalRegion()
Definition: ke_x.h:88
POBJECT_TYPE LpcPortObjectType
Definition: port.c:17
VOID NTAPI LpcExitThread(IN PETHREAD Thread)
Definition: close.c:19
#define PORT_ALL_ACCESS
Definition: lpctypes.h:51
#define ASSERT(a)
Definition: mode.c:44
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
#define LPC_CLIENT_DIED
Definition: port.c:98
#define KeGetPreviousMode()
Definition: ketypes.h:1115
#define KernelMode
Definition: asm.h:38
#define UserMode
Definition: asm.h:39
NTSYSAPI NTSTATUS NTAPI ZwSetTimerResolution(_In_ ULONG RequestedResolution, _In_ BOOLEAN SetOrUnset, _Out_ PULONG ActualResolution)
@ OriginalApcEnvironment
Definition: ketypes.h:911
VOID(NTAPI * PKNORMAL_ROUTINE)(IN PVOID NormalContext OPTIONAL, IN PVOID SystemArgument1 OPTIONAL, IN PVOID SystemArgument2 OPTIONAL)
Definition: ketypes.h:888
_In_ HANDLE ProcessHandle
Definition: mmfuncs.h:407
#define OBJECT_HEADER_TO_HANDLE_INFO(h)
Definition: obtypes.h:104
#define OBJECT_HEADER_TO_CREATOR_INFO(h)
Definition: obtypes.h:112
#define OBJECT_HEADER_TO_NAME_INFO(h)
Definition: obtypes.h:100
#define OBJECT_HEADER_TO_QUOTA_INFO(h)
Definition: obtypes.h:108
#define OBJECT_TO_OBJECT_HEADER(o)
Definition: obtypes.h:97
_In_ NTSTATUS ExitStatus
Definition: psfuncs.h:913
NTSYSAPI ULONG NTAPI DbgPrompt(_In_z_ PCCH Prompt, _Out_writes_bytes_(MaximumResponseLength) PCH Response, _In_ ULONG MaximumResponseLength)
#define THREAD_TERMINATE
Definition: nt_native.h:1339
#define NtCurrentProcess()
Definition: nt_native.h:1660
struct _EPROCESS * PEPROCESS
Definition: nt_native.h:30
struct _ETHREAD * PETHREAD
Definition: nt_native.h:29
#define MEM_RELEASE
Definition: nt_native.h:1319
BOOLEAN NTAPI ExDestroyHandle(IN PHANDLE_TABLE HandleTable, IN HANDLE Handle, IN PHANDLE_TABLE_ENTRY HandleTableEntry OPTIONAL)
Definition: handle.c:984
PVOID NTAPI ExEnterCriticalRegionAndAcquireResourceExclusive(IN PERESOURCE Resource)
Definition: resource.c:2194
VOID FASTCALL ExReleaseResourceAndLeaveCriticalRegion(IN PERESOURCE Resource)
Definition: resource.c:2283
VOID NTAPI ExTimerRundown(VOID)
Definition: timer.c:43
VOID NTAPI IoCancelThreadIo(IN PETHREAD Thread)
Definition: irp.c:1178
ULONG NTAPI KeForceResumeThread(IN PKTHREAD Thread)
Definition: thrdobj.c:267
ULONG NTAPI KeSetProcess(struct _KPROCESS *Process, KPRIORITY Increment, BOOLEAN InWait)
PLIST_ENTRY NTAPI KeFlushQueueApc(IN PKTHREAD Thread, IN KPROCESSOR_MODE PreviousMode)
Definition: apc.c:793
VOID NTAPI KeRundownThread(VOID)
Definition: thrdobj.c:430
BOOLEAN NTAPI KeReadStateThread(IN PKTHREAD Thread)
Definition: thrdobj.c:42
VOID NTAPI ExpCheckPoolAllocation(PVOID P, POOL_TYPE PoolType, ULONG Tag)
Definition: expool.c:296
VOID NTAPI MmDeleteKernelStack(PVOID Stack, BOOLEAN GuiStack)
VOID NTAPI MmCleanProcessAddressSpace(IN PEPROCESS Process)
Definition: procsup.c:1319
VOID NTAPI MmDeleteProcessAddressSpace(IN PEPROCESS Process)
Definition: procsup.c:1413
VOID NTAPI MmDeleteTeb(struct _EPROCESS *Process, PTEB Teb)
_Out_ PKAPC_STATE ApcState
Definition: mm.h:1751
VOID NTAPI SeAuditProcessExit(_In_ PEPROCESS Process)
Peforms a security auditing against a process that is about to be terminated.
Definition: audit.c:77
BOOLEAN NTAPI SeDetailedAuditingWithToken(_In_ PTOKEN Token)
Peforms a detailed security auditing with an access token.
Definition: audit.c:34
BOOLEAN NTAPI KeInsertQueueApc(IN PKAPC Apc, IN PVOID SystemArgument1, IN PVOID SystemArgument2, IN KPRIORITY PriorityBoost)
Definition: apc.c:735
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
ULONG KeMaximumIncrement
Definition: clock.c:20
NTSTATUS NTAPI LpcRequestPort(IN PVOID PortObject, IN PPORT_MESSAGE LpcMessage)
Definition: send.c:22
LIST_ENTRY PspReaperListHead
Definition: kill.c:19
NTSTATUS NTAPI NtTerminateThread(IN HANDLE ThreadHandle, IN NTSTATUS ExitStatus)
Definition: kill.c:1315
VOID NTAPI PspDeleteProcess(IN PVOID ObjectBody)
Definition: kill.c:253
VOID NTAPI PspExitNormalApc(IN PVOID NormalContext, IN PVOID SystemArgument1, IN PVOID SystemArgument2)
Definition: kill.c:971
VOID NTAPI PsShutdownSystem(VOID)
Definition: kill.c:135
LARGE_INTEGER ShortTime
Definition: kill.c:21
NTSTATUS NTAPI PsTerminateProcess(IN PEPROCESS Process, IN NTSTATUS ExitStatus)
Definition: kill.c:126
NTSTATUS NTAPI NtTerminateProcess(IN HANDLE ProcessHandle OPTIONAL, IN NTSTATUS ExitStatus)
Definition: kill.c:1197
BOOLEAN NTAPI PspIsProcessExiting(IN PEPROCESS Process)
Definition: kill.c:1092
VOID NTAPI PspExitThread(IN NTSTATUS ExitStatus)
Definition: kill.c:469
VOID NTAPI PspCatchCriticalBreak(IN PCHAR Message, IN PVOID ProcessOrThread, IN PCHAR ImageName)
Definition: kill.c:27
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:946
NTSTATUS NTAPI PsTerminateSystemThread(IN NTSTATUS ExitStatus)
Definition: kill.c:1181
NTSTATUS NTAPI PspTerminateThreadByPointer(IN PETHREAD Thread, IN NTSTATUS ExitStatus, IN BOOLEAN bSelf)
Definition: kill.c:1012
VOID NTAPI PspExitApcRundown(IN PKAPC Apc)
Definition: kill.c:157
NTSTATUS NTAPI PspTerminateProcess(IN PEPROCESS Process, IN NTSTATUS ExitStatus)
Definition: kill.c:79
VOID NTAPI PspDeleteThread(IN PVOID ObjectBody)
Definition: kill.c:402
NTSTATUS NTAPI NtRegisterThreadTerminatePort(IN HANDLE PortHandle)
Definition: kill.c:1378
WORK_QUEUE_ITEM PspReaperWorkItem
Definition: kill.c:20
VOID NTAPI PspReapRoutine(IN PVOID Context)
Definition: kill.c:167
VOID NTAPI PspExitProcess(IN BOOLEAN LastThread, IN PEPROCESS Process)
Definition: kill.c:1099
POBJECT_TYPE PsProcessType
Definition: process.c:20
PACCESS_TOKEN NTAPI PsReferencePrimaryToken(PEPROCESS Process)
Definition: security.c:440
POBJECT_TYPE PsThreadType
Definition: thread.c:20
#define STATUS_SYSTEM_SHUTDOWN
Definition: ntstatus.h:981
#define STATUS_THREAD_IS_TERMINATING
Definition: ntstatus.h:405
#define DBG_TERMINATE_PROCESS
Definition: ntstatus.h:102
#define STATUS_PROCESS_IS_TERMINATING
Definition: ntstatus.h:596
#define STATUS_NOTHING_TO_TERMINATE
Definition: ntstatus.h:159
#define STATUS_CANT_TERMINATE_SELF
Definition: ntstatus.h:549
VOID NTAPI ObKillProcess(IN PEPROCESS Process)
Definition: obhandle.c:2186
VOID NTAPI ObDereferenceDeviceMap(IN PEPROCESS Process)
Definition: devicemap.c:456
BOOLEAN FASTCALL ObReferenceObjectSafe(IN PVOID Object)
Definition: obref.c:22
VOID NTAPI ObClearProcessHandleTable(IN PEPROCESS Process)
Definition: obhandle.c:2053
VOID FASTCALL ObFastDereferenceObject(IN PEX_FAST_REF FastRef, IN PVOID Object)
Definition: obref.c:167
NTSTATUS NTAPI ObCloseHandle(IN HANDLE Handle, IN KPROCESSOR_MODE AccessMode)
Definition: obhandle.c:3411
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:493
char CHAR
Definition: pedump.c:57
PETHREAD LastThread
Definition: pinsup.c:109
VOID NTAPI PopCleanupPowerState(IN PPOWER_STATE PowerState)
Definition: power.c:164
BOOLEAN NTAPI KeIsAttachedProcess(VOID)
Definition: procobj.c:693
VOID NTAPI KeStackAttachProcess(IN PKPROCESS Process, OUT PRKAPC_STATE ApcState)
Definition: procobj.c:704
VOID NTAPI KeUnstackDetachProcess(IN PRKAPC_STATE ApcState)
Definition: procobj.c:756
#define PS_KILL_DEBUG
Definition: ps.h:25
NTSTATUS NTAPI PspSendJobMessageLocked(_In_ PEJOB Job, _In_ ULONG Message, _In_opt_ PVOID CompletionValue, _In_ BOOLEAN Quota)
Definition: job.c:397
PKWIN32_THREAD_CALLOUT PspW32ThreadCallout
Definition: win32.c:19
PKWIN32_PROCESS_CALLOUT PspW32ProcessCallout
Definition: win32.c:18
#define PSTRACE(x, fmt,...)
Definition: ps.h:57
#define PSREFTRACE(x)
Definition: ps.h:58
PHANDLE_TABLE PspCidTable
Definition: psmgr.c:48
VOID NTAPI PspExitProcessFromJob(_In_ PEPROCESS Process)
Definition: job.c:659
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
VOID NTAPI PspDeleteProcessSecurity(IN PEPROCESS Process)
Definition: security.c:30
PETHREAD NTAPI PsGetNextProcessThread(IN PEPROCESS Process, IN PETHREAD Thread OPTIONAL)
Definition: process.c:75
LIST_ENTRY PsActiveProcessHead
Definition: process.c:22
#define PSP_JOB_NOT_REALLY_ACTIVE
Definition: ps.h:111
VOID NTAPI PspRemoveProcessFromJob(_In_ PEPROCESS Process)
Definition: job.c:609
PEPROCESS NTAPI PsGetNextProcess(IN PEPROCESS OldProcess OPTIONAL)
KGUARDED_MUTEX PspActiveProcessMutex
Definition: process.c:23
PEPROCESS PsIdleProcess
Definition: psmgr.c:51
VOID NTAPI PspDeleteThreadSecurity(IN PETHREAD Thread)
Definition: security.c:46
FORCEINLINE VOID PspRunLegoRoutine(IN PKTHREAD Thread)
Definition: ps_x.h:103
#define PspSetCrossThreadFlag(Thread, Flag)
Definition: ps_x.h:25
FORCEINLINE VOID PspRunCreateThreadNotifyRoutines(IN PETHREAD CurrentThread, IN BOOLEAN Create)
Definition: ps_x.h:40
FORCEINLINE VOID PspRunCreateProcessNotifyRoutines(IN PEPROCESS CurrentProcess, IN BOOLEAN Create)
Definition: ps_x.h:62
#define PspSetProcessFlag(Process, Flag)
Definition: ps_x.h:33
VOID NTAPI PspDeleteLdt(PEPROCESS Process)
Definition: psldt.c:19
VOID NTAPI PspDeleteVdmObjects(PEPROCESS Process)
Definition: psldt.c:27
PEPROCESS PsInitialSystemProcess
Definition: psmgr.c:50
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
Entry
Definition: section.c:5216
#define STATUS_SUCCESS
Definition: shellext.h:65
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68
_In_ PVOID Context
Definition: storport.h:2325
PORT_MESSAGE h
Definition: lpctypes.h:273
LARGE_INTEGER CreateTime
Definition: lpctypes.h:274
HANDLE UniqueThread
Definition: compat.h:826
PVOID SectionObject
Definition: pstypes.h:1509
LIST_ENTRY ThreadListHead
Definition: pstypes.h:1534
PVOID VdmObjects
Definition: pstypes.h:1517
NTSTATUS ExitStatus
Definition: pstypes.h:1642
PVOID DebugPort
Definition: pstypes.h:1480
KPROCESS Pcb
Definition: pstypes.h:1467
EX_FAST_REF Token
Definition: pstypes.h:1492
struct _EJOB * Job
Definition: pstypes.h:1508
EX_PUSH_LOCK ProcessLock
Definition: pstypes.h:1468
ULONG Flags
Definition: pstypes.h:1640
PVOID * Win32Process
Definition: pstypes.h:1507
NTSTATUS LastThreadExitStatus
Definition: pstypes.h:1548
CHAR ImageFileName[16]
Definition: pstypes.h:1531
LARGE_INTEGER ExitTime
Definition: pstypes.h:1470
ULONG BreakOnTermination
Definition: pstypes.h:1610
ULONG ActiveThreads
Definition: pstypes.h:1541
LARGE_INTEGER ExitTime
Definition: pstypes.h:1300
NTSTATUS ExitStatus
Definition: pstypes.h:1306
KTHREAD Tcb
Definition: pstypes.h:1296
EX_RUNDOWN_REF RundownProtect
Definition: pstypes.h:1352
CLIENT_ID Cid
Definition: pstypes.h:1321
struct _TERMINATION_PORT * TerminationPort
Definition: pstypes.h:1312
PUNICODE_STRING ThreadName
Definition: pstypes.h:1450
ULONG ActiveExWorker
Definition: pstypes.h:1393
LARGE_INTEGER CreateTime
Definition: pstypes.h:1297
ULONG BreakOnTermination
Definition: pstypes.h:1377
ULONG CrossThreadFlags
Definition: pstypes.h:1387
ULONG SystemThread
Definition: pstypes.h:1375
LIST_ENTRY ThreadListEntry
Definition: pstypes.h:1351
Definition: ketypes.h:615
PVOID InitialStack
Definition: ketypes.h:1811
PVOID Win32Thread
Definition: ketypes.h:2013
ULONG CombinedApcDisable
Definition: ketypes.h:2030
UCHAR ApcStateIndex
Definition: ketypes.h:2089
PVOID Teb
Definition: ketypes.h:1954
PVOID LegoData
Definition: ketypes.h:2144
PVOID StackBase
Definition: ketypes.h:1813
ULONG EnableStackSwap
Definition: ketypes.h:1876
KAPC_STATE ApcState
Definition: ketypes.h:1925
ULONG ApcQueueable
Definition: ketypes.h:1858
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
Definition: ntbasedef.h:640
struct _SINGLE_LIST_ENTRY * Next
Definition: ntbasedef.h:641
Definition: compat.h:836
PVOID DbgSsReserved[2]
Definition: compat.h:883
PVOID DeallocationStack
Definition: compat.h:878
struct _TERMINATION_PORT * Next
Definition: pstypes.h:1273
#define TAG_SEPA
Definition: tag.h:158
#define TAG_PS_WOW64
Definition: tag.h:141
#define TAG_THREAD_NAME
Definition: tag.h:140
#define TAG_TERMINATE_APC
Definition: tag.h:135
#define STATUS_PENDING
Definition: telnetd.h:14
VOID NTAPI KeTerminateThread(IN KPRIORITY Increment)
Definition: thrdobj.c:1348
#define NTAPI
Definition: typedefs.h:36
void * PVOID
Definition: typedefs.h:50
ULONG_PTR SIZE_T
Definition: typedefs.h:80
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define IN
Definition: typedefs.h:39
int32_t * PLONG
Definition: typedefs.h:58
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59
#define OUT
Definition: typedefs.h:40
char * PCHAR
Definition: typedefs.h:51
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
_Must_inspect_result_ _In_ WDFCHILDLIST _In_ PWDF_CHILD_LIST_ITERATOR _Out_ WDFDEVICE _Inout_opt_ PWDF_CHILD_RETRIEVE_INFO Info
Definition: wdfchildlist.h:690
_In_ WDFIOTARGET _In_ _Strict_type_match_ WDF_IO_TARGET_SENT_IO_ACTION Action
Definition: wdfiotarget.h:510
NTSYSAPI void WINAPI DbgBreakPoint(void)
#define NtCurrentThread()
Definition: winternl.h:5372
@ Executive
Definition: ketypes.h:467
_In_ BOOLEAN Handled
Definition: ketypes.h:401
_In_opt_ PVOID _In_opt_ PVOID SystemArgument1
Definition: ketypes.h:756
struct _KAPC * PKAPC
_In_opt_ PVOID _In_opt_ PVOID _In_opt_ PVOID SystemArgument2
Definition: ketypes.h:757
KAPC_STATE
Definition: ketypes.h:1727
#define ObDereferenceObject
Definition: obfuncs.h:203
#define PsGetCurrentProcess
Definition: psfuncs.h:17