Skip to content

Add set_value_multistring_nothrow for REG_MULTI_SZ writes#631

Draft
benhillis wants to merge 1 commit into
microsoft:masterfrom
benhillis:add-set-value-multistring-nothrow
Draft

Add set_value_multistring_nothrow for REG_MULTI_SZ writes#631
benhillis wants to merge 1 commit into
microsoft:masterfrom
benhillis:add-set-value-multistring-nothrow

Conversation

@benhillis

Copy link
Copy Markdown
Member

Adds set_value_multistring_nothrow() — the missing nothrow counterpart to the existing set_value_multistring().

Two overloads, matching the existing pattern:

HRESULT set_value_multistring_nothrow(HKEY key, PCWSTR subkey, PCWSTR value_name, const std::vector<std::wstring>& data);
HRESULT set_value_multistring_nothrow(HKEY key, PCWSTR value_name, const std::vector<std::wstring>& data);

Uses try/CATCH_RETURN() since get_multistring_from_wstrings allocates internally. Gated behind WIL_USE_STL.

Tests cover round-trips via both overloads, empty arrays, default value names, E_ACCESSDENIED on read-only keys, and cross-verification with the cotaskmem nothrow reader.

Fixes #479

@benhillis benhillis force-pushed the add-set-value-multistring-nothrow branch from 8390244 to 98ac5fc Compare April 20, 2026 23:03
@dunhor

dunhor commented Apr 21, 2026

Copy link
Copy Markdown
Member

It feels very weird and unnatural to have a "nothrow" function use exceptions internally -- I'm not aware of any existing place where this is done either. Coupled with the fact that the argument is std::vector<std::wstring>, so the caller has to be at least somewhat aware that exceptions exist.

I get why you are doing it, though. OOM and system errors are two very different classes of errors, and it's nice to have control flow that deals with error codes as opposed to exceptions, so I don't necessarily object to the idea. Curious what other folks think.

@benhillis

Copy link
Copy Markdown
Member Author

not aware of any existing place where this is done either. Coupled with the fact that the argument is std::vector<std::wstring>, so the caller has to be at least somewhat aw

I agree, and that's not the way things are typically done in wil, let me think about this a bit more.

Comment thread include/wil/registry.h Outdated
Comment thread include/wil/registry_helpers.h Outdated
Comment thread include/wil/registry_helpers.h
@benhillis benhillis force-pushed the add-set-value-multistring-nothrow branch from aa93024 to da4b4db Compare June 10, 2026 16:20
Comment thread include/wil/registry_helpers.h Outdated
Comment on lines +266 to +270
if (data.empty())
{
// An empty multi-string still requires a leading null plus the final terminator.
total_size_bytes = 2 * 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.

While I've used multi-strings before, I haven't thought too much about this case until now... AFAICT the correct way to represent an empty list is just a single null character: https://devblogs.microsoft.com/oldnewthing/20091008-00/?p=16443

Makes sense as empty strings cannot be present in a multi-string in the general case.

@benhillis benhillis force-pushed the add-set-value-multistring-nothrow branch from cb07d86 to 64f6145 Compare June 18, 2026 16:46
@benhillis

Copy link
Copy Markdown
Member Author

Format fixed.

For the empty multistring: Windows automatically pads REG_MULTI_SZ to 4 bytes minimum. Writing 1 null for [] gets padded to 2 nulls, same as [""], making them indistinguishable on read. Current behavior (2 nulls for empty) maintains round-trip compatibility.

Adds set_value_multistring_nothrow(), the missing nothrow counterpart to
set_value_multistring(). Takes an array of null-terminated strings as
(PCWSTR* data, size_t count) so it works in both exception-free and
no-STL builds.

Marshaling is done by an exceptions-free helper that allocates via
unique_process_heap_ptr and builds the null-delimited, double-null
terminated REG_MULTI_SZ buffer directly, with no std::vector or
try/CATCH_RETURN().

Two overloads matching the existing pattern (with and without a subkey).

Fixes microsoft#479

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@benhillis benhillis force-pushed the add-set-value-multistring-nothrow branch from 3c550c3 to ff19b42 Compare July 8, 2026 22:31
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.

Function missing wil::reg::set_value_multistring_nothrow

2 participants