From fe2a4d8b0c520886458a35cb766450e39af9bba1 Mon Sep 17 00:00:00 2001 From: Jiahao XU Date: Sat, 6 Apr 2024 12:08:10 +1000 Subject: [PATCH] Remove dep windows-dll and replace it with manual loading (#1658) Fixed #1629 Signed-off-by: Jiahao XU --- Cargo.lock | 165 ++++---------------- crates/detect-targets/Cargo.toml | 18 ++- crates/detect-targets/src/detect/windows.rs | 86 ++++++---- 3 files changed, 99 insertions(+), 170 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 93ae107a0..1c90ba682 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -153,7 +153,7 @@ checksum = "a507401cad91ec6a857ed5513a2073c82a9b9048762b885bb98655b306964681" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn", ] [[package]] @@ -352,7 +352,7 @@ dependencies = [ "serde_json", "tempfile", "thiserror", - "toml_edit 0.22.9", + "toml_edit", "url", ] @@ -378,7 +378,7 @@ dependencies = [ "tempfile", "thiserror", "tokio", - "toml_edit 0.22.9", + "toml_edit", "tracing", "url", ] @@ -647,7 +647,7 @@ dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.58", + "syn", ] [[package]] @@ -849,7 +849,7 @@ checksum = "64b697ac90ff296f0fc031ee5a61c7ac31fb9fff50e3fb32873b09223613fc0c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn", ] [[package]] @@ -861,7 +861,6 @@ dependencies = [ "tokio", "tracing", "tracing-subscriber", - "windows-dll", "windows-sys 0.52.0", ] @@ -958,7 +957,7 @@ dependencies = [ "heck 0.4.1", "proc-macro2", "quote", - "syn 2.0.58", + "syn", ] [[package]] @@ -1164,7 +1163,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn", ] [[package]] @@ -1290,7 +1289,7 @@ dependencies = [ "gix-utils", "itoa", "thiserror", - "winnow 0.6.5", + "winnow", ] [[package]] @@ -1372,7 +1371,7 @@ dependencies = [ "smallvec", "thiserror", "unicode-bom", - "winnow 0.6.5", + "winnow", ] [[package]] @@ -1593,7 +1592,7 @@ checksum = "1dff438f14e67e7713ab9332f5fd18c8f20eb7eb249494f6c2bf170522224032" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn", ] [[package]] @@ -1628,7 +1627,7 @@ dependencies = [ "itoa", "smallvec", "thiserror", - "winnow 0.6.5", + "winnow", ] [[package]] @@ -1752,7 +1751,7 @@ dependencies = [ "gix-utils", "maybe-async", "thiserror", - "winnow 0.6.5", + "winnow", ] [[package]] @@ -1785,7 +1784,7 @@ dependencies = [ "gix-validate", "memmap2", "thiserror", - "winnow 0.6.5", + "winnow", ] [[package]] @@ -2521,7 +2520,7 @@ dependencies = [ "leon", "proc-macro2", "quote", - "syn 2.0.58", + "syn", ] [[package]] @@ -2622,7 +2621,7 @@ checksum = "5cf92c10c7e361d6b99666ec1c6f9805b0bea2c3bd8c78dc6fe98ac5bd78db11" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn", ] [[package]] @@ -2683,7 +2682,7 @@ checksum = "dcf09caffaac8068c346b6df2a7fc27a177fd20b39421a39ce0a211bde679a6c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn", ] [[package]] @@ -2881,7 +2880,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn", ] [[package]] @@ -2978,7 +2977,7 @@ checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn", ] [[package]] @@ -3011,16 +3010,6 @@ version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" -[[package]] -name = "proc-macro-crate" -version = "1.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919" -dependencies = [ - "once_cell", - "toml_edit 0.19.15", -] - [[package]] name = "proc-macro2" version = "1.0.79" @@ -3576,7 +3565,7 @@ checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn", ] [[package]] @@ -3758,7 +3747,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.58", + "syn", ] [[package]] @@ -3788,17 +3777,6 @@ version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b7401a30af6cb5818bb64852270bb722533397edcfc7344954a38f420819ece2" -[[package]] -name = "syn" -version = "1.0.109" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - [[package]] name = "syn" version = "2.0.58" @@ -3893,7 +3871,7 @@ checksum = "c61f3ba182994efc43764a46c018c347bc492c79f024e705f46567b418f6d4f7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn", ] [[package]] @@ -3980,7 +3958,7 @@ checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn", ] [[package]] @@ -4064,7 +4042,7 @@ dependencies = [ "serde", "serde_spanned", "toml_datetime", - "toml_edit 0.22.9", + "toml_edit", ] [[package]] @@ -4076,17 +4054,6 @@ dependencies = [ "serde", ] -[[package]] -name = "toml_edit" -version = "0.19.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" -dependencies = [ - "indexmap", - "toml_datetime", - "winnow 0.5.40", -] - [[package]] name = "toml_edit" version = "0.22.9" @@ -4097,7 +4064,7 @@ dependencies = [ "serde", "serde_spanned", "toml_datetime", - "winnow 0.6.5", + "winnow", ] [[package]] @@ -4148,7 +4115,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn", ] [[package]] @@ -4386,7 +4353,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.58", + "syn", "wasm-bindgen-shared", ] @@ -4420,7 +4387,7 @@ checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -4506,19 +4473,6 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" -[[package]] -name = "windows" -version = "0.35.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08746b4b7ac95f708b3cccceb97b7f9a21a8916dd47fc99b0e6aaf7208f26fd7" -dependencies = [ - "windows_aarch64_msvc 0.35.0", - "windows_i686_gnu 0.35.0", - "windows_i686_msvc 0.35.0", - "windows_x86_64_gnu 0.35.0", - "windows_x86_64_msvc 0.35.0", -] - [[package]] name = "windows" version = "0.48.0" @@ -4548,30 +4502,6 @@ dependencies = [ "windows-targets 0.52.4", ] -[[package]] -name = "windows-dll" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0895e287d32aad509d5720ea1975e5d22b2fa51fc3e1f94163cdb73b185b5555" -dependencies = [ - "once_cell", - "thiserror", - "windows 0.35.0", - "windows-dll-codegen", -] - -[[package]] -name = "windows-dll-codegen" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7c2f703a1e16b2447f1ce6c6a7c9231535fef0ca2e260f4bc69ecc8e06b208b" -dependencies = [ - "proc-macro-crate", - "proc-macro2", - "quote", - "syn 1.0.109", -] - [[package]] name = "windows-result" version = "0.1.0" @@ -4641,12 +4571,6 @@ version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bcf46cf4c365c6f2d1cc93ce535f2c8b244591df96ceee75d8e83deb70a9cac9" -[[package]] -name = "windows_aarch64_msvc" -version = "0.35.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db3bc5134e8ce0da5d64dcec3529793f1d33aee5a51fc2b4662e0f881dd463e6" - [[package]] name = "windows_aarch64_msvc" version = "0.48.5" @@ -4659,12 +4583,6 @@ version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "da9f259dd3bcf6990b55bffd094c4f7235817ba4ceebde8e6d11cd0c5633b675" -[[package]] -name = "windows_i686_gnu" -version = "0.35.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0343a6f35bf43a07b009b8591b78b10ea03de86b06f48e28c96206cd0f453b50" - [[package]] name = "windows_i686_gnu" version = "0.48.5" @@ -4677,12 +4595,6 @@ version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b474d8268f99e0995f25b9f095bc7434632601028cf86590aea5c8a5cb7801d3" -[[package]] -name = "windows_i686_msvc" -version = "0.35.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1acdcbf4ca63d8e7a501be86fee744347186275ec2754d129ddeab7a1e3a02e4" - [[package]] name = "windows_i686_msvc" version = "0.48.5" @@ -4695,12 +4607,6 @@ version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1515e9a29e5bed743cb4415a9ecf5dfca648ce85ee42e15873c3cd8610ff8e02" -[[package]] -name = "windows_x86_64_gnu" -version = "0.35.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "893c0924c5a990ec73cd2264d1c0cba1773a929e1a3f5dbccffd769f8c4edebb" - [[package]] name = "windows_x86_64_gnu" version = "0.48.5" @@ -4725,12 +4631,6 @@ version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "77ca79f2451b49fa9e2af39f0747fe999fcda4f5e241b2898624dca97a1f2177" -[[package]] -name = "windows_x86_64_msvc" -version = "0.35.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a29bd61f32889c822c99a8fdf2e93378bd2fae4d7efd2693fab09fcaaf7eff4b" - [[package]] name = "windows_x86_64_msvc" version = "0.48.5" @@ -4743,15 +4643,6 @@ version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32b752e52a2da0ddfbdbcc6fceadfeede4c939ed16d13e648833a61dfb611ed8" -[[package]] -name = "winnow" -version = "0.5.40" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" -dependencies = [ - "memchr", -] - [[package]] name = "winnow" version = "0.6.5" @@ -4827,7 +4718,7 @@ checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn", ] [[package]] diff --git a/crates/detect-targets/Cargo.toml b/crates/detect-targets/Cargo.toml index 6066568db..08f40576f 100644 --- a/crates/detect-targets/Cargo.toml +++ b/crates/detect-targets/Cargo.toml @@ -10,9 +10,15 @@ edition = "2021" license = "Apache-2.0 OR MIT" [dependencies] -tokio = { version = "1.35.0", features = ["rt", "process", "sync"], default-features = false } +tokio = { version = "1.35.0", features = [ + "rt", + "process", + "sync", +], default-features = false } tracing = { version = "0.1.39", optional = true } -tracing-subscriber = { version = "0.3.17", features = ["fmt"], default-features = false, optional = true } +tracing-subscriber = { version = "0.3.17", features = [ + "fmt", +], default-features = false, optional = true } cfg-if = "1.0.0" guess_host_triple = "0.1.3" @@ -21,8 +27,12 @@ tracing = ["dep:tracing"] cli-logging = ["tracing", "dep:tracing-subscriber"] [target.'cfg(target_os = "windows")'.dependencies] -windows-sys = { version = "0.52.0", features = ["Win32_System_Threading", "Win32_System_SystemInformation", "Win32_Foundation"] } -windows-dll = { version = "0.4.1", features = ["windows"], default-features = false } +windows-sys = { version = "0.52.0", features = [ + "Win32_System_Threading", + "Win32_System_SystemInformation", + "Win32_Foundation", + "Win32_System_LibraryLoader", +] } [dev-dependencies] tokio = { version = "1.35.0", features = ["macros"], default-features = false } diff --git a/crates/detect-targets/src/detect/windows.rs b/crates/detect-targets/src/detect/windows.rs index e41787960..5e4fe4479 100644 --- a/crates/detect-targets/src/detect/windows.rs +++ b/crates/detect-targets/src/detect/windows.rs @@ -1,46 +1,74 @@ use std::mem; -use windows_dll::dll; -use windows_sys::{ - core::HRESULT, - Win32::System::{ +use windows_sys::Win32::{ + Foundation::{FreeLibrary, HMODULE, S_OK}, + System::{ + LibraryLoader::{GetProcAddress, LoadLibraryA}, SystemInformation::{ IMAGE_FILE_MACHINE, IMAGE_FILE_MACHINE_AMD64, IMAGE_FILE_MACHINE_ARM, IMAGE_FILE_MACHINE_ARM64, IMAGE_FILE_MACHINE_I386, }, - Threading::{UserEnabled, Wow64Container, MACHINE_ATTRIBUTES}, + Threading::{GetMachineTypeAttributes, UserEnabled, Wow64Container, MACHINE_ATTRIBUTES}, }, }; -#[dll("Kernel32")] -extern "system" { - #[allow(non_snake_case)] - #[fallible] - fn GetMachineTypeAttributes( - machine: IMAGE_FILE_MACHINE, - machine_attributes: *mut MACHINE_ATTRIBUTES, - ) -> HRESULT; +struct LibraryHandle(HMODULE); + +impl LibraryHandle { + fn new(name: &[u8]) -> Option { + let handle = unsafe { LoadLibraryA(name.as_ptr() as _) }; + (handle != 0).then(|| Self(handle)) + } + + /// Get a function pointer to a function in the library. + /// # SAFETY + /// + /// The caller must ensure that the function signature matches the actual function. + /// The easiest way to do this is to add an entry to windows_sys_no_link.list and use the + /// generated function for `func_signature`. + /// + /// The function returned cannot be used after the handle is dropped. + unsafe fn get_proc_address(&self, name: &[u8]) -> Option { + let symbol = unsafe { GetProcAddress(self.0, name.as_ptr() as _) }; + symbol.map(|symbol| unsafe { mem::transmute_copy(&symbol) }) + } } -fn is_arch_supported(arch: IMAGE_FILE_MACHINE) -> bool { - let mut machine_attributes = mem::MaybeUninit::uninit(); +impl Drop for LibraryHandle { + fn drop(&mut self) { + unsafe { FreeLibrary(self.0) }; + } +} - // SAFETY: GetMachineTypeAttributes takes type IMAGE_FILE_MACHINE - // plus it takes a pointer to machine_attributes which is only - // written to. - match unsafe { GetMachineTypeAttributes(arch, machine_attributes.as_mut_ptr()) } { - Ok(0) => { - // SAFETY: Symbol GetMachineTypeAttributes exists and calls to it - // succceeds. - // - // Thus, machine_attributes is initialized. - let machine_attributes = unsafe { machine_attributes.assume_init() }; - - (machine_attributes & (Wow64Container | UserEnabled)) != 0 - } - _ => false, +type GetMachineTypeAttributesFuncType = + unsafe extern "system" fn(u16, *mut MACHINE_ATTRIBUTES) -> i32; +const _: () = { + // Ensure that our hand-written signature matches the actual function signature. + // We can't use `GetMachineTypeAttributes` outside of a const scope otherwise we'll end up statically linking to + // it, which will fail to load on older versions of Windows. + let _: GetMachineTypeAttributesFuncType = GetMachineTypeAttributes; +}; + +fn is_arch_supported_inner(arch: IMAGE_FILE_MACHINE) -> Option { + // GetMachineTypeAttributes is only available on Win11 22000+, so dynamically load it. + let kernel32 = LibraryHandle::new(b"kernel32.dll\0")?; + // SAFETY: GetMachineTypeAttributesFuncType is checked to match the real function signature. + let get_machine_type_attributes = unsafe { + kernel32.get_proc_address::(b"GetMachineTypeAttributes\0") + }?; + + let mut machine_attributes = mem::MaybeUninit::uninit(); + if unsafe { get_machine_type_attributes(arch, machine_attributes.as_mut_ptr()) } == S_OK { + let machine_attributes = unsafe { machine_attributes.assume_init() }; + Some((machine_attributes & (Wow64Container | UserEnabled)) != 0) + } else { + Some(false) } } +fn is_arch_supported(arch: IMAGE_FILE_MACHINE) -> bool { + is_arch_supported_inner(arch).unwrap_or(false) +} + pub(super) fn detect_alternative_targets(target: &str) -> impl Iterator { let (prefix, abi) = target .rsplit_once('-')