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)
12 /* INCLUDES *****************************************************************/
14 #include <ddk/ntddk.h>
15 #include <internal/ps.h>
16 #include <internal/safe.h>
18 #include <internal/debug.h>
20 /* FUNCTIONS *****************************************************************/
23 NtSetInformationThread(HANDLE ThreadHandle,
24 THREADINFOCLASS ThreadInformationClass,
25 PVOID ThreadInformation,
26 ULONG ThreadInformationLength)
31 Status = ObReferenceObjectByHandle(ThreadHandle,
32 THREAD_SET_INFORMATION,
37 if (!NT_SUCCESS(Status))
42 switch (ThreadInformationClass)
44 case ThreadBasicInformation:
45 /* Can only be queried */
46 Status = STATUS_INVALID_INFO_CLASS;
50 /* Can only be queried */
51 Status = STATUS_INVALID_INFO_CLASS;
58 if (ThreadInformationLength != sizeof(KPRIORITY))
60 Status = STATUS_INFO_LENGTH_MISMATCH;
63 Priority = *(KPRIORITY*)ThreadInformation;
64 if (Priority < LOW_PRIORITY || Priority >= MAXIMUM_PRIORITY)
66 Status = STATUS_INVALID_PARAMETER;
69 KeSetPriorityThread(&Thread->Tcb, Priority);
70 Status = STATUS_SUCCESS;
74 case ThreadBasePriority:
75 if (ThreadInformationLength != sizeof(ULONG))
77 Status = STATUS_INFO_LENGTH_MISMATCH;
80 Status = MmCopyFromCaller(&(Thread->Tcb.BasePriority),
85 case ThreadAffinityMask:
86 Thread->Tcb.UserAffinity = *((PULONG)ThreadInformation);
89 case ThreadImpersonationToken:
93 if (ThreadInformationLength != sizeof(HANDLE))
95 Status = STATUS_INFO_LENGTH_MISMATCH;
98 TokenHandle = *((PHANDLE)ThreadInformation);
99 Status = PsAssignImpersonationToken(Thread, TokenHandle);
103 case ThreadDescriptorTableEntry:
104 /* Can only be queried */
105 Status = STATUS_INVALID_INFO_CLASS;
108 case ThreadEventPair:
109 Status = STATUS_NOT_IMPLEMENTED;
112 case ThreadQuerySetWin32StartAddress:
113 if (ThreadInformationLength != sizeof(ULONG))
115 Status = STATUS_INFO_LENGTH_MISMATCH;
118 Thread->u2.Win32StartAddress = (PVOID)*((PULONG)ThreadInformation);
119 Status = STATUS_SUCCESS;
122 case ThreadZeroTlsCell:
124 Status = STATUS_NOT_IMPLEMENTED;
128 case ThreadPerformanceCount:
129 /* Can only be queried */
130 Status = STATUS_INVALID_INFO_CLASS;
133 case ThreadAmILastThread:
134 /* Can only be queried */
135 Status = STATUS_INVALID_INFO_CLASS;
138 case ThreadIdealProcessor:
139 Status = STATUS_NOT_IMPLEMENTED;
142 case ThreadPriorityBoost:
143 Status = STATUS_NOT_IMPLEMENTED;
146 case ThreadSetTlsArrayAddress:
147 Status = STATUS_NOT_IMPLEMENTED;
150 case ThreadIsIoPending:
151 /* Can only be queried */
152 Status = STATUS_INVALID_INFO_CLASS;
155 case ThreadHideFromDebugger:
156 Status = STATUS_NOT_IMPLEMENTED;
160 Status = STATUS_UNSUCCESSFUL;
162 ObDereferenceObject(Thread);
168 NtQueryInformationThread (IN HANDLE ThreadHandle,
169 IN THREADINFOCLASS ThreadInformationClass,
170 OUT PVOID ThreadInformation,
171 IN ULONG ThreadInformationLength,
172 OUT PULONG ReturnLength)
177 Status = ObReferenceObjectByHandle(ThreadHandle,
178 THREAD_QUERY_INFORMATION,
183 if (!NT_SUCCESS(Status))
188 switch (ThreadInformationClass)
190 case ThreadBasicInformation:
192 PTHREAD_BASIC_INFORMATION TBI;
194 TBI = (PTHREAD_BASIC_INFORMATION)ThreadInformation;
196 if (ThreadInformationLength != sizeof(THREAD_BASIC_INFORMATION))
198 Status = STATUS_INFO_LENGTH_MISMATCH;
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;
213 Status = STATUS_NOT_IMPLEMENTED;
217 /* Can be set only */
218 Status = STATUS_INVALID_INFO_CLASS;
221 case ThreadBasePriority:
222 /* Can be set only */
223 Status = STATUS_INVALID_INFO_CLASS;
226 case ThreadAffinityMask:
227 /* Can be set only */
228 Status = STATUS_INVALID_INFO_CLASS;
231 case ThreadImpersonationToken:
232 /* Can be set only */
233 Status = STATUS_INVALID_INFO_CLASS;
236 case ThreadDescriptorTableEntry:
237 /* Nebbett says nothing about this */
238 Status = STATUS_NOT_IMPLEMENTED;
241 case ThreadEnableAlignmentFaultFixup:
242 /* Can be set only */
243 Status = STATUS_INVALID_INFO_CLASS;
246 case ThreadEventPair:
247 /* Can be set only */
248 Status = STATUS_INVALID_INFO_CLASS;
251 case ThreadQuerySetWin32StartAddress:
252 if (ThreadInformationLength != sizeof(PVOID))
254 Status = STATUS_INFO_LENGTH_MISMATCH;
257 *((PVOID*)ThreadInformation) = Thread->u2.Win32StartAddress;
258 Status = STATUS_SUCCESS;
261 case ThreadZeroTlsCell:
262 /* Can only be set */
263 Status = STATUS_INVALID_INFO_CLASS;
266 case ThreadPerformanceCount:
267 /* Nebbett says this class is always zero */
268 if (ThreadInformationLength != sizeof(LARGE_INTEGER))
270 Status = STATUS_INFO_LENGTH_MISMATCH;
273 ((PLARGE_INTEGER)ThreadInformation)->QuadPart = 0;
274 Status = STATUS_SUCCESS;
277 case ThreadAmILastThread:
279 if (ThreadInformationLength != sizeof(BOOLEAN))
281 Status = STATUS_INFO_LENGTH_MISMATCH;
284 if (Thread->ThreadsProcess->ThreadListHead.Flink->Flink ==
285 &Thread->ThreadsProcess->ThreadListHead)
287 *((PBOOLEAN)ThreadInformation) = TRUE;
291 *((PBOOLEAN)ThreadInformation) = FALSE;
293 Status = STATUS_SUCCESS;
297 case ThreadIdealProcessor:
298 /* Can only be set */
299 Status = STATUS_INFO_LENGTH_MISMATCH;
302 case ThreadPriorityBoost:
303 Status = STATUS_NOT_IMPLEMENTED;
306 case ThreadSetTlsArrayAddress:
307 /* Can only be set */
308 Status = STATUS_INVALID_INFO_CLASS;
311 case ThreadIsIoPending:
312 Status = STATUS_NOT_IMPLEMENTED;
315 case ThreadHideFromDebugger:
316 /* Can only be set */
317 Status = STATUS_INVALID_INFO_CLASS;
321 Status = STATUS_INVALID_INFO_CLASS;
323 ObDereferenceObject(Thread);
327 VOID KeSetPreviousMode(ULONG Mode)
329 PsGetCurrentThread()->Tcb.PreviousMode = Mode;
333 KeGetPreviousMode (VOID)
335 return (ULONG)PsGetCurrentThread()->Tcb.PreviousMode;
339 ExGetPreviousMode (VOID)
341 return (ULONG)PsGetCurrentThread()->Tcb.PreviousMode;