extern ULONG MmTotalPagedPoolQuota;
extern ULONG MmTotalNonPagedPoolQuota;
extern PHYSICAL_ADDRESS MmSharedDataPagePhysicalAddress;
+extern ULONG MmNumberOfPhysicalPages;
extern PVOID MmPagedPoolBase;
extern ULONG MmPagedPoolSize;
+extern PMEMORY_ALLOCATION_DESCRIPTOR MiFreeDescriptor;
+extern MEMORY_ALLOCATION_DESCRIPTOR MiFreeDescriptorOrg;
+extern ULONG MmHighestPhysicalPage;
+extern PVOID MmPfnDatabase;
+
struct _KTRAP_FRAME;
struct _EPROCESS;
struct _MM_RMAP_ENTRY;
#define MM_PAGEOP_PAGESYNCH (3)
#define MM_PAGEOP_ACCESSFAULT (4)
+/* Number of list heads to use */
+#define MI_FREE_POOL_LISTS 4
+
+/* Signature of free pool blocks */
+#define MM_FREE_POOL_TAG TAG('F', 'r', 'p', 'l')
+
#define PAGE_TO_SECTION_PAGE_DIRECTORY_OFFSET(x) \
((x) / (4*1024*1024))
/* Although Microsoft says this isn't hardcoded anymore,
they won't be able to change it. Stuff depends on it */
-#define MM_VIRTMEM_GRANULARITY (64 * 1024)
+#define MM_VIRTMEM_GRANULARITY (64 * 1024)
#define STATUS_MM_RESTART_OPERATION ((NTSTATUS)0xD0000001)
typedef struct _MM_SECTION_SEGMENT
{
- LONG FileOffset; /* start offset into the file for image sections */
+ LONG FileOffset; /* start offset into the file for image sections */
ULONG_PTR VirtualAddress; /* dtart offset into the address range for image sections */
ULONG RawLength; /* length of the segment which is part of the mapped file */
ULONG Length; /* absolute length of the segment */
{
PMEMORY_AREA MemoryAreaRoot;
PVOID LowestAddress;
- struct _EPROCESS* Process;
+ PEPROCESS Process;
PUSHORT PageTableRefCountTable;
- ULONG PageTableRefCountTableSize;
+ PEX_PUSH_LOCK Lock;
} MADDRESS_SPACE, *PMADDRESS_SPACE;
typedef struct
{
ULONG NrTotalPages;
ULONG NrSystemPages;
- ULONG NrReservedPages;
ULONG NrUserPages;
ULONG NrFreePages;
ULONG NrDirtyPages;
ULONG PagingRequestsInLastFifteenMinutes;
} MM_STATS;
+typedef struct _PHYSICAL_PAGE
+{
+ union
+ {
+ struct
+ {
+ ULONG Type: 2;
+ ULONG Consumer: 3;
+ ULONG Zero: 1;
+ ULONG StartOfAllocation: 1;
+ ULONG EndOfAllocation: 1;
+ }
+ Flags;
+ ULONG AllFlags;
+ };
+
+ LIST_ENTRY ListEntry;
+ ULONG ReferenceCount;
+ SWAPENTRY SavedSwapEntry;
+ ULONG LockCount;
+ ULONG MapCount;
+ struct _MM_RMAP_ENTRY* RmapListHead;
+}
+PHYSICAL_PAGE, *PPHYSICAL_PAGE;
+
extern MM_STATS MmStats;
typedef struct _MM_PAGEOP
LIST_ENTRY RegionListEntry;
} MM_REGION, *PMM_REGION;
+/* Entry describing free pool memory */
+typedef struct _MMFREE_POOL_ENTRY
+{
+ LIST_ENTRY List;
+ PFN_NUMBER Size;
+ ULONG Signature;
+ struct _MMFREE_POOL_ENTRY *Owner;
+} MMFREE_POOL_ENTRY, *PMMFREE_POOL_ENTRY;
+
+/* Paged pool information */
+typedef struct _MM_PAGED_POOL_INFO
+{
+ PRTL_BITMAP PagedPoolAllocationMap;
+ PRTL_BITMAP EndOfPagedPoolBitmap;
+ PMMPTE FirstPteForPagedPool;
+ PMMPTE LastPteForPagedPool;
+ PMMPTE NextPdeForPagedPoolExpansion;
+ ULONG PagedPoolHint;
+ SIZE_T PagedPoolCommit;
+ SIZE_T AllocatedPagedPool;
+} MM_PAGED_POOL_INFO, *PMM_PAGED_POOL_INFO;
+
extern MM_MEMORY_CONSUMER MiMemoryConsumers[MC_MAXIMUM];
typedef VOID
/* aspace.c ******************************************************************/
-VOID
-NTAPI
-MmLockAddressSpace(PMADDRESS_SPACE AddressSpace);
-
-VOID
-NTAPI
-MmUnlockAddressSpace(PMADDRESS_SPACE AddressSpace);
-
VOID
NTAPI
MmInitializeKernelAddressSpace(VOID);
-PMADDRESS_SPACE
-NTAPI
-MmGetCurrentAddressSpace(VOID);
-
-PMADDRESS_SPACE
-NTAPI
-MmGetKernelAddressSpace(VOID);
-
NTSTATUS
NTAPI
MmInitializeAddressSpace(
PVOID BaseAddress
);
+VOID
+NTAPI
+MmMapMemoryArea(PVOID BaseAddress,
+ ULONG Length,
+ ULONG Consumer,
+ ULONG Protection);
+
/* npool.c *******************************************************************/
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
+);
+
PVOID
NTAPI
MmGetMdlPageAddress(
NTAPI
ExFreeNonPagedPool(PVOID block);
-VOID
+VOID
NTAPI
ExFreePagedPool(IN PVOID Block);
-VOID
+VOID
NTAPI
MmInitializePagedPool(VOID);
VOID
NTAPI
MmInit1(
- ULONG_PTR FirstKernelPhysAddress,
- ULONG_PTR LastKernelPhysAddress,
- ULONG_PTR LastKernelAddress,
- PADDRESS_RANGE BIOSMemoryMap,
- ULONG AddressRangeCount,
- ULONG MaxMemInMeg
+ VOID
);
BOOLEAN
NTSTATUS
NTAPI
-MmCreateProcessAddressSpace(
+MmInitializeProcessAddressSpace(
IN PEPROCESS Process,
- IN PROS_SECTION_OBJECT Section OPTIONAL,
+ IN PEPROCESS Clone OPTIONAL,
+ IN PVOID Section OPTIONAL,
+ IN OUT PULONG Flags,
IN POBJECT_NAME_INFORMATION *AuditName OPTIONAL
);
NTSTATUS (*Trim)(ULONG Target, ULONG Priority, PULONG NrFreed)
);
-VOID
+VOID
NTAPI
MmInitializeBalancer(
ULONG NrAvailablePages,
ULONG NrSystemPages
);
-NTSTATUS
+NTSTATUS
NTAPI
MmReleasePageMemoryConsumer(
ULONG Consumer,
/* freelist.c **********************************************************/
+#define ASSERT_PFN(x) ASSERT((x)->Flags.Type != 0)
+
+FORCEINLINE
+PPHYSICAL_PAGE
+MiGetPfnEntry(IN PFN_TYPE Pfn)
+{
+ PPHYSICAL_PAGE Page;
+ extern PPHYSICAL_PAGE MmPageArray;
+ extern ULONG MmPageArraySize;
+
+ /* Mark MmPageArraySize as unreferenced, otherwise it will appear as an unused variable on a Release build */
+ UNREFERENCED_PARAMETER(MmPageArraySize);
+
+ /* Make sure the PFN number is valid */
+ ASSERT(Pfn <= MmPageArraySize);
+
+ /* Get the entry */
+ Page = &MmPageArray[Pfn];
+
+ /* Make sure it's valid */
+ ASSERT_PFN(Page);
+
+ /* Return it */
+ return Page;
+};
+
PFN_TYPE
NTAPI
MmGetLRUNextUserPage(PFN_TYPE PreviousPage);
VOID
NTAPI
-MmSetLRULastPage(PFN_TYPE Page);
+MmInsertLRULastUserPage(PFN_TYPE Page);
+
+VOID
+NTAPI
+MmRemoveLRUUserPage(PFN_TYPE Page);
VOID
NTAPI
NTAPI
MmGetLockCountPage(PFN_TYPE Page);
-PVOID
+VOID
NTAPI
MmInitializePageList(
- ULONG_PTR FirstPhysKernelAddress,
- ULONG_PTR LastPhysKernelAddress,
- ULONG MemorySizeInPages,
- ULONG_PTR LastKernelBase,
- PADDRESS_RANGE BIOSMemoryMap,
- ULONG AddressRangeCount
+ VOID
);
PFN_TYPE
BOOLEAN
NTAPI
-MmIsUsablePage(PFN_TYPE Page);
+MmIsPageInUse(PFN_TYPE Page);
VOID
NTAPI
PVOID Address
);
+BOOLEAN
+NTAPI
+MmCreateProcessAddressSpace(
+ IN ULONG MinWs,
+ IN PEPROCESS Dest,
+ IN PLARGE_INTEGER DirectoryTableBase
+);
+
+NTSTATUS
+NTAPI
+MmInitializeHandBuiltProcess(
+ IN PEPROCESS Process,
+ IN PLARGE_INTEGER DirectoryTableBase
+);
+
+
NTSTATUS
NTAPI
-MmCopyMmInfo(
- struct _EPROCESS *Src,
- struct _EPROCESS *Dest,
- PPHYSICAL_ADDRESS DirectoryTableBase
+MmInitializeHandBuiltProcess2(
+ IN PEPROCESS Process
);
NTSTATUS
OUT POBJECT_NAME_INFORMATION *ModuleName
);
-PVOID
+PVOID
NTAPI
MmAllocateSection(
IN ULONG Length,
FORCEINLINE
VOID
NTAPI
-MiSyncThreadProcessViews(IN PKPROCESS Process,
+MiSyncThreadProcessViews(IN PVOID Process,
IN PVOID Address,
IN ULONG Size)
{
MmUpdatePageDir((PEPROCESS)Process, Address, Size);
}
+
+extern MADDRESS_SPACE MmKernelAddressSpace;
+
+FORCEINLINE
+VOID
+MmLockAddressSpace(PMADDRESS_SPACE AddressSpace)
+{
+ KeEnterCriticalRegion();
+ ExAcquirePushLockExclusive(AddressSpace->Lock);
+}
+
+FORCEINLINE
+VOID
+MmUnlockAddressSpace(PMADDRESS_SPACE AddressSpace)
+{
+ ExReleasePushLock(AddressSpace->Lock);
+ KeLeaveCriticalRegion();
+}
+
+FORCEINLINE
+PMADDRESS_SPACE
+MmGetCurrentAddressSpace(VOID)
+{
+ return (PMADDRESS_SPACE)&((PEPROCESS)KeGetCurrentThread()->ApcState.Process)->VadRoot;
+}
+
+FORCEINLINE
+PMADDRESS_SPACE
+MmGetKernelAddressSpace(VOID)
+{
+ return &MmKernelAddressSpace;
+}
+
#endif