#![cfg(windows)]
use crate::{DiskInfo, DiskInfoProvider, ProviderError};
use serde::Deserialize;
use wmi::{COMLibrary, WMIConnection};
#[allow(non_camel_case_types)]
#[derive(Deserialize, Debug)]
#[serde(rename_all = "PascalCase")]
struct Win32_DiskDrive {
device_id: String,
model: String,
serial_number: Option<String>,
media_type: Option<String>,
}
pub struct WindowsProvider;
impl DiskInfoProvider for WindowsProvider {
fn get_all_disks() -> Result<Vec<DiskInfo>, ProviderError> {
let com_lib = COMLibrary::new()?;
let wmi_con = WMIConnection::new(com_lib.into())?;
let results: Vec<Win32_DiskDrive> = wmi_con.query()?;
let disks = results
.into_iter()
.map(|dev| {
let serial = dev.serial_number.and_then(|s| {
if s.trim().is_empty() {
None
} else {
Some(s.trim().to_string())
}
});
let model = if dev.model.trim().is_empty() {
None
} else {
Some(dev.model.trim().to_string())
};
let removable = dev.media_type.and_then(|s| {
if s.trim().is_empty() {
None
} else {
let s_lower = s.to_lowercase();
Some(
s_lower.contains("removable media")
|| s_lower.contains("external hard disk media"),
)
}
});
DiskInfo {
name: dev.device_id.trim().to_string(),
model: model,
serial_number: serial,
removable,
}
})
.collect();
Ok(disks)
}
}