On this page
- §11.3.1 Common header
- §11.3.2 Variable-length encoding
- §11.3.3 Path operations
- §11.3.3.1 RSI_LOOKUP (0x01)
- §11.3.3.2 RSI_CREATE_ENTRY (0x02)
- §11.3.3.3 RSI_HIDE_ENTRY (0x03)
- §11.3.3.4 RSI_DELETE_ENTRY (0x04)
- §11.3.3.5 RSI_ENUM_CHILDREN (0x05)
- §11.3.4 Key operations
- §11.3.4.1 RSI_CREATE_KEY (0x10)
- §11.3.4.2 RSI_READ_KEY (0x11)
- §11.3.4.3 RSI_WRITE_KEY (0x12)
- §11.3.4.4 RSI_DROP_KEY (0x13)
- §11.3.5 Value operations
- §11.3.5.1 RSI_QUERY_VALUES (0x20)
- §11.3.5.2 RSI_SET_VALUE (0x21)
- §11.3.5.3 RSI_DELETE_VALUE_ENTRY (0x22)
- §11.3.5.4 RSI_SET_BLANKET_TOMBSTONE (0x23)
- §11.3.6 Transaction operations
- §11.3.6.1 RSI_BEGIN_TRANSACTION (0x30)
- §11.3.6.2 RSI_COMMIT_TRANSACTION (0x31)
- §11.3.6.3 RSI_ABORT_TRANSACTION (0x32)
- §11.3.7 Layer operations
- §11.3.7.1 RSI_DELETE_LAYER (0x50)
- §11.3.8 Maintenance operations
- §11.3.8.1 RSI_FLUSH (0x40)
RSI Wire Format
Byte-level layouts for all RSI messages over /dev/pkm_registry.
All multi-byte integers are little-endian. Strings are UTF-8,
length-prefixed with uint32. GUIDs are 16 bytes.
§11.3.1 Common header
Every request begins with:
| Offset | Size | Field |
|---|---|---|
| 0 | 4 | total_len |
| 4 | 8 | request_id |
| 12 | 2 | op_code |
| 14 | 8 | txn_id (0 = no transaction) |
Total request header: 22 bytes. Payload follows immediately.
Response messages begin with:
| Offset | Size | Field |
|---|---|---|
| 0 | 4 | total_len |
| 4 | 8 | request_id |
| 12 | 2 | op_code (high bit set: op_code | 0x8000) |
Total response header: 14 bytes. Payload follows (status + data).
Every response payload begins with:
| Offset | Size | Field |
|---|---|---|
| 0 | 4 | status |
Status 0 = success. Non-zero = RSI error code.
§11.3.2 Variable-length encoding
Strings and byte arrays are encoded as:
┌──────────────┬───────────────────┐
│ len (uint32) │ data (len bytes) │
└──────────────┴───────────────────┘
Arrays of structs are encoded as:
┌───────────────┬─────────┬─────────┬─────┐
│ count (uint32)│ entry_0 │ entry_1 │ ... │
└───────────────┴─────────┴─────────┴─────┘
§11.3.3 Path operations
§11.3.3.1 RSI_LOOKUP (0x01)
Request payload:
| Offset | Size | Field |
|---|---|---|
| 0 | 16 | parent_guid |
| 16 | 4+N | child_name (length-prefixed string) |
Response payload (success):
| Offset | Size | Field |
|---|---|---|
| 0 | 4 | status |
| 4 | 4 | entry_count |
Followed by entry_count path entries:
| Size | Field |
|---|---|
| 4+N | layer_name (length-prefixed) |
| 1 | target_type (0 = GUID, 1 = HIDDEN) |
| 16 | target_guid (zeroed if HIDDEN) |
| 8 | sequence |
Followed by key metadata for each unique GUID:
| Offset | Size | Field |
|---|---|---|
| 0 | 4 | metadata_count |
Per metadata entry:
| Size | Field |
|---|---|
| 16 | guid |
| 4+N | sd (length-prefixed bytes) |
| 1 | volatile |
| 1 | symlink |
| 8 | last_write_time |
HIDDEN entries (target_type=1, zero GUID) do not contribute metadata entries. The metadata_count reflects only unique non-zero GUIDs.
When the symlink flag is set, LCS resolves the target by issuing a separate RSI_QUERY_VALUES for the key's default value.
§11.3.3.2 RSI_CREATE_ENTRY (0x02)
Request payload:
| Size | Field |
|---|---|
| 16 | parent_guid |
| 4+N | child_name |
| 4+N | layer_name |
| 16 | child_guid |
| 8 | sequence |
Response: status only.
§11.3.3.3 RSI_HIDE_ENTRY (0x03)
Request payload:
| Size | Field |
|---|---|
| 16 | parent_guid |
| 4+N | child_name |
| 4+N | layer_name |
| 8 | sequence |
Response: status only.
§11.3.3.4 RSI_DELETE_ENTRY (0x04)
Request payload:
| Size | Field |
|---|---|
| 16 | parent_guid |
| 4+N | child_name |
| 4+N | layer_name |
Response: status only.
§11.3.3.5 RSI_ENUM_CHILDREN (0x05)
Request payload:
| Size | Field |
|---|---|
| 16 | parent_guid |
Response: Same format as RSI_LOOKUP but with multiple child names. Encoded as:
| Size | Field |
|---|---|
| 4 | status |
| 4 | child_count |
Per child:
| Size | Field |
|---|---|
| 4+N | child_name |
| 4 | entry_count |
Per entry within child (same as LOOKUP entries):
| Size | Field |
|---|---|
| 4+N | layer_name |
| 1 | target_type |
| 16 | target_guid |
| 8 | sequence |
Followed by key metadata block (same as LOOKUP).
§11.3.4 Key operations
§11.3.4.1 RSI_CREATE_KEY (0x10)
Request payload:
| Size | Field |
|---|---|
| 16 | guid |
| 4+N | name |
| 16 | parent_guid |
| 4+N | sd (length-prefixed bytes) |
| 1 | volatile |
| 1 | symlink |
Response: status only.
§11.3.4.2 RSI_READ_KEY (0x11)
Request payload:
| Size | Field |
|---|---|
| 16 | guid |
Response payload (success):
| Size | Field |
|---|---|
| 4 | status |
| 4+N | name |
| 16 | parent_guid |
| 4+N | sd |
| 1 | volatile |
| 1 | symlink |
| 8 | last_write_time |
§11.3.4.3 RSI_WRITE_KEY (0x12)
Request payload:
| Size | Field |
|---|---|
| 16 | guid |
| 4 | field_mask |
| (conditional) | fields per mask |
Field mask bits:
| Bit | Field | Size |
|---|---|---|
| 0 | sd | 4+N (length-prefixed) |
| 1 | last_write_time | 8 |
Only fields with their mask bit set are present in the payload, in bit order.
Response: status only.
§11.3.4.4 RSI_DROP_KEY (0x13)
Request payload:
| Size | Field |
|---|---|
| 16 | guid |
Response: status only.
§11.3.5 Value operations
§11.3.5.1 RSI_QUERY_VALUES (0x20)
Request payload:
| Size | Field |
|---|---|
| 16 | guid |
| 4+N | value_name (empty + flag for query-all) |
| 1 | query_all (1 = return all values for key) |
Response payload (success):
| Size | Field |
|---|---|
| 4 | status |
| 4 | entry_count |
Per entry:
| Size | Field |
|---|---|
| 4+N | value_name |
| 4+N | layer_name |
| 4 | type |
| 4+N | data (length-prefixed) |
| 8 | sequence |
Followed by blanket tombstone data:
| Size | Field |
|---|---|
| 4 | blanket_count |
Per blanket:
| Size | Field |
|---|---|
| 4+N | layer_name |
| 8 | sequence |
§11.3.5.2 RSI_SET_VALUE (0x21)
Request payload:
| Size | Field |
|---|---|
| 16 | guid |
| 4+N | value_name |
| 4+N | layer_name |
| 4 | type |
| 4+N | data |
| 8 | sequence |
| 8 | expected_sequence (0 = no CAS) |
Response: status only (RSI_CAS_FAILED if condition fails).
§11.3.5.3 RSI_DELETE_VALUE_ENTRY (0x22)
Request payload:
| Size | Field |
|---|---|
| 16 | guid |
| 4+N | value_name |
| 4+N | layer_name |
Response: status only.
§11.3.5.4 RSI_SET_BLANKET_TOMBSTONE (0x23)
Request payload:
| Size | Field |
|---|---|
| 16 | guid |
| 4+N | layer_name |
| 1 | set (1 = write, 0 = remove) |
| 8 | sequence |
Response: status only.
§11.3.6 Transaction operations
§11.3.6.1 RSI_BEGIN_TRANSACTION (0x30)
Request payload:
| Size | Field |
|---|---|
| 8 | txn_id |
Response: status only.
§11.3.6.2 RSI_COMMIT_TRANSACTION (0x31)
Request payload:
| Size | Field |
|---|---|
| 8 | txn_id |
Response: status only.
§11.3.6.3 RSI_ABORT_TRANSACTION (0x32)
Request payload:
| Size | Field |
|---|---|
| 8 | txn_id |
Response: status only.
§11.3.7 Layer operations
§11.3.7.1 RSI_DELETE_LAYER (0x50)
Request payload:
| Size | Field |
|---|---|
| 4+N | layer_name |
Response payload (success):
| Size | Field |
|---|---|
| 4 | status |
| 4 | orphaned_guid_count |
Per orphaned GUID:
| Size | Field |
|---|---|
| 16 | guid |
§11.3.8 Maintenance operations
§11.3.8.1 RSI_FLUSH (0x40)
Request payload:
| Size | Field |
|---|---|
| 4+N | hive_name (length-prefixed string) |
The hive name identifies which hive to flush. This is the only RSI operation that routes by hive name rather than key GUID, because flush is a hive-level operation (WAL checkpoint), not a key-level one.
Response: status only.