Merge pull request #5142 from youknowone/windows-sys

Windows sys
This commit is contained in:
Jeong, YunWon
2023-12-30 03:48:06 +09:00
committed by GitHub
16 changed files with 310 additions and 186 deletions

82
Cargo.lock generated
View File

@@ -2213,6 +2213,7 @@ dependencies = [
"uuid",
"widestring",
"winapi",
"windows-sys 0.52.0",
"xml-rs",
]
@@ -2287,9 +2288,8 @@ dependencies = [
"wasm-bindgen",
"which",
"widestring",
"winapi",
"windows",
"windows-sys 0.48.0",
"windows-sys 0.52.0",
"winreg",
]
@@ -3159,21 +3159,21 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[[package]]
name = "windows"
version = "0.51.1"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ca229916c5ee38c2f2bc1e9d8f04df975b4bd93f9955dc69fabb5d91270045c9"
checksum = "e48a53791691ab099e5e2ad123536d0fff50652600abaf43bbf952894110d0be"
dependencies = [
"windows-core",
"windows-targets 0.48.5",
"windows-targets 0.52.0",
]
[[package]]
name = "windows-core"
version = "0.51.1"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f1f8cf84f35d2db49a46868f947758c7a1138116f7fac3bc844f43ade1292e64"
checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9"
dependencies = [
"windows-targets 0.48.5",
"windows-targets 0.52.0",
]
[[package]]
@@ -3222,6 +3222,15 @@ dependencies = [
"windows-targets 0.48.5",
]
[[package]]
name = "windows-sys"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
dependencies = [
"windows-targets 0.52.0",
]
[[package]]
name = "windows-targets"
version = "0.42.1"
@@ -3252,6 +3261,21 @@ dependencies = [
"windows_x86_64_msvc 0.48.5",
]
[[package]]
name = "windows-targets"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd"
dependencies = [
"windows_aarch64_gnullvm 0.52.0",
"windows_aarch64_msvc 0.52.0",
"windows_i686_gnu 0.52.0",
"windows_i686_msvc 0.52.0",
"windows_x86_64_gnu 0.52.0",
"windows_x86_64_gnullvm 0.52.0",
"windows_x86_64_msvc 0.52.0",
]
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.42.1"
@@ -3264,6 +3288,12 @@ version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea"
[[package]]
name = "windows_aarch64_msvc"
version = "0.36.1"
@@ -3282,6 +3312,12 @@ version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
[[package]]
name = "windows_aarch64_msvc"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef"
[[package]]
name = "windows_i686_gnu"
version = "0.36.1"
@@ -3300,6 +3336,12 @@ version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
[[package]]
name = "windows_i686_gnu"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313"
[[package]]
name = "windows_i686_msvc"
version = "0.36.1"
@@ -3318,6 +3360,12 @@ version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
[[package]]
name = "windows_i686_msvc"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a"
[[package]]
name = "windows_x86_64_gnu"
version = "0.36.1"
@@ -3336,6 +3384,12 @@ version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
[[package]]
name = "windows_x86_64_gnu"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.42.1"
@@ -3348,6 +3402,12 @@ version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e"
[[package]]
name = "windows_x86_64_msvc"
version = "0.36.1"
@@ -3366,6 +3426,12 @@ version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
[[package]]
name = "windows_x86_64_msvc"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04"
[[package]]
name = "winreg"
version = "0.10.1"

View File

@@ -112,8 +112,16 @@ widestring = { workspace = true }
[target.'cfg(windows)'.dependencies.winapi]
version = "0.3.9"
features = [
"winsock2", "ws2def", "std", "wincrypt", "fileapi",
"impl-default", "vcruntime", "ifdef", "netioapi", "profileapi",
"winsock2", "ifdef", "netioapi",
]
[target.'cfg(windows)'.dependencies.windows-sys]
version = "0.52.0"
features = [
"Win32_Networking_WinSock",
"Win32_NetworkManagement_IpHelper",
"Win32_NetworkManagement_Ndis",
"Win32_Security_Cryptography",
]
[target.'cfg(target_os = "macos")'.dependencies]

View File

@@ -4,11 +4,11 @@ pub(crate) use _multiprocessing::make_module;
#[pymodule]
mod _multiprocessing {
use crate::vm::{function::ArgBytesLike, stdlib::os, PyResult, VirtualMachine};
use winapi::um::winsock2::{self, SOCKET};
use windows_sys::Win32::Networking::WinSock::{self, SOCKET};
#[pyfunction]
fn closesocket(socket: usize, vm: &VirtualMachine) -> PyResult<()> {
let res = unsafe { winsock2::closesocket(socket as SOCKET) };
let res = unsafe { WinSock::closesocket(socket as SOCKET) };
if res == 0 {
Err(os::errno_err(vm))
} else {
@@ -20,7 +20,7 @@ mod _multiprocessing {
fn recv(socket: usize, size: usize, vm: &VirtualMachine) -> PyResult<libc::c_int> {
let mut buf = vec![0; size];
let nread =
unsafe { winsock2::recv(socket as SOCKET, buf.as_mut_ptr() as *mut _, size as i32, 0) };
unsafe { WinSock::recv(socket as SOCKET, buf.as_mut_ptr() as *mut _, size as i32, 0) };
if nread < 0 {
Err(os::errno_err(vm))
} else {
@@ -31,7 +31,7 @@ mod _multiprocessing {
#[pyfunction]
fn send(socket: usize, buf: ArgBytesLike, vm: &VirtualMachine) -> PyResult<libc::c_int> {
let ret = buf.with_ref(|b| unsafe {
winsock2::send(socket as SOCKET, b.as_ptr() as *const _, b.len() as i32, 0)
WinSock::send(socket as SOCKET, b.as_ptr() as *const _, b.len() as i32, 0)
});
if ret < 0 {
Err(os::errno_err(vm))

View File

@@ -30,8 +30,8 @@ mod platform {
#[allow(non_snake_case)]
#[cfg(windows)]
mod platform {
use winapi::um::winsock2;
pub use winsock2::{fd_set, select, timeval, FD_SETSIZE, SOCKET as RawFd};
use windows_sys::Win32::Networking::WinSock;
pub use WinSock::{select, FD_SET as fd_set, FD_SETSIZE, SOCKET as RawFd, TIMEVAL as timeval};
// based off winsock2.h: https://gist.github.com/piscisaureus/906386#file-winsock2-h-L128-L141
@@ -45,7 +45,7 @@ mod platform {
slot = slot.add(1);
}
// slot == &fd_array[fd_count] at this point
if fd_count < FD_SETSIZE as u32 {
if fd_count < FD_SETSIZE {
*slot = fd as RawFd;
(*set).fd_count += 1;
}
@@ -56,12 +56,12 @@ mod platform {
}
pub unsafe fn FD_ISSET(fd: RawFd, set: *mut fd_set) -> bool {
use winapi::um::winsock2::__WSAFDIsSet;
use WinSock::__WSAFDIsSet;
__WSAFDIsSet(fd as _, set) != 0
}
pub fn check_err(x: i32) -> bool {
x == winsock2::SOCKET_ERROR
x == WinSock::SOCKET_ERROR
}
}

View File

@@ -34,18 +34,46 @@ mod _socket {
use libc as c;
#[cfg(windows)]
mod c {
pub use winapi::shared::ifdef::IF_MAX_STRING_SIZE as IF_NAMESIZE;
pub use winapi::shared::mstcpip::*;
pub use winapi::shared::netioapi::{if_indextoname, if_nametoindex};
pub use winapi::shared::ws2def::*;
pub use winapi::shared::ws2ipdef::*;
pub use winapi::um::winsock2::{
IPPORT_RESERVED, SD_BOTH as SHUT_RDWR, SD_RECEIVE as SHUT_RD, SD_SEND as SHUT_WR,
SOCK_DGRAM, SOCK_RAW, SOCK_RDM, SOCK_SEQPACKET, SOCK_STREAM, SOL_SOCKET, SO_BROADCAST,
SO_ERROR, SO_EXCLUSIVEADDRUSE, SO_LINGER, SO_OOBINLINE, SO_REUSEADDR, SO_TYPE,
SO_USELOOPBACK, *,
pub use winapi::shared::ws2def::{
INADDR_ANY, INADDR_BROADCAST, INADDR_LOOPBACK, INADDR_NONE,
};
pub use winapi::um::ws2tcpip::*;
pub use winapi::um::winsock2::{
getprotobyname, getservbyname, getservbyport, getsockopt, setsockopt,
SO_EXCLUSIVEADDRUSE,
};
pub use winapi::um::ws2tcpip::{
EAI_AGAIN, EAI_BADFLAGS, EAI_FAIL, EAI_FAMILY, EAI_MEMORY, EAI_NODATA, EAI_NONAME,
EAI_SERVICE, EAI_SOCKTYPE,
};
pub use windows_sys::Win32::Networking::WinSock::{
AF_DECnet, AF_APPLETALK, AF_IPX, AF_LINK, AI_ADDRCONFIG, AI_ALL, AI_CANONNAME,
AI_NUMERICSERV, AI_V4MAPPED, IPPORT_RESERVED, IPPROTO_AH, IPPROTO_DSTOPTS, IPPROTO_EGP,
IPPROTO_ESP, IPPROTO_FRAGMENT, IPPROTO_GGP, IPPROTO_HOPOPTS, IPPROTO_ICMP,
IPPROTO_ICMPV6, IPPROTO_IDP, IPPROTO_IGMP, IPPROTO_IP, IPPROTO_IP as IPPROTO_IPIP,
IPPROTO_IPV4, IPPROTO_IPV6, IPPROTO_ND, IPPROTO_NONE, IPPROTO_PIM, IPPROTO_PUP,
IPPROTO_RAW, IPPROTO_ROUTING, IPPROTO_TCP, IPPROTO_UDP, IPV6_CHECKSUM, IPV6_DONTFRAG,
IPV6_HOPLIMIT, IPV6_HOPOPTS, IPV6_JOIN_GROUP, IPV6_LEAVE_GROUP, IPV6_MULTICAST_HOPS,
IPV6_MULTICAST_IF, IPV6_MULTICAST_LOOP, IPV6_PKTINFO, IPV6_RECVRTHDR, IPV6_RECVTCLASS,
IPV6_RTHDR, IPV6_TCLASS, IPV6_UNICAST_HOPS, IPV6_V6ONLY, IP_ADD_MEMBERSHIP,
IP_DROP_MEMBERSHIP, IP_HDRINCL, IP_MULTICAST_IF, IP_MULTICAST_LOOP, IP_MULTICAST_TTL,
IP_OPTIONS, IP_RECVDSTADDR, IP_TOS, IP_TTL, MSG_BCAST, MSG_CTRUNC, MSG_DONTROUTE,
MSG_MCAST, MSG_OOB, MSG_PEEK, MSG_TRUNC, MSG_WAITALL, NI_DGRAM, NI_MAXHOST, NI_MAXSERV,
NI_NAMEREQD, NI_NOFQDN, NI_NUMERICHOST, NI_NUMERICSERV, RCVALL_IPLEVEL, RCVALL_OFF,
RCVALL_ON, RCVALL_SOCKETLEVELONLY, SD_BOTH as SHUT_RDWR, SD_RECEIVE as SHUT_RD,
SD_SEND as SHUT_WR, SIO_KEEPALIVE_VALS, SIO_LOOPBACK_FAST_PATH, SIO_RCVALL, SOCK_DGRAM,
SOCK_RAW, SOCK_RDM, SOCK_SEQPACKET, SOCK_STREAM, SOL_SOCKET, SOMAXCONN, SO_BROADCAST,
SO_ERROR, SO_LINGER, SO_OOBINLINE, SO_REUSEADDR, SO_TYPE, SO_USELOOPBACK, TCP_NODELAY,
WSAEBADF, WSAECONNRESET, WSAENOTSOCK, WSAEWOULDBLOCK,
};
pub const IF_NAMESIZE: usize =
windows_sys::Win32::NetworkManagement::Ndis::IF_MAX_STRING_SIZE as _;
pub const AF_UNSPEC: i32 = windows_sys::Win32::Networking::WinSock::AF_UNSPEC as _;
pub const AF_INET: i32 = windows_sys::Win32::Networking::WinSock::AF_INET as _;
pub const AF_INET6: i32 = windows_sys::Win32::Networking::WinSock::AF_INET6 as _;
pub const AI_PASSIVE: i32 = windows_sys::Win32::Networking::WinSock::AI_PASSIVE as _;
pub const AI_NUMERICHOST: i32 =
windows_sys::Win32::Networking::WinSock::AI_NUMERICHOST as _;
}
// constants
#[pyattr(name = "has_ipv6")]
@@ -658,7 +686,7 @@ mod _socket {
#[cfg(windows)]
#[pyattr]
use winapi::shared::ws2def::{
use windows_sys::Win32::Networking::WinSock::{
IPPROTO_CBT, IPPROTO_ICLFXBM, IPPROTO_IGP, IPPROTO_L2TP, IPPROTO_PGM, IPPROTO_RDP,
IPPROTO_SCTP, IPPROTO_ST,
};
@@ -2216,7 +2244,7 @@ mod _socket {
}
#[cfg(windows)]
{
winapi::um::winsock2::INVALID_SOCKET as RawSocket
windows_sys::Win32::Networking::WinSock::INVALID_SOCKET as RawSocket
}
};
@@ -2329,7 +2357,7 @@ mod _socket {
#[cfg(unix)]
use libc::close;
#[cfg(windows)]
use winapi::um::winsock2::closesocket as close;
use windows_sys::Win32::Networking::WinSock::closesocket as close;
let ret = unsafe { close(x as _) };
if ret < 0 {
let err = crate::common::os::errno();

View File

@@ -1453,7 +1453,7 @@ mod windows {
#[pyfunction]
fn enum_certificates(store_name: PyStrRef, vm: &VirtualMachine) -> PyResult<Vec<PyObjectRef>> {
use schannel::{cert_context::ValidUses, cert_store::CertStore, RawPointer};
use winapi::um::wincrypt;
use windows_sys::Win32::Security::Cryptography;
// TODO: check every store for it, not just 2 of them:
// https://github.com/python/cpython/blob/3.8/Modules/_ssl.c#L5603-L5610
@@ -1465,12 +1465,12 @@ mod windows {
let certs = stores.iter().flat_map(|s| s.certs()).map(|c| {
let cert = vm.ctx.new_bytes(c.to_der().to_owned());
let enc_type = unsafe {
let ptr = c.as_ptr() as wincrypt::PCCERT_CONTEXT;
let ptr = c.as_ptr() as *const Cryptography::CERT_CONTEXT;
(*ptr).dwCertEncodingType
};
let enc_type = match enc_type {
wincrypt::X509_ASN_ENCODING => vm.new_pyobj(ascii!("x509_asn")),
wincrypt::PKCS_7_ASN_ENCODING => vm.new_pyobj(ascii!("pkcs_7_asn")),
Cryptography::X509_ASN_ENCODING => vm.new_pyobj(ascii!("x509_asn")),
Cryptography::PKCS_7_ASN_ENCODING => vm.new_pyobj(ascii!("pkcs_7_asn")),
other => vm.new_pyobj(other),
};
let usage: PyObjectRef = match c.valid_uses()? {

View File

@@ -113,7 +113,7 @@ widestring = { workspace = true }
winreg = "0.10.1"
[target.'cfg(windows)'.dependencies.windows]
version = "0.51.1"
version = "0.52.0"
features = [
"Win32_Foundation",
"Win32_System_LibraryLoader",
@@ -122,28 +122,26 @@ features = [
]
[target.'cfg(windows)'.dependencies.windows-sys]
version = "0.48.0"
version = "0.52.0"
features = [
"Win32_Foundation",
"Win32_Networking_WinSock",
"Win32_Security",
"Win32_Storage_FileSystem",
"Win32_System_Console",
"Win32_System_Diagnostics_Debug",
"Win32_System_LibraryLoader",
"Win32_System_Memory",
"Win32_System_Performance",
"Win32_System_Pipes",
"Win32_System_Registry",
"Win32_System_SystemInformation",
"Win32_System_SystemServices",
"Win32_System_Threading",
"Win32_UI_Shell",
"Win32_UI_WindowsAndMessaging",
]
[target.'cfg(windows)'.dependencies.winapi]
version = "0.3.9"
features = [
"winsock2", "handleapi", "std", "winbase", "processenv",
"winnt", "processthreadsapi", "errhandlingapi", "wincon",
"impl-default", "vcruntime", "sysinfoapi",
]
[target.'cfg(target_arch = "wasm32")'.dependencies]
wasm-bindgen = "0.2.80"

View File

@@ -24,12 +24,31 @@ pub fn make_module(vm: &VirtualMachine) -> PyRef<PyModule> {
pub mod errors {
pub use libc::*;
#[cfg(windows)]
pub use winapi::shared::winerror::*;
pub use windows_sys::Win32::{
Foundation::*,
Networking::WinSock::{
WSABASEERR, WSADESCRIPTION_LEN, WSAEACCES, WSAEADDRINUSE, WSAEADDRNOTAVAIL,
WSAEAFNOSUPPORT, WSAEALREADY, WSAEBADF, WSAECANCELLED, WSAECONNABORTED,
WSAECONNREFUSED, WSAECONNRESET, WSAEDESTADDRREQ, WSAEDISCON, WSAEDQUOT, WSAEFAULT,
WSAEHOSTDOWN, WSAEHOSTUNREACH, WSAEINPROGRESS, WSAEINTR, WSAEINVAL,
WSAEINVALIDPROCTABLE, WSAEINVALIDPROVIDER, WSAEISCONN, WSAELOOP, WSAEMFILE,
WSAEMSGSIZE, WSAENAMETOOLONG, WSAENETDOWN, WSAENETRESET, WSAENETUNREACH, WSAENOBUFS,
WSAENOMORE, WSAENOPROTOOPT, WSAENOTCONN, WSAENOTEMPTY, WSAENOTSOCK, WSAEOPNOTSUPP,
WSAEPFNOSUPPORT, WSAEPROCLIM, WSAEPROTONOSUPPORT, WSAEPROTOTYPE,
WSAEPROVIDERFAILEDINIT, WSAEREFUSED, WSAEREMOTE, WSAESHUTDOWN, WSAESOCKTNOSUPPORT,
WSAESTALE, WSAETIMEDOUT, WSAETOOMANYREFS, WSAEUSERS, WSAEWOULDBLOCK, WSAHOST_NOT_FOUND,
WSAID_ACCEPTEX, WSAID_CONNECTEX, WSAID_DISCONNECTEX, WSAID_GETACCEPTEXSOCKADDRS,
WSAID_TRANSMITFILE, WSAID_TRANSMITPACKETS, WSAID_WSAPOLL, WSAID_WSARECVMSG,
WSANOTINITIALISED, WSANO_DATA, WSANO_RECOVERY, WSAPROTOCOL_LEN, WSASERVICE_NOT_FOUND,
WSASYSCALLFAILURE, WSASYSNOTREADY, WSASYS_STATUS_LEN, WSATRY_AGAIN, WSATYPE_NOT_FOUND,
WSAVERNOTSUPPORTED,
},
};
#[cfg(windows)]
macro_rules! reexport_wsa {
($($errname:ident),*$(,)?) => {
paste::paste! {
$(pub const $errname: i32 = [<WSA $errname>] as i32;)*
$(pub const $errname: i32 = windows_sys::Win32::Networking::WinSock:: [<WSA $errname>] as i32;)*
}
}
}
@@ -43,7 +62,7 @@ pub mod errors {
// TODO: EBADF should be here once winerrs are translated to errnos but it messes up some things atm
}
#[cfg(windows)]
pub const WSAHOS: i32 = WSAHOST_NOT_FOUND as i32;
pub const WSAHOS: i32 = WSAHOST_NOT_FOUND;
}
#[cfg(any(unix, windows, target_os = "wasi"))]

View File

@@ -9,13 +9,13 @@ mod msvcrt {
PyRef, PyResult, VirtualMachine,
};
use itertools::Itertools;
use winapi::{
shared::minwindef::UINT,
um::{handleapi::INVALID_HANDLE_VALUE, winnt::HANDLE},
use windows_sys::Win32::{
Foundation::{HANDLE, INVALID_HANDLE_VALUE},
System::Diagnostics::Debug,
};
#[pyattr]
use winapi::um::winbase::{
use windows_sys::Win32::System::Diagnostics::Debug::{
SEM_FAILCRITICALERRORS, SEM_NOALIGNMENTFAULTEXCEPT, SEM_NOGPFAULTERRORBOX,
SEM_NOOPENFILEERRORBOX,
};
@@ -111,7 +111,7 @@ mod msvcrt {
#[allow(non_snake_case)]
#[pyfunction]
fn SetErrorMode(mode: UINT, _: &VirtualMachine) -> UINT {
unsafe { suppress_iph!(winapi::um::errhandlingapi::SetErrorMode(mode)) }
fn SetErrorMode(mode: Debug::THREAD_ERROR_MODE, _: &VirtualMachine) -> u32 {
unsafe { suppress_iph!(Debug::SetErrorMode(mode)) }
}
}

View File

@@ -10,8 +10,10 @@ pub(crate) fn make_module(vm: &VirtualMachine) -> PyRef<PyModule> {
#[pymodule(name = "nt", with(super::os::_os))]
pub(crate) mod module {
#[cfg(target_env = "msvc")]
use crate::builtins::PyListRef;
use crate::{
builtins::{PyStrRef, PyTupleRef},
builtins::{PyDictRef, PyStrRef, PyTupleRef},
common::{crt_fd::Fd, os::errno, suppress_iph},
convert::ToPyException,
function::Either,
@@ -21,27 +23,28 @@ pub(crate) mod module {
},
PyResult, TryFromObject, VirtualMachine,
};
use libc::intptr_t;
use std::{
env, fs, io,
mem::MaybeUninit,
os::windows::ffi::{OsStrExt, OsStringExt},
};
use crate::builtins::PyDictRef;
#[cfg(target_env = "msvc")]
use crate::builtins::PyListRef;
use winapi::{um, vc::vcruntime::intptr_t};
use windows_sys::Win32::{
Foundation::{self, INVALID_HANDLE_VALUE},
Storage::FileSystem,
System::{Console, Threading},
};
#[pyattr]
use libc::{O_BINARY, O_TEMPORARY};
#[pyfunction]
pub(super) fn access(path: OsPath, mode: u8, vm: &VirtualMachine) -> PyResult<bool> {
use um::{fileapi, winnt};
let attr = unsafe { fileapi::GetFileAttributesW(path.to_widecstring(vm)?.as_ptr()) };
Ok(attr != fileapi::INVALID_FILE_ATTRIBUTES
let attr = unsafe { FileSystem::GetFileAttributesW(path.to_widecstring(vm)?.as_ptr()) };
Ok(attr != FileSystem::INVALID_FILE_ATTRIBUTES
&& (mode & 2 == 0
|| attr & winnt::FILE_ATTRIBUTE_READONLY == 0
|| attr & winnt::FILE_ATTRIBUTE_DIRECTORY != 0))
|| attr & FileSystem::FILE_ATTRIBUTE_READONLY == 0
|| attr & FileSystem::FILE_ATTRIBUTE_DIRECTORY != 0))
}
#[derive(FromArgs)]
@@ -135,26 +138,23 @@ pub(crate) mod module {
#[pyfunction]
fn kill(pid: i32, sig: isize, vm: &VirtualMachine) -> PyResult<()> {
{
use um::{handleapi, processthreadsapi, wincon, winnt};
let sig = sig as u32;
let pid = pid as u32;
let sig = sig as u32;
let pid = pid as u32;
if sig == wincon::CTRL_C_EVENT || sig == wincon::CTRL_BREAK_EVENT {
let ret = unsafe { wincon::GenerateConsoleCtrlEvent(sig, pid) };
let res = if ret == 0 { Err(errno_err(vm)) } else { Ok(()) };
return res;
}
let h = unsafe { processthreadsapi::OpenProcess(winnt::PROCESS_ALL_ACCESS, 0, pid) };
if h.is_null() {
return Err(errno_err(vm));
}
let ret = unsafe { processthreadsapi::TerminateProcess(h, sig) };
if sig == Console::CTRL_C_EVENT || sig == Console::CTRL_BREAK_EVENT {
let ret = unsafe { Console::GenerateConsoleCtrlEvent(sig, pid) };
let res = if ret == 0 { Err(errno_err(vm)) } else { Ok(()) };
unsafe { handleapi::CloseHandle(h) };
res
return res;
}
let h = unsafe { Threading::OpenProcess(Threading::PROCESS_ALL_ACCESS, 0, pid) };
if h == 0 {
return Err(errno_err(vm));
}
let ret = unsafe { Threading::TerminateProcess(h, sig) };
let res = if ret == 0 { Err(errno_err(vm)) } else { Ok(()) };
unsafe { Foundation::CloseHandle(h) };
res
}
#[pyfunction]
@@ -163,22 +163,22 @@ pub(crate) mod module {
vm: &VirtualMachine,
) -> PyResult<_os::PyTerminalSize> {
let (columns, lines) = {
use um::{handleapi, processenv, winbase, wincon};
let stdhandle = match fd {
OptionalArg::Present(0) => winbase::STD_INPUT_HANDLE,
OptionalArg::Present(1) | OptionalArg::Missing => winbase::STD_OUTPUT_HANDLE,
OptionalArg::Present(2) => winbase::STD_ERROR_HANDLE,
OptionalArg::Present(0) => Console::STD_INPUT_HANDLE,
OptionalArg::Present(1) | OptionalArg::Missing => Console::STD_OUTPUT_HANDLE,
OptionalArg::Present(2) => Console::STD_ERROR_HANDLE,
_ => return Err(vm.new_value_error("bad file descriptor".to_owned())),
};
let h = unsafe { processenv::GetStdHandle(stdhandle) };
if h.is_null() {
let h = unsafe { Console::GetStdHandle(stdhandle) };
if h == 0 {
return Err(vm.new_os_error("handle cannot be retrieved".to_owned()));
}
if h == handleapi::INVALID_HANDLE_VALUE {
if h == INVALID_HANDLE_VALUE {
return Err(errno_err(vm));
}
let mut csbi = wincon::CONSOLE_SCREEN_BUFFER_INFO::default();
let ret = unsafe { wincon::GetConsoleScreenBufferInfo(h, &mut csbi) };
let mut csbi = MaybeUninit::uninit();
let ret = unsafe { Console::GetConsoleScreenBufferInfo(h, csbi.as_mut_ptr()) };
let csbi = unsafe { csbi.assume_init() };
if ret == 0 {
return Err(errno_err(vm));
}
@@ -250,9 +250,9 @@ pub(crate) mod module {
#[pyfunction]
fn _getfullpathname(path: OsPath, vm: &VirtualMachine) -> PyResult {
let wpath = path.to_widecstring(vm)?;
let mut buffer = vec![0u16; winapi::shared::minwindef::MAX_PATH];
let mut buffer = vec![0u16; Foundation::MAX_PATH as usize];
let ret = unsafe {
um::fileapi::GetFullPathNameW(
FileSystem::GetFullPathNameW(
wpath.as_ptr(),
buffer.len() as _,
buffer.as_mut_ptr(),
@@ -265,7 +265,7 @@ pub(crate) mod module {
if ret as usize > buffer.len() {
buffer.resize(ret as usize, 0);
let ret = unsafe {
um::fileapi::GetFullPathNameW(
FileSystem::GetFullPathNameW(
wpath.as_ptr(),
buffer.len() as _,
buffer.as_mut_ptr(),
@@ -283,10 +283,10 @@ pub(crate) mod module {
#[pyfunction]
fn _getvolumepathname(path: OsPath, vm: &VirtualMachine) -> PyResult {
let wide = path.to_widecstring(vm)?;
let buflen = std::cmp::max(wide.len(), winapi::shared::minwindef::MAX_PATH);
let buflen = std::cmp::max(wide.len(), Foundation::MAX_PATH as usize);
let mut buffer = vec![0u16; buflen];
let ret = unsafe {
um::fileapi::GetVolumePathNameW(wide.as_ptr(), buffer.as_mut_ptr(), buflen as _)
FileSystem::GetVolumePathNameW(wide.as_ptr(), buffer.as_mut_ptr(), buflen as _)
};
if ret == 0 {
return Err(errno_err(vm));
@@ -335,20 +335,19 @@ pub(crate) mod module {
#[pyfunction]
fn _getdiskusage(path: OsPath, vm: &VirtualMachine) -> PyResult<(u64, u64)> {
use um::fileapi::GetDiskFreeSpaceExW;
use winapi::shared::{ntdef::ULARGE_INTEGER, winerror};
use FileSystem::GetDiskFreeSpaceExW;
let wpath = path.to_widecstring(vm)?;
let mut _free_to_me = ULARGE_INTEGER::default();
let mut total = ULARGE_INTEGER::default();
let mut free = ULARGE_INTEGER::default();
let mut _free_to_me: u64 = 0;
let mut total: u64 = 0;
let mut free: u64 = 0;
let ret =
unsafe { GetDiskFreeSpaceExW(wpath.as_ptr(), &mut _free_to_me, &mut total, &mut free) };
if ret != 0 {
return Ok(unsafe { (*total.QuadPart(), *free.QuadPart()) });
return Ok((total, free));
}
let err = io::Error::last_os_error();
if err.raw_os_error() == Some(winerror::ERROR_DIRECTORY as i32) {
if err.raw_os_error() == Some(Foundation::ERROR_DIRECTORY as i32) {
if let Some(parent) = path.as_ref().parent() {
let parent = widestring::WideCString::from_os_str(parent).unwrap();
@@ -359,7 +358,7 @@ pub(crate) mod module {
return if ret == 0 {
Err(errno_err(vm))
} else {
Ok(unsafe { (*total.QuadPart(), *free.QuadPart()) })
Ok((total, free))
};
}
}
@@ -369,18 +368,22 @@ pub(crate) mod module {
#[pyfunction]
fn get_handle_inheritable(handle: intptr_t, vm: &VirtualMachine) -> PyResult<bool> {
let mut flags = 0;
if unsafe { um::handleapi::GetHandleInformation(handle as _, &mut flags) } == 0 {
if unsafe { Foundation::GetHandleInformation(handle as _, &mut flags) } == 0 {
Err(errno_err(vm))
} else {
Ok(flags & um::winbase::HANDLE_FLAG_INHERIT != 0)
Ok(flags & Foundation::HANDLE_FLAG_INHERIT != 0)
}
}
pub fn raw_set_handle_inheritable(handle: intptr_t, inheritable: bool) -> io::Result<()> {
use um::winbase::HANDLE_FLAG_INHERIT;
let flags = if inheritable { HANDLE_FLAG_INHERIT } else { 0 };
let res =
unsafe { um::handleapi::SetHandleInformation(handle as _, HANDLE_FLAG_INHERIT, flags) };
let flags = if inheritable {
Foundation::HANDLE_FLAG_INHERIT
} else {
0
};
let res = unsafe {
Foundation::SetHandleInformation(handle as _, Foundation::HANDLE_FLAG_INHERIT, flags)
};
if res == 0 {
Err(errno())
} else {
@@ -408,7 +411,7 @@ pub(crate) mod module {
let [] = dir_fd.0;
let _ = mode;
let wide = path.to_widecstring(vm)?;
let res = unsafe { um::fileapi::CreateDirectoryW(wide.as_ptr(), std::ptr::null_mut()) };
let res = unsafe { FileSystem::CreateDirectoryW(wide.as_ptr(), std::ptr::null_mut()) };
if res == 0 {
return Err(errno_err(vm));
}
@@ -424,6 +427,6 @@ pub fn init_winsock() {
static WSA_INIT: parking_lot::Once = parking_lot::Once::new();
WSA_INIT.call_once(|| unsafe {
let mut wsa_data = std::mem::MaybeUninit::uninit();
let _ = winapi::um::winsock2::WSAStartup(0x0101, wsa_data.as_mut_ptr());
let _ = windows_sys::Win32::Networking::WinSock::WSAStartup(0x0101, wsa_data.as_mut_ptr());
})
}

View File

@@ -1200,21 +1200,20 @@ pub(super) mod _os {
let res = unsafe { suppress_iph!(libc::lseek(fd, position, how)) };
#[cfg(windows)]
let res = unsafe {
use winapi::um::{fileapi, winnt};
use windows_sys::Win32::Storage::FileSystem;
let handle = Fd(fd).to_raw_handle().map_err(|e| e.into_pyexception(vm))?;
let mut li = winnt::LARGE_INTEGER::default();
*li.QuadPart_mut() = position;
let ret = fileapi::SetFilePointer(
handle,
li.u().LowPart as _,
&mut li.u_mut().HighPart,
let mut distance_to_move: [i32; 2] = std::mem::transmute(position);
let ret = FileSystem::SetFilePointer(
handle as _,
distance_to_move[0],
&mut distance_to_move[1],
how as _,
);
if ret == fileapi::INVALID_SET_FILE_POINTER {
if ret == FileSystem::INVALID_SET_FILE_POINTER {
-1
} else {
li.u_mut().LowPart = ret;
*li.QuadPart()
distance_to_move[0] = ret as _;
std::mem::transmute(distance_to_move)
}
};
if res < 0 {
@@ -1357,10 +1356,8 @@ pub(super) mod _os {
#[cfg(windows)]
{
use std::{fs::OpenOptions, os::windows::prelude::*};
use winapi::{
shared::minwindef::{DWORD, FILETIME},
um::fileapi::SetFileTime,
};
type DWORD = u32;
use windows_sys::Win32::{Foundation::FILETIME, Storage::FileSystem};
let [] = dir_fd.0;
@@ -1378,12 +1375,13 @@ pub(super) mod _os {
let f = OpenOptions::new()
.write(true)
.custom_flags(winapi::um::winbase::FILE_FLAG_BACKUP_SEMANTICS)
.custom_flags(windows_sys::Win32::Storage::FileSystem::FILE_FLAG_BACKUP_SEMANTICS)
.open(path)
.map_err(|err| err.into_pyexception(vm))?;
let ret =
unsafe { SetFileTime(f.as_raw_handle() as _, std::ptr::null(), &acc, &modif) };
let ret = unsafe {
FileSystem::SetFileTime(f.as_raw_handle() as _, std::ptr::null(), &acc, &modif)
};
if ret == 0 {
Err(io::Error::last_os_error().into_pyexception(vm))
@@ -1414,19 +1412,28 @@ pub(super) mod _os {
fn times(vm: &VirtualMachine) -> PyResult {
#[cfg(windows)]
{
use winapi::shared::minwindef::FILETIME;
use winapi::um::processthreadsapi::{GetCurrentProcess, GetProcessTimes};
use std::mem::MaybeUninit;
use windows_sys::Win32::{Foundation::FILETIME, System::Threading};
let mut _create = FILETIME::default();
let mut _exit = FILETIME::default();
let mut kernel = FILETIME::default();
let mut user = FILETIME::default();
let mut _create = MaybeUninit::<FILETIME>::uninit();
let mut _exit = MaybeUninit::<FILETIME>::uninit();
let mut kernel = MaybeUninit::<FILETIME>::uninit();
let mut user = MaybeUninit::<FILETIME>::uninit();
unsafe {
let h_proc = GetCurrentProcess();
GetProcessTimes(h_proc, &mut _create, &mut _exit, &mut kernel, &mut user);
let h_proc = Threading::GetCurrentProcess();
Threading::GetProcessTimes(
h_proc,
_create.as_mut_ptr(),
_exit.as_mut_ptr(),
kernel.as_mut_ptr(),
user.as_mut_ptr(),
);
}
let kernel = unsafe { kernel.assume_init() };
let user = unsafe { user.assume_init() };
let times_result = TimesResult {
user: user.dwHighDateTime as f64 * 429.4967296 + user.dwLowDateTime as f64 * 1e-7,
system: kernel.dwHighDateTime as f64 * 429.4967296
@@ -1596,9 +1603,10 @@ pub(super) mod _os {
if #[cfg(any(target_os = "android", target_os = "redox"))] {
Ok(Some("UTF-8".to_owned()))
} else if #[cfg(windows)] {
use windows_sys::Win32::System::Console;
let cp = match fd {
0 => unsafe { winapi::um::consoleapi::GetConsoleCP() },
1 | 2 => unsafe { winapi::um::consoleapi::GetConsoleOutputCP() },
0 => unsafe { Console::GetConsoleCP() },
1 | 2 => unsafe { Console::GetConsoleOutputCP() },
_ => 0,
};

View File

@@ -19,7 +19,6 @@ pub(crate) mod _signal {
cfg_if::cfg_if! {
if #[cfg(windows)] {
use winapi::um::winsock2;
type WakeupFd = libc::SOCKET;
const INVALID_WAKEUP: WakeupFd = (-1isize) as usize;
static WAKEUP: atomic::AtomicUsize = atomic::AtomicUsize::new(INVALID_WAKEUP);
@@ -200,14 +199,16 @@ pub(crate) mod _signal {
#[cfg(windows)]
let is_socket = if fd != INVALID_WAKEUP {
use windows_sys::Win32::Networking::WinSock;
crate::stdlib::nt::init_winsock();
let mut res = 0i32;
let mut res_size = std::mem::size_of::<i32>() as i32;
let res = unsafe {
winsock2::getsockopt(
WinSock::getsockopt(
fd,
winsock2::SOL_SOCKET,
winsock2::SO_ERROR,
WinSock::SOL_SOCKET,
WinSock::SO_ERROR,
&mut res as *mut i32 as *mut _,
&mut res_size,
)
@@ -217,7 +218,7 @@ pub(crate) mod _signal {
if !is_socket {
let err = std::io::Error::last_os_error();
// if getsockopt failed for some other reason, throw
if err.raw_os_error() != Some(winsock2::WSAENOTSOCK) {
if err.raw_os_error() != Some(WinSock::WSAENOTSOCK) {
return Err(err.into_pyexception(vm));
}
}
@@ -263,8 +264,14 @@ pub(crate) mod _signal {
let sigbyte = signum as u8;
#[cfg(windows)]
if WAKEUP_IS_SOCKET.load(Ordering::Relaxed) {
let _res =
unsafe { winsock2::send(wakeup_fd, &sigbyte as *const u8 as *const _, 1, 0) };
let _res = unsafe {
windows_sys::Win32::Networking::WinSock::send(
wakeup_fd,
&sigbyte as *const u8 as *const _,
1,
0,
)
};
return;
}
let _res = unsafe { libc::write(wakeup_fd as _, &sigbyte as *const u8 as *const _, 1) };

View File

@@ -487,18 +487,15 @@ mod sys {
fn getwindowsversion(vm: &VirtualMachine) -> PyResult<crate::builtins::tuple::PyTupleRef> {
use std::ffi::OsString;
use std::os::windows::ffi::OsStringExt;
use winapi::um::{
sysinfoapi::GetVersionExW,
winnt::{LPOSVERSIONINFOEXW, LPOSVERSIONINFOW, OSVERSIONINFOEXW},
use windows_sys::Win32::System::SystemInformation::{
GetVersionExW, OSVERSIONINFOEXW, OSVERSIONINFOW,
};
let mut version = OSVERSIONINFOEXW {
dwOSVersionInfoSize: std::mem::size_of::<OSVERSIONINFOEXW>() as u32,
..OSVERSIONINFOEXW::default()
};
let mut version: OSVERSIONINFOEXW = unsafe { std::mem::zeroed() };
version.dwOSVersionInfoSize = std::mem::size_of::<OSVERSIONINFOEXW>() as u32;
let result = unsafe {
let osvi = &mut version as LPOSVERSIONINFOEXW as LPOSVERSIONINFOW;
// SAFETY: GetVersionExW accepts a pointer of OSVERSIONINFOW, but winapi crate's type currently doesn't allow to do so.
let osvi = &mut version as *mut OSVERSIONINFOEXW as *mut OSVERSIONINFOW;
// SAFETY: GetVersionExW accepts a pointer of OSVERSIONINFOW, but windows-sys crate's type currently doesn't allow to do so.
// https://docs.microsoft.com/en-us/windows/win32/api/sysinfoapi/nf-sysinfoapi-getversionexw#parameters
GetVersionExW(osvi)
};

View File

@@ -628,42 +628,33 @@ mod platform {
PyRef, PyResult, VirtualMachine,
};
use std::time::Duration;
use winapi::shared::{minwindef::FILETIME, ntdef::ULARGE_INTEGER};
use winapi::um::processthreadsapi::{
GetCurrentProcess, GetCurrentThread, GetProcessTimes, GetThreadTimes,
use windows_sys::Win32::{
Foundation::FILETIME,
System::Performance::{QueryPerformanceCounter, QueryPerformanceFrequency},
System::SystemInformation::{GetSystemTimeAdjustment, GetTickCount64},
System::Threading::{GetCurrentProcess, GetCurrentThread, GetProcessTimes, GetThreadTimes},
};
use winapi::um::profileapi::{QueryPerformanceCounter, QueryPerformanceFrequency};
use winapi::um::sysinfoapi::{GetSystemTimeAdjustment, GetTickCount64};
fn u64_from_filetime(time: FILETIME) -> u64 {
unsafe {
let mut large = std::mem::MaybeUninit::<ULARGE_INTEGER>::uninit();
{
let m = (*large.as_mut_ptr()).u_mut();
m.LowPart = time.dwLowDateTime;
m.HighPart = time.dwHighDateTime;
}
let large = large.assume_init();
*large.QuadPart()
}
let large: [u32; 2] = [time.dwLowDateTime, time.dwHighDateTime];
unsafe { std::mem::transmute(large) }
}
fn win_perf_counter_frequency(vm: &VirtualMachine) -> PyResult<i64> {
let freq = unsafe {
let frequency = unsafe {
let mut freq = std::mem::MaybeUninit::uninit();
if QueryPerformanceFrequency(freq.as_mut_ptr()) == 0 {
return Err(errno_err(vm));
}
freq.assume_init()
};
let frequency = unsafe { freq.QuadPart() };
if *frequency < 1 {
if frequency < 1 {
Err(vm.new_runtime_error("invalid QueryPerformanceFrequency".to_owned()))
} else if *frequency > i64::MAX / SEC_TO_NS {
} else if frequency > i64::MAX / SEC_TO_NS {
Err(vm.new_overflow_error("QueryPerformanceFrequency is too large".to_owned()))
} else {
Ok(*frequency)
Ok(frequency)
}
}
@@ -677,15 +668,14 @@ mod platform {
}
pub(super) fn get_perf_time(vm: &VirtualMachine) -> PyResult<Duration> {
let now = unsafe {
let ticks = unsafe {
let mut performance_count = std::mem::MaybeUninit::uninit();
QueryPerformanceCounter(performance_count.as_mut_ptr());
performance_count.assume_init()
};
let ticks = unsafe { now.QuadPart() };
Ok(Duration::from_nanos(time_muldiv(
*ticks,
ticks,
SEC_TO_NS,
global_frequency(vm)?,
)))

View File

@@ -34,18 +34,18 @@ mod winreg {
};
use ::winreg::{enums::RegType, RegKey, RegValue};
use std::{ffi::OsStr, io};
use winapi::shared::winerror;
use windows_sys::Win32::Foundation;
// access rights
#[pyattr]
pub use winapi::um::winnt::{
pub use windows_sys::Win32::System::Registry::{
KEY_ALL_ACCESS, KEY_CREATE_LINK, KEY_CREATE_SUB_KEY, KEY_ENUMERATE_SUB_KEYS, KEY_EXECUTE,
KEY_NOTIFY, KEY_QUERY_VALUE, KEY_READ, KEY_SET_VALUE, KEY_WOW64_32KEY, KEY_WOW64_64KEY,
KEY_WRITE,
};
// value types
#[pyattr]
pub use winapi::um::winnt::{
pub use windows_sys::Win32::System::Registry::{
REG_BINARY, REG_DWORD, REG_DWORD_BIG_ENDIAN, REG_DWORD_LITTLE_ENDIAN, REG_EXPAND_SZ,
REG_FULL_RESOURCE_DESCRIPTOR, REG_LINK, REG_MULTI_SZ, REG_NONE, REG_QWORD,
REG_QWORD_LITTLE_ENDIAN, REG_RESOURCE_LIST, REG_RESOURCE_REQUIREMENTS_LIST, REG_SZ,
@@ -201,7 +201,7 @@ mod winreg {
key.with_key(|k| k.enum_keys().nth(index as usize))
.unwrap_or_else(|| {
Err(io::Error::from_raw_os_error(
winerror::ERROR_NO_MORE_ITEMS as i32,
Foundation::ERROR_NO_MORE_ITEMS as i32,
))
})
.map_err(|e| e.to_pyexception(vm))
@@ -217,7 +217,7 @@ mod winreg {
.with_key(|k| k.enum_values().nth(index as usize))
.unwrap_or_else(|| {
Err(io::Error::from_raw_os_error(
winerror::ERROR_NO_MORE_ITEMS as i32,
Foundation::ERROR_NO_MORE_ITEMS as i32,
))
})
.map_err(|e| e.to_pyexception(vm))?;

View File

@@ -4,7 +4,7 @@ use crate::{
PyObjectRef, PyResult, TryFromObject, VirtualMachine,
};
use windows::Win32::Foundation::HANDLE;
use windows_sys::Win32::Foundation::{BOOL, HANDLE as RAW_HANDLE};
use windows_sys::Win32::Foundation::{BOOL, HANDLE as RAW_HANDLE, INVALID_HANDLE_VALUE};
pub(crate) trait WindowsSysResultValue {
type Ok: ToPyObject;
@@ -15,7 +15,7 @@ pub(crate) trait WindowsSysResultValue {
impl WindowsSysResultValue for RAW_HANDLE {
type Ok = HANDLE;
fn is_err(&self) -> bool {
*self == windows_sys::Win32::Foundation::INVALID_HANDLE_VALUE
*self == INVALID_HANDLE_VALUE
}
fn into_ok(self) -> Self::Ok {
HANDLE(self)