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}