MMPFNENTRY

The MMPFNENTRY is a set of bit flags that is thought to exist only in the u3 member of an MMPFN. The 32-bit u3 is in essence 16 bits of flags and a 16-bit reference count, in that order originally, but reversed in the version 5.2 from Windows Server 2003 SP1 and in all versions since. For the original order, the MMPFNENTRY overlays the whole 32 bits of the u3, and the flags are ULONG bit fields with the reference count allowed for at the end as one 16-bit field named DontUse. With the reversal, the MMPFNENTRY is only the 16 bits that follow the reference count: the flags are USHORT bit fields. Version 6.0 reordered the flags into two bytes of UCHAR bit fields. The 1607 release of Windows 10 discontinues the MMPFNENTRY in favour of separating the two bytes of flags into their own structures, named MMPFNENTRY1 and MMPFNENTRY3.

The MMPFNENTRY has so long been a 16-bit set of flags for the MMPFN—even if now defined in 8-bit parts—that one might wonder what ever was so special about these flags that they are collectively any sort of entry. It is here thought that the name MMPFNENTRY originates from the MMPFN keeping a Page Table Entry (PTE) for what the debugger extension command !pfn presents as the “containing page”. Within this PTE, only the page frame number is wanted. The low 12 bits that would otherwise be flags in a “live” PTE are instead available to use as MMPFN flags. When version 4.0 separated these flags from the page frame number, which became its own PteFrame member, the name MMPFNENTRY followed the flags.

It won’t surprise anyone that by version 5.1 the pressure for more flags was eased by yet again using that the PteFrame does not take the whole of its containing dword or qword. New flags then join PteFrame as high bits. Some old flags were moved back.

Original

The MMPFNENTRY starts as a structure of ULONG bit fields. When version 5.2 from Windows Server 2003 SP1 moved the ReferenceCount ahead of the 16 bits of defined flags within the MMPFN, it also formalised that there are only 16 bits of flags: they all become USHORT bit fields.

Mask Definition Versions Remarks
0x00000001 (3.10 to early 5.2);
0x0001 (late 5.2)
ULONG Modified : 1;
3.10 to early 5.2  
USHORT Modified : 1;
late 5.2 only next as 0x10 in first byte
0x00000002 (3.10 to early 5.2);
0x0002 (late 5.2)
ULONG ReadInProgress : 1;
3.10 to early 5.2  
USHORT ReadInProgress : 1;
late 5.2 only next as 0x20 in first byte
0x00000004 (3.10 to early 5.2);
0x0004 (late 5.2)
ULONG WriteInProgress : 1;
3.10 to early 5.2  
USHORT WriteInProgress : 1;
late 5.2 only next as 0x08 in first byte
0x00000008 (3.10 to early 5.2);
0x0008 (late 5.2)
ULONG PrototypePte : 1;
3.10 to early 5.2  
USHORT PrototypePte : 1;
late 5.2 only next in u4 in MMPFN
0x00000070 (3.50 to 5.1);
0x000000F0 (early 5.2);
0x00F0 (late 5.2)
ULONG PageColor : 3;
3.50 to 5.1  
ULONG PageColor : 4;
early 5.2 only  
USHORT PageColor : 4;
late 5.2 only next in u4 in MMPFN
0x00000080 (3.10 to 5.1)
ULONG RemovalRequested : 1;
3.10 to 3.50 later as 0x00002000
ULONG ParityError : 1;
3.51 to 5.1 next as 0x80000000
0x00000700 (3.10 to early 5.2);
0x0700 (late 5.2)
ULONG PageLocation : 3;
3.10 to early 5.2  
USHORT PageLocation : 3;
late 5.2 only next as 0x07 in first byte
0x00000800 (3.10 to 5.0) apparently unused 3.10  
ULONG InPageError : 1;
4.0 to 5.0 next in u4 in MMPFN
0x00001000 (5.0)
ULONG VerifierAllocation : 1;
5.0 only next in u4 in MMPFN
0x00002000 (5.0);
0x00000800 (5.1 to early 5.2);
0x0800 (late 5.2)
ULONG RemovalRequested : 1;
5.0 to early 5.1 previously 0x00000080
USHORT RemovalRequested : 1;
late 5.2 only next as 0x40 in second byte
0x00003000 (5.1 to early 5.2);
0x3000 (late 5.2)
ULONG CacheAttribute : 2;
5.1 to early 5.2  
USHORT CacheAttribute : 2;
late 5.2 only next as 0xC0 in first byte
0x00004000 (5.0 to early 5.2);
0x4000 (late 5.2)
ULONG Reserved : 1;
5.0 only  
ULONG Rom : 1;
5.1 to early 5.2  
USHORT Rom : 1;
late 5.2 only next as 0x08 in second byte
0x00008000 (5.0 to early 5.2);
0x8000 (late 5.2)
ULONG LockCharged : 1;
5.0 to 5.1 next in u4 in MMPFN
USHORT ParityError : 1;
5.2 only previously 0x00000080;
next as 0x80 in second byte
0xFFFFF000 (3.10 to 3.51);
0xFFFF0000 (4.0 to early 5.2)
ULONG PteFrame : 20;
3.10 to 3.51 next as PteFrame in MMPFN
ULONG DontUse : 16;
4.0 to early 5.2  

The multi-bit PageLocation and CacheAttribute take their values from the MMLISTS and MI_PFN_CACHE_ATTRIBUTE enumerations, respectively.

The DontUse member overlays the ReferenceCount in the MMPFN.

Windows Vista and Higher

Version 6.0 rearranged the 16 bits of flags into two sets of eight. The flags become UCHAR bit fields.

Mask Definition Versions Remarks
0x00 / 0x07
UCHAR PageLocation : 3;
6.0 to 1511 previously 0x0700
0x00 / 0x08
UCHAR WriteInProgress : 1;
6.0 to 1511 previously 0x0004
0x00 / 0x10
UCHAR Modified : 1;
6.0 to 1511 previously 0x0001
0x00 / 0x20
UCHAR ReadInProgress : 1;
6.0 to 1511 previously 0x0002
0x00 / 0xC0
UCHAR CacheAttribute : 2;
6.0 to 1511 previously 0x3000
0x01 / 0x07
UCHAR Priority : 3;
6.0 to 1511 previously in u4 in MMPFN
0x01 / 0x08
UCHAR Rom : 1;
6.0 to 6.1 previously 0x4000
UCHAR OnProtectedStandby;
6.2 to 1511  
0x01 / 0x10
UCHAR InPageError : 1;
6.0 to 1511 previously in u4 in MMPFN
0x01 / 0x20
UCHAR KernelStack : 1;
6.0 to 6.1 previously in u4 in MMPFN
UCHAR Spare : 1;
6.2 to 6.3  
UCHAR SystemChargedPage : 1;
10.0 to 1511  
0x01 / 0x40
UCHAR RemovalRequested : 1;
6.0 to 1511 previously 0x0800
0x01 / 0x80
UCHAR ParityError : 1;
6.0 to 1511 previously 0x8000