+ntoskrnl/se/sid.c
[reactos.git] / ntoskrnl / ps / tinfo.c
1 /* $Id$
2  *
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)
8  * UPDATE HISTORY:
9  *                  Created 22/05/98
10  */
11
12 /* INCLUDES *****************************************************************/
13
14 #include <ddk/ntddk.h>
15 #include <internal/ps.h>
16
17 #include <internal/debug.h>
18
19 /* FUNCTIONS *****************************************************************/
20
21 NTSTATUS STDCALL 
22 NtSetInformationThread(HANDLE           ThreadHandle,
23                        THREADINFOCLASS  ThreadInformationClass,
24                        PVOID            ThreadInformation,
25                        ULONG ThreadInformationLength)
26 {
27    PETHREAD                     Thread;
28    NTSTATUS                     Status;
29    
30    Status = ObReferenceObjectByHandle(ThreadHandle,
31                                       THREAD_SET_INFORMATION,
32                                       PsThreadType,
33                                       ExGetPreviousMode(),
34                                       (PVOID*)&Thread,
35                                       NULL);
36    if (!NT_SUCCESS(Status))
37      {
38         return Status;
39      }
40    
41    switch (ThreadInformationClass)
42      {
43       case ThreadBasicInformation:
44         /* Can only be queried */
45         Status = STATUS_INVALID_INFO_CLASS;
46         break;
47         
48       case ThreadTimes:
49         /* Can only be queried */
50         Status = STATUS_INVALID_INFO_CLASS;
51         break;
52         
53       case ThreadPriority:
54           {
55             KPRIORITY Priority;
56             
57             if (ThreadInformationLength != sizeof(KPRIORITY))
58               {
59                 Status = STATUS_INFO_LENGTH_MISMATCH;
60                 break;
61               }
62             Priority = *(KPRIORITY*)ThreadInformation;
63             if (Priority < LOW_PRIORITY || Priority >= MAXIMUM_PRIORITY)
64               {
65                 Status = STATUS_INVALID_PARAMETER;
66                 break;
67               }
68             KeSetPriorityThread(&Thread->Tcb, Priority);
69             Status = STATUS_SUCCESS;
70             break;
71           }
72         
73       case ThreadBasePriority:
74         Status = STATUS_NOT_IMPLEMENTED;
75         break;
76         
77       case ThreadAffinityMask:
78         Thread->Tcb.UserAffinity = *((PULONG)ThreadInformation);
79         break;
80         
81       case ThreadImpersonationToken:
82         {
83           HANDLE TokenHandle;
84
85           if (ThreadInformationLength != sizeof(HANDLE))
86             {
87               Status = STATUS_INFO_LENGTH_MISMATCH;
88               break;
89             }
90           TokenHandle = *((PHANDLE)ThreadInformation);
91           Status = PsAssignImpersonationToken(Thread, TokenHandle);
92           break;
93         }
94         
95       case ThreadDescriptorTableEntry:
96         /* Can only be queried */
97         Status = STATUS_INVALID_INFO_CLASS;
98         break;
99         
100       case ThreadEventPair:
101         Status = STATUS_NOT_IMPLEMENTED;
102         break;
103         
104       case ThreadQuerySetWin32StartAddress:
105         if (ThreadInformationLength != sizeof(ULONG))
106           {
107             Status = STATUS_INFO_LENGTH_MISMATCH;
108             break;
109           }
110         Thread->u2.Win32StartAddress = (PVOID)*((PULONG)ThreadInformation);
111         Status = STATUS_SUCCESS;
112         break;
113                 
114       case ThreadZeroTlsCell:
115         {
116           Status = STATUS_NOT_IMPLEMENTED;
117           break;
118         }
119         
120       case ThreadPerformanceCount:
121         /* Can only be queried */
122         Status = STATUS_INVALID_INFO_CLASS;
123         break;
124         
125       case ThreadAmILastThread:
126         /* Can only be queried */
127         Status = STATUS_INVALID_INFO_CLASS;
128         break;
129         
130      case ThreadIdealProcessor:
131        Status = STATUS_NOT_IMPLEMENTED;
132        break;
133        
134      case ThreadPriorityBoost:
135        Status = STATUS_NOT_IMPLEMENTED;
136        break;
137         
138      case ThreadSetTlsArrayAddress:
139        Status = STATUS_NOT_IMPLEMENTED;
140        break;
141
142      case ThreadIsIoPending:
143        /* Can only be queried */
144        Status = STATUS_INVALID_INFO_CLASS;
145        break;
146
147      case ThreadHideFromDebugger:
148        Status = STATUS_NOT_IMPLEMENTED;
149        break;
150
151       default:
152         Status = STATUS_UNSUCCESSFUL;
153      }
154    ObDereferenceObject(Thread);
155    return Status;
156 }
157
158
159 NTSTATUS STDCALL
160 NtQueryInformationThread (IN    HANDLE          ThreadHandle,
161                           IN    THREADINFOCLASS ThreadInformationClass,
162                           OUT   PVOID           ThreadInformation,
163                           IN    ULONG           ThreadInformationLength,
164                           OUT   PULONG          ReturnLength)
165 {
166    PETHREAD Thread;
167    NTSTATUS Status;
168
169    Status = ObReferenceObjectByHandle(ThreadHandle,
170                                       THREAD_QUERY_INFORMATION,
171                                       PsThreadType,
172                                       ExGetPreviousMode(),
173                                       (PVOID*)&Thread,
174                                       NULL);
175    if (!NT_SUCCESS(Status))
176      {
177         return Status;
178      }
179
180    switch (ThreadInformationClass)
181      {
182      case ThreadBasicInformation:
183        {
184          PTHREAD_BASIC_INFORMATION TBI;
185          
186          TBI = (PTHREAD_BASIC_INFORMATION)ThreadInformation;
187          
188          if (ThreadInformationLength != sizeof(THREAD_BASIC_INFORMATION))
189            {
190              Status = STATUS_INFO_LENGTH_MISMATCH;
191              break;
192            }
193          
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;
201          break;
202        }
203        
204      case ThreadTimes:
205        Status = STATUS_NOT_IMPLEMENTED;
206        break;
207        
208      case ThreadPriority:
209        /* Can be set only */
210        Status = STATUS_INVALID_INFO_CLASS;
211        break;
212        
213      case ThreadBasePriority:
214        /* Can be set only */
215        Status = STATUS_INVALID_INFO_CLASS;
216        break;
217        
218      case ThreadAffinityMask:
219        /* Can be set only */
220        Status = STATUS_INVALID_INFO_CLASS;
221        break;
222
223      case ThreadImpersonationToken:
224        /* Can be set only */
225        Status = STATUS_INVALID_INFO_CLASS;
226        break;
227        
228      case ThreadDescriptorTableEntry:
229        /* Nebbett says nothing about this */
230        Status = STATUS_NOT_IMPLEMENTED;
231        break;
232
233      case ThreadEnableAlignmentFaultFixup:
234        /* Can be set only */
235        Status = STATUS_INVALID_INFO_CLASS;
236        break;
237        
238      case ThreadEventPair:
239        /* Can be set only */
240        Status = STATUS_INVALID_INFO_CLASS;
241        break;
242
243      case ThreadQuerySetWin32StartAddress:
244        if (ThreadInformationLength != sizeof(PVOID))
245          {
246            Status = STATUS_INFO_LENGTH_MISMATCH;
247            break;
248          }
249        *((PVOID*)ThreadInformation) = Thread->u2.Win32StartAddress;
250        Status = STATUS_SUCCESS;
251        break;
252
253      case ThreadZeroTlsCell:
254        /* Can only be set */
255        Status = STATUS_INVALID_INFO_CLASS;
256        break;
257
258      case ThreadPerformanceCount:
259        /* Nebbett says this class is always zero */
260        if (ThreadInformationLength != sizeof(LARGE_INTEGER))
261          {
262            Status = STATUS_INFO_LENGTH_MISMATCH;
263            break;
264          }
265        ((PLARGE_INTEGER)ThreadInformation)->QuadPart = 0;
266        Status = STATUS_SUCCESS;
267        break;
268
269      case ThreadAmILastThread:
270        {
271          if (ThreadInformationLength != sizeof(BOOLEAN))
272            {
273              Status = STATUS_INFO_LENGTH_MISMATCH;
274              break;
275            }
276          if (Thread->ThreadsProcess->ThreadListHead.Flink->Flink ==
277              &Thread->ThreadsProcess->ThreadListHead)
278            {
279              *((PBOOLEAN)ThreadInformation) = TRUE;
280            }
281          else
282            {
283              *((PBOOLEAN)ThreadInformation) = FALSE;
284            }
285          Status = STATUS_SUCCESS;
286          break;
287        }
288
289      case ThreadIdealProcessor:
290        /* Can only be set */
291        Status = STATUS_INFO_LENGTH_MISMATCH;
292        break;
293
294      case ThreadPriorityBoost:
295        Status = STATUS_NOT_IMPLEMENTED;
296        break;
297
298      case ThreadSetTlsArrayAddress:
299        /* Can only be set */
300        Status = STATUS_INVALID_INFO_CLASS;
301        break;
302
303      case ThreadIsIoPending:
304        Status = STATUS_NOT_IMPLEMENTED;
305        break;
306        
307      case ThreadHideFromDebugger:
308        /* Can only be set */
309        Status = STATUS_INVALID_INFO_CLASS;
310        break;
311
312       default:
313         Status = STATUS_INVALID_INFO_CLASS;
314      }
315    ObDereferenceObject(Thread);
316    return(Status);
317 }
318
319 VOID KeSetPreviousMode(ULONG Mode)
320 {
321    PsGetCurrentThread()->Tcb.PreviousMode = Mode;
322 }
323
324 ULONG STDCALL
325 KeGetPreviousMode (VOID)
326 {
327    return (ULONG)PsGetCurrentThread()->Tcb.PreviousMode;
328 }
329
330 ULONG STDCALL
331 ExGetPreviousMode (VOID)
332 {
333    return (ULONG)PsGetCurrentThread()->Tcb.PreviousMode;
334 }
335
336 /* EOF */