ReactOS  0.4.15-dev-3718-g2318f7f
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  _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
 
struct  _MMPAGING_FILE
 

Macros

#define MI_QUOTA_NON_PAGED_NEEDED_PAGES   64
 
#define MI_NON_PAGED_QUOTA_MIN_RESIDENT_PAGES   200
 
#define MI_CHARGE_PAGED_POOL_QUOTA   0x80000
 
#define MI_CHARGE_NON_PAGED_POOL_QUOTA   0x10000
 
#define MM_NOIRQL   ((KIRQL)0xFFFFFFFF)
 
#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_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 MC_USER   (0)
 
#define MC_SYSTEM   (1)
 
#define MC_MAXIMUM   (2)
 
#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 MAX_PAGING_FILES   (16)
 
#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 InterlockedCompareExchangePte(PointerPte, Exchange, Comperand)   InterlockedCompareExchange((PLONG)(PointerPte), Exchange, Comperand)
 
#define InterlockedExchangePte(PointerPte, Value)   InterlockedExchange((PLONG)(PointerPte), Value)
 
#define MM_PHYSICALMEMORY_SEGMENT   (0x1)
 
#define MM_DATAFILE_SEGMENT   (0x2)
 
#define MM_SEGMENT_INDELETE   (0x4)
 
#define MM_SEGMENT_INCREATE   (0x8)
 
#define MM_IMAGE_SECTION_FLUSH_DELETE   (0x10)
 
#define MA_GetStartingAddress(_MemoryArea)   ((_MemoryArea)->VadNode.StartingVpn << PAGE_SHIFT)
 
#define MA_GetEndingAddress(_MemoryArea)   (((_MemoryArea)->VadNode.EndingVpn + 1) << PAGE_SHIFT)
 
#define MI_SET_USAGE(x)
 
#define MI_SET_PROCESS(x)
 
#define MI_SET_PROCESS2(x)
 
#define StartOfAllocation   ReadInProgress
 
#define EndOfAllocation   WriteInProgress
 
#define MM_FREE_POOL_SIGNATURE   'ARM3'
 
#define RMAP_SEGMENT_MASK   ~((ULONG_PTR)0xff)
 
#define RMAP_IS_SEGMENT(x)   (((ULONG_PTR)(x) & RMAP_SEGMENT_MASK) == RMAP_SEGMENT_MASK)
 
#define MI_ASSERT_PFN_LOCK_HELD()   NT_ASSERT((KeGetCurrentIrql() >= DISPATCH_LEVEL) && (MmPfnLock != 0))
 
#define MmSetCleanPage(__P, __A)   MmSetDirtyBit(__P, __A, FALSE)
 
#define MmSetDirtyPage(__P, __A)   MmSetDirtyBit(__P, __A, TRUE)
 
#define PFN_FROM_SSE(E)   ((PFN_NUMBER)((E) >> PAGE_SHIFT))
 
#define IS_SWAP_FROM_SSE(E)   ((E) & 0x00000001)
 
#define MM_IS_WAIT_PTE(E)   (IS_SWAP_FROM_SSE(E) && SWAPENTRY_FROM_SSE(E) == MM_WAIT_ENTRY)
 
#define MAKE_PFN_SSE(P)   ((ULONG_PTR)((P) << PAGE_SHIFT))
 
#define SWAPENTRY_FROM_SSE(E)   ((E) >> 1)
 
#define MAKE_SWAP_SSE(S)   (((ULONG_PTR)(S) << 1) | 0x1)
 
#define DIRTY_SSE(E)   ((E) | 2)
 
#define CLEAN_SSE(E)   ((E) & ~2)
 
#define IS_DIRTY_SSE(E)   ((E) & 2)
 
#define WRITE_SSE(E)   ((E) | 4)
 
#define IS_WRITE_SSE(E)   ((E) & 4)
 
#define PAGE_FROM_SSE(E)   ((E) & 0xFFFFF000)
 
#define SHARE_COUNT_FROM_SSE(E)   (((E) & 0x00000FFC) >> 3)
 
#define MAX_SHARE_COUNT   0x1FF
 
#define MAKE_SSE(P, C)   ((ULONG_PTR)((P) | ((C) << 3)))
 
#define BUMPREF_SSE(E)   (PAGE_FROM_SSE(E) | ((SHARE_COUNT_FROM_SSE(E) + 1) << 3) | ((E) & 0x7))
 
#define DECREF_SSE(E)   (PAGE_FROM_SSE(E) | ((SHARE_COUNT_FROM_SSE(E) - 1) << 3) | ((E) & 0x7))
 
#define MmLockSectionSegment(x)   _MmLockSectionSegment(x,__FILE__,__LINE__)
 
#define MmUnlockSectionSegment(x)   _MmUnlockSectionSegment(x,__FILE__,__LINE__)
 
#define MmSetPageEntrySectionSegment(S, O, E)   _MmSetPageEntrySectionSegment(S,O,E,__FILE__,__LINE__)
 
#define MmGetPageEntrySectionSegment(S, O)   _MmGetPageEntrySectionSegment(S,O,__FILE__,__LINE__)
 

Typedefs

typedef ULONG_PTR SWAPENTRY
 
typedef struct _MM_SECTION_SEGMENT MM_SECTION_SEGMENT
 
typedef struct _MM_SECTION_SEGMENTPMM_SECTION_SEGMENT
 
typedef struct _MM_IMAGE_SECTION_OBJECT MM_IMAGE_SECTION_OBJECT
 
typedef struct _MM_IMAGE_SECTION_OBJECTPMM_IMAGE_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_CONSUMERPMM_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_INFOPMM_PAGED_POOL_INFO
 
typedef struct _MMPAGING_FILE MMPAGING_FILE
 
typedef struct _MMPAGING_FILEPMMPAGING_FILE
 
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_PAGE_FILE, MI_USAGE_COW,
  MI_USAGE_WSLE, 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)
 
 _Requires_lock_held_ (PspQuotaLock) BOOLEAN NTAPI MmRaisePoolQuota(_In_ POOL_TYPE PoolType
 
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)
 
VOID 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 ULONG FaultCode, IN PVOID Address, IN KPROCESSOR_MODE Mode, IN PVOID TrapInformation)
 
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)
 
NTSTATUS NTAPI MmPageOutPhysicalAddress (PFN_NUMBER Page)
 
PMM_SECTION_SEGMENT NTAPI MmGetSectionAssociation (PFN_NUMBER Page, PLARGE_INTEGER Offset)
 
 _IRQL_raises_ (DISPATCH_LEVEL) _IRQL_requires_max_(DISPATCH_LEVEL) _Requires_lock_not_held_(MmPfnLock) _Acquires_lock_(MmPfnLock) _IRQL_saves_ FORCEINLINE KIRQL MiAcquirePfnLock(VOID)
 
 _Requires_lock_held_ (MmPfnLock) _Releases_lock_(MmPfnLock) _IRQL_requires_(DISPATCH_LEVEL) FORCEINLINE VOID MiReleasePfnLock(_In_ _IRQL_restores_ KIRQL OldIrql)
 
 _IRQL_requires_min_ (DISPATCH_LEVEL) _Requires_lock_not_held_(MmPfnLock) _Acquires_lock_(MmPfnLock) FORCEINLINE VOID MiAcquirePfnLockAtDpcLevel(VOID)
 
FORCEINLINE PMMPFN MiGetPfnEntry (IN PFN_NUMBER Pfn)
 
FORCEINLINE PFN_NUMBER MiGetPfnEntryIndex (IN PMMPFN Pfn1)
 
PFN_NUMBER NTAPI MmGetLRUNextUserPage (PFN_NUMBER PreviousPage, BOOLEAN MoveToLast)
 
PFN_NUMBER NTAPI MmGetLRUFirstUserPage (VOID)
 
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)
 
NTSTATUS NTAPI MmCreateVirtualMapping (struct _EPROCESS *Process, PVOID Address, ULONG flProtect, PFN_NUMBER Page)
 
NTSTATUS NTAPI MmCreateVirtualMappingUnsafe (struct _EPROCESS *Process, PVOID Address, ULONG flProtect, PFN_NUMBER Page)
 
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 MmDeletePageFileMapping (struct _EPROCESS *Process, PVOID Address, SWAPENTRY *SwapEntry)
 
NTSTATUS NTAPI MmCreatePageFileMapping (struct _EPROCESS *Process, PVOID Address, SWAPENTRY SwapEntry)
 
VOID NTAPI MmGetPageFileMapping (PEPROCESS Process, PVOID Address, SWAPENTRY *SwapEntry)
 
BOOLEAN NTAPI MmIsPageSwapEntry (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 MmSetDirtyBit (PEPROCESS Process, PVOID Address, BOOLEAN Bit)
 
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 MiArchCreateProcessAddressSpace (_In_ PEPROCESS Process, _In_ PULONG_PTR DirectoryTableBase)
 
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 _MmLockSectionSegment (PMM_SECTION_SEGMENT Segment, const char *file, int line)
 
VOID NTAPI _MmUnlockSectionSegment (PMM_SECTION_SEGMENT Segment, const char *file, int line)
 
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, BOOLEAN Locked)
 
VOID NTAPI MmFreeSectionSegments (PFILE_OBJECT FileObject)
 
NTSTATUS NTAPI MmMapViewInSystemSpaceEx (_In_ PVOID Section, _Outptr_result_bytebuffer_(*ViewSize) PVOID *MappedBase, _Inout_ PSIZE_T ViewSize, _Inout_ PLARGE_INTEGER SectionOffset, _In_ ULONG_PTR Flags)
 
BOOLEAN NTAPI MmArePagesResident (_In_ PEPROCESS Process, _In_ PVOID BaseAddress, _In_ ULONG Length)
 
NTSTATUS NTAPI MmMakePagesDirty (_In_ PEPROCESS Process, _In_ PVOID Address, _In_ ULONG Length)
 
NTSTATUS NTAPI MmFlushSegment (_In_ PSECTION_OBJECT_POINTERS SectionObjectPointer, _In_opt_ PLARGE_INTEGER Offset, _In_ ULONG Length, _Out_opt_ PIO_STATUS_BLOCK Iosb)
 
NTSTATUS NTAPI MmMakeDataSectionResident (_In_ PSECTION_OBJECT_POINTERS SectionObjectPointer, _In_ LONGLONG Offset, _In_ ULONG Length, _In_ PLARGE_INTEGER ValidDataLength)
 
BOOLEAN NTAPI MmPurgeSegment (_In_ PSECTION_OBJECT_POINTERS SectionObjectPointer, _In_opt_ PLARGE_INTEGER Offset, _In_ ULONG Length)
 
BOOLEAN NTAPI MmCheckDirtySegment (PMM_SECTION_SEGMENT Segment, PLARGE_INTEGER Offset, BOOLEAN ForceDirty, BOOLEAN PageOut)
 
BOOLEAN NTAPI MmUnsharePageEntrySectionSegment (PMEMORY_AREA MemoryArea, PMM_SECTION_SEGMENT Segment, PLARGE_INTEGER Offset, BOOLEAN Dirty, BOOLEAN PageOut, ULONG_PTR *InEntry)
 
 _When_ (OldIrql==MM_NOIRQL, _IRQL_requires_max_(DISPATCH_LEVEL)) _When_(OldIrql
 
 _Requires_lock_not_held_ (MmPfnLock)) _When_(OldIrql !
 
 _Releases_lock_ (MmPfnLock)) _When_(OldIrql !
 
 _IRQL_requires_ (DISPATCH_LEVEL)) VOID NTAPI MmDereferenceSegmentWithLock(_In_ PMM_SECTION_SEGMENT Segment
 
_In_ _When_ (OldIrql !=MM_NOIRQL, _IRQL_restores_) KIRQL OldIrql)
 
 _IRQL_requires_max_ (DISPATCH_LEVEL) _Requires_lock_not_held_(MmPfnLock) FORCEINLINE VOID MmDereferenceSegment(PMM_SECTION_SEGMENT Segment)
 
NTSTATUS NTAPI MmExtendSection (_In_ PVOID Section, _Inout_ PLARGE_INTEGER NewSize)
 
NTSTATUS NTAPI _MmSetPageEntrySectionSegment (PMM_SECTION_SEGMENT Segment, PLARGE_INTEGER Offset, ULONG_PTR Entry, const char *file, int line)
 
ULONG_PTR NTAPI _MmGetPageEntrySectionSegment (PMM_SECTION_SEGMENT Segment, PLARGE_INTEGER Offset, const char *file, int line)
 
VOID NTAPI MiReloadBootLoadedDrivers (IN PLOADER_PARAMETER_BLOCK LoaderBlock)
 
BOOLEAN NTAPI MiInitializeLoadedModuleList (IN PLOADER_PARAMETER_BLOCK LoaderBlock)
 
BOOLEAN NTAPI MmChangeKernelResourceSectionProtection (IN ULONG_PTR ProtectionMask)
 
VOID NTAPI MmMakeKernelResourceSectionWritable (VOID)
 
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)
 
VOID NTAPI MmFreeDriverInitialization (IN PLDR_DATA_TABLE_ENTRY LdrEntry)
 
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)
 
VOID MmShutdownSystem (IN ULONG Phase)
 
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)
 
 _Requires_exclusive_lock_held_ (WorkingSet->WorkingSetMutex) VOID NTAPI MiInitializeWorkingSetList(_Inout_ PMMSUPPORT WorkingSet)
 

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
 
ULONG MmThrottleTop
 
ULONG MmThrottleBottom
 
LIST_ENTRY MmLoadedUserImageList
 
KMUTANT MmSystemLoadLock
 
ULONG MmNumberOfPagingFiles
 
SIZE_T MmTotalNonPagedPoolQuota
 
SIZE_T MmTotalPagedPoolQuota
 
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
 
KSPIN_LOCK MmPfnLock
 
PMMPFN MmPfnDatabase
 
MMPFNLIST MmZeroedPageListHead
 
MMPFNLIST MmFreePageListHead
 
MMPFNLIST MmStandbyPageListHead
 
MMPFNLIST MmModifiedPageListHead
 
MMPFNLIST MmModifiedNoWritePageListHead
 
MM_MEMORY_CONSUMER MiMemoryConsumers [MC_MAXIMUM]
 
PMMPAGING_FILE MmPagingFile [MAX_PAGING_FILES]
 
_In_ SIZE_T CurrentMaxQuota
 
_In_ SIZE_T _Out_ PSIZE_T NewMaxQuota
 
_In_ SIZE_T QuotaToReturn
 
_Out_ PKAPC_STATE ApcState
 

Macro Definition Documentation

◆ BUMPREF_SSE

#define BUMPREF_SSE (   E)    (PAGE_FROM_SSE(E) | ((SHARE_COUNT_FROM_SSE(E) + 1) << 3) | ((E) & 0x7))

Definition at line 1344 of file mm.h.

◆ CACHE_ALIGNED_POOL_MASK

#define CACHE_ALIGNED_POOL_MASK   4

Definition at line 120 of file mm.h.

◆ CLEAN_SSE

#define CLEAN_SSE (   E)    ((E) & ~2)

Definition at line 1332 of file mm.h.

◆ DECREF_SSE

#define DECREF_SSE (   E)    (PAGE_FROM_SSE(E) | ((SHARE_COUNT_FROM_SSE(E) - 1) << 3) | ((E) & 0x7))

Definition at line 1345 of file mm.h.

◆ DIRTY_SSE

#define DIRTY_SSE (   E)    ((E) | 2)

Definition at line 1331 of file mm.h.

◆ EndOfAllocation

#define EndOfAllocation   WriteInProgress

Definition at line 356 of file mm.h.

◆ InterlockedCompareExchangePte

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

Definition at line 187 of file mm.h.

◆ InterlockedExchangePte

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

Definition at line 190 of file mm.h.

◆ IS_DIRTY_SSE

#define IS_DIRTY_SSE (   E)    ((E) & 2)

Definition at line 1333 of file mm.h.

◆ IS_SWAP_FROM_SSE

#define IS_SWAP_FROM_SSE (   E)    ((E) & 0x00000001)

Definition at line 1325 of file mm.h.

◆ IS_WRITE_SSE

#define IS_WRITE_SSE (   E)    ((E) & 4)

Definition at line 1335 of file mm.h.

◆ MA_GetEndingAddress

#define MA_GetEndingAddress (   _MemoryArea)    (((_MemoryArea)->VadNode.EndingVpn + 1) << PAGE_SHIFT)

Definition at line 245 of file mm.h.

◆ MA_GetStartingAddress

#define MA_GetStartingAddress (   _MemoryArea)    ((_MemoryArea)->VadNode.StartingVpn << PAGE_SHIFT)

Definition at line 244 of file mm.h.

◆ MAKE_PFN_SSE

#define MAKE_PFN_SSE (   P)    ((ULONG_PTR)((P) << PAGE_SHIFT))

Definition at line 1328 of file mm.h.

◆ MAKE_SSE

#define MAKE_SSE (   P,
  C 
)    ((ULONG_PTR)((P) | ((C) << 3)))

Definition at line 1343 of file mm.h.

◆ MAKE_SWAP_SSE

#define MAKE_SWAP_SSE (   S)    (((ULONG_PTR)(S) << 1) | 0x1)

Definition at line 1330 of file mm.h.

◆ MAX_PAGING_FILES

#define MAX_PAGING_FILES   (16)

Definition at line 125 of file mm.h.

◆ MAX_SHARE_COUNT

#define MAX_SHARE_COUNT   0x1FF

Definition at line 1342 of file mm.h.

◆ MC_MAXIMUM

#define MC_MAXIMUM   (2)

Definition at line 116 of file mm.h.

◆ MC_SYSTEM

#define MC_SYSTEM   (1)

Definition at line 115 of file mm.h.

◆ MC_USER

#define MC_USER   (0)

Definition at line 114 of file mm.h.

◆ MEMORY_AREA_OWNED_BY_ARM3

#define MEMORY_AREA_OWNED_BY_ARM3   (15)

Definition at line 97 of file mm.h.

◆ MEMORY_AREA_SECTION_VIEW

#define MEMORY_AREA_SECTION_VIEW   (1)

Definition at line 93 of file mm.h.

◆ MEMORY_AREA_STATIC

#define MEMORY_AREA_STATIC   (0x80000000)

Definition at line 98 of file mm.h.

◆ MI_ASSERT_PFN_LOCK_HELD

#define MI_ASSERT_PFN_LOCK_HELD ( )    NT_ASSERT((KeGetCurrentIrql() >= DISPATCH_LEVEL) && (MmPfnLock != 0))

Definition at line 1016 of file mm.h.

◆ MI_CHARGE_NON_PAGED_POOL_QUOTA

#define MI_CHARGE_NON_PAGED_POOL_QUOTA   0x10000

Definition at line 65 of file mm.h.

◆ MI_CHARGE_PAGED_POOL_QUOTA

#define MI_CHARGE_PAGED_POOL_QUOTA   0x80000

Definition at line 64 of file mm.h.

◆ MI_NON_PAGED_QUOTA_MIN_RESIDENT_PAGES

#define MI_NON_PAGED_QUOTA_MIN_RESIDENT_PAGES   200

Definition at line 63 of file mm.h.

◆ MI_QUOTA_NON_PAGED_NEEDED_PAGES

#define MI_QUOTA_NON_PAGED_NEEDED_PAGES   64

Definition at line 62 of file mm.h.

◆ MI_SET_PROCESS

#define MI_SET_PROCESS (   x)

Definition at line 318 of file mm.h.

◆ MI_SET_PROCESS2

#define MI_SET_PROCESS2 (   x)

Definition at line 319 of file mm.h.

◆ MI_SET_USAGE

#define MI_SET_USAGE (   x)

Definition at line 317 of file mm.h.

◆ MI_STATIC_MEMORY_AREAS

#define MI_STATIC_MEMORY_AREAS   (13)

Definition at line 90 of file mm.h.

◆ MM_DATAFILE_SEGMENT

#define MM_DATAFILE_SEGMENT   (0x2)

Definition at line 238 of file mm.h.

◆ MM_FREE_POOL_SIGNATURE

#define MM_FREE_POOL_SIGNATURE   'ARM3'

Definition at line 481 of file mm.h.

◆ MM_IMAGE_SECTION_FLUSH_DELETE

#define MM_IMAGE_SECTION_FLUSH_DELETE   (0x10)

Definition at line 241 of file mm.h.

◆ MM_IS_WAIT_PTE

#define MM_IS_WAIT_PTE (   E)    (IS_SWAP_FROM_SSE(E) && SWAPENTRY_FROM_SSE(E) == MM_WAIT_ENTRY)

Definition at line 1326 of file mm.h.

◆ MM_NOIRQL

#define MM_NOIRQL   ((KIRQL)0xFFFFFFFF)

Definition at line 70 of file mm.h.

◆ MM_PHYSICALMEMORY_SEGMENT

#define MM_PHYSICALMEMORY_SEGMENT   (0x1)

Definition at line 237 of file mm.h.

◆ MM_ROUND_DOWN

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

Definition at line 131 of file mm.h.

◆ MM_ROUND_UP

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

Definition at line 128 of file mm.h.

◆ MM_SEGMENT_INCREATE

#define MM_SEGMENT_INCREATE   (0x8)

Definition at line 240 of file mm.h.

◆ MM_SEGMENT_INDELETE

#define MM_SEGMENT_INDELETE   (0x4)

Definition at line 239 of file mm.h.

◆ MM_VIRTMEM_GRANULARITY

#define MM_VIRTMEM_GRANULARITY   (64 * 1024)

Definition at line 102 of file mm.h.

◆ MMDBG_COPY_CACHED

#define MMDBG_COPY_CACHED   0x00000008

Definition at line 78 of file mm.h.

◆ MMDBG_COPY_MAX_SIZE

#define MMDBG_COPY_MAX_SIZE   0x8

Definition at line 85 of file mm.h.

◆ MMDBG_COPY_PHYSICAL

#define MMDBG_COPY_PHYSICAL   0x00000002

Definition at line 76 of file mm.h.

◆ MMDBG_COPY_UNCACHED

#define MMDBG_COPY_UNCACHED   0x00000010

Definition at line 79 of file mm.h.

◆ MMDBG_COPY_UNSAFE

#define MMDBG_COPY_UNSAFE   0x00000004

Definition at line 77 of file mm.h.

◆ MMDBG_COPY_WRITE

#define MMDBG_COPY_WRITE   0x00000001

Definition at line 75 of file mm.h.

◆ MMDBG_COPY_WRITE_COMBINED

#define MMDBG_COPY_WRITE_COMBINED   0x00000020

Definition at line 80 of file mm.h.

◆ MmGetPageEntrySectionSegment

#define MmGetPageEntrySectionSegment (   S,
  O 
)    _MmGetPageEntrySectionSegment(S,O,__FILE__,__LINE__)

Definition at line 1559 of file mm.h.

◆ MmLockSectionSegment

#define MmLockSectionSegment (   x)    _MmLockSectionSegment(x,__FILE__,__LINE__)

Definition at line 1353 of file mm.h.

◆ MmSetCleanPage

#define MmSetCleanPage (   __P,
  __A 
)    MmSetDirtyBit(__P, __A, FALSE)

Definition at line 1216 of file mm.h.

◆ MmSetDirtyPage

#define MmSetDirtyPage (   __P,
  __A 
)    MmSetDirtyBit(__P, __A, TRUE)

Definition at line 1217 of file mm.h.

◆ MmSetPageEntrySectionSegment

#define MmSetPageEntrySectionSegment (   S,
  O,
  E 
)    _MmSetPageEntrySectionSegment(S,O,E,__FILE__,__LINE__)

Definition at line 1557 of file mm.h.

◆ MmUnlockSectionSegment

#define MmUnlockSectionSegment (   x)    _MmUnlockSectionSegment(x,__FILE__,__LINE__)

Definition at line 1361 of file mm.h.

◆ MUST_SUCCEED_POOL_MASK

#define MUST_SUCCEED_POOL_MASK   2

Definition at line 119 of file mm.h.

◆ PAGE_FLAGS_VALID_FOR_SECTION

#define PAGE_FLAGS_VALID_FOR_SECTION
Value:
PAGE_READWRITE | \
PAGE_WRITECOPY | \
PAGE_EXECUTE | \
PAGE_EXECUTE_READ | \
PAGE_EXECUTE_READWRITE | \
PAGE_EXECUTE_WRITECOPY | \
PAGE_NOACCESS | \
PAGE_NOCACHE)
#define PAGE_READONLY
Definition: compat.h:138

Definition at line 134 of file mm.h.

◆ PAGE_FROM_SSE

#define PAGE_FROM_SSE (   E)    ((E) & 0xFFFFF000)

Definition at line 1339 of file mm.h.

◆ PAGE_IS_EXECUTABLE

#define PAGE_IS_EXECUTABLE
Value:
PAGE_EXECUTE_READ | \
PAGE_EXECUTE_READWRITE | \
PAGE_EXECUTE_WRITECOPY)
#define PAGE_EXECUTE
Definition: nt_native.h:1306

Definition at line 159 of file mm.h.

◆ PAGE_IS_READABLE

#define PAGE_IS_READABLE
Value:
PAGE_READWRITE | \
PAGE_WRITECOPY | \
PAGE_EXECUTE_READ | \
PAGE_EXECUTE_READWRITE | \
PAGE_EXECUTE_WRITECOPY)
#define PAGE_READONLY
Definition: compat.h:138

Definition at line 145 of file mm.h.

◆ PAGE_IS_WRITABLE

#define PAGE_IS_WRITABLE
Value:
PAGE_WRITECOPY | \
PAGE_EXECUTE_READWRITE | \
PAGE_EXECUTE_WRITECOPY)
#define PAGE_READWRITE
Definition: nt_native.h:1304

Definition at line 153 of file mm.h.

◆ PAGE_IS_WRITECOPY

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

Definition at line 165 of file mm.h.

◆ PAGE_SYSTEM

#define PAGE_SYSTEM   (2048)

Definition at line 110 of file mm.h.

◆ PAGE_WRITETHROUGH

#define PAGE_WRITETHROUGH   (1024)

Definition at line 109 of file mm.h.

◆ PAGED_POOL_MASK

#define PAGED_POOL_MASK   1

Definition at line 118 of file mm.h.

◆ PFN_FROM_SSE

#define PFN_FROM_SSE (   E)    ((PFN_NUMBER)((E) >> PAGE_SHIFT))

Definition at line 1324 of file mm.h.

◆ QUOTA_POOL_MASK

#define QUOTA_POOL_MASK   8

Definition at line 121 of file mm.h.

◆ RMAP_IS_SEGMENT

#define RMAP_IS_SEGMENT (   x)    (((ULONG_PTR)(x) & RMAP_SEGMENT_MASK) == RMAP_SEGMENT_MASK)

Definition at line 913 of file mm.h.

◆ RMAP_SEGMENT_MASK

#define RMAP_SEGMENT_MASK   ~((ULONG_PTR)0xff)

Definition at line 912 of file mm.h.

◆ SEC_PHYSICALMEMORY

#define SEC_PHYSICALMEMORY   (0x80000000)

Definition at line 112 of file mm.h.

◆ SESSION_POOL_MASK

#define SESSION_POOL_MASK   32

Definition at line 122 of file mm.h.

◆ SHARE_COUNT_FROM_SSE

#define SHARE_COUNT_FROM_SSE (   E)    (((E) & 0x00000FFC) >> 3)

Definition at line 1341 of file mm.h.

◆ StartOfAllocation

#define StartOfAllocation   ReadInProgress

Definition at line 355 of file mm.h.

◆ STATUS_MM_RESTART_OPERATION

#define STATUS_MM_RESTART_OPERATION   ((NTSTATUS)0xD0000001)

Definition at line 104 of file mm.h.

◆ SWAPENTRY_FROM_SSE

#define SWAPENTRY_FROM_SSE (   E)    ((E) >> 1)

Definition at line 1329 of file mm.h.

◆ VERIFIER_POOL_MASK

#define VERIFIER_POOL_MASK   64

Definition at line 123 of file mm.h.

◆ WRITE_SSE

#define WRITE_SSE (   E)    ((E) | 4)

Definition at line 1334 of file mm.h.

Typedef Documentation

◆ MEMORY_AREA

◆ MI_PFN_USAGES

◆ MM_IMAGE_SECTION_OBJECT

◆ MM_MEMORY_CONSUMER

◆ MM_PAGED_POOL_INFO

◆ MM_REGION

◆ MM_RMAP_ENTRY

◆ MM_SECTION_SEGMENT

◆ MMFREE_POOL_ENTRY

◆ MMPAGING_FILE

◆ MMPFN

typedef struct _MMPFN MMPFN

◆ MMPFNENTRY

◆ MMPFNLIST

◆ PMEMORY_AREA

◆ PMM_ALTER_REGION_FUNC

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

Definition at line 516 of file mm.h.

◆ PMM_FREE_PAGE_FUNC

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

Definition at line 527 of file mm.h.

◆ PMM_IMAGE_SECTION_OBJECT

◆ PMM_MEMORY_CONSUMER

◆ PMM_PAGED_POOL_INFO

◆ PMM_REGION

◆ PMM_RMAP_ENTRY

◆ PMM_SECTION_SEGMENT

◆ PMMFREE_POOL_ENTRY

◆ PMMPAGING_FILE

◆ PMMPFN

typedef struct _MMPFN * PMMPFN

◆ PMMPFNLIST

◆ SWAPENTRY

Definition at line 56 of file mm.h.

Enumeration Type Documentation

◆ _MI_PFN_USAGES

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_PAGE_FILE 
MI_USAGE_COW 
MI_USAGE_WSLE 
MI_USAGE_FREE_PAGE 

Definition at line 322 of file mm.h.

323 {
324  MI_USAGE_NOT_SET = 0,
331  MI_USAGE_VAD,
339  MI_USAGE_MDL,
347  MI_USAGE_COW,
350 } MI_PFN_USAGES;
enum _MI_PFN_USAGES MI_PFN_USAGES

Function Documentation

◆ _IRQL_raises_()

_IRQL_raises_ ( DISPATCH_LEVEL  )

Definition at line 965 of file mm.h.

973 {
975 }
KIRQL FASTCALL KeAcquireQueuedSpinLock(IN KSPIN_LOCK_QUEUE_NUMBER LockNumber)
Definition: spinlock.c:108

◆ _IRQL_requires_()

_IRQL_requires_ ( DISPATCH_LEVEL  )

◆ _IRQL_requires_max_() [1/2]

_IRQL_requires_max_ ( DISPATCH_LEVEL  )

Definition at line 1525 of file mm.h.

1530 {
1531  MmDereferenceSegmentWithLock(Segment, MM_NOIRQL);
1532 }
#define MM_NOIRQL
Definition: mm.h:70
_Inout_ PVOID Segment
Definition: exfuncs.h:1101

◆ _IRQL_requires_max_() [2/2]

_IRQL_requires_max_ ( APC_LEVEL  )

Definition at line 197 of file cddata.c.

254 {
255  THREAD_CONTEXT ThreadContext = {0};
256  PIRP_CONTEXT IrpContext = NULL;
257  BOOLEAN Wait;
258 
259 #ifdef CD_SANITY
260  PVOID PreviousTopLevel;
261 #endif
262 
264 
265 #if DBG
266 
267  KIRQL SaveIrql = KeGetCurrentIrql();
268 
269 #endif
270 
272 
274 
276 
277 #ifdef CD_SANITY
278  PreviousTopLevel = IoGetTopLevelIrp();
279 #endif
280 
281  //
282  // Loop until this request has been completed or posted.
283  //
284 
285  do {
286 
287  //
288  // Use a try-except to handle the exception cases.
289  //
290 
291  _SEH2_TRY {
292 
293  //
294  // If the IrpContext is NULL then this is the first pass through
295  // this loop.
296  //
297 
298  if (IrpContext == NULL) {
299 
300  //
301  // Decide if this request is waitable an allocate the IrpContext.
302  // If the file object in the stack location is NULL then this
303  // is a mount which is always waitable. Otherwise we look at
304  // the file object flags.
305  //
306 
308 
309  Wait = TRUE;
310 
311  } else {
312 
313  Wait = CanFsdWait( Irp );
314  }
315 
316  IrpContext = CdCreateIrpContext( Irp, Wait );
317 
318  //
319  // Update the thread context information.
320  //
321 
322  CdSetThreadContext( IrpContext, &ThreadContext );
323 
324 #ifdef CD_SANITY
325  NT_ASSERT( !CdTestTopLevel ||
326  SafeNodeType( IrpContext->TopLevel ) == CDFS_NTC_IRP_CONTEXT );
327 #endif
328 
329  //
330  // Otherwise cleanup the IrpContext for the retry.
331  //
332 
333  } else {
334 
335  //
336  // Set the MORE_PROCESSING flag to make sure the IrpContext
337  // isn't inadvertently deleted here. Then cleanup the
338  // IrpContext to perform the retry.
339  //
340 
341  SetFlag( IrpContext->Flags, IRP_CONTEXT_FLAG_MORE_PROCESSING );
342  CdCleanupIrpContext( IrpContext, FALSE );
343  }
344 
345  //
346  // Case on the major irp code.
347  //
348 
349  switch (IrpContext->MajorFunction) {
350 
351  case IRP_MJ_CREATE :
352 
353  Status = CdCommonCreate( IrpContext, Irp );
354  break;
355 
356  case IRP_MJ_CLOSE :
357 
358  Status = CdCommonClose( IrpContext, Irp );
359  break;
360 
361  case IRP_MJ_READ :
362 
363  //
364  // If this is an Mdl complete request, don't go through
365  // common read.
366  //
367 
368  if (FlagOn( IrpContext->MinorFunction, IRP_MN_COMPLETE )) {
369 
370  Status = CdCompleteMdl( IrpContext, Irp );
371 
372  } else {
373 
374  Status = CdCommonRead( IrpContext, Irp );
375  }
376 
377  break;
378 
379  case IRP_MJ_WRITE :
380 
381  Status = CdCommonWrite( IrpContext, Irp );
382  break;
383 
385 
386  Status = CdCommonQueryInfo( IrpContext, Irp );
387  break;
388 
390 
391  Status = CdCommonSetInfo( IrpContext, Irp );
392  break;
393 
395 
396  Status = CdCommonQueryVolInfo( IrpContext, Irp );
397  break;
398 
400 
401  Status = CdCommonDirControl( IrpContext, Irp );
402  break;
403 
405 
406  Status = CdCommonFsControl( IrpContext, Irp );
407  break;
408 
409  case IRP_MJ_DEVICE_CONTROL :
410 
411  Status = CdCommonDevControl( IrpContext, Irp );
412  break;
413 
414  case IRP_MJ_LOCK_CONTROL :
415 
416  Status = CdCommonLockControl( IrpContext, Irp );
417  break;
418 
419  case IRP_MJ_CLEANUP :
420 
421  Status = CdCommonCleanup( IrpContext, Irp );
422  break;
423 
424  case IRP_MJ_PNP :
425 
426  Status = CdCommonPnp( IrpContext, Irp );
427  break;
428 
429  case IRP_MJ_SHUTDOWN :
430 
431  Status = CdCommonShutdown( IrpContext, Irp );
432  break;
433 
434  default :
435 
437  CdCompleteRequest( IrpContext, Irp, Status );
438  }
439 
441 
442  Status = CdProcessException( IrpContext, Irp, _SEH2_GetExceptionCode() );
443  } _SEH2_END;
444 
445  } while (Status == STATUS_CANT_WAIT);
446 
447 #ifdef CD_SANITY
448  NT_ASSERT( !CdTestTopLevel ||
449  (PreviousTopLevel == IoGetTopLevelIrp()) );
450 #endif
451 
453 
454  NT_ASSERT( SaveIrql == KeGetCurrentIrql( ));
455 
456  return Status;
457 }
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
VOID CdSetThreadContext(_Inout_ PIRP_CONTEXT IrpContext, _In_ PTHREAD_CONTEXT ThreadContext)
Definition: cddata.c:981
#define IRP_MJ_CREATE
Definition: rdpdr.c:44
#define FsRtlEnterFileSystem
#define FsRtlExitFileSystem
#define IRP_MJ_SHUTDOWN
#define TRUE
Definition: types.h:120
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
#define IRP_CONTEXT_FLAG_MORE_PROCESSING
Definition: cdstruc.h:1214
_In_ WDFDPC _In_ BOOLEAN Wait
Definition: wdfdpc.h:167
#define SafeNodeType(Ptr)
Definition: nodetype.h:54
#define IRP_MJ_PNP
Definition: cdrw_usr.h:52
LONG NTSTATUS
Definition: precomp.h:26
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138
_SEH2_TRY
Definition: create.c:4226
#define IRP_MN_COMPLETE
Definition: iotypes.h:4420
UCHAR KIRQL
Definition: env_spec_w32.h:591
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
#define FALSE
Definition: types.h:117
_In_ PIRP Irp
Definition: csq.h:116
VOID CdCompleteRequest(_Inout_opt_ PIRP_CONTEXT IrpContext, _Inout_opt_ PIRP Irp, _In_ NTSTATUS Status)
Definition: cddata.c:914
#define _SEH2_GetExceptionInformation()
Definition: pseh2_64.h:164
unsigned char BOOLEAN
#define IRP_MJ_QUERY_VOLUME_INFORMATION
Definition: rdpdr.c:50
#define IRP_MJ_DIRECTORY_CONTROL
Definition: rdpdr.c:51
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:547
Status
Definition: gdiplustypes.h:24
#define IRP_MJ_FILE_SYSTEM_CONTROL
PIRP NTAPI IoGetTopLevelIrp(VOID)
Definition: irp.c:1843
#define CanFsdWait(I)
Definition: cdprocs.h:2001
NTSTATUS CdCompleteMdl(_In_ PIRP_CONTEXT IrpContext, _Inout_ PIRP Irp)
Definition: cachesup.c:411
#define IRP_MJ_CLOSE
Definition: rdpdr.c:45
NTSTATUS CdCommonDevControl(_Inout_ PIRP_CONTEXT IrpContext, _Inout_ PIRP Irp)
Definition: devctrl.c:46
#define FlagOn(_F, _SF)
Definition: ext2fs.h:179
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2793
#define SetFlag(_F, _SF)
Definition: ext2fs.h:187
_SEH2_END
Definition: create.c:4400
LONG CdExceptionFilter(_Inout_ PIRP_CONTEXT IrpContext, _In_ PEXCEPTION_POINTERS ExceptionPointer)
Definition: cddata.c:525
#define ASSERT_OPTIONAL_IRP(I)
Definition: cddata.h:251
#define NULL
Definition: types.h:112
VOID CdCleanupIrpContext(_In_ PIRP_CONTEXT IrpContext, _In_ BOOLEAN Post)
Definition: strucsup.c:1733
NTSTATUS CdCommonLockControl(_Inout_ PIRP_CONTEXT IrpContext, _Inout_ PIRP Irp)
Definition: lockctrl.c:35
#define CDFS_NTC_IRP_CONTEXT
Definition: nodetype.h:34
#define IRP_MJ_LOCK_CONTROL
Definition: rdpdr.c:53
#define IRP_MJ_READ
Definition: rdpdr.c:46
#define IRP_MJ_CLEANUP
#define IRP_MJ_SET_INFORMATION
Definition: rdpdr.c:49
#define IRP_MJ_WRITE
Definition: rdpdr.c:47
#define IRP_MJ_QUERY_INFORMATION
Definition: rdpdr.c:48
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:40
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:165
_Ret_valid_ PIRP_CONTEXT CdCreateIrpContext(_In_ PIRP Irp, _In_ BOOLEAN Wait)
Definition: strucsup.c:1573
#define IRP_MJ_DEVICE_CONTROL
Definition: rdpdr.c:52
#define STATUS_CANT_WAIT
Definition: ntstatus.h:452
#define NT_ASSERT
Definition: rtlfuncs.h:3310

◆ _IRQL_requires_min_()

_IRQL_requires_min_ ( DISPATCH_LEVEL  )

Definition at line 988 of file mm.h.

994 {
995  PKSPIN_LOCK_QUEUE LockQueue;
996 
998  LockQueue = &KeGetCurrentPrcb()->LockQueue[LockQueuePfnLock];
999  KeAcquireQueuedSpinLockAtDpcLevel(LockQueue);
1000 }
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
FORCEINLINE struct _KPRCB * KeGetCurrentPrcb(VOID)
Definition: ketypes.h:1079
#define ASSERT(a)
Definition: mode.c:44
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696

◆ _MmGetPageEntrySectionSegment()

ULONG_PTR NTAPI _MmGetPageEntrySectionSegment ( PMM_SECTION_SEGMENT  Segment,
PLARGE_INTEGER  Offset,
const char file,
int  line 
)

Definition at line 266 of file sptab.c.

270 {
272  ULONG_PTR PageIndex, Result;
274 
275  ASSERT(Segment->Locked);
276  FileOffset.QuadPart = ROUND_DOWN(Offset->QuadPart,
279  if (!PageTable) return 0;
280  PageIndex = (ULONG_PTR)((Offset->QuadPart - PageTable->FileOffset.QuadPart) / PAGE_SIZE);
281  Result = PageTable->PageEntries[PageIndex];
282 #if 0
283  DPRINTC
284  ("MiGetPageEntrySectionSegment(%p,%08x%08x) => %x %s:%d\n",
285  Segment,
286  FileOffset.u.HighPart,
287  FileOffset.u.LowPart + PageIndex * PAGE_SIZE,
288  Result,
289  file, line);
290 #endif
291  return Result;
292 }
static PMEM_HOOK PageTable[TOTAL_PAGES]
Definition: memory.c:43
static PCACHE_SECTION_PAGE_TABLE NTAPI MiSectionPageTableGet(PRTL_GENERIC_TABLE Table, PLARGE_INTEGER FileOffset)
Definition: sptab.c:117
uint32_t ULONG_PTR
Definition: typedefs.h:65
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:426
Definition: parser.c:48
_Inout_ PVOID Segment
Definition: exfuncs.h:1101
#define ASSERT(a)
Definition: mode.c:44
#define PAGE_SIZE
Definition: env_spec_w32.h:49
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
#define ROUND_DOWN(n, align)
Definition: eventvwr.h:30
_In_ PFCB _In_ LONGLONG FileOffset
Definition: cdprocs.h:159
#define ULONG_PTR
Definition: config.h:101
#define DPRINTC
Definition: sptab.c:61
#define ENTRIES_PER_ELEMENT
Definition: newmm.h:21
Definition: fci.c:126

◆ _MmLockSectionSegment()

VOID NTAPI _MmLockSectionSegment ( PMM_SECTION_SEGMENT  Segment,
const char file,
int  line 
)

Definition at line 98 of file data.c.

99 {
100  //DPRINT("MmLockSectionSegment(%p,%s:%d)\n", Segment, file, line);
101  ExAcquireFastMutex(&Segment->Lock);
102  Segment->Locked = TRUE;
103 }
#define TRUE
Definition: types.h:120
_Inout_ PVOID Segment
Definition: exfuncs.h:1101
VOID FASTCALL ExAcquireFastMutex(IN PFAST_MUTEX FastMutex)
Definition: fmutex.c:23

◆ _MmSetPageEntrySectionSegment()

NTSTATUS NTAPI _MmSetPageEntrySectionSegment ( PMM_SECTION_SEGMENT  Segment,
PLARGE_INTEGER  Offset,
ULONG_PTR  Entry,
const char file,
int  line 
)

Definition at line 178 of file sptab.c.

183 {
184  ULONG_PTR PageIndex, OldEntry;
186 
187  ASSERT(Segment->Locked);
189 
191 
192  if (!PageTable) return STATUS_NO_MEMORY;
193 
195 
196  PageTable->Segment = Segment;
197  PageIndex = (ULONG_PTR)((Offset->QuadPart - PageTable->FileOffset.QuadPart) / PAGE_SIZE);
198  OldEntry = PageTable->PageEntries[PageIndex];
199 
200  DPRINT("MiSetPageEntrySectionSegment(%p,%08x%08x,%x=>%x)\n",
201  Segment,
202  Offset->u.HighPart,
203  Offset->u.LowPart,
204  OldEntry,
205  Entry);
206 
207  /* Manage ref on segment */
208  if (Entry && !OldEntry)
209  {
210  InterlockedIncrement64(Segment->ReferenceCount);
211  }
212  if (OldEntry && !Entry)
213  {
214  MmDereferenceSegment(Segment);
215  }
216 
217  if (Entry && !IS_SWAP_FROM_SSE(Entry))
218  {
219  /* We have a valid entry. See if we must do something */
220  if (OldEntry && !IS_SWAP_FROM_SSE(OldEntry))
221  {
222  /* The previous entry was valid. Shall we swap the Rmaps ? */
223  if (PFN_FROM_SSE(Entry) != PFN_FROM_SSE(OldEntry))
224  {
227  }
228  }
229  else
230  {
231  /*
232  * We're switching to a valid entry from an invalid one.
233  * Add the Rmap and take a ref on the segment.
234  */
236 
237  if (Offset->QuadPart >= (Segment->LastPage << PAGE_SHIFT))
238  Segment->LastPage = (Offset->QuadPart >> PAGE_SHIFT) + 1;
239  }
240  }
241  else if (OldEntry && !IS_SWAP_FROM_SSE(OldEntry))
242  {
243  /* We're switching to an invalid entry from a valid one */
245 
246  if (Offset->QuadPart == ((Segment->LastPage - 1ULL) << PAGE_SHIFT))
247  {
248  /* We are unsetting the last page */
249  while (--Segment->LastPage)
250  {
251  LARGE_INTEGER CheckOffset;
252  CheckOffset.QuadPart = (Segment->LastPage - 1) << PAGE_SHIFT;
254  if ((Entry != 0) && !IS_SWAP_FROM_SSE(Entry))
255  break;
256  }
257  }
258  }
259 
260  PageTable->PageEntries[PageIndex] = Entry;
261  return STATUS_SUCCESS;
262 }
#define PAGE_SHIFT
Definition: env_spec_w32.h:45
#define MmGetPageEntrySectionSegment(S, O)
Definition: mm.h:1559
struct _Entry Entry
Definition: kefuncs.h:627
static PMEM_HOOK PageTable[TOTAL_PAGES]
Definition: memory.c:43
#define PFN_FROM_SSE(E)
Definition: mm.h:1324
static PCACHE_SECTION_PAGE_TABLE NTAPI MiSectionPageTableGet(PRTL_GENERIC_TABLE Table, PLARGE_INTEGER FileOffset)
Definition: sptab.c:117
static PCACHE_SECTION_PAGE_TABLE NTAPI MiSectionPageTableGetOrAllocate(PRTL_GENERIC_TABLE Table, PLARGE_INTEGER FileOffset)
Definition: sptab.c:136
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define IS_DIRTY_SSE(E)
Definition: mm.h:1333
VOID NTAPI MmDeleteSectionAssociation(PFN_NUMBER Page)
Definition: rmap.c:495
#define ULL(a, b)
Definition: format_msg.c:27
_Inout_ PVOID Segment
Definition: exfuncs.h:1101
#define InterlockedIncrement64
Definition: interlocked.h:211
#define ASSERT(a)
Definition: mode.c:44
NTSTATUS NTAPI MmSetSectionAssociation(PFN_NUMBER Page, PMM_SECTION_SEGMENT Segment, PLARGE_INTEGER Offset)
Definition: sptab.c:382
#define PAGE_SIZE
Definition: env_spec_w32.h:49
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
#define IS_SWAP_FROM_SSE(E)
Definition: mm.h:1325
#define STATUS_NO_MEMORY
Definition: ntstatus.h:260
#define ULONG_PTR
Definition: config.h:101
#define STATUS_SUCCESS
Definition: shellext.h:65
#define DPRINT
Definition: sndvol32.h:71
base of all file and directory entries
Definition: entries.h:82
LONGLONG QuadPart
Definition: typedefs.h:114

◆ _MmUnlockSectionSegment()

VOID NTAPI _MmUnlockSectionSegment ( PMM_SECTION_SEGMENT  Segment,
const char file,
int  line 
)

Definition at line 107 of file data.c.

108 {
109  ASSERT(Segment->Locked);
110  Segment->Locked = FALSE;
111  ExReleaseFastMutex(&Segment->Lock);
112  //DPRINT("MmUnlockSectionSegment(%p,%s:%d)\n", Segment, file, line);
113 }
VOID FASTCALL ExReleaseFastMutex(IN PFAST_MUTEX FastMutex)
Definition: fmutex.c:31
#define FALSE
Definition: types.h:117
_Inout_ PVOID Segment
Definition: exfuncs.h:1101
#define ASSERT(a)
Definition: mode.c:44

◆ _Releases_lock_()

_Releases_lock_ ( MmPfnLock  )

◆ _Requires_exclusive_lock_held_()

_Requires_exclusive_lock_held_ ( WorkingSet->  WorkingSetMutex)

◆ _Requires_lock_held_() [1/2]

_Requires_lock_held_ ( PspQuotaLock  )

◆ _Requires_lock_held_() [2/2]

_Requires_lock_held_ ( MmPfnLock  )

Definition at line 977 of file mm.h.

984 {
986 }
VOID FASTCALL KeReleaseQueuedSpinLock(IN KSPIN_LOCK_QUEUE_NUMBER LockNumber, IN KIRQL OldIrql)
Definition: spinlock.c:154
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:790

◆ _Requires_lock_not_held_()

_Requires_lock_not_held_ ( MmPfnLock  )

◆ _When_() [1/2]

◆ _When_() [2/2]

_In_ _When_ ( OldIrql = MM_NOIRQL,
_IRQL_restores_   
)

◆ ExpCheckPoolAllocation()

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

Definition at line 296 of file expool.c.

300 {
302  ULONG i;
303  KIRQL OldIrql;
304  POOL_TYPE RealPoolType;
305 
306  /* Get the pool header */
307  Entry = ((PPOOL_HEADER)P) - 1;
308 
309  /* Check if this is a large allocation */
310  if (PAGE_ALIGN(P) == P)
311  {
312  /* Lock the pool table */
314 
315  /* Find the pool tag */
316  for (i = 0; i < PoolBigPageTableSize; i++)
317  {
318  /* Check if this is our allocation */
319  if (PoolBigPageTable[i].Va == P)
320  {
321  /* Make sure the tag is ok */
322  if (PoolBigPageTable[i].Key != Tag)
323  {
324  KeBugCheckEx(BAD_POOL_CALLER, 0x0A, (ULONG_PTR)P, PoolBigPageTable[i].Key, Tag);
325  }
326 
327  break;
328  }
329  }
330 
331  /* Release the lock */
333 
334  if (i == PoolBigPageTableSize)
335  {
336  /* Did not find the allocation */
337  //ASSERT(FALSE);
338  }
339 
340  /* Get Pool type by address */
341  RealPoolType = MmDeterminePoolType(P);
342  }
343  else
344  {
345  /* Verify the tag */
346  if (Entry->PoolTag != Tag)
347  {
348  DPRINT1("Allocation has wrong pool tag! Expected '%.4s', got '%.4s' (0x%08lx)\n",
349  &Tag, &Entry->PoolTag, Entry->PoolTag);
350  KeBugCheckEx(BAD_POOL_CALLER, 0x0A, (ULONG_PTR)P, Entry->PoolTag, Tag);
351  }
352 
353  /* Check the rest of the header */
355 
356  /* Get Pool type from entry */
357  RealPoolType = (Entry->PoolType - 1);
358  }
359 
360  /* Should we check the pool type? */
361  if (PoolType != -1)
362  {
363  /* Verify the pool type */
364  if (RealPoolType != PoolType)
365  {
366  DPRINT1("Wrong pool type! Expected %s, got %s\n",
367  PoolType & BASE_POOL_TYPE_MASK ? "PagedPool" : "NonPagedPool",
368  (Entry->PoolType - 1) & BASE_POOL_TYPE_MASK ? "PagedPool" : "NonPagedPool");
369  KeBugCheckEx(BAD_POOL_CALLER, 0xCC, (ULONG_PTR)P, Entry->PoolTag, Tag);
370  }
371  }
372 }
struct _Entry Entry
Definition: kefuncs.h:627
VOID NTAPI KeAcquireSpinLock(PKSPIN_LOCK SpinLock, PKIRQL OldIrql)
Definition: spinlock.c:50
uint32_t ULONG_PTR
Definition: typedefs.h:65
KSPIN_LOCK ExpLargePoolTableLock
Definition: expool.c:54
UCHAR KIRQL
Definition: env_spec_w32.h:591
SIZE_T PoolBigPageTableSize
Definition: expool.c:47
VOID NTAPI ExpCheckPoolHeader(IN PPOOL_HEADER Entry)
Definition: expool.c:193
#define BASE_POOL_TYPE_MASK
Definition: ExPools.c:15
struct _POOL_HEADER * PPOOL_HEADER
POOL_TYPE NTAPI MmDeterminePoolType(IN PVOID VirtualAddress)
Definition: pool.c:408
INT POOL_TYPE
Definition: typedefs.h:78
#define PAGE_ALIGN(Va)
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:790
_Must_inspect_result_ _In_ WDFDEVICE _In_ BOOLEAN _In_opt_ PVOID Tag
Definition: wdfdevice.h:4061
#define P(row, col)
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
#define DPRINT1
Definition: precomp.h:8
PPOOL_TRACKER_BIG_PAGES PoolBigPageTable
Definition: expool.c:50
_Must_inspect_result_ _In_ WDFDEVICE _In_ DEVICE_REGISTRY_PROPERTY _In_ _Strict_type_match_ POOL_TYPE PoolType
Definition: wdfdevice.h:3810
unsigned int ULONG
Definition: retypes.h:1
base of all file and directory entries
Definition: entries.h:82
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:108

◆ ExReturnPoolQuota()

VOID NTAPI ExReturnPoolQuota ( IN PVOID  P)

Definition at line 1849 of file expool.c.

1850 {
1853  USHORT BlockSize;
1855 
1858  {
1859  return;
1860  }
1861 
1862  Entry = P;
1863  Entry--;
1865 
1866  PoolType = Entry->PoolType - 1;
1867  BlockSize = Entry->BlockSize;
1868 
1869  if (PoolType & QUOTA_POOL_MASK)
1870  {
1871  Process = ((PVOID *)POOL_NEXT_BLOCK(Entry))[-1];
1872  ASSERT(Process != NULL);
1873  if (Process)
1874  {
1875  if (Process->Pcb.Header.Type != ProcessObject)
1876  {
1877  DPRINT1("Object %p is not a process. Type %u, pool type 0x%x, block size %u\n",
1878  Process, Process->Pcb.Header.Type, Entry->PoolType, BlockSize);
1879  KeBugCheckEx(BAD_POOL_CALLER,
1881  (ULONG_PTR)P,
1882  Entry->PoolTag,
1883  (ULONG_PTR)Process);
1884  }
1885  ((PVOID *)POOL_NEXT_BLOCK(Entry))[-1] = NULL;
1888  BlockSize * POOL_BLOCK_SIZE);
1890  }
1891  }
1892 }
struct _Entry Entry
Definition: kefuncs.h:627
#define POOL_FLAG_SPECIAL_POOL
Definition: miarm.h:288
VOID NTAPI PsReturnPoolQuota(_In_ PEPROCESS Process, _In_ POOL_TYPE PoolType, _In_ SIZE_T Amount)
Returns the pool quota that the process was taking up.
Definition: quota.c:907
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define POOL_NEXT_BLOCK(x)
Definition: expool.c:64
#define BASE_POOL_TYPE_MASK
Definition: ExPools.c:15
#define ASSERT(a)
Definition: mode.c:44
INT POOL_TYPE
Definition: typedefs.h:78
#define ObDereferenceObject
Definition: obfuncs.h:203
#define P(row, col)
#define QUOTA_POOL_MASK
Definition: ExPools.c:16
unsigned short USHORT
Definition: pedump.c:61
#define NULL
Definition: types.h:112
#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
_Must_inspect_result_ _In_ WDFDEVICE _In_ DEVICE_REGISTRY_PROPERTY _In_ _Strict_type_match_ POOL_TYPE PoolType
Definition: wdfdevice.h:3810
ULONG ExpPoolFlags
Definition: expool.c:56
#define POOL_BLOCK_SIZE
Definition: miarm.h:274
BOOLEAN NTAPI MmIsSpecialPoolAddress(IN PVOID P)
base of all file and directory entries
Definition: entries.h:82
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:108
#define POOL_BILLED_PROCESS_INVALID
Definition: miarm.h:311

Referenced by IoFreeIrp().

◆ MiAllocatePoolPages()

PVOID NTAPI MiAllocatePoolPages ( IN POOL_TYPE  PoolType,
IN SIZE_T  SizeInBytes 
)

Definition at line 422 of file pool.c.

424 {
425  PFN_NUMBER PageFrameNumber;
426  PFN_COUNT SizeInPages, PageTableCount;
427  ULONG i;
428  KIRQL OldIrql;
429  PLIST_ENTRY NextEntry, NextHead, LastHead;
430  PMMPTE PointerPte, StartPte;
431  PMMPDE PointerPde;
432  ULONG EndAllocation;
433  MMPTE TempPte;
434  MMPDE TempPde;
435  PMMPFN Pfn1;
436  PVOID BaseVa, BaseVaStart;
437  PMMFREE_POOL_ENTRY FreeEntry;
438 
439  //
440  // Figure out how big the allocation is in pages
441  //
442  SizeInPages = (PFN_COUNT)BYTES_TO_PAGES(SizeInBytes);
443 
444  //
445  // Check for overflow
446  //
447  if (SizeInPages == 0)
448  {
449  //
450  // Fail
451  //
452  return NULL;
453  }
454 
455  //
456  // Handle paged pool
457  //
459  {
460  //
461  // If only one page is being requested, try to grab it from the S-LIST
462  //
463  if ((SizeInPages == 1) && (ExQueryDepthSList(&MiPagedPoolSListHead)))
464  {
466  if (BaseVa) return BaseVa;
467  }
468 
469  //
470  // Lock the paged pool mutex
471  //
473 
474  //
475  // Find some empty allocation space
476  //
478  SizeInPages,
480  if (i == 0xFFFFFFFF)
481  {
482  //
483  // Get the page bit count
484  //
485  i = ((SizeInPages - 1) / PTE_PER_PAGE) + 1;
486  DPRINT("Paged pool expansion: %lu %x\n", i, SizeInPages);
487 
488  //
489  // Check if there is enougn paged pool expansion space left
490  //
493  {
494  //
495  // Out of memory!
496  //
497  DPRINT1("FAILED to allocate %Iu bytes from paged pool\n", SizeInBytes);
499  return NULL;
500  }
501 
502  //
503  // Check if we'll have to expand past the last PTE we have available
504  //
507  {
508  //
509  // We can only support this much then
510  //
512  PageTableCount = (PFN_COUNT)(PointerPde + 1 -
514  ASSERT(PageTableCount < i);
515  i = PageTableCount;
516  }
517  else
518  {
519  //
520  // Otherwise, there is plenty of space left for this expansion
521  //
522  PageTableCount = i;
523  }
524 
525  //
526  // Get the template PDE we'll use to expand
527  //
529 
530  //
531  // Get the first PTE in expansion space
532  //
534  BaseVa = MiPdeToPte(PointerPde);
535  BaseVaStart = BaseVa;
536 
537  //
538  // Lock the PFN database and loop pages
539  //
540  OldIrql = MiAcquirePfnLock();
541  do
542  {
543  //
544  // It should not already be valid
545  //
546  ASSERT(PointerPde->u.Hard.Valid == 0);
547 
548  /* Request a page */
550  MI_SET_PROCESS2("Kernel");
551  PageFrameNumber = MiRemoveAnyPage(MI_GET_NEXT_COLOR());
552  TempPde.u.Hard.PageFrameNumber = PageFrameNumber;
553 #if (_MI_PAGING_LEVELS >= 3)
554  /* On PAE/x64 systems, there's no double-buffering */
555  /* Initialize the PFN entry for it */
556  MiInitializePfnForOtherProcess(PageFrameNumber,
557  (PMMPTE)PointerPde,
558  PFN_FROM_PTE(MiAddressToPte(PointerPde)));
559 
560  /* Write the actual PDE now */
561  MI_WRITE_VALID_PDE(PointerPde, TempPde);
562 #else
563  //
564  // Save it into our double-buffered system page directory
565  //
566  MmSystemPagePtes[((ULONG_PTR)PointerPde & (SYSTEM_PD_SIZE - 1)) / sizeof(MMPTE)] = TempPde;
567 
568  /* Initialize the PFN */
569  MiInitializePfnForOtherProcess(PageFrameNumber,
570  (PMMPTE)PointerPde,
572 #endif
573 
574  //
575  // Move on to the next expansion address
576  //
577  PointerPde++;
578  BaseVa = (PVOID)((ULONG_PTR)BaseVa + PAGE_SIZE);
579  i--;
580  } while (i > 0);
581 
582  //
583  // Release the PFN database lock
584  //
585  MiReleasePfnLock(OldIrql);
586 
587  //
588  // These pages are now available, clear their availablity bits
589  //
592  PTE_PER_PAGE;
594  EndAllocation,
595  PageTableCount * PTE_PER_PAGE);
596 
597  //
598  // Update the next expansion location
599  //
601 
602  //
603  // Zero out the newly available memory
604  //
605  RtlZeroMemory(BaseVaStart, PageTableCount * PAGE_SIZE);
606 
607  //
608  // Now try consuming the pages again
609  //
611  SizeInPages,
612  0);
613  if (i == 0xFFFFFFFF)
614  {
615  //
616  // Out of memory!
617  //
618  DPRINT1("FAILED to allocate %Iu bytes from paged pool\n", SizeInBytes);
620  return NULL;
621  }
622  }
623 
624  //
625  // Update the pool hint if the request was just one page
626  //
627  if (SizeInPages == 1) MmPagedPoolInfo.PagedPoolHint = i + 1;
628 
629  //
630  // Update the end bitmap so we know the bounds of this allocation when
631  // the time comes to free it
632  //
633  EndAllocation = i + SizeInPages - 1;
635 
636  //
637  // Now we can release the lock (it mainly protects the bitmap)
638  //
640 
641  //
642  // Now figure out where this allocation starts
643  //
644  BaseVa = (PVOID)((ULONG_PTR)MmPagedPoolStart + (i << PAGE_SHIFT));
645 
646  //
647  // Flush the TLB
648  //
650 
651  /* Setup a demand-zero writable PTE */
653 
654  //
655  // Find the first and last PTE, then loop them all
656  //
657  PointerPte = MiAddressToPte(BaseVa);
658  StartPte = PointerPte + SizeInPages;
659  do
660  {
661  //
662  // Write the demand zero PTE and keep going
663  //
664  MI_WRITE_INVALID_PTE(PointerPte, TempPte);
665  } while (++PointerPte < StartPte);
666 
667  //
668  // Return the allocation address to the caller
669  //
670  return BaseVa;
671  }
672 
673  //
674  // If only one page is being requested, try to grab it from the S-LIST
675  //
676  if ((SizeInPages == 1) && (ExQueryDepthSList(&MiNonPagedPoolSListHead)))
677  {
679  if (BaseVa) return BaseVa;
680  }
681 
682  //
683  // Allocations of less than 4 pages go into their individual buckets
684  //
685  i = min(SizeInPages, MI_MAX_FREE_PAGE_LISTS) - 1;
686 
687  //
688  // Loop through all the free page lists based on the page index
689  //
690  NextHead = &MmNonPagedPoolFreeListHead[i];
692 
693  //
694  // Acquire the nonpaged pool lock
695  //
697  do
698  {
699  //
700  // Now loop through all the free page entries in this given list
701  //
702  NextEntry = NextHead->Flink;
703  while (NextEntry != NextHead)
704  {
705  /* Is freed non paged pool enabled */
707  {
708  /* We need to be able to touch this page, unprotect it */
709  MiUnProtectFreeNonPagedPool(NextEntry, 0);
710  }
711 
712  //
713  // Grab the entry and see if it can handle our allocation
714  //
715  FreeEntry = CONTAINING_RECORD(NextEntry, MMFREE_POOL_ENTRY, List);
716  ASSERT(FreeEntry->Signature == MM_FREE_POOL_SIGNATURE);
717  if (FreeEntry->Size >= SizeInPages)
718  {
719  //
720  // It does, so consume the pages from here
721  //
722  FreeEntry->Size -= SizeInPages;
723 
724  //
725  // The allocation will begin in this free page area
726  //
727  BaseVa = (PVOID)((ULONG_PTR)FreeEntry +
728  (FreeEntry->Size << PAGE_SHIFT));
729 
730  /* Remove the item from the list, depending if pool is protected */
733  else
734  RemoveEntryList(&FreeEntry->List);
735 
736  //
737  // However, check if its' still got space left
738  //
739  if (FreeEntry->Size != 0)
740  {
741  /* Check which list to insert this entry into */
742  i = min(FreeEntry->Size, MI_MAX_FREE_PAGE_LISTS) - 1;
743 
744  /* Insert the entry into the free list head, check for prot. pool */
747  else
749 
750  /* Is freed non paged pool protected? */
752  {
753  /* Protect the freed pool! */
754  MiProtectFreeNonPagedPool(FreeEntry, FreeEntry->Size);
755  }
756  }
757 
758  //
759  // Grab the PTE for this allocation
760  //
761  PointerPte = MiAddressToPte(BaseVa);
762  ASSERT(PointerPte->u.Hard.Valid == 1);
763 
764  //
765  // Grab the PFN NextEntry and index
766  //
767  Pfn1 = MiGetPfnEntry(PFN_FROM_PTE(PointerPte));
768 
769  //
770  // Now mark it as the beginning of an allocation
771  //
772  ASSERT(Pfn1->u3.e1.StartOfAllocation == 0);
773  Pfn1->u3.e1.StartOfAllocation = 1;
774 
775  /* Mark it as special pool if needed */
776  ASSERT(Pfn1->u4.VerifierAllocation == 0);
778  {
779  Pfn1->u4.VerifierAllocation = 1;
780  }
781 
782  //
783  // Check if the allocation is larger than one page
784  //
785  if (SizeInPages != 1)
786  {
787  //
788  // Navigate to the last PFN entry and PTE
789  //
790  PointerPte += SizeInPages - 1;
791  ASSERT(PointerPte->u.Hard.Valid == 1);
792  Pfn1 = MiGetPfnEntry(PointerPte->u.Hard.PageFrameNumber);
793  }
794 
795  //
796  // Mark this PFN as the last (might be the same as the first)
797  //
798  ASSERT(Pfn1->u3.e1.EndOfAllocation == 0);
799  Pfn1->u3.e1.EndOfAllocation = 1;
800 
801  //
802  // Release the nonpaged pool lock, and return the allocation
803  //
805  return BaseVa;
806  }
807 
808  //
809  // Try the next free page entry
810  //
811  NextEntry = FreeEntry->List.Flink;
812 
813  /* Is freed non paged pool protected? */
815  {
816  /* Protect the freed pool! */
817  MiProtectFreeNonPagedPool(FreeEntry, FreeEntry->Size);
818  }
819  }
820  } while (++NextHead < LastHead);
821 
822  //
823  // If we got here, we're out of space.
824  // Start by releasing the lock
825  //
827 
828  //
829  // Allocate some system PTEs
830  //
831  StartPte = MiReserveSystemPtes(SizeInPages, NonPagedPoolExpansion);
832  PointerPte = StartPte;
833  if (StartPte == NULL)
834  {
835  //
836  // Ran out of memory
837  //
838  DPRINT("Out of NP Expansion Pool\n");
839  return NULL;
840  }
841 
842  //
843  // Acquire the pool lock now
844  //
846 
847  //
848  // Lock the PFN database too
849  //
850  MiAcquirePfnLockAtDpcLevel();
851 
852  /* Check that we have enough available pages for this request */
853  if (MmAvailablePages < SizeInPages)
854  {
855  MiReleasePfnLockFromDpcLevel();
857 
858  MiReleaseSystemPtes(StartPte, SizeInPages, NonPagedPoolExpansion);
859 
860  DPRINT1("OUT OF AVAILABLE PAGES! Required %lu, Available %lu\n", SizeInPages, MmAvailablePages);
861 
862  return NULL;
863  }
864 
865  //
866  // Loop the pages
867  //
869  do
870  {
871  /* Allocate a page */
873  MI_SET_PROCESS2("Kernel");
874  PageFrameNumber = MiRemoveAnyPage(MI_GET_NEXT_COLOR());
875 
876  /* Get the PFN entry for it and fill it out */
877  Pfn1 = MiGetPfnEntry(PageFrameNumber);
878  Pfn1->u3.e2.ReferenceCount = 1;
879  Pfn1->u2.ShareCount = 1;
880  Pfn1->PteAddress = PointerPte;
882  Pfn1->u4.VerifierAllocation = 0;
883 
884  /* Write the PTE for it */
885  TempPte.u.Hard.PageFrameNumber = PageFrameNumber;
886  MI_WRITE_VALID_PTE(PointerPte++, TempPte);
887  } while (--SizeInPages > 0);
888 
889  //
890  // This is the last page
891  //
892  Pfn1->u3.e1.EndOfAllocation = 1;
893 
894  //
895  // Get the first page and mark it as such
896  //
897  Pfn1 = MiGetPfnEntry(StartPte->u.Hard.PageFrameNumber);
898  Pfn1->u3.e1.StartOfAllocation = 1;
899 
900  /* Mark it as a verifier allocation if needed */
901  ASSERT(Pfn1->u4.VerifierAllocation == 0);
903 
904  //
905  // Release the PFN and nonpaged pool lock
906  //
907  MiReleasePfnLockFromDpcLevel();
909 
910  //
911  // Return the address
912  //
913  return MiPteToAddress(StartPte);
914 }
#define MI_MAKE_SOFTWARE_PTE(p, x)
Definition: miarm.h:189
PRTL_BITMAP PagedPoolAllocationMap
Definition: mm.h:486
#define PDE_PER_PAGE
Definition: mm.h:21
#define PAGE_SHIFT
Definition: env_spec_w32.h:45
BOOLEAN NTAPI MiUnProtectFreeNonPagedPool(IN PVOID VirtualAddress, IN ULONG PageCount)
Definition: pool.c:70
#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
#define TRUE
Definition: types.h:120
PMMPTE NTAPI MiReserveSystemPtes(IN ULONG NumberOfPtes, IN MMSYSTEM_PTE_POOL_TYPE SystemPtePoolType)
Definition: syspte.c:246
ULONG Signature
Definition: mm.h:476
#define VERIFIER_POOL_MASK
Definition: mm.h:123
NTSYSAPI VOID NTAPI RtlSetBit(_In_ PRTL_BITMAP BitMapHeader, _In_range_(<, BitMapHeader->SizeOfBitMap) ULONG BitNumber)
Definition: bitmap.c:304
#define MI_GET_NEXT_COLOR()
Definition: miarm.h:237
HARDWARE_PDE_ARMV6 TempPde
Definition: winldr.c:78
VOID NTAPI MiInitializePfnForOtherProcess(IN PFN_NUMBER PageFrameIndex, IN PVOID PteAddress, IN PFN_NUMBER PteFrame)
Definition: pfnlist.c:1282
#define InsertTailList(ListHead, Entry)
PFN_NUMBER MmAvailablePages
Definition: freelist.c:26
FORCEINLINE PMMPDE MiPteToPde(PMMPTE PointerPte)
Definition: mm.h:268
USHORT PageLocation
Definition: mm.h:365
SLIST_HEADER MiNonPagedPoolSListHead
Definition: pool.c:32
uint32_t ULONG_PTR
Definition: typedefs.h:65
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
UCHAR KIRQL
Definition: env_spec_w32.h:591
MMPFNENTRY e1
Definition: mm.h:397
#define MiAddressToPte(x)
Definition: mmx86.c:19
ULONG PFN_NUMBER
Definition: ke.h:9
PMMPTE LastPteForPagedPool
Definition: mm.h:489
FORCEINLINE VOID MI_WRITE_VALID_PTE(IN PMMPTE PointerPte, IN MMPTE TempPte)
Definition: miarm.h:964
ULONG_PTR ShareCount
Definition: mm.h:390
VOID NTAPI MiProtectedPoolRemoveEntryList(IN PLIST_ENTRY Entry)
Definition: pool.c:168
#define MI_SET_PROCESS2(x)
Definition: mm.h:319
LIST_ENTRY List
Definition: mm.h:474
PFN_NUMBER MmSystemPageDirectory[PPE_PER_PAGE]
Definition: init.c:40
#define MI_MAX_FREE_PAGE_LISTS
Definition: mm.h:80
FORCEINLINE PMMPTE MiPdeToPte(PMMPDE PointerPde)
Definition: mm.h:244
ULONG_PTR VerifierAllocation
Definition: mm.h:420
NTSYSAPI ULONG WINAPI RtlFindClearBitsAndSet(PRTL_BITMAP, ULONG, ULONG)
#define BASE_POOL_TYPE_MASK
Definition: ExPools.c:15
FORCEINLINE VOID MI_WRITE_VALID_PDE(IN PMMPDE PointerPde, IN MMPDE TempPde)
Definition: miarm.h:1023
#define MI_SET_USAGE(x)
Definition: mm.h:317
void * PVOID
Definition: retypes.h:9
VOID NTAPI MiReleaseSystemPtes(IN PMMPTE StartingPte, IN ULONG NumberOfPtes, IN MMSYSTEM_PTE_POOL_TYPE SystemPtePoolType)
Definition: syspte.c:264
union _MMPFN::@1745 u2
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
VOID NTAPI KeFlushEntireTb(IN BOOLEAN Invalid, IN BOOLEAN AllProcessors)
Definition: cpu.c:400
PMMPDE MmSystemPagePtes
Definition: init.c:41
KGUARDED_MUTEX MmPagedPoolMutex
Definition: pool.c:24
PFN_COUNT Size
Definition: mm.h:475
ULONG PageFrameNumber
Definition: mmtypes.h:74
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
struct _MMPFN::@1746::@1752 e2
#define MM_FREE_POOL_SIGNATURE
Definition: mm.h:481
#define ASSERT(a)
Definition: mode.c:44
Definition: mm.h:472
ULONG64 Valid
Definition: mmtypes.h:150
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
#define PTE_PER_PAGE
Definition: mm.h:20
HARDWARE_PTE_ARMV6 TempPte
Definition: winldr.c:76
FORCEINLINE USHORT ExQueryDepthSList(_In_ PSLIST_HEADER SListHead)
Definition: exfuncs.h:153
union _MMPTE::@2272 u
MMPTE ValidKernelPte
Definition: init.c:29
union _MMPFN::@1746 u3
VOID NTAPI MiProtectedPoolInsertList(IN PLIST_ENTRY ListHead, IN PLIST_ENTRY Entry, IN BOOLEAN Critical)
Definition: pool.c:150
#define BYTES_TO_PAGES(Size)
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:790
#define MM_READWRITE
Definition: inbv.c:12
_Must_inspect_result_ _In_ WDFCMRESLIST List
Definition: wdfresource.h:550
Definition: mm.h:373
#define PAGE_SIZE
Definition: env_spec_w32.h:49
Definition: typedefs.h:119
KIRQL FASTCALL KeAcquireQueuedSpinLock(IN KSPIN_LOCK_QUEUE_NUMBER LockNumber)
Definition: spinlock.c:108
FORCEINLINE PMMPFN MiGetPfnEntry(IN PFN_NUMBER Pfn)
Definition: mm.h:1020
MMPTE ValidKernelPde
Definition: init.c:28
PVOID MmPagedPoolStart
Definition: miarm.h:579
NTSYSAPI void WINAPI RtlClearBits(PRTL_BITMAP, ULONG, ULONG)
PFN_NUMBER NTAPI MiRemoveAnyPage(IN ULONG Color)
Definition: pfnlist.c:477
MMPTE_HARDWARE Hard
Definition: mmtypes.h:217
#define SYSTEM_PD_SIZE
Definition: miarm.h:32
FORCEINLINE VOID MI_WRITE_INVALID_PTE(IN PMMPTE PointerPte, IN MMPTE InvalidPte)
Definition: miarm.h:997
BOOLEAN MmProtectFreedNonPagedPool
Definition: pool.c:31
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
PRTL_BITMAP EndOfPagedPoolBitmap
Definition: mm.h:487
PMMPTE PteAddress
Definition: mm.h:386
#define min(a, b)
Definition: monoChain.cc:55
#define NULL
Definition: types.h:112
VOID FASTCALL KeReleaseGuardedMutex(IN OUT PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:53
#define DPRINT1
Definition: precomp.h:8
union _MMPFN::@1749 u4
SLIST_HEADER MiPagedPoolSListHead
Definition: pool.c:34
_Must_inspect_result_ _In_ WDFDEVICE _In_ DEVICE_REGISTRY_PROPERTY _In_ _Strict_type_match_ POOL_TYPE PoolType
Definition: wdfdevice.h:3810
unsigned int ULONG
Definition: retypes.h:1
#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:41
ULONG PagedPoolHint
Definition: mm.h:491
#define InterlockedPopEntrySList(SListHead)
Definition: rtlfuncs.h:3392
#define DPRINT
Definition: sndvol32.h:71
PMMPTE FirstPteForPagedPool
Definition: mm.h:488
FORCEINLINE PVOID MiPteToAddress(PMMPTE PointerPte)
Definition: mm.h:208
LIST_ENTRY MmNonPagedPoolFreeListHead[MI_MAX_FREE_PAGE_LISTS]
Definition: pool.c:20
#define PFN_FROM_PTE(v)
Definition: mm.h:92
ULONG PageFrameNumber
Definition: mmtypes.h:109
PMMPDE NextPdeForPagedPoolExpansion
Definition: mm.h:490

Referenced by _IRQL_requires_(), ExAllocatePoolWithTag(), and InitializePool().

◆ MiArchCreateProcessAddressSpace()

BOOLEAN MiArchCreateProcessAddressSpace ( _In_ PEPROCESS  Process,
_In_ PULONG_PTR  DirectoryTableBase 
)

Definition at line 21 of file procsup.c.

24 {
25  KIRQL OldIrql;
26  PFN_NUMBER TableBasePfn, HyperPfn, HyperPdPfn, HyperPtPfn;
27  PMMPTE SystemPte;
28  MMPTE TempPte, PdePte;
29  ULONG TableIndex;
30  PMMPTE PageTablePointer;
31  ULONG PageColor;
32 
33  /* Non-arch specific code-path allocated those for us */
34  TableBasePfn = DirectoryTableBase[0] >> PAGE_SHIFT;
35  HyperPfn = DirectoryTableBase[1] >> PAGE_SHIFT;
36 
37  /*
38  * Lock PFN database. Try getting zero pages.
39  * If that doesn't work, we take the slow path
40  * outside of the PFN lock.
41  */
42  OldIrql = MiAcquirePfnLock();
44  HyperPdPfn = MiRemoveZeroPageSafe(PageColor);
45  if(!HyperPdPfn)
46  {
47  HyperPdPfn = MiRemoveAnyPage(PageColor);
48  MiReleasePfnLock(OldIrql);
49  MiZeroPhysicalPage(HyperPdPfn);
50  OldIrql = MiAcquirePfnLock();
51  }
53  HyperPtPfn = MiRemoveZeroPageSafe(PageColor);
54  if(!HyperPtPfn)
55  {
56  HyperPtPfn = MiRemoveAnyPage(PageColor);
57  MiReleasePfnLock(OldIrql);
58  MiZeroPhysicalPage(HyperPtPfn);
59  }
60  else
61  {
62  MiReleasePfnLock(OldIrql);
63  }
64 
65  /* Get a PTE to map the page directory */
66  SystemPte = MiReserveSystemPtes(1, SystemPteSpace);
67  if (!SystemPte)
68  return FALSE;
69 
70  /* Get its address */
71  PageTablePointer = MiPteToAddress(SystemPte);
72 
73  /* Build the PTE for the page directory and map it */
74  MI_MAKE_HARDWARE_PTE_KERNEL(&PdePte, SystemPte, MM_READWRITE, TableBasePfn);
75  MI_WRITE_VALID_PTE(SystemPte, PdePte);
76 
77  /* Copy the kernel mappings and zero out the rest */
78  TableIndex = PXE_PER_PAGE / 2;
79  RtlZeroMemory(PageTablePointer, TableIndex * sizeof(MMPTE));
80  RtlCopyMemory(PageTablePointer + TableIndex,
81  MiAddressToPxe(0) + TableIndex,
82  PAGE_SIZE - TableIndex * sizeof(MMPTE));
83 
84  /* Sanity check */
85  ASSERT(MiAddressToPxi(MmHyperSpaceEnd) >= TableIndex);
86 
87  /* Setup a PTE for the page directory mappings */
89 
90  /* Update the self mapping of the PML4 */
91  TableIndex = MiAddressToPxi((PVOID)PXE_SELFMAP);
92  TempPte.u.Hard.PageFrameNumber = TableBasePfn;
93  PageTablePointer[TableIndex] = TempPte;
94 
95  /* Write the PML4 entry for hyperspace */
96  TableIndex = MiAddressToPxi((PVOID)HYPER_SPACE);
97  TempPte.u.Hard.PageFrameNumber = HyperPfn;
98  PageTablePointer[TableIndex] = TempPte;
99 
100  /* Map the hyperspace PDPT to the system PTE */
101  PdePte.u.Hard.PageFrameNumber = HyperPfn;
102  *SystemPte = PdePte;
103  __invlpg(PageTablePointer);
104 
105  /* Write the hyperspace entry for the first PD */
106  TempPte.u.Hard.PageFrameNumber = HyperPdPfn;
107  PageTablePointer[0] = TempPte;
108 
109  /* Map the hyperspace PD to the system PTE */
110  PdePte.u.Hard.PageFrameNumber = HyperPdPfn;
111  *SystemPte = PdePte;
112  __invlpg(PageTablePointer);
113 
114  /* Write the hyperspace entry for the first PT */
115  TempPte.u.Hard.PageFrameNumber = HyperPtPfn;
116  PageTablePointer[0] = TempPte;
117 
118  /* Map the hyperspace PT to the system PTE */
119  PdePte.u.Hard.PageFrameNumber = HyperPtPfn;
120  *SystemPte = PdePte;
121  __invlpg(PageTablePointer);
122 
123  /* Write the hyperspace PTE for the working set list index */
124  TempPte.u.Hard.PageFrameNumber = Process->WorkingSetPage;
125  TableIndex = MiAddressToPti(MmWorkingSetList);
126  PageTablePointer[TableIndex] = TempPte;
127 
128  /* Release the system PTE */
129  MiReleaseSystemPtes(SystemPte, 1, SystemPteSpace);
130 
131  return TRUE;
132 }
#define PAGE_SHIFT
Definition: env_spec_w32.h:45
#define PXE_PER_PAGE
#define TRUE
Definition: types.h:120
PMMPTE NTAPI MiReserveSystemPtes(IN ULONG NumberOfPtes, IN MMSYSTEM_PTE_POOL_TYPE SystemPtePoolType)
Definition: syspte.c:246
VOID NTAPI MiZeroPhysicalPage(IN PFN_NUMBER PageFrameIndex)
Definition: pfnlist.c:122
UCHAR KIRQL
Definition: env_spec_w32.h:591
ULONG PFN_NUMBER
Definition: ke.h:9
#define FALSE
Definition: types.h:117
FORCEINLINE VOID MI_WRITE_VALID_PTE(IN PMMPTE PointerPte, IN MMPTE TempPte)
Definition: miarm.h:964
FORCEINLINE PFN_NUMBER MiRemoveZeroPageSafe(IN ULONG Color)
Definition: miarm.h:2420
VOID NTAPI MiReleaseSystemPtes(IN PMMPTE StartingPte, IN ULONG NumberOfPtes, IN MMSYSTEM_PTE_POOL_TYPE SystemPtePoolType)
Definition: syspte.c:264
#define PXE_SELFMAP
FORCEINLINE PMMPTE MiAddressToPxe(PVOID Address)
Definition: mm.h:171
#define ASSERT(a)
Definition: mode.c:44
#define MI_GET_NEXT_PROCESS_COLOR(x)
Definition: miarm.h:238
HARDWARE_PTE_ARMV6 TempPte
Definition: winldr.c:76
union _MMPTE::@2272 u
MMPTE ValidKernelPte
Definition: init.c:29
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:790
#define MM_READWRITE
Definition: inbv.c:12
FORCEINLINE ULONG MiAddressToPxi(PVOID Address)
Definition: mm.h:200
#define PAGE_SIZE
Definition: env_spec_w32.h:49
PMMWSL MmWorkingSetList
Definition: wslist.cpp:19
PFN_NUMBER NTAPI MiRemoveAnyPage(IN ULONG Color)
Definition: pfnlist.c:477
MMPTE_HARDWARE Hard
Definition: mmtypes.h:217
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:219
__INTRIN_INLINE void __invlpg(void *Address)
Definition: intrin_x86.h:1969
#define HYPER_SPACE
Definition: mm.h:14
PVOID MmHyperSpaceEnd
Definition: init.c:56
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
ULONG64 PageFrameNumber
Definition: mmtypes.h:171
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
FORCEINLINE VOID MI_MAKE_HARDWARE_PTE_KERNEL(IN PMMPTE NewPte, IN PMMPTE MappingPte, IN ULONG_PTR ProtectionMask, IN PFN_NUMBER PageFrameNumber)
Definition: miarm.h:778
FORCEINLINE PVOID MiPteToAddress(PMMPTE PointerPte)
Definition: mm.h:208
FORCEINLINE ULONG MiAddressToPti(PVOID Address)
Definition: mm.h:181
ULONG PageFrameNumber
Definition: mmtypes.h:109

Referenced by MmCreateProcessAddressSpace().

◆ MiCheckAllProcessMemoryAreas()

VOID NTAPI MiCheckAllProcessMemoryAreas ( VOID  )

◆ MiFreePoolPages()

ULONG NTAPI MiFreePoolPages ( IN PVOID  StartingAddress)

Definition at line 918 of file pool.c.

919 {
920  PMMPTE PointerPte, StartPte;
921  PMMPFN Pfn1, StartPfn;
922  PFN_COUNT FreePages, NumberOfPages;
923  KIRQL OldIrql;
924  PMMFREE_POOL_ENTRY FreeEntry, NextEntry, LastEntry;
925  ULONG i, End;
927 
928  //
929  // Handle paged pool
930  //
931  if ((StartingVa >= MmPagedPoolStart) && (StartingVa <= MmPagedPoolEnd))
932  {
933  //
934  // Calculate the offset from the beginning of paged pool, and convert it
935  // into pages
936  //
937  Offset = (ULONG_PTR)StartingVa - (ULONG_PTR)MmPagedPoolStart;
938  i = (ULONG)(Offset >> PAGE_SHIFT);
939  End = i;
940 
941  //
942  // Now use the end bitmap to scan until we find a set bit, meaning that
943  // this allocation finishes here
944  //
945  while (!RtlTestBit(MmPagedPoolInfo.EndOfPagedPoolBitmap, End)) End++;
946 
947  //
948  // Now calculate the total number of pages this allocation spans. If it's
949  // only one page, add it to the S-LIST instead of freeing it
950  //
951  NumberOfPages = End - i + 1;
952  if ((NumberOfPages == 1) &&
954  {
956  return 1;
957  }
958 
959  /* Delete the actual pages */
960  PointerPte = MmPagedPoolInfo.FirstPteForPagedPool + i;
961  FreePages = MiDeleteSystemPageableVm(PointerPte, NumberOfPages, 0, NULL);
962  ASSERT(FreePages == NumberOfPages);
963 
964  //
965  // Acquire the paged pool lock
966  //
968 
969  //
970  // Clear the allocation and free bits
971  //
974 
975  //
976  // Update the hint if we need to
977  //
979 
980  //
981  // Release the lock protecting the bitmaps
982  //
984 
985  //
986  // And finally return the number of pages freed
987  //
988  return NumberOfPages;
989  }
990 
991  //
992  // Get the first PTE and its corresponding PFN entry. If this is also the
993  // last PTE, meaning that this allocation was only for one page, push it into
994  // the S-LIST instead of freeing it
995  //
996  StartPte = PointerPte = MiAddressToPte(StartingVa);
997  StartPfn = Pfn1 = MiGetPfnEntry(PointerPte->u.Hard.PageFrameNumber);
998  if ((Pfn1->u3.e1.EndOfAllocation == 1) &&
1000  {
1002  return 1;
1003  }
1004 
1005  //
1006  // Loop until we find the last PTE
1007  //
1008  while (Pfn1->u3.e1.EndOfAllocation == 0)
1009  {
1010  //
1011  // Keep going
1012  //
1013  PointerPte++;
1014  Pfn1 = MiGetPfnEntry(PointerPte->u.Hard.PageFrameNumber);
1015  }
1016 
1017  //
1018  // Now we know how many pages we have
1019  //
1020  NumberOfPages = (PFN_COUNT)(PointerPte - StartPte + 1);
1021 
1022  //
1023  // Acquire the nonpaged pool lock
1024  //
1026 
1027  //
1028  // Mark the first and last PTEs as not part of an allocation anymore
1029  //
1030  StartPfn->u3.e1.StartOfAllocation = 0;
1031  Pfn1->u3.e1.EndOfAllocation = 0;
1032 
1033  //
1034  // Assume we will free as many pages as the allocation was
1035  //
1036  FreePages = NumberOfPages;
1037 
1038  //
1039  // Peek one page past the end of the allocation
1040  //
1041  PointerPte++;
1042 
1043  //
1044  // Guard against going past initial nonpaged pool
1045  //
1047  {
1048  //
1049  // This page is on the outskirts of initial nonpaged pool, so ignore it
1050  //
1051  Pfn1 = NULL;
1052  }
1053  else
1054  {
1055  /* Sanity check */
1056  ASSERT((ULONG_PTR)StartingVa + NumberOfPages <= (ULONG_PTR)MmNonPagedPoolEnd);
1057 
1058  /* Check if protected pool is enabled */
1060  {
1061  /* The freed block will be merged, it must be made accessible */
1063  }
1064 
1065  //
1066  // Otherwise, our entire allocation must've fit within the initial non
1067  // paged pool, or the expansion nonpaged pool, so get the PFN entry of
1068  // the next allocation
1069  //
1070  if (PointerPte->u.Hard.Valid == 1)
1071  {
1072  //
1073  // It's either expansion or initial: get the PFN entry
1074  //
1075  Pfn1 = MiGetPfnEntry(PointerPte->u.Hard.PageFrameNumber);
1076  }
1077  else
1078  {
1079  //
1080  // This means we've reached the guard page that protects the end of
1081  // the expansion nonpaged pool
1082  //
1083  Pfn1 = NULL;
1084  }
1085 
1086  }
1087 
1088  //
1089  // Check if this allocation actually exists
1090  //
1091  if ((Pfn1) && (Pfn1->u3.e1.StartOfAllocation == 0))
1092  {
1093  //
1094  // It doesn't, so we should actually locate a free entry descriptor
1095  //
1096  FreeEntry = (PMMFREE_POOL_ENTRY)((ULONG_PTR)StartingVa +
1097  (NumberOfPages << PAGE_SHIFT));
1098  ASSERT(FreeEntry->Signature == MM_FREE_POOL_SIGNATURE);
1099  ASSERT(FreeEntry->Owner == FreeEntry);
1100 
1101  /* Consume this entry's pages */
1102  FreePages += FreeEntry->Size;
1103 
1104  /* Remove the item from the list, depending if pool is protected */
1106  MiProtectedPoolRemoveEntryList(&FreeEntry->List);
1107  else
1108  RemoveEntryList(&FreeEntry->List);
1109  }
1110 
1111  //
1112  // Now get the official free entry we'll create for the caller's allocation
1113  //
1114  FreeEntry = StartingVa;
1115 
1116  //
1117  // Check if the our allocation is the very first page
1118  //
1120  {
1121  //
1122  // Then we can't do anything or we'll risk underflowing
1123  //
1124  Pfn1 = NULL;
1125  }
1126  else
1127  {
1128  //
1129  // Otherwise, get the PTE for the page right before our allocation
1130  //
1131  PointerPte -= NumberOfPages + 1;
1132 
1133  /* Check if protected pool is enabled */
1135  {
1136  /* The freed block will be merged, it must be made accessible */
1138  }
1139 
1140  /* Check if this is valid pool, or a guard page */
1141  if (PointerPte->u.Hard.Valid == 1)
1142  {
1143  //
1144  // It's either expansion or initial nonpaged pool, get the PFN entry
1145  //
1146  Pfn1 = MiGetPfnEntry(PointerPte->u.Hard.PageFrameNumber);
1147  }
1148  else
1149  {
1150  //
1151  // We must've reached the guard page, so don't risk touching it
1152  //
1153  Pfn1 = NULL;
1154  }
1155  }
1156 
1157  //
1158  // Check if there is a valid PFN entry for the page before the allocation
1159  // and then check if this page was actually the end of an allocation.
1160  // If it wasn't, then we know for sure it's a free page
1161  //
1162  if ((Pfn1) && (Pfn1->u3.e1.EndOfAllocation == 0))
1163  {
1164  //
1165  // Get the free entry descriptor for that given page range
1166  //
1167  FreeEntry = (PMMFREE_POOL_ENTRY)((ULONG_PTR)StartingVa - PAGE_SIZE);
1168  ASSERT(FreeEntry->Signature == MM_FREE_POOL_SIGNATURE);
1169  FreeEntry = FreeEntry->Owner;
1170 
1171  /* Check if protected pool is enabled */
1173  {
1174  /* The freed block will be merged, it must be made accessible */
1175  MiUnProtectFreeNonPagedPool(FreeEntry, 0);
1176  }
1177 
1178  //
1179  // Check if the entry is small enough (1-3 pages) to be indexed on a free list
1180  // If it is, we'll want to re-insert it, since we're about to
1181  // collapse our pages on top of it, which will change its count
1182  //
1183  if (FreeEntry->Size < MI_MAX_FREE_PAGE_LISTS)
1184  {
1185  /* Remove the item from the list, depending if pool is protected */
1187  MiProtectedPoolRemoveEntryList(&FreeEntry->List);
1188  else
1189  RemoveEntryList(&FreeEntry->List);
1190 
1191  //
1192  // Update its size
1193  //
1194  FreeEntry->Size += FreePages;
1195 
1196  //
1197  // And now find the new appropriate list to place it in
1198  //
1199  i = min(FreeEntry->Size, MI_MAX_FREE_PAGE_LISTS) - 1;
1200 
1201  /* Insert the entry into the free list head, check for prot. pool */
1204  else
1206  }
1207  else
1208  {
1209  //
1210  // Otherwise, just combine our free pages into this entry
1211  //
1212  FreeEntry->Size += FreePages;
1213  }
1214  }
1215 
1216  //
1217  // Check if we were unable to do any compaction, and we'll stick with this
1218  //
1219  if (FreeEntry == StartingVa)
1220  {
1221  //
1222  // Well, now we are a free entry. At worse we just have our newly freed
1223  // pages, at best we have our pages plus whatever entry came after us
1224  //
1225  FreeEntry->Size = FreePages;
1226 
1227  //
1228  // Find the appropriate list we should be on
1229  //
1230  i = min(FreeEntry->Size, MI_MAX_FREE_PAGE_LISTS) - 1;
1231 
1232  /* Insert the entry into the free list head, check for prot. pool */
1235  else
1237  }
1238 
1239  //
1240  // Just a sanity check
1241  //
1242  ASSERT(FreePages != 0);
1243 
1244  //
1245  // Get all the pages between our allocation and its end. These will all now
1246  // become free page chunks.
1247  //
1248  NextEntry = StartingVa;
1249  LastEntry = (PMMFREE_POOL_ENTRY)((ULONG_PTR)NextEntry + (FreePages << PAGE_SHIFT));
1250  do
1251  {
1252  //
1253  // Link back to the parent free entry, and keep going
1254  //
1255  NextEntry->Owner = FreeEntry;
1256  NextEntry->Signature = MM_FREE_POOL_SIGNATURE;
1257  NextEntry = (PMMFREE_POOL_ENTRY)((ULONG_PTR)NextEntry + PAGE_SIZE);
1258  } while (NextEntry != LastEntry);
1259 
1260  /* Is freed non paged pool protected? */
1262  {
1263  /* Protect the freed pool! */
1264  MiProtectFreeNonPagedPool(FreeEntry, FreeEntry->Size);
1265  }
1266 
1267  //
1268  // We're done, release the lock and let the caller know how much we freed
1269  //
1271  return NumberOfPages;
1272 }
PRTL_BITMAP PagedPoolAllocationMap
Definition: mm.h:486
#define PAGE_SHIFT
Definition: env_spec_w32.h:45
BOOLEAN NTAPI MiUnProtectFreeNonPagedPool(IN PVOID VirtualAddress, IN ULONG PageCount)
Definition: pool.c:70
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
#define TRUE
Definition: types.h:120
ULONG Signature
Definition: mm.h:476
PVOID MmPagedPoolEnd
Definition: init.c:26
#define InsertTailList(ListHead, Entry)
SLIST_HEADER MiNonPagedPoolSListHead
Definition: pool.c:32
PVOID MmNonPagedPoolEnd
Definition: mminit.c:99
uint32_t ULONG_PTR
Definition: typedefs.h:65
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
UCHAR KIRQL
Definition: env_spec_w32.h:591
MMPFNENTRY e1
Definition: mm.h:397
#define MiAddressToPte(x)
Definition: mmx86.c:19
VOID NTAPI MiProtectedPoolRemoveEntryList(IN PLIST_ENTRY Entry)
Definition: pool.c:168
PFN_NUMBER MiStartOfInitialPoolFrame
Definition: pool.c:23
LIST_ENTRY List
Definition: mm.h:474
#define MI_MAX_FREE_PAGE_LISTS
Definition: mm.h:80
KGUARDED_MUTEX MmPagedPoolMutex
Definition: pool.c:24
PFN_COUNT Size
Definition: mm.h:475
#define MM_FREE_POOL_SIGNATURE
Definition: mm.h:481
#define ASSERT(a)
Definition: mode.c:44
Definition: mm.h:472
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
union _MMPTE::@2272 u
union _MMPFN::@1746 u3
ULONG MiNonPagedPoolSListMaximum
Definition: pool.c:33
VOID NTAPI MiProtectedPoolInsertList(IN PLIST_ENTRY ListHead, IN PLIST_ENTRY Entry, IN BOOLEAN Critical)
Definition: pool.c:150
struct _MMFREE_POOL_ENTRY * Owner
Definition: mm.h:477
ULONG MiPagedPoolSListMaximum
Definition: pool.c:35
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:790
#define InterlockedPushEntrySList(SListHead, SListEntry)
Definition: rtlfuncs.h:3389
Definition: mm.h:373
#define PAGE_SIZE
Definition: env_spec_w32.h:49
KIRQL FASTCALL KeAcquireQueuedSpinLock(IN KSPIN_LOCK_QUEUE_NUMBER LockNumber)
Definition: spinlock.c:108
FORCEINLINE PMMPFN MiGetPfnEntry(IN PFN_NUMBER Pfn)
Definition: mm.h:1020
PVOID MmPagedPoolStart
Definition: miarm.h:579
PFN_COUNT NTAPI MiDeleteSystemPageableVm(IN PMMPTE PointerPte, IN PFN_NUMBER PageCount, IN ULONG Flags, OUT PPFN_NUMBER ValidPages)
Definition: virtual.c:275
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
NTSYSAPI void WINAPI RtlClearBits(PRTL_BITMAP, ULONG, ULONG)
MMPTE_HARDWARE Hard
Definition: mmtypes.h:217
BOOLEAN MmProtectFreedNonPagedPool
Definition: pool.c:31
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
struct _MMFREE_POOL_ENTRY * PMMFREE_POOL_ENTRY
PRTL_BITMAP EndOfPagedPoolBitmap
Definition: mm.h:487
#define min(a, b)
Definition: monoChain.cc:55
#define NULL
Definition: types.h:112
VOID FASTCALL KeReleaseGuardedMutex(IN OUT PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:53
SLIST_HEADER MiPagedPoolSListHead
Definition: pool.c:34
FORCEINLINE PFN_NUMBER MiGetPfnEntryIndex(IN PMMPFN Pfn1)
Definition: mm.h:1040
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:41
ULONG PagedPoolHint
Definition: mm.h:491
PMMPTE FirstPteForPagedPool
Definition: mm.h:488
FORCEINLINE PVOID MiPteToAddress(PMMPTE PointerPte)
Definition: mm.h:208
LIST_ENTRY MmNonPagedPoolFreeListHead[MI_MAX_FREE_PAGE_LISTS]
Definition: pool.c:20

Referenced by _IRQL_requires_(), and ExFreePoolWithTag().

◆ MiGetPfnEntry()

FORCEINLINE PMMPFN MiGetPfnEntry ( IN PFN_NUMBER  Pfn)

Definition at line 1020 of file mm.h.

1021 {
1022  PMMPFN Page;
1023  extern RTL_BITMAP MiPfnBitMap;
1024 
1025  /* Make sure the PFN number is valid */
1026  if (Pfn > MmHighestPhysicalPage) return NULL;
1027 
1028  /* Make sure this page actually has a PFN entry */
1029  if ((MiPfnBitMap.Buffer) && !(RtlTestBit(&MiPfnBitMap, (ULONG)Pfn))) return NULL;
1030 
1031  /* Get the entry */
1032  Page = &MmPfnDatabase[Pfn];
1033 
1034  /* Return it */
1035  return Page;
1036 };
PULONG Buffer
Definition: typedefs.h:91
PMMPFN MmPfnDatabase
Definition: freelist.c:24
RTL_BITMAP MiPfnBitMap
Definition: init.c:44
PFN_NUMBER Page
Definition: section.c:4924
_Must_inspect_result_ NTSYSAPI BOOLEAN NTAPI RtlTestBit(_In_ PRTL_BITMAP BitMapHeader, _In_range_(<, BitMapHeader->SizeOfBitMap) ULONG BitNumber)
Definition: bitmap.c:434
Definition: mm.h:373
#define NULL
Definition: types.h:112
PFN_NUMBER MmHighestPhysicalPage
Definition: meminit.c:31
unsigned int ULONG
Definition: retypes.h:1

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

◆ MiGetPfnEntryIndex()

FORCEINLINE PFN_NUMBER MiGetPfnEntryIndex ( IN PMMPFN  Pfn1)

Definition at line 1040 of file mm.h.

1041 {
1042  //
1043  // This will return the Page Frame Number (PFN) from the MMPFN
1044  //
1045  return Pfn1 - MmPfnDatabase;
1046 }
PMMPFN MmPfnDatabase
Definition: freelist.c:24

Referenced by MiAllocatePagesForMdl(), MiDecrementShareCount(), MiDereferencePfnAndDropLockCount(), MiFreePoolPages(), MiInsertPageInFreeList(), MiMapPagesInZeroSpace(), MiUnlinkFreeOrZeroedPage(), MmGetLRUFirstUserPage(), MmGetLRUNextUserPage(), MmInitializeProcessAddressSpace(), and MmZeroPageThread().

◆ MiInitBalancerThread()

VOID NTAPI MiInitBalancerThread ( VOID  )

Definition at line 361 of file balance.c.

362 {
366 
369 
370  Timeout.QuadPart = -20000000; /* 2 sec */
372  Timeout,
373  2000, /* 2 sec */
374  NULL);
375 
378  NULL,
379  NULL,
382  NULL);
383  if (!NT_SUCCESS(Status))
384  {
385  KeBugCheck(MEMORY_MANAGEMENT);
386  }
387 
391  &Priority,
392  sizeof(Priority));
393 
394 }
#define THREAD_ALL_ACCESS
Definition: nt_native.h:1339
VOID NTAPI MiBalancerThread(PVOID Unused)
Definition: balance.c:303
LONG NTSTATUS
Definition: precomp.h:26
#define LOW_REALTIME_PRIORITY
BOOLEAN NTAPI KeSetTimerEx(IN OUT PKTIMER Timer, IN LARGE_INTEGER DueTime, IN LONG Period, IN PKDPC Dpc OPTIONAL)
Definition: timerobj.c:294
LONG KPRIORITY
Definition: compat.h:662
static KEVENT MiBalancerEvent
Definition: balance.c:35
#define FALSE
Definition: types.h:117
DECLSPEC_NORETURN VOID NTAPI KeBugCheck(ULONG BugCheckCode)
Definition: bug.c:1427
static CLIENT_ID MiBalancerThreadId
Definition: balance.c:33
NTSTATUS NTAPI NtSetInformationThread(IN HANDLE ThreadHandle, IN THREADINFOCLASS ThreadInformationClass, IN PVOID ThreadInformation, IN ULONG ThreadInformationLength)
Definition: query.c:2018
Status
Definition: gdiplustypes.h:24
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
_In_ WDFINTERRUPT _In_ WDF_INTERRUPT_POLICY _In_ WDF_INTERRUPT_PRIORITY Priority
Definition: wdfinterrupt.h:651
static ULONG Timeout
Definition: ping.c:61
#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
#define NULL
Definition: types.h:112
static HANDLE MiBalancerThreadHandle
Definition: balance.c:34
VOID NTAPI KeInitializeTimerEx(OUT PKTIMER Timer, IN TIMER_TYPE Type)
Definition: timerobj.c:244
static KTIMER MiBalancerTimer
Definition: balance.c:36

Referenced by MmInitSystem().

◆ MiInitializeLoadedModuleList()

BOOLEAN NTAPI MiInitializeLoadedModuleList ( IN PLOADER_PARAMETER_BLOCK  LoaderBlock)

Definition at line 2204 of file sysldr.c.

2205 {
2206  PLDR_DATA_TABLE_ENTRY LdrEntry, NewEntry;
2207  PLIST_ENTRY ListHead, NextEntry;
2208  ULONG EntrySize;
2209 
2210  /* Setup the loaded module list and locks */
2214 
2215  /* Get loop variables and the kernel entry */
2216  ListHead = &LoaderBlock->LoadOrderListHead;
2217  NextEntry = ListHead->Flink;
2218  LdrEntry = CONTAINING_RECORD(NextEntry,
2220  InLoadOrderLinks);
2221  PsNtosImageBase = (ULONG_PTR)LdrEntry->DllBase;
2222 
2223  /* Locate resource section, pool code, and system pte code */
2224  MiLocateKernelSections(LdrEntry);
2225 
2226  /* Loop the loader block */
2227  while (NextEntry != ListHead)
2228  {
2229  /* Get the loader entry */
2230  LdrEntry = CONTAINING_RECORD(NextEntry,
2232  InLoadOrderLinks);
2233 
2234  /* FIXME: ROS HACK. Make sure this is a driver */
2235  if (!RtlImageNtHeader(LdrEntry->DllBase))
2236  {
2237  /* Skip this entry */
2238  NextEntry = NextEntry->Flink;
2239  continue;
2240  }
2241 
2242  /* Calculate the size we'll need and allocate a copy */
2243  EntrySize = sizeof(LDR_DATA_TABLE_ENTRY) +
2244  LdrEntry->BaseDllName.MaximumLength +
2245  sizeof(UNICODE_NULL);
2247  if (!NewEntry) return FALSE;
2248 
2249  /* Copy the entry over */
2250  *NewEntry = *LdrEntry;
2251 
2252  /* Allocate the name */
2253  NewEntry->FullDllName.Buffer =
2255  LdrEntry->FullDllName.MaximumLength +
2256  sizeof(UNICODE_NULL),
2257  TAG_LDR_WSTR);
2258  if (!NewEntry->FullDllName.Buffer)
2259  {
2261  return FALSE;
2262  }
2263 
2264  /* Set the base name */
2265  NewEntry->BaseDllName.Buffer = (PVOID)(NewEntry + 1);
2266 
2267  /* Copy the full and base name */
2268  RtlCopyMemory(NewEntry->FullDllName.Buffer,
2269  LdrEntry->FullDllName.Buffer,
2270  LdrEntry->FullDllName.MaximumLength);
2271  RtlCopyMemory(NewEntry->BaseDllName.Buffer,
2272  LdrEntry->BaseDllName.Buffer,
2273  LdrEntry->BaseDllName.MaximumLength);
2274 
2275  /* Null-terminate the base name */
2276  NewEntry->BaseDllName.Buffer[NewEntry->BaseDllName.Length /
2277  sizeof(WCHAR)] = UNICODE_NULL;
2278 
2279  /* Insert the entry into the list */
2281  NextEntry = NextEntry->Flink;
2282  }
2283 
2284  /* Build the import lists for the boot drivers */
2286 
2287  /* We're done */
2288  return TRUE;
2289 }
ERESOURCE PsLoadedModuleResource
Definition: sysldr.c:37
struct _LDR_DATA_TABLE_ENTRY LDR_DATA_TABLE_ENTRY
VOID NTAPI MiLocateKernelSections(IN PLDR_DATA_TABLE_ENTRY LdrEntry)
Definition: sysldr.c:2147
USHORT MaximumLength
Definition: env_spec_w32.h:370
ULONG_PTR PsNtosImageBase
Definition: sysldr.c:38
#define TRUE
Definition: types.h:120
LIST_ENTRY PsLoadedModuleList
Definition: sysldr.c:34
NTSTATUS ExInitializeResourceLite(PULONG res)
Definition: env_spec_w32.h:641
#define InsertTailList(ListHead, Entry)
_In_ UCHAR EntrySize
Definition: iofuncs.h:642
KSPIN_LOCK PsLoadedModuleSpinLock
Definition: sysldr.c:36
PVOID DllBase
Definition: btrfs_drv.h:1926
#define TAG_LDR_WSTR
Definition: tag.h:97
#define FALSE
Definition: types.h:117
#define UNICODE_NULL
FORCEINLINE VOID KeInitializeSpinLock(_Out_ PKSPIN_LOCK SpinLock)
Definition: kefuncs.h:238
void * PVOID
Definition: retypes.h:9
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
Definition: btrfs_drv.h:1922
Definition: typedefs.h:119
LIST_ENTRY InLoadOrderLinks
Definition: ldrtypes.h:138
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
NTSTATUS NTAPI MiBuildImportsForBootDrivers(VOID)
Definition: sysldr.c:1882
UNICODE_STRING FullDllName
Definition: btrfs_drv.h:1928
UNICODE_STRING BaseDllName
Definition: ldrtypes.h:145
#define RtlImageNtHeader
Definition: compat.h:665
#define TAG_MODULE_OBJECT
Definition: tag.h:96
unsigned int ULONG
Definition: retypes.h:1
#define ULONG_PTR
Definition: config.h:101
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099

Referenced by MmArmInitSystem().

◆ MiInitializeNonPagedPool()

VOID NTAPI MiInitializeNonPagedPool ( VOID  )

Definition at line 278 of file pool.c.

279 {
280  ULONG i;
281  PFN_COUNT PoolPages;
282  PMMFREE_POOL_ENTRY FreeEntry, FirstEntry;
283  PMMPTE PointerPte;
284  PAGED_CODE();
285 
286  //
287  // Initialize the pool S-LISTs as well as their maximum count. In general,
288  // we'll allow 8 times the default on a 2GB system, and two times the default
289  // on a 1GB system.
290  //
293  if (MmNumberOfPhysicalPages >= ((2 * _1GB) /PAGE_SIZE))
294  {
297  }
298  else if (MmNumberOfPhysicalPages >= (_1GB /PAGE_SIZE))
299  {
302  }
303 
304  //
305  // However if debugging options for the pool are enabled, turn off the S-LIST
306  // to reduce the risk of messing things up even more
307  //
309  {
312  }
313 
314  //
315  // We keep 4 lists of free pages (4 lists help avoid contention)
316  //
317  for (i = 0; i < MI_MAX_FREE_PAGE_LISTS; i++)
318  {
319  //
320  // Initialize each of them
321  //
323  }
324 
325  //
326  // Calculate how many pages the initial nonpaged pool has
327  //
329  MmNumberOfFreeNonPagedPool = PoolPages;
330 
331  //
332  // Initialize the first free entry
333  //
334  FreeEntry = MmNonPagedPoolStart;
335  FirstEntry = FreeEntry;
336  FreeEntry->Size = PoolPages;
337  FreeEntry->Signature = MM_FREE_POOL_SIGNATURE;
338  FreeEntry->Owner = FirstEntry;
339 
340  //
341  // Insert it into the last list
342  //
344  &FreeEntry->List);
345 
346  //
347  // Now create free entries for every single other page
348  //
349  while (PoolPages-- > 1)
350  {
351  //
352  // Link them all back to the original entry
353  //
354  FreeEntry = (PMMFREE_POOL_ENTRY)((ULONG_PTR)FreeEntry + PAGE_SIZE);
355  FreeEntry->Owner = FirstEntry;
356  FreeEntry->Signature = MM_FREE_POOL_SIGNATURE;
357  }
358 
359  //
360  // Validate and remember first allocated pool page
361  //
362  PointerPte = MiAddressToPte(MmNonPagedPoolStart);
363  ASSERT(PointerPte->u.Hard.Valid == 1);
365 
366  //
367  // Keep track of where initial nonpaged pool ends
368  //
371 
372  //
373  // Validate and remember last allocated pool page
374  //
375  PointerPte = MiAddressToPte((PVOID)((ULONG_PTR)MmNonPagedPoolEnd0 - 1));
376  ASSERT(PointerPte->u.Hard.Valid == 1);
378 
379  //
380  // Validate the first nonpaged pool expansion page (which is a guard page)
381  //
383  ASSERT(PointerPte->u.Hard.Valid == 0);
384 
385  //
386  // Calculate the size of the expansion region alone
387  //
390 
391  //
392  // Remove 2 pages, since there's a guard page on top and on the bottom
393  //
395 
396  //
397  // Now initialize the nonpaged pool expansion PTE space. Remember there's a
398  // guard page on top so make sure to skip it. The bottom guard page will be
399  // guaranteed by the fact our size is off by one.
400  //
401  MiInitializeSystemPtes(PointerPte + 1,
404 }
PFN_NUMBER MiEndOfInitialPoolFrame
Definition: pool.c:23
ULONG PFN_COUNT
Definition: mmtypes.h:102
FORCEINLINE VOID InsertHeadList(_Inout_ PLIST_ENTRY ListHead, _Inout_ __drv_aliasesMem PLIST_ENTRY Entry)
Definition: rtlfuncs.h:201
ULONG Signature
Definition: mm.h:476
PVOID MmNonPagedPoolExpansionStart
Definition: init.c:25
SLIST_HEADER MiNonPagedPoolSListHead
Definition: pool.c:32
uint32_t ULONG_PTR
Definition: typedefs.h:65
PFN_COUNT MmNumberOfFreeNonPagedPool
Definition: pool.c:21
#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:388
PFN_NUMBER MiStartOfInitialPoolFrame
Definition: pool.c:23
LIST_ENTRY List
Definition: mm.h:474
#define MI_MAX_FREE_PAGE_LISTS
Definition: mm.h:80
PVOID MmNonPagedPoolEnd0
Definition: pool.c:22
PFN_COUNT MiExpansionPoolPagesInitialCharge
Definition: pool.c:21
void * PVOID
Definition: retypes.h:9
FORCEINLINE VOID InitializeSListHead(_Out_ PSLIST_HEADER SListHead)
Definition: rtlfuncs.h:3351
PFN_COUNT Size
Definition: mm.h:475
#define MM_FREE_POOL_SIGNATURE
Definition: mm.h:481
#define ASSERT(a)
Definition: mode.c:44
Definition: mm.h:472
ULONG64 Valid
Definition: mmtypes.h:150
union _MMPTE::@2272 u
ULONG MiNonPagedPoolSListMaximum
Definition: pool.c:33
struct _MMFREE_POOL_ENTRY * Owner
Definition: mm.h:477
#define BYTES_TO_PAGES(Size)
ULONG MiPagedPoolSListMaximum
Definition: pool.c:35
#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:31
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
struct _MMFREE_POOL_ENTRY * PMMFREE_POOL_ENTRY
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
ULONG MmMaximumNonPagedPoolInBytes
Definition: init.c:22
SLIST_HEADER MiPagedPoolSListHead
Definition: pool.c:34
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:92
#define _1GB
Definition: miarm.h:20
#define PAGED_CODE()

Referenced by MiBuildNonPagedPool(), and MiInitMachineDependent().

◆ MiInitializeSpecialPool()

VOID NTAPI MiInitializeSpecialPool ( VOID  )

Definition at line 123 of file special.c.

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
#define MM_EMPTY_PTE_LIST
Definition: mm.h:87
#define POOL_FLAG_SPECIAL_POOL
Definition: miarm.h:288
ULONG MmNumberOfSystemPtes
Definition: init.c:42
PMMPTE MiSpecialPoolLastPte
Definition: special.c:44
PVOID MmSpecialPoolEnd
Definition: special.c:39
ULONG MmSpecialPoolTag
Definition: pool.c:29
PFN_COUNT MiSpecialPagesNonPagedMaximum
Definition: special.c:52
PVOID MiSpecialPoolExtra
Definition: special.c:40
#define ASSERT(a)
Definition: mode.c:44
MMPTE_LIST List
Definition: mmtypes.h:222
#define PTE_PER_PAGE
Definition: mm.h:20
union _MMPTE::@2272 u
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
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
PVOID MmSpecialPoolStart
Definition: special.c:38
#define PAGE_ROUND_UP(x)
Definition: mmtypes.h:38
PMMPTE MmSystemPteBase
Definition: syspte.c:21
#define DPRINT1
Definition: precomp.h:8
ULONG ExpPoolFlags
Definition: expool.c:56
unsigned int ULONG
Definition: retypes.h:1
FORCEINLINE PVOID MiPteToAddress(PMMPTE PointerPte)
Definition: mm.h:208
PMMPTE MiSpecialPoolFirstPte
Definition: special.c:43

Referenced by MiBuildPagedPool().

◆ MiMapPageInHyperSpace()

PVOID NTAPI MiMapPageInHyperSpace ( IN PEPROCESS  Process,
IN PFN_NUMBER  Page,
IN PKIRQL  OldIrql 
)

Definition at line 28 of file hypermap.c.

31 {
32  MMPTE TempPte;
33  PMMPTE PointerPte;
35 
36  //
37  // Never accept page 0 or non-physical pages
38  //
39  ASSERT(Page != 0);
41 
42  //
43  // Build the PTE
44  //
46  TempPte.u.Hard.PageFrameNumber = Page;
47 
48  //
49  // Pick the first hyperspace PTE
50  //
51  PointerPte = MmFirstReservedMappingPte;
52 
53  //
54  // Acquire the hyperlock
55  //
57  KeAcquireSpinLock(&Process->HyperSpaceLock, OldIrql);
58 
59  //
60  // Now get the first free PTE
61  //
62  Offset = PFN_FROM_PTE(PointerPte);
63  if (!Offset)
64  {
65  //
66  // Reset the PTEs
67  //
70  }
71 
72  //
73  // Prepare the next PTE
74  //
75  PointerPte->u.Hard.PageFrameNumber = Offset - 1;
76 
77  //
78  // Write the current PTE
79  //
80  PointerPte += Offset;
81  MI_WRITE_VALID_PTE(PointerPte, TempPte);
82 
83  //
84  // Return the address
85  //
86  return MiPteToAddress(PointerPte);
87 }
VOID NTAPI KeAcquireSpinLock(PKSPIN_LOCK SpinLock, PKIRQL OldIrql)
Definition: spinlock.c:50
ULONG PFN_NUMBER
Definition: ke.h:9
FORCEINLINE VOID MI_WRITE_VALID_PTE(IN PMMPTE PointerPte, IN MMPTE TempPte)
Definition: miarm.h:964
PMMPTE MmFirstReservedMappingPte
Definition: hypermap.c:20
#define PsGetCurrentProcess
Definition: psfuncs.h:17
#define MI_HYPERSPACE_PTES
Definition: mm.h:81
PFN_NUMBER Page
Definition: section.c:4924
#define ASSERT(a)
Definition: mode.c:44
MMPTE ValidKernelPteLocal
Definition: init.c:33
HARDWARE_PTE_ARMV6 TempPte
Definition: winldr.c:76
union _MMPTE::@2272 u
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:790
FORCEINLINE PMMPFN MiGetPfnEntry(IN PFN_NUMBER Pfn)
Definition: mm.h:1020
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
MMPTE_HARDWARE Hard
Definition: mmtypes.h:217
#define NULL
Definition: types.h:112
FORCEINLINE VOID KeFlushProcessTb(VOID)
Definition: ke.h:268
_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
FORCEINLINE PVOID MiPteToAddress(PMMPTE PointerPte)
Definition: mm.h:208
#define PFN_FROM_PTE(v)
Definition: mm.h:92
ULONG PageFrameNumber
Definition: mmtypes.h:109

Referenced by MiCopyFromUserPage(), MiReadFilePage(), and MiZeroPhysicalPage().

◆ MiMapPagesInZeroSpace()

PVOID NTAPI MiMapPagesInZeroSpace ( IN PMMPFN  Pfn1,
IN PFN_NUMBER  NumberOfPages 
)

Definition at line 111 of file hypermap.c.

113 {
114  MMPTE TempPte;
115  PMMPTE PointerPte;
116  PFN_NUMBER Offset, PageFrameIndex;
117 
118  //
119  // Sanity checks
120  //
122  ASSERT(NumberOfPages != 0);
123  ASSERT(NumberOfPages <= MI_ZERO_PTES);
124 
125  //
126  // Pick the first zeroing PTE
127  //
128  PointerPte = MiFirstReservedZeroingPte;
129 
130  //
131  // Now get the first free PTE
132  //
133  Offset = PFN_FROM_PTE(PointerPte);
134  if (NumberOfPages > Offset)
135  {
136  //
137  // Reset the PTEs
138  //
140  PointerPte->u.Hard.PageFrameNumber = Offset;
142  }
143 
144  //
145  // Prepare the next PTE
146