Implement DeleteFileW

This commit is contained in:
Rune Tynan 2025-04-09 18:00:23 -07:00
parent 52b204ef55
commit 37a34c042d
4 changed files with 46 additions and 5 deletions

View file

@ -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" => {

View file

@ -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

View file

@ -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);

View file

@ -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();