Skip to content

Commit 0de1a1a

Browse files
committed
feat: expand wdk-sys coverage to include spb-related headers
1 parent 852532a commit 0de1a1a

File tree

13 files changed

+136
-18
lines changed

13 files changed

+136
-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

+16-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)

crates/wdk-sys/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ wdk-macros.workspace = true
3838
default = []
3939

4040
hid = []
41+
spb = []
4142

4243
nightly = ["wdk-macros/nightly"]
4344
test-stubs = []

crates/wdk-sys/build.rs

+43-4
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,7 @@ const BINDGEN_FILE_GENERATORS_TUPLES: &[(&str, GenerateFn)] = &[
158158
("base.rs", generate_base),
159159
("wdf.rs", generate_wdf),
160160
("hid.rs", generate_hid),
161+
("spb.rs", generate_spb),
161162
];
162163

163164
fn initialize_tracing() -> Result<(), ParseError> {
@@ -222,6 +223,8 @@ fn generate_constants(out_path: &Path, config: &Config) -> Result<(), ConfigErro
222223
ApiSubset::Wdf,
223224
#[cfg(feature = "hid")]
224225
ApiSubset::Hid,
226+
#[cfg(feature = "spb")]
227+
ApiSubset::Spb,
225228
]);
226229
trace!(header_contents = ?header_contents);
227230

@@ -244,6 +247,8 @@ fn generate_types(out_path: &Path, config: &Config) -> Result<(), ConfigError> {
244247
ApiSubset::Wdf,
245248
#[cfg(feature = "hid")]
246249
ApiSubset::Hid,
250+
#[cfg(feature = "spb")]
251+
ApiSubset::Spb,
247252
]);
248253
trace!(header_contents = ?header_contents);
249254

@@ -294,10 +299,6 @@ fn generate_wdf(out_path: &Path, config: &Config) -> Result<(), ConfigError> {
294299
.allowlist_file("(?i).*wdf.*");
295300
trace!(bindgen_builder = ?bindgen_builder);
296301

297-
// As of NI WDK, this may generate an empty file due to no non-type and non-var
298-
// items in the wdf headers(i.e. functions are all inlined). This step is
299-
// intentionally left here in case older/newer WDKs have non-inlined functions
300-
// or new WDKs may introduce non-inlined functions.
301302
Ok(bindgen_builder
302303
.generate()
303304
.expect("Bindings should succeed to generate")
@@ -347,6 +348,42 @@ fn generate_hid(out_path: &Path, config: &Config) -> Result<(), ConfigError> {
347348
}
348349
}
349350

351+
fn generate_spb(out_path: &Path, config: &Config) -> Result<(), ConfigError> {
352+
cfg_if::cfg_if! {
353+
if #[cfg(feature = "spb")] {
354+
info!("Generating bindings to WDK: spb.rs");
355+
356+
let header_contents = config.bindgen_header_contents([ApiSubset::Base, ApiSubset::Wdf, ApiSubset::Spb]);
357+
trace!(header_contents = ?header_contents);
358+
359+
let bindgen_builder = {
360+
let mut builder = bindgen::Builder::wdk_default(config)?
361+
.with_codegen_config((CodegenConfig::TYPES | CodegenConfig::VARS).complement())
362+
.header_contents("spb-input.h", &header_contents);
363+
364+
// Only allowlist files in the spb-specific files to avoid duplicate definitions
365+
for header_file in config.headers(ApiSubset::Spb)
366+
{
367+
builder = builder.allowlist_file(format!("(?i).*{header_file}.*"));
368+
}
369+
builder
370+
};
371+
trace!(bindgen_builder = ?bindgen_builder);
372+
373+
Ok(bindgen_builder
374+
.generate()
375+
.expect("Bindings should succeed to generate")
376+
.write_to_file(out_path.join("spb.rs"))?)
377+
} else {
378+
let _ = (out_path, config); // Silence unused variable warnings when spb feature is not enabled
379+
380+
info!(
381+
"Skipping spb.rs generation since spb feature is not enabled");
382+
Ok(())
383+
}
384+
}
385+
}
386+
350387
/// Generates a `wdf_function_table.rs` file in `OUT_DIR` which contains the
351388
/// definition of `WDF_FUNCTION_TABLE`. This is required to be generated here
352389
/// since the size of the table is derived from either a global symbol
@@ -516,6 +553,8 @@ fn main() -> anyhow::Result<()> {
516553
ApiSubset::Wdf,
517554
#[cfg(feature = "hid")]
518555
ApiSubset::Hid,
556+
#[cfg(feature = "spb")]
557+
ApiSubset::Spb,
519558
])
520559
.as_bytes(),
521560
)?;

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
@@ -41,6 +41,16 @@ pub mod windows;
4141
))]
4242
pub mod hid;
4343

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

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)