From c162146abb3ce5e4974cbc88f2925bb756021c81 Mon Sep 17 00:00:00 2001 From: Ivan Baravy Date: Wed, 18 Oct 2017 23:19:53 +0300 Subject: [PATCH] Use fuse3, rewrite no-fuse version in C. --- .gitignore | 6 +- kocdecl.asm | 202 +++++++++++++++++++ kocdecl.h | 7 + kofu.c | 37 ++++ xfskosfuse.c => kofuse.c | 58 +++--- makefile | 29 +-- xfs.asm | 53 ++--- xfs.inc | 11 +- xfskos.asm | 416 --------------------------------------- 9 files changed, 313 insertions(+), 506 deletions(-) create mode 100644 kocdecl.asm create mode 100644 kocdecl.h create mode 100644 kofu.c rename xfskosfuse.c => kofuse.c (61%) delete mode 100644 xfskos.asm diff --git a/.gitignore b/.gitignore index eec579c..a152d37 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ +*.swp +.vim *.o -xfskos -xfskosfuse +kofu +kofuse diff --git a/kocdecl.asm b/kocdecl.asm new file mode 100644 index 0000000..d7cd431 --- /dev/null +++ b/kocdecl.asm @@ -0,0 +1,202 @@ +format ELF + +__DEBUG__ = 1 +__DEBUG_LEVEL__ = 2 + +include 'proc32.inc' +include 'struct.inc' +include 'macros.inc' +include 'const.inc' +include 'system.inc' +include 'debug-fdo.inc' +include 'disk.inc' +include 'fs_common.inc' + +ERROR_SUCCESS = 0 +ERROR_DISK_BASE = 1 +ERROR_UNSUPPORTED_FS = 2 +ERROR_UNKNOWN_FS = 3 +ERROR_PARTITION = 4 +ERROR_FILE_NOT_FOUND = 5 +ERROR_END_OF_FILE = 6 +ERROR_MEMORY_POINTER = 7 +ERROR_DISK_FULL = 8 +ERROR_FS_FAIL = 9 +ERROR_ACCESS_DENIED = 10 +ERROR_DEVICE = 11 +ERROR_OUT_OF_MEMORY = 12 + +purge section,mov,add,sub +section '.text' executable align 16 + +public kos_fuse_init +kos_fuse_init: + push ebx esi edi ebp + + mov eax, [esp + 0x14] + mov [fd], eax + + mov eax, 0 + mov ebx, mbr_buffer + mov ebp, partition + call fs_read32_sys + + mov esi, disk + mov [esi + DISK.MediaInfo.SectorSize], 512 + mov ebp, partition + mov [ebp + PARTITION.Disk], esi + mov ebx, mbr_buffer + call xfs_create_partition + test eax, eax + jnz @f + mov eax, SYS_WRITE + mov ebx, STDOUT + mov ecx, msg_not_xfs_partition + mov edx, msg_not_xfs_partition.size + int 0x80 + @@: + mov [fs_struct], eax + + pop ebp edi esi ebx + ret + +;char *hello_readdir(const char *path, off_t offset) +public kos_fuse_readdir +kos_fuse_readdir: + push ebx esi edi ebp + + mov edx, sf70_params + mov dword[edx + 0x00], 1 + mov eax, [esp + 0x18] ; offset + mov [edx + 0x04], eax + mov dword[edx + 0x08], 1 + mov dword[edx + 0x0c], 100 + mov dword[edx + 0x10], sf70_buffer + mov eax, [esp + 0x14] ; path + inc eax ; skip '/' + mov [edx + 0x14], eax + + mov ebp, [fs_struct] + mov ebx, sf70_params + mov esi, eax + push 0 + call xfs_ReadFolder + pop eax + + pop ebp edi esi ebx + mov eax, sf70_buffer + ret + + +; in: eax = sector, ebx = buffer, ebp = pointer to PARTITION structure +fs_read32_sys: + pushad + imul ecx, eax, 512 + add ecx, 2048*512 + mov eax, SYS_LSEEK + mov ebx, [fd] + mov edx, SEEK_SET + int 0x80 +;DEBUGF 1, "lseek: %x\n", eax + popad + + pushad + mov eax, SYS_READ + mov ecx, ebx + mov ebx, [fd] + mov edx, 512 + int 0x80 +;DEBUGF 1, "read: %d\n", eax + popad + + xor eax, eax + + ret + + +fs_read32_app: + ret + + +fs_read64_sys: + pushad + imul ecx, eax, 512 + add ecx, 2048*512 + mov eax, SYS_LSEEK + mov ebx, [fd] + mov edx, SEEK_SET + int 0x80 +;DEBUGF 1, "lseek: %x\n", eax + popad + + pushad + mov eax, SYS_READ + imul edx, ecx, 512 + mov ecx, ebx + mov ebx, [fd] + int 0x80 +;DEBUGF 1, "read: %d\n", eax + popad + + xor eax, eax + ret + + +fs_read64_app: + ret + + +malloc: + push [alloc_pos] + add [alloc_pos], eax + pop eax + ret + +free: + ret + + +kernel_free: + ret + + +mutex_init: +mutex_lock: +mutex_unlock: + ret + +put_board: + pushad + mov eax, SYS_WRITE + mov ebx, STDOUT + push ecx + mov ecx, esp + mov edx, 1 + int 0x80 + pop ecx + popad +ret + + +include 'xfs.asm' + + +section '.data' writeable align 16 +include_debug_strings + +partition_offset dd 2048*512 +alloc_pos dd alloc_base +sf70_params rd 6 +msg_not_xfs_partition db 'not xfs partition',0x0a ; TODO: return codes, report in C +msg_not_xfs_partition.size = $ - msg_not_xfs_partition +IncludeIGlobals + + +section '.bss' writeable align 16 +mbr_buffer rb 4096*3 +fd rd 1 +partition PARTITION +disk DISK +alloc_base rb 1024*1024 +fs_struct rd 1 +sf70_buffer rb 1024*1024 diff --git a/kocdecl.h b/kocdecl.h new file mode 100644 index 0000000..6603eea --- /dev/null +++ b/kocdecl.h @@ -0,0 +1,7 @@ +#ifndef KOS_H_INCLUDED +#define KOS_H_INCLUDED + +void kos_fuse_init(int fd); +char *kos_fuse_readdir(const char *path, off_t offset); + +#endif diff --git a/kofu.c b/kofu.c new file mode 100644 index 0000000..3ce20a1 --- /dev/null +++ b/kofu.c @@ -0,0 +1,37 @@ +#include +#include +#include +#include +#include +#include +#include +#include "kocdecl.h" + +void prompt() { + printf("> "); + fflush(stdout); +} + +int main(int argc, char **argv) { + char cmd_buf[4096]; + int fd = open(argv[1], O_RDONLY); + kos_fuse_init(fd); + +//msg_few_args db 'usage: xfskos image [offset]',0x0a +//msg_file_not_found db 'file not found: ' +//msg_unknown_command db 'unknown command',0x0a +//msg_not_xfs_partition db 'not xfs partition',0x0a + while(true) { + prompt(); + scanf("%s", cmd_buf); + char *bdfe = kos_fuse_readdir("", 0); + uint32_t file_cnt = *(uint32_t*)(bdfe + 4); + bdfe += 0x20; + for (; file_cnt > 0; file_cnt--) { + printf("%s\n", bdfe + 0x28); + bdfe += 304; + } + } + + return 0; +} diff --git a/xfskosfuse.c b/kofuse.c similarity index 61% rename from xfskosfuse.c rename to kofuse.c index 69c04e0..741fc7c 100644 --- a/xfskosfuse.c +++ b/kofuse.c @@ -1,45 +1,36 @@ -/* - FUSE: Filesystem in Userspace - Copyright (C) 2001-2007 Miklos Szeredi - - This program can be distributed under the terms of the GNU GPL. - See the file COPYING. - - gcc -Wall hello.c `pkg-config fuse --cflags --libs` -o hello -*/ - -#define FUSE_USE_VERSION 26 +#define FUSE_USE_VERSION 31 #include #include #include #include -#include -#include #include -#include #include -#include -#include +#include +#include "kocdecl.h" -char *kos_fuse_readdir(const char *path, off_t offset); -void kos_fuse_init(int fd); - -static const char *hello_str = "Hello World!\n"; -static const char *hello_path = "/hello"; - -static int hello_getattr(const char *path, struct stat *stbuf) +static void *hello_init(struct fuse_conn_info *conn, + struct fuse_config *cfg) { + (void) conn; + cfg->kernel_cache = 1; + return NULL; +} + +static int hello_getattr(const char *path, struct stat *stbuf, + struct fuse_file_info *fi) +{ + (void) fi; int res = 0; memset(stbuf, 0, sizeof(struct stat)); if (strcmp(path, "/") == 0) { stbuf->st_mode = S_IFDIR | 0755; stbuf->st_nlink = 2; - } else if (strcmp(path, hello_path) == 0) { + } else if (strcmp(path+1, "blah") == 0) { stbuf->st_mode = S_IFREG | 0444; stbuf->st_nlink = 1; - stbuf->st_size = strlen(hello_str); + stbuf->st_size = strlen("blah"); } else res = -ENOENT; @@ -47,10 +38,12 @@ static int hello_getattr(const char *path, struct stat *stbuf) } static int hello_readdir(const char *path, void *buf, fuse_fill_dir_t filler, - off_t offset, struct fuse_file_info *fi) + off_t offset, struct fuse_file_info *fi, + enum fuse_readdir_flags flags) { (void) offset; (void) fi; + (void) flags; char *bdfe = kos_fuse_readdir(path, offset); @@ -63,7 +56,7 @@ static int hello_readdir(const char *path, void *buf, fuse_fill_dir_t filler, // close(f); bdfe += 0x20; for(; i>0; i--) { - filler(buf, bdfe + 0x28, NULL, 0); + filler(buf, bdfe + 0x28, NULL, 0, 0); bdfe += 304; } @@ -72,10 +65,10 @@ static int hello_readdir(const char *path, void *buf, fuse_fill_dir_t filler, static int hello_open(const char *path, struct fuse_file_info *fi) { - if (strcmp(path, hello_path) != 0) + if (strcmp(path+1, "blah") != 0) return -ENOENT; - if ((fi->flags & 3) != O_RDONLY) + if ((fi->flags & O_ACCMODE) != O_RDONLY) return -EACCES; return 0; @@ -86,14 +79,14 @@ static int hello_read(const char *path, char *buf, size_t size, off_t offset, { size_t len; (void) fi; - if(strcmp(path, hello_path) != 0) + if(strcmp(path+1, "blah") != 0) return -ENOENT; - len = strlen(hello_str); + len = strlen("blah"); if (offset < len) { if (offset + size > len) size = len - offset; - memcpy(buf, hello_str + offset, size); + memcpy(buf, "blah" + offset, size); } else size = 0; @@ -101,6 +94,7 @@ static int hello_read(const char *path, char *buf, size_t size, off_t offset, } static struct fuse_operations hello_oper = { + .init = hello_init, .getattr = hello_getattr, .readdir = hello_readdir, .open = hello_open, diff --git a/makefile b/makefile index f69eac5..5d9d6e6 100644 --- a/makefile +++ b/makefile @@ -1,25 +1,26 @@ FASM=fasm +CC=gcc -m32 +CFLAGS=-Wall -g3 -O0 -D_FILE_OFFSET_BITS=64 -all: xfskosfuse +all: kofu kofuse -#xfskos: xfskos.o -# ld *.o -o $@ -m elf_i386 -nostdlib -# strip $@ +kofu: kofu.o kocdecl.o + $(CC) $^ -o $@ -xfskos.o: xfskos.asm xfs.inc xfs.asm +kofuse: kofuse.o kocdecl.o + $(CC) $^ -o $@ `pkg-config fuse3 --libs` + +kocdecl.o: kocdecl.asm xfs.inc xfs.asm $(FASM) $< $@ -xfskosfuse: xfskosfuse.o xfskos.o - gcc -m32 -Wall $^ -o $@ -D_FILE_OFFSET_BITS=64 -lfuse -g3 -O0 +kofu.o: kofu.c + $(CC) $(CFLAGS) -c $< -xfskosfuse.o: xfskosfuse.c - gcc -m32 -Wall -c $< -D_FILE_OFFSET_BITS=64 -g3 -O0 +kofuse.o: kofuse.c + $(CC) $(CFLAGS) `pkg-config fuse3 --cflags` -c $< -.PHONY: all clean check +.PHONY: all clean clean: - rm -f *.o xfskos - -check: xfskos - echo ok + rm -f *.o kofu kofuse diff --git a/xfs.asm b/xfs.asm index b956dbe..731aba7 100644 --- a/xfs.asm +++ b/xfs.asm @@ -14,7 +14,7 @@ $Revision: 6462 $ ; [esi]+[[esp+4]] = name ; out: ; eax, ebx = return values for sysfunc 70 -;iglobal +iglobal align 4 xfs_user_functions: dd xfs_free @@ -30,7 +30,7 @@ xfs_user_functions: dd 0;xfs_Delete dd 0;xfs_CreateFolder xfs_user_functions_end: -;endg +endg include 'xfs.inc' @@ -263,8 +263,8 @@ endp ;--------------------------------------------------------------- ; block number (AG relative) -; eax -- block_lo -; edx -- block_hi +; eax -- inode_lo +; edx -- inode_hi ; ebx -- buffer ;--------------------------------------------------------------- xfs_read_block: @@ -294,7 +294,7 @@ xfs_read_block: add eax, ecx adc edx, esi -DEBUGF 1,"read block: 0x%x%x\n",edx,eax +;DEBUGF 1,"read block: 0x%x%x\n",edx,eax ; there is no way to read file system block at once, therefore we ; 1. calculate the number of sectors first ; 2. and then read them in series @@ -384,7 +384,7 @@ xfs_read_dirblock: ; test eax, eax ;--------------------------------------------------------------- xfs_read_inode: -DEBUGF 1,"reading inode: 0x%x%x\n",[esp+8],[esp+4] +;DEBUGF 1,"reading inode: 0x%x%x\n",[esp+8],[esp+4] push ebx mov eax, [esp + 8] ; inode_lo mov edx, [esp + 12] ; inode_hi @@ -416,25 +416,8 @@ DEBUGF 1,"reading inode: 0x%x%x\n",[esp+8],[esp+4] shl eax, cl add ebx, eax -;DEBUGF 1,"dinode: %x\n", ebx -;DEBUGF 1," %x\n",[ebx+0x00] -;DEBUGF 1," %x\n",[ebx+0x04] -;DEBUGF 1," %x\n",[ebx+0x08] -;DEBUGF 1," %x\n",[ebx+0x0c] -;DEBUGF 1," %x\n",[ebx+0x10] -;DEBUGF 1," %x\n",[ebx+0x14] -;DEBUGF 1," %x\n",[ebx+0x18] -;DEBUGF 1," %x\n",[ebx+0x1c] -;DEBUGF 1," %x\n",[ebx+0x20] -;DEBUGF 1," %x\n",[ebx+0x24] -;DEBUGF 1," %x\n",[ebx+0x28] -;DEBUGF 1," %x\n",[ebx+0x2c] -;DEBUGF 1," %x\n",[ebx+0x30] -;DEBUGF 1," %x\n",[ebx+0x34] -;DEBUGF 1," %x\n",[ebx+0x38] -;DEBUGF 1," %x\n",[ebx+0x3c] cmp word[ebx], XFS_DINODE_MAGIC ; test signature - jnz .error + jne .error .quit: xor eax, eax mov edx, ebx @@ -1111,7 +1094,7 @@ xfs_get_inode_short: ; this function searches for the file in _current_ dir ; it is called recursively for all the subdirs /path/to/my/file -DEBUGF 1, "xfs_get_inode_short: %s\n", [esp+4] +;DEBUGF 1,"xfs_get_inode_short: %s\n",[esp+4] mov esi, [esp + 4] ; name movzx eax, word[esi] cmp eax, '.' ; current dir; it is already read, just return @@ -1135,7 +1118,7 @@ DEBUGF 1, "xfs_get_inode_short: %s\n", [esp+4] mov [ebp + XFS.cur_inode_save], ebx cmp byte[ebx + xfs_inode.di_core.di_format], XFS_DINODE_FMT_LOCAL jne .not_shortdir -DEBUGF 1, "dir: shortdir\n" +;DEBUGF 1,"dir: shortdir\n" jmp .shortdir .not_shortdir: cmp byte[ebx + xfs_inode.di_core.di_format], XFS_DINODE_FMT_EXTENTS @@ -1171,9 +1154,9 @@ DEBUGF 1,"NOT IMPLEMENTED: DIR FORMAT\n" mov eax, [esi] and eax, 0x00ffffff cmp eax, '..' - jz .shortdir.parent2 + je .shortdir.parent2 cmp eax, '../' - jz .shortdir.parent3 + je .shortdir.parent3 jmp .shortdir.common .shortdir.parent3: inc esi @@ -1181,7 +1164,7 @@ DEBUGF 1,"NOT IMPLEMENTED: DIR FORMAT\n" add esi, 2 add ebx, xfs_inode.di_u stdcall xfs_get_inode_number_sf, dword[ebx + xfs_dir2_sf_hdr.count], dword[ebx + xfs_dir2_sf_hdr.parent + 4], dword[ebx + xfs_dir2_sf_hdr.parent] -DEBUGF 1,"found inode: 0x%x%x\n",edx,eax +;DEBUGF 1,"found inode: 0x%x%x\n",edx,eax jmp .quit ; not a parent inode? @@ -1201,8 +1184,8 @@ DEBUGF 1,"found inode: 0x%x%x\n",edx,eax movzx ecx, byte[edi + xfs_dir2_sf_entry.namelen] add edi, xfs_dir2_sf_entry.name mov esi, [esp + 4] -DEBUGF 1,"esi: %s\n",esi -DEBUGF 1,"edi: %s\n",edi +;DEBUGF 1,"esi: %s\n",esi +;DEBUGF 1,"edi: %s\n",edi repe cmpsb jne @f cmp byte[esi], 0 ; HINT: use adc here? @@ -1596,7 +1579,7 @@ DEBUGF 1,"found inode: 0x%x%x\n",edx,eax xfs_get_inode: ; call xfs_get_inode_short until file is found / error returned -DEBUGF 1,"getting inode of: %s\n",[esp+4] +;DEBUGF 1,"getting inode of: %s\n",[esp+4] push ebx esi edi ; start from the root inode @@ -1607,7 +1590,7 @@ DEBUGF 1,"getting inode of: %s\n",[esp+4] .next_dir: cmp byte[esi], 0 - jz .found + je .found ;DEBUGF 1,"next_level: |%s|\n",esi stdcall xfs_get_inode_short, esi, eax, edx @@ -1619,7 +1602,6 @@ DEBUGF 1,"getting inode of: %s\n",[esp+4] jmp .next_dir ; file name found, go to next directory level .found: -DEBUGF 1, "inode found: 0x%x%x\n", edx, eax .quit: pop edi esi ebx @@ -1654,14 +1636,13 @@ xfs_ReadFolder: ; 2. push ebx esi edi add esi, [esp + 32] ; directory name -DEBUGF 1,"xfs_ReadFolder: |%s|\n",esi +;DEBUGF 1,"xfs_ReadFolder: |%s|\n",esi stdcall xfs_get_inode, esi pop edi esi ebx mov ecx, edx or ecx, eax jnz @f movi eax, ERROR_FILE_NOT_FOUND - jmp .error @@: ; 3. diff --git a/xfs.inc b/xfs.inc index 860753f..ac81944 100644 --- a/xfs.inc +++ b/xfs.inc @@ -42,7 +42,7 @@ XFS_ABTC_MAGIC = 'ABTC' XFS_IBT_MAGIC = 'IABT' XFS_DINODE_MAGIC = 'IN' XFS_BMAP_MAGIC = 'BMAP' -XFS_DA_NODE_MAGIC = 0xbefe ; these are little endian here +XFS_DA_NODE_MAGIC = 0xbefe ; those are little endian here XFS_ATTR_LEAF_MAGIC = 0xeefb ; but big endian in docs XFS_DIR2_LEAF1_MAGIC = 0xf1d2 ; pay attention! XFS_DIR2_LEAFN_MAGIC = 0xffd2 ; @@ -64,11 +64,11 @@ BMBT_BLOCKCOUNT_BITLEN = 21 ; they are magic infile offsets for directories XFS_DIR2_DATA_ALIGN_LOG = 3 ; i.e., 8 bytes XFS_DIR2_LEAF_SPACE = 1 -XFS_DIR2_SPACE_SIZE = 1 SHL (32 + XFS_DIR2_DATA_ALIGN_LOG) -XFS_DIR2_LEAF_OFFSET = XFS_DIR2_LEAF_SPACE * XFS_DIR2_SPACE_SIZE +XFS_DIR2_SPACE_SIZE = (1 SHL (32 + XFS_DIR2_DATA_ALIGN_LOG)) +XFS_DIR2_LEAF_OFFSET = (XFS_DIR2_LEAF_SPACE * XFS_DIR2_SPACE_SIZE) XFS_DIR2_FREE_SPACE = 2 -XFS_DIR2_SPACE_SIZE = 1 SHL (32 + XFS_DIR2_DATA_ALIGN_LOG) -XFS_DIR2_FREE_OFFSET = XFS_DIR2_FREE_SPACE * XFS_DIR2_SPACE_SIZE +XFS_DIR2_SPACE_SIZE = (1 SHL (32 + XFS_DIR2_DATA_ALIGN_LOG)) +XFS_DIR2_FREE_OFFSET = (XFS_DIR2_FREE_SPACE * XFS_DIR2_SPACE_SIZE) ; data section magic constants for directories (xfs_dir2_data.h) @@ -526,4 +526,3 @@ struct XFS PARTITION buffer_pos dd ? eof dd ? ends - diff --git a/xfskos.asm b/xfskos.asm deleted file mode 100644 index 035e259..0000000 --- a/xfskos.asm +++ /dev/null @@ -1,416 +0,0 @@ -; lib -; -; Copyright (C) 2012-2013,2016 Ivan Baravy (dunkaist) -; -; This program is free software: you can redistribute it and/or modify -; it under the terms of the GNU General Public License as published by -; the Free Software Foundation, either version 3 of the License, or -; (at your option) any later version. -; -; This program is distributed in the hope that it will be useful, -; but WITHOUT ANY WARRANTY; without even the implied warranty of -; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -; GNU General Public License for more details. -; -; You should have received a copy of the GNU General Public License -; along with this program. If not, see . - -format ELF - -__DEBUG__ = 1 -__DEBUG_LEVEL__ = 2 - -include 'proc32.inc' -include 'struct.inc' -include 'macros.inc' -include 'const.inc' -include 'system.inc' -;include 'fdo.inc' -include 'debug-fdo.inc' -include 'disk.inc' -;include 'fs_lfn.inc' -include 'fs_common.inc' - -ERROR_SUCCESS = 0 -ERROR_DISK_BASE = 1 -ERROR_UNSUPPORTED_FS = 2 -ERROR_UNKNOWN_FS = 3 -ERROR_PARTITION = 4 -ERROR_FILE_NOT_FOUND = 5 -ERROR_END_OF_FILE = 6 -ERROR_MEMORY_POINTER = 7 -ERROR_DISK_FULL = 8 -ERROR_FS_FAIL = 9 -ERROR_ACCESS_DENIED = 10 -ERROR_DEVICE = 11 -ERROR_OUT_OF_MEMORY = 12 - - - -purge section,mov,add,sub -section '.text' executable align 16 - - -;public _start -_start: - -; pushfd -; pop eax -; or eax, 1 SHL 18 ; Alignment Check flag -; push eax -; popfd - - pop eax - cmp eax, 2 - jz .params_ok - .few_arguments: - mov eax, SYS_WRITE - mov ebx, STDOUT - mov ecx, msg_few_args - mov edx, msg_few_args.size - int 0x80 - jmp .error_quit - .params_ok: - pop eax - pop ebx - mov [filename], ebx - mov eax, SYS_OPEN - mov ecx, O_RDONLY OR O_LARGEFILE - int 0x80 - cmp eax, -2 ; FIXME RETURN VALUE - je .file_not_found - mov [fd], eax - - mov eax, 0 - mov ebx, mbr_buffer - mov ebp, partition - call fs_read32_sys - - mov esi, disk - mov [esi + DISK.MediaInfo.SectorSize], 512 - mov ebp, partition - mov [ebp + PARTITION.Disk], esi - mov ebx, mbr_buffer - call xfs_create_partition - test eax, eax - jz .not_xfs_partition - mov [fs_struct], eax - - .next_cmd: - call prompt - call read_cmd - mov eax, dword[cmd_buf] - cmp eax, dword 'exit' - jnz @f - jmp .quit - @@: - cmp ax, word 'ls' - jnz @f - call cmd_ls - jmp .next_cmd - @@: - .unknown: - call unknown_command - jmp .next_cmd - - .quit: - mov eax, SYS_EXIT - xor ebx, ebx - int 0x80 - .not_xfs_partition: - mov eax, SYS_WRITE - mov ebx, STDOUT - mov ecx, msg_not_xfs_partition - mov edx, msg_not_xfs_partition.size - int 0x80 - jmp .error_quit - .file_not_found: - mov eax, SYS_WRITE - mov ebx, STDOUT - mov ecx, msg_file_not_found - mov edx, msg_file_not_found.size - int 0x80 - stdcall print_filename, [filename] - jmp .error_quit - .error_quit: - mov eax, SYS_EXIT - mov ebx, 1 - int 0x80 - - -cmd_ls: - mov ebp, [fs_struct] - mov ebx, sf70_params - mov esi, cmd_buf - mov edi, esi - mov al, ' ' - mov ecx, 100 - repnz scasb - mov [ebx + 0x14], edi - mov eax, edi - sub eax, esi - push eax - mov al, 0x0a - repnz scasb - mov byte[edi-1], 0 - call xfs_ReadFolder - pop eax - - mov eax, sf70_buffer - mov ecx, [eax + 4] ; read bdfes - add eax, 0x20 ; skip header - .next_bdfe: - lea edx, [eax + 0x28] - push eax ecx - stdcall print_filename, edx - pop ecx eax - add eax, 304 - dec ecx - jnz .next_bdfe - - ret - - -public kos_fuse_init -kos_fuse_init: - push ebx esi edi ebp - - mov eax, [esp + 0x14] - mov [fd], eax - - mov eax, 0 - mov ebx, mbr_buffer - mov ebp, partition - call fs_read32_sys - - mov esi, disk - mov [esi + DISK.MediaInfo.SectorSize], 512 - mov ebp, partition - mov [ebp + PARTITION.Disk], esi - mov ebx, mbr_buffer - call xfs_create_partition - test eax, eax - jnz @f - mov eax, SYS_WRITE - mov ebx, STDOUT - mov ecx, msg_not_xfs_partition - mov edx, msg_not_xfs_partition.size - int 0x80 - @@: - mov [fs_struct], eax - - pop ebp edi esi ebx - ret - -;char *hello_readdir(const char *path, off_t offset) -public kos_fuse_readdir -kos_fuse_readdir: - push ebx esi edi ebp - - mov edx, sf70_params - mov dword[edx + 0x00], 1 - mov eax, [esp + 0x18] ; offset - mov [edx + 0x04], eax - mov dword[edx + 0x08], 1 - mov dword[edx + 0x0c], 100 - mov dword[edx + 0x10], sf70_buffer - mov eax, [esp + 0x14] ; path - inc eax ; skip '/' - mov [edx + 0x14], eax - - mov ebp, [fs_struct] - mov ebx, sf70_params - mov esi, eax - push 0 - call xfs_ReadFolder - pop eax - - pop ebp edi esi ebx - mov eax, sf70_buffer - ret - - -unknown_command: - pushad - mov eax, SYS_WRITE - mov ebx, STDOUT - mov ecx, msg_unknown_command - mov edx, msg_unknown_command.size - int 0x80 - popad - ret - - -prompt: - pushad - mov eax, SYS_WRITE - mov ebx, STDOUT - mov ecx, endl_prompt - mov edx, 2 - int 0x80 - popad - ret - -read_cmd: - pushad - mov eax, SYS_READ - mov ebx, STDIN - mov ecx, cmd_buf - mov edx, 4096 - int 0x80 - popad - ret - - -; in: eax = sector, ebx = buffer, ebp = pointer to PARTITION structure -fs_read32_sys: - pushad - imul ecx, eax, 512 - add ecx, 2048*512 - mov eax, SYS_LSEEK - mov ebx, [fd] - mov edx, SEEK_SET - int 0x80 -;DEBUGF 1, "lseek: %x\n", eax - popad - - pushad - mov eax, SYS_READ - mov ecx, ebx - mov ebx, [fd] - mov edx, 512 - int 0x80 -;DEBUGF 1, "read: %d\n", eax - popad - - xor eax, eax - - ret - - -fs_read32_app: - ret - - -fs_read64_sys: - pushad - imul ecx, eax, 512 - add ecx, 2048*512 - mov eax, SYS_LSEEK - mov ebx, [fd] - mov edx, SEEK_SET - int 0x80 -;DEBUGF 1, "lseek: %x\n", eax - popad - - pushad - mov eax, SYS_READ - imul edx, ecx, 512 - mov ecx, ebx - mov ebx, [fd] - int 0x80 -;DEBUGF 1, "read: %d\n", eax - popad - - xor eax, eax - ret - - -fs_read64_app: - ret - - -malloc: - push [alloc_pos] - add [alloc_pos], eax - pop eax - ret - -free: - ret - - -kernel_free: - ret - - -mutex_init: - ret - - -mutex_lock: - ret - - -mutex_unlock: - ret - - -put_board: - pushad - mov eax, SYS_WRITE - mov ebx, STDOUT - push ecx - mov ecx, esp - mov edx, 1 - int 0x80 - pop ecx - popad -ret - - -proc print_filename _filename - stdcall strlen, [_filename] - mov byte[edi - 1], 0x0a - inc edx - mov ecx, [_filename] - mov eax, SYS_WRITE - mov ebx, STDOUT - int 0x80 - ret -endp - - -proc strlen _str - mov edi, [_str] - mov ecx, -1 - xor eax, eax - repnz scasb - not ecx - dec ecx - mov edx, ecx - ret -endp - - -include 'xfs.asm' - - -section '.data' writeable align 16 -msg_few_args db 'usage: xfskos image [offset]',0x0a -msg_few_args.size = $ - msg_few_args -msg_file_not_found db 'file not found: ' -msg_file_not_found.size = $ - msg_file_not_found -msg_unknown_command db 'unknown command',0x0a -msg_unknown_command.size = $ - msg_unknown_command -msg_not_xfs_partition db 'not xfs partition',0x0a -msg_not_xfs_partition.size = $ - msg_not_xfs_partition -endl_prompt db '> ' - -include_debug_strings - -partition_offset dd 2048*512 -alloc_pos dd alloc_base -sf70_params dd 1, 0, 1, 100, sf70_buffer, -1 - - -section '.bss' writeable align 16 -mbr_buffer rb 4096*3 -filename rd 1 -fd rd 1 -cmd_buf rb 4096 -partition PARTITION -disk DISK -alloc_base rb 1024*1024 -fs_struct rd 1 -sf70_buffer rb 1024*1024