MMPFN Union 3

The MMPFN (Memory Manager Page Frame Number) structure is the key to pretty much everything that the Memory Manager knows about a page of physical memory that is in general use. Since an array of these structures for all physical memory needs to be kept in physical memory, the MMPFN is its own substantial overhead. Presumably to keep this down, ever more gets packed in to the MMPFN ever more intricately.

Apparently starting with version 5.0, a u3 member combines 16 bits of flags and a 16-bit reference count. Originally, the e1 and e2 branch each lay out the whole four bytes, the first as bit fields, leaving the reference count as a 16-bit DontUse field, the second as 16-bit integers, collecting the flags as ShortFlags. Version 5.2 from Windows Server 2003 SP1 switched the flags and reference count, and changed many details of the construction.

Offset (x86) Offset (x64) Definition Versions
0x0C (5.0 to 6.3);
0x14
0x18 (late 5.2 to 6.3);
0x20
MMPFNENTRY e1;
5.0 to early 5.2
struct {
    /*  see below: Structure with Entry 1  */
};
late 5.2 and higher
0x0C (5.0 to 6.3);
0x14
0x18 (late 5.2 to 6.3);
0x20
struct {
    /*  see below: Entry 2 Structure  */
} e2;
5.0 and higher
0x0C (6.0) 0x18 (6.0)
struct {
    USHORT ReferenceCount;
    UCHAR ByteFlags;
    UCHAR InterlockedByteFlags;
} e3;
6.0 only
0x14 0x20
struct {
    ULONG EntireField;
} e4;
1607 and higher

The u3 union is almost certainly not original. The only known use that the earliest versions make of this space is for two 16-bit reference counts. The flags were instead in union with the PteFrame, which is here thought to be the origin of the name MMPFNENTRY for the flags as a structure.

Structure with Entry 1

When the version 5.2 from Windows Server 2003 SP1 brought the 16-bit ReferenceCount to the front of u3, the MMPFNENTRY of ULONG bit fields lost its high 16 bits that were labelled as DontUse, and was narrowed to USHORT bit fields. Version 6.0 rearranged further into two sets of UCHAR bit fields, which the 1607 release of Windows 10 formalises as separate structures MMPFNENTRY1 and MMPFNENTRY3.

Offset (x86) Offset (x64) Definition Versions
0x0C (5.0 to 6.3);
0x14
0x18 (late 5.2 to 6.3);
0x20
USHORT ReferenceCount;
late 5.2 and higher
0x0E (5.0 to 6.3);
0x16
0x1A (late 5.2 to 6.3);
0x22
MMPFNENTRY e1;
late 5.2 to 1511
MMPFNENTRY1 e1;
1607 and higher
0x17 0x23
MMPFNENTRY3 e3;
1607 and higher

Entry 2 Structure

The e2 member is in essence a pair of 16-bit integers: the 16 bits of flags that e1 defines as bit fields; and a 16-bit reference count. The order changes and different versions put either or both of the 16-bit integers in union with another that is volatile. Starting with the 1607 release of Windows 10, the flags are lost, which leaves the e2 member as just the ReferenceCount.

Offset (x86) Offset (x64) Definition Versions
0x0C (5.0 to 6.3);
0x14
 
USHORT ShortFlags;
5.0 to early 5.2
USHORT ReferenceCount;
late 5.2 only
union {
    USHORT ReferenceCount;
    SHORT volatile VolatileReferenceCount;
};
6.0 to 6.3
USHORT ReferenceCount;
10.0 and higher
0x0E (5.0 to 6.3);
0x16
 
USHORT ReferenceCount;
5.0 to early 5.2
USHORT ShortFlags;
late 5.2 to 6.1
union {
    USHORT ShortFlags;
    USHORT volatile VolatileShortFlags;
};
6.2 to 1511