From 88ff0178fe4e1b357fc8ceb932729753e370da7c Mon Sep 17 00:00:00 2001 From: Melvin Wang Date: Thu, 28 Sep 2023 11:36:36 -0700 Subject: [PATCH 01/20] add _KERNEL_MODE flag to clang parsing --- crates/wdk-build/src/lib.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/crates/wdk-build/src/lib.rs b/crates/wdk-build/src/lib.rs index 64b1a136..e3694f73 100644 --- a/crates/wdk-build/src/lib.rs +++ b/crates/wdk-build/src/lib.rs @@ -536,10 +536,15 @@ impl Config { .chain( match self.driver_config { DriverConfig::Wdm => { - vec![] + vec![ + // This is normally defined by msvc via /kernel flag + "_KERNEL_MODE".to_string(), + ] } DriverConfig::Kmdf(kmdf_config) => { let mut kmdf_definitions = vec![ + // This is normally defined by msvc via /kernel flag + ("_KERNEL_MODE", None), ("KMDF_VERSION_MAJOR", Some(kmdf_config.kmdf_version_major)), ( "KMDF_VERSION_MINOR", From 07f122285a8893a180af76fd9e0e026b5a8009ab Mon Sep 17 00:00:00 2001 From: Melvin Wang Date: Thu, 28 Sep 2023 11:48:52 -0700 Subject: [PATCH 02/20] add initial pass of hid apis Signed-off-by: Melvin Wang --- crates/wdk-sys/build.rs | 40 ++++++++++++++++++++++++++-------- crates/wdk-sys/src/hid-input.h | 16 ++++++++++++++ crates/wdk-sys/src/hid.rs | 14 ++++++++++++ crates/wdk-sys/src/lib.rs | 9 ++++++++ 4 files changed, 70 insertions(+), 9 deletions(-) create mode 100644 crates/wdk-sys/src/hid-input.h create mode 100644 crates/wdk-sys/src/hid.rs diff --git a/crates/wdk-sys/build.rs b/crates/wdk-sys/build.rs index f0b37dd7..c971d917 100644 --- a/crates/wdk-sys/build.rs +++ b/crates/wdk-sys/build.rs @@ -220,18 +220,40 @@ fn generate_types(out_path: &Path, config: &Config) -> Result<(), ConfigError> { .write_to_file(out_path.join("types.rs"))?) } -fn generate_base(out_path: &Path, config: &Config) -> Result<(), ConfigError> { - let outfile_name = match &config.driver_config { - DriverConfig::Wdm | DriverConfig::Kmdf(_) => "ntddk.rs", - DriverConfig::Umdf(_) => "windows.rs", - }; - info!("Generating bindings to WDK: {outfile_name}.rs"); +fn generate_ntddk(out_path: &Path, config: Config) -> Result<(), ConfigError> { + Ok( + bindgen::Builder::wdk_default(vec!["src/ntddk-input.h"], config)? + .with_codegen_config((CodegenConfig::TYPES | CodegenConfig::VARS).complement()) + .generate() + .expect("Bindings should succeed to generate") + .write_to_file(out_path.join("ntddk.rs"))?, + ) +} - Ok(bindgen::Builder::wdk_default(vec!["src/input.h"], config)? - .with_codegen_config((CodegenConfig::TYPES | CodegenConfig::VARS).complement()) +fn generate_hid(out_path: &Path, config: Config) -> Result<(), ConfigError> { + let mut builder = bindgen::Builder::wdk_default(vec!["src/hid-input.h"], config)? + .with_codegen_config((CodegenConfig::TYPES | CodegenConfig::VARS).complement()); + + // Only allowlist files in the hid-specific files declared in hid-input.h to + // avoid duplicate definitions + for header_file in [ + "hidclass.h", + "hidpddi.h", + "hidpi.h", + "hidport.h", + "hidsdi.h", + "hidspicx.h", + "kbdmou.h", + "ntdd8042.h", + "vhf.h", + ] { + builder = builder.allowlist_file(format!(".*{header_file}.*")); + } + + Ok(builder .generate() .expect("Bindings should succeed to generate") - .write_to_file(out_path.join(outfile_name))?) + .write_to_file(out_path.join("hid.rs"))?) } fn generate_wdf(out_path: &Path, config: &Config) -> Result<(), ConfigError> { diff --git a/crates/wdk-sys/src/hid-input.h b/crates/wdk-sys/src/hid-input.h new file mode 100644 index 00000000..86744051 --- /dev/null +++ b/crates/wdk-sys/src/hid-input.h @@ -0,0 +1,16 @@ +/* Copyright (c) Microsoft Corporation + License: MIT OR Apache-2.0 */ + +#include "ntddk.h" + +// FIXME: enable all of these +// Headers list from https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/_hid/ +#include "hidclass.h" +//#include "hidpddi.h" +//#include "hidpi.h" +#include "hidport.h" +#include "hidsdi.h" +//#include "HidSpiCx/1.0/hidspicx.h" +//#include "kbdmou.h" +//#include "ntdd8042.h" +//#include "vhf.h" diff --git a/crates/wdk-sys/src/hid.rs b/crates/wdk-sys/src/hid.rs new file mode 100644 index 00000000..d871fdbd --- /dev/null +++ b/crates/wdk-sys/src/hid.rs @@ -0,0 +1,14 @@ +// Copyright (c) Microsoft Corporation +// License: MIT OR Apache-2.0 + +// #[allow(non_upper_case_globals)] +// #[allow(clippy::unreadable_literal)] +mod bindings { + // allow wildcards for types module since underlying c code relies on all + // type definitions being in scope + #[allow(clippy::wildcard_imports)] + use crate::types::*; + + include!(concat!(env!("OUT_DIR"), "/hid.rs")); +} +pub use bindings::*; diff --git a/crates/wdk-sys/src/lib.rs b/crates/wdk-sys/src/lib.rs index bd76282f..b02d749e 100644 --- a/crates/wdk-sys/src/lib.rs +++ b/crates/wdk-sys/src/lib.rs @@ -23,12 +23,21 @@ pub use crate::{constants::*, types::*}; #[cfg(any(driver_model__driver_type = "WDM", driver_model__driver_type = "KMDF"))] pub mod ntddk; + #[cfg(any(driver_model__driver_type = "KMDF", driver_model__driver_type = "UMDF"))] pub mod wdf; #[cfg(driver_model__driver_type = "UMDF")] pub mod windows; +#[cfg(any( + driver_model__driver_type = "WDM", + driver_model__driver_type = "KMDF", + driver_model__driver_type = "UMDF" +))] +pub mod hid; + + #[cfg(feature = "test-stubs")] pub mod test_stubs; From c52b2f393f2c29783e20d7913830e9067041dfaf Mon Sep 17 00:00:00 2001 From: Melvin Wang Date: Mon, 23 Sep 2024 14:47:43 -0700 Subject: [PATCH 03/20] fix merge conflict --- crates/wdk-build/src/lib.rs | 6 ++---- crates/wdk-sys/build.rs | 29 +++++++++++++++++------------ crates/wdk-sys/src/hid.rs | 2 -- 3 files changed, 19 insertions(+), 18 deletions(-) diff --git a/crates/wdk-build/src/lib.rs b/crates/wdk-build/src/lib.rs index e3694f73..0d33cc7a 100644 --- a/crates/wdk-build/src/lib.rs +++ b/crates/wdk-build/src/lib.rs @@ -537,14 +537,12 @@ impl Config { match self.driver_config { DriverConfig::Wdm => { vec![ - // This is normally defined by msvc via /kernel flag - "_KERNEL_MODE".to_string(), + ("_KERNEL_MODE", None), // Normally defined by msvc via /kernel flag ] } DriverConfig::Kmdf(kmdf_config) => { let mut kmdf_definitions = vec![ - // This is normally defined by msvc via /kernel flag - ("_KERNEL_MODE", None), + ("_KERNEL_MODE", None), // Normally defined by msvc via /kernel flag ("KMDF_VERSION_MAJOR", Some(kmdf_config.kmdf_version_major)), ( "KMDF_VERSION_MINOR", diff --git a/crates/wdk-sys/build.rs b/crates/wdk-sys/build.rs index c971d917..f4e1f946 100644 --- a/crates/wdk-sys/build.rs +++ b/crates/wdk-sys/build.rs @@ -16,19 +16,19 @@ use std::{ use anyhow::Context; use bindgen::CodegenConfig; use lazy_static::lazy_static; -use tracing::{info, info_span, Span}; +use tracing::{Span, info, info_span}; use tracing_subscriber::{ - filter::{LevelFilter, ParseError}, EnvFilter, + filter::{LevelFilter, ParseError}, }; use wdk_build::{ - configure_wdk_library_build_and_then, BuilderExt, Config, ConfigError, DriverConfig, KmdfConfig, UmdfConfig, + configure_wdk_library_build_and_then, }; const NUM_WDF_FUNCTIONS_PLACEHOLDER: &str = @@ -144,6 +144,7 @@ const BINDGEN_FILE_GENERATORS_TUPLES: &[(&str, GenerateFn)] = &[ ("types.rs", generate_types), ("base.rs", generate_base), ("wdf.rs", generate_wdf), + ("hid.rs", generate_hid), ]; fn initialize_tracing() -> Result<(), ParseError> { @@ -220,17 +221,21 @@ fn generate_types(out_path: &Path, config: &Config) -> Result<(), ConfigError> { .write_to_file(out_path.join("types.rs"))?) } -fn generate_ntddk(out_path: &Path, config: Config) -> Result<(), ConfigError> { - Ok( - bindgen::Builder::wdk_default(vec!["src/ntddk-input.h"], config)? - .with_codegen_config((CodegenConfig::TYPES | CodegenConfig::VARS).complement()) - .generate() - .expect("Bindings should succeed to generate") - .write_to_file(out_path.join("ntddk.rs"))?, - ) +fn generate_base(out_path: &Path, config: &Config) -> Result<(), ConfigError> { + let outfile_name = match &config.driver_config { + DriverConfig::Wdm | DriverConfig::Kmdf(_) => "ntddk.rs", + DriverConfig::Umdf(_) => "windows.rs", + }; + info!("Generating bindings to WDK: {outfile_name}.rs"); + + Ok(bindgen::Builder::wdk_default(vec!["src/input.h"], config)? + .with_codegen_config((CodegenConfig::TYPES | CodegenConfig::VARS).complement()) + .generate() + .expect("Bindings should succeed to generate") + .write_to_file(out_path.join(outfile_name))?) } -fn generate_hid(out_path: &Path, config: Config) -> Result<(), ConfigError> { +fn generate_hid(out_path: &Path, config: &Config) -> Result<(), ConfigError> { let mut builder = bindgen::Builder::wdk_default(vec!["src/hid-input.h"], config)? .with_codegen_config((CodegenConfig::TYPES | CodegenConfig::VARS).complement()); diff --git a/crates/wdk-sys/src/hid.rs b/crates/wdk-sys/src/hid.rs index d871fdbd..ba7c4e30 100644 --- a/crates/wdk-sys/src/hid.rs +++ b/crates/wdk-sys/src/hid.rs @@ -1,8 +1,6 @@ // Copyright (c) Microsoft Corporation // License: MIT OR Apache-2.0 -// #[allow(non_upper_case_globals)] -// #[allow(clippy::unreadable_literal)] mod bindings { // allow wildcards for types module since underlying c code relies on all // type definitions being in scope From a1a4bf1a6e05e63ee8f184ff06a36949128316c0 Mon Sep 17 00:00:00 2001 From: Melvin Wang Date: Mon, 14 Oct 2024 23:59:11 -0700 Subject: [PATCH 04/20] refactor wdk_default to not require header files on disk --- crates/wdk-build/src/bindgen.rs | 18 +-- crates/wdk-sys/build.rs | 187 +++++++++++++++++++++++++------- crates/wdk-sys/src/hid-input.h | 16 --- crates/wdk-sys/src/input.h | 72 ------------ crates/wdk-sys/src/wdf.c | 4 - 5 files changed, 151 insertions(+), 146 deletions(-) delete mode 100644 crates/wdk-sys/src/hid-input.h delete mode 100644 crates/wdk-sys/src/input.h delete mode 100644 crates/wdk-sys/src/wdf.c diff --git a/crates/wdk-build/src/bindgen.rs b/crates/wdk-build/src/bindgen.rs index 5609304a..04a6f8d9 100644 --- a/crates/wdk-build/src/bindgen.rs +++ b/crates/wdk-build/src/bindgen.rs @@ -20,10 +20,7 @@ pub trait BuilderExt { /// /// Implementation may return `wdk_build::ConfigError` if it fails to create /// a builder - fn wdk_default( - c_header_files: Vec<&str>, - config: impl Borrow, - ) -> Result; + fn wdk_default(config: impl Borrow) -> Result; } #[derive(Debug)] @@ -39,19 +36,10 @@ impl BuilderExt for Builder { /// /// Will return `wdk_build::ConfigError` if any of the resolved include or /// library paths do not exist - fn wdk_default( - c_header_files: Vec<&str>, - config: impl Borrow, - ) -> Result { + fn wdk_default(config: impl Borrow) -> Result { let config = config.borrow(); - let mut builder = Self::default(); - - for c_header in c_header_files { - builder = builder.header(c_header); - } - - builder = builder + let builder = Self::default() .use_core() // Can't use std for kernel code .derive_default(true) // allows for default initializing structs // CStr types are safer and easier to work with when interacting with string constants diff --git a/crates/wdk-sys/build.rs b/crates/wdk-sys/build.rs index f4e1f946..8f789621 100644 --- a/crates/wdk-sys/build.rs +++ b/crates/wdk-sys/build.rs @@ -7,30 +7,107 @@ //! and generates the relevant bindings to WDK APIs. use std::{ - env, - io::Write, - path::{Path, PathBuf}, - thread, + env, fs::File, io::Write, path::{Path, PathBuf}, thread }; use anyhow::Context; use bindgen::CodegenConfig; use lazy_static::lazy_static; -use tracing::{Span, info, info_span}; +use tracing::{info, info_span, Span}; use tracing_subscriber::{ - EnvFilter, filter::{LevelFilter, ParseError}, + EnvFilter, }; use wdk_build::{ + configure_wdk_library_build_and_then, BuilderExt, Config, ConfigError, DriverConfig, KmdfConfig, UmdfConfig, - configure_wdk_library_build_and_then, }; +const BASE_INPUT_HEADER_FILE_CONTENTS: &str = r#" +#if defined(UMDF_VERSION_MAJOR) + +#include "windows.h" + +#else // !defined(UMDF_VERSION_MAJOR) + +#include "ntifs.h" +#include "ntddk.h" + +// FIXME: Why is there no definition for this struct? Maybe blocklist this struct in bindgen. +typedef union _KGDTENTRY64 +{ + struct + { + unsigned short LimitLow; + unsigned short BaseLow; + union + { + struct + { + unsigned char BaseMiddle; + unsigned char Flags1; + unsigned char Flags2; + unsigned char BaseHigh; + } Bytes; + struct + { + unsigned long BaseMiddle : 8; + unsigned long Type : 5; + unsigned long Dpl : 2; + unsigned long Present : 1; + unsigned long LimitHigh : 4; + unsigned long System : 1; + unsigned long LongMode : 1; + unsigned long DefaultBig : 1; + unsigned long Granularity : 1; + unsigned long BaseHigh : 8; + } Bits; + }; + unsigned long BaseUpper; + unsigned long MustBeZero; + }; + unsigned __int64 Alignment; +} KGDTENTRY64, *PKGDTENTRY64; + +typedef union _KIDTENTRY64 +{ + struct + { + unsigned short OffsetLow; + unsigned short Selector; + unsigned short IstIndex : 3; + unsigned short Reserved0 : 5; + unsigned short Type : 5; + unsigned short Dpl : 2; + unsigned short Present : 1; + unsigned short OffsetMiddle; + unsigned long OffsetHigh; + unsigned long Reserved1; + }; + unsigned __int64 Alignment; +} KIDTENTRY64, *PKIDTENTRY64; +#endif // !defined(UMDF_VERSION_MAJOR) +"#; + +const WDF_INPUT_HEADER_CONTENTS: &str = r#" +#include "wdf.h" +"#; + +// HID Headers list from https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/_hid/ +const HID_BASE_HEADERS: &[&str] = &["hidclass.h", "hidpi.h", "hidsdi.h", "vhf.h"]; +const HID_KERNEL_MODE_HEADERS: &[&str] = &[ + "hidpddi.h", + "hidport.h", + "HidSpiCx/1.0/hidspicx.h", + "kbdmou.h", + "ntdd8042.h", +]; + const NUM_WDF_FUNCTIONS_PLACEHOLDER: &str = ""; const WDF_FUNCTION_COUNT_DECLARATION_PLACEHOLDER: &str = @@ -39,11 +116,25 @@ const OUT_DIR_PLACEHOLDER: &str = ""; const WDFFUNCTIONS_SYMBOL_NAME_PLACEHOLDER: &str = ""; +const HID_BASE_HEADER_INCLUDES_PLACEHOLDER: &str = + ""; +const HID_KERNEL_MODE_HEADER_INCLUDES_PLACEHOLDER: &str = + ""; +/// Rust code snippet that declares and initializes wdf_function_count based off +/// the bindgen-generated `WdfFunctionCount` symbol +/// +/// This is only used in configurations where WDF generates a +/// `WdfFunctionCount`. const WDF_FUNCTION_COUNT_DECLARATION_EXTERNAL_SYMBOL: &str = " // SAFETY: `crate::WdfFunctionCount` is generated as a mutable static, but is not supposed \ to be ever mutated by WDF. let wdf_function_count = unsafe { crate::WdfFunctionCount } as usize;"; +/// Rust code snippet that declares and initializes wdf_function_count based off +/// the bindgen-generated `WdfFunctionTableNumEntries` constant +/// +/// This is only used in older WDF versions that didn't generate a +/// `WdfFunctionCount` symbol const WDF_FUNCTION_COUNT_DECLARATION_TABLE_INDEX: &str = " let wdf_function_count = crate::_WDFFUNCENUM::WdfFunctionTableNumEntries as usize;"; @@ -133,7 +224,16 @@ use crate::WDFFUNC; /// Stubbed version of the symbol that [`WdfFunctions`] links to so that test targets will compile #[no_mangle] pub static mut {WDFFUNCTIONS_SYMBOL_NAME_PLACEHOLDER}: *const WDFFUNC = core::ptr::null(); -"#, +"# + ); + static ref HID_INPUT_HEADER_CONTENTS_TEMPLATE: String = format!( + r#" +{HID_BASE_HEADER_INCLUDES_PLACEHOLDER} + +#if defined(_KERNEL_MODE) +{HID_KERNEL_MODE_HEADER_INCLUDES_PLACEHOLDER} +#endif // defined(_KERNEL_MODE) +"# ); } @@ -144,7 +244,7 @@ const BINDGEN_FILE_GENERATORS_TUPLES: &[(&str, GenerateFn)] = &[ ("types.rs", generate_types), ("base.rs", generate_base), ("wdf.rs", generate_wdf), - ("hid.rs", generate_hid), + // ("hid.rs", generate_hid), ]; fn initialize_tracing() -> Result<(), ParseError> { @@ -204,7 +304,9 @@ fn initialize_tracing() -> Result<(), ParseError> { fn generate_constants(out_path: &Path, config: &Config) -> Result<(), ConfigError> { info!("Generating bindings to WDK: constants.rs"); - Ok(bindgen::Builder::wdk_default(vec!["src/input.h"], config)? + Ok(bindgen::Builder::wdk_default(config)? + .header_contents("base", BASE_INPUT_HEADER_FILE_CONTENTS) + .header_contents("wdf", WDF_INPUT_HEADER_CONTENTS) .with_codegen_config(CodegenConfig::VARS) .generate() .expect("Bindings should succeed to generate") @@ -214,7 +316,9 @@ fn generate_constants(out_path: &Path, config: &Config) -> Result<(), ConfigErro fn generate_types(out_path: &Path, config: &Config) -> Result<(), ConfigError> { info!("Generating bindings to WDK: types.rs"); - Ok(bindgen::Builder::wdk_default(vec!["src/input.h"], config)? + Ok(bindgen::Builder::wdk_default(config)? + .header_contents("base", BASE_INPUT_HEADER_FILE_CONTENTS) + .header_contents("wdf", WDF_INPUT_HEADER_CONTENTS) .with_codegen_config(CodegenConfig::TYPES) .generate() .expect("Bindings should succeed to generate") @@ -228,38 +332,34 @@ fn generate_base(out_path: &Path, config: &Config) -> Result<(), ConfigError> { }; info!("Generating bindings to WDK: {outfile_name}.rs"); - Ok(bindgen::Builder::wdk_default(vec!["src/input.h"], config)? + Ok(bindgen::Builder::wdk_default(config)? + .header_contents("base", BASE_INPUT_HEADER_FILE_CONTENTS) + .header_contents("wdf", WDF_INPUT_HEADER_CONTENTS) .with_codegen_config((CodegenConfig::TYPES | CodegenConfig::VARS).complement()) .generate() .expect("Bindings should succeed to generate") .write_to_file(out_path.join(outfile_name))?) } -fn generate_hid(out_path: &Path, config: &Config) -> Result<(), ConfigError> { - let mut builder = bindgen::Builder::wdk_default(vec!["src/hid-input.h"], config)? - .with_codegen_config((CodegenConfig::TYPES | CodegenConfig::VARS).complement()); - - // Only allowlist files in the hid-specific files declared in hid-input.h to - // avoid duplicate definitions - for header_file in [ - "hidclass.h", - "hidpddi.h", - "hidpi.h", - "hidport.h", - "hidsdi.h", - "hidspicx.h", - "kbdmou.h", - "ntdd8042.h", - "vhf.h", - ] { - builder = builder.allowlist_file(format!(".*{header_file}.*")); - } - - Ok(builder - .generate() - .expect("Bindings should succeed to generate") - .write_to_file(out_path.join("hid.rs"))?) -} +// fn generate_hid(out_path: &Path, config: &Config) -> Result<(), ConfigError> +// { let mut builder = bindgen::Builder::wdk_default(config)? +// .with_codegen_config((CodegenConfig::TYPES | +// CodegenConfig::VARS).complement()); + +// // Only allowlist files in the hid-specific files declared in hid-input.h +// to // avoid duplicate definitions +// for header_file in HID_BASE_HEADERS +// .iter() +// .chain(HID_KERNEL_MODE_HEADERS.iter()) +// { +// builder = builder.allowlist_file(format!(".*{header_file}.*")); +// } + +// Ok(builder +// .generate() +// .expect("Bindings should succeed to generate") +// .write_to_file(out_path.join("hid.rs"))?) +// } fn generate_wdf(out_path: &Path, config: &Config) -> Result<(), ConfigError> { if let DriverConfig::Kmdf(_) | DriverConfig::Umdf(_) = &config.driver_config { @@ -269,7 +369,9 @@ fn generate_wdf(out_path: &Path, config: &Config) -> Result<(), ConfigError> { // items in the wdf headers(i.e. functions are all inlined). This step is // intentionally left here in case older/newer WDKs have non-inlined functions // or new WDKs may introduce non-inlined functions. - Ok(bindgen::Builder::wdk_default(vec!["src/input.h"], config)? + Ok(bindgen::Builder::wdk_default(config)? + .header_contents("base", BASE_INPUT_HEADER_FILE_CONTENTS) + .header_contents("wdf", WDF_INPUT_HEADER_CONTENTS) .with_codegen_config((CodegenConfig::TYPES | CodegenConfig::VARS).complement()) // Only generate for files that are prefixed with (case-insensitive) wdf (ie. // /some/path/WdfSomeHeader.h), to prevent duplication of code in ntddk.rs @@ -439,6 +541,13 @@ fn main() -> anyhow::Result<()> { // Parent span must be manually set since spans do not persist across thread boundaries: https://github.com/tokio-rs/tracing/issues/1391 info_span!(parent: current_span, "cc").in_scope(|| { info!("Compiling wdf.c"); + + // Write all included headers into wdf.c + let wdf_c_file_path = out_path.join("wdf.c"); + let mut wdf_c_file = File::create_new(&wdf_c_file_path)?; + wdf_c_file.write_all(BASE_INPUT_HEADER_FILE_CONTENTS.as_bytes())?; + wdf_c_file.write_all(WDF_INPUT_HEADER_CONTENTS.as_bytes())?; + let mut cc_builder = cc::Build::new(); for (key, value) in config.get_preprocessor_definitions_iter() { cc_builder.define(&key, value.as_deref()); @@ -446,7 +555,7 @@ fn main() -> anyhow::Result<()> { cc_builder .includes(config.get_include_paths()?) - .file("src/wdf.c") + .file(wdf_c_file_path) .compile("wdf"); Ok::<(), ConfigError>(()) }) diff --git a/crates/wdk-sys/src/hid-input.h b/crates/wdk-sys/src/hid-input.h deleted file mode 100644 index 86744051..00000000 --- a/crates/wdk-sys/src/hid-input.h +++ /dev/null @@ -1,16 +0,0 @@ -/* Copyright (c) Microsoft Corporation - License: MIT OR Apache-2.0 */ - -#include "ntddk.h" - -// FIXME: enable all of these -// Headers list from https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/_hid/ -#include "hidclass.h" -//#include "hidpddi.h" -//#include "hidpi.h" -#include "hidport.h" -#include "hidsdi.h" -//#include "HidSpiCx/1.0/hidspicx.h" -//#include "kbdmou.h" -//#include "ntdd8042.h" -//#include "vhf.h" diff --git a/crates/wdk-sys/src/input.h b/crates/wdk-sys/src/input.h deleted file mode 100644 index dec71ce3..00000000 --- a/crates/wdk-sys/src/input.h +++ /dev/null @@ -1,72 +0,0 @@ -/* Copyright (c) Microsoft Corporation - License: MIT OR Apache-2.0 */ - -#if defined(UMDF_VERSION_MAJOR) - -#include - -#else // !defined(UMDF_VERSION_MAJOR) - -#include "ntifs.h" -#include "ntddk.h" - -// FIXME: Why is there no definition for this struct? Maybe blocklist this struct in bindgen. -typedef union _KGDTENTRY64 -{ - struct - { - unsigned short LimitLow; - unsigned short BaseLow; - union - { - struct - { - unsigned char BaseMiddle; - unsigned char Flags1; - unsigned char Flags2; - unsigned char BaseHigh; - } Bytes; - struct - { - unsigned long BaseMiddle : 8; - unsigned long Type : 5; - unsigned long Dpl : 2; - unsigned long Present : 1; - unsigned long LimitHigh : 4; - unsigned long System : 1; - unsigned long LongMode : 1; - unsigned long DefaultBig : 1; - unsigned long Granularity : 1; - unsigned long BaseHigh : 8; - } Bits; - }; - unsigned long BaseUpper; - unsigned long MustBeZero; - }; - unsigned __int64 Alignment; -} KGDTENTRY64, *PKGDTENTRY64; - -typedef union _KIDTENTRY64 -{ - struct - { - unsigned short OffsetLow; - unsigned short Selector; - unsigned short IstIndex : 3; - unsigned short Reserved0 : 5; - unsigned short Type : 5; - unsigned short Dpl : 2; - unsigned short Present : 1; - unsigned short OffsetMiddle; - unsigned long OffsetHigh; - unsigned long Reserved1; - }; - unsigned __int64 Alignment; -} KIDTENTRY64, *PKIDTENTRY64; -#endif // !defined(UMDF_VERSION_MAJOR) - -#if defined(KMDF_VERSION_MAJOR) || defined(UMDF_VERSION_MAJOR) - -#include - -#endif // defined(KMDF_VERSION_MAJOR) || defined(UMDF_VERSION_MAJOR) diff --git a/crates/wdk-sys/src/wdf.c b/crates/wdk-sys/src/wdf.c deleted file mode 100644 index 37275965..00000000 --- a/crates/wdk-sys/src/wdf.c +++ /dev/null @@ -1,4 +0,0 @@ -/* Copyright (c) Microsoft Corporation - License: MIT OR Apache-2.0 */ - -#include "input.h" From 5a939957f0858d8f2b66cf4e6f42c82f286bb969 Mon Sep 17 00:00:00 2001 From: Melvin Wang Date: Fri, 10 Jan 2025 14:31:18 -0800 Subject: [PATCH 05/20] refactor to have a single header for bindgen to process --- .vscode/settings.json | 3 +- Cargo.lock | 23 +- Cargo.toml | 2 +- crates/wdk-build/Cargo.toml | 5 + crates/wdk-build/src/lib.rs | 133 ++++++- crates/wdk-sys/Cargo.toml | 4 + crates/wdk-sys/build.rs | 330 +++++++++--------- crates/wdk-sys/src/hid.rs | 13 + crates/wdk-sys/src/lib.rs | 12 +- examples/sample-kmdf-driver/Cargo.lock | 23 +- examples/sample-kmdf-driver/Cargo.toml | 3 + examples/sample-umdf-driver/Cargo.lock | 23 +- examples/sample-umdf-driver/Cargo.toml | 3 + examples/sample-wdm-driver/Cargo.lock | 23 +- examples/sample-wdm-driver/Cargo.toml | 3 + tests/config-kmdf/Cargo.lock | 23 +- tests/config-umdf/Cargo.lock | 23 +- tests/mixed-package-kmdf-workspace/Cargo.lock | 23 +- .../crates/driver/src/lib.rs | 1 + tests/umdf-driver-workspace/Cargo.lock | 23 +- tests/wdk-sys-tests/Cargo.lock | 23 +- 21 files changed, 455 insertions(+), 264 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 38e5522c..138d12e0 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -19,5 +19,6 @@ "./tests/umdf-driver-workspace/Cargo.toml", "./tests/wdk-macros-tests/Cargo.toml", "./tests/wdk-sys-tests/Cargo.toml", - ] + ], + "rust-analyzer.cargo.features": "all" } \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock index 7d521a67..9bface0a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,6 +1,6 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 +version = 4 [[package]] name = "aho-corasick" @@ -68,9 +68,9 @@ checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" [[package]] name = "bindgen" -version = "0.69.4" +version = "0.69.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a00dc851838a2120612785d195287475a3ac45514741da670b735818822129a0" +checksum = "271383c67ccabffb7381723dea0672a673f292304fcb45c01cc648c7a8d58088" dependencies = [ "bitflags", "cexpr", @@ -626,9 +626,9 @@ dependencies = [ [[package]] name = "tracing" -version = "0.1.40" +version = "0.1.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" +checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" dependencies = [ "pin-project-lite", "tracing-attributes", @@ -637,9 +637,9 @@ dependencies = [ [[package]] name = "tracing-attributes" -version = "0.1.27" +version = "0.1.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" +checksum = "395ae124c09f9e6918a2310af6038fba074bcf474ac352496d5910dd59a2226d" dependencies = [ "proc-macro2", "quote", @@ -648,9 +648,9 @@ dependencies = [ [[package]] name = "tracing-core" -version = "0.1.32" +version = "0.1.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +checksum = "e672c95779cf947c5311f83787af4fa8fffd12fb27e4993211a84bdfd9610f9c" dependencies = [ "once_cell", "valuable", @@ -669,9 +669,9 @@ dependencies = [ [[package]] name = "tracing-subscriber" -version = "0.3.18" +version = "0.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" +checksum = "e8189decb5ac0fa7bc8b96b7cb9b2701d60d48805aca84a238004d665fcc4008" dependencies = [ "matchers", "nu-ansi-term", @@ -767,6 +767,7 @@ dependencies = [ "bindgen", "cargo_metadata", "cc", + "cfg-if", "lazy_static", "rustversion", "serde_json", diff --git a/Cargo.toml b/Cargo.toml index 8254e142..5f57bde5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -37,7 +37,7 @@ wdk-sys = { path = "crates/wdk-sys", version = "0.3.0" } # External Crates anyhow = "1.0.86" -bindgen = "0.69.4" +bindgen = "0.69.5" camino = "1.1.9" cargo_metadata = "0.18.1" cc = "1.1.0" diff --git a/crates/wdk-build/Cargo.toml b/crates/wdk-build/Cargo.toml index ad92f32f..4f12dd50 100644 --- a/crates/wdk-build/Cargo.toml +++ b/crates/wdk-build/Cargo.toml @@ -35,6 +35,11 @@ windows = { workspace = true, features = [ [dev-dependencies] windows = { workspace = true, features = ["Win32_UI_Shell"] } +[features] +default = [] + +hid = [] + [lints.rust.unexpected_cfgs] level = "warn" check-cfg = ["cfg(wdk_build_unstable)", "cfg(skip_umdf_static_crt_check)"] diff --git a/crates/wdk-build/src/lib.rs b/crates/wdk-build/src/lib.rs index c7b1161b..1d9d1230 100644 --- a/crates/wdk-build/src/lib.rs +++ b/crates/wdk-build/src/lib.rs @@ -313,6 +313,7 @@ impl Config { Ok(()) } + // TODO: deprecate in favor of include_paths() /// Return header include paths required to build and link based off of the /// configuration of `Config` /// @@ -411,6 +412,7 @@ impl Config { Ok(include_paths) } + // TODO: deprecate in favor of library_paths() /// Return library include paths required to build and link based off of /// the configuration of [`Config`]. /// @@ -498,6 +500,7 @@ impl Config { Ok(library_paths) } + // TODO: Deprecate in favor of preprocessor_definitions_iter /// Return an iterator of strings that represent compiler definitions /// derived from the `Config` pub fn get_preprocessor_definitions_iter( @@ -626,6 +629,134 @@ impl Config { .map(std::string::ToString::to_string) } + pub fn base_headers(&self) -> impl Iterator { + match &self.driver_config { + DriverConfig::Wdm | DriverConfig::Kmdf(_) => { + vec!["ntifs.h", "ntddk.h"] + } + DriverConfig::Umdf(_) => { + vec!["windows.h"] + } + } + .into_iter() + .map(std::string::ToString::to_string) + } + + pub fn wdf_headers(&self) -> impl Iterator { + ["wdf.h"].into_iter().map(std::string::ToString::to_string) + } + + #[cfg(feature = "hid")] + pub fn hid_headers(&self) -> impl Iterator { + // HID Headers list from https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/_hid/ + { + let mut hid_headers = vec!["hidclass.h", "hidsdi.h", "hidpi.h", "vhf.h"]; + if let DriverConfig::Wdm | DriverConfig::Kmdf(_) = self.driver_config { + hid_headers.extend(["hidpddi.h", "hidport.h", "kbdmou.h", "ntdd8042.h"]); + } + if let DriverConfig::Kmdf(_) = self.driver_config { + hid_headers.extend(["HidSpiCx/1.0/hidspicx.h"]); + } + hid_headers + } + .into_iter() + .map(std::string::ToString::to_string) + } + + pub fn bindgen_base_header_contents(&self) -> String { + let mut header_contents = self.base_headers().fold(String::new(), |mut acc, header| { + acc.push_str(r#"#include ""#); + acc.push_str(&header); + acc.push_str("\"\n"); + acc + }); + + if let DriverConfig::Wdm | DriverConfig::Kmdf(_) = self.driver_config { + // TODO: Why is there no definition for this struct? Maybe blocklist this struct + // in bindgen. + header_contents.push_str( + r" +typedef union _KGDTENTRY64 +{ + struct + { + unsigned short LimitLow; + unsigned short BaseLow; + union + { + struct + { + unsigned char BaseMiddle; + unsigned char Flags1; + unsigned char Flags2; + unsigned char BaseHigh; + } Bytes; + struct + { + unsigned long BaseMiddle : 8; + unsigned long Type : 5; + unsigned long Dpl : 2; + unsigned long Present : 1; + unsigned long LimitHigh : 4; + unsigned long System : 1; + unsigned long LongMode : 1; + unsigned long DefaultBig : 1; + unsigned long Granularity : 1; + unsigned long BaseHigh : 8; + } Bits; + }; + unsigned long BaseUpper; + unsigned long MustBeZero; + }; + unsigned __int64 Alignment; +} KGDTENTRY64, *PKGDTENTRY64; + +typedef union _KIDTENTRY64 +{ + struct + { + unsigned short OffsetLow; + unsigned short Selector; + unsigned short IstIndex : 3; + unsigned short Reserved0 : 5; + unsigned short Type : 5; + unsigned short Dpl : 2; + unsigned short Present : 1; + unsigned short OffsetMiddle; + unsigned long OffsetHigh; + unsigned long Reserved1; + }; + unsigned __int64 Alignment; +} KIDTENTRY64, *PKIDTENTRY64; +", + ); + } + + header_contents + } + + pub fn bindgen_wdf_header_contents(&self) -> Option { + if let DriverConfig::Kmdf(_) | DriverConfig::Umdf(_) = self.driver_config { + return Some(self.wdf_headers().fold(String::new(), |mut acc, header| { + acc.push_str(r#"#include ""#); + acc.push_str(&header); + acc.push_str("\"\n"); + acc + })); + } + None + } + + #[cfg(feature = "hid")] + pub fn bindgen_hid_header_contents(&self) -> String { + self.hid_headers().fold(String::new(), |mut acc, header| { + acc.push_str(r#"#include ""#); + acc.push_str(&header); + acc.push_str("\"\n"); + acc + }) + } + /// Configure a Cargo build of a library that depends on the WDK. This /// emits specially formatted prints to Cargo based on this [`Config`]. /// @@ -842,8 +973,6 @@ impl CpuArchitecture { } /// Converts from a cargo-provided [`std::str`] to a [`CpuArchitecture`]. - /// - /// # #[must_use] pub fn try_from_cargo_str>(cargo_str: S) -> Option { // Specifically not using the [`std::convert::TryFrom`] trait to be more diff --git a/crates/wdk-sys/Cargo.toml b/crates/wdk-sys/Cargo.toml index d1de5c29..f76caef2 100644 --- a/crates/wdk-sys/Cargo.toml +++ b/crates/wdk-sys/Cargo.toml @@ -21,6 +21,7 @@ anyhow.workspace = true bindgen.workspace = true cargo_metadata.workspace = true cc.workspace = true +cfg-if.workspace = true lazy_static.workspace = true serde_json.workspace = true thiserror.workspace = true @@ -35,6 +36,9 @@ wdk-macros.workspace = true [features] default = [] + +hid = ["wdk-build/hid"] + nightly = ["wdk-macros/nightly"] test-stubs = [] diff --git a/crates/wdk-sys/build.rs b/crates/wdk-sys/build.rs index 2cab476c..d78c90a3 100644 --- a/crates/wdk-sys/build.rs +++ b/crates/wdk-sys/build.rs @@ -7,13 +7,18 @@ //! and generates the relevant bindings to WDK APIs. use std::{ - env, fs::File, io::Write, path::{Path, PathBuf}, thread + env, + fs::File, + io::Write, + panic, + path::{Path, PathBuf}, + thread, }; use anyhow::Context; use bindgen::CodegenConfig; use lazy_static::lazy_static; -use tracing::{info, info_span, Span}; +use tracing::{info, info_span, trace, Span}; use tracing_subscriber::{ filter::{LevelFilter, ParseError}, EnvFilter, @@ -28,86 +33,6 @@ use wdk_build::{ UmdfConfig, }; -const BASE_INPUT_HEADER_FILE_CONTENTS: &str = r#" -#if defined(UMDF_VERSION_MAJOR) - -#include "windows.h" - -#else // !defined(UMDF_VERSION_MAJOR) - -#include "ntifs.h" -#include "ntddk.h" - -// FIXME: Why is there no definition for this struct? Maybe blocklist this struct in bindgen. -typedef union _KGDTENTRY64 -{ - struct - { - unsigned short LimitLow; - unsigned short BaseLow; - union - { - struct - { - unsigned char BaseMiddle; - unsigned char Flags1; - unsigned char Flags2; - unsigned char BaseHigh; - } Bytes; - struct - { - unsigned long BaseMiddle : 8; - unsigned long Type : 5; - unsigned long Dpl : 2; - unsigned long Present : 1; - unsigned long LimitHigh : 4; - unsigned long System : 1; - unsigned long LongMode : 1; - unsigned long DefaultBig : 1; - unsigned long Granularity : 1; - unsigned long BaseHigh : 8; - } Bits; - }; - unsigned long BaseUpper; - unsigned long MustBeZero; - }; - unsigned __int64 Alignment; -} KGDTENTRY64, *PKGDTENTRY64; - -typedef union _KIDTENTRY64 -{ - struct - { - unsigned short OffsetLow; - unsigned short Selector; - unsigned short IstIndex : 3; - unsigned short Reserved0 : 5; - unsigned short Type : 5; - unsigned short Dpl : 2; - unsigned short Present : 1; - unsigned short OffsetMiddle; - unsigned long OffsetHigh; - unsigned long Reserved1; - }; - unsigned __int64 Alignment; -} KIDTENTRY64, *PKIDTENTRY64; -#endif // !defined(UMDF_VERSION_MAJOR) -"#; - -const WDF_INPUT_HEADER_CONTENTS: &str = r#" -#include "wdf.h" -"#; - -// HID Headers list from https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/_hid/ -const HID_BASE_HEADERS: &[&str] = &["hidclass.h", "hidpi.h", "hidsdi.h", "vhf.h"]; -const HID_KERNEL_MODE_HEADERS: &[&str] = &[ - "hidpddi.h", - "hidport.h", - "HidSpiCx/1.0/hidspicx.h", - "kbdmou.h", - "ntdd8042.h", -]; - const NUM_WDF_FUNCTIONS_PLACEHOLDER: &str = ""; const WDF_FUNCTION_COUNT_DECLARATION_PLACEHOLDER: &str = @@ -116,13 +41,9 @@ const OUT_DIR_PLACEHOLDER: &str = ""; const WDFFUNCTIONS_SYMBOL_NAME_PLACEHOLDER: &str = ""; -const HID_BASE_HEADER_INCLUDES_PLACEHOLDER: &str = - ""; -const HID_KERNEL_MODE_HEADER_INCLUDES_PLACEHOLDER: &str = - ""; -/// Rust code snippet that declares and initializes wdf_function_count based off -/// the bindgen-generated `WdfFunctionCount` symbol +/// Rust code snippet that declares and initializes `wdf_function_count` based +/// off the bindgen-generated `WdfFunctionCount` symbol /// /// This is only used in configurations where WDF generates a /// `WdfFunctionCount`. @@ -130,8 +51,8 @@ const WDF_FUNCTION_COUNT_DECLARATION_EXTERNAL_SYMBOL: &str = " // SAFETY: `crate::WdfFunctionCount` is generated as a mutable static, but is not supposed \ to be ever mutated by WDF. let wdf_function_count = unsafe { crate::WdfFunctionCount } as usize;"; -/// Rust code snippet that declares and initializes wdf_function_count based off -/// the bindgen-generated `WdfFunctionTableNumEntries` constant +/// Rust code snippet that declares and initializes `wdf_function_count` based +/// off the bindgen-generated `WdfFunctionTableNumEntries` constant /// /// This is only used in older WDF versions that didn't generate a /// `WdfFunctionCount` symbol @@ -224,15 +145,6 @@ use crate::WDFFUNC; /// Stubbed version of the symbol that [`WdfFunctions`] links to so that test targets will compile #[no_mangle] pub static mut {WDFFUNCTIONS_SYMBOL_NAME_PLACEHOLDER}: *const WDFFUNC = core::ptr::null(); -" - ); - static ref HID_INPUT_HEADER_CONTENTS_TEMPLATE: String = format!( - r" -{HID_BASE_HEADER_INCLUDES_PLACEHOLDER} - -#if defined(_KERNEL_MODE) -{HID_KERNEL_MODE_HEADER_INCLUDES_PLACEHOLDER} -#endif // defined(_KERNEL_MODE) " ); } @@ -240,11 +152,12 @@ pub static mut {WDFFUNCTIONS_SYMBOL_NAME_PLACEHOLDER}: *const WDFFUNC = core::pt type GenerateFn = fn(&Path, &Config) -> Result<(), ConfigError>; const BINDGEN_FILE_GENERATORS_TUPLES: &[(&str, GenerateFn)] = &[ + // TODO: rename all references of constants to constant and variables ("constants.rs", generate_constants), ("types.rs", generate_types), ("base.rs", generate_base), ("wdf.rs", generate_wdf), - // ("hid.rs", generate_hid), + ("hid.rs", generate_hid), ]; fn initialize_tracing() -> Result<(), ParseError> { @@ -304,10 +217,29 @@ fn initialize_tracing() -> Result<(), ParseError> { fn generate_constants(out_path: &Path, config: &Config) -> Result<(), ConfigError> { info!("Generating bindings to WDK: constants.rs"); - Ok(bindgen::Builder::wdk_default(config)? - .header_contents("base", BASE_INPUT_HEADER_FILE_CONTENTS) - .header_contents("wdf", WDF_INPUT_HEADER_CONTENTS) + let header_contents = { + let mut contents = config.bindgen_base_header_contents(); + + if let Some(wdf_header_contents) = config.bindgen_wdf_header_contents() { + contents.push_str(&wdf_header_contents); + } + + #[cfg(feature = "hid")] + if env::var("CARGO_FEATURE_HID").is_ok() { + // TODO: this check can be removed? + contents.push_str(&config.bindgen_hid_header_contents()); + }; + + contents + }; + trace!(header_contents = ?header_contents); + + let bindgen_builder = bindgen::Builder::wdk_default(config)? .with_codegen_config(CodegenConfig::VARS) + .header_contents("constants-input.h", &header_contents); + trace!(bindgen_builder = ?bindgen_builder); + + Ok(bindgen_builder .generate() .expect("Bindings should succeed to generate") .write_to_file(out_path.join("constants.rs"))?) @@ -316,10 +248,28 @@ fn generate_constants(out_path: &Path, config: &Config) -> Result<(), ConfigErro fn generate_types(out_path: &Path, config: &Config) -> Result<(), ConfigError> { info!("Generating bindings to WDK: types.rs"); - Ok(bindgen::Builder::wdk_default(config)? - .header_contents("base", BASE_INPUT_HEADER_FILE_CONTENTS) - .header_contents("wdf", WDF_INPUT_HEADER_CONTENTS) + let header_contents = { + let mut contents = config.bindgen_base_header_contents(); + + if let Some(wdf_header_contents) = config.bindgen_wdf_header_contents() { + contents.push_str(&wdf_header_contents); + } + + #[cfg(feature = "hid")] + if env::var("CARGO_FEATURE_HID").is_ok() { + contents.push_str(&config.bindgen_hid_header_contents()); + }; + + contents + }; + trace!(header_contents = ?header_contents); + + let bindgen_builder = bindgen::Builder::wdk_default(config)? .with_codegen_config(CodegenConfig::TYPES) + .header_contents("types-input.h", &header_contents); + trace!(bindgen_builder = ?bindgen_builder); + + Ok(bindgen_builder .generate() .expect("Bindings should succeed to generate") .write_to_file(out_path.join("types.rs"))?) @@ -327,55 +277,49 @@ fn generate_types(out_path: &Path, config: &Config) -> Result<(), ConfigError> { fn generate_base(out_path: &Path, config: &Config) -> Result<(), ConfigError> { let outfile_name = match &config.driver_config { - DriverConfig::Wdm | DriverConfig::Kmdf(_) => "ntddk.rs", - DriverConfig::Umdf(_) => "windows.rs", + DriverConfig::Wdm | DriverConfig::Kmdf(_) => "ntddk", + DriverConfig::Umdf(_) => "windows", }; info!("Generating bindings to WDK: {outfile_name}.rs"); - Ok(bindgen::Builder::wdk_default(config)? - .header_contents("base", BASE_INPUT_HEADER_FILE_CONTENTS) - .header_contents("wdf", WDF_INPUT_HEADER_CONTENTS) + let header_contents = config.bindgen_base_header_contents(); + trace!(header_contents = ?header_contents); + + let bindgen_builder = bindgen::Builder::wdk_default(config)? .with_codegen_config((CodegenConfig::TYPES | CodegenConfig::VARS).complement()) + .header_contents(&format!("{outfile_name}-input.h"), &header_contents); + trace!(bindgen_builder = ?bindgen_builder); + + Ok(bindgen_builder .generate() .expect("Bindings should succeed to generate") - .write_to_file(out_path.join(outfile_name))?) + .write_to_file(out_path.join(format!("{outfile_name}.rs")))?) } -// fn generate_hid(out_path: &Path, config: &Config) -> Result<(), ConfigError> -// { let mut builder = bindgen::Builder::wdk_default(config)? -// .with_codegen_config((CodegenConfig::TYPES | -// CodegenConfig::VARS).complement()); - -// // Only allowlist files in the hid-specific files declared in hid-input.h -// to // avoid duplicate definitions -// for header_file in HID_BASE_HEADERS -// .iter() -// .chain(HID_KERNEL_MODE_HEADERS.iter()) -// { -// builder = builder.allowlist_file(format!(".*{header_file}.*")); -// } - -// Ok(builder -// .generate() -// .expect("Bindings should succeed to generate") -// .write_to_file(out_path.join("hid.rs"))?) -// } - fn generate_wdf(out_path: &Path, config: &Config) -> Result<(), ConfigError> { - if let DriverConfig::Kmdf(_) | DriverConfig::Umdf(_) = &config.driver_config { + if let Some(wdf_header_contents) = config.bindgen_wdf_header_contents() { info!("Generating bindings to WDK: wdf.rs"); + let header_contents = { + let mut contents = config.bindgen_base_header_contents(); + contents.push_str(&wdf_header_contents); + contents + }; + trace!(header_contents = ?header_contents); + + let bindgen_builder = bindgen::Builder::wdk_default(config)? + .with_codegen_config((CodegenConfig::TYPES | CodegenConfig::VARS).complement()) + .header_contents("wdf-input.h", &header_contents) + // Only generate for files that are prefixed with (case-insensitive) wdf (ie. + // /some/path/WdfSomeHeader.h), to prevent duplication of code in ntddk.rs + .allowlist_file("(?i).*wdf.*"); + trace!(bindgen_builder = ?bindgen_builder); + // As of NI WDK, this may generate an empty file due to no non-type and non-var // items in the wdf headers(i.e. functions are all inlined). This step is // intentionally left here in case older/newer WDKs have non-inlined functions // or new WDKs may introduce non-inlined functions. - Ok(bindgen::Builder::wdk_default(config)? - .header_contents("base", BASE_INPUT_HEADER_FILE_CONTENTS) - .header_contents("wdf", WDF_INPUT_HEADER_CONTENTS) - .with_codegen_config((CodegenConfig::TYPES | CodegenConfig::VARS).complement()) - // Only generate for files that are prefixed with (case-insensitive) wdf (ie. - // /some/path/WdfSomeHeader.h), to prevent duplication of code in ntddk.rs - .allowlist_file("(?i).*wdf.*") + Ok(bindgen_builder .generate() .expect("Bindings should succeed to generate") .write_to_file(out_path.join("wdf.rs"))?) @@ -388,6 +332,56 @@ fn generate_wdf(out_path: &Path, config: &Config) -> Result<(), ConfigError> { } } +fn generate_hid(out_path: &Path, config: &Config) -> Result<(), ConfigError> { + cfg_if::cfg_if! { + if #[cfg(feature = "hid")] { + info!("Generating bindings to WDK: hid.rs"); + + let header_contents = { + let mut contents = config.bindgen_base_header_contents(); + + if let Some(wdf_header_contents) = config.bindgen_wdf_header_contents() { + contents.push_str(&wdf_header_contents); + } + + if env::var("CARGO_FEATURE_HID").is_ok() { + contents.push_str(&config.bindgen_hid_header_contents()); + }; + + contents + }; + trace!(header_contents = ?header_contents); + + let bindgen_builder = { + let mut builder = bindgen::Builder::wdk_default(config)? + .with_codegen_config((CodegenConfig::TYPES | CodegenConfig::VARS).complement()) + .header_contents("hid-input.h", &header_contents); + + // Only allowlist files in the hid-specific files to avoid duplicate definitions + for header_file in config.hid_headers() + { + + builder = builder.allowlist_file(format!("(?i).*{header_file}.*")); + } + + builder + }; + trace!(bindgen_builder = ?bindgen_builder); + + Ok(bindgen_builder + .generate() + .expect("Bindings should succeed to generate") + .write_to_file(out_path.join("hid.rs"))?) + } else { + let _ = (out_path, config); // Silence unused variable warnings when hid feature is not enabled + + info!( + "Skipping hid.rs generation since hid feature is not enabled"); + Ok(()) + } + } +} + /// Generates a `wdf_function_table.rs` file in `OUT_DIR` which contains the /// definition of `WDF_FUNCTION_TABLE`. This is required to be generated here /// since the size of the table is derived from either a global symbol @@ -523,30 +517,47 @@ fn main() -> anyhow::Result<()> { .name(format!("bindgen {file_name} generator")) .spawn_scoped(thread_scope, move || { // Parent span must be manually set since spans do not persist across thread boundaries: https://github.com/tokio-rs/tracing/issues/1391 - info_span!(parent: current_span, "worker thread", generated_file_name = file_name).in_scope(|| generate_function(out_path, config)) + info_span!(parent: ¤t_span, "worker thread", generated_file_name = file_name).in_scope(|| generate_function(out_path, config)) }) .expect("Scoped Thread should spawn successfully"), ); } }); - if let DriverConfig::Kmdf(_) | DriverConfig::Umdf(_) = config.driver_config { + if let Some(wdf_header_contents) = config.bindgen_wdf_header_contents() { let current_span = Span::current(); + let config = &config; + let out_path = &out_path; + // Compile a c library to expose symbols that are not exposed because of // __declspec(selectany) thread_join_handles.push( thread::Builder::new() .name("wdf.c cc compilation".to_string()) - .spawn_scoped(thread_scope, || { + .spawn_scoped(thread_scope, move || { // Parent span must be manually set since spans do not persist across thread boundaries: https://github.com/tokio-rs/tracing/issues/1391 info_span!(parent: current_span, "cc").in_scope(|| { info!("Compiling wdf.c"); - // Write all included headers into wdf.c + // Write all included headers into wdf.c (existing file, if present + // (i.e. incremental rebuild), is truncated) let wdf_c_file_path = out_path.join("wdf.c"); - let mut wdf_c_file = File::create_new(&wdf_c_file_path)?; - wdf_c_file.write_all(BASE_INPUT_HEADER_FILE_CONTENTS.as_bytes())?; - wdf_c_file.write_all(WDF_INPUT_HEADER_CONTENTS.as_bytes())?; + { + let mut wdf_c_file = File::create(&wdf_c_file_path)?; + wdf_c_file.write_all( + config.bindgen_base_header_contents().as_bytes(), + )?; + wdf_c_file.write_all(wdf_header_contents.as_bytes())?; + + #[cfg(feature = "hid")] + wdf_c_file.write_all( + config.bindgen_hid_header_contents().as_bytes(), + )?; + + // Explicitly sync_all to surface any IO errors (File::drop + // silently ignores close errors) + wdf_c_file.sync_all()?; + } let mut cc_builder = cc::Build::new(); for (key, value) in config.get_preprocessor_definitions_iter() { @@ -564,29 +575,36 @@ fn main() -> anyhow::Result<()> { ); info_span!("wdf_function_table.rs generation").in_scope(|| { - generate_wdf_function_table(&out_path, &config)?; + generate_wdf_function_table(out_path, config)?; Ok::<(), std::io::Error>(()) })?; info_span!("call_unsafe_wdf_function_binding.rs generation").in_scope(|| { - generate_call_unsafe_wdf_function_binding_macro(&out_path)?; + generate_call_unsafe_wdf_function_binding_macro(out_path)?; Ok::<(), std::io::Error>(()) })?; info_span!("test_stubs.rs generation").in_scope(|| { - generate_test_stubs(&out_path, &config)?; + generate_test_stubs(out_path, config)?; Ok::<(), std::io::Error>(()) })?; } for join_handle in thread_join_handles { let thread_name = join_handle.thread().name().unwrap_or("UNNAMED").to_string(); - join_handle - .join() - .expect("Thread should complete without panicking") - .with_context(|| { - format!(r#""{thread_name}" thread failed to exit successfully"#) - })?; + + match join_handle.join() { + // Forward panics to the main thread + Err(panic_payload) => { + panic::resume_unwind(panic_payload); + } + + Ok(thread_result) => { + thread_result.with_context(|| { + format!(r#""{thread_name}" thread failed to exit successfully"#) + })?; + } + } } Ok::<(), anyhow::Error>(()) })?; diff --git a/crates/wdk-sys/src/hid.rs b/crates/wdk-sys/src/hid.rs index ba7c4e30..1e5d67f0 100644 --- a/crates/wdk-sys/src/hid.rs +++ b/crates/wdk-sys/src/hid.rs @@ -1,6 +1,19 @@ // Copyright (c) Microsoft Corporation // License: MIT OR Apache-2.0 +//! Direct FFI bindings to HID APIs from the Windows Driver Kit (WDK) +//! +//! This module contains all bindings to functions, constants, methods, +//! constructors and destructors in the following headers: `hidpddi.h`, +//! `hidport.h`, `HidSpiCx/1.0/hidspicx.h`, `kbdmou.h`, `ntdd8042.h`, +//! `hidclass.h`, `hidsdi.h`, `hidpi.h`, `vhf.h`. Types are not included in this +//! module, but are available in the top-level `wdk_sys` module. + +#[allow( + missing_docs, + reason = "most items in the WDK headers have no inline documentation, so bindgen is unable to \ + generate documentation for their bindings" +)] mod bindings { // allow wildcards for types module since underlying c code relies on all // type definitions being in scope diff --git a/crates/wdk-sys/src/lib.rs b/crates/wdk-sys/src/lib.rs index c761cbba..9f0342ac 100644 --- a/crates/wdk-sys/src/lib.rs +++ b/crates/wdk-sys/src/lib.rs @@ -31,14 +31,16 @@ pub mod wdf; #[cfg(driver_model__driver_type = "UMDF")] pub mod windows; -#[cfg(any( - driver_model__driver_type = "WDM", - driver_model__driver_type = "KMDF", - driver_model__driver_type = "UMDF" +#[cfg(all( + any( + driver_model__driver_type = "WDM", + driver_model__driver_type = "KMDF", + driver_model__driver_type = "UMDF" + ), + feature = "hid" ))] pub mod hid; - #[cfg(feature = "test-stubs")] pub mod test_stubs; diff --git a/examples/sample-kmdf-driver/Cargo.lock b/examples/sample-kmdf-driver/Cargo.lock index 68afe172..8446b0c5 100644 --- a/examples/sample-kmdf-driver/Cargo.lock +++ b/examples/sample-kmdf-driver/Cargo.lock @@ -1,6 +1,6 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 +version = 4 [[package]] name = "aho-corasick" @@ -68,9 +68,9 @@ checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" [[package]] name = "bindgen" -version = "0.69.4" +version = "0.69.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a00dc851838a2120612785d195287475a3ac45514741da670b735818822129a0" +checksum = "271383c67ccabffb7381723dea0672a673f292304fcb45c01cc648c7a8d58088" dependencies = [ "bitflags", "cexpr", @@ -620,9 +620,9 @@ dependencies = [ [[package]] name = "tracing" -version = "0.1.40" +version = "0.1.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" +checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" dependencies = [ "pin-project-lite", "tracing-attributes", @@ -631,9 +631,9 @@ dependencies = [ [[package]] name = "tracing-attributes" -version = "0.1.27" +version = "0.1.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" +checksum = "395ae124c09f9e6918a2310af6038fba074bcf474ac352496d5910dd59a2226d" dependencies = [ "proc-macro2", "quote", @@ -642,9 +642,9 @@ dependencies = [ [[package]] name = "tracing-core" -version = "0.1.32" +version = "0.1.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +checksum = "e672c95779cf947c5311f83787af4fa8fffd12fb27e4993211a84bdfd9610f9c" dependencies = [ "once_cell", "valuable", @@ -663,9 +663,9 @@ dependencies = [ [[package]] name = "tracing-subscriber" -version = "0.3.18" +version = "0.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" +checksum = "e8189decb5ac0fa7bc8b96b7cb9b2701d60d48805aca84a238004d665fcc4008" dependencies = [ "matchers", "nu-ansi-term", @@ -760,6 +760,7 @@ dependencies = [ "bindgen", "cargo_metadata", "cc", + "cfg-if", "lazy_static", "rustversion", "serde_json", diff --git a/examples/sample-kmdf-driver/Cargo.toml b/examples/sample-kmdf-driver/Cargo.toml index e5bf2ef8..42c92bb6 100644 --- a/examples/sample-kmdf-driver/Cargo.toml +++ b/examples/sample-kmdf-driver/Cargo.toml @@ -31,6 +31,9 @@ wdk-sys = { path = "../../crates/wdk-sys", version = "0.3.0" } [features] default = [] + +hid = ["wdk-sys/hid"] + nightly = ["wdk/nightly", "wdk-sys/nightly"] [profile.dev] diff --git a/examples/sample-umdf-driver/Cargo.lock b/examples/sample-umdf-driver/Cargo.lock index d95db0be..d55732b7 100644 --- a/examples/sample-umdf-driver/Cargo.lock +++ b/examples/sample-umdf-driver/Cargo.lock @@ -1,6 +1,6 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 +version = 4 [[package]] name = "aho-corasick" @@ -68,9 +68,9 @@ checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" [[package]] name = "bindgen" -version = "0.69.4" +version = "0.69.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a00dc851838a2120612785d195287475a3ac45514741da670b735818822129a0" +checksum = "271383c67ccabffb7381723dea0672a673f292304fcb45c01cc648c7a8d58088" dependencies = [ "bitflags", "cexpr", @@ -618,9 +618,9 @@ dependencies = [ [[package]] name = "tracing" -version = "0.1.40" +version = "0.1.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" +checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" dependencies = [ "pin-project-lite", "tracing-attributes", @@ -629,9 +629,9 @@ dependencies = [ [[package]] name = "tracing-attributes" -version = "0.1.27" +version = "0.1.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" +checksum = "395ae124c09f9e6918a2310af6038fba074bcf474ac352496d5910dd59a2226d" dependencies = [ "proc-macro2", "quote", @@ -640,9 +640,9 @@ dependencies = [ [[package]] name = "tracing-core" -version = "0.1.32" +version = "0.1.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +checksum = "e672c95779cf947c5311f83787af4fa8fffd12fb27e4993211a84bdfd9610f9c" dependencies = [ "once_cell", "valuable", @@ -661,9 +661,9 @@ dependencies = [ [[package]] name = "tracing-subscriber" -version = "0.3.18" +version = "0.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" +checksum = "e8189decb5ac0fa7bc8b96b7cb9b2701d60d48805aca84a238004d665fcc4008" dependencies = [ "matchers", "nu-ansi-term", @@ -744,6 +744,7 @@ dependencies = [ "bindgen", "cargo_metadata", "cc", + "cfg-if", "lazy_static", "rustversion", "serde_json", diff --git a/examples/sample-umdf-driver/Cargo.toml b/examples/sample-umdf-driver/Cargo.toml index 36e72907..9b8d9003 100644 --- a/examples/sample-umdf-driver/Cargo.toml +++ b/examples/sample-umdf-driver/Cargo.toml @@ -29,6 +29,9 @@ wdk-sys = { path = "../../crates/wdk-sys", version = "0.3.0" } [features] default = [] + +hid = ["wdk-sys/hid"] + nightly = ["wdk/nightly", "wdk-sys/nightly"] [profile.dev] diff --git a/examples/sample-wdm-driver/Cargo.lock b/examples/sample-wdm-driver/Cargo.lock index a79d27fb..9c327584 100644 --- a/examples/sample-wdm-driver/Cargo.lock +++ b/examples/sample-wdm-driver/Cargo.lock @@ -1,6 +1,6 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 +version = 4 [[package]] name = "aho-corasick" @@ -68,9 +68,9 @@ checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" [[package]] name = "bindgen" -version = "0.69.4" +version = "0.69.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a00dc851838a2120612785d195287475a3ac45514741da670b735818822129a0" +checksum = "271383c67ccabffb7381723dea0672a673f292304fcb45c01cc648c7a8d58088" dependencies = [ "bitflags", "cexpr", @@ -620,9 +620,9 @@ dependencies = [ [[package]] name = "tracing" -version = "0.1.40" +version = "0.1.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" +checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" dependencies = [ "pin-project-lite", "tracing-attributes", @@ -631,9 +631,9 @@ dependencies = [ [[package]] name = "tracing-attributes" -version = "0.1.27" +version = "0.1.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" +checksum = "395ae124c09f9e6918a2310af6038fba074bcf474ac352496d5910dd59a2226d" dependencies = [ "proc-macro2", "quote", @@ -642,9 +642,9 @@ dependencies = [ [[package]] name = "tracing-core" -version = "0.1.32" +version = "0.1.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +checksum = "e672c95779cf947c5311f83787af4fa8fffd12fb27e4993211a84bdfd9610f9c" dependencies = [ "once_cell", "valuable", @@ -663,9 +663,9 @@ dependencies = [ [[package]] name = "tracing-subscriber" -version = "0.3.18" +version = "0.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" +checksum = "e8189decb5ac0fa7bc8b96b7cb9b2701d60d48805aca84a238004d665fcc4008" dependencies = [ "matchers", "nu-ansi-term", @@ -760,6 +760,7 @@ dependencies = [ "bindgen", "cargo_metadata", "cc", + "cfg-if", "lazy_static", "rustversion", "serde_json", diff --git a/examples/sample-wdm-driver/Cargo.toml b/examples/sample-wdm-driver/Cargo.toml index 529876d9..96457bd1 100644 --- a/examples/sample-wdm-driver/Cargo.toml +++ b/examples/sample-wdm-driver/Cargo.toml @@ -30,6 +30,9 @@ wdk-sys = { path = "../../crates/wdk-sys", version = "0.3.0" } [features] default = [] + +hid = ["wdk-sys/hid"] + nightly = ["wdk/nightly", "wdk-sys/nightly"] [profile.dev] diff --git a/tests/config-kmdf/Cargo.lock b/tests/config-kmdf/Cargo.lock index af8a88c1..a9d3edf6 100644 --- a/tests/config-kmdf/Cargo.lock +++ b/tests/config-kmdf/Cargo.lock @@ -1,6 +1,6 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 +version = 4 [[package]] name = "aho-corasick" @@ -77,9 +77,9 @@ dependencies = [ [[package]] name = "bindgen" -version = "0.69.4" +version = "0.69.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a00dc851838a2120612785d195287475a3ac45514741da670b735818822129a0" +checksum = "271383c67ccabffb7381723dea0672a673f292304fcb45c01cc648c7a8d58088" dependencies = [ "bitflags", "cexpr", @@ -744,9 +744,9 @@ dependencies = [ [[package]] name = "tracing" -version = "0.1.40" +version = "0.1.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" +checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" dependencies = [ "pin-project-lite", "tracing-attributes", @@ -755,9 +755,9 @@ dependencies = [ [[package]] name = "tracing-attributes" -version = "0.1.27" +version = "0.1.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" +checksum = "395ae124c09f9e6918a2310af6038fba074bcf474ac352496d5910dd59a2226d" dependencies = [ "proc-macro2", "quote", @@ -766,9 +766,9 @@ dependencies = [ [[package]] name = "tracing-core" -version = "0.1.32" +version = "0.1.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +checksum = "e672c95779cf947c5311f83787af4fa8fffd12fb27e4993211a84bdfd9610f9c" dependencies = [ "once_cell", "valuable", @@ -787,9 +787,9 @@ dependencies = [ [[package]] name = "tracing-subscriber" -version = "0.3.18" +version = "0.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" +checksum = "e8189decb5ac0fa7bc8b96b7cb9b2701d60d48805aca84a238004d665fcc4008" dependencies = [ "matchers", "nu-ansi-term", @@ -888,6 +888,7 @@ dependencies = [ "bindgen", "cargo_metadata", "cc", + "cfg-if", "lazy_static", "rustversion", "serde_json", diff --git a/tests/config-umdf/Cargo.lock b/tests/config-umdf/Cargo.lock index 99a963cd..adf5ef76 100644 --- a/tests/config-umdf/Cargo.lock +++ b/tests/config-umdf/Cargo.lock @@ -1,6 +1,6 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 +version = 4 [[package]] name = "aho-corasick" @@ -77,9 +77,9 @@ dependencies = [ [[package]] name = "bindgen" -version = "0.69.4" +version = "0.69.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a00dc851838a2120612785d195287475a3ac45514741da670b735818822129a0" +checksum = "271383c67ccabffb7381723dea0672a673f292304fcb45c01cc648c7a8d58088" dependencies = [ "bitflags", "cexpr", @@ -744,9 +744,9 @@ dependencies = [ [[package]] name = "tracing" -version = "0.1.40" +version = "0.1.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" +checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" dependencies = [ "pin-project-lite", "tracing-attributes", @@ -755,9 +755,9 @@ dependencies = [ [[package]] name = "tracing-attributes" -version = "0.1.27" +version = "0.1.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" +checksum = "395ae124c09f9e6918a2310af6038fba074bcf474ac352496d5910dd59a2226d" dependencies = [ "proc-macro2", "quote", @@ -766,9 +766,9 @@ dependencies = [ [[package]] name = "tracing-core" -version = "0.1.32" +version = "0.1.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +checksum = "e672c95779cf947c5311f83787af4fa8fffd12fb27e4993211a84bdfd9610f9c" dependencies = [ "once_cell", "valuable", @@ -787,9 +787,9 @@ dependencies = [ [[package]] name = "tracing-subscriber" -version = "0.3.18" +version = "0.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" +checksum = "e8189decb5ac0fa7bc8b96b7cb9b2701d60d48805aca84a238004d665fcc4008" dependencies = [ "matchers", "nu-ansi-term", @@ -888,6 +888,7 @@ dependencies = [ "bindgen", "cargo_metadata", "cc", + "cfg-if", "lazy_static", "rustversion", "serde_json", diff --git a/tests/mixed-package-kmdf-workspace/Cargo.lock b/tests/mixed-package-kmdf-workspace/Cargo.lock index 93f31b48..b67f4f75 100644 --- a/tests/mixed-package-kmdf-workspace/Cargo.lock +++ b/tests/mixed-package-kmdf-workspace/Cargo.lock @@ -1,6 +1,6 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 +version = 4 [[package]] name = "aho-corasick" @@ -68,9 +68,9 @@ checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" [[package]] name = "bindgen" -version = "0.69.4" +version = "0.69.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a00dc851838a2120612785d195287475a3ac45514741da670b735818822129a0" +checksum = "271383c67ccabffb7381723dea0672a673f292304fcb45c01cc648c7a8d58088" dependencies = [ "bitflags", "cexpr", @@ -625,9 +625,9 @@ dependencies = [ [[package]] name = "tracing" -version = "0.1.40" +version = "0.1.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" +checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" dependencies = [ "pin-project-lite", "tracing-attributes", @@ -636,9 +636,9 @@ dependencies = [ [[package]] name = "tracing-attributes" -version = "0.1.27" +version = "0.1.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" +checksum = "395ae124c09f9e6918a2310af6038fba074bcf474ac352496d5910dd59a2226d" dependencies = [ "proc-macro2", "quote", @@ -647,9 +647,9 @@ dependencies = [ [[package]] name = "tracing-core" -version = "0.1.32" +version = "0.1.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +checksum = "e672c95779cf947c5311f83787af4fa8fffd12fb27e4993211a84bdfd9610f9c" dependencies = [ "once_cell", "valuable", @@ -668,9 +668,9 @@ dependencies = [ [[package]] name = "tracing-subscriber" -version = "0.3.18" +version = "0.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" +checksum = "e8189decb5ac0fa7bc8b96b7cb9b2701d60d48805aca84a238004d665fcc4008" dependencies = [ "matchers", "nu-ansi-term", @@ -765,6 +765,7 @@ dependencies = [ "bindgen", "cargo_metadata", "cc", + "cfg-if", "lazy_static", "rustversion", "serde_json", diff --git a/tests/mixed-package-kmdf-workspace/crates/driver/src/lib.rs b/tests/mixed-package-kmdf-workspace/crates/driver/src/lib.rs index c7053e02..35c25388 100644 --- a/tests/mixed-package-kmdf-workspace/crates/driver/src/lib.rs +++ b/tests/mixed-package-kmdf-workspace/crates/driver/src/lib.rs @@ -24,6 +24,7 @@ use wdk_sys::{ DRIVER_OBJECT, NTSTATUS, PCUNICODE_STRING, + PDRIVER_OBJECT, ULONG, UNICODE_STRING, WCHAR, diff --git a/tests/umdf-driver-workspace/Cargo.lock b/tests/umdf-driver-workspace/Cargo.lock index 1dee849d..6fe553fb 100644 --- a/tests/umdf-driver-workspace/Cargo.lock +++ b/tests/umdf-driver-workspace/Cargo.lock @@ -1,6 +1,6 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 +version = 4 [[package]] name = "aho-corasick" @@ -68,9 +68,9 @@ checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" [[package]] name = "bindgen" -version = "0.69.4" +version = "0.69.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a00dc851838a2120612785d195287475a3ac45514741da670b735818822129a0" +checksum = "271383c67ccabffb7381723dea0672a673f292304fcb45c01cc648c7a8d58088" dependencies = [ "bitflags", "cexpr", @@ -628,9 +628,9 @@ dependencies = [ [[package]] name = "tracing" -version = "0.1.40" +version = "0.1.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" +checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" dependencies = [ "pin-project-lite", "tracing-attributes", @@ -639,9 +639,9 @@ dependencies = [ [[package]] name = "tracing-attributes" -version = "0.1.27" +version = "0.1.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" +checksum = "395ae124c09f9e6918a2310af6038fba074bcf474ac352496d5910dd59a2226d" dependencies = [ "proc-macro2", "quote", @@ -650,9 +650,9 @@ dependencies = [ [[package]] name = "tracing-core" -version = "0.1.32" +version = "0.1.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +checksum = "e672c95779cf947c5311f83787af4fa8fffd12fb27e4993211a84bdfd9610f9c" dependencies = [ "once_cell", "valuable", @@ -671,9 +671,9 @@ dependencies = [ [[package]] name = "tracing-subscriber" -version = "0.3.18" +version = "0.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" +checksum = "e8189decb5ac0fa7bc8b96b7cb9b2701d60d48805aca84a238004d665fcc4008" dependencies = [ "matchers", "nu-ansi-term", @@ -754,6 +754,7 @@ dependencies = [ "bindgen", "cargo_metadata", "cc", + "cfg-if", "lazy_static", "rustversion", "serde_json", diff --git a/tests/wdk-sys-tests/Cargo.lock b/tests/wdk-sys-tests/Cargo.lock index 3b4cd777..0dac5396 100644 --- a/tests/wdk-sys-tests/Cargo.lock +++ b/tests/wdk-sys-tests/Cargo.lock @@ -1,6 +1,6 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 +version = 4 [[package]] name = "aho-corasick" @@ -68,9 +68,9 @@ checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" [[package]] name = "bindgen" -version = "0.69.4" +version = "0.69.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a00dc851838a2120612785d195287475a3ac45514741da670b735818822129a0" +checksum = "271383c67ccabffb7381723dea0672a673f292304fcb45c01cc648c7a8d58088" dependencies = [ "bitflags", "cexpr", @@ -613,9 +613,9 @@ dependencies = [ [[package]] name = "tracing" -version = "0.1.40" +version = "0.1.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" +checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" dependencies = [ "pin-project-lite", "tracing-attributes", @@ -624,9 +624,9 @@ dependencies = [ [[package]] name = "tracing-attributes" -version = "0.1.27" +version = "0.1.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" +checksum = "395ae124c09f9e6918a2310af6038fba074bcf474ac352496d5910dd59a2226d" dependencies = [ "proc-macro2", "quote", @@ -635,9 +635,9 @@ dependencies = [ [[package]] name = "tracing-core" -version = "0.1.32" +version = "0.1.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +checksum = "e672c95779cf947c5311f83787af4fa8fffd12fb27e4993211a84bdfd9610f9c" dependencies = [ "once_cell", "valuable", @@ -656,9 +656,9 @@ dependencies = [ [[package]] name = "tracing-subscriber" -version = "0.3.18" +version = "0.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" +checksum = "e8189decb5ac0fa7bc8b96b7cb9b2701d60d48805aca84a238004d665fcc4008" dependencies = [ "matchers", "nu-ansi-term", @@ -729,6 +729,7 @@ dependencies = [ "bindgen", "cargo_metadata", "cc", + "cfg-if", "lazy_static", "rustversion", "serde_json", From 951c26f95ac46f4d344b79c121dcaf5bac4d9b46 Mon Sep 17 00:00:00 2001 From: Melvin Wang Date: Fri, 10 Jan 2025 15:39:32 -0800 Subject: [PATCH 06/20] cargo fmt --- examples/sample-kmdf-driver/src/lib.rs | 7 ++++--- examples/sample-umdf-driver/src/lib.rs | 7 ++++--- .../mixed-package-kmdf-workspace/crates/driver/src/lib.rs | 7 ++++--- tests/umdf-driver-workspace/crates/driver_1/src/lib.rs | 7 ++++--- tests/umdf-driver-workspace/crates/driver_2/src/lib.rs | 7 ++++--- 5 files changed, 20 insertions(+), 15 deletions(-) diff --git a/examples/sample-kmdf-driver/src/lib.rs b/examples/sample-kmdf-driver/src/lib.rs index 62540648..72266c3c 100644 --- a/examples/sample-kmdf-driver/src/lib.rs +++ b/examples/sample-kmdf-driver/src/lib.rs @@ -135,9 +135,10 @@ pub unsafe extern "system" fn driver_entry( // of the slice must be no larger than `isize::MAX`. This is proven by the below // `debug_assert!`. unsafe { - debug_assert!( - isize::try_from(number_of_slice_elements * core::mem::size_of::()).is_ok() - ); + debug_assert!(isize::try_from( + number_of_slice_elements * core::mem::size_of::() + ) + .is_ok()); slice::from_raw_parts(registry_path.Buffer, number_of_slice_elements) }, ); diff --git a/examples/sample-umdf-driver/src/lib.rs b/examples/sample-umdf-driver/src/lib.rs index 70010e80..61607443 100644 --- a/examples/sample-umdf-driver/src/lib.rs +++ b/examples/sample-umdf-driver/src/lib.rs @@ -120,9 +120,10 @@ pub unsafe extern "system" fn driver_entry( // of the slice must be no larger than `isize::MAX`. This is proven by the below // `debug_assert!`. unsafe { - debug_assert!( - isize::try_from(number_of_slice_elements * core::mem::size_of::()).is_ok() - ); + debug_assert!(isize::try_from( + number_of_slice_elements * core::mem::size_of::() + ) + .is_ok()); slice::from_raw_parts(registry_path.Buffer, number_of_slice_elements) }, ); diff --git a/tests/mixed-package-kmdf-workspace/crates/driver/src/lib.rs b/tests/mixed-package-kmdf-workspace/crates/driver/src/lib.rs index 35c25388..289d22f5 100644 --- a/tests/mixed-package-kmdf-workspace/crates/driver/src/lib.rs +++ b/tests/mixed-package-kmdf-workspace/crates/driver/src/lib.rs @@ -133,9 +133,10 @@ pub unsafe extern "system" fn driver_entry( // of the slice must be no larger than `isize::MAX`. This is proven by the below // `debug_assert!`. unsafe { - debug_assert!( - isize::try_from(number_of_slice_elements * core::mem::size_of::()).is_ok() - ); + debug_assert!(isize::try_from( + number_of_slice_elements * core::mem::size_of::() + ) + .is_ok()); slice::from_raw_parts(registry_path.Buffer, number_of_slice_elements) }, ); diff --git a/tests/umdf-driver-workspace/crates/driver_1/src/lib.rs b/tests/umdf-driver-workspace/crates/driver_1/src/lib.rs index a322d789..71623cce 100644 --- a/tests/umdf-driver-workspace/crates/driver_1/src/lib.rs +++ b/tests/umdf-driver-workspace/crates/driver_1/src/lib.rs @@ -120,9 +120,10 @@ pub unsafe extern "system" fn driver_entry( // of the slice must be no larger than `isize::MAX`. This is proven by the below // `debug_assert!`. unsafe { - debug_assert!( - isize::try_from(number_of_slice_elements * core::mem::size_of::()).is_ok() - ); + debug_assert!(isize::try_from( + number_of_slice_elements * core::mem::size_of::() + ) + .is_ok()); slice::from_raw_parts(registry_path.Buffer, number_of_slice_elements) }, ); diff --git a/tests/umdf-driver-workspace/crates/driver_2/src/lib.rs b/tests/umdf-driver-workspace/crates/driver_2/src/lib.rs index a322d789..71623cce 100644 --- a/tests/umdf-driver-workspace/crates/driver_2/src/lib.rs +++ b/tests/umdf-driver-workspace/crates/driver_2/src/lib.rs @@ -120,9 +120,10 @@ pub unsafe extern "system" fn driver_entry( // of the slice must be no larger than `isize::MAX`. This is proven by the below // `debug_assert!`. unsafe { - debug_assert!( - isize::try_from(number_of_slice_elements * core::mem::size_of::()).is_ok() - ); + debug_assert!(isize::try_from( + number_of_slice_elements * core::mem::size_of::() + ) + .is_ok()); slice::from_raw_parts(registry_path.Buffer, number_of_slice_elements) }, ); From 99093869a3ee103fe1eeea14218006727ddcd0fe Mon Sep 17 00:00:00 2001 From: Melvin Wang Date: Fri, 10 Jan 2025 15:43:49 -0800 Subject: [PATCH 07/20] add missing EOL --- .vscode/settings.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 138d12e0..c1d287ed 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -21,4 +21,4 @@ "./tests/wdk-sys-tests/Cargo.toml", ], "rust-analyzer.cargo.features": "all" -} \ No newline at end of file +} From 38d4b5f0c1a645ddb8add1052654a92f59d66ad8 Mon Sep 17 00:00:00 2001 From: Melvin Wang Date: Wed, 15 Jan 2025 16:54:45 -0800 Subject: [PATCH 08/20] refactor implementation so that apis are always available to `wdk_build::Config` --- crates/wdk-build/Cargo.toml | 5 -- crates/wdk-build/src/lib.rs | 126 ++++++++++++++++++------------------ crates/wdk-sys/Cargo.toml | 2 +- crates/wdk-sys/build.rs | 82 +++++++---------------- 4 files changed, 90 insertions(+), 125 deletions(-) diff --git a/crates/wdk-build/Cargo.toml b/crates/wdk-build/Cargo.toml index 4f12dd50..ad92f32f 100644 --- a/crates/wdk-build/Cargo.toml +++ b/crates/wdk-build/Cargo.toml @@ -35,11 +35,6 @@ windows = { workspace = true, features = [ [dev-dependencies] windows = { workspace = true, features = ["Win32_UI_Shell"] } -[features] -default = [] - -hid = [] - [lints.rust.unexpected_cfgs] level = "warn" check-cfg = ["cfg(wdk_build_unstable)", "cfg(skip_umdf_static_crt_check)"] diff --git a/crates/wdk-build/src/lib.rs b/crates/wdk-build/src/lib.rs index 1d9d1230..28162ae0 100644 --- a/crates/wdk-build/src/lib.rs +++ b/crates/wdk-build/src/lib.rs @@ -190,6 +190,13 @@ rustflags = [\"-C\", \"target-feature=+crt-static\"] SerdeError(#[from] metadata::Error), } +#[derive(Debug, Copy, Clone, PartialEq, Eq)] +pub enum ApiSubset { + Base, + Wdf, + Hid, +} + impl Default for Config { #[must_use] fn default() -> Self { @@ -629,53 +636,70 @@ impl Config { .map(std::string::ToString::to_string) } - pub fn base_headers(&self) -> impl Iterator { - match &self.driver_config { - DriverConfig::Wdm | DriverConfig::Kmdf(_) => { - vec!["ntifs.h", "ntddk.h"] - } - DriverConfig::Umdf(_) => { - vec!["windows.h"] + pub fn headers(&self, api_subset: ApiSubset) -> impl Iterator { + match api_subset { + ApiSubset::Base => match &self.driver_config { + DriverConfig::Wdm | DriverConfig::Kmdf(_) => { + vec!["ntifs.h", "ntddk.h"] + } + DriverConfig::Umdf(_) => { + vec!["windows.h"] + } + }, + ApiSubset::Wdf => { + if let DriverConfig::Kmdf(_) | DriverConfig::Umdf(_) = self.driver_config { + vec!["wdf.h"] + } else { + vec![] + } } - } - .into_iter() - .map(std::string::ToString::to_string) - } + ApiSubset::Hid => { + // HID Headers list from https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/_hid/ + let mut hid_headers = vec!["hidclass.h", "hidsdi.h", "hidpi.h", "vhf.h"]; - pub fn wdf_headers(&self) -> impl Iterator { - ["wdf.h"].into_iter().map(std::string::ToString::to_string) - } + if let DriverConfig::Wdm | DriverConfig::Kmdf(_) = self.driver_config { + hid_headers.extend(["hidpddi.h", "hidport.h", "kbdmou.h", "ntdd8042.h"]); + } - #[cfg(feature = "hid")] - pub fn hid_headers(&self) -> impl Iterator { - // HID Headers list from https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/_hid/ - { - let mut hid_headers = vec!["hidclass.h", "hidsdi.h", "hidpi.h", "vhf.h"]; - if let DriverConfig::Wdm | DriverConfig::Kmdf(_) = self.driver_config { - hid_headers.extend(["hidpddi.h", "hidport.h", "kbdmou.h", "ntdd8042.h"]); - } - if let DriverConfig::Kmdf(_) = self.driver_config { - hid_headers.extend(["HidSpiCx/1.0/hidspicx.h"]); + if let DriverConfig::Kmdf(_) = self.driver_config { + hid_headers.extend(["HidSpiCx/1.0/hidspicx.h"]); + } + + hid_headers } - hid_headers } .into_iter() .map(std::string::ToString::to_string) } - pub fn bindgen_base_header_contents(&self) -> String { - let mut header_contents = self.base_headers().fold(String::new(), |mut acc, header| { - acc.push_str(r#"#include ""#); - acc.push_str(&header); - acc.push_str("\"\n"); - acc - }); + pub fn bindgen_header_contents( + &self, + api_subsets: impl IntoIterator, + ) -> String { + api_subsets + .into_iter() + .fold(String::new(), |mut acc, api_subset| { + acc.push_str( + self.headers(api_subset) + .fold(String::new(), |mut acc, header| { + acc.push_str(r#"#include ""#); + acc.push_str(&header); + acc.push_str("\"\n"); + acc + }) + .as_str(), + ); - if let DriverConfig::Wdm | DriverConfig::Kmdf(_) = self.driver_config { - // TODO: Why is there no definition for this struct? Maybe blocklist this struct - // in bindgen. - header_contents.push_str( - r" + if api_subset == ApiSubset::Base + && matches!( + self.driver_config, + DriverConfig::Wdm | DriverConfig::Kmdf(_) + ) + { + // TODO: Why is there no definition for this struct? Maybe blocklist this struct + // in bindgen. + acc.push_str( + r" typedef union _KGDTENTRY64 { struct @@ -729,32 +753,10 @@ typedef union _KIDTENTRY64 unsigned __int64 Alignment; } KIDTENTRY64, *PKIDTENTRY64; ", - ); - } - - header_contents - } - - pub fn bindgen_wdf_header_contents(&self) -> Option { - if let DriverConfig::Kmdf(_) | DriverConfig::Umdf(_) = self.driver_config { - return Some(self.wdf_headers().fold(String::new(), |mut acc, header| { - acc.push_str(r#"#include ""#); - acc.push_str(&header); - acc.push_str("\"\n"); + ); + } acc - })); - } - None - } - - #[cfg(feature = "hid")] - pub fn bindgen_hid_header_contents(&self) -> String { - self.hid_headers().fold(String::new(), |mut acc, header| { - acc.push_str(r#"#include ""#); - acc.push_str(&header); - acc.push_str("\"\n"); - acc - }) + }) } /// Configure a Cargo build of a library that depends on the WDK. This diff --git a/crates/wdk-sys/Cargo.toml b/crates/wdk-sys/Cargo.toml index f76caef2..531c4adf 100644 --- a/crates/wdk-sys/Cargo.toml +++ b/crates/wdk-sys/Cargo.toml @@ -37,7 +37,7 @@ wdk-macros.workspace = true [features] default = [] -hid = ["wdk-build/hid"] +hid = [] nightly = ["wdk-macros/nightly"] test-stubs = [] diff --git a/crates/wdk-sys/build.rs b/crates/wdk-sys/build.rs index d78c90a3..bc36c00e 100644 --- a/crates/wdk-sys/build.rs +++ b/crates/wdk-sys/build.rs @@ -25,6 +25,7 @@ use tracing_subscriber::{ }; use wdk_build::{ configure_wdk_library_build_and_then, + ApiSubset, BuilderExt, Config, ConfigError, @@ -217,21 +218,12 @@ fn initialize_tracing() -> Result<(), ParseError> { fn generate_constants(out_path: &Path, config: &Config) -> Result<(), ConfigError> { info!("Generating bindings to WDK: constants.rs"); - let header_contents = { - let mut contents = config.bindgen_base_header_contents(); - - if let Some(wdf_header_contents) = config.bindgen_wdf_header_contents() { - contents.push_str(&wdf_header_contents); - } - + let header_contents = config.bindgen_header_contents([ + ApiSubset::Base, + ApiSubset::Wdf, #[cfg(feature = "hid")] - if env::var("CARGO_FEATURE_HID").is_ok() { - // TODO: this check can be removed? - contents.push_str(&config.bindgen_hid_header_contents()); - }; - - contents - }; + ApiSubset::Hid, + ]); trace!(header_contents = ?header_contents); let bindgen_builder = bindgen::Builder::wdk_default(config)? @@ -248,20 +240,12 @@ fn generate_constants(out_path: &Path, config: &Config) -> Result<(), ConfigErro fn generate_types(out_path: &Path, config: &Config) -> Result<(), ConfigError> { info!("Generating bindings to WDK: types.rs"); - let header_contents = { - let mut contents = config.bindgen_base_header_contents(); - - if let Some(wdf_header_contents) = config.bindgen_wdf_header_contents() { - contents.push_str(&wdf_header_contents); - } - + let header_contents = config.bindgen_header_contents([ + ApiSubset::Base, + ApiSubset::Wdf, #[cfg(feature = "hid")] - if env::var("CARGO_FEATURE_HID").is_ok() { - contents.push_str(&config.bindgen_hid_header_contents()); - }; - - contents - }; + ApiSubset::Hid, + ]); trace!(header_contents = ?header_contents); let bindgen_builder = bindgen::Builder::wdk_default(config)? @@ -282,7 +266,7 @@ fn generate_base(out_path: &Path, config: &Config) -> Result<(), ConfigError> { }; info!("Generating bindings to WDK: {outfile_name}.rs"); - let header_contents = config.bindgen_base_header_contents(); + let header_contents = config.bindgen_header_contents([ApiSubset::Base]); trace!(header_contents = ?header_contents); let bindgen_builder = bindgen::Builder::wdk_default(config)? @@ -297,14 +281,10 @@ fn generate_base(out_path: &Path, config: &Config) -> Result<(), ConfigError> { } fn generate_wdf(out_path: &Path, config: &Config) -> Result<(), ConfigError> { - if let Some(wdf_header_contents) = config.bindgen_wdf_header_contents() { + if let DriverConfig::Kmdf(_) | DriverConfig::Umdf(_) = config.driver_config { info!("Generating bindings to WDK: wdf.rs"); - let header_contents = { - let mut contents = config.bindgen_base_header_contents(); - contents.push_str(&wdf_header_contents); - contents - }; + let header_contents = config.bindgen_header_contents([ApiSubset::Base, ApiSubset::Wdf]); trace!(header_contents = ?header_contents); let bindgen_builder = bindgen::Builder::wdk_default(config)? @@ -337,19 +317,7 @@ fn generate_hid(out_path: &Path, config: &Config) -> Result<(), ConfigError> { if #[cfg(feature = "hid")] { info!("Generating bindings to WDK: hid.rs"); - let header_contents = { - let mut contents = config.bindgen_base_header_contents(); - - if let Some(wdf_header_contents) = config.bindgen_wdf_header_contents() { - contents.push_str(&wdf_header_contents); - } - - if env::var("CARGO_FEATURE_HID").is_ok() { - contents.push_str(&config.bindgen_hid_header_contents()); - }; - - contents - }; + let header_contents = config.bindgen_header_contents([ApiSubset::Base, ApiSubset::Wdf, ApiSubset::Hid]); trace!(header_contents = ?header_contents); let bindgen_builder = { @@ -358,9 +326,8 @@ fn generate_hid(out_path: &Path, config: &Config) -> Result<(), ConfigError> { .header_contents("hid-input.h", &header_contents); // Only allowlist files in the hid-specific files to avoid duplicate definitions - for header_file in config.hid_headers() + for header_file in config.headers(ApiSubset::Hid) { - builder = builder.allowlist_file(format!("(?i).*{header_file}.*")); } @@ -524,7 +491,7 @@ fn main() -> anyhow::Result<()> { } }); - if let Some(wdf_header_contents) = config.bindgen_wdf_header_contents() { + if let DriverConfig::Kmdf(_) | DriverConfig::Umdf(_) = config.driver_config { let current_span = Span::current(); let config = &config; let out_path = &out_path; @@ -545,13 +512,14 @@ fn main() -> anyhow::Result<()> { { let mut wdf_c_file = File::create(&wdf_c_file_path)?; wdf_c_file.write_all( - config.bindgen_base_header_contents().as_bytes(), - )?; - wdf_c_file.write_all(wdf_header_contents.as_bytes())?; - - #[cfg(feature = "hid")] - wdf_c_file.write_all( - config.bindgen_hid_header_contents().as_bytes(), + config + .bindgen_header_contents([ + ApiSubset::Base, + ApiSubset::Wdf, + #[cfg(feature = "hid")] + ApiSubset::Hid, + ]) + .as_bytes(), )?; // Explicitly sync_all to surface any IO errors (File::drop From 6b6b0809a9bb8c91c8f19999a3e1bae1a1718b9b Mon Sep 17 00:00:00 2001 From: Melvin Wang Date: Thu, 16 Jan 2025 13:22:25 -0800 Subject: [PATCH 09/20] update workflows to use --all-features flag for Cargo commands --- .github/workflows/build.yaml | 8 ++++---- .github/workflows/code-formatting-check.yaml | 1 - .github/workflows/codeql.yml | 2 +- .github/workflows/docs.yaml | 14 ++------------ .github/workflows/lint.yaml | 10 +++++----- .github/workflows/test.yaml | 6 +----- Makefile.toml | 6 ++---- 7 files changed, 15 insertions(+), 32 deletions(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 3c916bf9..031b785a 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -73,7 +73,7 @@ jobs: targets: ${{ matrix.target_triple }} - name: Run Cargo Build - run: cargo +${{ matrix.rust_toolchain }} build --locked --profile ${{ matrix.cargo_profile }} --target ${{ matrix.target_triple }} --workspace + run: cargo +${{ matrix.rust_toolchain }} build --locked --profile ${{ matrix.cargo_profile }} --target ${{ matrix.target_triple }} --workspace --all-features - name: Install Cargo Make uses: taiki-e/install-action@v2 @@ -81,10 +81,10 @@ jobs: tool: cargo-make - name: Run Cargo Make (package-driver-flow) in Workspace - run: cargo make package-driver-flow +${{ matrix.rust_toolchain }} --locked --profile ${{ matrix.cargo_profile }} --target ${{ matrix.target_triple }} --workspace + run: cargo make package-driver-flow +${{ matrix.rust_toolchain }} --locked --profile ${{ matrix.cargo_profile }} --target ${{ matrix.target_triple }} --workspace --all-features - name: Build Examples (via Cargo Make) - run: cargo make --cwd ./examples build +${{ matrix.rust_toolchain }} --locked --profile ${{ matrix.cargo_profile }} --target ${{ matrix.target_triple }} + run: cargo make --cwd ./examples build +${{ matrix.rust_toolchain }} --locked --profile ${{ matrix.cargo_profile }} --target ${{ matrix.target_triple }} --all-features - name: Package Examples (via Cargo Make) - run: cargo make --cwd ./examples package-driver-flow +${{ matrix.rust_toolchain }} --locked --profile ${{ matrix.cargo_profile }} --target ${{ matrix.target_triple }} + run: cargo make --cwd ./examples package-driver-flow +${{ matrix.rust_toolchain }} --locked --profile ${{ matrix.cargo_profile }} --target ${{ matrix.target_triple }} --all-features diff --git a/.github/workflows/code-formatting-check.yaml b/.github/workflows/code-formatting-check.yaml index fe4ff92d..f54851ec 100644 --- a/.github/workflows/code-formatting-check.yaml +++ b/.github/workflows/code-formatting-check.yaml @@ -6,7 +6,6 @@ on: schedule: # Trigger a job on default branch at 4AM PST everyday - cron: 0 11 * * * - jobs: cargo-fmt: name: .rs Formatting Check diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index f7b28a66..3017eb26 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -89,7 +89,7 @@ jobs: - if: matrix.build-mode == 'manual' working-directory: ./examples - run: cargo +${{ matrix.rust_toolchain }} make default --locked --profile ${{ matrix.cargo_profile }} --target ${{ matrix.target_triple }} --workspace + run: cargo +${{ matrix.rust_toolchain }} make default --locked --profile ${{ matrix.cargo_profile }} --target ${{ matrix.target_triple }} --workspace --all-features - name: Perform CodeQL Analysis uses: github/codeql-action/analyze@v3 diff --git a/.github/workflows/docs.yaml b/.github/workflows/docs.yaml index 56f9412b..f24123a5 100644 --- a/.github/workflows/docs.yaml +++ b/.github/workflows/docs.yaml @@ -72,19 +72,9 @@ jobs: - name: Run Cargo Doc # proc-macro crates must be excluded to avoid cargo doc bug: https://github.com/rust-lang/cargo/issues/10368 - run: cargo +${{ matrix.rust_toolchain }} doc --locked --profile ${{ matrix.cargo_profile }} --target ${{ matrix.target_triple }} --workspace --exclude wdk-macros - - - name: Run Cargo Doc (--features nightly) - if: matrix.rust_toolchain == 'nightly' - # proc-macro crates must be excluded to avoid cargo doc bug: https://github.com/rust-lang/cargo/issues/10368 - run: cargo +${{ matrix.rust_toolchain }} doc --locked --profile ${{ matrix.cargo_profile }} --target ${{ matrix.target_triple }} --workspace --exclude wdk-macros --features nightly + run: cargo +${{ matrix.rust_toolchain }} doc --locked --profile ${{ matrix.cargo_profile }} --target ${{ matrix.target_triple }} --workspace --exclude wdk-macros --all-features - name: Run Cargo Doc w/ proc-macro crates if: matrix.target_triple == 'x86_64-pc-windows-msvc' # cargo doc can only generate documentation for proc-macro crates when --target is not specified due to a cargo doc bug: https://github.com/rust-lang/cargo/issues/7677 - run: cargo +${{ matrix.rust_toolchain }} doc --locked --profile ${{ matrix.cargo_profile }} - - - name: Run Cargo Doc w/ proc-macro crates (--features nightly) - if: ${{ matrix.target_triple == 'x86_64-pc-windows-msvc' && matrix.rust_toolchain == 'nightly' }} - # cargo doc can only generate documentation for proc-macro crates when --target is not specified due to a cargo doc bug: https://github.com/rust-lang/cargo/issues/7677 - run: cargo +${{ matrix.rust_toolchain }} doc --locked --profile ${{ matrix.cargo_profile }} --features nightly + run: cargo +${{ matrix.rust_toolchain }} doc --locked --profile ${{ matrix.cargo_profile }} --all-features diff --git a/.github/workflows/lint.yaml b/.github/workflows/lint.yaml index 6bef9782..c5ca03d7 100644 --- a/.github/workflows/lint.yaml +++ b/.github/workflows/lint.yaml @@ -7,6 +7,10 @@ on: name: Lint +env: + RUSTFLAGS: >- + -D warnings + jobs: clippy: name: Clippy @@ -71,11 +75,7 @@ jobs: targets: ${{ matrix.target_triple }} - name: Run Cargo Clippy - run: cargo +${{ matrix.rust_toolchain }} clippy --locked --profile ${{ matrix.cargo_profile }} --target ${{ matrix.target_triple }} --all-targets -- -D warnings - - - name: Run Cargo Clippy (--features nightly) - if: matrix.rust_toolchain == 'nightly' - run: cargo +${{ matrix.rust_toolchain }} clippy --locked --profile ${{ matrix.cargo_profile }} --target ${{ matrix.target_triple }} --all-targets --features nightly -- -D warnings + run: cargo +${{ matrix.rust_toolchain }} clippy --locked --profile ${{ matrix.cargo_profile }} --target ${{ matrix.target_triple }} --all-targets --all-features unused_deps: name: Detect Unused Cargo Dependencies diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 2f63b1e1..7c7fe4cd 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -73,8 +73,4 @@ jobs: tool: cargo-expand@1.0.85 - name: Run Cargo Test - run: cargo +${{ matrix.rust_toolchain }} test --locked --profile ${{ matrix.cargo_profile }} --target ${{ matrix.target_triple }} - - - name: Run Cargo Test (--features nightly) - if: matrix.rust_toolchain == 'nightly' - run: cargo +${{ matrix.rust_toolchain }} test --locked --profile ${{ matrix.cargo_profile }} --target ${{ matrix.target_triple }} --features nightly + run: cargo +${{ matrix.rust_toolchain }} test --locked --profile ${{ matrix.cargo_profile }} --target ${{ matrix.target_triple }} --all-features diff --git a/Makefile.toml b/Makefile.toml index 2137bc1b..1310a467 100644 --- a/Makefile.toml +++ b/Makefile.toml @@ -6,9 +6,9 @@ additional_profiles = ["all-default-tasks"] [env] CARGO_MAKE_SKIP_SLOW_SECONDARY_FLOWS = false -CARGO_MAKE_CLIPPY_ARGS = "--all-targets -- -D warnings" -RUSTFLAGS = "-D warnings" +CARGO_MAKE_CLIPPY_ARGS = "--all-targets --all-features" CARGO_MAKE_RUST_DEFAULT_TOOLCHAIN = "stable" +RUSTFLAGS = "-D warnings" RUSTDOCFLAGS = "-D warnings" [tasks.wdk-pre-commit-flow] @@ -71,12 +71,10 @@ alias = "pre-test" [tasks.nightly-test] extend = "test" -env = { CARGO_MAKE_CARGO_BUILD_TEST_FLAGS = "--features nightly" } toolchain = "nightly" [tasks.post-nightly-test] extend = "post-test" -env = { CARGO_MAKE_CARGO_BUILD_TEST_FLAGS = { unset = true } } [tasks.nightly-clippy-flow] extend = "clippy-flow" From e777268b39531e1b8c30c3e4dc0dbc4d5391a879 Mon Sep 17 00:00:00 2001 From: Melvin Wang Date: Tue, 21 Jan 2025 17:07:32 -0800 Subject: [PATCH 10/20] resolve clippy errors --- crates/wdk-build/src/lib.rs | 16 ++++++++++++- examples/sample-kmdf-driver/Cargo.lock | 23 +++++++++++-------- examples/sample-umdf-driver/Cargo.lock | 23 +++++++++++-------- examples/sample-wdm-driver/Cargo.lock | 23 +++++++++++-------- tests/config-kmdf/Cargo.lock | 23 +++++++++++-------- tests/config-umdf/Cargo.lock | 23 +++++++++++-------- tests/mixed-package-kmdf-workspace/Cargo.lock | 23 +++++++++++-------- tests/umdf-driver-workspace/Cargo.lock | 23 +++++++++++-------- tests/wdk-sys-tests/Cargo.lock | 20 ++++++++-------- 9 files changed, 116 insertions(+), 81 deletions(-) diff --git a/crates/wdk-build/src/lib.rs b/crates/wdk-build/src/lib.rs index 28162ae0..b73e279b 100644 --- a/crates/wdk-build/src/lib.rs +++ b/crates/wdk-build/src/lib.rs @@ -190,10 +190,14 @@ rustflags = [\"-C\", \"target-feature=+crt-static\"] SerdeError(#[from] metadata::Error), } +/// Subset of APIs in the Windows Driver Kit #[derive(Debug, Copy, Clone, PartialEq, Eq)] pub enum ApiSubset { + /// API subset typically required for all Windows drivers Base, + /// API subset required for WDF (Windows Driver Framework) drivers Wdf, + /// API subset for HID (Human Interface Device) drivers: https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/_hid/ Hid, } @@ -636,6 +640,11 @@ impl Config { .map(std::string::ToString::to_string) } + /// Returns a [`String`] iterator over all the headers for a given + /// [`ApiSubset`] + /// + /// The iterator considers both the [`ApiSubset`] and the [`Config`] to + /// determine which headers to yield pub fn headers(&self, api_subset: ApiSubset) -> impl Iterator { match api_subset { ApiSubset::Base => match &self.driver_config { @@ -654,7 +663,6 @@ impl Config { } } ApiSubset::Hid => { - // HID Headers list from https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/_hid/ let mut hid_headers = vec!["hidclass.h", "hidsdi.h", "hidpi.h", "vhf.h"]; if let DriverConfig::Wdm | DriverConfig::Kmdf(_) = self.driver_config { @@ -672,6 +680,12 @@ impl Config { .map(std::string::ToString::to_string) } + /// Returns a [`String`] containing the contents of a header file designed + /// for [`bindgen`] to processs + /// + /// The contents contains `#include`'ed headers based off the [`ApiSubset`] + /// and [`Config`], as well as any additional definitions required for the + /// headers to be processed sucessfully pub fn bindgen_header_contents( &self, api_subsets: impl IntoIterator, diff --git a/examples/sample-kmdf-driver/Cargo.lock b/examples/sample-kmdf-driver/Cargo.lock index 8446b0c5..f8d885c6 100644 --- a/examples/sample-kmdf-driver/Cargo.lock +++ b/examples/sample-kmdf-driver/Cargo.lock @@ -129,9 +129,12 @@ dependencies = [ [[package]] name = "cc" -version = "1.1.0" +version = "1.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eaff6f8ce506b9773fa786672d63fc7a191ffea1be33f72bbd4aeacefca9ffc8" +checksum = "c8293772165d9345bdaaa39b45b2109591e63fe5e6fbc23c6ff930a048aa310b" +dependencies = [ + "shlex", +] [[package]] name = "cexpr" @@ -411,9 +414,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.36" +version = "1.0.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" +checksum = "0e4dccaaaf89514f546c693ddc140f729f958c247918a13380cccc6078391acc" dependencies = [ "proc-macro2", ] @@ -579,9 +582,9 @@ checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] name = "syn" -version = "2.0.79" +version = "2.0.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89132cd0bf050864e1d38dc3bbc07a0eb8e7530af26344d3d2bbbef83499f590" +checksum = "25aa4ce346d03a6dcd68dd8b4010bcb74e54e62c90c573f394c46eae99aba32d" dependencies = [ "proc-macro2", "quote", @@ -590,18 +593,18 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.62" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2675633b1499176c2dff06b0856a27976a8f9d436737b4cf4f312d4d91d8bbb" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.62" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d20468752b09f49e909e55a5d338caa8bedf615594e9d80bc4c565d30faf798c" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", diff --git a/examples/sample-umdf-driver/Cargo.lock b/examples/sample-umdf-driver/Cargo.lock index d55732b7..95a8f085 100644 --- a/examples/sample-umdf-driver/Cargo.lock +++ b/examples/sample-umdf-driver/Cargo.lock @@ -129,9 +129,12 @@ dependencies = [ [[package]] name = "cc" -version = "1.1.0" +version = "1.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eaff6f8ce506b9773fa786672d63fc7a191ffea1be33f72bbd4aeacefca9ffc8" +checksum = "c8293772165d9345bdaaa39b45b2109591e63fe5e6fbc23c6ff930a048aa310b" +dependencies = [ + "shlex", +] [[package]] name = "cexpr" @@ -411,9 +414,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.36" +version = "1.0.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" +checksum = "0e4dccaaaf89514f546c693ddc140f729f958c247918a13380cccc6078391acc" dependencies = [ "proc-macro2", ] @@ -577,9 +580,9 @@ checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] name = "syn" -version = "2.0.79" +version = "2.0.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89132cd0bf050864e1d38dc3bbc07a0eb8e7530af26344d3d2bbbef83499f590" +checksum = "25aa4ce346d03a6dcd68dd8b4010bcb74e54e62c90c573f394c46eae99aba32d" dependencies = [ "proc-macro2", "quote", @@ -588,18 +591,18 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.62" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2675633b1499176c2dff06b0856a27976a8f9d436737b4cf4f312d4d91d8bbb" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.62" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d20468752b09f49e909e55a5d338caa8bedf615594e9d80bc4c565d30faf798c" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", diff --git a/examples/sample-wdm-driver/Cargo.lock b/examples/sample-wdm-driver/Cargo.lock index 9c327584..4ef7885a 100644 --- a/examples/sample-wdm-driver/Cargo.lock +++ b/examples/sample-wdm-driver/Cargo.lock @@ -129,9 +129,12 @@ dependencies = [ [[package]] name = "cc" -version = "1.1.0" +version = "1.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eaff6f8ce506b9773fa786672d63fc7a191ffea1be33f72bbd4aeacefca9ffc8" +checksum = "c8293772165d9345bdaaa39b45b2109591e63fe5e6fbc23c6ff930a048aa310b" +dependencies = [ + "shlex", +] [[package]] name = "cexpr" @@ -411,9 +414,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.36" +version = "1.0.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" +checksum = "0e4dccaaaf89514f546c693ddc140f729f958c247918a13380cccc6078391acc" dependencies = [ "proc-macro2", ] @@ -579,9 +582,9 @@ checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] name = "syn" -version = "2.0.79" +version = "2.0.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89132cd0bf050864e1d38dc3bbc07a0eb8e7530af26344d3d2bbbef83499f590" +checksum = "25aa4ce346d03a6dcd68dd8b4010bcb74e54e62c90c573f394c46eae99aba32d" dependencies = [ "proc-macro2", "quote", @@ -590,18 +593,18 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.62" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2675633b1499176c2dff06b0856a27976a8f9d436737b4cf4f312d4d91d8bbb" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.62" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d20468752b09f49e909e55a5d338caa8bedf615594e9d80bc4c565d30faf798c" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", diff --git a/tests/config-kmdf/Cargo.lock b/tests/config-kmdf/Cargo.lock index a9d3edf6..f0622438 100644 --- a/tests/config-kmdf/Cargo.lock +++ b/tests/config-kmdf/Cargo.lock @@ -138,9 +138,12 @@ dependencies = [ [[package]] name = "cc" -version = "1.1.6" +version = "1.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2aba8f4e9906c7ce3c73463f62a7f0c65183ada1a2d47e397cc8810827f9694f" +checksum = "c8293772165d9345bdaaa39b45b2109591e63fe5e6fbc23c6ff930a048aa310b" +dependencies = [ + "shlex", +] [[package]] name = "cexpr" @@ -494,9 +497,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.36" +version = "1.0.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" +checksum = "0e4dccaaaf89514f546c693ddc140f729f958c247918a13380cccc6078391acc" dependencies = [ "proc-macro2", ] @@ -660,9 +663,9 @@ checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] name = "syn" -version = "2.0.79" +version = "2.0.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89132cd0bf050864e1d38dc3bbc07a0eb8e7530af26344d3d2bbbef83499f590" +checksum = "25aa4ce346d03a6dcd68dd8b4010bcb74e54e62c90c573f394c46eae99aba32d" dependencies = [ "proc-macro2", "quote", @@ -680,18 +683,18 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.63" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.63" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", diff --git a/tests/config-umdf/Cargo.lock b/tests/config-umdf/Cargo.lock index adf5ef76..01f0fb65 100644 --- a/tests/config-umdf/Cargo.lock +++ b/tests/config-umdf/Cargo.lock @@ -138,9 +138,12 @@ dependencies = [ [[package]] name = "cc" -version = "1.1.6" +version = "1.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2aba8f4e9906c7ce3c73463f62a7f0c65183ada1a2d47e397cc8810827f9694f" +checksum = "c8293772165d9345bdaaa39b45b2109591e63fe5e6fbc23c6ff930a048aa310b" +dependencies = [ + "shlex", +] [[package]] name = "cexpr" @@ -494,9 +497,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.36" +version = "1.0.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" +checksum = "0e4dccaaaf89514f546c693ddc140f729f958c247918a13380cccc6078391acc" dependencies = [ "proc-macro2", ] @@ -660,9 +663,9 @@ checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] name = "syn" -version = "2.0.79" +version = "2.0.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89132cd0bf050864e1d38dc3bbc07a0eb8e7530af26344d3d2bbbef83499f590" +checksum = "25aa4ce346d03a6dcd68dd8b4010bcb74e54e62c90c573f394c46eae99aba32d" dependencies = [ "proc-macro2", "quote", @@ -680,18 +683,18 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.63" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.63" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", diff --git a/tests/mixed-package-kmdf-workspace/Cargo.lock b/tests/mixed-package-kmdf-workspace/Cargo.lock index b67f4f75..ea13bf6a 100644 --- a/tests/mixed-package-kmdf-workspace/Cargo.lock +++ b/tests/mixed-package-kmdf-workspace/Cargo.lock @@ -129,9 +129,12 @@ dependencies = [ [[package]] name = "cc" -version = "1.1.7" +version = "1.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26a5c3fd7bfa1ce3897a3a3501d362b2d87b7f2583ebcb4a949ec25911025cbc" +checksum = "c8293772165d9345bdaaa39b45b2109591e63fe5e6fbc23c6ff930a048aa310b" +dependencies = [ + "shlex", +] [[package]] name = "cexpr" @@ -426,9 +429,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.36" +version = "1.0.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" +checksum = "0e4dccaaaf89514f546c693ddc140f729f958c247918a13380cccc6078391acc" dependencies = [ "proc-macro2", ] @@ -584,9 +587,9 @@ checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] name = "syn" -version = "2.0.79" +version = "2.0.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89132cd0bf050864e1d38dc3bbc07a0eb8e7530af26344d3d2bbbef83499f590" +checksum = "25aa4ce346d03a6dcd68dd8b4010bcb74e54e62c90c573f394c46eae99aba32d" dependencies = [ "proc-macro2", "quote", @@ -595,18 +598,18 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.63" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.63" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", diff --git a/tests/umdf-driver-workspace/Cargo.lock b/tests/umdf-driver-workspace/Cargo.lock index 6fe553fb..2b5a9428 100644 --- a/tests/umdf-driver-workspace/Cargo.lock +++ b/tests/umdf-driver-workspace/Cargo.lock @@ -129,9 +129,12 @@ dependencies = [ [[package]] name = "cc" -version = "1.1.7" +version = "1.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26a5c3fd7bfa1ce3897a3a3501d362b2d87b7f2583ebcb4a949ec25911025cbc" +checksum = "c8293772165d9345bdaaa39b45b2109591e63fe5e6fbc23c6ff930a048aa310b" +dependencies = [ + "shlex", +] [[package]] name = "cexpr" @@ -429,9 +432,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.36" +version = "1.0.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" +checksum = "0e4dccaaaf89514f546c693ddc140f729f958c247918a13380cccc6078391acc" dependencies = [ "proc-macro2", ] @@ -587,9 +590,9 @@ checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] name = "syn" -version = "2.0.79" +version = "2.0.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89132cd0bf050864e1d38dc3bbc07a0eb8e7530af26344d3d2bbbef83499f590" +checksum = "25aa4ce346d03a6dcd68dd8b4010bcb74e54e62c90c573f394c46eae99aba32d" dependencies = [ "proc-macro2", "quote", @@ -598,18 +601,18 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.63" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.63" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", diff --git a/tests/wdk-sys-tests/Cargo.lock b/tests/wdk-sys-tests/Cargo.lock index 0dac5396..a15c6e05 100644 --- a/tests/wdk-sys-tests/Cargo.lock +++ b/tests/wdk-sys-tests/Cargo.lock @@ -129,9 +129,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.1.16" +version = "1.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9d013ecb737093c0e86b151a7b837993cf9ec6c502946cfb44bedc392421e0b" +checksum = "c8293772165d9345bdaaa39b45b2109591e63fe5e6fbc23c6ff930a048aa310b" dependencies = [ "shlex", ] @@ -414,9 +414,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.37" +version = "1.0.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" +checksum = "0e4dccaaaf89514f546c693ddc140f729f958c247918a13380cccc6078391acc" dependencies = [ "proc-macro2", ] @@ -572,9 +572,9 @@ checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] name = "syn" -version = "2.0.77" +version = "2.0.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" +checksum = "25aa4ce346d03a6dcd68dd8b4010bcb74e54e62c90c573f394c46eae99aba32d" dependencies = [ "proc-macro2", "quote", @@ -583,18 +583,18 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.63" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.63" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", From f4f3a407cd4578ecb5f0f899ccba1543cc282e97 Mon Sep 17 00:00:00 2001 From: Melvin Wang Date: Tue, 21 Jan 2025 17:21:22 -0800 Subject: [PATCH 11/20] enable all-features for local cargo make flow --- Makefile.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/Makefile.toml b/Makefile.toml index 1310a467..df0bcb92 100644 --- a/Makefile.toml +++ b/Makefile.toml @@ -6,6 +6,7 @@ additional_profiles = ["all-default-tasks"] [env] CARGO_MAKE_SKIP_SLOW_SECONDARY_FLOWS = false +CARGO_MAKE_CARGO_BUILD_TEST_FLAGS = "${CARGO_MAKE_CARGO_ALL_FEATURES}" CARGO_MAKE_CLIPPY_ARGS = "--all-targets --all-features" CARGO_MAKE_RUST_DEFAULT_TOOLCHAIN = "stable" RUSTFLAGS = "-D warnings" From 1e938701e94bfab8f42570f19788f1b5a9a70e20 Mon Sep 17 00:00:00 2001 From: Melvin Wang Date: Tue, 21 Jan 2025 17:21:32 -0800 Subject: [PATCH 12/20] fix rustdoc lint --- crates/wdk-build/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/wdk-build/src/lib.rs b/crates/wdk-build/src/lib.rs index b73e279b..8338ed8f 100644 --- a/crates/wdk-build/src/lib.rs +++ b/crates/wdk-build/src/lib.rs @@ -197,7 +197,7 @@ pub enum ApiSubset { Base, /// API subset required for WDF (Windows Driver Framework) drivers Wdf, - /// API subset for HID (Human Interface Device) drivers: https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/_hid/ + /// API subset for HID (Human Interface Device) drivers: Hid, } From 826a4bcf9f284db1fc7129cf1fe8db1d068d5098 Mon Sep 17 00:00:00 2001 From: Melvin Wang Date: Tue, 21 Jan 2025 19:03:39 -0800 Subject: [PATCH 13/20] refactor!: rename get_include_paths, get_library_paths, and get_preprocessor_definitions_iter to include_paths, library_paths, and preprocessor_definitions --- crates/wdk-build/src/bindgen.rs | 4 ++-- crates/wdk-build/src/lib.rs | 18 ++++++------------ crates/wdk-sys/build.rs | 4 ++-- 3 files changed, 10 insertions(+), 16 deletions(-) diff --git a/crates/wdk-build/src/bindgen.rs b/crates/wdk-build/src/bindgen.rs index 04a6f8d9..63b417de 100644 --- a/crates/wdk-build/src/bindgen.rs +++ b/crates/wdk-build/src/bindgen.rs @@ -48,7 +48,7 @@ impl BuilderExt for Builder { // Building in eWDK can pollute system search path when clang-sys tries to detect // c_search_paths .detect_include_paths(false) - .clang_args(config.get_include_paths()?.iter().map(|include_path| { + .clang_args(config.include_paths()?.map(|include_path| { format!( "--include-directory={}", include_path @@ -58,7 +58,7 @@ impl BuilderExt for Builder { })) .clang_args( config - .get_preprocessor_definitions_iter() + .preprocessor_definitions() .map(|(key, value)| { format!( "--define-macro={key}{}", diff --git a/crates/wdk-build/src/lib.rs b/crates/wdk-build/src/lib.rs index 8338ed8f..d1d05091 100644 --- a/crates/wdk-build/src/lib.rs +++ b/crates/wdk-build/src/lib.rs @@ -324,7 +324,6 @@ impl Config { Ok(()) } - // TODO: deprecate in favor of include_paths() /// Return header include paths required to build and link based off of the /// configuration of `Config` /// @@ -332,8 +331,7 @@ impl Config { /// /// This function will return an error if any of the required paths do not /// exist. - pub fn get_include_paths(&self) -> Result, ConfigError> { - // FIXME: consider deprecating in favor of iter + pub fn include_paths(&self) -> Result, ConfigError> { let mut include_paths = vec![]; let include_directory = self.wdk_content_root.join("Include"); @@ -420,10 +418,9 @@ impl Config { } } - Ok(include_paths) + Ok(include_paths.into_iter()) } - // TODO: deprecate in favor of library_paths() /// Return library include paths required to build and link based off of /// the configuration of [`Config`]. /// @@ -433,7 +430,7 @@ impl Config { /// /// This function will return an error if any of the required paths do not /// exist. - pub fn get_library_paths(&self) -> Result, ConfigError> { + pub fn library_paths(&self) -> Result, ConfigError> { let mut library_paths = vec![]; let library_directory = self.wdk_content_root.join("Lib"); @@ -508,13 +505,12 @@ impl Config { // Reverse order of library paths so that paths pushed later into the vec take // precedence library_paths.reverse(); - Ok(library_paths) + Ok(library_paths.into_iter()) } - // TODO: Deprecate in favor of preprocessor_definitions_iter /// Return an iterator of strings that represent compiler definitions /// derived from the `Config` - pub fn get_preprocessor_definitions_iter( + pub fn preprocessor_definitions( &self, ) -> impl Iterator)> { // _WIN32_WINNT=$(WIN32_WINNT_VERSION); @@ -833,10 +829,8 @@ typedef union _KIDTENTRY64 }; } - let library_paths: Vec = self.get_library_paths()?; - // Emit linker search paths - for path in library_paths { + for path in self.library_paths()? { println!("cargo::rustc-link-search={}", path.display()); } diff --git a/crates/wdk-sys/build.rs b/crates/wdk-sys/build.rs index bc36c00e..aef913fd 100644 --- a/crates/wdk-sys/build.rs +++ b/crates/wdk-sys/build.rs @@ -528,12 +528,12 @@ fn main() -> anyhow::Result<()> { } let mut cc_builder = cc::Build::new(); - for (key, value) in config.get_preprocessor_definitions_iter() { + for (key, value) in config.preprocessor_definitions() { cc_builder.define(&key, value.as_deref()); } cc_builder - .includes(config.get_include_paths()?) + .includes(config.include_paths()?) .file(wdf_c_file_path) .compile("wdf"); Ok::<(), ConfigError>(()) From 8e4e4bb0f2d648f5e9ed8a25445bf2dbf594948d Mon Sep 17 00:00:00 2001 From: Melvin Wang Date: Wed, 22 Jan 2025 09:59:25 -0800 Subject: [PATCH 14/20] fix formatting --- crates/wdk-build/src/lib.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/crates/wdk-build/src/lib.rs b/crates/wdk-build/src/lib.rs index d1d05091..1b983104 100644 --- a/crates/wdk-build/src/lib.rs +++ b/crates/wdk-build/src/lib.rs @@ -510,9 +510,7 @@ impl Config { /// Return an iterator of strings that represent compiler definitions /// derived from the `Config` - pub fn preprocessor_definitions( - &self, - ) -> impl Iterator)> { + pub fn preprocessor_definitions(&self) -> impl Iterator)> { // _WIN32_WINNT=$(WIN32_WINNT_VERSION); // WINVER=$(WINVER_VERSION); // WINNT=1; From c02f27a23f9b4a488160931af2d31a575d4a9e7a Mon Sep 17 00:00:00 2001 From: Melvin Wang Date: Wed, 22 Jan 2025 11:25:35 -0800 Subject: [PATCH 15/20] fix rustdoc error --- crates/wdk-build/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/wdk-build/src/lib.rs b/crates/wdk-build/src/lib.rs index 1b983104..88a8ff08 100644 --- a/crates/wdk-build/src/lib.rs +++ b/crates/wdk-build/src/lib.rs @@ -675,7 +675,7 @@ impl Config { } /// Returns a [`String`] containing the contents of a header file designed - /// for [`bindgen`] to processs + /// for [`bindgen`](https://docs.rs/bindgen) to processs /// /// The contents contains `#include`'ed headers based off the [`ApiSubset`] /// and [`Config`], as well as any additional definitions required for the From 5e5050592fa4f587e1013119e7433c95b697a178 Mon Sep 17 00:00:00 2001 From: Melvin Wang Date: Wed, 22 Jan 2025 13:49:10 -0800 Subject: [PATCH 16/20] remove double inclusion of --all-features when invoking cargo make in CI --- .github/workflows/build.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 031b785a..21a9dcbf 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -81,10 +81,10 @@ jobs: tool: cargo-make - name: Run Cargo Make (package-driver-flow) in Workspace - run: cargo make package-driver-flow +${{ matrix.rust_toolchain }} --locked --profile ${{ matrix.cargo_profile }} --target ${{ matrix.target_triple }} --workspace --all-features + run: cargo make package-driver-flow +${{ matrix.rust_toolchain }} --locked --profile ${{ matrix.cargo_profile }} --target ${{ matrix.target_triple }} --workspace - name: Build Examples (via Cargo Make) - run: cargo make --cwd ./examples build +${{ matrix.rust_toolchain }} --locked --profile ${{ matrix.cargo_profile }} --target ${{ matrix.target_triple }} --all-features + run: cargo make --cwd ./examples build +${{ matrix.rust_toolchain }} --locked --profile ${{ matrix.cargo_profile }} --target ${{ matrix.target_triple }} - name: Package Examples (via Cargo Make) - run: cargo make --cwd ./examples package-driver-flow +${{ matrix.rust_toolchain }} --locked --profile ${{ matrix.cargo_profile }} --target ${{ matrix.target_triple }} --all-features + run: cargo make --cwd ./examples package-driver-flow +${{ matrix.rust_toolchain }} --locked --profile ${{ matrix.cargo_profile }} --target ${{ matrix.target_triple }} From 7cf36239f4b391fcda1490a5c03d0d20c90cb977 Mon Sep 17 00:00:00 2001 From: Melvin Wang Date: Wed, 22 Jan 2025 18:41:52 -0800 Subject: [PATCH 17/20] address pr comments --- CONTRIBUTING.md | 16 +++++++--------- Makefile.toml | 2 +- crates/wdk-build/src/lib.rs | 2 +- crates/wdk-sys/build.rs | 11 +++++------ 4 files changed, 14 insertions(+), 17 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index afaa715f..5bf47f8a 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -96,9 +96,8 @@ The following tools should be installed as a part of the `windows-drivers-rs` de ### Generating Documentation -* To compile and open documentation: `cargo doc --locked --open` - * To include nightly features: `cargo +nightly doc --locked --open --features nightly` - * To open docs for non-host architecture: `cargo doc --locked --open --target --workspace --exclude wdk-macros` +* To compile and open documentation: `cargo doc --locked --all-features --open` + * To open docs for non-host architecture: `cargo doc --locked --all-features --open --target --workspace --exclude wdk-macros` * `--target` is incompatible with `proc-macro` crates due to a [cargo bug](https://github.com/rust-lang/cargo/issues/10368) ### Policy on using Nightly/Unstable Features @@ -113,7 +112,7 @@ The crates in this repository are designed to work with `stable` rust. Some of t ### Build and Test -To **only build** the workspace: `cargo build` +To **only build** the workspace: `cargo build --locked --all-features` To **both** build and package the samples in the workspace: `cargo make --cwd .\crates\` @@ -123,13 +122,13 @@ To maintain the quality of code, tests and tools are required to pass before con **_Functional Correctness:_** -* `cargo test --locked` +* `cargo test --locked --all-features` * To test `nightly` features: `cargo +nightly test --locked --features nightly` **_Static Analysis and Linting:_** -* `cargo clippy --locked --all-targets -- -D warnings` - * To lint `nightly` features: `cargo +nightly clippy --locked --all-targets --features nightly -- -D warnings` +* `cargo clippy --locked --all-features --all-targets -- -D warnings` + * To lint `nightly` features: `cargo +nightly clippy --locked --all-features --all-targets --features nightly -- -D warnings` **_Formatting:_** @@ -146,8 +145,7 @@ To maintain the quality of code, tests and tools are required to pass before con **_Rust Documentation Build Test_** -* `cargo doc --locked` - * To build docs for `nightly` features: `cargo +nightly doc --locked --features nightly` +* `cargo doc --locked --all-features` ### A Note on Code-Style diff --git a/Makefile.toml b/Makefile.toml index df0bcb92..7d82cc2b 100644 --- a/Makefile.toml +++ b/Makefile.toml @@ -7,7 +7,7 @@ additional_profiles = ["all-default-tasks"] [env] CARGO_MAKE_SKIP_SLOW_SECONDARY_FLOWS = false CARGO_MAKE_CARGO_BUILD_TEST_FLAGS = "${CARGO_MAKE_CARGO_ALL_FEATURES}" -CARGO_MAKE_CLIPPY_ARGS = "--all-targets --all-features" +CARGO_MAKE_CLIPPY_ARGS = "--all-targets --all-features -- -D warnings" CARGO_MAKE_RUST_DEFAULT_TOOLCHAIN = "stable" RUSTFLAGS = "-D warnings" RUSTDOCFLAGS = "-D warnings" diff --git a/crates/wdk-build/src/lib.rs b/crates/wdk-build/src/lib.rs index 88a8ff08..a9ca3c0c 100644 --- a/crates/wdk-build/src/lib.rs +++ b/crates/wdk-build/src/lib.rs @@ -677,7 +677,7 @@ impl Config { /// Returns a [`String`] containing the contents of a header file designed /// for [`bindgen`](https://docs.rs/bindgen) to processs /// - /// The contents contains `#include`'ed headers based off the [`ApiSubset`] + /// The contents contain `#include`'ed headers based off the [`ApiSubset`] /// and [`Config`], as well as any additional definitions required for the /// headers to be processed sucessfully pub fn bindgen_header_contents( diff --git a/crates/wdk-sys/build.rs b/crates/wdk-sys/build.rs index aef913fd..3a1ec2b2 100644 --- a/crates/wdk-sys/build.rs +++ b/crates/wdk-sys/build.rs @@ -325,12 +325,11 @@ fn generate_hid(out_path: &Path, config: &Config) -> Result<(), ConfigError> { .with_codegen_config((CodegenConfig::TYPES | CodegenConfig::VARS).complement()) .header_contents("hid-input.h", &header_contents); - // Only allowlist files in the hid-specific files to avoid duplicate definitions - for header_file in config.headers(ApiSubset::Hid) - { - builder = builder.allowlist_file(format!("(?i).*{header_file}.*")); - } - + // Only allowlist files in the hid-specific files to avoid duplicate definitions + for header_file in config.headers(ApiSubset::Hid) + { + builder = builder.allowlist_file(format!("(?i).*{header_file}.*")); + } builder }; trace!(bindgen_builder = ?bindgen_builder); From 90a52c23d528fd539828e1bc62ba8649c8959df5 Mon Sep 17 00:00:00 2001 From: Melvin Wang Date: Thu, 23 Jan 2025 12:12:36 -0800 Subject: [PATCH 18/20] remove redundant -D warnings --- Makefile.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile.toml b/Makefile.toml index 7d82cc2b..df0bcb92 100644 --- a/Makefile.toml +++ b/Makefile.toml @@ -7,7 +7,7 @@ additional_profiles = ["all-default-tasks"] [env] CARGO_MAKE_SKIP_SLOW_SECONDARY_FLOWS = false CARGO_MAKE_CARGO_BUILD_TEST_FLAGS = "${CARGO_MAKE_CARGO_ALL_FEATURES}" -CARGO_MAKE_CLIPPY_ARGS = "--all-targets --all-features -- -D warnings" +CARGO_MAKE_CLIPPY_ARGS = "--all-targets --all-features" CARGO_MAKE_RUST_DEFAULT_TOOLCHAIN = "stable" RUSTFLAGS = "-D warnings" RUSTDOCFLAGS = "-D warnings" From 852532a5008d994f5e03332fc57eec217fd85c74 Mon Sep 17 00:00:00 2001 From: Melvin Wang Date: Sat, 25 Jan 2025 18:56:14 -0800 Subject: [PATCH 19/20] fix link --- crates/wdk-build/src/lib.rs | 2 +- crates/wdk-sys/build.rs | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/crates/wdk-build/src/lib.rs b/crates/wdk-build/src/lib.rs index a9ca3c0c..f3459c15 100644 --- a/crates/wdk-build/src/lib.rs +++ b/crates/wdk-build/src/lib.rs @@ -195,7 +195,7 @@ rustflags = [\"-C\", \"target-feature=+crt-static\"] pub enum ApiSubset { /// API subset typically required for all Windows drivers Base, - /// API subset required for WDF (Windows Driver Framework) drivers + /// API subset required for WDF (Windows Driver Framework) drivers: Wdf, /// API subset for HID (Human Interface Device) drivers: Hid, diff --git a/crates/wdk-sys/build.rs b/crates/wdk-sys/build.rs index 3a1ec2b2..a69346a2 100644 --- a/crates/wdk-sys/build.rs +++ b/crates/wdk-sys/build.rs @@ -153,7 +153,6 @@ pub static mut {WDFFUNCTIONS_SYMBOL_NAME_PLACEHOLDER}: *const WDFFUNC = core::pt type GenerateFn = fn(&Path, &Config) -> Result<(), ConfigError>; const BINDGEN_FILE_GENERATORS_TUPLES: &[(&str, GenerateFn)] = &[ - // TODO: rename all references of constants to constant and variables ("constants.rs", generate_constants), ("types.rs", generate_types), ("base.rs", generate_base), From 0de1a1a1070feedfc02946d0af525abca49561af Mon Sep 17 00:00:00 2001 From: Melvin Wang Date: Sun, 12 Jan 2025 21:27:50 -0800 Subject: [PATCH 20/20] feat: expand `wdk-sys` coverage to include spb-related headers --- .vscode/settings.json | 3 +- crates/wdk-build/src/lib.rs | 17 +++++++++- crates/wdk-sys/Cargo.toml | 1 + crates/wdk-sys/build.rs | 47 +++++++++++++++++++++++--- crates/wdk-sys/src/hid.rs | 9 +++-- crates/wdk-sys/src/lib.rs | 10 ++++++ crates/wdk-sys/src/ntddk.rs | 9 +++-- crates/wdk-sys/src/spb.rs | 37 ++++++++++++++++++++ crates/wdk-sys/src/wdf.rs | 9 +++-- crates/wdk-sys/src/windows.rs | 9 +++-- examples/sample-kmdf-driver/Cargo.toml | 1 + examples/sample-umdf-driver/Cargo.toml | 1 + examples/sample-wdm-driver/Cargo.toml | 1 + 13 files changed, 136 insertions(+), 18 deletions(-) create mode 100644 crates/wdk-sys/src/spb.rs diff --git a/.vscode/settings.json b/.vscode/settings.json index c1d287ed..fa9e9b63 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,6 +1,7 @@ { "rust-analyzer.rustfmt.extraArgs": [ - "+nightly" + "+nightly", + "--all" ], "rust-analyzer.rustfmt.rangeFormatting.enable": true, "evenBetterToml.formatter.crlf": true, diff --git a/crates/wdk-build/src/lib.rs b/crates/wdk-build/src/lib.rs index f3459c15..498d674d 100644 --- a/crates/wdk-build/src/lib.rs +++ b/crates/wdk-build/src/lib.rs @@ -199,6 +199,8 @@ pub enum ApiSubset { Wdf, /// API subset for HID (Human Interface Device) drivers: Hid, + /// API subset for SPB (Serial Peripheral Bus) drivers: + Spb, } impl Default for Config { @@ -643,7 +645,7 @@ impl Config { match api_subset { ApiSubset::Base => match &self.driver_config { DriverConfig::Wdm | DriverConfig::Kmdf(_) => { - vec!["ntifs.h", "ntddk.h"] + vec!["ntifs.h", "ntddk.h", "ntstrsafe.h"] } DriverConfig::Umdf(_) => { vec!["windows.h"] @@ -669,6 +671,19 @@ impl Config { hid_headers } + ApiSubset::Spb => { + let mut spb_headers = vec!["spb.h", "reshub.h"]; + + if let DriverConfig::Wdm | DriverConfig::Kmdf(_) = self.driver_config { + spb_headers.extend(["pwmutil.h"]); + } + + if let DriverConfig::Kmdf(_) = self.driver_config { + spb_headers.extend(["spb/1.1/spbcx.h"]); + } + + spb_headers + } } .into_iter() .map(std::string::ToString::to_string) diff --git a/crates/wdk-sys/Cargo.toml b/crates/wdk-sys/Cargo.toml index 531c4adf..2222e58a 100644 --- a/crates/wdk-sys/Cargo.toml +++ b/crates/wdk-sys/Cargo.toml @@ -38,6 +38,7 @@ wdk-macros.workspace = true default = [] hid = [] +spb = [] nightly = ["wdk-macros/nightly"] test-stubs = [] diff --git a/crates/wdk-sys/build.rs b/crates/wdk-sys/build.rs index a69346a2..51c77f31 100644 --- a/crates/wdk-sys/build.rs +++ b/crates/wdk-sys/build.rs @@ -158,6 +158,7 @@ const BINDGEN_FILE_GENERATORS_TUPLES: &[(&str, GenerateFn)] = &[ ("base.rs", generate_base), ("wdf.rs", generate_wdf), ("hid.rs", generate_hid), + ("spb.rs", generate_spb), ]; fn initialize_tracing() -> Result<(), ParseError> { @@ -222,6 +223,8 @@ fn generate_constants(out_path: &Path, config: &Config) -> Result<(), ConfigErro ApiSubset::Wdf, #[cfg(feature = "hid")] ApiSubset::Hid, + #[cfg(feature = "spb")] + ApiSubset::Spb, ]); trace!(header_contents = ?header_contents); @@ -244,6 +247,8 @@ fn generate_types(out_path: &Path, config: &Config) -> Result<(), ConfigError> { ApiSubset::Wdf, #[cfg(feature = "hid")] ApiSubset::Hid, + #[cfg(feature = "spb")] + ApiSubset::Spb, ]); trace!(header_contents = ?header_contents); @@ -294,10 +299,6 @@ fn generate_wdf(out_path: &Path, config: &Config) -> Result<(), ConfigError> { .allowlist_file("(?i).*wdf.*"); trace!(bindgen_builder = ?bindgen_builder); - // As of NI WDK, this may generate an empty file due to no non-type and non-var - // items in the wdf headers(i.e. functions are all inlined). This step is - // intentionally left here in case older/newer WDKs have non-inlined functions - // or new WDKs may introduce non-inlined functions. Ok(bindgen_builder .generate() .expect("Bindings should succeed to generate") @@ -347,6 +348,42 @@ fn generate_hid(out_path: &Path, config: &Config) -> Result<(), ConfigError> { } } +fn generate_spb(out_path: &Path, config: &Config) -> Result<(), ConfigError> { + cfg_if::cfg_if! { + if #[cfg(feature = "spb")] { + info!("Generating bindings to WDK: spb.rs"); + + let header_contents = config.bindgen_header_contents([ApiSubset::Base, ApiSubset::Wdf, ApiSubset::Spb]); + trace!(header_contents = ?header_contents); + + let bindgen_builder = { + let mut builder = bindgen::Builder::wdk_default(config)? + .with_codegen_config((CodegenConfig::TYPES | CodegenConfig::VARS).complement()) + .header_contents("spb-input.h", &header_contents); + + // Only allowlist files in the spb-specific files to avoid duplicate definitions + for header_file in config.headers(ApiSubset::Spb) + { + builder = builder.allowlist_file(format!("(?i).*{header_file}.*")); + } + builder + }; + trace!(bindgen_builder = ?bindgen_builder); + + Ok(bindgen_builder + .generate() + .expect("Bindings should succeed to generate") + .write_to_file(out_path.join("spb.rs"))?) + } else { + let _ = (out_path, config); // Silence unused variable warnings when spb feature is not enabled + + info!( + "Skipping spb.rs generation since spb feature is not enabled"); + Ok(()) + } + } +} + /// Generates a `wdf_function_table.rs` file in `OUT_DIR` which contains the /// definition of `WDF_FUNCTION_TABLE`. This is required to be generated here /// since the size of the table is derived from either a global symbol @@ -516,6 +553,8 @@ fn main() -> anyhow::Result<()> { ApiSubset::Wdf, #[cfg(feature = "hid")] ApiSubset::Hid, + #[cfg(feature = "spb")] + ApiSubset::Spb, ]) .as_bytes(), )?; diff --git a/crates/wdk-sys/src/hid.rs b/crates/wdk-sys/src/hid.rs index 1e5d67f0..236fb1b7 100644 --- a/crates/wdk-sys/src/hid.rs +++ b/crates/wdk-sys/src/hid.rs @@ -15,9 +15,12 @@ generate documentation for their bindings" )] mod bindings { - // allow wildcards for types module since underlying c code relies on all - // type definitions being in scope - #[allow(clippy::wildcard_imports)] + #[allow( + clippy::wildcard_imports, + reason = "the underlying c code relies on all type definitions being in scope, which \ + results in the bindgen generated code relying on the generated types being in \ + scope as well" + )] use crate::types::*; include!(concat!(env!("OUT_DIR"), "/hid.rs")); diff --git a/crates/wdk-sys/src/lib.rs b/crates/wdk-sys/src/lib.rs index 9f0342ac..db3ba1e3 100644 --- a/crates/wdk-sys/src/lib.rs +++ b/crates/wdk-sys/src/lib.rs @@ -41,6 +41,16 @@ pub mod windows; ))] pub mod hid; +#[cfg(all( + any( + driver_model__driver_type = "WDM", + driver_model__driver_type = "KMDF", + driver_model__driver_type = "UMDF" + ), + feature = "spb" +))] +pub mod spb; + #[cfg(feature = "test-stubs")] pub mod test_stubs; diff --git a/crates/wdk-sys/src/ntddk.rs b/crates/wdk-sys/src/ntddk.rs index d7a703e9..8f771e74 100644 --- a/crates/wdk-sys/src/ntddk.rs +++ b/crates/wdk-sys/src/ntddk.rs @@ -11,9 +11,12 @@ pub use bindings::*; #[allow(missing_docs)] mod bindings { - // allow wildcards for types module since underlying c code relies on all - // type definitions being in scope - #[allow(clippy::wildcard_imports)] + #[allow( + clippy::wildcard_imports, + reason = "the underlying c code relies on all type definitions being in scope, which \ + results in the bindgen generated code relying on the generated types being in \ + scope as well" + )] use crate::types::*; include!(concat!(env!("OUT_DIR"), "/ntddk.rs")); diff --git a/crates/wdk-sys/src/spb.rs b/crates/wdk-sys/src/spb.rs new file mode 100644 index 00000000..467e209f --- /dev/null +++ b/crates/wdk-sys/src/spb.rs @@ -0,0 +1,37 @@ +// Copyright (c) Microsoft Corporation +// License: MIT OR Apache-2.0 + +//! Direct FFI bindings to SPB APIs from the Windows Driver Kit (WDK) +//! +//! This module contains all bindings to functions, constants, methods, +//! constructors and destructors in the following headers: `spb.h`, `spbcx.h`, +//! `reshub.h`, `pwmutil.h`. Types are not included in this module, but are +//! available in the top-level `wdk_sys` module. + +#[allow( + missing_docs, + reason = "most items in the WDK headers have no inline documentation, so bindgen is unable to \ + generate documentation for their bindings" +)] +mod bindings { + #[allow( + clippy::wildcard_imports, + reason = "the underlying c code relies on all type definitions being in scope, which \ + results in the bindgen generated code relying on the generated types being in \ + scope as well" + )] + #[allow( + unused_imports, + reason = "in certain versions of the WDK, there are no functions related to SPB that can \ + be generated by bindgen, so these types are unused " + )] + use crate::types::*; + + include!(concat!(env!("OUT_DIR"), "/spb.rs")); +} +#[allow( + unused_imports, + reason = "in certain versions of the WDK, there are no functions related to SPB that can be \ + generated by bindgen, so the `bindings` module is empty" +)] +pub use bindings::*; diff --git a/crates/wdk-sys/src/wdf.rs b/crates/wdk-sys/src/wdf.rs index 28e75fc8..986116a6 100644 --- a/crates/wdk-sys/src/wdf.rs +++ b/crates/wdk-sys/src/wdf.rs @@ -12,9 +12,12 @@ pub use bindings::*; #[allow(missing_docs)] #[allow(clippy::unreadable_literal)] mod bindings { - // allow wildcards for types module since underlying c code relies on all - // type definitions being in scope - #[allow(clippy::wildcard_imports)] + #[allow( + clippy::wildcard_imports, + reason = "the underlying c code relies on all type definitions being in scope, which \ + results in the bindgen generated code relying on the generated types being in \ + scope as well" + )] use crate::types::*; include!(concat!(env!("OUT_DIR"), "/wdf.rs")); diff --git a/crates/wdk-sys/src/windows.rs b/crates/wdk-sys/src/windows.rs index 99d2bf53..4ab80248 100644 --- a/crates/wdk-sys/src/windows.rs +++ b/crates/wdk-sys/src/windows.rs @@ -11,9 +11,12 @@ pub use bindings::*; #[allow(missing_docs)] mod bindings { - // allow wildcards for types module since underlying c code relies on all - // type definitions being in scope - #[allow(clippy::wildcard_imports)] + #[allow( + clippy::wildcard_imports, + reason = "the underlying c code relies on all type definitions being in scope, which \ + results in the bindgen generated code relying on the generated types being in \ + scope as well" + )] use crate::types::*; include!(concat!(env!("OUT_DIR"), "/windows.rs")); diff --git a/examples/sample-kmdf-driver/Cargo.toml b/examples/sample-kmdf-driver/Cargo.toml index 42c92bb6..cff1287e 100644 --- a/examples/sample-kmdf-driver/Cargo.toml +++ b/examples/sample-kmdf-driver/Cargo.toml @@ -33,6 +33,7 @@ wdk-sys = { path = "../../crates/wdk-sys", version = "0.3.0" } default = [] hid = ["wdk-sys/hid"] +spb = ["wdk-sys/spb"] nightly = ["wdk/nightly", "wdk-sys/nightly"] diff --git a/examples/sample-umdf-driver/Cargo.toml b/examples/sample-umdf-driver/Cargo.toml index 9b8d9003..3ae09d09 100644 --- a/examples/sample-umdf-driver/Cargo.toml +++ b/examples/sample-umdf-driver/Cargo.toml @@ -31,6 +31,7 @@ wdk-sys = { path = "../../crates/wdk-sys", version = "0.3.0" } default = [] hid = ["wdk-sys/hid"] +spb = ["wdk-sys/spb"] nightly = ["wdk/nightly", "wdk-sys/nightly"] diff --git a/examples/sample-wdm-driver/Cargo.toml b/examples/sample-wdm-driver/Cargo.toml index 96457bd1..5fd3a516 100644 --- a/examples/sample-wdm-driver/Cargo.toml +++ b/examples/sample-wdm-driver/Cargo.toml @@ -32,6 +32,7 @@ wdk-sys = { path = "../../crates/wdk-sys", version = "0.3.0" } default = [] hid = ["wdk-sys/hid"] +spb = ["wdk-sys/spb"] nightly = ["wdk/nightly", "wdk-sys/nightly"]