|
|
@ -1,30 +1,29 @@
|
|
|
|
use std::ffi::{CString};
|
|
|
|
use std::ffi::CString;
|
|
|
|
use std::ptr::{null, null_mut};
|
|
|
|
use std::ptr::{null, null_mut};
|
|
|
|
#[cfg(windows)]
|
|
|
|
#[cfg(windows)]
|
|
|
|
use winapi::{
|
|
|
|
use winapi::{
|
|
|
|
shared::minwindef::{HKEY, MAX_PATH, DWORD},
|
|
|
|
shared::minwindef::{DWORD, HKEY, MAX_PATH},
|
|
|
|
um::{
|
|
|
|
um::{
|
|
|
|
winnt::{
|
|
|
|
libloaderapi::GetModuleFileNameA,
|
|
|
|
REG_SZ, REG_OPTION_NON_VOLATILE, KEY_WRITE
|
|
|
|
winnt::{KEY_WRITE, REG_OPTION_NON_VOLATILE, REG_SZ},
|
|
|
|
|
|
|
|
winreg::{RegCloseKey, RegCreateKeyExA, RegDeleteTreeA, RegSetValueExA, HKEY_CLASSES_ROOT},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
winreg::{
|
|
|
|
|
|
|
|
RegCreateKeyExA, RegSetValueExA, RegCloseKey, RegDeleteTreeA,
|
|
|
|
|
|
|
|
HKEY_CLASSES_ROOT
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
libloaderapi::{
|
|
|
|
|
|
|
|
GetModuleFileNameA
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
#[cfg(target_os = "windows")]
|
|
|
|
#[cfg(target_os = "windows")]
|
|
|
|
fn get_binary_path() -> String {
|
|
|
|
fn get_binary_path() -> String {
|
|
|
|
let mut buffer = vec![0u8; MAX_PATH];
|
|
|
|
let mut buffer = vec![0u8; MAX_PATH];
|
|
|
|
unsafe {
|
|
|
|
unsafe {
|
|
|
|
GetModuleFileNameA(null_mut(), buffer.as_mut_ptr() as *mut i8, MAX_PATH as DWORD);
|
|
|
|
GetModuleFileNameA(
|
|
|
|
|
|
|
|
null_mut(),
|
|
|
|
|
|
|
|
buffer.as_mut_ptr() as *mut i8,
|
|
|
|
|
|
|
|
MAX_PATH as DWORD,
|
|
|
|
|
|
|
|
);
|
|
|
|
CString::from_vec_unchecked(buffer)
|
|
|
|
CString::from_vec_unchecked(buffer)
|
|
|
|
.into_string().unwrap_or_else(|_| "".to_string())
|
|
|
|
.into_string()
|
|
|
|
.trim_end_matches(char::from(0)).to_string()
|
|
|
|
.unwrap_or_else(|_| "".to_string())
|
|
|
|
|
|
|
|
.trim_end_matches(char::from(0))
|
|
|
|
|
|
|
|
.to_string()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -44,41 +43,83 @@ pub fn register_rightclick_directory() -> bool {
|
|
|
|
let neovide_path = get_binary_path();
|
|
|
|
let neovide_path = get_binary_path();
|
|
|
|
let mut registry_key: HKEY = null_mut();
|
|
|
|
let mut registry_key: HKEY = null_mut();
|
|
|
|
let str_registry_path = CString::new("Directory\\Background\\shell\\Neovide").unwrap();
|
|
|
|
let str_registry_path = CString::new("Directory\\Background\\shell\\Neovide").unwrap();
|
|
|
|
let str_registry_command_path = CString::new("Directory\\Background\\shell\\Neovide\\command").unwrap();
|
|
|
|
let str_registry_command_path =
|
|
|
|
|
|
|
|
CString::new("Directory\\Background\\shell\\Neovide\\command").unwrap();
|
|
|
|
let str_icon = CString::new("Icon").unwrap();
|
|
|
|
let str_icon = CString::new("Icon").unwrap();
|
|
|
|
let str_command = CString::new(format!("{} \"%V\"", neovide_path).as_bytes()).unwrap();
|
|
|
|
let str_command = CString::new(format!("{} \"%V\"", neovide_path).as_bytes()).unwrap();
|
|
|
|
let str_description= CString::new("Open with Neovide").unwrap();
|
|
|
|
let str_description = CString::new("Open with Neovide").unwrap();
|
|
|
|
let str_neovide_path = CString::new(neovide_path.as_bytes()).unwrap();
|
|
|
|
let str_neovide_path = CString::new(neovide_path.as_bytes()).unwrap();
|
|
|
|
unsafe {
|
|
|
|
unsafe {
|
|
|
|
if RegCreateKeyExA(
|
|
|
|
if RegCreateKeyExA(
|
|
|
|
HKEY_CLASSES_ROOT, str_registry_path.as_ptr(),
|
|
|
|
HKEY_CLASSES_ROOT,
|
|
|
|
0, null_mut(),
|
|
|
|
str_registry_path.as_ptr(),
|
|
|
|
REG_OPTION_NON_VOLATILE, KEY_WRITE,
|
|
|
|
0,
|
|
|
|
null_mut(), &mut registry_key, null_mut()) != 0 {
|
|
|
|
null_mut(),
|
|
|
|
|
|
|
|
REG_OPTION_NON_VOLATILE,
|
|
|
|
|
|
|
|
KEY_WRITE,
|
|
|
|
|
|
|
|
null_mut(),
|
|
|
|
|
|
|
|
&mut registry_key,
|
|
|
|
|
|
|
|
null_mut(),
|
|
|
|
|
|
|
|
) != 0
|
|
|
|
|
|
|
|
{
|
|
|
|
RegCloseKey(registry_key);
|
|
|
|
RegCloseKey(registry_key);
|
|
|
|
return false;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
let registry_values = [
|
|
|
|
let registry_values = [
|
|
|
|
(null(), REG_SZ, str_description.as_ptr() as *const u8, str_description.to_bytes().len() + 1),
|
|
|
|
(
|
|
|
|
(str_icon.as_ptr(), REG_SZ, str_neovide_path.as_ptr() as *const u8, str_neovide_path.to_bytes().len() + 1),
|
|
|
|
null(),
|
|
|
|
|
|
|
|
REG_SZ,
|
|
|
|
|
|
|
|
str_description.as_ptr() as *const u8,
|
|
|
|
|
|
|
|
str_description.to_bytes().len() + 1,
|
|
|
|
|
|
|
|
),
|
|
|
|
|
|
|
|
(
|
|
|
|
|
|
|
|
str_icon.as_ptr(),
|
|
|
|
|
|
|
|
REG_SZ,
|
|
|
|
|
|
|
|
str_neovide_path.as_ptr() as *const u8,
|
|
|
|
|
|
|
|
str_neovide_path.to_bytes().len() + 1,
|
|
|
|
|
|
|
|
),
|
|
|
|
];
|
|
|
|
];
|
|
|
|
for &(key, keytype, value_ptr, size_in_bytes) in ®istry_values {
|
|
|
|
for &(key, keytype, value_ptr, size_in_bytes) in ®istry_values {
|
|
|
|
RegSetValueExA(registry_key, key, 0, keytype, value_ptr, size_in_bytes as u32);
|
|
|
|
RegSetValueExA(
|
|
|
|
|
|
|
|
registry_key,
|
|
|
|
|
|
|
|
key,
|
|
|
|
|
|
|
|
0,
|
|
|
|
|
|
|
|
keytype,
|
|
|
|
|
|
|
|
value_ptr,
|
|
|
|
|
|
|
|
size_in_bytes as u32,
|
|
|
|
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
RegCloseKey(registry_key);
|
|
|
|
RegCloseKey(registry_key);
|
|
|
|
|
|
|
|
|
|
|
|
if RegCreateKeyExA(
|
|
|
|
if RegCreateKeyExA(
|
|
|
|
HKEY_CLASSES_ROOT, str_registry_command_path.as_ptr(),
|
|
|
|
HKEY_CLASSES_ROOT,
|
|
|
|
0, null_mut(),
|
|
|
|
str_registry_command_path.as_ptr(),
|
|
|
|
REG_OPTION_NON_VOLATILE, KEY_WRITE,
|
|
|
|
0,
|
|
|
|
null_mut(), &mut registry_key, null_mut()) != 0 {
|
|
|
|
null_mut(),
|
|
|
|
|
|
|
|
REG_OPTION_NON_VOLATILE,
|
|
|
|
|
|
|
|
KEY_WRITE,
|
|
|
|
|
|
|
|
null_mut(),
|
|
|
|
|
|
|
|
&mut registry_key,
|
|
|
|
|
|
|
|
null_mut(),
|
|
|
|
|
|
|
|
) != 0
|
|
|
|
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
let registry_values = [
|
|
|
|
let registry_values = [(
|
|
|
|
(null(), REG_SZ, str_command.as_ptr() as *const u8, str_command.to_bytes().len() + 1),
|
|
|
|
null(),
|
|
|
|
];
|
|
|
|
REG_SZ,
|
|
|
|
|
|
|
|
str_command.as_ptr() as *const u8,
|
|
|
|
|
|
|
|
str_command.to_bytes().len() + 1,
|
|
|
|
|
|
|
|
)];
|
|
|
|
for &(key, keytype, value_ptr, size_in_bytes) in ®istry_values {
|
|
|
|
for &(key, keytype, value_ptr, size_in_bytes) in ®istry_values {
|
|
|
|
RegSetValueExA(registry_key, key, 0, keytype, value_ptr, size_in_bytes as u32);
|
|
|
|
RegSetValueExA(
|
|
|
|
|
|
|
|
registry_key,
|
|
|
|
|
|
|
|
key,
|
|
|
|
|
|
|
|
0,
|
|
|
|
|
|
|
|
keytype,
|
|
|
|
|
|
|
|
value_ptr,
|
|
|
|
|
|
|
|
size_in_bytes as u32,
|
|
|
|
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
RegCloseKey(registry_key);
|
|
|
|
RegCloseKey(registry_key);
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -93,38 +134,79 @@ pub fn register_rightclick_file() -> bool {
|
|
|
|
let str_registry_command_path = CString::new("*\\shell\\Neovide\\command").unwrap();
|
|
|
|
let str_registry_command_path = CString::new("*\\shell\\Neovide\\command").unwrap();
|
|
|
|
let str_icon = CString::new("Icon").unwrap();
|
|
|
|
let str_icon = CString::new("Icon").unwrap();
|
|
|
|
let str_command = CString::new(format!("{} \"%1\"", neovide_path).as_bytes()).unwrap();
|
|
|
|
let str_command = CString::new(format!("{} \"%1\"", neovide_path).as_bytes()).unwrap();
|
|
|
|
let str_description= CString::new("Open with Neovide").unwrap();
|
|
|
|
let str_description = CString::new("Open with Neovide").unwrap();
|
|
|
|
let str_neovide_path = CString::new(neovide_path.as_bytes()).unwrap();
|
|
|
|
let str_neovide_path = CString::new(neovide_path.as_bytes()).unwrap();
|
|
|
|
unsafe {
|
|
|
|
unsafe {
|
|
|
|
if RegCreateKeyExA(
|
|
|
|
if RegCreateKeyExA(
|
|
|
|
HKEY_CLASSES_ROOT, str_registry_path.as_ptr(),
|
|
|
|
HKEY_CLASSES_ROOT,
|
|
|
|
0, null_mut(),
|
|
|
|
str_registry_path.as_ptr(),
|
|
|
|
REG_OPTION_NON_VOLATILE, KEY_WRITE,
|
|
|
|
0,
|
|
|
|
null_mut(), &mut registry_key, null_mut()) != 0 {
|
|
|
|
null_mut(),
|
|
|
|
|
|
|
|
REG_OPTION_NON_VOLATILE,
|
|
|
|
|
|
|
|
KEY_WRITE,
|
|
|
|
|
|
|
|
null_mut(),
|
|
|
|
|
|
|
|
&mut registry_key,
|
|
|
|
|
|
|
|
null_mut(),
|
|
|
|
|
|
|
|
) != 0
|
|
|
|
|
|
|
|
{
|
|
|
|
RegCloseKey(registry_key);
|
|
|
|
RegCloseKey(registry_key);
|
|
|
|
return false;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
let registry_values = [
|
|
|
|
let registry_values = [
|
|
|
|
(null(), REG_SZ, str_description.as_ptr() as *const u8, str_description.to_bytes().len() + 1),
|
|
|
|
(
|
|
|
|
(str_icon.as_ptr(), REG_SZ, str_neovide_path.as_ptr() as *const u8, str_neovide_path.to_bytes().len() + 1),
|
|
|
|
null(),
|
|
|
|
|
|
|
|
REG_SZ,
|
|
|
|
|
|
|
|
str_description.as_ptr() as *const u8,
|
|
|
|
|
|
|
|
str_description.to_bytes().len() + 1,
|
|
|
|
|
|
|
|
),
|
|
|
|
|
|
|
|
(
|
|
|
|
|
|
|
|
str_icon.as_ptr(),
|
|
|
|
|
|
|
|
REG_SZ,
|
|
|
|
|
|
|
|
str_neovide_path.as_ptr() as *const u8,
|
|
|
|
|
|
|
|
str_neovide_path.to_bytes().len() + 1,
|
|
|
|
|
|
|
|
),
|
|
|
|
];
|
|
|
|
];
|
|
|
|
for &(key, keytype, value_ptr, size_in_bytes) in ®istry_values {
|
|
|
|
for &(key, keytype, value_ptr, size_in_bytes) in ®istry_values {
|
|
|
|
RegSetValueExA(registry_key, key, 0, keytype, value_ptr, size_in_bytes as u32);
|
|
|
|
RegSetValueExA(
|
|
|
|
|
|
|
|
registry_key,
|
|
|
|
|
|
|
|
key,
|
|
|
|
|
|
|
|
0,
|
|
|
|
|
|
|
|
keytype,
|
|
|
|
|
|
|
|
value_ptr,
|
|
|
|
|
|
|
|
size_in_bytes as u32,
|
|
|
|
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
RegCloseKey(registry_key);
|
|
|
|
RegCloseKey(registry_key);
|
|
|
|
|
|
|
|
|
|
|
|
if RegCreateKeyExA(
|
|
|
|
if RegCreateKeyExA(
|
|
|
|
HKEY_CLASSES_ROOT, str_registry_command_path.as_ptr(),
|
|
|
|
HKEY_CLASSES_ROOT,
|
|
|
|
0, null_mut(),
|
|
|
|
str_registry_command_path.as_ptr(),
|
|
|
|
REG_OPTION_NON_VOLATILE, KEY_WRITE,
|
|
|
|
0,
|
|
|
|
null_mut(), &mut registry_key, null_mut()) != 0 {
|
|
|
|
null_mut(),
|
|
|
|
|
|
|
|
REG_OPTION_NON_VOLATILE,
|
|
|
|
|
|
|
|
KEY_WRITE,
|
|
|
|
|
|
|
|
null_mut(),
|
|
|
|
|
|
|
|
&mut registry_key,
|
|
|
|
|
|
|
|
null_mut(),
|
|
|
|
|
|
|
|
) != 0
|
|
|
|
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
let registry_values = [
|
|
|
|
let registry_values = [(
|
|
|
|
(null(), REG_SZ, str_command.as_ptr() as *const u8, str_command.to_bytes().len() + 1),
|
|
|
|
null(),
|
|
|
|
];
|
|
|
|
REG_SZ,
|
|
|
|
|
|
|
|
str_command.as_ptr() as *const u8,
|
|
|
|
|
|
|
|
str_command.to_bytes().len() + 1,
|
|
|
|
|
|
|
|
)];
|
|
|
|
for &(key, keytype, value_ptr, size_in_bytes) in ®istry_values {
|
|
|
|
for &(key, keytype, value_ptr, size_in_bytes) in ®istry_values {
|
|
|
|
RegSetValueExA(registry_key, key, 0, keytype, value_ptr, size_in_bytes as u32);
|
|
|
|
RegSetValueExA(
|
|
|
|
|
|
|
|
registry_key,
|
|
|
|
|
|
|
|
key,
|
|
|
|
|
|
|
|
0,
|
|
|
|
|
|
|
|
keytype,
|
|
|
|
|
|
|
|
value_ptr,
|
|
|
|
|
|
|
|
size_in_bytes as u32,
|
|
|
|
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
RegCloseKey(registry_key);
|
|
|
|
RegCloseKey(registry_key);
|
|
|
|
}
|
|
|
|
}
|
|
|
|