Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 14 additions & 1 deletion dev/AppLifecycle/AppInstance.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -291,7 +291,7 @@ namespace winrt::Microsoft::Windows::AppLifecycle::implementation
return s_current.as<Microsoft::Windows::AppLifecycle::AppInstance>();
}

IVector<Microsoft::Windows::AppLifecycle::AppInstance> AppInstance::GetInstances()
HRESULT AppInstance::GetInstancesImpl(IVector<Microsoft::Windows::AppLifecycle::AppInstance>& instancesOut) noexcept try
{
// Force the singleton init.
GetCurrent();
Expand Down Expand Up @@ -338,6 +338,19 @@ namespace winrt::Microsoft::Windows::AppLifecycle::implementation
}
}

instancesOut = instances;
return S_OK;
}
CATCH_RETURN()

IVector<Microsoft::Windows::AppLifecycle::AppInstance> 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<Microsoft::Windows::AppLifecycle::AppInstance> instances{ nullptr };
THROW_IF_FAILED(GetInstancesImpl(instances));
return instances;
}

Expand Down
6 changes: 6 additions & 0 deletions dev/AppLifecycle/AppInstance.h
Original file line number Diff line number Diff line change
Expand Up @@ -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<Microsoft::Windows::AppLifecycle::AppInstance>& instancesOut) noexcept;

// Named object prefixes used to scope.
std::wstring m_moduleName;
std::wstring m_processName;
Expand Down
29 changes: 20 additions & 9 deletions dev/AppNotifications/AppNotificationManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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<NotificationProperties>(notification);

winrt::com_ptr<::ABI::Microsoft::Internal::ToastNotifications::INotificationTransientProperties> notificationTransientProperties = winrt::make_self<NotificationTransientProperties>(notification);

DWORD notificationId = 0;
THROW_IF_FAILED(ToastNotifications_PostToast(m_appId.c_str(), notificationProperties.get(), notificationTransientProperties.get(), &notificationId));
RETURN_IF_FAILED(ToastNotifications_PostToast(m_appId.c_str(), notificationProperties.get(), notificationTransientProperties.get(), &notificationId));

THROW_HR_IF(E_UNEXPECTED, notificationId == 0);
RETURN_HR_IF(E_UNEXPECTED, notificationId == 0);

implementation::AppNotification* notificationImpl = get_self<implementation::AppNotification>(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<winrt::Microsoft::Windows::AppNotifications::AppNotificationProgressResult> AppNotificationManager::UpdateAsync(winrt::Microsoft::Windows::AppNotifications::AppNotificationProgressData const data, hstring const tag, hstring const group)
Expand Down
6 changes: 6 additions & 0 deletions dev/AppNotifications/AppNotificationManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -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<NotificationActivationEventHandler> m_notificationHandlers;
Expand Down
Loading