diff options
author | Benji Dial <benji6283@gmail.com> | 2020-09-19 14:53:29 -0400 |
---|---|---|
committer | Benji Dial <benji6283@gmail.com> | 2020-09-19 14:53:29 -0400 |
commit | de20d7430df08731d9108acb83e1234ba7f1fe16 (patch) | |
tree | 8646f3d1bae3d30391df34766e3e58c0c2af8aab /src/kernel/fat.c | |
parent | 20853582d5385d12421433d21910e783caa00764 (diff) | |
download | portland-os-de20d7430df08731d9108acb83e1234ba7f1fe16.tar.gz |
file manager
Diffstat (limited to 'src/kernel/fat.c')
-rw-r--r-- | src/kernel/fat.c | 67 |
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; |