#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); } bool to_fat_name(uint8_t *sname, uint8_t *fname) { uint8_t *sp = sname, *fp = fname; while (*sp != '.') { if (!*sp) { while (fp != fname + 11) *(fp++) = ' '; return false; } if (sp == sname + 8) return true; *(fp++) = *(sp++); } while (fp != fname + 8) *(fp++) = ' '; while (*++sp) { if (fp == fname + 11) return true; *(fp++) = *sp; } while (fp != fname + 11) *(fp++) = ' '; return false; } 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)); } 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) { uint8_t fname[11]; if (to_fat_name(name, fname)) return 0; struct directory_entry *ptr = buffer; uint16_t dir_current = dir_start; read_sectors(buffer_from = dir_current, 1, buffer); while (*(uint8_t *)ptr) { if (check_fat_names(ptr->name, fname)) return ptr; if (++ptr == buffer + 16) { read_sectors(buffer_from = ++dir_current, 1, buffer); ptr = buffer; } }; return 0; } bool load_subdir(uint8_t *name) { struct directory_entry *e = load_subentry(name); if (!e) return true; dir_start = CTOS(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; }