ReactOS  r75214
mm.h File Reference
#include <internal/arch/mm.h>
Include dependency graph for mm.h:

Go to the source code of this file.

Classes

struct  _MM_SECTION_SEGMENT
 
struct  _MM_IMAGE_SECTION_OBJECT
 
struct  _ROS_SECTION_OBJECT
 
struct  _MEMORY_AREA
 
struct  _MM_RMAP_ENTRY
 
struct  _MMPFNENTRY
 
struct  _MMPFN
 
struct  _MMPFNLIST
 
struct  _MM_MEMORY_CONSUMER
 
struct  _MM_REGION
 
struct  _MMFREE_POOL_ENTRY
 
struct  _MM_PAGED_POOL_INFO
 

Macros

#define MMDBG_COPY_WRITE   0x00000001
 
#define MMDBG_COPY_PHYSICAL   0x00000002
 
#define MMDBG_COPY_UNSAFE   0x00000004
 
#define MMDBG_COPY_CACHED   0x00000008
 
#define MMDBG_COPY_UNCACHED   0x00000010
 
#define MMDBG_COPY_WRITE_COMBINED   0x00000020
 
#define MMDBG_COPY_MAX_SIZE   0x8
 
#define MI_STATIC_MEMORY_AREAS   (13)
 
#define MEMORY_AREA_SECTION_VIEW   (1)
 
#define MEMORY_AREA_CACHE   (2)
 
#define MEMORY_AREA_OWNED_BY_ARM3   (15)
 
#define MEMORY_AREA_STATIC   (0x80000000)
 
#define MM_VIRTMEM_GRANULARITY   (64 * 1024)
 
#define STATUS_MM_RESTART_OPERATION   ((NTSTATUS)0xD0000001)
 
#define PAGE_WRITETHROUGH   (1024)
 
#define PAGE_SYSTEM   (2048)
 
#define SEC_PHYSICALMEMORY   (0x80000000)
 
#define MM_PAGEFILE_SEGMENT   (0x1)
 
#define MM_DATAFILE_SEGMENT   (0x2)
 
#define MC_CACHE   (0)
 
#define MC_USER   (1)
 
#define MC_SYSTEM   (2)
 
#define MC_MAXIMUM   (3)
 
#define PAGED_POOL_MASK   1
 
#define MUST_SUCCEED_POOL_MASK   2
 
#define CACHE_ALIGNED_POOL_MASK   4
 
#define QUOTA_POOL_MASK   8
 
#define SESSION_POOL_MASK   32
 
#define VERIFIER_POOL_MASK   64
 
#define MM_ROUND_UP(x, s)   ((PVOID)(((ULONG_PTR)(x)+(s)-1) & ~((ULONG_PTR)(s)-1)))
 
#define MM_ROUND_DOWN(x, s)   ((PVOID)(((ULONG_PTR)(x)) & ~((ULONG_PTR)(s)-1)))
 
#define PAGE_FLAGS_VALID_FOR_SECTION
 
#define PAGE_IS_READABLE
 
#define PAGE_IS_WRITABLE
 
#define PAGE_IS_EXECUTABLE
 
#define PAGE_IS_WRITECOPY
 
#define MM_WAIT_ENTRY   0x7ffffc00
 
#define InterlockedCompareExchangePte(PointerPte, Exchange, Comperand)   InterlockedCompareExchange((PLONG)(PointerPte), Exchange, Comperand)
 
#define InterlockedExchangePte(PointerPte, Value)   InterlockedExchange((PLONG)(PointerPte), Value)
 
#define MA_GetStartingAddress(_MemoryArea)   ((_MemoryArea)->StartingVpn << PAGE_SHIFT)
 
#define MA_GetEndingAddress(_MemoryArea)   (((_MemoryArea)->EndingVpn + 1) << PAGE_SHIFT)
 
#define MI_SET_USAGE(x)
 
#define MI_SET_PROCESS2(x)
 
#define StartOfAllocation   ReadInProgress
 
#define EndOfAllocation   WriteInProgress
 
#define MM_FREE_POOL_SIGNATURE   'ARM3'
 
#define MmDeleteHyperspaceMapping(x)   MiUnmapPageInHyperSpace(HyperProcess, x, HyperIrql);
 

Typedefs

typedef ULONG_PTR SWAPENTRY
 
typedef struct _MM_SECTION_SEGMENT MM_SECTION_SEGMENT
 
typedef struct
_MM_SECTION_SEGMENT
PMM_SECTION_SEGMENT
 
typedef struct
_MM_IMAGE_SECTION_OBJECT 
MM_IMAGE_SECTION_OBJECT
 
typedef struct
_MM_IMAGE_SECTION_OBJECT
PMM_IMAGE_SECTION_OBJECT
 
typedef struct _ROS_SECTION_OBJECT ROS_SECTION_OBJECT
 
typedef struct
_ROS_SECTION_OBJECT
PROS_SECTION_OBJECT
 
typedef struct _MEMORY_AREA MEMORY_AREA
 
typedef struct _MEMORY_AREAPMEMORY_AREA
 
typedef struct _MM_RMAP_ENTRY MM_RMAP_ENTRY
 
typedef struct _MM_RMAP_ENTRYPMM_RMAP_ENTRY
 
typedef enum _MI_PFN_USAGES MI_PFN_USAGES
 
typedef struct _MMPFNENTRY MMPFNENTRY
 
typedef struct _MMPFN MMPFN
 
typedef struct _MMPFNPMMPFN
 
typedef struct _MMPFNLIST MMPFNLIST
 
typedef struct _MMPFNLISTPMMPFNLIST
 
typedef struct _MM_MEMORY_CONSUMER MM_MEMORY_CONSUMER
 
typedef struct
_MM_MEMORY_CONSUMER
PMM_MEMORY_CONSUMER
 
typedef struct _MM_REGION MM_REGION
 
typedef struct _MM_REGIONPMM_REGION
 
typedef struct _MMFREE_POOL_ENTRY MMFREE_POOL_ENTRY
 
typedef struct _MMFREE_POOL_ENTRYPMMFREE_POOL_ENTRY
 
typedef struct _MM_PAGED_POOL_INFO MM_PAGED_POOL_INFO
 
typedef struct
_MM_PAGED_POOL_INFO
PMM_PAGED_POOL_INFO
 
typedef VOID(* PMM_ALTER_REGION_FUNC )(PMMSUPPORT AddressSpace, PVOID BaseAddress, SIZE_T Length, ULONG OldType, ULONG OldProtect, ULONG NewType, ULONG NewProtect)
 
typedef VOID(* PMM_FREE_PAGE_FUNC )(PVOID Context, PMEMORY_AREA MemoryArea, PVOID Address, PFN_NUMBER Page, SWAPENTRY SwapEntry, BOOLEAN Dirty)
 

Enumerations

enum  _MI_PFN_USAGES {
  MI_USAGE_NOT_SET = 0, MI_USAGE_PAGED_POOL, MI_USAGE_NONPAGED_POOL, MI_USAGE_NONPAGED_POOL_EXPANSION,
  MI_USAGE_KERNEL_STACK, MI_USAGE_KERNEL_STACK_EXPANSION, MI_USAGE_SYSTEM_PTE, MI_USAGE_VAD,
  MI_USAGE_PEB_TEB, MI_USAGE_SECTION, MI_USAGE_PAGE_TABLE, MI_USAGE_PAGE_DIRECTORY,
  MI_USAGE_LEGACY_PAGE_DIRECTORY, MI_USAGE_DRIVER_PAGE, MI_USAGE_CONTINOUS_ALLOCATION, MI_USAGE_MDL,
  MI_USAGE_DEMAND_ZERO, MI_USAGE_ZERO_LOOP, MI_USAGE_CACHE, MI_USAGE_PFN_DATABASE,
  MI_USAGE_BOOT_DRIVER, MI_USAGE_INIT_MEMORY, MI_USAGE_FREE_PAGE
}
 

Functions

NTSTATUS NTAPI MmDbgCopyMemory (IN ULONG64 Address, IN PVOID Buffer, IN ULONG Size, IN ULONG Flags)
 
BOOLEAN NTAPI MmIsSessionAddress (IN PVOID Address)
 
ULONG NTAPI MmGetSessionId (IN PEPROCESS Process)
 
ULONG NTAPI MmGetSessionIdEx (IN PEPROCESS Process)
 
NTSTATUS NTAPI MmCreateMemoryArea (PMMSUPPORT AddressSpace, ULONG Type, PVOID *BaseAddress, SIZE_T Length, ULONG Protection, PMEMORY_AREA *Result, ULONG AllocationFlags, ULONG AllocationGranularity)
 
PMEMORY_AREA NTAPI MmLocateMemoryAreaByAddress (PMMSUPPORT AddressSpace, PVOID Address)
 
NTSTATUS NTAPI MmFreeMemoryArea (PMMSUPPORT AddressSpace, PMEMORY_AREA MemoryArea, PMM_FREE_PAGE_FUNC FreePage, PVOID FreePageContext)
 
VOID NTAPI MiRosCleanupMemoryArea (PEPROCESS Process, PMMVAD Vad)
 
PMEMORY_AREA NTAPI MmLocateMemoryAreaByRegion (PMMSUPPORT AddressSpace, PVOID Address, SIZE_T Length)
 
PVOID NTAPI MmFindGap (PMMSUPPORT AddressSpace, SIZE_T Length, ULONG_PTR Granularity, BOOLEAN TopDown)
 
VOID NTAPI MiRosCheckMemoryAreas (PMMSUPPORT AddressSpace)
 
VOID NTAPI MiCheckAllProcessMemoryAreas (VOID)
 
VOID NTAPI MiInitializeNonPagedPool (VOID)
 
PVOID NTAPI MiAllocatePoolPages (IN POOL_TYPE PoolType, IN SIZE_T SizeInBytes)
 
POOL_TYPE NTAPI MmDeterminePoolType (IN PVOID VirtualAddress)
 
ULONG NTAPI MiFreePoolPages (IN PVOID StartingAddress)
 
BOOLEAN NTAPI MiRaisePoolQuota (IN POOL_TYPE PoolType, IN ULONG CurrentMaxQuota, OUT PULONG NewMaxQuota)
 
VOID NTAPI MmBuildMdlFromPages (PMDL Mdl, PPFN_NUMBER Pages)
 
VOID NTAPI MmInit1 (VOID)
 
BOOLEAN NTAPI MmInitSystem (IN ULONG Phase, IN PLOADER_PARAMETER_BLOCK LoaderBlock)
 
SWAPENTRY NTAPI MmAllocSwapPage (VOID)
 
VOID NTAPI MmFreeSwapPage (SWAPENTRY Entry)
 
VOID NTAPI MmInitPagingFile (VOID)
 
BOOLEAN NTAPI MmIsFileObjectAPagingFile (PFILE_OBJECT FileObject)
 
NTSTATUS NTAPI MmReadFromSwapPage (SWAPENTRY SwapEntry, PFN_NUMBER Page)
 
NTSTATUS NTAPI MmWriteToSwapPage (SWAPENTRY SwapEntry, PFN_NUMBER Page)
 
VOID NTAPI MmShowOutOfSpaceMessagePagingFile (VOID)
 
NTSTATUS NTAPI MiReadPageFile (_In_ PFN_NUMBER Page, _In_ ULONG PageFileIndex, _In_ ULONG_PTR PageFileOffset)
 
NTSTATUS NTAPI MmInitializeProcessAddressSpace (IN PEPROCESS Process, IN PEPROCESS Clone OPTIONAL, IN PVOID Section OPTIONAL, IN OUT PULONG Flags, IN POBJECT_NAME_INFORMATION *AuditName OPTIONAL)
 
NTSTATUS NTAPI MmCreatePeb (IN PEPROCESS Process, IN PINITIAL_PEB InitialPeb, OUT PPEB *BasePeb)
 
NTSTATUS NTAPI MmCreateTeb (IN PEPROCESS Process, IN PCLIENT_ID ClientId, IN PINITIAL_TEB InitialTeb, OUT PTEB *BaseTeb)
 
VOID NTAPI MmDeleteTeb (struct _EPROCESS *Process, PTEB Teb)
 
VOID NTAPI MmCleanProcessAddressSpace (IN PEPROCESS Process)
 
NTSTATUS NTAPI MmDeleteProcessAddressSpace (IN PEPROCESS Process)
 
ULONG NTAPI MmGetSessionLocaleId (VOID)
 
NTSTATUS NTAPI MmSetMemoryPriorityProcess (IN PEPROCESS Process, IN UCHAR MemoryPriority)
 
NTSTATUS NTAPI MmPageFault (ULONG Cs, PULONG Eip, PULONG Eax, ULONG Cr2, ULONG ErrorCode)
 
VOID NTAPI MiInitializeSpecialPool (VOID)
 
BOOLEAN NTAPI MmUseSpecialPool (IN SIZE_T NumberOfBytes, IN ULONG Tag)
 
BOOLEAN NTAPI MmIsSpecialPoolAddress (IN PVOID P)
 
BOOLEAN NTAPI MmIsSpecialPoolAddressFree (IN PVOID P)
 
PVOID NTAPI MmAllocateSpecialPool (IN SIZE_T NumberOfBytes, IN ULONG Tag, IN POOL_TYPE PoolType, IN ULONG SpecialType)
 
VOID NTAPI MmFreeSpecialPool (IN PVOID P)
 
NTSTATUS NTAPI MmAccessFault (IN BOOLEAN StoreInstruction, IN PVOID Address, IN KPROCESSOR_MODE Mode, IN PVOID TrapInformation)
 
NTSTATUS NTAPI MiCopyFromUserPage (PFN_NUMBER NewPage, PFN_NUMBER OldPage)
 
PVOID NTAPI MmCreateKernelStack (BOOLEAN GuiStack, UCHAR Node)
 
VOID NTAPI MmDeleteKernelStack (PVOID Stack, BOOLEAN GuiStack)
 
VOID NTAPI MmInitializeMemoryConsumer (ULONG Consumer, NTSTATUS(*Trim)(ULONG Target, ULONG Priority, PULONG NrFreed))
 
VOID NTAPI MmInitializeBalancer (ULONG NrAvailablePages, ULONG NrSystemPages)
 
NTSTATUS NTAPI MmReleasePageMemoryConsumer (ULONG Consumer, PFN_NUMBER Page)
 
NTSTATUS NTAPI MmRequestPageMemoryConsumer (ULONG Consumer, BOOLEAN MyWait, PPFN_NUMBER AllocatedPage)
 
VOID NTAPI MiInitBalancerThread (VOID)
 
VOID NTAPI MmRebalanceMemoryConsumers (VOID)
 
VOID NTAPI MmSetRmapListHeadPage (PFN_NUMBER Page, struct _MM_RMAP_ENTRY *ListHead)
 
struct _MM_RMAP_ENTRY *NTAPI MmGetRmapListHeadPage (PFN_NUMBER Page)
 
VOID NTAPI MmInsertRmap (PFN_NUMBER Page, struct _EPROCESS *Process, PVOID Address)
 
VOID NTAPI MmDeleteAllRmaps (PFN_NUMBER Page, PVOID Context, VOID(*DeleteMapping)(PVOID Context, struct _EPROCESS *Process, PVOID Address))
 
VOID NTAPI MmDeleteRmap (PFN_NUMBER Page, struct _EPROCESS *Process, PVOID Address)
 
VOID NTAPI MmInitializeRmapList (VOID)
 
VOID NTAPI MmSetCleanAllRmaps (PFN_NUMBER Page)
 
VOID NTAPI MmSetDirtyAllRmaps (PFN_NUMBER Page)
 
BOOLEAN NTAPI MmIsDirtyPageRmap (PFN_NUMBER Page)
 
NTSTATUS NTAPI MmPageOutPhysicalAddress (PFN_NUMBER Page)
 
FORCEINLINE PMMPFN MiGetPfnEntry (IN PFN_NUMBER Pfn)
 
FORCEINLINE PFN_NUMBER MiGetPfnEntryIndex (IN PMMPFN Pfn1)
 
PFN_NUMBER NTAPI MmGetLRUNextUserPage (PFN_NUMBER PreviousPage)
 
PFN_NUMBER NTAPI MmGetLRUFirstUserPage (VOID)
 
VOID NTAPI MmInsertLRULastUserPage (PFN_NUMBER Page)
 
VOID NTAPI MmRemoveLRUUserPage (PFN_NUMBER Page)
 
VOID NTAPI MmDumpArmPfnDatabase (IN BOOLEAN StatusOnly)
 
VOID NTAPI MmZeroPageThread (VOID)
 
PVOID NTAPI MiMapPageInHyperSpace (IN PEPROCESS Process, IN PFN_NUMBER Page, IN PKIRQL OldIrql)
 
VOID NTAPI MiUnmapPageInHyperSpace (IN PEPROCESS Process, IN PVOID Address, IN KIRQL OldIrql)
 
PVOID NTAPI MiMapPagesInZeroSpace (IN PMMPFN Pfn1, IN PFN_NUMBER NumberOfPages)
 
VOID NTAPI MiUnmapPagesInZeroSpace (IN PVOID VirtualAddress, IN PFN_NUMBER NumberOfPages)
 
FORCEINLINE PVOID MmCreateHyperspaceMapping (IN PFN_NUMBER Page)
 
NTSTATUS NTAPI MmCreateVirtualMapping (struct _EPROCESS *Process, PVOID Address, ULONG flProtect, PPFN_NUMBER Pages, ULONG PageCount)
 
NTSTATUS NTAPI MmCreateVirtualMappingUnsafe (struct _EPROCESS *Process, PVOID Address, ULONG flProtect, PPFN_NUMBER Pages, ULONG PageCount)
 
ULONG NTAPI MmGetPageProtect (struct _EPROCESS *Process, PVOID Address)
 
VOID NTAPI MmSetPageProtect (struct _EPROCESS *Process, PVOID Address, ULONG flProtect)
 
BOOLEAN NTAPI MmIsPagePresent (struct _EPROCESS *Process, PVOID Address)
 
BOOLEAN NTAPI MmIsDisabledPage (struct _EPROCESS *Process, PVOID Address)
 
VOID NTAPI MmInitGlobalKernelPageDirectory (VOID)
 
VOID NTAPI MmGetPageFileMapping (struct _EPROCESS *Process, PVOID Address, SWAPENTRY *SwapEntry)
 
VOID NTAPI MmDeletePageFileMapping (struct _EPROCESS *Process, PVOID Address, SWAPENTRY *SwapEntry)
 
NTSTATUS NTAPI MmCreatePageFileMapping (struct _EPROCESS *Process, PVOID Address, SWAPENTRY SwapEntry)
 
BOOLEAN NTAPI MmIsPageSwapEntry (struct _EPROCESS *Process, PVOID Address)
 
VOID NTAPI MmSetDirtyPage (struct _EPROCESS *Process, PVOID Address)
 
PFN_NUMBER NTAPI MmAllocPage (ULONG Consumer)
 
VOID NTAPI MmDereferencePage (PFN_NUMBER Page)
 
VOID NTAPI MmReferencePage (PFN_NUMBER Page)
 
ULONG NTAPI MmGetReferenceCountPage (PFN_NUMBER Page)
 
BOOLEAN NTAPI MmIsPageInUse (PFN_NUMBER Page)
 
VOID NTAPI MmSetSavedSwapEntryPage (PFN_NUMBER Page, SWAPENTRY SavedSwapEntry)
 
SWAPENTRY NTAPI MmGetSavedSwapEntryPage (PFN_NUMBER Page)
 
VOID NTAPI MmSetCleanPage (struct _EPROCESS *Process, PVOID Address)
 
VOID NTAPI MmDeletePageTable (struct _EPROCESS *Process, PVOID Address)
 
PFN_NUMBER NTAPI MmGetPfnForProcess (struct _EPROCESS *Process, PVOID Address)
 
BOOLEAN NTAPI MmCreateProcessAddressSpace (IN ULONG MinWs, IN PEPROCESS Dest, IN PULONG_PTR DirectoryTableBase)
 
NTSTATUS NTAPI MmInitializeHandBuiltProcess (IN PEPROCESS Process, IN PULONG_PTR DirectoryTableBase)
 
NTSTATUS NTAPI MmInitializeHandBuiltProcess2 (IN PEPROCESS Process)
 
NTSTATUS NTAPI MmSetExecuteOptions (IN ULONG ExecuteOptions)
 
NTSTATUS NTAPI MmGetExecuteOptions (IN PULONG ExecuteOptions)
 
VOID NTAPI MmDeleteVirtualMapping (struct _EPROCESS *Process, PVOID Address, BOOLEAN *WasDirty, PPFN_NUMBER Page)
 
BOOLEAN NTAPI MmIsDirtyPage (struct _EPROCESS *Process, PVOID Address)
 
NTSTATUS MmTrimUserMemory (ULONG Target, ULONG Priority, PULONG NrFreedPages)
 
NTSTATUS NTAPI MmAlterRegion (PMMSUPPORT AddressSpace, PVOID BaseAddress, PLIST_ENTRY RegionListHead, PVOID StartAddress, SIZE_T Length, ULONG NewType, ULONG NewProtect, PMM_ALTER_REGION_FUNC AlterFunc)
 
VOID NTAPI MmInitializeRegion (PLIST_ENTRY RegionListHead, SIZE_T Length, ULONG Type, ULONG Protect)
 
PMM_REGION NTAPI MmFindRegion (PVOID BaseAddress, PLIST_ENTRY RegionListHead, PVOID Address, PVOID *RegionBaseAddress)
 
VOID NTAPI MmGetImageInformation (OUT PSECTION_IMAGE_INFORMATION ImageInformation)
 
PFILE_OBJECT NTAPI MmGetFileObjectForSection (IN PVOID Section)
 
NTSTATUS NTAPI MmGetFileNameForAddress (IN PVOID Address, OUT PUNICODE_STRING ModuleName)
 
NTSTATUS NTAPI MmGetFileNameForSection (IN PVOID Section, OUT POBJECT_NAME_INFORMATION *ModuleName)
 
NTSTATUS NTAPI MmQuerySectionView (PMEMORY_AREA MemoryArea, PVOID Address, PMEMORY_BASIC_INFORMATION Info, PSIZE_T ResultLength)
 
NTSTATUS NTAPI MmProtectSectionView (PMMSUPPORT AddressSpace, PMEMORY_AREA MemoryArea, PVOID BaseAddress, SIZE_T Length, ULONG Protect, PULONG OldProtect)
 
NTSTATUS NTAPI MmInitSectionImplementation (VOID)
 
NTSTATUS NTAPI MmNotPresentFaultSectionView (PMMSUPPORT AddressSpace, MEMORY_AREA *MemoryArea, PVOID Address, BOOLEAN Locked)
 
NTSTATUS NTAPI MmPageOutSectionView (PMMSUPPORT AddressSpace, PMEMORY_AREA MemoryArea, PVOID Address, ULONG_PTR Entry)
 
NTSTATUS NTAPI MmCreatePhysicalMemorySection (VOID)
 
NTSTATUS NTAPI MmAccessFaultSectionView (PMMSUPPORT AddressSpace, MEMORY_AREA *MemoryArea, PVOID Address)
 
VOID NTAPI MmFreeSectionSegments (PFILE_OBJECT FileObject)
 
VOID NTAPI MiReloadBootLoadedDrivers (IN PLOADER_PARAMETER_BLOCK LoaderBlock)
 
BOOLEAN NTAPI MiInitializeLoadedModuleList (IN PLOADER_PARAMETER_BLOCK LoaderBlock)
 
NTSTATUS NTAPI MmLoadSystemImage (IN PUNICODE_STRING FileName, IN PUNICODE_STRING NamePrefix OPTIONAL, IN PUNICODE_STRING LoadedName OPTIONAL, IN ULONG Flags, OUT PVOID *ModuleObject, OUT PVOID *ImageBaseAddress)
 
NTSTATUS NTAPI MmUnloadSystemImage (IN PVOID ImageHandle)
 
NTSTATUS NTAPI MmCheckSystemImage (IN HANDLE ImageHandle, IN BOOLEAN PurgeSection)
 
NTSTATUS NTAPI MmCallDllInitialize (IN PLDR_DATA_TABLE_ENTRY LdrEntry, IN PLIST_ENTRY ListHead)
 
NTSTATUS NTAPI MmGrowKernelStack (IN PVOID StackPointer)
 
FORCEINLINE VOID MmLockAddressSpace (PMMSUPPORT AddressSpace)
 
FORCEINLINE VOID MmUnlockAddressSpace (PMMSUPPORT AddressSpace)
 
FORCEINLINE PEPROCESS MmGetAddressSpaceOwner (IN PMMSUPPORT AddressSpace)
 
FORCEINLINE PMMSUPPORT MmGetCurrentAddressSpace (VOID)
 
FORCEINLINE PMMSUPPORT MmGetKernelAddressSpace (VOID)
 
VOID NTAPI ExpCheckPoolAllocation (PVOID P, POOL_TYPE PoolType, ULONG Tag)
 
VOID NTAPI ExReturnPoolQuota (IN PVOID P)
 
NTSTATUS NTAPI MmAdjustWorkingSetSize (IN SIZE_T WorkingSetMinimumInBytes, IN SIZE_T WorkingSetMaximumInBytes, IN ULONG SystemCache, IN BOOLEAN IncreaseOkay)
 
 _IRQL_requires_max_ (APC_LEVEL) NTSTATUS NTAPI MmAttachSession(_Inout_ PVOID SessionEntry
 
VOID NTAPI MmQuitNextSession (_Inout_ PVOID SessionEntry)
 
PVOID NTAPI MmGetSessionById (_In_ ULONG SessionId)
 
NTSTATUS NTAPI MmCopyVirtualMemory (IN PEPROCESS SourceProcess, IN PVOID SourceAddress, IN PEPROCESS TargetProcess, OUT PVOID TargetAddress, IN SIZE_T BufferSize, IN KPROCESSOR_MODE PreviousMode, OUT PSIZE_T ReturnSize)
 

Variables

PMMSUPPORT MmKernelAddressSpace
 
PFN_COUNT MiFreeSwapPages
 
PFN_COUNT MiUsedSwapPages
 
PFN_COUNT MmNumberOfPhysicalPages
 
UCHAR MmDisablePagingExecutive
 
PFN_NUMBER MmLowestPhysicalPage
 
PFN_NUMBER MmHighestPhysicalPage
 
PFN_NUMBER MmAvailablePages
 
PFN_NUMBER MmResidentAvailablePages
 
LIST_ENTRY MmLoadedUserImageList
 
KMUTANT MmSystemLoadLock
 
ULONG MmNumberOfPagingFiles
 
PVOID MmUnloadedDrivers
 
PVOID MmLastUnloadedDrivers
 
PVOID MmTriageActionTaken
 
PVOID KernelVerifier
 
MM_DRIVER_VERIFIER_DATA MmVerifierData
 
SIZE_T MmTotalCommitLimit
 
SIZE_T MmTotalCommittedPages
 
SIZE_T MmSharedCommit
 
SIZE_T MmDriverCommit
 
SIZE_T MmProcessCommit
 
SIZE_T MmPagedPoolCommit
 
SIZE_T MmPeakCommitment
 
SIZE_T MmtotalCommitLimitMaximum
 
PVOID MiDebugMapping
 
PMMPTE MmDebugPte
 
PMMPFN MmPfnDatabase
 
MMPFNLIST MmZeroedPageListHead
 
MMPFNLIST MmFreePageListHead
 
MMPFNLIST MmStandbyPageListHead
 
MMPFNLIST MmModifiedPageListHead
 
MMPFNLIST MmModifiedNoWritePageListHead
 
MM_MEMORY_CONSUMER MiMemoryConsumers [MC_MAXIMUM]
 
PEPROCESS HyperProcess
 
KIRQL HyperIrql
 
_Out_ PKAPC_STATE ApcState
 

Macro Definition Documentation

#define CACHE_ALIGNED_POOL_MASK   4

Definition at line 98 of file mm.h.

#define EndOfAllocation   WriteInProgress

Definition at line 288 of file mm.h.

#define InterlockedCompareExchangePte (   PointerPte,
  Exchange,
  Comperand 
)    InterlockedCompareExchange((PLONG)(PointerPte), Exchange, Comperand)

Definition at line 150 of file mm.h.

Referenced by MmSetCleanPage(), and MmSetDirtyPage().

#define InterlockedExchangePte (   PointerPte,
  Value 
)    InterlockedExchange((PLONG)(PointerPte), Value)

Definition at line 153 of file mm.h.

#define MC_MAXIMUM   (3)

Definition at line 94 of file mm.h.

Referenced by MiBalancerThread().

#define MC_SYSTEM   (2)

Definition at line 93 of file mm.h.

Referenced by CcInitCacheZeroPage(), MmRequestPageMemoryConsumer(), and QSI_DEF().

#define MEMORY_AREA_STATIC   (0x80000000)

Definition at line 72 of file mm.h.

Referenced by MiCreateArm3StaticMemoryArea(), and MmCreateMemoryArea().

#define MI_STATIC_MEMORY_AREAS   (13)

Definition at line 66 of file mm.h.

Referenced by MmCreateMemoryArea().

#define MM_FREE_POOL_SIGNATURE   'ARM3'

Definition at line 409 of file mm.h.

Referenced by MiAllocatePoolPages(), MiFreePoolPages(), and MiInitializeNonPagedPool().

#define MM_ROUND_DOWN (   x,
  s 
)    ((PVOID)(((ULONG_PTR)(x)) & ~((ULONG_PTR)(s)-1)))
#define MM_ROUND_UP (   x,
  s 
)    ((PVOID)(((ULONG_PTR)(x)+(s)-1) & ~((ULONG_PTR)(s)-1)))

Definition at line 104 of file mm.h.

Referenced by MmCreateMemoryArea(), and MmFreeMemoryArea().

#define MM_VIRTMEM_GRANULARITY   (64 * 1024)
#define MMDBG_COPY_CACHED   0x00000008
#define MMDBG_COPY_MAX_SIZE   0x8

Definition at line 61 of file mm.h.

Referenced by KdpCopyMemoryChunks().

#define MMDBG_COPY_PHYSICAL   0x00000002

Definition at line 52 of file mm.h.

Referenced by KdpReadPhysicalmemory(), KdpWritePhysicalmemory(), and MmDbgCopyMemory().

#define MMDBG_COPY_UNCACHED   0x00000010
#define MMDBG_COPY_WRITE_COMBINED   0x00000020
#define MUST_SUCCEED_POOL_MASK   2

Definition at line 97 of file mm.h.

Referenced by ExAllocatePoolWithTag().

#define PAGE_FLAGS_VALID_FOR_SECTION
Value:
#define PAGE_NOCACHE
Definition: nt_native.h:1311
#define PAGE_EXECUTE_WRITECOPY
Definition: nt_native.h:1309
#define PAGE_NOACCESS
Definition: nt_native.h:1302
#define PAGE_EXECUTE
Definition: nt_native.h:1306
#define PAGE_READONLY
Definition: compat.h:127
#define PAGE_WRITECOPY
Definition: nt_native.h:1305
#define PAGE_EXECUTE_READ
Definition: nt_native.h:1307
#define PAGE_EXECUTE_READWRITE
Definition: nt_native.h:1308
#define PAGE_READWRITE
Definition: nt_native.h:1304

Definition at line 110 of file mm.h.

Referenced by MmMapViewOfSection().

#define PAGE_IS_EXECUTABLE
Value:
#define PAGE_EXECUTE_WRITECOPY
Definition: nt_native.h:1309
#define PAGE_EXECUTE
Definition: nt_native.h:1306
#define PAGE_EXECUTE_READ
Definition: nt_native.h:1307
#define PAGE_EXECUTE_READWRITE
Definition: nt_native.h:1308

Definition at line 135 of file mm.h.

Referenced by MmspPageAlignSegments(), and ProtectToPTE().

#define PAGE_IS_READABLE
Value:
#define PAGE_EXECUTE_WRITECOPY
Definition: nt_native.h:1309
#define PAGE_READONLY
Definition: compat.h:127
#define PAGE_WRITECOPY
Definition: nt_native.h:1305
#define PAGE_EXECUTE_READ
Definition: nt_native.h:1307
#define PAGE_EXECUTE_READWRITE
Definition: nt_native.h:1308
#define PAGE_READWRITE
Definition: nt_native.h:1304

Definition at line 121 of file mm.h.

Referenced by MmspPageAlignSegments(), and ProtectToPTE().

#define PAGE_IS_WRITABLE
Value:
#define PAGE_EXECUTE_WRITECOPY
Definition: nt_native.h:1309
#define PAGE_WRITECOPY
Definition: nt_native.h:1305
#define PAGE_EXECUTE_READWRITE
Definition: nt_native.h:1308
#define PAGE_READWRITE
Definition: nt_native.h:1304

Definition at line 129 of file mm.h.

Referenced by MmspPageAlignSegments(), and ProtectToPTE().

#define PAGE_IS_WRITECOPY
Value:
#define PAGE_EXECUTE_WRITECOPY
Definition: nt_native.h:1309
#define PAGE_WRITECOPY
Definition: nt_native.h:1305

Definition at line 141 of file mm.h.

Referenced by MmspPageAlignSegments().

#define PAGE_SYSTEM   (2048)

Definition at line 84 of file mm.h.

Referenced by MmGetPageProtect(), and ProtectToPTE().

#define PAGE_WRITETHROUGH   (1024)

Definition at line 83 of file mm.h.

Referenced by MiGetPteProtection(), MiSetPteProtection(), MmGetPageProtect(), and ProtectToPTE().

#define PAGED_POOL_MASK   1

Definition at line 96 of file mm.h.

Referenced by PsChargeProcessPoolQuota(), and PsReturnPoolQuota().

#define QUOTA_POOL_MASK   8

Definition at line 99 of file mm.h.

#define SESSION_POOL_MASK   32
#define StartOfAllocation   ReadInProgress

Definition at line 287 of file mm.h.

#define VERIFIER_POOL_MASK   64

Definition at line 101 of file mm.h.

Referenced by MiAllocatePoolPages().

Typedef Documentation

typedef struct _MMPFN MMPFN
typedef VOID(* PMM_ALTER_REGION_FUNC)(PMMSUPPORT AddressSpace, PVOID BaseAddress, SIZE_T Length, ULONG OldType, ULONG OldProtect, ULONG NewType, ULONG NewProtect)

Definition at line 427 of file mm.h.

typedef VOID(* PMM_FREE_PAGE_FUNC)(PVOID Context, PMEMORY_AREA MemoryArea, PVOID Address, PFN_NUMBER Page, SWAPENTRY SwapEntry, BOOLEAN Dirty)

Definition at line 438 of file mm.h.

typedef struct _MMPFN * PMMPFN

Definition at line 45 of file mm.h.

Enumeration Type Documentation

Enumerator
MI_USAGE_NOT_SET 
MI_USAGE_PAGED_POOL 
MI_USAGE_NONPAGED_POOL 
MI_USAGE_NONPAGED_POOL_EXPANSION 
MI_USAGE_KERNEL_STACK 
MI_USAGE_KERNEL_STACK_EXPANSION 
MI_USAGE_SYSTEM_PTE 
MI_USAGE_VAD 
MI_USAGE_PEB_TEB 
MI_USAGE_SECTION 
MI_USAGE_PAGE_TABLE 
MI_USAGE_PAGE_DIRECTORY 
MI_USAGE_LEGACY_PAGE_DIRECTORY 
MI_USAGE_DRIVER_PAGE 
MI_USAGE_CONTINOUS_ALLOCATION 
MI_USAGE_MDL 
MI_USAGE_DEMAND_ZERO 
MI_USAGE_ZERO_LOOP 
MI_USAGE_CACHE 
MI_USAGE_PFN_DATABASE 
MI_USAGE_BOOT_DRIVER 
MI_USAGE_INIT_MEMORY 
MI_USAGE_FREE_PAGE 

Definition at line 257 of file mm.h.

258 {
259  MI_USAGE_NOT_SET = 0,
266  MI_USAGE_VAD,
274  MI_USAGE_MDL,
282 } MI_PFN_USAGES;
enum _MI_PFN_USAGES MI_PFN_USAGES

Function Documentation

_IRQL_requires_max_ ( APC_LEVEL  )
VOID NTAPI ExpCheckPoolAllocation ( PVOID  P,
POOL_TYPE  PoolType,
ULONG  Tag 
)

Definition at line 286 of file expool.c.

290 {
292  ULONG i;
293  KIRQL OldIrql;
294  POOL_TYPE RealPoolType;
295 
296  /* Get the pool header */
297  Entry = ((PPOOL_HEADER)P) - 1;
298 
299  /* Check if this is a large allocation */
300  if (PAGE_ALIGN(P) == P)
301  {
302  /* Lock the pool table */
304 
305  /* Find the pool tag */
306  for (i = 0; i < PoolBigPageTableSize; i++)
307  {
308  /* Check if this is our allocation */
309  if (PoolBigPageTable[i].Va == P)
310  {
311  /* Make sure the tag is ok */
312  if (PoolBigPageTable[i].Key != Tag)
313  {
314  KeBugCheckEx(BAD_POOL_CALLER, 0x0A, (ULONG_PTR)P, PoolBigPageTable[i].Key, Tag);
315  }
316 
317  break;
318  }
319  }
320 
321  /* Release the lock */
323 
324  if (i == PoolBigPageTableSize)
325  {
326  /* Did not find the allocation */
327  //ASSERT(FALSE);
328  }
329 
330  /* Get Pool type by address */
331  RealPoolType = MmDeterminePoolType(P);
332  }
333  else
334  {
335  /* Verify the tag */
336  if (Entry->PoolTag != Tag)
337  {
338  DPRINT1("Allocation has wrong pool tag! Expected '%.4s', got '%.4s' (0x%08lx)\n",
339  &Tag, &Entry->PoolTag, Entry->PoolTag);
340  KeBugCheckEx(BAD_POOL_CALLER, 0x0A, (ULONG_PTR)P, Entry->PoolTag, Tag);
341  }
342 
343  /* Check the rest of the header */
344  ExpCheckPoolHeader(Entry);
345 
346  /* Get Pool type from entry */
347  RealPoolType = (Entry->PoolType - 1);
348  }
349 
350  /* Should we check the pool type? */
351  if (PoolType != -1)
352  {
353  /* Verify the pool type */
354  if (RealPoolType != PoolType)
355  {
356  DPRINT1("Wrong pool type! Expected %s, got %s\n",
357  PoolType & BASE_POOL_TYPE_MASK ? "PagedPool" : "NonPagedPool",
358  (Entry->PoolType - 1) & BASE_POOL_TYPE_MASK ? "PagedPool" : "NonPagedPool");
359  KeBugCheckEx(BAD_POOL_CALLER, 0xCC, (ULONG_PTR)P, Entry->PoolTag, Tag);
360  }
361  }
362 }
struct _Entry Entry
Definition: kefuncs.h:640
uint32_t ULONG_PTR
Definition: typedefs.h:64
KSPIN_LOCK ExpLargePoolTableLock
Definition: expool.c:45
UCHAR KIRQL
Definition: env_spec_w32.h:591
GLenum GLclampf GLint i
Definition: glfuncs.h:14
SIZE_T PoolBigPageTableSize
Definition: expool.c:39
VOID NTAPI ExpCheckPoolHeader(IN PPOOL_HEADER Entry)
Definition: expool.c:183
#define BASE_POOL_TYPE_MASK
Definition: ExPools.c:15
struct _POOL_HEADER * PPOOL_HEADER
POOL_TYPE NTAPI MmDeterminePoolType(IN PVOID VirtualAddress)
Definition: pool.c:406
INT POOL_TYPE
Definition: typedefs.h:77
#define KeAcquireSpinLock(sl, irql)
Definition: env_spec_w32.h:609
#define PAGE_ALIGN(Va)
IN REFCLSID IN PUNKNOWN IN POOL_TYPE PoolType
Definition: unknown.h:68
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:803
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
#define DPRINT1
Definition: precomp.h:8
IN ULONG IN ULONG Tag
Definition: evtlib.h:153
PPOOL_TRACKER_BIG_PAGES PoolBigPageTable
Definition: expool.c:41
unsigned int ULONG
Definition: retypes.h:1
VOID NTAPI KeBugCheckEx(_In_ ULONG BugCheckCode, _In_ ULONG_PTR BugCheckParameter1, _In_ ULONG_PTR BugCheckParameter2, _In_ ULONG_PTR BugCheckParameter3, _In_ ULONG_PTR BugCheckParameter4)
Definition: rtlcompat.c:90
#define P(row, col)
Definition: m_matrix.c:147
VOID NTAPI ExReturnPoolQuota ( IN PVOID  P)

Definition at line 1514 of file expool.c.

Referenced by IoFreeIrp().

1515 {
1518  USHORT BlockSize;
1520 
1523  {
1524  return;
1525  }
1526 
1527  Entry = P;
1528  Entry--;
1529  ASSERT((ULONG_PTR)Entry % POOL_BLOCK_SIZE == 0);
1530 
1531  PoolType = Entry->PoolType - 1;
1532  BlockSize = Entry->BlockSize;
1533 
1534  if (PoolType & QUOTA_POOL_MASK)
1535  {
1536  Process = ((PVOID *)POOL_NEXT_BLOCK(Entry))[-1];
1537  ASSERT(Process != NULL);
1538  if (Process)
1539  {
1540  if (Process->Pcb.Header.Type != ProcessObject)
1541  {
1542  DPRINT1("Object %p is not a process. Type %u, pool type 0x%x, block size %u\n",
1543  Process, Process->Pcb.Header.Type, Entry->PoolType, BlockSize);
1544  KeBugCheckEx(BAD_POOL_CALLER,
1545  0x0D,
1546  (ULONG_PTR)P,
1547  Entry->PoolTag,
1548  (ULONG_PTR)Process);
1549  }
1550  ((PVOID *)POOL_NEXT_BLOCK(Entry))[-1] = NULL;
1551  PsReturnPoolQuota(Process,
1552  PoolType & BASE_POOL_TYPE_MASK,
1553  BlockSize * POOL_BLOCK_SIZE);
1554  ObDereferenceObject(Process);
1555  }
1556  }
1557 }
DWORD *typedef PVOID
Definition: winlogon.h:52
struct _Entry Entry
Definition: kefuncs.h:640
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel)?(CompletionRoutine!=NULL):TRUE)
#define POOL_FLAG_SPECIAL_POOL
Definition: miarm.h:260
VOID NTAPI ObDereferenceObject(IN PVOID Object)
Definition: obref.c:267
uint32_t ULONG_PTR
Definition: typedefs.h:64
#define POOL_NEXT_BLOCK(x)
Definition: expool.c:54
VOID NTAPI PsReturnPoolQuota(IN PEPROCESS Process, IN POOL_TYPE PoolType, IN SIZE_T Amount)
Definition: quota.c:237
smooth NULL
Definition: ftsmooth.c:513
#define BASE_POOL_TYPE_MASK
Definition: ExPools.c:15
INT POOL_TYPE
Definition: typedefs.h:77
IN REFCLSID IN PUNKNOWN IN POOL_TYPE PoolType
Definition: unknown.h:68
KPROCESS Pcb
Definition: pstypes.h:1194
#define QUOTA_POOL_MASK
Definition: ExPools.c:16
unsigned short USHORT
Definition: pedump.c:61
#define DPRINT1
Definition: precomp.h:8
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:219
ULONG ExpPoolFlags
Definition: expool.c:47
#define POOL_BLOCK_SIZE
Definition: miarm.h:246
BOOLEAN NTAPI MmIsSpecialPoolAddress(IN PVOID P)
VOID NTAPI KeBugCheckEx(_In_ ULONG BugCheckCode, _In_ ULONG_PTR BugCheckParameter1, _In_ ULONG_PTR BugCheckParameter2, _In_ ULONG_PTR BugCheckParameter3, _In_ ULONG_PTR BugCheckParameter4)
Definition: rtlcompat.c:90
DISPATCHER_HEADER Header
Definition: ketypes.h:1380
#define P(row, col)
Definition: m_matrix.c:147
PVOID NTAPI MiAllocatePoolPages ( IN POOL_TYPE  PoolType,
IN SIZE_T  SizeInBytes 
)

Definition at line 420 of file pool.c.

Referenced by ExAllocatePoolWithTag(), and InitializePool().

422 {
423  PFN_NUMBER PageFrameNumber;
424  PFN_COUNT SizeInPages, PageTableCount;
425  ULONG i;
426  KIRQL OldIrql;
427  PLIST_ENTRY NextEntry, NextHead, LastHead;
428  PMMPTE PointerPte, StartPte;
429  PMMPDE PointerPde;
430  ULONG EndAllocation;
431  MMPTE TempPte;
432  MMPDE TempPde;
433  PMMPFN Pfn1;
434  PVOID BaseVa, BaseVaStart;
435  PMMFREE_POOL_ENTRY FreeEntry;
436  PKSPIN_LOCK_QUEUE LockQueue;
437 
438  //
439  // Figure out how big the allocation is in pages
440  //
441  SizeInPages = (PFN_COUNT)BYTES_TO_PAGES(SizeInBytes);
442 
443  //
444  // Check for overflow
445  //
446  if (SizeInPages == 0)
447  {
448  //
449  // Fail
450  //
451  return NULL;
452  }
453 
454  //
455  // Handle paged pool
456  //
458  {
459  //
460  // If only one page is being requested, try to grab it from the S-LIST
461  //
462  if ((SizeInPages == 1) && (ExQueryDepthSList(&MiPagedPoolSListHead)))
463  {
465  if (BaseVa) return BaseVa;
466  }
467 
468  //
469  // Lock the paged pool mutex
470  //
472 
473  //
474  // Find some empty allocation space
475  //
477  SizeInPages,
479  if (i == 0xFFFFFFFF)
480  {
481  //
482  // Get the page bit count
483  //
484  i = ((SizeInPages - 1) / PTE_COUNT) + 1;
485  DPRINT("Paged pool expansion: %lu %x\n", i, SizeInPages);
486 
487  //
488  // Check if there is enougn paged pool expansion space left
489  //
492  {
493  //
494  // Out of memory!
495  //
496  DPRINT1("OUT OF PAGED POOL!!!\n");
498  return NULL;
499  }
500 
501  //
502  // Check if we'll have to expand past the last PTE we have available
503  //
506  {
507  //
508  // We can only support this much then
509  //
511  PageTableCount = (PFN_COUNT)(PointerPde + 1 -
513  ASSERT(PageTableCount < i);
514  i = PageTableCount;
515  }
516  else
517  {
518  //
519  // Otherwise, there is plenty of space left for this expansion
520  //
521  PageTableCount = i;
522  }
523 
524  //
525  // Get the template PDE we'll use to expand
526  //
527  TempPde = ValidKernelPde;
528 
529  //
530  // Get the first PTE in expansion space
531  //
533  BaseVa = MiPdeToPte(PointerPde);
534  BaseVaStart = BaseVa;
535 
536  //
537  // Lock the PFN database and loop pages
538  //
540  do
541  {
542  //
543  // It should not already be valid
544  //
545  ASSERT(PointerPde->u.Hard.Valid == 0);
546 
547  /* Request a page */
549  MI_SET_PROCESS2("Kernel");
550  PageFrameNumber = MiRemoveAnyPage(MI_GET_NEXT_COLOR());
551  TempPde.u.Hard.PageFrameNumber = PageFrameNumber;
552 #if (_MI_PAGING_LEVELS >= 3)
553  /* On PAE/x64 systems, there's no double-buffering */
554  ASSERT(FALSE);
555 #else
556  //
557  // Save it into our double-buffered system page directory
558  //
559  MmSystemPagePtes[((ULONG_PTR)PointerPde & (SYSTEM_PD_SIZE - 1)) / sizeof(MMPTE)] = TempPde;
560 
561  /* Initialize the PFN */
562  MiInitializePfnForOtherProcess(PageFrameNumber,
563  (PMMPTE)PointerPde,
565 
566  /* Write the actual PDE now */
567 // MI_WRITE_VALID_PDE(PointerPde, TempPde);
568 #endif
569  //
570  // Move on to the next expansion address
571  //
572  PointerPde++;
573  BaseVa = (PVOID)((ULONG_PTR)BaseVa + PAGE_SIZE);
574  i--;
575  } while (i > 0);
576 
577  //
578  // Release the PFN database lock
579  //
581 
582  //
583  // These pages are now available, clear their availablity bits
584  //
587  PTE_COUNT;
589  EndAllocation,
590  PageTableCount * PTE_COUNT);
591 
592  //
593  // Update the next expansion location
594  //
596 
597  //
598  // Zero out the newly available memory
599  //
600  RtlZeroMemory(BaseVaStart, PageTableCount * PAGE_SIZE);
601 
602  //
603  // Now try consuming the pages again
604  //
606  SizeInPages,
607  0);
608  if (i == 0xFFFFFFFF)
609  {
610  //
611  // Out of memory!
612  //
613  DPRINT1("OUT OF PAGED POOL!!!\n");
615  return NULL;
616  }
617  }
618 
619  //
620  // Update the pool hint if the request was just one page
621  //
622  if (SizeInPages == 1) MmPagedPoolInfo.PagedPoolHint = i + 1;
623 
624  //
625  // Update the end bitmap so we know the bounds of this allocation when
626  // the time comes to free it
627  //
628  EndAllocation = i + SizeInPages - 1;
630 
631  //
632  // Now we can release the lock (it mainly protects the bitmap)
633  //
635 
636  //
637  // Now figure out where this allocation starts
638  //
639  BaseVa = (PVOID)((ULONG_PTR)MmPagedPoolStart + (i << PAGE_SHIFT));
640 
641  //
642  // Flush the TLB
643  //
645 
646  /* Setup a demand-zero writable PTE */
648 
649  //
650  // Find the first and last PTE, then loop them all
651  //
652  PointerPte = MiAddressToPte(BaseVa);
653  StartPte = PointerPte + SizeInPages;
654  do
655  {
656  //
657  // Write the demand zero PTE and keep going
658  //
659  MI_WRITE_INVALID_PTE(PointerPte, TempPte);
660  } while (++PointerPte < StartPte);
661 
662  //
663  // Return the allocation address to the caller
664  //
665  return BaseVa;
666  }
667 
668  //
669  // If only one page is being requested, try to grab it from the S-LIST
670  //
671  if ((SizeInPages == 1) && (ExQueryDepthSList(&MiNonPagedPoolSListHead)))
672  {
674  if (BaseVa) return BaseVa;
675  }
676 
677  //
678  // Allocations of less than 4 pages go into their individual buckets
679  //
680  i = SizeInPages - 1;
682 
683  //
684  // Loop through all the free page lists based on the page index
685  //
686  NextHead = &MmNonPagedPoolFreeListHead[i];
688 
689  //
690  // Acquire the nonpaged pool lock
691  //
693  do
694  {
695  //
696  // Now loop through all the free page entries in this given list
697  //
698  NextEntry = NextHead->Flink;
699  while (NextEntry != NextHead)
700  {
701  /* Is freed non paged pool enabled */
703  {
704  /* We need to be able to touch this page, unprotect it */
705  MiUnProtectFreeNonPagedPool(NextEntry, 0);
706  }
707 
708  //
709  // Grab the entry and see if it can handle our allocation
710  //
711  FreeEntry = CONTAINING_RECORD(NextEntry, MMFREE_POOL_ENTRY, List);
712  ASSERT(FreeEntry->Signature == MM_FREE_POOL_SIGNATURE);
713  if (FreeEntry->Size >= SizeInPages)
714  {
715  //
716  // It does, so consume the pages from here
717  //
718  FreeEntry->Size -= SizeInPages;
719 
720  //
721  // The allocation will begin in this free page area
722  //
723  BaseVa = (PVOID)((ULONG_PTR)FreeEntry +
724  (FreeEntry->Size << PAGE_SHIFT));
725 
726  /* Remove the item from the list, depending if pool is protected */
729  else
730  RemoveEntryList(&FreeEntry->List);
731 
732  //
733  // However, check if its' still got space left
734  //
735  if (FreeEntry->Size != 0)
736  {
737  /* Check which list to insert this entry into */
738  i = FreeEntry->Size - 1;
740 
741  /* Insert the entry into the free list head, check for prot. pool */
744  else
746 
747  /* Is freed non paged pool protected? */
749  {
750  /* Protect the freed pool! */
751  MiProtectFreeNonPagedPool(FreeEntry, FreeEntry->Size);
752  }
753  }
754 
755  //
756  // Grab the PTE for this allocation
757  //
758  PointerPte = MiAddressToPte(BaseVa);
759  ASSERT(PointerPte->u.Hard.Valid == 1);
760 
761  //
762  // Grab the PFN NextEntry and index
763  //
764  Pfn1 = MiGetPfnEntry(PFN_FROM_PTE(PointerPte));
765 
766  //
767  // Now mark it as the beginning of an allocation
768  //
769  ASSERT(Pfn1->u3.e1.StartOfAllocation == 0);
770  Pfn1->u3.e1.StartOfAllocation = 1;
771 
772  /* Mark it as special pool if needed */
773  ASSERT(Pfn1->u4.VerifierAllocation == 0);
775  {
776  Pfn1->u4.VerifierAllocation = 1;
777  }
778 
779  //
780  // Check if the allocation is larger than one page
781  //
782  if (SizeInPages != 1)
783  {
784  //
785  // Navigate to the last PFN entry and PTE
786  //
787  PointerPte += SizeInPages - 1;
788  ASSERT(PointerPte->u.Hard.Valid == 1);
789  Pfn1 = MiGetPfnEntry(PointerPte->u.Hard.PageFrameNumber);
790  }
791 
792  //
793  // Mark this PFN as the last (might be the same as the first)
794  //
795  ASSERT(Pfn1->u3.e1.EndOfAllocation == 0);
796  Pfn1->u3.e1.EndOfAllocation = 1;
797 
798  //
799  // Release the nonpaged pool lock, and return the allocation
800  //
802  return BaseVa;
803  }
804 
805  //
806  // Try the next free page entry
807  //
808  NextEntry = FreeEntry->List.Flink;
809 
810  /* Is freed non paged pool protected? */
812  {
813  /* Protect the freed pool! */
814  MiProtectFreeNonPagedPool(FreeEntry, FreeEntry->Size);
815  }
816  }
817  } while (++NextHead < LastHead);
818 
819  //
820  // If we got here, we're out of space.
821  // Start by releasing the lock
822  //
824 
825  //
826  // Allocate some system PTEs
827  //
828  StartPte = MiReserveSystemPtes(SizeInPages, NonPagedPoolExpansion);
829  PointerPte = StartPte;
830  if (StartPte == NULL)
831  {
832  //
833  // Ran out of memory
834  //
835  DPRINT1("Out of NP Expansion Pool\n");
836  return NULL;
837  }
838 
839  //
840  // Acquire the pool lock now
841  //
843 
844  //
845  // Lock the PFN database too
846  //
847  LockQueue = &KeGetCurrentPrcb()->LockQueue[LockQueuePfnLock];
849 
850  //
851  // Loop the pages
852  //
853  TempPte = ValidKernelPte;
854  do
855  {
856  /* Allocate a page */
858  MI_SET_PROCESS2("Kernel");
859  PageFrameNumber = MiRemoveAnyPage(MI_GET_NEXT_COLOR());
860 
861  /* Get the PFN entry for it and fill it out */
862  Pfn1 = MiGetPfnEntry(PageFrameNumber);
863  Pfn1->u3.e2.ReferenceCount = 1;
864  Pfn1->u2.ShareCount = 1;
865  Pfn1->PteAddress = PointerPte;
867  Pfn1->u4.VerifierAllocation = 0;
868 
869  /* Write the PTE for it */
870  TempPte.u.Hard.PageFrameNumber = PageFrameNumber;
871  MI_WRITE_VALID_PTE(PointerPte++, TempPte);
872  } while (--SizeInPages > 0);
873 
874  //
875  // This is the last page
876  //
877  Pfn1->u3.e1.EndOfAllocation = 1;
878 
879  //
880  // Get the first page and mark it as such
881  //
882  Pfn1 = MiGetPfnEntry(StartPte->u.Hard.PageFrameNumber);
883  Pfn1->u3.e1.StartOfAllocation = 1;
884 
885  /* Mark it as a verifier allocation if needed */
886  ASSERT(Pfn1->u4.VerifierAllocation == 0);
888 
889  //
890  // Release the PFN and nonpaged pool lock
891  //
894 
895  //
896  // Return the address
897  //
898  return MiPteToAddress(StartPte);
899 }
DWORD *typedef PVOID
Definition: winlogon.h:52
#define MI_MAKE_SOFTWARE_PTE(p, x)
Definition: miarm.h:156
VOID FASTCALL KeReleaseQueuedSpinLockFromDpcLevel(IN OUT PKSPIN_LOCK_QUEUE LockQueue)
PRTL_BITMAP PagedPoolAllocationMap
Definition: mm.h:414
#define PAGE_SHIFT
Definition: env_spec_w32.h:45
NTSYSAPI void WINAPI RtlClearBits(PRTL_BITMAP, ULONG, ULONG)
#define TRUE
Definition: types.h:120
BOOLEAN NTAPI MiUnProtectFreeNonPagedPool(IN PVOID VirtualAddress, IN ULONG PageCount)
Definition: pool.c:68
#define MiAddressToPde(x)
Definition: mmx86.c:20
VOID FASTCALL KeAcquireGuardedMutex(IN PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:42
ULONG PFN_COUNT
Definition: mmtypes.h:102
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel)?(CompletionRoutine!=NULL):TRUE)
PMMPTE NTAPI MiReserveSystemPtes(IN ULONG NumberOfPtes, IN MMSYSTEM_PTE_POOL_TYPE SystemPtePoolType)
Definition: syspte.c:246
ULONG Signature
Definition: mm.h:404
#define VERIFIER_POOL_MASK
Definition: mm.h:101
FORCEINLINE struct _KPRCB * KeGetCurrentPrcb(VOID)
Definition: ketypes.h:1054
NTSYSAPI VOID NTAPI RtlSetBit(_In_ PRTL_BITMAP BitMapHeader, _In_range_(<, BitMapHeader->SizeOfBitMap) ULONG BitNumber)
Definition: bitmap.c:304
#define MM_READWRITE
Definition: miarm.h:49
#define MI_GET_NEXT_COLOR()
Definition: miarm.h:209
HARDWARE_PDE_ARMV6 TempPde
Definition: winldr.c:77
VOID FASTCALL KeAcquireQueuedSpinLockAtDpcLevel(IN OUT PKSPIN_LOCK_QUEUE LockQueue)
VOID NTAPI MiInitializePfnForOtherProcess(IN PFN_NUMBER PageFrameIndex, IN PVOID PteAddress, IN PFN_NUMBER PteFrame)
Definition: pfnlist.c:1280
union _MMPFN::@1575 u2
#define InsertTailList(ListHead, Entry)
USHORT PageLocation
Definition: mm.h:297
PSLIST_ENTRY WINAPI InterlockedPopEntrySList(PSLIST_HEADER ListHead)
Definition: interlocked.c:55
SLIST_HEADER MiNonPagedPoolSListHead
Definition: pool.c:30
uint32_t ULONG_PTR
Definition: typedefs.h:64
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
UCHAR KIRQL
Definition: env_spec_w32.h:591
MMPFNENTRY e1
Definition: mm.h:329
#define PDE_COUNT
Definition: miarm.h:30
GLenum GLclampf GLint i
Definition: glfuncs.h:14
#define MiAddressToPte(x)
Definition: mmx86.c:19
ULONG PFN_NUMBER
Definition: ke.h:8
PMMPTE LastPteForPagedPool
Definition: mm.h:417
#define FALSE
Definition: types.h:117
FORCEINLINE VOID MI_WRITE_VALID_PTE(IN PMMPTE PointerPte, IN MMPTE TempPte)
Definition: miarm.h:914
ULONG_PTR ShareCount
Definition: mm.h:322
VOID NTAPI MiProtectedPoolRemoveEntryList(IN PLIST_ENTRY Entry)
Definition: pool.c:166
#define MI_SET_PROCESS2(x)
Definition: mm.h:254
LIST_ENTRY List
Definition: mm.h:402
#define MI_MAX_FREE_PAGE_LISTS
Definition: mm.h:70
smooth NULL
Definition: ftsmooth.c:513
PVOID FORCEINLINE MiPteToAddress(PMMPTE PointerPte)
Definition: mm.h:185
ULONG_PTR VerifierAllocation
Definition: mm.h:352
void DPRINT(...)
Definition: polytest.cpp:61
#define BASE_POOL_TYPE_MASK
Definition: ExPools.c:15
#define MI_SET_USAGE(x)
Definition: mm.h:253
VOID NTAPI KeFlushEntireTb(IN BOOLEAN Invalid, IN BOOLEAN AllProcessors)
Definition: cpu.c:423
PMMPDE MmSystemPagePtes
Definition: init.c:41
KGUARDED_MUTEX MmPagedPoolMutex
Definition: pool.c:24
PFN_COUNT Size
Definition: mm.h:403
struct _LIST_ENTRY * Flink
Definition: typedefs.h:120
#define MM_FREE_POOL_SIGNATURE
Definition: mm.h:409
LIST_ENTRY List
Definition: psmgr.c:57
Definition: mm.h:400
ULONG64 Valid
Definition: mmtypes.h:150
union _MMPFN::@1579 u4
MM_PAGED_POOL_INFO MmPagedPoolInfo
Definition: pool.c:25
VOID FASTCALL KeReleaseQueuedSpinLock(IN KSPIN_LOCK_QUEUE_NUMBER LockNumber, IN KIRQL OldIrql)
Definition: spinlock.c:154
HARDWARE_PTE_ARMV6 TempPte
Definition: winldr.c:75
FORCEINLINE USHORT ExQueryDepthSList(_In_ PSLIST_HEADER SListHead)
Definition: exfuncs.h:153
MMPTE ValidKernelPte
Definition: init.c:31
#define PTE_COUNT
Definition: miarm.h:31
struct _MMPFN::@1576::@1582 e2
VOID NTAPI MiProtectedPoolInsertList(IN PLIST_ENTRY ListHead, IN PLIST_ENTRY Entry, IN BOOLEAN Critical)
Definition: pool.c:148
#define BYTES_TO_PAGES(Size)
IN REFCLSID IN PUNKNOWN IN POOL_TYPE PoolType
Definition: unknown.h:68
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:803
Definition: mm.h:305
#define PAGE_SIZE
Definition: env_spec_w32.h:49
PFN_NUMBER MmSystemPageDirectory[PD_COUNT]
Definition: init.c:40
Definition: typedefs.h:118
NTSYSAPI ULONG WINAPI RtlFindClearBitsAndSet(PRTL_BITMAP, ULONG, ULONG)
KIRQL FASTCALL KeAcquireQueuedSpinLock(IN KSPIN_LOCK_QUEUE_NUMBER LockNumber)
Definition: spinlock.c:108
FORCEINLINE PMMPFN MiGetPfnEntry(IN PFN_NUMBER Pfn)
Definition: mm.h:877
MMPTE ValidKernelPde
Definition: init.c:30
PVOID MmPagedPoolStart
Definition: miarm.h:552
PFN_NUMBER NTAPI MiRemoveAnyPage(IN ULONG Color)
Definition: pfnlist.c:475
MMPTE_HARDWARE Hard
Definition: mmtypes.h:217
#define SYSTEM_PD_SIZE
Definition: miarm.h:34
#define MiPteToPde(_Pte)
Definition: mm.h:220
FORCEINLINE VOID MI_WRITE_INVALID_PTE(IN PMMPTE PointerPte, IN MMPTE InvalidPte)
Definition: miarm.h:943
BOOLEAN MmProtectFreedNonPagedPool
Definition: pool.c:29
#define MiPdeToPte(_Pde)
Definition: mm.h:219
PRTL_BITMAP EndOfPagedPoolBitmap
Definition: mm.h:415
union _MMPTE::@2061 u
PMMPTE PteAddress
Definition: mm.h:318
VOID FASTCALL KeReleaseGuardedMutex(IN OUT PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:53
#define DPRINT1
Definition: precomp.h:8
union _MMPFN::@1576 u3
SLIST_HEADER MiPagedPoolSListHead
Definition: pool.c:32
unsigned int ULONG
Definition: retypes.h:1
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define ULONG_PTR
Definition: config.h:101
ULONG64 PageFrameNumber
Definition: mmtypes.h:171
VOID NTAPI MiProtectFreeNonPagedPool(IN PVOID VirtualAddress, IN ULONG PageCount)
Definition: pool.c:39
ULONG PagedPoolHint
Definition: mm.h:419
PMMPTE FirstPteForPagedPool
Definition: mm.h:416
LIST_ENTRY MmNonPagedPoolFreeListHead[MI_MAX_FREE_PAGE_LISTS]
Definition: pool.c:20
#define PFN_FROM_PTE(v)
Definition: mm.h:82
PMMPDE NextPdeForPagedPoolExpansion
Definition: mm.h:418
VOID NTAPI MiCheckAllProcessMemoryAreas ( VOID  )
NTSTATUS NTAPI MiCopyFromUserPage ( PFN_NUMBER  NewPage,
PFN_NUMBER  OldPage 
)

Definition at line 1043 of file section.c.

Referenced by MmAccessFaultSectionView().

1044 {
1046  KIRQL Irql, Irql2;
1047  PVOID DestAddress, SrcAddress;
1048 
1049  Process = PsGetCurrentProcess();
1050  DestAddress = MiMapPageInHyperSpace(Process, DestPage, &Irql);
1051  SrcAddress = MiMapPageInHyperSpace(Process, SrcPage, &Irql2);
1052  if (DestAddress == NULL || SrcAddress == NULL)
1053  {
1054  return(STATUS_NO_MEMORY);
1055  }
1056  ASSERT((ULONG_PTR)DestAddress % PAGE_SIZE == 0);
1057  ASSERT((ULONG_PTR)SrcAddress % PAGE_SIZE == 0);
1058  RtlCopyMemory(DestAddress, SrcAddress, PAGE_SIZE);
1059  MiUnmapPageInHyperSpace(Process, SrcAddress, Irql2);
1060  MiUnmapPageInHyperSpace(Process, DestAddress, Irql);
1061  return(STATUS_SUCCESS);
1062 }
DWORD *typedef PVOID
Definition: winlogon.h:52
#define STATUS_SUCCESS
Definition: contextmenu.cpp:55
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel)?(CompletionRoutine!=NULL):TRUE)
_Out_ PKIRQL Irql
Definition: csq.h:179
uint32_t ULONG_PTR
Definition: typedefs.h:64
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define PsGetCurrentProcess
Definition: psfuncs.h:17
PVOID NTAPI MiMapPageInHyperSpace(IN PEPROCESS Process, IN PFN_NUMBER Page, IN PKIRQL OldIrql)
Definition: hypermap.c:30
smooth NULL
Definition: ftsmooth.c:513
VOID NTAPI MiUnmapPageInHyperSpace(IN PEPROCESS Process, IN PVOID Address, IN KIRQL OldIrql)
Definition: hypermap.c:93
#define PAGE_SIZE
Definition: env_spec_w32.h:49
#define STATUS_NO_MEMORY
Definition: ntstatus.h:246
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:219
ULONG NTAPI MiFreePoolPages ( IN PVOID  StartingAddress)

Definition at line 903 of file pool.c.

Referenced by ExFreePoolWithTag().

904 {
905  PMMPTE PointerPte, StartPte;
906  PMMPFN Pfn1, StartPfn;
907  PFN_COUNT FreePages, NumberOfPages;
908  KIRQL OldIrql;
909  PMMFREE_POOL_ENTRY FreeEntry, NextEntry, LastEntry;
910  ULONG i, End;
912 
913  //
914  // Handle paged pool
915  //
916  if ((StartingVa >= MmPagedPoolStart) && (StartingVa <= MmPagedPoolEnd))
917  {
918  //
919  // Calculate the offset from the beginning of paged pool, and convert it
920  // into pages
921  //
922  Offset = (ULONG_PTR)StartingVa - (ULONG_PTR)MmPagedPoolStart;
923  i = (ULONG)(Offset >> PAGE_SHIFT);
924  End = i;
925 
926  //
927  // Now use the end bitmap to scan until we find a set bit, meaning that
928  // this allocation finishes here
929  //
930  while (!RtlTestBit(MmPagedPoolInfo.EndOfPagedPoolBitmap, End)) End++;
931 
932  //
933  // Now calculate the total number of pages this allocation spans. If it's
934  // only one page, add it to the S-LIST instead of freeing it
935  //
936  NumberOfPages = End - i + 1;
937  if ((NumberOfPages == 1) &&
939  {
941  return 1;
942  }
943 
944  /* Delete the actual pages */
945  PointerPte = MmPagedPoolInfo.FirstPteForPagedPool + i;
946  FreePages = MiDeleteSystemPageableVm(PointerPte, NumberOfPages, 0, NULL);
947  ASSERT(FreePages == NumberOfPages);
948 
949  //
950  // Acquire the paged pool lock
951  //
953 
954  //
955  // Clear the allocation and free bits
956  //
959 
960  //
961  // Update the hint if we need to
962  //
964 
965  //
966  // Release the lock protecting the bitmaps
967  //
969 
970  //
971  // And finally return the number of pages freed
972  //
973  return NumberOfPages;
974  }
975 
976  //
977  // Get the first PTE and its corresponding PFN entry. If this is also the
978  // last PTE, meaning that this allocation was only for one page, push it into
979  // the S-LIST instead of freeing it
980  //
981  StartPte = PointerPte = MiAddressToPte(StartingVa);
982  StartPfn = Pfn1 = MiGetPfnEntry(PointerPte->u.Hard.PageFrameNumber);
983  if ((Pfn1->u3.e1.EndOfAllocation == 1) &&
985  {
987  return 1;
988  }
989 
990  //
991  // Loop until we find the last PTE
992  //
993  while (Pfn1->u3.e1.EndOfAllocation == 0)
994  {
995  //
996  // Keep going
997  //
998  PointerPte++;
999  Pfn1 = MiGetPfnEntry(PointerPte->u.Hard.PageFrameNumber);
1000  }
1001 
1002  //
1003  // Now we know how many pages we have
1004  //
1005  NumberOfPages = (PFN_COUNT)(PointerPte - StartPte + 1);
1006 
1007  //
1008  // Acquire the nonpaged pool lock
1009  //
1011 
1012  //
1013  // Mark the first and last PTEs as not part of an allocation anymore
1014  //
1015  StartPfn->u3.e1.StartOfAllocation = 0;
1016  Pfn1->u3.e1.EndOfAllocation = 0;
1017 
1018  //
1019  // Assume we will free as many pages as the allocation was
1020  //
1021  FreePages = NumberOfPages;
1022 
1023  //
1024  // Peek one page past the end of the allocation
1025  //
1026  PointerPte++;
1027 
1028  //
1029  // Guard against going past initial nonpaged pool
1030  //
1032  {
1033  //
1034  // This page is on the outskirts of initial nonpaged pool, so ignore it
1035  //
1036  Pfn1 = NULL;
1037  }
1038  else
1039  {
1040  /* Sanity check */
1041  ASSERT((ULONG_PTR)StartingVa + NumberOfPages <= (ULONG_PTR)MmNonPagedPoolEnd);
1042 
1043  /* Check if protected pool is enabled */
1045  {
1046  /* The freed block will be merged, it must be made accessible */
1048  }
1049 
1050  //
1051  // Otherwise, our entire allocation must've fit within the initial non
1052  // paged pool, or the expansion nonpaged pool, so get the PFN entry of
1053  // the next allocation
1054  //
1055  if (PointerPte->u.Hard.Valid == 1)
1056  {
1057  //
1058  // It's either expansion or initial: get the PFN entry
1059  //
1060  Pfn1 = MiGetPfnEntry(PointerPte->u.Hard.PageFrameNumber);
1061  }
1062  else
1063  {
1064  //
1065  // This means we've reached the guard page that protects the end of
1066  // the expansion nonpaged pool
1067  //
1068  Pfn1 = NULL;
1069  }
1070 
1071  }
1072 
1073  //
1074  // Check if this allocation actually exists
1075  //
1076  if ((Pfn1) && (Pfn1->u3.e1.StartOfAllocation == 0))
1077  {
1078  //
1079  // It doesn't, so we should actually locate a free entry descriptor
1080  //
1081  FreeEntry = (PMMFREE_POOL_ENTRY)((ULONG_PTR)StartingVa +
1082  (NumberOfPages << PAGE_SHIFT));
1083  ASSERT(FreeEntry->Signature == MM_FREE_POOL_SIGNATURE);
1084  ASSERT(FreeEntry->Owner == FreeEntry);
1085 
1086  /* Consume this entry's pages */
1087  FreePages += FreeEntry->Size;
1088 
1089  /* Remove the item from the list, depending if pool is protected */
1091  MiProtectedPoolRemoveEntryList(&FreeEntry->List);
1092  else
1093  RemoveEntryList(&FreeEntry->List);
1094  }
1095 
1096  //
1097  // Now get the official free entry we'll create for the caller's allocation
1098  //
1099  FreeEntry = StartingVa;
1100 
1101  //
1102  // Check if the our allocation is the very first page
1103  //
1105  {
1106  //
1107  // Then we can't do anything or we'll risk underflowing
1108  //
1109  Pfn1 = NULL;
1110  }
1111  else
1112  {
1113  //
1114  // Otherwise, get the PTE for the page right before our allocation
1115  //
1116  PointerPte -= NumberOfPages + 1;
1117 
1118  /* Check if protected pool is enabled */
1120  {
1121  /* The freed block will be merged, it must be made accessible */
1123  }
1124 
1125  /* Check if this is valid pool, or a guard page */
1126  if (PointerPte->u.Hard.Valid == 1)
1127  {
1128  //
1129  // It's either expansion or initial nonpaged pool, get the PFN entry
1130  //
1131  Pfn1 = MiGetPfnEntry(PointerPte->u.Hard.PageFrameNumber);
1132  }
1133  else
1134  {
1135  //
1136  // We must've reached the guard page, so don't risk touching it
1137  //
1138  Pfn1 = NULL;
1139  }
1140  }
1141 
1142  //
1143  // Check if there is a valid PFN entry for the page before the allocation
1144  // and then check if this page was actually the end of an allocation.
1145  // If it wasn't, then we know for sure it's a free page
1146  //
1147  if ((Pfn1) && (Pfn1->u3.e1.EndOfAllocation == 0))
1148  {
1149  //
1150  // Get the free entry descriptor for that given page range
1151  //
1152  FreeEntry = (PMMFREE_POOL_ENTRY)((ULONG_PTR)StartingVa - PAGE_SIZE);
1153  ASSERT(FreeEntry->Signature == MM_FREE_POOL_SIGNATURE);
1154  FreeEntry = FreeEntry->Owner;
1155 
1156  /* Check if protected pool is enabled */
1158  {
1159  /* The freed block will be merged, it must be made accessible */
1160  MiUnProtectFreeNonPagedPool(FreeEntry, 0);
1161  }
1162 
1163  //
1164  // Check if the entry is small enough to be indexed on a free list
1165  // If it is, we'll want to re-insert it, since we're about to
1166  // collapse our pages on top of it, which will change its count
1167  //
1168  if (FreeEntry->Size < (MI_MAX_FREE_PAGE_LISTS - 1))
1169  {
1170  /* Remove the item from the list, depending if pool is protected */
1172  MiProtectedPoolRemoveEntryList(&FreeEntry->List);
1173  else
1174  RemoveEntryList(&FreeEntry->List);
1175 
1176  //
1177  // Update its size
1178  //
1179  FreeEntry->Size += FreePages;
1180 
1181  //
1182  // And now find the new appropriate list to place it in
1183  //
1184  i = (ULONG)(FreeEntry->Size - 1);
1186 
1187  /* Insert the entry into the free list head, check for prot. pool */
1190  else
1192  }
1193  else
1194  {
1195  //
1196  // Otherwise, just combine our free pages into this entry
1197  //
1198  FreeEntry->Size += FreePages;
1199  }
1200  }
1201 
1202  //
1203  // Check if we were unable to do any compaction, and we'll stick with this
1204  //
1205  if (FreeEntry == StartingVa)
1206  {
1207  //
1208  // Well, now we are a free entry. At worse we just have our newly freed
1209  // pages, at best we have our pages plus whatever entry came after us
1210  //
1211  FreeEntry->Size = FreePages;
1212 
1213  //
1214  // Find the appropriate list we should be on
1215  //
1216  i = FreeEntry->Size - 1;
1218 
1219  /* Insert the entry into the free list head, check for prot. pool */
1222  else
1224  }
1225 
1226  //
1227  // Just a sanity check
1228  //
1229  ASSERT(FreePages != 0);
1230 
1231  //
1232  // Get all the pages between our allocation and its end. These will all now
1233  // become free page chunks.
1234  //
1235  NextEntry = StartingVa;
1236  LastEntry = (PMMFREE_POOL_ENTRY)((ULONG_PTR)NextEntry + (FreePages << PAGE_SHIFT));
1237  do
1238  {
1239  //
1240  // Link back to the parent free entry, and keep going
1241  //
1242  NextEntry->Owner = FreeEntry;
1243  NextEntry->Signature = MM_FREE_POOL_SIGNATURE;
1244  NextEntry = (PMMFREE_POOL_ENTRY)((ULONG_PTR)NextEntry + PAGE_SIZE);
1245  } while (NextEntry != LastEntry);
1246 
1247  /* Is freed non paged pool protected? */
1249  {
1250  /* Protect the freed pool! */
1251  MiProtectFreeNonPagedPool(FreeEntry, FreeEntry->Size);
1252  }
1253 
1254  //
1255  // We're done, release the lock and let the caller know how much we freed
1256  //
1258  return NumberOfPages;
1259 }
PRTL_BITMAP PagedPoolAllocationMap
Definition: mm.h:414
#define PAGE_SHIFT
Definition: env_spec_w32.h:45
NTSYSAPI void WINAPI RtlClearBits(PRTL_BITMAP, ULONG, ULONG)
#define TRUE
Definition: types.h:120
BOOLEAN NTAPI MiUnProtectFreeNonPagedPool(IN PVOID VirtualAddress, IN ULONG PageCount)
Definition: pool.c:68
PFN_NUMBER MiEndOfInitialPoolFrame
Definition: pool.c:23
VOID FASTCALL KeAcquireGuardedMutex(IN PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:42
ULONG PFN_COUNT
Definition: mmtypes.h:102
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel)?(CompletionRoutine!=NULL):TRUE)
ULONG Signature
Definition: mm.h:404
PVOID MmPagedPoolEnd
Definition: init.c:26
#define InsertTailList(ListHead, Entry)
SLIST_HEADER MiNonPagedPoolSListHead
Definition: pool.c:30
PVOID MmNonPagedPoolEnd
Definition: mminit.c:99
uint32_t ULONG_PTR
Definition: typedefs.h:64
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
UCHAR KIRQL
Definition: env_spec_w32.h:591
MMPFNENTRY e1
Definition: mm.h:329
GLenum GLclampf GLint i
Definition: glfuncs.h:14
#define MiAddressToPte(x)
Definition: mmx86.c:19
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
VOID NTAPI MiProtectedPoolRemoveEntryList(IN PLIST_ENTRY Entry)
Definition: pool.c:166
PFN_NUMBER MiStartOfInitialPoolFrame
Definition: pool.c:23
LIST_ENTRY List
Definition: mm.h:402
#define MI_MAX_FREE_PAGE_LISTS
Definition: mm.h:70
smooth NULL
Definition: ftsmooth.c:513
PVOID FORCEINLINE MiPteToAddress(PMMPTE PointerPte)
Definition: mm.h:185
KGUARDED_MUTEX MmPagedPoolMutex
Definition: pool.c:24
PFN_COUNT Size
Definition: mm.h:403
#define MM_FREE_POOL_SIGNATURE
Definition: mm.h:409
Definition: mm.h:400
ULONG64 Valid
Definition: mmtypes.h:150
MM_PAGED_POOL_INFO MmPagedPoolInfo
Definition: pool.c:25
VOID NTAPI RtlClearBit(_In_ PRTL_BITMAP BitMapHeader, _In_ BITMAP_INDEX BitNumber)
Definition: bitmap.c:294
VOID FASTCALL KeReleaseQueuedSpinLock(IN KSPIN_LOCK_QUEUE_NUMBER LockNumber, IN KIRQL OldIrql)
Definition: spinlock.c:154
FORCEINLINE USHORT ExQueryDepthSList(_In_ PSLIST_HEADER SListHead)
Definition: exfuncs.h:153
_Must_inspect_result_ NTSYSAPI BOOLEAN NTAPI RtlTestBit(_In_ PRTL_BITMAP BitMapHeader, _In_range_(<, BitMapHeader->SizeOfBitMap) ULONG BitNumber)
Definition: bitmap.c:434
ULONG MiNonPagedPoolSListMaximum
Definition: pool.c:31
VOID NTAPI MiProtectedPoolInsertList(IN PLIST_ENTRY ListHead, IN PLIST_ENTRY Entry, IN BOOLEAN Critical)
Definition: pool.c:148
struct _MMFREE_POOL_ENTRY * Owner
Definition: mm.h:405
ULONG MiPagedPoolSListMaximum
Definition: pool.c:33
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:803
Definition: mm.h:305
#define PAGE_SIZE
Definition: env_spec_w32.h:49
NTKERNELAPI PSLIST_ENTRY FASTCALL InterlockedPushEntrySList(IN PSLIST_HEADER ListHead, IN PSLIST_ENTRY ListEntry)
Definition: interlocked.c:82
KIRQL FASTCALL KeAcquireQueuedSpinLock(IN KSPIN_LOCK_QUEUE_NUMBER LockNumber)
Definition: spinlock.c:108
FORCEINLINE PMMPFN MiGetPfnEntry(IN PFN_NUMBER Pfn)
Definition: mm.h:877
PVOID MmPagedPoolStart
Definition: miarm.h:552
PFN_COUNT NTAPI MiDeleteSystemPageableVm(IN PMMPTE PointerPte, IN PFN_NUMBER PageCount, IN ULONG Flags, OUT PPFN_NUMBER ValidPages)
Definition: virtual.c:297
MMPTE_HARDWARE Hard
Definition: mmtypes.h:217
BOOLEAN MmProtectFreedNonPagedPool
Definition: pool.c:29
struct _MMFREE_POOL_ENTRY * PMMFREE_POOL_ENTRY
PRTL_BITMAP EndOfPagedPoolBitmap
Definition: mm.h:415
union _MMPTE::@2061 u
VOID FASTCALL KeReleaseGuardedMutex(IN OUT PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:53
union _MMPFN::@1576 u3
SLIST_HEADER MiPagedPoolSListHead
Definition: pool.c:32
FORCEINLINE PFN_NUMBER MiGetPfnEntryIndex(IN PMMPFN Pfn1)
Definition: mm.h:897
unsigned int ULONG
Definition: retypes.h:1
#define ULONG_PTR
Definition: config.h:101
ULONG64 PageFrameNumber
Definition: mmtypes.h:171
VOID NTAPI MiProtectFreeNonPagedPool(IN PVOID VirtualAddress, IN ULONG PageCount)
Definition: pool.c:39
ULONG PagedPoolHint
Definition: mm.h:419
PMMPTE FirstPteForPagedPool
Definition: mm.h:416
LIST_ENTRY MmNonPagedPoolFreeListHead[MI_MAX_FREE_PAGE_LISTS]
Definition: pool.c:20
FORCEINLINE PMMPFN MiGetPfnEntry ( IN PFN_NUMBER  Pfn)

Definition at line 877 of file mm.h.

Referenced by MiAddHalIoMappings(), MiAllocatePagesForMdl(), MiAllocatePoolPages(), MiBuildPfnDatabaseFromLoaderBlock(), MiBuildPfnDatabaseFromPages(), MiBuildPfnDatabaseFromPageTables(), MiBuildPfnDatabaseSelf(), MiBuildPfnDatabaseZeroPage(), MiCompleteProtoPteFault(), MiCopyPfn(), MiDbgTranslatePhysicalAddress(), MiDecommitPages(), MiDeletePte(), MiDeleteSystemPageableVm(), MiFindContiguousMemory(), MiFreeContiguousMemory(), MiFreePoolPages(), MiGetPageProtection(), MiInitializeWorkingSetList(), MiInitMachineDependent(), MiLockVirtualMemory(), MiMapLockedPagesInUserSpace(), MiMapPageInHyperSpace(), MiProcessValidPteList(), MiProtectVirtualMemory(), MiReloadBootLoadedDrivers(), MiRemoveMappedPtes(), MiResolveProtoPteFault(), MiResolveTransitionFault(), MiSetPagingOfDriver(), MiSetProtectionOnSection(), MiSetupPfnForPageTable(), MiUnlockVirtualMemory(), MiUnmapLockedPagesInUserSpace(), MiZeroPfn(), MmAllocPage(), MmBuildMdlForNonPagedPool(), MmDeleteKernelStack(), MmDeleteProcessAddressSpace2(), MmDereferencePage(), MmDumpArmPfnDatabase(), MmFreeLoaderBlock(), MmFreePagesFromMdl(), MmGetLRUFirstUserPage(), MmGetLRUNextUserPage(), MmGetReferenceCountPage(), MmGetRmapListHeadPage(), MmGetSavedSwapEntryPage(), MmInsertLRULastUserPage(), MmIsPageInUse(), MmMapIoSpace(), MmNotPresentFaultCachePage(), MmProbeAndLockPages(), MmReferencePage(), MmRemoveLRUUserPage(), MmRosNotifyAvailablePage(), MmSetRmapListHeadPage(), MmSetSavedSwapEntryPage(), MmUnlockPages(), MmUnmapIoSpace(), MmZeroPageThread(), and PspCreateProcess().

878 {
879  PMMPFN Page;
880  extern RTL_BITMAP MiPfnBitMap;
881 
882  /* Make sure the PFN number is valid */
883  if (Pfn > MmHighestPhysicalPage) return NULL;
884 
885  /* Make sure this page actually has a PFN entry */
886  if ((MiPfnBitMap.Buffer) && !(RtlTestBit(&MiPfnBitMap, (ULONG)Pfn))) return NULL;
887 
888  /* Get the entry */
889  Page = &MmPfnDatabase[Pfn];
890 
891  /* Return it */
892  return Page;
893 };
PULONG Buffer
Definition: typedefs.h:90
PMMPFN MmPfnDatabase
Definition: freelist.c:24
RTL_BITMAP MiPfnBitMap
Definition: init.c:44
smooth NULL
Definition: ftsmooth.c:513
_Must_inspect_result_ NTSYSAPI BOOLEAN NTAPI RtlTestBit(_In_ PRTL_BITMAP BitMapHeader, _In_range_(<, BitMapHeader->SizeOfBitMap) ULONG BitNumber)
Definition: bitmap.c:434
Definition: mm.h:305
PFN_NUMBER MmHighestPhysicalPage
Definition: meminit.c:31
unsigned int ULONG
Definition: retypes.h:1
FORCEINLINE PFN_NUMBER MiGetPfnEntryIndex ( IN PMMPFN  Pfn1)

Definition at line 897 of file mm.h.

Referenced by MiAllocatePagesForMdl(), MiDecrementShareCount(), MiDereferencePfnAndDropLockCount(), MiFreePoolPages(), MiInitializeWorkingSetList(), MiInsertPageInFreeList(), MiMapPagesInZeroSpace(), and MiUnlinkFreeOrZeroedPage().

898 {
899  //
900  // This will return the Page Frame Number (PFN) from the MMPFN
901  //
902  return Pfn1 - MmPfnDatabase;
903 }
PMMPFN MmPfnDatabase
Definition: freelist.c:24
VOID NTAPI MiInitBalancerThread ( VOID  )

Definition at line 449 of file balance.c.

Referenced by MmInitSystem().

450 {
453 #if !defined(__GNUC__)
454 
455  LARGE_INTEGER dummyJunkNeeded;
456  dummyJunkNeeded.QuadPart = -20000000; /* 2 sec */
457  ;
458 #endif
459 
460 
464 #if defined(__GNUC__)
465  (LARGE_INTEGER)(LONGLONG)-20000000LL, /* 2 sec */
466 #else
467  dummyJunkNeeded,
468 #endif
469  2000, /* 2 sec */
470  NULL);
471 
474  NULL,
475  NULL,
478  NULL);
479  if (!NT_SUCCESS(Status))
480  {
481  KeBugCheck(MEMORY_MANAGEMENT);
482  }
483 
484  Priority = LOW_REALTIME_PRIORITY + 1;
487  &Priority,
488  sizeof(Priority));
489 
490 }
#define THREAD_ALL_ACCESS
Definition: nt_native.h:1339
#define LL
Definition: tui.h:72
VOID NTAPI MiBalancerThread(PVOID Unused)
Definition: balance.c:328
#define __GNUC__
Definition: _icc.h:38
_In_ KPRIORITY Priority
Definition: kefuncs.h:516
BOOLEAN NTAPI KeSetTimerEx(IN OUT PKTIMER Timer, IN LARGE_INTEGER DueTime, IN LONG Period, IN PKDPC Dpc OPTIONAL)
Definition: timerobj.c:294
#define LOW_REALTIME_PRIORITY
LONG KPRIORITY
Definition: compat.h:454
static KEVENT MiBalancerEvent
Definition: balance.c:45
#define FALSE
Definition: types.h:117
static CLIENT_ID MiBalancerThreadId
Definition: balance.c:43
smooth NULL
Definition: ftsmooth.c:513
VOID NTAPI KeBugCheck(ULONG BugCheckCode)
Definition: bug.c:1469
NTSTATUS NTAPI NtSetInformationThread(IN HANDLE ThreadHandle, IN THREADINFOCLASS ThreadInformationClass, IN PVOID ThreadInformation, IN ULONG ThreadInformationLength)
Definition: query.c:1966
int64_t LONGLONG
Definition: typedefs.h:67
Status
Definition: gdiplustypes.h:24
#define NT_SUCCESS(StatCode)
Definition: cmd.c:149
LONG NTSTATUS
Definition: DriverTester.h:11
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
NTSTATUS NTAPI PsCreateSystemThread(OUT PHANDLE ThreadHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, IN HANDLE ProcessHandle, IN PCLIENT_ID ClientId, IN PKSTART_ROUTINE StartRoutine, IN PVOID StartContext)
Definition: thread.c:602
static HANDLE MiBalancerThreadHandle
Definition: balance.c:44
VOID NTAPI KeInitializeTimerEx(OUT PKTIMER Timer, IN TIMER_TYPE Type)
Definition: timerobj.c:244
LONGLONG QuadPart
Definition: typedefs.h:113
static KTIMER MiBalancerTimer
Definition: balance.c:46
BOOLEAN NTAPI MiInitializeLoadedModuleList ( IN PLOADER_PARAMETER_BLOCK  LoaderBlock)

Definition at line 2188 of file sysldr.c.

Referenced by MmArmInitSystem().

2189 {
2190  PLDR_DATA_TABLE_ENTRY LdrEntry, NewEntry;
2191  PLIST_ENTRY ListHead, NextEntry;
2192  ULONG EntrySize;
2193 
2194  /* Setup the loaded module list and locks */
2198 
2199  /* Get loop variables and the kernel entry */
2200  ListHead = &LoaderBlock->LoadOrderListHead;
2201  NextEntry = ListHead->Flink;
2202  LdrEntry = CONTAINING_RECORD(NextEntry,
2204  InLoadOrderLinks);
2205  PsNtosImageBase = (ULONG_PTR)LdrEntry->DllBase;
2206 
2207  /* Locate resource section, pool code, and system pte code */
2208  MiLocateKernelSections(LdrEntry);
2209 
2210  /* Loop the loader block */
2211  while (NextEntry != ListHead)
2212  {
2213  /* Get the loader entry */
2214  LdrEntry = CONTAINING_RECORD(NextEntry,
2216  InLoadOrderLinks);
2217 
2218  /* FIXME: ROS HACK. Make sure this is a driver */
2219  if (!RtlImageNtHeader(LdrEntry->DllBase))
2220  {
2221  /* Skip this entry */
2222  NextEntry = NextEntry->Flink;
2223  continue;
2224  }
2225 
2226  /* Calculate the size we'll need and allocate a copy */
2227  EntrySize = sizeof(LDR_DATA_TABLE_ENTRY) +
2228  LdrEntry->BaseDllName.MaximumLength +
2229  sizeof(UNICODE_NULL);
2230  NewEntry = ExAllocatePoolWithTag(NonPagedPool, EntrySize, TAG_MODULE_OBJECT);
2231  if (!NewEntry) return FALSE;
2232 
2233  /* Copy the entry over */
2234  *NewEntry = *LdrEntry;
2235 
2236  /* Allocate the name */
2237  NewEntry->FullDllName.Buffer =
2239  LdrEntry->FullDllName.MaximumLength +
2240  sizeof(UNICODE_NULL),
2241  TAG_LDR_WSTR);
2242  if (!NewEntry->FullDllName.Buffer)
2243  {
2245  return FALSE;
2246  }
2247 
2248  /* Set the base name */
2249  NewEntry->BaseDllName.Buffer = (PVOID)(NewEntry + 1);
2250 
2251  /* Copy the full and base name */
2252  RtlCopyMemory(NewEntry->FullDllName.Buffer,
2253  LdrEntry->FullDllName.Buffer,
2254  LdrEntry->FullDllName.MaximumLength);
2255  RtlCopyMemory(NewEntry->BaseDllName.Buffer,
2256  LdrEntry->BaseDllName.Buffer,
2257  LdrEntry->BaseDllName.MaximumLength);
2258 
2259  /* Null-terminate the base name */
2260  NewEntry->BaseDllName.Buffer[NewEntry->BaseDllName.Length /
2261  sizeof(WCHAR)] = UNICODE_NULL;
2262 
2263  /* Insert the entry into the list */
2265  NextEntry = NextEntry->Flink;
2266  }
2267 
2268  /* Build the import lists for the boot drivers */
2270 
2271  /* We're done */
2272  return TRUE;
2273 }
DWORD *typedef PVOID
Definition: winlogon.h:52
ERESOURCE PsLoadedModuleResource
Definition: sysldr.c:37
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
USHORT MaximumLength
Definition: env_spec_w32.h:370
ULONG_PTR PsNtosImageBase
Definition: sysldr.c:38
LIST_ENTRY PsLoadedModuleList
Definition: sysldr.c:34
NTSTATUS ExInitializeResourceLite(PULONG res)
Definition: env_spec_w32.h:641
VOID NTAPI INIT_FUNCTION MiLocateKernelSections(IN PLDR_DATA_TABLE_ENTRY LdrEntry)
Definition: sysldr.c:2127
#define InsertTailList(ListHead, Entry)
#define WCHAR
Definition: msvc.h:43
_In_ UCHAR EntrySize
Definition: iofuncs.h:640
KSPIN_LOCK PsLoadedModuleSpinLock
Definition: sysldr.c:36
PVOID DllBase
Definition: ldrtypes.h:139
#define TAG_LDR_WSTR
Definition: tag.h:110
#define FALSE
Definition: types.h:117
#define UNICODE_NULL
FORCEINLINE VOID KeInitializeSpinLock(_Out_ PKSPIN_LOCK SpinLock)
Definition: kefuncs.h:251
struct _LIST_ENTRY * Flink
Definition: typedefs.h:120
struct _LDR_DATA_TABLE_ENTRY LDR_DATA_TABLE_ENTRY
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
Definition: ntddk_ex.h:202
NTSTATUS NTAPI INIT_FUNCTION MiBuildImportsForBootDrivers(VOID)
Definition: sysldr.c:1862
Definition: typedefs.h:118
LIST_ENTRY InLoadOrderLinks
Definition: ldrtypes.h:136
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
UNICODE_STRING FullDllName
Definition: ldrtypes.h:142
UNICODE_STRING BaseDllName
Definition: ldrtypes.h:143
#define RtlImageNtHeader
Definition: compat.h:457
#define TAG_MODULE_OBJECT
Definition: tag.h:109
unsigned int ULONG
Definition: retypes.h:1
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
#define ULONG_PTR
Definition: config.h:101
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1097
VOID NTAPI MiInitializeNonPagedPool ( VOID  )

Definition at line 276 of file pool.c.

Referenced by MiBuildNonPagedPool(), and MiInitMachineDependent().

277 {
278  ULONG i;
279  PFN_COUNT PoolPages;
280  PMMFREE_POOL_ENTRY FreeEntry, FirstEntry;
281  PMMPTE PointerPte;
282  PAGED_CODE();
283 
284  //
285  // Initialize the pool S-LISTs as well as their maximum count. In general,
286  // we'll allow 8 times the default on a 2GB system, and two times the default
287  // on a 1GB system.
288  //
291  if (MmNumberOfPhysicalPages >= ((2 * _1GB) /PAGE_SIZE))
292  {
295  }
296  else if (MmNumberOfPhysicalPages >= (_1GB /PAGE_SIZE))
297  {
300  }
301 
302  //
303  // However if debugging options for the pool are enabled, turn off the S-LIST
304  // to reduce the risk of messing things up even more
305  //
307  {
310  }
311 
312  //
313  // We keep 4 lists of free pages (4 lists help avoid contention)
314  //
315  for (i = 0; i < MI_MAX_FREE_PAGE_LISTS; i++)
316  {
317  //
318  // Initialize each of them
319  //
321  }
322 
323  //
324  // Calculate how many pages the initial nonpaged pool has
325  //
327  MmNumberOfFreeNonPagedPool = PoolPages;
328 
329  //
330  // Initialize the first free entry
331  //
332  FreeEntry = MmNonPagedPoolStart;
333  FirstEntry = FreeEntry;
334  FreeEntry->Size = PoolPages;
335  FreeEntry->Signature = MM_FREE_POOL_SIGNATURE;
336  FreeEntry->Owner = FirstEntry;
337 
338  //
339  // Insert it into the last list
340  //
341  InsertHeadList(&MmNonPagedPoolFreeListHead[MI_MAX_FREE_PAGE_LISTS - 1],
342  &FreeEntry->List);
343 
344  //
345  // Now create free entries for every single other page
346  //
347  while (PoolPages-- > 1)
348  {
349  //
350  // Link them all back to the original entry
351  //
352  FreeEntry = (PMMFREE_POOL_ENTRY)((ULONG_PTR)FreeEntry + PAGE_SIZE);
353  FreeEntry->Owner = FirstEntry;
354  FreeEntry->Signature = MM_FREE_POOL_SIGNATURE;
355  }
356 
357  //
358  // Validate and remember first allocated pool page
359  //
360  PointerPte = MiAddressToPte(MmNonPagedPoolStart);
361  ASSERT(PointerPte->u.Hard.Valid == 1);
363 
364  //
365  // Keep track of where initial nonpaged pool ends
366  //
369 
370  //
371  // Validate and remember last allocated pool page
372  //
373  PointerPte = MiAddressToPte((PVOID)((ULONG_PTR)MmNonPagedPoolEnd0 - 1));
374  ASSERT(PointerPte->u.Hard.Valid == 1);
376 
377  //
378  // Validate the first nonpaged pool expansion page (which is a guard page)
379  //
381  ASSERT(PointerPte->u.Hard.Valid == 0);
382 
383  //
384  // Calculate the size of the expansion region alone
385  //
388 
389  //
390  // Remove 2 pages, since there's a guard page on top and on the bottom
391  //
393 
394  //
395  // Now initialize the nonpaged pool expansion PTE space. Remember there's a
396  // guard page on top so make sure to skip it. The bottom guard page will be
397  // guaranteed by the fact our size is off by one.
398  //
399  MiInitializeSystemPtes(PointerPte + 1,
402 }
DWORD *typedef PVOID
Definition: winlogon.h:52
PFN_NUMBER MiEndOfInitialPoolFrame
Definition: pool.c:23
ULONG PFN_COUNT
Definition: mmtypes.h:102
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel)?(CompletionRoutine!=NULL):TRUE)
FORCEINLINE VOID InsertHeadList(_Inout_ PLIST_ENTRY ListHead, _Inout_ __drv_aliasesMem PLIST_ENTRY Entry)
Definition: rtlfuncs.h:201
ULONG Signature
Definition: mm.h:404
PVOID MmNonPagedPoolExpansionStart
Definition: init.c:25
SLIST_HEADER MiNonPagedPoolSListHead
Definition: pool.c:30
uint32_t ULONG_PTR
Definition: typedefs.h:64
PFN_COUNT MmNumberOfFreeNonPagedPool
Definition: pool.c:21
GLenum GLclampf GLint i
Definition: glfuncs.h:14
#define MiAddressToPte(x)
Definition: mmx86.c:19
VOID NTAPI MiInitializeSystemPtes(IN PMMPTE StartingPte, IN ULONG NumberOfPtes, IN MMSYSTEM_PTE_POOL_TYPE PoolType)
Definition: syspte.c:399
PFN_NUMBER MiStartOfInitialPoolFrame
Definition: pool.c:23
LIST_ENTRY List
Definition: mm.h:402
#define MI_MAX_FREE_PAGE_LISTS
Definition: mm.h:70
PVOID MmNonPagedPoolEnd0
Definition: pool.c:22
PFN_COUNT MiExpansionPoolPagesInitialCharge
Definition: pool.c:21
PFN_COUNT Size
Definition: mm.h:403
#define MM_FREE_POOL_SIGNATURE
Definition: mm.h:409
Definition: mm.h:400
ULONG64 Valid
Definition: mmtypes.h:150
#define PAGED_CODE()
Definition: video.h:57
ULONG MiNonPagedPoolSListMaximum
Definition: pool.c:31
struct _MMFREE_POOL_ENTRY * Owner
Definition: mm.h:405
#define BYTES_TO_PAGES(Size)
ULONG MiPagedPoolSListMaximum
Definition: pool.c:33
#define PAGE_SIZE
Definition: env_spec_w32.h:49
PVOID MmNonPagedPoolStart
Definition: init.c:24
MMPTE_HARDWARE Hard
Definition: mmtypes.h:217
PFN_COUNT MmNumberOfPhysicalPages
Definition: init.c:48
BOOLEAN MmProtectFreedNonPagedPool
Definition: pool.c:29
struct _MMFREE_POOL_ENTRY * PMMFREE_POOL_ENTRY
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
union _MMPTE::@2061 u
ULONG MmMaximumNonPagedPoolInBytes
Definition: init.c:22
SLIST_HEADER MiPagedPoolSListHead
Definition: pool.c:32
unsigned int ULONG
Definition: retypes.h:1
ULONG MmSizeOfNonPagedPoolInBytes
Definition: init.c:21
LIST_ENTRY MmNonPagedPoolFreeListHead[MI_MAX_FREE_PAGE_LISTS]
Definition: pool.c:20
#define PFN_FROM_PTE(v)
Definition: mm.h:82
#define _1GB
Definition: miarm.h:14
WINBASEAPI VOID WINAPI InitializeSListHead(_Out_ PSLIST_HEADER ListHead)
Definition: rtlfuncs.h:3353
VOID NTAPI MiInitializeSpecialPool ( VOID  )

Definition at line 123 of file special.c.

Referenced by MiBuildPagedPool().

124 {
125  ULONG SpecialPoolPtes, i;
126  PMMPTE PointerPte;
127 
128  /* Check if there is a special pool tag */
129  if ((MmSpecialPoolTag == 0) ||
130  (MmSpecialPoolTag == -1)) return;
131 
132  /* Calculate number of system PTEs for the special pool */
133  if (MmNumberOfSystemPtes >= 0x3000)
134  SpecialPoolPtes = MmNumberOfSystemPtes / 3;
135  else
136  SpecialPoolPtes = MmNumberOfSystemPtes / 6;
137 
138  /* Don't let the number go too high */
139  if (SpecialPoolPtes > 0x6000) SpecialPoolPtes = 0x6000;
140 
141  /* Round up to the page size */
142  SpecialPoolPtes = PAGE_ROUND_UP(SpecialPoolPtes);
143 
144  ASSERT((SpecialPoolPtes & (PTE_PER_PAGE - 1)) == 0);
145 
146  /* Reserve those PTEs */
147  do
148  {
149  PointerPte = MiReserveAlignedSystemPtes(SpecialPoolPtes,
151  /*0x400000*/0); // FIXME:
152  if (PointerPte) break;
153 
154  /* Reserving didn't work, so try to reduce the requested size */
155  ASSERT(SpecialPoolPtes >= PTE_PER_PAGE);
156  SpecialPoolPtes -= PTE_PER_PAGE;
157  } while (SpecialPoolPtes);
158 
159  /* Fail if we couldn't reserve them at all */
160  if (!SpecialPoolPtes) return;
161 
162  /* Make sure we got enough */
163  ASSERT(SpecialPoolPtes >= PTE_PER_PAGE);
164 
165  /* Save first PTE and its address */
166  MiSpecialPoolFirstPte = PointerPte;
167  MmSpecialPoolStart = MiPteToAddress(PointerPte);
168 
169  for (i = 0; i < PTE_PER_PAGE / 2; i++)
170  {
171  /* Point it to the next entry */
172  PointerPte->u.List.NextEntry = &PointerPte[2] - MmSystemPteBase;
173 
174  /* Move to the next pair */
175  PointerPte += 2;
176  }
177 
178  /* Save extra values */
179  MiSpecialPoolExtra = PointerPte;
180  MiSpecialPoolExtraCount = SpecialPoolPtes - PTE_PER_PAGE;
181 
182  /* Mark the previous PTE as the last one */
183  MiSpecialPoolLastPte = PointerPte - 2;
185 
186  /* Save end address of the special pool */
188 
189  /* Calculate maximum non-paged part of the special pool */
191 
192  /* And limit it if it turned out to be too big */
193  if (MmNumberOfPhysicalPages > 0x3FFF)
195 
196  DPRINT1("Special pool start %p - end %p\n", MmSpecialPoolStart, MmSpecialPoolEnd);
198 
199  //MiTestSpecialPool();
200 }
PFN_NUMBER MmResidentAvailablePages
Definition: freelist.c:27
ULONG MiSpecialPoolExtraCount
Definition: special.c:41
ULONG64 NextEntry
Definition: mmtypes.h:145
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel)?(CompletionRoutine!=NULL):TRUE)
#define MM_EMPTY_PTE_LIST
Definition: mm.h:77
#define POOL_FLAG_SPECIAL_POOL
Definition: miarm.h:260
ULONG MmNumberOfSystemPtes
Definition: init.c:42
#define PAGE_ROUND_UP(x)
Definition: scsiport_int.h:13
PMMPTE MiSpecialPoolLastPte
Definition: special.c:44
PVOID MmSpecialPoolEnd
Definition: special.c:39
GLenum GLclampf GLint i
Definition: glfuncs.h:14
ULONG MmSpecialPoolTag
Definition: pool.c:27
PVOID FORCEINLINE MiPteToAddress(PMMPTE PointerPte)
Definition: mm.h:185
PFN_COUNT MiSpecialPagesNonPagedMaximum
Definition: special.c:52
PVOID MiSpecialPoolExtra
Definition: special.c:40
MMPTE_LIST List
Definition: mmtypes.h:222
#define PTE_PER_PAGE
Definition: mm.h:18
PMMPTE NTAPI MiReserveAlignedSystemPtes(IN ULONG NumberOfPtes, IN MMSYSTEM_PTE_POOL_TYPE SystemPtePoolType, IN ULONG Alignment)
Definition: syspte.c:88
PFN_COUNT MmNumberOfPhysicalPages
Definition: init.c:48
union _MMPTE::@2061 u
PVOID MmSpecialPoolStart
Definition: special.c:38
PMMPTE MmSystemPteBase
Definition: syspte.c:21
#define DPRINT1
Definition: precomp.h:8
ULONG ExpPoolFlags
Definition: expool.c:47
unsigned int ULONG
Definition: retypes.h:1
PMMPTE MiSpecialPoolFirstPte
Definition: special.c:43
PVOID NTAPI MiMapPageInHyperSpace ( IN PEPROCESS  Process,
IN PFN_NUMBER  Page,
IN PKIRQL  OldIrql 
)

Definition at line 30 of file hypermap.c.

Referenced by _MiWriteBackPage(), MiCopyFromUserPage(), MiCopyPageToPage(), MiReadFilePage(), MiReadPage(), MiZeroPhysicalPage(), and MmCreateHyperspaceMapping().

33 {
34  MMPTE TempPte;
35  PMMPTE PointerPte;
37 
38  //
39  // Never accept page 0 or non-physical pages
40  //
41  ASSERT(Page != 0);
42  ASSERT(MiGetPfnEntry(Page) != NULL);
43 
44  //
45  // Build the PTE
46  //
47  TempPte = ValidKernelPteLocal;
48  TempPte.u.Hard.PageFrameNumber = Page;
49 
50  //
51  // Pick the first hyperspace PTE
52  //
53  PointerPte = MmFirstReservedMappingPte;
54 
55  //
56  // Acquire the hyperlock
57  //
59  KeAcquireSpinLock(&Process->HyperSpaceLock, OldIrql);
60 
61  //
62  // Now get the first free PTE
63  //
64  Offset = PFN_FROM_PTE(PointerPte);
65  if (!Offset)
66  {
67  //
68  // Reset the PTEs
69  //
70  Offset = MI_HYPERSPACE_PTES;
72  }
73 
74  //
75  // Prepare the next PTE
76  //
77  PointerPte->u.Hard.PageFrameNumber = Offset - 1;
78 
79  //
80  // Write the current PTE
81  //
82  PointerPte += Offset;
83  MI_WRITE_VALID_PTE(PointerPte, TempPte);
84 
85  //
86  // Return the address
87  //
88  return MiPteToAddress(PointerPte);
89 }
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel)?(CompletionRoutine!=NULL):TRUE)
ULONG PFN_NUMBER
Definition: ke.h:8
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
FORCEINLINE VOID MI_WRITE_VALID_PTE(IN PMMPTE PointerPte, IN MMPTE TempPte)
Definition: miarm.h:914
PMMPTE MmFirstReservedMappingPte
Definition: hypermap.c:20
#define PsGetCurrentProcess
Definition: psfuncs.h:17
#define MI_HYPERSPACE_PTES
Definition: mm.h:71
smooth NULL
Definition: ftsmooth.c:513
PVOID FORCEINLINE MiPteToAddress(PMMPTE PointerPte)
Definition: mm.h:185
MMPTE ValidKernelPteLocal
Definition: init.c:35
#define KeAcquireSpinLock(sl, irql)
Definition: env_spec_w32.h:609
HARDWARE_PTE_ARMV6 TempPte
Definition: winldr.c:75
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:803
FORCEINLINE PMMPFN MiGetPfnEntry(IN PFN_NUMBER Pfn)
Definition: mm.h:877
MMPTE_HARDWARE Hard
Definition: mmtypes.h:217
union _MMPTE::@2061 u
FORCEINLINE VOID KeFlushProcessTb(VOID)
Definition: ke.h:185
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:219
ULONG64 PageFrameNumber
Definition: mmtypes.h:171
#define PFN_FROM_PTE(v)
Definition: mm.h:82
PVOID NTAPI MiMapPagesInZeroSpace ( IN PMMPFN  Pfn1,
IN PFN_NUMBER  NumberOfPages 
)

Definition at line 113 of file hypermap.c.

Referenced by MmZeroPageThread().

115 {
116  MMPTE TempPte;
117  PMMPTE PointerPte;
118  PFN_NUMBER Offset, PageFrameIndex;
119 
120  //
121  // Sanity checks
122  //
124  ASSERT(NumberOfPages != 0);
125  ASSERT(NumberOfPages <= (MI_ZERO_PTES - 1));
126 
127  //
128  // Pick the first zeroing PTE
129  //
130  PointerPte = MiFirstReservedZeroingPte;
131 
132  //
133  // Now get the first free PTE
134  //
135  Offset = PFN_FROM_PTE(PointerPte);
136  if (NumberOfPages > Offset)
137  {
138  //
139  // Reset the PTEs
140  //
141  Offset = MI_ZERO_PTES - 1;
142  PointerPte->u.Hard.PageFrameNumber = Offset;
144  }
145 
146  //
147  // Prepare the next PTE
148  //
149  PointerPte->u.Hard.PageFrameNumber = Offset - NumberOfPages;
150 
151  /* Choose the correct PTE to use, and which template */
152  PointerPte += (Offset + 1);
153  TempPte = ValidKernelPte;
154 
155  /* Make sure the list isn't empty and loop it */
156  ASSERT(Pfn1 != (PVOID)LIST_HEAD);
157  while (Pfn1 != (PVOID)LIST_HEAD)
158  {
159  /* Get the page index for this PFN */
160  PageFrameIndex = MiGetPfnEntryIndex(Pfn1);
161 
162  //
163  // Write the PFN
164  //
165  TempPte.u.Hard.PageFrameNumber = PageFrameIndex;
166 
167  //
168  // Set the correct PTE to write to, and set its new value
169  //
170  PointerPte--;
171  MI_WRITE_VALID_PTE(PointerPte, TempPte);
172 
173  /* Move to the next PFN */
174  Pfn1 = (PMMPFN)Pfn1->u1.Flink;
175  }
176 
177  //
178  // Return the address
179  //
180  return MiPteToAddress(PointerPte);
181 }
DWORD *typedef PVOID
Definition: winlogon.h:52
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel)?(CompletionRoutine!=NULL):TRUE)
ULONG PFN_NUMBER
Definition: ke.h:8
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
FORCEINLINE VOID MI_WRITE_VALID_PTE(IN PMMPTE PointerPte, IN MMPTE TempPte)
Definition: miarm.h:914
PVOID FORCEINLINE MiPteToAddress(PMMPTE PointerPte)
Definition: mm.h:185
HARDWARE_PTE_ARMV6 TempPte
Definition: winldr.c:75
MMPTE ValidKernelPte
Definition: init.c:31
#define PASSIVE_LEVEL
Definition: env_spec_w32.h:693
LIST_HEAD(acpi_bus_event_list)
MMPTE_HARDWARE Hard
Definition: mmtypes.h:217
union _MMPTE::@2061 u
struct _MMPFN * PMMPFN
FORCEINLINE VOID KeFlushProcessTb(VOID)
Definition: ke.h:185
FORCEINLINE PFN_NUMBER MiGetPfnEntryIndex(IN PMMPFN Pfn1)
Definition: mm.h:897
ULONG64 PageFrameNumber
Definition: mmtypes.h:171
PMMPTE MiFirstReservedZeroingPte
Definition: hypermap.c:21
#define MI_ZERO_PTES
Definition: mm.h:72
#define PFN_FROM_PTE(v)
Definition: mm.h:82
BOOLEAN NTAPI MiRaisePoolQuota ( IN POOL_TYPE  PoolType,
IN ULONG  CurrentMaxQuota,
OUT PULONG  NewMaxQuota 
)

Definition at line 1264 of file pool.c.

1267 {
1268  //
1269  // Not implemented
1270  //
1271  UNIMPLEMENTED;
1272  *NewMaxQuota = CurrentMaxQuota + 65536;
1273  return TRUE;
1274 }
#define TRUE
Definition: types.h:120
#define UNIMPLEMENTED
Definition: debug.h:114
NTSTATUS NTAPI MiReadPageFile ( _In_ PFN_NUMBER  Page,
_In_ ULONG  PageFileIndex,
_In_ ULONG_PTR  PageFileOffset 
)

Definition at line 287 of file pagefile.c.

Referenced by MiResolvePageFileFault(), and MmReadFromSwapPage().

291 {
292  LARGE_INTEGER file_offset;
295  KEVENT Event;
296  UCHAR MdlBase[sizeof(MDL) + sizeof(ULONG)];
297  PMDL Mdl = (PMDL)MdlBase;
298  PPAGINGFILE PagingFile;
299 
300  DPRINT("MiReadSwapFile\n");
301 
302  if (PageFileOffset == 0)
303  {
304  KeBugCheck(MEMORY_MANAGEMENT);
305  return(STATUS_UNSUCCESSFUL);
306  }
307 
308  ASSERT(PageFileIndex < MAX_PAGING_FILES);
309 
310  PagingFile = PagingFileList[PageFileIndex];
311 
312  if (PagingFile->FileObject == NULL || PagingFile->FileObject->DeviceObject == NULL)
313  {
314  DPRINT1("Bad paging file %u\n", PageFileIndex);
315  KeBugCheck(MEMORY_MANAGEMENT);
316  }
317 
319  MmBuildMdlFromPages(Mdl, &Page);
320  Mdl->MdlFlags |= MDL_PAGES_LOCKED;
321 
322  file_offset.QuadPart = PageFileOffset * PAGE_SIZE;
323  file_offset = MmGetOffsetPageFile(PagingFile->RetrievalPointers, file_offset);
324 
326  Status = IoPageRead(PagingFile->FileObject,
327  Mdl,
328  &file_offset,
329  &Event,
330  &Iosb);
331  if (Status == STATUS_PENDING)
332  {
334  Status = Iosb.Status;
335  }
336  if (Mdl->MdlFlags & MDL_MAPPED_TO_SYSTEM_VA)
337  {
338  MmUnmapLockedPages (Mdl->MappedSystemVa, Mdl);
339  }
340  return(Status);
341 }
static LARGE_INTEGER MmGetOffsetPageFile(PRETRIEVAL_POINTERS_BUFFER RetrievalPointers, LARGE_INTEGER Offset)
Definition: pagefile.c:164
#define MmInitializeMdl(_MemoryDescriptorList, _BaseVa, _Length)
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel)?(CompletionRoutine!=NULL):TRUE)
PFILE_OBJECT FileObject
Definition: pagefile.c:48
VOID NTAPI MmBuildMdlFromPages(PMDL Mdl, PPFN_NUMBER Pages)
Definition: pagefile.c:126
NTSTATUS NTAPI IoPageRead(IN PFILE_OBJECT FileObject, IN PMDL Mdl, IN PLARGE_INTEGER Offset, IN PKEVENT Event, IN PIO_STATUS_BLOCK StatusBlock)
Definition: iofunc.c:1074
PVOID PMDL
Definition: usb.h:39
NTSTATUS NTAPI KeWaitForSingleObject(IN PVOID Object, IN KWAIT_REASON WaitReason, IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout OPTIONAL)
Definition: wait.c:416
#define MDL_MAPPED_TO_SYSTEM_VA
Definition: mmtypes.h:18
ACPI_EFI_EVENT Event
Definition: acefiex.h:607
_Must_inspect_result_ _Out_ PIO_STATUS_BLOCK Iosb
Definition: fltkernel.h:1761
#define FALSE
Definition: types.h:117
VOID NTAPI MmUnmapLockedPages(IN PVOID BaseAddress, IN PMDL Mdl)
Definition: mdlsup.c:811
smooth NULL
Definition: ftsmooth.c:513
void DPRINT(...)
Definition: polytest.cpp:61
VOID NTAPI KeBugCheck(ULONG BugCheckCode)
Definition: bug.c:1469
PRETRIEVAL_POINTERS_BUFFER RetrievalPointers
Definition: pagefile.c:56
#define MDL_PAGES_LOCKED
Definition: mmtypes.h:19
#define STATUS_PENDING
Definition: ntstatus.h:82
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
unsigned char UCHAR
Definition: xmlstorage.h:181
MDL
Definition: mmtypes.h:117
#define PAGE_SIZE
Definition: env_spec_w32.h:49
#define MAX_PAGING_FILES
Definition: pagefile.c:71
Status
Definition: gdiplustypes.h:24
LONG NTSTATUS
Definition: DriverTester.h:11
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
#define DPRINT1
Definition: precomp.h:8
unsigned int ULONG
Definition: retypes.h:1
static PPAGINGFILE PagingFileList[MAX_PAGING_FILES]
Definition: pagefile.c:74
LONGLONG QuadPart
Definition: typedefs.h:113
VOID NTAPI MiReloadBootLoadedDrivers ( IN PLOADER_PARAMETER_BLOCK  LoaderBlock)

Definition at line 1673 of file sysldr.c.

Referenced by MmArmInitSystem().

1674 {
1675  PLIST_ENTRY NextEntry;
1676  ULONG i = 0;
1677  PIMAGE_NT_HEADERS NtHeader;
1678  PLDR_DATA_TABLE_ENTRY LdrEntry;
1679  PIMAGE_FILE_HEADER FileHeader;
1680  BOOLEAN ValidRelocs;
1681  PIMAGE_DATA_DIRECTORY DataDirectory;
1682  PVOID DllBase, NewImageAddress;
1683  NTSTATUS Status;
1684  PMMPTE PointerPte, StartPte, LastPte;
1685  PFN_COUNT PteCount;
1686  PMMPFN Pfn1;
1687  MMPTE TempPte, OldPte;
1688 
1689  /* Loop driver list */
1690  for (NextEntry = LoaderBlock->LoadOrderListHead.Flink;
1691  NextEntry != &LoaderBlock->LoadOrderListHead;
1692  NextEntry = NextEntry->Flink)
1693  {
1694  /* Get the loader entry and NT header */
1695  LdrEntry = CONTAINING_RECORD(NextEntry,
1697  InLoadOrderLinks);
1698  NtHeader = RtlImageNtHeader(LdrEntry->DllBase);
1699 
1700  /* Debug info */
1701  DPRINT("[Mm0]: Driver at: %p ending at: %p for module: %wZ\n",
1702  LdrEntry->DllBase,
1703  (ULONG_PTR)LdrEntry->DllBase + LdrEntry->SizeOfImage,
1704  &LdrEntry->FullDllName);
1705 
1706  /* Get the first PTE and the number of PTEs we'll need */
1707  PointerPte = StartPte = MiAddressToPte(LdrEntry->DllBase);
1708  PteCount = ROUND_TO_PAGES(LdrEntry->SizeOfImage) >> PAGE_SHIFT;
1709  LastPte = StartPte + PteCount;
1710 
1711 #if MI_TRACE_PFNS
1712  /* Loop the PTEs */
1713  while (PointerPte < LastPte)
1714  {
1715  ULONG len;
1716  ASSERT(PointerPte->u.Hard.Valid == 1);
1717  Pfn1 = MiGetPfnEntry(PFN_FROM_PTE(PointerPte));
1718  len = wcslen(LdrEntry->BaseDllName.Buffer) * sizeof(WCHAR);
1719  snprintf(Pfn1->ProcessName, min(16, len), "%S", LdrEntry->BaseDllName.Buffer);
1720  PointerPte++;
1721  }
1722 #endif
1723  /* Skip kernel and HAL */
1724  /* ROS HACK: Skip BOOTVID/KDCOM too */
1725  i++;
1726  if (i <= 4) continue;
1727 
1728  /* Skip non-drivers */
1729  if (!NtHeader) continue;
1730 
1731  /* Get the file header and make sure we can relocate */
1732  FileHeader = &NtHeader->FileHeader;
1733  if (FileHeader->Characteristics & IMAGE_FILE_RELOCS_STRIPPED) continue;
1734  if (NtHeader->OptionalHeader.NumberOfRvaAndSizes <
1736 
1737  /* Everything made sense until now, check the relocation section too */
1738  DataDirectory = &NtHeader->OptionalHeader.
1739  DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC];
1740  if (!DataDirectory->VirtualAddress)
1741  {
1742  /* We don't really have relocations */
1743  ValidRelocs = FALSE;
1744  }
1745  else
1746  {
1747  /* Make sure the size is valid */
1748  if ((DataDirectory->VirtualAddress + DataDirectory->Size) >
1749  LdrEntry->SizeOfImage)
1750  {
1751  /* They're not, skip */
1752  continue;
1753  }
1754 
1755  /* We have relocations */
1756  ValidRelocs = TRUE;
1757  }
1758 
1759  /* Remember the original address */
1760  DllBase = LdrEntry->DllBase;
1761 
1762  /* Loop the PTEs */
1763  PointerPte = StartPte;
1764  while (PointerPte < LastPte)
1765  {
1766  /* Mark the page modified in the PFN database */
1767  ASSERT(PointerPte->u.Hard.Valid == 1);
1768  Pfn1 = MiGetPfnEntry(PFN_FROM_PTE(PointerPte));
1769  ASSERT(Pfn1->u3.e1.Rom == 0);
1770  Pfn1->u3.e1.Modified = TRUE;
1771 
1772  /* Next */
1773  PointerPte++;
1774  }
1775 
1776  /* Now reserve system PTEs for the image */
1777  PointerPte = MiReserveSystemPtes(PteCount, SystemPteSpace);
1778  if (!PointerPte)
1779  {
1780  /* Shouldn't happen */
1781  ERROR_FATAL("[Mm0]: Couldn't allocate driver section!\n");
1782  return;
1783  }
1784 
1785  /* This is the new virtual address for the module */
1786  LastPte = PointerPte + PteCount;
1787  NewImageAddress = MiPteToAddress(PointerPte);
1788 
1789  /* Sanity check */
1790  DPRINT("[Mm0]: Copying from: %p to: %p\n", DllBase, NewImageAddress);
1792 
1793  /* Loop the new driver PTEs */
1794  TempPte = ValidKernelPte;
1795  while (PointerPte < LastPte)
1796  {
1797  /* Copy the old data */
1798  OldPte = *StartPte;
1799  ASSERT(OldPte.u.Hard.Valid == 1);
1800 
1801  /* Set page number from the loader's memory */
1802  TempPte.u.Hard.PageFrameNumber = OldPte.u.Hard.PageFrameNumber;
1803 
1804  /* Write it */
1805  MI_WRITE_VALID_PTE(PointerPte, TempPte);
1806 
1807  /* Move on */
1808  PointerPte++;
1809  StartPte++;
1810  }
1811 
1812  /* Update position */
1813  PointerPte -= PteCount;
1814 
1815  /* Sanity check */
1816  ASSERT(*(PULONG)NewImageAddress == *(PULONG)DllBase);
1817 
1818  /* Set the image base to the address where the loader put it */
1819  NtHeader->OptionalHeader.ImageBase = (ULONG_PTR)DllBase;
1820 
1821  /* Check if we had relocations */
1822  if (ValidRelocs)
1823  {
1824  /* Relocate the image */
1825  Status = LdrRelocateImageWithBias(NewImageAddress,
1826  0,
1827  "SYSLDR",
1831  if (!NT_SUCCESS(Status))
1832  {
1833  /* This shouldn't happen */
1834  ERROR_FATAL("Relocations failed!\n");
1835  return;
1836  }
1837  }
1838 
1839  /* Update the loader entry */
1840  LdrEntry->DllBase = NewImageAddress;
1841 
1842  /* Update the thunks */
1843  DPRINT("[Mm0]: Updating thunks to: %wZ\n", &LdrEntry->BaseDllName);
1844  MiUpdateThunks(LoaderBlock,
1845  DllBase,
1846  NewImageAddress,
1847  LdrEntry->SizeOfImage);
1848 
1849  /* Update the loader entry */
1850  LdrEntry->Flags |= LDRP_SYSTEM_MAPPED;
1851  LdrEntry->EntryPoint = (PVOID)((ULONG_PTR)NewImageAddress +
1853  LdrEntry->SizeOfImage = PteCount << PAGE_SHIFT;
1854 
1855  /* FIXME: We'll need to fixup the PFN linkage when switching to ARM3 */
1856  }
1857 }
DWORD *typedef PVOID
Definition: winlogon.h:52
#define STATUS_SUCCESS
Definition: contextmenu.cpp:55
#define PAGE_SHIFT
Definition: env_spec_w32.h:45
#define TRUE
Definition: types.h:120
ULONG PFN_COUNT
Definition: mmtypes.h:102
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel)?(CompletionRoutine!=NULL):TRUE)
PMMPTE NTAPI MiReserveSystemPtes(IN ULONG NumberOfPtes, IN MMSYSTEM_PTE_POOL_TYPE SystemPtePoolType)
Definition: syspte.c:246
VOID NTAPI INIT_FUNCTION MiUpdateThunks(IN PLOADER_PARAMETER_BLOCK LoaderBlock, IN PVOID OldBase, IN PVOID NewBase, IN ULONG Size)
Definition: sysldr.c:592
ULONG SizeOfImage
Definition: ldrtypes.h:141
#define snprintf
Definition: wintirpc.h:48
USHORT Modified
Definition: mm.h:292
#define WCHAR
Definition: msvc.h:43
IMAGE_OPTIONAL_HEADER32 OptionalHeader
Definition: ntddk_ex.h:184
uint32_t ULONG_PTR
Definition: typedefs.h:64
#define ERROR_FATAL(...)
Definition: debug.h:237
PVOID DllBase
Definition: ldrtypes.h:139
MMPFNENTRY e1
Definition: mm.h:329
GLenum GLclampf GLint i
Definition: glfuncs.h:14
#define MiAddressToPte(x)
Definition: mmx86.c:19
#define FALSE
Definition: types.h:117
FORCEINLINE VOID MI_WRITE_VALID_PTE(IN PMMPTE PointerPte, IN MMPTE TempPte)
Definition: miarm.h:914
PVOID EntryPoint
Definition: ntddk_ex.h:207
PVOID FORCEINLINE MiPteToAddress(PMMPTE PointerPte)
Definition: mm.h:185
void DPRINT(...)
Definition: polytest.cpp:61
IMAGE_FILE_HEADER FileHeader
Definition: ntddk_ex.h:183
struct _LIST_ENTRY * Flink
Definition: typedefs.h:120
unsigned char BOOLEAN
#define STATUS_INVALID_IMAGE_FORMAT
Definition: ntstatus.h:345
ULONG64 Valid
Definition: mmtypes.h:150
HARDWARE_PTE_ARMV6 TempPte
Definition: winldr.c:75
MMPTE ValidKernelPte
Definition: init.c:31
Definition: mm.h:305
Definition: ntddk_ex.h:202
ULONG ExpInitializationPhase
Definition: init.c:65
GLenum GLsizei len
Definition: glext.h:6722
Definition: typedefs.h:118
FORCEINLINE PMMPFN MiGetPfnEntry(IN PFN_NUMBER Pfn)
Definition: mm.h:877
Status
Definition: gdiplustypes.h:24
MMPTE_HARDWARE Hard
Definition: mmtypes.h:217
#define NT_SUCCESS(StatCode)
Definition: cmd.c:149
LONG NTSTATUS
Definition: DriverTester.h:11
NTSYSAPI ULONG NTAPI LdrRelocateImageWithBias(_In_ PVOID NewAddress, _In_ LONGLONG AdditionalBias, _In_ PCCH LoaderName, _In_ ULONG Success, _In_ ULONG Conflict, _In_ ULONG Invalid)
#define ROUND_TO_PAGES(Size)
union _MMPTE::@2061 u
UNICODE_STRING FullDllName
Definition: ldrtypes.h:142
UNICODE_STRING BaseDllName
Definition: ldrtypes.h:143
USHORT Rom
Definition: mm.h:300
unsigned int * PULONG
Definition: retypes.h:1
#define min(a, b)
Definition: monoChain.cc:55
#define IMAGE_DIRECTORY_ENTRY_BASERELOC
Definition: pedump.c:264
#define RtlImageNtHeader
Definition: compat.h:457
union _MMPFN::@1576 u3
ULONG Flags
Definition: ntddk_ex.h:211
unsigned int ULONG
Definition: retypes.h:1
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
#define IMAGE_FILE_RELOCS_STRIPPED
Definition: pedump.c:159
#define ULONG_PTR
Definition: config.h:101
ULONG64 PageFrameNumber
Definition: mmtypes.h:171
#define STATUS_CONFLICTING_ADDRESSES
Definition: ntstatus.h:247
#define PFN_FROM_PTE(v)
Definition: mm.h:82
size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
#define LDRP_SYSTEM_MAPPED
Definition: ldrtypes.h:52
VOID NTAPI MiRosCheckMemoryAreas ( PMMSUPPORT  AddressSpace)
VOID NTAPI MiRosCleanupMemoryArea ( PEPROCESS  Process,
PMMVAD  Vad 
)

Definition at line 524 of file marea.c.

Referenced by MmCleanProcessAddressSpace().

527 {
531 
532  /* We must be called from MmCleanupAddressSpace and nowhere else!
533  Make sure things are as expected... */
534  ASSERT(Process == PsGetCurrentProcess());
535  ASSERT(Process->VmDeleted == TRUE);
536  ASSERT(((PsGetCurrentThread()->ThreadsProcess == Process) &&
537  (Process->ActiveThreads == 1)) ||
538  (Process->ActiveThreads == 0));
539 
540  /* We are in cleanup, we don't need to synchronize */
541  MmUnlockAddressSpace(&Process->Vm);
542 
543  MemoryArea = (PMEMORY_AREA)Vad;
544  BaseAddress = (PVOID)MA_GetStartingAddress(MemoryArea);
545 
546  if (MemoryArea->Type == MEMORY_AREA_SECTION_VIEW)
547  {
548  Status = MiRosUnmapViewOfSection(Process, BaseAddress, Process->ProcessExiting);
549  }
550  else if (MemoryArea->Type == MEMORY_AREA_CACHE)
551  {
552  Status = MmUnmapViewOfCacheSegment(&Process->Vm, BaseAddress);
553  }
554  else
555  {
556  /* There shouldn't be anything else! */
557  ASSERT(FALSE);
558  }
559 
560  /* Make sure this worked! */
561  ASSERT(NT_SUCCESS(Status));
562 
563  /* Lock the address space again */
564  MmLockAddressSpace(&Process->Vm);
565 }
DWORD *typedef PVOID
Definition: winlogon.h:52
#define TRUE
Definition: types.h:120
ULONG Type
Definition: mm.h:214
struct _MEMORY_AREA * PMEMORY_AREA
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel)?(CompletionRoutine!=NULL):TRUE)
FORCEINLINE VOID MmUnlockAddressSpace(PMMSUPPORT AddressSpace)
Definition: mm.h:1354
#define MEMORY_AREA_CACHE
Definition: mm.h:70
#define FALSE
Definition: types.h:117
ULONG ProcessExiting
Definition: pstypes.h:1327
ULONG ActiveThreads
Definition: pstypes.h:1268
#define PsGetCurrentProcess
Definition: psfuncs.h:17
#define MEMORY_AREA_SECTION_VIEW
Definition: mm.h:69
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID * BaseAddress
Definition: mmfuncs.h:404
ULONG VmDeleted
Definition: pstypes.h:1330
#define MA_GetStartingAddress(_MemoryArea)
Definition: mm.h:203
MMSUPPORT Vm
Definition: pstypes.h:1288
Status
Definition: gdiplustypes.h:24
NTSTATUS NTAPI MmUnmapViewOfCacheSegment(PMMSUPPORT AddressSpace, PVOID BaseAddress)
Definition: data.c:713
#define NT_SUCCESS(StatCode)
Definition: cmd.c:149
LONG NTSTATUS
Definition: DriverTester.h:11
NTSTATUS NTAPI MiRosUnmapViewOfSection(IN PEPROCESS Process, IN PVOID BaseAddress, IN BOOLEAN SkipDebuggerNotify)
Definition: section.c:4126
struct _MEMORY_AREA * MemoryArea
Definition: newmm.h:65
FORCEINLINE VOID MmLockAddressSpace(PMMSUPPORT AddressSpace)
Definition: mm.h:1347
VOID NTAPI MiUnmapPageInHyperSpace ( IN PEPROCESS  Process,
IN PVOID  Address,
IN KIRQL  OldIrql 
)

Definition at line 93 of file hypermap.c.

Referenced by _MiWriteBackPage(), MiCopyFromUserPage(), MiCopyPageToPage(), MiReadFilePage(), MiReadPage(), and MiZeroPhysicalPage().

96 {
98 
99  //
100  // Blow away the mapping
101  //
102  MiAddressToPte(Address)->u.Long = 0;
103 
104  //
105  // Release the hyperlock
106  //
108  KeReleaseSpinLock(&Process->HyperSpaceLock, OldIrql);
109 }
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
PVOID ULONG Address
Definition: oprghdlr.h:14
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel)?(CompletionRoutine!=NULL):TRUE)
#define MiAddressToPte(x)
Definition: mmx86.c:19
#define PsGetCurrentProcess
Definition: psfuncs.h:17
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:803
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:219
VOID NTAPI MiUnmapPagesInZeroSpace ( IN PVOID  VirtualAddress,
IN PFN_NUMBER  NumberOfPages 
)

Definition at line 185 of file hypermap.c.

Referenced by MmZeroPageThread().

187 {
188  PMMPTE PointerPte;
189 
190  //
191  // Sanity checks
192  //
194  ASSERT (NumberOfPages != 0);
195  ASSERT (NumberOfPages <= (MI_ZERO_PTES - 1));
196 
197  //
198  // Get the first PTE for the mapped zero VA
199  //
200  PointerPte = MiAddressToPte(VirtualAddress);
201 
202  //
203  // Blow away the mapped zero PTEs
204  //
205  RtlZeroMemory(PointerPte, NumberOfPages * sizeof(MMPTE));
206 }
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel)?(CompletionRoutine!=NULL):TRUE)
#define MiAddressToPte(x)
Definition: mmx86.c:19
_In_ ULONG _In_ BOOLEAN _Must_inspect_result_ PVOID * VirtualAddress
Definition: ndis.h:3772
#define PASSIVE_LEVEL
Definition: env_spec_w32.h:693
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define MI_ZERO_PTES
Definition: mm.h:72
NTSTATUS NTAPI MmAccessFault ( IN BOOLEAN  StoreInstruction,
IN PVOID  Address,
IN KPROCESSOR_MODE  Mode,
IN PVOID  TrapInformation 
)

Definition at line 204 of file mmfault.c.

Referenced by KiDataAbortHandler(), KiPageFaultHandler(), KiTrap0EHandler(), MiLockVirtualMemory(), MiMakeSystemAddressValid(), MiMakeSystemAddressValidPfn(), and MmProbeAndLockPages().

208 {
210 
211  /* Cute little hack for ROS */
213  {
214 #ifdef _M_IX86
215  /* Check for an invalid page directory in kernel mode */
217  {
218  /* All is well with the world */
219  return STATUS_SUCCESS;
220  }
221 #endif
222  }
223 
224  /* Handle shared user page, which doesn't have a VAD / MemoryArea */
226  {
227  /* This is an ARM3 fault */
228  DPRINT("ARM3 fault %p\n", MemoryArea);
229  return MmArmAccessFault(StoreInstruction, Address, Mode, TrapInformation);
230  }
231 
232  /* Is there a ReactOS address space yet? */
234  {
235  /* Check if this is an ARM3 memory area */
237  if (!(MemoryArea) && (Address <= MM_HIGHEST_USER_ADDRESS))
238  {
239  /* Could this be a VAD fault from user-mode? */
241  }
242  }
243 
244  /* Is this an ARM3 memory area, or is there no address space yet? */
245  if (((MemoryArea) && (MemoryArea->Type == MEMORY_AREA_OWNED_BY_ARM3)) ||
246  (!(MemoryArea) && ((ULONG_PTR)Address >= (ULONG_PTR)MmPagedPoolStart)) ||
248  {
249  /* This is an ARM3 fault */
250  DPRINT("ARM3 fault %p\n", MemoryArea);
251  return MmArmAccessFault(StoreInstruction, Address, Mode, TrapInformation);
252  }
253 
254  /* Keep same old ReactOS Behaviour */
255  if (StoreInstruction)
256  {
257  /* Call access fault */
258  return MmpAccessFault(Mode, (ULONG_PTR)Address, TrapInformation ? FALSE : TRUE);
259  }
260  else
261  {
262  /* Call not present */
263  return MmNotPresentFault(Mode, (ULONG_PTR)Address, TrapInformation ? FALSE : TRUE);
264  }
265 }
DWORD *typedef PVOID
Definition: winlogon.h:52
#define STATUS_SUCCESS
Definition: contextmenu.cpp:55
#define MM_HIGHEST_USER_ADDRESS
Definition: armddk.h:17
#define TRUE
Definition: types.h:120
PVOID ULONG Address
Definition: oprghdlr.h:14
ULONG Type
Definition: mm.h:214
_In_ ULONG Mode
Definition: hubbusif.h:303
NTSTATUS NTAPI MmArmAccessFault(IN BOOLEAN StoreInstruction, IN PVOID Address, IN KPROCESSOR_MODE Mode, IN PVOID TrapInformation)
Definition: pagfault.c:1638
#define MM_SHARED_USER_DATA_VA
Definition: mmtypes.h:48
PMEMORY_AREA NTAPI MmLocateMemoryAreaByAddress(PMMSUPPORT AddressSpace, PVOID Address)
Definition: marea.c:60
uint32_t ULONG_PTR
Definition: typedefs.h:64
#define MEMORY_AREA_OWNED_BY_ARM3
Definition: mm.h:71
#define FALSE
Definition: types.h:117
NTSTATUS NTAPI MmpAccessFault(KPROCESSOR_MODE Mode, ULONG_PTR Address, BOOLEAN FromMdl)
Definition: mmfault.c:23
smooth NULL
Definition: ftsmooth.c:513
void DPRINT(...)
Definition: polytest.cpp:61
#define PAGE_ALIGN(Va)
BOOLEAN Mmi386MakeKernelPageTableGlobal(PVOID Address)
Definition: page.c:497
PVOID MmPagedPoolStart
Definition: miarm.h:552
FORCEINLINE PMMSUPPORT MmGetKernelAddressSpace(VOID)
Definition: mm.h:1376
NTSTATUS NTAPI MmNotPresentFault(KPROCESSOR_MODE Mode, ULONG_PTR Address, BOOLEAN FromMdl)
Definition: mmfault.c:110
#define MmSystemRangeStart
Definition: mm.h:25
FORCEINLINE PMMSUPPORT MmGetCurrentAddressSpace(VOID)
Definition: mm.h:1369
NTSTATUS NTAPI MmAccessFaultSectionView ( PMMSUPPORT  AddressSpace,
MEMORY_AREA MemoryArea,
PVOID  Address 
)

Definition at line 1692 of file section.c.

Referenced by MmpAccessFault().

1695 {
1697  PROS_SECTION_OBJECT Section;
1698  PFN_NUMBER OldPage;
1699  PFN_NUMBER NewPage;
1700  NTSTATUS Status;
1701  PVOID PAddress;
1704  ULONG_PTR Entry;
1705  PEPROCESS Process = MmGetAddressSpaceOwner(AddressSpace);
1706 
1707  DPRINT("MmAccessFaultSectionView(%p, %p, %p)\n", AddressSpace, MemoryArea, Address);
1708 
1709  /* Make sure we have a page mapping for this address. */
1710  Status = MmNotPresentFaultSectionView(AddressSpace, MemoryArea, Address, TRUE);
1711  if (!NT_SUCCESS(Status))
1712  {
1713  /* This is invalid access ! */
1714  return Status;
1715  }
1716 
1717  /*
1718  * Check if the page has already been set readwrite
1719  */
1720  if (MmGetPageProtect(Process, Address) & PAGE_READWRITE)
1721  {
1722  DPRINT("Address 0x%p\n", Address);
1723  return(STATUS_SUCCESS);
1724  }
1725 
1726  /*
1727  * Find the offset of the page
1728  */
1729  PAddress = MM_ROUND_DOWN(Address, PAGE_SIZE);
1730  Offset.QuadPart = (ULONG_PTR)PAddress - MA_GetStartingAddress(MemoryArea)
1731  + MemoryArea->Data.SectionData.ViewOffset.QuadPart;
1732 
1733  Segment = MemoryArea->Data.SectionData.Segment;
1734  Section = MemoryArea->Data.SectionData.Section;
1735  Region = MmFindRegion((PVOID)MA_GetStartingAddress(MemoryArea),
1736  &MemoryArea->Data.SectionData.RegionListHead,
1737  Address, NULL);
1738  ASSERT(Region != NULL);
1739 
1740  /*
1741  * Check if we are doing COW
1742  */
1743  if (!((Segment->WriteCopy) &&
1744  (Region->Protect == PAGE_READWRITE ||
1745  Region->Protect == PAGE_EXECUTE_READWRITE)))
1746  {
1747  DPRINT("Address 0x%p\n", Address);
1748  return(STATUS_ACCESS_VIOLATION);
1749  }
1750 
1751  /* Get the page mapping this section offset. */
1752  MmLockSectionSegment(Segment);
1753  Entry = MmGetPageEntrySectionSegment(Segment, &Offset);
1754 
1755  /* Get the current page mapping for the process */
1756  ASSERT(MmIsPagePresent(Process, PAddress));
1757  OldPage = MmGetPfnForProcess(Process, PAddress);
1758  ASSERT(OldPage != 0);
1759 
1760  if (IS_SWAP_FROM_SSE(Entry) ||
1761  PFN_FROM_SSE(Entry) != OldPage)
1762  {
1763  MmUnlockSectionSegment(Segment);
1764  /* This is a private page. We must only change the page protection. */
1765  MmSetPageProtect(Process, PAddress, Region->Protect);
1766  return(STATUS_SUCCESS);
1767  }
1768 
1769  /*
1770  * Allocate a page
1771  */
1773  if (Process) MI_SET_PROCESS2(Process->ImageFileName);
1774  if (!Process) MI_SET_PROCESS2("Kernel Section");
1775  Status = MmRequestPageMemoryConsumer(MC_USER, TRUE, &NewPage);
1776  if (!NT_SUCCESS(Status))
1777  {
1778  KeBugCheck(MEMORY_MANAGEMENT);
1779  }
1780 
1781  /*
1782  * Copy the old page
1783  */
1784  MiCopyFromUserPage(NewPage, OldPage);
1785 
1786  /*
1787  * Unshare the old page.
1788  */
1789  DPRINT("Swapping page (Old %x New %x)\n", OldPage, NewPage);
1790  MmDeleteVirtualMapping(Process, PAddress, NULL, NULL);
1791  MmDeleteRmap(OldPage, Process, PAddress);
1792  MmUnsharePageEntrySectionSegment(Section, Segment, &Offset, FALSE, FALSE, NULL);
1793  MmUnlockSectionSegment(Segment);
1794 
1795  /*
1796  * Set the PTE to point to the new page
1797  */
1798  Status = MmCreateVirtualMapping(Process,
1799  PAddress,
1800  Region->Protect,
1801  &NewPage,
1802  1);
1803  if (!NT_SUCCESS(Status))
1804  {
1805  DPRINT1("MmCreateVirtualMapping failed, unable to create virtual mapping, not out of memory\n");
1806  KeBugCheck(MEMORY_MANAGEMENT);
1807  return(Status);
1808  }
1809  MmInsertRmap(NewPage, Process, PAddress);
1810 
1811  MiSetPageEvent(Process, Address);
1812  DPRINT("Address 0x%p\n", Address);
1813  return(STATUS_SUCCESS);
1814 }
DWORD *typedef PVOID
Definition: winlogon.h:52
#define STATUS_SUCCESS
Definition: contextmenu.cpp:55
PMM_REGION NTAPI MmFindRegion(PVOID BaseAddress, PLIST_ENTRY RegionListHead, PVOID Address, PVOID *RegionBaseAddress)
Definition: region.c:257
BOOLEAN WriteCopy
Definition: mm.h:166
#define TRUE
Definition: types.h:120
PVOID ULONG Address
Definition: oprghdlr.h:14
VOID NTAPI MmInsertRmap(PFN_NUMBER Page, struct _EPROCESS *Process, PVOID Address)
#define MiSetPageEvent(Process, Address)
Definition: newmm.h:43
struct _Entry Entry
Definition: kefuncs.h:640
#define PFN_FROM_SSE(E)
Definition: newmm.h:7
NTSTATUS NTAPI MmCreateVirtualMapping(struct _EPROCESS *Process, PVOID Address, ULONG flProtect, PPFN_NUMBER Pages, ULONG PageCount)
ULONG NTAPI MmGetPageProtect(struct _EPROCESS *Process, PVOID Address)
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel)?(CompletionRoutine!=NULL):TRUE)
#define MC_USER
Definition: mm.h:92
VOID NTAPI MmDeleteRmap(PFN_NUMBER Page, struct _EPROCESS *Process, PVOID Address)
Definition: mm.h:390
union _MEMORY_AREA::@1571 Data
NTSTATUS NTAPI MmRequestPageMemoryConsumer(ULONG Consumer, BOOLEAN MyWait, PPFN_NUMBER AllocatedPage)
Definition: balance.c:229
uint32_t ULONG_PTR
Definition: typedefs.h:64
BOOLEAN NTAPI MmIsPagePresent(struct _EPROCESS *Process, PVOID Address)
ULONG PFN_NUMBER
Definition: ke.h:8
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
#define FALSE
Definition: types.h:117
NTSTATUS NTAPI MmNotPresentFaultSectionView(PMMSUPPORT AddressSpace, MEMORY_AREA *MemoryArea, PVOID Address, BOOLEAN Locked)
Definition: section.c:1282
#define MI_SET_PROCESS2(x)
Definition: mm.h:254
BOOLEAN NTAPI MmUnsharePageEntrySectionSegment(PROS_SECTION_OBJECT Section, PMM_SECTION_SEGMENT Segment, PLARGE_INTEGER Offset, BOOLEAN Dirty, BOOLEAN PageOut, ULONG_PTR *InEntry)
Definition: section.c:876
smooth NULL
Definition: ftsmooth.c:513
VOID NTAPI MmDeleteVirtualMapping(struct _EPROCESS *Process, PVOID Address, BOOLEAN *WasDirty, PPFN_NUMBER Page)
void DPRINT(...)
Definition: polytest.cpp:61
VOID NTAPI KeBugCheck(ULONG BugCheckCode)
Definition: bug.c:1469
#define MI_SET_USAGE(x)
Definition: mm.h:253
_Inout_ PVOID Segment
Definition: exfuncs.h:893
ULONG Protect
Definition: mm.h:393
VOID NTAPI MmSetPageProtect(struct _EPROCESS *Process, PVOID Address, ULONG flProtect)
struct _MEMORY_AREA::@1571::@1572 SectionData
#define MM_ROUND_DOWN(x, s)
Definition: mm.h:107
#define PAGE_SIZE
Definition: env_spec_w32.h:49
#define IS_SWAP_FROM_SSE(E)
Definition: newmm.h:8
#define MA_GetStartingAddress(_MemoryArea)
Definition: mm.h:203
Status
Definition: gdiplustypes.h:24
#define NT_SUCCESS(StatCode)
Definition: cmd.c:149
LONG NTSTATUS
Definition: DriverTester.h:11
#define STATUS_ACCESS_VIOLATION
Definition: ntstatus.h:228
PFN_NUMBER NTAPI MmGetPfnForProcess(struct _EPROCESS *Process, PVOID Address)
FORCEINLINE PEPROCESS MmGetAddressSpaceOwner(IN PMMSUPPORT AddressSpace)
Definition: mm.h:1361
NTSTATUS NTAPI MiCopyFromUserPage(PFN_NUMBER DestPage, PFN_NUMBER SrcPage)
Definition: section.c:1043
#define DPRINT1
Definition: precomp.h:8
#define MmLockSectionSegment(x)
Definition: newmm.h:276
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:219
CHAR ImageFileName[16]
Definition: pstypes.h:1258
#define ULONG_PTR
Definition: config.h:101
#define PAGE_EXECUTE_READWRITE
Definition: nt_native.h:1308
#define MmUnlockSectionSegment(x)
Definition: newmm.h:284
#define MmGetPageEntrySectionSegment(S, O)
Definition: newmm.h:143
LONGLONG QuadPart
Definition: typedefs.h:113
#define PAGE_READWRITE
Definition: nt_native.h:1304
NTSTATUS NTAPI MmAdjustWorkingSetSize ( IN SIZE_T  WorkingSetMinimumInBytes,
IN SIZE_T  WorkingSetMaximumInBytes,
IN ULONG  SystemCache,
IN BOOLEAN  IncreaseOkay 
)

Definition at line 44 of file mmsup.c.

Referenced by PspSetQuotaLimits().

48 {
49  SIZE_T MinimumWorkingSetSize, MaximumWorkingSetSize;
50  SSIZE_T Delta;
51  PMMSUPPORT Ws;
53 
54  /* Check for special case: empty the working set */
55  if ((WorkingSetMinimumInBytes == -1) &&
56  (WorkingSetMaximumInBytes == -1))
57  {
60  }
61 
62  /* Assume success */
63  Status = STATUS_SUCCESS;
64 
65  /* Get the working set and lock it */
66  Ws = &PsGetCurrentProcess()->Vm;
68 
69  /* Calculate the actual minimum and maximum working set size to set */
70  MinimumWorkingSetSize = (WorkingSetMinimumInBytes != 0) ?
71  (WorkingSetMinimumInBytes / PAGE_SIZE) : Ws->MinimumWorkingSetSize;
72  MaximumWorkingSetSize = (WorkingSetMaximumInBytes != 0) ?
73  (WorkingSetMaximumInBytes / PAGE_SIZE) : Ws->MaximumWorkingSetSize;
74 
75  /* Check if the new maximum exceeds the global maximum */
76  if (MaximumWorkingSetSize > MmMaximumWorkingSetSize)
77  {
78  MaximumWorkingSetSize = MmMaximumWorkingSetSize;
80  }
81 
82  /* Check if the new minimum is below the global minimum */
83  if (MinimumWorkingSetSize < MmMinimumWorkingSetSize)
84  {
85  MinimumWorkingSetSize = MmMinimumWorkingSetSize;
87  }
88 
89  /* Check if the new minimum exceeds the new maximum */
90  if (MinimumWorkingSetSize > MaximumWorkingSetSize)
91  {
92  DPRINT1("MinimumWorkingSetSize (%lu) > MaximumWorkingSetSize (%lu)\n",
93  MinimumWorkingSetSize, MaximumWorkingSetSize);
95  goto Cleanup;
96  }
97 
98  /* Calculate the minimum WS size adjustment and check if we increase */
99  Delta = MinimumWorkingSetSize - Ws->MinimumWorkingSetSize;
100  if (Delta > 0)
101  {
102  /* Is increasing ok? */
103  if (!IncreaseOkay)
104  {
105  DPRINT1("Privilege for WS size increase not held\n");
106  Status = STATUS_PRIVILEGE_NOT_HELD;
107  goto Cleanup;
108  }
109 
110  /* Check if the number of available pages is large enough */
111  if (((SIZE_T)Delta / 1024) > (MmAvailablePages - 128))
112  {
113  DPRINT1("Not enough available pages\n");
115  goto Cleanup;
116  }
117 
118  /* Check if there are enough resident available pages */
119  if ((SIZE_T)Delta >
121  {
122  DPRINT1("Not enough resident pages\n");
124  goto Cleanup;
125  }
126  }
127 
128  /* Update resident available pages */
129  if (Delta != 0)
130  {
132  }
133 
134  /* Calculate new pages above minimum WS size */
135  Delta += max((SSIZE_T)Ws->WorkingSetSize - MinimumWorkingSetSize, 0);
136 
137  /* Subtract old pages above minimum WS size */
138  Delta -= max((SSIZE_T)Ws->WorkingSetSize - Ws->MinimumWorkingSetSize, 0);
139 
140  /* If it changed, add it to the global variable */
141  if (Delta != 0)
142  {
144  }
145 
146  /* Set the new working set size */
147  Ws->MinimumWorkingSetSize = MinimumWorkingSetSize;
148  Ws->MaximumWorkingSetSize = MaximumWorkingSetSize;
149 
150 Cleanup:
151 
152  /* Unlock the working set and return the status */
154  return Status;
155 }
SIZE_T MmPagesAboveWsMinimum
Definition: mmsup.c:22
#define STATUS_SUCCESS
Definition: contextmenu.cpp:55
PFN_NUMBER MmResidentAvailablePages
Definition: freelist.c:27
#define STATUS_PRIVILEGE_NOT_HELD
Definition: DriverTester.h:9
#define max(a, b)
Definition: svc.c:63
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:225
SIZE_T MmSystemLockPagesCount
Definition: mdlsup.c:22
LONG_PTR SSIZE_T
Definition: basetsd.h:182
ULONG MinimumWorkingSetSize
Definition: mmtypes.h:915
PFN_NUMBER MmAvailablePages
Definition: freelist.c:26
#define STATUS_BAD_WORKING_SET_LIMIT
Definition: ntstatus.h:298
#define PsGetCurrentProcess
Definition: