From 0b47d1aacc2483cd21000e75c6b27faf999193fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Tue, 20 Aug 2024 10:09:05 -0400 Subject: [PATCH] adding context menu icon resource --- Cargo.lock | 1 + .../Cargo.toml | 3 + .../build.rs | 85 +++++++++++++++++++ .../resources.rc | 1 + .../src/lib_win.rs | 23 ++++- devolutions-agent/build.rs | 1 + devolutions-agent/resources.rc | 1 + 7 files changed, 111 insertions(+), 4 deletions(-) create mode 100644 crates/devolutions-pedm-contextmenu/devolutions-pedm-contextmenu-shell/build.rs create mode 100644 crates/devolutions-pedm-contextmenu/devolutions-pedm-contextmenu-shell/resources.rc create mode 100644 devolutions-agent/resources.rc diff --git a/Cargo.lock b/Cargo.lock index b05b7ca6e..7d2da40c4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1193,6 +1193,7 @@ name = "devolutions-pedm-contextmenu-shell" version = "0.0.0" dependencies = [ "devolutions-pedm-shared", + "embed-resource", "parking_lot", "tokio 1.38.1", "win-api-wrappers", diff --git a/crates/devolutions-pedm-contextmenu/devolutions-pedm-contextmenu-shell/Cargo.toml b/crates/devolutions-pedm-contextmenu/devolutions-pedm-contextmenu-shell/Cargo.toml index 106bd39ba..aa7e17ca9 100644 --- a/crates/devolutions-pedm-contextmenu/devolutions-pedm-contextmenu-shell/Cargo.toml +++ b/crates/devolutions-pedm-contextmenu/devolutions-pedm-contextmenu-shell/Cargo.toml @@ -16,3 +16,6 @@ windows-core = "0.58.0" # necessary because of macro resolving `windows::core`. devolutions-pedm-shared = { path = "../../devolutions-pedm-shared", features = ["pedm_client", "desktop"] } win-api-wrappers = { path = "../../win-api-wrappers" } parking_lot = "0.12.3" + +[target.'cfg(windows)'.build-dependencies] +embed-resource = "2.4" diff --git a/crates/devolutions-pedm-contextmenu/devolutions-pedm-contextmenu-shell/build.rs b/crates/devolutions-pedm-contextmenu/devolutions-pedm-contextmenu-shell/build.rs new file mode 100644 index 000000000..87c6e6262 --- /dev/null +++ b/crates/devolutions-pedm-contextmenu/devolutions-pedm-contextmenu-shell/build.rs @@ -0,0 +1,85 @@ +fn main() { + #[cfg(target_os = "windows")] + win::embed_version_rc(); +} + +#[cfg(target_os = "windows")] +mod win { + use std::{env, fs}; + + pub(super) fn embed_version_rc() { + let out_dir = env::var("OUT_DIR").unwrap(); + let version_rc_file = format!("{}/version.rc", out_dir); + let version_rc_data = generate_version_rc(); + fs::write(&version_rc_file, version_rc_data).unwrap(); + + embed_resource::compile(&version_rc_file, embed_resource::NONE); + embed_resource::compile("resources.rc", embed_resource::NONE); + } + + fn generate_version_rc() -> String { + let output_name = "devolutions-pedm-contextmenu"; + let filename = format!("{}.exe", output_name); + let company_name = "Devolutions Inc."; + let legal_copyright = format!("Copyright 2020-2024 {}", company_name); + + let version_number = env::var("CARGO_PKG_VERSION").unwrap() + ".0"; + let version_commas = version_number.replace('.', ","); + let file_description = output_name; + let file_version = version_number.clone(); + let internal_name = filename.clone(); + let original_filename = filename; + let product_name = output_name; + let product_version = version_number; + let vs_file_version = version_commas.clone(); + let vs_product_version = version_commas; + + let version_rc = format!( + r#"#include +VS_VERSION_INFO VERSIONINFO + FILEVERSION {vs_file_version} + PRODUCTVERSION {vs_product_version} + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x40004L + FILETYPE 0x1L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" + BEGIN + VALUE "CompanyName", "{company_name}" + VALUE "FileDescription", "{file_description}" + VALUE "FileVersion", "{file_version}" + VALUE "InternalName", "{internal_name}" + VALUE "LegalCopyright", "{legal_copyright}" + VALUE "OriginalFilename", "{original_filename}" + VALUE "ProductName", "{product_name}" + VALUE "ProductVersion", "{product_version}" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1200 + END +END"#, + vs_file_version = vs_file_version, + vs_product_version = vs_product_version, + company_name = company_name, + file_description = file_description, + file_version = file_version, + internal_name = internal_name, + legal_copyright = legal_copyright, + original_filename = original_filename, + product_name = product_name, + product_version = product_version + ); + + version_rc + } +} diff --git a/crates/devolutions-pedm-contextmenu/devolutions-pedm-contextmenu-shell/resources.rc b/crates/devolutions-pedm-contextmenu/devolutions-pedm-contextmenu-shell/resources.rc new file mode 100644 index 000000000..458ac8da1 --- /dev/null +++ b/crates/devolutions-pedm-contextmenu/devolutions-pedm-contextmenu-shell/resources.rc @@ -0,0 +1 @@ +101 ICON "../../../package/AgentWindowsManaged/Resources/DevolutionsAgent.ico" \ No newline at end of file diff --git a/crates/devolutions-pedm-contextmenu/devolutions-pedm-contextmenu-shell/src/lib_win.rs b/crates/devolutions-pedm-contextmenu/devolutions-pedm-contextmenu-shell/src/lib_win.rs index fef3b923a..e8f1253de 100644 --- a/crates/devolutions-pedm-contextmenu/devolutions-pedm-contextmenu-shell/src/lib_win.rs +++ b/crates/devolutions-pedm-contextmenu/devolutions-pedm-contextmenu-shell/src/lib_win.rs @@ -10,7 +10,7 @@ use devolutions_pedm_shared::client::{self}; use devolutions_pedm_shared::desktop; use parking_lot::{Mutex, RwLock}; use tokio::sync::mpsc::{self, Receiver, Sender}; -use win_api_wrappers::process::Process; +use win_api_wrappers::process::{Module, Process}; use win_api_wrappers::raw::core::{ implement, interface, w, Error, IUnknown, IUnknown_Vtbl, Interface, Result, GUID, HRESULT, PWSTR, }; @@ -29,7 +29,9 @@ use win_api_wrappers::raw::Win32::UI::Shell::{ ECS_ENABLED, SIGDN_FILESYSPATH, }; use win_api_wrappers::token::Token; -use win_api_wrappers::utils::{environment_block, expand_environment, expand_environment_path, Link, Snapshot}; +use win_api_wrappers::utils::{ + environment_block, expand_environment, expand_environment_path, Link, Snapshot, WideString, +}; struct Channels { pub tx: Sender, @@ -68,11 +70,24 @@ impl IElevationContextMenuCommand_Impl for ElevationContextMenuCommand_Impl {} impl IExplorerCommand_Impl for ElevationContextMenuCommand_Impl { fn GetTitle(&self, _item_array: Option<&IShellItemArray>) -> Result { // SAFETY: The `w` macro creates a constant, so the argument is valid. - unsafe { SHStrDupW(w!("Run as administrator with Devolutions PEDM")) } + unsafe { SHStrDupW(w!("Run elevated")) } } fn GetIcon(&self, _item_array: Option<&IShellItemArray>) -> Result { - Err(E_NOTIMPL.into()) + let module = match Module::current() { + Ok(mod_) => mod_, + Err(_) => return Err(E_NOTIMPL.into()), + }; + + let module_path = match module.file_name() { + Ok(path) => path, + Err(_) => return Err(E_NOTIMPL.into()), + }; + + let module_path_str = module_path.to_string_lossy(); + let icon_path = format!("{},101", module_path_str); + let icon_path_wide = WideString::from(icon_path.as_str()).as_pwstr(); + unsafe { SHStrDupW(icon_path_wide) } } fn GetToolTip(&self, _item_array: Option<&IShellItemArray>) -> Result { diff --git a/devolutions-agent/build.rs b/devolutions-agent/build.rs index a15066ead..8c8bcedf8 100644 --- a/devolutions-agent/build.rs +++ b/devolutions-agent/build.rs @@ -14,6 +14,7 @@ mod win { fs::write(&version_rc_file, version_rc_data).unwrap(); embed_resource::compile(&version_rc_file, embed_resource::NONE); + embed_resource::compile("resources.rc", embed_resource::NONE); } fn generate_version_rc() -> String { diff --git a/devolutions-agent/resources.rc b/devolutions-agent/resources.rc new file mode 100644 index 000000000..b007d2a19 --- /dev/null +++ b/devolutions-agent/resources.rc @@ -0,0 +1 @@ +101 ICON "../package/AgentWindowsManaged/Resources/DevolutionsAgent.ico" \ No newline at end of file