Skip to content

feat: add PE resource version + metadata generation#661

Open
Alan632 wants to merge 25 commits into
microsoft:mainfrom
Alan632:driver_file_versioning
Open

feat: add PE resource version + metadata generation#661
Alan632 wants to merge 25 commits into
microsoft:mainfrom
Alan632:driver_file_versioning

Conversation

@Alan632

@Alan632 Alan632 commented May 22, 2026

Copy link
Copy Markdown
Contributor

Summary

Currently driver PE resource metadata and versioning do not get populated (the version in the *.inf does) and makes issue and post-mortem troubleshooting/tracing difficult.

This PR adds the functionality to populate the PE resource metadata automatically.

wdk-build/src/lib.rs

  • Adds a new variant to ConfigError
  • Extends configure_binary_build to initiate *.rc generation, compilation to *.res, and linker directive emission

wdk-build/src/resource_compile.rs

  • Entry point via compile_version_resource called from configure_binary_build
  • Grabs the driver version from the environment variable STAMPINF_VERSION, falling back to CARGO_PKG_VERSION set by Cargo
  • Pulls other PE Property values from Cargo.toml, defaulting to Cargo environment variables if missing
  • Generates an *.rc file and runs rc.exe to compile to a *.res and emits linker directives

wdk-build/src/metadata/mod.rs

  • Changes parsing functions for wdk metadata to allow other sections to coexist in the Cargo.toml (eg. new [package.metadata.wdk.version-resource]), keeps strict serde validation of Wdk/DriverConfig (eg. [package.metadata.wdk.driver-model])
  • Adds additional unit tests

Validation

Local testing with in production driver in the following scenarios: missing version-resource metadata, populated version-resource metadata, and STAMPINF_VERSION set.

Tested with sample drivers kmdf/wdm/umdf.

WDM sample driver with [package.metadata.wdk.version-resource] info filled in:

image

UMDF sample driver without [package.metadata.wdk.version-resource] info:

image

@Alan632 Alan632 self-assigned this May 22, 2026
Copilot AI review requested due to automatic review settings May 22, 2026 23:29

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

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 adds automatic generation and compilation of Windows PE VERSIONINFO resources for driver binaries built with wdk-build, so that file version and descriptive metadata are embedded directly into the produced .sys / .dll artifacts (not just the .inf).

Changes:

  • Introduces resource_compile module to generate a .rc, compile it via rc.exe to a .res, and emit linker args to embed it into the driver binary.
  • Extends ConfigError and Config::configure_binary_build to run the version-resource compilation step during build script configuration.
  • Updates WDK metadata parsing so [package.metadata.wdk.*] sections (e.g., version-resource) can coexist while still strictly validating the driver-model configuration, plus adds unit tests.

Reviewed changes

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

File Description
crates/wdk-build/src/resource_compile.rs New module implementing version/metadata resolution, .rc generation, rc.exe invocation, and link-arg emission, with unit tests.
crates/wdk-build/src/metadata/mod.rs Narrows WDK configuration deserialization to metadata.wdk.driver-model while permitting other metadata.wdk.* sections; adds tests.
crates/wdk-build/src/lib.rs Exposes the new module, adds a ConfigError variant, and invokes resource compilation from configure_binary_build.

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

Comment thread crates/wdk-build/src/resource_compile.rs Outdated
Comment thread crates/wdk-build/src/resource_compile.rs
Comment thread crates/wdk-build/src/resource_compile.rs Dismissed
@codecov-commenter

codecov-commenter commented May 23, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 93.09665% with 70 lines in your changes missing coverage. Please review.
✅ Project coverage is 81.89%. Comparing base (21ec8f8) to head (9d1fc94).

Files with missing lines Patch % Lines
crates/wdk-build/src/resource_compile.rs 92.74% 47 Missing and 20 partials ⚠️
crates/wdk-build/src/metadata/mod.rs 96.59% 1 Missing and 2 partials ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #661      +/-   ##
==========================================
+ Coverage   79.93%   81.89%   +1.95%     
==========================================
  Files          26       27       +1     
  Lines        5633     6627     +994     
  Branches     5633     6627     +994     
==========================================
+ Hits         4503     5427     +924     
- Misses       1002     1050      +48     
- Partials      128      150      +22     

☔ View full report in Codecov by Harness.
📢 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.

…tness for different dev environment setups
Copilot AI review requested due to automatic review settings May 27, 2026 18:47

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

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 3 out of 3 changed files in this pull request and generated 4 comments.

Comment thread crates/wdk-build/src/resource_compile.rs
Comment thread crates/wdk-build/src/resource_compile.rs Outdated
Comment thread crates/wdk-build/src/resource_compile.rs Outdated
Comment thread crates/wdk-build/src/resource_compile.rs Outdated
@Alan632 Alan632 marked this pull request as ready for review May 27, 2026 20:13
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Signed-off-by: Alan632 <aln.noda7@gmail.com>
Copilot AI review requested due to automatic review settings May 27, 2026 20:59

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

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 3 out of 3 changed files in this pull request and generated 3 comments.

Comment thread crates/wdk-build/src/resource_compile.rs Outdated
Comment thread crates/wdk-build/src/resource_compile.rs
Comment thread crates/wdk-build/src/lib.rs Outdated
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Signed-off-by: Alan632 <aln.noda7@gmail.com>
Copilot AI review requested due to automatic review settings May 27, 2026 21:28

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

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 3 out of 3 changed files in this pull request and generated 3 comments.

Comment thread crates/wdk-build/src/lib.rs
Comment thread crates/wdk-build/src/resource_compile.rs
Comment thread crates/wdk-build/src/resource_compile.rs Outdated
Copilot AI review requested due to automatic review settings May 27, 2026 22:38

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

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.

Comment thread crates/wdk-build/src/resource_compile.rs
Comment thread crates/wdk-build/src/resource_compile.rs
Comment thread crates/wdk-build/src/lib.rs
…ary rerun directive (CI builds are fresh), fix formatting in .typos.toml
Copilot AI review requested due to automatic review settings June 15, 2026 17:14

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

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

Comment thread crates/wdk-build/src/resource_compile.rs
Alan632 and others added 2 commits June 22, 2026 09:58
Copilot AI review requested due to automatic review settings June 23, 2026 00:14

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

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

Comment thread crates/wdk-build/src/resource_compile.rs
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Signed-off-by: Alan632 <aln.noda7@gmail.com>
Copilot AI review requested due to automatic review settings June 23, 2026 00:45

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

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.

Comment thread crates/wdk-build/src/resource_compile.rs Outdated
Comment thread crates/wdk-build/src/resource_compile.rs Outdated
// Invoke rc.exe (expected to be on PATH via eWDK prompt or cargo-wdk setup)
let include_paths = resource_include_paths(config)?;

let mut cmd = Command::new("rc.exe");

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Was it an intentional choice not to use pre-existing crates for RC file generation and compilation, such as winresource, winres, or embed_resource, or were there other reasons?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

It wasn't an intentional choice not to use an existing crate, just something carried over after looking at someone else's previous work (#243).

From my quick look it looks like winresource supersedes winres (winres doesn't support Rust >= v1.61). I think the benefit winresource brings is it handles the .rc file content generation automatically but we would still need the toolchain/resource path creation for it. And, embed_resource requires both (it needs a pre-generated .rc file). I'll take a further look into these crates but initially I'm thinking the extra complexity with integrating them doesn't gain us that much compared with the extra dependencies we'd pull in?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

just chiming in here. When I assigned this to Alan, I did intentionally tell Alan that the existing crates I surveyed previously either had long-standing bugs that affected their reliability, were unmaintained, or otherwise did not satisfy our requirements. Our goal here is to piggy-back off our existing metadata configuration system to avoid needing to manually an rc file that duplicates information we've provided elsewhere.

Alan Ngo added 2 commits June 23, 2026 17:10
- add a handler to deal with multiple authors cleanly
- move env_var_non_empty to utils.rs
- fix a cyclic error types with ResourceCompileError
Copilot AI review requested due to automatic review settings June 29, 2026 17:53

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

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.

Comment on lines +1399 to +1402
fn create_include_subdirectories(include_directory: &Path, subdirectories: &[&str]) {
for subdirectory in subdirectories {
fs::create_dir_all(include_directory.join(subdirectory)).unwrap();
}
Comment thread .typos.toml
[files]
extend-exclude = ["**/Cargo.lock", "**/target/**"]

# Allowlist short words that collide with the typos dictionary but are

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

nit: scope this down as much as possible since this could be a common typo. Something like this could work:

[type.resource_compile]
extend-glob = ["resource_compile.rs"]
extend-words = {
	# rc.exe /fo (output file) switch
	fo = "fo"
}

// Invoke rc.exe (expected to be on PATH via eWDK prompt or cargo-wdk setup)
let include_paths = resource_include_paths(config)?;

let mut cmd = Command::new("rc.exe");

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

just chiming in here. When I assigned this to Alan, I did intentionally tell Alan that the existing crates I surveyed previously either had long-standing bugs that affected their reliability, were unmaintained, or otherwise did not satisfy our requirements. Our goal here is to piggy-back off our existing metadata configuration system to avoid needing to manually an rc file that duplicates information we've provided elsewhere.

/// `CARGO_PKG_VERSION` env var (emitted by cargo)
/// if env var is not present or empty.
fn resolve_version() -> Result<DriverVersion, ResourceCompileError> {
let version_str = env_var_non_empty(VERSION_ENV_VAR).map_or_else(

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

VERSION_ENV_VAR corresponds with STAMPINF_VERSION that was previously added in order to get around cargo-wdk currently not having a flexible customization system. That system is being developed right now. I think perhaps we should avoid tying more functionality to that temporary workaround.

for (macro_name, macro_value) in [
("VER_FILEDESCRIPTION_STR", format!("\"{file_description}\"")),
("VER_PRODUCTNAME_STR", format!("\"{product_name}\"")),
("VER_FILEVERSION", version.as_rc_numeric()),

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

What about PRODUCTVERSION? do both get set by default in a C driver?

DriverConfig::Umdf(_) => ("VFT_DLL", "VFT2_UNKNOWN"),
};

let mut rc = String::with_capacity(1024);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Since you're writing into a string anyways, I think this chunk would be a lot more readable and easier to grok the RC file contents if it did a template with string replacement similar to

static CALL_UNSAFE_WDF_BINDING_TEMPLATE: LazyLock<String> = LazyLock::new(|| {
.


let rc = generate_rc_content(version, &metadata, &config);

assert!(rc.contains("#pragma code_page(65001)"));

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Not necessarily required for this PR to merge, but I think some snapshot testing here would be better since the output is fairly complex. It would be worth looking into insta or snapbox

@@ -0,0 +1,1645 @@
// Copyright (c) Microsoft Corporation

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I think there should be an integration test asserting the version derived here matches the version in the inf. You can probably add that test coverage by piggybacking on some of the existing integration tests in cargo-wdk

fn resolve_version() -> Result<DriverVersion, ResourceCompileError> {
let version_str = env_var_non_empty(VERSION_ENV_VAR).map_or_else(
|| {
env::var("CARGO_PKG_VERSION").map_err(|_| ResourceCompileError::MetadataError {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

what is the current behavior here if there is not version defined (since cargo made version field optional)? Does it error out or does it default to 0.0.0?

Copilot AI review requested due to automatic review settings July 6, 2026 21:08

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

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.

Comment on lines +300 to +306
let metadata = cargo_metadata::MetadataCommand::new()
.manifest_path(&manifest_path)
.no_deps()
.exec()
.map_err(|e| ResourceCompileError::MetadataError {
detail: format!("cargo metadata failed: {e}"),
})?;
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