Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

psquery.c File Reference

#include "psp.h"
#include "winerror.h"

Go to the source code of this file.

Defines

#define WS_CATCH_SIZE   8192
#define WS_OVERHEAD   16
#define MAX_WS_CATCH_INDEX   (((WS_CATCH_SIZE-WS_OVERHEAD)/sizeof(PROCESS_WS_WATCH_INFORMATION)) - 2)

Functions

NTSTATUS PsConvertToGuiThread (VOID)
NTSTATUS PspQueryWorkingSetWatch (IN HANDLE ProcessHandle, IN PROCESSINFOCLASS ProcessInformationClass, OUT PVOID ProcessInformation, IN ULONG ProcessInformationLength, OUT PULONG ReturnLength OPTIONAL, IN KPROCESSOR_MODE PreviousMode)
NTSTATUS PspQueryQuotaLimits (IN HANDLE ProcessHandle, IN PROCESSINFOCLASS ProcessInformationClass, OUT PVOID ProcessInformation, IN ULONG ProcessInformationLength, OUT PULONG ReturnLength OPTIONAL, IN KPROCESSOR_MODE PreviousMode)
NTSTATUS PspQueryPooledQuotaLimits (IN HANDLE ProcessHandle, IN PROCESSINFOCLASS ProcessInformationClass, OUT PVOID ProcessInformation, IN ULONG ProcessInformationLength, OUT PULONG ReturnLength OPTIONAL, IN KPROCESSOR_MODE PreviousMode)
NTSTATUS PspSetQuotaLimits (IN HANDLE ProcessHandle, IN PROCESSINFOCLASS ProcessInformationClass, IN PVOID ProcessInformation, IN ULONG ProcessInformationLength, IN KPROCESSOR_MODE PreviousMode)
NTSTATUS PspSetPrimaryToken (IN HANDLE ProcessHandle, IN HANDLE TokenHandle OPTIONAL, IN PACCESS_TOKEN TokenPointer OPTIONAL)
NTSTATUS NtQueryInformationProcess (IN HANDLE ProcessHandle, IN PROCESSINFOCLASS ProcessInformationClass, OUT PVOID ProcessInformation, IN ULONG ProcessInformationLength, OUT PULONG ReturnLength OPTIONAL)
NTSTATUS NtSetInformationProcess (IN HANDLE ProcessHandle, IN PROCESSINFOCLASS ProcessInformationClass, IN PVOID ProcessInformation, IN ULONG ProcessInformationLength)
NTSTATUS NtQueryInformationThread (IN HANDLE ThreadHandle, IN THREADINFOCLASS ThreadInformationClass, OUT PVOID ThreadInformation, IN ULONG ThreadInformationLength, OUT PULONG ReturnLength OPTIONAL)
NTSTATUS NtSetInformationThread (IN HANDLE ThreadHandle, IN THREADINFOCLASS ThreadInformationClass, IN PVOID ThreadInformation, IN ULONG ThreadInformationLength)
NTSTATUS PsWatchWorkingSet (IN NTSTATUS Status, IN PVOID PcValue, IN PVOID Va)
NTKERNELAPI VOID PsEstablishWin32Callouts (IN PKWIN32_PROCESS_CALLOUT ProcessCallout, IN PKWIN32_THREAD_CALLOUT ThreadCallout, IN PKWIN32_GLOBALATOMTABLE_CALLOUT GlobalAtomTableCallout, IN PKWIN32_POWEREVENT_CALLOUT PowerEventCallout, IN PKWIN32_POWERSTATE_CALLOUT PowerStateCallout, IN PKWIN32_JOB_CALLOUT JobCallout, IN PVOID BatchFlushRoutine)
VOID PsSetProcessPriorityByClass (IN PEPROCESS Process, IN PSPROCESSPRIORITYMODE PriorityMode)

Variables

KMUTANT ObpInitKillMutant
PEPROCESS ExpDefaultErrorPortProcess
BOOLEAN PsWatchEnabled
KPRIORITY PspPriorityTable [PROCESS_PRIORITY_CLASS_ABOVE_NORMAL+1] = {8,4,8,13,24,6,10}
PKWIN32_PROCESS_CALLOUT PspW32ProcessCallout
PKWIN32_THREAD_CALLOUT PspW32ThreadCallout
PKWIN32_JOB_CALLOUT PspW32JobCallout
PKWIN32_POWEREVENT_CALLOUT PopEventCallout
PKWIN32_POWERSTATE_CALLOUT PopStateCallout


Define Documentation

#define MAX_WS_CATCH_INDEX   (((WS_CATCH_SIZE-WS_OVERHEAD)/sizeof(PROCESS_WS_WATCH_INFORMATION)) - 2)
 

Definition at line 50 of file psquery.c.

Referenced by NtSetInformationProcess(), and PspQueryWorkingSetWatch().

#define WS_CATCH_SIZE   8192
 

Definition at line 48 of file psquery.c.

Referenced by NtSetInformationProcess().

#define WS_OVERHEAD   16
 

Definition at line 49 of file psquery.c.


Function Documentation

NTSTATUS NtQueryInformationProcess IN HANDLE  ProcessHandle,
IN PROCESSINFOCLASS  ProcessInformationClass,
OUT PVOID  ProcessInformation,
IN ULONG  ProcessInformationLength,
OUT PULONG ReturnLength  OPTIONAL
 

Definition at line 531 of file psquery.c.

References DebugPort, EXCEPTION_EXECUTE_HANDLER, Executive, FALSE, _HANDLE_TABLE::HandleCount, KeMaximumIncrement, KeReleaseMutant(), KernelMode, KeWaitForSingleObject(), KPROCESSOR_MODE, NonPagedPool, NT_SUCCESS, NTSTATUS(), NULL, ObDereferenceObject, ObpInitKillMutant, ObQueryDeviceMapInformation(), ObReferenceObjectByHandle(), PAGE_SHIFT, PAGED_CODE, PagedPool, ProbeForWrite(), ProbeForWriteUlong, PspQueryLdtInformation(), PspQueryPooledQuotaLimits(), PspQueryQuotaLimits(), PspQueryWorkingSetWatch(), and PsProcessType.

Referenced by _EndTask(), CreateCtrlThread(), GetHardErrorText(), GetNetworkDrives(), UserClientShutdown(), and WaitForInputIdle().

00539 { 00540 PEPROCESS Process; 00541 KPROCESSOR_MODE PreviousMode; 00542 NTSTATUS st; 00543 PROCESS_BASIC_INFORMATION BasicInfo; 00544 VM_COUNTERS VmCounters; 00545 IO_COUNTERS IoCounters; 00546 KERNEL_USER_TIMES SysUserTime; 00547 HANDLE DebugPort; 00548 ULONG HandleCount; 00549 ULONG DefaultHardErrorMode; 00550 HANDLE Wx86Info; 00551 PHANDLE_TABLE Ht; 00552 ULONG DisableBoost; 00553 PPROCESS_DEVICEMAP_INFORMATION DeviceMapInfo; 00554 PROCESS_SESSION_INFORMATION SessionInfo; 00555 PROCESS_PRIORITY_CLASS PriorityClass; 00556 ULONG_PTR Wow64Info; 00557 00558 PAGED_CODE(); 00559 00560 // 00561 // Get previous processor mode and probe output argument if necessary. 00562 // 00563 00564 PreviousMode = KeGetPreviousMode(); 00565 if (PreviousMode != KernelMode) { 00566 try { 00567 ProbeForWrite(ProcessInformation, 00568 ProcessInformationLength, 00569 sizeof(ULONG)); 00570 if (ARGUMENT_PRESENT(ReturnLength)) { 00571 ProbeForWriteUlong(ReturnLength); 00572 } 00573 } except(EXCEPTION_EXECUTE_HANDLER) { 00574 return GetExceptionCode(); 00575 } 00576 } 00577 00578 // 00579 // Check argument validity. 00580 // 00581 00582 switch ( ProcessInformationClass ) { 00583 00584 case ProcessWorkingSetWatch: 00585 00586 return PspQueryWorkingSetWatch( 00587 ProcessHandle, 00588 ProcessInformationClass, 00589 ProcessInformation, 00590 ProcessInformationLength, 00591 ReturnLength, 00592 PreviousMode 00593 ); 00594 00595 case ProcessBasicInformation: 00596 00597 if ( ProcessInformationLength != (ULONG) sizeof(PROCESS_BASIC_INFORMATION) ) { 00598 return STATUS_INFO_LENGTH_MISMATCH; 00599 } 00600 00601 st = ObReferenceObjectByHandle( 00602 ProcessHandle, 00603 PROCESS_QUERY_INFORMATION, 00604 PsProcessType, 00605 PreviousMode, 00606 (PVOID *)&Process, 00607 NULL 00608 ); 00609 if ( !NT_SUCCESS(st) ) { 00610 return st; 00611 } 00612 00613 BasicInfo.ExitStatus = Process->ExitStatus; 00614 BasicInfo.PebBaseAddress = Process->Peb; 00615 BasicInfo.AffinityMask = Process->Pcb.Affinity; 00616 BasicInfo.BasePriority = Process->Pcb.BasePriority; 00617 BasicInfo.UniqueProcessId = (ULONG_PTR)Process->UniqueProcessId; 00618 BasicInfo.InheritedFromUniqueProcessId = (ULONG_PTR)Process->InheritedFromUniqueProcessId; 00619 00620 ObDereferenceObject(Process); 00621 00622 // 00623 // Either of these may cause an access violation. The 00624 // exception handler will return access violation as 00625 // status code. No further cleanup needs to be done. 00626 // 00627 00628 try { 00629 *(PPROCESS_BASIC_INFORMATION) ProcessInformation = BasicInfo; 00630 00631 if (ARGUMENT_PRESENT(ReturnLength) ) { 00632 *ReturnLength = sizeof(PROCESS_BASIC_INFORMATION); 00633 } 00634 } except(EXCEPTION_EXECUTE_HANDLER) { 00635 return STATUS_SUCCESS; 00636 } 00637 00638 return STATUS_SUCCESS; 00639 00640 case ProcessDefaultHardErrorMode: 00641 00642 if ( ProcessInformationLength != sizeof(ULONG) ) { 00643 return STATUS_INFO_LENGTH_MISMATCH; 00644 } 00645 00646 st = ObReferenceObjectByHandle( 00647 ProcessHandle, 00648 PROCESS_QUERY_INFORMATION, 00649 PsProcessType, 00650 PreviousMode, 00651 (PVOID *)&Process, 00652 NULL 00653 ); 00654 00655 if ( !NT_SUCCESS(st) ) { 00656 return st; 00657 } 00658 00659 DefaultHardErrorMode = Process->DefaultHardErrorProcessing; 00660 00661 ObDereferenceObject(Process); 00662 00663 try { 00664 *(PULONG) ProcessInformation = DefaultHardErrorMode; 00665 00666 if (ARGUMENT_PRESENT(ReturnLength) ) { 00667 *ReturnLength = sizeof(ULONG); 00668 } 00669 } except(EXCEPTION_EXECUTE_HANDLER) { 00670 return STATUS_SUCCESS; 00671 } 00672 00673 return STATUS_SUCCESS; 00674 case ProcessQuotaLimits: 00675 00676 return PspQueryQuotaLimits( 00677 ProcessHandle, 00678 ProcessInformationClass, 00679 ProcessInformation, 00680 ProcessInformationLength, 00681 ReturnLength, 00682 PreviousMode 00683 ); 00684 00685 case ProcessPooledUsageAndLimits: 00686 00687 return PspQueryPooledQuotaLimits( 00688 ProcessHandle, 00689 ProcessInformationClass, 00690 ProcessInformation, 00691 ProcessInformationLength, 00692 ReturnLength, 00693 PreviousMode 00694 ); 00695 00696 case ProcessIoCounters: 00697 00698 if ( ProcessInformationLength != (ULONG) sizeof(IO_COUNTERS) ) { 00699 return STATUS_INFO_LENGTH_MISMATCH; 00700 } 00701 00702 st = ObReferenceObjectByHandle( 00703 ProcessHandle, 00704 PROCESS_QUERY_INFORMATION, 00705 PsProcessType, 00706 PreviousMode, 00707 (PVOID *)&Process, 00708 NULL 00709 ); 00710 if ( !NT_SUCCESS(st) ) { 00711 return st; 00712 } 00713 00714 IoCounters.ReadOperationCount = Process->ReadOperationCount.QuadPart; 00715 IoCounters.WriteOperationCount = Process->WriteOperationCount.QuadPart; 00716 IoCounters.OtherOperationCount = Process->OtherOperationCount.QuadPart; 00717 IoCounters.ReadTransferCount = Process->ReadTransferCount.QuadPart; 00718 IoCounters.WriteTransferCount = Process->WriteTransferCount.QuadPart; 00719 IoCounters.OtherTransferCount = Process->OtherTransferCount.QuadPart; 00720 00721 ObDereferenceObject(Process); 00722 00723 // 00724 // Either of these may cause an access violation. The 00725 // exception handler will return access violation as 00726 // status code. No further cleanup needs to be done. 00727 // 00728 00729 try { 00730 *(PIO_COUNTERS) ProcessInformation = IoCounters; 00731 00732 if (ARGUMENT_PRESENT(ReturnLength) ) { 00733 *ReturnLength = sizeof(IO_COUNTERS); 00734 } 00735 } except(EXCEPTION_EXECUTE_HANDLER) { 00736 return STATUS_SUCCESS; 00737 } 00738 00739 return STATUS_SUCCESS; 00740 00741 case ProcessVmCounters: 00742 00743 if ( ProcessInformationLength != (ULONG) sizeof(VM_COUNTERS) ) { 00744 return STATUS_INFO_LENGTH_MISMATCH; 00745 } 00746 00747 st = ObReferenceObjectByHandle( 00748 ProcessHandle, 00749 PROCESS_QUERY_INFORMATION, 00750 PsProcessType, 00751 PreviousMode, 00752 (PVOID *)&Process, 00753 NULL 00754 ); 00755 if ( !NT_SUCCESS(st) ) { 00756 return st; 00757 } 00758 00759 00760 // 00761 // Note: At some point, we might have to grab the statistics 00762 // lock to reliably read this stuff 00763 // 00764 00765 VmCounters.PeakVirtualSize = Process->PeakVirtualSize; 00766 VmCounters.VirtualSize = Process->VirtualSize; 00767 VmCounters.PageFaultCount = Process->Vm.PageFaultCount; 00768 VmCounters.PeakWorkingSetSize = Process->Vm.PeakWorkingSetSize << PAGE_SHIFT; 00769 VmCounters.WorkingSetSize = Process->Vm.WorkingSetSize << PAGE_SHIFT; 00770 VmCounters.QuotaPeakPagedPoolUsage = Process->QuotaPeakPoolUsage[PagedPool]; 00771 VmCounters.QuotaPagedPoolUsage = Process->QuotaPoolUsage[PagedPool]; 00772 VmCounters.QuotaPeakNonPagedPoolUsage = Process->QuotaPeakPoolUsage[NonPagedPool]; 00773 VmCounters.QuotaNonPagedPoolUsage = Process->QuotaPoolUsage[NonPagedPool]; 00774 VmCounters.PagefileUsage = Process->PagefileUsage << PAGE_SHIFT; 00775 VmCounters.PeakPagefileUsage = Process->PeakPagefileUsage << PAGE_SHIFT; 00776 00777 ObDereferenceObject(Process); 00778 00779 // 00780 // Either of these may cause an access violation. The 00781 // exception handler will return access violation as 00782 // status code. No further cleanup needs to be done. 00783 // 00784 00785 try { 00786 *(PVM_COUNTERS) ProcessInformation = VmCounters; 00787 00788 if (ARGUMENT_PRESENT(ReturnLength) ) { 00789 *ReturnLength = sizeof(VM_COUNTERS); 00790 } 00791 } except(EXCEPTION_EXECUTE_HANDLER) { 00792 return STATUS_SUCCESS; 00793 } 00794 00795 return STATUS_SUCCESS; 00796 00797 case ProcessTimes: 00798 00799 if ( ProcessInformationLength != (ULONG) sizeof(KERNEL_USER_TIMES) ) { 00800 return STATUS_INFO_LENGTH_MISMATCH; 00801 } 00802 00803 st = ObReferenceObjectByHandle( 00804 ProcessHandle, 00805 PROCESS_QUERY_INFORMATION, 00806 PsProcessType, 00807 PreviousMode, 00808 (PVOID *)&Process, 00809 NULL 00810 ); 00811 00812 if ( !NT_SUCCESS(st) ) { 00813 return st; 00814 } 00815 00816 // 00817 // Need some type of interlock on KiTimeLock 00818 // 00819 00820 SysUserTime.KernelTime.QuadPart = UInt32x32To64(Process->Pcb.KernelTime, 00821 KeMaximumIncrement); 00822 00823 SysUserTime.UserTime.QuadPart = UInt32x32To64(Process->Pcb.UserTime, 00824 KeMaximumIncrement); 00825 00826 SysUserTime.CreateTime = Process->CreateTime; 00827 SysUserTime.ExitTime = Process->ExitTime; 00828 00829 ObDereferenceObject(Process); 00830 00831 // 00832 // Either of these may cause an access violation. The 00833 // exception handler will return access violation as 00834 // status code. No further cleanup needs to be done. 00835 // 00836 00837 try { 00838 *(PKERNEL_USER_TIMES) ProcessInformation = SysUserTime; 00839 00840 if (ARGUMENT_PRESENT(ReturnLength) ) { 00841 *ReturnLength = sizeof(KERNEL_USER_TIMES); 00842 } 00843 } except(EXCEPTION_EXECUTE_HANDLER) { 00844 return STATUS_SUCCESS; 00845 } 00846 00847 return STATUS_SUCCESS; 00848 00849 case ProcessDebugPort : 00850 00851 // 00852 // Hack for RtlQueryProcessDebugInformation: 00853 // if length is sizeof(HANDLE)+1, return a handle 00854 // to the object so that the debugger may be temporarily 00855 // disabled by clearing and replacing the port. 00856 // 00857 if ( ProcessInformationLength != (ULONG) sizeof(HANDLE) ) { 00858 return STATUS_INFO_LENGTH_MISMATCH; 00859 } 00860 00861 st = ObReferenceObjectByHandle( 00862 ProcessHandle, 00863 PROCESS_QUERY_INFORMATION, 00864 PsProcessType, 00865 PreviousMode, 00866 (PVOID *)&Process, 00867 NULL 00868 ); 00869 00870 if ( !NT_SUCCESS(st) ) { 00871 return st; 00872 } 00873 00874 if (Process->DebugPort == NULL) { 00875 00876 DebugPort = NULL; 00877 00878 } else if (ProcessInformationLength == (ULONG) sizeof(HANDLE)) { 00879 00880 DebugPort = (HANDLE)-1; 00881 00882 } 00883 00884 ObDereferenceObject(Process); 00885 00886 // 00887 // Either of these may cause an access violation. The 00888 // exception handler will return access violation as 00889 // status code. No further cleanup needs to be done. 00890 // 00891 00892 try { 00893 *(PHANDLE) ProcessInformation = DebugPort; 00894 00895 if (ARGUMENT_PRESENT(ReturnLength) ) { 00896 *ReturnLength = sizeof(HANDLE); 00897 } 00898 } except(EXCEPTION_EXECUTE_HANDLER) { 00899 return STATUS_ACCESS_VIOLATION; 00900 } 00901 00902 return STATUS_SUCCESS; 00903 00904 case ProcessHandleCount : 00905 00906 if ( ProcessInformationLength != (ULONG) sizeof(ULONG) ) { 00907 return STATUS_INFO_LENGTH_MISMATCH; 00908 } 00909 00910 st = ObReferenceObjectByHandle( 00911 ProcessHandle, 00912 PROCESS_QUERY_INFORMATION, 00913 PsProcessType, 00914 PreviousMode, 00915 (PVOID *)&Process, 00916 NULL 00917 ); 00918 00919 if ( !NT_SUCCESS(st) ) { 00920 return st; 00921 } 00922 00923 KeWaitForSingleObject( &ObpInitKillMutant, 00924 Executive, 00925 KernelMode, 00926 FALSE, 00927 NULL 00928 ); 00929 00930 Ht = (PHANDLE_TABLE)Process->ObjectTable; 00931 00932 if ( Ht ) { 00933 HandleCount = Ht->HandleCount; 00934 } 00935 else { 00936 HandleCount = 0; 00937 } 00938 00939 KeReleaseMutant( &ObpInitKillMutant, 0, FALSE, FALSE ); 00940 00941 ObDereferenceObject(Process); 00942 00943 // 00944 // Either of these may cause an access violation. The 00945 // exception handler will return access violation as 00946 // status code. No further cleanup needs to be done. 00947 // 00948 00949 try { 00950 *(PULONG) ProcessInformation = HandleCount; 00951 00952 if (ARGUMENT_PRESENT(ReturnLength) ) { 00953 *ReturnLength = sizeof(HANDLE); 00954 } 00955 } except(EXCEPTION_EXECUTE_HANDLER) { 00956 return STATUS_SUCCESS; 00957 } 00958 00959 return STATUS_SUCCESS; 00960 00961 case ProcessLdtInformation : 00962 00963 st = ObReferenceObjectByHandle( 00964 ProcessHandle, 00965 PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, 00966 PsProcessType, 00967 PreviousMode, 00968 (PVOID *)&Process, 00969 NULL 00970 ); 00971 00972 if ( !NT_SUCCESS(st) ) { 00973 return st; 00974 } 00975 00976 try { 00977 00978 st = PspQueryLdtInformation( 00979 Process, 00980 ProcessInformation, 00981 ProcessInformationLength, 00982 ReturnLength 00983 ); 00984 00985 } except(EXCEPTION_EXECUTE_HANDLER) { 00986 st = STATUS_SUCCESS; 00987 } 00988 00989 ObDereferenceObject(Process); 00990 return st; 00991 00992 00993 case ProcessWx86Information : 00994 00995 if ( ProcessInformationLength != sizeof(HANDLE) ) { 00996 return STATUS_INFO_LENGTH_MISMATCH; 00997 } 00998 00999 Wx86Info = NULL; 01000 01001 #ifndef i386 01002 st = ObReferenceObjectByHandle( 01003 ProcessHandle, 01004 PROCESS_QUERY_INFORMATION, 01005 PsProcessType, 01006 PreviousMode, 01007 (PVOID *)&Process, 01008 NULL 01009 ); 01010 01011 if ( !NT_SUCCESS(st) ) { 01012 return st; 01013 } 01014 01015 if ((ULONG_PTR)Process->VdmObjects == sizeof(WX86TIB)) { 01016 Wx86Info = Process->VdmObjects; 01017 } 01018 01019 ObDereferenceObject(Process); 01020 #endif 01021 01022 try { 01023 *(PHANDLE) ProcessInformation = Wx86Info; 01024 01025 if (ARGUMENT_PRESENT(ReturnLength) ) { 01026 *ReturnLength = sizeof(HANDLE); 01027 } 01028 } except(EXCEPTION_EXECUTE_HANDLER) { 01029 return STATUS_SUCCESS; 01030 } 01031 01032 return STATUS_SUCCESS; 01033 01034 case ProcessPriorityBoost: 01035 if ( ProcessInformationLength != sizeof(ULONG) ) { 01036 return STATUS_INFO_LENGTH_MISMATCH; 01037 } 01038 01039 st = ObReferenceObjectByHandle( 01040 ProcessHandle, 01041 PROCESS_QUERY_INFORMATION, 01042 PsProcessType, 01043 PreviousMode, 01044 (PVOID *)&Process, 01045 NULL 01046 ); 01047 01048 if ( !NT_SUCCESS(st) ) { 01049 return st; 01050 } 01051 01052 DisableBoost = Process->Pcb.DisableBoost ? 1 : 0; 01053 01054 ObDereferenceObject(Process); 01055 01056 try { 01057 *(PULONG)ProcessInformation = DisableBoost; 01058 01059 if (ARGUMENT_PRESENT(ReturnLength) ) { 01060 *ReturnLength = sizeof(ULONG); 01061 } 01062 } except(EXCEPTION_EXECUTE_HANDLER) { 01063 return GetExceptionCode(); 01064 } 01065 01066 return st; 01067 01068 case ProcessDeviceMap: 01069 DeviceMapInfo = (PPROCESS_DEVICEMAP_INFORMATION)ProcessInformation; 01070 if ( ProcessInformationLength != sizeof(DeviceMapInfo->Query) ) { 01071 return STATUS_INFO_LENGTH_MISMATCH; 01072 } 01073 01074 st = ObReferenceObjectByHandle( 01075 ProcessHandle, 01076 PROCESS_QUERY_INFORMATION, 01077 PsProcessType, 01078 PreviousMode, 01079 (PVOID *)&Process, 01080 NULL 01081 ); 01082 01083 if ( !NT_SUCCESS(st) ) { 01084 return st; 01085 } 01086 01087 st = ObQueryDeviceMapInformation( Process, DeviceMapInfo ); 01088 ObDereferenceObject(Process); 01089 return st; 01090 01091 case ProcessSessionInformation : 01092 01093 if ( ProcessInformationLength != (ULONG) sizeof(PROCESS_SESSION_INFORMATION) ) { 01094 return STATUS_INFO_LENGTH_MISMATCH; 01095 } 01096 01097 st = ObReferenceObjectByHandle( 01098 ProcessHandle, 01099 PROCESS_QUERY_INFORMATION, 01100 PsProcessType, 01101 PreviousMode, 01102 (PVOID *)&Process, 01103 NULL 01104 ); 01105 if ( !NT_SUCCESS(st) ) { 01106 return st; 01107 } 01108 01109 SessionInfo.SessionId = Process->SessionId; 01110 01111 ObDereferenceObject(Process); 01112 01113 try { 01114 *(PPROCESS_SESSION_INFORMATION) ProcessInformation = SessionInfo; 01115 01116 if (ARGUMENT_PRESENT(ReturnLength) ) { 01117 *ReturnLength = sizeof(PROCESS_SESSION_INFORMATION); 01118 } 01119 } except(EXCEPTION_EXECUTE_HANDLER) { 01120 return STATUS_SUCCESS; 01121 } 01122 01123 return( STATUS_SUCCESS ); 01124 01125 01126 01127 case ProcessPriorityClass: 01128 01129 if ( ProcessInformationLength != sizeof(PROCESS_PRIORITY_CLASS) ) { 01130 return STATUS_INFO_LENGTH_MISMATCH; 01131 } 01132 01133 st = ObReferenceObjectByHandle( 01134 ProcessHandle, 01135 PROCESS_QUERY_INFORMATION, 01136 PsProcessType, 01137 PreviousMode, 01138 (PVOID *)&Process, 01139 NULL 01140 ); 01141 if ( !NT_SUCCESS(st) ) { 01142 return st; 01143 } 01144 01145 PriorityClass.Foreground = FALSE; 01146 PriorityClass.PriorityClass = Process->PriorityClass; 01147 01148 ObDereferenceObject(Process); 01149 01150 try { 01151 *(PPROCESS_PRIORITY_CLASS) ProcessInformation = PriorityClass; 01152 01153 if (ARGUMENT_PRESENT(ReturnLength) ) { 01154 *ReturnLength = sizeof(PROCESS_PRIORITY_CLASS); 01155 } 01156 } except(EXCEPTION_EXECUTE_HANDLER) { 01157 return STATUS_SUCCESS; 01158 } 01159 01160 return( STATUS_SUCCESS ); 01161 01162 01163 case ProcessWow64Information: 01164 01165 if ( ProcessInformationLength != sizeof(ULONG_PTR) ) { 01166 return STATUS_INFO_LENGTH_MISMATCH; 01167 } 01168 01169 st = ObReferenceObjectByHandle( 01170 ProcessHandle, 01171 PROCESS_QUERY_INFORMATION, 01172 PsProcessType, 01173 PreviousMode, 01174 (PVOID *)&Process, 01175 NULL 01176 ); 01177 if ( !NT_SUCCESS(st) ) { 01178 return st; 01179 } 01180 01181 Wow64Info = 0; 01182 01183 if (Process->Wow64Process != NULL) { 01184 Wow64Info = (ULONG_PTR)(Process->Wow64Process->Wow64); 01185 } 01186 01187 01188 ObDereferenceObject(Process); 01189 01190 try { 01191 *(PULONG_PTR)ProcessInformation = Wow64Info; 01192 01193 if (ARGUMENT_PRESENT(ReturnLength) ) { 01194 *ReturnLength = sizeof(ULONG_PTR); 01195 } 01196 } except(EXCEPTION_EXECUTE_HANDLER) { 01197 return STATUS_SUCCESS; 01198 } 01199 01200 return( STATUS_SUCCESS ); 01201 01202 01203 default: 01204 01205 return STATUS_INVALID_INFO_CLASS; 01206 } 01207 01208 }

NTSTATUS NtQueryInformationThread IN HANDLE  ThreadHandle,
IN THREADINFOCLASS  ThreadInformationClass,
OUT PVOID  ThreadInformation,
IN ULONG  ThreadInformationLength,
OUT PULONG ReturnLength  OPTIONAL
 

Definition at line 2706 of file psquery.c.

References APC_LEVEL, EXCEPTION_EXECUTE_HANDLER, KeLowerIrql(), KeMaximumIncrement, KeQueryBasePriorityThread(), KeRaiseIrql(), KeReadStateThread(), KernelMode, KPROCESSOR_MODE, NT_SUCCESS, NTSTATUS(), NULL, ObDereferenceObject, ObReferenceObjectByHandle(), PAGED_CODE, ProbeForWrite(), ProbeForWriteUlong, PS_GET_THREAD_CREATE_TIME, PsGetCurrentThread, PspQueryDescriptorThread(), PsThreadType, THREAD_TO_PROCESS, ThreadHandle, and _EPROCESS::ThreadListHead.

Referenced by CreateWindowsWindow(), RtlCheckForOrphanedCriticalSections(), RtlDestroyQueryDebugBuffer(), RtlFreeUserThreadStack(), RtlpIOWorkerThread(), RtlpWorkerThread(), and RtlQueryProcessDebugInformation().

02716 : 02717 02718 This function queries the state of a thread object and returns the 02719 requested information in the specified record structure. 02720 02721 Arguments: 02722 02723 ThreadHandle - Supplies a handle to a thread object. 02724 02725 ThreadInformationClass - Supplies the class of information being 02726 requested. 02727 02728 ThreadInformation - Supplies a pointer to a record that is to 02729 receive the requested information. 02730 02731 ThreadInformationLength - Supplies the length of the record that is 02732 to receive the requested information. 02733 02734 ReturnLength - Supplies an optional pointer to a variable that is to 02735 receive the actual length of information that is returned. 02736 02737 Return Value: 02738 02739 TBS 02740 02741 --*/ 02742 02743 { 02744 02745 LARGE_INTEGER PerformanceCount; 02746 PETHREAD Thread; 02747 PEPROCESS Process; 02748 ULONG LastThread; 02749 KPROCESSOR_MODE PreviousMode; 02750 NTSTATUS st; 02751 THREAD_BASIC_INFORMATION BasicInfo; 02752 KERNEL_USER_TIMES SysUserTime; 02753 PVOID Win32StartAddressValue; 02754 ULONG DisableBoost; 02755 ULONG IoPending ; 02756 KIRQL irql ; 02757 02758 // 02759 // Get previous processor mode and probe output argument if necessary. 02760 // 02761 02762 PAGED_CODE(); 02763 02764 PreviousMode = KeGetPreviousMode(); 02765 if (PreviousMode != KernelMode) { 02766 try { 02767 ProbeForWrite(ThreadInformation, 02768 ThreadInformationLength, 02769 sizeof(ULONG)); 02770 if (ARGUMENT_PRESENT(ReturnLength)) { 02771 ProbeForWriteUlong(ReturnLength); 02772 } 02773 } except(EXCEPTION_EXECUTE_HANDLER) { 02774 return GetExceptionCode(); 02775 } 02776 } 02777 02778 // 02779 // Check argument validity. 02780 // 02781 02782 switch ( ThreadInformationClass ) { 02783 02784 case ThreadBasicInformation: 02785 02786 if ( ThreadInformationLength != (ULONG) sizeof(THREAD_BASIC_INFORMATION) ) { 02787 return STATUS_INFO_LENGTH_MISMATCH; 02788 } 02789 02790 st = ObReferenceObjectByHandle( 02791 ThreadHandle, 02792 THREAD_QUERY_INFORMATION, 02793 PsThreadType, 02794 PreviousMode, 02795 (PVOID *)&Thread, 02796 NULL 02797 ); 02798 if ( !NT_SUCCESS(st) ) { 02799 return st; 02800 } 02801 02802 if (KeReadStateThread(&Thread->Tcb)) { 02803 BasicInfo.ExitStatus = Thread->ExitStatus; 02804 } 02805 else { 02806 BasicInfo.ExitStatus = STATUS_PENDING; 02807 } 02808 02809 BasicInfo.TebBaseAddress = (PTEB) Thread->Tcb.Teb; 02810 BasicInfo.ClientId = Thread->Cid; 02811 BasicInfo.AffinityMask = Thread->Tcb.Affinity; 02812 BasicInfo.Priority = Thread->Tcb.Priority; 02813 BasicInfo.BasePriority = KeQueryBasePriorityThread(&Thread->Tcb); 02814 02815 ObDereferenceObject(Thread); 02816 02817 // 02818 // Either of these may cause an access violation. The 02819 // exception handler will return access violation as 02820 // status code. No further cleanup needs to be done. 02821 // 02822 02823 try { 02824 *(PTHREAD_BASIC_INFORMATION) ThreadInformation = BasicInfo; 02825 02826 if (ARGUMENT_PRESENT(ReturnLength) ) { 02827 *ReturnLength = sizeof(THREAD_BASIC_INFORMATION); 02828 } 02829 } except(EXCEPTION_EXECUTE_HANDLER) { 02830 return STATUS_SUCCESS; 02831 } 02832 02833 return STATUS_SUCCESS; 02834 02835 case ThreadTimes: 02836 02837 if ( ThreadInformationLength != (ULONG) sizeof(KERNEL_USER_TIMES) ) { 02838 return STATUS_INFO_LENGTH_MISMATCH; 02839 } 02840 02841 st = ObReferenceObjectByHandle( 02842 ThreadHandle, 02843 THREAD_QUERY_INFORMATION, 02844 PsThreadType, 02845 PreviousMode, 02846 (PVOID *)&Thread, 02847 NULL 02848 ); 02849 02850 if ( !NT_SUCCESS(st) ) { 02851 return st; 02852 } 02853 02854 SysUserTime.KernelTime.QuadPart = UInt32x32To64(Thread->Tcb.KernelTime, 02855 KeMaximumIncrement); 02856 02857 SysUserTime.UserTime.QuadPart = UInt32x32To64(Thread->Tcb.UserTime, 02858 KeMaximumIncrement); 02859 02860 SysUserTime.CreateTime.QuadPart = PS_GET_THREAD_CREATE_TIME(Thread); 02861 if (KeReadStateThread(&Thread->Tcb)) { 02862 SysUserTime.ExitTime = Thread->ExitTime; 02863 } else { 02864 SysUserTime.ExitTime.QuadPart = 0; 02865 } 02866 ObDereferenceObject(Thread); 02867 02868 // 02869 // Either of these may cause an access violation. The 02870 // exception handler will return access violation as 02871 // status code. No further cleanup needs to be done. 02872 // 02873 02874 try { 02875 *(PKERNEL_USER_TIMES) ThreadInformation = SysUserTime; 02876 02877 if (ARGUMENT_PRESENT(ReturnLength) ) { 02878 *ReturnLength = sizeof(KERNEL_USER_TIMES); 02879 } 02880 } except(EXCEPTION_EXECUTE_HANDLER) { 02881 return STATUS_SUCCESS; 02882 } 02883 02884 return STATUS_SUCCESS; 02885 02886 case ThreadDescriptorTableEntry : 02887 02888 st = ObReferenceObjectByHandle( 02889 ThreadHandle, 02890 THREAD_QUERY_INFORMATION, 02891 PsThreadType, 02892 PreviousMode, 02893 (PVOID *)&Thread, 02894 NULL 02895 ); 02896 02897 if ( !NT_SUCCESS(st) ) { 02898 return st; 02899 } 02900 02901 st = PspQueryDescriptorThread( Thread, 02902 ThreadInformation, 02903 ThreadInformationLength, 02904 ReturnLength 02905 ); 02906 02907 ObDereferenceObject(Thread); 02908 02909 return st; 02910 02911 case ThreadQuerySetWin32StartAddress: 02912 if ( ThreadInformationLength != sizeof(ULONG_PTR) ) { 02913 return STATUS_INFO_LENGTH_MISMATCH; 02914 } 02915 02916 st = ObReferenceObjectByHandle( 02917 ThreadHandle, 02918 THREAD_QUERY_INFORMATION, 02919 PsThreadType, 02920 PreviousMode, 02921 (PVOID *)&Thread, 02922 NULL 02923 ); 02924 02925 if ( !NT_SUCCESS(st) ) { 02926 return st; 02927 } 02928 02929 Win32StartAddressValue = Thread->Win32StartAddress; 02930 ObDereferenceObject(Thread); 02931 02932 try { 02933 *(PVOID *) ThreadInformation = Win32StartAddressValue; 02934 02935 if (ARGUMENT_PRESENT(ReturnLength) ) { 02936 *ReturnLength = sizeof(ULONG_PTR); 02937 } 02938 } except(EXCEPTION_EXECUTE_HANDLER) { 02939 return GetExceptionCode(); 02940 } 02941 02942 return st; 02943 02944 // 02945 // Query thread cycle counter. 02946 // 02947 02948 case ThreadPerformanceCount: 02949 if ( ThreadInformationLength != sizeof(LARGE_INTEGER) ) { 02950 return STATUS_INFO_LENGTH_MISMATCH; 02951 } 02952 02953 st = ObReferenceObjectByHandle( 02954 ThreadHandle, 02955 THREAD_QUERY_INFORMATION, 02956 PsThreadType, 02957 PreviousMode, 02958 (PVOID *)&Thread, 02959 NULL 02960 ); 02961 02962 if ( !NT_SUCCESS(st) ) { 02963 return st; 02964 } 02965 02966 PerformanceCount.LowPart = Thread->PerformanceCountLow; 02967 PerformanceCount.HighPart = Thread->PerformanceCountHigh; 02968 ObDereferenceObject(Thread); 02969 02970 try { 02971 *(PLARGE_INTEGER)ThreadInformation = PerformanceCount; 02972 02973 if (ARGUMENT_PRESENT(ReturnLength) ) { 02974 *ReturnLength = sizeof(LARGE_INTEGER); 02975 } 02976 } except(EXCEPTION_EXECUTE_HANDLER) { 02977 return GetExceptionCode(); 02978 } 02979 02980 return st; 02981 02982 case ThreadAmILastThread: 02983 if ( ThreadInformationLength != sizeof(ULONG) ) { 02984 return STATUS_INFO_LENGTH_MISMATCH; 02985 } 02986 02987 Thread = PsGetCurrentThread(); 02988 Process = THREAD_TO_PROCESS(Thread); 02989 02990 if ( (Process->ThreadListHead.Flink == Process->ThreadListHead.Blink) 02991 && (Process->ThreadListHead.Flink == &Thread->ThreadListEntry) ) { 02992 LastThread = 1; 02993 } 02994 else { 02995 LastThread = 0; 02996 } 02997 02998 try { 02999 *(PULONG)ThreadInformation = LastThread; 03000 03001 if (ARGUMENT_PRESENT(ReturnLength) ) { 03002 *ReturnLength = sizeof(ULONG); 03003 } 03004 } except(EXCEPTION_EXECUTE_HANDLER) { 03005 return GetExceptionCode(); 03006 } 03007 03008 return STATUS_SUCCESS; 03009 03010 case ThreadPriorityBoost: 03011 if ( ThreadInformationLength != sizeof(ULONG) ) { 03012 return STATUS_INFO_LENGTH_MISMATCH; 03013 } 03014 03015 st = ObReferenceObjectByHandle( 03016 ThreadHandle, 03017 THREAD_QUERY_INFORMATION, 03018 PsThreadType, 03019 PreviousMode, 03020 (PVOID *)&Thread, 03021 NULL 03022 ); 03023 03024 if ( !NT_SUCCESS(st) ) { 03025 return st; 03026 } 03027 03028 DisableBoost = Thread->Tcb.DisableBoost ? 1 : 0; 03029 03030 ObDereferenceObject(Thread); 03031 03032 try { 03033 *(PULONG)ThreadInformation = DisableBoost; 03034 03035 if (ARGUMENT_PRESENT(ReturnLength) ) { 03036 *ReturnLength = sizeof(ULONG); 03037 } 03038 } except(EXCEPTION_EXECUTE_HANDLER) { 03039 return GetExceptionCode(); 03040 } 03041 03042 return st; 03043 03044 case ThreadIsIoPending: 03045 03046 // 03047 // NB: Darryl wanted it pointed out that this is, 03048 // of course, transitory information, somewhat 03049 // lame, and better handled by tracking the number 03050 // of pending io's from usermode. 03051 // 03052 03053 if ( ThreadInformationLength != sizeof(ULONG) ) { 03054 return STATUS_INFO_LENGTH_MISMATCH; 03055 } 03056 03057 st = ObReferenceObjectByHandle( 03058 ThreadHandle, 03059 THREAD_QUERY_INFORMATION, 03060 PsThreadType, 03061 PreviousMode, 03062 (PVOID *)&Thread, 03063 NULL 03064 ); 03065 03066 if ( !NT_SUCCESS(st) ) { 03067 return st; 03068 } 03069 03070 // 03071 // Raise the IRQL so that the IrpList cannot be modified by a completion 03072 // APC. 03073 // 03074 03075 KeRaiseIrql( APC_LEVEL, &irql ); 03076 03077 IoPending = !IsListEmpty( &Thread->IrpList ); 03078 03079 KeLowerIrql( irql ); 03080 03081 ObDereferenceObject(Thread); 03082 03083 try { 03084 *(PULONG)ThreadInformation = IoPending ; 03085 03086 if (ARGUMENT_PRESENT(ReturnLength) ) { 03087 *ReturnLength = sizeof(ULONG); 03088 } 03089 } except(EXCEPTION_EXECUTE_HANDLER) { 03090 return GetExceptionCode(); 03091 } 03092 03093 return STATUS_SUCCESS ; 03094 03095 03096 default: 03097 return STATUS_INVALID_INFO_CLASS; 03098 } 03099 03100 }

NTSTATUS NtSetInformationProcess IN HANDLE  ProcessHandle,
IN PROCESSINFOCLASS  ProcessInformationClass,
IN PVOID  ProcessInformation,
IN ULONG  ProcessInformationLength
 

Definition at line 1510 of file psquery.c.

References C_ASSERT(), DebugPort, DirectoryHandle, ExAcquireResourceShared, ExAllocatePool, EXCEPTION_EXECUTE_HANDLER, ExFreePool(), ExReleaseResource, FALSE, IS_SYSTEM_THREAD, Ke386SetIOPL(), KeActiveProcessors, KeAttachProcess(), KeBoostPriorityThread(), KeDetachProcess(), KeEnterCriticalRegion, KeInitializeSpinLock(), KeLeaveCriticalRegion, KeReadStateProcess(), KernelMode, KeSetAffinityThread(), KeSetAutoAlignmentProcess(), KeSetDisableBoostThread(), KeSetPriorityProcess(), KPROCESSOR_MODE, LpcPortObjectType, MAX_WS_CATCH_INDEX, MEMORY_PRIORITY_BACKGROUND, MEMORY_PRIORITY_FOREGROUND, MmSetMemoryPriorityProcess(), NonPagedPool, NT_SUCCESS, NTSTATUS(), NULL, ObDereferenceObject, ObReferenceObjectByHandle(), ObSetDeviceMap(), PAGED_CODE, ProbeForRead, PsDereferencePrimaryToken, PsGetCurrentProcess, PsLockPollOnTimeout, PsLockProcess(), PsLockReturnTimeout, PsProcessPriorityBackground, PsProcessPriorityForeground, PsProcessType, PspSetLdtInformation(), PspSetLdtSize(), PspSetPrimaryToken(), PspSetProcessIoHandlers(), PspSetQuotaLimits(), PsReferencePrimaryToken(), PsSetProcessPriorityByClass(), PsUnlockProcess(), PsWatchEnabled, SeCheckPrivilegedObject(), SeIncreaseBasePriorityPrivilege, SeSetSessionIdToken(), SeSinglePrivilegeCheck(), SeTcbPrivilege, _ETHREAD::Tcb, _KTHREAD::Teb, Token, TRUE, and WS_CATCH_SIZE.

Referenced by CreateDAclToken(), LdrpInitializeProcess(), and TestTokenAssignPrimary().

01519 : 01520 01521 This function sets the state of a process object. 01522 01523 Arguments: 01524 01525 ProcessHandle - Supplies a handle to a process object. 01526 01527 ProcessInformationClass - Supplies the class of information being 01528 set. 01529 01530 ProcessInformation - Supplies a pointer to a record that contains the 01531 information to set. 01532 01533 ProcessInformationLength - Supplies the length of the record that contains 01534 the information to set. 01535 01536 Return Value: 01537 01538 TBS 01539 01540 --*/ 01541 01542 { 01543 01544 PEPROCESS Process; 01545 PETHREAD Thread; 01546 KPROCESSOR_MODE PreviousMode; 01547 NTSTATUS st; 01548 KPRIORITY BasePriority; 01549 ULONG BoostValue; 01550 ULONG DefaultHardErrorMode; 01551 PVOID DebugPort; 01552 PVOID ExceptionPort; 01553 HANDLE DebugPortHandle; 01554 BOOLEAN EnableAlignmentFaultFixup; 01555 HANDLE ExceptionPortHandle; 01556 ULONG ProbeAlignment; 01557 HANDLE PrimaryTokenHandle; 01558 BOOLEAN HasPrivilege = FALSE; 01559 BOOLEAN IsChildToken = FALSE; 01560 PLIST_ENTRY Next; 01561 UCHAR MemoryPriority; 01562 PROCESS_PRIORITY_CLASS LocalPriorityClass; 01563 PROCESS_FOREGROUND_BACKGROUND LocalForeground; 01564 HANDLE Wx86Info; 01565 KAFFINITY Affinity, AffinityWithMasks; 01566 ULONG_PTR BigAffinity; 01567 ULONG DisableBoost; 01568 BOOLEAN bDisableBoost; 01569 PPROCESS_DEVICEMAP_INFORMATION DeviceMapInfo; 01570 HANDLE DirectoryHandle; 01571 PROCESS_SESSION_INFORMATION SessionInfo; 01572 ULONG BytesCopied; 01573 PACCESS_TOKEN Token; 01574 01575 PAGED_CODE(); 01576 01577 // 01578 // Get previous processor mode and probe input argument if necessary. 01579 // 01580 01581 PreviousMode = KeGetPreviousMode(); 01582 if (PreviousMode != KernelMode) { 01583 01584 if (ProcessInformationClass == ProcessBasePriority) { 01585 ProbeAlignment = sizeof(KPRIORITY); 01586 01587 } else if (ProcessInformationClass == ProcessEnableAlignmentFaultFixup) { 01588 ProbeAlignment = sizeof(BOOLEAN); 01589 } else if (ProcessInformationClass == ProcessForegroundInformation) { 01590 ProbeAlignment = sizeof(PROCESS_FOREGROUND_BACKGROUND); 01591 } else if (ProcessInformationClass == ProcessPriorityClass) { 01592 ProbeAlignment = sizeof(BOOLEAN); 01593 } else if (ProcessInformationClass == ProcessAffinityMask) { 01594 ProbeAlignment = sizeof (ULONG_PTR); 01595 } else { 01596 ProbeAlignment = sizeof(ULONG); 01597 } 01598 01599 try { 01600 ProbeForRead( 01601 ProcessInformation, 01602 ProcessInformationLength, 01603 ProbeAlignment 01604 ); 01605 } except(EXCEPTION_EXECUTE_HANDLER) { 01606 return GetExceptionCode(); 01607 } 01608 } 01609 01610 // 01611 // Check argument validity. 01612 // 01613 01614 switch ( ProcessInformationClass ) { 01615 01616 case ProcessWorkingSetWatch: 01617 { 01618 PPAGEFAULT_HISTORY WorkingSetCatcher; 01619 01620 st = ObReferenceObjectByHandle( 01621 ProcessHandle, 01622 PROCESS_SET_INFORMATION, 01623 PsProcessType, 01624 PreviousMode, 01625 (PVOID *)&Process, 01626 NULL 01627 ); 01628 01629 if ( !NT_SUCCESS(st) ) { 01630 return st; 01631 } 01632 01633 WorkingSetCatcher = ExAllocatePool(NonPagedPool,WS_CATCH_SIZE); 01634 if ( !WorkingSetCatcher ) { 01635 ObDereferenceObject(Process); 01636 return STATUS_NO_MEMORY; 01637 } 01638 01639 PsWatchEnabled = TRUE; 01640 WorkingSetCatcher->CurrentIndex = 0; 01641 WorkingSetCatcher->MaxIndex = MAX_WS_CATCH_INDEX; 01642 01643 st = PsLockProcess(Process,PreviousMode,PsLockPollOnTimeout); 01644 01645 if ( st != STATUS_SUCCESS ) { 01646 ExFreePool(WorkingSetCatcher); 01647 ObDereferenceObject( Process ); 01648 return STATUS_PROCESS_IS_TERMINATING; 01649 } 01650 01651 if ( Process->WorkingSetWatch ) { 01652 PsUnlockProcess(Process); 01653 ExFreePool(WorkingSetCatcher); 01654 ObDereferenceObject(Process); 01655 return STATUS_PORT_ALREADY_SET; 01656 } 01657 01658 KeInitializeSpinLock(&WorkingSetCatcher->SpinLock); 01659 Process->WorkingSetWatch = WorkingSetCatcher; 01660 01661 PsUnlockProcess(Process); 01662 01663 ObDereferenceObject(Process); 01664 01665 return STATUS_SUCCESS; 01666 } 01667 01668 case ProcessBasePriority: 01669 { 01670 01671 01672 // 01673 // THIS ITEM CODE IS OBSOLETE ! 01674 // 01675 01676 if ( ProcessInformationLength != sizeof(KPRIORITY) ) { 01677 return STATUS_INFO_LENGTH_MISMATCH; 01678 } 01679 01680 try { 01681 BasePriority = *(KPRIORITY *)ProcessInformation; 01682 } except(EXCEPTION_EXECUTE_HANDLER) { 01683 return GetExceptionCode(); 01684 } 01685 01686 if ( BasePriority & 0x80000000 ) { 01687 MemoryPriority = MEMORY_PRIORITY_FOREGROUND; 01688 BasePriority &= ~0x80000000; 01689 } 01690 else { 01691 MemoryPriority = MEMORY_PRIORITY_BACKGROUND; 01692 } 01693 01694 if ( BasePriority > HIGH_PRIORITY || 01695 BasePriority <= LOW_PRIORITY ) { 01696 01697 return STATUS_INVALID_PARAMETER; 01698 } 01699 01700 st = ObReferenceObjectByHandle( 01701 ProcessHandle, 01702 PROCESS_SET_INFORMATION, 01703 PsProcessType, 01704 PreviousMode, 01705 (PVOID *)&Process, 01706 NULL 01707 ); 01708 01709 if ( !NT_SUCCESS(st) ) { 01710 return st; 01711 } 01712 01713 01714 if ( BasePriority > Process->Pcb.BasePriority ) { 01715 01716 // 01717 // Increasing the base priority of a process is a 01718 // privileged operation. Check for the privilege 01719 // here. 01720 // 01721 01722 HasPrivilege = SeCheckPrivilegedObject( 01723 SeIncreaseBasePriorityPrivilege, 01724 ProcessHandle, 01725 PROCESS_SET_INFORMATION, 01726 PreviousMode 01727 ); 01728 01729 if (!HasPrivilege) { 01730 01731 ObDereferenceObject(Process); 01732 return STATUS_PRIVILEGE_NOT_HELD; 01733 } 01734 } 01735 01736 KeSetPriorityProcess(&Process->Pcb,BasePriority); 01737 MmSetMemoryPriorityProcess(Process, MemoryPriority); 01738 ObDereferenceObject(Process); 01739 01740 return STATUS_SUCCESS; 01741 } 01742 01743 case ProcessPriorityClass: 01744 { 01745 if ( ProcessInformationLength != sizeof(PROCESS_PRIORITY_CLASS) ) { 01746 return STATUS_INFO_LENGTH_MISMATCH; 01747 } 01748 01749 try { 01750 LocalPriorityClass = *(PPROCESS_PRIORITY_CLASS)ProcessInformation; 01751 } except(EXCEPTION_EXECUTE_HANDLER) { 01752 return GetExceptionCode(); 01753 } 01754 01755 if ( LocalPriorityClass.PriorityClass > PROCESS_PRIORITY_CLASS_ABOVE_NORMAL ) { 01756 return STATUS_INVALID_PARAMETER; 01757 } 01758 01759 st = ObReferenceObjectByHandle( 01760 ProcessHandle, 01761 PROCESS_SET_INFORMATION, 01762 PsProcessType, 01763 PreviousMode, 01764 (PVOID *)&Process, 01765 NULL 01766 ); 01767 01768 if ( !NT_SUCCESS(st) ) { 01769 return st; 01770 } 01771 01772 01773 if ( LocalPriorityClass.PriorityClass != Process->PriorityClass && 01774 LocalPriorityClass.PriorityClass == PROCESS_PRIORITY_CLASS_REALTIME ) { 01775 01776 // 01777 // Increasing the base priority of a process is a 01778 // privileged operation. Check for the privilege 01779 // here. 01780 // 01781 01782 HasPrivilege = SeCheckPrivilegedObject( 01783 SeIncreaseBasePriorityPrivilege, 01784 ProcessHandle, 01785 PROCESS_SET_INFORMATION, 01786 PreviousMode 01787 ); 01788 01789 if (!HasPrivilege) { 01790 01791 ObDereferenceObject(Process); 01792 return STATUS_PRIVILEGE_NOT_HELD; 01793 } 01794 } 01795 01796 // 01797 // If the process has a job object, override whatever the process 01798 // is calling with with the value from the job object 01799 // 01800 if ( Process->Job ) { 01801 KeEnterCriticalRegion(); 01802 ExAcquireResourceShared(&Process->Job->JobLock, TRUE); 01803 01804 if ( Process->Job->LimitFlags & JOB_OBJECT_LIMIT_PRIORITY_CLASS ) { 01805 LocalPriorityClass.PriorityClass = Process->Job->PriorityClass; 01806 } 01807 01808 ExReleaseResource(&Process->Job->JobLock); 01809 KeLeaveCriticalRegion(); 01810 } 01811 01812 Process->PriorityClass = LocalPriorityClass.PriorityClass; 01813 01814 PsSetProcessPriorityByClass(Process, LocalPriorityClass.Foreground ? 01815 PsProcessPriorityForeground : PsProcessPriorityBackground); 01816 01817 ObDereferenceObject(Process); 01818 01819 return STATUS_SUCCESS; 01820 } 01821 01822 case ProcessForegroundInformation: 01823 { 01824 01825 if ( ProcessInformationLength != sizeof(PROCESS_FOREGROUND_BACKGROUND) ) { 01826 return STATUS_INFO_LENGTH_MISMATCH; 01827 } 01828 01829 try { 01830 LocalForeground = *(PPROCESS_FOREGROUND_BACKGROUND)ProcessInformation; 01831 } except(EXCEPTION_EXECUTE_HANDLER) { 01832 return GetExceptionCode(); 01833 } 01834 01835 st = ObReferenceObjectByHandle( 01836 ProcessHandle, 01837 PROCESS_SET_INFORMATION, 01838 PsProcessType, 01839 PreviousMode, 01840 (PVOID *)&Process, 01841 NULL 01842 ); 01843 01844 if ( !NT_SUCCESS(st) ) { 01845 return st; 01846 } 01847 01848 01849 PsSetProcessPriorityByClass(Process, LocalForeground.Foreground ? 01850 PsProcessPriorityForeground : PsProcessPriorityBackground); 01851 01852 ObDereferenceObject(Process); 01853 01854 return STATUS_SUCCESS; 01855 } 01856 01857 case ProcessRaisePriority: 01858 { 01859 // 01860 // This code is used to boost the priority of all threads 01861 // within a process. It cannot be used to change a thread into 01862 // a realtime class, or to lower the priority of a thread. The 01863 // argument is a boost value that is added to the base priority 01864 // of the specified process. 01865 // 01866 01867 01868 if ( ProcessInformationLength != sizeof(ULONG) ) { 01869 return STATUS_INFO_LENGTH_MISMATCH; 01870 } 01871 01872 try { 01873 BoostValue = *(PULONG)ProcessInformation; 01874 } except(EXCEPTION_EXECUTE_HANDLER) { 01875 return GetExceptionCode(); 01876 } 01877 01878 st = ObReferenceObjectByHandle( 01879 ProcessHandle, 01880 PROCESS_SET_INFORMATION, 01881 PsProcessType, 01882 PreviousMode, 01883 (PVOID *)&Process, 01884 NULL 01885 ); 01886 01887 if ( !NT_SUCCESS(st) ) { 01888 return st; 01889 } 01890 01891 // 01892 // Get the process create/delete lock and walk through the 01893 // thread list boosting each thread. 01894 // 01895 01896 01897 st = PsLockProcess(Process,KernelMode,PsLockReturnTimeout); 01898 01899 if ( st != STATUS_SUCCESS ) { 01900 ObDereferenceObject( Process ); 01901 return( st ); 01902 } 01903 01904 Next = Process->ThreadListHead.Flink; 01905 01906 while ( Next != &Process->ThreadListHead) { 01907 Thread = (PETHREAD)(CONTAINING_RECORD(Next,ETHREAD,ThreadListEntry)); 01908 KeBoostPriorityThread(&Thread->Tcb,(KPRIORITY)BoostValue); 01909 Next = Next->Flink; 01910 } 01911 01912 PsUnlockProcess(Process); 01913 01914 ObDereferenceObject(Process); 01915 01916 return STATUS_SUCCESS; 01917 } 01918 01919 case ProcessDefaultHardErrorMode: 01920 { 01921 if ( ProcessInformationLength != sizeof(ULONG) ) { 01922 return STATUS_INFO_LENGTH_MISMATCH; 01923 } 01924 01925 try { 01926 DefaultHardErrorMode = *(PULONG)ProcessInformation; 01927 } except(EXCEPTION_EXECUTE_HANDLER) { 01928 return GetExceptionCode(); 01929 } 01930 01931 st = ObReferenceObjectByHandle( 01932 ProcessHandle, 01933 PROCESS_SET_INFORMATION, 01934 PsProcessType, 01935 PreviousMode, 01936 (PVOID *)&Process, 01937 NULL 01938 ); 01939 01940 if ( !NT_SUCCESS(st) ) { 01941 return st; 01942 } 01943 01944 Process->DefaultHardErrorProcessing = DefaultHardErrorMode; 01945 if (DefaultHardErrorMode & PROCESS_HARDERROR_ALIGNMENT_BIT) { 01946 KeSetAutoAlignmentProcess(&Process->Pcb,TRUE); 01947 } 01948 else { 01949 KeSetAutoAlignmentProcess(&Process->Pcb,FALSE); 01950 } 01951 01952 ObDereferenceObject(Process); 01953 01954 return STATUS_SUCCESS; 01955 } 01956 01957 case ProcessQuotaLimits: 01958 { 01959 return PspSetQuotaLimits( 01960 ProcessHandle, 01961 ProcessInformationClass, 01962 ProcessInformation, 01963 ProcessInformationLength, 01964 PreviousMode 01965 ); 01966 } 01967 01968 case ProcessDebugPort : 01969 { 01970 if ( ProcessInformationLength != sizeof(HANDLE) ) { 01971 return STATUS_INFO_LENGTH_MISMATCH; 01972 } 01973 01974 try { 01975 DebugPortHandle = *(PHANDLE) ProcessInformation; 01976 } except(EXCEPTION_EXECUTE_HANDLER) { 01977 return GetExceptionCode(); 01978 } 01979 01980 if ( DebugPortHandle ) { 01981 st = ObReferenceObjectByHandle ( 01982 DebugPortHandle, 01983 0, 01984 LpcPortObjectType, 01985 PreviousMode, 01986 (PVOID *)&DebugPort, 01987 NULL 01988 ); 01989 if ( !NT_SUCCESS(st) ) { 01990 return st; 01991 } 01992 } else { 01993 return STATUS_INVALID_PARAMETER; 01994 } 01995 01996 st = ObReferenceObjectByHandle( 01997 ProcessHandle, 01998 PROCESS_SET_PORT, 01999 PsProcessType, 02000 PreviousMode, 02001 (PVOID *)&Process, 02002 NULL 02003 ); 02004 02005 if ( !NT_SUCCESS(st) ) { 02006 if ( DebugPort ) { 02007 ObDereferenceObject(DebugPort); 02008 } 02009 return st; 02010 } 02011 02012 02013 // 02014 // Conditional set Process->DebugPort 02015 // 02016 02017 if ( InterlockedCompareExchangePointer(&Process->DebugPort,DebugPort,NULL) == NULL ) { 02018 02019 if ( (Process->ExitTime.QuadPart != 0 || KeReadStateProcess(&Process->Pcb) != FALSE) ) { 02020 DebugPort = InterlockedExchangePointer(&Process->DebugPort,NULL); 02021 if ( DebugPort ) { 02022 ObDereferenceObject(DebugPort); 02023 } 02024 ObDereferenceObject( Process ); 02025 return STATUS_PROCESS_IS_TERMINATING; 02026 } 02027 } 02028 else { 02029 ObDereferenceObject(Process); 02030 ObDereferenceObject(DebugPort); 02031 return STATUS_PORT_ALREADY_SET; 02032 } 02033 02034 KeAttachProcess (&Process->Pcb); 02035 if (Process->Peb != NULL) { 02036 Process->Peb->BeingDebugged = (BOOLEAN)(Process->DebugPort != NULL ? TRUE : FALSE); 02037 #if defined(_WIN64) 02038 if (Process->Wow64Process != NULL) { 02039 PPEB32 Peb32 = (PPEB32)Process->Wow64Process->Wow64; 02040 if (Peb32 != NULL) { 02041 Peb32->BeingDebugged = Process->Peb->BeingDebugged; 02042 } 02043 } 02044 #endif 02045 } 02046 KeDetachProcess(); 02047 02048 02049 ObDereferenceObject(Process); 02050 02051 return STATUS_SUCCESS; 02052 } 02053 02054 case ProcessExceptionPort : 02055 { 02056 if ( ProcessInformationLength != sizeof(HANDLE) ) { 02057 return STATUS_INFO_LENGTH_MISMATCH; 02058 } 02059 02060 try { 02061 ExceptionPortHandle = *(PHANDLE) ProcessInformation; 02062 } except(EXCEPTION_EXECUTE_HANDLER) { 02063 return GetExceptionCode(); 02064 } 02065 02066 st = ObReferenceObjectByHandle ( 02067 ExceptionPortHandle, 02068 0, 02069 LpcPortObjectType, 02070 PreviousMode, 02071 (PVOID *)&ExceptionPort, 02072 NULL 02073 ); 02074 if ( !NT_SUCCESS(st) ) { 02075 return st; 02076 } 02077 02078 st = ObReferenceObjectByHandle( 02079 ProcessHandle, 02080 PROCESS_SET_PORT, 02081 PsProcessType, 02082 PreviousMode, 02083 (PVOID *)&Process, 02084 NULL 02085 ); 02086 02087 if ( !NT_SUCCESS(st) ) { 02088 ObDereferenceObject(ExceptionPort); 02089 return st; 02090 } 02091 02092 st = PsLockProcess(Process,PreviousMode,PsLockPollOnTimeout); 02093 02094 if ( st != STATUS_SUCCESS ) { 02095 ObDereferenceObject(ExceptionPort); 02096 ObDereferenceObject( Process ); 02097 return STATUS_PROCESS_IS_TERMINATING; 02098 } 02099 02100 if ( Process->ExceptionPort ) { 02101 ObDereferenceObject(Process); 02102 ObDereferenceObject(ExceptionPort); 02103 PsUnlockProcess(Process); 02104 return STATUS_PORT_ALREADY_SET; 02105 } else { 02106 Process->ExceptionPort = ExceptionPort; 02107 } 02108 PsUnlockProcess(Process); 02109 02110 ObDereferenceObject(Process); 02111 02112 return STATUS_SUCCESS; 02113 } 02114 02115 case ProcessAccessToken : 02116 { 02117 02118 if ( ProcessInformationLength != sizeof(PROCESS_ACCESS_TOKEN) ) { 02119 return STATUS_INFO_LENGTH_MISMATCH; 02120 } 02121 02122 try { 02123 PrimaryTokenHandle = ((PROCESS_ACCESS_TOKEN *)ProcessInformation)->Token; 02124 // OnlyThread field of this structure is obsolete. 02125 } except(EXCEPTION_EXECUTE_HANDLER) { 02126 return GetExceptionCode(); 02127 } 02128 02129 02130 st = PspSetPrimaryToken( 02131 ProcessHandle, 02132 PrimaryTokenHandle, 02133 NULL ); 02134 02135 return st; 02136 } 02137 02138 02139 case ProcessLdtInformation: 02140 02141 st = ObReferenceObjectByHandle( 02142 ProcessHandle, 02143 PROCESS_SET_INFORMATION | PROCESS_VM_WRITE, 02144 PsProcessType, 02145 PreviousMode, 02146 (PVOID *)&Process, 02147 NULL 02148 ); 02149 02150 if ( !NT_SUCCESS(st) ) { 02151 return st; 02152 } 02153 02154 try { 02155 st = PspSetLdtInformation( 02156 Process, 02157 ProcessInformation, 02158 ProcessInformationLength 02159 ); 02160 } except (EXCEPTION_EXECUTE_HANDLER) { 02161 st = STATUS_SUCCESS; 02162 } 02163 02164 ObDereferenceObject(Process); 02165 return st; 02166 02167 case ProcessLdtSize: 02168 02169 st = ObReferenceObjectByHandle( 02170 ProcessHandle, 02171 PROCESS_SET_INFORMATION | PROCESS_VM_WRITE, 02172 PsProcessType, 02173 PreviousMode, 02174 (PVOID *)&Process, 02175 NULL 02176 ); 02177 02178 if ( !NT_SUCCESS(st) ) { 02179 return st; 02180 } 02181 02182 try { 02183 02184 st = PspSetLdtSize( 02185 Process, 02186 ProcessInformation, 02187 ProcessInformationLength 02188 ); 02189 02190 } except(EXCEPTION_EXECUTE_HANDLER) { 02191 02192 st = GetExceptionCode(); 02193 02194 } 02195 02196 ObDereferenceObject(Process); 02197 return st; 02198 02199 case ProcessIoPortHandlers: 02200 02201 st = ObReferenceObjectByHandle( 02202 ProcessHandle, 02203 PROCESS_SET_INFORMATION, 02204 PsProcessType, 02205 PreviousMode, 02206 (PVOID *)&Process, 02207 NULL 02208 ); 02209 02210 if ( !NT_SUCCESS(st) ) { 02211 return st; 02212 } 02213 02214 st = PspSetProcessIoHandlers( 02215 Process, 02216 ProcessInformation, 02217 ProcessInformationLength 02218 ); 02219 02220 ObDereferenceObject(Process); 02221 return st; 02222 02223 case ProcessUserModeIOPL: 02224 02225 // 02226 // Must make sure the caller is a trusted subsystem with the 02227 // appropriate privilege level before executing this call. 02228 // If the calls returns FALSE we must return an error code. 02229 // 02230 02231 if (!SeSinglePrivilegeCheck(RtlConvertLongToLuid( 02232 SE_TCB_PRIVILEGE), 02233 PreviousMode )) { 02234 02235 return STATUS_PRIVILEGE_NOT_HELD; 02236 02237 } 02238 02239 st = ObReferenceObjectByHandle( 02240 ProcessHandle, 02241 PROCESS_SET_INFORMATION, 02242 PsProcessType, 02243 PreviousMode, 02244 (PVOID *)&Process, 02245 NULL 02246 ); 02247 02248 if ( NT_SUCCESS(st) ) { 02249 02250 #ifdef i386 02251 Ke386SetIOPL(&Process->Pcb); 02252 #endif 02253 02254 ObDereferenceObject(Process); 02255 } 02256 02257 return st; 02258 02259 // 02260 // Enable/disable auto-alignment fixup for a process and all its threads. 02261 // 02262 02263 case ProcessEnableAlignmentFaultFixup: 02264 02265 if ( ProcessInformationLength != sizeof(BOOLEAN) ) { 02266 return STATUS_INFO_LENGTH_MISMATCH; 02267 } 02268 02269 try { 02270 EnableAlignmentFaultFixup = *(PBOOLEAN)ProcessInformation; 02271 02272 } except(EXCEPTION_EXECUTE_HANDLER) { 02273 return GetExceptionCode(); 02274 } 02275 02276 st = ObReferenceObjectByHandle( 02277 ProcessHandle, 02278 PROCESS_SET_INFORMATION, 02279 PsProcessType, 02280 PreviousMode, 02281 (PVOID *)&Process, 02282 NULL 02283 ); 02284 02285 if ( !NT_SUCCESS(st) ) { 02286 return st; 02287 } 02288 02289 if ( EnableAlignmentFaultFixup ) { 02290 Process->DefaultHardErrorProcessing |= PROCESS_HARDERROR_ALIGNMENT_BIT; 02291 } 02292 else { 02293 Process->DefaultHardErrorProcessing &= ~PROCESS_HARDERROR_ALIGNMENT_BIT; 02294 } 02295 02296 KeSetAutoAlignmentProcess( &(Process->Pcb), EnableAlignmentFaultFixup ); 02297 ObDereferenceObject(Process); 02298 return STATUS_SUCCESS; 02299 02300 02301 #ifndef i386 02302 case ProcessWx86Information : 02303 if ( ProcessInformationLength != sizeof(HANDLE) ) { 02304 return STATUS_INFO_LENGTH_MISMATCH; 02305 } 02306 02307 try { 02308 Wx86Info = *(PHANDLE) ProcessInformation; 02309 } 02310 except(EXCEPTION_EXECUTE_HANDLER) { 02311 return GetExceptionCode(); 02312 } 02313 02314 st = ObReferenceObjectByHandle( 02315 ProcessHandle, 02316 PROCESS_SET_INFORMATION, 02317 PsProcessType, 02318 PreviousMode, 02319 (PVOID *)&Process, 02320 NULL 02321 ); 02322 02323 if (!NT_SUCCESS(st)) { 02324 return st; 02325 } 02326 02327 // 02328 // If Wx86Info == sizeof(WX86TIB) then process is becoming a wx86 process. 02329 // If Wx86Info == 0 then process is no longer a Wx86 process. 02330 // 02331 02332 if ((ULONG_PTR)Wx86Info != sizeof(WX86TIB)) { 02333 if ((ULONG_PTR)Wx86Info != 0 || Process != PsGetCurrentProcess()) { 02334 ObDereferenceObject( Process ); 02335 return STATUS_INVALID_PARAMETER; 02336 } 02337 02338 Wx86Info = NULL; 02339 } 02340 02341 02342 Process->VdmObjects = Wx86Info; 02343 02344 // 02345 // Clean out all of the x86 stacks, this allows dynamic wx86 02346 // to operate with less memory when wx86 is not loaded. 02347 // 02348 02349 if (Wx86Info == NULL) { 02350 NTSTATUS xst; 02351 PTEB Teb; 02352 PLIST_ENTRY Next; 02353 PWX86TIB Wx86Tib; 02354 PVOID BaseAddress; 02355 SIZE_T StackSize; 02356 02357 st = PsLockProcess(Process,PreviousMode,PsLockPollOnTimeout); 02358 if ( st != STATUS_SUCCESS ) { 02359 ObDereferenceObject(Process); 02360 return STATUS_PROCESS_IS_TERMINATING; 02361 } 02362 02363 Next = Process->ThreadListHead.Flink; 02364 02365 while ( Next != &Process->ThreadListHead) { 02366 02367 Thread = (PETHREAD)(CONTAINING_RECORD(Next,ETHREAD,ThreadListEntry)); 02368 if ( !IS_SYSTEM_THREAD(Thread) ) { 02369 if ( Thread->Tcb.Teb ) { 02370 Teb = (PTEB)Thread->Tcb.Teb; 02371 try { 02372 Wx86Tib = Teb->Vdm; 02373 Teb->Vdm = 0; 02374 ProbeForRead(Wx86Tib, sizeof(WX86TIB), sizeof(ULONG)); 02375 if (Wx86Tib && Wx86Tib->Size == sizeof(WX86TIB)) { 02376 StackSize = 0; 02377 BaseAddress = Wx86Tib->DeallocationStack; 02378 ZwFreeVirtualMemory(ProcessHandle, 02379 &BaseAddress, 02380 &StackSize, 02381 MEM_RELEASE 02382 ); 02383 02384 if (Teb->Wx86Thread.DeallocationCpu) { 02385 BaseAddress = Teb->Wx86Thread.DeallocationCpu; 02386 Teb->Wx86Thread.DeallocationCpu = 0; 02387 StackSize = 0; 02388 st = ZwFreeVirtualMemory(ProcessHandle, 02389 &BaseAddress, 02390 &StackSize, 02391 MEM_RELEASE 02392 ); 02393 } 02394 } 02395 } 02396 except(EXCEPTION_EXECUTE_HANDLER) { 02397 ; 02398 } 02399 } 02400 } 02401 Next = Next->Flink; 02402 } 02403 02404 PsUnlockProcess(Process); 02405 } 02406 02407 ObDereferenceObject(Process); 02408 return STATUS_SUCCESS; 02409 #endif 02410 02411 case ProcessAffinityMask: 02412 02413 #ifdef _WIN64 02414 if ( ProcessInformationLength != sizeof(ULONG_PTR) ) { 02415 // 02416 // Remove this ifdef when KAFFINITY is made 64 bits. 02417 // 02418 02419 C_ASSERT(sizeof(KAFFINITY) != sizeof(ULONG_PTR) ); 02420 return STATUS_INFO_LENGTH_MISMATCH; 02421 } 02422 #else 02423 if ( ProcessInformationLength != sizeof(KAFFINITY) ) { 02424 return STATUS_INFO_LENGTH_MISMATCH; 02425 } 02426 #endif 02427 02428 try { 02429 BigAffinity = *(PULONG_PTR)ProcessInformation; 02430 Affinity = (KAFFINITY)BigAffinity; 02431 02432 } 02433 except(EXCEPTION_EXECUTE_HANDLER) { 02434 return GetExceptionCode(); 02435 } 02436 02437 AffinityWithMasks = Affinity & KeActiveProcessors; 02438 02439 if ( !Affinity || ( AffinityWithMasks != Affinity ) ) { 02440 return STATUS_INVALID_PARAMETER; 02441 } 02442 02443 st = ObReferenceObjectByHandle( 02444 ProcessHandle, 02445 PROCESS_SET_INFORMATION, 02446 PsProcessType, 02447 PreviousMode, 02448 (PVOID *)&Process, 02449 NULL 02450 ); 02451 02452 if ( !NT_SUCCESS(st) ) { 02453 return st; 02454 } 02455 02456 // 02457 // If the process has a job object, override whatever the process 02458 // is calling with with the value from the job object 02459 // 02460 if ( Process->Job ) { 02461 KeEnterCriticalRegion(); 02462 ExAcquireResourceShared(&Process->Job->JobLock, TRUE); 02463 02464 if ( Process->Job->LimitFlags & JOB_OBJECT_LIMIT_AFFINITY ) { 02465 AffinityWithMasks = Process->Job->Affinity; 02466 } 02467 02468 ExReleaseResource(&Process->Job->JobLock); 02469 KeLeaveCriticalRegion(); 02470 } 02471 02472 02473 { 02474 NTSTATUS xst; 02475 PLIST_ENTRY Next; 02476 PETHREAD OriginalThread; 02477 02478 // 02479 // the following allows this api to properly if 02480 // called while the exiting process is blocked holding the 02481 // createdeletelock. This can happen during debugger/server 02482 // lpc transactions that occur in pspexitthread 02483 // 02484 02485 xst = PsLockProcess(Process,PreviousMode,PsLockPollOnTimeout); 02486 02487 if ( xst != STATUS_SUCCESS ) { 02488 ObDereferenceObject( Process ); 02489 return STATUS_PROCESS_IS_TERMINATING; 02490 } 02491 02492 Process->Pcb.Affinity = AffinityWithMasks; 02493 02494 Next = Process->ThreadListHead.Flink; 02495 02496 while ( Next != &Process->ThreadListHead) { 02497 02498 Thread = (PETHREAD)(CONTAINING_RECORD(Next,ETHREAD,ThreadListEntry)); 02499 KeSetAffinityThread(&Thread->Tcb,AffinityWithMasks); 02500 Next = Next->Flink; 02501 } 02502 02503 PsUnlockProcess(Process); 02504 } 02505 ObDereferenceObject(Process); 02506 return STATUS_SUCCESS; 02507 02508 case ProcessPriorityBoost: 02509 if ( ProcessInformationLength != sizeof(ULONG) ) { 02510 return STATUS_INFO_LENGTH_MISMATCH; 02511 } 02512 02513 try { 02514 DisableBoost = *(PULONG)ProcessInformation; 02515 } except(EXCEPTION_EXECUTE_HANDLER) { 02516 return GetExceptionCode(); 02517 } 02518 02519 bDisableBoost = (DisableBoost ? TRUE : FALSE); 02520 02521 st = ObReferenceObjectByHandle( 02522 ProcessHandle, 02523 PROCESS_SET_INFORMATION, 02524 PsProcessType, 02525 PreviousMode, 02526 (PVOID *)&Process, 02527 NULL 02528 ); 02529 02530 if ( !NT_SUCCESS(st) ) { 02531 return st; 02532 } 02533 02534 { 02535 NTSTATUS xst; 02536 PLIST_ENTRY Next; 02537 PETHREAD OriginalThread; 02538 02539 // 02540 // the following allows this api to properly if 02541 // called while the exiting process is blocked holding the 02542 // createdeletelock. This can happen during debugger/server 02543 // lpc transactions that occur in pspexitthread 02544 // 02545 02546 xst = PsLockProcess(Process,PreviousMode,PsLockPollOnTimeout); 02547 02548 if ( xst != STATUS_SUCCESS ) { 02549 ObDereferenceObject( Process ); 02550 return STATUS_PROCESS_IS_TERMINATING; 02551 } 02552 02553 Process->Pcb.DisableBoost = bDisableBoost; 02554 02555 Next = Process->ThreadListHead.Flink; 02556 02557 while ( Next != &Process->ThreadListHead) { 02558 02559 Thread = (PETHREAD)(CONTAINING_RECORD(Next,ETHREAD,ThreadListEntry)); 02560 KeSetDisableBoostThread(&Thread->Tcb,bDisableBoost); 02561 Next = Next->Flink; 02562 } 02563 02564 PsUnlockProcess(Process); 02565 } 02566 ObDereferenceObject(Process); 02567 return STATUS_SUCCESS; 02568 02569 case ProcessDeviceMap: 02570 DeviceMapInfo = (PPROCESS_DEVICEMAP_INFORMATION)ProcessInformation; 02571 if ( ProcessInformationLength != sizeof(DeviceMapInfo->Set) ) { 02572 return STATUS_INFO_LENGTH_MISMATCH; 02573 } 02574 02575 try { 02576 DirectoryHandle = DeviceMapInfo->Set.DirectoryHandle; 02577 } except(EXCEPTION_EXECUTE_HANDLER) { 02578 return GetExceptionCode(); 02579 } 02580 02581 st = ObReferenceObjectByHandle( 02582 ProcessHandle, 02583 PROCESS_SET_INFORMATION, 02584 PsProcessType, 02585 PreviousMode, 02586 (PVOID *)&Process, 02587 NULL 02588 ); 02589 02590 if ( !NT_SUCCESS(st) ) { 02591 return st; 02592 } 02593 02594 // 02595 // the following allows this api to properly if 02596 // called while the exiting process is blocked holding the 02597 // createdeletelock. This can happen during debugger/server 02598 // lpc transactions that occur in pspexitthread 02599 // 02600 02601 st = PsLockProcess(Process,PreviousMode,PsLockPollOnTimeout); 02602 02603 if ( st != STATUS_SUCCESS ) { 02604 ObDereferenceObject( Process ); 02605 return STATUS_PROCESS_IS_TERMINATING; 02606 } 02607 02608 st = ObSetDeviceMap( Process, DirectoryHandle ); 02609 PsUnlockProcess(Process); 02610 ObDereferenceObject(Process); 02611 return st; 02612 02613 case ProcessSessionInformation : 02614 02615 // 02616 // Update Multi-User session specific process information 02617 // 02618 if ( ProcessInformationLength != (ULONG) sizeof(PROCESS_SESSION_INFORMATION) ) { 02619 return STATUS_INFO_LENGTH_MISMATCH; 02620 } 02621 02622 try { 02623 SessionInfo = *(PPROCESS_SESSION_INFORMATION) ProcessInformation; 02624 } except(EXCEPTION_EXECUTE_HANDLER) { 02625 return GetExceptionCode(); 02626 } 02627 02628 // 02629 // We only allow TCB to set SessionId's 02630 // 02631 if ( !SeSinglePrivilegeCheck(SeTcbPrivilege,PreviousMode) ) { 02632 return( STATUS_PRIVILEGE_NOT_HELD ); 02633 } 02634 02635 // 02636 // Reference process object 02637 // 02638 st = ObReferenceObjectByHandle( 02639 ProcessHandle, 02640 PROCESS_SET_INFORMATION | PROCESS_SET_SESSIONID, 02641 PsProcessType, 02642 PreviousMode, 02643 (PVOID *)&Process, 02644 NULL 02645 ); 02646 if ( !NT_SUCCESS(st) ) { 02647 return st; 02648 } 02649 02650 02651 02652 // 02653 // Update SessionId in the Token 02654 // 02655 02656 Token = PsReferencePrimaryToken( Process ); 02657 SeSetSessionIdToken( Token, SessionInfo.SessionId ); 02658 PsDereferencePrimaryToken( Token ); 02659 02660 02661 02662 // 02663 // Update process SessionId 02664 // 02665 Process->SessionId = SessionInfo.SessionId; 02666 02667 02668 st = PsLockProcess(Process,PreviousMode,PsLockPollOnTimeout); 02669 02670 if ( st != STATUS_SUCCESS ) { 02671 ObDereferenceObject(Process); 02672 return STATUS_PROCESS_IS_TERMINATING; 02673 } 02674 02675 // 02676 // Check if the Peb is NULL . System processes don't have a PEB 02677 // 02678 if (Process->Peb != NULL) { 02679 02680 02681 KeAttachProcess (&Process->Pcb); 02682 02683 // 02684 // Update SessionId in PEB 02685 // 02686 02687 Process->Peb->SessionId = Process->SessionId; 02688 02689 KeDetachProcess(); 02690 02691 } 02692 02693 PsUnlockProcess(Process); 02694 ObDereferenceObject(Process); 02695 02696 return( st ); 02697 02698 default: 02699 return STATUS_INVALID_INFO_CLASS; 02700 } 02701 02702 }

NTSTATUS NtSetInformationThread IN HANDLE  ThreadHandle,
IN THREADINFOCLASS  ThreadInformationClass,
IN PVOID  ThreadInformation,
IN ULONG  ThreadInformationLength
 

Definition at line 3103 of file psquery.c.

References _KPROCESS::Affinity, EXCEPTION_EXECUTE_HANDLER, ExpDefaultErrorPortProcess, FALSE, IS_SYSTEM_THREAD, _EPROCESS::Job, KernelMode, KeSetAffinityThread(), KeSetAutoAlignmentThread(), KeSetBasePriorityThread(), KeSetDisableBoostThread(), KeSetIdealProcessorThread(), KeSetPriorityThread(), KPROCESSOR_MODE, _EJOB::LimitFlags, MAXIMUM_PROCESSORS, NT_SUCCESS, NTSTATUS(), NULL, ObDereferenceObject, ObReferenceObjectByHandle(), PAGED_CODE, _EPROCESS::Pcb, PEEVENT_PAIR, _EPROCESS::PriorityClass, ProbeAndReadLong, ProbeAndWriteLong, ProbeForRead, PsAssignImpersonationToken(), PsGetCurrentProcess, PsGetCurrentThread, PsLockPollOnTimeout, PsLockProcess(), PsThreadType, PsUnlockProcess(), SeCheckPrivilegedObject(), SeIncreaseBasePriorityPrivilege, THREAD_TO_PROCESS, ThreadHandle, _EPROCESS::ThreadListHead, TRUE, and _EPROCESS::Wow64Process.

Referenced by CreateDAclToken(), InternalCreateCallbackThread(), MemPrintWriteThread(), NotificationThread(), RtlImpersonateSelf(), RtlQueryProcessDebugInformation(), SepServerRevertToSelf(), TestTokenImpersonation(), W32WinStationDoConnect(), and WinStationAPIInit().

03112 : 03113 03114 This function sets the state of a thread object. 03115 03116 Arguments: 03117 03118 ThreadHandle - Supplies a handle to a thread object. 03119 03120 ThreadInformationClass - Supplies the class of information being 03121 set. 03122 03123 ThreadInformation - Supplies a pointer to a record that contains the 03124 information to set. 03125 03126 ThreadInformationLength - Supplies the length of the record that contains 03127 the information to set. 03128 03129 Return Value: 03130 03131 TBS 03132 03133 --*/ 03134 03135 { 03136 PEEVENT_PAIR EventPair; 03137 HANDLE EventPairHandle; 03138 PETHREAD Thread; 03139 PEPROCESS Process; 03140 KPROCESSOR_MODE PreviousMode; 03141 NTSTATUS st; 03142 KAFFINITY Affinity, AffinityWithMasks; 03143 ULONG_PTR BigAffinity; 03144 KPRIORITY Priority; 03145 LONG BasePriority; 03146 ULONG TlsIndex; 03147 PVOID TlsArrayAddress; 03148 PVOID Win32StartAddressValue; 03149 ULONG ProbeAlignment; 03150 BOOLEAN EnableAlignmentFaultFixup; 03151 ULONG IdealProcessor; 03152 ULONG DisableBoost; 03153 PVOID *ExpansionSlots; 03154 HANDLE ImpersonationTokenHandle; 03155 BOOLEAN HasPrivilege; 03156 03157 PAGED_CODE(); 03158 03159 // 03160 // Get previous processor mode and probe input argument if necessary. 03161 // 03162 03163 PreviousMode = KeGetPreviousMode(); 03164 if (PreviousMode != KernelMode) { 03165 try { 03166 03167 switch (ThreadInformationClass) { 03168 03169 case ThreadPriority : 03170 ProbeAlignment = sizeof(KPRIORITY); 03171 break; 03172 case ThreadAffinityMask : 03173 case ThreadQuerySetWin32StartAddress : 03174 ProbeAlignment = sizeof (ULONG_PTR); 03175 break; 03176 case ThreadEnableAlignmentFaultFixup : 03177 ProbeAlignment = sizeof (BOOLEAN); 03178 break; 03179 default : 03180 ProbeAlignment = sizeof(ULONG); 03181 } 03182 03183 ProbeForRead( 03184 ThreadInformation, 03185 ThreadInformationLength, 03186 ProbeAlignment 03187 ); 03188 } except(EXCEPTION_EXECUTE_HANDLER) { 03189 return GetExceptionCode(); 03190 } 03191 } 03192 03193 // 03194 // Check argument validity. 03195 // 03196 03197 switch ( ThreadInformationClass ) { 03198 03199 case ThreadPriority: 03200 03201 if ( ThreadInformationLength != sizeof(KPRIORITY) ) { 03202 return STATUS_INFO_LENGTH_MISMATCH; 03203 } 03204 03205 try { 03206 Priority = *(KPRIORITY *)ThreadInformation; 03207 } except(EXCEPTION_EXECUTE_HANDLER) { 03208 return GetExceptionCode(); 03209 } 03210 03211 if ( Priority > HIGH_PRIORITY || 03212 Priority <= LOW_PRIORITY ) { 03213 03214 return STATUS_INVALID_PARAMETER; 03215 } 03216 03217 if ( Priority >= LOW_REALTIME_PRIORITY ) { 03218 03219 // 03220 // Increasing the priority of a thread beyond 03221 // LOW_REALTIME_PRIORITY is a privileged operation. 03222 // 03223 03224 HasPrivilege = SeCheckPrivilegedObject( 03225 SeIncreaseBasePriorityPrivilege, 03226 ThreadHandle, 03227 THREAD_SET_INFORMATION, 03228 PreviousMode 03229 ); 03230 03231 if (!HasPrivilege) { 03232 return STATUS_PRIVILEGE_NOT_HELD; 03233 } 03234 } 03235 03236 st = ObReferenceObjectByHandle( 03237 ThreadHandle, 03238 THREAD_SET_INFORMATION, 03239 PsThreadType, 03240 PreviousMode, 03241 (PVOID *)&Thread, 03242 NULL 03243 ); 03244 03245 if ( !NT_SUCCESS(st) ) { 03246 return st; 03247 } 03248 03249 Process = THREAD_TO_PROCESS(Thread); 03250 03251 KeSetPriorityThread(&Thread->Tcb,Priority); 03252 03253 ObDereferenceObject(Thread); 03254 03255 return STATUS_SUCCESS; 03256 03257 case ThreadBasePriority: 03258 03259 if ( ThreadInformationLength != sizeof(LONG) ) { 03260 return STATUS_INFO_LENGTH_MISMATCH; 03261 } 03262 03263 try { 03264 BasePriority = *(PLONG)ThreadInformation; 03265 } except(EXCEPTION_EXECUTE_HANDLER) { 03266 return GetExceptionCode(); 03267 } 03268 03269 st = ObReferenceObjectByHandle( 03270 ThreadHandle, 03271 THREAD_SET_INFORMATION, 03272 PsThreadType, 03273 PreviousMode, 03274 (PVOID *)&Thread, 03275 NULL 03276 ); 03277 03278 if ( !NT_SUCCESS(st) ) { 03279 return st; 03280 } 03281 Process = THREAD_TO_PROCESS(Thread); 03282 03283 03284 if ( BasePriority > THREAD_BASE_PRIORITY_MAX || 03285 BasePriority < THREAD_BASE_PRIORITY_MIN ) { 03286 if ( BasePriority == THREAD_BASE_PRIORITY_LOWRT+1 || 03287 BasePriority == THREAD_BASE_PRIORITY_IDLE-1 ) { 03288 ; 03289 } 03290 else { 03291 03292 // 03293 // Allow csrss, or realtime processes to select any 03294 // priority 03295 // 03296 03297 if ( PsGetCurrentProcess() == ExpDefaultErrorPortProcess || 03298 Process->PriorityClass == PROCESS_PRIORITY_CLASS_REALTIME ){ 03299 ; 03300 } 03301 else { 03302 ObDereferenceObject(Thread); 03303 return STATUS_INVALID_PARAMETER; 03304 } 03305 } 03306 } 03307 03308 // 03309 // If the thread is running within a job object, and the job 03310 // object has a priority class limit, do not allow 03311 // priority adjustments that raise the thread's priority, unless 03312 // the priority class is realtime 03313 // 03314 03315 if ( Process->Job && (Process->Job->LimitFlags & JOB_OBJECT_LIMIT_PRIORITY_CLASS) ) { 03316 if ( Process->PriorityClass != PROCESS_PRIORITY_CLASS_REALTIME ){ 03317 if ( BasePriority > 0 ) { 03318 ObDereferenceObject(Thread); 03319 return STATUS_SUCCESS; 03320 } 03321 } 03322 } 03323 03324 KeSetBasePriorityThread(&Thread->Tcb,BasePriority); 03325 03326 ObDereferenceObject(Thread); 03327 03328 return STATUS_SUCCESS; 03329 03330 case ThreadEnableAlignmentFaultFixup: 03331 03332 if ( ThreadInformationLength != sizeof(BOOLEAN) ) { 03333 return STATUS_INFO_LENGTH_MISMATCH; 03334 } 03335 03336 try { 03337 EnableAlignmentFaultFixup = *(PBOOLEAN)ThreadInformation; 03338 } except(EXCEPTION_EXECUTE_HANDLER) { 03339 return GetExceptionCode(); 03340 } 03341 03342 st = ObReferenceObjectByHandle( 03343 ThreadHandle, 03344 THREAD_SET_INFORMATION, 03345 PsThreadType, 03346 PreviousMode, 03347 (PVOID *)&Thread, 03348 NULL 03349 ); 03350 03351 if ( !NT_SUCCESS(st) ) { 03352 return st; 03353 } 03354 03355 KeSetAutoAlignmentThread( &(Thread->Tcb), EnableAlignmentFaultFixup ); 03356 03357 ObDereferenceObject(Thread); 03358 03359 return STATUS_SUCCESS; 03360 03361 case ThreadAffinityMask: 03362 03363 if ( ThreadInformationLength != sizeof(ULONG_PTR) ) { 03364 return STATUS_INFO_LENGTH_MISMATCH; 03365 } 03366 03367 try { 03368 BigAffinity = *(ULONG_PTR *) ThreadInformation; 03369 Affinity = (KAFFINITY) BigAffinity; 03370 } except(EXCEPTION_EXECUTE_HANDLER) { 03371 return GetExceptionCode(); 03372 } 03373 03374 if ( !Affinity ) { 03375 03376 return STATUS_INVALID_PARAMETER; 03377 03378 } 03379 03380 st = ObReferenceObjectByHandle( 03381 ThreadHandle, 03382 THREAD_SET_INFORMATION, 03383 PsThreadType, 03384 PreviousMode, 03385 (PVOID *)&Thread, 03386 NULL 03387 ); 03388 03389 if ( !NT_SUCCESS(st) ) { 03390 return st; 03391 } 03392 03393 Process = THREAD_TO_PROCESS(Thread); 03394 03395 // 03396 // the following allows this api to properly if 03397 // called while the exiting process is blocked holding the 03398 // createdeletelock. This can happen during debugger/server 03399 // lpc transactions that occur in pspexitthread 03400 // 03401 03402 st = PsLockProcess(Process,PreviousMode,PsLockPollOnTimeout); 03403 03404 if ( st != STATUS_SUCCESS ) { 03405 ObDereferenceObject(Thread); 03406 return STATUS_PROCESS_IS_TERMINATING; 03407 } 03408 03409 AffinityWithMasks = Affinity & Process->Pcb.Affinity; 03410 03411 if ( AffinityWithMasks != Affinity ) { 03412 03413 st = STATUS_INVALID_PARAMETER; 03414 03415 } else { 03416 03417 KeSetAffinityThread( 03418 &Thread->Tcb, 03419 AffinityWithMasks 03420 ); 03421 st = STATUS_SUCCESS; 03422 } 03423 03424 PsUnlockProcess(Process); 03425 03426 ObDereferenceObject(Thread); 03427 03428 return st; 03429 03430 case ThreadImpersonationToken: 03431 03432 03433 if ( ThreadInformationLength != sizeof(HANDLE) ) { 03434 return STATUS_INFO_LENGTH_MISMATCH; 03435 } 03436 03437 03438 try { 03439 ImpersonationTokenHandle = *(PHANDLE) ThreadInformation; 03440 } except(EXCEPTION_EXECUTE_HANDLER) { 03441 return GetExceptionCode(); 03442 } 03443 03444 03445 st = ObReferenceObjectByHandle( 03446 ThreadHandle, 03447 THREAD_SET_THREAD_TOKEN, 03448 PsThreadType, 03449 PreviousMode, 03450 (PVOID *)&Thread, 03451 NULL 03452 ); 03453 03454 if ( !NT_SUCCESS(st) ) { 03455 return st; 03456 } 03457 03458 // 03459 // Check for proper access to (and type of) the token, and assign 03460 // it as the thread's impersonation token. 03461 // 03462 03463 st = PsAssignImpersonationToken( Thread, ImpersonationTokenHandle ); 03464 03465 03466 ObDereferenceObject(Thread); 03467 03468 return st; 03469 03470 case ThreadQuerySetWin32StartAddress: 03471 if ( ThreadInformationLength != sizeof(ULONG_PTR) ) { 03472 return STATUS_INFO_LENGTH_MISMATCH; 03473 } 03474 03475 03476 try { 03477 Win32StartAddressValue = *(PVOID *) ThreadInformation; 03478 } except(EXCEPTION_EXECUTE_HANDLER) { 03479 return GetExceptionCode(); 03480 } 03481 03482 03483 st = ObReferenceObjectByHandle( 03484 ThreadHandle, 03485 THREAD_SET_INFORMATION, 03486 PsThreadType, 03487 PreviousMode, 03488 (PVOID *)&Thread, 03489 NULL 03490 ); 03491 03492 if ( !NT_SUCCESS(st) ) { 03493 return st; 03494 } 03495 03496 Thread->Win32StartAddress = (PVOID)Win32StartAddressValue; 03497 ObDereferenceObject(Thread); 03498 03499 return st; 03500 03501 03502 case ThreadIdealProcessor: 03503 03504 if ( ThreadInformationLength != sizeof(ULONG) ) { 03505 return STATUS_INFO_LENGTH_MISMATCH; 03506 } 03507 03508 03509 try { 03510 IdealProcessor = *(PULONG)ThreadInformation; 03511 } except(EXCEPTION_EXECUTE_HANDLER) { 03512 return GetExceptionCode(); 03513 } 03514 03515 if ( IdealProcessor > MAXIMUM_PROCESSORS ) { 03516 return STATUS_INVALID_PARAMETER; 03517 } 03518 03519 st = ObReferenceObjectByHandle( 03520 ThreadHandle, 03521 THREAD_SET_INFORMATION, 03522 PsThreadType, 03523 PreviousMode, 03524 (PVOID *)&Thread, 03525 NULL 03526 ); 03527 03528 if ( !NT_SUCCESS(st) ) { 03529 return st; 03530 } 03531 03532 // 03533 // this is sort of a slimey way of returning info from this set only 03534 // api 03535 // 03536 03537 st = (NTSTATUS)KeSetIdealProcessorThread(&Thread->Tcb,(CCHAR)IdealProcessor); 03538 03539 ObDereferenceObject(Thread); 03540 03541 return st; 03542 03543 03544 case ThreadPriorityBoost: 03545 if ( ThreadInformationLength != sizeof(ULONG) ) { 03546 return STATUS_INFO_LENGTH_MISMATCH; 03547 } 03548 03549 try { 03550 DisableBoost = *(PULONG)ThreadInformation; 03551 } except(EXCEPTION_EXECUTE_HANDLER) { 03552 return GetExceptionCode(); 03553 } 03554 03555 st = ObReferenceObjectByHandle( 03556 ThreadHandle, 03557 THREAD_SET_INFORMATION, 03558 PsThreadType, 03559 PreviousMode, 03560 (PVOID *)&Thread, 03561 NULL 03562 ); 03563 03564 if ( !NT_SUCCESS(st) ) { 03565 return st; 03566 } 03567 03568 KeSetDisableBoostThread(&Thread->Tcb,DisableBoost ? TRUE : FALSE); 03569 03570 ObDereferenceObject(Thread); 03571 03572 return st; 03573 03574 case ThreadZeroTlsCell: 03575 if ( ThreadInformationLength != sizeof(ULONG) ) { 03576 return STATUS_INFO_LENGTH_MISMATCH; 03577 } 03578 03579 03580 try { 03581 TlsIndex = *(PULONG) ThreadInformation; 03582 } except(EXCEPTION_EXECUTE_HANDLER) { 03583 return GetExceptionCode(); 03584 } 03585 03586 st = ObReferenceObjectByHandle( 03587 ThreadHandle, 03588 THREAD_SET_INFORMATION, 03589 PsThreadType, 03590 PreviousMode, 03591 (PVOID *)&Thread, 03592 NULL 03593 ); 03594 03595 if ( !NT_SUCCESS(st) ) { 03596 return st; 03597 } 03598 03599 if ( Thread != PsGetCurrentThread() ) { 03600 ObDereferenceObject( Thread ); 03601 return STATUS_INVALID_PARAMETER; 03602 } 03603 { 03604 NTSTATUS xst; 03605 PTEB Teb; 03606 PLIST_ENTRY Next; 03607 PETHREAD OriginalThread; 03608 03609 OriginalThread = Thread; 03610 03611 Process = THREAD_TO_PROCESS(Thread); 03612 03613 // 03614 // the following allows this api to properly if 03615 // called while the exiting process is blocked holding the 03616 // createdeletelock. This can happen during debugger/server 03617 // lpc transactions that occur in pspexitthread 03618 // 03619 03620 xst = PsLockProcess(Process,PreviousMode,PsLockPollOnTimeout); 03621 03622 if ( xst != STATUS_SUCCESS ) { 03623 ObDereferenceObject( OriginalThread ); 03624 return STATUS_PROCESS_IS_TERMINATING; 03625 } 03626 03627 // The 32bit TEB needs to be set if this is a WOW64 process on a 64BIT system. 03628 // This code isn't 100% correct since threads have a conversion state where they 03629 // are chaning from 64 to 32 and they don't have a TEB32 yet. Fortunatly, the slots 03630 // will be zero when the thread is created so no damage is done by not clearing it here. 03631 03632 // Note that the test for the process type is inside the inner loop. This 03633 // is bad programming, but this function is hardly time constrained and 03634 // fixing this with complex macros would not be worth it due to the loss of clairity. 03635 03636 Next = Process->ThreadListHead.Flink; 03637 03638 while ( Next != &Process->ThreadListHead) { 03639 03640 Thread = (PETHREAD)(CONTAINING_RECORD(Next,ETHREAD,ThreadListEntry)); 03641 if ( !IS_SYSTEM_THREAD(Thread) ) { 03642 if ( Thread->Tcb.Teb ) { 03643 Teb = (PTEB)Thread->Tcb.Teb; 03644 03645 if ( TlsIndex > TLS_MINIMUM_AVAILABLE-1 ) { 03646 if ( TlsIndex < (TLS_MINIMUM_AVAILABLE+TLS_EXPANSION_SLOTS) - 1 ) { 03647 // 03648 // This is an expansion slot, so see if the thread 03649 // has an expansion cell 03650 // 03651 try { 03652 #if defined(_WIN64) 03653 if (Process->Wow64Process) { //Wow64 process. 03654 PTEB32 Teb32; 03655 PLONG ExpansionSlots32; 03656 03657 Teb32 = WOW64_GET_TEB32(Teb); //No probing needed on regular TEB. 03658 if (Teb32) { 03659 ExpansionSlots32 = ULongToPtr(ProbeAndReadLong(&(Teb32->TlsExpansionSlots))); 03660 if (ExpansionSlots32) { 03661 ProbeAndWriteLong(ExpansionSlots32 + TlsIndex - TLS_MINIMUM_AVAILABLE, 0); 03662 } 03663 } 03664 } 03665 else 03666 #endif 03667 { 03668 ExpansionSlots = Teb->TlsExpansionSlots; 03669 ProbeForRead(ExpansionSlots,TLS_EXPANSION_SLOTS*4,8); 03670 if ( ExpansionSlots ) { 03671 ExpansionSlots[TlsIndex-TLS_MINIMUM_AVAILABLE] = 0; 03672 } 03673 03674 } 03675 } 03676 except(EXCEPTION_EXECUTE_HANDLER) { 03677 ; 03678 } 03679 } 03680 } 03681 else { 03682 try { 03683 #if defined(_WIN64) 03684 if (Process->Wow64Process) { //wow64 process 03685 PTEB32 Teb32; 03686 03687 Teb32 = WOW64_GET_TEB32(Teb); //No probing needed on regular TEB. 03688 if(Teb32) { 03689 ProbeAndWriteLong(Teb32->TlsSlots + TlsIndex, 0); 03690 } 03691 } 03692 else 03693 #endif 03694 { 03695 Teb->TlsSlots[TlsIndex] = NULL; 03696 } 03697 } 03698 except(EXCEPTION_EXECUTE_HANDLER) { 03699 ; 03700 } 03701 } 03702 03703 } 03704 } 03705 Next = Next->Flink; 03706 } 03707 03708 PsUnlockProcess(Process); 03709 03710 ObDereferenceObject(OriginalThread); 03711 03712 } 03713 return st; 03714 break; 03715 03716 case ThreadSetTlsArrayAddress: 03717 if ( ThreadInformationLength != sizeof(PVOID) ) { 03718 return STATUS_INFO_LENGTH_MISMATCH; 03719 } 03720 03721 03722 try { 03723 TlsArrayAddress = *(PVOID *)ThreadInformation; 03724 } except(EXCEPTION_EXECUTE_HANDLER) { 03725 return GetExceptionCode(); 03726 } 03727 03728 st = ObReferenceObjectByHandle( 03729 ThreadHandle, 03730 THREAD_SET_INFORMATION, 03731 PsThreadType, 03732 PreviousMode, 03733 (PVOID *)&Thread, 03734 NULL 03735 ); 03736 03737 if ( !NT_SUCCESS(st) ) { 03738 return st; 03739 } 03740 03741 Thread->Tcb.TlsArray = TlsArrayAddress; 03742 03743 #if defined(_MIPS_) 03744 03745 if (Thread == PsGetCurrentThread()) { 03746 PCR->TlsArray = TlsArrayAddress; 03747 } 03748 03749 #endif 03750 03751 ObDereferenceObject(Thread); 03752 03753 return st; 03754 break; 03755 03756 case ThreadHideFromDebugger: 03757 if ( ThreadInformationLength != 0 ) { 03758 return STATUS_INFO_LENGTH_MISMATCH; 03759 } 03760 03761 st = ObReferenceObjectByHandle( 03762 ThreadHandle, 03763 THREAD_SET_INFORMATION, 03764 PsThreadType, 03765 PreviousMode, 03766 (PVOID *)&Thread, 03767 NULL 03768 ); 03769 03770 if ( !NT_SUCCESS(st) ) { 03771 return st; 03772 } 03773 03774 Thread->HideFromDebugger = TRUE; 03775 03776 ObDereferenceObject(Thread); 03777 03778 return st; 03779 break; 03780 03781 default: 03782 return STATUS_INVALID_INFO_CLASS; 03783 } 03784 }

NTSTATUS PsConvertToGuiThread VOID   ) 
 

Definition at line 3964 of file psquery.c.

References ASSERT, FALSE, KernelMode, KeServiceDescriptorTable, KeServiceDescriptorTableShadow, KeSwitchKernelStack(), _KTHREAD::LargeStack, MmCreateKernelStack(), MmDeleteKernelStack(), NT_SUCCESS, NTSTATUS(), PAGED_CODE, PERFINFO_CONVERT_TO_GUI_THREAD, PsGetCurrentProcess, PsGetCurrentThread, PspW32ProcessCallout, PspW32ThreadCallout, PsW32ThreadCalloutInitialize, _KTHREAD::ServiceTable, Status, _ETHREAD::Tcb, TRUE, and _KTHREAD::Win32Thread.

03970 : 03971 03972 This function converts a thread to a GUI thread. This involves giving the 03973 thread a larger variable sized stack, and allocating appropriate w32 03974 thread and process objects. 03975 03976 Arguments: 03977 03978 None. 03979 03980 Environment: 03981 03982 On x86 this function needs to build an EBP frame. The function 03983 KeSwitchKernelStack depends on this fact. The '#pragma optimize 03984 ("y",off)' below disables frame pointer omission for all builds. 03985 Note that this modification to the optimizations being 03986 performed is from this point in the source module below. 03987 03988 Return Value: 03989 03990 TBD 03991 03992 --*/ 03993 03994 #if defined(i386) 03995 #pragma optimize ("y",off) 03996 #endif 03997 03998 { 03999 PVOID NewStack; 04000 PVOID OldStack; 04001 PETHREAD Thread; 04002 PEPROCESS Process; 04003 NTSTATUS Status; 04004 04005 PAGED_CODE(); 04006 04007 if (KeGetPreviousMode() == KernelMode) { 04008 return STATUS_INVALID_PARAMETER; 04009 } 04010 04011 if ( !PspW32ProcessCallout ) { 04012 return STATUS_ACCESS_DENIED; 04013 } 04014 04015 04016 Thread = PsGetCurrentThread(); 04017 04018 // 04019 // If the thread is using the shadow service table, then an attempt is 04020 // being made to convert a thread that has already been converted, or 04021 // a limit violation has occured on the Win32k system service table. 04022 // 04023 04024 if ( Thread->Tcb.ServiceTable != (PVOID)&KeServiceDescriptorTable[0] ) { 04025 return STATUS_ALREADY_WIN32; 04026 } 04027 04028 Process = PsGetCurrentProcess(); 04029 04030 // 04031 // Get a larger kernel stack if we haven't already. 04032 // 04033 04034 if ( !Thread->Tcb.LargeStack ) { 04035 04036 NewStack = MmCreateKernelStack(TRUE); 04037 04038 if ( !NewStack ) { 04039 04040 NtCurrentTeb()->LastErrorValue = (LONG)ERROR_NOT_ENOUGH_MEMORY; 04041 04042 return STATUS_NO_MEMORY; 04043 } 04044 04045 #if defined(_IA64_) 04046 OldStack = KeSwitchKernelStack(NewStack, 04047 (UCHAR *)NewStack - KERNEL_LARGE_STACK_COMMIT, 04048 (UCHAR *)NewStack + KERNEL_LARGE_BSTORE_COMMIT); 04049 #else 04050 OldStack = KeSwitchKernelStack(NewStack, 04051 (UCHAR *)NewStack - KERNEL_LARGE_STACK_COMMIT); 04052 #endif // defined(_IA64_) 04053 04054 MmDeleteKernelStack(OldStack, FALSE); 04055 04056 } 04057 04058 PERFINFO_CONVERT_TO_GUI_THREAD(Thread); 04059 04060 // 04061 // We are all clean on the stack, now call out and then link the Win32 structures 04062 // to the base exec structures 04063 // 04064 04065 Status = (PspW32ProcessCallout)(Process,TRUE); 04066 04067 if ( !NT_SUCCESS(Status) ) { 04068 return Status; 04069 } 04070 04071 // 04072 // Switch the thread to use the shadow system serive table which will 04073 // enable it to execute Win32k services. 04074 // 04075 04076 Thread->Tcb.ServiceTable = (PVOID)&KeServiceDescriptorTableShadow[0]; 04077 04078 ASSERT( Thread->Tcb.Win32Thread == 0 ); 04079 04080 04081 // 04082 // Make the thread callout. 04083 // 04084 04085 Status = (PspW32ThreadCallout)(Thread,PsW32ThreadCalloutInitialize); 04086 if ( !NT_SUCCESS(Status) ) { 04087 Thread->Tcb.ServiceTable = (PVOID)&KeServiceDescriptorTable[0]; 04088 } 04089 04090 return Status; 04091 04092 } }

NTKERNELAPI VOID PsEstablishWin32Callouts IN PKWIN32_PROCESS_CALLOUT  ProcessCallout,
IN PKWIN32_THREAD_CALLOUT  ThreadCallout,
IN PKWIN32_GLOBALATOMTABLE_CALLOUT  GlobalAtomTableCallout,
IN PKWIN32_POWEREVENT_CALLOUT  PowerEventCallout,
IN PKWIN32_POWERSTATE_CALLOUT  PowerStateCallout,
IN PKWIN32_JOB_CALLOUT  JobCallout,
IN PVOID  BatchFlushRoutine
 

Definition at line 3855 of file psquery.c.

References ExGlobalAtomTableCallout, KeGdiFlushUserBatch, PAGED_CODE, PGDI_BATCHFLUSH_ROUTINE, PopEventCallout, PopStateCallout, PspW32JobCallout, PspW32ProcessCallout, and PspW32ThreadCallout.

03867 : 03868 03869 This function is used by the Win32 kernel mode component to 03870 register callout functions for process/thread init/deinit functions 03871 and to report the sizes of the structures. 03872 03873 Arguments: 03874 03875 ProcessCallout - Supplies the address of the function to be called when 03876 a process is either created or deleted. 03877 03878 ThreadCallout - Supplies the address of the function to be called when 03879 a thread is either created or deleted. 03880 03881 GlobalAtomTableCallout - Supplies the address of the function to be called 03882 to get the correct global atom table for the current process 03883 03884 PowerEventCallout - Supplies the address of a function to be called when 03885 a power event occurs. 03886 03887 PowerStateCallout - Supplies the address of a function to be called when 03888 the power state changes. 03889 03890 JobCallout - Supplies the address of a function to be called when 03891 the job state changes or a process is assigned to a job. 03892 03893 BatchFlushRoutine - Supplies the address of the function to be called 03894 03895 Return Value: 03896 03897 None. 03898 03899 --*/ 03900 03901 { 03902 PAGED_CODE(); 03903 03904 PspW32ProcessCallout = ProcessCallout; 03905 PspW32ThreadCallout = ThreadCallout; 03906 ExGlobalAtomTableCallout = GlobalAtomTableCallout; 03907 KeGdiFlushUserBatch = (PGDI_BATCHFLUSH_ROUTINE)BatchFlushRoutine; 03908 PopEventCallout = PowerEventCallout; 03909 PopStateCallout = PowerStateCallout; 03910 PspW32JobCallout = JobCallout; 03911 // PoSetSystemState(ES_SYSTEM_REQUIRED); 03912 }

NTSTATUS PspQueryPooledQuotaLimits IN HANDLE  ProcessHandle,
IN PROCESSINFOCLASS  ProcessInformationClass,
OUT PVOID  ProcessInformation,
IN ULONG  ProcessInformationLength,
OUT PULONG ReturnLength  OPTIONAL,
IN KPROCESSOR_MODE  PreviousMode
 

Definition at line 291 of file psquery.c.

References EXCEPTION_EXECUTE_HANDLER, ExPageLockHandle, MmLockPagableSectionByHandle(), MmUnlockPagableImageSection(), NonPagedPool, NT_SUCCESS, NTSTATUS(), NULL, ObDereferenceObject, ObReferenceObjectByHandle(), PagedPool, _EPROCESS_QUOTA_BLOCK::PagefileLimit, _EPROCESS_QUOTA_BLOCK::PagefileUsage, _EPROCESS_QUOTA_BLOCK::PeakPagefileUsage, PsProcessType, _EPROCESS_QUOTA_BLOCK::QuotaLock, _EPROCESS_QUOTA_BLOCK::QuotaPeakPoolUsage, _EPROCESS_QUOTA_BLOCK::QuotaPoolLimit, and _EPROCESS_QUOTA_BLOCK::QuotaPoolUsage.

Referenced by NtQueryInformationProcess().

00299 { 00300 PEPROCESS Process; 00301 KIRQL OldIrql; 00302 NTSTATUS st; 00303 PEPROCESS_QUOTA_BLOCK QuotaBlock; 00304 POOLED_USAGE_AND_LIMITS UsageAndLimits; 00305 00306 if ( ProcessInformationLength != (ULONG) sizeof(POOLED_USAGE_AND_LIMITS) ) { 00307 return STATUS_INFO_LENGTH_MISMATCH; 00308 } 00309 00310 st = ObReferenceObjectByHandle( 00311 ProcessHandle, 00312 PROCESS_QUERY_INFORMATION, 00313 PsProcessType, 00314 PreviousMode, 00315 (PVOID *)&Process, 00316 NULL 00317 ); 00318 if ( !NT_SUCCESS(st) ) { 00319 return st; 00320 } 00321 00322 00323 QuotaBlock = Process->QuotaBlock; 00324 00325 MmLockPagableSectionByHandle(ExPageLockHandle); 00326 00327 ExAcquireSpinLock(&QuotaBlock->QuotaLock,&OldIrql); 00328 00329 UsageAndLimits.PagedPoolLimit = QuotaBlock->QuotaPoolLimit[PagedPool]; 00330 UsageAndLimits.NonPagedPoolLimit = QuotaBlock->QuotaPoolLimit[NonPagedPool]; 00331 UsageAndLimits.PagefileLimit = QuotaBlock->PagefileLimit; 00332 00333 UsageAndLimits.PagedPoolUsage = QuotaBlock->QuotaPoolUsage[PagedPool]; 00334 UsageAndLimits.NonPagedPoolUsage = QuotaBlock->QuotaPoolUsage[NonPagedPool]; 00335 UsageAndLimits.PagefileUsage = QuotaBlock->PagefileUsage; 00336 00337 UsageAndLimits.PeakPagedPoolUsage = QuotaBlock->QuotaPeakPoolUsage[PagedPool]; 00338 UsageAndLimits.PeakNonPagedPoolUsage = QuotaBlock->QuotaPeakPoolUsage[NonPagedPool]; 00339 UsageAndLimits.PeakPagefileUsage = QuotaBlock->PeakPagefileUsage; 00340 00341 ExReleaseSpinLock(&QuotaBlock->QuotaLock,OldIrql); 00342 MmUnlockPagableImageSection(ExPageLockHandle); 00343 00344 ObDereferenceObject(Process); 00345 00346 // 00347 // Either of these may cause an access violation. The 00348 // exception handler will return access violation as 00349 // status code. No further cleanup needs to be done. 00350 // 00351 00352 try { 00353 *(PPOOLED_USAGE_AND_LIMITS) ProcessInformation = UsageAndLimits; 00354 00355 if (ARGUMENT_PRESENT(ReturnLength) ) { 00356 *ReturnLength = sizeof(POOLED_USAGE_AND_LIMITS); 00357 } 00358 } except(EXCEPTION_EXECUTE_HANDLER) { 00359 return STATUS_SUCCESS; 00360 } 00361 00362 return STATUS_SUCCESS; 00363 }

NTSTATUS PspQueryQuotaLimits IN HANDLE  ProcessHandle,
IN PROCESSINFOCLASS  ProcessInformationClass,
OUT PVOID  ProcessInformation,
IN ULONG  ProcessInformationLength,
OUT PULONG ReturnLength  OPTIONAL,
IN KPROCESSOR_MODE  PreviousMode
 

Definition at line 209 of file psquery.c.

References EXCEPTION_EXECUTE_HANDLER, ExPageLockHandle, MmLockPagableSectionByHandle(), MmUnlockPagableImageSection(), NonPagedPool, NT_SUCCESS, NTSTATUS(), NULL, ObDereferenceObject, ObReferenceObjectByHandle(), PAGE_SHIFT, PagedPool, _EPROCESS_QUOTA_BLOCK::PagefileLimit, PspDefaultQuotaBlock, PsProcessType, _EPROCESS_QUOTA_BLOCK::QuotaLock, and _EPROCESS_QUOTA_BLOCK::QuotaPoolLimit.

Referenced by NtQueryInformationProcess().

00217 { 00218 QUOTA_LIMITS QuotaLimits; 00219 PEPROCESS Process; 00220 KIRQL OldIrql; 00221 NTSTATUS st; 00222 PEPROCESS_QUOTA_BLOCK QuotaBlock; 00223 00224 if ( ProcessInformationLength != (ULONG) sizeof(QUOTA_LIMITS) ) { 00225 return STATUS_INFO_LENGTH_MISMATCH; 00226 } 00227 00228 st = ObReferenceObjectByHandle( 00229 ProcessHandle, 00230 PROCESS_QUERY_INFORMATION, 00231 PsProcessType, 00232 PreviousMode, 00233 (PVOID *)&Process, 00234 NULL 00235 ); 00236 if ( !NT_SUCCESS(st) ) { 00237 return st; 00238 } 00239 00240 00241 QuotaBlock = Process->QuotaBlock; 00242 00243 MmLockPagableSectionByHandle(ExPageLockHandle); 00244 00245 if ( QuotaBlock != &PspDefaultQuotaBlock ) { 00246 ExAcquireSpinLock(&QuotaBlock->QuotaLock,&OldIrql); 00247 00248 QuotaLimits.PagedPoolLimit = QuotaBlock->QuotaPoolLimit[PagedPool]; 00249 QuotaLimits.NonPagedPoolLimit = QuotaBlock->QuotaPoolLimit[NonPagedPool]; 00250 QuotaLimits.PagefileLimit = QuotaBlock->PagefileLimit; 00251 QuotaLimits.TimeLimit.LowPart = 0xffffffff; 00252 QuotaLimits.TimeLimit.HighPart = 0xffffffff; 00253 00254 ExReleaseSpinLock(&QuotaBlock->QuotaLock,OldIrql); 00255 } else { 00256 QuotaLimits.PagedPoolLimit = (SIZE_T)-1; 00257 QuotaLimits.NonPagedPoolLimit = (SIZE_T)-1; 00258 QuotaLimits.PagefileLimit = (SIZE_T)-1; 00259 QuotaLimits.TimeLimit.LowPart = 0xffffffff; 00260 QuotaLimits.TimeLimit.HighPart = 0xffffffff; 00261 } 00262 00263 QuotaLimits.MinimumWorkingSetSize = 00264 Process->Vm.MinimumWorkingSetSize << PAGE_SHIFT; 00265 QuotaLimits.MaximumWorkingSetSize = 00266 Process->Vm.MaximumWorkingSetSize << PAGE_SHIFT; 00267 00268 ObDereferenceObject(Process); 00269 00270 // 00271 // Either of these may cause an access violation. The 00272 // exception handler will return access violation as 00273 // status code. No further cleanup needs to be done. 00274 // 00275 00276 try { 00277 *(PQUOTA_LIMITS) ProcessInformation = QuotaLimits; 00278 00279 if (ARGUMENT_PRESENT(ReturnLength) ) { 00280 *ReturnLength = sizeof(QUOTA_LIMITS); 00281 } 00282 } except(EXCEPTION_EXECUTE_HANDLER) { 00283 ; 00284 } 00285 00286 MmUnlockPagableImageSection(ExPageLockHandle); 00287 return STATUS_SUCCESS; 00288 }

NTSTATUS PspQueryWorkingSetWatch IN HANDLE  ProcessHandle,
IN PROCESSINFOCLASS  ProcessInformationClass,
OUT PVOID  ProcessInformation,
IN ULONG  ProcessInformationLength,
OUT PULONG ReturnLength  OPTIONAL,
IN KPROCESSOR_MODE  PreviousMode
 

Definition at line 113 of file psquery.c.

References EXCEPTION_EXECUTE_HANDLER, ExPageLockHandle, MAX_WS_CATCH_INDEX, MmLockPagableSectionByHandle(), MmUnlockPagableImageSection(), NT_SUCCESS, NTSTATUS(), NULL, ObDereferenceObject, ObReferenceObjectByHandle(), and PsProcessType.

Referenced by NtQueryInformationProcess().

00121 { 00122 PPAGEFAULT_HISTORY WorkingSetCatcher; 00123 ULONG SpaceNeeded; 00124 PEPROCESS Process; 00125 KIRQL OldIrql; 00126 NTSTATUS st; 00127 00128 st = ObReferenceObjectByHandle( 00129 ProcessHandle, 00130 PROCESS_QUERY_INFORMATION, 00131 PsProcessType, 00132 PreviousMode, 00133 (PVOID *)&Process, 00134 NULL 00135 ); 00136 00137 if ( !NT_SUCCESS(st) ) { 00138 return st; 00139 } 00140 00141 if ( !(WorkingSetCatcher = Process->WorkingSetWatch) ) { 00142 ObDereferenceObject(Process); 00143 return STATUS_UNSUCCESSFUL; 00144 } 00145 00146 MmLockPagableSectionByHandle(ExPageLockHandle); 00147 ExAcquireSpinLock(&WorkingSetCatcher->SpinLock,&OldIrql); 00148 00149 if ( WorkingSetCatcher->CurrentIndex ) { 00150 00151 // 00152 // Null Terminate the first empty entry in the buffer 00153 // 00154 00155 WorkingSetCatcher->WatchInfo[WorkingSetCatcher->CurrentIndex].FaultingPc = NULL; 00156 00157 //Store a special Va value if the buffer was full and 00158 //page faults could have been lost 00159 00160 if (WorkingSetCatcher->CurrentIndex != WorkingSetCatcher->MaxIndex) 00161 WorkingSetCatcher->WatchInfo[WorkingSetCatcher->CurrentIndex].FaultingVa = NULL; 00162 else 00163 WorkingSetCatcher->WatchInfo[WorkingSetCatcher->CurrentIndex].FaultingVa = (PVOID) 1; 00164 00165 SpaceNeeded = (WorkingSetCatcher->CurrentIndex+1) * sizeof(PROCESS_WS_WATCH_INFORMATION); 00166 } else { 00167 ExReleaseSpinLock(&WorkingSetCatcher->SpinLock,OldIrql); 00168 MmUnlockPagableImageSection(ExPageLockHandle); 00169 ObDereferenceObject(Process); 00170 return STATUS_NO_MORE_ENTRIES; 00171 } 00172 00173 if ( ProcessInformationLength < SpaceNeeded ) { 00174 ExReleaseSpinLock(&WorkingSetCatcher->SpinLock,OldIrql); 00175 MmUnlockPagableImageSection(ExPageLockHandle); 00176 ObDereferenceObject(Process); 00177 return STATUS_BUFFER_TOO_SMALL; 00178 } 00179 00180 // 00181 // Mark the Working Set buffer as full and then drop the lock 00182 // and copy the bytes 00183 // 00184 00185 WorkingSetCatcher->CurrentIndex = MAX_WS_CATCH_INDEX; 00186 00187 ExReleaseSpinLock(&WorkingSetCatcher->SpinLock,OldIrql); 00188 00189 try { 00190 RtlMoveMemory(ProcessInformation,&WorkingSetCatcher->WatchInfo[0],SpaceNeeded); 00191 if (ARGUMENT_PRESENT(ReturnLength) ) { 00192 *ReturnLength = SpaceNeeded; 00193 } 00194 } except(EXCEPTION_EXECUTE_HANDLER) { 00195 ; 00196 } 00197 00198 ExAcquireSpinLock(&WorkingSetCatcher->SpinLock,&OldIrql); 00199 WorkingSetCatcher->CurrentIndex = 0; 00200 ExReleaseSpinLock(&WorkingSetCatcher->SpinLock,OldIrql); 00201 00202 MmUnlockPagableImageSection(ExPageLockHandle); 00203 ObDereferenceObject(Process); 00204 00205 return STATUS_SUCCESS; 00206 }

NTSTATUS PspSetPrimaryToken IN HANDLE  ProcessHandle,
IN HANDLE TokenHandle  OPTIONAL,
IN PACCESS_TOKEN TokenPointer  OPTIONAL
 

Definition at line 366 of file psquery.c.

References _SECURITY_SUBJECT_CONTEXT::ClientToken, FALSE, _OBJECT_TYPE_INITIALIZER::GenericMapping, KPROCESSOR_MODE, NT_SUCCESS, NTSTATUS(), NULL, ObDereferenceObject, ObGetObjectSecurity(), ObReferenceObjectByHandle(), ObReleaseObjectSecurity(), _SECURITY_SUBJECT_CONTEXT::PrimaryToken, _SECURITY_SUBJECT_CONTEXT::ProcessAuditId, PsDereferencePrimaryToken, PspAssignPrimaryToken(), PsProcessType, PsReferencePrimaryToken(), SeAccessCheck(), SeAssignPrimaryTokenPrivilege, SeCheckPrivilegedObject(), SeIsChildTokenByPointer(), SeTokenObjectType, and _OBJECT_TYPE::TypeInfo.

Referenced by NtAssignProcessToJobObject(), and NtSetInformationProcess().

00377 { 00378 NTSTATUS st ; 00379 BOOLEAN HasPrivilege ; 00380 BOOLEAN IsChildToken ; 00381 PEPROCESS Process ; 00382 KPROCESSOR_MODE PreviousMode ; 00383 00384 // 00385 // Check to see if the supplied token is a child of the caller's 00386 // token. If so, we don't need to do the privilege check. 00387 // 00388 00389 PreviousMode = KeGetPreviousMode(); 00390 00391 if ( TokenHandle ) 00392 { 00393 // 00394 // Reference the specified token, and make sure it can be assigned 00395 // as a primary token. 00396 // 00397 00398 st = ObReferenceObjectByHandle ( 00399 TokenHandle, 00400 TOKEN_ASSIGN_PRIMARY, 00401 SeTokenObjectType(), 00402 PreviousMode, 00403 (PVOID *)&TokenPointer, 00404 NULL 00405 ); 00406 00407 if (!NT_SUCCESS(st)) { 00408 return( st ); 00409 } 00410 } 00411 00412 st = SeIsChildTokenByPointer( 00413 TokenPointer, 00414 &IsChildToken 00415 ); 00416 00417 if (!NT_SUCCESS(st)) { 00418 00419 if ( TokenHandle ) { 00420 ObDereferenceObject( TokenPointer ); 00421 } 00422 return( st ); 00423 } 00424 00425 if (!IsChildToken ) { 00426 00427 00428 // 00429 // SeCheckPrivilegedObject will perform auditing as appropriate 00430 // 00431 00432 HasPrivilege = SeCheckPrivilegedObject( 00433 SeAssignPrimaryTokenPrivilege, 00434 ProcessHandle, 00435 PROCESS_SET_INFORMATION, 00436 PreviousMode 00437 ); 00438 00439 if ( !HasPrivilege ) { 00440 00441 if ( TokenHandle ) { 00442 ObDereferenceObject( TokenPointer ); 00443 } 00444 00445 return( STATUS_PRIVILEGE_NOT_HELD ); 00446 } 00447 00448 } 00449 00450 st = ObReferenceObjectByHandle( 00451 ProcessHandle, 00452 PROCESS_SET_INFORMATION, 00453 PsProcessType, 00454 PreviousMode, 00455 (PVOID *)&Process, 00456 NULL 00457 ); 00458 00459 if ( NT_SUCCESS(st) ) { 00460 00461 // 00462 // Check for proper access to the token, and assign the primary 00463 // token for the process. 00464 // 00465 00466 st = PspAssignPrimaryToken( Process, NULL, TokenPointer ); 00467 00468 // 00469 // Recompute the process's access to itself for use 00470 // with the CurrentProcess() pseudo handle. 00471 // 00472 00473 if ( NT_SUCCESS(st) ) { 00474 00475 NTSTATUS accesst; 00476 BOOLEAN AccessCheck; 00477 BOOLEAN MemoryAllocated; 00478 PSECURITY_DESCRIPTOR SecurityDescriptor; 00479 SECURITY_SUBJECT_CONTEXT SubjectContext; 00480 00481 st = ObGetObjectSecurity( 00482 Process, 00483 &SecurityDescriptor, 00484 &MemoryAllocated 00485 ); 00486 00487 if ( NT_SUCCESS(st) ) { 00488 00489 // 00490 // Compute the subject security context 00491 // 00492 00493 SubjectContext.ProcessAuditId = Process; 00494 SubjectContext.PrimaryToken = PsReferencePrimaryToken(Process); 00495 SubjectContext.ClientToken = NULL; 00496 AccessCheck = SeAccessCheck( 00497 SecurityDescriptor, 00498 &SubjectContext, 00499 FALSE, 00500 MAXIMUM_ALLOWED, 00501 0, 00502 NULL, 00503 &PsProcessType->TypeInfo.GenericMapping, 00504 PreviousMode, 00505 &Process->GrantedAccess, 00506 &accesst 00507 ); 00508 PsDereferencePrimaryToken(SubjectContext.PrimaryToken); 00509 ObReleaseObjectSecurity( 00510 SecurityDescriptor, 00511 MemoryAllocated 00512 ); 00513 if ( !AccessCheck ) { 00514 Process->GrantedAccess = 0; 00515 } 00516 } 00517 } 00518 00519 ObDereferenceObject(Process); 00520 } 00521 00522 if ( TokenHandle) { 00523 ObDereferenceObject( TokenPointer ); 00524 } 00525 00526 return st; 00527 }

NTSTATUS PspSetQuotaLimits IN HANDLE  ProcessHandle,
IN PROCESSINFOCLASS  ProcessInformationClass,
IN PVOID  ProcessInformation,
IN ULONG  ProcessInformationLength,
IN KPROCESSOR_MODE  PreviousMode
 

Definition at line 1211 of file psquery.c.

References ExAcquireResourceShared, ExAllocatePool, EXCEPTION_EXECUTE_HANDLER, ExFreePool(), ExPageLockHandle, ExReleaseResource, FALSE, KeAttachProcess(), KeDetachProcess(), KeEnterCriticalRegion, KeInitializeSpinLock(), KeLeaveCriticalRegion, MmAdjustWorkingSetSize(), MmLockPagableSectionByHandle(), MmRaisePoolQuota(), MmUnlockPagableImageSection(), NonPagedPool, NT_SUCCESS, NTSTATUS(), NULL, ObDereferenceObject, ObReferenceObjectByHandle(), PagedPool, _EPROCESS_QUOTA_BLOCK::PagefileUsage, PspDefaultNonPagedLimit, PspDefaultPagedLimit, PspDefaultPagefileLimit, PspDefaultQuotaBlock, PsProcessType, _EPROCESS_QUOTA_BLOCK::QuotaLock, _EPROCESS_QUOTA_BLOCK::QuotaPoolUsage, SeIncreaseQuotaPrivilege, SeSinglePrivilegeCheck(), and TRUE.

Referenced by NtSetInformationProcess().

01218 { 01219 PEPROCESS Process; 01220 QUOTA_LIMITS RequestedLimits; 01221 KIRQL OldIrql; 01222 PEPROCESS_QUOTA_BLOCK NewQuotaBlock; 01223 BOOLEAN HasPrivilege = FALSE; 01224 NTSTATUS st, ReturnStatus; 01225 PVOID UnlockHandle; 01226 SIZE_T NewLimit; 01227 01228 if ( ProcessInformationLength != sizeof(QUOTA_LIMITS) ) { 01229 return STATUS_INFO_LENGTH_MISMATCH; 01230 } 01231 01232 try { 01233 RequestedLimits = *(PQUOTA_LIMITS) ProcessInformation; 01234 } except(EXCEPTION_EXECUTE_HANDLER) { 01235 return GetExceptionCode(); 01236 } 01237 01238 st = ObReferenceObjectByHandle( 01239 ProcessHandle, 01240 PROCESS_SET_QUOTA, 01241 PsProcessType, 01242 PreviousMode, 01243 (PVOID *)&Process, 01244 NULL 01245 ); 01246 01247 if ( !NT_SUCCESS(st) ) { 01248 return st; 01249 } 01250 01251 UnlockHandle = NULL; 01252 01253 // 01254 // Now we are ready to set the quota limits for the process 01255 // 01256 // If the process already has a quota block, then all we allow 01257 // is working set changes. 01258 // 01259 // If the process has no quota block, all that can be done is a 01260 // quota set operation. The quotas must be high enough that the 01261 // current usage can be charged without causing a quota overflow. 01262 // 01263 // If a quota field is zero, we pick the value. 01264 // 01265 // Setting quotas requires the SeIncreaseQuotaPrivilege (except for 01266 // working set size since this is only advisory). 01267 // 01268 01269 ReturnStatus = STATUS_SUCCESS; 01270 01271 if ( Process->QuotaBlock == &PspDefaultQuotaBlock ) { 01272 if ( RequestedLimits.MinimumWorkingSetSize && 01273 RequestedLimits.MaximumWorkingSetSize ) { 01274 01275 if ( RequestedLimits.MinimumWorkingSetSize != (SIZE_T)-1 && 01276 RequestedLimits.MaximumWorkingSetSize != (SIZE_T)-1 ) { 01277 if ( Process->Job ) { 01278 KeEnterCriticalRegion(); 01279 ExAcquireResourceShared(&Process->Job->JobLock, TRUE); 01280 01281 if ( Process->Job->LimitFlags & JOB_OBJECT_LIMIT_WORKINGSET ) { 01282 RequestedLimits.MinimumWorkingSetSize = Process->Job->MinimumWorkingSetSize; 01283 RequestedLimits.MaximumWorkingSetSize = Process->Job->MaximumWorkingSetSize; 01284 } 01285 01286 ExReleaseResource(&Process->Job->JobLock); 01287 KeLeaveCriticalRegion(); 01288 } 01289 } 01290 01291 KeAttachProcess (&Process->Pcb); 01292 ReturnStatus = MmAdjustWorkingSetSize ( 01293 RequestedLimits.MinimumWorkingSetSize, 01294 RequestedLimits.MaximumWorkingSetSize, 01295 FALSE 01296 ); 01297 KeDetachProcess(); 01298 01299 } else { 01300 01301 01302 // 01303 // You must have a privilege to assign quotas 01304 // 01305 01306 if ( !SeSinglePrivilegeCheck(SeIncreaseQuotaPrivilege,PreviousMode) ) { 01307 ObDereferenceObject(Process); 01308 return STATUS_PRIVILEGE_NOT_HELD; 01309 } 01310 01311 NewQuotaBlock = ExAllocatePool(NonPagedPool,sizeof(*NewQuotaBlock)); 01312 if ( !NewQuotaBlock ) { 01313 ObDereferenceObject(Process); 01314 return STATUS_NO_MEMORY; 01315 } 01316 RtlZeroMemory(NewQuotaBlock,sizeof(*NewQuotaBlock)); 01317 01318 // 01319 // Initialize the quota block 01320 // 01321 01322 KeInitializeSpinLock(&NewQuotaBlock->QuotaLock); 01323 NewQuotaBlock->ReferenceCount = 1; 01324 01325 // 01326 // Grab the quota lock to prevent usage changes 01327 // 01328 01329 MmLockPagableSectionByHandle(ExPageLockHandle); 01330 UnlockHandle = ExPageLockHandle; 01331 01332 ExAcquireSpinLock(&PspDefaultQuotaBlock.QuotaLock, &OldIrql ); 01333 01334 01335 NewQuotaBlock->QuotaPeakPoolUsage[NonPagedPool] = Process->QuotaPeakPoolUsage[NonPagedPool]; 01336 NewQuotaBlock->QuotaPeakPoolUsage[PagedPool] = Process->QuotaPeakPoolUsage[PagedPool]; 01337 NewQuotaBlock->QuotaPoolUsage[NonPagedPool] = Process->QuotaPoolUsage[NonPagedPool]; 01338 NewQuotaBlock->QuotaPoolUsage[PagedPool] = Process->QuotaPoolUsage[PagedPool]; 01339 01340 NewQuotaBlock->PagefileUsage = Process->PagefileUsage; 01341 NewQuotaBlock->PeakPagefileUsage = Process->PeakPagefileUsage; 01342 01343 // 01344 // Now compute limits 01345 // 01346 01347 // 01348 // lou... We need to think this out a bit 01349 // 01350 // Get the defaults that the system would pick. 01351 // 01352 01353 NewQuotaBlock->QuotaPoolLimit[PagedPool] = PspDefaultPagedLimit; 01354 NewQuotaBlock->QuotaPoolLimit[NonPagedPool] = PspDefaultNonPagedLimit; 01355 NewQuotaBlock->PagefileLimit = PspDefaultPagefileLimit; 01356 01357 // 01358 // Now see if current usage exceeds requested limits. If 01359 // so, fail the operation. 01360 // 01361 01362 // 01363 // Paged 01364 // 01365 01366 if ( NewQuotaBlock->QuotaPoolUsage[PagedPool] > NewQuotaBlock->QuotaPoolLimit[PagedPool] ) { 01367 01368 while ( (PspDefaultPagedLimit == 0) && MmRaisePoolQuota(PagedPool,NewQuotaBlock->QuotaPoolLimit[PagedPool],&NewLimit) ) { 01369 NewQuotaBlock->QuotaPoolLimit[PagedPool] = NewLimit; 01370 if ( NewQuotaBlock->QuotaPoolUsage[PagedPool] <= NewLimit ) { 01371 goto LimitRaised0; 01372 } 01373 } 01374 01375 // 01376 // current usage exceeds requested limit 01377 // 01378 01379 ExReleaseSpinLock(&PspDefaultQuotaBlock.QuotaLock,OldIrql ); 01380 MmUnlockPagableImageSection(UnlockHandle); 01381 ExFreePool(NewQuotaBlock); 01382 ObDereferenceObject(Process); 01383 return STATUS_QUOTA_EXCEEDED; 01384 } 01385 01386 // 01387 // NonPaged 01388 // 01389 01390 LimitRaised0: 01391 if ( NewQuotaBlock->QuotaPoolUsage[NonPagedPool] > NewQuotaBlock->QuotaPoolLimit[NonPagedPool] ) { 01392 01393 while ( (PspDefaultNonPagedLimit == 0) && MmRaisePoolQuota(NonPagedPool,NewQuotaBlock->QuotaPoolLimit[NonPagedPool],&NewLimit) ) { 01394 NewQuotaBlock->QuotaPoolLimit[NonPagedPool] = NewLimit; 01395 if ( NewQuotaBlock->QuotaPoolUsage[NonPagedPool] <= NewLimit ) { 01396 goto LimitRaised1; 01397 } 01398 } 01399 01400 // 01401 // current usage exceeds requested limit 01402 // 01403 01404 ExReleaseSpinLock(&PspDefaultQuotaBlock.QuotaLock,OldIrql ); 01405 MmUnlockPagableImageSection(UnlockHandle); 01406 ExFreePool(NewQuotaBlock); 01407 ObDereferenceObject(Process); 01408 return STATUS_QUOTA_EXCEEDED; 01409 } 01410 01411 // 01412 // Pagefile 01413 // 01414 01415 LimitRaised1: 01416 if ( NewQuotaBlock->PagefileUsage > NewQuotaBlock->PagefileLimit ) { 01417 01418 // 01419 // current usage exceeds requested limit 01420 // 01421 01422 ExReleaseSpinLock(&PspDefaultQuotaBlock.QuotaLock,OldIrql ); 01423 MmUnlockPagableImageSection(UnlockHandle); 01424 ExFreePool(NewQuotaBlock); 01425 ObDereferenceObject(Process); 01426 return STATUS_QUOTA_EXCEEDED; 01427 } 01428 01429 // Everything is set. Now double check to quota block fieled 01430 // If we still have no quota block then assign and succeed. 01431 // Otherwise punt. 01432 // 01433 01434 if ( Process->QuotaBlock != &PspDefaultQuotaBlock ) { 01435 ExReleaseSpinLock(&PspDefaultQuotaBlock.QuotaLock,OldIrql ); 01436 ExFreePool(NewQuotaBlock); 01437 } else { 01438 01439 // 01440 // return the quotas used by this process, and attach process 01441 // to new quota block 01442 // 01443 01444 if ( Process->QuotaPoolUsage[NonPagedPool] <= PspDefaultQuotaBlock.QuotaPoolUsage[NonPagedPool] ) { 01445 PspDefaultQuotaBlock.QuotaPoolUsage[NonPagedPool] -= Process->QuotaPoolUsage[NonPagedPool]; 01446 } 01447 else { 01448 PspDefaultQuotaBlock.QuotaPoolUsage[NonPagedPool] = 0; 01449 } 01450 01451 if ( Process->QuotaPoolUsage[PagedPool] <= PspDefaultQuotaBlock.QuotaPoolUsage[PagedPool] ) { 01452 PspDefaultQuotaBlock.QuotaPoolUsage[PagedPool] -= Process->QuotaPoolUsage[PagedPool]; 01453 } 01454 else { 01455 PspDefaultQuotaBlock.QuotaPoolUsage[PagedPool] = 0; 01456 } 01457 01458 if ( Process->PagefileUsage <= PspDefaultQuotaBlock.PagefileUsage ) { 01459 PspDefaultQuotaBlock.PagefileUsage -= Process->PagefileUsage; 01460 } 01461 01462 Process->QuotaBlock = NewQuotaBlock; 01463 ExReleaseSpinLock(&PspDefaultQuotaBlock.QuotaLock,OldIrql ); 01464 } 01465 MmUnlockPagableImageSection(UnlockHandle); 01466 ReturnStatus = STATUS_SUCCESS; 01467 } 01468 } else { 01469 01470 // 01471 // Only allow a working set size change 01472 // 01473 01474 if ( RequestedLimits.MinimumWorkingSetSize && 01475 RequestedLimits.MaximumWorkingSetSize ) { 01476 01477 if ( RequestedLimits.MinimumWorkingSetSize != (SIZE_T)-1 && 01478 RequestedLimits.MaximumWorkingSetSize != (SIZE_T)-1 ) { 01479 if ( Process->Job ) { 01480 KeEnterCriticalRegion(); 01481 ExAcquireResourceShared(&Process->Job->JobLock, TRUE); 01482 01483 if ( Process->Job->LimitFlags & JOB_OBJECT_LIMIT_WORKINGSET ) { 01484 RequestedLimits.MinimumWorkingSetSize = Process->Job->MinimumWorkingSetSize; 01485 RequestedLimits.MaximumWorkingSetSize = Process->Job->MaximumWorkingSetSize; 01486 } 01487 01488 ExReleaseResource(&Process->Job->JobLock); 01489 KeLeaveCriticalRegion(); 01490 } 01491 } 01492 01493 KeAttachProcess (&Process->Pcb); 01494 ReturnStatus = MmAdjustWorkingSetSize ( 01495 RequestedLimits.MinimumWorkingSetSize, 01496 RequestedLimits.MaximumWorkingSetSize, 01497 FALSE 01498 ); 01499 KeDetachProcess(); 01500 01501 } 01502 } 01503 ObDereferenceObject(Process); 01504 01505 return ReturnStatus; 01506 01507 }

VOID PsSetProcessPriorityByClass IN PEPROCESS  Process,
IN PSPROCESSPRIORITYMODE  PriorityMode
 

Definition at line 3916 of file psquery.c.

References KeSetPriorityProcess(), MEMORY_PRIORITY_BACKGROUND, MEMORY_PRIORITY_FOREGROUND, MmSetMemoryPriorityProcess(), PAGED_CODE, PS_WS_TRIM_BACKGROUND_ONLY_APP, PspForegroundQuantum, PspJobSchedulingClasses, PspPriorityTable, PsPrioritySeperation, PsProcessPriorityForeground, PsProcessPrioritySpinning, PspUseJobSchedulingClasses, and THREAD_QUANTUM.

Referenced by NtSetInformationProcess(), PspApplyJobLimitsToProcess(), PspCreateProcess(), and SetForegroundPriorityProcess().

03920 { 03921 KPRIORITY BasePriority; 03922 UCHAR MemoryPriority; 03923 ULONG QuantumIndex; 03924 03925 PAGED_CODE(); 03926 03927 03928 BasePriority = PspPriorityTable[Process->PriorityClass]; 03929 03930 03931 if ( PriorityMode == PsProcessPriorityForeground ) { 03932 QuantumIndex = PsPrioritySeperation; 03933 MemoryPriority = MEMORY_PRIORITY_FOREGROUND; 03934 #if defined(_X86_) 03935 Process->MmAgressiveWsTrimMask &= ~PS_WS_TRIM_BACKGROUND_ONLY_APP; 03936 #endif // _X86_ 03937 } 03938 else { 03939 QuantumIndex = 0; 03940 MemoryPriority = MEMORY_PRIORITY_BACKGROUND; 03941 } 03942 03943 if ( Process->PriorityClass != PROCESS_PRIORITY_CLASS_IDLE ) { 03944 if ( Process->Job && PspUseJobSchedulingClasses ) { 03945 Process->Pcb.ThreadQuantum = PspJobSchedulingClasses[Process->Job->SchedulingClass]; 03946 } 03947 else { 03948 Process->Pcb.ThreadQuantum = PspForegroundQuantum[QuantumIndex]; 03949 } 03950 } 03951 else { 03952 Process->Pcb.ThreadQuantum = THREAD_QUANTUM; 03953 } 03954 03955 KeSetPriorityProcess(&Process->Pcb,BasePriority); 03956 if ( PriorityMode != PsProcessPrioritySpinning ) { 03957 MmSetMemoryPriorityProcess(Process, MemoryPriority); 03958 } 03959 }

NTSTATUS PsWatchWorkingSet IN NTSTATUS  Status,
IN PVOID  PcValue,
IN PVOID  Va
 

Definition at line 3788 of file psquery.c.

References FALSE, NT_SUCCESS, PsGetCurrentProcess, Status, TRUE, and _EPROCESS::WorkingSetWatch.

Referenced by KiMemoryFault().

03796 : 03797 03798 This function collects data about page faults. 03799 For both user and kernel space page faults, it stores information about 03800 the page fault in the causing process's data structure. 03801 03802 Arguments: 03803 03804 Status - type of page fault 03805 PcValue - Program Counter value that caused page fault 03806 Va - Memory address that was being accessed to cause the page fault 03807 03808 --*/ 03809 03810 { 03811 PEPROCESS Process; 03812 PPAGEFAULT_HISTORY WorkingSetCatcher; 03813 KIRQL OldIrql; 03814 BOOLEAN TransitionFault = FALSE; 03815 03816 if ( !NT_SUCCESS( Status )) 03817 return Status; 03818 03819 //Both transition and demand zero faults count as soft faults. Only disk 03820 //reads count as hard faults. 03821 if ( Status <= STATUS_PAGE_FAULT_DEMAND_ZERO ) { 03822 TransitionFault = TRUE; 03823 } 03824 Process = PsGetCurrentProcess(); 03825 if ( !(WorkingSetCatcher = Process->WorkingSetWatch) ) { 03826 return Status; 03827 } 03828 03829 ExAcquireSpinLock(&WorkingSetCatcher->SpinLock,&OldIrql); 03830 if ( WorkingSetCatcher->CurrentIndex >= WorkingSetCatcher->MaxIndex ) { 03831 ExReleaseSpinLock(&WorkingSetCatcher->SpinLock,OldIrql); 03832 return Status; 03833 } 03834 03835 //Store the Pc and Va values in the buffer. Use the least sig. bit 03836 //of the Va to store whether it was a soft or hard fault 03837 WorkingSetCatcher->WatchInfo[WorkingSetCatcher->CurrentIndex].FaultingPc = PcValue; 03838 WorkingSetCatcher->WatchInfo[WorkingSetCatcher->CurrentIndex].FaultingVa = TransitionFault ? (PVOID)((ULONG_PTR)Va | 1) : (PVOID)((ULONG_PTR)Va & 0xfffffffe) ; 03839 WorkingSetCatcher->CurrentIndex++; 03840 03841 ExReleaseSpinLock(&WorkingSetCatcher->SpinLock,OldIrql); 03842 return Status; 03843 }


Variable Documentation

PEPROCESS ExpDefaultErrorPortProcess
 

Definition at line 40 of file psquery.c.

Referenced by ExpRaiseHardError(), MiCheckForUserStackOverflow(), MiLoadImageSection(), NtSetDefaultHardErrorPort(), and NtSetInformationThread().

KMUTANT ObpInitKillMutant
 

Definition at line 35 of file psquery.c.

PKWIN32_POWEREVENT_CALLOUT PopEventCallout
 

Definition at line 3848 of file psquery.c.

Referenced by PsEstablishWin32Callouts().

PKWIN32_POWERSTATE_CALLOUT PopStateCallout
 

Definition at line 3849 of file psquery.c.

Referenced by PsEstablishWin32Callouts().

KPRIORITY PspPriorityTable[PROCESS_PRIORITY_CLASS_ABOVE_NORMAL+1] = {8,4,8,13,24,6,10}
 

Definition at line 52 of file psquery.c.

Referenced by PsSetProcessPriorityByClass().

PKWIN32_JOB_CALLOUT PspW32JobCallout
 

Definition at line 3847 of file psquery.c.

Referenced by NtAssignProcessToJobObject(), NtSetInformationJobObject(), PsEstablishWin32Callouts(), and PspJobDelete().

PKWIN32_PROCESS_CALLOUT PspW32ProcessCallout
 

Definition at line 3845 of file psquery.c.

Referenced by PsConvertToGuiThread(), PsEstablishWin32Callouts(), and PspExitThread().

PKWIN32_THREAD_CALLOUT PspW32ThreadCallout
 

Definition at line 3846 of file psquery.c.

Referenced by PsConvertToGuiThread(), PsEstablishWin32Callouts(), and PspExitThread().

BOOLEAN PsWatchEnabled
 

Definition at line 41 of file psquery.c.


Generated on Sat May 15 19:45:24 2004 for test by doxygen 1.3.7