summaryrefslogtreecommitdiffstats
path: root/vendor/sysinfo/src/windows/utils.rs
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/sysinfo/src/windows/utils.rs')
-rw-r--r--vendor/sysinfo/src/windows/utils.rs93
1 files changed, 92 insertions, 1 deletions
diff --git a/vendor/sysinfo/src/windows/utils.rs b/vendor/sysinfo/src/windows/utils.rs
index 419ee195c..96132117e 100644
--- a/vendor/sysinfo/src/windows/utils.rs
+++ b/vendor/sysinfo/src/windows/utils.rs
@@ -1,8 +1,13 @@
// Take a look at the license at the top of the repository in the LICENSE file.
use winapi::shared::minwindef::FILETIME;
-use winapi::um::winnt::LPWSTR;
+use winapi::shared::minwindef::{DWORD, HKEY};
+use winapi::shared::winerror;
+use winapi::um::winnt::{KEY_READ, LPWSTR};
+use winapi::um::winreg::{RegCloseKey, RegOpenKeyExW, RegQueryValueExW};
+use std::ffi::OsStr;
+use std::os::windows::ffi::OsStrExt;
use std::time::SystemTime;
#[inline]
@@ -34,3 +39,89 @@ pub(crate) unsafe fn to_str(p: LPWSTR) -> String {
String::new()
})
}
+
+fn utf16_str<S: AsRef<OsStr> + ?Sized>(text: &S) -> Vec<u16> {
+ OsStr::new(text)
+ .encode_wide()
+ .chain(Some(0).into_iter())
+ .collect::<Vec<_>>()
+}
+
+struct RegKey(HKEY);
+
+impl RegKey {
+ unsafe fn open(hkey: HKEY, path: &[u16]) -> Option<Self> {
+ let mut new_hkey: HKEY = std::ptr::null_mut();
+ if RegOpenKeyExW(hkey, path.as_ptr(), 0, KEY_READ, &mut new_hkey) != 0 {
+ return None;
+ }
+ Some(Self(new_hkey))
+ }
+
+ unsafe fn get_value(&self, field_name: &[u16], buf: &mut [u8], buf_len: &mut DWORD) -> DWORD {
+ let mut buf_type: DWORD = 0;
+
+ RegQueryValueExW(
+ self.0,
+ field_name.as_ptr(),
+ std::ptr::null_mut(),
+ &mut buf_type,
+ buf.as_mut_ptr() as _,
+ buf_len,
+ ) as DWORD
+ }
+}
+
+impl Drop for RegKey {
+ fn drop(&mut self) {
+ unsafe {
+ RegCloseKey(self.0);
+ }
+ }
+}
+
+pub(crate) fn get_reg_string_value(hkey: HKEY, path: &str, field_name: &str) -> Option<String> {
+ let c_path = utf16_str(path);
+ let c_field_name = utf16_str(field_name);
+
+ unsafe {
+ let new_key = RegKey::open(hkey, &c_path)?;
+ let mut buf_len: DWORD = 2048;
+ let mut buf: Vec<u8> = Vec::with_capacity(buf_len as usize);
+
+ loop {
+ match new_key.get_value(&c_field_name, &mut buf, &mut buf_len) {
+ winerror::ERROR_SUCCESS => break,
+ winerror::ERROR_MORE_DATA => {
+ buf.reserve(buf_len as _);
+ }
+ _ => return None,
+ }
+ }
+
+ buf.set_len(buf_len as _);
+
+ let words = std::slice::from_raw_parts(buf.as_ptr() as *const u16, buf.len() / 2);
+ let mut s = String::from_utf16_lossy(words);
+ while s.ends_with('\u{0}') {
+ s.pop();
+ }
+ Some(s)
+ }
+}
+
+pub(crate) fn get_reg_value_u32(hkey: HKEY, path: &str, field_name: &str) -> Option<[u8; 4]> {
+ let c_path = utf16_str(path);
+ let c_field_name = utf16_str(field_name);
+
+ unsafe {
+ let new_key = RegKey::open(hkey, &c_path)?;
+ let mut buf_len: DWORD = 4;
+ let mut buf = [0u8; 4];
+
+ match new_key.get_value(&c_field_name, &mut buf, &mut buf_len) {
+ winerror::ERROR_SUCCESS => Some(buf),
+ _ => None,
+ }
+ }
+}