From 527db2e976427795927056fc8882b3fe26d034d8 Mon Sep 17 00:00:00 2001 From: Jake Shadle Date: Fri, 18 Mar 2022 11:00:30 +0100 Subject: [PATCH] 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. --- Cargo.toml | 16 ++++++-- src/sys/windows/afd.rs | 65 ++++++++++++++++++------------ src/sys/windows/io_status_block.rs | 6 +-- src/sys/windows/named_pipe.rs | 7 ++-- src/sys/windows/net.rs | 56 ++++++++++++------------- src/sys/windows/overlapped.rs | 4 +- src/sys/windows/selector.rs | 39 ++++++++++-------- src/sys/windows/tcp.rs | 14 +++---- src/sys/windows/udp.rs | 20 +++++---- tests/util/mod.rs | 12 +++--- tests/win_named_pipe.rs | 3 +- 11 files changed, 135 insertions(+), 107 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index fdc875a9..171ddda5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -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" diff --git a/src/sys/windows/afd.rs b/src/sys/windows/afd.rs index 6eae3bc0..2c7a99cd 100644 --- a/src/sys/windows/afd.rs +++ b/src/sys/windows/afd.rs @@ -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; +/// +#[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 { - 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::() as ULONG, + Length: size_of::() 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::()) as USHORT, - MaximumLength: (AFD_HELPER_NAME.len() * size_of::()) as USHORT, + Length: (AFD_HELPER_NAME.len() * size_of::()) as u16, + MaximumLength: (AFD_HELPER_NAME.len() * size_of::()) 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 { 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), diff --git a/src/sys/windows/io_status_block.rs b/src/sys/windows/io_status_block.rs index 3e603349..d7eda6a6 100644 --- a/src/sys/windows/io_status_block.rs +++ b/src/sys/windows/io_status_block.rs @@ -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, }) } diff --git a/src/sys/windows/named_pipe.rs b/src/sys/windows/named_pipe.rs index adda51f2..f17dc5bf 100644 --- a/src/sys/windows/named_pipe.rs +++ b/src/sys/windows/named_pipe.rs @@ -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}; diff --git a/src/sys/windows/net.rs b/src/sys/windows/net.rs index db1896f1..2df4b689 100644 --- a/src/sys/windows/net.rs +++ b/src/sys/windows/net.rs @@ -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 { - use winapi::um::winsock2::{PF_INET, PF_INET6}; - +pub(crate) fn new_ip_socket(addr: SocketAddr, socket_type: u16) -> io::Result { 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 { +pub(crate) fn new_socket(domain: u16, socket_type: u16) -> io::Result { 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 (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::(); - *s_un.S_addr_mut() = u32::from_ne_bytes(addr.ip().octets()); + let mut s_un = mem::zeroed::(); + 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::() as c_int) + (sockaddr, mem::size_of::() as i32) } SocketAddr::V6(ref addr) => { let sin6_addr = unsafe { - let mut u = mem::zeroed::(); - *u.Byte_mut() = addr.ip().octets(); + let mut u = mem::zeroed::(); + u.Byte = addr.ip().octets(); IN6_ADDR { u } }; let u = unsafe { - let mut u = mem::zeroed::(); - *u.sin6_scope_id_mut() = addr.scope_id(); + let mut u = mem::zeroed::(); + 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::() as c_int) + (sockaddr, mem::size_of::() as i32) } } } diff --git a/src/sys/windows/overlapped.rs b/src/sys/windows/overlapped.rs index 837b78b6..992c84a0 100644 --- a/src/sys/windows/overlapped.rs +++ b/src/sys/windows/overlapped.rs @@ -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 { diff --git a/src/sys/windows/selector.rs b/src/sys/windows/selector.rs index 133fefe8..63bcfbca 100644 --- a/src/sys/windows/selector.rs +++ b/src/sys/windows/selector.rs @@ -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>>) -> PVOID { +fn into_overlapped(sock_state: Pin>>) -> *mut c_void { let overlapped_ptr: *const Mutex = 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::() as u32, &mut bytes, null_mut(), @@ -655,7 +660,7 @@ cfg_io_source! { } fn get_base_socket(raw_socket: RawSocket) -> io::Result { - 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 diff --git a/src/sys/windows/tcp.rs b/src/sys/windows/tcp.rs index b3f05aec..e452e875 100644 --- a/src/sys/windows/tcp.rs +++ b/src/sys/windows/tcp.rs @@ -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 { 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!( diff --git a/src/sys/windows/udp.rs b/src/sys/windows/udp.rs index 825ecccf..91516ccc 100644 --- a/src/sys/windows/udp.rs +++ b/src/sys/windows/udp.rs @@ -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 { init(); @@ -31,14 +29,14 @@ pub fn bind(addr: SocketAddr) -> io::Result { } pub(crate) fn only_v6(socket: &net::UdpSocket) -> io::Result { - let mut optval: MaybeUninit = MaybeUninit::uninit(); - let mut optlen = mem::size_of::() as c_int; + let mut optval: MaybeUninit = MaybeUninit::uninit(); + let mut optlen = mem::size_of::() 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 { SOCKET_ERROR )?; - debug_assert_eq!(optlen as usize, mem::size_of::()); + debug_assert_eq!(optlen as usize, mem::size_of::()); // Safety: `getsockopt` initialised `optval` for us. let optval = unsafe { optval.assume_init() }; Ok(optval != 0) diff --git a/tests/util/mod.rs b/tests/util/mod.rs index 7eedc345..9233dbe7 100644 --- a/tests/util/mod.rs +++ b/tests/util/mod.rs @@ -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::() as _, ) }; diff --git a/tests/win_named_pipe.rs b/tests/win_named_pipe.rs index e1451f0d..50f28131 100644 --- a/tests/win_named_pipe.rs +++ b/tests/win_named_pipe.rs @@ -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() {}