www.pudn.com > test_megbox_vc.rar > fat_in.c, change:2003-10-15,size:6188b


/* 
********************************************************************** 
*                          Micrium, Inc. 
*                      949 Crestview Circle 
*                     Weston,  FL 33327-1848 
* 
*                            uC/FS 
* 
*             (c) Copyright 2001 - 2003, Micrium, Inc. 
*                      All rights reserved. 
* 
*********************************************************************** 
 
---------------------------------------------------------------------- 
File        : fat_in.c 
Purpose     : FAT read routines 
---------------------------------------------------------------------- 
Known problems or limitations with current version 
---------------------------------------------------------------------- 
None. 
---------------------------END-OF-HEADER------------------------------ 
*/ 
 
/********************************************************************* 
* 
*             #include Section 
* 
********************************************************************** 
*/ 
 
#include "fs_conf.h" 
#include "fs_port.h" 
#include "fs_dev.h" 
#include "fs_api.h" 
#include "fs_fsl.h" 
#include "fs_int.h" 
#include "fs_os.h" 
#include "fs_lbl.h" 
#include "fs_fat.h" 
 
 
/********************************************************************* 
* 
*             Global functions 
* 
********************************************************************** 
*/ 
 
/********************************************************************* 
* 
*             FS__fat_fread 
* 
  Description: 
  FS internal function. Read data from a file. 
 
  Parameters: 
  pData       - Pointer to a data buffer for storing data transferred 
                from file.  
  Size        - Size of an element to be transferred from file to data 
                buffer 
  N           - Number of elements to be transferred from the file. 
  pFile       - Pointer to a FS_FILE data structure. 
   
  Return value: 
  Number of elements read. 
*/ 
 
FS_size_t FS__fat_fread(void *pData, FS_size_t Size, FS_size_t N, FS_FILE *pFile) { 
  FS_size_t todo; 
  FS_u32 i; 
  FS_u32 j; 
  FS_u32 fatsize; 
  FS_u32 fileclustnum; 
  FS_u32 diskclustnum; 
  FS_u32 prevclust; 
  FS_u32 dstart; 
  FS_u32 dsize; 
  FS_u32 datastart; 
  char *buffer; 
  int err; 
                                             
  if (!pFile) { 
      return 0;  /* No valid pointer to a FS_FILE structure */ 
  } 
  /* Check if media is OK */ 
  err = FS__lb_status(FS__pDevInfo[pFile->dev_index].devdriver, pFile->fileid_lo); 
  if (err == FS_LBL_MEDIACHANGED) { 
    /* Media has changed */ 
    pFile->error = FS_ERR_DISKCHANGED; 
    return 0; 
  } 
  else if (err < 0) { 
    /* Media cannot be accessed */ 
    pFile->error = FS_ERR_READERROR; 
    return 0; 
  } 
  buffer = FS__fat_malloc(FS_FAT_SEC_SIZE); 
  if (!buffer) { 
    return 0; 
  } 
  fatsize = FS__FAT_aBPBUnit[pFile->dev_index][pFile->fileid_lo].FATSz16; 
  if (fatsize == 0) { 
    /* FAT32 */ 
     fatsize = FS__FAT_aBPBUnit[pFile->dev_index][pFile->fileid_lo].FATSz32; 
  } 
  dstart    = FS__FAT_aBPBUnit[pFile->dev_index][pFile->fileid_lo].RsvdSecCnt + FS__FAT_aBPBUnit[pFile->dev_index][pFile->fileid_lo].NumFATs * fatsize; 
  dsize     = ((FS_u32)((FS_u32)FS__FAT_aBPBUnit[pFile->dev_index][pFile->fileid_lo].RootEntCnt) * FS_FAT_DENTRY_SIZE) / FS_FAT_SEC_SIZE; 
  datastart = dstart + dsize; 
  prevclust = 0; 
  todo = N * Size; 
  while (todo) { 
    if (pFile->filepos >= pFile->size) { 
      /* EOF has been reached */ 
      pFile->error = FS_ERR_EOF; 
      FS__fat_free(buffer); 
      return ((N * Size - todo) / Size); 
    } 
    fileclustnum = pFile->filepos / (FS_FAT_SEC_SIZE * FS__FAT_aBPBUnit[pFile->dev_index][pFile->fileid_lo].SecPerClus); 
    if (prevclust == 0) { 
      diskclustnum = pFile->CurClust;  
      if (diskclustnum == 0) { 
        /* Find current cluster by starting at 1st cluster of the file */ 
        diskclustnum = FS__fat_diskclust(pFile->dev_index, pFile->fileid_lo, pFile->fileid_hi, fileclustnum); 
      } 
    } 
    else { 
      /* Get next cluster of the file */ 
      diskclustnum = FS__fat_diskclust(pFile->dev_index, pFile->fileid_lo, prevclust, 1); 
    } 
    prevclust       = diskclustnum; 
    pFile->CurClust = diskclustnum; 
    if (diskclustnum == 0) { 
      /* Could not find current cluster */ 
      pFile->error = FS_ERR_READERROR; 
      FS__fat_free(buffer); 
      return ((N * Size - todo) / Size); 
    } 
    diskclustnum -= 2; 
    j = (pFile->filepos % (FS_FAT_SEC_SIZE * FS__FAT_aBPBUnit[pFile->dev_index][pFile->fileid_lo].SecPerClus))/ FS_FAT_SEC_SIZE; 
    while (1) { 
      if (!todo) { 
        break;  /* Nothing more to write */ 
      } 
      if (j >= (FS_u32)FS__FAT_aBPBUnit[pFile->dev_index][pFile->fileid_lo].SecPerClus) { 
        break;  /* End of the cluster reached */ 
      } 
      if (pFile->filepos >= pFile->size) { 
        break;  /* End of the file reached */ 
      } 
      err = FS__lb_read(FS__pDevInfo[pFile->dev_index].devdriver, pFile->fileid_lo, 
                    datastart + 
                    diskclustnum * FS__FAT_aBPBUnit[pFile->dev_index][pFile->fileid_lo].SecPerClus + j, 
                    (void*)buffer); 
      if (err < 0) { 
        pFile->error = FS_ERR_READERROR; 
        FS__fat_free(buffer); 
        return ((N * Size - todo) / Size); 
      } 
      i = pFile->filepos % FS_FAT_SEC_SIZE; 
      while (1) { 
        if (!todo) { 
          break;  /* Nothing more to write */ 
        } 
        if (i >= FS_FAT_SEC_SIZE) { 
          break;  /* End of the sector reached */ 
        } 
        if (pFile->filepos >= pFile->size) { 
          break;  /* End of the file reached */ 
        } 
        *((char*)(((char*)pData) + N * Size - todo)) = buffer[i]; 
        i++; 
        pFile->filepos++; 
        todo--; 
      } 
      j++; 
    }  /* Sector loop */ 
  }  /* Cluster loop */ 
  if (i >= FS_FAT_SEC_SIZE) { 
    if (j >= FS__FAT_aBPBUnit[pFile->dev_index][pFile->fileid_lo].SecPerClus) { 
      pFile->CurClust = FS__fat_diskclust(pFile->dev_index, pFile->fileid_lo, prevclust, 1); 
    } 
  } 
  FS__fat_free(buffer); 
  return ((N * Size - todo) / Size); 
}