fat32: update the code because the author seemed to fix the bugs in a282d4b92fc0ce6bc6dfd08111791b984f6834e4
This commit is contained in:
+2
-1
@@ -8,6 +8,7 @@
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
//#include <stdio.h>
|
||||
#include "../include/stdio.h"
|
||||
#include <stdarg.h>
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
@@ -74,7 +75,7 @@ typedef struct fat_t
|
||||
uint32_t sect_per_clust;
|
||||
uint32_t clust_cnt;
|
||||
uint32_t info_sect;
|
||||
uint32_t fat_sect;
|
||||
uint32_t fat_sect[2];
|
||||
uint32_t data_sect;
|
||||
uint32_t root_sect;
|
||||
|
||||
|
||||
@@ -2,11 +2,8 @@
|
||||
// Copyright (c) 2025, Bjørn Brodtkorb. All rights reserved.
|
||||
|
||||
//#include <string.h>
|
||||
#include "../include/fat.h"
|
||||
#include "../include/stdio.h"
|
||||
#include "../include/string.h"
|
||||
|
||||
#define NULL 0
|
||||
#include "../include/fat.h"
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#define LIMIT(a, b) ((a) < (b) ? (a) : (b))
|
||||
@@ -444,6 +441,7 @@ static fat_t* find_fat_volume(const char* path, int len)
|
||||
if (len == it->pathlen && 0 == memcmp(path, it->path, len))
|
||||
return it;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -559,7 +557,8 @@ static uint32_t clust_to_sect(fat_t* fat, uint32_t clust)
|
||||
//------------------------------------------------------------------------------
|
||||
static int get_fat(fat_t* fat, uint32_t clust, uint32_t* res)
|
||||
{
|
||||
uint32_t sect = fat->fat_sect + clust / 128;
|
||||
// Assume first FAT is correct
|
||||
uint32_t sect = fat->fat_sect[0] + clust / 128;
|
||||
uint32_t off = (clust % 128) << 2;
|
||||
|
||||
int err = move_win(fat, sect);
|
||||
@@ -573,9 +572,9 @@ static int get_fat(fat_t* fat, uint32_t clust, uint32_t* res)
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static int put_fat(fat_t* fat, uint32_t clust, uint32_t val)
|
||||
static int put_fat_in(fat_t* fat, int idx, uint32_t clust, uint32_t val)
|
||||
{
|
||||
uint32_t sect = fat->fat_sect + clust / 128;
|
||||
uint32_t sect = fat->fat_sect[idx] + clust / 128;
|
||||
uint32_t off = 4 * (clust % 128);
|
||||
|
||||
int err = move_win(fat, sect);
|
||||
@@ -590,6 +589,16 @@ static int put_fat(fat_t* fat, uint32_t clust, uint32_t val)
|
||||
return FAT_ERR_NONE;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static int put_fat(fat_t* fat, uint32_t clust, uint32_t val)
|
||||
{
|
||||
int err = put_fat_in(fat, 0, clust, val);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
return put_fat_in(fat, 1, clust, val);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static int get_clust_status(fat_t* fat, uint32_t clust)
|
||||
{
|
||||
@@ -643,7 +652,7 @@ static int clust_chain_remove(fat_t* fat, uint32_t clust)
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
fat->info_cnt--;
|
||||
fat->info_cnt++;
|
||||
clust = next;
|
||||
|
||||
if (status & CLUST_LAST)
|
||||
@@ -942,7 +951,7 @@ static int load_lfn_name(fat_t* fat, dir_t* dir)
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static int dir_search(fat_t* fat, dir_t* dir, const char* name, int len)
|
||||
static int dir_search(fat_t* fat, dir_t* dir, const char* name, int len, dir_t* start)
|
||||
{
|
||||
dir_rewind(fat, dir);
|
||||
|
||||
@@ -959,8 +968,15 @@ static int dir_search(fat_t* fat, dir_t* dir, const char* name, int len)
|
||||
|
||||
if (!dir_ent_is_free(ent))
|
||||
{
|
||||
if (start)
|
||||
{
|
||||
start->sect = dir->sect;
|
||||
start->idx = dir->idx;
|
||||
}
|
||||
|
||||
if (dir_ent_is_lfn(ent))
|
||||
{
|
||||
|
||||
err = load_lfn_name(fat, dir);
|
||||
if (err)
|
||||
return err;
|
||||
@@ -1007,9 +1023,11 @@ static int follow_path(dir_t* dir, const char** path)
|
||||
len = subpath_len(str);
|
||||
if (len == 0)
|
||||
return FAT_ERR_PATH;
|
||||
|
||||
fat_t* fat = find_fat_volume(str, len);
|
||||
if (!fat)
|
||||
return FAT_ERR_PATH;
|
||||
|
||||
str += len;
|
||||
|
||||
dir->fat = fat;
|
||||
@@ -1037,7 +1055,7 @@ static int follow_path(dir_t* dir, const char** path)
|
||||
if (len == 0)
|
||||
return FAT_ERR_NONE;
|
||||
|
||||
err = dir_search(fat, dir, str, len);
|
||||
err = dir_search(fat, dir, str, len, NULL);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
@@ -1184,8 +1202,10 @@ static int get_mbr_partition(fat_t* fat, mbr_part_t* part, int part_num)
|
||||
int err = move_win(fat, 0);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
if (fat->win[510] != 0x55 || fat->win[511] != 0xaa)
|
||||
return FAT_ERR_NOFAT;
|
||||
|
||||
*part = ((mbr_part_t*)(fat->win + 446))[part_num];
|
||||
return FAT_ERR_NONE;
|
||||
}
|
||||
@@ -1238,8 +1258,9 @@ int fat_mount(disk_ops_t* ops, int part_num, fat_t* fat, const char* path)
|
||||
fat->sect_per_clust = bpb->sect_per_clust;
|
||||
fat->clust_cnt = bpb->sect_per_fat_32 * 128;
|
||||
fat->info_sect = part.lba + bpb->info_sect;
|
||||
fat->fat_sect = part.lba + bpb->res_sect_cnt;
|
||||
fat->data_sect = fat->fat_sect + bpb->fat_cnt * bpb->sect_per_fat_32;
|
||||
fat->fat_sect[0] = part.lba + bpb->res_sect_cnt;
|
||||
fat->fat_sect[1] = fat->fat_sect[0] + bpb->sect_per_fat_32;
|
||||
fat->data_sect = fat->fat_sect[0] + bpb->fat_cnt * bpb->sect_per_fat_32;
|
||||
fat->root_sect = clust_to_sect(fat, bpb->root_cluster);
|
||||
|
||||
err = move_win(fat, fat->info_sect);
|
||||
@@ -1258,7 +1279,7 @@ int fat_mount(disk_ops_t* ops, int part_num, fat_t* fat, const char* path)
|
||||
|
||||
fat->info_last = info->next_free;
|
||||
fat->info_cnt = info->free_cnt;
|
||||
|
||||
|
||||
int path_len = strlen(path);
|
||||
if (sizeof(fat->path) < path_len)
|
||||
return FAT_ERR_PARAM;
|
||||
@@ -1345,13 +1366,13 @@ int fat_fopen(file_t* file, const char* path, const char* mode)
|
||||
if (len == 0 || path[len])
|
||||
return FAT_ERR_PATH;
|
||||
|
||||
err = dir_search(fat, dir, path, len);
|
||||
err = dir_search(fat, dir, path, len, NULL);
|
||||
|
||||
if (err == FAT_ERR_EOF)
|
||||
{
|
||||
if (!create)
|
||||
return FAT_ERR_DENIED;
|
||||
|
||||
|
||||
// Create a new file
|
||||
uint32_t new;
|
||||
err = clust_chain_create(fat, &new);
|
||||
@@ -1640,8 +1661,9 @@ int fat_unlink(const char* path)
|
||||
return FAT_ERR_PATH;
|
||||
|
||||
fat_t* fat = dir.fat;
|
||||
dir_t sdir = dir;
|
||||
|
||||
err = dir_search(fat, &dir, path, len);
|
||||
err = dir_search(fat, &dir, path, len, &sdir);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
@@ -1651,8 +1673,23 @@ int fat_unlink(const char* path)
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
ent->name[0] = SFN_FREE;
|
||||
fat->win_dirty = true;
|
||||
for (;;)
|
||||
{
|
||||
err = move_win(fat, sdir.sect);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
dir_ent_t* ent = (dir_ent_t*)(fat->win + sdir.idx);
|
||||
ent->name[0] = SFN_FREE;
|
||||
fat->win_dirty = true;
|
||||
|
||||
if (sdir.sect == dir.sect && sdir.idx == dir.idx)
|
||||
break;
|
||||
|
||||
err = dir_next(fat, &sdir);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
|
||||
return sync_fat(fat);
|
||||
}
|
||||
@@ -1666,11 +1703,15 @@ int fat_mkdir(const char* path)
|
||||
return err;
|
||||
|
||||
fat_t* fat = dir.fat;
|
||||
|
||||
|
||||
int len = subpath_len(path);
|
||||
if (len == 0 || path[len])
|
||||
return FAT_ERR_PATH;
|
||||
|
||||
uint32_t prev = dir.first_clust;
|
||||
if (prev == 2) // Old cluster is the root directory
|
||||
prev = 0;
|
||||
|
||||
// Create a new directory
|
||||
uint32_t new;
|
||||
err = clust_chain_create(fat, &new);
|
||||
@@ -1704,8 +1745,8 @@ int fat_mkdir(const char* path)
|
||||
|
||||
memcpy(ent + 1, ent, sizeof(dir_ent_t));
|
||||
ent[1].name[1] = '.';
|
||||
ent[1].clust_hi = dir.first_clust >> 16;
|
||||
ent[1].clust_lo = dir.first_clust & 0xffff;
|
||||
ent[1].clust_hi = prev >> 16;
|
||||
ent[1].clust_lo = prev & 0xffff;
|
||||
|
||||
err = dir_register(fat, &dir, path, len, FAT_ATTR_DIR, new);
|
||||
if (err)
|
||||
|
||||
Reference in New Issue
Block a user