📄 fatfilt.c
字号:
#endif
return flFormatNotSupported;
/*
* Is it a bogus BPB (leftover from previous disk partitioning) ?
* Check that there is no overlap with next partition (if one exists).
*/
#ifndef FL_NO_PACKED_STRUCTS_SUPPORTED
sectors = UNAL2(bpb->totalSectorsInVolumeDOS3);
if (sectors == (SectorNo)0)
sectors = (SectorNo) LE4(bpb->totalSectorsInVolume);
#else
sectors = FL_GET_UNAL2(bpb, FL_BPB_TOTAL_SECTORS_IN_VOL_DOS3_OFFSET);
if (sectors == (SectorNo)0)
sectors = (SectorNo) FL_GET_LE4(bpb, FL_BPB_TOTAL_SECTORS_IN_VOL_OFFSET);
#endif
if ((partNo+1 < pd->parts) && (pd->part[partNo+1] != NULL)) {
if( sectors > (pd->part[partNo+1])->startSecNo - pv->startSecNo )
return flNonFATformat;
}
/* number of sectors in partition as reported by BPB */
pv->sectors = sectors;
/* get number of reserved sectors from BPB, and check it's sanity */
#ifndef FL_NO_PACKED_STRUCTS_SUPPORTED
reservedSectors = (SectorNo) LE2(bpb->reservedSectors);
#else
reservedSectors = (SectorNo) FL_GET_LE2(bpb, FL_BPB_RESERVED_SECTORS_OFFSET);
#endif
switch( (int)reservedSectors ) {
case 32: /* always the case with FAT 32 */
#ifndef FL_INCLUDE_FAT32
DBG_PRINT_FLOW(FLZONE_FS,"Debug: (partEnableFF) FAT32 detected.\r\n");
return flFormatNotSupported;
#endif
case 1: /* must always be the case for FAT 12 and FAT16 */
default:
break;
}
/* get location and size of the first FAT copy */
pv->firstFATsecNo = pv->startSecNo + reservedSectors;
#ifndef FL_NO_PACKED_STRUCTS_SUPPORTED
sectorsPerFAT = (SectorNo) LE2(bpb->sectorsPerFAT);
#else
sectorsPerFAT = (SectorNo) FL_GET_LE2(bpb, FL_BPB_SECTORS_PER_FAT_OFFSET);
#endif
#ifndef FL_INCLUDE_FAT32
if (sectorsPerFAT == 0) { /* always the case with FAT32 */
DBG_PRINT_FLOW(FLZONE_FS,"Debug: (partEnableFF) FAT32 detected.\r\n");
return flFormatNotSupported;
}
#endif
pv->lastFATsecNo = pv->firstFATsecNo + sectorsPerFAT - (SectorNo)1;
/* get location and size of root directory */
#ifndef FL_NO_PACKED_STRUCTS_SUPPORTED
rootDirSecNo = pv->firstFATsecNo + (sectorsPerFAT * bpb->noOfFATS);
rootDirEntries = (SectorNo) UNAL2(bpb->rootDirectoryEntries);
#else
rootDirSecNo = pv->firstFATsecNo + (sectorsPerFAT * (FL_REF_1(bpb, FL_BPB_NO_OF_FATS_OFFSET)));
rootDirEntries = (SectorNo) FL_GET_UNAL2(bpb, FL_BPB_ROOT_DIR_ENTRIES_OFFSET);
#endif
switch (rootDirEntries) {
#ifndef FL_INCLUDE_FAT32
case 0: /* always the case with FAT32 */
DBG_PRINT_FLOW(FLZONE_FS,"Debug: (partEnableFF) FAT32 detected.\r\n");
return flFormatNotSupported;
#endif
default:
if( ((rootDirEntries * DIRECTORY_ENTRY_SIZE) % FL_SECTOR_SIZE) != 0 )
return flNonFATformat;
break;
}
rootDirSectors = (SectorNo)(((rootDirEntries * DIRECTORY_ENTRY_SIZE) - 1) / FL_SECTOR_SIZE) +
(SectorNo)1;
/* get location of data area */
pv->firstDataSecNo = rootDirSecNo + rootDirSectors;
/* get size of FAT cluster in sectors, and check it's sanity */
#ifndef FL_NO_PACKED_STRUCTS_SUPPORTED
pv->clusterSize = bpb->sectorsPerCluster;
#else
pv->clusterSize = FL_REF_1(bpb, FL_BPB_SECTORS_PER_CLUSTER_OFFSET);
#endif
switch( (int)pv->clusterSize ) {
case 1: case 2: case 4: case 8: case 16: case 32: case 64: case 128:
break;
default:
return flNonFATformat;
}
if ((pv->clusterSize << FL_SECTOR_SIZE_BITS) > (32768 /*(32 * 1024)*/))
return flFormatNotSupported;
/* sanity check */
if( (pv->lastFATsecNo < pv->firstFATsecNo) ||
(pv->firstDataSecNo <= pv->lastFATsecNo) ||
(pv->sectors < pv->firstDataSecNo) )
return flNonFATformat;
/* decide which type of FAT is it */
maxCluster = (unsigned)1 + (unsigned)
((pv->sectors - (pv->firstDataSecNo - pv->startSecNo)) / pv->clusterSize);
if (maxCluster < 4085) {
pv->flags |= VOLUME_12BIT_FAT; /* 12-bit FAT */
#ifndef FS_FAT_12BIT
DBG_PRINT_ERR(FLZONE_FS,"ERROR - FS_FAT_12BIT must be defined.\r\n");
return flFormatNotSupported;
#else
DBG_PRINT_FLOW(FLZONE_FS,"Debug: (partEnableFF) FAT12 detected.\r\n");
#endif /* FS_FAT_12BIT */
}
else {
DBG_PRINT_FLOW(FLZONE_FS,"Debug: (partEnableFF) FAT16 detected.\r\n");
}
/* turn on FAT filter on this partition */
pv->ffEnabled = TRUE;
return flOK;
}
/* --------------------------------------------------------------------------- *
* *
* p a r t F r e e D e l C l u s t e r s *
* *
* Compare the new contents of the specified FAT sector against the old *
* one on the disk. If any freed clusters are found, issue 'sector delete' *
* calls for all sectors that are occupied by these freed clusters. *
* *
* Parameters: *
* pv : disk partition (filesystem volume) *
* secNo : abs. sector # of the FAT sector *
* newFAT : new contents of this FAT sector *
* *
* Returns: *
* flOK on success, otherwise error code *
* *
* NOTE: This routine uses disk's scratch buffer. *
* *
* --------------------------------------------------------------------------- */
static FLStatus partFreeDelClusters ( FLffVol * pv,
SectorNo secNo,
FLSByte FAR1 * newFAT,
IOreq * ioreq_delete )
{
FLffDisk * pd;
int socNo, diskNo;
FLWord oldFATentry, newFATentry;
SectorNo iSec;
unsigned firstCluster;
IOreq ioreq;
int offset;
int iPart;
#ifdef FS_FAT_12BIT
int halfBytes;
#endif
#ifdef FL_MALLOC
FLSByte * oldFAT;
#else
FLSByte oldFAT[FL_SECTOR_SIZE];
#endif
/* arg. sanity check */
if (pv == NULL)
return flBadDriveHandle;
/* break TFFS handle into socket# and disk#, and do sanity check */
socNo = H2S(pv->handle);
diskNo = H2D(pv->handle);
if ((socNo >= ((int) noOfSockets)) || (diskNo >= FL_MAX_TL_PARTITIONS))
return flBadDriveHandle;
/* check if 'pv' belongs to this disk */
pd = ffDisk[socNo][diskNo];
if (pd == NULL)
return flBadDriveHandle;
for (iPart = 0; iPart < pd->parts; iPart++) {
if (pd->part[iPart] == pv)
break;
}
if (iPart >= pd->parts)
return flBadDriveHandle;
#ifdef FL_MALLOC
/* make sure scratch buffer is available */
if (pd->buf == NULL)
return flBufferingError;
oldFAT = pd->buf;
#endif /* FL_MALLOC */
/* read in the FAT sector from the disk */
ioreq.irHandle = pv->handle;
ioreq.irSectorNo = secNo;
ioreq.irSectorCount = 1;
ioreq.irData = (void FAR1 *) oldFAT;
checkStatus( flAbsRead(&ioreq) );
#ifdef FS_FAT_12BIT
/* size of FAT entry in half-bytes */
halfBytes = ((pv->flags & VOLUME_12BIT_FAT) ? 3 : 4);
/* starting cluster */
if (halfBytes == 3) {
firstCluster =
((((unsigned)(secNo - pv->firstFATsecNo)) * (2 * FL_SECTOR_SIZE)) + 2) / 3;
}
else {
firstCluster = ((unsigned)(secNo - pv->firstFATsecNo)) * (FL_SECTOR_SIZE / 2);
}
/* starting data sector */
iSec = (((SectorNo)firstCluster - 2) * pv->clusterSize) + pv->firstDataSecNo;
offset = (firstCluster * ((unsigned) halfBytes)) & ((2 * FL_SECTOR_SIZE) - 1);
/*
* Find if any clusters were logically deleted, and if so, delete them.
*
* NOTE: We are skipping over 12-bit FAT entries which span more than
* one sector.
*/
for (; offset < ((2 * FL_SECTOR_SIZE) - 2);
offset += halfBytes, iSec += pv->clusterSize) {
oldFATentry = UNAL2( *(Unaligned FAR0 *)(oldFAT + (offset / 2)) );
newFATentry = UNAL2( *(Unaligned FAR1 *)(newFAT + (offset / 2)) );
if (offset & 1) {
oldFATentry >>= 4;
newFATentry >>= 4;
}
else {
if (halfBytes == 3) {
oldFATentry &= 0xfff;
newFATentry &= 0xfff;
}
}
#else /* !FS_FAT_12BIT */
firstCluster = ((unsigned) (secNo - pv->firstFATsecNo) * (FL_SECTOR_SIZE / 2));
iSec = pv->firstDataSecNo +
(((SectorNo)(firstCluster - (unsigned)2)) * pv->clusterSize);
/* Find if any clusters were logically deleted, and if so, delete them */
for (offset = 0; offset < FL_SECTOR_SIZE; offset += 2, iSec += pv->clusterSize) {
oldFATentry = LE2( *(LEushort FAR0 *)(oldFAT + offset) );
newFATentry = LE2( *(LEushort FAR1 *)(newFAT + offset) );
#endif /* FS_FAT_12BIT */
if ((oldFATentry != FAT_FREE) && (newFATentry == FAT_FREE)) {
#ifdef FL_DEL_SECTOR_SETS
if (del_sect_sets == TRUE) {
/* Rather then deleting this cluster's sectors immediately, we try to
* accumulate as many consecutive clusters as only possible before
* calling flAbsDelete(). The hope here is that the underlaying
* TL will be able to handle deletion of larger sets of
* consecutive sectors more efficiently.
*/
if ((SectorNo)(ioreq_delete->irSectorNo + ioreq_delete->irSectorCount) == iSec) {
ioreq_delete->irSectorCount += pv->clusterSize;
}
else {
if (ioreq_delete->irSectorNo != (SectorNo)(-1)) {
#ifdef FL_DEL_SECTOR_STATS
{ register int x = -1, S = (int)(ioreq_delete->irSectorCount);
while (S != 0) { x++; S >>= 1; }
if ((x >= 0) && (x < (sizeof(del_sect_stats)/sizeof(del_sect_stats[0])))) { del_sect_stats[x]++; }
}
#endif
flAbsDelete (ioreq_delete);
}
ioreq_delete->irSectorNo = iSec;
ioreq_delete->irSectorCount = pv->clusterSize;
}
}
else
#endif /* FL_DEL_SECTOR_SETS */
{ /* delete one FAT cluster at a time */
ioreq_delete->irHandle = pv->handle;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -