about summary refs log tree commit diff
diff options
context:
space:
mode:
authorRune Tynan <runetynan@gmail.com>2025-04-09 22:53:57 -0700
committerRune Tynan <runetynan@gmail.com>2025-04-10 11:29:16 -0700
commitf243cb8861fc2def232e43b6acc2e2cd6867b89c (patch)
treea36b3c96782bc4b0a1b6c387b40f51565350510c
parentd0ea07e9084ace9879384e55e90d5d2625458120 (diff)
downloadrust-f243cb8861fc2def232e43b6acc2e2cd6867b89c.tar.gz
rust-f243cb8861fc2def232e43b6acc2e2cd6867b89c.zip
Implement RtlNtStatusToDosError and shim test for it
-rw-r--r--src/tools/miri/src/shims/windows/foreign_items.rs19
-rw-r--r--src/tools/miri/tests/pass-dep/shims/windows-fs.rs11
2 files changed, 29 insertions, 1 deletions
diff --git a/src/tools/miri/src/shims/windows/foreign_items.rs b/src/tools/miri/src/shims/windows/foreign_items.rs
index 33b65404239..0c4afc069e2 100644
--- a/src/tools/miri/src/shims/windows/foreign_items.rs
+++ b/src/tools/miri/src/shims/windows/foreign_items.rs
@@ -346,6 +346,25 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
                 let last_error = this.get_last_error()?;
                 this.write_scalar(last_error, dest)?;
             }
+            "RtlNtStatusToDosError" => {
+                let [status] = this.check_shim(abi, sys_conv, link_name, args)?;
+                let status = this.read_scalar(status)?.to_u32()?;
+                let err = match status {
+                    // STATUS_MEDIA_WRITE_PROTECTED => ERROR_WRITE_PROTECT
+                    0xC00000A2 => 19,
+                    // STATUS_FILE_INVALID => ERROR_FILE_INVALID
+                    0xC0000098 => 1006,
+                    // STATUS_DISK_FULL => ERROR_DISK_FULL
+                    0xC000007F => 112,
+                    // STATUS_IO_DEVICE_ERROR => ERROR_IO_DEVICE
+                    0xC0000185 => 1117,
+                    // STATUS_ACCESS_DENIED => ERROR_ACCESS_DENIED
+                    0xC0000022 => 5,
+                    // Anything without an error code => ERROR_MR_MID_NOT_FOUND
+                    _ => 317,
+                };
+                this.write_scalar(Scalar::from_i32(err), dest)?;
+            }
 
             // Querying system information
             "GetSystemInfo" => {
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 312df9eb115..a015464dbde 100644
--- a/src/tools/miri/tests/pass-dep/shims/windows-fs.rs
+++ b/src/tools/miri/tests/pass-dep/shims/windows-fs.rs
@@ -10,7 +10,9 @@ use std::ptr;
 mod utils;
 
 use windows_sys::Win32::Foundation::{
-    CloseHandle, ERROR_ALREADY_EXISTS, GENERIC_READ, GENERIC_WRITE, GetLastError,
+    CloseHandle, ERROR_ACCESS_DENIED, ERROR_ALREADY_EXISTS, ERROR_IO_DEVICE, GENERIC_READ,
+    GENERIC_WRITE, GetLastError, RtlNtStatusToDosError, STATUS_ACCESS_DENIED,
+    STATUS_IO_DEVICE_ERROR,
 };
 use windows_sys::Win32::Storage::FileSystem::{
     BY_HANDLE_FILE_INFORMATION, CREATE_ALWAYS, CREATE_NEW, CreateFileW, FILE_ATTRIBUTE_DIRECTORY,
@@ -26,6 +28,7 @@ fn main() {
         test_create_always_twice();
         test_open_always_twice();
         test_open_dir_reparse();
+        test_ntstatus_to_dos();
     }
 }
 
@@ -191,6 +194,12 @@ unsafe fn test_open_dir_reparse() {
     };
 }
 
+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);
+    assert_eq!(RtlNtStatusToDosError(STATUS_ACCESS_DENIED), ERROR_ACCESS_DENIED);
+}
+
 fn to_wide_cstr(path: &Path) -> Vec<u16> {
     let mut raw_path = path.as_os_str().encode_wide().collect::<Vec<_>>();
     raw_path.extend([0, 0]);