ReactOS 0.4.17-dev-1196-gb6224c3
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 PsShutdownSystem (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 1378 of file kill.c.

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()
LONG NTSTATUS
Definition: precomp.h:26
#define NULL
Definition: types.h:112
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
#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:24
POBJECT_TYPE LpcPortObjectType
Definition: port.c:17
#define PORT_ALL_ACCESS
Definition: lpctypes.h:51
#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:493
#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:1312
struct _TERMINATION_PORT * Next
Definition: pstypes.h:1273
#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 1197 of file kill.c.

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}
unsigned char BOOLEAN
Definition: actypes.h:127
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:139
#define ExAcquireRundownProtection
Definition: ex.h:138
_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:153
#define PSF_PROCESS_DELETE_BIT
Definition: pstypes.h:302
_In_ HANDLE ProcessHandle
Definition: mmfuncs.h:407
_In_ NTSTATUS ExitStatus
Definition: psfuncs.h:913
#define NtCurrentProcess()
Definition: nt_native.h:1660
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:1012
POBJECT_TYPE PsProcessType
Definition: process.c:20
#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
VOID NTAPI ObClearProcessHandleTable(IN PEPROCESS Process)
Definition: obhandle.c:2053
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 1315 of file kill.c.

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}
#define THREAD_TERMINATE
Definition: nt_native.h:1339
POBJECT_TYPE PsThreadType
Definition: thread.c:20
#define STATUS_CANT_TERMINATE_SELF
Definition: ntstatus.h:549
#define NtCurrentThread()
Definition: winternl.h:5372

Referenced by _main(), BaseSrvBSMThread(), CreateRemoteThread(), CsrApiRequestThread(), CsrpCheckRequestThreads(), DummyThread(), ExitThread(), InitializeUserModePnpManager(), PnpEventThread(), RtlExitUserThread(), RtlpExitThread(), TerminateThread(), TerminateUserModePnpManager(), test_notifications(), Test_ThreadHideFromDebuggerClass(), Test_ThreadNameInformation(), TestThreadProc(), 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 946 of file kill.c.

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}
#define PtrToUlong(u)
Definition: config.h:107
VOID NTAPI PspExitThread(IN NTSTATUS ExitStatus)
Definition: kill.c:469
VOID NTAPI PspExitApcRundown(IN PKAPC Apc)
Definition: kill.c:157
_In_opt_ PVOID _In_opt_ PVOID _In_opt_ PVOID SystemArgument2
Definition: ketypes.h:757

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,
72 (ULONG_PTR)ImageName,
74 }
75}
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
Definition: Header.h:9
static const WCHAR Message[]
Definition: register.c:74
#define DbgPrint
Definition: hal.h:12
BOOLEAN KdDebuggerNotPresent
Definition: kddata.c:81
BOOLEAN KdDebuggerEnabled
Definition: kddata.c:82
NTSYSAPI ULONG NTAPI DbgPrompt(_In_z_ PCCH Prompt, _Out_writes_bytes_(MaximumResponseLength) PCH Response, _In_ ULONG MaximumResponseLength)
char CHAR
Definition: pedump.c:57
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
NTSYSAPI void WINAPI DbgBreakPoint(void)
_In_ BOOLEAN Handled
Definition: ketypes.h:401

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#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}
DECLSPEC_NORETURN VOID NTAPI KeBugCheck(ULONG BugCheckCode)
Definition: bug.c:1434
#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:1413
_Out_ PKAPC_STATE ApcState
Definition: mm.h:1751
VOID NTAPI PspExitProcess(IN BOOLEAN LastThread, IN PEPROCESS Process)
Definition: kill.c:1099
VOID NTAPI ObKillProcess(IN PEPROCESS Process)
Definition: obhandle.c:2186
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
#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
VOID NTAPI PspRemoveProcessFromJob(_In_ PEPROCESS Process)
Definition: job.c:609
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:164
#define TAG_PS_WOW64
Definition: tag.h:147
KAPC_STATE
Definition: ketypes.h:1727

Referenced by PspInitPhase0().

◆ PspDeleteThread()

VOID NTAPI PspDeleteThread ( IN PVOID  ObjectBody)

Definition at line 402 of file kill.c.

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}
FORCEINLINE VOID ExAcquirePushLockExclusive(PEX_PUSH_LOCK PushLock)
Definition: ex.h:1039
FORCEINLINE VOID ExReleasePushLockExclusive(PEX_PUSH_LOCK PushLock)
Definition: ex.h:1255
#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:1296
CLIENT_ID Cid
Definition: pstypes.h:1321
PUNICODE_STRING ThreadName
Definition: pstypes.h:1450
LIST_ENTRY ThreadListEntry
Definition: pstypes.h:1351
PVOID InitialStack
Definition: ketypes.h:1811
PVOID Win32Thread
Definition: ketypes.h:2013
PVOID StackBase
Definition: ketypes.h:1813
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
#define TAG_THREAD_NAME
Definition: tag.h:146

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 971 of file kill.c.

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}
#define UserMode
Definition: asm.h:39
@ OriginalApcEnvironment
Definition: ketypes.h:911
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:971
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
Definition: ketypes.h:615
KAPC_STATE ApcState
Definition: ketypes.h:1925
_In_opt_ PVOID _In_opt_ PVOID SystemArgument1
Definition: ketypes.h:756
struct _KAPC * PKAPC

Referenced by PspExitNormalApc(), and PspTerminateThreadByPointer().

◆ PspExitProcess()

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

Definition at line 1099 of file kill.c.

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}
#define VOID
Definition: acefi.h:82
#define FlagOn(_F, _SF)
Definition: ext2fs.h:179
#define PSF_PROCESS_EXITING_BIT
Definition: pstypes.h:301
#define JOB_OBJECT_MSG_EXIT_PROCESS
Definition: pstypes.h:254
#define InterlockedOr
Definition: interlocked.h:239
NTSYSAPI NTSTATUS NTAPI ZwSetTimerResolution(_In_ ULONG RequestedResolution, _In_ BOOLEAN SetOrUnset, _Out_ PULONG ActualResolution)
PVOID NTAPI ExEnterCriticalRegionAndAcquireResourceExclusive(IN PERESOURCE Resource)
Definition: resource.c:2194
VOID FASTCALL ExReleaseResourceAndLeaveCriticalRegion(IN PERESOURCE Resource)
Definition: resource.c:2283
VOID NTAPI MmCleanProcessAddressSpace(IN PEPROCESS Process)
Definition: procsup.c:1319
ULONG KeMaximumIncrement
Definition: clock.c:20
PETHREAD LastThread
Definition: pinsup.c:109
VOID NTAPI PopCleanupPowerState(IN PPOWER_STATE PowerState)
Definition: power.c:164
NTSTATUS NTAPI PspSendJobMessageLocked(_In_ PEJOB Job, _In_ ULONG Message, _In_opt_ PVOID CompletionValue, _In_ BOOLEAN Quota)
Definition: job.c:397
#define PSP_JOB_NOT_REALLY_ACTIVE
Definition: ps.h:111
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 469 of file kill.c.

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}
#define STATUS_NO_MEMORY
Definition: d3dkmdt.h:51
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:141
@ PsW32ThreadCalloutExit
Definition: pstypes.h:564
VOID NTAPI LpcExitThread(IN PETHREAD Thread)
Definition: close.c:19
#define LPC_CLIENT_DIED
Definition: port.c:98
#define KernelMode
Definition: asm.h:38
#define MEM_RELEASE
Definition: nt_native.h:1319
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 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:405
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:3411
BOOLEAN NTAPI KeIsAttachedProcess(VOID)
Definition: procobj.c:693
PKWIN32_THREAD_CALLOUT PspW32ThreadCallout
Definition: win32.c:19
PKWIN32_PROCESS_CALLOUT PspW32ProcessCallout
Definition: win32.c:18
VOID NTAPI PspExitProcessFromJob(_In_ PEPROCESS Process)
Definition: job.c:659
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:273
LARGE_INTEGER CreateTime
Definition: lpctypes.h:274
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
EX_RUNDOWN_REF RundownProtect
Definition: pstypes.h:1352
ULONG ActiveExWorker
Definition: pstypes.h:1393
LARGE_INTEGER CreateTime
Definition: pstypes.h:1297
ULONG BreakOnTermination
Definition: pstypes.h:1377
ULONG SystemThread
Definition: pstypes.h:1375
ULONG CombinedApcDisable
Definition: ketypes.h:2030
UCHAR ApcStateIndex
Definition: ketypes.h:2089
PVOID Teb
Definition: ketypes.h:1954
PVOID LegoData
Definition: ketypes.h:2144
ULONG EnableStackSwap
Definition: ketypes.h:1876
ULONG ApcQueueable
Definition: ketypes.h:1858
Definition: typedefs.h:120
Definition: compat.h:836
PVOID DbgSsReserved[2]
Definition: compat.h:883
PVOID DeallocationStack
Definition: compat.h:878
#define STATUS_PENDING
Definition: telnetd.h:14
VOID NTAPI KeTerminateThread(IN KPRIORITY Increment)
Definition: thrdobj.c:1348
ULONG_PTR SIZE_T
Definition: typedefs.h:80
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
@ Executive
Definition: ketypes.h:467

Referenced by PsExitSpecialApc(), and PspTerminateThreadByPointer().

◆ PspIsProcessExiting()

BOOLEAN NTAPI PspIsProcessExiting ( IN PEPROCESS  Process)

Definition at line 1092 of file kill.c.

1093{
1094 return Process->Flags & PSF_PROCESS_EXITING_BIT;
1095}

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:144
_In_ PIRP _In_ PIO_COMPLETION_ROUTINE _In_ PVOID Context
Definition: kse.h:81
LIST_ENTRY PspReaperListHead
Definition: kill.c:19
Definition: ntbasedef.h:640
struct _SINGLE_LIST_ENTRY * Next
Definition: ntbasedef.h:641

Referenced by PspInitPhase0().

◆ 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 PsShutdownSystem(), and PsTerminateProcess().

◆ PspTerminateThreadByPointer()

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

Definition at line 1012 of file kill.c.

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}
#define InterlockedExchange
Definition: armddk.h:54
_In_ D3DDDI_VIDEO_PRESENT_TARGET_ID _In_ ULONG _In_ ULONG Flags
Definition: dispmprt.h:245
#define ASSERT_IRQL_EQUAL(x)
Definition: debug.h:43
#define UlongToPtr(u)
Definition: config.h:106
#define CT_TERMINATED_BIT
Definition: pstypes.h:264
#define PspSetCrossThreadFlag(Thread, Flag)
Definition: ps_x.h:25
ULONG CrossThreadFlags
Definition: pstypes.h:1387
#define TAG_TERMINATE_APC
Definition: tag.h:141
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132

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

◆ PsShutdownSystem()

VOID NTAPI PsShutdownSystem ( 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:981
PEPROCESS NTAPI PsGetNextProcess(IN PEPROCESS OldProcess OPTIONAL)
PEPROCESS PsIdleProcess
Definition: psmgr.c:51
PEPROCESS PsInitialSystemProcess
Definition: psmgr.c:50

◆ 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(), ExpDebuggerWorker(), NtAssignProcessToJobObject(), PspAssignProcessToJob(), and PspTerminateProcessCallback().

◆ 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().