5.3 Records

Payload fields are listed in wire order, immediately after the six-byte framing header, with no padding between them.

5.3.1 HEADER0x01 #

Exactly one, first in the stream. Fixed portion 44 bytes plus the hive name.

SizeFieldDescription
8MagicThe ASCII bytes PEIOSREG50 45 49 4F 53 52 45 47.
4FormatVersionu32.
4MinReaderVersionu32.
8Timestampi64, Unix nanoseconds.
16RootGUIDThe GUID of the key at the root of this backup.
4+nHiveNameThe hive the backup was taken from.

A reader MUST reject a stream whose magic does not match, and MUST reject one whose MinReaderVersion exceeds its own supported version.

HiveName MUST be a valid hive name under the ordinary naming rules.

RootGUID is a stream-local identity for the backup root. On restore it is remapped to the target key (§5.4).

5.3.2 LAYER0x02 #

One per layer name that has layer-tagged data anywhere in the stream. All LAYER records precede all key data.

SizeFieldDescription
4+nNameThe layer name.
4Precedenceu32, as observed at backup time.
1Enabledu8. MUST be 0 or 1.
4+nOwnerBinary SID, as observed at backup time.

A LAYER record is a stream manifest entry, not a backup of the layer's definition. It records what the layer looked like when the backup was taken so that a restore can validate the stream against it, and it creates, updates, deletes, enables, disables and authorises nothing.

A layer's definition is backed up only when its metadata subtree is itself inside the exported subtree, in which case it appears as ordinary KEY, PATH_ENTRY and VALUE records like anything else.

A reader MUST validate that every layer name is valid, that folded layer identities are unique within the manifest, that Enabled is 0 or 1, that Owner parses as a SID, and that every layer name appearing in a PATH_ENTRY, VALUE or BLANKET_TOMBSTONE has exactly one corresponding LAYER record.

5.3.3 KEY0x03 #

One per distinct key object in the subtree, however many layers name it.

SizeFieldDescription
16GUIDThe key's identity. MUST NOT be nil.
4Flagsu32. Bit 0 volatile, bit 1 symlink.
4SDLengthu32.
nSDThe full Security Descriptor.
8LastWriteTimei64, Unix nanoseconds.

Name and parent GUID are absent. They are derivable from the PATH_ENTRY records in the key's own section, and carrying them separately would let a stream contradict itself.

Undefined bits in Flags MUST be zero. A reader MUST reject a record with any bit outside 0x03 set, rather than ignoring it.

SD MUST parse as a Security Descriptor and MUST have an owner.

5.3.4 PATH_ENTRY0x04 #

One per name-to-key mapping per layer.

SizeFieldDescription
16ParentGUIDThe parent key. MUST NOT be nil.
4+nChildNameThe name under that parent.
16ChildGUIDThe key being named, or an all-zero GUID meaning HIDDEN.
4+nLayerNameThe layer this entry belongs to.
8Sequenceu64.

ChildGUID is the only GUID field in the format that may be nil, and a nil one means HIDDEN rather than "no key". No KEY record is emitted for the zero GUID.

5.3.5 VALUE0x05 #

One per value entry per layer, tombstones included.

SizeFieldDescription
16KeyGUIDThe key this value belongs to. MUST NOT be nil.
4+nNameThe value name; empty for the default value.
4Typeu32.
4DataLengthu32.
nDataThe value's bytes.
4+nLayerNameThe layer this entry belongs to.
8Sequenceu64.

Type MUST be one of the defined registry value types, or REG_TOMBSTONE (0xFFFF). A tombstone MUST carry zero-length data.

5.3.6 BLANKET_TOMBSTONE0x06 #

One per blanket tombstone per layer.

SizeFieldDescription
16KeyGUIDThe key this blanket belongs to. MUST NOT be nil.
4+nLayerNameThe layer.
8Sequenceu64.

5.3.7 TRAILER0xFF #

Exactly one, last. Payload 40 bytes, so the whole record is 46.

SizeFieldDescription
8RecordCountu64. Every record in the stream, HEADER and TRAILER included.
32ChecksumSHA-256.

RecordCount MUST be at least 2 — a stream has at minimum a header and a trailer.

5.3.7.1 What the checksum covers #

The checksum is a SHA-256 over the bytes from the start of the HEADER record's framing header through the end of TRAILER.RecordCount, inclusive.

That is: every byte of every preceding record, then the trailer's own six-byte framing header, then the eight bytes of RecordCount. The 32 checksum bytes themselves are not covered, and nothing follows them.

Skipped unknown records are covered, in full, like any other.

A reader MUST verify both RecordCount and Checksum. A stream whose record count does not match, or whose checksum does not verify, MUST be rejected.

Edit this page