diff --git a/src/Rust/Cargo.lock b/src/Rust/Cargo.lock index 17dfd362..e8b74fe4 100644 --- a/src/Rust/Cargo.lock +++ b/src/Rust/Cargo.lock @@ -750,6 +750,16 @@ version = "0.2.153" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" +[[package]] +name = "libloading" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c2a198fb6b0eada2a8df47933734e6d35d350665a33a3593d7164fa52c75c19" +dependencies = [ + "cfg-if 1.0.0", + "windows-targets 0.52.5", +] + [[package]] name = "libredox" version = "0.0.1" @@ -1623,6 +1633,7 @@ dependencies = [ "image", "lazy_static", "libc", + "libloading", "log", "memmap2", "native-dialog", diff --git a/src/Rust/Cargo.toml b/src/Rust/Cargo.toml index 2ba56f36..d03d400d 100644 --- a/src/Rust/Cargo.toml +++ b/src/Rust/Cargo.toml @@ -128,6 +128,7 @@ windows-sys = { version = "0.52", default-features = false, features = [ ] } normpath = "1.0.1" webview2-com = "0.30" +libloading = "0.8" [dev-dependencies] tempfile = "3.9" diff --git a/src/Rust/src/shared/runtime_arch.rs b/src/Rust/src/shared/runtime_arch.rs index e8b3a8a8..03a67a33 100644 --- a/src/Rust/src/shared/runtime_arch.rs +++ b/src/Rust/src/shared/runtime_arch.rs @@ -1,3 +1,5 @@ +use anyhow::Result; + #[derive(PartialEq, Debug, Clone, strum::IntoStaticStr)] pub enum RuntimeArch { X86, @@ -7,7 +9,7 @@ pub enum RuntimeArch { impl RuntimeArch { #[cfg(target_os = "windows")] - fn from_u32(value: u32) -> Option { + fn from_u16(value: u16) -> Option { match value { 0x014c => Some(RuntimeArch::X86), 0x8664 => Some(RuntimeArch::X64), @@ -51,16 +53,12 @@ impl RuntimeArch { #[cfg(target_os = "windows")] fn check_arch_windows() -> Option { use windows::Win32::Foundation::{FALSE, TRUE}; - use windows::Win32::System::SystemInformation::IMAGE_FILE_MACHINE; - use windows::Win32::System::Threading::{GetCurrentProcess, IsWow64Process, IsWow64Process2}; + use windows::Win32::System::Threading::{GetCurrentProcess, IsWow64Process}; unsafe { let handle = GetCurrentProcess(); - - let mut process_machine: IMAGE_FILE_MACHINE = Default::default(); - let mut native_machine: IMAGE_FILE_MACHINE = Default::default(); - if let Ok(()) = IsWow64Process2(handle, &mut process_machine, Some(&mut native_machine)) { - return RuntimeArch::from_u32(native_machine.0.into()); + if let Ok(x) = is_wow64_process2(handle) { + return RuntimeArch::from_u16(x); } let mut iswow64 = FALSE; @@ -80,6 +78,31 @@ fn check_arch_windows() -> Option { } } +#[cfg(target_os = "windows")] +type IsWow64Process2Fn = unsafe extern "system" fn( + hProcess: windows::Win32::Foundation::HANDLE, + pprocessmachine: *mut windows::Win32::System::SystemInformation::IMAGE_FILE_MACHINE, + pnativemachine: *mut windows::Win32::System::SystemInformation::IMAGE_FILE_MACHINE, +) -> windows::Win32::Foundation::BOOL; + +#[cfg(target_os = "windows")] +unsafe fn is_wow64_process2(handle: windows::Win32::Foundation::HANDLE) -> Result { + use windows::Win32::Foundation::TRUE; + use windows::Win32::System::SystemInformation::IMAGE_FILE_MACHINE; + + let lib = libloading::Library::new("kernel32.dll")?; + let func: libloading::Symbol = lib.get(b"IsWow64Process2")?; + let mut process_machine: IMAGE_FILE_MACHINE = Default::default(); + let mut native_machine: IMAGE_FILE_MACHINE = Default::default(); + + let result = func(handle, &mut process_machine, &mut native_machine); + if result == TRUE { + Ok(native_machine.0) + } else { + Err(anyhow::anyhow!("IsWow64Process2 failed")) + } +} + #[test] #[cfg(target_os = "windows")] fn test_current_architecture() {