Codex Handbook
windows-sandbox-rs/src/bin/setup_main/win/read_acl_mutex.rs 61 lines
use anyhow::Result;use codex_windows_sandbox::to_wide;use std::ffi::OsStr;use windows_sys::Win32::Foundation::CloseHandle;use windows_sys::Win32::Foundation::ERROR_ALREADY_EXISTS;use windows_sys::Win32::Foundation::ERROR_FILE_NOT_FOUND;use windows_sys::Win32::Foundation::GetLastError;use windows_sys::Win32::Foundation::HANDLE;use windows_sys::Win32::System::Threading::CreateMutexW;use windows_sys::Win32::System::Threading::MUTEX_ALL_ACCESS;use windows_sys::Win32::System::Threading::OpenMutexW;use windows_sys::Win32::System::Threading::ReleaseMutex;const READ_ACL_MUTEX_NAME: &str = "Local\\CodexSandboxReadAcl";pub(super) struct ReadAclMutexGuard {    handle: HANDLE,}impl Drop for ReadAclMutexGuard {    fn drop(&mut self) {        unsafe {            let _ = ReleaseMutex(self.handle);            CloseHandle(self.handle);        }    }}pub(super) fn read_acl_mutex_exists() -> Result<bool> {    let name = to_wide(OsStr::new(READ_ACL_MUTEX_NAME));    let handle = unsafe { OpenMutexW(MUTEX_ALL_ACCESS, 0, name.as_ptr()) };    if handle == 0 {        let err = unsafe { GetLastError() };        if err == ERROR_FILE_NOT_FOUND {            return Ok(false);        }        return Err(anyhow::anyhow!("OpenMutexW failed: {err}"));    }    unsafe {        CloseHandle(handle);    }    Ok(true)}pub(super) fn acquire_read_acl_mutex() -> Result<Option<ReadAclMutexGuard>> {    let name = to_wide(OsStr::new(READ_ACL_MUTEX_NAME));    let handle = unsafe { CreateMutexW(std::ptr::null_mut(), 1, name.as_ptr()) };    if handle == 0 {        return Err(anyhow::anyhow!("CreateMutexW failed: {}", unsafe {            GetLastError()        }));    }    let err = unsafe { GetLastError() };    if err == ERROR_ALREADY_EXISTS {        unsafe {            CloseHandle(handle);        }        return Ok(None);    }    Ok(Some(ReadAclMutexGuard { handle }))}