11.3 The decoders
Each decoder takes the parsed req and fills a flat struct: GUIDs by value, names and data as borrowed (ptr, len) pairs. All return 0, or -1 with errno — EINVAL if the arguments are NULL or the decoder doesn't match req->op_code (so calling the wrong decoder for an op is a clean error), and EBADMSG on a malformed payload. You dispatch on req.op_code and call the matching one.
11.3.0.1 Path and entry operations #
These operate on the name→GUID bindings that make up the key hierarchy. A child is named under a parent GUID, and entries live in layers.
/* LOOKUP — is child_name visible under parent_guid? */
;
int ;
/* CREATE_ENTRY — bind child_name → child_guid in layer_name. */
;
int ;
/* HIDE_ENTRY — tombstone child_name in layer_name. */
;
int ;
/* DELETE_ENTRY — remove child_name's entry in layer_name. */
;
int ;
/* ENUM_CHILDREN — list the children of parent_guid. */
;
int ;
| Op | You must | Reply with |
|---|---|---|
LOOKUP | Resolve child_name under parent_guid across your layers. | rsi_respond_lookup |
CREATE_ENTRY | Bind child_name → child_guid in layer_name at sequence. | status |
HIDE_ENTRY | Place a tombstone for child_name in layer_name. | status |
DELETE_ENTRY | Remove child_name's entry in layer_name. | status |
ENUM_CHILDREN | List every child of parent_guid. | rsi_respond_enum_children |
11.3.0.2 Key operations #
These operate on key metadata records — the non-layered facts about a key (its name, parent, security descriptor, flags).
/* CREATE_KEY — create the metadata record guid under parent_guid. */
;
int ;
/* READ_KEY / DROP_KEY — a request carrying just a key GUID. */
;
int ;
int ;
/* WRITE_KEY — update the mutable fields of guid named by field_mask. */
;
int ;
| Op | You must | Reply with |
|---|---|---|
CREATE_KEY | Store the metadata record for guid (its name, parent, sd, and the volatile_key/symlink flags). | status |
READ_KEY | Return the metadata of guid. | rsi_respond_read_key |
DROP_KEY | Delete the metadata record for guid. | status |
WRITE_KEY | Update only the fields selected in field_mask — the SD when RSI_WRITE_KEY_FIELD_SD is set, the last_write_time when its bit is set — leaving the rest untouched. | status |
WRITE_KEY's field_mask is the important detail: sd is NULL unless the SD bit is set, and last_write_time is meaningful only when the time bit is set, so consult the mask before reading either.
11.3.0.3 Value operations #
These operate on the typed values stored on a key, each written into a layer.
/* QUERY_VALUES — read value_name (or all values when query_all) of guid. */
;
int ;
/* SET_VALUE — store value_name in layer_name with the given type/data. */
;
int ;
/* DELETE_VALUE_ENTRY — remove value_name's entry in layer_name. */
;
int ;
/* SET_BLANKET_TOMBSTONE — set or clear a blanket tombstone on layer_name. */
;
int ;
| Op | You must | Reply with |
|---|---|---|
QUERY_VALUES | Return value_name — or every value when query_all is 1 (then value_name is ignored) — plus any blanket tombstones. | rsi_respond_query_values |
SET_VALUE | Store value_name of value_type in layer_name. Honour expected_sequence as a compare-and-swap guard (0 disables it) — reject with a non-OK status if the current sequence differs. | status |
DELETE_VALUE_ENTRY | Remove value_name's entry in layer_name. | status |
SET_BLANKET_TOMBSTONE | Set (set == 1) or clear a blanket tombstone on layer_name, masking all lower values at once. | status |
11.3.0.4 Transaction operations #
The kernel drives transaction boundaries; your source honours them so a group of writes commits or aborts atomically.
/* BEGIN_TRANSACTION — open transaction_id in mode. */
;
int ;
/* COMMIT_TRANSACTION / ABORT_TRANSACTION — a request carrying just a transaction id. */
;
int ;
int ;
| Op | You must | Reply with |
|---|---|---|
BEGIN_TRANSACTION | Open transaction_id in mode (RSI_TXN_READ_WRITE or RSI_TXN_READ_ONLY); buffer subsequent writes tagged with this id. | status |
COMMIT_TRANSACTION | Atomically apply everything buffered under transaction_id. | status |
ABORT_TRANSACTION | Discard everything buffered under transaction_id. | status |
Requests that belong to a transaction carry its id in req.txn_id; a txn_id of 0 means the request is outside any transaction.
11.3.0.5 Layer operations #
/* DELETE_LAYER / FLUSH — a request carrying just a length-prefixed name. */
;
int ;
int ;
| Op | You must | Reply with |
|---|---|---|
DELETE_LAYER | Remove the entire named layer, reporting the GUIDs of any keys it orphaned. | rsi_respond_delete_layer |
FLUSH | Durably persist pending writes for the named hive, replying only once persistence is confirmed. | status |