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>
17 #include <internal/debug.h>
19 /* FUNCTIONS *****************************************************************/
22 NtSetInformationThread(HANDLE ThreadHandle,
23 THREADINFOCLASS ThreadInformationClass,
24 PVOID ThreadInformation,
25 ULONG ThreadInformationLength)
30 Status = ObReferenceObjectByHandle(ThreadHandle,
31 THREAD_SET_INFORMATION,
36 if (!NT_SUCCESS(Status))
41 switch (ThreadInformationClass)
43 case ThreadBasicInformation:
44 /* Can only be queried */
45 Status = STATUS_INVALID_INFO_CLASS;
49 /* Can only be queried */
50 Status = STATUS_INVALID_INFO_CLASS;
57 if (ThreadInformationLength != sizeof(KPRIORITY))
59 Status = STATUS_INFO_LENGTH_MISMATCH;
62 Priority = *(KPRIORITY*)ThreadInformation;
63 if (Priority < LOW_PRIORITY || Priority >= MAXIMUM_PRIORITY)
65 Status = STATUS_INVALID_PARAMETER;
68 KeSetPriorityThread(&Thread->Tcb, Priority);
69 Status = STATUS_SUCCESS;
73 case ThreadBasePriority:
74 Status = STATUS_NOT_IMPLEMENTED;
77 case ThreadAffinityMask:
78 Thread->Tcb.UserAffinity = *((PULONG)ThreadInformation);
81 case ThreadImpersonationToken:
85 if (ThreadInformationLength != sizeof(HANDLE))
87 Status = STATUS_INFO_LENGTH_MISMATCH;
90 TokenHandle = *((PHANDLE)ThreadInformation);
91 Status = PsAssignImpersonationToken(Thread, TokenHandle);
95 case ThreadDescriptorTableEntry:
96 /* Can only be queried */
97 Status = STATUS_INVALID_INFO_CLASS;
100 case ThreadEventPair:
101 Status = STATUS_NOT_IMPLEMENTED;
104 case ThreadQuerySetWin32StartAddress:
105 if (ThreadInformationLength != sizeof(ULONG))
107 Status = STATUS_INFO_LENGTH_MISMATCH;
110 Thread->u2.Win32StartAddress = (PVOID)*((PULONG)ThreadInformation);
111 Status = STATUS_SUCCESS;
114 case ThreadZeroTlsCell:
116 Status = STATUS_NOT_IMPLEMENTED;
120 case ThreadPerformanceCount:
121 /* Can only be queried */
122 Status = STATUS_INVALID_INFO_CLASS;
125 case ThreadAmILastThread:
126 /* Can only be queried */
127 Status = STATUS_INVALID_INFO_CLASS;
130 case ThreadIdealProcessor:
131 Status = STATUS_NOT_IMPLEMENTED;
134 case ThreadPriorityBoost:
135 Status = STATUS_NOT_IMPLEMENTED;
138 case ThreadSetTlsArrayAddress:
139 Status = STATUS_NOT_IMPLEMENTED;
142 case ThreadIsIoPending:
143 /* Can only be queried */
144 Status = STATUS_INVALID_INFO_CLASS;
147 case ThreadHideFromDebugger:
148 Status = STATUS_NOT_IMPLEMENTED;
152 Status = STATUS_UNSUCCESSFUL;
154 ObDereferenceObject(Thread);
160 NtQueryInformationThread (IN HANDLE ThreadHandle,
161 IN THREADINFOCLASS ThreadInformationClass,
162 OUT PVOID ThreadInformation,
163 IN ULONG ThreadInformationLength,
164 OUT PULONG ReturnLength)
169 Status = ObReferenceObjectByHandle(ThreadHandle,
170 THREAD_QUERY_INFORMATION,
175 if (!NT_SUCCESS(Status))
180 switch (ThreadInformationClass)
182 case ThreadBasicInformation:
184 PTHREAD_BASIC_INFORMATION TBI;
186 TBI = (PTHREAD_BASIC_INFORMATION)ThreadInformation;
188 if (ThreadInformationLength != sizeof(THREAD_BASIC_INFORMATION))
190 Status = STATUS_INFO_LENGTH_MISMATCH;
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;
205 Status = STATUS_NOT_IMPLEMENTED;
209 /* Can be set only */
210 Status = STATUS_INVALID_INFO_CLASS;
213 case ThreadBasePriority:
214 /* Can be set only */
215 Status = STATUS_INVALID_INFO_CLASS;
218 case ThreadAffinityMask:
219 /* Can be set only */
220 Status = STATUS_INVALID_INFO_CLASS;
223 case ThreadImpersonationToken:
224 /* Can be set only */
225 Status = STATUS_INVALID_INFO_CLASS;
228 case ThreadDescriptorTableEntry:
229 /* Nebbett says nothing about this */
230 Status = STATUS_NOT_IMPLEMENTED;
233 case ThreadEnableAlignmentFaultFixup:
234 /* Can be set only */
235 Status = STATUS_INVALID_INFO_CLASS;
238 case ThreadEventPair:
239 /* Can be set only */
240 Status = STATUS_INVALID_INFO_CLASS;
243 case ThreadQuerySetWin32StartAddress:
244 if (ThreadInformationLength != sizeof(PVOID))
246 Status = STATUS_INFO_LENGTH_MISMATCH;
249 *((PVOID*)ThreadInformation) = Thread->u2.Win32StartAddress;
250 Status = STATUS_SUCCESS;
253 case ThreadZeroTlsCell:
254 /* Can only be set */
255 Status = STATUS_INVALID_INFO_CLASS;
258 case ThreadPerformanceCount:
259 /* Nebbett says this class is always zero */
260 if (ThreadInformationLength != sizeof(LARGE_INTEGER))
262 Status = STATUS_INFO_LENGTH_MISMATCH;
265 ((PLARGE_INTEGER)ThreadInformation)->QuadPart = 0;
266 Status = STATUS_SUCCESS;
269 case ThreadAmILastThread:
271 if (ThreadInformationLength != sizeof(BOOLEAN))
273 Status = STATUS_INFO_LENGTH_MISMATCH;
276 if (Thread->ThreadsProcess->ThreadListHead.Flink->Flink ==
277 &Thread->ThreadsProcess->ThreadListHead)
279 *((PBOOLEAN)ThreadInformation) = TRUE;
283 *((PBOOLEAN)ThreadInformation) = FALSE;
285 Status = STATUS_SUCCESS;
289 case ThreadIdealProcessor:
290 /* Can only be set */
291 Status = STATUS_INFO_LENGTH_MISMATCH;
294 case ThreadPriorityBoost:
295 Status = STATUS_NOT_IMPLEMENTED;
298 case ThreadSetTlsArrayAddress:
299 /* Can only be set */
300 Status = STATUS_INVALID_INFO_CLASS;
303 case ThreadIsIoPending:
304 Status = STATUS_NOT_IMPLEMENTED;
307 case ThreadHideFromDebugger:
308 /* Can only be set */
309 Status = STATUS_INVALID_INFO_CLASS;
313 Status = STATUS_INVALID_INFO_CLASS;
315 ObDereferenceObject(Thread);
319 VOID KeSetPreviousMode(ULONG Mode)
321 PsGetCurrentThread()->Tcb.PreviousMode = Mode;
325 KeGetPreviousMode (VOID)
327 return (ULONG)PsGetCurrentThread()->Tcb.PreviousMode;
331 ExGetPreviousMode (VOID)
333 return (ULONG)PsGetCurrentThread()->Tcb.PreviousMode;