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

📄 fatfilt.c

📁 DOC文件系统驱动源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
            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
    char     * buf;
#else
    char       buf[SECTOR_SIZE];
#endif

    DEBUG_PRINT(("Debug: 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 >= 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 ? */

    bpb = &( ((DOSBootSector *) buf)->bpb );

    if( !((bpb->jumpInstruction[0] == 0xe9) 
            || 
         ((bpb->jumpInstruction[0] == 0xeb) && (bpb->jumpInstruction[2] == 0x90)))) {

        return flNonFATformat;
    }

    /* Do we handle this sector size ? */

    if (UNAL2(bpb->bytesPerSector) != SECTOR_SIZE)
        return flFormatNotSupported;

    /* 
     * Is it a bogus BPB (leftover from previous disk partitioning) ? 
     * Check that there is no overlap with next partition (if one exists).
     */

    sectors = UNAL2(bpb->totalSectorsInVolumeDOS3);

    if (sectors == (SectorNo)0)
        sectors = (SectorNo) LE4(bpb->totalSectorsInVolume);

    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 */

    reservedSectors = (SectorNo) LE2(bpb->reservedSectors);

    switch( (int)reservedSectors ) {

        case 32:      /* always the case with FAT 32 */

#ifndef FL_INCLUDE_FAT32

            DEBUG_PRINT(("Debug: 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;

    sectorsPerFAT = (SectorNo) LE2(bpb->sectorsPerFAT);

#ifndef FL_INCLUDE_FAT32

    if (sectorsPerFAT == 0) {        /* always the case with FAT32 */

        DEBUG_PRINT(("Debug: FAT32 detected.\r\n"));
        return flFormatNotSupported;
    }

#endif

    pv->lastFATsecNo = pv->firstFATsecNo + sectorsPerFAT - (SectorNo)1;

    /* get location and size of root directory */

    rootDirSecNo = pv->firstFATsecNo + (sectorsPerFAT * bpb->noOfFATS);

    rootDirEntries = (SectorNo) UNAL2(bpb->rootDirectoryEntries);

    switch (rootDirEntries) {

#ifndef FL_INCLUDE_FAT32

        case 0:            /* always the case with FAT32 */

            DEBUG_PRINT(("Debug: FAT32 detected.\r\n"));
            return flFormatNotSupported;
#endif
    
        default:

            if( ((rootDirEntries * DIRECTORY_ENTRY_SIZE) % SECTOR_SIZE) != 0 )
                return flNonFATformat;
            break;
    }

    rootDirSectors = (SectorNo)(((rootDirEntries * DIRECTORY_ENTRY_SIZE) - 1) / 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 */

    pv->clusterSize = bpb->sectorsPerCluster;

    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 * SECTOR_SIZE) > (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 FAT_12BIT

        DEBUG_PRINT(("Debug: FAT_12BIT must be defined.\r\n"));
        return flFormatNotSupported;

#else

        DEBUG_PRINT(("Debug: FAT12 detected.\r\n"));

#endif /* FAT_12BIT */
    }
    else {

        DEBUG_PRINT(("Debug: 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,
                                       char FAR1 * newFAT)
{
    FLffDisk * pd;
    int        socNo, diskNo;
    unsigned   short oldFATentry, newFATentry;
    SectorNo   iSec;
    unsigned   firstCluster;
    IOreq      ioreq;
    int        offset;
    int        iPart;

#ifdef FAT_12BIT
    int        halfBytes;
#endif

#ifdef  FL_MALLOC
    char     * oldFAT;
#else
    char       oldFAT[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 >= 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 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 * SECTOR_SIZE)) + 2) / 3;
    }
    else {
        firstCluster = ((unsigned)(secNo - pv->firstFATsecNo)) * (SECTOR_SIZE / 2);
    }

    /* staring data sector */

    iSec = (((SectorNo)firstCluster - 2) * pv->clusterSize) + pv->firstDataSecNo;

    offset = (firstCluster * ((unsigned) halfBytes)) & ((2 * 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 * SECTOR_SIZE) - 2); 
               offset += halfBytes, iSec += pv->clusterSize) {

#ifdef FL_BIG_ENDIAN
        oldFATentry = LE2( *(LEushort FAR0 *)(oldFAT + (offset / 2)) );
        newFATentry = LE2( *(LEushort FAR1 *)(newFAT + (offset / 2)) );
#else
        oldFATentry = UNAL2( *(Unaligned FAR0 *)(oldFAT + (offset / 2)) );
        newFATentry = UNAL2( *(Unaligned FAR1 *)(newFAT + (offset / 2)) );
#endif /* FL_BIG_ENDIAN */

        if (offset & 1) {
            oldFATentry >>= 4;
            newFATentry >>= 4;
        }
        else { 
            if (halfBytes == 3) {
                oldFATentry &= 0xfff;
                newFATentry &= 0xfff;
        }
        }

#else /* !FAT_12BIT */

    firstCluster = ((unsigned) (secNo - pv->firstFATsecNo) * (SECTOR_SIZE / 2));
    iSec  = pv->firstDataSecNo + 
            (((SectorNo)(firstCluster - (unsigned)2)) * pv->clusterSize);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -