Codex Handbook
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());        }    }}