16 #if defined (ALLOC_PRAGMA) 17 #pragma alloc_text(INIT, MmInitGlobalKernelPageDirectory) 22 #define PA_BIT_PRESENT (0) 23 #define PA_BIT_READWRITE (1) 24 #define PA_BIT_USER (2) 27 #define PA_BIT_ACCESSED (5) 28 #define PA_BIT_DIRTY (6) 29 #define PA_BIT_GLOBAL (8) 31 #define PA_PRESENT (1 << PA_BIT_PRESENT) 32 #define PA_READWRITE (1 << PA_BIT_READWRITE) 33 #define PA_USER (1 << PA_BIT_USER) 34 #define PA_DIRTY (1 << PA_BIT_DIRTY) 35 #define PA_WT (1 << PA_BIT_WT) 36 #define PA_CD (1 << PA_BIT_CD) 37 #define PA_ACCESSED (1 << PA_BIT_ACCESSED) 38 #define PA_GLOBAL (1 << PA_BIT_GLOBAL) 40 #define PAGEDIRECTORY_MAP (0xc0000000 + (PTE_BASE / (1024))) 41 #define PAE_PAGEDIRECTORY_MAP (0xc0000000 + (PTE_BASE / (512))) 43 #define HYPERSPACE (Ke386Pae ? 0xc0800000 : 0xc0400000) 44 #define IS_HYPERSPACE(v) (((ULONG)(v) >= HYPERSPACE && (ULONG)(v) < HYPERSPACE + 0x400000)) 49 #define PTE_TO_PFN(X) ((X) >> PAGE_SHIFT) 50 #define PFN_TO_PTE(X) ((X) << PAGE_SHIFT) 52 #define PAE_PTE_TO_PFN(X) (PAE_PAGE_MASK(X) >> PAGE_SHIFT) 53 #define PAE_PFN_TO_PTE(X) ((X) << PAGE_SHIFT) 55 #define PAGE_MASK(x) ((x)&(~0xfff)) 56 #define PAE_PAGE_MASK(x) ((x)&(~0xfffLL)) 127 DPRINT1(
"Unknown main protection type.\n");
154 #define ADDR_TO_PAGE_TABLE(v) (((ULONG)(v)) / (1024 * PAGE_SIZE)) 156 #define ADDR_TO_PDE(v) (PULONG)(PAGEDIRECTORY_MAP + \ 157 ((((ULONG)(v)) / (1024 * 1024))&(~0x3))) 158 #define ADDR_TO_PTE(v) (PULONG)(PTE_BASE + ((((ULONG)(v) / 1024))&(~0x3))) 160 #define ADDR_TO_PDE_OFFSET(v) ((((ULONG)(v)) / (1024 * PAGE_SIZE))) 162 #define ADDR_TO_PTE_OFFSET(v) ((((ULONG)(v)) % (1024 * PAGE_SIZE)) / PAGE_SIZE) 165 #define PAE_ADDR_TO_PAGE_TABLE(v) (((ULONG)(v)) / (512 * PAGE_SIZE)) 167 #define PAE_ADDR_TO_PDE(v) (PULONGLONG) (PAE_PAGEDIRECTORY_MAP + \ 168 ((((ULONG_PTR)(v)) / (512 * 512))&(~0x7))) 169 #define PAE_ADDR_TO_PTE(v) (PULONGLONG) (PTE_BASE + ((((ULONG_PTR)(v) / 512))&(~0x7))) 172 #define PAE_ADDR_TO_PDTE_OFFSET(v) (((ULONG_PTR)(v)) / (512 * 512 * PAGE_SIZE)) 174 #define PAE_ADDR_TO_PDE_PAGE_OFFSET(v) ((((ULONG_PTR)(v)) % (512 * 512 * PAGE_SIZE)) / (512 * PAGE_SIZE)) 176 #define PAE_ADDR_TO_PDE_OFFSET(v) (((ULONG_PTR)(v))/ (512 * PAGE_SIZE)) 178 #define PAE_ADDR_TO_PTE_OFFSET(v) ((((ULONG_PTR)(v)) % (512 * PAGE_SIZE)) / PAGE_SIZE) 200 for (
j = 0;
j <
i;
j++)
215 for (
i = 0;
i < 4;
i++)
226 for (
j = 0;
j < 4;
j++)
255 DirectoryTableBase->QuadPart =
PFN_TO_PTE(Pfn[0]);
256 DPRINT(
"Finished MmCopyMmInfo(): %I64x\n", DirectoryTableBase->QuadPart);
278 for (
i = 0;
i < 512;
i++)
282 DbgPrint(
"Page table entry not clear at %x/%x (is %I64x)\n",
295 for (
i = 0;
i < 1024;
i++)
299 DbgPrint(
"Page table entry not clear at %x/%x (is %x)\n",
335 DPRINT(
"MmGetPageTableForProcessForPAE(%x %x %d)\n",
344 if (PageDirTable ==
NULL)
405 if (Ke386GlobalPagesEnabled)
502 if (Ke386GlobalPagesEnabled)
626 DPRINT(
"MmDeleteVirtualMapping(%x, %x, %d, %x, %x)\n",
636 if (WasDirty !=
NULL)
651 Pte = ExfpInterlockedExchange64UL(Pt, &Pte);
659 MmMarkPageUnmapped(Pfn);
669 if (WasDirty !=
NULL)
687 if (WasDirty !=
NULL)
709 MmMarkPageUnmapped(Pfn);
719 if (WasDirty !=
NULL)
732 ((PMADDRESS_SPACE)&
Process->VadRoot)->PageTableRefCountTable !=
NULL &&
738 Ptrc = ((PMADDRESS_SPACE)&
Process->VadRoot)->PageTableRefCountTable;
773 Pte = ExfpInterlockedExchange64UL(Pt, &Pte);
781 ((PMADDRESS_SPACE)&
Process->VadRoot)->PageTableRefCountTable !=
NULL &&
786 Ptrc = ((PMADDRESS_SPACE)&
Process->VadRoot)->PageTableRefCountTable;
799 *SwapEntry = Pte >> 1;
825 ((PMADDRESS_SPACE)&
Process->VadRoot)->PageTableRefCountTable !=
NULL &&
830 Ptrc = ((PMADDRESS_SPACE)&
Process->VadRoot)->PageTableRefCountTable;
843 *SwapEntry = Pte >> 1;
860 FLASH_TLB_ONE(PAddress);
877 FLASH_TLB_ONE(PAddress);
908 DPRINT1(
"MmSetCleanPage is called for user space without a process.\n");
973 DPRINT1(
"MmSetDirtyPage is called for user space without a process.\n");
1073 DPRINT1(
"Setting kernel address with process context\n");
1076 if (SwapEntry & (1 << 31))
1092 tmpPte = SwapEntry << 1;
1093 Pte = ExfpInterlockedExchange64UL(Pt, &tmpPte);
1134 ((PMADDRESS_SPACE)&
Process->VadRoot)->PageTableRefCountTable !=
NULL &&
1140 Ptrc = ((PMADDRESS_SPACE)&
Process->VadRoot)->PageTableRefCountTable;
1159 ULONG oldPdeOffset, PdeOffset;
1162 DPRINT(
"MmCreateVirtualMappingUnsafe(%x, %x, %x, %x (%x), %d)\n",
1172 if (PageCount > 0x10000 ||
1175 DPRINT1(
"Page count to large\n");
1183 DPRINT1(
"Setting kernel address with process context\n");
1190 DPRINT1(
"Page Count to large\n");
1204 if (Ke386GlobalPagesEnabled)
1226 DPRINT1(
"Setting physical address but not allowing access at address " 1227 "0x%.8X with attributes %x/%x.\n",
1232 if (oldPdeOffset != PdeOffset)
1245 oldPdeOffset = PdeOffset;
1247 MmMarkPageMapped(Pages[
i]);
1251 tmpPte |= 0x8000000000000000
LL;
1253 Pte = ExfpInterlockedExchange64UL(Pt, &tmpPte);
1263 ((PMADDRESS_SPACE)&
Process->VadRoot)->PageTableRefCountTable !=
NULL &&
1268 Ptrc = ((PMADDRESS_SPACE)&
Process->VadRoot)->PageTableRefCountTable;
1295 DPRINT1(
"Setting physical address but not allowing access at address " 1296 "0x%.8X with attributes %x/%x.\n",
1301 if (oldPdeOffset != PdeOffset)
1314 oldPdeOffset = PdeOffset;
1317 MmMarkPageMapped(Pages[
i]);
1328 ((PMADDRESS_SPACE)&
Process->VadRoot)->PageTableRefCountTable !=
NULL &&
1333 Ptrc = ((PMADDRESS_SPACE)&
Process->VadRoot)->PageTableRefCountTable;
1364 for (
i = 0;
i < PageCount;
i++)
1433 DPRINT(
"MmSetPageProtect(Process %x Address %x flProtect %x)\n",
1445 if (Ke386GlobalPagesEnabled)
1471 tmpPte |= 0x8000000000000000
LL;
1475 tmpPte &= ~0x8000000000000000
LL;
1502 DPRINT(
"MmInitGlobalKernelPageDirectory()\n");
1514 if (Ke386GlobalPagesEnabled)
1532 if (Ke386GlobalPagesEnabled)
#define PAGE_WRITETHROUGH
NTSTATUS NTAPI MmCreateVirtualMapping(PEPROCESS Process, PVOID Address, ULONG flProtect, PPFN_NUMBER Pages, ULONG PageCount)
#define PAE_ADDR_TO_PTE(v)
NTSTATUS NTAPI MmCreatePageFileMapping(PEPROCESS Process, PVOID Address, SWAPENTRY SwapEntry)
BOOLEAN NTAPI MmIsPagePresent(PEPROCESS Process, PVOID Address)
struct png_info_def **typedef void(__cdecl typeof(png_destroy_read_struct))(struct png_struct_def **
#define PAGE_IS_EXECUTABLE
static PMEM_HOOK PageTable[TOTAL_PAGES]
VOID NTAPI MmSetDirtyPage(PEPROCESS Process, PVOID Address)
_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
BOOLEAN NTAPI MmIsPageSwapEntry(PEPROCESS Process, PVOID Address)
BOOLEAN NTAPI MmIsPageInUse(PFN_NUMBER Page)
#define PAGEDIRECTORY_MAP
#define ADDR_TO_PTE_OFFSET(v)
NTSTATUS NTAPI MmReleasePageMemoryConsumer(ULONG Consumer, PFN_NUMBER Page)
NTSTATUS NTAPI MmCreateVirtualMappingUnsafe(PEPROCESS Process, PVOID Address, ULONG flProtect, PPFN_NUMBER Pages, ULONG PageCount)
#define PAGE_ROUND_DOWN(x)
VOID NTAPI MmSetCleanPage(PEPROCESS Process, PVOID Address)
VOID NTAPI MmFreePageTable(PEPROCESS Process, PVOID Address)
NTSTATUS NTAPI MmRequestPageMemoryConsumer(ULONG Consumer, BOOLEAN MyWait, PPFN_NUMBER AllocatedPage)
_Inout_ __drv_aliasesMem PSLIST_ENTRY _Inout_ PSLIST_ENTRY _In_ ULONG Count
static ULONG ProtectToPTE(ULONG flProtect)
static ULONG MmGlobalKernelPageDirectory[1024]
#define InterlockedCompareExchangeUL(Destination, Exchange, Comperand)
#define PAE_PAGEDIRECTORY_MAP
ULONG NTAPI MmGetPageProtect(PEPROCESS Process, PVOID Address)
BOOLEAN Mmi386MakeKernelPageTableGlobal(PVOID PAddress)
#define ExfInterlockedCompareExchange64UL(Destination, Exchange, Comperand)
VOID NTAPI MmDeleteVirtualMapping(PEPROCESS Process, PVOID Address, BOOLEAN *WasDirty, PPFN_NUMBER Page)
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
#define PAE_ADDR_TO_PDE_PAGE_OFFSET(v)
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
VOID NTAPI MmDeletePageFileMapping(PEPROCESS Process, PVOID Address, SWAPENTRY *SwapEntry)
#define PsGetCurrentProcess
static ULONG MmGetPageEntryForProcess(PEPROCESS Process, PVOID Address)
#define InterlockedExchangeUL(Target, Value)
BOOLEAN MmUnmapPageTable(PULONG Pt)
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 GLint GLint j
#define NT_SUCCESS(StatCode)
BOOLEAN NTAPI MmCreateProcessAddressSpace(IN ULONG MinWs, IN PEPROCESS Process, IN PLARGE_INTEGER DirectoryTableBase)
PFN_NUMBER NTAPI MmGetPfnForProcess(PEPROCESS Process, PVOID Address)
#define PAE_ADDR_TO_PTE_OFFSET(v)
#define MmDeleteHyperspaceMapping(x)
VOID INIT_FUNCTION NTAPI MmInitGlobalKernelPageDirectory(VOID)
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
VOID NTAPI KeDetachProcess(VOID)
static PULONGLONG MmGetPageTableForProcessForPAE(PEPROCESS Process, PVOID Address, BOOLEAN Create)
#define memcpy(s1, s2, n)
#define PAE_ADDR_TO_PAGE_TABLE(v)
static PULONG MmGetPageTableForProcess(PEPROCESS Process, PVOID Address, BOOLEAN Create)
#define InterlockedExchange
_Must_inspect_result_ _In_ USHORT _In_ PHIDP_PREPARSED_DATA _Out_writes_to_ LengthAttributes PHIDP_EXTENDED_ATTRIBUTES Attributes
VOID MiFlushTlb(PULONG Pt, PVOID Address)
#define PAE_PFN_TO_PTE(X)
VOID NTAPI KeAttachProcess(IN PKPROCESS Process)
FORCEINLINE PVOID MmCreateHyperspaceMapping(IN PFN_NUMBER Page)
#define PAE_ADDR_TO_PDTE_OFFSET(v)
BOOLEAN NTAPI MmIsDirtyPage(PEPROCESS Process, PVOID Address)
#define PAE_ADDR_TO_PDE(v)
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
__INTRIN_INLINE void __invlpg(void *Address)
__GNU_EXTENSION typedef unsigned __int64 * PULONGLONG
ULONG_PTR NTAPI MiFlushTlbIpiRoutine(ULONG_PTR Address)
#define ADDR_TO_PDE_OFFSET(v)
static ULONGLONG MmGetPageEntryForProcessForPAE(PEPROCESS Process, PVOID Address)
#define PAGE_EXECUTE_READ
#define PAE_ADDR_TO_PDE_OFFSET(v)
#define PAE_PTE_TO_PFN(X)
VOID NTAPI MmSetPageProtect(PEPROCESS Process, PVOID Address, ULONG flProtect)
#define MmSystemRangeStart
base of all file and directory entries
ULONG_PTR NTAPI KeIpiGenericCall(IN PKIPI_BROADCAST_WORKER Function, IN ULONG_PTR Argument)
#define ADDR_TO_PAGE_TABLE(v)
VOID NTAPI KeFlushCurrentTb(VOID)
static ULONGLONG MmGlobalKernelPageDirectoryForPAE[2048]