Skip to content

Add set_value_multistring_nothrow for REG_MULTI_SZ writes#631

Draft
benhillis wants to merge 2 commits 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 2 commits 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
Adds set_value_multistring_nothrow() - the missing nothrow counterpart
to the existing set_value_multistring().

Two overloads matching the existing pattern. Uses try/CATCH_RETURN()
since get_multistring_from_wstrings allocates internally. Gated behind
WIL_USE_STL.

Fixes microsoft#479
@benhillis benhillis force-pushed the add-set-value-multistring-nothrow branch from aa93024 to da4b4db Compare June 10, 2026 16:20
Replace the try/CATCH_RETURN() implementation with an exceptions-free
get_multistring_from_wstrings_nothrow helper so the API works in
no-exception builds (guard broadened to WIL_USE_STL). Addresses review
feedback: use unique_process_heap_ptr for ownership, single memcpy of
size()+1 to include the terminator, and a WI_ASSERT size sanity check.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
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.

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