From 4361041d09d939f35fba361b4ca2a0cca72576d9 Mon Sep 17 00:00:00 2001 From: d0p1 Date: Sun, 3 Mar 2024 16:38:54 +0100 Subject: [PATCH] feat(tools): list file in fat12 root directory --- tools/fat.c | 114 +++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 104 insertions(+), 10 deletions(-) diff --git a/tools/fat.c b/tools/fat.c index e18838f..17838fd 100644 --- a/tools/fat.c +++ b/tools/fat.c @@ -32,7 +32,24 @@ typedef struct uint8_t fs_type[8]; } __attribute__((packed)) BiosParamBlock; +typedef struct +{ + uint8_t name[8]; + uint8_t ext[3]; + uint8_t attr; + uint16_t reserved0; + uint16_t creation_time; + uint16_t creation_date; + uint16_t access_date; + uint16_t reserved1; + uint16_t mod_time; + uint16_t mod_date; + uint16_t start; + uint32_t size; +} __attribute__((packed)) Entry; + static const char *prg_name; +static int sector_size = 512; static void fatal(const char *str, ...) @@ -48,27 +65,104 @@ fatal(const char *str, ...) exit(EXIT_FAILURE); } +static void +read_sector(uint8_t *dest, int sect, FILE *fp) +{ + if (fseek(fp, sect*sector_size, SEEK_SET) != 0) goto fatal_sect; + if (fread(dest, 1, sector_size, fp) != sector_size) goto fatal_sect; + + return; + + fatal_sect: + fatal("Can't read sector %d", sect); +} + +static void +dump_bpb(BiosParamBlock *bpb) +{ + char label[12]; + + printf("Bytes per logical sector: %hd\n", bpb->bytes_per_sector); + sector_size = bpb->bytes_per_sector; + printf("Logical sectors per cluster: %d\n", bpb->sectors_per_cluster); + printf("Reserved logical sectors: %hd\n", bpb->reserved_sectors); + printf("Number of FATs: %d\n", bpb->number_of_FATs); + printf("Root directory entries: %hd\n", bpb->root_entries); + printf("Total logical sectors: %hd\n", bpb->logical_sectors); + printf("Logical sectors per FAT: %hd\n", bpb->sectors_per_FAT); + printf("Serial: %X\n", bpb->serial); + memset(label, 0, 12); + strncpy(label, bpb->label, 11); + printf("Label: '%s'\n", label); + printf("signature: %X\n", bpb->signature); +} + +static void +dump_entry(Entry *entry) +{ + char filename[9]; + char ext[4]; + int i; + + if (entry->name[0] == 0x0) return; + + memset(filename, 0, 9); + strncpy(filename, entry->name, 8); + memset(ext, 0, 4); + strncpy(ext, entry->ext, 3); + for (i = 7; i > 0; i--) + { + if (filename[i] == ' ') + { + filename[i] = '\0'; + } + else + { + break; + } + } + + printf("%s.%s\n", filename, ext); +} + static void dump(const char *img) { FILE *fp; - BiosParamBlock bpb; - char label[12]; + BiosParamBlock *bpb; + uint8_t buffer[512]; + int root_start; + int root_size; + int i; + int j; fp = fopen(img, "rb"); if (fp == NULL) fatal("Can't open '%s': %s", img, strerror(errno)); - if (fread(&bpb, 1, sizeof(BiosParamBlock), fp) != sizeof(BiosParamBlock)) + read_sector(buffer, 0, fp); + if (buffer[511] != 0xAA || buffer[510] != 0x55) { - fatal("Can't read BPB"); + fatal("MBR not found"); + } + + bpb = (BiosParamBlock *)buffer; + + dump_bpb(bpb); + + root_start = bpb->sectors_per_FAT * bpb->number_of_FATs; + root_start += bpb->reserved_sectors; + + root_size = bpb->root_entries / (sector_size >> 0x5); + + for (i = 0; i < root_size; i++) + { + read_sector(buffer, root_start + i, fp); + for (j = 0; j < sector_size; j+=32) + { + dump_entry((Entry *)(buffer + j)); + } } - printf("Bytes per logical sector: %hd\n", bpb.bytes_per_sector); - printf("Logical sectors per cluster: %d\n", bpb.sectors_per_cluster); - memset(label, 0, 12); - strncpy(label, bpb.label, 11); - printf("Label: '%s'\n", label); - printf("signature: %X\n", bpb.signature); fclose(fp); exit(EXIT_SUCCESS); }