mirror of
https://github.com/openharmony/third_party_rust_mio.git
synced 2026-07-01 20:53:59 -04:00
Replace winapi/ntapi with windows-sys
This updates miow to 0.4, which now uses the windows-sys crate instead of winapi, as the former is maintained and updated frequently as opposed to winapi. The windows-sys crate also covers more of the Windows API surface, which also allowed me to remove the dependency on ntapi (as it still depends on winapi). There was only a single function, `NtCancelIoFileEx` that was present in ntapi but not windows-sys, so I merely added the extern declaration in the one place it was used as it is not worth bringing in a dependency just for that.
This commit is contained in:
committed by
Thomas de Zeeuw
parent
5d8cc365f3
commit
527db2e976
+12
-4
@@ -34,7 +34,7 @@ default = []
|
||||
# Enables the `Poll` and `Registry` types.
|
||||
os-poll = []
|
||||
# Enables additional OS specific extensions, e.g. Unix `pipe(2)`.
|
||||
os-ext = ["os-poll"]
|
||||
os-ext = ["os-poll", "windows-sys/Win32_System_Pipes"]
|
||||
# Enables `mio::net` module containing networking primitives.
|
||||
net = []
|
||||
|
||||
@@ -45,9 +45,17 @@ log = "0.4.8"
|
||||
libc = "0.2.121"
|
||||
|
||||
[target.'cfg(windows)'.dependencies]
|
||||
miow = "0.3.6"
|
||||
winapi = { version = "0.3", features = ["winsock2", "mswsock"] }
|
||||
ntapi = "0.3"
|
||||
miow = "0.4"
|
||||
|
||||
[target.'cfg(windows)'.dependencies.windows-sys]
|
||||
version = "0.28" # This matches the version in miow, but it's fairly outdated
|
||||
features = [
|
||||
"Win32_Storage_FileSystem", # Enables NtCreateFile
|
||||
"Win32_Foundation", # Basic types eg HANDLE
|
||||
"Win32_Networking_WinSock", # winsock2 types/functions
|
||||
"Win32_System_IO", # IO types like OVERLAPPED etc
|
||||
"Win32_System_WindowsProgramming", # General future used for various types/funcs
|
||||
]
|
||||
|
||||
[target.'cfg(target_os = "wasi")'.dependencies]
|
||||
wasi = "0.11.0"
|
||||
|
||||
+39
-26
@@ -1,17 +1,28 @@
|
||||
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};
|
||||
use windows_sys::Win32::{
|
||||
Foundation::{
|
||||
RtlNtStatusToDosError, HANDLE, NTSTATUS, STATUS_NOT_FOUND, STATUS_PENDING, STATUS_SUCCESS,
|
||||
},
|
||||
System::WindowsProgramming::{NtDeviceIoControlFile, IO_STATUS_BLOCK, IO_STATUS_BLOCK_0},
|
||||
};
|
||||
|
||||
const IOCTL_AFD_POLL: ULONG = 0x00012024;
|
||||
const IOCTL_AFD_POLL: u32 = 0x00012024;
|
||||
|
||||
/// <https://processhacker.sourceforge.io/doc/ntioapi_8h.html#a0d4d550cad4d62d75b76961e25f6550c>
|
||||
#[link(name = "ntdll")]
|
||||
extern "system" {
|
||||
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 +35,7 @@ pub struct Afd {
|
||||
#[derive(Debug)]
|
||||
pub struct AfdPollHandleInfo {
|
||||
pub handle: HANDLE,
|
||||
pub events: ULONG,
|
||||
pub events: u32,
|
||||
pub status: NTSTATUS,
|
||||
}
|
||||
|
||||
@@ -32,10 +43,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,10 +69,10 @@ 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(),
|
||||
@@ -93,12 +104,12 @@ 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);
|
||||
@@ -117,14 +128,16 @@ cfg_io_source! {
|
||||
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 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,
|
||||
Length: size_of::<OBJECT_ATTRIBUTES>() as u32,
|
||||
RootDirectory: null_mut(),
|
||||
ObjectName: &AFD_OBJ_NAME as *const _ as *mut _,
|
||||
Attributes: 0,
|
||||
@@ -133,12 +146,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 _,
|
||||
@@ -169,7 +182,7 @@ cfg_io_source! {
|
||||
pub 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,
|
||||
};
|
||||
|
||||
@@ -204,7 +217,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),
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
use std::fmt;
|
||||
use std::ops::{Deref, DerefMut};
|
||||
|
||||
use ntapi::ntioapi::IO_STATUS_BLOCK;
|
||||
use windows_sys::Win32::System::WindowsProgramming::IO_STATUS_BLOCK;
|
||||
|
||||
pub struct IoStatusBlock(IO_STATUS_BLOCK);
|
||||
|
||||
cfg_io_source! {
|
||||
use ntapi::ntioapi::IO_STATUS_BLOCK_u;
|
||||
use windows_sys::Win32::System::WindowsProgramming::{IO_STATUS_BLOCK_0};
|
||||
|
||||
impl IoStatusBlock {
|
||||
pub fn zeroed() -> Self {
|
||||
Self(IO_STATUS_BLOCK {
|
||||
u: IO_STATUS_BLOCK_u { Status: 0 },
|
||||
Anonymous: IO_STATUS_BLOCK_0 { Status: 0 },
|
||||
Information: 0,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -8,9 +8,10 @@ use std::{fmt, mem, slice};
|
||||
|
||||
use miow::iocp::{CompletionPort, CompletionStatus};
|
||||
use miow::pipe;
|
||||
use winapi::shared::winerror::{ERROR_BROKEN_PIPE, ERROR_PIPE_LISTENING};
|
||||
use winapi::um::ioapiset::CancelIoEx;
|
||||
use winapi::um::minwinbase::{OVERLAPPED, OVERLAPPED_ENTRY};
|
||||
use windows_sys::Win32::{
|
||||
Foundation::{ERROR_BROKEN_PIPE, ERROR_PIPE_LISTENING},
|
||||
System::IO::{CancelIoEx, OVERLAPPED, OVERLAPPED_ENTRY},
|
||||
};
|
||||
|
||||
use crate::event::Source;
|
||||
use crate::sys::windows::{Event, Overlapped};
|
||||
|
||||
+29
-27
@@ -3,12 +3,16 @@ use std::mem;
|
||||
use std::net::SocketAddr;
|
||||
use std::sync::Once;
|
||||
|
||||
use winapi::ctypes::c_int;
|
||||
use winapi::shared::in6addr::{in6_addr_u, IN6_ADDR};
|
||||
use winapi::shared::inaddr::{in_addr_S_un, IN_ADDR};
|
||||
use winapi::shared::ws2def::{ADDRESS_FAMILY, AF_INET, AF_INET6, SOCKADDR, SOCKADDR_IN};
|
||||
use winapi::shared::ws2ipdef::{SOCKADDR_IN6_LH_u, SOCKADDR_IN6_LH};
|
||||
use winapi::um::winsock2::{ioctlsocket, socket, FIONBIO, INVALID_SOCKET, SOCKET};
|
||||
use windows_sys::Win32::Networking::WinSock::{
|
||||
ioctlsocket, socket, FIONBIO, IN6_ADDR, IN6_ADDR_0, INVALID_SOCKET, IN_ADDR, IN_ADDR_0,
|
||||
SOCKADDR, SOCKADDR_IN, SOCKADDR_IN6, SOCKADDR_IN6_0, SOCKET,
|
||||
};
|
||||
|
||||
// AF_INET/6 are in the Win32_NetworkManagement_IpHelper feature for some reason,
|
||||
// so just directly define them here rather than import that whole feature set
|
||||
// these constants won't ever change
|
||||
pub(crate) const AF_INET: u16 = 2;
|
||||
pub(crate) const AF_INET6: u16 = 23;
|
||||
|
||||
/// Initialise the network stack for Windows.
|
||||
pub(crate) fn init() {
|
||||
@@ -22,20 +26,18 @@ pub(crate) fn init() {
|
||||
}
|
||||
|
||||
/// Create a new non-blocking socket.
|
||||
pub(crate) fn new_ip_socket(addr: SocketAddr, socket_type: c_int) -> io::Result<SOCKET> {
|
||||
use winapi::um::winsock2::{PF_INET, PF_INET6};
|
||||
|
||||
pub(crate) fn new_ip_socket(addr: SocketAddr, socket_type: u16) -> io::Result<SOCKET> {
|
||||
let domain = match addr {
|
||||
SocketAddr::V4(..) => PF_INET,
|
||||
SocketAddr::V6(..) => PF_INET6,
|
||||
SocketAddr::V4(..) => AF_INET,
|
||||
SocketAddr::V6(..) => AF_INET6,
|
||||
};
|
||||
|
||||
new_socket(domain, socket_type)
|
||||
}
|
||||
|
||||
pub(crate) fn new_socket(domain: c_int, socket_type: c_int) -> io::Result<SOCKET> {
|
||||
pub(crate) fn new_socket(domain: u16, socket_type: u16) -> io::Result<SOCKET> {
|
||||
syscall!(
|
||||
socket(domain, socket_type, 0),
|
||||
socket(domain as i32, socket_type as i32, 0),
|
||||
PartialEq::eq,
|
||||
INVALID_SOCKET
|
||||
)
|
||||
@@ -51,7 +53,7 @@ pub(crate) fn new_socket(domain: c_int, socket_type: c_int) -> io::Result<SOCKET
|
||||
#[repr(C)]
|
||||
pub(crate) union SocketAddrCRepr {
|
||||
v4: SOCKADDR_IN,
|
||||
v6: SOCKADDR_IN6_LH,
|
||||
v6: SOCKADDR_IN6,
|
||||
}
|
||||
|
||||
impl SocketAddrCRepr {
|
||||
@@ -60,49 +62,49 @@ impl SocketAddrCRepr {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn socket_addr(addr: &SocketAddr) -> (SocketAddrCRepr, c_int) {
|
||||
pub(crate) fn socket_addr(addr: &SocketAddr) -> (SocketAddrCRepr, i32) {
|
||||
match addr {
|
||||
SocketAddr::V4(ref addr) => {
|
||||
// `s_addr` is stored as BE on all machine and the array is in BE order.
|
||||
// So the native endian conversion method is used so that it's never swapped.
|
||||
let sin_addr = unsafe {
|
||||
let mut s_un = mem::zeroed::<in_addr_S_un>();
|
||||
*s_un.S_addr_mut() = u32::from_ne_bytes(addr.ip().octets());
|
||||
let mut s_un = mem::zeroed::<IN_ADDR_0>();
|
||||
s_un.S_addr = u32::from_ne_bytes(addr.ip().octets());
|
||||
IN_ADDR { S_un: s_un }
|
||||
};
|
||||
|
||||
let sockaddr_in = SOCKADDR_IN {
|
||||
sin_family: AF_INET as ADDRESS_FAMILY,
|
||||
sin_family: AF_INET,
|
||||
sin_port: addr.port().to_be(),
|
||||
sin_addr,
|
||||
sin_zero: [0; 8],
|
||||
};
|
||||
|
||||
let sockaddr = SocketAddrCRepr { v4: sockaddr_in };
|
||||
(sockaddr, mem::size_of::<SOCKADDR_IN>() as c_int)
|
||||
(sockaddr, mem::size_of::<SOCKADDR_IN>() as i32)
|
||||
}
|
||||
SocketAddr::V6(ref addr) => {
|
||||
let sin6_addr = unsafe {
|
||||
let mut u = mem::zeroed::<in6_addr_u>();
|
||||
*u.Byte_mut() = addr.ip().octets();
|
||||
let mut u = mem::zeroed::<IN6_ADDR_0>();
|
||||
u.Byte = addr.ip().octets();
|
||||
IN6_ADDR { u }
|
||||
};
|
||||
let u = unsafe {
|
||||
let mut u = mem::zeroed::<SOCKADDR_IN6_LH_u>();
|
||||
*u.sin6_scope_id_mut() = addr.scope_id();
|
||||
let mut u = mem::zeroed::<SOCKADDR_IN6_0>();
|
||||
u.sin6_scope_id = addr.scope_id();
|
||||
u
|
||||
};
|
||||
|
||||
let sockaddr_in6 = SOCKADDR_IN6_LH {
|
||||
sin6_family: AF_INET6 as ADDRESS_FAMILY,
|
||||
let sockaddr_in6 = SOCKADDR_IN6 {
|
||||
sin6_family: AF_INET6,
|
||||
sin6_port: addr.port().to_be(),
|
||||
sin6_addr,
|
||||
sin6_flowinfo: addr.flowinfo(),
|
||||
u,
|
||||
Anonymous: u,
|
||||
};
|
||||
|
||||
let sockaddr = SocketAddrCRepr { v6: sockaddr_in6 };
|
||||
(sockaddr, mem::size_of::<SOCKADDR_IN6_LH>() as c_int)
|
||||
(sockaddr, mem::size_of::<SOCKADDR_IN6>() as i32)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,8 +4,8 @@ use std::cell::UnsafeCell;
|
||||
use std::fmt;
|
||||
|
||||
#[cfg(feature = "os-ext")]
|
||||
use winapi::um::minwinbase::OVERLAPPED;
|
||||
use winapi::um::minwinbase::OVERLAPPED_ENTRY;
|
||||
use windows_sys::Win32::System::IO::OVERLAPPED;
|
||||
use windows_sys::Win32::System::IO::OVERLAPPED_ENTRY;
|
||||
|
||||
#[repr(C)]
|
||||
pub(crate) struct Overlapped {
|
||||
|
||||
+22
-17
@@ -12,6 +12,7 @@ cfg_net! {
|
||||
|
||||
use miow::iocp::{CompletionPort, CompletionStatus};
|
||||
use std::collections::VecDeque;
|
||||
use std::ffi::c_void;
|
||||
use std::io;
|
||||
use std::marker::PhantomPinned;
|
||||
use std::os::windows::io::RawSocket;
|
||||
@@ -21,11 +22,11 @@ use std::sync::atomic::AtomicUsize;
|
||||
use std::sync::atomic::{AtomicBool, Ordering};
|
||||
use std::sync::{Arc, Mutex};
|
||||
use std::time::Duration;
|
||||
use winapi::shared::ntdef::NT_SUCCESS;
|
||||
use winapi::shared::ntdef::{HANDLE, PVOID};
|
||||
use winapi::shared::ntstatus::STATUS_CANCELLED;
|
||||
use winapi::shared::winerror::{ERROR_INVALID_HANDLE, ERROR_IO_PENDING, WAIT_TIMEOUT};
|
||||
use winapi::um::minwinbase::OVERLAPPED;
|
||||
|
||||
use windows_sys::Win32::{
|
||||
Foundation::{ERROR_INVALID_HANDLE, ERROR_IO_PENDING, HANDLE, STATUS_CANCELLED, WAIT_TIMEOUT},
|
||||
System::IO::OVERLAPPED,
|
||||
};
|
||||
|
||||
#[derive(Debug)]
|
||||
struct AfdGroup {
|
||||
@@ -141,7 +142,7 @@ impl SockState {
|
||||
/* No poll operation is pending; start one. */
|
||||
self.poll_info.exclusive = 0;
|
||||
self.poll_info.number_of_handles = 1;
|
||||
*unsafe { self.poll_info.timeout.QuadPart_mut() } = std::i64::MAX;
|
||||
self.poll_info.timeout = i64::MAX;
|
||||
self.poll_info.handles[0].handle = self.base_socket as HANDLE;
|
||||
self.poll_info.handles[0].status = 0;
|
||||
self.poll_info.handles[0].events = self.user_evts | afd::POLL_LOCAL_CLOSE;
|
||||
@@ -204,9 +205,9 @@ impl SockState {
|
||||
unsafe {
|
||||
if self.delete_pending {
|
||||
return None;
|
||||
} else if self.iosb.u.Status == STATUS_CANCELLED {
|
||||
} else if self.iosb.Anonymous.Status == STATUS_CANCELLED {
|
||||
/* The poll request was cancelled by CancelIoEx. */
|
||||
} else if !NT_SUCCESS(self.iosb.u.Status) {
|
||||
} else if self.iosb.Anonymous.Status < 0 {
|
||||
/* The overlapped request itself failed in an unexpected way. */
|
||||
afd_events = afd::POLL_CONNECT_FAIL;
|
||||
} else if self.poll_info.number_of_handles < 1 {
|
||||
@@ -295,7 +296,7 @@ impl Drop for SockState {
|
||||
|
||||
/// Converts the pointer to a `SockState` into a raw pointer.
|
||||
/// To revert see `from_overlapped`.
|
||||
fn into_overlapped(sock_state: Pin<Arc<Mutex<SockState>>>) -> PVOID {
|
||||
fn into_overlapped(sock_state: Pin<Arc<Mutex<SockState>>>) -> *mut c_void {
|
||||
let overlapped_ptr: *const Mutex<SockState> =
|
||||
unsafe { Arc::into_raw(Pin::into_inner_unchecked(sock_state)) };
|
||||
overlapped_ptr as *mut _
|
||||
@@ -534,9 +535,13 @@ impl SelectorInner {
|
||||
cfg_io_source! {
|
||||
use std::mem::size_of;
|
||||
use std::ptr::null_mut;
|
||||
use winapi::um::mswsock;
|
||||
use winapi::um::winsock2::WSAGetLastError;
|
||||
use winapi::um::winsock2::{WSAIoctl, SOCKET_ERROR};
|
||||
|
||||
use windows_sys::Win32::Networking::WinSock::{WSAGetLastError, SOCKET_ERROR, WSAIoctl, IOC_OUT, IOC_WS2};
|
||||
|
||||
const SIO_BSP_HANDLE: u32 = IOC_OUT | IOC_WS2 | 27; // 1_207_959_579u32
|
||||
const SIO_BSP_HANDLE_SELECT: u32 = IOC_OUT | IOC_WS2 | 28; // 1_207_959_580u32
|
||||
const SIO_BSP_HANDLE_POLL: u32 = IOC_OUT | IOC_WS2 | 29; // 1_207_959_581u32
|
||||
const SIO_BASE_HANDLE: u32 = IOC_OUT | IOC_WS2 | 34; // 1_207_959_586u32
|
||||
|
||||
impl SelectorInner {
|
||||
fn register(
|
||||
@@ -640,7 +645,7 @@ cfg_io_source! {
|
||||
ioctl,
|
||||
null_mut(),
|
||||
0,
|
||||
&mut base_socket as *mut _ as PVOID,
|
||||
&mut base_socket as *mut _ as *mut c_void,
|
||||
size_of::<RawSocket>() as u32,
|
||||
&mut bytes,
|
||||
null_mut(),
|
||||
@@ -655,7 +660,7 @@ cfg_io_source! {
|
||||
}
|
||||
|
||||
fn get_base_socket(raw_socket: RawSocket) -> io::Result<RawSocket> {
|
||||
let res = try_get_base_socket(raw_socket, mswsock::SIO_BASE_HANDLE);
|
||||
let res = try_get_base_socket(raw_socket, SIO_BASE_HANDLE);
|
||||
if let Ok(base_socket) = res {
|
||||
return Ok(base_socket);
|
||||
}
|
||||
@@ -666,9 +671,9 @@ cfg_io_source! {
|
||||
// However, at least one known LSP deliberately breaks it, so we try
|
||||
// some alternative IOCTLs, starting with the most appropriate one.
|
||||
for &ioctl in &[
|
||||
mswsock::SIO_BSP_HANDLE_SELECT,
|
||||
mswsock::SIO_BSP_HANDLE_POLL,
|
||||
mswsock::SIO_BSP_HANDLE,
|
||||
SIO_BSP_HANDLE_SELECT,
|
||||
SIO_BSP_HANDLE_POLL,
|
||||
SIO_BSP_HANDLE,
|
||||
] {
|
||||
if let Ok(base_socket) = try_get_base_socket(raw_socket, ioctl) {
|
||||
// Since we know now that we're dealing with an LSP (otherwise
|
||||
|
||||
@@ -2,21 +2,21 @@ use std::io;
|
||||
use std::net::{self, SocketAddr};
|
||||
use std::os::windows::io::AsRawSocket;
|
||||
|
||||
use winapi::um::winsock2::{self, PF_INET, PF_INET6, SOCKET, SOCKET_ERROR, SOCK_STREAM};
|
||||
use windows_sys::Win32::Networking::WinSock::{self, SOCKET, SOCKET_ERROR, SOCK_STREAM};
|
||||
|
||||
use crate::sys::windows::net::{init, new_socket, socket_addr};
|
||||
use crate::sys::windows::net::{init, new_socket, socket_addr, AF_INET, AF_INET6};
|
||||
|
||||
pub(crate) fn new_for_addr(address: SocketAddr) -> io::Result<SOCKET> {
|
||||
init();
|
||||
let domain = match address {
|
||||
SocketAddr::V4(_) => PF_INET,
|
||||
SocketAddr::V6(_) => PF_INET6,
|
||||
SocketAddr::V4(_) => AF_INET,
|
||||
SocketAddr::V6(_) => AF_INET6,
|
||||
};
|
||||
new_socket(domain, SOCK_STREAM)
|
||||
}
|
||||
|
||||
pub(crate) fn bind(socket: &net::TcpListener, addr: SocketAddr) -> io::Result<()> {
|
||||
use winsock2::bind;
|
||||
use WinSock::bind;
|
||||
|
||||
let (raw_addr, raw_addr_length) = socket_addr(&addr);
|
||||
syscall!(
|
||||
@@ -32,7 +32,7 @@ pub(crate) fn bind(socket: &net::TcpListener, addr: SocketAddr) -> io::Result<()
|
||||
}
|
||||
|
||||
pub(crate) fn connect(socket: &net::TcpStream, addr: SocketAddr) -> io::Result<()> {
|
||||
use winsock2::connect;
|
||||
use WinSock::connect;
|
||||
|
||||
let (raw_addr, raw_addr_length) = socket_addr(&addr);
|
||||
let res = syscall!(
|
||||
@@ -53,7 +53,7 @@ pub(crate) fn connect(socket: &net::TcpStream, addr: SocketAddr) -> io::Result<(
|
||||
|
||||
pub(crate) fn listen(socket: &net::TcpListener, backlog: u32) -> io::Result<()> {
|
||||
use std::convert::TryInto;
|
||||
use winsock2::listen;
|
||||
use WinSock::listen;
|
||||
|
||||
let backlog = backlog.try_into().unwrap_or(i32::max_value());
|
||||
syscall!(
|
||||
|
||||
+9
-11
@@ -2,14 +2,12 @@ use std::io;
|
||||
use std::mem::{self, MaybeUninit};
|
||||
use std::net::{self, SocketAddr};
|
||||
use std::os::windows::io::{AsRawSocket, FromRawSocket};
|
||||
use std::os::windows::raw::SOCKET as StdSocket; // winapi uses usize, stdlib uses u32/u64.
|
||||
|
||||
use winapi::ctypes::c_int;
|
||||
use winapi::shared::ws2def::IPPROTO_IPV6;
|
||||
use winapi::shared::ws2ipdef::IPV6_V6ONLY;
|
||||
use winapi::um::winsock2::{bind as win_bind, closesocket, getsockopt, SOCKET_ERROR, SOCK_DGRAM};
|
||||
use std::os::windows::raw::SOCKET as StdSocket; // windows-sys uses usize, stdlib uses u32/u64.
|
||||
|
||||
use crate::sys::windows::net::{init, new_ip_socket, socket_addr};
|
||||
use windows_sys::Win32::Networking::WinSock::{
|
||||
bind as win_bind, closesocket, getsockopt, IPPROTO_IPV6, IPV6_V6ONLY, SOCKET_ERROR, SOCK_DGRAM,
|
||||
};
|
||||
|
||||
pub fn bind(addr: SocketAddr) -> io::Result<net::UdpSocket> {
|
||||
init();
|
||||
@@ -31,14 +29,14 @@ pub fn bind(addr: SocketAddr) -> io::Result<net::UdpSocket> {
|
||||
}
|
||||
|
||||
pub(crate) fn only_v6(socket: &net::UdpSocket) -> io::Result<bool> {
|
||||
let mut optval: MaybeUninit<c_int> = MaybeUninit::uninit();
|
||||
let mut optlen = mem::size_of::<c_int>() as c_int;
|
||||
let mut optval: MaybeUninit<i32> = MaybeUninit::uninit();
|
||||
let mut optlen = mem::size_of::<i32>() as i32;
|
||||
|
||||
syscall!(
|
||||
getsockopt(
|
||||
socket.as_raw_socket() as usize,
|
||||
IPPROTO_IPV6 as c_int,
|
||||
IPV6_V6ONLY as c_int,
|
||||
IPPROTO_IPV6 as i32,
|
||||
IPV6_V6ONLY as i32,
|
||||
optval.as_mut_ptr().cast(),
|
||||
&mut optlen,
|
||||
),
|
||||
@@ -46,7 +44,7 @@ pub(crate) fn only_v6(socket: &net::UdpSocket) -> io::Result<bool> {
|
||||
SOCKET_ERROR
|
||||
)?;
|
||||
|
||||
debug_assert_eq!(optlen as usize, mem::size_of::<c_int>());
|
||||
debug_assert_eq!(optlen as usize, mem::size_of::<i32>());
|
||||
// Safety: `getsockopt` initialised `optval` for us.
|
||||
let optval = unsafe { optval.assume_init() };
|
||||
Ok(optval != 0)
|
||||
|
||||
+7
-5
@@ -263,9 +263,11 @@ pub fn set_linger_zero(socket: &TcpStream) {
|
||||
#[cfg(windows)]
|
||||
pub fn set_linger_zero(socket: &TcpStream) {
|
||||
use std::os::windows::io::AsRawSocket;
|
||||
use winapi::um::winsock2::{linger, setsockopt, SOCKET_ERROR, SOL_SOCKET, SO_LINGER};
|
||||
use windows_sys::Win32::Networking::WinSock::{
|
||||
linger, setsockopt, SOCKET_ERROR, SOL_SOCKET, SO_LINGER,
|
||||
};
|
||||
|
||||
let val = linger {
|
||||
let mut val = linger {
|
||||
l_onoff: 1,
|
||||
l_linger: 0,
|
||||
};
|
||||
@@ -273,9 +275,9 @@ pub fn set_linger_zero(socket: &TcpStream) {
|
||||
let res = unsafe {
|
||||
setsockopt(
|
||||
socket.as_raw_socket() as _,
|
||||
SOL_SOCKET,
|
||||
SO_LINGER,
|
||||
&val as *const _ as *const _,
|
||||
SOL_SOCKET as i32,
|
||||
SO_LINGER as i32,
|
||||
&mut val as *mut _ as *mut _,
|
||||
size_of::<linger>() as _,
|
||||
)
|
||||
};
|
||||
|
||||
@@ -9,8 +9,7 @@ use std::time::Duration;
|
||||
use mio::windows::NamedPipe;
|
||||
use mio::{Events, Interest, Poll, Token};
|
||||
use rand::Rng;
|
||||
use winapi::shared::winerror::*;
|
||||
use winapi::um::winbase::FILE_FLAG_OVERLAPPED;
|
||||
use windows_sys::Win32::{Foundation::ERROR_NO_DATA, Storage::FileSystem::FILE_FLAG_OVERLAPPED};
|
||||
|
||||
fn _assert_kinds() {
|
||||
fn _assert_send<T: Send>() {}
|
||||
|
||||
Reference in New Issue
Block a user