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