2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * FILE: ntoskrnl/ps/kill.c
5 * PURPOSE: Terminating a thread
6 * PROGRAMMER: David Welch (welch@cwcom.net)
11 /* INCLUDES *****************************************************************/
13 #include <ddk/ntddk.h>
14 #include <internal/ps.h>
15 #include <internal/ke.h>
16 #include <internal/mm.h>
17 #include <internal/ob.h>
20 #include <internal/debug.h>
22 /* GLOBALS *******************************************************************/
24 extern ULONG PiNrThreads
;
25 extern ULONG PiNrRunnableThreads
;
26 extern KSPIN_LOCK PiThreadListLock
;
28 /* FUNCTIONS *****************************************************************/
30 VOID
PsTerminateCurrentThread(NTSTATUS ExitStatus
)
32 * FUNCTION: Terminates the current thread
36 PETHREAD CurrentThread
;
40 CurrentThread
= PsGetCurrentThread();
42 CurrentThread
->ExitStatus
= ExitStatus
;
44 DPRINT("terminating %x\n",CurrentThread
);
45 ObDereferenceObject(CurrentThread
->ThreadsProcess
);
46 CurrentThread
->ThreadsProcess
= NULL
;
47 KeRaiseIrql(DISPATCH_LEVEL
,&oldlvl
);
49 ObDereferenceObject(CurrentThread
);
50 DPRINT("ObGetReferenceCount(CurrentThread) %d\n",
51 ObGetReferenceCount(CurrentThread
));
53 CurrentThread
->Tcb
.DispatcherHeader
.SignalState
= TRUE
;
54 KeDispatcherObjectWake(&CurrentThread
->Tcb
.DispatcherHeader
);
56 PsDispatchThread(THREAD_STATE_TERMINATED
);
60 VOID
PsTerminateOtherThread(PETHREAD Thread
, NTSTATUS ExitStatus
)
62 * FUNCTION: Terminate a thread when calling from that thread's context
67 KeAcquireSpinLock(&PiThreadListLock
, &oldIrql
);
69 if (Thread
->Tcb
.State
== THREAD_STATE_RUNNABLE
)
71 PiNrRunnableThreads
--;
72 RemoveEntryList(&Thread
->Tcb
.QueueListEntry
);
74 Thread
->Tcb
.State
= THREAD_STATE_TERMINATED
;
75 Thread
->Tcb
.DispatcherHeader
.SignalState
= TRUE
;
76 KeDispatcherObjectWake(&Thread
->Tcb
.DispatcherHeader
);
77 ObDereferenceObject(Thread
->ThreadsProcess
);
78 ObDereferenceObject(Thread
);
79 Thread
->ThreadsProcess
= NULL
;
80 KeReleaseSpinLock(&PiThreadListLock
, oldIrql
);
83 NTSTATUS STDCALL
PiTerminateProcess(PEPROCESS Process
,
88 DPRINT("PsTerminateProcess(Process %x, ExitStatus %x)\n",
91 PiTerminateProcessThreads(Process
, ExitStatus
);
92 KeRaiseIrql(DISPATCH_LEVEL
, &oldlvl
);
93 Process
->Pcb
.ProcessState
= PROCESS_STATE_TERMINATED
;
94 Process
->Pcb
.DispatcherHeader
.SignalState
= TRUE
;
95 KeDispatcherObjectWake(&Process
->Pcb
.DispatcherHeader
);
97 return(STATUS_SUCCESS
);
100 NTSTATUS STDCALL
NtTerminateProcess(IN HANDLE ProcessHandle
,
101 IN NTSTATUS ExitStatus
)
106 DPRINT("NtTerminateProcess(ProcessHandle %x, ExitStatus %x)\n",
107 ProcessHandle
, ExitStatus
);
109 Status
= ObReferenceObjectByHandle(ProcessHandle
,
115 if (Status
!= STATUS_SUCCESS
)
120 PiTerminateProcess(Process
, ExitStatus
);
121 if (PsGetCurrentThread()->ThreadsProcess
== Process
)
123 ObDereferenceObject(Process
);
124 PsTerminateCurrentThread(ExitStatus
);
126 ObDereferenceObject(Process
);
127 return(STATUS_SUCCESS
);
131 NTSTATUS STDCALL
NtTerminateThread(IN HANDLE ThreadHandle
,
132 IN NTSTATUS ExitStatus
)
137 Status
= ObReferenceObjectByHandle(ThreadHandle
,
143 if (Status
!= STATUS_SUCCESS
)
148 if (Thread
== PsGetCurrentThread())
150 PsTerminateCurrentThread(ExitStatus
);
154 PsTerminateOtherThread(Thread
, ExitStatus
);
156 return(STATUS_SUCCESS
);
160 NTSTATUS
PsTerminateSystemThread(NTSTATUS ExitStatus
)
162 * FUNCTION: Terminates the current thread
164 * ExitStatus = Status to pass to the creater
168 PsTerminateCurrentThread(ExitStatus
);
169 return(STATUS_SUCCESS
);
173 NTSTATUS STDCALL
NtRegisterThreadTerminatePort(HANDLE TerminationPort
)