use windows_sys::Win32::Foundation::ERROR_SUCCESS;
use windows_sys::Win32::System::Registry::{
RegCloseKey, RegOpenKeyExW, RegQueryValueExW, HKEY, HKEY_LOCAL_MACHINE, KEY_READ,
KEY_WOW64_64KEY, REG_SZ,
};
fn to_wide_null(s: &str) -> Vec<u16> {
s.encode_utf16().chain(core::iter::once(0u16)).collect()
}
pub fn get_machine_id_impl() -> String {
let access = KEY_READ | KEY_WOW64_64KEY;
let mut hkey: HKEY = 0;
let subkey = to_wide_null("SOFTWARE\\Microsoft\\Cryptography");
let status =
unsafe { RegOpenKeyExW(HKEY_LOCAL_MACHINE, subkey.as_ptr(), 0, access, &mut hkey) };
if status != ERROR_SUCCESS {
return String::new();
}
let value_wide = to_wide_null("MachineGuid");
let mut data_type: u32 = 0;
let mut data_len: u32 = 0;
let status = unsafe {
RegQueryValueExW(
hkey,
value_wide.as_ptr(),
core::ptr::null_mut(),
&mut data_type,
core::ptr::null_mut(),
&mut data_len,
)
};
if status != ERROR_SUCCESS || data_type != REG_SZ {
unsafe { RegCloseKey(hkey) };
return String::new();
}
let mut buf: Vec<u16> = vec![0u16; (data_len as usize).div_ceil(2)];
let mut actual_len = data_len;
let status = unsafe {
RegQueryValueExW(
hkey,
value_wide.as_ptr(),
core::ptr::null_mut(),
&mut data_type,
buf.as_mut_ptr().cast(),
&mut actual_len,
)
};
unsafe { RegCloseKey(hkey) };
if status != ERROR_SUCCESS {
return String::new();
}
while buf.last() == Some(&0u16) {
buf.pop();
}
String::from_utf16(&buf)
.unwrap_or_default()
.trim()
.to_owned()
}