diff --git a/libs/hbb_common/src/platform/windows.rs b/libs/hbb_common/src/platform/windows.rs index 26cd907ab..ae3e33839 100644 --- a/libs/hbb_common/src/platform/windows.rs +++ b/libs/hbb_common/src/platform/windows.rs @@ -5,7 +5,7 @@ use std::{ time::Instant, }; use winapi::{ - shared::minwindef::{DWORD, FALSE}, + shared::minwindef::{DWORD, FALSE, TRUE}, um::{ handleapi::CloseHandle, pdh::{ @@ -14,7 +14,12 @@ use winapi::{ PDH_HCOUNTER, PDH_HQUERY, }, synchapi::{CreateEventA, WaitForSingleObject}, - winbase::{INFINITE, WAIT_OBJECT_0}, + sysinfoapi::VerSetConditionMask, + winbase::{VerifyVersionInfoW, INFINITE, WAIT_OBJECT_0}, + winnt::{ + OSVERSIONINFOEXW, VER_BUILDNUMBER, VER_GREATER_EQUAL, VER_MAJORVERSION, + VER_MINORVERSION, VER_SERVICEPACKMAJOR, VER_SERVICEPACKMINOR, + }, }, }; @@ -152,3 +157,43 @@ pub fn sync_cpu_usage(cpu_usage: Option) { *CPU_USAGE_ONE_MINUTE.lock().unwrap() = v; log::info!("cpu usage synced: {:?}", cpu_usage); } + +// https://learn.microsoft.com/en-us/windows/win32/sysinfo/targeting-your-application-at-windows-8-1 +// https://github.com/nodejs/node-convergence-archive/blob/e11fe0c2777561827cdb7207d46b0917ef3c42a7/deps/uv/src/win/util.c#L780 +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 { + let mut osvi: OSVERSIONINFOEXW = unsafe { std::mem::zeroed() }; + osvi.dwOSVersionInfoSize = std::mem::size_of::() as DWORD; + osvi.dwMajorVersion = os_major as _; + osvi.dwMinorVersion = os_minor as _; + osvi.dwBuildNumber = build_number as _; + osvi.wServicePackMajor = service_pack_major as _; + osvi.wServicePackMinor = service_pack_minor as _; + + let result = unsafe { + let mut condition_mask = 0; + let op = VER_GREATER_EQUAL; + condition_mask = VerSetConditionMask(condition_mask, VER_MAJORVERSION, op); + condition_mask = VerSetConditionMask(condition_mask, VER_MINORVERSION, op); + condition_mask = VerSetConditionMask(condition_mask, VER_BUILDNUMBER, op); + condition_mask = VerSetConditionMask(condition_mask, VER_SERVICEPACKMAJOR, op); + condition_mask = VerSetConditionMask(condition_mask, VER_SERVICEPACKMINOR, op); + + VerifyVersionInfoW( + &mut osvi as *mut OSVERSIONINFOEXW, + VER_MAJORVERSION + | VER_MINORVERSION + | VER_BUILDNUMBER + | VER_SERVICEPACKMAJOR + | VER_SERVICEPACKMINOR, + condition_mask, + ) + }; + + result == TRUE +} diff --git a/src/core_main.rs b/src/core_main.rs index dc439f344..4529df6ab 100644 --- a/src/core_main.rs +++ b/src/core_main.rs @@ -204,7 +204,9 @@ pub fn core_main() -> Option> { #[cfg(windows)] hbb_common::allow_err!(crate::platform::windows::install_cert(&args[1])); #[cfg(all(windows, feature = "virtual_display_driver"))] - hbb_common::allow_err!(crate::virtual_display_manager::install_update_driver()); + if crate::virtual_display_manager::is_virtual_display_supported() { + hbb_common::allow_err!(crate::virtual_display_manager::install_update_driver()); + } return None; } else if args[0] == "--uninstall-cert" { #[cfg(windows)] diff --git a/src/lang/ar.rs b/src/lang/ar.rs index 95f0a8a04..b46a47a46 100644 --- a/src/lang/ar.rs +++ b/src/lang/ar.rs @@ -572,5 +572,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("privacy_mode_impl_virtual_display_tip", ""), ("Enter privacy mode", ""), ("Exit privacy mode", ""), + ("idd_not_support_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/ca.rs b/src/lang/ca.rs index 37ac295aa..36061dcfe 100644 --- a/src/lang/ca.rs +++ b/src/lang/ca.rs @@ -572,5 +572,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("privacy_mode_impl_virtual_display_tip", ""), ("Enter privacy mode", ""), ("Exit privacy mode", ""), + ("idd_not_support_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/cn.rs b/src/lang/cn.rs index be59faecb..a3b85908f 100644 --- a/src/lang/cn.rs +++ b/src/lang/cn.rs @@ -572,5 +572,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("privacy_mode_impl_virtual_display_tip", "模式 2"), ("Enter privacy mode", "进入隐私模式"), ("Exit privacy mode", "退出隐私模式"), + ("idd_not_support_tip", "不支持 Indirect Display Driver 。需要更新的 Windows 10 版本。"), ].iter().cloned().collect(); } diff --git a/src/lang/cs.rs b/src/lang/cs.rs index 993f136f4..12b16d79c 100644 --- a/src/lang/cs.rs +++ b/src/lang/cs.rs @@ -572,5 +572,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("privacy_mode_impl_virtual_display_tip", ""), ("Enter privacy mode", ""), ("Exit privacy mode", ""), + ("idd_not_support_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/da.rs b/src/lang/da.rs index 7cbe8d99d..8a6387ce3 100644 --- a/src/lang/da.rs +++ b/src/lang/da.rs @@ -572,5 +572,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("privacy_mode_impl_virtual_display_tip", ""), ("Enter privacy mode", ""), ("Exit privacy mode", ""), + ("idd_not_support_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/de.rs b/src/lang/de.rs index 9017a744a..ed134f778 100644 --- a/src/lang/de.rs +++ b/src/lang/de.rs @@ -572,5 +572,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("privacy_mode_impl_virtual_display_tip", ""), ("Enter privacy mode", ""), ("Exit privacy mode", ""), + ("idd_not_support_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/el.rs b/src/lang/el.rs index 46577ce90..76aab3198 100644 --- a/src/lang/el.rs +++ b/src/lang/el.rs @@ -572,5 +572,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("privacy_mode_impl_virtual_display_tip", ""), ("Enter privacy mode", ""), ("Exit privacy mode", ""), + ("idd_not_support_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/en.rs b/src/lang/en.rs index a5f494b74..30e58e875 100644 --- a/src/lang/en.rs +++ b/src/lang/en.rs @@ -205,5 +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 (:).\nIf you want to access a device on another server, please append the server address (@?key=), for example,\n9123456234@192.168.16.1:21117?key=5Qbwsde3unUcJBtrx9ZkvUmwFNoExHzpryHuPUdqlWM=.\nIf you want to access a device on a public server, please input \"@public\", the key is not needed for public server"), ("privacy_mode_impl_mag_tip", "Mode 1"), ("privacy_mode_impl_virtual_display_tip", "Mode 2"), + ("idd_not_support_tip", "Indirect Display Driver is not supported. Newer Windows 10 version is required."), ].iter().cloned().collect(); } diff --git a/src/lang/eo.rs b/src/lang/eo.rs index 35230ccb1..45ac4b033 100644 --- a/src/lang/eo.rs +++ b/src/lang/eo.rs @@ -572,5 +572,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("privacy_mode_impl_virtual_display_tip", ""), ("Enter privacy mode", ""), ("Exit privacy mode", ""), + ("idd_not_support_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/es.rs b/src/lang/es.rs index a2dcd53ba..8125323ef 100644 --- a/src/lang/es.rs +++ b/src/lang/es.rs @@ -572,5 +572,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("privacy_mode_impl_virtual_display_tip", "Modo 2"), ("Enter privacy mode", "Entrar al modo privado"), ("Exit privacy mode", "Salir del modo privado"), + ("idd_not_support_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/fa.rs b/src/lang/fa.rs index 0d8c8e356..fcedaaedf 100644 --- a/src/lang/fa.rs +++ b/src/lang/fa.rs @@ -572,5 +572,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("privacy_mode_impl_virtual_display_tip", ""), ("Enter privacy mode", ""), ("Exit privacy mode", ""), + ("idd_not_support_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/fr.rs b/src/lang/fr.rs index 7f840558e..2f9d811ac 100644 --- a/src/lang/fr.rs +++ b/src/lang/fr.rs @@ -572,5 +572,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("privacy_mode_impl_virtual_display_tip", ""), ("Enter privacy mode", ""), ("Exit privacy mode", ""), + ("idd_not_support_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/hu.rs b/src/lang/hu.rs index 298a07d6e..a8afd1dfa 100644 --- a/src/lang/hu.rs +++ b/src/lang/hu.rs @@ -572,5 +572,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("privacy_mode_impl_virtual_display_tip", ""), ("Enter privacy mode", ""), ("Exit privacy mode", ""), + ("idd_not_support_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/id.rs b/src/lang/id.rs index 3455ddab4..419967ff6 100644 --- a/src/lang/id.rs +++ b/src/lang/id.rs @@ -572,5 +572,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("privacy_mode_impl_virtual_display_tip", "Mode 2"), ("Enter privacy mode", "Masuk mode privasi"), ("Exit privacy mode", "Keluar mode privasi"), + ("idd_not_support_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/it.rs b/src/lang/it.rs index 70fbe1c4e..9c2b769b9 100644 --- a/src/lang/it.rs +++ b/src/lang/it.rs @@ -572,5 +572,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("privacy_mode_impl_virtual_display_tip", "Modo 2"), ("Enter privacy mode", "Entra in modalità privacy"), ("Exit privacy mode", "Esci dalla modalità privacy"), + ("idd_not_support_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/ja.rs b/src/lang/ja.rs index a5c0dff2f..25706fda5 100644 --- a/src/lang/ja.rs +++ b/src/lang/ja.rs @@ -572,5 +572,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("privacy_mode_impl_virtual_display_tip", ""), ("Enter privacy mode", ""), ("Exit privacy mode", ""), + ("idd_not_support_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/ko.rs b/src/lang/ko.rs index 26a666d53..c7f25fb72 100644 --- a/src/lang/ko.rs +++ b/src/lang/ko.rs @@ -572,5 +572,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("privacy_mode_impl_virtual_display_tip", "모드 2"), ("Enter privacy mode", "개인정보 보호 모드 사용"), ("Exit privacy mode", "개인정보 보호 모드 종료"), + ("idd_not_support_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/kz.rs b/src/lang/kz.rs index 5d9ec3f3a..c8d46e5dc 100644 --- a/src/lang/kz.rs +++ b/src/lang/kz.rs @@ -572,5 +572,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("privacy_mode_impl_virtual_display_tip", ""), ("Enter privacy mode", ""), ("Exit privacy mode", ""), + ("idd_not_support_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/lt.rs b/src/lang/lt.rs index 69b210311..33da68196 100644 --- a/src/lang/lt.rs +++ b/src/lang/lt.rs @@ -572,5 +572,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("privacy_mode_impl_virtual_display_tip", ""), ("Enter privacy mode", ""), ("Exit privacy mode", ""), + ("idd_not_support_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/lv.rs b/src/lang/lv.rs index 100d701fb..6ed5daf82 100644 --- a/src/lang/lv.rs +++ b/src/lang/lv.rs @@ -572,5 +572,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("privacy_mode_impl_virtual_display_tip", "2. režīms"), ("Enter privacy mode", "Ieiet privātuma režīmā"), ("Exit privacy mode", "Iziet no privātuma režīma"), + ("idd_not_support_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/nb.rs b/src/lang/nb.rs index d36499d7f..09b31a9e0 100644 --- a/src/lang/nb.rs +++ b/src/lang/nb.rs @@ -154,15 +154,15 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("config_screen", "For å kunne få adgang til ditt skrivebord med fjernstyring, må du gi Rustdesk \"skjerstøtte \" tillatelser."), ("Installing ...", "Installerer ..."), ("Install", "installer"), - ("installasjon", "Installasjon"), - ("installasjon Path", "Installasjonssti"), + ("Installation", ""), + ("Installation Path", ""), ("Create start menu shortcuts", "Oppret start meny snarvei"), ("Create desktop icon", "Oppret skrivebords-snarvei"), ("agreement_tip", "Hvis du starter installasjonen, må du akseptere lisensavtalen"), ("Accept and Install", "Aksepter og installer"), ("End-user license agreement", "Lisensavtale for sluttbrukere"), ("Generating ...", "Genererer kode ..."), - ("Your installasjon is lower version.", "Din installasjon er en eldre versjon."), + ("Your installation is lower version.", ""), ("not_close_tcp_tip", "Ikke lukk dette vinduet, mens du bruker tunnelen."), ("Listening ...", "Lytter ..."), ("Remote Host", "Fjern-Host"), @@ -532,8 +532,8 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Change Color", ""), ("Primary Color", ""), ("HSV Color", ""), - ("installasjon Successful!", ""), - ("installasjon failed!", ""), + ("Installation Successful!", ""), + ("Installation failed!", ""), ("Reverse mouse wheel", ""), ("{} sessions", ""), ("scam_title", ""), @@ -572,5 +572,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("privacy_mode_impl_virtual_display_tip", ""), ("Enter privacy mode", ""), ("Exit privacy mode", ""), + ("idd_not_support_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/nl.rs b/src/lang/nl.rs index 280f5e9a0..260937b00 100644 --- a/src/lang/nl.rs +++ b/src/lang/nl.rs @@ -572,5 +572,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("privacy_mode_impl_virtual_display_tip", ""), ("Enter privacy mode", ""), ("Exit privacy mode", ""), + ("idd_not_support_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/pl.rs b/src/lang/pl.rs index aa91e8e9a..c63133cc6 100644 --- a/src/lang/pl.rs +++ b/src/lang/pl.rs @@ -572,5 +572,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("privacy_mode_impl_virtual_display_tip", "Tryb 2"), ("Enter privacy mode", "Wejdź w tryb prywatności"), ("Exit privacy mode", "Wyjdź z trybu prywatności"), + ("idd_not_support_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/pt_PT.rs b/src/lang/pt_PT.rs index 8ca5a0b84..f2a7c7253 100644 --- a/src/lang/pt_PT.rs +++ b/src/lang/pt_PT.rs @@ -572,5 +572,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("privacy_mode_impl_virtual_display_tip", ""), ("Enter privacy mode", ""), ("Exit privacy mode", ""), + ("idd_not_support_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/ptbr.rs b/src/lang/ptbr.rs index 708784c20..541b28eda 100644 --- a/src/lang/ptbr.rs +++ b/src/lang/ptbr.rs @@ -572,5 +572,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("privacy_mode_impl_virtual_display_tip", ""), ("Enter privacy mode", ""), ("Exit privacy mode", ""), + ("idd_not_support_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/ro.rs b/src/lang/ro.rs index c1eac74f8..85374e87d 100644 --- a/src/lang/ro.rs +++ b/src/lang/ro.rs @@ -572,5 +572,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("privacy_mode_impl_virtual_display_tip", ""), ("Enter privacy mode", ""), ("Exit privacy mode", ""), + ("idd_not_support_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/ru.rs b/src/lang/ru.rs index abca158c9..5e4271080 100644 --- a/src/lang/ru.rs +++ b/src/lang/ru.rs @@ -572,5 +572,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("privacy_mode_impl_virtual_display_tip", "Режим 2"), ("Enter privacy mode", "Включить режим конфиденциальности"), ("Exit privacy mode", "Отключить режим конфиденциальности"), + ("idd_not_support_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/sk.rs b/src/lang/sk.rs index 072b532e6..7867da466 100644 --- a/src/lang/sk.rs +++ b/src/lang/sk.rs @@ -572,5 +572,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("privacy_mode_impl_virtual_display_tip", ""), ("Enter privacy mode", ""), ("Exit privacy mode", ""), + ("idd_not_support_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/sl.rs b/src/lang/sl.rs index 382b8a89d..f9dd56308 100755 --- a/src/lang/sl.rs +++ b/src/lang/sl.rs @@ -572,5 +572,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("privacy_mode_impl_virtual_display_tip", ""), ("Enter privacy mode", ""), ("Exit privacy mode", ""), + ("idd_not_support_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/sq.rs b/src/lang/sq.rs index c47a154ca..0f9a4f05d 100644 --- a/src/lang/sq.rs +++ b/src/lang/sq.rs @@ -572,5 +572,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("privacy_mode_impl_virtual_display_tip", ""), ("Enter privacy mode", ""), ("Exit privacy mode", ""), + ("idd_not_support_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/sr.rs b/src/lang/sr.rs index 832e81283..e7ca84c05 100644 --- a/src/lang/sr.rs +++ b/src/lang/sr.rs @@ -572,5 +572,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("privacy_mode_impl_virtual_display_tip", ""), ("Enter privacy mode", ""), ("Exit privacy mode", ""), + ("idd_not_support_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/sv.rs b/src/lang/sv.rs index b2e42a291..1e9eb0b1b 100644 --- a/src/lang/sv.rs +++ b/src/lang/sv.rs @@ -572,5 +572,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("privacy_mode_impl_virtual_display_tip", ""), ("Enter privacy mode", ""), ("Exit privacy mode", ""), + ("idd_not_support_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/template.rs b/src/lang/template.rs index 027baebad..16735d180 100644 --- a/src/lang/template.rs +++ b/src/lang/template.rs @@ -572,5 +572,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("privacy_mode_impl_virtual_display_tip", ""), ("Enter privacy mode", ""), ("Exit privacy mode", ""), + ("idd_not_support_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/th.rs b/src/lang/th.rs index b81b77b0a..796bde955 100644 --- a/src/lang/th.rs +++ b/src/lang/th.rs @@ -572,5 +572,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("privacy_mode_impl_virtual_display_tip", ""), ("Enter privacy mode", ""), ("Exit privacy mode", ""), + ("idd_not_support_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/tr.rs b/src/lang/tr.rs index 3fc58963a..ffd3c862d 100644 --- a/src/lang/tr.rs +++ b/src/lang/tr.rs @@ -572,5 +572,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("privacy_mode_impl_virtual_display_tip", ""), ("Enter privacy mode", ""), ("Exit privacy mode", ""), + ("idd_not_support_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/tw.rs b/src/lang/tw.rs index 4ea5bc250..a8a413a70 100644 --- a/src/lang/tw.rs +++ b/src/lang/tw.rs @@ -572,5 +572,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("privacy_mode_impl_virtual_display_tip", ""), ("Enter privacy mode", ""), ("Exit privacy mode", ""), + ("idd_not_support_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/ua.rs b/src/lang/ua.rs index b0b193f94..449aec697 100644 --- a/src/lang/ua.rs +++ b/src/lang/ua.rs @@ -572,5 +572,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("privacy_mode_impl_virtual_display_tip", "Режим 2"), ("Enter privacy mode", "Увійти в режим конфіденційності"), ("Exit privacy mode", "Вийти з режиму конфіденційності"), + ("idd_not_support_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/vn.rs b/src/lang/vn.rs index 89b6a189f..727e73241 100644 --- a/src/lang/vn.rs +++ b/src/lang/vn.rs @@ -572,5 +572,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("privacy_mode_impl_virtual_display_tip", ""), ("Enter privacy mode", ""), ("Exit privacy mode", ""), + ("idd_not_support_tip", ""), ].iter().cloned().collect(); } diff --git a/src/platform/windows.cc b/src/platform/windows.cc index 25372b218..8e2f73fbe 100644 --- a/src/platform/windows.cc +++ b/src/platform/windows.cc @@ -634,42 +634,3 @@ extern "C" freopen("CONOUT$", "w", stdout); } } // end of extern "C" - -extern "C" -{ - // https://learn.microsoft.com/en-us/windows/win32/sysinfo/targeting-your-application-at-windows-8-1 - // 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_BUILDNUMBER, 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_BUILDNUMBER | - VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR, - condition_mask); - } -} diff --git a/src/platform/windows.rs b/src/platform/windows.rs index 3a726c2a1..42e071468 100644 --- a/src/platform/windows.rs +++ b/src/platform/windows.rs @@ -460,13 +460,6 @@ 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" { @@ -1255,25 +1248,6 @@ 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); diff --git a/src/privacy_mode/win_exclude_from_capture.rs b/src/privacy_mode/win_exclude_from_capture.rs index 0bb81f693..63164f838 100644 --- a/src/privacy_mode/win_exclude_from_capture.rs +++ b/src/privacy_mode/win_exclude_from_capture.rs @@ -1,3 +1,5 @@ +use hbb_common::platform::windows::is_windows_version_or_greater; + pub use super::win_topmost_window::PrivacyModeImpl; pub(super) const PRIVACY_MODE_IMPL: &str = "privacy_mode_impl_exclude_from_capture"; @@ -5,5 +7,5 @@ pub(super) const PRIVACY_MODE_IMPL: &str = "privacy_mode_impl_exclude_from_captu 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) + is_windows_version_or_greater(10, 0, 19041, 0, 0) } diff --git a/src/privacy_mode/win_virtual_display.rs b/src/privacy_mode/win_virtual_display.rs index 372479b5d..30ae6aaa2 100644 --- a/src/privacy_mode/win_virtual_display.rs +++ b/src/privacy_mode/win_virtual_display.rs @@ -357,6 +357,10 @@ impl PrivacyMode for PrivacyModeImpl { } fn turn_on_privacy(&mut self, conn_id: i32) -> ResultType { + if !virtual_display_manager::is_virtual_display_supported() { + bail!("idd_not_support_tip"); + } + if self.check_on_conn_id(conn_id)? { log::debug!("Privacy mode of conn {} is already on", conn_id); return Ok(true); diff --git a/src/server/connection.rs b/src/server/connection.rs index 464edfb37..8d16380a1 100644 --- a/src/server/connection.rs +++ b/src/server/connection.rs @@ -2371,14 +2371,19 @@ impl Connection { }; if t.on { - if let Err(e) = virtual_display_manager::plug_in_index_modes(t.display as _, Vec::new()) - { - log::error!("Failed to plug in virtual display: {}", e); - self.send(make_msg(format!( - "Failed to plug in virtual display: {}", - e - ))) - .await; + if !virtual_display_manager::is_virtual_display_supported() { + self.send(make_msg("idd_not_support_tip".to_string())).await; + } else { + if let Err(e) = + virtual_display_manager::plug_in_index_modes(t.display as _, Vec::new()) + { + log::error!("Failed to plug in virtual display: {}", e); + self.send(make_msg(format!( + "Failed to plug in virtual display: {}", + e + ))) + .await; + } } } else { let indices = if t.display == -1 { diff --git a/src/server/display_service.rs b/src/server/display_service.rs index 3ff9f4954..35d7ac07d 100644 --- a/src/server/display_service.rs +++ b/src/server/display_service.rs @@ -348,7 +348,10 @@ pub fn try_get_displays() -> ResultType> { #[cfg(all(windows, feature = "virtual_display_driver"))] pub fn try_get_displays() -> ResultType> { let mut displays = Display::all()?; - if crate::platform::is_installed() && no_displays(&displays) { + if crate::platform::is_installed() + && no_displays(&displays) + && virtual_display_manager::is_virtual_display_supported() + { log::debug!("no displays, create virtual display"); if let Err(e) = virtual_display_manager::plug_in_headless() { log::error!("plug in headless failed {}", e); diff --git a/src/virtual_display_manager.rs b/src/virtual_display_manager.rs index c51b74baf..da8780c7f 100644 --- a/src/virtual_display_manager.rs +++ b/src/virtual_display_manager.rs @@ -1,3 +1,5 @@ +#[cfg(target_os = "windows")] +use hbb_common::platform::windows::is_windows_version_or_greater; use hbb_common::{allow_err, bail, lazy_static, log, ResultType}; use std::{ collections::{HashMap, HashSet}, @@ -53,6 +55,17 @@ impl VirtualDisplayManager { } } +pub fn is_virtual_display_supported() -> bool { + #[cfg(target_os = "windows")] + { + is_windows_version_or_greater(10, 0, 19041, 0, 0) + } + #[cfg(not(target_os = "windows"))] + { + false + } +} + pub fn install_update_driver() -> ResultType<()> { VIRTUAL_DISPLAY_MANAGER .lock() @@ -146,6 +159,10 @@ pub fn plug_in_index_modes( } pub fn reset_all() -> ResultType<()> { + if is_virtual_display_supported() { + return Ok(()); + } + if let Err(e) = plug_out_peer_request(&get_virtual_displays()) { log::error!("Failed to plug out virtual displays: {}", e); }