about summary refs log tree commit diff
diff options
context:
space:
mode:
authorRune Tynan <runetynan@gmail.com>2025-04-09 18:00:23 -0700
committerRune Tynan <runetynan@gmail.com>2025-04-11 12:19:43 -0700
commit37a34c042d945dd8198647ecbdd8638d5775a051 (patch)
treeabefaf50a716ea92e4f13c886d311e27203ad2ef
parent52b204ef5589dfedc25f6b85ffa307ecd1305794 (diff)
downloadrust-37a34c042d945dd8198647ecbdd8638d5775a051.tar.gz
rust-37a34c042d945dd8198647ecbdd8638d5775a051.zip
Implement DeleteFileW
-rw-r--r--src/tools/miri/src/shims/windows/foreign_items.rs5
-rw-r--r--src/tools/miri/src/shims/windows/fs.rs19
-rw-r--r--src/tools/miri/tests/pass-dep/shims/windows-fs.rs25
-rw-r--r--src/tools/miri/tests/pass/shims/fs.rs2
4 files changed, 46 insertions, 5 deletions
diff --git a/src/tools/miri/src/shims/windows/foreign_items.rs b/src/tools/miri/src/shims/windows/foreign_items.rs
index 8dcadbed130..c80858c6363 100644
--- a/src/tools/miri/src/shims/windows/foreign_items.rs
+++ b/src/tools/miri/src/shims/windows/foreign_items.rs
@@ -317,6 +317,11 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
                 let res = this.GetFileInformationByHandle(handle, info)?;
                 this.write_scalar(res, dest)?;
             }
+            "DeleteFileW" => {
+                let [file_name] = this.check_shim(abi, sys_conv, link_name, args)?;
+                let res = this.DeleteFileW(file_name)?;
+                this.write_scalar(res, dest)?;
+            }
 
             // Allocation
             "HeapAlloc" => {
diff --git a/src/tools/miri/src/shims/windows/fs.rs b/src/tools/miri/src/shims/windows/fs.rs
index 32bab548969..7561bf45219 100644
--- a/src/tools/miri/src/shims/windows/fs.rs
+++ b/src/tools/miri/src/shims/windows/fs.rs
@@ -371,6 +371,25 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
 
         interp_ok(this.eval_windows("c", "TRUE"))
     }
+
+    fn DeleteFileW(
+        &mut self,
+        file_name: &OpTy<'tcx>, // LPCWSTR
+    ) -> InterpResult<'tcx, Scalar> {
+        // ^ Returns BOOL (i32 on Windows)
+        let this = self.eval_context_mut();
+        this.assert_target_os("windows", "DeleteFileW");
+        this.check_no_isolation("`DeleteFileW`")?;
+
+        let file_name = this.read_path_from_wide_str(this.read_pointer(file_name)?)?;
+        match std::fs::remove_file(file_name) {
+            Ok(_) => interp_ok(this.eval_windows("c", "TRUE")),
+            Err(e) => {
+                this.set_last_error(e)?;
+                interp_ok(this.eval_windows("c", "FALSE"))
+            }
+        }
+    }
 }
 
 /// Windows FILETIME is measured in 100-nanosecs since 1601
diff --git a/src/tools/miri/tests/pass-dep/shims/windows-fs.rs b/src/tools/miri/tests/pass-dep/shims/windows-fs.rs
index a015464dbde..698ca4e0b4b 100644
--- a/src/tools/miri/tests/pass-dep/shims/windows-fs.rs
+++ b/src/tools/miri/tests/pass-dep/shims/windows-fs.rs
@@ -2,6 +2,7 @@
 //@compile-flags: -Zmiri-disable-isolation
 #![allow(nonstandard_style)]
 
+use std::io::ErrorKind;
 use std::os::windows::ffi::OsStrExt;
 use std::path::Path;
 use std::ptr;
@@ -15,10 +16,10 @@ use windows_sys::Win32::Foundation::{
     STATUS_IO_DEVICE_ERROR,
 };
 use windows_sys::Win32::Storage::FileSystem::{
-    BY_HANDLE_FILE_INFORMATION, CREATE_ALWAYS, CREATE_NEW, CreateFileW, FILE_ATTRIBUTE_DIRECTORY,
-    FILE_ATTRIBUTE_NORMAL, FILE_FLAG_BACKUP_SEMANTICS, FILE_FLAG_OPEN_REPARSE_POINT,
-    FILE_SHARE_DELETE, FILE_SHARE_READ, FILE_SHARE_WRITE, GetFileInformationByHandle, OPEN_ALWAYS,
-    OPEN_EXISTING,
+    BY_HANDLE_FILE_INFORMATION, CREATE_ALWAYS, CREATE_NEW, CreateFileW, DeleteFileW,
+    FILE_ATTRIBUTE_DIRECTORY, FILE_ATTRIBUTE_NORMAL, FILE_FLAG_BACKUP_SEMANTICS,
+    FILE_FLAG_OPEN_REPARSE_POINT, FILE_SHARE_DELETE, FILE_SHARE_READ, FILE_SHARE_WRITE,
+    GetFileInformationByHandle, OPEN_ALWAYS, OPEN_EXISTING,
 };
 
 fn main() {
@@ -28,6 +29,7 @@ fn main() {
         test_create_always_twice();
         test_open_always_twice();
         test_open_dir_reparse();
+        test_delete_file();
         test_ntstatus_to_dos();
     }
 }
@@ -194,6 +196,21 @@ unsafe fn test_open_dir_reparse() {
     };
 }
 
+unsafe fn test_delete_file() {
+    let temp = utils::tmp().join("test_delete_file.txt");
+    let raw_path = to_wide_cstr(&temp);
+    let _ = std::fs::File::create(&temp).unwrap();
+
+    if DeleteFileW(raw_path.as_ptr()) == 0 {
+        panic!("Failed to delete file");
+    }
+
+    match std::fs::File::open(temp) {
+        Ok(_) => panic!("File not deleted"),
+        Err(e) => assert!(e.kind() == ErrorKind::NotFound, "File not deleted"),
+    }
+}
+
 unsafe fn test_ntstatus_to_dos() {
     // We won't test all combinations, just a couple common ones
     assert_eq!(RtlNtStatusToDosError(STATUS_IO_DEVICE_ERROR), ERROR_IO_DEVICE);
diff --git a/src/tools/miri/tests/pass/shims/fs.rs b/src/tools/miri/tests/pass/shims/fs.rs
index 6ad23055f30..d0a7f245ee0 100644
--- a/src/tools/miri/tests/pass/shims/fs.rs
+++ b/src/tools/miri/tests/pass/shims/fs.rs
@@ -17,10 +17,10 @@ mod utils;
 
 fn main() {
     test_path_conversion();
+    test_file_create_new();
     // Windows file handling is very incomplete.
     if cfg!(not(windows)) {
         test_file();
-        test_file_create_new();
         test_seek();
         test_file_clone();
         test_metadata();