3.2 Persistent Tables
Each hive is one SQLite database, and every hive database has the same four data tables. loregd creates them on first boot (§2.2, step 4).
The tables hold what the kernel gives loregd and nothing derived from it. Security descriptors are stored as opaque blobs, GUIDs and sequence numbers are assigned by the kernel, and no table records a resolved or filtered view of anything.
3.2.1 keys #
(
guid BLOB NOT NULL PRIMARY KEY,
name TEXT NOT NULL,
name_folded TEXT NOT NULL,
parent_guid BLOB,
sd BLOB NOT NULL,
volatile INTEGER NOT NULL DEFAULT 0,
symlink INTEGER NOT NULL DEFAULT 0,
last_write_time INTEGER NOT NULL
);
| Column | Meaning |
|---|---|
guid | The 16-byte key GUID assigned by the kernel. Primary key. |
name | The key's own name component, with case preserved as written. |
name_folded | The folded form of name (§3.4), used for case-insensitive lookup. |
parent_guid | The parent key's GUID; null for the hive root, which is how the root is identified. |
sd | The security descriptor, in binary self-relative form. Opaque to loregd. |
volatile | 1 for a volatile key, 0 for a persistent one. In this table it is always 0 — volatile keys live in the volatile database (§3.3). |
symlink | 1 if the key is a symbolic link. |
last_write_time | Unix nanoseconds. |
3.2.2 path_entries #
(
parent_guid BLOB NOT NULL,
child_name TEXT NOT NULL,
child_name_folded TEXT NOT NULL,
layer TEXT NOT NULL,
target_type INTEGER NOT NULL,
target_guid BLOB,
sequence INTEGER NOT NULL,
PRIMARY KEY (parent_guid, child_name_folded, layer)
);
ON path_entries (target_guid)
WHERE target_type = 0;
A path entry is one layer's opinion about one child name under one parent. Several layers may hold entries for the same name; resolving between them is the kernel's job, not loregd's.
The partial index on target_guid covers only non-HIDDEN rows.
It is what
makes the reverse lookup — which path entries point at this key — cheap,
and that reverse lookup is what orphan detection (§2.2, step 6) and
RSI_DROP_KEY need.
3.2.3 values #
[values] (
key_guid BLOB NOT NULL,
name TEXT NOT NULL,
name_folded TEXT NOT NULL,
layer TEXT NOT NULL,
type INTEGER NOT NULL,
data BLOB,
sequence INTEGER NOT NULL,
PRIMARY KEY (key_guid, name_folded, layer)
);
values is a reserved word in SQL, so every reference to this table is
quoted — [values], or main.[values] and volatile.[values] when the
schema is named explicitly. Unquoted, it is a syntax error.
3.2.4 blanket_tombstones #
(
key_guid BLOB NOT NULL,
layer TEXT NOT NULL,
sequence INTEGER NOT NULL,
PRIMARY KEY (key_guid, layer)
);
A blanket tombstone hides every value a key holds in the layers beneath
it, rather than naming one value the way a REG_TOMBSTONE entry does.
One row per key per layer.