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

📄 fatfilt.c

📁 DOC文件系统驱动源代码
💻 C
📖 第 1 页 / 共 4 页
字号:

/******************************************************************************* 
 *                                                                             * 
 *                         M-Systems Confidential                              * 
 *           Copyright (C) M-Systems Flash Disk Pioneers Ltd. 1995-2001        * 
 *                         All Rights Reserved                                 * 
 *                                                                             * 
 ******************************************************************************* 
 *                                                                             * 
 *                         NOTICE OF M-SYSTEMS OEM                             * 
 *                         SOFTWARE LICENSE AGREEMENT                          * 
 *                                                                             * 
 *  THE USE OF THIS SOFTWARE IS GOVERNED BY A SEPARATE LICENSE AGREEMENT       * 
 *  BETWEEN THE OEM AND M-SYSTEMS. REFER TO THAT AGREEMENT FOR THE SPECIFIC    * 
 *  TERMS AND CONDITIONS OF USE, OR CONTACT M-SYSTEMS FOR LICENSE              * 
 *  ASSISTANCE:                                                                * 
 *  E-MAIL = info@m-sys.com                                                    * 
 *                                                                             * 
 *******************************************************************************
 *                                                                             * 
 *                                                                             * 
 *                         Module: FATFILT                                     * 
 *                                                                             * 
 *  This module implements installable FAT12/16 filters. It supports up to     *
 *  SOCKETS sockets, with up to MAX_TL_PARTITIONS disks per socket.            * 
 *  Each disk can contain up to FL_MAX_PARTS_PER_DISK partitions on it, with   * 
 *  maximum depth of partition nesting in extended partitions equal to         * 
 *  MAX_PARTITION_DEPTH.                                                       *
 *                                                                             * 
 *  In order for this module to work, disks must be abs.mounted rather then    * 
 *  mounted. In latter case, this module won't detect any of disk's            * 
 *  partitions, and won't install FAT filters.                                 * 
 *                                                                             * 
 *  This module uses more then 512 bytes of stack space in case if MALLOC is   * 
 *  not enabled.                                                               * 
 *                                                                             * 
 *******************************************************************************/

/*
 * $Log:   V:/Flite/archives/TrueFFS5/Src/FATFILT.C_V  $
 * 
 *    Rev 1.12   06 Jun 2002 19:30:24   andreyk
 * sanity checks for BPB fields, checking for FAT32
 * 
 *    Rev 1.11   04 Jun 2002 22:59:28   andreyk
 * turn off FAT monitor if BPB is changed
 * 
 *    Rev 1.10   Jan 17 2002 23:00:14   oris
 * Changed debug print added \r.
 * 
 *    Rev 1.9   Sep 15 2001 23:45:50   oris
 * Changed BIG_ENDIAN to FL_BIG_ENDIAN
 * 
 *    Rev 1.8   Jun 17 2001 16:39:10   oris
 * Improved documentation and remove warnings.
 * 
 *    Rev 1.7   May 16 2001 21:17:18   oris
 * Added the FL_ prefix to the following defines: MALLOC and FREE.
 * 
 *    Rev 1.6   May 01 2001 14:21:02   oris
 * Remove warnings.
 * 
 *    Rev 1.5   Apr 30 2001 18:00:10   oris
 * Added casting to remove warrnings.
 * 
 *    Rev 1.4   Apr 24 2001 17:07:32   oris
 * Missing casting of MALLOC calls.
 * 
 *    Rev 1.3   Apr 10 2001 23:54:24   oris
 * FL_MAX_DISKS_PER_SOCKET changed to MAX_TL_PARTITIONS.
 * 
 *    Rev 1.2   Apr 09 2001 15:00:42   oris
 * Change static allocation to dynamic allocations.
 * Renamed flffCheck back to ffCheckBeforeWrite to be backwards compatible with OSAK 4.2.
 * 
 *    Rev 1.1   Apr 01 2001 07:51:16   oris
 * New implementation of fat filter.
 * 
 *    Rev 1.0   19 Feb 2001 21:14:14   andreyk
 * Initial revision.
 */




/* 
 * Includes
 */

#include "fatfilt.h"
#include "blockdev.h"
#include "flflash.h"
#include "bddefs.h"


#if defined(ABS_READ_WRITE) && !defined(FL_READ_ONLY)




/*
 * Module configuration
 */

#define  FL_INCLUDE_FAT_MONITOR     /* undefine it to remove FAT filter code */
#undef   FL_INCLUDE_FAT32           /* define after support for FAT32 is added */




/*
 * Defines
 */

/* extract pointer to user's buffer from IOreq */

#ifdef SCATTER_GATHER
#define  FLBUF(ioreq,i)  (*((char FAR1 **)((ioreq)->irData) + (int)(i)))
#else
#define  FLBUF(ioreq,i)  ((char FAR1 *)(ioreq->irData) + (SECTOR_SIZE * ((int)(i))))
#endif

/* extract socket# and disk# from TFFS handle */

#define  H2S(handle)     (((int)(handle)) & 0xf)
#define  H2D(handle)     ((((int)(handle)) >> 4) & 0xf)

/* construct TFFS handle from socket# and disk# */

#define  SD2H(socNo,diskNo)  ((int)((((diskNo) & 0xf) << 4) | ((socNo) & 0xf)))

/* unformatted ("raw") disk partition */

#define  FL_RAW_PART  (-1)




/*
 * Local routines 
 */

static FLStatus   reset (void);
static FLStatus   discardDisk (int handle);
static FLStatus   newDisk (int handle);
static FLStatus   parseDisk (int handle);
static FLStatus   discardDiskParts (FLffDisk *pd);
static FLStatus   addDiskPart (FLffDisk *pd, int partNo);
static FLStatus   addNewDiskPart (FLffDisk *pd);
static FLBoolean  isPartTableWrite (FLffDisk *pd, IOreq FAR2 *ioreq);
static FLStatus   isExtPartPresent (char FAR1 *buf, SectorNo *nextExtPartSec);
static FLBoolean  isBPBchanged (FLffVol *pv, char FAR1 *buf);


#ifdef FL_INCLUDE_FAT_MONITOR

static FLStatus   partEnableFF (FLffVol* pv);
static FLStatus   partFreeDelClusters (FLffVol *pv, SectorNo secNo, char FAR1 *newFAT);

#endif




/*
 * Local data
 */

/* module reset flag */

static FLBoolean  resetDone = FALSE; 

/* disks (BDTL partitions in OSAK terminology) */

static FLffDisk*  ffDisk[SOCKETS][MAX_TL_PARTITIONS] = { { NULL } };


#ifndef FL_MALLOC

/*          
 *        WARNING: Large static arrays ! 
 *
 *  sizeof(ffAllDisks[x][y])    is 64 bytes. 
 *  sizeof(ffAllParts[x][y][z]) is 40 bytes.
 *
 */

static FLffDisk ffAllDisks[SOCKETS][MAX_TL_PARTITIONS];
static FLffVol  ffAllParts[SOCKETS][MAX_TL_PARTITIONS][FL_MAX_PARTS_PER_DISK];

#endif /* FL_MALLOC */

static const char zeroes[SECTOR_SIZE] = {0};




/* --------------------------------------------------------------------------- *
 *                                                                             *
 *                    d i s c a r d D i s k P a r t s                          *
 *                                                                             * 
 *  Discard all the partition info (if any) associated with particular disk.   * 
 *                                                                             * 
 *  Parameters:                                                                * 
 *      pd                 : disk (BDTL volume)                                   * 
 *                                                                             * 
 *  Returns:                                                                   * 
 *      Always flOK.                                                           * 
 *                                                                             * 
 * --------------------------------------------------------------------------- */

static FLStatus  discardDiskParts ( FLffDisk * pd )
{
    register int  i;

    if (pd != NULL) {

        for (i = 0; i < FL_MAX_PARTS_PER_DISK; i++) {

#ifdef FL_MALLOC
        if (pd->part[i] != NULL)
            FL_FREE(pd->part[i]);
#endif

            pd->part[i] = NULL;
        }

        pd->parts = 0;
    }

    return flOK;
}




/* --------------------------------------------------------------------------- *
 *                                                                             *
 *                      a d d D i s k P a r t                                  *
 *                                                                             * 
 *  If there is partition record #partNo associated with the disk, discard     * 
 *  this info. Attach new partition record #partNo.                            * 
 *                                                                             * 
 *  Parameters:                                                                * 
 *      pd                 : disk (BDTL volume)                                   * 
 *      partNo             : partition (0 ... FL_MAX_PARTS_PER_DISK-1)            * 
 *                                                                             * 
 *  Returns:                                                                   * 
 *      flOK if success, otherwise respective error code                       * 
 *                                                                             * 
 * --------------------------------------------------------------------------- */

static FLStatus  addDiskPart ( FLffDisk * pd, 
                               int        partNo )
{
    FLffVol  * pv;    
    FLStatus   status;
    int        socNo, diskNo;

    /* arg. sanity check */

    if ((pd == NULL) || (partNo >= FL_MAX_PARTS_PER_DISK))
        return flBadDriveHandle;

    /* break TFFS handle into socket# and disk#, and do sanity check */

    socNo  = H2S(pd->handle);
    diskNo = H2D(pd->handle);
 
    if ((socNo >= SOCKETS) || (diskNo >= MAX_TL_PARTITIONS))
        return flBadDriveHandle;

    status = flNotEnoughMemory;

#ifdef FL_MALLOC
    pv = (FLffVol *)FL_MALLOC( sizeof(FLffVol) );
#else
    pv = &ffAllParts[socNo][diskNo][partNo];
#endif

    if (pv != NULL) {

        /* initialize fields in struct FLffDisk to safe values */
 
        pv->handle         = pd->handle; 
        pv->type           = FL_RAW_PART;
        pv->flags          = 0;          
        pv->ffEnabled      = FALSE;                  /* turn off FAT minitor */
        pv->sectors        = (SectorNo) 0;
        pv->firstFATsecNo  = (SectorNo) -1;          /* none */
        pv->lastFATsecNo   = pv->firstFATsecNo;      /* none */
        pv->firstDataSecNo = (SectorNo) 0;
        pv->clusterSize    = (unsigned) 0;

#ifdef FL_MALLOC
        if( pd->part[partNo] != NULL )
        FL_FREE(pd->part[partNo]);
#endif
        
        pd->part[partNo] = pv;

        status = flOK;
    }

    return status;    
}




/* --------------------------------------------------------------------------- *
 *                                                                             *
 *                    a d d N e w D i s k P a r t                              *
 *                                                                             * 
 *  Add one more partition record to the disk.                                 * 
 *                                                                             * 
 *  Parameters:                                                                * 
 *      pd                 : disk (BDTL volume)                                   * 
 *                                                                             * 
 *  Returns:                                                                   * 
 *      flOK if success, otherwise respective error code                       * 
 *                                                                             * 
 * --------------------------------------------------------------------------- */

static FLStatus  addNewDiskPart ( FLffDisk * pd )
{
    if (pd->parts < FL_MAX_PARTS_PER_DISK) {

        checkStatus( addDiskPart (pd, pd->parts) );
    pd->parts++;
    }

    return flOK;
}




/* --------------------------------------------------------------------------- *
 *                                                                             *
 *                       d i s c a r d D i s k                                 *
 *                                                                             * 
 *  Remove disk record (with all the associated partition records).            * 
 *                                                                             * 
 *  Parameters:                                                                * 
 *      handle             : TFFS handle                                          * 
 *                                                                             * 
 *  Returns:                                                                   * 
 *      flOK if success, otherwise respective error code                       * 
 *                                                                             * 
 * --------------------------------------------------------------------------- */

static FLStatus  discardDisk ( int  handle )
{
    int  socNo, diskNo;

    /* break TFFS handle into socket# and disk#, and do sanity check */

    socNo  = H2S(handle);
    diskNo = H2D(handle);
 
    if ((socNo >= SOCKETS) || (diskNo >= MAX_TL_PARTITIONS))
        return flBadDriveHandle;

    if( ffDisk[socNo][diskNo] != NULL ) {

    /* discard associated partition info */

    (void) discardDiskParts( ffDisk[socNo][diskNo] );

#ifdef FL_MALLOC

        /* release disk's scratch buffer */
 
        if( (ffDisk[socNo][diskNo])->buf != NULL)
            FL_FREE( (ffDisk[socNo][diskNo])->buf );

        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 >= SOCKETS) || (diskNo >= 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 = (char *)FL_MALLOC( SECTOR_SIZE );

⌨️ 快捷键说明

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