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

queryvm.c File Reference

#include "mi.h"

Go to the source code of this file.

Functions

NTSTATUS MiGetWorkingSetInfo (IN PMEMORY_WORKING_SET_INFORMATION WorkingSetInfo, IN ULONG Length, IN PEPROCESS Process)
MMPTE MiCaptureSystemPte (IN PMMPTE PointerProtoPte, IN PEPROCESS Process)
ULONG MiQueryAddressState (IN PVOID Va, IN PMMVAD Vad, IN PEPROCESS TargetProcess, OUT PULONG ReturnedProtect)
NTSTATUS NtQueryVirtualMemory (IN HANDLE ProcessHandle, IN PVOID BaseAddress, IN MEMORY_INFORMATION_CLASS MemoryInformationClass, OUT PVOID MemoryInformation, IN ULONG MemoryInformationLength, OUT PULONG ReturnLength OPTIONAL)

Variables

POBJECT_TYPE IoFileObjectType


Function Documentation

MMPTE MiCaptureSystemPte IN PMMPTE  PointerProtoPte,
IN PEPROCESS  Process
 

Referenced by MiGetPageProtection(), MiQueryAddressState(), and MiSetProtectionOnSection().

NTSTATUS MiGetWorkingSetInfo IN PMEMORY_WORKING_SET_INFORMATION  WorkingSetInfo,
IN ULONG  Length,
IN PEPROCESS  Process
 

Definition at line 890 of file queryvm.c.

References ASSERT, BYTES_TO_PAGES, ExAllocatePoolWithTag, EXCEPTION_EXECUTE_HANDLER, ExFreePool(), FALSE, IoWriteAccess, KeAttachProcess(), KeDetachProcess(), _MMWSL::LastEntry, LOCK_WS, MI_GET_PROTECTION_FROM_SOFT_PTE, MI_PFN_ELEMENT, MiGetPteAddress, MmGetSystemAddressForMdlSafe, MmInitializeMdl, MmProbeAndLockPages(), MmUnlockPages(), MmWorkingSetList, MmWsle, NonPagedPool, NormalPagePriority, NTSTATUS(), NULL, _MMPFN::OriginalPte, PsGetCurrentProcess, TRUE, _MMPTE::u, _MMWSLE::u1, _MMPFN::u2, _MMPFN::u3, and UNLOCK_WS.

Referenced by NtQueryVirtualMemory().

00896 { 00897 PMDL Mdl; 00898 PMEMORY_WORKING_SET_INFORMATION Info; 00899 PMEMORY_WORKING_SET_BLOCK Entry; 00900 PMEMORY_WORKING_SET_BLOCK LastEntry; 00901 PMMWSLE Wsle; 00902 PMMWSLE LastWsle; 00903 ULONG WsSize; 00904 PMMPTE PointerPte; 00905 PMMPFN Pfn1; 00906 NTSTATUS status; 00907 LOGICAL Attached; 00908 00909 // 00910 // Allocate an MDL to map the request. 00911 // 00912 00913 Mdl = ExAllocatePoolWithTag (NonPagedPool, 00914 sizeof(MDL) + sizeof(PFN_NUMBER) + 00915 BYTES_TO_PAGES (Length) * sizeof(PFN_NUMBER), 00916 ' mM'); 00917 00918 if (Mdl == NULL) { 00919 return(STATUS_INSUFFICIENT_RESOURCES); 00920 } 00921 00922 // 00923 // Initialize the MDL for the request. 00924 // 00925 00926 MmInitializeMdl(Mdl, WorkingSetInfo, Length); 00927 00928 try { 00929 MmProbeAndLockPages (Mdl, KeGetPreviousMode(), IoWriteAccess); 00930 } except (EXCEPTION_EXECUTE_HANDLER) { 00931 ExFreePool (Mdl); 00932 return GetExceptionCode(); 00933 } 00934 00935 Info = MmGetSystemAddressForMdlSafe (Mdl, NormalPagePriority); 00936 00937 if (Info == NULL) { 00938 MmUnlockPages (Mdl); 00939 ExFreePool (Mdl); 00940 return STATUS_INSUFFICIENT_RESOURCES; 00941 } 00942 00943 if (PsGetCurrentProcess() != Process) { 00944 KeAttachProcess (&Process->Pcb); 00945 Attached = TRUE; 00946 } 00947 else { 00948 Attached = FALSE; 00949 } 00950 00951 LOCK_WS (Process); 00952 00953 status = STATUS_SUCCESS; 00954 00955 if (Process->AddressSpaceDeleted != 0) { 00956 status = STATUS_PROCESS_IS_TERMINATING; 00957 } 00958 00959 WsSize = Process->Vm.WorkingSetSize; 00960 Info->NumberOfEntries = WsSize; 00961 00962 if ((WsSize * sizeof(ULONG)) >= Length) { 00963 status = STATUS_INFO_LENGTH_MISMATCH; 00964 } 00965 00966 if (status != STATUS_SUCCESS) { 00967 UNLOCK_WS (Process); 00968 if (Attached == TRUE) { 00969 KeDetachProcess (); 00970 } 00971 MmUnlockPages (Mdl); 00972 ExFreePool (Mdl); 00973 return status; 00974 } 00975 00976 Wsle = MmWsle; 00977 LastWsle = &MmWsle[MmWorkingSetList->LastEntry]; 00978 Entry = &Info->WorkingSetInfo[0]; 00979 LastEntry = (PMEMORY_WORKING_SET_BLOCK)( 00980 (PCHAR)Info + (Length & (~(sizeof(ULONG) - 1)))); 00981 00982 do { 00983 if (Wsle->u1.e1.Valid == 1) { 00984 Entry->VirtualPage = Wsle->u1.e1.VirtualPageNumber; 00985 PointerPte = MiGetPteAddress (Wsle->u1.VirtualAddress); 00986 ASSERT (PointerPte->u.Hard.Valid == 1); 00987 Pfn1 = MI_PFN_ELEMENT (PointerPte->u.Hard.PageFrameNumber); 00988 00989 Entry->Shared = Pfn1->u3.e1.PrototypePte; 00990 if (Pfn1->u3.e1.PrototypePte == 0) { 00991 Entry->ShareCount = 0; 00992 Entry->Protection = MI_GET_PROTECTION_FROM_SOFT_PTE(&Pfn1->OriginalPte); 00993 } else { 00994 if (Pfn1->u2.ShareCount <= 7) { 00995 Entry->ShareCount = Pfn1->u2.ShareCount; 00996 } 00997 else { 00998 Entry->ShareCount = 7; 00999 } 01000 if (Wsle->u1.e1.SameProtectAsProto == 1) { 01001 Entry->Protection = MI_GET_PROTECTION_FROM_SOFT_PTE(&Pfn1->OriginalPte); 01002 } else { 01003 Entry->Protection = Wsle->u1.e1.Protection; 01004 } 01005 } 01006 Entry += 1; 01007 } 01008 Wsle += 1; 01009 }while ((Entry < LastEntry) && (Wsle <= LastWsle)); 01010 01011 UNLOCK_WS (Process); 01012 if (Attached == TRUE) { 01013 KeDetachProcess (); 01014 } 01015 MmUnlockPages (Mdl); 01016 ExFreePool (Mdl); 01017 return STATUS_SUCCESS; 01018 }

ULONG MiQueryAddressState IN PVOID  Va,
IN PMMVAD  Vad,
IN PEPROCESS  TargetProcess,
OUT PULONG  ReturnedProtect
 

Definition at line 673 of file queryvm.c.

References ASSERT, FALSE, MI_CONVERT_FROM_PTE_PROTECTION, MI_VA_TO_VPN, MiCaptureSystemPte(), MiDoesPdeExistAndMakeValid(), MiDoesPpeExistAndMakeValid, MiGetPageProtection(), MiGetPdeAddress, MiGetPpeAddress, MiGetProtoPteAddress, MiGetPteAddress, MiIsPteDecommittedPage(), NULL, TRUE, and _MMPTE::u.

Referenced by NtQueryVirtualMemory().

00682 : 00683 00684 00685 Arguments: 00686 00687 Return Value: 00688 00689 Returns the state (MEM_COMMIT, MEM_RESERVE, MEM_PRIVATE). 00690 00691 Environment: 00692 00693 Kernel mode. Working set lock and address creation lock held. 00694 00695 --*/ 00696 00697 { 00698 PMMPTE PointerPte; 00699 PMMPTE PointerPde; 00700 PMMPTE PointerPpe; 00701 MMPTE CapturedProtoPte; 00702 PMMPTE ProtoPte; 00703 ULONG PteIsZero; 00704 ULONG State; 00705 ULONG Protect; 00706 ULONG Waited; 00707 LOGICAL PteDetected; 00708 00709 #ifdef LARGE_PAGES 00710 if (Vad->u.VadFlags.LargePages) { 00711 *ReturnedProtect = MI_CONVERT_FROM_PTE_PROTECTION ( 00712 Vad->u.VadFlags.Protection); 00713 return MEM_COMMIT; 00714 } 00715 #endif //LARGE_PAGES 00716 00717 PointerPpe = MiGetPpeAddress (Va); 00718 PointerPde = MiGetPdeAddress (Va); 00719 PointerPte = MiGetPteAddress (Va); 00720 00721 ASSERT ((Vad->StartingVpn <= MI_VA_TO_VPN (Va)) && 00722 (Vad->EndingVpn >= MI_VA_TO_VPN (Va))); 00723 00724 PteIsZero = TRUE; 00725 PteDetected = FALSE; 00726 00727 do { 00728 00729 if (!MiDoesPpeExistAndMakeValid(PointerPpe, 00730 TargetProcess, 00731 FALSE, 00732 &Waited)) { 00733 break; 00734 } 00735 00736 Waited = 0; 00737 00738 if (!MiDoesPdeExistAndMakeValid(PointerPde, 00739 TargetProcess, 00740 FALSE, 00741 &Waited)) { 00742 break; 00743 } 00744 00745 if (Waited == 0) { 00746 PteDetected = TRUE; 00747 } 00748 00749 } while (Waited != 0); 00750 00751 if (PteDetected == TRUE) { 00752 00753 // 00754 // A PTE exists at this address, see if it is zero. 00755 // 00756 00757 if (PointerPte->u.Long != 0) { 00758 00759 PteIsZero = FALSE; 00760 00761 // 00762 // There is a non-zero PTE at this address, use 00763 // it to build the information block. 00764 // 00765 00766 if (MiIsPteDecommittedPage (PointerPte)) { 00767 Protect = 0; 00768 State = MEM_RESERVE; 00769 } else { 00770 00771 State = MEM_COMMIT; 00772 if (Vad->u.VadFlags.PhysicalMapping == 1) { 00773 00774 // 00775 // Physical mapping, there is no corresponding 00776 // PFN element to get the page protection from. 00777 // 00778 00779 Protect = MI_CONVERT_FROM_PTE_PROTECTION ( 00780 Vad->u.VadFlags.Protection); 00781 } else { 00782 Protect = MiGetPageProtection (PointerPte, 00783 TargetProcess); 00784 00785 if ((PointerPte->u.Soft.Valid == 0) && 00786 (PointerPte->u.Soft.Prototype == 1) && 00787 (Vad->u.VadFlags.PrivateMemory == 0) && 00788 (Vad->ControlArea != (PCONTROL_AREA)NULL)) { 00789 00790 // 00791 // Make sure the protoPTE is committed. 00792 // 00793 00794 ProtoPte = MiGetProtoPteAddress(Vad, 00795 MI_VA_TO_VPN (Va)); 00796 CapturedProtoPte.u.Long = 0; 00797 if (ProtoPte) { 00798 CapturedProtoPte = MiCaptureSystemPte (ProtoPte, 00799 TargetProcess); 00800 } 00801 if (CapturedProtoPte.u.Long == 0) { 00802 State = MEM_RESERVE; 00803 Protect = 0; 00804 } 00805 } 00806 } 00807 } 00808 } 00809 } 00810 00811 if (PteIsZero) { 00812 00813 // 00814 // There is no PDE at this address, the template from 00815 // the VAD supplies the information unless the VAD is 00816 // for an image file. For image files the individual 00817 // protection is on the prototype PTE. 00818 // 00819 00820 // 00821 // Get the default protection information. 00822 // 00823 00824 State = MEM_RESERVE; 00825 Protect = 0; 00826 00827 if (Vad->u.VadFlags.PhysicalMapping == 1) { 00828 00829 // 00830 // Must be banked memory, just return reserved. 00831 // 00832 00833 NOTHING; 00834 00835 } else if ((Vad->u.VadFlags.PrivateMemory == 0) && 00836 (Vad->ControlArea != (PCONTROL_AREA)NULL)) { 00837 00838 // 00839 // This VAD refers to a section. Even though the PTE is 00840 // zero, the actual page may be committed in the section. 00841 // 00842 00843 ProtoPte = MiGetProtoPteAddress(Vad, MI_VA_TO_VPN (Va)); 00844 00845 CapturedProtoPte.u.Long = 0; 00846 if (ProtoPte) { 00847 CapturedProtoPte = MiCaptureSystemPte (ProtoPte, 00848 TargetProcess); 00849 } 00850 00851 if (CapturedProtoPte.u.Long != 0) { 00852 State = MEM_COMMIT; 00853 00854 if (Vad->u.VadFlags.ImageMap == 0) { 00855 Protect = MI_CONVERT_FROM_PTE_PROTECTION ( 00856 Vad->u.VadFlags.Protection); 00857 } else { 00858 00859 // 00860 // This is an image file, the protection is in the 00861 // prototype PTE. 00862 // 00863 00864 Protect = MiGetPageProtection (&CapturedProtoPte, 00865 TargetProcess); 00866 } 00867 } 00868 00869 } else { 00870 00871 // 00872 // Get the protection from the corresponding VAD. 00873 // 00874 00875 if (Vad->u.VadFlags.MemCommit) { 00876 State = MEM_COMMIT; 00877 Protect = MI_CONVERT_FROM_PTE_PROTECTION ( 00878 Vad->u.VadFlags.Protection); 00879 } 00880 } 00881 } 00882 00883 *ReturnedProtect = Protect; 00884 return State; 00885 }

NTSTATUS NtQueryVirtualMemory IN HANDLE  ProcessHandle,
IN PVOID  BaseAddress,
IN MEMORY_INFORMATION_CLASS  MemoryInformationClass,
OUT PVOID  MemoryInformation,
IN ULONG  MemoryInformationLength,
OUT PULONG ReturnLength  OPTIONAL
 

Definition at line 61 of file queryvm.c.

References _EPROCESS::AddressSpaceDeleted, _MMVAD::ControlArea, DbgPrint, _MMVAD::EndingVpn, EXCEPTION_EXECUTE_HANDLER, ExPageLockHandle, FALSE, _CONTROL_AREA::FilePointer, KeAttachProcess(), KeDetachProcess(), KernelMode, KPROCESSOR_MODE, _MMVAD::LeftChild, LOCK_WS_AND_ADDRESS_SPACE, MI_CONVERT_FROM_PTE_PROTECTION, MI_VA_TO_VPN, MI_VPN_TO_VA, MI_VPN_TO_VA_ENDING, MiGetNextVad, MiGetWorkingSetInfo(), MiQueryAddressState(), MiQueryRegionFor4kPage(), MM_DBG_SHOW_NT_CALLS, MM_HIGHEST_VAD_ADDRESS, MmLockPagableSectionByHandle(), MmUnlockPagableImageSection(), NT_SUCCESS, NTSTATUS(), NULL, ObDereferenceObject, ObQueryNameString(), ObReferenceObject, ObReferenceObjectByHandle(), PAGE_4K_ALIGN, PAGE_ALIGN, PAGE_SIZE, _EPROCESS::Pcb, ProbeForWrite(), ProbeForWriteUlong, PsGetCurrentProcess, PsProcessType, _MMVAD::RightChild, _MMVAD::StartingVpn, Status, TRUE, _MMVAD::u, UNLOCK_ADDRESS_SPACE, UNLOCK_WS_AND_ADDRESS_SPACE, UNLOCK_WS_UNSAFE, _EPROCESS::VadRoot, and _EPROCESS::Wow64Process.

Referenced by LdrpAccessResourceData(), LdrpInitialize(), RtlDebugCreateHeap(), RtlExtendHeap(), RtlPcToFileHeader(), and UnlockConsole().

00072 : 00073 00074 This function provides the capability to determine the state, 00075 protection, and type of a region of pages within the virtual address 00076 space of the subject process. 00077 00078 The state of the first page within the region is determined and then 00079 subsequent entries in the process address map are scanned from the 00080 base address upward until either the entire range of pages has been 00081 scanned or until a page with a nonmatching set of attributes is 00082 encountered. The region attributes, the length of the region of pages 00083 with matching attributes, and an appropriate status value are 00084 returned. 00085 00086 If the entire region of pages does not have a matching set of 00087 attributes, then the returned length parameter value can be used to 00088 calculate the address and length of the region of pages that was not 00089 scanned. 00090 00091 Arguments: 00092 00093 00094 ProcessHandle - An open handle to a process object. 00095 00096 BaseAddress - The base address of the region of pages to be 00097 queried. This value is rounded down to the next host-page- 00098 address boundary. 00099 00100 MemoryInformationClass - The memory information class about which 00101 to retrieve information. 00102 00103 MemoryInformation - A pointer to a buffer that receives the 00104 specified information. The format and content of the buffer 00105 depend on the specified information class. 00106 00107 00108 MemoryBasicInformation - Data type is PMEMORY_BASIC_INFORMATION. 00109 00110 MEMORY_BASIC_INFORMATION Structure 00111 00112 00113 ULONG RegionSize - The size of the region in bytes 00114 beginning at the base address in which all pages have 00115 identical attributes. 00116 00117 ULONG State - The state of the pages within the region. 00118 00119 State Values State Values 00120 00121 MEM_COMMIT - The state of the pages within the region 00122 is committed. 00123 00124 MEM_FREE - The state of the pages within the region 00125 is free. 00126 00127 MEM_RESERVE - The state of the pages within the 00128 region is reserved. 00129 00130 ULONG Protect - The protection of the pages within the 00131 region. 00132 00133 00134 Protect Values Protect Values 00135 00136 PAGE_NOACCESS - No access to the region of pages is 00137 allowed. An attempt to read, write, or execute 00138 within the region results in an access violation 00139 (i.e., a GP fault). 00140 00141 PAGE_EXECUTE - Execute access to the region of pages 00142 is allowed. An attempt to read or write within 00143 the region results in an access violation. 00144 00145 PAGE_READONLY - Read-only and execute access to the 00146 region of pages is allowed. An attempt to write 00147 within the region results in an access violation. 00148 00149 PAGE_READWRITE - Read, write, and execute access to 00150 the region of pages is allowed. If write access 00151 to the underlying section is allowed, then a 00152 single copy of the pages are shared. Otherwise, 00153 the pages are shared read-only/copy-on-write. 00154 00155 PAGE_GUARD - Read, write, and execute access to the 00156 region of pages is allowed; however, access to 00157 the region causes a "guard region entered" 00158 condition to be raised in the subject process. 00159 00160 PAGE_NOCACHE - Disable the placement of committed 00161 pages into the data cache. 00162 00163 ULONG Type - The type of pages within the region. 00164 00165 00166 Type Values 00167 00168 MEM_PRIVATE - The pages within the region are 00169 private. 00170 00171 MEM_MAPPED - The pages within the region are mapped 00172 into the view of a section. 00173 00174 MEM_IMAGE - The pages within the region are mapped 00175 into the view of an image section. 00176 00177 MemoryInformationLength - Specifies the length in bytes of 00178 the memory information buffer. 00179 00180 ReturnLength - An optional pointer which, if specified, 00181 receives the number of bytes placed in the process 00182 information buffer. 00183 00184 00185 Return Value: 00186 00187 Returns the status 00188 00189 TBS 00190 00191 00192 Environment: 00193 00194 Kernel mode. 00195 00196 --*/ 00197 00198 { 00199 KPROCESSOR_MODE PreviousMode; 00200 PEPROCESS TargetProcess; 00201 NTSTATUS Status; 00202 PMMVAD Vad; 00203 BOOLEAN PteIsZero; 00204 PVOID Va; 00205 BOOLEAN Found; 00206 SIZE_T TheRegionSize; 00207 ULONG NewProtect; 00208 ULONG NewState; 00209 PVOID FilePointer; 00210 ULONG_PTR BaseVpn; 00211 MEMORY_BASIC_INFORMATION Info; 00212 LOGICAL Attached; 00213 00214 Found = FALSE; 00215 PteIsZero = FALSE; 00216 00217 // 00218 // Make sure the user's buffer is large enough for the requested operation. 00219 // 00220 00221 // 00222 // Check argument validity. 00223 // 00224 switch (MemoryInformationClass) { 00225 case MemoryBasicInformation: 00226 if (MemoryInformationLength < sizeof(MEMORY_BASIC_INFORMATION)) { 00227 return STATUS_INFO_LENGTH_MISMATCH; 00228 } 00229 break; 00230 00231 case MemoryWorkingSetInformation: 00232 if (MemoryInformationLength < sizeof(ULONG)) { 00233 return STATUS_INFO_LENGTH_MISMATCH; 00234 } 00235 break; 00236 00237 case MemoryMappedFilenameInformation: 00238 FilePointer = NULL; 00239 break; 00240 default: 00241 return STATUS_INVALID_INFO_CLASS; 00242 } 00243 00244 PreviousMode = KeGetPreviousMode(); 00245 00246 if (PreviousMode != KernelMode) { 00247 00248 // 00249 // Check arguments. 00250 // 00251 00252 try { 00253 00254 ProbeForWrite(MemoryInformation, 00255 MemoryInformationLength, 00256 sizeof(ULONG_PTR)); 00257 00258 if (ARGUMENT_PRESENT(ReturnLength)) { 00259 ProbeForWriteUlong(ReturnLength); 00260 } 00261 00262 } except (EXCEPTION_EXECUTE_HANDLER) { 00263 00264 // 00265 // If an exception occurs during the probe or capture 00266 // of the initial values, then handle the exception and 00267 // return the exception code as the status value. 00268 // 00269 00270 return GetExceptionCode(); 00271 } 00272 } 00273 if (BaseAddress > MM_HIGHEST_USER_ADDRESS) { 00274 return STATUS_INVALID_PARAMETER; 00275 } 00276 00277 if ((BaseAddress >= MM_HIGHEST_VAD_ADDRESS) 00278 #if defined(MM_SHARED_USER_DATA_VA) 00279 || 00280 (PAGE_ALIGN(BaseAddress) == (PVOID)MM_SHARED_USER_DATA_VA) 00281 #endif 00282 ) { 00283 00284 // 00285 // Indicate a reserved area from this point on. 00286 // 00287 00288 if ( MemoryInformationClass == MemoryBasicInformation ) { 00289 00290 try { 00291 ((PMEMORY_BASIC_INFORMATION)MemoryInformation)->AllocationBase = 00292 (PCHAR) MM_HIGHEST_VAD_ADDRESS + 1; 00293 ((PMEMORY_BASIC_INFORMATION)MemoryInformation)->AllocationProtect = 00294 PAGE_READONLY; 00295 ((PMEMORY_BASIC_INFORMATION)MemoryInformation)->BaseAddress = 00296 PAGE_ALIGN(BaseAddress); 00297 ((PMEMORY_BASIC_INFORMATION)MemoryInformation)->RegionSize = 00298 ((PCHAR)MM_HIGHEST_USER_ADDRESS + 1) - 00299 (PCHAR)PAGE_ALIGN(BaseAddress); 00300 ((PMEMORY_BASIC_INFORMATION)MemoryInformation)->State = MEM_RESERVE; 00301 ((PMEMORY_BASIC_INFORMATION)MemoryInformation)->Protect = PAGE_NOACCESS; 00302 ((PMEMORY_BASIC_INFORMATION)MemoryInformation)->Type = MEM_PRIVATE; 00303 00304 if (ARGUMENT_PRESENT(ReturnLength)) { 00305 *ReturnLength = sizeof(MEMORY_BASIC_INFORMATION); 00306 } 00307 00308 #if defined(MM_SHARED_USER_DATA_VA) 00309 if (PAGE_ALIGN(BaseAddress) == (PVOID)MM_SHARED_USER_DATA_VA) { 00310 00311 // 00312 // This is the page that is double mapped between 00313 // user mode and kernel mode. 00314 // 00315 00316 ((PMEMORY_BASIC_INFORMATION)MemoryInformation)->AllocationBase = 00317 (PVOID)MM_SHARED_USER_DATA_VA; 00318 ((PMEMORY_BASIC_INFORMATION)MemoryInformation)->Protect = 00319 PAGE_READONLY; 00320 ((PMEMORY_BASIC_INFORMATION)MemoryInformation)->RegionSize = 00321 PAGE_SIZE; 00322 ((PMEMORY_BASIC_INFORMATION)MemoryInformation)->State = 00323 MEM_COMMIT; 00324 } 00325 #endif 00326 00327 } except (EXCEPTION_EXECUTE_HANDLER) { 00328 00329 // 00330 // Just return success. 00331 // 00332 } 00333 00334 return STATUS_SUCCESS; 00335 } else { 00336 return STATUS_INVALID_ADDRESS; 00337 } 00338 } 00339 00340 if ( ProcessHandle == NtCurrentProcess() ) { 00341 TargetProcess = PsGetCurrentProcess(); 00342 } else { 00343 Status = ObReferenceObjectByHandle ( ProcessHandle, 00344 PROCESS_QUERY_INFORMATION, 00345 PsProcessType, 00346 PreviousMode, 00347 (PVOID *)&TargetProcess, 00348 NULL ); 00349 00350 if (!NT_SUCCESS(Status)) { 00351 return Status; 00352 } 00353 } 00354 00355 if (MemoryInformationClass == MemoryWorkingSetInformation) { 00356 00357 MmLockPagableSectionByHandle(ExPageLockHandle); 00358 00359 Status = MiGetWorkingSetInfo (MemoryInformation, 00360 MemoryInformationLength, 00361 TargetProcess); 00362 MmUnlockPagableImageSection(ExPageLockHandle); 00363 00364 if ( ProcessHandle != NtCurrentProcess() ) { 00365 ObDereferenceObject (TargetProcess); 00366 } 00367 try { 00368 00369 if (ARGUMENT_PRESENT(ReturnLength)) { 00370 *ReturnLength = ((((PMEMORY_WORKING_SET_INFORMATION) 00371 MemoryInformation)->NumberOfEntries - 1) * 00372 sizeof(ULONG)) + 00373 sizeof(MEMORY_WORKING_SET_INFORMATION); 00374 } 00375 00376 } except (EXCEPTION_EXECUTE_HANDLER) { 00377 } 00378 00379 return STATUS_SUCCESS; 00380 } 00381 00382 // 00383 // If the specified process is not the current process, attach 00384 // to the specified process. 00385 // 00386 00387 if ( ProcessHandle != NtCurrentProcess() ) { 00388 KeAttachProcess (&TargetProcess->Pcb); 00389 Attached = TRUE; 00390 } 00391 else { 00392 Attached = FALSE; 00393 } 00394 00395 // 00396 // Get working set mutex and block APCs. 00397 // 00398 00399 LOCK_WS_AND_ADDRESS_SPACE (TargetProcess); 00400 00401 // 00402 // Make sure the address space was not deleted, if so, return an error. 00403 // 00404 00405 if (TargetProcess->AddressSpaceDeleted != 0) { 00406 UNLOCK_WS_AND_ADDRESS_SPACE (TargetProcess); 00407 if (Attached == TRUE) { 00408 KeDetachProcess(); 00409 ObDereferenceObject (TargetProcess); 00410 } 00411 return STATUS_PROCESS_IS_TERMINATING; 00412 } 00413 00414 // 00415 // Locate the VAD that contains the base address or the VAD 00416 // which follows the base address. 00417 // 00418 00419 Vad = TargetProcess->VadRoot; 00420 BaseVpn = MI_VA_TO_VPN (BaseAddress); 00421 00422 for (;;) { 00423 00424 if (Vad == (PMMVAD)NULL) { 00425 break; 00426 } 00427 00428 if ((BaseVpn >= Vad->StartingVpn) && 00429 (BaseVpn <= Vad->EndingVpn)) { 00430 Found = TRUE; 00431 break; 00432 } 00433 00434 if (BaseVpn < Vad->StartingVpn) { 00435 if (Vad->LeftChild == (PMMVAD)NULL) { 00436 break; 00437 } 00438 Vad = Vad->LeftChild; 00439 00440 } else { 00441 if (BaseVpn < Vad->EndingVpn) { 00442 break; 00443 } 00444 if (Vad->RightChild == (PMMVAD)NULL) { 00445 break; 00446 } 00447 Vad = Vad->RightChild; 00448 } 00449 } 00450 00451 if (!Found) { 00452 00453 // 00454 // There is no virtual address allocated at the base 00455 // address. Return the size of the hole starting at 00456 // the base address. 00457 // 00458 00459 if (Vad == NULL) { 00460 TheRegionSize = ((PCHAR)MM_HIGHEST_VAD_ADDRESS + 1) - 00461 (PCHAR)PAGE_ALIGN(BaseAddress); 00462 } else { 00463 if (Vad->StartingVpn < BaseVpn) { 00464 00465 // 00466 // We are looking at the Vad which occupies the range 00467 // just before the desired range. Get the next Vad. 00468 // 00469 00470 Vad = MiGetNextVad (Vad); 00471 if (Vad == NULL) { 00472 TheRegionSize = ((PCHAR)MM_HIGHEST_VAD_ADDRESS + 1) - 00473 (PCHAR)PAGE_ALIGN(BaseAddress); 00474 } else { 00475 TheRegionSize = (PCHAR)MI_VPN_TO_VA (Vad->StartingVpn) - 00476 (PCHAR)PAGE_ALIGN(BaseAddress); 00477 } 00478 } else { 00479 TheRegionSize = (PCHAR)MI_VPN_TO_VA (Vad->StartingVpn) - 00480 (PCHAR)PAGE_ALIGN(BaseAddress); 00481 } 00482 } 00483 00484 UNLOCK_WS_AND_ADDRESS_SPACE (TargetProcess); 00485 00486 if (Attached == TRUE) { 00487 KeDetachProcess(); 00488 ObDereferenceObject (TargetProcess); 00489 } 00490 00491 // 00492 // Establish an exception handler and write the information and 00493 // returned length. 00494 // 00495 00496 if ( MemoryInformationClass == MemoryBasicInformation ) { 00497 try { 00498 00499 ((PMEMORY_BASIC_INFORMATION)MemoryInformation)->AllocationBase = 00500 NULL; 00501 ((PMEMORY_BASIC_INFORMATION)MemoryInformation)->AllocationProtect = 00502 0; 00503 ((PMEMORY_BASIC_INFORMATION)MemoryInformation)->BaseAddress = 00504 PAGE_ALIGN(BaseAddress); 00505 ((PMEMORY_BASIC_INFORMATION)MemoryInformation)->RegionSize = 00506 TheRegionSize; 00507 ((PMEMORY_BASIC_INFORMATION)MemoryInformation)->State = MEM_FREE; 00508 ((PMEMORY_BASIC_INFORMATION)MemoryInformation)->Protect = PAGE_NOACCESS; 00509 ((PMEMORY_BASIC_INFORMATION)MemoryInformation)->Type = 0; 00510 00511 if (ARGUMENT_PRESENT(ReturnLength)) { 00512 *ReturnLength = sizeof(MEMORY_BASIC_INFORMATION); 00513 } 00514 00515 } except (EXCEPTION_EXECUTE_HANDLER) { 00516 00517 // 00518 // Just return success. 00519 // 00520 } 00521 00522 return STATUS_SUCCESS; 00523 } 00524 return STATUS_INVALID_ADDRESS; 00525 } 00526 00527 // 00528 // Found a VAD. 00529 // 00530 00531 Va = PAGE_ALIGN(BaseAddress); 00532 Info.BaseAddress = Va; 00533 00534 // 00535 // There is a page mapped at the base address. 00536 // 00537 00538 if (Vad->u.VadFlags.PrivateMemory) { 00539 Info.Type = MEM_PRIVATE; 00540 } else if (Vad->u.VadFlags.ImageMap == 0) { 00541 Info.Type = MEM_MAPPED; 00542 00543 if ( MemoryInformationClass == MemoryMappedFilenameInformation ) { 00544 if (Vad->ControlArea) { 00545 FilePointer = Vad->ControlArea->FilePointer; 00546 } 00547 if ( !FilePointer ) { 00548 FilePointer = (PVOID)1; 00549 } else { 00550 ObReferenceObject(FilePointer); 00551 } 00552 } 00553 00554 } else { 00555 Info.Type = MEM_IMAGE; 00556 } 00557 00558 Info.State = MiQueryAddressState (Va, Vad, TargetProcess, &Info.Protect); 00559 00560 Va = (PVOID)((PCHAR)Va + PAGE_SIZE); 00561 00562 while (MI_VA_TO_VPN (Va) <= Vad->EndingVpn) { 00563 00564 NewState = MiQueryAddressState (Va, 00565 Vad, 00566 TargetProcess, 00567 &NewProtect); 00568 00569 if ((NewState != Info.State) || (NewProtect != Info.Protect)) { 00570 00571 // 00572 // The state for this address does not match, calculate 00573 // size and return. 00574 // 00575 00576 break; 00577 } 00578 Va = (PVOID)((PCHAR)Va + PAGE_SIZE); 00579 } // end while 00580 00581 Info.RegionSize = ((PCHAR)Va - (PCHAR)Info.BaseAddress); 00582 Info.AllocationBase = MI_VPN_TO_VA (Vad->StartingVpn); 00583 Info.AllocationProtect = MI_CONVERT_FROM_PTE_PROTECTION ( 00584 Vad->u.VadFlags.Protection); 00585 00586 // 00587 // A range has been found, release the mutexes, deattach from the 00588 // target process and return the information. 00589 // 00590 00591 #if !(defined(_MIALT4K_)) 00592 00593 UNLOCK_WS_AND_ADDRESS_SPACE (TargetProcess); 00594 00595 #else 00596 00597 UNLOCK_WS_UNSAFE (TargetProcess); 00598 00599 if (TargetProcess->Wow64Process != NULL) { 00600 00601 Info.BaseAddress = PAGE_4K_ALIGN(BaseAddress); 00602 00603 MiQueryRegionFor4kPage(Info.BaseAddress, 00604 MI_VPN_TO_VA_ENDING(Vad->EndingVpn), 00605 &Info.RegionSize, 00606 &Info.State, 00607 &Info.Protect, 00608 TargetProcess); 00609 } 00610 00611 UNLOCK_ADDRESS_SPACE (TargetProcess); 00612 00613 #endif 00614 00615 if (Attached == TRUE) { 00616 KeDetachProcess(); 00617 ObDereferenceObject (TargetProcess); 00618 } 00619 00620 #if DBG 00621 if (MmDebug & MM_DBG_SHOW_NT_CALLS) { 00622 if ( !MmWatchProcess ) { 00623 DbgPrint("queryvm base %lx allocbase %lx protect %lx size %lx\n", 00624 Info.BaseAddress, Info.AllocationBase, Info.AllocationProtect, 00625 Info.RegionSize); 00626 DbgPrint(" state %lx protect %lx type %lx\n", 00627 Info.State, Info.Protect, Info.Type); 00628 } 00629 } 00630 #endif //DBG 00631 00632 if ( MemoryInformationClass == MemoryBasicInformation ) { 00633 try { 00634 00635 *(PMEMORY_BASIC_INFORMATION)MemoryInformation = Info; 00636 00637 if (ARGUMENT_PRESENT(ReturnLength)) { 00638 *ReturnLength = sizeof(MEMORY_BASIC_INFORMATION); 00639 } 00640 00641 } except (EXCEPTION_EXECUTE_HANDLER) { 00642 } 00643 return STATUS_SUCCESS; 00644 } 00645 00646 // 00647 // Try to return the name of the file that is mapped. 00648 // 00649 00650 if ( !FilePointer ) { 00651 return STATUS_INVALID_ADDRESS; 00652 } else if ( FilePointer == (PVOID)1 ) { 00653 return STATUS_FILE_INVALID; 00654 } 00655 00656 // 00657 // We have a referenced pointer to the file. Call ObQueryNameString 00658 // and get the file name 00659 // 00660 00661 Status = ObQueryNameString( 00662 FilePointer, 00663 MemoryInformation, 00664 MemoryInformationLength, 00665 ReturnLength 00666 ); 00667 ObDereferenceObject(FilePointer); 00668 return Status; 00669 }


Variable Documentation

POBJECT_TYPE IoFileObjectType
 

Definition at line 25 of file queryvm.c.


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