Skip to content

Commit 5748ea2

Browse files
leon-xdleon-xdCopilot
authored
feat!: stack-based format buffer for wdk crate (#611)
Adds and integrates `wdk::fmt::FormatBuffer`. ## Summary - Introduced `crates/wdk/src/fmt.rs` with a public `wdk::fmt` module containing two types: - `FormatBuffer<N>` — a fixed-size, stack-allocated formatting buffer implementing `fmt::Write` - `FlushableFormatBuffer<F, N>` — a wrapper that auto-flushes via closure on overflow and on drop - Swapped `print.rs` WDM/KMDF path to use `FlushableFormatBuffer` instead of `DbgPrintBufWriter`; removed that module and its tests. - Turns the `alloc` feature from the `wdk` crate into a no-op — it had no remaining uses after the stack-buffer migration. Avoids removal of feature to prevent a breaking change - Bumps MSRV from 1.85 to 1.91 due to use of [`str::char_floor_boundary`](https://doc.rust-lang.org/core/primitive.str.html#method.floor_char_boundary) ## Details - `FormatBuffer<N>` stores a zero-initialized `[u8; N]` and tracks `used` bytes. The last byte is reserved for a NUL terminator, so usable capacity is `N - 1`. `N` must be at least 2; smaller values will not compile (`const { assert!(N >= 2) }`). - All buffer mutations go through a single `append_bytes` helper that copies data and sets `buffer[used] = 0`, centralizing the NUL terminator invariant. - `as_str()` returns an infallible UTF-8 view — only valid UTF-8 enters via `write_str` (both `FormatBuffer::write_str` and `FlushableFormatBuffer::write_str` copy from `&str` sources). - `as_c_str()` returns a `&CStr` view up to the first NUL. Infallible in practice since the NUL invariant is always maintained. - `fmt::Write` clamps overflow writes at a UTF-8 char boundary via `floor_char_boundary` and signals truncation via `fmt::Error`. - `FlushableFormatBuffer<F, N>` wraps `FormatBuffer` and auto-flushes via a closure when the buffer fills. Remaining content is flushed on drop. This allows arbitrarily long formatted output to be processed in fixed-size chunks. - `print.rs` WDM/KMDF path now formats into `FlushableFormatBuffer<_, 512>` and calls `DbgPrint` via `%s` using the resulting `CStr`. - Removed the `alloc` feature gate from the WDM/KMDF print path — `print!`/`println!` no longer require heap allocation and work at any IRQL where `DbgPrint` is valid. - Custom `Debug` impl on `FormatBuffer` shows only the used content, not stale bytes after `clear()`. ## Testing 29 tests covering: - basic write, `as_str()`, `as_c_str()` usage - overflow, multi-write, and exact-fit scenarios - empty writes and min-sized buffers (`N = 2`) - clear-then-shorter-write regression (NUL terminator correctness) - multi-byte UTF-8 char boundary handling in both buffer types - explicit `flush()` mid-stream and flush-on-drop - interior NUL truncation via `as_c_str()` - `compile_fail` doctest for `N < 2` ```pwsh cargo test --package wdk --lib --all-features -- fmt --nocapture ``` ## Notes / Follow-ups - `_print` ignores `fmt::write` errors — partial output is acceptable for debug printing. Errors from individual `Display` impls are silently dropped. - The old `DbgPrintBufWriter` stripped interior NUL bytes and continued printing. The new WDM/KMDF path truncates each chunk at the first NUL (via `as_c_str`). UMDF still strips NULs and prints the remainder. --------- Signed-off-by: Leon Durrenberger <leon.durrenberger@gmail.com> Co-authored-by: leon-xd <leondu@microsoft.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
1 parent 2940ef8 commit 5748ea2

6 files changed

Lines changed: 713 additions & 437 deletions

File tree

AGENTS.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ cargo make wdk-pre-commit-flow
8787
- **FFI naming:** Bindings in `wdk-sys` retain their original C names and style (e.g., PascalCase functions). Safe Rust wrappers in `wdk` follow [Rust naming conventions (RFC 430)](https://rust-lang.github.io/api-guidelines/naming.html).
8888
- **Formatting:** `rustfmt` uses nightly-only unstable options (see `rustfmt.toml`). Import grouping is `StdExternalCrate`, granularity is `Crate`.
8989
- **Lints:** Clippy `all` is deny, `pedantic`/`nursery`/`cargo` are warn. Most workspace members inherit `[lints] workspace = true`; `wdk-sys`, `wdk-build`, `wdk-macros`, and `cargo-wdk` define their own `[lints]` tables instead (Cargo currently does not support both inheriting workspace lints and selectively overriding them per crate).
90-
- **Edition:** 2024, MSRV 1.85.0, resolver v3.
90+
- **Edition:** 2024, MSRV 1.91.0, resolver v3.
9191
- **Static CRT:** Enabled globally via `.cargo/config.toml` (`-C target-feature=+crt-static`).
9292
- **Spelling:** `typos` is configured in `.typos.toml`; Windows API identifiers are allowlisted rather than using file-level excludes.
9393
- **TOML:** `taplo` uses CRLF line endings (see `taplo.toml`).

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ edition = "2024"
1919
license = "MIT OR Apache-2.0"
2020
readme = "README.md"
2121
repository = "https://github.com/microsoft/windows-drivers-rs"
22-
rust-version = "1.85.0"
22+
rust-version = "1.91.0"
2323

2424
[workspace.dependencies]
2525
# Workspace Crates

crates/wdk/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@ readme.workspace = true
1717
repository.workspace = true
1818

1919
[features]
20+
# Deprecated: no longer required. Kept as a no-op for backward compatibility.
2021
alloc = []
21-
default = ["alloc"]
2222
nightly = ["wdk-sys/nightly"]
2323

2424
[dependencies]

0 commit comments

Comments
 (0)