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