?? fatfilt.c
字號:
/***********************************************************************************/
/* M-Systems Confidential */
/* Copyright (C) M-Systems Flash Disk Pioneers Ltd. 1995-2003 */
/* 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 */
/***********************************************************************************/
/*
* $Log: V:/PVCSDB/DiskOnChip/archives/general storage/TrueFFS/src/fs/fatfilt.c-arc $
*
* Rev 1.1 Sep 30 2003 17:57:20 oris
* Added FL prefix to SECTOR_SIZE and SECTOR_SIZE_BITS
*
* Rev 1.0 Apr 09 2003 12:16:02 OriS
* Initial revision.
*
*/
/*******************************************************************************
* *
* *
* Module: FATFILT *
* *
* This module implements installable FAT12/16 filters. It supports up to *
* SOCKETS sockets, with up to FL_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. *
* *
*******************************************************************************/
/*
* 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) (*((FLSByte FAR1 **)((ioreq)->irData) + (int)(i)))
#else
#define FLBUF(ioreq,i) ((FLSByte FAR1 *)(ioreq->irData) + (FL_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 (FLSByte FAR1 *buf, SectorNo *nextExtPartSec);
static FLBoolean isBPBchanged (FLffVol *pv, FLSByte FAR1 *buf);
#ifdef FL_INCLUDE_FAT_MONITOR
static FLStatus partEnableFF (FLffVol* pv);
static FLStatus partFreeDelClusters (FLffVol *pv, SectorNo secNo, FLSByte FAR1 *newFAT);
#endif
/*
* Local data
*/
/* module reset flag */
static FLBoolean resetDone = FALSE;
/* disks (BDTL partitions in OSAK terminology) */
static FLffDisk* ffDisk[SOCKETS][FL_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][FL_MAX_TL_PARTITIONS];
static FLffVol ffAllParts[SOCKETS][FL_MAX_TL_PARTITIONS][FL_MAX_PARTS_PER_DISK];
#endif /* FL_MALLOC */
static const FLSByte zeroes[FL_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 >= FL_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 >= FL_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 >= FL_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 = (FLSByte *)FL_MALLOC( FL_SECTOR_SIZE );
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;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -