windows-sandbox-rs/src/proc_thread_attr.rs
100 lines
use std::ffi::c_void;use std::io;use windows_sys::Win32::Foundation::GetLastError;use windows_sys::Win32::Foundation::HANDLE;use windows_sys::Win32::System::Threading::DeleteProcThreadAttributeList;use windows_sys::Win32::System::Threading::InitializeProcThreadAttributeList;use windows_sys::Win32::System::Threading::LPPROC_THREAD_ATTRIBUTE_LIST;use windows_sys::Win32::System::Threading::UpdateProcThreadAttribute;const PROC_THREAD_ATTRIBUTE_HANDLE_LIST: usize = 0x0002_0002;const PROC_THREAD_ATTRIBUTE_PSEUDOCONSOLE: usize = 0x0002_0016;pub struct ProcThreadAttributeList { buffer: Vec<u8>, handle_list: Option<Vec<HANDLE>>,}impl ProcThreadAttributeList { pub fn new(attr_count: u32) -> io::Result<Self> { let mut size: usize = 0; unsafe { InitializeProcThreadAttributeList(std::ptr::null_mut(), attr_count, 0, &mut size); } if size == 0 { return Err(io::Error::from_raw_os_error(unsafe { GetLastError() as i32 })); } let mut buffer = vec![0u8; size]; let list = buffer.as_mut_ptr() as LPPROC_THREAD_ATTRIBUTE_LIST; let ok = unsafe { InitializeProcThreadAttributeList(list, attr_count, 0, &mut size) }; if ok == 0 { return Err(io::Error::from_raw_os_error(unsafe { GetLastError() as i32 })); } Ok(Self { buffer, handle_list: None, }) } pub fn as_mut_ptr(&mut self) -> LPPROC_THREAD_ATTRIBUTE_LIST { self.buffer.as_mut_ptr() as LPPROC_THREAD_ATTRIBUTE_LIST } pub fn set_pseudoconsole(&mut self, hpc: isize) -> io::Result<()> { let list = self.as_mut_ptr(); let ok = unsafe { UpdateProcThreadAttribute( list, 0, PROC_THREAD_ATTRIBUTE_PSEUDOCONSOLE, hpc as *mut c_void, std::mem::size_of::<HANDLE>(), std::ptr::null_mut(), std::ptr::null_mut(), ) }; if ok == 0 { return Err(io::Error::from_raw_os_error(unsafe { GetLastError() as i32 })); } Ok(()) } pub fn set_handle_list(&mut self, handles: Vec<HANDLE>) -> io::Result<()> { self.handle_list = Some(handles); let list = self.as_mut_ptr(); let Some(handle_list) = self.handle_list.as_mut() else { return Err(io::Error::other("handle list missing after initialization")); }; let ok = unsafe { UpdateProcThreadAttribute( list, 0, PROC_THREAD_ATTRIBUTE_HANDLE_LIST, handle_list.as_mut_ptr().cast(), std::mem::size_of_val(handle_list.as_slice()), std::ptr::null_mut(), std::ptr::null_mut(), ) }; if ok == 0 { return Err(io::Error::from_raw_os_error(unsafe { GetLastError() as i32 })); } Ok(()) }}impl Drop for ProcThreadAttributeList { fn drop(&mut self) { unsafe { DeleteProcThreadAttributeList(self.as_mut_ptr()); } }}