From 644211558faa1bcda4c79af0d65a4a5fa1a7c654 Mon Sep 17 00:00:00 2001 From: Carterpersall Date: Tue, 14 Mar 2023 14:31:03 -0500 Subject: [PATCH 01/11] Implementation working --- src/android/mod.rs | 4 ++ src/freebsd/mod.rs | 4 ++ src/linux/mod.rs | 4 ++ src/macos/mod.rs | 4 ++ src/netbsd/mod.rs | 4 ++ src/openwrt/mod.rs | 4 ++ src/traits.rs | 3 + src/windows/mod.rs | 140 ++++++++++++++++++++++++++++++++++++++++++++- 8 files changed, 166 insertions(+), 1 deletion(-) diff --git a/src/android/mod.rs b/src/android/mod.rs index 6d90dd4a..17bb4e17 100644 --- a/src/android/mod.rs +++ b/src/android/mod.rs @@ -268,6 +268,10 @@ impl GeneralReadout for AndroidGeneralReadout { } } + fn gpu_model_name(&self) -> Result { + Err(ReadoutError::NotImplemented) + } + fn uptime(&self) -> Result { let mut info = self.sysinfo; let info_ptr: *mut sysinfo = &mut info; diff --git a/src/freebsd/mod.rs b/src/freebsd/mod.rs index ee988ec0..0c3dd2a8 100644 --- a/src/freebsd/mod.rs +++ b/src/freebsd/mod.rs @@ -257,6 +257,10 @@ impl GeneralReadout for FreeBSDGeneralReadout { shared::cpu_usage() } + fn gpu_model_name(&self) -> Result { + Err(ReadoutError::NotImplemented) + } + fn uptime(&self) -> Result { let ctl = match sysctl::Ctl::new("kern.boottime") { Ok(ctl) => ctl, diff --git a/src/linux/mod.rs b/src/linux/mod.rs index 23763e08..1995bfe8 100644 --- a/src/linux/mod.rs +++ b/src/linux/mod.rs @@ -495,6 +495,10 @@ impl GeneralReadout for LinuxGeneralReadout { Ok(unsafe { libc::sysconf(libc::_SC_NPROCESSORS_CONF) } as usize) } + fn gpu_model_name(&self) -> Result { + Err(ReadoutError::NotImplemented) + } + fn uptime(&self) -> Result { let mut info = self.sysinfo; let info_ptr: *mut sysinfo = &mut info; diff --git a/src/macos/mod.rs b/src/macos/mod.rs index 3d5f1e3c..4524241e 100644 --- a/src/macos/mod.rs +++ b/src/macos/mod.rs @@ -365,6 +365,10 @@ impl GeneralReadout for MacOSGeneralReadout { shared::cpu_cores() } + fn gpu_model_name(&self) -> Result { + Err(ReadoutError::NotImplemented) + } + fn uptime(&self) -> Result { use libc::timeval; use std::time::{Duration, SystemTime, UNIX_EPOCH}; diff --git a/src/netbsd/mod.rs b/src/netbsd/mod.rs index aa936a60..f3c600bb 100644 --- a/src/netbsd/mod.rs +++ b/src/netbsd/mod.rs @@ -300,6 +300,10 @@ impl GeneralReadout for NetBSDGeneralReadout { shared::cpu_usage() } + fn gpu_model_name(&self) -> Result { + Err(ReadoutError::NotImplemented) + } + fn uptime(&self) -> Result { shared::uptime() } diff --git a/src/openwrt/mod.rs b/src/openwrt/mod.rs index 519c5598..0d2b157d 100644 --- a/src/openwrt/mod.rs +++ b/src/openwrt/mod.rs @@ -194,6 +194,10 @@ impl GeneralReadout for OpenWrtGeneralReadout { } } + fn gpu_model_name(&self) -> Result { + Err(ReadoutError::NotImplemented) + } + fn uptime(&self) -> Result { let mut info = self.sysinfo; let info_ptr: *mut sysinfo = &mut info; diff --git a/src/traits.rs b/src/traits.rs index 44704890..c8310319 100644 --- a/src/traits.rs +++ b/src/traits.rs @@ -564,6 +564,9 @@ pub trait GeneralReadout { /// This function should return the number of logical cores of the host's processor. fn cpu_cores(&self) -> Result; + /// This function should return the model name of the GPU. + fn gpu_model_name(&self) -> Result; + /// This function should return the uptime of the OS in seconds. fn uptime(&self) -> Result; diff --git a/src/windows/mod.rs b/src/windows/mod.rs index 8256600e..b0a080c6 100644 --- a/src/windows/mod.rs +++ b/src/windows/mod.rs @@ -292,6 +292,140 @@ impl GeneralReadout for WindowsGeneralReadout { Err(ReadoutError::NotImplemented) } + fn gpu_model_name(&self) -> Result { + // Sources: + // https://github.com/Carterpersall/OxiFetch/blob/main/src/main.rs#L360 + // https://github.com/lptstr/winfetch/pull/155 + + // Create the Vector to store each GPU's name. + let mut output: Vec = Vec::new(); + + let hklm = RegKey::predef(HKEY_LOCAL_MACHINE); + + // Open the location where some DirectX information is stored + match hklm.open_subkey("SOFTWARE\\Microsoft\\DirectX\\") { + Ok(dx_key) => { + // Get the parent key's LastSeen value + match dx_key.get_value::("LastSeen") { + Ok(lastseen) => { + // Iterate over the parent key's subkeys and find the ones with the same LastSeen value + for key in dx_key.enum_keys() { + if key.is_err() { + continue; + } + let key = key.unwrap(); + + let sublastseen = match dx_key.open_subkey(&key).unwrap().get_value::("LastSeen") { + Ok(key) => key, + Err(_) => continue, + }; + + if sublastseen == lastseen { + // Get the GPU's name + let name = match dx_key.open_subkey(&key).unwrap().get_value::("Description") { + Ok(key) => key, + Err(_) => continue, + }; + + // Exclude the Microsoft Basic Render Driver + if name == "Microsoft Basic Render Driver" { + continue; + } + + // Add the GPU's name to the output vector + output.push(name); + } + } + }, + Err(_) => {}, //Failed to get parent key's LastSeen value. + }; + }, + Err(_) => {}, //Failed to open the DirectX key + }; + + // Some systems have a DirectX key that lacks the LastSeen value, so a backup method is needed. + if output.len() != 0 { + return Ok(output.join(", ")) + } + + // Alternative Method 1: Get GPUs from Device Manager's Registry Keys + match hklm.open_subkey("SYSTEM\\CurrentControlSet\\Enum\\PCI\\") { + Ok(pci_key) => { + for key in pci_key.enum_keys() { + if key.is_err() { + continue; + } + let key = key.unwrap(); + + let subkey = match pci_key.open_subkey(&key) { + Ok(key) => key, + Err(_) => continue, + }; + + for subkey_name in subkey.enum_keys() { + if subkey_name.is_err() { + continue; + } + let subkey_name = subkey_name.unwrap(); + + let device = match subkey.open_subkey(&subkey_name) { + Ok(key) => key, + Err(_) => continue, + }; + + let name = match device.get_value::("DeviceDesc") { + Ok(key) => key.split(";").last().unwrap().to_string(), + Err(_) => continue, + }; + + // Find the GPU using a manual list of names + if [ + "NVIDIA GeForce", "NVIDIA Quadro", "NVIDIA Tesla", "NVIDIA Titan", "NVIDIA GRID", + "Radeon", + "Intel(R) UHD", "Intel(R) HD", "Intel(R) Iris", "Intel(R) Arc" + ].iter().any(|&x| name.contains(x)) { + // Add the GPU's name to the output vector + output.push(name); + } else { + println!("Unknown GPU: {}", name); + } + } + } + }, + Err(_) => {}, //Failed to open the PCI key + }; + + if output.len() != 0 { + return Ok(output.join(", ")) + } + + // Alternative Method 2: Use WMI to query Win32_VideoController + + // Create a WMI connection + let com_con = match COMLibrary::new() { + Ok(con) => con, + // If os_name runs first, COMLibrary will already be initialized + Err(_) => unsafe { COMLibrary::assume_initialized() }, + }; + let wmi_con = WMIConnection::new(com_con)?; + + // Query the WMI connection + let results: Vec> = wmi_con.raw_query("SELECT Name FROM Win32_VideoController")?; + + // Get each GPU's name + for result in results { + if let Some(Variant::String(gpu)) = result.get("Name") { + output.push(gpu.to_string()); + } + } + + if output.len() != 0 { + return Ok(output.join(", ")) + } + + Err(ReadoutError::Other("Failed to find any GPUs.".to_string())) + } + fn uptime(&self) -> Result { let tick_count = unsafe { GetTickCount64() }; let duration = std::time::Duration::from_millis(tick_count); @@ -310,7 +444,11 @@ impl GeneralReadout for WindowsGeneralReadout { } fn os_name(&self) -> Result { - let com_con = COMLibrary::new()?; + let com_con = match COMLibrary::new() { + Ok(con) => con, + // If gpu_model_name runs first, COMLibrary will already be initialized + Err(_) => unsafe { COMLibrary::assume_initialized() }, + }; let wmi_con = WMIConnection::new(com_con)?; let results: Vec> = From e3a8c4f4b3f54eb7d633bc961792a34270b9dc3c Mon Sep 17 00:00:00 2001 From: Carterpersall Date: Sat, 18 Mar 2023 15:06:05 -0500 Subject: [PATCH 02/11] Resolve Conflict --- src/windows/mod.rs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/windows/mod.rs b/src/windows/mod.rs index b0a080c6..e59b4e99 100644 --- a/src/windows/mod.rs +++ b/src/windows/mod.rs @@ -444,11 +444,7 @@ impl GeneralReadout for WindowsGeneralReadout { } fn os_name(&self) -> Result { - let com_con = match COMLibrary::new() { - Ok(con) => con, - // If gpu_model_name runs first, COMLibrary will already be initialized - Err(_) => unsafe { COMLibrary::assume_initialized() }, - }; + let com_con = COMLibrary::new()?; let wmi_con = WMIConnection::new(com_con)?; let results: Vec> = From 841be957f6d004c723cc0a9dcb45eea81bed64bf Mon Sep 17 00:00:00 2001 From: Carterpersall Date: Sat, 18 Mar 2023 15:10:40 -0500 Subject: [PATCH 03/11] Make compatible with #143 --- src/windows/mod.rs | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/windows/mod.rs b/src/windows/mod.rs index 47a6e446..dc680493 100644 --- a/src/windows/mod.rs +++ b/src/windows/mod.rs @@ -412,12 +412,7 @@ impl GeneralReadout for WindowsGeneralReadout { // Alternative Method 2: Use WMI to query Win32_VideoController // Create a WMI connection - let com_con = match COMLibrary::new() { - Ok(con) => con, - // If os_name runs first, COMLibrary will already be initialized - Err(_) => unsafe { COMLibrary::assume_initialized() }, - }; - let wmi_con = WMIConnection::new(com_con)?; + let wmi_con = wmi_connection()?; // Query the WMI connection let results: Vec> = wmi_con.raw_query("SELECT Name FROM Win32_VideoController")?; From 87b31e9aea256b0044eaccee2158b87b1d94a971 Mon Sep 17 00:00:00 2001 From: Carterpersall Date: Mon, 20 Mar 2023 14:10:01 -0500 Subject: [PATCH 04/11] Make compatible with #140 --- src/android/mod.rs | 4 --- src/freebsd/mod.rs | 4 --- src/linux/mod.rs | 4 --- src/macos/mod.rs | 4 --- src/netbsd/mod.rs | 4 --- src/openwrt/mod.rs | 4 --- src/traits.rs | 3 -- src/windows/mod.rs | 90 ++++++++++++++++++++++------------------------ 8 files changed, 43 insertions(+), 74 deletions(-) diff --git a/src/android/mod.rs b/src/android/mod.rs index 49c1167a..7a4d6090 100644 --- a/src/android/mod.rs +++ b/src/android/mod.rs @@ -264,10 +264,6 @@ impl GeneralReadout for AndroidGeneralReadout { } } - fn gpu_model_name(&self) -> Result { - Err(ReadoutError::NotImplemented) - } - fn uptime(&self) -> Result { let mut info = self.sysinfo; let info_ptr: *mut sysinfo = &mut info; diff --git a/src/freebsd/mod.rs b/src/freebsd/mod.rs index f1fe2e70..724e2ef6 100644 --- a/src/freebsd/mod.rs +++ b/src/freebsd/mod.rs @@ -257,10 +257,6 @@ impl GeneralReadout for FreeBSDGeneralReadout { shared::cpu_usage() } - fn gpu_model_name(&self) -> Result { - Err(ReadoutError::NotImplemented) - } - fn uptime(&self) -> Result { let ctl = match sysctl::Ctl::new("kern.boottime") { Ok(ctl) => ctl, diff --git a/src/linux/mod.rs b/src/linux/mod.rs index df84bac0..3a195523 100644 --- a/src/linux/mod.rs +++ b/src/linux/mod.rs @@ -498,10 +498,6 @@ impl GeneralReadout for LinuxGeneralReadout { Ok(unsafe { libc::sysconf(libc::_SC_NPROCESSORS_CONF) } as usize) } - fn gpu_model_name(&self) -> Result { - Err(ReadoutError::NotImplemented) - } - fn uptime(&self) -> Result { let mut info = self.sysinfo; let info_ptr: *mut sysinfo = &mut info; diff --git a/src/macos/mod.rs b/src/macos/mod.rs index bf3cf834..c9114880 100644 --- a/src/macos/mod.rs +++ b/src/macos/mod.rs @@ -365,10 +365,6 @@ impl GeneralReadout for MacOSGeneralReadout { shared::cpu_cores() } - fn gpu_model_name(&self) -> Result { - Err(ReadoutError::NotImplemented) - } - fn uptime(&self) -> Result { use libc::timeval; use std::time::{Duration, SystemTime, UNIX_EPOCH}; diff --git a/src/netbsd/mod.rs b/src/netbsd/mod.rs index 8e598ae8..4d100597 100644 --- a/src/netbsd/mod.rs +++ b/src/netbsd/mod.rs @@ -296,10 +296,6 @@ impl GeneralReadout for NetBSDGeneralReadout { shared::cpu_usage() } - fn gpu_model_name(&self) -> Result { - Err(ReadoutError::NotImplemented) - } - fn uptime(&self) -> Result { shared::uptime() } diff --git a/src/openwrt/mod.rs b/src/openwrt/mod.rs index f554a08e..c9183ee8 100644 --- a/src/openwrt/mod.rs +++ b/src/openwrt/mod.rs @@ -194,10 +194,6 @@ impl GeneralReadout for OpenWrtGeneralReadout { } } - fn gpu_model_name(&self) -> Result { - Err(ReadoutError::NotImplemented) - } - fn uptime(&self) -> Result { let mut info = self.sysinfo; let info_ptr: *mut sysinfo = &mut info; diff --git a/src/traits.rs b/src/traits.rs index eb081cd2..a39d6382 100644 --- a/src/traits.rs +++ b/src/traits.rs @@ -569,9 +569,6 @@ pub trait GeneralReadout { /// This function should return the number of logical cores of the host's processor. fn cpu_cores(&self) -> Result; - /// This function should return the model name of the GPU. - fn gpu_model_name(&self) -> Result; - /// This function should return the uptime of the OS in seconds. fn uptime(&self) -> Result; diff --git a/src/windows/mod.rs b/src/windows/mod.rs index e46b60ce..7e22a623 100644 --- a/src/windows/mod.rs +++ b/src/windows/mod.rs @@ -302,7 +302,47 @@ impl GeneralReadout for WindowsGeneralReadout { Err(ReadoutError::NotImplemented) } - fn gpu_model_name(&self) -> Result { + fn uptime(&self) -> Result { + let tick_count = unsafe { GetTickCount64() }; + let duration = std::time::Duration::from_millis(tick_count); + + Ok(duration.as_secs() as usize) + } + + fn machine(&self) -> Result { + let product_readout = WindowsProductReadout::new(); + + Ok(format!( + "{} {}", + product_readout.vendor()?, + product_readout.product()? + )) + } + + fn os_name(&self) -> Result { + let wmi_con = wmi_connection()?; + + let results: Vec> = + wmi_con.raw_query("SELECT Caption FROM Win32_OperatingSystem")?; + + if let Some(os) = results.first() { + if let Some(Variant::String(caption)) = os.get("Caption") { + return Ok(caption.to_string()); + } + } + + Err(ReadoutError::Other( + "Trying to get the operating system name \ + from WMI failed" + .to_string(), + )) + } + + fn disk_space(&self) -> Result<(u128, u128), ReadoutError> { + Err(ReadoutError::NotImplemented) + } + + fn gpus(&self) -> Result, ReadoutError> { // Sources: // https://github.com/Carterpersall/OxiFetch/blob/main/src/main.rs#L360 // https://github.com/lptstr/winfetch/pull/155 @@ -406,7 +446,7 @@ impl GeneralReadout for WindowsGeneralReadout { }; if output.len() != 0 { - return Ok(output.join(", ")) + return Ok(output) } // Alternative Method 2: Use WMI to query Win32_VideoController @@ -425,55 +465,11 @@ impl GeneralReadout for WindowsGeneralReadout { } if output.len() != 0 { - return Ok(output.join(", ")) + return Ok(output); } Err(ReadoutError::Other("Failed to find any GPUs.".to_string())) } - - fn uptime(&self) -> Result { - let tick_count = unsafe { GetTickCount64() }; - let duration = std::time::Duration::from_millis(tick_count); - - Ok(duration.as_secs() as usize) - } - - fn machine(&self) -> Result { - let product_readout = WindowsProductReadout::new(); - - Ok(format!( - "{} {}", - product_readout.vendor()?, - product_readout.product()? - )) - } - - fn os_name(&self) -> Result { - let wmi_con = wmi_connection()?; - - let results: Vec> = - wmi_con.raw_query("SELECT Caption FROM Win32_OperatingSystem")?; - - if let Some(os) = results.first() { - if let Some(Variant::String(caption)) = os.get("Caption") { - return Ok(caption.to_string()); - } - } - - Err(ReadoutError::Other( - "Trying to get the operating system name \ - from WMI failed" - .to_string(), - )) - } - - fn disk_space(&self) -> Result<(u128, u128), ReadoutError> { - Err(ReadoutError::NotImplemented) - } - - fn gpus(&self) -> Result, ReadoutError> { - Err(ReadoutError::NotImplemented) - } } pub struct WindowsProductReadout { From 26b2e36610c6113bdeac27c404ccb85488542bfa Mon Sep 17 00:00:00 2001 From: Carterpersall Date: Mon, 20 Mar 2023 14:31:39 -0500 Subject: [PATCH 05/11] Fix error, fmt, and clippy --- src/windows/mod.rs | 154 ++++++++++++++++++++++----------------------- 1 file changed, 77 insertions(+), 77 deletions(-) diff --git a/src/windows/mod.rs b/src/windows/mod.rs index 7e22a623..929e67bf 100644 --- a/src/windows/mod.rs +++ b/src/windows/mod.rs @@ -353,100 +353,99 @@ impl GeneralReadout for WindowsGeneralReadout { let hklm = RegKey::predef(HKEY_LOCAL_MACHINE); // Open the location where some DirectX information is stored - match hklm.open_subkey("SOFTWARE\\Microsoft\\DirectX\\") { - Ok(dx_key) => { - // Get the parent key's LastSeen value - match dx_key.get_value::("LastSeen") { - Ok(lastseen) => { - // Iterate over the parent key's subkeys and find the ones with the same LastSeen value - for key in dx_key.enum_keys() { - if key.is_err() { - continue; - } - let key = key.unwrap(); - - let sublastseen = match dx_key.open_subkey(&key).unwrap().get_value::("LastSeen") { - Ok(key) => key, - Err(_) => continue, - }; - - if sublastseen == lastseen { - // Get the GPU's name - let name = match dx_key.open_subkey(&key).unwrap().get_value::("Description") { - Ok(key) => key, - Err(_) => continue, - }; - - // Exclude the Microsoft Basic Render Driver - if name == "Microsoft Basic Render Driver" { - continue; - } - - // Add the GPU's name to the output vector - output.push(name); - } + if let Ok(dx_key) = hklm.open_subkey("SOFTWARE\\Microsoft\\DirectX\\") { + // Get the parent key's LastSeen value + if let Ok(lastseen) = dx_key.get_value::("LastSeen") { + // Iterate over the parent key's subkeys and find the ones with the same LastSeen value + for key in dx_key.enum_keys() { + if key.is_err() { + continue; + } + let key = key.unwrap(); + + let sublastseen = match dx_key + .open_subkey(&key) + .unwrap() + .get_value::("LastSeen") + { + Ok(key) => key, + Err(_) => continue, + }; + + if sublastseen == lastseen { + // Get the GPU's name + let name = match dx_key + .open_subkey(&key) + .unwrap() + .get_value::("Description") + { + Ok(key) => key, + Err(_) => continue, + }; + + // Exclude the Microsoft Basic Render Driver + if name == "Microsoft Basic Render Driver" { + continue; } - }, - Err(_) => {}, //Failed to get parent key's LastSeen value. - }; - }, - Err(_) => {}, //Failed to open the DirectX key + + // Add the GPU's name to the output vector + output.push(name); + } + } + }; }; // Some systems have a DirectX key that lacks the LastSeen value, so a backup method is needed. - if output.len() != 0 { - return Ok(output.join(", ")) + if !output.is_empty() { + return Ok(output); } // Alternative Method 1: Get GPUs from Device Manager's Registry Keys - match hklm.open_subkey("SYSTEM\\CurrentControlSet\\Enum\\PCI\\") { - Ok(pci_key) => { - for key in pci_key.enum_keys() { - if key.is_err() { + if let Ok(pci_key) = hklm.open_subkey("SYSTEM\\CurrentControlSet\\Enum\\PCI\\") { + for key in pci_key.enum_keys() { + if key.is_err() { + continue; + } + let key = key.unwrap(); + + let subkey = match pci_key.open_subkey(&key) { + Ok(key) => key, + Err(_) => continue, + }; + + for subkey_name in subkey.enum_keys() { + if subkey_name.is_err() { continue; } - let key = key.unwrap(); + let subkey_name = subkey_name.unwrap(); - let subkey = match pci_key.open_subkey(&key) { + let device = match subkey.open_subkey(&subkey_name) { Ok(key) => key, Err(_) => continue, }; - for subkey_name in subkey.enum_keys() { - if subkey_name.is_err() { - continue; - } - let subkey_name = subkey_name.unwrap(); - - let device = match subkey.open_subkey(&subkey_name) { - Ok(key) => key, - Err(_) => continue, - }; - - let name = match device.get_value::("DeviceDesc") { - Ok(key) => key.split(";").last().unwrap().to_string(), - Err(_) => continue, - }; + let name = match device.get_value::("DeviceDesc") { + Ok(key) => key.split(';').last().unwrap().to_string(), + Err(_) => continue, + }; - // Find the GPU using a manual list of names - if [ - "NVIDIA GeForce", "NVIDIA Quadro", "NVIDIA Tesla", "NVIDIA Titan", "NVIDIA GRID", - "Radeon", - "Intel(R) UHD", "Intel(R) HD", "Intel(R) Iris", "Intel(R) Arc" - ].iter().any(|&x| name.contains(x)) { - // Add the GPU's name to the output vector - output.push(name); - } else { - println!("Unknown GPU: {}", name); - } + // Find the GPU using a manual list of names + if [ + "NVIDIA GeForce", "NVIDIA Quadro", "NVIDIA Tesla", "NVIDIA Titan", "NVIDIA GRID", + "Radeon", + "Intel(R) UHD", "Intel(R) HD", "Intel(R) Iris", "Intel(R) Arc" + ] + .iter() + .any(|&x| name.contains(x)) { + // Add the GPU's name to the output vector + output.push(name); } } - }, - Err(_) => {}, //Failed to open the PCI key + } }; - if output.len() != 0 { - return Ok(output) + if !output.is_empty() { + return Ok(output); } // Alternative Method 2: Use WMI to query Win32_VideoController @@ -455,7 +454,8 @@ impl GeneralReadout for WindowsGeneralReadout { let wmi_con = wmi_connection()?; // Query the WMI connection - let results: Vec> = wmi_con.raw_query("SELECT Name FROM Win32_VideoController")?; + let results: Vec> = + wmi_con.raw_query("SELECT Name FROM Win32_VideoController")?; // Get each GPU's name for result in results { @@ -464,7 +464,7 @@ impl GeneralReadout for WindowsGeneralReadout { } } - if output.len() != 0 { + if !output.is_empty() { return Ok(output); } From dd72da3caa5ac872ead1545c4aa7c2978e01513b Mon Sep 17 00:00:00 2001 From: Carterpersall Date: Wed, 22 Mar 2023 16:59:03 -0500 Subject: [PATCH 06/11] Replace Alternative Implementation 1 --- Cargo.toml | 5 ++- src/windows/mod.rs | 88 ++++++++++++++++++++++------------------------ 2 files changed, 47 insertions(+), 46 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 4d6e419c..576682d0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -47,9 +47,12 @@ wmi = "0.12.0" winreg = "0.10.1" windows = { version = "0.39.0", features = [ "Win32_Foundation", + "Win32_Graphics_Gdi", "Win32_System_Power", "Win32_System_SystemInformation", - "Win32_System_WindowsProgramming" + "Win32_System_WindowsProgramming", + "Win32_UI_HiDpi", + "Win32_UI_WindowsAndMessaging", ]} [target.'cfg(not(target_os = "windows"))'.dependencies] diff --git a/src/windows/mod.rs b/src/windows/mod.rs index 929e67bf..74450f32 100644 --- a/src/windows/mod.rs +++ b/src/windows/mod.rs @@ -1,5 +1,5 @@ use crate::traits::*; -use std::collections::HashMap; +use std::collections::{HashMap, HashSet}; use std::path::PathBuf; use winreg::enums::*; use winreg::RegKey; @@ -7,13 +7,19 @@ use wmi::WMIResult; use wmi::{COMLibrary, Variant, WMIConnection}; use windows::{ - core::PSTR, Win32::System::Power::GetSystemPowerStatus, + core::{PSTR, PCWSTR}, + Win32::Graphics::Gdi::{ + EnumDisplayDevicesW, + DISPLAY_DEVICEW, + }, + Win32::System::Power::GetSystemPowerStatus, Win32::System::Power::SYSTEM_POWER_STATUS, Win32::System::SystemInformation::GetComputerNameExA, Win32::System::SystemInformation::GetTickCount64, Win32::System::SystemInformation::GlobalMemoryStatusEx, Win32::System::SystemInformation::MEMORYSTATUSEX, Win32::System::WindowsProgramming::GetUserNameA, + Win32::UI::WindowsAndMessaging::EDD_GET_DEVICE_INTERFACE_NAME, }; impl From for ReadoutError { @@ -400,52 +406,44 @@ impl GeneralReadout for WindowsGeneralReadout { return Ok(output); } - // Alternative Method 1: Get GPUs from Device Manager's Registry Keys - if let Ok(pci_key) = hklm.open_subkey("SYSTEM\\CurrentControlSet\\Enum\\PCI\\") { - for key in pci_key.enum_keys() { - if key.is_err() { - continue; - } - let key = key.unwrap(); - - let subkey = match pci_key.open_subkey(&key) { - Ok(key) => key, - Err(_) => continue, - }; - - for subkey_name in subkey.enum_keys() { - if subkey_name.is_err() { - continue; - } - let subkey_name = subkey_name.unwrap(); - - let device = match subkey.open_subkey(&subkey_name) { - Ok(key) => key, - Err(_) => continue, - }; - - let name = match device.get_value::("DeviceDesc") { - Ok(key) => key.split(';').last().unwrap().to_string(), - Err(_) => continue, - }; - - // Find the GPU using a manual list of names - if [ - "NVIDIA GeForce", "NVIDIA Quadro", "NVIDIA Tesla", "NVIDIA Titan", "NVIDIA GRID", - "Radeon", - "Intel(R) UHD", "Intel(R) HD", "Intel(R) Iris", "Intel(R) Arc" - ] - .iter() - .any(|&x| name.contains(x)) { - // Add the GPU's name to the output vector - output.push(name); - } + // Alternative Method 1: Get GPUs by getting every display device + let mut devices = Vec::new(); + let mut index = 0; + let mut status = true; + // Iterate over EnumDisplayDevicesW until it returns false + while status { + devices.push(DISPLAY_DEVICEW::default()); + devices[index].cb = std::mem::size_of::() as u32; + unsafe { + status = EnumDisplayDevicesW( + PCWSTR::null(), + index as u32, + &mut devices[index], + EDD_GET_DEVICE_INTERFACE_NAME, + ).as_bool(); + }; + index += 1; + } + // Remove the last element, which will be invalid + devices.pop(); + + // Create a hashset to store the GPU names, which will prevent duplicates + let mut gpus: HashSet = HashSet::new(); + + // Iterate over each device + for device in devices { + // Convert [u16; 128] to a String and add to the HashSet + match String::from_utf16(&device.DeviceString) { + Ok(gpu) => { + gpus.insert(gpu.trim_matches(char::from(0)).to_string()); } + Err(_) => continue, } - }; + } - if !output.is_empty() { - return Ok(output); + if !gpus.is_empty() { + // Convert the HashSet to a Vec and return it + return Ok(gpus.into_iter().collect()); } // Alternative Method 2: Use WMI to query Win32_VideoController From 58a99a49e9f79104fa58a81b1e44943f38262a1d Mon Sep 17 00:00:00 2001 From: Carterpersall Date: Fri, 24 Mar 2023 11:08:04 -0500 Subject: [PATCH 07/11] Add yet another implementation --- Cargo.toml | 1 + src/windows/mod.rs | 117 ++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 116 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 576682d0..e57d4d35 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -48,6 +48,7 @@ winreg = "0.10.1" windows = { version = "0.39.0", features = [ "Win32_Foundation", "Win32_Graphics_Gdi", + "Win32_Graphics_Dxgi", "Win32_System_Power", "Win32_System_SystemInformation", "Win32_System_WindowsProgramming", diff --git a/src/windows/mod.rs b/src/windows/mod.rs index 74450f32..aa65a15f 100644 --- a/src/windows/mod.rs +++ b/src/windows/mod.rs @@ -12,6 +12,10 @@ use windows::{ EnumDisplayDevicesW, DISPLAY_DEVICEW, }, + Win32::Graphics::Dxgi::{ + CreateDXGIFactory, + IDXGIFactory + }, Win32::System::Power::GetSystemPowerStatus, Win32::System::Power::SYSTEM_POWER_STATUS, Win32::System::SystemInformation::GetComputerNameExA, @@ -406,7 +410,9 @@ impl GeneralReadout for WindowsGeneralReadout { return Ok(output); } - // Alternative Method 1: Get GPUs by getting every display device + + // Backup Implementation 1: Get GPUs by getting every display device + let mut devices = Vec::new(); let mut index = 0; let mut status = true; @@ -446,7 +452,114 @@ impl GeneralReadout for WindowsGeneralReadout { return Ok(gpus.into_iter().collect()); } - // Alternative Method 2: Use WMI to query Win32_VideoController + + // Backup Implementation 2: Get GPUs using DXGI + // Sources: + // https://github.com/SHAREVOX/sharevox_core/blob/297c6c75ea9c6a88ee9002a7848592f7a97b4f9a/crates/voicevox_core/src/publish.rs#L529 + // https://github.com/LinusDierheimer/fastfetch/blob/b3da6b0e89c0decb9ea648e1d98a75fa6ac40225/src/detection/gpu/gpu_windows.cpp#L91 + + // Create a DXGI Factory + let mut factory = unsafe {CreateDXGIFactory::()}; + + if factory.is_ok() { + // Get the GPU names + let mut index = 0; + loop { + // Get the adapter at the current index + let adapter = unsafe { factory.as_mut().unwrap().EnumAdapters(index) }; + if adapter.is_err() { break } + + // Get the adapter's information + let adapter_info = unsafe { adapter.unwrap().GetDesc() }; + if adapter_info.is_err() { break } + + // Get the name of the video adapter + + if let Ok(description) = String::from_utf16(&adapter_info.clone().unwrap().Description) { + if description.contains("Microsoft Basic Render Driver") { + index += 1; + continue; + } + + // GPU Video Memory + let dedicated_video_memory = adapter_info.clone().unwrap().DedicatedVideoMemory; + // System RAM not available to the CPU + let dedicated_system_memory = adapter_info.clone().unwrap().DedicatedSystemMemory; + // System RAM available to both the CPU and GPU + let shared_system_memory = adapter_info.unwrap().SharedSystemMemory; + + // Convert bytes to a human-readable string + fn bytes_to_string(value: usize) -> String { + if value / (1024 * 1024 * 1024) > 0 { + return format!( + "{} GB", + ((value * 100) / (1024 * 1024 * 1024)) as f64 / 100.0, + ); + } else if value / (1024 * 1024) > 0 { + return format!( + "{} MB", + ((value * 100) / (1024 * 1024)) as f64 / 100.0, + ); + } else if value / 1024 > 0 { + return format!( + "{} KB", + ((value * 100) / 1024) as f64 / 100.0, + ); + } + return "".to_string(); + } + + let memory = match (dedicated_video_memory, dedicated_system_memory, shared_system_memory) { + (0, 0, 0) => "".to_string(), + (0, 0, _) => format!( + " ({} Shared)", + bytes_to_string(shared_system_memory) + ), + (0, _, 0) => format!( + " ({} Dedicated)", + bytes_to_string(dedicated_system_memory) + ), + (0, _, _) => format!( + " ({} Dedicated, {} Shared)", + bytes_to_string(dedicated_system_memory), + bytes_to_string(shared_system_memory) + ), + (_, 0, 0) => format!( + " ({} Dedicated)", + bytes_to_string(dedicated_video_memory) + ), + (_, 0, _) => format!( + " ({} Dedicated, {} Shared)", + bytes_to_string(dedicated_video_memory), + bytes_to_string(shared_system_memory) + ), + (_, _, 0) => format!( + " ({} Dedicated, {} Dedicated)", + bytes_to_string(dedicated_video_memory), + bytes_to_string(dedicated_system_memory) + ), + (_, _, _) => format!( + " ({} Dedicated, {} Shared)", + bytes_to_string(dedicated_video_memory + dedicated_system_memory), + bytes_to_string(shared_system_memory) + ), + }; + + + output.push(format!("{}{}", description.trim_end_matches('\0'), memory)); + } + + index += 1; + } + } + + if !output.is_empty() { + return Ok(output); + } + + + + // Backup Implementation 3: Use WMI to query Win32_VideoController // Create a WMI connection let wmi_con = wmi_connection()?; From ffd3f9301eefde76ced397c57a9489ba9e60a430 Mon Sep 17 00:00:00 2001 From: Carterpersall Date: Fri, 24 Mar 2023 11:29:46 -0500 Subject: [PATCH 08/11] fmt, clippy, and eliminate some unwraps --- src/windows/mod.rs | 106 +++++++++++++++++++++------------------------ 1 file changed, 49 insertions(+), 57 deletions(-) diff --git a/src/windows/mod.rs b/src/windows/mod.rs index aa65a15f..7e38e588 100644 --- a/src/windows/mod.rs +++ b/src/windows/mod.rs @@ -7,15 +7,9 @@ use wmi::WMIResult; use wmi::{COMLibrary, Variant, WMIConnection}; use windows::{ - core::{PSTR, PCWSTR}, - Win32::Graphics::Gdi::{ - EnumDisplayDevicesW, - DISPLAY_DEVICEW, - }, - Win32::Graphics::Dxgi::{ - CreateDXGIFactory, - IDXGIFactory - }, + core::{PCWSTR, PSTR}, + Win32::Graphics::Dxgi::{CreateDXGIFactory, IDXGIFactory}, + Win32::Graphics::Gdi::{EnumDisplayDevicesW, DISPLAY_DEVICEW}, Win32::System::Power::GetSystemPowerStatus, Win32::System::Power::SYSTEM_POWER_STATUS, Win32::System::SystemInformation::GetComputerNameExA, @@ -375,24 +369,25 @@ impl GeneralReadout for WindowsGeneralReadout { let sublastseen = match dx_key .open_subkey(&key) - .unwrap() - .get_value::("LastSeen") { - Ok(key) => key, + Ok(key) => match key.get_value::("LastSeen") { + Ok(key) => key, + Err(_) => continue, + }, Err(_) => continue, }; if sublastseen == lastseen { // Get the GPU's name - let name = match dx_key - .open_subkey(&key) - .unwrap() - .get_value::("Description") - { - Ok(key) => key, + let name = match dx_key.open_subkey(&key) { + Ok(key) => match key.get_value::("Description") { + Ok(key) => key, + Err(_) => continue, + }, Err(_) => continue, }; + // Exclude the Microsoft Basic Render Driver if name == "Microsoft Basic Render Driver" { continue; @@ -410,7 +405,6 @@ impl GeneralReadout for WindowsGeneralReadout { return Ok(output); } - // Backup Implementation 1: Get GPUs by getting every display device let mut devices = Vec::new(); @@ -426,7 +420,8 @@ impl GeneralReadout for WindowsGeneralReadout { index as u32, &mut devices[index], EDD_GET_DEVICE_INTERFACE_NAME, - ).as_bool(); + ) + .as_bool(); }; index += 1; } @@ -452,82 +447,82 @@ impl GeneralReadout for WindowsGeneralReadout { return Ok(gpus.into_iter().collect()); } - // Backup Implementation 2: Get GPUs using DXGI // Sources: // https://github.com/SHAREVOX/sharevox_core/blob/297c6c75ea9c6a88ee9002a7848592f7a97b4f9a/crates/voicevox_core/src/publish.rs#L529 // https://github.com/LinusDierheimer/fastfetch/blob/b3da6b0e89c0decb9ea648e1d98a75fa6ac40225/src/detection/gpu/gpu_windows.cpp#L91 // Create a DXGI Factory - let mut factory = unsafe {CreateDXGIFactory::()}; + let mut factory = unsafe { CreateDXGIFactory::() }; if factory.is_ok() { // Get the GPU names let mut index = 0; loop { // Get the adapter at the current index - let adapter = unsafe { factory.as_mut().unwrap().EnumAdapters(index) }; - if adapter.is_err() { break } + let adapter = match unsafe { factory.as_mut().unwrap().EnumAdapters(index) }{ + Ok(adapter) => adapter, + Err(_) => break, + }; // Get the adapter's information - let adapter_info = unsafe { adapter.unwrap().GetDesc() }; - if adapter_info.is_err() { break } + let adapter_info = match unsafe { adapter.GetDesc() } { + Ok(info) => info, + Err(_) => break, + }; // Get the name of the video adapter - if let Ok(description) = String::from_utf16(&adapter_info.clone().unwrap().Description) { + if let Ok(description) = + String::from_utf16(&adapter_info.Description) + { if description.contains("Microsoft Basic Render Driver") { index += 1; continue; } // GPU Video Memory - let dedicated_video_memory = adapter_info.clone().unwrap().DedicatedVideoMemory; + let dedicated_video_memory = adapter_info.DedicatedVideoMemory; // System RAM not available to the CPU - let dedicated_system_memory = adapter_info.clone().unwrap().DedicatedSystemMemory; + let dedicated_system_memory = + adapter_info.DedicatedSystemMemory; // System RAM available to both the CPU and GPU - let shared_system_memory = adapter_info.unwrap().SharedSystemMemory; + let shared_system_memory = adapter_info.SharedSystemMemory; // Convert bytes to a human-readable string fn bytes_to_string(value: usize) -> String { if value / (1024 * 1024 * 1024) > 0 { - return format!( + format!( "{} GB", ((value * 100) / (1024 * 1024 * 1024)) as f64 / 100.0, - ); + ) } else if value / (1024 * 1024) > 0 { - return format!( - "{} MB", - ((value * 100) / (1024 * 1024)) as f64 / 100.0, - ); + format!("{} MB", ((value * 100) / (1024 * 1024)) as f64 / 100.0,) } else if value / 1024 > 0 { - return format!( - "{} KB", - ((value * 100) / 1024) as f64 / 100.0, - ); + format!("{} KB", ((value * 100) / 1024) as f64 / 100.0,) + } else { + "".to_string() } - return "".to_string(); } - let memory = match (dedicated_video_memory, dedicated_system_memory, shared_system_memory) { + let memory = match ( + dedicated_video_memory, + dedicated_system_memory, + shared_system_memory, + ) { (0, 0, 0) => "".to_string(), - (0, 0, _) => format!( - " ({} Shared)", - bytes_to_string(shared_system_memory) - ), - (0, _, 0) => format!( - " ({} Dedicated)", - bytes_to_string(dedicated_system_memory) - ), + (0, 0, _) => format!(" ({} Shared)", bytes_to_string(shared_system_memory)), + (0, _, 0) => { + format!(" ({} Dedicated)", bytes_to_string(dedicated_system_memory)) + } (0, _, _) => format!( " ({} Dedicated, {} Shared)", bytes_to_string(dedicated_system_memory), bytes_to_string(shared_system_memory) ), - (_, 0, 0) => format!( - " ({} Dedicated)", - bytes_to_string(dedicated_video_memory) - ), + (_, 0, 0) => { + format!(" ({} Dedicated)", bytes_to_string(dedicated_video_memory)) + } (_, 0, _) => format!( " ({} Dedicated, {} Shared)", bytes_to_string(dedicated_video_memory), @@ -545,7 +540,6 @@ impl GeneralReadout for WindowsGeneralReadout { ), }; - output.push(format!("{}{}", description.trim_end_matches('\0'), memory)); } @@ -557,8 +551,6 @@ impl GeneralReadout for WindowsGeneralReadout { return Ok(output); } - - // Backup Implementation 3: Use WMI to query Win32_VideoController // Create a WMI connection From ed532640b462eba460c4965900efce8047ba6c28 Mon Sep 17 00:00:00 2001 From: Carterpersall Date: Fri, 24 Mar 2023 12:58:51 -0500 Subject: [PATCH 09/11] Fix Backup 1 --- src/windows/mod.rs | 37 +++++++++++++++++-------------------- 1 file changed, 17 insertions(+), 20 deletions(-) diff --git a/src/windows/mod.rs b/src/windows/mod.rs index 7e38e588..eeec4b2a 100644 --- a/src/windows/mod.rs +++ b/src/windows/mod.rs @@ -1,5 +1,5 @@ use crate::traits::*; -use std::collections::{HashMap, HashSet}; +use std::collections::HashMap; use std::path::PathBuf; use winreg::enums::*; use winreg::RegKey; @@ -367,9 +367,7 @@ impl GeneralReadout for WindowsGeneralReadout { } let key = key.unwrap(); - let sublastseen = match dx_key - .open_subkey(&key) - { + let sublastseen = match dx_key.open_subkey(&key) { Ok(key) => match key.get_value::("LastSeen") { Ok(key) => key, Err(_) => continue, @@ -387,7 +385,6 @@ impl GeneralReadout for WindowsGeneralReadout { Err(_) => continue, }; - // Exclude the Microsoft Basic Render Driver if name == "Microsoft Basic Render Driver" { continue; @@ -428,23 +425,26 @@ impl GeneralReadout for WindowsGeneralReadout { // Remove the last element, which will be invalid devices.pop(); - // Create a hashset to store the GPU names, which will prevent duplicates - let mut gpus: HashSet = HashSet::new(); - // Iterate over each device for device in devices { // Convert [u16; 128] to a String and add to the HashSet - match String::from_utf16(&device.DeviceString) { - Ok(gpu) => { - gpus.insert(gpu.trim_matches(char::from(0)).to_string()); + match ( + String::from_utf16(&device.DeviceString), + String::from_utf16(&device.DeviceKey), + ) { + (Ok(gpu), Ok(key)) => { + // Check if the key ends with "\0000", which is the first entry for that GPU + if key.trim_matches(char::from(0)).ends_with("\\0000") { + output.push(gpu.trim_matches(char::from(0)).to_string()); + } } - Err(_) => continue, + (_, _) => continue, } } - if !gpus.is_empty() { + if !output.is_empty() { // Convert the HashSet to a Vec and return it - return Ok(gpus.into_iter().collect()); + return Ok(output); } // Backup Implementation 2: Get GPUs using DXGI @@ -460,7 +460,7 @@ impl GeneralReadout for WindowsGeneralReadout { let mut index = 0; loop { // Get the adapter at the current index - let adapter = match unsafe { factory.as_mut().unwrap().EnumAdapters(index) }{ + let adapter = match unsafe { factory.as_mut().unwrap().EnumAdapters(index) } { Ok(adapter) => adapter, Err(_) => break, }; @@ -473,9 +473,7 @@ impl GeneralReadout for WindowsGeneralReadout { // Get the name of the video adapter - if let Ok(description) = - String::from_utf16(&adapter_info.Description) - { + if let Ok(description) = String::from_utf16(&adapter_info.Description) { if description.contains("Microsoft Basic Render Driver") { index += 1; continue; @@ -484,8 +482,7 @@ impl GeneralReadout for WindowsGeneralReadout { // GPU Video Memory let dedicated_video_memory = adapter_info.DedicatedVideoMemory; // System RAM not available to the CPU - let dedicated_system_memory = - adapter_info.DedicatedSystemMemory; + let dedicated_system_memory = adapter_info.DedicatedSystemMemory; // System RAM available to both the CPU and GPU let shared_system_memory = adapter_info.SharedSystemMemory; From f55186a415248f4c52f7ebf60c573c52f911c02a Mon Sep 17 00:00:00 2001 From: Carterpersall Date: Mon, 27 Mar 2023 10:39:16 -0500 Subject: [PATCH 10/11] Add video memory detection to implementation 1 --- src/windows/mod.rs | 146 +++++++++++++++++++++++++++++---------------- 1 file changed, 95 insertions(+), 51 deletions(-) diff --git a/src/windows/mod.rs b/src/windows/mod.rs index eeec4b2a..317798fe 100644 --- a/src/windows/mod.rs +++ b/src/windows/mod.rs @@ -17,7 +17,6 @@ use windows::{ Win32::System::SystemInformation::GlobalMemoryStatusEx, Win32::System::SystemInformation::MEMORYSTATUSEX, Win32::System::WindowsProgramming::GetUserNameA, - Win32::UI::WindowsAndMessaging::EDD_GET_DEVICE_INTERFACE_NAME, }; impl From for ReadoutError { @@ -347,6 +346,67 @@ impl GeneralReadout for WindowsGeneralReadout { } fn gpus(&self) -> Result, ReadoutError> { + // Convert bytes to a string + fn bytes_to_string(value: usize) -> String { + if value / (1024 * 1024 * 1024) > 0 { + // Gigabytes + format!( + "{} GB", + ((value * 100) / (1024 * 1024 * 1024)) as f64 / 100.0, + ) + } else if value / (1024 * 1024) > 0 { + // Megabytes + format!("{} MB", ((value * 100) / (1024 * 1024)) as f64 / 100.0,) + } else if value / 1024 > 0 { + // Kilobytes + format!("{} KB", ((value * 100) / 1024) as f64 / 100.0,) + } else { + "".to_string() + } + } + + // Convert memory values to a human-readable string + fn memory_to_string ( + dedicated_video_memory: usize, + dedicated_system_memory: usize, + shared_system_memory: usize, + ) -> String { + return match ( + dedicated_video_memory, + dedicated_system_memory, + shared_system_memory, + ) { + (0, 0, 0) => "".to_string(), + (0, 0, _) => format!(" ({} Shared)", bytes_to_string(shared_system_memory)), + (0, _, 0) => { + format!(" ({} Dedicated)", bytes_to_string(dedicated_system_memory)) + } + (0, _, _) => format!( + " ({} Dedicated, {} Shared)", + bytes_to_string(dedicated_system_memory), + bytes_to_string(shared_system_memory) + ), + (_, 0, 0) => { + format!(" ({} Dedicated)", bytes_to_string(dedicated_video_memory)) + } + (_, 0, _) => format!( + " ({} Dedicated, {} Shared)", + bytes_to_string(dedicated_video_memory), + bytes_to_string(shared_system_memory) + ), + (_, _, 0) => format!( + " ({} Dedicated, {} Dedicated)", + bytes_to_string(dedicated_video_memory), + bytes_to_string(dedicated_system_memory) + ), + (_, _, _) => format!( + " ({} Dedicated, {} Shared)", + bytes_to_string(dedicated_video_memory + dedicated_system_memory), + bytes_to_string(shared_system_memory) + ), + } + } + // Sources: // https://github.com/Carterpersall/OxiFetch/blob/main/src/main.rs#L360 // https://github.com/lptstr/winfetch/pull/155 @@ -385,19 +445,48 @@ impl GeneralReadout for WindowsGeneralReadout { Err(_) => continue, }; + // Get the GPU's video memory + let dedicated_video_memory = match dx_key.open_subkey(&key) { + Ok(key) => match key.get_value::("DedicatedVideoMemory") { + Ok(key) => key as usize, + Err(_) => continue, + }, + Err(_) => continue, + }; + let dedicated_system_memory = match dx_key.open_subkey(&key) { + Ok(key) => match key.get_value::("DedicatedSystemMemory") { + Ok(key) => key as usize, + Err(_) => continue, + }, + Err(_) => continue, + }; + let shared_system_memory = match dx_key.open_subkey(&key) { + Ok(key) => match key.get_value::("SharedSystemMemory") { + Ok(key) => key as usize, + Err(_) => continue, + }, + Err(_) => continue, + }; + + let memory = memory_to_string( + dedicated_video_memory, + dedicated_system_memory, + shared_system_memory, + ); + // Exclude the Microsoft Basic Render Driver if name == "Microsoft Basic Render Driver" { continue; } // Add the GPU's name to the output vector - output.push(name); + output.push(name + &memory); } } }; }; - // Some systems have a DirectX key that lacks the LastSeen value, so a backup method is needed. + // Some systems have a DirectX key that lacks a LastSeen value, so a backup method is needed. if !output.is_empty() { return Ok(output); } @@ -416,7 +505,7 @@ impl GeneralReadout for WindowsGeneralReadout { PCWSTR::null(), index as u32, &mut devices[index], - EDD_GET_DEVICE_INTERFACE_NAME, + 0, ) .as_bool(); }; @@ -486,56 +575,11 @@ impl GeneralReadout for WindowsGeneralReadout { // System RAM available to both the CPU and GPU let shared_system_memory = adapter_info.SharedSystemMemory; - // Convert bytes to a human-readable string - fn bytes_to_string(value: usize) -> String { - if value / (1024 * 1024 * 1024) > 0 { - format!( - "{} GB", - ((value * 100) / (1024 * 1024 * 1024)) as f64 / 100.0, - ) - } else if value / (1024 * 1024) > 0 { - format!("{} MB", ((value * 100) / (1024 * 1024)) as f64 / 100.0,) - } else if value / 1024 > 0 { - format!("{} KB", ((value * 100) / 1024) as f64 / 100.0,) - } else { - "".to_string() - } - } - - let memory = match ( + let memory = memory_to_string( dedicated_video_memory, dedicated_system_memory, shared_system_memory, - ) { - (0, 0, 0) => "".to_string(), - (0, 0, _) => format!(" ({} Shared)", bytes_to_string(shared_system_memory)), - (0, _, 0) => { - format!(" ({} Dedicated)", bytes_to_string(dedicated_system_memory)) - } - (0, _, _) => format!( - " ({} Dedicated, {} Shared)", - bytes_to_string(dedicated_system_memory), - bytes_to_string(shared_system_memory) - ), - (_, 0, 0) => { - format!(" ({} Dedicated)", bytes_to_string(dedicated_video_memory)) - } - (_, 0, _) => format!( - " ({} Dedicated, {} Shared)", - bytes_to_string(dedicated_video_memory), - bytes_to_string(shared_system_memory) - ), - (_, _, 0) => format!( - " ({} Dedicated, {} Dedicated)", - bytes_to_string(dedicated_video_memory), - bytes_to_string(dedicated_system_memory) - ), - (_, _, _) => format!( - " ({} Dedicated, {} Shared)", - bytes_to_string(dedicated_video_memory + dedicated_system_memory), - bytes_to_string(shared_system_memory) - ), - }; + ); output.push(format!("{}{}", description.trim_end_matches('\0'), memory)); } From f127cac0c66df0e247dc3245bc6ed3504b919249 Mon Sep 17 00:00:00 2001 From: Carterpersall Date: Mon, 27 Mar 2023 10:58:10 -0500 Subject: [PATCH 11/11] fmt and clippy yet again I keep forgetting to run it --- src/windows/mod.rs | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/src/windows/mod.rs b/src/windows/mod.rs index 317798fe..a1a0a77e 100644 --- a/src/windows/mod.rs +++ b/src/windows/mod.rs @@ -366,12 +366,12 @@ impl GeneralReadout for WindowsGeneralReadout { } // Convert memory values to a human-readable string - fn memory_to_string ( + fn memory_to_string( dedicated_video_memory: usize, dedicated_system_memory: usize, shared_system_memory: usize, ) -> String { - return match ( + match ( dedicated_video_memory, dedicated_system_memory, shared_system_memory, @@ -501,13 +501,8 @@ impl GeneralReadout for WindowsGeneralReadout { devices.push(DISPLAY_DEVICEW::default()); devices[index].cb = std::mem::size_of::() as u32; unsafe { - status = EnumDisplayDevicesW( - PCWSTR::null(), - index as u32, - &mut devices[index], - 0, - ) - .as_bool(); + status = EnumDisplayDevicesW(PCWSTR::null(), index as u32, &mut devices[index], 0) + .as_bool(); }; index += 1; }