diff --git a/dev/AppLifecycle/AppInstance.cpp b/dev/AppLifecycle/AppInstance.cpp index 5631cb3872..3434ad860e 100644 --- a/dev/AppLifecycle/AppInstance.cpp +++ b/dev/AppLifecycle/AppInstance.cpp @@ -291,7 +291,7 @@ namespace winrt::Microsoft::Windows::AppLifecycle::implementation return s_current.as(); } - IVector AppInstance::GetInstances() + HRESULT AppInstance::GetInstancesImpl(IVector& instancesOut) noexcept try { // Force the singleton init. GetCurrent(); @@ -338,6 +338,19 @@ namespace winrt::Microsoft::Windows::AppLifecycle::implementation } } + instancesOut = instances; + return S_OK; + } + CATCH_RETURN() + + IVector AppInstance::GetInstances() + { + // Delegate to the noexcept GetInstancesImpl worker and rethrow any failure + // HRESULT cleanly via wil::ResultException. This avoids the deep WIL + // FormatMessage-based exception logging chain that caused stack overflow on + // the hot path (Bug 61688595). + IVector instances{ nullptr }; + THROW_IF_FAILED(GetInstancesImpl(instances)); return instances; } diff --git a/dev/AppLifecycle/AppInstance.h b/dev/AppLifecycle/AppInstance.h index beb02af484..325cd47eac 100644 --- a/dev/AppLifecycle/AppInstance.h +++ b/dev/AppLifecycle/AppInstance.h @@ -55,6 +55,12 @@ namespace winrt::Microsoft::Windows::AppLifecycle::implementation void EnqueueRedirectionRequestId(GUID id); GUID DequeueRedirectionRequestId(); + // noexcept HRESULT-returning worker for GetInstances. The public GetInstances + // boundary is intentionally thin so a failed HRESULT does not trigger the deep + // C++/WinRT projection rethrow path that exhausted the stack via WIL's + // FormatMessage-based exception logging (Bug 61688595). + static HRESULT GetInstancesImpl(winrt::Windows::Foundation::Collections::IVector& instancesOut) noexcept; + // Named object prefixes used to scope. std::wstring m_moduleName; std::wstring m_processName; diff --git a/dev/AppNotifications/AppNotificationManager.cpp b/dev/AppNotifications/AppNotificationManager.cpp index bcee2ddfc5..71f0a3ea32 100644 --- a/dev/AppNotifications/AppNotificationManager.cpp +++ b/dev/AppNotifications/AppNotificationManager.cpp @@ -421,13 +421,8 @@ namespace winrt::Microsoft::Windows::AppNotifications::implementation } CATCH_RETURN() - void AppNotificationManager::Show(winrt::Microsoft::Windows::AppNotifications::AppNotification const& notification) + HRESULT AppNotificationManager::ShowImpl(winrt::Microsoft::Windows::AppNotifications::AppNotification const& notification) noexcept try { - if (!IsSupported()) - { - return; - } - auto logTelemetry{ AppNotificationTelemetry::Show::Start( g_telemetryHelper, m_appId, @@ -436,21 +431,37 @@ namespace winrt::Microsoft::Windows::AppNotifications::implementation notification.Group(), winrt::AppNotificationConferencingConfig::IsCallingPreviewSupported()) }; - THROW_HR_IF(WPN_E_NOTIFICATION_POSTED, notification.Id() != 0); + RETURN_HR_IF(WPN_E_NOTIFICATION_POSTED, notification.Id() != 0); winrt::com_ptr<::ABI::Microsoft::Internal::ToastNotifications::INotificationProperties> notificationProperties = winrt::make_self(notification); winrt::com_ptr<::ABI::Microsoft::Internal::ToastNotifications::INotificationTransientProperties> notificationTransientProperties = winrt::make_self(notification); DWORD notificationId = 0; - THROW_IF_FAILED(ToastNotifications_PostToast(m_appId.c_str(), notificationProperties.get(), notificationTransientProperties.get(), ¬ificationId)); + RETURN_IF_FAILED(ToastNotifications_PostToast(m_appId.c_str(), notificationProperties.get(), notificationTransientProperties.get(), ¬ificationId)); - THROW_HR_IF(E_UNEXPECTED, notificationId == 0); + RETURN_HR_IF(E_UNEXPECTED, notificationId == 0); implementation::AppNotification* notificationImpl = get_self(notification); notificationImpl->SetNotificationId(notificationId); logTelemetry.Stop(); + return S_OK; + } + CATCH_RETURN() + + void AppNotificationManager::Show(winrt::Microsoft::Windows::AppNotifications::AppNotification const& notification) + { + if (!IsSupported()) + { + return; + } + + // Delegate to the noexcept ShowImpl worker and rethrow any failure HRESULT + // cleanly via wil::ResultException. This avoids the deep WIL + // FormatMessage-based exception logging chain that caused stack overflow on + // the hot path (Bug 61688595). + THROW_IF_FAILED(ShowImpl(notification)); } winrt::Windows::Foundation::IAsyncOperation AppNotificationManager::UpdateAsync(winrt::Microsoft::Windows::AppNotifications::AppNotificationProgressData const data, hstring const tag, hstring const group) diff --git a/dev/AppNotifications/AppNotificationManager.h b/dev/AppNotifications/AppNotificationManager.h index 7282fc0e59..09dfa8cfff 100644 --- a/dev/AppNotifications/AppNotificationManager.h +++ b/dev/AppNotifications/AppNotificationManager.h @@ -58,6 +58,12 @@ namespace winrt::Microsoft::Windows::AppNotifications::implementation void UnregisterHelper(); + // noexcept HRESULT-returning worker for Show. The public Show boundary is + // intentionally thin so a failed HRESULT does not trigger the deep C++/WinRT + // projection rethrow path that exhausted the stack via WIL's FormatMessage-based + // exception logging (Bug 61688595). + HRESULT ShowImpl(winrt::Microsoft::Windows::AppNotifications::AppNotification const& notification) noexcept; + wil::unique_com_class_object_cookie m_notificationComActivatorRegistration; wil::srwlock m_lock; winrt::event m_notificationHandlers;