📄 fatfilt.c
字号:
/*******************************************************************************
* *
* 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 + -