Registry
What is it?
The Registry is Impossible OS's hierarchical, typed key/value configuration store, the kernel-resident equivalent of Windows' HKEY_LOCAL_MACHINE tree. It gives every subsystem, from boot device discovery to NLS locale policy, one place to persist settings as reg_key_t nodes carrying reg_value_t entries (REG_SZ, REG_DWORD, REG_BINARY, and the rest of the standard type set), backed by an on-disk hive format with a write-ahead journal. The core engine (src/kernel/registry.c, 4293 lines) implements the full Win32 RegXxx surface, access-right enforcement, a change-notification engine, and 20 NT syscalls; what remains open is mostly user-mode exposure (advapi32, regedit), SMP locking, and a set of exclusive features (transactions, snapshots, schema validation) that go beyond what either Windows or Linux ships.
How does it work?
Every key lives in a static pool (reg_key_t / reg_value_t), addressed by an FNV-1a hash and a parent/child linked structure; a 32-entry LRU cache (reg_kcb_cache, registry.c) shortcuts repeated (parent, name) resolutions. All five root keys (HKLM, HKCU, HKCR, HKU, HKCC) exist, and the internal path walker (reg_walk_path()) follows REG_LINK keys transparently. Every public entry point (RegOpenKeyEx, RegCreateKeyEx, RegSetValueEx, and so on) funnels through reg_check_access(), which checks the caller's granted access mask against the key's KEY_* rights; the underlying SeAccessCheck DACL walk is not implemented yet (see below), so reg_check_access() currently enforces only the mask recorded on the open handle, not the security descriptor.
On disk, a hive is a flat file plus a .hive.log write-ahead journal: hive_save()/hive_load() serialize the tree, and on mount hive_best_source() replays a fully valid journal over the main hive, so a crash mid-write normally leaves a recoverable hive. The replay does not check that its copy succeeded before invalidating the journal, so a failed recovery write can lose the journal. RegCopyTree() and RegRenameKey() provide recursive subtree copy and in-place rename (not copy-plus-delete). A change-notification engine (reg_watcher_pool, 64 static slots) lets kernel-internal callers register on REG_NOTIFY_CHANGE_NAME/ATTRIBUTES/LAST_SET/SECURITY; reg_dispatch_notify() walks a mutated key up its parent chain, firing subtree watchers once per ancestor, and every tombstone path (RegDeleteKey, reg_delete_subtree, RegUnloadHive) unregisters its watchers so a freed slot never stays linked. The Win32-facing RegNotifyChangeKeyValue (event-based, asynchronous) is not wired to this engine yet.
The NT syscall surface in src/kernel/nt/nt_registry.c wires 20 handlers to the SSDT: NtCreateKey, NtOpenKey(Ex), NtDeleteKey, NtSetValueKey, NtQueryValueKey, NtDeleteValueKey, NtEnumerateKey, NtEnumerateValueKey, NtQueryKey, NtFlushKey, NtNotifyChangeKey, NtRenameKey, NtSaveKey(Ex), NtRestoreKey, NtLoadKey(Ex), NtUnloadKey(Ex). NtNotifyChangeKey is a real syscall slot but its handler unconditionally returns STATUS_NOT_IMPLEMENTED; it is waiting on the same event-based wiring as the Win32 entry point. HKEY values returned to user mode are still raw pointers into a 128-entry handle pool rather than Object Manager handles, so NtClose cannot release them today.
flowchart LR
Win32["RegXxx (Win32)"] --> Core["registry.c<br/>reg_check_access, tree, KCB cache"]
NT["NtCreateKey / NtSetValueKey / ..."] --> Core
Core --> Hive["hive_save / hive_load<br/>+ .hive.log WAJ"]
Core --> Notify["reg_dispatch_notify<br/>64-slot watcher pool"]
What are its interfaces?
| Interface | Purpose |
|---|---|
RegOpenKeyEx(), RegCreateKeyEx(), RegCloseKey(), RegDeleteKey(), RegDeleteTree() |
Core key lifecycle (registry.h) |
RegSetValueEx(), RegQueryValueEx(), RegGetValue(), RegDeleteValue(), RegEnumValue() |
Value read/write |
RegEnumKeyEx(), RegQueryInfoKey() |
Enumeration and metadata (FILETIME LastWriteTime) |
RegCopyTree(), RegRenameKey() |
Recursive subtree copy and in-place rename |
RegFlushKey() |
Immediate single-hive save |
reg_notify_register(), RegUnregisterNotify() |
Kernel-internal change-notification callbacks |
reg_check_access() |
The per-operation KEY_* access-mask chokepoint |
NtCreateKey, NtOpenKey, NtSetValueKey, NtQueryValueKey, NtEnumerateKey, NtQueryKey, NtFlushKey |
NT syscalls wired to the SSDT (nt_registry.c) |
NtSaveKey, NtRestoreKey, NtLoadKey, NtUnloadKey, NtRenameKey |
Hive-level NT syscalls |
NtNotifyChangeKey |
Wired SSDT slot, returns STATUS_NOT_IMPLEMENTED |
How do I use it?
The registry starts on every boot; the engine mounts and populates defaults automatically, with no setting to disable it.
bash scripts/test.sh SUITE=abi # or: make test-abi
Kernel code reads and writes through the RegXxx functions directly (RegGetDword, RegSetString, RegReadKeyValue are one-shot convenience wrappers); user-mode code goes through the NT syscalls once a process has a valid HKEY. %VAR% expansion for boot-path values uses reg_lookup_env_var()/reg_expand_sz(). The suite in test_registry.c covers access rights, RegCopyTree/RegRenameKey, volatile keys, the KCB cache, and the notification engine.
What is not implemented yet?
SeAccessCheck(the DACL walk itself) is not built, soreg_check_access()enforces only the handle's granted mask, not the key's security descriptor; see the Security Reference Monitor (SeAccessCheck Engine).- Registry-wide SMP locking does not exist:
registry.cstill assumes single-threaded access even though NT syscalls expose it to concurrent user-mode tasks (Registry SMP Synchronization). NtNotifyChangeKeyand the Win32RegNotifyChangeKeyValueevent path are unimplemented stubs; only the kernel-internal callback engine works today (Change Notifications).HKEYvalues are raw pointers into a 128-entry pool, not Object Manager handles, so a long-running process leakingHKEYs cannot be closed viaNtClose(Nt/Zw Registry Syscalls).RegSaveKey/RegRestoreKeyand their NT equivalents have their privilege gates wired but returnERROR_NOT_SUPPORTED/no hive I/O body (Advanced Key Operations).advapi32.dllA/W export shims, the mergedHKCRview,.regimport/export, and theregeditshell tool do not exist (advapi32.dll Win32 Compatibility).- Registry virtualization (
VirtualStoreredirect for low-IL writes) is not built (Registry Virtualization & .reg Import/Export). - Transactions, the pattern-search API, snapshot/diff, schema validation, dual-log WAJ failover, incremental delta flush, and hive compaction are all deferred, exclusive-feature work (Transactions, Search API & Snapshot/Diff, Advanced Hive Features).
- Value name/data limits are still 255 chars / 512 bytes, short of the 16383-char / 1 MiB Windows 11 limits, pending a heap-backed migration of five fixed stack buffers (Registry Value Size Expansion).
How does it compare with Windows 11 and Linux?
Windows 11's registry is the direct model: a hierarchical typed store, .LOG1/.LOG2 crash-safe journaling, RegNotifyChangeKeyValue, and a full NT syscall surface with DACL enforcement. Linux has no in-kernel equivalent; GNOME's dconf is the closest analogue, a user-space binary database with no write-ahead journal and no typed access-rights model. Impossible OS already matches Windows on the core tree, hive persistence with WAJ, RegCopyTree/RegRenameKey, volatile keys, and a 32-entry hot-key cache Windows' CmpCache pushlock also provides. It is behind Windows 11 on DACL enforcement, the full NT syscall surface (NtNotifyChangeKey is a stub), advapi32 A/W exposure, and SMP-safe concurrent access, all tracked above. Sections not yet started (transactions, snapshot/diff, schema-validated keys, incremental delta flush) are designed to exceed what either OS offers once built.