mirror of https://github.com/PCSX2/pcsx2.git
3324 lines
181 KiB
C
3324 lines
181 KiB
C
|
//*********************************************************
|
||
|
//
|
||
|
// Copyright (c) Microsoft. All rights reserved.
|
||
|
// This code is licensed under the MIT License.
|
||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
|
||
|
// ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
|
||
|
// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
||
|
// PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||
|
//
|
||
|
//*********************************************************
|
||
|
//! @file
|
||
|
//! Helpers for reading and writing values to/from the registry.
|
||
|
#ifndef __WIL_REGISTRY_INCLUDED
|
||
|
#define __WIL_REGISTRY_INCLUDED
|
||
|
|
||
|
#ifdef _KERNEL_MODE
|
||
|
#error This header is not supported in kernel-mode.
|
||
|
#endif
|
||
|
|
||
|
#include <winreg.h>
|
||
|
#include <new.h> // new(std::nothrow)
|
||
|
#include "registry_helpers.h"
|
||
|
#include "resource.h"
|
||
|
|
||
|
// wil registry does not require the use of the STL or C++ exceptions (see _nothrow functions)
|
||
|
// wil registry natively supports std::vector and std::wstring when preferring those types
|
||
|
// wil registry uses the __WIL_WINREG_STL define to enable support for wil::shared_* types (defined in resource.h)
|
||
|
|
||
|
namespace wil
|
||
|
{
|
||
|
//! Functions and classes that support reading and writing values to/from the registry.
|
||
|
namespace reg
|
||
|
{
|
||
|
#if defined(WIL_ENABLE_EXCEPTIONS)
|
||
|
/**
|
||
|
* @brief Opens a new HKEY to the specified path - see RegOpenKeyExW
|
||
|
* @param key An open or well-known registry key
|
||
|
* @param subKey The name of the registry subkey to be opened.
|
||
|
* If `nullptr`, then `key` is used without modification.
|
||
|
* @param access The requested access desired for the opened key
|
||
|
* @return A wil::unique_hkey containing the resulting opened HKEY
|
||
|
* @exception std::exception (including wil::ResultException) will be thrown on all failures
|
||
|
*/
|
||
|
inline ::wil::unique_hkey open_unique_key(HKEY key, _In_opt_ PCWSTR subKey, ::wil::reg::key_access access = ::wil::reg::key_access::read)
|
||
|
{
|
||
|
const reg_view_details::reg_view regview{key};
|
||
|
::wil::unique_hkey return_value;
|
||
|
regview.open_key(subKey, &return_value, access);
|
||
|
return return_value;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Creates a new HKEY to the specified path - see RegCreateKeyExW
|
||
|
* @param key An open or well-known registry key
|
||
|
* @param subKey The name of a subkey that this function opens or creates.
|
||
|
* Note: this cannot be null (see the above referenced API documentation)
|
||
|
* @param access The requested access desired for the opened key
|
||
|
* @return A wil::unique_hkey or wil::shared_hkey containing the resulting opened HKEY
|
||
|
* @exception std::exception (including wil::ResultException) will be thrown on all failures
|
||
|
*/
|
||
|
inline ::wil::unique_hkey create_unique_key(HKEY key, PCWSTR subKey, ::wil::reg::key_access access = ::wil::reg::key_access::read)
|
||
|
{
|
||
|
const reg_view_details::reg_view regview{key};
|
||
|
::wil::unique_hkey return_value;
|
||
|
regview.create_key(subKey, &return_value, access);
|
||
|
return return_value;
|
||
|
}
|
||
|
|
||
|
#if defined(__WIL_WINREG_STL) || defined(WIL_DOXYGEN)
|
||
|
/**
|
||
|
* @brief Opens a new HKEY to the specified path - see RegOpenKeyExW
|
||
|
* @param key An open or well-known registry key
|
||
|
* @param subKey The name of the registry subkey to be opened.
|
||
|
* If `nullptr`, then `key` is used without modification.
|
||
|
* @param access The requested access desired for the opened key
|
||
|
* @return A wil::shared_hkey containing the resulting opened HKEY
|
||
|
* @exception std::exception (including wil::ResultException) will be thrown on all failures
|
||
|
*/
|
||
|
inline ::wil::shared_hkey open_shared_key(HKEY key, _In_opt_ PCWSTR subKey, ::wil::reg::key_access access = ::wil::reg::key_access::read)
|
||
|
{
|
||
|
const reg_view_details::reg_view regview{key};
|
||
|
::wil::shared_hkey return_value;
|
||
|
regview.open_key(subKey, &return_value, access);
|
||
|
return return_value;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Creates a new HKEY to the specified path - see RegCreateKeyExW
|
||
|
* @param key An open or well-known registry key
|
||
|
* @param subKey The name of a subkey that this function opens or creates.
|
||
|
* Note: this cannot be null (see the above referenced API documentation)
|
||
|
* @param access The requested access desired for the opened key
|
||
|
* @return A wil::shared_hkey or wil::shared_hkey containing the resulting opened HKEY
|
||
|
* @exception std::exception (including wil::ResultException) will be thrown on all failures
|
||
|
*/
|
||
|
inline ::wil::shared_hkey create_shared_key(HKEY key, PCWSTR subKey, ::wil::reg::key_access access = ::wil::reg::key_access::read)
|
||
|
{
|
||
|
const reg_view_details::reg_view regview{key};
|
||
|
::wil::shared_hkey return_value;
|
||
|
regview.create_key(subKey, &return_value, access);
|
||
|
return return_value;
|
||
|
}
|
||
|
#endif // #if defined(__WIL_WINREG_STL)
|
||
|
#endif // #if defined(WIL_ENABLE_EXCEPTIONS)
|
||
|
|
||
|
/**
|
||
|
* @brief Opens a new HKEY to the specified path - see RegOpenKeyExW
|
||
|
* @param key An open or well-known registry key
|
||
|
* @param subKey The name of the registry subkey to be opened.
|
||
|
* If `nullptr`, then `key` is used without modification.
|
||
|
* @param[out] hkey A reference to a wil::unique_hkey to receive the opened HKEY
|
||
|
* @param access The requested access desired for the opened key
|
||
|
* @return HRESULT error code indicating success or failure (does not throw C++ exceptions)
|
||
|
*/
|
||
|
inline HRESULT open_unique_key_nothrow(
|
||
|
HKEY key, _In_opt_ PCWSTR subKey, ::wil::unique_hkey& hkey, ::wil::reg::key_access access = ::wil::reg::key_access::read) WI_NOEXCEPT
|
||
|
{
|
||
|
const reg_view_details::reg_view_nothrow regview{key};
|
||
|
return regview.open_key(subKey, hkey.put(), access);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Creates a new HKEY to the specified path - see RegCreateKeyExW
|
||
|
* @param key An open or well-known registry key
|
||
|
* @param subKey The name of a subkey that this function opens or creates.
|
||
|
* Note: this cannot be null (see the above referenced API documentation)
|
||
|
* @param[out] hkey A reference to a wil::unique_hkey to receive the opened HKEY
|
||
|
* @param access The requested access desired for the opened key
|
||
|
* @return HRESULT error code indicating success or failure (does not throw C++ exceptions)
|
||
|
*/
|
||
|
inline HRESULT create_unique_key_nothrow(
|
||
|
HKEY key, PCWSTR subKey, ::wil::unique_hkey& hkey, ::wil::reg::key_access access = ::wil::reg::key_access::read) WI_NOEXCEPT
|
||
|
{
|
||
|
const reg_view_details::reg_view_nothrow regview{key};
|
||
|
return regview.create_key(subKey, hkey.put(), access);
|
||
|
}
|
||
|
|
||
|
#if defined(__WIL_WINREG_STL) || defined(WIL_DOXYGEN)
|
||
|
/**
|
||
|
* @brief Opens a new HKEY to the specified path - see RegOpenKeyExW
|
||
|
* @param key An open or well-known registry key
|
||
|
* @param subKey The name of the registry subkey to be opened.
|
||
|
* If `nullptr`, then `key` is used without modification.
|
||
|
* @param[out] hkey A reference to a wil::shared_hkey to receive the opened HKEY
|
||
|
* @param access The requested access desired for the opened key
|
||
|
* @return HRESULT error code indicating success or failure (does not throw C++ exceptions)
|
||
|
*/
|
||
|
inline HRESULT open_shared_key_nothrow(
|
||
|
HKEY key, _In_opt_ PCWSTR subKey, ::wil::shared_hkey& hkey, ::wil::reg::key_access access = ::wil::reg::key_access::read) WI_NOEXCEPT
|
||
|
{
|
||
|
const reg_view_details::reg_view_nothrow regview{key};
|
||
|
return regview.open_key(subKey, hkey.put(), access);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Creates a new HKEY to the specified path - see RegCreateKeyExW
|
||
|
* @param key An open or well-known registry key
|
||
|
* @param subKey The name of a subkey that this function opens or creates.
|
||
|
* Note: this cannot be null (see the above referenced API documentation)
|
||
|
* @param[out] hkey A reference to a wil::shared_hkey to receive the opened HKEY
|
||
|
* @param access The requested access desired for the opened key
|
||
|
* @return HRESULT error code indicating success or failure (does not throw C++ exceptions)
|
||
|
*/
|
||
|
inline HRESULT create_shared_key_nothrow(
|
||
|
HKEY key, PCWSTR subKey, ::wil::shared_hkey& hkey, ::wil::reg::key_access access = ::wil::reg::key_access::read) WI_NOEXCEPT
|
||
|
{
|
||
|
const reg_view_details::reg_view_nothrow regview{key};
|
||
|
return regview.create_key(subKey, hkey.put(), access);
|
||
|
}
|
||
|
#endif // #define __WIL_WINREG_STL
|
||
|
|
||
|
//
|
||
|
// wil::key_iterator and wil::value_iterator objects enable enumerating registry keys and values.
|
||
|
//
|
||
|
// Examples of usage when std::wstring is included:
|
||
|
//
|
||
|
// for (const auto& key_data : wil::make_range(wil::reg::key_iterator{hkey}, wil::reg::key_iterator{}))
|
||
|
// {
|
||
|
// key_data.name; // the std::wstring of the enumerated key
|
||
|
// }
|
||
|
//
|
||
|
// for (const auto& value_data : wil::make_range(wil::reg::value_iterator{hkey}, wil::reg::value_iterator{}))
|
||
|
// {
|
||
|
// value_data.name; // the std::wstring of the enumerated value
|
||
|
// value_data.type; // the REG_ type of the enumerated value
|
||
|
// }
|
||
|
//
|
||
|
// When std::wstring is not included, wil::unique_process_heap_string can be used instead:
|
||
|
//
|
||
|
// for (const auto& key_data : wil::make_range(wil::reg::key_heap_string_iterator{hkey}, wil::reg::key_heap_string_iterator{}))
|
||
|
// {
|
||
|
// key_data.name.get(); // the PCWSTR of the enumerated key
|
||
|
// }
|
||
|
//
|
||
|
// for (const auto& value_data : wil::make_range(wil::reg::value_heap_string_iterator{hkey}, wil::reg::value_heap_string_iterator{}))
|
||
|
// {
|
||
|
// value_data.name.get(); // the PCWSTR of the enumerated value
|
||
|
// value_data.type; // the REG_ type of the enumerated value
|
||
|
// }
|
||
|
//
|
||
|
// When not using exceptions, can manually walk the iterator using wil::unique_process_heap_string:
|
||
|
//
|
||
|
// auto iterate_keys = wil::reg::key_heap_string_nothrow_iterator{hkey};
|
||
|
// for (const auto& key_data : wil::make_range(iterate_keys, wil::reg::key_heap_string_nothrow_iterator{}))
|
||
|
// {
|
||
|
// key_data.name.get(); // the PCWSTR of the enumerated key
|
||
|
// }
|
||
|
// if (FAILED(iterate_keys.last_error()))
|
||
|
// {
|
||
|
// // the HRESULT last_error() returns the registry error that prevented enumeration
|
||
|
// }
|
||
|
//
|
||
|
// auto iterate_values = wil::reg::value_heap_string_nothrow_iterator{hkey};
|
||
|
// for (const auto& value_data : wil::make_range(iterate_values, wil::reg::value_heap_string_nothrow_iterator{}))
|
||
|
// {
|
||
|
// value_data.name.get(); // the PCWSTR of the enumerated value
|
||
|
// value_data.type; // the REG_ type of the enumerated value
|
||
|
// }
|
||
|
// if (FAILED(iterate_values.last_error()))
|
||
|
// {
|
||
|
// // the HRESULT last_error() returns the registry error that prevented enumeration
|
||
|
// }
|
||
|
//
|
||
|
#if defined(WIL_ENABLE_EXCEPTIONS)
|
||
|
|
||
|
#if defined(_STRING_) || defined(WIL_DOXYGEN)
|
||
|
using key_iterator = ::wil::reg::iterator_t<::wil::reg::key_iterator_data<::std::wstring>>;
|
||
|
using value_iterator = ::wil::reg::iterator_t<::wil::reg::value_iterator_data<::std::wstring>>;
|
||
|
#endif
|
||
|
|
||
|
#if defined(__WIL_OLEAUTO_H_) || defined(WIL_DOXYGEN)
|
||
|
using key_bstr_iterator = ::wil::reg::iterator_t<::wil::reg::key_iterator_data<::wil::unique_bstr>>;
|
||
|
using value_bstr_iterator = ::wil::reg::iterator_t<::wil::reg::value_iterator_data<::wil::unique_bstr>>;
|
||
|
#endif // #if defined(__WIL_OLEAUTO_H_)
|
||
|
|
||
|
using key_heap_string_iterator = ::wil::reg::iterator_t<::wil::reg::key_iterator_data<::wil::unique_process_heap_string>>;
|
||
|
using value_heap_string_iterator = ::wil::reg::iterator_t<::wil::reg::value_iterator_data<::wil::unique_process_heap_string>>;
|
||
|
|
||
|
#endif // #if defined(WIL_ENABLE_EXCEPTIONS)
|
||
|
|
||
|
// no-throw versions of applicable registry iterators
|
||
|
#if defined(__WIL_OLEAUTO_H_) || defined(WIL_DOXYGEN)
|
||
|
using key_bstr_nothrow_iterator = ::wil::reg::iterator_nothrow_t<::wil::reg::key_iterator_data<::wil::unique_bstr>>;
|
||
|
using value_bstr_nothrow_iterator = ::wil::reg::iterator_nothrow_t<::wil::reg::value_iterator_data<::wil::unique_bstr>>;
|
||
|
#endif // #if defined(__WIL_OLEAUTO_H_)
|
||
|
|
||
|
using key_heap_string_nothrow_iterator =
|
||
|
::wil::reg::iterator_nothrow_t<::wil::reg::key_iterator_data<::wil::unique_process_heap_string>>;
|
||
|
using value_heap_string_nothrow_iterator =
|
||
|
::wil::reg::iterator_nothrow_t<::wil::reg::value_iterator_data<::wil::unique_process_heap_string>>;
|
||
|
|
||
|
/**
|
||
|
* @brief Queries for number of sub-keys
|
||
|
* @param key The HKEY to query for number of sub-keys
|
||
|
* @param[out] numSubKeys A pointer to a DWORD to receive the returned count
|
||
|
* @return HRESULT error code indicating success or failure (does not throw C++ exceptions)
|
||
|
*/
|
||
|
inline HRESULT get_child_key_count_nothrow(HKEY key, _Out_ DWORD* numSubKeys) WI_NOEXCEPT
|
||
|
{
|
||
|
RETURN_IF_WIN32_ERROR(RegQueryInfoKeyW(
|
||
|
key,
|
||
|
nullptr, // null class
|
||
|
nullptr, // null class character count,
|
||
|
nullptr, // null reserved
|
||
|
numSubKeys,
|
||
|
nullptr, // null max subkey length
|
||
|
nullptr, // null max class length
|
||
|
nullptr, // null value count
|
||
|
nullptr, // null max value name length
|
||
|
nullptr, // null max value length
|
||
|
nullptr, // null security descriptor
|
||
|
nullptr)); // null last write filetime
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
inline HRESULT get_child_key_count_nothrow(HKEY key, _Out_ uint32_t* numSubKeys) WI_NOEXCEPT
|
||
|
{
|
||
|
DWORD subKeys{};
|
||
|
RETURN_IF_FAILED(::wil::reg::get_child_key_count_nothrow(key, &subKeys));
|
||
|
*numSubKeys = subKeys;
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Queries for number of values
|
||
|
* @param key The HKEY to query for number of values
|
||
|
* @param[out] numSubValues A pointer to a DWORD to receive the returned count
|
||
|
* @return HRESULT error code indicating success or failure (does not throw C++ exceptions)
|
||
|
*/
|
||
|
inline HRESULT get_child_value_count_nothrow(HKEY key, _Out_ DWORD* numSubValues) WI_NOEXCEPT
|
||
|
{
|
||
|
RETURN_IF_WIN32_ERROR(RegQueryInfoKeyW(
|
||
|
key,
|
||
|
nullptr, // null class
|
||
|
nullptr, // null class char count,
|
||
|
nullptr, // null reserved
|
||
|
nullptr, // null subkey count
|
||
|
nullptr, // null max subkey length
|
||
|
nullptr, // null max class length
|
||
|
numSubValues,
|
||
|
nullptr, // null max value name length
|
||
|
nullptr, // null max value length
|
||
|
nullptr, // null security descriptor
|
||
|
nullptr)); // null last write filetime
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
inline HRESULT get_child_value_count_nothrow(HKEY key, _Out_ uint32_t* numSubValues) WI_NOEXCEPT
|
||
|
{
|
||
|
DWORD subValues{};
|
||
|
RETURN_IF_FAILED(::wil::reg::get_child_value_count_nothrow(key, &subValues));
|
||
|
*numSubValues = subValues;
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Queries for the filetime when the registry key was last written
|
||
|
* @param key The HKEY to query for number of values
|
||
|
* @param[out] lastModified A pointer to a FILETIME to receive the last write time
|
||
|
* @exception std::exception (including wil::ResultException) will be thrown on all failures
|
||
|
*/
|
||
|
inline HRESULT get_last_write_filetime_nothrow(HKEY key, _Out_ FILETIME* lastModified) WI_NOEXCEPT
|
||
|
{
|
||
|
RETURN_IF_WIN32_ERROR(RegQueryInfoKeyW(
|
||
|
key,
|
||
|
nullptr, // null class
|
||
|
nullptr, // null class char count,
|
||
|
nullptr, // null reserved
|
||
|
nullptr, // null subkey count
|
||
|
nullptr, // null max subkey length
|
||
|
nullptr, // null max class length
|
||
|
nullptr, // null value count
|
||
|
nullptr, // null max value name length
|
||
|
nullptr, // null max value length
|
||
|
nullptr, // null security descriptor
|
||
|
lastModified));
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
#if defined(WIL_ENABLE_EXCEPTIONS)
|
||
|
/**
|
||
|
* @brief Queries for number of sub-keys
|
||
|
* @param key The HKEY to query for number of sub-keys
|
||
|
* @return The queried number of sub-keys if succeeded
|
||
|
* @exception std::exception (including wil::ResultException) will be thrown on all failures
|
||
|
*/
|
||
|
inline uint32_t get_child_key_count(HKEY key)
|
||
|
{
|
||
|
uint32_t numSubKeys{};
|
||
|
THROW_IF_FAILED(::wil::reg::get_child_key_count_nothrow(key, &numSubKeys));
|
||
|
return numSubKeys;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Queries for number of values
|
||
|
* @param key The HKEY to query for number of values
|
||
|
* @return The queried number of value if succeeded
|
||
|
* @exception std::exception (including wil::ResultException) will be thrown on all failures
|
||
|
*/
|
||
|
inline uint32_t get_child_value_count(HKEY key)
|
||
|
{
|
||
|
uint32_t numSubValues{};
|
||
|
THROW_IF_FAILED(::wil::reg::get_child_value_count_nothrow(key, &numSubValues));
|
||
|
return numSubValues;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Queries for the filetime when the registry key was last written
|
||
|
* @param key The HKEY to query for number of values
|
||
|
* @return The queried filetime if succeeded
|
||
|
* @exception std::exception (including wil::ResultException) will be thrown on all failures
|
||
|
*/
|
||
|
inline FILETIME get_last_write_filetime(HKEY key)
|
||
|
{
|
||
|
FILETIME lastModified{};
|
||
|
THROW_IF_FAILED(::wil::reg::get_last_write_filetime_nothrow(key, &lastModified));
|
||
|
return lastModified;
|
||
|
}
|
||
|
#endif // #if defined(WIL_ENABLE_EXCEPTIONS)
|
||
|
|
||
|
#if defined(WIL_ENABLE_EXCEPTIONS)
|
||
|
//
|
||
|
// template <typename T>
|
||
|
// void set_value(...)
|
||
|
//
|
||
|
// - Writes a value to a specified key and subkey, deducing the type from the given data
|
||
|
// - Throws a std::exception on failure (including wil::ResultException)
|
||
|
//
|
||
|
// Examples of usage (the template type does not need to be explicitly specified)
|
||
|
// wil::reg::set_value(key, L"subkey", L"dword_value_name", 0); // writes a REG_DWORD
|
||
|
// wil::reg::set_value(key, L"subkey", L"qword_value_name", 0ull); // writes a REG_QWORD
|
||
|
// wil::reg::set_value(key, L"subkey", L"string_value_name", L"hello"); // writes a REG_SZ
|
||
|
//
|
||
|
// A subkey is not required if the key is opened where this should write the value:
|
||
|
// wil::reg::set_value(key, L"dword_value_name", 0); // writes a REG_DWORD
|
||
|
// wil::reg::set_value(key, L"qword_value_name", 0ull); // writes a REG_QWORD
|
||
|
// wil::reg::set_value(key, L"string_value_name", L"hello"); // writes a REG_SZ
|
||
|
//
|
||
|
// Example usage writing a vector of wstrings to a REG_MULTI_SZ
|
||
|
// std::vector<std::wstring> data { L"string1", L"string2", L"string3" };
|
||
|
// wil::reg::set_value(key, L"multi_string_value_name", data);
|
||
|
// wil::reg::set_value(key, L"multi_string_value_name", data);
|
||
|
//
|
||
|
// Example of usage writing directly to a registry value from a raw byte vector
|
||
|
// - notice the registry type is required, not implied
|
||
|
// std::vector<BYTE> data { 0x00, 0xff, 0xee, 0xdd, 0xcc };
|
||
|
// wil::reg::set_value_binary(key, L"binary_value_name", REG_BINARY, data);
|
||
|
// wil::reg::set_value_binary(key, L"binary_value_name", REG_BINARY, data);
|
||
|
//
|
||
|
|
||
|
/**
|
||
|
* @brief Writes a value to a specified key and subkey, deducing the type from the given data.
|
||
|
* @tparam T The type of the data being set (the registry value type is deduced from T).
|
||
|
* @param key An open or well-known registry key
|
||
|
* @param subkey The name of the subkey to append to `key`.
|
||
|
* If `nullptr`, then `key` is used without modification.
|
||
|
* @param value_name The name of the registry value whose data is to be updated.
|
||
|
* Can be nullptr to write to the unnamed default registry value.
|
||
|
* @param data The data (of type T) to write to the specified registry value
|
||
|
* @exception std::exception (including wil::ResultException) will be thrown on all failures
|
||
|
*/
|
||
|
template <typename T>
|
||
|
void set_value(HKEY key, _In_opt_ PCWSTR subkey, _In_opt_ PCWSTR value_name, const T& data)
|
||
|
{
|
||
|
const reg_view_details::reg_view regview{key};
|
||
|
regview.set_value(subkey, value_name, data);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Writes a value under a specified key, the registry type based off the templated type passed as data
|
||
|
* @tparam T The type of the data being set (the registry value type is deduced from T).
|
||
|
* @param key An open or well-known registry key
|
||
|
* @param value_name The name of the registry value whose data is to be updated.
|
||
|
* Can be nullptr to write to the unnamed default registry value.
|
||
|
* @param data The data (of type T) to write to the specified registry value
|
||
|
* @exception std::exception (including wil::ResultException) will be thrown on all failures
|
||
|
*/
|
||
|
template <typename T>
|
||
|
void set_value(HKEY key, _In_opt_ PCWSTR value_name, const T& data)
|
||
|
{
|
||
|
::wil::reg::set_value(key, nullptr, value_name, data);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Writes a null-terminated string value under a specified key
|
||
|
* @param key An open or well-known registry key
|
||
|
* @param subkey The name of the subkey to append to `key`.
|
||
|
* If `nullptr`, then `key` is used without modification.
|
||
|
* @param value_name The name of the registry value whose data is to be updated.
|
||
|
* Can be nullptr to write to the unnamed default registry value.
|
||
|
* @param data The null-terminated string to write to the specified registry value
|
||
|
* @exception std::exception (including wil::ResultException) will be thrown on all failures
|
||
|
*/
|
||
|
inline void set_value(HKEY key, _In_opt_ PCWSTR subkey, _In_opt_ PCWSTR value_name, PCWSTR data)
|
||
|
{
|
||
|
const reg_view_details::reg_view regview{key};
|
||
|
regview.set_value(subkey, value_name, data);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Writes a null-terminated string value under a specified key
|
||
|
* @param key An open or well-known registry key
|
||
|
* @param value_name The name of the registry value whose data is to be updated.
|
||
|
* Can be nullptr to write to the unnamed default registry value.
|
||
|
* @param data The null-terminated string to write to the specified registry value
|
||
|
* @exception std::exception (including wil::ResultException) will be thrown on all failures
|
||
|
*/
|
||
|
inline void set_value(HKEY key, _In_opt_ PCWSTR value_name, PCWSTR data)
|
||
|
{
|
||
|
::wil::reg::set_value(key, nullptr, value_name, data);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Writes a REG_DWORD value from a uint32_t
|
||
|
* @param key An open or well-known registry key
|
||
|
* @param subkey The name of the subkey to append to `key`.
|
||
|
* If `nullptr`, then `key` is used without modification.
|
||
|
* @param value_name The name of the registry value whose data is to be updated.
|
||
|
* Can be nullptr to write to the unnamed default registry value.
|
||
|
* @param data The 32-bit value to write to the specified registry value
|
||
|
* @exception std::exception (including wil::ResultException) will be thrown on all failures
|
||
|
*/
|
||
|
inline void set_value_dword(HKEY key, _In_opt_ PCWSTR subkey, _In_opt_ PCWSTR value_name, uint32_t data)
|
||
|
{
|
||
|
::wil::reg::set_value(key, subkey, value_name, data);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Writes a REG_DWORD value from a uint32_t
|
||
|
* @param key An open or well-known registry key
|
||
|
* @param value_name The name of the registry value whose data is to be updated.
|
||
|
* Can be nullptr to write to the unnamed default registry value.
|
||
|
* @param data The 32-bit value to write to the specified registry value
|
||
|
* @exception std::exception (including wil::ResultException) will be thrown on all failures
|
||
|
*/
|
||
|
inline void set_value_dword(HKEY key, _In_opt_ PCWSTR value_name, uint32_t data)
|
||
|
{
|
||
|
::wil::reg::set_value(key, nullptr, value_name, data);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Writes a REG_QWORD value from a uint64_t
|
||
|
* @param key An open or well-known registry key
|
||
|
* @param subkey The name of the subkey to append to `key`.
|
||
|
* If `nullptr`, then `key` is used without modification.
|
||
|
* @param value_name The name of the registry value whose data is to be updated.
|
||
|
* Can be nullptr to write to the unnamed default registry value.
|
||
|
* @param data The 64-bit value to write to the specified registry value
|
||
|
* @exception std::exception (including wil::ResultException) will be thrown on all failures
|
||
|
*/
|
||
|
inline void set_value_qword(HKEY key, _In_opt_ PCWSTR subkey, _In_opt_ PCWSTR value_name, uint64_t data)
|
||
|
{
|
||
|
::wil::reg::set_value(key, subkey, value_name, data);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Writes a REG_QWORD value from a uint64_t
|
||
|
* @param key An open or well-known registry key
|
||
|
* @param value_name The name of the registry value whose data is to be updated.
|
||
|
* Can be nullptr to write to the unnamed default registry value.
|
||
|
* @param data The 64-bit value to write to the specified registry value
|
||
|
* @exception std::exception (including wil::ResultException) will be thrown on all failures
|
||
|
*/
|
||
|
inline void set_value_qword(HKEY key, _In_opt_ PCWSTR value_name, uint64_t data)
|
||
|
{
|
||
|
::wil::reg::set_value(key, nullptr, value_name, data);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Writes a REG_SZ value from a null-terminated string
|
||
|
* @param key An open or well-known registry key
|
||
|
* @param subkey The name of the subkey to append to `key`.
|
||
|
* If `nullptr`, then `key` is used without modification.
|
||
|
* @param value_name The name of the registry value whose data is to be updated.
|
||
|
* Can be nullptr to write to the unnamed default registry value.
|
||
|
* @param data The null-terminated string value to write to the specified registry value
|
||
|
* @exception std::exception (including wil::ResultException) will be thrown on all failures
|
||
|
*/
|
||
|
inline void set_value_string(HKEY key, _In_opt_ PCWSTR subkey, _In_opt_ PCWSTR value_name, PCWSTR data)
|
||
|
{
|
||
|
::wil::reg::set_value(key, subkey, value_name, data);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Writes a REG_SZ value from a null-terminated string
|
||
|
* @param key An open or well-known registry key
|
||
|
* @param value_name The name of the registry value whose data is to be updated.
|
||
|
* Can be nullptr to write to the unnamed default registry value.
|
||
|
* @param data The null-terminated string value to write to the specified registry value
|
||
|
* @exception std::exception (including wil::ResultException) will be thrown on all failures
|
||
|
*/
|
||
|
inline void set_value_string(HKEY key, _In_opt_ PCWSTR value_name, PCWSTR data)
|
||
|
{
|
||
|
::wil::reg::set_value(key, nullptr, value_name, data);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Writes a REG_EXPAND_SZ value from a null-terminated string
|
||
|
* @param key An open or well-known registry key
|
||
|
* @param subkey The name of the subkey to append to `key`.
|
||
|
* If `nullptr`, then `key` is used without modification.
|
||
|
* @param value_name The name of the registry value whose data is to be updated.
|
||
|
* Can be nullptr to write to the unnamed default registry value.
|
||
|
* @param data The null-terminated, unexpanded string value to write to the specified registry value. For example, `%PATH%`.
|
||
|
* @exception std::exception (including wil::ResultException) will be thrown on all failures
|
||
|
*/
|
||
|
inline void set_value_expanded_string(HKEY key, _In_opt_ PCWSTR subkey, _In_opt_ PCWSTR value_name, PCWSTR data)
|
||
|
{
|
||
|
const reg_view_details::reg_view regview{key};
|
||
|
regview.set_value(subkey, value_name, data, REG_EXPAND_SZ);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Writes a REG_EXPAND_SZ value from a null-terminated string
|
||
|
* @param key An open or well-known registry key
|
||
|
* @param value_name The name of the registry value whose data is to be updated.
|
||
|
* Can be nullptr to write to the unnamed default registry value.
|
||
|
* @param data The null-terminated, unexpanded string value to write to the specified registry value. For example, `%PATH%`.
|
||
|
* @exception std::exception (including wil::ResultException) will be thrown on all failures
|
||
|
*/
|
||
|
inline void set_value_expanded_string(HKEY key, _In_opt_ PCWSTR value_name, PCWSTR data)
|
||
|
{
|
||
|
::wil::reg::set_value_expanded_string(key, nullptr, value_name, data);
|
||
|
}
|
||
|
|
||
|
#if (defined(_VECTOR_) && defined(_STRING_)) || defined(WIL_DOXYGEN)
|
||
|
/**
|
||
|
* @brief The generic set_value template function to write a REG_MULTI_SZ value from a std::vector<std::wstring>
|
||
|
* @param key An open or well-known registry key
|
||
|
* @param subkey The name of the subkey to append to `key`.
|
||
|
* If `nullptr`, then `key` is used without modification.
|
||
|
* @param value_name The name of the registry value whose data is to be updated.
|
||
|
* Can be nullptr to write to the unnamed default registry value.
|
||
|
* @param data A std::vector<std::wstring> to write to the specified registry value.
|
||
|
* Each string will be marshaled to a contiguous null-terminator-delimited multi-sz string
|
||
|
* @exception std::exception (including wil::ResultException) will be thrown on all failures
|
||
|
*/
|
||
|
inline void set_value(HKEY key, _In_opt_ PCWSTR subkey, _In_opt_ PCWSTR value_name, const ::std::vector<::std::wstring>& data)
|
||
|
{
|
||
|
const auto multiStringWcharVector(reg_view_details::get_multistring_from_wstrings(::std::begin(data), ::std::end(data)));
|
||
|
const reg_view_details::reg_view regview{key};
|
||
|
regview.set_value(subkey, value_name, multiStringWcharVector, REG_MULTI_SZ);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief The generic set_value template function to write a REG_MULTI_SZ value from a std::vector<std::wstring>
|
||
|
* @param key An open or well-known registry key
|
||
|
* @param value_name The name of the registry value whose data is to be updated.
|
||
|
* Can be nullptr to write to the unnamed default registry value.
|
||
|
* @param data A std::vector<std::wstring> to write to the specified registry value.
|
||
|
* Each string will be marshaled to a contiguous null-terminator-delimited multi-sz string.
|
||
|
* @exception std::exception (including wil::ResultException) will be thrown on all failures
|
||
|
*/
|
||
|
inline void set_value(HKEY key, _In_opt_ PCWSTR value_name, const ::std::vector<::std::wstring>& data)
|
||
|
{
|
||
|
::wil::reg::set_value(key, nullptr, value_name, data);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Writes a REG_MULTI_SZ value from a std::vector<std::wstring>
|
||
|
* @param key An open or well-known registry key
|
||
|
* @param subkey The name of the subkey to append to `key`.
|
||
|
* If `nullptr`, then `key` is used without modification.
|
||
|
* @param value_name The name of the registry value whose data is to be updated.
|
||
|
* Can be nullptr to write to the unnamed default registry value.
|
||
|
* @param data A std::vector<std::wstring> to write to the specified registry value.
|
||
|
* Each string will be marshaled to a contiguous null-terminator-delimited multi-sz string
|
||
|
* @exception std::exception (including wil::ResultException) will be thrown on all failures
|
||
|
*/
|
||
|
inline void set_value_multistring(HKEY key, _In_opt_ PCWSTR subkey, _In_opt_ PCWSTR value_name, const ::std::vector<::std::wstring>& data)
|
||
|
{
|
||
|
::wil::reg::set_value(key, subkey, value_name, data);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Writes a REG_MULTI_SZ value from a std::vector<std::wstring>
|
||
|
* @param key An open or well-known registry key
|
||
|
* @param value_name The name of the registry value whose data is to be updated.
|
||
|
* Can be nullptr to write to the unnamed default registry value.
|
||
|
* @param data A std::vector<std::wstring> to write to the specified registry value.
|
||
|
* Each string will be marshaled to a contiguous null-terminator-delimited multi-sz string.
|
||
|
* @exception std::exception (including wil::ResultException) will be thrown on all failures
|
||
|
*/
|
||
|
inline void set_value_multistring(HKEY key, _In_opt_ PCWSTR value_name, const ::std::vector<::std::wstring>& data)
|
||
|
{
|
||
|
::wil::reg::set_value(key, nullptr, value_name, data);
|
||
|
}
|
||
|
#endif // #if defined(_VECTOR_) && defined(_STRING_)
|
||
|
|
||
|
#if defined(_VECTOR_) || defined(WIL_DOXYGEN)
|
||
|
/**
|
||
|
* @brief Writes a registry value of the specified type from a `std::vector<uint8_t>`/`std::vector<BYTE>`
|
||
|
* @param key An open or well-known registry key
|
||
|
* @param subkey The name of the subkey to append to `key`.
|
||
|
* If `nullptr`, then `key` is used without modification.
|
||
|
* @param value_name The name of the registry value whose data is to be updated.
|
||
|
* Can be nullptr to write to the unnamed default registry value.
|
||
|
* @param type The registry type for the specified registry value - see RegSetKeyValueW
|
||
|
* @param data A `std::vector<uint8_t>`/`std::vector<BYTE>` to write to the specified registry value.
|
||
|
* The vector contents will be directly marshaled to the specified value.
|
||
|
* @exception std::exception (including wil::ResultException) will be thrown on all failures
|
||
|
*/
|
||
|
inline void set_value_binary(HKEY key, _In_opt_ PCWSTR subkey, _In_opt_ PCWSTR value_name, uint32_t type, const ::std::vector<uint8_t>& data)
|
||
|
{
|
||
|
const reg_view_details::reg_view regview{key};
|
||
|
regview.set_value(subkey, value_name, data, type);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Writes a registry value of the specified type from a `std::vector<uint8_t>`/`std::vector<BYTE>`
|
||
|
* @param key An open or well-known registry key
|
||
|
* @param value_name The name of the registry value whose data is to be updated.
|
||
|
* Can be nullptr to write to the unnamed default registry value.
|
||
|
* @param type The registry type for the specified registry value - see RegSetKeyValueW
|
||
|
* @param data A `std::vector<uint8_t>`/`std::vector<BYTE>` to write to the specified registry value.
|
||
|
* The vector contents will be directly marshaled to the specified value.
|
||
|
* @exception std::exception (including wil::ResultException) will be thrown on all failures
|
||
|
*/
|
||
|
inline void set_value_binary(HKEY key, _In_opt_ PCWSTR value_name, uint32_t type, const ::std::vector<uint8_t>& data)
|
||
|
{
|
||
|
::wil::reg::set_value_binary(key, nullptr, value_name, type, data);
|
||
|
}
|
||
|
#endif // #if defined(_VECTOR_)
|
||
|
#endif // #if defined(WIL_ENABLE_EXCEPTIONS)
|
||
|
|
||
|
//
|
||
|
// template <typename T>
|
||
|
// HRESULT set_value_nothrow(...)
|
||
|
//
|
||
|
// - Writes a value under a specified key
|
||
|
// - The type of registry value is determined by the template type T of data given
|
||
|
// - Returns an HRESULT error code indicating success or failure (does not throw C++ exceptions)
|
||
|
//
|
||
|
// Examples of usage (the template type does not need to be explicitly specified)
|
||
|
// hr = wil::reg::set_value_nothrow(key, L"subkey", L"dword_value_name", 0); // writes a REG_DWORD
|
||
|
// hr = wil::reg::set_value_nothrow(key, L"subkey", L"qword_value_name", 0ull); // writes a REG_QWORD
|
||
|
// hr = wil::reg::set_value_nothrow(key, L"subkey", L"string_value_name", L"hello"); // writes a REG_SZ
|
||
|
//
|
||
|
// A subkey is not required if the key is opened where this should write the value:
|
||
|
// hr = wil::reg::set_value_nothrow(key, L"dword_value_name", 0); // writes a REG_DWORD
|
||
|
// hr = wil::reg::set_value_nothrow(key, L"qword_value_name", 0ull); // writes a REG_QWORD
|
||
|
// hr = wil::reg::set_value_nothrow(key, L"string_value_name", L"hello"); // writes a REG_SZ
|
||
|
//
|
||
|
// Example of usage writing a REG_MULTI_SZ
|
||
|
// std::vector<std::wstring> multisz_data { L"string1", L"string2", L"string3" };
|
||
|
// hr = wil::reg::set_value_nothrow(key, L"multi_string_value_name", multisz_data);
|
||
|
//
|
||
|
// Values can be written directly from a vector of bytes - the registry type must be specified; e.g.:
|
||
|
// std::vector<BYTE> data { 0x00, 0xff, 0xee, 0xdd, 0xcc };
|
||
|
// hr = wil::reg::set_value_binary_nothrow(key, L"binary_value_name", REG_BINARY, data);
|
||
|
//
|
||
|
/**
|
||
|
* @brief Writes a value to a specified key and subkey, deducing the type from the given data.
|
||
|
* @tparam T The type of the data being set (the registry value type is deduced from T).
|
||
|
* @param key An open or well-known registry key
|
||
|
* @param subkey The name of the subkey to append to `key`.
|
||
|
* If `nullptr`, then `key` is used without modification.
|
||
|
* @param value_name The name of the registry value whose data is to be updated.
|
||
|
* Can be nullptr to write to the unnamed default registry value.
|
||
|
* @param data The data (of type T) to write to the specified registry value
|
||
|
* @return HRESULT error code indicating success or failure (does not throw C++ exceptions)
|
||
|
*/
|
||
|
template <typename T>
|
||
|
HRESULT set_value_nothrow(HKEY key, _In_opt_ PCWSTR subkey, _In_opt_ PCWSTR value_name, const T& data) WI_NOEXCEPT
|
||
|
{
|
||
|
const reg_view_details::reg_view_nothrow regview{key};
|
||
|
return regview.set_value(subkey, value_name, data);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Writes a value under a specified key, the registry type based off the templated type passed as data
|
||
|
* @tparam T The type of the data being set (the registry value type is deduced from T).
|
||
|
* @param key An open or well-known registry key
|
||
|
* @param value_name The name of the registry value whose data is to be updated.
|
||
|
* Can be nullptr to write to the unnamed default registry value.
|
||
|
* @param data The data (of type T) to write to the specified registry value
|
||
|
* @return HRESULT error code indicating success or failure (does not throw C++ exceptions)
|
||
|
*/
|
||
|
template <typename T>
|
||
|
HRESULT set_value_nothrow(HKEY key, _In_opt_ PCWSTR value_name, const T& data) WI_NOEXCEPT
|
||
|
{
|
||
|
return ::wil::reg::set_value_nothrow(key, nullptr, value_name, data);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Writes a null-terminated string value under a specified key
|
||
|
* @param key An open or well-known registry key
|
||
|
* @param subkey The name of the subkey to append to `key`.
|
||
|
* If `nullptr`, then `key` is used without modification.
|
||
|
* @param value_name The name of the registry value whose data is to be updated.
|
||
|
* Can be nullptr to write to the unnamed default registry value.
|
||
|
* @param data The null-terminated string to write to the specified registry value
|
||
|
* @return HRESULT error code indicating success or failure (does not throw C++ exceptions)
|
||
|
*/
|
||
|
inline HRESULT set_value_nothrow(HKEY key, _In_opt_ PCWSTR subkey, _In_opt_ PCWSTR value_name, PCWSTR data) WI_NOEXCEPT
|
||
|
{
|
||
|
const reg_view_details::reg_view_nothrow regview{key};
|
||
|
return regview.set_value(subkey, value_name, data);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Writes a null-terminated string value under a specified key
|
||
|
* @param key An open or well-known registry key
|
||
|
* @param value_name The name of the registry value whose data is to be updated.
|
||
|
* Can be nullptr to write to the unnamed default registry value.
|
||
|
* @param data The null-terminated string to write to the specified registry value
|
||
|
* @return HRESULT error code indicating success or failure (does not throw C++ exceptions)
|
||
|
*/
|
||
|
inline HRESULT set_value_nothrow(HKEY key, _In_opt_ PCWSTR value_name, PCWSTR data) WI_NOEXCEPT
|
||
|
{
|
||
|
return ::wil::reg::set_value_nothrow(key, nullptr, value_name, data);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Writes a REG_DWORD value from a uint32_t
|
||
|
* @param key An open or well-known registry key
|
||
|
* @param subkey The name of the subkey to append to `key`.
|
||
|
* If `nullptr`, then `key` is used without modification.
|
||
|
* @param value_name The name of the registry value whose data is to be updated.
|
||
|
* Can be nullptr to write to the unnamed default registry value.
|
||
|
* @param data The 32-bit value to write to the specified registry value
|
||
|
* @return HRESULT error code indicating success or failure (does not throw C++ exceptions)
|
||
|
*/
|
||
|
inline HRESULT set_value_dword_nothrow(HKEY key, _In_opt_ PCWSTR subkey, _In_opt_ PCWSTR value_name, uint32_t data) WI_NOEXCEPT
|
||
|
{
|
||
|
return ::wil::reg::set_value_nothrow(key, subkey, value_name, data);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Writes a REG_DWORD value from a uint32_t
|
||
|
* @param key An open or well-known registry key
|
||
|
* @param value_name The name of the registry value whose data is to be updated.
|
||
|
* Can be nullptr to write to the unnamed default registry value.
|
||
|
* @param data The 32-bit value to write to the specified registry value
|
||
|
* @return HRESULT error code indicating success or failure (does not throw C++ exceptions)
|
||
|
*/
|
||
|
inline HRESULT set_value_dword_nothrow(HKEY key, _In_opt_ PCWSTR value_name, uint32_t data) WI_NOEXCEPT
|
||
|
{
|
||
|
return ::wil::reg::set_value_nothrow(key, nullptr, value_name, data);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Writes a REG_QWORD value from a uint64_t
|
||
|
* @param key An open or well-known registry key
|
||
|
* @param subkey The name of the subkey to append to `key`.
|
||
|
* If `nullptr`, then `key` is used without modification.
|
||
|
* @param value_name The name of the registry value whose data is to be updated.
|
||
|
* Can be nullptr to write to the unnamed default registry value.
|
||
|
* @param data The 64-bit value to write to the specified registry value
|
||
|
* @return HRESULT error code indicating success or failure (does not throw C++ exceptions)
|
||
|
*/
|
||
|
inline HRESULT set_value_qword_nothrow(HKEY key, _In_opt_ PCWSTR subkey, _In_opt_ PCWSTR value_name, uint64_t data) WI_NOEXCEPT
|
||
|
{
|
||
|
return ::wil::reg::set_value_nothrow(key, subkey, value_name, data);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Writes a REG_QWORD value from a uint64_t
|
||
|
* @param key An open or well-known registry key
|
||
|
* @param value_name The name of the registry value whose data is to be updated.
|
||
|
* Can be nullptr to write to the unnamed default registry value.
|
||
|
* @param data The 64-bit value to write to the specified registry value
|
||
|
* @return HRESULT error code indicating success or failure (does not throw C++ exceptions)
|
||
|
*/
|
||
|
inline HRESULT set_value_qword_nothrow(HKEY key, _In_opt_ PCWSTR value_name, uint64_t data) WI_NOEXCEPT
|
||
|
{
|
||
|
return ::wil::reg::set_value_nothrow(key, nullptr, value_name, data);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Writes a REG_SZ value from a null-terminated string
|
||
|
* @param key An open or well-known registry key
|
||
|
* @param subkey The name of the subkey to append to `key`.
|
||
|
* If `nullptr`, then `key` is used without modification.
|
||
|
* @param value_name The name of the registry value whose data is to be updated.
|
||
|
* Can be nullptr to write to the unnamed default registry value.
|
||
|
* @param data The null-terminated string value to write to the specified registry value
|
||
|
* @return HRESULT error code indicating success or failure (does not throw C++ exceptions)
|
||
|
*/
|
||
|
inline HRESULT set_value_string_nothrow(HKEY key, _In_opt_ PCWSTR subkey, _In_opt_ PCWSTR value_name, PCWSTR data) WI_NOEXCEPT
|
||
|
{
|
||
|
return ::wil::reg::set_value_nothrow(key, subkey, value_name, data);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Writes a REG_SZ value from a null-terminated string
|
||
|
* @param key An open or well-known registry key
|
||
|
* @param value_name The name of the registry value whose data is to be updated.
|
||
|
* Can be nullptr to write to the unnamed default registry value.
|
||
|
* @param data The null-terminated string value to write to the specified registry value
|
||
|
* @return HRESULT error code indicating success or failure (does not throw C++ exceptions)
|
||
|
*/
|
||
|
inline HRESULT set_value_string_nothrow(HKEY key, _In_opt_ PCWSTR value_name, PCWSTR data) WI_NOEXCEPT
|
||
|
{
|
||
|
return ::wil::reg::set_value_nothrow(key, nullptr, value_name, data);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Writes a REG_EXPAND_SZ value from a null-terminated string
|
||
|
* @param key An open or well-known registry key
|
||
|
* @param subkey The name of the subkey to append to `key`.
|
||
|
* If `nullptr`, then `key` is used without modification.
|
||
|
* @param value_name The name of the registry value whose data is to be updated.
|
||
|
* Can be nullptr to write to the unnamed default registry value.
|
||
|
* @param data The null-terminated string value to write to the specified registry value
|
||
|
* @return HRESULT error code indicating success or failure (does not throw C++ exceptions)
|
||
|
*/
|
||
|
inline HRESULT set_value_expanded_string_nothrow(HKEY key, _In_opt_ PCWSTR subkey, _In_opt_ PCWSTR value_name, PCWSTR data) WI_NOEXCEPT
|
||
|
{
|
||
|
const reg_view_details::reg_view_nothrow regview{key};
|
||
|
return regview.set_value(subkey, value_name, data, REG_EXPAND_SZ);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Writes a REG_EXPAND_SZ value from a null-terminated string
|
||
|
* @param key An open or well-known registry key
|
||
|
* @param value_name The name of the registry value whose data is to be updated.
|
||
|
* Can be nullptr to write to the unnamed default registry value.
|
||
|
* @param data The null-terminated string value to write to the specified registry value
|
||
|
* @return HRESULT error code indicating success or failure (does not throw C++ exceptions)
|
||
|
*/
|
||
|
inline HRESULT set_value_expanded_string_nothrow(HKEY key, _In_opt_ PCWSTR value_name, PCWSTR data) WI_NOEXCEPT
|
||
|
{
|
||
|
return ::wil::reg::set_value_expanded_string_nothrow(key, nullptr, value_name, data);
|
||
|
}
|
||
|
|
||
|
#if defined(__WIL_OBJBASE_H_) || defined(WIL_DOXYGEN)
|
||
|
/**
|
||
|
* @brief Writes raw bytes into a registry value under a specified key of the specified type
|
||
|
* @param key An open or well-known registry key
|
||
|
* @param subkey The name of the subkey to append to `key`.
|
||
|
* If `nullptr`, then `key` is used without modification.
|
||
|
* @param value_name The name of the registry value whose data is to be updated.
|
||
|
* Can be nullptr to write to the unnamed default registry value.
|
||
|
* @param type The registry type for the specified registry value to write to - see RegSetValue
|
||
|
* @param value A ::wil::unique_cotaskmem_array_ptr<BYTE> holding the bytes to write into the specified registry value
|
||
|
* @return HRESULT error code indicating success or failure (does not throw C++ exceptions)
|
||
|
*/
|
||
|
inline HRESULT set_value_binary_nothrow(
|
||
|
HKEY key, _In_opt_ PCWSTR subkey, _In_opt_ PCWSTR value_name, uint32_t type, const ::wil::unique_cotaskmem_array_ptr<uint8_t>& value) WI_NOEXCEPT
|
||
|
{
|
||
|
const reg_view_details::reg_view_nothrow regview{key};
|
||
|
RETURN_IF_FAILED(regview.set_value<::wil::unique_cotaskmem_array_ptr<uint8_t>>(subkey, value_name, value, type));
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Writes raw bytes into a registry value under a specified key of the specified type
|
||
|
* @param key An open or well-known registry key
|
||
|
* @param value_name The name of the registry value whose data is to be updated.
|
||
|
* Can be nullptr to write to the unnamed default registry value.
|
||
|
* @param type The registry type for the specified registry value to write to - see RegSetValue
|
||
|
* @param value A ::wil::unique_cotaskmem_array_ptr<BYTE> holding the bytes to write into the specified registry value
|
||
|
* @return HRESULT error code indicating success or failure (does not throw C++ exceptions)
|
||
|
*/
|
||
|
inline HRESULT set_value_binary_nothrow(
|
||
|
HKEY key, _In_opt_ PCWSTR value_name, uint32_t type, const ::wil::unique_cotaskmem_array_ptr<uint8_t>& value) WI_NOEXCEPT
|
||
|
{
|
||
|
return ::wil::reg::set_value_binary_nothrow(key, nullptr, value_name, type, value);
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
#if defined(WIL_ENABLE_EXCEPTIONS)
|
||
|
//
|
||
|
// template <typename T>
|
||
|
// T get_value(...)
|
||
|
//
|
||
|
// - Reads a value under a specified key.
|
||
|
// - Requires a type T to be specified.
|
||
|
// - Throws a std::exception on failure (including wil::ResultException), including registry value not found.
|
||
|
// If you don't want an exception when the value does not exist, use try_get_value(...)
|
||
|
//
|
||
|
// Examples of usage (ensure the code handles a possible std::exception that will be thrown on all errors)
|
||
|
// uint32_t dword_value = wil::reg::get_value<uint32_t>(key, L"subkey", L"dword_value_name");
|
||
|
// uint64_t qword_value = wil::reg::get_value<uint64_t>(key, L"subkey", L"qword_value_name);
|
||
|
// std::wstring string_value = wil::reg::get_value<std::wstring>(key, L"subkey", L"string_value_name");
|
||
|
//
|
||
|
// A subkey is not required if the key is opened where this should write the value:
|
||
|
// uint32_t dword_value = wil::reg::get_value<uint32_t>(key, L"dword_value_name");
|
||
|
// uint64_t qword_value = wil::reg::get_value<uint64_t>(key, L"qword_value_name);
|
||
|
// std::wstring string_value = wil::reg::get_value<std::wstring>(key, L"string_value_name");
|
||
|
//
|
||
|
// The template type does not need to be specified if using functions written for a targeted type
|
||
|
// uint32_t dword_value = wil::reg::get_value_dword(key, L"dword_value_name");
|
||
|
// uint64_t qword_value = wil::reg::get_value_qword(key, L"qword_value_name");
|
||
|
// std::wstring string_value = wil::reg::get_value_string(key, L"string_value_name");
|
||
|
//
|
||
|
// Values with REG_EXPAND_SZ can be read into each of the string types; e.g.:
|
||
|
// std::wstring expanded_string_value = wil::reg::get_value_expanded_string(key, L"string_value_name_with_environment_variables");
|
||
|
//
|
||
|
// Values can be read directly into a vector of bytes - the registry type must be specified; e.g.:
|
||
|
// std::vector<BYTE> data = wil::reg::get_value_binary(key, L"binary_value_name", REG_BINARY);
|
||
|
//
|
||
|
// Multi-string values can be read into a vector<wstring>; e.g.:
|
||
|
// std::vector<std::wstring> multi_string_value = wil::reg::get_value_multistring(key, L"multi_string_value_name");
|
||
|
// for (const auto& sub_string_value : multi_string_value)
|
||
|
// {
|
||
|
// // can read each string parsed from the multi-string
|
||
|
// PCWSTR string_value = sub_string_value.c_str();
|
||
|
// }
|
||
|
//
|
||
|
// Reading REG_SZ and REG_EXPAND_SZ types are done through the below templated get_value_string and get_value_expanded_string functions
|
||
|
// Where the template type is the type to receive the string value
|
||
|
// The default template type is std::wstring, available if the caller has included the STL <string> header
|
||
|
//
|
||
|
// Reading a bstr can be stored in a wil::shared_bstr or wil::unique_bstr - wil::shared_bstr has a c'tor taking a wil::unique_bstr
|
||
|
// wil::unique_bstr unique_value { wil::reg::get_value_string<::wil::unique_bstr>(key, L"string_value_name") };
|
||
|
// wil::shared_bstr shared_value { wil::reg::get_value_string<::wil::shared_bstr>(key, L"string_value_name") };
|
||
|
//
|
||
|
// Reading a cotaskmem string can be stored in a wil::unique_cotaskmem_string or wil::shared_cotaskmem_string
|
||
|
// wil::unique_cotaskmem_string unique_value { wil::reg::get_value_string<wil::unique_cotaskmem_string>(key, L"string_value_name") };
|
||
|
// wil::shared_cotaskmem_string shared_value { wil::reg::get_value_string<wil::shared_cotaskmem_string>(key, L"string_value_name") };
|
||
|
//
|
||
|
// Blocking get_value_string template types that are not already specialized - this gives a much friendlier compiler error message
|
||
|
template <typename T>
|
||
|
T get_value_string(HKEY /*key*/, _In_opt_ PCWSTR /*subkey*/, _In_opt_ PCWSTR /*value_name*/)
|
||
|
{
|
||
|
static_assert(sizeof(T) != sizeof(T), "Unsupported type for get_value_string");
|
||
|
}
|
||
|
|
||
|
template <typename T>
|
||
|
T get_value_string(HKEY /*key*/, _In_opt_ PCWSTR /*value_name*/)
|
||
|
{
|
||
|
static_assert(sizeof(T) != sizeof(T), "Unsupported type for get_value_string");
|
||
|
}
|
||
|
|
||
|
template <typename T>
|
||
|
T get_value_expanded_string(HKEY /*key*/, _In_opt_ PCWSTR /*subkey*/, _In_opt_ PCWSTR /*value_name*/)
|
||
|
{
|
||
|
static_assert(sizeof(T) != sizeof(T), "Unsupported type for get_value_expanded_string");
|
||
|
}
|
||
|
|
||
|
template <typename T>
|
||
|
T get_value_expanded_string(HKEY /*key*/, _In_opt_ PCWSTR /*value_name*/)
|
||
|
{
|
||
|
static_assert(sizeof(T) != sizeof(T), "Unsupported type for get_value_expanded_string");
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Reads a value from a specified key and subkey, deducing registry type from the type parameter T.
|
||
|
* @tparam T The type to read (the registry value type is deduced from T)
|
||
|
* @param key An open or well-known registry key
|
||
|
* @param subkey The name of the subkey to append to `key`.
|
||
|
* If `nullptr`, then `key` is used without modification.
|
||
|
* @param value_name The name of the registry value whose data is to be updated.
|
||
|
* Can be nullptr to read from the unnamed default registry value.
|
||
|
* @return The value read from the registry value of the template type T
|
||
|
* @exception std::exception (including wil::ResultException) will be thrown on all failures, including value not found
|
||
|
*/
|
||
|
template <typename T>
|
||
|
T get_value(HKEY key, _In_opt_ PCWSTR subkey, _In_opt_ PCWSTR value_name)
|
||
|
{
|
||
|
T return_value{};
|
||
|
const reg_view_details::reg_view regview{key};
|
||
|
regview.get_value<T>(subkey, value_name, return_value);
|
||
|
return return_value;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Reads a value under a specified key, deducing registry type from the type parameter T.
|
||
|
* @tparam T The type to read (the registry value type is deduced from T)
|
||
|
* @param key An open or well-known registry key
|
||
|
* @param value_name The name of the registry value whose data is to be updated.
|
||
|
* Can be nullptr to read from the unnamed default registry value.
|
||
|
* @return The value read from the registry value of the template type T
|
||
|
* @exception std::exception (including wil::ResultException) will be thrown on all failures, including value not found
|
||
|
*/
|
||
|
template <typename T>
|
||
|
T get_value(HKEY key, _In_opt_ PCWSTR value_name)
|
||
|
{
|
||
|
return ::wil::reg::get_value<T>(key, nullptr, value_name);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Reads a REG_DWORD value, returning a uint32_t
|
||
|
* @param key An open or well-known registry key
|
||
|
* @param subkey The name of the subkey to append to `key`.
|
||
|
* If `nullptr`, then `key` is used without modification.
|
||
|
* @param value_name The name of the registry value whose data is to be updated.
|
||
|
* Can be nullptr to read from the unnamed default registry value.
|
||
|
* @return The uint32_t value read from the registry
|
||
|
* @exception std::exception (including wil::ResultException) will be thrown on all failures, including value not found
|
||
|
*/
|
||
|
inline uint32_t get_value_dword(HKEY key, _In_opt_ PCWSTR subkey, _In_opt_ PCWSTR value_name)
|
||
|
{
|
||
|
return ::wil::reg::get_value<uint32_t>(key, subkey, value_name);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Reads a REG_DWORD value, returning a uint32_t
|
||
|
* @param key An open or well-known registry key
|
||
|
* @param value_name The name of the registry value whose data is to be updated.
|
||
|
* Can be nullptr to read from the unnamed default registry value.
|
||
|
* @return The uint32_t value read from the registry
|
||
|
* @exception std::exception (including wil::ResultException) will be thrown on all failures, including value not found
|
||
|
*/
|
||
|
inline uint32_t get_value_dword(HKEY key, _In_opt_ PCWSTR value_name)
|
||
|
{
|
||
|
return ::wil::reg::get_value<uint32_t>(key, nullptr, value_name);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Reads a REG_QWORD value, returning a uint64_t
|
||
|
* @param key An open or well-known registry key
|
||
|
* @param subkey The name of the subkey to append to `key`.
|
||
|
* If `nullptr`, then `key` is used without modification.
|
||
|
* @param value_name The name of the registry value whose data is to be updated.
|
||
|
* Can be nullptr to read from the unnamed default registry value.
|
||
|
* @return The uint64_t value read from the registry
|
||
|
* @exception std::exception (including wil::ResultException) will be thrown on all failures, including value not found
|
||
|
*/
|
||
|
inline uint64_t get_value_qword(HKEY key, _In_opt_ PCWSTR subkey, _In_opt_ PCWSTR value_name)
|
||
|
{
|
||
|
return ::wil::reg::get_value<uint64_t>(key, subkey, value_name);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Reads a REG_QWORD value, returning a uint64_t
|
||
|
* @param key An open or well-known registry key
|
||
|
* @param value_name The name of the registry value whose data is to be updated.
|
||
|
* Can be nullptr to read from the unnamed default registry value.
|
||
|
* @return The uint64_t value read from the registry
|
||
|
* @exception std::exception (including wil::ResultException) will be thrown on all failures, including value not found
|
||
|
*/
|
||
|
inline uint64_t get_value_qword(HKEY key, _In_opt_ PCWSTR value_name)
|
||
|
{
|
||
|
return ::wil::reg::get_value<uint64_t>(key, nullptr, value_name);
|
||
|
}
|
||
|
|
||
|
#if defined(_STRING_) || defined(WIL_DOXYGEN)
|
||
|
/**
|
||
|
* @brief Reads a REG_SZ value, returning a std::wstring
|
||
|
* @param key An open or well-known registry key
|
||
|
* @param subkey The name of the subkey to append to `key`.
|
||
|
* If `nullptr`, then `key` is used without modification.
|
||
|
* @param value_name The name of the registry value whose data is to be updated.
|
||
|
* Can be nullptr to read from the unnamed default registry value.
|
||
|
* @return A std::wstring created from the string value read from the registry
|
||
|
* @exception std::exception (including wil::ResultException) will be thrown on all failures, including value not found
|
||
|
*/
|
||
|
inline ::std::wstring get_value_string(HKEY key, _In_opt_ PCWSTR subkey, _In_opt_ PCWSTR value_name)
|
||
|
{
|
||
|
return ::wil::reg::get_value<::std::wstring>(key, subkey, value_name);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Reads a REG_SZ value, returning a std::wstring
|
||
|
* @param key An open or well-known registry key
|
||
|
* @param value_name The name of the registry value whose data is to be updated.
|
||
|
* Can be nullptr to read from the unnamed default registry value.
|
||
|
* @return A std::wstring created from the string value read from the registry
|
||
|
* @exception std::exception (including wil::ResultException) will be thrown on all failures, including value not found
|
||
|
*/
|
||
|
inline ::std::wstring get_value_string(HKEY key, _In_opt_ PCWSTR value_name)
|
||
|
{
|
||
|
return ::wil::reg::get_value<::std::wstring>(key, nullptr, value_name);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Reads a REG_SZ value, returning a std::wstring
|
||
|
* @param key An open or well-known registry key
|
||
|
* @param subkey The name of the subkey to append to `key`.
|
||
|
* If `nullptr`, then `key` is used without modification.
|
||
|
* @param value_name The name of the registry value whose data is to be updated.
|
||
|
* Can be nullptr to read from the unnamed default registry value.
|
||
|
* @return A std::wstring created from the string value read from the registry
|
||
|
* @exception std::exception (including wil::ResultException) will be thrown on all failures, including value not found
|
||
|
*/
|
||
|
template <>
|
||
|
inline ::std::wstring get_value_string<::std::wstring>(HKEY key, _In_opt_ PCWSTR subkey, _In_opt_ PCWSTR value_name)
|
||
|
{
|
||
|
return ::wil::reg::get_value<::std::wstring>(key, subkey, value_name);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Reads a REG_SZ value, returning a std::wstring
|
||
|
* @param key An open or well-known registry key
|
||
|
* @param value_name The name of the registry value whose data is to be updated.
|
||
|
* Can be nullptr to read from the unnamed default registry value.
|
||
|
* @return A std::wstring created from the string value read from the registry
|
||
|
* @exception std::exception (including wil::ResultException) will be thrown on all failures, including value not found
|
||
|
*/
|
||
|
template <>
|
||
|
inline ::std::wstring get_value_string<::std::wstring>(HKEY key, _In_opt_ PCWSTR value_name)
|
||
|
{
|
||
|
return ::wil::reg::get_value<::std::wstring>(key, nullptr, value_name);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Reads a REG_EXPAND_SZ value, returning a std::wstring
|
||
|
* @param key An open or well-known registry key
|
||
|
* @param subkey The name of the subkey to append to `key`.
|
||
|
* If `nullptr`, then `key` is used without modification.
|
||
|
* @param value_name The name of the registry value whose data is to be updated.
|
||
|
* Can be nullptr to read from the unnamed default registry value.
|
||
|
* @return A std::wstring created from the string value read from the registry,
|
||
|
* with environment variables expanded, as though passed through ExpandEnvironmentStringsW
|
||
|
* @exception std::exception (including wil::ResultException) will be thrown on all failures, including value not found
|
||
|
*/
|
||
|
inline ::std::wstring get_value_expanded_string(HKEY key, _In_opt_ PCWSTR subkey, _In_opt_ PCWSTR value_name)
|
||
|
{
|
||
|
::std::wstring value;
|
||
|
const reg_view_details::reg_view regview{key};
|
||
|
regview.get_value(subkey, value_name, value, REG_EXPAND_SZ);
|
||
|
return value;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Reads a REG_EXPAND_SZ value, returning a std::wstring
|
||
|
* @param key An open or well-known registry key
|
||
|
* @param value_name The name of the registry value whose data is to be updated.
|
||
|
* Can be nullptr to read from the unnamed default registry value.
|
||
|
* @return A std::wstring created from the string value read from the registry,
|
||
|
* with environment variables expanded, as though passed through ExpandEnvironmentStringsW
|
||
|
* @exception std::exception (including wil::ResultException) will be thrown on all failures, including value not found
|
||
|
*/
|
||
|
inline ::std::wstring get_value_expanded_string(HKEY key, _In_opt_ PCWSTR value_name)
|
||
|
{
|
||
|
return ::wil::reg::get_value_expanded_string(key, nullptr, value_name);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Reads a REG_EXPAND_SZ value, returning a std::wstring
|
||
|
* @param key An open or well-known registry key
|
||
|
* @param subkey The name of the subkey to append to `key`.
|
||
|
* If `nullptr`, then `key` is used without modification.
|
||
|
* @param value_name The name of the registry value whose data is to be updated.
|
||
|
* Can be nullptr to read from the unnamed default registry value.
|
||
|
* @return A std::wstring created from the string value read from the registry,
|
||
|
* with environment variables expanded, as though passed through ExpandEnvironmentStringsW
|
||
|
* @exception std::exception (including wil::ResultException) will be thrown on all failures, including value not found
|
||
|
*/
|
||
|
template <>
|
||
|
inline ::std::wstring get_value_expanded_string<::std::wstring>(HKEY key, _In_opt_ PCWSTR subkey, _In_opt_ PCWSTR value_name)
|
||
|
{
|
||
|
return ::wil::reg::get_value_expanded_string(key, subkey, value_name);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Reads a REG_EXPAND_SZ value, returning a std::wstring
|
||
|
* @param key An open or well-known registry key
|
||
|
* @param value_name The name of the registry value whose data is to be updated.
|
||
|
* Can be nullptr to read from the unnamed default registry value.
|
||
|
* @return A std::wstring created from the string value read from the registry,
|
||
|
* with environment variables expanded, as though passed through ExpandEnvironmentStringsW
|
||
|
* @exception std::exception (including wil::ResultException) will be thrown on all failures, including value not found
|
||
|
*/
|
||
|
template <>
|
||
|
inline ::std::wstring get_value_expanded_string<::std::wstring>(HKEY key, _In_opt_ PCWSTR value_name)
|
||
|
{
|
||
|
return ::wil::reg::get_value_expanded_string(key, nullptr, value_name);
|
||
|
}
|
||
|
#endif // #if defined(_STRING_)
|
||
|
|
||
|
#if defined(__WIL_OLEAUTO_H_) || defined(WIL_DOXYGEN)
|
||
|
/**
|
||
|
* @brief Reads a REG_SZ value, returning a wil::unique_bstr
|
||
|
* @param key An open or well-known registry key
|
||
|
* @param subkey The name of the subkey to append to `key`.
|
||
|
* If `nullptr`, then `key` is used without modification.
|
||
|
* @param value_name The name of the registry value whose data is to be updated.
|
||
|
* Can be nullptr to read from the unnamed default registry value.
|
||
|
* @return A wil::unique_bstr created from the string value read from the registry
|
||
|
* @exception std::exception (including wil::ResultException) will be thrown on all failures, including value not found
|
||
|
*/
|
||
|
template <>
|
||
|
inline ::wil::unique_bstr get_value_string<::wil::unique_bstr>(HKEY key, _In_opt_ PCWSTR subkey, _In_opt_ PCWSTR value_name)
|
||
|
{
|
||
|
return ::wil::reg::get_value<::wil::unique_bstr>(key, subkey, value_name);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Reads a REG_SZ value, returning a wil::unique_bstr
|
||
|
* @param key An open or well-known registry key
|
||
|
* @param value_name The name of the registry value whose data is to be updated.
|
||
|
* Can be nullptr to read from the unnamed default registry value.
|
||
|
* @return A wil::unique_bstr created from the string value read from the registry
|
||
|
* @exception std::exception (including wil::ResultException) will be thrown on all failures, including value not found
|
||
|
*/
|
||
|
template <>
|
||
|
inline ::wil::unique_bstr get_value_string<::wil::unique_bstr>(HKEY key, _In_opt_ PCWSTR value_name)
|
||
|
{
|
||
|
return ::wil::reg::get_value<::wil::unique_bstr>(key, nullptr, value_name);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Reads a REG_EXPAND_SZ value, returning a wil::unique_bstr
|
||
|
* @param key An open or well-known registry key
|
||
|
* @param subkey The name of the subkey to append to `key`.
|
||
|
* If `nullptr`, then `key` is used without modification.
|
||
|
* @param value_name The name of the registry value whose data is to be updated.
|
||
|
* Can be nullptr to read from the unnamed default registry value.
|
||
|
* @return A wil::unique_bstr created from the string value read from the registry,
|
||
|
* with environment variables expanded, as though passed through ExpandEnvironmentStringsW
|
||
|
* @exception std::exception (including wil::ResultException) will be thrown on all failures, including value not found
|
||
|
*/
|
||
|
template <>
|
||
|
inline ::wil::unique_bstr get_value_expanded_string<::wil::unique_bstr>(HKEY key, _In_opt_ PCWSTR subkey, _In_opt_ PCWSTR value_name)
|
||
|
{
|
||
|
::wil::unique_bstr value;
|
||
|
const reg_view_details::reg_view regview{key};
|
||
|
regview.get_value(subkey, value_name, value, REG_EXPAND_SZ);
|
||
|
return value;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Reads a REG_EXPAND_SZ value, returning a wil::unique_bstr
|
||
|
* @param key An open or well-known registry key
|
||
|
* @param value_name The name of the registry value whose data is to be updated.
|
||
|
* Can be nullptr to read from the unnamed default registry value.
|
||
|
* @return A wil::unique_bstr created from the string value read from the registry,
|
||
|
* with environment variables expanded, as though passed through ExpandEnvironmentStringsW
|
||
|
* @exception std::exception (including wil::ResultException) will be thrown on all failures, including value not found
|
||
|
*/
|
||
|
template <>
|
||
|
inline ::wil::unique_bstr get_value_expanded_string<::wil::unique_bstr>(HKEY key, _In_opt_ PCWSTR value_name)
|
||
|
{
|
||
|
return ::wil::reg::get_value_expanded_string<::wil::unique_bstr>(key, nullptr, value_name);
|
||
|
}
|
||
|
|
||
|
#if defined(__WIL_OLEAUTO_H_STL) || defined(WIL_DOXYGEN)
|
||
|
/**
|
||
|
* @brief Reads a REG_SZ value, returning a wil::shared_bstr
|
||
|
* @param key An open or well-known registry key
|
||
|
* @param subkey The name of the subkey to append to `key`.
|
||
|
* If `nullptr`, then `key` is used without modification.
|
||
|
* @param value_name The name of the registry value whose data is to be updated.
|
||
|
* Can be nullptr to read from the unnamed default registry value.
|
||
|
* @return A wil::shared_bstr created from the string value read from the registry
|
||
|
* @exception std::exception (including wil::ResultException) will be thrown on all failures, including value not found
|
||
|
*/
|
||
|
template <>
|
||
|
inline ::wil::shared_bstr get_value_string<::wil::shared_bstr>(HKEY key, _In_opt_ PCWSTR subkey, _In_opt_ PCWSTR value_name)
|
||
|
{
|
||
|
return ::wil::reg::get_value<::wil::shared_bstr>(key, subkey, value_name);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Reads a REG_SZ value, returning a wil::shared_bstr
|
||
|
* @param key An open or well-known registry key
|
||
|
* @param value_name The name of the registry value whose data is to be updated.
|
||
|
* Can be nullptr to read from the unnamed default registry value.
|
||
|
* @return A wil::shared_bstr created from the string value read from the registry
|
||
|
* @exception std::exception (including wil::ResultException) will be thrown on all failures, including value not found
|
||
|
*/
|
||
|
template <>
|
||
|
inline ::wil::shared_bstr get_value_string<::wil::shared_bstr>(HKEY key, _In_opt_ PCWSTR value_name)
|
||
|
{
|
||
|
return ::wil::reg::get_value<::wil::shared_bstr>(key, nullptr, value_name);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Reads a REG_EXPAND_SZ value, returning a wil::unique_bstr
|
||
|
* @param key An open or well-known registry key
|
||
|
* @param subkey The name of the subkey to append to `key`.
|
||
|
* If `nullptr`, then `key` is used without modification.
|
||
|
* @param value_name The name of the registry value whose data is to be updated.
|
||
|
* Can be nullptr to read from the unnamed default registry value.
|
||
|
* @return A wil::shared_bstr created from the string value read from the registry,
|
||
|
* with environment variables expanded, as though passed through ExpandEnvironmentStringsW
|
||
|
* @exception std::exception (including wil::ResultException) will be thrown on all failures, including value not found
|
||
|
*/
|
||
|
template <>
|
||
|
inline ::wil::shared_bstr get_value_expanded_string<::wil::shared_bstr>(HKEY key, _In_opt_ PCWSTR subkey, _In_opt_ PCWSTR value_name)
|
||
|
{
|
||
|
::wil::shared_bstr value;
|
||
|
const reg_view_details::reg_view regview{key};
|
||
|
regview.get_value(subkey, value_name, value, REG_EXPAND_SZ);
|
||
|
return value;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Reads a REG_EXPAND_SZ value, returning a wil::shared_bstr
|
||
|
* @param key An open or well-known registry key
|
||
|
* @param value_name The name of the registry value whose data is to be updated.
|
||
|
* Can be nullptr to read from the unnamed default registry value.
|
||
|
* @return A wil::shared_bstr created from the string value read from the registry,
|
||
|
* with environment variables expanded, as though passed through ExpandEnvironmentStringsW
|
||
|
* @exception std::exception (including wil::ResultException) will be thrown on all failures, including value not found
|
||
|
*/
|
||
|
template <>
|
||
|
inline ::wil::shared_bstr get_value_expanded_string<::wil::shared_bstr>(HKEY key, _In_opt_ PCWSTR value_name)
|
||
|
{
|
||
|
return ::wil::reg::get_value_expanded_string<::wil::shared_bstr>(key, nullptr, value_name);
|
||
|
}
|
||
|
#endif // #if defined(__WIL_OLEAUTO_H_STL)
|
||
|
#endif // #if defined(__WIL_OLEAUTO_H_)
|
||
|
|
||
|
#if defined(__WIL_OBJBASE_H_) || defined(WIL_DOXYGEN)
|
||
|
/**
|
||
|
* @brief Reads a REG_SZ value, returning a wil::unique_cotaskmem_string
|
||
|
* @param key An open or well-known registry key
|
||
|
* @param subkey The name of the subkey to append to `key`.
|
||
|
* If `nullptr`, then `key` is used without modification.
|
||
|
* @param value_name The name of the registry value whose data is to be updated.
|
||
|
* Can be nullptr to read from the unnamed default registry value.
|
||
|
* @return A wil::unique_cotaskmem_string created from the string value read from the registry
|
||
|
* @exception std::exception (including wil::ResultException) will be thrown on all failures, including value not found
|
||
|
*/
|
||
|
template <>
|
||
|
inline ::wil::unique_cotaskmem_string get_value_string<::wil::unique_cotaskmem_string>(HKEY key, _In_opt_ PCWSTR subkey, _In_opt_ PCWSTR value_name)
|
||
|
{
|
||
|
return ::wil::reg::get_value<::wil::unique_cotaskmem_string>(key, subkey, value_name);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Reads a REG_SZ value, returning a wil::unique_cotaskmem_string
|
||
|
* @param key An open or well-known registry key
|
||
|
* @param value_name The name of the registry value whose data is to be updated.
|
||
|
* Can be nullptr to read from the unnamed default registry value.
|
||
|
* @return A wil::unique_cotaskmem_string created from the string value read from the registry
|
||
|
* @exception std::exception (including wil::ResultException) will be thrown on all failures, including value not found
|
||
|
*/
|
||
|
template <>
|
||
|
inline ::wil::unique_cotaskmem_string get_value_string<::wil::unique_cotaskmem_string>(HKEY key, _In_opt_ PCWSTR value_name)
|
||
|
{
|
||
|
return ::wil::reg::get_value<::wil::unique_cotaskmem_string>(key, nullptr, value_name);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Reads a REG_EXPAND_SZ value, returning a wil::unique_cotaskmem_string
|
||
|
* @param key An open or well-known registry key
|
||
|
* @param subkey The name of the subkey to append to `key`.
|
||
|
* If `nullptr`, then `key` is used without modification.
|
||
|
* @param value_name The name of the registry value whose data is to be updated.
|
||
|
* Can be nullptr to read from the unnamed default registry value.
|
||
|
* @return A wil::unique_cotaskmem_string created from the string value read from the registry,
|
||
|
* with environment variables expanded, as though passed through ExpandEnvironmentStringsW
|
||
|
* @exception std::exception (including wil::ResultException) will be thrown on all failures, including value not found
|
||
|
*/
|
||
|
template <>
|
||
|
inline ::wil::unique_cotaskmem_string get_value_expanded_string<::wil::unique_cotaskmem_string>(
|
||
|
HKEY key, _In_opt_ PCWSTR subkey, _In_opt_ PCWSTR value_name)
|
||
|
{
|
||
|
::wil::unique_cotaskmem_string value;
|
||
|
const reg_view_details::reg_view regview{key};
|
||
|
regview.get_value(subkey, value_name, value, REG_EXPAND_SZ);
|
||
|
return value;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Reads a REG_EXPAND_SZ value, returning a wil::unique_cotaskmem_string
|
||
|
* @param key An open or well-known registry key
|
||
|
* @param value_name The name of the registry value whose data is to be updated.
|
||
|
* Can be nullptr to read from the unnamed default registry value.
|
||
|
* @return A wil::unique_cotaskmem_string created from the string value read from the registry,
|
||
|
* with environment variables expanded, as though passed through ExpandEnvironmentStringsW
|
||
|
* @exception std::exception (including wil::ResultException) will be thrown on all failures, including value not found
|
||
|
*/
|
||
|
template <>
|
||
|
inline ::wil::unique_cotaskmem_string get_value_expanded_string<::wil::unique_cotaskmem_string>(HKEY key, _In_opt_ PCWSTR value_name)
|
||
|
{
|
||
|
return wil::reg::get_value_expanded_string<::wil::unique_cotaskmem_string>(key, nullptr, value_name);
|
||
|
}
|
||
|
|
||
|
#if defined(__WIL_OBJBASE_H_STL) || defined(WIL_DOXYGEN)
|
||
|
/**
|
||
|
* @brief Reads a REG_SZ value, returning a wil::shared_cotaskmem_string
|
||
|
* @param key An open or well-known registry key
|
||
|
* @param subkey The name of the subkey to append to `key`.
|
||
|
* If `nullptr`, then `key` is used without modification.
|
||
|
* @param value_name The name of the registry value whose data is to be updated.
|
||
|
* Can be nullptr to read from the unnamed default registry value.
|
||
|
* @return A wil::shared_cotaskmem_string created from the string value read from the registry
|
||
|
* @exception std::exception (including wil::ResultException) will be thrown on all failures, including value not found
|
||
|
*/
|
||
|
template <>
|
||
|
inline ::wil::shared_cotaskmem_string get_value_string<::wil::shared_cotaskmem_string>(HKEY key, _In_opt_ PCWSTR subkey, _In_opt_ PCWSTR value_name)
|
||
|
{
|
||
|
return ::wil::reg::get_value<::wil::shared_cotaskmem_string>(key, subkey, value_name);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Reads a REG_SZ value, returning a wil::shared_cotaskmem_string
|
||
|
* @param key An open or well-known registry key
|
||
|
* @param value_name The name of the registry value whose data is to be updated.
|
||
|
* Can be nullptr to read from the unnamed default registry value.
|
||
|
* @return A wil::shared_cotaskmem_string created from the string value read from the registry
|
||
|
* @exception std::exception (including wil::ResultException) will be thrown on all failures, including value not found
|
||
|
*/
|
||
|
template <>
|
||
|
inline ::wil::shared_cotaskmem_string get_value_string<::wil::shared_cotaskmem_string>(HKEY key, _In_opt_ PCWSTR value_name)
|
||
|
{
|
||
|
return ::wil::reg::get_value<::wil::shared_cotaskmem_string>(key, nullptr, value_name);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Reads a REG_EXPAND_SZ value, returning a wil::shared_cotaskmem_string
|
||
|
* @param key An open or well-known registry key
|
||
|
* @param subkey The name of the subkey to append to `key`.
|
||
|
* If `nullptr`, then `key` is used without modification.
|
||
|
* @param value_name The name of the registry value whose data is to be updated.
|
||
|
* Can be nullptr to read from the unnamed default registry value.
|
||
|
* @return A wil::shared_cotaskmem_string created from the string value read from the registry,
|
||
|
* with environment variables expanded, as though passed through ExpandEnvironmentStringsW
|
||
|
* @exception std::exception (including wil::ResultException) will be thrown on all failures, including value not found
|
||
|
*/
|
||
|
template <>
|
||
|
inline ::wil::shared_cotaskmem_string get_value_expanded_string<::wil::shared_cotaskmem_string>(
|
||
|
HKEY key, _In_opt_ PCWSTR subkey, _In_opt_ PCWSTR value_name)
|
||
|
{
|
||
|
::wil::shared_cotaskmem_string value;
|
||
|
const reg_view_details::reg_view regview{key};
|
||
|
regview.get_value(subkey, value_name, value, REG_EXPAND_SZ);
|
||
|
return value;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Reads a REG_EXPAND_SZ value, returning a wil::shared_cotaskmem_string
|
||
|
* @param key An open or well-known registry key
|
||
|
* @param value_name The name of the registry value whose data is to be updated.
|
||
|
* Can be nullptr to read from the unnamed default registry value.
|
||
|
* @return A wil::shared_cotaskmem_string created from the string value read from the registry,
|
||
|
* with environment variables expanded, as though passed through ExpandEnvironmentStringsW
|
||
|
* @exception std::exception (including wil::ResultException) will be thrown on all failures, including value not found
|
||
|
*/
|
||
|
template <>
|
||
|
inline ::wil::shared_cotaskmem_string get_value_expanded_string<::wil::shared_cotaskmem_string>(HKEY key, _In_opt_ PCWSTR value_name)
|
||
|
{
|
||
|
return wil::reg::get_value_expanded_string<::wil::shared_cotaskmem_string>(key, nullptr, value_name);
|
||
|
}
|
||
|
#endif // #if defined(__WIL_OBJBASE_H_STL)
|
||
|
#endif // defined(__WIL_OBJBASE_H_)
|
||
|
|
||
|
#if defined(_VECTOR_) || defined(WIL_DOXYGEN)
|
||
|
/**
|
||
|
* @brief Reads a registry value of the specified type, returning a std::vector<BYTE>
|
||
|
* @param key An open or well-known registry key
|
||
|
* @param subkey The name of the subkey to append to `key`.
|
||
|
* If `nullptr`, then `key` is used without modification.
|
||
|
* @param value_name The name of the registry value whose data is to be updated.
|
||
|
* Can be nullptr to read from the unnamed default registry value.
|
||
|
* @param type The registry type for the specified registry value to read from - see RegGetValueW
|
||
|
* @return A std::vector<BYTE> containing the bytes of the specified registry value
|
||
|
* @exception std::exception (including wil::ResultException) will be thrown on all failures, including value not found
|
||
|
*/
|
||
|
inline ::std::vector<uint8_t> get_value_binary(HKEY key, _In_opt_ PCWSTR subkey, _In_opt_ PCWSTR value_name, uint32_t type)
|
||
|
{
|
||
|
::std::vector<uint8_t> return_value{};
|
||
|
const reg_view_details::reg_view regview{key};
|
||
|
regview.get_value(subkey, value_name, return_value, type);
|
||
|
return return_value;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Reads a registry value of the specified type, returning a std::vector<BYTE>
|
||
|
* @param key An open or well-known registry key
|
||
|
* @param value_name The name of the registry value whose data is to be updated.
|
||
|
* Can be nullptr to read from the unnamed default registry value.
|
||
|
* @param type The registry type for the specified registry value to read from - see RegGetValueW
|
||
|
* @return A std::vector<BYTE> containing the bytes of the specified registry value
|
||
|
* @exception std::exception (including wil::ResultException) will be thrown on all failures, including value not found
|
||
|
*/
|
||
|
inline ::std::vector<uint8_t> get_value_binary(HKEY key, _In_opt_ PCWSTR value_name, uint32_t type)
|
||
|
{
|
||
|
return ::wil::reg::get_value_binary(key, nullptr, value_name, type);
|
||
|
}
|
||
|
#endif // #if defined(_VECTOR_)
|
||
|
|
||
|
#if (defined(_VECTOR_) && defined(_STRING_)) || defined(WIL_DOXYGEN)
|
||
|
/**
|
||
|
* @brief Reads a REG_MULTI_SZ value, returning a std::vector<std::wstring>
|
||
|
* @param key An open or well-known registry key
|
||
|
* @param subkey The name of the subkey to append to `key`.
|
||
|
* If `nullptr`, then `key` is used without modification.
|
||
|
* @param value_name The name of the registry value whose data is to be updated.
|
||
|
* Can be nullptr to read from the unnamed default registry value.
|
||
|
* @return A vector of strings read from the REG_MULTI_SZ. Note: embedded nulls will be read as empty strings. See remarks.
|
||
|
* @exception std::exception (including wil::ResultException) will be thrown on all failures, including value not found
|
||
|
*
|
||
|
* @remark Note that will return empty strings for embedded nulls - it won't stop at the first double-null character
|
||
|
* e.g. a REG_MULTI_SZ of L"string1\0\0string2\0\0string3\0\0"
|
||
|
* returns a vector of size 5: L"string1", empty-string, L"string2", empty-string, L"string3"
|
||
|
*/
|
||
|
template <>
|
||
|
inline ::std::vector<::std::wstring> get_value<::std::vector<::std::wstring>>(HKEY key, _In_opt_ PCWSTR subkey, _In_opt_ PCWSTR value_name)
|
||
|
{
|
||
|
::std::vector<::std::wstring> return_value;
|
||
|
::std::vector<uint8_t> rawData{::wil::reg::get_value_binary(key, subkey, value_name, REG_MULTI_SZ)};
|
||
|
if (!rawData.empty())
|
||
|
{
|
||
|
auto* const begin = reinterpret_cast<wchar_t*>(rawData.data());
|
||
|
auto* const end = begin + rawData.size() / sizeof(wchar_t);
|
||
|
return_value = ::wil::reg::reg_view_details::get_wstring_vector_from_multistring(begin, end);
|
||
|
}
|
||
|
|
||
|
return return_value;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Reads a REG_MULTI_SZ value, returning a std::vector<std::wstring>
|
||
|
* @param key An open or well-known registry key
|
||
|
* @param value_name The name of the registry value whose data is to be updated.
|
||
|
* Can be nullptr to read from the unnamed default registry value.
|
||
|
* @return A vector of strings read from the REG_MULTI_SZ. Note: embedded nulls will be read as empty strings. See remarks.
|
||
|
* @exception std::exception (including wil::ResultException) will be thrown on all failures, including value not found
|
||
|
*
|
||
|
* @remark Note that will return empty strings for embedded nulls - it won't stop at the first double-null character
|
||
|
* e.g. a REG_MULTI_SZ of L"string1\0\0string2\0\0string3\0\0"
|
||
|
* returns a vector of size 5: L"string1", empty-string, L"string2", empty-string, L"string3"
|
||
|
*/
|
||
|
template <>
|
||
|
inline ::std::vector<::std::wstring> get_value<::std::vector<::std::wstring>>(HKEY key, _In_opt_ PCWSTR value_name)
|
||
|
{
|
||
|
return ::wil::reg::get_value<::std::vector<::std::wstring>>(key, nullptr, value_name);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Reads a REG_MULTI_SZ value, returning a std::vector<std::wstring>
|
||
|
* @param key An open or well-known registry key
|
||
|
* @param subkey The name of the subkey to append to `key`.
|
||
|
* If `nullptr`, then `key` is used without modification.
|
||
|
* @param value_name The name of the registry value whose data is to be updated.
|
||
|
* Can be nullptr to read from the unnamed default registry value.
|
||
|
* @return A vector of strings read from the REG_MULTI_SZ. Note: embedded nulls will be read as empty strings. See remarks.
|
||
|
* @exception std::exception (including wil::ResultException) will be thrown on all failures, including value not found
|
||
|
*
|
||
|
* @remark Note that will return empty strings for embedded nulls - it won't stop at the first double-null character
|
||
|
* e.g. a REG_MULTI_SZ of L"string1\0\0string2\0\0string3\0\0"
|
||
|
* returns a vector of size 5: L"string1", empty-string, L"string2", empty-string, L"string3"
|
||
|
*/
|
||
|
inline ::std::vector<::std::wstring> get_value_multistring(HKEY key, _In_opt_ PCWSTR subkey, _In_opt_ PCWSTR value_name)
|
||
|
{
|
||
|
return ::wil::reg::get_value<::std::vector<::std::wstring>>(key, subkey, value_name);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Reads a REG_MULTI_SZ value, returning a std::vector<std::wstring>
|
||
|
* @param key An open or well-known registry key
|
||
|
* @param value_name The name of the registry value whose data is to be updated.
|
||
|
* Can be nullptr to read from the unnamed default registry value.
|
||
|
* @return A vector of strings read from the REG_MULTI_SZ. Note: embedded nulls will be read as empty strings. See remarks.
|
||
|
* @exception std::exception (including wil::ResultException) will be thrown on all failures, including value not found
|
||
|
*
|
||
|
* @remark Note that will return empty strings for embedded nulls - it won't stop at the first double-null character
|
||
|
* e.g. a REG_MULTI_SZ of L"string1\0\0string2\0\0string3\0\0"
|
||
|
* returns a vector of size 5: L"string1", empty-string, L"string2", empty-string, L"string3"
|
||
|
*/
|
||
|
inline ::std::vector<::std::wstring> get_value_multistring(HKEY key, _In_opt_ PCWSTR value_name)
|
||
|
{
|
||
|
return ::wil::reg::get_value<::std::vector<::std::wstring>>(key, nullptr, value_name);
|
||
|
}
|
||
|
#endif // #if defined(_VECTOR_) && defined(_STRING_)
|
||
|
|
||
|
#if (defined(_OPTIONAL_) && defined(__cpp_lib_optional)) || defined(WIL_DOXYGEN)
|
||
|
//
|
||
|
// template <typename T>
|
||
|
// void try_get_value(...)
|
||
|
//
|
||
|
// - Reads a value under a specified key and subkey, deducing registry type from the type parameter T.
|
||
|
// - throws a std::exception on failure (including wil::ResultException), except if the registry value was not found
|
||
|
// returns a std::nullopt if the registry value is not found
|
||
|
//
|
||
|
// Examples using the returned std::optional<uint32_t>
|
||
|
// - Caller should ensure the code handles a possible std::exception that will be thrown on all errors except value not found
|
||
|
//
|
||
|
// std::optional<uint32_t> opt_dword_value = wil::reg::try_get_value<uint32_t>(key, L"dword_value_name");
|
||
|
// if (opt_dword_value.has_value())
|
||
|
// {
|
||
|
// // opt_dword_value.value() returns the uint32_t read from the registry
|
||
|
// }
|
||
|
// else
|
||
|
// {
|
||
|
// // the registry value did not exist
|
||
|
// }
|
||
|
// // if the caller wants to apply a default value of 0, they can call value_or()
|
||
|
// uint32_t opt_dword_value = wil::reg::try_get_value<uint32_t>(key, L"dword_value_name").value_or(0);
|
||
|
//
|
||
|
// Examples using the returned std::optional<std::wstring>
|
||
|
// std::optional<std::wstring> opt_string_value = wil::reg::try_get_value_string(key, L"string_value_name");
|
||
|
// if (opt_string_value.has_value())
|
||
|
// {
|
||
|
// // opt_string_value.value() returns the std::wstring read from the registry
|
||
|
// // the below avoids copying the std::wstring as value() here returns a std::wstring&
|
||
|
// PCWSTR string_value = opt_string_value.value().c_str();
|
||
|
// }
|
||
|
// else
|
||
|
// {
|
||
|
// // the registry value did not exist
|
||
|
// }
|
||
|
//
|
||
|
// // if the caller wants to apply a default value of L"default", they can call value_or()
|
||
|
// // note that std::optional only attempts to construct a std::wstring for L"default" if the std::optional is empty (std::nullopt)
|
||
|
// // thus only allocating a new std::wstring for the default value when it's needed
|
||
|
// std::optional<std::wstring> opt_string_value = wil::reg::try_get_value_string(key, L"string_value_name").value_or(L"default");
|
||
|
//
|
||
|
// Examples of usage:
|
||
|
// std::optional<uint32_t> opt_dword_value = wil::reg::try_get_value<uint32_t>(key, L"subkey", L"dword_value_name");
|
||
|
// std::optional<uint64_t> opt_qword_value = wil::reg::try_get_value<uint64_t>(key, L"subkey", L"qword_value_name);
|
||
|
// std::optional<std::wstring> opt_string_value = wil::reg::try_get_value<std::wstring>(key, L"subkey", L"string_value_name");
|
||
|
//
|
||
|
// A subkey is not required if the key is opened where this should write the value; e.g.
|
||
|
// std::optional<uint32_t> opt_dword_value = wil::reg::try_get_value<uint32_t>(key, L"dword_value_name");
|
||
|
// std::optional<uint64_t> opt_qword_value = wil::reg::try_get_value<uint64_t>(key, L"qword_value_name);
|
||
|
// std::optional<std::wstring> opt_string_value = wil::reg::try_get_value<std::wstring>(key, L"string_value_name");
|
||
|
//
|
||
|
// The template type does not need to be specified if using functions written for a targeted type; e.g.
|
||
|
// std::optional<uint32_t> opt_dword_value = wil::reg::try_get_value_dword(key, L"dword_value_name");
|
||
|
// std::optional<uint64_t> opt_qword_value = wil::reg::try_get_value_qword(key, L"qword_value_name");
|
||
|
// std::optional<std::wstring> opt_string_value = wil::reg::try_get_value_string(key, L"string_value_name");
|
||
|
//
|
||
|
// Values with REG_EXPAND_SZ can be read into each of the string types; e.g.:
|
||
|
// std::optional<std::wstring> opt_expanded_string_value = wil::reg::try_get_value_expanded_string(key, L"string_value_name_with_environment_variables");
|
||
|
//
|
||
|
// Values can be read directly into a vector of bytes - the registry type must be specified; e.g.:
|
||
|
// std::optional<std::vector<BYTE>> opt_data = wil::reg::try_get_value_binary(key, L"binary_value_name", REG_BINARY);
|
||
|
//
|
||
|
// Multi-string values can be read into a std::vector<std::wstring>; e.g.:
|
||
|
// std::optional<::std::vector<::std::wstring>> try_get_value_multistring(key, L"multi_string_value_name");
|
||
|
// See the definition of try_get_value_multistring before for usage guidance
|
||
|
//
|
||
|
// Reading REG_SZ and REG_EXPAND_SZ types are done through the below templated try_get_value_string and try_get_value_expanded_string functions
|
||
|
// Where the template type is the type to receive the string value
|
||
|
// The default template type is std::wstring, available if the caller has included the STL <string> header
|
||
|
//
|
||
|
// Reading a bstr is returned in a std::optional<wil::shared_bstr> - because wil::unique_bstr cannot be copied and thus is difficult to work with a std::optional
|
||
|
// std::optional<wil::shared_bstr> shared_value { wil::reg::try_get_value_string<::wil::shared_bstr>(key, L"string_value_name") };
|
||
|
//
|
||
|
// Reading a cotaskmem string is returned in a std::optional<wil::shared_cotaskmem_string> - because wil::unique_cotaskmem_string cannot be copied and thus is difficult to work with a std::optional
|
||
|
// std::optional<wil::shared_cotaskmem_string> opt_shared_value { wil::reg::try_get_value_string<wil::shared_cotaskmem_string>(key, L"string_value_name") };
|
||
|
//
|
||
|
// Blocking try_get_value_string template types that are not already specialized - this gives a much friendlier compiler error message
|
||
|
template <typename T>
|
||
|
::std::optional<T> try_get_value_string(HKEY /*key*/, _In_opt_ PCWSTR /*subkey*/, _In_opt_ PCWSTR /*value_name*/)
|
||
|
{
|
||
|
static_assert(sizeof(T) != sizeof(T), "Unsupported type for try_get_value_string");
|
||
|
}
|
||
|
|
||
|
template <typename T>
|
||
|
::std::optional<T> try_get_value_string(HKEY /*key*/, _In_opt_ PCWSTR /*value_name*/)
|
||
|
{
|
||
|
static_assert(sizeof(T) != sizeof(T), "Unsupported type for try_get_value_string");
|
||
|
}
|
||
|
|
||
|
template <typename T>
|
||
|
::std::optional<T> try_get_value_expanded_string(HKEY /*key*/, _In_opt_ PCWSTR /*subkey*/, _In_opt_ PCWSTR /*value_name*/)
|
||
|
{
|
||
|
static_assert(sizeof(T) != sizeof(T), "Unsupported type for try_get_value_expanded_string");
|
||
|
}
|
||
|
|
||
|
template <typename T>
|
||
|
::std::optional<T> try_get_value_expanded_string(HKEY /*key*/, _In_opt_ PCWSTR /*value_name*/)
|
||
|
{
|
||
|
static_assert(sizeof(T) != sizeof(T), "Unsupported type for try_get_value_expanded_string");
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Attempts to read a value under a specified key and subkey, returning in a std::optional, deducing registry type from
|
||
|
* the type parameter T.
|
||
|
* @tparam T The type to read, which will be placed into a std::optional (the registry value type is deduced from T)
|
||
|
* @param key An open or well-known registry key
|
||
|
* @param subkey The name of the subkey to append to `key`.
|
||
|
* If `nullptr`, then `key` is used without modification.
|
||
|
* @param value_name The name of the registry value whose data is to be updated.
|
||
|
* Can be nullptr to read from the unnamed default registry value.
|
||
|
* @return The value (of type T) read from the registry value, in a std::optional<T>.
|
||
|
* Returns std::nullopt if the value does not exist.
|
||
|
* @exception std::exception (including wil::ResultException) will be thrown on failures except value not found
|
||
|
*/
|
||
|
template <typename T>
|
||
|
::std::optional<T> try_get_value(HKEY key, _In_opt_ PCWSTR subkey, _In_opt_ PCWSTR value_name)
|
||
|
{
|
||
|
#if defined(__WIL_OLEAUTO_H_)
|
||
|
// not allowing unique types with try_get_value: wil::unique_bstr cannot be copied and thus is difficult to work with a std::optional
|
||
|
static_assert(!wistd::is_same_v<T, ::wil::unique_bstr>, "try_get with wil::unique_bstr is disabled");
|
||
|
#endif // #if defined(__WIL_OLEAUTO_H_)
|
||
|
#if defined(__WIL_OBJBASE_H_)
|
||
|
// not allowing unique types with try_get_value: wil::unique_cotaskmem_string cannot be copied and thus is difficult to work with a std::optional
|
||
|
static_assert(!wistd::is_same_v<T, ::wil::unique_cotaskmem_string>, "try_get with wil::unique_cotaskmem_string is disabled");
|
||
|
#endif // #if defined(__WIL_OBJBASE_H_)
|
||
|
|
||
|
const reg_view_details::reg_view regview{key};
|
||
|
return regview.try_get_value<T>(subkey, value_name);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Attempts to read a value under a specified key, returning the value in a std::optional, deducing registry type from
|
||
|
* the type parameter T.
|
||
|
* @tparam T The type to read, which will be placed into a std::optional (the registry value type is deduced from T)
|
||
|
* @param key An open or well-known registry key
|
||
|
* @param value_name The name of the registry value whose data is to be updated.
|
||
|
* Can be nullptr to read from the unnamed default registry value.
|
||
|
* @return The value (of type T) read from the registry value, in a std::optional<T>.
|
||
|
* Returns std::nullopt if the value does not exist.
|
||
|
* @exception std::exception (including wil::ResultException) will be thrown on failures except value not found
|
||
|
*/
|
||
|
template <typename T>
|
||
|
::std::optional<T> try_get_value(HKEY key, _In_opt_ PCWSTR value_name)
|
||
|
{
|
||
|
#if defined(__WIL_OLEAUTO_H_)
|
||
|
// not allowing unique types with try_get_value: wil::unique_bstr cannot be copied and thus is difficult to work with a std::optional
|
||
|
static_assert(!wistd::is_same_v<T, ::wil::unique_bstr>, "try_get with wil::unique_bstr is disabled");
|
||
|
#endif // #if defined(__WIL_OLEAUTO_H_)
|
||
|
#if defined(__WIL_OBJBASE_H_)
|
||
|
// not allowing unique types with try_get_value: wil::unique_cotaskmem_string cannot be copied and thus is difficult to work with a std::optional
|
||
|
static_assert(!wistd::is_same_v<T, ::wil::unique_cotaskmem_string>, "try_get with wil::unique_cotaskmem_string is disabled");
|
||
|
#endif // #if defined(__WIL_OBJBASE_H_)
|
||
|
|
||
|
return ::wil::reg::try_get_value<T>(key, nullptr, value_name);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Attempts to read a REG_DWORD value under a specified key, returning the value in a std::optional
|
||
|
* @param key An open or well-known registry key
|
||
|
* @param subkey The name of the subkey to append to `key`.
|
||
|
* If `nullptr`, then `key` is used without modification.
|
||
|
* @param value_name The name of the registry value whose data is to be updated.
|
||
|
* Can be nullptr to read from the unnamed default registry value.
|
||
|
* @return The value read from the registry value, in a std::optional.
|
||
|
* Returns std::nullopt if the value does not exist.
|
||
|
* @exception std::exception (including wil::ResultException) will be thrown on failures except value not found
|
||
|
*/
|
||
|
inline ::std::optional<uint32_t> try_get_value_dword(HKEY key, _In_opt_ PCWSTR subkey, _In_opt_ PCWSTR value_name)
|
||
|
{
|
||
|
return ::wil::reg::try_get_value<uint32_t>(key, subkey, value_name);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Attempts to read a REG_DWORD value under a specified key, returning the value in a std::optional
|
||
|
* @param key An open or well-known registry key
|
||
|
* @param value_name The name of the registry value whose data is to be updated.
|
||
|
* Can be nullptr to read from the unnamed default registry value.
|
||
|
* @return The value read from the registry value, in a std::optional.
|
||
|
* Returns std::nullopt if the value does not exist.
|
||
|
* @exception std::exception (including wil::ResultException) will be thrown on failures except value not found
|
||
|
*/
|
||
|
inline ::std::optional<uint32_t> try_get_value_dword(HKEY key, _In_opt_ PCWSTR value_name)
|
||
|
{
|
||
|
return ::wil::reg::try_get_value<uint32_t>(key, nullptr, value_name);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Attempts to read a REG_QWORD value under a specified key, returning the value in a std::optional
|
||
|
* @param key An open or well-known registry key
|
||
|
* @param subkey The name of the subkey to append to `key`.
|
||
|
* If `nullptr`, then `key` is used without modification.
|
||
|
* @param value_name The name of the registry value whose data is to be updated.
|
||
|
* Can be nullptr to read from the unnamed default registry value.
|
||
|
* @return The value read from the registry value, in a std::optional.
|
||
|
* Returns std::nullopt if the value does not exist.
|
||
|
* @exception std::exception (including wil::ResultException) will be thrown on failures except value not found
|
||
|
*/
|
||
|
inline ::std::optional<uint64_t> try_get_value_qword(HKEY key, _In_opt_ PCWSTR subkey, _In_opt_ PCWSTR value_name)
|
||
|
{
|
||
|
return ::wil::reg::try_get_value<uint64_t>(key, subkey, value_name);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Attempts to read a REG_QWORD value under a specified key, returning the value in a std::optional
|
||
|
* @param key An open or well-known registry key
|
||
|
* @param value_name The name of the registry value whose data is to be updated.
|
||
|
* Can be nullptr to read from the unnamed default registry value.
|
||
|
* @return The value read from the registry value, in a std::optional.
|
||
|
* Returns std::nullopt if the value does not exist.
|
||
|
* @exception std::exception (including wil::ResultException) will be thrown on failures except value not found
|
||
|
*/
|
||
|
inline ::std::optional<uint64_t> try_get_value_qword(HKEY key, _In_opt_ PCWSTR value_name)
|
||
|
{
|
||
|
return ::wil::reg::try_get_value<uint64_t>(key, nullptr, value_name);
|
||
|
}
|
||
|
|
||
|
#if defined(_VECTOR_) || defined(WIL_DOXYGEN)
|
||
|
/**
|
||
|
* @brief Attempts to read a value under a specified key requiring the specified type, returning the raw bytes in a
|
||
|
* std::optional
|
||
|
* @param key An open or well-known registry key
|
||
|
* @param subkey The name of the subkey to append to `key`.
|
||
|
* If `nullptr`, then `key` is used without modification.
|
||
|
* @param value_name The name of the registry value whose data is to be updated.
|
||
|
* Can be nullptr to read from the unnamed default registry value.
|
||
|
* @param type The registry type for the specified registry value to read from - see RegGetValueW
|
||
|
* @return The raw bytes read from the registry value stored in a std::optional<std::vector<BYTE>>.
|
||
|
* Returns std::nullopt if the value does not exist.
|
||
|
* @exception std::exception (including wil::ResultException) will be thrown on failures except value not found
|
||
|
*/
|
||
|
inline ::std::optional<::std::vector<uint8_t>> try_get_value_binary(HKEY key, _In_opt_ PCWSTR subkey, _In_opt_ PCWSTR value_name, uint32_t type)
|
||
|
{
|
||
|
const reg_view_details::reg_view regview{key};
|
||
|
return regview.try_get_value<::std::vector<uint8_t>>(subkey, value_name, type);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Attempts to read a value under a specified key requiring the specified type, returning the raw bytes in a
|
||
|
* std::optional
|
||
|
* @param key An open or well-known registry key
|
||
|
* @param value_name The name of the registry value whose data is to be updated.
|
||
|
* Can be nullptr to read from the unnamed default registry value.
|
||
|
* @param type The registry type for the specified registry value to read from - see RegGetValueW
|
||
|
* @return The raw bytes read from the registry value stored in a std::optional<std::vector<BYTE>>.
|
||
|
* Returns std::nullopt if the value does not exist.
|
||
|
* @exception std::exception (including wil::ResultException) will be thrown on failures except value not found
|
||
|
*/
|
||
|
inline ::std::optional<::std::vector<uint8_t>> try_get_value_binary(HKEY key, _In_opt_ PCWSTR value_name, uint32_t type)
|
||
|
{
|
||
|
return ::wil::reg::try_get_value_binary(key, nullptr, value_name, type);
|
||
|
}
|
||
|
#endif // #if defined(_VECTOR_)
|
||
|
|
||
|
#if defined(_STRING_) || defined(WIL_DOXYGEN)
|
||
|
/**
|
||
|
* @brief Attempts to read a REG_SZ value under a specified key, returning the value in a std::optional
|
||
|
* @param key An open or well-known registry key
|
||
|
* @param subkey The name of the subkey to append to `key`.
|
||
|
* If `nullptr`, then `key` is used without modification.
|
||
|
* @param value_name The name of the registry value whose data is to be updated.
|
||
|
* Can be nullptr to read from the unnamed default registry value.
|
||
|
* @return The value read from the registry value, in a std::optional.
|
||
|
* Returns std::nullopt if the value does not exist.
|
||
|
* @exception std::exception (including wil::ResultException) will be thrown on failures except value not found
|
||
|
*/
|
||
|
inline ::std::optional<::std::wstring> try_get_value_string(HKEY key, _In_opt_ PCWSTR subkey, _In_opt_ PCWSTR value_name)
|
||
|
{
|
||
|
const reg_view_details::reg_view regview{key};
|
||
|
return regview.try_get_value<::std::wstring>(subkey, value_name);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Attempts to read a REG_SZ value under a specified key, returning the value in a std::optional
|
||
|
* @param key An open or well-known registry key
|
||
|
* @param value_name The name of the registry value whose data is to be updated.
|
||
|
* Can be nullptr to read from the unnamed default registry value.
|
||
|
* @return The value read from the registry value, in a std::optional.
|
||
|
* Returns std::nullopt if the value does not exist.
|
||
|
* @exception std::exception (including wil::ResultException) will be thrown on failures except value not found
|
||
|
*/
|
||
|
inline ::std::optional<::std::wstring> try_get_value_string(HKEY key, _In_opt_ PCWSTR value_name)
|
||
|
{
|
||
|
return ::wil::reg::try_get_value_string(key, nullptr, value_name);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Attempts to read a REG_SZ value under a specified key, returning the value in a std::optional
|
||
|
* @param key An open or well-known registry key
|
||
|
* @param subkey The name of the subkey to append to `key`.
|
||
|
* If `nullptr`, then `key` is used without modification.
|
||
|
* @param value_name The name of the registry value whose data is to be updated.
|
||
|
* Can be nullptr to read from the unnamed default registry value.
|
||
|
* @return The value read from the registry value, in a std::optional.
|
||
|
* Returns std::nullopt if the value does not exist.
|
||
|
* @exception std::exception (including wil::ResultException) will be thrown on failures except value not found
|
||
|
*/
|
||
|
template <>
|
||
|
inline ::std::optional<::std::wstring> try_get_value_string<::std::wstring>(HKEY key, _In_opt_ PCWSTR subkey, _In_opt_ PCWSTR value_name)
|
||
|
{
|
||
|
return ::wil::reg::try_get_value_string(key, subkey, value_name);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Attempts to read a REG_SZ value under a specified key, returning the value in a std::optional
|
||
|
* @param key An open or well-known registry key
|
||
|
* @param value_name The name of the registry value whose data is to be updated.
|
||
|
* Can be nullptr to read from the unnamed default registry value.
|
||
|
* @return The value read from the registry value, in a std::optional.
|
||
|
* Returns std::nullopt if the value does not exist.
|
||
|
* @exception std::exception (including wil::ResultException) will be thrown on failures except value not found
|
||
|
*/
|
||
|
template <>
|
||
|
inline ::std::optional<::std::wstring> try_get_value_string<::std::wstring>(HKEY key, _In_opt_ PCWSTR value_name)
|
||
|
{
|
||
|
return ::wil::reg::try_get_value_string(key, nullptr, value_name);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Attempts to read a REG_EXPAND_SZ value under a specified key, returning the value in a std::optional
|
||
|
* @param key An open or well-known registry key
|
||
|
* @param subkey The name of the subkey to append to `key`.
|
||
|
* If `nullptr`, then `key` is used without modification.
|
||
|
* @param value_name The name of the registry value whose data is to be updated.
|
||
|
* Can be nullptr to read from the unnamed default registry value.
|
||
|
* @return The value read from the registry value of the template type std::optional<std::wstring>,
|
||
|
* with environment variables expanded, as though passed through ExpandEnvironmentStringsW.
|
||
|
* Returns std::nullopt if the value does not exist.
|
||
|
* @exception std::exception (including wil::ResultException) will be thrown on failures except value not found
|
||
|
*/
|
||
|
inline ::std::optional<::std::wstring> try_get_value_expanded_string(HKEY key, _In_opt_ PCWSTR subkey, _In_opt_ PCWSTR value_name)
|
||
|
{
|
||
|
const reg_view_details::reg_view regview{key};
|
||
|
return regview.try_get_value<::std::wstring>(subkey, value_name, REG_EXPAND_SZ);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Attempts to read a REG_EXPAND_SZ value under a specified key, returning the value in a std::optional
|
||
|
* @param key An open or well-known registry key
|
||
|
* @param value_name The name of the registry value whose data is to be updated.
|
||
|
* Can be nullptr to read from the unnamed default registry value.
|
||
|
* @return The value read from the registry value of the template type std::optional<std::wstring>,
|
||
|
* with environment variables expanded, as though passed through ExpandEnvironmentStringsW.
|
||
|
* Returns std::nullopt if the value does not exist.
|
||
|
* @exception std::exception (including wil::ResultException) will be thrown on failures except value not found
|
||
|
*/
|
||
|
inline ::std::optional<::std::wstring> try_get_value_expanded_string(HKEY key, _In_opt_ PCWSTR value_name)
|
||
|
{
|
||
|
return ::wil::reg::try_get_value_expanded_string(key, nullptr, value_name);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Attempts to read a REG_EXPAND_SZ value under a specified key, returning the value in a std::optional
|
||
|
* @param key An open or well-known registry key
|
||
|
* @param subkey The name of the subkey to append to `key`.
|
||
|
* If `nullptr`, then `key` is used without modification.
|
||
|
* @param value_name The name of the registry value whose data is to be updated.
|
||
|
* Can be nullptr to read from the unnamed default registry value.
|
||
|
* @return The value read from the registry value of the template type std::optional<std::wstring>,
|
||
|
* with environment variables expanded, as though passed through ExpandEnvironmentStringsW.
|
||
|
* Returns std::nullopt if the value does not exist.
|
||
|
* @exception std::exception (including wil::ResultException) will be thrown on failures except value not found
|
||
|
*/
|
||
|
template <>
|
||
|
inline ::std::optional<::std::wstring> try_get_value_expanded_string<::std::wstring>(HKEY key, _In_opt_ PCWSTR subkey, _In_opt_ PCWSTR value_name)
|
||
|
{
|
||
|
return ::wil::reg::try_get_value_expanded_string(key, subkey, value_name);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Attempts to read a REG_EXPAND_SZ value under a specified key, returning the value in a std::optional
|
||
|
* @param key An open or well-known registry key
|
||
|
* @param value_name The name of the registry value whose data is to be updated.
|
||
|
* Can be nullptr to read from the unnamed default registry value.
|
||
|
* @return The value read from the registry value of the template type std::optional<std::wstring>,
|
||
|
* with environment variables expanded, as though passed through ExpandEnvironmentStringsW.
|
||
|
* Returns std::nullopt if the value does not exist.
|
||
|
* @exception std::exception (including wil::ResultException) will be thrown on failures except value not found
|
||
|
*/
|
||
|
template <>
|
||
|
inline ::std::optional<::std::wstring> try_get_value_expanded_string<::std::wstring>(HKEY key, _In_opt_ PCWSTR value_name)
|
||
|
{
|
||
|
return ::wil::reg::try_get_value_expanded_string(key, nullptr, value_name);
|
||
|
}
|
||
|
#endif // #if defined(_STRING_)
|
||
|
|
||
|
#if defined(__WIL_OLEAUTO_H_STL) || defined(WIL_DOXYGEN)
|
||
|
/**
|
||
|
* @brief Attempts to read a REG_SZ value under a specified key, returning the value in a std::optional
|
||
|
* @param key An open or well-known registry key
|
||
|
* @param subkey The name of the subkey to append to `key`.
|
||
|
* If `nullptr`, then `key` is used without modification.
|
||
|
* @param value_name The name of the registry value whose data is to be updated.
|
||
|
* Can be nullptr to read from the unnamed default registry value.
|
||
|
* @return The value read from the registry value of the template type std::optional<wil::shared_bstr>.
|
||
|
* Returns std::nullopt if the value does not exist.
|
||
|
* @exception std::exception (including wil::ResultException) will be thrown on failures except value not found
|
||
|
*/
|
||
|
template <>
|
||
|
inline ::std::optional<::wil::shared_bstr> try_get_value_string<::wil::shared_bstr>(HKEY key, _In_opt_ PCWSTR subkey, _In_opt_ PCWSTR value_name)
|
||
|
{
|
||
|
const reg_view_details::reg_view regview{key};
|
||
|
return regview.try_get_value<::wil::shared_bstr>(subkey, value_name);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Attempts to read a REG_SZ value under a specified key, returning the value in a std::optional
|
||
|
* @param key An open or well-known registry key
|
||
|
* @param value_name The name of the registry value whose data is to be updated.
|
||
|
* Can be nullptr to read from the unnamed default registry value.
|
||
|
* @return The value read from the registry value of the template type std::optional<wil::shared_bstr>.
|
||
|
* Returns std::nullopt if the value does not exist.
|
||
|
* @exception std::exception (including wil::ResultException) will be thrown on failures except value not found
|
||
|
*/
|
||
|
template <>
|
||
|
inline ::std::optional<::wil::shared_bstr> try_get_value_string<::wil::shared_bstr>(HKEY key, _In_opt_ PCWSTR value_name)
|
||
|
{
|
||
|
return ::wil::reg::try_get_value_string<::wil::shared_bstr>(key, nullptr, value_name);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Attempts to read a REG_EXPAND_SZ value under a specified key, returning the value in a std::optional
|
||
|
* @param key An open or well-known registry key
|
||
|
* @param subkey The name of the subkey to append to `key`.
|
||
|
* If `nullptr`, then `key` is used without modification.
|
||
|
* @param value_name The name of the registry value whose data is to be updated.
|
||
|
* Can be nullptr to read from the unnamed default registry value.
|
||
|
* @return The value read from the registry value of the template type std::optional<wil::shared_bstr>,
|
||
|
* with environment variables expanded, as though passed through ExpandEnvironmentStringsW.
|
||
|
* Returns std::nullopt if the value does not exist.
|
||
|
* @exception std::exception (including wil::ResultException) will be thrown on failures except value not found
|
||
|
*/
|
||
|
template <>
|
||
|
inline ::std::optional<::wil::shared_bstr> try_get_value_expanded_string<::wil::shared_bstr>(
|
||
|
HKEY key, _In_opt_ PCWSTR subkey, _In_opt_ PCWSTR value_name)
|
||
|
{
|
||
|
const reg_view_details::reg_view regview{key};
|
||
|
return regview.try_get_value<::wil::shared_bstr>(subkey, value_name, REG_EXPAND_SZ);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Attempts to read a REG_EXPAND_SZ value under a specified key, returning the value in a std::optional
|
||
|
* @param key An open or well-known registry key
|
||
|
* @param value_name The name of the registry value whose data is to be updated.
|
||
|
* Can be nullptr to read from the unnamed default registry value.
|
||
|
* @return The value read from the registry value of the template type std::optional<wil::shared_bstr>,
|
||
|
* with environment variables expanded, as though passed through ExpandEnvironmentStringsW.
|
||
|
* Returns std::nullopt if the value does not exist.
|
||
|
* @exception std::exception (including wil::ResultException) will be thrown on failures except value not found
|
||
|
*/
|
||
|
template <>
|
||
|
inline ::std::optional<::wil::shared_bstr> try_get_value_expanded_string<::wil::shared_bstr>(HKEY key, _In_opt_ PCWSTR value_name)
|
||
|
{
|
||
|
return ::wil::reg::try_get_value_expanded_string<::wil::shared_bstr>(key, nullptr, value_name);
|
||
|
}
|
||
|
#endif // #if defined(__WIL_OLEAUTO_H_STL)
|
||
|
|
||
|
#if defined(__WIL_OBJBASE_H_STL) || defined(WIL_DOXYGEN)
|
||
|
/**
|
||
|
* @brief Attempts to read a REG_SZ value under a specified key, returning the value in a std::optional
|
||
|
* @param key An open or well-known registry key
|
||
|
* @param subkey The name of the subkey to append to `key`.
|
||
|
* If `nullptr`, then `key` is used without modification.
|
||
|
* @param value_name The name of the registry value whose data is to be updated.
|
||
|
* Can be nullptr to read from the unnamed default registry value.
|
||
|
* @return The value read from the registry value of the template type std::optional<wil::shared_cotaskmem_string>.
|
||
|
* Returns std::nullopt if the value does not exist.
|
||
|
* @exception std::exception (including wil::ResultException) will be thrown on failures except value not found
|
||
|
*/
|
||
|
template <>
|
||
|
inline ::std::optional<::wil::shared_cotaskmem_string> try_get_value_string<::wil::shared_cotaskmem_string>(
|
||
|
HKEY key, _In_opt_ PCWSTR subkey, _In_opt_ PCWSTR value_name)
|
||
|
{
|
||
|
const reg_view_details::reg_view regview{key};
|
||
|
return regview.try_get_value<::wil::shared_cotaskmem_string>(subkey, value_name);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Attempts to read a REG_SZ value under a specified key, returning the value in a std::optional
|
||
|
* @param key An open or well-known registry key
|
||
|
* @param value_name The name of the registry value whose data is to be updated.
|
||
|
* Can be nullptr to read from the unnamed default registry value.
|
||
|
* @return The value read from the registry value of the template type std::optional<wil::shared_cotaskmem_string>
|
||
|
* Returns std::nullopt if the value does not exist.
|
||
|
* @exception std::exception (including wil::ResultException) will be thrown on failures except value not found
|
||
|
*/
|
||
|
template <>
|
||
|
inline ::std::optional<::wil::shared_cotaskmem_string> try_get_value_string<::wil::shared_cotaskmem_string>(HKEY key, _In_opt_ PCWSTR value_name)
|
||
|
{
|
||
|
return ::wil::reg::try_get_value_string<::wil::shared_cotaskmem_string>(key, nullptr, value_name);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Attempts to read a REG_EXPAND_SZ value under a specified key, returning the value in a std::optional
|
||
|
* @param key An open or well-known registry key
|
||
|
* @param subkey The name of the subkey to append to `key`.
|
||
|
* If `nullptr`, then `key` is used without modification.
|
||
|
* @param value_name The name of the registry value whose data is to be updated.
|
||
|
* Can be nullptr to read from the unnamed default registry value.
|
||
|
* @return The value read from the registry value of the template type std::optional<:wil::shared_cotaskmem_string>,
|
||
|
* with environment variables expanded, as though passed through ExpandEnvironmentStringsW.
|
||
|
* Returns std::nullopt if the value does not exist.
|
||
|
* @exception std::exception (including wil::ResultException) will be thrown on failures except value not found
|
||
|
*/
|
||
|
template <>
|
||
|
inline ::std::optional<::wil::shared_cotaskmem_string> try_get_value_expanded_string<::wil::shared_cotaskmem_string>(
|
||
|
HKEY key, _In_opt_ PCWSTR subkey, _In_opt_ PCWSTR value_name)
|
||
|
{
|
||
|
const reg_view_details::reg_view regview{key};
|
||
|
return regview.try_get_value<::wil::shared_cotaskmem_string>(subkey, value_name, REG_EXPAND_SZ);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Attempts to read a REG_EXPAND_SZ value under a specified key, returning the value in a std::optional
|
||
|
* @param key An open or well-known registry key
|
||
|
* @param value_name The name of the registry value whose data is to be updated.
|
||
|
* Can be nullptr to read from the unnamed default registry value.
|
||
|
* @return The value read from the registry value of the template type std::optional<wil::shared_cotaskmem_string>,
|
||
|
* with environment variables expanded, as though passed through ExpandEnvironmentStringsW.
|
||
|
* Returns std::nullopt if the value does not exist.
|
||
|
* @exception std::exception (including wil::ResultException) will be thrown on failures except value not found
|
||
|
*/
|
||
|
template <>
|
||
|
inline ::std::optional<::wil::shared_cotaskmem_string> try_get_value_expanded_string<::wil::shared_cotaskmem_string>(
|
||
|
HKEY key, _In_opt_ PCWSTR value_name)
|
||
|
{
|
||
|
return ::wil::reg::try_get_value_expanded_string<::wil::shared_cotaskmem_string>(key, nullptr, value_name);
|
||
|
}
|
||
|
#endif // defined(__WIL_OBJBASE_H_STL)
|
||
|
|
||
|
#if (defined(_VECTOR_) && defined(_STRING_)) || defined(WIL_DOXYGEN)
|
||
|
/**
|
||
|
* @brief Attempts to read a REG_MULTI_SZ value under a specified key, returning the value in a std::optional
|
||
|
* @param key An open or well-known registry key
|
||
|
* @param subkey The name of the subkey to append to `key`.
|
||
|
* If `nullptr`, then `key` is used without modification.
|
||
|
* @param value_name The name of the registry value whose data is to be updated.
|
||
|
* Can be nullptr to read from the unnamed default registry value.
|
||
|
* @return The value read from the registry value marshaled to a std::optional<std::vector<std::wstring>>.
|
||
|
* Returns std::nullopt if the value does not exist.
|
||
|
* @exception std::exception (including wil::ResultException) will be thrown on failures except value not found
|
||
|
*/
|
||
|
template <>
|
||
|
inline ::std::optional<::std::vector<::std::wstring>> try_get_value<::std::vector<::std::wstring>>(
|
||
|
HKEY key, _In_opt_ PCWSTR subkey, _In_opt_ PCWSTR value_name)
|
||
|
{
|
||
|
::std::vector<::std::wstring> value;
|
||
|
const auto hr = ::wil::ResultFromException([&] {
|
||
|
value = ::wil::reg::get_value_multistring(key, subkey, value_name);
|
||
|
});
|
||
|
if (SUCCEEDED(hr))
|
||
|
{
|
||
|
return value;
|
||
|
}
|
||
|
|
||
|
if (!::wil::reg::is_registry_not_found(hr))
|
||
|
{
|
||
|
THROW_HR(HRESULT_FROM_WIN32(hr));
|
||
|
}
|
||
|
|
||
|
return ::std::nullopt;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Attempts to read a REG_MULTI_SZ value under a specified key, returning the value in a std::optional
|
||
|
* @param key An open or well-known registry key
|
||
|
* @param value_name The name of the registry value whose data is to be updated.
|
||
|
* Can be nullptr to read from the unnamed default registry value.
|
||
|
* @return The value read from the registry value marshaled to a std::optional<std::vector<std::wstring>>.
|
||
|
* Returns std::nullopt if the value does not exist.
|
||
|
* @exception std::exception (including wil::ResultException) will be thrown on failures except value not found
|
||
|
*/
|
||
|
template <>
|
||
|
inline ::std::optional<::std::vector<::std::wstring>> try_get_value<::std::vector<::std::wstring>>(HKEY key, _In_opt_ PCWSTR value_name)
|
||
|
{
|
||
|
return ::wil::reg::try_get_value<::std::vector<::std::wstring>>(key, nullptr, value_name);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Attempts to read a REG_MULTI_SZ value under a specified key, returning the value in a std::optional
|
||
|
* @param key An open or well-known registry key
|
||
|
* @param subkey The name of the subkey to append to `key`.
|
||
|
* If `nullptr`, then `key` is used without modification.
|
||
|
* @param value_name The name of the registry value whose data is to be updated.
|
||
|
* Can be nullptr to read from the unnamed default registry value.
|
||
|
* @return The value read from the registry value marshaled to a std::optional<std::vector<std::wstring>>.
|
||
|
* Returns std::nullopt if the value does not exist.
|
||
|
* @exception std::exception (including wil::ResultException) will be thrown on failures except value not found
|
||
|
*/
|
||
|
inline ::std::optional<::std::vector<::std::wstring>> try_get_value_multistring(HKEY key, _In_opt_ PCWSTR subkey, _In_opt_ PCWSTR value_name)
|
||
|
{
|
||
|
return ::wil::reg::try_get_value<::std::vector<::std::wstring>>(key, subkey, value_name);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Attempts to read a REG_MULTI_SZ value under a specified key, returning the value in a std::optional
|
||
|
* @param key An open or well-known registry key
|
||
|
* @param value_name The name of the registry value whose data is to be updated.
|
||
|
* Can be nullptr to read from the unnamed default registry value.
|
||
|
* @return The value read from the registry value marshaled to a std::optional<std::vector<std::wstring>>.
|
||
|
* Returns std::nullopt if the value does not exist.
|
||
|
* @exception std::exception (including wil::ResultException) will be thrown on failures except value not found
|
||
|
*/
|
||
|
inline ::std::optional<::std::vector<::std::wstring>> try_get_value_multistring(HKEY key, _In_opt_ PCWSTR value_name)
|
||
|
{
|
||
|
return ::wil::reg::try_get_value<::std::vector<::std::wstring>>(key, nullptr, value_name);
|
||
|
}
|
||
|
#endif // #if defined (_VECTOR_) && defined (_STRING_)
|
||
|
#endif // #if defined (_OPTIONAL_) && defined(__cpp_lib_optional)
|
||
|
#endif // #if defined(WIL_ENABLE_EXCEPTIONS)
|
||
|
|
||
|
//
|
||
|
// template <typename T>
|
||
|
// HRESULT get_value_nothrow(...)
|
||
|
//
|
||
|
// - Reads a value from under a specified key
|
||
|
// - The required type of registry value being read from is determined by the template type T
|
||
|
// - Returns an HRESULT error code indicating success or failure (does not throw C++ exceptions)
|
||
|
//
|
||
|
// Examples of usage (the template type does not need to be explicitly specified)
|
||
|
// uint32_t dword_value{};
|
||
|
// hr = wil::reg::get_value_nothrow(key, L"subkey", L"dword_value_name", &dword_value); // reads a REG_DWORD
|
||
|
// uint64_t qword_value{};
|
||
|
// hr = wil::reg::get_value_nothrow(key, L"subkey", L"qword_value_name", &qword_value); // reads a REG_QWORD
|
||
|
// wil::unique_bstr string_value{};
|
||
|
// hr = wil::reg::get_value_nothrow(key, L"subkey", L"string_value_name", string_value); // reads a REG_SZ
|
||
|
//
|
||
|
// A subkey is not required if the key is opened where this should write the value:
|
||
|
// hr = wil::reg::get_value_nothrow(key, L"dword_value_name", &dword_value); // reads a REG_DWORD
|
||
|
// hr = wil::reg::get_value_nothrow(key, L"qword_value_name", &qword_value); // reads a REG_QWORD
|
||
|
// hr = wil::reg::get_value_nothrow(key, L"string_value_name", string_value); // reads a REG_SZ
|
||
|
//
|
||
|
// Can also specify the registry type in the function name:
|
||
|
// hr = wil::reg::get_value_dword_nothrow(key, L"dword_value_name", &dword_value); // reads a REG_DWORD
|
||
|
// hr = wil::reg::get_value_qword_nothrow(key, L"qword_value_name", &qword_value); // reads a REG_QWORD
|
||
|
// hr = wil::reg::get_value_string_nothrow(key, L"string_value_name", string_value); // reads a REG_SZ
|
||
|
//
|
||
|
// Example storing directly into a WCHAR array - note will return the required number of bytes if the supplied array is too small
|
||
|
// WCHAR string_value[100]{};
|
||
|
// uint32_t requiredBytes{};
|
||
|
// hr = wil::reg::get_value_string_nothrow(key, L"string_value_name", string_value, &requiredBytes);
|
||
|
//
|
||
|
// Example of usage writing a REG_MULTI_SZ
|
||
|
// wil::unique_cotaskmem_array_ptr<wil::unique_cotaskmem_string> string_values{};
|
||
|
// hr = wil::reg::get_value_multistring_nothrow(key, L"multi_string_value_name", string_values);
|
||
|
//
|
||
|
// Values can be written directly from a vector of bytes - the registry type must be specified; e.g.:
|
||
|
// wil::unique_cotaskmem_array_ptr<BYTE> raw_value{};
|
||
|
// hr = wil::reg::get_value_binary_nothrow(key, L"binary_value_name", REG_BINARY, raw_value);
|
||
|
//
|
||
|
// Reading REG_SZ and REG_EXPAND_SZ types are done through the below templated get_value_string_nothrow and get_value_expanded_string_nothrow functions
|
||
|
// Where the template type is the type to receive the string value
|
||
|
// The default template type is std::wstring, available if the caller has included the STL <string> header
|
||
|
//
|
||
|
// Example storing a string in a wil::unique_bstr, wil::shared_bstr, wil::unique_cotaskmem_string, or wil::shared_cotaskmem_string
|
||
|
/// - These string types are passed by reference, not by pointer, because the wil types overload the & operator
|
||
|
//
|
||
|
// wil::unique_bstr bstr_value{};
|
||
|
// hr = wil::reg::get_value_nothrow(key, L"string_value_name", bstr_value);
|
||
|
// // or can specify explicitly reading a string into a wil::unique_bstr type
|
||
|
// hr = wil::reg::get_value_string_nothrow(key, L"string_value_name", bstr_value);
|
||
|
//
|
||
|
// wil::shared_bstr shared_bstr_value{};
|
||
|
// hr = wil::reg::get_value_nothrow(key, L"string_value_name", shared_bstr_value);
|
||
|
// // or can specify explicitly reading a string into a wil::shared_bstr type
|
||
|
// hr = wil::reg::get_value_string_nothrow(key, L"string_value_name", shared_bstr_value);
|
||
|
//
|
||
|
// wil::unique_cotaskmem_string string_value{};
|
||
|
// hr = wil::reg::get_value_nothrow(key, L"string_value_name", string_value);
|
||
|
// // or can specify explicitly reading a string into a wil::unique_cotaskmem_string type
|
||
|
// hr = wil::reg::get_value_string_nothrow(key, L"string_value_name", string_value);
|
||
|
//
|
||
|
// wil::shared_cotaskmem_string shared_string_value{};
|
||
|
// hr = wil::reg::get_value_nothrow(key, L"string_value_name", shared_string_value);
|
||
|
// // or can specify explicitly reading a string into a wil::shared_cotaskmem_string type
|
||
|
// hr = wil::reg::get_value_string_nothrow(key, L"string_value_name", shared_string_value);
|
||
|
//
|
||
|
|
||
|
/**
|
||
|
* @brief Reads a value under a specified key, the registry type based off the templated type passed as data
|
||
|
* @tparam T The type of the data being set (the registry value type is deduced from T).
|
||
|
* @param key An open or well-known registry key
|
||
|
* @param subkey The name of the subkey to append to `key`.
|
||
|
* If `nullptr`, then `key` is used without modification.
|
||
|
* @param value_name The name of the registry value whose data is to be read.
|
||
|
* Can be nullptr to read from the unnamed default registry value.
|
||
|
* @param[out] return_value A pointer-to-T receiving the value read from the registry
|
||
|
* @return HRESULT error code indicating success or failure (does not throw C++ exceptions)
|
||
|
*/
|
||
|
template <typename T, wistd::enable_if_t<!wistd::is_same_v<T, wchar_t>>* = nullptr>
|
||
|
HRESULT get_value_nothrow(HKEY key, _In_opt_ PCWSTR subkey, _In_opt_ PCWSTR value_name, _Out_ T* return_value) WI_NOEXCEPT
|
||
|
{
|
||
|
const reg_view_details::reg_view_nothrow regview{key};
|
||
|
return regview.get_value<T>(subkey, value_name, *return_value);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Reads a value under a specified key, the registry type based off the templated type passed as data
|
||
|
* @tparam T The type of the data being set (the registry value type is deduced from T).
|
||
|
* @param key An open or well-known registry key
|
||
|
* @param value_name The name of the registry value whose data is to be read.
|
||
|
* Can be nullptr to read from the unnamed default registry value.
|
||
|
* @param[out] return_value A pointer-to-T receiving the value read from the registry
|
||
|
* @return HRESULT error code indicating success or failure (does not throw C++ exceptions)
|
||
|
*/
|
||
|
template <typename T, wistd::enable_if_t<!wistd::is_same_v<T, wchar_t>>* = nullptr>
|
||
|
HRESULT get_value_nothrow(HKEY key, _In_opt_ PCWSTR value_name, _Out_ T* return_value) WI_NOEXCEPT
|
||
|
{
|
||
|
return ::wil::reg::get_value_nothrow(key, nullptr, value_name, return_value);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Reads a REG_SZ value under a specified key
|
||
|
* @tparam Length The length of the WCHAR array passed as an OUT parameter
|
||
|
* @param key An open or well-known registry key
|
||
|
* @param subkey The name of the subkey to append to `key`.
|
||
|
* If `nullptr`, then `key` is used without modification.
|
||
|
* @param value_name The name of the registry value whose data is to be read.
|
||
|
* Can be nullptr to read from the unnamed default registry value.
|
||
|
* @param[out] return_value A WCHAR array receiving the value read from the registry.
|
||
|
* Will write to the WCHAR array the string value read from the registry, guaranteeing null-termination
|
||
|
* @param[out] requiredBytes An optional pointer to a unsigned 32-bit value to receive the required bytes of the string in the
|
||
|
* registry
|
||
|
* @return HRESULT error code indicating success or failure (does not throw C++ exceptions)
|
||
|
*/
|
||
|
template <size_t Length, typename DwordType, wistd::enable_if_t<wistd::is_same_v<DwordType, uint32_t> || wistd::is_same_v<DwordType, unsigned long>>* = nullptr>
|
||
|
HRESULT get_value_string_nothrow(
|
||
|
HKEY key, _In_opt_ PCWSTR subkey, _In_opt_ PCWSTR value_name, WCHAR (&return_value)[Length], _Out_opt_ DwordType* requiredBytes) WI_NOEXCEPT
|
||
|
{
|
||
|
const reg_view_details::reg_view_nothrow regview{key};
|
||
|
return regview.get_value_char_array(subkey, value_name, return_value, REG_SZ, requiredBytes);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Reads a REG_SZ value under a specified key
|
||
|
* @tparam Length The length of the WCHAR array passed as an OUT parameter
|
||
|
* @param key An open or well-known registry key
|
||
|
* @param value_name The name of the registry value whose data is to be read.
|
||
|
* Can be nullptr to read from the unnamed default registry value.
|
||
|
* @param[out] return_value A WCHAR array receiving the value read from the registry.
|
||
|
* Will write to the WCHAR array the string value read from the registry, guaranteeing null-termination
|
||
|
* @param[out] requiredBytes An optional pointer to an unsigned 32-bit value to receive the required bytes of the string to be
|
||
|
* read
|
||
|
* @return HRESULT error code indicating success or failure (does not throw C++ exceptions)
|
||
|
*/
|
||
|
template <size_t Length, typename DwordType, wistd::enable_if_t<wistd::is_same_v<DwordType, uint32_t> || wistd::is_same_v<DwordType, unsigned long>>* = nullptr>
|
||
|
HRESULT get_value_string_nothrow(HKEY key, _In_opt_ PCWSTR value_name, WCHAR (&return_value)[Length], _Out_opt_ DwordType* requiredBytes) WI_NOEXCEPT
|
||
|
{
|
||
|
return ::wil::reg::get_value_string_nothrow<Length>(key, nullptr, value_name, return_value, requiredBytes);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Reads a REG_SZ value under a specified key
|
||
|
* @tparam Length The length of the WCHAR array passed as an OUT parameter
|
||
|
* @param key An open or well-known registry key
|
||
|
* @param subkey The name of the subkey to append to `key`.
|
||
|
* If `nullptr`, then `key` is used without modification.
|
||
|
* @param value_name The name of the registry value whose data is to be read.
|
||
|
* Can be nullptr to read from the unnamed default registry value.
|
||
|
* @param[out] return_value A WCHAR array receiving the value read from the registry.
|
||
|
* Will write to the WCHAR array the string value read from the registry, guaranteeing null-termination
|
||
|
* @return HRESULT error code indicating success or failure (does not throw C++ exceptions)
|
||
|
*/
|
||
|
template <size_t Length>
|
||
|
HRESULT get_value_string_nothrow(HKEY key, _In_opt_ PCWSTR subkey, _In_opt_ PCWSTR value_name, WCHAR (&return_value)[Length]) WI_NOEXCEPT
|
||
|
{
|
||
|
constexpr uint32_t* null_out_param = nullptr;
|
||
|
const reg_view_details::reg_view_nothrow regview{key};
|
||
|
return regview.get_value_char_array(subkey, value_name, return_value, REG_SZ, null_out_param);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Reads a REG_SZ value under a specified key
|
||
|
* @tparam Length The length of the WCHAR array passed as an OUT parameter
|
||
|
* @param key An open or well-known registry key
|
||
|
* @param value_name The name of the registry value whose data is to be read.
|
||
|
* Can be nullptr to read from the unnamed default registry value.
|
||
|
* @param[out] return_value A WCHAR array receiving the value read from the registry.
|
||
|
* Will write to the WCHAR array the string value read from the registry, guaranteeing null-termination
|
||
|
* @return HRESULT error code indicating success or failure (does not throw C++ exceptions)
|
||
|
*/
|
||
|
template <size_t Length>
|
||
|
HRESULT get_value_string_nothrow(HKEY key, _In_opt_ PCWSTR value_name, WCHAR (&return_value)[Length]) WI_NOEXCEPT
|
||
|
{
|
||
|
return ::wil::reg::get_value_string_nothrow<Length>(key, nullptr, value_name, return_value);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Reads a REG_SZ value under a specified key
|
||
|
* @tparam Length The length of the WCHAR array passed as an OUT parameter
|
||
|
* @param key An open or well-known registry key
|
||
|
* @param subkey The name of the subkey to append to `key`.
|
||
|
* If `nullptr`, then `key` is used without modification.
|
||
|
* @param value_name The name of the registry value whose data is to be read.
|
||
|
* Can be nullptr to read from the unnamed default registry value.
|
||
|
* @param[out] return_value A WCHAR array receiving the value read from the registry.
|
||
|
* Will write to the WCHAR array the string value read from the registry, guaranteeing null-termination
|
||
|
* @return HRESULT error code indicating success or failure (does not throw C++ exceptions)
|
||
|
*/
|
||
|
template <size_t Length>
|
||
|
HRESULT get_value_nothrow(HKEY key, _In_opt_ PCWSTR subkey, _In_opt_ PCWSTR value_name, WCHAR (&return_value)[Length]) WI_NOEXCEPT
|
||
|
{
|
||
|
return ::wil::reg::get_value_string_nothrow<Length>(key, subkey, value_name, return_value);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Reads a REG_SZ value under a specified key
|
||
|
* @tparam Length The length of the WCHAR array passed as an OUT parameter
|
||
|
* @param key An open or well-known registry key
|
||
|
* @param value_name The name of the registry value whose data is to be read.
|
||
|
* Can be nullptr to read from the unnamed default registry value.
|
||
|
* @param[out] return_value A WCHAR array receiving the value read from the registry.
|
||
|
* Will write to the WCHAR array the string value read from the registry, guaranteeing null-termination
|
||
|
* @return HRESULT error code indicating success or failure (does not throw C++ exceptions)
|
||
|
*/
|
||
|
template <size_t Length>
|
||
|
HRESULT get_value_nothrow(HKEY key, _In_opt_ PCWSTR value_name, WCHAR (&return_value)[Length]) WI_NOEXCEPT
|
||
|
{
|
||
|
return ::wil::reg::get_value_string_nothrow<Length>(key, nullptr, value_name, return_value);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Reads a REG_DWORD value under a specified key
|
||
|
* @param key An open or well-known registry key
|
||
|
* @param subkey The name of the subkey to append to `key`.
|
||
|
* If `nullptr`, then `key` is used without modification.
|
||
|
* @param value_name The name of the registry value whose data is to be read.
|
||
|
* Can be nullptr to read from the unnamed default registry value.
|
||
|
* @param[out] return_value A pointer to an unsigned 32-bit value receiving the value read from the registry
|
||
|
* @return HRESULT error code indicating success or failure (does not throw C++ exceptions)
|
||
|
*/
|
||
|
template <typename DwordType, wistd::enable_if_t<wistd::is_same_v<DwordType, uint32_t> || wistd::is_same_v<DwordType, unsigned long>>* = nullptr>
|
||
|
HRESULT get_value_dword_nothrow(HKEY key, _In_opt_ PCWSTR subkey, _In_opt_ PCWSTR value_name, _Out_ DwordType* return_value) WI_NOEXCEPT
|
||
|
{
|
||
|
return ::wil::reg::get_value_nothrow(key, subkey, value_name, return_value);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Reads a REG_DWORD value under a specified key
|
||
|
* @param key An open or well-known registry key
|
||
|
* @param value_name The name of the registry value whose data is to be read.
|
||
|
* Can be nullptr to read from the unnamed default registry value.
|
||
|
* @param[out] return_value A pointer to an unsigned 32-bit value receiving the value read from the registry
|
||
|
* @return HRESULT error code indicating success or failure (does not throw C++ exceptions)
|
||
|
*/
|
||
|
template <typename DwordType, wistd::enable_if_t<wistd::is_same_v<DwordType, uint32_t> || wistd::is_same_v<DwordType, unsigned long>>* = nullptr>
|
||
|
HRESULT get_value_dword_nothrow(HKEY key, _In_opt_ PCWSTR value_name, _Out_ DwordType* return_value) WI_NOEXCEPT
|
||
|
{
|
||
|
return ::wil::reg::get_value_nothrow(key, nullptr, value_name, return_value);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Reads a REG_QWORD value under a specified key
|
||
|
* @param key An open or well-known registry key
|
||
|
* @param subkey The name of the subkey to append to `key`.
|
||
|
* If `nullptr`, then `key` is used without modification.
|
||
|
* @param value_name The name of the registry value whose data is to be read.
|
||
|
* Can be nullptr to read from the unnamed default registry value.
|
||
|
* @param[out] return_value A uint64_t receiving the value read from the registry
|
||
|
* @return HRESULT error code indicating success or failure (does not throw C++ exceptions)
|
||
|
*/
|
||
|
template <typename QwordType, wistd::enable_if_t<wistd::is_same_v<QwordType, uint64_t> || wistd::is_same_v<QwordType, unsigned long long>>* = nullptr>
|
||
|
HRESULT get_value_qword_nothrow(HKEY key, _In_opt_ PCWSTR subkey, _In_opt_ PCWSTR value_name, _Out_ QwordType* return_value) WI_NOEXCEPT
|
||
|
{
|
||
|
return ::wil::reg::get_value_nothrow(key, subkey, value_name, return_value);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Reads a REG_QWORD value under a specified key
|
||
|
* @param key An open or well-known registry key
|
||
|
* @param value_name The name of the registry value whose data is to be read.
|
||
|
* Can be nullptr to read from the unnamed default registry value.
|
||
|
* @param[out] return_value A uint64_t receiving the value read from the registry
|
||
|
* @return HRESULT error code indicating success or failure (does not throw C++ exceptions)
|
||
|
*/
|
||
|
template <typename QwordType, wistd::enable_if_t<wistd::is_same_v<QwordType, uint64_t> || wistd::is_same_v<QwordType, unsigned long long>>* = nullptr>
|
||
|
HRESULT get_value_qword_nothrow(HKEY key, _In_opt_ PCWSTR value_name, _Out_ QwordType* return_value) WI_NOEXCEPT
|
||
|
{
|
||
|
return ::wil::reg::get_value_nothrow(key, nullptr, value_name, return_value);
|
||
|
}
|
||
|
|
||
|
#if defined(__WIL_OLEAUTO_H_) || defined(WIL_DOXYGEN)
|
||
|
/**
|
||
|
* @brief Reads a REG_SZ value under a specified key
|
||
|
* @param key An open or well-known registry key
|
||
|
* @param subkey The name of the subkey to append to `key`.
|
||
|
* If `nullptr`, then `key` is used without modification.
|
||
|
* @param value_name The name of the registry value whose data is to be read.
|
||
|
* Can be nullptr to read from the unnamed default registry value.
|
||
|
* @param[out] return_value A wil::unique_bstr receiving the value read from the registry
|
||
|
* @return HRESULT error code indicating success or failure (does not throw C++ exceptions)
|
||
|
*/
|
||
|
inline HRESULT get_value_nothrow(HKEY key, _In_opt_ PCWSTR subkey, _In_opt_ PCWSTR value_name, ::wil::unique_bstr& return_value) WI_NOEXCEPT
|
||
|
{
|
||
|
const reg_view_details::reg_view_nothrow regview{key};
|
||
|
return regview.get_value(subkey, value_name, return_value);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Reads a REG_SZ value under a specified key
|
||
|
* @param key An open or well-known registry key
|
||
|
* @param value_name The name of the registry value whose data is to be read.
|
||
|
* Can be nullptr to read from the unnamed default registry value.
|
||
|
* @param[out] return_value A wil::unique_bstr receiving the value read from the registry
|
||
|
* @return HRESULT error code indicating success or failure (does not throw C++ exceptions)
|
||
|
*/
|
||
|
inline HRESULT get_value_nothrow(HKEY key, _In_opt_ PCWSTR value_name, ::wil::unique_bstr& return_value) WI_NOEXCEPT
|
||
|
{
|
||
|
return ::wil::reg::get_value_nothrow(key, nullptr, value_name, return_value);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Reads a REG_SZ value under a specified key
|
||
|
* @param key An open or well-known registry key
|
||
|
* @param subkey The name of the subkey to append to `key`.
|
||
|
* If `nullptr`, then `key` is used without modification.
|
||
|
* @param value_name The name of the registry value whose data is to be read.
|
||
|
* Can be nullptr to read from the unnamed default registry value.
|
||
|
* @param[out] return_value A wil::unique_bstr receiving the value read from the registry
|
||
|
* @return HRESULT error code indicating success or failure (does not throw C++ exceptions)
|
||
|
*/
|
||
|
inline HRESULT get_value_string_nothrow(HKEY key, _In_opt_ PCWSTR subkey, _In_opt_ PCWSTR value_name, ::wil::unique_bstr& return_value) WI_NOEXCEPT
|
||
|
{
|
||
|
return ::wil::reg::get_value_nothrow(key, subkey, value_name, return_value.addressof());
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Reads a REG_SZ value under a specified key
|
||
|
* @param key An open or well-known registry key
|
||
|
* @param value_name The name of the registry value whose data is to be read.
|
||
|
* Can be nullptr to read from the unnamed default registry value.
|
||
|
* @param[out] return_value A wil::unique_bstr receiving the value read from the registry
|
||
|
* @return HRESULT error code indicating success or failure (does not throw C++ exceptions)
|
||
|
*/
|
||
|
inline HRESULT get_value_string_nothrow(HKEY key, _In_opt_ PCWSTR value_name, ::wil::unique_bstr& return_value) WI_NOEXCEPT
|
||
|
{
|
||
|
return ::wil::reg::get_value_string_nothrow(key, nullptr, value_name, return_value);
|
||
|
}
|
||
|
|
||
|
#if defined(__WIL_OLEAUTO_H_STL) || defined(WIL_DOXYGEN)
|
||
|
/**
|
||
|
* @brief Reads a REG_SZ value under a specified key
|
||
|
* @param key An open or well-known registry key
|
||
|
* @param subkey The name of the subkey to append to `key`.
|
||
|
* If `nullptr`, then `key` is used without modification.
|
||
|
* @param value_name The name of the registry value whose data is to be read.
|
||
|
* Can be nullptr to read from the unnamed default registry value.
|
||
|
* @param[out] return_value A wil::shared_bstr receiving the value read from the registry
|
||
|
* @return HRESULT error code indicating success or failure (does not throw C++ exceptions)
|
||
|
*/
|
||
|
inline HRESULT get_value_nothrow(HKEY key, _In_opt_ PCWSTR subkey, _In_opt_ PCWSTR value_name, ::wil::shared_bstr& return_value) WI_NOEXCEPT
|
||
|
{
|
||
|
const reg_view_details::reg_view_nothrow regview{key};
|
||
|
return regview.get_value(subkey, value_name, return_value);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Reads a REG_SZ value under a specified key
|
||
|
* @param key An open or well-known registry key
|
||
|
* @param value_name The name of the registry value whose data is to be read.
|
||
|
* Can be nullptr to read from the unnamed default registry value.
|
||
|
* @param[out] return_value A wil::shared_bstr receiving the value read from the registry
|
||
|
* @return HRESULT error code indicating success or failure (does not throw C++ exceptions)
|
||
|
*/
|
||
|
inline HRESULT get_value_nothrow(HKEY key, _In_opt_ PCWSTR value_name, ::wil::shared_bstr& return_value) WI_NOEXCEPT
|
||
|
{
|
||
|
return ::wil::reg::get_value_nothrow(key, nullptr, value_name, return_value);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Reads a REG_SZ value under a specified key
|
||
|
* @param key An open or well-known registry key
|
||
|
* @param subkey The name of the subkey to append to `key`.
|
||
|
* If `nullptr`, then `key` is used without modification.
|
||
|
* @param value_name The name of the registry value whose data is to be read.
|
||
|
* Can be nullptr to read from the unnamed default registry value.
|
||
|
* @param[out] return_value A wil::shared_bstr receiving the value read from the registry
|
||
|
* @return HRESULT error code indicating success or failure (does not throw C++ exceptions)
|
||
|
*/
|
||
|
inline HRESULT get_value_string_nothrow(HKEY key, _In_opt_ PCWSTR subkey, _In_opt_ PCWSTR value_name, ::wil::shared_bstr& return_value) WI_NOEXCEPT
|
||
|
{
|
||
|
return ::wil::reg::get_value_nothrow(key, subkey, value_name, return_value.addressof());
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Reads a REG_SZ value under a specified key
|
||
|
* @param key An open or well-known registry key
|
||
|
* @param value_name The name of the registry value whose data is to be read.
|
||
|
* Can be nullptr to read from the unnamed default registry value.
|
||
|
* @param[out] return_value A wil::shared_bstr receiving the value read from the registry
|
||
|
* @return HRESULT error code indicating success or failure (does not throw C++ exceptions)
|
||
|
*/
|
||
|
inline HRESULT get_value_string_nothrow(HKEY key, _In_opt_ PCWSTR value_name, ::wil::shared_bstr& return_value) WI_NOEXCEPT
|
||
|
{
|
||
|
return ::wil::reg::get_value_string_nothrow(key, nullptr, value_name, return_value);
|
||
|
}
|
||
|
#endif // #if defined(__WIL_OLEAUTO_H_STL)
|
||
|
#endif // #if defined(__WIL_OLEAUTO_H_)
|
||
|
|
||
|
#if defined(__WIL_OBJBASE_H_) || defined(WIL_DOXYGEN)
|
||
|
/**
|
||
|
* @brief Reads a REG_SZ value under a specified key
|
||
|
* @param key An open or well-known registry key
|
||
|
* @param subkey The name of the subkey to append to `key`.
|
||
|
* If `nullptr`, then `key` is used without modification.
|
||
|
* @param value_name The name of the registry value whose data is to be read.
|
||
|
* Can be nullptr to read from the unnamed default registry value.
|
||
|
* @param[out] return_value A wil::unique_cotaskmem_string receiving the value read from the registry
|
||
|
* @return HRESULT error code indicating success or failure (does not throw C++ exceptions)
|
||
|
*/
|
||
|
inline HRESULT get_value_nothrow(HKEY key, _In_opt_ PCWSTR subkey, _In_opt_ PCWSTR value_name, ::wil::unique_cotaskmem_string& return_value) WI_NOEXCEPT
|
||
|
{
|
||
|
return_value.reset();
|
||
|
const reg_view_details::reg_view_nothrow regview{key};
|
||
|
return regview.get_value(subkey, value_name, return_value);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Reads a REG_SZ value under a specified key
|
||
|
* @param key An open or well-known registry key
|
||
|
* @param value_name The name of the registry value whose data is to be read.
|
||
|
* Can be nullptr to read from the unnamed default registry value.
|
||
|
* @param[out] return_value A wil::unique_cotaskmem_string receiving the value read from the registry
|
||
|
* @return HRESULT error code indicating success or failure (does not throw C++ exceptions)
|
||
|
*/
|
||
|
inline HRESULT get_value_nothrow(HKEY key, _In_opt_ PCWSTR value_name, ::wil::unique_cotaskmem_string& return_value) WI_NOEXCEPT
|
||
|
{
|
||
|
return ::wil::reg::get_value_nothrow(key, nullptr, value_name, return_value);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Reads a REG_SZ value under a specified key
|
||
|
* @param key An open or well-known registry key
|
||
|
* @param subkey The name of the subkey to append to `key`.
|
||
|
* If `nullptr`, then `key` is used without modification.
|
||
|
* @param value_name The name of the registry value whose data is to be read.
|
||
|
* Can be nullptr to read from the unnamed default registry value.
|
||
|
* @param[out] return_value A wil::unique_cotaskmem_string receiving the value read from the registry
|
||
|
* @return HRESULT error code indicating success or failure (does not throw C++ exceptions)
|
||
|
*/
|
||
|
inline HRESULT get_value_string_nothrow(
|
||
|
HKEY key, _In_opt_ PCWSTR subkey, _In_opt_ PCWSTR value_name, ::wil::unique_cotaskmem_string& return_value) WI_NOEXCEPT
|
||
|
{
|
||
|
return ::wil::reg::get_value_nothrow(key, subkey, value_name, return_value);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Reads a REG_SZ value under a specified key
|
||
|
* @param key An open or well-known registry key
|
||
|
* @param value_name The name of the registry value whose data is to be read.
|
||
|
* Can be nullptr to read from the unnamed default registry value.
|
||
|
* @param[out] return_value A wil::unique_cotaskmem_string receiving the value read from the registry
|
||
|
* @return HRESULT error code indicating success or failure (does not throw C++ exceptions)
|
||
|
*/
|
||
|
inline HRESULT get_value_string_nothrow(HKEY key, _In_opt_ PCWSTR value_name, ::wil::unique_cotaskmem_string& return_value) WI_NOEXCEPT
|
||
|
{
|
||
|
return ::wil::reg::get_value_nothrow(key, nullptr, value_name, return_value);
|
||
|
}
|
||
|
|
||
|
#if defined(__WIL_OBJBASE_H_STL) || defined(WIL_DOXYGEN)
|
||
|
/**
|
||
|
* @brief Reads a REG_SZ value under a specified key
|
||
|
* @param key An open or well-known registry key
|
||
|
* @param subkey The name of the subkey to append to `key`.
|
||
|
* If `nullptr`, then `key` is used without modification.
|
||
|
* @param value_name The name of the registry value whose data is to be read.
|
||
|
* Can be nullptr to read from the unnamed default registry value.
|
||
|
* @param[out] return_value A wil::shared_cotaskmem_string receiving the value read from the registry
|
||
|
* @return HRESULT error code indicating success or failure (does not throw C++ exceptions)
|
||
|
*/
|
||
|
inline HRESULT get_value_nothrow(HKEY key, _In_opt_ PCWSTR subkey, _In_opt_ PCWSTR value_name, ::wil::shared_cotaskmem_string& return_value) WI_NOEXCEPT
|
||
|
{
|
||
|
return_value.reset();
|
||
|
const reg_view_details::reg_view_nothrow regview{key};
|
||
|
return regview.get_value(subkey, value_name, return_value);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Reads a REG_SZ value under a specified key
|
||
|
* @param key An open or well-known registry key
|
||
|
* @param value_name The name of the registry value whose data is to be read.
|
||
|
* Can be nullptr to read from the unnamed default registry value.
|
||
|
* @param[out] return_value A wil::shared_cotaskmem_string receiving the value read from the registry
|
||
|
* @return HRESULT error code indicating success or failure (does not throw C++ exceptions)
|
||
|
*/
|
||
|
inline HRESULT get_value_nothrow(HKEY key, _In_opt_ PCWSTR value_name, ::wil::shared_cotaskmem_string& return_value) WI_NOEXCEPT
|
||
|
{
|
||
|
return ::wil::reg::get_value_nothrow(key, nullptr, value_name, return_value);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Reads a REG_SZ value under a specified key
|
||
|
* @param key An open or well-known registry key
|
||
|
* @param subkey The name of the subkey to append to `key`.
|
||
|
* If `nullptr`, then `key` is used without modification.
|
||
|
* @param value_name The name of the registry value whose data is to be read.
|
||
|
* Can be nullptr to read from the unnamed default registry value.
|
||
|
* @param[out] return_value A wil::shared_cotaskmem_string receiving the value read from the registry
|
||
|
* @return HRESULT error code indicating success or failure (does not throw C++ exceptions)
|
||
|
*/
|
||
|
inline HRESULT get_value_string_nothrow(
|
||
|
HKEY key, _In_opt_ PCWSTR subkey, _In_opt_ PCWSTR value_name, ::wil::shared_cotaskmem_string& return_value) WI_NOEXCEPT
|
||
|
{
|
||
|
return ::wil::reg::get_value_nothrow(key, subkey, value_name, return_value);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Reads a REG_SZ value under a specified key
|
||
|
* @param key An open or well-known registry key
|
||
|
* @param value_name The name of the registry value whose data is to be read.
|
||
|
* Can be nullptr to read from the unnamed default registry value.
|
||
|
* @param[out] return_value A wil::shared_cotaskmem_string receiving the value read from the registry
|
||
|
* @return HRESULT error code indicating success or failure (does not throw C++ exceptions)
|
||
|
*/
|
||
|
inline HRESULT get_value_string_nothrow(HKEY key, _In_opt_ PCWSTR value_name, ::wil::shared_cotaskmem_string& return_value) WI_NOEXCEPT
|
||
|
{
|
||
|
return ::wil::reg::get_value_nothrow(key, nullptr, value_name, return_value);
|
||
|
}
|
||
|
#endif // #if defined(__WIL_OBJBASE_H_STL)
|
||
|
#endif // defined(__WIL_OBJBASE_H_)
|
||
|
|
||
|
#if defined(__WIL_OBJBASE_H_) || defined(WIL_DOXYGEN)
|
||
|
/**
|
||
|
* @brief Reads the raw bytes from a registry value under a specified key of the specified type
|
||
|
* @param key An open or well-known registry key
|
||
|
* @param subkey The name of the subkey to append to `key`.
|
||
|
* If `nullptr`, then `key` is used without modification.
|
||
|
* @param value_name The name of the registry value whose data is to be read.
|
||
|
* Can be nullptr to read from the unnamed default registry value.
|
||
|
* @param type The registry type for the specified registry value to read from - see RegGetValueW
|
||
|
* @param[out] return_value A ::wil::unique_cotaskmem_array_ptr<BYTE> receiving the value read from the registry
|
||
|
* @return HRESULT error code indicating success or failure (does not throw C++ exceptions)
|
||
|
*/
|
||
|
inline HRESULT get_value_binary_nothrow(
|
||
|
HKEY key, _In_opt_ PCWSTR subkey, _In_opt_ PCWSTR value_name, uint32_t type, ::wil::unique_cotaskmem_array_ptr<uint8_t>& return_value) WI_NOEXCEPT
|
||
|
{
|
||
|
// zero the vector if it already had a buffer
|
||
|
for (auto& byte_value : return_value)
|
||
|
{
|
||
|
byte_value = 0x00;
|
||
|
}
|
||
|
const reg_view_details::reg_view_nothrow regview{key};
|
||
|
RETURN_IF_FAILED(regview.get_value<::wil::unique_cotaskmem_array_ptr<uint8_t>>(subkey, value_name, return_value, type));
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Reads the raw bytes from a registry value under a specified key of the specified type
|
||
|
* @param key An open or well-known registry key
|
||
|
* @param value_name The name of the registry value whose data is to be read.
|
||
|
* Can be nullptr to read from the unnamed default registry value.
|
||
|
* @param type The registry type for the specified registry value to read from - see RegGetValueW
|
||
|
* @param[out] return_value A ::wil::unique_cotaskmem_array_ptr<BYTE> receiving the value read from the registry
|
||
|
* @return HRESULT error code indicating success or failure (does not throw C++ exceptions)
|
||
|
*/
|
||
|
inline HRESULT get_value_binary_nothrow(
|
||
|
HKEY key, _In_opt_ PCWSTR value_name, uint32_t type, ::wil::unique_cotaskmem_array_ptr<uint8_t>& return_value) WI_NOEXCEPT
|
||
|
{
|
||
|
return ::wil::reg::get_value_binary_nothrow(key, nullptr, value_name, type, return_value);
|
||
|
}
|
||
|
#endif // #if defined(__WIL_OBJBASE_H_)
|
||
|
|
||
|
/**
|
||
|
* @brief Reads a REG_EXPAND_SZ value under a specified key
|
||
|
* @tparam Length The length of the WCHAR array passed as an OUT parameter
|
||
|
* @param key An open or well-known registry key
|
||
|
* @param subkey The name of the subkey to append to `key`.
|
||
|
* If `nullptr`, then `key` is used without modification.
|
||
|
* @param value_name The name of the registry value whose data is to be read.
|
||
|
* Can be nullptr to read from the unnamed default registry value.
|
||
|
* @param[out] return_value A WCHAR array receiving the value read from the registry,
|
||
|
* with environment variables expanded, as though passed through ExpandEnvironmentStringsW.
|
||
|
* Will write to the WCHAR array the string value read from the registry, guaranteeing null-termination
|
||
|
* @param[out] requiredBytes An optional pointer to a uint32_t to receive the required bytes of the string to be read
|
||
|
* @return HRESULT error code indicating success or failure (does not throw C++ exceptions)
|
||
|
*/
|
||
|
template <size_t Length, typename DwordType, wistd::enable_if_t<wistd::is_same_v<DwordType, uint32_t> || wistd::is_same_v<DwordType, unsigned long>>* = nullptr>
|
||
|
HRESULT get_value_expanded_string_nothrow(
|
||
|
HKEY key, _In_opt_ PCWSTR subkey, _In_opt_ PCWSTR value_name, WCHAR (&return_value)[Length], _Out_opt_ DwordType* requiredBytes) WI_NOEXCEPT
|
||
|
{
|
||
|
const reg_view_details::reg_view_nothrow regview{key};
|
||
|
return regview.get_value_char_array(subkey, value_name, return_value, REG_EXPAND_SZ, requiredBytes);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Reads a REG_EXPAND_SZ value under a specified key
|
||
|
* @tparam Length The length of the WCHAR array passed as an OUT parameter
|
||
|
* @param key An open or well-known registry key
|
||
|
* @param value_name The name of the registry value whose data is to be read.
|
||
|
* Can be nullptr to read from the unnamed default registry value.
|
||
|
* @param[out] return_value A WCHAR array receiving the value read from the registry,
|
||
|
* with environment variables expanded, as though passed through ExpandEnvironmentStringsW.
|
||
|
* Will write to the WCHAR array the string value read from the registry, guaranteeing null-termination
|
||
|
* @param[out] requiredBytes An optional pointer to a uint32_t to receive the required bytes of the string to be read
|
||
|
* @return HRESULT error code indicating success or failure (does not throw C++ exceptions)
|
||
|
*/
|
||
|
template <size_t Length, typename DwordType, wistd::enable_if_t<wistd::is_same_v<DwordType, uint32_t> || wistd::is_same_v<DwordType, unsigned long>>* = nullptr>
|
||
|
HRESULT get_value_expanded_string_nothrow(
|
||
|
HKEY key, _In_opt_ PCWSTR value_name, WCHAR (&return_value)[Length], _Out_opt_ DwordType* requiredBytes) WI_NOEXCEPT
|
||
|
{
|
||
|
return ::wil::reg::get_value_expanded_string_nothrow<Length>(key, nullptr, value_name, return_value, requiredBytes);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Reads a REG_EXPAND_SZ value under a specified key
|
||
|
* @tparam Length The length of the WCHAR array passed as an OUT parameter
|
||
|
* @param key An open or well-known registry key
|
||
|
* @param subkey The name of the subkey to append to `key`.
|
||
|
* If `nullptr`, then `key` is used without modification.
|
||
|
* @param value_name The name of the registry value whose data is to be read.
|
||
|
* Can be nullptr to read from the unnamed default registry value.
|
||
|
* @param[out] return_value A WCHAR array receiving the value read from the registry,
|
||
|
* with environment variables expanded, as though passed through ExpandEnvironmentStringsW.
|
||
|
* Will write to the WCHAR array the string value read from the registry, guaranteeing null-termination
|
||
|
* @return HRESULT error code indicating success or failure (does not throw C++ exceptions)
|
||
|
*/
|
||
|
template <size_t Length>
|
||
|
HRESULT get_value_expanded_string_nothrow(HKEY key, _In_opt_ PCWSTR subkey, _In_opt_ PCWSTR value_name, WCHAR (&return_value)[Length]) WI_NOEXCEPT
|
||
|
{
|
||
|
constexpr uint32_t* null_out_param = nullptr;
|
||
|
const reg_view_details::reg_view_nothrow regview{key};
|
||
|
return regview.get_value_char_array(subkey, value_name, return_value, REG_EXPAND_SZ, null_out_param);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Reads a REG_EXPAND_SZ value under a specified key
|
||
|
* @tparam Length The length of the WCHAR array passed as an OUT parameter
|
||
|
* @param key An open or well-known registry key
|
||
|
* @param value_name The name of the registry value whose data is to be read.
|
||
|
* Can be nullptr to read from the unnamed default registry value.
|
||
|
* @param[out] return_value A WCHAR array receiving the value read from the registry,
|
||
|
* with environment variables expanded, as though passed through ExpandEnvironmentStringsW.
|
||
|
* Will write to the WCHAR array the string value read from the registry, guaranteeing null-termination
|
||
|
* @return HRESULT error code indicating success or failure (does not throw C++ exceptions)
|
||
|
*/
|
||
|
template <size_t Length>
|
||
|
HRESULT get_value_expanded_string_nothrow(HKEY key, _In_opt_ PCWSTR value_name, WCHAR (&return_value)[Length]) WI_NOEXCEPT
|
||
|
{
|
||
|
return ::wil::reg::get_value_expanded_string_nothrow<Length>(key, nullptr, value_name, return_value);
|
||
|
}
|
||
|
|
||
|
#if defined(__WIL_OLEAUTO_H_) || defined(WIL_DOXYGEN)
|
||
|
/**
|
||
|
* @brief Reads a REG_EXPAND_SZ value under a specified key
|
||
|
* @param key An open or well-known registry key
|
||
|
* @param subkey The name of the subkey to append to `key`.
|
||
|
* If `nullptr`, then `key` is used without modification.
|
||
|
* @param value_name The name of the registry value whose data is to be read.
|
||
|
* Can be nullptr to read from the unnamed default registry value.
|
||
|
* @param[out] return_value A wil::unique_bstr receiving the value read from the registry,
|
||
|
* with environment variables expanded, as though passed through ExpandEnvironmentStringsW.
|
||
|
* @return HRESULT error code indicating success or failure (does not throw C++ exceptions)
|
||
|
*/
|
||
|
inline HRESULT get_value_expanded_string_nothrow(HKEY key, _In_opt_ PCWSTR subkey, _In_opt_ PCWSTR value_name, ::wil::unique_bstr& return_value) WI_NOEXCEPT
|
||
|
{
|
||
|
const reg_view_details::reg_view_nothrow regview{key};
|
||
|
return regview.get_value<::wil::unique_bstr>(subkey, value_name, return_value, REG_EXPAND_SZ);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Reads a REG_EXPAND_SZ value under a specified key
|
||
|
* @param key An open or well-known registry key
|
||
|
* @param value_name The name of the registry value whose data is to be read.
|
||
|
* Can be nullptr to read from the unnamed default registry value.
|
||
|
* @param[out] return_value A wil::unique_bstr receiving the value read from the registry,
|
||
|
* with environment variables expanded, as though passed through ExpandEnvironmentStringsW.
|
||
|
* @return HRESULT error code indicating success or failure (does not throw C++ exceptions)
|
||
|
*/
|
||
|
inline HRESULT get_value_expanded_string_nothrow(HKEY key, _In_opt_ PCWSTR value_name, ::wil::unique_bstr& return_value) WI_NOEXCEPT
|
||
|
{
|
||
|
return ::wil::reg::get_value_expanded_string_nothrow(key, nullptr, value_name, return_value);
|
||
|
}
|
||
|
|
||
|
#if defined(__WIL_OLEAUTO_H_STL) || defined(WIL_DOXYGEN)
|
||
|
/**
|
||
|
* @brief Reads a REG_EXPAND_SZ value under a specified key
|
||
|
* @param key An open or well-known registry key
|
||
|
* @param subkey The name of the subkey to append to `key`.
|
||
|
* If `nullptr`, then `key` is used without modification.
|
||
|
* @param value_name The name of the registry value whose data is to be read.
|
||
|
* Can be nullptr to read from the unnamed default registry value.
|
||
|
* @param[out] return_value A wil::shared_bstr receiving the value read from the registry,
|
||
|
* with environment variables expanded, as though passed through ExpandEnvironmentStringsW.
|
||
|
* @return HRESULT error code indicating success or failure (does not throw C++ exceptions)
|
||
|
*/
|
||
|
inline HRESULT get_value_expanded_string_nothrow(HKEY key, _In_opt_ PCWSTR subkey, _In_opt_ PCWSTR value_name, ::wil::shared_bstr& return_value) WI_NOEXCEPT
|
||
|
{
|
||
|
const reg_view_details::reg_view_nothrow regview{key};
|
||
|
return regview.get_value<::wil::shared_bstr>(subkey, value_name, return_value, REG_EXPAND_SZ);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Reads a REG_EXPAND_SZ value under a specified key
|
||
|
* @param key An open or well-known registry key
|
||
|
* @param value_name The name of the registry value whose data is to be read.
|
||
|
* Can be nullptr to read from the unnamed default registry value.
|
||
|
* @param[out] return_value A wil::shared_bstr receiving the value read from the registry,
|
||
|
* with environment variables expanded, as though passed through ExpandEnvironmentStringsW.
|
||
|
* @return HRESULT error code indicating success or failure (does not throw C++ exceptions)
|
||
|
*/
|
||
|
inline HRESULT get_value_expanded_string_nothrow(HKEY key, _In_opt_ PCWSTR value_name, ::wil::shared_bstr& return_value) WI_NOEXCEPT
|
||
|
{
|
||
|
return ::wil::reg::get_value_expanded_string_nothrow(key, nullptr, value_name, return_value);
|
||
|
}
|
||
|
#endif // #if defined(__WIL_OLEAUTO_H_STL)
|
||
|
#endif // #if defined(__WIL_OLEAUTO_H_)
|
||
|
|
||
|
#if defined(__WIL_OBJBASE_H_) || defined(WIL_DOXYGEN)
|
||
|
/**
|
||
|
* @brief Reads a REG_EXPAND_SZ value under a specified key
|
||
|
* @param key An open or well-known registry key
|
||
|
* @param subkey The name of the subkey to append to `key`.
|
||
|
* If `nullptr`, then `key` is used without modification.
|
||
|
* @param value_name The name of the registry value whose data is to be read.
|
||
|
* Can be nullptr to read from the unnamed default registry value.
|
||
|
* @param[out] return_value A wil::unique_cotaskmem_string receiving the value read from the registry,
|
||
|
* with environment variables expanded, as though passed through ExpandEnvironmentStringsW.
|
||
|
* @return HRESULT error code indicating success or failure (does not throw C++ exceptions)
|
||
|
*/
|
||
|
inline HRESULT get_value_expanded_string_nothrow(
|
||
|
HKEY key, _In_opt_ PCWSTR subkey, _In_opt_ PCWSTR value_name, ::wil::unique_cotaskmem_string& return_value) WI_NOEXCEPT
|
||
|
{
|
||
|
const reg_view_details::reg_view_nothrow regview{key};
|
||
|
return regview.get_value<::wil::unique_cotaskmem_string>(subkey, value_name, return_value, REG_EXPAND_SZ);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Reads a REG_EXPAND_SZ value under a specified key
|
||
|
* @param key An open or well-known registry key
|
||
|
* @param value_name The name of the registry value whose data is to be read.
|
||
|
* Can be nullptr to read from the unnamed default registry value.
|
||
|
* @param[out] return_value A wil::unique_cotaskmem_string receiving the value read from the registry,
|
||
|
* with environment variables expanded, as though passed through ExpandEnvironmentStringsW.
|
||
|
* @return HRESULT error code indicating success or failure (does not throw C++ exceptions)
|
||
|
*/
|
||
|
inline HRESULT get_value_expanded_string_nothrow(HKEY key, _In_opt_ PCWSTR value_name, ::wil::unique_cotaskmem_string& return_value) WI_NOEXCEPT
|
||
|
{
|
||
|
return ::wil::reg::get_value_expanded_string_nothrow(key, nullptr, value_name, return_value);
|
||
|
}
|
||
|
|
||
|
#if defined(__WIL_OBJBASE_H_STL) || defined(WIL_DOXYGEN)
|
||
|
/**
|
||
|
* @brief Reads a REG_EXPAND_SZ value under a specified key
|
||
|
* @param key An open or well-known registry key
|
||
|
* @param subkey The name of the subkey to append to `key`.
|
||
|
* If `nullptr`, then `key` is used without modification.
|
||
|
* @param value_name The name of the registry value whose data is to be read.
|
||
|
* Can be nullptr to read from the unnamed default registry value.
|
||
|
* @param[out] return_value A wil::shared_cotaskmem_string receiving the value read from the registry,
|
||
|
* with environment variables expanded, as though passed through ExpandEnvironmentStringsW.
|
||
|
* @return HRESULT error code indicating success or failure (does not throw C++ exceptions)
|
||
|
*/
|
||
|
inline HRESULT get_value_expanded_string_nothrow(
|
||
|
HKEY key, _In_opt_ PCWSTR subkey, _In_opt_ PCWSTR value_name, ::wil::shared_cotaskmem_string& return_value) WI_NOEXCEPT
|
||
|
{
|
||
|
const reg_view_details::reg_view_nothrow regview{key};
|
||
|
return regview.get_value<::wil::shared_cotaskmem_string>(subkey, value_name, return_value, REG_EXPAND_SZ);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Reads a REG_EXPAND_SZ value under a specified key
|
||
|
* @param key An open or well-known registry key
|
||
|
* @param value_name The name of the registry value whose data is to be read.
|
||
|
* Can be nullptr to read from the unnamed default registry value.
|
||
|
* @param[out] return_value A wil::shared_cotaskmem_string receiving the value read from the registry,
|
||
|
* with environment variables expanded, as though passed through ExpandEnvironmentStringsW.
|
||
|
* @return HRESULT error code indicating success or failure (does not throw C++ exceptions)
|
||
|
*/
|
||
|
inline HRESULT get_value_expanded_string_nothrow(HKEY key, _In_opt_ PCWSTR value_name, ::wil::shared_cotaskmem_string& return_value) WI_NOEXCEPT
|
||
|
{
|
||
|
return ::wil::reg::get_value_expanded_string_nothrow(key, nullptr, value_name, return_value);
|
||
|
}
|
||
|
#endif // #if defined(__WIL_OBJBASE_H_STL)
|
||
|
#endif // defined(__WIL_OBJBASE_H_)
|
||
|
|
||
|
#if defined(__WIL_OBJBASE_H_) || defined(WIL_DOXYGEN)
|
||
|
/**
|
||
|
* @brief Reads a REG_MULTI_SZ value under a specified key
|
||
|
* @param key An open or well-known registry key
|
||
|
* @param subkey The name of the subkey to append to `key`.
|
||
|
* If `nullptr`, then `key` is used without modification.
|
||
|
* @param value_name The name of the registry value whose data is to be read.
|
||
|
* Can be nullptr to read from the unnamed default registry value.
|
||
|
* @param[out] return_value A ::wil::unique_cotaskmem_array_ptr<::wil::unique_cotaskmem_string> receiving the value read from
|
||
|
* the registry
|
||
|
* @return HRESULT error code indicating success or failure (does not throw C++ exceptions)
|
||
|
*/
|
||
|
inline HRESULT get_value_nothrow(
|
||
|
HKEY key,
|
||
|
_In_opt_ PCWSTR subkey,
|
||
|
_In_opt_ PCWSTR value_name,
|
||
|
::wil::unique_cotaskmem_array_ptr<::wil::unique_cotaskmem_string>& return_value) WI_NOEXCEPT
|
||
|
{
|
||
|
::wil::unique_cotaskmem_array_ptr<uint8_t> rawData;
|
||
|
RETURN_IF_FAILED(::wil::reg::get_value_binary_nothrow(key, subkey, value_name, REG_MULTI_SZ, rawData));
|
||
|
if (!rawData.empty())
|
||
|
{
|
||
|
auto* const begin = reinterpret_cast<wchar_t*>(rawData.data());
|
||
|
auto* const end = begin + rawData.size() / sizeof(wchar_t);
|
||
|
::wil::reg::reg_view_details::get_cotaskmemstring_array_from_multistring_nothrow(begin, end, return_value);
|
||
|
}
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Reads a REG_MULTI_SZ value under a specified key
|
||
|
* @param key An open or well-known registry key
|
||
|
* @param value_name The name of the registry value whose data is to be read.
|
||
|
* Can be nullptr to read from the unnamed default registry value.
|
||
|
* @param[out] return_value A ::wil::unique_cotaskmem_array_ptr<::wil::unique_cotaskmem_string> receiving the value read from
|
||
|
* the registry
|
||
|
* @return HRESULT error code indicating success or failure (does not throw C++ exceptions)
|
||
|
*/
|
||
|
inline HRESULT get_value_nothrow(
|
||
|
HKEY key, _In_opt_ PCWSTR value_name, ::wil::unique_cotaskmem_array_ptr<::wil::unique_cotaskmem_string>& return_value) WI_NOEXCEPT
|
||
|
{
|
||
|
return ::wil::reg::get_value_nothrow(key, nullptr, value_name, return_value);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Reads a REG_MULTI_SZ value under a specified key
|
||
|
* @param key An open or well-known registry key
|
||
|
* @param subkey The name of the subkey to append to `key`.
|
||
|
* If `nullptr`, then `key` is used without modification.
|
||
|
* @param value_name The name of the registry value whose data is to be read.
|
||
|
* Can be nullptr to read from the unnamed default registry value.
|
||
|
* @param[out] return_value A ::wil::unique_cotaskmem_array_ptr<::wil::unique_cotaskmem_string> receiving the value read from
|
||
|
* the registry
|
||
|
* @return HRESULT error code indicating success or failure (does not throw C++ exceptions)
|
||
|
*/
|
||
|
inline HRESULT get_value_multistring_nothrow(
|
||
|
HKEY key,
|
||
|
_In_opt_ PCWSTR subkey,
|
||
|
_In_opt_ PCWSTR value_name,
|
||
|
::wil::unique_cotaskmem_array_ptr<::wil::unique_cotaskmem_string>& return_value) WI_NOEXCEPT
|
||
|
{
|
||
|
return ::wil::reg::get_value_nothrow(key, subkey, value_name, return_value);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Reads a REG_MULTI_SZ value under a specified key
|
||
|
* @param key An open or well-known registry key
|
||
|
* @param value_name The name of the registry value whose data is to be read.
|
||
|
* Can be nullptr to read from the unnamed default registry value.
|
||
|
* @param[out] return_value A ::wil::unique_cotaskmem_array_ptr<::wil::unique_cotaskmem_string> receiving the value read from
|
||
|
* the registry
|
||
|
* @return HRESULT error code indicating success or failure (does not throw C++ exceptions)
|
||
|
*/
|
||
|
inline HRESULT get_value_multistring_nothrow(
|
||
|
HKEY key, _In_opt_ PCWSTR value_name, ::wil::unique_cotaskmem_array_ptr<::wil::unique_cotaskmem_string>& return_value) WI_NOEXCEPT
|
||
|
{
|
||
|
return ::wil::reg::get_value_nothrow(key, nullptr, value_name, return_value);
|
||
|
}
|
||
|
#endif // #if defined(__WIL_OBJBASE_H_)
|
||
|
} // namespace reg
|
||
|
|
||
|
// unique_registry_watcher/unique_registry_watcher_nothrow/unique_registry_watcher_failfast
|
||
|
// These classes make it easy to execute a provided function when a
|
||
|
// registry key changes (optionally recursively). Specify the key
|
||
|
// either as a root key + path, or an open registry handle as wil::unique_hkey
|
||
|
// or a raw HKEY value (that will be duplicated).
|
||
|
//
|
||
|
// Example use with exceptions base error handling:
|
||
|
// auto watcher = wil::make_registry_watcher(HKEY_CURRENT_USER, L"Software\\MyApp", true, wil::RegistryChangeKind changeKind[]
|
||
|
// {
|
||
|
// if (changeKind == RegistryChangeKind::Delete)
|
||
|
// {
|
||
|
// watcher.reset();
|
||
|
// }
|
||
|
// // invalidate cached registry data here
|
||
|
// });
|
||
|
//
|
||
|
// Example use with error code base error handling:
|
||
|
// auto watcher = wil::make_registry_watcher_nothrow(HKEY_CURRENT_USER, L"Software\\MyApp", true, wil::RegistryChangeKind[]
|
||
|
// {
|
||
|
// // invalidate cached registry data here
|
||
|
// });
|
||
|
// RETURN_IF_NULL_ALLOC(watcher);
|
||
|
|
||
|
enum class RegistryChangeKind
|
||
|
{
|
||
|
Modify = 0,
|
||
|
Delete = 1,
|
||
|
};
|
||
|
|
||
|
/// @cond
|
||
|
namespace details
|
||
|
{
|
||
|
struct registry_watcher_state
|
||
|
{
|
||
|
registry_watcher_state(unique_hkey&& keyToWatch, bool isRecursive, wistd::function<void(RegistryChangeKind)>&& callback) :
|
||
|
m_callback(wistd::move(callback)), m_keyToWatch(wistd::move(keyToWatch)), m_isRecursive(isRecursive)
|
||
|
{
|
||
|
}
|
||
|
wistd::function<void(RegistryChangeKind)> m_callback;
|
||
|
unique_hkey m_keyToWatch;
|
||
|
unique_event_nothrow m_eventHandle;
|
||
|
|
||
|
// While not strictly needed since this is ref counted the thread pool wait
|
||
|
// should be last to ensure that the other members are valid
|
||
|
// when it is destructed as it will reference them.
|
||
|
unique_threadpool_wait m_threadPoolWait;
|
||
|
bool m_isRecursive;
|
||
|
|
||
|
volatile long m_refCount = 1;
|
||
|
srwlock m_lock;
|
||
|
|
||
|
// Returns true if the ref-count can be increased from a non zero value,
|
||
|
// false it was zero implying that the object is in or on the way to the destructor.
|
||
|
// In this case ReleaseFromCallback() should not be called.
|
||
|
bool TryAddRef()
|
||
|
{
|
||
|
return ::InterlockedIncrement(&m_refCount) > 1;
|
||
|
}
|
||
|
|
||
|
void Release()
|
||
|
{
|
||
|
auto lock = m_lock.lock_exclusive();
|
||
|
if (0 == ::InterlockedDecrement(&m_refCount))
|
||
|
{
|
||
|
lock.reset(); // leave the lock before deleting it.
|
||
|
delete this;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void ReleaseFromCallback(bool rearm)
|
||
|
{
|
||
|
auto lock = m_lock.lock_exclusive();
|
||
|
if (0 == ::InterlockedDecrement(&m_refCount))
|
||
|
{
|
||
|
// Destroy the thread pool wait now to avoid the wait that would occur in the
|
||
|
// destructor. That wait would cause a deadlock since we are doing this from the callback.
|
||
|
::CloseThreadpoolWait(m_threadPoolWait.release());
|
||
|
lock.reset(); // leave the lock before deleting it.
|
||
|
delete this;
|
||
|
// Sleep(1); // Enable for testing to find use after free bugs.
|
||
|
}
|
||
|
else if (rearm)
|
||
|
{
|
||
|
::SetThreadpoolWait(m_threadPoolWait.get(), m_eventHandle.get(), nullptr);
|
||
|
}
|
||
|
}
|
||
|
};
|
||
|
|
||
|
inline void delete_registry_watcher_state(_In_opt_ registry_watcher_state* watcherStorage)
|
||
|
{
|
||
|
watcherStorage->Release();
|
||
|
}
|
||
|
|
||
|
typedef resource_policy<registry_watcher_state*, decltype(&details::delete_registry_watcher_state), details::delete_registry_watcher_state, details::pointer_access_none>
|
||
|
registry_watcher_state_resource_policy;
|
||
|
} // namespace details
|
||
|
/// @endcond
|
||
|
|
||
|
template <typename storage_t, typename err_policy = err_exception_policy>
|
||
|
class registry_watcher_t : public storage_t
|
||
|
{
|
||
|
public:
|
||
|
// forward all base class constructors...
|
||
|
template <typename... args_t>
|
||
|
explicit registry_watcher_t(args_t&&... args) WI_NOEXCEPT : storage_t(wistd::forward<args_t>(args)...)
|
||
|
{
|
||
|
}
|
||
|
|
||
|
// HRESULT or void error handling...
|
||
|
typedef typename err_policy::result result;
|
||
|
|
||
|
// Exception-based constructors
|
||
|
registry_watcher_t(HKEY rootKey, _In_ PCWSTR subKey, bool isRecursive, wistd::function<void(RegistryChangeKind)>&& callback)
|
||
|
{
|
||
|
static_assert(wistd::is_same<void, result>::value, "this constructor requires exceptions; use the create method");
|
||
|
create(rootKey, subKey, isRecursive, wistd::move(callback));
|
||
|
}
|
||
|
|
||
|
registry_watcher_t(unique_hkey&& keyToWatch, bool isRecursive, wistd::function<void(RegistryChangeKind)>&& callback)
|
||
|
{
|
||
|
static_assert(wistd::is_same<void, result>::value, "this constructor requires exceptions; use the create method");
|
||
|
create(wistd::move(keyToWatch), isRecursive, wistd::move(callback));
|
||
|
}
|
||
|
|
||
|
// Pass a root key, sub key pair or use an empty string to use rootKey as the key to watch.
|
||
|
result create(HKEY rootKey, _In_ PCWSTR subKey, bool isRecursive, wistd::function<void(RegistryChangeKind)>&& callback)
|
||
|
{
|
||
|
// Most use will want to create the key, consider adding an option for open as a future design change.
|
||
|
unique_hkey keyToWatch;
|
||
|
HRESULT hr = HRESULT_FROM_WIN32(RegCreateKeyExW(rootKey, subKey, 0, nullptr, 0, KEY_NOTIFY, nullptr, &keyToWatch, nullptr));
|
||
|
if (FAILED(hr))
|
||
|
{
|
||
|
return err_policy::HResult(hr);
|
||
|
}
|
||
|
return err_policy::HResult(create_common(wistd::move(keyToWatch), isRecursive, wistd::move(callback)));
|
||
|
}
|
||
|
|
||
|
result create(unique_hkey&& keyToWatch, bool isRecursive, wistd::function<void(RegistryChangeKind)>&& callback)
|
||
|
{
|
||
|
return err_policy::HResult(create_common(wistd::move(keyToWatch), isRecursive, wistd::move(callback)));
|
||
|
}
|
||
|
|
||
|
private:
|
||
|
// Factored into a standalone function to support Clang which does not support conversion of stateless lambdas
|
||
|
// to __stdcall
|
||
|
static void __stdcall callback(PTP_CALLBACK_INSTANCE, void* context, TP_WAIT*, TP_WAIT_RESULT)
|
||
|
{
|
||
|
#ifndef __WIL_REGISTRY_CHANGE_CALLBACK_TEST
|
||
|
#define __WIL_REGISTRY_CHANGE_CALLBACK_TEST
|
||
|
#endif
|
||
|
__WIL_REGISTRY_CHANGE_CALLBACK_TEST
|
||
|
const auto watcherState = static_cast<details::registry_watcher_state*>(context);
|
||
|
if (watcherState->TryAddRef())
|
||
|
{
|
||
|
// using auto reset event so don't need to manually reset.
|
||
|
|
||
|
// failure here is a programming error.
|
||
|
const LSTATUS error = RegNotifyChangeKeyValue(
|
||
|
watcherState->m_keyToWatch.get(),
|
||
|
watcherState->m_isRecursive,
|
||
|
REG_NOTIFY_CHANGE_LAST_SET | REG_NOTIFY_CHANGE_NAME | REG_NOTIFY_THREAD_AGNOSTIC,
|
||
|
watcherState->m_eventHandle.get(),
|
||
|
TRUE);
|
||
|
|
||
|
// Call the client before re-arming to ensure that multiple callbacks don't
|
||
|
// run concurrently.
|
||
|
switch (error)
|
||
|
{
|
||
|
case ERROR_SUCCESS:
|
||
|
case ERROR_ACCESS_DENIED:
|
||
|
// Normal modification: send RegistryChangeKind::Modify and re-arm.
|
||
|
watcherState->m_callback(RegistryChangeKind::Modify);
|
||
|
watcherState->ReleaseFromCallback(true);
|
||
|
break;
|
||
|
|
||
|
case ERROR_KEY_DELETED:
|
||
|
// Key deleted, send RegistryChangeKind::Delete, do not re-arm.
|
||
|
watcherState->m_callback(RegistryChangeKind::Delete);
|
||
|
watcherState->ReleaseFromCallback(false);
|
||
|
break;
|
||
|
|
||
|
case ERROR_HANDLE_REVOKED:
|
||
|
// Handle revoked. This can occur if the user session ends before
|
||
|
// the watcher shuts-down. Disarm silently since there is generally no way to respond.
|
||
|
watcherState->ReleaseFromCallback(false);
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
FAIL_FAST_HR(HRESULT_FROM_WIN32(error));
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// This function exists to avoid template expansion of this code based on err_policy.
|
||
|
HRESULT create_common(unique_hkey&& keyToWatch, bool isRecursive, wistd::function<void(RegistryChangeKind)>&& callback)
|
||
|
{
|
||
|
wistd::unique_ptr<details::registry_watcher_state> watcherState(
|
||
|
new (std::nothrow) details::registry_watcher_state(wistd::move(keyToWatch), isRecursive, wistd::move(callback)));
|
||
|
RETURN_IF_NULL_ALLOC(watcherState);
|
||
|
RETURN_IF_FAILED(watcherState->m_eventHandle.create());
|
||
|
RETURN_IF_WIN32_ERROR(RegNotifyChangeKeyValue(
|
||
|
watcherState->m_keyToWatch.get(),
|
||
|
watcherState->m_isRecursive,
|
||
|
REG_NOTIFY_CHANGE_LAST_SET | REG_NOTIFY_CHANGE_NAME | REG_NOTIFY_THREAD_AGNOSTIC,
|
||
|
watcherState->m_eventHandle.get(),
|
||
|
TRUE));
|
||
|
|
||
|
watcherState->m_threadPoolWait.reset(CreateThreadpoolWait(®istry_watcher_t::callback, watcherState.get(), nullptr));
|
||
|
RETURN_LAST_ERROR_IF(!watcherState->m_threadPoolWait);
|
||
|
storage_t::reset(watcherState.release()); // no more failures after this, pass ownership
|
||
|
SetThreadpoolWait(storage_t::get()->m_threadPoolWait.get(), storage_t::get()->m_eventHandle.get(), nullptr);
|
||
|
return S_OK;
|
||
|
}
|
||
|
};
|
||
|
|
||
|
typedef unique_any_t<registry_watcher_t<details::unique_storage<details::registry_watcher_state_resource_policy>, err_returncode_policy>> unique_registry_watcher_nothrow;
|
||
|
typedef unique_any_t<registry_watcher_t<details::unique_storage<details::registry_watcher_state_resource_policy>, err_failfast_policy>> unique_registry_watcher_failfast;
|
||
|
|
||
|
inline unique_registry_watcher_nothrow make_registry_watcher_nothrow(
|
||
|
HKEY rootKey, _In_ PCWSTR subKey, bool isRecursive, wistd::function<void(RegistryChangeKind)>&& callback) WI_NOEXCEPT
|
||
|
{
|
||
|
unique_registry_watcher_nothrow watcher;
|
||
|
watcher.create(rootKey, subKey, isRecursive, wistd::move(callback));
|
||
|
return watcher; // caller must test for success using if (watcher)
|
||
|
}
|
||
|
|
||
|
inline unique_registry_watcher_nothrow make_registry_watcher_nothrow(
|
||
|
unique_hkey&& keyToWatch, bool isRecursive, wistd::function<void(RegistryChangeKind)>&& callback) WI_NOEXCEPT
|
||
|
{
|
||
|
unique_registry_watcher_nothrow watcher;
|
||
|
watcher.create(wistd::move(keyToWatch), isRecursive, wistd::move(callback));
|
||
|
return watcher; // caller must test for success using if (watcher)
|
||
|
}
|
||
|
|
||
|
inline unique_registry_watcher_failfast make_registry_watcher_failfast(
|
||
|
HKEY rootKey, _In_ PCWSTR subKey, bool isRecursive, wistd::function<void(RegistryChangeKind)>&& callback)
|
||
|
{
|
||
|
return unique_registry_watcher_failfast(rootKey, subKey, isRecursive, wistd::move(callback));
|
||
|
}
|
||
|
|
||
|
inline unique_registry_watcher_failfast make_registry_watcher_failfast(
|
||
|
unique_hkey&& keyToWatch, bool isRecursive, wistd::function<void(RegistryChangeKind)>&& callback)
|
||
|
{
|
||
|
return unique_registry_watcher_failfast(wistd::move(keyToWatch), isRecursive, wistd::move(callback));
|
||
|
}
|
||
|
|
||
|
#ifdef WIL_ENABLE_EXCEPTIONS
|
||
|
typedef unique_any_t<registry_watcher_t<details::unique_storage<details::registry_watcher_state_resource_policy>, err_exception_policy>> unique_registry_watcher;
|
||
|
|
||
|
inline unique_registry_watcher make_registry_watcher(
|
||
|
HKEY rootKey, _In_ PCWSTR subKey, bool isRecursive, wistd::function<void(RegistryChangeKind)>&& callback)
|
||
|
{
|
||
|
return unique_registry_watcher(rootKey, subKey, isRecursive, wistd::move(callback));
|
||
|
}
|
||
|
|
||
|
inline unique_registry_watcher make_registry_watcher(unique_hkey&& keyToWatch, bool isRecursive, wistd::function<void(RegistryChangeKind)>&& callback)
|
||
|
{
|
||
|
return unique_registry_watcher(wistd::move(keyToWatch), isRecursive, wistd::move(callback));
|
||
|
}
|
||
|
#endif // WIL_ENABLE_EXCEPTIONS
|
||
|
} // namespace wil
|
||
|
|
||
|
#endif
|