ReactOS 0.4.15-dev-7958-gcd0bb1a
kill.c File Reference
#include <ntoskrnl.h>
#include <debug.h>
Include dependency graph for kill.c:

Go to the source code of this file.

Macros

#define NDEBUG
 

Functions

VOID NTAPI PspCatchCriticalBreak (IN PCHAR Message, IN PVOID ProcessOrThread, IN PCHAR ImageName)
 
NTSTATUS NTAPI PspTerminateProcess (IN PEPROCESS Process, IN NTSTATUS ExitStatus)
 
NTSTATUS NTAPI PsTerminateProcess (IN PEPROCESS Process, IN NTSTATUS ExitStatus)
 
VOID NTAPI PspShutdownProcessManager (VOID)
 
VOID NTAPI PspExitApcRundown (IN PKAPC Apc)
 
VOID NTAPI PspReapRoutine (IN PVOID Context)
 
VOID NTAPI PspDeleteProcess (IN PVOID ObjectBody)
 
VOID NTAPI PspDeleteThread (IN PVOID ObjectBody)
 
VOID NTAPI PspExitThread (IN NTSTATUS ExitStatus)
 
VOID NTAPI PsExitSpecialApc (IN PKAPC Apc, IN OUT PKNORMAL_ROUTINE *NormalRoutine, IN OUT PVOID *NormalContext, IN OUT PVOID *SystemArgument1, IN OUT PVOID *SystemArgument2)
 
VOID NTAPI PspExitNormalApc (IN PVOID NormalContext, IN PVOID SystemArgument1, IN PVOID SystemArgument2)
 
NTSTATUS NTAPI PspTerminateThreadByPointer (IN PETHREAD Thread, IN NTSTATUS ExitStatus, IN BOOLEAN bSelf)
 
BOOLEAN NTAPI PspIsProcessExiting (IN PEPROCESS Process)
 
VOID NTAPI PspExitProcess (IN BOOLEAN LastThread, IN PEPROCESS Process)
 
NTSTATUS NTAPI PsTerminateSystemThread (IN NTSTATUS ExitStatus)
 
NTSTATUS NTAPI NtTerminateProcess (IN HANDLE ProcessHandle OPTIONAL, IN NTSTATUS ExitStatus)
 
NTSTATUS NTAPI NtTerminateThread (IN HANDLE ThreadHandle, IN NTSTATUS ExitStatus)
 
NTSTATUS NTAPI NtRegisterThreadTerminatePort (IN HANDLE PortHandle)
 

Variables

LIST_ENTRY PspReaperListHead = { NULL, NULL }
 
WORK_QUEUE_ITEM PspReaperWorkItem
 
LARGE_INTEGER ShortTime = {{-10 * 100 * 1000, -1}}
 

Macro Definition Documentation

◆ NDEBUG

#define NDEBUG

Definition at line 14 of file kill.c.

Function Documentation

◆ NtRegisterThreadTerminatePort()

NTSTATUS NTAPI NtRegisterThreadTerminatePort ( IN HANDLE  PortHandle)

Definition at line 1342 of file kill.c.

1343{
1345 PTERMINATION_PORT TerminationPort;
1346 PVOID TerminationLpcPort;
1348 PAGED_CODE();
1349 PSTRACE(PS_KILL_DEBUG, "PortHandle: %p\n", PortHandle);
1350
1351 /* Get the Port */
1352 Status = ObReferenceObjectByHandle(PortHandle,
1356 &TerminationLpcPort,
1357 NULL);
1358 if (!NT_SUCCESS(Status)) return(Status);
1359
1360 /* Allocate the Port and make sure it suceeded */
1361 TerminationPort = ExAllocatePoolWithTag(NonPagedPool,
1362 sizeof(TERMINATION_PORT),
1363 '=TsP');
1364 if(TerminationPort)
1365 {
1366 /* Associate the Port */
1368 TerminationPort->Port = TerminationLpcPort;
1369 TerminationPort->Next = Thread->TerminationPort;
1370 Thread->TerminationPort = TerminationPort;
1371
1372 /* Return success */
1373 return STATUS_SUCCESS;
1374 }
1375
1376 /* Dereference and Fail */
1377 ObDereferenceObject(TerminationLpcPort);
1379}
#define PAGED_CODE()
LONG NTSTATUS
Definition: precomp.h:26
#define NULL
Definition: types.h:112
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
#define NonPagedPool
Definition: env_spec_w32.h:307
_In_opt_ PFILE_OBJECT _In_opt_ PETHREAD Thread
Definition: fltkernel.h:2653
Status
Definition: gdiplustypes.h:25
POBJECT_TYPE LpcPortObjectType
Definition: port.c:17
#define PORT_ALL_ACCESS
Definition: lpctypes.h:47
#define KeGetPreviousMode()
Definition: ketypes.h:1115
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
#define PS_KILL_DEBUG
Definition: ps.h:25
#define PSTRACE(x, fmt,...)
Definition: ps.h:57
#define STATUS_SUCCESS
Definition: shellext.h:65
struct _TERMINATION_PORT * TerminationPort
Definition: pstypes.h:1119
struct _TERMINATION_PORT * Next
Definition: pstypes.h:1080
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define ObDereferenceObject
Definition: obfuncs.h:203

Referenced by CsrNewThread().

◆ NtTerminateProcess()

NTSTATUS NTAPI NtTerminateProcess ( IN HANDLE ProcessHandle  OPTIONAL,
IN NTSTATUS  ExitStatus 
)

Definition at line 1161 of file kill.c.

1163{
1165 PEPROCESS Process, CurrentProcess = PsGetCurrentProcess();
1166 PETHREAD Thread, CurrentThread = PsGetCurrentThread();
1167 BOOLEAN KillByHandle;
1168 PAGED_CODE();
1170 "ProcessHandle: %p ExitStatus: %d\n", ProcessHandle, ExitStatus);
1171
1172 /* Were we passed a process handle? */
1173 if (ProcessHandle)
1174 {
1175 /* Yes we were, use it */
1176 KillByHandle = TRUE;
1177 }
1178 else
1179 {
1180 /* We weren't... we assume this is suicide */
1181 KillByHandle = FALSE;
1183 }
1184
1185 /* Get the Process Object */
1190 (PVOID*)&Process,
1191 NULL);
1192 if (!NT_SUCCESS(Status)) return(Status);
1193
1194 /* Check if this is a Critical Process, and Bugcheck */
1195 if (Process->BreakOnTermination)
1196 {
1197 /* Break to debugger */
1198 PspCatchCriticalBreak("Terminating critical process 0x%p (%s)\n",
1199 Process,
1200 Process->ImageFileName);
1201 }
1202
1203 /* Lock the Process */
1204 if (!ExAcquireRundownProtection(&Process->RundownProtect))
1205 {
1206 /* Failed to lock, fail */
1209 }
1210
1211 /* Set the delete flag, unless the process is comitting suicide */
1213
1214 /* Get the first thread */
1217 if (Thread)
1218 {
1219 /* We know we have at least a thread */
1221
1222 /* Loop and kill the others */
1223 do
1224 {
1225 /* Ensure it's not ours*/
1226 if (Thread != CurrentThread)
1227 {
1228 /* Kill it */
1230 }
1231
1232 /* Move to the next thread */
1234 } while (Thread);
1235 }
1236
1237 /* Unlock the process */
1238 ExReleaseRundownProtection(&Process->RundownProtect);
1239
1240 /* Check if we are killing ourselves */
1241 if (Process == CurrentProcess)
1242 {
1243 /* Also make sure the caller gave us our handle */
1244 if (KillByHandle)
1245 {
1246 /* Dereference the process */
1248
1249 /* Terminate ourselves */
1251 }
1252 }
1254 {
1255 /* Disable debugging on this process */
1257 }
1258
1259 /* Check if there was nothing to terminate, or if we have a Debug Port */
1261 ((Process->DebugPort) && (KillByHandle)))
1262 {
1263 /* Clear the handle table */
1265
1266 /* Return status now */
1268 }
1269
1270 /* Decrease the reference count we added */
1272
1273 /* Return status */
1274 return Status;
1275}
unsigned char BOOLEAN
NTSTATUS NTAPI DbgkClearProcessDebugObject(IN PEPROCESS Process, IN PDEBUG_OBJECT SourceDebugObject OPTIONAL)
Definition: dbgkobj.c:1410
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define ExReleaseRundownProtection
Definition: ex.h:136
#define ExAcquireRundownProtection
Definition: ex.h:135
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:223
#define PROCESS_TERMINATE
Definition: pstypes.h:157
#define PSF_PROCESS_DELETE_BIT
Definition: pstypes.h:276
_In_ HANDLE ProcessHandle
Definition: mmfuncs.h:403
_In_ NTSTATUS ExitStatus
Definition: psfuncs.h:867
#define NtCurrentProcess()
Definition: nt_native.h:1657
VOID NTAPI PspCatchCriticalBreak(IN PCHAR Message, IN PVOID ProcessOrThread, IN PCHAR ImageName)
Definition: kill.c:27
NTSTATUS NTAPI PspTerminateThreadByPointer(IN PETHREAD Thread, IN NTSTATUS ExitStatus, IN BOOLEAN bSelf)
Definition: kill.c:988
POBJECT_TYPE PsProcessType
Definition: process.c:20
#define DBG_TERMINATE_PROCESS
Definition: ntstatus.h:51
#define STATUS_PROCESS_IS_TERMINATING
Definition: ntstatus.h:502
#define STATUS_NOTHING_TO_TERMINATE
Definition: ntstatus.h:106
VOID NTAPI ObClearProcessHandleTable(IN PEPROCESS Process)
Definition: obhandle.c:2027
PETHREAD NTAPI PsGetNextProcessThread(IN PEPROCESS Process, IN PETHREAD Thread OPTIONAL)
Definition: process.c:75
#define PspSetProcessFlag(Process, Flag)
Definition: ps_x.h:33
#define PsGetCurrentProcess
Definition: psfuncs.h:17

◆ NtTerminateThread()

NTSTATUS NTAPI NtTerminateThread ( IN HANDLE ThreadHandle  OPTIONAL,
IN NTSTATUS  ExitStatus 
)

Definition at line 1279 of file kill.c.

1281{
1283 PETHREAD CurrentThread = PsGetCurrentThread();
1285 PAGED_CODE();
1287 "ThreadHandle: %p ExitStatus: %d\n", ThreadHandle, ExitStatus);
1288
1289 /* Handle the special NULL case */
1290 if (!ThreadHandle)
1291 {
1292 /* Check if we're the only thread left */
1293 if (PsGetCurrentProcess()->ActiveThreads == 1)
1294 {
1295 /* This is invalid */
1297 }
1298
1299 /* Terminate us directly */
1300 goto TerminateSelf;
1301 }
1302 else if (ThreadHandle == NtCurrentThread())
1303 {
1304TerminateSelf:
1305 /* Terminate this thread */
1306 return PspTerminateThreadByPointer(CurrentThread,
1307 ExitStatus,
1308 TRUE);
1309 }
1310
1311 /* We are terminating another thread, get the Thread Object */
1312 Status = ObReferenceObjectByHandle(ThreadHandle,
1316 (PVOID*)&Thread,
1317 NULL);
1318 if (!NT_SUCCESS(Status)) return Status;
1319
1320 /* Check to see if we're running in the same thread */
1321 if (Thread != CurrentThread)
1322 {
1323 /* Terminate it */
1325
1326 /* Dereference the Thread and return */
1328 }
1329 else
1330 {
1331 /* Dereference the thread and terminate ourselves */
1333 goto TerminateSelf;
1334 }
1335
1336 /* Return status */
1337 return Status;
1338}
#define THREAD_TERMINATE
Definition: nt_native.h:1336
POBJECT_TYPE PsThreadType
Definition: thread.c:20
#define STATUS_CANT_TERMINATE_SELF
Definition: ntstatus.h:455
#define NtCurrentThread()

Referenced by _main(), BaseSrvBSMThread(), CreateRemoteThread(), CsrApiRequestThread(), CsrpCheckRequestThreads(), ExitThread(), InitializeUserModePnpManager(), PnpEventThread(), RtlExitUserThread(), RtlpExitThread(), TerminateThread(), TerminateUserModePnpManager(), and wWinMain().

◆ PsExitSpecialApc()

VOID NTAPI PsExitSpecialApc ( IN PKAPC  Apc,
IN OUT PKNORMAL_ROUTINE NormalRoutine,
IN OUT PVOID NormalContext,
IN OUT PVOID SystemArgument1,
IN OUT PVOID SystemArgument2 
)

Definition at line 922 of file kill.c.

927{
929 PAGED_CODE();
931 "Apc: %p SystemArgument2: %p\n", Apc, SystemArgument2);
932
933 /* Don't do anything unless we are in User-Mode */
934 if (Apc->SystemArgument2)
935 {
936 /* Free the APC */
937 Status = PtrToUlong(Apc->NormalContext);
939
940 /* Terminate the Thread */
942 }
943}
#define PtrToUlong(u)
Definition: config.h:107
VOID NTAPI PspExitThread(IN NTSTATUS ExitStatus)
Definition: kill.c:450
VOID NTAPI PspExitApcRundown(IN PKAPC Apc)
Definition: kill.c:157
_In_opt_ PVOID _In_opt_ PVOID _In_opt_ PVOID SystemArgument2
Definition: ketypes.h:689

Referenced by PspExitNormalApc(), and PspTerminateThreadByPointer().

◆ PspCatchCriticalBreak()

VOID NTAPI PspCatchCriticalBreak ( IN PCHAR  Message,
IN PVOID  ProcessOrThread,
IN PCHAR  ImageName 
)

Definition at line 27 of file kill.c.

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,
74 }
75}
Definition: Header.h:9
static const WCHAR Message[]
Definition: register.c:74
#define DbgPrint
Definition: hal.h:12
NTSYSAPI void WINAPI DbgBreakPoint(void)
BOOLEAN KdDebuggerNotPresent
Definition: kddata.c:81
BOOLEAN KdDebuggerEnabled
Definition: kddata.c:82
static const char * ImageName
Definition: image.c:34
NTSYSAPI ULONG NTAPI DbgPrompt(_In_z_ PCCH Prompt, _Out_writes_bytes_(MaximumResponseLength) PCH Response, _In_ ULONG MaximumResponseLength)
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
uint32_t ULONG_PTR
Definition: typedefs.h:65
_In_ WDFIOTARGET _In_ _Strict_type_match_ WDF_IO_TARGET_SENT_IO_ACTION Action
Definition: wdfiotarget.h:510
_In_ BOOLEAN Handled
Definition: ketypes.h:349
char CHAR
Definition: xmlstorage.h:175

Referenced by NtTerminateProcess(), PspExitThread(), PspTerminateProcess(), and PspTerminateThreadByPointer().

◆ PspDeleteProcess()

VOID NTAPI PspDeleteProcess ( IN PVOID  ObjectBody)

Definition at line 253 of file kill.c.

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 /*
382 * Dereference the quota block, the function
383 * will invoke a quota block cleanup if the
384 * block itself is no longer used by anybody.
385 */
387}
DECLSPEC_NORETURN VOID NTAPI KeBugCheck(ULONG BugCheckCode)
Definition: bug.c:1430
#define RemoveEntryList(Entry)
Definition: env_spec_w32.h:986
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
VOID FASTCALL KeReleaseGuardedMutex(IN OUT PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:53
VOID FASTCALL KeAcquireGuardedMutex(IN PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:42
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
struct _EPROCESS * PEPROCESS
Definition: nt_native.h:30
BOOLEAN NTAPI ExDestroyHandle(IN PHANDLE_TABLE HandleTable, IN HANDLE Handle, IN PHANDLE_TABLE_ENTRY HandleTableEntry OPTIONAL)
Definition: handle.c:984
VOID NTAPI MmDeleteProcessAddressSpace(IN PEPROCESS Process)
Definition: procsup.c:1366
_Out_ PKAPC_STATE ApcState
Definition: mm.h:1765
VOID NTAPI PspExitProcess(IN BOOLEAN LastThread, IN PEPROCESS Process)
Definition: kill.c:1075
VOID NTAPI ObKillProcess(IN PEPROCESS Process)
Definition: obhandle.c:2160
VOID NTAPI ObDereferenceDeviceMap(IN PEPROCESS Process)
Definition: devicemap.c:456
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
VOID NTAPI PspRemoveProcessFromJob(IN PEPROCESS Process, IN PEJOB Job)
Definition: job.c:138
#define PSREFTRACE(x)
Definition: ps.h:58
PHANDLE_TABLE PspCidTable
Definition: psmgr.c:48
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
KGUARDED_MUTEX PspActiveProcessMutex
Definition: process.c:23
VOID NTAPI PspDeleteLdt(PEPROCESS Process)
Definition: psldt.c:19
VOID NTAPI PspDeleteVdmObjects(PEPROCESS Process)
Definition: psldt.c:27
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 TAG_SEPA
Definition: tag.h:156
KAPC_STATE
Definition: ketypes.h:1409

Referenced by PspInitPhase0().

◆ PspDeleteThread()

VOID NTAPI PspDeleteThread ( IN PVOID  ObjectBody)

Definition at line 391 of file kill.c.

392{
393 PETHREAD Thread = (PETHREAD)ObjectBody;
394 PEPROCESS Process = Thread->ThreadsProcess;
395 PAGED_CODE();
396 PSTRACE(PS_KILL_DEBUG, "ObjectBody: %p\n", ObjectBody);
399
400 /* Check if we have a stack */
402 {
403 /* Release it */
405 Thread->Tcb.LargeStack);
406 }
407
408 /* Check if we have a CID Handle */
410 {
411 /* Delete the CID Handle */
413 {
414 /* Something wrong happened, bugcheck */
415 KeBugCheck(CID_HANDLE_DELETION);
416 }
417 }
418
419 /* Cleanup impersionation information */
421
422 /* Make sure the thread was inserted, before continuing */
423 if (!Process) return;
424
425 /* Check if the thread list is valid */
427 {
428 /* Lock the thread's process */
430 ExAcquirePushLockExclusive(&Process->ProcessLock);
431
432 /* Remove us from the list */
434
435 /* Release the lock */
436 ExReleasePushLockExclusive(&Process->ProcessLock);
438 }
439
440 /* Dereference the Process */
442}
FORCEINLINE VOID ExAcquirePushLockExclusive(PEX_PUSH_LOCK PushLock)
Definition: ex.h:1036
FORCEINLINE VOID ExReleasePushLockExclusive(PEX_PUSH_LOCK PushLock)
Definition: ex.h:1252
#define KeLeaveCriticalRegion()
Definition: ke_x.h:119
#define KeEnterCriticalRegion()
Definition: ke_x.h:88
#define ASSERT(a)
Definition: mode.c:44
struct _ETHREAD * PETHREAD
Definition: nt_native.h:29
VOID NTAPI MmDeleteKernelStack(PVOID Stack, BOOLEAN GuiStack)
VOID NTAPI PspDeleteThreadSecurity(IN PETHREAD Thread)
Definition: security.c:46
HANDLE UniqueThread
Definition: compat.h:826
KTHREAD Tcb
Definition: pstypes.h:1103
CLIENT_ID Cid
Definition: pstypes.h:1128
LIST_ENTRY ThreadListEntry
Definition: pstypes.h:1158
PVOID InitialStack
Definition: ketypes.h:1664
PVOID Win32Thread
Definition: ketypes.h:1866
PVOID StackBase
Definition: ketypes.h:1666
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121

Referenced by PspInitPhase0().

◆ PspExitApcRundown()

VOID NTAPI PspExitApcRundown ( IN PKAPC  Apc)

Definition at line 157 of file kill.c.

158{
159 PAGED_CODE();
160
161 /* Free the APC */
162 ExFreePool(Apc);
163}

Referenced by PsExitSpecialApc(), PspExitNormalApc(), and PspTerminateThreadByPointer().

◆ PspExitNormalApc()

VOID NTAPI PspExitNormalApc ( IN PVOID  NormalContext,
IN PVOID  SystemArgument1,
IN PVOID  SystemArgument2 
)

Definition at line 947 of file kill.c.

950{
953 PAGED_CODE();
954 PSTRACE(PS_KILL_DEBUG, "SystemArgument2: %p\n", SystemArgument2);
955
956 /* This should never happen */
958
959 /* If we're here, this is not a System Thread, so kill it from User-Mode */
960 KeInitializeApc(Apc,
961 &Thread->Tcb,
966 UserMode,
967 NormalContext);
968
969 /* Now insert the APC with the User-Mode Flag */
970 if (!(KeInsertQueueApc(Apc,
971 Apc,
973 2)))
974 {
975 /* Failed to insert, free the APC */
977 }
978
979 /* Set the APC Pending flag */
980 Thread->Tcb.ApcState.UserApcPending = TRUE;
981}
#define UserMode
Definition: asm.h:35
@ OriginalApcEnvironment
Definition: ketypes.h:767
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
VOID NTAPI PspExitNormalApc(IN PVOID NormalContext, IN PVOID SystemArgument1, IN PVOID SystemArgument2)
Definition: kill.c:947
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:922
Definition: ketypes.h:547
KAPC_STATE ApcState
Definition: ketypes.h:1778
_In_opt_ PVOID _In_opt_ PVOID SystemArgument1
Definition: ketypes.h:688
struct _KAPC * PKAPC

Referenced by PspExitNormalApc(), and PspTerminateThreadByPointer().

◆ PspExitProcess()

VOID NTAPI PspExitProcess ( IN BOOLEAN  LastThread,
IN PEPROCESS  Process 
)

Definition at line 1075 of file kill.c.

1077{
1078 ULONG Actual;
1079 PAGED_CODE();
1081 "LastThread: %u Process: %p\n", LastThread, Process);
1083
1084 /* Set Process Exit flag */
1086
1087 /* Check if we are the last thread */
1088 if (LastThread)
1089 {
1090 /* Notify the WMI Process Callback */
1091 //WmiTraceProcess(Process, FALSE);
1092
1093 /* Run the Notification Routines */
1095 }
1096
1097 /* Cleanup the power state */
1098 PopCleanupPowerState((PPOWER_STATE)&Process->Pcb.PowerState);
1099
1100 /* Clear the security port */
1101 if (!Process->SecurityPort)
1102 {
1103 /* So we don't double-dereference */
1104 Process->SecurityPort = (PVOID)1;
1105 }
1106 else if (Process->SecurityPort != (PVOID)1)
1107 {
1108 /* Dereference it */
1109 ObDereferenceObject(Process->SecurityPort);
1110 Process->SecurityPort = (PVOID)1;
1111 }
1112
1113 /* Check if we are the last thread */
1114 if (LastThread)
1115 {
1116 /* Check if we have to set the Timer Resolution */
1117 if (Process->SetTimerResolution)
1118 {
1119 /* Set it to default */
1121 }
1122
1123 /* Check if we are part of a Job that has a completion port */
1124 if ((Process->Job) && (Process->Job->CompletionPort))
1125 {
1126 /* FIXME: Check job status code and do I/O completion if needed */
1127 }
1128
1129 /* FIXME: Notify the Prefetcher */
1130 }
1131 else
1132 {
1133 /* Clear process' address space here */
1135 }
1136}
#define PSF_PROCESS_EXITING_BIT
Definition: pstypes.h:275
#define InterlockedOr
Definition: interlocked.h:224
NTSYSAPI NTSTATUS NTAPI ZwSetTimerResolution(_In_ ULONG RequestedResolution, _In_ BOOLEAN SetOrUnset, _Out_ PULONG ActualResolution)
VOID NTAPI MmCleanProcessAddressSpace(IN PEPROCESS Process)
Definition: procsup.c:1267
ULONG KeMaximumIncrement
Definition: clock.c:20
PETHREAD LastThread
Definition: pinsup.c:109
VOID NTAPI PopCleanupPowerState(IN PPOWER_STATE PowerState)
Definition: power.c:164
FORCEINLINE VOID PspRunCreateProcessNotifyRoutines(IN PEPROCESS CurrentProcess, IN BOOLEAN Create)
Definition: ps_x.h:62
void * PVOID
Definition: typedefs.h:50
int32_t * PLONG
Definition: typedefs.h:58
uint32_t ULONG
Definition: typedefs.h:59

Referenced by PspDeleteProcess(), and PspExitThread().

◆ PspExitThread()

VOID NTAPI PspExitThread ( IN NTSTATUS  ExitStatus)

Definition at line 450 of file kill.c.

451{
452 CLIENT_DIED_MSG TerminationMsg;
454 PTEB Teb;
455 PEPROCESS CurrentProcess;
456 PETHREAD Thread, OtherThread, PreviousThread = NULL;
457 PVOID DeallocationStack;
458 SIZE_T Dummy;
459 BOOLEAN Last = FALSE;
460 PTERMINATION_PORT TerminationPort, NextPort;
461 PLIST_ENTRY FirstEntry, CurrentEntry;
462 PKAPC Apc;
463 PTOKEN PrimaryToken;
464 PAGED_CODE();
465 PSTRACE(PS_KILL_DEBUG, "ExitStatus: %d\n", ExitStatus);
466
467 /* Get the Current Thread and Process */
469 CurrentProcess = Thread->ThreadsProcess;
471
472 /* Can't terminate a thread if it attached another process */
474 {
475 /* Bugcheck */
476 KeBugCheckEx(INVALID_PROCESS_ATTACH_ATTEMPT,
477 (ULONG_PTR)CurrentProcess,
478 (ULONG_PTR)Thread->Tcb.ApcState.Process,
481 }
482
483 /* Lower to Passive Level */
485
486 /* Can't be a worker thread */
488 {
489 /* Bugcheck */
490 KeBugCheckEx(ACTIVE_EX_WORKER_THREAD_TERMINATION,
492 0,
493 0,
494 0);
495 }
496
497 /* Can't have pending APCs */
498 if (Thread->Tcb.CombinedApcDisable != 0)
499 {
500 /* Bugcheck */
501 KeBugCheckEx(KERNEL_APC_PENDING_DURING_EXIT,
502 0,
504 0,
505 1);
506 }
507
508 /* Lock the thread */
510
511 /* Cleanup the power state */
513
514 /* Call the WMI Callback for Threads */
515 //WmiTraceThread(Thread, NULL, FALSE);
516
517 /* Run Thread Notify Routines before we desintegrate the thread */
519
520 /* Lock the Process before we modify its thread entries */
522 ExAcquirePushLockExclusive(&CurrentProcess->ProcessLock);
523
524 /* Decrease the active thread count, and check if it's 0 */
525 if (!(--CurrentProcess->ActiveThreads))
526 {
527 /* Set the delete flag */
529
530 /* Remember we are last */
531 Last = TRUE;
532
533 /* Check if this termination is due to the thread dying */
535 {
536 /* Check if the last thread was pending */
537 if (CurrentProcess->ExitStatus == STATUS_PENDING)
538 {
539 /* Use the last exit status */
540 CurrentProcess->ExitStatus = CurrentProcess->
541 LastThreadExitStatus;
542 }
543 }
544 else
545 {
546 /* Just a normal exit, write the code */
547 CurrentProcess->ExitStatus = ExitStatus;
548 }
549
550 /* Loop all the current threads */
551 FirstEntry = &CurrentProcess->ThreadListHead;
552 CurrentEntry = FirstEntry->Flink;
553 while (FirstEntry != CurrentEntry)
554 {
555 /* Get the thread on the list */
556 OtherThread = CONTAINING_RECORD(CurrentEntry,
557 ETHREAD,
558 ThreadListEntry);
559
560 /* Check if it's a thread that's still alive */
561 if ((OtherThread != Thread) &&
562 !(KeReadStateThread(&OtherThread->Tcb)) &&
563 (ObReferenceObjectSafe(OtherThread)))
564 {
565 /* It's a live thread and we referenced it, unlock process */
566 ExReleasePushLockExclusive(&CurrentProcess->ProcessLock);
568
569 /* Wait on the thread */
570 KeWaitForSingleObject(OtherThread,
571 Executive,
573 FALSE,
574 NULL);
575
576 /* Check if we had a previous thread to dereference */
577 if (PreviousThread) ObDereferenceObject(PreviousThread);
578
579 /* Remember the thread and re-lock the process */
580 PreviousThread = OtherThread;
582 ExAcquirePushLockExclusive(&CurrentProcess->ProcessLock);
583 }
584
585 /* Go to the next thread */
586 CurrentEntry = CurrentEntry->Flink;
587 }
588 }
590 {
591 /* Write down the exit status of the last thread to get killed */
592 CurrentProcess->LastThreadExitStatus = ExitStatus;
593 }
594
595 /* Unlock the Process */
596 ExReleasePushLockExclusive(&CurrentProcess->ProcessLock);
598
599 /* Check if we had a previous thread to dereference */
600 if (PreviousThread) ObDereferenceObject(PreviousThread);
601
602 /* Check if the process has a debug port and if this is a user thread */
603 if ((CurrentProcess->DebugPort) && !(Thread->SystemThread))
604 {
605 /* Notify the Debug API. */
606 Last ? DbgkExitProcess(CurrentProcess->ExitStatus) :
608 }
609
610 /* Check if this is a Critical Thread */
612 {
613 /* Break to debugger */
614 PspCatchCriticalBreak("Critical thread 0x%p (in %s) exited\n",
615 Thread,
616 CurrentProcess->ImageFileName);
617 }
618
619 /* Check if it's the last thread and this is a Critical Process */
620 if ((Last) && (CurrentProcess->BreakOnTermination))
621 {
622 /* Check if a debugger is here to handle this */
624 {
625 /* Break to debugger */
626 PspCatchCriticalBreak("Critical process 0x%p (in %s) exited\n",
627 CurrentProcess,
628 CurrentProcess->ImageFileName);
629 }
630 else
631 {
632 /* Bugcheck, we can't allow this */
633 KeBugCheckEx(CRITICAL_PROCESS_DIED,
634 (ULONG_PTR)CurrentProcess,
635 0,
636 0,
637 0);
638 }
639 }
640
641 /* Sanity check */
643
644 /* Process the Termination Ports */
645 TerminationPort = Thread->TerminationPort;
646 if (TerminationPort)
647 {
648 /* Setup the message header */
649 TerminationMsg.h.u2.ZeroInit = 0;
650 TerminationMsg.h.u2.s2.Type = LPC_CLIENT_DIED;
651 TerminationMsg.h.u1.s1.TotalLength = sizeof(TerminationMsg);
652 TerminationMsg.h.u1.s1.DataLength = sizeof(TerminationMsg) -
653 sizeof(PORT_MESSAGE);
654
655 /* Loop each port */
656 do
657 {
658 /* Save the Create Time */
659 TerminationMsg.CreateTime = Thread->CreateTime;
660
661 /* Loop trying to send message */
662 while (TRUE)
663 {
664 /* Send the LPC Message */
665 Status = LpcRequestPort(TerminationPort->Port,
666 &TerminationMsg.h);
667 if ((Status == STATUS_NO_MEMORY) ||
669 {
670 /* Wait a bit and try again */
672 continue;
673 }
674 break;
675 }
676
677 /* Dereference this LPC Port */
678 ObDereferenceObject(TerminationPort->Port);
679
680 /* Move to the next one */
681 NextPort = TerminationPort->Next;
682
683 /* Free the Termination Port Object */
684 ExFreePoolWithTag(TerminationPort, '=TsP');
685
686 /* Keep looping as long as there is a port */
687 TerminationPort = NextPort;
688 } while (TerminationPort);
689 }
691 (Thread->DeadThread)) ||
692 !(Thread->DeadThread))
693 {
694 /*
695 * This case is special and deserves some extra comments. What
696 * basically happens here is that this thread doesn't have a termination
697 * port, which means that it died before being fully created. Since we
698 * still have to notify an LPC Server, we'll use the exception port,
699 * which we know exists. However, we need to know how far the thread
700 * actually got created. We have three possibilities:
701 *
702 * - NtCreateThread returned an error really early: DeadThread is set.
703 * - NtCreateThread managed to create the thread: DeadThread is off.
704 * - NtCreateThread was creating the thread (with DeadThread set,
705 * but the thread got killed prematurely: STATUS_THREAD_IS_TERMINATING
706 * is our exit code.)
707 *
708 * For the 2 & 3rd scenarios, the thread has been created far enough to
709 * warrant notification to the LPC Server.
710 */
711
712 /* Setup the message header */
713 TerminationMsg.h.u2.ZeroInit = 0;
714 TerminationMsg.h.u2.s2.Type = LPC_CLIENT_DIED;
715 TerminationMsg.h.u1.s1.TotalLength = sizeof(TerminationMsg);
716 TerminationMsg.h.u1.s1.DataLength = sizeof(TerminationMsg) -
717 sizeof(PORT_MESSAGE);
718
719 /* Make sure the process has an exception port */
720 if (CurrentProcess->ExceptionPort)
721 {
722 /* Save the Create Time */
723 TerminationMsg.CreateTime = Thread->CreateTime;
724
725 /* Loop trying to send message */
726 while (TRUE)
727 {
728 /* Send the LPC Message */
729 Status = LpcRequestPort(CurrentProcess->ExceptionPort,
730 &TerminationMsg.h);
731 if ((Status == STATUS_NO_MEMORY) ||
733 {
734 /* Wait a bit and try again */
736 continue;
737 }
738 break;
739 }
740 }
741 }
742
743 /* Rundown Win32 Thread if there is one */
746
747 /* If we are the last thread and have a W32 Process */
748 if ((Last) && (CurrentProcess->Win32Process))
749 {
750 /* Run it down too */
751 PspW32ProcessCallout(CurrentProcess, FALSE);
752 }
753
754 /* Make sure Stack Swap is enabled */
756 {
757 /* Stack swap really shouldn't be disabled during exit! */
758 KeBugCheckEx(KERNEL_STACK_LOCKED_AT_EXIT, 0, 0, 0, 0);
759 }
760
761 /* Cancel I/O for the thread. */
763
764 /* Rundown Timers */
766
767 /* FIXME: Rundown Registry Notifications (NtChangeNotify)
768 CmNotifyRunDown(Thread); */
769
770 /* Rundown Mutexes */
772
773 /* Check if we have a TEB */
774 Teb = Thread->Tcb.Teb;
775 if (Teb)
776 {
777 /* Check if the thread is still alive */
778 if (!Thread->DeadThread)
779 {
780 /* Check if we need to free its stack */
781 if (Teb->FreeStackOnTermination)
782 {
783 /* Set the TEB's Deallocation Stack as the Base Address */
784 Dummy = 0;
785 DeallocationStack = Teb->DeallocationStack;
786
787 /* Free the Thread's Stack */
788 ZwFreeVirtualMemory(NtCurrentProcess(),
789 &DeallocationStack,
790 &Dummy,
792 }
793
794 /* Free the debug handle */
795 if (Teb->DbgSsReserved[1]) ObCloseHandle(Teb->DbgSsReserved[1],
796 UserMode);
797 }
798
799 /* Decommit the TEB */
800 MmDeleteTeb(CurrentProcess, Teb);
801 Thread->Tcb.Teb = NULL;
802 }
803
804 /* Free LPC Data */
806
807 /* Save the exit status and exit time */
810
811 /* Sanity check */
813
814 /* Check if this is the final thread or not */
815 if (Last)
816 {
817 /* Set the process exit time */
818 CurrentProcess->ExitTime = Thread->ExitTime;
819
820 /* Exit the process */
821 PspExitProcess(TRUE, CurrentProcess);
822
823 /* Get the process token and check if we need to audit */
824 PrimaryToken = PsReferencePrimaryToken(CurrentProcess);
825 if (SeDetailedAuditingWithToken(PrimaryToken))
826 {
827 /* Audit the exit */
828 SeAuditProcessExit(CurrentProcess);
829 }
830
831 /* Dereference the process token */
832 ObFastDereferenceObject(&CurrentProcess->Token, PrimaryToken);
833
834 /* Check if this is a VDM Process and rundown the VDM DPCs if so */
835 if (CurrentProcess->VdmObjects) { /* VdmRundownDpcs(CurrentProcess); */ }
836
837 /* Kill the process in the Object Manager */
838 ObKillProcess(CurrentProcess);
839
840 /* Check if we have a section object */
841 if (CurrentProcess->SectionObject)
842 {
843 /* Dereference and clear the Section Object */
844 ObDereferenceObject(CurrentProcess->SectionObject);
845 CurrentProcess->SectionObject = NULL;
846 }
847
848 /* Check if the process is part of a job */
849 if (CurrentProcess->Job)
850 {
851 /* Remove the process from the job */
852 PspExitProcessFromJob(CurrentProcess->Job, CurrentProcess);
853 }
854 }
855
856 /* Disable APCs */
858
859 /* Disable APC queueing, force a resumption */
862
863 /* Re-enable APCs */
865
866 /* Flush the User APCs */
867 FirstEntry = KeFlushQueueApc(&Thread->Tcb, UserMode);
868 if (FirstEntry)
869 {
870 /* Start with the first entry */
871 CurrentEntry = FirstEntry;
872 do
873 {
874 /* Get the APC */
875 Apc = CONTAINING_RECORD(CurrentEntry, KAPC, ApcListEntry);
876
877 /* Move to the next one */
878 CurrentEntry = CurrentEntry->Flink;
879
880 /* Rundown the APC or de-allocate it */
881 if (Apc->RundownRoutine)
882 {
883 /* Call its own routine */
884 Apc->RundownRoutine(Apc);
885 }
886 else
887 {
888 /* Do it ourselves */
889 ExFreePool(Apc);
890 }
891 }
892 while (CurrentEntry != FirstEntry);
893 }
894
895 /* Clean address space if this was the last thread */
896 if (Last) MmCleanProcessAddressSpace(CurrentProcess);
897
898 /* Call the Lego routine */
900
901 /* Flush the APC queue, which should be empty */
902 FirstEntry = KeFlushQueueApc(&Thread->Tcb, KernelMode);
903 if ((FirstEntry) || (Thread->Tcb.CombinedApcDisable != 0))
904 {
905 /* Bugcheck time */
906 KeBugCheckEx(KERNEL_APC_PENDING_DURING_EXIT,
907 (ULONG_PTR)FirstEntry,
910 0);
911 }
912
913 /* Signal the process if this was the last thread */
914 if (Last) KeSetProcess(&CurrentProcess->Pcb, 0, FALSE);
915
916 /* Terminate the Thread from the Scheduler */
918}
VOID NTAPI DbgkExitThread(IN NTSTATUS ExitStatus)
Definition: dbgkutil.c:340
VOID NTAPI DbgkExitProcess(IN NTSTATUS ExitStatus)
Definition: dbgkutil.c:304
#define PASSIVE_LEVEL
Definition: env_spec_w32.h:693
#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 KeDelayExecutionThread(mode, foo, t)
Definition: env_spec_w32.h:484
#define ExWaitForRundownProtectionRelease
Definition: ex.h:138
@ PsW32ThreadCalloutExit
Definition: pstypes.h:500
VOID NTAPI LpcExitThread(IN PETHREAD Thread)
Definition: close.c:19
#define LPC_CLIENT_DIED
Definition: port.c:98
#define KernelMode
Definition: asm.h:34
#define MEM_RELEASE
Definition: nt_native.h:1316
VOID NTAPI ExTimerRundown(VOID)
Definition: timer.c:43
VOID NTAPI IoCancelThreadIo(IN PETHREAD Thread)
Definition: irp.c:1146
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 MmDeleteTeb(struct _EPROCESS *Process, PTEB Teb)
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
NTSTATUS NTAPI LpcRequestPort(IN PVOID PortObject, IN PPORT_MESSAGE LpcMessage)
Definition: send.c:22
LARGE_INTEGER ShortTime
Definition: kill.c:21
PACCESS_TOKEN NTAPI PsReferencePrimaryToken(PEPROCESS Process)
Definition: security.c:440
#define STATUS_THREAD_IS_TERMINATING
Definition: ntstatus.h:311
#define STATUS_PENDING
Definition: ntstatus.h:82
#define STATUS_NO_MEMORY
Definition: ntstatus.h:260
BOOLEAN FASTCALL ObReferenceObjectSafe(IN PVOID Object)
Definition: obref.c:22
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:3379
BOOLEAN NTAPI KeIsAttachedProcess(VOID)
Definition: procobj.c:693
PKWIN32_THREAD_CALLOUT PspW32ThreadCallout
Definition: win32.c:19
VOID NTAPI PspExitProcessFromJob(IN PEJOB Job, IN PEPROCESS Process)
Definition: job.c:146
PKWIN32_PROCESS_CALLOUT PspW32ProcessCallout
Definition: win32.c:18
FORCEINLINE VOID PspRunLegoRoutine(IN PKTHREAD Thread)
Definition: ps_x.h:103
FORCEINLINE VOID PspRunCreateThreadNotifyRoutines(IN PETHREAD CurrentThread, IN BOOLEAN Create)
Definition: ps_x.h:40
PORT_MESSAGE h
Definition: lpctypes.h:269
LARGE_INTEGER CreateTime
Definition: lpctypes.h:270
PVOID SectionObject
Definition: pstypes.h:1304
LIST_ENTRY ThreadListHead
Definition: pstypes.h:1329
PVOID VdmObjects
Definition: pstypes.h:1312
NTSTATUS ExitStatus
Definition: pstypes.h:1437
PVOID DebugPort
Definition: pstypes.h:1275
KPROCESS Pcb
Definition: pstypes.h:1262
EX_FAST_REF Token
Definition: pstypes.h:1287
struct _EJOB * Job
Definition: pstypes.h:1303
EX_PUSH_LOCK ProcessLock
Definition: pstypes.h:1263
ULONG Flags
Definition: pstypes.h:1435
PVOID * Win32Process
Definition: pstypes.h:1302
NTSTATUS LastThreadExitStatus
Definition: pstypes.h:1343
CHAR ImageFileName[16]
Definition: pstypes.h:1326
LARGE_INTEGER ExitTime
Definition: pstypes.h:1265
ULONG BreakOnTermination
Definition: pstypes.h:1405
ULONG ActiveThreads
Definition: pstypes.h:1336
LARGE_INTEGER ExitTime
Definition: pstypes.h:1107
NTSTATUS ExitStatus
Definition: pstypes.h:1113
EX_RUNDOWN_REF RundownProtect
Definition: pstypes.h:1159
ULONG ActiveExWorker
Definition: pstypes.h:1200
LARGE_INTEGER CreateTime
Definition: pstypes.h:1104
ULONG BreakOnTermination
Definition: pstypes.h:1184
ULONG SystemThread
Definition: pstypes.h:1182
ULONG CombinedApcDisable
Definition: ketypes.h:1883
UCHAR ApcStateIndex
Definition: ketypes.h:1942
PVOID Teb
Definition: ketypes.h:1807
PVOID LegoData
Definition: ketypes.h:1997
ULONG EnableStackSwap
Definition: ketypes.h:1729
ULONG ApcQueueable
Definition: ketypes.h:1711
Definition: typedefs.h:120
Definition: compat.h:836
PVOID DbgSsReserved[2]
Definition: compat.h:883
PVOID DeallocationStack
Definition: compat.h:878
VOID NTAPI KeTerminateThread(IN KPRIORITY Increment)
Definition: thrdobj.c:1367
ULONG_PTR SIZE_T
Definition: typedefs.h:80
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
@ Executive
Definition: ketypes.h:415

Referenced by PsExitSpecialApc(), and PspTerminateThreadByPointer().

◆ PspIsProcessExiting()

BOOLEAN NTAPI PspIsProcessExiting ( IN PEPROCESS  Process)

Definition at line 1068 of file kill.c.

1069{
1070 return Process->Flags & PSF_PROCESS_EXITING_BIT;
1071}

Referenced by MmpPageOutPhysicalAddress().

◆ PspReapRoutine()

VOID NTAPI PspReapRoutine ( IN PVOID  Context)

Definition at line 167 of file kill.c.

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}
#define InterlockedExchangePointer(Target, Value)
Definition: dshow.h:45
#define InterlockedCompareExchangePointer
Definition: interlocked.h:129
LIST_ENTRY PspReaperListHead
Definition: kill.c:19
Definition: ntbasedef.h:628
struct _SINGLE_LIST_ENTRY * Next
Definition: ntbasedef.h:629

Referenced by PspInitPhase0().

◆ PspShutdownProcessManager()

VOID NTAPI PspShutdownProcessManager ( VOID  )

Definition at line 135 of file kill.c.

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}
NTSTATUS NTAPI PspTerminateProcess(IN PEPROCESS Process, IN NTSTATUS ExitStatus)
Definition: kill.c:79
#define STATUS_SYSTEM_SHUTDOWN
Definition: ntstatus.h:855
PEPROCESS NTAPI PsGetNextProcess(IN PEPROCESS OldProcess OPTIONAL)
Definition: process.c:128
PEPROCESS PsIdleProcess
Definition: psmgr.c:51
PEPROCESS PsInitialSystemProcess
Definition: psmgr.c:50

◆ PspTerminateProcess()

NTSTATUS NTAPI PspTerminateProcess ( IN PEPROCESS  Process,
IN NTSTATUS  ExitStatus 
)

Definition at line 79 of file kill.c.

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}

Referenced by PspShutdownProcessManager(), and PsTerminateProcess().

◆ PspTerminateThreadByPointer()

NTSTATUS NTAPI PspTerminateThreadByPointer ( IN PETHREAD  Thread,
IN NTSTATUS  ExitStatus,
IN BOOLEAN  bSelf 
)

Definition at line 988 of file kill.c.

991{
992 PKAPC Apc;
994 ULONG Flags;
995 PAGED_CODE();
996 PSTRACE(PS_KILL_DEBUG, "Thread: %p ExitStatus: %d\n", Thread, ExitStatus);
998
999 /* Check if this is a Critical Thread, and Bugcheck */
1001 {
1002 /* Break to debugger */
1003 PspCatchCriticalBreak("Terminating critical thread 0x%p (%s)\n",
1004 Thread,
1005 Thread->ThreadsProcess->ImageFileName);
1006 }
1007
1008 /* Check if we are already inside the thread */
1009 if ((bSelf) || (PsGetCurrentThread() == Thread))
1010 {
1011 /* This should only happen at passive */
1013
1014 /* Mark it as terminated */
1016
1017 /* Directly terminate the thread */
1019 }
1020
1021 /* This shouldn't be a system thread */
1023
1024 /* Allocate the APC */
1026 if (!Apc) return STATUS_INSUFFICIENT_RESOURCES;
1027
1028 /* Set the Terminated Flag */
1030
1031 /* Set it, and check if it was already set while we were running */
1034 {
1035 /* Initialize a Kernel Mode APC to Kill the Thread */
1036 KeInitializeApc(Apc,
1037 &Thread->Tcb,
1042 KernelMode,
1044
1045 /* Insert it into the APC Queue */
1046 if (!KeInsertQueueApc(Apc, Apc, NULL, 2))
1047 {
1048 /* The APC was already in the queue, fail */
1050 }
1051 else
1052 {
1053 /* Forcefully resume the thread and return */
1055 return Status;
1056 }
1057 }
1058
1059 /* We failed, free the APC */
1061
1062 /* Return Status */
1063 return Status;
1064}
#define InterlockedExchange
Definition: armddk.h:54
#define ASSERT_IRQL_EQUAL(x)
Definition: debug.h:43
#define UlongToPtr(u)
Definition: config.h:106
#define CT_TERMINATED_BIT
Definition: pstypes.h:238
#define PspSetCrossThreadFlag(Thread, Flag)
Definition: ps_x.h:25
ULONG CrossThreadFlags
Definition: pstypes.h:1194
#define TAG_TERMINATE_APC
Definition: tag.h:135
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170

Referenced by NtTerminateProcess(), NtTerminateThread(), PspSystemThreadStartup(), PspTerminateProcess(), PspUserThreadStartup(), and PsTerminateSystemThread().

◆ PsTerminateProcess()

NTSTATUS NTAPI PsTerminateProcess ( IN PEPROCESS  Process,
IN NTSTATUS  ExitStatus 
)

Definition at line 126 of file kill.c.

128{
129 /* Call the internal API */
131}

Referenced by DbgkpCloseObject(), and ExpDebuggerWorker().

◆ PsTerminateSystemThread()

Variable Documentation

◆ PspReaperListHead

LIST_ENTRY PspReaperListHead = { NULL, NULL }

Definition at line 19 of file kill.c.

Referenced by KeTerminateThread(), and PspReapRoutine().

◆ PspReaperWorkItem

WORK_QUEUE_ITEM PspReaperWorkItem

Definition at line 20 of file kill.c.

Referenced by KeTerminateThread(), and PspInitPhase0().

◆ ShortTime

LARGE_INTEGER ShortTime = {{-10 * 100 * 1000, -1}}

Definition at line 21 of file kill.c.

Referenced by PspExitThread().