3rdparty: Update WIL to v1.0.240803.1

This commit is contained in:
JordanTheToaster 2024-12-05 06:06:53 +00:00 committed by Ty
parent caaa3519ad
commit 3f1df0ea92
15 changed files with 395 additions and 284 deletions

File diff suppressed because it is too large Load Diff

View File

@ -2398,7 +2398,7 @@ RETURN_IF_FAILED(wil::stream_seek_nothrow(source, LLONG_MAX, STREAM_SEEK_CUR));
@param stream The stream to seek @param stream The stream to seek
@param offset The position, in bytes from the current position, to seek @param offset The position, in bytes from the current position, to seek
@param from The starting point from which to seek, from the STREAM_SEEK_* set of values @param from The starting point from which to seek, from the STREAM_SEEK_* set of values
@param value Optionally recieves the new absolute position from the stream @param value Optionally receives the new absolute position from the stream
*/ */
inline HRESULT stream_seek_nothrow(_In_ IStream* stream, long long offset, unsigned long from, _Out_opt_ unsigned long long* value = nullptr) inline HRESULT stream_seek_nothrow(_In_ IStream* stream, long long offset, unsigned long from, _Out_opt_ unsigned long long* value = nullptr)
{ {
@ -2418,7 +2418,7 @@ RETURN_HR(wil::stream_set_position_nothrow(source, 16));
~~~~ ~~~~
@param stream The stream whose size is to be returned in `value` @param stream The stream whose size is to be returned in `value`
@param offset The position, in bytes from the start of the stream, to seek to @param offset The position, in bytes from the start of the stream, to seek to
@param value Optionally recieves the new absolute position from the stream @param value Optionally receives the new absolute position from the stream
*/ */
inline HRESULT stream_set_position_nothrow(_In_ IStream* stream, unsigned long long offset, _Out_opt_ unsigned long long* value = nullptr) inline HRESULT stream_set_position_nothrow(_In_ IStream* stream, unsigned long long offset, _Out_opt_ unsigned long long* value = nullptr)
{ {
@ -2888,7 +2888,7 @@ if (wcscmp(content.get(), L"waffles") == 0)
@endcode @endcode
@param source The stream from which to read a string @param source The stream from which to read a string
@param options Controls the behavior when reading a zero-length string @param options Controls the behavior when reading a zero-length string
@return An non-null string (but possibly zero lengh) string read from `source` @return An non-null string (but possibly zero length) string read from `source`
*/ */
inline wil::unique_cotaskmem_string stream_read_string(_In_ ISequentialStream* source, empty_string_options options = empty_string_options::returns_empty) inline wil::unique_cotaskmem_string stream_read_string(_In_ ISequentialStream* source, empty_string_options options = empty_string_options::returns_empty)
{ {

View File

@ -526,7 +526,7 @@ to be able to layer additional functionality into other libraries by their mere
of initialization should be used whenever they are available. of initialization should be used whenever they are available.
~~~~ ~~~~
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) #if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
WI_HEADER_INITITALIZATION_FUNCTION(InitializeDesktopFamilyApis, [] WI_HEADER_INITIALIZATION_FUNCTION(InitializeDesktopFamilyApis, []
{ {
g_pfnGetModuleName = GetCurrentModuleName; g_pfnGetModuleName = GetCurrentModuleName;
g_pfnFailFastInLoaderCallout = FailFastInLoaderCallout; g_pfnFailFastInLoaderCallout = FailFastInLoaderCallout;
@ -537,16 +537,16 @@ WI_HEADER_INITITALIZATION_FUNCTION(InitializeDesktopFamilyApis, []
The above example is used within WIL to decide whether or not the library containing WIL is allowed to use The above example is used within WIL to decide whether or not the library containing WIL is allowed to use
desktop APIs. Building this functionality as `#IFDEF`s within functions would create ODR violations, whereas desktop APIs. Building this functionality as `#IFDEF`s within functions would create ODR violations, whereas
doing it with global function pointers and header initialization allows a runtime determination. */ doing it with global function pointers and header initialization allows a runtime determination. */
#define WI_HEADER_INITITALIZATION_FUNCTION(name, fn) #define WI_HEADER_INITIALIZATION_FUNCTION(name, fn)
#elif defined(_M_IX86) #elif defined(_M_IX86)
#define WI_HEADER_INITITALIZATION_FUNCTION(name, fn) \ #define WI_HEADER_INITIALIZATION_FUNCTION(name, fn) \
extern "C" \ extern "C" \
{ \ { \
__declspec(selectany) unsigned char g_header_init_##name = static_cast<unsigned char>(fn()); \ __declspec(selectany) unsigned char g_header_init_##name = static_cast<unsigned char>(fn()); \
} \ } \
__pragma(comment(linker, "/INCLUDE:_g_header_init_" #name)) __pragma(comment(linker, "/INCLUDE:_g_header_init_" #name))
#elif defined(_M_IA64) || defined(_M_AMD64) || defined(_M_ARM) || defined(_M_ARM64) #elif defined(_M_IA64) || defined(_M_AMD64) || defined(_M_ARM) || defined(_M_ARM64)
#define WI_HEADER_INITITALIZATION_FUNCTION(name, fn) \ #define WI_HEADER_INITIALIZATION_FUNCTION(name, fn) \
extern "C" \ extern "C" \
{ \ { \
__declspec(selectany) unsigned char g_header_init_##name = static_cast<unsigned char>(fn()); \ __declspec(selectany) unsigned char g_header_init_##name = static_cast<unsigned char>(fn()); \
@ -556,6 +556,9 @@ doing it with global function pointers and header initialization allows a runtim
#error linker pragma must include g_header_init variation #error linker pragma must include g_header_init variation
#endif #endif
// Keep the misspelled name for backward compatibility.
#define WI_HEADER_INITITALIZATION_FUNCTION(name, fn) WI_HEADER_INITIALIZATION_FUNCTION(name, fn)
/** All Windows Implementation Library classes and functions are located within the "wil" namespace. /** All Windows Implementation Library classes and functions are located within the "wil" namespace.
The 'wil' namespace is an intentionally short name as the intent is for code to be able to reference The 'wil' namespace is an intentionally short name as the intent is for code to be able to reference
the namespace directly (example: `wil::srwlock lock;`) without a using statement. Resist adding a using the namespace directly (example: `wil::srwlock lock;`) without a using statement. Resist adding a using
@ -687,32 +690,32 @@ boolean, BOOLEAN, and classes with an explicit bool cast.
@param val The logical bool expression @param val The logical bool expression
@return A C++ bool representing the evaluation of `val`. */ @return A C++ bool representing the evaluation of `val`. */
template <typename T, __R_ENABLE_IF_IS_CLASS(T)> template <typename T, __R_ENABLE_IF_IS_CLASS(T)>
_Post_satisfies_(return == static_cast<bool>(val)) __forceinline constexpr bool verify_bool(const T& val) _Post_satisfies_(return == static_cast<bool>(val)) __forceinline constexpr bool verify_bool(const T& val) WI_NOEXCEPT
{ {
return static_cast<bool>(val); return static_cast<bool>(val);
} }
template <typename T, __R_ENABLE_IF_IS_NOT_CLASS(T)> template <typename T, __R_ENABLE_IF_IS_NOT_CLASS(T)>
__forceinline constexpr bool verify_bool(T /*val*/) __forceinline constexpr bool verify_bool(T /*val*/) WI_NOEXCEPT
{ {
static_assert(!wistd::is_same<T, T>::value, "Wrong Type: bool/BOOL/BOOLEAN/boolean expected"); static_assert(!wistd::is_same<T, T>::value, "Wrong Type: bool/BOOL/BOOLEAN/boolean expected");
return false; return false;
} }
template <> template <>
_Post_satisfies_(return == val) __forceinline constexpr bool verify_bool<bool>(bool val) _Post_satisfies_(return == val) __forceinline constexpr bool verify_bool<bool>(bool val) WI_NOEXCEPT
{ {
return val; return val;
} }
template <> template <>
_Post_satisfies_(return == (val != 0)) __forceinline constexpr bool verify_bool<int>(int val) _Post_satisfies_(return == (val != 0)) __forceinline constexpr bool verify_bool<int>(int val) WI_NOEXCEPT
{ {
return (val != 0); return (val != 0);
} }
template <> template <>
_Post_satisfies_(return == (val != 0)) __forceinline constexpr bool verify_bool<unsigned char>(unsigned char val) _Post_satisfies_(return == (val != 0)) __forceinline constexpr bool verify_bool<unsigned char>(unsigned char val) WI_NOEXCEPT
{ {
return (val != 0); return (val != 0);
} }
@ -723,7 +726,7 @@ accept any `int` value as long as that is the underlying typedef behind `BOOL`.
@param val The Win32 BOOL returning expression @param val The Win32 BOOL returning expression
@return A Win32 BOOL representing the evaluation of `val`. */ @return A Win32 BOOL representing the evaluation of `val`. */
template <typename T> template <typename T>
_Post_satisfies_(return == val) __forceinline constexpr int verify_BOOL(T val) _Post_satisfies_(return == val) __forceinline constexpr int verify_BOOL(T val) WI_NOEXCEPT
{ {
// Note: Written in terms of 'int' as BOOL is actually: typedef int BOOL; // Note: Written in terms of 'int' as BOOL is actually: typedef int BOOL;
static_assert((wistd::is_same<T, int>::value), "Wrong Type: BOOL expected"); static_assert((wistd::is_same<T, int>::value), "Wrong Type: BOOL expected");
@ -752,7 +755,7 @@ RETURN_HR_IF(static_cast<HRESULT>(UIA_E_NOTSUPPORTED), (patternId != UIA_DragPat
@param hr The HRESULT returning expression @param hr The HRESULT returning expression
@return An HRESULT representing the evaluation of `val`. */ @return An HRESULT representing the evaluation of `val`. */
template <typename T> template <typename T>
_Post_satisfies_(return == hr) inline constexpr long verify_hresult(T hr) _Post_satisfies_(return == hr) inline constexpr long verify_hresult(T hr) WI_NOEXCEPT
{ {
// Note: Written in terms of 'long' as HRESULT is actually: typedef _Return_type_success_(return >= 0) long HRESULT // Note: Written in terms of 'long' as HRESULT is actually: typedef _Return_type_success_(return >= 0) long HRESULT
static_assert(wistd::is_same<T, long>::value, "Wrong Type: HRESULT expected"); static_assert(wistd::is_same<T, long>::value, "Wrong Type: HRESULT expected");
@ -781,7 +784,7 @@ NT_RETURN_IF_FALSE(static_cast<NTSTATUS>(STATUS_NOT_SUPPORTED), (dispatch->Versi
@param status The NTSTATUS returning expression @param status The NTSTATUS returning expression
@return An NTSTATUS representing the evaluation of `val`. */ @return An NTSTATUS representing the evaluation of `val`. */
template <typename T> template <typename T>
_Post_satisfies_(return == status) inline long verify_ntstatus(T status) _Post_satisfies_(return == status) inline long verify_ntstatus(T status) WI_NOEXCEPT
{ {
// Note: Written in terms of 'long' as NTSTATUS is actually: typedef _Return_type_success_(return >= 0) long NTSTATUS // Note: Written in terms of 'long' as NTSTATUS is actually: typedef _Return_type_success_(return >= 0) long NTSTATUS
static_assert(wistd::is_same<T, long>::value, "Wrong Type: NTSTATUS expected"); static_assert(wistd::is_same<T, long>::value, "Wrong Type: NTSTATUS expected");
@ -795,7 +798,7 @@ commonly used when manipulating Win32 error codes.
@param error The Win32 error code returning expression @param error The Win32 error code returning expression
@return An Win32 error code representing the evaluation of `error`. */ @return An Win32 error code representing the evaluation of `error`. */
template <typename T> template <typename T>
_Post_satisfies_(return == error) inline T verify_win32(T error) _Post_satisfies_(return == error) inline T verify_win32(T error) WI_NOEXCEPT
{ {
// Note: Win32 error code are defined as 'long' (#define ERROR_SUCCESS 0L), but are more frequently used as DWORD (unsigned // Note: Win32 error code are defined as 'long' (#define ERROR_SUCCESS 0L), but are more frequently used as DWORD (unsigned
// long). This accept both types. // long). This accept both types.

View File

@ -191,7 +191,7 @@ struct com_task;
/// @cond /// @cond
namespace wil::details::coro namespace wil::details::coro
{ {
// task and com_task are convertable to each other. However, not // task and com_task are convertible to each other. However, not
// all consumers of this header have COM enabled. Support for saving // all consumers of this header have COM enabled. Support for saving
// COM thread-local error information and restoring it on the resuming // COM thread-local error information and restoring it on the resuming
// thread is enabled using these function pointers. If COM is not // thread is enabled using these function pointers. If COM is not
@ -764,8 +764,8 @@ inline void __stdcall DestroyRestrictedErrorInformation(_In_ void* restricted_er
struct apartment_info struct apartment_info
{ {
APTTYPE aptType; APTTYPE aptType{};
APTTYPEQUALIFIER aptTypeQualifier; APTTYPEQUALIFIER aptTypeQualifier{};
void load() void load()
{ {
@ -814,7 +814,7 @@ struct apartment_resumer
__WI_COROUTINE_NAMESPACE::coroutine_handle<> waiter; __WI_COROUTINE_NAMESPACE::coroutine_handle<> waiter;
wil::com_ptr<IContextCallback> context{nullptr}; wil::com_ptr<IContextCallback> context{nullptr};
apartment_info info; apartment_info info{};
HRESULT resume_result = S_OK; HRESULT resume_result = S_OK;
void capture_context(__WI_COROUTINE_NAMESPACE::coroutine_handle<> handle) void capture_context(__WI_COROUTINE_NAMESPACE::coroutine_handle<> handle)
@ -925,7 +925,7 @@ auto task_base<T>::resume_same_apartment() && noexcept
// This section is lit up when COM headers are available. Initialize the global function // This section is lit up when COM headers are available. Initialize the global function
// pointers such that error information can be saved and restored across thread boundaries. // pointers such that error information can be saved and restored across thread boundaries.
WI_HEADER_INITITALIZATION_FUNCTION(CoroutineRestrictedErrorInitialize, [] { WI_HEADER_INITIALIZATION_FUNCTION(CoroutineRestrictedErrorInitialize, [] {
::wil::details::coro::g_pfnCaptureRestrictedErrorInformation = ::wil::details::coro::CaptureRestrictedErrorInformation; ::wil::details::coro::g_pfnCaptureRestrictedErrorInformation = ::wil::details::coro::CaptureRestrictedErrorInformation;
::wil::details::coro::g_pfnRestoreRestrictedErrorInformation = ::wil::details::coro::RestoreRestrictedErrorInformation; ::wil::details::coro::g_pfnRestoreRestrictedErrorInformation = ::wil::details::coro::RestoreRestrictedErrorInformation;
::wil::details::coro::g_pfnDestroyRestrictedErrorInformation = ::wil::details::coro::DestroyRestrictedErrorInformation; ::wil::details::coro::g_pfnDestroyRestrictedErrorInformation = ::wil::details::coro::DestroyRestrictedErrorInformation;

View File

@ -255,7 +255,7 @@ namespace details
{ {
#ifndef CPPWINRT_SUPPRESS_STATIC_INITIALIZERS #ifndef CPPWINRT_SUPPRESS_STATIC_INITIALIZERS
WI_ODR_PRAGMA("CPPWINRT_SUPPRESS_STATIC_INITIALIZERS", "0") WI_ODR_PRAGMA("CPPWINRT_SUPPRESS_STATIC_INITIALIZERS", "0")
WI_HEADER_INITITALIZATION_FUNCTION(WilInitialize_CppWinRT, [] { WI_HEADER_INITIALIZATION_FUNCTION(WilInitialize_CppWinRT, [] {
::wil::WilInitialize_CppWinRT(); ::wil::WilInitialize_CppWinRT();
return 1; return 1;
}); });

View File

@ -476,7 +476,7 @@ next_entry_offset_iterator<T> create_next_entry_offset_iterator(T* p)
enum class FolderChangeEvent : DWORD enum class FolderChangeEvent : DWORD
{ {
ChangesLost = 0, // requies special handling, reset state as events were lost ChangesLost = 0, // requires special handling, reset state as events were lost
Added = FILE_ACTION_ADDED, Added = FILE_ACTION_ADDED,
Removed = FILE_ACTION_REMOVED, Removed = FILE_ACTION_REMOVED,
Modified = FILE_ACTION_MODIFIED, Modified = FILE_ACTION_MODIFIED,
@ -1122,9 +1122,9 @@ struct file_and_error_result
DWORD last_error{}; DWORD last_error{};
}; };
/** Non-throwing open existing using OPEN_EXISTING. /** Non-throwing open existing using OPEN_EXISTING, returns handle and error code.
~~~ ~~~
auto handle = wil::try_open_file(filePath.c_str()); auto [handle, error] = wil::try_open_file(filePath.c_str());
~~~ ~~~
*/ */
inline file_and_error_result try_open_file( inline file_and_error_result try_open_file(
@ -1150,7 +1150,7 @@ inline wil::unique_hfile open_file(
DWORD dwDesiredAccess = GENERIC_READ, DWORD dwDesiredAccess = GENERIC_READ,
DWORD dwShareMode = FILE_SHARE_READ, DWORD dwShareMode = FILE_SHARE_READ,
DWORD dwFlagsAndAttributes = FILE_ATTRIBUTE_NORMAL, DWORD dwFlagsAndAttributes = FILE_ATTRIBUTE_NORMAL,
bool inheritHandle = false) noexcept bool inheritHandle = false)
{ {
auto result = try_open_file(path, dwDesiredAccess, dwShareMode, dwFlagsAndAttributes, inheritHandle); auto result = try_open_file(path, dwDesiredAccess, dwShareMode, dwFlagsAndAttributes, inheritHandle);
THROW_WIN32_IF(result.last_error, !result.file.is_valid()); THROW_WIN32_IF(result.last_error, !result.file.is_valid());
@ -1173,7 +1173,7 @@ namespace details
/** create using CREATE_NEW, returns handle and error code. /** create using CREATE_NEW, returns handle and error code.
~~~ ~~~
auto [handle, error = wil::try_create_new_file(filePath.c_str()); auto [handle, error] = wil::try_create_new_file(filePath.c_str());
~~~ ~~~
*/ */
inline file_and_error_result try_create_new_file( inline file_and_error_result try_create_new_file(
@ -1189,7 +1189,7 @@ inline file_and_error_result try_create_new_file(
/** create using OPEN_ALWAYS, returns handle and error code. /** create using OPEN_ALWAYS, returns handle and error code.
~~~ ~~~
auto [handle, error = wil::try_open_or_create_file(filePath.c_str()); auto [handle, error] = wil::try_open_or_create_file(filePath.c_str());
~~~ ~~~
*/ */
inline file_and_error_result try_open_or_create_file( inline file_and_error_result try_open_or_create_file(
@ -1205,7 +1205,7 @@ inline file_and_error_result try_open_or_create_file(
/** create using CREATE_ALWAYS, returns handle and error code. /** create using CREATE_ALWAYS, returns handle and error code.
~~~ ~~~
auto [handle, error = wil::try_open_or_truncate_existing_file(filePath.c_str()); auto [handle, error] = wil::try_open_or_truncate_existing_file(filePath.c_str());
~~~ ~~~
*/ */
inline file_and_error_result try_open_or_truncate_existing_file( inline file_and_error_result try_open_or_truncate_existing_file(
@ -1221,7 +1221,7 @@ inline file_and_error_result try_open_or_truncate_existing_file(
/** create using TRUNCATE_EXISTING, returns handle and error code. /** create using TRUNCATE_EXISTING, returns handle and error code.
~~~ ~~~
auto [handle, error = wil::try_truncate_existing_file(filePath.c_str()); auto [handle, error] = wil::try_truncate_existing_file(filePath.c_str());
~~~ ~~~
*/ */
inline file_and_error_result try_truncate_existing_file( inline file_and_error_result try_truncate_existing_file(
@ -1247,7 +1247,7 @@ inline wil::unique_hfile create_new_file(
DWORD dwShareMode = FILE_SHARE_READ, DWORD dwShareMode = FILE_SHARE_READ,
LPSECURITY_ATTRIBUTES lpSecurityAttributes = nullptr, LPSECURITY_ATTRIBUTES lpSecurityAttributes = nullptr,
DWORD dwFlagsAndAttributes = FILE_ATTRIBUTE_NORMAL, DWORD dwFlagsAndAttributes = FILE_ATTRIBUTE_NORMAL,
HANDLE hTemplateFile = nullptr) noexcept HANDLE hTemplateFile = nullptr)
{ {
auto result = try_create_new_file(path, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwFlagsAndAttributes, hTemplateFile); auto result = try_create_new_file(path, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwFlagsAndAttributes, hTemplateFile);
THROW_WIN32_IF(result.last_error, !result.file.is_valid()); THROW_WIN32_IF(result.last_error, !result.file.is_valid());
@ -1265,7 +1265,7 @@ inline wil::unique_hfile open_or_create_file(
DWORD dwShareMode = FILE_SHARE_READ, DWORD dwShareMode = FILE_SHARE_READ,
LPSECURITY_ATTRIBUTES lpSecurityAttributes = nullptr, LPSECURITY_ATTRIBUTES lpSecurityAttributes = nullptr,
DWORD dwFlagsAndAttributes = FILE_ATTRIBUTE_NORMAL, DWORD dwFlagsAndAttributes = FILE_ATTRIBUTE_NORMAL,
HANDLE hTemplateFile = nullptr) noexcept HANDLE hTemplateFile = nullptr)
{ {
auto result = try_open_or_create_file(path, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwFlagsAndAttributes, hTemplateFile); auto result = try_open_or_create_file(path, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwFlagsAndAttributes, hTemplateFile);
THROW_WIN32_IF(result.last_error, !result.file.is_valid()); THROW_WIN32_IF(result.last_error, !result.file.is_valid());
@ -1283,7 +1283,7 @@ inline wil::unique_hfile open_or_truncate_existing_file(
DWORD dwShareMode = FILE_SHARE_READ, DWORD dwShareMode = FILE_SHARE_READ,
LPSECURITY_ATTRIBUTES lpSecurityAttributes = nullptr, LPSECURITY_ATTRIBUTES lpSecurityAttributes = nullptr,
DWORD dwFlagsAndAttributes = FILE_ATTRIBUTE_NORMAL, DWORD dwFlagsAndAttributes = FILE_ATTRIBUTE_NORMAL,
HANDLE hTemplateFile = nullptr) noexcept HANDLE hTemplateFile = nullptr)
{ {
auto result = try_open_or_truncate_existing_file( auto result = try_open_or_truncate_existing_file(
path, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwFlagsAndAttributes, hTemplateFile); path, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwFlagsAndAttributes, hTemplateFile);
@ -1302,7 +1302,7 @@ inline wil::unique_hfile truncate_existing_file(
DWORD dwShareMode = FILE_SHARE_READ, DWORD dwShareMode = FILE_SHARE_READ,
LPSECURITY_ATTRIBUTES lpSecurityAttributes = nullptr, LPSECURITY_ATTRIBUTES lpSecurityAttributes = nullptr,
DWORD dwFlagsAndAttributes = FILE_ATTRIBUTE_NORMAL, DWORD dwFlagsAndAttributes = FILE_ATTRIBUTE_NORMAL,
HANDLE hTemplateFile = nullptr) noexcept HANDLE hTemplateFile = nullptr)
{ {
auto result = auto result =
try_truncate_existing_file(path, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwFlagsAndAttributes, hTemplateFile); try_truncate_existing_file(path, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwFlagsAndAttributes, hTemplateFile);

View File

@ -27,9 +27,9 @@
// stdint.h and intsafe.h have conflicting definitions, so it's not safe to include either to pick up our dependencies, // stdint.h and intsafe.h have conflicting definitions, so it's not safe to include either to pick up our dependencies,
// so the definitions we need are copied below // so the definitions we need are copied below
#ifdef _WIN64 #ifdef _WIN64
#define __WI_SIZE_MAX 0xffffffffffffffffui64 // UINT64_MAX #define __WI_SIZE_MAX 0xffffffffffffffffULL // UINT64_MAX
#else /* _WIN64 */ #else /* _WIN64 */
#define __WI_SIZE_MAX 0xffffffffui32 // UINT32_MAX #define __WI_SIZE_MAX 0xffffffffUL // UINT32_MAX
#endif /* _WIN64 */ #endif /* _WIN64 */
/// @endcond /// @endcond
@ -721,7 +721,7 @@ class com_ptr_t; // forward
namespace details namespace details
{ {
// The first two attach_to_smart_pointer() overloads are ambiguous when passed a com_ptr_t. // The first two attach_to_smart_pointer() overloads are ambiguous when passed a com_ptr_t.
// To solve that use this functions return type to elminate the reset form for com_ptr_t. // To solve that use this functions return type to eliminate the reset form for com_ptr_t.
template <typename T, typename err> template <typename T, typename err>
wistd::false_type use_reset(wil::com_ptr_t<T, err>*) wistd::false_type use_reset(wil::com_ptr_t<T, err>*)
{ {
@ -1025,7 +1025,7 @@ struct empty_deleter
}; };
/** unique_any_array_ptr is a RAII type for managing conformant arrays that need to be freed and have elements that may need to be /** unique_any_array_ptr is a RAII type for managing conformant arrays that need to be freed and have elements that may need to be
freed. The intented use for this RAII type would be to capture out params from API like IPropertyValue::GetStringArray. This class freed. The intended use for this RAII type would be to capture out params from API like IPropertyValue::GetStringArray. This class
also maintains the size of the array, so it can iterate over the members and deallocate them before it deallocates the base array also maintains the size of the array, so it can iterate over the members and deallocate them before it deallocates the base array
pointer. pointer.
@ -2892,6 +2892,7 @@ typedef unique_any_t<event_t<details::unique_storage<details::handle_resource_po
typedef unique_any_t<event_t<details::unique_storage<details::handle_resource_policy>, err_exception_policy>> unique_event; typedef unique_any_t<event_t<details::unique_storage<details::handle_resource_policy>, err_exception_policy>> unique_event;
#endif #endif
#ifndef WIL_NO_SLIM_EVENT
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) && \ #if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) && \
((_WIN32_WINNT >= _WIN32_WINNT_WIN8) || (__WIL_RESOURCE_ENABLE_QUIRKS && (_WIN32_WINNT >= _WIN32_WINNT_WIN7))) ((_WIN32_WINNT >= _WIN32_WINNT_WIN8) || (__WIL_RESOURCE_ENABLE_QUIRKS && (_WIN32_WINNT >= _WIN32_WINNT_WIN7)))
enum class SlimEventType enum class SlimEventType
@ -2973,13 +2974,13 @@ public:
return !!ReadAcquire(&m_isSignaled); return !!ReadAcquire(&m_isSignaled);
} }
bool wait(DWORD timeoutMiliseconds) WI_NOEXCEPT bool wait(DWORD timeoutMilliseconds) WI_NOEXCEPT
{ {
if (timeoutMiliseconds == 0) if (timeoutMilliseconds == 0)
{ {
return TryAcquireEvent(); return TryAcquireEvent();
} }
else if (timeoutMiliseconds == INFINITE) else if (timeoutMilliseconds == INFINITE)
{ {
return wait(); return wait();
} }
@ -2991,12 +2992,12 @@ public:
while (!TryAcquireEvent()) while (!TryAcquireEvent())
{ {
if (elapsedTimeMilliseconds >= timeoutMiliseconds) if (elapsedTimeMilliseconds >= timeoutMilliseconds)
{ {
return false; return false;
} }
DWORD newTimeout = static_cast<DWORD>(timeoutMiliseconds - elapsedTimeMilliseconds); DWORD newTimeout = static_cast<DWORD>(timeoutMilliseconds - elapsedTimeMilliseconds);
if (!WaitForSignal(newTimeout)) if (!WaitForSignal(newTimeout))
{ {
@ -3039,10 +3040,10 @@ private:
} }
} }
bool WaitForSignal(DWORD timeoutMiliseconds) WI_NOEXCEPT bool WaitForSignal(DWORD timeoutMilliseconds) WI_NOEXCEPT
{ {
LONG falseValue = FALSE; LONG falseValue = FALSE;
BOOL waitResult = WaitOnAddress(&m_isSignaled, &falseValue, sizeof(m_isSignaled), timeoutMiliseconds); BOOL waitResult = WaitOnAddress(&m_isSignaled, &falseValue, sizeof(m_isSignaled), timeoutMilliseconds);
__FAIL_FAST_ASSERT__(waitResult || ::GetLastError() == ERROR_TIMEOUT); __FAIL_FAST_ASSERT__(waitResult || ::GetLastError() == ERROR_TIMEOUT);
return !!waitResult; return !!waitResult;
} }
@ -3060,6 +3061,7 @@ using slim_event_manual_reset = slim_event_t<SlimEventType::ManualReset>;
using slim_event = slim_event_auto_reset; using slim_event = slim_event_auto_reset;
#endif // WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) && (_WIN32_WINNT >= _WIN32_WINNT_WIN8) #endif // WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) && (_WIN32_WINNT >= _WIN32_WINNT_WIN8)
#endif // WIL_NO_SLIM_EVENT
typedef unique_any<HANDLE, decltype(&details::ReleaseMutex), details::ReleaseMutex, details::pointer_access_none> mutex_release_scope_exit; typedef unique_any<HANDLE, decltype(&details::ReleaseMutex), details::ReleaseMutex, details::pointer_access_none> mutex_release_scope_exit;
@ -4731,7 +4733,7 @@ inline unique_hstring make_unique_string_nothrow<unique_hstring>(
_When_((source != nullptr) && length == static_cast<size_t>(-1), _In_z_) PCWSTR source, _When_((source != nullptr) && length == static_cast<size_t>(-1), _In_z_) PCWSTR source,
size_t length) WI_NOEXCEPT size_t length) WI_NOEXCEPT
{ {
WI_ASSERT(source != nullptr); // the HSTRING version of this function does not suport this case WI_ASSERT(source != nullptr); // the HSTRING version of this function does not support this case
if (length == static_cast<size_t>(-1)) if (length == static_cast<size_t>(-1))
{ {
length = wcslen(source); length = wcslen(source);
@ -5218,7 +5220,7 @@ struct cert_context_t
} }
/** A wrapper around CertEnumCertificatesInStore. /** A wrapper around CertEnumCertificatesInStore.
CertEnumCertificatesInStore takes ownership of its second paramter in an unclear fashion, CertEnumCertificatesInStore takes ownership of its second parameter in an unclear fashion,
making it error-prone to use in combination with unique_cert_context. This wrapper helps making it error-prone to use in combination with unique_cert_context. This wrapper helps
manage the resource correctly while ensuring the GetLastError state set by CertEnumCertificatesInStore. manage the resource correctly while ensuring the GetLastError state set by CertEnumCertificatesInStore.
is not lost. See MSDN for more information on `CertEnumCertificatesInStore`. is not lost. See MSDN for more information on `CertEnumCertificatesInStore`.
@ -6264,7 +6266,7 @@ using wdf_wait_lock_release_scope_exit =
using unique_wdf_device_init = unique_any<WDFDEVICE_INIT*, decltype(&::WdfDeviceInitFree), ::WdfDeviceInitFree>; using unique_wdf_device_init = unique_any<WDFDEVICE_INIT*, decltype(&::WdfDeviceInitFree), ::WdfDeviceInitFree>;
#endif #endif
inline WI_NODISCARD _IRQL_requires_max_(PASSIVE_LEVEL) WI_NODISCARD inline _IRQL_requires_max_(PASSIVE_LEVEL)
_Acquires_lock_(lock) _Acquires_lock_(lock)
wdf_wait_lock_release_scope_exit acquire_wdf_wait_lock(WDFWAITLOCK lock) WI_NOEXCEPT wdf_wait_lock_release_scope_exit acquire_wdf_wait_lock(WDFWAITLOCK lock) WI_NOEXCEPT
{ {
@ -6272,7 +6274,7 @@ wdf_wait_lock_release_scope_exit acquire_wdf_wait_lock(WDFWAITLOCK lock) WI_NOEX
return wdf_wait_lock_release_scope_exit(lock); return wdf_wait_lock_release_scope_exit(lock);
} }
inline WI_NODISCARD _IRQL_requires_max_(APC_LEVEL) WI_NODISCARD inline _IRQL_requires_max_(APC_LEVEL)
_When_(return, _Acquires_lock_(lock)) _When_(return, _Acquires_lock_(lock))
wdf_wait_lock_release_scope_exit try_acquire_wdf_wait_lock(WDFWAITLOCK lock) WI_NOEXCEPT wdf_wait_lock_release_scope_exit try_acquire_wdf_wait_lock(WDFWAITLOCK lock) WI_NOEXCEPT
{ {
@ -6291,7 +6293,7 @@ wdf_wait_lock_release_scope_exit try_acquire_wdf_wait_lock(WDFWAITLOCK lock) WI_
using wdf_spin_lock_release_scope_exit = using wdf_spin_lock_release_scope_exit =
unique_any<WDFSPINLOCK, decltype(&::WdfSpinLockRelease), ::WdfSpinLockRelease, details::pointer_access_none>; unique_any<WDFSPINLOCK, decltype(&::WdfSpinLockRelease), ::WdfSpinLockRelease, details::pointer_access_none>;
inline WI_NODISCARD _IRQL_requires_max_(DISPATCH_LEVEL) WI_NODISCARD inline _IRQL_requires_max_(DISPATCH_LEVEL)
_IRQL_raises_(DISPATCH_LEVEL) _IRQL_raises_(DISPATCH_LEVEL)
_Acquires_lock_(lock) _Acquires_lock_(lock)
wdf_spin_lock_release_scope_exit acquire_wdf_spin_lock(WDFSPINLOCK lock) WI_NOEXCEPT wdf_spin_lock_release_scope_exit acquire_wdf_spin_lock(WDFSPINLOCK lock) WI_NOEXCEPT
@ -6507,7 +6509,7 @@ private:
// function only if the call-site source location is obtained from elsewhere (i.e., plumbed // function only if the call-site source location is obtained from elsewhere (i.e., plumbed
// through other abstractions). // through other abstractions).
template <typename wdf_object_t> template <typename wdf_object_t>
inline WI_NODISCARD unique_wdf_object_reference<wdf_object_t> wdf_object_reference_increment( WI_NODISCARD inline unique_wdf_object_reference<wdf_object_t> wdf_object_reference_increment(
wdf_object_t wdfObject, PVOID tag, LONG lineNumber, PCSTR fileName) WI_NOEXCEPT wdf_object_t wdfObject, PVOID tag, LONG lineNumber, PCSTR fileName) WI_NOEXCEPT
{ {
// Parameter is incorrectly marked as non-const, so the const-cast is required. // Parameter is incorrectly marked as non-const, so the const-cast is required.
@ -6516,7 +6518,7 @@ inline WI_NODISCARD unique_wdf_object_reference<wdf_object_t> wdf_object_referen
} }
template <typename wdf_object_t> template <typename wdf_object_t>
inline WI_NODISCARD unique_wdf_object_reference<wdf_object_t> wdf_object_reference_increment( WI_NODISCARD inline unique_wdf_object_reference<wdf_object_t> wdf_object_reference_increment(
const wil::unique_wdf_any<wdf_object_t>& wdfObject, PVOID tag, LONG lineNumber, PCSTR fileName) WI_NOEXCEPT const wil::unique_wdf_any<wdf_object_t>& wdfObject, PVOID tag, LONG lineNumber, PCSTR fileName) WI_NOEXCEPT
{ {
return wdf_object_reference_increment(wdfObject.get(), tag, lineNumber, fileName); return wdf_object_reference_increment(wdfObject.get(), tag, lineNumber, fileName);
@ -7451,7 +7453,7 @@ namespace details
{ {
// Only those lock types specialized by lock_proof_traits will allow either a write_lock_required or // Only those lock types specialized by lock_proof_traits will allow either a write_lock_required or
// read_lock_required to be constructed. The allows_exclusive value indicates if the type represents an exclusive, // read_lock_required to be constructed. The allows_exclusive value indicates if the type represents an exclusive,
// write-safe lock aquisition, or a shared, read-only lock acquisition. // write-safe lock acquisition, or a shared, read-only lock acquisition.
template <typename T> template <typename T>
struct lock_proof_traits struct lock_proof_traits
{ {
@ -7480,7 +7482,7 @@ another function that requires them.
These types are implicitly convertible from various lock holding types, enabling callers to provide them as These types are implicitly convertible from various lock holding types, enabling callers to provide them as
proof of the lock that they hold. proof of the lock that they hold.
The following example is intentially contrived to demonstrate multiple use cases: The following example is intentionally contrived to demonstrate multiple use cases:
- Methods that require only shared/read access - Methods that require only shared/read access
- Methods that require only exclusive write access - Methods that require only exclusive write access
- Methods that pass their proof-of-lock to a helper - Methods that pass their proof-of-lock to a helper

View File

@ -435,7 +435,7 @@ namespace details_abi
private: private:
struct Node struct Node
{ {
DWORD threadId = ULONG_MAX; DWORD threadId = 0xffffffff; // MAXDWORD
Node* pNext = nullptr; Node* pNext = nullptr;
T value{}; T value{};
}; };
@ -1169,7 +1169,7 @@ namespace details
__declspec(selectany)::wil::details_abi::ProcessLocalStorage<::wil::details_abi::ProcessLocalData> g_processLocalData("WilError_03"); __declspec(selectany)::wil::details_abi::ProcessLocalStorage<::wil::details_abi::ProcessLocalData> g_processLocalData("WilError_03");
__declspec(selectany)::wil::details_abi::ThreadLocalStorage<ThreadFailureCallbackHolder*> g_threadFailureCallbacks; __declspec(selectany)::wil::details_abi::ThreadLocalStorage<ThreadFailureCallbackHolder*> g_threadFailureCallbacks;
WI_HEADER_INITITALIZATION_FUNCTION(InitializeResultHeader, [] { WI_HEADER_INITIALIZATION_FUNCTION(InitializeResultHeader, [] {
g_pfnGetContextAndNotifyFailure = GetContextAndNotifyFailure; g_pfnGetContextAndNotifyFailure = GetContextAndNotifyFailure;
::wil::details_abi::g_pProcessLocalData = &g_processLocalData; ::wil::details_abi::g_pProcessLocalData = &g_processLocalData;
g_pThreadFailureCallbacks = &g_threadFailureCallbacks; g_pThreadFailureCallbacks = &g_threadFailureCallbacks;

View File

@ -757,6 +757,14 @@ WI_ODR_PRAGMA("WIL_FreeMemory", "0")
return __hr; \ return __hr; \
} \ } \
__WI_SUPPRESS_4127_E while ((void)0, 0) __WI_SUPPRESS_4127_E while ((void)0, 0)
#define __RETURN_HR_FAIL_SUPPRESS_TELEMETRY(hr, str) \
__WI_SUPPRESS_4127_S do \
{ \
const HRESULT __hr = (hr); \
__R_FN(Return_HrSuppressTelemetry)(__R_INFO(str) __hr); \
return __hr; \
} \
__WI_SUPPRESS_4127_E while ((void)0, 0)
#define __RETURN_HR_FAIL_NOFILE(hr, str) \ #define __RETURN_HR_FAIL_NOFILE(hr, str) \
__WI_SUPPRESS_4127_S do \ __WI_SUPPRESS_4127_S do \
{ \ { \
@ -1097,6 +1105,21 @@ WI_ODR_PRAGMA("WIL_FreeMemory", "0")
} \ } \
} while ((void)0, 0) } while ((void)0, 0)
// Always logs failed HR, if expected, telemetry will be called with 'alreadyReported'
#define RETURN_IF_FAILED_SUPPRESS_TELEMETRY_IF_EXPECTED(hr, hrExpected, ...) \
do \
{ \
const auto __hrRet = wil::verify_hresult(hr); \
if (FAILED(__hrRet)) \
{ \
if ((__hrRet == wil::verify_hresult(hrExpected)) WI_FOREACH(__WI_OR_IS_EXPECTED_HRESULT, ##__VA_ARGS__)) \
{ \
__RETURN_HR_FAIL_SUPPRESS_TELEMETRY(__hrRet, #hr); \
} \
__RETURN_HR_FAIL(__hrRet, #hr); \
} \
} while ((void)0, 0)
//***************************************************************************** //*****************************************************************************
// Macros for logging failures (ignore or pass-through) // Macros for logging failures (ignore or pass-through)
//***************************************************************************** //*****************************************************************************
@ -1267,7 +1290,7 @@ WI_ODR_PRAGMA("WIL_FreeMemory", "0")
if (!wil::verify_bool(condition)) \ if (!wil::verify_bool(condition)) \
{ \ { \
WI_ASSERT_FAIL(#condition); \ WI_ASSERT_FAIL(#condition); \
__RFF_FN(FailFast_Unexpected)(__RFF_INFO_ONLY(#condition)) \ __RFF_FN(FailFast_Unexpected)(__RFF_INFO_ONLY(#condition)); \
} \ } \
} while (0, 0) } while (0, 0)
#define WI_FAIL_FAST_ASSERT_MSG(condition, msg) \ #define WI_FAIL_FAST_ASSERT_MSG(condition, msg) \
@ -1738,7 +1761,7 @@ inline HRESULT GetFailureLogString(
_Pre_satisfies_(cchDest > 0) _In_ size_t cchDest, _Pre_satisfies_(cchDest > 0) _In_ size_t cchDest,
_In_ FailureInfo const& failure) WI_NOEXCEPT _In_ FailureInfo const& failure) WI_NOEXCEPT
{ {
// This function was lenient to empty strings at one point and some callers became dependent on this beahvior // This function was lenient to empty strings at one point and some callers became dependent on this behavior
if ((cchDest == 0) || (pszDest == nullptr)) if ((cchDest == 0) || (pszDest == nullptr))
{ {
return S_OK; return S_OK;
@ -2155,6 +2178,7 @@ namespace details
_Pre_satisfies_(debugStringSizeChars > 0) size_t debugStringSizeChars, _Pre_satisfies_(debugStringSizeChars > 0) size_t debugStringSizeChars,
_Out_writes_(callContextStringSizeChars) _Post_z_ PSTR callContextString, _Out_writes_(callContextStringSizeChars) _Post_z_ PSTR callContextString,
_Pre_satisfies_(callContextStringSizeChars > 0) size_t callContextStringSizeChars, _Pre_satisfies_(callContextStringSizeChars > 0) size_t callContextStringSizeChars,
FailureFlags flags,
_Out_ FailureInfo* failure) WI_NOEXCEPT; _Out_ FailureInfo* failure) WI_NOEXCEPT;
__declspec(noinline) inline void ReportFailure( __declspec(noinline) inline void ReportFailure(
@ -2168,12 +2192,13 @@ namespace details
__R_FN_PARAMS_FULL, __R_FN_PARAMS_FULL,
const ResultStatus& resultPair, const ResultStatus& resultPair,
_In_opt_ PCWSTR message = nullptr, _In_opt_ PCWSTR message = nullptr,
ReportFailureOptions options = ReportFailureOptions::None); ReportFailureOptions options = ReportFailureOptions::None,
FailureFlags flags = FailureFlags::None);
template <FailureType> template <FailureType>
inline void ReportFailure_ReplaceMsg(__R_FN_PARAMS_FULL, HRESULT hr, _Printf_format_string_ PCSTR formatString, ...); inline void ReportFailure_ReplaceMsg(__R_FN_PARAMS_FULL, HRESULT hr, _Printf_format_string_ PCSTR formatString, ...);
__declspec(noinline) inline void ReportFailure_Hr(__R_FN_PARAMS_FULL, FailureType type, HRESULT hr); __declspec(noinline) inline void ReportFailure_Hr(__R_FN_PARAMS_FULL, FailureType type, HRESULT hr);
template <FailureType> template <FailureType>
__declspec(noinline) inline void ReportFailure_Hr(__R_FN_PARAMS_FULL, HRESULT hr); __declspec(noinline) inline void ReportFailure_Hr(__R_FN_PARAMS_FULL, HRESULT hr, FailureFlags flags = FailureFlags::None);
template <FailureType> template <FailureType>
__declspec(noinline) inline HRESULT __declspec(noinline) inline HRESULT
ReportFailure_CaughtException(__R_FN_PARAMS_FULL, SupportedExceptions supported = SupportedExceptions::Default); ReportFailure_CaughtException(__R_FN_PARAMS_FULL, SupportedExceptions supported = SupportedExceptions::Default);
@ -2826,8 +2851,8 @@ namespace details
// NOTE: The following two functions are unfortunate copies of strsafe.h functions that have been copied to reduce the friction associated with using // NOTE: The following two functions are unfortunate copies of strsafe.h functions that have been copied to reduce the friction associated with using
// Result.h and ResultException.h in a build that does not have WINAPI_PARTITION_DESKTOP defined (where these are conditionally enabled). // Result.h and ResultException.h in a build that does not have WINAPI_PARTITION_DESKTOP defined (where these are conditionally enabled).
static STRSAFEAPI WilStringLengthWorkerA( inline HRESULT WilStringLengthWorkerA(
_In_reads_or_z_(cchMax) STRSAFE_PCNZCH psz, _In_reads_or_z_(cchMax) PCNZCH psz,
_In_ _In_range_(<=, STRSAFE_MAX_CCH) size_t cchMax, _In_ _In_range_(<=, STRSAFE_MAX_CCH) size_t cchMax,
_Out_opt_ _Deref_out_range_(<, cchMax) _Deref_out_range_(<=, _String_length_(psz)) size_t* pcchLength) _Out_opt_ _Deref_out_range_(<, cchMax) _Deref_out_range_(<=, _String_length_(psz)) size_t* pcchLength)
{ {
@ -2858,8 +2883,8 @@ namespace details
} }
_Must_inspect_result_ _Must_inspect_result_
STRSAFEAPI StringCchLengthA( inline HRESULT StringCchLengthA(
_In_reads_or_z_(cchMax) STRSAFE_PCNZCH psz, _In_reads_or_z_(cchMax) PCNZCH psz,
_In_ _In_range_(1, STRSAFE_MAX_CCH) size_t cchMax, _In_ _In_range_(1, STRSAFE_MAX_CCH) size_t cchMax,
_Out_opt_ _Deref_out_range_(<, cchMax) _Deref_out_range_(<=, _String_length_(psz)) size_t* pcchLength) _Out_opt_ _Deref_out_range_(<, cchMax) _Deref_out_range_(<=, _String_length_(psz)) size_t* pcchLength)
{ {
@ -2880,8 +2905,8 @@ namespace details
} }
#pragma warning(pop) #pragma warning(pop)
_Post_satisfies_(cchDest > 0 && cchDest <= cchMax) static STRSAFEAPI _Post_satisfies_(cchDest > 0 && cchDest <= cchMax) inline HRESULT
WilStringValidateDestA(_In_reads_opt_(cchDest) STRSAFE_PCNZCH /*pszDest*/, _In_ size_t cchDest, _In_ const size_t cchMax) WilStringValidateDestA(_In_reads_opt_(cchDest) PCNZCH /*pszDest*/, _In_ size_t cchDest, _In_ const size_t cchMax)
{ {
HRESULT hr = S_OK; HRESULT hr = S_OK;
if ((cchDest == 0) || (cchDest > cchMax)) if ((cchDest == 0) || (cchDest > cchMax))
@ -2891,7 +2916,7 @@ namespace details
return hr; return hr;
} }
static STRSAFEAPI WilStringVPrintfWorkerA( inline HRESULT WilStringVPrintfWorkerA(
_Out_writes_(cchDest) _Always_(_Post_z_) STRSAFE_LPSTR pszDest, _Out_writes_(cchDest) _Always_(_Post_z_) STRSAFE_LPSTR pszDest,
_In_ _In_range_(1, STRSAFE_MAX_CCH) size_t cchDest, _In_ _In_range_(1, STRSAFE_MAX_CCH) size_t cchDest,
_Always_(_Out_opt_ _Deref_out_range_(<=, cchDest - 1)) size_t* pcchNewDestLength, _Always_(_Out_opt_ _Deref_out_range_(<=, cchDest - 1)) size_t* pcchNewDestLength,
@ -2948,7 +2973,7 @@ namespace details
return hr; return hr;
} }
__inline HRESULT StringCchPrintfA( inline HRESULT StringCchPrintfA(
_Out_writes_(cchDest) _Always_(_Post_z_) STRSAFE_LPSTR pszDest, _Out_writes_(cchDest) _Always_(_Post_z_) STRSAFE_LPSTR pszDest,
_In_ size_t cchDest, _In_ size_t cchDest,
_In_ _Printf_format_string_ STRSAFE_LPCSTR pszFormat, _In_ _Printf_format_string_ STRSAFE_LPCSTR pszFormat,
@ -3080,7 +3105,7 @@ namespace details
{ {
#ifndef RESULT_SUPPRESS_STATIC_INITIALIZERS #ifndef RESULT_SUPPRESS_STATIC_INITIALIZERS
#if !defined(BUILD_WINDOWS) || defined(WIL_SUPPRESS_PRIVATE_API_USE) #if !defined(BUILD_WINDOWS) || defined(WIL_SUPPRESS_PRIVATE_API_USE)
WI_HEADER_INITITALIZATION_FUNCTION(WilInitialize_ResultMacros_DesktopOrSystem_SuppressPrivateApiUse, [] { WI_HEADER_INITIALIZATION_FUNCTION(WilInitialize_ResultMacros_DesktopOrSystem_SuppressPrivateApiUse, [] {
::wil::WilInitialize_ResultMacros_DesktopOrSystem_SuppressPrivateApiUse(); ::wil::WilInitialize_ResultMacros_DesktopOrSystem_SuppressPrivateApiUse();
return 1; return 1;
}); });
@ -3091,7 +3116,7 @@ namespace details
#else // !WINAPI_PARTITION_DESKTOP, !WINAPI_PARTITION_SYSTEM, explicitly assume these modules can direct link #else // !WINAPI_PARTITION_DESKTOP, !WINAPI_PARTITION_SYSTEM, explicitly assume these modules can direct link
namespace details namespace details
{ {
WI_HEADER_INITITALIZATION_FUNCTION(WilInitialize_ResultMacros_AppOnly, [] { WI_HEADER_INITIALIZATION_FUNCTION(WilInitialize_ResultMacros_AppOnly, [] {
g_pfnRaiseFailFastException = ::RaiseFailFastException; g_pfnRaiseFailFastException = ::RaiseFailFastException;
return 1; return 1;
}); });
@ -3869,7 +3894,7 @@ namespace details
} }
#if !defined(RESULT_SUPPRESS_STATIC_INITIALIZERS) #if !defined(RESULT_SUPPRESS_STATIC_INITIALIZERS)
WI_HEADER_INITITALIZATION_FUNCTION(InitializeWinRt, [] { WI_HEADER_INITIALIZATION_FUNCTION(InitializeWinRt, [] {
g_pfnResultFromCaughtException_WinRt = ResultFromCaughtException_WinRt; g_pfnResultFromCaughtException_WinRt = ResultFromCaughtException_WinRt;
g_pfnResultFromKnownExceptions_WinRt = ResultFromKnownExceptions_WinRt; g_pfnResultFromKnownExceptions_WinRt = ResultFromKnownExceptions_WinRt;
g_pfnThrowPlatformException = ThrowPlatformException; g_pfnThrowPlatformException = ThrowPlatformException;
@ -4124,7 +4149,7 @@ namespace details
} }
} }
WI_HEADER_INITITALIZATION_FUNCTION(InitializeResultExceptions, [] { WI_HEADER_INITIALIZATION_FUNCTION(InitializeResultExceptions, [] {
g_pfnRunFunctorWithExceptionFilter = RunFunctorWithExceptionFilter; g_pfnRunFunctorWithExceptionFilter = RunFunctorWithExceptionFilter;
g_pfnRethrow = Rethrow; g_pfnRethrow = Rethrow;
g_pfnThrowResultException = ThrowResultExceptionInternal; g_pfnThrowResultException = ThrowResultExceptionInternal;
@ -4320,6 +4345,7 @@ namespace details
_Pre_satisfies_(debugStringSizeChars > 0) size_t debugStringSizeChars, _Pre_satisfies_(debugStringSizeChars > 0) size_t debugStringSizeChars,
_Out_writes_(callContextStringSizeChars) _Post_z_ PSTR callContextString, _Out_writes_(callContextStringSizeChars) _Post_z_ PSTR callContextString,
_Pre_satisfies_(callContextStringSizeChars > 0) size_t callContextStringSizeChars, _Pre_satisfies_(callContextStringSizeChars > 0) size_t callContextStringSizeChars,
FailureFlags flags,
_Out_ FailureInfo* failure) WI_NOEXCEPT _Out_ FailureInfo* failure) WI_NOEXCEPT
{ {
debugString[0] = L'\0'; debugString[0] = L'\0';
@ -4360,7 +4386,7 @@ namespace details
}; };
failure->type = type; failure->type = type;
failure->flags = FailureFlags::None; failure->flags = flags;
WI_SetFlagIf(failure->flags, FailureFlags::NtStatus, resultPair.kind == ResultStatus::Kind::NtStatus); WI_SetFlagIf(failure->flags, FailureFlags::NtStatus, resultPair.kind == ResultStatus::Kind::NtStatus);
failure->failureId = ::InterlockedIncrementNoFence(&s_failureId); failure->failureId = ::InterlockedIncrementNoFence(&s_failureId);
failure->pszMessage = ((message != nullptr) && (message[0] != L'\0')) ? message : nullptr; failure->pszMessage = ((message != nullptr) && (message[0] != L'\0')) ? message : nullptr;
@ -4501,7 +4527,8 @@ namespace details
} }
template <FailureType T> template <FailureType T>
inline __declspec(noinline) void ReportFailure_Return(__R_FN_PARAMS_FULL, const ResultStatus& resultPair, PCWSTR message, ReportFailureOptions options) inline __declspec(noinline) void ReportFailure_Return(
__R_FN_PARAMS_FULL, const ResultStatus& resultPair, PCWSTR message, ReportFailureOptions options, FailureFlags flags)
{ {
bool needPlatformException = bool needPlatformException =
((T == FailureType::Exception) && WI_IsFlagClear(options, ReportFailureOptions::MayRethrow) && ((T == FailureType::Exception) && WI_IsFlagClear(options, ReportFailureOptions::MayRethrow) &&
@ -4522,6 +4549,7 @@ namespace details
ARRAYSIZE(debugString), ARRAYSIZE(debugString),
callContextString, callContextString,
ARRAYSIZE(callContextString), ARRAYSIZE(callContextString),
flags,
&failure); &failure);
if (WI_IsFlagSet(failure.flags, FailureFlags::RequestFailFast)) if (WI_IsFlagSet(failure.flags, FailureFlags::RequestFailFast))
@ -4531,9 +4559,10 @@ namespace details
} }
template <FailureType T, bool SuppressAction> template <FailureType T, bool SuppressAction>
inline __declspec(noinline) void ReportFailure_Base(__R_FN_PARAMS_FULL, const ResultStatus& resultPair, PCWSTR message, ReportFailureOptions options) inline __declspec(noinline) void ReportFailure_Base(
__R_FN_PARAMS_FULL, const ResultStatus& resultPair, PCWSTR message, ReportFailureOptions options, FailureFlags flags)
{ {
ReportFailure_Return<T>(__R_FN_CALL_FULL, resultPair, message, options); ReportFailure_Return<T>(__R_FN_CALL_FULL, resultPair, message, options, flags);
} }
template <FailureType T> template <FailureType T>
@ -4559,6 +4588,7 @@ namespace details
ARRAYSIZE(debugString), ARRAYSIZE(debugString),
callContextString, callContextString,
ARRAYSIZE(callContextString), ARRAYSIZE(callContextString),
FailureFlags::None,
&failure); &failure);
__WI_SUPPRESS_4127_S __WI_SUPPRESS_4127_S
if ((T == FailureType::FailFast) || WI_IsFlagSet(failure.flags, FailureFlags::RequestFailFast)) if ((T == FailureType::FailFast) || WI_IsFlagSet(failure.flags, FailureFlags::RequestFailFast))
@ -4587,14 +4617,14 @@ namespace details
template <> template <>
inline __declspec(noinline) RESULT_NORETURN void ReportFailure_Base<FailureType::FailFast, false>( inline __declspec(noinline) RESULT_NORETURN void ReportFailure_Base<FailureType::FailFast, false>(
__R_FN_PARAMS_FULL, const ResultStatus& resultPair, PCWSTR message, ReportFailureOptions options) __R_FN_PARAMS_FULL, const ResultStatus& resultPair, PCWSTR message, ReportFailureOptions options, FailureFlags)
{ {
ReportFailure_NoReturn<FailureType::FailFast>(__R_FN_CALL_FULL, resultPair, message, options); ReportFailure_NoReturn<FailureType::FailFast>(__R_FN_CALL_FULL, resultPair, message, options);
} }
template <> template <>
inline __declspec(noinline) RESULT_NORETURN void ReportFailure_Base<FailureType::Exception, false>( inline __declspec(noinline) RESULT_NORETURN void ReportFailure_Base<FailureType::Exception, false>(
__R_FN_PARAMS_FULL, const ResultStatus& resultPair, PCWSTR message, ReportFailureOptions options) __R_FN_PARAMS_FULL, const ResultStatus& resultPair, PCWSTR message, ReportFailureOptions options, FailureFlags)
{ {
ReportFailure_NoReturn<FailureType::Exception>(__R_FN_CALL_FULL, resultPair, message, options); ReportFailure_NoReturn<FailureType::Exception>(__R_FN_CALL_FULL, resultPair, message, options);
} }
@ -4764,19 +4794,22 @@ namespace details
} }
template <FailureType T> template <FailureType T>
__declspec(noinline) inline void ReportFailure_Hr(__R_FN_PARAMS_FULL, HRESULT hr) __declspec(noinline) inline void ReportFailure_Hr(__R_FN_PARAMS_FULL, HRESULT hr, FailureFlags flags)
{ {
ReportFailure_Base<T>(__R_FN_CALL_FULL, ResultStatus::FromResult(hr)); ReportFailure_Base<T>(
__R_FN_CALL_FULL, ResultStatus::FromResult(hr), nullptr /*message*/, ReportFailureOptions::None /*options*/, flags);
} }
template <> template <>
__declspec(noinline) inline RESULT_NORETURN void ReportFailure_Hr<FailureType::FailFast>(__R_FN_PARAMS_FULL, HRESULT hr) __declspec(noinline) inline RESULT_NORETURN
void ReportFailure_Hr<FailureType::FailFast>(__R_FN_PARAMS_FULL, HRESULT hr, FailureFlags)
{ {
ReportFailure_Base<FailureType::FailFast>(__R_FN_CALL_FULL, ResultStatus::FromResult(hr)); ReportFailure_Base<FailureType::FailFast>(__R_FN_CALL_FULL, ResultStatus::FromResult(hr));
} }
template <> template <>
__declspec(noinline) inline RESULT_NORETURN void ReportFailure_Hr<FailureType::Exception>(__R_FN_PARAMS_FULL, HRESULT hr) __declspec(noinline) inline RESULT_NORETURN
void ReportFailure_Hr<FailureType::Exception>(__R_FN_PARAMS_FULL, HRESULT hr, FailureFlags)
{ {
ReportFailure_Base<FailureType::Exception>(__R_FN_CALL_FULL, ResultStatus::FromResult(hr)); ReportFailure_Base<FailureType::Exception>(__R_FN_CALL_FULL, ResultStatus::FromResult(hr));
} }
@ -5182,6 +5215,7 @@ namespace details
ARRAYSIZE(debugString), ARRAYSIZE(debugString),
callContextString, callContextString,
ARRAYSIZE(callContextString), ARRAYSIZE(callContextString),
FailureFlags::None,
&failure); &failure);
if (WI_IsFlagSet(failure.flags, FailureFlags::RequestFailFast)) if (WI_IsFlagSet(failure.flags, FailureFlags::RequestFailFast))
@ -5228,6 +5262,13 @@ namespace details
wil::details::ReportFailure_Hr<FailureType::Return>(__R_DIRECT_FN_CALL hr); wil::details::ReportFailure_Hr<FailureType::Return>(__R_DIRECT_FN_CALL hr);
} }
__R_DIRECT_METHOD(void, Return_HrSuppressTelemetry)(__R_DIRECT_FN_PARAMS HRESULT hr) WI_NOEXCEPT
{
__R_FN_LOCALS;
const FailureFlags flags = FailureFlags::RequestSuppressTelemetry;
wil::details::ReportFailure_Hr<FailureType::Return>(__R_DIRECT_FN_CALL hr, flags);
}
_Success_(true) _Success_(true)
_Translates_Win32_to_HRESULT_(err) _Translates_Win32_to_HRESULT_(err)
__R_DIRECT_METHOD(HRESULT, Return_Win32)(__R_DIRECT_FN_PARAMS DWORD err) WI_NOEXCEPT __R_DIRECT_METHOD(HRESULT, Return_Win32)(__R_DIRECT_FN_PARAMS DWORD err) WI_NOEXCEPT

View File

@ -122,7 +122,7 @@ namespace details
} // namespace wil } // namespace wil
// Automatically call RoOriginateError upon error origination by including this file // Automatically call RoOriginateError upon error origination by including this file
WI_HEADER_INITITALIZATION_FUNCTION(ResultStowedExceptionInitialize, [] { WI_HEADER_INITIALIZATION_FUNCTION(ResultStowedExceptionInitialize, [] {
::wil::SetOriginateErrorCallback(::wil::details::RaiseRoOriginateOnWilExceptions); ::wil::SetOriginateErrorCallback(::wil::details::RaiseRoOriginateOnWilExceptions);
::wil::SetFailfastWithContextCallback(::wil::details::FailfastWithContextCallback); ::wil::SetFailfastWithContextCallback(::wil::details::FailfastWithContextCallback);
return 1; return 1;

View File

@ -106,7 +106,7 @@ namespace details
wistd::is_same<T, int>::value || wistd::is_same<T, unsigned int>::value || wistd::is_same<T, long>::value || wistd::is_same<T, int>::value || wistd::is_same<T, unsigned int>::value || wistd::is_same<T, long>::value ||
wistd::is_same<T, unsigned long>::value || wistd::is_same<T, __int64>::value || wistd::is_same<T, unsigned __int64>::value; wistd::is_same<T, unsigned long>::value || wistd::is_same<T, __int64>::value || wistd::is_same<T, unsigned __int64>::value;
// True when either type is potentialy variably sized (e.g. size_t, ptrdiff_t) // True when either type is potentially variably sized (e.g. size_t, ptrdiff_t)
template <typename OldT, typename NewT> template <typename OldT, typename NewT>
constexpr bool is_potentially_variably_sized_cast_v = constexpr bool is_potentially_variably_sized_cast_v =
is_potentially_variably_sized_type_v<OldT> || is_potentially_variably_sized_type_v<NewT>; is_potentially_variably_sized_type_v<OldT> || is_potentially_variably_sized_type_v<NewT>;

View File

@ -24,10 +24,9 @@ namespace details
{ {
}; };
template <typename TEnumApi, typename TCallback> template <typename TCallback>
void DoEnumWindowsNoThrow(TEnumApi&& enumApi, TCallback&& callback) noexcept BOOL __stdcall EnumWindowsCallbackNoThrow(HWND hwnd, LPARAM lParam)
{ {
auto enumproc = [](HWND hwnd, LPARAM lParam) -> BOOL {
auto pCallback = reinterpret_cast<TCallback*>(lParam); auto pCallback = reinterpret_cast<TCallback*>(lParam);
#ifdef __cpp_if_constexpr #ifdef __cpp_if_constexpr
using result_t = decltype((*pCallback)(hwnd)); using result_t = decltype((*pCallback)(hwnd));
@ -52,21 +51,26 @@ namespace details
#else #else
return (*pCallback)(hwnd); return (*pCallback)(hwnd);
#endif #endif
}; }
enumApi(enumproc, reinterpret_cast<LPARAM>(&callback));
template <typename TEnumApi, typename TCallback>
void DoEnumWindowsNoThrow(TEnumApi&& enumApi, TCallback&& callback) noexcept
{
enumApi(EnumWindowsCallbackNoThrow<TCallback>, reinterpret_cast<LPARAM>(&callback));
} }
#ifdef WIL_ENABLE_EXCEPTIONS #ifdef WIL_ENABLE_EXCEPTIONS
template <typename TEnumApi, typename TCallback> template <typename TCallback>
void DoEnumWindows(TEnumApi&& enumApi, TCallback&& callback) struct EnumWindowsCallbackData
{
struct
{ {
std::exception_ptr exception; std::exception_ptr exception;
TCallback* pCallback; TCallback* pCallback;
} callbackData = {nullptr, &callback}; };
auto enumproc = [](HWND hwnd, LPARAM lParam) -> BOOL {
auto pCallbackData = reinterpret_cast<decltype(&callbackData)>(lParam); template <typename TCallback>
BOOL __stdcall EnumWindowsCallback(HWND hwnd, LPARAM lParam)
{
auto pCallbackData = reinterpret_cast<EnumWindowsCallbackData<TCallback>*>(lParam);
try try
{ {
auto pCallback = pCallbackData->pCallback; auto pCallback = pCallbackData->pCallback;
@ -100,7 +104,12 @@ namespace details
return FALSE; return FALSE;
} }
}; };
enumApi(enumproc, reinterpret_cast<LPARAM>(&callbackData));
template <typename TEnumApi, typename TCallback>
void DoEnumWindows(TEnumApi&& enumApi, TCallback&& callback)
{
EnumWindowsCallbackData<TCallback> callbackData = {nullptr, &callback};
enumApi(EnumWindowsCallback<TCallback>, reinterpret_cast<LPARAM>(&callbackData));
if (callbackData.exception) if (callbackData.exception)
{ {
std::rethrow_exception(callbackData.exception); std::rethrow_exception(callbackData.exception);

View File

@ -271,7 +271,7 @@ struct TwoPhaseHStringConstructor
return TwoPhaseHStringConstructor{characterLength}; return TwoPhaseHStringConstructor{characterLength};
} }
//! Returns the HSTRING after it has been populated like Detatch() or release(); be sure to put this in a RAII type to manage //! Returns the HSTRING after it has been populated like Detach() or release(); be sure to put this in a RAII type to manage
//! its lifetime. //! its lifetime.
HSTRING Promote() HSTRING Promote()
{ {
@ -1700,8 +1700,8 @@ hr = run_when_complete_nothrow<StorageFile*>(getFileOp.Get(), [](HRESULT hr, ISt
~~~ ~~~
*/ */
//! Run a fuction when an async operation completes. Use Microsoft::WRL::FtmBase for TAgility to make the completion handler agile //! Run a function when an async operation completes. Use Microsoft::WRL::FtmBase for TAgility to make the completion handler
//! and run on the async thread. //! agile and run on the async thread.
template <typename TAgility = IUnknown, typename TFunc> template <typename TAgility = IUnknown, typename TFunc>
HRESULT run_when_complete_nothrow(_In_ ABI::Windows::Foundation::IAsyncAction* operation, TFunc&& func) WI_NOEXCEPT HRESULT run_when_complete_nothrow(_In_ ABI::Windows::Foundation::IAsyncAction* operation, TFunc&& func) WI_NOEXCEPT
{ {
@ -1727,8 +1727,8 @@ HRESULT run_when_complete_nothrow(_In_ ABI::Windows::Foundation::IAsyncActionWit
} }
#ifdef WIL_ENABLE_EXCEPTIONS #ifdef WIL_ENABLE_EXCEPTIONS
//! Run a fuction when an async operation completes. Use Microsoft::WRL::FtmBase for TAgility to make the completion handler agile //! Run a function when an async operation completes. Use Microsoft::WRL::FtmBase for TAgility to make the completion handler
//! and run on the async thread. //! agile and run on the async thread.
template <typename TAgility = IUnknown, typename TFunc> template <typename TAgility = IUnknown, typename TFunc>
void run_when_complete(_In_ ABI::Windows::Foundation::IAsyncAction* operation, TFunc&& func) void run_when_complete(_In_ ABI::Windows::Foundation::IAsyncAction* operation, TFunc&& func)
{ {

View File

@ -33,7 +33,7 @@
// and non-exception based code should utilize this functionality. // and non-exception based code should utilize this functionality.
// This header mimics libc++'s '__config' header to the extent necessary to get the wistd::* definitions compiling. Note // This header mimics libc++'s '__config' header to the extent necessary to get the wistd::* definitions compiling. Note
// that this has a few key differences since libc++'s MSVC compatability is currently not functional and a bit behind // that this has a few key differences since libc++'s MSVC compatibility is currently not functional and a bit behind
#ifndef _WISTD_CONFIG_H_ #ifndef _WISTD_CONFIG_H_
#define _WISTD_CONFIG_H_ #define _WISTD_CONFIG_H_
@ -130,7 +130,7 @@
#define __WI_CLANG_DISABLE_WARNING(warning) #define __WI_CLANG_DISABLE_WARNING(warning)
#endif #endif
// NOTE: MSVC, which is what we primarily target, is severly underrepresented in libc++ and checks such as // NOTE: MSVC, which is what we primarily target, is severely underrepresented in libc++ and checks such as
// __has_feature(...) are always false for MSVC, even when the feature being tested _is_ present in MSVC. Therefore, we // __has_feature(...) are always false for MSVC, even when the feature being tested _is_ present in MSVC. Therefore, we
// instead modify all checks to be __WI_HAS_FEATURE_IS_UNION, etc., which provides the correct value for MSVC and falls // instead modify all checks to be __WI_HAS_FEATURE_IS_UNION, etc., which provides the correct value for MSVC and falls
// back to the __has_feature(...), etc. value otherwise. We intentionally leave '__has_feature', etc. undefined for MSVC // back to the __has_feature(...), etc. value otherwise. We intentionally leave '__has_feature', etc. undefined for MSVC

View File

@ -4775,7 +4775,7 @@ struct underlying_type
{ {
static_assert( static_assert(
_Support, _Support,
"The underyling_type trait requires compiler " "The underlying_type trait requires compiler "
"support. Either no such support exists or " "support. Either no such support exists or "
"libc++ does not know how to use it."); "libc++ does not know how to use it.");
}; };