📄 fatfilt.c
字号:
if (pd->buf == NULL) {
FL_FREE (pd);
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 long i;
if (pd != NULL) {
for (i = (long)0; i < ioreq->irSectorCount; i++) {
if( (ioreq->irSectorNo + i) == (long)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 ( char FAR1 * buf,
SectorNo * nextExtPartSec )
{
Partition FAR1 * p;
register int i;
/* does it look like partition table ? */
if (LE2(((PartitionTable FAR1 *) buf)->signature) != PARTITION_SIGNATURE)
return flBadFormat;
/* if extended. part. present, get sector# that will contain next part. in list */
p = &( ((PartitionTable FAR1 *) buf)->ptEntry[0] );
for (i = 0; i < FL_PART_TBL_ENTRIES; i++) {
if (p->type == EX_PARTIT) {
*nextExtPartSec = (SectorNo) UNAL4( (void *) p[i].startingSectorOfPartition );
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, char FAR1 * buf )
{
BPB * 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 */
bpb = &( ((DOSBootSector FAR1 *) buf)->bpb );
if( UNAL2(bpb->bytesPerSector) != 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 );
if (sectors != pv->sectors)
return TRUE;
/* check if 'FAT's starting sector #' has been changed */
firstFATsecNo = pv->startSecNo + (SectorNo)( LE2(bpb->reservedSectors) );
if (firstFATsecNo != pv->firstFATsecNo)
return TRUE;
/* check if 'FAT's ending sector #' has been changed */
sectorsPerFAT = (SectorNo) LE2( bpb->sectorsPerFAT );
lastFATsecNo = firstFATsecNo + sectorsPerFAT - (SectorNo)1;
if (lastFATsecNo != pv->lastFATsecNo)
return TRUE;
/* check if 'first data sector #' has been changed */
rootDirSecNo = firstFATsecNo + (sectorsPerFAT * bpb->noOfFATS);
rootDirSectors = (SectorNo)1 + (SectorNo)
(((UNAL2(bpb->rootDirectoryEntries) * DIRECTORY_ENTRY_SIZE) - 1) / SECTOR_SIZE);
firstDataSecNo = rootDirSecNo + rootDirSectors;
if (firstDataSecNo != pv->firstDataSecNo)
return TRUE;
/* check if cluster size has been changed */
if (pv->clusterSize != bpb->sectorsPerCluster)
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 < SOCKETS; iSoc++) {
/* discard existing disk structures for that socket */
for (iDisk = 0; iDisk < 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;
FLffDisk * pd;
FLffVol * pv;
Partition * pp;
IOreq ioreq;
#ifdef FL_MALLOC
char * buf;
#else
char buf[SECTOR_SIZE];
#endif
/* break TFFS handle into socket# and disk#, and do sanity check */
socNo = H2S(handle);
diskNo = H2D(handle);
if ((socNo >= ((int) noOfSockets)) || (diskNo >= MAX_TL_PARTITIONS))
return flBadDriveHandle;
/* if disk structure hasn't been allocated yet, do it now */
if (ffDisk[socNo][diskNo] == NULL)
checkStatus( newDisk(handle) );
pd = ffDisk[socNo][diskNo];
#ifdef FL_MALLOC
/* make sure scratch buffer is available */
if (pd->buf == NULL)
return flBufferingError;
buf = pd->buf;
#endif /* FL_MALLOC */
/* discard obsolete disk's partition info */
(void) discardDiskParts (pd);
/* read Master Boot Record */
ioreq.irHandle = handle;
ioreq.irSectorNo = (SectorNo) 0;
ioreq.irSectorCount = (SectorNo) 1;
ioreq.irData = (void FAR1 *) buf;
checkStatus( flAbsRead(&ioreq) );
/* is it MBR indeed ? */
if (LE2(((PartitionTable *) buf)->signature) != PARTITION_SIGNATURE)
return flPartitionNotFound;
/* do primary partitions only (we will do extended partitions later) */
pp = &( ((PartitionTable *) buf)->ptEntry[0] );
for (i = 0; i < FL_PART_TBL_ENTRIES; i++, pp++) {
if( pp->type == ((char)0) ) /* skip empty slot */
continue;
if( pp->type == ((char)EX_PARTIT) ) /* skip extended partition */
continue;
/* primary partition found (not necessarily FAT12/16) */
if( addNewDiskPart(pd) != flOK )
break;
pv = pd->part[pd->parts - 1];
/* remember partition's type, and where it starts */
pv->type = (int) pp->type;
pv->startSecNo = (SectorNo) UNAL4( (void *) pp->startingSectorOfPartition );
}
/* do extended partitions in depth */
for (i = 0; i < FL_PART_TBL_ENTRIES; i++) {
/* re-read Master Boot Record */
ioreq.irHandle = handle;
ioreq.irSectorNo = (SectorNo) 0;
ioreq.irSectorCount = (SectorNo) 1;
ioreq.irData = (void FAR1 *) buf;
checkStatus( flAbsRead(&ioreq) );
/* is it MBR indeed ? */
if (LE2(((PartitionTable *) buf)->signature) != PARTITION_SIGNATURE)
return flOK;
/* pick up next extended partition in MBR */
pp = &( ((PartitionTable *) buf)->ptEntry[i] );
if( pp->type == ((char)EX_PARTIT) ) {
/* remember where extended partition starts */
extPartStartSec = (SectorNo) UNAL4( (void *) pp->startingSectorOfPartition );
/* follow the list of partition tables */
sec = extPartStartSec;
for (depth = 0; depth < MAX_PARTITION_DEPTH; depth++) {
/* read next partition table in the list */
ioreq.irHandle = handle;
ioreq.irSectorNo = sec;
ioreq.irSectorCount = (SectorNo) 1;
ioreq.irData = (void FAR1 *) buf;
checkStatus( flAbsRead(&ioreq) );
/* is it valid partition table ? */
if (LE2(((PartitionTable *) buf)->signature) != PARTITION_SIGNATURE)
break;
/* if 1st entry is zero, it's the end of part. table list */
pp = &( ((PartitionTable *) buf)->ptEntry[0] );
if( pp->type == ((char)0) )
break;
/* Take this partition. Remember it's type, and where it starts */
if( addNewDiskPart(pd) != flOK )
break;
pv = pd->part[pd->parts - 1];
pv->type = (int) pp->type;
pv->startSecNo =
(SectorNo) UNAL4( (void *) pp->startingSectorOfPartition) + sec;
/* 2nd entry must be extended partition */
pp = &( ((PartitionTable *) buf)->ptEntry[1] );
if( pp->type != ((char)EX_PARTIT) )
break;
/* sector where next part. table in the list resides */
sec = extPartStartSec +
(SectorNo) UNAL4( (void *) pp->startingSectorOfPartition );
} /* for(depth) */
}
} /* for(i) */
#ifdef FL_INCLUDE_FAT_MONITOR
/* turn on FAT filters on FAT12/16 partition(s) */
if (pd->parts > 0) {
for (i = 0; i < pd->parts; i++) {
pv = pd->part[i];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -