Use free Windows DDK and compile with latest MinGW releases.
[reactos.git] / reactos / ntoskrnl / ps / tinfo.c
1 /* $Id: tinfo.c,v 1.18 2002/09/07 15:13:05 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 <ntoskrnl.h>
15
16 #define NDEBUG
17 #include <internal/debug.h>
18
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 Status = STATUS_NOT_IMPLEMENTED;
76 break;
77
78 case ThreadAffinityMask:
79 Thread->Tcb.UserAffinity = *((PULONG)ThreadInformation);
80 break;
81
82 case ThreadImpersonationToken:
83 {
84 HANDLE TokenHandle;
85
86 if (ThreadInformationLength != sizeof(HANDLE))
87 {
88 Status = STATUS_INFO_LENGTH_MISMATCH;
89 break;
90 }
91 TokenHandle = *((PHANDLE)ThreadInformation);
92 Status = PsAssignImpersonationToken(Thread, TokenHandle);
93 break;
94 }
95
96 case ThreadDescriptorTableEntry:
97 /* Can only be queried */
98 Status = STATUS_INVALID_INFO_CLASS;
99 break;
100
101 case ThreadEventPair:
102 Status = STATUS_NOT_IMPLEMENTED;
103 break;
104
105 case ThreadQuerySetWin32StartAddress:
106 if (ThreadInformationLength != sizeof(ULONG))
107 {
108 Status = STATUS_INFO_LENGTH_MISMATCH;
109 break;
110 }
111 Thread->u2.Win32StartAddress = (PVOID)*((PULONG)ThreadInformation);
112 Status = STATUS_SUCCESS;
113 break;
114
115 case ThreadZeroTlsCell:
116 {
117 Status = STATUS_NOT_IMPLEMENTED;
118 break;
119 }
120
121 case ThreadPerformanceCount:
122 /* Can only be queried */
123 Status = STATUS_INVALID_INFO_CLASS;
124 break;
125
126 case ThreadAmILastThread:
127 /* Can only be queried */
128 Status = STATUS_INVALID_INFO_CLASS;
129 break;
130
131 case ThreadIdealProcessor:
132 Status = STATUS_NOT_IMPLEMENTED;
133 break;
134
135 case ThreadPriorityBoost:
136 Status = STATUS_NOT_IMPLEMENTED;
137 break;
138
139 case ThreadSetTlsArrayAddress:
140 Status = STATUS_NOT_IMPLEMENTED;
141 break;
142
143 case ThreadIsIoPending:
144 /* Can only be queried */
145 Status = STATUS_INVALID_INFO_CLASS;
146 break;
147
148 case ThreadHideFromDebugger:
149 Status = STATUS_NOT_IMPLEMENTED;
150 break;
151
152 default:
153 Status = STATUS_UNSUCCESSFUL;
154 }
155 ObDereferenceObject(Thread);
156 return Status;
157 }
158
159
160 NTSTATUS STDCALL
161 NtQueryInformationThread (IN HANDLE ThreadHandle,
162 IN THREADINFOCLASS ThreadInformationClass,
163 OUT PVOID ThreadInformation,
164 IN ULONG ThreadInformationLength,
165 OUT PULONG ReturnLength)
166 {
167 PETHREAD Thread;
168 NTSTATUS Status;
169
170 Status = ObReferenceObjectByHandle(ThreadHandle,
171 THREAD_QUERY_INFORMATION,
172 PsThreadType,
173 ExGetPreviousMode(),
174 (PVOID*)&Thread,
175 NULL);
176 if (!NT_SUCCESS(Status))
177 {
178 return Status;
179 }
180
181 switch (ThreadInformationClass)
182 {
183 case ThreadBasicInformation:
184 {
185 PTHREAD_BASIC_INFORMATION TBI;
186
187 TBI = (PTHREAD_BASIC_INFORMATION)ThreadInformation;
188
189 if (ThreadInformationLength != sizeof(THREAD_BASIC_INFORMATION))
190 {
191 Status = STATUS_INFO_LENGTH_MISMATCH;
192 break;
193 }
194
195 TBI->ExitStatus = Thread->ExitStatus;
196 /* MINGWFIXME: Use NT_TIB */
197 TBI->TebBaseAddress = (PNT_TIB)Thread->Tcb.Teb;
198 TBI->ClientId = Thread->Cid;
199 TBI->AffinityMask = Thread->Tcb.Affinity;
200 TBI->Priority = Thread->Tcb.Priority;
201 TBI->BasePriority = Thread->Tcb.BasePriority;
202 Status = STATUS_SUCCESS;
203 break;
204 }
205
206 case ThreadTimes:
207 Status = STATUS_NOT_IMPLEMENTED;
208 break;
209
210 case ThreadPriority:
211 /* Can be set only */
212 Status = STATUS_INVALID_INFO_CLASS;
213 break;
214
215 case ThreadBasePriority:
216 /* Can be set only */
217 Status = STATUS_INVALID_INFO_CLASS;
218 break;
219
220 case ThreadAffinityMask:
221 /* Can be set only */
222 Status = STATUS_INVALID_INFO_CLASS;
223 break;
224
225 case ThreadImpersonationToken:
226 /* Can be set only */
227 Status = STATUS_INVALID_INFO_CLASS;
228 break;
229
230 case ThreadDescriptorTableEntry:
231 /* Nebbett says nothing about this */
232 Status = STATUS_NOT_IMPLEMENTED;
233 break;
234
235 case ThreadEnableAlignmentFaultFixup:
236 /* Can be set only */
237 Status = STATUS_INVALID_INFO_CLASS;
238 break;
239
240 case ThreadEventPair:
241 /* Can be set only */
242 Status = STATUS_INVALID_INFO_CLASS;
243 break;
244
245 case ThreadQuerySetWin32StartAddress:
246 if (ThreadInformationLength != sizeof(PVOID))
247 {
248 Status = STATUS_INFO_LENGTH_MISMATCH;
249 break;
250 }
251 *((PVOID*)ThreadInformation) = Thread->u2.Win32StartAddress;
252 Status = STATUS_SUCCESS;
253 break;
254
255 case ThreadZeroTlsCell:
256 /* Can only be set */
257 Status = STATUS_INVALID_INFO_CLASS;
258 break;
259
260 case ThreadPerformanceCount:
261 /* Nebbett says this class is always zero */
262 if (ThreadInformationLength != sizeof(LARGE_INTEGER))
263 {
264 Status = STATUS_INFO_LENGTH_MISMATCH;
265 break;
266 }
267 ((PLARGE_INTEGER)ThreadInformation)->QuadPart = 0;
268 Status = STATUS_SUCCESS;
269 break;
270
271 case ThreadAmILastThread:
272 {
273 if (ThreadInformationLength != sizeof(BOOLEAN))
274 {
275 Status = STATUS_INFO_LENGTH_MISMATCH;
276 break;
277 }
278 if (Thread->ThreadsProcess->ThreadListHead.Flink->Flink ==
279 &Thread->ThreadsProcess->ThreadListHead)
280 {
281 *((PBOOLEAN)ThreadInformation) = TRUE;
282 }
283 else
284 {
285 *((PBOOLEAN)ThreadInformation) = FALSE;
286 }
287 Status = STATUS_SUCCESS;
288 break;
289 }
290
291 case ThreadIdealProcessor:
292 /* Can only be set */
293 Status = STATUS_INFO_LENGTH_MISMATCH;
294 break;
295
296 case ThreadPriorityBoost:
297 Status = STATUS_NOT_IMPLEMENTED;
298 break;
299
300 case ThreadSetTlsArrayAddress:
301 /* Can only be set */
302 Status = STATUS_INVALID_INFO_CLASS;
303 break;
304
305 case ThreadIsIoPending:
306 Status = STATUS_NOT_IMPLEMENTED;
307 break;
308
309 case ThreadHideFromDebugger:
310 /* Can only be set */
311 Status = STATUS_INVALID_INFO_CLASS;
312 break;
313
314 default:
315 Status = STATUS_INVALID_INFO_CLASS;
316 }
317 ObDereferenceObject(Thread);
318 return(Status);
319 }
320
321 VOID KeSetPreviousMode(ULONG Mode)
322 {
323 PsGetCurrentThread()->Tcb.PreviousMode = Mode;
324 }
325
326 KPROCESSOR_MODE STDCALL
327 KeGetPreviousMode (VOID)
328 {
329 return PsGetCurrentThread()->Tcb.PreviousMode;
330 }
331
332 KPROCESSOR_MODE STDCALL
333 ExGetPreviousMode (VOID)
334 {
335 return PsGetCurrentThread()->Tcb.PreviousMode;
336 }
337
338 /* EOF */