ReactOS 0.4.16-dev-2498-g8632030
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 1350 of file kill.c.

1351{
1353 PTERMINATION_PORT TerminationPort;
1354 PVOID TerminationLpcPort;
1356 PAGED_CODE();
1357 PSTRACE(PS_KILL_DEBUG, "PortHandle: %p\n", PortHandle);
1358
1359 /* Get the Port */
1360 Status = ObReferenceObjectByHandle(PortHandle,
1364 &TerminationLpcPort,
1365 NULL);
1366 if (!NT_SUCCESS(Status)) return(Status);
1367
1368 /* Allocate the Port and make sure it suceeded */
1369 TerminationPort = ExAllocatePoolWithTag(NonPagedPool,
1370 sizeof(TERMINATION_PORT),
1371 '=TsP');
1372 if(TerminationPort)
1373 {
1374 /* Associate the Port */
1376 TerminationPort->Port = TerminationLpcPort;
1377 TerminationPort->Next = Thread->TerminationPort;
1378 Thread->TerminationPort = TerminationPort;
1379
1380 /* Return success */
1381 return STATUS_SUCCESS;
1382 }
1383
1384 /* Dereference and Fail */
1385 ObDereferenceObject(TerminationLpcPort);
1387}
#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: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:1208
struct _TERMINATION_PORT * Next
Definition: pstypes.h:1169
#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 1169 of file kill.c.

1171{
1173 PEPROCESS Process, CurrentProcess = PsGetCurrentProcess();
1174 PETHREAD Thread, CurrentThread = PsGetCurrentThread();
1175 BOOLEAN KillByHandle;
1176 PAGED_CODE();
1178 "ProcessHandle: %p ExitStatus: %d\n", ProcessHandle, ExitStatus);
1179
1180 /* Were we passed a process handle? */
1181 if (ProcessHandle)
1182 {
1183 /* Yes we were, use it */
1184 KillByHandle = TRUE;
1185 }
1186 else
1187 {
1188 /* We weren't... we assume this is suicide */
1189 KillByHandle = FALSE;
1191 }
1192
1193 /* Get the Process Object */
1198 (PVOID*)&Process,
1199 NULL);
1200 if (!NT_SUCCESS(Status)) return(Status);
1201
1202 /* Check if this is a Critical Process, and Bugcheck */
1203 if (Process->BreakOnTermination)
1204 {
1205 /* Break to debugger */
1206 PspCatchCriticalBreak("Terminating critical process 0x%p (%s)\n",
1207 Process,
1208 Process->ImageFileName);
1209 }
1210
1211 /* Lock the Process */
1212 if (!ExAcquireRundownProtection(&Process->RundownProtect))
1213 {
1214 /* Failed to lock, fail */
1217 }
1218
1219 /* Set the delete flag, unless the process is comitting suicide */
1221
1222 /* Get the first thread */
1225 if (Thread)
1226 {
1227 /* We know we have at least a thread */
1229
1230 /* Loop and kill the others */
1231 do
1232 {
1233 /* Ensure it's not ours*/
1234 if (Thread != CurrentThread)
1235 {
1236 /* Kill it */
1238 }
1239
1240 /* Move to the next thread */
1242 } while (Thread);
1243 }
1244
1245 /* Unlock the process */
1246 ExReleaseRundownProtection(&Process->RundownProtect);
1247
1248 /* Check if we are killing ourselves */
1249 if (Process == CurrentProcess)
1250 {
1251 /* Also make sure the caller gave us our handle */
1252 if (KillByHandle)
1253 {
1254 /* Dereference the process */
1256
1257 /* Terminate ourselves */
1259 }
1260 }
1262 {
1263 /* Disable debugging on this process */
1265 }
1266
1267 /* Check if there was nothing to terminate, or if we have a Debug Port */
1269 ((Process->DebugPort) && (KillByHandle)))
1270 {
1271 /* Clear the handle table */
1273
1274 /* Return status now */
1276 }
1277
1278 /* Decrease the reference count we added */
1280
1281 /* Return status */
1282 return Status;
1283}
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:158
#define PSF_PROCESS_DELETE_BIT
Definition: pstypes.h:277
_In_ HANDLE ProcessHandle
Definition: mmfuncs.h:403
_In_ NTSTATUS ExitStatus
Definition: psfuncs.h:868
#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:996
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: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 1287 of file kill.c.

1289{
1291 PETHREAD CurrentThread = PsGetCurrentThread();
1293 PAGED_CODE();
1295 "ThreadHandle: %p ExitStatus: %d\n", ThreadHandle, ExitStatus);
1296
1297 /* Handle the special NULL case */
1298 if (!ThreadHandle)
1299 {
1300 /* Check if we're the only thread left */
1301 if (PsGetCurrentProcess()->ActiveThreads == 1)
1302 {
1303 /* This is invalid */
1305 }
1306
1307 /* Terminate us directly */
1308 goto TerminateSelf;
1309 }
1310 else if (ThreadHandle == NtCurrentThread())
1311 {
1312TerminateSelf:
1313 /* Terminate this thread */
1314 return PspTerminateThreadByPointer(CurrentThread,
1315 ExitStatus,
1316 TRUE);
1317 }
1318
1319 /* We are terminating another thread, get the Thread Object */
1320 Status = ObReferenceObjectByHandle(ThreadHandle,
1324 (PVOID*)&Thread,
1325 NULL);
1326 if (!NT_SUCCESS(Status)) return Status;
1327
1328 /* Check to see if we're running in the same thread */
1329 if (Thread != CurrentThread)
1330 {
1331 /* Terminate it */
1333
1334 /* Dereference the Thread and return */
1336 }
1337 else
1338 {
1339 /* Dereference the thread and terminate ourselves */
1341 goto TerminateSelf;
1342 }
1343
1344 /* Return status */
1345 return Status;
1346}
#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:5368

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

935{
937 PAGED_CODE();
939 "Apc: %p SystemArgument2: %p\n", Apc, SystemArgument2);
940
941 /* Don't do anything unless we are in User-Mode */
942 if (Apc->SystemArgument2)
943 {
944 /* Free the APC */
945 Status = PtrToUlong(Apc->NormalContext);
947
948 /* Terminate the Thread */
950 }
951}
#define PtrToUlong(u)
Definition: config.h:107
VOID NTAPI PspExitThread(IN NTSTATUS ExitStatus)
Definition: kill.c:458
VOID NTAPI PspExitApcRundown(IN PKAPC Apc)
Definition: kill.c:157
_In_opt_ PVOID _In_opt_ PVOID _In_opt_ PVOID SystemArgument2
Definition: ketypes.h:741

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}
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
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)
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
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: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:1357
_Out_ PKAPC_STATE ApcState
Definition: mm.h:1769
VOID NTAPI PspExitProcess(IN BOOLEAN LastThread, IN PEPROCESS Process)
Definition: kill.c:1083
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:1711

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 impersonation information */
421
422 /* Free the thread name if set */
423 if (Thread->ThreadName)
424 {
427 }
428
429 /* Make sure the thread was inserted, before continuing */
430 if (!Process)
431 return;
432
433 /* Check if the thread list is valid */
435 {
436 /* Lock the thread's process */
438 ExAcquirePushLockExclusive(&Process->ProcessLock);
439
440 /* Remove us from the list */
442
443 /* Release the lock */
444 ExReleasePushLockExclusive(&Process->ProcessLock);
446 }
447
448 /* Dereference the Process */
450}
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:1192
CLIENT_ID Cid
Definition: pstypes.h:1217
PUNICODE_STRING ThreadName
Definition: pstypes.h:1346
LIST_ENTRY ThreadListEntry
Definition: pstypes.h:1247
PVOID InitialStack
Definition: ketypes.h:1792
PVOID Win32Thread
Definition: ketypes.h:1994
PVOID StackBase
Definition: ketypes.h:1794
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
#define TAG_THREAD_NAME
Definition: tag.h:139

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

958{
961 PAGED_CODE();
962 PSTRACE(PS_KILL_DEBUG, "SystemArgument2: %p\n", SystemArgument2);
963
964 /* This should never happen */
966
967 /* If we're here, this is not a System Thread, so kill it from User-Mode */
968 KeInitializeApc(Apc,
969 &Thread->Tcb,
974 UserMode,
975 NormalContext);
976
977 /* Now insert the APC with the User-Mode Flag */
978 if (!(KeInsertQueueApc(Apc,
979 Apc,
981 2)))
982 {
983 /* Failed to insert, free the APC */
985 }
986
987 /* Set the APC Pending flag */
988 Thread->Tcb.ApcState.UserApcPending = TRUE;
989}
#define UserMode
Definition: asm.h:39
@ OriginalApcEnvironment
Definition: ketypes.h:892
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:955
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:930
Definition: ketypes.h:599
KAPC_STATE ApcState
Definition: ketypes.h:1906
_In_opt_ PVOID _In_opt_ PVOID SystemArgument1
Definition: ketypes.h:740
struct _KAPC * PKAPC

Referenced by PspExitNormalApc(), and PspTerminateThreadByPointer().

◆ PspExitProcess()

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

Definition at line 1083 of file kill.c.

1085{
1086 ULONG Actual;
1087 PAGED_CODE();
1089 "LastThread: %u Process: %p\n", LastThread, Process);
1091
1092 /* Set Process Exit flag */
1094
1095 /* Check if we are the last thread */
1096 if (LastThread)
1097 {
1098 /* Notify the WMI Process Callback */
1099 //WmiTraceProcess(Process, FALSE);
1100
1101 /* Run the Notification Routines */
1103 }
1104
1105 /* Cleanup the power state */
1106 PopCleanupPowerState((PPOWER_STATE)&Process->Pcb.PowerState);
1107
1108 /* Clear the security port */
1109 if (!Process->SecurityPort)
1110 {
1111 /* So we don't double-dereference */
1112 Process->SecurityPort = (PVOID)1;
1113 }
1114 else if (Process->SecurityPort != (PVOID)1)
1115 {
1116 /* Dereference it */
1117 ObDereferenceObject(Process->SecurityPort);
1118 Process->SecurityPort = (PVOID)1;
1119 }
1120
1121 /* Check if we are the last thread */
1122 if (LastThread)
1123 {
1124 /* Check if we have to set the Timer Resolution */
1125 if (Process->SetTimerResolution)
1126 {
1127 /* Set it to default */
1129 }
1130
1131 /* Check if we are part of a Job that has a completion port */
1132 if ((Process->Job) && (Process->Job->CompletionPort))
1133 {
1134 /* FIXME: Check job status code and do I/O completion if needed */
1135 }
1136
1137 /* FIXME: Notify the Prefetcher */
1138 }
1139 else
1140 {
1141 /* Clear process' address space here */
1143 }
1144}
#define PSF_PROCESS_EXITING_BIT
Definition: pstypes.h:276
#define InterlockedOr
Definition: interlocked.h:239
NTSYSAPI NTSTATUS NTAPI ZwSetTimerResolution(_In_ ULONG RequestedResolution, _In_ BOOLEAN SetOrUnset, _Out_ PULONG ActualResolution)
VOID NTAPI MmCleanProcessAddressSpace(IN PEPROCESS Process)
Definition: procsup.c:1263
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 458 of file kill.c.

459{
460 CLIENT_DIED_MSG TerminationMsg;
462 PTEB Teb;
463 PEPROCESS CurrentProcess;
464 PETHREAD Thread, OtherThread, PreviousThread = NULL;
465 PVOID DeallocationStack;
466 SIZE_T Dummy;
467 BOOLEAN Last = FALSE;
468 PTERMINATION_PORT TerminationPort, NextPort;
469 PLIST_ENTRY FirstEntry, CurrentEntry;
470 PKAPC Apc;
471 PTOKEN PrimaryToken;
472 PAGED_CODE();
473 PSTRACE(PS_KILL_DEBUG, "ExitStatus: %d\n", ExitStatus);
474
475 /* Get the Current Thread and Process */
477 CurrentProcess = Thread->ThreadsProcess;
479
480 /* Can't terminate a thread if it attached another process */
482 {
483 /* Bugcheck */
484 KeBugCheckEx(INVALID_PROCESS_ATTACH_ATTEMPT,
485 (ULONG_PTR)CurrentProcess,
486 (ULONG_PTR)Thread->Tcb.ApcState.Process,
489 }
490
491 /* Lower to Passive Level */
493
494 /* Can't be a worker thread */
496 {
497 /* Bugcheck */
498 KeBugCheckEx(ACTIVE_EX_WORKER_THREAD_TERMINATION,
500 0,
501 0,
502 0);
503 }
504
505 /* Can't have pending APCs */
506 if (Thread->Tcb.CombinedApcDisable != 0)
507 {
508 /* Bugcheck */
509 KeBugCheckEx(KERNEL_APC_PENDING_DURING_EXIT,
510 0,
512 0,
513 1);
514 }
515
516 /* Lock the thread */
518
519 /* Cleanup the power state */
521
522 /* Call the WMI Callback for Threads */
523 //WmiTraceThread(Thread, NULL, FALSE);
524
525 /* Run Thread Notify Routines before we desintegrate the thread */
527
528 /* Lock the Process before we modify its thread entries */
530 ExAcquirePushLockExclusive(&CurrentProcess->ProcessLock);
531
532 /* Decrease the active thread count, and check if it's 0 */
533 if (!(--CurrentProcess->ActiveThreads))
534 {
535 /* Set the delete flag */
537
538 /* Remember we are last */
539 Last = TRUE;
540
541 /* Check if this termination is due to the thread dying */
543 {
544 /* Check if the last thread was pending */
545 if (CurrentProcess->ExitStatus == STATUS_PENDING)
546 {
547 /* Use the last exit status */
548 CurrentProcess->ExitStatus = CurrentProcess->
549 LastThreadExitStatus;
550 }
551 }
552 else
553 {
554 /* Just a normal exit, write the code */
555 CurrentProcess->ExitStatus = ExitStatus;
556 }
557
558 /* Loop all the current threads */
559 FirstEntry = &CurrentProcess->ThreadListHead;
560 CurrentEntry = FirstEntry->Flink;
561 while (FirstEntry != CurrentEntry)
562 {
563 /* Get the thread on the list */
564 OtherThread = CONTAINING_RECORD(CurrentEntry,
565 ETHREAD,
566 ThreadListEntry);
567
568 /* Check if it's a thread that's still alive */
569 if ((OtherThread != Thread) &&
570 !(KeReadStateThread(&OtherThread->Tcb)) &&
571 (ObReferenceObjectSafe(OtherThread)))
572 {
573 /* It's a live thread and we referenced it, unlock process */
574 ExReleasePushLockExclusive(&CurrentProcess->ProcessLock);
576
577 /* Wait on the thread */
578 KeWaitForSingleObject(OtherThread,
579 Executive,
581 FALSE,
582 NULL);
583
584 /* Check if we had a previous thread to dereference */
585 if (PreviousThread) ObDereferenceObject(PreviousThread);
586
587 /* Remember the thread and re-lock the process */
588 PreviousThread = OtherThread;
590 ExAcquirePushLockExclusive(&CurrentProcess->ProcessLock);
591 }
592
593 /* Go to the next thread */
594 CurrentEntry = CurrentEntry->Flink;
595 }
596 }
598 {
599 /* Write down the exit status of the last thread to get killed */
600 CurrentProcess->LastThreadExitStatus = ExitStatus;
601 }
602
603 /* Unlock the Process */
604 ExReleasePushLockExclusive(&CurrentProcess->ProcessLock);
606
607 /* Check if we had a previous thread to dereference */
608 if (PreviousThread) ObDereferenceObject(PreviousThread);
609
610 /* Check if the process has a debug port and if this is a user thread */
611 if ((CurrentProcess->DebugPort) && !(Thread->SystemThread))
612 {
613 /* Notify the Debug API. */
614 Last ? DbgkExitProcess(CurrentProcess->ExitStatus) :
616 }
617
618 /* Check if this is a Critical Thread */
620 {
621 /* Break to debugger */
622 PspCatchCriticalBreak("Critical thread 0x%p (in %s) exited\n",
623 Thread,
624 CurrentProcess->ImageFileName);
625 }
626
627 /* Check if it's the last thread and this is a Critical Process */
628 if ((Last) && (CurrentProcess->BreakOnTermination))
629 {
630 /* Check if a debugger is here to handle this */
632 {
633 /* Break to debugger */
634 PspCatchCriticalBreak("Critical process 0x%p (%s) exited\n",
635 CurrentProcess,
636 CurrentProcess->ImageFileName);
637 }
638 else
639 {
640 /* Bugcheck, we can't allow this */
641 KeBugCheckEx(CRITICAL_PROCESS_DIED,
642 (ULONG_PTR)CurrentProcess,
643 0,
644 0,
645 0);
646 }
647 }
648
649 /* Sanity check */
651
652 /* Process the Termination Ports */
653 TerminationPort = Thread->TerminationPort;
654 if (TerminationPort)
655 {
656 /* Setup the message header */
657 TerminationMsg.h.u2.ZeroInit = 0;
658 TerminationMsg.h.u2.s2.Type = LPC_CLIENT_DIED;
659 TerminationMsg.h.u1.s1.TotalLength = sizeof(TerminationMsg);
660 TerminationMsg.h.u1.s1.DataLength = sizeof(TerminationMsg) -
661 sizeof(PORT_MESSAGE);
662
663 /* Loop each port */
664 do
665 {
666 /* Save the Create Time */
667 TerminationMsg.CreateTime = Thread->CreateTime;
668
669 /* Loop trying to send message */
670 while (TRUE)
671 {
672 /* Send the LPC Message */
673 Status = LpcRequestPort(TerminationPort->Port,
674 &TerminationMsg.h);
675 if ((Status == STATUS_NO_MEMORY) ||
677 {
678 /* Wait a bit and try again */
680 continue;
681 }
682 break;
683 }
684
685 /* Dereference this LPC Port */
686 ObDereferenceObject(TerminationPort->Port);
687
688 /* Move to the next one */
689 NextPort = TerminationPort->Next;
690
691 /* Free the Termination Port Object */
692 ExFreePoolWithTag(TerminationPort, '=TsP');
693
694 /* Keep looping as long as there is a port */
695 TerminationPort = NextPort;
696 } while (TerminationPort);
697 }
699 (Thread->DeadThread)) ||
700 !(Thread->DeadThread))
701 {
702 /*
703 * This case is special and deserves some extra comments. What
704 * basically happens here is that this thread doesn't have a termination
705 * port, which means that it died before being fully created. Since we
706 * still have to notify an LPC Server, we'll use the exception port,
707 * which we know exists. However, we need to know how far the thread
708 * actually got created. We have three possibilities:
709 *
710 * - NtCreateThread returned an error really early: DeadThread is set.
711 * - NtCreateThread managed to create the thread: DeadThread is off.
712 * - NtCreateThread was creating the thread (with DeadThread set,
713 * but the thread got killed prematurely: STATUS_THREAD_IS_TERMINATING
714 * is our exit code.)
715 *
716 * For the 2 & 3rd scenarios, the thread has been created far enough to
717 * warrant notification to the LPC Server.
718 */
719
720 /* Setup the message header */
721 TerminationMsg.h.u2.ZeroInit = 0;
722 TerminationMsg.h.u2.s2.Type = LPC_CLIENT_DIED;
723 TerminationMsg.h.u1.s1.TotalLength = sizeof(TerminationMsg);
724 TerminationMsg.h.u1.s1.DataLength = sizeof(TerminationMsg) -
725 sizeof(PORT_MESSAGE);
726
727 /* Make sure the process has an exception port */
728 if (CurrentProcess->ExceptionPort)
729 {
730 /* Save the Create Time */
731 TerminationMsg.CreateTime = Thread->CreateTime;
732
733 /* Loop trying to send message */
734 while (TRUE)
735 {
736 /* Send the LPC Message */
737 Status = LpcRequestPort(CurrentProcess->ExceptionPort,
738 &TerminationMsg.h);
739 if ((Status == STATUS_NO_MEMORY) ||
741 {
742 /* Wait a bit and try again */
744 continue;
745 }
746 break;
747 }
748 }
749 }
750
751 /* Rundown Win32 Thread if there is one */
754
755 /* If we are the last thread and have a W32 Process */
756 if ((Last) && (CurrentProcess->Win32Process))
757 {
758 /* Run it down too */
759 PspW32ProcessCallout(CurrentProcess, FALSE);
760 }
761
762 /* Make sure Stack Swap is enabled */
764 {
765 /* Stack swap really shouldn't be disabled during exit! */
766 KeBugCheckEx(KERNEL_STACK_LOCKED_AT_EXIT, 0, 0, 0, 0);
767 }
768
769 /* Cancel I/O for the thread. */
771
772 /* Rundown Timers */
774
775 /* FIXME: Rundown Registry Notifications (NtChangeNotify)
776 CmNotifyRunDown(Thread); */
777
778 /* Rundown Mutexes */
780
781 /* Check if we have a TEB */
782 Teb = Thread->Tcb.Teb;
783 if (Teb)
784 {
785 /* Check if the thread is still alive */
786 if (!Thread->DeadThread)
787 {
788 /* Check if we need to free its stack */
789 if (Teb->FreeStackOnTermination)
790 {
791 /* Set the TEB's Deallocation Stack as the Base Address */
792 Dummy = 0;
793 DeallocationStack = Teb->DeallocationStack;
794
795 /* Free the Thread's Stack */
796 ZwFreeVirtualMemory(NtCurrentProcess(),
797 &DeallocationStack,
798 &Dummy,
800 }
801
802 /* Free the debug handle */
803 if (Teb->DbgSsReserved[1]) ObCloseHandle(Teb->DbgSsReserved[1],
804 UserMode);
805 }
806
807 /* Decommit the TEB */
808 MmDeleteTeb(CurrentProcess, Teb);
809 Thread->Tcb.Teb = NULL;
810 }
811
812 /* Free LPC Data */
814
815 /* Save the exit status and exit time */
818
819 /* Sanity check */
821
822 /* Check if this is the final thread or not */
823 if (Last)
824 {
825 /* Set the process exit time */
826 CurrentProcess->ExitTime = Thread->ExitTime;
827
828 /* Exit the process */
829 PspExitProcess(TRUE, CurrentProcess);
830
831 /* Get the process token and check if we need to audit */
832 PrimaryToken = PsReferencePrimaryToken(CurrentProcess);
833 if (SeDetailedAuditingWithToken(PrimaryToken))
834 {
835 /* Audit the exit */
836 SeAuditProcessExit(CurrentProcess);
837 }
838
839 /* Dereference the process token */
840 ObFastDereferenceObject(&CurrentProcess->Token, PrimaryToken);
841
842 /* Check if this is a VDM Process and rundown the VDM DPCs if so */
843 if (CurrentProcess->VdmObjects) { /* VdmRundownDpcs(CurrentProcess); */ }
844
845 /* Kill the process in the Object Manager */
846 ObKillProcess(CurrentProcess);
847
848 /* Check if we have a section object */
849 if (CurrentProcess->SectionObject)
850 {
851 /* Dereference and clear the Section Object */
852 ObDereferenceObject(CurrentProcess->SectionObject);
853 CurrentProcess->SectionObject = NULL;
854 }
855
856 /* Check if the process is part of a job */
857 if (CurrentProcess->Job)
858 {
859 /* Remove the process from the job */
860 PspExitProcessFromJob(CurrentProcess->Job, CurrentProcess);
861 }
862 }
863
864 /* Disable APCs */
866
867 /* Disable APC queueing, force a resumption */
870
871 /* Re-enable APCs */
873
874 /* Flush the User APCs */
875 FirstEntry = KeFlushQueueApc(&Thread->Tcb, UserMode);
876 if (FirstEntry)
877 {
878 /* Start with the first entry */
879 CurrentEntry = FirstEntry;
880 do
881 {
882 /* Get the APC */
883 Apc = CONTAINING_RECORD(CurrentEntry, KAPC, ApcListEntry);
884
885 /* Move to the next one */
886 CurrentEntry = CurrentEntry->Flink;
887
888 /* Rundown the APC or de-allocate it */
889 if (Apc->RundownRoutine)
890 {
891 /* Call its own routine */
892 Apc->RundownRoutine(Apc);
893 }
894 else
895 {
896 /* Do it ourselves */
897 ExFreePool(Apc);
898 }
899 }
900 while (CurrentEntry != FirstEntry);
901 }
902
903 /* Clean address space if this was the last thread */
904 if (Last) MmCleanProcessAddressSpace(CurrentProcess);
905
906 /* Call the Lego routine */
908
909 /* Flush the APC queue, which should be empty */
910 FirstEntry = KeFlushQueueApc(&Thread->Tcb, KernelMode);
911 if ((FirstEntry) || (Thread->Tcb.CombinedApcDisable != 0))
912 {
913 /* Bugcheck time */
914 KeBugCheckEx(KERNEL_APC_PENDING_DURING_EXIT,
915 (ULONG_PTR)FirstEntry,
918 0);
919 }
920
921 /* Signal the process if this was the last thread */
922 if (Last) KeSetProcess(&CurrentProcess->Pcb, 0, FALSE);
923
924 /* Terminate the Thread from the Scheduler */
926}
#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:539
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: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: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: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:1398
LIST_ENTRY ThreadListHead
Definition: pstypes.h:1423
PVOID VdmObjects
Definition: pstypes.h:1406
NTSTATUS ExitStatus
Definition: pstypes.h:1531
PVOID DebugPort
Definition: pstypes.h:1369
KPROCESS Pcb
Definition: pstypes.h:1356
EX_FAST_REF Token
Definition: pstypes.h:1381
struct _EJOB * Job
Definition: pstypes.h:1397
EX_PUSH_LOCK ProcessLock
Definition: pstypes.h:1357
ULONG Flags
Definition: pstypes.h:1529
PVOID * Win32Process
Definition: pstypes.h:1396
NTSTATUS LastThreadExitStatus
Definition: pstypes.h:1437
CHAR ImageFileName[16]
Definition: pstypes.h:1420
LARGE_INTEGER ExitTime
Definition: pstypes.h:1359
ULONG BreakOnTermination
Definition: pstypes.h:1499
ULONG ActiveThreads
Definition: pstypes.h:1430
LARGE_INTEGER ExitTime
Definition: pstypes.h:1196
NTSTATUS ExitStatus
Definition: pstypes.h:1202
EX_RUNDOWN_REF RundownProtect
Definition: pstypes.h:1248
ULONG ActiveExWorker
Definition: pstypes.h:1289
LARGE_INTEGER CreateTime
Definition: pstypes.h:1193
ULONG BreakOnTermination
Definition: pstypes.h:1273
ULONG SystemThread
Definition: pstypes.h:1271
ULONG CombinedApcDisable
Definition: ketypes.h:2011
UCHAR ApcStateIndex
Definition: ketypes.h:2070
PVOID Teb
Definition: ketypes.h:1935
PVOID LegoData
Definition: ketypes.h:2125
ULONG EnableStackSwap
Definition: ketypes.h:1857
ULONG ApcQueueable
Definition: ketypes.h:1839
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 1076 of file kill.c.

1077{
1078 return Process->Flags & PSF_PROCESS_EXITING_BIT;
1079}

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
LIST_ENTRY PspReaperListHead
Definition: kill.c:19
_In_ PVOID Context
Definition: storport.h:2269
Definition: ntbasedef.h:640
struct _SINGLE_LIST_ENTRY * Next
Definition: ntbasedef.h:641

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:981
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 996 of file kill.c.

999{
1000 PKAPC Apc;
1002 ULONG Flags;
1003 PAGED_CODE();
1004 PSTRACE(PS_KILL_DEBUG, "Thread: %p ExitStatus: %d\n", Thread, ExitStatus);
1006
1007 /* Check if this is a Critical Thread, and Bugcheck */
1009 {
1010 /* Break to debugger */
1011 PspCatchCriticalBreak("Terminating critical thread 0x%p (in %s)\n",
1012 Thread,
1013 Thread->ThreadsProcess->ImageFileName);
1014 }
1015
1016 /* Check if we are already inside the thread */
1017 if ((bSelf) || (PsGetCurrentThread() == Thread))
1018 {
1019 /* This should only happen at passive */
1021
1022 /* Mark it as terminated */
1024
1025 /* Directly terminate the thread */
1027 }
1028
1029 /* This shouldn't be a system thread */
1031
1032 /* Allocate the APC */
1034 if (!Apc) return STATUS_INSUFFICIENT_RESOURCES;
1035
1036 /* Set the Terminated Flag */
1038
1039 /* Set it, and check if it was already set while we were running */
1042 {
1043 /* Initialize a Kernel Mode APC to Kill the Thread */
1044 KeInitializeApc(Apc,
1045 &Thread->Tcb,
1050 KernelMode,
1052
1053 /* Insert it into the APC Queue */
1054 if (!KeInsertQueueApc(Apc, Apc, NULL, 2))
1055 {
1056 /* The APC was already in the queue, fail */
1058 }
1059 else
1060 {
1061 /* Forcefully resume the thread and return */
1063 return Status;
1064 }
1065 }
1066
1067 /* We failed, free the APC */
1069
1070 /* Return Status */
1071 return Status;
1072}
#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:239
#define PspSetCrossThreadFlag(Thread, Flag)
Definition: ps_x.h:25
ULONG CrossThreadFlags
Definition: pstypes.h:1283
#define TAG_TERMINATE_APC
Definition: tag.h:134
#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().