Skip to content
Merged
Show file tree
Hide file tree
Changes from 30 commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
0b755a5
Migration to Rust 2024
Aug 1, 2025
ed382b4
Recommented driver configuration
Aug 1, 2025
e5cf361
removed check on save blocker in vscode config
Aug 1, 2025
4f3bb02
Addressed comments
Aug 4, 2025
a2ae1c0
ran formatter
Aug 4, 2025
a5be482
fixed doc test issues
Aug 4, 2025
1db477b
Migration to Rust 2024
Aug 1, 2025
7d15f1d
Recommented driver configuration
Aug 1, 2025
0f6414d
removed check on save blocker in vscode config
Aug 1, 2025
8475b4a
Addressed comments
Aug 4, 2025
0b420a4
ran formatter
Aug 4, 2025
a4e0f09
fixed import in cargo_make.rs
Aug 5, 2025
3dce48e
resolve merge conflicts
Aug 5, 2025
f27ceab
correct merge
Sep 30, 2025
3b43728
target detection instead of host detection
Oct 7, 2025
18858d1
added rest of safety comments
Oct 8, 2025
177b8fb
fmt, build working
Oct 8, 2025
7818441
complete merge
Oct 8, 2025
476a597
additional lockfile
Oct 8, 2025
79608e3
fixed compile_error string
Oct 8, 2025
8b2bbb5
fixed failing tests
Oct 9, 2025
893002b
fix expanded macro
Oct 9, 2025
5ea1137
added commas to macrotest output
Oct 9, 2025
0cb1df7
updated nightly macro expansion tests
Oct 9, 2025
7cf8289
Apply suggestion from @Copilot
leon-xd Oct 9, 2025
0e7f74b
Apply suggestion from @Copilot
leon-xd Oct 9, 2025
17b05c3
Merge branch 'main' into update-rust-2024
leon-xd Oct 9, 2025
b98407b
Completed merge
Oct 14, 2025
27458c2
Updated safety comments
Oct 14, 2025
0d811d5
added cfg guard for safe_env_vars tests
Oct 14, 2025
8ca4e00
Update crates/wdk/src/wdf/timer.rs
leon-xd Oct 14, 2025
5c4ae9e
Removed accidental copied files
Oct 14, 2025
c54587c
Restore symbolic links in wdk-macros-tests from commit 17b05c3
Oct 15, 2025
cdb0c0c
Update crates/cargo-wdk/tests/test_utils/mod.rs
leon-xd Oct 15, 2025
86b9399
Update crates/wdk-build/src/utils.rs
leon-xd Oct 15, 2025
a37a004
Update crates/cargo-wdk/src/test_utils.rs
leon-xd Oct 15, 2025
9865b24
reverted all to_string functions to shorter path
Oct 15, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,9 +87,10 @@ That's it! Thank you for your contribution!

The following tools should be installed as a part of the `windows-drivers-rs` developer workflow:

* `cargo-expand`: `cargo install --locked cargo-expand --version 1.0.85`
* `cargo-audit`: `cargo install --locked cargo-audit`
* `cargo-expand`: `cargo install --locked cargo-expand --version 1.0.85`
* `cargo-machete`: `cargo install --locked cargo-machete`
* `cargo-sort`: `cargo install --locked cargo-sort`
* `taplo-cli`: `cargo install --locked taplo-cli`
* `typos-cli`: `cargo install --locked typos-cli`

Expand Down
4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ exclude = [
resolver = "3"

[workspace.package]
edition = "2021"
rust-version = "1.84.0"
edition = "2024"
rust-version = "1.85.0"
repository = "https://github.com/microsoft/windows-drivers-rs"
readme = "README.md"
license = "MIT OR Apache-2.0"
Expand Down
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,9 @@ The crates in this repository are available from [`crates.io`](https://crates.io
PCUNICODE_STRING,
};

#[export_name = "DriverEntry"] // WDF expects a symbol with the name DriverEntry
// SAFETY: "DriverEntry" is the required symbol name for Windows driver entry points.
// No other function in this compilation unit exports this name, preventing symbol conflicts.
#[unsafe(export_name = "DriverEntry")] // WDF expects a symbol with the name DriverEntry
pub unsafe extern "system" fn driver_entry(
driver: PDRIVER_OBJECT,
registry_path: PCUNICODE_STRING,
Expand Down
2 changes: 1 addition & 1 deletion crates/cargo-wdk/src/actions/build/build_task.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use tracing::debug;
#[double]
use crate::providers::exec::CommandExec;
use crate::{
actions::{build::error::BuildTaskError, to_target_triple, Profile, TargetArch},
actions::{Profile, TargetArch, build::error::BuildTaskError, to_target_triple},
trace,
};

Expand Down
4 changes: 2 additions & 2 deletions crates/cargo-wdk/src/actions/build/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ mod package_task;
#[cfg(test)]
mod tests;
use std::{
path::{absolute, Path, PathBuf},
path::{Path, PathBuf, absolute},
result::Result::Ok,
};

Expand All @@ -26,7 +26,7 @@ use package_task::{PackageTask, PackageTaskParams};
use tracing::{debug, error as err, info, warn};
use wdk_build::metadata::{TryFromCargoMetadataError, Wdk};

use crate::actions::{to_target_triple, Profile, TargetArch};
use crate::actions::{Profile, TargetArch, to_target_triple};
#[double]
use crate::providers::{exec::CommandExec, fs::Fs, metadata::Metadata, wdk_build::WdkBuild};

Expand Down
50 changes: 25 additions & 25 deletions crates/cargo-wdk/src/actions/build/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ use cargo_metadata::Metadata as CargoMetadata;
use mockall::predicate::eq;
use mockall_double::double;
use wdk_build::{
metadata::{TryFromCargoMetadataError, Wdk},
CpuArchitecture,
DriverConfig,
metadata::{TryFromCargoMetadataError, Wdk},
};

#[double]
Expand All @@ -28,10 +28,10 @@ use crate::providers::{
};
use crate::{
actions::{
build::{BuildAction, BuildActionError, BuildActionParams},
to_target_triple,
Profile,
TargetArch,
build::{BuildAction, BuildActionError, BuildActionParams},
to_target_triple,
},
providers::error::{CommandError, FileError},
};
Expand Down Expand Up @@ -139,8 +139,8 @@ pub fn given_a_driver_project_when_target_arch_is_arm64_then_it_builds_successfu
}

#[test]
pub fn given_a_driver_project_when_profile_is_release_and_target_arch_is_arm64_then_it_builds_successfully(
) {
pub fn given_a_driver_project_when_profile_is_release_and_target_arch_is_arm64_then_it_builds_successfully()
{
// Input CLI args
let cwd = PathBuf::from("C:\\tmp");
let profile = Some(Profile::Release);
Expand Down Expand Up @@ -781,8 +781,8 @@ pub fn given_a_driver_project_when_infverif_command_execution_fails_then_package
}

#[test]
pub fn given_a_non_driver_project_when_default_values_are_provided_with_no_wdk_metadata_are_provided_then_build_should_be_successful(
) {
pub fn given_a_non_driver_project_when_default_values_are_provided_with_no_wdk_metadata_are_provided_then_build_should_be_successful()
{
// Input CLI args
let cwd = PathBuf::from("C:\\tmp");
let profile = None;
Expand Down Expand Up @@ -811,8 +811,8 @@ pub fn given_a_non_driver_project_when_default_values_are_provided_with_no_wdk_m
}

#[test]
pub fn given_a_invalid_driver_project_with_partial_wdk_metadata_when_valid_default_values_are_provided_then_wdk_metadata_parse_should_fail(
) {
pub fn given_a_invalid_driver_project_with_partial_wdk_metadata_when_valid_default_values_are_provided_then_wdk_metadata_parse_should_fail()
{
// Input CLI args
let cwd = PathBuf::from("C:\\tmp\\sample-driver");
let profile = None;
Expand Down Expand Up @@ -851,8 +851,8 @@ pub fn given_a_invalid_driver_project_with_partial_wdk_metadata_when_valid_defau
/// Workspace tests
////////////////////////////////////////////////////////////////////////////////
#[test]
pub fn given_a_workspace_with_multiple_driver_and_non_driver_projects_when_default_values_are_provided_then_it_packages_successfully(
) {
pub fn given_a_workspace_with_multiple_driver_and_non_driver_projects_when_default_values_are_provided_then_it_packages_successfully()
{
// Input CLI args
let cwd = PathBuf::from("C:\\tmp");
let profile = None;
Expand Down Expand Up @@ -923,8 +923,8 @@ pub fn given_a_workspace_with_multiple_driver_and_non_driver_projects_when_defau
}

#[test]
pub fn given_a_workspace_with_multiple_driver_and_non_driver_projects_when_cwd_is_driver_project_then_it_packages_driver_project_successfully(
) {
pub fn given_a_workspace_with_multiple_driver_and_non_driver_projects_when_cwd_is_driver_project_then_it_packages_driver_project_successfully()
{
// Input CLI args
let workspace_root_dir = PathBuf::from("C:\\tmp");
let cwd = workspace_root_dir.join("sample-kmdf-1");
Expand Down Expand Up @@ -1011,8 +1011,8 @@ pub fn given_a_workspace_with_multiple_driver_and_non_driver_projects_when_cwd_i
}

#[test]
pub fn given_a_workspace_with_multiple_driver_and_non_driver_projects_when_verify_signature_is_false_then_it_skips_verify_tasks(
) {
pub fn given_a_workspace_with_multiple_driver_and_non_driver_projects_when_verify_signature_is_false_then_it_skips_verify_tasks()
{
// Input CLI args
let cwd = PathBuf::from("C:\\tmp");
let profile = None;
Expand Down Expand Up @@ -1083,8 +1083,8 @@ pub fn given_a_workspace_with_multiple_driver_and_non_driver_projects_when_verif
}

#[test]
pub fn given_a_workspace_with_multiple_driver_and_non_driver_projects_when_cwd_is_non_driver_project_then_it_builds_but_skips_packaging(
) {
pub fn given_a_workspace_with_multiple_driver_and_non_driver_projects_when_cwd_is_non_driver_project_then_it_builds_but_skips_packaging()
{
// Input CLI args
let workspace_root_dir = PathBuf::from("C:\\tmp");
let cwd = workspace_root_dir.join("non-driver");
Expand Down Expand Up @@ -1147,8 +1147,8 @@ pub fn given_a_workspace_with_multiple_driver_and_non_driver_projects_when_cwd_i
}

#[test]
pub fn given_a_workspace_with_multiple_distinct_wdk_configurations_at_each_workspace_member_level_when_default_values_are_provided_then_wdk_metadata_parse_should_fail(
) {
pub fn given_a_workspace_with_multiple_distinct_wdk_configurations_at_each_workspace_member_level_when_default_values_are_provided_then_wdk_metadata_parse_should_fail()
{
// Input CLI args
let cwd = PathBuf::from("C:\\tmp");
let profile = None;
Expand Down Expand Up @@ -1214,8 +1214,8 @@ pub fn given_a_workspace_with_multiple_distinct_wdk_configurations_at_each_works
}

#[test]
pub fn given_a_workspace_with_multiple_distinct_wdk_configurations_at_root_and_workspace_member_level_when_default_values_are_provided_then_wdk_metadata_parse_should_fail(
) {
pub fn given_a_workspace_with_multiple_distinct_wdk_configurations_at_root_and_workspace_member_level_when_default_values_are_provided_then_wdk_metadata_parse_should_fail()
{
// Input CLI args
let cwd = PathBuf::from("C:\\tmp");
let profile = None;
Expand Down Expand Up @@ -1281,8 +1281,8 @@ pub fn given_a_workspace_with_multiple_distinct_wdk_configurations_at_root_and_w
}

#[test]
pub fn given_a_workspace_only_with_non_driver_projects_when_cwd_is_workspace_root_then_build_should_be_successful(
) {
pub fn given_a_workspace_only_with_non_driver_projects_when_cwd_is_workspace_root_then_build_should_be_successful()
{
// Input CLI args
let cwd = PathBuf::from("C:\\tmp");
let profile = None;
Expand Down Expand Up @@ -1318,8 +1318,8 @@ pub fn given_a_workspace_only_with_non_driver_projects_when_cwd_is_workspace_roo
}

#[test]
pub fn given_a_workspace_only_with_non_driver_projects_when_cwd_is_workspace_member_then_build_should_be_successful(
) {
pub fn given_a_workspace_only_with_non_driver_projects_when_cwd_is_workspace_member_then_build_should_be_successful()
{
// Input CLI args
let workspace_root_dir = PathBuf::from("C:\\tmp");
let cwd = workspace_root_dir.join("non-driver");
Expand Down
2 changes: 1 addition & 1 deletion crates/cargo-wdk/src/actions/new/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use std::{

use clap_verbosity_flag::Verbosity;
use error::NewActionError;
use include_dir::{include_dir, Dir};
use include_dir::{Dir, include_dir};
use mockall_double::double;
use tracing::{debug, info};

Expand Down
6 changes: 3 additions & 3 deletions crates/cargo-wdk/src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,14 @@ use mockall_double::double;
use wdk_build::CpuArchitecture;

use crate::actions::{
build::{BuildAction, BuildActionParams},
new::NewAction,
DriverType,
KMDF_STR,
Profile,
TargetArch,
KMDF_STR,
UMDF_STR,
WDM_STR,
build::{BuildAction, BuildActionParams},
new::NewAction,
};
#[double]
use crate::providers::{exec::CommandExec, fs::Fs, metadata::Metadata, wdk_build::WdkBuild};
Expand Down
2 changes: 1 addition & 1 deletion crates/cargo-wdk/src/providers/fs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
#![allow(clippy::unused_self)]

use std::{
fs::{copy, create_dir, read_dir, rename, DirEntry, File, FileType, OpenOptions},
fs::{DirEntry, File, FileType, OpenOptions, copy, create_dir, read_dir, rename},
io::{Read, Write},
path::Path,
};
Expand Down
78 changes: 74 additions & 4 deletions crates/cargo-wdk/src/test_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,9 @@ where

// Remove the env var if value is None
if let Some(value) = value {
std::env::set_var(key, value);
set_var(key, value);
} else {
std::env::remove_var(key);
remove_var(key);
}
}

Expand All @@ -51,13 +51,83 @@ where
for (key, _) in env_vars_key_value_pairs {
original_env_vars.get(key).map_or_else(
|| {
std::env::remove_var(key);
remove_var(key);
},
|value| {
std::env::set_var(key, value);
set_var(key, value);
},
);
}

f_return_value
}

/// Safely sets an environment variable. Will not compile if crate is not
/// targeted for Windows.
///
/// This function provides a safe wrapper around [`std::env::set_var`] that
/// became unsafe in Rust 2024 edition.
///
/// # Panics
///
/// This function may panic if key is empty, contains an ASCII equals sign '='
/// or the NUL character '\0', or when value contains the NUL character.
#[cfg(target_os = "windows")]
pub fn set_var<K, V>(key: K, value: V)
where
K: AsRef<OsStr>,
V: AsRef<OsStr>,
{
// SAFETY: this function is only conditionally compiled for windows targets, and
// env::set_var is always safe for windows targets
unsafe {
std::env::set_var(key, value);
}
}

#[cfg(not(target_os = "windows"))]
pub fn set_var<K, V>(_key: K, _value: V)
where
K: AsRef<OsStr>,
V: AsRef<OsStr>,
{
compile_error!(
"windows-drivers-rs is designed to be run on a Windows host machine in a WDK environment. \
Please build using a Windows target."
);
}

/// Safely removes an environment variable. Will not compile if crate is not
/// targeted for Windows.
///
/// This function provides a safe wrapper around [`std::env::remove_var`] that
/// became unsafe in Rust 2024 edition.
///
/// # Panics
///
/// This function may panic if key is empty, contains an ASCII equals sign '='
/// or the NUL character '\0', or when value contains the NUL character.
#[allow(dead_code)]
#[cfg(target_os = "windows")]
pub fn remove_var<K>(key: K)
where
K: AsRef<OsStr>,
{
// SAFETY: this function is only conditionally compiled for windows targets, and
// env::set_var is always safe for windows targets
unsafe {
std::env::remove_var(key);
}
}

#[allow(dead_code)]
#[cfg(not(target_os = "windows"))]
pub fn remove_var<K>(_key: K)
where
K: AsRef<OsStr>,
{
compile_error!(
"windows-drivers-rs is designed to be run on a Windows host machine in a WDK environment. \
Please build using a Windows target."
);
}
2 changes: 2 additions & 0 deletions crates/cargo-wdk/templates/kmdf/lib.rs.tmp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ use wdk_alloc::WdkAllocator;
#[global_allocator]
static GLOBAL_ALLOCATOR: WdkAllocator = WdkAllocator;

// SAFETY: "DriverEntry" is the required symbol name for Windows driver entry points.
// No other function in this compilation unit exports this name, preventing symbol conflicts.
#[unsafe(export_name = "DriverEntry")] // WDF expects a symbol with the name DriverEntry
pub unsafe extern "system" fn driver_entry(
_driver: PDRIVER_OBJECT,
Expand Down
2 changes: 2 additions & 0 deletions crates/cargo-wdk/templates/umdf/lib.rs.tmp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ use wdk_sys::{
PCUNICODE_STRING,
};

// SAFETY: "DriverEntry" is the required symbol name for Windows driver entry points.
// No other function in this compilation unit exports this name, preventing symbol conflicts.
#[unsafe(export_name = "DriverEntry")] // WDF expects a symbol with the name DriverEntry
pub unsafe extern "system" fn driver_entry(
_driver: PDRIVER_OBJECT,
Expand Down
2 changes: 2 additions & 0 deletions crates/cargo-wdk/templates/wdm/lib.rs.tmp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ use wdk_alloc::WdkAllocator;
#[global_allocator]
static GLOBAL_ALLOCATOR: WdkAllocator = WdkAllocator;

// SAFETY: "DriverEntry" is the required symbol name for Windows driver entry points.
// No other function in this compilation unit exports this name, preventing symbol conflicts.
#[unsafe(export_name = "DriverEntry")] // WDF expects a symbol with the name DriverEntry
pub unsafe extern "system" fn driver_entry(
_driver: PDRIVER_OBJECT,
Expand Down
Loading
Loading