diff --git a/Cargo.toml b/Cargo.toml index bc59867..b7d3a6a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,3 +21,6 @@ path = "examples/dark.rs" [profile.release] opt-level = "z" lto = "thin" + +[[example]] +name = "fs_demo" diff --git a/examples/fs_demo.rs b/examples/fs_demo.rs new file mode 100644 index 0000000..f7fc4cb --- /dev/null +++ b/examples/fs_demo.rs @@ -0,0 +1,10 @@ +#![no_std] +#![no_main] + +use kos::fs::read_file; + +#[no_mangle] +pub fn kol_main() { + let mut buf = [0u8; 256]; + let _ = read_file(c"/rd/1/readme.txt", &mut buf); +} diff --git a/src/fs.rs b/src/fs.rs new file mode 100644 index 0000000..2e18776 --- /dev/null +++ b/src/fs.rs @@ -0,0 +1,58 @@ +use core::ffi::CStr; +use crate::sys::{fs_execute, FsBlock}; + +fn execute(op: u32, offset: u32, offset_hi: u32, count: u32, buf: *mut u8, path: &CStr) -> Result<(), u32> { + let info = FsBlock { + operation: op, + offset, + offset_hi, + byte_count: count, + buffer: buf, + _pad: 0, + path: path.as_ptr() as *const u8, + }; + match unsafe { fs_execute(&info) } { + 0 => Ok(()), + e => Err(e), + } +} + +pub fn read_file(path: &CStr, buf: &mut [u8]) -> Result<(), u32> { + execute(0, 0, 0, buf.len() as u32, buf.as_mut_ptr(), path) +} + +pub fn read_folder(path: &CStr, buf: &mut [u8]) -> Result<(), u32> { + execute(1, 0, 0, buf.len() as u32, buf.as_mut_ptr(), path) +} + +pub fn create_file(path: &CStr, buf: &[u8]) -> Result<(), u32> { + execute(2, 0, 0, buf.len() as u32, buf.as_ptr() as *mut u8, path) +} + +pub fn write_file(path: &CStr, buf: &[u8]) -> Result<(), u32> { + execute(3, 0, 0, buf.len() as u32, buf.as_ptr() as *mut u8, path) +} + +pub fn set_size(path: &CStr, size: u64) -> Result<(), u32> { + execute(4, size as u32, (size >> 32) as u32, 0, core::ptr::null_mut(), path) +} + +pub fn get_attributes(path: &CStr, buf: &mut [u8]) -> Result<(), u32> { + execute(5, 0, 0, buf.len() as u32, buf.as_mut_ptr(), path) +} + +pub fn set_attributes(path: &CStr, buf: &[u8]) -> Result<(), u32> { + execute(6, 0, 0, buf.len() as u32, buf.as_ptr() as *mut u8, path) +} + +pub fn run(path: &CStr) -> Result<(), u32> { + execute(7, 0, 0, 0, core::ptr::null_mut(), path) +} + +pub fn delete(path: &CStr) -> Result<(), u32> { + execute(8, 0, 0, 0, core::ptr::null_mut(), path) +} + +pub fn create_folder(path: &CStr) -> Result<(), u32> { + execute(9, 0, 0, 0, core::ptr::null_mut(), path) +} diff --git a/src/func_constants.inc b/src/func_constants.inc index cda41b6..677c023 100644 --- a/src/func_constants.inc +++ b/src/func_constants.inc @@ -20,3 +20,4 @@ SF_SYS_MISC = 68 SSF_MEM_ALLOC = 12 SSF_MEM_FREE = 13 SSF_LOAD_DLL = 19 +SF_FILE = 70 diff --git a/src/lib.rs b/src/lib.rs index 296cdf8..063bc76 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -6,6 +6,7 @@ mod nanolibc; pub mod allocation; pub mod dll; pub mod sys; +pub mod fs; pub use modules::*; diff --git a/src/sys.rs b/src/sys.rs index 41188e8..599b1f4 100644 --- a/src/sys.rs +++ b/src/sys.rs @@ -67,4 +67,19 @@ extern "C" { // 68.19 #[link_name = "_load_dll"] pub fn load_dll(name: *const u8) -> *const u32; + + // 70 + #[link_name = "_fs_execute"] + pub fn fs_execute(info: *const FsBlock) -> u32; +} + +#[repr(C)] +pub(crate) struct FsBlock { + pub operation: u32, + pub offset: u32, + pub offset_hi: u32, + pub byte_count: u32, + pub buffer: *mut u8, + pub _pad: u8, + pub path: *const u8, } diff --git a/src/syscalls.S b/src/syscalls.S index 85570eb..60fe4fa 100644 --- a/src/syscalls.S +++ b/src/syscalls.S @@ -20,6 +20,7 @@ section '.text' public _get_lang public _load_dll public _set_event_mask + public _fs_execute _exit: mov eax, SF_TERMINATE_PROCESS @@ -143,3 +144,10 @@ _set_event_mask: int 0x40 ret +_fs_execute: + push ebx + mov eax, SF_FILE + mov ebx, [esp + 4 * 2] + int 0x40 + pop ebx + ret