reading from a root-directory file basically works
This commit is contained in:
parent
46f6fe7494
commit
1e6e6253b9
101
fs/fat32/fat32.c
101
fs/fat32/fat32.c
@ -35,6 +35,7 @@ int fat32_load(Fat32_CtrlBlock *ctrl, uint32_t bpb_s, const MassStorage * mstg)
|
||||
memcpy(ctrl->volume_label, bpb_obj->volume_label, 11);
|
||||
ctrl->serial_number = bpb_obj->volume_serial_number;
|
||||
ctrl->fat_copies = bpb_obj->n_fats;
|
||||
ctrl->fat_entries_per_sector = ctrl->bytes_per_sector / sizeof(Fat32_FatTableEntry);
|
||||
|
||||
ctrl->fat_s = ctrl->bpb_s + bpb_obj->n_reserved_sectors; // FATs are stored on the hidden area right after the reserved sectors
|
||||
ctrl->data_s = ctrl->fat_s + ctrl->fat_copies * ctrl->sectors_per_fat; // data region begins right after the FAT copies
|
||||
@ -166,11 +167,11 @@ int fat32_print_file_entry(Fat32_FileEntry ** const entry) {
|
||||
|
||||
static inline uint16_t fat32_extract_next_basename_length(const char *path) {
|
||||
uint16_t i;
|
||||
for (i = 0; path[i] != FAT32_DIRECTORY_SEPARATOR && path[i] != '\0'; i++) {}
|
||||
for (i = 0; (path[i] != FAT32_DIRECTORY_SEPARATOR) && (path[i] != '\0'); i++) {}
|
||||
return i;
|
||||
}
|
||||
|
||||
int fat32_locate_file(const Fat32_CtrlBlock *ctrl, const char *path) {
|
||||
const Fat32_FileEntry *fat32_locate_file(const Fat32_CtrlBlock *ctrl, const char *path) {
|
||||
FETCH_MSTG;
|
||||
|
||||
// start search in the root directory
|
||||
@ -183,6 +184,8 @@ int fat32_locate_file(const Fat32_CtrlBlock *ctrl, const char *path) {
|
||||
const char *path_iter = path; // path is being fetched from its beginning
|
||||
char basename[FAT32_MAX_BASENAME_LENGTH + 1]; // basename
|
||||
basename[FAT32_MAX_BASENAME_LENGTH] = '\0'; // NULL-termination
|
||||
char entry_name[FAT32_MAX_BASENAME_LENGTH + 1]; // entry name
|
||||
Fat32_FileEntry *entry = NULL; // entry iterator
|
||||
|
||||
while ((!file_found) && (!no_such_file)) {
|
||||
// extract first basename
|
||||
@ -190,10 +193,63 @@ int fat32_locate_file(const Fat32_CtrlBlock *ctrl, const char *path) {
|
||||
uint16_t copy_len = MIN(basename_len, FAT32_MAX_BASENAME_LENGTH);
|
||||
memcpy(basename, path_iter, copy_len); // extract basename
|
||||
basename[copy_len] = '\0'; // NULL-termination
|
||||
path_iter += basename_len + 1; // advance basename
|
||||
path_iter += basename_len; // advance basename
|
||||
|
||||
// search for basename in the current directory
|
||||
// acquire pointer to the beginning of the file entry table
|
||||
entry = (Fat32_FileEntry *) buffer;
|
||||
bool basename_entry_found = false;
|
||||
while ((entry->short_fname[0] != 0x00) && (!basename_entry_found)) {
|
||||
if (entry->short_fname[0] != FAT32_UNUSED_FILE_ENTRY) {
|
||||
fat32_get_file_entry(&entry, entry_name);
|
||||
|
||||
// compare entry name
|
||||
if (!strncmp(entry_name, basename, basename_len)) { // if matches...
|
||||
basename_entry_found = true; // ...then the entry is found
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
entry++;
|
||||
|
||||
// if we crossed the first buffer - second buffer border, then
|
||||
// copy the second buffer to the first one and load the next sector
|
||||
// to the second buffer
|
||||
if ((void *) entry > (void *) (buffer + SECTOR_SIZE)) {
|
||||
// copy the second buffer to the first one
|
||||
fat32_copy_second_to_first_buffer();
|
||||
sector++;
|
||||
READ_MSTG_TO_SECOND_BUFFER(sector + 1);
|
||||
|
||||
// modify the entry pointer, since it's been moved
|
||||
entry = (Fat32_FileEntry *) (((uint8_t *) (entry)) - SECTOR_SIZE);
|
||||
}
|
||||
}
|
||||
|
||||
// if the basename entry is found...
|
||||
if (basename_entry_found) {
|
||||
if (path_iter[0] == '\0') { // ...and it's the end of the path
|
||||
file_found = true; // ...then the file is found
|
||||
} else { // ...if it's not the end of the path, then load the cluster corresponding to the entry
|
||||
// determine sector number
|
||||
uint32_t next_cluster = (entry->first_cluster_high << 16) | (entry->first_cluster_low);
|
||||
uint32_t next_sector = fat32_get_first_sector_of_cluster(ctrl, next_cluster);
|
||||
|
||||
// load sectors
|
||||
READ_MSTG_TO_FIRST_BUFFER(next_sector);
|
||||
READ_MSTG_TO_SECOND_BUFFER(next_sector + 1);
|
||||
}
|
||||
} else { // if not found...
|
||||
no_such_file = true; // ...then the file could not be located
|
||||
}
|
||||
}
|
||||
|
||||
// return with appropriate value
|
||||
if (!no_such_file) {
|
||||
return entry;
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
int fat32_list_dir(const Fat32_CtrlBlock *ctrl, const char *dir) {
|
||||
@ -234,8 +290,35 @@ static inline uint32_t fat32_get_fat_entry_sector_by_cluster_index(const Fat32_C
|
||||
return cluster * sizeof(Fat32_FatTableEntry) / ctrl->bytes_per_sector + ctrl->fat_s;
|
||||
}
|
||||
|
||||
//int fat32_read_file(const Fat32_CtrlBlock * ctrl, uint32_t pos, uint32_t len) {
|
||||
// FETCH_MSTG;
|
||||
// uint32_t fae_sec =
|
||||
// Fat32_FatTableEntry fae =
|
||||
//}
|
||||
static inline uint32_t fat32_get_cluster_from_pos(const Fat32_CtrlBlock * ctrl, uint32_t first_cluster, uint32_t pos) {
|
||||
FETCH_MSTG;
|
||||
uint32_t cluster_link_number = pos / (ctrl->sectors_per_cluster * ctrl->bytes_per_sector); // calculate the sequence number of the FAT entry containing the reference to the desired data cluster
|
||||
uint32_t fat_iter_sector = 0;
|
||||
uint32_t cluster = first_cluster; // linked cluster
|
||||
Fat32_FatTableEntry * fat_iter = NULL; // iterator on FAT table
|
||||
|
||||
for (uint32_t hop = 0; hop < cluster_link_number; hop++) {
|
||||
uint32_t new_fat_iter_sector = fat32_get_fat_entry_sector_by_cluster_index(ctrl, cluster); // get the FAT sector containing the referred entry
|
||||
if (new_fat_iter_sector != fat_iter_sector) {
|
||||
READ_MSTG_TO_FIRST_BUFFER(new_fat_iter_sector); // read FAT sector containing the specific entry to the buffer
|
||||
fat_iter_sector = new_fat_iter_sector;
|
||||
}
|
||||
fat_iter = ((Fat32_FatTableEntry *) buffer) + (cluster % ctrl->fat_entries_per_sector); // get FAT iter
|
||||
uint32_t next_cluster = (*fat_iter) & ~(0xF << 28);
|
||||
if (next_cluster >= 2 && next_cluster <= 0xFFFFFEF) {
|
||||
cluster = next_cluster;
|
||||
}
|
||||
}
|
||||
return cluster;
|
||||
}
|
||||
|
||||
int fat32_read_file(const Fat32_CtrlBlock * ctrl, const Fat32_FileEntry * entry, uint32_t pos, uint32_t len, uint8_t * p) {
|
||||
FETCH_MSTG;
|
||||
uint32_t first_cluster = (entry->first_cluster_high << 16) | (entry->first_cluster_low);
|
||||
uint32_t cluster = fat32_get_cluster_from_pos(ctrl, first_cluster, pos);
|
||||
uint32_t sector = fat32_get_first_sector_of_cluster(ctrl, cluster);
|
||||
READ_MSTG_TO_FIRST_BUFFER(sector);
|
||||
uint32_t pos_in_sector = pos % ctrl->bytes_per_sector;
|
||||
memcpy(p, buffer + pos_in_sector, len);
|
||||
return len; // TODO
|
||||
}
|
@ -50,6 +50,7 @@ typedef struct {
|
||||
uint32_t sectors_per_fat; // sectors per FAT table
|
||||
uint16_t bytes_per_sector; // number of bytes creating a sector
|
||||
uint16_t sectors_per_cluster; // number of sectors creating a cluster
|
||||
uint16_t fat_entries_per_sector; // number of FAT entries per sector
|
||||
uint8_t fat_copies; // number of FAT table copies
|
||||
uint8_t volume_label[11]; // pointer to volume label
|
||||
} Fat32_CtrlBlock;
|
||||
@ -94,8 +95,8 @@ int fat32_load(Fat32_CtrlBlock *ctrl, uint32_t bpb_s, const MassStorage * mstg);
|
||||
|
||||
int fat32_list_dir(const Fat32_CtrlBlock *ctrl, const char * dir);
|
||||
|
||||
int fat32_read_file(const Fat32_CtrlBlock * ctrl, uint32_t pos, uint32_t len);
|
||||
int fat32_read_file(const Fat32_CtrlBlock * ctrl, const Fat32_FileEntry * entry, uint32_t pos, uint32_t len, uint8_t * p);
|
||||
|
||||
int fat32_locate_file(const Fat32_CtrlBlock *ctrl, const char *path);
|
||||
const Fat32_FileEntry * fat32_locate_file(const Fat32_CtrlBlock *ctrl, const char *path);
|
||||
|
||||
#endif //EMBPART_FAT32_H
|
||||
|
Loading…
x
Reference in New Issue
Block a user