From 27cf4e55245e0040e715e0c43893c8e1369e7529 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 23 Jun 2022 14:47:07 +0000 Subject: [PATCH 1/3] Update windows requirement from 0.29.0 to 0.38.0 Updates the requirements on [windows](https://github.com/microsoft/windows-rs) to permit the latest version. - [Release notes](https://github.com/microsoft/windows-rs/releases) - [Commits](https://github.com/microsoft/windows-rs/compare/0.29.0...0.38.0) --- updated-dependencies: - dependency-name: windows dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- Cargo.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 407aa0a..0528ff9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,7 +19,7 @@ bitflags = "1.3" which = "4.1.0" [dependencies.windows] -version = "0.29.0" +version = "0.38.0" features = [ "Win32_Foundation", "Win32_Storage_FileSystem", @@ -34,7 +34,7 @@ features = [ ] [build-dependencies.windows] -version = "0.29.0" +version = "0.38.0" features = [ "Win32_Foundation", "Win32_System_LibraryLoader" From e44e071bcb45ab7a80947e4bd1f1284706937785 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edgar=20Andr=C3=A9s=20Margffoy=20Tuay?= Date: Tue, 5 Jul 2022 17:09:08 -0500 Subject: [PATCH 2/3] Fix compilation errors --- build.rs | 39 +++++++++++++++++++++++-- src/pty/base.rs | 29 +++++++++--------- src/pty/conpty/pty_impl.rs | 60 +++++++++++++++++++------------------- src/pty/winpty/pty_impl.rs | 28 ++++++++++++++---- 4 files changed, 104 insertions(+), 52 deletions(-) diff --git a/build.rs b/build.rs index 2dc8d33..70c88e3 100644 --- a/build.rs +++ b/build.rs @@ -1,5 +1,5 @@ use windows::Win32::System::LibraryLoader::{GetProcAddress, GetModuleHandleW}; -use windows::Win32::Foundation::{PWSTR, PSTR}; +use windows::core::{PWSTR, PSTR, PCWSTR, PCSTR}; use std::i64; use std::process::Command; use std::str; @@ -13,6 +13,25 @@ trait IntoPSTR { fn into_pstr(self) -> PSTR; } +trait IntoPCSTR { + fn into_pcstr(self) -> PCSTR; +} + +trait IntoPCWSTR { + fn into_pcwstr(self) -> PCWSTR; +} + +impl IntoPCWSTR for &str { + fn into_pcwstr(self) -> PCWSTR { + let encoded = self + .encode_utf16() + .chain([0u16]) + .collect::>(); + + PCWSTR(encoded.as_ptr()) + } +} + impl IntoPWSTR for &str { fn into_pwstr(self) -> PWSTR { let mut encoded = self @@ -35,6 +54,18 @@ impl IntoPSTR for &str { PSTR(encoded.as_mut_ptr()) } } +impl IntoPCSTR for &str { + fn into_pcstr(self) -> PCSTR { + let encoded = self + .as_bytes() + .iter() + .cloned() + .chain([0u8]) + .collect::>(); + + PCSTR(encoded.as_ptr()) } +} + impl IntoPWSTR for String { fn into_pwstr(self) -> PWSTR { let mut encoded = self @@ -99,8 +130,10 @@ fn main() { println!("Windows build number: {:?}", build_version); let conpty_enabled; - let kernel32 = unsafe { GetModuleHandleW("kernel32.dll".into_pwstr()) }; - let conpty = unsafe { GetProcAddress(kernel32, "CreatePseudoConsole".into_pstr()) }; + let kernel32_res = unsafe { GetModuleHandleW("kernel32.dll".into_pcwstr()) }; + let kernel32 = kernel32_res.unwrap(); + + let conpty = unsafe { GetProcAddress(kernel32, "CreatePseudoConsole".into_pcstr()) }; match conpty { Some(_) => { conpty_enabled = "1"; diff --git a/src/pty/base.rs b/src/pty/base.rs index 40e739c..7ec3c35 100644 --- a/src/pty/base.rs +++ b/src/pty/base.rs @@ -1,12 +1,12 @@ /// Base struct used to generalize some of the PTY I/O operations. -use windows::Win32::Foundation::{HANDLE, S_OK, STATUS_PENDING, CloseHandle, PSTR, PWSTR, WAIT_FAILED, WAIT_TIMEOUT}; +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::Threading::{GetExitCodeProcess, GetProcessId, WaitForSingleObject}; -use windows::Win32::Globalization::{MultiByteToWideChar, WideCharToMultiByte, CP_UTF8}; -use windows::core::{HRESULT, Error}; +use windows::Win32::Globalization::{MultiByteToWideChar, WideCharToMultiByte, CP_UTF8, MULTI_BYTE_TO_WIDE_CHAR_FLAGS}; +use windows::core::{HRESULT, Error, PSTR, PCSTR}; use std::ptr; use std::sync::mpsc; @@ -193,11 +193,10 @@ fn read(mut length: u32, blocking: bool, stream: HANDLE, using_pipes: bool) -> R // let os_str = OsString::with_capacity(buf_vec.len()); let mut vec_buf: Vec = std::iter::repeat(0).take(buf_vec.len()).collect(); - let vec_ptr = vec_buf.as_mut_ptr(); - let pstr = PSTR(buf_vec.as_mut_ptr()); - let pwstr = PWSTR(vec_ptr); + unsafe { - MultiByteToWideChar(CP_UTF8, 0, pstr, -1, pwstr, (total_bytes + 1) as i32); + MultiByteToWideChar( + CP_UTF8, MULTI_BYTE_TO_WIDE_CHAR_FLAGS(0), &buf_vec[..], &mut vec_buf[..]); } // let non_zeros: Vec = vec_buf.split(|elem| *elem == 0 as u16).collect(); @@ -218,10 +217,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; + let succ = is_timeout != WAIT_FAILED.0; if succ { - let alive = is_timeout == WAIT_TIMEOUT; + let alive = is_timeout == WAIT_TIMEOUT.0; Ok(alive) } else { let err: HRESULT = Error::from_win32().into(); @@ -458,22 +457,24 @@ impl PTYProcess { /// The total number of characters written if the call was successful, else /// an [`OsString`] containing an human-readable error. pub fn write(&self, buf: OsString) -> Result { - let mut vec_buf: Vec = buf.encode_wide().collect(); + let vec_buf: Vec = buf.encode_wide().collect(); let null_overlapped: *mut OVERLAPPED = ptr::null_mut(); let result: HRESULT; unsafe { - let pwstr = PWSTR(vec_buf.as_mut_ptr()); let required_size = WideCharToMultiByte( - CP_UTF8, 0, pwstr, vec_buf.len().try_into().map_err(|_| "buf too large")?, PSTR(ptr::null_mut::()), - 0, PSTR(ptr::null_mut::()), ptr::null_mut::()); + CP_UTF8, 0, &vec_buf[..], PSTR(ptr::null_mut::()), + 0, PCSTR(ptr::null_mut::()), ptr::null_mut::()); 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, pwstr, vec_buf.len().try_into().unwrap(), pstr, required_size, PSTR(ptr::null_mut::()), ptr::null_mut::()); + WideCharToMultiByte( + CP_UTF8, 0, &vec_buf[..], pstr, + required_size, PCSTR(ptr::null_mut::()), + ptr::null_mut::()); let mut written_bytes = MaybeUninit::::uninit(); let bytes_ptr: *mut u32 = ptr::addr_of_mut!(*written_bytes.as_mut_ptr()); diff --git a/src/pty/conpty/pty_impl.rs b/src/pty/conpty/pty_impl.rs index 15b20e6..dc978f2 100644 --- a/src/pty/conpty/pty_impl.rs +++ b/src/pty/conpty/pty_impl.rs @@ -1,12 +1,13 @@ /// Actual ConPTY implementation. +use windows::core::{PWSTR, PCWSTR, Error}; use windows::Win32::Foundation::{ - CloseHandle, PWSTR, HANDLE, + CloseHandle, HANDLE, S_OK, INVALID_HANDLE_VALUE}; use windows::Win32::Storage::FileSystem::{ CreateFileW, FILE_GENERIC_READ, FILE_SHARE_READ, FILE_SHARE_WRITE, OPEN_EXISTING, FILE_GENERIC_WRITE, - FILE_ATTRIBUTE_NORMAL}; + FILE_ATTRIBUTE_NORMAL, FILE_FLAGS_AND_ATTRIBUTES}; use windows::Win32::System::Console::{ HPCON, AllocConsole, GetConsoleWindow, GetConsoleMode, CONSOLE_MODE, ENABLE_VIRTUAL_TERMINAL_PROCESSING, @@ -21,7 +22,7 @@ use windows::Win32::System::Threading::{ EXTENDED_STARTUPINFO_PRESENT, CREATE_UNICODE_ENVIRONMENT, DeleteProcThreadAttributeList}; use windows::Win32::UI::WindowsAndMessaging::{ShowWindow, SW_HIDE}; -use windows::core::{HRESULT, Error}; +use windows::core::{HRESULT}; use std::{mem, ptr}; use std::mem::MaybeUninit; @@ -47,7 +48,7 @@ unsafe impl Sync for ConPTY {} impl PTYImpl for ConPTY { fn new(args: &PTYArgs) -> Result, OsString> { - let mut result: HRESULT = S_OK; + let mut result: HRESULT; if args.cols <= 0 || args.rows <= 0 { let err: OsString = OsString::from(format!( "PTY cols and rows must be positive and non-zero. Got: ({}, {})", args.cols, args.rows)); @@ -64,46 +65,43 @@ impl PTYImpl for ConPTY { // Recreate the standard stream inputs in case the parent process // has redirected them. let conout_name = OsString::from("CONOUT$\0"); - let mut conout_vec: Vec = conout_name.encode_wide().collect(); - let conout_pwstr = PWSTR(conout_vec.as_mut_ptr()); + let conout_vec: Vec = conout_name.encode_wide().collect(); + let conout_pwstr = PCWSTR(conout_vec.as_ptr()); - let h_console = CreateFileW( + 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)); - if h_console.is_invalid() { - result = Error::from_win32().into(); - } - - if result.is_err() { - let result_msg = result.message(); + if let Err(err) = h_console_res { + let result_msg = err.message(); let err_msg: &[u16] = result_msg.as_wide(); let string = OsString::from_wide(err_msg); return Err(string); } + let h_console = h_console_res.unwrap(); + let conin_name = OsString::from("CONIN$\0"); - let mut conin_vec: Vec = conin_name.encode_wide().collect(); - let conin_pwstr = PWSTR(conin_vec.as_mut_ptr()); + let conin_vec: Vec = conin_name.encode_wide().collect(); + let conin_pwstr = PCWSTR(conin_vec.as_ptr()); - let h_in = CreateFileW( + let h_in_res = CreateFileW( conin_pwstr, FILE_GENERIC_READ | FILE_GENERIC_WRITE, FILE_SHARE_READ, ptr::null(), - OPEN_EXISTING, 0, HANDLE(0)); + OPEN_EXISTING, FILE_FLAGS_AND_ATTRIBUTES(0), + HANDLE(0)); - if h_in.is_invalid() { - result = Error::from_win32().into(); - } - - if result.is_err() { - let result_msg = result.message(); + if let Err(err) = h_in_res { + let result_msg = err.message(); let err_msg: &[u16] = result_msg.as_wide(); let string = OsString::from_wide(err_msg); return Err(string); } + let h_in = h_in_res.unwrap(); + let mut console_mode_un = MaybeUninit::::uninit(); let console_mode_ptr = console_mode_un.as_mut_ptr(); @@ -222,7 +220,7 @@ impl PTYImpl for ConPTY { fn spawn(&mut self, appname: OsString, cmdline: Option, cwd: Option, env: Option) -> Result { let result: HRESULT; let mut environ: *const u16 = ptr::null(); - let mut working_dir: *mut u16 = ptr::null_mut(); + let mut working_dir: *const u16 = ptr::null_mut(); let mut env_buf: Vec; let mut cwd_buf: Vec; let cmd_buf: Vec; @@ -240,7 +238,7 @@ impl PTYImpl for ConPTY { if let Some(cwd_opt) = cwd { cwd_buf = cwd_opt.encode_wide().collect(); cwd_buf.push(0); - working_dir = cwd_buf.as_mut_ptr(); + working_dir = cwd_buf.as_ptr(); } if let Some(cmdline_opt) = cmdline { @@ -256,12 +254,14 @@ impl PTYImpl for ConPTY { // Discover the size required for the list let mut required_bytes_u = MaybeUninit::::uninit(); let required_bytes_ptr = required_bytes_u.as_mut_ptr(); - InitializeProcThreadAttributeList(ptr::null_mut(), 1, 0, required_bytes_ptr); + InitializeProcThreadAttributeList( + LPPROC_THREAD_ATTRIBUTE_LIST(ptr::null_mut()), 1, 0, required_bytes_ptr); // Allocate memory to represent the list let mut required_bytes = required_bytes_u.assume_init(); let mut lp_attribute_list: Box<[u8]> = vec![0; required_bytes].into_boxed_slice(); - let proc_thread_list: LPPROC_THREAD_ATTRIBUTE_LIST = lp_attribute_list.as_mut_ptr().cast::<_>(); + let proc_thread_list: LPPROC_THREAD_ATTRIBUTE_LIST = LPPROC_THREAD_ATTRIBUTE_LIST( + lp_attribute_list.as_mut_ptr().cast::<_>()); // Prepare Startup Information structure let start_info = STARTUPINFOEXW { @@ -284,7 +284,7 @@ impl PTYImpl for ConPTY { // Set the pseudoconsole information into the list if !UpdateProcThreadAttribute( start_info.lpAttributeList, 0, 0x00020016, - self.handle as _, mem::size_of::(), + self.handle.0 as _, mem::size_of::(), ptr::null_mut(), ptr::null_mut()).as_bool() { result = Error::from_win32().into(); let result_msg = result.message(); @@ -298,14 +298,14 @@ impl PTYImpl for ConPTY { let si_ptr = &start_info as *const STARTUPINFOEXW; let succ = CreateProcessW( - PWSTR(ptr::null_mut()), + PCWSTR(ptr::null_mut()), PWSTR(cmd), ptr::null_mut(), ptr::null_mut(), false, EXTENDED_STARTUPINFO_PRESENT | CREATE_UNICODE_ENVIRONMENT, environ as _, - PWSTR(working_dir), + PCWSTR(working_dir), si_ptr as *const _, pi_ptr ).as_bool(); diff --git a/src/pty/winpty/pty_impl.rs b/src/pty/winpty/pty_impl.rs index ff78c6f..1011796 100644 --- a/src/pty/winpty/pty_impl.rs +++ b/src/pty/winpty/pty_impl.rs @@ -1,6 +1,7 @@ /// Actual WinPTY backend implementation. -use windows::Win32::Foundation::{PWSTR, HANDLE}; +use windows::Win32::Foundation::{HANDLE}; +use windows::core::{PCWSTR}; use windows::Win32::Storage::FileSystem::{ CreateFileW, FILE_GENERIC_READ, FILE_SHARE_NONE, OPEN_EXISTING, FILE_GENERIC_WRITE, @@ -168,16 +169,33 @@ impl PTYImpl for WinPTY { let conout_name = pty_ptr.get_conout_name(); let empty_handle = HANDLE(0); - let conin = CreateFileW( - PWSTR(conin_name as *mut u16), FILE_GENERIC_WRITE, FILE_SHARE_NONE, ptr::null(), + let conin_res = CreateFileW( + PCWSTR(conin_name as *const u16), FILE_GENERIC_WRITE, FILE_SHARE_NONE, ptr::null(), OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, empty_handle ); - let conout = CreateFileW( - PWSTR(conout_name as *mut u16), FILE_GENERIC_READ, FILE_SHARE_NONE, ptr::null(), + if let Err(err) = conin_res { + let result_msg = err.message(); + let err_msg: &[u16] = result_msg.as_wide(); + let string = OsString::from_wide(err_msg); + return Err(string); + } + + let conout_res = CreateFileW( + PCWSTR(conout_name as *mut u16), FILE_GENERIC_READ, FILE_SHARE_NONE, ptr::null(), OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, empty_handle ); + if let Err(err) = conout_res { + let result_msg = err.message(); + let err_msg: &[u16] = result_msg.as_wide(); + let string = OsString::from_wide(err_msg); + return Err(string); + } + + let conin = conin_res.unwrap(); + let conout = conout_res.unwrap(); + let process = PTYProcess::new(conin, conout, false); Ok(Box::new(WinPTY { ptr: pty_ptr, process }) as Box) } From eb81e3296ca88d4d60f1feb908c333990c5d5dbc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edgar=20Andr=C3=A9s=20Margffoy=20Tuay?= Date: Tue, 5 Jul 2022 17:25:55 -0500 Subject: [PATCH 3/3] Update deprecated flag in CI --- .github/workflows/windows_stable.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/windows_stable.yml b/.github/workflows/windows_stable.yml index 3e34b71..bf4a801 100644 --- a/.github/workflows/windows_stable.yml +++ b/.github/workflows/windows_stable.yml @@ -38,14 +38,14 @@ jobs: shell: bash -l {0} run: | rustup component add llvm-tools-preview - echo "RUSTFLAGS=-Zinstrument-coverage" >> $GITHUB_ENV + echo "RUSTFLAGS=-Cinstrument-coverage" >> $GITHUB_ENV - name: Install miniconda uses: conda-incubator/setup-miniconda@v2 with: auto-update-conda: true activate-environment: test channels: conda-forge,defaults - python-version: 3.7 + python-version: 3.9 - name: Conda env info shell: bash -l {0} run: conda env list