Skip to content

Commit 1e7ef94

Browse files
committed
feat: add bindings for network driver headers (WFP only)
1 parent 723a4eb commit 1e7ef94

7 files changed

Lines changed: 103 additions & 3 deletions

File tree

crates/wdk-build/src/bindgen.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,9 @@ impl BuilderExt for Builder {
131131
.blocklist_item(".*USBDEVICE_ABORTIO")
132132
.blocklist_item(".*USBDEVICE_STARTIO")
133133
.blocklist_item(".*USBDEVICE_TREE_PURGEIO")
134+
// FIXME: bindgen unable to generate nameless fields
135+
.blocklist_item(".*NET_BUFFER_HEADER")
136+
.blocklist_item(".*NDIS_OPEN_BLOCK")
134137
// FIXME: arrays with more than 32 entries currently fail to generate a `Default`` impl: https://github.com/rust-lang/rust-bindgen/issues/2803
135138
.no_default(".*tagMONITORINFOEXA")
136139
.must_use_type("NTSTATUS")
@@ -152,6 +155,8 @@ impl BuilderExt for Builder {
152155
builder = builder.opaque_type("_USBPM_CLIENT_CONFIG_EXTRA_INFO");
153156
}
154157

158+
builder = builder.wrap_unsafe_ops(true);
159+
155160
Ok(builder)
156161
}
157162
}

crates/wdk-build/src/lib.rs

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -335,6 +335,8 @@ pub enum ApiSubset {
335335
Storage,
336336
/// API subset for USB (Universal Serial Bus) drivers: <https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/_usbref/>
337337
Usb,
338+
/// API subset for network drivers: <https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/_netvista/>
339+
Network,
338340
}
339341

340342
#[derive(Debug, Error, PartialEq, Eq)]
@@ -687,21 +689,25 @@ impl Config {
687689
// ]
688690
// .into_iter()
689691
// .map(|(key, value)| (key.to_string(), value.map(|v| v.to_string())))
692+
let mut defs = vec![("NDIS_SUPPORT_NDIS6", None)];
693+
690694
match self.cpu_architecture {
691695
// Definitions sourced from `Program Files\Windows
692696
// Kits\10\build\10.0.22621.0\WindowsDriver.x64.props`
693697
CpuArchitecture::Amd64 => {
694-
vec![("_WIN64", None), ("_AMD64_", None), ("AMD64", None)]
698+
defs.extend([("_WIN64", None), ("_AMD64_", None), ("AMD64", None)]);
699+
defs
695700
}
696701
// Definitions sourced from `Program Files\Windows
697702
// Kits\10\build\10.0.22621.0\WindowsDriver.arm64.props`
698703
CpuArchitecture::Arm64 => {
699-
vec![
704+
defs.extend([
700705
("_ARM64_", None),
701706
("ARM64", None),
702707
("_USE_DECLSPECS_FOR_SAL", Some(1)),
703708
("STD_CALL", None),
704-
]
709+
]);
710+
defs
705711
}
706712
}
707713
.into_iter()
@@ -816,6 +822,7 @@ impl Config {
816822
ApiSubset::Wdf => self.wdf_headers(),
817823
ApiSubset::Gpio => self.gpio_headers(),
818824
ApiSubset::Hid => self.hid_headers(),
825+
ApiSubset::Network => self.network_headers(),
819826
ApiSubset::ParallelPorts => self.parallel_ports_headers(),
820827
ApiSubset::Spb => self.spb_headers(),
821828
ApiSubset::Storage => self.storage_headers(),
@@ -994,6 +1001,11 @@ impl Config {
9941001
Ok(headers)
9951002
}
9961003

1004+
#[tracing::instrument(level = "trace")]
1005+
fn network_headers(&self) -> Vec<&'static str> {
1006+
vec!["ndis.h", "Fwpmk.h", "Fwpsk.h"]
1007+
}
1008+
9971009
/// Determines whether to include the ufxclient.h header based on the Clang
9981010
/// version used by bindgen.
9991011
///
@@ -1167,6 +1179,8 @@ impl Config {
11671179
println!("cargo::rustc-link-lib=static=wmilib");
11681180
println!("cargo::rustc-link-lib=static=WdfLdr");
11691181
println!("cargo::rustc-link-lib=static=WdfDriverEntry");
1182+
println!("cargo::rustc-link-lib=static=Fwpkclnt");
1183+
println!("cargo::rustc-link-lib=static=netio");
11701184

11711185
// Emit ARM64-specific libraries to link to derived from
11721186
// WindowsDriver.arm64.props

crates/wdk-sys/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ parallel-ports = ["gpio"]
2525
spb = []
2626
storage = []
2727
usb = []
28+
network = []
2829

2930
nightly = ["wdk-macros/nightly", "wdk-build/nightly"]
3031
test-stubs = []

crates/wdk-sys/build.rs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,8 @@ const ENABLED_API_SUBSETS: &[ApiSubset] = &[
145145
ApiSubset::Storage,
146146
#[cfg(feature = "usb")]
147147
ApiSubset::Usb,
148+
#[cfg(feature = "network")]
149+
ApiSubset::Network,
148150
];
149151

150152
type GenerateFn = fn(&Path, &Config) -> Result<(), ConfigError>;
@@ -165,6 +167,8 @@ const BINDGEN_FILE_GENERATORS_TUPLES: &[(&str, GenerateFn)] = &[
165167
("storage.rs", generate_storage),
166168
#[cfg(feature = "usb")]
167169
("usb.rs", generate_usb),
170+
#[cfg(feature = "network")]
171+
("network.rs", generate_network),
168172
];
169173

170174
fn initialize_tracing() -> Result<(), ParseError> {
@@ -495,6 +499,36 @@ fn generate_usb(out_path: &Path, config: &Config) -> Result<(), ConfigError> {
495499
.map_err(|source| IoError::with_path(output_file_path, source))?)
496500
}
497501

502+
#[cfg(feature = "network")]
503+
fn generate_network(out_path: &Path, config: &Config) -> Result<(), ConfigError> {
504+
info!("Generating bindings to WDK: network.rs");
505+
506+
let header_contents =
507+
config.bindgen_header_contents([ApiSubset::Base, ApiSubset::Wdf, ApiSubset::Network])?;
508+
trace!(header_contents = ?header_contents);
509+
510+
let bindgen_builder = {
511+
let mut builder = bindgen::Builder::wdk_default(config)?
512+
.with_codegen_config((CodegenConfig::TYPES | CodegenConfig::VARS).complement())
513+
.header_contents("network.h", &header_contents);
514+
515+
// Only allowlist files in the network-specific files to avoid
516+
// duplicate definitions
517+
for header_file in config.headers(ApiSubset::Network)? {
518+
builder = builder.allowlist_file(format!("(?i).*{header_file}.*"));
519+
}
520+
builder
521+
};
522+
trace!(bindgen_builder = ?bindgen_builder);
523+
524+
let output_file_path = out_path.join("network.rs");
525+
Ok(bindgen_builder
526+
.generate()
527+
.expect("Bindings should succeed to generate")
528+
.write_to_file(&output_file_path)
529+
.map_err(|source| IoError::with_path(output_file_path, source))?)
530+
}
531+
498532
/// Generates a `wdf_function_count.rs` file in `OUT_DIR` which contains the
499533
/// definition of the function `get_wdf_function_count()`. This is required to
500534
/// be generated here since the size of the table is derived from either a

crates/wdk-sys/src/lib.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,16 @@ pub mod storage;
8989
))]
9090
pub mod usb;
9191

92+
#[cfg(all(
93+
any(
94+
driver_model__driver_type = "WDM",
95+
driver_model__driver_type = "KMDF",
96+
driver_model__driver_type = "UMDF"
97+
),
98+
feature = "network"
99+
))]
100+
pub mod network;
101+
92102
#[cfg(feature = "test-stubs")]
93103
pub mod test_stubs;
94104

crates/wdk-sys/src/network.rs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
//! Direct FFI bindings to network APIs from the Windows Driver Kit (WDK)
2+
//!
3+
//! This module contains all bindings for network headers. Types are not
4+
//! included in this module, but are available in the top-level `wdk_sys`
5+
//! module.
6+
#[allow(
7+
missing_docs,
8+
reason = "most items in the WDK headers have no inline documentation, so bindgen is unable to \
9+
generate documentation for their bindings"
10+
)]
11+
#[allow(clippy::derive_partial_eq_without_eq)]
12+
#[allow(non_camel_case_types)]
13+
#[allow(non_snake_case)]
14+
#[allow(non_upper_case_globals)]
15+
#[allow(unnecessary_transmutes)]
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+
use crate::types::*;
24+
25+
include!(concat!(env!("OUT_DIR"), "/network.rs"));
26+
}
27+
28+
pub use bindings::*;

crates/wdk-sys/src/types.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,5 +69,13 @@ pub use bindings::*;
6969
#[allow(clippy::useless_transmute)]
7070
#[allow(clippy::use_self)]
7171
mod bindings {
72+
#[cfg(feature = "network")]
73+
pub union _NET_BUFFER_HEADER {
74+
pub NetBufferData: NET_BUFFER_DATA,
75+
pub Link: SLIST_HEADER,
76+
}
77+
#[cfg(feature = "network")]
78+
pub type NET_BUFFER_HEADER = _NET_BUFFER_HEADER;
79+
7280
include!(concat!(env!("OUT_DIR"), "/types.rs"));
7381
}

0 commit comments

Comments
 (0)