Skip to content

Commit

Permalink
chore: up
Browse files Browse the repository at this point in the history
  • Loading branch information
greenhat616 committed Nov 24, 2024
1 parent cdfda96 commit 292571b
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 33 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,5 @@ thiserror = "2"
dirs = "5.0.1"

[target.'cfg(windows)'.dependencies]
windows-registry = { version = "0.3.0", features = ["std"] }
windows-registry = "0.3.0"
windows-result = "0.2.0"
79 changes: 47 additions & 32 deletions src/windows.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use crate::{AutoLaunch, Result};
use windows_registry::{Key, CURRENT_USER, LOCAL_MACHINE};
use windows_result::HRESULT;

const ADMIN_AL_REGKEY: &str = "SOFTWARE\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\Run";
const AL_REGKEY: &str = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run";
Expand Down Expand Up @@ -38,15 +39,19 @@ impl AutoLaunch {
/// - failed to open the registry key
/// - failed to set value
pub fn enable(&self) -> Result<()> {
self.enable_as_admin().or_else(|e| match e.raw_os_error() {
Some(val) if val == E_ACCESSDENIED as i32 => {
self.enable_as_current_user().map_err(Into::into)
}
_ => Err(e.into()),
})
self.enable_as_admin()
.or_else(|e| {
if e.code() == windows_result::HRESULT(E_ACCESSDENIED as i32) {
self.enable_as_current_user()
} else {
Err(e)
}
})
.map_err(std::io::Error::from)?;
Ok(())
}

fn enable_as_admin(&self) -> std::io::Result<()> {
fn enable_as_admin(&self) -> windows_registry::Result<()> {
LOCAL_MACHINE.open(ADMIN_AL_REGKEY)?.set_string(
&self.app_name,
&format!("{} {}", &self.app_path, &self.args.join(" ")),
Expand All @@ -62,7 +67,7 @@ impl AutoLaunch {
Ok(())
}

fn enable_as_current_user(&self) -> std::io::Result<()> {
fn enable_as_current_user(&self) -> windows_registry::Result<()> {
CURRENT_USER.open(AL_REGKEY)?.set_string(
&self.app_name,
&format!("{} {}", &self.app_path, &self.args.join(" ")),
Expand All @@ -85,63 +90,73 @@ impl AutoLaunch {
/// - failed to open the registry key
/// - failed to delete value
pub fn disable(&self) -> Result<()> {
self.disable_as_admin().or_else(|e| match e.raw_os_error() {
Some(val) if val == E_ACCESSDENIED as i32 => {
self.disable_as_current_user().map_err(Into::into)
}
_ => Err(e.into()),
})
self.disable_as_admin()
.or_else(|e| {
if e.code() == HRESULT(E_ACCESSDENIED as i32) {
self.disable_as_current_user()
} else {
Err(e)
}
})
.map_err(std::io::Error::from)?;
Ok(())
}

fn disable_as_admin(&self) -> std::io::Result<()> {
fn disable_as_admin(&self) -> windows_registry::Result<()> {
LOCAL_MACHINE
.open(ADMIN_AL_REGKEY)?
.remove_value(&self.app_name)?;
Ok(())
}

fn disable_as_current_user(&self) -> std::io::Result<()> {
fn disable_as_current_user(&self) -> windows_registry::Result<()> {
CURRENT_USER.open(AL_REGKEY)?.remove_value(&self.app_name)?;
Ok(())
}

/// Check whether the AutoLaunch setting is enabled
pub fn is_enabled(&self) -> Result<bool> {
match self.is_enabled_as_admin() {
Ok(false) => self.is_enabled_as_current_user().map_err(Into::into),
Err(e) if e.raw_os_error() == Some(E_ACCESSDENIED as i32) => {
self.is_enabled_as_current_user().map_err(Into::into)
let res = match self.is_enabled_as_admin() {
Ok(false) => self.is_enabled_as_current_user(),
Err(e) if e.code() == HRESULT(E_ACCESSDENIED as i32) => {
self.is_enabled_as_current_user()
}
Ok(enabled) => Ok(enabled),
Err(e) => Err(e.into()),
Err(e) => Err(e),
}
.map_err(std::io::Error::from)?;
Ok(res)
}

fn is_enabled_as_admin(&self) -> std::io::Result<bool> {
fn is_enabled_as_admin(&self) -> windows_registry::Result<bool> {
let adm_enabled = LOCAL_MACHINE
.open(ADMIN_AL_REGKEY)?
.get_string(&self.app_name)
.map(|_| true)
.map_err(std::io::Error::from)
.or_else(|e| match e.raw_os_error() {
Some(code) if code == E_FILENOTFOUND as i32 => Ok(false),
_ => Err(e),
.or_else(|e| {
if e.code() == HRESULT(E_FILENOTFOUND as i32) {
Ok(false)
} else {
Err(e)
}
})?;
let task_manager_enabled = self
.task_manager_enabled(LOCAL_MACHINE, ADMIN_TASK_MANAGER_OVERRIDE_REGKEY)
.unwrap_or(true);
Ok(adm_enabled && task_manager_enabled)
}

fn is_enabled_as_current_user(&self) -> std::io::Result<bool> {
fn is_enabled_as_current_user(&self) -> windows_registry::Result<bool> {
let al_enabled = CURRENT_USER
.open(AL_REGKEY)?
.get_string(&self.app_name)
.map(|_| true)
.map_err(std::io::Error::from)
.or_else(|e| match e.raw_os_error() {
Some(code) if code == E_FILENOTFOUND as i32 => Ok(false),
_ => Err(e),
.or_else(|e| {
if e.code() == HRESULT(E_FILENOTFOUND as i32) {
Ok(false)
} else {
Err(e)
}
})?;
let task_manager_enabled = self
.task_manager_enabled(CURRENT_USER, TASK_MANAGER_OVERRIDE_REGKEY)
Expand All @@ -160,4 +175,4 @@ fn last_eight_bytes_all_zeros(bytes: &[u8]) -> Option<bool> {
return None;
}
Some(bytes.iter().rev().take(8).all(|v| *v == 0u8))
}
}

0 comments on commit 292571b

Please sign in to comment.