Skip to content

Commit

Permalink
feat: add support for Storage API subset in wdk-sys (#287)
Browse files Browse the repository at this point in the history
  • Loading branch information
wmmc88 authored Feb 6, 2025
1 parent e321c95 commit 8696928
Show file tree
Hide file tree
Showing 8 changed files with 127 additions and 1 deletion.
33 changes: 33 additions & 0 deletions crates/wdk-build/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,8 @@ pub enum ApiSubset {
Hid,
/// API subset for SPB (Serial Peripheral Bus) drivers: <https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/_spb/>
Spb,
/// API subset for Storage drivers: <https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/_storage/>
Storage,
}

impl Default for Config {
Expand Down Expand Up @@ -684,6 +686,37 @@ impl Config {

spb_headers
}
ApiSubset::Storage => {
let mut storage_headers = vec![
"ehstorioctl.h",
"ntddcdrm.h",
"ntddcdvd.h",
"ntdddisk.h",
"ntddmmc.h",
"ntddscsi.h",
"ntddstor.h",
"ntddtape.h",
"ntddvol.h",
"ufs.h",
];

if let DriverConfig::Wdm | DriverConfig::Kmdf(_) = self.driver_config {
storage_headers.extend([
"mountdev.h",
"mountmgr.h",
"ntddchgr.h",
"ntdddump.h",
"storduid.h",
"storport.h",
]);
}

if let DriverConfig::Kmdf(_) = self.driver_config {
storage_headers.extend(["ehstorbandmgmt.h"]);
}

storage_headers
}
}
.into_iter()
.map(std::string::ToString::to_string)
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 @@ -37,6 +37,7 @@ default = []

hid = []
spb = []
storage = []

nightly = ["wdk-macros/nightly"]
test-stubs = []
Expand Down
44 changes: 44 additions & 0 deletions crates/wdk-sys/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@ const BINDGEN_FILE_GENERATORS_TUPLES: &[(&str, GenerateFn)] = &[
("wdf.rs", generate_wdf),
("hid.rs", generate_hid),
("spb.rs", generate_spb),
("storage.rs", generate_storage),
];

fn initialize_tracing() -> Result<(), ParseError> {
Expand Down Expand Up @@ -199,6 +200,8 @@ fn generate_constants(out_path: &Path, config: &Config) -> Result<(), ConfigErro
ApiSubset::Hid,
#[cfg(feature = "spb")]
ApiSubset::Spb,
#[cfg(feature = "storage")]
ApiSubset::Storage,
]);
trace!(header_contents = ?header_contents);

Expand All @@ -223,6 +226,8 @@ fn generate_types(out_path: &Path, config: &Config) -> Result<(), ConfigError> {
ApiSubset::Hid,
#[cfg(feature = "spb")]
ApiSubset::Spb,
#[cfg(feature = "storage")]
ApiSubset::Storage,
]);
trace!(header_contents = ?header_contents);

Expand Down Expand Up @@ -358,6 +363,45 @@ fn generate_spb(out_path: &Path, config: &Config) -> Result<(), ConfigError> {
}
}

fn generate_storage(out_path: &Path, config: &Config) -> Result<(), ConfigError> {
cfg_if::cfg_if! {
if #[cfg(feature = "storage")] {
info!("Generating bindings to WDK: storage.rs");

let header_contents = config.bindgen_header_contents([
ApiSubset::Base,
ApiSubset::Wdf,
ApiSubset::Storage,
]);
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("storage-input.h", &header_contents);

// Only allowlist files in the storage-specific files to avoid
// duplicate definitions
for header_file in config.headers(ApiSubset::Storage) {
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("storage.rs"))?)
} else {
let _ = (out_path, config); // Silence unused variable warnings when storage feature is not enabled

info!("Skipping storage.rs generation since storage feature is not enabled");
Ok(())
}
}
}

/// Generates a `wdf_function_count.rs` file in `OUT_DIR` which contains the
/// definition of the function `get_wdf_function_count()`. This is required to
/// be generated here since the size of the table is derived from either a
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 @@ -49,6 +49,16 @@ pub mod hid;
))]
pub mod spb;

#[cfg(all(
any(
driver_model__driver_type = "WDM",
driver_model__driver_type = "KMDF",
driver_model__driver_type = "UMDF"
),
feature = "storage"
))]
pub mod storage;

#[cfg(feature = "test-stubs")]
pub mod test_stubs;

Expand Down
36 changes: 36 additions & 0 deletions crates/wdk-sys/src/storage.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// Copyright (c) Microsoft Corporation
// License: MIT OR Apache-2.0

//! Direct FFI bindings to Storage APIs from the Windows Driver Kit (WDK)
//!
//! This module contains all bindings to functions, constants, methods,
//! constructors and destructors for Storage headers. 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 configurations of the WDK (ex. UMDF), there are no functions related \
to Storage that can be generated by bindgen, so these types are unused"
)]
use crate::types::*;

include!(concat!(env!("OUT_DIR"), "/storage.rs"));
}
#[allow(
unused_imports,
reason = "in certain configurations of the WDK (ex. UMDF), there are no functions related to \
Storage that can be generated by bindgen, so the `bindings` module is empty"
)]
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 @@ -34,6 +34,7 @@ default = []

hid = ["wdk-sys/hid"]
spb = ["wdk-sys/spb"]
storage = ["wdk-sys/storage"]

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 @@ -32,6 +32,7 @@ default = []

hid = ["wdk-sys/hid"]
spb = ["wdk-sys/spb"]
storage = ["wdk-sys/storage"]

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

Expand Down
2 changes: 1 addition & 1 deletion examples/sample-wdm-driver/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,12 @@ wdk = { path = "../../crates/wdk", version = "0.3.0" }
wdk-panic = { path = "../../crates/wdk-panic", version = "0.3.0" }
wdk-sys = { path = "../../crates/wdk-sys", version = "0.3.0" }


[features]
default = []

hid = ["wdk-sys/hid"]
spb = ["wdk-sys/spb"]
storage = ["wdk-sys/storage"]

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

Expand Down

0 comments on commit 8696928

Please sign in to comment.