ReactOS 0.4.15-dev-8135-g1bc6c90
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)
 
FORCEINLINE VOID UpdateTotalCommittedPages (LONG Delta)
 
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)
 
NTSTATUS NTAPI MmCreatePhysicalMapping (_Inout_opt_ PEPROCESS Process, _In_ PVOID Address, _In_ ULONG flProtect, _In_ 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)
 
 _Success_ (return) BOOLEAN MmDeleteVirtualMapping(_Inout_opt_ PEPROCESS Process
 
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 ModuleListHead)
 
VOID NTAPI MmFreeDriverInitialization (IN PLDR_DATA_TABLE_ENTRY LdrEntry)
 
NTSTATUS NTAPI RtlpFindExportedRoutineByName (_In_ PVOID ImageBase, _In_ PCSTR ExportName, _Out_ PVOID *Function, _Out_opt_ PBOOLEAN IsForwarder, _In_ NTSTATUS NotFoundStatus)
 ReactOS-only helper routine for RtlFindExportedRoutineByName(), that provides a finer granularity regarding the nature of the export, and the failure reasons.
 
PVOID NTAPI RtlFindExportedRoutineByName (_In_ PVOID ImageBase, _In_ PCSTR ExportName)
 Finds the address of a given named exported routine in a loaded image. Note that this function does not support forwarders.
 
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
 
_In_ PVOID Address
 
_In_ PVOID _Out_opt_ BOOLEANWasDirty
 
_In_ PVOID _Out_opt_ BOOLEAN _Out_opt_ PPFN_NUMBER Page
 
_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 1388 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 1376 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 1389 of file mm.h.

◆ DIRTY_SSE

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

Definition at line 1375 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 1377 of file mm.h.

◆ IS_SWAP_FROM_SSE

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

Definition at line 1369 of file mm.h.

◆ IS_WRITE_SSE

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

Definition at line 1379 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 1372 of file mm.h.

◆ MAKE_SSE

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

Definition at line 1387 of file mm.h.

◆ MAKE_SWAP_SSE

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

Definition at line 1374 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 1386 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 1043 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 1370 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 1602 of file mm.h.

◆ MmLockSectionSegment

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

Definition at line 1397 of file mm.h.

◆ MmSetCleanPage

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

Definition at line 1251 of file mm.h.

◆ MmSetDirtyPage

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

Definition at line 1252 of file mm.h.

◆ MmSetPageEntrySectionSegment

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

Definition at line 1600 of file mm.h.

◆ MmUnlockSectionSegment

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

Definition at line 1405 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:
#define PAGE_READONLY
Definition: compat.h:138
#define PAGE_WRITECOPY
Definition: nt_native.h:1305
#define PAGE_NOCACHE
Definition: nt_native.h:1311
#define PAGE_READWRITE
Definition: nt_native.h:1304
#define PAGE_EXECUTE_READ
Definition: nt_native.h:1307
#define PAGE_EXECUTE
Definition: nt_native.h:1306
#define PAGE_EXECUTE_WRITECOPY
Definition: nt_native.h:1309
#define PAGE_NOACCESS
Definition: nt_native.h:1302
#define PAGE_EXECUTE_READWRITE
Definition: nt_native.h:1308

Definition at line 134 of file mm.h.

◆ PAGE_FROM_SSE

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

Definition at line 1383 of file mm.h.

◆ PAGE_IS_EXECUTABLE

#define PAGE_IS_EXECUTABLE
Value:

Definition at line 159 of file mm.h.

◆ PAGE_IS_READABLE

#define PAGE_IS_READABLE

◆ PAGE_IS_WRITABLE

#define PAGE_IS_WRITABLE
Value:

Definition at line 153 of file mm.h.

◆ PAGE_IS_WRITECOPY

#define PAGE_IS_WRITECOPY
Value:

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 1368 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 940 of file mm.h.

◆ RMAP_SEGMENT_MASK

#define RMAP_SEGMENT_MASK   ~((ULONG_PTR)0xff)

Definition at line 939 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 1385 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 1373 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 1378 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 515 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 526 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 57 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{
enum _MI_PFN_USAGES MI_PFN_USAGES
@ MI_USAGE_NONPAGED_POOL_EXPANSION
Definition: mm.h:327
@ MI_USAGE_LEGACY_PAGE_DIRECTORY
Definition: mm.h:336
@ MI_USAGE_PAGE_FILE
Definition: mm.h:346
@ MI_USAGE_NOT_SET
Definition: mm.h:324
@ MI_USAGE_COW
Definition: mm.h:347
@ MI_USAGE_PEB_TEB
Definition: mm.h:332
@ MI_USAGE_PAGE_TABLE
Definition: mm.h:334
@ MI_USAGE_INIT_MEMORY
Definition: mm.h:345
@ MI_USAGE_VAD
Definition: mm.h:331
@ MI_USAGE_SYSTEM_PTE
Definition: mm.h:330
@ MI_USAGE_CONTINOUS_ALLOCATION
Definition: mm.h:338
@ MI_USAGE_PAGED_POOL
Definition: mm.h:325
@ MI_USAGE_MDL
Definition: mm.h:339
@ MI_USAGE_PFN_DATABASE
Definition: mm.h:343
@ MI_USAGE_ZERO_LOOP
Definition: mm.h:341
@ MI_USAGE_DRIVER_PAGE
Definition: mm.h:337
@ MI_USAGE_DEMAND_ZERO
Definition: mm.h:340
@ MI_USAGE_SECTION
Definition: mm.h:333
@ MI_USAGE_WSLE
Definition: mm.h:348
@ MI_USAGE_FREE_PAGE
Definition: mm.h:349
@ MI_USAGE_PAGE_DIRECTORY
Definition: mm.h:335
@ MI_USAGE_CACHE
Definition: mm.h:342
@ MI_USAGE_KERNEL_STACK_EXPANSION
Definition: mm.h:329
@ MI_USAGE_KERNEL_STACK
Definition: mm.h:328
@ MI_USAGE_NONPAGED_POOL
Definition: mm.h:326
@ MI_USAGE_BOOT_DRIVER
Definition: mm.h:344

Function Documentation

◆ _IRQL_raises_()

_IRQL_raises_ ( DISPATCH_LEVEL  )

Definition at line 992 of file mm.h.

1000{
1002}
KIRQL FASTCALL KeAcquireQueuedSpinLock(IN KSPIN_LOCK_QUEUE_NUMBER LockNumber)
Definition: spinlock.c:108
@ LockQueuePfnLock
Definition: ketypes.h:660

◆ _IRQL_requires_()

_IRQL_requires_ ( DISPATCH_LEVEL  )

◆ _IRQL_requires_max_() [1/2]

_IRQL_requires_max_ ( APC_LEVEL  )

Definition at line 37 of file cddata.c.

254{
255 THREAD_CONTEXT ThreadContext = {0};
256 PIRP_CONTEXT IrpContext = NULL;
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
410
411 Status = CdCommonDevControl( IrpContext, Irp );
412 break;
413
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}
static PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(PIRP Irp)
unsigned char BOOLEAN
LONG NTSTATUS
Definition: precomp.h:26
VOID CdCompleteRequest(_Inout_opt_ PIRP_CONTEXT IrpContext, _Inout_opt_ PIRP Irp, _In_ NTSTATUS Status)
Definition: cddata.c:914
LONG CdExceptionFilter(_Inout_ PIRP_CONTEXT IrpContext, _In_ PEXCEPTION_POINTERS ExceptionPointer)
Definition: cddata.c:525
VOID CdSetThreadContext(_Inout_ PIRP_CONTEXT IrpContext, _In_ PTHREAD_CONTEXT ThreadContext)
Definition: cddata.c:981
#define ASSERT_OPTIONAL_IRP(I)
Definition: cddata.h:251
NTSTATUS CdCompleteMdl(_In_ PIRP_CONTEXT IrpContext, _Inout_ PIRP Irp)
Definition: cachesup.c:411
VOID CdCleanupIrpContext(_In_ PIRP_CONTEXT IrpContext, _In_ BOOLEAN Post)
Definition: strucsup.c:1733
#define CanFsdWait(I)
Definition: cdprocs.h:2001
NTSTATUS CdCommonLockControl(_Inout_ PIRP_CONTEXT IrpContext, _Inout_ PIRP Irp)
Definition: lockctrl.c:35
NTSTATUS CdCommonDevControl(_Inout_ PIRP_CONTEXT IrpContext, _Inout_ PIRP Irp)
Definition: devctrl.c:46
_Ret_valid_ PIRP_CONTEXT CdCreateIrpContext(_In_ PIRP Irp, _In_ BOOLEAN Wait)
Definition: strucsup.c:1573
#define IRP_MJ_PNP
Definition: cdrw_usr.h:52
#define IRP_CONTEXT_FLAG_MORE_PROCESSING
Definition: cdstruc.h:1214
_In_ PIRP Irp
Definition: csq.h:116
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define CDFS_NTC_IRP_CONTEXT
Definition: nodetype.h:34
#define SafeNodeType(Ptr)
Definition: nodetype.h:54
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
#define SetFlag(_F, _SF)
Definition: ext2fs.h:187
#define FlagOn(_F, _SF)
Definition: ext2fs.h:179
#define _SEH2_END
Definition: filesup.c:22
#define _SEH2_TRY
Definition: filesup.c:19
#define FsRtlEnterFileSystem
#define FsRtlExitFileSystem
Status
Definition: gdiplustypes.h:25
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
PIRP NTAPI IoGetTopLevelIrp(VOID)
Definition: irp.c:1843
#define STATUS_CANT_WAIT
Definition: ntstatus.h:452
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:165
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:66
#define _SEH2_GetExceptionInformation()
Definition: pseh2_64.h:164
#define IRP_MJ_DIRECTORY_CONTROL
Definition: rdpdr.c:51
#define IRP_MJ_CLOSE
Definition: rdpdr.c:45
#define IRP_MJ_READ
Definition: rdpdr.c:46
#define IRP_MJ_DEVICE_CONTROL
Definition: rdpdr.c:52
#define IRP_MJ_QUERY_VOLUME_INFORMATION
Definition: rdpdr.c:50
#define IRP_MJ_LOCK_CONTROL
Definition: rdpdr.c:53
#define IRP_MJ_WRITE
Definition: rdpdr.c:47
#define IRP_MJ_SET_INFORMATION
Definition: rdpdr.c:49
#define IRP_MJ_CREATE
Definition: rdpdr.c:44
#define IRP_MJ_QUERY_INFORMATION
Definition: rdpdr.c:48
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:550
_In_ WDFDPC _In_ BOOLEAN Wait
Definition: wdfdpc.h:170
#define IRP_MN_COMPLETE
Definition: iotypes.h:4420
#define IRP_MJ_FILE_SYSTEM_CONTROL
#define IRP_MJ_SHUTDOWN
#define IRP_MJ_CLEANUP
#define NT_ASSERT
Definition: rtlfuncs.h:3310

◆ _IRQL_requires_max_() [2/2]

_IRQL_requires_max_ ( DISPATCH_LEVEL  )

Definition at line 1568 of file mm.h.

1573{
1574 MmDereferenceSegmentWithLock(Segment, MM_NOIRQL);
1575}
#define MM_NOIRQL
Definition: mm.h:70
_Inout_ PVOID Segment
Definition: exfuncs.h:1101

◆ _IRQL_requires_min_()

_IRQL_requires_min_ ( DISPATCH_LEVEL  )

Definition at line 1015 of file mm.h.

1021{
1022 PKSPIN_LOCK_QUEUE LockQueue;
1023
1025 LockQueue = &KeGetCurrentPrcb()->LockQueue[LockQueuePfnLock];
1026 KeAcquireQueuedSpinLockAtDpcLevel(LockQueue);
1027}
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696
#define ASSERT(a)
Definition: mode.c:44
FORCEINLINE struct _KPRCB * KeGetCurrentPrcb(VOID)
Definition: ketypes.h:1161

◆ _MmGetPageEntrySectionSegment()

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

Definition at line 280 of file sptab.c.

284{
286 ULONG_PTR PageIndex, Result;
288
289 ASSERT(Segment->Locked);
290 FileOffset.QuadPart = ROUND_DOWN(Offset->QuadPart,
293 if (!PageTable) return 0;
294 PageIndex = (ULONG_PTR)((Offset->QuadPart - PageTable->FileOffset.QuadPart) / PAGE_SIZE);
295 Result = PageTable->PageEntries[PageIndex];
296#if 0
297 DPRINTC
298 ("MiGetPageEntrySectionSegment(%p,%08x%08x) => %x %s:%d\n",
299 Segment,
300 FileOffset.u.HighPart,
301 FileOffset.u.LowPart + PageIndex * PAGE_SIZE,
302 Result,
303 file, line);
304#endif
305 return Result;
306}
_In_ PFCB _In_ LONGLONG FileOffset
Definition: cdprocs.h:160
#define ULONG_PTR
Definition: config.h:101
#define PAGE_SIZE
Definition: env_spec_w32.h:49
#define ROUND_DOWN(n, align)
Definition: eventvwr.h:33
#define ENTRIES_PER_ELEMENT
Definition: newmm.h:21
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
#define DPRINTC
Definition: sptab.c:61
static PCACHE_SECTION_PAGE_TABLE NTAPI MiSectionPageTableGet(PRTL_GENERIC_TABLE Table, PLARGE_INTEGER FileOffset)
Definition: sptab.c:117
Definition: fci.c:127
Definition: parser.c:49
static PMEM_HOOK PageTable[TOTAL_PAGES]
Definition: memory.c:43
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:409

◆ _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);
102 Segment->Locked = TRUE;
103}
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
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 {
226
227 /* This has to be done before setting the new section association
228 to prevent a race condition with the paging out path */
229 PageTable->PageEntries[PageIndex] = Entry;
230
232 }
233 else
234 {
235 PageTable->PageEntries[PageIndex] = Entry;
236 }
237 }
238 else
239 {
240 /*
241 * We're switching to a valid entry from an invalid one.
242 * Add the Rmap and take a ref on the segment.
243 */
244 PageTable->PageEntries[PageIndex] = Entry;
246
247 if (Offset->QuadPart >= (Segment->LastPage << PAGE_SHIFT))
248 Segment->LastPage = (Offset->QuadPart >> PAGE_SHIFT) + 1;
249 }
250 }
251 else if (OldEntry && !IS_SWAP_FROM_SSE(OldEntry))
252 {
253 /* We're switching to an invalid entry from a valid one */
255 PageTable->PageEntries[PageIndex] = Entry;
256
257 if (Offset->QuadPart == ((Segment->LastPage - 1ULL) << PAGE_SHIFT))
258 {
259 /* We are unsetting the last page */
260 while (--Segment->LastPage)
261 {
262 LARGE_INTEGER CheckOffset;
263 CheckOffset.QuadPart = (Segment->LastPage - 1) << PAGE_SHIFT;
265 if ((Entry != 0) && !IS_SWAP_FROM_SSE(Entry))
266 break;
267 }
268 }
269 }
270 else
271 {
272 PageTable->PageEntries[PageIndex] = Entry;
273 }
274
275 return STATUS_SUCCESS;
276}
#define InterlockedIncrement64(a)
Definition: btrfs_drv.h:143
#define PAGE_SHIFT
Definition: env_spec_w32.h:45
VOID NTAPI MmDeleteSectionAssociation(PFN_NUMBER Page)
Definition: rmap.c:506
#define MmGetPageEntrySectionSegment(S, O)
Definition: mm.h:1602
#define IS_DIRTY_SSE(E)
Definition: mm.h:1377
#define PFN_FROM_SSE(E)
Definition: mm.h:1368
#define IS_SWAP_FROM_SSE(E)
Definition: mm.h:1369
#define STATUS_NO_MEMORY
Definition: ntstatus.h:260
#define STATUS_SUCCESS
Definition: shellext.h:65
#define DPRINT
Definition: sndvol32.h:73
static PCACHE_SECTION_PAGE_TABLE NTAPI MiSectionPageTableGetOrAllocate(PRTL_GENERIC_TABLE Table, PLARGE_INTEGER FileOffset)
Definition: sptab.c:136
NTSTATUS NTAPI MmSetSectionAssociation(PFN_NUMBER Page, PMM_SECTION_SEGMENT Segment, PLARGE_INTEGER Offset)
Definition: sptab.c:400
base of all file and directory entries
Definition: entries.h:83
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;
112 //DPRINT("MmUnlockSectionSegment(%p,%s:%d)\n", Segment, file, line);
113}
VOID FASTCALL ExReleaseFastMutex(IN PFAST_MUTEX FastMutex)
Definition: fmutex.c:31

◆ _Releases_lock_()

_Releases_lock_ ( MmPfnLock  )

◆ _Requires_exclusive_lock_held_()

_Requires_exclusive_lock_held_ ( WorkingSet->  WorkingSetMutex)

◆ _Requires_lock_held_() [1/2]

_Requires_lock_held_ ( MmPfnLock  )

Definition at line 1004 of file mm.h.

1011{
1013}
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:778

◆ _Requires_lock_held_() [2/2]

_Requires_lock_held_ ( PspQuotaLock  )

◆ _Requires_lock_not_held_()

_Requires_lock_not_held_ ( MmPfnLock  )

◆ _Success_()

_Success_ ( return  )

◆ _When_() [1/2]

_In_ _When_ ( OldIrql = MM_NOIRQL,
_IRQL_restores_   
)

◆ _When_() [2/2]

◆ ExpCheckPoolAllocation()

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

Definition at line 296 of file expool.c.

300{
302 ULONG i;
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}
#define BASE_POOL_TYPE_MASK
Definition: ExPools.c:15
#define DPRINT1
Definition: precomp.h:8
#define P(row, col)
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
#define KeAcquireSpinLock(sl, irql)
Definition: env_spec_w32.h:609
VOID NTAPI ExpCheckPoolHeader(IN PPOOL_HEADER Entry)
Definition: expool.c:193
SIZE_T PoolBigPageTableSize
Definition: expool.c:47
PPOOL_TRACKER_BIG_PAGES PoolBigPageTable
Definition: expool.c:50
KSPIN_LOCK ExpLargePoolTableLock
Definition: expool.c:54
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 _POOL_HEADER * PPOOL_HEADER
POOL_TYPE NTAPI MmDeterminePoolType(IN PVOID VirtualAddress)
Definition: pool.c:408
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
INT POOL_TYPE
Definition: typedefs.h:78
uint32_t ULONG
Definition: typedefs.h:59
_Must_inspect_result_ _In_ WDFDEVICE _In_ BOOLEAN _In_opt_ PVOID Tag
Definition: wdfdevice.h:4065
_Must_inspect_result_ _In_ WDFDEVICE _In_ DEVICE_REGISTRY_PROPERTY _In_ _Strict_type_match_ POOL_TYPE PoolType
Definition: wdfdevice.h:3815
#define PAGE_ALIGN(Va)

◆ ExReturnPoolQuota()

VOID NTAPI ExReturnPoolQuota ( IN PVOID  P)

Definition at line 1852 of file expool.c.

1853{
1856 USHORT BlockSize;
1858
1861 {
1862 return;
1863 }
1864
1865 Entry = P;
1866 Entry--;
1868
1869 PoolType = Entry->PoolType - 1;
1870 BlockSize = Entry->BlockSize;
1871
1873 {
1874 Process = ((PVOID *)POOL_NEXT_BLOCK(Entry))[-1];
1875 ASSERT(Process != NULL);
1876 if (Process)
1877 {
1878 if (Process->Pcb.Header.Type != ProcessObject)
1879 {
1880 DPRINT1("Object %p is not a process. Type %u, pool type 0x%x, block size %u\n",
1881 Process, Process->Pcb.Header.Type, Entry->PoolType, BlockSize);
1882 KeBugCheckEx(BAD_POOL_CALLER,
1884 (ULONG_PTR)P,
1885 Entry->PoolTag,
1887 }
1888 ((PVOID *)POOL_NEXT_BLOCK(Entry))[-1] = NULL;
1891 BlockSize * POOL_BLOCK_SIZE);
1893 }
1894 }
1895}
#define QUOTA_POOL_MASK
Definition: ExPools.c:16
#define POOL_NEXT_BLOCK(x)
Definition: expool.c:64
ULONG ExpPoolFlags
Definition: expool.c:56
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:223
#define POOL_BILLED_PROCESS_INVALID
Definition: miarm.h:306
#define POOL_BLOCK_SIZE
Definition: miarm.h:269
#define POOL_FLAG_SPECIAL_POOL
Definition: miarm.h:283
@ ProcessObject
Definition: ketypes.h:409
BOOLEAN NTAPI MmIsSpecialPoolAddress(IN PVOID P)
unsigned short USHORT
Definition: pedump.c:61
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
#define ObDereferenceObject
Definition: obfuncs.h:203

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;
429 PLIST_ENTRY NextEntry, NextHead, LastHead;
430 PMMPTE PointerPte, StartPte;
431 PMMPDE PointerPde;
432 ULONG EndAllocation;
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 //
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);
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}
HARDWARE_PTE_ARMV6 TempPte
Definition: winldr.c:76
HARDWARE_PDE_ARMV6 TempPde
Definition: winldr.c:78
#define MM_READWRITE
Definition: bootanim.c:19
#define RemoveEntryList(Entry)
Definition: env_spec_w32.h:986
#define InsertTailList(ListHead, Entry)
#define PagedPool
Definition: env_spec_w32.h:308
VOID FASTCALL KeReleaseGuardedMutex(IN OUT PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:53
VOID FASTCALL KeAcquireGuardedMutex(IN PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:42
NTSYSAPI ULONG WINAPI RtlFindClearBitsAndSet(PRTL_BITMAP, ULONG, ULONG)
NTSYSAPI void WINAPI RtlClearBits(PRTL_BITMAP, ULONG, ULONG)
@ NonPagedPoolExpansion
Definition: miarm.h:404
PVOID MmPagedPoolStart
Definition: miarm.h:574
#define MI_GET_NEXT_COLOR()
Definition: miarm.h:232
PFN_NUMBER NTAPI MiRemoveAnyPage(IN ULONG Color)
Definition: pfnlist.c:477
VOID NTAPI MiReleaseSystemPtes(IN PMMPTE StartingPte, IN ULONG NumberOfPtes, IN MMSYSTEM_PTE_POOL_TYPE SystemPtePoolType)
Definition: syspte.c:264
#define MI_MAKE_SOFTWARE_PTE(p, x)
Definition: miarm.h:189
VOID NTAPI MiInitializePfnForOtherProcess(IN PFN_NUMBER PageFrameIndex, IN PVOID PteAddress, IN PFN_NUMBER PteFrame)
Definition: pfnlist.c:1301
FORCEINLINE VOID MI_WRITE_VALID_PDE(IN PMMPDE PointerPde, IN MMPDE TempPde)
Definition: miarm.h:1018
FORCEINLINE VOID MI_WRITE_INVALID_PTE(IN PMMPTE PointerPte, IN MMPTE InvalidPte)
Definition: miarm.h:992
PMMPTE NTAPI MiReserveSystemPtes(IN ULONG NumberOfPtes, IN MMSYSTEM_PTE_POOL_TYPE SystemPtePoolType)
Definition: syspte.c:246
#define SYSTEM_PD_SIZE
Definition: miarm.h:32
FORCEINLINE VOID MI_WRITE_VALID_PTE(IN PMMPTE PointerPte, IN MMPTE TempPte)
Definition: miarm.h:959
#define MiAddressToPte(x)
Definition: mmx86.c:19
#define MiAddressToPde(x)
Definition: mmx86.c:20
#define min(a, b)
Definition: monoChain.cc:55
@ ActiveAndValid
Definition: mmtypes.h:159
#define MI_MAX_FREE_PAGE_LISTS
Definition: mm.h:80
#define PFN_FROM_PTE(v)
Definition: mm.h:92
#define MiPteToPde(_Pte)
Definition: mm.h:121
#define PTE_PER_PAGE
Definition: mm.h:20
#define MiPteToAddress(_Pte)
Definition: mm.h:116
#define PDE_PER_PAGE
Definition: mm.h:21
#define MiPdeToPte(_Pde)
Definition: mm.h:120
#define VERIFIER_POOL_MASK
Definition: mm.h:123
FORCEINLINE PMMPFN MiGetPfnEntry(IN PFN_NUMBER Pfn)
Definition: mm.h:1047
#define MI_SET_PROCESS2(x)
Definition: mm.h:319
#define MI_SET_USAGE(x)
Definition: mm.h:317
PFN_NUMBER MmAvailablePages
Definition: freelist.c:26
#define MM_FREE_POOL_SIGNATURE
Definition: mm.h:481
VOID NTAPI KeFlushEntireTb(IN BOOLEAN Invalid, IN BOOLEAN AllProcessors)
Definition: cpu.c:652
PMMPDE MmSystemPagePtes
Definition: init.c:41
PFN_NUMBER MmSystemPageDirectory[PPE_PER_PAGE]
Definition: init.c:40
VOID NTAPI MiProtectedPoolRemoveEntryList(IN PLIST_ENTRY Entry)
Definition: pool.c:168
BOOLEAN MmProtectFreedNonPagedPool
Definition: pool.c:31
KGUARDED_MUTEX MmPagedPoolMutex
Definition: pool.c:24
MM_PAGED_POOL_INFO MmPagedPoolInfo
Definition: pool.c:25
SLIST_HEADER MiNonPagedPoolSListHead
Definition: pool.c:32
VOID NTAPI MiProtectFreeNonPagedPool(IN PVOID VirtualAddress, IN ULONG PageCount)
Definition: pool.c:41
LIST_ENTRY MmNonPagedPoolFreeListHead[MI_MAX_FREE_PAGE_LISTS]
Definition: pool.c:20
SLIST_HEADER MiPagedPoolSListHead
Definition: pool.c:34
BOOLEAN NTAPI MiUnProtectFreeNonPagedPool(IN PVOID VirtualAddress, IN ULONG PageCount)
Definition: pool.c:70
VOID NTAPI MiProtectedPoolInsertList(IN PLIST_ENTRY ListHead, IN PLIST_ENTRY Entry, IN BOOLEAN Critical)
Definition: pool.c:150
MMPTE ValidKernelPte
Definition: init.c:29
MMPTE ValidKernelPde
Definition: init.c:28
ULONG PFN_NUMBER
Definition: ke.h:9
ULONG PageFrameNumber
Definition: mmtypes.h:74
ULONG PageFrameNumber
Definition: mmtypes.h:109
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
Definition: mm.h:473
ULONG Signature
Definition: mm.h:476
PFN_COUNT Size
Definition: mm.h:475
LIST_ENTRY List
Definition: mm.h:474
USHORT PageLocation
Definition: mm.h:365
Definition: mm.h:374
PMMPTE PteAddress
Definition: mm.h:386
MMPFNENTRY e1
Definition: mm.h:397
union _MMPFN::@1799 u2
ULONG_PTR VerifierAllocation
Definition: mm.h:420
ULONG_PTR ShareCount
Definition: mm.h:390
union _MMPFN::@1800 u3
struct _MMPFN::@1800::@1806 e2
union _MMPFN::@1803 u4
ULONG64 Valid
Definition: mmtypes.h:150
ULONG64 PageFrameNumber
Definition: mmtypes.h:171
union _MMPTE::@2335 u
MMPTE_HARDWARE Hard
Definition: mmtypes.h:217
PMMPTE LastPteForPagedPool
Definition: mm.h:489
PRTL_BITMAP EndOfPagedPoolBitmap
Definition: mm.h:487
PRTL_BITMAP PagedPoolAllocationMap
Definition: mm.h:486
PMMPDE NextPdeForPagedPoolExpansion
Definition: mm.h:490
PMMPTE FirstPteForPagedPool
Definition: mm.h:488
ULONG PagedPoolHint
Definition: mm.h:491
void * PVOID
Definition: typedefs.h:50
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
_Must_inspect_result_ _In_ WDFCMRESLIST List
Definition: wdfresource.h:550
FORCEINLINE USHORT ExQueryDepthSList(_In_ PSLIST_HEADER SListHead)
Definition: exfuncs.h:153
@ LockQueueMmNonPagedPoolLock
Definition: ketypes.h:673
#define BYTES_TO_PAGES(Size)
ULONG PFN_COUNT
Definition: mmtypes.h:102
NTSYSAPI VOID NTAPI RtlSetBit(_In_ PRTL_BITMAP BitMapHeader, _In_range_(<, BitMapHeader->SizeOfBitMap) ULONG BitNumber)
Definition: bitmap.c:304
#define InterlockedPopEntrySList(SListHead)
Definition: rtlfuncs.h:3392

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{
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 */
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}
__INTRIN_INLINE void __invlpg(void *Address)
Definition: intrin_x86.h:1968
@ SystemPteSpace
Definition: miarm.h:403
FORCEINLINE VOID MI_MAKE_HARDWARE_PTE_KERNEL(IN PMMPTE NewPte, IN PMMPTE MappingPte, IN ULONG_PTR ProtectionMask, IN PFN_NUMBER PageFrameNumber)
Definition: miarm.h:773
#define MI_GET_NEXT_PROCESS_COLOR(x)
Definition: miarm.h:233
FORCEINLINE PFN_NUMBER MiRemoveZeroPageSafe(IN ULONG Color)
Definition: miarm.h:2400
PMMWSL MmWorkingSetList
Definition: wslist.cpp:19
VOID NTAPI MiZeroPhysicalPage(IN PFN_NUMBER PageFrameIndex)
Definition: pfnlist.c:122
FORCEINLINE ULONG MiAddressToPxi(PVOID Address)
Definition: mm.h:200
#define HYPER_SPACE
Definition: mm.h:14
FORCEINLINE PMMPTE MiAddressToPxe(PVOID Address)
Definition: mm.h:171
FORCEINLINE ULONG MiAddressToPti(PVOID Address)
Definition: mm.h:181
PVOID MmHyperSpaceEnd
Definition: init.c:56
#define PXE_PER_PAGE
#define PXE_SELFMAP
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263

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;
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 //
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 //
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 */
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));
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 */
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);
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 */
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}
PVOID MmNonPagedPoolEnd
Definition: mminit.c:99
PFN_COUNT NTAPI MiDeleteSystemPageableVm(IN PMMPTE PointerPte, IN PFN_NUMBER PageCount, IN ULONG Flags, OUT PPFN_NUMBER ValidPages)
Definition: virtual.c:275
struct _MMFREE_POOL_ENTRY * PMMFREE_POOL_ENTRY
FORCEINLINE PFN_NUMBER MiGetPfnEntryIndex(IN PMMPFN Pfn1)
Definition: mm.h:1067
PVOID MmPagedPoolEnd
Definition: init.c:26
ULONG MiNonPagedPoolSListMaximum
Definition: pool.c:33
PFN_NUMBER MiStartOfInitialPoolFrame
Definition: pool.c:23
ULONG MiPagedPoolSListMaximum
Definition: pool.c:35
PFN_NUMBER MiEndOfInitialPoolFrame
Definition: pool.c:23
VOID NTAPI RtlClearBit(_In_ PRTL_BITMAP BitMapHeader, _In_ BITMAP_INDEX BitNumber)
Definition: bitmap.c:294
struct _MMFREE_POOL_ENTRY * Owner
Definition: mm.h:477
#define InterlockedPushEntrySList(SListHead, SListEntry)
Definition: rtlfuncs.h:3389
_Must_inspect_result_ NTSYSAPI BOOLEAN NTAPI RtlTestBit(_In_ PRTL_BITMAP BitMapHeader, _In_range_(<, BitMapHeader->SizeOfBitMap) ULONG BitNumber)
Definition: bitmap.c:434

Referenced by _IRQL_requires_(), and ExFreePoolWithTag().

◆ MiGetPfnEntry()

FORCEINLINE PMMPFN MiGetPfnEntry ( IN PFN_NUMBER  Pfn)

Definition at line 1047 of file mm.h.

1048{
1049 PMMPFN Page;
1050 extern RTL_BITMAP MiPfnBitMap;
1051
1052 /* Make sure the PFN number is valid */
1053 if (Pfn > MmHighestPhysicalPage) return NULL;
1054
1055 /* Make sure this page actually has a PFN entry */
1056 if ((MiPfnBitMap.Buffer) && !(RtlTestBit(&MiPfnBitMap, (ULONG)Pfn))) return NULL;
1057
1058 /* Get the entry */
1059 Page = &MmPfnDatabase[Pfn];
1060
1061 /* Return it */
1062 return Page;
1063};
PMMPFN MmPfnDatabase
Definition: freelist.c:24
_In_ PVOID _Out_opt_ BOOLEAN _Out_opt_ PPFN_NUMBER Page
Definition: mm.h:1306
PFN_NUMBER MmHighestPhysicalPage
Definition: meminit.c:31
RTL_BITMAP MiPfnBitMap
Definition: init.c:44
PULONG Buffer
Definition: typedefs.h:91

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(), 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)

◆ MiInitBalancerThread()

VOID NTAPI MiInitBalancerThread ( VOID  )

Definition at line 420 of file balance.c.

421{
425
429
430 Timeout.QuadPart = -20000000; /* 2 sec */
432 Timeout,
433 2000, /* 2 sec */
434 NULL);
435
438 NULL,
439 NULL,
442 NULL);
443 if (!NT_SUCCESS(Status))
444 {
445 KeBugCheck(MEMORY_MANAGEMENT);
446 }
447
451 &Priority,
452 sizeof(Priority));
453
454}
DECLSPEC_NORETURN VOID NTAPI KeBugCheck(ULONG BugCheckCode)
Definition: bug.c:1430
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
@ ThreadPriority
Definition: compat.h:937
LONG KPRIORITY
Definition: compat.h:803
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
#define LOW_REALTIME_PRIORITY
#define THREAD_ALL_ACCESS
Definition: nt_native.h:1339
@ SynchronizationEvent
@ SynchronizationTimer
static HANDLE MiBalancerThreadHandle
Definition: balance.c:32
static KTIMER MiBalancerTimer
Definition: balance.c:35
static KEVENT MiBalancerDoneEvent
Definition: balance.c:34
static CLIENT_ID MiBalancerThreadId
Definition: balance.c:31
VOID NTAPI MiBalancerThread(PVOID Unused)
Definition: balance.c:351
static KEVENT MiBalancerEvent
Definition: balance.c:33
NTSTATUS NTAPI NtSetInformationThread(IN HANDLE ThreadHandle, IN THREADINFOCLASS ThreadInformationClass, IN PVOID ThreadInformation, IN ULONG ThreadInformationLength)
Definition: query.c:2018
NTSTATUS NTAPI PsCreateSystemThread(OUT PHANDLE ThreadHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, IN HANDLE ProcessHandle, IN PCLIENT_ID ClientId, IN PKSTART_ROUTINE StartRoutine, IN PVOID StartContext)
Definition: thread.c:602
static ULONG Timeout
Definition: ping.c:61
BOOLEAN NTAPI KeSetTimerEx(IN OUT PKTIMER Timer, IN LARGE_INTEGER DueTime, IN LONG Period, IN PKDPC Dpc OPTIONAL)
Definition: timerobj.c:294
VOID NTAPI KeInitializeTimerEx(OUT PKTIMER Timer, IN TIMER_TYPE Type)
Definition: timerobj.c:244
_In_ WDFINTERRUPT _In_ WDF_INTERRUPT_POLICY _In_ WDF_INTERRUPT_PRIORITY Priority
Definition: wdfinterrupt.h:655

Referenced by MmInitSystem().

◆ MiInitializeLoadedModuleList()

BOOLEAN NTAPI MiInitializeLoadedModuleList ( IN PLOADER_PARAMETER_BLOCK  LoaderBlock)

Definition at line 2242 of file sysldr.c.

2243{
2244 PLDR_DATA_TABLE_ENTRY LdrEntry, NewEntry;
2245 PLIST_ENTRY ListHead, NextEntry;
2247
2248 /* Setup the loaded module list and locks */
2252
2253 /* Get loop variables and the kernel entry */
2254 ListHead = &LoaderBlock->LoadOrderListHead;
2255 NextEntry = ListHead->Flink;
2256 LdrEntry = CONTAINING_RECORD(NextEntry,
2258 InLoadOrderLinks);
2259 PsNtosImageBase = (ULONG_PTR)LdrEntry->DllBase;
2260
2261 /* Locate resource section, pool code, and system pte code */
2262 MiLocateKernelSections(LdrEntry);
2263
2264 /* Loop the loader block */
2265 while (NextEntry != ListHead)
2266 {
2267 /* Get the loader entry */
2268 LdrEntry = CONTAINING_RECORD(NextEntry,
2270 InLoadOrderLinks);
2271
2272 /* FIXME: ROS HACK. Make sure this is a driver */
2273 if (!RtlImageNtHeader(LdrEntry->DllBase))
2274 {
2275 /* Skip this entry */
2276 NextEntry = NextEntry->Flink;
2277 continue;
2278 }
2279
2280 /* Calculate the size we'll need and allocate a copy */
2282 LdrEntry->BaseDllName.MaximumLength +
2283 sizeof(UNICODE_NULL);
2285 if (!NewEntry) return FALSE;
2286
2287 /* Copy the entry over */
2288 *NewEntry = *LdrEntry;
2289
2290 /* Allocate the name */
2291 NewEntry->FullDllName.Buffer =
2293 LdrEntry->FullDllName.MaximumLength +
2294 sizeof(UNICODE_NULL),
2295 TAG_LDR_WSTR);
2296 if (!NewEntry->FullDllName.Buffer)
2297 {
2299 return FALSE;
2300 }
2301
2302 /* Set the base name */
2303 NewEntry->BaseDllName.Buffer = (PVOID)(NewEntry + 1);
2304
2305 /* Copy the full and base name */
2307 LdrEntry->FullDllName.Buffer,
2308 LdrEntry->FullDllName.MaximumLength);
2310 LdrEntry->BaseDllName.Buffer,
2311 LdrEntry->BaseDllName.MaximumLength);
2312
2313 /* Null-terminate the base name */
2314 NewEntry->BaseDllName.Buffer[NewEntry->BaseDllName.Length /
2315 sizeof(WCHAR)] = UNICODE_NULL;
2316
2317 /* Insert the entry into the list */
2319 NextEntry = NextEntry->Flink;
2320 }
2321
2322 /* Build the import lists for the boot drivers */
2324
2325 /* We're done */
2326 return TRUE;
2327}
struct _LDR_DATA_TABLE_ENTRY LDR_DATA_TABLE_ENTRY
#define RtlImageNtHeader
Definition: compat.h:806
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
NTSTATUS ExInitializeResourceLite(PULONG res)
Definition: env_spec_w32.h:641
#define NonPagedPool
Definition: env_spec_w32.h:307
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define KeInitializeSpinLock(sl)
Definition: env_spec_w32.h:604
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
#define UNICODE_NULL
Definition: btrfs_drv.h:1876
UNICODE_STRING FullDllName
Definition: btrfs_drv.h:1882
LIST_ENTRY InLoadOrderLinks
Definition: ldrtypes.h:138
PVOID DllBase
Definition: btrfs_drv.h:1880
UNICODE_STRING BaseDllName
Definition: ldrtypes.h:145
USHORT MaximumLength
Definition: env_spec_w32.h:370
NTSTATUS NTAPI MiBuildImportsForBootDrivers(VOID)
Definition: sysldr.c:1920
VOID NTAPI MiLocateKernelSections(IN PLDR_DATA_TABLE_ENTRY LdrEntry)
Definition: sysldr.c:2185
KSPIN_LOCK PsLoadedModuleSpinLock
Definition: sysldr.c:23
LIST_ENTRY PsLoadedModuleList
Definition: sysldr.c:21
ERESOURCE PsLoadedModuleResource
Definition: sysldr.c:24
ULONG_PTR PsNtosImageBase
Definition: sysldr.c:25
#define TAG_MODULE_OBJECT
Definition: tag.h:101
#define TAG_LDR_WSTR
Definition: tag.h:102
_In_ UCHAR EntrySize
Definition: iofuncs.h:642
__wchar_t WCHAR
Definition: xmlstorage.h:180

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 }
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;
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;
357 }
358
359 //
360 // Validate and remember first allocated pool page
361 //
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}
#define PAGED_CODE()
#define InsertHeadList(ListHead, Entry)
VOID NTAPI MiInitializeSystemPtes(IN PMMPTE StartingPte, IN ULONG NumberOfPtes, IN MMSYSTEM_PTE_POOL_TYPE PoolType)
Definition: syspte.c:388
#define _1GB
Definition: miarm.h:20
PFN_COUNT MmNumberOfPhysicalPages
Definition: init.c:48
ULONG MmMaximumNonPagedPoolInBytes
Definition: init.c:22
ULONG MmSizeOfNonPagedPoolInBytes
Definition: init.c:21
PVOID MmNonPagedPoolExpansionStart
Definition: init.c:25
PVOID MmNonPagedPoolStart
Definition: init.c:24
PFN_COUNT MmNumberOfFreeNonPagedPool
Definition: pool.c:21
PFN_COUNT MiExpansionPoolPagesInitialCharge
Definition: pool.c:21
PVOID MmNonPagedPoolEnd0
Definition: pool.c:22
FORCEINLINE VOID InitializeSListHead(_Out_ PSLIST_HEADER SListHead)
Definition: rtlfuncs.h:3351

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;
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}
ULONG MmSpecialPoolTag
Definition: pool.c:29
#define PAGE_ROUND_UP(x)
Definition: mmtypes.h:38
#define MM_EMPTY_PTE_LIST
Definition: mm.h:87
PFN_NUMBER MmResidentAvailablePages
Definition: freelist.c:27
ULONG MmNumberOfSystemPtes
Definition: init.c:42
PVOID MmSpecialPoolEnd
Definition: special.c:39
ULONG MiSpecialPoolExtraCount
Definition: special.c:41
PMMPTE MmSystemPteBase
Definition: syspte.c:21
PVOID MmSpecialPoolStart
Definition: special.c:38
PMMPTE MiSpecialPoolLastPte
Definition: special.c:44
PFN_COUNT MiSpecialPagesNonPagedMaximum
Definition: special.c:52
PMMPTE NTAPI MiReserveAlignedSystemPtes(IN ULONG NumberOfPtes, IN MMSYSTEM_PTE_POOL_TYPE SystemPtePoolType, IN ULONG Alignment)
Definition: syspte.c:88
PVOID MiSpecialPoolExtra
Definition: special.c:40
ULONG ExpPoolFlags
Definition: expool.c:56
PMMPTE MiSpecialPoolFirstPte
Definition: special.c:43
ULONG64 NextEntry
Definition: mmtypes.h:145
MMPTE_LIST List
Definition: mmtypes.h:222

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{
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 //
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}
PMMPTE MmFirstReservedMappingPte
Definition: hypermap.c:20
FORCEINLINE VOID KeFlushProcessTb(VOID)
Definition: ke.h:272
#define MI_HYPERSPACE_PTES
Definition: mm.h:81
MMPTE ValidKernelPteLocal
Definition: init.c:33
#define PsGetCurrentProcess
Definition: psfuncs.h:17

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{
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 //
147 PointerPte->u.Hard.PageFrameNumber = Offset - NumberOfPages;
148
149 /* Choose the correct PTE to use, and which template */
150 PointerPte += (Offset + 1);
152
153 /* Disable cache. Write through */
156
157 /* Make sure the list isn't empty and loop it */
158 ASSERT(Pfn1 != (PVOID)LIST_HEAD);
159 while (Pfn1 != (PVOID)LIST_HEAD)
160 {
161 /* Get the page index for this PFN */
162 PageFrameIndex = MiGetPfnEntryIndex(Pfn1);
163
164 //
165 // Write the PFN
166 //
167 TempPte.u.Hard.PageFrameNumber = PageFrameIndex;
168
169 //
170 // Set the correct PTE to write to, and set its new value
171 //
172 PointerPte--;
173 MI_WRITE_VALID_PTE(PointerPte, TempPte);
174
175 /* Move to the next PFN */
176 Pfn1 = (PMMPFN)Pfn1->u1.Flink;
177 }
178
179 //
180 // Return the address
181 //
182 return MiPteToAddress(PointerPte);
183}
#define PASSIVE_LEVEL
Definition: env_spec_w32.h:693
PMMPTE MiFirstReservedZeroingPte
Definition: hypermap.c:21
#define MI_PAGE_DISABLE_CACHE(x)
Definition: mm.h:101
#define MI_ZERO_PTES
Definition: mm.h:82
#define MI_PAGE_WRITE_THROUGH(x)
Definition: mm.h:102
struct _MMPFN * PMMPFN
#define LIST_HEAD(name, type)
Definition: queue.h:167

Referenced by MmZeroPageThread().

◆ MiReadPageFile()

NTSTATUS NTAPI MiReadPageFile ( _In_ PFN_NUMBER  Page,
_In_ ULONG  PageFileIndex,
_In_ ULONG_PTR  PageFileOffset 
)

Definition at line 211 of file pagefile.c.

215{
216 LARGE_INTEGER file_offset;
220 UCHAR MdlBase[sizeof(MDL) + sizeof(PFN_NUMBER)];
221 PMDL Mdl = (PMDL)MdlBase;
222 PMMPAGING_FILE PagingFile;
223
224 DPRINT("MiReadSwapFile\n");
225
226 if (PageFileOffset == 0)
227 {
228 KeBugCheck(MEMORY_MANAGEMENT);
229 return(STATUS_UNSUCCESSFUL);
230 }
231
232 /* Normalize offset. */
233 PageFileOffset--;
234
235 ASSERT(PageFileIndex < MAX_PAGING_FILES);
236
237 PagingFile = MmPagingFile[PageFileIndex];
238
239 if (PagingFile->FileObject == NULL || PagingFile->FileObject->DeviceObject == NULL)
240 {
241 DPRINT1("Bad paging file %u\n", PageFileIndex);
242 KeBugCheck(MEMORY_MANAGEMENT);
243 }
244
248
249 file_offset.QuadPart = PageFileOffset * PAGE_SIZE;
250
252 Status = IoPageRead(PagingFile->FileObject,
253 Mdl,
254 &file_offset,
255 &Event,
256 &Iosb);
257 if (Status == STATUS_PENDING)
258 {
260 Status = Iosb.Status;
261 }
262 if (Mdl->MdlFlags & MDL_MAPPED_TO_SYSTEM_VA)
263 {
264 MmUnmapLockedPages (Mdl->MappedSystemVa, Mdl);
265 }
266 return(Status);
267}
#define MAX_PAGING_FILES
Definition: pagefile.c:23
return Iosb
Definition: create.c:4402
#define KeWaitForSingleObject(pEvt, foo, a, b, c)
Definition: env_spec_w32.h:478
NTSTATUS NTAPI IoPageRead(IN PFILE_OBJECT FileObject, IN PMDL Mdl, IN PLARGE_INTEGER Offset, IN PKEVENT Event, IN PIO_STATUS_BLOCK StatusBlock)
Definition: iofunc.c:1201
VOID NTAPI MmUnmapLockedPages(IN PVOID BaseAddress, IN PMDL Mdl)
Definition: mdlsup.c:837
#define KernelMode
Definition: asm.h:34
@ NotificationEvent
PMMPAGING_FILE MmPagingFile[MAX_PAGING_FILES]
Definition: pagefile.c:57
VOID NTAPI MmBuildMdlFromPages(PMDL Mdl, PPFN_NUMBER Pages)
Definition: pagefile.c:111
#define STATUS_PENDING
Definition: ntstatus.h:82
PFILE_OBJECT FileObject
Definition: mm.h:506
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
PVOID PMDL
Definition: usb.h:39
_In_ WDFDEVICE _In_ PVOID _In_opt_ PMDL Mdl
@ Executive
Definition: ketypes.h:415
#define MmInitializeMdl(_MemoryDescriptorList, _BaseVa, _Length)
MDL
Definition: mmtypes.h:117
#define MDL_PAGES_LOCKED
Definition: mmtypes.h:19
#define MDL_IO_PAGE_READ
Definition: mmtypes.h:24
#define MDL_MAPPED_TO_SYSTEM_VA
Definition: mmtypes.h:18
unsigned char UCHAR
Definition: xmlstorage.h:181

Referenced by MiResolvePageFileFault(), and MmReadFromSwapPage().

◆ MiReloadBootLoadedDrivers()

VOID NTAPI MiReloadBootLoadedDrivers ( IN PLOADER_PARAMETER_BLOCK  LoaderBlock)

Definition at line 1731 of file sysldr.c.

1732{
1733 PLIST_ENTRY NextEntry;
1734 ULONG i = 0;
1735 PIMAGE_NT_HEADERS NtHeader;
1736 PLDR_DATA_TABLE_ENTRY LdrEntry;
1737 PIMAGE_FILE_HEADER FileHeader;
1738 BOOLEAN ValidRelocs;
1739 PIMAGE_DATA_DIRECTORY DataDirectory;
1740 PVOID DllBase, NewImageAddress;
1742 PMMPTE PointerPte, StartPte, LastPte;
1743 PFN_COUNT PteCount;
1744 PMMPFN Pfn1;
1745 MMPTE TempPte, OldPte;
1746
1747 /* Loop driver list */
1748 for (NextEntry = LoaderBlock->LoadOrderListHead.Flink;
1749 NextEntry != &LoaderBlock->LoadOrderListHead;
1750 NextEntry = NextEntry->Flink)
1751 {
1752 /* Get the loader entry and NT header */
1753 LdrEntry = CONTAINING_RECORD(NextEntry,
1755 InLoadOrderLinks);
1756 NtHeader = RtlImageNtHeader(LdrEntry->DllBase);
1757
1758 /* Debug info */
1759 DPRINT("[Mm0]: Driver at: %p ending at: %p for module: %wZ\n",
1760 LdrEntry->DllBase,
1761 (ULONG_PTR)LdrEntry->DllBase + LdrEntry->SizeOfImage,
1762 &LdrEntry->FullDllName);
1763
1764 /* Get the first PTE and the number of PTEs we'll need */
1765 PointerPte = StartPte = MiAddressToPte(LdrEntry->DllBase);
1766 PteCount = ROUND_TO_PAGES(LdrEntry->SizeOfImage) >> PAGE_SHIFT;
1767 LastPte = StartPte + PteCount;
1768
1769#if MI_TRACE_PFNS
1770 /* Loop the PTEs */
1771 while (PointerPte < LastPte)
1772 {
1773 ULONG len;
1774 ASSERT(PointerPte->u.Hard.Valid == 1);
1775 Pfn1 = MiGetPfnEntry(PFN_FROM_PTE(PointerPte));
1776 len = wcslen(LdrEntry->BaseDllName.Buffer) * sizeof(WCHAR);
1777 snprintf(Pfn1->ProcessName, min(16, len), "%S", LdrEntry->BaseDllName.Buffer);
1778 PointerPte++;
1779 }
1780#endif
1781 /* Skip kernel and HAL */
1782 /* ROS HACK: Skip BOOTVID/KDCOM too */
1783 i++;
1784 if (i <= 4) continue;
1785
1786 /* Skip non-drivers */
1787 if (!NtHeader) continue;
1788
1789 /* Get the file header and make sure we can relocate */
1790 FileHeader = &NtHeader->FileHeader;
1791 if (FileHeader->Characteristics & IMAGE_FILE_RELOCS_STRIPPED) continue;
1792 if (NtHeader->OptionalHeader.NumberOfRvaAndSizes <
1794
1795 /* Everything made sense until now, check the relocation section too */
1796 DataDirectory = &NtHeader->OptionalHeader.
1797 DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC];
1798 if (!DataDirectory->VirtualAddress)
1799 {
1800 /* We don't really have relocations */
1801 ValidRelocs = FALSE;
1802 }
1803 else
1804 {
1805 /* Make sure the size is valid */
1806 if ((DataDirectory->VirtualAddress + DataDirectory->Size) >
1807 LdrEntry->SizeOfImage)
1808 {
1809 /* They're not, skip */
1810 continue;
1811 }
1812
1813 /* We have relocations */
1814 ValidRelocs = TRUE;
1815 }
1816
1817 /* Remember the original address */
1818 DllBase = LdrEntry->DllBase;
1819
1820 /* Loop the PTEs */
1821 PointerPte = StartPte;
1822 while (PointerPte < LastPte)
1823 {
1824 /* Mark the page modified in the PFN database */
1825 ASSERT(PointerPte->u.Hard.Valid == 1);
1826 Pfn1 = MiGetPfnEntry(PFN_FROM_PTE(PointerPte));
1827 ASSERT(Pfn1->u3.e1.Rom == 0);
1828 Pfn1->u3.e1.Modified = TRUE;
1829
1830 /* Next */
1831 PointerPte++;
1832 }
1833
1834 /* Now reserve system PTEs for the image */
1835 PointerPte = MiReserveSystemPtes(PteCount, SystemPteSpace);
1836 if (!PointerPte)
1837 {
1838 /* Shouldn't happen */
1839 ERROR_FATAL("[Mm0]: Couldn't allocate driver section!\n");
1840 return;
1841 }
1842
1843 /* This is the new virtual address for the module */
1844 LastPte = PointerPte + PteCount;
1845 NewImageAddress = MiPteToAddress(PointerPte);
1846
1847 /* Sanity check */
1848 DPRINT("[Mm0]: Copying from: %p to: %p\n", DllBase, NewImageAddress);
1850
1851 /* Loop the new driver PTEs */
1853 while (PointerPte < LastPte)
1854 {
1855 /* Copy the old data */
1856 OldPte = *StartPte;
1857 ASSERT(OldPte.u.Hard.Valid == 1);
1858
1859 /* Set page number from the loader's memory */
1861
1862 /* Write it */
1863 MI_WRITE_VALID_PTE(PointerPte, TempPte);
1864
1865 /* Move on */
1866 PointerPte++;
1867 StartPte++;
1868 }
1869
1870 /* Update position */
1871 PointerPte -= PteCount;
1872
1873 /* Sanity check */
1874 ASSERT(*(PULONG)NewImageAddress == *(PULONG)DllBase);
1875
1876 /* Set the image base to the address where the loader put it */
1877 NtHeader->OptionalHeader.ImageBase = (ULONG_PTR)DllBase;
1878
1879 /* Check if we had relocations */
1880 if (ValidRelocs)
1881 {
1882 /* Relocate the image */
1883 Status = LdrRelocateImageWithBias(NewImageAddress,
1884 0,
1885 "SYSLDR",
1889 if (!NT_SUCCESS(Status))
1890 {
1891 /* This shouldn't happen */
1892 ERROR_FATAL("Relocations failed!\n");
1893 return;
1894 }
1895 }
1896
1897 /* Update the loader entry */
1898 LdrEntry->DllBase = NewImageAddress;
1899
1900 /* Update the thunks */
1901 DPRINT("[Mm0]: Updating thunks to: %wZ\n", &LdrEntry->BaseDllName);
1902 MiUpdateThunks(LoaderBlock,
1903 DllBase,
1904 NewImageAddress,
1905 LdrEntry->SizeOfImage);
1906
1907 /* Update the loader entry */
1908 LdrEntry->Flags |= LDRP_SYSTEM_MAPPED;
1909 LdrEntry->EntryPoint = (PVOID)((ULONG_PTR)NewImageAddress +
1911 LdrEntry->SizeOfImage = PteCount << PAGE_SHIFT;
1912
1913 /* FIXME: We'll need to fixup the PFN linkage when switching to ARM3 */
1914 }
1915}
GLenum GLsizei len
Definition: glext.h:6722
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
#define LDRP_SYSTEM_MAPPED
Definition: ldrtypes.h:54
ULONG NTAPI LdrRelocateImageWithBias(_In_ PVOID BaseAddress, _In_ LONGLONG AdditionalBias, _In_opt_ PCSTR LoaderName, _In_ ULONG Success, _In_ ULONG Conflict, _In_ ULONG Invalid)
Definition: image.c:474
ULONG ExpInitializationPhase
Definition: init.c:68
#define STATUS_INVALID_IMAGE_FORMAT
Definition: ntstatus.h:359
#define STATUS_CONFLICTING_ADDRESSES
Definition: ntstatus.h:261
#define IMAGE_DIRECTORY_ENTRY_BASERELOC
Definition: pedump.c:264
#define IMAGE_FILE_RELOCS_STRIPPED
Definition: pedump.c:159
#define ERROR_FATAL(...)
Definition: debug.h:238
IMAGE_OPTIONAL_HEADER32 OptionalHeader
Definition: ntddk_ex.h:184
IMAGE_FILE_HEADER FileHeader
Definition: ntddk_ex.h:183
PVOID EntryPoint
Definition: ntddk_ex.h:203
ULONG SizeOfImage
Definition: ldrtypes.h:143
ULONG Flags
Definition: ntddk_ex.h:207
USHORT Modified
Definition: mm.h:360
USHORT Rom
Definition: mm.h:368
VOID NTAPI MiUpdateThunks(IN PLOADER_PARAMETER_BLOCK LoaderBlock, IN PVOID OldBase, IN PVOID NewBase, IN ULONG Size)
Definition: sysldr.c:649
uint32_t * PULONG
Definition: typedefs.h:59
#define snprintf
Definition: wintirpc.h:48
#define ROUND_TO_PAGES(Size)

Referenced by MmArmInitSystem().

◆ MiRosCheckMemoryAreas()

VOID NTAPI MiRosCheckMemoryAreas ( PMMSUPPORT  AddressSpace)

◆ MiRosCleanupMemoryArea()

VOID NTAPI MiRosCleanupMemoryArea ( PEPROCESS  Process,
PMMVAD  Vad 
)

Definition at line 521 of file marea.c.

524{
528
529 /* We must be called from MmCleanupAddressSpace and nowhere else!
530 Make sure things are as expected... */
532 ASSERT(Process->VmDeleted == TRUE);
533 ASSERT(((PsGetCurrentThread()->ThreadsProcess == Process) &&
534 (Process->ActiveThreads == 1)) ||
535 (Process->ActiveThreads == 0));
536
539
541 {
543 }
544#ifdef NEWCC
545 else if (MemoryArea->Type == MEMORY_AREA_CACHE)
546 {
548 }
549#endif
550 else
551 {
552 /* There shouldn't be anything else! */
553 ASSERT(FALSE);
554 }
555
556 /* Make sure this worked! */
558}
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
NTSTATUS NTAPI MiRosUnmapViewOfSection(IN PEPROCESS Process, IN PVOID BaseAddress, IN BOOLEAN SkipDebuggerNotify)
Definition: section.c:3589
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID * BaseAddress
Definition: mmfuncs.h:404
_In_ PMEMORY_AREA MemoryArea
Definition: newmm.h:207
NTSTATUS NTAPI MmUnmapViewOfCacheSegment(PMMSUPPORT AddressSpace, PVOID BaseAddress)
struct _MEMORY_AREA * PMEMORY_AREA
#define MA_GetStartingAddress(_MemoryArea)
Definition: mm.h:244
#define MEMORY_AREA_SECTION_VIEW
Definition: mm.h:93
ULONG Type
Definition: mm.h:251

Referenced by MmCleanProcessAddressSpace().

◆ MiUnmapPageInHyperSpace()

VOID NTAPI MiUnmapPageInHyperSpace ( IN PEPROCESS  Process,
IN PVOID  Address,
IN KIRQL  OldIrql 
)

Definition at line 91 of file hypermap.c.

94{
96
97 //
98 // Blow away the mapping
99 //
100 MiAddressToPte(Address)->u.Long = 0;
101
102 //
103 // Release the hyperlock
104 //
106 KeReleaseSpinLock(&Process->HyperSpaceLock, OldIrql);
107}
static WCHAR Address[46]
Definition: ping.c:68

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

◆ MiUnmapPagesInZeroSpace()

VOID NTAPI MiUnmapPagesInZeroSpace ( IN PVOID  VirtualAddress,
IN PFN_NUMBER  NumberOfPages 
)

Definition at line 187 of file hypermap.c.

189{
190 PMMPTE PointerPte;
191
192 //
193 // Sanity checks
194 //
196 ASSERT (NumberOfPages != 0);
197 ASSERT(NumberOfPages <= MI_ZERO_PTES);
198
199 //
200 // Get the first PTE for the mapped zero VA
201 //
202 PointerPte = MiAddressToPte(VirtualAddress);
203
204 //
205 // Blow away the mapped zero PTEs
206 //
207 RtlZeroMemory(PointerPte, NumberOfPages * sizeof(MMPTE));
208}
_Must_inspect_result_ _In_ WDFDMATRANSACTION _In_ PFN_WDF_PROGRAM_DMA _In_ WDF_DMA_DIRECTION _In_ PMDL _In_ PVOID VirtualAddress

Referenced by MmZeroPageThread().

◆ MmAccessFault()

NTSTATUS NTAPI MmAccessFault ( IN ULONG  FaultCode,
IN PVOID  Address,
IN KPROCESSOR_MODE  Mode,
IN PVOID  TrapInformation 
)

Definition at line 209 of file mmfault.c.

213{
215