1 /* $Id: tinfo.c,v 1.21 2003/07/11 01:23:15 royce Exp $
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
;
336 KeGetPreviousMode (VOID
)
338 return (ULONG
)PsGetCurrentThread()->Tcb
.PreviousMode
;
345 ExGetPreviousMode (VOID
)
347 return (ULONG
)PsGetCurrentThread()->Tcb
.PreviousMode
;