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