ReactOS 0.4.16-dev-282-g4d0a26d
mm.h File Reference
#include <internal/arch/mm.h>
Include dependency graph for mm.h:

Go to the source code of this file.

Classes

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

Macros

#define MI_QUOTA_NON_PAGED_NEEDED_PAGES   64
 
#define MI_NON_PAGED_QUOTA_MIN_RESIDENT_PAGES   200
 
#define MI_CHARGE_PAGED_POOL_QUOTA   0x80000
 
#define MI_CHARGE_NON_PAGED_POOL_QUOTA   0x10000
 
#define MM_NOIRQL   ((KIRQL)0xFFFFFFFF)
 
#define MMDBG_COPY_WRITE   0x00000001
 
#define MMDBG_COPY_PHYSICAL   0x00000002
 
#define MMDBG_COPY_UNSAFE   0x00000004
 
#define MMDBG_COPY_CACHED   0x00000008
 
#define MMDBG_COPY_UNCACHED   0x00000010
 
#define MMDBG_COPY_WRITE_COMBINED   0x00000020
 
#define MMDBG_COPY_MAX_SIZE   0x8
 
#define MI_STATIC_MEMORY_AREAS   (13)
 
#define MEMORY_AREA_SECTION_VIEW   (1)
 
#define MEMORY_AREA_OWNED_BY_ARM3   (15)
 
#define MEMORY_AREA_STATIC   (0x80000000)
 
#define MM_VIRTMEM_GRANULARITY   (64 * 1024)
 
#define STATUS_MM_RESTART_OPERATION   ((NTSTATUS)0xD0000001)
 
#define PAGE_WRITETHROUGH   (1024)
 
#define PAGE_SYSTEM   (2048)
 
#define SEC_PHYSICALMEMORY   (0x80000000)
 
#define MC_USER   (0)
 
#define MC_SYSTEM   (1)
 
#define MC_MAXIMUM   (2)
 
#define PAGED_POOL_MASK   1
 
#define MUST_SUCCEED_POOL_MASK   2
 
#define CACHE_ALIGNED_POOL_MASK   4
 
#define QUOTA_POOL_MASK   8
 
#define SESSION_POOL_MASK   32
 
#define VERIFIER_POOL_MASK   64
 
#define MAX_PAGING_FILES   (16)
 
#define MM_ROUND_UP(x, s)    ((PVOID)(((ULONG_PTR)(x)+(s)-1) & ~((ULONG_PTR)(s)-1)))
 
#define MM_ROUND_DOWN(x, s)    ((PVOID)(((ULONG_PTR)(x)) & ~((ULONG_PTR)(s)-1)))
 
#define PAGE_FLAGS_VALID_FOR_SECTION
 
#define PAGE_IS_READABLE
 
#define PAGE_IS_WRITABLE
 
#define PAGE_IS_EXECUTABLE
 
#define PAGE_IS_WRITECOPY
 
#define InterlockedCompareExchangePte(PointerPte, Exchange, Comperand)    InterlockedCompareExchange((PLONG)(PointerPte), Exchange, Comperand)
 
#define InterlockedExchangePte(PointerPte, Value)    InterlockedExchange((PLONG)(PointerPte), Value)
 
#define MM_PHYSICALMEMORY_SEGMENT   (0x1)
 
#define MM_DATAFILE_SEGMENT   (0x2)
 
#define MM_SEGMENT_INDELETE   (0x4)
 
#define MM_SEGMENT_INCREATE   (0x8)
 
#define MM_IMAGE_SECTION_FLUSH_DELETE   (0x10)
 
#define MA_GetStartingAddress(_MemoryArea)   ((_MemoryArea)->VadNode.StartingVpn << PAGE_SHIFT)
 
#define MA_GetEndingAddress(_MemoryArea)   (((_MemoryArea)->VadNode.EndingVpn + 1) << PAGE_SHIFT)
 
#define MI_SET_USAGE(x)
 
#define MI_SET_PROCESS(x)
 
#define MI_SET_PROCESS2(x)
 
#define StartOfAllocation   ReadInProgress
 
#define EndOfAllocation   WriteInProgress
 
#define MM_FREE_POOL_SIGNATURE   'ARM3'
 
#define RMAP_SEGMENT_MASK   ~((ULONG_PTR)0xff)
 
#define RMAP_IS_SEGMENT(x)   (((ULONG_PTR)(x) & RMAP_SEGMENT_MASK) == RMAP_SEGMENT_MASK)
 
#define MI_ASSERT_PFN_LOCK_HELD()   NT_ASSERT((KeGetCurrentIrql() >= DISPATCH_LEVEL) && (MmPfnLock != 0))
 
#define MmSetCleanPage(__P, __A)   MmSetDirtyBit(__P, __A, FALSE)
 
#define MmSetDirtyPage(__P, __A)   MmSetDirtyBit(__P, __A, TRUE)
 
#define PFN_FROM_SSE(E)   ((PFN_NUMBER)((E) >> PAGE_SHIFT))
 
#define IS_SWAP_FROM_SSE(E)   ((E) & 0x00000001)
 
#define MM_IS_WAIT_PTE(E)    (IS_SWAP_FROM_SSE(E) && SWAPENTRY_FROM_SSE(E) == MM_WAIT_ENTRY)
 
#define MAKE_PFN_SSE(P)   ((ULONG_PTR)((P) << PAGE_SHIFT))
 
#define SWAPENTRY_FROM_SSE(E)   ((E) >> 1)
 
#define MAKE_SWAP_SSE(S)   (((ULONG_PTR)(S) << 1) | 0x1)
 
#define DIRTY_SSE(E)   ((E) | 2)
 
#define CLEAN_SSE(E)   ((E) & ~2)
 
#define IS_DIRTY_SSE(E)   ((E) & 2)
 
#define WRITE_SSE(E)   ((E) | 4)
 
#define IS_WRITE_SSE(E)   ((E) & 4)
 
#define PAGE_FROM_SSE(E)   ((E) & 0xFFFFF000)
 
#define SHARE_COUNT_FROM_SSE(E)   (((E) & 0x00000FFC) >> 3)
 
#define MAX_SHARE_COUNT   0x1FF
 
#define MAKE_SSE(P, C)   ((ULONG_PTR)((P) | ((C) << 3)))
 
#define BUMPREF_SSE(E)   (PAGE_FROM_SSE(E) | ((SHARE_COUNT_FROM_SSE(E) + 1) << 3) | ((E) & 0x7))
 
#define DECREF_SSE(E)   (PAGE_FROM_SSE(E) | ((SHARE_COUNT_FROM_SSE(E) - 1) << 3) | ((E) & 0x7))
 
#define MmLockSectionSegment(x)   _MmLockSectionSegment(x,__FILE__,__LINE__)
 
#define MmUnlockSectionSegment(x)   _MmUnlockSectionSegment(x,__FILE__,__LINE__)
 
#define MmSetPageEntrySectionSegment(S, O, E)   _MmSetPageEntrySectionSegment(S,O,E,__FILE__,__LINE__)
 
#define MmGetPageEntrySectionSegment(S, O)   _MmGetPageEntrySectionSegment(S,O,__FILE__,__LINE__)
 

Typedefs

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

Enumerations

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

Functions

NTSTATUS NTAPI MmDbgCopyMemory (IN ULONG64 Address, IN PVOID Buffer, IN ULONG Size, IN ULONG Flags)
 
BOOLEAN NTAPI MmIsSessionAddress (IN PVOID Address)
 
ULONG NTAPI MmGetSessionId (IN PEPROCESS Process)
 
ULONG NTAPI MmGetSessionIdEx (IN PEPROCESS Process)
 
NTSTATUS NTAPI MmCreateMemoryArea (PMMSUPPORT AddressSpace, ULONG Type, PVOID *BaseAddress, SIZE_T Length, ULONG Protection, PMEMORY_AREA *Result, ULONG AllocationFlags, ULONG AllocationGranularity)
 
PMEMORY_AREA NTAPI MmLocateMemoryAreaByAddress (PMMSUPPORT AddressSpace, PVOID Address)
 
NTSTATUS NTAPI MmFreeMemoryArea (PMMSUPPORT AddressSpace, PMEMORY_AREA MemoryArea, PMM_FREE_PAGE_FUNC FreePage, PVOID FreePageContext)
 
VOID NTAPI MiRosCleanupMemoryArea (PEPROCESS Process, PMMVAD Vad)
 
PMEMORY_AREA NTAPI MmLocateMemoryAreaByRegion (PMMSUPPORT AddressSpace, PVOID Address, SIZE_T Length)
 
PVOID NTAPI MmFindGap (PMMSUPPORT AddressSpace, SIZE_T Length, ULONG_PTR Granularity, BOOLEAN TopDown)
 
VOID NTAPI MiRosCheckMemoryAreas (PMMSUPPORT AddressSpace)
 
VOID NTAPI MiCheckAllProcessMemoryAreas (VOID)
 
VOID NTAPI MiInitializeNonPagedPool (VOID)
 
PVOID NTAPI MiAllocatePoolPages (IN POOL_TYPE PoolType, IN SIZE_T SizeInBytes)
 
POOL_TYPE NTAPI MmDeterminePoolType (IN PVOID VirtualAddress)
 
ULONG NTAPI MiFreePoolPages (IN PVOID StartingAddress)
 
 _Requires_lock_held_ (PspQuotaLock) BOOLEAN NTAPI MmRaisePoolQuota(_In_ POOL_TYPE PoolType
 
VOID NTAPI MmBuildMdlFromPages (PMDL Mdl, PPFN_NUMBER Pages)
 
VOID NTAPI MmInit1 (VOID)
 
BOOLEAN NTAPI MmInitSystem (IN ULONG Phase, IN PLOADER_PARAMETER_BLOCK LoaderBlock)
 
SWAPENTRY NTAPI MmAllocSwapPage (VOID)
 
VOID NTAPI MmFreeSwapPage (SWAPENTRY Entry)
 
VOID NTAPI MmInitPagingFile (VOID)
 
BOOLEAN NTAPI MmIsFileObjectAPagingFile (PFILE_OBJECT FileObject)
 
NTSTATUS NTAPI MmReadFromSwapPage (SWAPENTRY SwapEntry, PFN_NUMBER Page)
 
NTSTATUS NTAPI MmWriteToSwapPage (SWAPENTRY SwapEntry, PFN_NUMBER Page)
 
VOID NTAPI MmShowOutOfSpaceMessagePagingFile (VOID)
 
NTSTATUS NTAPI MiReadPageFile (_In_ PFN_NUMBER Page, _In_ ULONG PageFileIndex, _In_ ULONG_PTR PageFileOffset)
 
NTSTATUS NTAPI MmInitializeProcessAddressSpace (IN PEPROCESS Process, IN PEPROCESS Clone OPTIONAL, IN PVOID Section OPTIONAL, IN OUT PULONG Flags, IN POBJECT_NAME_INFORMATION *AuditName OPTIONAL)
 
NTSTATUS NTAPI MmCreatePeb (IN PEPROCESS Process, IN PINITIAL_PEB InitialPeb, OUT PPEB *BasePeb)
 
NTSTATUS NTAPI MmCreateTeb (IN PEPROCESS Process, IN PCLIENT_ID ClientId, IN PINITIAL_TEB InitialTeb, OUT PTEB *BaseTeb)
 
VOID NTAPI MmDeleteTeb (struct _EPROCESS *Process, PTEB Teb)
 
VOID NTAPI MmCleanProcessAddressSpace (IN PEPROCESS Process)
 
VOID NTAPI MmDeleteProcessAddressSpace (IN PEPROCESS Process)
 
ULONG NTAPI MmGetSessionLocaleId (VOID)
 
NTSTATUS NTAPI MmSetMemoryPriorityProcess (IN PEPROCESS Process, IN UCHAR MemoryPriority)
 
NTSTATUS NTAPI MmPageFault (ULONG Cs, PULONG Eip, PULONG Eax, ULONG Cr2, ULONG ErrorCode)
 
VOID NTAPI MiInitializeSpecialPool (VOID)
 
BOOLEAN NTAPI MmUseSpecialPool (IN SIZE_T NumberOfBytes, IN ULONG Tag)
 
BOOLEAN NTAPI MmIsSpecialPoolAddress (IN PVOID P)
 
BOOLEAN NTAPI MmIsSpecialPoolAddressFree (IN PVOID P)
 
PVOID NTAPI MmAllocateSpecialPool (IN SIZE_T NumberOfBytes, IN ULONG Tag, IN POOL_TYPE PoolType, IN ULONG SpecialType)
 
VOID NTAPI MmFreeSpecialPool (IN PVOID P)
 
NTSTATUS NTAPI MmAccessFault (IN ULONG FaultCode, IN PVOID Address, IN KPROCESSOR_MODE Mode, IN PVOID TrapInformation)
 
PVOID NTAPI MmCreateKernelStack (BOOLEAN GuiStack, UCHAR Node)
 
VOID NTAPI MmDeleteKernelStack (PVOID Stack, BOOLEAN GuiStack)
 
FORCEINLINE VOID UpdateTotalCommittedPages (LONG Delta)
 
VOID NTAPI MmInitializeMemoryConsumer (ULONG Consumer, NTSTATUS(*Trim)(ULONG Target, ULONG Priority, PULONG NrFreed))
 
VOID NTAPI MmInitializeBalancer (ULONG NrAvailablePages, ULONG NrSystemPages)
 
NTSTATUS NTAPI MmReleasePageMemoryConsumer (ULONG Consumer, PFN_NUMBER Page)
 
NTSTATUS NTAPI MmRequestPageMemoryConsumer (ULONG Consumer, BOOLEAN MyWait, PPFN_NUMBER AllocatedPage)
 
VOID NTAPI MiInitBalancerThread (VOID)
 
VOID NTAPI MmRebalanceMemoryConsumers (VOID)
 
VOID NTAPI MmSetRmapListHeadPage (PFN_NUMBER Page, struct _MM_RMAP_ENTRY *ListHead)
 
struct _MM_RMAP_ENTRY *NTAPI MmGetRmapListHeadPage (PFN_NUMBER Page)
 
VOID NTAPI MmInsertRmap (PFN_NUMBER Page, struct _EPROCESS *Process, PVOID Address)
 
VOID NTAPI MmDeleteAllRmaps (PFN_NUMBER Page, PVOID Context, VOID(*DeleteMapping)(PVOID Context, struct _EPROCESS *Process, PVOID Address))
 
VOID NTAPI MmDeleteRmap (PFN_NUMBER Page, struct _EPROCESS *Process, PVOID Address)
 
VOID NTAPI MmInitializeRmapList (VOID)
 
NTSTATUS NTAPI MmPageOutPhysicalAddress (PFN_NUMBER Page)
 
PMM_SECTION_SEGMENT NTAPI MmGetSectionAssociation (PFN_NUMBER Page, PLARGE_INTEGER Offset)
 
 _IRQL_raises_ (DISPATCH_LEVEL) _IRQL_requires_max_(DISPATCH_LEVEL) _Requires_lock_not_held_(MmPfnLock) _Acquires_lock_(MmPfnLock) _IRQL_saves_ FORCEINLINE KIRQL MiAcquirePfnLock(VOID)
 
 _Requires_lock_held_ (MmPfnLock) _Releases_lock_(MmPfnLock) _IRQL_requires_(DISPATCH_LEVEL) FORCEINLINE VOID MiReleasePfnLock(_In_ _IRQL_restores_ KIRQL OldIrql)
 
 _IRQL_requires_min_ (DISPATCH_LEVEL) _Requires_lock_not_held_(MmPfnLock) _Acquires_lock_(MmPfnLock) FORCEINLINE VOID MiAcquirePfnLockAtDpcLevel(VOID)
 
FORCEINLINE PMMPFN MiGetPfnEntry (IN PFN_NUMBER Pfn)
 
FORCEINLINE PFN_NUMBER MiGetPfnEntryIndex (IN PMMPFN Pfn1)
 
PFN_NUMBER NTAPI MmGetLRUNextUserPage (PFN_NUMBER PreviousPage, BOOLEAN MoveToLast)
 
PFN_NUMBER NTAPI MmGetLRUFirstUserPage (VOID)
 
VOID NTAPI MmDumpArmPfnDatabase (IN BOOLEAN StatusOnly)
 
VOID NTAPI MmZeroPageThread (VOID)
 
PVOID NTAPI MiMapPageInHyperSpace (IN PEPROCESS Process, IN PFN_NUMBER Page, IN PKIRQL OldIrql)
 
VOID NTAPI MiUnmapPageInHyperSpace (IN PEPROCESS Process, IN PVOID Address, IN KIRQL OldIrql)
 
PVOID NTAPI MiMapPagesInZeroSpace (IN PMMPFN Pfn1, IN PFN_NUMBER NumberOfPages)
 
VOID NTAPI MiUnmapPagesInZeroSpace (IN PVOID VirtualAddress, IN PFN_NUMBER NumberOfPages)
 
NTSTATUS NTAPI MmCreateVirtualMapping (struct _EPROCESS *Process, PVOID Address, ULONG flProtect, PFN_NUMBER Page)
 
NTSTATUS NTAPI MmCreateVirtualMappingUnsafe (struct _EPROCESS *Process, PVOID Address, ULONG flProtect, PFN_NUMBER Page)
 
NTSTATUS NTAPI MmCreatePhysicalMapping (_Inout_opt_ PEPROCESS Process, _In_ PVOID Address, _In_ ULONG flProtect, _In_ PFN_NUMBER Page)
 
ULONG NTAPI MmGetPageProtect (struct _EPROCESS *Process, PVOID Address)
 
VOID NTAPI MmSetPageProtect (struct _EPROCESS *Process, PVOID Address, ULONG flProtect)
 
BOOLEAN NTAPI MmIsPagePresent (struct _EPROCESS *Process, PVOID Address)
 
BOOLEAN NTAPI MmIsDisabledPage (struct _EPROCESS *Process, PVOID Address)
 
VOID NTAPI MmInitGlobalKernelPageDirectory (VOID)
 
VOID NTAPI MmDeletePageFileMapping (struct _EPROCESS *Process, PVOID Address, SWAPENTRY *SwapEntry)
 
NTSTATUS NTAPI MmCreatePageFileMapping (struct _EPROCESS *Process, PVOID Address, SWAPENTRY SwapEntry)
 
VOID NTAPI MmGetPageFileMapping (PEPROCESS Process, PVOID Address, SWAPENTRY *SwapEntry)
 
BOOLEAN NTAPI MmIsPageSwapEntry (struct _EPROCESS *Process, PVOID Address)
 
PFN_NUMBER NTAPI MmAllocPage (ULONG Consumer)
 
VOID NTAPI MmDereferencePage (PFN_NUMBER Page)
 
VOID NTAPI MmReferencePage (PFN_NUMBER Page)
 
ULONG NTAPI MmGetReferenceCountPage (PFN_NUMBER Page)
 
BOOLEAN NTAPI MmIsPageInUse (PFN_NUMBER Page)
 
VOID NTAPI MmSetSavedSwapEntryPage (PFN_NUMBER Page, SWAPENTRY SavedSwapEntry)
 
SWAPENTRY NTAPI MmGetSavedSwapEntryPage (PFN_NUMBER Page)
 
VOID NTAPI MmSetCleanPage (struct _EPROCESS *Process, PVOID Address)
 
VOID NTAPI MmSetDirtyBit (PEPROCESS Process, PVOID Address, BOOLEAN Bit)
 
VOID NTAPI MmDeletePageTable (struct _EPROCESS *Process, PVOID Address)
 
PFN_NUMBER NTAPI MmGetPfnForProcess (struct _EPROCESS *Process, PVOID Address)
 
BOOLEAN NTAPI MmCreateProcessAddressSpace (IN ULONG MinWs, IN PEPROCESS Dest, IN PULONG_PTR DirectoryTableBase)
 
NTSTATUS NTAPI MmInitializeHandBuiltProcess (IN PEPROCESS Process, IN PULONG_PTR DirectoryTableBase)
 
NTSTATUS NTAPI MmInitializeHandBuiltProcess2 (IN PEPROCESS Process)
 
NTSTATUS NTAPI MmSetExecuteOptions (IN ULONG ExecuteOptions)
 
NTSTATUS NTAPI MmGetExecuteOptions (IN PULONG ExecuteOptions)
 
 _Success_ (return) BOOLEAN MmDeleteVirtualMapping(_Inout_opt_ PEPROCESS Process
 
BOOLEAN MiArchCreateProcessAddressSpace (_In_ PEPROCESS Process, _In_ PULONG_PTR DirectoryTableBase)
 
NTSTATUS MmTrimUserMemory (ULONG Target, ULONG Priority, PULONG NrFreedPages)
 
NTSTATUS NTAPI MmAlterRegion (PMMSUPPORT AddressSpace, PVOID BaseAddress, PLIST_ENTRY RegionListHead, PVOID StartAddress, SIZE_T Length, ULONG NewType, ULONG NewProtect, PMM_ALTER_REGION_FUNC AlterFunc)
 
VOID NTAPI MmInitializeRegion (PLIST_ENTRY RegionListHead, SIZE_T Length, ULONG Type, ULONG Protect)
 
PMM_REGION NTAPI MmFindRegion (PVOID BaseAddress, PLIST_ENTRY RegionListHead, PVOID Address, PVOID *RegionBaseAddress)
 
VOID NTAPI _MmLockSectionSegment (PMM_SECTION_SEGMENT Segment, const char *file, int line)
 
VOID NTAPI _MmUnlockSectionSegment (PMM_SECTION_SEGMENT Segment, const char *file, int line)
 
VOID NTAPI MmGetImageInformation (OUT PSECTION_IMAGE_INFORMATION ImageInformation)
 
PFILE_OBJECT NTAPI MmGetFileObjectForSection (IN PVOID Section)
 
NTSTATUS NTAPI MmGetFileNameForAddress (IN PVOID Address, OUT PUNICODE_STRING ModuleName)
 
NTSTATUS NTAPI MmGetFileNameForSection (IN PVOID Section, OUT POBJECT_NAME_INFORMATION *ModuleName)
 
NTSTATUS NTAPI MmQuerySectionView (PMEMORY_AREA MemoryArea, PVOID Address, PMEMORY_BASIC_INFORMATION Info, PSIZE_T ResultLength)
 
NTSTATUS NTAPI MmProtectSectionView (PMMSUPPORT AddressSpace, PMEMORY_AREA MemoryArea, PVOID BaseAddress, SIZE_T Length, ULONG Protect, PULONG OldProtect)
 
NTSTATUS NTAPI MmInitSectionImplementation (VOID)
 
NTSTATUS NTAPI MmNotPresentFaultSectionView (PMMSUPPORT AddressSpace, MEMORY_AREA *MemoryArea, PVOID Address, BOOLEAN Locked)
 
NTSTATUS NTAPI MmPageOutSectionView (PMMSUPPORT AddressSpace, PMEMORY_AREA MemoryArea, PVOID Address, ULONG_PTR Entry)
 
NTSTATUS NTAPI MmCreatePhysicalMemorySection (VOID)
 
NTSTATUS NTAPI MmAccessFaultSectionView (PMMSUPPORT AddressSpace, MEMORY_AREA *MemoryArea, PVOID Address, BOOLEAN Locked)
 
VOID NTAPI MmFreeSectionSegments (PFILE_OBJECT FileObject)
 
NTSTATUS NTAPI MmMapViewInSystemSpaceEx (_In_ PVOID Section, _Outptr_result_bytebuffer_(*ViewSize) PVOID *MappedBase, _Inout_ PSIZE_T ViewSize, _Inout_ PLARGE_INTEGER SectionOffset, _In_ ULONG_PTR Flags)
 
BOOLEAN NTAPI MmArePagesResident (_In_ PEPROCESS Process, _In_ PVOID BaseAddress, _In_ ULONG Length)
 
NTSTATUS NTAPI MmMakePagesDirty (_In_ PEPROCESS Process, _In_ PVOID Address, _In_ ULONG Length)
 
NTSTATUS NTAPI MmFlushSegment (_In_ PSECTION_OBJECT_POINTERS SectionObjectPointer, _In_opt_ PLARGE_INTEGER Offset, _In_ ULONG Length, _Out_opt_ PIO_STATUS_BLOCK Iosb)
 
NTSTATUS NTAPI MmMakeDataSectionResident (_In_ PSECTION_OBJECT_POINTERS SectionObjectPointer, _In_ LONGLONG Offset, _In_ ULONG Length, _In_ PLARGE_INTEGER ValidDataLength)
 
BOOLEAN NTAPI MmPurgeSegment (_In_ PSECTION_OBJECT_POINTERS SectionObjectPointer, _In_opt_ PLARGE_INTEGER Offset, _In_ ULONG Length)
 
BOOLEAN NTAPI MmCheckDirtySegment (PMM_SECTION_SEGMENT Segment, PLARGE_INTEGER Offset, BOOLEAN ForceDirty, BOOLEAN PageOut)
 
BOOLEAN NTAPI MmUnsharePageEntrySectionSegment (PMEMORY_AREA MemoryArea, PMM_SECTION_SEGMENT Segment, PLARGE_INTEGER Offset, BOOLEAN Dirty, BOOLEAN PageOut, ULONG_PTR *InEntry)
 
 _When_ (OldIrql==MM_NOIRQL, _IRQL_requires_max_(DISPATCH_LEVEL)) _When_(OldIrql
 
 _Requires_lock_not_held_ (MmPfnLock)) _When_(OldIrql !
 
 _Releases_lock_ (MmPfnLock)) _When_(OldIrql !
 
 _IRQL_requires_ (DISPATCH_LEVEL)) VOID NTAPI MmDereferenceSegmentWithLock(_In_ PMM_SECTION_SEGMENT Segment
 
_In_ _When_ (OldIrql !=MM_NOIRQL, _IRQL_restores_) KIRQL OldIrql)
 
 _IRQL_requires_max_ (DISPATCH_LEVEL) _Requires_lock_not_held_(MmPfnLock) FORCEINLINE VOID MmDereferenceSegment(PMM_SECTION_SEGMENT Segment)
 
NTSTATUS NTAPI MmExtendSection (_In_ PVOID Section, _Inout_ PLARGE_INTEGER NewSize)
 
NTSTATUS NTAPI _MmSetPageEntrySectionSegment (PMM_SECTION_SEGMENT Segment, PLARGE_INTEGER Offset, ULONG_PTR Entry, const char *file, int line)
 
ULONG_PTR NTAPI _MmGetPageEntrySectionSegment (PMM_SECTION_SEGMENT Segment, PLARGE_INTEGER Offset, const char *file, int line)
 
VOID NTAPI MiReloadBootLoadedDrivers (IN PLOADER_PARAMETER_BLOCK LoaderBlock)
 
BOOLEAN NTAPI MiInitializeLoadedModuleList (IN PLOADER_PARAMETER_BLOCK LoaderBlock)
 
BOOLEAN NTAPI MmChangeKernelResourceSectionProtection (IN ULONG_PTR ProtectionMask)
 
VOID NTAPI MmMakeKernelResourceSectionWritable (VOID)
 
NTSTATUS NTAPI MmLoadSystemImage (IN PUNICODE_STRING FileName, IN PUNICODE_STRING NamePrefix OPTIONAL, IN PUNICODE_STRING LoadedName OPTIONAL, IN ULONG Flags, OUT PVOID *ModuleObject, OUT PVOID *ImageBaseAddress)
 
NTSTATUS NTAPI MmUnloadSystemImage (IN PVOID ImageHandle)
 
NTSTATUS NTAPI MmCheckSystemImage (IN HANDLE ImageHandle, IN BOOLEAN PurgeSection)
 
NTSTATUS NTAPI MmCallDllInitialize (_In_ PLDR_DATA_TABLE_ENTRY LdrEntry, _In_ PLIST_ENTRY ModuleListHead)
 
VOID NTAPI MmFreeDriverInitialization (IN PLDR_DATA_TABLE_ENTRY LdrEntry)
 
NTSTATUS NTAPI RtlpFindExportedRoutineByName (_In_ PVOID ImageBase, _In_ PCSTR ExportName, _Out_ PVOID *Function, _Out_opt_ PBOOLEAN IsForwarder, _In_ NTSTATUS NotFoundStatus)
 ReactOS-only helper routine for RtlFindExportedRoutineByName(), that provides a finer granularity regarding the nature of the export, and the failure reasons.
 
PVOID NTAPI RtlFindExportedRoutineByName (_In_ PVOID ImageBase, _In_ PCSTR ExportName)
 Finds the address of a given named exported routine in a loaded image. Note that this function does not support forwarders.
 
NTSTATUS NTAPI MmGrowKernelStack (IN PVOID StackPointer)
 
FORCEINLINE VOID MmLockAddressSpace (PMMSUPPORT AddressSpace)
 
FORCEINLINE VOID MmUnlockAddressSpace (PMMSUPPORT AddressSpace)
 
FORCEINLINE PEPROCESS MmGetAddressSpaceOwner (IN PMMSUPPORT AddressSpace)
 
FORCEINLINE PMMSUPPORT MmGetCurrentAddressSpace (VOID)
 
FORCEINLINE PMMSUPPORT MmGetKernelAddressSpace (VOID)
 
VOID NTAPI ExpCheckPoolAllocation (PVOID P, POOL_TYPE PoolType, ULONG Tag)
 
VOID NTAPI ExReturnPoolQuota (IN PVOID P)
 
NTSTATUS NTAPI MmAdjustWorkingSetSize (IN SIZE_T WorkingSetMinimumInBytes, IN SIZE_T WorkingSetMaximumInBytes, IN ULONG SystemCache, IN BOOLEAN IncreaseOkay)
 
 _IRQL_requires_max_ (APC_LEVEL) NTSTATUS NTAPI MmAttachSession(_Inout_ PVOID SessionEntry
 
VOID NTAPI MmQuitNextSession (_Inout_ PVOID SessionEntry)
 
PVOID NTAPI MmGetSessionById (_In_ ULONG SessionId)
 
VOID MmShutdownSystem (IN ULONG Phase)
 
NTSTATUS NTAPI MmCopyVirtualMemory (IN PEPROCESS SourceProcess, IN PVOID SourceAddress, IN PEPROCESS TargetProcess, OUT PVOID TargetAddress, IN SIZE_T BufferSize, IN KPROCESSOR_MODE PreviousMode, OUT PSIZE_T ReturnSize)
 
 _Requires_exclusive_lock_held_ (WorkingSet->WorkingSetMutex) VOID NTAPI MiInitializeWorkingSetList(_Inout_ PMMSUPPORT WorkingSet)
 

Variables

PMMSUPPORT MmKernelAddressSpace
 
PFN_COUNT MiFreeSwapPages
 
PFN_COUNT MiUsedSwapPages
 
PFN_COUNT MmNumberOfPhysicalPages
 
UCHAR MmDisablePagingExecutive
 
PFN_NUMBER MmLowestPhysicalPage
 
PFN_NUMBER MmHighestPhysicalPage
 
PFN_NUMBER MmAvailablePages
 
PFN_NUMBER MmResidentAvailablePages
 
ULONG MmThrottleTop
 
ULONG MmThrottleBottom
 
LIST_ENTRY MmLoadedUserImageList
 
KMUTANT MmSystemLoadLock
 
ULONG MmNumberOfPagingFiles
 
SIZE_T MmTotalNonPagedPoolQuota
 
SIZE_T MmTotalPagedPoolQuota
 
PVOID MmUnloadedDrivers
 
PVOID MmLastUnloadedDrivers
 
PVOID MmTriageActionTaken
 
PVOID KernelVerifier
 
MM_DRIVER_VERIFIER_DATA MmVerifierData
 
SIZE_T MmTotalCommitLimit
 
SIZE_T MmTotalCommittedPages
 
SIZE_T MmSharedCommit
 
SIZE_T MmDriverCommit
 
SIZE_T MmProcessCommit
 
SIZE_T MmPagedPoolCommit
 
SIZE_T MmPeakCommitment
 
SIZE_T MmtotalCommitLimitMaximum
 
PVOID MiDebugMapping
 
PMMPTE MmDebugPte
 
KSPIN_LOCK MmPfnLock
 
PMMPFN MmPfnDatabase
 
MMPFNLIST MmZeroedPageListHead
 
MMPFNLIST MmFreePageListHead
 
MMPFNLIST MmStandbyPageListHead
 
MMPFNLIST MmModifiedPageListHead
 
MMPFNLIST MmModifiedNoWritePageListHead
 
MM_MEMORY_CONSUMER MiMemoryConsumers [MC_MAXIMUM]
 
PMMPAGING_FILE MmPagingFile [MAX_PAGING_FILES]
 
_In_ SIZE_T CurrentMaxQuota
 
_In_ SIZE_T _Out_ PSIZE_T NewMaxQuota
 
_In_ SIZE_T QuotaToReturn
 
_In_ PVOID Address
 
_In_ PVOID _Out_opt_ BOOLEANWasDirty
 
_In_ PVOID _Out_opt_ BOOLEAN _Out_opt_ PPFN_NUMBER Page
 
_Out_ PKAPC_STATE ApcState
 

Macro Definition Documentation

◆ BUMPREF_SSE

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

Definition at line 1388 of file mm.h.

◆ CACHE_ALIGNED_POOL_MASK

#define CACHE_ALIGNED_POOL_MASK   4

Definition at line 120 of file mm.h.

◆ CLEAN_SSE

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

Definition at line 1376 of file mm.h.

◆ DECREF_SSE

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

Definition at line 1389 of file mm.h.

◆ DIRTY_SSE

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

Definition at line 1375 of file mm.h.

◆ EndOfAllocation

#define EndOfAllocation   WriteInProgress

Definition at line 356 of file mm.h.

◆ InterlockedCompareExchangePte

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

Definition at line 187 of file mm.h.

◆ InterlockedExchangePte

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

Definition at line 190 of file mm.h.

◆ IS_DIRTY_SSE

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

Definition at line 1377 of file mm.h.

◆ IS_SWAP_FROM_SSE

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

Definition at line 1369 of file mm.h.

◆ IS_WRITE_SSE

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

Definition at line 1379 of file mm.h.

◆ MA_GetEndingAddress

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

Definition at line 245 of file mm.h.

◆ MA_GetStartingAddress

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

Definition at line 244 of file mm.h.

◆ MAKE_PFN_SSE

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

Definition at line 1372 of file mm.h.

◆ MAKE_SSE

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

Definition at line 1387 of file mm.h.

◆ MAKE_SWAP_SSE

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

Definition at line 1374 of file mm.h.

◆ MAX_PAGING_FILES

#define MAX_PAGING_FILES   (16)

Definition at line 125 of file mm.h.

◆ MAX_SHARE_COUNT

#define MAX_SHARE_COUNT   0x1FF

Definition at line 1386 of file mm.h.

◆ MC_MAXIMUM

#define MC_MAXIMUM   (2)

Definition at line 116 of file mm.h.

◆ MC_SYSTEM

#define MC_SYSTEM   (1)

Definition at line 115 of file mm.h.

◆ MC_USER

#define MC_USER   (0)

Definition at line 114 of file mm.h.

◆ MEMORY_AREA_OWNED_BY_ARM3

#define MEMORY_AREA_OWNED_BY_ARM3   (15)

Definition at line 97 of file mm.h.

◆ MEMORY_AREA_SECTION_VIEW

#define MEMORY_AREA_SECTION_VIEW   (1)

Definition at line 93 of file mm.h.

◆ MEMORY_AREA_STATIC

#define MEMORY_AREA_STATIC   (0x80000000)

Definition at line 98 of file mm.h.

◆ MI_ASSERT_PFN_LOCK_HELD

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

Definition at line 1043 of file mm.h.

◆ MI_CHARGE_NON_PAGED_POOL_QUOTA

#define MI_CHARGE_NON_PAGED_POOL_QUOTA   0x10000

Definition at line 65 of file mm.h.

◆ MI_CHARGE_PAGED_POOL_QUOTA

#define MI_CHARGE_PAGED_POOL_QUOTA   0x80000

Definition at line 64 of file mm.h.

◆ MI_NON_PAGED_QUOTA_MIN_RESIDENT_PAGES

#define MI_NON_PAGED_QUOTA_MIN_RESIDENT_PAGES   200

Definition at line 63 of file mm.h.

◆ MI_QUOTA_NON_PAGED_NEEDED_PAGES

#define MI_QUOTA_NON_PAGED_NEEDED_PAGES   64

Definition at line 62 of file mm.h.

◆ MI_SET_PROCESS

#define MI_SET_PROCESS (   x)

Definition at line 318 of file mm.h.

◆ MI_SET_PROCESS2

#define MI_SET_PROCESS2 (   x)

Definition at line 319 of file mm.h.

◆ MI_SET_USAGE

#define MI_SET_USAGE (   x)

Definition at line 317 of file mm.h.

◆ MI_STATIC_MEMORY_AREAS

#define MI_STATIC_MEMORY_AREAS   (13)

Definition at line 90 of file mm.h.

◆ MM_DATAFILE_SEGMENT

#define MM_DATAFILE_SEGMENT   (0x2)

Definition at line 238 of file mm.h.

◆ MM_FREE_POOL_SIGNATURE

#define MM_FREE_POOL_SIGNATURE   'ARM3'

Definition at line 481 of file mm.h.

◆ MM_IMAGE_SECTION_FLUSH_DELETE

#define MM_IMAGE_SECTION_FLUSH_DELETE   (0x10)

Definition at line 241 of file mm.h.

◆ MM_IS_WAIT_PTE

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

Definition at line 1370 of file mm.h.

◆ MM_NOIRQL

#define MM_NOIRQL   ((KIRQL)0xFFFFFFFF)

Definition at line 70 of file mm.h.

◆ MM_PHYSICALMEMORY_SEGMENT

#define MM_PHYSICALMEMORY_SEGMENT   (0x1)

Definition at line 237 of file mm.h.

◆ MM_ROUND_DOWN

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

Definition at line 131 of file mm.h.

◆ MM_ROUND_UP

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

Definition at line 128 of file mm.h.

◆ MM_SEGMENT_INCREATE

#define MM_SEGMENT_INCREATE   (0x8)

Definition at line 240 of file mm.h.

◆ MM_SEGMENT_INDELETE

#define MM_SEGMENT_INDELETE   (0x4)

Definition at line 239 of file mm.h.

◆ MM_VIRTMEM_GRANULARITY

#define MM_VIRTMEM_GRANULARITY   (64 * 1024)

Definition at line 102 of file mm.h.

◆ MMDBG_COPY_CACHED

#define MMDBG_COPY_CACHED   0x00000008

Definition at line 78 of file mm.h.

◆ MMDBG_COPY_MAX_SIZE

#define MMDBG_COPY_MAX_SIZE   0x8

Definition at line 85 of file mm.h.

◆ MMDBG_COPY_PHYSICAL

#define MMDBG_COPY_PHYSICAL   0x00000002

Definition at line 76 of file mm.h.

◆ MMDBG_COPY_UNCACHED

#define MMDBG_COPY_UNCACHED   0x00000010

Definition at line 79 of file mm.h.

◆ MMDBG_COPY_UNSAFE

#define MMDBG_COPY_UNSAFE   0x00000004

Definition at line 77 of file mm.h.

◆ MMDBG_COPY_WRITE

#define MMDBG_COPY_WRITE   0x00000001

Definition at line 75 of file mm.h.

◆ MMDBG_COPY_WRITE_COMBINED

#define MMDBG_COPY_WRITE_COMBINED   0x00000020

Definition at line 80 of file mm.h.

◆ MmGetPageEntrySectionSegment

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

Definition at line 1602 of file mm.h.

◆ MmLockSectionSegment

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

Definition at line 1397 of file mm.h.

◆ MmSetCleanPage

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

Definition at line 1251 of file mm.h.

◆ MmSetDirtyPage

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

Definition at line 1252 of file mm.h.

◆ MmSetPageEntrySectionSegment

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

Definition at line 1600 of file mm.h.

◆ MmUnlockSectionSegment

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

Definition at line 1405 of file mm.h.

◆ MUST_SUCCEED_POOL_MASK

#define MUST_SUCCEED_POOL_MASK   2

Definition at line 119 of file mm.h.

◆ PAGE_FLAGS_VALID_FOR_SECTION

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

Definition at line 134 of file mm.h.

◆ PAGE_FROM_SSE

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

Definition at line 1383 of file mm.h.

◆ PAGE_IS_EXECUTABLE

#define PAGE_IS_EXECUTABLE
Value:

Definition at line 159 of file mm.h.

◆ PAGE_IS_READABLE

#define PAGE_IS_READABLE

◆ PAGE_IS_WRITABLE

#define PAGE_IS_WRITABLE
Value:

Definition at line 153 of file mm.h.

◆ PAGE_IS_WRITECOPY

#define PAGE_IS_WRITECOPY
Value:

Definition at line 165 of file mm.h.

◆ PAGE_SYSTEM

#define PAGE_SYSTEM   (2048)

Definition at line 110 of file mm.h.

◆ PAGE_WRITETHROUGH

#define PAGE_WRITETHROUGH   (1024)

Definition at line 109 of file mm.h.

◆ PAGED_POOL_MASK

#define PAGED_POOL_MASK   1

Definition at line 118 of file mm.h.

◆ PFN_FROM_SSE

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

Definition at line 1368 of file mm.h.

◆ QUOTA_POOL_MASK

#define QUOTA_POOL_MASK   8

Definition at line 121 of file mm.h.

◆ RMAP_IS_SEGMENT

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

Definition at line 940 of file mm.h.

◆ RMAP_SEGMENT_MASK

#define RMAP_SEGMENT_MASK   ~((ULONG_PTR)0xff)

Definition at line 939 of file mm.h.

◆ SEC_PHYSICALMEMORY

#define SEC_PHYSICALMEMORY   (0x80000000)

Definition at line 112 of file mm.h.

◆ SESSION_POOL_MASK

#define SESSION_POOL_MASK   32

Definition at line 122 of file mm.h.

◆ SHARE_COUNT_FROM_SSE

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

Definition at line 1385 of file mm.h.

◆ StartOfAllocation

#define StartOfAllocation   ReadInProgress

Definition at line 355 of file mm.h.

◆ STATUS_MM_RESTART_OPERATION

#define STATUS_MM_RESTART_OPERATION   ((NTSTATUS)0xD0000001)

Definition at line 104 of file mm.h.

◆ SWAPENTRY_FROM_SSE

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

Definition at line 1373 of file mm.h.

◆ VERIFIER_POOL_MASK

#define VERIFIER_POOL_MASK   64

Definition at line 123 of file mm.h.

◆ WRITE_SSE

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

Definition at line 1378 of file mm.h.

Typedef Documentation

◆ MEMORY_AREA

◆ MI_PFN_USAGES

◆ MM_IMAGE_SECTION_OBJECT

◆ MM_MEMORY_CONSUMER

◆ MM_PAGED_POOL_INFO

◆ MM_REGION

◆ MM_RMAP_ENTRY

◆ MM_SECTION_SEGMENT

◆ MMFREE_POOL_ENTRY

◆ MMPAGING_FILE

◆ MMPFN

typedef struct _MMPFN MMPFN

◆ MMPFNENTRY

◆ MMPFNLIST

◆ PMEMORY_AREA

◆ PMM_ALTER_REGION_FUNC

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

Definition at line 515 of file mm.h.

◆ PMM_FREE_PAGE_FUNC

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

Definition at line 526 of file mm.h.

◆ PMM_IMAGE_SECTION_OBJECT

◆ PMM_MEMORY_CONSUMER

◆ PMM_PAGED_POOL_INFO

◆ PMM_REGION

◆ PMM_RMAP_ENTRY

◆ PMM_SECTION_SEGMENT

◆ PMMFREE_POOL_ENTRY

◆ PMMPAGING_FILE

◆ PMMPFN

typedef struct _MMPFN * PMMPFN

◆ PMMPFNLIST

◆ SWAPENTRY

Definition at line 57 of file mm.h.

Enumeration Type Documentation

◆ _MI_PFN_USAGES

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

Definition at line 322 of file mm.h.

323{
enum _MI_PFN_USAGES MI_PFN_USAGES
@ MI_USAGE_NONPAGED_POOL_EXPANSION
Definition: mm.h:327
@ MI_USAGE_LEGACY_PAGE_DIRECTORY
Definition: mm.h:336
@ MI_USAGE_PAGE_FILE
Definition: mm.h:346
@ MI_USAGE_NOT_SET
Definition: mm.h:324
@ MI_USAGE_COW
Definition: mm.h:347
@ MI_USAGE_PEB_TEB
Definition: mm.h:332
@ MI_USAGE_PAGE_TABLE
Definition: mm.h:334
@ MI_USAGE_INIT_MEMORY
Definition: mm.h:345
@ MI_USAGE_VAD
Definition: mm.h:331
@ MI_USAGE_SYSTEM_PTE
Definition: mm.h:330
@ MI_USAGE_CONTINOUS_ALLOCATION
Definition: mm.h:338
@ MI_USAGE_PAGED_POOL
Definition: mm.h:325
@ MI_USAGE_MDL
Definition: mm.h:339
@ MI_USAGE_PFN_DATABASE
Definition: mm.h:343
@ MI_USAGE_ZERO_LOOP
Definition: mm.h:341
@ MI_USAGE_DRIVER_PAGE
Definition: mm.h:337
@ MI_USAGE_DEMAND_ZERO
Definition: mm.h:340
@ MI_USAGE_SECTION
Definition: mm.h:333
@ MI_USAGE_WSLE
Definition: mm.h:348
@ MI_USAGE_FREE_PAGE
Definition: mm.h:349
@ MI_USAGE_PAGE_DIRECTORY
Definition: mm.h:335
@ MI_USAGE_CACHE
Definition: mm.h:342
@ MI_USAGE_KERNEL_STACK_EXPANSION
Definition: mm.h:329
@ MI_USAGE_KERNEL_STACK
Definition: mm.h:328
@ MI_USAGE_NONPAGED_POOL
Definition: mm.h:326
@ MI_USAGE_BOOT_DRIVER
Definition: mm.h:344

Function Documentation

◆ _IRQL_raises_()

_IRQL_raises_ ( DISPATCH_LEVEL  )

Definition at line 992 of file mm.h.

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

◆ _IRQL_requires_()

_IRQL_requires_ ( DISPATCH_LEVEL  )

◆ _IRQL_requires_max_() [1/2]

_IRQL_requires_max_ ( APC_LEVEL  )

Definition at line 37 of file cddata.c.

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

◆ _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:1150

◆ _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 STATUS_NO_MEMORY
Definition: d3dkmdt.h:51
#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_SUCCESS
Definition: shellext.h:65
#define DPRINT
Definition: sndvol32.h:73
static PCACHE_SECTION_PAGE_TABLE NTAPI MiSectionPageTableGetOrAllocate(PRTL_GENERIC_TABLE Table, PLARGE_INTEGER FileOffset)
Definition: sptab.c:136
NTSTATUS NTAPI MmSetSectionAssociation(PFN_NUMBER Page, PMM_SECTION_SEGMENT Segment, PLARGE_INTEGER Offset)
Definition: sptab.c:400
base of all file and directory entries
Definition: entries.h:83
LONGLONG QuadPart
Definition: typedefs.h:114

◆ _MmUnlockSectionSegment()

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

Definition at line 107 of file data.c.

108{
109 ASSERT(Segment->Locked);
110 Segment->Locked = FALSE;
112 //DPRINT("MmUnlockSectionSegment(%p,%s:%d)\n", Segment, file, line);
113}
VOID FASTCALL ExReleaseFastMutex(IN PFAST_MUTEX FastMutex)
Definition: fmutex.c:31

◆ _Releases_lock_()

_Releases_lock_ ( MmPfnLock  )

◆ _Requires_exclusive_lock_held_()

_Requires_exclusive_lock_held_ ( WorkingSet->  WorkingSetMutex)

◆ _Requires_lock_held_() [1/2]

_Requires_lock_held_ ( MmPfnLock  )

Definition at line 1004 of file mm.h.

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

◆ _Requires_lock_held_() [2/2]

_Requires_lock_held_ ( PspQuotaLock  )

◆ _Requires_lock_not_held_()

_Requires_lock_not_held_ ( MmPfnLock  )

◆ _Success_()

_Success_ ( return  )

◆ _When_() [1/2]

_In_ _When_ ( OldIrql = MM_NOIRQL,
_IRQL_restores_   
)

◆ _When_() [2/2]

◆ ExpCheckPoolAllocation()

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

Definition at line 296 of file expool.c.

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

◆ ExReturnPoolQuota()

VOID NTAPI ExReturnPoolQuota ( IN PVOID  P)

Definition at line 1852 of file expool.c.

1853{
1856 USHORT BlockSize;
1858
1861 {
1862 return;
1863 }
1864
1865 Entry = P;
1866 Entry--;
1868
1869 PoolType = Entry->PoolType - 1;
1870 BlockSize = Entry->BlockSize;
1871
1873 {
1874 Process = ((PVOID *)POOL_NEXT_BLOCK(Entry))[-1];
1875 ASSERT(Process != NULL);
1876 if (Process)
1877 {
1878 if (Process->Pcb.Header.Type != ProcessObject)
1879 {
1880 DPRINT1("Object %p is not a process. Type %u, pool type 0x%x, block size %u\n",
1881 Process, Process->Pcb.Header.Type, Entry->PoolType, BlockSize);
1882 KeBugCheckEx(BAD_POOL_CALLER,
1884 (ULONG_PTR)P,
1885 Entry->PoolTag,
1887 }
1888 ((PVOID *)POOL_NEXT_BLOCK(Entry))[-1] = NULL;
1891 BlockSize * POOL_BLOCK_SIZE);
1893 }
1894 }
1895}
#define QUOTA_POOL_MASK
Definition: ExPools.c:16
#define POOL_NEXT_BLOCK(x)
Definition: expool.c:64
ULONG ExpPoolFlags
Definition: expool.c:56
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:223
#define POOL_BILLED_PROCESS_INVALID
Definition: miarm.h:320
#define POOL_BLOCK_SIZE
Definition: miarm.h:283
#define POOL_FLAG_SPECIAL_POOL
Definition: miarm.h:297
@ 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 RtlClearBits
Definition: dbgbitmap.h:331
#define RtlFindClearBitsAndSet
Definition: dbgbitmap.h:333
#define RtlSetBit
Definition: dbgbitmap.h:344
#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
@ NonPagedPoolExpansion
Definition: miarm.h:418
PVOID MmPagedPoolStart
Definition: miarm.h:588
#define MI_GET_NEXT_COLOR()
Definition: miarm.h:246
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:203
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:1031
FORCEINLINE VOID MI_WRITE_INVALID_PTE(IN PMMPTE PointerPte, IN MMPTE InvalidPte)
Definition: miarm.h:1006
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:973
#define MiAddressToPte(x)
Definition: mmx86.c:19
#define MiAddressToPde(x)
Definition: mmx86.c:20
#define min(a, b)
Definition: monoChain.cc:55
@ ActiveAndValid
Definition: mmtypes.h:159
#define MI_MAX_FREE_PAGE_LISTS
Definition: mm.h:80
#define PFN_FROM_PTE(v)
Definition: mm.h:92
#define MiPteToPde(_Pte)
Definition: mm.h:121
#define PTE_PER_PAGE
Definition: mm.h:20
#define MiPteToAddress(_Pte)
Definition: mm.h:116
#define PDE_PER_PAGE
Definition: mm.h:21
#define MiPdeToPte(_Pde)
Definition: mm.h:120
#define VERIFIER_POOL_MASK
Definition: mm.h:123
FORCEINLINE PMMPFN MiGetPfnEntry(IN PFN_NUMBER Pfn)
Definition: mm.h:1047
#define MI_SET_PROCESS2(x)
Definition: mm.h:319
#define MI_SET_USAGE(x)
Definition: mm.h:317
PFN_NUMBER MmAvailablePages
Definition: freelist.c:26
#define MM_FREE_POOL_SIGNATURE
Definition: mm.h:481
VOID NTAPI KeFlushEntireTb(IN BOOLEAN Invalid, IN BOOLEAN AllProcessors)
Definition: cpu.c:652
PMMPDE MmSystemPagePtes
Definition: init.c:41
PFN_NUMBER MmSystemPageDirectory[PPE_PER_PAGE]
Definition: init.c:40
VOID NTAPI MiProtectedPoolRemoveEntryList(IN PLIST_ENTRY Entry)
Definition: pool.c:168
BOOLEAN MmProtectFreedNonPagedPool
Definition: pool.c:31
KGUARDED_MUTEX MmPagedPoolMutex
Definition: pool.c:24
MM_PAGED_POOL_INFO MmPagedPoolInfo
Definition: pool.c:25
SLIST_HEADER MiNonPagedPoolSListHead
Definition: pool.c:32
VOID NTAPI MiProtectFreeNonPagedPool(IN PVOID VirtualAddress, IN ULONG PageCount)
Definition: pool.c:41
LIST_ENTRY MmNonPagedPoolFreeListHead[MI_MAX_FREE_PAGE_LISTS]
Definition: pool.c:20
SLIST_HEADER MiPagedPoolSListHead
Definition: pool.c:34
BOOLEAN NTAPI MiUnProtectFreeNonPagedPool(IN PVOID VirtualAddress, IN ULONG PageCount)
Definition: pool.c:70
VOID NTAPI MiProtectedPoolInsertList(IN PLIST_ENTRY ListHead, IN PLIST_ENTRY Entry, IN BOOLEAN Critical)
Definition: pool.c:150
MMPTE ValidKernelPte
Definition: init.c:29
MMPTE ValidKernelPde
Definition: init.c:28
ULONG PFN_NUMBER
Definition: ke.h:9
ULONG PageFrameNumber
Definition: mmtypes.h:74
ULONG PageFrameNumber
Definition: mmtypes.h:109
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
Definition: mm.h:473
ULONG Signature
Definition: mm.h:476
PFN_COUNT Size
Definition: mm.h:475
LIST_ENTRY List
Definition: mm.h:474
USHORT PageLocation
Definition: mm.h:365
Definition: mm.h:374
PMMPTE PteAddress
Definition: mm.h:386
union _MMPFN::@1803 u3
union _MMPFN::@1802 u2
union _MMPFN::@1806 u4
MMPFNENTRY e1
Definition: mm.h:397
ULONG_PTR VerifierAllocation
Definition: mm.h:420
ULONG_PTR ShareCount
Definition: mm.h:390
struct _MMPFN::@1803::@1809 e2
ULONG64 Valid
Definition: mmtypes.h:150
ULONG64 PageFrameNumber
Definition: mmtypes.h:171
union _MMPTE::@2337 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
#define InterlockedPopEntrySList(SListHead)
Definition: rtlfuncs.h:3409

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:417
FORCEINLINE VOID MI_MAKE_HARDWARE_PTE_KERNEL(IN PMMPTE NewPte, IN PMMPTE MappingPte, IN ULONG_PTR ProtectionMask, IN PFN_NUMBER PageFrameNumber)
Definition: miarm.h:787
#define MI_GET_NEXT_PROCESS_COLOR(x)
Definition: miarm.h:247
FORCEINLINE PFN_NUMBER MiRemoveZeroPageSafe(IN ULONG Color)
Definition: miarm.h:2413
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}
#define RtlClearBit
Definition: dbgbitmap.h:330
#define RtlTestBit
Definition: dbgbitmap.h:347
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
struct _MMFREE_POOL_ENTRY * Owner
Definition: mm.h:477
#define InterlockedPushEntrySList(SListHead, SListEntry)
Definition: rtlfuncs.h:3406

Referenced by _IRQL_requires_(), and ExFreePoolWithTag().

◆ MiGetPfnEntry()

FORCEINLINE PMMPFN MiGetPfnEntry ( IN PFN_NUMBER  Pfn)

Definition at line 1047 of file mm.h.

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

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

◆ MiGetPfnEntryIndex()

FORCEINLINE PFN_NUMBER MiGetPfnEntryIndex ( IN PMMPFN  Pfn1)

◆ MiInitBalancerThread()

VOID NTAPI MiInitBalancerThread ( VOID  )

Definition at line 420 of file balance.c.

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

Referenced by MmInitSystem().

◆ MiInitializeLoadedModuleList()

BOOLEAN NTAPI MiInitializeLoadedModuleList ( IN PLOADER_PARAMETER_BLOCK  LoaderBlock)

Definition at line 2242 of file sysldr.c.

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

Referenced by MmArmInitSystem().

◆ MiInitializeNonPagedPool()

VOID NTAPI MiInitializeNonPagedPool ( VOID  )

Definition at line 278 of file pool.c.

279{
280 ULONG i;
281 PFN_COUNT PoolPages;
282 PMMFREE_POOL_ENTRY FreeEntry, FirstEntry;
283 PMMPTE PointerPte;
284 PAGED_CODE();
285
286 //
287 // Initialize the pool S-LISTs as well as their maximum count. In general,
288 // we'll allow 8 times the default on a 2GB system, and two times the default
289 // on a 1GB system.
290 //
293 if (MmNumberOfPhysicalPages >= ((2 * _1GB) /PAGE_SIZE))
294 {
297 }
299 {
302 }
303
304 //
305 // However if debugging options for the pool are enabled, turn off the S-LIST
306 // to reduce the risk of messing things up even more
307 //
309 {
312 }
313
314 //
315 // We keep 4 lists of free pages (4 lists help avoid contention)
316 //
317 for (i = 0; i < MI_MAX_FREE_PAGE_LISTS; i++)
318 {
319 //
320 // Initialize each of them
321 //
323 }
324
325 //
326 // Calculate how many pages the initial nonpaged pool has
327 //
329 MmNumberOfFreeNonPagedPool = PoolPages;
330
331 //
332 // Initialize the first free entry
333 //
334 FreeEntry = MmNonPagedPoolStart;
335 FirstEntry = FreeEntry;
336 FreeEntry->Size = PoolPages;
338 FreeEntry->Owner = FirstEntry;
339
340 //
341 // Insert it into the last list
342 //
344 &FreeEntry->List);
345
346 //
347 // Now create free entries for every single other page
348 //
349 while (PoolPages-- > 1)
350 {
351 //
352 // Link them all back to the original entry
353 //
354 FreeEntry = (PMMFREE_POOL_ENTRY)((ULONG_PTR)FreeEntry + PAGE_SIZE);
355 FreeEntry->Owner = FirstEntry;
357 }
358
359 //
360 // Validate and remember first allocated pool page
361 //
363 ASSERT(PointerPte->u.Hard.Valid == 1);
365
366 //
367 // Keep track of where initial nonpaged pool ends
368 //
371
372 //
373 // Validate and remember last allocated pool page
374 //
375 PointerPte = MiAddressToPte((PVOID)((ULONG_PTR)MmNonPagedPoolEnd0 - 1));
376 ASSERT(PointerPte->u.Hard.Valid == 1);
378
379 //
380 // Validate the first nonpaged pool expansion page (which is a guard page)
381 //
383 ASSERT(PointerPte->u.Hard.Valid == 0);
384
385 //
386 // Calculate the size of the expansion region alone
387 //
390
391 //
392 // Remove 2 pages, since there's a guard page on top and on the bottom
393 //
395
396 //
397 // Now initialize the nonpaged pool expansion PTE space. Remember there's a
398 // guard page on top so make sure to skip it. The bottom guard page will be
399 // guaranteed by the fact our size is off by one.
400 //
401 MiInitializeSystemPtes(PointerPte + 1,
404}
#define PAGED_CODE()
#define InsertHeadList(ListHead, Entry)
VOID NTAPI MiInitializeSystemPtes(IN PMMPTE StartingPte, IN ULONG NumberOfPtes, IN MMSYSTEM_PTE_POOL_TYPE PoolType)
Definition: syspte.c:388
#define _1GB
Definition: miarm.h:20
PFN_COUNT MmNumberOfPhysicalPages
Definition: init.c:48
ULONG MmMaximumNonPagedPoolInBytes
Definition: init.c:22
ULONG MmSizeOfNonPagedPoolInBytes
Definition: init.c:21
PVOID MmNonPagedPoolExpansionStart
Definition: init.c:25
PVOID MmNonPagedPoolStart
Definition: init.c:24
PFN_COUNT MmNumberOfFreeNonPagedPool
Definition: pool.c:21
PFN_COUNT MiExpansionPoolPagesInitialCharge
Definition: pool.c:21
PVOID MmNonPagedPoolEnd0
Definition: pool.c:22
FORCEINLINE VOID InitializeSListHead(_Out_ PSLIST_HEADER SListHead)
Definition: rtlfuncs.h:3368

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
#define STATUS_PENDING
Definition: d3dkmdt.h:43
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
PFILE_OBJECT FileObject
Definition: mm.h:506
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
PVOID PMDL
Definition: usb.h:39
_In_ WDFDEVICE _In_ PVOID _In_opt_ PMDL Mdl
@ Executive
Definition: ketypes.h:415
#define MmInitializeMdl(_MemoryDescriptorList, _BaseVa, _Length)
MDL
Definition: mmtypes.h:117
#define MDL_PAGES_LOCKED
Definition: mmtypes.h:19
#define MDL_IO_PAGE_READ
Definition: mmtypes.h:24
#define MDL_MAPPED_TO_SYSTEM_VA
Definition: mmtypes.h:18
unsigned char UCHAR
Definition: xmlstorage.h:181

Referenced by MiResolvePageFileFault(), and MmReadFromSwapPage().

◆ MiReloadBootLoadedDrivers()

VOID NTAPI MiReloadBootLoadedDrivers ( IN PLOADER_PARAMETER_BLOCK  LoaderBlock)

Definition at line 1731 of file sysldr.c.

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

Referenced by MmArmInitSystem().

◆ MiRosCheckMemoryAreas()

VOID NTAPI MiRosCheckMemoryAreas ( PMMSUPPORT  AddressSpace)

◆ MiRosCleanupMemoryArea()

VOID NTAPI MiRosCleanupMemoryArea ( PEPROCESS  Process,
PMMVAD  Vad 
)

Definition at line 521 of file marea.c.

524{
528
529 /* We must be called from MmCleanupAddressSpace and nowhere else!
530 Make sure things are as expected... */
532 ASSERT(Process->VmDeleted == TRUE);
533 ASSERT(((PsGetCurrentThread()->ThreadsProcess == Process) &&
534 (Process->ActiveThreads == 1)) ||
535 (Process->ActiveThreads == 0));
536
539
541 {
543 }
544#ifdef NEWCC
545 else if (MemoryArea->Type == MEMORY_AREA_CACHE)
546 {
548 }
549#endif
550 else
551 {
552 /* There shouldn't be anything else! */
553 ASSERT(FALSE);
554 }
555
556 /* Make sure this worked! */
558}
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
NTSTATUS NTAPI MiRosUnmapViewOfSection(IN PEPROCESS Process, IN PVOID BaseAddress, IN BOOLEAN SkipDebuggerNotify)
Definition: section.c:3594
_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 218 of file mmfault.c.

222{
225 BOOLEAN IsArm3Fault = FALSE;
226
227 /* Cute little hack for ROS */
229 {
230#ifdef _M_IX86
231 /* Check for an invalid page directory in kernel mode */
233 {
234 /* All is well with the world */
235 return STATUS_SUCCESS;
236 }
237#endif
238 }
239
240 /* Handle shared user page / page table, which don't have a VAD / MemoryArea */
243 {
244 /* This is an ARM3 fault */
245 DPRINT("ARM3 fault %p\n", Address);
246 return MmArmAccessFault(FaultCode, Address, Mode, TrapInformation);
247 }
248
249 /* Is there a ReactOS address space yet? */
251 {
253 {
254 /* Check if this is an ARM3 memory area */
257
259 {
260 IsArm3Fault = TRUE;
261 }
262
264 }
265 else
266 {
267 /* Could this be a VAD fault from user-mode? */
270
272 {
273 IsArm3Fault = TRUE;
274 }
275
277 }
278 }
279
280 /* Is this an ARM3 memory area, or is there no address space yet? */
281 if (IsArm3Fault ||
282 ((MemoryArea == NULL) &&
286 {
287 /* This is an ARM3 fault */
288 DPRINT("ARM3 fault %p\n", MemoryArea);
289 return MmArmAccessFault(FaultCode, Address, Mode, TrapInformation);
290 }
291
292Retry:
293 /* Keep same old ReactOS Behaviour */
294 if (!MI_IS_NOT_PRESENT_FAULT(FaultCode))
295 {
296 /* Call access fault */
297 Status = MmpAccessFault(Mode, (ULONG_PTR)Address, TrapInformation ? FALSE : TRUE, FaultCode);
298 }
299 else
300 {
301 /* Call not present */
302 Status = MmNotPresentFault(Mode, (ULONG_PTR)Address, TrapInformation ? FALSE : TRUE);
303 }
304
306 {
308 goto Retry;
309 }
310
311 return Status;
312}
#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:1159
FORCEINLINE VOID MiUnlockProcessWorkingSetShared(IN PEPROCESS Process, IN PETHREAD Thread)
Definition: miarm.h:1228
#define MI_IS_PAGE_TABLE_ADDRESS(Address)
Definition: miarm.h:191
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:1319
FORCEINLINE VOID MiUnlockWorkingSetShared(_In_ PETHREAD Thread, _In_ PMMSUPPORT WorkingSet)
Definition: miarm.h:1402
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:120
NTSTATUS NTAPI MmpAccessFault(KPROCESSOR_MODE Mode, ULONG_PTR Address, BOOLEAN FromMdl, ULONG FaultCode)
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 1915 of file section.c.

1919{
1921 PFN_NUMBER OldPage;
1922 PFN_NUMBER NewPage;
1923 PFN_NUMBER UnmappedPage;
1924 PVOID PAddress;
1929 BOOLEAN Cow = FALSE;
1931 BOOLEAN Unmapped;
1933
1934 DPRINT("MmAccessFaultSectionView(%p, %p, %p)\n", AddressSpace, MemoryArea, Address);
1935
1936 /* Get the region for this address */
1938 &MemoryArea->SectionData.RegionListHead,
1939 Address, NULL);
1940 ASSERT(Region != NULL);
1941 if (!(Region->Protect & PAGE_IS_WRITABLE))
1943
1944 /* Make sure we have a page mapping for this address. */
1946 {
1948 if (!NT_SUCCESS(Status))
1949 {
1950 /* This is invalid access ! */
1951 return Status;
1952 }
1953 }
1954
1955 /*
1956 * Check if the page has already been set readwrite
1957 */
1959 {
1960 DPRINT("Address 0x%p\n", Address);
1961 return STATUS_SUCCESS;
1962 }
1963
1964 /* Check if we are doing Copy-On-Write */
1965 Segment = MemoryArea->SectionData.Segment;
1966 Cow = Segment->WriteCopy || (Region->Protect & PAGE_IS_WRITECOPY);
1967
1968 if (!Cow)
1969 {
1970 /* Simply update page protection and we're done */
1972 return STATUS_SUCCESS;
1973 }
1974
1975 /* Calculate the new protection & check if we should update the region */
1976 NewProtect = Region->Protect;
1978 {
1979 NewProtect &= ~PAGE_IS_WRITECOPY;
1980 if (Region->Protect & PAGE_IS_EXECUTABLE)
1982 else
1985 &MemoryArea->SectionData.RegionListHead,
1988 }
1989
1990 /*
1991 * Find the offset of the page
1992 */
1993 PAddress = MM_ROUND_DOWN(Address, PAGE_SIZE);
1994 Offset.QuadPart = (ULONG_PTR)PAddress - MA_GetStartingAddress(MemoryArea)
1995 + MemoryArea->SectionData.ViewOffset;
1996
1997 /* Get the page mapping this section offset. */
2000
2001 /* Get the current page mapping for the process */
2002 ASSERT(MmIsPagePresent(Process, PAddress));
2003 OldPage = MmGetPfnForProcess(Process, PAddress);
2004 ASSERT(OldPage != 0);
2005
2006 if (IS_SWAP_FROM_SSE(Entry) ||
2007 PFN_FROM_SSE(Entry) != OldPage)
2008 {
2010 /* This is a private page. We must only change the page protection. */
2012 return STATUS_SUCCESS;
2013 }
2014
2015 /*
2016 * Allocate a page
2017 */
2019 if (!NT_SUCCESS(Status))
2020 {
2022 return STATUS_NO_MEMORY;
2023 }
2024
2025 /*
2026 * Copy the old page
2027 */
2028 NT_VERIFY(NT_SUCCESS(MiCopyFromUserPage(NewPage, PAddress)));
2029
2030 /*
2031 * Unshare the old page.
2032 */
2033 DPRINT("Swapping page (Old %x New %x)\n", OldPage, NewPage);
2034 Unmapped = MmDeleteVirtualMapping(Process, PAddress, NULL, &UnmappedPage);
2035 if (!Unmapped || (UnmappedPage != OldPage))
2036 {
2037 /* Uh , we had a page just before, but suddenly it changes. Someone corrupted us. */
2038 KeBugCheckEx(MEMORY_MANAGEMENT,
2040 (ULONG_PTR)PAddress,
2041 (ULONG_PTR)__FILE__,
2042 __LINE__);
2043 }
2044
2045 if (Process)
2046 MmDeleteRmap(OldPage, Process, PAddress);
2049
2050 /*
2051 * Set the PTE to point to the new page
2052 */
2053 if (!NT_SUCCESS(MmCreateVirtualMapping(Process, PAddress, NewProtect, NewPage)))
2054 {
2055 DPRINT1("MmCreateVirtualMapping failed, unable to create virtual mapping, not out of memory\n");
2056 KeBugCheck(MEMORY_MANAGEMENT);
2057 }
2058
2059 if (Process)
2060 MmInsertRmap(NewPage, Process, PAddress);
2061
2062 DPRINT("Address 0x%p\n", Address);
2063 return STATUS_SUCCESS;
2064}
_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:1537
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::@1800 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:3304

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: ntoskrnl.c:15
#define STATUS_NOT_IMPLEMENTED
Definition: d3dkmdt.h:42
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:1278
FORCEINLINE VOID MiUnlockWorkingSet(IN PETHREAD Thread, IN PMMSUPPORT WorkingSet)
Definition: miarm.h:1364
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
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 602 of file freelist.c.

603{
604 PFN_NUMBER PfnOffset;
605 PMMPFN Pfn1;
607
608 OldIrql = MiAcquirePfnLock();
609
610#if MI_TRACE_PFNS
611 switch(Type)
612 {
613 case MC_SYSTEM:
615 break;
616 case MC_USER:
618 break;
619 default:
620 ASSERT(FALSE);
621 }
622#endif
623
624 PfnOffset = MiRemoveZeroPage(MI_GET_NEXT_COLOR());
625 if (!PfnOffset)
626 {
627 MiReleasePfnLock(OldIrql);
628 return 0;
629 }
630
631 DPRINT("Legacy allocate: %lx\n", PfnOffset);
632 Pfn1 = MiGetPfnEntry(PfnOffset);
633 Pfn1->u3.e2.ReferenceCount = 1;
635
636 /* This marks the PFN as a ReactOS PFN */
637 Pfn1->u4.AweAllocation = TRUE;
638
639 /* Allocate the extra ReactOS Data and zero it out */
640 Pfn1->u1.SwapEntry = 0;
641 Pfn1->RmapListHead = NULL;
642
643 Pfn1->NextLRU = NULL;
644 Pfn1->PreviousLRU = NULL;
645
646 if (Type == MC_USER)
647 {
648 Pfn1->u4.MustBeCached = 1; /* HACK again */
649 MmInsertLRULastUserPage(PfnOffset);
650 }
651
652 MiReleasePfnLock(OldIrql);
653 return PfnOffset;
654}
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
union _MMPFN::@1801 u1
struct _MMPFN * NextLRU
Definition: mm.h:435
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 4780 of file section.c.

4784{
4786 BOOLEAN Ret = TRUE;
4788 LARGE_INTEGER SegmentOffset, RangeEnd;
4790
4792
4794 if (MemoryArea == NULL)
4795 {
4797 return FALSE;
4798 }
4799
4800 /* Only supported in old Mm for now */
4802 /* For file mappings */
4804
4805 Segment = MemoryArea->SectionData.Segment;
4807
4809 + MemoryArea->SectionData.ViewOffset;
4811 + MemoryArea->SectionData.ViewOffset;
4812
4813 while (SegmentOffset.QuadPart < RangeEnd.QuadPart)
4814 {
4816 if ((Entry == 0) || IS_SWAP_FROM_SSE(Entry))
4817 {
4818 Ret = FALSE;
4819 break;
4820 }
4821 SegmentOffset.QuadPart += PAGE_SIZE;
4822 }
4823
4825
4827 return Ret;
4828}
@ 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
union _MMVAD::@2618 u
MMVAD_FLAGS VadFlags
Definition: mmtypes.h:734

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 433 of file sysldr.c.

436{
438 L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\");
439 PMM_DLL_INITIALIZE DllInit;
440 UNICODE_STRING RegPath, ImportName;
443
444 PAGED_CODE();
445
446 /* Try to see if the image exports a DllInitialize routine */
447 DllInit = (PMM_DLL_INITIALIZE)
448 RtlFindExportedRoutineByName(LdrEntry->DllBase, "DllInitialize");
449 if (!DllInit)
450 return STATUS_SUCCESS;
451
452 /* Make a temporary copy of BaseDllName because we will alter its length */
453 ImportName.Length = LdrEntry->BaseDllName.Length;
454 ImportName.MaximumLength = LdrEntry->BaseDllName.MaximumLength;
455 ImportName.Buffer = LdrEntry->BaseDllName.Buffer;
456
457 /* Obtain the path to this dll's service in the registry */
458 RegPath.MaximumLength = ServicesKeyName.Length +
459 ImportName.Length + sizeof(UNICODE_NULL);
461 RegPath.MaximumLength,
463
464 /* Check if this allocation was unsuccessful */
465 if (!RegPath.Buffer)
467
468 /* Build and append the service name itself */
469 RegPath.Length = ServicesKeyName.Length;
470 RtlCopyMemory(RegPath.Buffer,
471 ServicesKeyName.Buffer,
472 ServicesKeyName.Length);
473
474 /* If the filename has an extension, remove it */
475 Extension = wcschr(ImportName.Buffer, L'.');
476 if (Extension)
477 ImportName.Length = (USHORT)(Extension - ImportName.Buffer) * sizeof(WCHAR);
478
479 /* Append the service name (base name without extension) */
480 RtlAppendUnicodeStringToString(&RegPath, &ImportName);
481
482 /* Now call DllInitialize */
483 DPRINT("Calling DllInit(%wZ)\n", &RegPath);
484 Status = DllInit(&RegPath);
485
486 /* Clean up */
488
489 // TODO: This is for Driver Verifier support.
491
492 /* Return the DllInitialize status value */
493 return Status;
494}
#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:419
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:401
#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 2331 of file sysldr.c.

2332{
2333 PMMPTE PointerPte;
2334 MMPTE TempPte;
2335
2336 /* Don't do anything if the resource section is already writable */
2338 return FALSE;
2339
2340 /* If the resource section is physical, we cannot change its protection */
2342 return FALSE;
2343
2344 /* Loop the PTEs */
2345 for (PointerPte = MiKernelResourceStartPte; PointerPte < MiKernelResourceEndPte; ++PointerPte)
2346 {
2347 /* Read the PTE */
2348 TempPte = *PointerPte;
2349
2350 /* Update the protection */
2351 MI_MAKE_HARDWARE_PTE_KERNEL(&TempPte, PointerPte, ProtectionMask, TempPte.u.Hard.PageFrameNumber);
2352 MI_UPDATE_VALID_PTE(PointerPte, TempPte);
2353 }
2354
2355 /* Only flush the current processor's TLB */
2357 return TRUE;
2358}
FORCEINLINE BOOLEAN MI_IS_PHYSICAL_ADDRESS(IN PVOID Address)
Definition: miarm.h:959
FORCEINLINE VOID MI_UPDATE_VALID_PTE(IN PMMPTE PointerPte, IN MMPTE TempPte)
Definition: miarm.h:991
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 2745 of file sysldr.c.

2747{
2749 HANDLE SectionHandle;
2750 PVOID ViewBase = NULL;
2751 SIZE_T ViewSize = 0;
2753 FILE_STANDARD_INFORMATION FileStandardInfo;
2755 PIMAGE_NT_HEADERS NtHeaders;
2757 PAGED_CODE();
2758
2759 /* Setup the object attributes */
2761 NULL,
2763 NULL,
2764 NULL);
2765
2766 /* Create a section for the DLL */
2767 Status = ZwCreateSection(&SectionHandle,
2770 NULL,
2772 SEC_IMAGE,
2773 ImageHandle);
2774 if (!NT_SUCCESS(Status))
2775 {
2776 DPRINT1("ZwCreateSection failed with status 0x%x\n", Status);
2777 return Status;
2778 }
2779
2780 /* Make sure we're in the system process */
2782
2783 /* Map it */
2784 Status = ZwMapViewOfSection(SectionHandle,
2786 &ViewBase,
2787 0,
2788 0,
2789 NULL,
2790 &ViewSize,
2791 ViewShare,
2792 0,
2793 PAGE_EXECUTE);
2794 if (!NT_SUCCESS(Status))
2795 {
2796 /* We failed, close the handle and return */
2797 DPRINT1("ZwMapViewOfSection failed with status 0x%x\n", Status);
2799 ZwClose(SectionHandle);
2800 return Status;
2801 }
2802
2803 /* Now query image information */
2804 Status = ZwQueryInformationFile(ImageHandle,
2806 &FileStandardInfo,
2807 sizeof(FileStandardInfo),
2809 if (NT_SUCCESS(Status))
2810 {
2811 /* First, verify the checksum */
2813 ViewSize,
2814 FileStandardInfo.
2815 EndOfFile.LowPart))
2816 {
2817 /* Set checksum failure */
2819 goto Fail;
2820 }
2821
2822 /* Make sure it's a real image */
2823 NtHeaders = RtlImageNtHeader(ViewBase);
2824 if (!NtHeaders)
2825 {
2826 /* Set checksum failure */
2828 goto Fail;
2829 }
2830
2831 /* Make sure it's for the correct architecture */
2832 if ((NtHeaders->FileHeader.Machine != IMAGE_FILE_MACHINE_NATIVE) ||
2834 {
2835 /* Set protection failure */
2837 goto Fail;
2838 }
2839
2840 /* Check that it's a valid SMP image if we have more then one CPU */
2841 if (!MmVerifyImageIsOkForMpUse(ViewBase))
2842 {
2843 /* Otherwise it's not the right image */
2845 }
2846 }
2847
2848 /* Unmap the section, close the handle, and return status */
2849Fail:
2850 ZwUnmapViewOfSection(NtCurrentProcess(), ViewBase);
2852 ZwClose(SectionHandle);
2853 return Status;
2854}
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:1263
BOOLEAN NTAPI MmVerifyImageIsOkForMpUse(IN PVOID BaseAddress)
Definition: sysldr.c:2721
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:1252
VOID NTAPI MiSessionRemoveProcess(VOID)
Definition: session.c:392
FORCEINLINE VOID MiLockProcessWorkingSetUnsafe(IN PEPROCESS Process, IN PETHREAD Thread)
Definition: miarm.h:1182
@ 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 1270 of file virtual.c.

1277{
1279 PEPROCESS Process = SourceProcess;
1280
1281 //
1282 // Don't accept zero-sized buffers
1283 //
1284 if (!BufferSize) return STATUS_SUCCESS;
1285
1286 //
1287 // If we are copying from ourselves, lock the target instead
1288 //
1289 if (SourceProcess == PsGetCurrentProcess()) Process = TargetProcess;
1290
1291 //
1292 // Acquire rundown protection
1293 //
1294 if (!ExAcquireRundownProtection(&Process->RundownProtect))
1295 {
1296 //
1297 // Fail
1298 //
1300 }
1301
1302 //
1303 // See if we should use the pool copy
1304 //
1306 {
1307 //
1308 // Use MDL-copy
1309 //
1310 Status = MiDoMappedCopy(SourceProcess,
1312 TargetProcess,
1314 BufferSize,
1316 ReturnSize);
1317 }
1318 else
1319 {
1320 //
1321 // Do pool copy
1322 //
1323 Status = MiDoPoolCopy(SourceProcess,
1325 TargetProcess,
1327 BufferSize,
1329 ReturnSize);
1330 }
1331
1332 //
1333 // Release the lock
1334 //
1335 ExReleaseRundownProtection(&Process->RundownProtect);
1336 return Status;
1337}
#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:1019
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:794
#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
@ ProcessAffinityMask
Definition: winternl.h:877
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
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:168
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:4001
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 2208 of file section.c.

2209{
2210 PSECTION PhysSection;
2213 UNICODE_STRING Name = RTL_CONSTANT_STRING(L"\\Device\\PhysicalMemory");
2214 LARGE_INTEGER SectionSize;
2215 HANDLE Handle;
2217
2218 /*
2219 * Create the section mapping physical memory
2220 */
2223 &Name,
2225 NULL,
2226 NULL);
2227 /*
2228 * Create the Object
2229 */
2232 &Obj,
2234 NULL,
2235 sizeof(*PhysSection),
2236 0,
2237 0,
2238 (PVOID*)&PhysSection);
2239 if (!NT_SUCCESS(Status))
2240 {
2241 DPRINT1("MmCreatePhysicalMemorySection: failed to create object (0x%lx)\n", Status);
2242 return Status;
2243 }
2244
2245 /*
2246 * Initialize it
2247 */
2248 RtlZeroMemory(PhysSection, sizeof(*PhysSection));
2249
2250 /* Mark this as a "ROS Section" */
2251 PhysSection->u.Flags.filler = 1;
2253 PhysSection->u.Flags.PhysicalMemory = 1;
2254 PhysSection->SizeOfSection = SectionSize;
2257 if (Segment == NULL)
2258 {
2259 ObDereferenceObject(PhysSection);
2260 return STATUS_NO_MEMORY;
2261 }
2263 PhysSection->Segment = (PSEGMENT)Segment;
2264 Segment->RefCount = 1;
2265
2266 Segment->ReferenceCount = &Segment->RefCount;
2267 Segment->Flags = &Segment->SegFlags;
2268
2270 Segment->Image.FileOffset = 0;
2271 Segment->Protection = PAGE_EXECUTE_READWRITE;
2272 Segment->RawLength = SectionSize;
2273 Segment->Length = SectionSize;
2275 Segment->WriteCopy = FALSE;
2276 Segment->Image.VirtualAddress = 0;
2277 Segment->Image.Characteristics = 0;
2279
2280 Status = ObInsertObject(PhysSection,
2281 NULL,
2283 0,
2284 NULL,
2285 &Handle);
2286 if (!NT_SUCCESS(Status))
2287 {
2288 ObDereferenceObject(PhysSection);
2289 return Status;
2290 }
2292
2293 return STATUS_SUCCESS;
2294}
#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
MMSECTION_FLAGS Flags
Definition: mmtypes.h:817
union _SECTION::@2627 u
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:391
#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:1544
VOID NTAPI MiReleaseProcessReferenceToSessionDataPage(IN PMM_SESSION_SPACE SessionGlobal)
Definition: session.c:209
#define MI_SET_PFN_DELETED(x)
Definition: miarm.h:208
FORCEINLINE VOID MiReleaseExpansionLock(KIRQL OldIrql)
Definition: miarm.h:1557
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 566 of file freelist.c.

567{
568 PMMPFN Pfn1;
569 DPRINT("MmDereferencePage(PhysicalAddress %x)\n", Pfn << PAGE_SHIFT);
570
572
573 Pfn1 = MiGetPfnEntry(Pfn);
574 ASSERT(Pfn1);
575 ASSERT_IS_ROS_PFN(Pfn1);
576
577 ASSERT(Pfn1->u3.e2.ReferenceCount != 0);
578 Pfn1->u3.e2.ReferenceCount--;
579 if (Pfn1->u3.e2.ReferenceCount == 0)
580 {
581 /* Apply LRU hack */
582 if (Pfn1->u4.MustBeCached)
583 {
585 Pfn1->u4.MustBeCached = 0;
586 }
587
588 /* Mark the page temporarily as valid, we're going to make it free soon */
590
591 /* It's not a ROS PFN anymore */
592 Pfn1->u4.AweAllocation = FALSE;
593
594 /* Bring it back into the free list */
595 DPRINT("Legacy free: %lx\n", Pfn);
597 }
598}
#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:1111
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:386

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 4945 of file section.c.

4950{
4951 LARGE_INTEGER FlushStart, FlushEnd;
4953
4954 if (Offset)
4955 {
4956 FlushStart = *Offset;
4957 Status = RtlLongLongAdd(FlushStart.QuadPart, Length, &FlushEnd.QuadPart);
4958 if (!NT_SUCCESS(Status))
4959 return Status;
4960 }
4961
4962 if (Iosb)
4963 Iosb->Information = 0;
4964
4966 if (!Segment)
4967 {
4968 /* Nothing to flush */
4969 goto Quit;
4970 }
4971
4973
4975
4976 if (!Offset)
4977 {
4978 FlushStart.QuadPart = 0;
4979
4980 /* FIXME: All of this is suboptimal */
4981 ULONG ElemCount = RtlNumberGenericTableElements(&Segment->PageTable);
4982 if (!ElemCount)
4983 {
4984 /* No page. Nothing to flush */
4986 MmDereferenceSegment(Segment);
4987 goto Quit;
4988 }
4989
4991 FlushEnd.QuadPart = PageTable->FileOffset.QuadPart + _countof(PageTable->PageEntries) * PAGE_SIZE;
4992 }
4993
4994 FlushStart.QuadPart >>= PAGE_SHIFT;
4995 FlushStart.QuadPart <<= PAGE_SHIFT;
4996
4997 while (FlushStart.QuadPart < FlushEnd.QuadPart)
4998 {
5000
5001 if (IS_DIRTY_SSE(Entry))
5002 {
5003 MmCheckDirtySegment(Segment, &FlushStart, FALSE, FALSE);
5004
5005 if (Iosb)
5006 Iosb->Information += PAGE_SIZE;
5007 }
5008
5009 FlushStart.QuadPart += PAGE_SIZE;
5010 }
5011
5013 MmDereferenceSegment(Segment);
5014
5015Quit:
5016 /* FIXME: Handle failures */
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:70
_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 1673 of file sysldr.c.

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

1691{
1692 POBJECT_NAME_INFORMATION ModuleNameInformation;
1695 PMMVAD Vad;
1697
1698 /* Lock address space */
1701
1702 /* Get the VAD */
1703 Vad = MiLocateAddress(Address);
1704 if (Vad == NULL)
1705 {
1706 /* Fail, the address does not exist */
1707 DPRINT1("No VAD at address %p\n", Address);
1710 }
1711
1712 /* Get the file object pointer for the VAD */
1714 if (FileObject == NULL)
1715 {
1716 DPRINT1("Failed to get file object for Address %p\n", Address);
1719 }
1720
1721 /* Reference the file object */
1723
1724 /* Unlock address space */
1726
1727 /* Get the filename of the file object */
1728 Status = MmGetFileNameForFileObject(FileObject, &ModuleNameInformation);
1729
1730 /* Dereference the file object */
1732
1733 /* Check if we were able to get the file object name */
1734 if (NT_SUCCESS(Status))
1735 {
1736 /* Init modulename */
1737 if (!RtlCreateUnicodeString(ModuleName, ModuleNameInformation->Name.Buffer))
1739
1740 /* Free temp taged buffer from MmGetFileNameForFileObject() */
1741 ExFreePoolWithTag(ModuleNameInformation, TAG_MM);
1742
1743 DPRINT("Found ModuleName %wZ by address %p\n", ModuleName, Address);
1744 }
1745
1746 /* Return status */
1747 return Status;
1748}
static PFILE_OBJECT MiGetFileObjectForVad(_In_ PMMVAD Vad)
Definition: section.c:1560
static NTSTATUS MmGetFileNameForFileObject(IN PFILE_OBJECT FileObject, OUT POBJECT_NAME_INFORMATION *ModuleName)
Definition: section.c:1636
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 1668 of file section.c.

1670{
1672 PSECTION SectionObject = Section;
1673
1674 /* Make sure it's an image section */
1675 if (SectionObject->u.Flags.Image == 0)
1676 {
1677 /* It's not, fail */
1678 DPRINT1("Not an image section\n");
1680 }
1681
1682 /* Get the file object */
1685}
PFILE_OBJECT NTAPI MmGetFileObjectForSection(IN PVOID SectionObject)
Definition: section.c:1541
_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 1541 of file section.c.

1542{
1543 PSECTION Section = SectionObject;
1546
1547 /* Check if it's an ARM3, or ReactOS section */
1549 {
1550 /* Return the file pointer stored in the control area */
1551 return Section->Segment->ControlArea->FilePointer;
1552 }
1553
1554 /* Return the file object */
1555 return ((PMM_SECTION_SEGMENT)Section->Segment)->FileObject;
1556}
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 1615 of file section.c.

1616{
1618
1619 /* Get the section object of this process*/
1620 SectionObject = PsGetCurrentProcess()->SectionObject;
1623
1624 if (SectionObject->u.Flags.Image == 0)
1625 {
1626 RtlZeroMemory(ImageInformation, sizeof(*ImageInformation));
1627 return;
1628 }
1629
1630 /* Return the image information */
1631 *ImageInformation = ((PMM_IMAGE_SECTION_OBJECT)SectionObject->Segment)->ImageInformation;
1632}
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:519
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:566
ULONG NTAPI MmGetReferenceCountPage(PFN_NUMBER Pfn)
Definition: freelist.c:539

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 539 of file freelist.c.

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

Referenced by MmGetLRUNextUserPage(), and MmGetReferenceCountPageWithoutLock().

◆ MmGetRmapListHeadPage()

struct _MM_RMAP_ENTRY *NTAPI MmGetRmapListHeadPage ( PFN_NUMBER  Page)

Definition at line 459 of file freelist.c.

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

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

◆ MmGetSavedSwapEntryPage()

SWAPENTRY NTAPI MmGetSavedSwapEntryPage ( PFN_NUMBER  Page)

Definition at line 500 of file freelist.c.

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

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:491
LIST_ENTRY ProcessList
Definition: miarm.h:492

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 2299 of file section.c.

2300{
2301 OBJECT_TYPE_INITIALIZER ObjectTypeInitializer;
2303
2304 DPRINT("Creating Section Object Type\n");
2305
2306 /* Initialize the section based root */
2309
2310 /* Initialize the Section object type */
2311 RtlZeroMemory(&ObjectTypeInitializer, sizeof(ObjectTypeInitializer));
2312 RtlInitUnicodeString(&Name, L"Section");
2313 ObjectTypeInitializer.Length = sizeof(ObjectTypeInitializer);
2314 ObjectTypeInitializer.DefaultPagedPoolCharge = sizeof(SECTION);
2315 ObjectTypeInitializer.PoolType = PagedPool;
2316 ObjectTypeInitializer.UseDefaultObject = TRUE;
2317 ObjectTypeInitializer.GenericMapping = MmpSectionMapping;
2318 ObjectTypeInitializer.DeleteProcedure = MmpDeleteSection;
2319 ObjectTypeInitializer.CloseProcedure = MmpCloseSection;
2320 ObjectTypeInitializer.ValidAccessMask = SECTION_ALL_ACCESS;
2321 ObjectTypeInitializer.InvalidAttributes = OBJ_OPENLINK;
2322 ObCreateObjectType(&Name, &ObjectTypeInitializer, NULL, &MmSectionObjectType);
2323
2325
2326 return STATUS_SUCCESS;
2327}
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:2143
VOID NTAPI MmpCloseSection(IN PEPROCESS Process OPTIONAL, IN PVOID Object, IN ACCESS_MASK GrantedAccess, IN ULONG ProcessHandleCount, IN ULONG SystemHandleCount)
Definition: section.c:2196
NTSTATUS NTAPI MmCreatePhysicalMemorySection(VOID)
Definition: section.c:2208
union _MMADDRESS_NODE::@2616 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:2481
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:2299
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:1357

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 559 of file freelist.c.

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

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:185

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 2938 of file sysldr.c.

2944{
2945 PVOID ModuleLoadBase = NULL;
2950 PIMAGE_NT_HEADERS NtHeader;
2951 UNICODE_STRING BaseName, BaseDirectory, PrefixName;
2952 PLDR_DATA_TABLE_ENTRY LdrEntry = NULL;
2953 ULONG EntrySize, DriverSize;
2954 PLOAD_IMPORTS LoadedImports = MM_SYSLDR_NO_IMPORTS;
2955 PCHAR MissingApiName, Buffer;
2956 PWCHAR MissingDriverName, PrefixedBuffer = NULL;
2957 HANDLE SectionHandle;
2959 PSECTION Section = NULL;
2960 BOOLEAN LockOwned = FALSE;
2961 PLIST_ENTRY NextEntry;
2962 IMAGE_INFO ImageInfo;
2963
2964 PAGED_CODE();
2965
2966 /* Detect session-load */
2967 if (Flags)
2968 {
2969 /* Sanity checks */
2970 ASSERT(NamePrefix == NULL);
2971 ASSERT(LoadedName == NULL);
2972
2973 /* Make sure the process is in session too */
2974 if (!PsGetCurrentProcess()->ProcessInSession) return STATUS_NO_MEMORY;
2975 }
2976
2977 /* Allocate a buffer we'll use for names */
2980 TAG_LDR_WSTR);
2982
2983 /* Check for a separator */
2984 if (FileName->Buffer[0] == OBJ_NAME_PATH_SEPARATOR)
2985 {
2986 PWCHAR p;
2987 ULONG BaseLength;
2988
2989 /* Loop the path until we get to the base name */
2990 p = &FileName->Buffer[FileName->Length / sizeof(WCHAR)];
2991 while (*(p - 1) != OBJ_NAME_PATH_SEPARATOR) p--;
2992
2993 /* Get the length */
2994 BaseLength = (ULONG)(&FileName->Buffer[FileName->Length / sizeof(WCHAR)] - p);
2995 BaseLength *= sizeof(WCHAR);
2996
2997 /* Setup the string */
2998 BaseName.Length = (USHORT)BaseLength;
2999 BaseName.Buffer = p;
3000 }
3001 else
3002 {
3003 /* Otherwise, we already have a base name */
3004 BaseName.Length = FileName->Length;
3005 BaseName.Buffer = FileName->Buffer;
3006 }
3007
3008 /* Setup the maximum length */
3009 BaseName.MaximumLength = BaseName.Length;
3010
3011 /* Now compute the base directory */
3012 BaseDirectory = *FileName;
3013 BaseDirectory.Length -= BaseName.Length;
3014 BaseDirectory.MaximumLength = BaseDirectory.Length;
3015
3016 /* And the prefix, which for now is just the name itself */
3017 PrefixName = *FileName;
3018
3019 /* Check if we have a prefix */
3020 if (NamePrefix)
3021 {
3022 /* Check if "directory + prefix" is too long for the string */
3023 Status = RtlUShortAdd(BaseDirectory.Length,
3024 NamePrefix->Length,
3025 &PrefixName.MaximumLength);
3026 if (!NT_SUCCESS(Status))
3027 {
3029 goto Quickie;
3030 }
3031
3032 /* Check if "directory + prefix + basename" is too long for the string */
3033 Status = RtlUShortAdd(PrefixName.MaximumLength,
3034 BaseName.Length,
3035 &PrefixName.MaximumLength);
3036 if (!NT_SUCCESS(Status))
3037 {
3039 goto Quickie;
3040 }
3041
3042 /* Allocate the buffer exclusively used for prefixed name */
3043 PrefixedBuffer = ExAllocatePoolWithTag(PagedPool,
3044 PrefixName.MaximumLength,
3045 TAG_LDR_WSTR);
3046 if (!PrefixedBuffer)
3047 {
3049 goto Quickie;
3050 }
3051
3052 /* Clear out the prefixed name string */
3053 PrefixName.Buffer = PrefixedBuffer;
3054 PrefixName.Length = 0;
3055
3056 /* Concatenate the strings */
3057 RtlAppendUnicodeStringToString(&PrefixName, &BaseDirectory);
3058 RtlAppendUnicodeStringToString(&PrefixName, NamePrefix);
3059 RtlAppendUnicodeStringToString(&PrefixName, &BaseName);
3060
3061 /* Now the base name of the image becomes the prefixed version */
3062 BaseName.Buffer = &(PrefixName.Buffer[BaseDirectory.Length / sizeof(WCHAR)]);
3063 BaseName.Length += NamePrefix->Length;
3064 BaseName.MaximumLength = (PrefixName.MaximumLength - BaseDirectory.Length);
3065 }
3066
3067 /* Check if we already have a name, use it instead */
3068 if (LoadedName) BaseName = *LoadedName;
3069
3070 /* Check for loader snap debugging */
3072 {
3073 /* Print out standard string */
3074 DPRINT1("MM:SYSLDR Loading %wZ (%wZ) %s\n",
3075 &PrefixName, &BaseName, Flags ? "in session space" : "");
3076 }
3077
3078 /* Acquire the load lock */
3079LoaderScan:
3080 ASSERT(LockOwned == FALSE);
3081 LockOwned = TRUE;
3085 KernelMode,
3086 FALSE,
3087 NULL);
3088
3089 /* Scan the module list */
3090 NextEntry = PsLoadedModuleList.Flink;
3091 while (NextEntry != &PsLoadedModuleList)
3092 {
3093 /* Get the entry and compare the names */
3094 LdrEntry = CONTAINING_RECORD(NextEntry,
3096 InLoadOrderLinks);
3097 if (RtlEqualUnicodeString(&PrefixName, &LdrEntry->FullDllName, TRUE))
3098 {
3099 /* Found it, break out */
3100 break;
3101 }
3102
3103 /* Keep scanning */
3104 NextEntry = NextEntry->Flink;
3105 }
3106
3107 /* Check if we found the image */
3108 if (NextEntry != &PsLoadedModuleList)
3109 {
3110 /* Check if we had already mapped a section */
3111 if (Section)
3112 {
3113 /* Dereference and clear */
3114 ObDereferenceObject(Section);
3115 Section = NULL;
3116 }
3117
3118 /* Check if this was supposed to be a session load */
3119 if (!Flags)
3120 {
3121 /* It wasn't, so just return the data */
3122 *ModuleObject = LdrEntry;
3123 *ImageBaseAddress = LdrEntry->DllBase;
3125 }
3126 else
3127 {
3128 /* We don't support session loading yet */
3129 UNIMPLEMENTED_DBGBREAK("Unsupported Session-Load!\n");
3131 }
3132
3133 /* Do cleanup */
3134 goto Quickie;
3135 }
3136 else if (!Section)
3137 {
3138 /* It wasn't loaded, and we didn't have a previous attempt */
3141 LockOwned = FALSE;
3142
3143 /* Check if KD is enabled */
3145 {
3146 /* FIXME: Attempt to get image from KD */
3147 }
3148
3149 /* We don't have a valid entry */
3150 LdrEntry = NULL;
3151
3152 /* Setup image attributes */
3154 FileName,
3156 NULL,
3157 NULL);
3158
3159 /* Open the image */
3165 0);
3166 if (!NT_SUCCESS(Status))
3167 {
3168 DPRINT1("ZwOpenFile failed for '%wZ' with status 0x%x\n",
3169 FileName, Status);
3170 goto Quickie;
3171 }
3172
3173 /* Validate it */
3178 {
3179 /* Fail loading */
3180 goto Quickie;
3181 }
3182
3183 /* Check if this is a session-load */
3184 if (Flags)
3185 {
3186 /* Then we only need read and execute */
3188 }
3189 else
3190 {
3191 /* Otherwise, we can allow write access */
3193 }
3194
3195 /* Initialize the attributes for the section */
3197 NULL,
3199 NULL,
3200 NULL);
3201
3202 /* Create the section */
3203 Status = ZwCreateSection(&SectionHandle,
3206 NULL,
3208 SEC_IMAGE,
3209 FileHandle);
3210 if (!NT_SUCCESS(Status))
3211 {
3212 DPRINT1("ZwCreateSection failed with status 0x%x\n", Status);
3213 goto Quickie;
3214 }
3215
3216 /* Now get the section pointer */
3217 Status = ObReferenceObjectByHandle(SectionHandle,
3220 KernelMode,
3221 (PVOID*)&Section,
3222 NULL);
3223 ZwClose(SectionHandle);
3224 if (!NT_SUCCESS(Status)) goto Quickie;
3225
3226 /* Check if this was supposed to be a session-load */
3227 if (Flags)
3228 {
3229 /* We don't support session loading yet */
3230 UNIMPLEMENTED_DBGBREAK("Unsupported Session-Load!\n");
3231 goto Quickie;
3232 }
3233
3234 /* Check the loader list again, we should end up in the path below */
3235 goto LoaderScan;
3236 }
3237 else
3238 {
3239 /* We don't have a valid entry */
3240 LdrEntry = NULL;
3241 }
3242
3243 /* Load the image */
3244 Status = MiLoadImageSection(&Section,
3245 &ModuleLoadBase,
3246 FileName,
3247 FALSE,
3248 NULL);
3250
3251 /* Get the size of the driver */
3252 DriverSize = ((PMM_IMAGE_SECTION_OBJECT)Section->Segment)->ImageInformation.ImageFileSize;
3253
3254 /* Make sure we're not being loaded into session space */
3255 if (!Flags)
3256 {
3257 /* Check for success */
3258 if (NT_SUCCESS(Status))
3259 {
3260 /* Support large pages for drivers */
3261 MiUseLargeDriverPage(DriverSize / PAGE_SIZE,
3262 &ModuleLoadBase,
3263 &BaseName,
3264 TRUE);
3265 }
3266
3267 /* Dereference the section */
3268 ObDereferenceObject(Section);
3269 Section = NULL;
3270 }
3271
3272 /* Check for failure of the load earlier */
3273 if (!NT_SUCCESS(Status))
3274 {
3275 DPRINT1("MiLoadImageSection failed with status 0x%x\n", Status);
3276 goto Quickie;
3277 }
3278
3279 /* Relocate the driver */
3280 Status = LdrRelocateImageWithBias(ModuleLoadBase,
3281 0,
3282 "SYSLDR",
3286 if (!NT_SUCCESS(Status))
3287 {
3288 DPRINT1("LdrRelocateImageWithBias failed with status 0x%x\n", Status);
3289 goto Quickie;
3290 }
3291
3292 /* Get the NT Header */
3293 NtHeader = RtlImageNtHeader(ModuleLoadBase);
3294
3295 /* Calculate the size we'll need for the entry and allocate it */
3297 BaseName.Length +
3298 sizeof(UNICODE_NULL);
3299
3300 /* Allocate the entry */
3302 if (!LdrEntry)
3303 {
3304 /* Fail */
3306 goto Quickie;
3307 }
3308
3309 /* Setup the entry */
3310 LdrEntry->Flags = LDRP_LOAD_IN_PROGRESS;
3311 LdrEntry->LoadCount = 1;
3312 LdrEntry->LoadedImports = LoadedImports;
3313 LdrEntry->PatchInformation = NULL;
3314
3315 /* Check the version */
3316 if ((NtHeader->OptionalHeader.MajorOperatingSystemVersion >= 5) &&
3317 (NtHeader->OptionalHeader.MajorImageVersion >= 5))
3318 {
3319 /* Mark this image as a native image */
3320 LdrEntry->Flags |= LDRP_ENTRY_NATIVE;
3321 }
3322
3323 /* Setup the rest of the entry */
3324 LdrEntry->DllBase = ModuleLoadBase;
3325 LdrEntry->EntryPoint = (PVOID)((ULONG_PTR)ModuleLoadBase +
3327 LdrEntry->SizeOfImage = DriverSize;
3328 LdrEntry->CheckSum = NtHeader->OptionalHeader.CheckSum;
3329 LdrEntry->SectionPointer = Section;
3330
3331 /* Now write the DLL name */
3332 LdrEntry->BaseDllName.Buffer = (PVOID)(LdrEntry + 1);
3333 LdrEntry->BaseDllName.Length = BaseName.Length;
3334 LdrEntry->BaseDllName.MaximumLength = BaseName.Length;
3335
3336 /* Copy and null-terminate it */
3338 BaseName.Buffer,
3339 BaseName.Length);
3340 LdrEntry->BaseDllName.Buffer[BaseName.Length / sizeof(WCHAR)] = UNICODE_NULL;
3341
3342 /* Now allocate the full name */
3344 PrefixName.Length +
3345 sizeof(UNICODE_NULL),
3346 TAG_LDR_WSTR);
3347 if (!LdrEntry->FullDllName.Buffer)
3348 {
3349 /* Don't fail, just set it to zero */
3350 LdrEntry->FullDllName.Length = 0;
3351 LdrEntry->FullDllName.MaximumLength = 0;
3352 }
3353 else
3354 {
3355 /* Set it up */
3356 LdrEntry->FullDllName.Length = PrefixName.Length;
3357 LdrEntry->FullDllName.MaximumLength = PrefixName.Length;
3358
3359 /* Copy and null-terminate */
3361 PrefixName.Buffer,
3362 PrefixName.Length);
3363 LdrEntry->FullDllName.Buffer[PrefixName.Length / sizeof(WCHAR)] = UNICODE_NULL;
3364 }
3365
3366 /* Add the entry */
3367 MiProcessLoaderEntry(LdrEntry, TRUE);
3368
3369 /* Resolve imports */
3370 MissingApiName = Buffer;
3371 MissingDriverName = NULL;
3372 Status = MiResolveImageReferences(ModuleLoadBase,
3373 &BaseDirectory,
3374 NULL,
3375 &MissingApiName,
3376 &MissingDriverName,
3377 &LoadedImports);
3378 if (!NT_SUCCESS(Status))
3379 {
3380 BOOLEAN NeedToFreeString = FALSE;
3381
3382 /* If the lowest bit is set to 1, this is a hint that we need to free */
3383 if (*(ULONG_PTR*)&MissingDriverName & 1)
3384 {
3385 NeedToFreeString = TRUE;
3386 *(ULONG_PTR*)&MissingDriverName &= ~1;
3387 }
3388
3389 DPRINT1("MiResolveImageReferences failed with status 0x%x\n", Status);
3390 DPRINT1(" Missing driver '%ls', missing API '%s'\n",
3391 MissingDriverName, MissingApiName);
3392
3393 if (NeedToFreeString)
3394 {
3395 ExFreePoolWithTag(MissingDriverName, TAG_LDR_WSTR);
3396 }
3397
3398 /* Fail */
3399 MiProcessLoaderEntry(LdrEntry, FALSE);
3400
3401 /* Check if we need to free the name */
3402 if (LdrEntry->FullDllName.Buffer)
3403 {
3404 /* Free it */
3406 }
3407
3408 /* Free the entry itself */
3410 LdrEntry = NULL;
3411 goto Quickie;
3412 }
3413
3414 /* Update the loader entry */
3415 LdrEntry->Flags |= (LDRP_SYSTEM_MAPPED |
3418 LdrEntry->Flags &= ~LDRP_LOAD_IN_PROGRESS;
3419 LdrEntry->LoadedImports = LoadedImports;
3420
3421 /* FIXME: Call driver verifier's loader function */
3422
3423 /* Write-protect the system image */
3425
3426 /* Initialize the security cookie (Win7 is not doing this yet!) */
3427 LdrpInitSecurityCookie(LdrEntry);
3428
3429 /* Check if notifications are enabled */
3431 {
3432 /* Fill out the notification data */
3433 ImageInfo.Properties = 0;
3435 ImageInfo.SystemModeImage = TRUE;
3436 ImageInfo.ImageSize = LdrEntry->SizeOfImage;
3437 ImageInfo.ImageBase = LdrEntry->DllBase;
3438 ImageInfo.ImageSectionNumber = ImageInfo.ImageSelector = 0;
3439
3440 /* Send the notification */
3442 }
3443
3444#ifdef __ROS_ROSSYM__
3445 /* MiCacheImageSymbols doesn't detect rossym */
3446 if (TRUE)
3447#else
3448 /* Check if there's symbols */
3449 if (MiCacheImageSymbols(LdrEntry->DllBase))
3450#endif
3451 {
3452 UNICODE_STRING UnicodeTemp;
3453 STRING AnsiTemp;
3454
3455 /* Check if the system root is present */
3456 if ((PrefixName.Length > (11 * sizeof(WCHAR))) &&
3457 !(_wcsnicmp(PrefixName.Buffer, L"\\SystemRoot", 11)))
3458 {
3459 /* Add the system root */
3460 UnicodeTemp = PrefixName;
3461 UnicodeTemp.Buffer += 11;
3462 UnicodeTemp.Length -= (11 * sizeof(WCHAR));
3465 "%ws%wZ",
3466 &SharedUserData->NtSystemRoot[2],
3467 &UnicodeTemp);
3468 }
3469 else
3470 {
3471 /* Build the name */
3473 "%wZ", &BaseName);
3474 }
3475
3476 /* Setup the ANSI string */
3477 RtlInitString(&AnsiTemp, Buffer);
3478
3479 /* Notify the debugger */
3480 DbgLoadImageSymbols(&AnsiTemp,
3481 LdrEntry->DllBase,
3483 LdrEntry->Flags |= LDRP_DEBUG_SYMBOLS_LOADED;
3484 }
3485
3486 /* Page the driver */
3487 ASSERT(Section == NULL);
3488 MiEnablePagingOfDriver(LdrEntry);
3489
3490 /* Return pointers */
3491 *ModuleObject = LdrEntry;
3492 *ImageBaseAddress = LdrEntry->DllBase;
3493
3494Quickie:
3495 /* Check if we have the lock acquired */
3496 if (LockOwned)
3497 {
3498 /* Release the lock */
3501 LockOwned = FALSE;
3502 }
3503
3504 /* If we have a file handle, close it */
3506
3507 /* If we have allocated a prefixed name buffer, free it */
3508 if (PrefixedBuffer) ExFreePoolWithTag(PrefixedBuffer, TAG_LDR_WSTR);
3509
3510 /* Free the name buffer and return status */
3512 return Status;
3513}
#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:897
_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:81
BOOLEAN KdDebuggerEnabled
Definition: kddata.c:82
#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:214
#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:1034
PVOID NTAPI LdrpInitSecurityCookie(PLDR_DATA_TABLE_ENTRY LdrEntry)
Definition: sysldr.c:2895
VOID NTAPI MiWriteProtectSystemImage(_In_ PVOID ImageBase)
Definition: sysldr.c:2481
VOID NTAPI MiEnablePagingOfDriver(IN PLDR_DATA_TABLE_ENTRY LdrEntry)
Definition: sysldr.c:2657
VOID NTAPI MiProcessLoaderEntry(IN PLDR_DATA_TABLE_ENTRY LdrEntry, IN BOOLEAN Insert)
Definition: sysldr.c:622
PVOID NTAPI MiCacheImageSymbols(IN PVOID BaseAddress)
Definition: sysldr.c:51
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:78
NTSTATUS NTAPI MmCheckSystemImage(IN HANDLE ImageHandle, IN BOOLEAN PurgeSection)
Definition: sysldr.c:2745
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:2385
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
union _MMVAD_LONG::@2621 u
MMVAD_FLAGS VadFlags
Definition: mmtypes.h:763
PCONTROL_AREA ControlArea
Definition: mmtypes.h:765
union _MMVAD_LONG::@2624 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 4925 of file section.c.

4930{
4932
4933 /* There must be a segment for this call */
4934 ASSERT(Segment);
4935
4937
4938 MmDereferenceSegment(Segment);
4939
4940 return Status;
4941}
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 2362 of file sysldr.c.

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

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 4465 of file section.c.

4472{
4473 PSECTION Section = SectionObject;
4477
4479
4480 PAGED_CODE();
4481
4483 {
4485 &MmSession,
4486 MappedBase,
4487 ViewSize,
4489 }
4490
4491 DPRINT("MmMapViewInSystemSpaceEx() called\n");
4492
4493 /* unsupported for now */
4494 ASSERT(Section->u.Flags.Image == 0);
4495
4496 Section = SectionObject;
4498
4499 if (*ViewSize == 0)
4500 {
4501 LONGLONG MapSizeLL;
4502
4503 /* Page-align the mapping */
4504 SectionOffset->LowPart = PAGE_ROUND_DOWN(SectionOffset->LowPart);
4505
4506 if (!NT_SUCCESS(RtlLongLongSub(Section->SizeOfSection.QuadPart, SectionOffset->QuadPart, &MapSizeLL)))
4508
4509 if (!NT_SUCCESS(RtlLongLongToSIZET(MapSizeLL, ViewSize)))
4511 }
4512 else
4513 {
4514 LONGLONG HelperLL;
4515
4516 /* Get the map end */
4517 if (!NT_SUCCESS(RtlLongLongAdd(SectionOffset->QuadPart, *ViewSize, &HelperLL)))
4519
4520 /* Round it up, if needed */
4521 if (HelperLL % PAGE_SIZE)
4522 {
4523 if (!NT_SUCCESS(RtlLongLongAdd(HelperLL, PAGE_SIZE - (HelperLL % PAGE_SIZE), &HelperLL)))
4525 }
4526
4527 /* Now that we have the mapping end, we can align down its start */
4528 SectionOffset->LowPart = PAGE_ROUND_DOWN(SectionOffset->LowPart);
4529
4530 /* Get the new size */
4531 if (!NT_SUCCESS(RtlLongLongSub(HelperLL, SectionOffset->QuadPart, &HelperLL)))
4533
4534 if (!NT_SUCCESS(RtlLongLongToSIZET(HelperLL, ViewSize)))
4536 }
4537
4539
4541
4543
4545 Section->u.Flags.Image,
4546 Segment,
4547 MappedBase,
4548 *ViewSize,
4550 SectionOffset->QuadPart,
4551 SEC_RESERVE);
4552
4555
4556 return Status;
4557}
#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:3367
_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 1537 of file section.c.

1541{
1547 ULONG_PTR Entry1;
1550 BOOLEAN HasSwapEntry;
1551 PVOID PAddress;
1553 SWAPENTRY SwapEntry;
1554
1555 ASSERT(Locked);
1556
1557 /*
1558 * There is a window between taking the page fault and locking the
1559 * address space when another thread could load the page so we check
1560 * that.
1561 */
1563 {
1564 return STATUS_SUCCESS;
1565 }
1566
1568 {
1570 }
1571
1572 /*
1573 * Check for the virtual memory area being deleted.
1574 */
1576 {
1577 return STATUS_UNSUCCESSFUL;
1578 }
1579
1580 PAddress = MM_ROUND_DOWN(Address, PAGE_SIZE);
1581 Offset.QuadPart = (ULONG_PTR)PAddress - MA_GetStartingAddress(MemoryArea)
1582 + MemoryArea->SectionData.ViewOffset;
1583
1584 Segment = MemoryArea->SectionData.Segment;
1586 &MemoryArea->SectionData.RegionListHead,
1587 Address, NULL);
1588 ASSERT(Region != NULL);
1589
1590 /* Check for a NOACCESS mapping */
1591 if (Region->Protect & PAGE_NOACCESS)
1592 {
1594 }
1595
1596 if (Region->Protect & PAGE_GUARD)
1597 {
1598 /* Remove it */
1600 &MemoryArea->SectionData.RegionListHead,
1601 Address, PAGE_SIZE, Region->Type, Region->Protect & ~PAGE_GUARD,
1603
1604 if (!NT_SUCCESS(Status))
1605 {
1606 DPRINT1("Removing PAGE_GUARD protection failed : 0x%08x.\n", Status);
1607 }
1608
1610 }
1611
1612 HasSwapEntry = MmIsPageSwapEntry(Process, Address);
1613
1614 /* See if we should use a private page */
1615 if (HasSwapEntry)
1616 {
1617 SWAPENTRY DummyEntry;
1618
1619 MmGetPageFileMapping(Process, Address, &SwapEntry);
1620 if (SwapEntry == MM_WAIT_ENTRY)
1621 {
1626 }
1627
1629 if (Process) MI_SET_PROCESS2(Process->ImageFileName);
1630 if (!Process) MI_SET_PROCESS2("Kernel Section");
1632 if (!NT_SUCCESS(Status))
1633 {
1634 return STATUS_NO_MEMORY;
1635 }
1636
1637 /*
1638 * Must be private page we have swapped out.
1639 */
1640
1641 /*
1642 * Sanity check
1643 */
1645 ASSERT(DummyEntry == SwapEntry);
1646
1647 /* Tell everyone else we are serving the fault. */
1648 MmCreatePageFileMapping(Process, Address, MM_WAIT_ENTRY);
1649
1651
1652 Status = MmReadFromSwapPage(SwapEntry, Page);
1653 if (!NT_SUCCESS(Status))
1654 {
1655 DPRINT1("MmReadFromSwapPage failed, status = %x\n", Status);
1656 KeBugCheck(MEMORY_MANAGEMENT);
1657 }
1658
1660 MmDeletePageFileMapping(Process, PAddress, &DummyEntry);
1661 ASSERT(DummyEntry == MM_WAIT_ENTRY);
1662
1664 PAddress,
1665 Region->Protect,
1666 Page);
1667 if (!NT_SUCCESS(Status))
1668 {
1669 DPRINT("MmCreateVirtualMapping failed, not out of memory\n");
1670 KeBugCheck(MEMORY_MANAGEMENT);
1671 return Status;
1672 }
1673
1674 /*
1675 * Store the swap entry for later use.
1676 */
1677 MmSetSavedSwapEntryPage(Page, SwapEntry);
1678
1679 /*
1680 * Add the page to the process's working set
1681 */
1683 /*
1684 * Finish the operation
1685 */
1686 DPRINT("Address 0x%p\n", Address);
1687 return STATUS_SUCCESS;
1688 }
1689
1690 /*
1691 * Lock the segment
1692 */
1694
1695 /*
1696 * Satisfying a page fault on a map of /Device/PhysicalMemory is easy
1697 */
1698 if ((*Segment->Flags) & MM_PHYSICALMEMORY_SEGMENT)
1699 {
1701 /*
1702 * Just map the desired physical page
1703 */
1704 Page = (PFN_NUMBER)(Offset.QuadPart >> PAGE_SHIFT);
1706 PAddress,
1707 Region->Protect,
1708 Page);
1709 if (!NT_SUCCESS(Status))
1710 {
1711 DPRINT("MmCreateVirtualMappingUnsafe failed, not out of memory\n");
1712 KeBugCheck(MEMORY_MANAGEMENT);
1713 return Status;
1714 }
1715
1716 /*
1717 * Cleanup and release locks
1718 */
1719 DPRINT("Address 0x%p\n", Address);
1720 return STATUS_SUCCESS;
1721 }
1722
1723 /*
1724 * Check if this page needs to be mapped COW
1725 */
1726 if ((Segment->WriteCopy) &&
1727 (Region->Protect == PAGE_READWRITE || Region->Protect == PAGE_EXECUTE_READWRITE))
1728 {
1730 }
1731 else
1732 {
1733 Attributes = Region->Protect;
1734 }
1735
1736
1737 /*
1738 * Get the entry corresponding to the offset within the section
1739 */
1741 if (Entry == 0)
1742 {
1743 /*
1744 * If the entry is zero, then we need to load the page.
1745 */
1746 if ((Offset.QuadPart >= (LONGLONG)PAGE_ROUND_UP(Segment->RawLength.QuadPart)) && (MemoryArea->VadNode.u.VadFlags.VadType == VadImageMap))
1747 {
1748 /* We are beyond the data which is on file. Just get a new page. */
1750 if (Process) MI_SET_PROCESS2(Process->ImageFileName);
1751 if (!Process) MI_SET_PROCESS2("Kernel Section");
1753 if (!NT_SUCCESS(Status))
1754 {
1756 return STATUS_NO_MEMORY;
1757 }
1760
1762 if (!NT_SUCCESS(Status))
1763 {
1764 DPRINT1("Unable to create virtual mapping\n");
1765 KeBugCheck(MEMORY_MANAGEMENT);
1766 }
1767 ASSERT(MmIsPagePresent(Process, PAddress));
1768 if (Process)
1770
1771 DPRINT("Address 0x%p\n", Address);
1772 return STATUS_SUCCESS;
1773 }
1774
1777
1778 /* The data must be paged in. Lock the file, so that the VDL doesn't get updated behind us. */
1780
1781 PFSRTL_COMMON_FCB_HEADER FcbHeader = Segment->FileObject->FsContext;
1782
1784
1785 FsRtlReleaseFile(Segment->FileObject);
1786
1787 /* Lock address space again */
1789 if (!NT_SUCCESS(Status))
1790 {
1791 if (Status == STATUS_NO_MEMORY)
1792 {
1793 return Status;
1794 }
1795 /* Damn */
1796 DPRINT1("Failed to page data in!\n");
1797 return STATUS_IN_PAGE_ERROR;
1798 }
1799
1800 /* Everything went fine. Restart the operation */
1802 }
1803 else if (IS_SWAP_FROM_SSE(Entry))
1804 {
1805 SWAPENTRY SwapEntry;
1806
1807 SwapEntry = SWAPENTRY_FROM_SSE(Entry);
1808
1809 /* See if a page op is running on this segment. */
1810 if (SwapEntry == MM_WAIT_ENTRY)
1811 {
1817 }
1818
1820 if (!NT_SUCCESS(Status))
1821 {
1823 return STATUS_NO_MEMORY;
1824 }
1825
1826 /*
1827 * Release all our locks and read in the page from disk
1828 */
1831
1833
1834 Status = MmReadFromSwapPage(SwapEntry, Page);
1835 if (!NT_SUCCESS(Status))
1836 {
1837 KeBugCheck(MEMORY_MANAGEMENT);
1838 }
1839
1840 /*
1841 * Relock the address space and segment
1842 */
1845
1846 /*
1847 * Check the entry. No one should change the status of a page
1848 * that has a pending page-in.
1849 */
1851 if (Entry1 != MAKE_SWAP_SSE(MM_WAIT_ENTRY))
1852 {
1853 DPRINT1("Someone changed ppte entry while we slept (%x vs %x)\n", Entry, Entry1);
1854 KeBugCheck(MEMORY_MANAGEMENT);
1855 }
1856
1857 /*
1858 * Save the swap entry.
1859 */
1860 MmSetSavedSwapEntryPage(Page, SwapEntry);
1861
1862 /* Map the page into the process address space */
1864 PAddress,
1865 Attributes,
1866 Page);
1867 if (!NT_SUCCESS(Status))
1868 {
1869 DPRINT1("Unable to create virtual mapping\n");
1870 KeBugCheck(MEMORY_MANAGEMENT);
1871 }
1872 if (Process)
1874
1875 /*
1876 * Mark the offset within the section as having valid, in-memory
1877 * data
1878 */
1879 Entry = MAKE_SSE(Page << PAGE_SHIFT, 1);
1882
1883 DPRINT("Address 0x%p\n", Address);
1884 return STATUS_SUCCESS;
1885 }
1886 else
1887 {
1888 /* We already have a page on this section offset. Map it into the process address space. */
1890
1892 PAddress,
1893 Attributes,
1894 Page);
1895 if (!NT_SUCCESS(Status))
1896 {
1897 DPRINT1("Unable to create virtual mapping\n");
1898 KeBugCheck(MEMORY_MANAGEMENT);
1899 }
1900
1901 if (Process)
1903
1904 /* Take a reference on it */
1907
1908 DPRINT("Address 0x%p\n", Address);
1909 return STATUS_SUCCESS;
1910 }
1911}
#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:484
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:459
#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:500
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 2068 of file section.c.

2074{
2077 ULONG_PTR MaxLength;
2078
2080 if (Length > MaxLength)
2081 Length = (ULONG)MaxLength;
2082
2084 &MemoryArea->SectionData.RegionListHead,
2085 BaseAddress, NULL);
2086 ASSERT(Region != NULL);
2087
2088 if ((MemoryArea->Flags & SEC_NO_CHANGE) &&
2089 Region->Protect != Protect)
2090 {
2092 }
2093
2094 *OldProtect = Region->Protect;
2096 &MemoryArea->SectionData.RegionListHead,
2099
2100 return Status;
2101}
#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 4833 of file section.c.

4837{
4838 LARGE_INTEGER PurgeStart, PurgeEnd;
4840
4841 PurgeStart.QuadPart = Offset ? Offset->QuadPart : 0LL;
4842 if (Length && Offset)
4843 {
4844 if (!NT_SUCCESS(RtlLongLongAdd(PurgeStart.QuadPart, Length, &PurgeEnd.QuadPart)))
4845 return FALSE;
4846 }
4847
4849 if (!Segment)
4850 {
4851 /* Nothing to purge */
4852 return TRUE;
4853 }
4854
4856
4857 if (!Length || !Offset)
4858 {
4859 /* We must calculate the length for ourselves */
4860 /* FIXME: All of this is suboptimal */
4861 ULONG ElemCount = RtlNumberGenericTableElements(&Segment->PageTable);
4862 /* No page. Nothing to purge */
4863 if (!ElemCount)
4864 {
4866 MmDereferenceSegment(Segment);
4867 return TRUE;
4868 }
4869
4871 PurgeEnd.QuadPart = PageTable->FileOffset.QuadPart + _countof(PageTable->PageEntries) * PAGE_SIZE;
4872 }
4873
4874 while (PurgeStart.QuadPart < PurgeEnd.QuadPart)
4875 {
4877
4878 if (Entry == 0)
4879 {
4880 PurgeStart.QuadPart += PAGE_SIZE;
4881 continue;
4882 }
4883
4885 {
4886 ASSERT(SWAPENTRY_FROM_SSE(Entry) == MM_WAIT_ENTRY);
4887 /* The page is currently being read. Meaning someone will need it soon. Bad luck */
4889 MmDereferenceSegment(Segment);
4890 return FALSE;
4891 }
4892
4893 if (IS_WRITE_SSE(Entry))
4894 {
4895 /* We're trying to purge an entry which is being written. Restart this loop iteration */
4899 continue;
4900 }
4901
4902 if (SHARE_COUNT_FROM_SSE(Entry) > 0)
4903 {
4904 /* This page is currently in use. Bad luck */
4906 MmDereferenceSegment(Segment);
4907 return FALSE;
4908 }
4909
4910 /* We can let this page go */
4911 MmSetPageEntrySectionSegment(Segment, &PurgeStart, 0);
4913
4914 PurgeStart.QuadPart += PAGE_SIZE;
4915 }
4916
4917 /* This page is currently in use. Bad luck */
4919 MmDereferenceSegment(Segment);
4920 return TRUE;
4921}
#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 2104 of file section.c.

2108{
2110 PVOID RegionBaseAddress;
2112
2114 &MemoryArea->SectionData.RegionListHead,
2115 Address, &RegionBaseAddress);
2116 if (Region == NULL)
2117 {
2118 return STATUS_UNSUCCESSFUL;
2119 }
2120
2122 {
2123 Segment = MemoryArea->SectionData.Segment;
2124 Info->AllocationBase = (PUCHAR)MA_GetStartingAddress(MemoryArea) - Segment->Image.VirtualAddress;
2125 Info->Type = MEM_IMAGE;
2126 }
2127 else
2128 {
2129 Info->AllocationBase = (PVOID)MA_GetStartingAddress(MemoryArea);
2130 Info->Type = MEM_MAPPED;
2131 }
2132 Info->BaseAddress = RegionBaseAddress;
2134 Info->RegionSize = Region->Length;
2135 Info->State = MEM_COMMIT;
2136 Info->Protect = Region->Protect;
2137
2139 return STATUS_SUCCESS;
2140}
#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:1326
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 519 of file freelist.c.

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

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:602
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:2481
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:125
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 484 of file freelist.c.

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

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 945 of file sysldr.c.

946{
947 PLDR_DATA_TABLE_ENTRY LdrEntry = ImageHandle;
948 PVOID BaseAddress = LdrEntry->DllBase;
950 STRING TempName;
951 BOOLEAN HadEntry = FALSE;
952
953 /* Acquire the loader lock */
958 FALSE,
959 NULL);
960
961 /* Check if this driver was loaded at boot and didn't get imports parsed */
962 if (LdrEntry->LoadedImports == MM_SYSLDR_BOOT_LOADED) goto Done;
963
964 /* We should still be alive */
965 ASSERT(LdrEntry->LoadCount != 0);
966 LdrEntry->LoadCount--;
967
968 /* Check if we're still loaded */
969 if (LdrEntry->LoadCount) goto Done;
970
971 /* We should cleanup... are symbols loaded */
972 if (LdrEntry->Flags & LDRP_DEBUG_SYMBOLS_LOADED)
973 {
974 /* Create the ANSI name */
976 &LdrEntry->BaseDllName,
977 TRUE);
978 if (NT_SUCCESS(Status))
979 {
980 /* Unload the symbols */
981 DbgUnLoadImageSymbols(&TempName,
984 RtlFreeAnsiString(&TempName);
985 }
986 }
987
988 /* FIXME: Free the driver */
989 DPRINT1("Leaking driver: %wZ\n", &LdrEntry->BaseDllName);
990 //MmFreeSection(LdrEntry->DllBase);
991
992 /* Check if we're linked in */
993 if (LdrEntry->InLoadOrderLinks.Flink)
994 {
995 /* Remove us */
996 MiProcessLoaderEntry(LdrEntry, FALSE);
997 HadEntry = TRUE;
998 }
999
1000 /* Dereference and clear the imports */
1002 MiClearImports(LdrEntry);
1003
1004 /* Check if the entry needs to go away */
1005 if (HadEntry)
1006 {
1007 /* Check if it had a name */
1008 if (LdrEntry->FullDllName.Buffer)
1009 {
1010 /* Free it */
1012 }
1013
1014 /* Check if we had a section */
1015 if (LdrEntry->SectionPointer)
1016 {
1017 /* Dereference it */
1019 }
1020
1021 /* Free the entry */
1023 }
1024
1025 /* Release the system lock and return */
1026Done:
1029 return STATUS_SUCCESS;
1030}
#define MM_SYSLDR_BOOT_LOADED
Definition: miarm.h:215
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:527
VOID NTAPI MiClearImports(IN PLDR_DATA_TABLE_ENTRY LdrEntry)
Definition: sysldr.c:602

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:245
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:1465
VOID NTAPI MiFindInitializationCode(OUT PVOID *StartVa, OUT PVOID *EndVa)
Definition: sysldr.c:1488
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 401 of file sysldr.c.

404{
406 BOOLEAN IsForwarder = FALSE;
408
409 PAGED_CODE();
410
411 /* Call the internal API */
413 ExportName,
414 &Function,
415 &IsForwarder,
417 if (!NT_SUCCESS(Status))
418 return NULL;
419
420 /* If the export is actually a forwarder, log the error and fail */
421 if (IsForwarder)
422 {
423 DPRINT1("RtlFindExportedRoutineByName does not support forwarders!\n", FALSE);
424 return NULL;
425 }
426
427 /* We've found the export */
428 return Function;
429}
_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:309

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 309 of file sysldr.c.

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

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