fat.h File Reference


Detailed Description

FAT file system module C header file.

REVISION

Definition in file fat.h.

#include "../feature.h"
#include "../MESSAGE/message.h"
#include "../GENERIC/generic.h"
#include "../NAND/nand.h"
#include "../HDD/hdd.h"

Include dependency graph for fat.h:

Include dependency graph

This graph shows which files directly or indirectly include this file:

Included by dependency graph

Go to the source code of this file.

Data Structures

struct  st_FATDISK
 FAT disk data structure. More...
struct  st_CURWORKDIR
 Current working directory. More...
struct  st_FATFILEINFO
 FAT file info. More...
struct  st_FATDIRENT
 FAT dir/file entry structure. More...
struct  st_FATDIRSEARCH
 FAT dir/file entry search control structure. More...
struct  st_FATFIND
 FAT find operation control structure. More...
struct  File
 File structure defintion. More...

Defines

#define SET_DATETIME
 Enable date time support for file/dir creation.
#define _FAT_REMOVE_FAT12_SUPPORT
 Enable this definition removes FAT12 support.
#define _RECORD_CURWORKDIR_PATH
 Define to record current working directory path name.
#define BOOTLOADER_SEC_LEN   256
 256 Sectors reserved for bootloader backup in NAND.
#define MEDIA_RSV_SEC_LEN   64
 64 sectors reserved for parameters etc.
#define FAT_MAX_FOPEN   16
 Number concurrently opened files.
#define FAT_MAXLFN   (260)
 Maximum LFN length in bytes.
#define FAT_INVALIDSEC   (0xFFFFFFFFL)
 Invalid FAT sector.
#define FAT_FIRSTCLUS   (2)
 First data cluster.

Enumerations

enum  DISK_ID { DISK_C, DISK_D }
 Disk ID definition. More...
enum  FAT_MOUNT_MSG { FAT_MOUNT_SUCCESS, FAT_MOUNT_MEDIA_FAILURE, FAT_MOUNT_FAT_FAILURE, FAT_MOUNT_MEDIA_NOT_PRESENT }
 FAT mount disk returning message. More...
enum  FAT_TYPE
 FAT type enumeration.
enum  FAT_FORMAT_TYPE { FAT_HIGH_LEVEL_FORMAT, FAT_LOW_LEVEL_FORMAT, FAT_MEDIA_FORMAT }
 FAT format type enumeration. More...
enum  FOPEN_MODE { wb, rb, ab, r_b, w_b, a_b }
 File open mode defintion. More...
enum  SEEK_MODE { SEEK_HEAD, SEEK_MID, SEEK_TAIL }
 File seek mode flag. More...
enum  ENT_TYPE { ENT_FREE, ENT_DEL, ENT_DIR, ENT_FILE, ENT_VOL, ENT_LFN }

Functions

BOOL FAT_format (DISK_ID, FAT_FORMAT_TYPE, unsigned long)
 Function will reformat the entire volume at given level.
FAT_MOUNT_MSG FAT_mountDisk (DISK_ID)
 Function checks to mount specified disk and reports mount message.
void FAT_releaseCurWorkDir (TSK_Handle)
 Function release the current working directory of given task.
long FAT_findFirst (const char *, st_FATFILEINFO *)
 Function finds the first valid directory or file under current directory.
BOOL FAT_finsert (File *, unsigned long, const unsigned short *, unsigned short, unsigned long)
 This function is used to insert data inside of file.
BOOL FAT_attr (const char *, unsigned short)
 Function changes attribute of the specified file/directory.
FileFAT_bfopen (const char *, FOPEN_MODE, File *)
 Function opens the file with supplied file object buffer.
BOOL FAT_cd (const char *)
 Function changes current workding directory to specified path.
BOOL FAT_delete (const char *)
 Function deletes file ONLY under current working directory.
BOOL FAT_flushDisk (DISK_ID)
 Function flushes the FAT disk and makes all change final.
BOOL FAT_mkdir (const char *)
 Function creates directory under current working directory if not exists already.
BOOL FAT_rmdir (const char *)
 Function removes the given directory under current working directory and any subdirs or files.
FileFAT_fopen (const char *, FOPEN_MODE)
 Function opens the file specified by pName in a mode specified by eMode under current working directory.
BOOL FAT_fclose (File *)
 Function closes file and flushes disk.
BOOL FAT_fseek (File *, long, SEEK_MODE)
 Function seeks in file.
short FAT_fread (File *, unsigned short *, short)
 Function read file and return number of read words.
short FAT_fwrite (File *, unsigned short *, short)
 Function writes to file and return number of written words.
BOOL FAT_copyFile (const char *, const char *, USHORT *, USHORT)
 Copy srcFile to dstFile.
BOOL FAT_copyDir (const char *, const char *, USHORT *, USHORT)
 Copy all files in srcDir to dstDir.
ULONG FAT_freeSpace (DISK_ID)
 Function returns disk free space.
ULONG FAT_totalSpace (DISK_ID)
 Function returns total disk space.
BOOL FAT_frevive (const char *)
 Function checks to revive unclosed file.
unsigned long FAT__calcPhySecOfClus (unsigned long, st_FATDISK *)
 Function returns starting physical sector of given cluster.
BOOL FAT__cd (const char *, st_CURWORKDIR *)
 Function changes directory to specified path.
BOOL FAT__chg2PathDir (const char *, char **, st_CURWORKDIR *)
 Function changes directory to directory part of a given path ignoring the last part, no matter it is a directory or file.
void FAT__clearWorkDirReg (void)
 Function clears all workding directory registration.
unsigned long FAT__clusEntry (unsigned long, st_FATDISK *)
 Function returns FAT cluster entry of specified cluster.
BOOL FAT__createFile (const char *, unsigned short, unsigned long *, unsigned short *, st_CURWORKDIR *)
 Function creates directory/file under current working directory.
BOOL FAT__delete (st_FATFILEINFO *, st_CURWORKDIR *)
 Function deletes specified file/dir under the given directory.
void FAT__findClose (long)
 Function releases find cotrol objects.
long FAT__findFirst (const char *, st_FATFILEINFO *, st_CURWORKDIR *)
 Function finds the first valid dir/file under given directory.
BOOL FAT__findNext (long, st_FATFILEINFO *)
 Function finds next available directory or file under current workding directory.
unsigned short FAT__findNxtAvlblClus (unsigned long *, unsigned short, st_FATDISK *)
 Function finds next available clusters.
unsigned short FAT__findNxtOcupdClus (unsigned long, st_FATDISK *)
 Function finds next occupied clusters from FAT.
BOOL FAT__flush (st_FATDISK *)
 Function flushes the specified disk.
FileFAT__fopen (const char *pName, FOPEN_MODE eMode, st_CURWORKDIR *)
 Function opens the file specified by pName in a mode specified by eMode under given working directory.
FileFAT__bfopen (const char *pName, FOPEN_MODE eMode, File *, st_CURWORKDIR *)
 Function opens the file specified by pName in a mode specified by eMode under given working directory.
BOOL FAT__fflush (File *)
 Function flushes specified file.
unsigned long FAT__freeClusNum (DISK_ID)
 Function returns the free cluster number of the specified disk.
BOOL FAT__fseek (File *, long, SEEK_MODE)
 Function seeks in file, assuming file is seekable.
st_CURWORKDIRFAT__getCurWorkDir (void)
 Function returns the current working directory of current task.
void FAT__getFinfo (st_FATFILEINFO *, st_FATDIRSEARCH *, st_FATDIRENT *)
 Function fetches detailed file info out of directory entry.
void FAT__getFrstDirEnt (st_FATDIRSEARCH *, st_FATDIRENT *, st_CURWORKDIR *)
 Function fetches the first directory entry under current working directory.
BOOL FAT__getNxtDirEnt (st_FATDIRSEARCH *, st_FATDIRENT *)
 Function fetches the next directory entry under current working directory.
void FAT__intprtDirEnt (const unsigned short *, st_FATDIRENT *, st_FATDISK *)
 Function interpretes the directory entry.
BOOL FAT__isSnameChar (char)
 Function checks to see if character is valid for short file name, following MS standard.
BOOL FAT__mkdir (const char *, st_CURWORKDIR *)
 Function creates directory under given working directory if not exists already.
void FAT__pathAppend (char *, const char *)
 Function appends a name string to path.
BOOL FAT__readWord (unsigned long, unsigned short, unsigned short *, unsigned short, BOOL, st_FATDISK *)
 Function reads back words from data area.
BOOL FAT__readFatWord (unsigned long, unsigned short, unsigned short *, unsigned short, BOOL, st_FATDISK *)
 Function reads back a word from FAT area.
BOOL FAT__releaseClus (unsigned long, st_FATDISK *)
 Function releases the cluster linklist.
int FAT__strcmp (const char *, const char *)
 Function carries out special FAT string comparation, it checks the '/' or NULL as the string terminator and compares at upper case.
void FAT__pathTruncate (char *)
 Function truncate current path and go up once.
BOOL FAT__unmountDisk (DISK_ID)
 Function unmounts disk to flush.
BOOL FAT__updateCopyOfFAT (unsigned long, unsigned long, unsigned short, unsigned short, st_FATDISK *)
 Function updates specified copy of FAT.
BOOL FAT__updateSecondCopyOfFAT (unsigned long, st_FATDISK *)
 Function updates the second copy of FAT based on FAT entry in first copy.
BOOL FAT__updateFAT (unsigned long, unsigned long, unsigned short, st_FATDISK *)
 Function updates both copies of FAT.
BOOL FAT__writeWord (unsigned long, unsigned short, unsigned short *, unsigned short, st_FATDISK *)
 Function writes a word to data area.
void FAT_hdlInit (void)
 Function initializes file system handle objects.

Variables

st_FATDISK DiskC
 GLOBAL DATA.


Enumeration Type Documentation

enum DISK_ID
 

Disk ID definition.

Enumeration values:
DISK_C  Hard disk.
DISK_D  NAND disk.

Definition at line 85 of file fat.h.

00086 {
00087     DISK_C, 
00088     DISK_D  
00089 } DISK_ID;

enum ENT_TYPE
 

Enumeration values:
ENT_FREE  free entry.
ENT_DEL  deleted entry.
ENT_DIR  directory.
ENT_FILE  file.
ENT_VOL  volume entry.
ENT_LFN  long file name entry.

Definition at line 148 of file fat.h.

Referenced by FAT__createFile(), FAT__findFirst(), and FAT__findNext().

00149 {
00150     ENT_FREE,   
00151     ENT_DEL,    
00152     ENT_DIR,    
00153     ENT_FILE,   
00154     ENT_VOL,    
00155     ENT_LFN,    
00156     ENT_INVALID
00157 } ENT_TYPE;

enum FAT_FORMAT_TYPE
 

FAT format type enumeration.

Enumeration values:
FAT_HIGH_LEVEL_FORMAT  high-level format, rewrite FAT table.
FAT_LOW_LEVEL_FORMAT  low-level format, rewrite MBR/BR.
FAT_MEDIA_FORMAT  media level format.

Definition at line 116 of file fat.h.

00117 {
00118     FAT_HIGH_LEVEL_FORMAT,  
00119     FAT_LOW_LEVEL_FORMAT,   
00120     FAT_MEDIA_FORMAT        
00121 } FAT_FORMAT_TYPE;

enum FAT_MOUNT_MSG
 

FAT mount disk returning message.

Enumeration values:
FAT_MOUNT_SUCCESS  success.
FAT_MOUNT_MEDIA_FAILURE  unable to mount media.
FAT_MOUNT_FAT_FAILURE  unable to mount fat.
FAT_MOUNT_MEDIA_NOT_PRESENT  media not present.

Definition at line 94 of file fat.h.

00095 {
00096     FAT_MOUNT_SUCCESS,          
00097     FAT_MOUNT_MEDIA_FAILURE,    
00098     FAT_MOUNT_FAT_FAILURE,      
00099     FAT_MOUNT_MEDIA_NOT_PRESENT,
00100     FAT_MOUNT_UNKNOWN_ERROR
00101 } FAT_MOUNT_MSG;

enum FOPEN_MODE
 

File open mode defintion.

Use enumeration instead of string to save memeory.

Enumeration values:
wb  open(if exist) or create(if not exist) binary file to be written continuously only.
rb  open binary file to be read only.
ab  open(if exist) or create(if not exist) binary file to be appended continuously only.
r_b  open(if exist) or create(if not exist) binary file to be read/written.
w_b  create binary file to be read/written, not supported yet.
a_b  append to binary read/write file, not supported yet.

Definition at line 126 of file fat.h.

Referenced by FAT_fclose(), FAT_fseek(), and FAT_fwrite().

00127 {
00128     wb, 
00129     rb, 
00130     ab, 
00131     r_b,
00132     w_b,
00133     a_b,
00134     fopen_invalid_mode
00135 } FOPEN_MODE;

enum SEEK_MODE
 

File seek mode flag.

Enumeration values:
SEEK_HEAD  From start.
SEEK_MID  From current position.
SEEK_TAIL  From end.

Definition at line 139 of file fat.h.

00140 {   
00141     SEEK_HEAD,  
00142     SEEK_MID,   
00143     SEEK_TAIL   
00144 } SEEK_MODE;


Function Documentation

File* FAT__bfopen const char *  pName,
FOPEN_MODE  eMode,
File file,
st_CURWORKDIR pDir
 

Function opens the file specified by pName in a mode specified by eMode under given working directory.

Functoin will NOT change the current working directory. Function will NOT open or create any directory. pName is NOT case sensitive.

Parameters:
pName file name.
eMode file open mode.
file file object pointer.
pDir working directory.
Returns:
file pointer if successfully opened, other wise NULL.

Definition at line 1532 of file fat.c.

References ab, FAT__calcPhySecOfClus(), FAT__chg2PathDir(), FAT__createFile(), FAT__findFirst(), FAT__findNxtAvlblClus(), FAT__findNxtOcupdClus(), FAT__flush(), FAT__fseek(), FAT__releaseClus(), FAT__writeWord(), File::hdlID, st_FATDISK::maxFndClus, st_FATFILEINFO::phySec, r_b, rb, SEEK_TAIL, st_FATFILEINFO::size, st_FATFILEINFO::startClus, wb, st_FATFILEINFO::wordOffset, and st_FATDISK::wrFileNum.

Referenced by FAT__fopen(), and FAT_bfopen().

01533 {
01534     unsigned short          usNum;
01535     unsigned short          wordOffset;
01536     unsigned long           phySec;
01537     unsigned long           clus;   
01538     long                    handle;
01539     char *                  pNext;
01540     st_FATDISK *            pDisk;
01541     st_FATFILEINFO          info;
01542     File *                  fcpy = file;
01543     
01544     if(FAT__chg2PathDir(pName, &pNext, pDir) == FALSE)  return NULL;
01545 
01546     file->hdlID = FAT__getHdlID();
01547     if(file->hdlID == 0) 
01548     {
01549         return NULL;
01550     }
01551     
01552     handle = FAT__findFirst(pNext, &info, pDir );
01553     if(handle != -1) FAT_findClose(handle);
01554     
01555 
01556     pDisk               = pDir->pDisk;  
01557     file->mode          = eMode;
01558     file->pDisk         = pDisk;
01559     file->flushedSize   = 0;
01560     file->ptr           = 0;
01561     
01562     if(rb == eMode)
01563     {
01564         if( (handle == -1) ||(info.size == 0) )
01565         {
01566             file = NULL;
01567         }
01568         else
01569         {
01570             clus = info.startClus;              
01571             usNum = FAT__findNxtOcupdClus(clus, pDisk);
01572     
01573             file->size = (info.size + 1)/2;
01574             file->startClus = clus;
01575             file->curClus = clus;
01576             file->preBroknClus = clus;
01577             file->nxtBroknClus = clus+usNum;
01578                     
01579             file->curPhySec = FAT__calcPhySecOfClus(clus, pDisk);
01580             file->curSecOffsetInClus = 0;
01581             file->curWordOffsetInSec = 0;
01582         }
01583     }
01584     
01585     else if( (-1==handle)&&((wb==eMode)||(ab==eMode)||(r_b==eMode)) )
01586     {
01587         if(FAT__createFile(pNext,0, &phySec, &wordOffset, pDir) == FALSE)
01588         {
01589             file = NULL;
01590         }
01591         else
01592         {
01593             usNum = FAT__findNxtAvlblClus(&clus, pDisk->maxFndClus, pDisk);
01594             if(usNum == 0)
01595             {
01596                 file = NULL;
01597             }
01598             else
01599             {
01600                 file->dirEntphySec      = phySec;
01601                 file->dirEntwordOffset  = wordOffset;
01602             
01603                 file->startUpdtClus = clus;
01604                 file->startClus     = clus;             
01605                 file->curClus       = clus;
01606                 file->preBroknClus  = clus;
01607                 file->nxtBroknClus  = clus + usNum - 1;
01608                 file->centClus      = clus + usNum/2;
01609                 file->curPhySec     = FAT__calcPhySecOfClus(clus, pDisk);
01610                 
01611                 file->size          = 0L;
01612                 file->curSecOffsetInClus = 0;
01613                 file->curWordOffsetInSec = 0;
01614                 
01615                 // Update the start cluster field of directory entry.
01616                 {
01617                     unsigned short  tmpClusHi, tmpClusLo, wordOffset;
01618                     unsigned long   phySec;
01619 
01620                     // Byte-swap to match "PC endian"
01621                     tmpClusHi = (unsigned short)((file->startClus >>16) & 0x0000FFFF);
01622                     tmpClusHi = ((tmpClusHi<<8) & 0xFF00) | ((tmpClusHi>>8) & 0x00FF);
01623                 
01624                     tmpClusLo = (unsigned short)(file->startClus & 0x0000FFFF);
01625                     tmpClusLo = ((tmpClusLo<<8) & 0xFF00) | ((tmpClusLo>>8) & 0x00FF);
01626     
01627                     // Update dir entry.
01628                     phySec      = file->dirEntphySec;
01629                     wordOffset  = file->dirEntwordOffset;
01630                             
01631                     // start cluster low.
01632                     FAT__writeWord(phySec, (unsigned short)(wordOffset + 13), &tmpClusLo, 1, pDisk);
01633                             
01634                     // start cluster high.
01635                     FAT__writeWord(phySec, (unsigned short)(wordOffset + 10), &tmpClusHi, 1, pDisk);
01636                     
01637                     FAT__flush(pDisk);
01638                 }
01639             }
01640         }       
01641     }
01642     
01643     else if( wb == eMode )
01644     {
01645         FAT__releaseClus(info.startClus, pDisk);
01646         file->dirEntphySec      = info.phySec;
01647         file->dirEntwordOffset  = info.wordOffset;
01648 
01649         usNum = FAT__findNxtAvlblClus(&clus, pDisk->maxFndClus, pDisk);
01650         if(usNum == 0)
01651         {
01652             file = NULL;
01653         }
01654         else
01655         {
01656             file->startUpdtClus = clus;
01657             file->startClus     = clus;             
01658             file->curClus       = clus;
01659             file->preBroknClus  = clus;
01660             file->nxtBroknClus  = clus + usNum - 1;
01661             file->centClus      = clus + usNum/2;
01662             file->curPhySec     = FAT__calcPhySecOfClus(clus, pDisk);
01663             
01664             file->size          = 0L;
01665             file->curSecOffsetInClus = 0;
01666             file->curWordOffsetInSec = 0;
01667         }
01668     }
01669     
01670     else if( (ab == eMode)||(r_b == eMode) )
01671     {
01672         file->size              = (info.size + 1)>>1;
01673         file->flushedSize       = file->size;               
01674 
01675         file->dirEntphySec      = info.phySec;
01676         file->dirEntwordOffset  = info.wordOffset;
01677                 
01678         clus                    = info.startClus;
01679         file->startClus         = clus;
01680         FAT__fseek(file, 0, SEEK_TAIL);
01681 
01682         clus                = file->curClus;
01683         file->startUpdtClus = clus;
01684         file->centClus      = clus;
01685     }
01686 
01687     else 
01688     {
01689         file = NULL;
01690     }
01691 
01692     if( (file)&&((wb==eMode)||(ab==eMode)||(r_b==eMode)) )
01693     {
01694         pDisk->wrFileNum++;
01695     }
01696     
01697     if(NULL == file)
01698     {
01699         FAT__releaseHdlID(fcpy);
01700     }
01701     return file;    
01702 }

Here is the call graph for this function:

unsigned long FAT__calcPhySecOfClus unsigned long  clus,
st_FATDISK pDisk
 

Function returns starting physical sector of given cluster.

Parameters:
clus cluster number.
pDisk Disk structure pointer.
Returns:
Starting physical sector number.

Definition at line 748 of file fat.c.

References st_FATDISK::brPhySec, st_FATDISK::dataStartSec, and st_FATDISK::secPerClus.

Referenced by FAT__bfopen(), FAT__createFile(), FAT__delete(), FAT__format(), FAT__fseek(), FAT__getFrstDirEnt(), FAT__getNxtDirEnt(), FAT_copyDir(), FAT_fread(), and FAT_fwrite().

00750 {   
00751     unsigned long sec;
00752 
00753     FAT_assert( clus <= pDisk->maxClus, FAT__CALCPHYSECOFCLUS );
00754     
00755     sec = (unsigned long)(clus - 2)*pDisk->secPerClus + 
00756             pDisk->dataStartSec + pDisk->brPhySec;
00757     
00758     return sec;
00759 }

BOOL FAT__cd const char *  pName,
st_CURWORKDIR pDir
 

Function changes directory to specified path.

Parameters:
pName Path name, search for '/' or NULL terminator.
pDir working directory.
Returns:
TRUE if directory successfully changed, otherwise FALSE.

Definition at line 5280 of file fat.c.

References DISK_C, DISK_D, FAT__cdRoot(), FAT__findFirst(), FAT__pathAppend(), FAT__pathTruncate(), FAT__strcmp(), and st_FATFILEINFO::startClus.

Referenced by FAT__chg2PathDir(), FAT_cd(), and FAT_copyDir().

05281 {
05282     long            handle;
05283     st_FATFILEINFO  info;
05284     
05285     // Is this root?
05286     if( '/' == *pName )
05287     {
05288         if      (pDir->pDisk == &DiskD) return FAT__cdRoot(DISK_D, pDir);
05289         else if (pDir->pDisk == &DiskC) return FAT__cdRoot(DISK_C, pDir);
05290         else                            return FALSE;
05291     }
05292     
05293     // Is this root?
05294     if( (':' == *(pName+1))&& ('/' == *(pName+2)) )
05295     {
05296         if      (('D' == *pName)||('d' == *pName))  return FAT__cdRoot(DISK_D, pDir);
05297         else if (('C' == *pName)||('c' == *pName))  return FAT__cdRoot(DISK_C, pDir);
05298         else                                        return FALSE;
05299     }
05300     
05301 
05302     if(FAT__strcmp(pName, ".") == 0 )                                   return TRUE;
05303     if( (FAT__strcmp(pName, "..") == 0) && (pDir->bIsRoot == TRUE) )    return TRUE;
05304 
05305     handle = FAT__findFirst(pName, &info, pDir);
05306     if(handle == -1 ) return FALSE;
05307     FAT_findClose(handle);
05308 
05309     // update the data cluster number of the current working directory
05310     pDir->startClus = info.startClus;   
05311     
05312     // It is root directory when startClus turns to 0 here.
05313     if( pDir->startClus == 0 )  pDir->bIsRoot = TRUE;
05314     else                        pDir->bIsRoot = FALSE;
05315         
05316 #ifdef _RECORD_CURWORKDIR_PATH
05317     if ( FAT__strcmp((const char *)pName, "..") == 0 ) FAT__pathTruncate(pDir->path);
05318     else FAT__pathAppend(pDir->path, (const char *)pName);
05319 #endif
05320     
05321     return TRUE;
05322 }

Here is the call graph for this function:

BOOL FAT__chg2PathDir const char *  pName,
char **  pNext,
st_CURWORKDIR pDir
 

Function changes directory to directory part of a given path ignoring the last part, no matter it is a directory or file.

For example, function will do the same thing on "dir1/dir2/file" and "dir1/dir2/dir".

Parameters:
pName Path name.
pNext last part path start.
pDir working directory.
Returns:
TRUE if directory successfully changed and pNext points to a valid path, otherwise FALSE.

Definition at line 5233 of file fat.c.

References FAT__cd(), and FAT_MAXLFN.

Referenced by FAT__bfopen(), FAT__mkdir(), FAT_attr(), FAT_cd(), FAT_copyDir(), FAT_delete(), FAT_frevive(), and FAT_rmdir().

05234 {
05235     unsigned short  usNum = 1;
05236     char *          pC = (char *)pName;
05237     unsigned short  ii = 0;
05238     
05239     if ( *pC == 0 ) return FALSE;
05240 
05241     while( (*pC != 0) && (ii < FAT_MAXLFN ) )
05242     {       
05243         if(*pC++ == '/') usNum++;
05244         ii++;
05245     }
05246 
05247     if( FAT_MAXLFN <= ii)   return FALSE;
05248     
05249     pC--;
05250     if( '/' == *pC ) usNum--;
05251     
05252     if( 1 == usNum )
05253     {
05254         *pNext = (char *)pName;
05255         return TRUE;
05256     }
05257 
05258     pC = (char *)pName; 
05259     while( --usNum )
05260     {
05261         if( FALSE == FAT__cd(pC, pDir)) return FALSE;
05262         while( '/' != *pC++ );
05263     }
05264     
05265     *pNext = pC;
05266     return TRUE;
05267 }

Here is the call graph for this function:

unsigned long FAT__clusEntry unsigned long  Clus,
st_FATDISK pDisk
 

Function returns FAT cluster entry of specified cluster.

Parameters:
Clus cluster number.
pDisk undocumented.
Returns:
FAT cluster entry.

Definition at line 5114 of file fat.c.

References FAT__readFatWord(), FAT__readWord(), and SYS_die().

Referenced by FAT__delete(), FAT__findNxtAvlblClus(), FAT__findNxtOcupdClus(), FAT__fseek(), FAT__getNxtDirEnt(), FAT__updateSecondCopyOfFAT(), FAT_fread(), FAT_frevive(), and FAT_fwrite().

05115 {
05116     unsigned long   entry;
05117     unsigned long   sector;
05118 #ifndef _FAT_REMOVE_FAT12_SUPPORT
05119     unsigned long   jj, kk = 0;
05120 #endif
05121     unsigned short  offset;
05122     unsigned short  usTmp;
05123 
05124     switch(pDisk->fileSysType)
05125     {
05126 
05127 #ifndef _FAT_REMOVE_FAT12_SUPPORT
05128         case FAT_12:
05129 
05130             jj = Clus + (Clus/2);   // bytes 
05131 
05132             sector = pDisk->brPhySec + pDisk->rsvdSecCnt + 
05133                 (jj/(pDisk->wordsPerLogSec<<1));
05134             
05135             // word offset within the sector 
05136             offset = (unsigned short)((jj>>1)%pDisk->wordsPerLogSec); 
05137             jj = FAT__readWord(sector, offset, FALSE, pDisk);
05138 
05139             // To see if cross-sector happens. 
05140             if(offset == (pDisk->wordsPerLogSec-1) )
05141             {
05142                 kk = FAT__readWord(sector+1, 0, FALSE, pDisk);
05143             }
05144             else
05145             {
05146                 kk = FAT__readWord(sector, 
05147                         (unsigned short)(offset+1), FALSE, pDisk);
05148             }
05149 
05150             switch(Clus % 4)
05151             {
05152                 case 0:
05153                         entry = jj >> 4;
05154 
05155                         break;
05156                 case 1:
05157                         entry = ((jj&0xF)<<8) | (kk>>8);
05158 
05159                         break;
05160                 case 2:
05161                         entry = ((jj&0xFF)<<4 ) | (kk >> 12);
05162 
05163                         break;
05164                 case 3:
05165                         entry = jj & 0xFFF;
05166 
05167                         break;                  
05168             }
05169             break;
05170 #endif // end of _FAT_REMOVE_FAT12_SUPPORT. 
05171 
05172         case FAT_16:
05173 
05174             // For FAT16, there are (Clus) words (or 2*Clus bytes) in the FAT 
05175             //sector = pDisk->brPhySec + pDisk->rsvdSecCnt + 
05176             //  (Clus/pDisk->wordsPerLogSec);
05177             //offset = (unsigned short)(Clus%pDisk->wordsPerLogSec); 
05178             sector = pDisk->brPhySec + pDisk->rsvdSecCnt + (Clus >> 8);
05179             offset = (unsigned short)(Clus&0x00ff); 
05180 
05181             // The AND mask here is for safe to work around CCS bug.
05182             FAT__readFatWord(sector, offset, &usTmp, 1, TRUE, pDisk);
05183             entry = (unsigned long)usTmp;
05184 
05185             break;
05186 
05187         case FAT_32:
05188 
05189             // For FAT32, there are (2*Clus) words (or 4*Clus bytes) in the FAT
05190             //sector = pDisk->brPhySec + pDisk->rsvdSecCnt + 
05191             //  (long)(2*Clus/pDisk->wordsPerLogSec);
05192             //offset = (unsigned short)((unsigned long)(2*Clus)%pDisk->wordsPerLogSec); 
05193 
05194             sector = pDisk->brPhySec + pDisk->rsvdSecCnt + (Clus>>7);
05195             offset = (unsigned short)((unsigned long)(Clus<<1)&0x00ff); 
05196 
05197             // read 1st 2-byte of the 32-bit entry
05198             FAT__readFatWord(sector, offset, (unsigned short *)&entry, 2, TRUE, pDisk );
05199             entry = ((entry>>16)&0x0ffff)|((entry<<16)&0x0ffff0000);
05200             break;
05201 
05202         default: 
05203             if(pDisk == &DiskC)
05204             {
05205                 SYS_die(FAT__CLUSENTRY_HDD);
05206             }
05207             else
05208             {
05209                 SYS_die(FAT__CLUSENTRY);
05210             }
05211 
05212     }
05213  
05214     return entry;
05215 }

Here is the call graph for this function:

BOOL FAT__createFile const char *  pName,
unsigned short  attr,
unsigned long *  pPhySec,
unsigned short *  pWordOffset,
st_CURWORKDIR pDir
 

Function creates directory/file under current working directory.

pName should NOT contain any invalid file name characters, pName should NOT contain any trailing/prefixing spaces either.

Parameters:
pName Dir/file name to be created.
attr Dir/file attribute.
pPhySec Short name dir/file entry physical sector pointer.
pWordOffset Short name dir/file entry word offset.
pDir Current workding directory.
Returns:
TRUE if dir/file successfully created, otherwise FALSE.

Definition at line 4437 of file fat.c.

References st_FATDIRSEARCH::curClus, st_FATDIRSEARCH::curEnt, st_FATDIRENT::ent, ENT_TYPE, st_FATDISK::EOC, st_FATDIRENT::ext, FAT__calcPhySecOfClus(), FAT__findNxtAvlblClus(), FAT__flush(), FAT__getFrstDirEnt(), FAT__getNxtDirEnt(), FAT__updateFAT(), st_FATDISK::fileSysType, st_FATDIRENT::lname, st_FATDISK::newStartSrchClus, st_FATDIRSEARCH::phySec, st_FATDIRSEARCH::secOffset, st_FATDISK::secPerClus, st_FATDIRENT::sname, SYS_die(), and st_FATDIRSEARCH::wordOffset.

Referenced by FAT__bfopen(), and FAT__mkdir().

04442 {
04443     unsigned short      ii;
04444     char                sname[9];
04445     char                ext[4];
04446     unsigned short *    pEnt;
04447     unsigned long       clus = 0L;
04448     unsigned long       nextAvlblClus;
04449     st_FATDISK *        pDisk = pDir->pDisk;
04450     BOOL                isDir;
04451     BOOL                bLFN;
04452     char *              pC;
04453     unsigned short      numEnt;
04454     ENT_TYPE            entry;
04455     st_FATDIRENT        ent;
04456     st_FATDIRSEARCH     ctl;
04457     st_FATDIRSEARCH     startCtl;
04458     BOOL                bStarted; // To work with dir ent search.   
04459     BOOL                ret = TRUE;
04460     
04461     bLFN = _createSname(sname, ext, pName);
04462     _check2tailSname(sname, ext, pDir);
04463     
04464     // Calculate LFN numbers.
04465     pC = (char *)pName;
04466     while((*pC != 0)&&(*pC != '/')) pC++;
04467     
04468     // Num of LFN entries plus sname entry.
04469     // NULL is part of LFN!!!
04470     // But, when LFN is exactly a multiple of 13, no NULL or padded FFFF is needed.
04471     numEnt = 1;
04472     if(bLFN == TRUE)
04473     {
04474         ii = pC-pName;
04475         while(1)
04476         {
04477             numEnt++;
04478             if(ii <= 13) break;
04479             ii -= 13;
04480         }
04481     }
04482     
04483     isDir = (attr & FAT_ATTR_DIR)? TRUE:FALSE;
04484 
04485     if(isDir == TRUE)
04486     {
04487         // If creating dir, try to allocate a cluster first.
04488         // while creating a file, we hold to the caller to allocate this.
04489         if( FAT__findNxtAvlblClus(&clus, 1, pDisk) == 0)
04490         {
04491             // No cluster available, unable to create directory.
04492             return FALSE;
04493         }
04494             
04495         // update the starting search point 
04496         // make the startSrchClus point to the end of the reserved cluster
04497         //pDisk->startSrchClus = clus;
04498         //pDisk->newStartSrchClus = clus + 1;
04499     }
04500     
04501     if( ((pDisk->fileSysType != FAT_32) && (pDir->bIsRoot == FALSE)) ||
04502         (pDisk->fileSysType == FAT_32) ) 
04503     {
04504         // If (FAT12/16 & Not root) OR FAT32, attempt to pre-allocate a cluster,
04505         // in case cross cluster happens while updating dir entries. 
04506 
04507         // No error handling here since NO-CLUSTER does not mean 
04508         // error if cross-cluster does not happen. 
04509         FAT__findNxtAvlblClus(&nextAvlblClus, 1, pDisk);
04510 
04511         // Rare case, FAT rewind.
04512         //if(nextAvlblClus == clus) nextAvlblClus = 0;
04513         // should never happen.
04514         if(nextAvlblClus == clus) SYS_die(FAT__CREATEFILE);
04515             
04516         // update the starting search point, do not plus 1 since this cluster may
04517         // not be used.
04518         //else pDisk->startSrchClus = nextAvlblClus+1;
04519         if(nextAvlblClus) pDisk->newStartSrchClus = nextAvlblClus;
04520         
04521     }
04522     
04523     pEnt = (unsigned short *)malloc(16 * numEnt * sizeof(unsigned short));
04524     if(pEnt == NULL) SYS_die(FAT__CREATEFILE2);
04525 
04526     if(bLFN == TRUE)
04527         _genrtDirEnt(clus, sname, ext, pName, attr, pEnt);
04528     else
04529         _genrtDirEnt(clus, sname, ext, NULL, attr, pEnt);
04530 
04531     
04532     // Try to locate numEnt of dir entries, make sure we have enough 
04533     // DELETED entries if there is any. If reach the end of dir entry, we'll
04534     // leave and let __createDirEnt funtion to check if there are enough free
04535     // entries available.
04536     // Also be careful that FAT12/16 can only support limited number of entries.
04537     ent.sname   = (char *)ent.lname;
04538     ent.ext     = (char *)ent.lname+9;
04539     
04540     FAT__getFrstDirEnt(&ctl, &ent, pDir);   
04541     entry = ent.ent;
04542 
04543     ii = 0;
04544     bStarted = FALSE;
04545     while(entry != ENT_FREE)
04546     {
04547         if( entry == ENT_DEL )
04548         {
04549             if(bStarted == FALSE)
04550             {
04551                 startCtl = ctl;
04552                 bStarted = TRUE;
04553             }
04554             
04555             if(++ii == numEnt) 
04556             {
04557                 ctl = startCtl;                             
04558                 break;
04559             }
04560         }
04561         else
04562         {
04563             bStarted = FALSE;
04564             ii = 0;
04565         }
04566 
04567         if(FAT__getNxtDirEnt(&ctl, &ent) == FALSE)
04568         {
04569             // Reached the end of dir entries.
04570             if( (nextAvlblClus == 0)||( (pDir->bIsRoot==TRUE)&&(pDisk->fileSysType != FAT_32) ) )
04571             {
04572                 //certainly ERROR! no cluster left or root is full.
04573                 ret = FALSE;    
04574                 break;
04575             }
04576             else
04577             {
04578                 // Update the FAT table here.
04579                 FAT__updateFAT(ctl.curClus, nextAvlblClus, 1, pDisk);
04580                 FAT__updateFAT(nextAvlblClus, pDisk->EOC, 1, pDisk);
04581 
04582                 // Only update this varialb here if pre-allocated cluster is used.
04583                 pDisk->newStartSrchClus = nextAvlblClus + 1;
04584                 
04585                 ctl.curClus = nextAvlblClus;
04586                 ctl.curEnt++;
04587 
04588                 ctl.phySec = FAT__calcPhySecOfClus(nextAvlblClus, pDisk);
04589 
04590                 // Zero out the directory entries.
04591                 _clearSec(ctl.phySec, 0, pDisk->secPerClus, pDisk );
04592     
04593                 ctl.secOffset = 0;
04594                 ctl.wordOffset = 0;
04595                 break;
04596             }
04597         }
04598         entry = ent.ent;
04599     }
04600 
04601     // Create dir/file entry. 
04602     if(ret == TRUE)
04603     {
04604         ret = _createDirEnt(&ctl, pEnt, numEnt, nextAvlblClus);
04605         
04606         // record to return short name entry position.
04607         if(pPhySec)     *pPhySec        = ctl.phySec;
04608         if(pWordOffset) *pWordOffset    = ctl.wordOffset;
04609     }
04610     
04611     free(pEnt);
04612 
04613     if(ret == FALSE) return FALSE;
04614 
04615     // Create '.', '..' entry.
04616     if(isDir == TRUE)
04617     {
04618         if(_createDotEnt(clus, sname, ext, pEnt, pDir) == FALSE)    return FALSE;
04619 
04620         // Write FAT entry of dir cluster. 
04621         FAT__updateFAT(clus, pDisk->EOC, 1, pDisk);
04622     }   
04623 
04624     // Flush disk after creation to make sure all write happens.
04625     return ( FAT__flush(pDisk) );
04626 }

Here is the call graph for this function:

BOOL FAT__delete st_FATFILEINFO pInfo,
st_CURWORKDIR pOwnerDir
 

Function deletes specified file/dir under the given directory.

If a directory is chosen to be deleted, it is the caller's responsiblity to make sure that the directory is empty.

Parameters:
pInfo Pointer to FAT information.
pOwnerDir Dir/file's Owner working directory.
Returns:
TRUE if entry is successfully deleted, otherwise FALSE.

Definition at line 4349 of file fat.c.

References FAT__calcPhySecOfClus(), FAT__clusEntry(), FAT__readWord(), FAT__releaseClus(), FAT__writeWord(), st_FATDIRENT::numLFN, and st_FATDISK::secPerClus.

Referenced by FAT_delete().

04350 {
04351 #if 0
04352     unsigned long   entry;
04353     short           ii,jj;
04354     unsigned long   entbuf[256];
04355     unsigned long * pL;
04356 #endif
04357     unsigned long   clus;
04358     unsigned long   sec;
04359     unsigned long   secOffset;
04360     unsigned short  wordOffset;
04361     unsigned short  word;
04362     unsigned short  numLFN;
04363     st_FATDISK *    pDisk = pOwnerDir->pDisk;
04364     
04365     numLFN = pInfo->numLFN;
04366     clus = pInfo->fstLFNclus;
04367     sec = pInfo->fstLFNphySec;
04368     secOffset = pInfo->fstLFNsecOffset;
04369     wordOffset = pInfo->fstLFNwordOffset;
04370             
04371     while(1)
04372     {
04373         // Delete LFN/sname entries.
04374         FAT__readWord(sec, wordOffset, &word, 1, FALSE, pDisk);
04375         word &= 0x00FF;
04376         word |= 0xE500;
04377         
04378         FAT__writeWord(sec, wordOffset, &word, 1, pDisk);
04379 
04380         if(numLFN)
04381         {
04382             numLFN--;
04383 
04384             wordOffset += 16;
04385             if(wordOffset >= 256)
04386             {
04387                 // Cross sector. 
04388                 wordOffset -= 256;      
04389                 sec++;
04390                 secOffset++;
04391                 if(secOffset >= pDisk->secPerClus)
04392                 {
04393                     // Cross cluster.
04394                     secOffset = 0;
04395                     
04396                     if( (pOwnerDir->bIsRoot != TRUE)||(pOwnerDir->pDisk->fileSysType == FAT_32) )
04397                     {
04398                         // Only look up FAT if owner is NOT root or it is FAT-32.
04399                         clus = FAT__clusEntry(clus, pDisk);
04400                         sec =  FAT__calcPhySecOfClus(clus, pDisk);
04401                     }
04402                 }
04403             }
04404         }
04405         else    break;
04406 
04407     }
04408 
04409     // No cluster associated with '.' and '..' entry.
04410     if( (strcmp((const char *)pInfo->lname, strDOT) == 0) || 
04411         (strcmp((const char *)pInfo->lname, strDOTDOT) == 0) ) return TRUE;
04412 
04413     // Release FAT table.
04414     return FAT__releaseClus(pInfo->startClus, pDisk);
04415 
04416 }

Here is the call graph for this function:

BOOL FAT__fflush File file  ) 
 

Function flushes specified file.

Parameters:
file File to be flushed.
Returns:
TRUE if file successfully flushed, otherwise FALSE.

Definition at line 4306 of file fat.c.

References st_FATDISK::EOC, FAT__updateCopyOfFAT(), and st_FATDIRENT::size.

Referenced by FAT_fclose(), FAT_fread(), and FAT_fseek().

04307 {
04308     unsigned long   ulTmp1, ulTmp2;
04309     st_FATDISK *    pDisk = file->pDisk;
04310     
04311     if(file->flushedSize < file->ptr)
04312     {
04313         // Update FAT table.
04314         if(file->flag & FILE_FLUSH_BROKNCLUS_PENDING)
04315         {
04316             file->flag &= ~FILE_FLUSH_BROKNCLUS_PENDING;
04317             FAT__updateCopyOfFAT(file->nxtPreBroknClus, file->preBroknClus, 1, 0, pDisk);
04318         }
04319             
04320         ulTmp1 = file->preBroknClus;
04321         ulTmp2 = file->curClus;
04322         
04323         FAT__updateCopyOfFAT( ulTmp1, ulTmp1+1,(unsigned short)(ulTmp2-ulTmp1), 0, pDisk);
04324         FAT__updateCopyOfFAT( ulTmp2, pDisk->EOC, 1, 0, pDisk);
04325 
04326         file->nxtBroknClus = ulTmp2;
04327         file->preBroknClus = ulTmp2;
04328         file->flushedSize = file->size;
04329     }
04330 
04331     file->flag &= ~FILE_FAT_FLUSH_PENDING;
04332     
04333     return TRUE;
04334 }

Here is the call graph for this function:

void FAT__findClose long  handle  ) 
 

Function releases find cotrol objects.

Parameters:
handle FAT find object handle.

Definition at line 1924 of file fat.c.

References st_FATFIND::_pCtl.

Referenced by FAT__findFirst(), FAT_copyDir(), and FAT_delete().

01925 {
01926     FATfindObj[handle]._pCtl = NULL;
01927 }

long FAT__findFirst const char *  pName,
st_FATFILEINFO pInfo,
st_CURWORKDIR pDir
 

Function finds the first valid dir/file under given directory.

Parameters:
pName name of dir/file to be found, if NULL, find all.
pInfo dir/file info buffer.
pDir working directory.
Returns:
find handle that can be used by findnext(...), -1 otherwise.

Definition at line 4223 of file fat.c.

References st_FATFIND::_pCtl, st_FATFIND::_pEnt, st_FATDIRENT::ent, ENT_TYPE, st_FATDIRENT::ext, FAT__findClose(), FAT__getFinfo(), FAT__getFrstDirEnt(), FAT__getNxtDirEnt(), FAT__strcmp(), st_FATDIRENT::lname, st_FATDIRENT::sname, and SYS_die().

Referenced by FAT__bfopen(), FAT__cd(), FAT__mkdir(), FAT_attr(), FAT_copyDir(), FAT_delete(), FAT_findFirst(), and FAT_frevive().

04224 {
04225     long                handle = 0;
04226     st_FATDIRSEARCH *   pCtl;
04227     st_FATDIRENT    *   pEnt;
04228     ENT_TYPE            ent;
04229     
04230     while(handle < MAX_CONCURRENT_FIND)
04231     {
04232         if( FATfindObj[handle]._pCtl == NULL) break;        
04233         handle++;
04234     }
04235     if(handle >= MAX_CONCURRENT_FIND) SYS_die(FAT__FINDFIRST);
04236     
04237     pCtl =
04238     FATfindObj[handle]._pCtl = &FATcontrolObj[handle];
04239     pEnt =
04240     FATfindObj[handle]._pEnt = &FATentryObj[handle];
04241     
04242     pEnt->sname = (char *)pEnt->lname;
04243     pEnt->ext   = (char *)pEnt->lname+9;
04244     
04245     FAT__getFrstDirEnt( pCtl, pEnt, pDir );
04246                     
04247     // By now, first valid entry found. 
04248     if(pName == NULL)
04249     {
04250         // Act as wildcard '*.*', return whatever was found.            
04251         // Search till the valid file info found.
04252         while(1)
04253         {
04254             ent = pEnt->ent;
04255             if(ent == ENT_FREE) break;
04256 
04257             if( (ent == ENT_DIR)||(ent == ENT_FILE)||(ent== ENT_LFN) )
04258             {
04259                 FAT__getFinfo(pInfo, pCtl, pEnt);
04260                 ent = pEnt->ent;    
04261                 
04262                 if( (ent == ENT_FILE)||(ent == ENT_DIR) ) return handle;
04263             }
04264 
04265             //  Locate next entry. 
04266             if(FAT__getNxtDirEnt(pCtl, pEnt) == FALSE ) break;
04267         }
04268     }
04269 
04270     else
04271     {
04272         // Search till the valid file info found.
04273         while(1)
04274         {
04275             ent = pEnt->ent;
04276             if(ent == ENT_FREE) break;
04277 
04278             if( (ent == ENT_DIR)||(ent == ENT_FILE)||(ent== ENT_LFN) )
04279             {
04280                 FAT__getFinfo(pInfo, pCtl, pEnt);
04281                 ent = pEnt->ent;    
04282                 
04283                 if( (ent == ENT_FILE)||(ent == ENT_DIR) ) 
04284                 {
04285                     if(FAT__strcmp(pName, (const char*)pInfo->lname) == 0) return handle;
04286                 }
04287             }
04288 
04289             //  Locate next entry. 
04290             if(FAT__getNxtDirEnt(pCtl, pEnt) == FALSE ) break;
04291         }
04292     }
04293 
04294     FAT__findClose(handle); 
04295     return -1L;
04296 }

Here is the call graph for this function:

BOOL FAT__findNext long  handle,
st_FATFILEINFO pInfo
 

Function finds next available directory or file under current workding directory.

Parameters:
handle FAT find handle.
pInfo Dir/file info buffer.
Returns:
TRUE if dir/file found, otherwise FALSE.

Definition at line 1864 of file fat.c.

References st_FATFIND::_pCtl, st_FATFIND::_pEnt, st_FATDIRENT::ent, ENT_TYPE, FAT__getFinfo(), and FAT__getNxtDirEnt().

Referenced by FAT_copyDir().

01865 {
01866     st_FATDIRSEARCH *   pCtl = FATfindObj[handle]._pCtl;
01867     st_FATDIRENT *      pEnt = FATfindObj[handle]._pEnt;
01868     ENT_TYPE            ent;
01869     
01870     if(handle < 0) return FALSE;
01871 
01872     while(1)
01873     {
01874         //  Locate next entry. 
01875         if(FAT__getNxtDirEnt(pCtl, pEnt) == FALSE ) break;
01876         
01877         ent = pEnt->ent;
01878         if(ent == ENT_FREE) break;
01879 
01880         if( (ent == ENT_DIR)||(ent == ENT_FILE)||(ent== ENT_LFN) )
01881         {
01882             FAT__getFinfo(pInfo, pCtl, pEnt);
01883             ent = pEnt->ent;    
01884                 
01885             if( (ent == ENT_FILE)||(ent == ENT_DIR) ) return TRUE;
01886         }       
01887     }
01888     
01889     return FALSE;   
01890 }

Here is the call graph for this function:

unsigned short FAT__findNxtAvlblClus unsigned long *  pClus,
unsigned short  count,
st_FATDISK pDisk
 

Function finds next available clusters.

Parameters:
pClus the beginning cluster of free consecutive clusters that have been found.
count the max number of free consecutive cluster to be found.
pDisk pointer to FAT/disk structure? (undocumented).
Returns:
how many free consecutive clusters have found.

Definition at line 4152 of file fat.c.

References FAT__clusEntry(), st_FATDISK::flag, st_FATDISK::maxClus, st_FATDISK::newStartSrchClus, and st_FATDISK::oldStartSrchClus.

Referenced by FAT__bfopen(), FAT__createFile(), and FAT_fwrite().

04155 {
04156     unsigned short  usNum = 0;
04157     BOOL            bStartSet = FALSE;
04158     unsigned long   startClus = pDisk->newStartSrchClus; 
04159     unsigned long   endClus;
04160 
04161     *pClus = 0;
04162 
04163     // if haven't rollover yet, find until last cluster (maxClus)
04164     // if already rollover, find until pStart.
04165     if ( pDisk->flag & DISK_CLUS_SEARCH_ROLLOVER )
04166         endClus = pDisk->oldStartSrchClus;
04167     else
04168         endClus = pDisk->maxClus;
04169         
04170 
04171     while(usNum < count)
04172     {   
04173         if(startClus >= endClus)
04174         {
04175             // has searched to the end, still no free entry found
04176             if( (bStartSet == FALSE) && (!(pDisk->flag & DISK_CLUS_SEARCH_ROLLOVER))     )
04177             {
04178                 startClus               = FAT_FIRSTCLUS;
04179                 endClus                 = pDisk->oldStartSrchClus;
04180                 pDisk->flag            |= DISK_CLUS_SEARCH_ROLLOVER;
04181             }
04182             else break; // no free ones or at least one found already.
04183         }
04184 
04185         if(FAT__clusEntry(startClus, pDisk) == 0)
04186         {
04187             // cluster FAT entry = 0, the cluster is free
04188             if(bStartSet == FALSE) 
04189             {
04190                 *pClus = startClus;
04191                 bStartSet = TRUE;
04192             }
04193 
04194             startClus++;
04195             usNum++;    // count the number of free entry found
04196         }
04197         else if(bStartSet == FALSE)
04198         {
04199             // keep searching the next free entry in FAT
04200             startClus++;
04201         }
04202         else break; // Cluster broken, return.
04203     }
04204 
04205     pDisk->newStartSrchClus = startClus;
04206     
04207     return usNum;
04208 }

Here is the call graph for this function:

unsigned short FAT__findNxtOcupdClus unsigned long  startClus,
st_FATDISK pDisk
 

Function finds next occupied clusters from FAT.

Parameters:
startClus the beginning of cluster to start searching consecutive occupied cluster.
pDisk Active disk data pointer.
Returns:
The occupied clusters that have been found, excluding the startClus.

Definition at line 4114 of file fat.c.

References st_FATDISK::EOC, FAT__clusEntry(), and st_FATDISK::maxFndClus.

Referenced by FAT__bfopen(), FAT__fseek(), FAT_copyDir(), FAT_fread(), and FAT_fwrite().

04115 {
04116     unsigned short  usNum = 0;
04117     unsigned short  maxFndClus  = pDisk->maxFndClus;
04118     unsigned long   EOC         = pDisk->EOC;
04119     unsigned long   clus;
04120 
04121     while(1)
04122     {
04123         clus = FAT__clusEntry(startClus, pDisk);
04124         if( (clus == 0)||(clus>=EOC) ) break;
04125 
04126         startClus++;
04127         if(clus == startClus) 
04128         {
04129             usNum++;
04130             if(usNum >= maxFndClus)     break;
04131         }
04132         else break;
04133     }
04134 
04135     return usNum;
04136 }

Here is the call graph for this function:

BOOL FAT__flush st_FATDISK pDisk  ) 
 

Function flushes the specified disk.

Parameters:
pDisk Disk structure pointer.
Returns:
TRUE if successfully flushed, otherwise FALSE.

update freeClusNum to Fat table *

Definition at line 4046 of file fat.c.

References FAT__writeWord(), st_FATDISK::flag, st_FATDISK::freeClusNum, st_FATDISK::fsInfoSec, st_FATDISK::newStartSrchClus, st_FATDISK::oldFreeClusNum, and st_FATDISK::writeSec.

Referenced by FAT__bfopen(), FAT__createFile(), FAT__unmountDisk(), FAT_attr(), FAT_delete(), FAT_fclose(), FAT_flushDisk(), FAT_frevive(), and FAT_rmdir().

04047 {
04048     unsigned short  usTmp;
04049     unsigned long   sec, ulTmp;
04050     BOOL            ret = TRUE;
04051 
04052     if ( (FAT_32 == pDisk->fileSysType)&&(pDisk->oldFreeClusNum != pDisk->freeClusNum) )
04053     {
04054         sec = pDisk->fsInfoSec;
04055         
04057         ulTmp = pDisk->freeClusNum;
04058         usTmp = (unsigned short)(((ulTmp & 0x000000FF)<<8)|
04059                                 ((ulTmp>>8) & 0x000000FF));
04060                                 
04061         FAT__writeWord( sec, 488>>1, &usTmp, 1, pDisk);
04062 
04063         usTmp = (unsigned short)(((ulTmp>>8)&0x0000FF00)|
04064                                 ((ulTmp>>24) & 0x000000FF));
04065                                 
04066         FAT__writeWord( sec, 490>>1, &usTmp, 1, pDisk);
04067 
04068                                    
04069         /* FSI_Nxt_Free */
04070         ulTmp = pDisk->newStartSrchClus;
04071         usTmp = (unsigned short)(((ulTmp & 0x000000FF)<<8)|
04072                                 ((ulTmp>>8) & 0x000000FF));
04073                                 
04074         FAT__writeWord( sec, 492>>1, &usTmp, 1, pDisk);
04075 
04076         usTmp = (unsigned short)(((ulTmp>> 8) & 0x0000FF00) |
04077                                 ((ulTmp>>24) & 0x000000FF));
04078                                 
04079         FAT__writeWord( sec, 494>>1, &usTmp, 1, pDisk);
04080         
04081         pDisk->oldFreeClusNum = pDisk->freeClusNum;
04082     }
04083         
04084     if( pDisk->flag & DISK_FATWRITE_PENDING )
04085     {
04086             ret = pDisk->writeSec(  pDisk->curActvFatPhySec, 
04087                                         pDisk->fatSecBuf, 
04088                                         FALSE);
04089             pDisk->flag &= ~DISK_FATWRITE_PENDING;
04090     }
04091 
04092     if( (pDisk->flag&DISK_WRITE_PENDING) && (ret == TRUE) )
04093     {
04094             ret = pDisk->writeSec(  pDisk->curActvPhySec, 
04095                                         pDisk->secBuf, 
04096                                         FALSE);
04097             pDisk->flag &= ~DISK_WRITE_PENDING;
04098     }
04099 
04100     return ret;
04101 }

Here is the call graph for this function:

File* FAT__fopen const char *  pName,
FOPEN_MODE  eMode,
st_CURWORKDIR pDir
 

Function opens the file specified by pName in a mode specified by eMode under given working directory.

Functoin will NOT change the current working directory. Function will NOT open or create any directory. pName is NOT case sensitive.

Parameters:
pName file name.
eMode file open mode.
pDir working directory.
Returns:
file pointer if successfully opened, other wise NULL.

Definition at line 1495 of file fat.c.

References FAT__bfopen(), and File::flag.

Referenced by FAT_bfopen(), FAT_copyDir(), and FAT_fopen().

01496 {
01497     File  *                 file;
01498 
01499     file = (File *)malloc(sizeof(File));
01500     if(file)
01501     {
01502         if(NULL == FAT__bfopen(pName, eMode, file, pDir))
01503         {
01504             free(file);
01505             file = NULL;
01506         }
01507         else file->flag = FILE_OBJ_ALLOCATED;
01508     }
01509     
01510     return file;    
01511 }

Here is the call graph for this function:

unsigned long FAT__freeClusNum DISK_ID  disk  ) 
 

Function returns the free cluster number of the specified disk.

Parameters:
disk Disk ID.
Returns:
Free cluster number.

Definition at line 3863 of file fat.c.

References st_FATDISK::brPhySec, st_FATDISK::curActvPhySec, DISK_C, DiskC, FAT__readWord(), st_FATDISK::FATsz16_32, st_FATDISK::fileSysType, st_FATDISK::fsInfoSec, st_FATDISK::maxClus, st_FATDISK::readSec, st_FATDISK::rsvdSecCnt, st_FATDISK::secBuf, SYS_die(), and st_FATDISK::wordsPerLogSec.

Referenced by FAT_freeSpace().

03864 {
03865     unsigned short      ii, usTmp;
03866     unsigned short  *   pBuf, * pBufStart;
03867 
03868     unsigned long       fatStartPhySec, fatEndPhySec;
03869     unsigned long       fatCurrentPhySec;
03870     unsigned long       usedClusCnt = 0;
03871     st_FATDISK *        pDisk;
03872     unsigned long       frClus;
03873     
03874 #ifndef _FAT_REMOVE_FAT12_SUPPORT
03875     unsigned long       jj, kk, entry, savedLastWord, sector;
03876     unsigned short      offset;
03877     unsigned long       Clus = 2;
03878     BOOL                bFourBitsSaved = FALSE;
03879 #endif
03880     
03881     pDisk = (DISK_C == disk)? &DiskC : &DiskD;
03882     
03883     if ( FAT_32 == pDisk->fileSysType )
03884     {       
03885         // lookup FSInfo Sector to get disk free space
03886         FAT__readWord( pDisk->fsInfoSec, 488>>1, &usTmp, 1, TRUE, pDisk);
03887         frClus = (unsigned long)usTmp;
03888         FAT__readWord( pDisk->fsInfoSec, 490>>1, &usTmp, 1, TRUE, pDisk);
03889         frClus |= (unsigned long)usTmp << 16;
03890         
03891         if ( frClus < pDisk->maxClus ) 
03892         {
03893             // if it larger than maxClus, then it has to go thru whole fat table.
03894             return frClus;
03895         }
03896     }
03897 
03898     // Start sector number of FAT itself
03899     fatStartPhySec = pDisk->brPhySec + pDisk->rsvdSecCnt;   
03900     fatEndPhySec = fatStartPhySec + (pDisk->FATsz16_32) - 1;
03901 
03902     fatCurrentPhySec = fatStartPhySec;
03903     
03904     // Assuming logical sector always has a size of 512bytes.
03905     if(pDisk->wordsPerLogSec != 256) return 0xffffffff;
03906     
03907     if ( (pBufStart = (unsigned short *)malloc(pDisk->wordsPerLogSec*sizeof(short))) == NULL )
03908         // Out of memory, fatal error.
03909         SYS_die(FAT__FREECLUSNUM);
03910 
03911     while( (fatCurrentPhySec <= fatEndPhySec) && (usedClusCnt < pDisk->maxClus) ) 
03912     {
03913         pBuf = pBufStart;
03914         
03915         if( fatCurrentPhySec == pDisk->curActvPhySec)
03916         {
03917             memcpy(pBuf, pDisk->secBuf, 256);
03918         }
03919         else pDisk->readSec(fatCurrentPhySec, pBuf, FALSE);
03920         
03921         fatCurrentPhySec++;
03922 
03923         switch ( pDisk->fileSysType ) 
03924         {
03925 
03926 #ifndef _FAT_REMOVE_FAT12_SUPPORT
03927             case FAT_12:
03928 
03929                 // 12-bit/entry, 340 or 341 entries/sector depending on the
03930                 // bits alignment. The remaining 4 or 8 bits and the 8 or 4
03931                 // bits from the 1st byte of the next sector form the
03932                 // following entry.
03933                 jj = Clus + (Clus/2);   // bytes
03934 
03935                 // word offset within the sector
03936                 offset = (unsigned short)((jj>>1)%pDisk->wordsPerLogSec); 
03937 
03938                 while ( offset <= (pDisk->wordsPerLogSec-1) ) 
03939                 {
03940                     jj = Clus + (Clus/2);   // bytes
03941                                     
03942                     sector = pDisk->brPhySec + pDisk->rsvdSecCnt + 
03943                     (jj/(pDisk->wordsPerLogSec<<1));
03944             
03945                     // word offset within the sector
03946                     offset = (unsigned short)((jj>>1)%pDisk->wordsPerLogSec); 
03947 
03948                     jj = pBuf[offset];
03949 
03950                     // To see if cross-sector happens.
03951                     if(offset == (pDisk->wordsPerLogSec-1) )
03952                     {
03953                         kk = FAT__readWord(sector+1, 0, FALSE, pDisk);
03954                     }
03955                     else
03956                     {
03957                         kk = pBuf[offset+1];
03958                     }
03959 
03960                     switch(Clus % 4) 
03961                     {
03962                         case 0:
03963                             entry = jj >> 4;
03964                             if ( offset == (pDisk->wordsPerLogSec-1) )
03965                             { 
03966                                 // save 4 LSBs of the last word 
03967                                 // of the current sector.
03968                                 savedLastWord = jj;
03969                                 bFourBitsSaved = TRUE;
03970                             }
03971                             break;
03972 
03973                         case 1:
03974 
03975                             if ( (offset == 0) && (bFourBitsSaved == TRUE) )
03976                             {                               
03977                                 entry = ((savedLastWord&0x000F)<<8) | (jj&0x00FF);
03978                                 bFourBitsSaved = FALSE;
03979                             }
03980                             else 
03981                             {
03982                                 entry = ((jj&0xF)<<8) | (kk>>8);
03983                             }
03984                             break;
03985 
03986                         case 2:
03987                             entry = ((jj&0xFF)<<4 ) | (kk >> 12);
03988                             break;
03989 
03990                         case 3:
03991                             entry = jj & 0xFFF;
03992                             break;
03993                     }
03994 
03995                     if ( entry != 0 ) usedClusCnt++;
03996                     Clus++;
03997                 }
03998                 break;
03999 #endif // end of _FAT_REMOVE_FAT12_SUPPORT. 
04000 
04001             case FAT_16:
04002                 // One word (16-bit)/entry, 256 entries/sector
04003                 for ( ii = 0; ii < 256; ii++ ) 
04004                 {
04005                     if ( *pBuf++ != 0 ) usedClusCnt++;
04006                 }
04007                 break;
04008 
04009             case FAT_32:
04010                 // Two words (32-bit)/entry, 128 entries/sector
04011                 //for ( ii = 0; ii < 256; ii+=2 ) 
04012                 for ( ii = 0; ii < 128; ii++ ) 
04013                 {
04014                     //if ( ( *(pBuf+ii) != 0 ) || ( *(pBuf+ii+1) != 0 ) ) 
04015                     if ( ((*pBuf++)|(*pBuf++)) != 0 ) 
04016                     {                   
04017                         usedClusCnt++;
04018                     }
04019                 }
04020                 break;
04021 
04022             default:    break;
04023         }
04024     }
04025 
04026     free ( pBufStart );
04027 
04028     if (usedClusCnt > pDisk->maxClus) 
04029     {
04030         // should never happen
04031         usedClusCnt = pDisk->maxClus;
04032     }
04033 
04034     return ( pDisk->maxClus - usedClusCnt );
04035 }

Here is the call graph for this function:

BOOL FAT__fseek File file,
long  len,
SEEK_MODE  eMod
 

Function seeks in file, assuming file is seekable.

Parameters:
file File pointer.
len Seek offset.
eMod Seek mode.
Returns:
TRUE if successfully reset file pointer, otherwise FALSE.

Definition at line 5398 of file fat.c.

References FAT__calcPhySecOfClus(), FAT__clusEntry(), FAT__findNxtOcupdClus(), st_FATDISK::secPerClus, SEEK_HEAD, SEEK_MID, and SEEK_TAIL.

Referenced by FAT__bfopen(), and FAT_fseek().

05399 {
05400     st_FATDISK *    pDisk = file->pDisk;
05401     unsigned long   size =  file->size;
05402     unsigned long   ptr =   file->ptr;
05403     unsigned long   length;
05404     unsigned long   ulTmp;
05405     
05406     switch ( eMod )
05407     {
05408         case SEEK_HEAD:
05409             if ( (len > (long)size) || (len < 0 ) ) return FALSE;
05410             length = len;
05411 
05412             break;
05413 
05414         case SEEK_MID:
05415             if ( (((long)ptr + len) > size) || (((long)ptr + len) < 0 ) ) return FALSE;
05416             length = ptr + len;
05417 
05418             break;
05419 
05420         case SEEK_TAIL:
05421             if ( ((len + (long)size) < 0)|| (len > 0 ) ) return FALSE;
05422             length = size + len;
05423 
05424             break;
05425         default: return FALSE;
05426     }   
05427     
05428     ulTmp               = file->startClus;
05429     file->curClus       = ulTmp;
05430     file->preBroknClus  = ulTmp;
05431     file->nxtBroknClus  = ulTmp;
05432     //file->nxtBroknClus    = ulTmp + FAT__findNxtOcupdClus(ulTmp, pDisk);
05433     file->curPhySec     = FAT__calcPhySecOfClus(ulTmp, pDisk);
05434 
05435     file->curWordOffsetInSec = 0;
05436     file->curSecOffsetInClus = 0;
05437 
05438     file->ptr = length;
05439     while(1)
05440     {
05441         if(file->curSecOffsetInClus >= pDisk->secPerClus)
05442         {
05443             // Cross cluster boundary.
05444             file->curSecOffsetInClus = 0;
05445 
05446             if(file->curClus < file->nxtBroknClus ) file->curClus++;
05447             else
05448             {
05449                 ulTmp = FAT__clusEntry(file->nxtBroknClus, pDisk);
05450                 if(ulTmp == 0L) return FALSE;
05451                 file->curClus       = ulTmp;
05452                 file->preBroknClus  = ulTmp;
05453                     
05454                 file->nxtBroknClus  = ulTmp + FAT__findNxtOcupdClus(ulTmp, pDisk); 
05455                 file->curPhySec = FAT__calcPhySecOfClus(ulTmp, pDisk);
05456             }
05457         }
05458 
05459         if(length >= 256)
05460         {
05461             length -= 256;
05462             file->curPhySec++;
05463             file->curSecOffsetInClus++;
05464             if(length == 0) return TRUE;
05465         }
05466         
05467         else
05468         {
05469             file->curWordOffsetInSec = (unsigned short)length;
05470             return TRUE;
05471         }
05472     }   
05473 }

Here is the call graph for this function:

st_CURWORKDIR* FAT__getCurWorkDir void   ) 
 

Function returns the current working directory of current task.

Returns:
Current workding directory.

Definition at line 3769 of file fat.c.

References SYS_die().

Referenced by FAT_attr(), FAT_bfopen(), FAT_cd(), FAT_copyDir(), FAT_delete(), FAT_findFirst(), FAT_fopen(), FAT_frevive(), FAT_mkdir(), and FAT_rmdir().

03770 {
03771     TSK_Handle      task;
03772     st_WORKDIRREG * pAvailableReg = NULL;
03773     st_WORKDIRREG * pReg = &workdirREG[0];
03774     unsigned short  ii = MAX_CONCURRENT_WORKDIR;
03775     
03776     // Don't bother me at this time.
03777     TSK_disable();
03778     
03779     task = TSK_self();
03780     while(ii)
03781     {
03782         if(pReg->task == task) break;
03783         if(pReg->task == NULL) pAvailableReg = pReg;
03784         pReg++; 
03785         ii--;
03786     }
03787     
03788     if( 0==ii )
03789     {
03790         if( NULL==pAvailableReg ) SYS_die(FAT__GETCURWORKDIR);
03791         else
03792         {
03793             pAvailableReg->task = task;
03794             pReg = pAvailableReg;   
03795         }   
03796     }
03797     
03798     TSK_enable();
03799     
03800     return pReg->pDir;
03801 }

Here is the call graph for this function:

void FAT__getFinfo st_FATFILEINFO pInfo,
st_FATDIRSEARCH pCtl,
st_FATDIRENT pEnt
 

Function fetches detailed file info out of directory entry.

On return, pEnt->ent will be set to ENT_FILE, ENT_DIR or ENT_INVALID.

Parameters:
pInfo File info buffer.
pCtl File search control buffer.
pEnt Directory entry buffer.

Definition at line 3370 of file fat.c.

References FAT__getNxtDirEnt(), st_FATDIRSEARCH::phySec, and st_FATDIRSEARCH::wordOffset.

Referenced by FAT__findFirst(), and FAT__findNext().

03371 {
03372     unsigned short  usNum;
03373     unsigned short  usLen;
03374     unsigned short  usAvlbl;
03375     unsigned short  ii, jj;
03376     unsigned short* pS, *pD;
03377     st_FATDIRSEARCH ctl;
03378 
03379     // Set up LFN part of info if LFN available. 
03380     pInfo->numLFN = 0;
03381     pInfo->fstLFNclus = pCtl->curClus;
03382     pInfo->fstLFNsecOffset = pCtl->secOffset;
03383     pInfo->fstLFNphySec = pCtl->phySec;
03384     pInfo->fstLFNwordOffset = pCtl->wordOffset;         
03385     
03386     if(pEnt->ent == ENT_LFN)
03387     {           
03388         pInfo->numLFN = pEnt->numLFN;
03389         usNum =         pEnt->numLFN;
03390 
03391         usLen =         13 * usNum;
03392         
03393         usAvlbl =       13;
03394         ii =            pEnt->lname[12];
03395         if( (ii != 0)&&( ii != 0xFFFF) )
03396         {
03397             // LFN just fits the entry, manually append NULL.
03398             pInfo->lname[usLen] = 0;            
03399         }
03400         else
03401         {
03402             ii = 0;
03403             pS = &pEnt->lname[12];
03404             
03405             while( *pS-- == 0x0ffff)
03406             {
03407                 usLen--;
03408                 usAvlbl--;
03409             }
03410         }
03411 
03412         pS = &pEnt->lname[0];
03413         pD = &pInfo->lname[usLen-usAvlbl];
03414         for(jj = 0; jj< usAvlbl; jj++) *pD++ = *pS++;
03415         usLen -= usAvlbl;
03416 
03417         // Get the rest of the LFN entries. Check sum needs to checked here???
03418         for(ii = 0; ii < usNum -1 ; ii++)
03419         {
03420             usLen -= 13;
03421             ctl = *pCtl;
03422             FAT__getNxtDirEnt(pCtl, pEnt);
03423             if(pEnt->ent != ENT_LFN) 
03424             {
03425                 pEnt->ent = ENT_INVALID;
03426                 *pCtl = ctl;
03427                 return;
03428             }
03429             pS = &pEnt->lname[0];
03430             pD = &pInfo->lname[usLen];
03431             for(jj = 0; jj< 13; jj++) *pD++ = *pS++;            
03432         }
03433         
03434         // Get the short name entry. 
03435         ctl = *pCtl;
03436         FAT__getNxtDirEnt(pCtl, pEnt);
03437         if( (pEnt->ent != ENT_FILE)&&(pEnt->ent != ENT_DIR) ) 
03438         {
03439             pEnt->ent = ENT_INVALID;
03440             *pCtl = ctl;
03441             return;
03442         }
03443     }
03444     
03445     // Precess the sname entry. 
03446     pInfo->phySec = pCtl->phySec;
03447     pInfo->wordOffset = pCtl->wordOffset;
03448 
03449     strcpy(pInfo->sname, pEnt->sname);
03450     strcpy(pInfo->ext, pEnt->ext);
03451 
03452     if(pInfo->numLFN == 0)
03453     {
03454         _concatSnameExt((char *)pInfo->lname, pInfo->sname, pInfo->ext);
03455     }
03456 
03457     pInfo->attr = pEnt->attr;
03458     pInfo->size = pEnt->size;
03459     pInfo->startClus = pEnt->startClus;
03460 }

Here is the call graph for this function:

void FAT__getFrstDirEnt st_FATDIRSEARCH pCtl,
st_FATDIRENT pEnt,
st_CURWORKDIR pDir
 

Function fetches the first directory entry under current working directory.

Parameters:
pCtl Directory search control buffer.
pEnt Directory entry buffer.
pDir Current working directory.

Definition at line 3502 of file fat.c.

References st_FATDISK::brPhySec, FAT__calcPhySecOfClus(), FAT__intprtDirEnt(), FAT__readWord(), st_FATDISK::fileSysType, st_FATDIRSEARCH::pDisk, st_FATDISK::rootDirCluster, and st_FATDISK::rootDirSec.

Referenced by FAT__createFile(), and FAT__findFirst().

03505 {   
03506     unsigned long       sec;
03507     st_FATDISK *        pDisk = pDir->pDisk;
03508     unsigned short      buf[16]; // Dir entry buffer, 32 bytes.
03509 
03510     if ( TRUE == pDir->bIsRoot ) 
03511     {
03512         if ( pDisk->fileSysType != FAT_32 ) 
03513         {
03514             sec = pDisk->rootDirSec + pDisk->brPhySec;
03515             pCtl->curClus = 0;
03516         }
03517         else
03518         {
03519             sec = FAT__calcPhySecOfClus( pDisk->rootDirCluster, pDisk );
03520             pCtl->curClus = pDisk->rootDirCluster;
03521         }
03522     }
03523     else
03524     {
03525         sec = FAT__calcPhySecOfClus(pDir->startClus, pDisk);
03526         pCtl->curClus = pDir->startClus;
03527     }
03528 
03529     pCtl->pDisk = pDisk;
03530     pCtl->curEnt = 1;
03531     
03532     pCtl->phySec = sec;
03533     pCtl->secOffset = 0;
03534     pCtl->wordOffset = 0;
03535 
03536     FAT__readWord(sec, 0, buf, 16, TRUE, pDisk);
03537 
03538     FAT__intprtDirEnt(buf, pEnt, pDisk);
03539 }

Here is the call graph for this function:

BOOL FAT__getNxtDirEnt st_FATDIRSEARCH pCtl,
st_FATDIRENT pEnt
 

Function fetches the next directory entry under current working directory.

Parameters:
pCtl Directory search control buffer.
pEnt Directory entry buffer.
Returns:
TRUE if entry found, otherwise FALSE.

Definition at line 3551 of file fat.c.

References st_FATDISK::EOC, FAT__calcPhySecOfClus(), FAT__clusEntry(), FAT__intprtDirEnt(), FAT__readWord(), and st_FATDISK::secPerClus.

Referenced by FAT__createFile(), FAT__findFirst(), FAT__findNext(), and FAT__getFinfo().

03552 {   
03553     unsigned long   clus;
03554     st_FATDISK *    pDisk = pCtl->pDisk;
03555     unsigned short  buf[16];
03556 
03557     pCtl->wordOffset += 16;
03558     pCtl->curEnt++;
03559 
03560     if(pCtl->wordOffset >= 256)
03561     {
03562         // Cross sector. 
03563         pCtl->wordOffset = 0;
03564         pCtl->secOffset += 1;
03565         pCtl->phySec += 1;
03566 
03567         if(pCtl->secOffset >= pDisk->secPerClus)
03568         {
03569             pCtl->secOffset = 0;
03570             
03571             if(pCtl->curClus != 0)
03572             {
03573                 // Cross cluster boundary.              
03574                 clus = FAT__clusEntry(pCtl->curClus, pDisk);
03575     
03576                 if( clus >= pDisk->EOC) return FALSE;
03577                         
03578                 pCtl->curClus = clus;
03579                 pCtl->phySec = FAT__calcPhySecOfClus(clus, pDisk);
03580             }
03581             else
03582             {
03583                 // FAT12/16 support, rootclus = 0.
03584                 if(pCtl->curEnt > pCtl->pDisk->rootEntCnt) return FALSE;
03585             }
03586         }   
03587     }
03588     
03589     FAT__readWord(  pCtl->phySec, pCtl->wordOffset, buf, 16, TRUE, pDisk);
03590     
03591     FAT__intprtDirEnt(buf, pEnt, pDisk);
03592     
03593     return TRUE;
03594 }

Here is the call graph for this function:

void FAT__intprtDirEnt const unsigned short *  pBuf,
st_FATDIRENT pEnt,
st_FATDISK pDisk
 

Function interpretes the directory entry.

NOTE: Robust code needs to be added here to automatically delete the invalid diretory entry.

Parameters:
pBuf Directory entry data buffer.
pEnt Directory entry.
pDisk pointer to FAT/disk structure? (undocumented).

Definition at line 3609 of file fat.c.

References st_FATDIRENT::attr, st_FATDIRENT::ent, ENT_DIR, ENT_FILE, ENT_LFN, ENT_VOL, st_FATDIRENT::numLFN, and st_FATDIRENT::startClus.

Referenced by FAT__getFrstDirEnt(), and FAT__getNxtDirEnt().

03610 {   
03611     unsigned short attr;
03612 
03613     switch( (*pBuf)  & 0xFF)
03614     {
03615         case 0x00:      // free entry.  
03616             pEnt->ent = ENT_FREE;
03617             return;
03618 
03619         case 0xE5:      // deleted entry.  
03620             pEnt->ent = ENT_DEL;
03621             return;
03622 #if 0
03623         case 0x05:      // 0xE5 character.
03624             break;
03625 
03626         default:        // not a free/deleted entry
03627             break;
03628 #endif
03629     }
03630 
03631     // found a none free entry, not deleted either, further process needed. 
03632     attr = pBuf[5] >> 8;// little endian.
03633     pEnt->attr = attr;
03634     
03635     pEnt->numLFN = 0;
03636 
03637     if( (attr & FAT_LFN_MASK) == FAT_ATTR_LFN) 
03638     {
03639         pEnt->ent = (TRUE == _fetchLFN(pBuf, pEnt))? ENT_LFN:ENT_INVALID;
03640     }
03641     else if( (attr & ( FAT_ATTR_DIR|FAT_ATTR_VOLUME)) == 0 )
03642     {
03643         pEnt->ent = ( (TRUE == _fetchDir(pBuf, pEnt))&&(pEnt->startClus <= pDisk->maxClus))? ENT_FILE:ENT_INVALID;
03644     }
03645     else if( (attr & ( FAT_ATTR_DIR|FAT_ATTR_VOLUME)) == FAT_ATTR_DIR )
03646     {
03647         pEnt->ent = ( (TRUE == _fetchDir(pBuf, pEnt))&&(pEnt->startClus <= pDisk->maxClus))? ENT_DIR:ENT_INVALID;
03648     }
03649     else if( (attr & ( FAT_ATTR_DIR|FAT_ATTR_VOLUME)) == FAT_ATTR_VOLUME )
03650     {
03651         pEnt->ent = (TRUE == _fetchVolume(pBuf, pEnt))? ENT_VOL:ENT_INVALID;    
03652     }
03653     else pEnt->ent = ENT_INVALID;
03654 }

BOOL FAT__isSnameChar char  Ch  ) 
 

Function checks to see if character is valid for short file name, following MS standard.

Function is called to generate short name, thus ' ' and '.' are not counted as valid character.

Parameters:
Ch character.
Returns:
TRUE if it is valid short name character, otherwise FALSE.

Definition at line 3333 of file fat.c.

03334 {
03335     if( Ch & 0x80 ) return TRUE; /* > 127 */
03336     
03337     if( (Ch < '#' )&&( Ch != '!') ) return FALSE;
03338     
03339     if( Ch < '*' ) return TRUE;
03340 
03341     if( (Ch <'0') && ( Ch != '-') ) return FALSE;
03342 
03343     if( Ch < ':' ) return TRUE;
03344 
03345     if( Ch < '@' ) return FALSE;
03346 
03347     if( Ch < '[' ) return TRUE;
03348 
03349     if( Ch < '^') return FALSE;
03350 
03351     if( Ch < '|' ) return TRUE;
03352 
03353     if( (Ch != '}')&&(Ch != '~') ) return FALSE;
03354 
03355     return TRUE;
03356 }

BOOL FAT__mkdir const char *  pDirName,
st_CURWORKDIR pDir
 

Function creates directory under given working directory if not exists already.

Root directory can NOT be created by definition. Function does not translate path delimiters, which means only one directory can be created per call. No character validity function here, it is the caller's responsibility to make sure pDirName points to valid dir name.

Parameters:
pDirName Directory name.
pDir Actual working directory? (undocumented).
Returns:
TRUE if directory successfully created, otherwise FALSE.

Definition at line 522 of file fat.c.

References FAT__chg2PathDir(), FAT__createFile(), and FAT__findFirst().

Referenced by FAT_copyDir(), and FAT_mkdir().

00523 {
00524     long                handle;
00525     char *              pNext;
00526     st_FATFILEINFO      info;
00527         
00528     if(FAT__chg2PathDir(pDirName, &pNext, pDir) == FALSE)
00529         return FALSE;
00530         
00531     handle = FAT__findFirst(pNext, &info, pDir);
00532     if(handle != -1)
00533     {
00534         FAT_findClose(handle);
00535         return TRUE;            
00536     }
00537     
00538     return(FAT__createFile((const char *)pNext, FAT_ATTR_DIR, NULL, NULL, pDir));
00539 }

Here is the call graph for this function:

void FAT__pathAppend char *  path,
const char *  pName
 

Function appends a name string to path.

Parameters:
path working direcotry path.
pName name string.

Definition at line 2495 of file fat.c.

Referenced by FAT__cd().

02496 {
02497     unsigned short  usLen;
02498     
02499     usLen = strlen(path);
02500     path += usLen;
02501     while( (usLen < FAT_MAXLFN)&&(*pName != '/')&&(*pName != 0) )
02502     {
02503         *path++ = *pName++;
02504     }
02505     
02506     *path++ = '/';
02507     *path = 0;
02508 }

void FAT__pathTruncate char *  path  ) 
 

Function truncate current path and go up once.

Parameters:
path working direcotry path.

Definition at line 2468 of file fat.c.

Referenced by FAT__cd().

02469 {
02470     unsigned short  usLen;
02471     
02472     usLen = strlen(path) - 1;
02473     path += usLen;
02474     
02475     while(usLen--)
02476     {
02477         path--;
02478         if(*path == '/')
02479         {
02480             *(path+1) = 0;
02481             break;
02482         }
02483     }
02484 }

BOOL FAT__readFatWord unsigned long  ulPhySec,
unsigned short  usWordOffset,
unsigned short *  pWord,
unsigned short  wordNum,
BOOL  bByteSwap,
st_FATDISK pDisk
 

Function reads back a word from FAT area.

It is the caller's responsibility to make sure words do not cross sector boundary.

Parameters:
ulPhySec physical sector number.
usWordOffset word offset in sector.
pWord Word buffer.
wordNum Number of words to read.
bByteSwap TRUE if high-low byte is swapped.
pDisk drive global data structure pointer.
Returns:
TRUE if words successuflly read, otherwise FALSE.

Definition at line 3047 of file fat.c.

References st_FATDISK::curActvFatPhySec, st_FATDISK::fatSecBuf, st_FATDISK::flag, st_FATDISK::readSec, and st_FATDISK::writeSec.

Referenced by FAT__clusEntry().

03053 {
03054     unsigned short *    pBuf = (unsigned short *) &pDisk->fatSecBuf[0];
03055 
03056     FAT_assert(ulPhySec < pDisk->totalSec16_32, FAT__READFATWORD);
03057     
03058     FAT_lock(pDisk->lock2);
03059     
03060     if(ulPhySec != pDisk->curActvFatPhySec) 
03061     {
03062         if(pDisk->flag&DISK_FATWRITE_PENDING)
03063         {
03064             pDisk->writeSec(pDisk->curActvFatPhySec, pDisk->fatSecBuf, FALSE);
03065             pDisk->flag &= ~DISK_FATWRITE_PENDING;
03066         }
03067 
03068         pDisk->readSec(ulPhySec, pBuf, FALSE);
03069         pDisk->curActvFatPhySec = ulPhySec;
03070     }
03071 
03072     pBuf += usWordOffset;
03073     if( FALSE == bByteSwap) while(wordNum--) *pWord++ = *pBuf++;
03074     else
03075     {
03076         while(wordNum--)
03077         {
03078             *pWord = (*pBuf<<8) | ( ((*pBuf)>>8)&0x00ff );
03079             pWord++;
03080             pBuf++;
03081         }
03082     }
03083 
03084     FAT_unlock(pDisk->lock2);
03085     
03086     return TRUE;
03087 }

BOOL FAT__readWord unsigned long  ulPhySec,
unsigned short  usWordOffset,
unsigned short *  pWord,
unsigned short  wordNum,
BOOL  bByteSwap,
st_FATDISK pDisk
 

Function reads back words from data area.

It is the caller's responsibility to make sure words do not cross sector boundary.

Parameters:
ulPhySec physical sector number.
usWordOffset word offset in sector.
pWord Word buffer.
wordNum Number of words to read.
bByteSwap TRUE if high-low byte is swapped.
pDisk drive global data structure pointer.
Returns:
TRUE if words successuflly read, otherwise FALSE.

Definition at line 2935 of file fat.c.

References st_FATDISK::curActvPhySec, st_FATDISK::flag, st_FATDISK::readSec, st_FATDISK::secBuf, and st_FATDISK::writeSec.

Referenced by FAT__clusEntry(), FAT__delete(), FAT__freeClusNum(), FAT__getFrstDirEnt(), FAT__getNxtDirEnt(), FAT__globalsInit(), FAT_attr(), and FAT_fread().

02941 {
02942     unsigned short *    pBuf = (unsigned short *) &pDisk->secBuf[0];
02943 
02944     //FAT_assert(ulPhySec < pDisk->totalSec16_32, FAT__READWORD);
02945     
02946     FAT_lock(pDisk->lock);
02947 
02948     if(ulPhySec != pDisk->curActvPhySec) 
02949     {
02950         if(pDisk->flag&DISK_WRITE_PENDING)
02951         {
02952             pDisk->writeSec(pDisk->curActvPhySec, pDisk->secBuf, FALSE);
02953             pDisk->flag &= ~DISK_WRITE_PENDING;
02954         }
02955 
02956         pDisk->readSec(ulPhySec, pBuf, FALSE);
02957         pDisk->curActvPhySec = ulPhySec;
02958     }
02959     
02960     pBuf += usWordOffset;
02961     if( FALSE == bByteSwap) while(wordNum--) *pWord++ = *pBuf++;
02962     else
02963     {
02964         while(wordNum--)
02965         {
02966             *pWord = (*pBuf<<8) | ( ((*pBuf)>>8)&0x00ff );
02967             pWord++;
02968             pBuf++;
02969         }
02970     }
02971     
02972     FAT_unlock(pDisk->lock);
02973     
02974     return TRUE;
02975 }

BOOL FAT__releaseClus unsigned long  startClus,
st_FATDISK pDisk
 

Function releases the cluster linklist.

Parameters:
startClus Start cluster.
pDisk Disk data pointer.
Returns:
TRUE if list is successfully released, otherwise FALSE.

Definition at line 3151 of file fat.c.

References st_FATDISK::brPhySec, st_FATDISK::curActvFatPhySec, st_FATDISK::fatSecBuf, st_FATDISK::flag, st_FATDISK::freeClusNum, st_FATDISK::readSec, st_FATDISK::rsvdSecCnt, and st_FATDISK::writeSec.

Referenced by FAT__bfopen(), and FAT__delete().

03152 {
03153     unsigned short   copy, offset;
03154     unsigned short*  pD;
03155     unsigned short*  pBuf;
03156     unsigned short*  pEndBuf;
03157     unsigned long    entry, clus = startClus;
03158     unsigned long    actvFatSec;
03159     unsigned long    sector;
03160     unsigned long    fatSecOffset;
03161     
03162     FAT_lock(pDisk->lock2);
03163     
03164     pBuf       = pDisk->fatSecBuf;
03165     pEndBuf    = pBuf + 256;
03166     actvFatSec = pDisk->curActvFatPhySec;
03167         
03168     for( copy = 0; copy < pDisk->numFATs; copy++ )
03169     {
03170         startClus = clus;
03171         fatSecOffset = (unsigned short)(copy*pDisk->FATsz16_32) + pDisk->brPhySec + pDisk->rsvdSecCnt;
03172     
03173     #ifndef _FAT_REMOVE_FAT12_SUPPORT
03174         if( FAT_12 == pDisk->fileSysType )
03175         {
03176         
03177         }
03178         else
03179     #endif
03180         if( FAT_16 == pDisk->fileSysType )  
03181         {
03182             // For FAT16, there are (1*clus) words (or 2*clus bytes) in each FAT entry 
03183             // sector += (FAT_curDir.pDisk->brPhySec + 
03184             //          FAT_curDir.pDisk->rsvdSecCnt + 
03185             //              (clus/FAT_curDir.pDisk->wordsPerLogSec) );
03186             // Following to optimize, assuming sector size fixed to 512bytes.
03187             sector = fatSecOffset + (startClus>>8);
03188             
03189             //offset = (unsigned short)(clus%FAT_curDir.pDisk->wordsPerLogSec); 
03190             offset = (unsigned short)(startClus & 0x00FF);
03191             
03192             if(sector != actvFatSec) 
03193             {
03194                 if(pDisk->flag&DISK_FATWRITE_PENDING)
03195                             pDisk->writeSec(actvFatSec, pBuf, FALSE);
03196                 pDisk->readSec(sector, pBuf, FALSE);
03197             }
03198             
03199             pD = pBuf + offset;
03200             entry = (*pD>>8)|(*pD<<8);
03201             while(1)
03202             {
03203                 *pD++ = 0;
03204                 
03205                 // if ent is zero, meaning one cluster is free now, freeClusNum plus one.
03206                 // otherwise, one cluster is taken, freeClusNum minus one.
03207                 if ( copy == 0 ) 
03208                 {
03209                     pDisk->freeClusNum++;
03210                 }   
03211 
03212                 if( entry == startClus+1 )
03213                 {
03214                     if(pD == pEndBuf) 
03215                     {
03216                         pDisk->writeSec(sector++, pBuf, FALSE);
03217                         pDisk->readSec(sector, pBuf, FALSE);
03218                         pD     = pBuf;
03219                     }                   
03220                 }
03221                 else
03222                 {
03223                     if( (entry >= pDisk->EOC)||(entry == 0) ) 
03224                     {
03225                         actvFatSec              = sector;
03226                         pDisk->curActvFatPhySec = sector;
03227                         pDisk->flag            |= DISK_FATWRITE_PENDING;    
03228                         break;                      
03229                     }
03230                     
03231                     pDisk->writeSec(sector, pBuf, FALSE);
03232                     actvFatSec   = sector;                  
03233                     sector       = fatSecOffset + (entry>>8);
03234                     offset       = entry & 0x0ff;
03235                     pD           = pBuf + offset;
03236                     
03237                     if( sector != actvFatSec )
03238                         pDisk->readSec(sector, pBuf, FALSE);                                        
03239                 }
03240                 startClus = entry;
03241                 entry = (*pD>>8)|(*pD<<8);
03242             }
03243         }
03244 
03245         else if( FAT_32 == pDisk->fileSysType )
03246         {
03247             // For FAT32, there are (2*clus) words (or 4*clus bytes) in each FAT entry
03248             // sector += (FAT_curDir.pDisk->brPhySec + 
03249             //          FAT_curDir.pDisk->rsvdSecCnt + 
03250             //              (2*clus/FAT_curDir.pDisk->wordsPerLogSec) );
03251             sector = fatSecOffset + (startClus>>7);
03252         
03253             //offset = (unsigned short)(2*clus%
03254             //              FAT_curDir.pDisk->wordsPerLogSec); 
03255             offset = (unsigned short)((startClus<<1)&0x00FF);
03256     
03257             if(sector != actvFatSec) 
03258             {
03259                 if(pDisk->flag&DISK_FATWRITE_PENDING)
03260                             pDisk->writeSec(actvFatSec, pBuf, FALSE);
03261                 pDisk->readSec(sector, pBuf, FALSE);
03262             }
03263             
03264             pD = pBuf + offset;
03265             entry = (*pD>>8)|(*pD<<8);
03266             pD++;
03267             entry |= (unsigned long)((*pD>>8)|(*pD<<8))<<16;
03268             while(1)
03269             {   
03270                 *pD-- = 0;
03271                 *pD   = 0;
03272                 pD   += 2;
03273 
03274                 // if ent is zero, meaning one cluster is free now, freeClusNum plus one.
03275                 // otherwise, one cluster is taken, freeClusNum minus one.
03276                 if ( copy == 0 ) 
03277                 {
03278                     pDisk->freeClusNum++;
03279                 }       
03280 
03281                 if( entry == startClus+1 )
03282                 {
03283                     if(pD == pEndBuf) 
03284                     {
03285                         pDisk->writeSec(sector++, pBuf, FALSE);
03286                         pDisk->readSec(sector, pBuf, FALSE);
03287                         pD     = pBuf;
03288                     }                   
03289                 }
03290                 else
03291                 {
03292                     if( (entry >= pDisk->EOC)||(entry == 0) ) 
03293                     {
03294                         actvFatSec              = sector;
03295                         pDisk->curActvFatPhySec = sector;
03296                         pDisk->flag |= DISK_FATWRITE_PENDING;   
03297                         break;                      
03298                     }
03299                     
03300                     pDisk->writeSec(sector, pBuf, FALSE);
03301                     actvFatSec   = sector;                  
03302                     sector       = fatSecOffset + (entry>>7);
03303                     offset       = (unsigned short)((entry<<1)&0x00FF);;
03304                     pD           = pBuf + offset;
03305                     
03306                     if( sector != actvFatSec )
03307                         pDisk->readSec(sector, pBuf, FALSE);                                        
03308                 }
03309                 startClus = entry;
03310                 entry = (*pD>>8)|(*pD<<8);
03311                 pD++;
03312                 entry |= (unsigned long)((*pD>>8)|(*pD<<8))<<16;
03313             }
03314         }
03315     }
03316     
03317     FAT_unlock(pDisk->lock2);
03318         
03319     return TRUE;
03320 }

int FAT__strcmp const char *  str1,
const char *  str2
 

Function carries out special FAT string comparation, it checks the '/' or NULL as the string terminator and compares at upper case.

Parameters:
str1 string 1.
str2 string 2.
Returns:
0 If str1 is equal to str2, nonzero otherwise.

Definition at line 2899 of file fat.c.

Referenced by FAT__cd(), and FAT__findFirst().

02900 {
02901     FAT_assert((unsigned short)str1&&(unsigned short)str2, FAT__STRCMP);
02902     
02903     do
02904     {
02905         if( toupper(*str1) != toupper(*str2) ) return 1;
02906         str1++;
02907         str2++;
02908     } while( (*str1 != 0)&&(*str1 != '/') );
02909     
02910     if( (*str2 != 0)&&(*str2 != '/') ) return 1;
02911 
02912     return 0;
02913 }

BOOL FAT__unmountDisk DISK_ID  disk  ) 
 

Function unmounts disk to flush.

Parameters:
disk Disk specifier.
Returns:
TRUE if successfully unmounted, otherwise FALSE.

Definition at line 2867 of file fat.c.

References DISK_C, DISK_D, FAT__flush(), HDD_unmount(), and NAND_unmount().

Referenced by FAT_format().

02868 {
02869     st_FATDISK *    pDisk;
02870     
02871     if( DISK_C == disk)
02872     {
02873         pDisk = &DiskC;     
02874     }
02875     else if( DISK_D == disk )
02876     {
02877         pDisk = &DiskD;
02878     }
02879     else return FALSE;
02880 
02881     FAT__flush(pDisk);
02882     
02883     if(DISK_C == disk)  return HDD_unmount();
02884     else                return NAND_unmount();
02885 }

Here is the call graph for this function:

BOOL FAT__updateCopyOfFAT unsigned long  clus,
unsigned long  ent,
unsigned short  num,
unsigned short  copy,
st_FATDISK pDisk
 

Function updates specified copy of FAT.

Parameters:
clus cluster number.
ent cluster entry.
num Contiguous number of entry.
copy FAT copy number.
pDisk Disk structure pointer.
Returns:
TRUE if FAT successfully updated, otherwise FALSE.

Definition at line 2560 of file fat.c.

Referenced by FAT__fflush(), FAT__updateFAT(), FAT__updateSecondCopyOfFAT(), FAT_fclose(), FAT_frevive(), and FAT_fwrite().

02565 {
02566     unsigned long   sector;
02567     unsigned long   fatSecOffset;
02568     unsigned long   actvFatSec; 
02569     unsigned short* pD;
02570     unsigned short* pEndBuf;
02571     unsigned short* pBuf;
02572     unsigned short  offset; 
02573 
02574     if( 0 == num ) return TRUE;
02575     
02576     FAT_lock(pDisk->lock2);
02577     
02578     fatSecOffset = (unsigned short)(copy*pDisk->FATsz16_32);
02579     
02580     // Following to optimize, but only support TWO copies of FAT.
02581     //fatSecOffset = (copy)? FAT_curDir.pDisk->FATsz16_32 : 0;  
02582 
02583     pBuf       = pDisk->fatSecBuf;
02584     pEndBuf    = pBuf + 256;
02585     actvFatSec = pDisk->curActvFatPhySec;
02586 
02587 #ifndef _FAT_REMOVE_FAT12_SUPPORT
02588     if( FAT_12 == pDisk->fileSysType )
02589     {
02590     
02591     }
02592     else
02593 #endif
02594     if( FAT_16 == pDisk->fileSysType )  
02595     {
02596         // For FAT16, there are (1*clus) words (or 2*clus bytes) in each FAT entry 
02597         // sector += (FAT_curDir.pDisk->brPhySec + 
02598         //          FAT_curDir.pDisk->rsvdSecCnt + 
02599         //              (clus/FAT_curDir.pDisk->wordsPerLogSec) );
02600         // Following to optimize, assuming sector size fixed to 512bytes.
02601         sector = fatSecOffset + (pDisk->brPhySec + pDisk->rsvdSecCnt + (clus>>8) );
02602         
02603         //offset = (unsigned short)(clus%FAT_curDir.pDisk->wordsPerLogSec); 
02604         offset = (unsigned short)(clus & 0x00FF);
02605         
02606         if(sector != actvFatSec) 
02607         {
02608             if(pDisk->flag&DISK_FATWRITE_PENDING)
02609                         pDisk->writeSec(actvFatSec, pBuf, FALSE);
02610             pDisk->readSec(sector, pBuf, FALSE);
02611         }
02612         
02613         if( copy == 0 ) pDisk->freeClusNum -= num;
02614 
02615         while(num)
02616         {
02617             pD = pBuf + offset;
02618             
02619             while(pD < pEndBuf)
02620             {
02621                 *pD++ = ((ent & 0x000000FFL)<<8)|((ent & 0x0000FF00L)>>8);
02622                 
02623                 offset++;
02624                 num--;
02625                 if( 0 == num ) break;
02626                 
02627                 ent++;
02628             }
02629             
02630             if( pD == pEndBuf) 
02631             {
02632                 pDisk->writeSec(sector, pBuf, FALSE);
02633                 if( num )
02634                 {
02635                     sector++;
02636                     pDisk->readSec(sector, pBuf, FALSE);
02637                 }
02638                 offset = 0;
02639             }
02640         }
02641     }
02642     else if( FAT_32 == pDisk->fileSysType )
02643     {
02644         // For FAT32, there are (2*clus) words (or 4*clus bytes) in each FAT entry
02645         // sector += (FAT_curDir.pDisk->brPhySec + 
02646         //          FAT_curDir.pDisk->rsvdSecCnt + 
02647         //              (2*clus/FAT_curDir.pDisk->wordsPerLogSec) );
02648         sector = fatSecOffset + (pDisk->brPhySec + pDisk->rsvdSecCnt + (clus>>7) );
02649     
02650         //offset = (unsigned short)(2*clus%
02651         //              FAT_curDir.pDisk->wordsPerLogSec); 
02652         offset = (unsigned short)((clus<<1)&0x00FF);
02653 
02654         if(sector != actvFatSec) 
02655         {
02656             if(pDisk->flag&DISK_FATWRITE_PENDING)
02657                     pDisk->writeSec(actvFatSec, pBuf, FALSE);
02658             
02659             pDisk->readSec(sector, pBuf, FALSE);
02660         }
02661 
02662         if( copy == 0 ) pDisk->freeClusNum -= num;
02663 
02664         while(num)
02665         {   
02666             pD = pBuf + offset;
02667             
02668             while(pD < pEndBuf)
02669             {
02670                 *pD++ = ((ent & 0x000000FFL)<<8)|((ent & 0x0000FF00L)>>8);
02671                 *pD++ = ((ent>>8) & 0x0000FF00L)|((ent>>24) & 0x000000FFL);
02672                 offset+= 2;
02673                 
02674                 num--;
02675                 if( 0 == num ) break;
02676                 
02677                 ent++;
02678             }
02679 
02680             if( pD == pEndBuf) 
02681             {
02682                 pDisk->writeSec(sector, pBuf, FALSE);
02683                 if( num )
02684                 {
02685                     sector++;
02686                     pDisk->readSec(sector, pBuf, FALSE);
02687                 }
02688                 offset = 0;             
02689             }
02690         }
02691     }
02692 
02693     pDisk->curActvFatPhySec = sector;
02694     if(offset)  pDisk->flag |= DISK_FATWRITE_PENDING;
02695     else        pDisk->flag &= ~DISK_FATWRITE_PENDING;
02696 
02697     FAT_unlock(pDisk->lock2);
02698         
02699     return TRUE;
02700 }

BOOL FAT__updateFAT unsigned long  clus,
unsigned long  ent,
unsigned short  num,
st_FATDISK pDisk
 

Function updates both copies of FAT.

Parameters:
clus cluster number.
ent cluster entry.
num Contiguous number of entry.
pDisk Disk structure pointer.
Returns:
TRUE if FAT successfully updated, otherwise FALSE.

Definition at line 2527 of file fat.c.

References FAT__updateCopyOfFAT().

Referenced by FAT__createFile(), and FAT__format().

02531 {
02532 
02533     unsigned short ii;
02534 
02535     for(ii=0; ii<pDisk->numFATs; ii++)
02536     {   
02537         FAT__updateCopyOfFAT(clus, ent, num, ii, pDisk);
02538     }
02539 
02540     return TRUE;
02541 }

Here is the call graph for this function:

BOOL FAT__updateSecondCopyOfFAT unsigned long  startClus,
st_FATDISK pDisk
 

Function updates the second copy of FAT based on FAT entry in first copy.

Parameters:
startClus Start cluster.
pDisk Disk data pointer.
Returns:
TRUE if second copy FAT is successfully updated, otherwise FALSE.

Definition at line 2713 of file fat.c.

References FAT__clusEntry(), and FAT__updateCopyOfFAT().

Referenced by FAT_fclose(), and FAT_frevive().

02714 {
02715     unsigned long       EOC = pDisk->EOC;
02716     unsigned long       entry;
02717     unsigned long       startUpdtClus;
02718     unsigned short      contiguousClusNum;
02719     unsigned short      kk;
02720     unsigned short      numFATs = pDisk->numFATs;
02721 
02722     startUpdtClus     = startClus;
02723     contiguousClusNum = 0;
02724     while(1)
02725     { 
02726         entry = FAT__clusEntry(startClus, pDisk);
02727         if((entry == startClus)||(entry == 0))
02728         {
02729             // Unexpected error, simply return;
02730             // entry == startClus, cluster cross-linked.
02731             // entry == 0, cluster chain has to be ended by EOC.
02732             return FALSE;
02733         }
02734 
02735         if( (entry != startClus+1)&&(contiguousClusNum != 0xffff) )
02736         {
02737             for( kk = 1; kk < numFATs; kk++ )
02738             {
02739                 FAT__updateCopyOfFAT(startUpdtClus, startUpdtClus+1, contiguousClusNum, kk, pDisk);
02740                 FAT__updateCopyOfFAT(startClus, entry, 1, kk, pDisk);
02741             }
02742             
02743             if( entry >= EOC ) break;
02744             
02745             startUpdtClus     = entry;
02746             contiguousClusNum = 0;
02747         }
02748         else
02749         {
02750             contiguousClusNum++;
02751         }
02752         
02753         startClus = entry;
02754     }
02755     
02756     return TRUE;
02757 }

Here is the call graph for this function:

BOOL FAT__writeWord unsigned long  ulPhySec,
unsigned short  usWordOffset,
unsigned short *  pWord,
unsigned short  wordNum,
st_FATDISK pDisk
 

Function writes a word to data area.

It is the caller's responsibility to make sure words do not cross sector boundary.

Parameters:
ulPhySec physical sector number.
usWordOffset word offset in sector.
pWord Word buffer.
wordNum Number of words to write.
pDisk drive global data structure pointer.
Returns:
TRUE if successfully written, otherwise FALSE.

Definition at line 2995 of file fat.c.

References st_FATDISK::curActvPhySec, st_FATDISK::flag, st_FATDISK::readSec, st_FATDISK::secBuf, and st_FATDISK::writeSec.

Referenced by FAT__bfopen(), FAT__delete(), FAT__flush(), FAT_attr(), FAT_fclose(), FAT_frevive(), and FAT_fwrite().

03000 {
03001     unsigned short * pBuf = (unsigned short *) &pDisk->secBuf[0];
03002 
03003     FAT_assert(ulPhySec < pDisk->totalSec16_32, FAT__WRITEWORD);
03004     FAT_assert(usWordOffset <= 256, FAT__WRITEWORD2 );
03005 
03006     FAT_lock(pDisk->lock);
03007     
03008     if(ulPhySec != pDisk->curActvPhySec) 
03009     {
03010         if(pDisk->flag&DISK_WRITE_PENDING)
03011             pDisk->writeSec(pDisk->curActvPhySec, pDisk->secBuf, FALSE);
03012 
03013         pDisk->readSec(ulPhySec, pBuf, FALSE);
03014         pDisk->curActvPhySec = ulPhySec;
03015     }
03016     
03017     pBuf += usWordOffset;
03018     while(wordNum--) *pBuf++ = *pWord++;
03019 
03020     pDisk->flag |= DISK_WRITE_PENDING;
03021 
03022     FAT_unlock(pDisk->lock);
03023     
03024     return TRUE;
03025 }

BOOL FAT_attr const char *  pName,
unsigned short  attr
 

Function changes attribute of the specified file/directory.

Parameters:
pName Dir/file name.
attr Target attributes.
Returns:
TRUE if attributes successfully changed, otherwise FALSE.

Definition at line 2423 of file fat.c.

References FAT__chg2PathDir(), FAT__findFirst(), FAT__flush(), FAT__getCurWorkDir(), FAT__readWord(), FAT__writeWord(), st_CURWORKDIR::pDisk, st_FATFILEINFO::phySec, and st_FATFILEINFO::wordOffset.

02424 {
02425     long            handle;
02426     unsigned long   sec;
02427     unsigned short  offset, word;
02428     st_FATDISK *    pDisk;
02429     char *          pNext;
02430     st_CURWORKDIR * pDir = FAT__getCurWorkDir();
02431     st_CURWORKDIR   dir;
02432     st_FATFILEINFO  info;
02433     
02434     dir = *pDir;
02435 
02436     if(FAT__chg2PathDir(pName, &pNext, &dir) == FALSE)
02437         return FALSE;
02438         
02439     handle = FAT__findFirst(pNext, &info, &dir);    
02440     if(handle == -1) return FALSE;
02441     else
02442     {
02443         FAT_findClose(handle);
02444         
02445         pDisk   = dir.pDisk;
02446         sec     = info.phySec;
02447         offset  = info.wordOffset+5;
02448         
02449         FAT__readWord(sec, offset, &word, 1, FALSE, pDisk);
02450         
02451         word &= 0xFF00;
02452         word |= attr;
02453 
02454         FAT__writeWord(sec, offset, &word, 1, pDisk);
02455     }
02456 
02457     return FAT__flush(dir.pDisk);
02458 }

Here is the call graph for this function:

File* FAT_bfopen const char *  pName,
FOPEN_MODE  eMode,
File file
 

Function opens the file with supplied file object buffer.

Parameters:
pName file name.
eMode file open mode.
file file object pointer, if NULL, operation is the same as that of FAT_fopen.
Returns:
file pointer if successfully opened, other wise NULL.

Definition at line 1380 of file fat.c.

References FAT__bfopen(), FAT__fopen(), and FAT__getCurWorkDir().

Referenced by UI_m3uOpen(), UI_playQprevious(), and UI_setupPlayQ().

01381 {
01382     st_CURWORKDIR *         pDir = FAT__getCurWorkDir();
01383     st_CURWORKDIR           dir;
01384     
01385     dir = *pDir;
01386     
01387     if(file) 
01388     {
01389         file->flag = 0;
01390         return FAT__bfopen(pName, eMode, file, &dir);
01391     }
01392     
01393     return FAT__fopen(pName, eMode, &dir);  
01394 }

Here is the call graph for this function:

BOOL FAT_cd const char *  pName  ) 
 

Function changes current workding directory to specified path.

Directory name MUST take the following format:

"DRIVE:/XDIR/YDIR/" "/XDIR/YDIR/" "XDIR/YDIR/" the tailing '/' character is OPTIONAL.

pName is NOT case sensitive.

Parameters:
pName Path name.
Returns:
TRUE if directory successfully changed, otherwise FALSE.

Definition at line 2399 of file fat.c.

References FAT__cd(), FAT__chg2PathDir(), and FAT__getCurWorkDir().

Referenced by DB__cdDBdir(), DB_checkSyncMark(), DB_creator(), DB_setSyncMark(), EAR_getFirst(), EAR_init(), SYS_regist(), SYS_serialNumber(), UI_m3uClear(), UI_m3uInit(), UI_m3uOpen(), UI_pendingEarDiskSpace(), UI_processEAR(), and UI_rdSynclog().

02400 {
02401     char *          pNext;
02402     st_CURWORKDIR * pDir = FAT__getCurWorkDir();
02403 
02404 
02405     if(FAT__chg2PathDir(pName, &pNext, pDir) == FALSE)
02406         return FALSE;
02407         
02408     return FAT__cd(pNext, pDir);
02409 }

Here is the call graph for this function:

BOOL FAT_copyDir const char *  srcDir,
const char *  dstDir,
USHORT *  cpybuf,
USHORT  buflen
 

Copy all files in srcDir to dstDir.

NOTE that this function recursively copy the subdirectory to dstDir. If directory name does not contain drive letter, directory shall be relative to current working directory. If dstDir is NULL, copy source dirctory to current working directory. The current directory will be dstdir after the copying is done.

NOTE that the dstDir doesn't include the destination directory name, for example FAT_copyDir( "c:/woid", "d:/" ); This will create D:/woid, if d:/ alread has woid directory it will go to that dir, then copy all content to d:/woid. FAT_copyDir( "c:/woid", "d:/woid" ) meaning copy content of c:/woid to d:/woid/woid.

NOTE that the source directory must be different from the target directory. This function doesn't handle this case. For example, FAT_copyDir( "c:/woid", "c:/"); // wrong, same directory!!

NOTE that the srcDir can NOT be root directory. This will be fixed in near future. This function uses stack to copy directory recursivly, so be careful, don't copy a directory which has too many sub-dir

Parameters:
srcDir Source directory name.
dstDir Destination directory name.
cpybuf Supplied copy buffer if not NULL.
buflen Supplied copy buffer length.
Returns:
TRUE if successfully copied, otherwise FALSE.

Definition at line 2223 of file fat.c.

References st_FATFILEINFO::attr, st_CURWORKDIR::bIsRoot, File::curClus, File::curPhySec, File::curSecOffsetInClus, File::curWordOffsetInSec, FAT__calcPhySecOfClus(), FAT__cd(), FAT__chg2PathDir(), FAT__findClose(), FAT__findFirst(), FAT__findNext(), FAT__findNxtOcupdClus(), FAT__fopen(), FAT__getCurWorkDir(), FAT__mkdir(), FAT_fclose(), FAT_fread(), FAT_fwrite(), File::flag, File::flushedSize, File::hdlID, st_FATFILEINFO::lname, File::mode, File::nxtBroknClus, File::pDisk, st_CURWORKDIR::pDisk, File::preBroknClus, File::ptr, st_FATFILEINFO::size, File::size, File::startClus, st_FATFILEINFO::startClus, st_CURWORKDIR::startClus, and wb.

02227 {
02228     char *          pSrcNext;
02229     char *          pDstNext;
02230     File *          dstFP;
02231     File *          srcFP;
02232     st_FATDISK *    pDisk;
02233     USHORT          len;
02234     USHORT          usNum;
02235     USHORT          oldRoundCounter;
02236     USHORT          newRoundCounter;
02237     ULONG           clus;
02238     long            handle;
02239     unsigned long   srcClus;
02240     BOOL            bSrcIsRoot;
02241     BOOL            bDirFound = TRUE;
02242     BOOL            bSecondRound = FALSE;
02243     st_FATFILEINFO  info;
02244     USHORT          localbuf[COPY_BUF_LEN];
02245     USHORT *        buf;
02246     st_CURWORKDIR   srcWorkDir;
02247     st_CURWORKDIR   dstWorkDir;
02248 
02249     srcWorkDir = *FAT__getCurWorkDir();
02250     dstWorkDir = srcWorkDir;
02251     
02252     if(buflen&&cpybuf) buf = cpybuf;
02253     else
02254     {
02255         buflen = COPY_BUF_LEN;
02256         buf    = localbuf;
02257     }
02258         
02259     FAT_assert(srcDir&&dstDir, FAT_COPYDIR);
02260 
02261     if(FAT__chg2PathDir(srcDir, &pSrcNext, &srcWorkDir) == FALSE)   return FALSE;
02262     if(FAT__chg2PathDir(dstDir, &pDstNext, &dstWorkDir) == FALSE)   return FALSE;
02263 
02264     // Let's remember where current directory starts and if it is the ROOT.
02265     srcClus     = srcWorkDir.startClus; 
02266     bSrcIsRoot  = srcWorkDir.bIsRoot;
02267     
02268     // Directory does not exist, report error.
02269     if(FAT__cd(pSrcNext, &srcWorkDir) == FALSE) return FALSE;
02270     if(FAT__cd(pDstNext, &dstWorkDir) == FALSE) return FALSE;
02271     FAT__mkdir(pSrcNext, &dstWorkDir);
02272     FAT__cd(pSrcNext, &dstWorkDir);         
02273     
02274     oldRoundCounter = 0;
02275     newRoundCounter = 0;
02276 
02277     // Check to copy.
02278     while(1)
02279     {
02280         bDirFound = FALSE;
02281         
02282         // Skip '.' and '..' entries.
02283         handle = FAT__findFirst(NULL, &info, &srcWorkDir);
02284         FAT__findNext(handle, &info);
02285         
02286         // First round, copy all files.
02287         while( FAT__findNext(handle, &info) != FALSE )
02288         {
02289             if( (info.attr & ( FAT_ATTR_DIR|FAT_ATTR_VOLUME)) == FAT_ATTR_DIR )
02290             {                               
02291                 if(bSecondRound == TRUE)
02292                 {
02293                     if(0 == oldRoundCounter) 
02294                     {
02295                         bSecondRound = FALSE;
02296                         newRoundCounter++;
02297                     }
02298                     else oldRoundCounter--;
02299                 }
02300                 else
02301                 {
02302                     FAT__findClose(handle);
02303                     
02304                     // New subdir found, cd to it.
02305                     bSecondRound    = FALSE;
02306                     bDirFound       = TRUE;                 
02307                 
02308                     // Go one subdir further.
02309                     FAT__cd((const char *)info.lname, &srcWorkDir);
02310                     FAT__mkdir((const char *)info.lname, &dstWorkDir);
02311                     FAT__cd((const char *)info.lname, &dstWorkDir);             
02312                     break;
02313                 }
02314             }
02315             else 
02316             {
02317                 // If it is a file, copy it directly.
02318                 // rb mode open src.
02319                 srcFP = (File *)malloc(sizeof(File));
02320                 if(srcFP == NULL) return FALSE;
02321                 srcFP->hdlID = FAT__getHdlID();
02322                 if(srcFP->hdlID == 0) 
02323                 {
02324                     free(srcFP);
02325                     return FALSE;
02326                 }
02327                 
02328                 pDisk               = srcWorkDir.pDisk;
02329                 srcFP->mode         = rb;
02330                 srcFP->pDisk        = pDisk;
02331                 srcFP->flushedSize  = 0;
02332                 srcFP->ptr          = 0;
02333                 srcFP->flag         = FILE_OBJ_ALLOCATED;
02334                 clus = info.startClus;              
02335                 usNum = FAT__findNxtOcupdClus(clus, pDisk);
02336                 
02337                 srcFP->size = (info.size + 1)/2;
02338                 srcFP->startClus = clus;
02339                 srcFP->curClus = clus;
02340                 srcFP->preBroknClus = clus;
02341                 srcFP->nxtBroknClus = clus+usNum;
02342                                 
02343                 srcFP->curPhySec = FAT__calcPhySecOfClus(clus, pDisk);
02344                 srcFP->curSecOffsetInClus = 0;
02345                 srcFP->curWordOffsetInSec = 0;
02346 
02347                 dstFP = FAT__fopen((const char *)info.lname, wb, &dstWorkDir );
02348                 
02349                 if(dstFP == NULL)
02350                 {
02351                     FAT_fclose(srcFP);
02352                     return FALSE;
02353                 }
02354                 while ( 1 )
02355                 {
02356                     len = FAT_fread( srcFP, buf, buflen );
02357                     if(len) FAT_fwrite( dstFP, buf, len );
02358                     else break;
02359                 }
02360                 FAT_fclose( dstFP );
02361                 FAT_fclose( srcFP );    
02362             }
02363         }
02364         
02365         if(bDirFound == FALSE) 
02366         {
02367             // This subdir is fully copied now, cd to parent.
02368             bSecondRound    = TRUE;         
02369             oldRoundCounter = newRoundCounter;
02370             FAT__findClose(handle);                     
02371         
02372             // Go up one level.
02373             FAT__cd(strDOTDOT, &srcWorkDir);
02374             FAT__cd(strDOTDOT, &dstWorkDir);
02375             
02376             if( (srcClus == srcWorkDir.startClus)&&(bSrcIsRoot ==  srcWorkDir.bIsRoot) )    break; 
02377         }
02378     }
02379     return TRUE;    
02380 }

Here is the call graph for this function:

BOOL FAT_copyFile const char *  srcFile,
const char *  dstFile,
USHORT *  cpybuf,
USHORT  buflen
 

Copy srcFile to dstFile.

NOTE that if file name does not contain drive letter, file shall be relative to current working directory.

NOTE that, the source file must be different from the destination file. This function does not deal with the situation that the both files are the same name and in the same direcotry. For example, FAT_copyFile( "c:/abc/a.mp3", "c:/abc/a.mp3"); // wrong, same file same directory!!

Parameters:
srcFile Source file name.
dstFile Destination file name.
cpybuf Supplied copy buffer if not NULL.
buflen Supplied copy buffer length.
Returns:
TRUE if successfully copied, otherwise FALSE.

Definition at line 2146 of file fat.c.

References FAT_fclose(), FAT_fopen(), FAT_fread(), FAT_fwrite(), rb, and wb.

02150 {
02151     File *srcFP, *dstFP;
02152     USHORT   localbuf[COPY_BUF_LEN];
02153     USHORT   len;
02154     USHORT * buf;
02155     
02156     if(buflen&&cpybuf) buf = cpybuf;
02157     else
02158     {
02159         buflen = COPY_BUF_LEN;
02160         buf    = localbuf;
02161     }
02162      
02163     FAT_assert(srcFile&&dstFile, FAT_COPYFILE);
02164 
02165     /* open source file with read mode */
02166     srcFP = FAT_fopen( srcFile, rb );
02167     if ( srcFP == NULL ) return FALSE;
02168 
02169     /* open destination file with write mode */
02170     dstFP = FAT_fopen( dstFile, wb );
02171     if ( dstFP == NULL ) 
02172     {
02173         FAT_fclose(srcFP);
02174         return FALSE;
02175     }
02176     
02177     while ( 1 )
02178     {
02179         len = FAT_fread( srcFP, buf, buflen );
02180         if(len) FAT_fwrite( dstFP, buf, len );
02181         else break;
02182     }
02183 
02184     FAT_fclose( dstFP );
02185     FAT_fclose( srcFP );
02186     return TRUE;
02187 }

Here is the call graph for this function:

BOOL FAT_delete const char *  pName  ) 
 

Function deletes file ONLY under current working directory.

Parameters:
pName File to be deleted.
Returns:
TRUE if file is successfully deleted or does not exist, otherwise FALSE.

Definition at line 2101 of file fat.c.

References FAT__chg2PathDir(), FAT__delete(), FAT__findClose(), FAT__findFirst(), FAT__flush(), FAT__getCurWorkDir(), and st_CURWORKDIR::pDisk.

Referenced by SYS_regist(), UI_processEAR(), UI_PSF_hisidone(), UI_PSF_play(), UI_PSF_record(), and UI_PSF_recorddone().

02102 {
02103     char *          pNext;
02104     long            handle;
02105     st_CURWORKDIR * pDir = FAT__getCurWorkDir();
02106     st_CURWORKDIR   dir;
02107     st_FATFILEINFO  info;
02108     
02109     dir = *pDir;
02110 
02111     if(FAT__chg2PathDir(pName, &pNext, &dir) == FALSE)
02112         return FALSE;
02113         
02114     handle = FAT__findFirst(pNext, &info, &dir);
02115     if(-1 == handle) return FALSE;
02116     
02117     FAT__findClose(handle);
02118     
02119     FAT__delete(&info, &dir);
02120 
02121     return FAT__flush(dir.pDisk);
02122 }

Here is the call graph for this function:

BOOL FAT_fclose File file  ) 
 

Function closes file and flushes disk.

Parameters:
file File pointer.
Returns:
TRUE if successfully closed file object, otherwise FALSE.

Definition at line 2005 of file fat.c.

References ab, st_FATDISK::EOC, FAT__fflush(), FAT__flush(), FAT__updateCopyOfFAT(), FAT__updateSecondCopyOfFAT(), FAT__writeWord(), st_FATDISK::flag, FOPEN_MODE, st_FATDISK::maxClus, st_FATDISK::minAvlblClus, File::mode, st_FATDISK::newStartSrchClus, File::pDisk, r_b, wb, and st_FATDISK::wrFileNum.

Referenced by DB__addSAIentry(), DB__deleteChildRecord(), DB__info(), DB__insert2leaf(), DB__recordPosition(), DB__register(), DB__removePAIentry(), DB_add2child(), DB_checkSyncMark(), DB_deleteRecordByMdb(), DB_dspData(), DB_getField(), DB_getMdbByRecord(), DB_getSaiByMdb(), DB_insertRecord(), DB_queryClose(), DB_queryFirst(), DB_removeRecord(), DB_setSyncMark(), EAR_getClose(), EAR_getFirst(), EAR_init(), EAR_put(), FAT_copyDir(), FAT_copyFile(), SYS_regist(), SYS_serialNumber(), UI_m3uClear(), UI_m3uClose(), UI_m3uInit(), UI_pendingEarDiskSpace(), UI_playQprevious(), UI_rdSynclog(), and UI_setupPlayQ().

02006 {
02007     FOPEN_MODE      mode = file->mode;
02008     unsigned short  tmpClusHi, tmpClusLo, tmpSizeHi, tmpSizeLo;
02009     st_FATDISK *    pDisk = file->pDisk;
02010     unsigned long   phySec;
02011     unsigned short  wordOffset;
02012 
02013     if(FALSE == FAT__isHdlValid(file)) return FALSE;
02014 
02015     if( (wb==mode)||(ab==mode)||(r_b==mode) )
02016     {
02017         unsigned long size = file->size<<1;
02018         
02019         // Byte-swap to match "PC endian"
02020         tmpClusHi = (unsigned short)((file->startClus >>16) & 0x0000FFFF);
02021         tmpClusHi = ((tmpClusHi<<8) & 0xFF00) | ((tmpClusHi>>8) & 0x00FF);
02022     
02023         tmpClusLo = (unsigned short)(file->startClus & 0x0000FFFF);
02024         tmpClusLo = ((tmpClusLo<<8) & 0xFF00) | ((tmpClusLo>>8) & 0x00FF);
02025     
02026         tmpSizeHi = (unsigned short)((size >>16) & 0x0000FFFF);
02027         tmpSizeHi = ((tmpSizeHi<<8) & 0xFF00) | ((tmpSizeHi>>8) & 0x00FF);
02028     
02029         tmpSizeLo = (unsigned short)((size) & 0x0000FFFF);
02030         tmpSizeLo = ((tmpSizeLo<<8) & 0xFF00) | ((tmpSizeLo>>8) & 0x00FF);
02031 
02032         // Update dir entry.
02033         phySec      = file->dirEntphySec;
02034         wordOffset  = file->dirEntwordOffset;
02035                 
02036         // start cluster low.
02037         FAT__writeWord(phySec, (unsigned short)(wordOffset + 13), &tmpClusLo, 1, pDisk);
02038                 
02039         // start cluster high.
02040         FAT__writeWord(phySec, (unsigned short)(wordOffset + 10), &tmpClusHi, 1, pDisk);
02041 
02042         // size LOW 
02043         FAT__writeWord(phySec, (unsigned short)(wordOffset + 14), &tmpSizeLo, 1, pDisk);
02044 
02045         // size HIGH 
02046         FAT__writeWord(phySec, (unsigned short)(wordOffset + 15), &tmpSizeHi, 1, pDisk);
02047 
02048         // check to minimize the fragmentation.
02049         if( (file->curClus < file->nxtBroknClus)&&(file->curClus < pDisk->minAvlblClus) )
02050         {
02051             pDisk->minAvlblClus = file->curClus;
02052         }
02053         
02054         // Update FAT table.
02055         FAT__fflush(file);
02056         
02057         if(file->size == 0)
02058         {
02059             // To support zero-sized file.
02060             FAT__updateCopyOfFAT(file->startUpdtClus, pDisk->EOC, 1, 0, pDisk);
02061         }
02062         
02063         // We are now done with the preallocated clusters, really don't have to clear
02064         // this flag, just to make code clean. Upon closing, file flag shall be all
02065         // cleared.
02066         file->flag &= ~FILE_CLUS_PREALLOCATED;
02067                                    
02068         FAT__updateSecondCopyOfFAT(file->startUpdtClus, pDisk);
02069     }
02070 
02071     FAT__flush(pDisk);
02072 
02073     if((wb==mode)||(ab==mode)||(r_b==mode))
02074     {
02075         pDisk->wrFileNum--;
02076         if( 0 == pDisk->wrFileNum )
02077         {
02078             pDisk->newStartSrchClus = (file->curClus<pDisk->minAvlblClus)? 
02079                                         file->curClus:pDisk->minAvlblClus;
02080             pDisk->minAvlblClus     = pDisk->maxClus;
02081         }
02082     }
02083     
02084     FAT__releaseHdlID(file);
02085     
02086     if(file->flag & FILE_OBJ_ALLOCATED) free(file);
02087     
02088     return TRUE;
02089 }

Here is the call graph for this function:

long FAT_findFirst const char *  pName,
st_FATFILEINFO pInfo
 

Function finds the first valid directory or file under current directory.

If any time function returns a valid handle, caller has to call FAT_findClose(...) to release control objects. If pName is NULL, function returns the first valid entry, this is so-called limited wildcard support.

Parameters:
pName Dir/file name to be found if any.
pInfo Dir/file info buffer.
Returns:
find handle that can be used by findnext(...), -1 otherwise.

Definition at line 1907 of file fat.c.

References FAT__findFirst(), and FAT__getCurWorkDir().

01908 {
01909     st_CURWORKDIR   dir;
01910     st_CURWORKDIR * pDir = FAT__getCurWorkDir();
01911     
01912     dir = *pDir;
01913     
01914     return( FAT__findFirst(pName, pInfo, &dir) );
01915 }

Here is the call graph for this function:

BOOL FAT_finsert File file,
unsigned long  offset,
const unsigned short *  pData,
unsigned short  len,
unsigned long  endOffset
 

This function is used to insert data inside of file.

This is a standalong function, meaning no OPEN/CLOSE action needed before/after. Basically there are tow insert modes: 1. endOffset = 0 When insert data, the origin data from the insert point will be moved backward to make space for new data. So the file's boundary and size will change after new data is inserted. 2. endOffset > 0 In this situation, endOffset must larger than ( offset + len ), when insert data, the old data before endOffset will be moved backward, the old data after endOffset will stay there. So the size and boundary of the file will not be changed. For example, a file is 50 words long, offset = 10; len = 2; endOffset = 20, after function returns, the words after 20 remain the same, data at 10 and 11 are new, data from 12 to 19 are old data, but they have been moved from location 10, the old data data at 18 and 19 have been removed since they have crossed the boundary at 20.

Parameters:
file file pointer, has to be opened in r_b mode.
offset the insert point counting from begining of file.
pData the data to be inserted.
len the length of the new data in words.
endOffset the boundary of the old data to be moved.
Returns:
TRUE if successful, otherwise FALSE.

Definition at line 1766 of file fat.c.

References FAT_fread(), FAT_fseek(), FAT_fwrite(), SEEK_HEAD, and SEEK_TAIL.

Referenced by DB__addSAIentry(), DB__insert2leaf(), and UI_m3uChgOrder().

01771 {
01772     unsigned short  buf[BUF_LEN];
01773     unsigned short  rdLen;
01774     unsigned short  wrLen;
01775     unsigned long   startOffset;
01776     
01777     if( 0 == len ) return TRUE;
01778     if( (endOffset < offset+len)&&(0 != endOffset) ) return TRUE;
01779     
01780     
01781     if(0 == endOffset) 
01782     {
01783         unsigned long oldSize;
01784         
01785         oldSize     = file->size;
01786         
01787         if(file->size < offset+len)
01788         {
01789             unsigned short tmp;
01790             
01791             tmp = file->size-offset;
01792             
01793             FAT_fseek(file, 0, SEEK_TAIL);
01794             FAT_fwrite(file, (unsigned short *)pData-tmp, len-tmp);
01795             len = tmp;
01796             
01797             endOffset   = file->size;
01798             startOffset = offset;
01799         }
01800         else
01801         {
01802             endOffset   = file->size;
01803             startOffset = endOffset-len;            
01804         }
01805         
01806         rdLen = len;            
01807 
01808         while(rdLen)
01809         {
01810             if(rdLen > BUF_LEN) wrLen = BUF_LEN;
01811             else wrLen = rdLen;
01812     
01813             FAT_fseek(file, startOffset, SEEK_HEAD);
01814             FAT_fread(file, buf, wrLen);
01815             
01816             FAT_fseek(file, endOffset, SEEK_HEAD);
01817             FAT_fwrite(file, buf, wrLen);
01818             
01819             rdLen -= wrLen;
01820             startOffset += wrLen;
01821             endOffset += wrLen;
01822         }
01823         
01824         endOffset = oldSize;
01825     }
01826 
01827     startOffset = endOffset - len;
01828     rdLen = startOffset - offset;   
01829         
01830     while(rdLen)
01831     {
01832         if(rdLen > BUF_LEN) wrLen = BUF_LEN;
01833         else wrLen = rdLen;
01834     
01835         FAT_fseek(file, startOffset-wrLen, SEEK_HEAD);
01836         FAT_fread(file, buf, wrLen);
01837             
01838         FAT_fseek(file, endOffset-wrLen, SEEK_HEAD);
01839         FAT_fwrite(file, buf, wrLen);
01840             
01841         rdLen -= wrLen;
01842         startOffset -= wrLen;
01843         endOffset -= wrLen;
01844     }
01845         
01846     FAT_fseek(file, offset, SEEK_HEAD);
01847     FAT_fwrite(file, (unsigned short *)pData, len);
01848     
01849     return TRUE;
01850 }

Here is the call graph for this function:

BOOL FAT_flushDisk DISK_ID  disk  ) 
 

Function flushes the FAT disk and makes all change final.

Parameters:
disk Disk ID.
Returns:
TRUE if successfully flushed, otherwise FALSE.

Definition at line 1713 of file fat.c.

References DiskC, FAT__flush(), HDD_flush(), and NAND_flush().

01714 {
01715     if(disk == DISK_D)
01716     {
01717         if(FAT__flush(&DiskD) == TRUE)
01718         {
01719             return NAND_flush();
01720         }
01721     }
01722     else
01723     {
01724         if(FAT__flush(&DiskC) == TRUE)
01725         {
01726             return HDD_flush();
01727         }
01728     }
01729         
01730     return FALSE;
01731 }

Here is the call graph for this function:

File* FAT_fopen const char *  pName,
FOPEN_MODE  eMode
 

Function opens the file specified by pName in a mode specified by eMode under current working directory.

Functoin will NOT change the current working directory. Function will NOT open or create any directory. pName is NOT case sensitive.

Parameters:
pName file name.
eMode file open mode.
Returns:
file pointer if successfully opened, other wise NULL.

Definition at line 1356 of file fat.c.

References FAT__fopen(), and FAT__getCurWorkDir().

Referenced by DB__addSAIentry(), DB__deleteChildRecord(), DB__info(), DB__insert2leaf(), DB__recordPosition(), DB__register(), DB__removePAIentry(), DB_add2child(), DB_checkSyncMark(), DB_deleteRecordByMdb(), DB_dspData(), DB_getField(), DB_getMdbByRecord(), DB_getSaiByMdb(), DB_insertRecord(), DB_queryFirst(), DB_removeRecord(), DB_setSyncMark(), EAR_getFirst(), EAR_init(), EAR_put(), FAT_copyFile(), SYS_regist(), SYS_serialNumber(), UI_m3uClear(), UI_m3uInit(), UI_pendingEarDiskSpace(), and UI_rdSynclog().

01357 {
01358     st_CURWORKDIR *         pDir = FAT__getCurWorkDir();
01359     st_CURWORKDIR           dir;
01360     
01361     dir = *pDir;
01362 
01363     return FAT__fopen(pName, eMode, &dir);  
01364 }

Here is the call graph for this function:

BOOL FAT_format DISK_ID  disk,
FAT_FORMAT_TYPE  type,
unsigned long  rsvSecs
 

Function will reformat the entire volume at given level.

It will rewrite the MBR and BR, clear the entire FAT table if low level format is performed.

Parameters:
disk Disk specifier.
type format type.
rsvSecs Reserved number of sectors that are not FAT accessible.
Returns:
TRUE if successfully formated, otherwise FALSE.

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

Definition at line 931 of file fat.c.

References DISK_C, DISK_D, DiskC, FAT__format(), FAT__unmountDisk(), FAT_HIGH_LEVEL_FORMAT, FAT_LOW_LEVEL_FORMAT, FAT_MEDIA_FORMAT, st_FATDISK::lock, st_FATDISK::lock2, st_FATDISK::readSec, SYS_getParams(), SYS_setParams(), and st_FATDISK::writeSec.

00932 {   
00933     st_FATDISK *    pDisk;
00934     
00935     if( DISK_C == disk)
00936     {           
00937         pDisk = &DiskC;     
00938         DiskC.readSec = HDD_readSec;
00939         DiskC.writeSec = HDD_writeSec;
00940         DiskC.lock = &LCK_fathdd;
00941         DiskC.lock2 = &LCK_fathdd2;
00942     }
00943     else if( DISK_D == disk )   
00944     {   
00945         pDisk = &DiskD;
00946         DiskD.readSec = NAND_readSec;
00947         DiskD.writeSec = NAND_writeSec;
00948         DiskD.lock = &LCK_fatnand;
00949         DiskD.lock2 = &LCK_fatnand2;
00950     }       
00951     else return FALSE;
00952     
00953     switch( type ) 
00954     {
00955         case FAT_HIGH_LEVEL_FORMAT:
00956             if ( FAT__format(pDisk, FAT_HIGH_LEVEL_FORMAT, rsvSecs ) == TRUE ) break;
00957         case FAT_LOW_LEVEL_FORMAT:
00958             if ( FAT__format(pDisk, FAT_LOW_LEVEL_FORMAT, rsvSecs ) == TRUE ) break;
00959         case FAT_MEDIA_FORMAT:
00960             if ( FAT__format(pDisk, FAT_MEDIA_FORMAT, rsvSecs ) == TRUE ) break;    
00961         default: return FALSE;
00962     }   
00963     
00964     if(DISK_D == disk)
00965     {
00966         USHORT ii;
00968         #include "../SYSTEM/sys_param.h"
00969         // THIS REALLY SHOULD BE A GUI CALL, PLACE HERE TO 
00970         // SAVE CODE SPACE.-----------------------12/18/03. MG.
00971         // Clear HDD DB sync status.
00972         SYS_getParams(HDD_DB_STATUS, &ii);
00973         ii &= ~SP_HDS_NANDSYNCED;
00974         SYS_setParams(HDD_DB_STATUS, &ii);
00975         ii = SP_NDC_EMPTY;
00976         SYS_setParams(NAND_DB_CONTENTS, &ii);
00978     }
00979                 
00980     // If successfully format, unmount the disk then. It is the caller's
00981     // responsibility to make sure that disk is mounted before any FAT
00982     // operation.
00983     return FAT__unmountDisk(disk);  
00984 }

Here is the call graph for this function:

short FAT_fread File file,
unsigned short *  pBuf,
short  len
 

Function read file and return number of read words.

If returned length is not equal to specified length, it is either due to end of file or disk operation error. It is the caller's responsibility to handle any errors.

Parameters:
file File pointer.
pBuf Data buffer.
len Data length in words.
Returns:
Number of words read.

Definition at line 814 of file fat.c.

References FAT__calcPhySecOfClus(), FAT__clusEntry(), FAT__fflush(), FAT__findNxtOcupdClus(), FAT__readWord(), st_FATDISK::readSec, and st_FATDISK::secPerClus.

Referenced by DB__addSAIentry(), DB__deleteChildRecord(), DB__getRecord(), DB__info(), DB__insert2leaf(), DB__recordPosition(), DB__register(), DB__removePAIentry(), DB_add2child(), DB_checkSyncMark(), DB_deleteRecordByMdb(), DB_dspData(), DB_getMdbByRecord(), DB_getSaiByMdb(), DB_queryFirst(), DB_queryNext(), DB_removeRecord(), DB_setSyncMark(), DECODER_cache(), DECODER_getData(), EAR_getFirst(), EAR_getNext(), EAR_put(), FAT_copyDir(), FAT_copyFile(), FAT_finsert(), SYS_regist(), SYS_serialNumber(), UI_m3uChgOrder(), UI_pendingEarDiskSpace(), and UI_rdSynclog().

00815 {
00816     unsigned short      ii;
00817     short               length;
00818     st_FATDISK *        pDisk   = file->pDisk;
00819     unsigned short      wordOffset;
00820     unsigned long       ulTmp;
00821     unsigned long       size    = file->size;
00822     unsigned long       ptr     = file->ptr;
00823 
00824     ii = file->mode;    
00825     if( ((ii != rb)&&(ii != r_b))||(ptr >= size) ) return 0;
00826 
00827     if(ii == r_b)
00828     {
00829         if(file->flag & FILE_FAT_FLUSH_PENDING)
00830         {
00831             if(FAT__fflush(file) == FALSE) return -1;
00832         }
00833     }
00834 
00835     size    = file->size;
00836     ptr     = file->ptr;
00837 
00838     if(len >= (long)(size - ptr)) len = (short)(size - ptr);
00839     length = len;
00840     
00841     while(1)
00842     {
00843         if(file->curSecOffsetInClus >= pDisk->secPerClus)
00844         {
00845             // Cross cluster boundary.
00846             file->curSecOffsetInClus = 0;
00847             file->curWordOffsetInSec = 0;
00848             
00849             if(file->curClus < file->nxtBroknClus ) file->curClus++;
00850             else
00851             {
00852                 ulTmp               = FAT__clusEntry(file->nxtBroknClus, pDisk);
00853                 if(0L == ulTmp)     
00854                 {
00855                     file->ptr += (len-length);
00856                     file->curSecOffsetInClus = pDisk->secPerClus;
00857                     return(len - length);
00858                 }
00859                 
00860                 file->curClus       = ulTmp;
00861                 file->preBroknClus  = ulTmp;
00862 
00863                 file->nxtBroknClus  = ulTmp + FAT__findNxtOcupdClus(ulTmp, pDisk);
00864                 file->curPhySec     = FAT__calcPhySecOfClus(ulTmp, pDisk);
00865             }               
00866         }
00867         
00868         wordOffset = file->curWordOffsetInSec;
00869         
00870         if( (wordOffset != 0)||(length < 256) )
00871         {
00872             ii = 256-wordOffset;
00873             if( ii >= length )  ii = (unsigned short)length;    
00874             
00875             FAT__readWord(file->curPhySec, wordOffset, pBuf, ii, FALSE, pDisk);
00876             
00877             file->curWordOffsetInSec += ii;
00878             pBuf                     += ii;
00879     
00880             if(file->curWordOffsetInSec == 256)
00881             {       
00882                 file->curWordOffsetInSec = 0;   
00883                 file->curPhySec++;          
00884                 file->curSecOffsetInClus++;
00885             }
00886             
00887             if(length == ii)
00888             {   
00889                 file->ptr += len;
00890                 return len;
00891             }
00892             else length -= ii;  
00893         }
00894 
00895         else
00896         {       
00897             pDisk->readSec(file->curPhySec, pBuf, FALSE);
00898 
00899             pBuf += 256;
00900             length -= 256;
00901 
00902             file->curPhySec++;
00903             file->curSecOffsetInClus++;
00904                 
00905             if(length == 0)
00906             {               
00907                 file->ptr += len;
00908                 return len;
00909             }       
00910         }   
00911     }
00912 }

Here is the call graph for this function:

ULONG FAT_freeSpace DISK_ID  disk  ) 
 

Function returns disk free space.

Parameters:
disk Disk specifier.
Returns:
Current disk free space in kilo(1024) bytes.

Definition at line 771 of file fat.c.

References DISK_D, DiskC, FAT__freeClusNum(), st_FATDISK::freeClusNum, and st_FATDISK::secPerClus.

Referenced by MENU__createPropertiesMenu(), UI_earPut(), UI_PSF_hisi(), UI_PSF_record(), and UI_updateMembar().

00772 {
00773     if(DISK_D == disk)
00774     {
00775         return((unsigned long)FAT__freeClusNum(DISK_D)*DiskD.secPerClus>>1);
00776     }
00777     
00778     return(DiskC.freeClusNum*DiskC.secPerClus>>1);
00779 }

Here is the call graph for this function:

BOOL FAT_frevive const char *  pName  ) 
 

Function checks to revive unclosed file.

Parameters:
pName file name.
Returns:
TRUE if file successfully revived, otherwise FALSE.

Definition at line 1406 of file fat.c.

References st_FATDISK::EOC, FAT__chg2PathDir(), FAT__clusEntry(), FAT__findFirst(), FAT__flush(), FAT__getCurWorkDir(), FAT__updateCopyOfFAT(), FAT__updateSecondCopyOfFAT(), FAT__writeWord(), st_CURWORKDIR::pDisk, st_FATFILEINFO::phySec, st_FATFILEINFO::startClus, st_FATFILEINFO::wordOffset, and st_FATDISK::wordsPerClus.

01407 {
01408     st_CURWORKDIR *         pDir = FAT__getCurWorkDir();
01409     st_CURWORKDIR           dir;
01410     char *                  pNext;
01411     long                    handle;
01412     st_FATFILEINFO          info;
01413     st_FATDISK *            pDisk;
01414 
01415     dir = *pDir;
01416     
01417     if(FAT__chg2PathDir(pName, &pNext, &dir) == FALSE)  return FALSE;
01418 
01419     pDisk = dir.pDisk;  
01420     
01421     handle = FAT__findFirst(pNext, &info, &dir );
01422     if(handle != -1) 
01423     {
01424         unsigned long   nextClus, 
01425                         curClus = info.startClus,
01426                         clusNum = 1;
01427 
01428         FAT_findClose(handle);
01429         
01430         while(curClus != pDisk->EOC)
01431         {
01432             nextClus = FAT__clusEntry(curClus, pDisk);
01433             if(nextClus == 0L)
01434             {
01435                 FAT__updateCopyOfFAT(curClus, pDisk->EOC, 1, 0, pDisk);
01436                 FAT__updateSecondCopyOfFAT(info.startClus, pDisk);
01437                 
01438                 // Update the size field of directory entry.
01439                 {
01440                     unsigned short  tmpSizeHi, tmpSizeLo, wordOffset;
01441                     unsigned long   phySec, size;
01442                     
01443                     size = clusNum*pDisk->wordsPerClus*2;
01444 
01445                     tmpSizeHi = (unsigned short)((size >>16) & 0x0000FFFF);
01446                     tmpSizeHi = ((tmpSizeHi<<8) & 0xFF00) | ((tmpSizeHi>>8) & 0x00FF);
01447                 
01448                     tmpSizeLo = (unsigned short)((size) & 0x0000FFFF);
01449                     tmpSizeLo = ((tmpSizeLo<<8) & 0xFF00) | ((tmpSizeLo>>8) & 0x00FF);
01450             
01451                     // Update dir entry.
01452                     phySec      = info.phySec;
01453                     wordOffset  = info.wordOffset;
01454                             
01455                     // size LOW 
01456                     FAT__writeWord(phySec, (unsigned short)(wordOffset + 14), &tmpSizeLo, 1, pDisk);
01457             
01458                     // size HIGH 
01459                     FAT__writeWord(phySec, (unsigned short)(wordOffset + 15), &tmpSizeHi, 1, pDisk);    
01460                 }
01461                 
01462                 FAT__flush(pDisk);
01463                 break;
01464             }
01465             else
01466             {
01467                 curClus = nextClus;
01468                 clusNum++;
01469             }           
01470         }
01471         
01472         return TRUE;
01473     }
01474     
01475     return FALSE;
01476 }

Here is the call graph for this function:

BOOL FAT_fseek File file,
long  len,
SEEK_MODE  eMod
 

Function seeks in file.

Parameters:
file File pointer.
len Seek offset.
eMod Seek mode.
Returns:
TRUE if successfully reset file pointer, otherwise FALSE.

Definition at line 5370 of file fat.c.

References FAT__fflush(), FAT__fseek(), and FOPEN_MODE.

Referenced by DB__addSAIentry(), DB__deleteChildRecord(), DB__info(), DB__insert2leaf(), DB__recordPosition(), DB__register(), DB__removePAIentry(), DB_add2child(), DB_deleteRecordByMdb(), DB_dspData(), DB_getField(), DB_getMdbByRecord(), DB_getSaiByMdb(), DB_queryFirst(), DB_queryNext(), DB_removeRecord(), DB_setSyncMark(), DECODER_cache(), DECODER_getData(), EAR_getNext(), EAR_put(), FAT_finsert(), UI_m3uChgOrder(), UI_m3uPut(), UI_m3uRemove(), and UI_pendingEarDiskSpace().

05371 {
05372     FOPEN_MODE      mode =  file->mode;
05373 
05374     // Seek operation is only valid under "rb" and "r_b" mode. 
05375     if( (mode != rb ) && ( mode != r_b) ) return FALSE;
05376 
05377     if(file->flag & FILE_FAT_FLUSH_PENDING)
05378     {
05379         if(FAT__fflush(file) == FALSE) return FALSE;
05380     }
05381     
05382     return FAT__fseek(file, len, eMod);
05383 }

Here is the call graph for this function:

short FAT_fwrite File file,
unsigned short *  pBuf,
short  len
 

Function writes to file and return number of written words.

Parameters:
file File pointer.
pBuf Data buffer.
len Data length in words.
Returns:
Number of words written, -1 indicates error.

Definition at line 554 of file fat.c.

References FAT__calcPhySecOfClus(), FAT__clusEntry(), FAT__findNxtAvlblClus(), FAT__findNxtOcupdClus(), FAT__updateCopyOfFAT(), FAT__writeWord(), st_FATDISK::flag, FOPEN_MODE, st_FATDISK::maxFndClus, st_CURWORKDIR::pDisk, st_FATDISK::secPerClus, and st_FATDISK::writeSec.

Referenced by DB__addSAIentry(), DB__deleteChildRecord(), DB__insert2leaf(), DB__register(), DB__removePAIentry(), DB_add2child(), DB_insertRecord(), DB_removeRecord(), DB_setSyncMark(), EAR_init(), EAR_put(), ENCODER_cache(), ENCODER_putData(), FAT_copyDir(), FAT_copyFile(), FAT_finsert(), SYS_serialNumber(), UI_m3uClear(), UI_m3uInit(), UI_m3uPut(), and UI_m3uRemove().

00555 {
00556     unsigned short      ii;
00557     unsigned short      wordOffset;
00558     short               length = len;
00559     st_FATDISK *        pDisk = file->pDisk;
00560     FOPEN_MODE          mode;
00561     unsigned long       ulTmp;
00562 
00563     mode = file->mode;
00564     if( ((mode != wb)&&(mode != r_b)&&(mode!= ab))||(file->flag&FILE_DISK_FULL) ) return 0;
00565 
00566     // check if file length over 4G limit.
00567     if ( file->ptr > 0x80000000L ) return 0;
00568 
00569     file->flag |= FILE_FAT_FLUSH_PENDING;
00570     
00571     while(1)
00572     {
00573         if(file->curSecOffsetInClus >= pDisk->secPerClus)
00574         {
00575             // Cross cluster boundary. 
00576             file->curSecOffsetInClus = 0;
00577             file->curWordOffsetInSec = 0;
00578 
00579             if( (mode == r_b) && (file->ptr < file->flushedSize) )
00580             {
00581                 // No preallocation needed at this time.
00582             }
00583             else
00584             {
00585                 if( file->curClus == file->centClus )
00586                 {
00587                     if(file->flag & FILE_FLUSH_BROKNCLUS_PENDING)
00588                     {
00589                         file->flag &= ~FILE_FLUSH_BROKNCLUS_PENDING;
00590 
00591                         FAT__updateCopyOfFAT(   file->nxtPreBroknClus,
00592                                                 file->preBroknClus, 
00593                                                 1,
00594                                                 0,
00595                                                 pDisk);
00596                     }
00597 
00598                     if( !(file->flag&FILE_CLUS_PREALLOCATED) )
00599                     {
00600                         // Preallocate next available clusters.
00601                         file->preAllocatedClusNum = 
00602                             FAT__findNxtAvlblClus(  &file->nxtPreBroknClus,
00603                                                     pDisk->maxFndClus,
00604                                                     pDisk);
00605                         file->flag |= FILE_CLUS_PREALLOCATED;
00606                     }
00607                 }
00608             }
00609                 
00610             if(file->curClus < file->nxtBroknClus ) file->curClus++;
00611             else 
00612             {
00613                 if( (mode == r_b) && (file->ptr < file->flushedSize) )
00614                 {
00615                     file->preBroknClus = FAT__clusEntry(file->nxtBroknClus, pDisk);
00616                     
00617                     // Note that at least one cluster has been found here, even
00618                     // this is the last available cluster in file.
00619                     file->preAllocatedClusNum = 
00620                             FAT__findNxtOcupdClus(  file->preBroknClus, pDisk) + 1;
00621                 }
00622                 else
00623                 {
00624                     // Update FAT table
00625                     FAT__updateCopyOfFAT(   file->preBroknClus, 
00626                                             file->preBroknClus+1,
00627                                             (unsigned short)(file->curClus - file->preBroknClus),
00628                                             0,
00629                                             pDisk );
00630 
00631                     // Normally, this flag should have been set before coming here. 
00632                     // But there are cases that it is not set yet, for example, in r_b mode,
00633                     // seek to the end of file before any writing happens.
00634                     if( !(file->flag&FILE_CLUS_PREALLOCATED) )
00635                     {
00636                         // Preallocate next available clusters.
00637                         file->preAllocatedClusNum = 
00638                             FAT__findNxtAvlblClus(  &file->nxtPreBroknClus,
00639                                                     pDisk->maxFndClus,
00640                                                     pDisk);
00641                         file->flag |= FILE_CLUS_PREALLOCATED;
00642                     }
00643 
00644                     if( file->preAllocatedClusNum == 0 )
00645                     {
00646                         // Disk Full!
00647                         
00648                         // clusters from preBroknClus to curClus have been 
00649                         // updated to FAT already.
00650                         file->preBroknClus = file->curClus;
00651                         file->flag |= FILE_DISK_FULL;
00652 
00653                         file->size = file->ptr;
00654                         return (len-length);
00655                     }
00656                         
00657                     file->preBroknClus = file->nxtPreBroknClus;
00658                             
00659                     // Remember that file->nxtBroknClus has not been flushed yet. 
00660                     file->flag |= FILE_FLUSH_BROKNCLUS_PENDING;
00661                             
00662                     // Remember which cluster needs to be flushed.
00663                     file->nxtPreBroknClus = file->nxtBroknClus;                         
00664                     file->flag &= ~FILE_CLUS_PREALLOCATED;      
00665                 }
00666                     
00667                 ulTmp               = file->preBroknClus;
00668                 file->curClus       = ulTmp;
00669                 file->nxtBroknClus  = ulTmp + file->preAllocatedClusNum - 1;
00670                 file->centClus      = ulTmp + file->preAllocatedClusNum/2;
00671                 file->curPhySec = FAT__calcPhySecOfClus(ulTmp, pDisk);
00672             }               
00673         }
00674     
00675         wordOffset = file->curWordOffsetInSec;
00676         
00677         if( (wordOffset != 0)||(length < 256) )
00678         {
00679             ii = 256-wordOffset;
00680             if( ii >= length )  ii = (unsigned short)length;    
00681             
00682             FAT__writeWord(file->curPhySec, wordOffset, pBuf, ii, pDisk);
00683             
00684             file->curWordOffsetInSec    += ii;
00685             pBuf                        += ii;
00686     
00687             if(file->curWordOffsetInSec == 256)
00688             {       
00689                 file->curWordOffsetInSec = 0;   
00690                 file->curPhySec++;          
00691                 file->curSecOffsetInClus++;
00692             }
00693             
00694             if(length == ii)
00695             {   
00696                 file->ptr += len;
00697                 
00698                 // Check to update file size.
00699                 if(mode == r_b)
00700                 {
00701                     if(file->ptr > file->flushedSize) file->size = file->ptr;
00702                 }
00703                 else file->size = file->ptr;
00704                                 
00705                 return len;
00706             }
00707             else length -= ii;  
00708         }
00709         
00710         else
00711         {
00712             pDisk->writeSec(file->curPhySec, pBuf, FALSE);
00713 
00714             pBuf += 256;
00715             length -= 256;
00716 
00717             file->curPhySec++;
00718             file->curSecOffsetInClus++;
00719                 
00720             if(length == 0)
00721             {               
00722                 file->ptr += len;
00723                 
00724                 // Check to update file size.
00725                 if(mode == r_b)
00726                 {
00727                     if(file->ptr > file->flushedSize) file->size = file->ptr;
00728                 }
00729                 else file->size = file->ptr;
00730                 
00731                 return len;
00732             }       
00733         }               
00734     }
00735 }

Here is the call graph for this function:

BOOL FAT_mkdir const char *  pDirName  ) 
 

Function creates directory under current working directory if not exists already.

Root directory can NOT be created by definition. Function does not translate path delimiters, which means only one directory can be created per call. No character validity function here, it is the caller's responsibility to make sure pDirName points to valid dir name.

Parameters:
pDirName Directory name.
Returns:
TRUE if directory successfully created, otherwise FALSE.

Definition at line 495 of file fat.c.

References FAT__getCurWorkDir(), and FAT__mkdir().

Referenced by DB_creator(), and EAR_init().

00496 {
00497     st_CURWORKDIR *     pDir = FAT__getCurWorkDir();
00498     st_CURWORKDIR       dir;
00499         
00500     dir = *pDir;
00501     
00502     return(FAT__mkdir(pDirName, &dir));
00503 }

Here is the call graph for this function:

FAT_MOUNT_MSG FAT_mountDisk DISK_ID  disk  ) 
 

Function checks to mount specified disk and reports mount message.

FAT_mountDisk(...) and FAT_unmountDisk(...) can only be called by operating system.

Parameters:
disk Disk specifier.
Returns:
Mount message based on media status.

Definition at line 255 of file fat.c.

References DISK_C, DiskC, HDD_mount(), st_FATDISK::lock, st_FATDISK::lock2, st_FATDISK::readSec, and st_FATDISK::writeSec.

00255                                            {
00256 
00257     unsigned short  usTmp;
00258     st_FATDISK *    pDisk;
00259     unsigned long   navMaxAddr;
00260 
00261     if( DISK_C == disk)
00262     {
00263         if(SYS_isHDDpresent())
00264         {
00265             pDisk = &DiskC;         
00266             DiskC.readSec = HDD_readSec;
00267             DiskC.writeSec = HDD_writeSec;
00268             DiskC.lock = &LCK_fathdd;
00269             DiskC.lock2 = &LCK_fathdd2;
00270             navMaxAddr = HDD_mount();
00271         }
00272         else return FAT_MOUNT_MEDIA_NOT_PRESENT;
00273     }
00274     else if( DISK_D == disk )
00275     {
00276         pDisk = &DiskD;
00277         DiskD.readSec = NAND_readSec;
00278         DiskD.writeSec = NAND_writeSec;
00279         DiskD.lock = &LCK_fatnand;
00280         DiskD.lock2 = &LCK_fatnand2;
00281         navMaxAddr = NAND_mount();      
00282     }
00283     else return FAT_MOUNT_UNKNOWN_ERROR;
00284 
00285     if ( navMaxAddr == 0 ) return FAT_MOUNT_MEDIA_FAILURE;
00286  
00287     pDisk->flag = 0;
00288     
00289     // enable word/sector interface.
00290     pDisk->curActvPhySec = FAT_INVALIDSEC;
00291     pDisk->curActvFatPhySec = FAT_INVALIDSEC;
00292     
00293     if(FAT__globalsInit(pDisk) == TRUE)
00294     {       
00295         // Double check if BR/MBR does not match current media.
00296         if(pDisk->totalSec16_32 <= navMaxAddr)
00297         {       
00298             unsigned long num = (unsigned long)FAT__freeClusNum(disk);
00299             
00300             if( 0xffffffff != num )
00301             {
00302                 pDisk->freeClusNum = num;
00303                 pDisk->oldFreeClusNum = num;
00304                 
00305                 if ( pDisk->fileSysType == FAT_32 ) 
00306                 {   
00307                     /* FSI_Nxt_Free */
00308                     FAT__readWord( pDisk->fsInfoSec, 492>>1, &usTmp, 1, TRUE, pDisk );
00309                     pDisk->newStartSrchClus = usTmp;
00310                     FAT__readWord( pDisk->fsInfoSec, 494>>1, &usTmp, 1, TRUE, pDisk );
00311                     pDisk->newStartSrchClus |= (unsigned long)usTmp<<16;
00312         
00313                     if ( pDisk->newStartSrchClus == 0x0FFFFFFF )
00314                         pDisk->newStartSrchClus = FAT_FIRSTCLUS;
00315                 }
00316                 else 
00317                 {
00318                     pDisk->newStartSrchClus = FAT_FIRSTCLUS;
00319                 }
00320         
00321                 // init the pSearch and pStart, they should be equal when no file is open.
00322                 pDisk->wrFileNum        = 0;
00323                 pDisk->minAvlblClus     = pDisk->maxClus;
00324                 pDisk->oldStartSrchClus = pDisk->newStartSrchClus;
00325                 
00326                 return FAT_MOUNT_SUCCESS;
00327             }
00328         }
00329     }
00330     
00331     // Unmount media before return.
00332     if( DISK_C == disk) HDD_unmount();
00333     else                NAND_unmount();
00334         
00335     return FAT_MOUNT_FAT_FAILURE;
00336 }

Here is the call graph for this function:

void FAT_releaseCurWorkDir TSK_Handle  task  ) 
 

Function release the current working directory of given task.

Parameters:
task Task handle.

Definition at line 3810 of file fat.c.

Referenced by SYS_hookDelete(), and SYS_hookExit().

03811 {
03812     unsigned short  ii = MAX_CONCURRENT_WORKDIR;
03813     st_WORKDIRREG * pReg = &workdirREG[0];
03814     
03815     // Don't bother me at this time.
03816     TSK_disable();
03817 
03818     while(ii--)
03819     {
03820         if(pReg->task == task)
03821         {
03822             pReg->task = NULL;
03823             break;
03824         }
03825         pReg++; 
03826     }
03827         
03828     TSK_enable();
03829 }

BOOL FAT_rmdir const char *  pDirName  ) 
 

Function removes the given directory under current working directory and any subdirs or files.

Parameters:
pDirName Directory that is going to be removed.
Returns:
TRUE if directory is successfully removed or does not exist, otherwise FALSE.

Definition at line 144 of file fat.c.

References FAT__chg2PathDir(), FAT__flush(), FAT__getCurWorkDir(), and st_CURWORKDIR::pDisk.

00145 {
00146     char *          pNext;
00147     st_CURWORKDIR * pDir = FAT__getCurWorkDir();
00148     st_CURWORKDIR   dir;
00149     
00150     dir = *pDir;
00151 
00152     if(FAT__chg2PathDir(pDirName, &pNext, &dir) == FALSE)
00153         return FALSE;
00154         
00155     _deleteDir(pNext, &dir);
00156 
00157     return FAT__flush(dir.pDisk);
00158 }

Here is the call graph for this function:

ULONG FAT_totalSpace DISK_ID  disk  ) 
 

Function returns total disk space.

Parameters:
disk Disk specifier.
Returns:
Total disk space in kilo(1024) bytes.

Definition at line 790 of file fat.c.

References DISK_D, st_FATDISK::maxClus, and st_FATDISK::secPerClus.

Referenced by ENCODER_putData(), and UI_updateMembar().

00791 {
00792     st_FATDISK *    pDisk;
00793     
00794     pDisk = (DISK_D == disk)? &DiskD: &DiskC;
00795 
00796     return(pDisk->maxClus*pDisk->secPerClus>>1);
00797 }


Generated on Wed Jan 19 01:13:01 2005 for neuros-firmware by  doxygen 1.3.9.1