Skip to content

feat!: stack-based format buffer for wdk crate #611

Merged
leon-xd merged 33 commits into
microsoft:mainfrom
leon-xd:generic-stack-alloc
Apr 17, 2026
Merged

feat!: stack-based format buffer for wdk crate #611
leon-xd merged 33 commits into
microsoft:mainfrom
leon-xd:generic-stack-alloc

Conversation

@leon-xd
Copy link
Copy Markdown
Contributor

@leon-xd leon-xd commented Feb 13, 2026

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

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
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.

Copilot AI review requested due to automatic review settings February 13, 2026 00:10
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces a new fixed-size, stack-friendly formatting buffer (WdkFormatBuffer) to support heap-free formatting in driver contexts, and integrates it into the kernel print!/println! path by replacing the previous DbgPrintBufWriter implementation.

Changes:

  • Added crates/wdk/src/fmt.rs implementing WdkFormatBuffer<const T: usize = 512> with fmt::Write, plus as_str() / as_cstr() helpers and tests.
  • Updated crates/wdk/src/print.rs (WDM/KMDF path) to format into WdkFormatBuffer and call DbgPrint directly; removed the old buffering/flushing module.
  • Adjusted the KMDF sample driver to add an explicit type annotation for the WdfDriverCreate output handle pointer.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 7 comments.

File Description
examples/sample-kmdf-driver/src/lib.rs Tweaks the WdfDriverCreate out-handle variable typing.
crates/wdk/src/print.rs Switches kernel printing to WdkFormatBuffer + direct DbgPrint.
crates/wdk/src/lib.rs Adds the new fmt module and re-exports WdkFormatBuffer.
crates/wdk/src/fmt.rs New formatting buffer type, CStr/str views, and unit tests.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread crates/wdk/src/fmt.rs
Comment thread crates/wdk/src/fmt.rs Outdated
Comment thread crates/wdk/src/fmt.rs Outdated
Comment thread crates/wdk/src/fmt.rs Outdated
Comment thread crates/wdk/src/print.rs Outdated
Comment thread examples/sample-kmdf-driver/src/lib.rs Outdated
Comment thread crates/wdk/src/lib.rs
@codecov-commenter
Copy link
Copy Markdown

codecov-commenter commented Feb 13, 2026

Codecov Report

❌ Patch coverage is 91.78470% with 29 lines in your changes missing coverage. Please review.
✅ Project coverage is 78.44%. Comparing base (2940ef8) to head (bfc706d).

Files with missing lines Patch % Lines
crates/wdk/src/fmt.rs 91.78% 26 Missing and 3 partials ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #611      +/-   ##
==========================================
+ Coverage   77.47%   78.44%   +0.97%     
==========================================
  Files          24       25       +1     
  Lines        4848     5201     +353     
  Branches     4848     5201     +353     
==========================================
+ Hits         3756     4080     +324     
- Misses        975     1001      +26     
- Partials      117      120       +3     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@leon-xd leon-xd changed the title feat!: stack-based allocator for WDK crate feat!: stack-based allocator for wdk crate Feb 13, 2026
Copilot AI review requested due to automatic review settings February 19, 2026 19:04
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread crates/wdk/src/lib.rs Outdated
Comment thread crates/wdk/src/print.rs Outdated
Comment thread crates/wdk/src/fmt.rs
@leon-xd leon-xd force-pushed the generic-stack-alloc branch from 8050685 to 74a4e88 Compare February 19, 2026 19:10
Copilot AI review requested due to automatic review settings February 19, 2026 19:42
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread crates/wdk/src/print.rs Outdated
Comment thread crates/wdk/src/fmt.rs Outdated
@leon-xd leon-xd marked this pull request as ready for review February 19, 2026 22:29
Comment thread crates/wdk/src/print.rs Outdated
Comment thread crates/wdk/src/fmt.rs Outdated
Comment thread crates/wdk/src/fmt.rs Outdated
Comment thread crates/wdk/src/fmt.rs Outdated
Comment thread crates/wdk/src/fmt.rs Outdated
Comment thread crates/wdk/src/fmt.rs Outdated
Comment thread crates/wdk/src/fmt.rs
Comment thread crates/wdk/src/fmt.rs Outdated
Comment thread crates/wdk/src/fmt.rs Outdated
Comment thread crates/wdk/src/fmt.rs Outdated
Comment thread crates/wdk/src/fmt.rs
Copilot AI review requested due to automatic review settings February 25, 2026 22:34
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 5 out of 5 changed files in this pull request and generated 1 comment.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread crates/wdk/src/fmt.rs
wmmc88
wmmc88 previously approved these changes Apr 9, 2026
Comment thread crates/wdk/Cargo.toml
Comment thread crates/wdk/src/fmt.rs
Comment thread crates/wdk/src/fmt.rs
Comment thread crates/wdk/src/fmt.rs
Comment thread crates/wdk/src/fmt.rs
Comment thread examples/sample-kmdf-driver/src/lib.rs
Copilot AI review requested due to automatic review settings April 15, 2026 19:56
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated 4 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread crates/wdk/Cargo.toml
Comment thread crates/wdk/src/fmt.rs
Comment thread crates/wdk/src/fmt.rs Outdated
Comment thread crates/wdk/src/fmt.rs Outdated
Comment thread crates/wdk/src/fmt.rs Outdated
Copilot AI review requested due to automatic review settings April 16, 2026 17:46
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 6 out of 6 changed files in this pull request and generated 1 comment.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread Cargo.toml Outdated
Copilot AI review requested due to automatic review settings April 17, 2026 00:56
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 6 out of 6 changed files in this pull request and generated no new comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@leon-xd leon-xd requested review from gurry and wmmc88 April 17, 2026 01:16
@leon-xd leon-xd enabled auto-merge April 17, 2026 21:30
@leon-xd leon-xd added this pull request to the merge queue Apr 17, 2026
Merged via the queue into microsoft:main with commit 5748ea2 Apr 17, 2026
233 checks passed
@leon-xd leon-xd deleted the generic-stack-alloc branch April 17, 2026 23:55
svasista-ms pushed a commit to svasista-ms/windows-drivers-rs that referenced this pull request May 5, 2026
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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants