📄 fatfilt.c
字号:
FLffDisk * pd;
FLffVol * pv;
Partition * pp;
IOreq ioreq;
#ifdef FL_MALLOC
FLSByte * buf;
#else
FLSByte buf[FL_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 >= FL_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 ? */
#ifndef FL_NO_PACKED_STRUCTS_SUPPORTED
if (LE2(((PartitionTable *) buf)->signature) != PARTITION_SIGNATURE)
#else
if (FL_GET_LE2(buf, FL_PARTITION_TABLE_SIGNATURE_OFFSET) != PARTITION_SIGNATURE)
#endif
return flPartitionNotFound;
/* do primary partitions only (we will do extended partitions later) */
#ifndef FL_NO_PACKED_STRUCTS_SUPPORTED
pp = &( ((PartitionTable *) buf)->ptEntry[0] );
#else
pp = (Partition *) &FL_REF_1(buf, FL_PARTITION_TABLE_PT_ENTRY_OFFSET );
#endif
for (i = 0; i < FL_PART_TBL_ENTRIES; i++, pp++) {
#ifndef FL_NO_PACKED_STRUCTS_SUPPORTED
FLByte ppType = pp->type;
#else
FLByte ppType = FL_REF_1(pp, FL_PARTITION_TYPE_OFFSET);
#endif
if( ppType == ((FLSByte)0) ) /* skip empty slot */
continue;
if( ppType == ((FLSByte)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) ppType;
#ifndef FL_NO_PACKED_STRUCTS_SUPPORTED
pv->startSecNo = (SectorNo) UNAL4( pp->startingSectorOfPartition );
#else
pv->startSecNo = (SectorNo) FL_GET_UNAL4(pp, FL_PARTITION_STARTING_SECTOR_OF_PARTITION_OFFSET );
#endif
}
/* 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 ? */
#ifndef FL_NO_PACKED_STRUCTS_SUPPORTED
if (LE2(((PartitionTable *) buf)->signature) != PARTITION_SIGNATURE)
#else
if (FL_GET_LE2(buf, FL_PARTITION_TABLE_SIGNATURE_OFFSET) != PARTITION_SIGNATURE)
#endif
return flOK;
/* pick up next extended partition in MBR */
#ifndef FL_NO_PACKED_STRUCTS_SUPPORTED
pp = &( ((PartitionTable *) buf)->ptEntry[i] );
if( pp->type == ((FLSByte)EX_PARTIT) ) {
/* remember where extended partition starts */
extPartStartSec = (SectorNo) UNAL4( pp->startingSectorOfPartition );
#else
pp = (Partition *)&FL_REF_1(buf, FL_PARTITION_TABLE_PT_ENTRY_OFFSET + FL_PARTITION_SIZE*i);
if( FL_REF_1(pp, FL_PARTITION_TYPE_OFFSET) == ((FLSByte)EX_PARTIT) ) {
/* remember where extended partition starts */
extPartStartSec = (SectorNo) FL_GET_UNAL4(pp, FL_PARTITION_STARTING_SECTOR_OF_PARTITION_OFFSET );
#endif
/* follow the list of partition tables */
sec = extPartStartSec;
for (depth = 0; depth < FL_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 ? */
#ifndef FL_NO_PACKED_STRUCTS_SUPPORTED
if (LE2(((PartitionTable *) buf)->signature) != PARTITION_SIGNATURE)
#else
if (FL_GET_LE2(buf, FL_PARTITION_TABLE_SIGNATURE_OFFSET) != PARTITION_SIGNATURE)
#endif
break;
/* if 1st entry is zero, it's the end of part. table list */
#ifndef FL_NO_PACKED_STRUCTS_SUPPORTED
pp = &( ((PartitionTable *) buf)->ptEntry[0] );
if( pp->type == ((FLSByte)0) )
#else
pp = (Partition *) &FL_REF_1(buf, FL_PARTITION_TABLE_PT_ENTRY_OFFSET );
if( FL_REF_1(pp, FL_PARTITION_TYPE_OFFSET) == ((FLSByte)0) )
#endif
break;
/* Take this partition. Remember it's type, and where it starts */
if( addNewDiskPart(pd) != flOK )
break;
pv = pd->part[pd->parts - 1];
#ifndef FL_NO_PACKED_STRUCTS_SUPPORTED
pv->type = (int) pp->type;
pv->startSecNo =
(SectorNo) UNAL4( pp->startingSectorOfPartition) + sec;
#else
pv->type = (int) FL_REF_1(pp, FL_PARTITION_TYPE_OFFSET);
pv->startSecNo =
(SectorNo) FL_GET_UNAL4(pp, FL_PARTITION_STARTING_SECTOR_OF_PARTITION_OFFSET) + sec;
#endif
/* 2nd entry must be extended partition */
#ifndef FL_NO_PACKED_STRUCTS_SUPPORTED
pp = &( ((PartitionTable *) buf)->ptEntry[1] );
if( pp->type != ((FLSByte)EX_PARTIT) )
#else
pp = (Partition *) &FL_REF_1(buf, FL_PARTITION_TABLE_PT_ENTRY_OFFSET + FL_PARTITION_SIZE );
if( FL_REF_1(pp, FL_PARTITION_TYPE_OFFSET) != ((FLSByte)EX_PARTIT) )
#endif
break;
/* sector where next part. table in the list resides */
#ifndef FL_NO_PACKED_STRUCTS_SUPPORTED
sec = extPartStartSec +
(SectorNo) UNAL4( pp->startingSectorOfPartition );
#else
sec = extPartStartSec +
(SectorNo) FL_GET_UNAL4(pp, FL_PARTITION_STARTING_SECTOR_OF_PARTITION_OFFSET );
#endif
} /* 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];
type = pv->type;
/*
* WARNING : Routine partEnableFF() uses disk's scratch buffer !
*/
if((type == FAT12_PARTIT) || (type == FAT16_PARTIT) || (type == DOS4_PARTIT))
partEnableFF (pv);
}
}
#endif /* FL_INCLUDE_FAT_MONITOR */
/* watch for MBR (sector #0) update */
pd->secToWatch = (SectorNo) 0;
pd->ffstate = flStateInitialized;
return flOK;
}
#ifdef FL_INCLUDE_FAT_MONITOR
/* --------------------------------------------------------------------------- *
* *
* p a r t E n a b l e F F *
* *
* Installs and enables FAT filter on partition. *
* *
* Parameters: *
* pv : disk partition (filesystem volume) *
* *
* Returns: *
* flOK on success, otherwise error code *
* *
* NOTE: This routine uses disk's scratch buffer. *
* *
* --------------------------------------------------------------------------- */
static FLStatus partEnableFF ( FLffVol * pv )
{
int socNo, diskNo;
FLffDisk * pd;
BPB * bpb;
SectorNo sectors;
SectorNo reservedSectors;
SectorNo rootDirSecNo;
SectorNo rootDirSectors;
SectorNo sectorsPerFAT;
SectorNo rootDirEntries;
unsigned maxCluster;
int partNo;
IOreq ioreq;
#ifdef FL_MALLOC
FLSByte * buf;
#else
FLSByte buf[FL_SECTOR_SIZE];
#endif
DBG_PRINT_FLOW(FLZONE_FS,"Debug: (partEnableFF) checking FAT type.\r\n");
/* 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 (partNo = 0; partNo < pd->parts; partNo++) {
if (pd->part[partNo] == pv)
break;
}
if (partNo >= pd->parts)
return flBadDriveHandle;
#ifdef FL_MALLOC
/* make sure scratch buffer is available */
if (pd->buf == NULL)
return flBufferingError;
buf = pd->buf;
#endif /* FL_MALLOC */
/* make sure FAT filter is off on this partition */
pv->ffEnabled = FALSE;
pv->firstFATsecNo = (SectorNo) -1;
pv->lastFATsecNo = pv->firstFATsecNo;
pv->clusterSize = (unsigned) 0;
/* read BPB */
ioreq.irHandle = pv->handle;
ioreq.irSectorNo = pv->startSecNo;
ioreq.irSectorCount = (SectorNo) 1;
ioreq.irData = (void FAR1 *) buf;
checkStatus( flAbsRead(&ioreq) );
/* Does it look like DOS bootsector ? */
#ifndef FL_NO_PACKED_STRUCTS_SUPPORTED
bpb = &( ((DOSBootSector *) buf)->bpb );
if( !((bpb->jumpInstruction[0] == 0xe9)
||
((bpb->jumpInstruction[0] == 0xeb) && (bpb->jumpInstruction[2] == 0x90)))) {
#else
bpb = (BPB *) buf;
if( !((FL_REF_1(bpb, FL_BPB_JUMP_INSTRUCTION_OFFSET) == 0xe9)
||
((FL_REF_1(bpb, FL_BPB_JUMP_INSTRUCTION_OFFSET) == 0xeb) && (FL_REF_1(bpb, FL_BPB_JUMP_INSTRUCTION_OFFSET + 2) == 0x90)))) {
#endif
return flNonFATformat;
}
/* Do we handle this sector size ? */
#ifndef FL_NO_PACKED_STRUCTS_SUPPORTED
if (UNAL2(bpb->bytesPerSector) != FL_SECTOR_SIZE)
#else
if (FL_GET_UNAL2(bpb, FL_BPB_BYTES_PER_SECTOR_OFFSET) != FL_SECTOR_SIZE)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -