1 //
2 // Sysinfo
3 //
4 // Copyright (c) 2018 Guillaume Gomez
5 //
6 
7 use crate::{DiskExt, DiskType};
8 
9 use std::ffi::{OsStr, OsString};
10 use std::path::Path;
11 
12 use winapi::um::fileapi::GetDiskFreeSpaceExW;
13 use winapi::um::winnt::ULARGE_INTEGER;
14 
new_disk( name: &OsStr, mount_point: &[u16], file_system: &[u8], type_: DiskType, total_space: u64, is_removable: bool, ) -> Option<Disk>15 pub fn new_disk(
16     name: &OsStr,
17     mount_point: &[u16],
18     file_system: &[u8],
19     type_: DiskType,
20     total_space: u64,
21     is_removable: bool,
22 ) -> Option<Disk> {
23     if total_space == 0 {
24         return None;
25     }
26     let mut d = Disk {
27         type_,
28         name: name.to_owned(),
29         file_system: file_system.to_vec(),
30         mount_point: mount_point.to_vec(),
31         s_mount_point: String::from_utf16_lossy(&mount_point[..mount_point.len() - 1]),
32         total_space,
33         available_space: 0,
34         is_removable,
35     };
36     d.refresh();
37     Some(d)
38 }
39 
40 /// Struct containing a disk information.
41 pub struct Disk {
42     type_: DiskType,
43     name: OsString,
44     file_system: Vec<u8>,
45     mount_point: Vec<u16>,
46     s_mount_point: String,
47     total_space: u64,
48     available_space: u64,
49     is_removable: bool,
50 }
51 
52 impl DiskExt for Disk {
type_(&self) -> DiskType53     fn type_(&self) -> DiskType {
54         self.type_
55     }
56 
name(&self) -> &OsStr57     fn name(&self) -> &OsStr {
58         &self.name
59     }
60 
file_system(&self) -> &[u8]61     fn file_system(&self) -> &[u8] {
62         &self.file_system
63     }
64 
mount_point(&self) -> &Path65     fn mount_point(&self) -> &Path {
66         Path::new(&self.s_mount_point)
67     }
68 
total_space(&self) -> u6469     fn total_space(&self) -> u64 {
70         self.total_space
71     }
72 
available_space(&self) -> u6473     fn available_space(&self) -> u64 {
74         self.available_space
75     }
76 
is_removable(&self) -> bool77     fn is_removable(&self) -> bool {
78         self.is_removable
79     }
80 
refresh(&mut self) -> bool81     fn refresh(&mut self) -> bool {
82         if self.total_space != 0 {
83             unsafe {
84                 let mut tmp: ULARGE_INTEGER = std::mem::zeroed();
85                 if GetDiskFreeSpaceExW(
86                     self.mount_point.as_ptr(),
87                     std::ptr::null_mut(),
88                     std::ptr::null_mut(),
89                     &mut tmp,
90                 ) != 0
91                 {
92                     self.available_space = *tmp.QuadPart();
93                     return true;
94                 }
95             }
96         }
97         false
98     }
99 }
100