📄 fatfilt.c
字号:
(ffDisk[socNo][diskNo])->buf = NULL;
}
FL_FREE( ffDisk[socNo][diskNo] );
#endif
ffDisk[socNo][diskNo] = NULL;
}
return flOK;
}
/* --------------------------------------------------------------------------- *
* *
* n e w D i s k *
* *
* Discard existing disk record (if any), and create new one. *
* *
* Parameters: *
* handle : TFFS handle *
* *
* Returns: *
* flOK if success, otherwise respective error code *
* *
* --------------------------------------------------------------------------- */
static FLStatus newDisk ( int handle )
{
int socNo, diskNo;
int i;
FLffDisk * pd;
/* break TFFS handle into socket# and disk#, and do sanity check */
socNo = H2S(handle);
diskNo = H2D(handle);
if ((socNo >= FL_SOCKETS) || (diskNo >= FL_MAX_TL_PARTITIONS))
return flBadDriveHandle;
/* discard current disk and associated partition info (if any) */
checkStatus( discardDisk(handle) );
#ifdef FL_MALLOC
pd = (FLffDisk *) FL_MALLOC( sizeof(FLffDisk) );
if (pd == NULL)
return flNotEnoughMemory;
/* allocate and attach disk's scratch buffer */
pd->buf = (FLSByte *)FL_MALLOC( FL_SECTOR_SIZE );
if (pd->buf == NULL) {
FL_FREE (pd);
pd = NULL;
return flNotEnoughMemory;
}
#else /* !FL_MALLOC */
pd = &ffAllDisks[socNo][diskNo];
#endif /* FL_MALLOC */
pd->handle = handle;
pd->ffstate = flStateNotInitialized;
/* don't know partition layout yet */
pd->parts = 0;
for (i = 0; i < FL_MAX_PARTS_PER_DISK; i++)
pd->part[i] = NULL;
/* watch Master Boot Record for update */
pd->secToWatch = (SectorNo) 0;
ffDisk[socNo][diskNo] = pd;
return flOK;
}
/* --------------------------------------------------------------------------- *
* *
* i s P a r t T a b l e W r i t e *
* *
* Check if any of the sectors specified by 'ioreq' points to Master Boot *
* Record or next extended partition in the extended partitions list. *
* *
* Parameters: *
* pd : pointer to disk structure *
* ioreq : standard I/O request *
* *
* Returns: *
* TRUE if write to MBR or extended partition list is detected, otherwise *
* FALSE *
* *
* --------------------------------------------------------------------------- */
static FLBoolean isPartTableWrite ( FLffDisk * pd,
IOreq FAR2 * ioreq )
{
register FLSDword i;
if (pd != NULL) {
for (i = (FLSDword)0; i < ioreq->irSectorCount; i++) {
if( (ioreq->irSectorNo + i) == (FLSDword)pd->secToWatch )
return TRUE;
}
}
return FALSE;
}
/* --------------------------------------------------------------------------- *
* *
* i s E x t P a r t P r e s e n t *
* *
* Check if extended partition persent in the partition table. If it is, *
* calculate the sector # where next partition table will be written to. *
* *
* Parameters: *
* buf : partition table *
* nextExtPartSec : sector where next partition table will be written to *
* *
* Returns: *
* flOK on success, otherwise error code *
* *
* --------------------------------------------------------------------------- */
static FLStatus isExtPartPresent ( FLSByte FAR1 * buf,
SectorNo * nextExtPartSec )
{
Partition FAR1 * p;
register int i;
/* does it look like partition table ? */
#ifndef FL_NO_PACKED_STRUCTS_SUPPORTED
if (LE2(((PartitionTable FAR1 *) buf)->signature) != PARTITION_SIGNATURE)
#else
if (FL_GET_LE2(buf, FL_PARTITION_TABLE_SIGNATURE_OFFSET) != PARTITION_SIGNATURE)
#endif
return flBadFormat;
/* if extended. part. present, get sector# that will contain next part. in list */
#ifndef FL_NO_PACKED_STRUCTS_SUPPORTED
p = &( ((PartitionTable FAR1 *) buf)->ptEntry[0] );
#else
p = (Partition *) &FL_REF_1(buf, FL_PARTITION_TABLE_PT_ENTRY_OFFSET );
#endif
for (i = 0; i < FL_PART_TBL_ENTRIES; i++) {
#ifndef FL_NO_PACKED_STRUCTS_SUPPORTED
if (p->type == EX_PARTIT) {
*nextExtPartSec = (SectorNo) UNAL4( p[i].startingSectorOfPartition );
#else
if (FL_REF_1(p, FL_PARTITION_TYPE_OFFSET) == EX_PARTIT) {
*nextExtPartSec = (SectorNo) FL_GET_UNAL4(p, i* FL_PARTITION_SIZE + FL_PARTITION_STARTING_SECTOR_OF_PARTITION_OFFSET );
#endif
return flOK;
}
}
/* no extended partition found */
return flFileNotFound;
}
/* --------------------------------------------------------------------------- *
* *
* i s B P B c h a n g e d *
* *
* Check if critical fields in partition's boot sector have been changed. *
* *
* Parameters: *
* pv : disk partition (filesystem volume) *
* buf : new contents of partition's boot sector *
* *
* Returns: *
* TRUE if critical fields in BPB have been changed, otherwise FALSE *
* *
* --------------------------------------------------------------------------- */
static FLBoolean isBPBchanged ( FLffVol * pv, FLSByte FAR1 * buf )
{
BPB FAR1 * bpb;
SectorNo sectors;
SectorNo firstFATsecNo;
SectorNo lastFATsecNo;
SectorNo rootDirSecNo;
SectorNo rootDirSectors;
SectorNo sectorsPerFAT;
SectorNo firstDataSecNo;
/* if FAT monitor already inactive on this partition, do nothing and return */
if (pv->ffEnabled == FALSE)
return FALSE;
/* we only handle 512-byte sectors */
#ifndef FL_NO_PACKED_STRUCTS_SUPPORTED
bpb = &( ((DOSBootSector FAR1 *) buf)->bpb );
if( UNAL2(bpb->bytesPerSector) != FL_SECTOR_SIZE )
return TRUE;
/* check if 'number of sectors in partition' has been changed */
sectors = UNAL2( bpb->totalSectorsInVolumeDOS3 );
if (sectors == (SectorNo)0)
sectors = (SectorNo) LE4( bpb->totalSectorsInVolume );
#else
bpb = (BPB FAR1 *) buf;
if( FL_GET_UNAL2(bpb, FL_BPB_BYTES_PER_SECTOR_OFFSET) != FL_SECTOR_SIZE )
return TRUE;
/* check if 'number of sectors in partition' has been changed */
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 (sectors != pv->sectors)
return TRUE;
/* check if 'FAT's starting sector #' has been changed */
#ifndef FL_NO_PACKED_STRUCTS_SUPPORTED
firstFATsecNo = pv->startSecNo + (SectorNo)( LE2(bpb->reservedSectors) );
#else
firstFATsecNo = pv->startSecNo + (SectorNo)( FL_GET_LE2(bpb, FL_BPB_RESERVED_SECTORS_OFFSET) );
#endif
if (firstFATsecNo != pv->firstFATsecNo)
return TRUE;
/* check if 'FAT's ending sector #' has been changed */
#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
lastFATsecNo = firstFATsecNo + sectorsPerFAT - (SectorNo)1;
if (lastFATsecNo != pv->lastFATsecNo)
return TRUE;
/* check if 'first data sector #' has been changed */
#ifndef FL_NO_PACKED_STRUCTS_SUPPORTED
rootDirSecNo = firstFATsecNo + (sectorsPerFAT * bpb->noOfFATS);
rootDirSectors = (SectorNo)1 + (SectorNo)
(((UNAL2(bpb->rootDirectoryEntries) * DIRECTORY_ENTRY_SIZE) - 1) / FL_SECTOR_SIZE);
#else
rootDirSecNo = firstFATsecNo + (sectorsPerFAT * FL_REF_1(bpb, FL_BPB_NO_OF_FATS_OFFSET));
rootDirSectors = (SectorNo)1 + (SectorNo)
(((FL_GET_UNAL2(bpb, FL_BPB_ROOT_DIR_ENTRIES_OFFSET) * DIRECTORY_ENTRY_SIZE) - 1) / FL_SECTOR_SIZE);
#endif
firstDataSecNo = rootDirSecNo + rootDirSectors;
if (firstDataSecNo != pv->firstDataSecNo)
return TRUE;
/* check if cluster size has been changed */
#ifndef FL_NO_PACKED_STRUCTS_SUPPORTED
if (pv->clusterSize != bpb->sectorsPerCluster)
#else
if (pv->clusterSize != FL_REF_1(bpb, FL_BPB_SECTORS_PER_CLUSTER_OFFSET))
#endif
return TRUE;
return FALSE;
}
/* --------------------------------------------------------------------------- *
* *
* r e s e t *
* *
* Resets this software module to it's initial state upon boot. *
* *
* Parameters: *
* none *
* *
* Returns: *
* flOK in case of success, otherwise respective error code *
* *
* --------------------------------------------------------------------------- */
static FLStatus reset (void)
{
int iSoc, iDisk;
for (iSoc = 0; iSoc < FL_SOCKETS; iSoc++) {
/* discard existing disk structures for that socket */
for (iDisk = 0; iDisk < FL_MAX_TL_PARTITIONS; iDisk++)
(void) discardDisk( SD2H(iSoc, iDisk) );
/* pre-allocate disk structure for first disk of every socket */
checkStatus( newDisk(SD2H(iSoc, 0)) );
}
resetDone = TRUE;
return flOK;
}
/* --------------------------------------------------------------------------- *
* *
* p a r s e D i s k *
* *
* Read partition table(s), install and enable FAT filters on all FAT12/16 *
* partitions. *
* *
* Parameters: *
* handle : TFFS handle *
* *
* Returns: *
* flOK on success, otherwise error code *
* *
* NOTE: This routine uses disk's scratch buffer. *
* *
* --------------------------------------------------------------------------- */
static FLStatus parseDisk ( int handle )
{
int socNo, diskNo;
SectorNo extPartStartSec, sec;
int i, depth;
int type;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -