ReactOS  0.4.10-dev-2-g0fbaea8
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 */
41  *FileObject = MmGetFileObjectForSection((PVOID)Section);
42  ObReferenceObject(*FileObject);
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  PAGED_CODE();
86 
87  /* Check for user-mode caller */
88  if (PreviousMode != KernelMode)
89  {
90  /* Prepare to probe parameters */
91  _SEH2_TRY
92  {
93  /* Probe the buffer */
94  ProbeForRead(ProcessInformation,
95  ProcessInformationLength,
96  sizeof(ULONG));
97 
98  /* Probe the return length if required */
100  }
102  {
103  /* Return the exception code */
105  }
106  _SEH2_END;
107  }
108 
109  if (((ProcessInformationClass == ProcessCookie) ||
110  (ProcessInformationClass == ProcessImageInformation)) &&
111  (ProcessHandle != NtCurrentProcess()))
112  {
113  /*
114  * Retrieving the process cookie is only allowed for the calling process
115  * itself! XP only allows NtCurrentProcess() as process handles even if
116  * a real handle actually represents the current process.
117  */
119  }
120 
121  /* Check the information class */
122  switch (ProcessInformationClass)
123  {
124  /* Basic process information */
126 
127  if (ProcessInformationLength != sizeof(PROCESS_BASIC_INFORMATION))
128  {
130  break;
131  }
132 
133  /* Set return length */
134  Length = sizeof(PROCESS_BASIC_INFORMATION);
135 
136  /* Reference the process */
137  Status = ObReferenceObjectByHandle(ProcessHandle,
140  PreviousMode,
141  (PVOID*)&Process,
142  NULL);
143  if (!NT_SUCCESS(Status)) break;
144 
145  /* Protect writes with SEH */
146  _SEH2_TRY
147  {
148  /* Write all the information from the EPROCESS/KPROCESS */
149  ProcessBasicInfo->ExitStatus = Process->ExitStatus;
150  ProcessBasicInfo->PebBaseAddress = Process->Peb;
151  ProcessBasicInfo->AffinityMask = Process->Pcb.Affinity;
152  ProcessBasicInfo->UniqueProcessId = (ULONG_PTR)Process->
153  UniqueProcessId;
154  ProcessBasicInfo->InheritedFromUniqueProcessId =
156  ProcessBasicInfo->BasePriority = Process->Pcb.BasePriority;
157 
158  }
160  {
161  /* Get exception code */
162  Status = _SEH2_GetExceptionCode();
163  }
164  _SEH2_END;
165 
166  /* Dereference the process */
167  ObDereferenceObject(Process);
168  break;
169 
170  /* Process quota limits */
171  case ProcessQuotaLimits:
172 
173  if (ProcessInformationLength != sizeof(QUOTA_LIMITS))
174  {
176  break;
177  }
178 
179  Length = sizeof(QUOTA_LIMITS);
180 
181  /* Reference the process */
182  Status = ObReferenceObjectByHandle(ProcessHandle,
185  PreviousMode,
186  (PVOID*)&Process,
187  NULL);
188  if (!NT_SUCCESS(Status)) break;
189 
190  /* Indicate success */
191  Status = STATUS_SUCCESS;
192 
193  _SEH2_TRY
194  {
195  /* Set max/min working set sizes */
196  QuotaLimits->MaximumWorkingSetSize =
197  Process->Vm.MaximumWorkingSetSize << PAGE_SHIFT;
198  QuotaLimits->MinimumWorkingSetSize =
199  Process->Vm.MinimumWorkingSetSize << PAGE_SHIFT;
200 
201  /* Set default time limits */
202  QuotaLimits->TimeLimit.LowPart = MAXULONG;
203  QuotaLimits->TimeLimit.HighPart = MAXULONG;
204 
205  /* Is quota block a default one? */
206  if (Process->QuotaBlock == &PspDefaultQuotaBlock)
207  {
208  /* Set default pools and pagefile limits */
209  QuotaLimits->PagedPoolLimit = (SIZE_T)-1;
210  QuotaLimits->NonPagedPoolLimit = (SIZE_T)-1;
211  QuotaLimits->PagefileLimit = (SIZE_T)-1;
212  }
213  else
214  {
215  /* Get limits from non-default quota block */
216  QuotaLimits->PagedPoolLimit =
218  QuotaLimits->NonPagedPoolLimit =
220  QuotaLimits->PagefileLimit =
221  Process->QuotaBlock->QuotaEntry[2].Limit;
222  }
223  }
225  {
226  /* Get exception code */
227  Status = _SEH2_GetExceptionCode();
228  }
229  _SEH2_END;
230 
231  /* Dereference the process */
232  ObDereferenceObject(Process);
233  break;
234 
235  case ProcessIoCounters:
236 
237  if (ProcessInformationLength != sizeof(IO_COUNTERS))
238  {
240  break;
241  }
242 
243  Length = sizeof(IO_COUNTERS);
244 
245  /* Reference the process */
246  Status = ObReferenceObjectByHandle(ProcessHandle,
249  PreviousMode,
250  (PVOID*)&Process,
251  NULL);
252  if (!NT_SUCCESS(Status)) break;
253 
254  _SEH2_TRY
255  {
256  /* FIXME: Call KeQueryValuesProcess */
257  IoCounters->ReadOperationCount = Process->ReadOperationCount.QuadPart;
258  IoCounters->ReadTransferCount = Process->ReadTransferCount.QuadPart;
259  IoCounters->WriteOperationCount = Process->WriteOperationCount.QuadPart;
260  IoCounters->WriteTransferCount = Process->WriteTransferCount.QuadPart;
261  IoCounters->OtherOperationCount = Process->OtherOperationCount.QuadPart;
262  IoCounters->OtherTransferCount = Process->OtherTransferCount.QuadPart;
263  }
265  {
266  /* Ignore exception */
267  }
268  _SEH2_END;
269 
270  /* Set status to success in any case */
271  Status = STATUS_SUCCESS;
272 
273  /* Dereference the process */
274  ObDereferenceObject(Process);
275  break;
276 
277  /* Timing */
278  case ProcessTimes:
279 
280  /* Set the return length */
281  if (ProcessInformationLength != sizeof(KERNEL_USER_TIMES))
282  {
284  break;
285  }
286 
287  Length = sizeof(KERNEL_USER_TIMES);
288 
289  /* Reference the process */
290  Status = ObReferenceObjectByHandle(ProcessHandle,
293  PreviousMode,
294  (PVOID*)&Process,
295  NULL);
296  if (!NT_SUCCESS(Status)) break;
297 
298  /* Protect writes with SEH */
299  _SEH2_TRY
300  {
301  /* Copy time information from EPROCESS/KPROCESS */
302  KernelTime = KeQueryRuntimeProcess(&Process->Pcb, &UserTime);
303  ProcessTime->CreateTime = Process->CreateTime;
304  ProcessTime->UserTime.QuadPart = (LONGLONG)UserTime * KeMaximumIncrement;
305  ProcessTime->KernelTime.QuadPart = (LONGLONG)KernelTime * KeMaximumIncrement;
306  ProcessTime->ExitTime = Process->ExitTime;
307  }
309  {
310  /* Get exception code */
311  Status = _SEH2_GetExceptionCode();
312  }
313  _SEH2_END;
314 
315  /* Dereference the process */
316  ObDereferenceObject(Process);
317  break;
318 
319  /* Process Debug Port */
320  case ProcessDebugPort:
321 
322  if (ProcessInformationLength != sizeof(HANDLE))
323  {
325  break;
326  }
327 
328  /* Set return length */
329  Length = sizeof(HANDLE);
330 
331  /* Reference the process */
332  Status = ObReferenceObjectByHandle(ProcessHandle,
335  PreviousMode,
336  (PVOID*)&Process,
337  NULL);
338  if (!NT_SUCCESS(Status)) break;
339 
340  /* Protect write with SEH */
341  _SEH2_TRY
342  {
343  /* Return whether or not we have a debug port */
344  *(PHANDLE)ProcessInformation = (Process->DebugPort ?
345  (HANDLE)-1 : NULL);
346  }
348  {
349  /* Get exception code */
350  Status = _SEH2_GetExceptionCode();
351  }
352  _SEH2_END;
353 
354  /* Dereference the process */
355  ObDereferenceObject(Process);
356  break;
357 
358  case ProcessHandleCount:
359 
360  if (ProcessInformationLength != sizeof(ULONG))
361  {
363  break;
364  }
365 
366  /* Set the return length*/
367  Length = sizeof(ULONG);
368 
369  /* Reference the process */
370  Status = ObReferenceObjectByHandle(ProcessHandle,
373  PreviousMode,
374  (PVOID*)&Process,
375  NULL);
376  if (!NT_SUCCESS(Status)) break;
377 
378  /* Count the number of handles this process has */
379  HandleCount = ObGetProcessHandleCount(Process);
380 
381  /* Protect write in SEH */
382  _SEH2_TRY
383  {
384  /* Return the count of handles */
385  *(PULONG)ProcessInformation = HandleCount;
386  }
388  {
389  /* Get the exception code */
390  Status = _SEH2_GetExceptionCode();
391  }
392  _SEH2_END;
393 
394  /* Dereference the process */
395  ObDereferenceObject(Process);
396  break;
397 
398  /* Session ID for the process */
400 
401  if (ProcessInformationLength != sizeof(PROCESS_SESSION_INFORMATION))
402  {
404  break;
405  }
406 
407  /* Set the return length*/
408  Length = sizeof(PROCESS_SESSION_INFORMATION);
409 
410  /* Reference the process */
411  Status = ObReferenceObjectByHandle(ProcessHandle,
414  PreviousMode,
415  (PVOID*)&Process,
416  NULL);
417  if (!NT_SUCCESS(Status)) break;
418 
419  /* Enter SEH for write safety */
420  _SEH2_TRY
421  {
422  /* Write back the Session ID */
423  SessionInfo->SessionId = PsGetProcessSessionId(Process);
424  }
426  {
427  /* Get the exception code */
428  Status = _SEH2_GetExceptionCode();
429  }
430  _SEH2_END;
431 
432  /* Dereference the process */
433  ObDereferenceObject(Process);
434  break;
435 
436  /* Virtual Memory Statistics */
437  case ProcessVmCounters:
438 
439  /* Validate the input length */
440  if ((ProcessInformationLength != sizeof(VM_COUNTERS)) &&
441  (ProcessInformationLength != sizeof(VM_COUNTERS_EX)))
442  {
444  break;
445  }
446 
447  /* Reference the process */
448  Status = ObReferenceObjectByHandle(ProcessHandle,
451  PreviousMode,
452  (PVOID*)&Process,
453  NULL);
454  if (!NT_SUCCESS(Status)) break;
455 
456  /* Enter SEH for write safety */
457  _SEH2_TRY
458  {
459  /* Return data from EPROCESS */
460  VmCounters->PeakVirtualSize = Process->PeakVirtualSize;
461  VmCounters->VirtualSize = Process->VirtualSize;
462  VmCounters->PageFaultCount = Process->Vm.PageFaultCount;
463  VmCounters->PeakWorkingSetSize = Process->Vm.PeakWorkingSetSize;
464  VmCounters->WorkingSetSize = Process->Vm.WorkingSetSize;
465  VmCounters->QuotaPeakPagedPoolUsage = Process->QuotaPeak[0];
466  VmCounters->QuotaPagedPoolUsage = Process->QuotaUsage[0];
467  VmCounters->QuotaPeakNonPagedPoolUsage = Process->QuotaPeak[1];
468  VmCounters->QuotaNonPagedPoolUsage = Process->QuotaUsage[1];
469  VmCounters->PagefileUsage = Process->QuotaUsage[2] << PAGE_SHIFT;
470  VmCounters->PeakPagefileUsage = Process->QuotaPeak[2] << PAGE_SHIFT;
471  //VmCounters->PrivateUsage = Process->CommitCharge << PAGE_SHIFT;
472  //
473 
474  /* Set the return length */
475  Length = ProcessInformationLength;
476  }
478  {
479  /* Get the exception code */
480  Status = _SEH2_GetExceptionCode();
481  }
482  _SEH2_END;
483 
484  /* Dereference the process */
485  ObDereferenceObject(Process);
486  break;
487 
488  /* Hard Error Processing Mode */
490 
491  if (ProcessInformationLength != sizeof(ULONG))
492  {
494  break;
495  }
496 
497  /* Set the return length*/
498  Length = sizeof(ULONG);
499 
500  /* Reference the process */
501  Status = ObReferenceObjectByHandle(ProcessHandle,
504  PreviousMode,
505  (PVOID*)&Process,
506  NULL);
507  if (!NT_SUCCESS(Status)) break;
508 
509  /* Enter SEH for writing back data */
510  _SEH2_TRY
511  {
512  /* Write the current processing mode */
513  *(PULONG)ProcessInformation = Process->
514  DefaultHardErrorProcessing;
515  }
517  {
518  /* Get the exception code */
519  Status = _SEH2_GetExceptionCode();
520  }
521  _SEH2_END;
522 
523  /* Dereference the process */
524  ObDereferenceObject(Process);
525  break;
526 
527  /* Priority Boosting status */
529 
530  if (ProcessInformationLength != sizeof(ULONG))
531  {
533  break;
534  }
535 
536  /* Set the return length */
537  Length = sizeof(ULONG);
538 
539  /* Reference the process */
540  Status = ObReferenceObjectByHandle(ProcessHandle,
543  PreviousMode,
544  (PVOID*)&Process,
545  NULL);
546  if (!NT_SUCCESS(Status)) break;
547 
548  /* Enter SEH for writing back data */
549  _SEH2_TRY
550  {
551  /* Return boost status */
552  *(PULONG)ProcessInformation = Process->Pcb.DisableBoost ?
553  TRUE : FALSE;
554  }
556  {
557  /* Get the exception code */
558  Status = _SEH2_GetExceptionCode();
559  }
560  _SEH2_END;
561 
562  /* Dereference the process */
563  ObDereferenceObject(Process);
564  break;
565 
566  /* DOS Device Map */
567  case ProcessDeviceMap:
568 
569  if (ProcessInformationLength != sizeof(PROCESS_DEVICEMAP_INFORMATION))
570  {
571  if (ProcessInformationLength == sizeof(PROCESS_DEVICEMAP_INFORMATION_EX))
572  {
573  DPRINT1("PROCESS_DEVICEMAP_INFORMATION_EX not supported!\n");
574  Status = STATUS_NOT_IMPLEMENTED;
575  }
576  else
577  {
579  }
580  break;
581  }
582 
583  /* Set the return length */
584  Length = sizeof(PROCESS_DEVICEMAP_INFORMATION);
585 
586  /* Reference the process */
587  Status = ObReferenceObjectByHandle(ProcessHandle,
590  PreviousMode,
591  (PVOID*)&Process,
592  NULL);
593  if (!NT_SUCCESS(Status)) break;
594 
595  /* Query the device map information */
596  ObQueryDeviceMapInformation(Process, &DeviceMap);
597 
598  /* Enter SEH for writing back data */
599  _SEH2_TRY
600  {
601  *(PPROCESS_DEVICEMAP_INFORMATION)ProcessInformation = DeviceMap;
602  }
604  {
605  /* Get the exception code */
606  Status = _SEH2_GetExceptionCode();
607  }
608  _SEH2_END;
609 
610  /* Dereference the process */
611  ObDereferenceObject(Process);
612  break;
613 
614  /* Priority class */
616 
617  if (ProcessInformationLength != sizeof(PROCESS_PRIORITY_CLASS))
618  {
620  break;
621  }
622 
623  /* Set the return length*/
624  Length = sizeof(PROCESS_PRIORITY_CLASS);
625 
626  /* Reference the process */
627  Status = ObReferenceObjectByHandle(ProcessHandle,
630  PreviousMode,
631  (PVOID*)&Process,
632  NULL);
633  if (!NT_SUCCESS(Status)) break;
634 
635  /* Enter SEH for writing back data */
636  _SEH2_TRY
637  {
638  /* Return current priority class */
639  PsPriorityClass->PriorityClass = Process->PriorityClass;
640  PsPriorityClass->Foreground = FALSE;
641  }
643  {
644  /* Get the exception code */
645  Status = _SEH2_GetExceptionCode();
646  }
647  _SEH2_END;
648 
649  /* Dereference the process */
650  ObDereferenceObject(Process);
651  break;
652 
654 
655  /* Reference the process */
656  Status = ObReferenceObjectByHandle(ProcessHandle,
659  PreviousMode,
660  (PVOID*)&Process,
661  NULL);
662  if (!NT_SUCCESS(Status)) break;
663 
664  /* Get the image path */
665  Status = SeLocateProcessImageName(Process, &ImageName);
666  if (NT_SUCCESS(Status))
667  {
668  /* Set return length */
669  Length = ImageName->MaximumLength +
670  sizeof(OBJECT_NAME_INFORMATION);
671 
672  /* Make sure it's large enough */
673  if (Length <= ProcessInformationLength)
674  {
675  /* Enter SEH to protect write */
676  _SEH2_TRY
677  {
678  /* Copy it */
679  RtlCopyMemory(ProcessInformation,
680  ImageName,
681  Length);
682 
683  /* Update pointer */
684  ((PUNICODE_STRING)ProcessInformation)->Buffer =
685  (PWSTR)((PUNICODE_STRING)ProcessInformation + 1);
686  }
688  {
689  /* Get the exception code */
690  Status = _SEH2_GetExceptionCode();
691  }
692  _SEH2_END;
693  }
694  else
695  {
696  /* Buffer too small */
698  }
699 
700  /* Free the image path */
701  ExFreePoolWithTag(ImageName, TAG_SEPA);
702  }
703  /* Dereference the process */
704  ObDereferenceObject(Process);
705  break;
706 
707  case ProcessDebugFlags:
708 
709  if (ProcessInformationLength != sizeof(ULONG))
710  {
712  break;
713  }
714 
715  /* Set the return length*/
716  Length = sizeof(ULONG);
717 
718  /* Reference the process */
719  Status = ObReferenceObjectByHandle(ProcessHandle,
722  PreviousMode,
723  (PVOID*)&Process,
724  NULL);
725  if (!NT_SUCCESS(Status)) break;
726 
727  /* Enter SEH for writing back data */
728  _SEH2_TRY
729  {
730  /* Return the debug flag state */
731  *(PULONG)ProcessInformation = Process->NoDebugInherit ? 0 : 1;
732  }
734  {
735  /* Get the exception code */
736  Status = _SEH2_GetExceptionCode();
737  }
738  _SEH2_END;
739 
740  /* Dereference the process */
741  ObDereferenceObject(Process);
742  break;
743 
745 
746  if (ProcessInformationLength != sizeof(ULONG))
747  {
749  break;
750  }
751 
752  /* Set the return length */
753  Length = sizeof(ULONG);
754 
755  /* Reference the process */
756  Status = ObReferenceObjectByHandle(ProcessHandle,
759  PreviousMode,
760  (PVOID*)&Process,
761  NULL);
762  if (!NT_SUCCESS(Status)) break;
763 
764  /* Enter SEH for writing back data */
765  _SEH2_TRY
766  {
767  /* Return the BreakOnTermination state */
768  *(PULONG)ProcessInformation = Process->BreakOnTermination;
769  }
771  {
772  /* Get the exception code */
773  Status = _SEH2_GetExceptionCode();
774  }
775  _SEH2_END;
776 
777  /* Dereference the process */
778  ObDereferenceObject(Process);
779  break;
780 
781  /* Per-process security cookie */
782  case ProcessCookie:
783 
784  /* Get the current process and cookie */
785  Process = PsGetCurrentProcess();
786  Cookie = Process->Cookie;
787  if (!Cookie)
788  {
789  LARGE_INTEGER SystemTime;
790  ULONG NewCookie;
791  PKPRCB Prcb;
792 
793  /* Generate a new cookie */
794  KeQuerySystemTime(&SystemTime);
795  Prcb = KeGetCurrentPrcb();
796  NewCookie = Prcb->KeSystemCalls ^ Prcb->InterruptTime ^
797  SystemTime.u.LowPart ^ SystemTime.u.HighPart;
798 
799  /* Set the new cookie or return the current one */
800  Cookie = InterlockedCompareExchange((LONG*)&Process->Cookie,
801  NewCookie,
802  Cookie);
803  if (!Cookie) Cookie = NewCookie;
804 
805  /* Set return length */
806  Length = sizeof(ULONG);
807  }
808 
809  /* Indicate success */
810  Status = STATUS_SUCCESS;
811 
812  /* Enter SEH to protect write */
813  _SEH2_TRY
814  {
815  /* Write back the cookie */
816  *(PULONG)ProcessInformation = Cookie;
817  }
819  {
820  /* Get the exception code */
821  Status = _SEH2_GetExceptionCode();
822  }
823  _SEH2_END;
824  break;
825 
827 
828  if (ProcessInformationLength != sizeof(SECTION_IMAGE_INFORMATION))
829  {
830  /* Break out */
832  break;
833  }
834 
835  /* Set the length required and validate it */
836  Length = sizeof(SECTION_IMAGE_INFORMATION);
837 
838  /* Enter SEH to protect write */
839  _SEH2_TRY
840  {
842  }
844  {
845  /* Get the exception code */
846  Status = _SEH2_GetExceptionCode();
847  }
848  _SEH2_END;
849 
850  /* Indicate success */
851  Status = STATUS_SUCCESS;
852  break;
853 
855 
856  if (ProcessInformationLength != sizeof(HANDLE))
857  {
859  break;
860  }
861 
862  /* Set the return length */
863  Length = sizeof(HANDLE);
864 
865  /* Reference the process */
866  Status = ObReferenceObjectByHandle(ProcessHandle,
869  PreviousMode,
870  (PVOID*)&Process,
871  NULL);
872  if (!NT_SUCCESS(Status)) break;
873 
874  /* Get the debug port */
875  Status = DbgkOpenProcessDebugPort(Process, PreviousMode, &DebugPort);
876 
877  /* Let go of the process */
878  ObDereferenceObject(Process);
879 
880  /* Protect write in SEH */
881  _SEH2_TRY
882  {
883  /* Return debug port's handle */
884  *(PHANDLE)ProcessInformation = DebugPort;
885  }
887  {
888  /* Get the exception code */
889  Status = _SEH2_GetExceptionCode();
890  }
891  _SEH2_END;
892  break;
893 
895  DPRINT1("Handle tracing Not implemented: %lx\n", ProcessInformationClass);
896  Status = STATUS_NOT_IMPLEMENTED;
897  break;
898 
900 
901  if (ProcessInformationLength != sizeof(ULONG))
902  {
904  break;
905  }
906 
907  /* Set the return length */
908  Length = sizeof(ULONG);
909 
910  /* Indicate success */
911  Status = STATUS_SUCCESS;
912 
913  /* Protect write in SEH */
914  _SEH2_TRY
915  {
916  /* Return FALSE -- we don't support this */
917  *(PULONG)ProcessInformation = FALSE;
918  }
920  {
921  /* Get the exception code */
922  Status = _SEH2_GetExceptionCode();
923  }
924  _SEH2_END;
925  break;
926 
928 
929  if (ProcessInformationLength != sizeof(ULONG))
930  {
932  break;
933  }
934 
935  /* Set the return length */
936  Length = sizeof(ULONG);
937 
938  /* Reference the process */
939  Status = ObReferenceObjectByHandle(ProcessHandle,
942  PreviousMode,
943  (PVOID*)&Process,
944  NULL);
945  if (!NT_SUCCESS(Status)) break;
946 
947  /* Protect write in SEH */
948  _SEH2_TRY
949  {
950  /* Return if the flag is set */
951  *(PULONG)ProcessInformation = (ULONG)Process->VdmAllowed;
952  }
954  {
955  /* Get the exception code */
956  Status = _SEH2_GetExceptionCode();
957  }
958  _SEH2_END;
959 
960  /* Dereference the process */
961  ObDereferenceObject(Process);
962  break;
963 
965 
966  if (ProcessInformationLength != sizeof(ULONG_PTR))
967  {
969  break;
970  }
971 
972  /* Set return length */
973  Length = sizeof(ULONG_PTR);
974 
975  /* Reference the process */
976  Status = ObReferenceObjectByHandle(ProcessHandle,
979  PreviousMode,
980  (PVOID*)&Process,
981  NULL);
982  if (!NT_SUCCESS(Status)) break;
983 
984  /* Make sure the process isn't dying */
986  {
987  /* Get the WOW64 process structure */
988 #ifdef _WIN64
989  Wow64 = (ULONG_PTR)Process->Wow64Process;
990 #else
991  Wow64 = 0;
992 #endif
993  /* Release the lock */
995  }
996 
997  /* Protect write with SEH */
998  _SEH2_TRY
999  {
1000  /* Return whether or not we have a debug port */
1001  *(PULONG_PTR)ProcessInformation = Wow64;
1002  }
1004  {
1005  /* Get exception code */
1006  Status = _SEH2_GetExceptionCode();
1007  }
1008  _SEH2_END;
1009 
1010  /* Dereference the process */
1011  ObDereferenceObject(Process);
1012  break;
1013 
1014  case ProcessExecuteFlags:
1015 
1016  if (ProcessInformationLength != sizeof(ULONG))
1017  {
1018  Status = STATUS_INFO_LENGTH_MISMATCH;
1019  break;
1020  }
1021 
1022  /* Set return length */
1023  Length = sizeof(ULONG);
1024 
1025  if (ProcessHandle != NtCurrentProcess())
1026  {
1027  return STATUS_INVALID_PARAMETER;
1028  }
1029 
1030  /* Get the options */
1031  Status = MmGetExecuteOptions(&ExecuteOptions);
1032  if (NT_SUCCESS(Status))
1033  {
1034  /* Protect write with SEH */
1035  _SEH2_TRY
1036  {
1037  /* Return them */
1038  *(PULONG)ProcessInformation = ExecuteOptions;
1039  }
1041  {
1042  /* Get exception code */
1043  Status = _SEH2_GetExceptionCode();
1044  }
1045  _SEH2_END;
1046  }
1047  break;
1048 
1049  case ProcessLdtInformation:
1050  DPRINT1("VDM/16-bit not implemented: %lx\n", ProcessInformationClass);
1051  Status = STATUS_NOT_IMPLEMENTED;
1052  break;
1053 
1055  DPRINT1("WS Watch Not implemented: %lx\n", ProcessInformationClass);
1056  Status = STATUS_NOT_IMPLEMENTED;
1057  break;
1058 
1060  DPRINT1("Pool limits Not implemented: %lx\n", ProcessInformationClass);
1061  Status = STATUS_NOT_IMPLEMENTED;
1062  break;
1063 
1064  /* Not supported by Server 2003 */
1065  default:
1066  DPRINT1("Unsupported info class: %lx\n", ProcessInformationClass);
1067  Status = STATUS_INVALID_INFO_CLASS;
1068  }
1069 
1070  /* Protect write with SEH */
1071  _SEH2_TRY
1072  {
1073  /* Check if caller wanted return length */
1074  if ((ReturnLength) && (Length)) *ReturnLength = Length;
1075  }
1077  {
1078  /* Get exception code */
1079  Status = _SEH2_GetExceptionCode();
1080  }
1081  _SEH2_END;
1082 
1083  return Status;
1084 }
1085 
1086 /*
1087  * @implemented
1088  */
1089 NTSTATUS
1090 NTAPI
1092  IN PROCESSINFOCLASS ProcessInformationClass,
1093  IN PVOID ProcessInformation,
1094  IN ULONG ProcessInformationLength)
1095 {
1098  ACCESS_MASK Access;
1099  NTSTATUS Status;
1100  HANDLE PortHandle = NULL;
1103  PROCESS_PRIORITY_CLASS PriorityClass = {0};
1104  PROCESS_FOREGROUND_BACKGROUND Foreground = {0};
1105  PVOID ExceptionPort;
1106  ULONG Break;
1107  KAFFINITY ValidAffinity, Affinity = 0;
1108  KPRIORITY BasePriority = 0;
1109  UCHAR MemoryPriority = 0;
1110  BOOLEAN DisableBoost = 0;
1111  ULONG DefaultHardErrorMode = 0;
1112  ULONG DebugFlags = 0, EnableFixup = 0, Boost = 0;
1113  ULONG NoExecute = 0, VdmPower = 0;
1115  PLIST_ENTRY Next;
1116  PETHREAD Thread;
1117  PAGED_CODE();
1118 
1119  /* Verify Information Class validity */
1120 #if 0
1121  Status = DefaultSetInfoBufferCheck(ProcessInformationClass,
1122  PsProcessInfoClass,
1123  RTL_NUMBER_OF(PsProcessInfoClass),
1124  ProcessInformation,
1125  ProcessInformationLength,
1126  PreviousMode);
1127  if (!NT_SUCCESS(Status)) return Status;
1128 #endif
1129 
1130  /* Check what class this is */
1131  Access = PROCESS_SET_INFORMATION;
1132  if (ProcessInformationClass == ProcessSessionInformation)
1133  {
1134  /* Setting the Session ID needs a special mask */
1135  Access |= PROCESS_SET_SESSIONID;
1136  }
1137  else if (ProcessInformationClass == ProcessExceptionPort)
1138  {
1139  /* Setting the exception port needs a special mask */
1140  Access |= PROCESS_SUSPEND_RESUME;
1141  }
1142 
1143  /* Reference the process */
1144  Status = ObReferenceObjectByHandle(ProcessHandle,
1145  Access,
1146  PsProcessType,
1147  PreviousMode,
1148  (PVOID*)&Process,
1149  NULL);
1150  if (!NT_SUCCESS(Status)) return Status;
1151 
1152  /* Check what kind of information class this is */
1153  switch (ProcessInformationClass)
1154  {
1156 
1157  /* Check buffer length */
1158  if (ProcessInformationLength != sizeof(HANDLE))
1159  {
1160  Status = STATUS_INFO_LENGTH_MISMATCH;
1161  break;
1162  }
1163 
1164  /* Use SEH for capture */
1165  _SEH2_TRY
1166  {
1167  /* Capture the boolean */
1168  VdmPower = *(PULONG)ProcessInformation;
1169  }
1171  {
1172  /* Get the exception code */
1173  Status = _SEH2_GetExceptionCode();
1174  _SEH2_YIELD(break);
1175  }
1176  _SEH2_END;
1177 
1178  /* Getting VDM powers requires the SeTcbPrivilege */
1179  if (!SeSinglePrivilegeCheck(SeTcbPrivilege, PreviousMode))
1180  {
1181  /* We don't hold the privilege, bail out */
1182  Status = STATUS_PRIVILEGE_NOT_HELD;
1183  DPRINT1("Need TCB privilege\n");
1184  break;
1185  }
1186 
1187  /* Set or clear the flag */
1188  if (VdmPower)
1189  {
1191  }
1192  else
1193  {
1195  }
1196  break;
1197 
1198  /* Error/Exception Port */
1199  case ProcessExceptionPort:
1200 
1201  /* Check buffer length */
1202  if (ProcessInformationLength != sizeof(HANDLE))
1203  {
1204  Status = STATUS_INFO_LENGTH_MISMATCH;
1205  break;
1206  }
1207 
1208  /* Use SEH for capture */
1209  _SEH2_TRY
1210  {
1211  /* Capture the handle */
1212  PortHandle = *(PHANDLE)ProcessInformation;
1213  }
1215  {
1216  /* Get the exception code */
1217  Status = _SEH2_GetExceptionCode();
1218  _SEH2_YIELD(break);
1219  }
1220  _SEH2_END;
1221 
1222  /* Setting the error port requires the SeTcbPrivilege */
1223  if (!SeSinglePrivilegeCheck(SeTcbPrivilege, PreviousMode))
1224  {
1225  /* We don't hold the privilege, bail out */
1226  Status = STATUS_PRIVILEGE_NOT_HELD;
1227  break;
1228  }
1229 
1230  /* Get the LPC Port */
1231  Status = ObReferenceObjectByHandle(PortHandle,
1232  0,
1234  PreviousMode,
1235  (PVOID)&ExceptionPort,
1236  NULL);
1237  if (!NT_SUCCESS(Status)) break;
1238 
1239  /* Change the pointer */
1240  if (InterlockedCompareExchangePointer(&Process->ExceptionPort,
1241  ExceptionPort,
1242  NULL))
1243  {
1244  /* We already had one, fail */
1245  ObDereferenceObject(ExceptionPort);
1246  Status = STATUS_PORT_ALREADY_SET;
1247  }
1248  break;
1249 
1250  /* Security Token */
1251  case ProcessAccessToken:
1252 
1253  /* Check buffer length */
1254  if (ProcessInformationLength != sizeof(PROCESS_ACCESS_TOKEN))
1255  {
1256  Status = STATUS_INFO_LENGTH_MISMATCH;
1257  break;
1258  }
1259 
1260  /* Use SEH for capture */
1261  _SEH2_TRY
1262  {
1263  /* Save the token handle */
1264  TokenHandle = ((PPROCESS_ACCESS_TOKEN)ProcessInformation)->
1265  Token;
1266  }
1268  {
1269  /* Get the exception code */
1270  Status = _SEH2_GetExceptionCode();
1271  _SEH2_YIELD(break);
1272  }
1273  _SEH2_END;
1274 
1275  /* Assign the actual token */
1276  Status = PspSetPrimaryToken(Process, TokenHandle, NULL);
1277  break;
1278 
1279  /* Hard error processing */
1281 
1282  /* Check buffer length */
1283  if (ProcessInformationLength != sizeof(ULONG))
1284  {
1285  Status = STATUS_INFO_LENGTH_MISMATCH;
1286  break;
1287  }
1288 
1289  /* Enter SEH for direct buffer read */
1290  _SEH2_TRY
1291  {
1292  DefaultHardErrorMode = *(PULONG)ProcessInformation;
1293  }
1295  {
1296  /* Get exception code */
1297  Status = _SEH2_GetExceptionCode();
1298  _SEH2_YIELD(break);
1299  }
1300  _SEH2_END;
1301 
1302  /* Set the mode */
1303  Process->DefaultHardErrorProcessing = DefaultHardErrorMode;
1304 
1305  /* Call Ke for the update */
1306  if (DefaultHardErrorMode & SEM_NOALIGNMENTFAULTEXCEPT)
1307  {
1308  KeSetAutoAlignmentProcess(&Process->Pcb, TRUE);
1309  }
1310  else
1311  {
1312  KeSetAutoAlignmentProcess(&Process->Pcb, FALSE);
1313  }
1314  Status = STATUS_SUCCESS;
1315  break;
1316 
1317  /* Session ID */
1319 
1320  /* Check buffer length */
1321  if (ProcessInformationLength != sizeof(PROCESS_SESSION_INFORMATION))
1322  {
1323  Status = STATUS_INFO_LENGTH_MISMATCH;
1324  break;
1325  }
1326 
1327  /* Enter SEH for capture */
1328  _SEH2_TRY
1329  {
1330  /* Capture the caller's buffer */
1331  SessionInfo = *(PPROCESS_SESSION_INFORMATION)ProcessInformation;
1332  }
1334  {
1335  /* Get the exception code */
1336  Status = _SEH2_GetExceptionCode();
1337  _SEH2_YIELD(break);
1338  }
1339  _SEH2_END;
1340 
1341  /* Setting the session id requires the SeTcbPrivilege */
1342  if (!SeSinglePrivilegeCheck(SeTcbPrivilege, PreviousMode))
1343  {
1344  /* We don't hold the privilege, bail out */
1345  Status = STATUS_PRIVILEGE_NOT_HELD;
1346  break;
1347  }
1348 
1349 #if 0 // OLD AND DEPRECATED CODE!!!!
1350 
1351  /* FIXME - update the session id for the process token */
1352  //Status = PsLockProcess(Process, FALSE);
1353  if (!NT_SUCCESS(Status)) break;
1354 
1355  /* Write the session ID in the EPROCESS */
1356  Process->Session = UlongToPtr(SessionInfo.SessionId); // HACK!!!
1357 
1358  /* Check if the process also has a PEB */
1359  if (Process->Peb)
1360  {
1361  /*
1362  * Attach to the process to make sure we're in the right
1363  * context to access the PEB structure
1364  */
1365  KeAttachProcess(&Process->Pcb);
1366 
1367  /* Enter SEH for write to user-mode PEB */
1368  _SEH2_TRY
1369  {
1370  /* Write the session ID */
1371  Process->Peb->SessionId = SessionInfo.SessionId;
1372  }
1374  {
1375  /* Get exception code */
1376  Status = _SEH2_GetExceptionCode();
1377  }
1378  _SEH2_END;
1379 
1380  /* Detach from the process */
1381  KeDetachProcess();
1382  }
1383 
1384  /* Unlock the process */
1385  //PsUnlockProcess(Process);
1386 
1387 #endif
1388 
1389  /*
1390  * Since we cannot change the session ID of the given
1391  * process anymore because it is set once and for all
1392  * at process creation time and because it is stored
1393  * inside the Process->Session structure managed by MM,
1394  * we fake changing it: we just return success if the
1395  * user-defined value is the same as the session ID of
1396  * the process, and otherwise we fail.
1397  */
1398  if (SessionInfo.SessionId == PsGetProcessSessionId(Process))
1399  {
1400  Status = STATUS_SUCCESS;
1401  }
1402  else
1403  {
1404  Status = STATUS_ACCESS_DENIED;
1405  }
1406 
1407  break;
1408 
1409  case ProcessPriorityClass:
1410 
1411  /* Check buffer length */
1412  if (ProcessInformationLength != sizeof(PROCESS_PRIORITY_CLASS))
1413  {
1414  Status = STATUS_INFO_LENGTH_MISMATCH;
1415  break;
1416  }
1417 
1418  /* Enter SEH for capture */
1419  _SEH2_TRY
1420  {
1421  /* Capture the caller's buffer */
1422  PriorityClass = *(PPROCESS_PRIORITY_CLASS)ProcessInformation;
1423  }
1425  {
1426  /* Return the exception code */
1427  Status = _SEH2_GetExceptionCode();
1428  _SEH2_YIELD(break);
1429  }
1430  _SEH2_END;
1431 
1432  /* Check for invalid PriorityClass value */
1434  {
1435  Status = STATUS_INVALID_PARAMETER;
1436  break;
1437  }
1438 
1439  if ((PriorityClass.PriorityClass != Process->PriorityClass) &&
1441  {
1442  /* Check the privilege */
1444  ProcessHandle,
1446  PreviousMode);
1447  if (!HasPrivilege)
1448  {
1449  ObDereferenceObject(Process);
1450  DPRINT1("Privilege to change priority to realtime lacking\n");
1452  }
1453  }
1454 
1455  /* Check if we have a job */
1456  if (Process->Job)
1457  {
1458  DPRINT1("Jobs not yet supported\n");
1459  }
1460 
1461  /* Set process priority class */
1462  Process->PriorityClass = PriorityClass.PriorityClass;
1463 
1464  /* Set process priority mode (foreground or background) */
1466  PriorityClass.Foreground ?
1469  Status = STATUS_SUCCESS;
1470  break;
1471 
1473 
1474  /* Check buffer length */
1475  if (ProcessInformationLength != sizeof(PROCESS_FOREGROUND_BACKGROUND))
1476  {
1477  Status = STATUS_INFO_LENGTH_MISMATCH;
1478  break;
1479  }
1480 
1481  /* Enter SEH for capture */
1482  _SEH2_TRY
1483  {
1484  /* Capture the caller's buffer */
1485  Foreground = *(PPROCESS_FOREGROUND_BACKGROUND)ProcessInformation;
1486  }
1488  {
1489  /* Return the exception code */
1490  Status = _SEH2_GetExceptionCode();
1491  _SEH2_YIELD(break);
1492  }
1493  _SEH2_END;
1494 
1495  /* Set process priority mode (foreground or background) */
1497  Foreground.Foreground ?
1499  PsProcessPriorityBackground);
1500  Status = STATUS_SUCCESS;
1501  break;
1502 
1503  case ProcessBasePriority:
1504 
1505  /* Validate input length */
1506  if (ProcessInformationLength != sizeof(KPRIORITY))
1507  {
1508  Status = STATUS_INFO_LENGTH_MISMATCH;
1509  break;
1510  }
1511 
1512  /* Enter SEH for direct buffer read */
1513  _SEH2_TRY
1514  {
1515  BasePriority = *(KPRIORITY*)ProcessInformation;
1516  }
1518  {
1519  /* Get exception code */
1520  Break = 0;
1521  Status = _SEH2_GetExceptionCode();
1522  _SEH2_YIELD(break);
1523  }
1524  _SEH2_END;
1525 
1526  /* Extract the memory priority out of there */
1527  if (BasePriority & 0x80000000)
1528  {
1529  MemoryPriority = MEMORY_PRIORITY_FOREGROUND;
1530  BasePriority &= ~0x80000000;
1531  }
1532  else
1533  {
1534  MemoryPriority = MEMORY_PRIORITY_BACKGROUND;
1535  }
1536 
1537  /* Validate the number */
1538  if ((BasePriority > HIGH_PRIORITY) || (BasePriority <= LOW_PRIORITY))
1539  {
1540  ObDereferenceObject(Process);
1541  return STATUS_INVALID_PARAMETER;
1542  }
1543 
1544  /* Check if the new base is higher */
1545  if (BasePriority > Process->Pcb.BasePriority)
1546  {
1548  ProcessHandle,
1550  PreviousMode);
1551  if (!HasPrivilege)
1552  {
1553  ObDereferenceObject(Process);
1554  DPRINT1("Privilege to change priority from %lx to %lx lacking\n", BasePriority, Process->Pcb.BasePriority);
1556  }
1557  }
1558 
1559  /* Call Ke */
1560  KeSetPriorityAndQuantumProcess(&Process->Pcb, BasePriority, 0);
1561 
1562  /* Now set the memory priority */
1563  MmSetMemoryPriorityProcess(Process, MemoryPriority);
1564  Status = STATUS_SUCCESS;
1565  break;
1566 
1567  case ProcessRaisePriority:
1568 
1569  /* Validate input length */
1570  if (ProcessInformationLength != sizeof(ULONG))
1571  {
1572  Status = STATUS_INFO_LENGTH_MISMATCH;
1573  break;
1574  }
1575 
1576  /* Enter SEH for direct buffer read */
1577  _SEH2_TRY
1578  {
1579  Boost = *(PULONG)ProcessInformation;
1580  }
1582  {
1583  /* Get exception code */
1584  Break = 0;
1585  Status = _SEH2_GetExceptionCode();
1586  _SEH2_YIELD(break);
1587  }
1588  _SEH2_END;
1589 
1590  /* Make sure the process isn't dying */
1592  {
1593  /* Lock it */
1596 
1597  /* Loop the threads */
1598  for (Next = Process->ThreadListHead.Flink;
1599  Next != &Process->ThreadListHead;
1600  Next = Next->Flink)
1601  {
1602  /* Call Ke for the thread */
1603  Thread = CONTAINING_RECORD(Next, ETHREAD, ThreadListEntry);
1604  KeBoostPriorityThread(&Thread->Tcb, Boost);
1605  }
1606 
1607  /* Release the lock and rundown */
1611 
1612  /* Set success code */
1613  Status = STATUS_SUCCESS;
1614  }
1615  else
1616  {
1617  /* Avoid race conditions */
1619  }
1620  break;
1621 
1623 
1624  /* Check buffer length */
1625  if (ProcessInformationLength != sizeof(ULONG))
1626  {
1627  Status = STATUS_INFO_LENGTH_MISMATCH;
1628  break;
1629  }
1630 
1631  /* Enter SEH for direct buffer read */
1632  _SEH2_TRY
1633  {
1634  Break = *(PULONG)ProcessInformation;
1635  }
1637  {
1638  /* Get exception code */
1639  Break = 0;
1640  Status = _SEH2_GetExceptionCode();
1641  _SEH2_YIELD(break);
1642  }
1643  _SEH2_END;
1644 
1645  /* Setting 'break on termination' requires the SeDebugPrivilege */
1646  if (!SeSinglePrivilegeCheck(SeDebugPrivilege, PreviousMode))
1647  {
1648  /* We don't hold the privilege, bail out */
1649  Status = STATUS_PRIVILEGE_NOT_HELD;
1650  break;
1651  }
1652 
1653  /* Set or clear the flag */
1654  if (Break)
1655  {
1657  }
1658  else
1659  {
1661  }
1662 
1663  break;
1664 
1665  case ProcessAffinityMask:
1666 
1667  /* Check buffer length */
1668  if (ProcessInformationLength != sizeof(KAFFINITY))
1669  {
1670  Status = STATUS_INFO_LENGTH_MISMATCH;
1671  break;
1672  }
1673 
1674  /* Enter SEH for direct buffer read */
1675  _SEH2_TRY
1676  {
1677  Affinity = *(PKAFFINITY)ProcessInformation;
1678  }
1680  {
1681  /* Get exception code */
1682  Break = 0;
1683  Status = _SEH2_GetExceptionCode();
1684  _SEH2_YIELD(break);
1685  }
1686  _SEH2_END;
1687 
1688  /* Make sure it's valid for the CPUs present */
1689  ValidAffinity = Affinity & KeActiveProcessors;
1690  if (!Affinity || (ValidAffinity != Affinity))
1691  {
1692  Status = STATUS_INVALID_PARAMETER;
1693  break;
1694  }
1695 
1696  /* Check if it's within job affinity limits */
1697  if (Process->Job)
1698  {
1699  /* Not yet implemented */
1700  UNIMPLEMENTED;
1701  Status = STATUS_NOT_IMPLEMENTED;
1702  break;
1703  }
1704 
1705  /* Make sure the process isn't dying */
1707  {
1708  /* Lock it */
1711 
1712  /* Call Ke to do the work */
1713  KeSetAffinityProcess(&Process->Pcb, ValidAffinity);
1714 
1715  /* Release the lock and rundown */
1719 
1720  /* Set success code */
1721  Status = STATUS_SUCCESS;
1722  }
1723  else
1724  {
1725  /* Avoid race conditions */
1727  }
1728  break;
1729 
1730  /* Priority Boosting status */
1731  case ProcessPriorityBoost:
1732 
1733  /* Validate input length */
1734  if (ProcessInformationLength != sizeof(ULONG))
1735  {
1736  Status = STATUS_INFO_LENGTH_MISMATCH;
1737  break;
1738  }
1739 
1740  /* Enter SEH for direct buffer read */
1741  _SEH2_TRY
1742  {
1743  DisableBoost = *(PBOOLEAN)ProcessInformation;
1744  }
1746  {
1747  /* Get exception code */
1748  Break = 0;
1749  Status = _SEH2_GetExceptionCode();
1750  _SEH2_YIELD(break);
1751  }
1752  _SEH2_END;
1753 
1754  /* Make sure the process isn't dying */
1756  {
1757  /* Lock it */
1760 
1761  /* Call Ke to do the work */
1762  KeSetDisableBoostProcess(&Process->Pcb, DisableBoost);
1763 
1764  /* Loop the threads too */
1765  for (Next = Process->ThreadListHead.Flink;
1766  Next != &Process->ThreadListHead;
1767  Next = Next->Flink)
1768  {
1769  /* Call Ke for the thread */
1770  Thread = CONTAINING_RECORD(Next, ETHREAD, ThreadListEntry);
1771  KeSetDisableBoostThread(&Thread->Tcb, DisableBoost);
1772  }
1773 
1774  /* Release the lock and rundown */
1778 
1779  /* Set success code */
1780  Status = STATUS_SUCCESS;
1781  }
1782  else
1783  {
1784  /* Avoid race conditions */
1786  }
1787  break;
1788 
1789  case ProcessDebugFlags:
1790 
1791  /* Check buffer length */
1792  if (ProcessInformationLength != sizeof(ULONG))
1793  {
1794  Status = STATUS_INFO_LENGTH_MISMATCH;
1795  break;
1796  }
1797 
1798  /* Enter SEH for direct buffer read */
1799  _SEH2_TRY
1800  {
1801  DebugFlags = *(PULONG)ProcessInformation;
1802  }
1804  {
1805  /* Get exception code */
1806  Status = _SEH2_GetExceptionCode();
1807  _SEH2_YIELD(break);
1808  }
1809  _SEH2_END;
1810 
1811  /* Set the mode */
1812  if (DebugFlags & ~1)
1813  {
1814  Status = STATUS_INVALID_PARAMETER;
1815  }
1816  else
1817  {
1818  if (DebugFlags & 1)
1819  {
1821  }
1822  else
1823  {
1825  }
1826  }
1827 
1828  /* Done */
1829  Status = STATUS_SUCCESS;
1830  break;
1831 
1833 
1834  /* Check buffer length */
1835  if (ProcessInformationLength != sizeof(ULONG))
1836  {
1837  Status = STATUS_INFO_LENGTH_MISMATCH;
1838  break;
1839  }
1840 
1841  /* Enter SEH for direct buffer read */
1842  _SEH2_TRY
1843  {
1844  EnableFixup = *(PULONG)ProcessInformation;
1845  }
1847  {
1848  /* Get exception code */
1849  Status = _SEH2_GetExceptionCode();
1850  _SEH2_YIELD(break);
1851  }
1852  _SEH2_END;
1853 
1854  /* Set the mode */
1855  if (EnableFixup)
1856  {
1858  }
1859  else
1860  {
1861  Process->DefaultHardErrorProcessing &= ~SEM_NOALIGNMENTFAULTEXCEPT;
1862  }
1863 
1864  /* Call Ke for the update */
1865  KeSetAutoAlignmentProcess(&Process->Pcb, FALSE);
1866  Status = STATUS_SUCCESS;
1867  break;
1868 
1869  case ProcessUserModeIOPL:
1870 
1871  /* Only TCB can do this */
1872  if (!SeSinglePrivilegeCheck(SeTcbPrivilege, PreviousMode))
1873  {
1874  /* We don't hold the privilege, bail out */
1875  DPRINT1("Need TCB to set IOPL\n");
1876  Status = STATUS_PRIVILEGE_NOT_HELD;
1877  break;
1878  }
1879 
1880  /* Only supported on x86 */
1881 #if defined (_X86_)
1882  Ke386SetIOPL();
1883 #else
1884  Status = STATUS_NOT_IMPLEMENTED;
1885 #endif
1886  /* Done */
1887  break;
1888 
1889  case ProcessExecuteFlags:
1890 
1891  /* Check buffer length */
1892  if (ProcessInformationLength != sizeof(ULONG))
1893  {
1894  Status = STATUS_INFO_LENGTH_MISMATCH;
1895  break;
1896  }
1897 
1898  if (ProcessHandle != NtCurrentProcess())
1899  {
1900  Status = STATUS_INVALID_PARAMETER;
1901  break;
1902  }
1903 
1904  /* Enter SEH for direct buffer read */
1905  _SEH2_TRY
1906  {
1907  NoExecute = *(PULONG)ProcessInformation;
1908  }
1910  {
1911  /* Get exception code */
1912  Status = _SEH2_GetExceptionCode();
1913  _SEH2_YIELD(break);
1914  }
1915  _SEH2_END;
1916 
1917  /* Call Mm for the update */
1918  Status = MmSetExecuteOptions(NoExecute);
1919  break;
1920 
1921  /* We currently don't implement any of these */
1922  case ProcessLdtInformation:
1923  case ProcessLdtSize:
1924  case ProcessIoPortHandlers:
1925  DPRINT1("VDM/16-bit Request not implemented: %lx\n", ProcessInformationClass);
1926  Status = STATUS_NOT_IMPLEMENTED;
1927  break;
1928 
1929  case ProcessQuotaLimits:
1930 
1931  Status = PspSetQuotaLimits(Process,
1932  1,
1933  ProcessInformation,
1934  ProcessInformationLength,
1935  PreviousMode);
1936  break;
1937 
1939  DPRINT1("WS watch not implemented\n");
1940  Status = STATUS_NOT_IMPLEMENTED;
1941  break;
1942 
1943  case ProcessDeviceMap:
1944  DPRINT1("Device map not implemented\n");
1945  Status = STATUS_NOT_IMPLEMENTED;
1946  break;
1947 
1948  case ProcessHandleTracing:
1949  DPRINT1("Handle tracing not implemented\n");
1950  Status = STATUS_NOT_IMPLEMENTED;
1951  break;
1952 
1953  /* Anything else is invalid */
1954  default:
1955  DPRINT1("Invalid Server 2003 Info Class: %lx\n", ProcessInformationClass);
1956  Status = STATUS_INVALID_INFO_CLASS;
1957  }
1958 
1959  /* Dereference and return status */
1960  ObDereferenceObject(Process);
1961  return Status;
1962 }
1963 
1964 /*
1965  * @implemented
1966  */
1967 NTSTATUS
1968 NTAPI
1971  IN PVOID ThreadInformation,
1973 {
1974  PETHREAD Thread;
1975  ULONG Access;
1977  NTSTATUS Status;
1979  KPRIORITY Priority = 0;
1980  KAFFINITY Affinity = 0, CombinedAffinity;
1981  PVOID Address = NULL;
1983  ULONG_PTR DisableBoost = 0;
1984  ULONG_PTR IdealProcessor = 0;
1985  ULONG_PTR Break = 0;
1986  PTEB Teb;
1987  ULONG_PTR TlsIndex = 0;
1988  PVOID *ExpansionSlots;
1989  PETHREAD ProcThread;
1990  PAGED_CODE();
1991 
1992  /* Verify Information Class validity */
1993 #if 0
1994  Status = DefaultSetInfoBufferCheck(ThreadInformationClass,
1995  PsThreadInfoClass,
1996  RTL_NUMBER_OF(PsThreadInfoClass),
1997  ThreadInformation,
1998  ThreadInformationLength,
1999  PreviousMode);
2000  if (!NT_SUCCESS(Status)) return Status;
2001 #endif
2002 
2003  /* Check what class this is */
2004  Access = THREAD_SET_INFORMATION;
2005  if (ThreadInformationClass == ThreadImpersonationToken)
2006  {
2007  /* Setting the impersonation token needs a special mask */
2008  Access = THREAD_SET_THREAD_TOKEN;
2009  }
2010 
2011  /* Reference the thread */
2012  Status = ObReferenceObjectByHandle(ThreadHandle,
2013  Access,
2014  PsThreadType,
2015  PreviousMode,
2016  (PVOID*)&Thread,
2017  NULL);
2018  if (!NT_SUCCESS(Status)) return Status;
2019 
2020  /* Check what kind of information class this is */
2021  switch (ThreadInformationClass)
2022  {
2023  /* Thread priority */
2024  case ThreadPriority:
2025 
2026  /* Check buffer length */
2027  if (ThreadInformationLength != sizeof(KPRIORITY))
2028  {
2029  Status = STATUS_INFO_LENGTH_MISMATCH;
2030  break;
2031  }
2032 
2033  /* Use SEH for capture */
2034  _SEH2_TRY
2035  {
2036  /* Get the priority */
2037  Priority = *(PLONG)ThreadInformation;
2038  }
2040  {
2041  /* Get the exception code */
2042  Status = _SEH2_GetExceptionCode();
2043  _SEH2_YIELD(break);
2044  }
2045  _SEH2_END;
2046 
2047  /* Validate it */
2048  if ((Priority > HIGH_PRIORITY) ||
2049  (Priority <= LOW_PRIORITY))
2050  {
2051  /* Fail */
2052  Status = STATUS_INVALID_PARAMETER;
2053  break;
2054  }
2055 
2056  /* Set the priority */
2057  KeSetPriorityThread(&Thread->Tcb, Priority);
2058  break;
2059 
2060  case ThreadBasePriority:
2061 
2062  /* Check buffer length */
2063  if (ThreadInformationLength != sizeof(LONG))
2064  {
2065  Status = STATUS_INFO_LENGTH_MISMATCH;
2066  break;
2067  }
2068 
2069  /* Use SEH for capture */
2070  _SEH2_TRY
2071  {
2072  /* Get the priority */
2073  Priority = *(PLONG)ThreadInformation;
2074  }
2076  {
2077  /* Get the exception code */
2078  Status = _SEH2_GetExceptionCode();
2079  _SEH2_YIELD(break);
2080  }
2081  _SEH2_END;
2082 
2083  /* Validate it */
2084  if ((Priority > THREAD_BASE_PRIORITY_MAX) ||
2085  (Priority < THREAD_BASE_PRIORITY_MIN))
2086  {
2087  /* These ones are OK */
2088  if ((Priority != THREAD_BASE_PRIORITY_LOWRT + 1) &&
2089  (Priority != THREAD_BASE_PRIORITY_IDLE - 1))
2090  {
2091  /* Check if the process is real time */
2092  if (PsGetCurrentProcess()->PriorityClass !=
2094  {
2095  /* It isn't, fail */
2096  Status = STATUS_INVALID_PARAMETER;
2097  break;
2098  }
2099  }
2100  }
2101 
2102  /* Set the base priority */
2103  KeSetBasePriorityThread(&Thread->Tcb, Priority);
2104  break;
2105 
2106  case ThreadAffinityMask:
2107 
2108  /* Check buffer length */
2109  if (ThreadInformationLength != sizeof(ULONG_PTR))
2110  {
2111  Status = STATUS_INFO_LENGTH_MISMATCH;
2112  break;
2113  }
2114 
2115  /* Use SEH for capture */
2116  _SEH2_TRY
2117  {
2118  /* Get the priority */
2119  Affinity = *(PULONG_PTR)ThreadInformation;
2120  }
2122  {
2123  /* Get the exception code */
2124  Status = _SEH2_GetExceptionCode();
2125  _SEH2_YIELD(break);
2126  }
2127  _SEH2_END;
2128 
2129  /* Validate it */
2130  if (!Affinity)
2131  {
2132  /* Fail */
2133  Status = STATUS_INVALID_PARAMETER;
2134  break;
2135  }
2136 
2137  /* Get the process */
2138  Process = Thread->ThreadsProcess;
2139 
2140  /* Try to acquire rundown */
2142  {
2143  /* Lock it */
2146 
2147  /* Combine masks */
2148  CombinedAffinity = Affinity & Process->Pcb.Affinity;
2149  if (CombinedAffinity != Affinity)
2150  {
2151  /* Fail */
2152  Status = STATUS_INVALID_PARAMETER;
2153  }
2154  else
2155  {
2156  /* Set the affinity */
2157  KeSetAffinityThread(&Thread->Tcb, CombinedAffinity);
2158  }
2159 
2160  /* Release the lock and rundown */
2164  }
2165  else
2166  {
2167  /* Too late */
2169  }
2170 
2171  /* Return status */
2172  break;
2173 
2175 
2176  /* Check buffer length */
2177  if (ThreadInformationLength != sizeof(HANDLE))
2178  {
2179  Status = STATUS_INFO_LENGTH_MISMATCH;
2180  break;
2181  }
2182 
2183  /* Use SEH for capture */
2184  _SEH2_TRY
2185  {
2186  /* Save the token handle */
2187  TokenHandle = *(PHANDLE)ThreadInformation;
2188  }
2190  {
2191  /* Get the exception code */
2192  Status = _SEH2_GetExceptionCode();
2193  _SEH2_YIELD(break);
2194  }
2195  _SEH2_END;
2196 
2197  /* Assign the actual token */
2198  Status = PsAssignImpersonationToken(Thread, TokenHandle);
2199  break;
2200 
2202 
2203  /* Check buffer length */
2204  if (ThreadInformationLength != sizeof(ULONG_PTR))
2205  {
2206  Status = STATUS_INFO_LENGTH_MISMATCH;
2207  break;
2208  }
2209 
2210  /* Use SEH for capture */
2211  _SEH2_TRY
2212  {
2213  /* Get the priority */
2214  Address = *(PVOID*)ThreadInformation;
2215  }
2217  {
2218  /* Get the exception code */
2219  Status = _SEH2_GetExceptionCode();
2220  _SEH2_YIELD(break);
2221  }
2222  _SEH2_END;
2223 
2224  /* Set the address */
2225  Thread->Win32StartAddress = Address;
2226  break;
2227 
2228  case ThreadIdealProcessor:
2229 
2230  /* Check buffer length */
2231  if (ThreadInformationLength != sizeof(ULONG_PTR))
2232  {
2233  Status = STATUS_INFO_LENGTH_MISMATCH;
2234  break;
2235  }
2236 
2237  /* Use SEH for capture */
2238  _SEH2_TRY
2239  {
2240  /* Get the priority */
2241  IdealProcessor = *(PULONG_PTR)ThreadInformation;
2242  }
2244  {
2245  /* Get the exception code */
2246  Status = _SEH2_GetExceptionCode();
2247  _SEH2_YIELD(break);
2248  }
2249  _SEH2_END;
2250 
2251  /* Validate it */
2252  if (IdealProcessor > MAXIMUM_PROCESSORS)
2253  {
2254  /* Fail */
2255  Status = STATUS_INVALID_PARAMETER;
2256  break;
2257  }
2258 
2259  /* Set the ideal */
2260  Status = KeSetIdealProcessorThread(&Thread->Tcb,
2261  (CCHAR)IdealProcessor);
2262 
2263  /* Get the TEB and protect the thread */
2264  Teb = Thread->Tcb.Teb;
2265  if ((Teb) && (ExAcquireRundownProtection(&Thread->RundownProtect)))
2266  {
2267  /* Save the ideal processor */
2268  Teb->IdealProcessor = Thread->Tcb.IdealProcessor;
2269 
2270  /* Release rundown protection */
2272  }
2273 
2274  break;
2275 
2276  case ThreadPriorityBoost:
2277 
2278  /* Check buffer length */
2279  if (ThreadInformationLength != sizeof(ULONG_PTR))
2280  {
2281  Status = STATUS_INFO_LENGTH_MISMATCH;
2282  break;
2283  }
2284 
2285  /* Use SEH for capture */
2286  _SEH2_TRY
2287  {
2288  /* Get the priority */
2289  DisableBoost = *(PULONG_PTR)ThreadInformation;
2290  }
2292  {
2293  /* Get the exception code */
2294  Status = _SEH2_GetExceptionCode();
2295  _SEH2_YIELD(break);
2296  }
2297  _SEH2_END;
2298 
2299  /* Call the kernel */
2300  KeSetDisableBoostThread(&Thread->Tcb, (BOOLEAN)DisableBoost);
2301  break;
2302 
2303  case ThreadZeroTlsCell:
2304 
2305  /* Check buffer length */
2306  if (ThreadInformationLength != sizeof(ULONG_PTR))
2307  {
2308  Status = STATUS_INFO_LENGTH_MISMATCH;
2309  break;
2310  }
2311 
2312  /* Use SEH for capture */
2313  _SEH2_TRY
2314  {
2315  /* Get the priority */
2316  TlsIndex = *(PULONG_PTR)ThreadInformation;
2317  }
2319  {
2320  /* Get the exception code */
2321  Status = _SEH2_GetExceptionCode();
2322  _SEH2_YIELD(break);
2323  }
2324  _SEH2_END;
2325 
2326  /* This is only valid for the current thread */
2327  if (Thread != PsGetCurrentThread())
2328  {
2329  /* Fail */
2330  Status = STATUS_INVALID_PARAMETER;
2331  break;
2332  }
2333 
2334  /* Get the process */
2335  Process = Thread->ThreadsProcess;
2336 
2337  /* Loop the threads */
2338  ProcThread = PsGetNextProcessThread(Process, NULL);
2339  while (ProcThread)
2340  {
2341  /* Acquire rundown */
2342  if (ExAcquireRundownProtection(&ProcThread->RundownProtect))
2343  {
2344  /* Get the TEB */
2345  Teb = ProcThread->Tcb.Teb;
2346  if (Teb)
2347  {
2348  /* Check if we're in the expansion range */
2349  if (TlsIndex > TLS_MINIMUM_AVAILABLE - 1)
2350  {
2351  if (TlsIndex < (TLS_MINIMUM_AVAILABLE +
2352  TLS_EXPANSION_SLOTS) - 1)
2353  {
2354  /* Check if we have expansion slots */
2355  ExpansionSlots = Teb->TlsExpansionSlots;
2356  if (ExpansionSlots)
2357  {
2358  /* Clear the index */
2359  ExpansionSlots[TlsIndex - TLS_MINIMUM_AVAILABLE] = 0;
2360  }
2361  }
2362  }
2363  else
2364  {
2365  /* Clear the index */
2366  Teb->TlsSlots[TlsIndex] = NULL;
2367  }
2368  }
2369 
2370  /* Release rundown */
2372  }
2373 
2374  /* Go to the next thread */
2375  ProcThread = PsGetNextProcessThread(Process, ProcThread);
2376  }
2377 
2378  /* All done */
2379  break;
2380 
2382 
2383  /* Check buffer length */
2384  if (ThreadInformationLength != sizeof(ULONG))
2385  {
2386  Status = STATUS_INFO_LENGTH_MISMATCH;
2387  break;
2388  }
2389 
2390  /* Enter SEH for direct buffer read */
2391  _SEH2_TRY
2392  {
2393  Break = *(PULONG)ThreadInformation;
2394  }
2396  {
2397  /* Get exception code */
2398  Break = 0;
2399  Status = _SEH2_GetExceptionCode();
2400  _SEH2_YIELD(break);
2401  }
2402  _SEH2_END;
2403 
2404  /* Setting 'break on termination' requires the SeDebugPrivilege */
2405  if (!SeSinglePrivilegeCheck(SeDebugPrivilege, PreviousMode))
2406  {
2407  /* We don't hold the privilege, bail out */
2408  Status = STATUS_PRIVILEGE_NOT_HELD;
2409  break;
2410  }
2411 
2412  /* Set or clear the flag */
2413  if (Break)
2414  {
2416  }
2417  else
2418  {
2420  }
2421  break;
2422 
2424 
2425  /* Check buffer length */
2426  if (ThreadInformationLength != 0)
2427  {
2428  Status = STATUS_INFO_LENGTH_MISMATCH;
2429  break;
2430  }
2431 
2432  /* Set the flag */
2434  break;
2435 
2436  default:
2437  /* We don't implement it yet */
2438  DPRINT1("Not implemented: %d\n", ThreadInformationClass);
2439  Status = STATUS_NOT_IMPLEMENTED;
2440  }
2441 
2442  /* Dereference and return status */
2443  ObDereferenceObject(Thread);
2444  return Status;
2445 }
2446 
2447 /*
2448  * @implemented
2449  */
2450 NTSTATUS
2451 NTAPI
2454  OUT PVOID ThreadInformation,
2457 {
2458  PETHREAD Thread;
2460  NTSTATUS Status;
2461  ULONG Access;
2462  ULONG Length = 0;
2463  PTHREAD_BASIC_INFORMATION ThreadBasicInfo =
2464  (PTHREAD_BASIC_INFORMATION)ThreadInformation;
2465  PKERNEL_USER_TIMES ThreadTime = (PKERNEL_USER_TIMES)ThreadInformation;
2466  KIRQL OldIrql;
2467  ULONG ThreadTerminated;
2468  PAGED_CODE();
2469 
2470  /* Check if we were called from user mode */
2471  if (PreviousMode != KernelMode)
2472  {
2473  /* Enter SEH */
2474  _SEH2_TRY
2475  {
2476  /* Probe the buffer */
2477  ProbeForWrite(ThreadInformation,
2478  ThreadInformationLength,
2479  sizeof(ULONG));
2480 
2481  /* Probe the return length if required */
2483  }
2485  {
2486  /* Return the exception code */
2488  }
2489  _SEH2_END;
2490  }
2491 
2492  /* Check what class this is */
2493  Access = THREAD_QUERY_INFORMATION;
2494 
2495  /* Reference the process */
2496  Status = ObReferenceObjectByHandle(ThreadHandle,
2497  Access,
2498  PsThreadType,
2499  PreviousMode,
2500  (PVOID*)&Thread,
2501  NULL);
2502  if (!NT_SUCCESS(Status)) return Status;
2503 
2504  /* Check what kind of information class this is */
2505  switch (ThreadInformationClass)
2506  {
2507  /* Basic thread information */
2509 
2510  /* Set return length */
2511  Length = sizeof(THREAD_BASIC_INFORMATION);
2512 
2513  if (ThreadInformationLength != Length)
2514  {
2515  Status = STATUS_INFO_LENGTH_MISMATCH;
2516  break;
2517  }
2518  /* Protect writes with SEH */
2519  _SEH2_TRY
2520  {
2521  /* Write all the information from the ETHREAD/KTHREAD */
2522  ThreadBasicInfo->ExitStatus = Thread->ExitStatus;
2523  ThreadBasicInfo->TebBaseAddress = (PVOID)Thread->Tcb.Teb;
2524  ThreadBasicInfo->ClientId = Thread->Cid;
2525  ThreadBasicInfo->AffinityMask = Thread->Tcb.Affinity;
2526  ThreadBasicInfo->Priority = Thread->Tcb.Priority;
2527  ThreadBasicInfo->BasePriority = KeQueryBasePriorityThread(&Thread->Tcb);
2528  }
2530  {
2531  /* Get exception code */
2532  Status = _SEH2_GetExceptionCode();
2533  }
2534  _SEH2_END;
2535  break;
2536 
2537  /* Thread time information */
2538  case ThreadTimes:
2539 
2540  /* Set the return length */
2541  Length = sizeof(KERNEL_USER_TIMES);
2542 
2543  if (ThreadInformationLength != Length)
2544  {
2545  Status = STATUS_INFO_LENGTH_MISMATCH;
2546  break;
2547  }
2548  /* Protect writes with SEH */
2549  _SEH2_TRY
2550  {
2551  /* Copy time information from ETHREAD/KTHREAD */
2552  ThreadTime->KernelTime.QuadPart = Thread->Tcb.KernelTime * KeMaximumIncrement;
2553  ThreadTime->UserTime.QuadPart = Thread->Tcb.UserTime * KeMaximumIncrement;
2554  ThreadTime->CreateTime = Thread->CreateTime;
2555 
2556  /* Exit time is in a union and only valid on actual exit! */
2557  if (KeReadStateThread(&Thread->Tcb))
2558  {
2559  ThreadTime->ExitTime = Thread->ExitTime;
2560  }
2561  else
2562  {
2563  ThreadTime->ExitTime.QuadPart = 0;
2564  }
2565  }
2567  {
2568  /* Get exception code */
2569  Status = _SEH2_GetExceptionCode();
2570  }
2571  _SEH2_END;
2572  break;
2573 
2575 
2576  /* Set the return length*/
2577  Length = sizeof(PVOID);
2578 
2579  if (ThreadInformationLength != Length)
2580  {
2581  Status = STATUS_INFO_LENGTH_MISMATCH;
2582  break;
2583  }
2584  /* Protect write with SEH */
2585  _SEH2_TRY
2586  {
2587  /* Return the Win32 Start Address */
2588  *(PVOID*)ThreadInformation = Thread->Win32StartAddress;
2589  }
2591  {
2592  /* Get exception code */
2593  Status = _SEH2_GetExceptionCode();
2594  }
2595  _SEH2_END;
2596  break;
2597 
2599 
2600  /* Set the return length*/
2601  Length = sizeof(LARGE_INTEGER);
2602 
2603  if (ThreadInformationLength != Length)
2604  {
2605  Status = STATUS_INFO_LENGTH_MISMATCH;
2606  break;
2607  }
2608  /* Protect write with SEH */
2609  _SEH2_TRY
2610  {
2611  /* FIXME */
2612  (*(PLARGE_INTEGER)ThreadInformation).QuadPart = 0;
2613  }
2615  {
2616  /* Get exception code */
2617  Status = _SEH2_GetExceptionCode();
2618  }
2619  _SEH2_END;
2620  break;
2621 
2622  case ThreadAmILastThread:
2623 
2624  /* Set the return length*/
2625  Length = sizeof(ULONG);
2626 
2627  if (ThreadInformationLength != Length)
2628  {
2629  Status = STATUS_INFO_LENGTH_MISMATCH;
2630  break;
2631  }
2632  /* Protect write with SEH */
2633  _SEH2_TRY
2634  {
2635  /* Return whether or not we are the last thread */
2636  *(PULONG)ThreadInformation = ((Thread->ThreadsProcess->
2637  ThreadListHead.Flink->Flink ==
2638  &Thread->ThreadsProcess->
2639  ThreadListHead) ?
2640  TRUE : FALSE);
2641  }
2643  {
2644  /* Get exception code */
2645  Status = _SEH2_GetExceptionCode();
2646  }
2647  _SEH2_END;
2648  break;
2649 
2650  case ThreadIsIoPending:
2651 
2652  /* Set the return length*/
2653  Length = sizeof(ULONG);
2654 
2655  if (ThreadInformationLength != Length)
2656  {
2657  Status = STATUS_INFO_LENGTH_MISMATCH;
2658  break;
2659  }
2660  /* Raise the IRQL to protect the IRP list */
2661  KeRaiseIrql(APC_LEVEL, &OldIrql);
2662 
2663  /* Protect write with SEH */
2664  _SEH2_TRY
2665  {
2666  /* Check if the IRP list is empty or not */
2667  *(PULONG)ThreadInformation = !IsListEmpty(&Thread->IrpList);
2668  }
2670  {
2671  /* Get exception code */
2672  Status = _SEH2_GetExceptionCode();
2673  }
2674  _SEH2_END;
2675 
2676  /* Lower IRQL back */
2677  KeLowerIrql(OldIrql);
2678  break;
2679 
2680  /* LDT and GDT information */
2682 
2683 #if defined(_X86_)
2684  /* Call the worker routine */
2685  Status = PspQueryDescriptorThread(Thread,
2686  ThreadInformation,
2687  ThreadInformationLength,
2688  ReturnLength);
2689 #else
2690  /* Only implemented on x86 */
2691  Status = STATUS_NOT_IMPLEMENTED;
2692 #endif
2693  break;
2694 
2695  case ThreadPriorityBoost:
2696 
2697  /* Set the return length*/
2698  Length = sizeof(ULONG);
2699 
2700  if (ThreadInformationLength != Length)
2701  {
2702  Status = STATUS_INFO_LENGTH_MISMATCH;
2703  break;
2704  }
2705 
2706  _SEH2_TRY
2707  {
2708  *(PULONG)ThreadInformation = Thread->Tcb.DisableBoost ? 1 : 0;
2709  }
2711  {
2712  Status = _SEH2_GetExceptionCode();
2713  }
2714  _SEH2_END;
2715  break;
2716 
2717  case ThreadIsTerminated:
2718 
2719  /* Set the return length*/
2720  Length = sizeof(ThreadTerminated);
2721 
2722  if (ThreadInformationLength != Length)
2723  {
2724  Status = STATUS_INFO_LENGTH_MISMATCH;
2725  break;
2726  }
2727 
2728  ThreadTerminated = PsIsThreadTerminating(Thread);
2729 
2730  _SEH2_TRY
2731  {
2732  *(PULONG)ThreadInformation = ThreadTerminated ? 1 : 0;
2733  }
2735  {
2736  Status = _SEH2_GetExceptionCode();
2737  }
2738  _SEH2_END;
2739 
2740  break;
2741 
2742  /* Anything else */
2743  default:
2744 
2745  /* Not yet implemented */
2746  DPRINT1("Not implemented: %lx\n", ThreadInformationClass);
2747  Status = STATUS_NOT_IMPLEMENTED;
2748  }
2749 
2750  /* Protect write with SEH */
2751  _SEH2_TRY
2752  {
2753  /* Check if caller wanted return length */
2755  }
2757  {
2758  /* Get exception code */
2759  Status = _SEH2_GetExceptionCode();
2760  }
2761  _SEH2_END;
2762 
2763  /* Dereference the thread, and return */
2764  ObDereferenceObject(Thread);
2765  return Status;
2766 }
2767 
2768 /* EOF */
#define ProbeForWriteUlong(Ptr)
Definition: probe.h:36
LARGE_INTEGER WriteOperationCount
Definition: pstypes.h:1278
LARGE_INTEGER TimeLimit
Definition: lsa.idl:292
#define KeQuerySystemTime(t)
Definition: env_spec_w32.h:570
DWORD *typedef PVOID
Definition: winlogon.h:52
struct _THREAD_BASIC_INFORMATION THREAD_BASIC_INFORMATION
#define MAXIMUM_PROCESSORS
Definition: rwlock.h:5
BOOLEAN NTAPI KeSetDisableBoostThread(IN OUT PKTHREAD Thread, IN BOOLEAN Disable)
Definition: thrdobj.c:95
#define LOW_PRIORITY
ULONG KeMaximumIncrement
Definition: clock.c:20
IN CINT OUT PVOID IN ULONG OUT PULONG ReturnLength
Definition: dumpinfo.c:39
PFILE_OBJECT NTAPI MmGetFileObjectForSection(IN PVOID Section)
Definition: section.c:1681
ULONGLONG OtherOperationCount
Definition: pstypes.h:85
SIZE_T PeakVirtualSize
Definition: winternl.h:1592
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
PVOID ULONG Address
Definition: oprghdlr.h:14
LARGE_INTEGER ReadOperationCount
Definition: pstypes.h:1277
LONG DisableBoost
Definition: ketypes.h:2005
#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:1602
#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
USHORT MaximumLength
Definition: env_spec_w32.h:370
const LUID SeDebugPrivilege
Definition: priv.c:41
#define SEM_NOALIGNMENTFAULTEXCEPT
Definition: rtltypes.h:71
ULONG BreakOnTermination
Definition: pstypes.h:1336
SIZE_T QuotaPeak[3]
Definition: pstypes.h:1201
NTKERNELAPI VOID FASTCALL ExReleaseRundownProtection(_Inout_ PEX_RUNDOWN_REF RunRef)
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
HANDLE InheritedFromUniqueProcessId
Definition: pstypes.h:1240
BOOLEAN NTAPI KeSetDisableBoostProcess(IN PKPROCESS Process, IN BOOLEAN Disable)
Definition: procobj.c:331
SIZE_T PeakVirtualSize
Definition: pstypes.h:1203
SCHAR BasePriority
Definition: ketypes.h:2011
#define TLS_EXPANSION_SLOTS
Definition: pstypes.h:294
return STATUS_SUCCESS
Definition: btrfs.c:2690
SIZE_T QuotaPagedPoolUsage
Definition: winternl.h:1598
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
struct _PROCESS_DEVICEMAP_INFORMATION PROCESS_DEVICEMAP_INFORMATION
struct _PROCESS_ACCESS_TOKEN * PPROCESS_ACCESS_TOKEN
LARGE_INTEGER UserTime
Definition: winternl.h:1050
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:1054
_In_ KPRIORITY Priority
Definition: kefuncs.h:516
#define ExAcquireRundownProtection
Definition: ex.h:130
PVOID *typedef PWSTR
Definition: winlogon.h:57
SCHAR Priority
Definition: ketypes.h:1672
VOID NTAPI Ke386SetIOPL(VOID)
Definition: v86vdm.c:578
ULONGLONG WriteOperationCount
Definition: pstypes.h:84
SIZE_T PagefileUsage
Definition: winternl.h:1601
SIZE_T QuotaPeakPagedPoolUsage
Definition: winternl.h:1597
#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:2740
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:1593
ULONG MinimumWorkingSetSize
Definition: mmtypes.h:915
struct _EJOB * Job
Definition: pstypes.h:1234
#define PROCESS_SUSPEND_RESUME
Definition: pstypes.h:159
ULONG Cookie
Definition: pstypes.h:1385
struct _LARGE_INTEGER::@2136 u
_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
SIZE_T QuotaUsage[3]
Definition: pstypes.h:1200
KPRIORITY BasePriority
Definition: compat.h:581
_SEH2_TRY
Definition: create.c:4250
SIZE_T QuotaPeakNonPagedPoolUsage
Definition: winternl.h:1599
uint32_t ULONG_PTR
Definition: typedefs.h:63
LARGE_INTEGER CreateTime
Definition: pstypes.h:1195
ULONG PspTraceLevel
Definition: query.c:18
EPROCESS_QUOTA_ENTRY QuotaEntry[3]
Definition: pstypes.h:977
NTSTATUS ExitStatus
Definition: pstypes.h:1368
LARGE_INTEGER ExitTime
Definition: winternl.h:1048
NTSTATUS NTAPI PspQueryDescriptorThread(IN PETHREAD Thread, IN PVOID ThreadInformation, IN ULONG ThreadInformationLength, OUT PULONG ReturnLength OPTIONAL)
Definition: psldt.c:43
UCHAR PriorityClass
Definition: pstypes.h:1383
NTSTATUS NTAPI PspSetQuotaLimits(_In_ PEPROCESS Process, _In_ ULONG Unused, _In_ PVOID QuotaLimits, _In_ ULONG QuotaLimitsLength, _In_ KPROCESSOR_MODE PreviousMode)
Definition: quota.c:294
UCHAR KIRQL
Definition: env_spec_w32.h:591
ULONG PageFaultCount
Definition: winternl.h:1594
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
#define FALSE
Definition: types.h:117
long LONG
Definition: pedump.c:60
EPROCESS_QUOTA_BLOCK PspDefaultQuotaBlock
Definition: quota.c:18
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:2500
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
struct _OBJECT_NAME_INFORMATION OBJECT_NAME_INFORMATION
SIZE_T QuotaNonPagedPoolUsage
Definition: winternl.h:1600
struct _PROCESS_BASIC_INFORMATION PROCESS_BASIC_INFORMATION
smooth NULL
Definition: ftsmooth.c:416
struct _PEB * Peb
Definition: pstypes.h:1275
LARGE_INTEGER OtherTransferCount
Definition: pstypes.h:1282
_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
ULONGLONG WriteTransferCount
Definition: pstypes.h:87
NTSTATUS NTAPI NtSetInformationThread(IN HANDLE ThreadHandle, IN THREADINFOCLASS ThreadInformationClass, IN PVOID ThreadInformation, IN ULONG ThreadInformationLength)
Definition: query.c:1969
LIST_ENTRY ThreadListHead
Definition: pstypes.h:1260
#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
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
PVOID Session
Definition: pstypes.h:1256
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
KAFFINITY Affinity
Definition: ketypes.h:1999
ULONG PageFaultCount
Definition: mmtypes.h:908
unsigned char BOOLEAN
_In_ KPROCESSOR_MODE PreviousMode
Definition: sefuncs.h:103
struct _PROCESS_SESSION_INFORMATION * PPROCESS_SESSION_INFORMATION
#define UlongToPtr(ul)
Definition: basetsd.h:98
#define THREAD_BASE_PRIORITY_LOWRT
Definition: pstypes.h:174
ULONG KernelTime
Definition: ketypes.h:1877
LONG NTSTATUS
Definition: precomp.h:26
#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
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:24
char CCHAR
Definition: typedefs.h:50
LARGE_INTEGER CreateTime
Definition: winternl.h:1047
#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
#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
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:1949
NTSTATUS NTAPI NtQueryInformationThread(IN HANDLE ThreadHandle, IN THREADINFOCLASS ThreadInformationClass, OUT PVOID ThreadInformation, IN ULONG ThreadInformationLength, OUT PULONG ReturnLength OPTIONAL)
Definition: query.c:2452
struct _SECTION_IMAGE_INFORMATION SECTION_IMAGE_INFORMATION
LARGE_INTEGER WriteTransferCount
Definition: pstypes.h:1281
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
PETHREAD NTAPI PsGetNextProcessThread(IN PEPROCESS Process, IN PETHREAD Thread OPTIONAL)
Definition: process.c:75
ULONG VdmAllowed
Definition: pstypes.h:1351
PEPROCESS_QUOTA_BLOCK QuotaBlock
Definition: pstypes.h:1237
VOID NTAPI KeDetachProcess(VOID)
Definition: procobj.c:566
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:2542
#define STATUS_INVALID_INFO_CLASS
Definition: ntstatus.h:226
ULONGLONG ReadTransferCount
Definition: pstypes.h:86
VOID UINTN Length
Definition: acefiex.h:744
_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:411
#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:480
KPRIORITY NTAPI KeSetPriorityAndQuantumProcess(IN PKPROCESS Process, IN KPRIORITY Priority, IN UCHAR Quantum OPTIONAL)
Definition: procobj.c:349
EX_RUNDOWN_REF RundownProtect
Definition: pstypes.h:1197
Definition: typedefs.h:117
KPROCESS Pcb
Definition: pstypes.h:1193
struct _KERNEL_USER_TIMES KERNEL_USER_TIMES
#define TlsIndex
Definition: ws2_32p.h:267
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:128
MMSUPPORT Vm
Definition: pstypes.h:1287
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:1049
ULONG PeakWorkingSetSize
Definition: mmtypes.h:909
ULONG_PTR SIZE_T
Definition: typedefs.h:78
SIZE_T WorkingSetSize
Definition: winternl.h:1596
Definition: compat.h:484
DWORD *typedef HANDLE
Definition: winlogon.h:52
_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:1091
enum _THREADINFOCLASS THREADINFOCLASS
Definition: thread.c:106
struct _PROCESS_SESSION_INFORMATION PROCESS_SESSION_INFORMATION
PVOID DebugPort
Definition: pstypes.h:1206
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:527
ULONG NTAPI KeQueryRuntimeProcess(IN PKPROCESS Process, OUT PULONG UserTime)
Definition: procobj.c:805
NTSTATUS NTAPI MmSetMemoryPriorityProcess(IN PEPROCESS Process, IN UCHAR MemoryPriority)
Definition: procsup.c:471
SIZE_T Limit
Definition: pstypes.h:970
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
ULONG DefaultHardErrorProcessing
Definition: pstypes.h:1273
#define DPRINT1
Definition: precomp.h:8
ULONG UserTime
Definition: ketypes.h:1893
ULONG NoDebugInherit
Definition: pstypes.h:1325
LARGE_INTEGER OtherOperationCount
Definition: pstypes.h:1279
LARGE_INTEGER ReadTransferCount
Definition: pstypes.h:1280
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:219
#define PROCESS_SET_SESSIONID
Definition: pstypes.h:151
#define OUT
Definition: typedefs.h:39
#define ObReferenceObject
Definition: obfuncs.h:204
FORCEINLINE VOID ExReleasePushLockShared(PEX_PUSH_LOCK PushLock)
Definition: ex.h:1157
#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
EX_PUSH_LOCK ProcessLock
Definition: pstypes.h:1194
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:6
#define TAG_SEPA
Definition: tag.h:189
SIZE_T PeakWorkingSetSize
Definition: winternl.h:1595
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:12
ULONGLONG OtherTransferCount
Definition: pstypes.h:88
UCHAR NTAPI KeSetIdealProcessorThread(IN PKTHREAD Thread, IN UCHAR Processor)
Definition: thrdobj.c:1075
ULONG MaximumWorkingSetSize
Definition: mmtypes.h:916
LARGE_INTEGER ExitTime
Definition: pstypes.h:1196
BOOLEAN NTAPI PsIsThreadTerminating(IN PETHREAD Thread)
Definition: thread.c:868
_In_ HANDLE ProcessHandle
Definition: mmfuncs.h:403
SIZE_T VirtualSize
Definition: pstypes.h:1204
ULONG WorkingSetSize
Definition: mmtypes.h:931
signed int * PLONG
Definition: retypes.h:5
LARGE_INTEGER KernelTime
Definition: winternl.h:1049
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
IN HDEVINFO IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL
Definition: devinst.c:44
ULONG ACCESS_MASK
Definition: nt_native.h:40
union _LARGE_INTEGER * PLARGE_INTEGER
Definition: file.c:85
LONGLONG QuadPart
Definition: typedefs.h:112
ULONGLONG ReadOperationCount
Definition: pstypes.h:83
#define TLS_MINIMUM_AVAILABLE
Definition: ntddk_ex.h:240
struct _IO_COUNTERS * PIO_COUNTERS
#define STATUS_PORT_ALREADY_SET
Definition: ntstatus.h:294