Skip to content

Commit 35d5285

Browse files
committed
feat: expand wdk-sys coverage to include spb-related headers
1 parent b64d8f4 commit 35d5285

File tree

13 files changed

+138
-18
lines changed

13 files changed

+138
-18
lines changed

.vscode/settings.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
{
22
"rust-analyzer.rustfmt.extraArgs": [
3-
"+nightly"
3+
"+nightly",
4+
"--all"
45
],
56
"rust-analyzer.rustfmt.rangeFormatting.enable": true,
67
"evenBetterToml.formatter.crlf": true,

crates/wdk-build/src/lib.rs

+18-1
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,8 @@ pub enum ApiSubset {
199199
Wdf,
200200
/// API subset for HID (Human Interface Device) drivers: <https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/_hid/>
201201
Hid,
202+
/// API subset for SPB (Serial Peripheral Bus) drivers: <https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/_spb/>
203+
Spb,
202204
}
203205

204206
impl Default for Config {
@@ -643,7 +645,7 @@ impl Config {
643645
match api_subset {
644646
ApiSubset::Base => match &self.driver_config {
645647
DriverConfig::Wdm | DriverConfig::Kmdf(_) => {
646-
vec!["ntifs.h", "ntddk.h"]
648+
vec!["ntifs.h", "ntddk.h", "ntstrsafe.h"]
647649
}
648650
DriverConfig::Umdf(_) => {
649651
vec!["windows.h"]
@@ -669,6 +671,19 @@ impl Config {
669671

670672
hid_headers
671673
}
674+
ApiSubset::Spb => {
675+
let mut spb_headers = vec!["spb.h", "reshub.h"];
676+
677+
if let DriverConfig::Wdm | DriverConfig::Kmdf(_) = self.driver_config {
678+
spb_headers.extend(["pwmutil.h"]);
679+
}
680+
681+
if let DriverConfig::Kmdf(_) = self.driver_config {
682+
spb_headers.extend(["spb/1.1/spbcx.h"]);
683+
}
684+
685+
spb_headers
686+
}
672687
}
673688
.into_iter()
674689
.map(std::string::ToString::to_string)
@@ -1273,6 +1288,7 @@ mod tests {
12731288
config.bindgen_header_contents([ApiSubset::Base]),
12741289
r#"#include "ntifs.h"
12751290
#include "ntddk.h"
1291+
#include "ntstrsafe.h"
12761292
"#,
12771293
);
12781294
}
@@ -1292,6 +1308,7 @@ mod tests {
12921308
config.bindgen_header_contents([ApiSubset::Base, ApiSubset::Wdf]),
12931309
r#"#include "ntifs.h"
12941310
#include "ntddk.h"
1311+
#include "ntstrsafe.h"
12951312
#include "wdf.h"
12961313
"#,
12971314
);

crates/wdk-sys/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ wdk-macros.workspace = true
3636
default = []
3737

3838
hid = []
39+
spb = []
3940

4041
nightly = ["wdk-macros/nightly"]
4142
test-stubs = []

crates/wdk-sys/build.rs

+43-4
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,7 @@ const BINDGEN_FILE_GENERATORS_TUPLES: &[(&str, GenerateFn)] = &[
132132
("base.rs", generate_base),
133133
("wdf.rs", generate_wdf),
134134
("hid.rs", generate_hid),
135+
("spb.rs", generate_spb),
135136
];
136137

137138
fn initialize_tracing() -> Result<(), ParseError> {
@@ -196,6 +197,8 @@ fn generate_constants(out_path: &Path, config: &Config) -> Result<(), ConfigErro
196197
ApiSubset::Wdf,
197198
#[cfg(feature = "hid")]
198199
ApiSubset::Hid,
200+
#[cfg(feature = "spb")]
201+
ApiSubset::Spb,
199202
]);
200203
trace!(header_contents = ?header_contents);
201204

@@ -218,6 +221,8 @@ fn generate_types(out_path: &Path, config: &Config) -> Result<(), ConfigError> {
218221
ApiSubset::Wdf,
219222
#[cfg(feature = "hid")]
220223
ApiSubset::Hid,
224+
#[cfg(feature = "spb")]
225+
ApiSubset::Spb,
221226
]);
222227
trace!(header_contents = ?header_contents);
223228

@@ -268,10 +273,6 @@ fn generate_wdf(out_path: &Path, config: &Config) -> Result<(), ConfigError> {
268273
.allowlist_file("(?i).*wdf.*");
269274
trace!(bindgen_builder = ?bindgen_builder);
270275

271-
// As of NI WDK, this may generate an empty file due to no non-type and non-var
272-
// items in the wdf headers(i.e. functions are all inlined). This step is
273-
// intentionally left here in case older/newer WDKs have non-inlined functions
274-
// or new WDKs may introduce non-inlined functions.
275276
Ok(bindgen_builder
276277
.generate()
277278
.expect("Bindings should succeed to generate")
@@ -321,6 +322,42 @@ fn generate_hid(out_path: &Path, config: &Config) -> Result<(), ConfigError> {
321322
}
322323
}
323324

325+
fn generate_spb(out_path: &Path, config: &Config) -> Result<(), ConfigError> {
326+
cfg_if::cfg_if! {
327+
if #[cfg(feature = "spb")] {
328+
info!("Generating bindings to WDK: spb.rs");
329+
330+
let header_contents = config.bindgen_header_contents([ApiSubset::Base, ApiSubset::Wdf, ApiSubset::Spb]);
331+
trace!(header_contents = ?header_contents);
332+
333+
let bindgen_builder = {
334+
let mut builder = bindgen::Builder::wdk_default(config)?
335+
.with_codegen_config((CodegenConfig::TYPES | CodegenConfig::VARS).complement())
336+
.header_contents("spb-input.h", &header_contents);
337+
338+
// Only allowlist files in the spb-specific files to avoid duplicate definitions
339+
for header_file in config.headers(ApiSubset::Spb)
340+
{
341+
builder = builder.allowlist_file(format!("(?i).*{header_file}.*"));
342+
}
343+
builder
344+
};
345+
trace!(bindgen_builder = ?bindgen_builder);
346+
347+
Ok(bindgen_builder
348+
.generate()
349+
.expect("Bindings should succeed to generate")
350+
.write_to_file(out_path.join("spb.rs"))?)
351+
} else {
352+
let _ = (out_path, config); // Silence unused variable warnings when spb feature is not enabled
353+
354+
info!(
355+
"Skipping spb.rs generation since spb feature is not enabled");
356+
Ok(())
357+
}
358+
}
359+
}
360+
324361
/// Generates a `wdf_function_count.rs` file in `OUT_DIR` which contains the
325362
/// definition of the function `get_wdf_function_count()`. This is required to
326363
/// be generated here since the size of the table is derived from either a
@@ -480,6 +517,8 @@ fn main() -> anyhow::Result<()> {
480517
ApiSubset::Wdf,
481518
#[cfg(feature = "hid")]
482519
ApiSubset::Hid,
520+
#[cfg(feature = "spb")]
521+
ApiSubset::Spb,
483522
])
484523
.as_bytes(),
485524
)?;

crates/wdk-sys/src/hid.rs

+6-3
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,12 @@
1515
generate documentation for their bindings"
1616
)]
1717
mod bindings {
18-
// allow wildcards for types module since underlying c code relies on all
19-
// type definitions being in scope
20-
#[allow(clippy::wildcard_imports)]
18+
#[allow(
19+
clippy::wildcard_imports,
20+
reason = "the underlying c code relies on all type definitions being in scope, which \
21+
results in the bindgen generated code relying on the generated types being in \
22+
scope as well"
23+
)]
2124
use crate::types::*;
2225

2326
include!(concat!(env!("OUT_DIR"), "/hid.rs"));

crates/wdk-sys/src/lib.rs

+10
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,16 @@ pub mod windows;
3939
))]
4040
pub mod hid;
4141

42+
#[cfg(all(
43+
any(
44+
driver_model__driver_type = "WDM",
45+
driver_model__driver_type = "KMDF",
46+
driver_model__driver_type = "UMDF"
47+
),
48+
feature = "spb"
49+
))]
50+
pub mod spb;
51+
4252
#[cfg(feature = "test-stubs")]
4353
pub mod test_stubs;
4454

crates/wdk-sys/src/ntddk.rs

+6-3
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,12 @@ pub use bindings::*;
1111

1212
#[allow(missing_docs)]
1313
mod bindings {
14-
// allow wildcards for types module since underlying c code relies on all
15-
// type definitions being in scope
16-
#[allow(clippy::wildcard_imports)]
14+
#[allow(
15+
clippy::wildcard_imports,
16+
reason = "the underlying c code relies on all type definitions being in scope, which \
17+
results in the bindgen generated code relying on the generated types being in \
18+
scope as well"
19+
)]
1720
use crate::types::*;
1821

1922
include!(concat!(env!("OUT_DIR"), "/ntddk.rs"));

crates/wdk-sys/src/spb.rs

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
// Copyright (c) Microsoft Corporation
2+
// License: MIT OR Apache-2.0
3+
4+
//! Direct FFI bindings to SPB APIs from the Windows Driver Kit (WDK)
5+
//!
6+
//! This module contains all bindings to functions, constants, methods,
7+
//! constructors and destructors in the following headers: `spb.h`, `spbcx.h`,
8+
//! `reshub.h`, `pwmutil.h`. Types are not included in this module, but are
9+
//! available in the top-level `wdk_sys` module.
10+
11+
#[allow(
12+
missing_docs,
13+
reason = "most items in the WDK headers have no inline documentation, so bindgen is unable to \
14+
generate documentation for their bindings"
15+
)]
16+
mod bindings {
17+
#[allow(
18+
clippy::wildcard_imports,
19+
reason = "the underlying c code relies on all type definitions being in scope, which \
20+
results in the bindgen generated code relying on the generated types being in \
21+
scope as well"
22+
)]
23+
#[allow(
24+
unused_imports,
25+
reason = "in certain versions of the WDK, there are no functions related to SPB that can \
26+
be generated by bindgen, so these types are unused "
27+
)]
28+
use crate::types::*;
29+
30+
include!(concat!(env!("OUT_DIR"), "/spb.rs"));
31+
}
32+
#[allow(
33+
unused_imports,
34+
reason = "in certain versions of the WDK, there are no functions related to SPB that can be \
35+
generated by bindgen, so the `bindings` module is empty"
36+
)]
37+
pub use bindings::*;

crates/wdk-sys/src/wdf.rs

+6-3
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,12 @@ pub use bindings::*;
1212
#[allow(missing_docs)]
1313
#[allow(clippy::unreadable_literal)]
1414
mod bindings {
15-
// allow wildcards for types module since underlying c code relies on all
16-
// type definitions being in scope
17-
#[allow(clippy::wildcard_imports)]
15+
#[allow(
16+
clippy::wildcard_imports,
17+
reason = "the underlying c code relies on all type definitions being in scope, which \
18+
results in the bindgen generated code relying on the generated types being in \
19+
scope as well"
20+
)]
1821
use crate::types::*;
1922

2023
include!(concat!(env!("OUT_DIR"), "/wdf.rs"));

crates/wdk-sys/src/windows.rs

+6-3
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,12 @@ pub use bindings::*;
1111

1212
#[allow(missing_docs)]
1313
mod bindings {
14-
// allow wildcards for types module since underlying c code relies on all
15-
// type definitions being in scope
16-
#[allow(clippy::wildcard_imports)]
14+
#[allow(
15+
clippy::wildcard_imports,
16+
reason = "the underlying c code relies on all type definitions being in scope, which \
17+
results in the bindgen generated code relying on the generated types being in \
18+
scope as well"
19+
)]
1720
use crate::types::*;
1821

1922
include!(concat!(env!("OUT_DIR"), "/windows.rs"));

examples/sample-kmdf-driver/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ wdk-sys = { path = "../../crates/wdk-sys", version = "0.3.0" }
3333
default = []
3434

3535
hid = ["wdk-sys/hid"]
36+
spb = ["wdk-sys/spb"]
3637

3738
nightly = ["wdk/nightly", "wdk-sys/nightly"]
3839

examples/sample-umdf-driver/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ wdk-sys = { path = "../../crates/wdk-sys", version = "0.3.0" }
3131
default = []
3232

3333
hid = ["wdk-sys/hid"]
34+
spb = ["wdk-sys/spb"]
3435

3536
nightly = ["wdk/nightly", "wdk-sys/nightly"]
3637

examples/sample-wdm-driver/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ wdk-sys = { path = "../../crates/wdk-sys", version = "0.3.0" }
3232
default = []
3333

3434
hid = ["wdk-sys/hid"]
35+
spb = ["wdk-sys/spb"]
3536

3637
nightly = ["wdk/nightly", "wdk-sys/nightly"]
3738

0 commit comments

Comments
 (0)