Skip to content

Commit 2412f89

Browse files
committed
UWP: link ntdll functions using raw-dylib
1 parent 8df4a58 commit 2412f89

File tree

2 files changed

+30
-62
lines changed
  • library
    • std/src/sys/pal/windows
    • windows_targets/src

2 files changed

+30
-62
lines changed

library/std/src/sys/pal/windows/c.rs

Lines changed: 9 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,7 @@ compat_fn_optional! {
197197
pub fn WakeByAddressSingle(address: *const c_void);
198198
}
199199

200-
#[cfg(any(target_vendor = "win7", target_vendor = "uwp"))]
200+
#[cfg(any(target_vendor = "win7"))]
201201
compat_fn_with_fallback! {
202202
pub static NTDLL: &CStr = c"ntdll";
203203

@@ -228,65 +228,14 @@ compat_fn_with_fallback! {
228228
) -> NTSTATUS {
229229
panic!("keyed events not available")
230230
}
231+
}
231232

232-
// These functions are available on UWP when lazily loaded. They will fail WACK if loaded statically.
233-
#[cfg(target_vendor = "uwp")]
234-
pub fn NtCreateFile(
235-
filehandle: *mut HANDLE,
236-
desiredaccess: FILE_ACCESS_RIGHTS,
237-
objectattributes: *const OBJECT_ATTRIBUTES,
238-
iostatusblock: *mut IO_STATUS_BLOCK,
239-
allocationsize: *const i64,
240-
fileattributes: FILE_FLAGS_AND_ATTRIBUTES,
241-
shareaccess: FILE_SHARE_MODE,
242-
createdisposition: NTCREATEFILE_CREATE_DISPOSITION,
243-
createoptions: NTCREATEFILE_CREATE_OPTIONS,
244-
eabuffer: *const c_void,
245-
ealength: u32
246-
) -> NTSTATUS {
247-
STATUS_NOT_IMPLEMENTED
248-
}
249-
#[cfg(target_vendor = "uwp")]
250-
pub fn NtOpenFile(
251-
filehandle: *mut HANDLE,
252-
desiredaccess: u32,
253-
objectattributes: *const OBJECT_ATTRIBUTES,
254-
iostatusblock: *mut IO_STATUS_BLOCK,
255-
shareaccess: u32,
256-
openoptions: u32
257-
) -> NTSTATUS {
258-
STATUS_NOT_IMPLEMENTED
259-
}
260-
#[cfg(target_vendor = "uwp")]
261-
pub fn NtReadFile(
262-
filehandle: HANDLE,
263-
event: HANDLE,
264-
apcroutine: PIO_APC_ROUTINE,
265-
apccontext: *const c_void,
266-
iostatusblock: *mut IO_STATUS_BLOCK,
267-
buffer: *mut c_void,
268-
length: u32,
269-
byteoffset: *const i64,
270-
key: *const u32
271-
) -> NTSTATUS {
272-
STATUS_NOT_IMPLEMENTED
273-
}
274-
#[cfg(target_vendor = "uwp")]
275-
pub fn NtWriteFile(
276-
filehandle: HANDLE,
277-
event: HANDLE,
278-
apcroutine: PIO_APC_ROUTINE,
279-
apccontext: *const c_void,
280-
iostatusblock: *mut IO_STATUS_BLOCK,
281-
buffer: *const c_void,
282-
length: u32,
283-
byteoffset: *const i64,
284-
key: *const u32
285-
) -> NTSTATUS {
286-
STATUS_NOT_IMPLEMENTED
287-
}
288-
#[cfg(target_vendor = "uwp")]
289-
pub fn RtlNtStatusToDosError(Status: NTSTATUS) -> u32 {
290-
Status as u32
233+
cfg_if::cfg_if! {
234+
if #[cfg(target_vendor = "uwp")] {
235+
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);
236+
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);
237+
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);
238+
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);
239+
windows_targets::link_raw_dylib!("ntdll.dll" "system" fn RtlNtStatusToDosError(status : NTSTATUS) -> u32);
291240
}
292241
}

library/windows_targets/src/lib.rs

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,7 @@
77
#![feature(decl_macro)]
88
#![feature(no_core)]
99

10-
#[cfg(feature = "windows_raw_dylib")]
11-
pub macro link {
10+
pub macro link_raw_dylib {
1211
($library:literal $abi:literal $($link_name:literal)? $(#[$doc:meta])? fn $($function:tt)*) => (
1312
#[cfg_attr(not(target_arch = "x86"), link(name = $library, kind = "raw-dylib", modifiers = "+verbatim"))]
1413
#[cfg_attr(target_arch = "x86", link(name = $library, kind = "raw-dylib", modifiers = "+verbatim", import_name_type = "undecorated"))]
@@ -18,6 +17,26 @@ pub macro link {
1817
}
1918
)
2019
}
20+
21+
pub macro link_dylib {
22+
($library:literal $abi:literal $($link_name:literal)? $(#[$doc:meta])? fn $($function:tt)*) => (
23+
// Note: the windows-targets crate uses a pre-built Windows.lib import library which we don't
24+
// have in this repo. So instead we always link kernel32.lib and add the rest of the import
25+
// libraries below by using an empty extern block. This works because extern blocks are not
26+
// connected to the library given in the #[link] attribute.
27+
#[link(name = "kernel32")]
28+
unsafe extern $abi {
29+
$(#[link_name=$link_name])?
30+
pub fn $($function)*;
31+
}
32+
)
33+
}
34+
35+
#[cfg(feature = "windows_raw_dylib")]
36+
pub macro link($($tt:tt)*) {
37+
$crate::link_raw_dylib!($($tt)*)
38+
}
39+
2140
#[cfg(not(feature = "windows_raw_dylib"))]
2241
pub macro link {
2342
($library:literal $abi:literal $($link_name:literal)? $(#[$doc:meta])? fn $($function:tt)*) => (

0 commit comments

Comments
 (0)