Skip to content
14 changes: 7 additions & 7 deletions cppwinrt/code_writers.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 <typename D%> auto consume_%<D%>::%(%) const noexcept
{%
if constexpr (!std::is_same_v<D, %>)
{
auto const& castedResult = static_cast<% const&>(static_cast<D const&>(*this));
auto const [castedResult, code] = impl::try_as_with_reason<%, D const*>(static_cast<D const*>(this));
check_hresult(code);
auto const abiType = *(abi_t<%>**)&castedResult;
check_cast_result(abiType);
abiType->%(%);
}
else
Expand All @@ -1156,9 +1156,9 @@ namespace cppwinrt
{%
if constexpr (!std::is_same_v<D, %>)
{
auto const& castedResult = static_cast<% const&>(static_cast<D const&>(*this));
auto const [castedResult, code] = impl::try_as_with_reason<%, D const*>(static_cast<D const*>(this));
check_hresult(code);
auto const abiType = *(abi_t<%>**)&castedResult;
check_cast_result(abiType);
WINRT_VERIFY_(0, abiType->%(%));
}
else
Expand All @@ -1176,9 +1176,9 @@ namespace cppwinrt
{%
if constexpr (!std::is_same_v<D, %>)
{
auto const& castedResult = static_cast<% const&>(static_cast<D const&>(*this));
auto const [castedResult, code] = impl::try_as_with_reason<%, D const*>(static_cast<D const*>(this));
check_hresult(code);
auto const abiType = *(abi_t<%>**)&castedResult;
check_cast_result(abiType);
check_hresult(abiType->%(%));
}
else
Expand Down
21 changes: 0 additions & 21 deletions strings/base_error.h
Original file line number Diff line number Diff line change
Expand Up @@ -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<impl::IRestrictedErrorInfo> 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
2 changes: 0 additions & 2 deletions strings/base_extern.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
11 changes: 11 additions & 0 deletions strings/base_implements.h
Original file line number Diff line number Diff line change
Expand Up @@ -792,9 +792,20 @@ namespace winrt::impl
{
return m_inner.operator bool();
}

template <typename To, typename From>
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 <typename Qi>
auto try_as_with_reason() const noexcept
{
return m_inner.try_as_with_reason<Qi>();
}
};

template <typename D, bool>
Expand Down
33 changes: 29 additions & 4 deletions strings/base_windows.h
Original file line number Diff line number Diff line change
Expand Up @@ -128,12 +128,31 @@ namespace winrt::impl
}

void* result{};
hresult code = ptr->QueryInterface(guid_of<To>(), &result);
if (code < 0)
ptr->QueryInterface(guid_of<To>(), &result);
return wrap_as_result<To>(result);
}

template <typename To, typename From, std::enable_if_t<is_com_interface_v<To>, int> = 0>
std::pair<com_ref<To>, hresult> try_as_with_reason(From* ptr) noexcept
{
#ifdef WINRT_DIAGNOSTICS
get_diagnostics_info().add_query<To>();
#endif

if (!ptr)
{
WINRT_IMPL_RoCaptureErrorContext(code);
return { nullptr, 0 };
}
return wrap_as_result<To>(result);

void* result{};
hresult code = ptr->QueryInterface(guid_of<To>(), &result);
return { wrap_as_result<To>(result), code };
}

template <typename To, typename From>
auto try_as_with_reason(From ptr) noexcept
{
return ptr->template try_as_with_reason<To>();
}
}

Expand Down Expand Up @@ -209,6 +228,12 @@ WINRT_EXPORT namespace winrt::Windows::Foundation
return impl::try_as<To>(m_ptr);
}

template <typename To>
auto try_as_with_reason() const noexcept
{
return impl::try_as_with_reason<To>(m_ptr);
}

template <typename To>
void as(To& to) const
{
Expand Down
Loading