5.3 Key Operations

5.3.1 RSI_CREATE_KEY #

The request's volatile flag selects the target table (§5.1). For a persistent key:

INSERT INTO keys
    (guid, name, name_folded, parent_guid, sd, volatile, symlink,
     last_write_time)
VALUES (?, ?, fold(?), ?, ?, 0, ?, ?)

last_write_time is not carried in the request. loregd sets it to the current wall-clock time in Unix nanoseconds at insertion.

Uniqueness comes from the target table's primary key on guid, surfaced as RSI_ALREADY_EXISTS. Because that key is per-schema, a GUID already present in the other store does not collide: creating a persistent key whose GUID exists in volatile.keys succeeds, and the GUID then exists in both. Subsequent metadata reads resolve such a GUID to the main row, since the reading query takes the first row of a UNION ALL that puts main first.

The new GUID is added to the hive cache immediately, before the enclosing transaction commits, with an abort hook to remove it if that transaction rolls back (§4.2).

An unresolvable parent GUID returns RSI_NOT_FOUND, after a fallback check of the registered hives' root GUIDs.

5.3.2 RSI_READ_KEY #

SELECT name, parent_guid, sd, volatile, symlink, last_write_time
FROM main.keys WHERE guid = ?
UNION ALL
SELECT name, parent_guid, sd, volatile, symlink, last_write_time
FROM volatile.keys WHERE guid = ?
LIMIT 1

RSI_NOT_FOUND if the GUID is in neither store, and likewise if it resolves to no hive. The volatile field in the response is the stored column value.

5.3.3 RSI_WRITE_KEY #

Updates the two mutable fields of a key, selected by a field mask:

BitValueField
00x01sd
10x02last_write_time

Valid masks are therefore 0x00, 0x01, 0x02 and 0x03. Any other bit set returns RSI_INVALID — it indicates an attempt to modify an immutable field.

loregd builds one UPDATE from the mask, setting only the named fields:

-- mask 0x03
UPDATE keys SET sd = ?, last_write_time = ? WHERE guid = ?

A mask of 0x00 names no fields and acts as an existence check, returning RSI_OK or RSI_NOT_FOUND. An update that matches no row also returns RSI_NOT_FOUND.

Outside a transaction the update is a single auto-committed statement. Inside one it runs on the transaction's connection.

5.3.4 RSI_DROP_KEY #

Purges every trace of a GUID from both stores — four tables in each schema:

DELETE FROM keys               WHERE guid = ?;
DELETE FROM path_entries       WHERE target_guid = ?;
DELETE FROM [values]           WHERE key_guid = ?;
DELETE FROM blanket_tombstones WHERE key_guid = ?;

Outside a transaction, the eight statements are wrapped in a BEGIN IMMEDIATE transaction of their own so the purge is atomic. Inside one, they run on the transaction's connection.

Dropping a GUID that does not exist returns RSI_OK; so does one that resolves to no hive. The operation is idempotent. The GUID is evicted from the hive cache (§4.2).

Edit this page