From 5bf16b65abe185936cdc75f284d19223a50b86e1 Mon Sep 17 00:00:00 2001 From: Chris Down Date: Sun, 3 Nov 2024 21:15:36 -0800 Subject: [PATCH] windows_sys --- Cargo.lock | 24 +------------------ Cargo.toml | 2 +- src/file.rs | 48 ++++++++++++++++++++++++++++---------- tests/integration_tests.rs | 2 +- 4 files changed, 39 insertions(+), 37 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index cde2961..bb721f3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -163,7 +163,7 @@ dependencies = [ "rayon", "tempfile", "walkdir", - "winapi", + "windows-sys 0.59.0", ] [[package]] @@ -452,22 +452,6 @@ dependencies = [ "winapi-util", ] -[[package]] -name = "winapi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" -dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", -] - -[[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" - [[package]] name = "winapi-util" version = "0.1.9" @@ -477,12 +461,6 @@ dependencies = [ "windows-sys 0.59.0", ] -[[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" - [[package]] name = "windows-sys" version = "0.52.0" diff --git a/Cargo.toml b/Cargo.toml index d332b37..a1cddf1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,7 +24,7 @@ rayon = "1.10.0" libc = "0.2.161" [target.'cfg(target_family = "windows")'.dependencies] -winapi = { version = "0.3.9", features = ["errhandlingapi", "winbase", "winerror"] } +windows-sys = "0.59.0" [dev-dependencies] assert_cmd = "2.0.16" diff --git a/src/file.rs b/src/file.rs index 1987bfe..d515557 100644 --- a/src/file.rs +++ b/src/file.rs @@ -8,7 +8,7 @@ use tempfile::NamedTempFile; #[cfg(target_family = "unix")] use libc::EXDEV as xdev_err; #[cfg(target_family = "windows")] -use winapi::shared::winerror::ERROR_NOT_SAME_DEVICE as xdev_err; +use windows_sys::Win32::Foundation::ERROR_NOT_SAME_DEVICE as xdev_err; #[cfg(target_os = "linux")] fn rename(from: &Path, to: &Path, overwrite: bool) -> io::Result<()> { @@ -50,18 +50,20 @@ fn rename(from: &Path, to: &Path, overwrite: bool) -> io::Result<()> { #[cfg(target_family = "windows")] fn rename(from: &Path, to: &Path, overwrite: bool) -> io::Result<()> { use std::os::windows::ffi::OsStrExt; - use winapi::um::errhandlingapi::GetLastError; - use winapi::um::winbase::{MoveFileExW, MOVEFILE_REPLACE_EXISTING}; - + use windows_sys::Win32::Foundation::{GetLastError, FORMAT_MESSAGE_FROM_SYSTEM, FORMAT_MESSAGE_IGNORE_INSERTS}; + use windows_sys::Win32::Storage::FileSystem::{MoveFileExW, MOVEFILE_REPLACE_EXISTING}; + use windows_sys::Win32::System::Diagnostics::Debug::FormatMessageW; + use std::{iter, ptr, slice}; + let from_wide: Vec = from .as_os_str() .encode_wide() - .chain(std::iter::once(0)) + .chain(iter::once(0)) .collect(); let to_wide: Vec = to .as_os_str() .encode_wide() - .chain(std::iter::once(0)) + .chain(iter::once(0)) .collect(); let flags = if overwrite { @@ -70,19 +72,41 @@ fn rename(from: &Path, to: &Path, overwrite: bool) -> io::Result<()> { 0 }; - dbg!(to.exists()); - dbg!(overwrite); - dbg!(flags); - - dbg!(String::from_utf16(&from_wide)); - dbg!(String::from_utf16(&to_wide)); + // Initial debug output + dbg!(from); + dbg!(to); + dbg!(to.exists(), overwrite, flags); + // Additional check right before calling MoveFileExW + dbg!(std::fs::metadata(to)); + + // Attempt the rename operation let ret = unsafe { MoveFileExW(from_wide.as_ptr(), to_wide.as_ptr(), flags) }; + // Recheck existence after attempting the rename dbg!(ret); + dbg!(to.exists()); if ret == 0 { let err = unsafe { GetLastError() }; + + // Retrieve and print a descriptive error message + let mut buf: [u16; 512] = [0; 512]; + let len = unsafe { + FormatMessageW( + FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, + ptr::null(), + err, + 0, + buf.as_mut_ptr(), + buf.len() as u32, + ptr::null_mut(), + ) + }; + + let message = String::from_utf16_lossy(&buf[..len as usize]); + dbg!(err, message); + Err(io::Error::from_raw_os_error(err as i32)) } else { Ok(()) diff --git a/tests/integration_tests.rs b/tests/integration_tests.rs index d6a1160..4abe7ad 100644 --- a/tests/integration_tests.rs +++ b/tests/integration_tests.rs @@ -8,7 +8,7 @@ fn test_rename_no_overwrite() -> Result<()> { let temp_path = temp_dir.path(); std::fs::copy("tests/data/1.jpg", temp_path.join("1.jpg"))?; - + dbg!("at 1"); let mut cmd = assert_cmd::Command::cargo_bin("exifrename")?;