ReFS Reference

Schema Table

The Schema Table (roots #3/#9, schema 0xe060) is self-describing: it contains one entry per table type used by the volume. Each entry fixes the key-comparison rules that let the generic B+-tree engine order rows without knowing their meaning.

Key format — 8 bytes

OffsetSizeFieldDescription
0x004Schema ID (u32)Unique schema identifier
0x044Zero padding (u32)Always 0

Value — schema definition (80 bytes, 20 × u32)

Each entry’s value is an 80-byte definition (20 × u32) describing the table’s layout. It is byte-identical across versions for a given schema ID. Notable fields:

FieldByteMeaning
u32[0]+0x00Definition size (0x50)
u32[1]+0x04Key-descriptor size (0x18, constant)
u32[6]+0x18Value-descriptor size (0x38, constant)
u32[7]+0x1CKey-comparison-rules selector (see below)
u32[9]+0x24Self schema ID
u32[18]+0x48System flag (0x01)

The field that fixes “the key-comparison rules” is u32[7] (byte +0x1C) — the key-comparison-rules selector, a small enum (disk-observed 1..0x11 across schemas), not a bitfield. The driver bounds-checks it < 0x15 and uses it to index a key-rules dispatch table. For 0xe040 (Parent-Child Table) it is 8CmsRulesPARENT_CHILD_LINK; for 0xe0c0 (Container Table) it is 10; for 0xe130 (Heat Engine) it is 17. The schema object is registered by RegisterSchema; the rules table is read by GetKeyRulesInternal.

Total schema count

Across all versions, there are 36 distinct schema IDs (18 system + 18 attribute). Any single volume has fewer, since schemas are added and retired across versions.

Entry counts by version

VersionSystem schemasAttribute schemasTotal
v3.4151227
v3.7151530
v3.9161531
v3.10151530
v3.14131629
Insider141630
Upgraded (union)up to 18up to 18up to 36

Totals are the on-disk schema-table leaf-row count (system ID ≥ 0xe000, attribute ID < 0xe000). The pre-3.14 attribute count includes two legacy schemas 0x04 and 0x06 (present on every v3.4–v3.10 volume, retired at v3.14): v3.4 = 0x04,0x06 + 0x110–0x1A0 (10) = 12; v3.7/v3.9/v3.10 = 0x04,0x06 + 13 = 15. Upgraded v3.4→v3.14 volumes keep 0x04/0x06, so a “union” volume can reach 36.

System schemas (18 distinct)

Schema IDNamePurposeVersions Present
0xe010Allocator TableThree-tier allocator (roots 1, 2, 12)v3.4-Insider
0xe030Object ID TableOID-to-LCN mapping (roots 0, 5)v3.4-Insider
0xe040Parent-Child TableDirectory relationships (root 4)v3.4-Insider
0xe050Object Data TableVestigial (legacy)v3.4-v3.9
0xe060Schema TableSelf-describing schemas (roots 3, 9)v3.4-Insider
0xe070Reserved / PlaceholderVestigial (legacy)v3.4-v3.10
0xe080Integrity StatePer-extent integrity tracking (root 11)v3.4-Insider
0xe090Upcase / Logfile InfoUnicode case mapping + MLog metadatav3.4-Insider
0xe0b0Block RefcountShared block reference counts (root 6)v3.4-Insider
0xe0c0Container TableVirtual-to-physical mapping (roots 7, 8)v3.4-Insider
0xe0d0Trash TableAsync deletion queue (OID 0x0D)v3.4-Insider
0xe0e0System Directory Entry ListVestigial (legacy)v3.4-v3.10
0xe0f0System File StreamVestigial (legacy)v3.4-v3.9
0xe100Container IndexContainer lookup by state (root 10)v3.4-Insider
0xe110Read Cache MetadataRead-ahead caching metadatav3.4-Insider
0xe120Candidate Table (Dirty Range)Dirty page tracking for checkpointv3.9-Insider
0xe130Heat EngineBlock tier classification (hot/warm/cold)v3.10-Insider
0xe140Volume Attestation TableTPM-bound attestation dataInsider only

Attribute schemas (18 distinct)

Schema IDEmbedded TypeSinceAttribute / Role
0x1100x10v3.4Directory Entry List
0x1200x20v3.4File Stream
0x1300x30v3.4$FILE_NAME — directory entry, keyed by the full long name (ReFS has no 8.3 short names)
0x1400x40v3.4$FILE_NAME (long-name entries; the largest attribute population)
0x1500x50v3.4$VOLUME_INFORMATION (label, version, flags)
0x1600x60v3.4Reparse Index
0x1700x70v3.4$REPARSE_POINT (per-file reparse data)
0x1800x80v3.4$DATA (file data streams, extent references)
0x1900x90v3.4$STANDARD_INFORMATION
0x1A00xA0v3.4$INDEX_ROOT
0x1B00xB0v3.7$SNAPSHOT (stream snapshot metadata)
0x1C00xC0v3.7$REPARSE_POINT (v3.7+ format)
0x1D00xD0v3.7$EA_INFORMATION
0x1E00xE0v3.14$EA body (WSL $LXUID/$LXGID/$LXMOD/$LXDEV)
0x1F00xF0v3.14$LOGGED_UTILITY_STREAM data
0x2000x100v3.14$LOGGED_UTILITY_STREAM ($EFS metadata, see $EFS)
0x004v3.4-v3.10Legacy fixed-format (descriptor_size=0x50)
0x006v3.4-v3.10Legacy variable-format (anomalous properties)

Naming rule

For attribute schemas: schema ID = embedded type code + 0x100.

Example: embedded code 0x80 ($DATA) yields schema 0x180.

The $FILE_NAME schemas (0x130, 0x140) are retained-numbering entries that carry the directory-entry / long filename. ReFS has no 8.3 short names — there is no separate short-name entry and no short-name field (refs.sys has no 8.3-generation code; all 8dot3/ShortName code lives in fsutil.exe; fsutil file setshortname returns “A local NTFS volume is required”). Directory entries carry only the long name. ReFS also does not duplicate the four MACB timestamps in a name entry the way NTFS does in $FILE_NAME, so the NTFS $SI-vs-$FILE_NAME timestomp cross-check does not exist on ReFS for a single-named file. A hard-linked file is the exception: each name is a separate type-0x30 row carrying its own MACB (value +0x10/+0x18/+0x20/+0x28), so a name-scoped timestomp leaves the sibling names at the true birth — a ReFS-only, journal-independent cross-check (forefst’s HARDLINK_MACB_MISMATCH signal). (The exact embedded-code mapping of 0x130/0x140 — the +0x100 rule vs. the 0x38/0x39 retained-numbering exception — is discussed in the thesis $FILE_NAME section; it is not resolved here.)

Four concepts to keep separate

  1. Attribute name – the Unicode string ($STANDARD_INFORMATION, $DATA)
  2. Definition (Type) code – the in-driver lookup handle (e.g., 0x10 for $SI)
  3. Embedded code – the on-disk key prefix (e.g., 0x90 for $SI)
  4. Schema identifier – the Schema Table key (e.g., 0x190 for $SI)

The Definition code and Embedded code are independent numbering systems. For $DATA they coincide (both 0x80); for $STANDARD_INFORMATION they differ (0x10 vs 0x90).

Schema names

These schema functions are version-independent — the schemas have always had the same function across v3.4 through Insider.

SchemaPrior NameCorrect NameNotes
0x160“Security Descriptor”Reparse IndexInitializeReparseIndexTable creates OIDs 0x540/0x541 with schema 0x160.
0x1B0“Index Root”$SNAPSHOTPDB symbol; introduced at v3.7 with snapshot support.

Schema 0x160 indexes reparse points (symlinks, junctions, WSL device nodes) globally — it has no relationship to security descriptors. The actual security descriptors reside in OID 0x530, which is a schema-less stream-type table (see Security Descriptors).

The 36 distinct schema IDs were named using three sources: PDB symbols for 24, string literals for the attribute names, and structural inference for 4 legacy schemas.

Failover

Root #3 (table ID 0x01) and root #9 (table ID 0x06) form a failover pair.

Cross-references

Evidence

The Schema Table identity (roots #3/#9, table IDs 0x01/0x06, schema 0xe060, virtual addressing) is decompiled from the CmsSchemaTable class and parsed on every analysed image. The key/value layout and the u32[7] key-comparison-rules selector are decompiled from RegisterSchema / GetKeyRulesInternal and corroborated against the driver’s baked-in schema table, which reproduces the disk values exactly. u32[7] is a key-comparison-rules enum (disk-observed 1..0x11), bounds-checked < 0x15 and used to index the key-rules dispatch table. The 36 distinct schema IDs, the per-version entry counts, and the naming corrections (0x160 = Reparse Index, 0x1B0 = $SNAPSHOT) are raw-disk re-measured across the corpus and named from PDB symbols and string literals. The “no 8.3 short names” and “no $SI-vs-$FILE_NAME timestomp cross-check for a single-named file” facts are decompiled; the per-name hard-link exception (each name carries its own MACB, so hard-link names can diverge) is confirmed.