From 86bceda4b356130cf7e9b648e5ee9e784aa68a74 Mon Sep 17 00:00:00 2001 From: Begild Date: Sun, 20 Oct 2024 16:51:09 +0800 Subject: [PATCH] =?UTF-8?q?1.=20=E4=BF=AE=E6=94=B9mountmap=E7=9A=84?= =?UTF-8?q?=E8=A1=8C=E4=B8=BA=E3=80=82=E5=9B=A0=E4=B8=BA=E5=9C=A8L3?= =?UTF-8?q?=E5=8F=AF=E8=83=BD=E9=87=8D=E5=90=AF=E8=BF=9C=E7=A8=8B=E6=A1=8C?= =?UTF-8?q?=E9=9D=A2=E4=BC=9A=E4=BD=BF=E5=BE=97=E7=A3=81=E7=9B=98=E7=9A=84?= =?UTF-8?q?=E9=A1=BA=E5=BA=8F=E5=8F=98=E5=8C=96=E3=80=82=E6=89=80=E4=BB=A5?= =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=94=AF=E6=8C=81=E7=9B=B4=E6=8E=A5=E9=80=9A?= =?UTF-8?q?=E8=BF=87=E7=A3=81=E7=9B=98=E7=9A=84=E5=8D=B7=E6=A0=87=E6=9D=A5?= =?UTF-8?q?=E6=8C=82=E8=BD=BD=E8=80=8C=E4=B8=8D=E5=9B=BA=E5=AE=9A=E6=98=AF?= =?UTF-8?q?=E6=9F=90=E4=B8=AA=E7=9B=98=EF=BC=8C=E8=BF=99=E6=A0=B7=E5=8F=AF?= =?UTF-8?q?=E4=BB=A5=E4=BD=BF=E5=BE=97=E7=A8=8B=E5=BA=8F=E8=87=AA=E5=8A=A8?= =?UTF-8?q?=E6=9F=A5=E6=89=BE=E5=8C=B9=E9=85=8D=E7=9A=84=E7=A3=81=E7=9B=98?= =?UTF-8?q?=E6=9D=A5=E8=BF=9B=E8=A1=8C=E6=8C=82=E8=BD=BD=EF=BC=8C=E8=80=8C?= =?UTF-8?q?=E4=B8=8D=E6=98=AF=E6=8C=82=E8=BD=BD=E5=90=8E=E5=8F=91=E7=8E=B0?= =?UTF-8?q?=E5=86=85=E5=AE=B9=E5=AF=B9=E4=B8=8D=E4=B8=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Cargo.toml | 1 + src/disk/mod.rs | 56 +++++++++++++++++++++++++++++++++++++++++++++++++ src/lib.rs | 56 +++++++++++++++++++++++++++++++++++++++++-------- src/server.rs | 10 --------- 4 files changed, 104 insertions(+), 19 deletions(-) create mode 100755 src/disk/mod.rs diff --git a/Cargo.toml b/Cargo.toml index bbda702..66f67d2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,6 +21,7 @@ winapi = { version = "0.3", features = [ "winnt", ] } windows = "0.28" +encoding_rs = "0.8" serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" libc = "0.2" diff --git a/src/disk/mod.rs b/src/disk/mod.rs new file mode 100755 index 0000000..a24ecac --- /dev/null +++ b/src/disk/mod.rs @@ -0,0 +1,56 @@ +extern crate winapi; + +use std::ffi::CString; +use winapi::um::fileapi::GetVolumeInformationA; +use encoding_rs::GBK; + +extern crate log; + +pub fn get_disk_info(drive: &str) -> Option<(String, String, u32)> { + let mut volume_name: [i8; 100] = [0; 100]; + let mut file_system_name: [i8; 100] = [0; 100]; + let mut volume_serial_number: u32 = 0; + let mut max_component_length: u32 = 0; + let mut file_system_flags: u32 = 0; + let tstr = CString::new(drive).unwrap(); + let success = unsafe { + GetVolumeInformationA( + tstr.as_ptr(), + volume_name.as_mut_ptr(), + volume_name.len() as u32, + &mut volume_serial_number, + &mut max_component_length, + &mut file_system_flags, + file_system_name.as_mut_ptr(), + file_system_name.len() as u32, + ) + }; + fn gbk2uft8(gbk: &[i8]) -> String { + let unsigned_slice = gbk.iter().map(|&x| x as u8).collect::>(); + let (utf8, _, _) = GBK.decode(&unsigned_slice); + utf8.replace("\0", "").to_string() + } + + if success != 0 { + let volume_label = gbk2uft8(&volume_name); + let file_system_name = gbk2uft8(&file_system_name); + log::info!("Volume Label: {}, file_system: {}, serial_number:{}\n", volume_label, file_system_name, volume_serial_number); + return Some((volume_label, file_system_name, volume_serial_number)); + } else { + log::debug!("volume {} Failed to get volume information.\n", drive); + return None; + } +} +#[test] +fn test_get_disk_info() { + env_logger::init(); + let (label, file_system, serial_number) = get_disk_info("C:\\").unwrap(); + assert_eq!(label, "系统"); + assert_eq!(file_system, "NTFS"); + assert_ne!(serial_number, 0); + + let (label, file_system, serial_number) = get_disk_info("V:\\").unwrap(); + assert_eq!(label, "homes"); + assert_eq!(file_system, "NTFS"); + assert_ne!(serial_number, 0); +} diff --git a/src/lib.rs b/src/lib.rs index b27edbf..042d5a8 100755 --- a/src/lib.rs +++ b/src/lib.rs @@ -4,6 +4,7 @@ use lws_vfs::{ Access, Chown, FileInfo, Flush, Fstat, Getattr, Getxattr, HelloReply, HelloRequest, Mkdir, Open, Read, Readdir, Release, Rmdir, Setxattr, Truncate, Utimens, Write, Create, Unlink, Opendir, Releasedir, Rename, GetConfig, }; + use self::fs_impl::FSImpl; use serde_json::{self, Value}; use serde::Serialize; @@ -15,6 +16,7 @@ use std::collections::HashMap; extern crate log; mod fs_impl; +mod disk; pub mod lws_vfs { tonic::include_proto!("lws_vfs"); } @@ -54,15 +56,44 @@ impl Config { ))) } }; - let mount_map = mounts - .iter() - .map(|(key, value)| { - ( - key.as_str().to_string(), - value.as_str().unwrap().to_string(), - ) - }) - .collect(); + let mut mount_map: HashMap = mounts.iter().filter(|(key, _)| { + match disk::get_disk_info(&key) { + None => false, + Some(_) => true, + } + }).map(|(key, value)| (key.to_string(), value.to_string())).collect(); + + let mut volume_names = HashMap::new(); + + // 获取所有的盘符对应的卷标便于后续进行比对 + for drive in 'C'..='Z' { + let drive = format!("{}:\\", drive); + if let Some((volume, _, _)) = disk::get_disk_info(&drive) { + //TODO: 这里如果存在同名的卷标会出现问题 + volume_names.insert(volume, drive); + } + } + log::info!("local disk: {:?}", volume_names); + + // 遍历配置的盘符和卷标,将配置的盘符和卷标映射到实际盘符上 + for (key, value) in mounts.iter() { + // 直接看下是不是盘符 + if let Some((drive, _, _)) = disk::get_disk_info(&key) { + mount_map.insert(drive.to_string(), value.to_string()); + } else { + // 看下是不是卷标 + if let Some(drive) = volume_names.get(key.as_str()) { + mount_map.insert(drive.to_string(), value.to_string()); + } else { + log::error!("mount volume name [{}] not found in disk list", key); + return Err(Box::new(std::io::Error::new( + std::io::ErrorKind::Other, + "mount map unavailable", + ))) + } + + } + } Ok(Config { port, mount_map }) } @@ -564,3 +595,10 @@ impl LwsVfs for LwsVfsIns { Ok(Response::new(reply)) } } + +# [test] +fn test_config_new() { + env_logger::init(); + let _config = Config::new("config.json").unwrap(); + println!("Config: {:#?}", _config); +} \ No newline at end of file diff --git a/src/server.rs b/src/server.rs index 54b8019..1e5cb2a 100644 --- a/src/server.rs +++ b/src/server.rs @@ -3,16 +3,6 @@ use tonic::transport; use lws_vfs::LwsVfsIns; use lws_vfs::lws_vfs::lws_vfs_server::LwsVfsServer; extern crate log; -// fn main() { -// println!("Hello, world!"); -// let file = "test.txt"; -// let mut sta = Stat { -// st_size: 0, -// st_mode: 0, -// }; -// let mut fi = FuseFileInfo {}; -// getattr(file, &mut sta, &mut fi); -// } #[tokio::main] async fn main() -> Result<(), Box> {