aboutsummaryrefslogtreecommitdiff
path: root/src/sys/windows/afd.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/sys/windows/afd.rs')
-rw-r--r--src/sys/windows/afd.rs108
1 files changed, 63 insertions, 45 deletions
diff --git a/src/sys/windows/afd.rs b/src/sys/windows/afd.rs
index 6241a45..0308e2f 100644
--- a/src/sys/windows/afd.rs
+++ b/src/sys/windows/afd.rs
@@ -1,17 +1,32 @@
-use ntapi::ntioapi::{IO_STATUS_BLOCK_u, IO_STATUS_BLOCK};
-use ntapi::ntioapi::{NtCancelIoFileEx, NtDeviceIoControlFile};
-use ntapi::ntrtl::RtlNtStatusToDosError;
+use std::ffi::c_void;
use std::fmt;
use std::fs::File;
use std::io;
use std::mem::size_of;
use std::os::windows::io::AsRawHandle;
-use std::ptr::null_mut;
-use winapi::shared::ntdef::{HANDLE, LARGE_INTEGER, NTSTATUS, PVOID, ULONG};
-use winapi::shared::ntstatus::{STATUS_NOT_FOUND, STATUS_PENDING, STATUS_SUCCESS};
-const IOCTL_AFD_POLL: ULONG = 0x00012024;
+use windows_sys::Win32::Foundation::{
+ RtlNtStatusToDosError, HANDLE, NTSTATUS, STATUS_NOT_FOUND, STATUS_PENDING, STATUS_SUCCESS,
+};
+use windows_sys::Win32::System::WindowsProgramming::{
+ NtDeviceIoControlFile, IO_STATUS_BLOCK, IO_STATUS_BLOCK_0,
+};
+const IOCTL_AFD_POLL: u32 = 0x00012024;
+
+#[link(name = "ntdll")]
+extern "system" {
+ /// See <https://processhacker.sourceforge.io/doc/ntioapi_8h.html#a0d4d550cad4d62d75b76961e25f6550c>
+ ///
+ /// This is an undocumented API and as such not part of <https://github.com/microsoft/win32metadata>
+ /// from which `windows-sys` is generated, and also unlikely to be added, so
+ /// we manually declare it here
+ fn NtCancelIoFileEx(
+ FileHandle: HANDLE,
+ IoRequestToCancel: *mut IO_STATUS_BLOCK,
+ IoStatusBlock: *mut IO_STATUS_BLOCK,
+ ) -> NTSTATUS;
+}
/// Winsock2 AFD driver instance.
///
/// All operations are unsafe due to IO_STATUS_BLOCK parameter are being used by Afd driver during STATUS_PENDING before I/O Completion Port returns its result.
@@ -24,7 +39,7 @@ pub struct Afd {
#[derive(Debug)]
pub struct AfdPollHandleInfo {
pub handle: HANDLE,
- pub events: ULONG,
+ pub events: u32,
pub status: NTSTATUS,
}
@@ -32,10 +47,10 @@ unsafe impl Send for AfdPollHandleInfo {}
#[repr(C)]
pub struct AfdPollInfo {
- pub timeout: LARGE_INTEGER,
+ pub timeout: i64,
// Can have only value 1.
- pub number_of_handles: ULONG,
- pub exclusive: ULONG,
+ pub number_of_handles: u32,
+ pub exclusive: u32,
pub handles: [AfdPollHandleInfo; 1],
}
@@ -58,13 +73,13 @@ impl Afd {
&self,
info: &mut AfdPollInfo,
iosb: *mut IO_STATUS_BLOCK,
- overlapped: PVOID,
+ overlapped: *mut c_void,
) -> io::Result<bool> {
- let info_ptr: PVOID = info as *mut _ as PVOID;
- (*iosb).u.Status = STATUS_PENDING;
+ let info_ptr = info as *mut _ as *mut c_void;
+ (*iosb).Anonymous.Status = STATUS_PENDING;
let status = NtDeviceIoControlFile(
- self.fd.as_raw_handle(),
- null_mut(),
+ self.fd.as_raw_handle() as HANDLE,
+ 0,
None,
overlapped,
iosb,
@@ -93,15 +108,15 @@ impl Afd {
/// Use it only with request is still being polled so that you have valid `IO_STATUS_BLOCK` to use.
/// User should NOT deallocate there overlapped value after the `cancel` to prevent double free.
pub unsafe fn cancel(&self, iosb: *mut IO_STATUS_BLOCK) -> io::Result<()> {
- if (*iosb).u.Status != STATUS_PENDING {
+ if (*iosb).Anonymous.Status != STATUS_PENDING {
return Ok(());
}
let mut cancel_iosb = IO_STATUS_BLOCK {
- u: IO_STATUS_BLOCK_u { Status: 0 },
+ Anonymous: IO_STATUS_BLOCK_0 { Status: 0 },
Information: 0,
};
- let status = NtCancelIoFileEx(self.fd.as_raw_handle(), iosb, &mut cancel_iosb);
+ let status = NtCancelIoFileEx(self.fd.as_raw_handle() as HANDLE, iosb, &mut cancel_iosb);
if status == STATUS_SUCCESS || status == STATUS_NOT_FOUND {
return Ok(());
}
@@ -114,18 +129,21 @@ impl Afd {
cfg_io_source! {
use std::mem::zeroed;
use std::os::windows::io::{FromRawHandle, RawHandle};
+ use std::ptr::null_mut;
use std::sync::atomic::{AtomicUsize, Ordering};
- use miow::iocp::CompletionPort;
- use ntapi::ntioapi::{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};
- use winapi::um::winnt::{SYNCHRONIZE, FILE_SHARE_READ, FILE_SHARE_WRITE};
+ use super::iocp::CompletionPort;
+ use windows_sys::Win32::{
+ Foundation::{UNICODE_STRING, INVALID_HANDLE_VALUE},
+ System::WindowsProgramming::{
+ OBJECT_ATTRIBUTES, FILE_SKIP_SET_EVENT_ON_HANDLE,
+ },
+ Storage::FileSystem::{FILE_OPEN, NtCreateFile, SetFileCompletionNotificationModes, SYNCHRONIZE, FILE_SHARE_READ, FILE_SHARE_WRITE},
+ };
const AFD_HELPER_ATTRIBUTES: OBJECT_ATTRIBUTES = OBJECT_ATTRIBUTES {
- Length: size_of::<OBJECT_ATTRIBUTES>() as ULONG,
- RootDirectory: null_mut(),
+ Length: size_of::<OBJECT_ATTRIBUTES>() as u32,
+ RootDirectory: 0,
ObjectName: &AFD_OBJ_NAME as *const _ as *mut _,
Attributes: 0,
SecurityDescriptor: null_mut(),
@@ -133,12 +151,12 @@ cfg_io_source! {
};
const AFD_OBJ_NAME: UNICODE_STRING = UNICODE_STRING {
- Length: (AFD_HELPER_NAME.len() * size_of::<WCHAR>()) as USHORT,
- MaximumLength: (AFD_HELPER_NAME.len() * size_of::<WCHAR>()) as USHORT,
+ Length: (AFD_HELPER_NAME.len() * size_of::<u16>()) as u16,
+ MaximumLength: (AFD_HELPER_NAME.len() * size_of::<u16>()) as u16,
Buffer: AFD_HELPER_NAME.as_ptr() as *mut _,
};
- const AFD_HELPER_NAME: &[WCHAR] = &[
+ const AFD_HELPER_NAME: &[u16] = &[
'\\' as _,
'D' as _,
'e' as _,
@@ -166,10 +184,10 @@ cfg_io_source! {
impl Afd {
/// Create new Afd instance.
- pub fn new(cp: &CompletionPort) -> io::Result<Afd> {
+ pub(crate) fn new(cp: &CompletionPort) -> io::Result<Afd> {
let mut afd_helper_handle: HANDLE = INVALID_HANDLE_VALUE;
let mut iosb = IO_STATUS_BLOCK {
- u: IO_STATUS_BLOCK_u { Status: 0 },
+ Anonymous: IO_STATUS_BLOCK_0 { Status: 0 },
Information: 0,
};
@@ -180,12 +198,12 @@ cfg_io_source! {
&AFD_HELPER_ATTRIBUTES as *const _ as *mut _,
&mut iosb,
null_mut(),
- 0 as ULONG,
+ 0,
FILE_SHARE_READ | FILE_SHARE_WRITE,
FILE_OPEN,
- 0 as ULONG,
+ 0,
null_mut(),
- 0 as ULONG,
+ 0,
);
if status != STATUS_SUCCESS {
let raw_err = io::Error::from_raw_os_error(
@@ -204,7 +222,7 @@ cfg_io_source! {
cp.add_handle(token, &afd.fd)?;
match SetFileCompletionNotificationModes(
afd_helper_handle,
- FILE_SKIP_SET_EVENT_ON_HANDLE,
+ FILE_SKIP_SET_EVENT_ON_HANDLE as u8 // This is just 2, so fits in u8
) {
0 => Err(io::Error::last_os_error()),
_ => Ok(afd),
@@ -214,18 +232,18 @@ cfg_io_source! {
}
}
-pub const POLL_RECEIVE: u32 = 0b000_000_001;
-pub const POLL_RECEIVE_EXPEDITED: u32 = 0b000_000_010;
-pub const POLL_SEND: u32 = 0b000_000_100;
-pub const POLL_DISCONNECT: u32 = 0b000_001_000;
-pub const POLL_ABORT: u32 = 0b000_010_000;
-pub const POLL_LOCAL_CLOSE: u32 = 0b000_100_000;
+pub const POLL_RECEIVE: u32 = 0b0_0000_0001;
+pub const POLL_RECEIVE_EXPEDITED: u32 = 0b0_0000_0010;
+pub const POLL_SEND: u32 = 0b0_0000_0100;
+pub const POLL_DISCONNECT: u32 = 0b0_0000_1000;
+pub const POLL_ABORT: u32 = 0b0_0001_0000;
+pub const POLL_LOCAL_CLOSE: u32 = 0b0_0010_0000;
// Not used as it indicated in each event where a connection is connected, not
// just the first time a connection is established.
// Also see https://github.com/piscisaureus/wepoll/commit/8b7b340610f88af3d83f40fb728e7b850b090ece.
-pub const POLL_CONNECT: u32 = 0b001_000_000;
-pub const POLL_ACCEPT: u32 = 0b010_000_000;
-pub const POLL_CONNECT_FAIL: u32 = 0b100_000_000;
+pub const POLL_CONNECT: u32 = 0b0_0100_0000;
+pub const POLL_ACCEPT: u32 = 0b0_1000_0000;
+pub const POLL_CONNECT_FAIL: u32 = 0b1_0000_0000;
pub const KNOWN_EVENTS: u32 = POLL_RECEIVE
| POLL_RECEIVE_EXPEDITED