check if WDA_EXCLUDEFROMCAPTURE is supported

Signed-off-by: fufesou <shuanglongchen@yeah.net>
This commit is contained in:
fufesou 2023-11-19 19:23:10 +08:00
parent c23f377039
commit 7c98bfd363
6 changed files with 114 additions and 32 deletions

View File

@ -570,7 +570,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("id_input_tip", ""),
("privacy_mode_impl_mag_tip", "模式 1 (不推荐)"),
("privacy_mode_impl_virtual_display_tip", "模式 2 (推荐)"),
("privacy_mode_impl_exclude_from_capture_tip", "模式 3"),
("privacy_mode_impl_exclude_from_capture_tip", "模式 1"),
("Enter privacy mode", "进入隐私模式"),
("Exit privacy mode", "退出隐私模式"),
].iter().cloned().collect();

View File

@ -205,6 +205,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("id_input_tip", "You can input an ID, a direct IP, or a domain with a port (<domain>:<port>).\nIf you want to access a device on another server, please append the server address (<id>@<server_address>?key=<key_value>), for example,\n9123456234@192.168.16.1:21117?key=5Qbwsde3unUcJBtrx9ZkvUmwFNoExHzpryHuPUdqlWM=.\nIf you want to access a device on a public server, please input \"<id>@public\", the key is not needed for public server"),
("privacy_mode_impl_mag_tip", "Mode 1 (deprecated)"),
("privacy_mode_impl_virtual_display_tip", "Mode 2 (recommended)"),
("privacy_mode_impl_exclude_from_capture_tip", "Mode 3"),
("privacy_mode_impl_exclude_from_capture_tip", "Mode 1"),
].iter().cloned().collect();
}

View File

@ -628,8 +628,46 @@ extern "C"
return bSystem;
}
void alloc_console_and_redirect() {
void alloc_console_and_redirect()
{
AllocConsole();
freopen("CONOUT$", "w", stdout);
}
} // end of extern "C"
} // end of extern "C"
extern "C"
{
// https://github.com/nodejs/node-convergence-archive/blob/e11fe0c2777561827cdb7207d46b0917ef3c42a7/deps/uv/src/win/util.c#L780
BOOL IsWindowsVersionOrGreater(DWORD os_major,
DWORD os_minor,
DWORD build_number,
WORD service_pack_major,
WORD service_pack_minor)
{
OSVERSIONINFOEX osvi;
DWORDLONG condition_mask = 0;
int op = VER_GREATER_EQUAL;
/* Initialize the OSVERSIONINFOEX structure. */
ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
osvi.dwMajorVersion = os_major;
osvi.dwMinorVersion = os_minor;
osvi.dwBuildNumber = build_number;
osvi.wServicePackMajor = service_pack_major;
osvi.wServicePackMinor = service_pack_minor;
/* Initialize the condition mask. */
VER_SET_CONDITION(condition_mask, VER_MAJORVERSION, op);
VER_SET_CONDITION(condition_mask, VER_MINORVERSION, op);
VER_SET_CONDITION(condition_mask, VER_SERVICEPACKMAJOR, op);
VER_SET_CONDITION(condition_mask, VER_SERVICEPACKMINOR, op);
/* Perform the test. */
return VerifyVersionInfo(
&osvi,
VER_MAJORVERSION | VER_MINORVERSION |
VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
condition_mask);
}
}

View File

@ -460,6 +460,13 @@ extern "C" {
fn is_win_down() -> BOOL;
fn is_local_system() -> BOOL;
fn alloc_console_and_redirect();
fn IsWindowsVersionOrGreater(
os_major: DWORD,
os_minor: DWORD,
build_number: DWORD,
service_pack_major: WORD,
service_pack_minor: WORD,
) -> BOOL;
}
extern "system" {
@ -1283,6 +1290,25 @@ pub fn block_input(v: bool) -> (bool, String) {
}
}
#[inline]
pub fn is_windows_version_or_greater(
os_major: u32,
os_minor: u32,
build_number: u32,
service_pack_major: u32,
service_pack_minor: u32,
) -> bool {
unsafe {
IsWindowsVersionOrGreater(
os_major as _,
os_minor as _,
build_number as _,
service_pack_major as _,
service_pack_minor as _,
) == TRUE
}
}
pub fn add_recent_document(path: &str) {
extern "C" {
fn AddRecentDocument(path: *const u16);

View File

@ -90,23 +90,26 @@ lazy_static::lazy_static! {
pub static ref DEFAULT_PRIVACY_MODE_IMPL: String = {
#[cfg(windows)]
{
PRIVACY_MODE_IMPL_WIN_EXCLUDE_FROM_CAPTURE.to_owned()
// if display_service::is_privacy_mode_mag_supported() {
// PRIVACY_MODE_IMPL_WIN_MAG
// } else {
// #[cfg(feature = "virtual_display_driver")]
// {
// if is_installed() {
// PRIVACY_MODE_IMPL_WIN_VIRTUAL_DISPLAY
// } else {
// ""
// }
// }
// #[cfg(not(feature = "virtual_display_driver"))]
// {
// ""
// }
// }.to_owned()
if win_exclude_from_capture::is_supported() {
PRIVACY_MODE_IMPL_WIN_EXCLUDE_FROM_CAPTURE
} else {
if display_service::is_privacy_mode_mag_supported() {
PRIVACY_MODE_IMPL_WIN_MAG
} else {
#[cfg(feature = "virtual_display_driver")]
{
if is_installed() {
PRIVACY_MODE_IMPL_WIN_VIRTUAL_DISPLAY
} else {
""
}
}
#[cfg(not(feature = "virtual_display_driver"))]
{
""
}
}
}.to_owned()
}
#[cfg(not(windows))]
{
@ -140,13 +143,15 @@ lazy_static::lazy_static! {
let mut map: HashMap<&'static str, PrivacyModeCreator> = HashMap::new();
#[cfg(windows)]
{
map.insert(win_mag::PRIVACY_MODE_IMPL, || {
Box::new(win_mag::PrivacyModeImpl::default())
});
map.insert(win_exclude_from_capture::PRIVACY_MODE_IMPL, || {
if win_exclude_from_capture::is_supported() {
map.insert(win_exclude_from_capture::PRIVACY_MODE_IMPL, || {
Box::new(win_exclude_from_capture::PrivacyModeImpl::default())
});
} else {
map.insert(win_mag::PRIVACY_MODE_IMPL, || {
Box::new(win_mag::PrivacyModeImpl::default())
});
}
#[cfg(feature = "virtual_display_driver")]
map.insert(win_virtual_display::PRIVACY_MODE_IMPL, || {
@ -280,13 +285,18 @@ pub fn get_supported_privacy_mode_impl() -> Vec<(&'static str, &'static str)> {
#[cfg(target_os = "windows")]
{
let mut vec_impls = Vec::new();
if display_service::is_privacy_mode_mag_supported() {
vec_impls.push((PRIVACY_MODE_IMPL_WIN_MAG, "privacy_mode_impl_mag_tip"));
if win_exclude_from_capture::is_supported() {
vec_impls.push((
PRIVACY_MODE_IMPL_WIN_EXCLUDE_FROM_CAPTURE,
"privacy_mode_impl_exclude_from_capture_tip",
));
} else {
if display_service::is_privacy_mode_mag_supported() {
vec_impls.push((PRIVACY_MODE_IMPL_WIN_MAG, "privacy_mode_impl_mag_tip"));
}
}
vec_impls.push((
PRIVACY_MODE_IMPL_WIN_EXCLUDE_FROM_CAPTURE,
"privacy_mode_impl_exclude_from_capture_tip",
));
#[cfg(feature = "virtual_display_driver")]
if is_installed() {
vec_impls.push((
@ -294,6 +304,7 @@ pub fn get_supported_privacy_mode_impl() -> Vec<(&'static str, &'static str)> {
"privacy_mode_impl_virtual_display_tip",
));
}
vec_impls
}
#[cfg(not(target_os = "windows"))]
@ -324,6 +335,7 @@ pub fn check_privacy_mode_err(
display_idx: usize,
timeout_millis: u64,
) -> String {
// win magnifier implementation requires a test of creating a capturer.
if is_current_privacy_mode_impl(PRIVACY_MODE_IMPL_WIN_MAG) {
crate::video_service::test_create_capturer(privacy_mode_id, display_idx, timeout_millis)
} else {

View File

@ -1,3 +1,9 @@
pub use super::win_topmost_window::PrivacyModeImpl;
pub(super) const PRIVACY_MODE_IMPL: &str = "privacy_mode_impl_exclude_from_capture";
pub(super) fn is_supported() -> bool {
// https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-setwindowdisplayaffinity
// https://en.wikipedia.org/wiki/Windows_10_version_history
crate::platform::windows::is_windows_version_or_greater(10, 0, 19041, 0, 0)
}