From 1ebdb6c4e1ee6a544aa1b8609df704dbc94a1e3e Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sun, 7 Jul 2024 22:00:29 +1000 Subject: [PATCH] Regenerate windows sys bindings (#1132) --- dev-tools/gen-windows-sys-binding/Cargo.toml | 1 + dev-tools/gen-windows-sys-binding/src/main.rs | 48 +++++-- src/windows/mod.rs | 2 + src/windows/windows_sys.rs | 130 ++++-------------- src/windows/windows_targets.rs | 19 +++ 5 files changed, 81 insertions(+), 119 deletions(-) create mode 100644 src/windows/windows_targets.rs diff --git a/dev-tools/gen-windows-sys-binding/Cargo.toml b/dev-tools/gen-windows-sys-binding/Cargo.toml index 15446016..12d9f276 100644 --- a/dev-tools/gen-windows-sys-binding/Cargo.toml +++ b/dev-tools/gen-windows-sys-binding/Cargo.toml @@ -7,3 +7,4 @@ publish = false [dependencies] windows-bindgen = "0.58" tempfile = "3" +regex = "1" diff --git a/dev-tools/gen-windows-sys-binding/src/main.rs b/dev-tools/gen-windows-sys-binding/src/main.rs index 245f5af4..ef7c15f3 100644 --- a/dev-tools/gen-windows-sys-binding/src/main.rs +++ b/dev-tools/gen-windows-sys-binding/src/main.rs @@ -3,9 +3,11 @@ use std::{ fs, - io::{self, Read, Write}, + io::{BufWriter, Write as _}, }; +use regex::Regex; + /// This is printed to the file before the rest of the contents. const PRELUDE: &str = r#"// This file is autogenerated. // @@ -14,10 +16,9 @@ const PRELUDE: &str = r#"// This file is autogenerated. // ``` // cd generate-windows-sys/ // cargo run -// ``` -"#; +// ```"#; -fn main() -> io::Result<()> { +fn main() { let manifest_dir = env!("CARGO_MANIFEST_DIR"); let temp_file = tempfile::Builder::new() .suffix(".rs") @@ -50,16 +51,39 @@ fn main() -> io::Result<()> { // Generate bindings. windows_bindgen::bindgen(&args).expect("running bindgen failed"); - let mut bindings = String::new(); - fs::File::open(temp_file.path()) - .expect("failed to open temp windows_sys.rs") - .read_to_string(&mut bindings) - .expect("failed to read temp windows_sys.rs"); + let bindings = + fs::read_to_string(temp_file.path()).expect("failed to read temp windows_sys.rs"); let mut f = fs::File::create(format!("{manifest_dir}/../../src/windows/windows_sys.rs")) + .map(BufWriter::new) .expect("failed to create windows_sys.rs"); - f.write_all(PRELUDE.as_bytes())?; - f.write_all(bindings.as_bytes())?; - Ok(()) + write!(&mut f, "{PRELUDE}\n{bindings}\n").unwrap(); + + let mut dll_names: Vec<&str> = Regex::new(r#"link!\("(.*)\.dll""#) + .unwrap() + .captures_iter(&bindings) + .map(|caps| caps.extract().1) + .map(|[dll_name]| dll_name) + .filter(|dll_name| *dll_name != "kernel32") + .collect(); + + if !dll_names.is_empty() { + dll_names.sort_unstable(); + dll_names.dedup(); + + for dll_name in dll_names { + write!(&mut f, r#"#[link(name = "{dll_name}")]"#).unwrap(); + f.write_all("\n".as_bytes()).unwrap(); + } + + f.write_all(r#"extern "C" {}"#.as_bytes()).unwrap(); + f.write_all("\n".as_bytes()).unwrap(); + } + + f.write_all(r#"use super::windows_targets;"#.as_bytes()) + .unwrap(); + f.write_all("\n".as_bytes()).unwrap(); + + f.into_inner().unwrap().sync_all().unwrap(); } diff --git a/src/windows/mod.rs b/src/windows/mod.rs index 9b6f297e..ccf22b0e 100644 --- a/src/windows/mod.rs +++ b/src/windows/mod.rs @@ -6,6 +6,8 @@ pub mod find_tools; #[cfg(windows)] pub(crate) mod windows_sys; +#[cfg(windows)] +mod windows_targets; #[cfg(windows)] mod registry; diff --git a/src/windows/windows_sys.rs b/src/windows/windows_sys.rs index 80d23ebf..fd177e65 100644 --- a/src/windows/windows_sys.rs +++ b/src/windows/windows_sys.rs @@ -6,7 +6,7 @@ // cd generate-windows-sys/ // cargo run // ``` -// Bindings generated by `windows-bindgen` 0.57.0 +// Bindings generated by `windows-bindgen` 0.58.0 #![allow( non_snake_case, @@ -15,112 +15,22 @@ dead_code, clippy::all )] -#[link(name = "advapi32")] -extern "system" { - pub fn RegCloseKey(hkey: HKEY) -> WIN32_ERROR; -} -#[link(name = "advapi32")] -extern "system" { - pub fn RegEnumKeyExW( - hkey: HKEY, - dwindex: u32, - lpname: PWSTR, - lpcchname: *mut u32, - lpreserved: *const u32, - lpclass: PWSTR, - lpcchclass: *mut u32, - lpftlastwritetime: *mut FILETIME, - ) -> WIN32_ERROR; -} -#[link(name = "advapi32")] -extern "system" { - pub fn RegOpenKeyExW( - hkey: HKEY, - lpsubkey: PCWSTR, - uloptions: u32, - samdesired: REG_SAM_FLAGS, - phkresult: *mut HKEY, - ) -> WIN32_ERROR; -} -#[link(name = "advapi32")] -extern "system" { - pub fn RegQueryValueExW( - hkey: HKEY, - lpvaluename: PCWSTR, - lpreserved: *const u32, - lptype: *mut REG_VALUE_TYPE, - lpdata: *mut u8, - lpcbdata: *mut u32, - ) -> WIN32_ERROR; -} -#[link(name = "kernel32")] -extern "system" { - pub fn FreeLibrary(hlibmodule: HMODULE) -> BOOL; -} -#[link(name = "kernel32")] -extern "system" { - pub fn GetMachineTypeAttributes( - machine: u16, - machinetypeattributes: *mut MACHINE_ATTRIBUTES, - ) -> HRESULT; -} -#[link(name = "kernel32")] -extern "system" { - pub fn GetProcAddress(hmodule: HMODULE, lpprocname: PCSTR) -> FARPROC; -} -#[link(name = "kernel32")] -extern "system" { - pub fn LoadLibraryA(lplibfilename: PCSTR) -> HMODULE; -} -#[link(name = "kernel32")] -extern "system" { - pub fn OpenSemaphoreA(dwdesiredaccess: u32, binherithandle: BOOL, lpname: PCSTR) -> HANDLE; -} -#[link(name = "kernel32")] -extern "system" { - pub fn PeekNamedPipe( - hnamedpipe: HANDLE, - lpbuffer: *mut core::ffi::c_void, - nbuffersize: u32, - lpbytesread: *mut u32, - lptotalbytesavail: *mut u32, - lpbytesleftthismessage: *mut u32, - ) -> BOOL; -} -#[link(name = "kernel32")] -extern "system" { - pub fn ReleaseSemaphore( - hsemaphore: HANDLE, - lreleasecount: i32, - lppreviouscount: *mut i32, - ) -> BOOL; -} -#[link(name = "kernel32")] -extern "system" { - pub fn WaitForSingleObject(hhandle: HANDLE, dwmilliseconds: u32) -> WAIT_EVENT; -} -#[link(name = "ole32")] -extern "system" { - pub fn CoCreateInstance( - rclsid: *const GUID, - punkouter: *mut core::ffi::c_void, - dwclscontext: CLSCTX, - riid: *const GUID, - ppv: *mut *mut core::ffi::c_void, - ) -> HRESULT; -} -#[link(name = "ole32")] -extern "system" { - pub fn CoInitializeEx(pvreserved: *const core::ffi::c_void, dwcoinit: u32) -> HRESULT; -} -#[link(name = "oleaut32")] -extern "system" { - pub fn SysFreeString(bstrstring: BSTR); -} -#[link(name = "oleaut32")] -extern "system" { - pub fn SysStringLen(pbstr: BSTR) -> u32; -} +windows_targets::link!("advapi32.dll" "system" fn RegCloseKey(hkey : HKEY) -> WIN32_ERROR); +windows_targets::link!("advapi32.dll" "system" fn RegEnumKeyExW(hkey : HKEY, dwindex : u32, lpname : PWSTR, lpcchname : *mut u32, lpreserved : *const u32, lpclass : PWSTR, lpcchclass : *mut u32, lpftlastwritetime : *mut FILETIME) -> WIN32_ERROR); +windows_targets::link!("advapi32.dll" "system" fn RegOpenKeyExW(hkey : HKEY, lpsubkey : PCWSTR, uloptions : u32, samdesired : REG_SAM_FLAGS, phkresult : *mut HKEY) -> WIN32_ERROR); +windows_targets::link!("advapi32.dll" "system" fn RegQueryValueExW(hkey : HKEY, lpvaluename : PCWSTR, lpreserved : *const u32, lptype : *mut REG_VALUE_TYPE, lpdata : *mut u8, lpcbdata : *mut u32) -> WIN32_ERROR); +windows_targets::link!("kernel32.dll" "system" fn FreeLibrary(hlibmodule : HMODULE) -> BOOL); +windows_targets::link!("kernel32.dll" "system" fn GetMachineTypeAttributes(machine : u16, machinetypeattributes : *mut MACHINE_ATTRIBUTES) -> HRESULT); +windows_targets::link!("kernel32.dll" "system" fn GetProcAddress(hmodule : HMODULE, lpprocname : PCSTR) -> FARPROC); +windows_targets::link!("kernel32.dll" "system" fn LoadLibraryA(lplibfilename : PCSTR) -> HMODULE); +windows_targets::link!("kernel32.dll" "system" fn OpenSemaphoreA(dwdesiredaccess : u32, binherithandle : BOOL, lpname : PCSTR) -> HANDLE); +windows_targets::link!("kernel32.dll" "system" fn PeekNamedPipe(hnamedpipe : HANDLE, lpbuffer : *mut core::ffi::c_void, nbuffersize : u32, lpbytesread : *mut u32, lptotalbytesavail : *mut u32, lpbytesleftthismessage : *mut u32) -> BOOL); +windows_targets::link!("kernel32.dll" "system" fn ReleaseSemaphore(hsemaphore : HANDLE, lreleasecount : i32, lppreviouscount : *mut i32) -> BOOL); +windows_targets::link!("kernel32.dll" "system" fn WaitForSingleObject(hhandle : HANDLE, dwmilliseconds : u32) -> WAIT_EVENT); +windows_targets::link!("ole32.dll" "system" fn CoCreateInstance(rclsid : *const GUID, punkouter : * mut core::ffi::c_void, dwclscontext : CLSCTX, riid : *const GUID, ppv : *mut *mut core::ffi::c_void) -> HRESULT); +windows_targets::link!("ole32.dll" "system" fn CoInitializeEx(pvreserved : *const core::ffi::c_void, dwcoinit : u32) -> HRESULT); +windows_targets::link!("oleaut32.dll" "system" fn SysFreeString(bstrstring : BSTR)); +windows_targets::link!("oleaut32.dll" "system" fn SysStringLen(pbstr : BSTR) -> u32); pub type ADVANCED_FEATURE_FLAGS = u16; pub type BOOL = i32; pub type BSTR = *const u16; @@ -203,3 +113,9 @@ pub const WAIT_FAILED: WAIT_EVENT = 4294967295u32; pub const WAIT_OBJECT_0: WAIT_EVENT = 0u32; pub const WAIT_TIMEOUT: WAIT_EVENT = 258u32; pub type WIN32_ERROR = u32; + +#[link(name = "advapi32")] +#[link(name = "ole32")] +#[link(name = "oleaut32")] +extern "C" {} +use super::windows_targets; diff --git a/src/windows/windows_targets.rs b/src/windows/windows_targets.rs new file mode 100644 index 00000000..d08affe0 --- /dev/null +++ b/src/windows/windows_targets.rs @@ -0,0 +1,19 @@ +//! Provides the `link!` macro used by the generated windows bindings. +//! +//! This is a simple wrapper around an `extern` block with a `#[link]` attribute. +//! It's very roughly equivalent to the windows-targets crate. + +macro_rules! link_macro { + ($library:literal $abi:literal $($link_name:literal)? $(#[$doc:meta])? fn $($function:tt)*) => ( + // Note: the windows-targets crate uses a pre-built Windows.lib import library which we don't + // have in this repo. So instead we always link kernel32.lib and add the rest of the import + // libraries below by using an empty extern block. This works because extern blocks are not + // connected to the library given in the #[link] attribute. + #[link(name = "kernel32")] + extern $abi { + $(#[link_name=$link_name])? + pub fn $($function)*; + } + ) +} +pub(crate) use link_macro as link;