forked from len0rd/rockbox
Added longname handling to fat_remove().
Added proper 0xffff padding of last longname entry. add_dir_entry() now makes sure shortname is unique. Changed update_file_size() to use dir-as-file handling. Simplified create_dos_name() since we never use shortnames. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@2853 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
7aabb1ab66
commit
eee2c01697
2 changed files with 246 additions and 147 deletions
|
@ -100,7 +100,6 @@
|
|||
#define FATDIR_FILESIZE 28
|
||||
|
||||
#define FATLONG_ORDER 0
|
||||
#define FATLONG_ATTR 11
|
||||
#define FATLONG_TYPE 12
|
||||
#define FATLONG_CHKSUM 13
|
||||
|
||||
|
@ -648,9 +647,9 @@ static int write_long_name(struct fat_file* file,
|
|||
unsigned char* entry;
|
||||
unsigned int idx = firstentry % DIR_ENTRIES_PER_SECTOR;
|
||||
unsigned int sector = firstentry / DIR_ENTRIES_PER_SECTOR;
|
||||
unsigned int i, j=0, nameidx;
|
||||
unsigned int i, j=0;
|
||||
unsigned char chksum = 0;
|
||||
unsigned int namelen = strlen(name);
|
||||
int nameidx=0, namelen = strlen(name);
|
||||
int rc;
|
||||
|
||||
LDEBUGF("write_long_name(file:%x, first:%d, num:%d, name:%s)\n",
|
||||
|
@ -669,9 +668,10 @@ static int write_long_name(struct fat_file* file,
|
|||
chksum = ((chksum & 1) ? 0x80 : 0) + (chksum >> 1) + shortname[j++];
|
||||
|
||||
/* calc position of last name segment */
|
||||
for (nameidx=0;
|
||||
nameidx < (namelen - NAME_BYTES_PER_ENTRY);
|
||||
nameidx += NAME_BYTES_PER_ENTRY);
|
||||
if ( namelen > NAME_BYTES_PER_ENTRY )
|
||||
for (nameidx=0;
|
||||
nameidx < (namelen - NAME_BYTES_PER_ENTRY);
|
||||
nameidx += NAME_BYTES_PER_ENTRY);
|
||||
|
||||
for (i=0; i < numentries; i++) {
|
||||
/* new sector? */
|
||||
|
@ -685,10 +685,15 @@ static int write_long_name(struct fat_file* file,
|
|||
if (rc<1)
|
||||
return -4;
|
||||
|
||||
/* grab next sector */
|
||||
/* read next sector */
|
||||
rc = fat_readwrite(file, 1, buf, false);
|
||||
if (rc<1)
|
||||
if (rc<0) {
|
||||
LDEBUGF("Failed writing new sector: %d\n",rc);
|
||||
return -5;
|
||||
}
|
||||
if (rc==0)
|
||||
/* end of dir */
|
||||
memset(buf, 0, sizeof buf);
|
||||
|
||||
sector++;
|
||||
idx = 0;
|
||||
|
@ -707,13 +712,34 @@ static int write_long_name(struct fat_file* file,
|
|||
if ( i+1 < numentries ) {
|
||||
/* longname entry */
|
||||
int k, l = nameidx;
|
||||
|
||||
entry[FATLONG_ORDER] = numentries-i-1;
|
||||
if (i==0)
|
||||
if (i==0) {
|
||||
/* mark this as last long entry */
|
||||
entry[FATLONG_ORDER] |= 0x40;
|
||||
for (k=0; k<5 && name[l]; k++) entry[k*2 + 1] = name[l++];
|
||||
for (k=0; k<6 && name[l]; k++) entry[k*2 + 14] = name[l++];
|
||||
for (k=0; k<2 && name[l]; k++) entry[k*2 + 28] = name[l++];
|
||||
entry[FATLONG_ATTR] = FAT_ATTR_LONG_NAME;
|
||||
|
||||
/* pad name with 0xffff */
|
||||
for (k=1; k<12; k++) entry[k] = 0xff;
|
||||
for (k=14; k<26; k++) entry[k] = 0xff;
|
||||
for (k=28; k<32; k++) entry[k] = 0xff;
|
||||
};
|
||||
/* set name */
|
||||
for (k=0; k<5 && l <= namelen; k++) {
|
||||
entry[k*2 + 1] = name[l++];
|
||||
entry[k*2 + 2] = 0;
|
||||
}
|
||||
for (k=0; k<6 && l <= namelen; k++) {
|
||||
entry[k*2 + 14] = name[l++];
|
||||
entry[k*2 + 15] = 0;
|
||||
}
|
||||
for (k=0; k<2 && l <= namelen; k++) {
|
||||
entry[k*2 + 28] = name[l++];
|
||||
entry[k*2 + 29] = 0;
|
||||
}
|
||||
|
||||
entry[FATDIR_ATTR] = FAT_ATTR_LONG_NAME;
|
||||
entry[FATDIR_FSTCLUSLO] = 0;
|
||||
entry[FATLONG_TYPE] = 0;
|
||||
entry[FATLONG_CHKSUM] = chksum;
|
||||
LDEBUGF("Longname entry %d: %.13s\n", idx, name+nameidx);
|
||||
}
|
||||
|
@ -726,14 +752,13 @@ static int write_long_name(struct fat_file* file,
|
|||
}
|
||||
idx++;
|
||||
nameidx -= NAME_BYTES_PER_ENTRY;
|
||||
//dbg_dump_buffer(buf, SECTOR_SIZE, 0);
|
||||
}
|
||||
|
||||
/* update last sector */
|
||||
rc = fat_seek(file, sector);
|
||||
if (rc<0)
|
||||
return -5;
|
||||
|
||||
|
||||
rc = fat_readwrite(file, 1, buf, true);
|
||||
if (rc<1)
|
||||
return -6;
|
||||
|
@ -751,8 +776,10 @@ static int add_dir_entry(struct fat_dir* dir,
|
|||
unsigned int sector;
|
||||
bool done = false;
|
||||
bool eof = false;
|
||||
bool last = false;
|
||||
int entries_needed, entries_found = 0;
|
||||
int namelen = strlen(name);
|
||||
int firstentry;
|
||||
|
||||
LDEBUGF( "add_dir_entry(%s,%x)\n",
|
||||
name, file->firstcluster);
|
||||
|
@ -767,6 +794,9 @@ static int add_dir_entry(struct fat_dir* dir,
|
|||
if (namelen % NAME_BYTES_PER_ENTRY)
|
||||
entries_needed++;
|
||||
|
||||
restart:
|
||||
firstentry = 0;
|
||||
|
||||
err=fat_seek(&dir->file, 0);
|
||||
if (err<0)
|
||||
return -1;
|
||||
|
@ -803,7 +833,7 @@ static int add_dir_entry(struct fat_dir* dir,
|
|||
}
|
||||
|
||||
/* look for free slots */
|
||||
for (i=0; i < DIR_ENTRIES_PER_SECTOR; i++)
|
||||
for (i=0; i < DIR_ENTRIES_PER_SECTOR && !done; i++)
|
||||
{
|
||||
unsigned char firstbyte = buf[i * DIR_ENTRY_SIZE];
|
||||
switch (firstbyte) {
|
||||
|
@ -811,6 +841,8 @@ static int add_dir_entry(struct fat_dir* dir,
|
|||
entries_found = entries_needed;
|
||||
LDEBUGF("Found last entry %d\n",
|
||||
sector * DIR_ENTRIES_PER_SECTOR + i);
|
||||
last = true;
|
||||
done = true;
|
||||
break;
|
||||
|
||||
case 0xe5: /* free entry */
|
||||
|
@ -822,55 +854,90 @@ static int add_dir_entry(struct fat_dir* dir,
|
|||
|
||||
default:
|
||||
entries_found = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
if (entries_found == entries_needed)
|
||||
{
|
||||
int firstentry = sector * DIR_ENTRIES_PER_SECTOR + i;
|
||||
/* check that our intended shortname doesn't already exist */
|
||||
if (!strncmp(shortname, buf + i * DIR_ENTRY_SIZE, 12)) {
|
||||
/* filename exists already. make a new one */
|
||||
snprintf(shortname+8, 4, "%03X", (unsigned)rand() & 0xfff);
|
||||
LDEBUGF("Duplicate shortname, changing to %s\n",
|
||||
shortname);
|
||||
|
||||
/* if we're not extending the dir, we must go back to first
|
||||
free entry */
|
||||
if (firstbyte)
|
||||
firstentry -= (entries_needed - 1);
|
||||
|
||||
LDEBUGF("Adding longname to entry %d in sector %d\n",
|
||||
i, sector);
|
||||
|
||||
err = write_long_name(&dir->file, firstentry,
|
||||
entries_needed, name, shortname);
|
||||
if (err < 0)
|
||||
return -5;
|
||||
|
||||
/* remember where the shortname dir entry is located */
|
||||
file->dirsector = dir->file.lastsector;
|
||||
file->direntry =
|
||||
(i + entries_needed - 1) % DIR_ENTRIES_PER_SECTOR;
|
||||
|
||||
/* advance the last_empty_entry marker? */
|
||||
if (firstbyte == 0)
|
||||
{
|
||||
i++;
|
||||
if (i < DIR_ENTRIES_PER_SECTOR)
|
||||
{
|
||||
/* next entry is now last */
|
||||
buf[i*DIR_ENTRY_SIZE] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* add a new sector/cluster for last entry */
|
||||
memset(buf, 0, sizeof buf);
|
||||
do {
|
||||
err = fat_readwrite(&dir->file, 1, buf, true);
|
||||
if (err<1)
|
||||
return -6;
|
||||
} while (dir->file.sectornum <
|
||||
(int)fat_bpb.bpb_secperclus);
|
||||
}
|
||||
/* name has changed, we need to restart search */
|
||||
goto restart;
|
||||
}
|
||||
done = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!firstentry && (entries_found == entries_needed)) {
|
||||
firstentry = sector * DIR_ENTRIES_PER_SECTOR + i;
|
||||
|
||||
/* if we're not extending the dir,
|
||||
we must go back to first free entry */
|
||||
if (!last)
|
||||
firstentry -= (entries_needed - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sector = firstentry / DIR_ENTRIES_PER_SECTOR;
|
||||
LDEBUGF("Adding longname to entry %d in sector %d\n",
|
||||
firstentry, sector);
|
||||
|
||||
err = write_long_name(&dir->file, firstentry,
|
||||
entries_needed, name, shortname);
|
||||
if (err < 0)
|
||||
return -5;
|
||||
|
||||
/* remember where the shortname dir entry is located */
|
||||
file->direntry = firstentry + entries_needed - 1;
|
||||
file->direntries = entries_needed;
|
||||
file->dircluster = dir->file.firstcluster;
|
||||
LDEBUGF("Added new dir entry %d, using %d slots.\n",
|
||||
file->direntry, file->direntries);
|
||||
|
||||
/* advance the end-of-dir marker? */
|
||||
if (last)
|
||||
{
|
||||
unsigned int lastentry = firstentry + entries_needed;
|
||||
|
||||
LDEBUGF("Updating end-of-dir entry %d\n",lastentry);
|
||||
|
||||
if (lastentry % DIR_ENTRIES_PER_SECTOR)
|
||||
{
|
||||
int idx = (lastentry % DIR_ENTRIES_PER_SECTOR) * DIR_ENTRY_SIZE;
|
||||
|
||||
err=fat_seek(&dir->file, lastentry / DIR_ENTRIES_PER_SECTOR);
|
||||
if (err<0)
|
||||
return -6;
|
||||
|
||||
err = fat_readwrite(&dir->file, 1, buf, false);
|
||||
if (err<1)
|
||||
return -7;
|
||||
|
||||
/* clear last entry */
|
||||
buf[idx] = 0;
|
||||
|
||||
err=fat_seek(&dir->file, lastentry / DIR_ENTRIES_PER_SECTOR);
|
||||
if (err<0)
|
||||
return -8;
|
||||
|
||||
/* we must clear entire last cluster */
|
||||
do {
|
||||
err = fat_readwrite(&dir->file, 1, buf, true);
|
||||
if (err<1)
|
||||
return -9;
|
||||
memset(buf, 0, sizeof buf);
|
||||
} while (dir->file.sectornum < (int)fat_bpb.bpb_secperclus);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* add a new sector/cluster for last entry */
|
||||
memset(buf, 0, sizeof buf);
|
||||
do {
|
||||
err = fat_readwrite(&dir->file, 1, buf, true);
|
||||
if (err<1)
|
||||
return -10;
|
||||
} while (dir->file.sectornum < (int)fat_bpb.bpb_secperclus);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -916,106 +983,70 @@ unsigned char char2dos(unsigned char c)
|
|||
|
||||
static int create_dos_name(unsigned char *name, unsigned char *newname)
|
||||
{
|
||||
unsigned char n[12];
|
||||
unsigned char c;
|
||||
int i;
|
||||
char *ext;
|
||||
int i,j;
|
||||
|
||||
strncpy(n, name, sizeof n);
|
||||
|
||||
ext = strchr(n, '.');
|
||||
if(ext)
|
||||
{
|
||||
*ext++ = 0;
|
||||
}
|
||||
|
||||
/* The file name is either empty, or there was only an extension.
|
||||
In either case it is illegal. */
|
||||
if(n[0] == 0)
|
||||
{
|
||||
return -2;
|
||||
}
|
||||
|
||||
/* Name part */
|
||||
for(i = 0;n[i] && (i < 8);i++)
|
||||
for (i=0, j=0; name[i] && (j < 8); i++)
|
||||
{
|
||||
c = char2dos(n[i]);
|
||||
if(c)
|
||||
{
|
||||
newname[i] = toupper(c);
|
||||
}
|
||||
}
|
||||
while(i < 8)
|
||||
{
|
||||
newname[i++] = ' ';
|
||||
unsigned char c = char2dos(name[i]);
|
||||
if (c)
|
||||
newname[j++] = toupper(c);
|
||||
}
|
||||
while (j < 8)
|
||||
newname[j++] = ' ';
|
||||
|
||||
/* Extension part */
|
||||
for (i = 0;ext && ext[i] && (i < 3);i++)
|
||||
{
|
||||
c = char2dos(ext[i]);
|
||||
if (c)
|
||||
{
|
||||
newname[8+i] = toupper(c);
|
||||
}
|
||||
}
|
||||
while(i < 3)
|
||||
{
|
||||
newname[8+i++] = ' ';
|
||||
}
|
||||
snprintf(newname+8, 4, "%03X", (unsigned)rand() & 0xfff);
|
||||
|
||||
newname[11] = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int update_file_size( struct fat_file* file, int size )
|
||||
{
|
||||
unsigned char buf[SECTOR_SIZE];
|
||||
int sector = file->dirsector + fat_bpb.startsector;
|
||||
unsigned char* entry = buf + file->direntry * DIR_ENTRY_SIZE;
|
||||
int sector = file->direntry / DIR_ENTRIES_PER_SECTOR;
|
||||
unsigned char* entry =
|
||||
buf + DIR_ENTRY_SIZE * (file->direntry % DIR_ENTRIES_PER_SECTOR);
|
||||
unsigned int* sizeptr;
|
||||
unsigned short* clusptr;
|
||||
struct fat_file dir;
|
||||
int err;
|
||||
|
||||
LDEBUGF("update_file_size(cluster:%x entry:%d sector:%x size:%d)\n",
|
||||
file->firstcluster, file->direntry, file->dirsector, size);
|
||||
LDEBUGF("update_file_size(cluster:%x entry:%d size:%d)\n",
|
||||
file->firstcluster, file->direntry, size);
|
||||
|
||||
if ( file->direntry >= DIR_ENTRIES_PER_SECTOR )
|
||||
panicf("update_file_size(): Illegal entry %d!\n",file->direntry);
|
||||
|
||||
if ( file->direntry < 0 )
|
||||
panicf("update_file_size(): Illegal entry %d!\n",file->direntry);
|
||||
|
||||
err = ata_read_sectors(sector, 1, buf);
|
||||
if (err)
|
||||
{
|
||||
DEBUGF( "update_file_size() - Couldn't read dir sector %d"
|
||||
" (error code %d)\n", sector, err);
|
||||
/* create a temporary file handle for the dir holding this file */
|
||||
err = fat_open(file->dircluster, &dir, NULL);
|
||||
if (err<0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ( size == -1 ) {
|
||||
/* mark entry deleted */
|
||||
entry[0] = 0xe5;
|
||||
}
|
||||
else {
|
||||
clusptr = (short*)(entry + FATDIR_FSTCLUSHI);
|
||||
*clusptr = SWAB16(file->firstcluster >> 16);
|
||||
|
||||
clusptr = (short*)(entry + FATDIR_FSTCLUSLO);
|
||||
*clusptr = SWAB16(file->firstcluster & 0xffff);
|
||||
|
||||
sizeptr = (int*)(entry + FATDIR_FILESIZE);
|
||||
*sizeptr = SWAB32(size);
|
||||
}
|
||||
|
||||
err = ata_write_sectors(sector, 1, buf);
|
||||
if (err)
|
||||
{
|
||||
DEBUGF( "update_file_size() - Couldn't write dir sector %d"
|
||||
" (error code %d)\n", sector, err);
|
||||
err = fat_seek( &dir, sector );
|
||||
if (err<0)
|
||||
return -2;
|
||||
}
|
||||
|
||||
err = fat_readwrite(&dir, 1, buf, false);
|
||||
if (err<1)
|
||||
return -3;
|
||||
|
||||
if (!entry[0] || entry[0] == 0xe5)
|
||||
panicf("Updating size on empty dir entry %d\n", file->direntry);
|
||||
|
||||
clusptr = (short*)(entry + FATDIR_FSTCLUSHI);
|
||||
*clusptr = SWAB16(file->firstcluster >> 16);
|
||||
|
||||
clusptr = (short*)(entry + FATDIR_FSTCLUSLO);
|
||||
*clusptr = SWAB16(file->firstcluster & 0xffff);
|
||||
|
||||
sizeptr = (int*)(entry + FATDIR_FILESIZE);
|
||||
*sizeptr = SWAB32(size);
|
||||
|
||||
err = fat_seek( &dir, sector );
|
||||
if (err<0)
|
||||
return -4;
|
||||
|
||||
err = fat_readwrite(&dir, 1, buf, true);
|
||||
if (err<1)
|
||||
return -5;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1057,8 +1088,9 @@ int fat_open(unsigned int startcluster,
|
|||
|
||||
/* remember where the file's dir entry is located */
|
||||
if ( dir ) {
|
||||
file->dirsector = dir->sector;
|
||||
file->direntry = dir->entry - 1;
|
||||
file->direntries = dir->entrycount;
|
||||
file->dircluster = dir->file.firstcluster;
|
||||
}
|
||||
LDEBUGF("fat_open(%x), entry %d\n",startcluster,file->direntry);
|
||||
return 0;
|
||||
|
@ -1113,7 +1145,7 @@ int fat_closewrite(struct fat_file *file, int size)
|
|||
}
|
||||
}
|
||||
|
||||
if (file->dirsector)
|
||||
if (file->dircluster)
|
||||
if (update_file_size(file, size) < 0)
|
||||
return -1;
|
||||
|
||||
|
@ -1152,9 +1184,69 @@ int fat_remove(struct fat_file* file)
|
|||
update_fat_entry(last,0);
|
||||
last = next;
|
||||
}
|
||||
update_file_size(file, -1);
|
||||
file->dirsector = 0;
|
||||
|
||||
/* free all dir entries */
|
||||
if ( file->dircluster ) {
|
||||
unsigned char buf[SECTOR_SIZE];
|
||||
struct fat_file dir;
|
||||
unsigned int entry = file->direntry - file->direntries + 1;
|
||||
unsigned int sector = entry / DIR_ENTRIES_PER_SECTOR;
|
||||
unsigned int i;
|
||||
int err;
|
||||
|
||||
/* create a temporary file handle for the dir holding this file */
|
||||
err = fat_open(file->dircluster, &dir, NULL);
|
||||
if (err<0)
|
||||
return -1;
|
||||
|
||||
err = fat_seek( &dir, sector );
|
||||
if (err<0)
|
||||
return -2;
|
||||
|
||||
err = fat_readwrite(&dir, 1, buf, false);
|
||||
if (err<1)
|
||||
return -3;
|
||||
|
||||
for (i=0; i < file->direntries; i++) {
|
||||
LDEBUGF("Clearing dir entry %d (%d/%d)\n",
|
||||
entry, i+1, file->direntries);
|
||||
buf[(entry % DIR_ENTRIES_PER_SECTOR) * DIR_ENTRY_SIZE] = 0xe5;
|
||||
entry++;
|
||||
|
||||
if ( (entry % DIR_ENTRIES_PER_SECTOR) == 0 ) {
|
||||
/* flush this sector */
|
||||
err = fat_seek(&dir, sector);
|
||||
if (err<0)
|
||||
return -4;
|
||||
|
||||
err = fat_readwrite(&dir, 1, buf, true);
|
||||
if (err<1)
|
||||
return -5;
|
||||
|
||||
if ( i+1 < file->direntries ) {
|
||||
/* read next sector */
|
||||
err = fat_readwrite(&dir, 1, buf, false);
|
||||
if (err<1)
|
||||
return -6;
|
||||
}
|
||||
sector++;
|
||||
}
|
||||
}
|
||||
|
||||
if ( entry % DIR_ENTRIES_PER_SECTOR ) {
|
||||
/* flush this sector */
|
||||
err = fat_seek(&dir, sector);
|
||||
if (err<0)
|
||||
return -7;
|
||||
|
||||
err = fat_readwrite(&dir, 1, buf, true);
|
||||
if (err<1)
|
||||
return -8;
|
||||
}
|
||||
}
|
||||
|
||||
file->firstcluster = 0;
|
||||
file->dircluster = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1384,9 +1476,11 @@ int fat_getnext(struct fat_dir *dir, struct fat_direntry *entry)
|
|||
int sectoridx=0;
|
||||
static unsigned char cached_buf[SECTOR_SIZE];
|
||||
|
||||
dir->entrycount = 0;
|
||||
|
||||
while(!done)
|
||||
{
|
||||
if ( dir->entry >= DIR_ENTRIES_PER_SECTOR || !dir->sector )
|
||||
if ( !(dir->entry % DIR_ENTRIES_PER_SECTOR) || !dir->sector )
|
||||
{
|
||||
err = fat_readwrite(&dir->file, 1, cached_buf, false);
|
||||
if (err==0) {
|
||||
|
@ -1400,7 +1494,6 @@ int fat_getnext(struct fat_dir *dir, struct fat_direntry *entry)
|
|||
return -1;
|
||||
}
|
||||
dir->sector = dir->file.lastsector;
|
||||
dir->entry = 0;
|
||||
}
|
||||
|
||||
for (i = dir->entry % DIR_ENTRIES_PER_SECTOR;
|
||||
|
@ -1414,15 +1507,19 @@ int fat_getnext(struct fat_dir *dir, struct fat_direntry *entry)
|
|||
if (firstbyte == 0xe5) {
|
||||
/* free entry */
|
||||
sectoridx = 0;
|
||||
dir->entrycount = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (firstbyte == 0) {
|
||||
/* last entry */
|
||||
entry->name[0] = 0;
|
||||
dir->entrycount = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
dir->entrycount++;
|
||||
|
||||
/* longname entry? */
|
||||
if ( ( cached_buf[entrypos + FATDIR_ATTR] &
|
||||
FAT_ATTR_LONG_NAME_MASK ) == FAT_ATTR_LONG_NAME ) {
|
||||
|
|
|
@ -52,14 +52,16 @@ struct fat_file
|
|||
int lastcluster; /* cluster of last access */
|
||||
int lastsector; /* sector of last access */
|
||||
int sectornum; /* sector number in this cluster */
|
||||
int dirsector; /* sector where the dir entry is located */
|
||||
int direntry; /* dir entry index in sector */
|
||||
unsigned int direntry; /* short dir entry index from start of dir */
|
||||
unsigned int direntries; /* number of dir entries used by this file */
|
||||
unsigned int dircluster; /* first cluster of dir */
|
||||
bool eof;
|
||||
};
|
||||
|
||||
struct fat_dir
|
||||
{
|
||||
unsigned int entry;
|
||||
unsigned int entrycount;
|
||||
int sector;
|
||||
struct fat_file file;
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue