ReactOS 0.4.16-dev-1401-gf1332c7
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 /* Indicate success */
894
895 /* Enter SEH to protect write */
897 {
899 }
901 {
902 /* Get the exception code */
904 }
905 _SEH2_END;
906 break;
907
909 {
910 HANDLE DebugPort = NULL;
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. Continue even if this fails. */
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 if (DebugPort)
945 ObCloseHandle(DebugPort, PreviousMode);
946
947 /* Get the exception code.
948 * Note: This overwrites any previous failure status. */
950 }
951 _SEH2_END;
952 break;
953 }
954
956 DPRINT1("Handle tracing Not implemented: %lx\n", ProcessInformationClass);
958 break;
959
961
962 if (ProcessInformationLength != sizeof(ULONG))
963 {
965 break;
966 }
967
968 /* Set the return length */
969 Length = sizeof(ULONG);
970
971 /* Indicate success */
973
974 /* Protect write in SEH */
976 {
977 /* Query Ob */
978 *(PULONG)ProcessInformation = ObIsLUIDDeviceMapsEnabled();
979 }
981 {
982 /* Get the exception code */
984 }
985 _SEH2_END;
986 break;
987
989
990 if (ProcessInformationLength != sizeof(ULONG))
991 {
993 break;
994 }
995
996 /* Set the return length */
997 Length = sizeof(ULONG);
998
999 /* Reference the process */
1004 (PVOID*)&Process,
1005 NULL);
1006 if (!NT_SUCCESS(Status)) break;
1007
1008 /* Protect write in SEH */
1009 _SEH2_TRY
1010 {
1011 /* Return if the flag is set */
1012 *(PULONG)ProcessInformation = (ULONG)Process->VdmAllowed;
1013 }
1015 {
1016 /* Get the exception code */
1018 }
1019 _SEH2_END;
1020
1021 /* Dereference the process */
1023 break;
1024
1026 {
1027 ULONG_PTR Wow64 = 0;
1028
1029 if (ProcessInformationLength != sizeof(ULONG_PTR))
1030 {
1032 break;
1033 }
1034
1035 /* Set return length */
1036 Length = sizeof(ULONG_PTR);
1037
1038 /* Reference the process */
1043 (PVOID*)&Process,
1044 NULL);
1045 if (!NT_SUCCESS(Status)) break;
1046
1047#ifdef _WIN64
1048 /* Make sure the process isn't dying */
1049 if (ExAcquireRundownProtection(&Process->RundownProtect))
1050 {
1051 /* Get the WOW64 process structure */
1052 Wow64 = (ULONG_PTR)Process->Wow64Process;
1053 /* Release the lock */
1054 ExReleaseRundownProtection(&Process->RundownProtect);
1055 }
1056#endif
1057
1058 /* Dereference the process */
1060
1061 /* Protect write with SEH */
1062 _SEH2_TRY
1063 {
1064 /* Return the Wow64 process information */
1065 *(PULONG_PTR)ProcessInformation = Wow64;
1066 }
1068 {
1069 /* Get exception code */
1071 }
1072 _SEH2_END;
1073 break;
1074 }
1075
1077 {
1078 ULONG ExecuteOptions = 0;
1079
1080 if (ProcessInformationLength != sizeof(ULONG))
1081 {
1083 break;
1084 }
1085
1086 /* Set return length */
1087 Length = sizeof(ULONG);
1088
1090 {
1092 break;
1093 }
1094
1095 /* Get the options */
1096 Status = MmGetExecuteOptions(&ExecuteOptions);
1097 if (NT_SUCCESS(Status))
1098 {
1099 /* Protect write with SEH */
1100 _SEH2_TRY
1101 {
1102 /* Return them */
1103 *(PULONG)ProcessInformation = ExecuteOptions;
1104 }
1106 {
1107 /* Get exception code */
1109 }
1110 _SEH2_END;
1111 }
1112 break;
1113 }
1114
1116 DPRINT1("VDM/16-bit not implemented: %lx\n", ProcessInformationClass);
1118 break;
1119
1121 DPRINT1("WS Watch Not implemented: %lx\n", ProcessInformationClass);
1123 break;
1124
1126 DPRINT1("Pool limits Not implemented: %lx\n", ProcessInformationClass);
1128 break;
1129
1130 /* Not supported by Server 2003 */
1131 default:
1132 DPRINT1("Unsupported info class: %lx\n", ProcessInformationClass);
1134 }
1135
1136 /* Check if caller wants the return length and if there is one */
1137 if (ReturnLength != NULL && Length != 0)
1138 {
1139 /* Protect write with SEH */
1140 _SEH2_TRY
1141 {
1143 }
1145 {
1146 /* Get exception code.
1147 * Note: This overwrites any previous failure status. */
1149 }
1150 _SEH2_END;
1151 }
1152
1153 return Status;
1154}
1155
1156/*
1157 * @implemented
1158 */
1160NTAPI
1162 IN PROCESSINFOCLASS ProcessInformationClass,
1163 IN PVOID ProcessInformation,
1164 IN ULONG ProcessInformationLength)
1165{
1168 ACCESS_MASK Access;
1170 HANDLE PortHandle = NULL;
1174 PROCESS_PRIORITY_CLASS PriorityClass = {0};
1175 PROCESS_FOREGROUND_BACKGROUND Foreground = {0};
1176 PVOID ExceptionPort;
1177 ULONG Break;
1178 KAFFINITY ValidAffinity, Affinity = 0;
1179 KPRIORITY BasePriority = 0;
1180 UCHAR MemoryPriority = 0;
1181 BOOLEAN DisableBoost = 0;
1182 ULONG DefaultHardErrorMode = 0;
1183 ULONG DebugFlags = 0, EnableFixup = 0, Boost = 0;
1184 ULONG NoExecute = 0, VdmPower = 0;
1188 PAGED_CODE();
1189
1190 /* Verify Information Class validity */
1191 Status = DefaultSetInfoBufferCheck(ProcessInformationClass,
1194 ProcessInformation,
1195 ProcessInformationLength,
1196 PreviousMode);
1197 if (!NT_SUCCESS(Status))
1198 {
1199 DPRINT1("NtSetInformationProcess(): Information verification class failed! (Status -> 0x%lx, ProcessInformationClass -> %lx)\n", Status, ProcessInformationClass);
1200 return Status;
1201 }
1202
1203 /* Check what class this is */
1204 Access = PROCESS_SET_INFORMATION;
1205 if (ProcessInformationClass == ProcessSessionInformation)
1206 {
1207 /* Setting the Session ID needs a special mask */
1208 Access |= PROCESS_SET_SESSIONID;
1209 }
1210 else if (ProcessInformationClass == ProcessExceptionPort)
1211 {
1212 /* Setting the exception port needs a special mask */
1213 Access |= PROCESS_SUSPEND_RESUME;
1214 }
1215
1216 /* Reference the process */
1218 Access,
1221 (PVOID*)&Process,
1222 NULL);
1223 if (!NT_SUCCESS(Status)) return Status;
1224
1225 /* Check what kind of information class this is */
1226 switch (ProcessInformationClass)
1227 {
1229
1230 /* Check buffer length */
1231 if (ProcessInformationLength != sizeof(ULONG))
1232 {
1234 break;
1235 }
1236
1237 /* Use SEH for capture */
1238 _SEH2_TRY
1239 {
1240 /* Capture the boolean */
1241 VdmPower = *(PULONG)ProcessInformation;
1242 }
1244 {
1245 /* Get the exception code */
1247 _SEH2_YIELD(break);
1248 }
1249 _SEH2_END;
1250
1251 /* Getting VDM powers requires the SeTcbPrivilege */
1253 {
1254 /* We don't hold the privilege, bail out */
1256 DPRINT1("Need TCB privilege\n");
1257 break;
1258 }
1259
1260 /* Set or clear the flag */
1261 if (VdmPower)
1262 {
1264 }
1265 else
1266 {
1268 }
1269 break;
1270
1271 /* Error/Exception Port */
1273
1274 /* Check buffer length */
1275 if (ProcessInformationLength != sizeof(HANDLE))
1276 {
1278 break;
1279 }
1280
1281 /* Use SEH for capture */
1282 _SEH2_TRY
1283 {
1284 /* Capture the handle */
1285 PortHandle = *(PHANDLE)ProcessInformation;
1286 }
1288 {
1289 /* Get the exception code */
1291 _SEH2_YIELD(break);
1292 }
1293 _SEH2_END;
1294
1295 /* Setting the error port requires the SeTcbPrivilege */
1297 {
1298 /* We don't hold the privilege, bail out */
1300 break;
1301 }
1302
1303 /* Get the LPC Port */
1304 Status = ObReferenceObjectByHandle(PortHandle,
1305 0,
1308 (PVOID)&ExceptionPort,
1309 NULL);
1310 if (!NT_SUCCESS(Status)) break;
1311
1312 /* Change the pointer */
1313 if (InterlockedCompareExchangePointer(&Process->ExceptionPort,
1314 ExceptionPort,
1315 NULL))
1316 {
1317 /* We already had one, fail */
1318 ObDereferenceObject(ExceptionPort);
1320 }
1321 break;
1322
1323 /* Security Token */
1324 case ProcessAccessToken:
1325
1326 /* Check buffer length */
1327 if (ProcessInformationLength != sizeof(PROCESS_ACCESS_TOKEN))
1328 {
1330 break;
1331 }
1332
1333 /* Use SEH for capture */
1334 _SEH2_TRY
1335 {
1336 /* Save the token handle */
1337 TokenHandle = ((PPROCESS_ACCESS_TOKEN)ProcessInformation)->
1338 Token;
1339 }
1341 {
1342 /* Get the exception code */
1344 _SEH2_YIELD(break);
1345 }
1346 _SEH2_END;
1347
1348 /* Assign the actual token */
1350 break;
1351
1352 /* Hard error processing */
1354
1355 /* Check buffer length */
1356 if (ProcessInformationLength != sizeof(ULONG))
1357 {
1359 break;
1360 }
1361
1362 /* Enter SEH for direct buffer read */
1363 _SEH2_TRY
1364 {
1365 DefaultHardErrorMode = *(PULONG)ProcessInformation;
1366 }
1368 {
1369 /* Get exception code */
1371 _SEH2_YIELD(break);
1372 }
1373 _SEH2_END;
1374
1375 /* Set the mode */
1376 Process->DefaultHardErrorProcessing = DefaultHardErrorMode;
1377
1378 /* Call Ke for the update */
1379 if (DefaultHardErrorMode & SEM_NOALIGNMENTFAULTEXCEPT)
1380 {
1382 }
1383 else
1384 {
1386 }
1388 break;
1389
1390 /* Session ID */
1392
1393 /* Check buffer length */
1394 if (ProcessInformationLength != sizeof(PROCESS_SESSION_INFORMATION))
1395 {
1397 break;
1398 }
1399
1400 /* Enter SEH for capture */
1401 _SEH2_TRY
1402 {
1403 /* Capture the caller's buffer */
1404 SessionInfo = *(PPROCESS_SESSION_INFORMATION)ProcessInformation;
1405 }
1407 {
1408 /* Get the exception code */
1410 _SEH2_YIELD(break);
1411 }
1412 _SEH2_END;
1413
1414 /* Setting the session id requires the SeTcbPrivilege */
1416 {
1417 /* We don't hold the privilege, bail out */
1419 break;
1420 }
1421
1422#if 0 // OLD AND DEPRECATED CODE!!!!
1423
1424 /* FIXME - update the session id for the process token */
1425 //Status = PsLockProcess(Process, FALSE);
1426 if (!NT_SUCCESS(Status)) break;
1427
1428 /* Write the session ID in the EPROCESS */
1429 Process->Session = UlongToPtr(SessionInfo.SessionId); // HACK!!!
1430
1431 /* Check if the process also has a PEB */
1432 if (Process->Peb)
1433 {
1434 /*
1435 * Attach to the process to make sure we're in the right
1436 * context to access the PEB structure
1437 */
1438 KeAttachProcess(&Process->Pcb);
1439
1440 /* Enter SEH for write to user-mode PEB */
1441 _SEH2_TRY
1442 {
1443 /* Write the session ID */
1444 Process->Peb->SessionId = SessionInfo.SessionId;
1445 }
1447 {
1448 /* Get exception code */
1450 }
1451 _SEH2_END;
1452
1453 /* Detach from the process */
1455 }
1456
1457 /* Unlock the process */
1458 //PsUnlockProcess(Process);
1459
1460#endif
1461
1462 /*
1463 * Since we cannot change the session ID of the given
1464 * process anymore because it is set once and for all
1465 * at process creation time and because it is stored
1466 * inside the Process->Session structure managed by MM,
1467 * we fake changing it: we just return success if the
1468 * user-defined value is the same as the session ID of
1469 * the process, and otherwise we fail.
1470 */
1471 if (SessionInfo.SessionId == PsGetProcessSessionId(Process))
1472 {
1474 }
1475 else
1476 {
1478 }
1479
1480 break;
1481
1483
1484 /* Check buffer length */
1485 if (ProcessInformationLength != sizeof(PROCESS_PRIORITY_CLASS))
1486 {
1488 break;
1489 }
1490
1491 /* Enter SEH for capture */
1492 _SEH2_TRY
1493 {
1494 /* Capture the caller's buffer */
1495 PriorityClass = *(PPROCESS_PRIORITY_CLASS)ProcessInformation;
1496 }
1498 {
1499 /* Return the exception code */
1501 _SEH2_YIELD(break);
1502 }
1503 _SEH2_END;
1504
1505 /* Check for invalid PriorityClass value */
1507 {
1509 break;
1510 }
1511
1512 if ((PriorityClass.PriorityClass != Process->PriorityClass) &&
1514 {
1515 /* Check the privilege */
1519 PreviousMode);
1520 if (!HasPrivilege)
1521 {
1523 DPRINT1("Privilege to change priority to realtime lacking\n");
1525 }
1526 }
1527
1528 /* Check if we have a job */
1529 if (Process->Job)
1530 {
1531 DPRINT1("Jobs not yet supported\n");
1532 }
1533
1534 /* Set process priority class */
1535 Process->PriorityClass = PriorityClass.PriorityClass;
1536
1537 /* Set process priority mode (foreground or background) */
1539 PriorityClass.Foreground ?
1543 break;
1544
1546
1547 /* Check buffer length */
1548 if (ProcessInformationLength != sizeof(PROCESS_FOREGROUND_BACKGROUND))
1549 {
1551 break;
1552 }
1553
1554 /* Enter SEH for capture */
1555 _SEH2_TRY
1556 {
1557 /* Capture the caller's buffer */
1558 Foreground = *(PPROCESS_FOREGROUND_BACKGROUND)ProcessInformation;
1559 }
1561 {
1562 /* Return the exception code */
1564 _SEH2_YIELD(break);
1565 }
1566 _SEH2_END;
1567
1568 /* Set process priority mode (foreground or background) */
1570 Foreground.Foreground ?
1574 break;
1575
1577
1578 /* Validate input length */
1579 if (ProcessInformationLength != sizeof(KPRIORITY))
1580 {
1582 break;
1583 }
1584
1585 /* Enter SEH for direct buffer read */
1586 _SEH2_TRY
1587 {
1588 BasePriority = *(KPRIORITY*)ProcessInformation;
1589 }
1591 {
1592 /* Get exception code */
1593 Break = 0;
1595 _SEH2_YIELD(break);
1596 }
1597 _SEH2_END;
1598
1599 /* Extract the memory priority out of there */
1600 if (BasePriority & 0x80000000)
1601 {
1602 MemoryPriority = MEMORY_PRIORITY_FOREGROUND;
1603 BasePriority &= ~0x80000000;
1604 }
1605 else
1606 {
1607 MemoryPriority = MEMORY_PRIORITY_BACKGROUND;
1608 }
1609
1610 /* Validate the number */
1611 if ((BasePriority > HIGH_PRIORITY) || (BasePriority <= LOW_PRIORITY))
1612 {
1615 }
1616
1617 /* Check if the new base is higher */
1618 if (BasePriority > Process->Pcb.BasePriority)
1619 {
1623 PreviousMode);
1624 if (!HasPrivilege)
1625 {
1627 DPRINT1("Privilege to change priority from %lx to %lx lacking\n", BasePriority, Process->Pcb.BasePriority);
1629 }
1630 }
1631
1632 /* Call Ke */
1633 KeSetPriorityAndQuantumProcess(&Process->Pcb, BasePriority, 0);
1634
1635 /* Now set the memory priority */
1636 MmSetMemoryPriorityProcess(Process, MemoryPriority);
1638 break;
1639
1641
1642 /* Validate input length */
1643 if (ProcessInformationLength != sizeof(ULONG))
1644 {
1646 break;
1647 }
1648
1649 /* Enter SEH for direct buffer read */
1650 _SEH2_TRY
1651 {
1652 Boost = *(PULONG)ProcessInformation;
1653 }
1655 {
1656 /* Get exception code */
1657 Break = 0;
1659 _SEH2_YIELD(break);
1660 }
1661 _SEH2_END;
1662
1663 /* Make sure the process isn't dying */
1664 if (ExAcquireRundownProtection(&Process->RundownProtect))
1665 {
1666 /* Lock it */
1668 ExAcquirePushLockShared(&Process->ProcessLock);
1669
1670 /* Loop the threads */
1671 for (Next = Process->ThreadListHead.Flink;
1672 Next != &Process->ThreadListHead;
1673 Next = Next->Flink)
1674 {
1675 /* Call Ke for the thread */
1676 Thread = CONTAINING_RECORD(Next, ETHREAD, ThreadListEntry);
1678 }
1679
1680 /* Release the lock and rundown */
1681 ExReleasePushLockShared(&Process->ProcessLock);
1683 ExReleaseRundownProtection(&Process->RundownProtect);
1684
1685 /* Set success code */
1687 }
1688 else
1689 {
1690 /* Avoid race conditions */
1692 }
1693 break;
1694
1696
1697 /* Check buffer length */
1698 if (ProcessInformationLength != sizeof(ULONG))
1699 {
1701 break;
1702 }
1703
1704 /* Enter SEH for direct buffer read */
1705 _SEH2_TRY
1706 {
1707 Break = *(PULONG)ProcessInformation;
1708 }
1710 {
1711 /* Get exception code */
1712 Break = 0;
1714 _SEH2_YIELD(break);
1715 }
1716 _SEH2_END;
1717
1718 /* Setting 'break on termination' requires the SeDebugPrivilege */
1720 {
1721 /* We don't hold the privilege, bail out */
1723 break;
1724 }
1725
1726 /* Set or clear the flag */
1727 if (Break)
1728 {
1730 }
1731 else
1732 {
1734 }
1735
1736 break;
1737
1739
1740 /* Check buffer length */
1741 if (ProcessInformationLength != sizeof(KAFFINITY))
1742 {
1744 break;
1745 }
1746
1747 /* Enter SEH for direct buffer read */
1748 _SEH2_TRY
1749 {
1750 Affinity = *(PKAFFINITY)ProcessInformation;
1751 }
1753 {
1754 /* Get exception code */
1755 Break = 0;
1757 _SEH2_YIELD(break);
1758 }
1759 _SEH2_END;
1760
1761 /* Make sure it's valid for the CPUs present */
1762 ValidAffinity = Affinity & KeActiveProcessors;
1763 if (!Affinity || (ValidAffinity != Affinity))
1764 {
1766 break;
1767 }
1768
1769 /* Check if it's within job affinity limits */
1770 if (Process->Job)
1771 {
1772 /* Not yet implemented */
1775 break;
1776 }
1777
1778 /* Make sure the process isn't dying */
1779 if (ExAcquireRundownProtection(&Process->RundownProtect))
1780 {
1781 /* Lock it */
1783 ExAcquirePushLockShared(&Process->ProcessLock);
1784
1785 /* Call Ke to do the work */
1786 KeSetAffinityProcess(&Process->Pcb, ValidAffinity);
1787
1788 /* Release the lock and rundown */
1789 ExReleasePushLockShared(&Process->ProcessLock);
1791 ExReleaseRundownProtection(&Process->RundownProtect);
1792
1793 /* Set success code */
1795 }
1796 else
1797 {
1798 /* Avoid race conditions */
1800 }
1801 break;
1802
1803 /* Priority Boosting status */
1805
1806 /* Validate input length */
1807 if (ProcessInformationLength != sizeof(ULONG))
1808 {
1810 break;
1811 }
1812
1813 /* Enter SEH for direct buffer read */
1814 _SEH2_TRY
1815 {
1816 DisableBoost = *(PBOOLEAN)ProcessInformation;
1817 }
1819 {
1820 /* Get exception code */
1821 Break = 0;
1823 _SEH2_YIELD(break);
1824 }
1825 _SEH2_END;
1826
1827 /* Make sure the process isn't dying */
1828 if (ExAcquireRundownProtection(&Process->RundownProtect))
1829 {
1830 /* Lock it */
1832 ExAcquirePushLockShared(&Process->ProcessLock);
1833
1834 /* Call Ke to do the work */
1835 KeSetDisableBoostProcess(&Process->Pcb, DisableBoost);
1836
1837 /* Loop the threads too */
1838 for (Next = Process->ThreadListHead.Flink;
1839 Next != &Process->ThreadListHead;
1840 Next = Next->Flink)
1841 {
1842 /* Call Ke for the thread */
1843 Thread = CONTAINING_RECORD(Next, ETHREAD, ThreadListEntry);
1844 KeSetDisableBoostThread(&Thread->Tcb, DisableBoost);
1845 }
1846
1847 /* Release the lock and rundown */
1848 ExReleasePushLockShared(&Process->ProcessLock);
1850 ExReleaseRundownProtection(&Process->RundownProtect);
1851
1852 /* Set success code */
1854 }
1855 else
1856 {
1857 /* Avoid race conditions */
1859 }
1860 break;
1861
1862 case ProcessDebugFlags:
1863
1864 /* Check buffer length */
1865 if (ProcessInformationLength != sizeof(ULONG))
1866 {
1868 break;
1869 }
1870
1871 /* Enter SEH for direct buffer read */
1872 _SEH2_TRY
1873 {
1874 DebugFlags = *(PULONG)ProcessInformation;
1875 }
1877 {
1878 /* Get exception code */
1880 _SEH2_YIELD(break);
1881 }
1882 _SEH2_END;
1883
1884 /* Set the mode */
1885 if (DebugFlags & ~1)
1886 {
1888 }
1889 else
1890 {
1891 if (DebugFlags & 1)
1892 {
1894 }
1895 else
1896 {
1898 }
1899 }
1900
1901 /* Done */
1903 break;
1904
1906
1907 /* Check buffer length */
1908 if (ProcessInformationLength != sizeof(BOOLEAN))
1909 {
1911 break;
1912 }
1913
1914 /* Enter SEH for direct buffer read */
1915 _SEH2_TRY
1916 {
1917 EnableFixup = *(PULONG)ProcessInformation;
1918 }
1920 {
1921 /* Get exception code */
1923 _SEH2_YIELD(break);
1924 }
1925 _SEH2_END;
1926
1927 /* Set the mode */
1928 if (EnableFixup)
1929 {
1930 Process->DefaultHardErrorProcessing |= SEM_NOALIGNMENTFAULTEXCEPT;
1931 }
1932 else
1933 {
1934 Process->DefaultHardErrorProcessing &= ~SEM_NOALIGNMENTFAULTEXCEPT;
1935 }
1936
1937 /* Call Ke for the update */
1940 break;
1941
1943
1944 /* Only TCB can do this */
1946 {
1947 /* We don't hold the privilege, bail out */
1948 DPRINT1("Need TCB to set IOPL\n");
1950 break;
1951 }
1952
1953 /* Only supported on x86 */
1954#if defined (_X86_)
1955 Ke386SetIOPL();
1956#elif defined(_M_AMD64)
1957 /* On x64 this function isn't implemented.
1958 On Windows 2003 it returns success.
1959 On Vista+ it returns STATUS_NOT_IMPLEMENTED. */
1960 if ((ExGetPreviousMode() != KernelMode) &&
1961 (RtlRosGetAppcompatVersion() > _WIN32_WINNT_WS03))
1962 {
1964 }
1965#else
1967#endif
1968 /* Done */
1969 break;
1970
1972
1973 /* Check buffer length */
1974 if (ProcessInformationLength != sizeof(ULONG))
1975 {
1977 break;
1978 }
1979
1981 {
1983 break;
1984 }
1985
1986 /* Enter SEH for direct buffer read */
1987 _SEH2_TRY
1988 {
1989 NoExecute = *(PULONG)ProcessInformation;
1990 }
1992 {
1993 /* Get exception code */
1995 _SEH2_YIELD(break);
1996 }
1997 _SEH2_END;
1998
1999 /* Call Mm for the update */
2000 Status = MmSetExecuteOptions(NoExecute);
2001 break;
2002
2003 case ProcessDeviceMap:
2004
2005 /* Check buffer length */
2006 if (ProcessInformationLength != sizeof(HANDLE))
2007 {
2009 break;
2010 }
2011
2012 /* Use SEH for capture */
2013 _SEH2_TRY
2014 {
2015 /* Capture the handle */
2016 DirectoryHandle = *(PHANDLE)ProcessInformation;
2017 }
2019 {
2020 /* Get the exception code */
2022 _SEH2_YIELD(break);
2023 }
2024 _SEH2_END;
2025
2026 /* Call Ob to set the device map */
2028 break;
2029
2030
2031 /* We currently don't implement any of these */
2033 case ProcessLdtSize:
2035 DPRINT1("VDM/16-bit Request not implemented: %lx\n", ProcessInformationClass);
2037 break;
2038
2039 case ProcessQuotaLimits:
2040
2042 1,
2043 ProcessInformation,
2044 ProcessInformationLength,
2045 PreviousMode);
2046 break;
2047
2049 DPRINT1("WS watch not implemented\n");
2051 break;
2052
2054 DPRINT1("Handle tracing not implemented\n");
2056 break;
2057
2058 /* Anything else is invalid */
2059 default:
2060 DPRINT1("Invalid Server 2003 Info Class: %lx\n", ProcessInformationClass);
2062 }
2063
2064 /* Dereference and return status */
2066 return Status;
2067}
2068
2069/*
2070 * @implemented
2071 */
2073NTAPI
2076 IN PVOID ThreadInformation,
2078{
2083 KPRIORITY Priority = 0;
2084 KAFFINITY Affinity = 0, CombinedAffinity;
2085 PVOID Address = NULL;
2087 ULONG_PTR DisableBoost = 0;
2088 ULONG_PTR IdealProcessor = 0;
2089 ULONG_PTR Break = 0;
2090 PTEB Teb;
2091 ULONG_PTR TlsIndex = 0;
2092 PVOID *ExpansionSlots;
2093 PETHREAD ProcThread;
2095 PAGED_CODE();
2096
2097 /* Verify Information Class validity */
2101 ThreadInformation,
2103 PreviousMode);
2104 if (!NT_SUCCESS(Status))
2105 {
2106 DPRINT1("NtSetInformationThread(): Information verification class failed! (Status -> 0x%lx, ThreadInformationClass -> %lx)\n", Status, ThreadInformationClass);
2107 return Status;
2108 }
2109
2110 /* Check what kind of information class this is */
2111 switch (ThreadInformationClass)
2112 {
2113 /* Thread priority */
2114 case ThreadPriority:
2115
2116 /* Check buffer length */
2117 if (ThreadInformationLength != sizeof(KPRIORITY))
2118 {
2120 break;
2121 }
2122
2123 /* Use SEH for capture */
2124 _SEH2_TRY
2125 {
2126 /* Get the priority */
2127 Priority = *(PLONG)ThreadInformation;
2128 }
2130 {
2131 /* Get the exception code */
2133 _SEH2_YIELD(break);
2134 }
2135 _SEH2_END;
2136
2137 /* Validate it */
2138 if ((Priority > HIGH_PRIORITY) ||
2140 {
2141 /* Fail */
2143 break;
2144 }
2145
2146 /* Check for the required privilege */
2148 {
2150 ThreadHandle,
2152 PreviousMode);
2153 if (!HasPrivilege)
2154 {
2155 DPRINT1("Privilege to change priority to %lx lacking\n", Priority);
2157 }
2158 }
2159
2160 /* Reference the thread */
2161 Status = ObReferenceObjectByHandle(ThreadHandle,
2165 (PVOID*)&Thread,
2166 NULL);
2167 if (!NT_SUCCESS(Status))
2168 break;
2169
2170 /* Set the priority */
2172
2173 /* Dereference the thread */
2175 break;
2176
2177 case ThreadBasePriority:
2178
2179 /* Check buffer length */
2180 if (ThreadInformationLength != sizeof(LONG))
2181 {
2183 break;
2184 }
2185
2186 /* Use SEH for capture */
2187 _SEH2_TRY
2188 {
2189 /* Get the priority */
2190 Priority = *(PLONG)ThreadInformation;
2191 }
2193 {
2194 /* Get the exception code */
2196 _SEH2_YIELD(break);
2197 }
2198 _SEH2_END;
2199
2200 /* Validate it */
2203 {
2204 /* These ones are OK */
2205 if ((Priority != THREAD_BASE_PRIORITY_LOWRT + 1) &&
2207 {
2208 /* Check if the process is real time */
2209 if (PsGetCurrentProcess()->PriorityClass !=
2211 {
2212 /* It isn't, fail */
2214 break;
2215 }
2216 }
2217 }
2218
2219 /* Reference the thread */
2220 Status = ObReferenceObjectByHandle(ThreadHandle,
2224 (PVOID*)&Thread,
2225 NULL);
2226 if (!NT_SUCCESS(Status))
2227 break;
2228
2229 /* Set the base priority */
2231
2232 /* Dereference the thread */
2234 break;
2235
2236 case ThreadAffinityMask:
2237
2238 /* Check buffer length */
2239 if (ThreadInformationLength != sizeof(ULONG_PTR))
2240 {
2242 break;
2243 }
2244
2245 /* Use SEH for capture */
2246 _SEH2_TRY
2247 {
2248 /* Get the priority */
2249 Affinity = *(PULONG_PTR)ThreadInformation;
2250 }
2252 {
2253 /* Get the exception code */
2255 _SEH2_YIELD(break);
2256 }
2257 _SEH2_END;
2258
2259 /* Validate it */
2260 if (!Affinity)
2261 {
2262 /* Fail */
2264 break;
2265 }
2266
2267 /* Reference the thread */
2268 Status = ObReferenceObjectByHandle(ThreadHandle,
2272 (PVOID*)&Thread,
2273 NULL);
2274 if (!NT_SUCCESS(Status))
2275 break;
2276
2277 /* Get the process */
2278 Process = Thread->ThreadsProcess;
2279
2280 /* Try to acquire rundown */
2281 if (ExAcquireRundownProtection(&Process->RundownProtect))
2282 {
2283 /* Lock it */
2285 ExAcquirePushLockShared(&Process->ProcessLock);
2286
2287 /* Combine masks */
2288 CombinedAffinity = Affinity & Process->Pcb.Affinity;
2289 if (CombinedAffinity != Affinity)
2290 {
2291 /* Fail */
2293 }
2294 else
2295 {
2296 /* Set the affinity */
2297 KeSetAffinityThread(&Thread->Tcb, CombinedAffinity);
2298 }
2299
2300 /* Release the lock and rundown */
2301 ExReleasePushLockShared(&Process->ProcessLock);
2303 ExReleaseRundownProtection(&Process->RundownProtect);
2304 }
2305 else
2306 {
2307 /* Too late */
2309 }
2310
2311 /* Dereference the thread */
2313 break;
2314
2316
2317 /* Check buffer length */
2318 if (ThreadInformationLength != sizeof(HANDLE))
2319 {
2321 break;
2322 }
2323
2324 /* Use SEH for capture */
2325 _SEH2_TRY
2326 {
2327 /* Save the token handle */
2328 TokenHandle = *(PHANDLE)ThreadInformation;
2329 }
2331 {
2332 /* Get the exception code */
2334 _SEH2_YIELD(break);
2335 }
2336 _SEH2_END;
2337
2338 /* Reference the thread */
2339 Status = ObReferenceObjectByHandle(ThreadHandle,
2343 (PVOID*)&Thread,
2344 NULL);
2345 if (!NT_SUCCESS(Status))
2346 break;
2347
2348 /* Assign the actual token */
2350
2351 /* Dereference the thread */
2353 break;
2354
2356
2357 /* Check buffer length */
2358 if (ThreadInformationLength != sizeof(ULONG_PTR))
2359 {
2361 break;
2362 }
2363
2364 /* Use SEH for capture */
2365 _SEH2_TRY
2366 {
2367 /* Get the priority */
2368 Address = *(PVOID*)ThreadInformation;
2369 }
2371 {
2372 /* Get the exception code */
2374 _SEH2_YIELD(break);
2375 }
2376 _SEH2_END;
2377
2378 /* Reference the thread */
2379 Status = ObReferenceObjectByHandle(ThreadHandle,
2383 (PVOID*)&Thread,
2384 NULL);
2385 if (!NT_SUCCESS(Status))
2386 break;
2387
2388 /* Set the address */
2390
2391 /* Dereference the thread */
2393 break;
2394
2396
2397 /* Check buffer length */
2398 if (ThreadInformationLength != sizeof(ULONG_PTR))
2399 {
2401 break;
2402 }
2403
2404 /* Use SEH for capture */
2405 _SEH2_TRY
2406 {
2407 /* Get the priority */
2408 IdealProcessor = *(PULONG_PTR)ThreadInformation;
2409 }
2411 {
2412 /* Get the exception code */
2414 _SEH2_YIELD(break);
2415 }
2416 _SEH2_END;
2417
2418 /* Validate it */
2419 if (IdealProcessor > MAXIMUM_PROCESSORS)
2420 {
2421 /* Fail */
2423 break;
2424 }
2425
2426 /* Reference the thread */
2427 Status = ObReferenceObjectByHandle(ThreadHandle,
2431 (PVOID*)&Thread,
2432 NULL);
2433 if (!NT_SUCCESS(Status))
2434 break;
2435
2436 /* Set the ideal */
2438 (CCHAR)IdealProcessor);
2439
2440 /* Get the TEB and protect the thread */
2441 Teb = Thread->Tcb.Teb;
2443 {
2444 /* Save the ideal processor */
2445 Teb->IdealProcessor = Thread->Tcb.IdealProcessor;
2446
2447 /* Release rundown protection */
2449 }
2450
2451 /* Dereference the thread */
2453 break;
2454
2456
2457 /* Check buffer length */
2458 if (ThreadInformationLength != sizeof(ULONG_PTR))
2459 {
2461 break;
2462 }
2463
2464 /* Use SEH for capture */
2465 _SEH2_TRY
2466 {
2467 /* Get the priority */
2468 DisableBoost = *(PULONG_PTR)ThreadInformation;
2469 }
2471 {
2472 /* Get the exception code */
2474 _SEH2_YIELD(break);
2475 }
2476 _SEH2_END;
2477
2478 /* Reference the thread */
2479 Status = ObReferenceObjectByHandle(ThreadHandle,
2483 (PVOID*)&Thread,
2484 NULL);
2485 if (!NT_SUCCESS(Status))
2486 break;
2487
2488 /* Call the kernel */
2489 KeSetDisableBoostThread(&Thread->Tcb, (BOOLEAN)DisableBoost);
2490
2491 /* Dereference the thread */
2493 break;
2494
2495 case ThreadZeroTlsCell:
2496
2497 /* Check buffer length */
2498 if (ThreadInformationLength != sizeof(ULONG))
2499 {
2501 break;
2502 }
2503
2504 /* Use SEH for capture */
2505 _SEH2_TRY
2506 {
2507 /* Get the priority */
2508 TlsIndex = *(PULONG)ThreadInformation;
2509 }
2511 {
2512 /* Get the exception code */
2514 _SEH2_YIELD(break);
2515 }
2516 _SEH2_END;
2517
2518 /* Reference the thread */
2519 Status = ObReferenceObjectByHandle(ThreadHandle,
2523 (PVOID*)&Thread,
2524 NULL);
2525 if (!NT_SUCCESS(Status))
2526 break;
2527
2528 /* This is only valid for the current thread */
2529 if (Thread != PsGetCurrentThread())
2530 {
2531 /* Fail */
2534 break;
2535 }
2536
2537 /* Get the process */
2538 Process = Thread->ThreadsProcess;
2539
2540 /* Loop the threads */
2541 ProcThread = PsGetNextProcessThread(Process, NULL);
2542 while (ProcThread)
2543 {
2544 /* Acquire rundown */
2546 {
2547 /* Get the TEB */
2548 Teb = ProcThread->Tcb.Teb;
2549 if (Teb)
2550 {
2551 /* Check if we're in the expansion range */
2553 {
2556 {
2557 /* Check if we have expansion slots */
2558 ExpansionSlots = Teb->TlsExpansionSlots;
2559 if (ExpansionSlots)
2560 {
2561 /* Clear the index */
2562 ExpansionSlots[TlsIndex - TLS_MINIMUM_AVAILABLE] = 0;
2563 }
2564 }
2565 }
2566 else
2567 {
2568 /* Clear the index */
2569 Teb->TlsSlots[TlsIndex] = NULL;
2570 }
2571 }
2572
2573 /* Release rundown */
2575 }
2576
2577 /* Go to the next thread */
2578 ProcThread = PsGetNextProcessThread(Process, ProcThread);
2579 }
2580
2581 /* Dereference the thread */
2583 break;
2584
2586
2587 /* Check buffer length */
2588 if (ThreadInformationLength != sizeof(ULONG))
2589 {
2591 break;
2592 }
2593
2594 /* Enter SEH for direct buffer read */
2595 _SEH2_TRY
2596 {
2597 Break = *(PULONG)ThreadInformation;
2598 }
2600 {
2601 /* Get exception code */
2602 Break = 0;
2604 _SEH2_YIELD(break);
2605 }
2606 _SEH2_END;
2607
2608 /* Setting 'break on termination' requires the SeDebugPrivilege */
2610 {
2611 /* We don't hold the privilege, bail out */
2613 break;
2614 }
2615
2616 /* Reference the thread */
2617 Status = ObReferenceObjectByHandle(ThreadHandle,
2621 (PVOID*)&Thread,
2622 NULL);
2623 if (!NT_SUCCESS(Status))
2624 break;
2625
2626 /* Set or clear the flag */
2627 if (Break)
2628 {
2630 }
2631 else
2632 {
2634 }
2635
2636 /* Dereference the thread */
2638 break;
2639
2641
2642 /* Check buffer length */
2643 if (ThreadInformationLength != 0)
2644 {
2646 break;
2647 }
2648
2649 /* Reference the thread */
2650 Status = ObReferenceObjectByHandle(ThreadHandle,
2654 (PVOID*)&Thread,
2655 NULL);
2656 if (!NT_SUCCESS(Status))
2657 break;
2658
2659 /* Set the flag */
2661
2662 /* Dereference the thread */
2664 break;
2665
2666 default:
2667 /* We don't implement it yet */
2668 DPRINT1("Not implemented: %d\n", ThreadInformationClass);
2670 }
2671
2672 return Status;
2673}
2674
2675/*
2676 * @implemented
2677 */
2679NTAPI
2682 OUT PVOID ThreadInformation,
2685{
2689 ULONG Access;
2690 ULONG Length = 0;
2691 PTHREAD_BASIC_INFORMATION ThreadBasicInfo =
2692 (PTHREAD_BASIC_INFORMATION)ThreadInformation;
2693 PKERNEL_USER_TIMES ThreadTime = (PKERNEL_USER_TIMES)ThreadInformation;
2694 KIRQL OldIrql;
2695 ULONG ThreadTerminated;
2696 PAGED_CODE();
2697
2698 /* Verify Information Class validity */
2703 ThreadInformation,
2706 NULL,
2707 PreviousMode);
2708 if (!NT_SUCCESS(Status))
2709 {
2710 DPRINT1("NtQueryInformationThread(): Information verification class failed! (Status -> 0x%lx , ThreadInformationClass -> %lx)\n", Status, ThreadInformationClass);
2711 return Status;
2712 }
2713
2714 /* Check what class this is */
2715 Access = THREAD_QUERY_INFORMATION;
2716
2717 /* Check what kind of information class this is */
2718 switch (ThreadInformationClass)
2719 {
2720 /* Basic thread information */
2722
2723 /* Set return length */
2725
2727 {
2729 break;
2730 }
2731
2732 /* Reference the process */
2733 Status = ObReferenceObjectByHandle(ThreadHandle,
2734 Access,
2737 (PVOID*)&Thread,
2738 NULL);
2739 if (!NT_SUCCESS(Status))
2740 break;
2741
2742 /* Protect writes with SEH */
2743 _SEH2_TRY
2744 {
2745 /* Write all the information from the ETHREAD/KTHREAD */
2746 ThreadBasicInfo->ExitStatus = Thread->ExitStatus;
2747 ThreadBasicInfo->TebBaseAddress = (PVOID)Thread->Tcb.Teb;
2748 ThreadBasicInfo->ClientId = Thread->Cid;
2749 ThreadBasicInfo->AffinityMask = Thread->Tcb.Affinity;
2750 ThreadBasicInfo->Priority = Thread->Tcb.Priority;
2751 ThreadBasicInfo->BasePriority = KeQueryBasePriorityThread(&Thread->Tcb);
2752 }
2754 {
2755 /* Get exception code */
2757 }
2758 _SEH2_END;
2759
2760 /* Dereference the thread */
2762 break;
2763
2764 /* Thread time information */
2765 case ThreadTimes:
2766
2767 /* Set the return length */
2768 Length = sizeof(KERNEL_USER_TIMES);
2769
2771 {
2773 break;
2774 }
2775
2776 /* Reference the process */
2777 Status = ObReferenceObjectByHandle(ThreadHandle,
2778 Access,
2781 (PVOID*)&Thread,
2782 NULL);
2783 if (!NT_SUCCESS(Status))
2784 break;
2785
2786 /* Protect writes with SEH */
2787 _SEH2_TRY
2788 {
2789 /* Copy time information from ETHREAD/KTHREAD */
2792 ThreadTime->CreateTime = Thread->CreateTime;
2793
2794 /* Exit time is in a union and only valid on actual exit! */
2796 {
2797 ThreadTime->ExitTime = Thread->ExitTime;
2798 }
2799 else
2800 {
2801 ThreadTime->ExitTime.QuadPart = 0;
2802 }
2803 }
2805 {
2806 /* Get exception code */
2808 }
2809 _SEH2_END;
2810
2811 /* Dereference the thread */
2813 break;
2814
2816
2817 /* Set the return length*/
2818 Length = sizeof(PVOID);
2819
2821 {
2823 break;
2824 }
2825
2826 /* Reference the process */
2827 Status = ObReferenceObjectByHandle(ThreadHandle,
2828 Access,
2831 (PVOID*)&Thread,
2832 NULL);
2833 if (!NT_SUCCESS(Status))
2834 break;
2835
2836 /* Protect write with SEH */
2837 _SEH2_TRY
2838 {
2839 /* Return the Win32 Start Address */
2840 *(PVOID*)ThreadInformation = Thread->Win32StartAddress;
2841 }
2843 {
2844 /* Get exception code */
2846 }
2847 _SEH2_END;
2848
2849 /* Dereference the thread */
2851 break;
2852
2854
2855 /* Set the return length*/
2856 Length = sizeof(LARGE_INTEGER);
2857
2859 {
2861 break;
2862 }
2863
2864 /* Reference the process */
2865 Status = ObReferenceObjectByHandle(ThreadHandle,
2866 Access,
2869 (PVOID*)&Thread,
2870 NULL);
2871 if (!NT_SUCCESS(Status))
2872 break;
2873
2874 /* Protect write with SEH */
2875 _SEH2_TRY
2876 {
2877 /* FIXME */
2878 (*(PLARGE_INTEGER)ThreadInformation).QuadPart = 0;
2879 }
2881 {
2882 /* Get exception code */
2884 }
2885 _SEH2_END;
2886
2887 /* Dereference the thread */
2889 break;
2890
2892
2893 /* Set the return length*/
2894 Length = sizeof(ULONG);
2895
2897 {
2899 break;
2900 }
2901
2902 /* Reference the process */
2903 Status = ObReferenceObjectByHandle(ThreadHandle,
2904 Access,
2907 (PVOID*)&Thread,
2908 NULL);
2909 if (!NT_SUCCESS(Status))
2910 break;
2911
2912 /* Protect write with SEH */
2913 _SEH2_TRY
2914 {
2915 /* Return whether or not we are the last thread */
2916 *(PULONG)ThreadInformation = ((Thread->ThreadsProcess->
2917 ThreadListHead.Flink->Flink ==
2918 &Thread->ThreadsProcess->
2920 TRUE : FALSE);
2921 }
2923 {
2924 /* Get exception code */
2926 }
2927 _SEH2_END;
2928
2929 /* Dereference the thread */
2931 break;
2932
2933 case ThreadIsIoPending:
2934
2935 /* Set the return length*/
2936 Length = sizeof(ULONG);
2937
2939 {
2941 break;
2942 }
2943
2944 /* Reference the process */
2945 Status = ObReferenceObjectByHandle(ThreadHandle,
2946 Access,
2949 (PVOID*)&Thread,
2950 NULL);
2951 if (!NT_SUCCESS(Status))
2952 break;
2953
2954 /* Raise the IRQL to protect the IRP list */
2956
2957 /* Protect write with SEH */
2958 _SEH2_TRY
2959 {
2960 /* Check if the IRP list is empty or not */
2961 *(PULONG)ThreadInformation = !IsListEmpty(&Thread->IrpList);
2962 }
2964 {
2965 /* Get exception code */
2967 }
2968 _SEH2_END;
2969
2970 /* Lower IRQL back */
2972
2973 /* Dereference the thread */
2975 break;
2976
2977 /* LDT and GDT information */
2979
2980#if defined(_X86_)
2981 /* Reference the process */
2982 Status = ObReferenceObjectByHandle(ThreadHandle,
2983 Access,
2986 (PVOID*)&Thread,
2987 NULL);
2988 if (!NT_SUCCESS(Status))
2989 break;
2990
2991 /* Call the worker routine */
2993 ThreadInformation,
2995 ReturnLength);
2996
2997 /* Dereference the thread */
2999#else
3000 /* Only implemented on x86 */
3002#endif
3003 break;
3004
3006
3007 /* Set the return length*/
3008 Length = sizeof(ULONG);
3009
3011 {
3013 break;
3014 }
3015
3016 /* Reference the process */
3017 Status = ObReferenceObjectByHandle(ThreadHandle,
3018 Access,
3021 (PVOID*)&Thread,
3022 NULL);
3023 if (!NT_SUCCESS(Status))
3024 break;
3025
3026 _SEH2_TRY
3027 {
3028 *(PULONG)ThreadInformation = Thread->Tcb.DisableBoost ? 1 : 0;
3029 }
3031 {
3033 }
3034 _SEH2_END;
3035
3036 /* Dereference the thread */
3038 break;
3039
3040 case ThreadIsTerminated:
3041
3042 /* Set the return length*/
3043 Length = sizeof(ThreadTerminated);
3044
3046 {
3048 break;
3049 }
3050
3051 /* Reference the process */
3052 Status = ObReferenceObjectByHandle(ThreadHandle,
3053 Access,
3056 (PVOID*)&Thread,
3057 NULL);
3058 if (!NT_SUCCESS(Status))
3059 break;
3060
3061 ThreadTerminated = PsIsThreadTerminating(Thread);
3062
3063 _SEH2_TRY
3064 {
3065 *(PULONG)ThreadInformation = ThreadTerminated ? 1 : 0;
3066 }
3068 {
3070 }
3071 _SEH2_END;
3072
3073 /* Dereference the thread */
3075 break;
3076
3077 /* Anything else */
3078 default:
3079
3080 /* Not yet implemented */
3081 DPRINT1("Not implemented: %lx\n", ThreadInformationClass);
3083 }
3084
3085 /* Protect write with SEH */
3086 _SEH2_TRY
3087 {
3088 /* Check if caller wanted return length */
3090 }
3092 {
3093 /* Get exception code */
3095 }
3096 _SEH2_END;
3097
3098 return Status;
3099}
3100
3101/* EOF */
#define PAGED_CODE()
#define STATUS_PRIVILEGE_NOT_HELD
Definition: DriverTester.h:9
_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
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
@ ProcessDebugPort
Definition: cicbase.cpp:45
@ ProcessBreakOnTermination
Definition: cicbase.cpp:48
@ ProcessBasicInformation
Definition: cicbase.cpp:44
@ ProcessWow64Information
Definition: cicbase.cpp:46
@ ProcessImageFileName
Definition: cicbase.cpp:47
enum _PROCESSINFOCLASS PROCESSINFOCLASS
Definition: loader.c:63
#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
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
struct _PROCESS_BASIC_INFORMATION * PPROCESS_BASIC_INFORMATION
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: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
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: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: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: 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:1540
VOID NTAPI MmGetImageInformation(OUT PSECTION_IMAGE_INFORMATION ImageInformation)
Definition: section.c:1617
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
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:2680
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:1161
NTSTATUS NTAPI NtSetInformationThread(IN HANDLE ThreadHandle, IN THREADINFOCLASS ThreadInformationClass, IN PVOID ThreadInformation, IN ULONG ThreadInformationLength)
Definition: query.c:2074
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 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
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:181
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:82
#define _SEH2_END
Definition: pseh2_64.h:171
#define _SEH2_TRY
Definition: pseh2_64.h:71
#define _SEH2_YIELD(__stmt)
Definition: pseh2_64.h:184
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
STDMETHOD() Next(THIS_ ULONG celt, IAssociationElement *pElement, ULONG *pceltFetched) PURE
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: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
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: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 * 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
LONGLONG QuadPart
Definition: typedefs.h:114
struct _LARGE_INTEGER::@2473 u
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
unsigned char UCHAR
Definition: xmlstorage.h:181