ReactOS 0.4.16-dev-550-g2186ce3
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
26{
27 PSECTION Section;
28 PAGED_CODE();
29
30 /* Lock the process */
31 if (!ExAcquireRundownProtection(&Process->RundownProtect))
32 {
34 }
35
36 /* Get the section */
37 Section = Process->SectionObject;
38 if (Section)
39 {
40 /* Get the file object and reference it */
43 }
44
45 /* Release the protection */
46 ExReleaseRundownProtection(&Process->RundownProtect);
47
48 /* Return status */
49 return Section ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL;
50}
51
52/* PUBLIC FUNCTIONS **********************************************************/
53
54/*
55 * @implemented
56 */
61 _In_ PROCESSINFOCLASS ProcessInformationClass,
62 _Out_ PVOID ProcessInformation,
63 _In_ ULONG ProcessInformationLength,
65{
69 ULONG Length = 0;
70
71 PAGED_CODE();
72
73 /* Verify Information Class validity */
74 Status = DefaultQueryInfoBufferCheck(ProcessInformationClass,
78 ProcessInformation,
79 ProcessInformationLength,
81 NULL,
83 if (!NT_SUCCESS(Status))
84 {
85 DPRINT1("NtQueryInformationProcess(): Information verification class failed! (Status -> 0x%lx, ProcessInformationClass -> %lx)\n", Status, ProcessInformationClass);
86 return Status;
87 }
88
89 if (((ProcessInformationClass == ProcessCookie) ||
90 (ProcessInformationClass == ProcessImageInformation)) &&
92 {
93 /*
94 * Retrieving the process cookie is only allowed for the calling process
95 * itself! XP only allows NtCurrentProcess() as process handles even if
96 * a real handle actually represents the current process.
97 */
99 }
100
101 /* Check the information class */
102 switch (ProcessInformationClass)
103 {
104 /* Basic process information */
106 {
107 PPROCESS_BASIC_INFORMATION ProcessBasicInfo = (PPROCESS_BASIC_INFORMATION)ProcessInformation;
108
109 if (ProcessInformationLength != sizeof(PROCESS_BASIC_INFORMATION))
110 {
112 break;
113 }
114
115 /* Set return length */
117
118 /* Reference the process */
123 (PVOID*)&Process,
124 NULL);
125 if (!NT_SUCCESS(Status)) break;
126
127 /* Protect writes with SEH */
129 {
130 /* Write all the information from the EPROCESS/KPROCESS */
131 ProcessBasicInfo->ExitStatus = Process->ExitStatus;
132 ProcessBasicInfo->PebBaseAddress = Process->Peb;
133 ProcessBasicInfo->AffinityMask = Process->Pcb.Affinity;
134 ProcessBasicInfo->UniqueProcessId = (ULONG_PTR)Process->
135 UniqueProcessId;
136 ProcessBasicInfo->InheritedFromUniqueProcessId =
137 (ULONG_PTR)Process->InheritedFromUniqueProcessId;
138 ProcessBasicInfo->BasePriority = Process->Pcb.BasePriority;
139
140 }
142 {
143 /* Get exception code */
145 }
146 _SEH2_END;
147
148 /* Dereference the process */
150 break;
151 }
152
153 /* Process quota limits */
155 {
156 QUOTA_LIMITS_EX QuotaLimits;
157 BOOLEAN Extended;
158
159 if (ProcessInformationLength != sizeof(QUOTA_LIMITS) &&
160 ProcessInformationLength != sizeof(QUOTA_LIMITS_EX))
161 {
163 break;
164 }
165
166 /* Set return length */
167 Length = ProcessInformationLength;
168 Extended = (Length == sizeof(QUOTA_LIMITS_EX));
169
170 /* Reference the process */
175 (PVOID*)&Process,
176 NULL);
177 if (!NT_SUCCESS(Status)) break;
178
179 /* Indicate success */
181
182 RtlZeroMemory(&QuotaLimits, sizeof(QuotaLimits));
183
184 /* Get max/min working set sizes */
185 QuotaLimits.MaximumWorkingSetSize =
186 Process->Vm.MaximumWorkingSetSize << PAGE_SHIFT;
187 QuotaLimits.MinimumWorkingSetSize =
188 Process->Vm.MinimumWorkingSetSize << PAGE_SHIFT;
189
190 /* Get default time limits */
191 QuotaLimits.TimeLimit.QuadPart = -1LL;
192
193 /* Is quota block a default one? */
194 if (Process->QuotaBlock == &PspDefaultQuotaBlock)
195 {
196 /* Get default pools and pagefile limits */
197 QuotaLimits.PagedPoolLimit = (SIZE_T)-1;
198 QuotaLimits.NonPagedPoolLimit = (SIZE_T)-1;
199 QuotaLimits.PagefileLimit = (SIZE_T)-1;
200 }
201 else
202 {
203 /* Get limits from non-default quota block */
204 QuotaLimits.PagedPoolLimit =
205 Process->QuotaBlock->QuotaEntry[PsPagedPool].Limit;
206 QuotaLimits.NonPagedPoolLimit =
207 Process->QuotaBlock->QuotaEntry[PsNonPagedPool].Limit;
208 QuotaLimits.PagefileLimit =
209 Process->QuotaBlock->QuotaEntry[PsPageFile].Limit;
210 }
211
212 /* Get additional information, if needed */
213 if (Extended)
214 {
215 QuotaLimits.Flags |= (Process->Vm.Flags.MaximumWorkingSetHard ?
217 QuotaLimits.Flags |= (Process->Vm.Flags.MinimumWorkingSetHard ?
219
220 /* FIXME: Get the correct information */
221 //QuotaLimits.WorkingSetLimit = (SIZE_T)-1; // Not used on Win2k3, it is set to 0
222 QuotaLimits.CpuRateLimit.RateData = 0;
223 }
224
225 /* Protect writes with SEH */
227 {
228 RtlCopyMemory(ProcessInformation, &QuotaLimits, Length);
229 }
231 {
232 /* Get exception code */
234 }
235 _SEH2_END;
236
237 /* Dereference the process */
239 break;
240 }
241
243 {
244 PIO_COUNTERS IoCounters = (PIO_COUNTERS)ProcessInformation;
245 PROCESS_VALUES ProcessValues;
246
247 if (ProcessInformationLength != sizeof(IO_COUNTERS))
248 {
250 break;
251 }
252
253 Length = sizeof(IO_COUNTERS);
254
255 /* Reference the process */
260 (PVOID*)&Process,
261 NULL);
262 if (!NT_SUCCESS(Status)) break;
263
264 /* Query IO counters from the process */
265 KeQueryValuesProcess(&Process->Pcb, &ProcessValues);
266
268 {
269 RtlCopyMemory(IoCounters, &ProcessValues.IoInfo, sizeof(IO_COUNTERS));
270 }
272 {
273 /* Ignore exception */
274 }
275 _SEH2_END;
276
277 /* Set status to success in any case */
279
280 /* Dereference the process */
282 break;
283 }
284
285 /* Timing */
286 case ProcessTimes:
287 {
288 PKERNEL_USER_TIMES ProcessTime = (PKERNEL_USER_TIMES)ProcessInformation;
289 ULONG UserTime, KernelTime;
290
291 /* Set the return length */
292 if (ProcessInformationLength != sizeof(KERNEL_USER_TIMES))
293 {
295 break;
296 }
297
298 Length = sizeof(KERNEL_USER_TIMES);
299
300 /* Reference the process */
305 (PVOID*)&Process,
306 NULL);
307 if (!NT_SUCCESS(Status)) break;
308
309 /* Protect writes with SEH */
311 {
312 /* Copy time information from EPROCESS/KPROCESS */
313 KernelTime = KeQueryRuntimeProcess(&Process->Pcb, &UserTime);
314 ProcessTime->CreateTime = Process->CreateTime;
316 ProcessTime->KernelTime.QuadPart = (LONGLONG)KernelTime * KeMaximumIncrement;
317 ProcessTime->ExitTime = Process->ExitTime;
318 }
320 {
321 /* Get exception code */
323 }
324 _SEH2_END;
325
326 /* Dereference the process */
328 break;
329 }
330
331 /* Process Debug Port */
332 case ProcessDebugPort:
333
334 if (ProcessInformationLength != sizeof(HANDLE))
335 {
337 break;
338 }
339
340 /* Set return length */
341 Length = sizeof(HANDLE);
342
343 /* Reference the process */
348 (PVOID*)&Process,
349 NULL);
350 if (!NT_SUCCESS(Status)) break;
351
352 /* Protect write with SEH */
354 {
355 /* Return whether or not we have a debug port */
356 *(PHANDLE)ProcessInformation = (Process->DebugPort ?
357 (HANDLE)-1 : NULL);
358 }
360 {
361 /* Get exception code */
363 }
364 _SEH2_END;
365
366 /* Dereference the process */
368 break;
369
371 {
372 ULONG HandleCount;
373
374 if (ProcessInformationLength != sizeof(ULONG))
375 {
377 break;
378 }
379
380 /* Set the return length*/
381 Length = sizeof(ULONG);
382
383 /* Reference the process */
388 (PVOID*)&Process,
389 NULL);
390 if (!NT_SUCCESS(Status)) break;
391
392 /* Count the number of handles this process has */
393 HandleCount = ObGetProcessHandleCount(Process);
394
395 /* Protect write in SEH */
397 {
398 /* Return the count of handles */
399 *(PULONG)ProcessInformation = HandleCount;
400 }
402 {
403 /* Get the exception code */
405 }
406 _SEH2_END;
407
408 /* Dereference the process */
410 break;
411 }
412
413 /* Session ID for the process */
415 {
417
418 if (ProcessInformationLength != sizeof(PROCESS_SESSION_INFORMATION))
419 {
421 break;
422 }
423
424 /* Set the return length*/
426
427 /* Reference the process */
432 (PVOID*)&Process,
433 NULL);
434 if (!NT_SUCCESS(Status)) break;
435
436 /* Enter SEH for write safety */
438 {
439 /* Write back the Session ID */
441 }
443 {
444 /* Get the exception code */
446 }
447 _SEH2_END;
448
449 /* Dereference the process */
451 break;
452 }
453
454 /* Virtual Memory Statistics */
456 {
457 PVM_COUNTERS VmCounters = (PVM_COUNTERS)ProcessInformation;
458
459 /* Validate the input length */
460 if ((ProcessInformationLength != sizeof(VM_COUNTERS)) &&
461 (ProcessInformationLength != sizeof(VM_COUNTERS_EX)))
462 {
464 break;
465 }
466
467 /* Reference the process */
472 (PVOID*)&Process,
473 NULL);
474 if (!NT_SUCCESS(Status)) break;
475
476 /* Enter SEH for write safety */
478 {
479 /* Return data from EPROCESS */
480 VmCounters->PeakVirtualSize = Process->PeakVirtualSize;
481 VmCounters->VirtualSize = Process->VirtualSize;
482 VmCounters->PageFaultCount = Process->Vm.PageFaultCount;
483 VmCounters->PeakWorkingSetSize = Process->Vm.PeakWorkingSetSize;
484 VmCounters->WorkingSetSize = Process->Vm.WorkingSetSize;
485 VmCounters->QuotaPeakPagedPoolUsage = Process->QuotaPeak[PsPagedPool];
486 VmCounters->QuotaPagedPoolUsage = Process->QuotaUsage[PsPagedPool];
487 VmCounters->QuotaPeakNonPagedPoolUsage = Process->QuotaPeak[PsNonPagedPool];
488 VmCounters->QuotaNonPagedPoolUsage = Process->QuotaUsage[PsNonPagedPool];
489 VmCounters->PagefileUsage = Process->QuotaUsage[PsPageFile] << PAGE_SHIFT;
490 VmCounters->PeakPagefileUsage = Process->QuotaPeak[PsPageFile] << PAGE_SHIFT;
491 //VmCounters->PrivateUsage = Process->CommitCharge << PAGE_SHIFT;
492 //
493
494 /* Set the return length */
495 Length = ProcessInformationLength;
496 }
498 {
499 /* Get the exception code */
501 }
502 _SEH2_END;
503
504 /* Dereference the process */
506 break;
507 }
508
509 /* Hard Error Processing Mode */
511
512 if (ProcessInformationLength != sizeof(ULONG))
513 {
515 break;
516 }
517
518 /* Set the return length*/
519 Length = sizeof(ULONG);
520
521 /* Reference the process */
526 (PVOID*)&Process,
527 NULL);
528 if (!NT_SUCCESS(Status)) break;
529
530 /* Enter SEH for writing back data */
532 {
533 /* Write the current processing mode */
534 *(PULONG)ProcessInformation = Process->
535 DefaultHardErrorProcessing;
536 }
538 {
539 /* Get the exception code */
541 }
542 _SEH2_END;
543
544 /* Dereference the process */
546 break;
547
548 /* Priority Boosting status */
550
551 if (ProcessInformationLength != sizeof(ULONG))
552 {
554 break;
555 }
556
557 /* Set the return length */
558 Length = sizeof(ULONG);
559
560 /* Reference the process */
565 (PVOID*)&Process,
566 NULL);
567 if (!NT_SUCCESS(Status)) break;
568
569 /* Enter SEH for writing back data */
571 {
572 /* Return boost status */
573 *(PULONG)ProcessInformation = Process->Pcb.DisableBoost ?
574 TRUE : FALSE;
575 }
577 {
578 /* Get the exception code */
580 }
581 _SEH2_END;
582
583 /* Dereference the process */
585 break;
586
587 /* DOS Device Map */
588 case ProcessDeviceMap:
589 {
590 ULONG Flags;
591
592 if (ProcessInformationLength == sizeof(PROCESS_DEVICEMAP_INFORMATION_EX))
593 {
594 /* Protect read in SEH */
596 {
597 PPROCESS_DEVICEMAP_INFORMATION_EX DeviceMapEx = ProcessInformation;
598
599 Flags = DeviceMapEx->Flags;
600 }
602 {
603 /* Get the exception code */
605 _SEH2_YIELD(break);
606 }
607 _SEH2_END;
608
609 /* Only one flag is supported and it needs LUID mappings */
610 if ((Flags & ~PROCESS_LUID_DOSDEVICES_ONLY) != 0 ||
612 {
614 break;
615 }
616 }
617 else
618 {
619 /* This has to be the size of the Query union field for x64 compatibility! */
620 if (ProcessInformationLength != RTL_FIELD_SIZE(PROCESS_DEVICEMAP_INFORMATION, Query))
621 {
623 break;
624 }
625
626 /* No flags for standard call */
627 Flags = 0;
628 }
629
630 /* Set the return length */
631 Length = ProcessInformationLength;
632
633 /* Reference the process */
638 (PVOID*)&Process,
639 NULL);
640 if (!NT_SUCCESS(Status)) break;
641
642 /* Query the device map information */
644 ProcessInformation,
645 Flags);
646
647 /* Dereference the process */
649 break;
650 }
651
652 /* Priority class */
654 {
655 PPROCESS_PRIORITY_CLASS PsPriorityClass = (PPROCESS_PRIORITY_CLASS)ProcessInformation;
656
657 if (ProcessInformationLength != sizeof(PROCESS_PRIORITY_CLASS))
658 {
660 break;
661 }
662
663 /* Set the return length*/
665
666 /* Reference the process */
671 (PVOID*)&Process,
672 NULL);
673 if (!NT_SUCCESS(Status)) break;
674
675 /* Enter SEH for writing back data */
677 {
678 /* Return current priority class */
679 PsPriorityClass->PriorityClass = Process->PriorityClass;
680 PsPriorityClass->Foreground = FALSE;
681 }
683 {
684 /* Get the exception code */
686 }
687 _SEH2_END;
688
689 /* Dereference the process */
691 break;
692 }
693
695 {
697
698 /* Reference the process */
703 (PVOID*)&Process,
704 NULL);
705 if (!NT_SUCCESS(Status)) break;
706
707 /* Get the image path */
709 if (NT_SUCCESS(Status))
710 {
711 /* Set return length */
712 Length = ImageName->MaximumLength +
714
715 /* Make sure it's large enough */
716 if (Length <= ProcessInformationLength)
717 {
718 /* Enter SEH to protect write */
720 {
721 /* Copy it */
722 RtlCopyMemory(ProcessInformation,
723 ImageName,
724 Length);
725
726 /* Update pointer */
727 ((PUNICODE_STRING)ProcessInformation)->Buffer =
728 (PWSTR)((PUNICODE_STRING)ProcessInformation + 1);
729 }
731 {
732 /* Get the exception code */
734 }
735 _SEH2_END;
736 }
737 else
738 {
739 /* Buffer too small */
741 }
742
743 /* Free the image path */
745 }
746 /* Dereference the process */
748 break;
749 }
750
752
753 if (ProcessInformationLength != sizeof(ULONG))
754 {
756 break;
757 }
758
759 /* Set the return length*/
760 Length = sizeof(ULONG);
761
762 /* Reference the process */
767 (PVOID*)&Process,
768 NULL);
769 if (!NT_SUCCESS(Status)) break;
770
771 /* Enter SEH for writing back data */
773 {
774 /* Return the debug flag state */
775 *(PULONG)ProcessInformation = Process->NoDebugInherit ? 0 : 1;
776 }
778 {
779 /* Get the exception code */
781 }
782 _SEH2_END;
783
784 /* Dereference the process */
786 break;
787
789
790 if (ProcessInformationLength != sizeof(ULONG))
791 {
793 break;
794 }
795
796 /* Set the return length */
797 Length = sizeof(ULONG);
798
799 /* Reference the process */
804 (PVOID*)&Process,
805 NULL);
806 if (!NT_SUCCESS(Status)) break;
807
808 /* Enter SEH for writing back data */
810 {
811 /* Return the BreakOnTermination state */
812 *(PULONG)ProcessInformation = Process->BreakOnTermination;
813 }
815 {
816 /* Get the exception code */
818 }
819 _SEH2_END;
820
821 /* Dereference the process */
823 break;
824
825 /* Per-process security cookie */
826 case ProcessCookie:
827 {
829
830 if (ProcessInformationLength != sizeof(ULONG))
831 {
832 /* Length size wrong, bail out */
834 break;
835 }
836
837 /* Get the current process and cookie */
839 Cookie = Process->Cookie;
840 if (!Cookie)
841 {
842 LARGE_INTEGER SystemTime;
843 ULONG NewCookie;
844 PKPRCB Prcb;
845
846 /* Generate a new cookie */
847 KeQuerySystemTime(&SystemTime);
848 Prcb = KeGetCurrentPrcb();
849 NewCookie = Prcb->KeSystemCalls ^ Prcb->InterruptTime ^
850 SystemTime.u.LowPart ^ SystemTime.u.HighPart;
851
852 /* Set the new cookie or return the current one */
854 NewCookie,
855 Cookie);
856 if (!Cookie) Cookie = NewCookie;
857
858 /* Set return length */
859 Length = sizeof(ULONG);
860 }
861
862 /* Indicate success */
864
865 /* Enter SEH to protect write */
867 {
868 /* Write back the cookie */
869 *(PULONG)ProcessInformation = Cookie;
870 }
872 {
873 /* Get the exception code */
875 }
876 _SEH2_END;
877 break;
878 }
879
881
882 if (ProcessInformationLength != sizeof(SECTION_IMAGE_INFORMATION))
883 {
884 /* Break out */
886 break;
887 }
888
889 /* Set the length required and validate it */
891
892 /* Enter SEH to protect write */
894 {
896 }
898 {
899 /* Get the exception code */
901 }
902 _SEH2_END;
903
904 /* Indicate success */
906 break;
907
909 {
910 HANDLE DebugPort = 0;
911
912 if (ProcessInformationLength != sizeof(HANDLE))
913 {
915 break;
916 }
917
918 /* Set the return length */
919 Length = sizeof(HANDLE);
920
921 /* Reference the process */
926 (PVOID*)&Process,
927 NULL);
928 if (!NT_SUCCESS(Status)) break;
929
930 /* Get the debug port */
932
933 /* Let go of the process */
935
936 /* Protect write in SEH */
938 {
939 /* Return debug port's handle */
940 *(PHANDLE)ProcessInformation = DebugPort;
941 }
943 {
944 /* Get the exception code */
946 }
947 _SEH2_END;
948 break;
949 }
950
952 DPRINT1("Handle tracing Not implemented: %lx\n", ProcessInformationClass);
954 break;
955
957
958 if (ProcessInformationLength != sizeof(ULONG))
959 {
961 break;
962 }
963
964 /* Set the return length */
965 Length = sizeof(ULONG);
966
967 /* Indicate success */
969
970 /* Protect write in SEH */
972 {
973 /* Query Ob */
974 *(PULONG)ProcessInformation = ObIsLUIDDeviceMapsEnabled();
975 }
977 {
978 /* Get the exception code */
980 }
981 _SEH2_END;
982 break;
983
985
986 if (ProcessInformationLength != sizeof(ULONG))
987 {
989 break;
990 }
991
992 /* Set the return length */
993 Length = sizeof(ULONG);
994
995 /* Reference the process */
1000 (PVOID*)&Process,
1001 NULL);
1002 if (!NT_SUCCESS(Status)) break;
1003
1004 /* Protect write in SEH */
1005 _SEH2_TRY
1006 {
1007 /* Return if the flag is set */
1008 *(PULONG)ProcessInformation = (ULONG)Process->VdmAllowed;
1009 }
1011 {
1012 /* Get the exception code */
1014 }
1015 _SEH2_END;
1016
1017 /* Dereference the process */
1019 break;
1020
1022 {
1023 ULONG_PTR Wow64 = 0;
1024
1025 if (ProcessInformationLength != sizeof(ULONG_PTR))
1026 {
1028 break;
1029 }
1030
1031 /* Set return length */
1032 Length = sizeof(ULONG_PTR);
1033
1034 /* Reference the process */
1039 (PVOID*)&Process,
1040 NULL);
1041 if (!NT_SUCCESS(Status)) break;
1042
1043 /* Make sure the process isn't dying */
1044 if (ExAcquireRundownProtection(&Process->RundownProtect))
1045 {
1046 /* Get the WOW64 process structure */
1047#ifdef _WIN64
1048 Wow64 = (ULONG_PTR)Process->Wow64Process;
1049#else
1050 Wow64 = 0;
1051#endif
1052 /* Release the lock */
1053 ExReleaseRundownProtection(&Process->RundownProtect);
1054 }
1055
1056 /* Protect write with SEH */
1057 _SEH2_TRY
1058 {
1059 /* Return whether or not we have a debug port */
1060 *(PULONG_PTR)ProcessInformation = Wow64;
1061 }
1063 {
1064 /* Get exception code */
1066 }
1067 _SEH2_END;
1068
1069 /* Dereference the process */
1071 break;
1072 }
1073
1075 {
1076 ULONG ExecuteOptions = 0;
1077
1078 if (ProcessInformationLength != sizeof(ULONG))
1079 {
1081 break;
1082 }
1083
1084 /* Set return length */
1085 Length = sizeof(ULONG);
1086
1088 {
1090 }
1091
1092 /* Get the options */
1093 Status = MmGetExecuteOptions(&ExecuteOptions);
1094 if (NT_SUCCESS(Status))
1095 {
1096 /* Protect write with SEH */
1097 _SEH2_TRY
1098 {
1099 /* Return them */
1100 *(PULONG)ProcessInformation = ExecuteOptions;
1101 }
1103 {
1104 /* Get exception code */
1106 }
1107 _SEH2_END;
1108 }
1109 break;
1110 }
1111
1113 DPRINT1("VDM/16-bit not implemented: %lx\n", ProcessInformationClass);
1115 break;
1116
1118 DPRINT1("WS Watch Not implemented: %lx\n", ProcessInformationClass);
1120 break;
1121
1123 DPRINT1("Pool limits Not implemented: %lx\n", ProcessInformationClass);
1125 break;
1126
1127 /* Not supported by Server 2003 */
1128 default:
1129 DPRINT1("Unsupported info class: %lx\n", ProcessInformationClass);
1131 }
1132
1133 /* Protect write with SEH */
1134 _SEH2_TRY
1135 {
1136 /* Check if caller wanted return length */
1137 if ((ReturnLength) && (Length)) *ReturnLength = Length;
1138 }
1140 {
1141 /* Get exception code */
1143 }
1144 _SEH2_END;
1145
1146 return Status;
1147}
1148
1149/*
1150 * @implemented
1151 */
1153NTAPI
1155 IN PROCESSINFOCLASS ProcessInformationClass,
1156 IN PVOID ProcessInformation,
1157 IN ULONG ProcessInformationLength)
1158{
1161 ACCESS_MASK Access;
1163 HANDLE PortHandle = NULL;
1167 PROCESS_PRIORITY_CLASS PriorityClass = {0};
1168 PROCESS_FOREGROUND_BACKGROUND Foreground = {0};
1169 PVOID ExceptionPort;
1170 ULONG Break;
1171 KAFFINITY ValidAffinity, Affinity = 0;
1172 KPRIORITY BasePriority = 0;
1173 UCHAR MemoryPriority = 0;
1174 BOOLEAN DisableBoost = 0;
1175 ULONG DefaultHardErrorMode = 0;
1176 ULONG DebugFlags = 0, EnableFixup = 0, Boost = 0;
1177 ULONG NoExecute = 0, VdmPower = 0;
1179 PLIST_ENTRY Next;
1181 PAGED_CODE();
1182
1183 /* Verify Information Class validity */
1184 Status = DefaultSetInfoBufferCheck(ProcessInformationClass,
1187 ProcessInformation,
1188 ProcessInformationLength,
1189 PreviousMode);
1190 if (!NT_SUCCESS(Status))
1191 {
1192 DPRINT1("NtSetInformationProcess(): Information verification class failed! (Status -> 0x%lx, ProcessInformationClass -> %lx)\n", Status, ProcessInformationClass);
1193 return Status;
1194 }
1195
1196 /* Check what class this is */
1197 Access = PROCESS_SET_INFORMATION;
1198 if (ProcessInformationClass == ProcessSessionInformation)
1199 {
1200 /* Setting the Session ID needs a special mask */
1201 Access |= PROCESS_SET_SESSIONID;
1202 }
1203 else if (ProcessInformationClass == ProcessExceptionPort)
1204 {
1205 /* Setting the exception port needs a special mask */
1206 Access |= PROCESS_SUSPEND_RESUME;
1207 }
1208
1209 /* Reference the process */
1211 Access,
1214 (PVOID*)&Process,
1215 NULL);
1216 if (!NT_SUCCESS(Status)) return Status;
1217
1218 /* Check what kind of information class this is */
1219 switch (ProcessInformationClass)
1220 {
1222
1223 /* Check buffer length */
1224 if (ProcessInformationLength != sizeof(ULONG))
1225 {
1227 break;
1228 }
1229
1230 /* Use SEH for capture */
1231 _SEH2_TRY
1232 {
1233 /* Capture the boolean */
1234 VdmPower = *(PULONG)ProcessInformation;
1235 }
1237 {
1238 /* Get the exception code */
1240 _SEH2_YIELD(break);
1241 }
1242 _SEH2_END;
1243
1244 /* Getting VDM powers requires the SeTcbPrivilege */
1246 {
1247 /* We don't hold the privilege, bail out */
1249 DPRINT1("Need TCB privilege\n");
1250 break;
1251 }
1252
1253 /* Set or clear the flag */
1254 if (VdmPower)
1255 {
1257 }
1258 else
1259 {
1261 }
1262 break;
1263
1264 /* Error/Exception Port */
1266
1267 /* Check buffer length */
1268 if (ProcessInformationLength != sizeof(HANDLE))
1269 {
1271 break;
1272 }
1273
1274 /* Use SEH for capture */
1275 _SEH2_TRY
1276 {
1277 /* Capture the handle */
1278 PortHandle = *(PHANDLE)ProcessInformation;
1279 }
1281 {
1282 /* Get the exception code */
1284 _SEH2_YIELD(break);
1285 }
1286 _SEH2_END;
1287
1288 /* Setting the error port requires the SeTcbPrivilege */
1290 {
1291 /* We don't hold the privilege, bail out */
1293 break;
1294 }
1295
1296 /* Get the LPC Port */
1297 Status = ObReferenceObjectByHandle(PortHandle,
1298 0,
1301 (PVOID)&ExceptionPort,
1302 NULL);
1303 if (!NT_SUCCESS(Status)) break;
1304
1305 /* Change the pointer */
1306 if (InterlockedCompareExchangePointer(&Process->ExceptionPort,
1307 ExceptionPort,
1308 NULL))
1309 {
1310 /* We already had one, fail */
1311 ObDereferenceObject(ExceptionPort);
1313 }
1314 break;
1315
1316 /* Security Token */
1317 case ProcessAccessToken:
1318
1319 /* Check buffer length */
1320 if (ProcessInformationLength != sizeof(PROCESS_ACCESS_TOKEN))
1321 {
1323 break;
1324 }
1325
1326 /* Use SEH for capture */
1327 _SEH2_TRY
1328 {
1329 /* Save the token handle */
1330 TokenHandle = ((PPROCESS_ACCESS_TOKEN)ProcessInformation)->
1331 Token;
1332 }
1334 {
1335 /* Get the exception code */
1337 _SEH2_YIELD(break);
1338 }
1339 _SEH2_END;
1340
1341 /* Assign the actual token */
1343 break;
1344
1345 /* Hard error processing */
1347
1348 /* Check buffer length */
1349 if (ProcessInformationLength != sizeof(ULONG))
1350 {
1352 break;
1353 }
1354
1355 /* Enter SEH for direct buffer read */
1356 _SEH2_TRY
1357 {
1358 DefaultHardErrorMode = *(PULONG)ProcessInformation;
1359 }
1361 {
1362 /* Get exception code */
1364 _SEH2_YIELD(break);
1365 }
1366 _SEH2_END;
1367
1368 /* Set the mode */
1369 Process->DefaultHardErrorProcessing = DefaultHardErrorMode;
1370
1371 /* Call Ke for the update */
1372 if (DefaultHardErrorMode & SEM_NOALIGNMENTFAULTEXCEPT)
1373 {
1375 }
1376 else
1377 {
1379 }
1381 break;
1382
1383 /* Session ID */
1385
1386 /* Check buffer length */
1387 if (ProcessInformationLength != sizeof(PROCESS_SESSION_INFORMATION))
1388 {
1390 break;
1391 }
1392
1393 /* Enter SEH for capture */
1394 _SEH2_TRY
1395 {
1396 /* Capture the caller's buffer */
1397 SessionInfo = *(PPROCESS_SESSION_INFORMATION)ProcessInformation;
1398 }
1400 {
1401 /* Get the exception code */
1403 _SEH2_YIELD(break);
1404 }
1405 _SEH2_END;
1406
1407 /* Setting the session id requires the SeTcbPrivilege */
1409 {
1410 /* We don't hold the privilege, bail out */
1412 break;
1413 }
1414
1415#if 0 // OLD AND DEPRECATED CODE!!!!
1416
1417 /* FIXME - update the session id for the process token */
1418 //Status = PsLockProcess(Process, FALSE);
1419 if (!NT_SUCCESS(Status)) break;
1420
1421 /* Write the session ID in the EPROCESS */
1422 Process->Session = UlongToPtr(SessionInfo.SessionId); // HACK!!!
1423
1424 /* Check if the process also has a PEB */
1425 if (Process->Peb)
1426 {
1427 /*
1428 * Attach to the process to make sure we're in the right
1429 * context to access the PEB structure
1430 */
1431 KeAttachProcess(&Process->Pcb);
1432
1433 /* Enter SEH for write to user-mode PEB */
1434 _SEH2_TRY
1435 {
1436 /* Write the session ID */
1437 Process->Peb->SessionId = SessionInfo.SessionId;
1438 }
1440 {
1441 /* Get exception code */
1443 }
1444 _SEH2_END;
1445
1446 /* Detach from the process */
1448 }
1449
1450 /* Unlock the process */
1451 //PsUnlockProcess(Process);
1452
1453#endif
1454
1455 /*
1456 * Since we cannot change the session ID of the given
1457 * process anymore because it is set once and for all
1458 * at process creation time and because it is stored
1459 * inside the Process->Session structure managed by MM,
1460 * we fake changing it: we just return success if the
1461 * user-defined value is the same as the session ID of
1462 * the process, and otherwise we fail.
1463 */
1464 if (SessionInfo.SessionId == PsGetProcessSessionId(Process))
1465 {
1467 }
1468 else
1469 {
1471 }
1472
1473 break;
1474
1476
1477 /* Check buffer length */
1478 if (ProcessInformationLength != sizeof(PROCESS_PRIORITY_CLASS))
1479 {
1481 break;
1482 }
1483
1484 /* Enter SEH for capture */
1485 _SEH2_TRY
1486 {
1487 /* Capture the caller's buffer */
1488 PriorityClass = *(PPROCESS_PRIORITY_CLASS)ProcessInformation;
1489 }
1491 {
1492 /* Return the exception code */
1494 _SEH2_YIELD(break);
1495 }
1496 _SEH2_END;
1497
1498 /* Check for invalid PriorityClass value */
1500 {
1502 break;
1503 }
1504
1505 if ((PriorityClass.PriorityClass != Process->PriorityClass) &&
1507 {
1508 /* Check the privilege */
1512 PreviousMode);
1513 if (!HasPrivilege)
1514 {
1516 DPRINT1("Privilege to change priority to realtime lacking\n");
1518 }
1519 }
1520
1521 /* Check if we have a job */
1522 if (Process->Job)
1523 {
1524 DPRINT1("Jobs not yet supported\n");
1525 }
1526
1527 /* Set process priority class */
1528 Process->PriorityClass = PriorityClass.PriorityClass;
1529
1530 /* Set process priority mode (foreground or background) */
1532 PriorityClass.Foreground ?
1536 break;
1537
1539
1540 /* Check buffer length */
1541 if (ProcessInformationLength != sizeof(PROCESS_FOREGROUND_BACKGROUND))
1542 {
1544 break;
1545 }
1546
1547 /* Enter SEH for capture */
1548 _SEH2_TRY
1549 {
1550 /* Capture the caller's buffer */
1551 Foreground = *(PPROCESS_FOREGROUND_BACKGROUND)ProcessInformation;
1552 }
1554 {
1555 /* Return the exception code */
1557 _SEH2_YIELD(break);
1558 }
1559 _SEH2_END;
1560
1561 /* Set process priority mode (foreground or background) */
1563 Foreground.Foreground ?
1567 break;
1568
1570
1571 /* Validate input length */
1572 if (ProcessInformationLength != sizeof(KPRIORITY))
1573 {
1575 break;
1576 }
1577
1578 /* Enter SEH for direct buffer read */
1579 _SEH2_TRY
1580 {
1581 BasePriority = *(KPRIORITY*)ProcessInformation;
1582 }
1584 {
1585 /* Get exception code */
1586 Break = 0;
1588 _SEH2_YIELD(break);
1589 }
1590 _SEH2_END;
1591
1592 /* Extract the memory priority out of there */
1593 if (BasePriority & 0x80000000)
1594 {
1595 MemoryPriority = MEMORY_PRIORITY_FOREGROUND;
1596 BasePriority &= ~0x80000000;
1597 }
1598 else
1599 {
1600 MemoryPriority = MEMORY_PRIORITY_BACKGROUND;
1601 }
1602
1603 /* Validate the number */
1604 if ((BasePriority > HIGH_PRIORITY) || (BasePriority <= LOW_PRIORITY))
1605 {
1608 }
1609
1610 /* Check if the new base is higher */
1611 if (BasePriority > Process->Pcb.BasePriority)
1612 {
1616 PreviousMode);
1617 if (!HasPrivilege)
1618 {
1620 DPRINT1("Privilege to change priority from %lx to %lx lacking\n", BasePriority, Process->Pcb.BasePriority);
1622 }
1623 }
1624
1625 /* Call Ke */
1626 KeSetPriorityAndQuantumProcess(&Process->Pcb, BasePriority, 0);
1627
1628 /* Now set the memory priority */
1629 MmSetMemoryPriorityProcess(Process, MemoryPriority);
1631 break;
1632
1634
1635 /* Validate input length */
1636 if (ProcessInformationLength != sizeof(ULONG))
1637 {
1639 break;
1640 }
1641
1642 /* Enter SEH for direct buffer read */
1643 _SEH2_TRY
1644 {
1645 Boost = *(PULONG)ProcessInformation;
1646 }
1648 {
1649 /* Get exception code */
1650 Break = 0;
1652 _SEH2_YIELD(break);
1653 }
1654 _SEH2_END;
1655
1656 /* Make sure the process isn't dying */
1657 if (ExAcquireRundownProtection(&Process->RundownProtect))
1658 {
1659 /* Lock it */
1661 ExAcquirePushLockShared(&Process->ProcessLock);
1662
1663 /* Loop the threads */
1664 for (Next = Process->ThreadListHead.Flink;
1665 Next != &Process->ThreadListHead;
1666 Next = Next->Flink)
1667 {
1668 /* Call Ke for the thread */
1669 Thread = CONTAINING_RECORD(Next, ETHREAD, ThreadListEntry);
1671 }
1672
1673 /* Release the lock and rundown */
1674 ExReleasePushLockShared(&Process->ProcessLock);
1676 ExReleaseRundownProtection(&Process->RundownProtect);
1677
1678 /* Set success code */
1680 }
1681 else
1682 {
1683 /* Avoid race conditions */
1685 }
1686 break;
1687
1689
1690 /* Check buffer length */
1691 if (ProcessInformationLength != sizeof(ULONG))
1692 {
1694 break;
1695 }
1696
1697 /* Enter SEH for direct buffer read */
1698 _SEH2_TRY
1699 {
1700 Break = *(PULONG)ProcessInformation;
1701 }
1703 {
1704 /* Get exception code */
1705 Break = 0;
1707 _SEH2_YIELD(break);
1708 }
1709 _SEH2_END;
1710
1711 /* Setting 'break on termination' requires the SeDebugPrivilege */
1713 {
1714 /* We don't hold the privilege, bail out */
1716 break;
1717 }
1718
1719 /* Set or clear the flag */
1720 if (Break)
1721 {
1723 }
1724 else
1725 {
1727 }
1728
1729 break;
1730
1732
1733 /* Check buffer length */
1734 if (ProcessInformationLength != sizeof(KAFFINITY))
1735 {
1737 break;
1738 }
1739
1740 /* Enter SEH for direct buffer read */
1741 _SEH2_TRY
1742 {
1743 Affinity = *(PKAFFINITY)ProcessInformation;
1744 }
1746 {
1747 /* Get exception code */
1748 Break = 0;
1750 _SEH2_YIELD(break);
1751 }
1752 _SEH2_END;
1753
1754 /* Make sure it's valid for the CPUs present */
1755 ValidAffinity = Affinity & KeActiveProcessors;
1756 if (!Affinity || (ValidAffinity != Affinity))
1757 {
1759 break;
1760 }
1761
1762 /* Check if it's within job affinity limits */
1763 if (Process->Job)
1764 {
1765 /* Not yet implemented */
1768 break;
1769 }
1770
1771 /* Make sure the process isn't dying */
1772 if (ExAcquireRundownProtection(&Process->RundownProtect))
1773 {
1774 /* Lock it */
1776 ExAcquirePushLockShared(&Process->ProcessLock);
1777
1778 /* Call Ke to do the work */
1779 KeSetAffinityProcess(&Process->Pcb, ValidAffinity);
1780
1781 /* Release the lock and rundown */
1782 ExReleasePushLockShared(&Process->ProcessLock);
1784 ExReleaseRundownProtection(&Process->RundownProtect);
1785
1786 /* Set success code */
1788 }
1789 else
1790 {
1791 /* Avoid race conditions */
1793 }
1794 break;
1795
1796 /* Priority Boosting status */
1798
1799 /* Validate input length */
1800 if (ProcessInformationLength != sizeof(ULONG))
1801 {
1803 break;
1804 }
1805
1806 /* Enter SEH for direct buffer read */
1807 _SEH2_TRY
1808 {
1809 DisableBoost = *(PBOOLEAN)ProcessInformation;
1810 }
1812 {
1813 /* Get exception code */
1814 Break = 0;
1816 _SEH2_YIELD(break);
1817 }
1818 _SEH2_END;
1819
1820 /* Make sure the process isn't dying */
1821 if (ExAcquireRundownProtection(&Process->RundownProtect))
1822 {
1823 /* Lock it */
1825 ExAcquirePushLockShared(&Process->ProcessLock);
1826
1827 /* Call Ke to do the work */
1828 KeSetDisableBoostProcess(&Process->Pcb, DisableBoost);
1829
1830 /* Loop the threads too */
1831 for (Next = Process->ThreadListHead.Flink;
1832 Next != &Process->ThreadListHead;
1833 Next = Next->Flink)
1834 {
1835 /* Call Ke for the thread */
1836 Thread = CONTAINING_RECORD(Next, ETHREAD, ThreadListEntry);
1837 KeSetDisableBoostThread(&Thread->Tcb, DisableBoost);
1838 }
1839
1840 /* Release the lock and rundown */
1841 ExReleasePushLockShared(&Process->ProcessLock);
1843 ExReleaseRundownProtection(&Process->RundownProtect);
1844
1845 /* Set success code */
1847 }
1848 else
1849 {
1850 /* Avoid race conditions */
1852 }
1853 break;
1854
1855 case ProcessDebugFlags:
1856
1857 /* Check buffer length */
1858 if (ProcessInformationLength != sizeof(ULONG))
1859 {
1861 break;
1862 }
1863
1864 /* Enter SEH for direct buffer read */
1865 _SEH2_TRY
1866 {
1867 DebugFlags = *(PULONG)ProcessInformation;
1868 }
1870 {
1871 /* Get exception code */
1873 _SEH2_YIELD(break);
1874 }
1875 _SEH2_END;
1876
1877 /* Set the mode */
1878 if (DebugFlags & ~1)
1879 {
1881 }
1882 else
1883 {
1884 if (DebugFlags & 1)
1885 {
1887 }
1888 else
1889 {
1891 }
1892 }
1893
1894 /* Done */
1896 break;
1897
1899
1900 /* Check buffer length */
1901 if (ProcessInformationLength != sizeof(BOOLEAN))
1902 {
1904 break;
1905 }
1906
1907 /* Enter SEH for direct buffer read */
1908 _SEH2_TRY
1909 {
1910 EnableFixup = *(PULONG)ProcessInformation;
1911 }
1913 {
1914 /* Get exception code */
1916 _SEH2_YIELD(break);
1917 }
1918 _SEH2_END;
1919
1920 /* Set the mode */
1921 if (EnableFixup)
1922 {
1923 Process->DefaultHardErrorProcessing |= SEM_NOALIGNMENTFAULTEXCEPT;
1924 }
1925 else
1926 {
1927 Process->DefaultHardErrorProcessing &= ~SEM_NOALIGNMENTFAULTEXCEPT;
1928 }
1929
1930 /* Call Ke for the update */
1933 break;
1934
1936
1937 /* Only TCB can do this */
1939 {
1940 /* We don't hold the privilege, bail out */
1941 DPRINT1("Need TCB to set IOPL\n");
1943 break;
1944 }
1945
1946 /* Only supported on x86 */
1947#if defined (_X86_)
1948 Ke386SetIOPL();
1949#elif defined(_M_AMD64)
1950 /* On x64 this function isn't implemented.
1951 On Windows 2003 it returns success.
1952 On Vista+ it returns STATUS_NOT_IMPLEMENTED. */
1953 if ((ExGetPreviousMode() != KernelMode) &&
1954 (RtlRosGetAppcompatVersion() > _WIN32_WINNT_WS03))
1955 {
1957 }
1958#else
1960#endif
1961 /* Done */
1962 break;
1963
1965
1966 /* Check buffer length */
1967 if (ProcessInformationLength != sizeof(ULONG))
1968 {
1970 break;
1971 }
1972
1974 {
1976 break;
1977 }
1978
1979 /* Enter SEH for direct buffer read */
1980 _SEH2_TRY
1981 {
1982 NoExecute = *(PULONG)ProcessInformation;
1983 }
1985 {
1986 /* Get exception code */
1988 _SEH2_YIELD(break);
1989 }
1990 _SEH2_END;
1991
1992 /* Call Mm for the update */
1993 Status = MmSetExecuteOptions(NoExecute);
1994 break;
1995
1996 case ProcessDeviceMap:
1997
1998 /* Check buffer length */
1999 if (ProcessInformationLength != sizeof(HANDLE))
2000 {
2002 break;
2003 }
2004
2005 /* Use SEH for capture */
2006 _SEH2_TRY
2007 {
2008 /* Capture the handle */
2009 DirectoryHandle = *(PHANDLE)ProcessInformation;
2010 }
2012 {
2013 /* Get the exception code */
2015 _SEH2_YIELD(break);
2016 }
2017 _SEH2_END;
2018
2019 /* Call Ob to set the device map */
2021 break;
2022
2023
2024 /* We currently don't implement any of these */
2026 case ProcessLdtSize:
2028 DPRINT1("VDM/16-bit Request not implemented: %lx\n", ProcessInformationClass);
2030 break;
2031
2032 case ProcessQuotaLimits:
2033
2035 1,
2036 ProcessInformation,
2037 ProcessInformationLength,
2038 PreviousMode);
2039 break;
2040
2042 DPRINT1("WS watch not implemented\n");
2044 break;
2045
2047 DPRINT1("Handle tracing not implemented\n");
2049 break;
2050
2051 /* Anything else is invalid */
2052 default:
2053 DPRINT1("Invalid Server 2003 Info Class: %lx\n", ProcessInformationClass);
2055 }
2056
2057 /* Dereference and return status */
2059 return Status;
2060}
2061
2062/*
2063 * @implemented
2064 */
2066NTAPI
2069 IN PVOID ThreadInformation,
2071{
2076 KPRIORITY Priority = 0;
2077 KAFFINITY Affinity = 0, CombinedAffinity;
2078 PVOID Address = NULL;
2080 ULONG_PTR DisableBoost = 0;
2081 ULONG_PTR IdealProcessor = 0;
2082 ULONG_PTR Break = 0;
2083 PTEB Teb;
2084 ULONG_PTR TlsIndex = 0;
2085 PVOID *ExpansionSlots;
2086 PETHREAD ProcThread;
2088 PAGED_CODE();
2089
2090 /* Verify Information Class validity */
2094 ThreadInformation,
2096 PreviousMode);
2097 if (!NT_SUCCESS(Status))
2098 {
2099 DPRINT1("NtSetInformationThread(): Information verification class failed! (Status -> 0x%lx, ThreadInformationClass -> %lx)\n", Status, ThreadInformationClass);
2100 return Status;
2101 }
2102
2103 /* Check what kind of information class this is */
2104 switch (ThreadInformationClass)
2105 {
2106 /* Thread priority */
2107 case ThreadPriority:
2108
2109 /* Check buffer length */
2110 if (ThreadInformationLength != sizeof(KPRIORITY))
2111 {
2113 break;
2114 }
2115
2116 /* Use SEH for capture */
2117 _SEH2_TRY
2118 {
2119 /* Get the priority */
2120 Priority = *(PLONG)ThreadInformation;
2121 }
2123 {
2124 /* Get the exception code */
2126 _SEH2_YIELD(break);
2127 }
2128 _SEH2_END;
2129
2130 /* Validate it */
2131 if ((Priority > HIGH_PRIORITY) ||
2133 {
2134 /* Fail */
2136 break;
2137 }
2138
2139 /* Check for the required privilege */
2141 {
2143 ThreadHandle,
2145 PreviousMode);
2146 if (!HasPrivilege)
2147 {
2148 DPRINT1("Privilege to change priority to %lx lacking\n", Priority);
2150 }
2151 }
2152
2153 /* Reference the thread */
2154 Status = ObReferenceObjectByHandle(ThreadHandle,
2158 (PVOID*)&Thread,
2159 NULL);
2160 if (!NT_SUCCESS(Status))
2161 break;
2162
2163 /* Set the priority */
2165
2166 /* Dereference the thread */
2168 break;
2169
2170 case ThreadBasePriority:
2171
2172 /* Check buffer length */
2173 if (ThreadInformationLength != sizeof(LONG))
2174 {
2176 break;
2177 }
2178
2179 /* Use SEH for capture */
2180 _SEH2_TRY
2181 {
2182 /* Get the priority */
2183 Priority = *(PLONG)ThreadInformation;
2184 }
2186 {
2187 /* Get the exception code */
2189 _SEH2_YIELD(break);
2190 }
2191 _SEH2_END;
2192
2193 /* Validate it */
2196 {
2197 /* These ones are OK */
2198 if ((Priority != THREAD_BASE_PRIORITY_LOWRT + 1) &&
2200 {
2201 /* Check if the process is real time */
2202 if (PsGetCurrentProcess()->PriorityClass !=
2204 {
2205 /* It isn't, fail */
2207 break;
2208 }
2209 }
2210 }
2211
2212 /* Reference the thread */
2213 Status = ObReferenceObjectByHandle(ThreadHandle,
2217 (PVOID*)&Thread,
2218 NULL);
2219 if (!NT_SUCCESS(Status))
2220 break;
2221
2222 /* Set the base priority */
2224
2225 /* Dereference the thread */
2227 break;
2228
2229 case ThreadAffinityMask:
2230
2231 /* Check buffer length */
2232 if (ThreadInformationLength != sizeof(ULONG_PTR))
2233 {
2235 break;
2236 }
2237
2238 /* Use SEH for capture */
2239 _SEH2_TRY
2240 {
2241 /* Get the priority */
2242 Affinity = *(PULONG_PTR)ThreadInformation;
2243 }
2245 {
2246 /* Get the exception code */
2248 _SEH2_YIELD(break);
2249 }
2250 _SEH2_END;
2251
2252 /* Validate it */
2253 if (!Affinity)
2254 {
2255 /* Fail */
2257 break;
2258 }
2259
2260 /* Reference the thread */
2261 Status = ObReferenceObjectByHandle(ThreadHandle,
2265 (PVOID*)&Thread,
2266 NULL);
2267 if (!NT_SUCCESS(Status))
2268 break;
2269
2270 /* Get the process */
2271 Process = Thread->ThreadsProcess;
2272
2273 /* Try to acquire rundown */
2274 if (ExAcquireRundownProtection(&Process->RundownProtect))
2275 {
2276 /* Lock it */
2278 ExAcquirePushLockShared(&Process->ProcessLock);
2279
2280 /* Combine masks */
2281 CombinedAffinity = Affinity & Process->Pcb.Affinity;
2282 if (CombinedAffinity != Affinity)
2283 {
2284 /* Fail */
2286 }
2287 else
2288 {
2289 /* Set the affinity */
2290 KeSetAffinityThread(&Thread->Tcb, CombinedAffinity);
2291 }
2292
2293 /* Release the lock and rundown */
2294 ExReleasePushLockShared(&Process->ProcessLock);
2296 ExReleaseRundownProtection(&Process->RundownProtect);
2297 }
2298 else
2299 {
2300 /* Too late */
2302 }
2303
2304 /* Dereference the thread */
2306 break;
2307
2309
2310 /* Check buffer length */
2311 if (ThreadInformationLength != sizeof(HANDLE))
2312 {
2314 break;
2315 }
2316
2317 /* Use SEH for capture */
2318 _SEH2_TRY
2319 {
2320 /* Save the token handle */
2321 TokenHandle = *(PHANDLE)ThreadInformation;
2322 }
2324 {
2325 /* Get the exception code */
2327 _SEH2_YIELD(break);
2328 }
2329 _SEH2_END;
2330
2331 /* Reference the thread */
2332 Status = ObReferenceObjectByHandle(ThreadHandle,
2336 (PVOID*)&Thread,
2337 NULL);
2338 if (!NT_SUCCESS(Status))
2339 break;
2340
2341 /* Assign the actual token */
2343
2344 /* Dereference the thread */
2346 break;
2347
2349
2350 /* Check buffer length */
2351 if (ThreadInformationLength != sizeof(ULONG_PTR))
2352 {
2354 break;
2355 }
2356
2357 /* Use SEH for capture */
2358 _SEH2_TRY
2359 {
2360 /* Get the priority */
2361 Address = *(PVOID*)ThreadInformation;
2362 }
2364 {
2365 /* Get the exception code */
2367 _SEH2_YIELD(break);
2368 }
2369 _SEH2_END;
2370
2371 /* Reference the thread */
2372 Status = ObReferenceObjectByHandle(ThreadHandle,
2376 (PVOID*)&Thread,
2377 NULL);
2378 if (!NT_SUCCESS(Status))
2379 break;
2380
2381 /* Set the address */
2383
2384 /* Dereference the thread */
2386 break;
2387
2389
2390 /* Check buffer length */
2391 if (ThreadInformationLength != sizeof(ULONG_PTR))
2392 {
2394 break;
2395 }
2396
2397 /* Use SEH for capture */
2398 _SEH2_TRY
2399 {
2400 /* Get the priority */
2401 IdealProcessor = *(PULONG_PTR)ThreadInformation;
2402 }
2404 {
2405 /* Get the exception code */
2407 _SEH2_YIELD(break);
2408 }
2409 _SEH2_END;
2410
2411 /* Validate it */
2412 if (IdealProcessor > MAXIMUM_PROCESSORS)
2413 {
2414 /* Fail */
2416 break;
2417 }
2418
2419 /* Reference the thread */
2420 Status = ObReferenceObjectByHandle(ThreadHandle,
2424 (PVOID*)&Thread,
2425 NULL);
2426 if (!NT_SUCCESS(Status))
2427 break;
2428
2429 /* Set the ideal */
2431 (CCHAR)IdealProcessor);
2432
2433 /* Get the TEB and protect the thread */
2434 Teb = Thread->Tcb.Teb;
2436 {
2437 /* Save the ideal processor */
2438 Teb->IdealProcessor = Thread->Tcb.IdealProcessor;
2439
2440 /* Release rundown protection */
2442 }
2443
2444 /* Dereference the thread */
2446 break;
2447
2449
2450 /* Check buffer length */
2451 if (ThreadInformationLength != sizeof(ULONG_PTR))
2452 {
2454 break;
2455 }
2456
2457 /* Use SEH for capture */
2458 _SEH2_TRY
2459 {
2460 /* Get the priority */
2461 DisableBoost = *(PULONG_PTR)ThreadInformation;
2462 }
2464 {
2465 /* Get the exception code */
2467 _SEH2_YIELD(break);
2468 }
2469 _SEH2_END;
2470
2471 /* Reference the thread */
2472 Status = ObReferenceObjectByHandle(ThreadHandle,
2476 (PVOID*)&Thread,
2477 NULL);
2478 if (!NT_SUCCESS(Status))
2479 break;
2480
2481 /* Call the kernel */
2482 KeSetDisableBoostThread(&Thread->Tcb, (BOOLEAN)DisableBoost);
2483
2484 /* Dereference the thread */
2486 break;
2487
2488 case ThreadZeroTlsCell:
2489
2490 /* Check buffer length */
2491 if (ThreadInformationLength != sizeof(ULONG))
2492 {
2494 break;
2495 }
2496
2497 /* Use SEH for capture */
2498 _SEH2_TRY
2499 {
2500 /* Get the priority */
2501 TlsIndex = *(PULONG)ThreadInformation;
2502 }
2504 {
2505 /* Get the exception code */
2507 _SEH2_YIELD(break);
2508 }
2509 _SEH2_END;
2510
2511 /* Reference the thread */
2512 Status = ObReferenceObjectByHandle(ThreadHandle,
2516 (PVOID*)&Thread,
2517 NULL);
2518 if (!NT_SUCCESS(Status))
2519 break;
2520
2521 /* This is only valid for the current thread */
2522 if (Thread != PsGetCurrentThread())
2523 {
2524 /* Fail */
2527 break;
2528 }
2529
2530 /* Get the process */
2531 Process = Thread->ThreadsProcess;
2532
2533 /* Loop the threads */
2534 ProcThread = PsGetNextProcessThread(Process, NULL);
2535 while (ProcThread)
2536 {
2537 /* Acquire rundown */
2539 {
2540 /* Get the TEB */
2541 Teb = ProcThread->Tcb.Teb;
2542 if (Teb)
2543 {
2544 /* Check if we're in the expansion range */
2546 {
2549 {
2550 /* Check if we have expansion slots */
2551 ExpansionSlots = Teb->TlsExpansionSlots;
2552 if (ExpansionSlots)
2553 {
2554 /* Clear the index */
2555 ExpansionSlots[TlsIndex - TLS_MINIMUM_AVAILABLE] = 0;
2556 }
2557 }
2558 }
2559 else
2560 {
2561 /* Clear the index */
2562 Teb->TlsSlots[TlsIndex] = NULL;
2563 }
2564 }
2565
2566 /* Release rundown */
2568 }
2569
2570 /* Go to the next thread */
2571 ProcThread = PsGetNextProcessThread(Process, ProcThread);
2572 }
2573
2574 /* Dereference the thread */
2576 break;
2577
2579
2580 /* Check buffer length */
2581 if (ThreadInformationLength != sizeof(ULONG))
2582 {
2584 break;
2585 }
2586
2587 /* Enter SEH for direct buffer read */
2588 _SEH2_TRY
2589 {
2590 Break = *(PULONG)ThreadInformation;
2591 }
2593 {
2594 /* Get exception code */
2595 Break = 0;
2597 _SEH2_YIELD(break);
2598 }
2599 _SEH2_END;
2600
2601 /* Setting 'break on termination' requires the SeDebugPrivilege */
2603 {
2604 /* We don't hold the privilege, bail out */
2606 break;
2607 }
2608
2609 /* Reference the thread */
2610 Status = ObReferenceObjectByHandle(ThreadHandle,
2614 (PVOID*)&Thread,
2615 NULL);
2616 if (!NT_SUCCESS(Status))
2617 break;
2618
2619 /* Set or clear the flag */
2620 if (Break)
2621 {
2623 }
2624 else
2625 {
2627 }
2628
2629 /* Dereference the thread */
2631 break;
2632
2634
2635 /* Check buffer length */
2636 if (ThreadInformationLength != 0)
2637 {
2639 break;
2640 }
2641
2642 /* Reference the thread */
2643 Status = ObReferenceObjectByHandle(ThreadHandle,
2647 (PVOID*)&Thread,
2648 NULL);
2649 if (!NT_SUCCESS(Status))
2650 break;
2651
2652 /* Set the flag */
2654
2655 /* Dereference the thread */
2657 break;
2658
2659 default:
2660 /* We don't implement it yet */
2661 DPRINT1("Not implemented: %d\n", ThreadInformationClass);
2663 }
2664
2665 return Status;
2666}
2667
2668/*
2669 * @implemented
2670 */
2672NTAPI
2675 OUT PVOID ThreadInformation,
2678{
2682 ULONG Access;
2683 ULONG Length = 0;
2684 PTHREAD_BASIC_INFORMATION ThreadBasicInfo =
2685 (PTHREAD_BASIC_INFORMATION)ThreadInformation;
2686 PKERNEL_USER_TIMES ThreadTime = (PKERNEL_USER_TIMES)ThreadInformation;
2687 KIRQL OldIrql;
2688 ULONG ThreadTerminated;
2689 PAGED_CODE();
2690
2691 /* Verify Information Class validity */
2696 ThreadInformation,
2699 NULL,
2700 PreviousMode);
2701 if (!NT_SUCCESS(Status))
2702 {
2703 DPRINT1("NtQueryInformationThread(): Information verification class failed! (Status -> 0x%lx , ThreadInformationClass -> %lx)\n", Status, ThreadInformationClass);
2704 return Status;
2705 }
2706
2707 /* Check what class this is */
2708 Access = THREAD_QUERY_INFORMATION;
2709
2710 /* Check what kind of information class this is */
2711 switch (ThreadInformationClass)
2712 {
2713 /* Basic thread information */
2715
2716 /* Set return length */
2718
2720 {
2722 break;
2723 }
2724
2725 /* Reference the process */
2726 Status = ObReferenceObjectByHandle(ThreadHandle,
2727 Access,
2730 (PVOID*)&Thread,
2731 NULL);
2732 if (!NT_SUCCESS(Status))
2733 break;
2734
2735 /* Protect writes with SEH */
2736 _SEH2_TRY
2737 {
2738 /* Write all the information from the ETHREAD/KTHREAD */
2739 ThreadBasicInfo->ExitStatus = Thread->ExitStatus;
2740 ThreadBasicInfo->TebBaseAddress = (PVOID)Thread->Tcb.Teb;
2741 ThreadBasicInfo->ClientId = Thread->Cid;
2742 ThreadBasicInfo->AffinityMask = Thread->Tcb.Affinity;
2743 ThreadBasicInfo->Priority = Thread->Tcb.Priority;
2744 ThreadBasicInfo->BasePriority = KeQueryBasePriorityThread(&Thread->Tcb);
2745 }
2747 {
2748 /* Get exception code */
2750 }
2751 _SEH2_END;
2752
2753 /* Dereference the thread */
2755 break;
2756
2757 /* Thread time information */
2758 case ThreadTimes:
2759
2760 /* Set the return length */
2761 Length = sizeof(KERNEL_USER_TIMES);
2762
2764 {
2766 break;
2767 }
2768
2769 /* Reference the process */
2770 Status = ObReferenceObjectByHandle(ThreadHandle,
2771 Access,
2774 (PVOID*)&Thread,
2775 NULL);
2776 if (!NT_SUCCESS(Status))
2777 break;
2778
2779 /* Protect writes with SEH */
2780 _SEH2_TRY
2781 {
2782 /* Copy time information from ETHREAD/KTHREAD */
2785 ThreadTime->CreateTime = Thread->CreateTime;
2786
2787 /* Exit time is in a union and only valid on actual exit! */
2789 {
2790 ThreadTime->ExitTime = Thread->ExitTime;
2791 }
2792 else
2793 {
2794 ThreadTime->ExitTime.QuadPart = 0;
2795 }
2796 }
2798 {
2799 /* Get exception code */
2801 }
2802 _SEH2_END;
2803
2804 /* Dereference the thread */
2806 break;
2807
2809
2810 /* Set the return length*/
2811 Length = sizeof(PVOID);
2812
2814 {
2816 break;
2817 }
2818
2819 /* Reference the process */
2820 Status = ObReferenceObjectByHandle(ThreadHandle,
2821 Access,
2824 (PVOID*)&Thread,
2825 NULL);
2826 if (!NT_SUCCESS(Status))
2827 break;
2828
2829 /* Protect write with SEH */
2830 _SEH2_TRY
2831 {
2832 /* Return the Win32 Start Address */
2833 *(PVOID*)ThreadInformation = Thread->Win32StartAddress;
2834 }
2836 {
2837 /* Get exception code */
2839 }
2840 _SEH2_END;
2841
2842 /* Dereference the thread */
2844 break;
2845
2847
2848 /* Set the return length*/
2849 Length = sizeof(LARGE_INTEGER);
2850
2852 {
2854 break;
2855 }
2856
2857 /* Reference the process */
2858 Status = ObReferenceObjectByHandle(ThreadHandle,
2859 Access,
2862 (PVOID*)&Thread,
2863 NULL);
2864 if (!NT_SUCCESS(Status))
2865 break;
2866
2867 /* Protect write with SEH */
2868 _SEH2_TRY
2869 {
2870 /* FIXME */
2871 (*(PLARGE_INTEGER)ThreadInformation).QuadPart = 0;
2872 }
2874 {
2875 /* Get exception code */
2877 }
2878 _SEH2_END;
2879
2880 /* Dereference the thread */
2882 break;
2883
2885
2886 /* Set the return length*/
2887 Length = sizeof(ULONG);
2888
2890 {
2892 break;
2893 }
2894
2895 /* Reference the process */
2896 Status = ObReferenceObjectByHandle(ThreadHandle,
2897 Access,
2900 (PVOID*)&Thread,
2901 NULL);
2902 if (!NT_SUCCESS(Status))
2903 break;
2904
2905 /* Protect write with SEH */
2906 _SEH2_TRY
2907 {
2908 /* Return whether or not we are the last thread */
2909 *(PULONG)ThreadInformation = ((Thread->ThreadsProcess->
2910 ThreadListHead.Flink->Flink ==
2911 &Thread->ThreadsProcess->
2913 TRUE : FALSE);
2914 }
2916 {
2917 /* Get exception code */
2919 }
2920 _SEH2_END;
2921
2922 /* Dereference the thread */
2924 break;
2925
2926 case ThreadIsIoPending:
2927
2928 /* Set the return length*/
2929 Length = sizeof(ULONG);
2930
2932 {
2934 break;
2935 }
2936
2937 /* Reference the process */
2938 Status = ObReferenceObjectByHandle(ThreadHandle,
2939 Access,
2942 (PVOID*)&Thread,
2943 NULL);
2944 if (!NT_SUCCESS(Status))
2945 break;
2946
2947 /* Raise the IRQL to protect the IRP list */
2949
2950 /* Protect write with SEH */
2951 _SEH2_TRY
2952 {
2953 /* Check if the IRP list is empty or not */
2954 *(PULONG)ThreadInformation = !IsListEmpty(&Thread->IrpList);
2955 }
2957 {
2958 /* Get exception code */
2960 }
2961 _SEH2_END;
2962
2963 /* Lower IRQL back */
2965
2966 /* Dereference the thread */
2968 break;
2969
2970 /* LDT and GDT information */
2972
2973#if defined(_X86_)
2974 /* Reference the process */
2975 Status = ObReferenceObjectByHandle(ThreadHandle,
2976 Access,
2979 (PVOID*)&Thread,
2980 NULL);
2981 if (!NT_SUCCESS(Status))
2982 break;
2983
2984 /* Call the worker routine */
2986 ThreadInformation,
2988 ReturnLength);
2989
2990 /* Dereference the thread */
2992#else
2993 /* Only implemented on x86 */
2995#endif
2996 break;
2997
2999
3000 /* Set the return length*/
3001 Length = sizeof(ULONG);
3002
3004 {
3006 break;
3007 }
3008
3009 /* Reference the process */
3010 Status = ObReferenceObjectByHandle(ThreadHandle,
3011 Access,
3014 (PVOID*)&Thread,
3015 NULL);
3016 if (!NT_SUCCESS(Status))
3017 break;
3018
3019 _SEH2_TRY
3020 {
3021 *(PULONG)ThreadInformation = Thread->Tcb.DisableBoost ? 1 : 0;
3022 }
3024 {
3026 }
3027 _SEH2_END;
3028
3029 /* Dereference the thread */
3031 break;
3032
3033 case ThreadIsTerminated:
3034
3035 /* Set the return length*/
3036 Length = sizeof(ThreadTerminated);
3037
3039 {
3041 break;
3042 }
3043
3044 /* Reference the process */
3045 Status = ObReferenceObjectByHandle(ThreadHandle,
3046 Access,
3049 (PVOID*)&Thread,
3050 NULL);
3051 if (!NT_SUCCESS(Status))
3052 break;
3053
3054 ThreadTerminated = PsIsThreadTerminating(Thread);
3055
3056 _SEH2_TRY
3057 {
3058 *(PULONG)ThreadInformation = ThreadTerminated ? 1 : 0;
3059 }
3061 {
3063 }
3064 _SEH2_END;
3065
3066 /* Dereference the thread */
3068 break;
3069
3070 /* Anything else */
3071 default:
3072
3073 /* Not yet implemented */
3074 DPRINT1("Not implemented: %lx\n", ThreadInformationClass);
3076 }
3077
3078 /* Protect write with SEH */
3079 _SEH2_TRY
3080 {
3081 /* Check if caller wanted return length */
3083 }
3085 {
3086 /* Get exception code */
3088 }
3089 _SEH2_END;
3090
3091 return Status;
3092}
3093
3094/* EOF */
#define PAGED_CODE()
#define STATUS_PRIVILEGE_NOT_HELD
Definition: DriverTester.h:9
static HANDLE DirectoryHandle
Definition: ObType.c:48
unsigned char BOOLEAN
#define RTL_NUMBER_OF(x)
Definition: RtlRegistry.c:12
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:195
#define UNIMPLEMENTED
Definition: ntoskrnl.c:15
#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
@ ThreadDescriptorTableEntry
Definition: compat.h:941
@ ThreadAmILastThread
Definition: compat.h:947
@ ThreadTimes
Definition: compat.h:936
@ ThreadPriority
Definition: compat.h:937
@ ThreadIdealProcessor
Definition: compat.h:948
@ ThreadQuerySetWin32StartAddress
Definition: compat.h:944
@ ThreadIsTerminated
Definition: compat.h:955
@ ThreadBreakOnTermination
Definition: compat.h:953
@ ThreadImpersonationToken
Definition: compat.h:940
@ ThreadAffinityMask
Definition: compat.h:939
@ ThreadBasePriority
Definition: compat.h:938
@ ThreadBasicInformation
Definition: compat.h:935
@ ThreadPriorityBoost
Definition: compat.h:949
@ ThreadPerformanceCount
Definition: compat.h:946
@ ThreadIsIoPending
Definition: compat.h:951
@ ThreadZeroTlsCell
Definition: compat.h:945
@ ThreadHideFromDebugger
Definition: compat.h:952
enum _THREADINFOCLASS THREADINFOCLASS
Definition: thread.c:101
struct _THREAD_BASIC_INFORMATION * PTHREAD_BASIC_INFORMATION
LONG KPRIORITY
Definition: compat.h:803
#define UlongToPtr(u)
Definition: config.h:106
#define ULONG_PTR
Definition: config.h:101
IN CINT OUT PVOID IN ULONG OUT PULONG ReturnLength
Definition: dumpinfo.c:43
UNICODE_STRING * PUNICODE_STRING
Definition: env_spec_w32.h:373
#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 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:422
@ PsProcessPriorityBackground
Definition: pstypes.h:423
#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:1022
@ PsPageFile
Definition: pstypes.h:1024
@ PsPagedPool
Definition: pstypes.h:1023
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
@ ProcessDebugPort
Definition: winternl.h:395
@ ProcessBreakOnTermination
Definition: winternl.h:398
@ ProcessBasicInformation
Definition: winternl.h:394
@ ProcessWow64Information
Definition: winternl.h:396
@ ProcessImageFileName
Definition: winternl.h:397
struct _PROCESS_BASIC_INFORMATION * PPROCESS_BASIC_INFORMATION
enum _PROCESSINFOCLASS PROCESSINFOCLASS
Definition: loader.c:63
struct _PROCESS_BASIC_INFORMATION PROCESS_BASIC_INFORMATION
struct _KERNEL_USER_TIMES KERNEL_USER_TIMES
struct _KERNEL_USER_TIMES * PKERNEL_USER_TIMES
@ ProcessLUIDDeviceMapsEnabled
Definition: winternl.h:884
@ ProcessWx86Information
Definition: winternl.h:875
@ ProcessDebugFlags
Definition: winternl.h:887
@ ProcessSessionInformation
Definition: winternl.h:880
@ ProcessAffinityMask
Definition: winternl.h:877
@ ProcessIoPortHandlers
Definition: winternl.h:869
@ ProcessRaisePriority
Definition: winternl.h:862
@ ProcessVmCounters
Definition: winternl.h:859
@ ProcessPriorityClass
Definition: winternl.h:874
@ ProcessPriorityBoost
Definition: winternl.h:878
@ ProcessImageInformation
Definition: winternl.h:892
@ ProcessExecuteFlags
Definition: winternl.h:889
@ ProcessCookie
Definition: winternl.h:891
@ ProcessPooledUsageAndLimits
Definition: winternl.h:870
@ ProcessLdtSize
Definition: winternl.h:867
@ ProcessIoCounters
Definition: winternl.h:858
@ ProcessDefaultHardErrorMode
Definition: winternl.h:868
@ ProcessEnableAlignmentFaultFixup
Definition: winternl.h:873
@ ProcessDeviceMap
Definition: winternl.h:879
@ ProcessBasePriority
Definition: winternl.h:861
@ ProcessQuotaLimits
Definition: winternl.h:857
@ ProcessAccessToken
Definition: winternl.h:865
@ ProcessHandleTracing
Definition: winternl.h:888
@ ProcessForegroundInformation
Definition: winternl.h:881
@ ProcessTimes
Definition: winternl.h:860
@ ProcessDebugObjectHandle
Definition: winternl.h:886
@ ProcessExceptionPort
Definition: winternl.h:864
@ ProcessWorkingSetWatch
Definition: winternl.h:871
@ ProcessLdtInformation
Definition: winternl.h:866
@ ProcessHandleCount
Definition: winternl.h:876
@ ProcessUserModeIOPL
Definition: winternl.h:872
struct _VM_COUNTERS_ * PVM_COUNTERS
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:90
#define QUOTA_LIMITS_HARDWS_MIN_DISABLE
#define PROCESS_LUID_DOSDEVICES_ONLY
Definition: pstypes.h:228
struct _PROCESS_ACCESS_TOKEN * PPROCESS_ACCESS_TOKEN
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 _VM_COUNTERS_EX VM_COUNTERS_EX
struct _IO_COUNTERS * PIO_COUNTERS
#define InterlockedCompareExchangePointer
Definition: interlocked.h:129
#define InterlockedCompareExchange
Definition: interlocked.h:104
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
POBJECT_TYPE LpcPortObjectType
Definition: port.c:17
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
static const char * ImageName
Definition: image.c:34
FORCEINLINE struct _KPRCB * KeGetCurrentPrcb(VOID)
Definition: ketypes.h:1179
#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:726
_In_ THREADINFOCLASS _In_ ULONG ThreadInformationLength
Definition: psfuncs.h:843
_In_ THREADINFOCLASS ThreadInformationClass
Definition: psfuncs.h:840
#define SEM_NOALIGNMENTFAULTEXCEPT
Definition: rtltypes.h:71
#define _Out_opt_
Definition: no_sal2.h:214
#define _Out_
Definition: no_sal2.h:160
#define _In_
Definition: no_sal2.h:158
ULONG ACCESS_MASK
Definition: nt_native.h:40
#define NtCurrentProcess()
Definition: nt_native.h:1657
struct _OBJECT_NAME_INFORMATION OBJECT_NAME_INFORMATION
#define THREAD_SET_INFORMATION
Definition: nt_native.h:1337
_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: krnlinit.c:23
VOID NTAPI Ke386SetIOPL(VOID)
Definition: v86vdm.c:581
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:1541
VOID NTAPI MmGetImageInformation(OUT PSECTION_IMAGE_INFORMATION ImageInformation)
Definition: section.c:1615
NTSTATUS NTAPI MmSetExecuteOptions(IN ULONG ExecuteOptions)
Definition: pagfault.c:2695
NTSTATUS NTAPI MmSetMemoryPriorityProcess(IN PEPROCESS Process, IN UCHAR MemoryPriority)
Definition: procsup.c:486
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
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
NTSTATUS NTAPI NtQueryInformationThread(IN HANDLE ThreadHandle, IN THREADINFOCLASS ThreadInformationClass, OUT PVOID ThreadInformation, IN ULONG ThreadInformationLength, OUT PULONG ReturnLength OPTIONAL)
Definition: query.c:2673
ULONG PspTraceLevel
Definition: query.c:18
NTSTATUS NTAPI PsReferenceProcessFilePointer(IN PEPROCESS Process, OUT PFILE_OBJECT *FileObject)
Definition: query.c:24
NTSTATUS NTAPI NtSetInformationProcess(IN HANDLE ProcessHandle, IN PROCESSINFOCLASS ProcessInformationClass, IN PVOID ProcessInformation, IN ULONG ProcessInformationLength)
Definition: query.c:1154
NTSTATUS NTAPI NtSetInformationThread(IN HANDLE ThreadHandle, IN THREADINFOCLASS ThreadInformationClass, IN PVOID ThreadInformation, IN ULONG ThreadInformationLength)
Definition: query.c:2067
NTSTATUS NTAPI NtQueryInformationProcess(_In_ HANDLE ProcessHandle, _In_ PROCESSINFOCLASS ProcessInformationClass, _Out_ PVOID ProcessInformation, _In_ ULONG ProcessInformationLength, _Out_opt_ PULONG ReturnLength)
Definition: query.c:59
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:502
#define STATUS_INVALID_INFO_CLASS
Definition: ntstatus.h:240
#define STATUS_PORT_ALREADY_SET
Definition: ntstatus.h:308
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 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
long LONG
Definition: pedump.c:60
static WCHAR Address[46]
Definition: ping.c:68
VOID NTAPI KeDetachProcess(VOID)
Definition: procobj.c:621
VOID NTAPI KeAttachProcess(IN PKPROCESS Process)
Definition: procobj.c:582
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
#define PspSetCrossThreadFlag(Thread, Flag)
Definition: ps_x.h:25
#define PspClearCrossThreadFlag(Thread, Flag)
Definition: ps_x.h:27
#define PspClearProcessFlag(Process, Flag)
Definition: ps_x.h:35
#define PspSetProcessFlag(Process, Flag)
Definition: ps_x.h:33
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:165
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:66
#define _SEH2_END
Definition: pseh2_64.h:155
#define _SEH2_TRY
Definition: pseh2_64.h:55
#define _SEH2_YIELD(__stmt)
Definition: pseh2_64.h:168
NTSTATUS NTAPI PspQueryDescriptorThread(IN PETHREAD Thread, IN PVOID ThreadInformation, IN ULONG ThreadInformationLength, OUT PULONG ReturnLength OPTIONAL)
Definition: psldt.c:43
#define _WIN32_WINNT_WS03
Definition: sdkddkver.h:23
#define STATUS_SUCCESS
Definition: shellext.h:65
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68
#define TLS_MINIMUM_AVAILABLE
Definition: ntddk_ex.h:236
LARGE_INTEGER ExitTime
Definition: pstypes.h:1108
NTSTATUS ExitStatus
Definition: pstypes.h:1114
KTHREAD Tcb
Definition: pstypes.h:1104
EX_RUNDOWN_REF RundownProtect
Definition: pstypes.h:1160
PVOID Win32StartAddress
Definition: pstypes.h:1153
CLIENT_ID Cid
Definition: pstypes.h:1129
LIST_ENTRY IrpList
Definition: pstypes.h:1145
LARGE_INTEGER CreateTime
Definition: pstypes.h:1105
LARGE_INTEGER UserTime
Definition: winternl.h:1063
LARGE_INTEGER CreateTime
Definition: winternl.h:1060
LARGE_INTEGER KernelTime
Definition: winternl.h:1062
LARGE_INTEGER ExitTime
Definition: winternl.h:1061
ULONG InterruptTime
Definition: ketypes.h:829
ULONG KeSystemCalls
Definition: ketypes.h:740
GROUP_AFFINITY Affinity
Definition: ketypes.h:1938
ULONG IdealProcessor
Definition: ketypes.h:1944
ULONG DisableBoost
Definition: ketypes.h:1725
SCHAR Priority
Definition: ketypes.h:1782
PVOID Teb
Definition: ketypes.h:1807
ULONG KernelTime
Definition: ketypes.h:1987
ULONG UserTime
Definition: ketypes.h:2003
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
ULONG_PTR InheritedFromUniqueProcessId
Definition: pstypes.h:340
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
SIZE_T QuotaPeakPagedPoolUsage
Definition: winternl.h:1610
SIZE_T PeakWorkingSetSize
Definition: winternl.h:1608
SIZE_T QuotaPeakNonPagedPoolUsage
Definition: winternl.h:1612
SIZE_T VirtualSize
Definition: winternl.h:1606
SIZE_T PeakPagefileUsage
Definition: winternl.h:1615
SIZE_T QuotaNonPagedPoolUsage
Definition: winternl.h:1613
SIZE_T PagefileUsage
Definition: winternl.h:1614
SIZE_T PeakVirtualSize
Definition: winternl.h:1605
SIZE_T QuotaPagedPoolUsage
Definition: winternl.h:1611
SIZE_T WorkingSetSize
Definition: winternl.h:1609
ULONG PageFaultCount
Definition: winternl.h:1607
#define TAG_SEPA
Definition: tag.h:155
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:1176
KPRIORITY NTAPI KeSetPriorityThread(IN PKTHREAD Thread, IN KPRIORITY Priority)
Definition: thrdobj.c:1319
KAFFINITY NTAPI KeSetAffinityThread(IN PKTHREAD Thread, IN KAFFINITY Affinity)
Definition: thrdobj.c:1295
uint16_t * PWSTR
Definition: typedefs.h:56
uint32_t * PULONG_PTR
Definition: typedefs.h:65
uint32_t * PULONG
Definition: typedefs.h:59
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
#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
#define IN
Definition: typedefs.h:39
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
#define OUT
Definition: typedefs.h:40
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
struct _LARGE_INTEGER::@2306 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
#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
_In_ KPROCESSOR_MODE PreviousMode
Definition: sefuncs.h:103
unsigned char UCHAR
Definition: xmlstorage.h:181