Skip to content

Commit 7066383

Browse files
authored
chore: avoid winreg dependency (#1825)
1 parent 177f616 commit 7066383

File tree

4 files changed

+112
-40
lines changed

4 files changed

+112
-40
lines changed

Cargo.lock

Lines changed: 1 addition & 20 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

THIRD_PARTY_NOTICES.md

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2659,12 +2659,6 @@ Distributed under the following license(s):
26592659

26602660
* MIT
26612661

2662-
## winreg <https://crates.io/crates/winreg>
2663-
2664-
Distributed under the following license(s):
2665-
2666-
* MIT
2667-
26682662
## wit-bindgen <https://crates.io/crates/wit-bindgen>
26692663

26702664
Distributed under the following license(s):

resource-detection/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ konst = { workspace = true }
2020

2121
[target.'cfg(windows)'.dependencies]
2222
windows-link = "0.2.1"
23-
winreg = "0.55"
23+
windows-sys = { version = "0.61.2", features = ["Win32_System_Registry"] }
2424

2525
[dev-dependencies]
2626
assert_matches = { workspace = true }

resource-detection/src/system/machine_identifier/windows.rs

Lines changed: 110 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use crate::system::detector::SystemDetectorError;
2-
use winreg::{
3-
RegKey,
4-
enums::{HKEY_LOCAL_MACHINE, KEY_READ},
2+
use windows_sys::Win32::Foundation::ERROR_SUCCESS;
3+
use windows_sys::Win32::System::Registry::{
4+
HKEY_LOCAL_MACHINE, KEY_READ, REG_SZ, RegCloseKey, RegOpenKeyExW, RegQueryValueExW,
55
};
66

77
const CRYPTOGRAPHY_KEY_PATH: &str = "SOFTWARE\\Microsoft\\Cryptography";
@@ -11,17 +11,114 @@ const MACHINE_GUID_KEY_NAME: &str = "MachineGuid";
1111
pub struct MachineIdentityProvider {}
1212

1313
impl MachineIdentityProvider {
14-
/// Reads the _MachineGuid_ from the Windows registry using [winreg].
14+
/// Reads the _MachineGuid_ from the Windows registry.
1515
pub fn provide(&self) -> Result<String, SystemDetectorError> {
16-
let hklm = RegKey::predef(HKEY_LOCAL_MACHINE); // Open the local machine root key.
17-
// Open the Cryptography reg key with read permissions
18-
let cryptography_key = hklm
19-
.open_subkey_with_flags(CRYPTOGRAPHY_KEY_PATH, KEY_READ)
20-
.map_err(|err| SystemDetectorError::MachineIDError(err.to_string()))?;
21-
// Get the value from the registry
22-
cryptography_key
23-
.get_value(MACHINE_GUID_KEY_NAME)
24-
.map_err(|err| SystemDetectorError::MachineIDError(err.to_string()))
16+
// Convert the value names to wide strings (UTF-16)
17+
let key_path: Vec<u16> = CRYPTOGRAPHY_KEY_PATH
18+
.encode_utf16()
19+
.chain(std::iter::once(0))
20+
.collect();
21+
let key_name: Vec<u16> = MACHINE_GUID_KEY_NAME
22+
.encode_utf16()
23+
.chain(std::iter::once(0))
24+
.collect();
25+
26+
Self::read_string_from_registry(key_path, key_name)
27+
}
28+
29+
/// Helper to read a string from the registry
30+
pub fn read_string_from_registry(
31+
key_path: Vec<u16>,
32+
key_name: Vec<u16>,
33+
) -> Result<String, SystemDetectorError> {
34+
unsafe {
35+
// Open the registry key
36+
let mut registry_key: *mut std::ffi::c_void = std::ptr::null_mut();
37+
let result = RegOpenKeyExW(
38+
HKEY_LOCAL_MACHINE,
39+
key_path.as_ptr(),
40+
0,
41+
KEY_READ,
42+
&mut registry_key,
43+
);
44+
45+
if result != ERROR_SUCCESS {
46+
return Err(SystemDetectorError::MachineIDError(format!(
47+
"failed to open registry key: error code {}",
48+
result
49+
)));
50+
}
51+
52+
// Query the type and size of the value
53+
let mut value_type = 0u32;
54+
let mut data_size = 0u32;
55+
56+
let result = RegQueryValueExW(
57+
registry_key,
58+
key_name.as_ptr(),
59+
std::ptr::null(),
60+
&mut value_type,
61+
std::ptr::null_mut(),
62+
&mut data_size,
63+
);
64+
65+
if result != ERROR_SUCCESS {
66+
Self::close_registry_key(registry_key)?;
67+
return Err(SystemDetectorError::MachineIDError(format!(
68+
"failed to query registry value size: error code {}",
69+
result
70+
)));
71+
}
72+
73+
// Allocate buffer and read the actual value
74+
let mut buffer: Vec<u16> = vec![0; (data_size / 2) as usize];
75+
76+
let result = RegQueryValueExW(
77+
registry_key,
78+
key_name.as_ptr(),
79+
std::ptr::null(),
80+
&mut value_type,
81+
buffer.as_mut_ptr() as *mut u8,
82+
&mut data_size,
83+
);
84+
85+
Self::close_registry_key(registry_key)?;
86+
87+
if result != ERROR_SUCCESS {
88+
return Err(SystemDetectorError::MachineIDError(format!(
89+
"failed to read registry value: error code {}",
90+
result
91+
)));
92+
}
93+
94+
// Verify it's a string type
95+
if value_type != REG_SZ {
96+
return Err(SystemDetectorError::MachineIDError(format!(
97+
"unexpected registry value type: {}",
98+
value_type
99+
)));
100+
}
101+
102+
// Convert from UTF-16 to String, removing the null terminator
103+
let string_value = String::from_utf16_lossy(&buffer)
104+
.trim_end_matches('\0')
105+
.to_string();
106+
107+
Ok(string_value)
108+
}
109+
}
110+
111+
/// Helper to close the registry key returning the corresponding error on failure
112+
unsafe fn close_registry_key(hkey: *mut std::ffi::c_void) -> Result<(), SystemDetectorError> {
113+
unsafe {
114+
let result = RegCloseKey(hkey);
115+
if result != ERROR_SUCCESS {
116+
return Err(SystemDetectorError::MachineIDError(format!(
117+
"failed to close the registry key: error code {result}"
118+
)));
119+
}
120+
Ok(())
121+
}
25122
}
26123
}
27124

0 commit comments

Comments
 (0)