diff --git a/Cargo.toml b/Cargo.toml index bb84d24ba..7c0c39e8e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -58,7 +58,6 @@ libc = "0.2.86" [target.'cfg(windows)'.dependencies] miow = "0.3.6" winapi = { version = "0.3", features = ["winsock2", "mswsock", "mstcpip"] } -ntapi = "0.3" [dev-dependencies] env_logger = { version = "0.6.2", default-features = false } diff --git a/src/sys/windows/afd.rs b/src/sys/windows/afd.rs index 6241a45ef..aa90baefa 100644 --- a/src/sys/windows/afd.rs +++ b/src/sys/windows/afd.rs @@ -1,6 +1,6 @@ -use ntapi::ntioapi::{IO_STATUS_BLOCK_u, IO_STATUS_BLOCK}; -use ntapi::ntioapi::{NtCancelIoFileEx, NtDeviceIoControlFile}; -use ntapi::ntrtl::RtlNtStatusToDosError; +use super::RtlNtStatusToDosError; +use super::{IO_STATUS_BLOCK_u, IO_STATUS_BLOCK}; +use super::{NtCancelIoFileEx, NtDeviceIoControlFile}; use std::fmt; use std::fs::File; use std::io; @@ -117,7 +117,7 @@ cfg_io_source! { use std::sync::atomic::{AtomicUsize, Ordering}; use miow::iocp::CompletionPort; - use ntapi::ntioapi::{NtCreateFile, FILE_OPEN}; + use super::{NtCreateFile, FILE_OPEN}; use winapi::shared::ntdef::{OBJECT_ATTRIBUTES, UNICODE_STRING, USHORT, WCHAR}; use winapi::um::handleapi::INVALID_HANDLE_VALUE; use winapi::um::winbase::{SetFileCompletionNotificationModes, FILE_SKIP_SET_EVENT_ON_HANDLE}; diff --git a/src/sys/windows/io_status_block.rs b/src/sys/windows/io_status_block.rs index 3e6033496..ead4f8320 100644 --- a/src/sys/windows/io_status_block.rs +++ b/src/sys/windows/io_status_block.rs @@ -1,12 +1,12 @@ use std::fmt; use std::ops::{Deref, DerefMut}; -use ntapi::ntioapi::IO_STATUS_BLOCK; +use super::IO_STATUS_BLOCK; pub struct IoStatusBlock(IO_STATUS_BLOCK); cfg_io_source! { - use ntapi::ntioapi::IO_STATUS_BLOCK_u; + use super::IO_STATUS_BLOCK_u; impl IoStatusBlock { pub fn zeroed() -> Self { diff --git a/src/sys/windows/mod.rs b/src/sys/windows/mod.rs index 98b6fc63e..6febae395 100644 --- a/src/sys/windows/mod.rs +++ b/src/sys/windows/mod.rs @@ -4,6 +4,12 @@ mod io_status_block; pub mod event; pub use event::{Event, Events}; +mod ntapi; +pub(crate) use ntapi::{ + IO_STATUS_BLOCK_u, NtCancelIoFileEx, NtDeviceIoControlFile, RtlNtStatusToDosError, + IO_STATUS_BLOCK, +}; + mod selector; pub use selector::{Selector, SelectorInner, SockState}; @@ -30,6 +36,8 @@ cfg_net! { pub(crate) mod tcp; pub(crate) mod udp; + + pub(crate) use ntapi::{NtCreateFile, FILE_OPEN}; } cfg_os_ext! { diff --git a/src/sys/windows/ntapi.rs b/src/sys/windows/ntapi.rs new file mode 100644 index 000000000..a7493c304 --- /dev/null +++ b/src/sys/windows/ntapi.rs @@ -0,0 +1,162 @@ +// The code in this file is adapted from the ntapi crate +// version 0.3.7 (https://crates.io/crates/ntapi/0.3.7) +// which was released under the MIT License or +// Apache License 2.0. +// This was necessary because ntapi v.0.3.7 +// uses code which is rejected in rust versions greater +// than or equal to version 1.68. +// See here for further information on the error: +// https://github.com/rust-lang/rust/issues/82523. + +#![allow(non_camel_case_types)] +#![allow(non_snake_case)] + +use winapi::shared::{ + basetsd::ULONG_PTR, + ntdef::{HANDLE, NTSTATUS, PVOID, ULONG}, +}; + +pub type PIO_STATUS_BLOCK = *mut IO_STATUS_BLOCK; + +macro_rules! EXTERN { + (extern $c:tt {$( + fn $n:ident ($( $p:tt $(: $t:ty)?),* $(,)?) $(-> $r:ty)?; + )+}) => { + #[cfg_attr(all(target_env = "msvc", feature = "user"), link(name = "ntdll"))] + #[cfg_attr(all(target_env = "msvc", feature = "kernel"), link(name = "ntoskrnl"))] + extern $c {$( + pub fn $n( + $($p $(: $t)?),* + ) $(-> $r)?; + )+} + $( + #[cfg(feature = "func-types")] + pub type $n = unsafe extern $c fn($($p $(: $t)?),*) $(-> $r)?; + )+ + }; + (extern $c:tt {$( + static mut $n:ident : $t:ty; + )+}) => { + #[cfg_attr(all(target_env = "msvc", feature = "user"), link(name = "ntdll"))] + extern $c {$( + pub static mut $n: $t; + )+} + }; +} + +macro_rules! FN { + (stdcall $func:ident($($p:ident: $t:ty,)*) -> $ret:ty) => ( + pub type $func = Option $ret>; + ); + (cdecl $func:ident($($p:ident: $t:ty,)*) -> $ret:ty) => ( + pub type $func = Option $ret>; + ); +} + +macro_rules! STRUCT { + (#[debug] $($rest:tt)*) => ( + STRUCT!{#[cfg_attr(feature = "impl-debug", derive(Debug))] $($rest)*} + ); + ($(#[$attrs:meta])* struct $name:ident { + $($field:ident: $ftype:ty,)+ + }) => ( + #[repr(C)] #[derive(Copy)] $(#[$attrs])* + pub struct $name { + $(pub $field: $ftype,)+ + } + impl Clone for $name { + #[inline] + fn clone(&self) -> $name { *self } + } + #[cfg(feature = "impl-default")] + impl Default for $name { + #[inline] + fn default() -> $name { unsafe { $crate::_core::mem::zeroed() } } + } + ); +} + +macro_rules! UNION { + ($(#[$attrs:meta])* union $name:ident { + $($variant:ident: $ftype:ty,)+ + }) => ( + #[repr(C)] $(#[$attrs])* + pub union $name { + $(pub $variant: $ftype,)+ + } + impl Copy for $name {} + impl Clone for $name { + #[inline] + fn clone(&self) -> $name { *self } + } + #[cfg(feature = "impl-default")] + impl Default for $name { + #[inline] + fn default() -> $name { unsafe { $crate::_core::mem::zeroed() } } + } + ); +} + +EXTERN! {extern "system" { + fn NtCancelIoFileEx( + FileHandle: HANDLE, + IoRequestToCancel: PIO_STATUS_BLOCK, + IoStatusBlock: PIO_STATUS_BLOCK, + ) -> NTSTATUS; + fn NtDeviceIoControlFile( + FileHandle: HANDLE, + Event: HANDLE, + ApcRoutine: PIO_APC_ROUTINE, + ApcContext: PVOID, + IoStatusBlock: PIO_STATUS_BLOCK, + IoControlCode: ULONG, + InputBuffer: PVOID, + InputBufferLength: ULONG, + OutputBuffer: PVOID, + OutputBufferLength: ULONG, + ) -> NTSTATUS; + fn RtlNtStatusToDosError( + Status: NTSTATUS, + ) -> ULONG; +}} + +FN! {stdcall PIO_APC_ROUTINE( + ApcContext: PVOID, + IoStatusBlock: PIO_STATUS_BLOCK, + Reserved: ULONG, +) -> ()} + +STRUCT! {struct IO_STATUS_BLOCK { + u: IO_STATUS_BLOCK_u, + Information: ULONG_PTR, +}} + +UNION! {union IO_STATUS_BLOCK_u { + Status: NTSTATUS, + Pointer: PVOID, +}} + +cfg_net! { + use winapi::{ + shared::ntdef::{PHANDLE, PLARGE_INTEGER, POBJECT_ATTRIBUTES}, + um::winnt::ACCESS_MASK, + }; + + pub(crate) const FILE_OPEN: ULONG = 0x00000001; + + EXTERN! {extern "system" { + fn NtCreateFile( + FileHandle: PHANDLE, + DesiredAccess: ACCESS_MASK, + ObjectAttributes: POBJECT_ATTRIBUTES, + IoStatusBlock: PIO_STATUS_BLOCK, + AllocationSize: PLARGE_INTEGER, + FileAttributes: ULONG, + ShareAccess: ULONG, + CreateDisposition: ULONG, + CreateOptions: ULONG, + EaBuffer: PVOID, + EaLength: ULONG, + ) -> NTSTATUS; + }} +}