about summary refs log tree commit diff
diff options
context:
space:
mode:
authorChris Denton <chris@chrisdenton.dev>2025-07-07 15:39:31 +0000
committerChris Denton <chris@chrisdenton.dev>2025-07-07 15:39:31 +0000
commit2412f8921ce39b986664e27c71b07f0ae24ac100 (patch)
tree718a2188fb874cd6be394eb0def443d1bf27f431
parent8df4a58ac47b778b093652d6190a6f9d54638774 (diff)
downloadrust-2412f8921ce39b986664e27c71b07f0ae24ac100.tar.gz
rust-2412f8921ce39b986664e27c71b07f0ae24ac100.zip
UWP: link ntdll functions using raw-dylib
-rw-r--r--library/std/src/sys/pal/windows/c.rs69
-rw-r--r--library/windows_targets/src/lib.rs23
2 files changed, 30 insertions, 62 deletions
diff --git a/library/std/src/sys/pal/windows/c.rs b/library/std/src/sys/pal/windows/c.rs
index eee169d410a..edac5262a4e 100644
--- a/library/std/src/sys/pal/windows/c.rs
+++ b/library/std/src/sys/pal/windows/c.rs
@@ -197,7 +197,7 @@ compat_fn_optional! {
     pub fn WakeByAddressSingle(address: *const c_void);
 }
 
-#[cfg(any(target_vendor = "win7", target_vendor = "uwp"))]
+#[cfg(any(target_vendor = "win7"))]
 compat_fn_with_fallback! {
     pub static NTDLL: &CStr = c"ntdll";
 
@@ -228,65 +228,14 @@ compat_fn_with_fallback! {
     ) -> NTSTATUS {
         panic!("keyed events not available")
     }
+}
 
-    // These functions are available on UWP when lazily loaded. They will fail WACK if loaded statically.
-    #[cfg(target_vendor = "uwp")]
-    pub fn NtCreateFile(
-        filehandle: *mut HANDLE,
-        desiredaccess: FILE_ACCESS_RIGHTS,
-        objectattributes: *const OBJECT_ATTRIBUTES,
-        iostatusblock: *mut IO_STATUS_BLOCK,
-        allocationsize: *const i64,
-        fileattributes: FILE_FLAGS_AND_ATTRIBUTES,
-        shareaccess: FILE_SHARE_MODE,
-        createdisposition: NTCREATEFILE_CREATE_DISPOSITION,
-        createoptions: NTCREATEFILE_CREATE_OPTIONS,
-        eabuffer: *const c_void,
-        ealength: u32
-    ) -> NTSTATUS {
-        STATUS_NOT_IMPLEMENTED
-    }
-    #[cfg(target_vendor = "uwp")]
-    pub fn NtOpenFile(
-        filehandle: *mut HANDLE,
-        desiredaccess: u32,
-        objectattributes: *const OBJECT_ATTRIBUTES,
-        iostatusblock: *mut IO_STATUS_BLOCK,
-        shareaccess: u32,
-        openoptions: u32
-    ) -> NTSTATUS {
-        STATUS_NOT_IMPLEMENTED
-    }
-    #[cfg(target_vendor = "uwp")]
-    pub fn NtReadFile(
-        filehandle: HANDLE,
-        event: HANDLE,
-        apcroutine: PIO_APC_ROUTINE,
-        apccontext: *const c_void,
-        iostatusblock: *mut IO_STATUS_BLOCK,
-        buffer: *mut c_void,
-        length: u32,
-        byteoffset: *const i64,
-        key: *const u32
-    ) -> NTSTATUS {
-        STATUS_NOT_IMPLEMENTED
-    }
-    #[cfg(target_vendor = "uwp")]
-    pub fn NtWriteFile(
-        filehandle: HANDLE,
-        event: HANDLE,
-        apcroutine: PIO_APC_ROUTINE,
-        apccontext: *const c_void,
-        iostatusblock: *mut IO_STATUS_BLOCK,
-        buffer: *const c_void,
-        length: u32,
-        byteoffset: *const i64,
-        key: *const u32
-    ) -> NTSTATUS {
-        STATUS_NOT_IMPLEMENTED
-    }
-    #[cfg(target_vendor = "uwp")]
-    pub fn RtlNtStatusToDosError(Status: NTSTATUS) -> u32 {
-        Status as u32
+cfg_if::cfg_if! {
+    if #[cfg(target_vendor = "uwp")] {
+        windows_targets::link_raw_dylib!("ntdll.dll" "system" fn NtCreateFile(filehandle : *mut HANDLE, desiredaccess : FILE_ACCESS_RIGHTS, objectattributes : *const OBJECT_ATTRIBUTES, iostatusblock : *mut IO_STATUS_BLOCK, allocationsize : *const i64, fileattributes : FILE_FLAGS_AND_ATTRIBUTES, shareaccess : FILE_SHARE_MODE, createdisposition : NTCREATEFILE_CREATE_DISPOSITION, createoptions : NTCREATEFILE_CREATE_OPTIONS, eabuffer : *const core::ffi::c_void, ealength : u32) -> NTSTATUS);
+        windows_targets::link_raw_dylib!("ntdll.dll" "system" fn NtOpenFile(filehandle : *mut HANDLE, desiredaccess : u32, objectattributes : *const OBJECT_ATTRIBUTES, iostatusblock : *mut IO_STATUS_BLOCK, shareaccess : u32, openoptions : u32) -> NTSTATUS);
+        windows_targets::link_raw_dylib!("ntdll.dll" "system" fn NtReadFile(filehandle : HANDLE, event : HANDLE, apcroutine : PIO_APC_ROUTINE, apccontext : *const core::ffi::c_void, iostatusblock : *mut IO_STATUS_BLOCK, buffer : *mut core::ffi::c_void, length : u32, byteoffset : *const i64, key : *const u32) -> NTSTATUS);
+        windows_targets::link_raw_dylib!("ntdll.dll" "system" fn NtWriteFile(filehandle : HANDLE, event : HANDLE, apcroutine : PIO_APC_ROUTINE, apccontext : *const core::ffi::c_void, iostatusblock : *mut IO_STATUS_BLOCK, buffer : *const core::ffi::c_void, length : u32, byteoffset : *const i64, key : *const u32) -> NTSTATUS);
+        windows_targets::link_raw_dylib!("ntdll.dll" "system" fn RtlNtStatusToDosError(status : NTSTATUS) -> u32);
     }
 }
diff --git a/library/windows_targets/src/lib.rs b/library/windows_targets/src/lib.rs
index bce54c5ffce..9e82e6a7200 100644
--- a/library/windows_targets/src/lib.rs
+++ b/library/windows_targets/src/lib.rs
@@ -7,8 +7,7 @@
 #![feature(decl_macro)]
 #![feature(no_core)]
 
-#[cfg(feature = "windows_raw_dylib")]
-pub macro link {
+pub macro link_raw_dylib {
     ($library:literal $abi:literal $($link_name:literal)? $(#[$doc:meta])? fn $($function:tt)*) => (
         #[cfg_attr(not(target_arch = "x86"), link(name = $library, kind = "raw-dylib", modifiers = "+verbatim"))]
         #[cfg_attr(target_arch = "x86", link(name = $library, kind = "raw-dylib", modifiers = "+verbatim", import_name_type = "undecorated"))]
@@ -18,6 +17,26 @@ pub macro link {
         }
     )
 }
+
+pub macro link_dylib {
+    ($library:literal $abi:literal $($link_name:literal)? $(#[$doc:meta])? fn $($function:tt)*) => (
+        // Note: the windows-targets crate uses a pre-built Windows.lib import library which we don't
+        // have in this repo. So instead we always link kernel32.lib and add the rest of the import
+        // libraries below by using an empty extern block. This works because extern blocks are not
+        // connected to the library given in the #[link] attribute.
+        #[link(name = "kernel32")]
+        unsafe extern $abi {
+            $(#[link_name=$link_name])?
+            pub fn $($function)*;
+        }
+    )
+}
+
+#[cfg(feature = "windows_raw_dylib")]
+pub macro link($($tt:tt)*) {
+    $crate::link_raw_dylib!($($tt)*)
+}
+
 #[cfg(not(feature = "windows_raw_dylib"))]
 pub macro link {
     ($library:literal $abi:literal $($link_name:literal)? $(#[$doc:meta])? fn $($function:tt)*) => (