diff --git a/cppwinrt/code_writers.h b/cppwinrt/code_writers.h index f93279a74..01f7dea10 100644 --- a/cppwinrt/code_writers.h +++ b/cppwinrt/code_writers.h @@ -1130,16 +1130,16 @@ namespace cppwinrt { // we intentionally ignore errors when unregistering event handlers to be consistent with event_revoker // - // The `noexcept` versions will crash if check_cast_result throws but that is no different than previous + // The `noexcept` versions will crash if check_hresult throws but that is no different than previous // behavior where it would not check the cast result and nullptr crash. At least the exception will terminate // immediately while preserving the error code and local variables. format = R"( template auto consume_%::%(%) const noexcept {% if constexpr (!std::is_same_v) { - auto const& castedResult = static_cast<% const&>(static_cast(*this)); + auto const [castedResult, code] = impl::try_as_with_reason<%, D const*>(static_cast(this)); + check_hresult(code); auto const abiType = *(abi_t<%>**)&castedResult; - check_cast_result(abiType); abiType->%(%); } else @@ -1156,9 +1156,9 @@ namespace cppwinrt {% if constexpr (!std::is_same_v) { - auto const& castedResult = static_cast<% const&>(static_cast(*this)); + auto const [castedResult, code] = impl::try_as_with_reason<%, D const*>(static_cast(this)); + check_hresult(code); auto const abiType = *(abi_t<%>**)&castedResult; - check_cast_result(abiType); WINRT_VERIFY_(0, abiType->%(%)); } else @@ -1176,9 +1176,9 @@ namespace cppwinrt {% if constexpr (!std::is_same_v) { - auto const& castedResult = static_cast<% const&>(static_cast(*this)); + auto const [castedResult, code] = impl::try_as_with_reason<%, D const*>(static_cast(this)); + check_hresult(code); auto const abiType = *(abi_t<%>**)&castedResult; - check_cast_result(abiType); check_hresult(abiType->%(%)); } else diff --git a/strings/base_error.h b/strings/base_error.h index 9b9624277..85de70f63 100644 --- a/strings/base_error.h +++ b/strings/base_error.h @@ -538,27 +538,6 @@ namespace winrt::impl } return result; } - - inline WINRT_IMPL_NOINLINE void check_cast_result(void* from, winrt::impl::slim_source_location const& sourceInformation = winrt::impl::slim_source_location::current()) - { - if (!from) - { - com_ptr restrictedError; - if (WINRT_IMPL_GetRestrictedErrorInfo(restrictedError.put_void()) == 0) - { - WINRT_IMPL_SetRestrictedErrorInfo(restrictedError.get()); - - int32_t code; - impl::bstr_handle description; - impl::bstr_handle restrictedDescription; - impl::bstr_handle capabilitySid; - if (restrictedError->GetErrorDetails(description.put(), &code, restrictedDescription.put(), capabilitySid.put()) == 0) - { - throw hresult_error(code, take_ownership_from_abi, sourceInformation); - } - } - } - } } #undef WINRT_IMPL_RETURNADDRESS diff --git a/strings/base_extern.h b/strings/base_extern.h index c0e83e75a..2412f9f2c 100644 --- a/strings/base_extern.h +++ b/strings/base_extern.h @@ -32,8 +32,6 @@ extern "C" int32_t __stdcall WINRT_IMPL_RoCaptureErrorContext(int32_t error) noexcept WINRT_IMPL_LINK(RoCaptureErrorContext, 4); void __stdcall WINRT_IMPL_RoFailFastWithErrorContext(int32_t) noexcept WINRT_IMPL_LINK(RoFailFastWithErrorContext, 4); int32_t __stdcall WINRT_IMPL_RoTransformError(int32_t, int32_t, void*) noexcept WINRT_IMPL_LINK(RoTransformError, 12); - int32_t __stdcall WINRT_IMPL_GetRestrictedErrorInfo(void**) noexcept WINRT_IMPL_LINK(GetRestrictedErrorInfo, 4); - int32_t __stdcall WINRT_IMPL_SetRestrictedErrorInfo(void*) noexcept WINRT_IMPL_LINK(SetRestrictedErrorInfo, 4); void* __stdcall WINRT_IMPL_LoadLibraryExW(wchar_t const* name, void* unused, uint32_t flags) noexcept WINRT_IMPL_LINK(LoadLibraryExW, 12); int32_t __stdcall WINRT_IMPL_FreeLibrary(void* library) noexcept WINRT_IMPL_LINK(FreeLibrary, 4); diff --git a/strings/base_implements.h b/strings/base_implements.h index d0bb09012..0847f5019 100644 --- a/strings/base_implements.h +++ b/strings/base_implements.h @@ -792,9 +792,20 @@ namespace winrt::impl { return m_inner.operator bool(); } + + template + friend auto winrt::impl::try_as_with_reason(From ptr) noexcept; + protected: static constexpr bool is_composing = true; Windows::Foundation::IInspectable m_inner; + + private: + template + auto try_as_with_reason() const noexcept + { + return m_inner.try_as_with_reason(); + } }; template diff --git a/strings/base_windows.h b/strings/base_windows.h index f5230e1c8..a67ef0b20 100644 --- a/strings/base_windows.h +++ b/strings/base_windows.h @@ -128,12 +128,31 @@ namespace winrt::impl } void* result{}; - hresult code = ptr->QueryInterface(guid_of(), &result); - if (code < 0) + ptr->QueryInterface(guid_of(), &result); + return wrap_as_result(result); + } + + template , int> = 0> + std::pair, hresult> try_as_with_reason(From* ptr) noexcept + { +#ifdef WINRT_DIAGNOSTICS + get_diagnostics_info().add_query(); +#endif + + if (!ptr) { - WINRT_IMPL_RoCaptureErrorContext(code); + return { nullptr, 0 }; } - return wrap_as_result(result); + + void* result{}; + hresult code = ptr->QueryInterface(guid_of(), &result); + return { wrap_as_result(result), code }; + } + + template + auto try_as_with_reason(From ptr) noexcept + { + return ptr->template try_as_with_reason(); } } @@ -209,6 +228,12 @@ WINRT_EXPORT namespace winrt::Windows::Foundation return impl::try_as(m_ptr); } + template + auto try_as_with_reason() const noexcept + { + return impl::try_as_with_reason(m_ptr); + } + template void as(To& to) const {