ReactOS 0.4.16-dev-976-g18fc5a1
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_ROUND_UP_64(x)    (((x) + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1))
 
#define PAGE_ROUND_DOWN_64(x)    ((x) & ~(PAGE_SIZE - 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 MmIsDataSectionResident (_In_ PSECTION_OBJECT_POINTERS SectionObjectPointer, _In_ LONGLONG Offset, _In_ ULONG Length)
 
NTSTATUS NTAPI MmMakeSegmentDirty (_In_ PSECTION_OBJECT_POINTERS SectionObjectPointer, _In_ LONGLONG Offset, _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)
 
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 1395 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 1383 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 1396 of file mm.h.

◆ DIRTY_SSE

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

Definition at line 1382 of file mm.h.

◆ EndOfAllocation

#define EndOfAllocation   WriteInProgress

Definition at line 363 of file mm.h.

◆ InterlockedCompareExchangePte

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

Definition at line 194 of file mm.h.

◆ InterlockedExchangePte

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

Definition at line 197 of file mm.h.

◆ IS_DIRTY_SSE

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

Definition at line 1384 of file mm.h.

◆ IS_SWAP_FROM_SSE

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

Definition at line 1376 of file mm.h.

◆ IS_WRITE_SSE

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

Definition at line 1386 of file mm.h.

◆ MA_GetEndingAddress

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

Definition at line 252 of file mm.h.

◆ MA_GetStartingAddress

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

Definition at line 251 of file mm.h.

◆ MAKE_PFN_SSE

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

Definition at line 1379 of file mm.h.

◆ MAKE_SSE

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

Definition at line 1394 of file mm.h.

◆ MAKE_SWAP_SSE

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

Definition at line 1381 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 1393 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 1050 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 325 of file mm.h.

◆ MI_SET_PROCESS2

#define MI_SET_PROCESS2 (   x)

Definition at line 326 of file mm.h.

◆ MI_SET_USAGE

#define MI_SET_USAGE (   x)

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

◆ MM_FREE_POOL_SIGNATURE

#define MM_FREE_POOL_SIGNATURE   'ARM3'

Definition at line 488 of file mm.h.

◆ MM_IMAGE_SECTION_FLUSH_DELETE

#define MM_IMAGE_SECTION_FLUSH_DELETE   (0x10)

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

◆ MM_SEGMENT_INDELETE

#define MM_SEGMENT_INDELETE   (0x4)

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

◆ MmLockSectionSegment

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

Definition at line 1404 of file mm.h.

◆ MmSetCleanPage

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

Definition at line 1258 of file mm.h.

◆ MmSetDirtyPage

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

Definition at line 1259 of file mm.h.

◆ MmSetPageEntrySectionSegment

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

Definition at line 1607 of file mm.h.

◆ MmUnlockSectionSegment

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

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

◆ PAGE_FROM_SSE

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

Definition at line 1390 of file mm.h.

◆ PAGE_IS_EXECUTABLE

#define PAGE_IS_EXECUTABLE
Value:

Definition at line 166 of file mm.h.

◆ PAGE_IS_READABLE

#define PAGE_IS_READABLE

◆ PAGE_IS_WRITABLE

#define PAGE_IS_WRITABLE
Value:

Definition at line 160 of file mm.h.

◆ PAGE_IS_WRITECOPY

#define PAGE_IS_WRITECOPY
Value:

Definition at line 172 of file mm.h.

◆ PAGE_ROUND_DOWN_64

#define PAGE_ROUND_DOWN_64 (   x)     ((x) & ~(PAGE_SIZE - 1))

Definition at line 138 of file mm.h.

◆ PAGE_ROUND_UP_64

#define PAGE_ROUND_UP_64 (   x)     (((x) + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1))

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

◆ RMAP_SEGMENT_MASK

#define RMAP_SEGMENT_MASK   ~((ULONG_PTR)0xff)

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

◆ StartOfAllocation

#define StartOfAllocation   ReadInProgress

Definition at line 362 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 1380 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 1385 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 522 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 533 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 329 of file mm.h.

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

Function Documentation

◆ _IRQL_raises_()

_IRQL_raises_ ( DISPATCH_LEVEL  )

Definition at line 999 of file mm.h.

1007{
1009}
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:181
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:82
#define _SEH2_GetExceptionInformation()
Definition: pseh2_64.h:180
#define _SEH2_END
Definition: pseh2_64.h:171
#define _SEH2_TRY
Definition: pseh2_64.h:71
#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 1575 of file mm.h.

1580{
1581 MmDereferenceSegmentWithLock(Segment, MM_NOIRQL);
1582}
#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 1022 of file mm.h.

1028{
1029 PKSPIN_LOCK_QUEUE LockQueue;
1030
1032 LockQueue = &KeGetCurrentPrcb()->LockQueue[LockQueuePfnLock];
1033 KeAcquireQueuedSpinLockAtDpcLevel(LockQueue);
1034}
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696
#define ASSERT(a)
Definition: mode.c:44
FORCEINLINE struct _KPRCB * KeGetCurrentPrcb(VOID)
Definition: ketypes.h:1182

◆ _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:1609
#define IS_DIRTY_SSE(E)
Definition: mm.h:1384
#define PFN_FROM_SSE(E)
Definition: mm.h:1375
#define IS_SWAP_FROM_SSE(E)
Definition: mm.h:1376
#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 1011 of file mm.h.

1018{
1020}
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  )

Definition at line 57 of file firmware.c.

207{
210
211 /* Check input parameters */
212 if (FirmwareType == NULL)
213 {
215 return FALSE;
216 }
217
218 /* Query firmware type */
220 &BootInfo,
221 sizeof(BootInfo),
222 0);
223 if (!NT_SUCCESS(Status))
224 {
226 return FALSE;
227 }
228
229 *FirmwareType = BootInfo.FirmwareType;
230 return TRUE;
231}
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
#define SetLastError(x)
Definition: compat.h:752
@ SystemBootEnvironmentInformation
Definition: extypes.h:307
DWORD BaseSetLastNTError(IN NTSTATUS Status)
Definition: reactos.cpp:167
NTSYSAPI NTSTATUS NTAPI NtQuerySystemInformation(IN SYSTEM_INFORMATION_CLASS SystemInfoClass, OUT PVOID SystemInfoBuffer, IN ULONG SystemInfoBufferSize, OUT PULONG BytesReturned OPTIONAL)

◆ _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}
ULONG_PTR PFN_NUMBER
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:1054
#define MI_SET_PROCESS2(x)
Definition: mm.h:326
#define MI_SET_USAGE(x)
Definition: mm.h:324
PFN_NUMBER MmAvailablePages
Definition: freelist.c:26
#define MM_FREE_POOL_SIGNATURE
Definition: mm.h:488
VOID NTAPI KeFlushEntireTb(IN BOOLEAN Invalid, IN BOOLEAN AllProcessors)
Definition: cpu.c:654
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 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:480
ULONG Signature
Definition: mm.h:483
PFN_COUNT Size
Definition: mm.h:482
LIST_ENTRY List
Definition: mm.h:481
USHORT PageLocation
Definition: mm.h:372
Definition: mm.h:381
union _MMPFN::@1838 u4
PMMPTE PteAddress
Definition: mm.h:393
union _MMPFN::@1835 u3
MMPFNENTRY e1
Definition: mm.h:404
struct _MMPFN::@1835::@1841 e2
ULONG_PTR VerifierAllocation
Definition: mm.h:427
ULONG_PTR ShareCount
Definition: mm.h:397
union _MMPFN::@1834 u2
ULONG64 Valid
Definition: mmtypes.h:150
ULONG64 PageFrameNumber
Definition: mmtypes.h:171
union _MMPTE::@2414 u
MMPTE_HARDWARE Hard
Definition: mmtypes.h:217
PMMPTE LastPteForPagedPool
Definition: mm.h:496
PRTL_BITMAP EndOfPagedPoolBitmap
Definition: mm.h:494
PRTL_BITMAP PagedPoolAllocationMap
Definition: mm.h:493
PMMPDE NextPdeForPagedPoolExpansion
Definition: mm.h:497
PMMPTE FirstPteForPagedPool
Definition: mm.h:495
ULONG PagedPoolHint
Definition: mm.h:498
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:1982
@ 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:1074
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:484
#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 1054 of file mm.h.

1055{
1056 PMMPFN Page;
1057 extern RTL_BITMAP MiPfnBitMap;
1058
1059 /* Make sure the PFN number is valid */
1060 if (Pfn > MmHighestPhysicalPage) return NULL;
1061
1062 /* Make sure this page actually has a PFN entry */
1063 if ((MiPfnBitMap.Buffer) && !(RtlTestBit(&MiPfnBitMap, (ULONG)Pfn))) return NULL;
1064
1065 /* Get the entry */
1066 Page = &MmPfnDatabase[Pfn];
1067
1068 /* Return it */
1069 return Page;
1070};
PMMPFN MmPfnDatabase
Definition: freelist.c:24
_In_ PVOID _Out_opt_ BOOLEAN _Out_opt_ PPFN_NUMBER Page
Definition: mm.h:1313
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 426 of file balance.c.

427{
431
435
436 Timeout.QuadPart = -20000000; /* 2 sec */
438 Timeout,
439 2000, /* 2 sec */
440 NULL);
441
444 NULL,
445 NULL,
448 NULL);
449 if (!NT_SUCCESS(Status))
450 {
451 KeBugCheck(MEMORY_MANAGEMENT);
452 }
453
457 &Priority,
458 sizeof(Priority));
459
460}
DECLSPEC_NORETURN VOID NTAPI KeBugCheck(ULONG BugCheckCode)
Definition: bug.c:1434
@ 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:354
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:2067
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:142
PVOID DllBase
Definition: btrfs_drv.h:1880
UNICODE_STRING BaseDllName
Definition: ldrtypes.h:149
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:100
#define TAG_LDR_WSTR
Definition: tag.h:101
_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:4403
#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:38
@ 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:513
#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:58
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:147
ULONG Flags
Definition: ntddk_ex.h:207
USHORT Modified
Definition: mm.h:367
USHORT Rom
Definition: mm.h:375
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:251
#define MEMORY_AREA_SECTION_VIEW
Definition: mm.h:93
ULONG Type
Definition: mm.h:258

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:1731
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:1738
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:1404
#define MC_USER
Definition: mm.h:114
#define MmUnlockSectionSegment(x)
Definition: mm.h:1412
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:160
FORCEINLINE PEPROCESS MmGetAddressSpaceOwner(IN PMMSUPPORT AddressSpace)
Definition: mm.h:1723
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:166
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:172
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:5139
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:5148
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:5303
PLARGE_INTEGER Offset
Definition: section.c:5134
struct _MEMORY_AREA::@1832 SectionData
Definition: mm.h:470
_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:418
ULONG_PTR MustBeCached
Definition: mm.h:430
struct _MMPFN * NextLRU
Definition: mm.h:442
union _MMPFN::@1833 u1
struct _MMPFN * PreviousLRU
Definition: mm.h:443
SWAPENTRY SwapEntry
Definition: mm.h:391
ULONG_PTR AweAllocation
Definition: mm.h:428

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:878
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:474
ULONG Type
Definition: mm.h:471
SIZE_T Length
Definition: mm.h:473
ULONG Protect
Definition: mm.h:472
#define TAG_MM_REGION
Definition: tag.h:110

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

◆ 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:528
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)

Definition at line 2754 of file sysldr.c.

2756{
2758 HANDLE SectionHandle;
2759 PVOID ViewBase = NULL;
2760 SIZE_T ViewSize = 0;
2762 FILE_STANDARD_INFORMATION FileStandardInfo;
2764 PIMAGE_NT_HEADERS NtHeaders;
2766 PAGED_CODE();
2767
2768 /* Setup the object attributes */
2770 NULL,
2772 NULL,
2773 NULL);
2774
2775 /* Create a section for the DLL */
2776 Status = ZwCreateSection(&SectionHandle,
2779 NULL,
2781 SEC_IMAGE,
2782 ImageHandle);
2783 if (!NT_SUCCESS(Status))
2784 {
2785 DPRINT1("ZwCreateSection failed with status 0x%x\n", Status);
2786 return Status;
2787 }
2788
2789 /* Make sure we're in the system process */
2791
2792 /* Map it */
2793 Status = ZwMapViewOfSection(SectionHandle,
2795 &ViewBase,
2796 0,
2797 0,
2798 NULL,
2799 &ViewSize,
2800 ViewShare,
2801 0,
2802 PAGE_EXECUTE);
2803 if (!NT_SUCCESS(Status))
2804 {
2805 /* We failed, close the handle and return */
2806 DPRINT1("ZwMapViewOfSection failed with status 0x%x\n", Status);
2808 ZwClose(SectionHandle);
2809 return Status;
2810 }
2811
2812 /* Now query image information */
2813 Status = ZwQueryInformationFile(ImageHandle,
2815 &FileStandardInfo,
2816 sizeof(FileStandardInfo),
2818 if (NT_SUCCESS(Status))
2819 {
2820 /* First, verify the checksum */
2822 ViewSize,
2823 FileStandardInfo.
2824 EndOfFile.LowPart))
2825 {
2826 /* Set checksum failure */
2828 goto Fail;
2829 }
2830
2831 /* Make sure it's a real image */
2832 NtHeaders = RtlImageNtHeader(ViewBase);
2833 if (!NtHeaders)
2834 {
2835 /* Set checksum failure */
2837 goto Fail;
2838 }
2839
2840 /* Make sure it's for the correct architecture */
2841 if ((NtHeaders->FileHeader.Machine != IMAGE_FILE_MACHINE_NATIVE) ||
2843 {
2844 /* Set protection failure */
2846 goto Fail;
2847 }
2848
2849#ifdef CONFIG_SMP
2850 /* Check that the image is safe to use if we have more than one CPU */
2851 if (!MiVerifyImageIsOkForMpUse(NtHeaders))
2852 {
2853 /* Otherwise it's not the right image */
2855 }
2856#endif // CONFIG_SMP
2857 }
2858
2859 /* Unmap the section, close the handle, and return status */
2860Fail:
2861 ZwUnmapViewOfSection(NtCurrentProcess(), ViewBase);
2863 ZwClose(SectionHandle);
2864 return Status;
2865}
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:1777
#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
PEPROCESS PsInitialSystemProcess
Definition: psmgr.c:50
#define FileStandardInformation
Definition: propsheet.cpp:61
KPROCESS Pcb
Definition: pstypes.h:1263
KAPC_STATE
Definition: ketypes.h:1409

Referenced by MmLoadSystemImage(), and PsLocateSystemDll().

◆ MmCleanProcessAddressSpace()

VOID NTAPI MmCleanProcessAddressSpace ( IN PEPROCESS  Process)

Definition at line 1263 of file procsup.c.

1264{
1265 PMMVAD Vad;
1266 PMM_AVL_TABLE VadTree;
1268
1269 /* Remove from the session */
1271
1272 /* Abort early, when the address space wasn't fully initialized */
1273 if (Process->AddressSpaceInitialized < 2)
1274 {
1275 DPRINT1("Incomplete address space for Process %p. Might leak resources.\n",
1276 Process);
1277 return;
1278 }
1279
1280 /* Lock the process address space from changes */
1283
1284 /* VM is deleted now */
1285 Process->VmDeleted = TRUE;
1287
1288 /* Enumerate the VADs */
1289 VadTree = &Process->VadRoot;
1290 while (VadTree->NumberGenericTableElements)
1291 {
1292 /* Grab the current VAD */
1293 Vad = (PMMVAD)VadTree->BalancedRoot.RightChild;
1294
1295 /* Check for old-style memory areas */
1296 if (Vad->u.VadFlags.Spare == 1)
1297 {
1298 /* Let RosMm handle this */
1300 continue;
1301 }
1302
1303 /* Lock the working set */
1305
1306 /* Remove this VAD from the tree */
1307 ASSERT(VadTree->NumberGenericTableElements >= 1);
1308 MiRemoveNode((PMMADDRESS_NODE)Vad, VadTree);
1309
1310 /* Only regular VADs supported for now */
1311 ASSERT(Vad->u.VadFlags.VadType == VadNone);
1312
1313 /* Check if this is a section VAD */
1314 if (!(Vad->u.VadFlags.PrivateMemory) && (Vad->ControlArea))
1315 {
1316 /* Remove the view */
1318 }
1319 else
1320 {
1321 /* Delete the addresses */
1323 (Vad->EndingVpn << PAGE_SHIFT) | (PAGE_SIZE - 1),
1324 Vad);
1325
1326 /* Release the working set */
1328 }
1329
1330 /* Skip ARM3 fake VADs, they'll be freed by MmDeleteProcessAddresSpace */
1331 if (Vad->u.VadFlags.Spare == 1)
1332 {
1333 /* Set a flag so MmDeleteMemoryArea knows to free, but not to remove */
1334 Vad->u.VadFlags.Spare = 2;
1335 continue;
1336 }
1337
1338 /* Free the VAD memory */
1339 ExFreePool(Vad);
1340
1341 /* Return the quota the VAD used */
1343 }
1344
1345 /* Lock the working set */
1347 ASSERT(Process->CloneRoot == NULL);
1348 ASSERT(Process->PhysicalVadRoot == NULL);
1349
1350 /* Delete the shared user data section */
1352
1353 /* Release the working set */
1355
1356 /* Release the address space */
1358}
#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
FORCEINLINE VOID MmLockAddressSpace(PMMSUPPORT AddressSpace)
Definition: mm.h:1703
VOID NTAPI MiRosCleanupMemoryArea(PEPROCESS Process, PMMVAD Vad)
Definition: marea.c:521
FORCEINLINE VOID MmUnlockAddressSpace(PMMSUPPORT AddressSpace)
Definition: mm.h:1716
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 VadType
Definition: mmtypes.h:694
ULONG_PTR PrivateMemory
Definition: mmtypes.h:698
ULONG_PTR EndingVpn
Definition: mmtypes.h:730
PCONTROL_AREA ControlArea
Definition: mmtypes.h:736
union _MMVAD::@2703 u
ULONG_PTR StartingVpn
Definition: mmtypes.h:729
MMVAD_FLAGS VadFlags
Definition: mmtypes.h:734
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}
_In_ PVOID _In_ ULONG _Out_ PVOID _In_ ULONG _Inout_ PULONG _In_ KPROCESSOR_MODE PreviousMode
#define ExReleaseRundownProtection
Definition: ex.h:139
#define ExAcquireRundownProtection
Definition: ex.h:138
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

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:259
ULONG Magic
Definition: mm.h:261
BOOLEAN DeleteInProgress
Definition: mm.h:260
MMVAD VadNode
Definition: mm.h:256
#define TAG_MAREA
Definition: tag.h:106
#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 518 of file procsup.c.

521{
522 PPEB Peb = NULL;
524 SIZE_T ViewSize = 0;
525 PVOID TableBase = NULL;
526 PIMAGE_NT_HEADERS NtHeaders;
527 PIMAGE_LOAD_CONFIG_DIRECTORY ImageConfigData;
529 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 //
610 Peb->BeingDebugged = (BOOLEAN)(Process->DebugPort != NULL);
618 Peb->MaximumNumberOfHeaps = (PAGE_SIZE - sizeof(PEB)) / sizeof(PVOID);
619 Peb->ProcessHeaps = (PVOID*)(Peb + 1);
620
621 //
622 // Session ID
623 //
624 if (Process->Session) Peb->SessionId = MmGetSessionId(Process);
625 }
627 {
628 //
629 // Fail
630 //
633 }
634 _SEH2_END;
635
636 //
637 // Use SEH in case we can't load the image
638 //
640 {
641 //
642 // Get NT Headers
643 //
645 Characteristics = NtHeaders->FileHeader.Characteristics;
646 }
648 {
649 //
650 // Fail
651 //
654 }
655 _SEH2_END;
656
657 //
658 // Parse the headers
659 //
660 if (NtHeaders)
661 {
662 //
663 // Use SEH in case we can't load the headers
664 //
666 {
667 //
668 // Get the Image Config Data too
669 //
671 TRUE,
673 (PULONG)&ViewSize);
674 if (ImageConfigData)
675 {
676 //
677 // Probe it
678 //
679 ProbeForRead(ImageConfigData,
681 sizeof(ULONG));
682 }
683
684 //
685 // Write subsystem data
686 //
690
691 //
692 // Check for version data
693 //
694 if (NtHeaders->OptionalHeader.Win32VersionValue)
695 {
696 //
697 // Extract values and write them
698 //
700 Peb->OSMinorVersion = (NtHeaders->OptionalHeader.Win32VersionValue >> 8) & 0xFF;
701 Peb->OSBuildNumber = (NtHeaders->OptionalHeader.Win32VersionValue >> 16) & 0x3FFF;
702 Peb->OSPlatformId = (NtHeaders->OptionalHeader.Win32VersionValue >> 30) ^ 2;
703
704 /* Process CSD version override */
705 if ((ImageConfigData) && (ImageConfigData->CSDVersion))
706 {
707 /* Take the value from the image configuration directory */
708 Peb->OSCSDVersion = ImageConfigData->CSDVersion;
709 }
710 }
711
712 /* Process optional process affinity mask override */
713 if ((ImageConfigData) && (ImageConfigData->ProcessAffinityMask))
714 {
715 /* Take the value from the image configuration directory */
717 }
718
719 //
720 // Check if this is a UP image
721 if (Characteristics & IMAGE_FILE_UP_SYSTEM_ONLY)
722 {
723 //
724 // Set single processor rotating affinity.
725 // See https://www.microsoftpressstore.com/articles/article.aspx?p=2233328&seqNum=3
726 //
730 }
731 }
733 {
734 //
735 // Fail
736 //
739 }
740 _SEH2_END;
741 }
742
743 //
744 // Detach from the Process
745 //
747 *BasePeb = Peb;
748 return STATUS_SUCCESS;
749}
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
#define RtlImageDirectoryEntryToData
Definition: compat.h:809
#define IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG
Definition: compat.h:153
PPEB Peb
Definition: dllmain.c:27
VOID NTAPI ProbeForRead(IN CONST VOID *Address, IN SIZE_T Length, IN ULONG Alignment)
Definition: exintrin.c:102
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:90
SIZE_T MmMinimumStackCommitInBytes
Definition: mminit.c:370
LARGE_INTEGER MmCriticalSectionTimeout
Definition: mminit.c:388
#define PCHAR
Definition: match.c:90
FORCEINLINE KAFFINITY AFFINITY_MASK(ULONG Index)
Definition: kefuncs.h:39
_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
KAFFINITY KeActiveProcessors
Definition: processor.c:16
ULONG NTAPI MmGetSessionId(IN PEPROCESS Process)
Definition: session.c:179
CCHAR KeNumberProcessors
Definition: processor.c:19
ULONG MmRotatingUniprocessorNumber
Definition: procsup.c:23
NTSTATUS NTAPI MiCreatePebOrTeb(IN PEPROCESS Process, IN ULONG Size, OUT PULONG_PTR BaseAddress)
Definition: procsup.c:29
#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:184
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}
LPWSTR Name
Definition: desk.c:124
#define ExGetPreviousMode
Definition: ex.h:143
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:244
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
PSEGMENT Segment
Definition: mmtypes.h:812
ULONG InitialPageProtection
Definition: mmtypes.h:819
union _SECTION::@2712 u
LARGE_INTEGER SizeOfSection
Definition: mmtypes.h:813
#define TAG_MM_SECTION_SEGMENT
Definition: tag.h:113
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 753 of file procsup.c.

757{
758 PTEB Teb;
760 *BaseTeb = NULL;
761
762 //
763 // Attach to Target
764 //
766
767 //
768 // Allocate the TEB
769 //
770 Status = MiCreatePebOrTeb(Process, sizeof(TEB), (PULONG_PTR)&Teb);
771 if (!NT_SUCCESS(Status))
772 {
773 /* Cleanup and exit */
775 return Status;
776 }
777
778 //
779 // Use SEH in case we can't load the TEB
780 //
782 {
783 //
784 // Initialize the PEB
785 //
786 RtlZeroMemory(Teb, sizeof(TEB));
787
788 //
789 // Set TIB Data
790 //
791#ifdef _M_AMD64
792 Teb->NtTib.ExceptionList = NULL;
793#else
795#endif
796 Teb->NtTib.Self = (PNT_TIB)Teb;
797
798 //
799 // Identify this as an OS/2 V3.0 ("Cruiser") TIB
800 //
801 Teb->NtTib.Version = 30 << 8;
802
803 //
804 // Set TEB Data
805 //
806 Teb->ClientId = *ClientId;
807 Teb->RealClientId = *ClientId;
810
811 //
812 // Check if we have a grandparent TEB
813 //
814 if ((InitialTeb->PreviousStackBase == NULL) &&
815 (InitialTeb->PreviousStackLimit == NULL))
816 {
817 //
818 // Use initial TEB values
819 //
820 Teb->NtTib.StackBase = InitialTeb->StackBase;
821 Teb->NtTib.StackLimit = InitialTeb->StackLimit;
822 Teb->DeallocationStack = InitialTeb->AllocatedStackBase;
823 }
824 else
825 {
826 //
827 // Use grandparent TEB values
828 //
829 Teb->NtTib.StackBase = InitialTeb->PreviousStackBase;
830 Teb->NtTib.StackLimit = InitialTeb->PreviousStackLimit;
831 }
832
833 //
834 // Initialize the static unicode string
835 //
838 }
840 {
841 //
842 // Get error code
843 //
845 }
846 _SEH2_END;
847
848 //
849 // Return
850 //
852 *BaseTeb = Teb;
853 return Status;
854}
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 */
135 if (!(Flags & MMDBG_COPY_UNSAFE))
136 {
137 static BOOLEAN Warned = FALSE;
138 if (!Warned)
139 {
140 KdpDprintf("MmDbgCopyMemory: not providing MMDBG_COPY_UNSAFE is UNIMPLEMENTED\n");
141 Warned = TRUE;
142 }
143 }
144
145 /* We only handle 1, 2, 4 and 8 byte requests */
146 if ((Size != 1) &&
147 (Size != 2) &&
148 (Size != 4) &&
149 (Size != 8))
150 {
151 /* Invalid size, fail */
152 KdpDprintf("MmDbgCopyMemory: Received Illegal Size 0x%lx\n",
153 Size);
155 }
156
157 /* The copy must be aligned */
158 if ((Address & (Size - 1)) != 0)
159 {
160 /* Not allowing unaligned access */
161 KdpDprintf("MmDbgCopyMemory: Received Unaligned Address 0x%I64x Size %lx\n",
162 Address,
163 Size);
165 }
166
167 /* Check for physical or virtual copy */
169 {
170 /* Physical: translate and map it to our mapping space */
172 Flags);
173
174 /* Check if translation failed */
175 if (!TargetAddress)
176 {
177 /* Fail */
178 KdpDprintf("MmDbgCopyMemory: Failed to Translate Physical Address %I64x\n",
179 Address);
180 return STATUS_UNSUCCESSFUL;
181 }
182
183 /* The address we received must be valid! */
185 }
186 else
187 {
188 /* Virtual; truncate it to avoid casts later down */
190
191 /* Make sure address is valid */
193 {
194 /* Fail */
195 KdpDprintf("MmDbgCopyMemory: Failing %s for invalid Virtual Address 0x%p\n",
196 Flags & MMDBG_COPY_WRITE ? "write" : "read",
198 return STATUS_UNSUCCESSFUL;
199 }
200
201 /* Not handling session space correctly yet */
203 {
204 /* FIXME */
205 }
206
207 /* If we are going to write to the address, then check if its writable */
208 PointerPte = MiAddressToPte(TargetAddress);
209 if ((Flags & MMDBG_COPY_WRITE) &&
210 (!MI_IS_PAGE_WRITEABLE(PointerPte)))
211 {
212 /* Not writable, we need to do a physical copy */
214
215 /* Calculate the physical address */
218
219 /* Translate the physical address */
221 Flags);
222
223 /* Check if translation failed */
224 if (!TargetAddress)
225 {
226 /* Fail */
227 KdpDprintf("MmDbgCopyMemory: Failed to translate for write %I64x (%I64x)\n",
229 Address);
230 return STATUS_UNSUCCESSFUL;
231 }
232 }
233 }
234
235 /* Check what kind of operation this is */
237 {
238 /* Write */
239 CopyDestination = TargetAddress;
240 CopySource = Buffer;
241 }
242 else
243 {
244 /* Read */
245 CopyDestination = Buffer;
246 CopySource = TargetAddress;
247 }
248
249 /* Do the copy */
250 switch (Size)
251 {
252 case 1:
253
254 /* 1 byte */
255 *(PUCHAR)CopyDestination = *(PUCHAR)CopySource;
256 break;
257
258 case 2:
259
260 /* 2 bytes */
261 *(PUSHORT)CopyDestination = *(PUSHORT)CopySource;
262 break;
263
264 case 4:
265
266 /* 4 bytes */
267 *(PULONG)CopyDestination = *(PULONG)CopySource;
268 break;
269
270 case 8:
271
272 /* 8 bytes */
273 *(PULONGLONG)CopyDestination = *(PULONGLONG)CopySource;
274 break;
275
276 /* Size is sanitized above */
278 }
279
280 /* Get rid of the mapping if this was a physical copy */
282 {
283 /* Unmap and flush it */
285 }
286
287 /* And we are done */
288 return STATUS_SUCCESS;
289}
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 1362 of file procsup.c.

1363{
1364 PMMPFN Pfn1, Pfn2;
1365 KIRQL OldIrql;
1366 PFN_NUMBER PageFrameIndex;
1367
1368#ifndef _M_AMD64
1370 RemoveEntryList(&Process->MmProcessLinks);
1372#endif
1373
1374 //ASSERT(Process->CommitCharge == 0);
1375
1376 /* Remove us from the list */
1378 if (Process->Vm.WorkingSetExpansionLinks.Flink != NULL)
1379 RemoveEntryList(&Process->Vm.WorkingSetExpansionLinks);
1381
1382 /* Acquire the PFN lock */
1383 OldIrql = MiAcquirePfnLock();
1384
1385 /* Check for fully initialized process */
1386 if (Process->AddressSpaceInitialized == 2)
1387 {
1388 /* Map the working set page and its page table */
1389 Pfn1 = MiGetPfnEntry(Process->WorkingSetPage);
1390 Pfn2 = MiGetPfnEntry(Pfn1->u4.PteFrame);
1391
1392 /* Nuke it */
1393 MI_SET_PFN_DELETED(Pfn1);
1394 MiDecrementShareCount(Pfn2, Pfn1->u4.PteFrame);
1395 MiDecrementShareCount(Pfn1, Process->WorkingSetPage);
1396 ASSERT((Pfn1->u3.e2.ReferenceCount == 0) || (Pfn1->u3.e1.WriteInProgress));
1397
1398 /* Now map hyperspace and its page table */
1399 PageFrameIndex = Process->Pcb.DirectoryTableBase[1] >> PAGE_SHIFT;
1400 Pfn1 = MiGetPfnEntry(PageFrameIndex);
1401 Pfn2 = MiGetPfnEntry(Pfn1->u4.PteFrame);
1402
1403 /* Nuke it */
1404 MI_SET_PFN_DELETED(Pfn1);
1405 MiDecrementShareCount(Pfn2, Pfn1->u4.PteFrame);
1406 MiDecrementShareCount(Pfn1, PageFrameIndex);
1407 ASSERT((Pfn1->u3.e2.ReferenceCount == 0) || (Pfn1->u3.e1.WriteInProgress));
1408
1409 /* Finally, nuke the PDE itself */
1410 PageFrameIndex = Process->Pcb.DirectoryTableBase[0] >> PAGE_SHIFT;
1411 Pfn1 = MiGetPfnEntry(PageFrameIndex);
1412 MI_SET_PFN_DELETED(Pfn1);
1413 MiDecrementShareCount(Pfn1, PageFrameIndex);
1414 MiDecrementShareCount(Pfn1, PageFrameIndex);
1415
1416 /* Page table is now dead. Bye bye... */
1417 ASSERT((Pfn1->u3.e2.ReferenceCount == 0) || (Pfn1->u3.e1.WriteInProgress));
1418 }
1419 else
1420 {
1421 DPRINT1("Deleting partially initialized address space of Process %p. Might leak resources.\n",
1422 Process);
1423 }
1424
1425 /* Release the PFN lock */
1426 MiReleasePfnLock(OldIrql);
1427
1428 /* Drop a reference on the session */
1430
1431 /* Clear out the PDE pages */
1432 Process->Pcb.DirectoryTableBase[0] = 0;
1433 Process->Pcb.DirectoryTableBase[1] = 0;
1434}
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:369
ULONG_PTR PteFrame
Definition: mm.h:425

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

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 1465 of file mminit.c.

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

5386{
5387 PSECTION Section = _Section;
5388
5389 /* It makes no sense to extend an image mapping */
5390 if (Section->u.Flags.Image)
5392
5393 /* Nor is it possible to extend a page file mapping */
5394 if (!Section->u.Flags.File)
5396
5397 if (!MiIsRosSectionObject(Section))
5399
5400 /* We just extend the sizes. Shrinking is a no-op ? */
5401 if (NewSize->QuadPart > Section->SizeOfSection.QuadPart)
5402 {
5404 Section->SizeOfSection = *NewSize;
5405
5406 if (!Section->u.Flags.Reserve)
5407 {
5409 if (Segment->RawLength.QuadPart < NewSize->QuadPart)
5410 {
5411 Segment->RawLength = *NewSize;
5412 Segment->Length.QuadPart = (NewSize->QuadPart + PAGE_SIZE - 1) & ~((LONGLONG)PAGE_SIZE);
5413 }
5415 }
5416 }
5417
5418 return STATUS_SUCCESS;
5419}
_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 5051 of file section.c.

5056{
5057 LARGE_INTEGER FlushStart, FlushEnd;
5059
5060 if (Offset)
5061 {
5062 FlushStart = *Offset;
5063 Status = RtlLongLongAdd(FlushStart.QuadPart, Length, &FlushEnd.QuadPart);
5064 if (!NT_SUCCESS(Status))
5065 return Status;
5066 }
5067
5068 if (Iosb)
5069 Iosb->Information = 0;
5070
5072 if (!Segment)
5073 {
5074 /* Nothing to flush */
5075 goto Quit;
5076 }
5077
5079
5081
5082 if (!Offset)
5083 {
5084 FlushStart.QuadPart = 0;
5085
5086 /* FIXME: All of this is suboptimal */
5087 ULONG ElemCount = RtlNumberGenericTableElements(&Segment->PageTable);
5088 if (!ElemCount)
5089 {
5090 /* No page. Nothing to flush */
5092 MmDereferenceSegment(Segment);
5093 goto Quit;
5094 }
5095
5097 FlushEnd.QuadPart = PageTable->FileOffset.QuadPart + _countof(PageTable->PageEntries) * PAGE_SIZE;
5098 }
5099
5100 /* Find byte offset of the page to start */
5101 FlushStart.QuadPart = PAGE_ROUND_DOWN_64(FlushStart.QuadPart);
5102
5103 while (FlushStart.QuadPart < FlushEnd.QuadPart)
5104 {
5106
5107 if (IS_DIRTY_SSE(Entry))
5108 {
5109 MmCheckDirtySegment(Segment, &FlushStart, FALSE, FALSE);
5110
5111 if (Iosb)
5112 Iosb->Information += PAGE_SIZE;
5113 }
5114
5115 FlushStart.QuadPart += PAGE_SIZE;
5116 }
5117
5119 MmDereferenceSegment(Segment);
5120
5121Quit:
5122 /* FIXME: Handle failures */
5123 if (Iosb)
5124 Iosb->Status = STATUS_SUCCESS;
5125
5126 return STATUS_SUCCESS;
5127}
_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 PAGE_ROUND_DOWN_64(x)
Definition: mm.h:138
#define MM_DATAFILE_SEGMENT
Definition: mm.h:245
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:252
VOID NTAPI MmDeletePageFileMapping(struct _EPROCESS *Process, PVOID Address, SWAPENTRY *SwapEntry)
PVOID Vad
Definition: mm.h:262
@ 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:515
PFN_NUMBER CurrentUsage
Definition: mm.h:512
PFN_NUMBER FreeSpace
Definition: mm.h:511

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

◆ MmGetAddressSpaceOwner()

◆ MmGetCurrentAddressSpace()

FORCEINLINE PMMSUPPORT MmGetCurrentAddressSpace ( VOID  )

Definition at line 1731 of file mm.h.

1732{
1733 return &((PEPROCESS)KeGetCurrentThread()->ApcState.Process)->Vm;
1734}
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:112
* 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 477 of file procsup.c.

478{
479 //
480 // Call the extended version
481 //
483}
NTSTATUS NTAPI MmGrowKernelStackEx(IN PVOID StackPointer, IN ULONG GrowSize)
Definition: procsup.c:389
#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:465

Referenced by MiInitMachineDependent().

◆ MmInitializeHandBuiltProcess()

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

Definition at line 1127 of file procsup.c.

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

Referenced by PspCreateProcess().

◆ MmInitializeHandBuiltProcess2()

NTSTATUS NTAPI MmInitializeHandBuiltProcess2 ( IN PEPROCESS  Process)

Definition at line 1153 of file procsup.c.

1154{
1155 /* Lock the VAD, ARM3-owned ranges away */
1156 return STATUS_SUCCESS;
1157}

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

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:273
#define TAG_RMAP
Definition: tag.h:111

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}
#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::@2701 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:1330
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:426
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 
)

◆ MmIsDataSectionResident()

BOOLEAN NTAPI MmIsDataSectionResident ( _In_ PSECTION_OBJECT_POINTERS  SectionObjectPointer,
_In_ LONGLONG  Offset,
_In_ ULONG  Length 
)

Definition at line 4932 of file section.c.

4936{
4938 LARGE_INTEGER RangeStart, RangeEnd;
4939 BOOLEAN Ret = TRUE;
4940
4941 RangeStart.QuadPart = Offset;
4942 if (!NT_SUCCESS(RtlLongLongAdd(RangeStart.QuadPart, Length, &RangeEnd.QuadPart)))
4943 return FALSE;
4944
4946 if (!Segment)
4947 return FALSE;
4948
4949 /* Find byte offset of the page to start */
4950 RangeStart.QuadPart = PAGE_ROUND_DOWN_64(RangeStart.QuadPart);
4951
4953
4954 while (RangeStart.QuadPart < RangeEnd.QuadPart)
4955 {
4957 if ((Entry == 0) || IS_SWAP_FROM_SSE(Entry))
4958 {
4959 Ret = FALSE;
4960 break;
4961 }
4962
4963 RangeStart.QuadPart += PAGE_SIZE;
4964 }
4965
4967 MmDereferenceSegment(Segment);
4968
4969 return Ret;
4970}

Referenced by CcRosEnsureVacbResident().

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

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

Referenced by MiProtectVirtualMemory(), MiQueryMemoryBasicInformation(), MiRosProtectVirtualMemory(), MiRosUnmapViewOfSection(), MiUnmapViewOfSection(), MmAccessFault(), MmAlterViewAttributes(), 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 4974 of file section.c.

4979{
4981
4982 /* There must be a segment for this call */
4983 ASSERT(Segment);
4984
4986
4987 MmDereferenceSegment(Segment);
4988
4989 return Status;
4990}
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().

◆ MmMakeSegmentDirty()

NTSTATUS NTAPI MmMakeSegmentDirty ( _In_ PSECTION_OBJECT_POINTERS  SectionObjectPointer,
_In_ LONGLONG  Offset,
_In_ ULONG  Length 
)

Definition at line 4994 of file section.c.

4998{
5000 LARGE_INTEGER RangeStart, RangeEnd;
5002
5003 RangeStart.QuadPart = Offset;
5004 Status = RtlLongLongAdd(RangeStart.QuadPart, Length, &RangeEnd.QuadPart);
5005 if (!NT_SUCCESS(Status))
5006 return Status;
5007
5009 if (!Segment)
5011
5012 /* Find byte offset of the page to start */
5013 RangeStart.QuadPart = PAGE_ROUND_DOWN_64(RangeStart.QuadPart);
5014
5016
5017 while (RangeStart.QuadPart < RangeEnd.QuadPart)
5018 {
5020
5021 /* Let any pending read proceed */
5022 while (MM_IS_WAIT_PTE(Entry))
5023 {
5028 }
5029
5030 /* We are called from Cc, this can't be backed by the page files */
5032
5033 /* If there is no page there, there is nothing to make dirty */
5034 if (Entry != 0)
5035 {
5036 /* Dirtify the entry */
5038 }
5039
5040 RangeStart.QuadPart += PAGE_SIZE;
5041 }
5042
5044 MmDereferenceSegment(Segment);
5045
5046 return STATUS_SUCCESS;
5047}
#define KeDelayExecutionThread(mode, foo, t)
Definition: env_spec_w32.h:484
#define DIRTY_SSE(E)
Definition: mm.h:1382
#define MM_IS_WAIT_PTE(E)
Definition: mm.h:1377
#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 PAGE_ROUND_DOWN(x)
Definition: mmtypes.h:36
#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}
@ VadImageMap
Definition: mmtypes.h:206
#define PAGE_GUARD
Definition: nt_native.h:1310
VOID NTAPI FsRtlReleaseFile(IN PFILE_OBJECT FileObject)
Definition: fastio.c:1665
VOID NTAPI FsRtlAcquireFileExclusive(IN PFILE_OBJECT FileObject)
Definition: fastio.c:1640
VOID NTAPI MmGetPageFileMapping(PEPROCESS Process, PVOID Address, SWAPENTRY *SwapEntry)
Definition: page.c:299
#define MAKE_SSE(P, C)
Definition: mm.h:1394
BOOLEAN NTAPI MmIsDisabledPage(struct _EPROCESS *Process, PVOID Address)
#define SWAPENTRY_FROM_SSE(E)
Definition: mm.h:1380
#define MAKE_SWAP_SSE(S)
Definition: mm.h:1381
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:5140
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:1259
struct _MM_RMAP_ENTRY *NTAPI MmGetRmapListHeadPage(PFN_NUMBER Page)
Definition: freelist.c:459
#define RMAP_IS_SEGMENT(x)
Definition: mm.h:947
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 4837 of file section.c.

4841{
4842 LARGE_INTEGER PurgeStart, PurgeEnd;
4844
4845 PurgeStart.QuadPart = Offset ? Offset->QuadPart : 0LL;
4846 if (Length && Offset)
4847 {
4848 if (!NT_SUCCESS(RtlLongLongAdd(PurgeStart.QuadPart, Length, &PurgeEnd.QuadPart)))
4849 return FALSE;
4850 }
4851
4853 if (!Segment)
4854 {
4855 /* Nothing to purge */
4856 return TRUE;
4857 }
4858
4860
4861 if (!Length || !Offset)
4862 {
4863 /* We must calculate the length for ourselves */
4864 /* FIXME: All of this is suboptimal */
4865 ULONG ElemCount = RtlNumberGenericTableElements(&Segment->PageTable);
4866 if (!ElemCount)
4867 {
4868 /* No page. Nothing to purge */
4870 MmDereferenceSegment(Segment);
4871 return TRUE;
4872 }
4873
4875 PurgeEnd.QuadPart = PageTable->FileOffset.QuadPart + _countof(PageTable->PageEntries) * PAGE_SIZE;
4876 }
4877
4878 /* Find byte offset of the page to start */
4879 PurgeStart.QuadPart = PAGE_ROUND_DOWN_64(PurgeStart.QuadPart);
4880
4881 while (PurgeStart.QuadPart < PurgeEnd.QuadPart)
4882 {
4884
4885 if (Entry == 0)
4886 {
4887 PurgeStart.QuadPart += PAGE_SIZE;
4888 continue;
4889 }
4890
4892 {
4893 ASSERT(SWAPENTRY_FROM_SSE(Entry) == MM_WAIT_ENTRY);
4894 /* The page is currently being read. Meaning someone will need it soon. Bad luck */
4896 MmDereferenceSegment(Segment);
4897 return FALSE;
4898 }
4899
4900 if (IS_WRITE_SSE(Entry))
4901 {
4902 /* We're trying to purge an entry which is being written. Restart this loop iteration */
4906 continue;
4907 }
4908
4909 if (SHARE_COUNT_FROM_SSE(Entry) > 0)
4910 {
4911 /* This page is currently in use. Bad luck */
4913 MmDereferenceSegment(Segment);
4914 return FALSE;
4915 }
4916
4917 /* We can let this page go */
4918 MmSetPageEntrySectionSegment(Segment, &PurgeStart, 0);
4920
4921 PurgeStart.QuadPart += PAGE_SIZE;
4922 }
4923
4924 /* This page is currently in use. Bad luck */
4926 MmDereferenceSegment(Segment);
4927 return TRUE;
4928}
#define SHARE_COUNT_FROM_SSE(E)
Definition: mm.h:1392
#define IS_WRITE_SSE(E)
Definition: mm.h:1386
#define LL
Definition: tui.h:166

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{
293 {
295 }
296}
#define KeSetEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:476
#define InterlockedCompareExchange
Definition: interlocked.h:104
static LONG PageOutThreadActive
Definition: balance.c:37
#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
318 /* Delay some requests for the Memory Manager to recover pages (CORE-17624).
319 * FIXME: This is suboptimal.
320 */
321 static INT i = 0;
322 static LARGE_INTEGER TinyTime = {{-1L, -1L}};
323 if (i++ >= 100)
324 {
326 i = 0;
327 }
328
329 /*
330 * Actually allocate the page.
331 */
332 Page = MmAllocPage(Consumer);
333 if (Page == 0)
334 {
335 *AllocatedPage = 0;
336 return STATUS_NO_MEMORY;
337 }
338 *AllocatedPage = Page;
339
340 /* Update the target */
341 InterlockedIncrementUL(&MiMemoryConsumers[Consumer].PagesUsed);
343
344 return(STATUS_SUCCESS);
345}
#define InterlockedIncrementUL(Addend)
Definition: ex.h:1544
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 487 of file procsup.c.

489{
490 UCHAR OldPriority;
491
492 //
493 // Check if we have less then 16MB of Physical Memory
494 //
495 if ((MmSystemSize == MmSmallSystem) &&
496 (MmNumberOfPhysicalPages < ((15 * 1024 * 1024) / PAGE_SIZE)))
497 {
498 //
499 // Always use background priority
500 //
501 MemoryPriority = MEMORY_PRIORITY_BACKGROUND;
502 }
503
504 //
505 // Save the old priority and update it
506 //
507 OldPriority = (UCHAR)Process->Vm.Flags.MemoryPriority;
508 Process->Vm.Flags.MemoryPriority = MemoryPriority;
509
510 //
511 // Return the old priority
512 //
513 return OldPriority;
514}
#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:1396
PLARGE_INTEGER BOOLEAN BOOLEAN PageOut
Definition: section.c:5137

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:450
PFN_NUMBER Flink
Definition: mm.h:452
PFN_NUMBER Flink
Definition: mm.h:384
KPRIORITY NTAPI KeSetPriorityThread(IN PKTHREAD Thread, IN KPRIORITY Priority)
Definition: thrdobj.c:1300
@ 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 878 of file mm.h.

879{
880 /*
881 * Add up all the used "Committed" memory + pagefile.
882 * Not sure this is right. 8^\
883 * MmTotalCommittedPages should be adjusted consistently with
884 * other counters at different places.
885 *
886 MmTotalCommittedPages = MiMemoryConsumers[MC_SYSTEM].PagesUsed +
887 MiMemoryConsumers[MC_USER].PagesUsed +
888 MiUsedSwapPages;
889 */
890
891 /* Update Commitment */
893
894 /* Update Peak = max(Peak, Total) in a lockless way */
895 SIZE_T PeakCommitment = MmPeakCommitment;
896 while (TotalCommittedPages > PeakCommitment &&
897 InterlockedCompareExchangeSizeT(&MmPeakCommitment, TotalCommittedPages, PeakCommitment) != PeakCommitment)
898 {
899 PeakCommitment = MmPeakCommitment;
900 }
901}
#define InterlockedCompareExchangeSizeT(Destination, Exchange, Comperand)
Definition: ex.h:1556
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 1310 of file mm.h.

◆ ApcState

◆ CurrentMaxQuota

_In_ SIZE_T CurrentMaxQuota

Definition at line 672 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 45 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 673 of file mm.h.

Referenced by _Requires_lock_held_().

◆ Page

Definition at line 1312 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_CreatePropertySheetPageEx(), ShowFolderOptionsDialog(), TestFreeNoAccess(), TestMmBuildMdlForNonPagedPool(), TrimWsList(), vfatDirFindFile(), VidBiosDrawGlyph(), VidBiosGetCursorPosition(), VidBiosPrintCharacter(), VidBiosScrollWindow(), VidBiosSetCursorPosition(), VidBiosSetVideoMode(), and VidBiosVideoService().

◆ QuotaToReturn

_In_ SIZE_T QuotaToReturn

Definition at line 681 of file mm.h.

Referenced by _Requires_lock_held_().

◆ WasDirty

Definition at line 1311 of file mm.h.

Referenced by _Success_(), and MmDeleteVirtualMapping().