ReactOS 0.4.16-dev-2610-ge2c92c0
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
27{
28 PSECTION Section;
29 PAGED_CODE();
30
31 /* Lock the process */
32 if (!ExAcquireRundownProtection(&Process->RundownProtect))
33 {
35 }
36
37 /* Get the section */
38 Section = Process->SectionObject;
39 if (Section)
40 {
41 /* Get the file object and reference it */
44 }
45
46 /* Release the protection */
47 ExReleaseRundownProtection(&Process->RundownProtect);
48
49 /* Return status */
50 return Section ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL;
51}
52
53#if DBG
54static
56PspDumpProcessInfoClassName(
57 _In_ PROCESSINFOCLASS ProcessInformationClass)
58{
59 static CHAR UnknownClassName[11];
60
61#define DBG_PROCESS_INFO_CLASS(InfoClass) [InfoClass] = #InfoClass
62 static const PCSTR ProcessInfoClasses[] =
63 {
64 DBG_PROCESS_INFO_CLASS(ProcessBasicInformation),
65 DBG_PROCESS_INFO_CLASS(ProcessQuotaLimits),
66 DBG_PROCESS_INFO_CLASS(ProcessVmCounters),
67 DBG_PROCESS_INFO_CLASS(ProcessTimes),
68 DBG_PROCESS_INFO_CLASS(ProcessBasePriority),
69 DBG_PROCESS_INFO_CLASS(ProcessRaisePriority),
70 DBG_PROCESS_INFO_CLASS(ProcessDebugPort),
71 DBG_PROCESS_INFO_CLASS(ProcessExceptionPort),
72 DBG_PROCESS_INFO_CLASS(ProcessAccessToken),
73 DBG_PROCESS_INFO_CLASS(ProcessLdtInformation),
74 DBG_PROCESS_INFO_CLASS(ProcessLdtSize),
75 DBG_PROCESS_INFO_CLASS(ProcessDefaultHardErrorMode),
76 DBG_PROCESS_INFO_CLASS(ProcessIoPortHandlers),
77 DBG_PROCESS_INFO_CLASS(ProcessPooledUsageAndLimits),
78 DBG_PROCESS_INFO_CLASS(ProcessWorkingSetWatch),
79 DBG_PROCESS_INFO_CLASS(ProcessUserModeIOPL),
80 DBG_PROCESS_INFO_CLASS(ProcessEnableAlignmentFaultFixup),
81 DBG_PROCESS_INFO_CLASS(ProcessPriorityClass),
82 DBG_PROCESS_INFO_CLASS(ProcessWx86Information),
83 DBG_PROCESS_INFO_CLASS(ProcessHandleCount),
84 DBG_PROCESS_INFO_CLASS(ProcessAffinityMask),
85 DBG_PROCESS_INFO_CLASS(ProcessPriorityBoost),
86 DBG_PROCESS_INFO_CLASS(ProcessDeviceMap),
87 DBG_PROCESS_INFO_CLASS(ProcessSessionInformation),
88 DBG_PROCESS_INFO_CLASS(ProcessForegroundInformation),
89 DBG_PROCESS_INFO_CLASS(ProcessWow64Information),
90 DBG_PROCESS_INFO_CLASS(ProcessImageFileName),
91 DBG_PROCESS_INFO_CLASS(ProcessLUIDDeviceMapsEnabled),
92 DBG_PROCESS_INFO_CLASS(ProcessBreakOnTermination),
93 DBG_PROCESS_INFO_CLASS(ProcessDebugObjectHandle),
94 DBG_PROCESS_INFO_CLASS(ProcessDebugFlags),
95 DBG_PROCESS_INFO_CLASS(ProcessHandleTracing),
96 DBG_PROCESS_INFO_CLASS(ProcessIoPriority),
97 DBG_PROCESS_INFO_CLASS(ProcessExecuteFlags),
98 DBG_PROCESS_INFO_CLASS(ProcessTlsInformation),
99 DBG_PROCESS_INFO_CLASS(ProcessCookie),
100 DBG_PROCESS_INFO_CLASS(ProcessImageInformation),
101 DBG_PROCESS_INFO_CLASS(ProcessCycleTime),
102 DBG_PROCESS_INFO_CLASS(ProcessPagePriority),
103 DBG_PROCESS_INFO_CLASS(ProcessInstrumentationCallback),
104 DBG_PROCESS_INFO_CLASS(ProcessThreadStackAllocation),
105 DBG_PROCESS_INFO_CLASS(ProcessWorkingSetWatchEx),
106 DBG_PROCESS_INFO_CLASS(ProcessImageFileNameWin32),
107 DBG_PROCESS_INFO_CLASS(ProcessImageFileMapping),
108 DBG_PROCESS_INFO_CLASS(ProcessAffinityUpdateMode),
109 DBG_PROCESS_INFO_CLASS(ProcessMemoryAllocationMode),
110 DBG_PROCESS_INFO_CLASS(ProcessGroupInformation),
111 DBG_PROCESS_INFO_CLASS(ProcessConsoleHostProcess),
112 DBG_PROCESS_INFO_CLASS(ProcessWindowInformation),
113 };
114#undef DBG_PROCESS_INFO_CLASS
115
116 if (ProcessInformationClass < RTL_NUMBER_OF(ProcessInfoClasses))
117 {
118 return ProcessInfoClasses[ProcessInformationClass];
119 }
120
121 sprintf(UnknownClassName, "%lu", ProcessInformationClass);
122 return UnknownClassName;
123}
124
125static
126PCSTR
127PspDumpThreadInfoClassName(
129{
130 static CHAR UnknownClassName[11];
131
132#define DBG_THREAD_INFO_CLASS(InfoClass) [InfoClass] = #InfoClass
133 static const PCSTR ThreadInfoClasses[] =
134 {
135 DBG_THREAD_INFO_CLASS(ThreadBasicInformation),
136 DBG_THREAD_INFO_CLASS(ThreadTimes),
137 DBG_THREAD_INFO_CLASS(ThreadPriority),
138 DBG_THREAD_INFO_CLASS(ThreadBasePriority),
139 DBG_THREAD_INFO_CLASS(ThreadAffinityMask),
140 DBG_THREAD_INFO_CLASS(ThreadImpersonationToken),
141 DBG_THREAD_INFO_CLASS(ThreadDescriptorTableEntry),
142 DBG_THREAD_INFO_CLASS(ThreadEnableAlignmentFaultFixup),
143 DBG_THREAD_INFO_CLASS(ThreadEventPair_Reusable),
144 DBG_THREAD_INFO_CLASS(ThreadQuerySetWin32StartAddress),
145 DBG_THREAD_INFO_CLASS(ThreadZeroTlsCell),
146 DBG_THREAD_INFO_CLASS(ThreadPerformanceCount),
147 DBG_THREAD_INFO_CLASS(ThreadAmILastThread),
148 DBG_THREAD_INFO_CLASS(ThreadIdealProcessor),
149 DBG_THREAD_INFO_CLASS(ThreadPriorityBoost),
150 DBG_THREAD_INFO_CLASS(ThreadSetTlsArrayAddress),
151 DBG_THREAD_INFO_CLASS(ThreadIsIoPending),
152 DBG_THREAD_INFO_CLASS(ThreadHideFromDebugger),
153 DBG_THREAD_INFO_CLASS(ThreadBreakOnTermination),
154 DBG_THREAD_INFO_CLASS(ThreadSwitchLegacyState),
155 DBG_THREAD_INFO_CLASS(ThreadIsTerminated),
156 DBG_THREAD_INFO_CLASS(ThreadLastSystemCall),
157 DBG_THREAD_INFO_CLASS(ThreadIoPriority),
158 DBG_THREAD_INFO_CLASS(ThreadCycleTime),
159 DBG_THREAD_INFO_CLASS(ThreadPagePriority),
160 DBG_THREAD_INFO_CLASS(ThreadActualBasePriority),
161 DBG_THREAD_INFO_CLASS(ThreadTebInformation),
162 DBG_THREAD_INFO_CLASS(ThreadCSwitchMon),
163 DBG_THREAD_INFO_CLASS(ThreadCSwitchPmu),
164 DBG_THREAD_INFO_CLASS(ThreadWow64Context),
165 DBG_THREAD_INFO_CLASS(ThreadGroupInformation),
166 DBG_THREAD_INFO_CLASS(ThreadUmsInformation),
167 DBG_THREAD_INFO_CLASS(ThreadCounterProfiling),
168 DBG_THREAD_INFO_CLASS(ThreadIdealProcessorEx),
169 DBG_THREAD_INFO_CLASS(ThreadCpuAccountingInformation),
170 DBG_THREAD_INFO_CLASS(ThreadSuspendCount),
171 DBG_THREAD_INFO_CLASS(ThreadHeterogeneousCpuPolicy),
172 DBG_THREAD_INFO_CLASS(ThreadContainerId),
173 DBG_THREAD_INFO_CLASS(ThreadNameInformation),
174 DBG_THREAD_INFO_CLASS(ThreadSelectedCpuSets),
175 DBG_THREAD_INFO_CLASS(ThreadSystemThreadInformation),
176 DBG_THREAD_INFO_CLASS(ThreadActualGroupAffinity),
177 DBG_THREAD_INFO_CLASS(ThreadDynamicCodePolicyInfo),
178 DBG_THREAD_INFO_CLASS(ThreadExplicitCaseSensitivity),
179 DBG_THREAD_INFO_CLASS(ThreadWorkOnBehalfTicket),
180 DBG_THREAD_INFO_CLASS(ThreadSubsystemInformation),
181 DBG_THREAD_INFO_CLASS(ThreadDbgkWerReportActive),
182 DBG_THREAD_INFO_CLASS(ThreadAttachContainer),
183 DBG_THREAD_INFO_CLASS(ThreadManageWritesToExecutableMemory),
184 DBG_THREAD_INFO_CLASS(ThreadPowerThrottlingState),
185 DBG_THREAD_INFO_CLASS(ThreadWorkloadClass),
186 DBG_THREAD_INFO_CLASS(ThreadCreateStateChange),
187 DBG_THREAD_INFO_CLASS(ThreadApplyStateChange),
188 DBG_THREAD_INFO_CLASS(ThreadStrongerBadHandleChecks),
189 DBG_THREAD_INFO_CLASS(ThreadEffectiveIoPriority),
190 DBG_THREAD_INFO_CLASS(ThreadEffectivePagePriority),
191 };
192#undef DBG_THREAD_INFO_CLASS
193
194 if (ThreadInformationClass < RTL_NUMBER_OF(ThreadInfoClasses))
195 {
196 return ThreadInfoClasses[ThreadInformationClass];
197 }
198
199 sprintf(UnknownClassName, "%lu", ThreadInformationClass);
200 return UnknownClassName;
201}
202#endif // #if DBG
203
204/* PUBLIC FUNCTIONS **********************************************************/
205
206/*
207 * @implemented
208 */
210NTAPI
213 _In_ PROCESSINFOCLASS ProcessInformationClass,
214 _Out_writes_bytes_to_opt_(ProcessInformationLength, *ReturnLength)
215 PVOID ProcessInformation,
216 _In_ ULONG ProcessInformationLength,
218{
222 ULONG Length = 0;
223
224 PAGED_CODE();
225
226 /* Validate the information class */
227 Status = DefaultQueryInfoBufferCheck(ProcessInformationClass,
231 ProcessInformation,
232 ProcessInformationLength,
234 NULL,
236 if (!NT_SUCCESS(Status))
237 {
238#if DBG
239 DPRINT1("NtQueryInformationProcess(ProcessInformationClass: %s): Class validation failed! (Status: 0x%lx)\n",
240 PspDumpProcessInfoClassName(ProcessInformationClass), Status);
241#endif
242 return Status;
243 }
244
245 if (((ProcessInformationClass == ProcessCookie) ||
246 (ProcessInformationClass == ProcessImageInformation)) &&
248 {
249 /*
250 * Retrieving the process cookie is only allowed for the calling process
251 * itself! XP only allows NtCurrentProcess() as process handles even if
252 * a real handle actually represents the current process.
253 */
255 }
256
257 /* Check the information class */
258 switch (ProcessInformationClass)
259 {
260 /* Basic process information */
262 {
263 PPROCESS_BASIC_INFORMATION ProcessBasicInfo = (PPROCESS_BASIC_INFORMATION)ProcessInformation;
264
265 if (ProcessInformationLength != sizeof(PROCESS_BASIC_INFORMATION))
266 {
268 break;
269 }
270
271 /* Set the return length */
273
274 /* Reference the process */
279 (PVOID*)&Process,
280 NULL);
281 if (!NT_SUCCESS(Status)) break;
282
283 /* Protect writes with SEH */
285 {
286 /* Write all the information from the EPROCESS/KPROCESS */
287 ProcessBasicInfo->ExitStatus = Process->ExitStatus;
288 ProcessBasicInfo->PebBaseAddress = Process->Peb;
289 ProcessBasicInfo->AffinityMask = Process->Pcb.Affinity;
290 ProcessBasicInfo->UniqueProcessId = (ULONG_PTR)Process->
291 UniqueProcessId;
292 ProcessBasicInfo->InheritedFromUniqueProcessId =
293 (ULONG_PTR)Process->InheritedFromUniqueProcessId;
294 ProcessBasicInfo->BasePriority = Process->Pcb.BasePriority;
295
296 }
298 {
299 /* Get exception code */
301 }
302 _SEH2_END;
303
304 /* Dereference the process */
306 break;
307 }
308
309 /* Process quota limits */
311 {
312 QUOTA_LIMITS_EX QuotaLimits;
313 BOOLEAN Extended;
314
315 if (ProcessInformationLength != sizeof(QUOTA_LIMITS) &&
316 ProcessInformationLength != sizeof(QUOTA_LIMITS_EX))
317 {
319 break;
320 }
321
322 /* Set the return length */
323 Length = ProcessInformationLength;
324 Extended = (Length == sizeof(QUOTA_LIMITS_EX));
325
326 /* Reference the process */
331 (PVOID*)&Process,
332 NULL);
333 if (!NT_SUCCESS(Status)) break;
334
335 /* Indicate success */
337
338 RtlZeroMemory(&QuotaLimits, sizeof(QuotaLimits));
339
340 /* Get max/min working set sizes */
341 QuotaLimits.MaximumWorkingSetSize =
342 Process->Vm.MaximumWorkingSetSize << PAGE_SHIFT;
343 QuotaLimits.MinimumWorkingSetSize =
344 Process->Vm.MinimumWorkingSetSize << PAGE_SHIFT;
345
346 /* Get default time limits */
347 QuotaLimits.TimeLimit.QuadPart = -1LL;
348
349 /* Is quota block a default one? */
350 if (Process->QuotaBlock == &PspDefaultQuotaBlock)
351 {
352 /* Get default pools and pagefile limits */
353 QuotaLimits.PagedPoolLimit = (SIZE_T)-1;
354 QuotaLimits.NonPagedPoolLimit = (SIZE_T)-1;
355 QuotaLimits.PagefileLimit = (SIZE_T)-1;
356 }
357 else
358 {
359 /* Get limits from non-default quota block */
360 QuotaLimits.PagedPoolLimit =
361 Process->QuotaBlock->QuotaEntry[PsPagedPool].Limit;
362 QuotaLimits.NonPagedPoolLimit =
363 Process->QuotaBlock->QuotaEntry[PsNonPagedPool].Limit;
364 QuotaLimits.PagefileLimit =
365 Process->QuotaBlock->QuotaEntry[PsPageFile].Limit;
366 }
367
368 /* Get additional information, if needed */
369 if (Extended)
370 {
371 QuotaLimits.Flags |= (Process->Vm.Flags.MaximumWorkingSetHard ?
373 QuotaLimits.Flags |= (Process->Vm.Flags.MinimumWorkingSetHard ?
375
376 /* FIXME: Get the correct information */
377 //QuotaLimits.WorkingSetLimit = (SIZE_T)-1; // Not used on Win2k3, it is set to 0
378 QuotaLimits.CpuRateLimit.RateData = 0;
379 }
380
381 /* Protect writes with SEH */
383 {
384 RtlCopyMemory(ProcessInformation, &QuotaLimits, Length);
385 }
387 {
388 /* Get exception code */
390 }
391 _SEH2_END;
392
393 /* Dereference the process */
395 break;
396 }
397
399 {
400 PIO_COUNTERS IoCounters = (PIO_COUNTERS)ProcessInformation;
401 PROCESS_VALUES ProcessValues;
402
403 if (ProcessInformationLength != sizeof(IO_COUNTERS))
404 {
406 break;
407 }
408
409 Length = sizeof(IO_COUNTERS);
410
411 /* Reference the process */
416 (PVOID*)&Process,
417 NULL);
418 if (!NT_SUCCESS(Status)) break;
419
420 /* Query IO counters from the process */
421 KeQueryValuesProcess(&Process->Pcb, &ProcessValues);
422
424 {
425 RtlCopyMemory(IoCounters, &ProcessValues.IoInfo, sizeof(IO_COUNTERS));
426 }
428 {
429 /* Ignore exception */
430 }
431 _SEH2_END;
432
433 /* Set status to success in any case */
435
436 /* Dereference the process */
438 break;
439 }
440
441 /* Timing */
442 case ProcessTimes:
443 {
444 PKERNEL_USER_TIMES ProcessTime = (PKERNEL_USER_TIMES)ProcessInformation;
445 ULONG UserTime, KernelTime;
446
447 /* Set the return length */
448 if (ProcessInformationLength != sizeof(KERNEL_USER_TIMES))
449 {
451 break;
452 }
453
454 Length = sizeof(KERNEL_USER_TIMES);
455
456 /* Reference the process */
461 (PVOID*)&Process,
462 NULL);
463 if (!NT_SUCCESS(Status)) break;
464
465 /* Protect writes with SEH */
467 {
468 /* Copy time information from EPROCESS/KPROCESS */
469 KernelTime = KeQueryRuntimeProcess(&Process->Pcb, &UserTime);
470 ProcessTime->CreateTime = Process->CreateTime;
472 ProcessTime->KernelTime.QuadPart = (LONGLONG)KernelTime * KeMaximumIncrement;
473 ProcessTime->ExitTime = Process->ExitTime;
474 }
476 {
477 /* Get exception code */
479 }
480 _SEH2_END;
481
482 /* Dereference the process */
484 break;
485 }
486
487 /* Process Debug Port */
488 case ProcessDebugPort:
489
490 if (ProcessInformationLength != sizeof(HANDLE))
491 {
493 break;
494 }
495
496 /* Set the return length */
497 Length = sizeof(HANDLE);
498
499 /* Reference the process */
504 (PVOID*)&Process,
505 NULL);
506 if (!NT_SUCCESS(Status)) break;
507
508 /* Protect write with SEH */
510 {
511 /* Return whether or not we have a debug port */
512 *(PHANDLE)ProcessInformation = (Process->DebugPort ?
513 (HANDLE)-1 : NULL);
514 }
516 {
517 /* Get exception code */
519 }
520 _SEH2_END;
521
522 /* Dereference the process */
524 break;
525
527 {
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 */
544 (PVOID*)&Process,
545 NULL);
546 if (!NT_SUCCESS(Status)) break;
547
548 /* Count the number of handles this process has */
550
551 /* Protect write in SEH */
553 {
554 /* Return the count of handles */
555 *(PULONG)ProcessInformation = HandleCount;
556 }
558 {
559 /* Get the exception code */
561 }
562 _SEH2_END;
563
564 /* Dereference the process */
566 break;
567 }
568
569 /* Session ID for the process */
571 {
573
574 if (ProcessInformationLength != sizeof(PROCESS_SESSION_INFORMATION))
575 {
577 break;
578 }
579
580 /* Set the return length*/
582
583 /* Reference the process */
588 (PVOID*)&Process,
589 NULL);
590 if (!NT_SUCCESS(Status)) break;
591
592 /* Enter SEH for write safety */
594 {
595 /* Write back the Session ID */
597 }
599 {
600 /* Get the exception code */
602 }
603 _SEH2_END;
604
605 /* Dereference the process */
607 break;
608 }
609
610 /* Virtual Memory Statistics */
612 {
613 PVM_COUNTERS VmCounters = (PVM_COUNTERS)ProcessInformation;
614
615 /* Validate the input length */
616 if ((ProcessInformationLength != sizeof(VM_COUNTERS)) &&
617 (ProcessInformationLength != sizeof(VM_COUNTERS_EX)))
618 {
620 break;
621 }
622
623 /* Reference the process */
628 (PVOID*)&Process,
629 NULL);
630 if (!NT_SUCCESS(Status)) break;
631
632 /* Enter SEH for write safety */
634 {
635 /* Return data from EPROCESS */
636 VmCounters->PeakVirtualSize = Process->PeakVirtualSize;
637 VmCounters->VirtualSize = Process->VirtualSize;
638 VmCounters->PageFaultCount = Process->Vm.PageFaultCount;
639 VmCounters->PeakWorkingSetSize = Process->Vm.PeakWorkingSetSize;
640 VmCounters->WorkingSetSize = Process->Vm.WorkingSetSize;
641 VmCounters->QuotaPeakPagedPoolUsage = Process->QuotaPeak[PsPagedPool];
642 VmCounters->QuotaPagedPoolUsage = Process->QuotaUsage[PsPagedPool];
643 VmCounters->QuotaPeakNonPagedPoolUsage = Process->QuotaPeak[PsNonPagedPool];
644 VmCounters->QuotaNonPagedPoolUsage = Process->QuotaUsage[PsNonPagedPool];
645 VmCounters->PagefileUsage = Process->QuotaUsage[PsPageFile] << PAGE_SHIFT;
646 VmCounters->PeakPagefileUsage = Process->QuotaPeak[PsPageFile] << PAGE_SHIFT;
647 //VmCounters->PrivateUsage = Process->CommitCharge << PAGE_SHIFT;
648 //
649
650 /* Set the return length */
651 Length = ProcessInformationLength;
652 }
654 {
655 /* Get the exception code */
657 }
658 _SEH2_END;
659
660 /* Dereference the process */
662 break;
663 }
664
665 /* Hard Error Processing Mode */
667
668 if (ProcessInformationLength != sizeof(ULONG))
669 {
671 break;
672 }
673
674 /* Set the return length*/
675 Length = sizeof(ULONG);
676
677 /* Reference the process */
682 (PVOID*)&Process,
683 NULL);
684 if (!NT_SUCCESS(Status)) break;
685
686 /* Enter SEH for writing back data */
688 {
689 /* Write the current processing mode */
690 *(PULONG)ProcessInformation = Process->
691 DefaultHardErrorProcessing;
692 }
694 {
695 /* Get the exception code */
697 }
698 _SEH2_END;
699
700 /* Dereference the process */
702 break;
703
704 /* Priority Boosting status */
706
707 if (ProcessInformationLength != sizeof(ULONG))
708 {
710 break;
711 }
712
713 /* Set the return length */
714 Length = sizeof(ULONG);
715
716 /* Reference the process */
721 (PVOID*)&Process,
722 NULL);
723 if (!NT_SUCCESS(Status)) break;
724
725 /* Enter SEH for writing back data */
727 {
728 /* Return boost status */
729 *(PULONG)ProcessInformation = Process->Pcb.DisableBoost ?
730 TRUE : FALSE;
731 }
733 {
734 /* Get the exception code */
736 }
737 _SEH2_END;
738
739 /* Dereference the process */
741 break;
742
743 /* DOS Device Map */
744 case ProcessDeviceMap:
745 {
746 ULONG Flags;
747
748 if (ProcessInformationLength == sizeof(PROCESS_DEVICEMAP_INFORMATION_EX))
749 {
750 /* Protect read in SEH */
752 {
753 PPROCESS_DEVICEMAP_INFORMATION_EX DeviceMapEx = ProcessInformation;
754
755 Flags = DeviceMapEx->Flags;
756 }
758 {
759 /* Get the exception code */
761 _SEH2_YIELD(break);
762 }
763 _SEH2_END;
764
765 /* Only one flag is supported and it needs LUID mappings */
766 if ((Flags & ~PROCESS_LUID_DOSDEVICES_ONLY) != 0 ||
768 {
770 break;
771 }
772 }
773 else
774 {
775 /* This has to be the size of the Query union field for x64 compatibility! */
776 if (ProcessInformationLength != RTL_FIELD_SIZE(PROCESS_DEVICEMAP_INFORMATION, Query))
777 {
779 break;
780 }
781
782 /* No flags for standard call */
783 Flags = 0;
784 }
785
786 /* Set the return length */
787 Length = ProcessInformationLength;
788
789 /* Reference the process */
794 (PVOID*)&Process,
795 NULL);
796 if (!NT_SUCCESS(Status)) break;
797
798 /* Query the device map information */
800 ProcessInformation,
801 Flags);
802
803 /* Dereference the process */
805 break;
806 }
807
808 /* Priority class */
810 {
811 PPROCESS_PRIORITY_CLASS PsPriorityClass = (PPROCESS_PRIORITY_CLASS)ProcessInformation;
812
813 if (ProcessInformationLength != sizeof(PROCESS_PRIORITY_CLASS))
814 {
816 break;
817 }
818
819 /* Set the return length*/
821
822 /* Reference the process */
827 (PVOID*)&Process,
828 NULL);
829 if (!NT_SUCCESS(Status)) break;
830
831 /* Enter SEH for writing back data */
833 {
834 /* Return current priority class */
835 PsPriorityClass->PriorityClass = Process->PriorityClass;
836 PsPriorityClass->Foreground = FALSE;
837 }
839 {
840 /* Get the exception code */
842 }
843 _SEH2_END;
844
845 /* Dereference the process */
847 break;
848 }
849
851 {
853
854 /* Reference the process */
859 (PVOID*)&Process,
860 NULL);
861 if (!NT_SUCCESS(Status)) break;
862
863 /* Get the image path */
865 if (NT_SUCCESS(Status))
866 {
867 /* Set the return length */
868 Length = ImageName->MaximumLength +
870
871 /* Make sure it's large enough */
872 if (Length <= ProcessInformationLength)
873 {
874 /* Enter SEH to protect write */
876 {
877 /* Copy it */
878 RtlCopyMemory(ProcessInformation,
879 ImageName,
880 Length);
881
882 /* Update pointer */
883 ((PUNICODE_STRING)ProcessInformation)->Buffer =
884 (PWSTR)((PUNICODE_STRING)ProcessInformation + 1);
885 }
887 {
888 /* Get the exception code */
890 }
891 _SEH2_END;
892 }
893 else
894 {
895 /* Buffer too small */
897 }
898
899 /* Free the image path */
901 }
902 /* Dereference the process */
904 break;
905 }
906
907#if (NTDDI_VERSION >= NTDDI_VISTA) || (DLL_EXPORT_VERSION >= _WIN32_WINNT_VISTA)
909 {
912
913 /* Reference the process */
915 // FIXME: Use PROCESS_QUERY_LIMITED_INFORMATION when implemented
919 (PVOID*)&Process,
920 NULL);
921 if (!NT_SUCCESS(Status))
922 {
923 break;
924 }
925
926 /* Get the image path */
929 if (!NT_SUCCESS(Status))
930 {
931 break;
932 }
935 if (!NT_SUCCESS(Status))
936 {
937 break;
938 }
939
940 /* Determine return length and output */
941 Length = sizeof(UNICODE_STRING) + ObjectNameInformation->Name.MaximumLength;
942 if (Length <= ProcessInformationLength)
943 {
945 {
946 PUNICODE_STRING ImageName = (PUNICODE_STRING)ProcessInformation;
947 ImageName->Length = ObjectNameInformation->Name.Length;
948 ImageName->MaximumLength = ObjectNameInformation->Name.MaximumLength;
949 if (ObjectNameInformation->Name.MaximumLength)
950 {
951 ImageName->Buffer = (PWSTR)(ImageName + 1);
952 RtlCopyMemory(ImageName->Buffer,
953 ObjectNameInformation->Name.Buffer,
954 ObjectNameInformation->Name.MaximumLength);
955 }
956 else
957 {
958 ASSERT(ImageName->Length == 0);
959 ImageName->Buffer = NULL;
960 }
961 }
963 {
965 }
966 _SEH2_END;
967 }
968 else
969 {
971 }
973
974 break;
975 }
976#endif /* (NTDDI_VERSION >= NTDDI_VISTA) || (DLL_EXPORT_VERSION >= _WIN32_WINNT_VISTA) */
977
979
980 if (ProcessInformationLength != sizeof(ULONG))
981 {
983 break;
984 }
985
986 /* Set the return length*/
987 Length = sizeof(ULONG);
988
989 /* Reference the process */
994 (PVOID*)&Process,
995 NULL);
996 if (!NT_SUCCESS(Status)) break;
997
998 /* Enter SEH for writing back data */
1000 {
1001 /* Return the debug flag state */
1002 *(PULONG)ProcessInformation = Process->NoDebugInherit ? 0 : 1;
1003 }
1005 {
1006 /* Get the exception code */
1008 }
1009 _SEH2_END;
1010
1011 /* Dereference the process */
1013 break;
1014
1016
1017 if (ProcessInformationLength != sizeof(ULONG))
1018 {
1020 break;
1021 }
1022
1023 /* Set the return length */
1024 Length = sizeof(ULONG);
1025
1026 /* Reference the process */
1031 (PVOID*)&Process,
1032 NULL);
1033 if (!NT_SUCCESS(Status)) break;
1034
1035 /* Enter SEH for writing back data */
1036 _SEH2_TRY
1037 {
1038 /* Return the BreakOnTermination state */
1039 *(PULONG)ProcessInformation = Process->BreakOnTermination;
1040 }
1042 {
1043 /* Get the exception code */
1045 }
1046 _SEH2_END;
1047
1048 /* Dereference the process */
1050 break;
1051
1052 /* Per-process security cookie */
1053 case ProcessCookie:
1054 {
1055 ULONG Cookie;
1056
1057 if (ProcessInformationLength != sizeof(ULONG))
1058 {
1059 /* Length size wrong, bail out */
1061 break;
1062 }
1063
1064 /* Get the current process and cookie */
1066 Cookie = Process->Cookie;
1067 if (!Cookie)
1068 {
1069 LARGE_INTEGER SystemTime;
1070 ULONG NewCookie;
1071 PKPRCB Prcb;
1072
1073 /* Generate a new cookie */
1074 KeQuerySystemTime(&SystemTime);
1075 Prcb = KeGetCurrentPrcb();
1076 NewCookie = Prcb->KeSystemCalls ^ Prcb->InterruptTime ^
1077 SystemTime.u.LowPart ^ SystemTime.u.HighPart;
1078
1079 /* Set the new cookie or return the current one */
1081 NewCookie,
1082 Cookie);
1083 if (!Cookie) Cookie = NewCookie;
1084
1085 /* Set the return length */
1086 Length = sizeof(ULONG);
1087 }
1088
1089 /* Indicate success */
1091
1092 /* Enter SEH to protect write */
1093 _SEH2_TRY
1094 {
1095 /* Write back the cookie */
1096 *(PULONG)ProcessInformation = Cookie;
1097 }
1099 {
1100 /* Get the exception code */
1102 }
1103 _SEH2_END;
1104 break;
1105 }
1106
1108
1109 if (ProcessInformationLength != sizeof(SECTION_IMAGE_INFORMATION))
1110 {
1111 /* Break out */
1113 break;
1114 }
1115
1116 /* Set the length required and validate it */
1118
1119 /* Indicate success */
1121
1122 /* Enter SEH to protect write */
1123 _SEH2_TRY
1124 {
1126 }
1128 {
1129 /* Get the exception code */
1131 }
1132 _SEH2_END;
1133 break;
1134
1136 {
1137 HANDLE DebugPort = NULL;
1138
1139 if (ProcessInformationLength != sizeof(HANDLE))
1140 {
1142 break;
1143 }
1144
1145 /* Set the return length */
1146 Length = sizeof(HANDLE);
1147
1148 /* Reference the process */
1153 (PVOID*)&Process,
1154 NULL);
1155 if (!NT_SUCCESS(Status)) break;
1156
1157 /* Get the debug port. Continue even if this fails. */
1159
1160 /* Let go of the process */
1162
1163 /* Protect write in SEH */
1164 _SEH2_TRY
1165 {
1166 /* Return debug port's handle */
1167 *(PHANDLE)ProcessInformation = DebugPort;
1168 }
1170 {
1171 if (DebugPort)
1172 ObCloseHandle(DebugPort, PreviousMode);
1173
1174 /* Get the exception code.
1175 * Note: This overwrites any previous failure status. */
1177 }
1178 _SEH2_END;
1179 break;
1180 }
1181
1183 DPRINT1("Handle tracing not implemented: %lu\n", ProcessInformationClass);
1185 break;
1186
1188
1189 if (ProcessInformationLength != sizeof(ULONG))
1190 {
1192 break;
1193 }
1194
1195 /* Set the return length */
1196 Length = sizeof(ULONG);
1197
1198 /* Indicate success */
1200
1201 /* Protect write in SEH */
1202 _SEH2_TRY
1203 {
1204 /* Query Ob */
1205 *(PULONG)ProcessInformation = ObIsLUIDDeviceMapsEnabled();
1206 }
1208 {
1209 /* Get the exception code */
1211 }
1212 _SEH2_END;
1213 break;
1214
1216
1217 if (ProcessInformationLength != sizeof(ULONG))
1218 {
1220 break;
1221 }
1222
1223 /* Set the return length */
1224 Length = sizeof(ULONG);
1225
1226 /* Reference the process */
1231 (PVOID*)&Process,
1232 NULL);
1233 if (!NT_SUCCESS(Status)) break;
1234
1235 /* Protect write in SEH */
1236 _SEH2_TRY
1237 {
1238 /* Return if the flag is set */
1239 *(PULONG)ProcessInformation = (ULONG)Process->VdmAllowed;
1240 }
1242 {
1243 /* Get the exception code */
1245 }
1246 _SEH2_END;
1247
1248 /* Dereference the process */
1250 break;
1251
1253 {
1254 ULONG_PTR Wow64 = 0;
1255
1256 if (ProcessInformationLength != sizeof(ULONG_PTR))
1257 {
1259 break;
1260 }
1261
1262 /* Set the return length */
1263 Length = sizeof(ULONG_PTR);
1264
1265 /* Reference the process */
1270 (PVOID*)&Process,
1271 NULL);
1272 if (!NT_SUCCESS(Status)) break;
1273
1274#ifdef _WIN64
1275 /* Make sure the process isn't dying */
1276 if (ExAcquireRundownProtection(&Process->RundownProtect))
1277 {
1278 /* Get the WOW64 process structure */
1279 Wow64 = (ULONG_PTR)Process->Wow64Process;
1280 /* Release the lock */
1281 ExReleaseRundownProtection(&Process->RundownProtect);
1282 }
1283#endif
1284
1285 /* Dereference the process */
1287
1288 /* Protect write with SEH */
1289 _SEH2_TRY
1290 {
1291 /* Return the Wow64 process information */
1292 *(PULONG_PTR)ProcessInformation = Wow64;
1293 }
1295 {
1296 /* Get exception code */
1298 }
1299 _SEH2_END;
1300 break;
1301 }
1302
1304 {
1305 ULONG ExecuteOptions = 0;
1306
1307 if (ProcessInformationLength != sizeof(ULONG))
1308 {
1310 break;
1311 }
1312
1313 /* Set the return length */
1314 Length = sizeof(ULONG);
1315
1317 {
1319 break;
1320 }
1321
1322 /* Get the options */
1323 Status = MmGetExecuteOptions(&ExecuteOptions);
1324 if (NT_SUCCESS(Status))
1325 {
1326 /* Protect write with SEH */
1327 _SEH2_TRY
1328 {
1329 /* Return them */
1330 *(PULONG)ProcessInformation = ExecuteOptions;
1331 }
1333 {
1334 /* Get exception code */
1336 }
1337 _SEH2_END;
1338 }
1339 break;
1340 }
1341
1343 DPRINT1("VDM/16-bit not implemented: %lu\n", ProcessInformationClass);
1345 break;
1346
1348 DPRINT1("WS Watch not implemented: %lu\n", ProcessInformationClass);
1350 break;
1351
1353 DPRINT1("Pool limits not implemented: %lu\n", ProcessInformationClass);
1355 break;
1356
1357 /* Not supported by Server 2003 */
1358 default:
1359#if DBG
1360 DPRINT1("Unsupported info class: %s\n", PspDumpProcessInfoClassName(ProcessInformationClass));
1361#endif
1363 }
1364
1365 /* Check if caller wants the return length and if there is one */
1366 if (ReturnLength != NULL && Length != 0)
1367 {
1368 /* Protect write with SEH */
1369 _SEH2_TRY
1370 {
1372 }
1374 {
1375 /* Get exception code.
1376 * Note: This overwrites any previous failure status. */
1378 }
1379 _SEH2_END;
1380 }
1381
1382 return Status;
1383}
1384
1385/*
1386 * @implemented
1387 */
1389NTAPI
1392 _In_ PROCESSINFOCLASS ProcessInformationClass,
1393 _In_reads_bytes_(ProcessInformationLength) PVOID ProcessInformation,
1394 _In_ ULONG ProcessInformationLength)
1395{
1398 ACCESS_MASK Access;
1400 HANDLE PortHandle = NULL;
1404 PROCESS_PRIORITY_CLASS PriorityClass = {0};
1405 PROCESS_FOREGROUND_BACKGROUND Foreground = {0};
1406 PVOID ExceptionPort;
1407 ULONG Break;
1408 KAFFINITY ValidAffinity, Affinity = 0;
1409 KPRIORITY BasePriority = 0;
1410 UCHAR MemoryPriority = 0;
1411 BOOLEAN DisableBoost = 0;
1412 ULONG DefaultHardErrorMode = 0;
1413 ULONG DebugFlags = 0, EnableFixup = 0, Boost = 0;
1414 ULONG NoExecute = 0, VdmPower = 0;
1418 PAGED_CODE();
1419
1420 /* Validate the information class */
1421 Status = DefaultSetInfoBufferCheck(ProcessInformationClass,
1424 ProcessInformation,
1425 ProcessInformationLength,
1426 PreviousMode);
1427 if (!NT_SUCCESS(Status))
1428 {
1429#if DBG
1430 DPRINT1("NtSetInformationProcess(ProcessInformationClass: %s): Class validation failed! (Status: 0x%lx)\n",
1431 PspDumpProcessInfoClassName(ProcessInformationClass), Status);
1432#endif
1433 return Status;
1434 }
1435
1436 /* Check what class this is */
1437 Access = PROCESS_SET_INFORMATION;
1438 if (ProcessInformationClass == ProcessSessionInformation)
1439 {
1440 /* Setting the Session ID needs a special mask */
1441 Access |= PROCESS_SET_SESSIONID;
1442 }
1443 else if (ProcessInformationClass == ProcessExceptionPort)
1444 {
1445 /* Setting the exception port needs a special mask */
1446 Access |= PROCESS_SUSPEND_RESUME;
1447 }
1448
1449 /* Reference the process */
1451 Access,
1454 (PVOID*)&Process,
1455 NULL);
1456 if (!NT_SUCCESS(Status)) return Status;
1457
1458 /* Check what kind of information class this is */
1459 switch (ProcessInformationClass)
1460 {
1462
1463 /* Check buffer length */
1464 if (ProcessInformationLength != sizeof(ULONG))
1465 {
1467 break;
1468 }
1469
1470 /* Use SEH for capture */
1471 _SEH2_TRY
1472 {
1473 /* Capture the boolean */
1474 VdmPower = *(PULONG)ProcessInformation;
1475 }
1477 {
1478 /* Get the exception code */
1480 _SEH2_YIELD(break);
1481 }
1482 _SEH2_END;
1483
1484 /* Getting VDM powers requires the SeTcbPrivilege */
1486 {
1487 /* We don't hold the privilege, bail out */
1489 DPRINT1("Need TCB privilege\n");
1490 break;
1491 }
1492
1493 /* Set or clear the flag */
1494 if (VdmPower)
1495 {
1497 }
1498 else
1499 {
1501 }
1502 break;
1503
1504 /* Error/Exception Port */
1506
1507 /* Check buffer length */
1508 if (ProcessInformationLength != sizeof(HANDLE))
1509 {
1511 break;
1512 }
1513
1514 /* Use SEH for capture */
1515 _SEH2_TRY
1516 {
1517 /* Capture the handle */
1518 PortHandle = *(PHANDLE)ProcessInformation;
1519 }
1521 {
1522 /* Get the exception code */
1524 _SEH2_YIELD(break);
1525 }
1526 _SEH2_END;
1527
1528 /* Setting the error port requires the SeTcbPrivilege */
1530 {
1531 /* We don't hold the privilege, bail out */
1533 break;
1534 }
1535
1536 /* Get the LPC Port */
1537 Status = ObReferenceObjectByHandle(PortHandle,
1538 0,
1541 (PVOID)&ExceptionPort,
1542 NULL);
1543 if (!NT_SUCCESS(Status)) break;
1544
1545 /* Change the pointer */
1546 if (InterlockedCompareExchangePointer(&Process->ExceptionPort,
1547 ExceptionPort,
1548 NULL))
1549 {
1550 /* We already had one, fail */
1551 ObDereferenceObject(ExceptionPort);
1553 }
1554 break;
1555
1556 /* Security Token */
1557 case ProcessAccessToken:
1558
1559 /* Check buffer length */
1560 if (ProcessInformationLength != sizeof(PROCESS_ACCESS_TOKEN))
1561 {
1563 break;
1564 }
1565
1566 /* Use SEH for capture */
1567 _SEH2_TRY
1568 {
1569 /* Save the token handle */
1570 TokenHandle = ((PPROCESS_ACCESS_TOKEN)ProcessInformation)->
1571 Token;
1572 }
1574 {
1575 /* Get the exception code */
1577 _SEH2_YIELD(break);
1578 }
1579 _SEH2_END;
1580
1581 /* Assign the actual token */
1583 break;
1584
1585 /* Hard error processing */
1587
1588 /* Check buffer length */
1589 if (ProcessInformationLength != sizeof(ULONG))
1590 {
1592 break;
1593 }
1594
1595 /* Enter SEH for direct buffer read */
1596 _SEH2_TRY
1597 {
1598 DefaultHardErrorMode = *(PULONG)ProcessInformation;
1599 }
1601 {
1602 /* Get exception code */
1604 _SEH2_YIELD(break);
1605 }
1606 _SEH2_END;
1607
1608 /* Set the mode */
1609 Process->DefaultHardErrorProcessing = DefaultHardErrorMode;
1610
1611 /* Call Ke for the update */
1612 if (DefaultHardErrorMode & SEM_NOALIGNMENTFAULTEXCEPT)
1613 {
1615 }
1616 else
1617 {
1619 }
1621 break;
1622
1623 /* Session ID */
1625
1626 /* Check buffer length */
1627 if (ProcessInformationLength != sizeof(PROCESS_SESSION_INFORMATION))
1628 {
1630 break;
1631 }
1632
1633 /* Enter SEH for capture */
1634 _SEH2_TRY
1635 {
1636 /* Capture the caller's buffer */
1637 SessionInfo = *(PPROCESS_SESSION_INFORMATION)ProcessInformation;
1638 }
1640 {
1641 /* Get the exception code */
1643 _SEH2_YIELD(break);
1644 }
1645 _SEH2_END;
1646
1647 /* Setting the session id requires the SeTcbPrivilege */
1649 {
1650 /* We don't hold the privilege, bail out */
1652 break;
1653 }
1654
1655 /*
1656 * Since we cannot change the session ID of the given
1657 * process anymore because it is set once and for all
1658 * at process creation time and because it is stored
1659 * inside the Process->Session structure managed by MM,
1660 * we fake changing it: we just return success if the
1661 * user-defined value is the same as the session ID of
1662 * the process, and otherwise we fail.
1663 */
1664 if (SessionInfo.SessionId == PsGetProcessSessionId(Process))
1665 {
1667 }
1668 else
1669 {
1671 }
1672
1673 break;
1674
1676
1677 /* Check buffer length */
1678 if (ProcessInformationLength != sizeof(PROCESS_PRIORITY_CLASS))
1679 {
1681 break;
1682 }
1683
1684 /* Enter SEH for capture */
1685 _SEH2_TRY
1686 {
1687 /* Capture the caller's buffer */
1688 PriorityClass = *(PPROCESS_PRIORITY_CLASS)ProcessInformation;
1689 }
1691 {
1692 /* Return the exception code */
1694 _SEH2_YIELD(break);
1695 }
1696 _SEH2_END;
1697
1698 /* Check for invalid PriorityClass value */
1700 {
1702 break;
1703 }
1704
1705 if ((PriorityClass.PriorityClass != Process->PriorityClass) &&
1707 {
1708 /* Check the privilege */
1712 PreviousMode);
1713 if (!HasPrivilege)
1714 {
1716 DPRINT1("Privilege to change priority to realtime lacking\n");
1718 }
1719 }
1720
1721 /* Check if we have a job */
1722 if (Process->Job)
1723 {
1724 DPRINT1("Jobs not yet supported\n");
1725 }
1726
1727 /* Set process priority class */
1728 Process->PriorityClass = PriorityClass.PriorityClass;
1729
1730 /* Set process priority mode (foreground or background) */
1732 PriorityClass.Foreground ?
1736 break;
1737
1739
1740 /* Check buffer length */
1741 if (ProcessInformationLength != sizeof(PROCESS_FOREGROUND_BACKGROUND))
1742 {
1744 break;
1745 }
1746
1747 /* Enter SEH for capture */
1748 _SEH2_TRY
1749 {
1750 /* Capture the caller's buffer */
1751 Foreground = *(PPROCESS_FOREGROUND_BACKGROUND)ProcessInformation;
1752 }
1754 {
1755 /* Return the exception code */
1757 _SEH2_YIELD(break);
1758 }
1759 _SEH2_END;
1760
1761 /* Set process priority mode (foreground or background) */
1763 Foreground.Foreground ?
1767 break;
1768
1770
1771 /* Validate input length */
1772 if (ProcessInformationLength != sizeof(KPRIORITY))
1773 {
1775 break;
1776 }
1777
1778 /* Enter SEH for direct buffer read */
1779 _SEH2_TRY
1780 {
1781 BasePriority = *(KPRIORITY*)ProcessInformation;
1782 }
1784 {
1785 /* Get exception code */
1786 Break = 0;
1788 _SEH2_YIELD(break);
1789 }
1790 _SEH2_END;
1791
1792 /* Extract the memory priority out of there */
1793 if (BasePriority & 0x80000000)
1794 {
1795 MemoryPriority = MEMORY_PRIORITY_FOREGROUND;
1796 BasePriority &= ~0x80000000;
1797 }
1798 else
1799 {
1800 MemoryPriority = MEMORY_PRIORITY_BACKGROUND;
1801 }
1802
1803 /* Validate the number */
1804 if ((BasePriority > HIGH_PRIORITY) || (BasePriority <= LOW_PRIORITY))
1805 {
1808 }
1809
1810 /* Check if the new base is higher */
1811 if (BasePriority > Process->Pcb.BasePriority)
1812 {
1816 PreviousMode);
1817 if (!HasPrivilege)
1818 {
1820 DPRINT1("Privilege to change priority from %lx to %lx lacking\n", Process->Pcb.BasePriority, BasePriority);
1822 }
1823 }
1824
1825 /* Call Ke */
1826 KeSetPriorityAndQuantumProcess(&Process->Pcb, BasePriority, 0);
1827
1828 /* Now set the memory priority */
1829 MmSetMemoryPriorityProcess(Process, MemoryPriority);
1831 break;
1832
1834
1835 /* Validate input length */
1836 if (ProcessInformationLength != sizeof(ULONG))
1837 {
1839 break;
1840 }
1841
1842 /* Enter SEH for direct buffer read */
1843 _SEH2_TRY
1844 {
1845 Boost = *(PULONG)ProcessInformation;
1846 }
1848 {
1849 /* Get exception code */
1850 Break = 0;
1852 _SEH2_YIELD(break);
1853 }
1854 _SEH2_END;
1855
1856 /* Make sure the process isn't dying */
1857 if (ExAcquireRundownProtection(&Process->RundownProtect))
1858 {
1859 /* Lock it */
1861 ExAcquirePushLockShared(&Process->ProcessLock);
1862
1863 /* Loop the threads */
1864 for (Next = Process->ThreadListHead.Flink;
1865 Next != &Process->ThreadListHead;
1866 Next = Next->Flink)
1867 {
1868 /* Call Ke for the thread */
1869 Thread = CONTAINING_RECORD(Next, ETHREAD, ThreadListEntry);
1871 }
1872
1873 /* Release the lock and rundown */
1874 ExReleasePushLockShared(&Process->ProcessLock);
1876 ExReleaseRundownProtection(&Process->RundownProtect);
1877
1878 /* Set success code */
1880 }
1881 else
1882 {
1883 /* Avoid race conditions */
1885 }
1886 break;
1887
1889
1890 /* Check buffer length */
1891 if (ProcessInformationLength != sizeof(ULONG))
1892 {
1894 break;
1895 }
1896
1897 /* Enter SEH for direct buffer read */
1898 _SEH2_TRY
1899 {
1900 Break = *(PULONG)ProcessInformation;
1901 }
1903 {
1904 /* Get exception code */
1905 Break = 0;
1907 _SEH2_YIELD(break);
1908 }
1909 _SEH2_END;
1910
1911 /* Setting 'break on termination' requires the SeDebugPrivilege */
1913 {
1914 /* We don't hold the privilege, bail out */
1916 break;
1917 }
1918
1919 /* Set or clear the flag */
1920 if (Break)
1921 {
1923 }
1924 else
1925 {
1927 }
1928
1929 break;
1930
1932
1933 /* Check buffer length */
1934 if (ProcessInformationLength != sizeof(KAFFINITY))
1935 {
1937 break;
1938 }
1939
1940 /* Enter SEH for direct buffer read */
1941 _SEH2_TRY
1942 {
1943 Affinity = *(PKAFFINITY)ProcessInformation;
1944 }
1946 {
1947 /* Get exception code */
1948 Break = 0;
1950 _SEH2_YIELD(break);
1951 }
1952 _SEH2_END;
1953
1954 /* Make sure it's valid for the CPUs present */
1955 ValidAffinity = Affinity & KeActiveProcessors;
1956 if (!Affinity || (ValidAffinity != Affinity))
1957 {
1959 break;
1960 }
1961
1962 /* Check if it's within job affinity limits */
1963 if (Process->Job)
1964 {
1965 /* Not yet implemented */
1968 break;
1969 }
1970
1971 /* Make sure the process isn't dying */
1972 if (ExAcquireRundownProtection(&Process->RundownProtect))
1973 {
1974 /* Lock it */
1976 ExAcquirePushLockShared(&Process->ProcessLock);
1977
1978 /* Call Ke to do the work */
1979 KeSetAffinityProcess(&Process->Pcb, ValidAffinity);
1980
1981 /* Release the lock and rundown */
1982 ExReleasePushLockShared(&Process->ProcessLock);
1984 ExReleaseRundownProtection(&Process->RundownProtect);
1985
1986 /* Set success code */
1988 }
1989 else
1990 {
1991 /* Avoid race conditions */
1993 }
1994 break;
1995
1996 /* Priority Boosting status */
1998
1999 /* Validate input length */
2000 if (ProcessInformationLength != sizeof(ULONG))
2001 {
2003 break;
2004 }
2005
2006 /* Enter SEH for direct buffer read */
2007 _SEH2_TRY
2008 {
2009 DisableBoost = *(PBOOLEAN)ProcessInformation;
2010 }
2012 {
2013 /* Get exception code */
2014 Break = 0;
2016 _SEH2_YIELD(break);
2017 }
2018 _SEH2_END;
2019
2020 /* Make sure the process isn't dying */
2021 if (ExAcquireRundownProtection(&Process->RundownProtect))
2022 {
2023 /* Lock it */
2025 ExAcquirePushLockShared(&Process->ProcessLock);
2026
2027 /* Call Ke to do the work */
2028 KeSetDisableBoostProcess(&Process->Pcb, DisableBoost);
2029
2030 /* Loop the threads too */
2031 for (Next = Process->ThreadListHead.Flink;
2032 Next != &Process->ThreadListHead;
2033 Next = Next->Flink)
2034 {
2035 /* Call Ke for the thread */
2036 Thread = CONTAINING_RECORD(Next, ETHREAD, ThreadListEntry);
2037 KeSetDisableBoostThread(&Thread->Tcb, DisableBoost);
2038 }
2039
2040 /* Release the lock and rundown */
2041 ExReleasePushLockShared(&Process->ProcessLock);
2043 ExReleaseRundownProtection(&Process->RundownProtect);
2044
2045 /* Set success code */
2047 }
2048 else
2049 {
2050 /* Avoid race conditions */
2052 }
2053 break;
2054
2055 case ProcessDebugFlags:
2056
2057 /* Check buffer length */
2058 if (ProcessInformationLength != sizeof(ULONG))
2059 {
2061 break;
2062 }
2063
2064 /* Enter SEH for direct buffer read */
2065 _SEH2_TRY
2066 {
2067 DebugFlags = *(PULONG)ProcessInformation;
2068 }
2070 {
2071 /* Get exception code */
2073 _SEH2_YIELD(break);
2074 }
2075 _SEH2_END;
2076
2077 /* Set the mode */
2078 if (DebugFlags & ~1)
2079 {
2081 }
2082 else
2083 {
2084 if (DebugFlags & 1)
2085 {
2087 }
2088 else
2089 {
2091 }
2092 }
2093
2094 /* Done */
2096 break;
2097
2099
2100 /* Check buffer length */
2101 if (ProcessInformationLength != sizeof(BOOLEAN))
2102 {
2104 break;
2105 }
2106
2107 /* Enter SEH for direct buffer read */
2108 _SEH2_TRY
2109 {
2110 EnableFixup = *(PULONG)ProcessInformation;
2111 }
2113 {
2114 /* Get exception code */
2116 _SEH2_YIELD(break);
2117 }
2118 _SEH2_END;
2119
2120 /* Set the mode */
2121 if (EnableFixup)
2122 {
2123 Process->DefaultHardErrorProcessing |= SEM_NOALIGNMENTFAULTEXCEPT;
2124 }
2125 else
2126 {
2127 Process->DefaultHardErrorProcessing &= ~SEM_NOALIGNMENTFAULTEXCEPT;
2128 }
2129
2130 /* Call Ke for the update */
2133 break;
2134
2136
2137 /* Only TCB can do this */
2139 {
2140 /* We don't hold the privilege, bail out */
2141 DPRINT1("Need TCB to set IOPL\n");
2143 break;
2144 }
2145
2146 /* Only supported on x86 */
2147#if defined (_X86_)
2148 Ke386SetIOPL();
2149#elif defined(_M_AMD64)
2150 /* On x64 this function isn't implemented.
2151 On Windows 2003 it returns success.
2152 On Vista+ it returns STATUS_NOT_IMPLEMENTED. */
2153 if ((ExGetPreviousMode() != KernelMode) &&
2154 (RtlRosGetAppcompatVersion() > _WIN32_WINNT_WS03))
2155 {
2157 }
2158#else
2160#endif
2161 /* Done */
2162 break;
2163
2165
2166 /* Check buffer length */
2167 if (ProcessInformationLength != sizeof(ULONG))
2168 {
2170 break;
2171 }
2172
2174 {
2176 break;
2177 }
2178
2179 /* Enter SEH for direct buffer read */
2180 _SEH2_TRY
2181 {
2182 NoExecute = *(PULONG)ProcessInformation;
2183 }
2185 {
2186 /* Get exception code */
2188 _SEH2_YIELD(break);
2189 }
2190 _SEH2_END;
2191
2192 /* Call Mm for the update */
2193 Status = MmSetExecuteOptions(NoExecute);
2194 break;
2195
2196 case ProcessDeviceMap:
2197
2198 /* Check buffer length */
2199 if (ProcessInformationLength != sizeof(HANDLE))
2200 {
2202 break;
2203 }
2204
2205 /* Use SEH for capture */
2206 _SEH2_TRY
2207 {
2208 /* Capture the handle */
2209 DirectoryHandle = *(PHANDLE)ProcessInformation;
2210 }
2212 {
2213 /* Get the exception code */
2215 _SEH2_YIELD(break);
2216 }
2217 _SEH2_END;
2218
2219 /* Call Ob to set the device map */
2221 break;
2222
2223
2224 /* We currently don't implement any of these */
2226 case ProcessLdtSize:
2228 DPRINT1("VDM/16-bit Request not implemented: %lu\n", ProcessInformationClass);
2230 break;
2231
2232 case ProcessQuotaLimits:
2233
2235 1,
2236 ProcessInformation,
2237 ProcessInformationLength,
2238 PreviousMode);
2239 break;
2240
2242 DPRINT1("WS watch not implemented\n");
2244 break;
2245
2247 DPRINT1("Handle tracing not implemented\n");
2249 break;
2250
2251 /* Anything else is invalid */
2252 default:
2253#if DBG
2254 DPRINT1("Invalid Server 2003 Info Class: %s\n", PspDumpProcessInfoClassName(ProcessInformationClass));
2255#endif
2257 }
2258
2259 /* Dereference and return status */
2261 return Status;
2262}
2263
2264/*
2265 * @implemented
2266 */
2268NTAPI
2270 _In_ HANDLE ThreadHandle,
2274{
2278 KPRIORITY Priority = 0;
2280 PTEB Teb;
2281
2282 PAGED_CODE();
2283
2284 /* Validate the information class */
2288 ThreadInformation,
2290 PreviousMode);
2291 if (!NT_SUCCESS(Status))
2292 {
2293#if DBG
2294 DPRINT1("NtSetInformationThread(ThreadInformationClass: %s): Class validation failed! (Status: 0x%lx)\n",
2295 PspDumpThreadInfoClassName(ThreadInformationClass), Status);
2296#endif
2297 return Status;
2298 }
2299
2300 /* Check what kind of information class this is */
2301 switch (ThreadInformationClass)
2302 {
2303 /* Thread priority */
2304 case ThreadPriority:
2305 {
2306 /* Check buffer length */
2307 if (ThreadInformationLength != sizeof(KPRIORITY))
2308 {
2310 break;
2311 }
2312
2313 /* Use SEH for capture */
2314 _SEH2_TRY
2315 {
2316 /* Get the priority */
2317 Priority = *(PLONG)ThreadInformation;
2318 }
2320 {
2321 /* Get the exception code */
2323 _SEH2_YIELD(break);
2324 }
2325 _SEH2_END;
2326
2327 /* Validate it */
2328 if ((Priority > HIGH_PRIORITY) ||
2330 {
2331 /* Fail */
2333 break;
2334 }
2335
2336 /* Check for the required privilege */
2338 {
2341 ThreadHandle,
2343 PreviousMode);
2344 if (!HasPrivilege)
2345 {
2346 DPRINT1("Privilege to change priority to %lx lacking\n", Priority);
2348 }
2349 }
2350
2351 /* Reference the thread */
2352 Status = ObReferenceObjectByHandle(ThreadHandle,
2356 (PVOID*)&Thread,
2357 NULL);
2358 if (!NT_SUCCESS(Status))
2359 break;
2360
2361 /* Set the priority */
2363
2364 /* Dereference the thread */
2366 break;
2367 }
2368
2369 case ThreadBasePriority:
2370 {
2371 /* Check buffer length */
2372 if (ThreadInformationLength != sizeof(LONG))
2373 {
2375 break;
2376 }
2377
2378 /* Use SEH for capture */
2379 _SEH2_TRY
2380 {
2381 /* Get the priority */
2382 Priority = *(PLONG)ThreadInformation;
2383 }
2385 {
2386 /* Get the exception code */
2388 _SEH2_YIELD(break);
2389 }
2390 _SEH2_END;
2391
2392 /* Validate it */
2395 {
2396 /* These ones are OK */
2397 if ((Priority != THREAD_BASE_PRIORITY_LOWRT + 1) &&
2399 {
2400 /* Check if the process is real time */
2401 if (PsGetCurrentProcess()->PriorityClass !=
2403 {
2404 /* It isn't, fail */
2406 break;
2407 }
2408 }
2409 }
2410
2411 /* Reference the thread */
2412 Status = ObReferenceObjectByHandle(ThreadHandle,
2416 (PVOID*)&Thread,
2417 NULL);
2418 if (!NT_SUCCESS(Status))
2419 break;
2420
2421 /* Set the base priority */
2423
2424 /* Dereference the thread */
2426 break;
2427 }
2428
2429 case ThreadAffinityMask:
2430 {
2431 KAFFINITY Affinity = 0, CombinedAffinity;
2432
2433 /* Check buffer length */
2434 if (ThreadInformationLength != sizeof(ULONG_PTR))
2435 {
2437 break;
2438 }
2439
2440 /* Use SEH for capture */
2441 _SEH2_TRY
2442 {
2443 /* Get the priority */
2444 Affinity = *(PULONG_PTR)ThreadInformation;
2445 }
2447 {
2448 /* Get the exception code */
2450 _SEH2_YIELD(break);
2451 }
2452 _SEH2_END;
2453
2454 /* Validate it */
2455 if (!Affinity)
2456 {
2457 /* Fail */
2459 break;
2460 }
2461
2462 /* Reference the thread */
2463 Status = ObReferenceObjectByHandle(ThreadHandle,
2467 (PVOID*)&Thread,
2468 NULL);
2469 if (!NT_SUCCESS(Status))
2470 break;
2471
2472 /* Get the process */
2473 Process = Thread->ThreadsProcess;
2474
2475 /* Try to acquire rundown */
2476 if (ExAcquireRundownProtection(&Process->RundownProtect))
2477 {
2478 /* Lock it */
2480 ExAcquirePushLockShared(&Process->ProcessLock);
2481
2482 /* Combine masks */
2483 CombinedAffinity = Affinity & Process->Pcb.Affinity;
2484 if (CombinedAffinity != Affinity)
2485 {
2486 /* Fail */
2488 }
2489 else
2490 {
2491 /* Set the affinity */
2492 KeSetAffinityThread(&Thread->Tcb, CombinedAffinity);
2493 }
2494
2495 /* Release the lock and rundown */
2496 ExReleasePushLockShared(&Process->ProcessLock);
2498 ExReleaseRundownProtection(&Process->RundownProtect);
2499 }
2500 else
2501 {
2502 /* Too late */
2504 }
2505
2506 /* Dereference the thread */
2508 break;
2509 }
2510
2512 {
2514
2515 /* Check buffer length */
2516 if (ThreadInformationLength != sizeof(HANDLE))
2517 {
2519 break;
2520 }
2521
2522 /* Use SEH for capture */
2523 _SEH2_TRY
2524 {
2525 /* Save the token handle */
2526 TokenHandle = *(PHANDLE)ThreadInformation;
2527 }
2529 {
2530 /* Get the exception code */
2532 _SEH2_YIELD(break);
2533 }
2534 _SEH2_END;
2535
2536 /* Reference the thread */
2537 Status = ObReferenceObjectByHandle(ThreadHandle,
2541 (PVOID*)&Thread,
2542 NULL);
2543 if (!NT_SUCCESS(Status))
2544 break;
2545
2546 /* Assign the actual token */
2548
2549 /* Dereference the thread */
2551 break;
2552 }
2553
2555 {
2556 PVOID Address;
2557
2558 /* Check buffer length */
2559 if (ThreadInformationLength != sizeof(ULONG_PTR))
2560 {
2562 break;
2563 }
2564
2565 /* Use SEH for capture */
2566 _SEH2_TRY
2567 {
2568 /* Get the priority */
2569 Address = *(PVOID*)ThreadInformation;
2570 }
2572 {
2573 /* Get the exception code */
2575 _SEH2_YIELD(break);
2576 }
2577 _SEH2_END;
2578
2579 /* Reference the thread */
2580 Status = ObReferenceObjectByHandle(ThreadHandle,
2584 (PVOID*)&Thread,
2585 NULL);
2586 if (!NT_SUCCESS(Status))
2587 break;
2588
2589 /* Set the address */
2591
2592 /* Dereference the thread */
2594 break;
2595 }
2596
2598 {
2599 ULONG_PTR IdealProcessor;
2600
2601 /* Check buffer length */
2602 if (ThreadInformationLength != sizeof(ULONG_PTR))
2603 {
2605 break;
2606 }
2607
2608 /* Use SEH for capture */
2609 _SEH2_TRY
2610 {
2611 /* Get the priority */
2612 IdealProcessor = *(PULONG_PTR)ThreadInformation;
2613 }
2615 {
2616 /* Get the exception code */
2618 _SEH2_YIELD(break);
2619 }
2620 _SEH2_END;
2621
2622 /* Validate it */
2623 if (IdealProcessor > MAXIMUM_PROCESSORS)
2624 {
2625 /* Fail */
2627 break;
2628 }
2629
2630 /* Reference the thread */
2631 Status = ObReferenceObjectByHandle(ThreadHandle,
2635 (PVOID*)&Thread,
2636 NULL);
2637 if (!NT_SUCCESS(Status))
2638 break;
2639
2640 /* Set the ideal */
2642 (CCHAR)IdealProcessor);
2643
2644 /* Get the TEB and protect the thread */
2645 Teb = Thread->Tcb.Teb;
2647 {
2648 /* Save the ideal processor */
2649 Teb->IdealProcessor = Thread->Tcb.IdealProcessor;
2650
2651 /* Release rundown protection */
2653 }
2654
2655 /* Dereference the thread */
2657 break;
2658 }
2659
2661 {
2662 ULONG_PTR DisableBoost;
2663
2664 /* Check buffer length */
2665 if (ThreadInformationLength != sizeof(ULONG_PTR))
2666 {
2668 break;
2669 }
2670
2671 /* Use SEH for capture */
2672 _SEH2_TRY
2673 {
2674 /* Get the priority */
2675 DisableBoost = *(PULONG_PTR)ThreadInformation;
2676 }
2678 {
2679 /* Get the exception code */
2681 _SEH2_YIELD(break);
2682 }
2683 _SEH2_END;
2684
2685 /* Reference the thread */
2686 Status = ObReferenceObjectByHandle(ThreadHandle,
2690 (PVOID*)&Thread,
2691 NULL);
2692 if (!NT_SUCCESS(Status))
2693 break;
2694
2695 /* Call the kernel */
2696 KeSetDisableBoostThread(&Thread->Tcb, (BOOLEAN)DisableBoost);
2697
2698 /* Dereference the thread */
2700 break;
2701 }
2702
2703 case ThreadZeroTlsCell:
2704 {
2706 PETHREAD ProcThread;
2707
2708 /* Check buffer length */
2709 if (ThreadInformationLength != sizeof(ULONG))
2710 {
2712 break;
2713 }
2714
2715 /* Use SEH for capture */
2716 _SEH2_TRY
2717 {
2718 /* Get the priority */
2719 TlsIndex = *(PULONG)ThreadInformation;
2720 }
2722 {
2723 /* Get the exception code */
2725 _SEH2_YIELD(break);
2726 }
2727 _SEH2_END;
2728
2729 /* Reference the thread */
2730 Status = ObReferenceObjectByHandle(ThreadHandle,
2734 (PVOID*)&Thread,
2735 NULL);
2736 if (!NT_SUCCESS(Status))
2737 break;
2738
2739 /* This is only valid for the current thread */
2740 if (Thread != PsGetCurrentThread())
2741 {
2742 /* Fail */
2745 break;
2746 }
2747
2748 /* Get the process */
2749 Process = Thread->ThreadsProcess;
2750
2751 /* Loop the threads */
2752 ProcThread = PsGetNextProcessThread(Process, NULL);
2753 while (ProcThread)
2754 {
2755 /* Acquire rundown */
2757 {
2758 /* Get the TEB */
2759 Teb = ProcThread->Tcb.Teb;
2760 if (Teb)
2761 {
2762 /* Check if we're in the expansion range */
2764 {
2767 {
2768 /* Check if we have expansion slots */
2769 PVOID* ExpansionSlots = Teb->TlsExpansionSlots;
2770 if (ExpansionSlots)
2771 {
2772 /* Clear the index */
2773 ExpansionSlots[TlsIndex - TLS_MINIMUM_AVAILABLE] = 0;
2774 }
2775 }
2776 }
2777 else
2778 {
2779 /* Clear the index */
2780 Teb->TlsSlots[TlsIndex] = NULL;
2781 }
2782 }
2783
2784 /* Release rundown */
2786 }
2787
2788 /* Go to the next thread */
2789 ProcThread = PsGetNextProcessThread(Process, ProcThread);
2790 }
2791
2792 /* Dereference the thread */
2794 break;
2795 }
2796
2798 {
2799 ULONG Break;
2800
2801 /* Check buffer length */
2802 if (ThreadInformationLength != sizeof(ULONG))
2803 {
2805 break;
2806 }
2807
2808 /* Enter SEH for direct buffer read */
2809 _SEH2_TRY
2810 {
2811 Break = *(PULONG)ThreadInformation;
2812 }
2814 {
2815 /* Get exception code */
2816 Break = 0;
2818 _SEH2_YIELD(break);
2819 }
2820 _SEH2_END;
2821
2822 /* Setting 'break on termination' requires the SeDebugPrivilege */
2824 {
2825 /* We don't hold the privilege, bail out */
2827 break;
2828 }
2829
2830 /* Reference the thread */
2831 Status = ObReferenceObjectByHandle(ThreadHandle,
2835 (PVOID*)&Thread,
2836 NULL);
2837 if (!NT_SUCCESS(Status))
2838 break;
2839
2840 /* Set or clear the flag */
2841 if (Break)
2842 {
2844 }
2845 else
2846 {
2848 }
2849
2850 /* Dereference the thread */
2852 break;
2853 }
2854
2856 {
2857 /* Check buffer length */
2858 if (ThreadInformationLength != 0)
2859 {
2861 break;
2862 }
2863
2864 /* Reference the thread */
2865 Status = ObReferenceObjectByHandle(ThreadHandle,
2869 (PVOID*)&Thread,
2870 NULL);
2871 if (!NT_SUCCESS(Status))
2872 break;
2873
2874 /* Set the flag */
2876
2877 /* Dereference the thread */
2879 break;
2880 }
2881
2882#if (NTDDI_VERSION >= NTDDI_WIN10_RS1) || defined(__REACTOS__)
2884 {
2885 UNICODE_STRING CapturedThreadName;
2886 PUNICODE_STRING NewThreadName;
2887
2888 /* Check buffer length */
2890 {
2892 break;
2893 }
2894
2895 /* Reference the thread.
2896 * NOTE: Win10+ uses THREAD_SET_LIMITED_INFORMATION instead;
2897 * however some tools misuse thread names to perform suspicious
2898 * operations; therefore we try to mess with these by requiring
2899 * a bit more of access rights. */
2900 Status = ObReferenceObjectByHandle(ThreadHandle,
2904 (PVOID*)&Thread,
2905 NULL);
2906 if (!NT_SUCCESS(Status))
2907 break;
2908
2909 /* Probe and capture the thread name */
2910 Status = ProbeAndCaptureUnicodeString(&CapturedThreadName,
2912 (PUNICODE_STRING)ThreadInformation);
2913 if (!NT_SUCCESS(Status))
2914 {
2916 break;
2917 }
2918
2919 /* Allocate a new buffer only if the thread name isn't empty
2920 * (REMARK: We only consider Length instead of MaximumLength).
2921 * If empty, just reset the thread name pointer to NULL instead
2922 * of allocating an empty UNICODE_STRING. */
2923 NewThreadName = NULL;
2924 if (CapturedThreadName.Length > 0)
2925 {
2926 ULONG Length = sizeof(UNICODE_STRING) + CapturedThreadName.Length;
2927 NewThreadName = ExAllocatePoolWithTag(NonPagedPool, // FIXME: NonPagedPoolNx
2929 if (!NewThreadName)
2930 {
2932 }
2933 else
2934 {
2935 /* Copy the new thread name */
2936 NewThreadName->Length =
2937 NewThreadName->MaximumLength = CapturedThreadName.Length;
2938 NewThreadName->Buffer = (PWCH)(NewThreadName + 1);
2939 RtlCopyMemory(NewThreadName->Buffer,
2940 CapturedThreadName.Buffer,
2941 CapturedThreadName.Length);
2942 }
2943 }
2944
2945 /* Free the captured string */
2946 ReleaseCapturedUnicodeString(&CapturedThreadName, PreviousMode);
2947
2948 /* Replace the original thread name with the new one */
2949 if (NT_SUCCESS(Status))
2950 {
2951 PUNICODE_STRING OldThreadName;
2953 OldThreadName = Thread->ThreadName;
2954 Thread->ThreadName = NewThreadName;
2956
2957 /* Free the old thread name */
2958 if (OldThreadName)
2959 ExFreePoolWithTag(OldThreadName, TAG_THREAD_NAME);
2960 }
2961
2962 /* Dereference the thread */
2964 break;
2965 }
2966#endif /* (NTDDI_VERSION >= NTDDI_WIN10_RS1) || defined(__REACTOS__) */
2967
2968 /* Anything else */
2969 default:
2970 /* Not yet implemented */
2971#if DBG
2972 DPRINT1("Not implemented: %s\n", PspDumpThreadInfoClassName(ThreadInformationClass));
2973#endif
2975 }
2976
2977 return Status;
2978}
2979
2980/*
2981 * @implemented
2982 */
2984NTAPI
2986 _In_ HANDLE ThreadHandle,
2989 PVOID ThreadInformation,
2992{
2996 ULONG Access;
2997 ULONG Length = 0;
2998
2999 PAGED_CODE();
3000
3001 /* Validate the information class */
3006 ThreadInformation,
3009 NULL,
3010 PreviousMode);
3011 if (!NT_SUCCESS(Status))
3012 {
3013#if DBG
3014 DPRINT1("NtQueryInformationThread(ThreadInformationClass: %s): Class validation failed! (Status: 0x%lx)\n",
3015 PspDumpThreadInfoClassName(ThreadInformationClass), Status);
3016#endif
3017 return Status;
3018 }
3019
3020 /* Check what class this is */
3021 Access = THREAD_QUERY_INFORMATION;
3022
3023 /* Check what kind of information class this is */
3024 switch (ThreadInformationClass)
3025 {
3026 /* Basic thread information */
3028 {
3029 PTHREAD_BASIC_INFORMATION ThreadBasicInfo =
3030 (PTHREAD_BASIC_INFORMATION)ThreadInformation;
3031
3032 /* Set the return length */
3034
3036 {
3038 break;
3039 }
3040
3041 /* Reference the thread */
3042 Status = ObReferenceObjectByHandle(ThreadHandle,
3043 Access,
3046 (PVOID*)&Thread,
3047 NULL);
3048 if (!NT_SUCCESS(Status))
3049 break;
3050
3051 /* Protect writes with SEH */
3052 _SEH2_TRY
3053 {
3054 /* Write all the information from the ETHREAD/KTHREAD */
3055 ThreadBasicInfo->ExitStatus = Thread->ExitStatus;
3056 ThreadBasicInfo->TebBaseAddress = (PVOID)Thread->Tcb.Teb;
3057 ThreadBasicInfo->ClientId = Thread->Cid;
3058 ThreadBasicInfo->AffinityMask = Thread->Tcb.Affinity;
3059 ThreadBasicInfo->Priority = Thread->Tcb.Priority;
3060 ThreadBasicInfo->BasePriority = KeQueryBasePriorityThread(&Thread->Tcb);
3061 }
3063 {
3064 /* Get exception code */
3066 }
3067 _SEH2_END;
3068
3069 /* Dereference the thread */
3071 break;
3072 }
3073
3074 /* Thread time information */
3075 case ThreadTimes:
3076 {
3077 PKERNEL_USER_TIMES ThreadTime = (PKERNEL_USER_TIMES)ThreadInformation;
3078
3079 /* Set the return length */
3080 Length = sizeof(KERNEL_USER_TIMES);
3081
3083 {
3085 break;
3086 }
3087
3088 /* Reference the thread */
3089 Status = ObReferenceObjectByHandle(ThreadHandle,
3090 Access,
3093 (PVOID*)&Thread,
3094 NULL);
3095 if (!NT_SUCCESS(Status))
3096 break;
3097
3098 /* Protect writes with SEH */
3099 _SEH2_TRY
3100 {
3101 /* Copy time information from ETHREAD/KTHREAD */
3104 ThreadTime->CreateTime = Thread->CreateTime;
3105
3106 /* Exit time is in a union and only valid on actual exit! */
3108 {
3109 ThreadTime->ExitTime = Thread->ExitTime;
3110 }
3111 else
3112 {
3113 ThreadTime->ExitTime.QuadPart = 0;
3114 }
3115 }
3117 {
3118 /* Get exception code */
3120 }
3121 _SEH2_END;
3122
3123 /* Dereference the thread */
3125 break;
3126 }
3127
3129 {
3130 /* Set the return length*/
3131 Length = sizeof(PVOID);
3132
3134 {
3136 break;
3137 }
3138
3139 /* Reference the thread */
3140 Status = ObReferenceObjectByHandle(ThreadHandle,
3141 Access,
3144 (PVOID*)&Thread,
3145 NULL);
3146 if (!NT_SUCCESS(Status))
3147 break;
3148
3149 /* Protect write with SEH */
3150 _SEH2_TRY
3151 {
3152 /* Return the Win32 Start Address */
3153 *(PVOID*)ThreadInformation = Thread->Win32StartAddress;
3154 }
3156 {
3157 /* Get exception code */
3159 }
3160 _SEH2_END;
3161
3162 /* Dereference the thread */
3164 break;
3165 }
3166
3168 {
3169 /* Set the return length*/
3170 Length = sizeof(LARGE_INTEGER);
3171
3173 {
3175 break;
3176 }
3177
3178 /* Reference the thread */
3179 Status = ObReferenceObjectByHandle(ThreadHandle,
3180 Access,
3183 (PVOID*)&Thread,
3184 NULL);
3185 if (!NT_SUCCESS(Status))
3186 break;
3187
3188 /* Protect write with SEH */
3189 _SEH2_TRY
3190 {
3191 /* FIXME */
3192 (*(PLARGE_INTEGER)ThreadInformation).QuadPart = 0;
3193 }
3195 {
3196 /* Get exception code */
3198 }
3199 _SEH2_END;
3200
3201 /* Dereference the thread */
3203 break;
3204 }
3205
3207 {
3208 /* Set the return length*/
3209 Length = sizeof(ULONG);
3210
3212 {
3214 break;
3215 }
3216
3217 /* Reference the thread */
3218 Status = ObReferenceObjectByHandle(ThreadHandle,
3219 Access,
3222 (PVOID*)&Thread,
3223 NULL);
3224 if (!NT_SUCCESS(Status))
3225 break;
3226
3227 /* Protect write with SEH */
3228 _SEH2_TRY
3229 {
3230 /* Return whether or not we are the last thread */
3231 *(PULONG)ThreadInformation = ((Thread->ThreadsProcess->
3232 ThreadListHead.Flink->Flink ==
3233 &Thread->ThreadsProcess->
3235 TRUE : FALSE);
3236 }
3238 {
3239 /* Get exception code */
3241 }
3242 _SEH2_END;
3243
3244 /* Dereference the thread */
3246 break;
3247 }
3248
3249 case ThreadIsIoPending:
3250 {
3251 KIRQL OldIrql;
3252
3253 /* Set the return length*/
3254 Length = sizeof(ULONG);
3255
3257 {
3259 break;
3260 }
3261
3262 /* Reference the thread */
3263 Status = ObReferenceObjectByHandle(ThreadHandle,
3264 Access,
3267 (PVOID*)&Thread,
3268 NULL);
3269 if (!NT_SUCCESS(Status))
3270 break;
3271
3272 /* Raise the IRQL to protect the IRP list */
3274
3275 /* Protect write with SEH */
3276 _SEH2_TRY
3277 {
3278 /* Check if the IRP list is empty or not */
3279 *(PULONG)ThreadInformation = !IsListEmpty(&Thread->IrpList);
3280 }
3282 {
3283 /* Get exception code */
3285 }
3286 _SEH2_END;
3287
3288 /* Lower IRQL back */
3290
3291 /* Dereference the thread */
3293 break;
3294 }
3295
3296 /* LDT and GDT information */
3298 {
3299#if defined(_X86_)
3300 /* Reference the thread */
3301 Status = ObReferenceObjectByHandle(ThreadHandle,
3302 Access,
3305 (PVOID*)&Thread,
3306 NULL);
3307 if (!NT_SUCCESS(Status))
3308 break;
3309
3310 /* Call the worker routine */
3312 ThreadInformation,
3314 ReturnLength);
3315
3316 /* Dereference the thread */
3318#else
3319 /* Only implemented on x86 */
3321#endif
3322 break;
3323 }
3324
3326 {
3327 /* Set the return length*/
3328 Length = sizeof(ULONG);
3329
3331 {
3333 break;
3334 }
3335
3336 /* Reference the thread */
3337 Status = ObReferenceObjectByHandle(ThreadHandle,
3338 Access,
3341 (PVOID*)&Thread,
3342 NULL);
3343 if (!NT_SUCCESS(Status))
3344 break;
3345
3346 _SEH2_TRY
3347 {
3348 *(PULONG)ThreadInformation = Thread->Tcb.DisableBoost ? 1 : 0;
3349 }
3351 {
3353 }
3354 _SEH2_END;
3355
3356 /* Dereference the thread */
3358 break;
3359 }
3360
3361#if (NTDDI_VERSION >= NTDDI_VISTA)
3363 {
3364 /* Set the return length */
3365 Length = sizeof(BOOLEAN);
3366
3368 {
3370 break;
3371 }
3372
3373 /* Reference the thread */
3374 Status = ObReferenceObjectByHandle(ThreadHandle,
3375 Access,
3378 (PVOID*)&Thread,
3379 NULL);
3380 if (!NT_SUCCESS(Status))
3381 break;
3382
3383 /* Protect write with SEH */
3384 _SEH2_TRY
3385 {
3386 *(PBOOLEAN)ThreadInformation = Thread->HideFromDebugger;
3387 }
3389 {
3390 /* Get exception code */
3392 }
3393 _SEH2_END;
3394
3395 /* Dereference the thread */
3397 break;
3398 }
3399#endif /* (NTDDI_VERSION >= NTDDI_VISTA) */
3400
3402 {
3403 /* Set the return length */
3404 Length = sizeof(ULONG);
3405
3407 {
3409 break;
3410 }
3411
3412 /* Reference the thread */
3413 Status = ObReferenceObjectByHandle(ThreadHandle,
3414 Access,
3417 (PVOID*)&Thread,
3418 NULL);
3419 if (!NT_SUCCESS(Status))
3420 break;
3421
3422 _SEH2_TRY
3423 {
3424 *(PULONG)ThreadInformation = Thread->BreakOnTermination;
3425 }
3427 {
3429 }
3430 _SEH2_END;
3431
3432 /* Dereference the thread */
3434 break;
3435 }
3436
3437 case ThreadIsTerminated:
3438 {
3439 ULONG ThreadTerminated;
3440
3441 /* Set the return length*/
3442 Length = sizeof(ThreadTerminated);
3443
3445 {
3447 break;
3448 }
3449
3450 /* Reference the thread */
3451 Status = ObReferenceObjectByHandle(ThreadHandle,
3452 Access,
3455 (PVOID*)&Thread,
3456 NULL);
3457 if (!NT_SUCCESS(Status))
3458 break;
3459
3460 ThreadTerminated = PsIsThreadTerminating(Thread);
3461
3462 _SEH2_TRY
3463 {
3464 *(PULONG)ThreadInformation = ThreadTerminated ? 1 : 0;
3465 }
3467 {
3469 }
3470 _SEH2_END;
3471
3472 /* Dereference the thread */
3474 break;
3475 }
3476
3477#if (NTDDI_VERSION >= NTDDI_WIN10_RS1) || defined(__REACTOS__)
3479 {
3480 PUNICODE_STRING ThreadName;
3481
3482 /* Reference the thread */
3483 Status = ObReferenceObjectByHandle(ThreadHandle,
3484 // FIXME: Use THREAD_QUERY_LIMITED_INFORMATION when implemented
3488 (PVOID*)&Thread,
3489 NULL);
3490 if (!NT_SUCCESS(Status))
3491 break;
3492
3494
3495 ThreadName = Thread->ThreadName;
3496
3497 /* Set the return length (REMARK: We only
3498 * consider Length instead of MaximumLength) */
3499 Length = sizeof(UNICODE_STRING);
3500 Length += (ThreadName ? ThreadName->Length : 0);
3502 {
3506 /* As on Windows, and *not* STATUS_INFO_LENGTH_MISMATCH */
3507 break;
3508 }
3509
3510 /* Protect writes with SEH */
3511 _SEH2_TRY
3512 {
3513 PTHREAD_NAME_INFORMATION NameInfo =
3514 (PTHREAD_NAME_INFORMATION)ThreadInformation;
3515 if (ThreadName && (ThreadName->Length > 0))
3516 {
3517 NameInfo->ThreadName.Length =
3518 NameInfo->ThreadName.MaximumLength = ThreadName->Length;
3519 NameInfo->ThreadName.Buffer = (PWCH)(&NameInfo->ThreadName + 1);
3521 ThreadName->Buffer,
3522 ThreadName->Length);
3523 }
3524 else
3525 {
3526 RtlInitEmptyUnicodeString(&NameInfo->ThreadName, NULL, 0);
3527 }
3528 }
3530 {
3531 /* Get exception code */
3533 }
3534 _SEH2_END;
3535
3537
3538 /* Dereference the thread */
3540 break;
3541 }
3542#endif /* (NTDDI_VERSION >= NTDDI_WIN10_RS1) || defined(__REACTOS__) */
3543
3544 /* Anything else */
3545 default:
3546 /* Not yet implemented */
3547#if DBG
3548 DPRINT1("Not implemented: %s\n", PspDumpThreadInfoClassName(ThreadInformationClass));
3549#endif
3551 }
3552
3553 /* Protect write with SEH */
3554 _SEH2_TRY
3555 {
3556 /* Check if caller wanted return length */
3558 }
3560 {
3561 /* Get exception code */
3563 }
3564 _SEH2_END;
3565
3566 return Status;
3567}
3568
3569/* EOF */
#define PAGED_CODE()
#define STATUS_PRIVILEGE_NOT_HELD
Definition: DriverTester.h:9
@ ObjectNameInformation
Definition: DriverTester.h:55
_In_ PVOID _In_ ULONG _Out_ PVOID _In_ ULONG _Inout_ PULONG ReturnLength
_In_ PVOID _In_ ULONG _Out_ PVOID _In_ ULONG _Inout_ PULONG _In_ KPROCESSOR_MODE PreviousMode
static HANDLE DirectoryHandle
Definition: ObType.c:48
#define RTL_NUMBER_OF(x)
Definition: RtlRegistry.c:12
unsigned char BOOLEAN
Definition: actypes.h:127
LONG NTSTATUS
Definition: precomp.h:26
#define DPRINT1
Definition: precomp.h:8
BOOL Query(LPCTSTR *ServiceArgs, DWORD ArgCount, BOOL bExtended)
Definition: query.c:292
KAFFINITY * PKAFFINITY
Definition: basetsd.h:189
#define UNIMPLEMENTED
Definition: ntoskrnl.c:15
@ ProcessDebugPort
Definition: cicbase.cpp:64
@ ProcessBreakOnTermination
Definition: cicbase.cpp:67
@ ProcessBasicInformation
Definition: cicbase.cpp:63
@ ProcessWow64Information
Definition: cicbase.cpp:65
@ ProcessImageFileName
Definition: cicbase.cpp:66
enum _PROCESSINFOCLASS PROCESSINFOCLASS
Definition: loader.c:66
#define STATUS_NOT_IMPLEMENTED
Definition: d3dkmdt.h:42
NTSTATUS NTAPI DbgkOpenProcessDebugPort(IN PEPROCESS Process, IN KPROCESSOR_MODE PreviousMode, OUT HANDLE *DebugHandle)
Definition: dbgkobj.c:1526
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
struct _THREAD_BASIC_INFORMATION THREAD_BASIC_INFORMATION
ULONG_PTR KAFFINITY
Definition: compat.h:85
@ ThreadEnableAlignmentFaultFixup
Definition: compat.h:942
@ ThreadCSwitchPmu
Definition: compat.h:963
@ ThreadDescriptorTableEntry
Definition: compat.h:941
@ ThreadEventPair_Reusable
Definition: compat.h:943
@ ThreadIdealProcessorEx
Definition: compat.h:968
@ ThreadAmILastThread
Definition: compat.h:947
@ ThreadTimes
Definition: compat.h:936
@ ThreadPagePriority
Definition: compat.h:959
@ ThreadUmsInformation
Definition: compat.h:966
@ ThreadCSwitchMon
Definition: compat.h:962
@ ThreadPriority
Definition: compat.h:937
@ ThreadIdealProcessor
Definition: compat.h:948
@ ThreadActualBasePriority
Definition: compat.h:960
@ ThreadGroupInformation
Definition: compat.h:965
@ ThreadSwitchLegacyState
Definition: compat.h:954
@ ThreadQuerySetWin32StartAddress
Definition: compat.h:944
@ ThreadIsTerminated
Definition: compat.h:955
@ ThreadLastSystemCall
Definition: compat.h:956
@ ThreadBreakOnTermination
Definition: compat.h:953
@ ThreadImpersonationToken
Definition: compat.h:940
@ ThreadSetTlsArrayAddress
Definition: compat.h:950
@ ThreadAffinityMask
Definition: compat.h:939
@ ThreadBasePriority
Definition: compat.h:938
@ ThreadTebInformation
Definition: compat.h:961
@ ThreadIoPriority
Definition: compat.h:957
@ ThreadCycleTime
Definition: compat.h:958
@ ThreadBasicInformation
Definition: compat.h:935
@ ThreadCounterProfiling
Definition: compat.h:967
@ ThreadPriorityBoost
Definition: compat.h:949
@ ThreadPerformanceCount
Definition: compat.h:946
@ ThreadIsIoPending
Definition: compat.h:951
@ ThreadZeroTlsCell
Definition: compat.h:945
@ ThreadWow64Context
Definition: compat.h:964
@ ThreadHideFromDebugger
Definition: compat.h:952
enum _THREADINFOCLASS THREADINFOCLASS
Definition: thread.c:99
struct _THREAD_BASIC_INFORMATION * PTHREAD_BASIC_INFORMATION
LONG KPRIORITY
Definition: compat.h:803
#define ULONG_PTR
Definition: config.h:101
UNICODE_STRING * PUNICODE_STRING
Definition: env_spec_w32.h:373
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define IsListEmpty(ListHead)
Definition: env_spec_w32.h:954
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
#define KeRaiseIrql(irql, oldIrql)
Definition: env_spec_w32.h:597
#define APC_LEVEL
Definition: env_spec_w32.h:695
#define KeLowerIrql(oldIrql)
Definition: env_spec_w32.h:602
#define PAGE_SHIFT
Definition: env_spec_w32.h:45
#define KeQuerySystemTime(t)
Definition: env_spec_w32.h:570
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
struct _UNICODE_STRING UNICODE_STRING
#define NonPagedPool
Definition: env_spec_w32.h:307
#define ExReleaseRundownProtection
Definition: ex.h:139
#define ExGetPreviousMode
Definition: ex.h:143
FORCEINLINE VOID ExAcquirePushLockShared(PEX_PUSH_LOCK PushLock)
Definition: ex.h:1108
FORCEINLINE VOID ExReleasePushLockShared(PEX_PUSH_LOCK PushLock)
Definition: ex.h:1216
#define ExAcquireRundownProtection
Definition: ex.h:138
#define MAXIMUM_PROCESSORS
Definition: rwlock.h:5
_In_opt_ PFILE_OBJECT _In_opt_ PETHREAD Thread
Definition: fltkernel.h:2653
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:223
Status
Definition: gdiplustypes.h:25
#define ICIF_PROBE_READ
Definition: icif.h:25
#define PROCESS_SUSPEND_RESUME
Definition: pstypes.h:168
struct _PROCESS_PRIORITY_CLASS PROCESS_PRIORITY_CLASS
#define PROCESS_QUERY_INFORMATION
Definition: pstypes.h:167
#define THREAD_SET_THREAD_TOKEN
Definition: pstypes.h:151
#define THREAD_BASE_PRIORITY_LOWRT
Definition: pstypes.h:183
struct _PROCESS_PRIORITY_CLASS * PPROCESS_PRIORITY_CLASS
#define THREAD_QUERY_INFORMATION
Definition: pstypes.h:150
#define PROCESS_PRIORITY_CLASS_ABOVE_NORMAL
Definition: pstypes.h:113
#define PSF_NO_DEBUG_INHERIT_BIT
Definition: pstypes.h:275
#define CT_HIDE_FROM_DEBUGGER_BIT
Definition: pstypes.h:241
#define THREAD_BASE_PRIORITY_MIN
Definition: pstypes.h:185
#define PROCESS_SET_SESSIONID
Definition: pstypes.h:160
#define THREAD_BASE_PRIORITY_MAX
Definition: pstypes.h:184
@ PsProcessPriorityForeground
Definition: pstypes.h:460
@ PsProcessPriorityBackground
Definition: pstypes.h:461
struct _THREAD_NAME_INFORMATION * PTHREAD_NAME_INFORMATION
#define THREAD_BASE_PRIORITY_IDLE
Definition: pstypes.h:186
#define PROCESS_SET_INFORMATION
Definition: pstypes.h:166
#define PSF_VDM_ALLOWED_BIT
Definition: pstypes.h:297
#define TLS_EXPANSION_SLOTS
Definition: pstypes.h:311
#define PROCESS_PRIORITY_CLASS_REALTIME
Definition: pstypes.h:111
#define CT_BREAK_ON_TERMINATION_BIT
Definition: pstypes.h:245
@ PsNonPagedPool
Definition: pstypes.h:1110
@ PsPageFile
Definition: pstypes.h:1112
@ PsPagedPool
Definition: pstypes.h:1111
struct _PROCESS_FOREGROUND_BACKGROUND * PPROCESS_FOREGROUND_BACKGROUND
#define MEMORY_PRIORITY_BACKGROUND
Definition: pstypes.h:125
#define PSF_BREAK_ON_TERMINATION_BIT
Definition: pstypes.h:286
#define MEMORY_PRIORITY_FOREGROUND
Definition: pstypes.h:127
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:90
#define QUOTA_LIMITS_HARDWS_MIN_DISABLE
#define PROCESS_LUID_DOSDEVICES_ONLY
Definition: pstypes.h:228
struct _IO_COUNTERS IO_COUNTERS
struct _PROCESS_SESSION_INFORMATION PROCESS_SESSION_INFORMATION
struct _PROCESS_SESSION_INFORMATION * PPROCESS_SESSION_INFORMATION
#define LOW_PRIORITY
#define QUOTA_LIMITS_HARDWS_MAX_DISABLE
struct _QUOTA_LIMITS_EX QUOTA_LIMITS_EX
#define QUOTA_LIMITS_HARDWS_MAX_ENABLE
#define QUOTA_LIMITS_HARDWS_MIN_ENABLE
#define LOW_REALTIME_PRIORITY
#define HIGH_PRIORITY
struct _IO_COUNTERS * PIO_COUNTERS
#define InterlockedCompareExchangePointer
Definition: interlocked.h:144
#define InterlockedCompareExchange
Definition: interlocked.h:119
static LIST_ENTRY ThreadListHead
Definition: sys_arch.c:6
#define RTL_FIELD_SIZE(type, field)
Definition: kdb_expr.c:86
#define KeLeaveCriticalRegion()
Definition: ke_x.h:119
#define KeEnterCriticalRegion()
Definition: ke_x.h:88
if(dx< 0)
Definition: linetemp.h:194
POBJECT_TYPE LpcPortObjectType
Definition: port.c:17
#define ASSERT(a)
Definition: mode.c:44
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
#define sprintf
Definition: sprintf.c:45
static const char * ImageName
Definition: image.c:34
FORCEINLINE struct _KPRCB * KeGetCurrentPrcb(VOID)
Definition: ketypes.h:1187
#define KernelMode
Definition: asm.h:38
_In_ HANDLE ProcessHandle
Definition: mmfuncs.h:403
struct _SECTION_IMAGE_INFORMATION SECTION_IMAGE_INFORMATION
_In_ ACCESS_MASK _In_ ULONG _Out_ PHANDLE TokenHandle
Definition: psfuncs.h:727
_In_ THREADINFOCLASS _In_ ULONG ThreadInformationLength
Definition: psfuncs.h:844
_In_ THREADINFOCLASS ThreadInformationClass
Definition: psfuncs.h:841
#define SEM_NOALIGNMENTFAULTEXCEPT
Definition: rtltypes.h:71
#define _In_reads_bytes_(s)
Definition: no_sal2.h:170
#define _Out_opt_
Definition: no_sal2.h:214
#define _Outptr_
Definition: no_sal2.h:262
#define _In_
Definition: no_sal2.h:158
#define _Out_writes_bytes_to_opt_(s, c)
Definition: no_sal2.h:240
ULONG ACCESS_MASK
Definition: nt_native.h:40
#define NtCurrentProcess()
Definition: nt_native.h:1660
struct _OBJECT_NAME_INFORMATION OBJECT_NAME_INFORMATION
#define THREAD_SET_INFORMATION
Definition: nt_native.h:1340
WCHAR * PWCH
Definition: ntbasedef.h:422
struct _PROCESS_ACCESS_TOKEN * PPROCESS_ACCESS_TOKEN
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
LONG NTAPI KeQueryBasePriorityThread(IN PKTHREAD Thread)
Definition: thrdobj.c:52
ULONG NTAPI KeQueryRuntimeProcess(IN PKPROCESS Process, OUT PULONG UserTime)
Definition: procobj.c:860
KAFFINITY NTAPI KeSetAffinityProcess(IN PKPROCESS Process, IN KAFFINITY Affinity)
Definition: procobj.c:265
KAFFINITY KeActiveProcessors
Definition: processor.c:16
VOID NTAPI Ke386SetIOPL(VOID)
Definition: v86vdm.c:595
VOID NTAPI KeQueryValuesProcess(IN PKPROCESS Process, PPROCESS_VALUES Values)
Definition: procobj.c:525
BOOLEAN NTAPI KeSetDisableBoostProcess(IN PKPROCESS Process, IN BOOLEAN Disable)
Definition: procobj.c:331
BOOLEAN NTAPI KeSetDisableBoostThread(IN OUT PKTHREAD Thread, IN BOOLEAN Disable)
Definition: thrdobj.c:86
BOOLEAN NTAPI KeReadStateThread(IN PKTHREAD Thread)
Definition: thrdobj.c:42
BOOLEAN NTAPI KeSetAutoAlignmentProcess(IN PKPROCESS Process, IN BOOLEAN Enable)
Definition: procobj.c:313
VOID NTAPI KeBoostPriorityThread(IN PKTHREAD Thread, IN KPRIORITY Increment)
Definition: thrdobj.c:220
KPRIORITY NTAPI KeSetPriorityAndQuantumProcess(IN PKPROCESS Process, IN KPRIORITY Priority, IN UCHAR Quantum OPTIONAL)
Definition: procobj.c:349
PFILE_OBJECT NTAPI MmGetFileObjectForSection(IN PVOID Section)
Definition: section.c:1542
VOID NTAPI MmGetImageInformation(OUT PSECTION_IMAGE_INFORMATION ImageInformation)
Definition: section.c:1619
NTSTATUS NTAPI MmSetExecuteOptions(IN ULONG ExecuteOptions)
Definition: pagfault.c:2695
NTSTATUS NTAPI MmSetMemoryPriorityProcess(IN PEPROCESS Process, IN UCHAR MemoryPriority)
Definition: procsup.c:487
NTSTATUS NTAPI MmGetExecuteOptions(IN PULONG ExecuteOptions)
Definition: pagfault.c:2653
static __inline NTSTATUS DefaultQueryInfoBufferCheck(_In_ ULONG Class, _In_ const INFORMATION_CLASS_INFO *ClassList, _In_ ULONG ClassListEntries, _In_ ULONG Flags, _In_opt_ PVOID Buffer, _In_ ULONG BufferLength, _In_opt_ PULONG ReturnLength, _In_opt_ PULONG_PTR ReturnLengthPtr, _In_ KPROCESSOR_MODE PreviousMode)
Probe helper that validates the provided parameters whenever a NtQuery*** system call is invoked from...
Definition: probe.h:219
static __inline NTSTATUS DefaultSetInfoBufferCheck(_In_ ULONG Class, _In_ const INFORMATION_CLASS_INFO *ClassList, _In_ ULONG ClassListEntries, _In_ PVOID Buffer, _In_ ULONG BufferLength, _In_ KPROCESSOR_MODE PreviousMode)
Probe helper that validates the provided parameters whenever a NtSet*** system call is invoked from u...
Definition: probe.h:70
const LUID SeDebugPrivilege
Definition: priv.c:39
BOOLEAN NTAPI SeCheckPrivilegedObject(_In_ LUID PrivilegeValue, _In_ HANDLE ObjectHandle, _In_ ACCESS_MASK DesiredAccess, _In_ KPROCESSOR_MODE PreviousMode)
Checks a privileged object if such object has the specific privilege submitted by the caller.
Definition: priv.c:803
const LUID SeTcbPrivilege
Definition: priv.c:26
const LUID SeIncreaseBasePriorityPrivilege
Definition: priv.c:33
NTSTATUS NTAPI IoQueryFileDosDeviceName(IN PFILE_OBJECT FileObject, OUT POBJECT_NAME_INFORMATION *ObjectNameInformation)
Definition: file.c:3661
ULONG KeMaximumIncrement
Definition: clock.c:20
POBJECT_TYPE PsProcessType
Definition: process.c:20
ULONG NTAPI PsGetProcessSessionId(IN PEPROCESS Process)
Definition: process.c:1163
VOID NTAPI PsSetProcessPriorityByClass(IN PEPROCESS Process, IN PSPROCESSPRIORITYMODE Type)
Definition: process.c:1325
ULONG PspTraceLevel
Definition: query.c:18
NTSTATUS NTAPI NtQueryInformationThread(_In_ HANDLE ThreadHandle, _In_ THREADINFOCLASS ThreadInformationClass, _Out_writes_bytes_to_opt_(ThreadInformationLength, *ReturnLength) PVOID ThreadInformation, _In_ ULONG ThreadInformationLength, _Out_opt_ PULONG ReturnLength)
Definition: query.c:2985
NTSTATUS NTAPI NtSetInformationProcess(_In_ HANDLE ProcessHandle, _In_ PROCESSINFOCLASS ProcessInformationClass, _In_reads_bytes_(ProcessInformationLength) PVOID ProcessInformation, _In_ ULONG ProcessInformationLength)
Definition: query.c:1390
NTSTATUS NTAPI PsReferenceProcessFilePointer(_In_ PEPROCESS Process, _Outptr_ PFILE_OBJECT *FileObject)
Definition: query.c:24
NTSTATUS NTAPI NtSetInformationThread(_In_ HANDLE ThreadHandle, _In_ THREADINFOCLASS ThreadInformationClass, _In_reads_bytes_(ThreadInformationLength) PVOID ThreadInformation, _In_ ULONG ThreadInformationLength)
Definition: query.c:2269
NTSTATUS NTAPI NtQueryInformationProcess(_In_ HANDLE ProcessHandle, _In_ PROCESSINFOCLASS ProcessInformationClass, _Out_writes_bytes_to_opt_(ProcessInformationLength, *ReturnLength) PVOID ProcessInformation, _In_ ULONG ProcessInformationLength, _Out_opt_ PULONG ReturnLength)
Definition: query.c:211
NTSTATUS NTAPI PsAssignImpersonationToken(IN PETHREAD Thread, IN HANDLE TokenHandle)
Definition: security.c:502
POBJECT_TYPE PsThreadType
Definition: thread.c:20
BOOLEAN NTAPI PsIsThreadTerminating(IN PETHREAD Thread)
Definition: thread.c:868
NTSTATUS NTAPI SeLocateProcessImageName(_In_ PEPROCESS Process, _Out_ PUNICODE_STRING *ProcessImageName)
Finds the process image name of a specific process.
Definition: audit.c:199
BOOLEAN NTAPI SeSinglePrivilegeCheck(_In_ LUID PrivilegeValue, _In_ KPROCESSOR_MODE PreviousMode)
Checks if a single privilege is present in the context of the calling thread.
Definition: priv.c:744
PVOID *typedef PHANDLE
Definition: ntsecpkg.h:455
#define STATUS_PROCESS_IS_TERMINATING
Definition: ntstatus.h:596
#define STATUS_INVALID_INFO_CLASS
Definition: ntstatus.h:333
#define STATUS_PORT_ALREADY_SET
Definition: ntstatus.h:402
ULONG NTAPI ObGetProcessHandleCount(IN PEPROCESS Process)
Definition: obhandle.c:56
NTSTATUS NTAPI ObSetDeviceMap(IN PEPROCESS Process, IN HANDLE DirectoryHandle)
Definition: devicemap.c:24
ULONG NTAPI ObIsLUIDDeviceMapsEnabled(VOID)
Definition: devicemap.c:662
NTSTATUS NTAPI ObQueryDeviceMapInformation(_In_opt_ PEPROCESS Process, _Out_ PPROCESS_DEVICEMAP_INFORMATION DeviceMapInfo, _In_ ULONG Flags)
Definition: devicemap.c:539
NTSTATUS NTAPI ObCloseHandle(IN HANDLE Handle, IN KPROCESSOR_MODE AccessMode)
Definition: obhandle.c:3379
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:494
#define BOOLEAN
Definition: pedump.c:73
long LONG
Definition: pedump.c:60
char CHAR
Definition: pedump.c:57
static WCHAR Address[46]
Definition: ping.c:68
NTSTATUS NTAPI PspSetPrimaryToken(IN PEPROCESS Process, IN HANDLE TokenHandle OPTIONAL, IN PACCESS_TOKEN Token OPTIONAL)
Definition: security.c:215
NTSTATUS NTAPI PspSetQuotaLimits(_In_ PEPROCESS Process, _In_ ULONG Unused, _In_ PVOID QuotaLimits, _In_ ULONG QuotaLimitsLength, _In_ KPROCESSOR_MODE PreviousMode)
This function adjusts the working set limits of a process and sets up new quota limits when necessary...
Definition: quota.c:1045
PETHREAD NTAPI PsGetNextProcessThread(IN PEPROCESS Process, IN PETHREAD Thread OPTIONAL)
Definition: process.c:75
EPROCESS_QUOTA_BLOCK PspDefaultQuotaBlock
Definition: quota.c:16
static const INFORMATION_CLASS_INFO PsThreadInfoClass[]
Definition: ps_i.h:362
static const INFORMATION_CLASS_INFO PsProcessInfoClass[]
Definition: ps_i.h:15
FORCEINLINE VOID PspUnlockThreadSecurityShared(IN PETHREAD Thread)
Definition: ps_x.h:166
FORCEINLINE VOID PspLockThreadSecurityExclusive(IN PETHREAD Thread)
Definition: ps_x.h:177
#define PspSetCrossThreadFlag(Thread, Flag)
Definition: ps_x.h:25
FORCEINLINE VOID PspUnlockThreadSecurityExclusive(IN PETHREAD Thread)
Definition: ps_x.h:188
#define PspClearCrossThreadFlag(Thread, Flag)
Definition: ps_x.h:27
#define PspClearProcessFlag(Process, Flag)
Definition: ps_x.h:35
FORCEINLINE VOID PspLockThreadSecurityShared(IN PETHREAD Thread)
Definition: ps_x.h:155
#define PspSetProcessFlag(Process, Flag)
Definition: ps_x.h:33
struct _PROCESS_BASIC_INFORMATION * PPROCESS_BASIC_INFORMATION
struct _PROCESS_BASIC_INFORMATION PROCESS_BASIC_INFORMATION
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:204
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:104
#define _SEH2_END
Definition: pseh2_64.h:194
#define _SEH2_TRY
Definition: pseh2_64.h:93
#define _SEH2_YIELD(__stmt)
Definition: pseh2_64.h:207
NTSTATUS NTAPI PspQueryDescriptorThread(IN PETHREAD Thread, IN PVOID ThreadInformation, IN ULONG ThreadInformationLength, OUT PULONG ReturnLength OPTIONAL)
Definition: psldt.c:43
static __inline NTSTATUS ProbeAndCaptureUnicodeString(OUT PUNICODE_STRING Dest, IN KPROCESSOR_MODE CurrentMode, IN const UNICODE_STRING *UnsafeSrc)
Definition: probe.h:142
static __inline VOID ReleaseCapturedUnicodeString(IN PUNICODE_STRING CapturedString, IN KPROCESSOR_MODE CurrentMode)
Definition: probe.h:239
#define _WIN32_WINNT_WS03
Definition: sdkddkver.h:23
#define STATUS_SUCCESS
Definition: shellext.h:65
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
STDMETHOD() Next(THIS_ ULONG celt, IAssociationElement *pElement, ULONG *pceltFetched) PURE
#define TLS_MINIMUM_AVAILABLE
Definition: ntddk_ex.h:236
LARGE_INTEGER ExitTime
Definition: pstypes.h:1196
NTSTATUS ExitStatus
Definition: pstypes.h:1202
KTHREAD Tcb
Definition: pstypes.h:1192
EX_RUNDOWN_REF RundownProtect
Definition: pstypes.h:1248
PVOID Win32StartAddress
Definition: pstypes.h:1241
CLIENT_ID Cid
Definition: pstypes.h:1217
LIST_ENTRY IrpList
Definition: pstypes.h:1233
PUNICODE_STRING ThreadName
Definition: pstypes.h:1346
LARGE_INTEGER CreateTime
Definition: pstypes.h:1193
ULONG BreakOnTermination
Definition: pstypes.h:1273
ULONG HideFromDebugger
Definition: pstypes.h:1269
LARGE_INTEGER UserTime
Definition: winternl.h:2377
LARGE_INTEGER CreateTime
Definition: winternl.h:2374
LARGE_INTEGER KernelTime
Definition: winternl.h:2376
LARGE_INTEGER ExitTime
Definition: winternl.h:2375
ULONG InterruptTime
Definition: ketypes.h:834
ULONG KeSystemCalls
Definition: ketypes.h:745
GROUP_AFFINITY Affinity
Definition: ketypes.h:2066
ULONG IdealProcessor
Definition: ketypes.h:2072
ULONG DisableBoost
Definition: ketypes.h:1853
SCHAR Priority
Definition: ketypes.h:1910
PVOID Teb
Definition: ketypes.h:1935
ULONG KernelTime
Definition: ketypes.h:2115
ULONG UserTime
Definition: ketypes.h:2131
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
ULONG_PTR InheritedFromUniqueProcessId
Definition: pstypes.h:362
IO_COUNTERS IoInfo
Definition: ke.h:48
SIZE_T MaximumWorkingSetSize
Definition: pstypes.h:71
SIZE_T PagedPoolLimit
Definition: pstypes.h:68
SIZE_T PagefileLimit
Definition: pstypes.h:72
LARGE_INTEGER TimeLimit
Definition: pstypes.h:73
RATE_QUOTA_LIMIT CpuRateLimit
Definition: pstypes.h:79
SIZE_T NonPagedPoolLimit
Definition: pstypes.h:69
SIZE_T MinimumWorkingSetSize
Definition: pstypes.h:70
Definition: compat.h:836
PVOID * TlsExpansionSlots
Definition: compat.h:894
PVOID TlsSlots[64]
Definition: compat.h:879
KPRIORITY BasePriority
Definition: compat.h:932
KAFFINITY AffinityMask
Definition: compat.h:930
UNICODE_STRING ThreadName
Definition: pstypes.h:1090
USHORT MaximumLength
Definition: env_spec_w32.h:370
SIZE_T PeakWorkingSetSize
Definition: winternl.h:3134
SIZE_T PeakPagefileUsage
Definition: winternl.h:3141
ULONG PageFaultCount
Definition: winternl.h:3133
SIZE_T QuotaPagedPoolUsage
Definition: winternl.h:3137
SIZE_T QuotaPeakPagedPoolUsage
Definition: winternl.h:3136
SIZE_T QuotaPeakNonPagedPoolUsage
Definition: winternl.h:3138
SIZE_T PeakVirtualSize
Definition: winternl.h:3131
SIZE_T VirtualSize
Definition: winternl.h:3132
SIZE_T QuotaNonPagedPoolUsage
Definition: winternl.h:3139
SIZE_T WorkingSetSize
Definition: winternl.h:3135
SIZE_T PagefileUsage
Definition: winternl.h:3140
#define TAG_SEPA
Definition: tag.h:156
#define TAG_THREAD_NAME
Definition: tag.h:139
UCHAR NTAPI KeSetIdealProcessorThread(IN PKTHREAD Thread, IN UCHAR Processor)
Definition: thrdobj.c:1066
LONG NTAPI KeSetBasePriorityThread(IN PKTHREAD Thread, IN LONG Increment)
Definition: thrdobj.c:1157
KPRIORITY NTAPI KeSetPriorityThread(IN PKTHREAD Thread, IN KPRIORITY Priority)
Definition: thrdobj.c:1300
KAFFINITY NTAPI KeSetAffinityThread(IN PKTHREAD Thread, IN KAFFINITY Affinity)
Definition: thrdobj.c:1276
uint16_t * PWSTR
Definition: typedefs.h:56
uint32_t * PULONG_PTR
Definition: typedefs.h:65
uint32_t * PULONG
Definition: typedefs.h:59
unsigned char UCHAR
Definition: typedefs.h:53
unsigned char * PBOOLEAN
Definition: typedefs.h:53
int64_t LONGLONG
Definition: typedefs.h:68
#define NTAPI
Definition: typedefs.h:36
union _LARGE_INTEGER LARGE_INTEGER
void * PVOID
Definition: typedefs.h:50
PVOID HANDLE
Definition: typedefs.h:73
ULONG_PTR SIZE_T
Definition: typedefs.h:80
const char * PCSTR
Definition: typedefs.h:52
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
uint32_t ULONG_PTR
Definition: typedefs.h:65
int32_t * PLONG
Definition: typedefs.h:58
union _LARGE_INTEGER * PLARGE_INTEGER
Definition: file.c:85
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59
char CCHAR
Definition: typedefs.h:51
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define STATUS_INFO_LENGTH_MISMATCH
Definition: udferr_usr.h:133
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
static ULONG HandleCount
Definition: uefidisk.c:68
struct _LARGE_INTEGER::@2470 u
LONGLONG QuadPart
Definition: typedefs.h:114
ULONG RateData
Definition: pstypes.h:60
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:550
_In_ WDFINTERRUPT _In_ WDF_INTERRUPT_POLICY _In_ WDF_INTERRUPT_PRIORITY Priority
Definition: wdfinterrupt.h:655
BOOLEAN HasPrivilege(IN PPRIVILEGE_SET Privilege)
Definition: shutdown.c:92
struct _KERNEL_USER_TIMES KERNEL_USER_TIMES
@ ThreadSuspendCount
Definition: winternl.h:2316
@ ThreadActualGroupAffinity
Definition: winternl.h:2322
@ ThreadStrongerBadHandleChecks
Definition: winternl.h:2334
@ ThreadCpuAccountingInformation
Definition: winternl.h:2315
@ ThreadWorkOnBehalfTicket
Definition: winternl.h:2325
@ ThreadEffectiveIoPriority
Definition: winternl.h:2335
@ ThreadCreateStateChange
Definition: winternl.h:2332
@ ThreadSelectedCpuSets
Definition: winternl.h:2320
@ ThreadApplyStateChange
Definition: winternl.h:2333
@ ThreadSystemThreadInformation
Definition: winternl.h:2321
@ ThreadManageWritesToExecutableMemory
Definition: winternl.h:2329
@ ThreadDynamicCodePolicyInfo
Definition: winternl.h:2323
@ ThreadExplicitCaseSensitivity
Definition: winternl.h:2324
@ ThreadPowerThrottlingState
Definition: winternl.h:2330
@ ThreadHeterogeneousCpuPolicy
Definition: winternl.h:2317
@ ThreadEffectivePagePriority
Definition: winternl.h:2336
@ ThreadNameInformation
Definition: winternl.h:2319
@ ThreadDbgkWerReportActive
Definition: winternl.h:2327
@ ThreadSubsystemInformation
Definition: winternl.h:2326
@ ThreadAttachContainer
Definition: winternl.h:2328
@ ThreadContainerId
Definition: winternl.h:2318
@ ThreadWorkloadClass
Definition: winternl.h:2331
struct _KERNEL_USER_TIMES * PKERNEL_USER_TIMES
@ ProcessPagePriority
Definition: winternl.h:1921
@ ProcessLUIDDeviceMapsEnabled
Definition: winternl.h:1910
@ ProcessMemoryAllocationMode
Definition: winternl.h:1928
@ ProcessTlsInformation
Definition: winternl.h:1917
@ ProcessWx86Information
Definition: winternl.h:1901
@ ProcessDebugFlags
Definition: winternl.h:1913
@ ProcessConsoleHostProcess
Definition: winternl.h:1931
@ ProcessSessionInformation
Definition: winternl.h:1906
@ ProcessWorkingSetWatchEx
Definition: winternl.h:1924
@ ProcessAffinityMask
Definition: winternl.h:1903
@ ProcessInstrumentationCallback
Definition: winternl.h:1922
@ ProcessImageFileMapping
Definition: winternl.h:1926
@ ProcessIoPortHandlers
Definition: winternl.h:1895
@ ProcessRaisePriority
Definition: winternl.h:1888
@ ProcessVmCounters
Definition: winternl.h:1885
@ ProcessPriorityClass
Definition: winternl.h:1900
@ ProcessPriorityBoost
Definition: winternl.h:1904
@ ProcessImageInformation
Definition: winternl.h:1919
@ ProcessExecuteFlags
Definition: winternl.h:1916
@ ProcessCookie
Definition: winternl.h:1918
@ ProcessPooledUsageAndLimits
Definition: winternl.h:1896
@ ProcessLdtSize
Definition: winternl.h:1893
@ ProcessIoCounters
Definition: winternl.h:1884
@ ProcessImageFileNameWin32
Definition: winternl.h:1925
@ ProcessDefaultHardErrorMode
Definition: winternl.h:1894
@ ProcessAffinityUpdateMode
Definition: winternl.h:1927
@ ProcessEnableAlignmentFaultFixup
Definition: winternl.h:1899
@ ProcessDeviceMap
Definition: winternl.h:1905
@ ProcessBasePriority
Definition: winternl.h:1887
@ ProcessQuotaLimits
Definition: winternl.h:1883
@ ProcessCycleTime
Definition: winternl.h:1920
@ ProcessAccessToken
Definition: winternl.h:1891
@ ProcessIoPriority
Definition: winternl.h:1915
@ ProcessHandleTracing
Definition: winternl.h:1914
@ ProcessThreadStackAllocation
Definition: winternl.h:1923
@ ProcessForegroundInformation
Definition: winternl.h:1907
@ ProcessWindowInformation
Definition: winternl.h:1932
@ ProcessTimes
Definition: winternl.h:1886
@ ProcessDebugObjectHandle
Definition: winternl.h:1912
@ ProcessExceptionPort
Definition: winternl.h:1890
@ ProcessWorkingSetWatch
Definition: winternl.h:1897
@ ProcessGroupInformation
Definition: winternl.h:1929
@ ProcessLdtInformation
Definition: winternl.h:1892
@ ProcessHandleCount
Definition: winternl.h:1902
@ ProcessUserModeIOPL
Definition: winternl.h:1898
struct _VM_COUNTERS * PVM_COUNTERS
struct _VM_COUNTERS_EX VM_COUNTERS_EX
#define TlsIndex
Definition: ws2_32p.h:277
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
_In_opt_ PVOID _Out_ PLARGE_INTEGER Cookie
Definition: cmfuncs.h:14
_In_ ULONG _In_ ULONG _In_ ULONG _Out_ PKIRQL _Out_ PKAFFINITY Affinity
Definition: halfuncs.h:174
* PFILE_OBJECT
Definition: iotypes.h:1998
_Out_ PULONG UserTime
Definition: kefuncs.h:759
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:778
CCHAR KPROCESSOR_MODE
Definition: ketypes.h:7
#define ObDereferenceObject
Definition: obfuncs.h:203
#define ObReferenceObject
Definition: obfuncs.h:204
#define PsGetCurrentProcess
Definition: psfuncs.h:17