On this page
- §11.2.1 Reserved and padding fields
- §11.2.2 Variable-size output buffer probes
- §11.2.3 Syscall argument structs
- §11.2.3.1 reg_create_key_args
- §11.2.4 Ioctl argument structs
- §11.2.4.1 reg_query_value_args (REG_IOC_QUERY_VALUE)
- §11.2.4.2 reg_set_value_args (REG_IOC_SET_VALUE)
- §11.2.4.3 reg_delete_value_args (REG_IOC_DELETE_VALUE)
- §11.2.4.4 reg_blanket_tombstone_args (REG_IOC_BLANKET_TOMBSTONE)
- §11.2.4.5 reg_query_values_batch_args (REG_IOC_QUERY_VALUES_BATCH)
- §11.2.4.6 reg_enum_value_args (REG_IOC_ENUM_VALUES)
- §11.2.4.7 reg_enum_subkey_args (REG_IOC_ENUM_SUBKEYS)
- §11.2.4.8 reg_query_key_info_args (REG_IOC_QUERY_KEY_INFO)
- §11.2.4.9 reg_delete_key_args (REG_IOC_DELETE_KEY)
- §11.2.4.10 reg_hide_key_args (REG_IOC_HIDE_KEY)
- §11.2.4.11 reg_get_security_args (REG_IOC_GET_SECURITY)
- §11.2.4.12 reg_set_security_args (REG_IOC_SET_SECURITY)
- §11.2.4.13 reg_notify_args (REG_IOC_NOTIFY)
- §11.2.4.14 reg_backup_args (REG_IOC_BACKUP)
- §11.2.4.15 reg_restore_args (REG_IOC_RESTORE)
- §11.2.4.16 reg_txn_status_args (REG_IOC_TXN_STATUS)
- §11.2.5 Security information flags
- §11.2.6 Watch event structures
- §11.2.6.1 Direct watch event
- §11.2.6.2 Subtree watch event
- §11.2.7 RSI registration struct
- §11.2.7.1 reg_src_register_args (REG_SRC_REGISTER ioctl)
- §11.2.7.2 reg_src_hive_entry
Struct Layouts
Byte-level layouts for all structures crossing the kernel/userspace
boundary. Kernel/userspace syscall and ioctl argument structures use
natural C layout with fixed-width fields and explicit padding fields.
They are not packed with #pragma pack or __attribute__((packed)).
The offsets and totals shown below are normative for the supported
little-endian ABI. GUIDs are 16 bytes, stored as raw bytes (not a
struct of fields).
Variable byte records such as watch events, RSI frames, and backup records are raw offset-defined byte streams rather than C structs. They may be unaligned; consumers parse them using the offsets in this specification.
An independent implementer can write compatible userspace code from this page.
Strings in ioctl structs are length-delimited, not
null-terminated. Each string is referenced by a (len, ptr) pair
where len is the byte count and ptr is a uint64 userspace
address. LCS reads exactly len bytes from ptr. Null terminators
are neither required nor expected.
§11.2.1 Reserved and padding fields
All fields named _pad, reserved, or otherwise described as
reserved are ABI extension points. On every syscall or ioctl input
structure, callers MUST set these fields to zero. LCS MUST reject
the operation with EINVAL if any reserved or padding input field is
non-zero. This validation occurs before source dispatch, transaction
enlistment, sequence allocation, or output copy.
For kernel-produced output structures and watch events, LCS MUST zero every reserved or padding byte before copying data to userspace. Future versions may define semantics for reserved fields; older kernels must not silently accept non-zero values whose meaning they do not understand.
Any flags field in a kernel-facing ABI structure MUST contain only the bits defined for that field. Unknown or reserved flag bits fail with EINVAL unless the field-specific text explicitly defines a different rule.
§11.2.2 Variable-size output buffer probes
Ioctls that return variable-size data use the uniform two-pass ABI
defined in §6.3. A (len = 0, ptr = NULL) output buffer is a valid
probe. A (len = 0, ptr != NULL) output buffer is also treated as a
probe and the pointer is ignored. If len > 0, ptr must be
non-null and writable for len bytes or the ioctl fails with
EFAULT. On ERANGE, required size fields are updated, output buffers
are not partially filled, and output scalar metadata is valid only
when explicitly documented for ERANGE.
§11.2.3 Syscall argument structs
§11.2.3.1 reg_create_key_args
The path and layer fields retain the syscall string convention from §6.2: they are pointers to null-terminated userspace strings, not length-delimited ioctl strings.
| Offset | Size | Field | Description |
|---|---|---|---|
| 0 | 4 | parent_fd | Parent key fd, or -1 for an absolute path. |
| 4 | 4 | _pad0 | Reserved. Must be zero on input. |
| 8 | 8 | path_ptr | Pointer to null-terminated path string. |
| 16 | 4 | desired_access | Requested key access mask. |
| 20 | 4 | flags | REG_OPTION_* create flags. Reserved bits must be zero. |
| 24 | 8 | layer_ptr | Pointer to null-terminated layer name, or null for base. |
| 32 | 4 | txn_fd | Transaction fd (-1 if none). |
| 36 | 4 | _pad1 | Reserved. Must be zero on input. |
| 40 | 8 | disposition_ptr | Optional pointer to uint32 disposition output. |
Total: 48 bytes.
§11.2.4 Ioctl argument structs
§11.2.4.1 reg_query_value_args (REG_IOC_QUERY_VALUE)
| Offset | Size | Field | Description |
|---|---|---|---|
| 0 | 4 | name_len | Length of value name in bytes. |
| 4 | 4 | _pad0 | Reserved. Must be zero on input. |
| 8 | 8 | name_ptr | Pointer to value name (userspace address). |
| 16 | 4 | type | Output: value type (uint32). |
| 20 | 4 | data_len | Input: buffer size. Output: actual data size. |
| 24 | 4 | txn_fd | Transaction fd (-1 if none). |
| 28 | 4 | layer_buf_len | Input: buffer size for layer name. |
| 32 | 8 | data_ptr | Pointer to data buffer (userspace address). |
| 40 | 8 | sequence | Output: sequence number of the effective entry. Used as expected_sequence in conditional writes to the same layer. |
| 48 | 4 | layer_len | Output: length of effective layer name. |
| 52 | 4 | _pad1 | Reserved. Must be zero on input. |
| 56 | 8 | layer_ptr | Input: pointer to buffer for layer name. |
Total: 64 bytes.
If data_len on input is too small, the ioctl returns ERANGE and sets data_len to the required size. If the layer-name buffer is too small, layer_len is set to the required size. If both are too small, both required sizes are reported. The caller retries with larger buffers.
§11.2.4.2 reg_set_value_args (REG_IOC_SET_VALUE)
| Offset | Size | Field | Description |
|---|---|---|---|
| 0 | 4 | name_len | Length of value name in bytes. |
| 4 | 4 | _pad0 | Reserved. Must be zero on input. |
| 8 | 8 | name_ptr | Pointer to value name. |
| 16 | 4 | type | Value type (uint32). REG_TOMBSTONE for tombstones. |
| 20 | 4 | data_len | Length of data in bytes. |
| 24 | 8 | data_ptr | Pointer to data. |
| 32 | 4 | layer_len | Length of layer name (0 for base layer). |
| 36 | 4 | _pad1 | Reserved. Must be zero on input. |
| 40 | 8 | layer_ptr | Pointer to layer name (null for base layer). |
| 48 | 4 | txn_fd | Transaction fd (-1 if none). |
| 52 | 4 | _pad2 | Reserved. Must be zero on input. |
| 56 | 8 | expected_seq | Expected sequence for CAS (0 to disable). |
Total: 64 bytes.
§11.2.4.3 reg_delete_value_args (REG_IOC_DELETE_VALUE)
| Offset | Size | Field | Description |
|---|---|---|---|
| 0 | 4 | name_len | Length of value name in bytes. |
| 4 | 4 | _pad0 | Reserved. Must be zero on input. |
| 8 | 8 | name_ptr | Pointer to value name. |
| 16 | 4 | layer_len | Length of layer name. |
| 20 | 4 | _pad1 | Reserved. Must be zero on input. |
| 24 | 8 | layer_ptr | Pointer to layer name. |
| 32 | 4 | txn_fd | Transaction fd (-1 if none). |
| 36 | 4 | _pad2 | Reserved. Must be zero on input. |
Total: 40 bytes.
§11.2.4.4 reg_blanket_tombstone_args (REG_IOC_BLANKET_TOMBSTONE)
| Offset | Size | Field | Description |
|---|---|---|---|
| 0 | 4 | layer_len | Length of layer name. |
| 4 | 4 | _pad0 | Reserved. Must be zero on input. |
| 8 | 8 | layer_ptr | Pointer to layer name. |
| 16 | 1 | set | 1 to write blanket, 0 to remove. |
| 17 | 3 | _pad1 | Reserved. Must be zero on input. |
| 20 | 4 | txn_fd | Transaction fd (-1 if none). |
Total: 24 bytes.
§11.2.4.5 reg_query_values_batch_args (REG_IOC_QUERY_VALUES_BATCH)
| Offset | Size | Field | Description |
|---|---|---|---|
| 0 | 4 | buf_len | Input: buffer size. Output: bytes written. |
| 4 | 4 | count | Output: number of values returned. |
| 8 | 8 | buf_ptr | Pointer to output buffer. |
| 16 | 4 | txn_fd | Transaction fd (-1 if none). |
| 20 | 4 | _pad | Reserved. Must be zero on input. |
Total: 24 bytes.
Each value in the buffer is packed as:
| Offset | Size | Field |
|---|---|---|
| 0 | 4 | name_len |
| 4 | name_len | name (UTF-8) |
| 4+name_len | 4 | type |
| 8+name_len | 4 | data_len |
| 12+name_len | data_len | data |
Values are packed consecutively with no padding between them. If the buffer is too small, the ioctl returns ERANGE and sets buf_len to the required size.
§11.2.4.6 reg_enum_value_args (REG_IOC_ENUM_VALUES)
| Offset | Size | Field | Description |
|---|---|---|---|
| 0 | 4 | index | Value index (0-based). |
| 4 | 4 | name_len | Input: buffer size. Output: actual name length. |
| 8 | 8 | name_ptr | Pointer to name buffer. |
| 16 | 4 | type | Output: value type. |
| 20 | 4 | data_len | Input: buffer size. Output: actual data size. |
| 24 | 8 | data_ptr | Pointer to data buffer. |
| 32 | 4 | txn_fd | Transaction fd (-1 if none). |
| 36 | 4 | _pad | Reserved. Must be zero on input. |
Total: 40 bytes.
§11.2.4.7 reg_enum_subkey_args (REG_IOC_ENUM_SUBKEYS)
| Offset | Size | Field | Description |
|---|---|---|---|
| 0 | 4 | index | Subkey index (0-based). |
| 4 | 4 | name_len | Input: buffer size. Output: actual name length. |
| 8 | 8 | name_ptr | Pointer to name buffer. |
| 16 | 8 | last_write_time | Output: last modification (Unix ns). |
| 24 | 4 | subkey_count | Output: number of child keys. |
| 28 | 4 | value_count | Output: number of values. |
| 32 | 4 | txn_fd | Transaction fd (-1 if none). |
| 36 | 4 | _pad | Reserved. Must be zero on input. |
Total: 40 bytes.
§11.2.4.8 reg_query_key_info_args (REG_IOC_QUERY_KEY_INFO)
| Offset | Size | Field | Description |
|---|---|---|---|
| 0 | 4 | name_len | Input: buffer size. Output: actual name length. |
| 4 | 4 | _pad0 | Reserved. Must be zero on input. |
| 8 | 8 | name_ptr | Pointer to name buffer. |
| 16 | 8 | last_write_time | Output: Unix nanoseconds. |
| 24 | 4 | subkey_count | Output. |
| 28 | 4 | value_count | Output. |
| 32 | 4 | max_subkey_name_len | Output: bytes. |
| 36 | 4 | max_value_name_len | Output: bytes. |
| 40 | 4 | max_value_data_size | Output: bytes. |
| 44 | 4 | sd_size | Output: bytes. |
| 48 | 1 | volatile_key | Output: 1 if volatile. |
| 49 | 1 | symlink | Output: 1 if symlink. |
| 50 | 6 | _pad1 | Reserved. Zeroed by LCS on output. |
| 56 | 8 | hive_generation | Output: volatile LCS-owned per-hive change epoch. |
Total: 64 bytes.
§11.2.4.9 reg_delete_key_args (REG_IOC_DELETE_KEY)
| Offset | Size | Field | Description |
|---|---|---|---|
| 0 | 4 | layer_len | Length of layer name. |
| 4 | 4 | _pad0 | Reserved. Must be zero on input. |
| 8 | 8 | layer_ptr | Pointer to layer name. |
| 16 | 4 | txn_fd | Transaction fd (-1 if none). |
| 20 | 4 | _pad1 | Reserved. Must be zero on input. |
Total: 24 bytes.
§11.2.4.10 reg_hide_key_args (REG_IOC_HIDE_KEY)
| Offset | Size | Field | Description |
|---|---|---|---|
| 0 | 4 | layer_len | Length of layer name. |
| 4 | 4 | _pad0 | Reserved. Must be zero on input. |
| 8 | 8 | layer_ptr | Pointer to layer name. |
| 16 | 4 | txn_fd | Transaction fd (-1 if none). |
| 20 | 4 | _pad1 | Reserved. Must be zero on input. |
Total: 24 bytes.
§11.2.4.11 reg_get_security_args (REG_IOC_GET_SECURITY)
| Offset | Size | Field | Description |
|---|---|---|---|
| 0 | 4 | security_info | Flags: which SD components to return. |
| 4 | 4 | sd_len | Input: buffer size. Output: actual SD size. |
| 8 | 8 | sd_ptr | Pointer to SD buffer. |
Total: 16 bytes.
§11.2.4.12 reg_set_security_args (REG_IOC_SET_SECURITY)
| Offset | Size | Field | Description |
|---|---|---|---|
| 0 | 4 | security_info | Flags: which components to set. |
| 4 | 4 | sd_len | Length of SD data. |
| 8 | 8 | sd_ptr | Pointer to SD data in KACS binary format. |
| 16 | 4 | txn_fd | Transaction fd (-1 if none). |
| 20 | 4 | _pad | Reserved. Must be zero on input. |
Total: 24 bytes.
§11.2.4.13 reg_notify_args (REG_IOC_NOTIFY)
| Offset | Size | Field | Description |
|---|---|---|---|
| 0 | 4 | filter | Bitmask: REG_NOTIFY_VALUE, _SUBKEY, _SD. |
| 4 | 1 | subtree | 1 for subtree watch, 0 for direct. |
| 5 | 3 | _pad | Reserved. Must be zero on input. |
Total: 8 bytes.
§11.2.4.14 reg_backup_args (REG_IOC_BACKUP)
| Offset | Size | Field | Description |
|---|---|---|---|
| 0 | 4 | output_fd | Writable fd to write backup stream to. |
Total: 4 bytes.
§11.2.4.15 reg_restore_args (REG_IOC_RESTORE)
| Offset | Size | Field | Description |
|---|---|---|---|
| 0 | 4 | input_fd | Readable fd to read backup stream from. |
Total: 4 bytes.
§11.2.4.16 reg_txn_status_args (REG_IOC_TXN_STATUS)
| Offset | Size | Field | Description |
|---|---|---|---|
| 0 | 4 | state | Output: REG_TXN_* state code. |
| 4 | 4 | terminal_errno | Output: errno associated with terminal state, or 0 while active. |
Total: 8 bytes.
§11.2.5 Security information flags
Used in reg_get_security_args and reg_set_security_args:
| Flag | Value | Description |
|---|---|---|
| OWNER_SECURITY_INFORMATION | 0x01 | Owner SID. |
| GROUP_SECURITY_INFORMATION | 0x02 | Group SID. |
| DACL_SECURITY_INFORMATION | 0x04 | Discretionary ACL. |
| SACL_SECURITY_INFORMATION | 0x08 | System ACL. |
security_info values passed to REG_IOC_GET_SECURITY and REG_IOC_SET_SECURITY MUST be non-zero subsets of these four flags. Unknown bits fail with EINVAL.
§11.2.6 Watch event structures
§11.2.6.1 Direct watch event
| Offset | Size | Field | Description |
|---|---|---|---|
| 0 | 4 | total_len | Total event size in bytes. |
| 4 | 2 | event_type | Event type code. |
| 6 | 2 | name_len | Length of name in bytes (0 for no-name events). |
| 8 | name_len | name | Changed entity name (UTF-8). |
Minimum size: 8 bytes (no name).
§11.2.6.2 Subtree watch event
Extends the direct event with path components:
| Offset | Size | Field | Description |
|---|---|---|---|
| 0 | 4 | total_len | Total event size. |
| 4 | 2 | event_type | Event type code. |
| 6 | 2 | name_len | Length of name. |
| 8 | name_len | name | Changed entity name. |
| 8+name_len | 2 | path_depth | Components from watched key to changed key. |
| 10+name_len | variable | path_components | Sequence of (len:uint16, UTF-8 bytes). |
path_depth of 0 means the change is on the watched key itself (equivalent to a direct event). Consumers distinguish direct from subtree events by checking whether bytes remain after the name field (using total_len).
§11.2.7 RSI registration struct
§11.2.7.1 reg_src_register_args (REG_SRC_REGISTER ioctl)
| Offset | Size | Field | Description |
|---|---|---|---|
| 0 | 4 | hive_count | Number of hives to register. |
| 4 | 4 | _pad | Reserved. Must be zero on input. |
| 8 | 8 | max_sequence | Highest persisted sequence number. |
| 16 | 8 | hives_ptr | Pointer to array of reg_src_hive_entry. |
Total: 24 bytes.
§11.2.7.2 reg_src_hive_entry
| Offset | Size | Field | Description |
|---|---|---|---|
| 0 | 4 | name_len | Length of hive name. |
| 4 | 4 | _pad0 | Reserved. Must be zero on input. |
| 8 | 8 | name_ptr | Pointer to hive name string. |
| 16 | 16 | root_guid | Root key GUID. |
| 32 | 4 | flags | RSI_HIVE_PRIVATE (0x01) if private. Unknown bits fail with EINVAL. |
| 36 | 4 | _pad1 | Reserved. Must be zero on input. |
| 40 | 16 | scope_guid | Scope GUID (only if PRIVATE flag set, zeroed otherwise). Must be all-zero unless RSI_HIVE_PRIVATE is set. |
Total: 56 bytes per entry.