Add UAC elevation support with manifest

- Added guruconnect.manifest requesting highestAvailable privileges
- Using winres to embed manifest in executable
- Added is_elevated() function to detect admin status
- Logs elevation status on startup
- Manifest includes Windows 7-11 compatibility

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2025-12-28 16:12:03 -07:00
parent c57429f26a
commit 43f15b0b1a
5 changed files with 123 additions and 3 deletions

View File

@@ -28,6 +28,10 @@ use tracing_subscriber::FmtSubscriber;
use windows::Win32::UI::WindowsAndMessaging::{MessageBoxW, MB_OK, MB_ICONINFORMATION};
#[cfg(windows)]
use windows::core::PCWSTR;
#[cfg(windows)]
use windows::Win32::Security::{GetTokenInformation, TokenElevation, TOKEN_ELEVATION, TOKEN_QUERY};
#[cfg(windows)]
use windows::Win32::System::Threading::{GetCurrentProcess, OpenProcessToken};
/// Extract a 6-digit support code from the executable's filename.
/// Looks for patterns like "GuruConnect-123456.exe" or "123456.exe"
@@ -56,6 +60,38 @@ fn extract_code_from_filename() -> Option<String> {
None
}
/// Check if the process is running with elevated privileges (Windows only)
#[cfg(windows)]
fn is_elevated() -> bool {
unsafe {
let mut token_handle = windows::Win32::Foundation::HANDLE::default();
if OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &mut token_handle).is_err() {
return false;
}
let mut elevation = TOKEN_ELEVATION::default();
let mut size = std::mem::size_of::<TOKEN_ELEVATION>() as u32;
let result = GetTokenInformation(
token_handle,
TokenElevation,
Some(&mut elevation as *mut _ as *mut _),
size,
&mut size,
);
let _ = windows::Win32::Foundation::CloseHandle(token_handle);
result.is_ok() && elevation.TokenIsElevated != 0
}
}
#[cfg(not(windows))]
fn is_elevated() -> bool {
// On non-Windows, check if running as root
unsafe { libc::geteuid() == 0 }
}
/// Show a message box to the user (Windows only)
#[cfg(windows)]
fn show_message_box(title: &str, message: &str) {
@@ -98,6 +134,13 @@ async fn main() -> Result<()> {
info!("GuruConnect Agent v{}", env!("CARGO_PKG_VERSION"));
// Check and log elevation status
if is_elevated() {
info!("Running with elevated (administrator) privileges");
} else {
info!("Running with standard user privileges");
}
// Extract support code from executable filename
// e.g., GuruConnect-123456.exe -> 123456
let support_code = extract_code_from_filename();