rs_drivelist/
lib.rs

1#[allow(non_snake_case)]
2#[allow(non_snake_case)]
3pub mod device;
4#[cfg(target_os = "windows")]
5pub(crate)mod windows;
6#[cfg(target_os="linux")]
7pub(crate)mod linux;
8
9use device::DeviceDescriptor;
10
11#[cfg(target_os = "windows")]
12pub fn drive_list()->anyhow::Result<Vec<DeviceDescriptor>>
13{
14    use windows::*;
15    use std::{ptr::null_mut, mem::{zeroed,size_of}};
16
17    use winapi::um::{setupapi::{SetupDiGetClassDevsA, DIGCF_PRESENT, DIGCF_DEVICEINTERFACE, SP_DEVINFO_DATA, SetupDiEnumDeviceInfo, SetupDiDestroyDeviceInfoList}, winioctl::GUID_DEVINTERFACE_DISK, handleapi::INVALID_HANDLE_VALUE};
18
19    let mut drives:Vec<DeviceDescriptor>=Vec::new();
20
21    unsafe {
22        let h_device_info=SetupDiGetClassDevsA(&GUID_DEVINTERFACE_DISK, null_mut(), null_mut(), DIGCF_PRESENT|DIGCF_DEVICEINTERFACE);
23
24        if h_device_info!=INVALID_HANDLE_VALUE {
25            let mut i=0;
26            let mut device_info_data:SP_DEVINFO_DATA=zeroed();
27            device_info_data.cbSize=size_of::<SP_DEVINFO_DATA>() as _;
28    
29            while SetupDiEnumDeviceInfo(h_device_info, i, &mut device_info_data)!=0
30            {
31                let enumerator_name=get_enumerator_name(h_device_info, &mut device_info_data);
32                let friendly_name=get_friendly_name(h_device_info, &mut device_info_data);
33    
34                if friendly_name.is_empty() {
35                    continue;
36                }
37
38                let mut item=DeviceDescriptor{
39                    description:friendly_name.clone(),
40                    enumerator:enumerator_name.clone(),
41                    isUSB:is_usb_drive(&enumerator_name),
42                    isRemovable:is_removable(h_device_info, &mut device_info_data),
43                    ..Default::default()
44                };
45    
46                get_detail_data(&mut item,h_device_info, &mut device_info_data);
47                let bt=item.busType.clone().unwrap_or("UNKNOWN".to_string());
48                item.isSystem=item.isSystem || is_system_device(&item);
49                item.isCard=["SDCARD","MMC"].contains(&bt.as_str());
50                item.isUAS=Some(&item.enumerator=="SCSI" && bt=="USB");
51                item.isVirtual = item.isVirtual || bt == "VIRTUAL" || bt == "FILEBACKEDVIRTUAL";
52                drives.push(item);
53                i+=1;
54            }
55        }
56
57        SetupDiDestroyDeviceInfoList(h_device_info);
58    }
59
60    Ok(drives)
61}
62
63#[cfg(target_os = "linux")]
64pub fn drive_list()->anyhow::Result<Vec<DeviceDescriptor>> {
65    use linux::lsblk;
66
67    lsblk()
68}
69
70pub fn add(left: usize, right: usize) -> usize {
71    left + right
72}
73
74#[cfg(test)]
75mod tests {
76    use super::*;
77
78    #[test]
79    fn it_works() {
80        let result = add(2, 2);
81        assert_eq!(result, 4);
82    }
83}