Skip to content

Commit

Permalink
ERROR enum for win32 errors
Browse files Browse the repository at this point in the history
  • Loading branch information
evmar committed Sep 23, 2024
1 parent 769053b commit 3eddb09
Show file tree
Hide file tree
Showing 11 changed files with 204 additions and 233 deletions.
53 changes: 28 additions & 25 deletions cli/src/host.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,23 +6,22 @@ use std::path::{Path, PathBuf};
use std::time::{SystemTime, UNIX_EPOCH};
use std::{cell::RefCell, io::Write, rc::Rc};
use typed_path::{UnixPath, WindowsPath, WindowsPathBuf};
use win32::winapi::types::io_error_to_win32;
use win32::{FileOptions, ReadDir, Stat};
use win32::{FileOptions, ReadDir, Stat, ERROR};

struct File {
f: std::fs::File,
}

impl win32::File for File {
fn stat(&self) -> Result<Stat, u32> {
fn stat(&self) -> Result<Stat, ERROR> {
match self.f.metadata() {
Ok(ref meta) => Ok(metadata_to_stat(meta)),
Err(ref e) => Err(io_error_to_win32(e)),
Err(ref e) => Err(ERROR::from_io_error(e)),
}
}

fn set_len(&self, len: u64) -> Result<(), u32> {
self.f.set_len(len).map_err(|e| io_error_to_win32(&e))
fn set_len(&self, len: u64) -> Result<(), ERROR> {
self.f.set_len(len).map_err(|e| ERROR::from_io_error(&e))
}
}

Expand Down Expand Up @@ -53,7 +52,7 @@ struct ReadDirIter {
}

impl ReadDir for ReadDirIter {
fn next(&mut self) -> Result<Option<win32::ReadDirEntry>, u32> {
fn next(&mut self) -> Result<Option<win32::ReadDirEntry>, ERROR> {
match self.iter.next() {
Some(Ok(entry)) => {
let name = entry
Expand All @@ -68,7 +67,7 @@ impl ReadDir for ReadDirIter {
stat: metadata_to_stat(&meta),
}))
}
Some(Err(ref e)) => Err(io_error_to_win32(e)),
Some(Err(ref e)) => Err(ERROR::from_io_error(e)),
None => Ok(None),
}
}
Expand All @@ -80,7 +79,7 @@ struct ReadDirFile {
}

impl ReadDir for ReadDirFile {
fn next(&mut self) -> Result<Option<win32::ReadDirEntry>, u32> {
fn next(&mut self) -> Result<Option<win32::ReadDirEntry>, ERROR> {
if self.consumed {
Ok(None)
} else {
Expand Down Expand Up @@ -145,12 +144,16 @@ impl win32::Host for EnvRef {
gui.block(wait)
}

fn current_dir(&self) -> Result<WindowsPathBuf, u32> {
let path = std::env::current_dir().map_err(|e| io_error_to_win32(&e))?;
fn current_dir(&self) -> Result<WindowsPathBuf, ERROR> {
let path = std::env::current_dir().map_err(|e| ERROR::from_io_error(&e))?;
Ok(host_to_windows_path(&path))
}

fn open(&self, path: &WindowsPath, options: FileOptions) -> Result<Box<dyn win32::File>, u32> {
fn open(
&self,
path: &WindowsPath,
options: FileOptions,
) -> Result<Box<dyn win32::File>, ERROR> {
let path = windows_to_host_path(path);
let result = std::fs::File::options()
.read(options.read)
Expand All @@ -161,30 +164,30 @@ impl win32::Host for EnvRef {
.open(path);
match result {
Ok(f) => Ok(Box::new(File { f })),
Err(ref e) => Err(io_error_to_win32(e)),
Err(ref e) => Err(ERROR::from_io_error(e)),
}
}

fn stat(&self, path: &WindowsPath) -> Result<Stat, u32> {
fn stat(&self, path: &WindowsPath) -> Result<Stat, ERROR> {
let path = windows_to_host_path(path);
match std::fs::metadata(path) {
Ok(ref meta) => Ok(metadata_to_stat(meta)),
Err(ref e) => Err(io_error_to_win32(e)),
Err(ref e) => Err(ERROR::from_io_error(e)),
}
}

fn read_dir(&self, path: &WindowsPath) -> Result<Box<dyn ReadDir>, u32> {
fn read_dir(&self, path: &WindowsPath) -> Result<Box<dyn ReadDir>, ERROR> {
let path = windows_to_host_path(path);
let full_path = match std::fs::canonicalize(path) {
Ok(p) => p,
Err(ref e) => return Err(io_error_to_win32(e)),
Err(ref e) => return Err(ERROR::from_io_error(e)),
};
match std::fs::metadata(&full_path) {
Ok(meta) => {
if meta.is_dir() {
let iter = match std::fs::read_dir(&full_path) {
Ok(iter) => iter,
Err(ref e) => return Err(io_error_to_win32(e)),
Err(ref e) => return Err(ERROR::from_io_error(e)),
};
Ok(Box::new(ReadDirIter { iter }))
} else {
Expand All @@ -203,23 +206,23 @@ impl win32::Host for EnvRef {
}))
}
}
Err(ref e) => Err(io_error_to_win32(e)),
Err(ref e) => Err(ERROR::from_io_error(e)),
}
}

fn create_dir(&self, path: &WindowsPath) -> Result<(), u32> {
fn create_dir(&self, path: &WindowsPath) -> Result<(), ERROR> {
let path = windows_to_host_path(path);
std::fs::create_dir(path).map_err(|e| io_error_to_win32(&e))
std::fs::create_dir(path).map_err(|e| ERROR::from_io_error(&e))
}

fn remove_file(&self, path: &WindowsPath) -> Result<(), u32> {
fn remove_file(&self, path: &WindowsPath) -> Result<(), ERROR> {
let path = windows_to_host_path(path);
std::fs::remove_file(path).map_err(|e| io_error_to_win32(&e))
std::fs::remove_file(path).map_err(|e| ERROR::from_io_error(&e))
}

fn remove_dir(&self, path: &WindowsPath) -> Result<(), u32> {
fn remove_dir(&self, path: &WindowsPath) -> Result<(), ERROR> {
let path = windows_to_host_path(path);
std::fs::remove_dir(path).map_err(|e| io_error_to_win32(&e))
std::fs::remove_dir(path).map_err(|e| ERROR::from_io_error(&e))
}

fn log(&self, buf: &[u8]) {
Expand Down
3 changes: 1 addition & 2 deletions cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ mod resv32;
use anyhow::anyhow;
use std::borrow::Cow;
use std::process::ExitCode;
use win32::winapi::types::win32_error_str;
use win32::Host;

#[derive(argh::FromArgs)]
Expand Down Expand Up @@ -125,7 +124,7 @@ fn main() -> anyhow::Result<ExitCode> {
let mut cmdline = args.cmdline.clone();
let cwd = host
.current_dir()
.map_err(|e| anyhow!("failed to get current dir: {}", win32_error_str(e)))?;
.map_err(|e| anyhow!("failed to get current dir: {e:?}"))?;
cmdline[0] = cwd
.join(&cmdline[0])
.normalize()
Expand Down
22 changes: 11 additions & 11 deletions web/glue/src/host.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
use anyhow::bail;
use wasm_bindgen::prelude::*;
use win32::{ReadDir, Stat, StatKind, WindowsPath};
use win32::{ReadDir, Stat, StatKind, WindowsPath, ERROR};

struct WebSurface {
_hwnd: u32,
Expand Down Expand Up @@ -145,7 +145,7 @@ extern "C" {
}

impl win32::File for JsFile {
fn stat(&self) -> Result<Stat, u32> {
fn stat(&self) -> Result<Stat, ERROR> {
Ok(Stat {
kind: StatKind::File,
size: JsFile::info(self),
Expand All @@ -155,7 +155,7 @@ impl win32::File for JsFile {
})
}

fn set_len(&self, len: u64) -> Result<(), u32> {
fn set_len(&self, len: u64) -> Result<(), ERROR> {
todo!("set_len {len}")
}
}
Expand Down Expand Up @@ -313,18 +313,18 @@ impl win32::Host for JsHost {
&self,
path: &WindowsPath,
options: win32::FileOptions,
) -> Result<Box<dyn win32::File>, u32> {
) -> Result<Box<dyn win32::File>, ERROR> {
match JsHost::open(self, &path.to_string_lossy(), options) {
Some(file) => Ok(Box::new(file)),
None => Err(win32::winapi::types::ERROR_FILE_NOT_FOUND),
None => Err(ERROR::FILE_NOT_FOUND),
}
}

fn stat(&self, path: &WindowsPath) -> Result<Stat, u32> {
fn stat(&self, path: &WindowsPath) -> Result<Stat, ERROR> {
todo!("stat {path}")
}

fn read_dir(&self, path: &WindowsPath) -> Result<Box<dyn ReadDir>, u32> {
fn read_dir(&self, path: &WindowsPath) -> Result<Box<dyn ReadDir>, ERROR> {
todo!("read_dir {path}")
}

Expand All @@ -345,19 +345,19 @@ impl win32::Host for JsHost {
Box::new(WebSurface::new(hwnd, opts, JsHost::screen(self)))
}

fn current_dir(&self) -> Result<win32::WindowsPathBuf, u32> {
fn current_dir(&self) -> Result<win32::WindowsPathBuf, ERROR> {
todo!()
}

fn create_dir(&self, path: &WindowsPath) -> Result<(), u32> {
fn create_dir(&self, path: &WindowsPath) -> Result<(), ERROR> {
todo!("create_dir {path}")
}

fn remove_file(&self, path: &WindowsPath) -> Result<(), u32> {
fn remove_file(&self, path: &WindowsPath) -> Result<(), ERROR> {
todo!("remove_file {path}")
}

fn remove_dir(&self, path: &WindowsPath) -> Result<(), u32> {
fn remove_dir(&self, path: &WindowsPath) -> Result<(), ERROR> {
todo!("remove_dir {path}")
}
}
21 changes: 11 additions & 10 deletions win32/src/host.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
//! Interfaces expected of the x86 host.
pub use crate::winapi::ERROR;
pub use typed_path::{WindowsPath, WindowsPathBuf};

/// DirectDraw surface.
Expand Down Expand Up @@ -65,12 +66,12 @@ impl FileOptions {
}

pub trait File: std::io::Read + std::io::Write + std::io::Seek {
fn stat(&self) -> Result<Stat, u32>;
fn set_len(&self, len: u64) -> Result<(), u32>;
fn stat(&self) -> Result<Stat, ERROR>;
fn set_len(&self, len: u64) -> Result<(), ERROR>;
}

pub trait ReadDir {
fn next(&mut self) -> Result<Option<ReadDirEntry>, u32>;
fn next(&mut self) -> Result<Option<ReadDirEntry>, ERROR>;
}

#[derive(Debug, Clone)]
Expand Down Expand Up @@ -141,19 +142,19 @@ pub trait Host {
fn block(&self, wait: Option<u32>) -> bool;

/// Retrieves the absolute (Windows-style) path of the current working directory.
fn current_dir(&self) -> Result<WindowsPathBuf, u32>;
fn current_dir(&self) -> Result<WindowsPathBuf, ERROR>;
/// Open a file at the given (Windows-style) path.
fn open(&self, path: &WindowsPath, options: FileOptions) -> Result<Box<dyn File>, u32>;
fn open(&self, path: &WindowsPath, options: FileOptions) -> Result<Box<dyn File>, ERROR>;
/// Retrieve file or directory metadata at the given (Windows-style) path.
fn stat(&self, path: &WindowsPath) -> Result<Stat, u32>;
fn stat(&self, path: &WindowsPath) -> Result<Stat, ERROR>;
/// Iterate the contents of a directory at the given (Windows-style) path.
fn read_dir(&self, path: &WindowsPath) -> Result<Box<dyn ReadDir>, u32>;
fn read_dir(&self, path: &WindowsPath) -> Result<Box<dyn ReadDir>, ERROR>;
/// Create a new directory at the given (Windows-style) path.
fn create_dir(&self, path: &WindowsPath) -> Result<(), u32>;
fn create_dir(&self, path: &WindowsPath) -> Result<(), ERROR>;
/// Remove a file at the given (Windows-style) path.
fn remove_file(&self, path: &WindowsPath) -> Result<(), u32>;
fn remove_file(&self, path: &WindowsPath) -> Result<(), ERROR>;
/// Remove a directory at the given (Windows-style) path.
fn remove_dir(&self, path: &WindowsPath) -> Result<(), u32>;
fn remove_dir(&self, path: &WindowsPath) -> Result<(), ERROR>;
fn log(&self, buf: &[u8]);

fn create_window(&mut self, hwnd: u32) -> Box<dyn Window>;
Expand Down
36 changes: 36 additions & 0 deletions win32/src/winapi/error.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// https://learn.microsoft.com/en-us/windows/win32/debug/system-error-codes--0-499-

/// Windows error codes.
#[allow(non_camel_case_types)]
#[derive(Debug, win32_derive::TryFromEnum)]
pub enum ERROR {
SUCCESS = 0,
FILE_NOT_FOUND = 2,
ACCESS_DENIED = 5,
INVALID_HANDLE = 6,
INVALID_ACCESS = 12,
INVALID_DATA = 13,
FILE_EXISTS = 80,
OPEN_FAILED = 110,
MOD_NOT_FOUND = 126,
ALREADY_EXISTS = 183,
}

impl ERROR {
pub fn from_io_error(err: &std::io::Error) -> ERROR {
match err.kind() {
std::io::ErrorKind::NotFound => ERROR::FILE_NOT_FOUND,
std::io::ErrorKind::PermissionDenied => ERROR::ACCESS_DENIED,
std::io::ErrorKind::InvalidData => ERROR::INVALID_DATA,
std::io::ErrorKind::AlreadyExists => ERROR::FILE_EXISTS,
std::io::ErrorKind::InvalidInput => ERROR::INVALID_ACCESS,
_ => ERROR::OPEN_FAILED,
}
}
}

impl From<ERROR> for u32 {
fn from(err: ERROR) -> u32 {
err as u32
}
}
2 changes: 1 addition & 1 deletion win32/src/winapi/kernel32/dll.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ pub fn GetModuleHandleA(machine: &mut Machine, lpModuleName: Option<&str>) -> HM
return *hmodule;
}

set_last_error(machine, ERROR_MOD_NOT_FOUND);
set_last_error(machine, winapi::ERROR::MOD_NOT_FOUND);
return HMODULE::null();
}

Expand Down
Loading

0 comments on commit 3eddb09

Please sign in to comment.