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