fix: add arbitrarily_delete_value and fix various bugs for lowlevel and highlevel
This commit is contained in:
@@ -402,6 +402,7 @@ impl Program {
|
||||
|
||||
// Add this progid to file extension "open with" list.
|
||||
let ext_key = &mut program_key.ext_key;
|
||||
ext_key.ensure(scope)?;
|
||||
ext_key.add_into_open_with_progids(scope, progid_key.inner())?;
|
||||
}
|
||||
|
||||
@@ -438,9 +439,12 @@ impl Program {
|
||||
// there is no need to reset the default open way of file extension.
|
||||
// So we simply remove it from "open with" list.
|
||||
|
||||
// Remove this ProgId from file extension "open with" list.
|
||||
// Remove this ProgId from file extension "open with" list,
|
||||
// if this file extension is existing
|
||||
let ext_key = &mut program_key.ext_key;
|
||||
ext_key.remove_from_open_with_progids(scope, progid_key.inner())?;
|
||||
if ext_key.is_exist(scope.into())? {
|
||||
ext_key.remove_from_open_with_progids(scope, progid_key.inner())?;
|
||||
}
|
||||
|
||||
// Delete ProgId subkey
|
||||
progid_key.delete(scope)?;
|
||||
|
||||
@@ -156,7 +156,7 @@ impl Schema {
|
||||
}
|
||||
|
||||
pub(super) fn get_behavior(&self) -> Option<&str> {
|
||||
self.icon.as_ref().map(|v| v.as_str())
|
||||
self.behavior.as_ref().map(|v| v.as_str())
|
||||
}
|
||||
|
||||
pub(super) fn get_strs(&self) -> &HashMap<String, String> {
|
||||
|
||||
@@ -257,7 +257,7 @@ impl ApplicationsKey {
|
||||
}
|
||||
None => {
|
||||
// Delete this key
|
||||
key.delete_value(Self::NAMEOF_FRIENDLY_APP_NAME)?;
|
||||
regext::arbitrarily_delete_value(&key, Self::NAMEOF_FRIENDLY_APP_NAME)?;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -329,7 +329,7 @@ impl ApplicationsKey {
|
||||
if flag {
|
||||
key.set_value(Self::NAMEOF_NO_OPEN_WITH, &"")?;
|
||||
} else {
|
||||
key.delete_value(Self::NAMEOF_NO_OPEN_WITH)?;
|
||||
regext::arbitrarily_delete_value(&key, Self::NAMEOF_NO_OPEN_WITH)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -136,7 +136,7 @@ impl ExtKey {
|
||||
}
|
||||
None => {
|
||||
// Delete this key
|
||||
key.delete_value(Self::NAMEOF_DEFAULT)?;
|
||||
regext::arbitrarily_delete_value(&key, Self::NAMEOF_DEFAULT)?;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -214,7 +214,10 @@ impl ExtKey {
|
||||
None => return Ok(()),
|
||||
};
|
||||
// Remove given key
|
||||
open_with_progids_key.delete_value(pid.to_string())?;
|
||||
regext::arbitrarily_delete_value(
|
||||
&open_with_progids_key,
|
||||
regext::blank_path_guard(pid.to_string())?,
|
||||
)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -138,7 +138,7 @@ impl ProgIdKey {
|
||||
}
|
||||
None => {
|
||||
// Delete this key
|
||||
key.delete_value(Self::NAMEOF_DEFAULT)?;
|
||||
regext::arbitrarily_delete_value(&key, Self::NAMEOF_DEFAULT)?;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -252,7 +252,7 @@ impl ProgIdKey {
|
||||
}
|
||||
None => {
|
||||
// Delete this key
|
||||
key.delete_value(Self::NAMEOF_FRIENDLY_TYPE_NAME)?;
|
||||
regext::arbitrarily_delete_value(&key, Self::NAMEOF_FRIENDLY_TYPE_NAME)?;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -66,7 +66,7 @@ pub fn try_get_value<T: FromRegValue, N: AsRef<OsStr>>(
|
||||
/// This function was invented to fix the shortcoming of [RegKey::delete_subkey_all].
|
||||
/// This function always delete given path of given key no matter it is existing.
|
||||
/// Oppositely, [RegKey::delete_subkey_all] will return error if there is no such path.
|
||||
///
|
||||
///
|
||||
/// Return true if we successfully delete this key,
|
||||
/// otherwise false indicating there is no such key (already deleted).
|
||||
pub fn arbitrarily_delete_subkey_all<P: AsRef<OsStr>>(
|
||||
@@ -85,6 +85,30 @@ pub fn arbitrarily_delete_subkey_all<P: AsRef<OsStr>>(
|
||||
}
|
||||
}
|
||||
|
||||
/// Delete given value key of given key anyway.
|
||||
///
|
||||
/// This function was invented to fix the shortcoming of [RegKey::delete_value].
|
||||
/// This function always delete given value key of given key no matter it is existing.
|
||||
/// Oppositely, [RegKey::delete_value] will return error if there is no such value key.
|
||||
///
|
||||
/// Return true if we successfully delete this value key,
|
||||
/// otherwise false indicating there is no such value key (already deleted).
|
||||
pub fn arbitrarily_delete_value<N: AsRef<OsStr>>(
|
||||
regkey: &RegKey,
|
||||
name: N,
|
||||
) -> std::io::Result<bool> {
|
||||
match regkey.delete_value(name) {
|
||||
Ok(()) => Ok(true),
|
||||
Err(e) => match e.raw_os_error() {
|
||||
Some(errno) => match errno as u32 {
|
||||
ERROR_FILE_NOT_FOUND => Ok(false),
|
||||
_ => Err(e),
|
||||
},
|
||||
_ => Err(e),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
/// Get the name of only subkey in given key.
|
||||
///
|
||||
/// If there is only one subkey in given key, the return value is its name.
|
||||
|
||||
@@ -9,8 +9,19 @@ pub fn check_sandbox() {
|
||||
std::env::var("SANDBOXIE").is_ok(),
|
||||
concat!(
|
||||
"Non-sandbox environment detected. ",
|
||||
"Executing these test in non-sandbox environment is VERY dangerous. ",
|
||||
"Please set \"SANDBOXIE\" environment variable to explicitly indicate you are running these test in sandbox environment."
|
||||
"Executing these tests in non-sandbox environment is VERY dangerous. ",
|
||||
"Please set \"SANDBOXIE\" environment variable to explicitly indicate you are running these tests in sandbox environment."
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
pub fn check_privilege() {
|
||||
assert!(
|
||||
wfassoc::win32::utilities::has_privilege(),
|
||||
concat!(
|
||||
"You are running test without privilege. ",
|
||||
"These tests must be run with some privilege because it need to manipulate Windows Registry. ",
|
||||
"Please give it privilege in your sandbox environment."
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -13,8 +13,8 @@ fn make_valid_schema() -> Schema {
|
||||
schema.set_clsid(CLSID);
|
||||
schema.add_str("main_name", "Passoc Application").unwrap();
|
||||
schema.add_str("ext_name", "Pacfg File").unwrap();
|
||||
schema.add_icon("main_icon", r"notepad.exe,0").unwrap();
|
||||
schema.add_icon("ext_icon", r"notepad.exe,0").unwrap();
|
||||
schema.add_icon("main_icon", "notepad.exe,0").unwrap();
|
||||
schema.add_icon("ext_icon", "notepad.exe,0").unwrap();
|
||||
schema.add_behavior("main_behavior", "notepad.exe %1").unwrap();
|
||||
schema.add_behavior("ext_behavior", "notepad.exe %1").unwrap();
|
||||
schema.set_name(Some("main_name"));
|
||||
@@ -29,21 +29,20 @@ fn make_valid_schema() -> Schema {
|
||||
#[test]
|
||||
fn test_schema() {
|
||||
common::check_sandbox();
|
||||
common::check_privilege();
|
||||
|
||||
// valid schema -> valid program
|
||||
let schema = make_valid_schema();
|
||||
let rv = schema.into_program();
|
||||
assert!(rv.is_ok());
|
||||
|
||||
// missing identifier
|
||||
let mut schema = Schema::new();
|
||||
schema.set_path(APP_PATH);
|
||||
// missing essential parts (schema, path and etc)
|
||||
let schema = Schema::new();
|
||||
let rv = schema.into_program();
|
||||
assert!(rv.is_err());
|
||||
|
||||
// invalid path
|
||||
let mut schema = Schema::new();
|
||||
schema.set_identifier(IDENTIFIER);
|
||||
let mut schema = make_valid_schema();
|
||||
schema.set_path(r"C:\");
|
||||
let rv = schema.into_program();
|
||||
assert!(rv.is_err());
|
||||
@@ -93,6 +92,7 @@ fn test_schema() {
|
||||
#[test]
|
||||
fn test_program() {
|
||||
common::check_sandbox();
|
||||
common::check_privilege();
|
||||
|
||||
fn tester(scope: Scope, view: View) {
|
||||
// build program
|
||||
|
||||
@@ -22,6 +22,7 @@ static VERB: LazyLock<ShellVerb> = LazyLock::new(|| {
|
||||
#[test]
|
||||
fn test_app_paths_key() {
|
||||
common::check_sandbox();
|
||||
common::check_privilege();
|
||||
|
||||
static APP_PATH: &str = r"C:\Program Files\Passoc\passoc.exe";
|
||||
static APP_DIR: &str = r"C:\Program Files\Passoc";
|
||||
@@ -31,7 +32,6 @@ fn test_app_paths_key() {
|
||||
|
||||
// delete and ensure
|
||||
let rv = key.delete(scope);
|
||||
eprintln!("{rv:?}");
|
||||
assert!(rv.is_ok());
|
||||
let rv = key.is_exist(scope);
|
||||
assert!(rv.is_ok());
|
||||
@@ -76,6 +76,7 @@ fn test_app_paths_key() {
|
||||
#[test]
|
||||
fn test_applications_key() {
|
||||
common::check_sandbox();
|
||||
common::check_privilege();
|
||||
|
||||
static FRIENDLY_APP_NAME: LazyLock<StrResVariant> =
|
||||
LazyLock::new(|| "Passoc Application".into());
|
||||
@@ -178,6 +179,7 @@ fn test_applications_key() {
|
||||
#[test]
|
||||
fn test_ext_key() {
|
||||
common::check_sandbox();
|
||||
common::check_privilege();
|
||||
|
||||
fn tester(scope: Scope, view: View) {
|
||||
let mut key = ExtKey::new(EXT.clone());
|
||||
@@ -247,6 +249,7 @@ fn test_ext_key() {
|
||||
#[test]
|
||||
fn test_prog_id_key() {
|
||||
common::check_sandbox();
|
||||
common::check_privilege();
|
||||
|
||||
static LEGACY_NAME: LazyLock<StrResVariant> = LazyLock::new(|| "Passoc Pacfg File".into());
|
||||
static FRIENDLY_TYPE_NAME: LazyLock<StrResVariant> =
|
||||
|
||||
Reference in New Issue
Block a user