📄 fat_misc.c
字号:
clstcount = 0;
while (clstcount < maxclst) {
eofclst = curclst;
clstcount++;
if (fattype == 1) {
fatindex = curclst + (curclst / 2); /* FAT12 */
}
#if (FS_FAT_NOFAT32==0)
else if (fattype == 2) {
fatindex = curclst * 4; /* FAT32 */
}
#endif /* FS_FAT_NOFAT32==0 */
else {
fatindex = curclst * 2; /* FAT16 */
}
fatsec = FS__FAT_aBPBUnit[Idx][Unit].RsvdSecCnt + (fatindex / bytespersec);
fatoffs = fatindex % bytespersec;
if (fatsec != lastsec) {
err = FS__lb_read(FS__pDevInfo[Idx].devdriver, Unit, fatsec, (void*)buffer);
if (err < 0) {
err = FS__lb_read(FS__pDevInfo[Idx].devdriver, Unit, fatsize + fatsec, (void*)buffer);
if (err < 0) {
FS__fat_free(buffer);
return -1;
}
/* Try to repair original FAT sector with contents of copy */
FS__lb_write(FS__pDevInfo[Idx].devdriver, Unit, fatsec, (void*)buffer);
}
lastsec = fatsec;
}
if (fattype == 1) {
if (fatoffs == (bytespersec - 1)) {
a = buffer[fatoffs];
err = FS__lb_read(FS__pDevInfo[Idx].devdriver, Unit, fatsec + 1, (void*)buffer);
if (err < 0) {
err = FS__lb_read(FS__pDevInfo[Idx].devdriver, Unit, fatsize + fatsec + 1, (void*)buffer);
if (err < 0) {
FS__fat_free(buffer);
return -1;
}
/* Try to repair original FAT sector with contents of copy */
FS__lb_write(FS__pDevInfo[Idx].devdriver, Unit, fatsec + 1, (void*)buffer);
}
lastsec = fatsec + 1;
b = buffer[0];
}
else {
a = buffer[fatoffs];
b = buffer[fatoffs + 1];
}
if (curclst & 1) {
curclst = ((a & 0xf0) >> 4 ) + 16 * b;
}
else {
curclst = a + 256 * (b & 0x0f);
}
curclst &= 0x0fffL;
if (curclst >= 0x0ff8L) {
/* EOF found */
FS__fat_free(buffer);
if (pClstCnt) {
*pClstCnt = clstcount;
}
return eofclst;
}
}
#if (FS_FAT_NOFAT32==0)
else if (fattype == 2) {
a = buffer[fatoffs];
b = buffer[fatoffs + 1];
c = buffer[fatoffs + 2];
d = buffer[fatoffs + 3];
curclst = a + 0x100L * b + 0x10000L * c + 0x1000000L * d;
curclst &= 0x0fffffffL;
if (curclst >= (FS_i32)0x0ffffff8L) {
/* EOF found */
FS__fat_free(buffer);
if (pClstCnt) {
*pClstCnt = clstcount;
}
return eofclst;
}
}
#endif /* FS_FAT_NOFAT32==0 */
else {
a = buffer[fatoffs];
b = buffer[fatoffs + 1];
curclst = a + 256 * b;
curclst &= 0xffffL;
if (curclst >= (FS_i32)0xfff8L) {
/* EOF found */
FS__fat_free(buffer);
if (pClstCnt) {
*pClstCnt = clstcount;
}
return eofclst;
}
}
} /* while (clstcount<maxclst) */
FS__fat_free(buffer);
return -1;
}
/*********************************************************************
*
* FS__fat_FAT_alloc
*
Description:
FS internal function. Allocate a new cluster in the FAT and link it
to LastClust. Assign an EOF mark to the new allocated cluster.
The function has grown a lot, since it supports all FAT types (FAT12,
FAT16 & FAT32). There is also room for performance improvement, when
makeing the new FAT entry and the old entry is within the same FAT
sector.
Parameters:
Idx - Index of device in the device information table
referred by FS__pDevInfo.
Unit - Unit number.
LastClust - Number of cluster, to which the new allocated cluster
is linked to. If this is negative, the new cluster is
not linked to anything and only the EOF mark is set.
Return value:
>=0 - Number of new allocated cluster, which contains the
EOF mark.
<0 - An error has occured.
*/
FS_i32 FS__fat_FAT_alloc(int Idx, FS_u32 Unit, FS_i32 LastClust) {
FS_u32 fatsize;
FS_i32 fatoffs;
FS_i32 bytespersec;
FS_i32 curclst;
FS_i32 fatsec;
FS_i32 lastsec;
unsigned char *buffer;
int fattype;
int err;
int err2;
int lexp;
buffer = (unsigned char*)FS__fat_malloc(FS_FAT_SEC_SIZE);
if (!buffer) {
return -1;
}
fattype = FS__fat_which_type(Idx, Unit);
#if (FS_FAT_NOFAT32!=0)
if (fattype == 2) {
FS__fat_free(buffer);
return -1;
}
#endif /* FS_FAT_NOFAT32!=0 */
fatsize = FS__FAT_aBPBUnit[Idx][Unit].FATSz16;
if (fatsize == 0) {
fatsize = FS__FAT_aBPBUnit[Idx][Unit].FATSz32;
}
bytespersec = (FS_i32)FS__FAT_aBPBUnit[Idx][Unit].BytesPerSec;
/* Find a free cluster in the FAT */
curclst = _FS__fat_FindFreeCluster(Idx, Unit, &fatsec, &lastsec, &fatoffs, LastClust, buffer, fattype, fatsize, bytespersec);
if (curclst < 0) {
FS__fat_free(buffer); /* No free cluster found. */
return -1;
}
/* Make an EOF entry for the new cluster */
err = _FS__fat_SetEOFMark(Idx, Unit, fatsec, &lastsec, fatoffs, curclst, buffer, fattype, fatsize, bytespersec);
if (err < 0) {
FS__fat_free(buffer);
return -1;
}
/* Link the new cluster to the cluster list */
if (LastClust < 0) {
err = FS__lb_write(FS__pDevInfo[Idx].devdriver, Unit, lastsec, (void*)buffer);
err2 = FS__lb_write(FS__pDevInfo[Idx].devdriver, Unit, fatsize + lastsec, (void*)buffer);
lexp = (err < 0);
lexp = lexp || (err2 < 0);
if (lexp) {
FS__fat_free(buffer);
return -1;
}
}
else {
err = _FS__fat_LinkCluster(Idx, Unit, &lastsec, curclst, LastClust, buffer, fattype, fatsize, bytespersec);
if (err < 0) {
FS__fat_free(buffer);
return -1;
}
}
#if (FS_FAT_NOFAT32==0)
/* Update the FSInfo structure */
if (fattype == 2) { /* FAT32 */
/* Modify FSInfo */
err = FS__lb_read(FS__pDevInfo[Idx].devdriver, Unit, FS__FAT_aBPBUnit[Idx][Unit].FSInfo, (void*)buffer);
if (err < 0) {
FS__fat_free(buffer);
return -1;
}
/* Check for FSInfo structure in buffer */
if (buffer[0] == (char)0x52) {
if (buffer[1] == (char)0x52) {
if (buffer[2] == (char)0x61) {
if (buffer[3] == (char)0x41) {
if (buffer[484] == (char)0x72) {
if (buffer[485] == (char)0x72) {
if (buffer[486] == (char)0x41) {
if (buffer[487] == (char)0x61) {
if (buffer[508] == (char)0x00) {
if (buffer[509] == (char)0x00) {
if (buffer[510] == (char)0x55) {
if (buffer[511] == (char)0xaa) {
/* Invalidate last known free cluster count */
buffer[488] = (char)0xff;
buffer[489] = (char)0xff;
buffer[490] = (char)0xff;
buffer[491] = (char)0xff;
/* Give hint for free cluster search */
buffer[492] = curclst & 0xff;
buffer[493] = (curclst / 0x100L) & 0xff;
buffer[494] = (curclst / 0x10000L) & 0xff;
buffer[495] = (curclst / 0x1000000L) & 0x0f;
err = FS__lb_write(FS__pDevInfo[Idx].devdriver, Unit, FS__FAT_aBPBUnit[Idx][Unit].FSInfo, (void*)buffer);
if (err < 0) {
FS__fat_free(buffer);
return -1;
}
}
}
}
}
}
}
}
}
}
}
}
} /* buffer contains FSInfo structure */
} /* FS_Info modification for fattype==2 */
#endif /* FS_FAT_NOFAT32==0 */
FS__fat_free(buffer);
return curclst;
}
/*********************************************************************
*
* FS__fat_diskclust
*
Description:
FS internal function. Walk through the FAT starting at StrtClst for
ClstNum times. Return the found cluster number of the media. This is
very similar to FS__fat_FAT_find_eof.
Parameters:
Idx - Index of device in the device information table
referred by FS__pDevInfo.
Unit - Unit number.
StrtClst - Starting point for FAT walk.
ClstNum - Number of steps.
Return value:
> 0 - Number of cluster found after ClstNum steps.
==0 - An error has occured.
*/
FS_i32 FS__fat_diskclust(int Idx, FS_u32 Unit, FS_i32 StrtClst, FS_i32 ClstNum) {
FS_u32 fatsize;
FS_i32 fatindex;
FS_i32 fatsec;
FS_i32 fatoffs;
FS_i32 lastsec;
FS_i32 curclst;
FS_i32 todo;
FS_i32 bytespersec;
int err;
int fattype;
char *buffer;
unsigned char a;
unsigned char b;
#if (FS_FAT_NOFAT32==0)
unsigned char c;
unsigned char d;
#endif /* FS_FAT_NOFAT32==0 */
fattype = FS__fat_which_type(Idx, Unit);
#if (FS_FAT_NOFAT32!=0)
if (fattype == 2) {
return 0;
}
#endif /* FS_FAT_NOFAT32!=0 */
buffer = FS__fat_malloc(FS_FAT_SEC_SIZE);
if (!buffer) {
return 0;
}
fatsize = FS__FAT_aBPBUnit[Idx][Unit].FATSz16;
if (fatsize == 0) {
fatsize = FS__FAT_aBPBUnit[Idx][Unit].FATSz32;
}
bytespersec = (FS_i32)FS__FAT_aBPBUnit[Idx][Unit].BytesPerSec;
todo = ClstNum;
curclst = StrtClst;
lastsec = -1;
while (todo) {
if (fattype == 1) {
fatindex = curclst + (curclst / 2); /* FAT12 */
}
#if (FS_FAT_NOFAT32==0)
else if (fattype == 2) {
fatindex = curclst * 4; /* FAT32 */
}
#endif /* FS_FAT_NOFAT32==0 */
else {
fatindex = curclst * 2; /* FAT16 */
}
fatsec = FS__FAT_aBPBUnit[Idx][Unit].RsvdSecCnt + (fatindex / bytespersec);
fatoffs = fatindex % bytespersec;
if (fatsec != lastsec) {
err = FS__lb_read(FS__pDevInfo[Idx].devdriver, Unit, fatsec, (void*)buffer);
if (err < 0) {
err = FS__lb_read(FS__pDevInfo[Idx].devdriver, Unit, fatsize + fatsec, (void*)buffer);
if (err < 0) {
FS__fat_free(buffer);
return 0;
}
/* Try to repair original FAT sector with contents of copy */
FS__lb_write(FS__pDevInfo[Idx].devdriver, Unit, fatsec, (void*)buffer);
}
lastsec = fatsec;
}
if (fattype == 1) {
if (fatoffs == (bytespersec - 1)) {
a = buffer[fatoffs];
err = FS__lb_read(FS__pDevInfo[Idx].devdriver, Unit, fatsec + 1, (void*)buffer);
if (err < 0) {
err = FS__lb_read(FS__pDevInfo[Idx].devdriver, Unit, fatsize + fatsec + 1, (void*)buffer);
if (err < 0) {
FS__fat_free(buffer);
return 0;
}
/* Try to repair original FAT sector with contents of copy */
FS__lb_write(FS__pDevInfo[Idx].devdriver, Unit, fatsec + 1, (void*)buffer);
}
lastsec = fatsec + 1;
b = buffer[0];
}
else {
a = buffer[fatoffs];
b = buffer[fatoffs + 1];
}
if (curclst & 1) {
curclst = ((a & 0xf0) >> 4) + 16 * b;
}
else {
curclst = a + 256 * (b & 0x0f);
}
curclst &= 0x0fffL;
if (curclst >= 0x0ff8L) {
FS__fat_free(buffer);
return 0;
}
}
#if (FS_FAT_NOFAT32==0)
else if (fattype == 2) {
a = buffer[fatoffs];
b = buffer[fatoffs + 1];
c = buffer[fatoffs + 2];
d = buffer[fatoffs + 3];
curclst = a + 0x100L * b + 0x10000L * c + 0x1000000L * d;
curclst &= 0x0fffffffL;
if (curclst >= (FS_i32)0x0ffffff8L) {
FS__fat_free(buffer);
return 0;
}
}
#endif /* FS_FAT_NOFAT32==0 */
else {
a = buffer[fatoffs];
b = buffer[fatoffs + 1];
curclst = a + 256 * b;
curclst &= 0xffffL;
if (curclst >= (FS_i32)0xfff8L) {
FS__fat_free(buffer);
return 0;
}
}
todo--;
}
FS__fat_free(buffer);
return curclst;
}
/*********************************************************************
*
* Global Variables
*
**********************************************************************
*/
const FS__fsl_type FS__fat_functable = {
#if (FS_FAT_NOFAT32==0)
"FAT12/FAT16/FAT32",
#else
"FAT12/FAT16",
#endif /* FS_FAT_NOFAT32==0 */
FS__fat_fopen, /* open */
FS__fat_fclose, /* close */
FS__fat_fread, /* read */
FS__fat_fwrite, /* write */
0, /* tell */
0, /* seek */
FS__fat_ioctl, /* ioctl */
#if FS_POSIX_DIR_SUPPORT
FS__fat_opendir, /* opendir */
FS__fat_closedir, /* closedir */
FS__fat_readdir, /* readdir */
0, /* rewinddir */
FS__fat_MkRmDir, /* mkdir */
FS__fat_MkRmDir, /* rmdir */
#endif /* FS_POSIX_DIR_SUPPORT */
};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -