diff --git a/kocdecl.asm b/kocdecl.asm index d7cd431..e8703a4 100644 --- a/kocdecl.asm +++ b/kocdecl.asm @@ -1,7 +1,7 @@ format ELF __DEBUG__ = 1 -__DEBUG_LEVEL__ = 2 +__DEBUG_LEVEL__ = 1 include 'proc32.inc' include 'struct.inc' @@ -26,6 +26,21 @@ ERROR_ACCESS_DENIED = 10 ERROR_DEVICE = 11 ERROR_OUT_OF_MEMORY = 12 +struct FS_FUNCTIONS + Free dd ? + Size dd ? + ReadFile dd ? + ReadFolder dd ? + CreateFile dd ? + WriteFile dd ? + SetFileEnd dd ? + GetFileInfo dd ? + SetFileInfo dd ? + Run dd ? + Delete dd ? + CreateFolder dd ? +ends + purge section,mov,add,sub section '.text' executable align 16 @@ -88,6 +103,32 @@ kos_fuse_readdir: ret +public kos_fuse_getattr +kos_fuse_getattr: + push ebx esi edi ebp + + mov edx, sf70_params + mov dword[edx + 0x00], 5 + mov dword[edx + 0x04], 0 + mov dword[edx + 0x08], 0 + mov dword[edx + 0x0c], 0 + 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_GetFileInfo + 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 @@ -178,6 +219,7 @@ put_board: ret +;include 'ext.inc' include 'xfs.asm' diff --git a/kocdecl.h b/kocdecl.h index 6603eea..9d31c4d 100644 --- a/kocdecl.h +++ b/kocdecl.h @@ -1,7 +1,29 @@ #ifndef KOS_H_INCLUDED #define KOS_H_INCLUDED +#include + +struct bdfe { + uint32_t attr; + uint32_t enc; + uint32_t ctime; + uint32_t cdate; + uint32_t atime; + uint32_t adate; + uint32_t mtime; + uint32_t mdate; + uint64_t size; + char name[264]; +}; + +#define KF_READONLY 0x01 +#define KF_HIDDEN 0x02 +#define KF_SYSTEM 0x04 +#define KF_LABEL 0x08 +#define KF_FOLDER 0x10 + void kos_fuse_init(int fd); -char *kos_fuse_readdir(const char *path, off_t offset); +uint8_t *kos_fuse_readdir(const char *path, off_t offset); +void *kos_fuse_getattr(const char *path); #endif diff --git a/kofu.c b/kofu.c index 3ce20a1..0bda593 100644 --- a/kofu.c +++ b/kofu.c @@ -2,6 +2,7 @@ #include #include #include +#include #include #include #include @@ -23,13 +24,25 @@ int main(int argc, char **argv) { //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; + fgets(cmd_buf, 4095, stdin); + int len = strlen(cmd_buf); + cmd_buf[len-1] = '\0'; +// printf("'%s'\n", cmd_buf); + if (!strncmp(cmd_buf, "ls ", 3)) { + void *header = kos_fuse_readdir(cmd_buf + 4, 0); + uint32_t file_cnt = ((uint32_t*)header)[1]; + printf("file_cnt: %u\n", file_cnt); + struct bdfe *kf = header + 0x20; + for (; file_cnt > 0; file_cnt--) { + printf("%s\n", kf->name); + kf++; + } + } else if (!strncmp(cmd_buf, "stat ", 5)) { + struct bdfe *kf = kos_fuse_getattr(cmd_buf + 5); + printf("attr: 0x%2.2x\n", kf->attr); + printf("size: %llu\n", kf->size); + } else { + printf("unknown command: %s\n", cmd_buf); } } diff --git a/kofuse.c b/kofuse.c index 741fc7c..bbd274d 100644 --- a/kofuse.c +++ b/kofuse.c @@ -6,104 +6,123 @@ #include #include #include +#include #include #include "kocdecl.h" +static void bdfe_to_stat(struct bdfe *kf, struct stat *st) { + if (kf->attr & KF_FOLDER) { + st->st_mode = S_IFDIR | 0755; + st->st_nlink = 2; + } else { + st->st_mode = S_IFREG | 0444; + st->st_nlink = 1; + st->st_size = kf->size; + } +} + static void *hello_init(struct fuse_conn_info *conn, - struct fuse_config *cfg) -{ - (void) conn; - cfg->kernel_cache = 1; - return NULL; + 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; + 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+1, "blah") == 0) { - stbuf->st_mode = S_IFREG | 0444; - stbuf->st_nlink = 1; - stbuf->st_size = strlen("blah"); - } else - res = -ENOENT; +// memset(stbuf, 0, sizeof(struct stat)); +// if (strcmp(path, "/") == 0) { +// stbuf->st_mode = S_IFDIR | 0755; +// stbuf->st_nlink = 2; +// } else { + struct bdfe *kf = kos_fuse_getattr(path); + bdfe_to_stat(kf, stbuf); +// } - return res; +/* + if (strcmp(path, "/") == 0) { + stbuf->st_mode = S_IFDIR | 0755; + stbuf->st_nlink = 2; + } else if (strcmp(path+1, "blah") == 0) { + stbuf->st_mode = S_IFREG | 0444; + stbuf->st_nlink = 1; + stbuf->st_size = strlen("blah"); + } else + res = -ENOENT; +*/ + return res; } static int hello_readdir(const char *path, void *buf, fuse_fill_dir_t filler, - off_t offset, struct fuse_file_info *fi, - enum fuse_readdir_flags flags) -{ - (void) offset; - (void) fi; - (void) flags; + 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); + void *header = kos_fuse_readdir(path, offset); -// if (strcmp(path, "/") != 0) -// return -ENOENT; - uint32_t i = *(uint32_t*)(bdfe + 4); +// if (strcmp(path, "/") != 0) +// return -ENOENT; + uint32_t i = *(uint32_t*)(header + 4); // int f = open("/tmp/t", O_RDWR | O_CREAT); // write(f, bdfe, 1000); // write(f, &i, 4); // close(f); - bdfe += 0x20; + struct bdfe *kf = header + 0x20; for(; i>0; i--) { - filler(buf, bdfe + 0x28, NULL, 0, 0); - bdfe += 304; + filler(buf, kf->name, NULL, 0, 0); + kf++; } - return 0; + return 0; } -static int hello_open(const char *path, struct fuse_file_info *fi) -{ - if (strcmp(path+1, "blah") != 0) - return -ENOENT; +static int hello_open(const char *path, struct fuse_file_info *fi) { + if (strcmp(path+1, "blah") != 0) + return -ENOENT; - if ((fi->flags & O_ACCMODE) != O_RDONLY) - return -EACCES; + if ((fi->flags & O_ACCMODE) != O_RDONLY) + return -EACCES; - return 0; + return 0; } static int hello_read(const char *path, char *buf, size_t size, off_t offset, - struct fuse_file_info *fi) -{ - size_t len; - (void) fi; - if(strcmp(path+1, "blah") != 0) - return -ENOENT; + struct fuse_file_info *fi) { + size_t len; + (void) fi; + if(strcmp(path+1, "blah") != 0) + return -ENOENT; - len = strlen("blah"); - if (offset < len) { - if (offset + size > len) - size = len - offset; - memcpy(buf, "blah" + offset, size); - } else - size = 0; + len = strlen("blah"); + if (offset < len) { + if (offset + size > len) + size = len - offset; + memcpy(buf, "blah" + offset, size); + } else + size = 0; - return size; + return size; } static struct fuse_operations hello_oper = { - .init = hello_init, - .getattr = hello_getattr, - .readdir = hello_readdir, - .open = hello_open, - .read = hello_read, + .init = hello_init, + .getattr = hello_getattr, + .readdir = hello_readdir, + .open = hello_open, + .read = hello_read, }; -int main(int argc, char *argv[]) -{ +int main(int argc, char *argv[]) { + if (argc != 3) { + printf("usage: kofuse dir img\n"); + exit(1); + } int fd = open(argv[2], O_RDONLY); kos_fuse_init(fd); - return fuse_main(argc-1, argv, &hello_oper, NULL); + return fuse_main(argc-1, argv, &hello_oper, NULL); } diff --git a/makefile b/makefile index 5d9d6e6..c9d45a4 100644 --- a/makefile +++ b/makefile @@ -13,10 +13,10 @@ kofuse: kofuse.o kocdecl.o kocdecl.o: kocdecl.asm xfs.inc xfs.asm $(FASM) $< $@ -kofu.o: kofu.c +kofu.o: kofu.c kocdecl.h $(CC) $(CFLAGS) -c $< -kofuse.o: kofuse.c +kofuse.o: kofuse.c kocdecl.h $(CC) $(CFLAGS) `pkg-config fuse3 --cflags` -c $< .PHONY: all clean diff --git a/system.inc b/system.inc index a7d6de6..501479a 100644 --- a/system.inc +++ b/system.inc @@ -15,3 +15,5 @@ O_LARGEFILE = 0x8000 STDIN = 0 STDOUT = 1 STDERR = 2 + +ENOENT = 2