1use thiserror::Error;
8
9#[derive(Debug, Error)]
11pub enum HwIdError {
12 #[error("no HWID was found on system")]
16 NotFound,
17 #[error("{0:?}: contains malformed HWID")]
23 Malformed(String),
24}
25
26#[cfg(target_os = "windows")]
27mod hwid {
28 use super::*;
29 use winreg::enums::{HKEY_LOCAL_MACHINE, KEY_QUERY_VALUE};
30
31 pub fn get_id() -> Result<std::string::String, HwIdError> {
35 let hive = winreg::RegKey::predef(HKEY_LOCAL_MACHINE)
37 .open_subkey_with_flags("Software\\Microsoft\\Cryptography", KEY_QUERY_VALUE)
38 .or(Err(HwIdError::NotFound))?;
39 let id = hive.get_value("MachineGuid").or(Err(HwIdError::NotFound))?;
40 Ok(id)
41 }
42}
43
44#[cfg(target_os = "macos")]
45mod hwid {
46 use super::*;
47
48 pub fn get_id() -> Result<std::string::String, HwIdError> {
57 let cmd = std::process::Command::new("ioreg")
58 .arg("-rd1")
59 .arg("-c")
60 .arg("IOPlatformExpertDevice")
61 .output()
62 .or(Err(HwIdError::NotFound))?
63 .stdout;
64 let out = String::from_utf8(cmd).or(Err(HwIdError::Malformed(String::from("ioreg"))))?;
65 match out
66 .lines()
67 .find(|l| l.contains("IOPlatformUUID"))
68 .unwrap_or("")
69 .split('=')
70 .nth(1)
71 .unwrap_or("")
72 .split('\"')
73 .nth(1)
74 {
75 None => Err(HwIdError::NotFound),
76 Some(id) => {
77 if id.is_empty() {
78 Err(HwIdError::Malformed(String::from("ioreg")))
79 } else {
80 Ok(id.to_string())
81 }
82 }
83 }
84 }
85}
86
87#[cfg(target_os = "linux")]
88mod hwid {
89 use super::*;
90
91 pub fn get_id() -> Result<std::string::String, HwIdError> {
95 let paths = ["/var/lib/dbus/machine-id", "/etc/machine-id"];
96 for p in paths {
97 if let Ok(id_contents) = std::fs::read_to_string(p) {
98 let id_str = id_contents
99 .lines()
100 .next()
101 .ok_or_else(|| HwIdError::Malformed(id_contents.to_string()))?;
102 return Ok(id_str.to_string());
103 }
104 }
105 Err(HwIdError::NotFound)
106 }
107}
108
109#[cfg(target_os = "freebsd")]
110#[cfg(target_os = "dragonfly")]
111#[cfg(target_os = "openbsd")]
112#[cfg(target_os = "netbsd")]
113mod hwid {
114 pub fn get_id() -> std::string::String {
115 unimplemented!("*BSD support is not implemented")
116 }
117}
118
119pub use crate::hwid::get_id;