diff --git a/Cargo.toml b/Cargo.toml index a3fff58..161b3a3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,7 +19,7 @@ bitflags = "1.3" which = "4.1.0" [dependencies.windows] -version = "0.39.0" +version = "0.40.0" features = [ "Win32_Foundation", "Win32_Storage_FileSystem", @@ -34,7 +34,7 @@ features = [ ] [build-dependencies.windows] -version = "0.39.0" +version = "0.40.0" features = [ "Win32_Foundation", "Win32_System_LibraryLoader" diff --git a/src/pty/base.rs b/src/pty/base.rs index ad1c961..16d38eb 100644 --- a/src/pty/base.rs +++ b/src/pty/base.rs @@ -3,10 +3,10 @@ use windows::Win32::Foundation::{HANDLE, S_OK, STATUS_PENDING, CloseHandle, WAIT_FAILED, WAIT_TIMEOUT}; use windows::Win32::Storage::FileSystem::{GetFileSizeEx, ReadFile, WriteFile}; use windows::Win32::System::Pipes::PeekNamedPipe; -use windows::Win32::System::IO::{OVERLAPPED, CancelIoEx}; +use windows::Win32::System::IO::{CancelIoEx}; use windows::Win32::System::Threading::{GetExitCodeProcess, GetProcessId, WaitForSingleObject}; use windows::Win32::Globalization::{MultiByteToWideChar, WideCharToMultiByte, CP_UTF8, MULTI_BYTE_TO_WIDE_CHAR_FLAGS}; -use windows::core::{HRESULT, Error, PSTR, PCSTR}; +use windows::core::{HRESULT, Error, PCSTR}; use std::ptr; use std::sync::mpsc; @@ -14,7 +14,7 @@ use std::thread; use std::time::Duration; use std::mem::MaybeUninit; use std::cmp::min; -use std::ffi::{OsString, c_void}; +use std::ffi::{OsString}; #[cfg(windows)] use std::os::windows::prelude::*; #[cfg(windows)] @@ -129,13 +129,16 @@ fn read(mut length: u32, blocking: bool, stream: HANDLE, using_pipes: bool) -> R if !blocking { if using_pipes { let mut bytes_u = MaybeUninit::::uninit(); - let bytes_ptr = bytes_u.as_mut_ptr(); + //let mut available_bytes = Box::<>::new_uninit(); //let bytes_ptr: *mut u32 = &mut *available_bytes; unsafe { + let bytes_ptr = ptr::addr_of_mut!(*bytes_u.as_mut_ptr()); + let bytes_ref = bytes_ptr.as_mut().unwrap(); + result = - if PeekNamedPipe(stream, ptr::null_mut::(), 0, - ptr::null_mut::(), bytes_ptr, ptr::null_mut::()).as_bool() { + if PeekNamedPipe(stream, None, + None, Some(bytes_ref), None).as_bool() { S_OK } else { Error::from_win32().into() @@ -158,7 +161,9 @@ fn read(mut length: u32, blocking: bool, stream: HANDLE, using_pipes: bool) -> R // let size_ptr: *mut i64 = ptr::null_mut(); unsafe { let size_ptr = ptr::addr_of_mut!(*size.as_mut_ptr()); - result = if GetFileSizeEx(stream, size_ptr).as_bool() { S_OK } else { Error::from_win32().into() }; + let size_ref = size_ptr.as_mut().unwrap(); + // let size_ref = *size.as_mut_ptr(); + result = if GetFileSizeEx(stream, size_ref).as_bool() { S_OK } else { Error::from_win32().into() }; if result.is_err() { let result_msg = result.message(); @@ -177,30 +182,26 @@ fn read(mut length: u32, blocking: bool, stream: HANDLE, using_pipes: bool) -> R let os_str = "\0".repeat((length + 1) as usize); let mut buf_vec: Vec = os_str.as_str().as_bytes().to_vec(); let mut chars_read = MaybeUninit::::uninit(); - let total_bytes: u32; //let chars_read: *mut u32 = ptr::null_mut(); - let null_overlapped: *mut OVERLAPPED = ptr::null_mut(); // println!("Length: {}, {}", length, length > 0); // if length > 0 { unsafe { match length { 0 => { - total_bytes = 0; + } _ => { - let buf_ptr = buf_vec.as_mut_ptr(); - let buf_void = buf_ptr as *mut c_void; + // let chars_read_ptr = chars_read.as_mut_ptr(); let chars_read_ptr = ptr::addr_of_mut!(*chars_read.as_mut_ptr()); + let chars_read_mut = chars_read_ptr.as_mut(); // println!("Blocked here"); result = - if ReadFile(stream, buf_void, length, chars_read_ptr, null_overlapped).as_bool() { + if ReadFile(stream, Some(&mut buf_vec[..]), chars_read_mut, None).as_bool() { S_OK } else { Error::from_win32().into() }; // println!("Unblocked here"); - total_bytes = *chars_read_ptr; - chars_read.assume_init(); if result.is_err() { let result_msg = result.message(); @@ -218,7 +219,8 @@ fn read(mut length: u32, blocking: bool, stream: HANDLE, using_pipes: bool) -> R unsafe { MultiByteToWideChar( - CP_UTF8, MULTI_BYTE_TO_WIDE_CHAR_FLAGS(0), &buf_vec[..], &mut vec_buf[..]); + CP_UTF8, MULTI_BYTE_TO_WIDE_CHAR_FLAGS(0), &buf_vec[..], + Some(&mut vec_buf[..])); } // let non_zeros: Vec = vec_buf.split(|elem| *elem == 0 as u16).collect(); @@ -239,10 +241,10 @@ fn read(mut length: u32, blocking: bool, stream: HANDLE, using_pipes: bool) -> R fn is_alive(process: HANDLE) -> Result { unsafe { let is_timeout = WaitForSingleObject(process, 0); - let succ = is_timeout != WAIT_FAILED.0; + let succ = is_timeout != WAIT_FAILED; if succ { - let alive = is_timeout == WAIT_TIMEOUT.0; + let alive = is_timeout == WAIT_TIMEOUT; Ok(alive) } else { let err: HRESULT = Error::from_win32().into(); @@ -258,7 +260,8 @@ fn get_exitstatus(process: HANDLE) -> Result, OsString> { let mut exit = MaybeUninit::::uninit(); unsafe { let exit_ptr: *mut u32 = ptr::addr_of_mut!(*exit.as_mut_ptr()); - let succ = GetExitCodeProcess(process, exit_ptr).as_bool(); + let exit_ref = exit_ptr.as_mut().unwrap(); + let succ = GetExitCodeProcess(process, exit_ref).as_bool(); if succ { let actual_exit = *exit_ptr; @@ -283,9 +286,9 @@ fn is_eof(process: HANDLE, stream: HANDLE) -> Result { let mut bytes = MaybeUninit::::uninit(); unsafe { let bytes_ptr: *mut u32 = ptr::addr_of_mut!(*bytes.as_mut_ptr()); + let bytes_ref = bytes_ptr.as_mut(); let succ = PeekNamedPipe( - stream, ptr::null_mut::(), 0, - ptr::null_mut::(), bytes_ptr, ptr::null_mut::()).as_bool(); + stream, None, None, bytes_ref, None).as_bool(); let total_bytes = bytes.assume_init(); if succ { @@ -480,29 +483,26 @@ impl PTYProcess { /// an [`OsString`] containing an human-readable error. pub fn write(&self, buf: OsString) -> Result { let vec_buf: Vec = buf.encode_wide().collect(); - - let null_overlapped: *mut OVERLAPPED = ptr::null_mut(); let result: HRESULT; unsafe { let required_size = WideCharToMultiByte( - CP_UTF8, 0, &vec_buf[..], PSTR(ptr::null_mut::()), - 0, PCSTR(ptr::null_mut::()), ptr::null_mut::()); + CP_UTF8, 0, &vec_buf[..], None, + PCSTR(ptr::null_mut::()), None); let mut bytes_buf: Vec = std::iter::repeat(0).take((required_size) as usize).collect(); - let bytes_buf_ptr = bytes_buf.as_mut_ptr(); - let pstr = PSTR(bytes_buf_ptr); WideCharToMultiByte( - CP_UTF8, 0, &vec_buf[..], pstr, - required_size, PCSTR(ptr::null_mut::()), - ptr::null_mut::()); + CP_UTF8, 0, &vec_buf[..], Some(&mut bytes_buf[..]), + PCSTR(ptr::null_mut::()), + None); let mut written_bytes = MaybeUninit::::uninit(); let bytes_ptr: *mut u32 = ptr::addr_of_mut!(*written_bytes.as_mut_ptr()); + let bytes_ref = bytes_ptr.as_mut(); result = - if WriteFile(self.conin, bytes_buf[..].as_ptr() as *const c_void, bytes_buf.len() as u32, bytes_ptr, null_overlapped).as_bool() { + if WriteFile(self.conin, Some(&bytes_buf[..]), bytes_ref, None).as_bool() { S_OK } else { Error::from_win32().into() @@ -531,9 +531,9 @@ impl PTYProcess { let mut bytes = MaybeUninit::::uninit(); unsafe { let bytes_ptr: *mut u32 = ptr::addr_of_mut!(*bytes.as_mut_ptr()); + let bytes_ref = bytes_ptr.as_mut(); let mut succ = PeekNamedPipe( - self.conout, ptr::null_mut::(), 0, - ptr::null_mut::(), bytes_ptr, ptr::null_mut::()).as_bool(); + self.conout, None, None, bytes_ref, None).as_bool(); let total_bytes = bytes.assume_init(); @@ -624,7 +624,7 @@ impl Drop for PTYProcess { if self.reader_process_out.send(None).is_ok() { } // Cancel all pending IO operations on conout - CancelIoEx(self.conout, ptr::null()); + CancelIoEx(self.conout, None); // Send instruction to thread to finish if self.reader_alive.send(false).is_ok() { } diff --git a/src/pty/conpty/pty_impl.rs b/src/pty/conpty/pty_impl.rs index dc978f2..db915b6 100644 --- a/src/pty/conpty/pty_impl.rs +++ b/src/pty/conpty/pty_impl.rs @@ -71,7 +71,7 @@ impl PTYImpl for ConPTY { let h_console_res = CreateFileW( conout_pwstr, FILE_GENERIC_READ | FILE_GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, - ptr::null(), OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, HANDLE(0)); + None, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, HANDLE(0)); if let Err(err) = h_console_res { let result_msg = err.message(); @@ -89,7 +89,7 @@ impl PTYImpl for ConPTY { let h_in_res = CreateFileW( conin_pwstr, FILE_GENERIC_READ | FILE_GENERIC_WRITE, - FILE_SHARE_READ, ptr::null(), + FILE_SHARE_READ, None, OPEN_EXISTING, FILE_FLAGS_AND_ATTRIBUTES(0), HANDLE(0)); @@ -103,10 +103,10 @@ impl PTYImpl for ConPTY { let h_in = h_in_res.unwrap(); let mut console_mode_un = MaybeUninit::::uninit(); - let console_mode_ptr = console_mode_un.as_mut_ptr(); + let console_mode_ref = console_mode_un.as_mut_ptr(); result = - if GetConsoleMode(h_console, console_mode_ptr).as_bool() { + if GetConsoleMode(h_console, console_mode_ref.as_mut().unwrap()).as_bool() { S_OK } else { Error::from_win32().into() @@ -175,7 +175,7 @@ impl PTYImpl for ConPTY { // Setup PTY size let size = COORD {X: args.cols as i16, Y: args.rows as i16}; - if !CreatePipe(&mut input_read_side, &mut input_write_side, ptr::null(), 0).as_bool() { + if !CreatePipe(&mut input_read_side, &mut input_write_side, None, 0).as_bool() { result = Error::from_win32().into(); let result_msg = result.message(); let err_msg: &[u16] = result_msg.as_wide(); @@ -183,7 +183,7 @@ impl PTYImpl for ConPTY { return Err(string); } - if !CreatePipe(&mut output_read_side, &mut output_write_side, ptr::null(), 0).as_bool() { + if !CreatePipe(&mut output_read_side, &mut output_write_side, None, 0).as_bool() { result = Error::from_win32().into(); let result_msg = result.message(); let err_msg: &[u16] = result_msg.as_wide(); @@ -255,7 +255,8 @@ impl PTYImpl for ConPTY { let mut required_bytes_u = MaybeUninit::::uninit(); let required_bytes_ptr = required_bytes_u.as_mut_ptr(); InitializeProcThreadAttributeList( - LPPROC_THREAD_ATTRIBUTE_LIST(ptr::null_mut()), 1, 0, required_bytes_ptr); + LPPROC_THREAD_ATTRIBUTE_LIST(ptr::null_mut()), 1, 0, + required_bytes_ptr.as_mut().unwrap()); // Allocate memory to represent the list let mut required_bytes = required_bytes_u.assume_init(); @@ -285,7 +286,7 @@ impl PTYImpl for ConPTY { if !UpdateProcThreadAttribute( start_info.lpAttributeList, 0, 0x00020016, self.handle.0 as _, mem::size_of::(), - ptr::null_mut(), ptr::null_mut()).as_bool() { + ptr::null_mut(), None).as_bool() { result = Error::from_win32().into(); let result_msg = result.message(); let err_msg: &[u16] = result_msg.as_wide(); @@ -294,20 +295,21 @@ impl PTYImpl for ConPTY { } self.startup_info = start_info; - let pi_ptr = &mut self.process_info as *mut _; let si_ptr = &start_info as *const STARTUPINFOEXW; + let si_ptr_addr = si_ptr as usize; + let si_w_ptr = si_ptr_addr as *const STARTUPINFOW; let succ = CreateProcessW( PCWSTR(ptr::null_mut()), PWSTR(cmd), - ptr::null_mut(), - ptr::null_mut(), + None, + None, false, EXTENDED_STARTUPINFO_PRESENT | CREATE_UNICODE_ENVIRONMENT, environ as _, PCWSTR(working_dir), - si_ptr as *const _, - pi_ptr + si_w_ptr.as_ref().unwrap(), + &mut self.process_info ).as_bool(); if !succ { diff --git a/src/pty/winpty/pty_impl.rs b/src/pty/winpty/pty_impl.rs index 1011796..439e912 100644 --- a/src/pty/winpty/pty_impl.rs +++ b/src/pty/winpty/pty_impl.rs @@ -170,7 +170,7 @@ impl PTYImpl for WinPTY { let empty_handle = HANDLE(0); let conin_res = CreateFileW( - PCWSTR(conin_name as *const u16), FILE_GENERIC_WRITE, FILE_SHARE_NONE, ptr::null(), + PCWSTR(conin_name as *const u16), FILE_GENERIC_WRITE, FILE_SHARE_NONE, None, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, empty_handle ); @@ -182,7 +182,7 @@ impl PTYImpl for WinPTY { } let conout_res = CreateFileW( - PCWSTR(conout_name as *mut u16), FILE_GENERIC_READ, FILE_SHARE_NONE, ptr::null(), + PCWSTR(conout_name as *mut u16), FILE_GENERIC_READ, FILE_SHARE_NONE, None, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, empty_handle );