ReactOS  0.4.15-dev-1068-g467feb9
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_EX))
568  {
569  /* Protect read in SEH */
570  _SEH2_TRY
571  {
572  PPROCESS_DEVICEMAP_INFORMATION_EX DeviceMapEx = ProcessInformation;
573 
574  Flags = DeviceMapEx->Flags;
575  }
577  {
578  /* Get the exception code */
580  }
581  _SEH2_END;
582 
583  if (!NT_SUCCESS(Status))
584  {
585  break;
586  }
587 
588  /* Only one flag is supported and it needs LUID mappings */
589  if ((Flags & ~PROCESS_LUID_DOSDEVICES_ONLY) != 0 ||
591  {
593  break;
594  }
595  }
596  else
597  {
598  /* This has to be the size of the Query union field for x64 compatibility! */
599  if (ProcessInformationLength != RTL_FIELD_SIZE(PROCESS_DEVICEMAP_INFORMATION, Query))
600  {
602  break;
603  }
604 
605  /* No flags for standard call */
606  Flags = 0;
607  }
608 
609  /* Set the return length */
610  Length = ProcessInformationLength;
611 
612  /* Reference the process */
616  PreviousMode,
617  (PVOID*)&Process,
618  NULL);
619  if (!NT_SUCCESS(Status)) break;
620 
621  /* Query the device map information */
623  ProcessInformation,
624  Flags);
625 
626  /* Dereference the process */
628  break;
629 
630  /* Priority class */
632 
633  if (ProcessInformationLength != sizeof(PROCESS_PRIORITY_CLASS))
634  {
636  break;
637  }
638 
639  /* Set the return length*/
640  Length = sizeof(PROCESS_PRIORITY_CLASS);
641 
642  /* Reference the process */
646  PreviousMode,
647  (PVOID*)&Process,
648  NULL);
649  if (!NT_SUCCESS(Status)) break;
650 
651  /* Enter SEH for writing back data */
652  _SEH2_TRY
653  {
654  /* Return current priority class */
655  PsPriorityClass->PriorityClass = Process->PriorityClass;
656  PsPriorityClass->Foreground = FALSE;
657  }
659  {
660  /* Get the exception code */
662  }
663  _SEH2_END;
664 
665  /* Dereference the process */
667  break;
668 
670 
671  /* Reference the process */
675  PreviousMode,
676  (PVOID*)&Process,
677  NULL);
678  if (!NT_SUCCESS(Status)) break;
679 
680  /* Get the image path */
682  if (NT_SUCCESS(Status))
683  {
684  /* Set return length */
685  Length = ImageName->MaximumLength +
686  sizeof(OBJECT_NAME_INFORMATION);
687 
688  /* Make sure it's large enough */
689  if (Length <= ProcessInformationLength)
690  {
691  /* Enter SEH to protect write */
692  _SEH2_TRY
693  {
694  /* Copy it */
695  RtlCopyMemory(ProcessInformation,
696  ImageName,
697  Length);
698 
699  /* Update pointer */
700  ((PUNICODE_STRING)ProcessInformation)->Buffer =
701  (PWSTR)((PUNICODE_STRING)ProcessInformation + 1);
702  }
704  {
705  /* Get the exception code */
707  }
708  _SEH2_END;
709  }
710  else
711  {
712  /* Buffer too small */
714  }
715 
716  /* Free the image path */
718  }
719  /* Dereference the process */
721  break;
722 
723  case ProcessDebugFlags:
724 
725  if (ProcessInformationLength != sizeof(ULONG))
726  {
728  break;
729  }
730 
731  /* Set the return length*/
732  Length = sizeof(ULONG);
733 
734  /* Reference the process */
738  PreviousMode,
739  (PVOID*)&Process,
740  NULL);
741  if (!NT_SUCCESS(Status)) break;
742 
743  /* Enter SEH for writing back data */
744  _SEH2_TRY
745  {
746  /* Return the debug flag state */
747  *(PULONG)ProcessInformation = Process->NoDebugInherit ? 0 : 1;
748  }
750  {
751  /* Get the exception code */
753  }
754  _SEH2_END;
755 
756  /* Dereference the process */
758  break;
759 
761 
762  if (ProcessInformationLength != sizeof(ULONG))
763  {
765  break;
766  }
767 
768  /* Set the return length */
769  Length = sizeof(ULONG);
770 
771  /* Reference the process */
775  PreviousMode,
776  (PVOID*)&Process,
777  NULL);
778  if (!NT_SUCCESS(Status)) break;
779 
780  /* Enter SEH for writing back data */
781  _SEH2_TRY
782  {
783  /* Return the BreakOnTermination state */
784  *(PULONG)ProcessInformation = Process->BreakOnTermination;
785  }
787  {
788  /* Get the exception code */
790  }
791  _SEH2_END;
792 
793  /* Dereference the process */
795  break;
796 
797  /* Per-process security cookie */
798  case ProcessCookie:
799 
800  /* Get the current process and cookie */
802  Cookie = Process->Cookie;
803  if (!Cookie)
804  {
805  LARGE_INTEGER SystemTime;
806  ULONG NewCookie;
807  PKPRCB Prcb;
808 
809  /* Generate a new cookie */
810  KeQuerySystemTime(&SystemTime);
811  Prcb = KeGetCurrentPrcb();
812  NewCookie = Prcb->KeSystemCalls ^ Prcb->InterruptTime ^
813  SystemTime.u.LowPart ^ SystemTime.u.HighPart;
814 
815  /* Set the new cookie or return the current one */
817  NewCookie,
818  Cookie);
819  if (!Cookie) Cookie = NewCookie;
820 
821  /* Set return length */
822  Length = sizeof(ULONG);
823  }
824 
825  /* Indicate success */
827 
828  /* Enter SEH to protect write */
829  _SEH2_TRY
830  {
831  /* Write back the cookie */
832  *(PULONG)ProcessInformation = Cookie;
833  }
835  {
836  /* Get the exception code */
838  }
839  _SEH2_END;
840  break;
841 
843 
844  if (ProcessInformationLength != sizeof(SECTION_IMAGE_INFORMATION))
845  {
846  /* Break out */
848  break;
849  }
850 
851  /* Set the length required and validate it */
853 
854  /* Enter SEH to protect write */
855  _SEH2_TRY
856  {
858  }
860  {
861  /* Get the exception code */
863  }
864  _SEH2_END;
865 
866  /* Indicate success */
868  break;
869 
871 
872  if (ProcessInformationLength != sizeof(HANDLE))
873  {
875  break;
876  }
877 
878  /* Set the return length */
879  Length = sizeof(HANDLE);
880 
881  /* Reference the process */
885  PreviousMode,
886  (PVOID*)&Process,
887  NULL);
888  if (!NT_SUCCESS(Status)) break;
889 
890  /* Get the debug port */
892 
893  /* Let go of the process */
895 
896  /* Protect write in SEH */
897  _SEH2_TRY
898  {
899  /* Return debug port's handle */
900  *(PHANDLE)ProcessInformation = DebugPort;
901  }
903  {
904  /* Get the exception code */
906  }
907  _SEH2_END;
908  break;
909 
911  DPRINT1("Handle tracing Not implemented: %lx\n", ProcessInformationClass);
913  break;
914 
916 
917  if (ProcessInformationLength != sizeof(ULONG))
918  {
920  break;
921  }
922 
923  /* Set the return length */
924  Length = sizeof(ULONG);
925 
926  /* Indicate success */
928 
929  /* Protect write in SEH */
930  _SEH2_TRY
931  {
932  /* Query Ob */
933  *(PULONG)ProcessInformation = ObIsLUIDDeviceMapsEnabled();
934  }
936  {
937  /* Get the exception code */
939  }
940  _SEH2_END;
941  break;
942 
944 
945  if (ProcessInformationLength != sizeof(ULONG))
946  {
948  break;
949  }
950 
951  /* Set the return length */
952  Length = sizeof(ULONG);
953 
954  /* Reference the process */
958  PreviousMode,
959  (PVOID*)&Process,
960  NULL);
961  if (!NT_SUCCESS(Status)) break;
962 
963  /* Protect write in SEH */
964  _SEH2_TRY
965  {
966  /* Return if the flag is set */
967  *(PULONG)ProcessInformation = (ULONG)Process->VdmAllowed;
968  }
970  {
971  /* Get the exception code */
973  }
974  _SEH2_END;
975 
976  /* Dereference the process */
978  break;
979 
981 
982  if (ProcessInformationLength != sizeof(ULONG_PTR))
983  {
985  break;
986  }
987 
988  /* Set return length */
989  Length = sizeof(ULONG_PTR);
990 
991  /* Reference the process */
995  PreviousMode,
996  (PVOID*)&Process,
997  NULL);
998  if (!NT_SUCCESS(Status)) break;
999 
1000  /* Make sure the process isn't dying */
1001  if (ExAcquireRundownProtection(&Process->RundownProtect))
1002  {
1003  /* Get the WOW64 process structure */
1004 #ifdef _WIN64
1005  Wow64 = (ULONG_PTR)Process->Wow64Process;
1006 #else
1007  Wow64 = 0;
1008 #endif
1009  /* Release the lock */
1010  ExReleaseRundownProtection(&Process->RundownProtect);
1011  }
1012 
1013  /* Protect write with SEH */
1014  _SEH2_TRY
1015  {
1016  /* Return whether or not we have a debug port */
1017  *(PULONG_PTR)ProcessInformation = Wow64;
1018  }
1020  {
1021  /* Get exception code */
1023  }
1024  _SEH2_END;
1025 
1026  /* Dereference the process */
1028  break;
1029 
1030  case ProcessExecuteFlags:
1031 
1032  if (ProcessInformationLength != sizeof(ULONG))
1033  {
1035  break;
1036  }
1037 
1038  /* Set return length */
1039  Length = sizeof(ULONG);
1040 
1042  {
1043  return STATUS_INVALID_PARAMETER;
1044  }
1045 
1046  /* Get the options */
1047  Status = MmGetExecuteOptions(&ExecuteOptions);
1048  if (NT_SUCCESS(Status))
1049  {
1050  /* Protect write with SEH */
1051  _SEH2_TRY
1052  {
1053  /* Return them */
1054  *(PULONG)ProcessInformation = ExecuteOptions;
1055  }
1057  {
1058  /* Get exception code */
1060  }
1061  _SEH2_END;
1062  }
1063  break;
1064 
1065  case ProcessLdtInformation:
1066  DPRINT1("VDM/16-bit not implemented: %lx\n", ProcessInformationClass);
1068  break;
1069 
1071  DPRINT1("WS Watch Not implemented: %lx\n", ProcessInformationClass);
1073  break;
1074 
1076  DPRINT1("Pool limits Not implemented: %lx\n", ProcessInformationClass);
1078  break;
1079 
1080  /* Not supported by Server 2003 */
1081  default:
1082  DPRINT1("Unsupported info class: %lx\n", ProcessInformationClass);
1084  }
1085 
1086  /* Protect write with SEH */
1087  _SEH2_TRY
1088  {
1089  /* Check if caller wanted return length */
1090  if ((ReturnLength) && (Length)) *ReturnLength = Length;
1091  }
1093  {
1094  /* Get exception code */
1096  }
1097  _SEH2_END;
1098 
1099  return Status;
1100 }
1101 
1102 /*
1103  * @implemented
1104  */
1105 NTSTATUS
1106 NTAPI
1108  IN PROCESSINFOCLASS ProcessInformationClass,
1109  IN PVOID ProcessInformation,
1110  IN ULONG ProcessInformationLength)
1111 {
1114  ACCESS_MASK Access;
1115  NTSTATUS Status;
1116  HANDLE PortHandle = NULL;
1120  PROCESS_PRIORITY_CLASS PriorityClass = {0};
1121  PROCESS_FOREGROUND_BACKGROUND Foreground = {0};
1122  PVOID ExceptionPort;
1123  ULONG Break;
1124  KAFFINITY ValidAffinity, Affinity = 0;
1125  KPRIORITY BasePriority = 0;
1126  UCHAR MemoryPriority = 0;
1127  BOOLEAN DisableBoost = 0;
1128  ULONG DefaultHardErrorMode = 0;
1129  ULONG DebugFlags = 0, EnableFixup = 0, Boost = 0;
1130  ULONG NoExecute = 0, VdmPower = 0;
1132  PLIST_ENTRY Next;
1133  PETHREAD Thread;
1134  PAGED_CODE();
1135 
1136  /* Verify Information Class validity */
1137 #if 0
1138  Status = DefaultSetInfoBufferCheck(ProcessInformationClass,
1139  PsProcessInfoClass,
1140  RTL_NUMBER_OF(PsProcessInfoClass),
1141  ProcessInformation,
1142  ProcessInformationLength,
1143  PreviousMode);
1144  if (!NT_SUCCESS(Status)) return Status;
1145 #endif
1146 
1147  /* Check what class this is */
1148  Access = PROCESS_SET_INFORMATION;
1149  if (ProcessInformationClass == ProcessSessionInformation)
1150  {
1151  /* Setting the Session ID needs a special mask */
1152  Access |= PROCESS_SET_SESSIONID;
1153  }
1154  else if (ProcessInformationClass == ProcessExceptionPort)
1155  {
1156  /* Setting the exception port needs a special mask */
1157  Access |= PROCESS_SUSPEND_RESUME;
1158  }
1159 
1160  /* Reference the process */
1162  Access,
1163  PsProcessType,
1164  PreviousMode,
1165  (PVOID*)&Process,
1166  NULL);
1167  if (!NT_SUCCESS(Status)) return Status;
1168 
1169  /* Check what kind of information class this is */
1170  switch (ProcessInformationClass)
1171  {
1173 
1174  /* Check buffer length */
1175  if (ProcessInformationLength != sizeof(HANDLE))
1176  {
1178  break;
1179  }
1180 
1181  /* Use SEH for capture */
1182  _SEH2_TRY
1183  {
1184  /* Capture the boolean */
1185  VdmPower = *(PULONG)ProcessInformation;
1186  }
1188  {
1189  /* Get the exception code */
1191  _SEH2_YIELD(break);
1192  }
1193  _SEH2_END;
1194 
1195  /* Getting VDM powers requires the SeTcbPrivilege */
1197  {
1198  /* We don't hold the privilege, bail out */
1200  DPRINT1("Need TCB privilege\n");
1201  break;
1202  }
1203 
1204  /* Set or clear the flag */
1205  if (VdmPower)
1206  {
1208  }
1209  else
1210  {
1212  }
1213  break;
1214 
1215  /* Error/Exception Port */
1216  case ProcessExceptionPort:
1217 
1218  /* Check buffer length */
1219  if (ProcessInformationLength != sizeof(HANDLE))
1220  {
1222  break;
1223  }
1224 
1225  /* Use SEH for capture */
1226  _SEH2_TRY
1227  {
1228  /* Capture the handle */
1229  PortHandle = *(PHANDLE)ProcessInformation;
1230  }
1232  {
1233  /* Get the exception code */
1235  _SEH2_YIELD(break);
1236  }
1237  _SEH2_END;
1238 
1239  /* Setting the error port requires the SeTcbPrivilege */
1241  {
1242  /* We don't hold the privilege, bail out */
1244  break;
1245  }
1246 
1247  /* Get the LPC Port */
1248  Status = ObReferenceObjectByHandle(PortHandle,
1249  0,
1251  PreviousMode,
1252  (PVOID)&ExceptionPort,
1253  NULL);
1254  if (!NT_SUCCESS(Status)) break;
1255 
1256  /* Change the pointer */
1257  if (InterlockedCompareExchangePointer(&Process->ExceptionPort,
1258  ExceptionPort,
1259  NULL))
1260  {
1261  /* We already had one, fail */
1262  ObDereferenceObject(ExceptionPort);
1264  }
1265  break;
1266 
1267  /* Security Token */
1268  case ProcessAccessToken:
1269 
1270  /* Check buffer length */
1271  if (ProcessInformationLength != sizeof(PROCESS_ACCESS_TOKEN))
1272  {
1274  break;
1275  }
1276 
1277  /* Use SEH for capture */
1278  _SEH2_TRY
1279  {
1280  /* Save the token handle */
1281  TokenHandle = ((PPROCESS_ACCESS_TOKEN)ProcessInformation)->
1282  Token;
1283  }
1285  {
1286  /* Get the exception code */
1288  _SEH2_YIELD(break);
1289  }
1290  _SEH2_END;
1291 
1292  /* Assign the actual token */
1294  break;
1295 
1296  /* Hard error processing */
1298 
1299  /* Check buffer length */
1300  if (ProcessInformationLength != sizeof(ULONG))
1301  {
1303  break;
1304  }
1305 
1306  /* Enter SEH for direct buffer read */
1307  _SEH2_TRY
1308  {
1309  DefaultHardErrorMode = *(PULONG)ProcessInformation;
1310  }
1312  {
1313  /* Get exception code */
1315  _SEH2_YIELD(break);
1316  }
1317  _SEH2_END;
1318 
1319  /* Set the mode */
1320  Process->DefaultHardErrorProcessing = DefaultHardErrorMode;
1321 
1322  /* Call Ke for the update */
1323  if (DefaultHardErrorMode & SEM_NOALIGNMENTFAULTEXCEPT)
1324  {
1326  }
1327  else
1328  {
1330  }
1332  break;
1333 
1334  /* Session ID */
1336 
1337  /* Check buffer length */
1338  if (ProcessInformationLength != sizeof(PROCESS_SESSION_INFORMATION))
1339  {
1341  break;
1342  }
1343 
1344  /* Enter SEH for capture */
1345  _SEH2_TRY
1346  {
1347  /* Capture the caller's buffer */
1348  SessionInfo = *(PPROCESS_SESSION_INFORMATION)ProcessInformation;
1349  }
1351  {
1352  /* Get the exception code */
1354  _SEH2_YIELD(break);
1355  }
1356  _SEH2_END;
1357 
1358  /* Setting the session id requires the SeTcbPrivilege */
1360  {
1361  /* We don't hold the privilege, bail out */
1363  break;
1364  }
1365 
1366 #if 0 // OLD AND DEPRECATED CODE!!!!
1367 
1368  /* FIXME - update the session id for the process token */
1369  //Status = PsLockProcess(Process, FALSE);
1370  if (!NT_SUCCESS(Status)) break;
1371 
1372  /* Write the session ID in the EPROCESS */
1373  Process->Session = UlongToPtr(SessionInfo.SessionId); // HACK!!!
1374 
1375  /* Check if the process also has a PEB */
1376  if (Process->Peb)
1377  {
1378  /*
1379  * Attach to the process to make sure we're in the right
1380  * context to access the PEB structure
1381  */
1382  KeAttachProcess(&Process->Pcb);
1383 
1384  /* Enter SEH for write to user-mode PEB */
1385  _SEH2_TRY
1386  {
1387  /* Write the session ID */
1388  Process->Peb->SessionId = SessionInfo.SessionId;
1389  }
1391  {
1392  /* Get exception code */
1394  }
1395  _SEH2_END;
1396 
1397  /* Detach from the process */
1398  KeDetachProcess();
1399  }
1400 
1401  /* Unlock the process */
1402  //PsUnlockProcess(Process);
1403 
1404 #endif
1405 
1406  /*
1407  * Since we cannot change the session ID of the given
1408  * process anymore because it is set once and for all
1409  * at process creation time and because it is stored
1410  * inside the Process->Session structure managed by MM,
1411  * we fake changing it: we just return success if the
1412  * user-defined value is the same as the session ID of
1413  * the process, and otherwise we fail.
1414  */
1415  if (SessionInfo.SessionId == PsGetProcessSessionId(Process))
1416  {
1418  }
1419  else
1420  {
1422  }
1423 
1424  break;
1425 
1426  case ProcessPriorityClass:
1427 
1428  /* Check buffer length */
1429  if (ProcessInformationLength != sizeof(PROCESS_PRIORITY_CLASS))
1430  {
1432  break;
1433  }
1434 
1435  /* Enter SEH for capture */
1436  _SEH2_TRY
1437  {
1438  /* Capture the caller's buffer */
1439  PriorityClass = *(PPROCESS_PRIORITY_CLASS)ProcessInformation;
1440  }
1442  {
1443  /* Return the exception code */
1445  _SEH2_YIELD(break);
1446  }
1447  _SEH2_END;
1448 
1449  /* Check for invalid PriorityClass value */
1451  {
1453  break;
1454  }
1455 
1456  if ((PriorityClass.PriorityClass != Process->PriorityClass) &&
1458  {
1459  /* Check the privilege */
1461  ProcessHandle,
1463  PreviousMode);
1464  if (!HasPrivilege)
1465  {
1467  DPRINT1("Privilege to change priority to realtime lacking\n");
1469  }
1470  }
1471 
1472  /* Check if we have a job */
1473  if (Process->Job)
1474  {
1475  DPRINT1("Jobs not yet supported\n");
1476  }
1477 
1478  /* Set process priority class */
1479  Process->PriorityClass = PriorityClass.PriorityClass;
1480 
1481  /* Set process priority mode (foreground or background) */
1483  PriorityClass.Foreground ?
1487  break;
1488 
1490 
1491  /* Check buffer length */
1492  if (ProcessInformationLength != sizeof(PROCESS_FOREGROUND_BACKGROUND))
1493  {
1495  break;
1496  }
1497 
1498  /* Enter SEH for capture */
1499  _SEH2_TRY
1500  {
1501  /* Capture the caller's buffer */
1502  Foreground = *(PPROCESS_FOREGROUND_BACKGROUND)ProcessInformation;
1503  }
1505  {
1506  /* Return the exception code */
1508  _SEH2_YIELD(break);
1509  }
1510  _SEH2_END;
1511 
1512  /* Set process priority mode (foreground or background) */
1514  Foreground.Foreground ?
1518  break;
1519 
1520  case ProcessBasePriority:
1521 
1522  /* Validate input length */
1523  if (ProcessInformationLength != sizeof(KPRIORITY))
1524  {
1526  break;
1527  }
1528 
1529  /* Enter SEH for direct buffer read */
1530  _SEH2_TRY
1531  {
1532  BasePriority = *(KPRIORITY*)ProcessInformation;
1533  }
1535  {
1536  /* Get exception code */
1537  Break = 0;
1539  _SEH2_YIELD(break);
1540  }
1541  _SEH2_END;
1542 
1543  /* Extract the memory priority out of there */
1544  if (BasePriority & 0x80000000)
1545  {
1546  MemoryPriority = MEMORY_PRIORITY_FOREGROUND;
1547  BasePriority &= ~0x80000000;
1548  }
1549  else
1550  {
1551  MemoryPriority = MEMORY_PRIORITY_BACKGROUND;
1552  }
1553 
1554  /* Validate the number */
1555  if ((BasePriority > HIGH_PRIORITY) || (BasePriority <= LOW_PRIORITY))
1556  {
1558  return STATUS_INVALID_PARAMETER;
1559  }
1560 
1561  /* Check if the new base is higher */
1562  if (BasePriority > Process->Pcb.BasePriority)
1563  {
1565  ProcessHandle,
1567  PreviousMode);
1568  if (!HasPrivilege)
1569  {
1571  DPRINT1("Privilege to change priority from %lx to %lx lacking\n", BasePriority, Process->Pcb.BasePriority);
1573  }
1574  }
1575 
1576  /* Call Ke */
1577  KeSetPriorityAndQuantumProcess(&Process->Pcb, BasePriority, 0);
1578 
1579  /* Now set the memory priority */
1580  MmSetMemoryPriorityProcess(Process, MemoryPriority);
1582  break;
1583 
1584  case ProcessRaisePriority:
1585 
1586  /* Validate input length */
1587  if (ProcessInformationLength != sizeof(ULONG))
1588  {
1590  break;
1591  }
1592 
1593  /* Enter SEH for direct buffer read */
1594  _SEH2_TRY
1595  {
1596  Boost = *(PULONG)ProcessInformation;
1597  }
1599  {
1600  /* Get exception code */
1601  Break = 0;
1603  _SEH2_YIELD(break);
1604  }
1605  _SEH2_END;
1606 
1607  /* Make sure the process isn't dying */
1608  if (ExAcquireRundownProtection(&Process->RundownProtect))
1609  {
1610  /* Lock it */
1612  ExAcquirePushLockShared(&Process->ProcessLock);
1613 
1614  /* Loop the threads */
1615  for (Next = Process->ThreadListHead.Flink;
1616  Next != &Process->ThreadListHead;
1617  Next = Next->Flink)
1618  {
1619  /* Call Ke for the thread */
1620  Thread = CONTAINING_RECORD(Next, ETHREAD, ThreadListEntry);
1621  KeBoostPriorityThread(&Thread->Tcb, Boost);
1622  }
1623 
1624  /* Release the lock and rundown */
1625  ExReleasePushLockShared(&Process->ProcessLock);
1627  ExReleaseRundownProtection(&Process->RundownProtect);
1628 
1629  /* Set success code */
1631  }
1632  else
1633  {
1634  /* Avoid race conditions */
1636  }
1637  break;
1638 
1640 
1641  /* Check buffer length */
1642  if (ProcessInformationLength != sizeof(ULONG))
1643  {
1645  break;
1646  }
1647 
1648  /* Enter SEH for direct buffer read */
1649  _SEH2_TRY
1650  {
1651  Break = *(PULONG)ProcessInformation;
1652  }
1654  {
1655  /* Get exception code */
1656  Break = 0;
1658  _SEH2_YIELD(break);
1659  }
1660  _SEH2_END;
1661 
1662  /* Setting 'break on termination' requires the SeDebugPrivilege */
1664  {
1665  /* We don't hold the privilege, bail out */
1667  break;
1668  }
1669 
1670  /* Set or clear the flag */
1671  if (Break)
1672  {
1674  }
1675  else
1676  {
1678  }
1679 
1680  break;
1681 
1682  case ProcessAffinityMask:
1683 
1684  /* Check buffer length */
1685  if (ProcessInformationLength != sizeof(KAFFINITY))
1686  {
1688  break;
1689  }
1690 
1691  /* Enter SEH for direct buffer read */
1692  _SEH2_TRY
1693  {
1694  Affinity = *(PKAFFINITY)ProcessInformation;
1695  }
1697  {
1698  /* Get exception code */
1699  Break = 0;
1701  _SEH2_YIELD(break);
1702  }
1703  _SEH2_END;
1704 
1705  /* Make sure it's valid for the CPUs present */
1706  ValidAffinity = Affinity & KeActiveProcessors;
1707  if (!Affinity || (ValidAffinity != Affinity))
1708  {
1710  break;
1711  }
1712 
1713  /* Check if it's within job affinity limits */
1714  if (Process->Job)
1715  {
1716  /* Not yet implemented */
1717  UNIMPLEMENTED;
1719  break;
1720  }
1721 
1722  /* Make sure the process isn't dying */
1723  if (ExAcquireRundownProtection(&Process->RundownProtect))
1724  {
1725  /* Lock it */
1727  ExAcquirePushLockShared(&Process->ProcessLock);
1728 
1729  /* Call Ke to do the work */
1730  KeSetAffinityProcess(&Process->Pcb, ValidAffinity);
1731 
1732  /* Release the lock and rundown */
1733  ExReleasePushLockShared(&Process->ProcessLock);
1735  ExReleaseRundownProtection(&Process->RundownProtect);
1736 
1737  /* Set success code */
1739  }
1740  else
1741  {
1742  /* Avoid race conditions */
1744  }
1745  break;
1746 
1747  /* Priority Boosting status */
1748  case ProcessPriorityBoost:
1749 
1750  /* Validate input length */
1751  if (ProcessInformationLength != sizeof(ULONG))
1752  {
1754  break;
1755  }
1756 
1757  /* Enter SEH for direct buffer read */
1758  _SEH2_TRY
1759  {
1760  DisableBoost = *(PBOOLEAN)ProcessInformation;
1761  }
1763  {
1764  /* Get exception code */
1765  Break = 0;
1767  _SEH2_YIELD(break);
1768  }
1769  _SEH2_END;
1770 
1771  /* Make sure the process isn't dying */
1772  if (ExAcquireRundownProtection(&Process->RundownProtect))
1773  {
1774  /* Lock it */
1776  ExAcquirePushLockShared(&Process->ProcessLock);
1777 
1778  /* Call Ke to do the work */
1779  KeSetDisableBoostProcess(&Process->Pcb, DisableBoost);
1780 
1781  /* Loop the threads too */
1782  for (Next = Process->ThreadListHead.Flink;
1783  Next != &Process->ThreadListHead;
1784  Next = Next->Flink)
1785  {
1786  /* Call Ke for the thread */
1787  Thread = CONTAINING_RECORD(Next, ETHREAD, ThreadListEntry);
1788  KeSetDisableBoostThread(&Thread->Tcb, DisableBoost);
1789  }
1790 
1791  /* Release the lock and rundown */
1792  ExReleasePushLockShared(&Process->ProcessLock);
1794  ExReleaseRundownProtection(&Process->RundownProtect);
1795 
1796  /* Set success code */
1798  }
1799  else
1800  {
1801  /* Avoid race conditions */
1803  }
1804  break;
1805 
1806  case ProcessDebugFlags:
1807 
1808  /* Check buffer length */
1809  if (ProcessInformationLength != sizeof(ULONG))
1810  {
1812  break;
1813  }
1814 
1815  /* Enter SEH for direct buffer read */
1816  _SEH2_TRY
1817  {
1818  DebugFlags = *(PULONG)ProcessInformation;
1819  }
1821  {
1822  /* Get exception code */
1824  _SEH2_YIELD(break);
1825  }
1826  _SEH2_END;
1827 
1828  /* Set the mode */
1829  if (DebugFlags & ~1)
1830  {
1832  }
1833  else
1834  {
1835  if (DebugFlags & 1)
1836  {
1838  }
1839  else
1840  {
1842  }
1843  }
1844 
1845  /* Done */
1847  break;
1848 
1850 
1851  /* Check buffer length */
1852  if (ProcessInformationLength != sizeof(ULONG))
1853  {
1855  break;
1856  }
1857 
1858  /* Enter SEH for direct buffer read */
1859  _SEH2_TRY
1860  {
1861  EnableFixup = *(PULONG)ProcessInformation;
1862  }
1864  {
1865  /* Get exception code */
1867  _SEH2_YIELD(break);
1868  }
1869  _SEH2_END;
1870 
1871  /* Set the mode */
1872  if (EnableFixup)
1873  {
1874  Process->DefaultHardErrorProcessing |= SEM_NOALIGNMENTFAULTEXCEPT;
1875  }
1876  else
1877  {
1878  Process->DefaultHardErrorProcessing &= ~SEM_NOALIGNMENTFAULTEXCEPT;
1879  }
1880 
1881  /* Call Ke for the update */
1884  break;
1885 
1886  case ProcessUserModeIOPL:
1887 
1888  /* Only TCB can do this */
1890  {
1891  /* We don't hold the privilege, bail out */
1892  DPRINT1("Need TCB to set IOPL\n");
1894  break;
1895  }
1896 
1897  /* Only supported on x86 */
1898 #if defined (_X86_)
1899  Ke386SetIOPL();
1900 #elif defined(_M_AMD64)
1901  /* On x64 this function isn't implemented.
1902  On Windows 2003 it returns success.
1903  On Vista+ it returns STATUS_NOT_IMPLEMENTED. */
1904  if ((ExGetPreviousMode() != KernelMode) &&
1905  (RtlRosGetAppcompatVersion() > _WIN32_WINNT_WS03))
1906  {
1908  }
1909 #else
1911 #endif
1912  /* Done */
1913  break;
1914 
1915  case ProcessExecuteFlags:
1916 
1917  /* Check buffer length */
1918  if (ProcessInformationLength != sizeof(ULONG))
1919  {
1921  break;
1922  }
1923 
1925  {
1927  break;
1928  }
1929 
1930  /* Enter SEH for direct buffer read */
1931  _SEH2_TRY
1932  {
1933  NoExecute = *(PULONG)ProcessInformation;
1934  }
1936  {
1937  /* Get exception code */
1939  _SEH2_YIELD(break);
1940  }
1941  _SEH2_END;
1942 
1943  /* Call Mm for the update */
1944  Status = MmSetExecuteOptions(NoExecute);
1945  break;
1946 
1947  case ProcessDeviceMap:
1948 
1949  /* Check buffer length */
1950  if (ProcessInformationLength != sizeof(HANDLE))
1951  {
1953  break;
1954  }
1955 
1956  /* Use SEH for capture */
1957  _SEH2_TRY
1958  {
1959  /* Capture the handle */
1960  DirectoryHandle = *(PHANDLE)ProcessInformation;
1961  }
1963  {
1964  /* Get the exception code */
1966  _SEH2_YIELD(break);
1967  }
1968  _SEH2_END;
1969 
1970  /* Call Ob to set the device map */
1972  break;
1973 
1974 
1975  /* We currently don't implement any of these */
1976  case ProcessLdtInformation:
1977  case ProcessLdtSize:
1978  case ProcessIoPortHandlers:
1979  DPRINT1("VDM/16-bit Request not implemented: %lx\n", ProcessInformationClass);
1981  break;
1982 
1983  case ProcessQuotaLimits:
1984 
1986  1,
1987  ProcessInformation,
1988  ProcessInformationLength,
1989  PreviousMode);
1990  break;
1991 
1993  DPRINT1("WS watch not implemented\n");
1995  break;
1996 
1997  case ProcessHandleTracing:
1998  DPRINT1("Handle tracing not implemented\n");
2000  break;
2001 
2002  /* Anything else is invalid */
2003  default:
2004  DPRINT1("Invalid Server 2003 Info Class: %lx\n", ProcessInformationClass);
2006  }
2007 
2008  /* Dereference and return status */
2010  return Status;
2011 }
2012 
2013 /*
2014  * @implemented
2015  */
2016 NTSTATUS
2017 NTAPI
2020  IN PVOID ThreadInformation,
2022 {
2023  PETHREAD Thread;
2024  ULONG Access;
2026  NTSTATUS Status;
2028  KPRIORITY Priority = 0;
2029  KAFFINITY Affinity = 0, CombinedAffinity;
2030  PVOID Address = NULL;
2032  ULONG_PTR DisableBoost = 0;
2033  ULONG_PTR IdealProcessor = 0;
2034  ULONG_PTR Break = 0;
2035  PTEB Teb;
2036  ULONG_PTR TlsIndex = 0;
2037  PVOID *ExpansionSlots;
2038  PETHREAD ProcThread;
2039  PAGED_CODE();
2040 
2041  /* Verify Information Class validity */
2042 #if 0
2044  PsThreadInfoClass,
2045  RTL_NUMBER_OF(PsThreadInfoClass),
2046  ThreadInformation,
2048  PreviousMode);
2049  if (!NT_SUCCESS(Status)) return Status;
2050 #endif
2051 
2052  /* Check what class this is */
2053  Access = THREAD_SET_INFORMATION;
2055  {
2056  /* Setting the impersonation token needs a special mask */
2057  Access = THREAD_SET_THREAD_TOKEN;
2058  }
2059 
2060  /* Reference the thread */
2061  Status = ObReferenceObjectByHandle(ThreadHandle,
2062  Access,
2063  PsThreadType,
2064  PreviousMode,
2065  (PVOID*)&Thread,
2066  NULL);
2067  if (!NT_SUCCESS(Status)) return Status;
2068 
2069  /* Check what kind of information class this is */
2070  switch (ThreadInformationClass)
2071  {
2072  /* Thread priority */
2073  case ThreadPriority:
2074 
2075  /* Check buffer length */
2076  if (ThreadInformationLength != sizeof(KPRIORITY))
2077  {
2079  break;
2080  }
2081 
2082  /* Use SEH for capture */
2083  _SEH2_TRY
2084  {
2085  /* Get the priority */
2086  Priority = *(PLONG)ThreadInformation;
2087  }
2089  {
2090  /* Get the exception code */
2092  _SEH2_YIELD(break);
2093  }
2094  _SEH2_END;
2095 
2096  /* Validate it */
2097  if ((Priority > HIGH_PRIORITY) ||
2098  (Priority <= LOW_PRIORITY))
2099  {
2100  /* Fail */
2102  break;
2103  }
2104 
2105  /* Set the priority */
2107  break;
2108 
2109  case ThreadBasePriority:
2110 
2111  /* Check buffer length */
2112  if (ThreadInformationLength != sizeof(LONG))
2113  {
2115  break;
2116  }
2117 
2118  /* Use SEH for capture */
2119  _SEH2_TRY
2120  {
2121  /* Get the priority */
2122  Priority = *(PLONG)ThreadInformation;
2123  }
2125  {
2126  /* Get the exception code */
2128  _SEH2_YIELD(break);
2129  }
2130  _SEH2_END;
2131 
2132  /* Validate it */
2135  {
2136  /* These ones are OK */
2137  if ((Priority != THREAD_BASE_PRIORITY_LOWRT + 1) &&
2139  {
2140  /* Check if the process is real time */
2141  if (PsGetCurrentProcess()->PriorityClass !=
2143  {
2144  /* It isn't, fail */
2146  break;
2147  }
2148  }
2149  }
2150 
2151  /* Set the base priority */
2153  break;
2154 
2155  case ThreadAffinityMask:
2156 
2157  /* Check buffer length */
2158  if (ThreadInformationLength != sizeof(ULONG_PTR))
2159  {
2161  break;
2162  }
2163 
2164  /* Use SEH for capture */
2165  _SEH2_TRY
2166  {
2167  /* Get the priority */
2168  Affinity = *(PULONG_PTR)ThreadInformation;
2169  }
2171  {
2172  /* Get the exception code */
2174  _SEH2_YIELD(break);
2175  }
2176  _SEH2_END;
2177 
2178  /* Validate it */
2179  if (!Affinity)
2180  {
2181  /* Fail */
2183  break;
2184  }
2185 
2186  /* Get the process */
2187  Process = Thread->ThreadsProcess;
2188 
2189  /* Try to acquire rundown */
2190  if (ExAcquireRundownProtection(&Process->RundownProtect))
2191  {
2192  /* Lock it */
2194  ExAcquirePushLockShared(&Process->ProcessLock);
2195 
2196  /* Combine masks */
2197  CombinedAffinity = Affinity & Process->Pcb.Affinity;
2198  if (CombinedAffinity != Affinity)
2199  {
2200  /* Fail */
2202  }
2203  else
2204  {
2205  /* Set the affinity */
2206  KeSetAffinityThread(&Thread->Tcb, CombinedAffinity);
2207  }
2208 
2209  /* Release the lock and rundown */
2210  ExReleasePushLockShared(&Process->ProcessLock);
2212  ExReleaseRundownProtection(&Process->RundownProtect);
2213  }
2214  else
2215  {
2216  /* Too late */
2218  }
2219 
2220  /* Return status */
2221  break;
2222 
2224 
2225  /* Check buffer length */
2226  if (ThreadInformationLength != sizeof(HANDLE))
2227  {
2229  break;
2230  }
2231 
2232  /* Use SEH for capture */
2233  _SEH2_TRY
2234  {
2235  /* Save the token handle */
2236  TokenHandle = *(PHANDLE)ThreadInformation;
2237  }
2239  {
2240  /* Get the exception code */
2242  _SEH2_YIELD(break);
2243  }
2244  _SEH2_END;
2245 
2246  /* Assign the actual token */
2248  break;
2249 
2251 
2252  /* Check buffer length */
2253  if (ThreadInformationLength != sizeof(ULONG_PTR))
2254  {
2256  break;
2257  }
2258 
2259  /* Use SEH for capture */
2260  _SEH2_TRY
2261  {
2262  /* Get the priority */
2263  Address = *(PVOID*)ThreadInformation;
2264  }
2266  {
2267  /* Get the exception code */
2269  _SEH2_YIELD(break);
2270  }
2271  _SEH2_END;
2272 
2273  /* Set the address */
2275  break;
2276 
2277  case ThreadIdealProcessor:
2278 
2279  /* Check buffer length */
2280  if (ThreadInformationLength != sizeof(ULONG_PTR))
2281  {
2283  break;
2284  }
2285 
2286  /* Use SEH for capture */
2287  _SEH2_TRY
2288  {
2289  /* Get the priority */
2290  IdealProcessor = *(PULONG_PTR)ThreadInformation;
2291  }
2293  {
2294  /* Get the exception code */
2296  _SEH2_YIELD(break);
2297  }
2298  _SEH2_END;
2299 
2300  /* Validate it */
2301  if (IdealProcessor > MAXIMUM_PROCESSORS)
2302  {
2303  /* Fail */
2305  break;
2306  }
2307 
2308  /* Set the ideal */
2310  (CCHAR)IdealProcessor);
2311 
2312  /* Get the TEB and protect the thread */
2313  Teb = Thread->Tcb.Teb;
2315  {
2316  /* Save the ideal processor */
2317  Teb->IdealProcessor = Thread->Tcb.IdealProcessor;
2318 
2319  /* Release rundown protection */
2321  }
2322 
2323  break;
2324 
2325  case ThreadPriorityBoost:
2326 
2327  /* Check buffer length */
2328  if (ThreadInformationLength != sizeof(ULONG_PTR))
2329  {
2331  break;
2332  }
2333 
2334  /* Use SEH for capture */
2335  _SEH2_TRY
2336  {
2337  /* Get the priority */
2338  DisableBoost = *(PULONG_PTR)ThreadInformation;
2339  }
2341  {
2342  /* Get the exception code */
2344  _SEH2_YIELD(break);
2345  }
2346  _SEH2_END;
2347 
2348  /* Call the kernel */
2349  KeSetDisableBoostThread(&Thread->Tcb, (BOOLEAN)DisableBoost);
2350  break;
2351 
2352  case ThreadZeroTlsCell:
2353 
2354  /* Check buffer length */
2355  if (ThreadInformationLength != sizeof(ULONG_PTR))
2356  {
2358  break;
2359  }
2360 
2361  /* Use SEH for capture */
2362  _SEH2_TRY
2363  {
2364  /* Get the priority */
2365  TlsIndex = *(PULONG_PTR)ThreadInformation;
2366  }
2368  {
2369  /* Get the exception code */
2371  _SEH2_YIELD(break);
2372  }
2373  _SEH2_END;
2374 
2375  /* This is only valid for the current thread */
2376  if (Thread != PsGetCurrentThread())
2377  {
2378  /* Fail */
2380  break;
2381  }
2382 
2383  /* Get the process */
2384  Process = Thread->ThreadsProcess;
2385 
2386  /* Loop the threads */
2387  ProcThread = PsGetNextProcessThread(Process, NULL);
2388  while (ProcThread)
2389  {
2390  /* Acquire rundown */
2391  if (ExAcquireRundownProtection(&ProcThread->RundownProtect))
2392  {
2393  /* Get the TEB */
2394  Teb = ProcThread->Tcb.Teb;
2395  if (Teb)
2396  {
2397  /* Check if we're in the expansion range */
2398  if (TlsIndex > TLS_MINIMUM_AVAILABLE - 1)
2399  {
2401  TLS_EXPANSION_SLOTS) - 1)
2402  {
2403  /* Check if we have expansion slots */
2404  ExpansionSlots = Teb->TlsExpansionSlots;
2405  if (ExpansionSlots)
2406  {
2407  /* Clear the index */
2408  ExpansionSlots[TlsIndex - TLS_MINIMUM_AVAILABLE] = 0;
2409  }
2410  }
2411  }
2412  else
2413  {
2414  /* Clear the index */
2415  Teb->TlsSlots[TlsIndex] = NULL;
2416  }
2417  }
2418 
2419  /* Release rundown */
2421  }
2422 
2423  /* Go to the next thread */
2424  ProcThread = PsGetNextProcessThread(Process, ProcThread);
2425  }
2426 
2427  /* All done */
2428  break;
2429 
2431 
2432  /* Check buffer length */
2433  if (ThreadInformationLength != sizeof(ULONG))
2434  {
2436  break;
2437  }
2438 
2439  /* Enter SEH for direct buffer read */
2440  _SEH2_TRY
2441  {
2442  Break = *(PULONG)ThreadInformation;
2443  }
2445  {
2446  /* Get exception code */
2447  Break = 0;
2449  _SEH2_YIELD(break);
2450  }
2451  _SEH2_END;
2452 
2453  /* Setting 'break on termination' requires the SeDebugPrivilege */
2455  {
2456  /* We don't hold the privilege, bail out */
2458  break;
2459  }
2460 
2461  /* Set or clear the flag */
2462  if (Break)
2463  {
2465  }
2466  else
2467  {
2469  }
2470  break;
2471 
2473 
2474  /* Check buffer length */
2475  if (ThreadInformationLength != 0)
2476  {
2478  break;
2479  }
2480 
2481  /* Set the flag */
2483  break;
2484 
2485  default:
2486  /* We don't implement it yet */
2487  DPRINT1("Not implemented: %d\n", ThreadInformationClass);
2489  }
2490 
2491  /* Dereference and return status */
2493  return Status;
2494 }
2495 
2496 /*
2497  * @implemented
2498  */
2499 NTSTATUS
2500 NTAPI
2503  OUT PVOID ThreadInformation,
2506 {
2507  PETHREAD Thread;
2509  NTSTATUS Status;
2510  ULONG Access;
2511  ULONG Length = 0;
2512  PTHREAD_BASIC_INFORMATION ThreadBasicInfo =
2513  (PTHREAD_BASIC_INFORMATION)ThreadInformation;
2514  PKERNEL_USER_TIMES ThreadTime = (PKERNEL_USER_TIMES)ThreadInformation;
2515  KIRQL OldIrql;
2516  ULONG ThreadTerminated;
2517  PAGED_CODE();
2518 
2519  /* Check if we were called from user mode */
2520  if (PreviousMode != KernelMode)
2521  {
2522  /* Enter SEH */
2523  _SEH2_TRY
2524  {
2525  /* Probe the buffer */
2526  ProbeForWrite(ThreadInformation,
2528  sizeof(ULONG));
2529 
2530  /* Probe the return length if required */
2532  }
2534  {
2535  /* Return the exception code */
2537  }
2538  _SEH2_END;
2539  }
2540 
2541  /* Check what class this is */
2542  Access = THREAD_QUERY_INFORMATION;
2543 
2544  /* Reference the process */
2545  Status = ObReferenceObjectByHandle(ThreadHandle,
2546  Access,
2547  PsThreadType,
2548  PreviousMode,
2549  (PVOID*)&Thread,
2550  NULL);
2551  if (!NT_SUCCESS(Status)) return Status;
2552 
2553  /* Check what kind of information class this is */
2554  switch (ThreadInformationClass)
2555  {
2556  /* Basic thread information */
2558 
2559  /* Set return length */
2560  Length = sizeof(THREAD_BASIC_INFORMATION);
2561 
2563  {
2565  break;
2566  }
2567  /* Protect writes with SEH */
2568  _SEH2_TRY
2569  {
2570  /* Write all the information from the ETHREAD/KTHREAD */
2571  ThreadBasicInfo->ExitStatus = Thread->ExitStatus;
2572  ThreadBasicInfo->TebBaseAddress = (PVOID)Thread->Tcb.Teb;
2573  ThreadBasicInfo->ClientId = Thread->Cid;
2574  ThreadBasicInfo->AffinityMask = Thread->Tcb.Affinity;
2575  ThreadBasicInfo->Priority = Thread->Tcb.Priority;
2576  ThreadBasicInfo->BasePriority = KeQueryBasePriorityThread(&Thread->Tcb);
2577  }
2579  {
2580  /* Get exception code */
2582  }
2583  _SEH2_END;
2584  break;
2585 
2586  /* Thread time information */
2587  case ThreadTimes:
2588 
2589  /* Set the return length */
2590  Length = sizeof(KERNEL_USER_TIMES);
2591 
2593  {
2595  break;
2596  }
2597  /* Protect writes with SEH */
2598  _SEH2_TRY
2599  {
2600  /* Copy time information from ETHREAD/KTHREAD */
2603  ThreadTime->CreateTime = Thread->CreateTime;
2604 
2605  /* Exit time is in a union and only valid on actual exit! */
2606  if (KeReadStateThread(&Thread->Tcb))
2607  {
2608  ThreadTime->ExitTime = Thread->ExitTime;
2609  }
2610  else
2611  {
2612  ThreadTime->ExitTime.QuadPart = 0;
2613  }
2614  }
2616  {
2617  /* Get exception code */
2619  }
2620  _SEH2_END;
2621  break;
2622 
2624 
2625  /* Set the return length*/
2626  Length = sizeof(PVOID);
2627 
2629  {
2631  break;
2632  }
2633  /* Protect write with SEH */
2634  _SEH2_TRY
2635  {
2636  /* Return the Win32 Start Address */
2637  *(PVOID*)ThreadInformation = Thread->Win32StartAddress;
2638  }
2640  {
2641  /* Get exception code */
2643  }
2644  _SEH2_END;
2645  break;
2646 
2648 
2649  /* Set the return length*/
2650  Length = sizeof(LARGE_INTEGER);
2651 
2653  {
2655  break;
2656  }
2657  /* Protect write with SEH */
2658  _SEH2_TRY
2659  {
2660  /* FIXME */
2661  (*(PLARGE_INTEGER)ThreadInformation).QuadPart = 0;
2662  }
2664  {
2665  /* Get exception code */
2667  }
2668  _SEH2_END;
2669  break;
2670 
2671  case ThreadAmILastThread:
2672 
2673  /* Set the return length*/
2674  Length = sizeof(ULONG);
2675 
2677  {
2679  break;
2680  }
2681  /* Protect write with SEH */
2682  _SEH2_TRY
2683  {
2684  /* Return whether or not we are the last thread */
2685  *(PULONG)ThreadInformation = ((Thread->ThreadsProcess->
2686  ThreadListHead.Flink->Flink ==
2687  &Thread->ThreadsProcess->
2688  ThreadListHead) ?
2689  TRUE : FALSE);
2690  }
2692  {
2693  /* Get exception code */
2695  }
2696  _SEH2_END;
2697  break;
2698 
2699  case ThreadIsIoPending:
2700 
2701  /* Set the return length*/
2702  Length = sizeof(ULONG);
2703 
2705  {
2707  break;
2708  }
2709  /* Raise the IRQL to protect the IRP list */
2711 
2712  /* Protect write with SEH */
2713  _SEH2_TRY
2714  {
2715  /* Check if the IRP list is empty or not */
2716  *(PULONG)ThreadInformation = !IsListEmpty(&Thread->IrpList);
2717  }
2719  {
2720  /* Get exception code */
2722  }
2723  _SEH2_END;
2724 
2725  /* Lower IRQL back */
2727  break;
2728 
2729  /* LDT and GDT information */
2731 
2732 #if defined(_X86_)
2733  /* Call the worker routine */
2735  ThreadInformation,
2737  ReturnLength);
2738 #else
2739  /* Only implemented on x86 */
2741 #endif
2742  break;
2743 
2744  case ThreadPriorityBoost:
2745 
2746  /* Set the return length*/
2747  Length = sizeof(ULONG);
2748 
2750  {
2752  break;
2753  }
2754 
2755  _SEH2_TRY
2756  {
2757  *(PULONG)ThreadInformation = Thread->Tcb.DisableBoost ? 1 : 0;
2758  }
2760  {
2762  }
2763  _SEH2_END;
2764  break;
2765 
2766  case ThreadIsTerminated:
2767 
2768  /* Set the return length*/
2769  Length = sizeof(ThreadTerminated);
2770 
2772  {
2774  break;
2775  }
2776 
2777  ThreadTerminated = PsIsThreadTerminating(Thread);
2778 
2779  _SEH2_TRY
2780  {
2781  *(PULONG)ThreadInformation = ThreadTerminated ? 1 : 0;
2782  }
2784  {
2786  }
2787  _SEH2_END;
2788 
2789  break;
2790 
2791  /* Anything else */
2792  default:
2793 
2794  /* Not yet implemented */
2795  DPRINT1("Not implemented: %lx\n", ThreadInformationClass);
2797  }
2798 
2799  /* Protect write with SEH */
2800  _SEH2_TRY
2801  {
2802  /* Check if caller wanted return length */
2804  }
2806  {
2807  /* Get exception code */
2809  }
2810  _SEH2_END;
2811 
2812  /* Dereference the thread, and return */
2814  return Status;
2815 }
2816 
2817 /* 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
#define RTL_FIELD_SIZE(type, field)
Definition: kdb_expr.c:84
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:39
#define PspClearProcessFlag(Process, Flag)
Definition: ps_x.h:35
struct _VM_COUNTERS_ * PVM_COUNTERS
#define STATUS_PRIVILEGE_NOT_HELD
Definition: DriverTester.h:9
#define PSF_BREAK_ON_TERMINATION_BIT
Definition: pstypes.h:277
LARGE_INTEGER ExitTime
Definition: pstypes.h:1049
#define KeRaiseIrql(irql, oldIrql)
Definition: env_spec_w32.h:597
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
FORCEINLINE _Post_maybenull_ _Must_inspect_result_ _In_ SIZE_T _In_ ULONG _In_ EX_POOL_PRIORITY Priority
Definition: exfuncs.h:700
#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:678
SIZE_T PeakPagefileUsage
Definition: winternl.h:1615
#define _WIN32_WINNT_WS03
Definition: sdkddkver.h:23
#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:239
#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 TRUE
Definition: types.h:120
#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:302
uint16_t * PWSTR
Definition: typedefs.h:56
SIZE_T QuotaPagedPoolUsage
Definition: winternl.h:1611
LARGE_INTEGER CreateTime
Definition: pstypes.h:1046
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
struct _KERNEL_USER_TIMES KERNEL_USER_TIMES
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:1101
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:1045
FORCEINLINE struct _KPRCB * KeGetCurrentPrcb(VOID)
Definition: ketypes.h:1063
#define ExAcquireRundownProtection
Definition: ex.h:130
SCHAR Priority
Definition: ketypes.h:1672
VOID NTAPI Ke386SetIOPL(VOID)
Definition: v86vdm.c:581
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
struct _LARGE_INTEGER::@2260 u
#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:551
KPRIORITY BasePriority
Definition: compat.h:680
_SEH2_TRY
Definition: create.c:4226
SIZE_T QuotaPeakNonPagedPoolUsage
Definition: winternl.h:1612
uint32_t ULONG_PTR
Definition: typedefs.h:65
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
enum _PROCESSINFOCLASS PROCESSINFOCLASS
Definition: loader.c:63
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
#define FALSE
Definition: types.h:117
long LONG
Definition: pedump.c:60
EPROCESS_QUOTA_BLOCK PspDefaultQuotaBlock
Definition: quota.c:17
INT64 PagedPoolLimit
Definition: lsa.idl:287
ULONG NTAPI ObGetProcessHandleCount(IN PEPROCESS Process)
Definition: obhandle.c:59
PVOID Win32StartAddress
Definition: pstypes.h:1094
#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 _KERNEL_USER_TIMES * PKERNEL_USER_TIMES
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:232
NTSTATUS NTAPI NtSetInformationThread(IN HANDLE ThreadHandle, IN THREADINFOCLASS ThreadInformationClass, IN PVOID ThreadInformation, IN ULONG ThreadInformationLength)
Definition: query.c:2018
void * PVOID
Definition: retypes.h:9
#define CT_BREAK_ON_TERMINATION_BIT
Definition: pstypes.h:236
#define HIGH_PRIORITY
_Inout_ PFILE_OBJECT FileObject
Definition: cdprocs.h:588
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:771
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:68
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
_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:51
LARGE_INTEGER CreateTime
Definition: winternl.h:1060
#define PSF_NO_DEBUG_INHERIT_BIT
Definition: pstypes.h:266
CLIENT_ID Cid
Definition: pstypes.h:1070
#define THREAD_BASE_PRIORITY_IDLE
Definition: pstypes.h:177
_In_opt_ PVOID _Out_ PLARGE_INTEGER Cookie
Definition: cmfuncs.h:13
#define STATUS_PROCESS_IS_TERMINATING
Definition: ntstatus.h:502
_In_ ULONG _In_ ULONG _In_ ULONG _Out_ PKIRQL _Out_ PKAFFINITY Affinity
Definition: halfuncs.h:170
PVOID HANDLE
Definition: typedefs.h:73
#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
BOOL Query(LPCTSTR *ServiceArgs, DWORD ArgCount, BOOL bExtended)
Definition: query.c:292
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:1978
NTSTATUS NTAPI NtQueryInformationThread(IN HANDLE ThreadHandle, IN THREADINFOCLASS ThreadInformationClass, OUT PVOID ThreadInformation, IN ULONG ThreadInformationLength, OUT PULONG ReturnLength OPTIONAL)
Definition: query.c:2501
struct _SECTION_IMAGE_INFORMATION SECTION_IMAGE_INFORMATION
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
struct _PROCESS_BASIC_INFORMATION * PPROCESS_BASIC_INFORMATION
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
Status
Definition: gdiplustypes.h:24
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:240
#define PROCESS_LUID_DOSDEVICES_ONLY
Definition: pstypes.h:228
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:790
#define PspSetCrossThreadFlag(Thread, Flag)
Definition: ps_x.h:25
#define PSF_VDM_ALLOWED_BIT
Definition: pstypes.h:288
PVOID *typedef PHANDLE
Definition: ntsecpkg.h:454
#define KeEnterCriticalRegion()
Definition: ke_x.h:83
ULONG IdealProcessor
Definition: ketypes.h:1834
ULONG LowPart
Definition: typedefs.h:106
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:119
#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
#define MEMORY_PRIORITY_FOREGROUND
Definition: pstypes.h:126
const LUID SeTcbPrivilege
Definition: priv.c:28
#define MAXULONG
Definition: typedefs.h:251
FORCEINLINE VOID ExAcquirePushLockShared(PEX_PUSH_LOCK PushLock)
Definition: ex.h:1091
ULONG_PTR SIZE_T
Definition: typedefs.h:80
SIZE_T WorkingSetSize
Definition: winternl.h:1609
Definition: compat.h:583
_SEH2_END
Definition: create.c:4400
NTSTATUS ExitStatus
Definition: pstypes.h:1055
#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:1107
enum _THREADINFOCLASS THREADINFOCLASS
Definition: thread.c:101
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:85
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:40
#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
#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:115
#define ULONG_PTR
Definition: config.h:101
uint32_t * PULONG_PTR
Definition: typedefs.h:65
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:627
PVOID * TlsExpansionSlots
Definition: compat.h:642
#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
struct _PROCESS_BASIC_INFORMATION PROCESS_BASIC_INFORMATION
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:3014
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:1086
#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:114
#define TLS_MINIMUM_AVAILABLE
Definition: ntddk_ex.h:236
#define PAGED_CODE()
struct _IO_COUNTERS * PIO_COUNTERS
#define STATUS_PORT_ALREADY_SET
Definition: ntstatus.h:308
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68