Use new bindings

This commit is contained in:
Chris Denton 2023-04-06 17:27:47 +01:00
parent e92ee03559
commit 3ffb27ff89
No known key found for this signature in database
GPG Key ID: 713472F2F45627DE
12 changed files with 70 additions and 53 deletions

View File

@ -110,7 +110,7 @@ impl BorrowedSocket<'_> {
/// object as the existing `BorrowedSocket` instance.
#[stable(feature = "io_safety", since = "1.63.0")]
pub fn try_clone_to_owned(&self) -> io::Result<OwnedSocket> {
let mut info = unsafe { mem::zeroed::<c::WSAPROTOCOL_INFO>() };
let mut info = unsafe { mem::zeroed::<c::WSAPROTOCOL_INFOW>() };
let result = unsafe {
c::WSADuplicateSocketW(self.as_raw_socket(), c::GetCurrentProcessId(), &mut info)
};

View File

@ -114,17 +114,20 @@ impl Module {
/// (e.g. kernel32 and ntdll).
pub unsafe fn new(name: &CStr) -> Option<Self> {
// SAFETY: A CStr is always null terminated.
let module = c::GetModuleHandleA(name.as_ptr());
let module = c::GetModuleHandleA(name.as_ptr().cast::<u8>());
NonNull::new(module).map(Self)
}
// Try to get the address of a function.
pub fn proc_address(self, name: &CStr) -> Option<NonNull<c_void>> {
// SAFETY:
// `self.0` will always be a valid module.
// A CStr is always null terminated.
let proc = unsafe { c::GetProcAddress(self.0.as_ptr(), name.as_ptr()) };
NonNull::new(proc)
unsafe {
// SAFETY:
// `self.0` will always be a valid module.
// A CStr is always null terminated.
let proc = c::GetProcAddress(self.0.as_ptr(), name.as_ptr().cast::<u8>());
// SAFETY: `GetProcAddress` returns None on null.
proc.map(|p| NonNull::new_unchecked(p as *mut c_void))
}
}
}
@ -199,6 +202,7 @@ macro_rules! compat_fn_optional {
)+) => (
$(
pub mod $symbol {
#[allow(unused_imports)]
use super::*;
use crate::ffi::c_void;
use crate::mem;

View File

@ -89,6 +89,12 @@ pub struct FileTimes {
accessed: Option<c::FILETIME>,
modified: Option<c::FILETIME>,
}
impl core::fmt::Debug for c::FILETIME {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let time = ((self.dwHighDateTime as u64) << 32) | self.dwLowDateTime as u64;
f.debug_tuple("FILETIME").field(&time).finish()
}
}
#[derive(Debug)]
pub struct DirBuilder;
@ -290,6 +296,7 @@ impl File {
ptr::null_mut(),
)
};
let handle = unsafe { HandleOrInvalid::from_raw_handle(handle) };
if let Ok(handle) = handle.try_into() {
Ok(File { handle: Handle::from_inner(handle) })
} else {
@ -501,7 +508,8 @@ impl File {
}
fn readlink(&self) -> io::Result<PathBuf> {
let mut space = Align8([MaybeUninit::<u8>::uninit(); c::MAXIMUM_REPARSE_DATA_BUFFER_SIZE]);
let mut space =
Align8([MaybeUninit::<u8>::uninit(); c::MAXIMUM_REPARSE_DATA_BUFFER_SIZE as usize]);
let (_bytes, buf) = self.reparse_point(&mut space)?;
unsafe {
let (path_buffer, subst_off, subst_len, relative) = match (*buf).ReparseTag {
@ -589,7 +597,11 @@ impl File {
));
}
cvt(unsafe {
c::SetFileTime(self.as_handle(), None, times.accessed.as_ref(), times.modified.as_ref())
let accessed =
times.accessed.as_ref().map(|a| a as *const c::FILETIME).unwrap_or(ptr::null());
let modified =
times.modified.as_ref().map(|a| a as *const c::FILETIME).unwrap_or(ptr::null());
c::SetFileTime(self.as_raw_handle(), ptr::null_mut(), accessed, modified)
})?;
Ok(())
}
@ -618,9 +630,9 @@ impl File {
/// then errors will be `ERROR_NOT_SUPPORTED` or `ERROR_INVALID_PARAMETER`.
fn posix_delete(&self) -> io::Result<()> {
let mut info = c::FILE_DISPOSITION_INFO_EX {
Flags: c::FILE_DISPOSITION_DELETE
| c::FILE_DISPOSITION_POSIX_SEMANTICS
| c::FILE_DISPOSITION_IGNORE_READONLY_ATTRIBUTE,
Flags: c::FILE_DISPOSITION_FLAG_DELETE
| c::FILE_DISPOSITION_FLAG_POSIX_SEMANTICS
| c::FILE_DISPOSITION_FLAG_IGNORE_READONLY_ATTRIBUTE,
};
let size = mem::size_of_val(&info);
cvt(unsafe {
@ -791,15 +803,15 @@ fn open_link_no_reparse(parent: &File, name: &[u16], access: u32) -> io::Result<
// See https://docs.microsoft.com/en-us/windows/win32/api/winternl/nf-winternl-ntcreatefile
unsafe {
let mut handle = ptr::null_mut();
let mut io_status = c::IO_STATUS_BLOCK::default();
let name_str = c::UNICODE_STRING::from_ref(name);
let mut io_status = c::IO_STATUS_BLOCK::PENDING;
let mut name_str = c::UNICODE_STRING::from_ref(name);
use crate::sync::atomic::{AtomicU32, Ordering};
// The `OBJ_DONT_REPARSE` attribute ensures that we haven't been
// tricked into following a symlink. However, it may not be available in
// earlier versions of Windows.
static ATTRIBUTES: AtomicU32 = AtomicU32::new(c::OBJ_DONT_REPARSE);
let object = c::OBJECT_ATTRIBUTES {
ObjectName: &name_str,
let mut object = c::OBJECT_ATTRIBUTES {
ObjectName: &mut name_str,
RootDirectory: parent.as_raw_handle(),
Attributes: ATTRIBUTES.load(Ordering::Relaxed),
..c::OBJECT_ATTRIBUTES::default()
@ -807,7 +819,7 @@ fn open_link_no_reparse(parent: &File, name: &[u16], access: u32) -> io::Result<
let status = c::NtCreateFile(
&mut handle,
access,
&object,
&mut object,
&mut io_status,
crate::ptr::null_mut(),
0,
@ -1368,7 +1380,7 @@ pub fn copy(from: &Path, to: &Path) -> io::Result<u64> {
_dwCallbackReason: c::DWORD,
_hSourceFile: c::HANDLE,
_hDestinationFile: c::HANDLE,
lpData: c::LPVOID,
lpData: c::LPCVOID,
) -> c::DWORD {
if dwStreamNumber == 1 {
*(lpData as *mut i64) = StreamBytesTransferred;
@ -1415,9 +1427,10 @@ fn symlink_junction_inner(original: &Path, junction: &Path) -> io::Result<()> {
let f = File::open(junction, &opts)?;
let h = f.as_inner().as_raw_handle();
unsafe {
let mut data = Align8([MaybeUninit::<u8>::uninit(); c::MAXIMUM_REPARSE_DATA_BUFFER_SIZE]);
let mut data =
Align8([MaybeUninit::<u8>::uninit(); c::MAXIMUM_REPARSE_DATA_BUFFER_SIZE as usize]);
let data_ptr = data.0.as_mut_ptr();
let data_end = data_ptr.add(c::MAXIMUM_REPARSE_DATA_BUFFER_SIZE);
let data_end = data_ptr.add(c::MAXIMUM_REPARSE_DATA_BUFFER_SIZE as usize);
let db = data_ptr.cast::<c::REPARSE_MOUNTPOINT_DATA_BUFFER>();
// Zero the header to ensure it's fully initialized, including reserved parameters.
*db = mem::zeroed();

View File

@ -144,7 +144,7 @@ impl Handle {
let len = cmp::min(buf.len(), <c::DWORD>::MAX as usize) as c::DWORD;
let mut amt = 0;
let res = cvt(c::ReadFile(
self.as_handle(),
self.as_raw_handle(),
buf.as_ptr() as c::LPVOID,
len,
&mut amt,
@ -235,7 +235,7 @@ impl Handle {
len: usize,
offset: Option<u64>,
) -> io::Result<usize> {
let mut io_status = c::IO_STATUS_BLOCK::default();
let mut io_status = c::IO_STATUS_BLOCK::PENDING;
// The length is clamped at u32::MAX.
let len = cmp::min(len, c::DWORD::MAX as usize) as c::DWORD;
@ -283,7 +283,7 @@ impl Handle {
///
/// If `offset` is `None` then the current file position is used.
fn synchronous_write(&self, buf: &[u8], offset: Option<u64>) -> io::Result<usize> {
let mut io_status = c::IO_STATUS_BLOCK::default();
let mut io_status = c::IO_STATUS_BLOCK::PENDING;
// The length is clamped at u32::MAX.
let len = cmp::min(buf.len(), c::DWORD::MAX as usize) as c::DWORD;

View File

@ -17,10 +17,7 @@ impl<'a> IoSlice<'a> {
pub fn new(buf: &'a [u8]) -> IoSlice<'a> {
assert!(buf.len() <= c::ULONG::MAX as usize);
IoSlice {
vec: c::WSABUF {
len: buf.len() as c::ULONG,
buf: buf.as_ptr() as *mut u8 as *mut c::CHAR,
},
vec: c::WSABUF { len: buf.len() as c::ULONG, buf: buf.as_ptr() as *mut u8 },
_p: PhantomData,
}
}
@ -54,7 +51,7 @@ impl<'a> IoSliceMut<'a> {
pub fn new(buf: &'a mut [u8]) -> IoSliceMut<'a> {
assert!(buf.len() <= c::ULONG::MAX as usize);
IoSliceMut {
vec: c::WSABUF { len: buf.len() as c::ULONG, buf: buf.as_mut_ptr() as *mut c::CHAR },
vec: c::WSABUF { len: buf.len() as c::ULONG, buf: buf.as_mut_ptr() },
_p: PhantomData,
}
}

View File

@ -263,7 +263,7 @@ impl Socket {
&mut nread,
&mut flags,
ptr::null_mut(),
ptr::null_mut(),
None,
)
};
@ -347,7 +347,7 @@ impl Socket {
&mut nwritten,
0,
ptr::null_mut(),
ptr::null_mut(),
None,
)
};
cvt(result).map(|_| nwritten as usize)

View File

@ -373,7 +373,7 @@ impl AnonPipe {
// Asynchronous read of the pipe.
// If successful, `callback` will be called once it completes.
let result = io(self.inner.as_handle(), buf, len, &mut overlapped, callback);
let result = io(self.inner.as_handle(), buf, len, &mut overlapped, Some(callback));
if result == c::FALSE {
// We can return here because the call failed.
// After this we must not return until the I/O completes.

View File

@ -308,7 +308,7 @@ impl Command {
let stderr = stderr.to_handle(c::STD_ERROR_HANDLE, &mut pipes.stderr)?;
let mut si = zeroed_startupinfo();
si.cb = mem::size_of::<c::STARTUPINFO>() as c::DWORD;
si.cb = mem::size_of::<c::STARTUPINFOW>() as c::DWORD;
// If at least one of stdin, stdout or stderr are set (i.e. are non null)
// then set the `hStd` fields in `STARTUPINFO`.
@ -332,7 +332,7 @@ impl Command {
flags,
envp,
dirp,
&mut si,
&si,
&mut pi,
))
}?;
@ -720,8 +720,8 @@ impl From<u32> for ExitCode {
}
}
fn zeroed_startupinfo() -> c::STARTUPINFO {
c::STARTUPINFO {
fn zeroed_startupinfo() -> c::STARTUPINFOW {
c::STARTUPINFOW {
cb: 0,
lpReserved: ptr::null_mut(),
lpDesktop: ptr::null_mut(),
@ -731,7 +731,7 @@ fn zeroed_startupinfo() -> c::STARTUPINFO {
dwXSize: 0,
dwYSize: 0,
dwXCountChars: 0,
dwYCountCharts: 0,
dwYCountChars: 0,
dwFillAttribute: 0,
dwFlags: 0,
wShowWindow: 0,

View File

@ -1,3 +1,4 @@
use crate::ffi::c_void;
use crate::io;
use crate::mem;
use crate::ptr;
@ -25,8 +26,9 @@ pub fn hashmap_random_keys() -> (u64, u64) {
#[inline(never)]
fn fallback_rng() -> (u64, u64) {
let mut v = (0, 0);
let ret =
unsafe { c::RtlGenRandom(&mut v as *mut _ as *mut u8, mem::size_of_val(&v) as c::ULONG) };
let ret = unsafe {
c::RtlGenRandom(&mut v as *mut _ as *mut c_void, mem::size_of_val(&v) as c::ULONG)
};
if ret != 0 { v } else { panic!("fallback RNG broken: {}", io::Error::last_os_error()) }
}

View File

@ -18,7 +18,7 @@ impl Handler {
}
}
extern "system" fn vectored_handler(ExceptionInfo: *mut c::EXCEPTION_POINTERS) -> c::LONG {
unsafe extern "system" fn vectored_handler(ExceptionInfo: *mut c::EXCEPTION_POINTERS) -> c::LONG {
unsafe {
let rec = &(*(*ExceptionInfo).ExceptionRecord);
let code = rec.ExceptionCode;
@ -34,7 +34,7 @@ extern "system" fn vectored_handler(ExceptionInfo: *mut c::EXCEPTION_POINTERS) -
}
pub unsafe fn init() {
if c::AddVectoredExceptionHandler(0, vectored_handler).is_null() {
if c::AddVectoredExceptionHandler(0, Some(vectored_handler)).is_null() {
panic!("failed to install exception handler");
}
// Set the thread stack guarantee for the main thread.

View File

@ -180,7 +180,7 @@ fn write_valid_utf8_to_console(handle: c::HANDLE, utf8: &str) -> io::Result<usiz
let result = c::MultiByteToWideChar(
c::CP_UTF8, // CodePage
c::MB_ERR_INVALID_CHARS, // dwFlags
utf8.as_ptr() as c::LPCCH, // lpMultiByteStr
utf8.as_ptr(), // lpMultiByteStr
utf8.len() as c::c_int, // cbMultiByte
utf16.as_mut_ptr() as c::LPWSTR, // lpWideCharStr
utf16.len() as c::c_int, // cchWideChar
@ -344,7 +344,7 @@ fn read_u16s(handle: c::HANDLE, buf: &mut [MaybeUninit<u16>]) -> io::Result<usiz
// See #38274 and https://stackoverflow.com/questions/43836040/win-api-readconsole.
const CTRL_Z: u16 = 0x1A;
const CTRL_Z_MASK: c::ULONG = 1 << CTRL_Z;
let mut input_control = c::CONSOLE_READCONSOLE_CONTROL {
let input_control = c::CONSOLE_READCONSOLE_CONTROL {
nLength: crate::mem::size_of::<c::CONSOLE_READCONSOLE_CONTROL>() as c::ULONG,
nInitialChars: 0,
dwCtrlWakeupMask: CTRL_Z_MASK,
@ -360,7 +360,7 @@ fn read_u16s(handle: c::HANDLE, buf: &mut [MaybeUninit<u16>]) -> io::Result<usiz
buf.as_mut_ptr() as c::LPVOID,
buf.len() as u32,
&mut amount,
&mut input_control as c::PCONSOLE_READCONSOLE_CONTROL,
&input_control,
)
})?;
@ -385,14 +385,14 @@ fn utf16_to_utf8(utf16: &[u16], utf8: &mut [u8]) -> io::Result<usize> {
let result = unsafe {
c::WideCharToMultiByte(
c::CP_UTF8, // CodePage
c::WC_ERR_INVALID_CHARS, // dwFlags
utf16.as_ptr(), // lpWideCharStr
utf16.len() as c::c_int, // cchWideChar
utf8.as_mut_ptr() as c::LPSTR, // lpMultiByteStr
utf8.len() as c::c_int, // cbMultiByte
ptr::null(), // lpDefaultChar
ptr::null_mut(), // lpUsedDefaultChar
c::CP_UTF8, // CodePage
c::WC_ERR_INVALID_CHARS, // dwFlags
utf16.as_ptr(), // lpWideCharStr
utf16.len() as c::c_int, // cchWideChar
utf8.as_mut_ptr(), // lpMultiByteStr
utf8.len() as c::c_int, // cbMultiByte
ptr::null(), // lpDefaultChar
ptr::null_mut(), // lpUsedDefaultChar
)
};
if result == 0 {

View File

@ -2,6 +2,7 @@ use crate::ffi::CStr;
use crate::io;
use crate::num::NonZeroUsize;
use crate::os::windows::io::AsRawHandle;
use crate::os::windows::io::HandleOrNull;
use crate::ptr;
use crate::sys::c;
use crate::sys::handle::Handle;
@ -32,12 +33,12 @@ impl Thread {
let ret = c::CreateThread(
ptr::null_mut(),
stack,
thread_start,
Some(thread_start),
p as *mut _,
c::STACK_SIZE_PARAM_IS_A_RESERVATION,
ptr::null_mut(),
);
let ret = HandleOrNull::from_raw_handle(ret);
return if let Ok(handle) = ret.try_into() {
Ok(Thread { handle: Handle::from_inner(handle) })
} else {