1 /* $Id: tinfo.c,v 1.17 2002/01/03 14:03:05 ekohl 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
:
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
;