summaryrefslogtreecommitdiff
path: root/src/kernel/fat.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/kernel/fat.c')
-rw-r--r--src/kernel/fat.c82
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