Fixed header inclusion order.
[reactos.git] / reactos / ntoskrnl / ps / kill.c
1 /*
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)
7 * UPDATE HISTORY:
8 * Created 22/05/98
9 */
10
11 /* INCLUDES *****************************************************************/
12
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>
18
19 #define NDEBUG
20 #include <internal/debug.h>
21
22 /* GLOBALS *******************************************************************/
23
24 extern ULONG PiNrThreads;
25
26 /* FUNCTIONS *****************************************************************/
27
28 VOID PsTerminateCurrentThread(NTSTATUS ExitStatus)
29 /*
30 * FUNCTION: Terminates the current thread
31 */
32 {
33 KIRQL oldlvl;
34 PETHREAD CurrentThread;
35
36 PiNrThreads--;
37
38 CurrentThread = PsGetCurrentThread();
39
40 CurrentThread->ExitStatus = ExitStatus;
41
42 DPRINT("terminating %x\n",CurrentThread);
43 ObDereferenceObject(CurrentThread->ThreadsProcess);
44 CurrentThread->ThreadsProcess = NULL;
45 KeRaiseIrql(DISPATCH_LEVEL,&oldlvl);
46 CurrentThread->Tcb.State = THREAD_STATE_TERMINATED;
47 CurrentThread->Tcb.DispatcherHeader.SignalState = TRUE;
48 KeDispatcherObjectWake(&CurrentThread->Tcb.DispatcherHeader);
49 ZwYieldExecution();
50 for(;;);
51 }
52
53 VOID PsTerminateOtherThread(PETHREAD Thread, NTSTATUS ExitStatus)
54 /*
55 * FUNCTION: Terminate a thread when calling from that thread's context
56 */
57 {
58 KIRQL oldlvl;
59
60 PiNrThreads--;
61 KeRaiseIrql(DISPATCH_LEVEL, &oldlvl);
62 Thread->Tcb.State = THREAD_STATE_TERMINATED;
63 Thread->Tcb.DispatcherHeader.SignalState = TRUE;
64 KeDispatcherObjectWake(&Thread->Tcb.DispatcherHeader);
65 ObDereferenceObject(Thread->ThreadsProcess);
66 Thread->ThreadsProcess = NULL;
67 KeLowerIrql(oldlvl);
68 }
69
70
71 NTSTATUS
72 STDCALL
73 NtTerminateProcess (
74 IN HANDLE ProcessHandle,
75 IN NTSTATUS ExitStatus
76 )
77 {
78 NTSTATUS Status;
79 PEPROCESS Process;
80 KIRQL oldlvl;
81
82 DPRINT("NtTerminateProcess(ProcessHandle %x, ExitStatus %x)\n",
83 ProcessHandle, ExitStatus);
84
85 Status = ObReferenceObjectByHandle(ProcessHandle,
86 PROCESS_TERMINATE,
87 PsProcessType,
88 UserMode,
89 (PVOID*)&Process,
90 NULL);
91 if (Status != STATUS_SUCCESS)
92 {
93 return(Status);
94 }
95
96 PiTerminateProcessThreads(Process, ExitStatus);
97 KeRaiseIrql(DISPATCH_LEVEL, &oldlvl);
98 Process->Pcb.ProcessState = PROCESS_STATE_TERMINATED;
99 Process->Pcb.DispatcherHeader.SignalState = TRUE;
100 KeDispatcherObjectWake(&Process->Pcb.DispatcherHeader);
101 if (PsGetCurrentThread()->ThreadsProcess == Process)
102 {
103 KeLowerIrql(oldlvl);
104 ObDereferenceObject(Process);
105 PsTerminateCurrentThread(ExitStatus);
106 }
107 KeLowerIrql(oldlvl);
108 ObDereferenceObject(Process);
109 return(STATUS_SUCCESS);
110 }
111
112
113 NTSTATUS
114 STDCALL
115 NtTerminateThread (
116 IN HANDLE ThreadHandle,
117 IN NTSTATUS ExitStatus
118 )
119 {
120 PETHREAD Thread;
121 NTSTATUS Status;
122
123 Status = ObReferenceObjectByHandle(ThreadHandle,
124 THREAD_TERMINATE,
125 PsThreadType,
126 UserMode,
127 (PVOID*)&Thread,
128 NULL);
129 if (Status != STATUS_SUCCESS)
130 {
131 return(Status);
132 }
133
134 if (Thread == PsGetCurrentThread())
135 {
136 PsTerminateCurrentThread(ExitStatus);
137 }
138 else
139 {
140 PsTerminateOtherThread(Thread, ExitStatus);
141 }
142 return(STATUS_SUCCESS);
143 }
144
145 VOID PsReleaseThread(PETHREAD Thread)
146 /*
147 * FUNCTION: Called internally to release a thread's resources from another
148 * thread's context
149 * ARGUMENTS:
150 * Thread = Thread to release
151 */
152 {
153 DPRINT("PsReleaseThread(Thread %x)\n",Thread);
154
155 RemoveEntryList(&Thread->Tcb.Entry);
156 HalReleaseTask(Thread);
157 ObDereferenceObject(Thread);
158 }
159
160
161 NTSTATUS PsTerminateSystemThread(NTSTATUS ExitStatus)
162 /*
163 * FUNCTION: Terminates the current thread
164 * ARGUMENTS:
165 * ExitStatus = Status to pass to the creater
166 * RETURNS: Doesn't
167 */
168 {
169 PsTerminateCurrentThread(ExitStatus);
170 return(STATUS_SUCCESS);
171 }
172
173
174 NTSTATUS
175 STDCALL
176 NtRegisterThreadTerminatePort (
177 HANDLE TerminationPort
178 )
179 {
180 UNIMPLEMENTED;
181 }