Skip to content

Add open_options support to registry open_*_key helpers#643

Open
benhillis wants to merge 2 commits into
microsoft:masterfrom
benhillis:reg-open-options
Open

Add open_options support to registry open_*_key helpers#643
benhillis wants to merge 2 commits into
microsoft:masterfrom
benhillis:reg-open-options

Conversation

@benhillis

Copy link
Copy Markdown
Member

Adds open-with-options support to wil's registry open_*_key helpers.

Motivation

Today open_unique_key / open_shared_key (and their _nothrow variants) hardcode ulOptions to 0 in their RegOpenKeyExW call. Callers that need a non-zero option — most notably REG_OPTION_BACKUP_RESTORE and REG_OPTION_OPEN_LINK — have no choice but to drop down to raw Win32. This is the last remaining gap preventing WSL from replacing its in-house registry helper with wil (WSL opens keys with REG_OPTION_BACKUP_RESTORE).

Change

  • New wil::reg::open_options flag enum: none, open_link (REG_OPTION_OPEN_LINK), backup_restore (REG_OPTION_BACKUP_RESTORE), dont_virtualize (REG_OPTION_DONT_VIRTUALIZE), with DEFINE_ENUM_FLAG_OPERATORS.
  • Threaded as a trailing defaulted parameter (= open_options::none) through open_unique_key, open_shared_key, open_unique_key_nothrow, open_shared_key_nothrow and the internal reg_view::open_key. Source-compatible — existing callers are unaffected.
  • Mirrors the established key_options precedent on the create side (kept separate because create/open option semantics differ).

Tests

Added BasicRegistryTests::open_options ([registry]) covering:

  • static_assert mapping of each enum value to its REG_OPTION_* constant and flag-OR composition.
  • Default open parity (none behaves like a plain open).
  • A volatile symbolic-link round-trip proving open_link returns the link key itself while a plain open follows through to the target.

Validated in both normal and noexcept configurations; full [registry] suite green.

Opening as draft for review.

Adds a wil::reg::open_options flag enum (none / open_link / backup_restore /
dont_virtualize) that maps to the ulOptions parameter of RegOpenKeyExW, and
threads it through open_unique_key, open_shared_key, and their _nothrow
variants as a trailing defaulted parameter. Previously these helpers hardcoded
ulOptions to 0, so callers needing e.g. REG_OPTION_OPEN_LINK had to fall back
to raw Win32.

Includes [registry] tests covering option-to-ulOptions mapping (static_assert),
default-open parity, and a symbolic-link round-trip proving open_link opens the
link key itself rather than its target.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@benhillis benhillis marked this pull request as ready for review June 18, 2026 17:23
Comment thread tests/RegistryTests.cpp

// KEY_NAME_INFORMATION { ULONG NameLength; WCHAR Name[1]; }; KeyNameInformation == 3.
constexpr int c_KeyNameInformation = 3;
BYTE buffer[512]{};

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
BYTE buffer[512]{};
alignas(ULONG) BYTE buffer[512]{};

I believe this is technically guaranteed for all relevant ABIs for stack variables, but good hygiene

Comment thread tests/RegistryTests.cpp
}

const auto nameLength = *reinterpret_cast<const ULONG*>(buffer);
const std::wstring targetNtPath(reinterpret_cast<const wchar_t*>(buffer + sizeof(ULONG)), nameLength / sizeof(wchar_t));

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm surprised this compiles outside of an #ifdef WIL_ENABLE_EXCEPTIONS. In my past experiences, Clang loves to complain about encountering throw statements when exceptions are disabled.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants