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
);
84 NTSTATUS STDCALL
NtTerminateProcess(IN HANDLE ProcessHandle
,
85 IN NTSTATUS ExitStatus
)
91 DPRINT("NtTerminateProcess(ProcessHandle %x, ExitStatus %x)\n",
92 ProcessHandle
, ExitStatus
);
94 Status
= ObReferenceObjectByHandle(ProcessHandle
,
100 if (Status
!= STATUS_SUCCESS
)
105 PiTerminateProcessThreads(Process
, ExitStatus
);
106 KeRaiseIrql(DISPATCH_LEVEL
, &oldlvl
);
107 Process
->Pcb
.ProcessState
= PROCESS_STATE_TERMINATED
;
108 Process
->Pcb
.DispatcherHeader
.SignalState
= TRUE
;
109 KeDispatcherObjectWake(&Process
->Pcb
.DispatcherHeader
);
110 if (PsGetCurrentThread()->ThreadsProcess
== Process
)
113 ObDereferenceObject(Process
);
114 PsTerminateCurrentThread(ExitStatus
);
117 ObDereferenceObject(Process
);
118 return(STATUS_SUCCESS
);
122 NTSTATUS STDCALL
NtTerminateThread(IN HANDLE ThreadHandle
,
123 IN NTSTATUS ExitStatus
)
128 Status
= ObReferenceObjectByHandle(ThreadHandle
,
134 if (Status
!= STATUS_SUCCESS
)
139 if (Thread
== PsGetCurrentThread())
141 PsTerminateCurrentThread(ExitStatus
);
145 PsTerminateOtherThread(Thread
, ExitStatus
);
147 return(STATUS_SUCCESS
);
151 NTSTATUS
PsTerminateSystemThread(NTSTATUS ExitStatus
)
153 * FUNCTION: Terminates the current thread
155 * ExitStatus = Status to pass to the creater
159 PsTerminateCurrentThread(ExitStatus
);
160 return(STATUS_SUCCESS
);
164 NTSTATUS STDCALL
NtRegisterThreadTerminatePort(HANDLE TerminationPort
)