File nut/fs/fat.c

* This file is part of the AVRIDE device driver.
* Copyright (c) 2002-2003 by Michael Fischer. All rights reserved.
* Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met:
* 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the author nor the names of its contributors may * be used to endorse or promote products derived from this software * without specific prior written permission.
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL * THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE.
**************************************************************************** * History:
* 14.12.02 mifi First Version * 23.12.02 mifi Add FileOpen, FileClose, FileError, FileSize, * FileSeek and FileRead. But the FileSeek function. * does not work in the moment, later... * 28.12.02 mifi Now support FAT16 AND FAT32. * 01.01.03 mifi Support long directory entries, but without to * check the checksum of the short entry. * Change FAT32FileSize return value from int to long. * The max size of a long filename segment is * (FAT_LONG_NAME_LEN-1). But the complete filename can * be longer.
* segment1/segment2/segment3/index.html
* segmentX max length = (FAT_LONG_NAME_LEN-1)
* 04.01.03 mifi Take a look at the return values... * 18.01.03 mifi Change Licence from GPL to BSD. * 25.01.03 mifi Implement a new FindFile function. * I have some trouble with short file names under * Win98. Win98 store a short name like "enlogo.gif" * as a long name, nasty OS. * Remove FAT32_MAX_FILES and the array aFileHandle, * a file handle will now be allocated by NutHeapAlloc, * therefore we have no restrictions about the count of * the open file handle. (Only by available memory) * 27.01.03 mifi Rename all FAT32xxx function to FATxxx.
* 28.01.03 mifi Start porting to Nut/OS 3.X.X * 19.06.03 mifi Change the call of IDEInit, now we use the BaseAddress * of 0. Because the fat module does not need to know the * address. It will be handled in ide.c. * 29.06.03 mifi First ATAPI-Version * Now we can read files from a CD-ROM. But there exist * some open points: * - only first session from a multisession CD is supported * - only iso9660, no Joliet support now, later

References Functions: FATFileClose() nut/fs/fat.c
  FATFileOpen() nut/fs/fat.c
  FATFileRead() nut/fs/fat.c
  FATFileSize() nut/fs/fat.c
  FATFileWrite() nut/fs/fat.c
  FATFileWriteP() nut/fs/fat.c
  FATInit() nut/fs/fat.c

Included Files


Preprocessor definitions

#define __FAT_C__

#define FAT_OK 0

#define FAT_ERROR -1

#define FAT_ERROR_EOF -2

#define FAT_ERROR_IDE -3

#define NUTDEV_OK 0

#define NUTDEV_ERROR -1

#define FAT_MAX_DRIVE 2

#define ZIP_DRIVE_BR_SECTOR 32

#define BPB_RsvdSecCnt 32

#define BPB_NumFATs 2

#define BPB_HiddSec 63

#define FAT32_MEDIA 0xf8

#define FAT32_OFFSET_FSINFO 1

#define FAT32_OFFSET_BACKUP_BOOT 6

#define FAT16_CLUSTER_EOF 0x0000FFFF

#define FAT16_CLUSTER_ERROR 0x0000FFF7

#define FAT16_CLUSTER_MASK 0x0000FFFF

#define FAT32_CLUSTER_EOF 0x0FFFFFFF

#define FAT32_CLUSTER_ERROR 0x0FFFFFF7

#define FAT32_CLUSTER_MASK 0x0FFFFFFF

#define FAT_SIGNATURE 0xAA55

#define MBR_SIGNATURE FAT_SIGNATURE

#define MBR_FAT32 0x0C

#define FSINFO_FIRSTSIGNATURE 0x41615252

#define FSINFO_FSINFOSIGNATURE 0x61417272

#define FSINFO_SIGNATURE FAT_SIGNATURE

#define DIRECTORY_ATTRIBUTE_READ_ONLY 0x01

#define DIRECTORY_ATTRIBUTE_HIDDEN 0x02

#define DIRECTORY_ATTRIBUTE_SYSTEM_FILE 0x04

#define DIRECTORY_ATTRIBUTE_VOLUME_ID 0x08

#define DIRECTORY_ATTRIBUTE_DIRECTORY 0x10

#define DIRECTORY_ATTRIBUTE_ARCHIVE 0x20

#define DIRECTORY_ATTRIBUTE_LONG_NAME 0x0F

#define DIRECTORY_ATTRIBUTE_LONG_NAME_MASK 0x3F

#define FAT_NAME_LEN 8

#define FAT_EXT_LEN 3

#define FAT_SHORT_NAME_LEN

#define FAT_LONG_NAME_LEN 64

#define FLAG_FAT_IS_CDROM 0x0001

#define FLAG_FAT_IS_ZIP 0x0002

#define ATAPI_BOOT_RECORD 0x00

#define ATAPI_PVD_DESC 0x01

#define ATAPI_SVD_DESC 0x02

#define ATAPI_VDST_DESC 0xFF


Typedef DSKSZTOSECPERCLUS

typedef struct {...} DSKSZTOSECPERCLUS
struct  
   {  
      DWORD DiskSize;  
      BYTE SecPerClusVal;  
   }  

Typedef FAT32_FILEDATETIME

typedef struct _FAT32FileDataTime FAT32_FILEDATETIME
struct _FAT32FileDataTime  
   {  
      unsigned Seconds:5;  
      unsigned Minute:6;  
      unsigned Hour:5;  
      unsigned Day:5;  
      unsigned Month:4;  
      unsigned Year:7;  
   }  

Typedef PFAT32_FILEDATETIME

typedef struct _FAT32FileDataTime* PFAT32_FILEDATETIME
See: Typedef FAT32_FILEDATETIME

Typedef FAT32_DIRECTORY_ENTRY

typedef struct _FAT32DirectoryEntry FAT32_DIRECTORY_ENTRY
struct _FAT32DirectoryEntry  
   {  
      BYTE Name[8];  
      BYTE Extension[3];  
      BYTE Attribute;  
      BYTE Reserved[8];  
      WORD HighCluster;  
      FAT32_FILEDATETIME Date;  
      WORD LowCluster;  
      DWORD FileSize;  
   }  

Typedef FAT32_DIRECTORY_ENTRY_LONG

typedef struct _FAT32DirectoryEntryLong FAT32_DIRECTORY_ENTRY_LONG
struct _FAT32DirectoryEntryLong  
   {  
      BYTE Order;  
      WORD Name1[5];  
      BYTE Attribute;  
      BYTE Type;  
      BYTE Chksum;  
      WORD Name2[6];  
      WORD LowCluster;  
      WORD Name3[2];  
   }  

Typedef FAT32_FSINFO

typedef struct _FAT32FileSystemInformation FAT32_FSINFO
struct _FAT32FileSystemInformation  
   {  
      DWORD FirstSignature;  
      BYTE Reserved1[480];  
      DWORD FSInfoSignature;  
      DWORD NumberOfFreeClusters;  
      DWORD MostRecentlyAllocatedCluster;  
      BYTE Reserved2[12];  
      BYTE Reserved3[2];  
      WORD Signature;  
   }  

Typedef FAT32_PARTITION_ENTRY

typedef struct _FAT32PartitionEntry FAT32_PARTITION_ENTRY
struct _FAT32PartitionEntry  
   {  
      BYTE BootInd;  
      BYTE FirstHead;  
      BYTE FirstSector;  
      BYTE FirstTrack;  
      BYTE FileSystem;  
      BYTE LastHead;  
      BYTE LastSector;  
      BYTE LastTrack;  
      DWORD StartSectors;  
      DWORD NumSectors;  
   }  

Typedef FAT32_PARTITION_TABLE

typedef struct _FAT32PartionTable FAT32_PARTITION_TABLE
struct _FAT32PartionTable  
   {  
      BYTE LoadInstruction[446];  
      FAT32_PARTITION_ENTRY Partition[4];  
      WORD Signature;  
   }  

Typedef BPBFAT16

typedef struct _bpbfat16 BPBFAT16
struct _bpbfat16  
   {  
      BYTE DrvNum;  
      BYTE Reserved1;  
      BYTE BootSig;  
      DWORD VollID;  
      BYTE VolLab[11];  
      BYTE FilSysType[8];  
      BYTE Reserved2[28];  
   }  

Typedef BPBFAT32

typedef struct _bpbfat32 BPBFAT32
struct _bpbfat32  
   {  
      DWORD FATSz32;  
      WORD ExtFlags;  
      WORD FSVer;  
      DWORD RootClus;  
      WORD FSInfo;  
      WORD BkBootSec;  
      BYTE Reserved[12];  
      BYTE DrvNum;  
      BYTE Reserved1;  
      BYTE BootSig;  
      DWORD VollID;  
      BYTE VolLab[11];  
      BYTE FilSysType[8];  
   }  

Typedef BPBOFFSET36

typedef union _bpboffset36 BPBOFFSET36
union _bpboffset36  
   {  
      BPBFAT16 FAT16;  
      BPBFAT32 FAT32;  
   }  

Typedef FAT32_BOOT_RECORD

typedef struct _FAT32BootRecord FAT32_BOOT_RECORD
struct _FAT32BootRecord  
   {  
      BYTE JumpBoot[3];  
      BYTE OEMName[8];  
      WORD BytsPerSec;  
      BYTE SecPerClus;  
      WORD RsvdSecCnt;  
      BYTE NumFATs;  
      WORD RootEntCnt;  
      WORD TotSec16;  
      BYTE Media;  
      WORD FATSz16;  
      WORD SecPerTrk;  
      WORD NumHeads;  
      DWORD HiddSec;  
      DWORD TotSec32;  
      BPBOFFSET36 Off36;  
      BYTE Reserved[420];  
      WORD Signature;  
   }  

Typedef PFAT32_BOOT_RECORD

typedef struct _FAT32BootRecord* PFAT32_BOOT_RECORD
See: Typedef FAT32_BOOT_RECORD

Typedef FAT_ENTRY_TABLE16

typedef struct _fat_entry_table16 FAT_ENTRY_TABLE16
struct _fat_entry_table16  
   {  
      WORD aEntry[256];  
   }  

Typedef FAT_ENTRY_TABLE32

typedef struct _fat_entry_table32 FAT_ENTRY_TABLE32
struct _fat_entry_table32  
   {  
      DWORD aEntry[128];  
   }  

Typedef FAT_DIR_TABLE

typedef union _fat_dir_table FAT_DIR_TABLE
union _fat_dir_table  
   {  
      FAT32_DIRECTORY_ENTRY aShort[16];  
      FAT32_DIRECTORY_ENTRY_LONG aLong[16];  
   }  

Typedef DRIVE_INFO

typedef struct _drive_info DRIVE_INFO
struct _drive_info  
   {  
      BYTE bIsFAT32;  
      BYTE bDevice;  
      BYTE bSectorsPerCluster;  
      BYTE bFlags;  
      WORD wSectorSize;  
      DWORD dwRootDirSectors;  
      DWORD dwFirstRootDirSector;  
      DWORD dwRootCluster;  
      DWORD dwFAT1StartSector;  
      DWORD dwFAT2StartSector;  
      DWORD dwCluster2StartSector;  
      DWORD dwClusterSize;  
   }  

Typedef FHANDLE

typedef struct _fhandle FHANDLE
struct _fhandle  
   {  
      DWORD dwFileSize;  
      DWORD dwStartCluster;  
      DWORD dwReadCluster;  
      DWORD dwFilePointer;  
      DWORD dwClusterPointer;  
      int nLastError;  
      int nEOF;  
      DRIVE_INFO* pDrive;  
   }  

Typedef ATAPI_PVD

typedef struct _atapi_pvd ATAPI_PVD
struct _atapi_pvd  
   {  
      BYTE descr_type;  
      BYTE magic[5];  
      BYTE descr_ver;  
      BYTE unused;  
      BYTE sysid[32];  
      BYTE volid[32];  
      BYTE zeros1[8];  
      BYTE seknum[8];  
      BYTE zeros2[32];  
      BYTE volsetsize[4];  
      BYTE volseqnum[4];  
      BYTE seksize[4];  
      BYTE pathtablen[8];  
      DWORD firstsek_LEpathtab1_LE;  
      DWORD firstsek_LEpathtab2_LE;  
      BYTE firstsek_BEpathtab1_BE[4];  
      BYTE firstsek_BEpathtab2_BE[4];  
      BYTE rootdir[34];  
      BYTE volsetid[128];  
      BYTE pubid[128];  
      BYTE dataprepid[128];  
      BYTE appid[128];  
      BYTE copyr[37];  
      BYTE abstractfileid[37];  
      BYTE bibliofileid[37];  
      BYTE creationdate[17];  
      BYTE modify[17];  
      BYTE expire[17];  
      BYTE effective[17];  
      BYTE filestruc_ver;  
      BYTE zero;  
      BYTE app_use[512];  
      BYTE res[653];  
   }  

Typedef ATAPI2_DIRECTORY_RECORD

typedef struct _ATAPIDirectoryRecord ATAPI2_DIRECTORY_RECORD
struct _ATAPIDirectoryRecord  
   {  
      BYTE bRecordSize;  
      BYTE bShouldBeZero;  
      DWORD dwFirstSector;  
      DWORD dwNotUse1;  
      DWORD dwEntrySize;  
      DWORD dwNotUse2;  
      BYTE bDate[7];  
      BYTE bFlags;  
      BYTE bInterleaveInfo[2];  
      BYTE bVolumeSequenceNumber[4];  
      BYTE bIdentifierLength;  
      BYTE bName[1];  
   }  

Global Variable devFATC

NUTDEVICE devFATC
Visible in:   nut/fs/fat.c

Local Variables

gnIsInit
static int gnIsInit
Used in: FATFileOpen()  
  FATInit()  

pSectorBuffer
static BYTE* pSectorBuffer

Used in: FATFileRead()  
  FATMountDrive()  
  FindFile()  
  FindFileATAPI()  
  GetNextCluster()  
  MountATAPI()  
  MountIDE()  

pLongName1
static char* pLongName1

Used in: FATFileOpen()  
  FATMountDrive()  

pLongName2
static char* pLongName2

Used in: FATMountDrive()  
  FindFile()  

sDriveInfo
static DRIVE_INFO sDriveInfo[2]

Used in: FATFileOpen()  
  FATMountDrive()  
  FATUnMountDrive()  
  MountATAPI()  
  MountIDE()  

hFATSemaphore
static HANDLE hFATSemaphore

Used in: FATFree()  
  FATLock()  
  FATSemaInit()  

Global Function FATFileRead()

int FATFileRead ( NUTFILE* hNUTFile, void* pData, int nSize )
Calls: FATFree() nut/fs/fat.c
  FATLock() nut/fs/fat.c
  GetFirstSectorOfCluster() nut/fs/fat.c
  GetNextCluster() nut/fs/fat.c
  IDEReadSectors() nut/arch/avr/dev/ide.c
  memcpy() nut/c/string/memcpy.c
Used in:   nut/fs/fat.c
References Variables: pSectorBuffer nut/fs/fat.c

Global Function FATFileSize()

long FATFileSize ( NUTFILE* hNUTFile )
Calls: FATFree() nut/fs/fat.c
  FATLock() nut/fs/fat.c
Used in:   nut/fs/fat.c

Global Function FATFree()

void FATFree ( void )
Calls: NutEventPost()
Called by: FATFileClose() nut/fs/fat.c
  FATFileOpen() nut/fs/fat.c
  FATFileRead() nut/fs/fat.c
  FATFileSize() nut/fs/fat.c
  FATMountDrive() nut/fs/fat.c
  FATUnMountDrive() nut/fs/fat.c
References Variables: hFATSemaphore nut/fs/fat.c

Global Function FATLock()

void FATLock ( void )
Calls: NutEventWait()
Called by: FATFileClose() nut/fs/fat.c
  FATFileOpen() nut/fs/fat.c
  FATFileRead() nut/fs/fat.c
  FATFileSize() nut/fs/fat.c
  FATMountDrive() nut/fs/fat.c
  FATUnMountDrive() nut/fs/fat.c
References Variables: hFATSemaphore nut/fs/fat.c

Global Function FATSemaInit()

void FATSemaInit ( void )
Calls: NutEventPost()
Called by: FATInit() nut/fs/fat.c
References Variables: hFATSemaphore nut/fs/fat.c

Local Function CFMount()

static void CFMount ( int nDrive )
Calls: FATMountDrive() nut/fs/fat.c
  NutHeapRootAlloc(), NutHeapRootFree()
Used in: FATInit() nut/fs/fat.c

Local Function CFUnMount()

static void CFUnMount ( int nDrive )
Calls: FATUnMountDrive() nut/fs/fat.c
Used in: FATInit() nut/fs/fat.c

Local Function CheckATAPIName()

static char* CheckATAPIName ( char* pLongName )
Called by: FindFileATAPI() nut/fs/fat.c

Local Function FATFileClose()

static int FATFileClose ( NUTFILE* hNUTFile )
Calls: FATFree() nut/fs/fat.c
  FATLock() nut/fs/fat.c
  NutHeapRootFree()
Used in:   nut/fs/fat.c

Local Function FATFileOpen()

static NUTFILE* FATFileOpen ( NUTDEVICE* pDevice, const char* pName, int nMode, int nAccess )
Calls: FATFree() nut/fs/fat.c
  FATInit() nut/fs/fat.c
  FATLock() nut/fs/fat.c
  FindFile() nut/fs/fat.c
  FindFileATAPI() nut/fs/fat.c
  memset() nut/c/string/memset.c
  strchr() nut/c/string/strchr.c
  strlen() nut/c/string/strlen.c
  NutHeapRootAlloc(), NutHeapRootFree(), toupper()
Used in:   nut/fs/fat.c
References Variables: gnIsInit nut/fs/fat.c
  pLongName1 nut/fs/fat.c
  sDriveInfo nut/fs/fat.c

Local Function FATFileWrite()

static int FATFileWrite ( NUTFILE* hNUTFile, const void* pData, int nSize )
Used in:   nut/fs/fat.c

Local Function FATFileWriteP()

static int FATFileWriteP ( NUTFILE* hNUTFile, const prog_char* pData, int nSize )
Used in:   nut/fs/fat.c

Local Function FATInit()

static int FATInit ( NUTDEVICE* pDevice )
Calls: FATMountDrive() nut/fs/fat.c
  FATSemaInit() nut/fs/fat.c
  IDEInit() nut/arch/avr/dev/ide.c
  IDEMountDevice() nut/arch/avr/dev/ide.c
  NutHeapRootAlloc(), NutHeapRootFree()
Called by: FATFileOpen() nut/fs/fat.c
Used in:   nut/fs/fat.c
References Functions: CFMount() nut/fs/fat.c
  CFUnMount() nut/fs/fat.c
References Variables: gnIsInit nut/fs/fat.c

Local Function FATMountDrive()

static int FATMountDrive ( int nDrive )
Calls: FATFree() nut/fs/fat.c
  FATLock() nut/fs/fat.c
  IDEGetSectorSize() nut/arch/avr/dev/ide.c
  IDEIsCDROMDevice() nut/arch/avr/dev/ide.c
  IDEIsZIPDevice() nut/arch/avr/dev/ide.c
  MountATAPI() nut/fs/fat.c
  MountIDE() nut/fs/fat.c
  memset() nut/c/string/memset.c
  NutHeapRootAlloc()
Called by: CFMount() nut/fs/fat.c
  FATInit() nut/fs/fat.c
References Variables: pLongName1 nut/fs/fat.c
  pLongName2 nut/fs/fat.c
  pSectorBuffer nut/fs/fat.c
  sDriveInfo nut/fs/fat.c

Local Function FATUnMountDrive()

static int FATUnMountDrive ( int nDrive )
Calls: FATFree() nut/fs/fat.c
  FATLock() nut/fs/fat.c
Called by: CFUnMount() nut/fs/fat.c
References Variables: sDriveInfo nut/fs/fat.c

Local Function FindFile()

static DWORD FindFile ( DRIVE_INFO* pDrive, FAT32_DIRECTORY_ENTRY* pSearchEntry, char* pLongName, DWORD dwDirCluster, DWORD* pFileSize, int nIsLongName )
Calls: GetFirstSectorOfCluster() nut/fs/fat.c
  GetLongChar() nut/fs/fat.c
  GetNextCluster() nut/fs/fat.c
  IDEReadSectors() nut/arch/avr/dev/ide.c
  memcmp() nut/c/string/memcmp.c
  strlen() nut/c/string/strlen.c
Called by: FATFileOpen() nut/fs/fat.c
References Variables: pLongName2 nut/fs/fat.c
  pSectorBuffer nut/fs/fat.c

Local Function FindFileATAPI()

static DWORD FindFileATAPI ( DRIVE_INFO* pDrive, FAT32_DIRECTORY_ENTRY* pSearchEntry, char* pLongName, DWORD dwDirCluster, DWORD* pFileSize, int nIsLongName )
Calls: CheckATAPIName() nut/fs/fat.c
  IDEReadSectors() nut/arch/avr/dev/ide.c
  RemoveChar() nut/fs/fat.c
  strlen() nut/c/string/strlen.c
  strncmp() nut/c/string/strncmp.c
Called by: FATFileOpen() nut/fs/fat.c
References Variables: pSectorBuffer nut/fs/fat.c

Local Function GetFirstSectorOfCluster()

static DWORD GetFirstSectorOfCluster ( DRIVE_INFO* pDrive, DWORD dwCluster )
Called by: FATFileRead() nut/fs/fat.c
  FindFile() nut/fs/fat.c

Local Function GetLongChar()

static char GetLongChar ( WORD wValue )
Calls: toupper()
Called by: FindFile() nut/fs/fat.c

Local Function GetNextCluster()

static DWORD GetNextCluster ( DRIVE_INFO* pDrive, DWORD dwCluster )
Calls: IDEReadSectors() nut/arch/avr/dev/ide.c
Called by: FATFileRead() nut/fs/fat.c
  FindFile() nut/fs/fat.c
References Variables: pSectorBuffer nut/fs/fat.c

Local Function MountATAPI()

static int MountATAPI ( int nDrive )
Calls: IDEReadSectors() nut/arch/avr/dev/ide.c
Called by: FATMountDrive() nut/fs/fat.c
References Variables: pSectorBuffer nut/fs/fat.c
  sDriveInfo nut/fs/fat.c

Local Function MountIDE()

static int MountIDE ( int nDrive )
Calls: IDEReadSectors() nut/arch/avr/dev/ide.c
Called by: FATMountDrive() nut/fs/fat.c
References Variables: pSectorBuffer nut/fs/fat.c
  sDriveInfo nut/fs/fat.c

Local Function RemoveChar()

static char* RemoveChar ( char* pLongName, BYTE bDir )
Called by: FindFileATAPI() nut/fs/fat.c