ReactOS 0.4.15-dev-7788-g1ad9096
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}
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:159
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:34
#define _SEH2_GetExceptionInformation()
Definition: pseh2_64.h:158
#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
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2793
#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:1148

◆ _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:71
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:617
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
union _MMPFN::@1790 u3
union _MMPFN::@1789 u2
PMMPTE PteAddress
Definition: mm.h:386
MMPFNENTRY e1
Definition: mm.h:397
union _MMPFN::@1793 u4
ULONG_PTR VerifierAllocation
Definition: mm.h:420
ULONG_PTR ShareCount
Definition: mm.h:390
struct _MMPFN::@1790::@1796 e2
ULONG64 Valid
Definition: mmtypes.h:150
ULONG64 PageFrameNumber
Definition: mmtypes.h:171
union _MMPTE::@2325 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:2415
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(), MiSetProtectionOnSection(), MiSetupPfnForPageTable(), MiUnlockVirtualMemory(), MiUnmapLockedPagesInUserSpace(), MiZeroPfn(), MmAllocPage(), MmArmAccessFault(), MmBuildMdlForNonPagedPool(), MmDeleteKernelStack(), MmDeleteProcessAddressSpace(), MmDereferencePage(), MmDumpArmPfnDatabase(), MmFreeLoaderBlock(), MmFreePagesFromMdl(), MmGetLRUNextUserPage(), MmGetReferenceCountPage(), MmGetRmapListHeadPage(), MmGetSavedSwapEntryPage(), MmInitializeProcessAddressSpace(), MmInsertLRULastUserPage(), MmIsPageInUse(), MmMapIoSpace(), MmProbeAndLockPages(), MmReferencePage(), MmRemoveLRUUserPage(), MmSetRmapListHeadPage(), MmSetSavedSwapEntryPage(), MmUnlockPages(), MmUnmapIoSpace(), MmZeroPageThread(), PspCreateProcess(), RemoveFromWsList(), and TrimWsList().

◆ MiGetPfnEntryIndex()

FORCEINLINE PFN_NUMBER MiGetPfnEntryIndex ( IN PMMPFN  Pfn1)

◆ 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:1431
#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 2241 of file sysldr.c.

2242{
2243 PLDR_DATA_TABLE_ENTRY LdrEntry, NewEntry;
2244 PLIST_ENTRY ListHead, NextEntry;
2246
2247 /* Setup the loaded module list and locks */
2251
2252 /* Get loop variables and the kernel entry */
2253 ListHead = &LoaderBlock->LoadOrderListHead;
2254 NextEntry = ListHead->Flink;
2255 LdrEntry = CONTAINING_RECORD(NextEntry,
2257 InLoadOrderLinks);
2258 PsNtosImageBase = (ULONG_PTR)LdrEntry->DllBase;
2259
2260 /* Locate resource section, pool code, and system pte code */
2261 MiLocateKernelSections(LdrEntry);
2262
2263 /* Loop the loader block */
2264 while (NextEntry != ListHead)
2265 {
2266 /* Get the loader entry */
2267 LdrEntry = CONTAINING_RECORD(NextEntry,
2269 InLoadOrderLinks);
2270
2271 /* FIXME: ROS HACK. Make sure this is a driver */
2272 if (!RtlImageNtHeader(LdrEntry->DllBase))
2273 {
2274 /* Skip this entry */
2275 NextEntry = NextEntry->Flink;
2276 continue;
2277 }
2278
2279 /* Calculate the size we'll need and allocate a copy */
2281 LdrEntry->BaseDllName.MaximumLength +
2282 sizeof(UNICODE_NULL);
2284 if (!NewEntry) return FALSE;
2285
2286 /* Copy the entry over */
2287 *NewEntry = *LdrEntry;
2288
2289 /* Allocate the name */
2290 NewEntry->FullDllName.Buffer =
2292 LdrEntry->FullDllName.MaximumLength +
2293 sizeof(UNICODE_NULL),
2294 TAG_LDR_WSTR);
2295 if (!NewEntry->FullDllName.Buffer)
2296 {
2298 return FALSE;
2299 }
2300
2301 /* Set the base name */
2302 NewEntry->BaseDllName.Buffer = (PVOID)(NewEntry + 1);
2303
2304 /* Copy the full and base name */
2306 LdrEntry->FullDllName.Buffer,
2307 LdrEntry->FullDllName.MaximumLength);
2309 LdrEntry->BaseDllName.Buffer,
2310 LdrEntry->BaseDllName.MaximumLength);
2311
2312 /* Null-terminate the base name */
2313 NewEntry->BaseDllName.Buffer[NewEntry->BaseDllName.Length /
2314 sizeof(WCHAR)] = UNICODE_NULL;
2315
2316 /* Insert the entry into the list */
2318 NextEntry = NextEntry->Flink;
2319 }
2320
2321 /* Build the import lists for the boot drivers */
2323
2324 /* We're done */
2325 return TRUE;
2326}
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:1919
VOID NTAPI MiLocateKernelSections(IN PLDR_DATA_TABLE_ENTRY LdrEntry)
Definition: sysldr.c:2184
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 1730 of file sysldr.c.

1731{
1732 PLIST_ENTRY NextEntry;
1733 ULONG i = 0;
1734 PIMAGE_NT_HEADERS NtHeader;
1735 PLDR_DATA_TABLE_ENTRY LdrEntry;
1736 PIMAGE_FILE_HEADER FileHeader;
1737 BOOLEAN ValidRelocs;
1738 PIMAGE_DATA_DIRECTORY DataDirectory;
1739 PVOID DllBase, NewImageAddress;
1741 PMMPTE PointerPte, StartPte, LastPte;
1742 PFN_COUNT PteCount;
1743 PMMPFN Pfn1;
1744 MMPTE TempPte, OldPte;
1745
1746 /* Loop driver list */
1747 for (NextEntry = LoaderBlock->LoadOrderListHead.Flink;
1748 NextEntry != &LoaderBlock->LoadOrderListHead;
1749 NextEntry = NextEntry->Flink)
1750 {
1751 /* Get the loader entry and NT header */
1752 LdrEntry = CONTAINING_RECORD(NextEntry,
1754 InLoadOrderLinks);
1755 NtHeader = RtlImageNtHeader(LdrEntry->DllBase);
1756
1757 /* Debug info */
1758 DPRINT("[Mm0]: Driver at: %p ending at: %p for module: %wZ\n",
1759 LdrEntry->DllBase,
1760 (ULONG_PTR)LdrEntry->DllBase + LdrEntry->SizeOfImage,
1761 &LdrEntry->FullDllName);
1762
1763 /* Get the first PTE and the number of PTEs we'll need */
1764 PointerPte = StartPte = MiAddressToPte(LdrEntry->DllBase);
1765 PteCount = ROUND_TO_PAGES(LdrEntry->SizeOfImage) >> PAGE_SHIFT;
1766 LastPte = StartPte + PteCount;
1767
1768#if MI_TRACE_PFNS
1769 /* Loop the PTEs */
1770 while (PointerPte < LastPte)
1771 {
1772 ULONG len;
1773 ASSERT(PointerPte->u.Hard.Valid == 1);
1774 Pfn1 = MiGetPfnEntry(PFN_FROM_PTE(PointerPte));
1775 len = wcslen(LdrEntry->BaseDllName.Buffer) * sizeof(WCHAR);
1776 snprintf(Pfn1->ProcessName, min(16, len), "%S", LdrEntry->BaseDllName.Buffer);
1777 PointerPte++;
1778 }
1779#endif
1780 /* Skip kernel and HAL */
1781 /* ROS HACK: Skip BOOTVID/KDCOM too */
1782 i++;
1783 if (i <= 4) continue;
1784
1785 /* Skip non-drivers */
1786 if (!NtHeader) continue;
1787
1788 /* Get the file header and make sure we can relocate */
1789 FileHeader = &NtHeader->FileHeader;
1790 if (FileHeader->Characteristics & IMAGE_FILE_RELOCS_STRIPPED) continue;
1791 if (NtHeader->OptionalHeader.NumberOfRvaAndSizes <
1793
1794 /* Everything made sense until now, check the relocation section too */
1795 DataDirectory = &NtHeader->OptionalHeader.
1796 DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC];
1797 if (!DataDirectory->VirtualAddress)
1798 {
1799 /* We don't really have relocations */
1800 ValidRelocs = FALSE;
1801 }
1802 else
1803 {
1804 /* Make sure the size is valid */
1805 if ((DataDirectory->VirtualAddress + DataDirectory->Size) >
1806 LdrEntry->SizeOfImage)
1807 {
1808 /* They're not, skip */
1809 continue;
1810 }
1811
1812 /* We have relocations */
1813 ValidRelocs = TRUE;
1814 }
1815
1816 /* Remember the original address */
1817 DllBase = LdrEntry->DllBase;
1818
1819 /* Loop the PTEs */
1820 PointerPte = StartPte;
1821 while (PointerPte < LastPte)
1822 {
1823 /* Mark the page modified in the PFN database */
1824 ASSERT(PointerPte->u.Hard.Valid == 1);
1825 Pfn1 = MiGetPfnEntry(PFN_FROM_PTE(PointerPte));
1826 ASSERT(Pfn1->u3.e1.Rom == 0);
1827 Pfn1->u3.e1.Modified = TRUE;
1828
1829 /* Next */
1830 PointerPte++;
1831 }
1832
1833 /* Now reserve system PTEs for the image */
1834 PointerPte = MiReserveSystemPtes(PteCount, SystemPteSpace);
1835 if (!PointerPte)
1836 {
1837 /* Shouldn't happen */
1838 ERROR_FATAL("[Mm0]: Couldn't allocate driver section!\n");
1839 return;
1840 }
1841
1842 /* This is the new virtual address for the module */
1843 LastPte = PointerPte + PteCount;
1844 NewImageAddress = MiPteToAddress(PointerPte);
1845
1846 /* Sanity check */
1847 DPRINT("[Mm0]: Copying from: %p to: %p\n", DllBase, NewImageAddress);
1849
1850 /* Loop the new driver PTEs */
1852 while (PointerPte < LastPte)
1853 {
1854 /* Copy the old data */
1855 OldPte = *StartPte;
1856 ASSERT(OldPte.u.Hard.Valid == 1);
1857
1858 /* Set page number from the loader's memory */
1860
1861 /* Write it */
1862 MI_WRITE_VALID_PTE(PointerPte, TempPte);
1863
1864 /* Move on */
1865 PointerPte++;
1866 StartPte++;
1867 }
1868
1869 /* Update position */
1870 PointerPte -= PteCount;
1871
1872 /* Sanity check */
1873 ASSERT(*(PULONG)NewImageAddress == *(PULONG)DllBase);
1874
1875 /* Set the image base to the address where the loader put it */
1876 NtHeader->OptionalHeader.ImageBase = (ULONG_PTR)DllBase;
1877
1878 /* Check if we had relocations */
1879 if (ValidRelocs)
1880 {
1881 /* Relocate the image */
1882 Status = LdrRelocateImageWithBias(NewImageAddress,
1883 0,
1884 "SYSLDR",
1888 if (!NT_SUCCESS(Status))
1889 {
1890 /* This shouldn't happen */
1891 ERROR_FATAL("Relocations failed!\n");
1892 return;
1893 }
1894 }
1895
1896 /* Update the loader entry */
1897 LdrEntry->DllBase = NewImageAddress;
1898
1899 /* Update the thunks */
1900 DPRINT("[Mm0]: Updating thunks to: %wZ\n", &LdrEntry->BaseDllName);
1901 MiUpdateThunks(LoaderBlock,
1902 DllBase,
1903 NewImageAddress,
1904 LdrEntry->SizeOfImage);
1905
1906 /* Update the loader entry */
1907 LdrEntry->Flags |= LDRP_SYSTEM_MAPPED;
1908 LdrEntry->EntryPoint = (PVOID)((ULONG_PTR)NewImageAddress +
1910 LdrEntry->SizeOfImage = PteCount << PAGE_SHIFT;
1911
1912 /* FIXME: We'll need to fixup the PFN linkage when switching to ARM3 */
1913 }
1914}
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:648
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{
216 BOOLEAN IsArm3Fault = FALSE;
217
218 /* Cute little hack for ROS */
220 {
221#ifdef _M_IX86
222 /* Check for an invalid page directory in kernel mode */
224 {
225 /* All is well with the world */
226 return STATUS_SUCCESS;
227 }
228#endif
229 }
230
231 /* Handle shared user page / page table, which don't have a VAD / MemoryArea */
234 {
235 /* This is an ARM3 fault */
236 DPRINT("ARM3 fault %p\n", Address);
237 return MmArmAccessFault(FaultCode, Address, Mode, TrapInformation);
238 }
239
240 /* Is there a ReactOS address space yet? */
242 {
244 {
245 /* Check if this is an ARM3 memory area */
248
250 {
251 IsArm3Fault = TRUE;
252 }
253
255 }
256 else
257 {
258 /* Could this be a VAD fault from user-mode? */
261
263 {
264 IsArm3Fault = TRUE;
265 }
266
268 }
269 }
270
271 /* Is this an ARM3 memory area, or is there no address space yet? */
272 if (IsArm3Fault ||
273 ((MemoryArea == NULL) &&
277 {
278 /* This is an ARM3 fault */
279 DPRINT("ARM3 fault %p\n", MemoryArea);
280 return MmArmAccessFault(FaultCode, Address, Mode, TrapInformation);
281 }
282
283Retry:
284 /* Keep same old ReactOS Behaviour */
285 if (!MI_IS_NOT_PRESENT_FAULT(FaultCode))
286 {
287 /* Call access fault */
288 Status = MmpAccessFault(Mode, (ULONG_PTR)Address, TrapInformation ? FALSE : TRUE);
289 }
290 else
291 {
292 /* Call not present */
293 Status = MmNotPresentFault(Mode, (ULONG_PTR)Address, TrapInformation ? FALSE : TRUE);
294 }
295
297 {
299 goto Retry;
300 }
301
302 return Status;
303}
#define MM_HIGHEST_USER_ADDRESS
Definition: armddk.h:17
_In_ PSCSI_REQUEST_BLOCK _Out_ NTSTATUS _Inout_ BOOLEAN * Retry
Definition: classpnp.h:312
_In_ ULONG Mode
Definition: hubbusif.h:303
FORCEINLINE VOID MiLockProcessWorkingSetShared(IN PEPROCESS Process, IN PETHREAD Thread)
Definition: miarm.h:1146
FORCEINLINE VOID MiUnlockProcessWorkingSetShared(IN PEPROCESS Process, IN PETHREAD Thread)
Definition: miarm.h:1215
#define MI_IS_PAGE_TABLE_ADDRESS(Address)
Definition: miarm.h:177
NTSTATUS NTAPI MmArmAccessFault(IN ULONG FaultCode, IN PVOID Address, IN KPROCESSOR_MODE Mode, IN PVOID TrapInformation)
Definition: pagfault.c:1698
FORCEINLINE VOID MiLockWorkingSetShared(_In_ PETHREAD Thread, _In_ PMMSUPPORT WorkingSet)
Definition: miarm.h:1306
FORCEINLINE VOID MiUnlockWorkingSetShared(_In_ PETHREAD Thread, _In_ PMMSUPPORT WorkingSet)
Definition: miarm.h:1389
BOOLEAN Mmi386MakeKernelPageTableGlobal(PVOID Address)
Definition: pagepae.c:844
VOID NTAPI MmRebalanceMemoryConsumersAndWait(VOID)
Definition: balance.c:300
NTSTATUS NTAPI MmNotPresentFault(KPROCESSOR_MODE Mode, ULONG_PTR Address, BOOLEAN FromMdl)
Definition: mmfault.c:111
NTSTATUS NTAPI MmpAccessFault(KPROCESSOR_MODE Mode, ULONG_PTR Address, BOOLEAN FromMdl)
Definition: mmfault.c:23
#define MM_SHARED_USER_DATA_VA
Definition: mmtypes.h:48
#define MI_IS_NOT_PRESENT_FAULT(FaultCode)
Definition: mm.h:121
#define MmSystemRangeStart
Definition: mm.h:32
FORCEINLINE PMMSUPPORT MmGetCurrentAddressSpace(VOID)
Definition: mm.h:1719
PMEMORY_AREA NTAPI MmLocateMemoryAreaByAddress(PMMSUPPORT AddressSpace, PVOID Address)
Definition: marea.c:60
#define MEMORY_AREA_OWNED_BY_ARM3
Definition: mm.h:97
FORCEINLINE PMMSUPPORT MmGetKernelAddressSpace(VOID)
Definition: mm.h:1726
MMSUPPORT MmSystemCacheWs
Definition: init.c:55

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

◆ MmAccessFaultSectionView()

NTSTATUS NTAPI MmAccessFaultSectionView ( PMMSUPPORT  AddressSpace,
MEMORY_AREA MemoryArea,
PVOID  Address,
BOOLEAN  Locked 
)

Definition at line 1910 of file section.c.

1914{
1916 PFN_NUMBER OldPage;
1917 PFN_NUMBER NewPage;
1918 PFN_NUMBER UnmappedPage;
1919 PVOID PAddress;
1924 BOOLEAN Cow = FALSE;
1926 BOOLEAN Unmapped;
1928
1929 DPRINT("MmAccessFaultSectionView(%p, %p, %p)\n", AddressSpace, MemoryArea, Address);
1930
1931 /* Get the region for this address */
1933 &MemoryArea->SectionData.RegionListHead,
1934 Address, NULL);
1935 ASSERT(Region != NULL);
1936 if (!(Region->Protect & PAGE_IS_WRITABLE))
1938
1939 /* Make sure we have a page mapping for this address. */
1941 {
1943 if (!NT_SUCCESS(Status))
1944 {
1945 /* This is invalid access ! */
1946 return Status;
1947 }
1948 }
1949
1950 /*
1951 * Check if the page has already been set readwrite
1952 */
1954 {
1955 DPRINT("Address 0x%p\n", Address);
1956 return STATUS_SUCCESS;
1957 }
1958
1959 /* Check if we are doing Copy-On-Write */
1960 Segment = MemoryArea->SectionData.Segment;
1961 Cow = Segment->WriteCopy || (Region->Protect & PAGE_IS_WRITECOPY);
1962
1963 if (!Cow)
1964 {
1965 /* Simply update page protection and we're done */
1967 return STATUS_SUCCESS;
1968 }
1969
1970 /* Calculate the new protection & check if we should update the region */
1971 NewProtect = Region->Protect;
1973 {
1974 NewProtect &= ~PAGE_IS_WRITECOPY;
1975 if (Region->Protect & PAGE_IS_EXECUTABLE)
1977 else
1980 &MemoryArea->SectionData.RegionListHead,
1983 }
1984
1985 /*
1986 * Find the offset of the page
1987 */
1988 PAddress = MM_ROUND_DOWN(Address, PAGE_SIZE);
1989 Offset.QuadPart = (ULONG_PTR)PAddress - MA_GetStartingAddress(MemoryArea)
1990 + MemoryArea->SectionData.ViewOffset;
1991
1992 /* Get the page mapping this section offset. */
1995
1996 /* Get the current page mapping for the process */
1997 ASSERT(MmIsPagePresent(Process, PAddress));
1998 OldPage = MmGetPfnForProcess(Process, PAddress);
1999 ASSERT(OldPage != 0);
2000
2001 if (IS_SWAP_FROM_SSE(Entry) ||
2002 PFN_FROM_SSE(Entry) != OldPage)
2003 {
2005 /* This is a private page. We must only change the page protection. */
2007 return STATUS_SUCCESS;
2008 }
2009
2010 /*
2011 * Allocate a page
2012 */
2014 if (!NT_SUCCESS(Status))
2015 {
2017 return STATUS_NO_MEMORY;
2018 }
2019
2020 /*
2021 * Copy the old page
2022 */
2023 NT_VERIFY(NT_SUCCESS(MiCopyFromUserPage(NewPage, PAddress)));
2024
2025 /*
2026 * Unshare the old page.
2027 */
2028 DPRINT("Swapping page (Old %x New %x)\n", OldPage, NewPage);
2029 Unmapped = MmDeleteVirtualMapping(Process, PAddress, NULL, &UnmappedPage);
2030 if (!Unmapped || (UnmappedPage != OldPage))
2031 {
2032 /* Uh , we had a page just before, but suddenly it changes. Someone corrupted us. */
2033 KeBugCheckEx(MEMORY_MANAGEMENT,
2035 (ULONG_PTR)PAddress,
2036 (ULONG_PTR)__FILE__,
2037 __LINE__);
2038 }
2039
2040 if (Process)
2041 MmDeleteRmap(OldPage, Process, PAddress);
2044
2045 /*
2046 * Set the PTE to point to the new page
2047 */
2048 if (!NT_SUCCESS(MmCreateVirtualMapping(Process, PAddress, NewProtect, NewPage)))
2049 {
2050 DPRINT1("MmCreateVirtualMapping failed, unable to create virtual mapping, not out of memory\n");
2051 KeBugCheck(MEMORY_MANAGEMENT);
2052 }
2053
2054 if (Process)
2055 MmInsertRmap(NewPage, Process, PAddress);
2056
2057 DPRINT("Address 0x%p\n", Address);
2058 return STATUS_SUCCESS;
2059}
_In_ PMEMORY_AREA _In_ PVOID _In_ BOOLEAN Locked
Definition: newmm.h:209
VOID NTAPI MmSetPageProtect(struct _EPROCESS *Process, PVOID Address, ULONG flProtect)
ULONG NTAPI MmGetPageProtect(struct _EPROCESS *Process, PVOID Address)
#define MmLockSectionSegment(x)
Definition: mm.h:1397
#define MC_USER
Definition: mm.h:114
#define MmUnlockSectionSegment(x)
Definition: mm.h:1405
PMM_REGION NTAPI MmFindRegion(PVOID BaseAddress, PLIST_ENTRY RegionListHead, PVOID Address, PVOID *RegionBaseAddress)
Definition: region.c:257
PFN_NUMBER NTAPI MmGetPfnForProcess(struct _EPROCESS *Process, PVOID Address)
#define PAGE_IS_WRITABLE
Definition: mm.h:153
FORCEINLINE PEPROCESS MmGetAddressSpaceOwner(IN PMMSUPPORT AddressSpace)
Definition: mm.h:1711
BOOLEAN NTAPI MmIsPagePresent(struct _EPROCESS *Process, PVOID Address)
NTSTATUS NTAPI MmAlterRegion(PMMSUPPORT AddressSpace, PVOID BaseAddress, PLIST_ENTRY RegionListHead, PVOID StartAddress, SIZE_T Length, ULONG NewType, ULONG NewProtect, PMM_ALTER_REGION_FUNC AlterFunc)
Definition: region.c:108
#define PAGE_IS_EXECUTABLE
Definition: mm.h:159
NTSTATUS NTAPI MmRequestPageMemoryConsumer(ULONG Consumer, BOOLEAN MyWait, PPFN_NUMBER AllocatedPage)
Definition: balance.c:313
NTSTATUS NTAPI MmCreateVirtualMapping(struct _EPROCESS *Process, PVOID Address, ULONG flProtect, PFN_NUMBER Page)
VOID NTAPI MmDeleteRmap(PFN_NUMBER Page, struct _EPROCESS *Process, PVOID Address)
#define MM_ROUND_DOWN(x, s)
Definition: mm.h:131
VOID NTAPI MmInsertRmap(PFN_NUMBER Page, struct _EPROCESS *Process, PVOID Address)
#define PAGE_IS_WRITECOPY
Definition: mm.h:165
VOID NTAPI MmDeleteVirtualMapping(IN PEPROCESS Process, IN PVOID Address, OUT PBOOLEAN WasDirty, OUT PPFN_NUMBER Page)
Definition: page.c:177
#define STATUS_ACCESS_VIOLATION
Definition: ntstatus.h:242
NTSTATUS Status
Definition: section.c:5033
NTSTATUS NTAPI MmNotPresentFaultSectionView(PMMSUPPORT AddressSpace, MEMORY_AREA *MemoryArea, PVOID Address, BOOLEAN Locked)
Definition: section.c:1532
BOOLEAN NTAPI MmUnsharePageEntrySectionSegment(PMEMORY_AREA MemoryArea, PMM_SECTION_SEGMENT Segment, PLARGE_INTEGER Offset, BOOLEAN Dirty, BOOLEAN PageOut, ULONG_PTR *InEntry)
Definition: section.c:1089
Entry
Definition: section.c:5042
static NTSTATUS MiCopyFromUserPage(PFN_NUMBER DestPage, const VOID *SrcAddress)
Definition: section.c:1170
static VOID MmAlterViewAttributes(PMMSUPPORT AddressSpace, PVOID BaseAddress, SIZE_T RegionSize, ULONG OldType, ULONG OldProtect, ULONG NewType, ULONG NewProtect)
Definition: section.c:1446
return FALSE
Definition: section.c:5197
PLARGE_INTEGER Offset
Definition: section.c:5028
struct _MEMORY_AREA::@1787 SectionData
Definition: mm.h:463
_In_ ULONG _In_ PHYSICAL_ADDRESS _Inout_ PULONG AddressSpace
Definition: iofuncs.h:2274
_Must_inspect_result_ _In_ ULONG NewProtect
Definition: mmfuncs.h:682
#define NT_VERIFY(exp)
Definition: rtlfuncs.h:3287

Referenced by MmpAccessFault().

◆ MmAdjustWorkingSetSize()

NTSTATUS NTAPI MmAdjustWorkingSetSize ( IN SIZE_T  WorkingSetMinimumInBytes,
IN SIZE_T  WorkingSetMaximumInBytes,
IN ULONG  SystemCache,
IN BOOLEAN  IncreaseOkay 
)

Definition at line 44 of file mmsup.c.

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

Referenced by PspSetQuotaLimits().

◆ MmAllocateSpecialPool()

PVOID NTAPI MmAllocateSpecialPool ( IN SIZE_T  NumberOfBytes,
IN ULONG  Tag,
IN POOL_TYPE  PoolType,
IN ULONG  SpecialType 
)

Referenced by ExAllocatePoolWithTag().

◆ MmAllocPage()

PFN_NUMBER NTAPI MmAllocPage ( ULONG  Consumer)

Definition at line 601 of file freelist.c.

602{
603 PFN_NUMBER PfnOffset;
604 PMMPFN Pfn1;
606
607 OldIrql = MiAcquirePfnLock();
608
609#if MI_TRACE_PFNS
610 switch(Type)
611 {
612 case MC_SYSTEM:
614 break;
615 case MC_USER:
617 break;
618 default:
619 ASSERT(FALSE);
620 }
621#endif
622
623 PfnOffset = MiRemoveZeroPage(MI_GET_NEXT_COLOR());
624 if (!PfnOffset)
625 {
626 MiReleasePfnLock(OldIrql);
627 return 0;
628 }
629
630 DPRINT("Legacy allocate: %lx\n", PfnOffset);
631 Pfn1 = MiGetPfnEntry(PfnOffset);
632 Pfn1->u3.e2.ReferenceCount = 1;
634
635 /* This marks the PFN as a ReactOS PFN */
636 Pfn1->u4.AweAllocation = TRUE;
637
638 /* Allocate the extra ReactOS Data and zero it out */
639 Pfn1->u1.SwapEntry = 0;
640 Pfn1->RmapListHead = NULL;
641
642 Pfn1->NextLRU = NULL;
643 Pfn1->PreviousLRU = NULL;
644
645 if (Type == MC_USER)
646 {
647 Pfn1->u4.MustBeCached = 1; /* HACK again */
648 MmInsertLRULastUserPage(PfnOffset);
649 }
650
651 MiReleasePfnLock(OldIrql);
652 return PfnOffset;
653}
Type
Definition: Type.h:7
static VOID MmInsertLRULastUserPage(PFN_NUMBER Page)
Definition: freelist.c:69
PFN_NUMBER NTAPI MiRemoveZeroPage(IN ULONG Color)
Definition: pfnlist.c:537
#define MC_SYSTEM
Definition: mm.h:115
PMM_RMAP_ENTRY RmapListHead
Definition: mm.h:411
ULONG_PTR MustBeCached
Definition: mm.h:423
struct _MMPFN * NextLRU
Definition: mm.h:435
union _MMPFN::@1788 u1
struct _MMPFN * PreviousLRU
Definition: mm.h:436
SWAPENTRY SwapEntry
Definition: mm.h:384
ULONG_PTR AweAllocation
Definition: mm.h:421

Referenced by MmRequestPageMemoryConsumer().

◆ MmAllocSwapPage()

SWAPENTRY NTAPI MmAllocSwapPage ( VOID  )

Definition at line 322 of file pagefile.c.

323{
324 ULONG i;
325 ULONG off;
327
329
330 if (MiFreeSwapPages == 0)
331 {
333 return(0);
334 }
335
336 for (i = 0; i < MAX_PAGING_FILES; i++)
337 {
338 if (MmPagingFile[i] != NULL &&
339 MmPagingFile[i]->FreeSpace >= 1)
340 {
342 if (off == 0xFFFFFFFF)
343 {
344 KeBugCheck(MEMORY_MANAGEMENT);
346 return(STATUS_UNSUCCESSFUL);
347 }
351
353
354 entry = ENTRY_FROM_FILE_OFFSET(i, off + 1);
355 return(entry);
356 }
357 }
358
360 KeBugCheck(MEMORY_MANAGEMENT);
361 return(0);
362}
uint32_t entry
Definition: isohybrid.c:63
FORCEINLINE VOID UpdateTotalCommittedPages(LONG Delta)
Definition: mm.h:871
ULONG_PTR SWAPENTRY
Definition: mm.h:57
KGUARDED_MUTEX MmPageFileCreationLock
Definition: pagefile.c:60
PFN_COUNT MiFreeSwapPages
Definition: pagefile.c:66
#define ENTRY_FROM_FILE_OFFSET(i, j)
Definition: pagefile.c:98
PFN_COUNT MiUsedSwapPages
Definition: pagefile.c:69

Referenced by MmPageOutPhysicalAddress().

◆ MmAlterRegion()

NTSTATUS NTAPI MmAlterRegion ( PMMSUPPORT  AddressSpace,
PVOID  BaseAddress,
PLIST_ENTRY  RegionListHead,
PVOID  StartAddress,
SIZE_T  Length,
ULONG  NewType,
ULONG  NewProtect,
PMM_ALTER_REGION_FUNC  AlterFunc 
)

Definition at line 108 of file region.c.

111{
112 PMM_REGION InitialRegion;
113 PVOID InitialBaseAddress = NULL;
114 PMM_REGION NewRegion;
115 PLIST_ENTRY CurrentEntry;
116 PMM_REGION CurrentRegion = NULL;
117 PVOID CurrentBaseAddress;
118 SIZE_T RemainingLength;
119
120 /*
121 * Find the first region containing part of the range of addresses to
122 * be altered.
123 */
124 InitialRegion = MmFindRegion(BaseAddress, RegionListHead, StartAddress,
125 &InitialBaseAddress);
126 /*
127 * If necessary then split the region into the affected and unaffected parts.
128 */
129 if (InitialRegion->Type != NewType || InitialRegion->Protect != NewProtect)
130 {
131 NewRegion = MmSplitRegion(InitialRegion, InitialBaseAddress,
132 StartAddress, Length, NewType, NewProtect,
133 AddressSpace, AlterFunc);
134 if (NewRegion == NULL)
135 {
136 return(STATUS_NO_MEMORY);
137 }
138 if(NewRegion->Length < Length)
139 RemainingLength = Length - NewRegion->Length;
140 else
141 RemainingLength = 0;
142 }
143 else
144 {
145 NewRegion = InitialRegion;
146 if(((ULONG_PTR)InitialBaseAddress + NewRegion->Length) <
147 ((ULONG_PTR)StartAddress + Length))
148 RemainingLength = ((ULONG_PTR)StartAddress + Length) - ((ULONG_PTR)InitialBaseAddress + NewRegion->Length);
149 else
150 RemainingLength = 0;
151 }
152
153 /*
154 * Free any complete regions that are containing in the range of addresses
155 * and call the helper function to actually do the changes.
156 */
157 CurrentEntry = NewRegion->RegionListEntry.Flink;
158 CurrentRegion = CONTAINING_RECORD(CurrentEntry, MM_REGION,
159 RegionListEntry);
160 CurrentBaseAddress = (char*)StartAddress + NewRegion->Length;
161 while (RemainingLength > 0 && CurrentRegion->Length <= RemainingLength &&
162 CurrentEntry != RegionListHead)
163 {
164 if (CurrentRegion->Type != NewType ||
165 CurrentRegion->Protect != NewProtect)
166 {
167 AlterFunc(AddressSpace, CurrentBaseAddress, CurrentRegion->Length,
168 CurrentRegion->Type, CurrentRegion->Protect,
169 NewType, NewProtect);
170 }
171
172 CurrentBaseAddress = (PVOID)((ULONG_PTR)CurrentBaseAddress + CurrentRegion->Length);
173 NewRegion->Length += CurrentRegion->Length;
174 RemainingLength -= CurrentRegion->Length;
175 CurrentEntry = CurrentEntry->Flink;
176 RemoveEntryList(&CurrentRegion->RegionListEntry);
177 ExFreePoolWithTag(CurrentRegion, TAG_MM_REGION);
178 CurrentRegion = CONTAINING_RECORD(CurrentEntry, MM_REGION,
179 RegionListEntry);
180 }
181
182 /*
183 * Split any final region.
184 */
185 if (RemainingLength > 0 && CurrentEntry != RegionListHead)
186 {
187 CurrentRegion = CONTAINING_RECORD(CurrentEntry, MM_REGION,
188 RegionListEntry);
189 if (CurrentRegion->Type != NewType ||
190 CurrentRegion->Protect != NewProtect)
191 {
192 AlterFunc(AddressSpace, CurrentBaseAddress, RemainingLength,
193 CurrentRegion->Type, CurrentRegion->Protect,
194 NewType, NewProtect);
195 }
196 NewRegion->Length += RemainingLength;
197 CurrentRegion->Length -= RemainingLength;
198 }
199
200 /*
201 * If the region after the new region has the same type then merge them.
202 */
203 if (NewRegion->RegionListEntry.Flink != RegionListHead)
204 {
205 CurrentEntry = NewRegion->RegionListEntry.Flink;
206 CurrentRegion = CONTAINING_RECORD(CurrentEntry, MM_REGION,
207 RegionListEntry);
208 if (CurrentRegion->Type == NewRegion->Type &&
209 CurrentRegion->Protect == NewRegion->Protect)
210 {
211 NewRegion->Length += CurrentRegion->Length;
212 RemoveEntryList(&CurrentRegion->RegionListEntry);
213 ExFreePoolWithTag(CurrentRegion, TAG_MM_REGION);
214 }
215 }
216
217 /*
218 * If the region before the new region has the same type then merge them.
219 */
220 if (NewRegion->RegionListEntry.Blink != RegionListHead)
221 {
222 CurrentEntry = NewRegion->RegionListEntry.Blink;
223 CurrentRegion = CONTAINING_RECORD(CurrentEntry, MM_REGION,
224 RegionListEntry);
225 if (CurrentRegion->Type == NewRegion->Type &&
226 CurrentRegion->Protect == NewRegion->Protect)
227 {
228 NewRegion->Length += CurrentRegion->Length;
229 RemoveEntryList(&CurrentRegion->RegionListEntry);
230 ExFreePoolWithTag(CurrentRegion, TAG_MM_REGION);
231 }
232 }
233
234 return(STATUS_SUCCESS);
235}
while(CdLookupNextInitialFileDirent(IrpContext, Fcb, FileContext))
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
static PMM_REGION MmSplitRegion(PMM_REGION InitialRegion, PVOID InitialBaseAddress, PVOID StartAddress, SIZE_T Length, ULONG NewType, ULONG NewProtect, PMMSUPPORT AddressSpace, PMM_ALTER_REGION_FUNC AlterFunc)
Definition: region.c:34
PMM_REGION NTAPI MmFindRegion(PVOID BaseAddress, PLIST_ENTRY RegionListHead, PVOID Address, PVOID *RegionBaseAddress)
Definition: region.c:257
struct _LIST_ENTRY * Blink
Definition: typedefs.h:122
LIST_ENTRY RegionListEntry
Definition: mm.h:467
ULONG Type
Definition: mm.h:464
SIZE_T Length
Definition: mm.h:466
ULONG Protect
Definition: mm.h:465
#define TAG_MM_REGION
Definition: tag.h:111

Referenced by MmAccessFaultSectionView(), MmNotPresentFaultSectionView(), and MmProtectSectionView().

◆ MmArePagesResident()

BOOLEAN NTAPI MmArePagesResident ( _In_ PEPROCESS  Process,
_In_ PVOID  BaseAddress,
_In_ ULONG  Length 
)

Definition at line 4775 of file section.c.

4779{
4781 BOOLEAN Ret = TRUE;
4783 LARGE_INTEGER SegmentOffset, RangeEnd;
4785
4787
4789 if (MemoryArea == NULL)
4790 {
4792 return FALSE;
4793 }
4794
4795 /* Only supported in old Mm for now */
4797 /* For file mappings */
4799
4800 Segment = MemoryArea->SectionData.Segment;
4802
4804 + MemoryArea->SectionData.ViewOffset;
4806 + MemoryArea->SectionData.ViewOffset;
4807
4808 while (SegmentOffset.QuadPart < RangeEnd.QuadPart)
4809 {
4811 if ((Entry == 0) || IS_SWAP_FROM_SSE(Entry))
4812 {
4813 Ret = FALSE;
4814 break;
4815 }
4816 SegmentOffset.QuadPart += PAGE_SIZE;
4817 }
4818
4820
4822 return Ret;
4823}
@ VadImageMap
Definition: mmtypes.h:206
#define PAGE_ROUND_DOWN(x)
Definition: mmtypes.h:36
FORCEINLINE VOID MmLockAddressSpace(PMMSUPPORT AddressSpace)
Definition: mm.h:1691
FORCEINLINE VOID MmUnlockAddressSpace(PMMSUPPORT AddressSpace)
Definition: mm.h:1704
MMVAD VadNode
Definition: mm.h:249
ULONG_PTR VadType
Definition: mmtypes.h:694
MMVAD_FLAGS VadFlags
Definition: mmtypes.h:734
union _MMVAD::@2606 u

Referenced by CcRosEnsureVacbResident().

◆ MmBuildMdlFromPages()

VOID NTAPI MmBuildMdlFromPages ( PMDL  Mdl,
PPFN_NUMBER  Pages 
)

Definition at line 111 of file pagefile.c.

112{
113 memcpy(Mdl + 1, Pages, sizeof(PFN_NUMBER) * (PAGE_ROUND_UP(Mdl->ByteOffset+Mdl->ByteCount)/PAGE_SIZE));
114}
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878

Referenced by MiReadPageFile(), and MmWriteToSwapPage().

◆ MmCallDllInitialize()

NTSTATUS NTAPI MmCallDllInitialize ( _In_ PLDR_DATA_TABLE_ENTRY  LdrEntry,
_In_ PLIST_ENTRY  ModuleListHead 
)

Definition at line 432 of file sysldr.c.

435{
437 L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\");
438 PMM_DLL_INITIALIZE DllInit;
439 UNICODE_STRING RegPath, ImportName;
442
443 PAGED_CODE();
444
445 /* Try to see if the image exports a DllInitialize routine */
446 DllInit = (PMM_DLL_INITIALIZE)
447 RtlFindExportedRoutineByName(LdrEntry->DllBase, "DllInitialize");
448 if (!DllInit)
449 return STATUS_SUCCESS;
450
451 /* Make a temporary copy of BaseDllName because we will alter its length */
452 ImportName.Length = LdrEntry->BaseDllName.Length;
453 ImportName.MaximumLength = LdrEntry->BaseDllName.MaximumLength;
454 ImportName.Buffer = LdrEntry->BaseDllName.Buffer;
455
456 /* Obtain the path to this dll's service in the registry */
457 RegPath.MaximumLength = ServicesKeyName.Length +
458 ImportName.Length + sizeof(UNICODE_NULL);
460 RegPath.MaximumLength,
462
463 /* Check if this allocation was unsuccessful */
464 if (!RegPath.Buffer)
466
467 /* Build and append the service name itself */
468 RegPath.Length = ServicesKeyName.Length;
469 RtlCopyMemory(RegPath.Buffer,
470 ServicesKeyName.Buffer,
471 ServicesKeyName.Length);
472
473 /* If the filename has an extension, remove it */
474 Extension = wcschr(ImportName.Buffer, L'.');
475 if (Extension)
476 ImportName.Length = (USHORT)(Extension - ImportName.Buffer) * sizeof(WCHAR);
477
478 /* Append the service name (base name without extension) */
479 RtlAppendUnicodeStringToString(&RegPath, &ImportName);
480
481 /* Now call DllInitialize */
482 DPRINT("Calling DllInit(%wZ)\n", &RegPath);
483 Status = DllInit(&RegPath);
484
485 /* Clean up */
487
488 // TODO: This is for Driver Verifier support.
490
491 /* Return the DllInitialize status value */
492 return Status;
493}
#define wcschr
Definition: compat.h:17
_Inout_opt_ PUNICODE_STRING Extension
Definition: fltkernel.h:1092
LIST_ENTRY * ModuleListHead
Definition: kdpacket.c:23
NTSYSAPI NTSTATUS NTAPI RtlAppendUnicodeStringToString(PUNICODE_STRING Destination, PUNICODE_STRING Source)
CONST WCHAR * PCWCH
Definition: ntbasedef.h:411
static const WCHAR ServicesKeyName[]
Definition: driver.c:32
#define L(x)
Definition: ntvdm.h:50
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 n...
Definition: sysldr.c:400
#define RTL_CONSTANT_STRING(s)
Definition: tunneltest.c:14
NTSTATUS(NTAPI * PMM_DLL_INITIALIZE)(_In_ PUNICODE_STRING RegistryPath)
Definition: iotypes.h:2850

Referenced by IopInitializeBootDrivers(), and MiResolveImageReferences().

◆ MmChangeKernelResourceSectionProtection()

BOOLEAN NTAPI MmChangeKernelResourceSectionProtection ( IN ULONG_PTR  ProtectionMask)

Definition at line 2330 of file sysldr.c.

2331{
2332 PMMPTE PointerPte;
2333 MMPTE TempPte;
2334
2335 /* Don't do anything if the resource section is already writable */
2337 return FALSE;
2338
2339 /* If the resource section is physical, we cannot change its protection */
2341 return FALSE;
2342
2343 /* Loop the PTEs */
2344 for (PointerPte = MiKernelResourceStartPte; PointerPte < MiKernelResourceEndPte; ++PointerPte)
2345 {
2346 /* Read the PTE */
2347 TempPte = *PointerPte;
2348
2349 /* Update the protection */
2350 MI_MAKE_HARDWARE_PTE_KERNEL(&TempPte, PointerPte, ProtectionMask, TempPte.u.Hard.PageFrameNumber);
2351 MI_UPDATE_VALID_PTE(PointerPte, TempPte);
2352 }
2353
2354 /* Only flush the current processor's TLB */
2356 return TRUE;
2357}
FORCEINLINE BOOLEAN MI_IS_PHYSICAL_ADDRESS(IN PVOID Address)
Definition: miarm.h:945
FORCEINLINE VOID MI_UPDATE_VALID_PTE(IN PMMPTE PointerPte, IN MMPTE TempPte)
Definition: miarm.h:977
VOID NTAPI KeFlushCurrentTb(VOID)
Definition: cpu.c:526
PMMPTE MiKernelResourceEndPte
Definition: sysldr.c:36
PMMPTE MiKernelResourceStartPte
Definition: sysldr.c:36

Referenced by DisplayBootBitmap(), and MmMakeKernelResourceSectionWritable().

◆ MmCheckDirtySegment()

BOOLEAN NTAPI MmCheckDirtySegment ( PMM_SECTION_SEGMENT  Segment,
PLARGE_INTEGER  Offset,
BOOLEAN  ForceDirty,
BOOLEAN  PageOut 
)

◆ MmCheckSystemImage()

NTSTATUS NTAPI MmCheckSystemImage ( IN HANDLE  ImageHandle,
IN BOOLEAN  PurgeSection 
)

Definition at line 2744 of file sysldr.c.

2746{
2748 HANDLE SectionHandle;
2749 PVOID ViewBase = NULL;
2750 SIZE_T ViewSize = 0;
2752 FILE_STANDARD_INFORMATION FileStandardInfo;
2754 PIMAGE_NT_HEADERS NtHeaders;
2756 PAGED_CODE();
2757
2758 /* Setup the object attributes */
2760 NULL,
2762 NULL,
2763 NULL);
2764
2765 /* Create a section for the DLL */
2766 Status = ZwCreateSection(&SectionHandle,
2769 NULL,
2771 SEC_IMAGE,
2772 ImageHandle);
2773 if (!NT_SUCCESS(Status))
2774 {
2775 DPRINT1("ZwCreateSection failed with status 0x%x\n", Status);
2776 return Status;
2777 }
2778
2779 /* Make sure we're in the system process */
2781
2782 /* Map it */
2783 Status = ZwMapViewOfSection(SectionHandle,
2785 &ViewBase,
2786 0,
2787 0,
2788 NULL,
2789 &ViewSize,
2790 ViewShare,
2791 0,
2792 PAGE_EXECUTE);
2793 if (!NT_SUCCESS(Status))
2794 {
2795 /* We failed, close the handle and return */
2796 DPRINT1("ZwMapViewOfSection failed with status 0x%x\n", Status);
2798 ZwClose(SectionHandle);
2799 return Status;
2800 }
2801
2802 /* Now query image information */
2803 Status = ZwQueryInformationFile(ImageHandle,
2805 &FileStandardInfo,
2806 sizeof(FileStandardInfo),
2808 if (NT_SUCCESS(Status))
2809 {
2810 /* First, verify the checksum */
2812 ViewSize,
2813 FileStandardInfo.
2814 EndOfFile.LowPart))
2815 {
2816 /* Set checksum failure */
2818 goto Fail;
2819 }
2820
2821 /* Make sure it's a real image */
2822 NtHeaders = RtlImageNtHeader(ViewBase);
2823 if (!NtHeaders)
2824 {
2825 /* Set checksum failure */
2827 goto Fail;
2828 }
2829
2830 /* Make sure it's for the correct architecture */
2831 if ((NtHeaders->FileHeader.Machine != IMAGE_FILE_MACHINE_NATIVE) ||
2833 {
2834 /* Set protection failure */
2836 goto Fail;
2837 }
2838
2839 /* Check that it's a valid SMP image if we have more then one CPU */
2840 if (!MmVerifyImageIsOkForMpUse(ViewBase))
2841 {
2842 /* Otherwise it's not the right image */
2844 }
2845 }
2846
2847 /* Unmap the section, close the handle, and return status */
2848Fail:
2849 ZwUnmapViewOfSection(NtCurrentProcess(), ViewBase);
2851 ZwClose(SectionHandle);
2852 return Status;
2853}
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:36
int Fail
Definition: ehthrow.cxx:24
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
BOOLEAN NTAPI LdrVerifyMappedImageMatchesChecksum(_In_ PVOID BaseAddress, _In_ SIZE_T NumberOfBytes, _In_ ULONG FileLength)
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID _In_ ULONG_PTR _In_ SIZE_T _Inout_opt_ PLARGE_INTEGER _Inout_ PSIZE_T ViewSize
Definition: mmfuncs.h:408
#define SEC_IMAGE
Definition: mmtypes.h:97
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
#define SECTION_MAP_EXECUTE
Definition: nt_native.h:1290
#define NtCurrentProcess()
Definition: nt_native.h:1657
@ ViewShare
Definition: nt_native.h:1278
#define IMAGE_NT_OPTIONAL_HDR_MAGIC
Definition: ntimage.h:387
_Out_ PKAPC_STATE ApcState
Definition: mm.h:1765
#define STATUS_IMAGE_CHECKSUM_MISMATCH
Definition: ntstatus.h:677
#define STATUS_IMAGE_MP_UP_MISMATCH
Definition: ntstatus.h:717
#define STATUS_INVALID_IMAGE_PROTECT
Definition: ntstatus.h:540
VOID NTAPI KeStackAttachProcess(IN PKPROCESS Process, OUT PRKAPC_STATE ApcState)
Definition: procobj.c:704
VOID NTAPI KeUnstackDetachProcess(IN PRKAPC_STATE ApcState)
Definition: procobj.c:756
#define FileStandardInformation
Definition: propsheet.cpp:61
PEPROCESS PsInitialSystemProcess
Definition: psmgr.c:50
KPROCESS Pcb
Definition: pstypes.h:1262
BOOLEAN NTAPI MmVerifyImageIsOkForMpUse(IN PVOID BaseAddress)
Definition: sysldr.c:2720
KAPC_STATE
Definition: ketypes.h:1409

Referenced by MmLoadSystemImage(), and PsLocateSystemDll().

◆ MmCleanProcessAddressSpace()

VOID NTAPI MmCleanProcessAddressSpace ( IN PEPROCESS  Process)

Definition at line 1267 of file procsup.c.

1268{
1269 PMMVAD Vad;
1270 PMM_AVL_TABLE VadTree;
1272
1273 /* Remove from the session */
1275
1276 /* Abort early, when the address space wasn't fully initialized */
1277 if (Process->AddressSpaceInitialized < 2)
1278 {
1279 DPRINT1("Incomplete address space for Process %p. Might leak resources.\n",
1280 Process);
1281 return;
1282 }
1283
1284 /* Lock the process address space from changes */
1287
1288 /* VM is deleted now */
1289 Process->VmDeleted = TRUE;
1291
1292 /* Enumerate the VADs */
1293 VadTree = &Process->VadRoot;
1294 while (VadTree->NumberGenericTableElements)
1295 {
1296 /* Grab the current VAD */
1297 Vad = (PMMVAD)VadTree->BalancedRoot.RightChild;
1298
1299 /* Check for old-style memory areas */
1300 if (Vad->u.VadFlags.Spare == 1)
1301 {
1302 /* Let RosMm handle this */
1304 continue;
1305 }
1306
1307 /* Lock the working set */
1309
1310 /* Remove this VAD from the tree */
1311 ASSERT(VadTree->NumberGenericTableElements >= 1);
1312 MiRemoveNode((PMMADDRESS_NODE)Vad, VadTree);
1313
1314 /* Only regular VADs supported for now */
1315 ASSERT(Vad->u.VadFlags.VadType == VadNone);
1316
1317 /* Check if this is a section VAD */
1318 if (!(Vad->u.VadFlags.PrivateMemory) && (Vad->ControlArea))
1319 {
1320 /* Remove the view */
1322 }
1323 else
1324 {
1325 /* Delete the addresses */
1327 (Vad->EndingVpn << PAGE_SHIFT) | (PAGE_SIZE - 1),
1328 Vad);
1329
1330 /* Release the working set */
1332 }
1333
1334 /* Skip ARM3 fake VADs, they'll be freed by MmDeleteProcessAddresSpace */
1335 if (Vad->u.VadFlags.Spare == 1)
1336 {
1337 /* Set a flag so MmDeleteMemoryArea knows to free, but not to remove */
1338 Vad->u.VadFlags.Spare = 2;
1339 continue;
1340 }
1341
1342 /* Free the VAD memory */
1343 ExFreePool(Vad);
1344
1345 /* Return the quota the VAD used */
1347 }
1348
1349 /* Lock the working set */
1351 ASSERT(Process->CloneRoot == NULL);
1352 ASSERT(Process->PhysicalVadRoot == NULL);
1353
1354 /* Delete the shared user data section */
1356
1357 /* Release the working set */
1359
1360 /* Release the address space */
1362}
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
_In_opt_ PFILE_OBJECT _In_opt_ PETHREAD Thread
Definition: fltkernel.h:2653
#define USER_SHARED_DATA
Definition: pstypes.h:51
if(dx< 0)
Definition: linetemp.h:194
VOID NTAPI MiDeleteVirtualAddresses(IN ULONG_PTR Va, IN ULONG_PTR EndingAddress, IN PMMVAD Vad)
Definition: virtual.c:530
VOID NTAPI MiRemoveNode(IN PMMADDRESS_NODE Node, IN PMM_AVL_TABLE Table)
Definition: vadnode.c:440
VOID NTAPI MiRemoveMappedView(IN PEPROCESS CurrentProcess, IN PMMVAD Vad)
Definition: section.c:766
FORCEINLINE VOID MiUnlockProcessWorkingSetUnsafe(IN PEPROCESS Process, IN PETHREAD Thread)
Definition: miarm.h:1239
VOID NTAPI MiSessionRemoveProcess(VOID)
Definition: session.c:392
FORCEINLINE VOID MiLockProcessWorkingSetUnsafe(IN PEPROCESS Process, IN PETHREAD Thread)
Definition: miarm.h:1169
@ VadNone
Definition: mmtypes.h:204
struct _MMVAD * PMMVAD
VOID NTAPI MiRosCleanupMemoryArea(PEPROCESS Process, PMMVAD Vad)
Definition: marea.c:521
VOID NTAPI PsReturnProcessNonPagedPoolQuota(_In_ PEPROCESS Process, _In_ SIZE_T Amount)
Returns the non paged quota pool that the process was taking up.
Definition: quota.c:938
struct _MMADDRESS_NODE * RightChild
Definition: mmtypes.h:652
ULONG_PTR Spare
Definition: mmtypes.h:697
ULONG_PTR PrivateMemory
Definition: mmtypes.h:698
ULONG_PTR EndingVpn
Definition: mmtypes.h:730
PCONTROL_AREA ControlArea
Definition: mmtypes.h:736
ULONG_PTR StartingVpn
Definition: mmtypes.h:729
ULONG_PTR NumberGenericTableElements
Definition: mmtypes.h:668
MMADDRESS_NODE BalancedRoot
Definition: mmtypes.h:662

Referenced by PspExitProcess(), and PspExitThread().

◆ MmCopyVirtualMemory()

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 
)

Definition at line 1268 of file virtual.c.

1275{
1277 PEPROCESS Process = SourceProcess;
1278
1279 //
1280 // Don't accept zero-sized buffers
1281 //
1282 if (!BufferSize) return STATUS_SUCCESS;
1283
1284 //
1285 // If we are copying from ourselves, lock the target instead
1286 //
1287 if (SourceProcess == PsGetCurrentProcess()) Process = TargetProcess;
1288
1289 //
1290 // Acquire rundown protection
1291 //
1292 if (!ExAcquireRundownProtection(&Process->RundownProtect))
1293 {
1294 //
1295 // Fail
1296 //
1298 }
1299
1300 //
1301 // See if we should use the pool copy
1302 //
1304 {
1305 //
1306 // Use MDL-copy
1307 //
1308 Status = MiDoMappedCopy(SourceProcess,
1310 TargetProcess,
1312 BufferSize,
1314 ReturnSize);
1315 }
1316 else
1317 {
1318 //
1319 // Do pool copy
1320 //
1321 Status = MiDoPoolCopy(SourceProcess,
1323 TargetProcess,
1325 BufferSize,
1327 ReturnSize);
1328 }
1329
1330 //
1331 // Release the lock
1332 //
1333 ExReleaseRundownProtection(&Process->RundownProtect);
1334 return Status;
1335}
#define ExReleaseRundownProtection
Definition: ex.h:136
#define ExAcquireRundownProtection
Definition: ex.h:135
NTSTATUS NTAPI MiDoPoolCopy(IN PEPROCESS SourceProcess, IN PVOID SourceAddress, IN PEPROCESS TargetProcess, OUT PVOID TargetAddress, IN SIZE_T BufferSize, IN KPROCESSOR_MODE PreviousMode, OUT PSIZE_T ReturnSize)
Definition: virtual.c:1017
NTSTATUS NTAPI MiDoMappedCopy(IN PEPROCESS SourceProcess, IN PVOID SourceAddress, IN PEPROCESS TargetProcess, OUT PVOID TargetAddress, IN SIZE_T BufferSize, IN KPROCESSOR_MODE PreviousMode, OUT PSIZE_T ReturnSize)
Definition: virtual.c:792
#define MI_POOL_COPY_BYTES
Definition: virtual.c:19
#define STATUS_PROCESS_IS_TERMINATING
Definition: ntstatus.h:502
_In_ WDFMEMORY _Out_opt_ size_t * BufferSize
Definition: wdfmemory.h:254
_Must_inspect_result_ typedef _In_ PHYSICAL_ADDRESS _Inout_ PLARGE_INTEGER _Outptr_ PVOID * TargetAddress
Definition: iotypes.h:1037
_Must_inspect_result_ typedef _In_ PHYSICAL_ADDRESS SourceAddress
Definition: iotypes.h:1127
_In_ KPROCESSOR_MODE PreviousMode
Definition: sefuncs.h:103

Referenced by LpcpCopyRequestData(), NtReadVirtualMemory(), and NtWriteVirtualMemory().

◆ MmCreateKernelStack()

PVOID NTAPI MmCreateKernelStack ( BOOLEAN  GuiStack,
UCHAR  Node 
)

◆ MmCreateMemoryArea()

NTSTATUS NTAPI MmCreateMemoryArea ( PMMSUPPORT  AddressSpace,
ULONG  Type,
PVOID BaseAddress,
SIZE_T  Length,
ULONG  Protection,
PMEMORY_AREA Result,
ULONG  AllocationFlags,
ULONG  AllocationGranularity 
)

Definition at line 410 of file marea.c.

418{
419 ULONG_PTR tmpLength;
421 ULONG_PTR EndingAddress;
422
423 DPRINT("MmCreateMemoryArea(Type 0x%lx, BaseAddress %p, "
424 "*BaseAddress %p, Length %p, AllocationFlags %x, "
425 "Result %p)\n",
426 Type, BaseAddress, *BaseAddress, Length, AllocationFlags,
427 Result);
428
429 /* Is this a static memory area? */
431 {
432 /* Use the static array instead of the pool */
435 }
436 else
437 {
438 /* Allocate the memory area from nonpaged pool */
440 sizeof(MEMORY_AREA),
441 TAG_MAREA);
442 }
443
444 if (!MemoryArea)
445 {
446 DPRINT1("Not enough memory.\n");
447 return STATUS_NO_MEMORY;
448 }
449
451 MemoryArea->Type = Type & ~MEMORY_AREA_STATIC;
452 MemoryArea->Flags = AllocationFlags;
453 MemoryArea->Magic = 'erAM';
455
456 if (*BaseAddress == 0)
457 {
458 tmpLength = (ULONG_PTR)MM_ROUND_UP(Length, PAGE_SIZE);
460 tmpLength,
461 Granularity,
462 (AllocationFlags & MEM_TOP_DOWN) == MEM_TOP_DOWN);
463 if ((*BaseAddress) == 0)
464 {
465 DPRINT("No suitable gap\n");
467 return STATUS_NO_MEMORY;
468 }
469
473 }
474 else
475 {
476 EndingAddress = ((ULONG_PTR)*BaseAddress + Length - 1) | (PAGE_SIZE - 1);
478 tmpLength = EndingAddress + 1 - (ULONG_PTR)*BaseAddress;
479
481 {
482 ASSERT(FALSE);
485 }
486
489 {
490 DPRINT("Memory area for user mode address space exceeds MmSystemRangeStart\n");
493 }
494
495 /* No need to check ARM3 owned memory areas, the range MUST be free */
497 {
500 tmpLength) != NULL)
501 {
502 DPRINT("Memory area already occupied\n");
505 }
506 }
507
511 }
512
514
515 DPRINT("MmCreateMemoryArea() succeeded (%p)\n", *BaseAddress);
516 return STATUS_SUCCESS;
517}
PMEMORY_AREA NTAPI MmLocateMemoryAreaByRegion(PMMSUPPORT AddressSpace, PVOID Address_, ULONG_PTR Length)
Definition: marea.c:106
MEMORY_AREA MiStaticMemoryAreas[MI_STATIC_MEMORY_AREAS]
Definition: marea.c:51
ULONG MiStaticMemoryAreaCount
Definition: marea.c:52
PVOID NTAPI MmFindGap(PMMSUPPORT AddressSpace, ULONG_PTR Length, ULONG_PTR Granularity, BOOLEAN TopDown)
Definition: marea.c:215
static VOID MmInsertMemoryArea(PMMSUPPORT AddressSpace, PMEMORY_AREA marea, ULONG Protect)
Definition: marea.c:166
#define MEM_TOP_DOWN
Definition: nt_native.h:1321
#define MI_STATIC_MEMORY_AREAS
Definition: mm.h:90
#define MM_ROUND_UP(x, s)
Definition: mm.h:128
#define MEMORY_AREA_STATIC
Definition: mm.h:98
ULONG Flags
Definition: mm.h:252
ULONG Magic
Definition: mm.h:254
BOOLEAN DeleteInProgress
Definition: mm.h:253
#define TAG_MAREA
Definition: tag.h:107
#define ALIGN_DOWN_POINTER_BY(ptr, align)
Definition: umtypes.h:82
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID _In_ ULONG_PTR _In_ SIZE_T _Inout_opt_ PLARGE_INTEGER _Inout_ PSIZE_T _In_ SECTION_INHERIT _In_ ULONG _In_ ULONG Protect
Definition: zwfuncs.h:221

Referenced by MiCreateArm3StaticMemoryArea(), MiInsertNode(), and MmMapViewOfSegment().

◆ MmCreatePageFileMapping()

NTSTATUS NTAPI MmCreatePageFileMapping ( struct _EPROCESS Process,
PVOID  Address,
SWAPENTRY  SwapEntry 
)

◆ MmCreatePeb()

NTSTATUS NTAPI MmCreatePeb ( IN PEPROCESS  Process,
IN PINITIAL_PEB  InitialPeb,
OUT PPEB BasePeb 
)

Definition at line 517 of file procsup.c.

520{
521 PPEB Peb = NULL;
523 SIZE_T ViewSize = 0;
524 PVOID TableBase = NULL;
525 PIMAGE_NT_HEADERS NtHeaders;
526 PIMAGE_LOAD_CONFIG_DIRECTORY ImageConfigData;
528 USHORT Characteristics;
530 SectionOffset.QuadPart = (ULONGLONG)0;
531 *BasePeb = NULL;
532
533 //
534 // Attach to Process
535 //
537
538 //
539 // Map NLS Tables
540 //
543 &TableBase,
544 0,
545 0,
547 &ViewSize,
548 ViewShare,
551 DPRINT("NLS Tables at: %p\n", TableBase);
552 if (!NT_SUCCESS(Status))
553 {
554 /* Cleanup and exit */
556 return Status;
557 }
558
559 //
560 // Allocate the PEB
561 //
563 DPRINT("PEB at: %p\n", Peb);
564 if (!NT_SUCCESS(Status))
565 {
566 /* Cleanup and exit */
568 return Status;
569 }
570
571 //
572 // Use SEH in case we can't load the PEB
573 //
575 {
576 //
577 // Initialize the PEB
578 //
579 RtlZeroMemory(Peb, sizeof(PEB));
580
581 //
582 // Set up data
583 //
584 Peb->ImageBaseAddress = Process->SectionBaseAddress;
585 Peb->InheritedAddressSpace = InitialPeb->InheritedAddressSpace;
586 Peb->Mutant = InitialPeb->Mutant;
587 Peb->ImageUsesLargePages = InitialPeb->ImageUsesLargePages;
588
589 //
590 // NLS
591 //
595
596 //
597 // Default Version Data (could get changed below)
598 //
601 Peb->OSBuildNumber = (USHORT)(NtBuildNumber & 0x3FFF);
603 Peb->OSCSDVersion = (USHORT)CmNtCSDVersion;
604
605 //
606 // Heap and Debug Data
607 //
609 Peb->BeingDebugged = (BOOLEAN)(Process->DebugPort != NULL);
617 Peb->MaximumNumberOfHeaps = (PAGE_SIZE - sizeof(PEB)) / sizeof(PVOID);
618 Peb->ProcessHeaps = (PVOID*)(Peb + 1);
619
620 //
621 // Session ID
622 //
623 if (Process->Session) Peb->SessionId = MmGetSessionId(Process);
624 }
626 {
627 //
628 // Fail
629 //
632 }
633 _SEH2_END;
634
635 //
636 // Use SEH in case we can't load the image
637 //
639 {
640 //
641 // Get NT Headers
642 //
644 Characteristics = NtHeaders->FileHeader.Characteristics;
645 }
647 {
648 //
649 // Fail
650 //
653 }
654 _SEH2_END;
655
656 //
657 // Parse the headers
658 //
659 if (NtHeaders)
660 {
661 //
662 // Use SEH in case we can't load the headers
663 //
665 {
666 //
667 // Get the Image Config Data too
668 //
670 TRUE,
672 (PULONG)&ViewSize);
673 if (ImageConfigData)
674 {
675 //
676 // Probe it
677 //
678 ProbeForRead(ImageConfigData,
680 sizeof(ULONG));
681 }
682
683 //
684 // Write subsystem data
685 //
689
690 //
691 // Check for version data
692 //
693 if (NtHeaders->OptionalHeader.Win32VersionValue)
694 {
695 //
696 // Extract values and write them
697 //
699 Peb->OSMinorVersion = (NtHeaders->OptionalHeader.Win32VersionValue >> 8) & 0xFF;
700 Peb->OSBuildNumber = (NtHeaders->OptionalHeader.Win32VersionValue >> 16) & 0x3FFF;
701 Peb->OSPlatformId = (NtHeaders->OptionalHeader.Win32VersionValue >> 30) ^ 2;
702
703 /* Process CSD version override */
704 if ((ImageConfigData) && (ImageConfigData->CSDVersion))
705 {
706 /* Take the value from the image configuration directory */
707 Peb->OSCSDVersion = ImageConfigData->CSDVersion;
708 }
709 }
710
711 /* Process optional process affinity mask override */
712 if ((ImageConfigData) && (ImageConfigData->ProcessAffinityMask))
713 {
714 /* Take the value from the image configuration directory */
715 ProcessAffinityMask = ImageConfigData->ProcessAffinityMask;
716 }
717
718 //
719 // Check if this is a UP image
720 if (Characteristics & IMAGE_FILE_UP_SYSTEM_ONLY)
721 {
722 //
723 // Force it to use CPU 0
724 //
725 /* FIXME: this should use the MmRotatingUniprocessorNumber */
727 }
728 else
729 {
730 //
731 // Whatever was configured
732 //
734 }
735 }
737 {
738 //
739 // Fail
740 //
743 }
744 _SEH2_END;
745 }
746
747 //
748 // Detach from the Process
749 //
751 *BasePeb = Peb;
752 return STATUS_SUCCESS;
753}
SIZE_T MmHeapSegmentReserve
Definition: mminit.c:366
SIZE_T MmHeapDeCommitFreeBlockThreshold
Definition: mminit.c:369
SIZE_T MmHeapDeCommitTotalFreeThreshold
Definition: mminit.c:368
SIZE_T MmHeapSegmentCommit
Definition: mminit.c:367
struct _PEB PEB
ULONG_PTR KAFFINITY
Definition: compat.h:85
#define RtlImageDirectoryEntryToData
Definition: compat.h:809
#define IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG
Definition: compat.h:153
PPEB Peb
Definition: dllmain.c:27
VOID NTAPI ProbeForRead(IN CONST VOID *Address, IN SIZE_T Length, IN ULONG Alignment)
Definition: exintrin.c:102
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
@ ProcessAffinityMask
Definition: winternl.h:877
CCHAR KeNumberProcessors
Definition: krnlinit.c:35
SIZE_T MmMinimumStackCommitInBytes
Definition: mminit.c:370
LARGE_INTEGER MmCriticalSectionTimeout
Definition: mminit.c:388
#define PCHAR
Definition: match.c:90
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID _In_ ULONG_PTR _In_ SIZE_T _Inout_opt_ PLARGE_INTEGER SectionOffset
Definition: mmfuncs.h:407
#define VER_PLATFORM_WIN32_NT
Definition: rtltypes.h:238
ULONG ExpOemCodePageDataOffset
Definition: init.c:86
ULONG NtMajorVersion
Definition: init.c:45
ULONG ExpUnicodeCaseTableDataOffset
Definition: init.c:87
ULONG NtGlobalFlag
Definition: init.c:54
PVOID ExpNlsSectionPointer
Definition: init.c:90
ULONG ExpAnsiCodePageDataOffset
Definition: init.c:86
ULONG NtMinorVersion
Definition: init.c:46
ULONG CmNtCSDVersion
Definition: init.c:59
ULONG NTAPI MmGetSessionId(IN PEPROCESS Process)
Definition: session.c:179
NTSTATUS NTAPI MiCreatePebOrTeb(IN PEPROCESS Process, IN ULONG Size, OUT PULONG_PTR BaseAddress)
Definition: procsup.c:28
#define BOOLEAN
Definition: pedump.c:73
#define IMAGE_FILE_UP_SYSTEM_ONLY
Definition: pedump.c:170
VOID NTAPI KeDetachProcess(VOID)
Definition: procobj.c:621
VOID NTAPI KeAttachProcess(IN PKPROCESS Process)
Definition: procobj.c:582
#define _SEH2_YIELD(__stmt)
Definition: pseh2_64.h:162
NTSTATUS NTAPI MmMapViewOfSection(IN PVOID SectionObject, IN PEPROCESS Process, IN OUT PVOID *BaseAddress, IN ULONG_PTR ZeroBits, IN SIZE_T CommitSize, IN OUT PLARGE_INTEGER SectionOffset OPTIONAL, IN OUT PSIZE_T ViewSize, IN SECTION_INHERIT InheritDisposition, IN ULONG AllocationType, IN ULONG Protect)
Definition: section.c:3996
ULONG NtBuildNumber
Definition: init.c:50
ULONG HeapDeCommitTotalFreeThreshold
Definition: ntddk_ex.h:277
ULONG HeapSegmentCommit
Definition: ntddk_ex.h:276
ULONG ImageSubsystem
Definition: ntddk_ex.h:304
ULONG NumberOfProcessors
Definition: ntddk_ex.h:269
ULONG ImageProcessAffinityMask
Definition: ntddk_ex.h:307
PVOID ImageBaseAddress
Definition: ntddk_ex.h:245
ULONG SessionId
Definition: btrfs_drv.h:1919
LARGE_INTEGER CriticalSectionTimeout
Definition: ntddk_ex.h:274
ULONG MaximumNumberOfHeaps
Definition: ntddk_ex.h:287
ULONG OSMinorVersion
Definition: ntddk_ex.h:301
PVOID * ProcessHeaps
Definition: ntddk_ex.h:288
ULONG HeapSegmentReserve
Definition: ntddk_ex.h:275
PVOID AnsiCodePageData
Definition: ntddk_ex.h:264
ULONG ImageSubsystemMinorVersion
Definition: ntddk_ex.h:306
BYTE BeingDebugged
Definition: btrfs_drv.h:1909
SIZE_T MinimumStackCommit
Definition: winternl.h:358
HANDLE Mutant
Definition: ntddk_ex.h:243
ULONG OSMajorVersion
Definition: ntddk_ex.h:300
ULONG OSBuildNumber
Definition: ntddk_ex.h:302
PVOID OemCodePageData
Definition: ntddk_ex.h:265
ULONG NtGlobalFlag
Definition: ntddk_ex.h:270
BOOLEAN InheritedAddressSpace
Definition: ntddk_ex.h:239
ULONG ImageSubsystemMajorVersion
Definition: ntddk_ex.h:305
ULONG OSPlatformId
Definition: ntddk_ex.h:303
ULONG HeapDeCommitFreeBlockThreshold
Definition: ntddk_ex.h:278
PVOID UnicodeCaseTableData
Definition: ntddk_ex.h:266
uint32_t * PULONG_PTR
Definition: typedefs.h:65
uint64_t ULONGLONG
Definition: typedefs.h:67

Referenced by PspCreateProcess().

◆ MmCreatePhysicalMapping()

NTSTATUS NTAPI MmCreatePhysicalMapping ( _Inout_opt_ PEPROCESS  Process,
_In_ PVOID  Address,
_In_ ULONG  flProtect,
_In_ PFN_NUMBER  Page 
)

Definition at line 735 of file page.c.

740{
742}
NTSTATUS NTAPI MmCreateVirtualMappingUnsafeEx(_Inout_opt_ PEPROCESS Process, _In_ PVOID Address, _In_ ULONG flProtect, _In_ PFN_NUMBER Page, _In_ BOOLEAN IsPhysical)
Definition: page.c:629

Referenced by MmNotPresentFaultSectionView().

◆ MmCreatePhysicalMemorySection()

NTSTATUS NTAPI MmCreatePhysicalMemorySection ( VOID  )

Definition at line 2203 of file section.c.

2204{
2205 PSECTION PhysSection;
2208 UNICODE_STRING Name = RTL_CONSTANT_STRING(L"\\Device\\PhysicalMemory");
2209 LARGE_INTEGER SectionSize;
2210 HANDLE Handle;
2212
2213 /*
2214 * Create the section mapping physical memory
2215 */
2218 &Name,
2220 NULL,
2221 NULL);
2222 /*
2223 * Create the Object
2224 */
2227 &Obj,
2229 NULL,
2230 sizeof(*PhysSection),
2231 0,
2232 0,
2233 (PVOID*)&PhysSection);
2234 if (!NT_SUCCESS(Status))
2235 {
2236 DPRINT1("MmCreatePhysicalMemorySection: failed to create object (0x%lx)\n", Status);
2237 return Status;
2238 }
2239
2240 /*
2241 * Initialize it
2242 */
2243 RtlZeroMemory(PhysSection, sizeof(*PhysSection));
2244
2245 /* Mark this as a "ROS Section" */
2246 PhysSection->u.Flags.filler = 1;
2248 PhysSection->u.Flags.PhysicalMemory = 1;
2249 PhysSection->SizeOfSection = SectionSize;
2252 if (Segment == NULL)
2253 {
2254 ObDereferenceObject(PhysSection);
2255 return STATUS_NO_MEMORY;
2256 }
2258 PhysSection->Segment = (PSEGMENT)Segment;
2259 Segment->RefCount = 1;
2260
2261 Segment->ReferenceCount = &Segment->RefCount;
2262 Segment->Flags = &Segment->SegFlags;
2263
2265 Segment->Image.FileOffset = 0;
2266 Segment->Protection = PAGE_EXECUTE_READWRITE;
2267 Segment->RawLength = SectionSize;
2268 Segment->Length = SectionSize;
2270 Segment->WriteCopy = FALSE;
2271 Segment->Image.VirtualAddress = 0;
2272 Segment->Image.Characteristics = 0;
2274
2275 Status = ObInsertObject(PhysSection,
2276 NULL,
2278 0,
2279 NULL,
2280 &Handle);
2281 if (!NT_SUCCESS(Status))
2282 {
2283 ObDereferenceObject(PhysSection);
2284 return Status;
2285 }
2287
2288 return STATUS_SUCCESS;
2289}
#define ExGetPreviousMode
Definition: ex.h:140
ULONG Handle
Definition: gdb_input.c:15
#define OBJ_PERMANENT
Definition: winternl.h:226
PFN_NUMBER MmHighestPhysicalPage
Definition: meminit.c:31
struct _SEGMENT * PSEGMENT
#define OBJ_KERNEL_EXCLUSIVE
Definition: obtypes.h:91
VOID NTAPI MiInitializeSectionPageTable(PMM_SECTION_SEGMENT Segment)
Definition: sptab.c:165
#define SECTION_ALL_ACCESS
Definition: nt_native.h:1293
#define MM_PHYSICALMEMORY_SEGMENT
Definition: mm.h:237
NTSTATUS NTAPI ObCloseHandle(IN HANDLE Handle, IN KPROCESSOR_MODE AccessMode)
Definition: obhandle.c:3379
NTSTATUS NTAPI ObInsertObject(IN PVOID Object, IN PACCESS_STATE AccessState OPTIONAL, IN ACCESS_MASK DesiredAccess, IN ULONG ObjectPointerBias, OUT PVOID *NewObject OPTIONAL, OUT PHANDLE Handle)
Definition: obhandle.c:2935
NTSTATUS NTAPI ObCreateObject(IN KPROCESSOR_MODE ProbeMode OPTIONAL, IN POBJECT_TYPE Type, IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, IN KPROCESSOR_MODE AccessMode, IN OUT PVOID ParseContext OPTIONAL, IN ULONG ObjectSize, IN ULONG PagedPoolCharge OPTIONAL, IN ULONG NonPagedPoolCharge OPTIONAL, OUT PVOID *Object)
Definition: oblife.c:1039
POBJECT_TYPE MmSectionObjectType
Definition: section.c:194
ULONG PhysicalMemory
Definition: mmtypes.h:473
union _SECTION::@2615 u
MMSECTION_FLAGS Flags
Definition: mmtypes.h:817
PSEGMENT Segment
Definition: mmtypes.h:812
ULONG InitialPageProtection
Definition: mmtypes.h:819
LARGE_INTEGER SizeOfSection
Definition: mmtypes.h:813
#define TAG_MM_SECTION_SEGMENT
Definition: tag.h:114
FORCEINLINE VOID ExInitializeFastMutex(_Out_ PFAST_MUTEX FastMutex)
Definition: exfuncs.h:274

Referenced by MmInitSectionImplementation().

◆ MmCreateProcessAddressSpace()

BOOLEAN NTAPI MmCreateProcessAddressSpace ( IN ULONG  MinWs,
IN PEPROCESS  Dest,
IN PULONG_PTR  DirectoryTableBase 
)

Definition at line 136 of file page.c.

139{
141 return FALSE;
142}
#define UNIMPLEMENTED_DBGBREAK(...)
Definition: debug.h:57

Referenced by PspCreateProcess().

◆ MmCreateTeb()

NTSTATUS NTAPI MmCreateTeb ( IN PEPROCESS  Process,
IN PCLIENT_ID  ClientId,
IN PINITIAL_TEB  InitialTeb,
OUT PTEB BaseTeb 
)

Definition at line 757 of file procsup.c.

761{
762 PTEB Teb;
764 *BaseTeb = NULL;
765
766 //
767 // Attach to Target
768 //
770
771 //
772 // Allocate the TEB
773 //
774 Status = MiCreatePebOrTeb(Process, sizeof(TEB), (PULONG_PTR)&Teb);
775 if (!NT_SUCCESS(Status))
776 {
777 /* Cleanup and exit */
779 return Status;
780 }
781
782 //
783 // Use SEH in case we can't load the TEB
784 //
786 {
787 //
788 // Initialize the PEB
789 //
790 RtlZeroMemory(Teb, sizeof(TEB));
791
792 //
793 // Set TIB Data
794 //
795#ifdef _M_AMD64
796 Teb->NtTib.ExceptionList = NULL;
797#else
799#endif
800 Teb->NtTib.Self = (PNT_TIB)Teb;
801
802 //
803 // Identify this as an OS/2 V3.0 ("Cruiser") TIB
804 //
805 Teb->NtTib.Version = 30 << 8;
806
807 //
808 // Set TEB Data
809 //
810 Teb->ClientId = *ClientId;
811 Teb->RealClientId = *ClientId;
814
815 //
816 // Check if we have a grandparent TEB
817 //
818 if ((InitialTeb->PreviousStackBase == NULL) &&
819 (InitialTeb->PreviousStackLimit == NULL))
820 {
821 //
822 // Use initial TEB values
823 //
824 Teb->NtTib.StackBase = InitialTeb->StackBase;
825 Teb->NtTib.StackLimit = InitialTeb->StackLimit;
826 Teb->DeallocationStack = InitialTeb->AllocatedStackBase;
827 }
828 else
829 {
830 //
831 // Use grandparent TEB values
832 //
833 Teb->NtTib.StackBase = InitialTeb->PreviousStackBase;
834 Teb->NtTib.StackLimit = InitialTeb->PreviousStackLimit;
835 }
836
837 //
838 // Initialize the static unicode string
839 //
842 }
844 {
845 //
846 // Get error code
847 //
849 }
850 _SEH2_END;
851
852 //
853 // Return
854 //
856 *BaseTeb = Teb;
857 return Status;
858}
struct _NT_TIB * PNT_TIB
#define EXCEPTION_CHAIN_END
Definition: rtltypes.h:63
LCID PsDefaultThreadLocaleId
Definition: locale.c:24
struct _NT_TIB * Self
Definition: compat.h:720
PVOID StackLimit
Definition: compat.h:713
DWORD Version
Definition: compat.h:717
PVOID StackBase
Definition: compat.h:712
struct _EXCEPTION_REGISTRATION_RECORD * ExceptionList
Definition: compat.h:711
Definition: compat.h:836
WCHAR StaticUnicodeBuffer[261]
Definition: compat.h:877
ULONG CurrentLocale
Definition: compat.h:849
NT_TIB NtTib
Definition: ntddk_ex.h:332
UNICODE_STRING StaticUnicodeString
Definition: compat.h:876
CLIENT_ID ClientId
Definition: compat.h:839
CLIENT_ID RealClientId
Definition: compat.h:861
PPEB ProcessEnvironmentBlock
Definition: ntddk_ex.h:337
PVOID DeallocationStack
Definition: compat.h:878
_Out_ PCLIENT_ID ClientId
Definition: kefuncs.h:1151

Referenced by PspCreateThread().

◆ MmCreateVirtualMapping()

NTSTATUS NTAPI MmCreateVirtualMapping ( struct _EPROCESS Process,
PVOID  Address,
ULONG  flProtect,
PFN_NUMBER  Page 
)

◆ MmCreateVirtualMappingUnsafe()

NTSTATUS NTAPI MmCreateVirtualMappingUnsafe ( struct _EPROCESS Process,
PVOID  Address,
ULONG  flProtect,
PFN_NUMBER  Page 
)

◆ MmDbgCopyMemory()

NTSTATUS NTAPI MmDbgCopyMemory ( IN ULONG64  Address,
IN PVOID  Buffer,
IN ULONG  Size,
IN ULONG  Flags 
)

Definition at line 124 of file mmdbg.c.

128{
131 PMMPTE PointerPte;
132 PVOID CopyDestination, CopySource;
133
134 /* No local kernel debugging support yet, so don't worry about locking */
136
137 /* We only handle 1, 2, 4 and 8 byte requests */
138 if ((Size != 1) &&
139 (Size != 2) &&
140 (Size != 4) &&
141 (Size != 8))
142 {
143 /* Invalid size, fail */
144 KdpDprintf("MmDbgCopyMemory: Received Illegal Size 0x%lx\n",
145 Size);
147 }
148
149 /* The copy must be aligned */
150 if ((Address & (Size - 1)) != 0)
151 {
152 /* Not allowing unaligned access */
153 KdpDprintf("MmDbgCopyMemory: Received Unaligned Address 0x%I64x Size %lx\n",
154 Address,
155 Size);
157 }
158
159 /* Check for physical or virtual copy */
161 {
162 /* Physical: translate and map it to our mapping space */
164 Flags);
165
166 /* Check if translation failed */
167 if (!TargetAddress)
168 {
169 /* Fail */
170 KdpDprintf("MmDbgCopyMemory: Failed to Translate Physical Address %I64x\n",
171 Address);
172 return STATUS_UNSUCCESSFUL;
173 }
174
175 /* The address we received must be valid! */
177 }
178 else
179 {
180 /* Virtual; truncate it to avoid casts later down */
182
183 /* Make sure address is valid */
185 {
186 /* Fail */
187 KdpDprintf("MmDbgCopyMemory: Failing %s for invalid Virtual Address 0x%p\n",
188 Flags & MMDBG_COPY_WRITE ? "write" : "read",
190 return STATUS_UNSUCCESSFUL;
191 }
192
193 /* Not handling session space correctly yet */
195 {
196 /* FIXME */
197 }
198
199 /* If we are going to write to the address, then check if its writable */
200 PointerPte = MiAddressToPte(TargetAddress);
201 if ((Flags & MMDBG_COPY_WRITE) &&
202 (!MI_IS_PAGE_WRITEABLE(PointerPte)))
203 {
204 /* Not writable, we need to do a physical copy */
206
207 /* Calculate the physical address */
210
211 /* Translate the physical address */
213 Flags);
214
215 /* Check if translation failed */
216 if (!TargetAddress)
217 {
218 /* Fail */
219 KdpDprintf("MmDbgCopyMemory: Failed to translate for write %I64x (%I64x)\n",
221 Address);
222 return STATUS_UNSUCCESSFUL;
223 }
224 }
225 }
226
227 /* Check what kind of operation this is */
229 {
230 /* Write */
231 CopyDestination = TargetAddress;
232 CopySource = Buffer;
233 }
234 else
235 {
236 /* Read */
237 CopyDestination = Buffer;
238 CopySource = TargetAddress;
239 }
240
241 /* Do the copy */
242 switch (Size)
243 {
244 case 1:
245
246 /* 1 byte */
247 *(PUCHAR)CopyDestination = *(PUCHAR)CopySource;
248 break;
249
250 case 2:
251
252 /* 2 bytes */
253 *(PUSHORT)CopyDestination = *(PUSHORT)CopySource;
254 break;
255
256 case 4:
257
258 /* 4 bytes */
259 *(PULONG)CopyDestination = *(PULONG)CopySource;
260 break;
261
262 case 8:
263
264 /* 8 bytes */
265 *(PULONGLONG)CopyDestination = *(PULONGLONG)CopySource;
266 break;
267
268 /* Size is sanitized above */
270 }
271
272 /* Get rid of the mapping if this was a physical copy */
274 {
275 /* Unmap and flush it */
277 }
278
279 /* And we are done */
280 return STATUS_SUCCESS;
281}
Definition: bufpool.h:45
VOID NTAPI MiDbgUnTranslatePhysicalAddress(VOID)
Definition: mmdbg.c:103
BOOLEAN NTAPI MmIsSessionAddress(IN PVOID Address)
Definition: session.c:48
#define KdpDprintf(...)
Definition: mmdbg.c:19
PVOID NTAPI MiDbgTranslatePhysicalAddress(IN ULONG64 PhysicalAddress, IN ULONG Flags)
Definition: mmdbg.c:37
BOOLEAN NTAPI MmIsAddressValid(IN PVOID VirtualAddress)
Definition: mmsup.c:174
unsigned __int64 ULONG64
Definition: imports.h:198
#define DEFAULT_UNREACHABLE
__GNU_EXTENSION typedef unsigned __int64 * PULONGLONG
Definition: ntbasedef.h:383
#define MI_IS_PAGE_WRITEABLE(x)
Definition: mm.h:106
#define MMDBG_COPY_PHYSICAL
Definition: mm.h:76
#define MMDBG_COPY_UNSAFE
Definition: mm.h:77
#define MMDBG_COPY_WRITE
Definition: mm.h:75
#define STATUS_INVALID_PARAMETER_3
Definition: ntstatus.h:477
uint16_t * PUSHORT
Definition: typedefs.h:56
unsigned char * PUCHAR
Definition: typedefs.h:53
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4533
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
_Must_inspect_result_ typedef _In_ PHYSICAL_ADDRESS PhysicalAddress
Definition: iotypes.h:1098
#define BYTE_OFFSET(Va)

Referenced by KdpCopyMemoryChunks().

◆ MmDeleteAllRmaps()

VOID NTAPI MmDeleteAllRmaps ( PFN_NUMBER  Page,
PVOID  Context,
VOID(*)(PVOID Context, struct _EPROCESS *Process, PVOID Address DeleteMapping 
)

◆ MmDeleteKernelStack()

◆ MmDeletePageFileMapping()

VOID NTAPI MmDeletePageFileMapping ( struct _EPROCESS Process,
PVOID  Address,
SWAPENTRY SwapEntry 
)

◆ MmDeletePageTable()

VOID NTAPI MmDeletePageTable ( struct _EPROCESS Process,
PVOID  Address 
)

◆ MmDeleteProcessAddressSpace()

VOID NTAPI MmDeleteProcessAddressSpace ( IN PEPROCESS  Process)

Definition at line 1366 of file procsup.c.

1367{
1368 PMMPFN Pfn1, Pfn2;
1369 KIRQL OldIrql;
1370 PFN_NUMBER PageFrameIndex;
1371
1372#ifndef _M_AMD64
1374 RemoveEntryList(&Process->MmProcessLinks);
1376#endif
1377
1378 //ASSERT(Process->CommitCharge == 0);
1379
1380 /* Remove us from the list */
1382 if (Process->Vm.WorkingSetExpansionLinks.Flink != NULL)
1383 RemoveEntryList(&Process->Vm.WorkingSetExpansionLinks);
1385
1386 /* Acquire the PFN lock */
1387 OldIrql = MiAcquirePfnLock();
1388
1389 /* Check for fully initialized process */
1390 if (Process->AddressSpaceInitialized == 2)
1391 {
1392 /* Map the working set page and its page table */
1393 Pfn1 = MiGetPfnEntry(Process->WorkingSetPage);
1394 Pfn2 = MiGetPfnEntry(Pfn1->u4.PteFrame);
1395
1396 /* Nuke it */
1397 MI_SET_PFN_DELETED(Pfn1);
1398 MiDecrementShareCount(Pfn2, Pfn1->u4.PteFrame);
1399 MiDecrementShareCount(Pfn1, Process->WorkingSetPage);
1400 ASSERT((Pfn1->u3.e2.ReferenceCount == 0) || (Pfn1->u3.e1.WriteInProgress));
1401
1402 /* Now map hyperspace and its page table */
1403 PageFrameIndex = Process->Pcb.DirectoryTableBase[1] >> PAGE_SHIFT;
1404 Pfn1 = MiGetPfnEntry(PageFrameIndex);
1405 Pfn2 = MiGetPfnEntry(Pfn1->u4.PteFrame);
1406
1407 /* Nuke it */
1408 MI_SET_PFN_DELETED(Pfn1);
1409 MiDecrementShareCount(Pfn2, Pfn1->u4.PteFrame);
1410 MiDecrementShareCount(Pfn1, PageFrameIndex);
1411 ASSERT((Pfn1->u3.e2.ReferenceCount == 0) || (Pfn1->u3.e1.WriteInProgress));
1412
1413 /* Finally, nuke the PDE itself */
1414 PageFrameIndex = Process->Pcb.DirectoryTableBase[0] >> PAGE_SHIFT;
1415 Pfn1 = MiGetPfnEntry(PageFrameIndex);
1416 MI_SET_PFN_DELETED(Pfn1);
1417 MiDecrementShareCount(Pfn1, PageFrameIndex);
1418 MiDecrementShareCount(Pfn1, PageFrameIndex);
1419
1420 /* Page table is now dead. Bye bye... */
1421 ASSERT((Pfn1->u3.e2.ReferenceCount == 0) || (Pfn1->u3.e1.WriteInProgress));
1422 }
1423 else
1424 {
1425 DPRINT1("Deleting partially initialized address space of Process %p. Might leak resources.\n",
1426 Process);
1427 }
1428
1429 /* Release the PFN lock */
1430 MiReleasePfnLock(OldIrql);
1431
1432 /* Drop a reference on the session */
1434
1435 /* Clear out the PDE pages */
1436 Process->Pcb.DirectoryTableBase[0] = 0;
1437 Process->Pcb.DirectoryTableBase[1] = 0;
1438}
FORCEINLINE KIRQL MiAcquireExpansionLock(VOID)
Definition: miarm.h:1531
VOID NTAPI MiReleaseProcessReferenceToSessionDataPage(IN PMM_SESSION_SPACE SessionGlobal)
Definition: session.c:209
#define MI_SET_PFN_DELETED(x)
Definition: miarm.h:194
FORCEINLINE VOID MiReleaseExpansionLock(KIRQL OldIrql)
Definition: miarm.h:1544
VOID NTAPI MiDecrementShareCount(IN PMMPFN Pfn1, IN PFN_NUMBER PageFrameIndex)
Definition: pfnlist.c:1141
USHORT WriteInProgress
Definition: mm.h:362
ULONG_PTR PteFrame
Definition: mm.h:418

Referenced by PspDeleteProcess().

◆ MmDeleteRmap()

◆ MmDeleteTeb()

VOID NTAPI MmDeleteTeb ( struct _EPROCESS Process,
PTEB  Teb 
)

Referenced by PspCreateThread(), and PspExitThread().

◆ MmDereferencePage()

VOID NTAPI MmDereferencePage ( PFN_NUMBER  Page)

Definition at line 565 of file freelist.c.

566{
567 PMMPFN Pfn1;
568 DPRINT("MmDereferencePage(PhysicalAddress %x)\n", Pfn << PAGE_SHIFT);
569
571
572 Pfn1 = MiGetPfnEntry(Pfn);
573 ASSERT(Pfn1);
574 ASSERT_IS_ROS_PFN(Pfn1);
575
576 ASSERT(Pfn1->u3.e2.ReferenceCount != 0);
577 Pfn1->u3.e2.ReferenceCount--;
578 if (Pfn1->u3.e2.ReferenceCount == 0)
579 {
580 /* Apply LRU hack */
581 if (Pfn1->u4.MustBeCached)
582 {
584 Pfn1->u4.MustBeCached = 0;
585 }
586
587 /* Mark the page temporarily as valid, we're going to make it free soon */
589
590 /* It's not a ROS PFN anymore */
591 Pfn1->u4.AweAllocation = FALSE;
592
593 /* Bring it back into the free list */
594 DPRINT("Legacy free: %lx\n", Pfn);
596 }
597}
#define ASSERT_IS_ROS_PFN(x)
Definition: freelist.c:20
static VOID MmRemoveLRUUserPage(PFN_NUMBER Page)
Definition: freelist.c:87
VOID NTAPI MiInsertPageInFreeList(IN PFN_NUMBER PageFrameIndex)
Definition: pfnlist.c:611
#define MI_ASSERT_PFN_LOCK_HELD()
Definition: mm.h:1043

Referenced by MmReleasePageMemoryConsumer(), and MmTrimUserMemory().

◆ MmDeterminePoolType()

POOL_TYPE NTAPI MmDeterminePoolType ( IN PVOID  VirtualAddress)

Definition at line 408 of file pool.c.

409{
410 //
411 // Use a simple bounds check
412 //
413 if (PoolAddress >= MmPagedPoolStart && PoolAddress <= MmPagedPoolEnd)
414 return PagedPool;
415 else if (PoolAddress >= MmNonPagedPoolStart && PoolAddress <= MmNonPagedPoolEnd)
416 return NonPagedPool;
417 KeBugCheckEx(BAD_POOL_CALLER, 0x42, (ULONG_PTR)PoolAddress, 0, 0);
418}

Referenced by ExFreePoolWithTag(), and ExpCheckPoolAllocation().

◆ MmDumpArmPfnDatabase()

VOID NTAPI MmDumpArmPfnDatabase ( IN BOOLEAN  StatusOnly)

Definition at line 1474 of file mminit.c.

1475{
1476 ULONG i;
1477 PMMPFN Pfn1;
1478 PCHAR Consumer = "Unknown";
1479 KIRQL OldIrql;
1480 ULONG ActivePages = 0, FreePages = 0, OtherPages = 0;
1481#if MI_TRACE_PFNS
1482 ULONG UsageBucket[MI_USAGE_FREE_PAGE + 1] = {0};
1483 PCHAR MI_USAGE_TEXT[MI_USAGE_FREE_PAGE + 1] =
1484 {
1485 "Not set",
1486 "Paged Pool",
1487 "Nonpaged Pool",
1488 "Nonpaged Pool Ex",
1489 "Kernel Stack",
1490 "Kernel Stack Ex",
1491 "System PTE",
1492 "VAD",
1493 "PEB/TEB",
1494 "Section",
1495 "Page Table",
1496 "Page Directory",
1497 "Old Page Table",
1498 "Driver Page",
1499 "Contiguous Alloc",
1500 "MDL",
1501 "Demand Zero",
1502 "Zero Loop",
1503 "Cache",
1504 "PFN Database",
1505 "Boot Driver",
1506 "Initial Memory",
1507 "Free Page"
1508 };
1509#endif
1510 //
1511 // Loop the PFN database
1512 //
1514 for (i = 0; i <= MmHighestPhysicalPage; i++)
1515 {
1516 Pfn1 = MiGetPfnEntry(i);
1517 if (!Pfn1) continue;
1518#if MI_TRACE_PFNS
1519 ASSERT(Pfn1->PfnUsage <= MI_USAGE_FREE_PAGE);
1520#endif
1521 //
1522 // Get the page location
1523 //
1524 switch (Pfn1->u3.e1.PageLocation)
1525 {
1526 case ActiveAndValid:
1527
1528 Consumer = "Active and Valid";
1529 ActivePages++;
1530 break;
1531
1532 case ZeroedPageList:
1533
1534 Consumer = "Zero Page List";
1535 FreePages++;
1536 break;//continue;
1537
1538 case FreePageList:
1539
1540 Consumer = "Free Page List";
1541 FreePages++;
1542 break;//continue;
1543
1544 default:
1545
1546 Consumer = "Other (ASSERT!)";
1547 OtherPages++;
1548 break;
1549 }
1550
1551#if MI_TRACE_PFNS
1552 /* Add into bucket */
1553 UsageBucket[Pfn1->PfnUsage]++;
1554#endif
1555
1556 //
1557 // Pretty-print the page
1558 //
1559 if (!StatusOnly)
1560 DbgPrint("0x%08p:\t%20s\t(%04d.%04d)\t[%16s - %16s]\n",
1561 i << PAGE_SHIFT,
1562 Consumer,
1563 Pfn1->u3.e2.ReferenceCount,
1564 Pfn1->u2.ShareCount == LIST_HEAD ? 0xFFFF : Pfn1->u2.ShareCount,
1565#if MI_TRACE_PFNS
1566 MI_USAGE_TEXT[Pfn1->PfnUsage],
1567 Pfn1->ProcessName);
1568#else
1569 "Page tracking",
1570 "is disabled");
1571#endif
1572 }
1573
1574 DbgPrint("Active: %5d pages\t[%6d KB]\n", ActivePages, (ActivePages << PAGE_SHIFT) / 1024);
1575 DbgPrint("Free: %5d pages\t[%6d KB]\n", FreePages, (FreePages << PAGE_SHIFT) / 1024);
1576 DbgPrint("Other: %5d pages\t[%6d KB]\n", OtherPages, (OtherPages << PAGE_SHIFT) / 1024);
1577 DbgPrint("-----------------------------------------\n");
1578#if MI_TRACE_PFNS
1579 OtherPages = UsageBucket[MI_USAGE_BOOT_DRIVER];
1580 DbgPrint("Boot Images: %5d pages\t[%6d KB]\n", OtherPages, (OtherPages << PAGE_SHIFT) / 1024);
1581 OtherPages = UsageBucket[MI_USAGE_DRIVER_PAGE];
1582 DbgPrint("System Drivers: %5d pages\t[%6d KB]\n", OtherPages, (OtherPages << PAGE_SHIFT) / 1024);
1583 OtherPages = UsageBucket[MI_USAGE_PFN_DATABASE];
1584 DbgPrint("PFN Database: %5d pages\t[%6d KB]\n", OtherPages, (OtherPages << PAGE_SHIFT) / 1024);
1585 OtherPages = UsageBucket[MI_USAGE_PAGE_TABLE] + UsageBucket[MI_USAGE_PAGE_DIRECTORY] + UsageBucket[MI_USAGE_LEGACY_PAGE_DIRECTORY];
1586 DbgPrint("Page Tables: %5d pages\t[%6d KB]\n", OtherPages, (OtherPages << PAGE_SHIFT) / 1024);
1587 OtherPages = UsageBucket[MI_USAGE_SYSTEM_PTE];
1588 DbgPrint("System PTEs: %5d pages\t[%6d KB]\n", OtherPages, (OtherPages << PAGE_SHIFT) / 1024);
1589 OtherPages = UsageBucket[MI_USAGE_VAD];
1590 DbgPrint("VADs: %5d pages\t[%6d KB]\n", OtherPages, (OtherPages << PAGE_SHIFT) / 1024);
1591 OtherPages = UsageBucket[MI_USAGE_CONTINOUS_ALLOCATION];
1592 DbgPrint("Continuous Allocs: %5d pages\t[%6d KB]\n", OtherPages, (OtherPages << PAGE_SHIFT) / 1024);
1593 OtherPages = UsageBucket[MI_USAGE_MDL];
1594 DbgPrint("MDLs: %5d pages\t[%6d KB]\n", OtherPages, (OtherPages << PAGE_SHIFT) / 1024);
1595 OtherPages = UsageBucket[MI_USAGE_NONPAGED_POOL] + UsageBucket[MI_USAGE_NONPAGED_POOL_EXPANSION];
1596 DbgPrint("NonPaged Pool: %5d pages\t[%6d KB]\n", OtherPages, (OtherPages << PAGE_SHIFT) / 1024);
1597 OtherPages = UsageBucket[MI_USAGE_PAGED_POOL];
1598 DbgPrint("Paged Pool: %5d pages\t[%6d KB]\n", OtherPages, (OtherPages << PAGE_SHIFT) / 1024);
1599 OtherPages = UsageBucket[MI_USAGE_DEMAND_ZERO];
1600 DbgPrint("Demand Zero: %5d pages\t[%6d KB]\n", OtherPages, (OtherPages << PAGE_SHIFT) / 1024);
1601 OtherPages = UsageBucket[MI_USAGE_ZERO_LOOP];
1602 DbgPrint("Zero Loop: %5d pages\t[%6d KB]\n", OtherPages, (OtherPages << PAGE_SHIFT) / 1024);
1603 OtherPages = UsageBucket[MI_USAGE_PEB_TEB];
1604 DbgPrint("PEB/TEB: %5d pages\t[%6d KB]\n", OtherPages, (OtherPages << PAGE_SHIFT) / 1024);
1605 OtherPages = UsageBucket[MI_USAGE_KERNEL_STACK] + UsageBucket[MI_USAGE_KERNEL_STACK_EXPANSION];
1606 DbgPrint("Kernel Stack: %5d pages\t[%6d KB]\n", OtherPages, (OtherPages << PAGE_SHIFT) / 1024);
1607 OtherPages = UsageBucket[MI_USAGE_INIT_MEMORY];
1608 DbgPrint("Init Memory: %5d pages\t[%6d KB]\n", OtherPages, (OtherPages << PAGE_SHIFT) / 1024);
1609 OtherPages = UsageBucket[MI_USAGE_SECTION];
1610 DbgPrint("Sections: %5d pages\t[%6d KB]\n", OtherPages, (OtherPages << PAGE_SHIFT) / 1024);
1611 OtherPages = UsageBucket[MI_USAGE_CACHE];
1612 DbgPrint("Cache: %5d pages\t[%6d KB]\n", OtherPages, (OtherPages << PAGE_SHIFT) / 1024);
1613 OtherPages = UsageBucket[MI_USAGE_FREE_PAGE];
1614 DbgPrint("Free: %5d pages\t[%6d KB]\n", OtherPages, (OtherPages << PAGE_SHIFT) / 1024);
1615#endif
1617}
PFN_NUMBER MmHighestPhysicalPage
Definition: mminit.c:211
#define KeRaiseIrql(irql, oldIrql)
Definition: env_spec_w32.h:597
#define HIGH_LEVEL
Definition: env_spec_w32.h:703
#define KeLowerIrql(oldIrql)
Definition: env_spec_w32.h:602
#define DbgPrint
Definition: hal.h:12
@ ZeroedPageList
Definition: mmtypes.h:153
@ FreePageList
Definition: mmtypes.h:154
char * PCHAR
Definition: typedefs.h:51

Referenced by KdSystemDebugControl().

◆ MmExtendSection()

NTSTATUS NTAPI MmExtendSection ( _In_ PVOID  Section,
_Inout_ PLARGE_INTEGER  NewSize 
)

Definition at line 5273 of file section.c.

5276{
5277 PSECTION Section = _Section;
5278
5279 /* It makes no sense to extend an image mapping */
5280 if (Section->u.Flags.Image)
5282
5283 /* Nor is it possible to extend a page file mapping */
5284 if (!Section->u.Flags.File)
5286
5287 if (!MiIsRosSectionObject(Section))
5289
5290 /* We just extend the sizes. Shrinking is a no-op ? */
5291 if (NewSize->QuadPart > Section->SizeOfSection.QuadPart)
5292 {
5294 Section->SizeOfSection = *NewSize;
5295
5296 if (!Section->u.Flags.Reserve)
5297 {
5299 if (Segment->RawLength.QuadPart < NewSize->QuadPart)
5300 {
5301 Segment->RawLength = *NewSize;
5302 Segment->Length.QuadPart = (NewSize->QuadPart + PAGE_SIZE - 1) & ~((LONGLONG)PAGE_SIZE);
5303 }
5305 }
5306 }
5307
5308 return STATUS_SUCCESS;
5309}
_Must_inspect_result_ _In_ USHORT NewSize
Definition: fltkernel.h:975
FORCEINLINE BOOLEAN MiIsRosSectionObject(IN PSECTION Section)
Definition: miarm.h:1098
struct _MM_SECTION_SEGMENT * PMM_SECTION_SEGMENT
#define STATUS_SECTION_NOT_EXTENDED
Definition: ntstatus.h:371
int64_t LONGLONG
Definition: typedefs.h:68

Referenced by CcSetFileSizes(), and NtExtendSection().

◆ MmFindGap()

PVOID NTAPI MmFindGap ( PMMSUPPORT  AddressSpace,
SIZE_T  Length,
ULONG_PTR  Granularity,
BOOLEAN  TopDown 
)

Definition at line 215 of file marea.c.

220{
222 PMM_AVL_TABLE VadRoot;
225 ULONG_PTR StartingAddress, HighestAddress;
226
228 VadRoot = Process ? &Process->VadRoot : &MiRosKernelVadRoot;
229 if (TopDown)
230 {
231 /* Find an address top-down */
232 HighestAddress = Process ? (ULONG_PTR)MM_HIGHEST_VAD_ADDRESS : (LONG_PTR)-1;
234 HighestAddress,
235 Granularity,
236 VadRoot,
237 &StartingAddress,
238 &Parent);
239 }
240 else
241 {
243 Granularity,
244 VadRoot,
245 &Parent,
246 &StartingAddress);
247 }
248
249 if (Result == TableFoundNode)
250 {
251 return NULL;
252 }
253
254 return (PVOID)StartingAddress;
255}
ACPI_PHYSICAL_ADDRESS ACPI_SIZE BOOLEAN Warn UINT32 *TableIdx UINT32 ACPI_TABLE_HEADER *OutTableHeader ACPI_TABLE_HEADER **OutTable ACPI_HANDLE UINT32 ACPI_WALK_CALLBACK ACPI_WALK_CALLBACK void void **ReturnValue UINT32 ACPI_BUFFER *RetPathPtr ACPI_OBJECT_HANDLER void *Data ACPI_OBJECT_HANDLER void **Data ACPI_STRING ACPI_OBJECT_LIST ACPI_BUFFER *ReturnObjectBuffer ACPI_DEVICE_INFO **ReturnBuffer ACPI_HANDLE Parent
Definition: acpixf.h:732
MM_AVL_TABLE MiRosKernelVadRoot
Definition: marea.c:54
TABLE_SEARCH_RESULT NTAPI MiFindEmptyAddressRangeDownTree(IN SIZE_T Length, IN ULONG_PTR BoundaryAddress, IN ULONG_PTR Alignment, IN PMM_AVL_TABLE Table, OUT PULONG_PTR Base, OUT PMMADDRESS_NODE *Parent)
Definition: vadnode.c:681
TABLE_SEARCH_RESULT NTAPI MiFindEmptyAddressRangeInTree(IN SIZE_T Length, IN ULONG_PTR Alignment, IN PMM_AVL_TABLE Table, OUT PMMADDRESS_NODE *PreviousVad, OUT PULONG_PTR Base)
Definition: vadnode.c:584
__int3264 LONG_PTR
Definition: mstsclib_h.h:276
#define MM_HIGHEST_VAD_ADDRESS
Definition: mm.h:46
TABLE_SEARCH_RESULT
Definition: rtltypes.h:373

Referenced by MmCreateMemoryArea(), and MmMapViewOfSection().

◆ MmFindRegion()

PMM_REGION NTAPI MmFindRegion ( PVOID  BaseAddress,
PLIST_ENTRY  RegionListHead,
PVOID  Address,
PVOID RegionBaseAddress 
)

Definition at line 257 of file region.c.

259{
260 PLIST_ENTRY current_entry;
262 PVOID StartAddress = BaseAddress;
263
264 current_entry = RegionListHead->Flink;
265 while (current_entry != RegionListHead)
266 {
267 current = CONTAINING_RECORD(current_entry, MM_REGION, RegionListEntry);
268
269 if (StartAddress <= Address &&
270 ((char*)StartAddress + current->Length) > (char*)Address)
271 {
272 if (RegionBaseAddress != NULL)
273 {
274 *RegionBaseAddress = StartAddress;
275 }
276 return(current);
277 }
278
279 current_entry = current_entry->Flink;
280
281 StartAddress = (PVOID)((ULONG_PTR)StartAddress + current->Length);
282
283 }
284 return(NULL);
285}
struct task_struct * current
Definition: linux.c:32

Referenced by MmAccessFaultSectionView(), MmAlterRegion(), MmNotPresentFaultSectionView(), MmPageOutPhysicalAddress(), MmProtectSectionView(), and MmQuerySectionView().

◆ MmFlushSegment()

NTSTATUS NTAPI MmFlushSegment ( _In_ PSECTION_OBJECT_POINTERS  SectionObjectPointer,
_In_opt_ PLARGE_INTEGER  Offset,
_In_ ULONG  Length,
_Out_opt_ PIO_STATUS_BLOCK  Iosb 
)

Definition at line 4940 of file section.c.

4945{
4946 LARGE_INTEGER FlushStart, FlushEnd;
4948
4949 if (Offset)
4950 {
4951 FlushStart = *Offset;
4952 Status = RtlLongLongAdd(FlushStart.QuadPart, Length, &FlushEnd.QuadPart);
4953 if (!NT_SUCCESS(Status))
4954 return Status;
4955 }
4956
4957 if (Iosb)
4958 Iosb->Information = 0;
4959
4961 if (!Segment)
4962 {
4963 /* Nothing to flush */
4964 if (Iosb)
4965 Iosb->Status = STATUS_SUCCESS;
4966 return STATUS_SUCCESS;
4967 }
4968
4970
4972
4973 if (!Offset)
4974 {
4975 FlushStart.QuadPart = 0;
4976
4977 /* FIXME: All of this is suboptimal */
4978 ULONG ElemCount = RtlNumberGenericTableElements(&Segment->PageTable);
4979 /* No page. Nothing to flush */
4980 if (!ElemCount)
4981 {
4983 MmDereferenceSegment(Segment);
4984 if (Iosb)
4985 {
4986 Iosb->Status = STATUS_SUCCESS;
4987 Iosb->Information = 0;
4988 }
4989 return STATUS_SUCCESS;
4990 }
4991
4993 FlushEnd.QuadPart = PageTable->FileOffset.QuadPart + _countof(PageTable->PageEntries) * PAGE_SIZE;
4994 }
4995
4996 FlushStart.QuadPart >>= PAGE_SHIFT;
4997 FlushStart.QuadPart <<= PAGE_SHIFT;
4998
4999 while (FlushStart.QuadPart < FlushEnd.QuadPart)
5000 {
5002
5003 if (IS_DIRTY_SSE(Entry))
5004 {
5005 MmCheckDirtySegment(Segment, &FlushStart, FALSE, FALSE);
5006
5007 if (Iosb)
5008 Iosb->Information += PAGE_SIZE;
5009 }
5010
5011 FlushStart.QuadPart += PAGE_SIZE;
5012 }
5013
5015 MmDereferenceSegment(Segment);
5016
5017 if (Iosb)
5018 Iosb->Status = STATUS_SUCCESS;
5019
5020 return STATUS_SUCCESS;
5021}
_Must_inspect_result_ _In_ PDEVICE_OBJECT _In_ PSECTION_OBJECT_POINTERS SectionObjectPointer
Definition: fsrtlfuncs.h:1369
BOOLEAN NTAPI MmCheckDirtySegment(PMM_SECTION_SEGMENT Segment, PLARGE_INTEGER Offset, BOOLEAN ForceDirty, BOOLEAN PageOut)
#define MM_DATAFILE_SEGMENT
Definition: mm.h:238
static PMM_SECTION_SEGMENT MiGrabDataSection(PSECTION_OBJECT_POINTERS SectionObjectPointer)
Definition: section.c:90
#define _countof(array)
Definition: sndvol32.h:68
_Must_inspect_result_ NTSYSAPI PVOID NTAPI RtlGetElementGenericTable(_In_ PRTL_GENERIC_TABLE Table, _In_ ULONG I)
NTSYSAPI ULONG NTAPI RtlNumberGenericTableElements(_In_ PRTL_GENERIC_TABLE Table)

Referenced by CcFlushCache(), CcRosDeleteFileCache(), CcRosFlushVacb(), and MiRosUnmapViewOfSection().

◆ MmFreeDriverInitialization()

VOID NTAPI MmFreeDriverInitialization ( IN PLDR_DATA_TABLE_ENTRY  LdrEntry)

Definition at line 1672 of file sysldr.c.

1673{
1674 PMMPTE StartPte, EndPte;
1675 PFN_NUMBER PageCount;
1676 PVOID DllBase;
1677 ULONG i;
1678 PIMAGE_NT_HEADERS NtHeader;
1679 PIMAGE_SECTION_HEADER Section, DiscardSection;
1680
1681 /* Get the base address and the page count */
1682 DllBase = LdrEntry->DllBase;
1683 PageCount = LdrEntry->SizeOfImage >> PAGE_SHIFT;
1684
1685 /* Get the last PTE in this image */
1686 EndPte = MiAddressToPte(DllBase) + PageCount;
1687
1688 /* Get the NT header */
1689 NtHeader = RtlImageNtHeader(DllBase);
1690 if (!NtHeader) return;
1691
1692 /* Get the last section and loop each section backwards */
1693 Section = IMAGE_FIRST_SECTION(NtHeader) + NtHeader->FileHeader.NumberOfSections;
1694 DiscardSection = NULL;
1695 for (i = 0; i < NtHeader->FileHeader.NumberOfSections; i++)
1696 {
1697 /* Go back a section and check if it's discardable */
1698 Section--;
1700 {
1701 /* It is, select it for freeing */
1702 DiscardSection = Section;
1703 }
1704 else
1705 {
1706 /* No more discardable sections exist, bail out */
1707 break;
1708 }
1709 }
1710
1711 /* Bail out if there's nothing to free */
1712 if (!DiscardSection) return;
1713
1714 /* Push the DLL base to the first disacrable section, and get its PTE */
1715 DllBase = (PVOID)ROUND_TO_PAGES((ULONG_PTR)DllBase + DiscardSection->VirtualAddress);
1716 ASSERT(MI_IS_PHYSICAL_ADDRESS(DllBase) == FALSE);
1717 StartPte = MiAddressToPte(DllBase);
1718
1719 /* Check how many pages to free total */
1720 PageCount = (PFN_NUMBER)(EndPte - StartPte);
1721 if (!PageCount) return;
1722
1723 /* Delete this many PTEs */
1724 MiDeleteSystemPageableVm(StartPte, PageCount, 0, NULL);
1725}
#define IMAGE_FIRST_SECTION(NtHeader)
Definition: ntimage.h:427
#define IMAGE_SCN_MEM_DISCARDABLE
Definition: ntimage.h:235

Referenced by IopInitializeDriverModule().

◆ MmFreeMemoryArea()

NTSTATUS NTAPI MmFreeMemoryArea ( PMMSUPPORT  AddressSpace,
PMEMORY_AREA  MemoryArea,
PMM_FREE_PAGE_FUNC  FreePage,
PVOID  FreePageContext 
)

Definition at line 283 of file marea.c.

288{
290 PVOID EndAddress;
291
292 /* Make sure we own the address space lock! */
293 ASSERT(CONTAINING_RECORD(AddressSpace, EPROCESS, Vm)->AddressCreationLock.Owner == KeGetCurrentThread());
294
295 /* Check magic */
296 ASSERT(MemoryArea->Magic == 'erAM');
297
299 {
300 PEPROCESS CurrentProcess = PsGetCurrentProcess();
302
303 if ((Process != NULL) && (Process != CurrentProcess))
304 {
306 }
307
310 Address < (ULONG_PTR)EndAddress;
312 {
313 BOOLEAN Dirty = FALSE;
314 SWAPENTRY SwapEntry = 0;
315 PFN_NUMBER Page = 0;
316 BOOLEAN DoFree;
317
319 {
321 /* We'll have to do some cleanup when we're on the page file */
322 DoFree = TRUE;
323 }
324 else if (FreePage == NULL)
325 {
326 DoFree = MmDeletePhysicalMapping(Process, (PVOID)Address, &Dirty, &Page);
327 }
328 else
329 {
330 DoFree = MmDeleteVirtualMapping(Process, (PVOID)Address, &Dirty, &Page);
331 }
332 if (DoFree && (FreePage != NULL))
333 {
334 FreePage(FreePageContext, MemoryArea, (PVOID)Address,
335 Page, SwapEntry, (BOOLEAN)Dirty);
336 }
337 }
338
339 //if (MemoryArea->VadNode.StartingVpn < (ULONG_PTR)MmSystemRangeStart >> PAGE_SHIFT
340 if (MemoryArea->Vad)
341 {
343#ifdef NEWCC
344 ASSERT(MemoryArea->Type == MEMORY_AREA_SECTION_VIEW || MemoryArea->Type == MEMORY_AREA_CACHE);
345#else
347#endif
348
349 /* MmCleanProcessAddressSpace might have removed it (and this would be MmDeleteProcessAddressSpace) */
351 if (((PMMVAD)MemoryArea->Vad)->u.VadFlags.Spare == 1)
352 {
356 }
357
359 }
360 else
361 {
365 }
366
367 if ((Process != NULL) && (Process != CurrentProcess))
368 {
370 }
371 }
372
373#if DBG
374 MemoryArea->Magic = 'daeD';
375#endif
377
378 DPRINT("MmFreeMemoryArea() succeeded\n");
379
380 return STATUS_SUCCESS;
381}
#define KeGetCurrentThread
Definition: hal.h:55
VOID NTAPI MiRemoveNode(IN PMMADDRESS_NODE Node, IN PMM_AVL_TABLE Table)
Definition: vadnode.c:440
FORCEINLINE VOID MiUnlockProcessWorkingSet(IN PEPROCESS Process, IN PETHREAD Thread)
Definition: miarm.h:1194
FORCEINLINE VOID MiLockProcessWorkingSet(IN PEPROCESS Process, IN PETHREAD Thread)
Definition: miarm.h:1124
BOOLEAN NTAPI MmIsPageSwapEntry(struct _EPROCESS *Process, PVOID Address)
#define MA_GetEndingAddress(_MemoryArea)
Definition: mm.h:245
VOID NTAPI MmDeletePageFileMapping(struct _EPROCESS *Process, PVOID Address, SWAPENTRY *SwapEntry)
PVOID Vad
Definition: mm.h:255
@ FreePage
Definition: ketypes.h:416

Referenced by MiRemoveNode(), and MmUnmapViewOfSegment().

◆ MmFreeSectionSegments()

VOID NTAPI MmFreeSectionSegments ( PFILE_OBJECT  FileObject)

◆ MmFreeSpecialPool()

VOID NTAPI MmFreeSpecialPool ( IN PVOID  P)

Referenced by ExFreePoolWithTag().

◆ MmFreeSwapPage()

VOID NTAPI MmFreeSwapPage ( SWAPENTRY  Entry)

Definition at line 291 of file pagefile.c.

292{
293 ULONG i;
294 ULONG_PTR off;
295 PMMPAGING_FILE PagingFile;
296
298 off = OFFSET_FROM_ENTRY(Entry) - 1;
299
301
302 PagingFile = MmPagingFile[i];
303 if (PagingFile == NULL)
304 {
305 KeBugCheck(MEMORY_MANAGEMENT);
306 }
307
308 RtlClearBit(PagingFile->Bitmap, off >> 5);
309
310 PagingFile->FreeSpace++;
311 PagingFile->CurrentUsage--;
312
316
318}
#define FILE_FROM_ENTRY(i)
Definition: pagefile.c:96
#define OFFSET_FROM_ENTRY(i)
Definition: pagefile.c:97
PRTL_BITMAP Bitmap
Definition: mm.h:508
PFN_NUMBER CurrentUsage
Definition: mm.h:505
PFN_NUMBER FreeSpace
Definition: mm.h:504

Referenced by MiFreeSegmentPage(), MmFreeCacheSectionPage(), MmFreeSectionPage(), MmPageOutPhysicalAddress(), MmpFreePageFileSegment(), and MmUnsharePageEntrySectionSegment().

◆ MmGetAddressSpaceOwner()

◆ MmGetCurrentAddressSpace()

FORCEINLINE PMMSUPPORT MmGetCurrentAddressSpace ( VOID  )

Definition at line 1719 of file mm.h.

1720{
1721 return &((PEPROCESS)KeGetCurrentThread()->ApcState.Process)->Vm;
1722}
struct _EPROCESS * PEPROCESS
Definition: nt_native.h:30

Referenced by MiLockVirtualMemory(), MiProtectVirtualMemory(), MiUnlockVirtualMemory(), MmAccessFault(), MmGetFileNameForAddress(), NtAllocateVirtualMemory(), NtAreMappedFilesTheSame(), and NtFreeVirtualMemory().

◆ MmGetExecuteOptions()

NTSTATUS NTAPI MmGetExecuteOptions ( IN PULONG  ExecuteOptions)

Definition at line 2653 of file pagfault.c.

2654{
2655 PKPROCESS CurrentProcess = &PsGetCurrentProcess()->Pcb;
2657
2658 *ExecuteOptions = 0;
2659
2660 if (CurrentProcess->Flags.ExecuteDisable)
2661 {
2662 *ExecuteOptions |= MEM_EXECUTE_OPTION_DISABLE;
2663 }
2664
2665 if (CurrentProcess->Flags.ExecuteEnable)
2666 {
2667 *ExecuteOptions |= MEM_EXECUTE_OPTION_ENABLE;
2668 }
2669
2670 if (CurrentProcess->Flags.DisableThunkEmulation)
2671 {
2673 }
2674
2675 if (CurrentProcess->Flags.Permanent)
2676 {
2677 *ExecuteOptions |= MEM_EXECUTE_OPTION_PERMANENT;
2678 }
2679
2680 if (CurrentProcess->Flags.ExecuteDispatchEnable)
2681 {
2683 }
2684
2685 if (CurrentProcess->Flags.ImageDispatchEnable)
2686 {
2688 }
2689
2690 return STATUS_SUCCESS;
2691}
#define MEM_EXECUTE_OPTION_DISABLE
Definition: mmtypes.h:73
#define MEM_EXECUTE_OPTION_PERMANENT
Definition: mmtypes.h:76
#define MEM_EXECUTE_OPTION_EXECUTE_DISPATCH_ENABLE
Definition: mmtypes.h:77
#define MEM_EXECUTE_OPTION_IMAGE_DISPATCH_ENABLE
Definition: mmtypes.h:78
#define MEM_EXECUTE_OPTION_DISABLE_THUNK_EMULATION
Definition: mmtypes.h:75
#define MEM_EXECUTE_OPTION_ENABLE
Definition: mmtypes.h:74
UCHAR DisableThunkEmulation
Definition: ketypes.h:989
UCHAR ExecuteDisable
Definition: ketypes.h:987
UCHAR ExecuteEnable
Definition: ketypes.h:988
UCHAR ExecuteDispatchEnable
Definition: ketypes.h:991
UCHAR ImageDispatchEnable
Definition: ketypes.h:992
KEXECUTE_OPTIONS Flags
Definition: ketypes.h:2130

Referenced by NtQueryInformationProcess().

◆ MmGetFileNameForAddress()

NTSTATUS NTAPI MmGetFileNameForAddress ( IN PVOID  Address,
OUT PUNICODE_STRING  ModuleName 
)

Definition at line 1885 of file section.c.

1887{
1888 POBJECT_NAME_INFORMATION ModuleNameInformation;
1891 PMMVAD Vad;
1893
1894 /* Lock address space */
1897
1898 /* Get the VAD */
1899 Vad = MiLocateAddress(Address);
1900 if (Vad == NULL)
1901 {
1902 /* Fail, the address does not exist */
1903 DPRINT1("No VAD at address %p\n", Address);
1906 }
1907
1908 /* Get the file object pointer for the VAD */
1910 if (FileObject == NULL)
1911 {
1912 DPRINT1("Failed to get file object for Address %p\n", Address);
1915 }
1916
1917 /* Reference the file object */
1919
1920 /* Unlock address space */
1922
1923 /* Get the filename of the file object */
1924 Status = MmGetFileNameForFileObject(FileObject, &ModuleNameInformation);
1925
1926 /* Dereference the file object */
1928
1929 /* Check if we were able to get the file object name */
1930 if (NT_SUCCESS(Status))
1931 {
1932 /* Init modulename */
1933 if (!RtlCreateUnicodeString(ModuleName, ModuleNameInformation->Name.Buffer))
1935
1936 /* Free temp taged buffer from MmGetFileNameForFileObject() */
1937 ExFreePoolWithTag(ModuleNameInformation, TAG_MM);
1938
1939 DPRINT("Found ModuleName %wZ by address %p\n", ModuleName, Address);
1940 }
1941
1942 /* Return status */
1943 return Status;
1944}
static PFILE_OBJECT MiGetFileObjectForVad(_In_ PMMVAD Vad)
Definition: section.c:1756
NTSTATUS NTAPI MmGetFileNameForFileObject(IN PFILE_OBJECT FileObject, OUT POBJECT_NAME_INFORMATION *ModuleName)
Definition: section.c:1832
ACPI_BUFFER *RetBuffer ACPI_BUFFER *RetBuffer char ACPI_WALK_RESOURCE_CALLBACK void *Context ACPI_BUFFER *RetBuffer UINT16 ACPI_RESOURCE **ResourcePtr ACPI_GENERIC_ADDRESS *Reg UINT32 *ReturnValue UINT8 UINT8 *Slp_TypB ACPI_PHYSICAL_ADDRESS PhysicalAddress64 UINT32 UINT32 *TimeElapsed UINT32 ACPI_STATUS const char UINT32 ACPI_STATUS const char UINT32 const char const char * ModuleName
Definition: acpixf.h:1280
NTSYSAPI BOOLEAN NTAPI RtlCreateUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
PMMVAD NTAPI MiLocateAddress(IN PVOID VirtualAddress)
Definition: vadnode.c:116
#define STATUS_INVALID_ADDRESS
Definition: ntstatus.h:557
#define STATUS_SECTION_NOT_IMAGE
Definition: ntstatus.h:309
UNICODE_STRING Name
Definition: nt_native.h:1270
#define TAG_MM
Definition: tag.h:113
* PFILE_OBJECT
Definition: iotypes.h:1998
#define ObReferenceObject
Definition: obfuncs.h:204

Referenced by DbgkpPostFakeModuleMessages(), and MiQueryMemorySectionName().

◆ MmGetFileNameForSection()

NTSTATUS NTAPI MmGetFileNameForSection ( IN PVOID  Section,
OUT POBJECT_NAME_INFORMATION ModuleName 
)

Definition at line 1864 of file section.c.

1866{
1868 PSECTION SectionObject = Section;
1869
1870 /* Make sure it's an image section */
1871 if (SectionObject->u.Flags.Image == 0)
1872 {
1873 /* It's not, fail */
1874 DPRINT1("Not an image section\n");
1876 }
1877
1878 /* Get the file object */
1881}
PFILE_OBJECT NTAPI MmGetFileObjectForSection(IN PVOID SectionObject)
Definition: section.c:1737
_Must_inspect_result_ _Outptr_ PVOID * SectionObject
Definition: fsrtlfuncs.h:860

Referenced by DbgkCreateThread(), and DbgkpSectionToFileHandle().

◆ MmGetFileObjectForSection()

PFILE_OBJECT NTAPI MmGetFileObjectForSection ( IN PVOID  Section)

Definition at line 1737 of file section.c.

1738{
1739 PSECTION Section = SectionObject;
1742
1743 /* Check if it's an ARM3, or ReactOS section */
1745 {
1746 /* Return the file pointer stored in the control area */
1747 return Section->Segment->ControlArea->FilePointer;
1748 }
1749
1750 /* Return the file object */
1751 return ((PMM_SECTION_SEGMENT)Section->Segment)->FileObject;
1752}
struct _CONTROL_AREA * ControlArea
Definition: mmtypes.h:409

Referenced by CcGetFileObjectFromBcb(), CcGetFileObjectFromSectionPtrs(), CcShutdownSystem(), MmGetFileNameForSection(), MmInitializeProcessAddressSpace(), and PsReferenceProcessFilePointer().

◆ MmGetImageInformation()

VOID NTAPI MmGetImageInformation ( OUT PSECTION_IMAGE_INFORMATION  ImageInformation)

Definition at line 1811 of file section.c.

1812{
1814
1815 /* Get the section object of this process*/
1816 SectionObject = PsGetCurrentProcess()->SectionObject;
1819
1820 if (SectionObject->u.Flags.Image == 0)
1821 {
1822 RtlZeroMemory(ImageInformation, sizeof(*ImageInformation));
1823 return;
1824 }
1825
1826 /* Return the image information */
1827 *ImageInformation = ((PMM_IMAGE_SECTION_OBJECT)SectionObject->Segment)->ImageInformation;
1828}
struct _MM_IMAGE_SECTION_OBJECT * PMM_IMAGE_SECTION_OBJECT

Referenced by NtQueryInformationProcess().

◆ MmGetKernelAddressSpace()

◆ MmGetLRUFirstUserPage()

PFN_NUMBER NTAPI MmGetLRUFirstUserPage ( VOID  )

Definition at line 45 of file freelist.c.

46{
49
50 /* Find the first user page */
51 OldIrql = MiAcquirePfnLock();
52
53 if (FirstUserLRUPfn == NULL)
54 {
55 MiReleasePfnLock(OldIrql);
56 return 0;
57 }
58
61
62 MiReleasePfnLock(OldIrql);
63
64 return Page;
65}
VOID NTAPI MmReferencePage(PFN_NUMBER Pfn)
Definition: freelist.c:518
PMMPFN FirstUserLRUPfn
Definition: freelist.c:38

Referenced by MiShutdownSystem(), and MmTrimUserMemory().

◆ MmGetLRUNextUserPage()

PFN_NUMBER NTAPI MmGetLRUNextUserPage ( PFN_NUMBER  PreviousPage,
BOOLEAN  MoveToLast 
)

Definition at line 125 of file freelist.c.

126{
127 PFN_NUMBER Page = 0;
129
130 /* Find the next user page */
131 OldIrql = MiAcquirePfnLock();
132
133 PMMPFN PreviousPfn = MiGetPfnEntry(PreviousPage);
134 PMMPFN NextPfn = PreviousPfn->NextLRU;
135
136 /*
137 * Move this one at the end of the list.
138 * It may be freed by MmDereferencePage below.
139 * If it's not, then it means it is still hanging in some process address space.
140 * This avoids paging-out e.g. ntdll early just because it's mapped first time.
141 */
142 if ((MoveToLast) && (MmGetReferenceCountPage(PreviousPage) > 1))
143 {
144 MmRemoveLRUUserPage(PreviousPage);
145 MmInsertLRULastUserPage(PreviousPage);
146 }
147
148 if (NextPfn)
149 {
150 Page = MiGetPfnEntryIndex(NextPfn);
152 }
153
154 MmDereferencePage(PreviousPage);
155
156 MiReleasePfnLock(OldIrql);
157
158 return Page;
159}
VOID NTAPI MmDereferencePage(PFN_NUMBER Pfn)
Definition: freelist.c:565
ULONG NTAPI MmGetReferenceCountPage(PFN_NUMBER Pfn)
Definition: freelist.c:538

Referenced by MiShutdownSystem(), and MmTrimUserMemory().

◆ MmGetPageFileMapping()

VOID NTAPI MmGetPageFileMapping ( PEPROCESS  Process,
PVOID  Address,
SWAPENTRY SwapEntry 
)

Definition at line 299 of file page.c.

303{
304 ASSERT(FALSE);
305}

Referenced by MmAlterViewAttributes(), MmNotPresentFaultSectionView(), and MmPageOutCacheSection().

◆ MmGetPageProtect()

ULONG NTAPI MmGetPageProtect ( struct _EPROCESS Process,
PVOID  Address 
)

◆ MmGetPfnForProcess()

◆ MmGetReferenceCountPage()

ULONG NTAPI MmGetReferenceCountPage ( PFN_NUMBER  Page)

Definition at line 538 of file freelist.c.

539{
540 ULONG RCount;
541 PMMPFN Pfn1;
542
544
545 DPRINT("MmGetReferenceCountPage(PhysicalAddress %x)\n", Pfn << PAGE_SHIFT);
546
547 Pfn1 = MiGetPfnEntry(Pfn);
548 ASSERT(Pfn1);
549 ASSERT_IS_ROS_PFN(Pfn1);
550
551 RCount = Pfn1->u3.e2.ReferenceCount;
552
553 return(RCount);
554}

Referenced by MmGetLRUNextUserPage(), and MmGetReferenceCountPageWithoutLock().

◆ MmGetRmapListHeadPage()

struct _MM_RMAP_ENTRY *NTAPI MmGetRmapListHeadPage ( PFN_NUMBER  Page)

Definition at line 458 of file freelist.c.

459{
460 PMMPFN Pfn1;
461
462 /* PFN database must be locked */
464
465 /* Get the entry */
466 Pfn1 = MiGetPfnEntry(Pfn);
467 ASSERT(Pfn1);
468
469 if (!MI_IS_ROS_PFN(Pfn1))
470 {
471 return NULL;
472 }
473
474 /* Should not have an RMAP for a non-active page */
475 ASSERT(MiIsPfnInUse(Pfn1) == TRUE);
476
477 /* Get the list head */
478 return Pfn1->RmapListHead;
479}
BOOLEAN NTAPI MiIsPfnInUse(IN PMMPFN Pfn1)
Definition: freelist.c:174
#define MI_IS_ROS_PFN(x)
Definition: miarm.h:1103

Referenced by MmDeleteRmap(), MmDeleteSectionAssociation(), MmGetSegmentRmap(), MmInsertRmap(), MmPageOutPhysicalAddress(), MmpPageOutPhysicalAddress(), and MmTrimUserMemory().

◆ MmGetSavedSwapEntryPage()

SWAPENTRY NTAPI MmGetSavedSwapEntryPage ( PFN_NUMBER  Page)

Definition at line 499 of file freelist.c.

500{
501 SWAPENTRY SwapEntry;
502 KIRQL oldIrql;
503 PMMPFN Pfn1;
504
505 Pfn1 = MiGetPfnEntry(Pfn);
506 ASSERT(Pfn1);
507 ASSERT_IS_ROS_PFN(Pfn1);
508
509 oldIrql = MiAcquirePfnLock();
510 SwapEntry = Pfn1->u1.SwapEntry;
511 MiReleasePfnLock(oldIrql);
512
513 return(SwapEntry);
514}

Referenced by if(), MiPurgeImageSegment(), MmFinalizeSectionPageOut(), MmFreeSectionPage(), MmPageOutPhysicalAddress(), MmpFreePageFileSegment(), and MmUnsharePageEntrySectionSegment().

◆ MmGetSectionAssociation()

PMM_SECTION_SEGMENT NTAPI MmGetSectionAssociation ( PFN_NUMBER  Page,
PLARGE_INTEGER  Offset 
)

Definition at line 374 of file sptab.c.

376{
377 ULONG RawOffset;
380
381 KIRQL OldIrql = MiAcquirePfnLock();
382
383 PageTable = MmGetSegmentRmap(Page, &RawOffset);
384 if (PageTable)
385 {
386 Segment = PageTable->Segment;
387 Offset->QuadPart = PageTable->FileOffset.QuadPart +
388 ((ULONG64)RawOffset << PAGE_SHIFT);
389 ASSERT(PFN_FROM_SSE(PageTable->PageEntries[RawOffset]) == Page);
390 InterlockedIncrement64(Segment->ReferenceCount);
391 }
392
393 MiReleasePfnLock(OldIrql);
394
395 return Segment;
396}
PVOID NTAPI MmGetSegmentRmap(PFN_NUMBER Page, PULONG RawOffset)
Definition: rmap.c:468

Referenced by MiShutdownSystem(), MmPageOutPhysicalAddress(), and MmpPageOutPhysicalAddress().

◆ MmGetSessionById()

PVOID NTAPI MmGetSessionById ( _In_ ULONG  SessionId)

Definition at line 1050 of file session.c.

1052{
1053 PLIST_ENTRY ListEntry;
1054 PMM_SESSION_SPACE Session;
1056 KIRQL OldIrql;
1057
1058 /* Acquire the expansion lock while touching the session */
1060
1061 /* Loop all entries in the session ws list */
1062 ListEntry = MiSessionWsList.Flink;
1063 while (ListEntry != &MiSessionWsList)
1064 {
1065 Session = CONTAINING_RECORD(ListEntry, MM_SESSION_SPACE, WsListEntry);
1066 ListEntry = ListEntry->Flink;
1067
1068 /* Check if this is the session we are looking for */
1069 if (Session->SessionId == SessionId)
1070 {
1071 /* Check if we also have a process in the process list */
1072 if (!IsListEmpty(&Session->ProcessList))
1073 {
1075 EPROCESS,
1076 SessionProcessLinks);
1077
1078 /* Reference the process */
1080 break;
1081 }
1082 }
1083 }
1084
1085 /* Release the lock again */
1087
1088 return Process;
1089}
ULONG SessionId
Definition: dllmain.c:28
#define IsListEmpty(ListHead)
Definition: env_spec_w32.h:954
LIST_ENTRY MiSessionWsList
Definition: session.c:29
ULONG SessionId
Definition: miarm.h:477
LIST_ENTRY ProcessList
Definition: miarm.h:478

Referenced by ExpWin32SessionCallout().

◆ MmGetSessionId()

ULONG NTAPI MmGetSessionId ( IN PEPROCESS  Process)

Definition at line 179 of file session.c.

180{
181 PMM_SESSION_SPACE SessionGlobal;
182
183 /* The session leader is always session zero */
184 if (Process->Vm.Flags.SessionLeader == 1) return 0;
185
186 /* Otherwise, get the session global, and read the session ID from it */
187 SessionGlobal = (PMM_SESSION_SPACE)Process->Session;
188 if (!SessionGlobal) return 0;
189 return SessionGlobal->SessionId;
190}
struct _MM_SESSION_SPACE * PMM_SESSION_SPACE

Referenced by IoGetRequestorSessionId(), MmCreatePeb(), PsGetCurrentProcessSessionId(), PsGetProcessSessionId(), PsGetThreadSessionId(), PspInitializeProcessSecurity(), and SeExchangePrimaryToken().

◆ MmGetSessionIdEx()

ULONG NTAPI MmGetSessionIdEx ( IN PEPROCESS  Process)

Definition at line 194 of file session.c.

195{
196 PMM_SESSION_SPACE SessionGlobal;
197
198 /* The session leader is always session zero */
199 if (Process->Vm.Flags.SessionLeader == 1) return 0;
200
201 /* Otherwise, get the session global, and read the session ID from it */
202 SessionGlobal = (PMM_SESSION_SPACE)Process->Session;
203 if (!SessionGlobal) return -1;
204 return SessionGlobal->SessionId;
205}

Referenced by PsGetProcessSessionIdEx().

◆ MmGetSessionLocaleId()

ULONG NTAPI MmGetSessionLocaleId ( VOID  )

Definition at line 56 of file session.c.

57{
59 PAGED_CODE();
60
61 //
62 // Get the current process
63 //
65
66 //
67 // Check if it's NOT the Session Leader
68 //
69 if (!Process->Vm.Flags.SessionLeader)
70 {
71 //
72 // Make sure it has a valid Session
73 //
74 if (Process->Session)
75 {
76 //
77 // Get the Locale ID
78 //
79 return ((PMM_SESSION_SPACE)Process->Session)->LocaleId;
80 }
81 }
82
83 //
84 // Not a session leader, return the default
85 //
87}

Referenced by NtQueryDefaultLocale(), and PspUserThreadStartup().

◆ MmGrowKernelStack()

NTSTATUS NTAPI MmGrowKernelStack ( IN PVOID  StackPointer)

Definition at line 476 of file procsup.c.

477{
478 //
479 // Call the extended version
480 //
482}
NTSTATUS NTAPI MmGrowKernelStackEx(IN PVOID StackPointer, IN ULONG GrowSize)
Definition: procsup.c:388
#define KERNEL_LARGE_STACK_COMMIT

Referenced by KiUserModeCallout().

◆ MmInit1()

VOID NTAPI MmInit1 ( VOID  )

◆ MmInitGlobalKernelPageDirectory()

VOID NTAPI MmInitGlobalKernelPageDirectory ( VOID  )

Definition at line 277 of file page.c.

278{
279 ULONG i;
280 PULONG CurrentPageDirectory = (PULONG)PDE_BASE;
281
282 /* Loop the 2GB of address space which belong to the kernel */
283 for (i = MiGetPdeOffset(MmSystemRangeStart); i < 2048; i++)
284 {
285 /* Check if we have an entry for this already */
286 if ((i != MiGetPdeOffset(PTE_BASE)) &&
289 (CurrentPageDirectory[i]))
290 {
291 /* We don't, link it in our global page directory */
292 MmGlobalKernelPageDirectory[i] = CurrentPageDirectory[i];
293 }
294 }
295}
#define PDE_BASE
Definition: winldr.c:21
#define PTE_BASE
Definition: mmx86.c:14
#define MiGetPdeOffset(x)
Definition: mm.h:195
ULONG MmGlobalKernelPageDirectory[4096]
Definition: page.c:107

Referenced by MmInitSystem().

◆ MmInitializeBalancer()

VOID NTAPI MmInitializeBalancer ( ULONG  NrAvailablePages,
ULONG  NrSystemPages 
)

Definition at line 44 of file balance.c.

45{
47
48 /* Set up targets. */
51 MiMemoryConsumers[MC_USER].PagesTarget = NrAvailablePages / 2;
52}
MM_MEMORY_CONSUMER MiMemoryConsumers[MC_MAXIMUM]
Definition: balance.c:28
static ULONG MiMinimumAvailablePages
Definition: balance.c:29
static ULONG MiMinimumPagesPerRun
Definition: balance.c:30
#define memset(x, y, z)
Definition: compat.h:39
ULONG PagesTarget
Definition: mm.h:458

Referenced by MiInitMachineDependent().

◆ MmInitializeHandBuiltProcess()

NTSTATUS NTAPI MmInitializeHandBuiltProcess ( IN PEPROCESS  Process,
IN PULONG_PTR  DirectoryTableBase 
)

Definition at line 1131 of file procsup.c.

1133{
1134 /* Share the directory base with the idle process */
1135 DirectoryTableBase[0] = PsGetCurrentProcess()->Pcb.DirectoryTableBase[0];
1136 DirectoryTableBase[1] = PsGetCurrentProcess()->Pcb.DirectoryTableBase[1];
1137
1138 /* Initialize the Addresss Space */
1139 KeInitializeGuardedMutex(&Process->AddressCreationLock);
1140 KeInitializeSpinLock(&Process->HyperSpaceLock);
1141 Process->Vm.WorkingSetExpansionLinks.Flink = NULL;
1142 ASSERT(Process->VadRoot.NumberGenericTableElements == 0);
1143 Process->VadRoot.BalancedRoot.u1.Parent = &Process->VadRoot.BalancedRoot;
1144
1145 /* Use idle process Working set */
1146 Process->Vm.VmWorkingSetList = PsGetCurrentProcess()->Vm.VmWorkingSetList;
1147 Process->WorkingSetPage = PsGetCurrentProcess()->WorkingSetPage;
1148
1149 /* Done */
1150 Process->HasAddressSpace = TRUE;//??
1151 return STATUS_SUCCESS;
1152}
VOID FASTCALL KeInitializeGuardedMutex(OUT PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:31

Referenced by PspCreateProcess().

◆ MmInitializeHandBuiltProcess2()

NTSTATUS NTAPI MmInitializeHandBuiltProcess2 ( IN PEPROCESS  Process)

Definition at line 1157 of file procsup.c.

1158{
1159 /* Lock the VAD, ARM3-owned ranges away */
1160 return STATUS_SUCCESS;
1161}

Referenced by PspCreateProcess().

◆ MmInitializeMemoryConsumer()

VOID NTAPI MmInitializeMemoryConsumer ( ULONG  Consumer,
NTSTATUS(*)(ULONG Target, ULONG Priority, PULONG NrFreed)  Trim 
)

Definition at line 57 of file balance.c.

60{
61 MiMemoryConsumers[Consumer].Trim = Trim;
62}
NTSTATUS(* Trim)(ULONG Target, ULONG Priority, PULONG NrFreed)
Definition: mm.h:459

Referenced by MmInitSystem().

◆ MmInitializeProcessAddressSpace()

NTSTATUS NTAPI MmInitializeProcessAddressSpace ( IN PEPROCESS  Process,
IN PEPROCESS Clone  OPTIONAL,
IN PVOID Section  OPTIONAL,
IN OUT PULONG  Flags,
IN POBJECT_NAME_INFORMATION *AuditName  OPTIONAL 
)

◆ MmInitializeRegion()

VOID NTAPI MmInitializeRegion ( PLIST_ENTRY  RegionListHead,
SIZE_T  Length,
ULONG  Type,
ULONG  Protect 
)

Definition at line 239 of file region.c.

241{
243
246 if (!Region) return;
247
248 Region->Type = Type;
249 Region->Protect = Protect;
250 Region->Length = Length;
251 InitializeListHead(RegionListHead);
252 InsertHeadList(RegionListHead, &Region->RegionListEntry);
253}

Referenced by MmMapViewOfSegment().

◆ MmInitializeRmapList()

VOID NTAPI MmInitializeRmapList ( VOID  )

Definition at line 38 of file rmap.c.

39{
41 NULL,
42 RmapListFree,
43 0,
44 sizeof(MM_RMAP_ENTRY),
46 50);
47}
VOID NTAPI ExInitializeNPagedLookasideList(IN PNPAGED_LOOKASIDE_LIST Lookaside, IN PALLOCATE_FUNCTION Allocate OPTIONAL, IN PFREE_FUNCTION Free OPTIONAL, IN ULONG Flags, IN SIZE_T Size, IN ULONG Tag, IN USHORT Depth)
Definition: lookas.c:218
static NPAGED_LOOKASIDE_LIST RmapLookasideList
Definition: rmap.c:21
Definition: mm.h:266
#define TAG_RMAP
Definition: tag.h:112

Referenced by MmInitSystem().

◆ MmInitPagingFile()

VOID NTAPI MmInitPagingFile ( VOID  )

Definition at line 272 of file pagefile.c.

273{
274 ULONG i;
275
277
278 MiFreeSwapPages = 0;
279 MiUsedSwapPages = 0;
281
282 for (i = 0; i < MAX_PAGING_FILES; i++)
283 {
285 }
287}
ULONG MmNumberOfPagingFiles
Definition: pagefile.c:63
static PFN_COUNT MiReservedSwapPages
Definition: pagefile.c:76

Referenced by MmInitSystem().

◆ MmInitSectionImplementation()

NTSTATUS NTAPI MmInitSectionImplementation ( VOID  )

Definition at line 2294 of file section.c.

2295{
2296 OBJECT_TYPE_INITIALIZER ObjectTypeInitializer;
2298
2299 DPRINT("Creating Section Object Type\n");
2300
2301 /* Initialize the section based root */
2304
2305 /* Initialize the Section object type */
2306 RtlZeroMemory(&ObjectTypeInitializer, sizeof(ObjectTypeInitializer));
2307 RtlInitUnicodeString(&Name, L"Section");
2308 ObjectTypeInitializer.Length = sizeof(ObjectTypeInitializer);
2309 ObjectTypeInitializer.DefaultPagedPoolCharge = sizeof(SECTION);
2310 ObjectTypeInitializer.PoolType = PagedPool;
2311 ObjectTypeInitializer.UseDefaultObject = TRUE;
2312 ObjectTypeInitializer.GenericMapping = MmpSectionMapping;
2313 ObjectTypeInitializer.DeleteProcedure = MmpDeleteSection;
2314 ObjectTypeInitializer.CloseProcedure = MmpCloseSection;
2315 ObjectTypeInitializer.ValidAccessMask = SECTION_ALL_ACCESS;
2316 ObjectTypeInitializer.InvalidAttributes = OBJ_OPENLINK;
2317 ObCreateObjectType(&Name, &ObjectTypeInitializer, NULL, &MmSectionObjectType);
2318
2320
2321 return STATUS_SUCCESS;
2322}
struct NameRec_ * Name
Definition: cdprocs.h:460
#define OBJ_OPENLINK
Definition: winternl.h:230
MM_AVL_TABLE MmSectionBasedRoot
Definition: section.c:109
#define SECTION
Definition: profile.c:31
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
NTSTATUS NTAPI ObCreateObjectType(IN PUNICODE_STRING TypeName, IN POBJECT_TYPE_INITIALIZER ObjectTypeInitializer, IN PVOID Reserved, OUT POBJECT_TYPE *ObjectType)
Definition: oblife.c:1136
static GENERIC_MAPPING MmpSectionMapping
Definition: section.c:223
VOID NTAPI MmpDeleteSection(PVOID ObjectBody)
Definition: section.c:2138
VOID NTAPI MmpCloseSection(IN PEPROCESS Process OPTIONAL, IN PVOID Object, IN ACCESS_MASK GrantedAccess, IN ULONG ProcessHandleCount, IN ULONG SystemHandleCount)
Definition: section.c:2191
NTSTATUS NTAPI MmCreatePhysicalMemorySection(VOID)
Definition: section.c:2203
union _MMADDRESS_NODE::@2604 u1
struct _MMADDRESS_NODE * Parent
Definition: mmtypes.h:649
OB_CLOSE_METHOD CloseProcedure
Definition: obtypes.h:368
GENERIC_MAPPING GenericMapping
Definition: obtypes.h:358
OB_DELETE_METHOD DeleteProcedure
Definition: obtypes.h:369

Referenced by MmInitSystem().

◆ MmInitSystem()

BOOLEAN NTAPI MmInitSystem ( IN ULONG  Phase,
IN PLOADER_PARAMETER_BLOCK  LoaderBlock 
)

Definition at line 206 of file mminit.c.

208{
209 extern MMPTE ValidKernelPte;
210 PMMPTE PointerPte;
212 PFN_NUMBER PageFrameNumber;
213 PLIST_ENTRY ListEntry;
214 PLDR_DATA_TABLE_ENTRY DataTableEntry;
215
216 /* Initialize the kernel address space */
217 ASSERT(Phase == 1);
218
219#ifdef NEWCC
223 // Until we're fully demand paged, we can do things the old way through
224 // the balance manager
225 // CcInitView will override this...
227#else
229#endif
230
232
233 /* Intialize system memory areas */
235
236 /* Dump the address space */
238
244
245 //
246 // Create a PTE to double-map the shared data section. We allocate it
247 // from paged pool so that we can't fault when trying to touch the PTE
248 // itself (to map it), since paged pool addresses will already be mapped
249 // by the fault handler.
250 //
252 sizeof(MMPTE),
253 TAG_MM);
254 if (!MmSharedUserDataPte) return FALSE;
255
256 //
257 // Now get the PTE for shared data, and read the PFN that holds it
258 //
260 ASSERT(PointerPte->u.Hard.Valid == 1);
261 PageFrameNumber = PFN_FROM_PTE(PointerPte);
262
263 /* Build the PTE and write it */
265 PointerPte,
267 PageFrameNumber);
269
270 /* Initialize session working set support */
272
273 /* Setup session IDs */
275
276 /* Setup the memory threshold events */
277 if (!MiInitializeMemoryEvents()) return FALSE;
278
279 /*
280 * Unmap low memory
281 */
283
284 /* Initialize the balance set manager */
286
287 /* Loop the boot loaded images (under lock) */
289 for (ListEntry = PsLoadedModuleList.Flink;
290 ListEntry != &PsLoadedModuleList;
291 ListEntry = ListEntry->Flink)
292 {
293 /* Get the data table entry */
294 DataTableEntry = CONTAINING_RECORD(ListEntry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
295
296 /* Set up the image protection */
297 MiWriteProtectSystemImage(DataTableEntry->DllBase);
298 }
300
301 return TRUE;
302}
#define MM_READONLY
Definition: bootanim.c:18
#define ExAcquireResourceExclusiveLite(res, wait)
Definition: env_spec_w32.h:615
BOOLEAN NTAPI MiInitializeMemoryEvents(VOID)
Definition: mminit.c:1339
VOID NTAPI MiInitializeSessionIds(VOID)
Definition: session.c:116
VOID NTAPI MiWriteProtectSystemImage(_In_ PVOID ImageBase)
Definition: sysldr.c:2480
VOID NTAPI MiInitializeSessionWsSupport(VOID)
Definition: session.c:40
PMMSUPPORT MmKernelAddressSpace
Definition: mminit.c:27
FAST_MUTEX MiGlobalPageOperation
Definition: swapout.c:74
NTSTATUS MiRosTrimCache(ULONG Target, ULONG Priority, PULONG NrFreed)
Definition: swapout.c:633
PMMPTE MmSharedUserDataPte
Definition: mminit.c:26
VOID NTAPI MiInitSystemMemoryAreas(VOID)
Definition: mminit.c:65
NTSTATUS NTAPI MmInitBsmThread(VOID)
Definition: mminit.c:182
VOID NTAPI MiDbgDumpAddressSpace(VOID)
Definition: mminit.c:130
LIST_ENTRY MiSegmentList
Definition: data.c:86
KEVENT MmWaitPageEvent
Definition: fault.c:461
VOID FASTCALL ExReleaseResourceLite(IN PERESOURCE Resource)
Definition: resource.c:1822
NTSTATUS MmTrimUserMemory(ULONG Target, ULONG Priority, PULONG NrFreedPages)
Definition: balance.c:138
VOID NTAPI MiInitBalancerThread(VOID)
Definition: balance.c:420
VOID NTAPI MmInitializeMemoryConsumer(ULONG Consumer, NTSTATUS(*Trim)(ULONG Target, ULONG Priority, PULONG NrFreed))
Definition: balance.c:57
NTSTATUS NTAPI MmInitSectionImplementation(VOID)
Definition: section.c:2294
VOID NTAPI MmInitializeRmapList(VOID)
Definition: rmap.c:38
VOID NTAPI MmInitGlobalKernelPageDirectory(VOID)
Definition: page.c:277
VOID NTAPI MmInitPagingFile(VOID)
Definition: pagefile.c:272
LIST_ENTRY PsLoadedModuleList
Definition: sysldr.c:21
ERESOURCE PsLoadedModuleResource
Definition: sysldr.c:24
PEPROCESS PsIdleProcess
Definition: psmgr.c:51
#define KI_USER_SHARED_DATA
MMSUPPORT Vm
Definition: pstypes.h:1356

Referenced by Phase1InitializationDiscard().

◆ MmInsertRmap()

VOID NTAPI MmInsertRmap ( PFN_NUMBER  Page,
struct _EPROCESS Process,
PVOID  Address 
)

◆ MmIsDisabledPage()

BOOLEAN NTAPI MmIsDisabledPage ( struct _EPROCESS Process,
PVOID  Address 
)

◆ MmIsFileObjectAPagingFile()

BOOLEAN NTAPI MmIsFileObjectAPagingFile ( PFILE_OBJECT  FileObject)

Definition at line 119 of file pagefile.c.

120{
121 ULONG i;
122
123 /* Loop through all the paging files */
124 for (i = 0; i < MmNumberOfPagingFiles; i++)
125 {
126 /* Check if this is one of them */
127 if (MmPagingFile[i]->FileObject == FileObject) return TRUE;
128 }
129
130 /* Nothing found */
131 return FALSE;
132}

Referenced by FsRtlIsPagingFile(), and IoPageRead().

◆ MmIsPageInUse()

BOOLEAN NTAPI MmIsPageInUse ( PFN_NUMBER  Page)

Definition at line 558 of file freelist.c.

559{
560 return MiIsPfnInUse(MiGetPfnEntry(Pfn));
561}

Referenced by MmCreateVirtualMapping().

◆ MmIsPagePresent()

BOOLEAN NTAPI MmIsPagePresent ( struct _EPROCESS Process,
PVOID  Address 
)

◆ MmIsPageSwapEntry()

BOOLEAN NTAPI MmIsPageSwapEntry ( struct _EPROCESS Process,
PVOID  Address 
)

◆ MmIsSessionAddress()

BOOLEAN NTAPI MmIsSessionAddress ( IN PVOID  Address)

Definition at line 48 of file session.c.

49{
50 /* Check if it is in range */
52}
#define MI_IS_SESSION_ADDRESS(Address)
Definition: miarm.h:171

Referenced by KdpQueryMemory().

◆ MmIsSpecialPoolAddress()

◆ MmIsSpecialPoolAddressFree()

BOOLEAN NTAPI MmIsSpecialPoolAddressFree ( IN PVOID  P)

Referenced by KeBugCheckWithTf().

◆ MmLoadSystemImage()

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 
)

Definition at line 2935 of file sysldr.c.

2941{
2942 PVOID ModuleLoadBase = NULL;
2947 PIMAGE_NT_HEADERS NtHeader;
2948 UNICODE_STRING BaseName, BaseDirectory, PrefixName;
2949 PLDR_DATA_TABLE_ENTRY LdrEntry = NULL;
2950 ULONG EntrySize, DriverSize;
2951 PLOAD_IMPORTS LoadedImports = MM_SYSLDR_NO_IMPORTS;
2952 PCHAR MissingApiName, Buffer;
2953 PWCHAR MissingDriverName, PrefixedBuffer = NULL;
2954 HANDLE SectionHandle;
2956 PSECTION Section = NULL;
2957 BOOLEAN LockOwned = FALSE;
2958 PLIST_ENTRY NextEntry;
2959 IMAGE_INFO ImageInfo;
2960
2961 PAGED_CODE();
2962
2963 /* Detect session-load */
2964 if (Flags)
2965 {
2966 /* Sanity checks */
2967 ASSERT(NamePrefix == NULL);
2968 ASSERT(LoadedName == NULL);
2969
2970 /* Make sure the process is in session too */
2971 if (!PsGetCurrentProcess()->ProcessInSession) return STATUS_NO_MEMORY;
2972 }
2973
2974 /* Allocate a buffer we'll use for names */
2977 TAG_LDR_WSTR);
2979
2980 /* Check for a separator */
2981 if (FileName->Buffer[0] == OBJ_NAME_PATH_SEPARATOR)
2982 {
2983 PWCHAR p;
2984 ULONG BaseLength;
2985
2986 /* Loop the path until we get to the base name */
2987 p = &FileName->Buffer[FileName->Length / sizeof(WCHAR)];
2988 while (*(p - 1) != OBJ_NAME_PATH_SEPARATOR) p--;
2989
2990 /* Get the length */
2991 BaseLength = (ULONG)(&FileName->Buffer[FileName->Length / sizeof(WCHAR)] - p);
2992 BaseLength *= sizeof(WCHAR);
2993
2994 /* Setup the string */
2995 BaseName.Length = (USHORT)BaseLength;
2996 BaseName.Buffer = p;
2997 }
2998 else
2999 {
3000 /* Otherwise, we already have a base name */
3001 BaseName.Length = FileName->Length;
3002 BaseName.Buffer = FileName->Buffer;
3003 }
3004
3005 /* Setup the maximum length */
3006 BaseName.MaximumLength = BaseName.Length;
3007
3008 /* Now compute the base directory */
3009 BaseDirectory = *FileName;
3010 BaseDirectory.Length -= BaseName.Length;
3011 BaseDirectory.MaximumLength = BaseDirectory.Length;
3012
3013 /* And the prefix, which for now is just the name itself */
3014 PrefixName = *FileName;
3015
3016 /* Check if we have a prefix */
3017 if (NamePrefix)
3018 {
3019 /* Check if "directory + prefix" is too long for the string */
3020 Status = RtlUShortAdd(BaseDirectory.Length,
3021 NamePrefix->Length,
3022 &PrefixName.MaximumLength);
3023 if (!NT_SUCCESS(Status))
3024 {
3026 goto Quickie;
3027 }
3028
3029 /* Check if "directory + prefix + basename" is too long for the string */
3030 Status = RtlUShortAdd(PrefixName.MaximumLength,
3031 BaseName.Length,
3032 &PrefixName.MaximumLength);
3033 if (!NT_SUCCESS(Status))
3034 {
3036 goto Quickie;
3037 }
3038
3039 /* Allocate the buffer exclusively used for prefixed name */
3040 PrefixedBuffer = ExAllocatePoolWithTag(PagedPool,
3041 PrefixName.MaximumLength,
3042 TAG_LDR_WSTR);
3043 if (!PrefixedBuffer)
3044 {
3046 goto Quickie;
3047 }
3048
3049 /* Clear out the prefixed name string */
3050 PrefixName.Buffer = PrefixedBuffer;
3051 PrefixName.Length = 0;
3052
3053 /* Concatenate the strings */
3054 RtlAppendUnicodeStringToString(&PrefixName, &BaseDirectory);
3055 RtlAppendUnicodeStringToString(&PrefixName, NamePrefix);
3056 RtlAppendUnicodeStringToString(&PrefixName, &BaseName);
3057
3058 /* Now the base name of the image becomes the prefixed version */
3059 BaseName.Buffer = &(PrefixName.Buffer[BaseDirectory.Length / sizeof(WCHAR)]);
3060 BaseName.Length += NamePrefix->Length;
3061 BaseName.MaximumLength = (PrefixName.MaximumLength - BaseDirectory.Length);
3062 }
3063
3064 /* Check if we already have a name, use it instead */
3065 if (LoadedName) BaseName = *LoadedName;
3066
3067 /* Check for loader snap debugging */
3069 {
3070 /* Print out standard string */
3071 DPRINT1("MM:SYSLDR Loading %wZ (%wZ) %s\n",
3072 &PrefixName, &BaseName, Flags ? "in session space" : "");
3073 }
3074
3075 /* Acquire the load lock */
3076LoaderScan:
3077 ASSERT(LockOwned == FALSE);
3078 LockOwned = TRUE;
3082 KernelMode,
3083 FALSE,
3084 NULL);
3085
3086 /* Scan the module list */
3087 NextEntry = PsLoadedModuleList.Flink;
3088 while (NextEntry != &PsLoadedModuleList)
3089 {
3090 /* Get the entry and compare the names */
3091 LdrEntry = CONTAINING_RECORD(NextEntry,
3093 InLoadOrderLinks);
3094 if (RtlEqualUnicodeString(&PrefixName, &LdrEntry->FullDllName, TRUE))
3095 {
3096 /* Found it, break out */
3097 break;
3098 }
3099
3100 /* Keep scanning */
3101 NextEntry = NextEntry->Flink;
3102 }
3103
3104 /* Check if we found the image */
3105 if (NextEntry != &PsLoadedModuleList)
3106 {
3107 /* Check if we had already mapped a section */
3108 if (Section)
3109 {
3110 /* Dereference and clear */
3111 ObDereferenceObject(Section);
3112 Section = NULL;
3113 }
3114
3115 /* Check if this was supposed to be a session load */
3116 if (!Flags)
3117 {
3118 /* It wasn't, so just return the data */
3119 *ModuleObject = LdrEntry;
3120 *ImageBaseAddress = LdrEntry->DllBase;
3122 }
3123 else
3124 {
3125 /* We don't support session loading yet */
3126 UNIMPLEMENTED_DBGBREAK("Unsupported Session-Load!\n");
3128 }
3129
3130 /* Do cleanup */
3131 goto Quickie;
3132 }
3133 else if (!Section)
3134 {
3135 /* It wasn't loaded, and we didn't have a previous attempt */
3138 LockOwned = FALSE;
3139
3140 /* Check if KD is enabled */
3142 {
3143 /* FIXME: Attempt to get image from KD */
3144 }
3145
3146 /* We don't have a valid entry */
3147 LdrEntry = NULL;
3148
3149 /* Setup image attributes */
3151 FileName,
3153 NULL,
3154 NULL);
3155
3156 /* Open the image */
3162 0);
3163 if (!NT_SUCCESS(Status))
3164 {
3165 DPRINT1("ZwOpenFile failed for '%wZ' with status 0x%x\n",
3166 FileName, Status);
3167 goto Quickie;
3168 }
3169
3170 /* Validate it */
3175 {
3176 /* Fail loading */
3177 goto Quickie;
3178 }
3179
3180 /* Check if this is a session-load */
3181 if (Flags)
3182 {
3183 /* Then we only need read and execute */
3185 }
3186 else
3187 {
3188 /* Otherwise, we can allow write access */
3190 }
3191
3192 /* Initialize the attributes for the section */
3194 NULL,
3196 NULL,
3197 NULL);
3198
3199 /* Create the section */
3200 Status = ZwCreateSection(&SectionHandle,
3203 NULL,
3205 SEC_IMAGE,
3206 FileHandle);
3207 if (!NT_SUCCESS(Status))
3208 {
3209 DPRINT1("ZwCreateSection failed with status 0x%x\n", Status);
3210 goto Quickie;
3211 }
3212
3213 /* Now get the section pointer */
3214 Status = ObReferenceObjectByHandle(SectionHandle,
3217 KernelMode,
3218 (PVOID*)&Section,
3219 NULL);
3220 ZwClose(SectionHandle);
3221 if (!NT_SUCCESS(Status)) goto Quickie;
3222
3223 /* Check if this was supposed to be a session-load */
3224 if (Flags)
3225 {
3226 /* We don't support session loading yet */
3227 UNIMPLEMENTED_DBGBREAK("Unsupported Session-Load!\n");
3228 goto Quickie;
3229 }
3230
3231 /* Check the loader list again, we should end up in the path below */
3232 goto LoaderScan;
3233 }
3234 else
3235 {
3236 /* We don't have a valid entry */
3237 LdrEntry = NULL;
3238 }
3239
3240 /* Load the image */
3241 Status = MiLoadImageSection(&Section,
3242 &ModuleLoadBase,
3243 FileName,
3244 FALSE,
3245 NULL);
3247
3248 /* Get the size of the driver */
3249 DriverSize = ((PMM_IMAGE_SECTION_OBJECT)Section->Segment)->ImageInformation.ImageFileSize;
3250
3251 /* Make sure we're not being loaded into session space */
3252 if (!Flags)
3253 {
3254 /* Check for success */
3255 if (NT_SUCCESS(Status))
3256 {
3257 /* Support large pages for drivers */
3258 MiUseLargeDriverPage(DriverSize / PAGE_SIZE,
3259 &ModuleLoadBase,
3260 &BaseName,
3261 TRUE);
3262 }
3263
3264 /* Dereference the section */
3265 ObDereferenceObject(Section);
3266 Section = NULL;
3267 }
3268
3269 /* Check for failure of the load earlier */
3270 if (!NT_SUCCESS(Status))
3271 {
3272 DPRINT1("MiLoadImageSection failed with status 0x%x\n", Status);
3273 goto Quickie;
3274 }
3275
3276 /* Relocate the driver */
3277 Status = LdrRelocateImageWithBias(ModuleLoadBase,
3278 0,
3279 "SYSLDR",
3283 if (!NT_SUCCESS(Status))
3284 {
3285 DPRINT1("LdrRelocateImageWithBias failed with status 0x%x\n", Status);
3286 goto Quickie;
3287 }
3288
3289 /* Get the NT Header */
3290 NtHeader = RtlImageNtHeader(ModuleLoadBase);
3291
3292 /* Calculate the size we'll need for the entry and allocate it */
3294 BaseName.Length +
3295 sizeof(UNICODE_NULL);
3296
3297 /* Allocate the entry */
3299 if (!LdrEntry)
3300 {
3301 /* Fail */
3303 goto Quickie;
3304 }
3305
3306 /* Setup the entry */
3307 LdrEntry->Flags = LDRP_LOAD_IN_PROGRESS;
3308 LdrEntry->LoadCount = 1;
3309 LdrEntry->LoadedImports = LoadedImports;
3310 LdrEntry->PatchInformation = NULL;
3311
3312 /* Check the version */
3313 if ((NtHeader->OptionalHeader.MajorOperatingSystemVersion >= 5) &&
3314 (NtHeader->OptionalHeader.MajorImageVersion >= 5))
3315 {
3316 /* Mark this image as a native image */
3317 LdrEntry->Flags |= LDRP_ENTRY_NATIVE;
3318 }
3319
3320 /* Setup the rest of the entry */
3321 LdrEntry->DllBase = ModuleLoadBase;
3322 LdrEntry->EntryPoint = (PVOID)((ULONG_PTR)ModuleLoadBase +
3324 LdrEntry->SizeOfImage = DriverSize;
3325 LdrEntry->CheckSum = NtHeader->OptionalHeader.CheckSum;
3326 LdrEntry->SectionPointer = Section;
3327
3328 /* Now write the DLL name */
3329 LdrEntry->BaseDllName.Buffer = (PVOID)(LdrEntry + 1);
3330 LdrEntry->BaseDllName.Length = BaseName.Length;
3331 LdrEntry->BaseDllName.MaximumLength = BaseName.Length;
3332
3333 /* Copy and null-terminate it */
3335 BaseName.Buffer,
3336 BaseName.Length);
3337 LdrEntry->BaseDllName.Buffer[BaseName.Length / sizeof(WCHAR)] = UNICODE_NULL;
3338
3339 /* Now allocate the full name */
3341 PrefixName.Length +
3342 sizeof(UNICODE_NULL),
3343 TAG_LDR_WSTR);
3344 if (!LdrEntry->FullDllName.Buffer)
3345 {
3346 /* Don't fail, just set it to zero */
3347 LdrEntry->FullDllName.Length = 0;
3348 LdrEntry->FullDllName.MaximumLength = 0;
3349 }
3350 else
3351 {
3352 /* Set it up */
3353 LdrEntry->FullDllName.Length = PrefixName.Length;
3354 LdrEntry->FullDllName.MaximumLength = PrefixName.Length;
3355
3356 /* Copy and null-terminate */
3358 PrefixName.Buffer,
3359 PrefixName.Length);
3360 LdrEntry->FullDllName.Buffer[PrefixName.Length / sizeof(WCHAR)] = UNICODE_NULL;
3361 }
3362
3363 /* Add the entry */
3364 MiProcessLoaderEntry(LdrEntry, TRUE);
3365
3366 /* Resolve imports */
3367 MissingApiName = Buffer;
3368 MissingDriverName = NULL;
3369 Status = MiResolveImageReferences(ModuleLoadBase,
3370 &BaseDirectory,
3371 NULL,
3372 &MissingApiName,
3373 &MissingDriverName,
3374 &LoadedImports);
3375 if (!NT_SUCCESS(Status))
3376 {
3377 BOOLEAN NeedToFreeString = FALSE;
3378
3379 /* If the lowest bit is set to 1, this is a hint that we need to free */
3380 if (*(ULONG_PTR*)&MissingDriverName & 1)
3381 {
3382 NeedToFreeString = TRUE;
3383 *(ULONG_PTR*)&MissingDriverName &= ~1;
3384 }
3385
3386 DPRINT1("MiResolveImageReferences failed with status 0x%x\n", Status);
3387 DPRINT1(" Missing driver '%ls', missing API '%s'\n",
3388 MissingDriverName, MissingApiName);
3389
3390 if (NeedToFreeString)
3391 {
3392 ExFreePoolWithTag(MissingDriverName, TAG_LDR_WSTR);
3393 }
3394
3395 /* Fail */
3396 MiProcessLoaderEntry(LdrEntry, FALSE);
3397
3398 /* Check if we need to free the name */
3399 if (LdrEntry->FullDllName.Buffer)
3400 {
3401 /* Free it */
3403 }
3404
3405 /* Free the entry itself */
3407 LdrEntry = NULL;
3408 goto Quickie;
3409 }
3410
3411 /* Update the loader entry */
3412 LdrEntry->Flags |= (LDRP_SYSTEM_MAPPED |
3415 LdrEntry->Flags &= ~LDRP_LOAD_IN_PROGRESS;
3416 LdrEntry->LoadedImports = LoadedImports;
3417
3418 /* FIXME: Call driver verifier's loader function */
3419
3420 /* Write-protect the system image */
3422
3423 /* Initialize the security cookie (Win7 is not doing this yet!) */
3424 LdrpInitSecurityCookie(LdrEntry);
3425
3426 /* Check if notifications are enabled */
3428 {
3429 /* Fill out the notification data */
3430 ImageInfo.Properties = 0;
3432 ImageInfo.SystemModeImage = TRUE;
3433 ImageInfo.ImageSize = LdrEntry->SizeOfImage;
3434 ImageInfo.ImageBase = LdrEntry->DllBase;
3435 ImageInfo.ImageSectionNumber = ImageInfo.ImageSelector = 0;
3436
3437 /* Send the notification */
3439 }
3440
3441#ifdef __ROS_ROSSYM__
3442 /* MiCacheImageSymbols doesn't detect rossym */
3443 if (TRUE)
3444#else
3445 /* Check if there's symbols */
3446 if (MiCacheImageSymbols(LdrEntry->DllBase))
3447#endif
3448 {
3449 UNICODE_STRING UnicodeTemp;
3450 STRING AnsiTemp;
3451
3452 /* Check if the system root is present */
3453 if ((PrefixName.Length > (11 * sizeof(WCHAR))) &&
3454 !(_wcsnicmp(PrefixName.Buffer, L"\\SystemRoot", 11)))
3455 {
3456 /* Add the system root */
3457 UnicodeTemp = PrefixName;
3458 UnicodeTemp.Buffer += 11;
3459 UnicodeTemp.Length -= (11 * sizeof(WCHAR));
3462 "%ws%wZ",
3463 &SharedUserData->NtSystemRoot[2],
3464 &UnicodeTemp);
3465 }
3466 else
3467 {
3468 /* Build the name */
3470 "%wZ", &BaseName);
3471 }
3472
3473 /* Setup the ANSI string */
3474 RtlInitString(&AnsiTemp, Buffer);
3475
3476 /* Notify the debugger */
3477 DbgLoadImageSymbols(&AnsiTemp,
3478 LdrEntry->DllBase,
3480 LdrEntry->Flags |= LDRP_DEBUG_SYMBOLS_LOADED;
3481 }
3482
3483 /* Page the driver */
3484 ASSERT(Section == NULL);
3485 MiEnablePagingOfDriver(LdrEntry);
3486
3487 /* Return pointers */
3488 *ModuleObject = LdrEntry;
3489 *ImageBaseAddress = LdrEntry->DllBase;
3490
3491Quickie:
3492 /* Check if we have the lock acquired */
3493 if (LockOwned)
3494 {
3495 /* Release the lock */
3498 LockOwned = FALSE;
3499 }
3500
3501 /* If we have a file handle, close it */
3503
3504 /* If we have allocated a prefixed name buffer, free it */
3505 if (PrefixedBuffer) ExFreePoolWithTag(PrefixedBuffer, TAG_LDR_WSTR);
3506
3507 /* Free the name buffer and return status */
3509 return Status;
3510}
#define OBJ_NAME_PATH_SEPARATOR
Definition: arcname_tests.c:25
#define SECTION_MAP_READ
Definition: compat.h:139
#define FILE_SHARE_READ
Definition: compat.h:136
#define MAXIMUM_FILENAME_LENGTH
Definition: env_spec_w32.h:41
struct _FileName FileName
Definition: fatprocs.h:896
_Must_inspect_result_ _In_opt_ PFLT_INSTANCE _Out_ PHANDLE FileHandle
Definition: fltkernel.h:1231
std::wstring STRING
Definition: fontsub.cpp:33
GLfloat GLfloat p
Definition: glext.h:8902
#define FLG_SHOW_LDR_SNAPS
Definition: pstypes.h:57
#define IMAGE_ADDRESSING_MODE_32BIT
Definition: pstypes.h:194
BOOLEAN KdDebuggerNotPresent
Definition: kddata.c:82
BOOLEAN KdDebuggerEnabled
Definition: kddata.c:83
#define KeLeaveCriticalRegion()
Definition: ke_x.h:119
#define KeEnterCriticalRegion()
Definition: ke_x.h:88
#define LDRP_DEBUG_SYMBOLS_LOADED
Definition: ldrtypes.h:50
#define LDRP_ENTRY_PROCESSED
Definition: ldrtypes.h:44
#define LDRP_ENTRY_NATIVE
Definition: ldrtypes.h:57
#define LDRP_MM_LOADED
Definition: ldrtypes.h:60
#define LDRP_LOAD_IN_PROGRESS
Definition: ldrtypes.h:42
#define MM_SYSLDR_NO_IMPORTS
Definition: miarm.h:200
#define MUTANT_INCREMENT
Definition: extypes.h:84
NTSYSAPI NTSTATUS NTAPI ZwOpenFile(_Out_ PHANDLE FileHandle, _In_ ACCESS_MASK DesiredAccess, _In_ POBJECT_ATTRIBUTES ObjectAttributes, _Out_ PIO_STATUS_BLOCK IoStatusBlock, _In_ ULONG ShareAccess, _In_ ULONG OpenOptions)
VOID NTAPI DbgLoadImageSymbols(_In_ PSTRING Name, _In_ PVOID Base, _In_ ULONG_PTR ProcessId)
NTSYSAPI VOID NTAPI RtlInitString(PSTRING DestinationString, PCSZ SourceString)
ULONG ACCESS_MASK
Definition: nt_native.h:40
NTSYSAPI BOOLEAN NTAPI RtlEqualUnicodeString(PUNICODE_STRING String1, PUNICODE_STRING String2, BOOLEAN CaseInSensitive)
#define FILE_SHARE_DELETE
Definition: nt_native.h:682
#define FILE_EXECUTE
Definition: nt_native.h:642
LONG NTAPI KeReleaseMutant(IN PKMUTANT Mutant, IN KPRIORITY Increment, IN BOOLEAN Abandon, IN BOOLEAN Wait)
Definition: mutex.c:98
HANDLE NTAPI PsGetCurrentProcessId(VOID)
Definition: process.c:1123
#define STATUS_IMAGE_ALREADY_LOADED
Definition: ntstatus.h:506
#define STATUS_ALREADY_COMMITTED
Definition: ntstatus.h:270
NTSTRSAFEVAPI RtlStringCbPrintfA(_Out_writes_bytes_(cbDest) _Always_(_Post_z_) NTSTRSAFE_PSTR pszDest, _In_ size_t cbDest, _In_ _Printf_format_string_ NTSTRSAFE_PCSTR pszFormat,...)
Definition: ntstrsafe.h:1148
NTSTATUS NTAPI ObReferenceObjectByHandle(IN HANDLE Handle, IN ACCESS_MASK DesiredAccess, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode, OUT PVOID *Object, OUT POBJECT_HANDLE_INFORMATION HandleInformation OPTIONAL)
Definition: obref.c:494
BOOLEAN PsImageNotifyEnabled
Definition: psnotify.c:18
FORCEINLINE VOID PspRunLoadImageNotifyRoutines(PUNICODE_STRING FullImageName, HANDLE ProcessId, PIMAGE_INFO ImageInfo)
Definition: ps_x.h:84
_Check_return_ _CRTIMP int __cdecl _wcsnicmp(_In_reads_or_z_(_MaxCount) const wchar_t *_Str1, _In_reads_or_z_(_MaxCount) const wchar_t *_Str2, _In_ size_t _MaxCount)
#define SharedUserData
SIZE_T ImageSize
Definition: pstypes.h:209
ULONG SystemModeImage
Definition: pstypes.h:201
ULONG ImageSectionNumber
Definition: pstypes.h:210
PVOID ImageBase
Definition: pstypes.h:207
ULONG Properties
Definition: pstypes.h:198
ULONG ImageAddressingMode
Definition: pstypes.h:200
ULONG ImageSelector
Definition: pstypes.h:208
WORD MajorOperatingSystemVersion
Definition: ntddk_ex.h:160
USHORT LoadCount
Definition: ntddk_ex.h:208
PVOID LoadedImports
Definition: ldrtypes.h:161
PVOID SectionPointer
Definition: ntddk_ex.h:213
ULONG CheckSum
Definition: btrfs_drv.h:1886
PVOID PatchInformation
Definition: ldrtypes.h:164
NTSTATUS NTAPI MiResolveImageReferences(IN PVOID ImageBase, IN PUNICODE_STRING ImageFileDirectory, IN PUNICODE_STRING NamePrefix OPTIONAL, OUT PCHAR *MissingApi, OUT PWCHAR *MissingDriver, OUT PLOAD_IMPORTS *LoadImports)
Definition: sysldr.c:1033
PVOID NTAPI LdrpInitSecurityCookie(PLDR_DATA_TABLE_ENTRY LdrEntry)
Definition: sysldr.c:2898
VOID NTAPI MiWriteProtectSystemImage(_In_ PVOID ImageBase)
Definition: sysldr.c:2480
VOID NTAPI MiEnablePagingOfDriver(IN PLDR_DATA_TABLE_ENTRY LdrEntry)
Definition: sysldr.c:2656
VOID NTAPI MiProcessLoaderEntry(IN PLDR_DATA_TABLE_ENTRY LdrEntry, IN BOOLEAN Insert)
Definition: sysldr.c:621
PVOID NTAPI MiCacheImageSymbols(IN PVOID BaseAddress)
Definition: sysldr.c:50
NTSTATUS NTAPI MiLoadImageSection(_Inout_ PSECTION *SectionPtr, _Out_ PVOID *ImageBase, _In_ PUNICODE_STRING FileName, _In_ BOOLEAN SessionLoad, _In_ PLDR_DATA_TABLE_ENTRY LdrEntry)
Definition: sysldr.c:77
NTSTATUS NTAPI MmCheckSystemImage(IN HANDLE ImageHandle, IN BOOLEAN PurgeSection)
Definition: sysldr.c:2744
KMUTANT MmSystemLoadLock
Definition: sysldr.c:26
LOGICAL NTAPI MiUseLargeDriverPage(IN ULONG NumberOfPtes, IN OUT PVOID *ImageBaseAddress, IN PUNICODE_STRING BaseImageName, IN BOOLEAN BootDriver)
Definition: sysldr.c:2384
uint16_t * PWCHAR
Definition: typedefs.h:56
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
_Must_inspect_result_ _In_ WDFDEVICE _In_ ULONG _In_ ACCESS_MASK DesiredAccess
Definition: wdfdevice.h:2658
@ WrVirtualMemory
Definition: ketypes.h:433

Referenced by IopLoadDriver(), MiResolveImageReferences(), and SSI_DEF().

◆ MmLocateMemoryAreaByAddress()

PMEMORY_AREA NTAPI MmLocateMemoryAreaByAddress ( PMMSUPPORT  AddressSpace,
PVOID  Address 
)

Definition at line 60 of file marea.c.

63{
64 ULONG_PTR StartVpn = (ULONG_PTR)Address_ / PAGE_SIZE;
70 PMMVAD_LONG Vad;
71
73 Table = (Process != NULL) ? &Process->VadRoot : &MiRosKernelVadRoot;
74
75 Result = MiCheckForConflictingNode(StartVpn, StartVpn, Table, &Node);
76 if (Result != TableFoundNode)
77 {
78 return NULL;
79 }
80
81 Vad = (PMMVAD_LONG)Node;
82 if (Vad->u.VadFlags.Spare == 0)
83 {
84 /* Check if this is VM VAD */
85 if (Vad->ControlArea == NULL)
86 {
87 /* We store the reactos MEMORY_AREA here */
89 }
90 else
91 {
92 /* This is a section VAD. Store the MAREA here for now */
94 }
95 }
96 else
97 {
99 }
100
101 return MemoryArea;
102}
union node Node
Definition: types.h:1255
ASMGENDATA Table[]
Definition: genincdata.c:61
TABLE_SEARCH_RESULT NTAPI MiCheckForConflictingNode(IN ULONG_PTR StartVpn, IN ULONG_PTR EndVpn, IN PMM_AVL_TABLE Table, OUT PMMADDRESS_NODE *NodeOrParent)
Definition: vadnode.c:150
struct _MMVAD_LONG * PMMVAD_LONG
PMMPTE FirstPrototypePte
Definition: mmtypes.h:766
PVOID Banked
Definition: mmtypes.h:780
MMVAD_FLAGS VadFlags
Definition: mmtypes.h:763
PCONTROL_AREA ControlArea
Definition: mmtypes.h:765
union _MMVAD_LONG::@2609 u
union _MMVAD_LONG::@2612 u4
Definition: dlist.c:348

Referenced by MiProtectVirtualMemory(), MiQueryMemoryBasicInformation(), MiRosProtectVirtualMemory(), MiRosUnmapViewOfSection(), MiUnmapViewOfSection(), MmAccessFault(), MmAlterViewAttributes(), MmArePagesResident(), MmMakePagesDirty(), MmNotPresentFault(), MmpAccessFault(), MmPageOutPhysicalAddress(), MmpPageOutPhysicalAddress(), MmUnmapViewInSystemSpace(), MmUnmapViewOfSegment(), NtAllocateVirtualMemory(), and NtFreeVirtualMemory().

◆ MmLocateMemoryAreaByRegion()

PMEMORY_AREA NTAPI MmLocateMemoryAreaByRegion ( PMMSUPPORT  AddressSpace,
PVOID  Address,
SIZE_T  Length 
)

Definition at line 106 of file marea.c.

110{
111 ULONG_PTR StartVpn = (ULONG_PTR)Address_ / PAGE_SIZE;
112 ULONG_PTR EndVpn = ((ULONG_PTR)Address_ + Length - 1) / PAGE_SIZE;
118 PMMVAD_LONG Vad;
119
121 Table = (Process != NULL) ? &Process->VadRoot : &MiRosKernelVadRoot;
122
123 Result = MiCheckForConflictingNode(StartVpn, EndVpn, Table, &Node);
124 if (Result != TableFoundNode)
125 {
126 return NULL;
127 }
128
129 Vad = (PMMVAD_LONG)Node;
130 if (Vad->u.VadFlags.Spare == 0)
131 {
132 /* Check if this is VM VAD */
133 if (Vad->ControlArea == NULL)
134 {
135 /* We store the reactos MEMORY_AREA here */
137 }
138 else
139 {
140 /* This is a section VAD. Store the MAREA here for now */
142 }
143 }
144 else
145 {
147 }
148
150 return MemoryArea;
151}

Referenced by MmCreateMemoryArea(), and MmMapViewOfSection().

◆ MmLockAddressSpace()

◆ MmMakeDataSectionResident()

NTSTATUS NTAPI MmMakeDataSectionResident ( _In_ PSECTION_OBJECT_POINTERS  SectionObjectPointer,
_In_ LONGLONG  Offset,
_In_ ULONG  Length,
_In_ PLARGE_INTEGER  ValidDataLength 
)

Definition at line 4920 of file section.c.

4925{
4927
4928 /* There must be a segment for this call */
4929 ASSERT(Segment);
4930
4932
4933 MmDereferenceSegment(Segment);
4934
4935 return Status;
4936}
static NTSTATUS NTAPI MmMakeSegmentResident(_In_ PMM_SECTION_SEGMENT Segment, _In_ LONGLONG Offset, _In_ ULONG Length, _In_opt_ PLARGE_INTEGER ValidDataLength, _In_ BOOLEAN SetDirty)
Definition: section.c:1192

Referenced by CcRosEnsureVacbResident().

◆ MmMakeKernelResourceSectionWritable()

VOID NTAPI MmMakeKernelResourceSectionWritable ( VOID  )

Definition at line 2361 of file sysldr.c.

2362{
2363 /* Don't do anything if the resource section is already writable */
2365 return;
2366
2367 /* If the resource section is physical, we cannot change its protection */
2369 return;
2370
2372 {
2373 /*
2374 * Invalidate the cached resource section PTEs
2375 * so as to not change its protection again later.
2376 */
2379 }
2380}
BOOLEAN NTAPI MmChangeKernelResourceSectionProtection(IN ULONG_PTR ProtectionMask)
Definition: sysldr.c:2330

Referenced by KeGetBugMessageText().

◆ MmMakePagesDirty()

NTSTATUS NTAPI MmMakePagesDirty ( _In_ PEPROCESS  Process,
_In_ PVOID  Address,
_In_ ULONG  Length 
)

Definition at line 5202 of file section.c.

5206{
5209 LARGE_INTEGER SegmentOffset, RangeEnd;
5211
5213
5215 if (MemoryArea == NULL)
5216 {
5217 DPRINT1("Unable to find memory area at address %p.\n", Address);
5220 }
5221
5222 /* Only supported in old Mm for now */
5224 /* For file mappings */
5226
5227 Segment = MemoryArea->SectionData.Segment;
5229
5231 + MemoryArea->SectionData.ViewOffset;
5233 + MemoryArea->SectionData.ViewOffset;
5234
5235 DPRINT("MmMakePagesResident: Segment %p, 0x%I64x -> 0x%I64x\n", Segment, SegmentOffset.QuadPart, RangeEnd.QuadPart);
5236
5237 while (SegmentOffset.QuadPart < RangeEnd.QuadPart)
5238 {
5240
5241 /* Let any pending read proceed */
5242 while (MM_IS_WAIT_PTE(Entry))
5243 {
5249 Entry = MmGetPageEntrySectionSegment(Segment, &SegmentOffset);
5250 }
5251
5252 /* We are called from Cc, this can't be backed by the page files */
5254
5255 /* If there is no page there, there is nothing to make dirty */
5256 if (Entry != 0)
5257 {
5258 /* Dirtify the entry */
5260 }
5261
5262 SegmentOffset.QuadPart += PAGE_SIZE;
5263 }
5264
5266
5268 return STATUS_SUCCESS;
5269}
#define KeDelayExecutionThread(mode, foo, t)
Definition: env_spec_w32.h:484
#define DIRTY_SSE(E)
Definition: mm.h:1375
#define MM_IS_WAIT_PTE(E)
Definition: mm.h:1370
#define STATUS_NOT_MAPPED_VIEW
Definition: ntstatus.h:262
static LARGE_INTEGER TinyTime
Definition: section.c:63
#define MmSetPageEntrySectionSegment(S, O, E)
Definition: section.c:56

Referenced by CcCopyWrite(), CcSetDirtyPinnedData(), and CcZeroData().

◆ MmMapViewInSystemSpaceEx()

NTSTATUS NTAPI MmMapViewInSystemSpaceEx ( _In_ PVOID  Section,
_Outptr_result_bytebuffer_ *ViewSize PVOID MappedBase,
_Inout_ PSIZE_T  ViewSize,
_Inout_ PLARGE_INTEGER  SectionOffset,
_In_ ULONG_PTR  Flags 
)

Definition at line 4460 of file section.c.

4467{
4468 PSECTION Section = SectionObject;
4472
4474
4475 PAGED_CODE();
4476
4478 {
4480 &MmSession,
4481 MappedBase,
4482 ViewSize,
4484 }
4485
4486 DPRINT("MmMapViewInSystemSpaceEx() called\n");
4487
4488 /* unsupported for now */
4489 ASSERT(Section->u.Flags.Image == 0);
4490
4491 Section = SectionObject;
4493
4494 if (*ViewSize == 0)
4495 {
4496 LONGLONG MapSizeLL;
4497
4498 /* Page-align the mapping */
4499 SectionOffset->LowPart = PAGE_ROUND_DOWN(SectionOffset->LowPart);
4500
4501 if (!NT_SUCCESS(RtlLongLongSub(Section->SizeOfSection.QuadPart, SectionOffset->QuadPart, &MapSizeLL)))
4503
4504 if (!NT_SUCCESS(RtlLongLongToSIZET(MapSizeLL, ViewSize)))
4506 }
4507 else
4508 {
4509 LONGLONG HelperLL;
4510
4511 /* Get the map end */
4512 if (!NT_SUCCESS(RtlLongLongAdd(SectionOffset->QuadPart, *ViewSize, &HelperLL)))
4514
4515 /* Round it up, if needed */
4516 if (HelperLL % PAGE_SIZE)
4517 {
4518 if (!NT_SUCCESS(RtlLongLongAdd(HelperLL, PAGE_SIZE - (HelperLL % PAGE_SIZE), &HelperLL)))
4520 }
4521
4522 /* Now that we have the mapping end, we can align down its start */
4523 SectionOffset->LowPart = PAGE_ROUND_DOWN(SectionOffset->LowPart);
4524
4525 /* Get the new size */
4526 if (!NT_SUCCESS(RtlLongLongSub(HelperLL, SectionOffset->QuadPart, &HelperLL)))
4528
4529 if (!NT_SUCCESS(RtlLongLongToSIZET(HelperLL, ViewSize)))
4531 }
4532
4534
4536
4538
4540 Section->u.Flags.Image,
4541 Segment,
4542 MappedBase,
4543 *ViewSize,
4545 SectionOffset->QuadPart,
4546 SEC_RESERVE);
4547
4550
4551 return Status;
4552}
#define SEC_RESERVE
Definition: nt_native.h:1323
#define STATUS_INVALID_VIEW_SIZE
Definition: ntstatus.h:268
MMSESSION MmSession
Definition: section.c:107
NTSTATUS MiMapViewInSystemSpace(IN PVOID Section, IN PVOID Session, OUT PVOID *MappedBase, IN OUT PSIZE_T ViewSize, IN PLARGE_INTEGER SectionOffset)
static NTSTATUS MmMapViewOfSegment(PMMSUPPORT AddressSpace, BOOLEAN AsImage, PMM_SECTION_SEGMENT Segment, PVOID *BaseAddress, SIZE_T ViewSize, ULONG Protect, LONGLONG ViewOffset, ULONG AllocationType)
Definition: section.c:3362
_Must_inspect_result_ _Outptr_result_bytebuffer_ ViewSize PVOID * MappedBase
Definition: mmfuncs.h:492

Referenced by CcRosCreateVacb(), and MmMapViewInSystemSpace().

◆ MmNotPresentFaultSectionView()

NTSTATUS NTAPI MmNotPresentFaultSectionView ( PMMSUPPORT  AddressSpace,
MEMORY_AREA MemoryArea,
PVOID  Address,
BOOLEAN  Locked 
)

Definition at line 1532 of file section.c.

1536{
1542 ULONG_PTR Entry1;
1545 BOOLEAN HasSwapEntry;
1546 PVOID PAddress;
1548 SWAPENTRY SwapEntry;
1549
1550 ASSERT(Locked);
1551
1552 /*
1553 * There is a window between taking the page fault and locking the
1554 * address space when another thread could load the page so we check
1555 * that.
1556 */
1558 {
1559 return STATUS_SUCCESS;
1560 }
1561
1563 {
1565 }
1566
1567 /*
1568 * Check for the virtual memory area being deleted.
1569 */
1571 {
1572 return STATUS_UNSUCCESSFUL;
1573 }
1574
1575 PAddress = MM_ROUND_DOWN(Address, PAGE_SIZE);
1576 Offset.QuadPart = (ULONG_PTR)PAddress - MA_GetStartingAddress(MemoryArea)
1577 + MemoryArea->SectionData.ViewOffset;
1578
1579 Segment = MemoryArea->SectionData.Segment;
1581 &MemoryArea->SectionData.RegionListHead,
1582 Address, NULL);
1583 ASSERT(Region != NULL);
1584
1585 /* Check for a NOACCESS mapping */
1586 if (Region->Protect & PAGE_NOACCESS)
1587 {
1589 }
1590
1591 if (Region->Protect & PAGE_GUARD)
1592 {
1593 /* Remove it */
1595 &MemoryArea->SectionData.RegionListHead,
1596 Address, PAGE_SIZE, Region->Type, Region->Protect & ~PAGE_GUARD,
1598
1599 if (!NT_SUCCESS(Status))
1600 {
1601 DPRINT1("Removing PAGE_GUARD protection failed : 0x%08x.\n", Status);
1602 }
1603
1605 }
1606
1607 HasSwapEntry = MmIsPageSwapEntry(Process, Address);
1608
1609 /* See if we should use a private page */
1610 if (HasSwapEntry)
1611 {
1612 SWAPENTRY DummyEntry;
1613
1614 MmGetPageFileMapping(Process, Address, &SwapEntry);
1615 if (SwapEntry == MM_WAIT_ENTRY)
1616 {
1621 }
1622
1624 if (Process) MI_SET_PROCESS2(Process->ImageFileName);
1625 if (!Process) MI_SET_PROCESS2("Kernel Section");
1627 if (!NT_SUCCESS(Status))
1628 {
1629 return STATUS_NO_MEMORY;
1630 }
1631
1632 /*
1633 * Must be private page we have swapped out.
1634 */
1635
1636 /*
1637 * Sanity check
1638 */
1640 ASSERT(DummyEntry == SwapEntry);
1641
1642 /* Tell everyone else we are serving the fault. */
1643 MmCreatePageFileMapping(Process, Address, MM_WAIT_ENTRY);
1644
1646
1647 Status = MmReadFromSwapPage(SwapEntry, Page);
1648 if (!NT_SUCCESS(Status))
1649 {
1650 DPRINT1("MmReadFromSwapPage failed, status = %x\n", Status);
1651 KeBugCheck(MEMORY_MANAGEMENT);
1652 }
1653
1655 MmDeletePageFileMapping(Process, PAddress, &DummyEntry);
1656 ASSERT(DummyEntry == MM_WAIT_ENTRY);
1657
1659 PAddress,
1660 Region->Protect,
1661 Page);
1662 if (!NT_SUCCESS(Status))
1663 {
1664 DPRINT("MmCreateVirtualMapping failed, not out of memory\n");
1665 KeBugCheck(MEMORY_MANAGEMENT);
1666 return Status;
1667 }
1668
1669 /*
1670 * Store the swap entry for later use.
1671 */
1672 MmSetSavedSwapEntryPage(Page, SwapEntry);
1673
1674 /*
1675 * Add the page to the process's working set
1676 */
1678 /*
1679 * Finish the operation
1680 */
1681 DPRINT("Address 0x%p\n", Address);
1682 return STATUS_SUCCESS;
1683 }
1684
1685 /*
1686 * Lock the segment
1687 */
1689
1690 /*
1691 * Satisfying a page fault on a map of /Device/PhysicalMemory is easy
1692 */
1693 if ((*Segment->Flags) & MM_PHYSICALMEMORY_SEGMENT)
1694 {
1696 /*
1697 * Just map the desired physical page
1698 */
1699 Page = (PFN_NUMBER)(Offset.QuadPart >> PAGE_SHIFT);
1701 PAddress,
1702 Region->Protect,
1703 Page);
1704 if (!NT_SUCCESS(Status))
1705 {
1706 DPRINT("MmCreateVirtualMappingUnsafe failed, not out of memory\n");
1707 KeBugCheck(MEMORY_MANAGEMENT);
1708 return Status;
1709 }
1710
1711 /*
1712 * Cleanup and release locks
1713 */
1714 DPRINT("Address 0x%p\n", Address);
1715 return STATUS_SUCCESS;
1716 }
1717
1718 /*
1719 * Check if this page needs to be mapped COW
1720 */
1721 if ((Segment->WriteCopy) &&
1722 (Region->Protect == PAGE_READWRITE || Region->Protect == PAGE_EXECUTE_READWRITE))
1723 {
1725 }
1726 else
1727 {
1728 Attributes = Region->Protect;
1729 }
1730
1731
1732 /*
1733 * Get the entry corresponding to the offset within the section
1734 */
1736 if (Entry == 0)
1737 {
1738 /*
1739 * If the entry is zero, then we need to load the page.
1740 */
1741 if ((Offset.QuadPart >= (LONGLONG)PAGE_ROUND_UP(Segment->RawLength.QuadPart)) && (MemoryArea->VadNode.u.VadFlags.VadType == VadImageMap))
1742 {
1743 /* We are beyond the data which is on file. Just get a new page. */
1745 if (Process) MI_SET_PROCESS2(Process->ImageFileName);
1746 if (!Process) MI_SET_PROCESS2("Kernel Section");
1748 if (!NT_SUCCESS(Status))
1749 {
1751 return STATUS_NO_MEMORY;
1752 }
1755
1757 if (!NT_SUCCESS(Status))
1758 {
1759 DPRINT1("Unable to create virtual mapping\n");
1760 KeBugCheck(MEMORY_MANAGEMENT);
1761 }
1762 ASSERT(MmIsPagePresent(Process, PAddress));
1763 if (Process)
1765
1766 DPRINT("Address 0x%p\n", Address);
1767 return STATUS_SUCCESS;
1768 }
1769
1772
1773 /* The data must be paged in. Lock the file, so that the VDL doesn't get updated behind us. */
1775
1776 PFSRTL_COMMON_FCB_HEADER FcbHeader = Segment->FileObject->FsContext;
1777
1779
1780 FsRtlReleaseFile(Segment->FileObject);
1781
1782 /* Lock address space again */
1784 if (!NT_SUCCESS(Status))
1785 {
1786 if (Status == STATUS_NO_MEMORY)
1787 {
1788 return Status;
1789 }
1790 /* Damn */
1791 DPRINT1("Failed to page data in!\n");
1792 return STATUS_IN_PAGE_ERROR;
1793 }
1794
1795 /* Everything went fine. Restart the operation */
1797 }
1798 else if (IS_SWAP_FROM_SSE(Entry))
1799 {
1800 SWAPENTRY SwapEntry;
1801
1802 SwapEntry = SWAPENTRY_FROM_SSE(Entry);
1803
1804 /* See if a page op is running on this segment. */
1805 if (SwapEntry == MM_WAIT_ENTRY)
1806 {
1812 }
1813
1815 if (!NT_SUCCESS(Status))
1816 {
1818 return STATUS_NO_MEMORY;
1819 }
1820
1821 /*
1822 * Release all our locks and read in the page from disk
1823 */
1826
1828
1829 Status = MmReadFromSwapPage(SwapEntry, Page);
1830 if (!NT_SUCCESS(Status))
1831 {
1832 KeBugCheck(MEMORY_MANAGEMENT);
1833 }
1834
1835 /*
1836 * Relock the address space and segment
1837 */
1840
1841 /*
1842 * Check the entry. No one should change the status of a page
1843 * that has a pending page-in.
1844 */
1846 if (Entry1 != MAKE_SWAP_SSE(MM_WAIT_ENTRY))
1847 {
1848 DPRINT1("Someone changed ppte entry while we slept (%x vs %x)\n", Entry, Entry1);
1849 KeBugCheck(MEMORY_MANAGEMENT);
1850 }
1851
1852 /*
1853 * Save the swap entry.
1854 */
1855 MmSetSavedSwapEntryPage(Page, SwapEntry);
1856
1857 /* Map the page into the process address space */
1859 PAddress,
1860 Attributes,
1861 Page);
1862 if (!NT_SUCCESS(Status))
1863 {
1864 DPRINT1("Unable to create virtual mapping\n");
1865 KeBugCheck(MEMORY_MANAGEMENT);
1866 }
1867 if (Process)
1869
1870 /*
1871 * Mark the offset within the section as having valid, in-memory
1872 * data
1873 */
1874 Entry = MAKE_SSE(Page << PAGE_SHIFT, 1);
1877
1878 DPRINT("Address 0x%p\n", Address);
1879 return STATUS_SUCCESS;
1880 }
1881 else
1882 {
1883 /* We already have a page on this section offset. Map it into the process address space. */
1885
1887 PAddress,
1888 Attributes,
1889 Page);
1890 if (!NT_SUCCESS(Status))
1891 {
1892 DPRINT1("Unable to create virtual mapping\n");
1893 KeBugCheck(MEMORY_MANAGEMENT);
1894 }
1895
1896 if (Process)
1898
1899 /* Take a reference on it */
1902
1903 DPRINT("Address 0x%p\n", Address);
1904 return STATUS_SUCCESS;
1905 }
1906}
#define PAGE_GUARD
Definition: nt_native.h:1310
VOID NTAPI FsRtlReleaseFile(IN PFILE_OBJECT FileObject)
Definition: fastio.c:1659
VOID NTAPI FsRtlAcquireFileExclusive(IN PFILE_OBJECT FileObject)
Definition: fastio.c:1634
VOID NTAPI MmGetPageFileMapping(PEPROCESS Process, PVOID Address, SWAPENTRY *SwapEntry)
Definition: page.c:299
#define MAKE_SSE(P, C)
Definition: mm.h:1387
BOOLEAN NTAPI MmIsDisabledPage(struct _EPROCESS *Process, PVOID Address)
#define SWAPENTRY_FROM_SSE(E)
Definition: mm.h:1373
#define MAKE_SWAP_SSE(S)
Definition: mm.h:1374
NTSTATUS NTAPI MmReadFromSwapPage(SWAPENTRY SwapEntry, PFN_NUMBER Page)
Definition: pagefile.c:204
VOID NTAPI MmSetSavedSwapEntryPage(PFN_NUMBER Page, SWAPENTRY SavedSwapEntry)
Definition: freelist.c:483
NTSTATUS NTAPI MmCreatePhysicalMapping(_Inout_opt_ PEPROCESS Process, _In_ PVOID Address, _In_ ULONG flProtect, _In_ PFN_NUMBER Page)
Definition: page.c:735
NTSTATUS NTAPI MmCreatePageFileMapping(struct _EPROCESS *Process, PVOID Address, SWAPENTRY SwapEntry)
#define STATUS_MM_RESTART_OPERATION
Definition: mm.h:104
#define STATUS_IN_PAGE_ERROR
Definition: ntstatus.h:243
#define STATUS_GUARD_PAGE_VIOLATION
Definition: ntstatus.h:182
PFN_NUMBER Page
Definition: section.c:5034
VOID NTAPI MmSharePageEntrySectionSegment(PMM_SECTION_SEGMENT Segment, PLARGE_INTEGER Offset)
Definition: section.c:1064
LARGE_INTEGER ValidDataLength
Definition: env_spec_w32.h:757
_Must_inspect_result_ _In_ WDFDMAENABLER _In_ _In_opt_ PWDF_OBJECT_ATTRIBUTES Attributes

Referenced by MmAccessFaultSectionView(), and MmNotPresentFault().

◆ MmPageFault()

NTSTATUS NTAPI MmPageFault ( ULONG  Cs,
PULONG  Eip,
PULONG  Eax,
ULONG  Cr2,
ULONG  ErrorCode 
)

◆ MmPageOutPhysicalAddress()

NTSTATUS NTAPI MmPageOutPhysicalAddress ( PFN_NUMBER  Page)

Definition at line 51 of file rmap.c.

52{
60 LARGE_INTEGER SegmentOffset;
62
63GetEntry:
64 OldIrql = MiAcquirePfnLock();
65
67
68 while (entry && RMAP_IS_SEGMENT(entry->Address))
69 entry = entry->Next;
70
71 if (entry == NULL)
72 {
73 MiReleasePfnLock(OldIrql);
74 goto WriteSegment;
75 }
76
77 Process = entry->Process;
78 Address = entry->Address;
79
80 if ((((ULONG_PTR)Address) & 0xFFF) != 0)
81 {
82 KeBugCheck(MEMORY_MANAGEMENT);
83 }
84
85 /* This is for user-mode address only */
87
88 if (!ExAcquireRundownProtection(&Process->RundownProtect))
89 {
90 MiReleasePfnLock(OldIrql);
92 }
93
95 MiReleasePfnLock(OldIrql);
96 if (!NT_SUCCESS(Status))
97 {
98 ExReleaseRundownProtection(&Process->RundownProtect);
99 return Status;
100 }
101 AddressSpace = &Process->Vm;
102
104
107 {
109 ExReleaseRundownProtection(&Process->RundownProtect);
111 goto GetEntry;
112 }
113
114
115 /* Attach to it, if needed */
119
121 {
122 /* This changed in the short window where we didn't have any locks */
126 ExReleaseRundownProtection(&Process->RundownProtect);
128 goto GetEntry;
129 }
130
132 {
134 BOOLEAN Dirty;
135 PFN_NUMBER MapPage;
137 BOOLEAN Released;
138 BOOLEAN Unmapped;
139
140 Offset.QuadPart = MemoryArea->SectionData.ViewOffset +
142
143 Segment = MemoryArea->SectionData.Segment;
144
146
148 if (Entry && MM_IS_WAIT_PTE(Entry))
149 {
150 /* The segment is being read or something. Give up */
155 ExReleaseRundownProtection(&Process->RundownProtect);
157 return(STATUS_UNSUCCESSFUL);
158 }
159
160 /* Delete this virtual mapping in the process */
162 Unmapped = MmDeleteVirtualMapping(Process, Address, &Dirty, &MapPage);
163 if (!Unmapped || (MapPage != Page))
164 {
165 /*
166 * Something's corrupted, we got there because this process is
167 * supposed to be mapping this page there.
168 */
169 KeBugCheckEx(MEMORY_MANAGEMENT,
172 (ULONG_PTR)__FILE__,
173 __LINE__);
174 }
175
176 if (Page != PFN_FROM_SSE(Entry))
177 {
178 SWAPENTRY SwapEntry;
179
180 /* This page is private to the process */
182
183 /* Check if we should write it back to the page file */
184 SwapEntry = MmGetSavedSwapEntryPage(Page);
185
186 if ((SwapEntry == 0) && Dirty)
187 {
188 /* We don't have a Swap entry, yet the page is dirty. Get one */
189 SwapEntry = MmAllocSwapPage();
190 if (!SwapEntry)
191 {
193 &MemoryArea->SectionData.RegionListHead,
194 Address, NULL);
195
196 /* We can't, so let this page in the Process VM */
200
204 ExReleaseRundownProtection(&Process->RundownProtect);
206
207 return STATUS_UNSUCCESSFUL;
208 }
209 }
210
211 if (Dirty)
212 {
213 SWAPENTRY Dummy;
214
215 /* Put a wait entry into the process and unlock */
216 MmCreatePageFileMapping(Process, Address, MM_WAIT_ENTRY);
218
219 Status = MmWriteToSwapPage(SwapEntry, Page);
220
223 ASSERT(Dummy == MM_WAIT_ENTRY);
224
225 if (!NT_SUCCESS(Status))
226 {
227 /* We failed at saving the content of this page. Keep it in */
229 &MemoryArea->SectionData.RegionListHead,
230 Address, NULL);
231
232 /* This Swap Entry is useless to us */
234 MmFreeSwapPage(SwapEntry);
235
236 /* We can't, so let this page in the Process VM */
240
244 ExReleaseRundownProtection(&Process->RundownProtect);
246
247 return STATUS_UNSUCCESSFUL;
248 }
249 }
250
251 if (SwapEntry)
252 {
253 /* Keep this in the process VM */
256 }
257
258 /* We can finally let this page go */
262#if DBG
263 OldIrql = MiAcquirePfnLock();
265 MiReleasePfnLock(OldIrql);
266#endif
268
269 ExReleaseRundownProtection(&Process->RundownProtect);
271
272 return STATUS_SUCCESS;
273 }
274
275 /* One less mapping referencing this segment */
277
282
283 ExReleaseRundownProtection(&Process->RundownProtect);
285
286 if (Released) return STATUS_SUCCESS;
287 }
288#ifdef NEWCC
289 else if (Type == MEMORY_AREA_CACHE)
290 {
291 /* NEWCC does locking itself */
294 }
295#endif
296 else
297 {
298 KeBugCheck(MEMORY_MANAGEMENT);
299 }
300
301WriteSegment:
302 /* Now write this page to file, if needed */
303 Segment = MmGetSectionAssociation(Page, &SegmentOffset);
304 if (Segment)
305 {
306 BOOLEAN Released;
307
309
310 Released = MmCheckDirtySegment(Segment, &SegmentOffset, FALSE, TRUE);
311
313 MmDereferenceSegment(Segment);
314
315 if (Released)
316 {
317 return STATUS_SUCCESS;
318 }
319 }
320
321 /* If we are here, then we didn't release the page */
322 return STATUS_UNSUCCESSFUL;
323}
NTSTATUS NTAPI MmpPageOutPhysicalAddress(PFN_NUMBER Page)
Definition: swapout.c:345
#define PROCESS_ALL_ACCESS
Definition: nt_native.h:1324
#define MmSetDirtyPage(__P, __A)
Definition: mm.h:1252
struct _MM_RMAP_ENTRY *NTAPI MmGetRmapListHeadPage(PFN_NUMBER Page)
Definition: freelist.c:458
#define RMAP_IS_SEGMENT(x)
Definition: mm.h:940
BOOLEAN NTAPI MmUnsharePageEntrySectionSegment(PMEMORY_AREA MemoryArea, PMM_SECTION_SEGMENT Segment, PLARGE_INTEGER Offset, BOOLEAN Dirty, BOOLEAN PageOut, ULONG_PTR *InEntry)
Definition: section.c:1089
SWAPENTRY NTAPI MmAllocSwapPage(VOID)
Definition: pagefile.c:322
NTSTATUS NTAPI MmWriteToSwapPage(SWAPENTRY SwapEntry, PFN_NUMBER Page)
Definition: pagefile.c:147
VOID NTAPI MmFreeSwapPage(SWAPENTRY Entry)
Definition: pagefile.c:291
SWAPENTRY NTAPI MmGetSavedSwapEntryPage(PFN_NUMBER Page)
Definition: freelist.c:499
NTSTATUS NTAPI MmReleasePageMemoryConsumer(ULONG Consumer, PFN_NUMBER Page)
Definition: balance.c:72
NTSTATUS NTAPI ObReferenceObjectByPointer(IN PVOID Object, IN ACCESS_MASK DesiredAccess, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode)
Definition: obref.c:381
VOID NTAPI MmInsertRmap(PFN_NUMBER Page, PEPROCESS Process, PVOID Address)
Definition: rmap.c:327
VOID NTAPI MmDeleteRmap(PFN_NUMBER Page, PEPROCESS Process, PVOID Address)
Definition: rmap.c:413
PMM_SECTION_SEGMENT NTAPI MmGetSectionAssociation(PFN_NUMBER Page, PLARGE_INTEGER Offset)
Definition: sptab.c:374

Referenced by CcRosTrimCache(), and MmTrimUserMemory().

◆ MmPageOutSectionView()

NTSTATUS NTAPI MmPageOutSectionView ( PMMSUPPORT  AddressSpace,
PMEMORY_AREA  MemoryArea,
PVOID  Address,
ULONG_PTR  Entry 
)

◆ MmProtectSectionView()

NTSTATUS NTAPI MmProtectSectionView ( PMMSUPPORT  AddressSpace,
PMEMORY_AREA  MemoryArea,
PVOID  BaseAddress,
SIZE_T  Length,
ULONG  Protect,
PULONG  OldProtect 
)

Definition at line 2063 of file section.c.

2069{
2072 ULONG_PTR MaxLength;
2073
2075 if (Length > MaxLength)
2076 Length = (ULONG)MaxLength;
2077
2079 &MemoryArea->SectionData.RegionListHead,
2080 BaseAddress, NULL);
2081 ASSERT(Region != NULL);
2082
2083 if ((MemoryArea->Flags & SEC_NO_CHANGE) &&
2084 Region->Protect != Protect)
2085 {
2087 }
2088
2089 *OldProtect = Region->Protect;
2091 &MemoryArea->SectionData.RegionListHead,
2094
2095 return Status;
2096}
#define SEC_NO_CHANGE
Definition: mmtypes.h:95
#define STATUS_INVALID_PAGE_PROTECTION
Definition: ntstatus.h:305

Referenced by MiRosProtectVirtualMemory().

◆ MmPurgeSegment()

BOOLEAN NTAPI MmPurgeSegment ( _In_ PSECTION_OBJECT_POINTERS  SectionObjectPointer,
_In_opt_ PLARGE_INTEGER  Offset,
_In_ ULONG  Length 
)

Definition at line 4828 of file section.c.

4832{
4833 LARGE_INTEGER PurgeStart, PurgeEnd;
4835
4837 if (!Segment)
4838 {
4839 /* Nothing to purge */
4840 return TRUE;
4841 }
4842
4843 PurgeStart.QuadPart = Offset ? Offset->QuadPart : 0LL;
4844 if (Length && Offset)
4845 {
4846 if (!NT_SUCCESS(RtlLongLongAdd(PurgeStart.QuadPart, Length, &PurgeEnd.QuadPart)))
4847 return FALSE;
4848 }
4849
4851
4852 if (!Length || !Offset)
4853 {
4854 /* We must calculate the length for ourselves */
4855 /* FIXME: All of this is suboptimal */
4856 ULONG ElemCount = RtlNumberGenericTableElements(&Segment->PageTable);
4857 /* No page. Nothing to purge */
4858 if (!ElemCount)
4859 {
4861 MmDereferenceSegment(Segment);
4862 return TRUE;
4863 }
4864
4866 PurgeEnd.QuadPart = PageTable->FileOffset.QuadPart + _countof(PageTable->PageEntries) * PAGE_SIZE;
4867 }
4868
4869 while (PurgeStart.QuadPart < PurgeEnd.QuadPart)
4870 {
4872
4873 if (Entry == 0)
4874 {
4875 PurgeStart.QuadPart += PAGE_SIZE;
4876 continue;
4877 }
4878
4880 {
4881 ASSERT(SWAPENTRY_FROM_SSE(Entry) == MM_WAIT_ENTRY);
4882 /* The page is currently being read. Meaning someone will need it soon. Bad luck */
4884 MmDereferenceSegment(Segment);
4885 return FALSE;
4886 }
4887
4888 if (IS_WRITE_SSE(Entry))
4889 {
4890 /* We're trying to purge an entry which is being written. Restart this loop iteration */
4894 continue;
4895 }
4896
4897 if (SHARE_COUNT_FROM_SSE(Entry) > 0)
4898 {
4899 /* This page is currently in use. Bad luck */
4901 MmDereferenceSegment(Segment);
4902 return FALSE;
4903 }
4904
4905 /* We can let this page go */
4906 MmSetPageEntrySectionSegment(Segment, &PurgeStart, 0);
4908
4909 PurgeStart.QuadPart += PAGE_SIZE;
4910 }
4911
4912 /* This page is currently in use. Bad luck */
4914 MmDereferenceSegment(Segment);
4915 return TRUE;
4916}
#define SHARE_COUNT_FROM_SSE(E)
Definition: mm.h:1385
#define IS_WRITE_SSE(E)
Definition: mm.h:1379
#define LL
Definition: tui.h:167

Referenced by CcPurgeCacheSection().

◆ MmQuerySectionView()

NTSTATUS NTAPI MmQuerySectionView ( PMEMORY_AREA  MemoryArea,
PVOID  Address,
PMEMORY_BASIC_INFORMATION  Info,
PSIZE_T  ResultLength 
)

Definition at line 2099 of file section.c.

2103{
2105 PVOID RegionBaseAddress;
2107
2109 &MemoryArea->SectionData.RegionListHead,
2110 Address, &RegionBaseAddress);
2111 if (Region == NULL)
2112 {
2113 return STATUS_UNSUCCESSFUL;
2114 }
2115
2117 {
2118 Segment = MemoryArea->SectionData.Segment;
2119 Info->AllocationBase = (PUCHAR)MA_GetStartingAddress(MemoryArea) - Segment->Image.VirtualAddress;
2120 Info->Type = MEM_IMAGE;
2121 }
2122 else
2123 {
2124 Info->AllocationBase = (PVOID)MA_GetStartingAddress(MemoryArea);
2125 Info->Type = MEM_MAPPED;
2126 }
2127 Info->BaseAddress = RegionBaseAddress;
2129 Info->RegionSize = Region->Length;
2130 Info->State = MEM_COMMIT;
2131 Info->Protect = Region->Protect;
2132
2134 return STATUS_SUCCESS;
2135}
#define MEM_IMAGE
Definition: mmtypes.h:89
struct _MEMORY_BASIC_INFORMATION MEMORY_BASIC_INFORMATION
#define MEM_MAPPED
Definition: nt_native.h:1319
#define MEM_COMMIT
Definition: nt_native.h:1313
const ULONG MmProtectToValue[32]
Definition: page.c:71
ULONG_PTR Protection
Definition: mmtypes.h:696
_Must_inspect_result_ _In_ WDFCHILDLIST _In_ PWDF_CHILD_LIST_ITERATOR _Out_ WDFDEVICE _Inout_opt_ PWDF_CHILD_RETRIEVE_INFO Info
Definition: wdfchildlist.h:690
_Must_inspect_result_ _In_ WDFDEVICE _In_ DEVICE_REGISTRY_PROPERTY _In_ ULONG _Out_ PULONG ResultLength
Definition: wdfdevice.h:3776

Referenced by MiQueryMemoryBasicInformation().

◆ MmQuitNextSession()

VOID NTAPI MmQuitNextSession ( _Inout_ PVOID  SessionEntry)

Definition at line 1030 of file session.c.

1032{
1033 PEPROCESS EntryProcess;
1034
1035 /* The parameter is the actual process! */
1036 EntryProcess = SessionEntry;
1037 ASSERT(EntryProcess != NULL);
1038
1039 /* Sanity checks */
1041 ASSERT(EntryProcess->Vm.Flags.SessionLeader == 0);
1042 ASSERT(EntryProcess->Session != NULL);
1043
1044 /* Get rid of the reference we took */
1045 ObDereferenceObject(EntryProcess);
1046}
#define APC_LEVEL
Definition: env_spec_w32.h:695
PVOID Session
Definition: pstypes.h:1325
ULONG SessionLeader
Definition: mmtypes.h:907
MMSUPPORT_FLAGS Flags
Definition: mmtypes.h:933

Referenced by ExpWin32SessionCallout().

◆ MmReadFromSwapPage()

NTSTATUS NTAPI MmReadFromSwapPage ( SWAPENTRY  SwapEntry,
PFN_NUMBER  Page 
)

Definition at line 204 of file pagefile.c.

205{
206 return MiReadPageFile(Page, FILE_FROM_ENTRY(SwapEntry), OFFSET_FROM_ENTRY(SwapEntry));
207}
NTSTATUS NTAPI MiReadPageFile(_In_ PFN_NUMBER Page, _In_ ULONG PageFileIndex, _In_ ULONG_PTR PageFileOffset)
Definition: pagefile.c:211

Referenced by MiSwapInPage(), and MmNotPresentFaultSectionView().

◆ MmRebalanceMemoryConsumers()

VOID NTAPI MmRebalanceMemoryConsumers ( VOID  )

Definition at line 290 of file balance.c.

291{
292 // if (InterlockedCompareExchange(&PageOutThreadActive, 0, 1) == 0)
293 {
295 }
296}
#define KeSetEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:476
#define IO_NO_INCREMENT
Definition: iotypes.h:598

Referenced by MiDecrementAvailablePages(), and MmRebalanceMemoryConsumersAndWait().

◆ MmReferencePage()

VOID NTAPI MmReferencePage ( PFN_NUMBER  Page)

Definition at line 518 of file freelist.c.

519{
520 PMMPFN Pfn1;
521
522 DPRINT("MmReferencePage(PysicalAddress %x)\n", Pfn << PAGE_SHIFT);
523
525 ASSERT(Pfn != 0);
527
528 Pfn1 = MiGetPfnEntry(Pfn);
529 ASSERT(Pfn1);
530 ASSERT_IS_ROS_PFN(Pfn1);
531
532 ASSERT(Pfn1->u3.e2.ReferenceCount != 0);
533 Pfn1->u3.e2.ReferenceCount++;
534}

Referenced by MmGetLRUFirstUserPage(), and MmGetLRUNextUserPage().

◆ MmReleasePageMemoryConsumer()

NTSTATUS NTAPI MmReleasePageMemoryConsumer ( ULONG  Consumer,
PFN_NUMBER  Page 
)

◆ MmRequestPageMemoryConsumer()

NTSTATUS NTAPI MmRequestPageMemoryConsumer ( ULONG  Consumer,
BOOLEAN  MyWait,
PPFN_NUMBER  AllocatedPage 
)

Definition at line 313 of file balance.c.

315{
317 static INT i = 0;
318 static LARGE_INTEGER TinyTime = {{-1L, -1L}};
319
320 /* Delay some requests for the Memory Manager to recover pages */
321 if (i++ >= 100)
322 {
324 i = 0;
325 }
326
327 /*
328 * Actually allocate the page.
329 */
330 Page = MmAllocPage(Consumer);
331 if (Page == 0)
332 {
333 *AllocatedPage = 0;
334 return STATUS_NO_MEMORY;
335 }
336 *AllocatedPage = Page;
337
338 /* Update the target */
339 InterlockedIncrementUL(&MiMemoryConsumers[Consumer].PagesUsed);
341
342 return(STATUS_SUCCESS);
343}
#define InterlockedIncrementUL(Addend)
Definition: ex.h:1527
PFN_NUMBER NTAPI MmAllocPage(ULONG Consumer)
Definition: freelist.c:601
int32_t INT
Definition: typedefs.h:58

Referenced by CcInitCacheZeroPage(), MiGetOnePage(), MiGetPageTableForProcess(), MiReadFilePage(), MiSwapInPage(), MmAccessFaultSectionView(), MmCreateProcessAddressSpace(), MmGetPageTableForProcess(), MmGetPageTableForProcessForPAE(), MmMakeSegmentResident(), and MmNotPresentFaultSectionView().

◆ MmSetCleanPage()

VOID NTAPI MmSetCleanPage ( struct _EPROCESS Process,
PVOID  Address 
)

◆ MmSetDirtyBit()

VOID NTAPI MmSetDirtyBit ( PEPROCESS  Process,
PVOID  Address,
BOOLEAN  Bit 
)

Definition at line 890 of file page.c.

891{
892 PMMPTE PointerPte;
893
894 DPRINT("MmSetDirtyBit(Process %p Address %p Bit %x)\n",
895 Process, Address, Bit);
896
897 ASSERT(Process != NULL);
899
901
903
905
906 PointerPte = MiAddressToPte(Address);
907 // We shouldnl't set dirty bit on non-mapped addresses
908 if (!PointerPte->u.Hard.Valid && (FlagOn(PointerPte->u.Long, 0x800) || (PointerPte->u.Hard.PageFrameNumber == 0)))
909 {
910 DPRINT1("Invalid Pte %lx\n", PointerPte->u.Long);
911 KeBugCheck(MEMORY_MANAGEMENT);
912 }
913
914 PointerPte->u.Hard.Dirty = !!Bit;
915
916 if (!Bit)
918
920}
VOID NTAPI MiMakePdeExistAndMakeValid(IN PMMPDE PointerPde, IN PEPROCESS TargetProcess, IN KIRQL OldIrql)
Definition: virtual.c:2479
FORCEINLINE VOID KeInvalidateTlbEntry(IN PVOID Address)
Definition: ke.h:264
ULONG64 Dirty
Definition: mmtypes.h:164
ULONG_PTR Long
Definition: mmtypes.h:215

◆ MmSetExecuteOptions()

NTSTATUS NTAPI MmSetExecuteOptions ( IN ULONG  ExecuteOptions)

Definition at line 2695 of file pagfault.c.

2696{
2697 PKPROCESS CurrentProcess = &PsGetCurrentProcess()->Pcb;
2698 KLOCK_QUEUE_HANDLE ProcessLock;
2701
2702 /* Only accept valid flags */
2703 if (ExecuteOptions & ~MEM_EXECUTE_OPTION_VALID_FLAGS)
2704 {
2705 /* Fail */
2706 DPRINT1("Invalid no-execute options\n");
2708 }
2709
2710 /* Change the NX state in the process lock */
2711 KiAcquireProcessLockRaiseToSynch(CurrentProcess, &ProcessLock);
2712
2713 /* Don't change anything if the permanent flag was set */
2714 if (!CurrentProcess->Flags.Permanent)
2715 {
2716 /* Start by assuming it's not disabled */
2717 CurrentProcess->Flags.ExecuteDisable = FALSE;
2718
2719 /* Now process each flag and turn the equivalent bit on */
2720 if (ExecuteOptions & MEM_EXECUTE_OPTION_DISABLE)
2721 {
2722 CurrentProcess->Flags.ExecuteDisable = TRUE;
2723 }
2724 if (ExecuteOptions & MEM_EXECUTE_OPTION_ENABLE)
2725 {
2726 CurrentProcess->Flags.ExecuteEnable = TRUE;
2727 }
2728 if (ExecuteOptions & MEM_EXECUTE_OPTION_DISABLE_THUNK_EMULATION)
2729 {
2730 CurrentProcess->Flags.DisableThunkEmulation = TRUE;
2731 }
2732 if (ExecuteOptions & MEM_EXECUTE_OPTION_PERMANENT)
2733 {
2734 CurrentProcess->Flags.Permanent = TRUE;
2735 }
2736 if (ExecuteOptions & MEM_EXECUTE_OPTION_EXECUTE_DISPATCH_ENABLE)
2737 {
2738 CurrentProcess->Flags.ExecuteDispatchEnable = TRUE;
2739 }
2740 if (ExecuteOptions & MEM_EXECUTE_OPTION_IMAGE_DISPATCH_ENABLE)
2741 {
2742 CurrentProcess->Flags.ImageDispatchEnable = TRUE;
2743 }
2744
2745 /* These are turned on by default if no-execution is also enabled */
2746 if (CurrentProcess->Flags.ExecuteEnable)
2747 {
2748 CurrentProcess->Flags.ExecuteDispatchEnable = TRUE;
2749 CurrentProcess->Flags.ImageDispatchEnable = TRUE;
2750 }
2751
2752 /* All good */
2754 }
2755
2756 /* Release the lock and return status */
2757 KiReleaseProcessLock(&ProcessLock);
2758 return Status;
2759}
FORCEINLINE VOID KiReleaseProcessLock(IN PKLOCK_QUEUE_HANDLE Handle)
Definition: ke_x.h:660
FORCEINLINE VOID KiAcquireProcessLockRaiseToSynch(IN PKPROCESS Process, IN PKLOCK_QUEUE_HANDLE Handle)
Definition: ke_x.h:651
#define MEM_EXECUTE_OPTION_VALID_FLAGS
Definition: mmtypes.h:79
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145

Referenced by NtSetInformationProcess().

◆ MmSetMemoryPriorityProcess()

NTSTATUS NTAPI MmSetMemoryPriorityProcess ( IN PEPROCESS  Process,
IN UCHAR  MemoryPriority 
)

Definition at line 486 of file procsup.c.

488{
489 UCHAR OldPriority;
490
491 //
492 // Check if we have less then 16MB of Physical Memory
493 //
494 if ((MmSystemSize == MmSmallSystem) &&
495 (MmNumberOfPhysicalPages < ((15 * 1024 * 1024) / PAGE_SIZE)))
496 {
497 //
498 // Always use background priority
499 //
500 MemoryPriority = MEMORY_PRIORITY_BACKGROUND;
501 }
502
503 //
504 // Save the old priority and update it
505 //
506 OldPriority = (UCHAR)Process->Vm.Flags.MemoryPriority;
507 Process->Vm.Flags.MemoryPriority = MemoryPriority;
508
509 //
510 // Return the old priority
511 //
512 return OldPriority;
513}
#define MEMORY_PRIORITY_BACKGROUND
Definition: pstypes.h:124
MM_SYSTEMSIZE MmSystemSize
Definition: mminit.c:326
@ MmSmallSystem
Definition: mmtypes.h:145

Referenced by NtSetInformationProcess(), and PspComputeQuantumAndPriority().

◆ MmSetPageProtect()

VOID NTAPI MmSetPageProtect ( struct _EPROCESS Process,
PVOID  Address,
ULONG  flProtect 
)

◆ MmSetRmapListHeadPage()

VOID NTAPI MmSetRmapListHeadPage ( PFN_NUMBER  Page,
struct _MM_RMAP_ENTRY ListHead 
)

◆ MmSetSavedSwapEntryPage()

VOID NTAPI MmSetSavedSwapEntryPage ( PFN_NUMBER  Page,
SWAPENTRY  SavedSwapEntry 
)

Definition at line 483 of file freelist.c.

484{
485 KIRQL oldIrql;
486 PMMPFN Pfn1;
487
488 Pfn1 = MiGetPfnEntry(Pfn);
489 ASSERT(Pfn1);
490 ASSERT_IS_ROS_PFN(Pfn1);
491
492 oldIrql = MiAcquirePfnLock();
493 Pfn1->u1.SwapEntry = SwapEntry;
494 MiReleasePfnLock(oldIrql);
495}

Referenced by MiSwapInPage(), MmFinalizeSectionPageOut(), MmFreeCacheSectionPage(), MmFreeSectionPage(), MmNotPresentFaultSectionView(), MmPageOutPhysicalAddress(), MmpFreePageFileSegment(), and MmUnsharePageEntrySectionSegment().

◆ MmShowOutOfSpaceMessagePagingFile()

VOID NTAPI MmShowOutOfSpaceMessagePagingFile ( VOID  )

Definition at line 136 of file pagefile.c.

137{
139 {
140 DPRINT1("MM: Out of swap space.\n");
142 }
143}
static BOOLEAN MmSwapSpaceMessage
Definition: pagefile.c:103

◆ MmShutdownSystem()

VOID MmShutdownSystem ( IN ULONG  Phase)

Definition at line 77 of file shutdown.c.

78{
79 if (Phase == 0)
80 {
82 }
83 else if (Phase == 1)
84 {
85 ULONG i;
86
87 /* Loop through all the paging files */
88 for (i = 0; i < MmNumberOfPagingFiles; i++)
89 {
90 /* And dereference them */
92 }
93 }
94 else
95 {
96 ASSERT(Phase == 2);
97
99 }
100}
PMMPAGING_FILE MmPagingFile[MAX_PAGING_FILES]
Definition: pagefile.c:57
ULONG MmNumberOfPagingFiles
Definition: pagefile.c:63
VOID MiShutdownSystem(VOID)
Definition: shutdown.c:21

Referenced by PopGracefulShutdown().

◆ MmTrimUserMemory()

NTSTATUS MmTrimUserMemory ( ULONG  Target,
ULONG  Priority,
PULONG  NrFreedPages 
)

Definition at line 138 of file balance.c.

139{
140 PFN_NUMBER FirstPage, CurrentPage;
142
143 (*NrFreedPages) = 0;
144
145 DPRINT("MM BALANCER: %s\n", Priority ? "Paging out!" : "Removing access bit!");
146
147 FirstPage = MmGetLRUFirstUserPage();
148 CurrentPage = FirstPage;
149 while (CurrentPage != 0 && Target > 0)
150 {
151 if (Priority)
152 {
153 Status = MmPageOutPhysicalAddress(CurrentPage);
154 if (NT_SUCCESS(Status))
155 {
156 DPRINT("Succeeded\n");
157 Target--;
158 (*NrFreedPages)++;
159 if (CurrentPage == FirstPage)
160 {
161 FirstPage = 0;
162 }
163 }
164 }
165 else
166 {
167 /* When not paging-out agressively, just reset the accessed bit */
170 BOOLEAN Accessed = FALSE;
171
172 /*
173 * We have a lock-ordering problem here. We cant lock the PFN DB before the Process address space.
174 * So we must use circonvoluted loops.
175 * Well...
176 */
177 while (TRUE)
178 {
180 KIRQL OldIrql = MiAcquirePfnLock();
182 while (Entry)
183 {
184 if (RMAP_IS_SEGMENT(Entry->Address))
185 {
186 Entry = Entry->Next;
187 continue;
188 }
189
190 /* Check that we didn't treat this entry before */
191 if (Entry->Address < Address)
192 {
193 Entry = Entry->Next;
194 continue;
195 }
196
197 if ((Entry->Address == Address) && (Entry->Process <= Process))
198 {
199 Entry = Entry->Next;
200 continue;
201 }
202
203 break;
204 }
205
206 if (!Entry)
207 {
208 MiReleasePfnLock(OldIrql);
209 break;
210 }
211
212 Process = Entry->Process;
213 Address = Entry->Address;
214
216
217 if (!ExAcquireRundownProtection(&Process->RundownProtect))
218 {
220 MiReleasePfnLock(OldIrql);
221 continue;
222 }
223
224 MiReleasePfnLock(OldIrql);
225
228
229 /* Be sure this is still valid. */
231 {
233 Accessed = Accessed || Pte->u.Hard.Accessed;
234 Pte->u.Hard.Accessed = 0;
235
236 /* There is no need to invalidate, the balancer thread is never on a user process */
237 //KeInvalidateTlbEntry(Address);
238 }
239
241
243 ExReleaseRundownProtection(&Process->RundownProtect);
245 }
246
247 if (!Accessed)
248 {
249 /* Nobody accessed this page since the last time we check. Time to clean up */
250
251 Status = MmPageOutPhysicalAddress(CurrentPage);
252 if (NT_SUCCESS(Status))
253 {
254 if (CurrentPage == FirstPage)
255 {
256 FirstPage = 0;
257 }
258 }
259 // DPRINT1("Paged-out one page: %s\n", NT_SUCCESS(Status) ? "Yes" : "No");
260 }
261
262 /* Done for this page. */
263 Target--;
264 }
265
266 CurrentPage = MmGetLRUNextUserPage(CurrentPage, TRUE);
267 if (FirstPage == 0)
268 {
269 FirstPage = CurrentPage;
270 }
271 else if (CurrentPage == FirstPage)
272 {
273 DPRINT1("We are back at the start, abort!\n");
274 return STATUS_SUCCESS;
275 }
276 }
277
278 if (CurrentPage)
279 {
280 KIRQL OldIrql = MiAcquirePfnLock();
281 MmDereferencePage(CurrentPage);
282 MiReleasePfnLock(OldIrql);
283 }
284
285 return STATUS_SUCCESS;
286}
PFN_NUMBER NTAPI MmGetLRUFirstUserPage(VOID)
Definition: freelist.c:45
PFN_NUMBER NTAPI MmGetLRUNextUserPage(PFN_NUMBER PreviousPage, BOOLEAN MoveToLast)
Definition: freelist.c:125
NTSTATUS NTAPI MmPageOutPhysicalAddress(PFN_NUMBER Page)
Definition: rmap.c:51
ULONG64 Accessed
Definition: mmtypes.h:163
_In_ WDFIOTARGET Target
Definition: wdfrequest.h:306

Referenced by MmInitSystem().

◆ MmUnloadSystemImage()

NTSTATUS NTAPI MmUnloadSystemImage ( IN PVOID  ImageHandle)

Definition at line 944 of file sysldr.c.

945{
946 PLDR_DATA_TABLE_ENTRY LdrEntry = ImageHandle;
947 PVOID BaseAddress = LdrEntry->DllBase;
949 STRING TempName;
950 BOOLEAN HadEntry = FALSE;
951
952 /* Acquire the loader lock */
957 FALSE,
958 NULL);
959
960 /* Check if this driver was loaded at boot and didn't get imports parsed */
961 if (LdrEntry->LoadedImports == MM_SYSLDR_BOOT_LOADED) goto Done;
962
963 /* We should still be alive */
964 ASSERT(LdrEntry->LoadCount != 0);
965 LdrEntry->LoadCount--;
966
967 /* Check if we're still loaded */
968 if (LdrEntry->LoadCount) goto Done;
969
970 /* We should cleanup... are symbols loaded */
971 if (LdrEntry->Flags & LDRP_DEBUG_SYMBOLS_LOADED)
972 {
973 /* Create the ANSI name */
975 &LdrEntry->BaseDllName,
976 TRUE);
977 if (NT_SUCCESS(Status))
978 {
979 /* Unload the symbols */
980 DbgUnLoadImageSymbols(&TempName,
983 RtlFreeAnsiString(&TempName);
984 }
985 }
986
987 /* FIXME: Free the driver */
988 DPRINT1("Leaking driver: %wZ\n", &LdrEntry->BaseDllName);
989 //MmFreeSection(LdrEntry->DllBase);
990
991 /* Check if we're linked in */
992 if (LdrEntry->InLoadOrderLinks.Flink)
993 {
994 /* Remove us */
995 MiProcessLoaderEntry(LdrEntry, FALSE);
996 HadEntry = TRUE;
997 }
998
999 /* Dereference and clear the imports */
1001 MiClearImports(LdrEntry);
1002
1003 /* Check if the entry needs to go away */
1004 if (HadEntry)
1005 {
1006 /* Check if it had a name */
1007 if (LdrEntry->FullDllName.Buffer)
1008 {
1009 /* Free it */
1011 }
1012
1013 /* Check if we had a section */
1014 if (LdrEntry->SectionPointer)
1015 {
1016 /* Dereference it */
1018 }
1019
1020 /* Free the entry */
1022 }
1023
1024 /* Release the system lock and return */
1025Done:
1028 return STATUS_SUCCESS;
1029}
#define MM_SYSLDR_BOOT_LOADED
Definition: miarm.h:201
VOID NTAPI DbgUnLoadImageSymbols(_In_ PSTRING Name, _In_ PVOID Base, _In_ ULONG_PTR ProcessId)
NTSYSAPI NTSTATUS NTAPI RtlUnicodeStringToAnsiString(PANSI_STRING DestinationString, PUNICODE_STRING SourceString, BOOLEAN AllocateDestinationString)
NTSYSAPI VOID NTAPI RtlFreeAnsiString(PANSI_STRING AnsiString)
NTSTATUS NTAPI MiDereferenceImports(IN PLOAD_IMPORTS ImportList)
Definition: sysldr.c:526
VOID NTAPI MiClearImports(IN PLDR_DATA_TABLE_ENTRY LdrEntry)
Definition: sysldr.c:601

Referenced by IopDeleteDriver(), IopInitializeDriverModule(), LoadSymbolsRoutine(), MiCallDllUnloadAndUnloadDll(), MiResolveImageReferences(), and SSI_DEF().

◆ MmUnlockAddressSpace()

◆ MmUnsharePageEntrySectionSegment()

BOOLEAN NTAPI MmUnsharePageEntrySectionSegment ( PMEMORY_AREA  MemoryArea,
PMM_SECTION_SEGMENT  Segment,
PLARGE_INTEGER  Offset,
BOOLEAN  Dirty,
BOOLEAN  PageOut,
ULONG_PTR InEntry 
)

Definition at line 1089 of file section.c.

1095{
1098 BOOLEAN IsDataMap = BooleanFlagOn(*Segment->Flags, MM_DATAFILE_SEGMENT);
1099 SWAPENTRY SwapEntry;
1100
1101 if (Entry == 0)
1102 {
1103 DPRINT1("Entry == 0 for MmUnsharePageEntrySectionSegment\n");
1104 KeBugCheck(MEMORY_MANAGEMENT);
1105 }
1106 if (SHARE_COUNT_FROM_SSE(Entry) == 0)
1107 {
1108 DPRINT1("Zero share count for unshare (Seg %p Offset %x Page %x)\n", Segment, Offset->LowPart, PFN_FROM_SSE(Entry));
1109 KeBugCheck(MEMORY_MANAGEMENT);
1110 }
1112 {
1113 KeBugCheck(MEMORY_MANAGEMENT);
1114 }
1116 if (Dirty) Entry = DIRTY_SSE(Entry);
1117
1118 /* If we are paging-out, pruning the page for real will be taken care of in MmCheckDirtySegment */
1119 if ((SHARE_COUNT_FROM_SSE(Entry) > 0) || PageOut)
1120 {
1121 /* Update the page mapping in the segment and we're done */
1123 return FALSE;
1124 }
1125
1126 /* We are pruning the last mapping on this page. See if we can keep it a bit more. */
1127 ASSERT(!PageOut);
1128
1129 if (IsDataMap)
1130 {
1131 /* We can always keep memory in for data maps */
1133 return FALSE;
1134 }
1135
1136 if (!FlagOn(Segment->Image.Characteristics, IMAGE_SCN_MEM_SHARED))
1137 {
1138 ASSERT(Segment->WriteCopy);
1141 /* So this must have been a read-only page. Keep it ! */
1143 return FALSE;
1144 }
1145
1146 /*
1147 * So this is a page for a shared section of a DLL.
1148 * We can keep it if it is not dirty.
1149 */
1150 SwapEntry = MmGetSavedSwapEntryPage(Page);
1151 if ((SwapEntry == 0) && !IS_DIRTY_SSE(Entry))
1152 {
1154 return FALSE;
1155 }
1156
1157 /* No more processes are referencing this shared dirty page. Ditch it. */
1158 if (SwapEntry)
1159 {
1161 MmFreeSwapPage(SwapEntry);
1162 }
1165 return TRUE;
1166}
#define BooleanFlagOn(F, SF)
Definition: ext2fs.h:183
#define IMAGE_SCN_MEM_SHARED
Definition: ntimage.h:238
#define DECREF_SSE(E)
Definition: mm.h:1389
PLARGE_INTEGER BOOLEAN BOOLEAN PageOut
Definition: section.c:5031

Referenced by MmAccessFaultSectionView(), MmFreeSectionPage(), and MmPageOutPhysicalAddress().

◆ MmUseSpecialPool()

BOOLEAN NTAPI MmUseSpecialPool ( IN SIZE_T  NumberOfBytes,
IN ULONG  Tag 
)

Referenced by ExAllocatePoolWithTag().

◆ MmWriteToSwapPage()

NTSTATUS NTAPI MmWriteToSwapPage ( SWAPENTRY  SwapEntry,
PFN_NUMBER  Page 
)

Definition at line 147 of file pagefile.c.

148{
149 ULONG i;
151 LARGE_INTEGER file_offset;
155 UCHAR MdlBase[sizeof(MDL) + sizeof(PFN_NUMBER)];
156 PMDL Mdl = (PMDL)MdlBase;
157
158 DPRINT("MmWriteToSwapPage\n");
159
160 if (SwapEntry == 0)
161 {
162 KeBugCheck(MEMORY_MANAGEMENT);
163 return(STATUS_UNSUCCESSFUL);
164 }
165
166 i = FILE_FROM_ENTRY(SwapEntry);
167 offset = OFFSET_FROM_ENTRY(SwapEntry) - 1;
168
169 if (MmPagingFile[i]->FileObject == NULL ||
170 MmPagingFile[i]->FileObject->DeviceObject == NULL)
171 {
172 DPRINT1("Bad paging file 0x%.8X\n", SwapEntry);
173 KeBugCheck(MEMORY_MANAGEMENT);
174 }
175
178 Mdl->MdlFlags |= MDL_PAGES_LOCKED;
179
180 file_offset.QuadPart = offset * PAGE_SIZE;
181
184 Mdl,
185 &file_offset,
186 &Event,
187 &Iosb);
188 if (Status == STATUS_PENDING)
189 {
191 Status = Iosb.Status;
192 }
193
194 if (Mdl->MdlFlags & MDL_MAPPED_TO_SYSTEM_VA)
195 {
196 MmUnmapLockedPages (Mdl->MappedSystemVa, Mdl);
197 }
198 return(Status);
199}
GLintptr offset
Definition: glext.h:5920
NTSTATUS NTAPI IoSynchronousPageWrite(IN PFILE_OBJECT FileObject, IN PMDL Mdl, IN PLARGE_INTEGER Offset, IN PKEVENT Event, IN PIO_STATUS_BLOCK StatusBlock)
Definition: iofunc.c:1146

Referenced by MmPageOutPhysicalAddress().

◆ MmZeroPageThread()

VOID NTAPI MmZeroPageThread ( VOID  )

Definition at line 36 of file zeropage.c.

37{
39 PVOID StartAddress, EndAddress;
40 PVOID WaitObjects[2];
41
42 /* Get the discardable sections to free them */
43 MiFindInitializationCode(&StartAddress, &EndAddress);
44 if (StartAddress) MiFreeInitializationCode(StartAddress, EndAddress);
45 DPRINT("Free pages: %lx\n", MmAvailablePages);
46
47 /* Set our priority to 0 */
48 Thread->BasePriority = 0;
50
51 /* Setup the wait objects */
52 WaitObjects[0] = &MmZeroingPageEvent;
53// WaitObjects[1] = &PoSystemIdleTimer; FIXME: Implement idle timer
54
55 while (TRUE)
56 {
58
60 WaitObjects,
61 WaitAny,
64 FALSE,
65 NULL,
66 NULL);
67 OldIrql = MiAcquirePfnLock();
68
69 while (TRUE)
70 {
71 ULONG PageCount = 0;
72 PMMPFN Pfn1 = (PMMPFN)LIST_HEAD;
73 PVOID ZeroAddress;
74 PFN_NUMBER PageIndex, FreePage;
75
76 while (PageCount < MI_ZERO_PTES)
77 {
78 PMMPFN Pfn2;
79
81 break;
82
83 PageIndex = MmFreePageListHead.Flink;
84 ASSERT(PageIndex != LIST_HEAD);
86 MI_SET_PROCESS2("Kernel 0 Loop");
88
89 /* The first global free page should also be the first on its own list */
90 if (FreePage != PageIndex)
91 {
92 KeBugCheckEx(PFN_LIST_CORRUPT,
93 0x8F,
95 PageIndex,
96 0);
97 }
98
99 Pfn2 = MiGetPfnEntry(PageIndex);
100 Pfn2->u1.Flink = (PFN_NUMBER)Pfn1;
101 Pfn1 = Pfn2;
102 PageCount++;
103 }
104 MiReleasePfnLock(OldIrql);
105
106 if (PageCount == 0)
107 {
109 break;
110 }
111
112 ZeroAddress = MiMapPagesInZeroSpace(Pfn1, PageCount);
113 ASSERT(ZeroAddress);
114 KeZeroPages(ZeroAddress, PageCount * PAGE_SIZE);
115 MiUnmapPagesInZeroSpace(ZeroAddress, PageCount);
116
117 OldIrql = MiAcquirePfnLock();
118
119 while (Pfn1 != (PMMPFN)LIST_HEAD)
120 {
121 PageIndex = MiGetPfnEntryIndex(Pfn1);
122 Pfn1 = (PMMPFN)Pfn1->u1.Flink;
124 }
125 }
126 }
127}
VOID NTAPI KeClearEvent(IN PKEVENT Event)
Definition: eventobj.c:22
#define MI_GET_PAGE_COLOR(x)
Definition: miarm.h:231
VOID NTAPI MiInsertPageInList(IN PMMPFNLIST ListHead, IN PFN_NUMBER PageFrameIndex)
Definition: pfnlist.c:779
@ WaitAny
VOID FASTCALL KeZeroPages(IN PVOID Address, IN ULONG Size)
Definition: cpu.c:56
MMPFNLIST MmZeroedPageListHead
Definition: pfnlist.c:41
VOID NTAPI MiUnmapPagesInZeroSpace(IN PVOID VirtualAddress, IN PFN_NUMBER NumberOfPages)
Definition: hypermap.c:187
PVOID NTAPI MiMapPagesInZeroSpace(IN PMMPFN Pfn1, IN PFN_NUMBER NumberOfPages)
Definition: hypermap.c:111
MMPFNLIST MmFreePageListHead
Definition: pfnlist.c:42
NTSTATUS NTAPI KeWaitForMultipleObjects(IN ULONG Count, IN PVOID Object[], IN WAIT_TYPE WaitType, IN KWAIT_REASON WaitReason, IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout OPTIONAL, OUT PKWAIT_BLOCK WaitBlockArray OPTIONAL)
Definition: wait.c:586
PFN_NUMBER Total
Definition: mm.h:443
PFN_NUMBER Flink
Definition: mm.h:445
PFN_NUMBER Flink
Definition: mm.h:377
KPRIORITY NTAPI KeSetPriorityThread(IN PKTHREAD Thread, IN KPRIORITY Priority)
Definition: thrdobj.c:1319
@ WrFreePage
Definition: ketypes.h:423
VOID NTAPI MiFreeInitializationCode(IN PVOID StartVa, IN PVOID EndVa)
Definition: sysldr.c:1464
VOID NTAPI MiFindInitializationCode(OUT PVOID *StartVa, OUT PVOID *EndVa)
Definition: sysldr.c:1487
KEVENT MmZeroingPageEvent
Definition: zeropage.c:20

Referenced by Phase1Initialization().

◆ RtlFindExportedRoutineByName()

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.

Parameters
[in]ImageBaseThe base address of the loaded image.
[in]ExportNameThe name of the export, given as an ANSI NULL-terminated string.
Returns
The address of the named exported routine, or NULL if not found. If the export is a forwarder, this function returns NULL as well.
Note
This routine was originally named MiLocateExportName(), with a separate duplicated MiFindExportedRoutineByName() one (taking a PANSI_STRING) on Windows <= 2003. Both routines have been then merged and renamed to MiFindExportedRoutineByName() on Windows 8 (taking a PCSTR instead), and finally renamed and exported as RtlFindExportedRoutineByName() on Windows 10.
See also
https://www.geoffchappell.com/studies/windows/km/ntoskrnl/api/mm/sysload/mmgetsystemroutineaddress.htm

Definition at line 400 of file sysldr.c.

403{
405 BOOLEAN IsForwarder = FALSE;
407
408 PAGED_CODE();
409
410 /* Call the internal API */
412 ExportName,
413 &Function,
414 &IsForwarder,
416 if (!NT_SUCCESS(Status))
417 return NULL;
418
419 /* If the export is actually a forwarder, log the error and fail */
420 if (IsForwarder)
421 {
422 DPRINT1("RtlFindExportedRoutineByName does not support forwarders!\n", FALSE);
423 return NULL;
424 }
425
426 /* We've found the export */
427 return Function;
428}
_In_ CDROM_SCAN_FOR_SPECIAL_INFO _In_ PCDROM_SCAN_FOR_SPECIAL_HANDLER Function
Definition: cdrom.h:1156
#define STATUS_ENTRYPOINT_NOT_FOUND
Definition: ntstatus.h:549
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 reg...
Definition: sysldr.c:308

Referenced by MiCallDllUnloadAndUnloadDll(), MmCallDllInitialize(), and MmGetSystemRoutineAddress().

◆ RtlpFindExportedRoutineByName()

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.

Parameters
[in]ImageBaseThe base address of the loaded image.
[in]ExportNameThe name of the export, given as an ANSI NULL-terminated string.
[out]FunctionThe address of the named exported routine, or NULL if not found. If the export is a forwarder (see IsForwarder below), this address points to the forwarder name.
[out]IsForwarderAn optional pointer to a BOOLEAN variable, that is set to TRUE if the found export is a forwarder, and FALSE otherwise.
[in]NotFoundStatusThe status code to return in case the export could not be found (examples: STATUS_ENTRYPOINT_NOT_FOUND, STATUS_PROCEDURE_NOT_FOUND).
Returns
A status code as follows:
  • STATUS_SUCCESS if the named exported routine is found;
  • The custom NotFoundStatus if the export could not be found;
  • STATUS_INVALID_PARAMETER if the image is invalid or does not contain an Export Directory.
Note
See RtlFindExportedRoutineByName() for more remarks. Used by psmgr.c PspLookupSystemDllEntryPoint() as well.

Definition at line 308 of file sysldr.c.

314{
315 PIMAGE_EXPORT_DIRECTORY ExportDirectory;
316 PULONG NameTable;
317 PUSHORT OrdinalTable;
318 ULONG ExportSize;
319 USHORT Ordinal;
320 PULONG ExportTable;
321 ULONG_PTR FunctionAddress;
322
323 PAGED_CODE();
324
325 /* Get the export directory */
326 ExportDirectory = RtlImageDirectoryEntryToData(ImageBase,
327 TRUE,
329 &ExportSize);
330 if (!ExportDirectory)
332
333 /* Setup name tables */
334 NameTable = (PULONG)RVA(ImageBase, ExportDirectory->AddressOfNames);
335 OrdinalTable = (PUSHORT)RVA(ImageBase, ExportDirectory->AddressOfNameOrdinals);
336
337 /* Get the ordinal */
338 Ordinal = NameToOrdinal(ExportName,
339 ImageBase,
340 ExportDirectory->NumberOfNames,
341 NameTable,
342 OrdinalTable);
343
344 /* Check if we couldn't find it */
345 if (Ordinal == -1)
346 return NotFoundStatus;
347
348 /* Validate the ordinal */
349 if (Ordinal >= ExportDirectory->NumberOfFunctions)
350 return NotFoundStatus;
351
352 /* Resolve the function's address */
353 ExportTable = (PULONG)RVA(ImageBase, ExportDirectory->AddressOfFunctions);
354 FunctionAddress = (ULONG_PTR)RVA(ImageBase, ExportTable[Ordinal]);
355
356 /* Check if the function is actually a forwarder */
357 if (IsForwarder)
358 {
359 *IsForwarder = FALSE;
360 if ((FunctionAddress > (ULONG_PTR)ExportDirectory) &&
361 (FunctionAddress < (ULONG_PTR)ExportDirectory + ExportSize))
362 {
363 /* It is, and points to the forwarder name */
364 *IsForwarder = TRUE;
365 }
366 }
367
368 /* We've found it */
369 *Function = (PVOID)FunctionAddress;
370 return STATUS_SUCCESS;
371}
#define IMAGE_DIRECTORY_ENTRY_EXPORT
Definition: compat.h:151
DWORD AddressOfNameOrdinals
Definition: compat.h:167
#define RVA(m, b)
Definition: sysldr.c:217
USHORT NTAPI NameToOrdinal(_In_ PCSTR ExportName, _In_ PVOID ImageBase, _In_ ULONG NumberOfNames, _In_ PULONG NameTable, _In_ PUSHORT OrdinalTable)
Definition: sysldr.c:222

Referenced by CODE_SEG(), and RtlFindExportedRoutineByName().

◆ UpdateTotalCommittedPages()

FORCEINLINE VOID UpdateTotalCommittedPages ( LONG  Delta)

Definition at line 871 of file mm.h.

872{
873 /*
874 * Add up all the used "Committed" memory + pagefile.
875 * Not sure this is right. 8^\
876 * MmTotalCommittedPages should be adjusted consistently with
877 * other counters at different places.
878 *
879 MmTotalCommittedPages = MiMemoryConsumers[MC_SYSTEM].PagesUsed +
880 MiMemoryConsumers[MC_USER].PagesUsed +
881 MiUsedSwapPages;
882 */
883
884 /* Update Commitment */
886
887 /* Update Peak = max(Peak, Total) in a lockless way */
888 SIZE_T PeakCommitment = MmPeakCommitment;
889 while (TotalCommittedPages > PeakCommitment &&
890 InterlockedCompareExchangeSizeT(&MmPeakCommitment, TotalCommittedPages, PeakCommitment) != PeakCommitment)
891 {
892 PeakCommitment = MmPeakCommitment;
893 }
894}
#define InterlockedCompareExchangeSizeT(Destination, Exchange, Comperand)
Definition: ex.h:1539
SIZE_T MmTotalCommittedPages
Definition: freelist.c:30
SIZE_T MmPeakCommitment
Definition: freelist.c:35

Referenced by MmAllocSwapPage(), MmFreeSwapPage(), MmReleasePageMemoryConsumer(), and MmRequestPageMemoryConsumer().

Variable Documentation

◆ Address

_In_ PVOID Address

Definition at line 1303 of file mm.h.

◆ ApcState

◆ CurrentMaxQuota

_In_ SIZE_T CurrentMaxQuota

Definition at line 665 of file mm.h.

Referenced by _Requires_lock_held_().

◆ KernelVerifier

PVOID KernelVerifier
extern

Definition at line 28 of file drvmgmt.c.

◆ MiDebugMapping

PVOID MiDebugMapping
extern

Definition at line 30 of file mmdbg.c.

Referenced by MmArmInitSystem().

◆ MiFreeSwapPages

PFN_COUNT MiFreeSwapPages
extern

◆ MiMemoryConsumers

◆ MiUsedSwapPages

PFN_COUNT MiUsedSwapPages
extern

Definition at line 69 of file pagefile.c.

Referenced by MmAllocSwapPage(), MmFreeSwapPage(), MmInitPagingFile(), and QSI_DEF().

◆ MmAvailablePages

◆ MmDebugPte

PMMPTE MmDebugPte
extern

Definition at line 31 of file mmdbg.c.

Referenced by MmArmInitSystem().

◆ MmDisablePagingExecutive

UCHAR MmDisablePagingExecutive
extern

Definition at line 25 of file mminit.c.

Referenced by MiEnablePagingOfDriver(), and MmPageEntireDriver().

◆ MmDriverCommit

SIZE_T MmDriverCommit
extern

Definition at line 32 of file freelist.c.

◆ MmFreePageListHead

MMPFNLIST MmFreePageListHead
extern

◆ MmHighestPhysicalPage

◆ MmKernelAddressSpace

PMMSUPPORT MmKernelAddressSpace
extern

Definition at line 27 of file mminit.c.

Referenced by MmGetAddressSpaceOwner(), MmGetKernelAddressSpace(), and MmInitSystem().

◆ MmLastUnloadedDrivers

PVOID MmLastUnloadedDrivers
extern

Definition at line 31 of file sysldr.c.

◆ MmLoadedUserImageList

LIST_ENTRY MmLoadedUserImageList
extern

Definition at line 22 of file sysldr.c.

Referenced by MiLoadUserSymbols(), MmArmInitSystem(), and QSI_DEF().

◆ MmLowestPhysicalPage

◆ MmModifiedNoWritePageListHead

MMPFNLIST MmModifiedNoWritePageListHead
extern

Definition at line 47 of file pfnlist.c.

Referenced by MiUnlinkPageFromList().

◆ MmModifiedPageListHead

MMPFNLIST MmModifiedPageListHead
extern

◆ MmNumberOfPagingFiles

ULONG MmNumberOfPagingFiles
extern

◆ MmNumberOfPhysicalPages

◆ MmPagedPoolCommit

SIZE_T MmPagedPoolCommit
extern

Definition at line 34 of file freelist.c.

◆ MmPagingFile

◆ MmPeakCommitment

SIZE_T MmPeakCommitment
extern

Definition at line 35 of file freelist.c.

Referenced by QSI_DEF(), and UpdateTotalCommittedPages().

◆ MmPfnDatabase

◆ MmPfnLock

KSPIN_LOCK MmPfnLock
extern

Definition at line 49 of file krnlinit.c.

Referenced by KiInitSpinLocks().

◆ MmProcessCommit

SIZE_T MmProcessCommit
extern

Definition at line 33 of file freelist.c.

◆ MmResidentAvailablePages

PFN_NUMBER MmResidentAvailablePages
extern

◆ MmSharedCommit

SIZE_T MmSharedCommit
extern

Definition at line 31 of file freelist.c.

Referenced by MmCommitSessionMappedView().

◆ MmStandbyPageListHead

MMPFNLIST MmStandbyPageListHead
extern

Definition at line 43 of file pfnlist.c.

Referenced by MiInsertPageInList(), and MiUnlinkPageFromList().

◆ MmSystemLoadLock

KMUTANT MmSystemLoadLock
extern

◆ MmThrottleBottom

ULONG MmThrottleBottom
extern

Definition at line 397 of file mminit.c.

Referenced by CcCanIWrite(), and MmArmInitSystem().

◆ MmThrottleTop

ULONG MmThrottleTop
extern

Definition at line 396 of file mminit.c.

Referenced by CcCanIWrite(), CcWriteBehind(), and MmArmInitSystem().

◆ MmTotalCommitLimit

SIZE_T MmTotalCommitLimit
extern

Definition at line 359 of file mminit.c.

Referenced by MmArmInitSystem().

◆ MmtotalCommitLimitMaximum

SIZE_T MmtotalCommitLimitMaximum
extern

Definition at line 36 of file freelist.c.

◆ MmTotalCommittedPages

SIZE_T MmTotalCommittedPages
extern

Definition at line 30 of file freelist.c.

Referenced by QSI_DEF(), and UpdateTotalCommittedPages().

◆ MmTotalNonPagedPoolQuota

SIZE_T MmTotalNonPagedPoolQuota
extern

Definition at line 27 of file pool.c.

Referenced by _Requires_lock_held_().

◆ MmTotalPagedPoolQuota

SIZE_T MmTotalPagedPoolQuota
extern

Definition at line 28 of file pool.c.

Referenced by _Requires_lock_held_().

◆ MmTriageActionTaken

PVOID MmTriageActionTaken
extern

Definition at line 27 of file drvmgmt.c.

◆ MmUnloadedDrivers

PVOID MmUnloadedDrivers
extern

Definition at line 30 of file sysldr.c.

◆ MmVerifierData

MM_DRIVER_VERIFIER_DATA MmVerifierData
extern

Definition at line 20 of file drvmgmt.c.

Referenced by MmIsVerifierEnabled().

◆ MmZeroedPageListHead

MMPFNLIST MmZeroedPageListHead
extern

Definition at line 41 of file pfnlist.c.

Referenced by MiRemoveAnyPage(), MiRemoveZeroPage(), and MmZeroPageThread().

◆ NewMaxQuota

_In_ SIZE_T _Out_ PSIZE_T NewMaxQuota

Definition at line 666 of file mm.h.

Referenced by _Requires_lock_held_().

◆ Page

Definition at line 1305 of file mm.h.

Referenced by _Success_(), CcRosTrimCache(), DiskClassInstaller(), DmaRequest(), FatBuildZeroMdl(), FatExamineFatEntries(), FatFlushFat(), FatSetFatRun(), FindFile(), FreeWsleIndex(), Ki386FreeIdentityMap(), MempSetupPaging(), MempUnmapPage(), MemQueryMemoryZone(), MI_MAKE_TRANSITION_PTE(), MiAllocatePagesForMdl(), MiCacheEvictPages(), MiCheckForContiguousMemory(), MiFindContiguousMemory(), MiFindContiguousPages(), MiGetPfnEntry(), MiMapPageInHyperSpace(), MiReadFilePage(), MiReadPageFile(), MiResolvePageFileFault(), MiShutdownSystem(), MmCreatePhysicalMapping(), MmCreateVirtualMapping(), MmCreateVirtualMappingUnsafe(), MmCreateVirtualMappingUnsafeEx(), MmDeleteRmap(), MmDeleteSectionAssociation(), MmDeleteVirtualMapping(), MmFinalizeSectionPageOut(), MmFreeCacheSectionPage(), MmFreeMemoryArea(), MmGetLRUFirstUserPage(), MmGetLRUNextUserPage(), MmGetPfnForProcess(), MmGetReferenceCountPageWithoutLock(), MmGetSectionAssociation(), MmGetSegmentRmap(), MmInsertLRULastUserPage(), MmInsertRmap(), MmMdFindDescriptor(), MmMdFindDescriptorFromMdl(), MmPageOutPhysicalAddress(), MmPapFreePhysicalPages(), MmpPageOutPhysicalAddress(), MmReadFromSwapPage(), MmReleasePageMemoryConsumer(), MmRemoveLRUUserPage(), MmRequestPageMemoryConsumer(), MmSetSectionAssociation(), MmWriteToSwapPage(), MUIClearStyledText(), MUIClearText(), MUIGetEntry(), MUISetStyledText(), MUISetText(), OpenControlPanelItem(), RunUSetup(), SH_CreatePropertySheetPage(), TestFreeNoAccess(), TestMmBuildMdlForNonPagedPool(), TrimWsList(), vfatDirFindFile(), VidBiosDrawGlyph(), VidBiosGetCursorPosition(), VidBiosPrintCharacter(), VidBiosScrollWindow(), VidBiosSetCursorPosition(), VidBiosSetVideoMode(), and VidBiosVideoService().

◆ QuotaToReturn

_In_ SIZE_T QuotaToReturn

Definition at line 674 of file mm.h.

Referenced by _Requires_lock_held_().

◆ WasDirty

Definition at line 1304 of file mm.h.

Referenced by _Success_(), and MmDeleteVirtualMapping().