Skip to content

Commit

Permalink
feat: expand wdk-sys coverage to include spb-related headers
Browse files Browse the repository at this point in the history
  • Loading branch information
wmmc88 committed Jan 13, 2025
1 parent 9909386 commit 8d03b2f
Show file tree
Hide file tree
Showing 9 changed files with 135 additions and 1 deletion.
1 change: 1 addition & 0 deletions crates/wdk-build/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ windows = { workspace = true, features = ["Win32_UI_Shell"] }
default = []

hid = []
spb = []

[lints.rust.unexpected_cfgs]
level = "warn"
Expand Down
29 changes: 28 additions & 1 deletion crates/wdk-build/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -632,7 +632,7 @@ impl Config {
pub fn base_headers(&self) -> impl Iterator<Item = String> {
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"]
Expand Down Expand Up @@ -663,6 +663,23 @@ impl Config {
.map(std::string::ToString::to_string)
}

#[cfg(feature = "spb")]
pub fn spb_headers(&self) -> impl Iterator<Item = String> {
// SPB Headers list from https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/_spb/
{
let mut hid_headers = vec!["spb.h", "reshub.h"];
if let DriverConfig::Wdm | DriverConfig::Kmdf(_) = self.driver_config {
hid_headers.extend(["pwmutil.h"]);
}
if let DriverConfig::Kmdf(_) = self.driver_config {
hid_headers.extend(["spb/1.1/spbcx.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 ""#);
Expand Down Expand Up @@ -757,6 +774,16 @@ typedef union _KIDTENTRY64
})
}

#[cfg(feature = "spb")]
pub fn bindgen_spb_header_contents(&self) -> String {
self.spb_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`].
///
Expand Down
1 change: 1 addition & 0 deletions crates/wdk-sys/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ wdk-macros.workspace = true
default = []

hid = ["wdk-build/hid"]
spb = ["wdk-build/spb"]

nightly = ["wdk-macros/nightly"]
test-stubs = []
Expand Down
68 changes: 68 additions & 0 deletions crates/wdk-sys/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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> {
Expand Down Expand Up @@ -230,6 +231,12 @@ fn generate_constants(out_path: &Path, config: &Config) -> Result<(), ConfigErro
contents.push_str(&config.bindgen_hid_header_contents());
};

#[cfg(feature = "spb")]
if env::var("CARGO_FEATURE_SPB").is_ok() {
// TODO: this check can be removed?
contents.push_str(&config.bindgen_spb_header_contents());
};

contents
};
trace!(header_contents = ?header_contents);
Expand Down Expand Up @@ -260,6 +267,12 @@ fn generate_types(out_path: &Path, config: &Config) -> Result<(), ConfigError> {
contents.push_str(&config.bindgen_hid_header_contents());
};

#[cfg(feature = "spb")]
if env::var("CARGO_FEATURE_SPB").is_ok() {
// TODO: this check can be removed?
contents.push_str(&config.bindgen_spb_header_contents());
};

contents
};
trace!(header_contents = ?header_contents);
Expand Down Expand Up @@ -382,6 +395,56 @@ 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 = {
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_SPB").is_ok() {
contents.push_str(&config.bindgen_spb_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("spb-input.h", &header_contents);

// Only allowlist files in the spb-specific files to avoid duplicate definitions
for header_file in config.spb_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("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
Expand Down Expand Up @@ -554,6 +617,11 @@ fn main() -> anyhow::Result<()> {
config.bindgen_hid_header_contents().as_bytes(),
)?;

#[cfg(feature = "spb")]
wdf_c_file.write_all(
config.bindgen_spb_header_contents().as_bytes(),
)?;

// Explicitly sync_all to surface any IO errors (File::drop
// silently ignores close errors)
wdf_c_file.sync_all()?;
Expand Down
10 changes: 10 additions & 0 deletions crates/wdk-sys/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
24 changes: 24 additions & 0 deletions crates/wdk-sys/src/spb.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// 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 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"), "/spb.rs"));
}
pub use bindings::*;
1 change: 1 addition & 0 deletions examples/sample-kmdf-driver/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"]

Expand Down
1 change: 1 addition & 0 deletions examples/sample-umdf-driver/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"]

Expand Down
1 change: 1 addition & 0 deletions examples/sample-wdm-driver/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"]

Expand Down

0 comments on commit 8d03b2f

Please sign in to comment.