ReactOS  0.4.13-dev-100-gc8611ae
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;
83  ULONG Cookie, ExecuteOptions = 0;
84  ULONG_PTR Wow64 = 0;
85  PROCESS_VALUES ProcessValues;
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 != RTL_FIELD_SIZE(PROCESS_DEVICEMAP_INFORMATION, Query))
568  {
569  if (ProcessInformationLength == sizeof(PROCESS_DEVICEMAP_INFORMATION_EX))
570  {
571  DPRINT1("PROCESS_DEVICEMAP_INFORMATION_EX not supported!\n");
573  }
574  else
575  {
577  }
578  break;
579  }
580 
581  /* Set the return length */
583 
584  /* Reference the process */
588  PreviousMode,
589  (PVOID*)&Process,
590  NULL);
591  if (!NT_SUCCESS(Status)) break;
592 
593  /* Query the device map information */
595 
596  /* Enter SEH for writing back data */
597  _SEH2_TRY
598  {
599  *(PPROCESS_DEVICEMAP_INFORMATION)ProcessInformation = DeviceMap;
600  }
602  {
603  /* Get the exception code */
605  }
606  _SEH2_END;
607 
608  /* Dereference the process */
610  break;
611 
612  /* Priority class */
614 
615  if (ProcessInformationLength != sizeof(PROCESS_PRIORITY_CLASS))
616  {
618  break;
619  }
620 
621  /* Set the return length*/
622  Length = sizeof(PROCESS_PRIORITY_CLASS);
623 
624  /* Reference the process */
628  PreviousMode,
629  (PVOID*)&Process,
630  NULL);
631  if (!NT_SUCCESS(Status)) break;
632 
633  /* Enter SEH for writing back data */
634  _SEH2_TRY
635  {
636  /* Return current priority class */
637  PsPriorityClass->PriorityClass = Process->PriorityClass;
638  PsPriorityClass->Foreground = FALSE;
639  }
641  {
642  /* Get the exception code */
644  }
645  _SEH2_END;
646 
647  /* Dereference the process */
649  break;
650 
652 
653  /* Reference the process */
657  PreviousMode,
658  (PVOID*)&Process,
659  NULL);
660  if (!NT_SUCCESS(Status)) break;
661 
662  /* Get the image path */
664  if (NT_SUCCESS(Status))
665  {
666  /* Set return length */
667  Length = ImageName->MaximumLength +
668  sizeof(OBJECT_NAME_INFORMATION);
669 
670  /* Make sure it's large enough */
671  if (Length <= ProcessInformationLength)
672  {
673  /* Enter SEH to protect write */
674  _SEH2_TRY
675  {
676  /* Copy it */
677  RtlCopyMemory(ProcessInformation,
678  ImageName,
679  Length);
680 
681  /* Update pointer */
682  ((PUNICODE_STRING)ProcessInformation)->Buffer =
683  (PWSTR)((PUNICODE_STRING)ProcessInformation + 1);
684  }
686  {
687  /* Get the exception code */
689  }
690  _SEH2_END;
691  }
692  else
693  {
694  /* Buffer too small */
696  }
697 
698  /* Free the image path */
700  }
701  /* Dereference the process */
703  break;
704 
705  case ProcessDebugFlags:
706 
707  if (ProcessInformationLength != sizeof(ULONG))
708  {
710  break;
711  }
712 
713  /* Set the return length*/
714  Length = sizeof(ULONG);
715 
716  /* Reference the process */
720  PreviousMode,
721  (PVOID*)&Process,
722  NULL);
723  if (!NT_SUCCESS(Status)) break;
724 
725  /* Enter SEH for writing back data */
726  _SEH2_TRY
727  {
728  /* Return the debug flag state */
729  *(PULONG)ProcessInformation = Process->NoDebugInherit ? 0 : 1;
730  }
732  {
733  /* Get the exception code */
735  }
736  _SEH2_END;
737 
738  /* Dereference the process */
740  break;
741 
743 
744  if (ProcessInformationLength != sizeof(ULONG))
745  {
747  break;
748  }
749 
750  /* Set the return length */
751  Length = sizeof(ULONG);
752 
753  /* Reference the process */
757  PreviousMode,
758  (PVOID*)&Process,
759  NULL);
760  if (!NT_SUCCESS(Status)) break;
761 
762  /* Enter SEH for writing back data */
763  _SEH2_TRY
764  {
765  /* Return the BreakOnTermination state */
766  *(PULONG)ProcessInformation = Process->BreakOnTermination;
767  }
769  {
770  /* Get the exception code */
772  }
773  _SEH2_END;
774 
775  /* Dereference the process */
777  break;
778 
779  /* Per-process security cookie */
780  case ProcessCookie:
781 
782  /* Get the current process and cookie */
784  Cookie = Process->Cookie;
785  if (!Cookie)
786  {
787  LARGE_INTEGER SystemTime;
788  ULONG NewCookie;
789  PKPRCB Prcb;
790 
791  /* Generate a new cookie */
792  KeQuerySystemTime(&SystemTime);
793  Prcb = KeGetCurrentPrcb();
794  NewCookie = Prcb->KeSystemCalls ^ Prcb->InterruptTime ^
795  SystemTime.u.LowPart ^ SystemTime.u.HighPart;
796 
797  /* Set the new cookie or return the current one */
799  NewCookie,
800  Cookie);
801  if (!Cookie) Cookie = NewCookie;
802 
803  /* Set return length */
804  Length = sizeof(ULONG);
805  }
806 
807  /* Indicate success */
809 
810  /* Enter SEH to protect write */
811  _SEH2_TRY
812  {
813  /* Write back the cookie */
814  *(PULONG)ProcessInformation = Cookie;
815  }
817  {
818  /* Get the exception code */
820  }
821  _SEH2_END;
822  break;
823 
825 
826  if (ProcessInformationLength != sizeof(SECTION_IMAGE_INFORMATION))
827  {
828  /* Break out */
830  break;
831  }
832 
833  /* Set the length required and validate it */
835 
836  /* Enter SEH to protect write */
837  _SEH2_TRY
838  {
840  }
842  {
843  /* Get the exception code */
845  }
846  _SEH2_END;
847 
848  /* Indicate success */
850  break;
851 
853 
854  if (ProcessInformationLength != sizeof(HANDLE))
855  {
857  break;
858  }
859 
860  /* Set the return length */
861  Length = sizeof(HANDLE);
862 
863  /* Reference the process */
867  PreviousMode,
868  (PVOID*)&Process,
869  NULL);
870  if (!NT_SUCCESS(Status)) break;
871 
872  /* Get the debug port */
874 
875  /* Let go of the process */
877 
878  /* Protect write in SEH */
879  _SEH2_TRY
880  {
881  /* Return debug port's handle */
882  *(PHANDLE)ProcessInformation = DebugPort;
883  }
885  {
886  /* Get the exception code */
888  }
889  _SEH2_END;
890  break;
891 
893  DPRINT1("Handle tracing Not implemented: %lx\n", ProcessInformationClass);
895  break;
896 
898 
899  if (ProcessInformationLength != sizeof(ULONG))
900  {
902  break;
903  }
904 
905  /* Set the return length */
906  Length = sizeof(ULONG);
907 
908  /* Indicate success */
910 
911  /* Protect write in SEH */
912  _SEH2_TRY
913  {
914  /* Return FALSE -- we don't support this */
915  *(PULONG)ProcessInformation = FALSE;
916  }
918  {
919  /* Get the exception code */
921  }
922  _SEH2_END;
923  break;
924 
926 
927  if (ProcessInformationLength != sizeof(ULONG))
928  {
930  break;
931  }
932 
933  /* Set the return length */
934  Length = sizeof(ULONG);
935 
936  /* Reference the process */
940  PreviousMode,
941  (PVOID*)&Process,
942  NULL);
943  if (!NT_SUCCESS(Status)) break;
944 
945  /* Protect write in SEH */
946  _SEH2_TRY
947  {
948  /* Return if the flag is set */
949  *(PULONG)ProcessInformation = (ULONG)Process->VdmAllowed;
950  }
952  {
953  /* Get the exception code */
955  }
956  _SEH2_END;
957 
958  /* Dereference the process */
960  break;
961 
963 
964  if (ProcessInformationLength != sizeof(ULONG_PTR))
965  {
967  break;
968  }
969 
970  /* Set return length */
971  Length = sizeof(ULONG_PTR);
972 
973  /* Reference the process */
977  PreviousMode,
978  (PVOID*)&Process,
979  NULL);
980  if (!NT_SUCCESS(Status)) break;
981 
982  /* Make sure the process isn't dying */
983  if (ExAcquireRundownProtection(&Process->RundownProtect))
984  {
985  /* Get the WOW64 process structure */
986 #ifdef _WIN64
987  Wow64 = (ULONG_PTR)Process->Wow64Process;
988 #else
989  Wow64 = 0;
990 #endif
991  /* Release the lock */
992  ExReleaseRundownProtection(&Process->RundownProtect);
993  }
994 
995  /* Protect write with SEH */
996  _SEH2_TRY
997  {
998  /* Return whether or not we have a debug port */
999  *(PULONG_PTR)ProcessInformation = Wow64;
1000  }
1002  {
1003  /* Get exception code */
1005  }
1006  _SEH2_END;
1007 
1008  /* Dereference the process */
1010  break;
1011 
1012  case ProcessExecuteFlags:
1013 
1014  if (ProcessInformationLength != sizeof(ULONG))
1015  {
1017  break;
1018  }
1019 
1020  /* Set return length */
1021  Length = sizeof(ULONG);
1022 
1024  {
1025  return STATUS_INVALID_PARAMETER;
1026  }
1027 
1028  /* Get the options */
1029  Status = MmGetExecuteOptions(&ExecuteOptions);
1030  if (NT_SUCCESS(Status))
1031  {
1032  /* Protect write with SEH */
1033  _SEH2_TRY
1034  {
1035  /* Return them */
1036  *(PULONG)ProcessInformation = ExecuteOptions;
1037  }
1039  {
1040  /* Get exception code */
1042  }
1043  _SEH2_END;
1044  }
1045  break;
1046 
1047  case ProcessLdtInformation:
1048  DPRINT1("VDM/16-bit not implemented: %lx\n", ProcessInformationClass);
1050  break;
1051 
1053  DPRINT1("WS Watch Not implemented: %lx\n", ProcessInformationClass);
1055  break;
1056 
1058  DPRINT1("Pool limits Not implemented: %lx\n", ProcessInformationClass);
1060  break;
1061 
1062  /* Not supported by Server 2003 */
1063  default:
1064  DPRINT1("Unsupported info class: %lx\n", ProcessInformationClass);
1066  }
1067 
1068  /* Protect write with SEH */
1069  _SEH2_TRY
1070  {
1071  /* Check if caller wanted return length */
1072  if ((ReturnLength) && (Length)) *ReturnLength = Length;
1073  }
1075  {
1076  /* Get exception code */
1078  }
1079  _SEH2_END;
1080 
1081  return Status;
1082 }
1083 
1084 /*
1085  * @implemented
1086  */
1087 NTSTATUS
1088 NTAPI
1090  IN PROCESSINFOCLASS ProcessInformationClass,
1091  IN PVOID ProcessInformation,
1092  IN ULONG ProcessInformationLength)
1093 {
1096  ACCESS_MASK Access;
1097  NTSTATUS Status;
1098  HANDLE PortHandle = NULL;
1101  PROCESS_PRIORITY_CLASS PriorityClass = {0};
1102  PROCESS_FOREGROUND_BACKGROUND Foreground = {0};
1103  PVOID ExceptionPort;
1104  ULONG Break;
1105  KAFFINITY ValidAffinity, Affinity = 0;
1106  KPRIORITY BasePriority = 0;
1107  UCHAR MemoryPriority = 0;
1108  BOOLEAN DisableBoost = 0;
1109  ULONG DefaultHardErrorMode = 0;
1110  ULONG DebugFlags = 0, EnableFixup = 0, Boost = 0;
1111  ULONG NoExecute = 0, VdmPower = 0;
1113  PLIST_ENTRY Next;
1114  PETHREAD Thread;
1115  PAGED_CODE();
1116 
1117  /* Verify Information Class validity */
1118 #if 0
1119  Status = DefaultSetInfoBufferCheck(ProcessInformationClass,
1120  PsProcessInfoClass,
1121  RTL_NUMBER_OF(PsProcessInfoClass),
1122  ProcessInformation,
1123  ProcessInformationLength,
1124  PreviousMode);
1125  if (!NT_SUCCESS(Status)) return Status;
1126 #endif
1127 
1128  /* Check what class this is */
1129  Access = PROCESS_SET_INFORMATION;
1130  if (ProcessInformationClass == ProcessSessionInformation)
1131  {
1132  /* Setting the Session ID needs a special mask */
1133  Access |= PROCESS_SET_SESSIONID;
1134  }
1135  else if (ProcessInformationClass == ProcessExceptionPort)
1136  {
1137  /* Setting the exception port needs a special mask */
1138  Access |= PROCESS_SUSPEND_RESUME;
1139  }
1140 
1141  /* Reference the process */
1143  Access,
1144  PsProcessType,
1145  PreviousMode,
1146  (PVOID*)&Process,
1147  NULL);
1148  if (!NT_SUCCESS(Status)) return Status;
1149 
1150  /* Check what kind of information class this is */
1151  switch (ProcessInformationClass)
1152  {
1154 
1155  /* Check buffer length */
1156  if (ProcessInformationLength != sizeof(HANDLE))
1157  {
1159  break;
1160  }
1161 
1162  /* Use SEH for capture */
1163  _SEH2_TRY
1164  {
1165  /* Capture the boolean */
1166  VdmPower = *(PULONG)ProcessInformation;
1167  }
1169  {
1170  /* Get the exception code */
1172  _SEH2_YIELD(break);
1173  }
1174  _SEH2_END;
1175 
1176  /* Getting VDM powers requires the SeTcbPrivilege */
1178  {
1179  /* We don't hold the privilege, bail out */
1181  DPRINT1("Need TCB privilege\n");
1182  break;
1183  }
1184 
1185  /* Set or clear the flag */
1186  if (VdmPower)
1187  {
1189  }
1190  else
1191  {
1193  }
1194  break;
1195 
1196  /* Error/Exception Port */
1197  case ProcessExceptionPort:
1198 
1199  /* Check buffer length */
1200  if (ProcessInformationLength != sizeof(HANDLE))
1201  {
1203  break;
1204  }
1205 
1206  /* Use SEH for capture */
1207  _SEH2_TRY
1208  {
1209  /* Capture the handle */
1210  PortHandle = *(PHANDLE)ProcessInformation;
1211  }
1213  {
1214  /* Get the exception code */
1216  _SEH2_YIELD(break);
1217  }
1218  _SEH2_END;
1219 
1220  /* Setting the error port requires the SeTcbPrivilege */
1222  {
1223  /* We don't hold the privilege, bail out */
1225  break;
1226  }
1227 
1228  /* Get the LPC Port */
1229  Status = ObReferenceObjectByHandle(PortHandle,
1230  0,
1232  PreviousMode,
1233  (PVOID)&ExceptionPort,
1234  NULL);
1235  if (!NT_SUCCESS(Status)) break;
1236 
1237  /* Change the pointer */
1238  if (InterlockedCompareExchangePointer(&Process->ExceptionPort,
1239  ExceptionPort,
1240  NULL))
1241  {
1242  /* We already had one, fail */
1243  ObDereferenceObject(ExceptionPort);
1245  }
1246  break;
1247 
1248  /* Security Token */
1249  case ProcessAccessToken:
1250 
1251  /* Check buffer length */
1252  if (ProcessInformationLength != sizeof(PROCESS_ACCESS_TOKEN))
1253  {
1255  break;
1256  }
1257 
1258  /* Use SEH for capture */
1259  _SEH2_TRY
1260  {
1261  /* Save the token handle */
1262  TokenHandle = ((PPROCESS_ACCESS_TOKEN)ProcessInformation)->
1263  Token;
1264  }
1266  {
1267  /* Get the exception code */
1269  _SEH2_YIELD(break);
1270  }
1271  _SEH2_END;
1272 
1273  /* Assign the actual token */
1275  break;
1276 
1277  /* Hard error processing */
1279 
1280  /* Check buffer length */
1281  if (ProcessInformationLength != sizeof(ULONG))
1282  {
1284  break;
1285  }
1286 
1287  /* Enter SEH for direct buffer read */
1288  _SEH2_TRY
1289  {
1290  DefaultHardErrorMode = *(PULONG)ProcessInformation;
1291  }
1293  {
1294  /* Get exception code */
1296  _SEH2_YIELD(break);
1297  }
1298  _SEH2_END;
1299 
1300  /* Set the mode */
1301  Process->DefaultHardErrorProcessing = DefaultHardErrorMode;
1302 
1303  /* Call Ke for the update */
1304  if (DefaultHardErrorMode & SEM_NOALIGNMENTFAULTEXCEPT)
1305  {
1307  }
1308  else
1309  {
1311  }
1313  break;
1314 
1315  /* Session ID */
1317 
1318  /* Check buffer length */
1319  if (ProcessInformationLength != sizeof(PROCESS_SESSION_INFORMATION))
1320  {
1322  break;
1323  }
1324 
1325  /* Enter SEH for capture */
1326  _SEH2_TRY
1327  {
1328  /* Capture the caller's buffer */
1329  SessionInfo = *(PPROCESS_SESSION_INFORMATION)ProcessInformation;
1330  }
1332  {
1333  /* Get the exception code */
1335  _SEH2_YIELD(break);
1336  }
1337  _SEH2_END;
1338 
1339  /* Setting the session id requires the SeTcbPrivilege */
1341  {
1342  /* We don't hold the privilege, bail out */
1344  break;
1345  }
1346 
1347 #if 0 // OLD AND DEPRECATED CODE!!!!
1348 
1349  /* FIXME - update the session id for the process token */
1350  //Status = PsLockProcess(Process, FALSE);
1351  if (!NT_SUCCESS(Status)) break;
1352 
1353  /* Write the session ID in the EPROCESS */
1354  Process->Session = UlongToPtr(SessionInfo.SessionId); // HACK!!!
1355 
1356  /* Check if the process also has a PEB */
1357  if (Process->Peb)
1358  {
1359  /*
1360  * Attach to the process to make sure we're in the right
1361  * context to access the PEB structure
1362  */
1363  KeAttachProcess(&Process->Pcb);
1364 
1365  /* Enter SEH for write to user-mode PEB */
1366  _SEH2_TRY
1367  {
1368  /* Write the session ID */
1369  Process->Peb->SessionId = SessionInfo.SessionId;
1370  }
1372  {
1373  /* Get exception code */
1375  }
1376  _SEH2_END;
1377 
1378  /* Detach from the process */
1379  KeDetachProcess();
1380  }
1381 
1382  /* Unlock the process */
1383  //PsUnlockProcess(Process);
1384 
1385 #endif
1386 
1387  /*
1388  * Since we cannot change the session ID of the given
1389  * process anymore because it is set once and for all
1390  * at process creation time and because it is stored
1391  * inside the Process->Session structure managed by MM,
1392  * we fake changing it: we just return success if the
1393  * user-defined value is the same as the session ID of
1394  * the process, and otherwise we fail.
1395  */
1396  if (SessionInfo.SessionId == PsGetProcessSessionId(Process))
1397  {
1399  }
1400  else
1401  {
1403  }
1404 
1405  break;
1406 
1407  case ProcessPriorityClass:
1408 
1409  /* Check buffer length */
1410  if (ProcessInformationLength != sizeof(PROCESS_PRIORITY_CLASS))
1411  {
1413  break;
1414  }
1415 
1416  /* Enter SEH for capture */
1417  _SEH2_TRY
1418  {
1419  /* Capture the caller's buffer */
1420  PriorityClass = *(PPROCESS_PRIORITY_CLASS)ProcessInformation;
1421  }
1423  {
1424  /* Return the exception code */
1426  _SEH2_YIELD(break);
1427  }
1428  _SEH2_END;
1429 
1430  /* Check for invalid PriorityClass value */
1432  {
1434  break;
1435  }
1436 
1437  if ((PriorityClass.PriorityClass != Process->PriorityClass) &&
1439  {
1440  /* Check the privilege */
1442  ProcessHandle,
1444  PreviousMode);
1445  if (!HasPrivilege)
1446  {
1448  DPRINT1("Privilege to change priority to realtime lacking\n");
1450  }
1451  }
1452 
1453  /* Check if we have a job */
1454  if (Process->Job)
1455  {
1456  DPRINT1("Jobs not yet supported\n");
1457  }
1458 
1459  /* Set process priority class */
1460  Process->PriorityClass = PriorityClass.PriorityClass;
1461 
1462  /* Set process priority mode (foreground or background) */
1464  PriorityClass.Foreground ?
1468  break;
1469 
1471 
1472  /* Check buffer length */
1473  if (ProcessInformationLength != sizeof(PROCESS_FOREGROUND_BACKGROUND))
1474  {
1476  break;
1477  }
1478 
1479  /* Enter SEH for capture */
1480  _SEH2_TRY
1481  {
1482  /* Capture the caller's buffer */
1483  Foreground = *(PPROCESS_FOREGROUND_BACKGROUND)ProcessInformation;
1484  }
1486  {
1487  /* Return the exception code */
1489  _SEH2_YIELD(break);
1490  }
1491  _SEH2_END;
1492 
1493  /* Set process priority mode (foreground or background) */
1495  Foreground.Foreground ?
1499  break;
1500 
1501  case ProcessBasePriority:
1502 
1503  /* Validate input length */
1504  if (ProcessInformationLength != sizeof(KPRIORITY))
1505  {
1507  break;
1508  }
1509 
1510  /* Enter SEH for direct buffer read */
1511  _SEH2_TRY
1512  {
1513  BasePriority = *(KPRIORITY*)ProcessInformation;
1514  }
1516  {
1517  /* Get exception code */
1518  Break = 0;
1520  _SEH2_YIELD(break);
1521  }
1522  _SEH2_END;
1523 
1524  /* Extract the memory priority out of there */
1525  if (BasePriority & 0x80000000)
1526  {
1527  MemoryPriority = MEMORY_PRIORITY_FOREGROUND;
1528  BasePriority &= ~0x80000000;
1529  }
1530  else
1531  {
1532  MemoryPriority = MEMORY_PRIORITY_BACKGROUND;
1533  }
1534 
1535  /* Validate the number */
1536  if ((BasePriority > HIGH_PRIORITY) || (BasePriority <= LOW_PRIORITY))
1537  {
1539  return STATUS_INVALID_PARAMETER;
1540  }
1541 
1542  /* Check if the new base is higher */
1543  if (BasePriority > Process->Pcb.BasePriority)
1544  {
1546  ProcessHandle,
1548  PreviousMode);
1549  if (!HasPrivilege)
1550  {
1552  DPRINT1("Privilege to change priority from %lx to %lx lacking\n", BasePriority, Process->Pcb.BasePriority);
1554  }
1555  }
1556 
1557  /* Call Ke */
1558  KeSetPriorityAndQuantumProcess(&Process->Pcb, BasePriority, 0);
1559 
1560  /* Now set the memory priority */
1561  MmSetMemoryPriorityProcess(Process, MemoryPriority);
1563  break;
1564 
1565  case ProcessRaisePriority:
1566 
1567  /* Validate input length */
1568  if (ProcessInformationLength != sizeof(ULONG))
1569  {
1571  break;
1572  }
1573 
1574  /* Enter SEH for direct buffer read */
1575  _SEH2_TRY
1576  {
1577  Boost = *(PULONG)ProcessInformation;
1578  }
1580  {
1581  /* Get exception code */
1582  Break = 0;
1584  _SEH2_YIELD(break);
1585  }
1586  _SEH2_END;
1587 
1588  /* Make sure the process isn't dying */
1589  if (ExAcquireRundownProtection(&Process->RundownProtect))
1590  {
1591  /* Lock it */
1593  ExAcquirePushLockShared(&Process->ProcessLock);
1594 
1595  /* Loop the threads */
1596  for (Next = Process->ThreadListHead.Flink;
1597  Next != &Process->ThreadListHead;
1598  Next = Next->Flink)
1599  {
1600  /* Call Ke for the thread */
1601  Thread = CONTAINING_RECORD(Next, ETHREAD, ThreadListEntry);
1602  KeBoostPriorityThread(&Thread->Tcb, Boost);
1603  }
1604 
1605  /* Release the lock and rundown */
1606  ExReleasePushLockShared(&Process->ProcessLock);
1608  ExReleaseRundownProtection(&Process->RundownProtect);
1609 
1610  /* Set success code */
1612  }
1613  else
1614  {
1615  /* Avoid race conditions */
1617  }
1618  break;
1619 
1621 
1622  /* Check buffer length */
1623  if (ProcessInformationLength != sizeof(ULONG))
1624  {
1626  break;
1627  }
1628 
1629  /* Enter SEH for direct buffer read */
1630  _SEH2_TRY
1631  {
1632  Break = *(PULONG)ProcessInformation;
1633  }
1635  {
1636  /* Get exception code */
1637  Break = 0;
1639  _SEH2_YIELD(break);
1640  }
1641  _SEH2_END;
1642 
1643  /* Setting 'break on termination' requires the SeDebugPrivilege */
1645  {
1646  /* We don't hold the privilege, bail out */
1648  break;
1649  }
1650 
1651  /* Set or clear the flag */
1652  if (Break)
1653  {
1655  }
1656  else
1657  {
1659  }
1660 
1661  break;
1662 
1663  case ProcessAffinityMask:
1664 
1665  /* Check buffer length */
1666  if (ProcessInformationLength != sizeof(KAFFINITY))
1667  {
1669  break;
1670  }
1671 
1672  /* Enter SEH for direct buffer read */
1673  _SEH2_TRY
1674  {
1675  Affinity = *(PKAFFINITY)ProcessInformation;
1676  }
1678  {
1679  /* Get exception code */
1680  Break = 0;
1682  _SEH2_YIELD(break);
1683  }
1684  _SEH2_END;
1685 
1686  /* Make sure it's valid for the CPUs present */
1687  ValidAffinity = Affinity & KeActiveProcessors;
1688  if (!Affinity || (ValidAffinity != Affinity))
1689  {
1691  break;
1692  }
1693 
1694  /* Check if it's within job affinity limits */
1695  if (Process->Job)
1696  {
1697  /* Not yet implemented */
1698  UNIMPLEMENTED;
1700  break;
1701  }
1702 
1703  /* Make sure the process isn't dying */
1704  if (ExAcquireRundownProtection(&Process->RundownProtect))
1705  {
1706  /* Lock it */
1708  ExAcquirePushLockShared(&Process->ProcessLock);
1709 
1710  /* Call Ke to do the work */
1711  KeSetAffinityProcess(&Process->Pcb, ValidAffinity);
1712 
1713  /* Release the lock and rundown */
1714  ExReleasePushLockShared(&Process->ProcessLock);
1716  ExReleaseRundownProtection(&Process->RundownProtect);
1717 
1718  /* Set success code */
1720  }
1721  else
1722  {
1723  /* Avoid race conditions */
1725  }
1726  break;
1727 
1728  /* Priority Boosting status */
1729  case ProcessPriorityBoost:
1730 
1731  /* Validate input length */
1732  if (ProcessInformationLength != sizeof(ULONG))
1733  {
1735  break;
1736  }
1737 
1738  /* Enter SEH for direct buffer read */
1739  _SEH2_TRY
1740  {
1741  DisableBoost = *(PBOOLEAN)ProcessInformation;
1742  }
1744  {
1745  /* Get exception code */
1746  Break = 0;
1748  _SEH2_YIELD(break);
1749  }
1750  _SEH2_END;
1751 
1752  /* Make sure the process isn't dying */
1753  if (ExAcquireRundownProtection(&Process->RundownProtect))
1754  {
1755  /* Lock it */
1757  ExAcquirePushLockShared(&Process->ProcessLock);
1758 
1759  /* Call Ke to do the work */
1760  KeSetDisableBoostProcess(&Process->Pcb, DisableBoost);
1761 
1762  /* Loop the threads too */
1763  for (Next = Process->ThreadListHead.Flink;
1764  Next != &Process->ThreadListHead;
1765  Next = Next->Flink)
1766  {
1767  /* Call Ke for the thread */
1768  Thread = CONTAINING_RECORD(Next, ETHREAD, ThreadListEntry);
1769  KeSetDisableBoostThread(&Thread->Tcb, DisableBoost);
1770  }
1771 
1772  /* Release the lock and rundown */
1773  ExReleasePushLockShared(&Process->ProcessLock);
1775  ExReleaseRundownProtection(&Process->RundownProtect);
1776 
1777  /* Set success code */
1779  }
1780  else
1781  {
1782  /* Avoid race conditions */
1784  }
1785  break;
1786 
1787  case ProcessDebugFlags:
1788 
1789  /* Check buffer length */
1790  if (ProcessInformationLength != sizeof(ULONG))
1791  {
1793  break;
1794  }
1795 
1796  /* Enter SEH for direct buffer read */
1797  _SEH2_TRY
1798  {
1799  DebugFlags = *(PULONG)ProcessInformation;
1800  }
1802  {
1803  /* Get exception code */
1805  _SEH2_YIELD(break);
1806  }
1807  _SEH2_END;
1808 
1809  /* Set the mode */
1810  if (DebugFlags & ~1)
1811  {
1813  }
1814  else
1815  {
1816  if (DebugFlags & 1)
1817  {
1819  }
1820  else
1821  {
1823  }
1824  }
1825 
1826  /* Done */
1828  break;
1829 
1831 
1832  /* Check buffer length */
1833  if (ProcessInformationLength != sizeof(ULONG))
1834  {
1836  break;
1837  }
1838 
1839  /* Enter SEH for direct buffer read */
1840  _SEH2_TRY
1841  {
1842  EnableFixup = *(PULONG)ProcessInformation;
1843  }
1845  {
1846  /* Get exception code */
1848  _SEH2_YIELD(break);
1849  }
1850  _SEH2_END;
1851 
1852  /* Set the mode */
1853  if (EnableFixup)
1854  {
1855  Process->DefaultHardErrorProcessing |= SEM_NOALIGNMENTFAULTEXCEPT;
1856  }
1857  else
1858  {
1859  Process->DefaultHardErrorProcessing &= ~SEM_NOALIGNMENTFAULTEXCEPT;
1860  }
1861 
1862  /* Call Ke for the update */
1865  break;
1866 
1867  case ProcessUserModeIOPL:
1868 
1869  /* Only TCB can do this */
1871  {
1872  /* We don't hold the privilege, bail out */
1873  DPRINT1("Need TCB to set IOPL\n");
1875  break;
1876  }
1877 
1878  /* Only supported on x86 */
1879 #if defined (_X86_)
1880  Ke386SetIOPL();
1881 #else
1883 #endif
1884  /* Done */
1885  break;
1886 
1887  case ProcessExecuteFlags:
1888 
1889  /* Check buffer length */
1890  if (ProcessInformationLength != sizeof(ULONG))
1891  {
1893  break;
1894  }
1895 
1897  {
1899  break;
1900  }
1901 
1902  /* Enter SEH for direct buffer read */
1903  _SEH2_TRY
1904  {
1905  NoExecute = *(PULONG)ProcessInformation;
1906  }
1908  {
1909  /* Get exception code */
1911  _SEH2_YIELD(break);
1912  }
1913  _SEH2_END;
1914 
1915  /* Call Mm for the update */
1916  Status = MmSetExecuteOptions(NoExecute);
1917  break;
1918 
1919  /* We currently don't implement any of these */
1920  case ProcessLdtInformation:
1921  case ProcessLdtSize:
1922  case ProcessIoPortHandlers:
1923  DPRINT1("VDM/16-bit Request not implemented: %lx\n", ProcessInformationClass);
1925  break;
1926 
1927  case ProcessQuotaLimits:
1928 
1930  1,
1931  ProcessInformation,
1932  ProcessInformationLength,
1933  PreviousMode);
1934  break;
1935 
1937  DPRINT1("WS watch not implemented\n");
1939  break;
1940 
1941  case ProcessDeviceMap:
1942  DPRINT1("Device map not implemented\n");
1944  break;
1945 
1946  case ProcessHandleTracing:
1947  DPRINT1("Handle tracing not implemented\n");
1949  break;
1950 
1951  /* Anything else is invalid */
1952  default:
1953  DPRINT1("Invalid Server 2003 Info Class: %lx\n", ProcessInformationClass);
1955  }
1956 
1957  /* Dereference and return status */
1959  return Status;
1960 }
1961 
1962 /*
1963  * @implemented
1964  */
1965 NTSTATUS
1966 NTAPI
1969  IN PVOID ThreadInformation,
1971 {
1972  PETHREAD Thread;
1973  ULONG Access;
1975  NTSTATUS Status;
1977  KPRIORITY Priority = 0;
1978  KAFFINITY Affinity = 0, CombinedAffinity;
1979  PVOID Address = NULL;
1981  ULONG_PTR DisableBoost = 0;
1982  ULONG_PTR IdealProcessor = 0;
1983  ULONG_PTR Break = 0;
1984  PTEB Teb;
1985  ULONG_PTR TlsIndex = 0;
1986  PVOID *ExpansionSlots;
1987  PETHREAD ProcThread;
1988  PAGED_CODE();
1989 
1990  /* Verify Information Class validity */
1991 #if 0
1993  PsThreadInfoClass,
1994  RTL_NUMBER_OF(PsThreadInfoClass),
1995  ThreadInformation,
1997  PreviousMode);
1998  if (!NT_SUCCESS(Status)) return Status;
1999 #endif
2000 
2001  /* Check what class this is */
2002  Access = THREAD_SET_INFORMATION;
2004  {
2005  /* Setting the impersonation token needs a special mask */
2006  Access = THREAD_SET_THREAD_TOKEN;
2007  }
2008 
2009  /* Reference the thread */
2010  Status = ObReferenceObjectByHandle(ThreadHandle,
2011  Access,
2012  PsThreadType,
2013  PreviousMode,
2014  (PVOID*)&Thread,
2015  NULL);
2016  if (!NT_SUCCESS(Status)) return Status;
2017 
2018  /* Check what kind of information class this is */
2019  switch (ThreadInformationClass)
2020  {
2021  /* Thread priority */
2022  case ThreadPriority:
2023 
2024  /* Check buffer length */
2025  if (ThreadInformationLength != sizeof(KPRIORITY))
2026  {
2028  break;
2029  }
2030 
2031  /* Use SEH for capture */
2032  _SEH2_TRY
2033  {
2034  /* Get the priority */
2035  Priority = *(PLONG)ThreadInformation;
2036  }
2038  {
2039  /* Get the exception code */
2041  _SEH2_YIELD(break);
2042  }
2043  _SEH2_END;
2044 
2045  /* Validate it */
2046  if ((Priority > HIGH_PRIORITY) ||
2047  (Priority <= LOW_PRIORITY))
2048  {
2049  /* Fail */
2051  break;
2052  }
2053 
2054  /* Set the priority */
2056  break;
2057 
2058  case ThreadBasePriority:
2059 
2060  /* Check buffer length */
2061  if (ThreadInformationLength != sizeof(LONG))
2062  {
2064  break;
2065  }
2066 
2067  /* Use SEH for capture */
2068  _SEH2_TRY
2069  {
2070  /* Get the priority */
2071  Priority = *(PLONG)ThreadInformation;
2072  }
2074  {
2075  /* Get the exception code */
2077  _SEH2_YIELD(break);
2078  }
2079  _SEH2_END;
2080 
2081  /* Validate it */
2084  {
2085  /* These ones are OK */
2086  if ((Priority != THREAD_BASE_PRIORITY_LOWRT + 1) &&
2088  {
2089  /* Check if the process is real time */
2090  if (PsGetCurrentProcess()->PriorityClass !=
2092  {
2093  /* It isn't, fail */
2095  break;
2096  }
2097  }
2098  }
2099 
2100  /* Set the base priority */
2102  break;
2103 
2104  case ThreadAffinityMask:
2105 
2106  /* Check buffer length */
2107  if (ThreadInformationLength != sizeof(ULONG_PTR))
2108  {
2110  break;
2111  }
2112 
2113  /* Use SEH for capture */
2114  _SEH2_TRY
2115  {
2116  /* Get the priority */
2117  Affinity = *(PULONG_PTR)ThreadInformation;
2118  }
2120  {
2121  /* Get the exception code */
2123  _SEH2_YIELD(break);
2124  }
2125  _SEH2_END;
2126 
2127  /* Validate it */
2128  if (!Affinity)
2129  {
2130  /* Fail */
2132  break;
2133  }
2134 
2135  /* Get the process */
2136  Process = Thread->ThreadsProcess;
2137 
2138  /* Try to acquire rundown */
2139  if (ExAcquireRundownProtection(&Process->RundownProtect))
2140  {
2141  /* Lock it */
2143  ExAcquirePushLockShared(&Process->ProcessLock);
2144 
2145  /* Combine masks */
2146  CombinedAffinity = Affinity & Process->Pcb.Affinity;
2147  if (CombinedAffinity != Affinity)
2148  {
2149  /* Fail */
2151  }
2152  else
2153  {
2154  /* Set the affinity */
2155  KeSetAffinityThread(&Thread->Tcb, CombinedAffinity);
2156  }
2157 
2158  /* Release the lock and rundown */
2159  ExReleasePushLockShared(&Process->ProcessLock);
2161  ExReleaseRundownProtection(&Process->RundownProtect);
2162  }
2163  else
2164  {
2165  /* Too late */
2167  }
2168 
2169  /* Return status */
2170  break;
2171 
2173 
2174  /* Check buffer length */
2175  if (ThreadInformationLength != sizeof(HANDLE))
2176  {
2178  break;
2179  }
2180 
2181  /* Use SEH for capture */
2182  _SEH2_TRY
2183  {
2184  /* Save the token handle */
2185  TokenHandle = *(PHANDLE)ThreadInformation;
2186  }
2188  {
2189  /* Get the exception code */
2191  _SEH2_YIELD(break);
2192  }
2193  _SEH2_END;
2194 
2195  /* Assign the actual token */
2197  break;
2198 
2200 
2201  /* Check buffer length */
2202  if (ThreadInformationLength != sizeof(ULONG_PTR))
2203  {
2205  break;
2206  }
2207 
2208  /* Use SEH for capture */
2209  _SEH2_TRY
2210  {
2211  /* Get the priority */
2212  Address = *(PVOID*)ThreadInformation;
2213  }
2215  {
2216  /* Get the exception code */
2218  _SEH2_YIELD(break);
2219  }
2220  _SEH2_END;
2221 
2222  /* Set the address */
2224  break;
2225 
2226  case ThreadIdealProcessor:
2227 
2228  /* Check buffer length */
2229  if (ThreadInformationLength != sizeof(ULONG_PTR))
2230  {
2232  break;
2233  }
2234 
2235  /* Use SEH for capture */
2236  _SEH2_TRY
2237  {
2238  /* Get the priority */
2239  IdealProcessor = *(PULONG_PTR)ThreadInformation;
2240  }
2242  {
2243  /* Get the exception code */
2245  _SEH2_YIELD(break);
2246  }
2247  _SEH2_END;
2248 
2249  /* Validate it */
2250  if (IdealProcessor > MAXIMUM_PROCESSORS)
2251  {
2252  /* Fail */
2254  break;
2255  }
2256 
2257  /* Set the ideal */
2259  (CCHAR)IdealProcessor);
2260 
2261  /* Get the TEB and protect the thread */
2262  Teb = Thread->Tcb.Teb;
2264  {
2265  /* Save the ideal processor */
2266  Teb->IdealProcessor = Thread->Tcb.IdealProcessor;
2267 
2268  /* Release rundown protection */
2270  }
2271 
2272  break;
2273 
2274  case ThreadPriorityBoost:
2275 
2276  /* Check buffer length */
2277  if (ThreadInformationLength != sizeof(ULONG_PTR))
2278  {
2280  break;
2281  }
2282 
2283  /* Use SEH for capture */
2284  _SEH2_TRY
2285  {
2286  /* Get the priority */
2287  DisableBoost = *(PULONG_PTR)ThreadInformation;
2288  }
2290  {
2291  /* Get the exception code */
2293  _SEH2_YIELD(break);
2294  }
2295  _SEH2_END;
2296 
2297  /* Call the kernel */
2298  KeSetDisableBoostThread(&Thread->Tcb, (BOOLEAN)DisableBoost);
2299  break;
2300 
2301  case ThreadZeroTlsCell:
2302 
2303  /* Check buffer length */
2304  if (ThreadInformationLength != sizeof(ULONG_PTR))
2305  {
2307  break;
2308  }
2309 
2310  /* Use SEH for capture */
2311  _SEH2_TRY
2312  {
2313  /* Get the priority */
2314  TlsIndex = *(PULONG_PTR)ThreadInformation;
2315  }
2317  {
2318  /* Get the exception code */
2320  _SEH2_YIELD(break);
2321  }
2322  _SEH2_END;
2323 
2324  /* This is only valid for the current thread */
2325  if (Thread != PsGetCurrentThread())
2326  {
2327  /* Fail */
2329  break;
2330  }
2331 
2332  /* Get the process */
2333  Process = Thread->ThreadsProcess;
2334 
2335  /* Loop the threads */
2336  ProcThread = PsGetNextProcessThread(Process, NULL);
2337  while (ProcThread)
2338  {
2339  /* Acquire rundown */
2340  if (ExAcquireRundownProtection(&ProcThread->RundownProtect))
2341  {
2342  /* Get the TEB */
2343  Teb = ProcThread->Tcb.Teb;
2344  if (Teb)
2345  {
2346  /* Check if we're in the expansion range */
2347  if (TlsIndex > TLS_MINIMUM_AVAILABLE - 1)
2348  {
2350  TLS_EXPANSION_SLOTS) - 1)
2351  {
2352  /* Check if we have expansion slots */
2353  ExpansionSlots = Teb->TlsExpansionSlots;
2354  if (ExpansionSlots)
2355  {
2356  /* Clear the index */
2357  ExpansionSlots[TlsIndex - TLS_MINIMUM_AVAILABLE] = 0;
2358  }
2359  }
2360  }
2361  else
2362  {
2363  /* Clear the index */
2364  Teb->TlsSlots[TlsIndex] = NULL;
2365  }
2366  }
2367 
2368  /* Release rundown */
2370  }
2371 
2372  /* Go to the next thread */
2373  ProcThread = PsGetNextProcessThread(Process, ProcThread);
2374  }
2375 
2376  /* All done */
2377  break;
2378 
2380 
2381  /* Check buffer length */
2382  if (ThreadInformationLength != sizeof(ULONG))
2383  {
2385  break;
2386  }
2387 
2388  /* Enter SEH for direct buffer read */
2389  _SEH2_TRY
2390  {
2391  Break = *(PULONG)ThreadInformation;
2392  }
2394  {
2395  /* Get exception code */
2396  Break = 0;
2398  _SEH2_YIELD(break);
2399  }
2400  _SEH2_END;
2401 
2402  /* Setting 'break on termination' requires the SeDebugPrivilege */
2404  {
2405  /* We don't hold the privilege, bail out */
2407  break;
2408  }
2409 
2410  /* Set or clear the flag */
2411  if (Break)
2412  {
2414  }
2415  else
2416  {
2418  }
2419  break;
2420 
2422 
2423  /* Check buffer length */
2424  if (ThreadInformationLength != 0)
2425  {
2427  break;
2428  }
2429 
2430  /* Set the flag */
2432  break;
2433 
2434  default:
2435  /* We don't implement it yet */
2436  DPRINT1("Not implemented: %d\n", ThreadInformationClass);
2438  }
2439 
2440  /* Dereference and return status */
2442  return Status;
2443 }
2444 
2445 /*
2446  * @implemented
2447  */
2448 NTSTATUS
2449 NTAPI
2452  OUT PVOID ThreadInformation,
2455 {
2456  PETHREAD Thread;
2458  NTSTATUS Status;
2459  ULONG Access;
2460  ULONG Length = 0;
2461  PTHREAD_BASIC_INFORMATION ThreadBasicInfo =
2462  (PTHREAD_BASIC_INFORMATION)ThreadInformation;
2463  PKERNEL_USER_TIMES ThreadTime = (PKERNEL_USER_TIMES)ThreadInformation;
2464  KIRQL OldIrql;
2465  ULONG ThreadTerminated;
2466  PAGED_CODE();
2467 
2468  /* Check if we were called from user mode */
2469  if (PreviousMode != KernelMode)
2470  {
2471  /* Enter SEH */
2472  _SEH2_TRY
2473  {
2474  /* Probe the buffer */
2475  ProbeForWrite(ThreadInformation,
2477  sizeof(ULONG));
2478 
2479  /* Probe the return length if required */
2481  }
2483  {
2484  /* Return the exception code */
2486  }
2487  _SEH2_END;
2488  }
2489 
2490  /* Check what class this is */
2491  Access = THREAD_QUERY_INFORMATION;
2492 
2493  /* Reference the process */
2494  Status = ObReferenceObjectByHandle(ThreadHandle,
2495  Access,
2496  PsThreadType,
2497  PreviousMode,
2498  (PVOID*)&Thread,
2499  NULL);
2500  if (!NT_SUCCESS(Status)) return Status;
2501 
2502  /* Check what kind of information class this is */
2503  switch (ThreadInformationClass)
2504  {
2505  /* Basic thread information */
2507 
2508  /* Set return length */
2509  Length = sizeof(THREAD_BASIC_INFORMATION);
2510 
2512  {
2514  break;
2515  }
2516  /* Protect writes with SEH */
2517  _SEH2_TRY
2518  {
2519  /* Write all the information from the ETHREAD/KTHREAD */
2520  ThreadBasicInfo->ExitStatus = Thread->ExitStatus;
2521  ThreadBasicInfo->TebBaseAddress = (PVOID)Thread->Tcb.Teb;
2522  ThreadBasicInfo->ClientId = Thread->Cid;
2523  ThreadBasicInfo->AffinityMask = Thread->Tcb.Affinity;
2524  ThreadBasicInfo->Priority = Thread->Tcb.Priority;
2525  ThreadBasicInfo->BasePriority = KeQueryBasePriorityThread(&Thread->Tcb);
2526  }
2528  {
2529  /* Get exception code */
2531  }
2532  _SEH2_END;
2533  break;
2534 
2535  /* Thread time information */
2536  case ThreadTimes:
2537 
2538  /* Set the return length */
2539  Length = sizeof(KERNEL_USER_TIMES);
2540 
2542  {
2544  break;
2545  }
2546  /* Protect writes with SEH */
2547  _SEH2_TRY
2548  {
2549  /* Copy time information from ETHREAD/KTHREAD */
2552  ThreadTime->CreateTime = Thread->CreateTime;
2553 
2554  /* Exit time is in a union and only valid on actual exit! */
2555  if (KeReadStateThread(&Thread->Tcb))
2556  {
2557  ThreadTime->ExitTime = Thread->ExitTime;
2558  }
2559  else
2560  {
2561  ThreadTime->ExitTime.QuadPart = 0;
2562  }
2563  }
2565  {
2566  /* Get exception code */
2568  }
2569  _SEH2_END;
2570  break;
2571 
2573 
2574  /* Set the return length*/
2575  Length = sizeof(PVOID);
2576 
2578  {
2580  break;
2581  }
2582  /* Protect write with SEH */
2583  _SEH2_TRY
2584  {
2585  /* Return the Win32 Start Address */
2586  *(PVOID*)ThreadInformation = Thread->Win32StartAddress;
2587  }
2589  {
2590  /* Get exception code */
2592  }
2593  _SEH2_END;
2594  break;
2595 
2597 
2598  /* Set the return length*/
2599  Length = sizeof(LARGE_INTEGER);
2600 
2602  {
2604  break;
2605  }
2606  /* Protect write with SEH */
2607  _SEH2_TRY
2608  {
2609  /* FIXME */
2610  (*(PLARGE_INTEGER)ThreadInformation).QuadPart = 0;
2611  }
2613  {
2614  /* Get exception code */
2616  }
2617  _SEH2_END;
2618  break;
2619 
2620  case ThreadAmILastThread:
2621 
2622  /* Set the return length*/
2623  Length = sizeof(ULONG);
2624 
2626  {
2628  break;
2629  }
2630  /* Protect write with SEH */
2631  _SEH2_TRY
2632  {
2633  /* Return whether or not we are the last thread */
2634  *(PULONG)ThreadInformation = ((Thread->ThreadsProcess->
2635  ThreadListHead.Flink->Flink ==
2636  &Thread->ThreadsProcess->
2637  ThreadListHead) ?
2638  TRUE : FALSE);
2639  }
2641  {
2642  /* Get exception code */
2644  }
2645  _SEH2_END;
2646  break;
2647 
2648  case ThreadIsIoPending:
2649 
2650  /* Set the return length*/
2651  Length = sizeof(ULONG);
2652 
2654  {
2656  break;
2657  }
2658  /* Raise the IRQL to protect the IRP list */
2660 
2661  /* Protect write with SEH */
2662  _SEH2_TRY
2663  {
2664  /* Check if the IRP list is empty or not */
2665  *(PULONG)ThreadInformation = !IsListEmpty(&Thread->IrpList);
2666  }
2668  {
2669  /* Get exception code */
2671  }
2672  _SEH2_END;
2673 
2674  /* Lower IRQL back */
2676  break;
2677 
2678  /* LDT and GDT information */
2680 
2681 #if defined(_X86_)
2682  /* Call the worker routine */
2684  ThreadInformation,
2686  ReturnLength);
2687 #else
2688  /* Only implemented on x86 */
2690 #endif
2691  break;
2692 
2693  case ThreadPriorityBoost:
2694 
2695  /* Set the return length*/
2696  Length = sizeof(ULONG);
2697 
2699  {
2701  break;
2702  }
2703 
2704  _SEH2_TRY
2705  {
2706  *(PULONG)ThreadInformation = Thread->Tcb.DisableBoost ? 1 : 0;
2707  }
2709  {
2711  }
2712  _SEH2_END;
2713  break;
2714 
2715  case ThreadIsTerminated:
2716 
2717  /* Set the return length*/
2718  Length = sizeof(ThreadTerminated);
2719 
2721  {
2723  break;
2724  }
2725 
2726  ThreadTerminated = PsIsThreadTerminating(Thread);
2727 
2728  _SEH2_TRY
2729  {
2730  *(PULONG)ThreadInformation = ThreadTerminated ? 1 : 0;
2731  }
2733  {
2735  }
2736  _SEH2_END;
2737 
2738  break;
2739 
2740  /* Anything else */
2741  default:
2742 
2743  /* Not yet implemented */
2744  DPRINT1("Not implemented: %lx\n", ThreadInformationClass);
2746  }
2747 
2748  /* Protect write with SEH */
2749  _SEH2_TRY
2750  {
2751  /* Check if caller wanted return length */
2753  }
2755  {
2756  /* Get exception code */
2758  }
2759  _SEH2_END;
2760 
2761  /* Dereference the thread, and return */
2763  return Status;
2764 }
2765 
2766 /* 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: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_DEVICEMAP_INFORMATION PROCESS_DEVICEMAP_INFORMATION
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
_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
SIZE_T PagefileUsage
Definition: winternl.h:1614
SIZE_T QuotaPeakPagedPoolUsage
Definition: winternl.h:1610
#define InterlockedCompareExchange
Definition: interlocked.h:104
BOOLEAN NTAPI SeSinglePrivilegeCheck(IN LUID PrivilegeValue, IN KPROCESSOR_MODE PreviousMode)
Definition: priv.c:524
KPROCESSOR_MODE NTAPI ExGetPreviousMode(VOID)
Definition: sysinfo.c:2966
LONG NTAPI KeSetBasePriorityThread(IN PKTHREAD Thread, IN LONG Increment)
Definition: thrdobj.c:1184
struct _PROCESS_DEVICEMAP_INFORMATION * PPROCESS_DEVICEMAP_INFORMATION
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
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
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:834
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:1967
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
VOID NTAPI ObQueryDeviceMapInformation(IN PEPROCESS Process, OUT PPROCESS_DEVICEMAP_INFORMATION DeviceMapInfo)
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
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:1954
NTSTATUS NTAPI NtQueryInformationThread(IN HANDLE ThreadHandle, IN THREADINFOCLASS ThreadInformationClass, OUT PVOID ThreadInformation, IN ULONG ThreadInformationLength, OUT PULONG ReturnLength OPTIONAL)
Definition: query.c:2450
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
_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:494
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:1089
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:837
#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:470
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
struct _LARGE_INTEGER::@2192 u
#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:187
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:2725
signed int * PLONG
Definition: retypes.h:5
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