From 5cd6fc7801299ee22c69628b84c820263c50c3ea Mon Sep 17 00:00:00 2001 From: NateD-MSFT <34494373+NateD-MSFT@users.noreply.github.com> Date: Tue, 23 Apr 2024 16:43:58 -0700 Subject: [PATCH 01/36] Initial stab at getting the WDK version into environment --- crates/wdk-build/rust-driver-makefile.toml | 1 + crates/wdk-build/src/cargo_make.rs | 17 +++++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/crates/wdk-build/rust-driver-makefile.toml b/crates/wdk-build/rust-driver-makefile.toml index 253f7e26..d383f584 100644 --- a/crates/wdk-build/rust-driver-makefile.toml +++ b/crates/wdk-build/rust-driver-makefile.toml @@ -80,6 +80,7 @@ script = ''' wdk_build::cargo_make::validate_and_forward_args(); wdk_build::cargo_make::setup_path()?; +wdk_build::cargo_make::setup_wdk_version()?; ''' [tasks.copy-inx-to-output] diff --git a/crates/wdk-build/src/cargo_make.rs b/crates/wdk-build/src/cargo_make.rs index c2846d5d..9e03482a 100644 --- a/crates/wdk-build/src/cargo_make.rs +++ b/crates/wdk-build/src/cargo_make.rs @@ -20,6 +20,7 @@ use crate::{ }; const PATH_ENV_VAR: &str = "Path"; +const WDK_VERSION_ENV_VAR: &str = "WDK_VER"; /// The name of the environment variable that cargo-make uses during `cargo /// build` and `cargo test` commands @@ -492,6 +493,22 @@ pub fn setup_path() -> Result<(), ConfigError> { Ok(()) } +/// Adds the WDK version to the environment. +/// +/// # Errors +/// +/// This function returns a [`ConfigError::WDKContentRootDetectionError`] if the +/// WDK content root directory could not be found. +pub fn setup_wdk_version() -> Result<(), ConfigError> { + let Some(wdk_content_root) = detect_wdk_content_root() else { + return Err(ConfigError::WDKContentRootDetectionError); + }; + let version = get_latest_windows_sdk_version(&wdk_content_root.join("Lib"))?; + prepend_to_semicolon_delimited_env_var(&WDK_VERSION_ENV_VAR, &version); + forward_env_var_to_cargo_make(WDK_VERSION_ENV_VAR); + Ok(()) +} + /// Returns the path to the WDK build output directory for the current /// cargo-make flow /// From 60383481024ca7757150499033ba464e4615bf8e Mon Sep 17 00:00:00 2001 From: NateD-MSFT <34494373+NateD-MSFT@users.noreply.github.com> Date: Fri, 26 Apr 2024 00:11:36 -0700 Subject: [PATCH 02/36] Implement logic to select InfVerif flag. HAS BUG --- crates/sample-kmdf-driver/Makefile.toml | 2 +- crates/wdk-build/rust-driver-makefile.toml | 4 ++- crates/wdk-build/src/cargo_make.rs | 40 +++++++++++++++++++++- 3 files changed, 43 insertions(+), 3 deletions(-) diff --git a/crates/sample-kmdf-driver/Makefile.toml b/crates/sample-kmdf-driver/Makefile.toml index 64a2b957..93664570 100644 --- a/crates/sample-kmdf-driver/Makefile.toml +++ b/crates/sample-kmdf-driver/Makefile.toml @@ -1,4 +1,4 @@ extend = "../wdk-build/rust-driver-makefile.toml" [env] -WDK_BUILD_ADDITIONAL_INFVERIF_FLAGS = "/msft" +WDK_BUILD_ADDITIONAL_INFVERIF_FLAGS = "${WDK_INFVERIF_SAMPLE_FLAG}" # BUG: Applies a ; to the end of the environment variable for some reason diff --git a/crates/wdk-build/rust-driver-makefile.toml b/crates/wdk-build/rust-driver-makefile.toml index d383f584..4494ab2c 100644 --- a/crates/wdk-build/rust-driver-makefile.toml +++ b/crates/wdk-build/rust-driver-makefile.toml @@ -80,7 +80,9 @@ script = ''' wdk_build::cargo_make::validate_and_forward_args(); wdk_build::cargo_make::setup_path()?; -wdk_build::cargo_make::setup_wdk_version()?; + +let wdk_version = wdk_build::cargo_make::setup_wdk_version()?; +wdk_build::cargo_make::set_sample_infverif(wdk_version)?; ''' [tasks.copy-inx-to-output] diff --git a/crates/wdk-build/src/cargo_make.rs b/crates/wdk-build/src/cargo_make.rs index 9e03482a..aaa50d6d 100644 --- a/crates/wdk-build/src/cargo_make.rs +++ b/crates/wdk-build/src/cargo_make.rs @@ -21,6 +21,8 @@ use crate::{ const PATH_ENV_VAR: &str = "Path"; const WDK_VERSION_ENV_VAR: &str = "WDK_VER"; +/// The name of the environment variable we store the appropriate InfVerif flag for samples in. +const SAMPLE_ENV_VAR: &str = "WDK_INFVERIF_SAMPLE_FLAG"; // TODO: Should we return this directly instead of making it an environment variable? /// The name of the environment variable that cargo-make uses during `cargo /// build` and `cargo test` commands @@ -499,13 +501,30 @@ pub fn setup_path() -> Result<(), ConfigError> { /// /// This function returns a [`ConfigError::WDKContentRootDetectionError`] if the /// WDK content root directory could not be found. -pub fn setup_wdk_version() -> Result<(), ConfigError> { +pub fn setup_wdk_version() -> Result { let Some(wdk_content_root) = detect_wdk_content_root() else { return Err(ConfigError::WDKContentRootDetectionError); }; let version = get_latest_windows_sdk_version(&wdk_content_root.join("Lib"))?; prepend_to_semicolon_delimited_env_var(&WDK_VERSION_ENV_VAR, &version); forward_env_var_to_cargo_make(WDK_VERSION_ENV_VAR); + Ok(version) +} + +/// Sets the WDK_INFVERIF_SAMPLE_FLAG environment variable to contain the appropriate flag for building samples. +pub fn set_sample_infverif>(version: S) -> Result<(), ConfigError> { + let wdk_version = version.as_ref(); + let mut version_parts = wdk_version.split('.'); + let sample_flag = match version_parts.any(|version_part| match version_part.parse::() { + Ok(parsed_value) => parsed_value > 25798, + Err(_) => false, /* TODO: Should this short-circuit and return + * ConfigError::WDKContentRootDetectionError for the func as a whole? */ + }) { + true => "/sample", + false => "/msft", + }; + std::env::set_var(&SAMPLE_ENV_VAR, &sample_flag); + forward_env_var_to_cargo_make(SAMPLE_ENV_VAR); Ok(()) } @@ -723,3 +742,22 @@ fn forward_env_var_to_cargo_make>(env_var_name: S) { ); } } + +#[cfg(test)] +mod tests { + use crate::ConfigError; + + #[test] + fn check_env_passing() -> Result<(), ConfigError>{ + let wdk_version = crate::cargo_make::setup_wdk_version()?; + crate::cargo_make::set_sample_infverif(wdk_version)?; + let env_string = match std::env::var_os(crate::cargo_make::SAMPLE_ENV_VAR) + { + Some(os_env_string) => os_env_string.to_string_lossy().into_owned().clone(), + None => panic!("Couldn't get OS string") + }; + assert_eq!(env_string, "/msft"); + Ok(()) + } + +} \ No newline at end of file From 67f3717209e6dce0f4abc0d0935ca1ad6e0300d1 Mon Sep 17 00:00:00 2001 From: NateD-MSFT <34494373+NateD-MSFT@users.noreply.github.com> Date: Fri, 26 Apr 2024 12:36:09 -0700 Subject: [PATCH 03/36] Introduce WDK_IS_SAMPLE flag to make simpler environment logic --- crates/sample-kmdf-driver/Makefile.toml | 2 +- crates/wdk-build/rust-driver-makefile.toml | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/crates/sample-kmdf-driver/Makefile.toml b/crates/sample-kmdf-driver/Makefile.toml index 93664570..1c49146e 100644 --- a/crates/sample-kmdf-driver/Makefile.toml +++ b/crates/sample-kmdf-driver/Makefile.toml @@ -1,4 +1,4 @@ extend = "../wdk-build/rust-driver-makefile.toml" [env] -WDK_BUILD_ADDITIONAL_INFVERIF_FLAGS = "${WDK_INFVERIF_SAMPLE_FLAG}" # BUG: Applies a ; to the end of the environment variable for some reason +WDK_IS_SAMPLE = true diff --git a/crates/wdk-build/rust-driver-makefile.toml b/crates/wdk-build/rust-driver-makefile.toml index 4494ab2c..845fee2d 100644 --- a/crates/wdk-build/rust-driver-makefile.toml +++ b/crates/wdk-build/rust-driver-makefile.toml @@ -180,6 +180,7 @@ args = [ "1.33", ] + [tasks.infverif] private = true dependencies = ["stampinf"] @@ -187,6 +188,7 @@ command = "infverif" args = [ "/v", "/w", + "@@decode(WDK_IS_SAMPLE,true,${WDK_INFVERIF_SAMPLE_FLAG})", "@@split(WDK_BUILD_ADDITIONAL_INFVERIF_FLAGS, )", "${WDK_BUILD_OUTPUT_DIRECTORY}/${CARGO_MAKE_CRATE_FS_NAME}.inf", ] From 1dc570152ea9967ff2d4200f1555463d0749ecfc Mon Sep 17 00:00:00 2001 From: NateD-MSFT <34494373+NateD-MSFT@users.noreply.github.com> Date: Fri, 26 Apr 2024 12:38:28 -0700 Subject: [PATCH 04/36] Quick TODO to improve parsing --- crates/wdk-build/src/cargo_make.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/crates/wdk-build/src/cargo_make.rs b/crates/wdk-build/src/cargo_make.rs index aaa50d6d..6a602793 100644 --- a/crates/wdk-build/src/cargo_make.rs +++ b/crates/wdk-build/src/cargo_make.rs @@ -519,6 +519,7 @@ pub fn set_sample_infverif>(version: S) -> Result<(), ConfigError> Ok(parsed_value) => parsed_value > 25798, Err(_) => false, /* TODO: Should this short-circuit and return * ConfigError::WDKContentRootDetectionError for the func as a whole? */ + // TODO: Better to specifically look at substring 3 instead of "any" }) { true => "/sample", false => "/msft", From b261b0ae903b2c34a9e4fd748665f8ef06dd2649 Mon Sep 17 00:00:00 2001 From: NateD-MSFT <34494373+NateD-MSFT@users.noreply.github.com> Date: Fri, 26 Apr 2024 13:40:38 -0700 Subject: [PATCH 05/36] Refactor set_sample_infverif --- crates/wdk-build/src/cargo_make.rs | 48 ++++++++++++++++++------------ 1 file changed, 29 insertions(+), 19 deletions(-) diff --git a/crates/wdk-build/src/cargo_make.rs b/crates/wdk-build/src/cargo_make.rs index 6a602793..8a038c48 100644 --- a/crates/wdk-build/src/cargo_make.rs +++ b/crates/wdk-build/src/cargo_make.rs @@ -16,12 +16,14 @@ use clap::{Args, Parser}; use crate::{ utils::{detect_wdk_content_root, get_latest_windows_sdk_version, PathExt}, CPUArchitecture, + Config, ConfigError, }; const PATH_ENV_VAR: &str = "Path"; const WDK_VERSION_ENV_VAR: &str = "WDK_VER"; -/// The name of the environment variable we store the appropriate InfVerif flag for samples in. +/// The name of the environment variable we store the appropriate InfVerif flag +/// for samples in. const SAMPLE_ENV_VAR: &str = "WDK_INFVERIF_SAMPLE_FLAG"; // TODO: Should we return this directly instead of making it an environment variable? /// The name of the environment variable that cargo-make uses during `cargo @@ -511,22 +513,31 @@ pub fn setup_wdk_version() -> Result { Ok(version) } -/// Sets the WDK_INFVERIF_SAMPLE_FLAG environment variable to contain the appropriate flag for building samples. +/// Sets the WDK_INFVERIF_SAMPLE_FLAG environment variable to contain the +/// appropriate flag for building samples. pub fn set_sample_infverif>(version: S) -> Result<(), ConfigError> { let wdk_version = version.as_ref(); let mut version_parts = wdk_version.split('.'); - let sample_flag = match version_parts.any(|version_part| match version_part.parse::() { - Ok(parsed_value) => parsed_value > 25798, - Err(_) => false, /* TODO: Should this short-circuit and return - * ConfigError::WDKContentRootDetectionError for the func as a whole? */ - // TODO: Better to specifically look at substring 3 instead of "any" - }) { - true => "/sample", - false => "/msft", + let version_number = match version_parts.nth(2) { + Some(version_str) => match version_str.parse::() { + Ok(version_int) => Some(version_int), + Err(_) => None, + }, + None => None, }; - std::env::set_var(&SAMPLE_ENV_VAR, &sample_flag); - forward_env_var_to_cargo_make(SAMPLE_ENV_VAR); - Ok(()) + + if let Some(version) = version_number { + let sample_flag = match version > 25798 { + true => "/sample", + false => "/msft", + }; + std::env::set_var(&SAMPLE_ENV_VAR, &sample_flag); + forward_env_var_to_cargo_make(SAMPLE_ENV_VAR); + return Ok(()); + } + + // If we get this far, we weren't able to parse the WDK version number from the path + Err(ConfigError::WDKContentRootDetectionError) } /// Returns the path to the WDK build output directory for the current @@ -748,17 +759,16 @@ fn forward_env_var_to_cargo_make>(env_var_name: S) { mod tests { use crate::ConfigError; + /// This test must be run in a WDK environment. #[test] - fn check_env_passing() -> Result<(), ConfigError>{ + fn check_env_passing() -> Result<(), ConfigError> { let wdk_version = crate::cargo_make::setup_wdk_version()?; crate::cargo_make::set_sample_infverif(wdk_version)?; - let env_string = match std::env::var_os(crate::cargo_make::SAMPLE_ENV_VAR) - { + let env_string = match std::env::var_os(crate::cargo_make::SAMPLE_ENV_VAR) { Some(os_env_string) => os_env_string.to_string_lossy().into_owned().clone(), - None => panic!("Couldn't get OS string") + None => panic!("Couldn't get OS string"), }; assert_eq!(env_string, "/msft"); Ok(()) } - -} \ No newline at end of file +} From db8da442d47d9b15e32d2a8dd38cd370a54a51d1 Mon Sep 17 00:00:00 2001 From: NateD-MSFT <34494373+NateD-MSFT@users.noreply.github.com> Date: Fri, 26 Apr 2024 14:16:25 -0700 Subject: [PATCH 06/36] Cleanup and add test case. --- crates/wdk-build/src/cargo_make.rs | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/crates/wdk-build/src/cargo_make.rs b/crates/wdk-build/src/cargo_make.rs index 8a038c48..1edc0794 100644 --- a/crates/wdk-build/src/cargo_make.rs +++ b/crates/wdk-build/src/cargo_make.rs @@ -16,7 +16,6 @@ use clap::{Args, Parser}; use crate::{ utils::{detect_wdk_content_root, get_latest_windows_sdk_version, PathExt}, CPUArchitecture, - Config, ConfigError, }; @@ -24,7 +23,9 @@ const PATH_ENV_VAR: &str = "Path"; const WDK_VERSION_ENV_VAR: &str = "WDK_VER"; /// The name of the environment variable we store the appropriate InfVerif flag /// for samples in. -const SAMPLE_ENV_VAR: &str = "WDK_INFVERIF_SAMPLE_FLAG"; // TODO: Should we return this directly instead of making it an environment variable? +const SAMPLE_ENV_VAR: &str = "WDK_INFVERIF_SAMPLE_FLAG"; +/// The first WDK version with the new InfVerif behavior. +const WDK_INF_NEW_VERSION: i32 = 25798; /// The name of the environment variable that cargo-make uses during `cargo /// build` and `cargo test` commands @@ -527,7 +528,7 @@ pub fn set_sample_infverif>(version: S) -> Result<(), ConfigError> }; if let Some(version) = version_number { - let sample_flag = match version > 25798 { + let sample_flag = match version > WDK_INF_NEW_VERSION { true => "/sample", false => "/msft", }; @@ -536,7 +537,8 @@ pub fn set_sample_infverif>(version: S) -> Result<(), ConfigError> return Ok(()); } - // If we get this far, we weren't able to parse the WDK version number from the path + // If we get this far, we weren't able to parse the WDK version number from the + // path Err(ConfigError::WDKContentRootDetectionError) } @@ -759,16 +761,24 @@ fn forward_env_var_to_cargo_make>(env_var_name: S) { mod tests { use crate::ConfigError; - /// This test must be run in a WDK environment. + const WDK_TEST_OLD_INF_VERSION: &str = "10.0.22061.0"; + const WDK_TEST_NEW_INF_VERSION: &str = "10.0.26100.0"; + #[test] fn check_env_passing() -> Result<(), ConfigError> { - let wdk_version = crate::cargo_make::setup_wdk_version()?; - crate::cargo_make::set_sample_infverif(wdk_version)?; + crate::cargo_make::set_sample_infverif(WDK_TEST_OLD_INF_VERSION)?; let env_string = match std::env::var_os(crate::cargo_make::SAMPLE_ENV_VAR) { Some(os_env_string) => os_env_string.to_string_lossy().into_owned().clone(), None => panic!("Couldn't get OS string"), }; assert_eq!(env_string, "/msft"); + + crate::cargo_make::set_sample_infverif(WDK_TEST_NEW_INF_VERSION)?; + let env_string = match std::env::var_os(crate::cargo_make::SAMPLE_ENV_VAR) { + Some(os_env_string) => os_env_string.to_string_lossy().into_owned().clone(), + None => panic!("Couldn't get OS string"), + }; + assert_eq!(env_string, "/sample"); Ok(()) } } From f760c30c68a8974b3ea6d0cce342d7fa07290e16 Mon Sep 17 00:00:00 2001 From: NateD-MSFT <34494373+NateD-MSFT@users.noreply.github.com> Date: Fri, 26 Apr 2024 14:24:23 -0700 Subject: [PATCH 07/36] /samples, not /sample --- crates/wdk-build/src/cargo_make.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/wdk-build/src/cargo_make.rs b/crates/wdk-build/src/cargo_make.rs index 1edc0794..e195605f 100644 --- a/crates/wdk-build/src/cargo_make.rs +++ b/crates/wdk-build/src/cargo_make.rs @@ -529,7 +529,7 @@ pub fn set_sample_infverif>(version: S) -> Result<(), ConfigError> if let Some(version) = version_number { let sample_flag = match version > WDK_INF_NEW_VERSION { - true => "/sample", + true => "/samples", false => "/msft", }; std::env::set_var(&SAMPLE_ENV_VAR, &sample_flag); @@ -778,7 +778,7 @@ mod tests { Some(os_env_string) => os_env_string.to_string_lossy().into_owned().clone(), None => panic!("Couldn't get OS string"), }; - assert_eq!(env_string, "/sample"); + assert_eq!(env_string, "/samples"); Ok(()) } } From b6e2951d5af95db5a683727fb3044b4ced98401d Mon Sep 17 00:00:00 2001 From: NateD-MSFT <34494373+NateD-MSFT@users.noreply.github.com> Date: Fri, 26 Apr 2024 16:36:15 -0700 Subject: [PATCH 08/36] Update to not run infverif for samples --- crates/wdk-build/rust-driver-makefile.toml | 1 + crates/wdk-build/src/cargo_make.rs | 7 ++++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/crates/wdk-build/rust-driver-makefile.toml b/crates/wdk-build/rust-driver-makefile.toml index 845fee2d..6f5a5434 100644 --- a/crates/wdk-build/rust-driver-makefile.toml +++ b/crates/wdk-build/rust-driver-makefile.toml @@ -184,6 +184,7 @@ args = [ [tasks.infverif] private = true dependencies = ["stampinf"] +condition = { env_not_set = ["WDK_INF_NEW_VERSION"] } command = "infverif" args = [ "/v", diff --git a/crates/wdk-build/src/cargo_make.rs b/crates/wdk-build/src/cargo_make.rs index e195605f..2d096ab7 100644 --- a/crates/wdk-build/src/cargo_make.rs +++ b/crates/wdk-build/src/cargo_make.rs @@ -26,6 +26,7 @@ const WDK_VERSION_ENV_VAR: &str = "WDK_VER"; const SAMPLE_ENV_VAR: &str = "WDK_INFVERIF_SAMPLE_FLAG"; /// The first WDK version with the new InfVerif behavior. const WDK_INF_NEW_VERSION: i32 = 25798; +const WDK_INF_NEW_VERSION_FLAG: &str = "WDK_INF_NEW_VERSION"; /// The name of the environment variable that cargo-make uses during `cargo /// build` and `cargo test` commands @@ -533,7 +534,11 @@ pub fn set_sample_infverif>(version: S) -> Result<(), ConfigError> false => "/msft", }; std::env::set_var(&SAMPLE_ENV_VAR, &sample_flag); - forward_env_var_to_cargo_make(SAMPLE_ENV_VAR); + forward_env_var_to_cargo_make(&SAMPLE_ENV_VAR); + if version > WDK_INF_NEW_VERSION { + std::env::set_var(&WDK_INF_NEW_VERSION_FLAG, "true"); + forward_env_var_to_cargo_make(&WDK_INF_NEW_VERSION_FLAG); + } return Ok(()); } From ab732abac3f74fb7f745342effa64c977586c46c Mon Sep 17 00:00:00 2001 From: NateD-MSFT <34494373+NateD-MSFT@users.noreply.github.com> Date: Fri, 26 Apr 2024 16:56:10 -0700 Subject: [PATCH 09/36] Fix cargo format bug --- crates/wdk-build/src/cargo_make.rs | 2 +- crates/wdk-sys/generated_bindings/types.rs | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/crates/wdk-build/src/cargo_make.rs b/crates/wdk-build/src/cargo_make.rs index 2d096ab7..24b4015c 100644 --- a/crates/wdk-build/src/cargo_make.rs +++ b/crates/wdk-build/src/cargo_make.rs @@ -23,7 +23,7 @@ const PATH_ENV_VAR: &str = "Path"; const WDK_VERSION_ENV_VAR: &str = "WDK_VER"; /// The name of the environment variable we store the appropriate InfVerif flag /// for samples in. -const SAMPLE_ENV_VAR: &str = "WDK_INFVERIF_SAMPLE_FLAG"; +const SAMPLE_ENV_VAR: &str = "WDK_INFVERIF_SAMPLE_FLAG"; /// The first WDK version with the new InfVerif behavior. const WDK_INF_NEW_VERSION: i32 = 25798; const WDK_INF_NEW_VERSION_FLAG: &str = "WDK_INF_NEW_VERSION"; diff --git a/crates/wdk-sys/generated_bindings/types.rs b/crates/wdk-sys/generated_bindings/types.rs index 475b4bc9..042b4ba6 100644 --- a/crates/wdk-sys/generated_bindings/types.rs +++ b/crates/wdk-sys/generated_bindings/types.rs @@ -125664,6 +125664,7 @@ impl _WHEA_XPF_PROCINFO_VALIDBITS__bindgen_ty_1 { 1u8, { let TargetId: u64 = unsafe { ::core::mem::transmute(TargetId) }; + stringify!(Flags), TargetId as u64 }, ); From dca2606278bc8f7fee112dbf0c376a1c63d29a6f Mon Sep 17 00:00:00 2001 From: NateD-MSFT <34494373+NateD-MSFT@users.noreply.github.com> Date: Fri, 26 Apr 2024 17:22:37 -0700 Subject: [PATCH 10/36] Cargo auto-fixes --- crates/wdk-build/src/cargo_make.rs | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/crates/wdk-build/src/cargo_make.rs b/crates/wdk-build/src/cargo_make.rs index 24b4015c..6c82e62f 100644 --- a/crates/wdk-build/src/cargo_make.rs +++ b/crates/wdk-build/src/cargo_make.rs @@ -21,10 +21,10 @@ use crate::{ const PATH_ENV_VAR: &str = "Path"; const WDK_VERSION_ENV_VAR: &str = "WDK_VER"; -/// The name of the environment variable we store the appropriate InfVerif flag +/// The name of the environment variable we store the appropriate `InfVerif` flag /// for samples in. const SAMPLE_ENV_VAR: &str = "WDK_INFVERIF_SAMPLE_FLAG"; -/// The first WDK version with the new InfVerif behavior. +/// The first WDK version with the new `InfVerif` behavior. const WDK_INF_NEW_VERSION: i32 = 25798; const WDK_INF_NEW_VERSION_FLAG: &str = "WDK_INF_NEW_VERSION"; @@ -510,12 +510,12 @@ pub fn setup_wdk_version() -> Result { return Err(ConfigError::WDKContentRootDetectionError); }; let version = get_latest_windows_sdk_version(&wdk_content_root.join("Lib"))?; - prepend_to_semicolon_delimited_env_var(&WDK_VERSION_ENV_VAR, &version); + prepend_to_semicolon_delimited_env_var(WDK_VERSION_ENV_VAR, &version); forward_env_var_to_cargo_make(WDK_VERSION_ENV_VAR); Ok(version) } -/// Sets the WDK_INFVERIF_SAMPLE_FLAG environment variable to contain the +/// Sets the `WDK_INFVERIF_SAMPLE_FLAG` environment variable to contain the /// appropriate flag for building samples. pub fn set_sample_infverif>(version: S) -> Result<(), ConfigError> { let wdk_version = version.as_ref(); @@ -533,11 +533,11 @@ pub fn set_sample_infverif>(version: S) -> Result<(), ConfigError> true => "/samples", false => "/msft", }; - std::env::set_var(&SAMPLE_ENV_VAR, &sample_flag); - forward_env_var_to_cargo_make(&SAMPLE_ENV_VAR); + std::env::set_var(SAMPLE_ENV_VAR, sample_flag); + forward_env_var_to_cargo_make(SAMPLE_ENV_VAR); if version > WDK_INF_NEW_VERSION { - std::env::set_var(&WDK_INF_NEW_VERSION_FLAG, "true"); - forward_env_var_to_cargo_make(&WDK_INF_NEW_VERSION_FLAG); + std::env::set_var(WDK_INF_NEW_VERSION_FLAG, "true"); + forward_env_var_to_cargo_make(WDK_INF_NEW_VERSION_FLAG); } return Ok(()); } @@ -773,14 +773,14 @@ mod tests { fn check_env_passing() -> Result<(), ConfigError> { crate::cargo_make::set_sample_infverif(WDK_TEST_OLD_INF_VERSION)?; let env_string = match std::env::var_os(crate::cargo_make::SAMPLE_ENV_VAR) { - Some(os_env_string) => os_env_string.to_string_lossy().into_owned().clone(), + Some(os_env_string) => os_env_string.to_string_lossy().into_owned(), None => panic!("Couldn't get OS string"), }; assert_eq!(env_string, "/msft"); crate::cargo_make::set_sample_infverif(WDK_TEST_NEW_INF_VERSION)?; let env_string = match std::env::var_os(crate::cargo_make::SAMPLE_ENV_VAR) { - Some(os_env_string) => os_env_string.to_string_lossy().into_owned().clone(), + Some(os_env_string) => os_env_string.to_string_lossy().into_owned(), None => panic!("Couldn't get OS string"), }; assert_eq!(env_string, "/samples"); From 963d12ce98662919374a08d832919f769c929c7b Mon Sep 17 00:00:00 2001 From: NateD-MSFT <34494373+NateD-MSFT@users.noreply.github.com> Date: Fri, 26 Apr 2024 17:34:55 -0700 Subject: [PATCH 11/36] Clippy fixes --- crates/wdk-build/src/cargo_make.rs | 43 ++++++++++++++++-------------- 1 file changed, 23 insertions(+), 20 deletions(-) diff --git a/crates/wdk-build/src/cargo_make.rs b/crates/wdk-build/src/cargo_make.rs index 6c82e62f..24dfcd02 100644 --- a/crates/wdk-build/src/cargo_make.rs +++ b/crates/wdk-build/src/cargo_make.rs @@ -21,8 +21,8 @@ use crate::{ const PATH_ENV_VAR: &str = "Path"; const WDK_VERSION_ENV_VAR: &str = "WDK_VER"; -/// The name of the environment variable we store the appropriate `InfVerif` flag -/// for samples in. +/// The name of the environment variable we store the appropriate `InfVerif` +/// flag for samples in. const SAMPLE_ENV_VAR: &str = "WDK_INFVERIF_SAMPLE_FLAG"; /// The first WDK version with the new `InfVerif` behavior. const WDK_INF_NEW_VERSION: i32 = 25798; @@ -517,21 +517,24 @@ pub fn setup_wdk_version() -> Result { /// Sets the `WDK_INFVERIF_SAMPLE_FLAG` environment variable to contain the /// appropriate flag for building samples. +/// +/// # Errors +/// +/// This function returns a [`ConfigError::WDKContentRootDetectionError`] if the +/// WDK version is ill-formed (that is, it does not match the form +/// 10.x.yyyyy.z). pub fn set_sample_infverif>(version: S) -> Result<(), ConfigError> { let wdk_version = version.as_ref(); let mut version_parts = wdk_version.split('.'); - let version_number = match version_parts.nth(2) { - Some(version_str) => match version_str.parse::() { - Ok(version_int) => Some(version_int), - Err(_) => None, - }, - None => None, - }; + let version_number = version_parts + .nth(2) + .and_then(|version_str| version_str.parse::().ok()); if let Some(version) = version_number { - let sample_flag = match version > WDK_INF_NEW_VERSION { - true => "/samples", - false => "/msft", + let sample_flag = if version > WDK_INF_NEW_VERSION { + "/samples" + } else { + "/msft" }; std::env::set_var(SAMPLE_ENV_VAR, sample_flag); forward_env_var_to_cargo_make(SAMPLE_ENV_VAR); @@ -772,17 +775,17 @@ mod tests { #[test] fn check_env_passing() -> Result<(), ConfigError> { crate::cargo_make::set_sample_infverif(WDK_TEST_OLD_INF_VERSION)?; - let env_string = match std::env::var_os(crate::cargo_make::SAMPLE_ENV_VAR) { - Some(os_env_string) => os_env_string.to_string_lossy().into_owned(), - None => panic!("Couldn't get OS string"), - }; + let env_string = std::env::var_os(crate::cargo_make::SAMPLE_ENV_VAR).map_or_else( + || panic!("Couldn't get OS string"), + |os_env_string| os_env_string.to_string_lossy().into_owned(), + ); assert_eq!(env_string, "/msft"); crate::cargo_make::set_sample_infverif(WDK_TEST_NEW_INF_VERSION)?; - let env_string = match std::env::var_os(crate::cargo_make::SAMPLE_ENV_VAR) { - Some(os_env_string) => os_env_string.to_string_lossy().into_owned(), - None => panic!("Couldn't get OS string"), - }; + let env_string = std::env::var_os(crate::cargo_make::SAMPLE_ENV_VAR).map_or_else( + || panic!("Couldn't get OS string"), + |os_env_string| os_env_string.to_string_lossy().into_owned(), + ); assert_eq!(env_string, "/samples"); Ok(()) } From 5d575f3b201453947b6aab0c5146464cf767b033 Mon Sep 17 00:00:00 2001 From: NateD-MSFT <34494373+NateD-MSFT@users.noreply.github.com> Date: Fri, 26 Apr 2024 17:39:20 -0700 Subject: [PATCH 12/36] Undo accidental change to types.rs --- crates/wdk-sys/generated_bindings/types.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/crates/wdk-sys/generated_bindings/types.rs b/crates/wdk-sys/generated_bindings/types.rs index 042b4ba6..475b4bc9 100644 --- a/crates/wdk-sys/generated_bindings/types.rs +++ b/crates/wdk-sys/generated_bindings/types.rs @@ -125664,7 +125664,6 @@ impl _WHEA_XPF_PROCINFO_VALIDBITS__bindgen_ty_1 { 1u8, { let TargetId: u64 = unsafe { ::core::mem::transmute(TargetId) }; - stringify!(Flags), TargetId as u64 }, ); From bd557e57323b50c91bf845a1766eebfc373d40c7 Mon Sep 17 00:00:00 2001 From: NateD-MSFT <34494373+NateD-MSFT@users.noreply.github.com> Date: Tue, 30 Apr 2024 18:44:57 -0700 Subject: [PATCH 13/36] Refactors to address PR feedback. --- crates/sample-kmdf-driver/Makefile.toml | 5 +- crates/wdk-build/rust-driver-makefile.toml | 16 ++- crates/wdk-build/src/cargo_make.rs | 131 ++++++++++++++------- 3 files changed, 104 insertions(+), 48 deletions(-) diff --git a/crates/sample-kmdf-driver/Makefile.toml b/crates/sample-kmdf-driver/Makefile.toml index 1c49146e..55db0b39 100644 --- a/crates/sample-kmdf-driver/Makefile.toml +++ b/crates/sample-kmdf-driver/Makefile.toml @@ -1,4 +1,5 @@ extend = "../wdk-build/rust-driver-makefile.toml" -[env] -WDK_IS_SAMPLE = true +[tasks.infverif] +dependencies = ["wdk-samples-setup"] +condition = { env_not_set = ["WDK_INF_USING_NEW_VERSION"] } \ No newline at end of file diff --git a/crates/wdk-build/rust-driver-makefile.toml b/crates/wdk-build/rust-driver-makefile.toml index 6f5a5434..79cdbe31 100644 --- a/crates/wdk-build/rust-driver-makefile.toml +++ b/crates/wdk-build/rust-driver-makefile.toml @@ -80,7 +80,21 @@ script = ''' wdk_build::cargo_make::validate_and_forward_args(); wdk_build::cargo_make::setup_path()?; +''' +[tasks.wdk-samples-setup] +private = true +install_crate = { crate_name = "rust-script", min_version = "0.30.0" } +plugin = "rust-env-update" +script_runner = "@rust" +script = ''' +//! ```cargo +//! [dependencies] +//! wdk-build = { path = ".", version = "0.2.0" } +//! ``` +#![allow(unused_doc_comments)] + +wdk_build::cargo_make::validate_and_forward_args(); let wdk_version = wdk_build::cargo_make::setup_wdk_version()?; wdk_build::cargo_make::set_sample_infverif(wdk_version)?; ''' @@ -184,12 +198,10 @@ args = [ [tasks.infverif] private = true dependencies = ["stampinf"] -condition = { env_not_set = ["WDK_INF_NEW_VERSION"] } command = "infverif" args = [ "/v", "/w", - "@@decode(WDK_IS_SAMPLE,true,${WDK_INFVERIF_SAMPLE_FLAG})", "@@split(WDK_BUILD_ADDITIONAL_INFVERIF_FLAGS, )", "${WDK_BUILD_OUTPUT_DIRECTORY}/${CARGO_MAKE_CRATE_FS_NAME}.inf", ] diff --git a/crates/wdk-build/src/cargo_make.rs b/crates/wdk-build/src/cargo_make.rs index 24dfcd02..4e67eace 100644 --- a/crates/wdk-build/src/cargo_make.rs +++ b/crates/wdk-build/src/cargo_make.rs @@ -20,13 +20,11 @@ use crate::{ }; const PATH_ENV_VAR: &str = "Path"; -const WDK_VERSION_ENV_VAR: &str = "WDK_VER"; -/// The name of the environment variable we store the appropriate `InfVerif` -/// flag for samples in. -const SAMPLE_ENV_VAR: &str = "WDK_INFVERIF_SAMPLE_FLAG"; +const WDK_VERSION_ENV_VAR: &str = "WDK_BUILD_DETECTED_WDK_VERISON"; /// The first WDK version with the new `InfVerif` behavior. const WDK_INF_NEW_VERSION: i32 = 25798; -const WDK_INF_NEW_VERSION_FLAG: &str = "WDK_INF_NEW_VERSION"; +const WDK_INF_ADDITIONAL_FLAGS_ENV_VAR: &str = "WDK_BUILD_ADDITIONAL_INFVERIF_FLAGS"; +const WDK_INF_NEW_VERSION_FLAG: &str = "WDK_INF_USING_NEW_VERSION"; /// The name of the environment variable that cargo-make uses during `cargo /// build` and `cargo test` commands @@ -499,55 +497,98 @@ pub fn setup_path() -> Result<(), ConfigError> { Ok(()) } -/// Adds the WDK version to the environment. +/// Adds the WDK version to the environment in the full string form of +/// 10.xxx.yyy.zzz, where x, y, and z are numerical values. /// /// # Errors /// /// This function returns a [`ConfigError::WDKContentRootDetectionError`] if the -/// WDK content root directory could not be found. +/// WDK content root directory could not be found, or if the WDK version is +/// ill-formed. pub fn setup_wdk_version() -> Result { let Some(wdk_content_root) = detect_wdk_content_root() else { return Err(ConfigError::WDKContentRootDetectionError); }; let version = get_latest_windows_sdk_version(&wdk_content_root.join("Lib"))?; + + validate_wdk_version_format(&version)?; + prepend_to_semicolon_delimited_env_var(WDK_VERSION_ENV_VAR, &version); forward_env_var_to_cargo_make(WDK_VERSION_ENV_VAR); Ok(version) } -/// Sets the `WDK_INFVERIF_SAMPLE_FLAG` environment variable to contain the -/// appropriate flag for building samples. +/// Validates that a given string matches the WDK version format (10.xxx.yyy.zzz +/// where xxx, yyy, and zzz are numeric and not necessarily 3 digits long) +/// and returns the yyy portion (the build number) if so. /// /// # Errors /// /// This function returns a [`ConfigError::WDKContentRootDetectionError`] if the -/// WDK version is ill-formed (that is, it does not match the form -/// 10.x.yyyyy.z). -pub fn set_sample_infverif>(version: S) -> Result<(), ConfigError> { - let wdk_version = version.as_ref(); - let mut version_parts = wdk_version.split('.'); - let version_number = version_parts - .nth(2) - .and_then(|version_str| version_str.parse::().ok()); - - if let Some(version) = version_number { - let sample_flag = if version > WDK_INF_NEW_VERSION { - "/samples" - } else { - "/msft" - }; - std::env::set_var(SAMPLE_ENV_VAR, sample_flag); - forward_env_var_to_cargo_make(SAMPLE_ENV_VAR); - if version > WDK_INF_NEW_VERSION { - std::env::set_var(WDK_INF_NEW_VERSION_FLAG, "true"); - forward_env_var_to_cargo_make(WDK_INF_NEW_VERSION_FLAG); - } - return Ok(()); +/// version string provided is ill-formed. +fn validate_wdk_version_format>(version_string: &S) -> Result<&str, ConfigError> { + let version = version_string.as_ref(); + let mut version_parts = version.split('.'); + + // To make the code more readable we recreate the iterator + // for each validity check we do. + + // First, check if we have "10" as our first value + if !version_parts.next().is_some_and(|first| first == "10") { + return Err(ConfigError::WDKContentRootDetectionError); + } + + // Now check that we have four entries. + let version_parts = version.split('.'); + if !version_parts.count() == 4 { + return Err(ConfigError::WDKContentRootDetectionError); } - // If we get this far, we weren't able to parse the WDK version number from the - // path - Err(ConfigError::WDKContentRootDetectionError) + // Finally, confirm each part is numeric. + let mut version_parts = version.split('.'); + if !version_parts.all(|version_part| version_part.parse::().is_ok()) { + return Err(ConfigError::WDKContentRootDetectionError); + } + + // Now return the actual build number from the string (the yyy in + // 10.xxx.yyy.zzz). + let mut version_parts = version.split('.'); + + // Safe to call unwrap here as we validated we have 4 parts above. + Ok(version_parts.nth(2).unwrap()) +} + +/// Sets the `WDK_INFVERIF_SAMPLE_FLAG` environment variable to contain the +/// appropriate flag for building samples. +/// +/// # Errors +/// +/// This function returns a [`ConfigError::WDKContentRootDetectionError`] if +/// an invalid WDK version is provided. +/// +/// # Panics +/// +/// This function will panic if the [`validate_wdk_version_format`] function is +/// ever changed to no longer validate that each part of the version string is +/// an i32. +pub fn set_sample_infverif>(version: S) -> Result<(), ConfigError> { + let validated_version_string = validate_wdk_version_format(&version)?; + + // Safe to unwrap as we called .parse::().is_ok() in our call to + // validate_wdk_version_format above. + let version = validated_version_string + .parse::() + .expect("Unable to parse the build number of the WDK version string as an int!"); + let sample_flag = if version > WDK_INF_NEW_VERSION { + std::env::set_var(WDK_INF_NEW_VERSION_FLAG, "true"); + forward_env_var_to_cargo_make(WDK_INF_NEW_VERSION_FLAG); + "/samples" // Note: Not currently implemented, hence why we also set the WDK_INF_NEW_VERSION_FLAG + } else { + "/msft" + }; + append_to_space_delimited_env_var(WDK_INF_ADDITIONAL_FLAGS_ENV_VAR, sample_flag); + forward_env_var_to_cargo_make(WDK_INF_ADDITIONAL_FLAGS_ENV_VAR); + Ok(()) } /// Returns the path to the WDK build output directory for the current @@ -775,18 +816,20 @@ mod tests { #[test] fn check_env_passing() -> Result<(), ConfigError> { crate::cargo_make::set_sample_infverif(WDK_TEST_OLD_INF_VERSION)?; - let env_string = std::env::var_os(crate::cargo_make::SAMPLE_ENV_VAR).map_or_else( - || panic!("Couldn't get OS string"), - |os_env_string| os_env_string.to_string_lossy().into_owned(), - ); - assert_eq!(env_string, "/msft"); + let env_string = std::env::var_os(crate::cargo_make::WDK_INF_ADDITIONAL_FLAGS_ENV_VAR) + .map_or_else( + || panic!("Couldn't get OS string"), + |os_env_string| os_env_string.to_string_lossy().into_owned(), + ); + assert_eq!(env_string.split(" ").last(), Some("/msft")); crate::cargo_make::set_sample_infverif(WDK_TEST_NEW_INF_VERSION)?; - let env_string = std::env::var_os(crate::cargo_make::SAMPLE_ENV_VAR).map_or_else( - || panic!("Couldn't get OS string"), - |os_env_string| os_env_string.to_string_lossy().into_owned(), - ); - assert_eq!(env_string, "/samples"); + let env_string = std::env::var_os(crate::cargo_make::WDK_INF_ADDITIONAL_FLAGS_ENV_VAR) + .map_or_else( + || panic!("Couldn't get OS string"), + |os_env_string| os_env_string.to_string_lossy().into_owned(), + ); + assert_eq!(env_string.split(" ").last(), Some("/samples")); Ok(()) } } From df43c8911b7a57d62f5f0893dcee8980ec6738ff Mon Sep 17 00:00:00 2001 From: NateD-MSFT <34494373+NateD-MSFT@users.noreply.github.com> Date: Tue, 30 Apr 2024 18:51:27 -0700 Subject: [PATCH 14/36] Fix TOML formatting --- crates/sample-kmdf-driver/Makefile.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/sample-kmdf-driver/Makefile.toml b/crates/sample-kmdf-driver/Makefile.toml index 55db0b39..0b1edfeb 100644 --- a/crates/sample-kmdf-driver/Makefile.toml +++ b/crates/sample-kmdf-driver/Makefile.toml @@ -2,4 +2,4 @@ extend = "../wdk-build/rust-driver-makefile.toml" [tasks.infverif] dependencies = ["wdk-samples-setup"] -condition = { env_not_set = ["WDK_INF_USING_NEW_VERSION"] } \ No newline at end of file +condition = { env_not_set = ["WDK_INF_USING_NEW_VERSION"] } From ef2eba652c43935ec1125b3ac02f1fbbef723069 Mon Sep 17 00:00:00 2001 From: NateD-MSFT <34494373+NateD-MSFT@users.noreply.github.com> Date: Tue, 30 Apr 2024 19:10:13 -0700 Subject: [PATCH 15/36] Fix new clippy lint. --- crates/wdk-build/src/cargo_make.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/wdk-build/src/cargo_make.rs b/crates/wdk-build/src/cargo_make.rs index 4e67eace..a8ddbafb 100644 --- a/crates/wdk-build/src/cargo_make.rs +++ b/crates/wdk-build/src/cargo_make.rs @@ -821,7 +821,7 @@ mod tests { || panic!("Couldn't get OS string"), |os_env_string| os_env_string.to_string_lossy().into_owned(), ); - assert_eq!(env_string.split(" ").last(), Some("/msft")); + assert_eq!(env_string.split(' ').last(), Some("/msft")); crate::cargo_make::set_sample_infverif(WDK_TEST_NEW_INF_VERSION)?; let env_string = std::env::var_os(crate::cargo_make::WDK_INF_ADDITIONAL_FLAGS_ENV_VAR) @@ -829,7 +829,7 @@ mod tests { || panic!("Couldn't get OS string"), |os_env_string| os_env_string.to_string_lossy().into_owned(), ); - assert_eq!(env_string.split(" ").last(), Some("/samples")); + assert_eq!(env_string.split(' ').last(), Some("/samples")); Ok(()) } } From f3de079c640420302fb3c9144552141fbfd0d520 Mon Sep 17 00:00:00 2001 From: NateD-MSFT <34494373+NateD-MSFT@users.noreply.github.com> Date: Tue, 30 Apr 2024 20:21:39 -0700 Subject: [PATCH 16/36] Fix doc bug. --- crates/wdk-build/src/cargo_make.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/wdk-build/src/cargo_make.rs b/crates/wdk-build/src/cargo_make.rs index a8ddbafb..6a04f037 100644 --- a/crates/wdk-build/src/cargo_make.rs +++ b/crates/wdk-build/src/cargo_make.rs @@ -568,7 +568,7 @@ fn validate_wdk_version_format>(version_string: &S) -> Result<&str /// /// # Panics /// -/// This function will panic if the [`validate_wdk_version_format`] function is +/// This function will panic if the private validate_wdk_version_format() function is /// ever changed to no longer validate that each part of the version string is /// an i32. pub fn set_sample_infverif>(version: S) -> Result<(), ConfigError> { From db513197b2390f15b7bba445aa4d34e4452a7045 Mon Sep 17 00:00:00 2001 From: NateD-MSFT <34494373+NateD-MSFT@users.noreply.github.com> Date: Tue, 30 Apr 2024 20:24:21 -0700 Subject: [PATCH 17/36] Fix a formatting issue that slipped in. --- crates/wdk-build/src/cargo_make.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/crates/wdk-build/src/cargo_make.rs b/crates/wdk-build/src/cargo_make.rs index 6a04f037..eb97f324 100644 --- a/crates/wdk-build/src/cargo_make.rs +++ b/crates/wdk-build/src/cargo_make.rs @@ -568,9 +568,9 @@ fn validate_wdk_version_format>(version_string: &S) -> Result<&str /// /// # Panics /// -/// This function will panic if the private validate_wdk_version_format() function is -/// ever changed to no longer validate that each part of the version string is -/// an i32. +/// This function will panic if the private validate_wdk_version_format() +/// function is ever changed to no longer validate that each part of the version +/// string is an i32. pub fn set_sample_infverif>(version: S) -> Result<(), ConfigError> { let validated_version_string = validate_wdk_version_format(&version)?; From 31b4bd1dfec8ff5693d3dd5d625c4bd462064139 Mon Sep 17 00:00:00 2001 From: NateD-MSFT <34494373+NateD-MSFT@users.noreply.github.com> Date: Tue, 30 Apr 2024 22:56:00 -0700 Subject: [PATCH 18/36] Refactor `validate_wdk_version_format` into utils.rs --- crates/wdk-build/src/cargo_make.rs | 50 ++------------------ crates/wdk-build/src/utils.rs | 74 ++++++++++++++++++++++++++++++ 2 files changed, 79 insertions(+), 45 deletions(-) diff --git a/crates/wdk-build/src/cargo_make.rs b/crates/wdk-build/src/cargo_make.rs index eb97f324..c8aeafca 100644 --- a/crates/wdk-build/src/cargo_make.rs +++ b/crates/wdk-build/src/cargo_make.rs @@ -511,53 +511,13 @@ pub fn setup_wdk_version() -> Result { }; let version = get_latest_windows_sdk_version(&wdk_content_root.join("Lib"))?; - validate_wdk_version_format(&version)?; + crate::utils::validate_wdk_version_format(&version)?; prepend_to_semicolon_delimited_env_var(WDK_VERSION_ENV_VAR, &version); forward_env_var_to_cargo_make(WDK_VERSION_ENV_VAR); Ok(version) } -/// Validates that a given string matches the WDK version format (10.xxx.yyy.zzz -/// where xxx, yyy, and zzz are numeric and not necessarily 3 digits long) -/// and returns the yyy portion (the build number) if so. -/// -/// # Errors -/// -/// This function returns a [`ConfigError::WDKContentRootDetectionError`] if the -/// version string provided is ill-formed. -fn validate_wdk_version_format>(version_string: &S) -> Result<&str, ConfigError> { - let version = version_string.as_ref(); - let mut version_parts = version.split('.'); - - // To make the code more readable we recreate the iterator - // for each validity check we do. - - // First, check if we have "10" as our first value - if !version_parts.next().is_some_and(|first| first == "10") { - return Err(ConfigError::WDKContentRootDetectionError); - } - - // Now check that we have four entries. - let version_parts = version.split('.'); - if !version_parts.count() == 4 { - return Err(ConfigError::WDKContentRootDetectionError); - } - - // Finally, confirm each part is numeric. - let mut version_parts = version.split('.'); - if !version_parts.all(|version_part| version_part.parse::().is_ok()) { - return Err(ConfigError::WDKContentRootDetectionError); - } - - // Now return the actual build number from the string (the yyy in - // 10.xxx.yyy.zzz). - let mut version_parts = version.split('.'); - - // Safe to call unwrap here as we validated we have 4 parts above. - Ok(version_parts.nth(2).unwrap()) -} - /// Sets the `WDK_INFVERIF_SAMPLE_FLAG` environment variable to contain the /// appropriate flag for building samples. /// @@ -568,11 +528,11 @@ fn validate_wdk_version_format>(version_string: &S) -> Result<&str /// /// # Panics /// -/// This function will panic if the private validate_wdk_version_format() -/// function is ever changed to no longer validate that each part of the version -/// string is an i32. +/// This function will panic if the function for validating a WDK version string +/// is ever changed to no longer validate that each part of the version string +/// is an i32. pub fn set_sample_infverif>(version: S) -> Result<(), ConfigError> { - let validated_version_string = validate_wdk_version_format(&version)?; + let validated_version_string = crate::utils::validate_wdk_version_format(&version)?; // Safe to unwrap as we called .parse::().is_ok() in our call to // validate_wdk_version_format above. diff --git a/crates/wdk-build/src/utils.rs b/crates/wdk-build/src/utils.rs index bc9a3150..4cee0f97 100644 --- a/crates/wdk-build/src/utils.rs +++ b/crates/wdk-build/src/utils.rs @@ -281,6 +281,46 @@ pub fn detect_cpu_architecture_in_build_script() -> CPUArchitecture { }) } +/// Validates that a given string matches the WDK version format (10.xxx.yyy.zzz +/// where xxx, yyy, and zzz are numeric and not necessarily 3 digits long) +/// and returns the yyy portion (the build number) if so. +/// +/// # Errors +/// +/// This function returns a [`ConfigError::WDKContentRootDetectionError`] if the +/// version string provided is ill-formed. +pub fn validate_wdk_version_format>(version_string: &S) -> Result<&str, ConfigError> { + let version = version_string.as_ref(); + let mut version_parts = version.split('.'); + + // To make the code more readable we recreate the iterator + // for each validity check we do. + + // First, check if we have "10" as our first value + if !version_parts.next().is_some_and(|first| first == "10") { + return Err(ConfigError::WDKContentRootDetectionError); + } + + // Now check that we have four entries. + let version_parts = version.split('.'); + if version_parts.count() != 4 { + return Err(ConfigError::WDKContentRootDetectionError); + } + + // Finally, confirm each part is numeric. + let mut version_parts = version.split('.'); + if !version_parts.all(|version_part| version_part.parse::().is_ok()) { + return Err(ConfigError::WDKContentRootDetectionError); + } + + // Now return the actual build number from the string (the yyy in + // 10.xxx.yyy.zzz). + let mut version_parts = version.split('.'); + + // Safe to call unwrap here as we validated we have 4 parts above. + Ok(version_parts.nth(2).unwrap()) +} + #[cfg(test)] mod tests { use windows::Win32::UI::Shell::{FOLDERID_ProgramFiles, SHGetKnownFolderPath, KF_FLAG_DEFAULT}; @@ -343,4 +383,38 @@ mod tests { ) ); } + + #[test] + fn validate_wdk_strings() { + assert_eq!( + validate_wdk_version_format(&"10.0.12345.0").ok(), + Some("12345") + ); + assert_eq!(validate_wdk_version_format(&"10.0.5.0").ok(), Some("5")); + assert_eq!(validate_wdk_version_format(&"10.0.0.0").ok(), Some("0")); + assert!(matches!( + validate_wdk_version_format(&"11.0.0.0"), + Err(ConfigError::WDKContentRootDetectionError) + )); + assert!(matches!( + validate_wdk_version_format(&"10.0.12345.0.0"), + Err(ConfigError::WDKContentRootDetectionError) + )); + assert!(matches!( + validate_wdk_version_format(&"10.0.12345.a"), + Err(ConfigError::WDKContentRootDetectionError) + )); + assert!(matches!( + validate_wdk_version_format(&"10.0.12345"), + Err(ConfigError::WDKContentRootDetectionError) + )); + assert!(matches!( + validate_wdk_version_format(&"10.0.1234!5.0"), + Err(ConfigError::WDKContentRootDetectionError) + )); + assert!(matches!( + validate_wdk_version_format(&"Not a real version!"), + Err(ConfigError::WDKContentRootDetectionError) + )); + } } From dcaeb14719c2d66753af213dd8a1dbfdd7c7739f Mon Sep 17 00:00:00 2001 From: NateD-MSFT <34494373+NateD-MSFT@users.noreply.github.com> Date: Thu, 2 May 2024 14:48:01 -0700 Subject: [PATCH 19/36] Use a single collection instead of iterators --- crates/wdk-build/src/utils.rs | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/crates/wdk-build/src/utils.rs b/crates/wdk-build/src/utils.rs index 4cee0f97..51b5ff34 100644 --- a/crates/wdk-build/src/utils.rs +++ b/crates/wdk-build/src/utils.rs @@ -291,34 +291,33 @@ pub fn detect_cpu_architecture_in_build_script() -> CPUArchitecture { /// version string provided is ill-formed. pub fn validate_wdk_version_format>(version_string: &S) -> Result<&str, ConfigError> { let version = version_string.as_ref(); - let mut version_parts = version.split('.'); + let version_parts: Vec<&str> = version.split('.').collect(); // To make the code more readable we recreate the iterator // for each validity check we do. // First, check if we have "10" as our first value - if !version_parts.next().is_some_and(|first| first == "10") { + if !version_parts.first().is_some_and(|first| *first == "10") { return Err(ConfigError::WDKContentRootDetectionError); } // Now check that we have four entries. - let version_parts = version.split('.'); - if version_parts.count() != 4 { + if version_parts.len() != 4 { return Err(ConfigError::WDKContentRootDetectionError); } // Finally, confirm each part is numeric. - let mut version_parts = version.split('.'); - if !version_parts.all(|version_part| version_part.parse::().is_ok()) { + if !version_parts + .iter() + .all(|version_part| version_part.parse::().is_ok()) + { return Err(ConfigError::WDKContentRootDetectionError); } // Now return the actual build number from the string (the yyy in // 10.xxx.yyy.zzz). - let mut version_parts = version.split('.'); - - // Safe to call unwrap here as we validated we have 4 parts above. - Ok(version_parts.nth(2).unwrap()) + // Safe to dereference as we validated we have 4 parts above. + Ok(version_parts[2]) } #[cfg(test)] @@ -416,5 +415,9 @@ mod tests { validate_wdk_version_format(&"Not a real version!"), Err(ConfigError::WDKContentRootDetectionError) )); + assert!(matches!( + validate_wdk_version_format(&""), + Err(ConfigError::WDKContentRootDetectionError) + )); } } From 810e31be98f70f9a6d1cfee027e77f7b232961e4 Mon Sep 17 00:00:00 2001 From: NateD-MSFT <34494373+NateD-MSFT@users.noreply.github.com> Date: Thu, 2 May 2024 14:48:36 -0700 Subject: [PATCH 20/36] Comment fix --- crates/wdk-build/src/utils.rs | 3 --- 1 file changed, 3 deletions(-) diff --git a/crates/wdk-build/src/utils.rs b/crates/wdk-build/src/utils.rs index 51b5ff34..9ea7de0c 100644 --- a/crates/wdk-build/src/utils.rs +++ b/crates/wdk-build/src/utils.rs @@ -293,9 +293,6 @@ pub fn validate_wdk_version_format>(version_string: &S) -> Result< let version = version_string.as_ref(); let version_parts: Vec<&str> = version.split('.').collect(); - // To make the code more readable we recreate the iterator - // for each validity check we do. - // First, check if we have "10" as our first value if !version_parts.first().is_some_and(|first| *first == "10") { return Err(ConfigError::WDKContentRootDetectionError); From 2ce9838ba24a485cf8d08f1fac25faea4c7857c5 Mon Sep 17 00:00:00 2001 From: NateD-MSFT <34494373+NateD-MSFT@users.noreply.github.com> Date: Thu, 2 May 2024 17:27:51 -0700 Subject: [PATCH 21/36] Apply suggestions from code review Note: this will cause compilation failures until another commit updates a few references. Co-authored-by: Melvin Wang Signed-off-by: NateD-MSFT <34494373+NateD-MSFT@users.noreply.github.com> --- crates/sample-kmdf-driver/Makefile.toml | 2 +- crates/wdk-build/rust-driver-makefile.toml | 1 - crates/wdk-build/src/cargo_make.rs | 2 +- crates/wdk-build/src/utils.rs | 2 +- 4 files changed, 3 insertions(+), 4 deletions(-) diff --git a/crates/sample-kmdf-driver/Makefile.toml b/crates/sample-kmdf-driver/Makefile.toml index 0b1edfeb..83d41544 100644 --- a/crates/sample-kmdf-driver/Makefile.toml +++ b/crates/sample-kmdf-driver/Makefile.toml @@ -1,5 +1,5 @@ extend = "../wdk-build/rust-driver-makefile.toml" [tasks.infverif] -dependencies = ["wdk-samples-setup"] +dependencies = ["wdk-samples-setup", "stampinf"] condition = { env_not_set = ["WDK_INF_USING_NEW_VERSION"] } diff --git a/crates/wdk-build/rust-driver-makefile.toml b/crates/wdk-build/rust-driver-makefile.toml index 79cdbe31..2b4c9a6e 100644 --- a/crates/wdk-build/rust-driver-makefile.toml +++ b/crates/wdk-build/rust-driver-makefile.toml @@ -194,7 +194,6 @@ args = [ "1.33", ] - [tasks.infverif] private = true dependencies = ["stampinf"] diff --git a/crates/wdk-build/src/cargo_make.rs b/crates/wdk-build/src/cargo_make.rs index c8aeafca..e4edc4e7 100644 --- a/crates/wdk-build/src/cargo_make.rs +++ b/crates/wdk-build/src/cargo_make.rs @@ -531,7 +531,7 @@ pub fn setup_wdk_version() -> Result { /// This function will panic if the function for validating a WDK version string /// is ever changed to no longer validate that each part of the version string /// is an i32. -pub fn set_sample_infverif>(version: S) -> Result<(), ConfigError> { +pub fn setup_infverif_for_samples>(version: S) -> Result<(), ConfigError> { let validated_version_string = crate::utils::validate_wdk_version_format(&version)?; // Safe to unwrap as we called .parse::().is_ok() in our call to diff --git a/crates/wdk-build/src/utils.rs b/crates/wdk-build/src/utils.rs index 9ea7de0c..adf23448 100644 --- a/crates/wdk-build/src/utils.rs +++ b/crates/wdk-build/src/utils.rs @@ -289,7 +289,7 @@ pub fn detect_cpu_architecture_in_build_script() -> CPUArchitecture { /// /// This function returns a [`ConfigError::WDKContentRootDetectionError`] if the /// version string provided is ill-formed. -pub fn validate_wdk_version_format>(version_string: &S) -> Result<&str, ConfigError> { +pub fn validate_wdk_version_format>(version_string: S) -> Result<&str, ConfigError> { let version = version_string.as_ref(); let version_parts: Vec<&str> = version.split('.').collect(); From 15c5458bdc3cd9f2985dff61a6e889e24f2da817 Mon Sep 17 00:00:00 2001 From: NateD-MSFT <34494373+NateD-MSFT@users.noreply.github.com> Date: Tue, 7 May 2024 17:01:56 -0700 Subject: [PATCH 22/36] Refactor and add a new enum value. Still has a bug --- crates/sample-kmdf-driver/Makefile.toml | 2 +- crates/wdk-build/rust-driver-makefile.toml | 12 ++++++++---- crates/wdk-build/src/cargo_make.rs | 18 +++++++++++++++--- crates/wdk-build/src/lib.rs | 5 +++++ crates/wdk-build/src/utils.rs | 22 +++++++++++----------- 5 files changed, 40 insertions(+), 19 deletions(-) diff --git a/crates/sample-kmdf-driver/Makefile.toml b/crates/sample-kmdf-driver/Makefile.toml index 0b1edfeb..83d41544 100644 --- a/crates/sample-kmdf-driver/Makefile.toml +++ b/crates/sample-kmdf-driver/Makefile.toml @@ -1,5 +1,5 @@ extend = "../wdk-build/rust-driver-makefile.toml" [tasks.infverif] -dependencies = ["wdk-samples-setup"] +dependencies = ["wdk-samples-setup", "stampinf"] condition = { env_not_set = ["WDK_INF_USING_NEW_VERSION"] } diff --git a/crates/wdk-build/rust-driver-makefile.toml b/crates/wdk-build/rust-driver-makefile.toml index 79cdbe31..9a5fa728 100644 --- a/crates/wdk-build/rust-driver-makefile.toml +++ b/crates/wdk-build/rust-driver-makefile.toml @@ -80,10 +80,12 @@ script = ''' wdk_build::cargo_make::validate_and_forward_args(); wdk_build::cargo_make::setup_path()?; +wdk_build::cargo_make::setup_wdk_version()?; ''' [tasks.wdk-samples-setup] private = true +dependencies = ["wdk-build-init"] install_crate = { crate_name = "rust-script", min_version = "0.30.0" } plugin = "rust-env-update" script_runner = "@rust" @@ -93,10 +95,12 @@ script = ''' //! wdk-build = { path = ".", version = "0.2.0" } //! ``` #![allow(unused_doc_comments)] - -wdk_build::cargo_make::validate_and_forward_args(); -let wdk_version = wdk_build::cargo_make::setup_wdk_version()?; -wdk_build::cargo_make::set_sample_infverif(wdk_version)?; +let env_string = std::env::var_os(wdk_build::cargo_make::WDK_VERSION_ENV_VAR) + .map_or_else( + || panic!("Couldn't read WDK build version that should have been set in init"), + |os_env_string| os_env_string.to_string_lossy().into_owned(), + ); +wdk_build::cargo_make::set_sample_infverif(env_string)?; ''' [tasks.copy-inx-to-output] diff --git a/crates/wdk-build/src/cargo_make.rs b/crates/wdk-build/src/cargo_make.rs index c8aeafca..618ce93a 100644 --- a/crates/wdk-build/src/cargo_make.rs +++ b/crates/wdk-build/src/cargo_make.rs @@ -20,7 +20,9 @@ use crate::{ }; const PATH_ENV_VAR: &str = "Path"; -const WDK_VERSION_ENV_VAR: &str = "WDK_BUILD_DETECTED_WDK_VERISON"; +/// The environment variable that [`setup_wdk_version`] stores the WDK version +/// in. +pub const WDK_VERSION_ENV_VAR: &str = "WDK_BUILD_DETECTED_WDK_VERSION"; /// The first WDK version with the new `InfVerif` behavior. const WDK_INF_NEW_VERSION: i32 = 25798; const WDK_INF_ADDITIONAL_FLAGS_ENV_VAR: &str = "WDK_BUILD_ADDITIONAL_INFVERIF_FLAGS"; @@ -511,9 +513,10 @@ pub fn setup_wdk_version() -> Result { }; let version = get_latest_windows_sdk_version(&wdk_content_root.join("Lib"))?; + println!("FORWARDING ARGS TO CARGO-MAKE:"); crate::utils::validate_wdk_version_format(&version)?; - prepend_to_semicolon_delimited_env_var(WDK_VERSION_ENV_VAR, &version); + append_to_space_delimited_env_var(WDK_VERSION_ENV_VAR, &version); forward_env_var_to_cargo_make(WDK_VERSION_ENV_VAR); Ok(version) } @@ -532,7 +535,15 @@ pub fn setup_wdk_version() -> Result { /// is ever changed to no longer validate that each part of the version string /// is an i32. pub fn set_sample_infverif>(version: S) -> Result<(), ConfigError> { - let validated_version_string = crate::utils::validate_wdk_version_format(&version)?; + // The below two lines are just to unblock while debugging an issue with + // multiple versions populating the environment variable + let version = version.as_ref().split(' ').collect::>(); + let version = version.first().unwrap_or(&"No version provided"); + let validated_version_string = crate::utils::validate_wdk_version_format(version)?; + // This print signifies the start of the forwarding and signals to the + // `rust-env-update` plugin that it should forward args. This is also used to + // signal that the auto-generated help from `clap` was not executed. + println!("FORWARDING ARGS TO CARGO-MAKE:"); // Safe to unwrap as we called .parse::().is_ok() in our call to // validate_wdk_version_format above. @@ -548,6 +559,7 @@ pub fn set_sample_infverif>(version: S) -> Result<(), ConfigError> }; append_to_space_delimited_env_var(WDK_INF_ADDITIONAL_FLAGS_ENV_VAR, sample_flag); forward_env_var_to_cargo_make(WDK_INF_ADDITIONAL_FLAGS_ENV_VAR); + // println!("{{{WDK_INF_ADDITIONAL_FLAGS_ENV_VAR}}}={}", sample_flag); Ok(()) } diff --git a/crates/wdk-build/src/lib.rs b/crates/wdk-build/src/lib.rs index 56f89eb8..079f7147 100644 --- a/crates/wdk-build/src/lib.rs +++ b/crates/wdk-build/src/lib.rs @@ -119,6 +119,11 @@ pub enum ConfigError { )] WDKContentRootDetectionError, + /// Error returned when the WDK version string does not match the expected + /// format + #[error("The WDK version string provided was not in a valid format.")] + WDKVersionStringFormatError, + /// Error returned when `cargo_metadata` execution or parsing fails #[error(transparent)] CargoMetadataError(#[from] cargo_metadata::Error), diff --git a/crates/wdk-build/src/utils.rs b/crates/wdk-build/src/utils.rs index 9ea7de0c..3f7d040b 100644 --- a/crates/wdk-build/src/utils.rs +++ b/crates/wdk-build/src/utils.rs @@ -287,7 +287,7 @@ pub fn detect_cpu_architecture_in_build_script() -> CPUArchitecture { /// /// # Errors /// -/// This function returns a [`ConfigError::WDKContentRootDetectionError`] if the +/// This function returns a [`ConfigError::WDKVersionStringFormatError`] if the /// version string provided is ill-formed. pub fn validate_wdk_version_format>(version_string: &S) -> Result<&str, ConfigError> { let version = version_string.as_ref(); @@ -295,12 +295,12 @@ pub fn validate_wdk_version_format>(version_string: &S) -> Result< // First, check if we have "10" as our first value if !version_parts.first().is_some_and(|first| *first == "10") { - return Err(ConfigError::WDKContentRootDetectionError); + return Err(ConfigError::WDKVersionStringFormatError); } // Now check that we have four entries. if version_parts.len() != 4 { - return Err(ConfigError::WDKContentRootDetectionError); + return Err(ConfigError::WDKVersionStringFormatError); } // Finally, confirm each part is numeric. @@ -308,7 +308,7 @@ pub fn validate_wdk_version_format>(version_string: &S) -> Result< .iter() .all(|version_part| version_part.parse::().is_ok()) { - return Err(ConfigError::WDKContentRootDetectionError); + return Err(ConfigError::WDKVersionStringFormatError); } // Now return the actual build number from the string (the yyy in @@ -390,31 +390,31 @@ mod tests { assert_eq!(validate_wdk_version_format(&"10.0.0.0").ok(), Some("0")); assert!(matches!( validate_wdk_version_format(&"11.0.0.0"), - Err(ConfigError::WDKContentRootDetectionError) + Err(ConfigError::WDKVersionStringFormatError) )); assert!(matches!( validate_wdk_version_format(&"10.0.12345.0.0"), - Err(ConfigError::WDKContentRootDetectionError) + Err(ConfigError::WDKVersionStringFormatError) )); assert!(matches!( validate_wdk_version_format(&"10.0.12345.a"), - Err(ConfigError::WDKContentRootDetectionError) + Err(ConfigError::WDKVersionStringFormatError) )); assert!(matches!( validate_wdk_version_format(&"10.0.12345"), - Err(ConfigError::WDKContentRootDetectionError) + Err(ConfigError::WDKVersionStringFormatError) )); assert!(matches!( validate_wdk_version_format(&"10.0.1234!5.0"), - Err(ConfigError::WDKContentRootDetectionError) + Err(ConfigError::WDKVersionStringFormatError) )); assert!(matches!( validate_wdk_version_format(&"Not a real version!"), - Err(ConfigError::WDKContentRootDetectionError) + Err(ConfigError::WDKVersionStringFormatError) )); assert!(matches!( validate_wdk_version_format(&""), - Err(ConfigError::WDKContentRootDetectionError) + Err(ConfigError::WDKVersionStringFormatError) )); } } From 0cbea241ef55aa1e680ef146683b24f6a6872935 Mon Sep 17 00:00:00 2001 From: NateD-MSFT <34494373+NateD-MSFT@users.noreply.github.com> Date: Tue, 7 May 2024 17:28:40 -0700 Subject: [PATCH 23/36] This borrow actually is required here --- crates/wdk-build/rust-driver-makefile.toml | 2 +- crates/wdk-build/src/utils.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/wdk-build/rust-driver-makefile.toml b/crates/wdk-build/rust-driver-makefile.toml index 99e42dc7..ae345e77 100644 --- a/crates/wdk-build/rust-driver-makefile.toml +++ b/crates/wdk-build/rust-driver-makefile.toml @@ -100,7 +100,7 @@ let env_string = std::env::var_os(wdk_build::cargo_make::WDK_VERSION_ENV_VAR) || panic!("Couldn't read WDK build version that should have been set in init"), |os_env_string| os_env_string.to_string_lossy().into_owned(), ); -wdk_build::cargo_make::set_sample_infverif(env_string)?; +wdk_build::cargo_make::setup_infverif_for_samples(env_string)?; ''' [tasks.copy-inx-to-output] diff --git a/crates/wdk-build/src/utils.rs b/crates/wdk-build/src/utils.rs index 2573614b..3f7d040b 100644 --- a/crates/wdk-build/src/utils.rs +++ b/crates/wdk-build/src/utils.rs @@ -289,7 +289,7 @@ pub fn detect_cpu_architecture_in_build_script() -> CPUArchitecture { /// /// This function returns a [`ConfigError::WDKVersionStringFormatError`] if the /// version string provided is ill-formed. -pub fn validate_wdk_version_format>(version_string: S) -> Result<&str, ConfigError> { +pub fn validate_wdk_version_format>(version_string: &S) -> Result<&str, ConfigError> { let version = version_string.as_ref(); let version_parts: Vec<&str> = version.split('.').collect(); From 75c09a2c21aa72293f2e19d4ca3938a5c773e986 Mon Sep 17 00:00:00 2001 From: NateD-MSFT <34494373+NateD-MSFT@users.noreply.github.com> Date: Wed, 8 May 2024 17:12:07 -0700 Subject: [PATCH 24/36] Significant refactoring and renaming --- crates/sample-kmdf-driver/Makefile.toml | 9 +- .../rust-driver-sample-makefile.toml | 7 ++ crates/wdk-build/src/cargo_make.rs | 90 +++++++++++++++---- crates/wdk-build/src/utils.rs | 72 +++++++++------ 4 files changed, 131 insertions(+), 47 deletions(-) create mode 100644 crates/wdk-build/rust-driver-sample-makefile.toml diff --git a/crates/sample-kmdf-driver/Makefile.toml b/crates/sample-kmdf-driver/Makefile.toml index 83d41544..f91ac160 100644 --- a/crates/sample-kmdf-driver/Makefile.toml +++ b/crates/sample-kmdf-driver/Makefile.toml @@ -1,5 +1,4 @@ -extend = "../wdk-build/rust-driver-makefile.toml" - -[tasks.infverif] -dependencies = ["wdk-samples-setup", "stampinf"] -condition = { env_not_set = ["WDK_INF_USING_NEW_VERSION"] } +extend = [ + { path = "../wdk-build/rust-driver-makefile.toml" }, + { path = "../wdk-build/rust-driver-sample-makefile.toml" }, +] diff --git a/crates/wdk-build/rust-driver-sample-makefile.toml b/crates/wdk-build/rust-driver-sample-makefile.toml new file mode 100644 index 00000000..ceb56023 --- /dev/null +++ b/crates/wdk-build/rust-driver-sample-makefile.toml @@ -0,0 +1,7 @@ +# This file is used to extend the standarrd rust-driver-makefile to build official sample drivers. See examples at https://github.com/microsoft/Windows-rust-drivers-samples +# Using this file requires extending both the standard makefile and this makefile in order, as follows: +# extend = [ { path = "target/rust-driver-makefile.toml" }, { path = "target/rust-driver-sample-makefile.toml" } ] + +[tasks.infverif] +dependencies = ["wdk-samples-setup", "stampinf"] +condition = { env_not_set = ["WDK_INF_USING_NEW_VERSION"] } diff --git a/crates/wdk-build/src/cargo_make.rs b/crates/wdk-build/src/cargo_make.rs index 11f9e12c..666d8b4a 100644 --- a/crates/wdk-build/src/cargo_make.rs +++ b/crates/wdk-build/src/cargo_make.rs @@ -10,7 +10,7 @@ use std::path::{Path, PathBuf}; -use cargo_metadata::MetadataCommand; +use cargo_metadata::{camino::Utf8Path, MetadataCommand}; use clap::{Args, Parser}; use crate::{ @@ -19,14 +19,19 @@ use crate::{ ConfigError, }; +/// The filename of the main makefile for Rust Windows drivers. +pub const RUST_DRIVER_MAKEFILE_NAME: &str = "rust-driver-makefile.toml"; +/// The filename of the samples makefile for Rust Windows drivers. +pub const RUST_DRIVER_SAMPLE_MAKEFILE_NAME: &str = "rust-driver-sample-makefile.toml"; + const PATH_ENV_VAR: &str = "Path"; /// The environment variable that [`setup_wdk_version`] stores the WDK version /// in. pub const WDK_VERSION_ENV_VAR: &str = "WDK_BUILD_DETECTED_WDK_VERSION"; /// The first WDK version with the new `InfVerif` behavior. -const WDK_INF_NEW_VERSION: i32 = 25798; +const MINIMUM_SAMPLES_FLAG_WDK_VERSION: i32 = 25798; const WDK_INF_ADDITIONAL_FLAGS_ENV_VAR: &str = "WDK_BUILD_ADDITIONAL_INFVERIF_FLAGS"; -const WDK_INF_NEW_VERSION_FLAG: &str = "WDK_INF_USING_NEW_VERSION"; +const WDK_INF_NEW_VERSION_FLAG_ENV_VAR: &str = "WDK_INF_USING_NEW_VERSION"; /// The name of the environment variable that cargo-make uses during `cargo /// build` and `cargo test` commands @@ -514,7 +519,9 @@ pub fn setup_wdk_version() -> Result { let version = get_latest_windows_sdk_version(&wdk_content_root.join("Lib"))?; println!("FORWARDING ARGS TO CARGO-MAKE:"); - crate::utils::validate_wdk_version_format(&version)?; + if !crate::utils::validate_wdk_version_format(&version) { + return Err(ConfigError::WDKVersionStringFormatError); + } append_to_space_delimited_env_var(WDK_VERSION_ENV_VAR, &version); forward_env_var_to_cargo_make(WDK_VERSION_ENV_VAR); @@ -539,7 +546,7 @@ pub fn setup_infverif_for_samples>(version: S) -> Result<(), Confi // multiple versions populating the environment variable let version = version.as_ref().split(' ').collect::>(); let version = version.first().unwrap_or(&"No version provided"); - let validated_version_string = crate::utils::validate_wdk_version_format(version)?; + let validated_version_string = crate::utils::get_wdk_version_number(version)?; // This print signifies the start of the forwarding and signals to the // `rust-env-update` plugin that it should forward args. This is also used to // signal that the auto-generated help from `clap` was not executed. @@ -549,10 +556,10 @@ pub fn setup_infverif_for_samples>(version: S) -> Result<(), Confi let version = validated_version_string .parse::() .expect("Unable to parse the build number of the WDK version string as an int!"); - let sample_flag = if version > WDK_INF_NEW_VERSION { - std::env::set_var(WDK_INF_NEW_VERSION_FLAG, "true"); - forward_env_var_to_cargo_make(WDK_INF_NEW_VERSION_FLAG); - "/samples" // Note: Not currently implemented, hence why we also set the WDK_INF_NEW_VERSION_FLAG + let sample_flag = if version > MINIMUM_SAMPLES_FLAG_WDK_VERSION { + std::env::set_var(WDK_INF_NEW_VERSION_FLAG_ENV_VAR, "true"); + forward_env_var_to_cargo_make(WDK_INF_NEW_VERSION_FLAG_ENV_VAR); + "/samples" // Note: Not currently implemented, hence why we also set the MINIMUM_SAMPLES_FLAG_WDK_VERSION_FLAG } else { "/msft" }; @@ -623,9 +630,9 @@ pub fn copy_to_driver_package_folder>(path_to_copy: P) -> Result< Ok(()) } -/// Symlinks `rust-driver-toolchain.toml` to the `target` folder where it can be +/// Symlinks `rust-driver-makefile.toml` to the `target` folder where it can be /// extended from a `Makefile.toml`. This is necessary so that paths in the -/// `rust-driver-toolchain.toml` can to be relative to +/// `rust-driver-makefile.toml` can to be relative to /// `CARGO_MAKE_CURRENT_TASK_INITIAL_MAKEFILE_DIRECTORY` /// /// # Errors @@ -636,13 +643,61 @@ pub fn copy_to_driver_package_folder>(path_to_copy: P) -> Result< /// - [`ConfigError::MultipleWDKBuildCratesDetected`] if there are multiple /// versions of the WDK build crate detected /// - [`ConfigError::IoError`] if there is an error creating or updating the -/// symlink to `rust-driver-toolchain.toml` +/// symlink to `rust-driver-makefile.toml` /// /// # Panics /// /// This function will panic if the `CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY` /// environment variable is not set pub fn load_rust_driver_makefile() -> Result<(), ConfigError> { + load_rust_driver_makefile_internal(RUST_DRIVER_MAKEFILE_NAME) +} + +/// Symlinks `rust-driversample-makefiletoml` to the `target` folder where it can be +/// extended from a `Makefile.toml`. This is necessary so that paths in the +/// `rust-driver-sample-makefile.toml` can to be relative to +/// `CARGO_MAKE_CURRENT_TASK_INITIAL_MAKEFILE_DIRECTORY` +/// +/// # Errors +/// +/// This function returns: +/// - [`ConfigError::CargoMetadataError`] if there is an error executing or +/// parsing `cargo_metadata` +/// - [`ConfigError::MultipleWDKBuildCratesDetected`] if there are multiple +/// versions of the WDK build crate detected +/// - [`ConfigError::IoError`] if there is an error creating or updating the +/// symlink to `rust-driver-sample-makefile.toml` +/// +/// # Panics +/// +/// This function will panic if the `CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY` +/// environment variable is not set +pub fn load_rust_driver_sample_makefile() -> Result<(), ConfigError> { + load_rust_driver_makefile_internal(RUST_DRIVER_SAMPLE_MAKEFILE_NAME) +} + +/// Symlinks a given Windows Driver rust makefile to the `target` folder where +/// it can be extended from a `Makefile.toml`. This is necessary so that paths +/// in the Windows Driver makefile can to be relative to +/// `CARGO_MAKE_CURRENT_TASK_INITIAL_MAKEFILE_DIRECTORY` +/// +/// # Errors +/// +/// This function returns: +/// - [`ConfigError::CargoMetadataError`] if there is an error executing or +/// parsing `cargo_metadata` +/// - [`ConfigError::MultipleWDKBuildCratesDetected`] if there are multiple +/// versions of the WDK build crate detected +/// - [`ConfigError::IoError`] if there is an error creating or updating the +/// symlink to `rust-driver-toolchain.toml` +/// +/// # Panics +/// +/// This function will panic if the `CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY` +/// environment variable is not set +fn load_rust_driver_makefile_internal + AsRef + AsRef>( + makefile_name: S, +) -> Result<(), ConfigError> { let cargo_metadata = MetadataCommand::new().exec()?; let wdk_build_package_matches = cargo_metadata @@ -663,15 +718,16 @@ pub fn load_rust_driver_makefile() -> Result<(), ConfigError> { .manifest_path .parent() .expect("The parsed manifest_path should have a valid parent directory") - .join("rust-driver-makefile.toml"); + .join(&makefile_name); let cargo_make_workspace_working_directory = std::env::var(CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY_ENV_VAR).unwrap_or_else(|_| { panic!("{CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY_ENV_VAR} should be set by cargo-make.") }); - let destination_path = - Path::new(&cargo_make_workspace_working_directory).join("target/rust-driver-makefile.toml"); + let destination_path = Path::new(&cargo_make_workspace_working_directory) + .join("target") + .join(&makefile_name); // Only create a new symlink if the existing one is not already pointing to the // correct file @@ -786,7 +842,7 @@ mod tests { #[test] fn check_env_passing() -> Result<(), ConfigError> { - crate::cargo_make::set_sample_infverif(WDK_TEST_OLD_INF_VERSION)?; + crate::cargo_make::setup_infverif_for_samples(WDK_TEST_OLD_INF_VERSION)?; let env_string = std::env::var_os(crate::cargo_make::WDK_INF_ADDITIONAL_FLAGS_ENV_VAR) .map_or_else( || panic!("Couldn't get OS string"), @@ -794,7 +850,7 @@ mod tests { ); assert_eq!(env_string.split(' ').last(), Some("/msft")); - crate::cargo_make::set_sample_infverif(WDK_TEST_NEW_INF_VERSION)?; + crate::cargo_make::setup_infverif_for_samples(WDK_TEST_NEW_INF_VERSION)?; let env_string = std::env::var_os(crate::cargo_make::WDK_INF_ADDITIONAL_FLAGS_ENV_VAR) .map_or_else( || panic!("Couldn't get OS string"), diff --git a/crates/wdk-build/src/utils.rs b/crates/wdk-build/src/utils.rs index 3f7d040b..8b58c48f 100644 --- a/crates/wdk-build/src/utils.rs +++ b/crates/wdk-build/src/utils.rs @@ -282,25 +282,19 @@ pub fn detect_cpu_architecture_in_build_script() -> CPUArchitecture { } /// Validates that a given string matches the WDK version format (10.xxx.yyy.zzz -/// where xxx, yyy, and zzz are numeric and not necessarily 3 digits long) -/// and returns the yyy portion (the build number) if so. -/// -/// # Errors -/// -/// This function returns a [`ConfigError::WDKVersionStringFormatError`] if the -/// version string provided is ill-formed. -pub fn validate_wdk_version_format>(version_string: &S) -> Result<&str, ConfigError> { +/// where xxx, yyy, and zzz are numeric and not necessarily 3 digits long). +pub fn validate_wdk_version_format>(version_string: S) -> bool { let version = version_string.as_ref(); let version_parts: Vec<&str> = version.split('.').collect(); // First, check if we have "10" as our first value if !version_parts.first().is_some_and(|first| *first == "10") { - return Err(ConfigError::WDKVersionStringFormatError); + return false; } // Now check that we have four entries. if version_parts.len() != 4 { - return Err(ConfigError::WDKVersionStringFormatError); + return false; } // Finally, confirm each part is numeric. @@ -308,13 +302,35 @@ pub fn validate_wdk_version_format>(version_string: &S) -> Result< .iter() .all(|version_part| version_part.parse::().is_ok()) { + return false; + } + + true +} + +/// Returns the version number from a full WDK version string. +/// +/// # Errors +/// +/// This function returns a [`ConfigError::WDKVersionStringFormatError`] if the +/// version string provided is ill-formed. +/// +/// # Panics +/// +/// If the WDK version format validation function is ever changed not to +/// validate that there are 4 substrings in the WDK version string, this +/// function will panic. +pub fn get_wdk_version_number>(version_string: S) -> Result { + if !validate_wdk_version_format(&version_string) { return Err(ConfigError::WDKVersionStringFormatError); } - // Now return the actual build number from the string (the yyy in - // 10.xxx.yyy.zzz). - // Safe to dereference as we validated we have 4 parts above. - Ok(version_parts[2]) + let version_substrings = version_string.as_ref().split('.').collect::>(); + let version_substring = version_substrings.get(2).expect( + "WDK version string was validated to be well-formatted, but we couldn't get the \ + appropriate substring!", + ); + Ok((*version_substring).to_string()) } #[cfg(test)] @@ -383,37 +399,43 @@ mod tests { #[test] fn validate_wdk_strings() { assert_eq!( - validate_wdk_version_format(&"10.0.12345.0").ok(), - Some("12345") + get_wdk_version_number("10.0.12345.0").ok(), + Some("12345".to_string()) + ); + assert_eq!( + get_wdk_version_number("10.0.5.0").ok(), + Some("5".to_string()) + ); + assert_eq!( + get_wdk_version_number("10.0.0.0").ok(), + Some("0".to_string()) ); - assert_eq!(validate_wdk_version_format(&"10.0.5.0").ok(), Some("5")); - assert_eq!(validate_wdk_version_format(&"10.0.0.0").ok(), Some("0")); assert!(matches!( - validate_wdk_version_format(&"11.0.0.0"), + get_wdk_version_number("11.0.0.0"), Err(ConfigError::WDKVersionStringFormatError) )); assert!(matches!( - validate_wdk_version_format(&"10.0.12345.0.0"), + get_wdk_version_number("10.0.12345.0.0"), Err(ConfigError::WDKVersionStringFormatError) )); assert!(matches!( - validate_wdk_version_format(&"10.0.12345.a"), + get_wdk_version_number("10.0.12345.a"), Err(ConfigError::WDKVersionStringFormatError) )); assert!(matches!( - validate_wdk_version_format(&"10.0.12345"), + get_wdk_version_number("10.0.12345"), Err(ConfigError::WDKVersionStringFormatError) )); assert!(matches!( - validate_wdk_version_format(&"10.0.1234!5.0"), + get_wdk_version_number("10.0.1234!5.0"), Err(ConfigError::WDKVersionStringFormatError) )); assert!(matches!( - validate_wdk_version_format(&"Not a real version!"), + get_wdk_version_number("Not a real version!"), Err(ConfigError::WDKVersionStringFormatError) )); assert!(matches!( - validate_wdk_version_format(&""), + get_wdk_version_number(""), Err(ConfigError::WDKVersionStringFormatError) )); } From 754e1f91fca4a76be7272328a958a801b957e8b4 Mon Sep 17 00:00:00 2001 From: NateD-MSFT <34494373+NateD-MSFT@users.noreply.github.com> Date: Thu, 9 May 2024 12:14:52 -0700 Subject: [PATCH 25/36] BUGGY: Attempt to refactor samples logic into makefiles --- crates/wdk-build/rust-driver-makefile.toml | 20 -------- .../rust-driver-sample-makefile.toml | 48 ++++++++++++++++++- crates/wdk-build/src/cargo_make.rs | 16 +++---- 3 files changed, 53 insertions(+), 31 deletions(-) diff --git a/crates/wdk-build/rust-driver-makefile.toml b/crates/wdk-build/rust-driver-makefile.toml index ae345e77..d383f584 100644 --- a/crates/wdk-build/rust-driver-makefile.toml +++ b/crates/wdk-build/rust-driver-makefile.toml @@ -83,26 +83,6 @@ wdk_build::cargo_make::setup_path()?; wdk_build::cargo_make::setup_wdk_version()?; ''' -[tasks.wdk-samples-setup] -private = true -dependencies = ["wdk-build-init"] -install_crate = { crate_name = "rust-script", min_version = "0.30.0" } -plugin = "rust-env-update" -script_runner = "@rust" -script = ''' -//! ```cargo -//! [dependencies] -//! wdk-build = { path = ".", version = "0.2.0" } -//! ``` -#![allow(unused_doc_comments)] -let env_string = std::env::var_os(wdk_build::cargo_make::WDK_VERSION_ENV_VAR) - .map_or_else( - || panic!("Couldn't read WDK build version that should have been set in init"), - |os_env_string| os_env_string.to_string_lossy().into_owned(), - ); -wdk_build::cargo_make::setup_infverif_for_samples(env_string)?; -''' - [tasks.copy-inx-to-output] private = true script_runner = "@rust" diff --git a/crates/wdk-build/rust-driver-sample-makefile.toml b/crates/wdk-build/rust-driver-sample-makefile.toml index ceb56023..77284c31 100644 --- a/crates/wdk-build/rust-driver-sample-makefile.toml +++ b/crates/wdk-build/rust-driver-sample-makefile.toml @@ -2,6 +2,52 @@ # Using this file requires extending both the standard makefile and this makefile in order, as follows: # extend = [ { path = "target/rust-driver-makefile.toml" }, { path = "target/rust-driver-sample-makefile.toml" } ] +[tasks.wdk-samples-setup] +private = true +dependencies = ["wdk-build-init"] +install_crate = { crate_name = "rust-script", min_version = "0.30.0" } +plugin = "rust-env-update" +script_runner = "@rust" +script = ''' +//! ```cargo +//! [dependencies] +//! wdk-build = { path = ".", version = "0.2.0" } +//! ``` +#![allow(unused_doc_comments)] +let env_string = std::env::var_os(wdk_build::cargo_make::WDK_VERSION_ENV_VAR) + .map_or_else( + || panic!("Couldn't read WDK build version that should have been set in init"), + |os_env_string| os_env_string.to_string_lossy().into_owned(), + ); +wdk_build::cargo_make::setup_infverif_for_samples(env_string)?; +''' + [tasks.infverif] dependencies = ["wdk-samples-setup", "stampinf"] -condition = { env_not_set = ["WDK_INF_USING_NEW_VERSION"] } +install_crate = { crate_name = "rust-script", min_version = "0.30.0" } +script_runner = "@rust" +condition_script = ''' +//! ```cargo +//! [dependencies] +//! wdk-build = { path = ".", version = "0.2.0" } +//! ``` +#![allow(unused_doc_comments)] + +// This range is inclusive of 25798. Will update with range end after /sample flag is added to InfVerif CLI +const MISSING_SAMPLE_FLAG_WDK_BUILD_NUMBER_RANGE: u32 = 25798..; + +std::panic::catch_unwind(|| { + let wdk_version = std::env::var(wdk_build::cargo_make::WDK_VERSION_ENV_VAR).expect("WDK_BUILD_DETECTED_VERSION should always be set by wdk-build-init cargo make task"); + let wdk_build_number = wdk_build::utils::get_wdk_build_number(wdk_version); + + if MISSING_SAMPLE_FLAG_WDK_BUILD_NUMBER_RANGE.contains(&wdk_build_number) { + // cargo_make will interpret returning an error from the rust-script condition_script as skipping the task + return Err(format!("Skipping InfVerif. InfVerif in WDK Build {version} is bugged and does not contain the /samples flag.").into()); + } + Ok(()) +}).unwrap_or_else(|_|{ + // panic contents would have already been printed to console + eprintln!("condition_script for infverif task panicked while executing. Defaulting to running inverif task."); + Ok(()) +})? +''' \ No newline at end of file diff --git a/crates/wdk-build/src/cargo_make.rs b/crates/wdk-build/src/cargo_make.rs index 666d8b4a..a54e9008 100644 --- a/crates/wdk-build/src/cargo_make.rs +++ b/crates/wdk-build/src/cargo_make.rs @@ -27,11 +27,10 @@ pub const RUST_DRIVER_SAMPLE_MAKEFILE_NAME: &str = "rust-driver-sample-makefile. const PATH_ENV_VAR: &str = "Path"; /// The environment variable that [`setup_wdk_version`] stores the WDK version /// in. -pub const WDK_VERSION_ENV_VAR: &str = "WDK_BUILD_DETECTED_WDK_VERSION"; +pub const WDK_VERSION_ENV_VAR: &str = "WDK_BUILD_DETECTED_VERSION"; /// The first WDK version with the new `InfVerif` behavior. const MINIMUM_SAMPLES_FLAG_WDK_VERSION: i32 = 25798; const WDK_INF_ADDITIONAL_FLAGS_ENV_VAR: &str = "WDK_BUILD_ADDITIONAL_INFVERIF_FLAGS"; -const WDK_INF_NEW_VERSION_FLAG_ENV_VAR: &str = "WDK_INF_USING_NEW_VERSION"; /// The name of the environment variable that cargo-make uses during `cargo /// build` and `cargo test` commands @@ -557,15 +556,12 @@ pub fn setup_infverif_for_samples>(version: S) -> Result<(), Confi .parse::() .expect("Unable to parse the build number of the WDK version string as an int!"); let sample_flag = if version > MINIMUM_SAMPLES_FLAG_WDK_VERSION { - std::env::set_var(WDK_INF_NEW_VERSION_FLAG_ENV_VAR, "true"); - forward_env_var_to_cargo_make(WDK_INF_NEW_VERSION_FLAG_ENV_VAR); - "/samples" // Note: Not currently implemented, hence why we also set the MINIMUM_SAMPLES_FLAG_WDK_VERSION_FLAG + "/samples" // Note: Not currently implemented, so in samples TOML we currently skip infverif } else { "/msft" }; append_to_space_delimited_env_var(WDK_INF_ADDITIONAL_FLAGS_ENV_VAR, sample_flag); forward_env_var_to_cargo_make(WDK_INF_ADDITIONAL_FLAGS_ENV_VAR); - // println!("{{{WDK_INF_ADDITIONAL_FLAGS_ENV_VAR}}}={}", sample_flag); Ok(()) } @@ -653,9 +649,9 @@ pub fn load_rust_driver_makefile() -> Result<(), ConfigError> { load_rust_driver_makefile_internal(RUST_DRIVER_MAKEFILE_NAME) } -/// Symlinks `rust-driversample-makefiletoml` to the `target` folder where it can be -/// extended from a `Makefile.toml`. This is necessary so that paths in the -/// `rust-driver-sample-makefile.toml` can to be relative to +/// Symlinks `rust-driversample-makefiletoml` to the `target` folder where it +/// can be extended from a `Makefile.toml`. This is necessary so that paths in +/// the `rust-driver-sample-makefile.toml` can to be relative to /// `CARGO_MAKE_CURRENT_TASK_INITIAL_MAKEFILE_DIRECTORY` /// /// # Errors @@ -689,7 +685,7 @@ pub fn load_rust_driver_sample_makefile() -> Result<(), ConfigError> { /// - [`ConfigError::MultipleWDKBuildCratesDetected`] if there are multiple /// versions of the WDK build crate detected /// - [`ConfigError::IoError`] if there is an error creating or updating the -/// symlink to `rust-driver-toolchain.toml` +/// symlink to the makefile. /// /// # Panics /// From cb6ce1d067073b62bc2457866ea3c956864ca51a Mon Sep 17 00:00:00 2001 From: NateD-MSFT <34494373+NateD-MSFT@users.noreply.github.com> Date: Thu, 9 May 2024 12:27:36 -0700 Subject: [PATCH 26/36] TOML formatting fix --- crates/wdk-build/rust-driver-sample-makefile.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/wdk-build/rust-driver-sample-makefile.toml b/crates/wdk-build/rust-driver-sample-makefile.toml index 77284c31..8eab479b 100644 --- a/crates/wdk-build/rust-driver-sample-makefile.toml +++ b/crates/wdk-build/rust-driver-sample-makefile.toml @@ -50,4 +50,4 @@ std::panic::catch_unwind(|| { eprintln!("condition_script for infverif task panicked while executing. Defaulting to running inverif task."); Ok(()) })? -''' \ No newline at end of file +''' From 2ad53a5d970aef67d028415aee1855bc55db050e Mon Sep 17 00:00:00 2001 From: NateD-MSFT <34494373+NateD-MSFT@users.noreply.github.com> Date: Thu, 9 May 2024 16:06:47 -0700 Subject: [PATCH 27/36] Various typos and language fixes Co-authored-by: Melvin Wang Signed-off-by: NateD-MSFT <34494373+NateD-MSFT@users.noreply.github.com> --- crates/wdk-build/rust-driver-sample-makefile.toml | 4 ++-- crates/wdk-build/src/cargo_make.rs | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/crates/wdk-build/rust-driver-sample-makefile.toml b/crates/wdk-build/rust-driver-sample-makefile.toml index 77284c31..ba98f4b9 100644 --- a/crates/wdk-build/rust-driver-sample-makefile.toml +++ b/crates/wdk-build/rust-driver-sample-makefile.toml @@ -1,4 +1,4 @@ -# This file is used to extend the standarrd rust-driver-makefile to build official sample drivers. See examples at https://github.com/microsoft/Windows-rust-drivers-samples +# This file is used to extend the standard rust-driver-makefile to build official sample drivers. See examples at https://github.com/microsoft/Windows-rust-drivers-samples # Using this file requires extending both the standard makefile and this makefile in order, as follows: # extend = [ { path = "target/rust-driver-makefile.toml" }, { path = "target/rust-driver-sample-makefile.toml" } ] @@ -33,7 +33,7 @@ condition_script = ''' //! ``` #![allow(unused_doc_comments)] -// This range is inclusive of 25798. Will update with range end after /sample flag is added to InfVerif CLI +// This range is inclusive of 25798. FIXME: update with range end after /sample flag is added to InfVerif CLI const MISSING_SAMPLE_FLAG_WDK_BUILD_NUMBER_RANGE: u32 = 25798..; std::panic::catch_unwind(|| { diff --git a/crates/wdk-build/src/cargo_make.rs b/crates/wdk-build/src/cargo_make.rs index a54e9008..2bb2e2e5 100644 --- a/crates/wdk-build/src/cargo_make.rs +++ b/crates/wdk-build/src/cargo_make.rs @@ -649,7 +649,7 @@ pub fn load_rust_driver_makefile() -> Result<(), ConfigError> { load_rust_driver_makefile_internal(RUST_DRIVER_MAKEFILE_NAME) } -/// Symlinks `rust-driversample-makefiletoml` to the `target` folder where it +/// Symlinks `rust-driver-sample-makefile.toml` to the `target` folder where it /// can be extended from a `Makefile.toml`. This is necessary so that paths in /// the `rust-driver-sample-makefile.toml` can to be relative to /// `CARGO_MAKE_CURRENT_TASK_INITIAL_MAKEFILE_DIRECTORY` @@ -672,9 +672,9 @@ pub fn load_rust_driver_sample_makefile() -> Result<(), ConfigError> { load_rust_driver_makefile_internal(RUST_DRIVER_SAMPLE_MAKEFILE_NAME) } -/// Symlinks a given Windows Driver rust makefile to the `target` folder where -/// it can be extended from a `Makefile.toml`. This is necessary so that paths -/// in the Windows Driver makefile can to be relative to +/// Symlinks a [`wdk_build`] `cargo-make` makefile to the `target` folder where +/// it can be extended from a downstream `Makefile.toml`. This is necessary so that paths +/// in the [`wdk_build`] makefile can be relative to /// `CARGO_MAKE_CURRENT_TASK_INITIAL_MAKEFILE_DIRECTORY` /// /// # Errors @@ -691,7 +691,7 @@ pub fn load_rust_driver_sample_makefile() -> Result<(), ConfigError> { /// /// This function will panic if the `CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY` /// environment variable is not set -fn load_rust_driver_makefile_internal + AsRef + AsRef>( +fn load_wdk_build_makefile + AsRef + AsRef>( makefile_name: S, ) -> Result<(), ConfigError> { let cargo_metadata = MetadataCommand::new().exec()?; From fb129de5ae80938b82d94745547b33e22283fb25 Mon Sep 17 00:00:00 2001 From: NateD-MSFT <34494373+NateD-MSFT@users.noreply.github.com> Date: Thu, 9 May 2024 16:35:07 -0700 Subject: [PATCH 28/36] BUGGY: Add new plugin to work with cargo make paths --- .../rust-driver-sample-makefile.toml | 26 ++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/crates/wdk-build/rust-driver-sample-makefile.toml b/crates/wdk-build/rust-driver-sample-makefile.toml index 8eab479b..ac2dcd90 100644 --- a/crates/wdk-build/rust-driver-sample-makefile.toml +++ b/crates/wdk-build/rust-driver-sample-makefile.toml @@ -1,10 +1,29 @@ -# This file is used to extend the standarrd rust-driver-makefile to build official sample drivers. See examples at https://github.com/microsoft/Windows-rust-drivers-samples +# This file is used to extend the standard rust-driver-makefile to build official sample drivers. See examples at https://github.com/microsoft/Windows-rust-drivers-samples # Using this file requires extending both the standard makefile and this makefile in order, as follows: # extend = [ { path = "target/rust-driver-makefile.toml" }, { path = "target/rust-driver-sample-makefile.toml" } ] +# This plugin replaces the embedded `CARGO_MAKE_CURRENT_TASK_INITIAL_MAKEFILE_DIRECTORY` in the rust-script doc comment with its evaluated value. See https://github.com/sagiegurari/cargo-make/issues/1081 for more context. +[plugins.impl.rust-condition-script-cargo_make_current_task_initial_makefile_directory-substitution] +script = ''' +# Parse task json into variables +taskjson = json_parse ${task.as_json} + +# Convert backslashes to forward slashes +rust-driver-toolchain-path = replace ${taskjson.env.CARGO_MAKE_CURRENT_TASK_INITIAL_MAKEFILE_DIRECTORY} "\\" "/" + +# Replace the ${CARGO_MAKE_CURRENT_TASK_INITIAL_MAKEFILE_DIRECTORY} variable in the condition_script with the rust-driver-toolchain-path +taskjson.condition_script = replace ${taskjson.condition_script} "\${CARGO_MAKE_CURRENT_TASK_INITIAL_MAKEFILE_DIRECTORY}" "${rust-driver-toolchain-path}" + +# Reencode variables into json +taskjson = json_encode taskjson + +# Run the invoking task, with the modified condition_script +cm_plugin_run_custom_task ${taskjson} +''' + + [tasks.wdk-samples-setup] private = true -dependencies = ["wdk-build-init"] install_crate = { crate_name = "rust-script", min_version = "0.30.0" } plugin = "rust-env-update" script_runner = "@rust" @@ -26,10 +45,11 @@ wdk_build::cargo_make::setup_infverif_for_samples(env_string)?; dependencies = ["wdk-samples-setup", "stampinf"] install_crate = { crate_name = "rust-script", min_version = "0.30.0" } script_runner = "@rust" +plugin = "rust-condition-script-cargo_make_current_task_initial_makefile_directory-substitution" condition_script = ''' //! ```cargo //! [dependencies] -//! wdk-build = { path = ".", version = "0.2.0" } +//! wdk-build = { path = "${CARGO_MAKE_CURRENT_TASK_INITIAL_MAKEFILE_DIRECTORY}", version = "0.2.0" } //! ``` #![allow(unused_doc_comments)] From 916fe8f45eb4598abbe762d7920e83df49c642ec Mon Sep 17 00:00:00 2001 From: NateD-MSFT <34494373+NateD-MSFT@users.noreply.github.com> Date: Thu, 9 May 2024 16:38:08 -0700 Subject: [PATCH 29/36] Fix an updated function name --- crates/wdk-build/src/cargo_make.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/crates/wdk-build/src/cargo_make.rs b/crates/wdk-build/src/cargo_make.rs index 2bb2e2e5..b239be00 100644 --- a/crates/wdk-build/src/cargo_make.rs +++ b/crates/wdk-build/src/cargo_make.rs @@ -646,7 +646,7 @@ pub fn copy_to_driver_package_folder>(path_to_copy: P) -> Result< /// This function will panic if the `CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY` /// environment variable is not set pub fn load_rust_driver_makefile() -> Result<(), ConfigError> { - load_rust_driver_makefile_internal(RUST_DRIVER_MAKEFILE_NAME) + load_wdk_build_makefile(RUST_DRIVER_MAKEFILE_NAME) } /// Symlinks `rust-driver-sample-makefile.toml` to the `target` folder where it @@ -669,12 +669,12 @@ pub fn load_rust_driver_makefile() -> Result<(), ConfigError> { /// This function will panic if the `CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY` /// environment variable is not set pub fn load_rust_driver_sample_makefile() -> Result<(), ConfigError> { - load_rust_driver_makefile_internal(RUST_DRIVER_SAMPLE_MAKEFILE_NAME) + load_wdk_build_makefile(RUST_DRIVER_SAMPLE_MAKEFILE_NAME) } /// Symlinks a [`wdk_build`] `cargo-make` makefile to the `target` folder where -/// it can be extended from a downstream `Makefile.toml`. This is necessary so that paths -/// in the [`wdk_build`] makefile can be relative to +/// it can be extended from a downstream `Makefile.toml`. This is necessary so +/// that paths in the [`wdk_build`] makefile can be relative to /// `CARGO_MAKE_CURRENT_TASK_INITIAL_MAKEFILE_DIRECTORY` /// /// # Errors From bb5da2e42494b442a9403f7307f842622e3f46fe Mon Sep 17 00:00:00 2001 From: NateD-MSFT <34494373+NateD-MSFT@users.noreply.github.com> Date: Mon, 13 May 2024 15:48:57 -0700 Subject: [PATCH 30/36] Update crates/wdk-build/rust-driver-sample-makefile.toml Committing and signing off to see if the cloud build works where my local environment doesn't. Co-authored-by: Melvin Wang Signed-off-by: NateD-MSFT <34494373+NateD-MSFT@users.noreply.github.com> --- crates/wdk-build/rust-driver-sample-makefile.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/wdk-build/rust-driver-sample-makefile.toml b/crates/wdk-build/rust-driver-sample-makefile.toml index f37f1357..9b162997 100644 --- a/crates/wdk-build/rust-driver-sample-makefile.toml +++ b/crates/wdk-build/rust-driver-sample-makefile.toml @@ -43,10 +43,10 @@ wdk_build::cargo_make::setup_infverif_for_samples(env_string)?; [tasks.infverif] dependencies = ["wdk-samples-setup", "stampinf"] -install_crate = { crate_name = "rust-script", min_version = "0.30.0" } -script_runner = "@rust" plugin = "rust-condition-script-cargo_make_current_task_initial_makefile_directory-substitution" condition_script = ''' +#!@rust + //! ```cargo //! [dependencies] //! wdk-build = { path = "${CARGO_MAKE_CURRENT_TASK_INITIAL_MAKEFILE_DIRECTORY}", version = "0.2.0" } From a33c93d0d44d8b4060c26416321d2b47f78e55f8 Mon Sep 17 00:00:00 2001 From: NateD-MSFT <34494373+NateD-MSFT@users.noreply.github.com> Date: Wed, 15 May 2024 21:02:19 -0700 Subject: [PATCH 31/36] Fix conditional-script behavior --- crates/wdk-build/rust-driver-sample-makefile.toml | 15 ++++++++++----- crates/wdk-build/src/cargo_make.rs | 12 ++++++++++++ crates/wdk-build/src/lib.rs | 3 ++- crates/wdk-build/src/utils.rs | 6 ++++++ 4 files changed, 30 insertions(+), 6 deletions(-) diff --git a/crates/wdk-build/rust-driver-sample-makefile.toml b/crates/wdk-build/rust-driver-sample-makefile.toml index f37f1357..850cbb22 100644 --- a/crates/wdk-build/rust-driver-sample-makefile.toml +++ b/crates/wdk-build/rust-driver-sample-makefile.toml @@ -14,6 +14,9 @@ rust-driver-toolchain-path = replace ${taskjson.env.CARGO_MAKE_CURRENT_TASK_INIT # Replace the ${CARGO_MAKE_CURRENT_TASK_INITIAL_MAKEFILE_DIRECTORY} variable in the condition_script with the rust-driver-toolchain-path taskjson.condition_script = replace ${taskjson.condition_script} "\${CARGO_MAKE_CURRENT_TASK_INITIAL_MAKEFILE_DIRECTORY}" "${rust-driver-toolchain-path}" +# Unset the private flag since it breaks cm_plugin_run_custom_task +unset taskjson.private + # Reencode variables into json taskjson = json_encode taskjson @@ -43,26 +46,28 @@ wdk_build::cargo_make::setup_infverif_for_samples(env_string)?; [tasks.infverif] dependencies = ["wdk-samples-setup", "stampinf"] -install_crate = { crate_name = "rust-script", min_version = "0.30.0" } -script_runner = "@rust" plugin = "rust-condition-script-cargo_make_current_task_initial_makefile_directory-substitution" condition_script = ''' +#!@rust + //! ```cargo //! [dependencies] //! wdk-build = { path = "${CARGO_MAKE_CURRENT_TASK_INITIAL_MAKEFILE_DIRECTORY}", version = "0.2.0" } //! ``` #![allow(unused_doc_comments)] +use core::ops::RangeFrom; + // This range is inclusive of 25798. FIXME: update with range end after /sample flag is added to InfVerif CLI -const MISSING_SAMPLE_FLAG_WDK_BUILD_NUMBER_RANGE: u32 = 25798..; +const MISSING_SAMPLE_FLAG_WDK_BUILD_NUMBER_RANGE: RangeFrom = 25798..; std::panic::catch_unwind(|| { let wdk_version = std::env::var(wdk_build::cargo_make::WDK_VERSION_ENV_VAR).expect("WDK_BUILD_DETECTED_VERSION should always be set by wdk-build-init cargo make task"); - let wdk_build_number = wdk_build::utils::get_wdk_build_number(wdk_version); + let wdk_build_number = str::parse::(&wdk_build::utils::get_wdk_version_number(wdk_version.clone()).expect(&format!("Couldn't get WDK version number! Version number: {}", wdk_version))).expect("Couldn't parse WDK version number!"); if MISSING_SAMPLE_FLAG_WDK_BUILD_NUMBER_RANGE.contains(&wdk_build_number) { // cargo_make will interpret returning an error from the rust-script condition_script as skipping the task - return Err(format!("Skipping InfVerif. InfVerif in WDK Build {version} is bugged and does not contain the /samples flag.").into()); + return Err::<(), String>(format!("Skipping InfVerif. InfVerif in WDK Build {wdk_build_number} is bugged and does not contain the /samples flag.").into()); } Ok(()) }).unwrap_or_else(|_|{ diff --git a/crates/wdk-build/src/cargo_make.rs b/crates/wdk-build/src/cargo_make.rs index b239be00..49c6aefd 100644 --- a/crates/wdk-build/src/cargo_make.rs +++ b/crates/wdk-build/src/cargo_make.rs @@ -517,6 +517,18 @@ pub fn setup_wdk_version() -> Result { }; let version = get_latest_windows_sdk_version(&wdk_content_root.join("Lib"))?; + let existing_version = std::env::var(WDK_VERSION_ENV_VAR).ok(); + if existing_version.is_some() { + if version == existing_version.unwrap() { + // Skip updating. This can happen in certain recursive + // cargo-make cases. + return Ok(version); + } else { + // We have a bad version string set somehow. Return an error. + return Err(ConfigError::WDKContentRootDetectionError); + } + } + println!("FORWARDING ARGS TO CARGO-MAKE:"); if !crate::utils::validate_wdk_version_format(&version) { return Err(ConfigError::WDKVersionStringFormatError); diff --git a/crates/wdk-build/src/lib.rs b/crates/wdk-build/src/lib.rs index 7e83cd62..6278de09 100644 --- a/crates/wdk-build/src/lib.rs +++ b/crates/wdk-build/src/lib.rs @@ -13,7 +13,8 @@ #![cfg_attr(nightly_toolchain, feature(assert_matches))] mod bindgen; -mod utils; +/// Module for utility code related to the cargo-make experience for building drivers. +pub mod utils; pub mod cargo_make; diff --git a/crates/wdk-build/src/utils.rs b/crates/wdk-build/src/utils.rs index 05a5c63c..9c84cbef 100644 --- a/crates/wdk-build/src/utils.rs +++ b/crates/wdk-build/src/utils.rs @@ -26,14 +26,20 @@ use crate::{CPUArchitecture, ConfigError}; /// Errors that may occur when stripping the extended path prefix from a path #[derive(Debug, Error, PartialEq, Eq)] pub enum StripExtendedPathPrefixError { + /// Error raised when the provided path is empty. #[error("provided path is empty")] EmptyPath, + /// Error raised when the provided path has no extended path prefix to strip. #[error("provided path has no extended path prefix to strip")] NoExtendedPathPrefix, } + +/// A trait for dealing with paths with extended-length prefixes. pub trait PathExt { + /// The kinds of errors that can be returned when trying to deal with an extended path prefix. type Error; + /// Strips the extended length path prefix from a given path. fn strip_extended_length_path_prefix(&self) -> Result; } From f0cf0e4e55c13b34bf04b1acbbb4a7180e4ec552 Mon Sep 17 00:00:00 2001 From: NateD-MSFT <34494373+NateD-MSFT@users.noreply.github.com> Date: Wed, 15 May 2024 21:26:42 -0700 Subject: [PATCH 32/36] Clippy/fmt fixes --- crates/wdk-build/src/cargo_make.rs | 10 ++++------ crates/wdk-build/src/lib.rs | 3 ++- crates/wdk-build/src/utils.rs | 27 +++++++++++++++++++++++++-- 3 files changed, 31 insertions(+), 9 deletions(-) diff --git a/crates/wdk-build/src/cargo_make.rs b/crates/wdk-build/src/cargo_make.rs index 49c6aefd..20af9565 100644 --- a/crates/wdk-build/src/cargo_make.rs +++ b/crates/wdk-build/src/cargo_make.rs @@ -517,16 +517,14 @@ pub fn setup_wdk_version() -> Result { }; let version = get_latest_windows_sdk_version(&wdk_content_root.join("Lib"))?; - let existing_version = std::env::var(WDK_VERSION_ENV_VAR).ok(); - if existing_version.is_some() { - if version == existing_version.unwrap() { + if let Ok(existing_version) = std::env::var(WDK_VERSION_ENV_VAR) { + if version == existing_version { // Skip updating. This can happen in certain recursive // cargo-make cases. return Ok(version); - } else { - // We have a bad version string set somehow. Return an error. - return Err(ConfigError::WDKContentRootDetectionError); } + // We have a bad version string set somehow. Return an error. + return Err(ConfigError::WDKContentRootDetectionError); } println!("FORWARDING ARGS TO CARGO-MAKE:"); diff --git a/crates/wdk-build/src/lib.rs b/crates/wdk-build/src/lib.rs index 6278de09..c759698f 100644 --- a/crates/wdk-build/src/lib.rs +++ b/crates/wdk-build/src/lib.rs @@ -13,7 +13,8 @@ #![cfg_attr(nightly_toolchain, feature(assert_matches))] mod bindgen; -/// Module for utility code related to the cargo-make experience for building drivers. +/// Module for utility code related to the cargo-make experience for building +/// drivers. pub mod utils; pub mod cargo_make; diff --git a/crates/wdk-build/src/utils.rs b/crates/wdk-build/src/utils.rs index 9c84cbef..189e3f84 100644 --- a/crates/wdk-build/src/utils.rs +++ b/crates/wdk-build/src/utils.rs @@ -29,17 +29,24 @@ pub enum StripExtendedPathPrefixError { /// Error raised when the provided path is empty. #[error("provided path is empty")] EmptyPath, - /// Error raised when the provided path has no extended path prefix to strip. + /// Error raised when the provided path has no extended path prefix to + /// strip. #[error("provided path has no extended path prefix to strip")] NoExtendedPathPrefix, } /// A trait for dealing with paths with extended-length prefixes. pub trait PathExt { - /// The kinds of errors that can be returned when trying to deal with an extended path prefix. + /// The kinds of errors that can be returned when trying to deal with an + /// extended path prefix. type Error; /// Strips the extended length path prefix from a given path. + /// # Errors + /// + /// Returns an error defined by the implementer if unable to strip the + /// extended path length prefix. + fn strip_extended_length_path_prefix(&self) -> Result; } @@ -74,6 +81,7 @@ where /// Detect `WDKContentRoot` Directory. Logic is based off of Toolset.props in /// NI(22H2) WDK +#[must_use] pub fn detect_wdk_content_root() -> Option { // If WDKContentRoot is present in environment(ex. running in an eWDK prompt), // use it @@ -250,6 +258,15 @@ fn read_registry_key_string_value( /// Searches a directory and determines the latest windows SDK version in that /// directory +/// +/// # Errors +/// +/// Returns a `ConfigError::DirectoryNotFound` error if the directory provided +/// does not exist. +/// +/// # Panics +/// +/// Panics if the path provided is not valid Unicode. pub fn get_latest_windows_sdk_version(path_to_search: &Path) -> Result { Ok(path_to_search .read_dir()? @@ -278,6 +295,12 @@ pub fn get_latest_windows_sdk_version(path_to_search: &Path) -> Result CPUArchitecture { let target_arch = std::env::var("CARGO_CFG_TARGET_ARCH").expect( "Cargo should have set the CARGO_CFG_TARGET_ARCH environment variable when executing \ From cb9b7d52e1011cb4d344361305228906a12a85de Mon Sep 17 00:00:00 2001 From: NateD-MSFT <34494373+NateD-MSFT@users.noreply.github.com> Date: Wed, 15 May 2024 22:14:44 -0700 Subject: [PATCH 33/36] Remove pub marker on utils I thought this needed to be made pub when I was testing, but I think it was a side effect of how I was testing my script while blocked on the cargo make bug. So this shouldn't need to be pub specifically. --- crates/wdk-build/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/wdk-build/src/lib.rs b/crates/wdk-build/src/lib.rs index c759698f..6053c116 100644 --- a/crates/wdk-build/src/lib.rs +++ b/crates/wdk-build/src/lib.rs @@ -15,7 +15,7 @@ mod bindgen; /// Module for utility code related to the cargo-make experience for building /// drivers. -pub mod utils; +mod utils; pub mod cargo_make; From 52c9ce692d7ffad201128170179575ac6162cd51 Mon Sep 17 00:00:00 2001 From: NateD-MSFT <34494373+NateD-MSFT@users.noreply.github.com> Date: Thu, 23 May 2024 14:18:30 -0500 Subject: [PATCH 34/36] Add version field to WDKVersionStringFormatError --- crates/wdk-build/src/cargo_make.rs | 10 ++- crates/wdk-build/src/lib.rs | 7 +- crates/wdk-build/src/utils.rs | 103 +++++++++++++++++++---------- 3 files changed, 78 insertions(+), 42 deletions(-) diff --git a/crates/wdk-build/src/cargo_make.rs b/crates/wdk-build/src/cargo_make.rs index 20af9565..cd27282f 100644 --- a/crates/wdk-build/src/cargo_make.rs +++ b/crates/wdk-build/src/cargo_make.rs @@ -529,7 +529,7 @@ pub fn setup_wdk_version() -> Result { println!("FORWARDING ARGS TO CARGO-MAKE:"); if !crate::utils::validate_wdk_version_format(&version) { - return Err(ConfigError::WDKVersionStringFormatError); + return Err(ConfigError::WDKVersionStringFormatError { version }); } append_to_space_delimited_env_var(WDK_VERSION_ENV_VAR, &version); @@ -550,11 +550,9 @@ pub fn setup_wdk_version() -> Result { /// This function will panic if the function for validating a WDK version string /// is ever changed to no longer validate that each part of the version string /// is an i32. -pub fn setup_infverif_for_samples>(version: S) -> Result<(), ConfigError> { - // The below two lines are just to unblock while debugging an issue with - // multiple versions populating the environment variable - let version = version.as_ref().split(' ').collect::>(); - let version = version.first().unwrap_or(&"No version provided"); +pub fn setup_infverif_for_samples + ToString + ?Sized>( + version: &S, +) -> Result<(), ConfigError> { let validated_version_string = crate::utils::get_wdk_version_number(version)?; // This print signifies the start of the forwarding and signals to the // `rust-env-update` plugin that it should forward args. This is also used to diff --git a/crates/wdk-build/src/lib.rs b/crates/wdk-build/src/lib.rs index 6053c116..9561b753 100644 --- a/crates/wdk-build/src/lib.rs +++ b/crates/wdk-build/src/lib.rs @@ -123,8 +123,11 @@ pub enum ConfigError { /// Error returned when the WDK version string does not match the expected /// format - #[error("The WDK version string provided was not in a valid format.")] - WDKVersionStringFormatError, + #[error("The WDK version string provided ({version}) was not in a valid format.")] + WDKVersionStringFormatError { + /// The incorrect WDK version string. + version: String, + }, /// Error returned when `cargo_metadata` execution or parsing fails #[error(transparent)] diff --git a/crates/wdk-build/src/utils.rs b/crates/wdk-build/src/utils.rs index 189e3f84..e2acbf97 100644 --- a/crates/wdk-build/src/utils.rs +++ b/crates/wdk-build/src/utils.rs @@ -351,9 +351,13 @@ pub fn validate_wdk_version_format>(version_string: S) -> bool { /// If the WDK version format validation function is ever changed not to /// validate that there are 4 substrings in the WDK version string, this /// function will panic. -pub fn get_wdk_version_number>(version_string: S) -> Result { - if !validate_wdk_version_format(&version_string) { - return Err(ConfigError::WDKVersionStringFormatError); +pub fn get_wdk_version_number + ToString + ?Sized>( + version_string: &S, +) -> Result { + if !validate_wdk_version_format(version_string) { + return Err(ConfigError::WDKVersionStringFormatError { + version: version_string.to_string(), + }); } let version_substrings = version_string.as_ref().split('.').collect::>(); @@ -429,45 +433,76 @@ mod tests { #[test] fn validate_wdk_strings() { + let test_string = "10.0.12345.0"; assert_eq!( - get_wdk_version_number("10.0.12345.0").ok(), + get_wdk_version_number(test_string).ok(), Some("12345".to_string()) ); + let test_string = "10.0.5.0"; assert_eq!( - get_wdk_version_number("10.0.5.0").ok(), + get_wdk_version_number(test_string).ok(), Some("5".to_string()) ); + let test_string = "10.0.0.0"; assert_eq!( - get_wdk_version_number("10.0.0.0").ok(), + get_wdk_version_number(test_string).ok(), Some("0".to_string()) ); - assert!(matches!( - get_wdk_version_number("11.0.0.0"), - Err(ConfigError::WDKVersionStringFormatError) - )); - assert!(matches!( - get_wdk_version_number("10.0.12345.0.0"), - Err(ConfigError::WDKVersionStringFormatError) - )); - assert!(matches!( - get_wdk_version_number("10.0.12345.a"), - Err(ConfigError::WDKVersionStringFormatError) - )); - assert!(matches!( - get_wdk_version_number("10.0.12345"), - Err(ConfigError::WDKVersionStringFormatError) - )); - assert!(matches!( - get_wdk_version_number("10.0.1234!5.0"), - Err(ConfigError::WDKVersionStringFormatError) - )); - assert!(matches!( - get_wdk_version_number("Not a real version!"), - Err(ConfigError::WDKVersionStringFormatError) - )); - assert!(matches!( - get_wdk_version_number(""), - Err(ConfigError::WDKVersionStringFormatError) - )); + let test_string = "11.0.0.0"; + assert_eq!( + format!("{}", get_wdk_version_number(test_string).err().unwrap()), + format!( + "The WDK version string provided ({}) was not in a valid format.", + test_string + ) + ); + let test_string = "10.0.12345.0.0"; + assert_eq!( + format!("{}", get_wdk_version_number(test_string).err().unwrap()), + format!( + "The WDK version string provided ({}) was not in a valid format.", + test_string + ) + ); + let test_string = "10.0.12345.a"; + assert_eq!( + format!("{}", get_wdk_version_number(test_string).err().unwrap()), + format!( + "The WDK version string provided ({}) was not in a valid format.", + test_string + ) + ); + let test_string = "10.0.12345"; + assert_eq!( + format!("{}", get_wdk_version_number(test_string).err().unwrap()), + format!( + "The WDK version string provided ({}) was not in a valid format.", + test_string + ) + ); + let test_string = "10.0.1234!5.0"; + assert_eq!( + format!("{}", get_wdk_version_number(test_string).err().unwrap()), + format!( + "The WDK version string provided ({}) was not in a valid format.", + test_string + ) + ); + let test_string = "Not a real version!"; + assert_eq!( + format!("{}", get_wdk_version_number(test_string).err().unwrap()), + format!( + "The WDK version string provided ({}) was not in a valid format.", + test_string + ) + ); + let test_string = ""; + assert_eq!( + format!("{}", get_wdk_version_number(test_string).err().unwrap()), + format!( + "The WDK version string provided ({}) was not in a valid format.", + test_string + ) + ); } } From 5f2ac5798e518d8b37abb5e8ebf28f23667882f2 Mon Sep 17 00:00:00 2001 From: NateD-MSFT <34494373+NateD-MSFT@users.noreply.github.com> Date: Thu, 30 May 2024 12:52:38 -0500 Subject: [PATCH 35/36] Fix a missing reference in make script --- crates/wdk-build/rust-driver-sample-makefile.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/wdk-build/rust-driver-sample-makefile.toml b/crates/wdk-build/rust-driver-sample-makefile.toml index 850cbb22..66c0fc22 100644 --- a/crates/wdk-build/rust-driver-sample-makefile.toml +++ b/crates/wdk-build/rust-driver-sample-makefile.toml @@ -41,7 +41,7 @@ let env_string = std::env::var_os(wdk_build::cargo_make::WDK_VERSION_ENV_VAR) || panic!("Couldn't read WDK build version that should have been set in init"), |os_env_string| os_env_string.to_string_lossy().into_owned(), ); -wdk_build::cargo_make::setup_infverif_for_samples(env_string)?; +wdk_build::cargo_make::setup_infverif_for_samples(&env_string)?; ''' [tasks.infverif] From 8cb33114100492f826a8ffbd00e71529d8960ab2 Mon Sep 17 00:00:00 2001 From: NateD-MSFT <34494373+NateD-MSFT@users.noreply.github.com> Date: Thu, 30 May 2024 13:55:33 -0500 Subject: [PATCH 36/36] A few more fixes to the make script --- crates/wdk-build/rust-driver-sample-makefile.toml | 2 +- crates/wdk-build/src/lib.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/wdk-build/rust-driver-sample-makefile.toml b/crates/wdk-build/rust-driver-sample-makefile.toml index 66c0fc22..8b5cf74c 100644 --- a/crates/wdk-build/rust-driver-sample-makefile.toml +++ b/crates/wdk-build/rust-driver-sample-makefile.toml @@ -63,7 +63,7 @@ const MISSING_SAMPLE_FLAG_WDK_BUILD_NUMBER_RANGE: RangeFrom = 25798..; std::panic::catch_unwind(|| { let wdk_version = std::env::var(wdk_build::cargo_make::WDK_VERSION_ENV_VAR).expect("WDK_BUILD_DETECTED_VERSION should always be set by wdk-build-init cargo make task"); - let wdk_build_number = str::parse::(&wdk_build::utils::get_wdk_version_number(wdk_version.clone()).expect(&format!("Couldn't get WDK version number! Version number: {}", wdk_version))).expect("Couldn't parse WDK version number!"); + let wdk_build_number = str::parse::(&wdk_build::utils::get_wdk_version_number(&wdk_version).unwrap()).expect(&format!("Couldn't parse WDK version number! Version number: {}", wdk_version)); if MISSING_SAMPLE_FLAG_WDK_BUILD_NUMBER_RANGE.contains(&wdk_build_number) { // cargo_make will interpret returning an error from the rust-script condition_script as skipping the task diff --git a/crates/wdk-build/src/lib.rs b/crates/wdk-build/src/lib.rs index 9561b753..cb55083e 100644 --- a/crates/wdk-build/src/lib.rs +++ b/crates/wdk-build/src/lib.rs @@ -15,7 +15,7 @@ mod bindgen; /// Module for utility code related to the cargo-make experience for building /// drivers. -mod utils; +pub mod utils; pub mod cargo_make;