write shit
This commit is contained in:
@@ -1,6 +1,9 @@
|
||||
//! This crate provide utilities fetching and manilupating Windows file association.
|
||||
//! All code under crate are following Microsoft document: https://learn.microsoft.com/en-us/windows/win32/shell/customizing-file-types-bumper
|
||||
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
compile_error!("Crate wfassoc is only supported on Windows.");
|
||||
|
||||
use regex::Regex;
|
||||
use std::fmt::Display;
|
||||
use std::path::PathBuf;
|
||||
@@ -8,9 +11,6 @@ use std::str::FromStr;
|
||||
use std::sync::LazyLock;
|
||||
use thiserror::Error as TeError;
|
||||
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
compile_error!("Crate wfassoc is only supported on Windows.");
|
||||
|
||||
// region: Error Types
|
||||
|
||||
/// All possible error occurs in this crate.
|
||||
@@ -29,6 +29,7 @@ pub enum Error {
|
||||
// endregion
|
||||
|
||||
/// The scope where wfassoc will operate.
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub enum Scope {
|
||||
/// Scope for current user.
|
||||
User,
|
||||
@@ -40,17 +41,17 @@ pub enum Scope {
|
||||
///
|
||||
/// It usually means that checking whether current process is running as Administrator.
|
||||
/// Return true if it is, otherwise false.
|
||||
///
|
||||
///
|
||||
/// Reference: https://learn.microsoft.com/en-us/windows/win32/api/securitybaseapi/nf-securitybaseapi-checktokenmembership
|
||||
pub fn has_privilege() -> bool {
|
||||
use windows_sys::core::BOOL;
|
||||
use windows_sys::Win32::Foundation::HANDLE;
|
||||
use windows_sys::Win32::Security::{
|
||||
SECURITY_NT_AUTHORITY, PSID, AllocateAndInitializeSid, CheckTokenMembership, FreeSid
|
||||
AllocateAndInitializeSid, CheckTokenMembership, FreeSid, PSID, SECURITY_NT_AUTHORITY,
|
||||
};
|
||||
use windows_sys::Win32::System::SystemServices:: {
|
||||
SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS
|
||||
use windows_sys::Win32::System::SystemServices::{
|
||||
DOMAIN_ALIAS_RID_ADMINS, SECURITY_BUILTIN_DOMAIN_RID,
|
||||
};
|
||||
use windows_sys::core::BOOL;
|
||||
|
||||
let nt_authority = SECURITY_NT_AUTHORITY.clone();
|
||||
let mut administrators_group: PSID = PSID::default();
|
||||
@@ -75,13 +76,8 @@ pub fn has_privilege() -> bool {
|
||||
}
|
||||
|
||||
let mut is_member: BOOL = BOOL::default();
|
||||
let success: BOOL = unsafe {
|
||||
CheckTokenMembership(
|
||||
HANDLE::default(),
|
||||
administrators_group,
|
||||
&mut is_member,
|
||||
)
|
||||
};
|
||||
let success: BOOL =
|
||||
unsafe { CheckTokenMembership(HANDLE::default(), administrators_group, &mut is_member) };
|
||||
|
||||
unsafe {
|
||||
FreeSid(administrators_group);
|
||||
@@ -90,7 +86,7 @@ pub fn has_privilege() -> bool {
|
||||
if success == 0 {
|
||||
panic!("Win32 CheckTokenMembership() failed");
|
||||
}
|
||||
|
||||
|
||||
is_member != 0
|
||||
}
|
||||
|
||||
@@ -113,6 +109,10 @@ impl FileExt {
|
||||
None => Err(ParseFileExtError::new()),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn query(&self, scope: Scope) -> Option<FileExtAssoc> {
|
||||
FileExtAssoc::new(self, scope)
|
||||
}
|
||||
}
|
||||
|
||||
/// The error occurs when try parsing string into FileExt.
|
||||
@@ -140,6 +140,55 @@ impl FromStr for FileExt {
|
||||
}
|
||||
}
|
||||
|
||||
/// The association infomations of specific file extension.
|
||||
pub struct FileExtAssoc {
|
||||
default: String,
|
||||
open_with_progids: Vec<String>,
|
||||
}
|
||||
|
||||
impl FileExtAssoc {
|
||||
fn new(file_ext: &FileExt, scope: Scope) -> Option<Self> {
|
||||
let hk = match scope {
|
||||
Scope::User => winreg::RegKey::predef(winreg::enums::HKEY_CURRENT_USER),
|
||||
Scope::System => winreg::RegKey::predef(winreg::enums::HKEY_LOCAL_MACHINE),
|
||||
};
|
||||
let classes = hk
|
||||
.open_subkey_with_flags("Software\\Classes", winreg::enums::KEY_READ)
|
||||
.unwrap();
|
||||
let thisext =
|
||||
match classes.open_subkey_with_flags(file_ext.to_string(), winreg::enums::KEY_READ) {
|
||||
Ok(v) => v,
|
||||
Err(e) => return None,
|
||||
};
|
||||
|
||||
let default = thisext.get_value("").unwrap_or(String::new());
|
||||
let open_with_progids = if let Ok(progids) =
|
||||
thisext.open_subkey_with_flags("OpenWithProdIds", winreg::enums::KEY_READ)
|
||||
{
|
||||
progids.enum_keys().map(|x| x.unwrap()).collect()
|
||||
} else {
|
||||
Vec::new()
|
||||
};
|
||||
|
||||
Some(Self {
|
||||
default,
|
||||
open_with_progids,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn get_default(&self) -> &str {
|
||||
&self.default
|
||||
}
|
||||
|
||||
pub fn len_open_with_progid(&self) -> usize {
|
||||
self.open_with_progids.len()
|
||||
}
|
||||
|
||||
pub fn iter_open_with_progids(&self) -> impl Iterator<Item = &str> {
|
||||
self.open_with_progids.iter().map(|s| s.as_str())
|
||||
}
|
||||
}
|
||||
|
||||
// endregion
|
||||
|
||||
// region: Executable Resource
|
||||
|
||||
Reference in New Issue
Block a user