Reverted latest changes.
[reactos.git] / reactos / ntoskrnl / ps / tinfo.c
1 /* $Id: tinfo.c,v 1.19 2002/09/08 10:23:41 chorns Exp $
2 *
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * FILE: ntoskrnl/ps/tinfo.c
6 * PURPOSE: Getting/setting thread information
7 * PROGRAMMER: David Welch (welch@mcmail.com)
8 * UPDATE HISTORY:
9 * Created 22/05/98
10 */
11
12 /* INCLUDES *****************************************************************/
13
14 #include <ddk/ntddk.h>
15 #include <internal/ps.h>
16
17 #include <internal/debug.h>
18
19 /* FUNCTIONS *****************************************************************/
20
21 NTSTATUS STDCALL
22 NtSetInformationThread(HANDLE ThreadHandle,
23 THREADINFOCLASS ThreadInformationClass,
24 PVOID ThreadInformation,
25 ULONG ThreadInformationLength)
26 {
27 PETHREAD Thread;
28 NTSTATUS Status;
29
30 Status = ObReferenceObjectByHandle(ThreadHandle,
31 THREAD_SET_INFORMATION,
32 PsThreadType,
33 ExGetPreviousMode(),
34 (PVOID*)&Thread,
35 NULL);
36 if (!NT_SUCCESS(Status))
37 {
38 return Status;
39 }
40
41 switch (ThreadInformationClass)
42 {
43 case ThreadBasicInformation:
44 /* Can only be queried */
45 Status = STATUS_INVALID_INFO_CLASS;
46 break;
47
48 case ThreadTimes:
49 /* Can only be queried */
50 Status = STATUS_INVALID_INFO_CLASS;
51 break;
52
53 case ThreadPriority:
54 {
55 KPRIORITY Priority;
56
57 if (ThreadInformationLength != sizeof(KPRIORITY))
58 {
59 Status = STATUS_INFO_LENGTH_MISMATCH;
60 break;
61 }
62 Priority = *(KPRIORITY*)ThreadInformation;
63 if (Priority < LOW_PRIORITY || Priority >= MAXIMUM_PRIORITY)
64 {
65 Status = STATUS_INVALID_PARAMETER;
66 break;
67 }
68 KeSetPriorityThread(&Thread->Tcb, Priority);
69 Status = STATUS_SUCCESS;
70 break;
71 }
72
73 case ThreadBasePriority:
74 Status = STATUS_NOT_IMPLEMENTED;
75 break;
76
77 case ThreadAffinityMask:
78 Thread->Tcb.UserAffinity = *((PULONG)ThreadInformation);
79 break;
80
81 case ThreadImpersonationToken:
82 {
83 HANDLE TokenHandle;
84
85 if (ThreadInformationLength != sizeof(HANDLE))
86 {
87 Status = STATUS_INFO_LENGTH_MISMATCH;
88 break;
89 }
90 TokenHandle = *((PHANDLE)ThreadInformation);
91 Status = PsAssignImpersonationToken(Thread, TokenHandle);
92 break;
93 }
94
95 case ThreadDescriptorTableEntry:
96 /* Can only be queried */
97 Status = STATUS_INVALID_INFO_CLASS;
98 break;
99
100 case ThreadEventPair:
101 Status = STATUS_NOT_IMPLEMENTED;
102 break;
103
104 case ThreadQuerySetWin32StartAddress:
105 if (ThreadInformationLength != sizeof(ULONG))
106 {
107 Status = STATUS_INFO_LENGTH_MISMATCH;
108 break;
109 }
110 Thread->u2.Win32StartAddress = (PVOID)*((PULONG)ThreadInformation);
111 Status = STATUS_SUCCESS;
112 break;
113
114 case ThreadZeroTlsCell:
115 {
116 Status = STATUS_NOT_IMPLEMENTED;
117 break;
118 }
119
120 case ThreadPerformanceCount:
121 /* Can only be queried */
122 Status = STATUS_INVALID_INFO_CLASS;
123 break;
124
125 case ThreadAmILastThread:
126 /* Can only be queried */
127 Status = STATUS_INVALID_INFO_CLASS;
128 break;
129
130 case ThreadIdealProcessor:
131 Status = STATUS_NOT_IMPLEMENTED;
132 break;
133
134 case ThreadPriorityBoost:
135 Status = STATUS_NOT_IMPLEMENTED;
136 break;
137
138 case ThreadSetTlsArrayAddress:
139 Status = STATUS_NOT_IMPLEMENTED;
140 break;
141
142 case ThreadIsIoPending:
143 /* Can only be queried */
144 Status = STATUS_INVALID_INFO_CLASS;
145 break;
146
147 case ThreadHideFromDebugger:
148 Status = STATUS_NOT_IMPLEMENTED;
149 break;
150
151 default:
152 Status = STATUS_UNSUCCESSFUL;
153 }
154 ObDereferenceObject(Thread);
155 return Status;
156 }
157
158
159 NTSTATUS STDCALL
160 NtQueryInformationThread (IN HANDLE ThreadHandle,
161 IN THREADINFOCLASS ThreadInformationClass,
162 OUT PVOID ThreadInformation,
163 IN ULONG ThreadInformationLength,
164 OUT PULONG ReturnLength)
165 {
166 PETHREAD Thread;
167 NTSTATUS Status;
168
169 Status = ObReferenceObjectByHandle(ThreadHandle,
170 THREAD_QUERY_INFORMATION,
171 PsThreadType,
172 ExGetPreviousMode(),
173 (PVOID*)&Thread,
174 NULL);
175 if (!NT_SUCCESS(Status))
176 {
177 return Status;
178 }
179
180 switch (ThreadInformationClass)
181 {
182 case ThreadBasicInformation:
183 {
184 PTHREAD_BASIC_INFORMATION TBI;
185
186 TBI = (PTHREAD_BASIC_INFORMATION)ThreadInformation;
187
188 if (ThreadInformationLength != sizeof(THREAD_BASIC_INFORMATION))
189 {
190 Status = STATUS_INFO_LENGTH_MISMATCH;
191 break;
192 }
193
194 TBI->ExitStatus = Thread->ExitStatus;
195 TBI->TebBaseAddress = Thread->Tcb.Teb;
196 TBI->ClientId = Thread->Cid;
197 TBI->AffinityMask = Thread->Tcb.Affinity;
198 TBI->Priority = Thread->Tcb.Priority;
199 TBI->BasePriority = Thread->Tcb.BasePriority;
200 Status = STATUS_SUCCESS;
201 break;
202 }
203
204 case ThreadTimes:
205 Status = STATUS_NOT_IMPLEMENTED;
206 break;
207
208 case ThreadPriority:
209 /* Can be set only */
210 Status = STATUS_INVALID_INFO_CLASS;
211 break;
212
213 case ThreadBasePriority:
214 /* Can be set only */
215 Status = STATUS_INVALID_INFO_CLASS;
216 break;
217
218 case ThreadAffinityMask:
219 /* Can be set only */
220 Status = STATUS_INVALID_INFO_CLASS;
221 break;
222
223 case ThreadImpersonationToken:
224 /* Can be set only */
225 Status = STATUS_INVALID_INFO_CLASS;
226 break;
227
228 case ThreadDescriptorTableEntry:
229 /* Nebbett says nothing about this */
230 Status = STATUS_NOT_IMPLEMENTED;
231 break;
232
233 case ThreadEnableAlignmentFaultFixup:
234 /* Can be set only */
235 Status = STATUS_INVALID_INFO_CLASS;
236 break;
237
238 case ThreadEventPair:
239 /* Can be set only */
240 Status = STATUS_INVALID_INFO_CLASS;
241 break;
242
243 case ThreadQuerySetWin32StartAddress:
244 if (ThreadInformationLength != sizeof(PVOID))
245 {
246 Status = STATUS_INFO_LENGTH_MISMATCH;
247 break;
248 }
249 *((PVOID*)ThreadInformation) = Thread->u2.Win32StartAddress;
250 Status = STATUS_SUCCESS;
251 break;
252
253 case ThreadZeroTlsCell:
254 /* Can only be set */
255 Status = STATUS_INVALID_INFO_CLASS;
256 break;
257
258 case ThreadPerformanceCount:
259 /* Nebbett says this class is always zero */
260 if (ThreadInformationLength != sizeof(LARGE_INTEGER))
261 {
262 Status = STATUS_INFO_LENGTH_MISMATCH;
263 break;
264 }
265 ((PLARGE_INTEGER)ThreadInformation)->QuadPart = 0;
266 Status = STATUS_SUCCESS;
267 break;
268
269 case ThreadAmILastThread:
270 {
271 if (ThreadInformationLength != sizeof(BOOLEAN))
272 {
273 Status = STATUS_INFO_LENGTH_MISMATCH;
274 break;
275 }
276 if (Thread->ThreadsProcess->ThreadListHead.Flink->Flink ==
277 &Thread->ThreadsProcess->ThreadListHead)
278 {
279 *((PBOOLEAN)ThreadInformation) = TRUE;
280 }
281 else
282 {
283 *((PBOOLEAN)ThreadInformation) = FALSE;
284 }
285 Status = STATUS_SUCCESS;
286 break;
287 }
288
289 case ThreadIdealProcessor:
290 /* Can only be set */
291 Status = STATUS_INFO_LENGTH_MISMATCH;
292 break;
293
294 case ThreadPriorityBoost:
295 Status = STATUS_NOT_IMPLEMENTED;
296 break;
297
298 case ThreadSetTlsArrayAddress:
299 /* Can only be set */
300 Status = STATUS_INVALID_INFO_CLASS;
301 break;
302
303 case ThreadIsIoPending:
304 Status = STATUS_NOT_IMPLEMENTED;
305 break;
306
307 case ThreadHideFromDebugger:
308 /* Can only be set */
309 Status = STATUS_INVALID_INFO_CLASS;
310 break;
311
312 default:
313 Status = STATUS_INVALID_INFO_CLASS;
314 }
315 ObDereferenceObject(Thread);
316 return(Status);
317 }
318
319 VOID KeSetPreviousMode(ULONG Mode)
320 {
321 PsGetCurrentThread()->Tcb.PreviousMode = Mode;
322 }
323
324 ULONG STDCALL
325 KeGetPreviousMode (VOID)
326 {
327 return (ULONG)PsGetCurrentThread()->Tcb.PreviousMode;
328 }
329
330 ULONG STDCALL
331 ExGetPreviousMode (VOID)
332 {
333 return (ULONG)PsGetCurrentThread()->Tcb.PreviousMode;
334 }
335
336 /* EOF */