ReactOS 0.4.17-dev-683-g0dafdc5
query.c File Reference
#include <ntoskrnl.h>
#include <debug.h>
Include dependency graph for query.c:

Go to the source code of this file.

Macros

#define NDEBUG
 

Functions

NTSTATUS NTAPI PsReferenceProcessFilePointer (_In_ PEPROCESS Process, _Outptr_ PFILE_OBJECT *FileObject)
 
NTSTATUS NTAPI NtQueryInformationProcess (_In_ HANDLE ProcessHandle, _In_ PROCESSINFOCLASS ProcessInformationClass, _Out_writes_bytes_to_opt_(ProcessInformationLength, *ReturnLength) PVOID ProcessInformation, _In_ ULONG ProcessInformationLength, _Out_opt_ PULONG ReturnLength)
 
NTSTATUS NTAPI NtSetInformationProcess (_In_ HANDLE ProcessHandle, _In_ PROCESSINFOCLASS ProcessInformationClass, _In_reads_bytes_(ProcessInformationLength) PVOID ProcessInformation, _In_ ULONG ProcessInformationLength)
 
NTSTATUS NTAPI NtSetInformationThread (_In_ HANDLE ThreadHandle, _In_ THREADINFOCLASS ThreadInformationClass, _In_reads_bytes_(ThreadInformationLength) PVOID ThreadInformation, _In_ ULONG ThreadInformationLength)
 
NTSTATUS NTAPI NtQueryInformationThread (_In_ HANDLE ThreadHandle, _In_ THREADINFOCLASS ThreadInformationClass, _Out_writes_bytes_to_opt_(ThreadInformationLength, *ReturnLength) PVOID ThreadInformation, _In_ ULONG ThreadInformationLength, _Out_opt_ PULONG ReturnLength)
 

Variables

ULONG PspTraceLevel = 0
 

Macro Definition Documentation

◆ NDEBUG

#define NDEBUG

Definition at line 14 of file query.c.

Function Documentation

◆ NtQueryInformationProcess()

NTSTATUS NTAPI NtQueryInformationProcess ( _In_ HANDLE  ProcessHandle,
_In_ PROCESSINFOCLASS  ProcessInformationClass,
_Out_writes_bytes_to_opt_(ProcessInformationLength, *ReturnLength) PVOID  ProcessInformation,
_In_ ULONG  ProcessInformationLength,
_Out_opt_ PULONG  ReturnLength 
)

Definition at line 211 of file query.c.

218{
222 ULONG Length = 0;
223
224 PAGED_CODE();
225
226 /* Validate the information class */
227 Status = DefaultQueryInfoBufferCheck(ProcessInformationClass,
231 ProcessInformation,
232 ProcessInformationLength,
234 NULL,
236 if (!NT_SUCCESS(Status))
237 {
238#if DBG
239 DPRINT1("NtQueryInformationProcess(ProcessInformationClass: %s): Class validation failed! (Status: 0x%lx)\n",
240 PspDumpProcessInfoClassName(ProcessInformationClass), Status);
241#endif
242 return Status;
243 }
244
245 if (((ProcessInformationClass == ProcessCookie) ||
246 (ProcessInformationClass == ProcessImageInformation)) &&
248 {
249 /*
250 * Retrieving the process cookie is only allowed for the calling process
251 * itself! XP only allows NtCurrentProcess() as process handles even if
252 * a real handle actually represents the current process.
253 */
255 }
256
257 /* Check the information class */
258 switch (ProcessInformationClass)
259 {
260 /* Basic process information */
262 {
263 PPROCESS_BASIC_INFORMATION ProcessBasicInfo = (PPROCESS_BASIC_INFORMATION)ProcessInformation;
264
265 if (ProcessInformationLength != sizeof(PROCESS_BASIC_INFORMATION))
266 {
268 break;
269 }
270
271 /* Set the return length */
273
274 /* Reference the process */
279 (PVOID*)&Process,
280 NULL);
281 if (!NT_SUCCESS(Status)) break;
282
283 /* Protect writes with SEH */
285 {
286 /* Write all the information from the EPROCESS/KPROCESS */
287 ProcessBasicInfo->ExitStatus = Process->ExitStatus;
288 ProcessBasicInfo->PebBaseAddress = Process->Peb;
289 ProcessBasicInfo->AffinityMask = Process->Pcb.Affinity;
290 ProcessBasicInfo->UniqueProcessId = (ULONG_PTR)Process->
291 UniqueProcessId;
292 ProcessBasicInfo->InheritedFromUniqueProcessId =
293 (ULONG_PTR)Process->InheritedFromUniqueProcessId;
294 ProcessBasicInfo->BasePriority = Process->Pcb.BasePriority;
295
296 }
298 {
299 /* Get exception code */
301 }
302 _SEH2_END;
303
304 /* Dereference the process */
306 break;
307 }
308
309 /* Process quota limits */
311 {
312 QUOTA_LIMITS_EX QuotaLimits;
313 BOOLEAN Extended;
314
315 if (ProcessInformationLength != sizeof(QUOTA_LIMITS) &&
316 ProcessInformationLength != sizeof(QUOTA_LIMITS_EX))
317 {
319 break;
320 }
321
322 /* Set the return length */
323 Length = ProcessInformationLength;
324 Extended = (Length == sizeof(QUOTA_LIMITS_EX));
325
326 /* Reference the process */
331 (PVOID*)&Process,
332 NULL);
333 if (!NT_SUCCESS(Status)) break;
334
335 /* Indicate success */
337
338 RtlZeroMemory(&QuotaLimits, sizeof(QuotaLimits));
339
340 /* Get max/min working set sizes */
341 QuotaLimits.MaximumWorkingSetSize =
342 Process->Vm.MaximumWorkingSetSize << PAGE_SHIFT;
343 QuotaLimits.MinimumWorkingSetSize =
344 Process->Vm.MinimumWorkingSetSize << PAGE_SHIFT;
345
346 /* Get default time limits */
347 QuotaLimits.TimeLimit.QuadPart = -1LL;
348
349 /* Is quota block a default one? */
350 if (Process->QuotaBlock == &PspDefaultQuotaBlock)
351 {
352 /* Get default pools and pagefile limits */
353 QuotaLimits.PagedPoolLimit = (SIZE_T)-1;
354 QuotaLimits.NonPagedPoolLimit = (SIZE_T)-1;
355 QuotaLimits.PagefileLimit = (SIZE_T)-1;
356 }
357 else
358 {
359 /* Get limits from non-default quota block */
360 QuotaLimits.PagedPoolLimit =
361 Process->QuotaBlock->QuotaEntry[PsPagedPool].Limit;
362 QuotaLimits.NonPagedPoolLimit =
363 Process->QuotaBlock->QuotaEntry[PsNonPagedPool].Limit;
364 QuotaLimits.PagefileLimit =
365 Process->QuotaBlock->QuotaEntry[PsPageFile].Limit;
366 }
367
368 /* Get additional information, if needed */
369 if (Extended)
370 {
371 QuotaLimits.Flags |= (Process->Vm.Flags.MaximumWorkingSetHard ?
373 QuotaLimits.Flags |= (Process->Vm.Flags.MinimumWorkingSetHard ?
375
376 /* FIXME: Get the correct information */
377 //QuotaLimits.WorkingSetLimit = (SIZE_T)-1; // Not used on Win2k3, it is set to 0
378 QuotaLimits.CpuRateLimit.RateData = 0;
379 }
380
381 /* Protect writes with SEH */
383 {
384 RtlCopyMemory(ProcessInformation, &QuotaLimits, Length);
385 }
387 {
388 /* Get exception code */
390 }
391 _SEH2_END;
392
393 /* Dereference the process */
395 break;
396 }
397
399 {
400 PIO_COUNTERS IoCounters = (PIO_COUNTERS)ProcessInformation;
401 PROCESS_VALUES ProcessValues;
402
403 if (ProcessInformationLength != sizeof(IO_COUNTERS))
404 {
406 break;
407 }
408
409 Length = sizeof(IO_COUNTERS);
410
411 /* Reference the process */
416 (PVOID*)&Process,
417 NULL);
418 if (!NT_SUCCESS(Status)) break;
419
420 /* Query IO counters from the process */
421 KeQueryValuesProcess(&Process->Pcb, &ProcessValues);
422
424 {
425 RtlCopyMemory(IoCounters, &ProcessValues.IoInfo, sizeof(IO_COUNTERS));
426 }
428 {
429 /* Ignore exception */
430 }
431 _SEH2_END;
432
433 /* Set status to success in any case */
435
436 /* Dereference the process */
438 break;
439 }
440
441 /* Timing */
442 case ProcessTimes:
443 {
444 PKERNEL_USER_TIMES ProcessTime = (PKERNEL_USER_TIMES)ProcessInformation;
445 ULONG UserTime, KernelTime;
446
447 /* Set the return length */
448 if (ProcessInformationLength != sizeof(KERNEL_USER_TIMES))
449 {
451 break;
452 }
453
454 Length = sizeof(KERNEL_USER_TIMES);
455
456 /* Reference the process */
461 (PVOID*)&Process,
462 NULL);
463 if (!NT_SUCCESS(Status)) break;
464
465 /* Protect writes with SEH */
467 {
468 /* Copy time information from EPROCESS/KPROCESS */
469 KernelTime = KeQueryRuntimeProcess(&Process->Pcb, &UserTime);
470 ProcessTime->CreateTime = Process->CreateTime;
472 ProcessTime->KernelTime.QuadPart = (LONGLONG)KernelTime * KeMaximumIncrement;
473 ProcessTime->ExitTime = Process->ExitTime;
474 }
476 {
477 /* Get exception code */
479 }
480 _SEH2_END;
481
482 /* Dereference the process */
484 break;
485 }
486
487 /* Process Debug Port */
488 case ProcessDebugPort:
489
490 if (ProcessInformationLength != sizeof(HANDLE))
491 {
493 break;
494 }
495
496 /* Set the return length */
497 Length = sizeof(HANDLE);
498
499 /* Reference the process */
504 (PVOID*)&Process,
505 NULL);
506 if (!NT_SUCCESS(Status)) break;
507
508 /* Protect write with SEH */
510 {
511 /* Return whether or not we have a debug port */
512 *(PHANDLE)ProcessInformation = (Process->DebugPort ?
513 (HANDLE)-1 : NULL);
514 }
516 {
517 /* Get exception code */
519 }
520 _SEH2_END;
521
522 /* Dereference the process */
524 break;
525
527 {
529
530 if (ProcessInformationLength != sizeof(ULONG))
531 {
533 break;
534 }
535
536 /* Set the return length*/
537 Length = sizeof(ULONG);
538
539 /* Reference the process */
544 (PVOID*)&Process,
545 NULL);
546 if (!NT_SUCCESS(Status)) break;
547
548 /* Count the number of handles this process has */
550
551 /* Protect write in SEH */
553 {
554 /* Return the count of handles */
555 *(PULONG)ProcessInformation = HandleCount;
556 }
558 {
559 /* Get the exception code */
561 }
562 _SEH2_END;
563
564 /* Dereference the process */
566 break;
567 }
568
569 /* Session ID for the process */
571 {
573
574 if (ProcessInformationLength != sizeof(PROCESS_SESSION_INFORMATION))
575 {
577 break;
578 }
579
580 /* Set the return length*/
582
583 /* Reference the process */
588 (PVOID*)&Process,
589 NULL);
590 if (!NT_SUCCESS(Status)) break;
591
592 /* Enter SEH for write safety */
594 {
595 /* Write back the Session ID */
597 }
599 {
600 /* Get the exception code */
602 }
603 _SEH2_END;
604
605 /* Dereference the process */
607 break;
608 }
609
610 /* Virtual Memory Statistics */
612 {
613 PVM_COUNTERS VmCounters = (PVM_COUNTERS)ProcessInformation;
614
615 /* Validate the input length */
616 if ((ProcessInformationLength != sizeof(VM_COUNTERS)) &&
617 (ProcessInformationLength != sizeof(VM_COUNTERS_EX)))
618 {
620 break;
621 }
622
623 /* Reference the process */
628 (PVOID*)&Process,
629 NULL);
630 if (!NT_SUCCESS(Status)) break;
631
632 /* Enter SEH for write safety */
634 {
635 /* Return data from EPROCESS */
636 VmCounters->PeakVirtualSize = Process->PeakVirtualSize;
637 VmCounters->VirtualSize = Process->VirtualSize;
638 VmCounters->PageFaultCount = Process->Vm.PageFaultCount;
639 VmCounters->PeakWorkingSetSize = Process->Vm.PeakWorkingSetSize;
640 VmCounters->WorkingSetSize = Process->Vm.WorkingSetSize;
641 VmCounters->QuotaPeakPagedPoolUsage = Process->QuotaPeak[PsPagedPool];
642 VmCounters->QuotaPagedPoolUsage = Process->QuotaUsage[PsPagedPool];
643 VmCounters->QuotaPeakNonPagedPoolUsage = Process->QuotaPeak[PsNonPagedPool];
644 VmCounters->QuotaNonPagedPoolUsage = Process->QuotaUsage[PsNonPagedPool];
645 VmCounters->PagefileUsage = Process->QuotaUsage[PsPageFile] << PAGE_SHIFT;
646 VmCounters->PeakPagefileUsage = Process->QuotaPeak[PsPageFile] << PAGE_SHIFT;
647 //VmCounters->PrivateUsage = Process->CommitCharge << PAGE_SHIFT;
648 //
649
650 /* Set the return length */
651 Length = ProcessInformationLength;
652 }
654 {
655 /* Get the exception code */
657 }
658 _SEH2_END;
659
660 /* Dereference the process */
662 break;
663 }
664
665 /* Hard Error Processing Mode */
667
668 if (ProcessInformationLength != sizeof(ULONG))
669 {
671 break;
672 }
673
674 /* Set the return length*/
675 Length = sizeof(ULONG);
676
677 /* Reference the process */
682 (PVOID*)&Process,
683 NULL);
684 if (!NT_SUCCESS(Status)) break;
685
686 /* Enter SEH for writing back data */
688 {
689 /* Write the current processing mode */
690 *(PULONG)ProcessInformation = Process->
691 DefaultHardErrorProcessing;
692 }
694 {
695 /* Get the exception code */
697 }
698 _SEH2_END;
699
700 /* Dereference the process */
702 break;
703
704 /* Priority Boosting status */
706
707 if (ProcessInformationLength != sizeof(ULONG))
708 {
710 break;
711 }
712
713 /* Set the return length */
714 Length = sizeof(ULONG);
715
716 /* Reference the process */
721 (PVOID*)&Process,
722 NULL);
723 if (!NT_SUCCESS(Status)) break;
724
725 /* Enter SEH for writing back data */
727 {
728 /* Return boost status */
729 *(PULONG)ProcessInformation = Process->Pcb.DisableBoost ?
730 TRUE : FALSE;
731 }
733 {
734 /* Get the exception code */
736 }
737 _SEH2_END;
738
739 /* Dereference the process */
741 break;
742
743 /* DOS Device Map */
744 case ProcessDeviceMap:
745 {
746 ULONG Flags;
747
748 if (ProcessInformationLength == sizeof(PROCESS_DEVICEMAP_INFORMATION_EX))
749 {
750 /* Protect read in SEH */
752 {
753 PPROCESS_DEVICEMAP_INFORMATION_EX DeviceMapEx = ProcessInformation;
754
755 Flags = DeviceMapEx->Flags;
756 }
758 {
759 /* Get the exception code */
761 _SEH2_YIELD(break);
762 }
763 _SEH2_END;
764
765 /* Only one flag is supported and it needs LUID mappings */
766 if ((Flags & ~PROCESS_LUID_DOSDEVICES_ONLY) != 0 ||
768 {
770 break;
771 }
772 }
773 else
774 {
775 /* This has to be the size of the Query union field for x64 compatibility! */
776 if (ProcessInformationLength != RTL_FIELD_SIZE(PROCESS_DEVICEMAP_INFORMATION, Query))
777 {
779 break;
780 }
781
782 /* No flags for standard call */
783 Flags = 0;
784 }
785
786 /* Set the return length */
787 Length = ProcessInformationLength;
788
789 /* Reference the process */
794 (PVOID*)&Process,
795 NULL);
796 if (!NT_SUCCESS(Status)) break;
797
798 /* Query the device map information */
800 ProcessInformation,
801 Flags);
802
803 /* Dereference the process */
805 break;
806 }
807
808 /* Priority class */
810 {
811 PPROCESS_PRIORITY_CLASS PsPriorityClass = (PPROCESS_PRIORITY_CLASS)ProcessInformation;
812
813 if (ProcessInformationLength != sizeof(PROCESS_PRIORITY_CLASS))
814 {
816 break;
817 }
818
819 /* Set the return length*/
821
822 /* Reference the process */
827 (PVOID*)&Process,
828 NULL);
829 if (!NT_SUCCESS(Status)) break;
830
831 /* Enter SEH for writing back data */
833 {
834 /* Return current priority class */
835 PsPriorityClass->PriorityClass = Process->PriorityClass;
836 PsPriorityClass->Foreground = FALSE;
837 }
839 {
840 /* Get the exception code */
842 }
843 _SEH2_END;
844
845 /* Dereference the process */
847 break;
848 }
849
851 {
853
854 /* Reference the process */
859 (PVOID*)&Process,
860 NULL);
861 if (!NT_SUCCESS(Status)) break;
862
863 /* Get the image path */
865 if (NT_SUCCESS(Status))
866 {
867 /* Set the return length */
868 Length = ImageName->MaximumLength +
870
871 /* Make sure it's large enough */
872 if (Length <= ProcessInformationLength)
873 {
874 /* Enter SEH to protect write */
876 {
877 /* Copy it */
878 RtlCopyMemory(ProcessInformation,
879 ImageName,
880 Length);
881
882 /* Update pointer */
883 ((PUNICODE_STRING)ProcessInformation)->Buffer =
884 (PWSTR)((PUNICODE_STRING)ProcessInformation + 1);
885 }
887 {
888 /* Get the exception code */
890 }
891 _SEH2_END;
892 }
893 else
894 {
895 /* Buffer too small */
897 }
898
899 /* Free the image path */
901 }
902 /* Dereference the process */
904 break;
905 }
906
907#if (NTDDI_VERSION >= NTDDI_VISTA) || (DLL_EXPORT_VERSION >= _WIN32_WINNT_VISTA)
909 {
912
913 /* Reference the process */
915 // FIXME: Use PROCESS_QUERY_LIMITED_INFORMATION when implemented
919 (PVOID*)&Process,
920 NULL);
921 if (!NT_SUCCESS(Status))
922 {
923 break;
924 }
925
926 /* Get the image path */
929 if (!NT_SUCCESS(Status))
930 {
931 break;
932 }
935 if (!NT_SUCCESS(Status))
936 {
937 break;
938 }
939
940 /* Determine return length and output */
941 Length = sizeof(UNICODE_STRING) + ObjectNameInformation->Name.MaximumLength;
942 if (Length <= ProcessInformationLength)
943 {
945 {
946 PUNICODE_STRING ImageName = (PUNICODE_STRING)ProcessInformation;
947 ImageName->Length = ObjectNameInformation->Name.Length;
948 ImageName->MaximumLength = ObjectNameInformation->Name.MaximumLength;
949 if (ObjectNameInformation->Name.MaximumLength)
950 {
951 ImageName->Buffer = (PWSTR)(ImageName + 1);
952 RtlCopyMemory(ImageName->Buffer,
953 ObjectNameInformation->Name.Buffer,
954 ObjectNameInformation->Name.MaximumLength);
955 }
956 else
957 {
958 ASSERT(ImageName->Length == 0);
959 ImageName->Buffer = NULL;
960 }
961 }
963 {
965 }
966 _SEH2_END;
967 }
968 else
969 {
971 }
973
974 break;
975 }
976#endif /* (NTDDI_VERSION >= NTDDI_VISTA) || (DLL_EXPORT_VERSION >= _WIN32_WINNT_VISTA) */
977
979
980 if (ProcessInformationLength != sizeof(ULONG))
981 {
983 break;
984 }
985
986 /* Set the return length*/
987 Length = sizeof(ULONG);
988
989 /* Reference the process */
994 (PVOID*)&Process,
995 NULL);
996 if (!NT_SUCCESS(Status)) break;
997
998 /* Enter SEH for writing back data */
1000 {
1001 /* Return the debug flag state */
1002 *(PULONG)ProcessInformation = Process->NoDebugInherit ? 0 : 1;
1003 }
1005 {
1006 /* Get the exception code */
1008 }
1009 _SEH2_END;
1010
1011 /* Dereference the process */
1013 break;
1014
1016
1017 if (ProcessInformationLength != sizeof(ULONG))
1018 {
1020 break;
1021 }
1022
1023 /* Set the return length */
1024 Length = sizeof(ULONG);
1025
1026 /* Reference the process */
1031 (PVOID*)&Process,
1032 NULL);
1033 if (!NT_SUCCESS(Status)) break;
1034
1035 /* Enter SEH for writing back data */
1036 _SEH2_TRY
1037 {
1038 /* Return the BreakOnTermination state */
1039 *(PULONG)ProcessInformation = Process->BreakOnTermination;
1040 }
1042 {
1043 /* Get the exception code */
1045 }
1046 _SEH2_END;
1047
1048 /* Dereference the process */
1050 break;
1051
1052 /* Per-process security cookie */
1053 case ProcessCookie:
1054 {
1055 ULONG Cookie;
1056
1057 if (ProcessInformationLength != sizeof(ULONG))
1058 {
1059 /* Length size wrong, bail out */
1061 break;
1062 }
1063
1064 /* Get the current process and cookie */
1066 Cookie = Process->Cookie;
1067 if (!Cookie)
1068 {
1069 LARGE_INTEGER SystemTime;
1070 ULONG NewCookie;
1071 PKPRCB Prcb;
1072
1073 /* Generate a new cookie */
1074 KeQuerySystemTime(&SystemTime);
1075 Prcb = KeGetCurrentPrcb();
1076 NewCookie = Prcb->KeSystemCalls ^ Prcb->InterruptTime ^
1077 SystemTime.u.LowPart ^ SystemTime.u.HighPart;
1078
1079 /* Set the new cookie or return the current one */
1081 NewCookie,
1082 Cookie);
1083 if (!Cookie) Cookie = NewCookie;
1084
1085 /* Set the return length */
1086 Length = sizeof(ULONG);
1087 }
1088
1089 /* Indicate success */
1091
1092 /* Enter SEH to protect write */
1093 _SEH2_TRY
1094 {
1095 /* Write back the cookie */
1096 *(PULONG)ProcessInformation = Cookie;
1097 }
1099 {
1100 /* Get the exception code */
1102 }
1103 _SEH2_END;
1104 break;
1105 }
1106
1108
1109 if (ProcessInformationLength != sizeof(SECTION_IMAGE_INFORMATION))
1110 {
1111 /* Break out */
1113 break;
1114 }
1115
1116 /* Set the length required and validate it */
1118
1119 /* Indicate success */
1121
1122 /* Enter SEH to protect write */
1123 _SEH2_TRY
1124 {
1126 }
1128 {
1129 /* Get the exception code */
1131 }
1132 _SEH2_END;
1133 break;
1134
1136 {
1137 HANDLE DebugPort = NULL;
1138
1139 if (ProcessInformationLength != sizeof(HANDLE))
1140 {
1142 break;
1143 }
1144
1145 /* Set the return length */
1146 Length = sizeof(HANDLE);
1147
1148 /* Reference the process */
1153 (PVOID*)&Process,
1154 NULL);
1155 if (!NT_SUCCESS(Status)) break;
1156
1157 /* Get the debug port. Continue even if this fails. */
1159
1160 /* Let go of the process */
1162
1163 /* Protect write in SEH */
1164 _SEH2_TRY
1165 {
1166 /* Return debug port's handle */
1167 *(PHANDLE)ProcessInformation = DebugPort;
1168 }
1170 {
1171 if (DebugPort)
1172 ObCloseHandle(DebugPort, PreviousMode);
1173
1174 /* Get the exception code.
1175 * Note: This overwrites any previous failure status. */
1177 }
1178 _SEH2_END;
1179 break;
1180 }
1181
1183 DPRINT1("Handle tracing not implemented: %lu\n", ProcessInformationClass);
1185 break;
1186
1188
1189 if (ProcessInformationLength != sizeof(ULONG))
1190 {
1192 break;
1193 }
1194
1195 /* Set the return length */
1196 Length = sizeof(ULONG);
1197
1198 /* Indicate success */
1200
1201 /* Protect write in SEH */
1202 _SEH2_TRY
1203 {
1204 /* Query Ob */
1205 *(PULONG)ProcessInformation = ObIsLUIDDeviceMapsEnabled();
1206 }
1208 {
1209 /* Get the exception code */
1211 }
1212 _SEH2_END;
1213 break;
1214
1216
1217 if (ProcessInformationLength != sizeof(ULONG))
1218 {
1220 break;
1221 }
1222
1223 /* Set the return length */
1224 Length = sizeof(ULONG);
1225
1226 /* Reference the process */
1231 (PVOID*)&Process,
1232 NULL);
1233 if (!NT_SUCCESS(Status)) break;
1234
1235 /* Protect write in SEH */
1236 _SEH2_TRY
1237 {
1238 /* Return if the flag is set */
1239 *(PULONG)ProcessInformation = (ULONG)Process->VdmAllowed;
1240 }
1242 {
1243 /* Get the exception code */
1245 }
1246 _SEH2_END;
1247
1248 /* Dereference the process */
1250 break;
1251
1253 {
1254 ULONG_PTR Wow64 = 0;
1255
1256 if (ProcessInformationLength != sizeof(ULONG_PTR))
1257 {
1259 break;
1260 }
1261
1262 /* Set the return length */
1263 Length = sizeof(ULONG_PTR);
1264
1265 /* Reference the process */
1270 (PVOID*)&Process,
1271 NULL);
1272 if (!NT_SUCCESS(Status)) break;
1273
1274#if defined(_WIN64) && defined(BUILD_WOW64_ENABLED)
1275 /* Make sure the process isn't dying */
1276 if (ExAcquireRundownProtection(&Process->RundownProtect))
1277 {
1278 /* FIXME: A two-part hack: delay setting Process->Wow64Process,
1279 so 64-bit NTDLL can use IO to init stuff. */
1280 if (IS_WOW64_PROCESS_INITIALIZING(Process))
1281 {
1284 if (!Process->Wow64Process)
1285 {
1287
1289 Process->Wow64Process = UlongToPtr(1);
1290 }
1291 else
1292 {
1293 Process->Wow64Process->Wow64 = (PVOID)((ULONG_PTR)(Process->Peb) + ROUND_TO_PAGES(sizeof(PEB)));
1294 }
1295 }
1296
1297 /* Get the WOW64 process structure */
1298 if (Process->Wow64Process == NULL)
1299 {
1300 Wow64 = 0;
1301 }
1302 /* FIXME */
1303 else if (IS_WOW64_PROCESS_INITIALIZING(Process))
1304 {
1305 Wow64 = TRUE;
1306 }
1307 else
1308 {
1309 Wow64 = (ULONG_PTR)Process->Wow64Process->Wow64;
1310 }
1311
1312 /* Release the lock */
1313 ExReleaseRundownProtection(&Process->RundownProtect);
1314 }
1315#endif
1316
1317 /* Dereference the process */
1319
1320 /* Protect write with SEH */
1321 _SEH2_TRY
1322 {
1323 /* Return the Wow64 process information */
1324 *(PULONG_PTR)ProcessInformation = Wow64;
1325 }
1327 {
1328 /* Get exception code */
1330 }
1331 _SEH2_END;
1332 break;
1333 }
1334
1336 {
1337 ULONG ExecuteOptions = 0;
1338
1339 if (ProcessInformationLength != sizeof(ULONG))
1340 {
1342 break;
1343 }
1344
1345 /* Set the return length */
1346 Length = sizeof(ULONG);
1347
1349 {
1351 break;
1352 }
1353
1354 /* Get the options */
1355 Status = MmGetExecuteOptions(&ExecuteOptions);
1356 if (NT_SUCCESS(Status))
1357 {
1358 /* Protect write with SEH */
1359 _SEH2_TRY
1360 {
1361 /* Return them */
1362 *(PULONG)ProcessInformation = ExecuteOptions;
1363 }
1365 {
1366 /* Get exception code */
1368 }
1369 _SEH2_END;
1370 }
1371 break;
1372 }
1373
1375 DPRINT1("VDM/16-bit not implemented: %lu\n", ProcessInformationClass);
1377 break;
1378
1380 DPRINT1("WS Watch not implemented: %lu\n", ProcessInformationClass);
1382 break;
1383
1385 DPRINT1("Pool limits not implemented: %lu\n", ProcessInformationClass);
1387 break;
1388
1389 /* Not supported by Server 2003 */
1390 default:
1391#if DBG
1392 DPRINT1("Unsupported info class: %s\n", PspDumpProcessInfoClassName(ProcessInformationClass));
1393#endif
1395 }
1396
1397 /* Check if caller wants the return length and if there is one */
1398 if (ReturnLength != NULL && Length != 0)
1399 {
1400 /* Protect write with SEH */
1401 _SEH2_TRY
1402 {
1404 }
1406 {
1407 /* Get exception code.
1408 * Note: This overwrites any previous failure status. */
1410 }
1411 _SEH2_END;
1412 }
1413
1414 return Status;
1415}
#define PAGED_CODE()
@ ObjectNameInformation
Definition: DriverTester.h:55
_In_ PVOID _In_ ULONG _Out_ PVOID _In_ ULONG _Inout_ PULONG ReturnLength
_In_ PVOID _In_ ULONG _Out_ PVOID _In_ ULONG _Inout_ PULONG _In_ KPROCESSOR_MODE PreviousMode
#define RTL_NUMBER_OF(x)
Definition: RtlRegistry.c:12
unsigned char BOOLEAN
Definition: actypes.h:127
LONG NTSTATUS
Definition: precomp.h:26
#define DPRINT1
Definition: precomp.h:8
BOOL Query(LPCTSTR *ServiceArgs, DWORD ArgCount, BOOL bExtended)
Definition: query.c:292
@ ProcessDebugPort
Definition: cicbase.cpp:64
@ ProcessBreakOnTermination
Definition: cicbase.cpp:67
@ ProcessBasicInformation
Definition: cicbase.cpp:63
@ ProcessWow64Information
Definition: cicbase.cpp:65
@ ProcessImageFileName
Definition: cicbase.cpp:66
#define STATUS_NO_MEMORY
Definition: d3dkmdt.h:51
#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
#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 ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define PAGE_SHIFT
Definition: env_spec_w32.h:45
#define KeQuerySystemTime(t)
Definition: env_spec_w32.h:570
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
struct _UNICODE_STRING UNICODE_STRING
#define NonPagedPool
Definition: env_spec_w32.h:307
#define ExReleaseRundownProtection
Definition: ex.h:139
#define ExGetPreviousMode
Definition: ex.h:143
#define ExAcquireRundownProtection
Definition: ex.h:138
_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:24
#define ICIF_PROBE_READ
Definition: icif.h:25
struct _PROCESS_PRIORITY_CLASS PROCESS_PRIORITY_CLASS
#define PROCESS_QUERY_INFORMATION
Definition: pstypes.h:162
struct _PROCESS_PRIORITY_CLASS * PPROCESS_PRIORITY_CLASS
@ PsNonPagedPool
Definition: pstypes.h:1116
@ PsPageFile
Definition: pstypes.h:1118
@ PsPagedPool
Definition: pstypes.h:1117
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:90
#define QUOTA_LIMITS_HARDWS_MIN_DISABLE
#define PROCESS_LUID_DOSDEVICES_ONLY
Definition: pstypes.h:228
struct _IO_COUNTERS IO_COUNTERS
struct _PROCESS_SESSION_INFORMATION PROCESS_SESSION_INFORMATION
struct _PROCESS_SESSION_INFORMATION * PPROCESS_SESSION_INFORMATION
#define QUOTA_LIMITS_HARDWS_MAX_DISABLE
struct _QUOTA_LIMITS_EX QUOTA_LIMITS_EX
#define QUOTA_LIMITS_HARDWS_MAX_ENABLE
#define QUOTA_LIMITS_HARDWS_MIN_ENABLE
struct _IO_COUNTERS * PIO_COUNTERS
#define InterlockedCompareExchange
Definition: interlocked.h:119
#define RTL_FIELD_SIZE(type, field)
Definition: kdb_expr.c:86
if(dx< 0)
Definition: linetemp.h:194
#define ASSERT(a)
Definition: mode.c:44
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
static const char * ImageName
Definition: image.c:34
FORCEINLINE struct _KPRCB * KeGetCurrentPrcb(VOID)
Definition: ketypes.h:1197
_In_ HANDLE ProcessHandle
Definition: mmfuncs.h:407
struct _SECTION_IMAGE_INFORMATION SECTION_IMAGE_INFORMATION
#define NtCurrentProcess()
Definition: nt_native.h:1660
struct _OBJECT_NAME_INFORMATION OBJECT_NAME_INFORMATION
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
ULONG NTAPI KeQueryRuntimeProcess(IN PKPROCESS Process, OUT PULONG UserTime)
Definition: procobj.c:860
VOID NTAPI KeQueryValuesProcess(IN PKPROCESS Process, PPROCESS_VALUES Values)
Definition: procobj.c:525
VOID NTAPI MmGetImageInformation(OUT PSECTION_IMAGE_INFORMATION ImageInformation)
Definition: section.c:1623
NTSTATUS NTAPI MmGetExecuteOptions(IN PULONG ExecuteOptions)
Definition: pagfault.c:2669
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
NTSTATUS NTAPI IoQueryFileDosDeviceName(IN PFILE_OBJECT FileObject, OUT POBJECT_NAME_INFORMATION *ObjectNameInformation)
Definition: file.c:3662
ULONG KeMaximumIncrement
Definition: clock.c:20
POBJECT_TYPE PsProcessType
Definition: process.c:20
ULONG NTAPI PsGetProcessSessionId(IN PEPROCESS Process)
Definition: process.c:1163
NTSTATUS NTAPI PsReferenceProcessFilePointer(_In_ PEPROCESS Process, _Outptr_ PFILE_OBJECT *FileObject)
Definition: query.c:24
NTSTATUS NTAPI SeLocateProcessImageName(_In_ PEPROCESS Process, _Out_ PUNICODE_STRING *ProcessImageName)
Finds the process image name of a specific process.
Definition: audit.c:199
PVOID *typedef PHANDLE
Definition: ntsecpkg.h:455
#define STATUS_INVALID_INFO_CLASS
Definition: ntstatus.h:333
ULONG NTAPI ObGetProcessHandleCount(IN PEPROCESS Process)
Definition: obhandle.c:56
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:3406
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:493
long LONG
Definition: pedump.c:60
EPROCESS_QUOTA_BLOCK PspDefaultQuotaBlock
Definition: quota.c:16
static const INFORMATION_CLASS_INFO PsProcessInfoClass[]
Definition: ps_i.h:15
struct _PROCESS_BASIC_INFORMATION * PPROCESS_BASIC_INFORMATION
struct _PROCESS_BASIC_INFORMATION PROCESS_BASIC_INFORMATION
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:204
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:104
#define _SEH2_END
Definition: pseh2_64.h:194
#define _SEH2_TRY
Definition: pseh2_64.h:93
#define _SEH2_YIELD(__stmt)
Definition: pseh2_64.h:207
NTSTATUS NTAPI PsChargeProcessNonPagedPoolQuota(_In_ PEPROCESS Process, _In_ SIZE_T Amount)
Charges the non paged pool quota of a given process.
Definition: quota.c:811
VOID NTAPI PsReturnProcessNonPagedPoolQuota(_In_ PEPROCESS Process, _In_ SIZE_T Amount)
Returns the non paged quota pool that the process was taking up.
Definition: quota.c:938
#define STATUS_SUCCESS
Definition: shellext.h:65
LARGE_INTEGER UserTime
Definition: winternl.h:2377
LARGE_INTEGER CreateTime
Definition: winternl.h:2374
LARGE_INTEGER KernelTime
Definition: winternl.h:2376
LARGE_INTEGER ExitTime
Definition: winternl.h:2375
ULONG InterruptTime
Definition: ketypes.h:840
ULONG KeSystemCalls
Definition: ketypes.h:751
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
SIZE_T PeakWorkingSetSize
Definition: winternl.h:3134
SIZE_T PeakPagefileUsage
Definition: winternl.h:3141
ULONG PageFaultCount
Definition: winternl.h:3133
SIZE_T QuotaPagedPoolUsage
Definition: winternl.h:3137
SIZE_T QuotaPeakPagedPoolUsage
Definition: winternl.h:3136
SIZE_T QuotaPeakNonPagedPoolUsage
Definition: winternl.h:3138
SIZE_T PeakVirtualSize
Definition: winternl.h:3131
SIZE_T VirtualSize
Definition: winternl.h:3132
SIZE_T QuotaNonPagedPoolUsage
Definition: winternl.h:3139
SIZE_T WorkingSetSize
Definition: winternl.h:3135
SIZE_T PagefileUsage
Definition: winternl.h:3140
#define TAG_SEPA
Definition: tag.h:158
#define TAG_PS_WOW64
Definition: tag.h:141
uint16_t * PWSTR
Definition: typedefs.h:56
uint32_t * PULONG_PTR
Definition: typedefs.h:65
uint32_t * PULONG
Definition: typedefs.h:59
int64_t LONGLONG
Definition: typedefs.h:68
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
uint32_t ULONG
Definition: typedefs.h:59
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define STATUS_INFO_LENGTH_MISMATCH
Definition: udferr_usr.h:133
static ULONG HandleCount
Definition: uefidisk.c:67
LONGLONG QuadPart
Definition: typedefs.h:114
struct _LARGE_INTEGER::@2524 u
ULONG RateData
Definition: pstypes.h:60
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:550
struct _KERNEL_USER_TIMES KERNEL_USER_TIMES
struct _KERNEL_USER_TIMES * PKERNEL_USER_TIMES
@ ProcessLUIDDeviceMapsEnabled
Definition: winternl.h:1910
@ ProcessWx86Information
Definition: winternl.h:1901
@ ProcessDebugFlags
Definition: winternl.h:1913
@ ProcessSessionInformation
Definition: winternl.h:1906
@ ProcessVmCounters
Definition: winternl.h:1885
@ ProcessPriorityClass
Definition: winternl.h:1900
@ ProcessPriorityBoost
Definition: winternl.h:1904
@ ProcessImageInformation
Definition: winternl.h:1919
@ ProcessExecuteFlags
Definition: winternl.h:1916
@ ProcessCookie
Definition: winternl.h:1918
@ ProcessPooledUsageAndLimits
Definition: winternl.h:1896
@ ProcessIoCounters
Definition: winternl.h:1884
@ ProcessImageFileNameWin32
Definition: winternl.h:1925
@ ProcessDefaultHardErrorMode
Definition: winternl.h:1894
@ ProcessDeviceMap
Definition: winternl.h:1905
@ ProcessQuotaLimits
Definition: winternl.h:1883
@ ProcessHandleTracing
Definition: winternl.h:1914
@ ProcessTimes
Definition: winternl.h:1886
@ ProcessDebugObjectHandle
Definition: winternl.h:1912
@ ProcessWorkingSetWatch
Definition: winternl.h:1897
@ ProcessLdtInformation
Definition: winternl.h:1892
@ ProcessHandleCount
Definition: winternl.h:1902
struct _VM_COUNTERS * PVM_COUNTERS
struct _VM_COUNTERS_EX VM_COUNTERS_EX
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
_In_opt_ PVOID _Out_ PLARGE_INTEGER Cookie
Definition: cmfuncs.h:14
* PFILE_OBJECT
Definition: iotypes.h:1998
_Out_ PULONG UserTime
Definition: kefuncs.h:759
CCHAR KPROCESSOR_MODE
Definition: ketypes.h:7
#define ROUND_TO_PAGES(Size)
#define ObDereferenceObject
Definition: obfuncs.h:203
#define PsGetCurrentProcess
Definition: psfuncs.h:17

Referenced by _main(), BaseInitializeStaticServerData(), check_live_target(), CheckRemoteDebuggerPresent(), CON_API_NOCONSOLE(), EmptyWorkingSet(), EnumProcessModules(), FindModule(), get_shiminfo(), getCommandLineFromProcess(), GetDriveTypeW(), GetErrorMode(), GetExitCodeProcess(), GetLogicalDrives(), GetPriorityClass(), GetProcessAffinityMask(), GetProcessExecutablePath(), GetProcessHandleCount(), GetProcessId(), GetProcessImageFileNameA(), GetProcessImageFileNameW(), GetProcessIoCounters(), GetProcessMemoryInfo(), GetProcessPriorityBoost(), GetProcessTimes(), GetProcessVersion(), GetProcessWorkingSetSizeEx(), GetSourcePaths(), GetWsChanges(), GlobalMemoryStatusEx(), init_module_iterator(), init_module_iterator_wow64(), Is64BitSystem(), IsCriticalProcess(), IsWow64Process(), PerfDataGetCommandLine(), PrintProcess(), ProcessIdToSessionId(), PsaEnumerateProcessModules(), QueryFlag(), QueryFullProcessImageNameW(), QueryProcessCycleTime(), QuerySetProcessValidator(), RtlpQueryRemoteProcessModules(), RtlWow64GetProcessMachines(), SmpApiLoop(), SmpCreateVolumeDescriptors(), SmpGetProcessMuSessionId(), test_affinity(), test_amd64_shared_info(), test_dead_process(), test_debuggee_dbgport(), test_exec_memory_writes(), test_GlobalMemoryStatus(), test_mapprotection(), test_nt_wow64(), test_NtGetCurrentProcessorNumber(), test_peb_teb(), test_process_id(), test_process_machine(), Test_ProcessBasicInformation(), Test_ProcessPriorityClassAlignment(), Test_ProcessQuotaLimits(), Test_ProcessQuotaLimitsEx(), Test_ProcessTimes(), Test_ProcessWx86Information(), test_query_process(), test_query_process_basic(), test_query_process_debug_flags(), test_query_process_debug_object_handle(), test_query_process_debug_port(), test_query_process_handlecount(), test_query_process_image_file_name(), test_query_process_image_info(), test_query_process_io(), test_query_process_priority(), test_query_process_quota_limits(), test_query_process_times(), test_query_process_vm(), test_query_process_wow64(), test_redirection(), test_section_access(), test_wow64_shared_info(), UnhandledExceptionFilter(), UserpGetClientFileName(), wmain(), and Wow64QueryFlag().

◆ NtQueryInformationThread()

NTSTATUS NTAPI NtQueryInformationThread ( _In_ HANDLE  ThreadHandle,
_In_ THREADINFOCLASS  ThreadInformationClass,
_Out_writes_bytes_to_opt_(ThreadInformationLength, *ReturnLength) PVOID  ThreadInformation,
_In_ ULONG  ThreadInformationLength,
_Out_opt_ PULONG  ReturnLength 
)

Definition at line 3017 of file query.c.

3024{
3028 ULONG Access;
3029 ULONG Length = 0;
3030
3031 PAGED_CODE();
3032
3033 /* Validate the information class */
3038 ThreadInformation,
3041 NULL,
3042 PreviousMode);
3043 if (!NT_SUCCESS(Status))
3044 {
3045#if DBG
3046 DPRINT1("NtQueryInformationThread(ThreadInformationClass: %s): Class validation failed! (Status: 0x%lx)\n",
3047 PspDumpThreadInfoClassName(ThreadInformationClass), Status);
3048#endif
3049 return Status;
3050 }
3051
3052 /* Check what class this is */
3053 Access = THREAD_QUERY_INFORMATION;
3054
3055 /* Check what kind of information class this is */
3056 switch (ThreadInformationClass)
3057 {
3058 /* Basic thread information */
3060 {
3061 PTHREAD_BASIC_INFORMATION ThreadBasicInfo =
3062 (PTHREAD_BASIC_INFORMATION)ThreadInformation;
3063
3064 /* Set the return length */
3066
3068 {
3070 break;
3071 }
3072
3073 /* Reference the thread */
3074 Status = ObReferenceObjectByHandle(ThreadHandle,
3075 Access,
3078 (PVOID*)&Thread,
3079 NULL);
3080 if (!NT_SUCCESS(Status))
3081 break;
3082
3083 /* Protect writes with SEH */
3084 _SEH2_TRY
3085 {
3086 /* Write all the information from the ETHREAD/KTHREAD */
3087 ThreadBasicInfo->ExitStatus = Thread->ExitStatus;
3088 ThreadBasicInfo->TebBaseAddress = (PVOID)Thread->Tcb.Teb;
3089 ThreadBasicInfo->ClientId = Thread->Cid;
3090 ThreadBasicInfo->AffinityMask = Thread->Tcb.Affinity;
3091 ThreadBasicInfo->Priority = Thread->Tcb.Priority;
3092 ThreadBasicInfo->BasePriority = KeQueryBasePriorityThread(&Thread->Tcb);
3093 }
3095 {
3096 /* Get exception code */
3098 }
3099 _SEH2_END;
3100
3101 /* Dereference the thread */
3103 break;
3104 }
3105
3106 /* Thread time information */
3107 case ThreadTimes:
3108 {
3109 PKERNEL_USER_TIMES ThreadTime = (PKERNEL_USER_TIMES)ThreadInformation;
3110
3111 /* Set the return length */
3112 Length = sizeof(KERNEL_USER_TIMES);
3113
3115 {
3117 break;
3118 }
3119
3120 /* Reference the thread */
3121 Status = ObReferenceObjectByHandle(ThreadHandle,
3122 Access,
3125 (PVOID*)&Thread,
3126 NULL);
3127 if (!NT_SUCCESS(Status))
3128 break;
3129
3130 /* Protect writes with SEH */
3131 _SEH2_TRY
3132 {
3133 /* Copy time information from ETHREAD/KTHREAD */
3136 ThreadTime->CreateTime = Thread->CreateTime;
3137
3138 /* Exit time is in a union and only valid on actual exit! */
3140 {
3141 ThreadTime->ExitTime = Thread->ExitTime;
3142 }
3143 else
3144 {
3145 ThreadTime->ExitTime.QuadPart = 0;
3146 }
3147 }
3149 {
3150 /* Get exception code */
3152 }
3153 _SEH2_END;
3154
3155 /* Dereference the thread */
3157 break;
3158 }
3159
3161 {
3162 /* Set the return length*/
3163 Length = sizeof(PVOID);
3164
3166 {
3168 break;
3169 }
3170
3171 /* Reference the thread */
3172 Status = ObReferenceObjectByHandle(ThreadHandle,
3173 Access,
3176 (PVOID*)&Thread,
3177 NULL);
3178 if (!NT_SUCCESS(Status))
3179 break;
3180
3181 /* Protect write with SEH */
3182 _SEH2_TRY
3183 {
3184 /* Return the Win32 Start Address */
3185 *(PVOID*)ThreadInformation = Thread->Win32StartAddress;
3186 }
3188 {
3189 /* Get exception code */
3191 }
3192 _SEH2_END;
3193
3194 /* Dereference the thread */
3196 break;
3197 }
3198
3200 {
3201 /* Set the return length*/
3202 Length = sizeof(LARGE_INTEGER);
3203
3205 {
3207 break;
3208 }
3209
3210 /* Reference the thread */
3211 Status = ObReferenceObjectByHandle(ThreadHandle,
3212 Access,
3215 (PVOID*)&Thread,
3216 NULL);
3217 if (!NT_SUCCESS(Status))
3218 break;
3219
3220 /* Protect write with SEH */
3221 _SEH2_TRY
3222 {
3223 /* FIXME */
3224 (*(PLARGE_INTEGER)ThreadInformation).QuadPart = 0;
3225 }
3227 {
3228 /* Get exception code */
3230 }
3231 _SEH2_END;
3232
3233 /* Dereference the thread */
3235 break;
3236 }
3237
3239 {
3240 /* Set the return length*/
3241 Length = sizeof(ULONG);
3242
3244 {
3246 break;
3247 }
3248
3249 /* Reference the thread */
3250 Status = ObReferenceObjectByHandle(ThreadHandle,
3251 Access,
3254 (PVOID*)&Thread,
3255 NULL);
3256 if (!NT_SUCCESS(Status))
3257 break;
3258
3259 /* Protect write with SEH */
3260 _SEH2_TRY
3261 {
3262 /* Return whether or not we are the last thread */
3263 *(PULONG)ThreadInformation = ((Thread->ThreadsProcess->
3264 ThreadListHead.Flink->Flink ==
3265 &Thread->ThreadsProcess->
3267 TRUE : FALSE);
3268 }
3270 {
3271 /* Get exception code */
3273 }
3274 _SEH2_END;
3275
3276 /* Dereference the thread */
3278 break;
3279 }
3280
3281 case ThreadIsIoPending:
3282 {
3283 KIRQL OldIrql;
3284
3285 /* Set the return length*/
3286 Length = sizeof(ULONG);
3287
3289 {
3291 break;
3292 }
3293
3294 /* Reference the thread */
3295 Status = ObReferenceObjectByHandle(ThreadHandle,
3296 Access,
3299 (PVOID*)&Thread,
3300 NULL);
3301 if (!NT_SUCCESS(Status))
3302 break;
3303
3304 /* Raise the IRQL to protect the IRP list */
3306
3307 /* Protect write with SEH */
3308 _SEH2_TRY
3309 {
3310 /* Check if the IRP list is empty or not */
3311 *(PULONG)ThreadInformation = !IsListEmpty(&Thread->IrpList);
3312 }
3314 {
3315 /* Get exception code */
3317 }
3318 _SEH2_END;
3319
3320 /* Lower IRQL back */
3322
3323 /* Dereference the thread */
3325 break;
3326 }
3327
3328 /* LDT and GDT information */
3330 {
3331#if defined(_X86_)
3332 /* Reference the thread */
3333 Status = ObReferenceObjectByHandle(ThreadHandle,
3334 Access,
3337 (PVOID*)&Thread,
3338 NULL);
3339 if (!NT_SUCCESS(Status))
3340 break;
3341
3342 /* Call the worker routine */
3344 ThreadInformation,
3346 ReturnLength);
3347
3348 /* Dereference the thread */
3350#else
3351 /* Only implemented on x86 */
3353#endif
3354 break;
3355 }
3356
3358 {
3359 /* Set the return length*/
3360 Length = sizeof(ULONG);
3361
3363 {
3365 break;
3366 }
3367
3368 /* Reference the thread */
3369 Status = ObReferenceObjectByHandle(ThreadHandle,
3370 Access,
3373 (PVOID*)&Thread,
3374 NULL);
3375 if (!NT_SUCCESS(Status))
3376 break;
3377
3378 _SEH2_TRY
3379 {
3380 *(PULONG)ThreadInformation = Thread->Tcb.DisableBoost ? 1 : 0;
3381 }
3383 {
3385 }
3386 _SEH2_END;
3387
3388 /* Dereference the thread */
3390 break;
3391 }
3392
3393#if (NTDDI_VERSION >= NTDDI_VISTA)
3395 {
3396 /* Set the return length */
3397 Length = sizeof(BOOLEAN);
3398
3400 {
3402 break;
3403 }
3404
3405 /* Reference the thread */
3406 Status = ObReferenceObjectByHandle(ThreadHandle,
3407 Access,
3410 (PVOID*)&Thread,
3411 NULL);
3412 if (!NT_SUCCESS(Status))
3413 break;
3414
3415 /* Protect write with SEH */
3416 _SEH2_TRY
3417 {
3418 *(PBOOLEAN)ThreadInformation = Thread->HideFromDebugger;
3419 }
3421 {
3422 /* Get exception code */
3424 }
3425 _SEH2_END;
3426
3427 /* Dereference the thread */
3429 break;
3430 }
3431#endif /* (NTDDI_VERSION >= NTDDI_VISTA) */
3432
3434 {
3435 /* Set the return length */
3436 Length = sizeof(ULONG);
3437
3439 {
3441 break;
3442 }
3443
3444 /* Reference the thread */
3445 Status = ObReferenceObjectByHandle(ThreadHandle,
3446 Access,
3449 (PVOID*)&Thread,
3450 NULL);
3451 if (!NT_SUCCESS(Status))
3452 break;
3453
3454 _SEH2_TRY
3455 {
3456 *(PULONG)ThreadInformation = Thread->BreakOnTermination;
3457 }
3459 {
3461 }
3462 _SEH2_END;
3463
3464 /* Dereference the thread */
3466 break;
3467 }
3468
3469 case ThreadIsTerminated:
3470 {
3471 ULONG ThreadTerminated;
3472
3473 /* Set the return length*/
3474 Length = sizeof(ThreadTerminated);
3475
3477 {
3479 break;
3480 }
3481
3482 /* Reference the thread */
3483 Status = ObReferenceObjectByHandle(ThreadHandle,
3484 Access,
3487 (PVOID*)&Thread,
3488 NULL);
3489 if (!NT_SUCCESS(Status))
3490 break;
3491
3492 ThreadTerminated = PsIsThreadTerminating(Thread);
3493
3494 _SEH2_TRY
3495 {
3496 *(PULONG)ThreadInformation = ThreadTerminated ? 1 : 0;
3497 }
3499 {
3501 }
3502 _SEH2_END;
3503
3504 /* Dereference the thread */
3506 break;
3507 }
3508
3509#if (NTDDI_VERSION >= NTDDI_WIN10_RS1) || defined(__REACTOS__)
3511 {
3512 PUNICODE_STRING ThreadName;
3513
3514 /* Reference the thread */
3515 Status = ObReferenceObjectByHandle(ThreadHandle,
3516 // FIXME: Use THREAD_QUERY_LIMITED_INFORMATION when implemented
3520 (PVOID*)&Thread,
3521 NULL);
3522 if (!NT_SUCCESS(Status))
3523 break;
3524
3526
3527 ThreadName = Thread->ThreadName;
3528
3529 /* Set the return length (REMARK: We only
3530 * consider Length instead of MaximumLength) */
3531 Length = sizeof(UNICODE_STRING);
3532 Length += (ThreadName ? ThreadName->Length : 0);
3534 {
3538 /* As on Windows, and *not* STATUS_INFO_LENGTH_MISMATCH */
3539 break;
3540 }
3541
3542 /* Protect writes with SEH */
3543 _SEH2_TRY
3544 {
3545 PTHREAD_NAME_INFORMATION NameInfo =
3546 (PTHREAD_NAME_INFORMATION)ThreadInformation;
3547 if (ThreadName && (ThreadName->Length > 0))
3548 {
3549 NameInfo->ThreadName.Length =
3550 NameInfo->ThreadName.MaximumLength = ThreadName->Length;
3551 NameInfo->ThreadName.Buffer = (PWCH)(&NameInfo->ThreadName + 1);
3553 ThreadName->Buffer,
3554 ThreadName->Length);
3555 }
3556 else
3557 {
3558 RtlInitEmptyUnicodeString(&NameInfo->ThreadName, NULL, 0);
3559 }
3560 }
3562 {
3563 /* Get exception code */
3565 }
3566 _SEH2_END;
3567
3569
3570 /* Dereference the thread */
3572 break;
3573 }
3574#endif /* (NTDDI_VERSION >= NTDDI_WIN10_RS1) || defined(__REACTOS__) */
3575
3576 /* Anything else */
3577 default:
3578 /* Not yet implemented */
3579#if DBG
3580 DPRINT1("Not implemented: %s\n", PspDumpThreadInfoClassName(ThreadInformationClass));
3581#endif
3583 }
3584
3585 /* Protect write with SEH */
3586 _SEH2_TRY
3587 {
3588 /* Check if caller wanted return length */
3590 }
3592 {
3593 /* Get exception code */
3595 }
3596 _SEH2_END;
3597
3598 return Status;
3599}
struct _THREAD_BASIC_INFORMATION THREAD_BASIC_INFORMATION
@ ThreadDescriptorTableEntry
Definition: compat.h:941
@ ThreadAmILastThread
Definition: compat.h:947
@ ThreadTimes
Definition: compat.h:936
@ ThreadQuerySetWin32StartAddress
Definition: compat.h:944
@ ThreadIsTerminated
Definition: compat.h:955
@ ThreadBreakOnTermination
Definition: compat.h:953
@ ThreadBasicInformation
Definition: compat.h:935
@ ThreadPriorityBoost
Definition: compat.h:949
@ ThreadPerformanceCount
Definition: compat.h:946
@ ThreadIsIoPending
Definition: compat.h:951
@ ThreadHideFromDebugger
Definition: compat.h:952
struct _THREAD_BASIC_INFORMATION * PTHREAD_BASIC_INFORMATION
#define IsListEmpty(ListHead)
Definition: env_spec_w32.h:954
UCHAR KIRQL
Definition: env_spec_w32.h:591
#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
_In_opt_ PFILE_OBJECT _In_opt_ PETHREAD Thread
Definition: fltkernel.h:2653
#define THREAD_QUERY_INFORMATION
Definition: pstypes.h:145
struct _THREAD_NAME_INFORMATION * PTHREAD_NAME_INFORMATION
static LIST_ENTRY ThreadListHead
Definition: sys_arch.c:6
_In_ THREADINFOCLASS _In_ ULONG ThreadInformationLength
Definition: psfuncs.h:844
_In_ THREADINFOCLASS ThreadInformationClass
Definition: psfuncs.h:841
WCHAR * PWCH
Definition: ntbasedef.h:422
LONG NTAPI KeQueryBasePriorityThread(IN PKTHREAD Thread)
Definition: thrdobj.c:52
BOOLEAN NTAPI KeReadStateThread(IN PKTHREAD Thread)
Definition: thrdobj.c:42
POBJECT_TYPE PsThreadType
Definition: thread.c:20
BOOLEAN NTAPI PsIsThreadTerminating(IN PETHREAD Thread)
Definition: thread.c:868
#define BOOLEAN
Definition: pedump.c:73
static const INFORMATION_CLASS_INFO PsThreadInfoClass[]
Definition: ps_i.h:362
FORCEINLINE VOID PspUnlockThreadSecurityShared(IN PETHREAD Thread)
Definition: ps_x.h:166
FORCEINLINE VOID PspLockThreadSecurityShared(IN PETHREAD Thread)
Definition: ps_x.h:155
NTSTATUS NTAPI PspQueryDescriptorThread(IN PETHREAD Thread, IN PVOID ThreadInformation, IN ULONG ThreadInformationLength, OUT PULONG ReturnLength OPTIONAL)
Definition: psldt.c:43
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
LARGE_INTEGER ExitTime
Definition: pstypes.h:1202
NTSTATUS ExitStatus
Definition: pstypes.h:1208
KTHREAD Tcb
Definition: pstypes.h:1198
PVOID Win32StartAddress
Definition: pstypes.h:1247
CLIENT_ID Cid
Definition: pstypes.h:1223
LIST_ENTRY IrpList
Definition: pstypes.h:1239
PUNICODE_STRING ThreadName
Definition: pstypes.h:1352
LARGE_INTEGER CreateTime
Definition: pstypes.h:1199
ULONG BreakOnTermination
Definition: pstypes.h:1279
ULONG HideFromDebugger
Definition: pstypes.h:1275
GROUP_AFFINITY Affinity
Definition: ketypes.h:2085
ULONG DisableBoost
Definition: ketypes.h:1872
SCHAR Priority
Definition: ketypes.h:1929
PVOID Teb
Definition: ketypes.h:1954
ULONG KernelTime
Definition: ketypes.h:2134
ULONG UserTime
Definition: ketypes.h:2150
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
KPRIORITY BasePriority
Definition: compat.h:932
KAFFINITY AffinityMask
Definition: compat.h:930
UNICODE_STRING ThreadName
Definition: pstypes.h:1096
USHORT MaximumLength
Definition: env_spec_w32.h:370
unsigned char * PBOOLEAN
Definition: typedefs.h:53
union _LARGE_INTEGER LARGE_INTEGER
union _LARGE_INTEGER * PLARGE_INTEGER
Definition: file.c:57
@ ThreadNameInformation
Definition: winternl.h:2319
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:778

Referenced by CreateRemoteThread(), CsrCreateProcess(), CsrCreateRemoteThread(), CsrCreateThread(), CsrInsertThread(), CsrSbCreateSession(), DbgUiConvertStateChangeStructure(), DoThreadNameTest(), ExitThread(), fetch_thread_info(), GetExitCodeThread(), GetProcessIdOfThread(), GetThreadDescription(), GetThreadGroupAffinity(), GetThreadId(), GetThreadIdealProcessorEx(), GetThreadIOPendingFlag(), GetThreadPriority(), GetThreadPriorityBoost(), GetThreadSelectorEntry(), GetThreadTimes(), i386_stack_walk(), init_funcs(), InitFunctionPtrs(), ntGetThreadName(), PrintThreads(), QuerySetThreadValidator(), RtlCheckForOrphanedCriticalSections(), RtlFreeUserThreadStack(), RtlpIsIoPending(), SetThreadAffinityMask(), TerminateThread(), test_dbg_hidden_thread_creation(), test_HideFromDebugger(), test_peb_teb(), test_process_machine(), Test_ThreadBasicInformationClass(), test_ThreadEnableAlignmentFaultFixup(), Test_ThreadHideFromDebuggerClass(), and test_tls_links().

◆ NtSetInformationProcess()

NTSTATUS NTAPI NtSetInformationProcess ( _In_ HANDLE  ProcessHandle,
_In_ PROCESSINFOCLASS  ProcessInformationClass,
_In_reads_bytes_(ProcessInformationLength) PVOID  ProcessInformation,
_In_ ULONG  ProcessInformationLength 
)

Definition at line 1422 of file query.c.

1427{
1430 ACCESS_MASK Access;
1432 HANDLE PortHandle = NULL;
1436 PROCESS_PRIORITY_CLASS PriorityClass = {0};
1437 PROCESS_FOREGROUND_BACKGROUND Foreground = {0};
1438 PVOID ExceptionPort;
1439 ULONG Break;
1440 KAFFINITY ValidAffinity, Affinity = 0;
1441 KPRIORITY BasePriority = 0;
1442 UCHAR MemoryPriority = 0;
1443 BOOLEAN DisableBoost = 0;
1444 ULONG DefaultHardErrorMode = 0;
1445 ULONG DebugFlags = 0, EnableFixup = 0, Boost = 0;
1446 ULONG NoExecute = 0, VdmPower = 0;
1450 PAGED_CODE();
1451
1452 /* Validate the information class */
1453 Status = DefaultSetInfoBufferCheck(ProcessInformationClass,
1456 ProcessInformation,
1457 ProcessInformationLength,
1458 PreviousMode);
1459 if (!NT_SUCCESS(Status))
1460 {
1461#if DBG
1462 DPRINT1("NtSetInformationProcess(ProcessInformationClass: %s): Class validation failed! (Status: 0x%lx)\n",
1463 PspDumpProcessInfoClassName(ProcessInformationClass), Status);
1464#endif
1465 return Status;
1466 }
1467
1468 /* Check what class this is */
1469 Access = PROCESS_SET_INFORMATION;
1470 if (ProcessInformationClass == ProcessSessionInformation)
1471 {
1472 /* Setting the Session ID needs a special mask */
1473 Access |= PROCESS_SET_SESSIONID;
1474 }
1475 else if (ProcessInformationClass == ProcessExceptionPort)
1476 {
1477 /* Setting the exception port needs a special mask */
1478 Access |= PROCESS_SUSPEND_RESUME;
1479 }
1480
1481 /* Reference the process */
1483 Access,
1486 (PVOID*)&Process,
1487 NULL);
1488 if (!NT_SUCCESS(Status)) return Status;
1489
1490 /* Check what kind of information class this is */
1491 switch (ProcessInformationClass)
1492 {
1494
1495 /* Check buffer length */
1496 if (ProcessInformationLength != sizeof(ULONG))
1497 {
1499 break;
1500 }
1501
1502 /* Use SEH for capture */
1503 _SEH2_TRY
1504 {
1505 /* Capture the boolean */
1506 VdmPower = *(PULONG)ProcessInformation;
1507 }
1509 {
1510 /* Get the exception code */
1512 _SEH2_YIELD(break);
1513 }
1514 _SEH2_END;
1515
1516 /* Getting VDM powers requires the SeTcbPrivilege */
1518 {
1519 /* We don't hold the privilege, bail out */
1521 DPRINT1("Need TCB privilege\n");
1522 break;
1523 }
1524
1525 /* Set or clear the flag */
1526 if (VdmPower)
1527 {
1529 }
1530 else
1531 {
1533 }
1534 break;
1535
1536 /* Error/Exception Port */
1538
1539 /* Check buffer length */
1540 if (ProcessInformationLength != sizeof(HANDLE))
1541 {
1543 break;
1544 }
1545
1546 /* Use SEH for capture */
1547 _SEH2_TRY
1548 {
1549 /* Capture the handle */
1550 PortHandle = *(PHANDLE)ProcessInformation;
1551 }
1553 {
1554 /* Get the exception code */
1556 _SEH2_YIELD(break);
1557 }
1558 _SEH2_END;
1559
1560 /* Setting the error port requires the SeTcbPrivilege */
1562 {
1563 /* We don't hold the privilege, bail out */
1565 break;
1566 }
1567
1568 /* Get the LPC Port */
1569 Status = ObReferenceObjectByHandle(PortHandle,
1570 0,
1573 (PVOID)&ExceptionPort,
1574 NULL);
1575 if (!NT_SUCCESS(Status)) break;
1576
1577 /* Change the pointer */
1578 if (InterlockedCompareExchangePointer(&Process->ExceptionPort,
1579 ExceptionPort,
1580 NULL))
1581 {
1582 /* We already had one, fail */
1583 ObDereferenceObject(ExceptionPort);
1585 }
1586 break;
1587
1588 /* Security Token */
1589 case ProcessAccessToken:
1590
1591 /* Check buffer length */
1592 if (ProcessInformationLength != sizeof(PROCESS_ACCESS_TOKEN))
1593 {
1595 break;
1596 }
1597
1598 /* Use SEH for capture */
1599 _SEH2_TRY
1600 {
1601 /* Save the token handle */
1602 TokenHandle = ((PPROCESS_ACCESS_TOKEN)ProcessInformation)->
1603 Token;
1604 }
1606 {
1607 /* Get the exception code */
1609 _SEH2_YIELD(break);
1610 }
1611 _SEH2_END;
1612
1613 /* Assign the actual token */
1615 break;
1616
1617 /* Hard error processing */
1619
1620 /* Check buffer length */
1621 if (ProcessInformationLength != sizeof(ULONG))
1622 {
1624 break;
1625 }
1626
1627 /* Enter SEH for direct buffer read */
1628 _SEH2_TRY
1629 {
1630 DefaultHardErrorMode = *(PULONG)ProcessInformation;
1631 }
1633 {
1634 /* Get exception code */
1636 _SEH2_YIELD(break);
1637 }
1638 _SEH2_END;
1639
1640 /* Set the mode */
1641 Process->DefaultHardErrorProcessing = DefaultHardErrorMode;
1642
1643 /* Call Ke for the update */
1644 if (DefaultHardErrorMode & SEM_NOALIGNMENTFAULTEXCEPT)
1645 {
1647 }
1648 else
1649 {
1651 }
1653 break;
1654
1655 /* Session ID */
1657
1658 /* Check buffer length */
1659 if (ProcessInformationLength != sizeof(PROCESS_SESSION_INFORMATION))
1660 {
1662 break;
1663 }
1664
1665 /* Enter SEH for capture */
1666 _SEH2_TRY
1667 {
1668 /* Capture the caller's buffer */
1669 SessionInfo = *(PPROCESS_SESSION_INFORMATION)ProcessInformation;
1670 }
1672 {
1673 /* Get the exception code */
1675 _SEH2_YIELD(break);
1676 }
1677 _SEH2_END;
1678
1679 /* Setting the session id requires the SeTcbPrivilege */
1681 {
1682 /* We don't hold the privilege, bail out */
1684 break;
1685 }
1686
1687 /*
1688 * Since we cannot change the session ID of the given
1689 * process anymore because it is set once and for all
1690 * at process creation time and because it is stored
1691 * inside the Process->Session structure managed by MM,
1692 * we fake changing it: we just return success if the
1693 * user-defined value is the same as the session ID of
1694 * the process, and otherwise we fail.
1695 */
1696 if (SessionInfo.SessionId == PsGetProcessSessionId(Process))
1697 {
1699 }
1700 else
1701 {
1703 }
1704
1705 break;
1706
1708
1709 /* Check buffer length */
1710 if (ProcessInformationLength != sizeof(PROCESS_PRIORITY_CLASS))
1711 {
1713 break;
1714 }
1715
1716 /* Enter SEH for capture */
1717 _SEH2_TRY
1718 {
1719 /* Capture the caller's buffer */
1720 PriorityClass = *(PPROCESS_PRIORITY_CLASS)ProcessInformation;
1721 }
1723 {
1724 /* Return the exception code */
1726 _SEH2_YIELD(break);
1727 }
1728 _SEH2_END;
1729
1730 /* Check for invalid PriorityClass value */
1732 {
1734 break;
1735 }
1736
1737 if ((PriorityClass.PriorityClass != Process->PriorityClass) &&
1739 {
1740 /* Check the privilege */
1744 PreviousMode);
1745 if (!HasPrivilege)
1746 {
1748 DPRINT1("Privilege to change priority to realtime lacking\n");
1750 }
1751 }
1752
1753 /* Check if we have a job */
1754 if (Process->Job)
1755 {
1756 DPRINT1("Jobs not yet supported\n");
1757 }
1758
1759 /* Set process priority class */
1760 Process->PriorityClass = PriorityClass.PriorityClass;
1761
1762 /* Set process priority mode (foreground or background) */
1764 PriorityClass.Foreground ?
1768 break;
1769
1771
1772 /* Check buffer length */
1773 if (ProcessInformationLength != sizeof(PROCESS_FOREGROUND_BACKGROUND))
1774 {
1776 break;
1777 }
1778
1779 /* Enter SEH for capture */
1780 _SEH2_TRY
1781 {
1782 /* Capture the caller's buffer */
1783 Foreground = *(PPROCESS_FOREGROUND_BACKGROUND)ProcessInformation;
1784 }
1786 {
1787 /* Return the exception code */
1789 _SEH2_YIELD(break);
1790 }
1791 _SEH2_END;
1792
1793 /* Set process priority mode (foreground or background) */
1795 Foreground.Foreground ?
1799 break;
1800
1802
1803 /* Validate input length */
1804 if (ProcessInformationLength != sizeof(KPRIORITY))
1805 {
1807 break;
1808 }
1809
1810 /* Enter SEH for direct buffer read */
1811 _SEH2_TRY
1812 {
1813 BasePriority = *(KPRIORITY*)ProcessInformation;
1814 }
1816 {
1817 /* Get exception code */
1818 Break = 0;
1820 _SEH2_YIELD(break);
1821 }
1822 _SEH2_END;
1823
1824 /* Extract the memory priority out of there */
1825 if (BasePriority & 0x80000000)
1826 {
1827 MemoryPriority = MEMORY_PRIORITY_FOREGROUND;
1828 BasePriority &= ~0x80000000;
1829 }
1830 else
1831 {
1832 MemoryPriority = MEMORY_PRIORITY_BACKGROUND;
1833 }
1834
1835 /* Validate the number */
1836 if ((BasePriority > HIGH_PRIORITY) || (BasePriority <= LOW_PRIORITY))
1837 {
1840 }
1841
1842 /* Check if the new base is higher */
1843 if (BasePriority > Process->Pcb.BasePriority)
1844 {
1848 PreviousMode);
1849 if (!HasPrivilege)
1850 {
1852 DPRINT1("Privilege to change priority from %lx to %lx lacking\n", Process->Pcb.BasePriority, BasePriority);
1854 }
1855 }
1856
1857 /* Call Ke */
1858 KeSetPriorityAndQuantumProcess(&Process->Pcb, BasePriority, 0);
1859
1860 /* Now set the memory priority */
1861 MmSetMemoryPriorityProcess(Process, MemoryPriority);
1863 break;
1864
1866
1867 /* Validate input length */
1868 if (ProcessInformationLength != sizeof(ULONG))
1869 {
1871 break;
1872 }
1873
1874 /* Enter SEH for direct buffer read */
1875 _SEH2_TRY
1876 {
1877 Boost = *(PULONG)ProcessInformation;
1878 }
1880 {
1881 /* Get exception code */
1882 Break = 0;
1884 _SEH2_YIELD(break);
1885 }
1886 _SEH2_END;
1887
1888 /* Make sure the process isn't dying */
1889 if (ExAcquireRundownProtection(&Process->RundownProtect))
1890 {
1891 /* Lock it */
1893 ExAcquirePushLockShared(&Process->ProcessLock);
1894
1895 /* Loop the threads */
1896 for (Next = Process->ThreadListHead.Flink;
1897 Next != &Process->ThreadListHead;
1898 Next = Next->Flink)
1899 {
1900 /* Call Ke for the thread */
1901 Thread = CONTAINING_RECORD(Next, ETHREAD, ThreadListEntry);
1903 }
1904
1905 /* Release the lock and rundown */
1906 ExReleasePushLockShared(&Process->ProcessLock);
1908 ExReleaseRundownProtection(&Process->RundownProtect);
1909
1910 /* Set success code */
1912 }
1913 else
1914 {
1915 /* Avoid race conditions */
1917 }
1918 break;
1919
1921
1922 /* Check buffer length */
1923 if (ProcessInformationLength != sizeof(ULONG))
1924 {
1926 break;
1927 }
1928
1929 /* Enter SEH for direct buffer read */
1930 _SEH2_TRY
1931 {
1932 Break = *(PULONG)ProcessInformation;
1933 }
1935 {
1936 /* Get exception code */
1937 Break = 0;
1939 _SEH2_YIELD(break);
1940 }
1941 _SEH2_END;
1942
1943 /* Setting 'break on termination' requires the SeDebugPrivilege */
1945 {
1946 /* We don't hold the privilege, bail out */
1948 break;
1949 }
1950
1951 /* Set or clear the flag */
1952 if (Break)
1953 {
1955 }
1956 else
1957 {
1959 }
1960
1961 break;
1962
1964
1965 /* Check buffer length */
1966 if (ProcessInformationLength != sizeof(KAFFINITY))
1967 {
1969 break;
1970 }
1971
1972 /* Enter SEH for direct buffer read */
1973 _SEH2_TRY
1974 {
1975 Affinity = *(PKAFFINITY)ProcessInformation;
1976 }
1978 {
1979 /* Get exception code */
1980 Break = 0;
1982 _SEH2_YIELD(break);
1983 }
1984 _SEH2_END;
1985
1986 /* Make sure it's valid for the CPUs present */
1987 ValidAffinity = Affinity & KeActiveProcessors;
1988 if (!Affinity || (ValidAffinity != Affinity))
1989 {
1991 break;
1992 }
1993
1994 /* Check if it's within job affinity limits */
1995 if (Process->Job)
1996 {
1997 /* Not yet implemented */
2000 break;
2001 }
2002
2003 /* Make sure the process isn't dying */
2004 if (ExAcquireRundownProtection(&Process->RundownProtect))
2005 {
2006 /* Lock it */
2008 ExAcquirePushLockShared(&Process->ProcessLock);
2009
2010 /* Call Ke to do the work */
2011 KeSetAffinityProcess(&Process->Pcb, ValidAffinity);
2012
2013 /* Release the lock and rundown */
2014 ExReleasePushLockShared(&Process->ProcessLock);
2016 ExReleaseRundownProtection(&Process->RundownProtect);
2017
2018 /* Set success code */
2020 }
2021 else
2022 {
2023 /* Avoid race conditions */
2025 }
2026 break;
2027
2028 /* Priority Boosting status */
2030
2031 /* Validate input length */
2032 if (ProcessInformationLength != sizeof(ULONG))
2033 {
2035 break;
2036 }
2037
2038 /* Enter SEH for direct buffer read */
2039 _SEH2_TRY
2040 {
2041 DisableBoost = *(PBOOLEAN)ProcessInformation;
2042 }
2044 {
2045 /* Get exception code */
2046 Break = 0;
2048 _SEH2_YIELD(break);
2049 }
2050 _SEH2_END;
2051
2052 /* Make sure the process isn't dying */
2053 if (ExAcquireRundownProtection(&Process->RundownProtect))
2054 {
2055 /* Lock it */
2057 ExAcquirePushLockShared(&Process->ProcessLock);
2058
2059 /* Call Ke to do the work */
2060 KeSetDisableBoostProcess(&Process->Pcb, DisableBoost);
2061
2062 /* Loop the threads too */
2063 for (Next = Process->ThreadListHead.Flink;
2064 Next != &Process->ThreadListHead;
2065 Next = Next->Flink)
2066 {
2067 /* Call Ke for the thread */
2068 Thread = CONTAINING_RECORD(Next, ETHREAD, ThreadListEntry);
2069 KeSetDisableBoostThread(&Thread->Tcb, DisableBoost);
2070 }
2071
2072 /* Release the lock and rundown */
2073 ExReleasePushLockShared(&Process->ProcessLock);
2075 ExReleaseRundownProtection(&Process->RundownProtect);
2076
2077 /* Set success code */
2079 }
2080 else
2081 {
2082 /* Avoid race conditions */
2084 }
2085 break;
2086
2087 case ProcessDebugFlags:
2088
2089 /* Check buffer length */
2090 if (ProcessInformationLength != sizeof(ULONG))
2091 {
2093 break;
2094 }
2095
2096 /* Enter SEH for direct buffer read */
2097 _SEH2_TRY
2098 {
2099 DebugFlags = *(PULONG)ProcessInformation;
2100 }
2102 {
2103 /* Get exception code */
2105 _SEH2_YIELD(break);
2106 }
2107 _SEH2_END;
2108
2109 /* Set the mode */
2110 if (DebugFlags & ~1)
2111 {
2113 }
2114 else
2115 {
2116 if (DebugFlags & 1)
2117 {
2119 }
2120 else
2121 {
2123 }
2124 }
2125
2126 /* Done */
2128 break;
2129
2131
2132 /* Check buffer length */
2133 if (ProcessInformationLength != sizeof(BOOLEAN))
2134 {
2136 break;
2137 }
2138
2139 /* Enter SEH for direct buffer read */
2140 _SEH2_TRY
2141 {
2142 EnableFixup = *(PULONG)ProcessInformation;
2143 }
2145 {
2146 /* Get exception code */
2148 _SEH2_YIELD(break);
2149 }
2150 _SEH2_END;
2151
2152 /* Set the mode */
2153 if (EnableFixup)
2154 {
2155 Process->DefaultHardErrorProcessing |= SEM_NOALIGNMENTFAULTEXCEPT;
2156 }
2157 else
2158 {
2159 Process->DefaultHardErrorProcessing &= ~SEM_NOALIGNMENTFAULTEXCEPT;
2160 }
2161
2162 /* Call Ke for the update */
2165 break;
2166
2168
2169 /* Only TCB can do this */
2171 {
2172 /* We don't hold the privilege, bail out */
2173 DPRINT1("Need TCB to set IOPL\n");
2175 break;
2176 }
2177
2178 /* Only supported on x86 */
2179#if defined (_X86_)
2180 Ke386SetIOPL();
2181#elif defined(_M_AMD64)
2182 /* On x64 this function isn't implemented.
2183 On Windows 2003 it returns success.
2184 On Vista+ it returns STATUS_NOT_IMPLEMENTED. */
2185 if ((ExGetPreviousMode() != KernelMode) &&
2186 (RtlRosGetAppcompatVersion() > _WIN32_WINNT_WS03))
2187 {
2189 }
2190#else
2192#endif
2193 /* Done */
2194 break;
2195
2197
2198 /* Check buffer length */
2199 if (ProcessInformationLength != sizeof(ULONG))
2200 {
2202 break;
2203 }
2204
2206 {
2208 break;
2209 }
2210
2211 /* Enter SEH for direct buffer read */
2212 _SEH2_TRY
2213 {
2214 NoExecute = *(PULONG)ProcessInformation;
2215 }
2217 {
2218 /* Get exception code */
2220 _SEH2_YIELD(break);
2221 }
2222 _SEH2_END;
2223
2224 /* Call Mm for the update */
2225 Status = MmSetExecuteOptions(NoExecute);
2226 break;
2227
2228 case ProcessDeviceMap:
2229
2230 /* Check buffer length */
2231 if (ProcessInformationLength != sizeof(HANDLE))
2232 {
2234 break;
2235 }
2236
2237 /* Use SEH for capture */
2238 _SEH2_TRY
2239 {
2240 /* Capture the handle */
2241 DirectoryHandle = *(PHANDLE)ProcessInformation;
2242 }
2244 {
2245 /* Get the exception code */
2247 _SEH2_YIELD(break);
2248 }
2249 _SEH2_END;
2250
2251 /* Call Ob to set the device map */
2253 break;
2254
2255
2256 /* We currently don't implement any of these */
2258 case ProcessLdtSize:
2260 DPRINT1("VDM/16-bit Request not implemented: %lu\n", ProcessInformationClass);
2262 break;
2263
2264 case ProcessQuotaLimits:
2265
2267 1,
2268 ProcessInformation,
2269 ProcessInformationLength,
2270 PreviousMode);
2271 break;
2272
2274 DPRINT1("WS watch not implemented\n");
2276 break;
2277
2279 DPRINT1("Handle tracing not implemented\n");
2281 break;
2282
2283 /* Anything else is invalid */
2284 default:
2285#if DBG
2286 DPRINT1("Invalid Server 2003 Info Class: %s\n", PspDumpProcessInfoClassName(ProcessInformationClass));
2287#endif
2289 }
2290
2291 /* Dereference and return status */
2293 return Status;
2294}
#define STATUS_PRIVILEGE_NOT_HELD
Definition: DriverTester.h:9
static HANDLE DirectoryHandle
Definition: ObType.cpp:48
KAFFINITY * PKAFFINITY
Definition: basetsd.h:189
#define UNIMPLEMENTED
Definition: ntoskrnl.c:15
ULONG_PTR KAFFINITY
Definition: compat.h:85
LONG KPRIORITY
Definition: compat.h:803
FORCEINLINE VOID ExAcquirePushLockShared(PEX_PUSH_LOCK PushLock)
Definition: ex.h:1108
FORCEINLINE VOID ExReleasePushLockShared(PEX_PUSH_LOCK PushLock)
Definition: ex.h:1216
#define PROCESS_SUSPEND_RESUME
Definition: pstypes.h:163
#define PROCESS_PRIORITY_CLASS_ABOVE_NORMAL
Definition: pstypes.h:108
#define PSF_NO_DEBUG_INHERIT_BIT
Definition: pstypes.h:270
#define PROCESS_SET_SESSIONID
Definition: pstypes.h:155
@ PsProcessPriorityForeground
Definition: pstypes.h:455
@ PsProcessPriorityBackground
Definition: pstypes.h:456
#define PROCESS_SET_INFORMATION
Definition: pstypes.h:161
#define PSF_VDM_ALLOWED_BIT
Definition: pstypes.h:292
#define PROCESS_PRIORITY_CLASS_REALTIME
Definition: pstypes.h:106
struct _PROCESS_FOREGROUND_BACKGROUND * PPROCESS_FOREGROUND_BACKGROUND
#define MEMORY_PRIORITY_BACKGROUND
Definition: pstypes.h:120
#define PSF_BREAK_ON_TERMINATION_BIT
Definition: pstypes.h:281
#define MEMORY_PRIORITY_FOREGROUND
Definition: pstypes.h:122
#define LOW_PRIORITY
#define HIGH_PRIORITY
#define InterlockedCompareExchangePointer
Definition: interlocked.h:144
#define KeLeaveCriticalRegion()
Definition: ke_x.h:119
#define KeEnterCriticalRegion()
Definition: ke_x.h:88
POBJECT_TYPE LpcPortObjectType
Definition: port.c:17
#define KernelMode
Definition: asm.h:38
_In_ ACCESS_MASK _In_ ULONG _Out_ PHANDLE TokenHandle
Definition: psfuncs.h:727
#define SEM_NOALIGNMENTFAULTEXCEPT
Definition: rtltypes.h:71
ULONG ACCESS_MASK
Definition: nt_native.h:40
struct _PROCESS_ACCESS_TOKEN * PPROCESS_ACCESS_TOKEN
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
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 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
NTSTATUS NTAPI MmSetExecuteOptions(IN ULONG ExecuteOptions)
Definition: pagfault.c:2711
NTSTATUS NTAPI MmSetMemoryPriorityProcess(IN PEPROCESS Process, IN UCHAR MemoryPriority)
Definition: procsup.c:543
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
VOID NTAPI PsSetProcessPriorityByClass(IN PEPROCESS Process, IN PSPROCESSPRIORITYMODE Type)
Definition: process.c:1325
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
#define STATUS_PROCESS_IS_TERMINATING
Definition: ntstatus.h:596
#define STATUS_PORT_ALREADY_SET
Definition: ntstatus.h:402
NTSTATUS NTAPI ObSetDeviceMap(IN PEPROCESS Process, IN HANDLE DirectoryHandle)
Definition: devicemap.c:24
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
#define PspClearProcessFlag(Process, Flag)
Definition: ps_x.h:35
#define PspSetProcessFlag(Process, Flag)
Definition: ps_x.h:33
#define _WIN32_WINNT_WS03
Definition: sdkddkver.h:23
STDMETHOD() Next(THIS_ ULONG celt, IAssociationElement *pElement, ULONG *pceltFetched) PURE
Definition: typedefs.h:120
unsigned char UCHAR
Definition: typedefs.h:53
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
BOOLEAN HasPrivilege(IN PPRIVILEGE_SET Privilege)
Definition: shutdown.c:92
@ ProcessAffinityMask
Definition: winternl.h:1903
@ ProcessIoPortHandlers
Definition: winternl.h:1895
@ ProcessRaisePriority
Definition: winternl.h:1888
@ ProcessLdtSize
Definition: winternl.h:1893
@ ProcessEnableAlignmentFaultFixup
Definition: winternl.h:1899
@ ProcessBasePriority
Definition: winternl.h:1887
@ ProcessAccessToken
Definition: winternl.h:1891
@ ProcessForegroundInformation
Definition: winternl.h:1907
@ ProcessExceptionPort
Definition: winternl.h:1890
@ ProcessUserModeIOPL
Definition: winternl.h:1898
_In_ ULONG _In_ ULONG _In_ ULONG _Out_ PKIRQL _Out_ PKAFFINITY Affinity
Definition: halfuncs.h:174

Referenced by _main(), CreateProcessInternalW(), CSR_API(), CsrCreateProcess(), CsrpSetDefaultProcessHardErrorMode(), CsrSbCreateSession(), CsrSetBackgroundPriority(), CsrSetForegroundPriority(), CsrSetToNormalPriority(), CsrSetToShutdownPriority(), EmptyWorkingSet(), InitFunctionPtrs(), InitializeProcessForWsWatch(), InsertTokenToProcessCommon(), LdrpInitializeProcess(), QuerySetProcessValidator(), SetErrorMode(), SetPriorityClass(), SetProcessAffinityMask(), SetProcessInformation(), SetProcessPriorityBoost(), SetProcessWorkingSetSizeEx(), SmpInit(), SmpSbCreateSession(), SmpSetProcessMuSessionId(), test_exec_memory_writes(), Test_ProcBasePriorityClass(), test_process_instrumentation_callback(), Test_ProcessWx86InformationClass(), Test_ProcForegroundBackgroundClass(), and Test_ProcRaisePriorityClass().

◆ NtSetInformationThread()

NTSTATUS NTAPI NtSetInformationThread ( _In_ HANDLE  ThreadHandle,
_In_ THREADINFOCLASS  ThreadInformationClass,
_In_reads_bytes_(ThreadInformationLength) PVOID  ThreadInformation,
_In_ ULONG  ThreadInformationLength 
)

Definition at line 2301 of file query.c.

2306{
2310 KPRIORITY Priority = 0;
2312 PTEB Teb;
2313
2314 PAGED_CODE();
2315
2316 /* Validate the information class */
2320 ThreadInformation,
2322 PreviousMode);
2323 if (!NT_SUCCESS(Status))
2324 {
2325#if DBG
2326 DPRINT1("NtSetInformationThread(ThreadInformationClass: %s): Class validation failed! (Status: 0x%lx)\n",
2327 PspDumpThreadInfoClassName(ThreadInformationClass), Status);
2328#endif
2329 return Status;
2330 }
2331
2332 /* Check what kind of information class this is */
2333 switch (ThreadInformationClass)
2334 {
2335 /* Thread priority */
2336 case ThreadPriority:
2337 {
2338 /* Check buffer length */
2339 if (ThreadInformationLength != sizeof(KPRIORITY))
2340 {
2342 break;
2343 }
2344
2345 /* Use SEH for capture */
2346 _SEH2_TRY
2347 {
2348 /* Get the priority */
2349 Priority = *(PLONG)ThreadInformation;
2350 }
2352 {
2353 /* Get the exception code */
2355 _SEH2_YIELD(break);
2356 }
2357 _SEH2_END;
2358
2359 /* Validate it */
2360 if ((Priority > HIGH_PRIORITY) ||
2362 {
2363 /* Fail */
2365 break;
2366 }
2367
2368 /* Check for the required privilege */
2370 {
2373 ThreadHandle,
2375 PreviousMode);
2376 if (!HasPrivilege)
2377 {
2378 DPRINT1("Privilege to change priority to %lx lacking\n", Priority);
2380 }
2381 }
2382
2383 /* Reference the thread */
2384 Status = ObReferenceObjectByHandle(ThreadHandle,
2388 (PVOID*)&Thread,
2389 NULL);
2390 if (!NT_SUCCESS(Status))
2391 break;
2392
2393 /* Set the priority */
2395
2396 /* Dereference the thread */
2398 break;
2399 }
2400
2401 case ThreadBasePriority:
2402 {
2403 /* Check buffer length */
2404 if (ThreadInformationLength != sizeof(LONG))
2405 {
2407 break;
2408 }
2409
2410 /* Use SEH for capture */
2411 _SEH2_TRY
2412 {
2413 /* Get the priority */
2414 Priority = *(PLONG)ThreadInformation;
2415 }
2417 {
2418 /* Get the exception code */
2420 _SEH2_YIELD(break);
2421 }
2422 _SEH2_END;
2423
2424 /* Validate it */
2427 {
2428 /* These ones are OK */
2429 if ((Priority != THREAD_BASE_PRIORITY_LOWRT + 1) &&
2431 {
2432 /* Check if the process is real time */
2433 if (PsGetCurrentProcess()->PriorityClass !=
2435 {
2436 /* It isn't, fail */
2438 break;
2439 }
2440 }
2441 }
2442
2443 /* Reference the thread */
2444 Status = ObReferenceObjectByHandle(ThreadHandle,
2448 (PVOID*)&Thread,
2449 NULL);
2450 if (!NT_SUCCESS(Status))
2451 break;
2452
2453 /* Set the base priority */
2455
2456 /* Dereference the thread */
2458 break;
2459 }
2460
2461 case ThreadAffinityMask:
2462 {
2463 KAFFINITY Affinity = 0, CombinedAffinity;
2464
2465 /* Check buffer length */
2466 if (ThreadInformationLength != sizeof(ULONG_PTR))
2467 {
2469 break;
2470 }
2471
2472 /* Use SEH for capture */
2473 _SEH2_TRY
2474 {
2475 /* Get the priority */
2476 Affinity = *(PULONG_PTR)ThreadInformation;
2477 }
2479 {
2480 /* Get the exception code */
2482 _SEH2_YIELD(break);
2483 }
2484 _SEH2_END;
2485
2486 /* Validate it */
2487 if (!Affinity)
2488 {
2489 /* Fail */
2491 break;
2492 }
2493
2494 /* Reference the thread */
2495 Status = ObReferenceObjectByHandle(ThreadHandle,
2499 (PVOID*)&Thread,
2500 NULL);
2501 if (!NT_SUCCESS(Status))
2502 break;
2503
2504 /* Get the process */
2505 Process = Thread->ThreadsProcess;
2506
2507 /* Try to acquire rundown */
2508 if (ExAcquireRundownProtection(&Process->RundownProtect))
2509 {
2510 /* Lock it */
2512 ExAcquirePushLockShared(&Process->ProcessLock);
2513
2514 /* Combine masks */
2515 CombinedAffinity = Affinity & Process->Pcb.Affinity;
2516 if (CombinedAffinity != Affinity)
2517 {
2518 /* Fail */
2520 }
2521 else
2522 {
2523 /* Set the affinity */
2524 KeSetAffinityThread(&Thread->Tcb, CombinedAffinity);
2525 }
2526
2527 /* Release the lock and rundown */
2528 ExReleasePushLockShared(&Process->ProcessLock);
2530 ExReleaseRundownProtection(&Process->RundownProtect);
2531 }
2532 else
2533 {
2534 /* Too late */
2536 }
2537
2538 /* Dereference the thread */
2540 break;
2541 }
2542
2544 {
2546
2547 /* Check buffer length */
2548 if (ThreadInformationLength != sizeof(HANDLE))
2549 {
2551 break;
2552 }
2553
2554 /* Use SEH for capture */
2555 _SEH2_TRY
2556 {
2557 /* Save the token handle */
2558 TokenHandle = *(PHANDLE)ThreadInformation;
2559 }
2561 {
2562 /* Get the exception code */
2564 _SEH2_YIELD(break);
2565 }
2566 _SEH2_END;
2567
2568 /* Reference the thread */
2569 Status = ObReferenceObjectByHandle(ThreadHandle,
2573 (PVOID*)&Thread,
2574 NULL);
2575 if (!NT_SUCCESS(Status))
2576 break;
2577
2578 /* Assign the actual token */
2580
2581 /* Dereference the thread */
2583 break;
2584 }
2585
2587 {
2588 PVOID Address;
2589
2590 /* Check buffer length */
2591 if (ThreadInformationLength != sizeof(ULONG_PTR))
2592 {
2594 break;
2595 }
2596
2597 /* Use SEH for capture */
2598 _SEH2_TRY
2599 {
2600 /* Get the priority */
2601 Address = *(PVOID*)ThreadInformation;
2602 }
2604 {
2605 /* Get the exception code */
2607 _SEH2_YIELD(break);
2608 }
2609 _SEH2_END;
2610
2611 /* Reference the thread */
2612 Status = ObReferenceObjectByHandle(ThreadHandle,
2616 (PVOID*)&Thread,
2617 NULL);
2618 if (!NT_SUCCESS(Status))
2619 break;
2620
2621 /* Set the address */
2623
2624 /* Dereference the thread */
2626 break;
2627 }
2628
2630 {
2631 ULONG_PTR IdealProcessor;
2632
2633 /* Check buffer length */
2634 if (ThreadInformationLength != sizeof(ULONG_PTR))
2635 {
2637 break;
2638 }
2639
2640 /* Use SEH for capture */
2641 _SEH2_TRY
2642 {
2643 /* Get the priority */
2644 IdealProcessor = *(PULONG_PTR)ThreadInformation;
2645 }
2647 {
2648 /* Get the exception code */
2650 _SEH2_YIELD(break);
2651 }
2652 _SEH2_END;
2653
2654 /* Validate it */
2655 if (IdealProcessor > MAXIMUM_PROCESSORS)
2656 {
2657 /* Fail */
2659 break;
2660 }
2661
2662 /* Reference the thread */
2663 Status = ObReferenceObjectByHandle(ThreadHandle,
2667 (PVOID*)&Thread,
2668 NULL);
2669 if (!NT_SUCCESS(Status))
2670 break;
2671
2672 /* Set the ideal */
2674 (CCHAR)IdealProcessor);
2675
2676 /* Get the TEB and protect the thread */
2677 Teb = Thread->Tcb.Teb;
2679 {
2680 /* Save the ideal processor */
2681 Teb->IdealProcessor = Thread->Tcb.IdealProcessor;
2682
2683 /* Release rundown protection */
2685 }
2686
2687 /* Dereference the thread */
2689 break;
2690 }
2691
2693 {
2694 ULONG_PTR DisableBoost;
2695
2696 /* Check buffer length */
2697 if (ThreadInformationLength != sizeof(ULONG_PTR))
2698 {
2700 break;
2701 }
2702
2703 /* Use SEH for capture */
2704 _SEH2_TRY
2705 {
2706 /* Get the priority */
2707 DisableBoost = *(PULONG_PTR)ThreadInformation;
2708 }
2710 {
2711 /* Get the exception code */
2713 _SEH2_YIELD(break);
2714 }
2715 _SEH2_END;
2716
2717 /* Reference the thread */
2718 Status = ObReferenceObjectByHandle(ThreadHandle,
2722 (PVOID*)&Thread,
2723 NULL);
2724 if (!NT_SUCCESS(Status))
2725 break;
2726
2727 /* Call the kernel */
2728 KeSetDisableBoostThread(&Thread->Tcb, (BOOLEAN)DisableBoost);
2729
2730 /* Dereference the thread */
2732 break;
2733 }
2734
2735 case ThreadZeroTlsCell:
2736 {
2738 PETHREAD ProcThread;
2739
2740 /* Check buffer length */
2741 if (ThreadInformationLength != sizeof(ULONG))
2742 {
2744 break;
2745 }
2746
2747 /* Use SEH for capture */
2748 _SEH2_TRY
2749 {
2750 /* Get the priority */
2751 TlsIndex = *(PULONG)ThreadInformation;
2752 }
2754 {
2755 /* Get the exception code */
2757 _SEH2_YIELD(break);
2758 }
2759 _SEH2_END;
2760
2761 /* Reference the thread */
2762 Status = ObReferenceObjectByHandle(ThreadHandle,
2766 (PVOID*)&Thread,
2767 NULL);
2768 if (!NT_SUCCESS(Status))
2769 break;
2770
2771 /* This is only valid for the current thread */
2772 if (Thread != PsGetCurrentThread())
2773 {
2774 /* Fail */
2777 break;
2778 }
2779
2780 /* Get the process */
2781 Process = Thread->ThreadsProcess;
2782
2783 /* Loop the threads */
2784 ProcThread = PsGetNextProcessThread(Process, NULL);
2785 while (ProcThread)
2786 {
2787 /* Acquire rundown */
2789 {
2790 /* Get the TEB */
2791 Teb = ProcThread->Tcb.Teb;
2792 if (Teb)
2793 {
2794 /* Check if we're in the expansion range */
2796 {
2799 {
2800 /* Check if we have expansion slots */
2801 PVOID* ExpansionSlots = Teb->TlsExpansionSlots;
2802 if (ExpansionSlots)
2803 {
2804 /* Clear the index */
2805 ExpansionSlots[TlsIndex - TLS_MINIMUM_AVAILABLE] = 0;
2806 }
2807 }
2808 }
2809 else
2810 {
2811 /* Clear the index */
2812 Teb->TlsSlots[TlsIndex] = NULL;
2813 }
2814 }
2815
2816 /* Release rundown */
2818 }
2819
2820 /* Go to the next thread */
2821 ProcThread = PsGetNextProcessThread(Process, ProcThread);
2822 }
2823
2824 /* Dereference the thread */
2826 break;
2827 }
2828
2830 {
2831 ULONG Break;
2832
2833 /* Check buffer length */
2834 if (ThreadInformationLength != sizeof(ULONG))
2835 {
2837 break;
2838 }
2839
2840 /* Enter SEH for direct buffer read */
2841 _SEH2_TRY
2842 {
2843 Break = *(PULONG)ThreadInformation;
2844 }
2846 {
2847 /* Get exception code */
2848 Break = 0;
2850 _SEH2_YIELD(break);
2851 }
2852 _SEH2_END;
2853
2854 /* Setting 'break on termination' requires the SeDebugPrivilege */
2856 {
2857 /* We don't hold the privilege, bail out */
2859 break;
2860 }
2861
2862 /* Reference the thread */
2863 Status = ObReferenceObjectByHandle(ThreadHandle,
2867 (PVOID*)&Thread,
2868 NULL);
2869 if (!NT_SUCCESS(Status))
2870 break;
2871
2872 /* Set or clear the flag */
2873 if (Break)
2874 {
2876 }
2877 else
2878 {
2880 }
2881
2882 /* Dereference the thread */
2884 break;
2885 }
2886
2888 {
2889 /* Check buffer length */
2890 if (ThreadInformationLength != 0)
2891 {
2893 break;
2894 }
2895
2896 /* Reference the thread */
2897 Status = ObReferenceObjectByHandle(ThreadHandle,
2901 (PVOID*)&Thread,
2902 NULL);
2903 if (!NT_SUCCESS(Status))
2904 break;
2905
2906 /* Set the flag */
2908
2909 /* Dereference the thread */
2911 break;
2912 }
2913
2914#if (NTDDI_VERSION >= NTDDI_WIN10_RS1) || defined(__REACTOS__)
2916 {
2917 UNICODE_STRING CapturedThreadName;
2918 PUNICODE_STRING NewThreadName;
2919
2920 /* Check buffer length */
2922 {
2924 break;
2925 }
2926
2927 /* Reference the thread.
2928 * NOTE: Win10+ uses THREAD_SET_LIMITED_INFORMATION instead;
2929 * however some tools misuse thread names to perform suspicious
2930 * operations; therefore we try to mess with these by requiring
2931 * a bit more of access rights. */
2932 Status = ObReferenceObjectByHandle(ThreadHandle,
2936 (PVOID*)&Thread,
2937 NULL);
2938 if (!NT_SUCCESS(Status))
2939 break;
2940
2941 /* Probe and capture the thread name */
2942 Status = ProbeAndCaptureUnicodeString(&CapturedThreadName,
2944 (PUNICODE_STRING)ThreadInformation);
2945 if (!NT_SUCCESS(Status))
2946 {
2948 break;
2949 }
2950
2951 /* Allocate a new buffer only if the thread name isn't empty
2952 * (REMARK: We only consider Length instead of MaximumLength).
2953 * If empty, just reset the thread name pointer to NULL instead
2954 * of allocating an empty UNICODE_STRING. */
2955 NewThreadName = NULL;
2956 if (CapturedThreadName.Length > 0)
2957 {
2958 ULONG Length = sizeof(UNICODE_STRING) + CapturedThreadName.Length;
2959 NewThreadName = ExAllocatePoolWithTag(NonPagedPool, // FIXME: NonPagedPoolNx
2961 if (!NewThreadName)
2962 {
2964 }
2965 else
2966 {
2967 /* Copy the new thread name */
2968 NewThreadName->Length =
2969 NewThreadName->MaximumLength = CapturedThreadName.Length;
2970 NewThreadName->Buffer = (PWCH)(NewThreadName + 1);
2971 RtlCopyMemory(NewThreadName->Buffer,
2972 CapturedThreadName.Buffer,
2973 CapturedThreadName.Length);
2974 }
2975 }
2976
2977 /* Free the captured string */
2978 ReleaseCapturedUnicodeString(&CapturedThreadName, PreviousMode);
2979
2980 /* Replace the original thread name with the new one */
2981 if (NT_SUCCESS(Status))
2982 {
2983 PUNICODE_STRING OldThreadName;
2985 OldThreadName = Thread->ThreadName;
2986 Thread->ThreadName = NewThreadName;
2988
2989 /* Free the old thread name */
2990 if (OldThreadName)
2991 ExFreePoolWithTag(OldThreadName, TAG_THREAD_NAME);
2992 }
2993
2994 /* Dereference the thread */
2996 break;
2997 }
2998#endif /* (NTDDI_VERSION >= NTDDI_WIN10_RS1) || defined(__REACTOS__) */
2999
3000 /* Anything else */
3001 default:
3002 /* Not yet implemented */
3003#if DBG
3004 DPRINT1("Not implemented: %s\n", PspDumpThreadInfoClassName(ThreadInformationClass));
3005#endif
3007 }
3008
3009 return Status;
3010}
@ ThreadPriority
Definition: compat.h:937
@ ThreadIdealProcessor
Definition: compat.h:948
@ ThreadImpersonationToken
Definition: compat.h:940
@ ThreadAffinityMask
Definition: compat.h:939
@ ThreadBasePriority
Definition: compat.h:938
@ ThreadZeroTlsCell
Definition: compat.h:945
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
#define MAXIMUM_PROCESSORS
Definition: rwlock.h:5
#define THREAD_SET_THREAD_TOKEN
Definition: pstypes.h:146
#define THREAD_BASE_PRIORITY_LOWRT
Definition: pstypes.h:178
#define CT_HIDE_FROM_DEBUGGER_BIT
Definition: pstypes.h:236
#define THREAD_BASE_PRIORITY_MIN
Definition: pstypes.h:180
#define THREAD_BASE_PRIORITY_MAX
Definition: pstypes.h:179
#define THREAD_BASE_PRIORITY_IDLE
Definition: pstypes.h:181
#define TLS_EXPANSION_SLOTS
Definition: pstypes.h:306
#define CT_BREAK_ON_TERMINATION_BIT
Definition: pstypes.h:240
#define LOW_REALTIME_PRIORITY
#define THREAD_SET_INFORMATION
Definition: nt_native.h:1340
NTSTATUS NTAPI PsAssignImpersonationToken(IN PETHREAD Thread, IN HANDLE TokenHandle)
Definition: security.c:502
static WCHAR Address[46]
Definition: ping.c:68
PETHREAD NTAPI PsGetNextProcessThread(IN PEPROCESS Process, IN PETHREAD Thread OPTIONAL)
Definition: process.c:75
FORCEINLINE VOID PspLockThreadSecurityExclusive(IN PETHREAD Thread)
Definition: ps_x.h:177
#define PspSetCrossThreadFlag(Thread, Flag)
Definition: ps_x.h:25
FORCEINLINE VOID PspUnlockThreadSecurityExclusive(IN PETHREAD Thread)
Definition: ps_x.h:188
#define PspClearCrossThreadFlag(Thread, Flag)
Definition: ps_x.h:27
static __inline NTSTATUS ProbeAndCaptureUnicodeString(OUT PUNICODE_STRING Dest, IN KPROCESSOR_MODE CurrentMode, IN const UNICODE_STRING *UnsafeSrc)
Definition: probe.h:142
static __inline VOID ReleaseCapturedUnicodeString(IN PUNICODE_STRING CapturedString, IN KPROCESSOR_MODE CurrentMode)
Definition: probe.h:239
#define TLS_MINIMUM_AVAILABLE
Definition: ntddk_ex.h:236
EX_RUNDOWN_REF RundownProtect
Definition: pstypes.h:1254
ULONG IdealProcessor
Definition: ketypes.h:2091
Definition: compat.h:836
PVOID * TlsExpansionSlots
Definition: compat.h:894
PVOID TlsSlots[64]
Definition: compat.h:879
#define TAG_THREAD_NAME
Definition: tag.h:140
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
int32_t * PLONG
Definition: typedefs.h:58
char CCHAR
Definition: typedefs.h:51
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
_In_ WDFINTERRUPT _In_ WDF_INTERRUPT_POLICY _In_ WDF_INTERRUPT_PRIORITY Priority
Definition: wdfinterrupt.h:655
#define TlsIndex
Definition: ws2_32p.h:277

Referenced by BaseGetNamedObjectDirectory(), BaseProcessStartup(), CreateProcessAsUserCommon(), CsrRevertToSelf(), DoThreadNameTest(), exec_write_handler(), ImpersonateLoggedOnUser(), init_funcs(), InitFunctionPtrs(), InitializeDeviceData(), MiInitBalancerThread(), NpGetUserNamep(), QuerySetThreadValidator(), RevertToSelf(), RtlpExecuteIoWorkItem(), RtlpExecuteWorkItem(), set_thread_name(), SetThreadAffinityMask(), SetThreadDescription(), SetThreadGroupAffinity(), SetThreadIdealProcessor(), SetThreadInformation(), SetThreadPriority(), SetThreadPriorityBoost(), SetThreadToken(), START_TEST(), test_exec_memory_writes(), test_object_permanence(), test_thread_description(), Test_ThreadHideFromDebuggerClass(), Test_ThreadPriorityClass(), and TlsFree().

◆ PsReferenceProcessFilePointer()

NTSTATUS NTAPI PsReferenceProcessFilePointer ( _In_ PEPROCESS  Process,
_Outptr_ PFILE_OBJECT FileObject 
)

Definition at line 24 of file query.c.

27{
28 PSECTION Section;
29 PAGED_CODE();
30
31 /* Lock the process */
32 if (!ExAcquireRundownProtection(&Process->RundownProtect))
33 {
35 }
36
37 /* Get the section */
38 Section = Process->SectionObject;
39 if (Section)
40 {
41 /* Get the file object and reference it */
44 }
45
46 /* Release the protection */
47 ExReleaseRundownProtection(&Process->RundownProtect);
48
49 /* Return status */
50 return Section ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL;
51}
PFILE_OBJECT NTAPI MmGetFileObjectForSection(IN PVOID Section)
Definition: section.c:1546
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define ObReferenceObject
Definition: obfuncs.h:204

Referenced by NtQueryInformationProcess(), and SeLocateProcessImageName().

Variable Documentation

◆ PspTraceLevel

ULONG PspTraceLevel = 0

Definition at line 18 of file query.c.