feat(tools): list file in fat12 root directory
This commit is contained in:
parent
060c2835f6
commit
4361041d09
114
tools/fat.c
114
tools/fat.c
|
@ -32,7 +32,24 @@ typedef struct
|
||||||
uint8_t fs_type[8];
|
uint8_t fs_type[8];
|
||||||
} __attribute__((packed)) BiosParamBlock;
|
} __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 const char *prg_name;
|
||||||
|
static int sector_size = 512;
|
||||||
|
|
||||||
static void
|
static void
|
||||||
fatal(const char *str, ...)
|
fatal(const char *str, ...)
|
||||||
|
@ -48,27 +65,104 @@ fatal(const char *str, ...)
|
||||||
exit(EXIT_FAILURE);
|
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
|
static void
|
||||||
dump(const char *img)
|
dump(const char *img)
|
||||||
{
|
{
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
BiosParamBlock bpb;
|
BiosParamBlock *bpb;
|
||||||
char label[12];
|
uint8_t buffer[512];
|
||||||
|
int root_start;
|
||||||
|
int root_size;
|
||||||
|
int i;
|
||||||
|
int j;
|
||||||
|
|
||||||
fp = fopen(img, "rb");
|
fp = fopen(img, "rb");
|
||||||
if (fp == NULL) fatal("Can't open '%s': %s", img, strerror(errno));
|
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);
|
fclose(fp);
|
||||||
exit(EXIT_SUCCESS);
|
exit(EXIT_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue