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.c67
1 files changed, 67 insertions, 0 deletions
diff --git a/src/kernel/fat.c b/src/kernel/fat.c
index c4461de..362539c 100644
--- a/src/kernel/fat.c
+++ b/src/kernel/fat.c
@@ -365,6 +365,72 @@ static uint32_t fat_enumerate_dir(const struct drive *d, const char *path, struc
}
}
+static uint32_t n_root_entries(const struct drive *d) {
+ uint32_t sect = infos[d->drive_id].root_start - 1;
+ struct directory_entry *entry = (struct directory_entry *)(fat_driver_buffer + 512);
+
+ uint32_t count = 0;
+
+ while (true) {
+ if (entry == (struct directory_entry *)(fat_driver_buffer + 512)) {
+ entry = (struct directory_entry *)fat_driver_buffer;
+ ++sect;
+ d->read_sectors(d, sect, 1, entry);
+ }
+
+ if (!*(uint8_t *)entry) {
+ d->done(d);
+ return count;
+ }
+
+ if (entry-> attrib & FA_LABEL) {
+ ++entry;
+ continue;
+ }
+
+ ++entry;
+ ++count;
+ }
+}
+
+static uint32_t fat_n_dir_entries(const struct drive *d, const char *path) {
+ d->ready(d);
+
+ if (!*path)
+ return n_root_entries(d);
+
+ if (!try_load_from_path(d, path)) {
+ d->done(d);
+ return 0;
+ }
+
+ uint16_t cluster = cur_dir->first_cluster;
+ load_cluster(cluster, fat_driver_buffer);
+ struct directory_entry *entry = (struct directory_entry *)fat_driver_buffer;
+
+ uint32_t count = 0;
+
+ while (true) {
+ if (entry == (struct directory_entry *)(fat_driver_buffer + 512)) {
+ entry = (struct directory_entry *)fat_driver_buffer;
+ load_cluster(cluster = next_cluster(cluster), fat_driver_buffer);
+ }
+
+ if (!*(uint8_t *)entry) {
+ d->done(d);
+ return count;
+ }
+
+ if (check_fat_names(entry->name, this_dir) || check_fat_names(entry->name, parent_dir)) {
+ ++entry;
+ continue;
+ }
+
+ ++entry;
+ ++count;
+ }
+}
+
void init_fat() {
next_fi = allocate_kernel_pages(1);
next_id = 0;
@@ -388,6 +454,7 @@ bool try_fat_init_drive(struct drive *d) {
d->load_sector = &fat_load_sector;
d->get_file_length = &fat_get_file_length;
d->enumerate_dir = &fat_enumerate_dir;
+ d->n_dir_entries = &fat_n_dir_entries;
d->get_free_sectors = &fat_get_free_sectors;
d->fs_id = next_id;