diff options
Diffstat (limited to 'src/kernel/fat.c')
-rw-r--r-- | src/kernel/fat.c | 82 |
1 files changed, 74 insertions, 8 deletions
diff --git a/src/kernel/fat.c b/src/kernel/fat.c index 00fa61f..e574da5 100644 --- a/src/kernel/fat.c +++ b/src/kernel/fat.c @@ -1,21 +1,87 @@ #include "fat.h" #include "ata.h" #include "panic.h" +#include "fs.h" void load_fat() { read_sectors(FAT_INFO->reserved_sectors, FAT_INFO->sectors_per_fat, FAT); } -uint16_t get_cluster(uint16_t n) { - uint32_t t = *(uint32_t *)(FAT + (n / 2) * 3); - return (n % 2 ? (t >> 12) : t) & 0xfff; +bool check_fat_name(uint8_t *fname, uint8_t *sname) { + panic("Not implemented (check_fat_name)"); } -void set_cluster(uint16_t n, uint16_t v) { - uint32_t *t = (uint32_t *)(FAT + (n / 2) * 3); - *t = (*t & (n % 2 ? 0xff000fff : 0xfffff000)) | (n % 2 ? v << 12 : v); +bool check_fat_names(uint8_t *lname, uint8_t *rname) { + return (* (uint32_t *)lname == *(uint32_t *)rname) && + (*((uint32_t *)lname + 1) == *((uint32_t *)rname + 1)) && + (*((uint16_t *)lname + 4) == *((uint16_t *)rname + 4)) && + (*( lname + 10) == *( rname + 10)); } -uint16_t get_start_cluster(uint8_t *path) { - panic("Not implemented (get_start_cluster)."); +struct directory_entry buffer[16]; +uint16_t dir_start, buffer_from; + + +void load_root() { + dir_start = FAT_INFO->reserved_sectors + FAT_INFO->sectors_per_fat; +} + +struct directory_entry *load_subentry(uint8_t *name) { + struct directory_entry *ptr = buffer; + uint16_t dir_current = dir_start; + do + if (((ptr == buffer + 16) && !read_sectors(buffer_from = dir_current++, 1, ptr = buffer)) || !ptr->name[0]) + return 0; + while (!check_fat_name(ptr->name, name)); + return ptr; +} + +bool load_subdir(uint8_t *name) { + struct directory_entry *e = load_subentry(name); + if (!e) + return true; + dir_start = e->first_cluster; + return false; +} + +struct directory_entry *load_entry(uint8_t *path) { + load_root(); + for (uint8_t *ptr = path; ptr; ++ptr) + if (*ptr = '/') { + *ptr = 0; + if (load_subdir(path)) + return 0; + path = ptr + 1; + } + return load_subentry(path); +} + +bool get_entry(uint8_t *path, struct directory_entry *at) { + struct directory_entry *e = load_entry(path); + if (!e) + return true; + *at = *e; + return false; +} + +bool update_entry(uint8_t *path, struct directory_entry *value) { + struct directory_entry *e = load_entry(path); + if (!e) + return true; + *e = *value; + write_sectors(buffer_from, 1, buffer); + return false; +} + +bool create_entry(uint8_t *dir_path, struct directory_entry *value) { + fs_handle h = fs_open(dir_path); + struct directory_entry *check; + while (fs_read(h, 32, check)) + if (check_fat_names(check->name, value->name)) { + fs_close(h); + return true; + } + fs_write(h, 32, value); + fs_close(h); + return false; }
\ No newline at end of file |