Skip to content

Commit

Permalink
windows_sys
Browse files Browse the repository at this point in the history
  • Loading branch information
cdown committed Nov 4, 2024
1 parent efe8a0c commit 5bf16b6
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 37 deletions.
24 changes: 1 addition & 23 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
48 changes: 36 additions & 12 deletions src/file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<()> {
Expand Down Expand Up @@ -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<u16> = from
.as_os_str()
.encode_wide()
.chain(std::iter::once(0))
.chain(iter::once(0))
.collect();
let to_wide: Vec<u16> = to
.as_os_str()
.encode_wide()
.chain(std::iter::once(0))
.chain(iter::once(0))
.collect();

let flags = if overwrite {
Expand All @@ -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(())
Expand Down
2 changes: 1 addition & 1 deletion tests/integration_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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")?;
Expand Down

0 comments on commit 5bf16b6

Please sign in to comment.