diff --git a/crates/wdk-build/rust-driver-makefile.toml b/crates/wdk-build/rust-driver-makefile.toml index 903af810..e681d441 100644 --- a/crates/wdk-build/rust-driver-makefile.toml +++ b/crates/wdk-build/rust-driver-makefile.toml @@ -406,17 +406,23 @@ args = [ [tasks.generate-certificate] private = true +condition_script_runner_args = [ + "--base-path", + "${CARGO_MAKE_CURRENT_TASK_INITIAL_MAKEFILE_DIRECTORY}", +] condition_script = ''' -#!@duckscript +#!@rust -out = exec certmgr.exe -put -s WDRTestCertStore -c -n WDRLocalTestCert ${WDK_BUILD_OUTPUT_DIRECTORY}/WDRLocalTestCert.cer -if eq ${out.code} 0 - echo WDRLocalTestCert found in WDRTestCertStore. Skipping certificate generation. - exit 1 -else - echo WDRLocalTestCert not found in WDRTestCertStore. Generating new certificate. - exit 0 -end +//! ```cargo +//! [dependencies] +//! wdk-build = { path = ".", version = "0.3.0" } +//! anyhow = "1" +//! ``` +#![allow(unused_doc_comments)] + +fn main() -> anyhow::Result<()> { + wdk_build::cargo_make::generate_certificate_condition_script() +} ''' command = "makecert" args = [ diff --git a/crates/wdk-build/src/cargo_make.rs b/crates/wdk-build/src/cargo_make.rs index 26be9942..19b10179 100644 --- a/crates/wdk-build/src/cargo_make.rs +++ b/crates/wdk-build/src/cargo_make.rs @@ -16,6 +16,7 @@ use std::{ env, panic::UnwindSafe, path::{Path, PathBuf}, + process::Command, }; use anyhow::Context; @@ -1007,6 +1008,51 @@ pub fn package_driver_flow_condition_script() -> anyhow::Result<()> { }) } +/// `cargo-make` condition script for `generate-certificate` task in +/// [`rust-driver-makefile.toml`](../rust-driver-makefile.toml) +/// +/// # Errors +/// +/// This functions returns an error whenever it determines that the +/// `generate-certificate` `cargo-make` task should be skipped. This only +/// occurs when the `WdrLocalTestCert` cannot be added from the build directory +/// to `WDRTestCertStore`. +/// +/// # Panics +/// +/// Panics if certmgr is unable to be run. +pub fn generate_certificate_condition_script() -> anyhow::Result<()> { + condition_script(|| { + let output = Command::new("certmgr") + .args([ + "-put", + "-s", + "WDRTestCertStore", + "-c", + "-n", + "WdrLocalTestCert", + ]) + .arg(get_wdk_build_output_directory().join("WDRLocalTestCert.cer")) + .output() + .expect("Failed to run certmgr.exe."); + + match output.status.code() { + Some(0) => Err(anyhow::anyhow!( + "WDRLocalTestCert already in WDRTestCertStore. Skipping certificate generation." + )), + Some(1) => Ok(()), + Some(_) => { + eprintln!("Unknown status code found from certmgr. Generating certificate."); + Ok(()) + } + None => { + eprintln!("No status code found from certmgr. Generating certificate."); + Ok(()) + } + } + }) +} + fn configure_wdf_build_output_dir(target_arg: Option<&String>, cargo_make_cargo_profile: &str) { let cargo_make_crate_custom_triple_target_directory = env::var(CARGO_MAKE_CRATE_CUSTOM_TRIPLE_TARGET_DIRECTORY_ENV_VAR).unwrap_or_else(|_| {