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.
|
// Add this progid to file extension "open with" list.
|
||||||
let ext_key = &mut program_key.ext_key;
|
let ext_key = &mut program_key.ext_key;
|
||||||
|
ext_key.ensure(scope)?;
|
||||||
ext_key.add_into_open_with_progids(scope, progid_key.inner())?;
|
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.
|
// there is no need to reset the default open way of file extension.
|
||||||
// So we simply remove it from "open with" list.
|
// 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;
|
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
|
// Delete ProgId subkey
|
||||||
progid_key.delete(scope)?;
|
progid_key.delete(scope)?;
|
||||||
|
|||||||
@@ -156,7 +156,7 @@ impl Schema {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn get_behavior(&self) -> Option<&str> {
|
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> {
|
pub(super) fn get_strs(&self) -> &HashMap<String, String> {
|
||||||
|
|||||||
@@ -257,7 +257,7 @@ impl ApplicationsKey {
|
|||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
// Delete this key
|
// 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 {
|
if flag {
|
||||||
key.set_value(Self::NAMEOF_NO_OPEN_WITH, &"")?;
|
key.set_value(Self::NAMEOF_NO_OPEN_WITH, &"")?;
|
||||||
} else {
|
} else {
|
||||||
key.delete_value(Self::NAMEOF_NO_OPEN_WITH)?;
|
regext::arbitrarily_delete_value(&key, Self::NAMEOF_NO_OPEN_WITH)?;
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -136,7 +136,7 @@ impl ExtKey {
|
|||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
// Delete this key
|
// 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(()),
|
None => return Ok(()),
|
||||||
};
|
};
|
||||||
// Remove given key
|
// 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(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -138,7 +138,7 @@ impl ProgIdKey {
|
|||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
// Delete this key
|
// Delete this key
|
||||||
key.delete_value(Self::NAMEOF_DEFAULT)?;
|
regext::arbitrarily_delete_value(&key, Self::NAMEOF_DEFAULT)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -252,7 +252,7 @@ impl ProgIdKey {
|
|||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
// Delete this key
|
// Delete this key
|
||||||
key.delete_value(Self::NAMEOF_FRIENDLY_TYPE_NAME)?;
|
regext::arbitrarily_delete_value(&key, Self::NAMEOF_FRIENDLY_TYPE_NAME)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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.
|
/// Get the name of only subkey in given key.
|
||||||
///
|
///
|
||||||
/// If there is only one subkey in given key, the return value is its name.
|
/// 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(),
|
std::env::var("SANDBOXIE").is_ok(),
|
||||||
concat!(
|
concat!(
|
||||||
"Non-sandbox environment detected. ",
|
"Non-sandbox environment detected. ",
|
||||||
"Executing these test in non-sandbox environment is VERY dangerous. ",
|
"Executing these tests in non-sandbox environment is VERY dangerous. ",
|
||||||
"Please set \"SANDBOXIE\" environment variable to explicitly indicate you are running these test in sandbox environment."
|
"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.set_clsid(CLSID);
|
||||||
schema.add_str("main_name", "Passoc Application").unwrap();
|
schema.add_str("main_name", "Passoc Application").unwrap();
|
||||||
schema.add_str("ext_name", "Pacfg File").unwrap();
|
schema.add_str("ext_name", "Pacfg File").unwrap();
|
||||||
schema.add_icon("main_icon", r"notepad.exe,0").unwrap();
|
schema.add_icon("main_icon", "notepad.exe,0").unwrap();
|
||||||
schema.add_icon("ext_icon", r"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("main_behavior", "notepad.exe %1").unwrap();
|
||||||
schema.add_behavior("ext_behavior", "notepad.exe %1").unwrap();
|
schema.add_behavior("ext_behavior", "notepad.exe %1").unwrap();
|
||||||
schema.set_name(Some("main_name"));
|
schema.set_name(Some("main_name"));
|
||||||
@@ -29,21 +29,20 @@ fn make_valid_schema() -> Schema {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_schema() {
|
fn test_schema() {
|
||||||
common::check_sandbox();
|
common::check_sandbox();
|
||||||
|
common::check_privilege();
|
||||||
|
|
||||||
// valid schema -> valid program
|
// valid schema -> valid program
|
||||||
let schema = make_valid_schema();
|
let schema = make_valid_schema();
|
||||||
let rv = schema.into_program();
|
let rv = schema.into_program();
|
||||||
assert!(rv.is_ok());
|
assert!(rv.is_ok());
|
||||||
|
|
||||||
// missing identifier
|
// missing essential parts (schema, path and etc)
|
||||||
let mut schema = Schema::new();
|
let schema = Schema::new();
|
||||||
schema.set_path(APP_PATH);
|
|
||||||
let rv = schema.into_program();
|
let rv = schema.into_program();
|
||||||
assert!(rv.is_err());
|
assert!(rv.is_err());
|
||||||
|
|
||||||
// invalid path
|
// invalid path
|
||||||
let mut schema = Schema::new();
|
let mut schema = make_valid_schema();
|
||||||
schema.set_identifier(IDENTIFIER);
|
|
||||||
schema.set_path(r"C:\");
|
schema.set_path(r"C:\");
|
||||||
let rv = schema.into_program();
|
let rv = schema.into_program();
|
||||||
assert!(rv.is_err());
|
assert!(rv.is_err());
|
||||||
@@ -93,6 +92,7 @@ fn test_schema() {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_program() {
|
fn test_program() {
|
||||||
common::check_sandbox();
|
common::check_sandbox();
|
||||||
|
common::check_privilege();
|
||||||
|
|
||||||
fn tester(scope: Scope, view: View) {
|
fn tester(scope: Scope, view: View) {
|
||||||
// build program
|
// build program
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ static VERB: LazyLock<ShellVerb> = LazyLock::new(|| {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_app_paths_key() {
|
fn test_app_paths_key() {
|
||||||
common::check_sandbox();
|
common::check_sandbox();
|
||||||
|
common::check_privilege();
|
||||||
|
|
||||||
static APP_PATH: &str = r"C:\Program Files\Passoc\passoc.exe";
|
static APP_PATH: &str = r"C:\Program Files\Passoc\passoc.exe";
|
||||||
static APP_DIR: &str = r"C:\Program Files\Passoc";
|
static APP_DIR: &str = r"C:\Program Files\Passoc";
|
||||||
@@ -31,7 +32,6 @@ fn test_app_paths_key() {
|
|||||||
|
|
||||||
// delete and ensure
|
// delete and ensure
|
||||||
let rv = key.delete(scope);
|
let rv = key.delete(scope);
|
||||||
eprintln!("{rv:?}");
|
|
||||||
assert!(rv.is_ok());
|
assert!(rv.is_ok());
|
||||||
let rv = key.is_exist(scope);
|
let rv = key.is_exist(scope);
|
||||||
assert!(rv.is_ok());
|
assert!(rv.is_ok());
|
||||||
@@ -76,6 +76,7 @@ fn test_app_paths_key() {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_applications_key() {
|
fn test_applications_key() {
|
||||||
common::check_sandbox();
|
common::check_sandbox();
|
||||||
|
common::check_privilege();
|
||||||
|
|
||||||
static FRIENDLY_APP_NAME: LazyLock<StrResVariant> =
|
static FRIENDLY_APP_NAME: LazyLock<StrResVariant> =
|
||||||
LazyLock::new(|| "Passoc Application".into());
|
LazyLock::new(|| "Passoc Application".into());
|
||||||
@@ -178,6 +179,7 @@ fn test_applications_key() {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_ext_key() {
|
fn test_ext_key() {
|
||||||
common::check_sandbox();
|
common::check_sandbox();
|
||||||
|
common::check_privilege();
|
||||||
|
|
||||||
fn tester(scope: Scope, view: View) {
|
fn tester(scope: Scope, view: View) {
|
||||||
let mut key = ExtKey::new(EXT.clone());
|
let mut key = ExtKey::new(EXT.clone());
|
||||||
@@ -247,6 +249,7 @@ fn test_ext_key() {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_prog_id_key() {
|
fn test_prog_id_key() {
|
||||||
common::check_sandbox();
|
common::check_sandbox();
|
||||||
|
common::check_privilege();
|
||||||
|
|
||||||
static LEGACY_NAME: LazyLock<StrResVariant> = LazyLock::new(|| "Passoc Pacfg File".into());
|
static LEGACY_NAME: LazyLock<StrResVariant> = LazyLock::new(|| "Passoc Pacfg File".into());
|
||||||
static FRIENDLY_TYPE_NAME: LazyLock<StrResVariant> =
|
static FRIENDLY_TYPE_NAME: LazyLock<StrResVariant> =
|
||||||
|
|||||||
Reference in New Issue
Block a user