1 /* $Id: tinfo.c,v 1.16 2001/09/07 21:35:45 ea 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>
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
:
115 Status
= STATUS_NOT_IMPLEMENTED
;
118 case ThreadPerformanceCount
:
119 /* Can only be queried */
120 Status
= STATUS_INVALID_INFO_CLASS
;
123 case ThreadAmILastThread
:
124 /* Can only be queried */
125 Status
= STATUS_INVALID_INFO_CLASS
;
128 case ThreadIdealProcessor
:
129 Status
= STATUS_NOT_IMPLEMENTED
;
132 case ThreadPriorityBoost
:
133 Status
= STATUS_NOT_IMPLEMENTED
;
136 case ThreadSetTlsArrayAddress
:
137 Status
= STATUS_NOT_IMPLEMENTED
;
140 case ThreadIsIoPending
:
141 /* Can only be queried */
142 Status
= STATUS_INVALID_INFO_CLASS
;
145 case ThreadHideFromDebugger
:
146 Status
= STATUS_NOT_IMPLEMENTED
;
150 Status
= STATUS_UNSUCCESSFUL
;
152 ObDereferenceObject(Thread
);
158 NtQueryInformationThread (IN HANDLE ThreadHandle
,
159 IN THREADINFOCLASS ThreadInformationClass
,
160 OUT PVOID ThreadInformation
,
161 IN ULONG ThreadInformationLength
,
162 OUT PULONG ReturnLength
)
167 Status
= ObReferenceObjectByHandle(ThreadHandle
,
168 THREAD_QUERY_INFORMATION
,
173 if (!NT_SUCCESS(Status
))
178 switch (ThreadInformationClass
)
180 case ThreadBasicInformation
:
182 PTHREAD_BASIC_INFORMATION TBI
;
184 TBI
= (PTHREAD_BASIC_INFORMATION
)ThreadInformation
;
186 if (ThreadInformationLength
!= sizeof(THREAD_BASIC_INFORMATION
))
188 Status
= STATUS_INFO_LENGTH_MISMATCH
;
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
;
203 Status
= STATUS_NOT_IMPLEMENTED
;
207 /* Can be set only */
208 Status
= STATUS_INVALID_INFO_CLASS
;
211 case ThreadBasePriority
:
212 /* Can be set only */
213 Status
= STATUS_INVALID_INFO_CLASS
;
216 case ThreadAffinityMask
:
217 /* Can be set only */
218 Status
= STATUS_INVALID_INFO_CLASS
;
221 case ThreadImpersonationToken
:
222 /* Can be set only */
223 Status
= STATUS_INVALID_INFO_CLASS
;
226 case ThreadDescriptorTableEntry
:
227 /* Nebbett says nothing about this */
228 Status
= STATUS_NOT_IMPLEMENTED
;
231 case ThreadEnableAlignmentFaultFixup
:
232 /* Can be set only */
233 Status
= STATUS_INVALID_INFO_CLASS
;
236 case ThreadEventPair
:
237 /* Can be set only */
238 Status
= STATUS_INVALID_INFO_CLASS
;
241 case ThreadQuerySetWin32StartAddress
:
242 if (ThreadInformationLength
!= sizeof(PVOID
))
244 Status
= STATUS_INFO_LENGTH_MISMATCH
;
247 *((PVOID
*)ThreadInformation
) = Thread
->u2
.Win32StartAddress
;
248 Status
= STATUS_SUCCESS
;
251 case ThreadZeroTlsCell
:
252 /* Can only be set */
253 Status
= STATUS_INVALID_INFO_CLASS
;
256 case ThreadPerformanceCount
:
257 /* Nebbett says this class is always zero */
258 if (ThreadInformationLength
!= sizeof(LARGE_INTEGER
))
260 Status
= STATUS_INFO_LENGTH_MISMATCH
;
263 ((PLARGE_INTEGER
)ThreadInformation
)->QuadPart
= 0;
264 Status
= STATUS_SUCCESS
;
267 case ThreadAmILastThread
:
269 if (ThreadInformationLength
!= sizeof(BOOLEAN
))
271 Status
= STATUS_INFO_LENGTH_MISMATCH
;
274 if (Thread
->ThreadsProcess
->ThreadListHead
.Flink
->Flink
==
275 &Thread
->ThreadsProcess
->ThreadListHead
)
277 *((PBOOLEAN
)ThreadInformation
) = TRUE
;
281 *((PBOOLEAN
)ThreadInformation
) = FALSE
;
283 Status
= STATUS_SUCCESS
;
287 case ThreadIdealProcessor
:
288 /* Can only be set */
289 Status
= STATUS_INFO_LENGTH_MISMATCH
;
292 case ThreadPriorityBoost
:
293 Status
= STATUS_NOT_IMPLEMENTED
;
296 case ThreadSetTlsArrayAddress
:
297 /* Can only be set */
298 Status
= STATUS_INVALID_INFO_CLASS
;
301 case ThreadIsIoPending
:
302 Status
= STATUS_NOT_IMPLEMENTED
;
305 case ThreadHideFromDebugger
:
306 /* Can only be set */
307 Status
= STATUS_INVALID_INFO_CLASS
;
311 Status
= STATUS_INVALID_INFO_CLASS
;
313 ObDereferenceObject(Thread
);
317 VOID
KeSetPreviousMode(ULONG Mode
)
319 PsGetCurrentThread()->Tcb
.PreviousMode
= Mode
;
323 KeGetPreviousMode (VOID
)
325 return (ULONG
)PsGetCurrentThread()->Tcb
.PreviousMode
;
329 ExGetPreviousMode (VOID
)
331 return (ULONG
)PsGetCurrentThread()->Tcb
.PreviousMode
;