Skip to content

Commit 047cc30

Browse files
committed
WinSock2 fallbacks
Add fallback implementations for `getaddrinfo` and `freeaddrinfo` These fall back to wship6.dll (NT4/2000) if available, or are impl'd via a translation of the header-only wspiapi.h implementations (IPv4 only, all Windows versions with WS2 support). Stub `SetHandleInformation`/`Socket::set_no_inherit` SetHandleInformation is exported by kernel32 on Win9X/ME, but is just stubbed, returning `ERROR_CALL_NOT_IMPLEMENTED`. Sockets are non-inheritable on these systems anyways, so we "fail successfully". https://www.betaarchive.com/wiki/index.php/Microsoft_KB_Archive/150523#MORE_INFORMATION SetHandleInformation is also unavailable on WinNT before 3.51. This is fine, however, because MS did not supply WinSock 2 for Windows NT before 4.0, so this function is not called.
1 parent 2815b32 commit 047cc30

File tree

5 files changed

+648
-1
lines changed

5 files changed

+648
-1
lines changed

library/std/src/os/windows/io/socket.rs

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ impl OwnedSocket {
8787

8888
// FIXME(strict_provenance_magic): we defined RawSocket to be a u64 ;-;
8989
#[allow(fuzzy_provenance_casts)]
90-
#[cfg(not(target_vendor = "uwp"))]
90+
#[cfg(not(any(target_vendor = "uwp", target_vendor = "rust9x")))]
9191
pub(crate) fn set_no_inherit(&self) -> io::Result<()> {
9292
cvt(unsafe {
9393
sys::c::SetHandleInformation(
@@ -98,6 +98,31 @@ impl OwnedSocket {
9898
})
9999
.map(drop)
100100
}
101+
#[allow(fuzzy_provenance_casts)]
102+
#[cfg(target_vendor = "rust9x")]
103+
pub(crate) fn set_no_inherit(&self) -> io::Result<()> {
104+
let res = cvt(unsafe {
105+
sys::c::SetHandleInformation(
106+
self.as_raw_socket() as sys::c::HANDLE,
107+
sys::c::HANDLE_FLAG_INHERIT,
108+
0,
109+
)
110+
})
111+
.map(drop);
112+
113+
match res {
114+
// SetHandleInformation is exported by kernel32 on Win9X/ME, but only returns
115+
// `ERROR_CALL_NOT_IMPLEMENTED`. Sockets are non-inheritable on these systems anyways,
116+
// so we "fail successfully" here.
117+
// https://www.betaarchive.com/wiki/index.php/Microsoft_KB_Archive/150523#MORE_INFORMATION
118+
119+
// SetHandleInformation is also unavailable on WinNT before 3.51. This is fine,
120+
// however, because MS did not supply WinSock 2 for Windows NT before 4.0, so this
121+
// function is not called.
122+
Err(e) if e.raw_os_error() == Some(sys::c::ERROR_CALL_NOT_IMPLEMENTED as i32) => Ok(()),
123+
res => res,
124+
}
125+
}
101126

102127
#[cfg(target_vendor = "uwp")]
103128
pub(crate) fn set_no_inherit(&self) -> io::Result<()> {

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

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@ use core::{mem, ptr};
1313
mod windows_sys;
1414
pub use windows_sys::*;
1515

16+
#[cfg(target_vendor = "rust9x")]
17+
pub(crate) mod wspiapi;
18+
1619
pub type WCHAR = u16;
1720

1821
pub const INVALID_HANDLE_VALUE: HANDLE = ::core::ptr::without_provenance_mut(-1i32 as _);
@@ -544,3 +547,63 @@ compat_fn_with_fallback! {
544547
FALSE
545548
}
546549
}
550+
551+
#[cfg(target_vendor = "rust9x")]
552+
compat_fn_with_fallback! {
553+
pub static KERNEL32: &CStr = c"kernel32" => { load: false, unicows: false };
554+
// >= NT 3.51+
555+
// https://learn.microsoft.com/en-us/windows/win32/api/handleapi/nf-handleapi-sethandleinformation
556+
pub fn SetHandleInformation(hobject: HANDLE, dwmask: u32, dwflags: HANDLE_FLAGS) -> BOOL {
557+
unsafe { SetLastError(ERROR_CALL_NOT_IMPLEMENTED as u32); };
558+
FALSE
559+
}
560+
}
561+
562+
#[cfg(target_vendor = "rust9x")]
563+
mod ws2_32 {
564+
use super::*;
565+
compat_fn_with_fallback! {
566+
pub static WS2_32: &CStr = c"ws2_32" => { load: true, unicows: false };
567+
568+
// >= NT4/2000 with IPv6 Tech Preview
569+
// https://learn.microsoft.com/en-us/windows/win32/api/ws2tcpip/nf-ws2tcpip-getaddrinfo
570+
pub fn getaddrinfo(
571+
pnodename: PCSTR,
572+
pservicename: PCSTR,
573+
phints: *const ADDRINFOA,
574+
ppresult: *mut *mut ADDRINFOA,
575+
) -> i32 {
576+
unsafe { wship6::getaddrinfo(pnodename, pservicename, phints, ppresult) }
577+
}
578+
// >= NT4/2000 with IPv6 Tech Preview
579+
pub fn freeaddrinfo(paddrinfo: *const ADDRINFOA) -> () {
580+
unsafe { wship6::freeaddrinfo(paddrinfo) }
581+
}
582+
}
583+
}
584+
#[cfg(target_vendor = "rust9x")]
585+
pub use ws2_32::{freeaddrinfo, getaddrinfo};
586+
587+
#[cfg(target_vendor = "rust9x")]
588+
mod wship6 {
589+
use super::wspiapi::{wspiapi_freeaddrinfo, wspiapi_getaddrinfo};
590+
use super::{ADDRINFOA, PCSTR};
591+
592+
compat_fn_with_fallback! {
593+
pub static WSHIP6: &CStr = c"wship6" => { load: true, unicows: false };
594+
595+
// >= 2000 with IPv6 Tech Preview
596+
pub fn getaddrinfo(
597+
pnodename: PCSTR,
598+
pservicename: PCSTR,
599+
phints: *const ADDRINFOA,
600+
ppresult: *mut *mut ADDRINFOA,
601+
) -> i32 {
602+
unsafe { wspiapi_getaddrinfo(pnodename, pservicename, phints, ppresult) }
603+
}
604+
// >= 2000 with IPv6 Tech Preview
605+
pub fn freeaddrinfo(paddrinfo: *const ADDRINFOA)-> () {
606+
unsafe { wspiapi_freeaddrinfo(paddrinfo) }
607+
}
608+
}
609+
}

library/std/src/sys/pal/windows/c/bindings.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1978,11 +1978,15 @@ Windows.Win32.Networking.WinSock.FD_SET
19781978
Windows.Win32.Networking.WinSock.FIONBIO
19791979
Windows.Win32.Networking.WinSock.freeaddrinfo
19801980
Windows.Win32.Networking.WinSock.getaddrinfo
1981+
Windows.Win32.Networking.WinSock.gethostbyname
19811982
Windows.Win32.Networking.WinSock.getpeername
1983+
Windows.Win32.Networking.WinSock.getservbyname
19821984
Windows.Win32.Networking.WinSock.getsockname
19831985
Windows.Win32.Networking.WinSock.getsockopt
19841986
Windows.Win32.Networking.WinSock.IN6_ADDR
19851987
Windows.Win32.Networking.WinSock.IN_ADDR
1988+
Windows.Win32.Networking.WinSock.inet_addr
1989+
Windows.Win32.Networking.WinSock.inet_ntoa
19861990
Windows.Win32.Networking.WinSock.INVALID_SOCKET
19871991
Windows.Win32.Networking.WinSock.ioctlsocket
19881992
Windows.Win32.Networking.WinSock.IP_ADD_MEMBERSHIP

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

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,9 +148,13 @@ windows_targets::link!("ws2_32.dll" "system" fn closesocket(s : SOCKET) -> i32);
148148
windows_targets::link!("ws2_32.dll" "system" fn connect(s : SOCKET, name : *const SOCKADDR, namelen : i32) -> i32);
149149
windows_targets::link!("ws2_32.dll" "system" fn freeaddrinfo(paddrinfo : *const ADDRINFOA));
150150
windows_targets::link!("ws2_32.dll" "system" fn getaddrinfo(pnodename : PCSTR, pservicename : PCSTR, phints : *const ADDRINFOA, ppresult : *mut *mut ADDRINFOA) -> i32);
151+
windows_targets::link!("ws2_32.dll" "system" fn gethostbyname(name : PCSTR) -> *mut HOSTENT);
151152
windows_targets::link!("ws2_32.dll" "system" fn getpeername(s : SOCKET, name : *mut SOCKADDR, namelen : *mut i32) -> i32);
153+
windows_targets::link!("ws2_32.dll" "system" fn getservbyname(name : PCSTR, proto : PCSTR) -> *mut SERVENT);
152154
windows_targets::link!("ws2_32.dll" "system" fn getsockname(s : SOCKET, name : *mut SOCKADDR, namelen : *mut i32) -> i32);
153155
windows_targets::link!("ws2_32.dll" "system" fn getsockopt(s : SOCKET, level : i32, optname : i32, optval : PSTR, optlen : *mut i32) -> i32);
156+
windows_targets::link!("ws2_32.dll" "system" fn inet_addr(cp : PCSTR) -> u32);
157+
windows_targets::link!("ws2_32.dll" "system" fn inet_ntoa(r#in : IN_ADDR) -> PSTR);
154158
windows_targets::link!("ws2_32.dll" "system" fn ioctlsocket(s : SOCKET, cmd : i32, argp : *mut u32) -> i32);
155159
windows_targets::link!("ws2_32.dll" "system" fn listen(s : SOCKET, backlog : i32) -> i32);
156160
windows_targets::link!("ws2_32.dll" "system" fn recv(s : SOCKET, buf : PSTR, len : i32, flags : SEND_RECV_FLAGS) -> i32);
@@ -2650,6 +2654,15 @@ pub const HANDLE_FLAG_PROTECT_FROM_CLOSE: HANDLE_FLAGS = 2u32;
26502654
pub const HIGH_PRIORITY_CLASS: PROCESS_CREATION_FLAGS = 128u32;
26512655
pub type HLOCAL = *mut core::ffi::c_void;
26522656
pub type HMODULE = *mut core::ffi::c_void;
2657+
#[repr(C)]
2658+
#[derive(Clone, Copy)]
2659+
pub struct HOSTENT {
2660+
pub h_name: PSTR,
2661+
pub h_aliases: *mut *mut i8,
2662+
pub h_addrtype: i16,
2663+
pub h_length: i16,
2664+
pub h_addr_list: *mut *mut i8,
2665+
}
26532666
pub type HRESULT = i32;
26542667
pub const IDLE_PRIORITY_CLASS: PROCESS_CREATION_FLAGS = 64u32;
26552668
#[repr(C)]
@@ -2958,6 +2971,24 @@ pub const SECURITY_IMPERSONATION: FILE_FLAGS_AND_ATTRIBUTES = 131072u32;
29582971
pub const SECURITY_SQOS_PRESENT: FILE_FLAGS_AND_ATTRIBUTES = 1048576u32;
29592972
pub const SECURITY_VALID_SQOS_FLAGS: FILE_FLAGS_AND_ATTRIBUTES = 2031616u32;
29602973
pub type SEND_RECV_FLAGS = i32;
2974+
#[repr(C)]
2975+
#[cfg(any(target_arch = "aarch64", target_arch = "arm64ec", target_arch = "x86_64"))]
2976+
#[derive(Clone, Copy)]
2977+
pub struct SERVENT {
2978+
pub s_name: PSTR,
2979+
pub s_aliases: *mut *mut i8,
2980+
pub s_proto: PSTR,
2981+
pub s_port: i16,
2982+
}
2983+
#[repr(C)]
2984+
#[cfg(target_arch = "x86")]
2985+
#[derive(Clone, Copy)]
2986+
pub struct SERVENT {
2987+
pub s_name: PSTR,
2988+
pub s_aliases: *mut *mut i8,
2989+
pub s_port: i16,
2990+
pub s_proto: PSTR,
2991+
}
29612992
pub type SET_FILE_POINTER_MOVE_METHOD = u32;
29622993
#[repr(C)]
29632994
#[derive(Clone, Copy)]

0 commit comments

Comments
 (0)