ReactOS  0.4.14-dev-77-gd9e7c48
query.c
Go to the documentation of this file.
1 /*
2  * PROJECT: ReactOS Kernel
3  * LICENSE: GPL - See COPYING in the top level directory
4  * FILE: ntoskrnl/ps/query.c
5  * PURPOSE: Process Manager: Thread/Process Query/Set Information
6  * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
7  * Thomas Weidenmueller (w3seek@reactos.org)
8  * Eric Kohl
9  */
10 
11 /* INCLUDES ******************************************************************/
12 
13 #include <ntoskrnl.h>
14 #define NDEBUG
15 #include <debug.h>
16 
17 /* Debugging Level */
19 
20 /* PRIVATE FUNCTIONS *********************************************************/
21 
23 NTAPI
26 {
27  PSECTION Section;
28  PAGED_CODE();
29 
30  /* Lock the process */
31  if (!ExAcquireRundownProtection(&Process->RundownProtect))
32  {
34  }
35 
36  /* Get the section */
37  Section = Process->SectionObject;
38  if (Section)
39  {
40  /* Get the file object and reference it */
43  }
44 
45  /* Release the protection */
46  ExReleaseRundownProtection(&Process->RundownProtect);
47 
48  /* Return status */
49  return Section ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL;
50 }
51 
52 /* PUBLIC FUNCTIONS **********************************************************/
53 
54 /*
55  * @implemented
56  */
58 NTAPI
60  IN PROCESSINFOCLASS ProcessInformationClass,
61  OUT PVOID ProcessInformation,
62  IN ULONG ProcessInformationLength,
64 {
68  ULONG Length = 0;
69  HANDLE DebugPort = 0;
70  PPROCESS_BASIC_INFORMATION ProcessBasicInfo =
71  (PPROCESS_BASIC_INFORMATION)ProcessInformation;
72  PKERNEL_USER_TIMES ProcessTime = (PKERNEL_USER_TIMES)ProcessInformation;
73  ULONG UserTime, KernelTime;
74  PPROCESS_PRIORITY_CLASS PsPriorityClass = (PPROCESS_PRIORITY_CLASS)ProcessInformation;
75  ULONG HandleCount;
77  (PPROCESS_SESSION_INFORMATION)ProcessInformation;
78  PVM_COUNTERS VmCounters = (PVM_COUNTERS)ProcessInformation;
79  PIO_COUNTERS IoCounters = (PIO_COUNTERS)ProcessInformation;
80  PQUOTA_LIMITS QuotaLimits = (PQUOTA_LIMITS)ProcessInformation;
82  ULONG Cookie, ExecuteOptions = 0;
83  ULONG_PTR Wow64 = 0;
84  PROCESS_VALUES ProcessValues;
85  ULONG Flags;
86  PAGED_CODE();
87 
88  /* Check for user-mode caller */
89  if (PreviousMode != KernelMode)
90  {
91  /* Prepare to probe parameters */
92  _SEH2_TRY
93  {
94  /* Probe the buffer */
95  ProbeForRead(ProcessInformation,
96  ProcessInformationLength,
97  sizeof(ULONG));
98 
99  /* Probe the return length if required */
101  }
103  {
104  /* Return the exception code */
106  }
107  _SEH2_END;
108  }
109 
110  if (((ProcessInformationClass == ProcessCookie) ||
111  (ProcessInformationClass == ProcessImageInformation)) &&
113  {
114  /*
115  * Retrieving the process cookie is only allowed for the calling process
116  * itself! XP only allows NtCurrentProcess() as process handles even if
117  * a real handle actually represents the current process.
118  */
120  }
121 
122  /* Check the information class */
123  switch (ProcessInformationClass)
124  {
125  /* Basic process information */
127 
128  if (ProcessInformationLength != sizeof(PROCESS_BASIC_INFORMATION))
129  {
131  break;
132  }
133 
134  /* Set return length */
136 
137  /* Reference the process */
141  PreviousMode,
142  (PVOID*)&Process,
143  NULL);
144  if (!NT_SUCCESS(Status)) break;
145 
146  /* Protect writes with SEH */
147  _SEH2_TRY
148  {
149  /* Write all the information from the EPROCESS/KPROCESS */
150  ProcessBasicInfo->ExitStatus = Process->ExitStatus;
151  ProcessBasicInfo->PebBaseAddress = Process->Peb;
152  ProcessBasicInfo->AffinityMask = Process->Pcb.Affinity;
153  ProcessBasicInfo->UniqueProcessId = (ULONG_PTR)Process->
154  UniqueProcessId;
155  ProcessBasicInfo->InheritedFromUniqueProcessId =
156  (ULONG_PTR)Process->InheritedFromUniqueProcessId;
157  ProcessBasicInfo->BasePriority = Process->Pcb.BasePriority;
158 
159  }
161  {
162  /* Get exception code */
164  }
165  _SEH2_END;
166 
167  /* Dereference the process */
169  break;
170 
171  /* Process quota limits */
172  case ProcessQuotaLimits:
173 
174  if (ProcessInformationLength != sizeof(QUOTA_LIMITS))
175  {
177  break;
178  }
179 
180  Length = sizeof(QUOTA_LIMITS);
181 
182  /* Reference the process */
186  PreviousMode,
187  (PVOID*)&Process,
188  NULL);
189  if (!NT_SUCCESS(Status)) break;
190 
191  /* Indicate success */
193 
194  _SEH2_TRY
195  {
196  /* Set max/min working set sizes */
197  QuotaLimits->MaximumWorkingSetSize =
198  Process->Vm.MaximumWorkingSetSize << PAGE_SHIFT;
199  QuotaLimits->MinimumWorkingSetSize =
200  Process->Vm.MinimumWorkingSetSize << PAGE_SHIFT;
201 
202  /* Set default time limits */
203  QuotaLimits->TimeLimit.LowPart = MAXULONG;
204  QuotaLimits->TimeLimit.HighPart = MAXULONG;
205 
206  /* Is quota block a default one? */
207  if (Process->QuotaBlock == &PspDefaultQuotaBlock)
208  {
209  /* Set default pools and pagefile limits */
210  QuotaLimits->PagedPoolLimit = (SIZE_T)-1;
211  QuotaLimits->NonPagedPoolLimit = (SIZE_T)-1;
212  QuotaLimits->PagefileLimit = (SIZE_T)-1;
213  }
214  else
215  {
216  /* Get limits from non-default quota block */
217  QuotaLimits->PagedPoolLimit =
218  Process->QuotaBlock->QuotaEntry[PagedPool].Limit;
219  QuotaLimits->NonPagedPoolLimit =
220  Process->QuotaBlock->QuotaEntry[NonPagedPool].Limit;
221  QuotaLimits->PagefileLimit =
222  Process->QuotaBlock->QuotaEntry[2].Limit;
223  }
224  }
226  {
227  /* Get exception code */
229  }
230  _SEH2_END;
231 
232  /* Dereference the process */
234  break;
235 
236  case ProcessIoCounters:
237 
238  if (ProcessInformationLength != sizeof(IO_COUNTERS))
239  {
241  break;
242  }
243 
244  Length = sizeof(IO_COUNTERS);
245 
246  /* Reference the process */
250  PreviousMode,
251  (PVOID*)&Process,
252  NULL);
253  if (!NT_SUCCESS(Status)) break;
254 
255  /* Query IO counters from the process */
256  KeQueryValuesProcess(&Process->Pcb, &ProcessValues);
257 
258  _SEH2_TRY
259  {
260  RtlCopyMemory(IoCounters, &ProcessValues.IoInfo, sizeof(IO_COUNTERS));
261  }
263  {
264  /* Ignore exception */
265  }
266  _SEH2_END;
267 
268  /* Set status to success in any case */
270 
271  /* Dereference the process */
273  break;
274 
275  /* Timing */
276  case ProcessTimes:
277 
278  /* Set the return length */
279  if (ProcessInformationLength != sizeof(KERNEL_USER_TIMES))
280  {
282  break;
283  }
284 
285  Length = sizeof(KERNEL_USER_TIMES);
286 
287  /* Reference the process */
291  PreviousMode,
292  (PVOID*)&Process,
293  NULL);
294  if (!NT_SUCCESS(Status)) break;
295 
296  /* Protect writes with SEH */
297  _SEH2_TRY
298  {
299  /* Copy time information from EPROCESS/KPROCESS */
300  KernelTime = KeQueryRuntimeProcess(&Process->Pcb, &UserTime);
301  ProcessTime->CreateTime = Process->CreateTime;
303  ProcessTime->KernelTime.QuadPart = (LONGLONG)KernelTime * KeMaximumIncrement;
304  ProcessTime->ExitTime = Process->ExitTime;
305  }
307  {
308  /* Get exception code */
310  }
311  _SEH2_END;
312 
313  /* Dereference the process */
315  break;
316 
317  /* Process Debug Port */
318  case ProcessDebugPort:
319 
320  if (ProcessInformationLength != sizeof(HANDLE))
321  {
323  break;
324  }
325 
326  /* Set return length */
327  Length = sizeof(HANDLE);
328 
329  /* Reference the process */
333  PreviousMode,
334  (PVOID*)&Process,
335  NULL);
336  if (!NT_SUCCESS(Status)) break;
337 
338  /* Protect write with SEH */
339  _SEH2_TRY
340  {
341  /* Return whether or not we have a debug port */
342  *(PHANDLE)ProcessInformation = (Process->DebugPort ?
343  (HANDLE)-1 : NULL);
344  }
346  {
347  /* Get exception code */
349  }
350  _SEH2_END;
351 
352  /* Dereference the process */
354  break;
355 
356  case ProcessHandleCount:
357 
358  if (ProcessInformationLength != sizeof(ULONG))
359  {
361  break;
362  }
363 
364  /* Set the return length*/
365  Length = sizeof(ULONG);
366 
367  /* Reference the process */
371  PreviousMode,
372  (PVOID*)&Process,
373  NULL);
374  if (!NT_SUCCESS(Status)) break;
375 
376  /* Count the number of handles this process has */
377  HandleCount = ObGetProcessHandleCount(Process);
378 
379  /* Protect write in SEH */
380  _SEH2_TRY
381  {
382  /* Return the count of handles */
383  *(PULONG)ProcessInformation = HandleCount;
384  }
386  {
387  /* Get the exception code */
389  }
390  _SEH2_END;
391 
392  /* Dereference the process */
394  break;
395 
396  /* Session ID for the process */
398 
399  if (ProcessInformationLength != sizeof(PROCESS_SESSION_INFORMATION))
400  {
402  break;
403  }
404 
405  /* Set the return length*/
407 
408  /* Reference the process */
412  PreviousMode,
413  (PVOID*)&Process,
414  NULL);
415  if (!NT_SUCCESS(Status)) break;
416 
417  /* Enter SEH for write safety */
418  _SEH2_TRY
419  {
420  /* Write back the Session ID */
422  }
424  {
425  /* Get the exception code */
427  }
428  _SEH2_END;
429 
430  /* Dereference the process */
432  break;
433 
434  /* Virtual Memory Statistics */
435  case ProcessVmCounters:
436 
437  /* Validate the input length */
438  if ((ProcessInformationLength != sizeof(VM_COUNTERS)) &&
439  (ProcessInformationLength != sizeof(VM_COUNTERS_EX)))
440  {
442  break;
443  }
444 
445  /* Reference the process */
449  PreviousMode,
450  (PVOID*)&Process,
451  NULL);
452  if (!NT_SUCCESS(Status)) break;
453 
454  /* Enter SEH for write safety */
455  _SEH2_TRY
456  {
457  /* Return data from EPROCESS */
458  VmCounters->PeakVirtualSize = Process->PeakVirtualSize;
459  VmCounters->VirtualSize = Process->VirtualSize;
460  VmCounters->PageFaultCount = Process->Vm.PageFaultCount;
461  VmCounters->PeakWorkingSetSize = Process->Vm.PeakWorkingSetSize;
462  VmCounters->WorkingSetSize = Process->Vm.WorkingSetSize;
463  VmCounters->QuotaPeakPagedPoolUsage = Process->QuotaPeak[0];
464  VmCounters->QuotaPagedPoolUsage = Process->QuotaUsage[0];
465  VmCounters->QuotaPeakNonPagedPoolUsage = Process->QuotaPeak[1];
466  VmCounters->QuotaNonPagedPoolUsage = Process->QuotaUsage[1];
467  VmCounters->PagefileUsage = Process->QuotaUsage[2] << PAGE_SHIFT;
468  VmCounters->PeakPagefileUsage = Process->QuotaPeak[2] << PAGE_SHIFT;
469  //VmCounters->PrivateUsage = Process->CommitCharge << PAGE_SHIFT;
470  //
471 
472  /* Set the return length */
473  Length = ProcessInformationLength;
474  }
476  {
477  /* Get the exception code */
479  }
480  _SEH2_END;
481 
482  /* Dereference the process */
484  break;
485 
486  /* Hard Error Processing Mode */
488 
489  if (ProcessInformationLength != sizeof(ULONG))
490  {
492  break;
493  }
494 
495  /* Set the return length*/
496  Length = sizeof(ULONG);
497 
498  /* Reference the process */
502  PreviousMode,
503  (PVOID*)&Process,
504  NULL);
505  if (!NT_SUCCESS(Status)) break;
506 
507  /* Enter SEH for writing back data */
508  _SEH2_TRY
509  {
510  /* Write the current processing mode */
511  *(PULONG)ProcessInformation = Process->
512  DefaultHardErrorProcessing;
513  }
515  {
516  /* Get the exception code */
518  }
519  _SEH2_END;
520 
521  /* Dereference the process */
523  break;
524 
525  /* Priority Boosting status */
527 
528  if (ProcessInformationLength != sizeof(ULONG))
529  {
531  break;
532  }
533 
534  /* Set the return length */
535  Length = sizeof(ULONG);
536 
537  /* Reference the process */
541  PreviousMode,
542  (PVOID*)&Process,
543  NULL);
544  if (!NT_SUCCESS(Status)) break;
545 
546  /* Enter SEH for writing back data */
547  _SEH2_TRY
548  {
549  /* Return boost status */
550  *(PULONG)ProcessInformation = Process->Pcb.DisableBoost ?
551  TRUE : FALSE;
552  }
554  {
555  /* Get the exception code */
557  }
558  _SEH2_END;
559 
560  /* Dereference the process */
562  break;
563 
564  /* DOS Device Map */
565  case ProcessDeviceMap:
566 
567  if (ProcessInformationLength < sizeof(PROCESS_DEVICEMAP_INFORMATION))
568  {
570  break;
571  }
572 
573  if (ProcessInformationLength == sizeof(PROCESS_DEVICEMAP_INFORMATION_EX))
574  {
575  /* Protect read in SEH */
576  _SEH2_TRY
577  {
578  PPROCESS_DEVICEMAP_INFORMATION_EX DeviceMapEx = ProcessInformation;
579 
580  Flags = DeviceMapEx->Flags;
581  }
583  {
584  /* Get the exception code */
586  }
587  _SEH2_END;
588 
589  if (!NT_SUCCESS(Status))
590  {
591  break;
592  }
593 
594  /* Only one flag is supported and it needs LUID mappings */
595  if ((Flags & ~PROCESS_LUID_DOSDEVICES_ONLY) != 0 ||
597  {
599  break;
600  }
601  }
602  else
603  {
604  if (ProcessInformationLength != sizeof(PROCESS_DEVICEMAP_INFORMATION))
605  {
607  break;
608  }
609 
610  /* No flags for standard call */
611  Flags = 0;
612  }
613 
614  /* Set the return length */
615  Length = ProcessInformationLength;
616 
617  /* Reference the process */
621  PreviousMode,
622  (PVOID*)&Process,
623  NULL);
624  if (!NT_SUCCESS(Status)) break;
625 
626  /* Query the device map information */
628  ProcessInformation,
629  Flags);
630 
631  /* Dereference the process */
633  break;
634 
635  /* Priority class */
637 
638  if (ProcessInformationLength != sizeof(PROCESS_PRIORITY_CLASS))
639  {
641  break;
642  }
643 
644  /* Set the return length*/
645  Length = sizeof(PROCESS_PRIORITY_CLASS);
646 
647  /* Reference the process */
651  PreviousMode,
652  (PVOID*)&Process,
653  NULL);
654  if (!NT_SUCCESS(Status)) break;
655 
656  /* Enter SEH for writing back data */
657  _SEH2_TRY
658  {
659  /* Return current priority class */
660  PsPriorityClass->PriorityClass = Process->PriorityClass;
661  PsPriorityClass->Foreground = FALSE;
662  }
664  {
665  /* Get the exception code */
667  }
668  _SEH2_END;
669 
670  /* Dereference the process */
672  break;
673 
675 
676  /* Reference the process */
680  PreviousMode,
681  (PVOID*)&Process,
682  NULL);
683  if (!NT_SUCCESS(Status)) break;
684 
685  /* Get the image path */
687  if (NT_SUCCESS(Status))
688  {
689  /* Set return length */
690  Length = ImageName->MaximumLength +
691  sizeof(OBJECT_NAME_INFORMATION);
692 
693  /* Make sure it's large enough */
694  if (Length <= ProcessInformationLength)
695  {
696  /* Enter SEH to protect write */
697  _SEH2_TRY
698  {
699  /* Copy it */
700  RtlCopyMemory(ProcessInformation,
701  ImageName,
702  Length);
703 
704  /* Update pointer */
705  ((PUNICODE_STRING)ProcessInformation)->Buffer =
706  (PWSTR)((PUNICODE_STRING)ProcessInformation + 1);
707  }
709  {
710  /* Get the exception code */
712  }
713  _SEH2_END;
714  }
715  else
716  {
717  /* Buffer too small */
719  }
720 
721  /* Free the image path */
723  }
724  /* Dereference the process */
726  break;
727 
728  case ProcessDebugFlags:
729 
730  if (ProcessInformationLength != sizeof(ULONG))
731  {
733  break;
734  }
735 
736  /* Set the return length*/
737  Length = sizeof(ULONG);
738 
739  /* Reference the process */
743  PreviousMode,
744  (PVOID*)&Process,
745  NULL);
746  if (!NT_SUCCESS(Status)) break;
747 
748  /* Enter SEH for writing back data */
749  _SEH2_TRY
750  {
751  /* Return the debug flag state */
752  *(PULONG)ProcessInformation = Process->NoDebugInherit ? 0 : 1;
753  }
755  {
756  /* Get the exception code */
758  }
759  _SEH2_END;
760 
761  /* Dereference the process */
763  break;
764 
766 
767  if (ProcessInformationLength != sizeof(ULONG))
768  {
770  break;
771  }
772 
773  /* Set the return length */
774  Length = sizeof(ULONG);
775 
776  /* Reference the process */
780  PreviousMode,
781  (PVOID*)&Process,
782  NULL);
783  if (!NT_SUCCESS(Status)) break;
784 
785  /* Enter SEH for writing back data */
786  _SEH2_TRY
787  {
788  /* Return the BreakOnTermination state */
789  *(PULONG)ProcessInformation = Process->BreakOnTermination;
790  }
792  {
793  /* Get the exception code */
795  }
796  _SEH2_END;
797 
798  /* Dereference the process */
800  break;
801 
802  /* Per-process security cookie */
803  case ProcessCookie:
804 
805  /* Get the current process and cookie */
807  Cookie = Process->Cookie;
808  if (!Cookie)
809  {
810  LARGE_INTEGER SystemTime;
811  ULONG NewCookie;
812  PKPRCB Prcb;
813 
814  /* Generate a new cookie */
815  KeQuerySystemTime(&SystemTime);
816  Prcb = KeGetCurrentPrcb();
817  NewCookie = Prcb->KeSystemCalls ^ Prcb->InterruptTime ^
818  SystemTime.u.LowPart ^ SystemTime.u.HighPart;
819 
820  /* Set the new cookie or return the current one */
822  NewCookie,
823  Cookie);
824  if (!Cookie) Cookie = NewCookie;
825 
826  /* Set return length */
827  Length = sizeof(ULONG);
828  }
829 
830  /* Indicate success */
832 
833  /* Enter SEH to protect write */
834  _SEH2_TRY
835  {
836  /* Write back the cookie */
837  *(PULONG)ProcessInformation = Cookie;
838  }
840  {
841  /* Get the exception code */
843  }
844  _SEH2_END;
845  break;
846 
848 
849  if (ProcessInformationLength != sizeof(SECTION_IMAGE_INFORMATION))
850  {
851  /* Break out */
853  break;
854  }
855 
856  /* Set the length required and validate it */
858 
859  /* Enter SEH to protect write */
860  _SEH2_TRY
861  {
863  }
865  {
866  /* Get the exception code */
868  }
869  _SEH2_END;
870 
871  /* Indicate success */
873  break;
874 
876 
877  if (ProcessInformationLength != sizeof(HANDLE))
878  {
880  break;
881  }
882 
883  /* Set the return length */
884  Length = sizeof(HANDLE);
885 
886  /* Reference the process */
890  PreviousMode,
891  (PVOID*)&Process,
892  NULL);
893  if (!NT_SUCCESS(Status)) break;
894 
895  /* Get the debug port */
897 
898  /* Let go of the process */
900 
901  /* Protect write in SEH */
902  _SEH2_TRY
903  {
904  /* Return debug port's handle */
905  *(PHANDLE)ProcessInformation = DebugPort;
906  }
908  {
909  /* Get the exception code */
911  }
912  _SEH2_END;
913  break;
914 
916  DPRINT1("Handle tracing Not implemented: %lx\n", ProcessInformationClass);
918  break;
919 
921 
922  if (ProcessInformationLength != sizeof(ULONG))
923  {
925  break;
926  }
927 
928  /* Set the return length */
929  Length = sizeof(ULONG);
930 
931  /* Indicate success */
933 
934  /* Protect write in SEH */
935  _SEH2_TRY
936  {
937  /* Query Ob */
938  *(PULONG)ProcessInformation = ObIsLUIDDeviceMapsEnabled();
939  }
941  {
942  /* Get the exception code */
944  }
945  _SEH2_END;
946  break;
947 
949 
950  if (ProcessInformationLength != sizeof(ULONG))
951  {
953  break;
954  }
955 
956  /* Set the return length */
957  Length = sizeof(ULONG);
958 
959  /* Reference the process */
963  PreviousMode,
964  (PVOID*)&Process,
965  NULL);
966  if (!NT_SUCCESS(Status)) break;
967 
968  /* Protect write in SEH */
969  _SEH2_TRY
970  {
971  /* Return if the flag is set */
972  *(PULONG)ProcessInformation = (ULONG)Process->VdmAllowed;
973  }
975  {
976  /* Get the exception code */
978  }
979  _SEH2_END;
980 
981  /* Dereference the process */
983  break;
984 
986 
987  if (ProcessInformationLength != sizeof(ULONG_PTR))
988  {
990  break;
991  }
992 
993  /* Set return length */
994  Length = sizeof(ULONG_PTR);
995 
996  /* Reference the process */
1000  PreviousMode,
1001  (PVOID*)&Process,
1002  NULL);
1003  if (!NT_SUCCESS(Status)) break;
1004 
1005  /* Make sure the process isn't dying */
1006  if (ExAcquireRundownProtection(&Process->RundownProtect))
1007  {
1008  /* Get the WOW64 process structure */
1009 #ifdef _WIN64
1010  Wow64 = (ULONG_PTR)Process->Wow64Process;
1011 #else
1012  Wow64 = 0;
1013 #endif
1014  /* Release the lock */
1015  ExReleaseRundownProtection(&Process->RundownProtect);
1016  }
1017 
1018  /* Protect write with SEH */
1019  _SEH2_TRY
1020  {
1021  /* Return whether or not we have a debug port */
1022  *(PULONG_PTR)ProcessInformation = Wow64;
1023  }
1025  {
1026  /* Get exception code */
1028  }
1029  _SEH2_END;
1030 
1031  /* Dereference the process */
1033  break;
1034 
1035  case ProcessExecuteFlags:
1036 
1037  if (ProcessInformationLength != sizeof(ULONG))
1038  {
1040  break;
1041  }
1042 
1043  /* Set return length */
1044  Length = sizeof(ULONG);
1045 
1047  {
1048  return STATUS_INVALID_PARAMETER;
1049  }
1050 
1051  /* Get the options */
1052  Status = MmGetExecuteOptions(&ExecuteOptions);
1053  if (NT_SUCCESS(Status))
1054  {
1055  /* Protect write with SEH */
1056  _SEH2_TRY
1057  {
1058  /* Return them */
1059  *(PULONG)ProcessInformation = ExecuteOptions;
1060  }
1062  {
1063  /* Get exception code */
1065  }
1066  _SEH2_END;
1067  }
1068  break;
1069 
1070  case ProcessLdtInformation:
1071  DPRINT1("VDM/16-bit not implemented: %lx\n", ProcessInformationClass);
1073  break;
1074 
1076  DPRINT1("WS Watch Not implemented: %lx\n", ProcessInformationClass);
1078  break;
1079 
1081  DPRINT1("Pool limits Not implemented: %lx\n", ProcessInformationClass);
1083  break;
1084 
1085  /* Not supported by Server 2003 */
1086  default:
1087  DPRINT1("Unsupported info class: %lx\n", ProcessInformationClass);
1089  }
1090 
1091  /* Protect write with SEH */
1092  _SEH2_TRY
1093  {
1094  /* Check if caller wanted return length */
1095  if ((ReturnLength) && (Length)) *ReturnLength = Length;
1096  }
1098  {
1099  /* Get exception code */
1101  }
1102  _SEH2_END;
1103 
1104  return Status;
1105 }
1106 
1107 /*
1108  * @implemented
1109  */
1110 NTSTATUS
1111 NTAPI
1113  IN PROCESSINFOCLASS ProcessInformationClass,
1114  IN PVOID ProcessInformation,
1115  IN ULONG ProcessInformationLength)
1116 {
1119  ACCESS_MASK Access;
1120  NTSTATUS Status;
1121  HANDLE PortHandle = NULL;
1125  PROCESS_PRIORITY_CLASS PriorityClass = {0};
1126  PROCESS_FOREGROUND_BACKGROUND Foreground = {0};
1127  PVOID ExceptionPort;
1128  ULONG Break;
1129  KAFFINITY ValidAffinity, Affinity = 0;
1130  KPRIORITY BasePriority = 0;
1131  UCHAR MemoryPriority = 0;
1132  BOOLEAN DisableBoost = 0;
1133  ULONG DefaultHardErrorMode = 0;
1134  ULONG DebugFlags = 0, EnableFixup = 0, Boost = 0;
1135  ULONG NoExecute = 0, VdmPower = 0;
1137  PLIST_ENTRY Next;
1138  PETHREAD Thread;
1139  PAGED_CODE();
1140 
1141  /* Verify Information Class validity */
1142 #if 0
1143  Status = DefaultSetInfoBufferCheck(ProcessInformationClass,
1144  PsProcessInfoClass,
1145  RTL_NUMBER_OF(PsProcessInfoClass),
1146  ProcessInformation,
1147  ProcessInformationLength,
1148  PreviousMode);
1149  if (!NT_SUCCESS(Status)) return Status;
1150 #endif
1151 
1152  /* Check what class this is */
1153  Access = PROCESS_SET_INFORMATION;
1154  if (ProcessInformationClass == ProcessSessionInformation)
1155  {
1156  /* Setting the Session ID needs a special mask */
1157  Access |= PROCESS_SET_SESSIONID;
1158  }
1159  else if (ProcessInformationClass == ProcessExceptionPort)
1160  {
1161  /* Setting the exception port needs a special mask */
1162  Access |= PROCESS_SUSPEND_RESUME;
1163  }
1164 
1165  /* Reference the process */
1167  Access,
1168  PsProcessType,
1169  PreviousMode,
1170  (PVOID*)&Process,
1171  NULL);
1172  if (!NT_SUCCESS(Status)) return Status;
1173 
1174  /* Check what kind of information class this is */
1175  switch (ProcessInformationClass)
1176  {
1178 
1179  /* Check buffer length */
1180  if (ProcessInformationLength != sizeof(HANDLE))
1181  {
1183  break;
1184  }
1185 
1186  /* Use SEH for capture */
1187  _SEH2_TRY
1188  {
1189  /* Capture the boolean */
1190  VdmPower = *(PULONG)ProcessInformation;
1191  }
1193  {
1194  /* Get the exception code */
1196  _SEH2_YIELD(break);
1197  }
1198  _SEH2_END;
1199 
1200  /* Getting VDM powers requires the SeTcbPrivilege */
1202  {
1203  /* We don't hold the privilege, bail out */
1205  DPRINT1("Need TCB privilege\n");
1206  break;
1207  }
1208 
1209  /* Set or clear the flag */
1210  if (VdmPower)
1211  {
1213  }
1214  else
1215  {
1217  }
1218  break;
1219 
1220  /* Error/Exception Port */
1221  case ProcessExceptionPort:
1222 
1223  /* Check buffer length */
1224  if (ProcessInformationLength != sizeof(HANDLE))
1225  {
1227  break;
1228  }
1229 
1230  /* Use SEH for capture */
1231  _SEH2_TRY
1232  {
1233  /* Capture the handle */
1234  PortHandle = *(PHANDLE)ProcessInformation;
1235  }
1237  {
1238  /* Get the exception code */
1240  _SEH2_YIELD(break);
1241  }
1242  _SEH2_END;
1243 
1244  /* Setting the error port requires the SeTcbPrivilege */
1246  {
1247  /* We don't hold the privilege, bail out */
1249  break;
1250  }
1251 
1252  /* Get the LPC Port */
1253  Status = ObReferenceObjectByHandle(PortHandle,
1254  0,
1256  PreviousMode,
1257  (PVOID)&ExceptionPort,
1258  NULL);
1259  if (!NT_SUCCESS(Status)) break;
1260 
1261  /* Change the pointer */
1262  if (InterlockedCompareExchangePointer(&Process->ExceptionPort,
1263  ExceptionPort,
1264  NULL))
1265  {
1266  /* We already had one, fail */
1267  ObDereferenceObject(ExceptionPort);
1269  }
1270  break;
1271 
1272  /* Security Token */
1273  case ProcessAccessToken:
1274 
1275  /* Check buffer length */
1276  if (ProcessInformationLength != sizeof(PROCESS_ACCESS_TOKEN))
1277  {
1279  break;
1280  }
1281 
1282  /* Use SEH for capture */
1283  _SEH2_TRY
1284  {
1285  /* Save the token handle */
1286  TokenHandle = ((PPROCESS_ACCESS_TOKEN)ProcessInformation)->
1287  Token;
1288  }
1290  {
1291  /* Get the exception code */
1293  _SEH2_YIELD(break);
1294  }
1295  _SEH2_END;
1296 
1297  /* Assign the actual token */
1299  break;
1300 
1301  /* Hard error processing */
1303 
1304  /* Check buffer length */
1305  if (ProcessInformationLength != sizeof(ULONG))
1306  {
1308  break;
1309  }
1310 
1311  /* Enter SEH for direct buffer read */
1312  _SEH2_TRY
1313  {
1314  DefaultHardErrorMode = *(PULONG)ProcessInformation;
1315  }
1317  {
1318  /* Get exception code */
1320  _SEH2_YIELD(break);
1321  }
1322  _SEH2_END;
1323 
1324  /* Set the mode */
1325  Process->DefaultHardErrorProcessing = DefaultHardErrorMode;
1326 
1327  /* Call Ke for the update */
1328  if (DefaultHardErrorMode & SEM_NOALIGNMENTFAULTEXCEPT)
1329  {
1331  }
1332  else
1333  {
1335  }
1337  break;
1338 
1339  /* Session ID */
1341 
1342  /* Check buffer length */
1343  if (ProcessInformationLength != sizeof(PROCESS_SESSION_INFORMATION))
1344  {
1346  break;
1347  }
1348 
1349  /* Enter SEH for capture */
1350  _SEH2_TRY
1351  {
1352  /* Capture the caller's buffer */
1353  SessionInfo = *(PPROCESS_SESSION_INFORMATION)ProcessInformation;
1354  }
1356  {
1357  /* Get the exception code */
1359  _SEH2_YIELD(break);
1360  }
1361  _SEH2_END;
1362 
1363  /* Setting the session id requires the SeTcbPrivilege */
1365  {
1366  /* We don't hold the privilege, bail out */
1368  break;
1369  }
1370 
1371 #if 0 // OLD AND DEPRECATED CODE!!!!
1372 
1373  /* FIXME - update the session id for the process token */
1374  //Status = PsLockProcess(Process, FALSE);
1375  if (!NT_SUCCESS(Status)) break;
1376 
1377  /* Write the session ID in the EPROCESS */
1378  Process->Session = UlongToPtr(SessionInfo.SessionId); // HACK!!!
1379 
1380  /* Check if the process also has a PEB */
1381  if (Process->Peb)
1382  {
1383  /*
1384  * Attach to the process to make sure we're in the right
1385  * context to access the PEB structure
1386  */
1387  KeAttachProcess(&Process->Pcb);
1388 
1389  /* Enter SEH for write to user-mode PEB */
1390  _SEH2_TRY
1391  {
1392  /* Write the session ID */
1393  Process->Peb->SessionId = SessionInfo.SessionId;
1394  }
1396  {
1397  /* Get exception code */
1399  }
1400  _SEH2_END;
1401 
1402  /* Detach from the process */
1403  KeDetachProcess();
1404  }
1405 
1406  /* Unlock the process */
1407  //PsUnlockProcess(Process);
1408 
1409 #endif
1410 
1411  /*
1412  * Since we cannot change the session ID of the given
1413  * process anymore because it is set once and for all
1414  * at process creation time and because it is stored
1415  * inside the Process->Session structure managed by MM,
1416  * we fake changing it: we just return success if the
1417  * user-defined value is the same as the session ID of
1418  * the process, and otherwise we fail.
1419  */
1420  if (SessionInfo.SessionId == PsGetProcessSessionId(Process))
1421  {
1423  }
1424  else
1425  {
1427  }
1428 
1429  break;
1430 
1431  case ProcessPriorityClass:
1432 
1433  /* Check buffer length */
1434  if (ProcessInformationLength != sizeof(PROCESS_PRIORITY_CLASS))
1435  {
1437  break;
1438  }
1439 
1440  /* Enter SEH for capture */
1441  _SEH2_TRY
1442  {
1443  /* Capture the caller's buffer */
1444  PriorityClass = *(PPROCESS_PRIORITY_CLASS)ProcessInformation;
1445  }
1447  {
1448  /* Return the exception code */
1450  _SEH2_YIELD(break);
1451  }
1452  _SEH2_END;
1453 
1454  /* Check for invalid PriorityClass value */
1456  {
1458  break;
1459  }
1460 
1461  if ((PriorityClass.PriorityClass != Process->PriorityClass) &&
1463  {
1464  /* Check the privilege */
1466  ProcessHandle,
1468  PreviousMode);
1469  if (!HasPrivilege)
1470  {
1472  DPRINT1("Privilege to change priority to realtime lacking\n");
1474  }
1475  }
1476 
1477  /* Check if we have a job */
1478  if (Process->Job)
1479  {
1480  DPRINT1("Jobs not yet supported\n");
1481  }
1482 
1483  /* Set process priority class */
1484  Process->PriorityClass = PriorityClass.PriorityClass;
1485 
1486  /* Set process priority mode (foreground or background) */
1488  PriorityClass.Foreground ?
1492  break;
1493 
1495 
1496  /* Check buffer length */
1497  if (ProcessInformationLength != sizeof(PROCESS_FOREGROUND_BACKGROUND))
1498  {
1500  break;
1501  }
1502 
1503  /* Enter SEH for capture */
1504  _SEH2_TRY
1505  {
1506  /* Capture the caller's buffer */
1507  Foreground = *(PPROCESS_FOREGROUND_BACKGROUND)ProcessInformation;
1508  }
1510  {
1511  /* Return the exception code */
1513  _SEH2_YIELD(break);
1514  }
1515  _SEH2_END;
1516 
1517  /* Set process priority mode (foreground or background) */
1519  Foreground.Foreground ?
1523  break;
1524 
1525  case ProcessBasePriority:
1526 
1527  /* Validate input length */
1528  if (ProcessInformationLength != sizeof(KPRIORITY))
1529  {
1531  break;
1532  }
1533 
1534  /* Enter SEH for direct buffer read */
1535  _SEH2_TRY
1536  {
1537  BasePriority = *(KPRIORITY*)ProcessInformation;
1538  }
1540  {
1541  /* Get exception code */
1542  Break = 0;
1544  _SEH2_YIELD(break);
1545  }
1546  _SEH2_END;
1547 
1548  /* Extract the memory priority out of there */
1549  if (BasePriority & 0x80000000)
1550  {
1551  MemoryPriority = MEMORY_PRIORITY_FOREGROUND;
1552  BasePriority &= ~0x80000000;
1553  }
1554  else
1555  {
1556  MemoryPriority = MEMORY_PRIORITY_BACKGROUND;
1557  }
1558 
1559  /* Validate the number */
1560  if ((BasePriority > HIGH_PRIORITY) || (BasePriority <= LOW_PRIORITY))
1561  {
1563  return STATUS_INVALID_PARAMETER;
1564  }
1565 
1566  /* Check if the new base is higher */
1567  if (BasePriority > Process->Pcb.BasePriority)
1568  {
1570  ProcessHandle,
1572  PreviousMode);
1573  if (!HasPrivilege)
1574  {
1576  DPRINT1("Privilege to change priority from %lx to %lx lacking\n", BasePriority, Process->Pcb.BasePriority);
1578  }
1579  }
1580 
1581  /* Call Ke */
1582  KeSetPriorityAndQuantumProcess(&Process->Pcb, BasePriority, 0);
1583 
1584  /* Now set the memory priority */
1585  MmSetMemoryPriorityProcess(Process, MemoryPriority);
1587  break;
1588 
1589  case ProcessRaisePriority:
1590 
1591  /* Validate input length */
1592  if (ProcessInformationLength != sizeof(ULONG))
1593  {
1595  break;
1596  }
1597 
1598  /* Enter SEH for direct buffer read */
1599  _SEH2_TRY
1600  {
1601  Boost = *(PULONG)ProcessInformation;
1602  }
1604  {
1605  /* Get exception code */
1606  Break = 0;
1608  _SEH2_YIELD(break);
1609  }
1610  _SEH2_END;
1611 
1612  /* Make sure the process isn't dying */
1613  if (ExAcquireRundownProtection(&Process->RundownProtect))
1614  {
1615  /* Lock it */
1617  ExAcquirePushLockShared(&Process->ProcessLock);
1618 
1619  /* Loop the threads */
1620  for (Next = Process->ThreadListHead.Flink;
1621  Next != &Process->ThreadListHead;
1622  Next = Next->Flink)
1623  {
1624  /* Call Ke for the thread */
1625  Thread = CONTAINING_RECORD(Next, ETHREAD, ThreadListEntry);
1626  KeBoostPriorityThread(&Thread->Tcb, Boost);
1627  }
1628 
1629  /* Release the lock and rundown */
1630  ExReleasePushLockShared(&Process->ProcessLock);
1632  ExReleaseRundownProtection(&Process->RundownProtect);
1633 
1634  /* Set success code */
1636  }
1637  else
1638  {
1639  /* Avoid race conditions */
1641  }
1642  break;
1643 
1645 
1646  /* Check buffer length */
1647  if (ProcessInformationLength != sizeof(ULONG))
1648  {
1650  break;
1651  }
1652 
1653  /* Enter SEH for direct buffer read */
1654  _SEH2_TRY
1655  {
1656  Break = *(PULONG)ProcessInformation;
1657  }
1659  {
1660  /* Get exception code */
1661  Break = 0;
1663  _SEH2_YIELD(break);
1664  }
1665  _SEH2_END;
1666 
1667  /* Setting 'break on termination' requires the SeDebugPrivilege */
1669  {
1670  /* We don't hold the privilege, bail out */
1672  break;
1673  }
1674 
1675  /* Set or clear the flag */
1676  if (Break)
1677  {
1679  }
1680  else
1681  {
1683  }
1684 
1685  break;
1686 
1687  case ProcessAffinityMask:
1688 
1689  /* Check buffer length */
1690  if (ProcessInformationLength != sizeof(KAFFINITY))
1691  {
1693  break;
1694  }
1695 
1696  /* Enter SEH for direct buffer read */
1697  _SEH2_TRY
1698  {
1699  Affinity = *(PKAFFINITY)ProcessInformation;
1700  }
1702  {
1703  /* Get exception code */
1704  Break = 0;
1706  _SEH2_YIELD(break);
1707  }
1708  _SEH2_END;
1709 
1710  /* Make sure it's valid for the CPUs present */
1711  ValidAffinity = Affinity & KeActiveProcessors;
1712  if (!Affinity || (ValidAffinity != Affinity))
1713  {
1715  break;
1716  }
1717 
1718  /* Check if it's within job affinity limits */
1719  if (Process->Job)
1720  {
1721  /* Not yet implemented */
1722  UNIMPLEMENTED;
1724  break;
1725  }
1726 
1727  /* Make sure the process isn't dying */
1728  if (ExAcquireRundownProtection(&Process->RundownProtect))
1729  {
1730  /* Lock it */
1732  ExAcquirePushLockShared(&Process->ProcessLock);
1733 
1734  /* Call Ke to do the work */
1735  KeSetAffinityProcess(&Process->Pcb, ValidAffinity);
1736 
1737  /* Release the lock and rundown */
1738  ExReleasePushLockShared(&Process->ProcessLock);
1740  ExReleaseRundownProtection(&Process->RundownProtect);
1741 
1742  /* Set success code */
1744  }
1745  else
1746  {
1747  /* Avoid race conditions */
1749  }
1750  break;
1751 
1752  /* Priority Boosting status */
1753  case ProcessPriorityBoost:
1754 
1755  /* Validate input length */
1756  if (ProcessInformationLength != sizeof(ULONG))
1757  {
1759  break;
1760  }
1761 
1762  /* Enter SEH for direct buffer read */
1763  _SEH2_TRY
1764  {
1765  DisableBoost = *(PBOOLEAN)ProcessInformation;
1766  }
1768  {
1769  /* Get exception code */
1770  Break = 0;
1772  _SEH2_YIELD(break);
1773  }
1774  _SEH2_END;
1775 
1776  /* Make sure the process isn't dying */
1777  if (ExAcquireRundownProtection(&Process->RundownProtect))
1778  {
1779  /* Lock it */
1781  ExAcquirePushLockShared(&Process->ProcessLock);
1782 
1783  /* Call Ke to do the work */
1784  KeSetDisableBoostProcess(&Process->Pcb, DisableBoost);
1785 
1786  /* Loop the threads too */
1787  for (Next = Process->ThreadListHead.Flink;
1788  Next != &Process->ThreadListHead;
1789  Next = Next->Flink)
1790  {
1791  /* Call Ke for the thread */
1792  Thread = CONTAINING_RECORD(Next, ETHREAD, ThreadListEntry);
1793  KeSetDisableBoostThread(&Thread->Tcb, DisableBoost);
1794  }
1795 
1796  /* Release the lock and rundown */
1797  ExReleasePushLockShared(&Process->ProcessLock);
1799  ExReleaseRundownProtection(&Process->RundownProtect);
1800 
1801  /* Set success code */
1803  }
1804  else
1805  {
1806  /* Avoid race conditions */
1808  }
1809  break;
1810 
1811  case ProcessDebugFlags:
1812 
1813  /* Check buffer length */
1814  if (ProcessInformationLength != sizeof(ULONG))
1815  {
1817  break;
1818  }
1819 
1820  /* Enter SEH for direct buffer read */
1821  _SEH2_TRY
1822  {
1823  DebugFlags = *(PULONG)ProcessInformation;
1824  }
1826  {
1827  /* Get exception code */
1829  _SEH2_YIELD(break);
1830  }
1831  _SEH2_END;
1832 
1833  /* Set the mode */
1834  if (DebugFlags & ~1)
1835  {
1837  }
1838  else
1839  {
1840  if (DebugFlags & 1)
1841  {
1843  }
1844  else
1845  {
1847  }
1848  }
1849 
1850  /* Done */
1852  break;
1853 
1855 
1856  /* Check buffer length */
1857  if (ProcessInformationLength != sizeof(ULONG))
1858  {
1860  break;
1861  }
1862 
1863  /* Enter SEH for direct buffer read */
1864  _SEH2_TRY
1865  {
1866  EnableFixup = *(PULONG)ProcessInformation;
1867  }
1869  {
1870  /* Get exception code */
1872  _SEH2_YIELD(break);
1873  }
1874  _SEH2_END;
1875 
1876  /* Set the mode */
1877  if (EnableFixup)
1878  {
1879  Process->DefaultHardErrorProcessing |= SEM_NOALIGNMENTFAULTEXCEPT;
1880  }
1881  else
1882  {
1883  Process->DefaultHardErrorProcessing &= ~SEM_NOALIGNMENTFAULTEXCEPT;
1884  }
1885 
1886  /* Call Ke for the update */
1889  break;
1890 
1891  case ProcessUserModeIOPL:
1892 
1893  /* Only TCB can do this */
1895  {
1896  /* We don't hold the privilege, bail out */
1897  DPRINT1("Need TCB to set IOPL\n");
1899  break;
1900  }
1901 
1902  /* Only supported on x86 */
1903 #if defined (_X86_)
1904  Ke386SetIOPL();
1905 #else
1907 #endif
1908  /* Done */
1909  break;
1910 
1911  case ProcessExecuteFlags:
1912 
1913  /* Check buffer length */
1914  if (ProcessInformationLength != sizeof(ULONG))
1915  {
1917  break;
1918  }
1919 
1921  {
1923  break;
1924  }
1925 
1926  /* Enter SEH for direct buffer read */
1927  _SEH2_TRY
1928  {
1929  NoExecute = *(PULONG)ProcessInformation;
1930  }
1932  {
1933  /* Get exception code */
1935  _SEH2_YIELD(break);
1936  }
1937  _SEH2_END;
1938 
1939  /* Call Mm for the update */
1940  Status = MmSetExecuteOptions(NoExecute);
1941  break;
1942 
1943  case ProcessDeviceMap:
1944 
1945  /* Check buffer length */
1946  if (ProcessInformationLength != sizeof(HANDLE))
1947  {
1949  break;
1950  }
1951 
1952  /* Use SEH for capture */
1953  _SEH2_TRY
1954  {
1955  /* Capture the handle */
1956  DirectoryHandle = *(PHANDLE)ProcessInformation;
1957  }
1959  {
1960  /* Get the exception code */
1962  _SEH2_YIELD(break);
1963  }
1964  _SEH2_END;
1965 
1966  /* Call Ob to set the device map */
1968  break;
1969 
1970 
1971  /* We currently don't implement any of these */
1972  case ProcessLdtInformation:
1973  case ProcessLdtSize:
1974  case ProcessIoPortHandlers:
1975  DPRINT1("VDM/16-bit Request not implemented: %lx\n", ProcessInformationClass);
1977  break;
1978 
1979  case ProcessQuotaLimits:
1980 
1982  1,
1983  ProcessInformation,
1984  ProcessInformationLength,
1985  PreviousMode);
1986  break;
1987 
1989  DPRINT1("WS watch not implemented\n");
1991  break;
1992 
1993  case ProcessHandleTracing:
1994  DPRINT1("Handle tracing not implemented\n");
1996  break;
1997 
1998  /* Anything else is invalid */
1999  default:
2000  DPRINT1("Invalid Server 2003 Info Class: %lx\n", ProcessInformationClass);
2002  }
2003 
2004  /* Dereference and return status */
2006  return Status;
2007 }
2008 
2009 /*
2010  * @implemented
2011  */
2012 NTSTATUS
2013 NTAPI
2016  IN PVOID ThreadInformation,
2018 {
2019  PETHREAD Thread;
2020  ULONG Access;
2022  NTSTATUS Status;
2024  KPRIORITY Priority = 0;
2025  KAFFINITY Affinity = 0, CombinedAffinity;
2026  PVOID Address = NULL;
2028  ULONG_PTR DisableBoost = 0;
2029  ULONG_PTR IdealProcessor = 0;
2030  ULONG_PTR Break = 0;
2031  PTEB Teb;
2032  ULONG_PTR TlsIndex = 0;
2033  PVOID *ExpansionSlots;
2034  PETHREAD ProcThread;
2035  PAGED_CODE();
2036 
2037  /* Verify Information Class validity */
2038 #if 0
2040  PsThreadInfoClass,
2041  RTL_NUMBER_OF(PsThreadInfoClass),
2042  ThreadInformation,
2044  PreviousMode);
2045  if (!NT_SUCCESS(Status)) return Status;
2046 #endif
2047 
2048  /* Check what class this is */
2049  Access = THREAD_SET_INFORMATION;
2051  {
2052  /* Setting the impersonation token needs a special mask */
2053  Access = THREAD_SET_THREAD_TOKEN;
2054  }
2055 
2056  /* Reference the thread */
2057  Status = ObReferenceObjectByHandle(ThreadHandle,
2058  Access,
2059  PsThreadType,
2060  PreviousMode,
2061  (PVOID*)&Thread,
2062  NULL);
2063  if (!NT_SUCCESS(Status)) return Status;
2064 
2065  /* Check what kind of information class this is */
2066  switch (ThreadInformationClass)
2067  {
2068  /* Thread priority */
2069  case ThreadPriority:
2070 
2071  /* Check buffer length */
2072  if (ThreadInformationLength != sizeof(KPRIORITY))
2073  {
2075  break;
2076  }
2077 
2078  /* Use SEH for capture */
2079  _SEH2_TRY
2080  {
2081  /* Get the priority */
2082  Priority = *(PLONG)ThreadInformation;
2083  }
2085  {
2086  /* Get the exception code */
2088  _SEH2_YIELD(break);
2089  }
2090  _SEH2_END;
2091 
2092  /* Validate it */
2093  if ((Priority > HIGH_PRIORITY) ||
2094  (Priority <= LOW_PRIORITY))
2095  {
2096  /* Fail */
2098  break;
2099  }
2100 
2101  /* Set the priority */
2103  break;
2104 
2105  case ThreadBasePriority:
2106 
2107  /* Check buffer length */
2108  if (ThreadInformationLength != sizeof(LONG))
2109  {
2111  break;
2112  }
2113 
2114  /* Use SEH for capture */
2115  _SEH2_TRY
2116  {
2117  /* Get the priority */
2118  Priority = *(PLONG)ThreadInformation;
2119  }
2121  {
2122  /* Get the exception code */
2124  _SEH2_YIELD(break);
2125  }
2126  _SEH2_END;
2127 
2128  /* Validate it */
2131  {
2132  /* These ones are OK */
2133  if ((Priority != THREAD_BASE_PRIORITY_LOWRT + 1) &&
2135  {
2136  /* Check if the process is real time */
2137  if (PsGetCurrentProcess()->PriorityClass !=
2139  {
2140  /* It isn't, fail */
2142  break;
2143  }
2144  }
2145  }
2146 
2147  /* Set the base priority */
2149  break;
2150 
2151  case ThreadAffinityMask:
2152 
2153  /* Check buffer length */
2154  if (ThreadInformationLength != sizeof(ULONG_PTR))
2155  {
2157  break;
2158  }
2159 
2160  /* Use SEH for capture */
2161  _SEH2_TRY
2162  {
2163  /* Get the priority */
2164  Affinity = *(PULONG_PTR)ThreadInformation;
2165  }
2167  {
2168  /* Get the exception code */
2170  _SEH2_YIELD(break);
2171  }
2172  _SEH2_END;
2173 
2174  /* Validate it */
2175  if (!Affinity)
2176  {
2177  /* Fail */
2179  break;
2180  }
2181 
2182  /* Get the process */
2183  Process = Thread->ThreadsProcess;
2184 
2185  /* Try to acquire rundown */
2186  if (ExAcquireRundownProtection(&Process->RundownProtect))
2187  {
2188  /* Lock it */
2190  ExAcquirePushLockShared(&Process->ProcessLock);
2191 
2192  /* Combine masks */
2193  CombinedAffinity = Affinity & Process->Pcb.Affinity;
2194  if (CombinedAffinity != Affinity)
2195  {
2196  /* Fail */
2198  }
2199  else
2200  {
2201  /* Set the affinity */
2202  KeSetAffinityThread(&Thread->Tcb, CombinedAffinity);
2203  }
2204 
2205  /* Release the lock and rundown */
2206  ExReleasePushLockShared(&Process->ProcessLock);
2208  ExReleaseRundownProtection(&Process->RundownProtect);
2209  }
2210  else
2211  {
2212  /* Too late */
2214  }
2215 
2216  /* Return status */
2217  break;
2218 
2220 
2221  /* Check buffer length */
2222  if (ThreadInformationLength != sizeof(HANDLE))
2223  {
2225  break;
2226  }
2227 
2228  /* Use SEH for capture */
2229  _SEH2_TRY
2230  {
2231  /* Save the token handle */
2232  TokenHandle = *(PHANDLE)ThreadInformation;
2233  }
2235  {
2236  /* Get the exception code */
2238  _SEH2_YIELD(break);
2239  }
2240  _SEH2_END;
2241 
2242  /* Assign the actual token */
2244  break;
2245 
2247 
2248  /* Check buffer length */
2249  if (ThreadInformationLength != sizeof(ULONG_PTR))
2250  {
2252  break;
2253  }
2254 
2255  /* Use SEH for capture */
2256  _SEH2_TRY
2257  {
2258  /* Get the priority */
2259  Address = *(PVOID*)ThreadInformation;
2260  }
2262  {
2263  /* Get the exception code */
2265  _SEH2_YIELD(break);
2266  }
2267  _SEH2_END;
2268 
2269  /* Set the address */
2271  break;
2272 
2273  case ThreadIdealProcessor:
2274 
2275  /* Check buffer length */
2276  if (ThreadInformationLength != sizeof(ULONG_PTR))
2277  {
2279  break;
2280  }
2281 
2282  /* Use SEH for capture */
2283  _SEH2_TRY
2284  {
2285  /* Get the priority */
2286  IdealProcessor = *(PULONG_PTR)ThreadInformation;
2287  }
2289  {
2290  /* Get the exception code */
2292  _SEH2_YIELD(break);
2293  }
2294  _SEH2_END;
2295 
2296  /* Validate it */
2297  if (IdealProcessor > MAXIMUM_PROCESSORS)
2298  {
2299  /* Fail */
2301  break;
2302  }
2303 
2304  /* Set the ideal */
2306  (CCHAR)IdealProcessor);
2307 
2308  /* Get the TEB and protect the thread */
2309  Teb = Thread->Tcb.Teb;
2311  {
2312  /* Save the ideal processor */
2313  Teb->IdealProcessor = Thread->Tcb.IdealProcessor;
2314 
2315  /* Release rundown protection */
2317  }
2318 
2319  break;
2320 
2321  case ThreadPriorityBoost:
2322 
2323  /* Check buffer length */
2324  if (ThreadInformationLength != sizeof(ULONG_PTR))
2325  {
2327  break;
2328  }
2329 
2330  /* Use SEH for capture */
2331  _SEH2_TRY
2332  {
2333  /* Get the priority */
2334  DisableBoost = *(PULONG_PTR)ThreadInformation;
2335  }
2337  {
2338  /* Get the exception code */
2340  _SEH2_YIELD(break);
2341  }
2342  _SEH2_END;
2343 
2344  /* Call the kernel */
2345  KeSetDisableBoostThread(&Thread->Tcb, (BOOLEAN)DisableBoost);
2346  break;
2347 
2348  case ThreadZeroTlsCell:
2349 
2350  /* Check buffer length */
2351  if (ThreadInformationLength != sizeof(ULONG_PTR))
2352  {
2354  break;
2355  }
2356 
2357  /* Use SEH for capture */
2358  _SEH2_TRY
2359  {
2360  /* Get the priority */
2361  TlsIndex = *(PULONG_PTR)ThreadInformation;
2362  }
2364  {
2365  /* Get the exception code */
2367  _SEH2_YIELD(break);
2368  }
2369  _SEH2_END;
2370 
2371  /* This is only valid for the current thread */
2372  if (Thread != PsGetCurrentThread())
2373  {
2374  /* Fail */
2376  break;
2377  }
2378 
2379  /* Get the process */
2380  Process = Thread->ThreadsProcess;
2381 
2382  /* Loop the threads */
2383  ProcThread = PsGetNextProcessThread(Process, NULL);
2384  while (ProcThread)
2385  {
2386  /* Acquire rundown */
2387  if (ExAcquireRundownProtection(&ProcThread->RundownProtect))
2388  {
2389  /* Get the TEB */
2390  Teb = ProcThread->Tcb.Teb;
2391  if (Teb)
2392  {
2393  /* Check if we're in the expansion range */
2394  if (TlsIndex > TLS_MINIMUM_AVAILABLE - 1)
2395  {
2397  TLS_EXPANSION_SLOTS) - 1)
2398  {
2399  /* Check if we have expansion slots */
2400  ExpansionSlots = Teb->TlsExpansionSlots;
2401  if (ExpansionSlots)
2402  {
2403  /* Clear the index */
2404  ExpansionSlots[TlsIndex - TLS_MINIMUM_AVAILABLE] = 0;
2405  }
2406  }
2407  }
2408  else
2409  {
2410  /* Clear the index */
2411  Teb->TlsSlots[TlsIndex] = NULL;
2412  }
2413  }
2414 
2415  /* Release rundown */
2417  }
2418 
2419  /* Go to the next thread */
2420  ProcThread = PsGetNextProcessThread(Process, ProcThread);
2421  }
2422 
2423  /* All done */
2424  break;
2425 
2427 
2428  /* Check buffer length */
2429  if (ThreadInformationLength != sizeof(ULONG))
2430  {
2432  break;
2433  }
2434 
2435  /* Enter SEH for direct buffer read */
2436  _SEH2_TRY
2437  {
2438  Break = *(PULONG)ThreadInformation;
2439  }
2441  {
2442  /* Get exception code */
2443  Break = 0;
2445  _SEH2_YIELD(break);
2446  }
2447  _SEH2_END;
2448 
2449  /* Setting 'break on termination' requires the SeDebugPrivilege */
2451  {
2452  /* We don't hold the privilege, bail out */
2454  break;
2455  }
2456 
2457  /* Set or clear the flag */
2458  if (Break)
2459  {
2461  }
2462  else
2463  {
2465  }
2466  break;
2467 
2469 
2470  /* Check buffer length */
2471  if (ThreadInformationLength != 0)
2472  {
2474  break;
2475  }
2476 
2477  /* Set the flag */
2479  break;
2480 
2481  default:
2482  /* We don't implement it yet */
2483  DPRINT1("Not implemented: %d\n", ThreadInformationClass);
2485  }
2486 
2487  /* Dereference and return status */
2489  return Status;
2490 }
2491 
2492 /*
2493  * @implemented
2494  */
2495 NTSTATUS
2496 NTAPI
2499  OUT PVOID ThreadInformation,
2502 {
2503  PETHREAD Thread;
2505  NTSTATUS Status;
2506  ULONG Access;
2507  ULONG Length = 0;
2508  PTHREAD_BASIC_INFORMATION ThreadBasicInfo =
2509  (PTHREAD_BASIC_INFORMATION)ThreadInformation;
2510  PKERNEL_USER_TIMES ThreadTime = (PKERNEL_USER_TIMES)ThreadInformation;
2511  KIRQL OldIrql;
2512  ULONG ThreadTerminated;
2513  PAGED_CODE();
2514 
2515  /* Check if we were called from user mode */
2516  if (PreviousMode != KernelMode)
2517  {
2518  /* Enter SEH */
2519  _SEH2_TRY
2520  {
2521  /* Probe the buffer */
2522  ProbeForWrite(ThreadInformation,
2524  sizeof(ULONG));
2525 
2526  /* Probe the return length if required */
2528  }
2530  {
2531  /* Return the exception code */
2533  }
2534  _SEH2_END;
2535  }
2536 
2537  /* Check what class this is */
2538  Access = THREAD_QUERY_INFORMATION;
2539 
2540  /* Reference the process */
2541  Status = ObReferenceObjectByHandle(ThreadHandle,
2542  Access,
2543  PsThreadType,
2544  PreviousMode,
2545  (PVOID*)&Thread,
2546  NULL);
2547  if (!NT_SUCCESS(Status)) return Status;
2548 
2549  /* Check what kind of information class this is */
2550  switch (ThreadInformationClass)
2551  {
2552  /* Basic thread information */
2554 
2555  /* Set return length */
2556  Length = sizeof(THREAD_BASIC_INFORMATION);
2557 
2559  {
2561  break;
2562  }
2563  /* Protect writes with SEH */
2564  _SEH2_TRY
2565  {
2566  /* Write all the information from the ETHREAD/KTHREAD */
2567  ThreadBasicInfo->ExitStatus = Thread->ExitStatus;
2568  ThreadBasicInfo->TebBaseAddress = (PVOID)Thread->Tcb.Teb;
2569  ThreadBasicInfo->ClientId = Thread->Cid;
2570  ThreadBasicInfo->AffinityMask = Thread->Tcb.Affinity;
2571  ThreadBasicInfo->Priority = Thread->Tcb.Priority;
2572  ThreadBasicInfo->BasePriority = KeQueryBasePriorityThread(&Thread->Tcb);
2573  }
2575  {
2576  /* Get exception code */
2578  }
2579  _SEH2_END;
2580  break;
2581 
2582  /* Thread time information */
2583  case ThreadTimes:
2584 
2585  /* Set the return length */
2586  Length = sizeof(KERNEL_USER_TIMES);
2587 
2589  {
2591  break;
2592  }
2593  /* Protect writes with SEH */
2594  _SEH2_TRY
2595  {
2596  /* Copy time information from ETHREAD/KTHREAD */
2599  ThreadTime->CreateTime = Thread->CreateTime;
2600 
2601  /* Exit time is in a union and only valid on actual exit! */
2602  if (KeReadStateThread(&Thread->Tcb))
2603  {
2604  ThreadTime->ExitTime = Thread->ExitTime;
2605  }
2606  else
2607  {
2608  ThreadTime->ExitTime.QuadPart = 0;
2609  }
2610  }
2612  {
2613  /* Get exception code */
2615  }
2616  _SEH2_END;
2617  break;
2618 
2620 
2621  /* Set the return length*/
2622  Length = sizeof(PVOID);
2623 
2625  {
2627  break;
2628  }
2629  /* Protect write with SEH */
2630  _SEH2_TRY
2631  {
2632  /* Return the Win32 Start Address */
2633  *(PVOID*)ThreadInformation = Thread->Win32StartAddress;
2634  }
2636  {
2637  /* Get exception code */
2639  }
2640  _SEH2_END;
2641  break;
2642 
2644 
2645  /* Set the return length*/
2646  Length = sizeof(LARGE_INTEGER);
2647 
2649  {
2651  break;
2652  }
2653  /* Protect write with SEH */
2654  _SEH2_TRY
2655  {
2656  /* FIXME */
2657  (*(PLARGE_INTEGER)ThreadInformation).QuadPart = 0;
2658  }
2660  {
2661  /* Get exception code */
2663  }
2664  _SEH2_END;
2665  break;
2666 
2667  case ThreadAmILastThread:
2668 
2669  /* Set the return length*/
2670  Length = sizeof(ULONG);
2671 
2673  {
2675  break;
2676  }
2677  /* Protect write with SEH */
2678  _SEH2_TRY
2679  {
2680  /* Return whether or not we are the last thread */
2681  *(PULONG)ThreadInformation = ((Thread->ThreadsProcess->
2682  ThreadListHead.Flink->Flink ==
2683  &Thread->ThreadsProcess->
2684  ThreadListHead) ?
2685  TRUE : FALSE);
2686  }
2688  {
2689  /* Get exception code */
2691  }
2692  _SEH2_END;
2693  break;
2694 
2695  case ThreadIsIoPending:
2696 
2697  /* Set the return length*/
2698  Length = sizeof(ULONG);
2699 
2701  {
2703  break;
2704  }
2705  /* Raise the IRQL to protect the IRP list */
2707 
2708  /* Protect write with SEH */
2709  _SEH2_TRY
2710  {
2711  /* Check if the IRP list is empty or not */
2712  *(PULONG)ThreadInformation = !IsListEmpty(&Thread->IrpList);
2713  }
2715  {
2716  /* Get exception code */
2718  }
2719  _SEH2_END;
2720 
2721  /* Lower IRQL back */
2723  break;
2724 
2725  /* LDT and GDT information */
2727 
2728 #if defined(_X86_)
2729  /* Call the worker routine */
2731  ThreadInformation,
2733  ReturnLength);
2734 #else
2735  /* Only implemented on x86 */
2737 #endif
2738  break;
2739 
2740  case ThreadPriorityBoost:
2741 
2742  /* Set the return length*/
2743  Length = sizeof(ULONG);
2744 
2746  {
2748  break;
2749  }
2750 
2751  _SEH2_TRY
2752  {
2753  *(PULONG)ThreadInformation = Thread->Tcb.DisableBoost ? 1 : 0;
2754  }
2756  {
2758  }
2759  _SEH2_END;
2760  break;
2761 
2762  case ThreadIsTerminated:
2763 
2764  /* Set the return length*/
2765  Length = sizeof(ThreadTerminated);
2766 
2768  {
2770  break;
2771  }
2772 
2773  ThreadTerminated = PsIsThreadTerminating(Thread);
2774 
2775  _SEH2_TRY
2776  {
2777  *(PULONG)ThreadInformation = ThreadTerminated ? 1 : 0;
2778  }
2780  {
2782  }
2783  _SEH2_END;
2784 
2785  break;
2786 
2787  /* Anything else */
2788  default:
2789 
2790  /* Not yet implemented */
2791  DPRINT1("Not implemented: %lx\n", ThreadInformationClass);
2793  }
2794 
2795  /* Protect write with SEH */
2796  _SEH2_TRY
2797  {
2798  /* Check if caller wanted return length */
2800  }
2802  {
2803  /* Get exception code */
2805  }
2806  _SEH2_END;
2807 
2808  /* Dereference the thread, and return */
2810  return Status;
2811 }
2812 
2813 /* EOF */
#define ProbeForWriteUlong(Ptr)
Definition: probe.h:36
LARGE_INTEGER TimeLimit
Definition: lsa.idl:292
#define KeQuerySystemTime(t)
Definition: env_spec_w32.h:570
struct _THREAD_BASIC_INFORMATION THREAD_BASIC_INFORMATION
#define MAXIMUM_PROCESSORS
Definition: rwlock.h:5
BOOLEAN NTAPI KeSetDisableBoostThread(IN OUT PKTHREAD Thread, IN BOOLEAN Disable)
Definition: thrdobj.c:95
#define LOW_PRIORITY
ULONG KeMaximumIncrement
Definition: clock.c:20
IN CINT OUT PVOID IN ULONG OUT PULONG ReturnLength
Definition: dumpinfo.c:39
PFILE_OBJECT NTAPI MmGetFileObjectForSection(IN PVOID Section)
Definition: section.c:1681
SIZE_T PeakVirtualSize
Definition: winternl.h:1605
INT64 NonPagedPoolLimit
Definition: lsa.idl:288
#define PAGE_SHIFT
Definition: env_spec_w32.h:45
#define IN
Definition: typedefs.h:38
#define PspClearProcessFlag(Process, Flag)
Definition: ps_x.h:35
#define STATUS_PRIVILEGE_NOT_HELD
Definition: DriverTester.h:9
#define PSF_BREAK_ON_TERMINATION_BIT
Definition: pstypes.h:269
LARGE_INTEGER ExitTime
Definition: pstypes.h:1038
#define KeRaiseIrql(irql, oldIrql)
Definition: env_spec_w32.h:597
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
struct _KERNEL_USER_TIMES * PKERNEL_USER_TIMES
#define KeLowerIrql(oldIrql)
Definition: env_spec_w32.h:602
KAFFINITY NTAPI KeSetAffinityProcess(IN PKPROCESS Process, IN KAFFINITY Affinity)
Definition: procobj.c:265
INT64 PagefileLimit
Definition: lsa.idl:291
#define STATUS_INFO_LENGTH_MISMATCH
Definition: udferr_usr.h:133
ULONG InterruptTime
Definition: ketypes.h:736
KAFFINITY AffinityMask
Definition: compat.h:579
SIZE_T PeakPagefileUsage
Definition: winternl.h:1615
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
BOOLEAN NTAPI KeSetAutoAlignmentProcess(IN PKPROCESS Process, IN BOOLEAN Enable)
Definition: procobj.c:313
#define PspClearCrossThreadFlag(Thread, Flag)
Definition: ps_x.h:27
KAFFINITY NTAPI KeSetAffinityThread(IN PKTHREAD Thread, IN KAFFINITY Affinity)
Definition: thrdobj.c:1303
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:225
#define PROCESS_QUERY_INFORMATION
Definition: pstypes.h:158
const LUID SeDebugPrivilege
Definition: priv.c:41
#define SEM_NOALIGNMENTFAULTEXCEPT
Definition: rtltypes.h:71
NTKERNELAPI VOID FASTCALL ExReleaseRundownProtection(_Inout_ PEX_RUNDOWN_REF RunRef)
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
BOOLEAN NTAPI KeSetDisableBoostProcess(IN PKPROCESS Process, IN BOOLEAN Disable)
Definition: procobj.c:331
#define TLS_EXPANSION_SLOTS
Definition: pstypes.h:294
uint16_t * PWSTR
Definition: typedefs.h:54
SIZE_T QuotaPagedPoolUsage
Definition: winternl.h:1611
LARGE_INTEGER CreateTime
Definition: pstypes.h:1035
NTSTATUS NTAPI SeLocateProcessImageName(IN PEPROCESS Process, OUT PUNICODE_STRING *ProcessImageName)
Definition: audit.c:122
#define THREAD_SET_INFORMATION
Definition: nt_native.h:1337
#define THREAD_BASE_PRIORITY_MAX
Definition: pstypes.h:175
LONG NTSTATUS
Definition: precomp.h:26
struct _PROCESS_ACCESS_TOKEN * PPROCESS_ACCESS_TOKEN
LARGE_INTEGER UserTime
Definition: winternl.h:1063
EX_RUNDOWN_REF RundownProtect
Definition: pstypes.h:1090
NTSTATUS NTAPI NtQueryInformationProcess(IN HANDLE ProcessHandle, IN PROCESSINFOCLASS ProcessInformationClass, OUT PVOID ProcessInformation, IN ULONG ProcessInformationLength, OUT PULONG ReturnLength OPTIONAL)
Definition: query.c:59
NTSTATUS NTAPI ObSetDeviceMap(IN PEPROCESS Process, IN HANDLE DirectoryHandle)
Definition: devicemap.c:24
_IRQL_requires_same_ _In_ PLSA_STRING _In_ SECURITY_LOGON_TYPE _In_ ULONG _In_ ULONG _In_opt_ PTOKEN_GROUPS _In_ PTOKEN_SOURCE _Out_ PVOID _Out_ PULONG _Inout_ PLUID _Out_ PHANDLE Token
KTHREAD Tcb
Definition: pstypes.h:1034
FORCEINLINE struct _KPRCB * KeGetCurrentPrcb(VOID)
Definition: ketypes.h:1062
_In_ KPRIORITY Priority
Definition: kefuncs.h:516
#define ExAcquireRundownProtection
Definition: ex.h:130
SCHAR Priority
Definition: ketypes.h:1672
VOID NTAPI Ke386SetIOPL(VOID)
Definition: v86vdm.c:580
static HANDLE DirectoryHandle
Definition: ObType.c:48
SIZE_T PagefileUsage
Definition: winternl.h:1614
SIZE_T QuotaPeakPagedPoolUsage
Definition: winternl.h:1610
#define InterlockedCompareExchange
Definition: interlocked.h:104
NTSTATUS NTAPI ObQueryDeviceMapInformation(IN PEPROCESS Process, OUT PPROCESS_DEVICEMAP_INFORMATION DeviceMapInfo, IN ULONG Flags)
BOOLEAN NTAPI SeSinglePrivilegeCheck(IN LUID PrivilegeValue, IN KPROCESSOR_MODE PreviousMode)
Definition: priv.c:524
KPROCESSOR_MODE NTAPI ExGetPreviousMode(VOID)
Definition: sysinfo.c:3066
LONG NTAPI KeSetBasePriorityThread(IN PKTHREAD Thread, IN LONG Increment)
Definition: thrdobj.c:1184
VOID NTAPI ObDereferenceObject(IN PVOID Object)
Definition: obref.c:375
SIZE_T VirtualSize
Definition: winternl.h:1606
IO_COUNTERS IoInfo
Definition: ke.h:43
#define PROCESS_SUSPEND_RESUME
Definition: pstypes.h:159
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
static __inline NTSTATUS DefaultSetInfoBufferCheck(ULONG Class, const INFORMATION_CLASS_INFO *ClassList, ULONG ClassListEntries, PVOID Buffer, ULONG BufferLength, KPROCESSOR_MODE PreviousMode)
Definition: probe.h:8
#define THREAD_SET_THREAD_TOKEN
Definition: pstypes.h:142
VOID NTAPI ProbeForWrite(IN PVOID Address, IN SIZE_T Length, IN ULONG Alignment)
Definition: exintrin.c:143
LONG KPRIORITY
Definition: compat.h:454
#define PAGED_CODE()
Definition: video.h:57
KPRIORITY BasePriority
Definition: compat.h:581
_SEH2_TRY
Definition: create.c:4250
SIZE_T QuotaPeakNonPagedPoolUsage
Definition: winternl.h:1612
uint32_t ULONG_PTR
Definition: typedefs.h:63
ULONG PspTraceLevel
Definition: query.c:18
LARGE_INTEGER ExitTime
Definition: winternl.h:1061
NTSTATUS NTAPI PspQueryDescriptorThread(IN PETHREAD Thread, IN PVOID ThreadInformation, IN ULONG ThreadInformationLength, OUT PULONG ReturnLength OPTIONAL)
Definition: psldt.c:43
NTSTATUS NTAPI PspSetQuotaLimits(_In_ PEPROCESS Process, _In_ ULONG Unused, _In_ PVOID QuotaLimits, _In_ ULONG QuotaLimitsLength, _In_ KPROCESSOR_MODE PreviousMode)
Definition: quota.c:293
UCHAR KIRQL
Definition: env_spec_w32.h:591
ULONG PageFaultCount
Definition: winternl.h:1607
VOID NTAPI KeBoostPriorityThread(IN PKTHREAD Thread, IN KPRIORITY Increment)
Definition: thrdobj.c:229
struct _QUOTA_LIMITS QUOTA_LIMITS
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
NTSTATUS NTAPI ObReferenceObjectByHandle(IN HANDLE Handle, IN ACCESS_MASK DesiredAccess, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode, OUT PVOID *Object, OUT POBJECT_HANDLE_INFORMATION HandleInformation OPTIONAL)
Definition: obref.c:496
VOID NTAPI MmGetImageInformation(OUT PSECTION_IMAGE_INFORMATION ImageInformation)
Definition: section.c:1754
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
struct _VM_COUNTERS_ * PVM_COUNTERS
long LONG
Definition: pedump.c:60
EPROCESS_QUOTA_BLOCK PspDefaultQuotaBlock
Definition: quota.c:17
INT64 PagedPoolLimit
Definition: lsa.idl:287
struct _LARGE_INTEGER::@2201 u
ULONG NTAPI ObGetProcessHandleCount(IN PEPROCESS Process)
Definition: obhandle.c:59
PVOID Win32StartAddress
Definition: pstypes.h:1083
#define InterlockedCompareExchangePointer
Definition: interlocked.h:129
_In_ THREADINFOCLASS ThreadInformationClass
Definition: psfuncs.h:832
struct _QUOTA_LIMITS * PQUOTA_LIMITS
BOOLEAN NTAPI KeReadStateThread(IN PKTHREAD Thread)
Definition: thrdobj.c:51
#define PsGetCurrentProcess
Definition: psfuncs.h:17
struct _PROCESS_PRIORITY_CLASS PROCESS_PRIORITY_CLASS
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
NTSTATUS NTAPI MmGetExecuteOptions(IN PULONG ExecuteOptions)
Definition: pagfault.c:2521
KAFFINITY * PKAFFINITY
Definition: basetsd.h:197
NTSTATUS NTAPI PspSetPrimaryToken(IN PEPROCESS Process, IN HANDLE TokenHandle OPTIONAL, IN PACCESS_TOKEN Token OPTIONAL)
Definition: security.c:215
unsigned char BOOLEAN
struct _OBJECT_NAME_INFORMATION OBJECT_NAME_INFORMATION
SIZE_T QuotaNonPagedPoolUsage
Definition: winternl.h:1613
struct _PROCESS_BASIC_INFORMATION PROCESS_BASIC_INFORMATION
smooth NULL
Definition: ftsmooth.c:416
static WCHAR Address[46]
Definition: ping.c:68
_In_ ACCESS_MASK _In_ ULONG _Out_ PHANDLE TokenHandle
Definition: psfuncs.h:715
NTSTATUS NTAPI DbgkOpenProcessDebugPort(IN PEPROCESS Process, IN KPROCESSOR_MODE PreviousMode, OUT HANDLE *DebugHandle)
Definition: dbgkobj.c:1526
#define CT_HIDE_FROM_DEBUGGER_BIT
Definition: pstypes.h:224
NTSTATUS NTAPI NtSetInformationThread(IN HANDLE ThreadHandle, IN THREADINFOCLASS ThreadInformationClass, IN PVOID ThreadInformation, IN ULONG ThreadInformationLength)
Definition: query.c:2014
void * PVOID
Definition: retypes.h:9
#define CT_BREAK_ON_TERMINATION_BIT
Definition: pstypes.h:228
#define HIGH_PRIORITY
_Inout_ PFILE_OBJECT FileObject
Definition: cdprocs.h:593
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
#define UlongToPtr(u)
Definition: config.h:106
struct _THREAD_BASIC_INFORMATION * PTHREAD_BASIC_INFORMATION
ULONG_PTR InheritedFromUniqueProcessId
Definition: pstypes.h:340
#define NtCurrentProcess()
Definition: nt_native.h:1657
_Out_ PULONG UserTime
Definition: kefuncs.h:784
POBJECT_TYPE LpcPortObjectType
Definition: port.c:17
ULONG DisableBoost
Definition: ketypes.h:1615
#define PROCESS_PRIORITY_CLASS_ABOVE_NORMAL
Definition: pstypes.h:112
int64_t LONGLONG
Definition: typedefs.h:66
struct _LIST_ENTRY * Flink
Definition: typedefs.h:119
_In_ KPROCESSOR_MODE PreviousMode
Definition: sefuncs.h:103
struct _PROCESS_SESSION_INFORMATION * PPROCESS_SESSION_INFORMATION
#define THREAD_BASE_PRIORITY_LOWRT
Definition: pstypes.h:174
ULONG KernelTime
Definition: ketypes.h:1877
#define PROCESS_PRIORITY_CLASS_REALTIME
Definition: pstypes.h:110
#define _SEH2_YIELD(STMT_)
Definition: pseh2_64.h:8
struct _PROCESS_FOREGROUND_BACKGROUND * PPROCESS_FOREGROUND_BACKGROUND
VOID NTAPI KeQueryValuesProcess(IN PKPROCESS Process, PPROCESS_VALUES Values)
Definition: procobj.c:522
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
char CCHAR
Definition: typedefs.h:50
LARGE_INTEGER CreateTime
Definition: winternl.h:1060
#define PSF_NO_DEBUG_INHERIT_BIT
Definition: pstypes.h:258
CLIENT_ID Cid
Definition: pstypes.h:1059
#define THREAD_BASE_PRIORITY_IDLE
Definition: pstypes.h:177
_In_opt_ PVOID _Out_ PLARGE_INTEGER Cookie
Definition: cmfuncs.h:13
struct _PROCESS_BASIC_INFORMATION * PPROCESS_BASIC_INFORMATION
#define STATUS_PROCESS_IS_TERMINATING
Definition: ntstatus.h:488
_In_ ULONG _In_ ULONG _In_ ULONG _Out_ PKIRQL _Out_ PKAFFINITY Affinity
Definition: halfuncs.h:170
PVOID HANDLE
Definition: typedefs.h:71
#define MEMORY_PRIORITY_BACKGROUND
Definition: pstypes.h:124
ULONG KeSystemCalls
Definition: ketypes.h:647
_In_opt_ PFILE_OBJECT _In_opt_ PETHREAD Thread
Definition: fltkernel.h:2653
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
CCHAR KPROCESSOR_MODE
Definition: ketypes.h:7
NTSTATUS NTAPI PsReferenceProcessFilePointer(IN PEPROCESS Process, OUT PFILE_OBJECT *FileObject)
Definition: query.c:24
* PFILE_OBJECT
Definition: iotypes.h:1955
NTSTATUS NTAPI NtQueryInformationThread(IN HANDLE ThreadHandle, IN THREADINFOCLASS ThreadInformationClass, OUT PVOID ThreadInformation, IN ULONG ThreadInformationLength, OUT PULONG ReturnLength OPTIONAL)
Definition: query.c:2497
struct _SECTION_IMAGE_INFORMATION SECTION_IMAGE_INFORMATION
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
PETHREAD NTAPI PsGetNextProcessThread(IN PEPROCESS Process, IN PETHREAD Thread OPTIONAL)
Definition: process.c:75
VOID NTAPI KeDetachProcess(VOID)
Definition: procobj.c:618
struct _PROCESS_PRIORITY_CLASS * PPROCESS_PRIORITY_CLASS
unsigned char UCHAR
Definition: xmlstorage.h:181
static const char * ImageName
Definition: image.c:34
char * PBOOLEAN
Definition: retypes.h:11
union _LARGE_INTEGER LARGE_INTEGER
POBJECT_TYPE PsThreadType
Definition: thread.c:20
VOID NTAPI ProbeForRead(IN CONST VOID *Address, IN SIZE_T Length, IN ULONG Alignment)
Definition: exintrin.c:102
NTSTATUS NTAPI MmSetExecuteOptions(IN ULONG ExecuteOptions)
Definition: pagfault.c:2563
#define STATUS_INVALID_INFO_CLASS
Definition: ntstatus.h:226
#define PROCESS_LUID_DOSDEVICES_ONLY
Definition: pstypes.h:228
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:803
#define PspSetCrossThreadFlag(Thread, Flag)
Definition: ps_x.h:25
#define PSF_VDM_ALLOWED_BIT
Definition: pstypes.h:280
PVOID *typedef PHANDLE
Definition: ntsecpkg.h:414
#define KeEnterCriticalRegion()
Definition: ke_x.h:83
ULONG IdealProcessor
Definition: ketypes.h:1834
ULONG LowPart
Definition: typedefs.h:104
NTSTATUS NTAPI PsAssignImpersonationToken(IN PETHREAD Thread, IN HANDLE TokenHandle)
Definition: security.c:502
KPRIORITY NTAPI KeSetPriorityAndQuantumProcess(IN PKPROCESS Process, IN KPRIORITY Priority, IN UCHAR Quantum OPTIONAL)
Definition: procobj.c:349
Definition: typedefs.h:117
struct _KERNEL_USER_TIMES KERNEL_USER_TIMES
#define TlsIndex
Definition: ws2_32p.h:277
INT64 MinimumWorkingSetSize
Definition: lsa.idl:289
KAFFINITY KeActiveProcessors
Definition: krnlinit.c:23
VOID NTAPI PsSetProcessPriorityByClass(IN PEPROCESS Process, IN PSPROCESSPRIORITYMODE Type)
Definition: process.c:1325
const LUID SeIncreaseBasePriorityPrivilege
Definition: priv.c:35
BOOLEAN HasPrivilege(IN PPRIVILEGE_SET Privilege)
Definition: shutdown.c:92
Status
Definition: gdiplustypes.h:24
#define MEMORY_PRIORITY_FOREGROUND
Definition: pstypes.h:126
const LUID SeTcbPrivilege
Definition: priv.c:28
#define MAXULONG
Definition: typedefs.h:250
FORCEINLINE VOID ExAcquirePushLockShared(PEX_PUSH_LOCK PushLock)
Definition: ex.h:1091
ULONG_PTR SIZE_T
Definition: typedefs.h:78
SIZE_T WorkingSetSize
Definition: winternl.h:1609
Definition: compat.h:484
_SEH2_END
Definition: create.c:4424
NTSTATUS ExitStatus
Definition: pstypes.h:1044
#define KeLeaveCriticalRegion()
Definition: ke_x.h:114
#define THREAD_BASE_PRIORITY_MIN
Definition: pstypes.h:176
NTSTATUS NTAPI NtSetInformationProcess(IN HANDLE ProcessHandle, IN PROCESSINFOCLASS ProcessInformationClass, IN PVOID ProcessInformation, IN ULONG ProcessInformationLength)
Definition: query.c:1112
enum _THREADINFOCLASS THREADINFOCLASS
Definition: thread.c:106
struct _PROCESS_SESSION_INFORMATION PROCESS_SESSION_INFORMATION
KPRIORITY NTAPI KeSetPriorityThread(IN PKTHREAD Thread, IN KPRIORITY Priority)
Definition: thrdobj.c:1327
_In_ THREADINFOCLASS _In_ ULONG ThreadInformationLength
Definition: psfuncs.h:835
#define RTL_NUMBER_OF(x)
Definition: RtlRegistry.c:12
ULONG_PTR KAFFINITY
Definition: compat.h:75
VOID NTAPI KeAttachProcess(IN PKPROCESS Process)
Definition: procobj.c:579
ULONG NTAPI KeQueryRuntimeProcess(IN PKPROCESS Process, OUT PULONG UserTime)
Definition: procobj.c:857
NTSTATUS NTAPI MmSetMemoryPriorityProcess(IN PEPROCESS Process, IN UCHAR MemoryPriority)
Definition: procsup.c:469
unsigned int * PULONG
Definition: retypes.h:1
INT64 MaximumWorkingSetSize
Definition: lsa.idl:290
UNICODE_STRING * PUNICODE_STRING
Definition: env_spec_w32.h:373
struct _IO_COUNTERS IO_COUNTERS
PVOID Teb
Definition: ketypes.h:1697
#define DPRINT1
Definition: precomp.h:8
ULONG UserTime
Definition: ketypes.h:1893
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:219
#define PROCESS_SET_SESSIONID
Definition: pstypes.h:151
#define OUT
Definition: typedefs.h:39
#define ObReferenceObject
Definition: obfuncs.h:204
FORCEINLINE VOID ExReleasePushLockShared(PEX_PUSH_LOCK PushLock)
Definition: ex.h:1199
#define PspSetProcessFlag(Process, Flag)
Definition: ps_x.h:33
static LIST_ENTRY ThreadListHead
Definition: sys_arch.c:11
enum _PROCESSINFOCLASS PROCESSINFOCLASS
Definition: loader.c:63
#define THREAD_QUERY_INFORMATION
Definition: pstypes.h:141
GROUP_AFFINITY Affinity
Definition: ketypes.h:1828
unsigned int ULONG
Definition: retypes.h:1
ULONG NTAPI PsGetProcessSessionId(IN PEPROCESS Process)
Definition: process.c:1163
#define UNIMPLEMENTED
Definition: debug.h:114
#define ULONG_PTR
Definition: config.h:101
uint32_t * PULONG_PTR
Definition: typedefs.h:63
BOOLEAN NTAPI SeCheckPrivilegedObject(IN LUID PrivilegeValue, IN HANDLE ObjectHandle, IN ACCESS_MASK DesiredAccess, IN KPROCESSOR_MODE PreviousMode)
Definition: priv.c:560
#define PROCESS_SET_INFORMATION
Definition: pstypes.h:157
PVOID TlsSlots[64]
Definition: compat.h:528
PVOID * TlsExpansionSlots
Definition: compat.h:543
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:6
#define TAG_SEPA
Definition: tag.h:189
SIZE_T PeakWorkingSetSize
Definition: winternl.h:1608
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:12
UCHAR NTAPI KeSetIdealProcessorThread(IN PKTHREAD Thread, IN UCHAR Processor)
Definition: thrdobj.c:1075
BOOLEAN NTAPI PsIsThreadTerminating(IN PETHREAD Thread)
Definition: thread.c:868
_In_ HANDLE ProcessHandle
Definition: mmfuncs.h:403
return STATUS_SUCCESS
Definition: btrfs.c:2966
signed int * PLONG
Definition: retypes.h:5
ULONG NTAPI ObIsLUIDDeviceMapsEnabled(VOID)
Definition: devicemap.c:661
LARGE_INTEGER KernelTime
Definition: winternl.h:1062
LONG NTAPI KeQueryBasePriorityThread(IN PKTHREAD Thread)
Definition: thrdobj.c:61
LIST_ENTRY IrpList
Definition: pstypes.h:1075
#define APC_LEVEL
Definition: env_spec_w32.h:695
POBJECT_TYPE PsProcessType
Definition: process.c:20
ULONG ACCESS_MASK
Definition: nt_native.h:40
union _LARGE_INTEGER * PLARGE_INTEGER
Definition: file.c:85
LONGLONG QuadPart
Definition: typedefs.h:112
#define TLS_MINIMUM_AVAILABLE
Definition: ntddk_ex.h:236
struct _IO_COUNTERS * PIO_COUNTERS
#define STATUS_PORT_ALREADY_SET
Definition: ntstatus.h:294
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68