FAT32 - Can't read file names
Posted: Mon May 20, 2019 10:43 am
Again me, now I'm trying to implement FAT32 filesystem support.
I successfully abled to read the BPB and MBR, but now when I try to read the names of the files that are in the root directory, it doesn't work. Just displays "no more files"
The virtual harddisk image is formatted in FAT32 using fdisk.
fat32.c
As ever, thanks.
I successfully abled to read the BPB and MBR, but now when I try to read the names of the files that are in the root directory, it doesn't work. Just displays "no more files"
The virtual harddisk image is formatted in FAT32 using fdisk.
fat32.c
Code: Select all
#include <stdint.h>
#include <drivers/storage/hdd/hd.h>
#include <kernel/terminal.h>
#include <stdbool.h>
#define FATBPB_SIZE sizeof(struct FATBPB)
#define FAT32_FILES_PER_DIRECTORY 16
struct FATBPB
{
uint8_t jump[3];
uint8_t oem_id[8];
uint16_t bytes_per_sector;
uint8_t sectors_per_cluster;
uint16_t reserved_sectors;
uint8_t fats_number;
uint16_t dir_entries;
uint16_t logical_sectors;
uint8_t media_type;
uint16_t sectors_fat; /* FAT12- FAT16 only! */
uint16_t sectors_per_track;
uint16_t head_number;
uint32_t hidden_sectors;
uint32_t large_sector_count;
/* EBPB */
uint32_t sectors_per_fat;
uint16_t flags;
uint16_t fat_ver;
uint32_t cluster_root;
uint16_t fat_info;
uint32_t backup_sector;
uint8_t res[12];
uint8_t drive_number;
uint8_t res2;
uint8_t signature;
uint32_t volume_id;
uint8_t volume_label[11];
uint8_t boot_code[8];
uint16_t file_system;
}__attribute__((packed));
struct DirectoryEntry
{
uint8_t file_name[11];
uint8_t attributes;
uint8_t res;
uint8_t ctimeT;
uint16_t ctime;
uint16_t cdate;
uint16_t last_access;
uint16_t cluster_number_hi;
uint16_t lmtime;
uint16_t lmdate;
uint16_t cluster_number_lo;
uint32_t file_size;
}__attribute__((packed));
struct FATInfo
{
bool fixed_media;
};
/* Global declaration of an FAT BPB struct */
struct FATBPB bpb;
void read_bpb(uint32_t offset)
{
hd_read(offset, FATBPB_SIZE, (uint8_t*)&bpb);
struct DirectoryEntry drce[FAT32_FILES_PER_DIRECTORY];
uint32_t fat_start = (offset + bpb.reserved_sectors);
uint32_t fat_size = bpb.sectors_per_fat;
uint32_t start_of_data = fat_start * bpb.fats_number;
uint32_t start_of_root = (start_of_data + bpb.sectors_per_cluster) * (bpb.cluster_root - 2);
hd_read(start_of_root, FAT32_FILES_PER_DIRECTORY * sizeof(struct DirectoryEntry), (uint8_t*)&drce[0]);
for (int i = 0; i < FAT32_FILES_PER_DIRECTORY; ++i) {
if (drce[i].file_name[0] == 0x00) {
kputs("\n-- No more files in the directory --\n");
break;
}
if ((drce[i].attributes & 0x0F) == 0x0F)
continue;
/* Horrible solution, I'll fix this later, I promise */
char* asd = " \n";
for (int j = 0; j < 8; ++j) {
asd[j] = drce[i].file_name[j];
}
/* This should print the names of the files that are in the root directory... */
kputs(asd);
if ((drce[i].attributes & 0x10) == 0x10)
continue;
uint32_t fcluster = ((uint32_t)drce[i].cluster_number_hi) << 16 | ((uint32_t)drce[i].cluster_number_lo);
uint32_t fsect = start_of_data + bpb.sectors_per_cluster * (fcluster - 2);
uint8_t buff[512];
hd_read(fsect, 512, buff);
buff[drce[i].file_size] = '\0';
kputs("%s", (char*)buff);
}
}
/* Returs FALSE if the media is fixed, true if otherwise */
bool fat32_media_type(void)
{
/* All these values are valid for removable media, e.g: USB, floppy disk, etc */
uint8_t removable_media_valid_values[9] = {0xF0, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF};
for (int i = 0; i < 9; ++i)
if (bpb.media_type == removable_media_valid_values[i])
return true;
/* Media is an fixed one, e.g: HDD */
if (bpb.media_type == 0xF8) {
kputs("Fixed media\n");
return false;
}
}
/* Returns the volume label */
char* fat32_get_label(void)
{
return bpb.volume_label;
}