Repository: pkolaczk/fclones (language: rust)

Issue:
Windows-Test : OS-Error 87
[2022-08-03 08:34:01.175] fclones.exe:  warn: Failed to read file identifier of 'C:\adbLink\remotes\keymap1.xml': Falscher Parameter. (os error 87)

It seems on every file I got the OS-Error 87
Thats all I can report - sorry.

64-Bit-Windows7 (PC-Perfomance-Index: 5,6)
"DFHL.exe" (Duplicate File Hard Linker/(https://www.jensscheffler.de/dfhl) needs more than 3 Days.
"fclones.exe" less than 3 hours - but … it don't really works …
Test of "finddupe.exe" (v1.25 compiled May 11 2017) ist just running …




Discussion / hints:

Fix patch:
diff --git a/src/file.rs b/src/file.rs
index 69405b2..2715e64 100644
--- a/src/file.rs
+++ b/src/file.rs
@@ -185,7 +185,7 @@ impl FileChunk<'_> {
 #[cfg(unix)]
 pub type InodeId = u64;
 #[cfg(windows)]
-type InodeId = u128;
+pub type InodeId = u128;
 
 /// Useful for identifying files in presence of hardlinks
 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize, Deserialize)]
@@ -228,27 +228,41 @@ impl FileId {
     pub fn from_file(file: &fs::File) -> io::Result<FileId> {
         use std::os::windows::io::*;
         use winapi::ctypes::c_void;
-        use winapi::um::fileapi::FILE_ID_INFO;
+        use winapi::um::fileapi::{
+            GetFileInformationByHandle, BY_HANDLE_FILE_INFORMATION, FILE_ID_INFO,
+        };
         use winapi::um::minwinbase::FileIdInfo;
         use winapi::um::winbase::GetFileInformationByHandleEx;
+
         let handle = file.as_raw_handle();
         unsafe {
             let mut file_id: FILE_ID_INFO = std::mem::zeroed();
             let file_id_ptr = (&mut file_id) as *mut _ as *mut c_void;
             const FILE_ID_SIZE: u32 = std::mem::size_of::<FILE_ID_INFO>() as u32;
-            match GetFileInformationByHandleEx(handle, FileIdInfo, file_id_ptr, FILE_ID_SIZE) {
-                0 => Err(io::Error::new(
-                    ErrorKind::Other,
-                    format!(
-                        "Failed to read file identifier: {}",
-                        io::Error::last_os_error()
-                    ),
-                )),
-                _ => Ok(FileId {
+            if GetFileInformationByHandleEx(handle, FileIdInfo, file_id_ptr, FILE_ID_SIZE) != 0 {
+                return Ok(FileId {
                     device: file_id.VolumeSerialNumber as u64,
                     inode: u128::from_be_bytes(file_id.FileId.Identifier),
-                }),
+                });
+            }
+
+            let mut file_info: BY_HANDLE_FILE_INFORMATION = std::mem::zeroed();
+            let file_info_ptr = (&mut file_info) as *mut _;
+            if GetFileInformationByHandle(handle, file_info_ptr) != 0 {
+                return Ok(FileId {
+                    device: file_info.dwVolumeSerialNumber as u64,
+                    inode: ((file_info.nFileIndexHigh as u128) << 32)
+                        | file_info.nFileIndexLow as u128,
+                });
             }
+
+            Err(io::Error::new(
+                ErrorKind::Other,
+                format!(
+                    "Failed to read file identifier: {}",
+                    io::Error::last_os_error()
+                ),
+            ))
         }
     }
 
diff --git a/src/group.rs b/src/group.rs
index 80345c5..42388d3 100644
--- a/src/group.rs
+++ b/src/group.rs
@@ -23,7 +23,6 @@ use itertools::Itertools;
 use rayon::prelude::*;
 use serde::*;
 use smallvec::SmallVec;
-use sysinfo::DiskType;
 use thread_local::ThreadLocal;
 
 use crate::arg::Arg;
@@ -799,7 +798,7 @@ fn update_file_locations(ctx: &GroupCtx<'_>, groups: &mut (impl FileCollection +
     let err_counters = atomic_counter_vec(ctx.devices.len());
     groups.for_each_mut(|fi| {
         let device: &DiskDevice = &ctx.devices[fi.get_device_index()];
-        if device.disk_type != DiskType::SSD {
+        if device.disk_type != sysinfo::DiskType::SSD {
             if let Err(e) = fi.fetch_physical_location() {
                 handle_fetch_physical_location_err(ctx, &err_counters, fi, e)
             }
@@ -1227,6 +1226,7 @@ mod test {
     use std::sync::Mutex;
 
     use rand::seq::SliceRandom;
+    use sysinfo::DiskType;
 
     use crate::path::Path;
     use crate::util::test::*;
@@ -1826,7 +1826,7 @@ mod test {
                     device: 0,
                 },
                 len: FileLen(1024),
-                location: id * 1024,
+                location: id as u64 * 1024,
             }
         }
 
diff --git a/src/path.rs b/src/path.rs
index f2639d2..aaf1aff 100644
--- a/src/path.rs
+++ b/src/path.rs
@@ -53,7 +53,7 @@ impl Path {
     #[cfg(windows)]
     pub fn is_absolute(&self) -> bool {
         let root = self.root().component.as_bytes();
-        root[root.len() - 1] == b':'
+        root.len() >= 1 && root[0] == b'\\' || root.len() == 2 && root[1] == b':'
     }
 
     pub fn is_relative(&self) -> bool {


Test patch: