-
Notifications
You must be signed in to change notification settings - Fork 128
feat(cargo-wdk): add --target-platform option to the build command
#683
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 4 commits
0423f71
a1c2dbb
76f1a98
193cd94
455e48f
494c9d7
724504b
e25924c
546d35e
dc4933b
6e3c59f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -30,6 +30,13 @@ use windows::{ | |
| use crate::providers::{exec::CommandExec, fs::Fs, wdk_build::WdkBuild}; | ||
| use crate::{actions::build::error::PackageTaskError, providers::error::FileError}; | ||
|
|
||
| // FIXME: This range is inclusive of 25798. Update with range end after /sample | ||
| // flag is added to InfVerif CLI | ||
|
svasista-ms marked this conversation as resolved.
Outdated
svasista-ms marked this conversation as resolved.
Outdated
|
||
| const MISSING_SAMPLE_FLAG_WDK_BUILD_NUMBER_RANGE: RangeFrom<u32> = 25798..; | ||
|
svasista-ms marked this conversation as resolved.
|
||
| const WDR_TEST_CERT_STORE: &str = "WDRTestCertStore"; | ||
| const WDR_LOCAL_TEST_CERT: &str = "WDRLocalTestCert"; | ||
| const STAMPINF_VERSION_ENV_VAR: &str = "STAMPINF_VERSION"; | ||
|
|
||
| /// Signing mode. | ||
| #[derive(Debug, Clone, Copy, PartialEq, Eq)] | ||
| pub enum SignMode { | ||
|
|
@@ -43,12 +50,31 @@ pub enum SignMode { | |
| }, | ||
| } | ||
|
|
||
| // FIXME: This range is inclusive of 25798. Update with range end after /sample | ||
| // flag is added to InfVerif CLI | ||
| const MISSING_SAMPLE_FLAG_WDK_BUILD_NUMBER_RANGE: RangeFrom<u32> = 25798..; | ||
| const WDR_TEST_CERT_STORE: &str = "WDRTestCertStore"; | ||
| const WDR_LOCAL_TEST_CERT: &str = "WDRLocalTestCert"; | ||
| const STAMPINF_VERSION_ENV_VAR: &str = "STAMPINF_VERSION"; | ||
| /// Driver target platform as per <https://learn.microsoft.com/en-us/windows-hardware/drivers/develop/target-platforms> | ||
| #[derive(Debug, Clone, Copy, PartialEq, Eq)] | ||
| pub enum TargetPlatform { | ||
| /// Universal target (default). Validates that the INF meets Universal | ||
| /// driver requirements (`infverif /u`) — portable everywhere. | ||
|
gurry marked this conversation as resolved.
Outdated
|
||
| Universal, | ||
| /// Desktop target. Validates that the INF meets WHQL signature | ||
| /// requirements (`infverif /h`). | ||
| Desktop, | ||
| /// Windows Driver target. Validates that the INF meets Windows Driver | ||
| /// requirements (`infverif /w`) — declarative (DCH) + driver package | ||
| /// isolation. | ||
| WindowsDriver, | ||
| } | ||
|
|
||
| impl TargetPlatform { | ||
| /// Returns the `InfVerif` mode flag for this target platform. | ||
| const fn infverif_flag(self) -> &'static str { | ||
|
gurry marked this conversation as resolved.
Outdated
|
||
| match self { | ||
| Self::Universal => "/u", | ||
| Self::Desktop => "/h", | ||
| Self::WindowsDriver => "/w", | ||
| } | ||
| } | ||
| } | ||
|
|
||
| #[derive(Debug)] | ||
| pub struct PackageTaskParams<'a> { | ||
|
|
@@ -59,6 +85,7 @@ pub struct PackageTaskParams<'a> { | |
| pub sign_mode: SignMode, | ||
| pub sample_class: bool, | ||
| pub driver_model: DriverConfig, | ||
| pub target_platform: Option<TargetPlatform>, | ||
| } | ||
|
|
||
| /// Supports low level driver packaging operations | ||
|
|
@@ -87,6 +114,7 @@ pub struct PackageTask<'a> { | |
| arch: &'a CpuArchitecture, | ||
| os_mapping: &'a str, | ||
| driver_model: DriverConfig, | ||
| target_platform: Option<TargetPlatform>, | ||
|
|
||
| // Injected deps | ||
| wdk_build: &'a WdkBuild, | ||
|
|
@@ -192,6 +220,7 @@ impl<'a> PackageTask<'a> { | |
| arch: params.target_arch, | ||
| os_mapping, | ||
| driver_model: params.driver_model, | ||
| target_platform: params.target_platform, | ||
| wdk_build, | ||
| command_exec, | ||
| fs, | ||
|
|
@@ -558,15 +587,13 @@ impl<'a> PackageTask<'a> { | |
| }; | ||
|
|
||
| info!("Running infverif"); | ||
| let mut args = vec![ | ||
| "/v", | ||
| match self.driver_model { | ||
| DriverConfig::Kmdf(_) | DriverConfig::Wdm => "/w", | ||
| // TODO: This should be /u if WDK <= GE && DRIVER_MODEL == UMDF, otherwise it should | ||
| // be /w | ||
| DriverConfig::Umdf(_) => "/u", | ||
| }, | ||
| ]; | ||
|
|
||
| let mode_flag = self.target_platform.map_or_else( | ||
| || TargetPlatform::Universal.infverif_flag(), | ||
| TargetPlatform::infverif_flag, | ||
| ); | ||
|
|
||
| let mut args = vec!["/v", mode_flag]; | ||
|
svasista-ms marked this conversation as resolved.
Outdated
svasista-ms marked this conversation as resolved.
|
||
| let inf_path = self.dest_inf_file_path.to_string_lossy(); | ||
|
|
||
| if self.sample_class { | ||
|
|
@@ -644,7 +671,7 @@ mod tests { | |
| process::{ExitStatus, Output}, | ||
| }; | ||
|
|
||
| use wdk_build::{CpuArchitecture, KmdfConfig}; | ||
| use wdk_build::{CpuArchitecture, KmdfConfig, UmdfConfig}; | ||
|
|
||
| use super::*; | ||
|
|
||
|
|
@@ -665,6 +692,7 @@ mod tests { | |
| sign_mode: SignMode::Test { | ||
| verify_signature: false, | ||
| }, | ||
| target_platform: None, | ||
| }; | ||
| let dest_root = target_dir.join(format!("{package_name}_package")); | ||
|
|
||
|
|
@@ -735,6 +763,7 @@ mod tests { | |
| sign_mode: SignMode::Test { | ||
| verify_signature: false, | ||
| }, | ||
| target_platform: None, | ||
| }; | ||
|
|
||
| let command_exec = CommandExec::default(); | ||
|
|
@@ -763,6 +792,7 @@ mod tests { | |
| sign_mode: SignMode::Test { | ||
| verify_signature: false, | ||
| }, | ||
| target_platform: None, | ||
| }; | ||
|
|
||
| let command_exec = CommandExec::default(); | ||
|
|
@@ -800,6 +830,7 @@ mod tests { | |
| sign_mode: SignMode::Test { | ||
| verify_signature: false, | ||
| }, | ||
| target_platform: None, | ||
| }; | ||
|
|
||
| let wdk_build = WdkBuild::default(); | ||
|
|
@@ -839,6 +870,152 @@ mod tests { | |
| } | ||
| } | ||
|
|
||
| fn assert_default_infverif_mode_flag( | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Looks like an almost complete duplicate of fn assert_infverif_mode_flag(
driver_model: DriverConfig,
target_platform: TargetPlatform,
expected_mode_flag: &'static str,
)
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done ✅ |
||
| driver_model: DriverConfig, | ||
| expected_mode_flag: &'static str, | ||
| ) { | ||
| let package_name = "driver"; | ||
| let working_dir = PathBuf::from("C:/abs/driver"); | ||
| let target_dir = PathBuf::from("C:/abs/driver/target/debug"); | ||
| let arch = CpuArchitecture::Amd64; | ||
|
|
||
| let params = PackageTaskParams { | ||
| package_name, | ||
| working_dir: &working_dir, | ||
| target_dir: &target_dir, | ||
| target_arch: &arch, | ||
| driver_model, | ||
| sample_class: false, | ||
| sign_mode: SignMode::Off, | ||
| target_platform: None, | ||
| }; | ||
|
|
||
| let fs = Fs::default(); | ||
| let wdk_build = WdkBuild::default(); | ||
|
|
||
| let mut command_exec = CommandExec::default(); | ||
| command_exec | ||
| .expect_run() | ||
| .withf(move |cmd: &str, args: &[&str], _, _| { | ||
| cmd == "infverif" | ||
| && args.len() >= 2 | ||
| && args[0] == "/v" | ||
| && args[1] == expected_mode_flag | ||
| }) | ||
| .once() | ||
| .returning(|_, _, _, _| { | ||
| Ok(Output { | ||
| status: ExitStatus::default(), | ||
| stdout: vec![], | ||
| stderr: vec![], | ||
| }) | ||
| }); | ||
|
|
||
| let task = PackageTask::new(params, &wdk_build, &command_exec, &fs); | ||
| assert!(task.run_infverif().is_ok()); | ||
| } | ||
|
|
||
| #[test] | ||
| fn run_infverif_defaults_to_universal_for_all_driver_models() { | ||
| assert_default_infverif_mode_flag(DriverConfig::Kmdf(KmdfConfig::default()), "/u"); | ||
| assert_default_infverif_mode_flag(DriverConfig::Wdm, "/u"); | ||
| assert_default_infverif_mode_flag( | ||
| DriverConfig::Umdf(UmdfConfig { | ||
| umdf_version_major: 2, | ||
| target_umdf_version_minor: 33, | ||
| minimum_umdf_version_minor: None, | ||
| }), | ||
| "/u", | ||
| ); | ||
| } | ||
|
|
||
| #[test] | ||
| fn run_infverif_uses_target_platform_mode_flag() { | ||
| assert_target_platform_infverif_mode_flag(TargetPlatform::Universal, "/u"); | ||
| assert_target_platform_infverif_mode_flag(TargetPlatform::Desktop, "/h"); | ||
| assert_target_platform_infverif_mode_flag(TargetPlatform::WindowsDriver, "/w"); | ||
| } | ||
|
|
||
| fn assert_target_platform_infverif_mode_flag( | ||
| target_platform: TargetPlatform, | ||
| expected_mode_flag: &'static str, | ||
| ) { | ||
| let package_name = "kmdf_driver"; | ||
| let working_dir = PathBuf::from("C:/abs/kmdf_driver"); | ||
| let target_dir = PathBuf::from("C:/abs/kmdf_driver/target/debug"); | ||
| let arch = CpuArchitecture::Amd64; | ||
|
|
||
| let params = PackageTaskParams { | ||
| package_name, | ||
| working_dir: &working_dir, | ||
| target_dir: &target_dir, | ||
| target_arch: &arch, | ||
| driver_model: DriverConfig::Kmdf(KmdfConfig::default()), | ||
| sample_class: false, | ||
| sign_mode: SignMode::Off, | ||
| target_platform: Some(target_platform), | ||
| }; | ||
|
|
||
| let fs = Fs::default(); | ||
| let wdk_build = WdkBuild::default(); | ||
|
|
||
| let mut command_exec = CommandExec::default(); | ||
| command_exec | ||
| .expect_run() | ||
| .withf(move |cmd: &str, args: &[&str], _, _| { | ||
| cmd == "infverif" | ||
| && args.len() >= 2 | ||
| && args[0] == "/v" | ||
| && args[1] == expected_mode_flag | ||
| }) | ||
| .once() | ||
| .returning(|_, _, _, _| { | ||
| Ok(Output { | ||
| status: ExitStatus::default(), | ||
| stdout: vec![], | ||
| stderr: vec![], | ||
| }) | ||
| }); | ||
|
|
||
| let task = PackageTask::new(params, &wdk_build, &command_exec, &fs); | ||
| assert!(task.run_infverif().is_ok()); | ||
| } | ||
|
|
||
| #[test] | ||
| fn run_infverif_skips_sample_class_when_samples_flag_missing() { | ||
| let package_name = "kmdf_driver"; | ||
| let working_dir = PathBuf::from("C:/abs/kmdf_driver"); | ||
| let target_dir = PathBuf::from("C:/abs/kmdf_driver/target/debug"); | ||
| let arch = CpuArchitecture::Amd64; | ||
|
|
||
| let params = PackageTaskParams { | ||
| package_name, | ||
| working_dir: &working_dir, | ||
| target_dir: &target_dir, | ||
| target_arch: &arch, | ||
| driver_model: DriverConfig::Kmdf(KmdfConfig::default()), | ||
| sample_class: true, | ||
| sign_mode: SignMode::Off, | ||
| target_platform: Some(TargetPlatform::WindowsDriver), | ||
| }; | ||
|
|
||
| let fs = Fs::default(); | ||
| let mut wdk_build = WdkBuild::default(); | ||
| // A WDK build number in the missing-`/samples`-flag range, so InfVerif | ||
| // is skipped for the sample class. | ||
|
svasista-ms marked this conversation as resolved.
|
||
| wdk_build | ||
| .expect_detect_wdk_build_number() | ||
| .once() | ||
| .returning(|| Ok(28000u32)); | ||
|
|
||
| let mut command_exec = CommandExec::default(); | ||
| // `infverif` must not be invoked when the sample class is skipped. | ||
| command_exec.expect_run().never(); | ||
|
|
||
| let task = PackageTask::new(params, &wdk_build, &command_exec, &fs); | ||
| assert!(task.run_infverif().is_ok()); | ||
| } | ||
|
|
||
| mod named_mutex { | ||
| use std::{ | ||
| ffi::CString, | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.