MMPTE

The MMPTE structure is everything the Memory Manager puts in any sort of Page Table Entry (PTE). At its essence, a PTE is the processor-defined structure that an operating system must provide in the right way at the right place for the processor to translate a page’s linear address to a physical address. But for managing this translation the Memory Manager also has structures of its own which are more or less compatible with the processor’s. The MMPTE is a container for all of them.

The size of a PTE depends on which translation algorithm is in use. Versions 5.0 to 6.1 of 32-bit Windows each supply separate kernels that use different translation algorithms. One kernel, named NTOSKRNL.EXE or NTKRNLMP.EXE, has the processor translate 32-bit linear addresses to 32-bit physical addresses using 32-bit page table entries. This is all that’s available before version 5.0. This kernel is denoted below as x86. The other build of kernel uses Physical Address Extension (PAE) so that the translation algorithm is of 32-bit linear addresses to a wider physical address space using 64-bit page table entries. This kernel is denoted below as PAE. In the versions that are supplied with both kernels, the PAE kernel is named NTKRNLPA.EXE or NTKRPAMP.EXE. Version 6.2 discontinues the supply of the x86 kernel, such that NTOSKRNL.EXE is in fact a PAE kernel. For 64-bit Windows, the translation is of 48-bit linear addresses to 52-bit physical addresses using 64-bit page table entries. (Note that although Intel provides for 52 bits in a physical address, the Memory Manager’s structures for the translation allow no more than 48.)

Layout

Formally, the MMPTE has one immediate member u which is itself an unnamed union. The first few members ease access to the whole PTE as either one integer or two:

Offset Definition Versions
0x00
ULONG Long;
all (x86)
ULONGLONG Long;
all (PAE and x64)
0x00
ULONG volatile VolatileLong;
6.0 and higher (x86)
ULONGLONG volatile VolatileLong;
6.0 and higher (PAE and x64)
0x00
MMPTE_HIGHLOW HighLow;
all (PAE)

The remaining members of the union are the various types of PTE:

Offset Definition Versions
0x00
MMPTE_HARDWARE Hard;
all
0x00
MMPTE_HARDWARE_LARGEPAGE HardLarge;
late 5.2 to 6.0 (x64)
0x00
HARDWARE_PTE Flush;
3.10 to 4.0
HARDWARE_PTE_X86 Flush;
5.0 to early 5.1 (x86)
HARDWARE_PTE_X86PAE Flush;
5.0 to early 5.1 (PAE)
HARDWARE_PTE Flush;
late 5.1 and higher
0x00
MMPTE_PROTOTYPE Proto;
all
0x00
MMPTE_SOFTWARE Soft;
all
0x00
MMPTE_TIMESTAMP TimeStamp;
late 6.0 and higher
0x00
MMPTE_TRANSITION Trans;
all
0x00
MMPTE_SUBSECTION Subsect;
all
0x00
MMPTE_LIST List;
all

All names and types are from public symbol files for the kernel, starting with Windows 2000 SP3. What Microsoft defined for earlier versions is something of a guess, though the name HARDWARE_PTE for one of the types is well established from debugger extensions that Microsoft included in the Device Driver Kit (DDK) for Windows NT 4.0.

In version 5.0 and in version 5.1 before Windows XP SP1, the HARDWARE_PTE goes by separate names, HARDWARE_PTE_X86PAE and HARDWARE_PTE_X86, for the 32-bit kernels that do and don’t use PAE.

MMPTE_HIGHLOW

For 32-bit Windows with PAE, each PTE is eight bytes but the kernel has only 32-bit registers for working with the bits. The MMPTE_HIGHLOW is then defined as a simple structure for accessing the high and low dwords:

Offset (PAE) Definition Versions
0x00
ULONG LowPart;
all
0x04
ULONG HighPart;
all