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 <stdbool.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
//#include <stdio.h>
|
//#include <stdio.h>
|
||||||
|
#include "../include/stdio.h"
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
@@ -74,7 +75,7 @@ typedef struct fat_t
|
|||||||
uint32_t sect_per_clust;
|
uint32_t sect_per_clust;
|
||||||
uint32_t clust_cnt;
|
uint32_t clust_cnt;
|
||||||
uint32_t info_sect;
|
uint32_t info_sect;
|
||||||
uint32_t fat_sect;
|
uint32_t fat_sect[2];
|
||||||
uint32_t data_sect;
|
uint32_t data_sect;
|
||||||
uint32_t root_sect;
|
uint32_t root_sect;
|
||||||
|
|
||||||
|
|||||||
@@ -2,11 +2,8 @@
|
|||||||
// Copyright (c) 2025, Bjørn Brodtkorb. All rights reserved.
|
// Copyright (c) 2025, Bjørn Brodtkorb. All rights reserved.
|
||||||
|
|
||||||
//#include <string.h>
|
//#include <string.h>
|
||||||
#include "../include/fat.h"
|
|
||||||
#include "../include/stdio.h"
|
|
||||||
#include "../include/string.h"
|
#include "../include/string.h"
|
||||||
|
#include "../include/fat.h"
|
||||||
#define NULL 0
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
#define LIMIT(a, b) ((a) < (b) ? (a) : (b))
|
#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))
|
if (len == it->pathlen && 0 == memcmp(path, it->path, len))
|
||||||
return it;
|
return it;
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
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)
|
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;
|
uint32_t off = (clust % 128) << 2;
|
||||||
|
|
||||||
int err = move_win(fat, sect);
|
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);
|
uint32_t off = 4 * (clust % 128);
|
||||||
|
|
||||||
int err = move_win(fat, sect);
|
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;
|
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)
|
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)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
fat->info_cnt--;
|
fat->info_cnt++;
|
||||||
clust = next;
|
clust = next;
|
||||||
|
|
||||||
if (status & CLUST_LAST)
|
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);
|
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 (!dir_ent_is_free(ent))
|
||||||
{
|
{
|
||||||
|
if (start)
|
||||||
|
{
|
||||||
|
start->sect = dir->sect;
|
||||||
|
start->idx = dir->idx;
|
||||||
|
}
|
||||||
|
|
||||||
if (dir_ent_is_lfn(ent))
|
if (dir_ent_is_lfn(ent))
|
||||||
{
|
{
|
||||||
|
|
||||||
err = load_lfn_name(fat, dir);
|
err = load_lfn_name(fat, dir);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
@@ -1007,9 +1023,11 @@ static int follow_path(dir_t* dir, const char** path)
|
|||||||
len = subpath_len(str);
|
len = subpath_len(str);
|
||||||
if (len == 0)
|
if (len == 0)
|
||||||
return FAT_ERR_PATH;
|
return FAT_ERR_PATH;
|
||||||
|
|
||||||
fat_t* fat = find_fat_volume(str, len);
|
fat_t* fat = find_fat_volume(str, len);
|
||||||
if (!fat)
|
if (!fat)
|
||||||
return FAT_ERR_PATH;
|
return FAT_ERR_PATH;
|
||||||
|
|
||||||
str += len;
|
str += len;
|
||||||
|
|
||||||
dir->fat = fat;
|
dir->fat = fat;
|
||||||
@@ -1037,7 +1055,7 @@ static int follow_path(dir_t* dir, const char** path)
|
|||||||
if (len == 0)
|
if (len == 0)
|
||||||
return FAT_ERR_NONE;
|
return FAT_ERR_NONE;
|
||||||
|
|
||||||
err = dir_search(fat, dir, str, len);
|
err = dir_search(fat, dir, str, len, NULL);
|
||||||
if (err)
|
if (err)
|
||||||
return 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);
|
int err = move_win(fat, 0);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
if (fat->win[510] != 0x55 || fat->win[511] != 0xaa)
|
if (fat->win[510] != 0x55 || fat->win[511] != 0xaa)
|
||||||
return FAT_ERR_NOFAT;
|
return FAT_ERR_NOFAT;
|
||||||
|
|
||||||
*part = ((mbr_part_t*)(fat->win + 446))[part_num];
|
*part = ((mbr_part_t*)(fat->win + 446))[part_num];
|
||||||
return FAT_ERR_NONE;
|
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->sect_per_clust = bpb->sect_per_clust;
|
||||||
fat->clust_cnt = bpb->sect_per_fat_32 * 128;
|
fat->clust_cnt = bpb->sect_per_fat_32 * 128;
|
||||||
fat->info_sect = part.lba + bpb->info_sect;
|
fat->info_sect = part.lba + bpb->info_sect;
|
||||||
fat->fat_sect = part.lba + bpb->res_sect_cnt;
|
fat->fat_sect[0] = part.lba + bpb->res_sect_cnt;
|
||||||
fat->data_sect = fat->fat_sect + bpb->fat_cnt * bpb->sect_per_fat_32;
|
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);
|
fat->root_sect = clust_to_sect(fat, bpb->root_cluster);
|
||||||
|
|
||||||
err = move_win(fat, fat->info_sect);
|
err = move_win(fat, fat->info_sect);
|
||||||
@@ -1345,7 +1366,7 @@ int fat_fopen(file_t* file, const char* path, const char* mode)
|
|||||||
if (len == 0 || path[len])
|
if (len == 0 || path[len])
|
||||||
return FAT_ERR_PATH;
|
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 (err == FAT_ERR_EOF)
|
||||||
{
|
{
|
||||||
@@ -1640,8 +1661,9 @@ int fat_unlink(const char* path)
|
|||||||
return FAT_ERR_PATH;
|
return FAT_ERR_PATH;
|
||||||
|
|
||||||
fat_t* fat = dir.fat;
|
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)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
@@ -1651,9 +1673,24 @@ int fat_unlink(const char* path)
|
|||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
|
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;
|
ent->name[0] = SFN_FREE;
|
||||||
fat->win_dirty = true;
|
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);
|
return sync_fat(fat);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1671,6 +1708,10 @@ int fat_mkdir(const char* path)
|
|||||||
if (len == 0 || path[len])
|
if (len == 0 || path[len])
|
||||||
return FAT_ERR_PATH;
|
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
|
// Create a new directory
|
||||||
uint32_t new;
|
uint32_t new;
|
||||||
err = clust_chain_create(fat, &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));
|
memcpy(ent + 1, ent, sizeof(dir_ent_t));
|
||||||
ent[1].name[1] = '.';
|
ent[1].name[1] = '.';
|
||||||
ent[1].clust_hi = dir.first_clust >> 16;
|
ent[1].clust_hi = prev >> 16;
|
||||||
ent[1].clust_lo = dir.first_clust & 0xffff;
|
ent[1].clust_lo = prev & 0xffff;
|
||||||
|
|
||||||
err = dir_register(fat, &dir, path, len, FAT_ATTR_DIR, new);
|
err = dir_register(fat, &dir, path, len, FAT_ATTR_DIR, new);
|
||||||
if (err)
|
if (err)
|
||||||
|
|||||||
Reference in New Issue
Block a user