diff --git a/.vscode/launch.json b/.vscode/launch.json index 4728c02..2b46e1f 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -1,101 +1,36 @@ { - // Use IntelliSense to learn about possible attributes. - // Hover to view descriptions of existing attributes. - // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 - "version": "0.2.0", - "configurations": [ - { - "type": "lldb", - "request": "launch", - "name": "Debug unit tests in library 'autopower_shared'", - "cargo": { - "args": [ - "test", - "--no-run", - "--lib", - "--package=autopower_shared" - ], - "filter": { - "name": "autopower_shared", - "kind": "lib" - } - }, - "args": [], - "cwd": "${workspaceFolder}" - }, - { - "type": "lldb", - "request": "launch", - "name": "Debug executable 'autopower_notification_provider'", - "cargo": { - "args": [ - "build", - "--bin=autopower_notification_provider", - "--package=autopower_notification_provider" - ], - "filter": { - "name": "autopower_notification_provider", - "kind": "bin" - } - }, - "args": [], - "cwd": "${workspaceFolder}" - }, - { - "type": "lldb", - "request": "launch", - "name": "Debug unit tests in executable 'autopower_notification_provider'", - "cargo": { - "args": [ - "test", - "--no-run", - "--bin=autopower_notification_provider", - "--package=autopower_notification_provider" - ], - "filter": { - "name": "autopower_notification_provider", - "kind": "bin" - } - }, - "args": [], - "cwd": "${workspaceFolder}" - }, - { - "type": "lldb", - "request": "launch", - "name": "Debug executable 'autopower'", - "cargo": { - "args": [ - "build", - "--bin=autopower", - "--package=autopower" - ], - "filter": { - "name": "autopower", - "kind": "bin" - } - }, - "args": [], - "cwd": "${workspaceFolder}" - }, - { - "type": "lldb", - "request": "launch", - "name": "Debug unit tests in executable 'autopower'", - "cargo": { - "args": [ - "test", - "--no-run", - "--bin=autopower", - "--package=autopower" - ], - "filter": { - "name": "autopower", - "kind": "bin" - } - }, - "args": [], - "cwd": "${workspaceFolder}" + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "type": "lldb", + "request": "launch", + "name": "Debug executable 'autopower_proxy'", + "cargo": { + "args": ["build", "--bin=autopower_proxy", "--package=autopower_proxy"], + "filter": { + "name": "autopower_proxy", + "kind": "bin" } - ] -} \ No newline at end of file + }, + "args": [], + "cwd": "${workspaceFolder}" + }, + { + "type": "lldb", + "request": "launch", + "name": "Debug executable 'autopower'", + "cargo": { + "args": ["build", "--bin=autopower", "--package=autopower"], + "filter": { + "name": "autopower", + "kind": "bin" + } + }, + "args": [], + "cwd": "${workspaceFolder}" + } + ] +} diff --git a/Cargo.toml b/Cargo.toml index c8e3eb8..d8f8117 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -49,6 +49,7 @@ windows = { version = "^0.58", features = [ "Win32_System_Com", "Win32_System_Console", "Win32_Graphics_Gdi", + "Win32_System_LibraryLoader", ] } [dependencies] diff --git a/TODO.md b/TODO.md index 60db99e..ed4b583 100644 --- a/TODO.md +++ b/TODO.md @@ -1,3 +1,4 @@ # TODO -- Rewrite as a normal background process. The current way is too limiting due to session 0 isolation, and strange behaviour with some APIs. +- Start the proxy process from the service. +- Scrap the PS1 scripts and install/uninstall directly from the main exe. diff --git a/autopower_proxy/src/config/config_error.rs b/autopower_proxy/src/config/config_error.rs deleted file mode 100644 index d05faf3..0000000 --- a/autopower_proxy/src/config/config_error.rs +++ /dev/null @@ -1,14 +0,0 @@ -#[derive(Debug)] -pub enum ConfigError { - CouldNotLoadOrCreate, -} - -impl std::fmt::Display for ConfigError { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.write_str(match self { - ConfigError::CouldNotLoadOrCreate => "Could not load or create config!", - }) - } -} - -impl std::error::Error for ConfigError {} diff --git a/autopower_proxy/src/config/mod.rs b/autopower_proxy/src/config/mod.rs index f09bd77..e336fbe 100644 --- a/autopower_proxy/src/config/mod.rs +++ b/autopower_proxy/src/config/mod.rs @@ -1,22 +1,22 @@ -mod config_error; mod power_scheme; mod state_config; -pub use config_error::ConfigError; pub use power_scheme::PowerScheme; use state_config::StateConfig; use crate::display::RefreshRateMode; -use autopower_shared::logging::Logger; +use autopower_shared::{logging::Logger, util::get_process_exe_path}; use serde::{Deserialize, Serialize}; use std::{ fs::File, io::{BufReader, BufWriter, Write}, - path::{Path, PathBuf}, + path::Path, }; const LOGGER: Logger = Logger::new("power_config", "autopower_proxy"); +type Result = crate::Result; + #[derive(Serialize, Deserialize, Debug)] pub struct PowerConfig { wired_config: StateConfig, @@ -45,30 +45,26 @@ impl Default for PowerConfig { } impl PowerConfig { - fn get(path: &Path) -> Result { + fn get(path: &Path) -> Result { LOGGER.debug(format!("Reading power config at {}", path.display())); - - let fs = File::open(path).map_err(|_| ConfigError::CouldNotLoadOrCreate)?; + let fs = File::open(path)?; let buf = BufReader::new(fs); - serde_json::from_reader(buf).map_err(|_| ConfigError::CouldNotLoadOrCreate) + serde_json::from_reader(buf).map_err(|e| e.into()) } - fn new(path: &Path) -> Result { + fn new(path: &Path) -> Result { LOGGER.debug(format!("Writing new power config at {}", path.display())); let new_config = PowerConfig::default(); - let fs = File::create(path).map_err(|_| ConfigError::CouldNotLoadOrCreate)?; + let fs = File::create(path)?; let mut buf = BufWriter::new(fs); - serde_json::to_writer_pretty(&mut buf, &new_config) - .map_err(|_| ConfigError::CouldNotLoadOrCreate)?; - buf.flush().map_err(|_| ConfigError::CouldNotLoadOrCreate)?; + serde_json::to_writer_pretty(&mut buf, &new_config)?; + buf.flush()?; Ok(new_config) } - pub fn get_or_create() -> Result { - const CONFIG_PATH: &str = "./config.json"; - let path = PathBuf::from(CONFIG_PATH) - .canonicalize() - .map_err(|_| ConfigError::CouldNotLoadOrCreate)?; + pub fn get_or_create() -> Result { + const CONFIG_FILE: &str = "config.json"; + let path = get_process_exe_path()?.with_file_name(CONFIG_FILE); Self::get(&path).or_else(|_| Self::new(&path)) } diff --git a/autopower_proxy/src/config/state_config.rs b/autopower_proxy/src/config/state_config.rs index 3decbdb..6aaffd6 100644 --- a/autopower_proxy/src/config/state_config.rs +++ b/autopower_proxy/src/config/state_config.rs @@ -6,7 +6,7 @@ use crate::{ use serde::{Deserialize, Serialize}; use windows::Win32::System::Power::PowerSetActiveScheme; -type Result = crate::Result; // Perhaps make a custom error in the future. +type Result = crate::Result; #[derive(Serialize, Deserialize, Debug)] pub struct StateConfig { diff --git a/shared/src/util.rs b/shared/src/util.rs index 5d79d39..0b7912a 100644 --- a/shared/src/util.rs +++ b/shared/src/util.rs @@ -1,8 +1,13 @@ +use std::{ffi::OsStr, path::PathBuf}; + use windows::{ core::PWSTR, Win32::{ Foundation::GetLastError, - System::Diagnostics::Debug::{FormatMessageW, FORMAT_MESSAGE_FROM_SYSTEM}, + System::{ + Diagnostics::Debug::{FormatMessageW, FORMAT_MESSAGE_FROM_SYSTEM}, + LibraryLoader::GetModuleFileNameA, + }, }, }; @@ -24,3 +29,21 @@ pub fn get_last_win32_err() -> super::Result { let str = unsafe { buf.to_string()? }; return Ok(str[..count as usize].to_owned()); } + +pub fn get_process_exe_path() -> super::Result { + let mut buf = [0; 512]; + unsafe { + let count = GetModuleFileNameA(None, &mut buf); + let count_usize = count as usize; + if count_usize == buf.len() { + return Err("Process path is too long!".into()); + } + if buf[count_usize] != b'\0' { + return Err( + "Process path buffer did not end with a null terminator, possible overflow.".into(), + ); + } + let os_str = OsStr::from_encoded_bytes_unchecked(&buf[0..(count_usize)]); + Ok(PathBuf::from(os_str)) + } +} diff --git a/shared/src/winstr.rs b/shared/src/winstr.rs index 1110edb..4f212f2 100644 --- a/shared/src/winstr.rs +++ b/shared/src/winstr.rs @@ -14,7 +14,7 @@ impl Win32StrPtr { } pub fn from_buffer(data: Vec) -> Self { - Self { data: data } + Self { data } } } diff --git a/src/services/power_service.rs b/src/services/power_service.rs index bb7714d..9c27da7 100644 --- a/src/services/power_service.rs +++ b/src/services/power_service.rs @@ -158,11 +158,13 @@ impl PowerService { event_data: *mut c_void, _context: *mut c_void, ) -> u32 { + // DO NOT DROP, will be dropped in service_main on exit. let mut me = ManuallyDrop::new(_context.cast::().read()); let data = HandlerData { event_type, event_data, }; + // Win32 docs say to start new thread for any other work than returning immediately std::thread::spawn(move || { match ctrl_code {