⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fatfilt.c

📁 DOC文件系统驱动源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
    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 + -