mirror of
https://github.com/martinvonz/jj.git
synced 2025-05-05 15:32:49 +00:00
lib: remove usage of winreg
crate
This pulls in a whole library just for what is morally 3 function calls and can be done easily in the Windows API. Remove it. This uses `unsafe`; the usage of `windows-rs` might be more preferrable since we already (and will likely always) depend on it, but it would probably remain unsafe... Signed-off-by: Austin Seipp <aseipp@pobox.com>
This commit is contained in:
parent
af4f7a7811
commit
2c76f79b57
11
Cargo.lock
generated
11
Cargo.lock
generated
@ -2396,7 +2396,6 @@ dependencies = [
|
||||
"tracing",
|
||||
"version_check",
|
||||
"watchman_client",
|
||||
"winreg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -4798,16 +4797,6 @@ dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winreg"
|
||||
version = "0.52.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a277a57398d4bfa075df44f501a17cfdf8542d224f0d36095a2adc7aee4ef0a5"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wit-bindgen-rt"
|
||||
version = "0.39.0"
|
||||
|
@ -122,7 +122,6 @@ unicode-width = "0.2.0"
|
||||
version_check = "0.9.5"
|
||||
watchman_client = { version = "0.9.0" }
|
||||
whoami = "1.6.0"
|
||||
winreg = "0.52"
|
||||
|
||||
# put all inter-workspace libraries, i.e. those that use 'path = ...' here in
|
||||
# their own (alphabetically sorted) block
|
||||
|
@ -79,7 +79,6 @@ watchman_client = { workspace = true, optional = true }
|
||||
rustix = { workspace = true }
|
||||
|
||||
[target.'cfg(windows)'.dependencies]
|
||||
winreg = { workspace = true }
|
||||
|
||||
[dev-dependencies]
|
||||
assert_matches = { workspace = true }
|
||||
|
@ -180,20 +180,97 @@ mod platform {
|
||||
|
||||
#[cfg(windows)]
|
||||
mod platform {
|
||||
use std::ffi::c_void;
|
||||
use std::io;
|
||||
use std::mem;
|
||||
use std::os::windows::fs::symlink_file;
|
||||
use std::path::Path;
|
||||
use std::ptr;
|
||||
|
||||
use winreg::enums::HKEY_LOCAL_MACHINE;
|
||||
use winreg::RegKey;
|
||||
type HKEY = *mut c_void;
|
||||
type LSTATUS = i32;
|
||||
type DWORD = u32;
|
||||
type REGSAM = u32;
|
||||
|
||||
const HKEY_LOCAL_MACHINE: HKEY = 0x80000002 as HKEY;
|
||||
const KEY_READ: REGSAM = 0x20019;
|
||||
const REG_DWORD: DWORD = 4;
|
||||
const ERROR_SUCCESS: LSTATUS = 0;
|
||||
|
||||
#[link(name = "advapi32")]
|
||||
extern "system" {
|
||||
fn RegOpenKeyExA(
|
||||
hKey: HKEY,
|
||||
lpSubKey: *const u8,
|
||||
ulOptions: DWORD,
|
||||
samDesired: REGSAM,
|
||||
phkResult: *mut HKEY,
|
||||
) -> LSTATUS;
|
||||
|
||||
fn RegQueryValueExA(
|
||||
hKey: HKEY,
|
||||
lpValueName: *const u8,
|
||||
lpReserved: *mut DWORD,
|
||||
lpType: *mut DWORD,
|
||||
lpData: *mut u8,
|
||||
lpcbData: *mut DWORD,
|
||||
) -> LSTATUS;
|
||||
|
||||
fn RegCloseKey(hKey: HKEY) -> LSTATUS;
|
||||
}
|
||||
|
||||
/// Symlinks may or may not be enabled on Windows. They require the
|
||||
/// Developer Mode setting, which is stored in the registry key below.
|
||||
pub fn check_symlink_support() -> io::Result<bool> {
|
||||
let hklm = RegKey::predef(HKEY_LOCAL_MACHINE);
|
||||
let sideloading =
|
||||
hklm.open_subkey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\AppModelUnlock")?;
|
||||
let developer_mode: u32 = sideloading.get_value("AllowDevelopmentWithoutDevLicense")?;
|
||||
// Registry subkey containing the developer mode setting
|
||||
let subkey = b"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\AppModelUnlock\0";
|
||||
// Value name for developer mode setting
|
||||
let value_name = b"AllowDevelopmentWithoutDevLicense\0";
|
||||
|
||||
// Return value from registry operations
|
||||
let mut key_handle: HKEY = ptr::null_mut();
|
||||
let mut developer_mode: DWORD = 0;
|
||||
let mut value_type: DWORD = 0;
|
||||
let mut data_size: DWORD = mem::size_of::<DWORD>() as DWORD;
|
||||
|
||||
#[allow(unsafe_code)]
|
||||
unsafe {
|
||||
// Open the registry key
|
||||
let result = RegOpenKeyExA(
|
||||
HKEY_LOCAL_MACHINE,
|
||||
subkey.as_ptr(),
|
||||
0,
|
||||
KEY_READ,
|
||||
&mut key_handle,
|
||||
);
|
||||
|
||||
if result != ERROR_SUCCESS {
|
||||
return Err(io::Error::from_raw_os_error(result));
|
||||
}
|
||||
|
||||
let result = RegQueryValueExA(
|
||||
key_handle,
|
||||
value_name.as_ptr(),
|
||||
ptr::null_mut(),
|
||||
&mut value_type,
|
||||
&mut developer_mode as *mut DWORD as *mut u8,
|
||||
&mut data_size,
|
||||
);
|
||||
|
||||
RegCloseKey(key_handle);
|
||||
|
||||
if result != ERROR_SUCCESS {
|
||||
return Err(io::Error::from_raw_os_error(result));
|
||||
}
|
||||
|
||||
if value_type != REG_DWORD {
|
||||
return Err(io::Error::new(
|
||||
io::ErrorKind::InvalidData,
|
||||
"Registry value is not a DWORD",
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
Ok(developer_mode == 1)
|
||||
}
|
||||
|
||||
|
@ -16,7 +16,7 @@
|
||||
|
||||
#![warn(missing_docs)]
|
||||
#![deny(unused_must_use)]
|
||||
#![forbid(unsafe_code)]
|
||||
#![deny(unsafe_code)]
|
||||
|
||||
// Needed so that proc macros can be used inside jj_lib and by external crates
|
||||
// that depend on it.
|
||||
|
Loading…
x
Reference in New Issue
Block a user