1 /* $Id: tinfo.c,v 1.18 2002/09/07 15:13:05 chorns 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 *****************************************************************/
17 #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 Status
= STATUS_NOT_IMPLEMENTED
;
78 case ThreadAffinityMask
:
79 Thread
->Tcb
.UserAffinity
= *((PULONG
)ThreadInformation
);
82 case ThreadImpersonationToken
:
86 if (ThreadInformationLength
!= sizeof(HANDLE
))
88 Status
= STATUS_INFO_LENGTH_MISMATCH
;
91 TokenHandle
= *((PHANDLE
)ThreadInformation
);
92 Status
= PsAssignImpersonationToken(Thread
, TokenHandle
);
96 case ThreadDescriptorTableEntry
:
97 /* Can only be queried */
98 Status
= STATUS_INVALID_INFO_CLASS
;
101 case ThreadEventPair
:
102 Status
= STATUS_NOT_IMPLEMENTED
;
105 case ThreadQuerySetWin32StartAddress
:
106 if (ThreadInformationLength
!= sizeof(ULONG
))
108 Status
= STATUS_INFO_LENGTH_MISMATCH
;
111 Thread
->u2
.Win32StartAddress
= (PVOID
)*((PULONG
)ThreadInformation
);
112 Status
= STATUS_SUCCESS
;
115 case ThreadZeroTlsCell
:
117 Status
= STATUS_NOT_IMPLEMENTED
;
121 case ThreadPerformanceCount
:
122 /* Can only be queried */
123 Status
= STATUS_INVALID_INFO_CLASS
;
126 case ThreadAmILastThread
:
127 /* Can only be queried */
128 Status
= STATUS_INVALID_INFO_CLASS
;
131 case ThreadIdealProcessor
:
132 Status
= STATUS_NOT_IMPLEMENTED
;
135 case ThreadPriorityBoost
:
136 Status
= STATUS_NOT_IMPLEMENTED
;
139 case ThreadSetTlsArrayAddress
:
140 Status
= STATUS_NOT_IMPLEMENTED
;
143 case ThreadIsIoPending
:
144 /* Can only be queried */
145 Status
= STATUS_INVALID_INFO_CLASS
;
148 case ThreadHideFromDebugger
:
149 Status
= STATUS_NOT_IMPLEMENTED
;
153 Status
= STATUS_UNSUCCESSFUL
;
155 ObDereferenceObject(Thread
);
161 NtQueryInformationThread (IN HANDLE ThreadHandle
,
162 IN THREADINFOCLASS ThreadInformationClass
,
163 OUT PVOID ThreadInformation
,
164 IN ULONG ThreadInformationLength
,
165 OUT PULONG ReturnLength
)
170 Status
= ObReferenceObjectByHandle(ThreadHandle
,
171 THREAD_QUERY_INFORMATION
,
176 if (!NT_SUCCESS(Status
))
181 switch (ThreadInformationClass
)
183 case ThreadBasicInformation
:
185 PTHREAD_BASIC_INFORMATION TBI
;
187 TBI
= (PTHREAD_BASIC_INFORMATION
)ThreadInformation
;
189 if (ThreadInformationLength
!= sizeof(THREAD_BASIC_INFORMATION
))
191 Status
= STATUS_INFO_LENGTH_MISMATCH
;
195 TBI
->ExitStatus
= Thread
->ExitStatus
;
196 /* MINGWFIXME: Use NT_TIB */
197 TBI
->TebBaseAddress
= (PNT_TIB
)Thread
->Tcb
.Teb
;
198 TBI
->ClientId
= Thread
->Cid
;
199 TBI
->AffinityMask
= Thread
->Tcb
.Affinity
;
200 TBI
->Priority
= Thread
->Tcb
.Priority
;
201 TBI
->BasePriority
= Thread
->Tcb
.BasePriority
;
202 Status
= STATUS_SUCCESS
;
207 Status
= STATUS_NOT_IMPLEMENTED
;
211 /* Can be set only */
212 Status
= STATUS_INVALID_INFO_CLASS
;
215 case ThreadBasePriority
:
216 /* Can be set only */
217 Status
= STATUS_INVALID_INFO_CLASS
;
220 case ThreadAffinityMask
:
221 /* Can be set only */
222 Status
= STATUS_INVALID_INFO_CLASS
;
225 case ThreadImpersonationToken
:
226 /* Can be set only */
227 Status
= STATUS_INVALID_INFO_CLASS
;
230 case ThreadDescriptorTableEntry
:
231 /* Nebbett says nothing about this */
232 Status
= STATUS_NOT_IMPLEMENTED
;
235 case ThreadEnableAlignmentFaultFixup
:
236 /* Can be set only */
237 Status
= STATUS_INVALID_INFO_CLASS
;
240 case ThreadEventPair
:
241 /* Can be set only */
242 Status
= STATUS_INVALID_INFO_CLASS
;
245 case ThreadQuerySetWin32StartAddress
:
246 if (ThreadInformationLength
!= sizeof(PVOID
))
248 Status
= STATUS_INFO_LENGTH_MISMATCH
;
251 *((PVOID
*)ThreadInformation
) = Thread
->u2
.Win32StartAddress
;
252 Status
= STATUS_SUCCESS
;
255 case ThreadZeroTlsCell
:
256 /* Can only be set */
257 Status
= STATUS_INVALID_INFO_CLASS
;
260 case ThreadPerformanceCount
:
261 /* Nebbett says this class is always zero */
262 if (ThreadInformationLength
!= sizeof(LARGE_INTEGER
))
264 Status
= STATUS_INFO_LENGTH_MISMATCH
;
267 ((PLARGE_INTEGER
)ThreadInformation
)->QuadPart
= 0;
268 Status
= STATUS_SUCCESS
;
271 case ThreadAmILastThread
:
273 if (ThreadInformationLength
!= sizeof(BOOLEAN
))
275 Status
= STATUS_INFO_LENGTH_MISMATCH
;
278 if (Thread
->ThreadsProcess
->ThreadListHead
.Flink
->Flink
==
279 &Thread
->ThreadsProcess
->ThreadListHead
)
281 *((PBOOLEAN
)ThreadInformation
) = TRUE
;
285 *((PBOOLEAN
)ThreadInformation
) = FALSE
;
287 Status
= STATUS_SUCCESS
;
291 case ThreadIdealProcessor
:
292 /* Can only be set */
293 Status
= STATUS_INFO_LENGTH_MISMATCH
;
296 case ThreadPriorityBoost
:
297 Status
= STATUS_NOT_IMPLEMENTED
;
300 case ThreadSetTlsArrayAddress
:
301 /* Can only be set */
302 Status
= STATUS_INVALID_INFO_CLASS
;
305 case ThreadIsIoPending
:
306 Status
= STATUS_NOT_IMPLEMENTED
;
309 case ThreadHideFromDebugger
:
310 /* Can only be set */
311 Status
= STATUS_INVALID_INFO_CLASS
;
315 Status
= STATUS_INVALID_INFO_CLASS
;
317 ObDereferenceObject(Thread
);
321 VOID
KeSetPreviousMode(ULONG Mode
)
323 PsGetCurrentThread()->Tcb
.PreviousMode
= Mode
;
326 KPROCESSOR_MODE STDCALL
327 KeGetPreviousMode (VOID
)
329 return PsGetCurrentThread()->Tcb
.PreviousMode
;
332 KPROCESSOR_MODE STDCALL
333 ExGetPreviousMode (VOID
)
335 return PsGetCurrentThread()->Tcb
.PreviousMode
;