From 66779a1a61e21ec96433d307a36fddac40feb3dd Mon Sep 17 00:00:00 2001 From: "seer-by-sentry[bot]" <157164994+seer-by-sentry[bot]@users.noreply.github.com> Date: Mon, 13 Oct 2025 12:16:21 +0000 Subject: [PATCH] Fix: Handle C++ exceptions in Windows Graphics Capture API --- .../src/sources/screen_capture/windows.rs | 9 +++- crates/scap-targets/src/platform/win.rs | 46 +++++++++++++++++-- 2 files changed, 50 insertions(+), 5 deletions(-) diff --git a/crates/recording/src/sources/screen_capture/windows.rs b/crates/recording/src/sources/screen_capture/windows.rs index 05b020212f..d2942e78c7 100644 --- a/crates/recording/src/sources/screen_capture/windows.rs +++ b/crates/recording/src/sources/screen_capture/windows.rs @@ -186,7 +186,14 @@ impl output_pipeline::VideoSource for VideoSource { item } Err(e) => { - error!("Failed to create GraphicsCaptureItem on capture thread: {}", e); + error!( + "Failed to create GraphicsCaptureItem on capture thread: {}. \ + If you're running Windows 10 build 18363 (version 1903), this may be due to \ + a permissions issue or a known compatibility issue with the Graphics Capture API. \ + Please ensure the application has screen capture permissions, or try updating to \ + a newer version of Windows 10 or Windows 11.", + e + ); let _ = error_tx.send(anyhow!("Failed to create GraphicsCaptureItem: {}", e)); return; } diff --git a/crates/scap-targets/src/platform/win.rs b/crates/scap-targets/src/platform/win.rs index 817a230dd6..eccecb691b 100644 --- a/crates/scap-targets/src/platform/win.rs +++ b/crates/scap-targets/src/platform/win.rs @@ -1,5 +1,5 @@ -use std::{ffi::OsString, mem, os::windows::ffi::OsStringExt, path::PathBuf, str::FromStr}; -use tracing::error; +use std::{ffi::OsString, mem, os::windows::ffi::OsStringExt, panic, path::PathBuf, str::FromStr}; +use tracing::{error, warn}; use windows::{ Graphics::Capture::GraphicsCaptureItem, Win32::{ @@ -258,7 +258,26 @@ impl DisplayImpl { pub fn try_as_capture_item(&self) -> windows::core::Result { let interop = windows::core::factory::()?; - unsafe { interop.CreateForMonitor(self.0) } + + // Wrap the unsafe FFI call in catch_unwind to handle C++ exceptions that may cross the FFI boundary. + // On Windows 10 build 18363 (the minimum supported version), the Graphics Capture API can throw + // C++ exceptions instead of returning proper error codes, which would otherwise crash the application. + let monitor = self.0; + match panic::catch_unwind(panic::AssertUnwindSafe(|| unsafe { + interop.CreateForMonitor(monitor) + })) { + Ok(result) => result, + Err(panic_info) => { + // Log the panic to help diagnose issues on older Windows versions + warn!( + "Graphics Capture API panicked when creating capture item for monitor. \ + This may indicate a permissions issue or incompatibility with Windows 10 build 18363. \ + Panic info: {:?}", + panic_info + ); + Err(windows::core::Error::from_win32()) + } + } } } @@ -1148,7 +1167,26 @@ impl WindowImpl { pub fn try_as_capture_item(&self) -> windows::core::Result { let interop = windows::core::factory::()?; - unsafe { interop.CreateForWindow(self.0) } + + // Wrap the unsafe FFI call in catch_unwind to handle C++ exceptions that may cross the FFI boundary. + // On Windows 10 build 18363 (the minimum supported version), the Graphics Capture API can throw + // C++ exceptions instead of returning proper error codes, which would otherwise crash the application. + let window = self.0; + match panic::catch_unwind(panic::AssertUnwindSafe(|| unsafe { + interop.CreateForWindow(window) + })) { + Ok(result) => result, + Err(panic_info) => { + // Log the panic to help diagnose issues on older Windows versions + warn!( + "Graphics Capture API panicked when creating capture item for window. \ + This may indicate a permissions issue or incompatibility with Windows 10 build 18363. \ + Panic info: {:?}", + panic_info + ); + Err(windows::core::Error::from_win32()) + } + } } }