网站公告列表

  没有公告

加入收藏
设为首页
联系站长
您现在的位置: 61IC中国电子在线 >> DSP >> 代码示例 >> ADI DSP代码示例 >> Blackfin >> 文章正文
  ADSP-BF533 文件系统(C)源代码         ★★★ 【字体:
ADSP-BF533 文件系统(C)源代码
作者:61IC    文章来源:本站原创    点击数:    更新时间:2007-1-22    

/************************************************************************
* File         : filesystem.c
* Processor    : ADSP-BF533 
* IDDE         : VisualDSP++3.5
* Description  : Define operating functions of FAT32, includes:
*                 
*            Wait_Ready();
*            Wait_ReadyBusy();
*            CheckforError();
*            IdeStandby();
*            IdeIdle();
*
*************************************************************************/
#include "fat/filesystem.h"
#include "fat/fat32.h"
#include "IDE/ide_access.h"
#include "IDE/ide_base.h"
#include "type.h"


partition_table_t *partition_table[23];
FS_t fs;

extern BYTE fnUpdateFILE(FILE_t *fp);
extern currentcluster_t fnFAT32_WriteSector(currentcluster_t,DWORD);

extern unsigned int cycles[100];

/******************************************************************
* Function     : fnDetect_Partition
* Description : get HD DPT information
* Input     : none
* Return   : none
*******************************************************************/
void fnDetect_Partition(void)
{
 BYTE partition_num=0;
 BYTE temp;
 BYTE master_table_buffer[64];
 BYTE *table_buffer;
 BYTE i;
 
 DWORD LBABEGIN;
 DWORD EXT_next_partition;
  
  // Load MBR (LBA 0) into the 512 byte buffer
 fnIDE_BufferSector(&(buffers.currentsector),0,1); 
  
  // Make Sure 0x55 and 0xAA are at end of sector
 if (fnIDE_SectorWord(SIGN_POSITION)!=SIGN_VALUE)
 {
  printf("\r\nInvalid MBR, Please Format Drive\r\n");
  while(1);
 }
 //read main DPT (4 partitions)
 fnIDE_SectorData(PARTITION_TABLE_1,master_table_buffer,sizeof(master_table_buffer));
 //
 table_buffer=(BYTE*)malloc(sizeof(BYTE)*PARTITION_TABLE_SIZE);
 
 for (i=0;i<4;i++)
 {
  temp=master_table_buffer[i*PARTITION_TABLE_SIZE+SYSTEM_ID];
  //Processing Extended Aartition
  if((temp==EXT_TYPECODE1)||(temp==EXT_TYPECODE2))
  {
   memcpy(table_buffer,master_table_buffer+i*PARTITION_TABLE_SIZE,PARTITION_TABLE_SIZE);
   while(temp!=NO_PARTITION)
   {
    EXT_next_partition =table_buffer[OFFSET_SECTOR];
    EXT_next_partition+=((DWORD)table_buffer[OFFSET_SECTOR+1])<<8;
    EXT_next_partition+=((DWORD)table_buffer[OFFSET_SECTOR+2])<<16;
    EXT_next_partition+=((DWORD)table_buffer[OFFSET_SECTOR+3])<<24;
    fnIDE_BufferSector(&(buffers.currentsector),EXT_next_partition,1);
    
    fnIDE_SectorData(PARTITION_TABLE_1,table_buffer,sizeof(table_buffer));
    fnPartition_init(table_buffer,partition_num);
    partition_num++;
    fnIDE_SectorData(PARTITION_TABLE_2,table_buffer,sizeof(table_buffer));
    temp=table_buffer[SYSTEM_ID];
   }
   continue;
  }
  else if(temp==NO_PARTITION)
  {
   break;
  }
  
  memcpy(table_buffer,master_table_buffer+i*PARTITION_TABLE_SIZE,PARTITION_TABLE_SIZE);
  fnPartition_init(table_buffer,partition_num);
  partition_num++;
 }
 for(i=partition_num;i<23;i++)
 {
  partition_table[i]=NULL;
 }
 free(table_buffer);
 if(partition_num==0)
 {
  printf("The Disk isn't partitioned\r\n");
  return;
 }
}
/******************************************************************
* Function     : fnPartition_init
* Description : Initialize DPT, get DPT inforamtion
* Input     :
*              BYTE *buffer-informatioin of DPT
*              BYTE num-partition number
* Return   : none
*******************************************************************/
void fnPartition_init(BYTE *buffer,BYTE num)
{
 BYTE temp;
 temp=buffer[SYSTEM_ID];
 if ((temp==FAT32_TYPECODE1)||(temp==FAT32_TYPECODE2)||(temp==FAT32_TYPECODE3))
 {
  partition_table[num]=(partition_table_t *)malloc(sizeof(partition_table_t));
  partition_table[num]->flag=1;
  partition_table[num]->fs=(FS_t *)malloc(sizeof(FS_t));
  partition_table[num]->fnFS_init = fnFAT32_init;
 }
 else if ((temp==FAT16_TYPECODE1)||(temp==FAT16_TYPECODE2)||(temp==FAT16_TYPECODE3))
 {
  /*partition_table[num]=(partition_table_t *)malloc(sizeof(partition_table_t));
  partition_table[num]->flag=1;
  partition_table[num]->fs=(FS_t *)malloc(sizeof(FS_t));
  partition_table[num]->fnFS_init = fnFAT16_init;*/
 }
 else
 {
  partition_table[num]=(partition_table_t *)malloc(sizeof(partition_table_t));
  partition_table[num]->flag=0;
  return;
 }

 partition_table[num]->offset_sector = buffer[OFFSET_SECTOR];
 partition_table[num]->total_sector = buffer[TOTAL_SECTOR];
 partition_table[num]->fnFS_init(partition_table[num]->fs,partition_table[num]->offset_sector);
}

/******************************************************************
* Function     : fnFATMisc_If_LFN_TextOnly
* Description : Check long file name
* Input     :
*              BYTE recordoffset-offset of long file name entry in buffers
* Return   : yes-1/no-0
*******************************************************************/
int fnFATMisc_If_LFN_TextOnly(DWORD recordoffset)
{
 if ((fnIDE_SectorByte(recordoffset+11)&0x0F)==FILE_ATTR_LFN_TEXT)
  return 1;
 else
  return 0;
}

/******************************************************************
* Function     : fnFATMisc_If_LFN_Invalid
* Description : Check the entry wheter ignorable, ignore the entry if the entry is null or deleted
* Input     :
*              BYTE recordoffset-offset of long file name entry in buffers
* Return   : yes-1/no-0
*******************************************************************/
int fnFATMisc_If_LFN_Invalid(DWORD recordoffset)
{
 if ((fnIDE_SectorByte(recordoffset)==FILE_HEADER_BLANK)||(fnIDE_SectorByte(recordoffset)==FILE_HEADER_DELETED))//||(fnIDE_SectorByte(recordoffset+11)==FILE_ATTR_VOLUME_ID)||(fnIDE_SectorByte(recordoffset+11)&FILE_ATTR_SYSHID))
     return 1;
 else
  return 0;
}
/******************************************************************
* Function     : fnFATMisc_If_LFN_Exists
* Description : Check whether a long file name.
* Input     :
*              BYTE recordoffset-offset of long file name entryin buffers
* Return   : yes-1/no-0
*******************************************************************/
int fnFATMisc_If_LFN_Exists(DWORD recordoffset, BYTE LFNstrings)
{
 if ((fnIDE_SectorByte(recordoffset+11)!=FILE_ATTR_LFN_TEXT) && (fnIDE_SectorByte(recordoffset)!=FILE_HEADER_BLANK) && (fnIDE_SectorByte(recordoffset)!=FILE_HEADER_DELETED) /*&& (fnIDE_SectorByte(recordoffset+11)!=FILE_ATTR_VOLUME_ID) && (!(fnIDE_SectorByte(recordoffset+11)&FILE_ATTR_SYSHID))*/ && (LFNstrings))
  return 1;
 else
  return 0;
}
/******************************************************************
* Function     : fnFATMisc_If_noLFN_SFN_Only
* Description : Check whether not long file name only
* Input     :
*              BYTE recordoffset-offset of long file name entry in buffers
* Return   : yes-1/no-0
*******************************************************************/
int fnFATMisc_If_noLFN_SFN_Only(DWORD recordoffset)
{
 if ((fnIDE_SectorByte(recordoffset+11)!=FILE_ATTR_LFN_TEXT) && (fnIDE_SectorByte(recordoffset)!=FILE_HEADER_BLANK) && (fnIDE_SectorByte(recordoffset)!=FILE_HEADER_DELETED) /*&& (fnIDE_SectorByte(recordoffset+11)!=FILE_ATTR_VOLUME_ID) && (!(fnIDE_SectorByte(recordoffset+11)&FILE_ATTR_SYSHID))*/)
  return 1;
 else
  return 0;
}
/******************************************************************
* Function     : fnFATMisc_If_dir_entry
* Description : Check whether directory entry
* Input     :
*              BYTE recordoffset-offset of long file name entry in buffers
* Return   : yes-1/no-0
*******************************************************************/
int fnFATMisc_If_dir_entry(DWORD recordoffset)
{
 if ((fnIDE_SectorByte(recordoffset+11))&FILE_ATTR_DIRECTORY)
  return 1;
 else
  return 0;
}
/******************************************************************
* Function     : fnFATMisc_cacheLFN
* Description : fetch long file name entry - ASCII charaters
* Input     :
*              BYTE recordoffset-offset of long file name entry in buffers
*    BYTE LFNIndex-long file name entry number
*    BYTE *String-destinated address of store long file name
* Return   : BYTE numbers of ASCII charaters
*******************************************************************/
BYTE fnFATMisc_cacheLFN(WORD recordoffset,BYTE LFNIndex,BYTE *String)
{
 BYTE i;
 BYTE String_offset;
 //charater location in long file name entry
 BYTE char_locate[13]={1,3,5,7,9,0x0E,0x10,0x12,0x14,0x16,0x18,0x1C,0x1E};
 BYTE sub_size;   
  
 String_offset = 0;
 for(i=1;i<LFNIndex;i++)
 {
  String_offset += 13;
 } 
 sub_size=13; 
 for(i=0;i<13;i++)
 {

              //Charaters in long file name are encoded in unicode format.
  String[String_offset+i] = fnIDE_SectorByte(recordoffset+char_locate[i]);
  if(String[String_offset+i]==0)
  {
   sub_size=i;
   break;
  }
 }
 
 for (i=0; i<13; i++)
    if (String[String_offset+i]==0xFF)
     String[String_offset+i] = 0x0; // Replace with space
       //exclude '/0'
 return sub_size;
}
/******************************************************************
* Function     : fnGetChksum
* Description : get check code from 11 bytes in short file name
* Input     :
*              BYTE *shortname-address of short file name
* Return   : BYTE check code
*******************************************************************/
BYTE fnGetChksum(BYTE *shortname)
{
 BYTE i,j=0;
 BYTE chksum=0;
     for (i=11; i>0; i--)
         chksum = ((chksum & 1) ? 0x80 : 0) + (chksum >> 1) + shortname[j++];
        return chksum;
}

/******************************************************************
* Function     : fnFindFile_LongName
* Description : get long file name pointer
* Input     :
*              DWORD sector_num-sector number that contain file entry
*              WORD  item-entry number of file entry in current sector
*              DWORD up_folder-starting sector of up directory
*              BYTE  *String_buffer- size of file name
*              FILE_t *file-file pointer
* Return   : none
*******************************************************************/
void fnFindFile_LongName(DWORD sector_num,WORD item,DWORD up_folder,BYTE *String_buffer,WORD name_size,FILE_t *file) 
{
 WORD recordoffset=item*32;
 file->flag  |= MODE_OPEN;
 file->startcluster  = (DWORD)fnIDE_SectorWord(recordoffset+0x1A);
 file->startcluster += ((DWORD)fnIDE_SectorWord(recordoffset+0x14))<<16;
 file->currentcluster.value =file->startcluster;
 file->currentcluster.offset = 0;

 file->curp  = 0;
 file->type  = fnIDE_SectorByte(recordoffset+0x0B);
 file->filesize  = fnIDE_SectorDWORD(recordoffset+0x1C);
 
 memcpy(file->filename,String_buffer,name_size);
 file->filename[name_size]=0;
 file->listp=sector_num*16+item;
 file->up_folder=up_folder;
}

/******************************************************************
* Function     : fnFindFile_ShortName
* Description : get short file name pointer
* Input     :
*              DWORD sector_num-sector number that contain file entry
*              WORD  item-entry number of file entry in current sector
*              DWORD up_folder-starting sector of up directory
*              BYTE  *String_buffer- size of file name
*              FILE_t *file-file pointer
* Return   : none
*******************************************************************/
 
void fnFindFile_ShortName(DWORD sector_num,BYTE item,DWORD up_folder,FILE_t *file)
{
 BYTE i,j=0;
 BYTE temp;
 WORD recordoffset=item*32;
 file->flag  |= MODE_OPEN;
 file->startcluster  = (DWORD)fnIDE_SectorWord(recordoffset+0x1A);
 file->startcluster += ((DWORD)fnIDE_SectorWord(recordoffset+0x14))<<16;
 file->currentcluster.value =file->startcluster;
 file->currentcluster.offset = 0;
 
 file->curp  = 0;
 file->type  = fnIDE_SectorByte(recordoffset+0x0B);
 file->filesize  = fnIDE_SectorDWORD(recordoffset+0x1C);
 
 for(i=0;i<8;i++)
 {
  temp = fnIDE_SectorByte(recordoffset+i);
  if(temp!=0x20)
  {
   file->filename[i] = __tolower(temp);
  }
  else
  {
   break;
  }
 }
 if(fnIDE_SectorByte(recordoffset+8)!=0x20)
 {
  file->filename[i]='.';
  i++;
  for(j=0;j<3;j++)
  {
   temp = fnIDE_SectorByte(recordoffset+8+j);
   if(temp!=0x20)
   {
    file->filename[i+j] = __tolower(temp);
   }
   
   else
   {
    file->filename[i+j] = '\0';
    break;
   }
  }
 }
 else
 {
  file->filename[i]='\0';
 }
 
 file->filename[i+j] = '\0';
 file->listp=sector_num*16+item;
 file->up_folder=up_folder;
 return;
 
}
/******************************************************************
* Function     : fnDetectDirectory
* Description : get numbers of files and directores in current directory
* Input     :
*              DWORD startcluster-starting sector of curret directory
* Return   :DWORD amount of files and directories
*******************************************************************/ 
DWORD fnDetectDirectory(DWORD startcluster)
{
 BYTE item;
 WORD recordoffset;
 DWORD x=0;
 BYTE stringnum=0;
 DWORD filenum=0;
 currentcluster_t current_cluster;
 
 current_cluster.value=startcluster;
 current_cluster.offset=0;
 
 while (current_cluster.value!= 0xFFFFFFFF) // Do while not end of cluster chain
 {
  // Read Sector
  current_cluster = fnFAT32_SectorReader(current_cluster, x++);

  if (current_cluster.value!=0xFFFFFFFF)
  {
   for (item=0; item<=15;item++)
   {
     recordoffset = (32*item);
      if ( fnFATMisc_If_LFN_Exists(recordoffset,stringnum) )
     {
               filenum++; //File / Dir Count
              }
              else if ( fnFATMisc_If_noLFN_SFN_Only(recordoffset) )
     {
       filenum++; //File / Dir Count
      }
   }// end of for
  }
 }
 return filenum;
}

/******************************************************************
* Function     : fnListDirectory
* Description : open a directory, get all file pointers of all files in the directory and store them in FILELIST_t.
* Input     :
*              DWORD startcluster-starting sector of curret directory
* Return   :FILELIST_t file list pointer
*******************************************************************/
FILELIST_t* fnListDirectory(DWORD startcluster)
{
 BYTE i,item,index;
 WORD recordoffset;
 BYTE LFNIndex=0;
 DWORD x=0;
 currentcluster_t current_cluster;
 
 BYTE stringnum=0,next_num=0;
 BYTE chksum;
 DWORD filenumber=0;
 BYTE String_buffer[20*13];
 BYTE short_name[11];
 WORD name_size=0;
 
 current_cluster.value=startcluster;
 current_cluster.offset=0;
 
 FILELIST_t *filelist=NULL;
 
 
       //get numbers of files in current directory
 filenumber = fnDetectDirectory(startcluster);
 
 
 filelist=(FILELIST_t *)malloc(sizeof(FILELIST_t));
 filelist->list=(FILE_t **)malloc(sizeof(FILE_t *)*(filenumber));
 filelist->num=filenumber;
 
 if(filenumber==0)
 {
  
  return NULL;
 }
 
 filenumber=0;
 
  
 while (current_cluster.value!= 0xFFFFFFFF) // Do while not end of cluster chain
 {
  // Read Sector
  current_cluster = fnFAT32_SectorReader(current_cluster, x++);

  if (current_cluster.value!=0xFFFFFFFF)
  {
   LFNIndex=0;
   for (item=0; item<=15;item++)
   {
     recordoffset = (32*item);
    //check entry type
     if ( fnFATMisc_If_LFN_Invalid(recordoffset) )  
     {
                                   //invalid entry
      stringnum = 0;
      name_size = 0;
      next_num =0 ;
      continue;
     }
    // Long File Name Text Found
    else if ( fnFATMisc_If_LFN_TextOnly(recordoffset) )
    {
     // if file name entry
     if(stringnum==0)
     { 
                                     //check last entry by checking bit-7, first byte in file name entry
      if((fnIDE_SectorByte(recordoffset)&0x40)!=0)
      {
       LFNIndex  =fnIDE_SectorByte(recordoffset)&0x1F;
       stringnum = LFNIndex;
       next_num  = stringnum;
       chksum   = fnIDE_SectorByte(recordoffset+0x0D);
      }
      else
      {
                                                 // do nothing if bit-7 is not '1'.
       continue;
      }
     }
     else
     {     
            // check file name serial number and check code, correct-get file name charaters, error-reset with 0
      if(((fnIDE_SectorByte(recordoffset)&0x1F)==next_num)&&(fnIDE_SectorByte(recordoffset+0x0D)==chksum))
      {
       LFNIndex =(fnIDE_SectorByte(recordoffset)&0x1F);
      }
      else
      {
       stringnum = 0;
        name_size = 0;
        next_num =0 ;
        continue;
       }
      }
     name_size += fnFATMisc_cacheLFN(recordoffset,LFNIndex,String_buffer);
     next_num--;
    }
     // Normal Entry and Long text exists
     else if ( fnFATMisc_If_LFN_Exists(recordoffset,stringnum) )
     {
      filelist->list[filenumber]=(FILE_t*)malloc(sizeof(FILE_t));
      fnIDE_SectorData(recordoffset,short_name,11);
     // check file name serial number and check code, correct-get long file name charaters, error-get short file name
      if((next_num!=0)||(chksum!=fnGetChksum(short_name)))
       fnFindFile_ShortName(x-1,item,startcluster,filelist->list[filenumber]);
      else
       fnFindFile_LongName(x-1,item,startcluster,String_buffer,name_size,filelist->list[filenumber]);
      filenumber++;
      stringnum = 0;
      name_size = 0;
      next_num =0 ;  
                  
     }
  
     // Normal Entry, only 8.3 Text  
     else if ( fnFATMisc_If_noLFN_SFN_Only(recordoffset) )
     {
      filelist->list[filenumber]=(FILE_t*)malloc(sizeof(FILE_t));
      fnFindFile_ShortName(x-1,item,startcluster,filelist->list[filenumber]);
              filenumber++;
      stringnum = 0;
      name_size = 0;
      next_num =0 ;
     }
   }// end of for
  }
 }
 return filelist;
 
}

/******************************************************************
* Function     : fnFindFile
* Description : search a file or directory.
* Input     :
*              DWORD startcluster-starting sector of curret directory
*              BYTE* filename-target file name
*              BYTE mode -file type: file or directory
* Return   :FILE_t - file pointer if found, or none
*******************************************************************/
FILE_t *fnFindFile(DWORD startcluster,BYTE *filename,BYTE mode)
{
 BYTE i,item,index;
 WORD recordoffset;
 BYTE LFNIndex=0;
 DWORD x=0;
 currentcluster_t current_cluster;
 
 BYTE stringnum=0,next_num=0;
 BYTE chksum;
 DWORD filenumber=0;
 BYTE String_buffer[20*13];
 BYTE short_name[11];
 WORD name_size=0;
 FILE_t *fp;
 
 
 current_cluster.value = startcluster;
 current_cluster.offset = 0;
 
 fp = (FILE_t*)malloc(sizeof(FILE_t));
 fp->flag=0; 
 //
 while (current_cluster.value!= 0xFFFFFFFF) // Do while not end of cluster chain
 {
  // Read Sector
  current_cluster = fnFAT32_SectorReader(current_cluster, x++);

  if (current_cluster.value!=0xFFFFFFFF)
  {
   LFNIndex=0;
   for (item=0; item<=15;item++)
   {
     recordoffset = (32*item);
      //check entry type
     if ( fnFATMisc_If_LFN_Invalid(recordoffset) )  
     {
                               // check file name, reset with 0 if invalid
      stringnum = 0;
      name_size = 0;
      next_num =0 ;
      continue;
     }
    // Long File Name Text Found
    else if ( fnFATMisc_If_LFN_TextOnly(recordoffset) )
    {
     //if long file name entry
     if(stringnum==0)
     {
       //check last entry by checking bit-7, first byte in file name entry
      if((fnIDE_SectorByte(recordoffset)&0x40)!=0)
      {
       LFNIndex  =fnIDE_SectorByte(recordoffset)&0x1F;
       stringnum = LFNIndex;
       next_num  = stringnum;
       chksum   = fnIDE_SectorByte(recordoffset+0x0D);
      }
      else
      {
       continue;
      }
     }
     else
     {
      if(((fnIDE_SectorByte(recordoffset)&0x1F)==next_num)&&(fnIDE_SectorByte(recordoffset+0x0D)==chksum))
      {
       LFNIndex =(fnIDE_SectorByte(recordoffset)&0x1F);
      }
      else
      {
       stringnum = 0;
        name_size = 0;
        next_num =0 ;
        continue;
       }
      }
     name_size += fnFATMisc_cacheLFN(recordoffset,LFNIndex,String_buffer);
     next_num--;
    }
     // Normal Entry and Long text exists
     else if ( fnFATMisc_If_LFN_Exists(recordoffset,stringnum) )
     {
      //check search mode and entry type matched or not.
      if(((fnIDE_SectorByte(recordoffset+0x0B)&FILE_ATTR_DIRECTORY)==0&&mode==FIND_FILE_MODE)||
         ((fnIDE_SectorByte(recordoffset+0x0B)&FILE_ATTR_DIRECTORY)!=0&&mode==FIND_DIR_MODE)||
         (mode==FIND_ALL_MODE))
      {
       fnIDE_SectorData(recordoffset,short_name,11);
       if((next_num!=0)||(chksum!=fnGetChksum(short_name)))
        fnFindFile_ShortName(x-1,item,startcluster,fp);
       else
        fnFindFile_LongName(x-1,item,startcluster,String_buffer,name_size,fp);
       
       filenumber++;
       stringnum = 0;
       name_size = 0;
       next_num =0 ;
       i=0;
       while(1)
       {
        if(__tolower(filename[i])!=__tolower(fp->filename[i]))
        {
         break;
        }
        if(filename[i]=='\0')
        {
         return fp;
        }
        i++;
       }
      }
                    
     }
  
     // Normal Entry, only 8.3 Text  
     else if ( fnFATMisc_If_noLFN_SFN_Only(recordoffset) )
     {
      if(((fnIDE_SectorByte(recordoffset+0x0B)&FILE_ATTR_DIRECTORY)==0&&mode==FIND_FILE_MODE)||
         ((fnIDE_SectorByte(recordoffset+0x0B)&FILE_ATTR_DIRECTORY)!=0&&mode==FIND_DIR_MODE)||
         (mode==FIND_ALL_MODE))
      {
       fnFindFile_ShortName(x-1,item,startcluster,fp);
               filenumber++;
       i=0;
       while(1)
       {
        if(__tolower(filename[i])!=__tolower(fp->filename[i]))
        {
         break;
        }
        if(filename[i]=='\0')
        {
         return fp;
        }
        i++;
       }
      
       stringnum = 0;
       name_size = 0;
       next_num =0 ;
      }
      
      
     }
   }// end of for
  }
 }
 free(fp);
 return fp;
}

/******************************************************************
* Function     : fnReadFile
* Description : read a file into data buffer
* Input     :
*              BYTE *buffer-data buffer addess
*              BYTE size-size of data entry
*              DWORD count -number of data entry
*              FILE_t *fp-file pointer
* Return   :DWORD count of reading data
*******************************************************************/
DWORD fnReadFile(BYTE *buffer, BYTE size, DWORD count, FILE_t *fp)
{

 
 DWORD read_num;
 DWORD  offset,sp1,sp2,length;
 DWORD bytepercluster = current_fs->byte_per_cluster;
 DWORD bytepersector = current_fs->bpb.byte_per_sector;
 BYTE  *rbuffer;
 DWORD remain;
 
 rbuffer=buffers.currentsector.u8data;
 //which sector *fp locates 
 offset=fp->curp/bytepersector;

 //sp1 is starting address of target sector
 sp1=fp->curp-offset*bytepersector;
 
 read_num=size*count;
 //counting  reading data, cut data if overflow
 if((read_num+fp->curp)>fp->filesize)
 {
  read_num=fp->filesize-fp->curp;
 }
 //length: numbers of Byte will be read next operation
 //if length more than one sector, cut length or do next reading operation?
 if(read_num>bytepersector-sp1)
 {
  length=bytepersector-sp1;
 }
 else
 {
  length=read_num;
 }
       //start reading data, follow 3 cases
       //case1-start sector-target data start is not the start of the sector
       //case2-reading data-target data is a whole data sector
       //case3-end sector-target data is not the ead of the sector
      
 //case1-read the first sector
 fp->currentcluster = fnFAT32_SectorReader(fp->currentcluster,offset);
 memcpy(buffer,rbuffer+sp1,length);
 
 fp->curp=fp->curp+length;
 remain=read_num-length;
 sp2 = length;
 offset = offset +1;
 if(remain==0)
  return read_num;
 
 //case2
  while(remain>bytepersector)
  {
   fp->currentcluster = fnFAT32_SectorReader(fp->currentcluster,offset);
   memcpy(buffer+sp2,rbuffer,bytepersector); 
   fp->curp = fp->curp+bytepersector;
   //sp1=(fp->curp%bytepercluster)%bytepersector;
   sp2 += bytepersector;
   remain =remain-bytepersector;
   offset = offset+1;
  }
 
 //case3
 fp->currentcluster = fnFAT32_SectorReader(fp->currentcluster,offset);
 memcpy(buffer+sp2,rbuffer,remain);
 fp->curp=fp->curp+remain;
 
 return read_num;
}
/******************************************************************
* Function     : fnFreeFile
* Description : Free a file(free the chain) when the target file is O_TRUNC and O_WRONLY
* Input     :
*              DWORD startcluster -start sector of the file
* Return   :none
*******************************************************************/
void fnFreeFile(DWORD startcluster)
{
 DWORD cluster_chain;
 DWORD cluster_temp;
 
 if(startcluster==0)
  return;
 cluster_chain=startcluster;
 while (cluster_chain!=0xFFFFFFFF)
 {
  cluster_temp=fnFAT32_FindNextCluster(cluster_chain);
  fnFAT32_EditFat(cluster_chain,0x00000000);
  cluster_chain=cluster_temp;
 }
}

/******************************************************************
* Function     : fnOpenFile
* Description : after get file pointer via finFindFile, open a file
* Input     :
*              FILE_t *fp-file pointer
*              BYTE mode-open mode
* Return   :FILE_t *p
*******************************************************************/ 
FILE_t * fnOpenFile(FILE_t* fp,BYTE mode)
{
 DWORD cluster_chain=0;
 DWORD cluster_temp=0;
 DWORD i;
 // check file properties
 if((fp->type&FILE_ATTR_HIDDEN)||(fp->type&FILE_ATTR_SYSTEM)||(fp->type&FILE_ATTR_SYSHID)
    ||(fp->type&FILE_ATTR_VOLUME_ID ))
 {
  return 0;
 }
 //can not open read-only file by open mode-writable
 else if(fp->type&FILE_ATTR_READ_ONLY)
 {
  if((mode&O_WRONLY)||(mode&O_RDWR))
  {
   return 0;
  }
 }
 else
 {
  //initial operation on open mode
  if((mode&O_TRUNC)&&(mode&O_WRONLY))
  {
   fnFreeFile(fp->startcluster);
   fp->startcluster=0;
   fp->currentcluster.value=0;
   fp->currentcluster.offset=0;
   fp->curp=0;
   fp->filesize = 0; 
  }
  if(mode&O_APPEND)
  {
   if(fp->filesize!=0)
   {
    
    fp->curp = fp->filesize;
    cluster_temp=fp->startcluster;
    i=0;
    while (cluster_temp!=0xFFFFFFFF)
    {
     cluster_chain=cluster_temp;
     cluster_temp=fnFAT32_FindNextCluster(cluster_chain);
     i++;
    }
    fp->currentcluster.value = cluster_chain;
    fp->currentcluster.offset = i-1;
   }
  }
 }
  
 return fp;
}

/******************************************************************
* Function     : fnWriteFile
* Description : write a data section from data buffer to target file
* Input     :
*              BYTE *buffer-data buffer address
*              BYTE size-data unit size
*              DWORD count-number of data unit-data section size
*              FILE_t *fp-file pointer
* Return   :DWORD wrote data section size
*******************************************************************/
DWORD fnWriteFile(BYTE *buffer, BYTE size, DWORD count, FILE_t *fp)
{
 DWORD write_num=size*count;
 DWORD  offset,offset1,sp1,sp2,length;
 DWORD bytepercluster = current_fs->bpb.byte_per_sector*current_fs->bpb.sector_per_cluster;
 WORD bytepersector = current_fs->bpb.byte_per_sector;
 BYTE  *wbuffer;
 DWORD remain_write,remain_place;
 DWORD cluster_temp;
 DWORD old_filesize=fp->filesize;
 
 wbuffer=buffers.currentsector.u8data;
 //get sector number that contain the current file
 offset=fp->curp/bytepersector;
 //get offest of current sector in current clustor
 offset1= offset%current_fs->bpb.sector_per_cluster;

 //modify file size if it overflows
 if(fp->curp+write_num>fp->filesize)
 {
  fp->filesize=fp->curp+write_num;
 }
 //get starting address of writing
 sp1=fp->curp-offset*bytepersector;//(fp->curp%bytepercluster)%bytepersector;

 //get starting address of buffer
 sp2=0;

 //remain_write: left mumber of bytes which not be writtin in buffer
 remain_write=write_num;

 //remain_place: left space in current cluster
 remain_place=bytepercluster-fp->curp%bytepercluster;
 
  while(1)
  {
         //read in source sector
   if(fp->curp<old_filesize)
   {
    fp->currentcluster = fnFAT32_SectorReader(fp->currentcluster,offset);
   }
   
   //length: mumber of bytes in one copy operation
   length=remain_write;
   if(length>bytepersector-sp1)
   {
    length=bytepersector-sp1;
   }
   //create a new cluster if length > main_place or current custer is invalid
   if((length>remain_place)&&(fp->currentcluster.value==0xFFFFFFFF)) 
   {
    
    fp->currentcluster.value = fnFAT32_NextEmptyCluster(cluster_temp);

                            //modify the size of file if fail in creating a new cluster, return
    if(fp->currentcluster.value==0xFFFFFFFF)
    {
     if(fp->filesize>old_filesize)
     {
      fp->filesize=fp->curp;
     }
     return sp2;
    }
    //在FAT_buffer中修改簇链
    fnFAT32_EditFatChain(cluster_temp,fp->currentcluster.value);
    fnFAT32_EditFatChain(fp->currentcluster.value,0x0FFFFFFF);
    remain_place +=bytepercluster;
   }
   memcpy(wbuffer+sp1,buffer+sp2,length); 
   //stop_cycle();
   fp->currentcluster=fnFAT32_WriteSector(fp->currentcluster,offset);
   //enable_cycle();
   offset++;
   offset1++;
   fp->curp = fp->curp+length;
   sp1=0;//(fp->curp%bytepercluster)%bytepersector;
   sp2 += length;
   if(sp2>=write_num)
    break;
   remain_write -=length;
   remain_place -=length;
   if(offset1 == current_fs->bpb.sector_per_cluster)
   {
    offset1 = 0;
    cluster_temp=fp->currentcluster.value;
    fp->currentcluster.value=fnFAT32_FindNextCluster(fp->currentcluster.value);
    fp->currentcluster.offset++;
   }
   
  }
  //refresh FAT
  fnFAT32_UpdateFAT(fp->currentcluster.value);
  //refresh file directory
  fnUpdateFILE(fp);
  return write_num;
 //}
}

/******************************************************************
* Function     : fnDeleteFileLabel
* Description : remove dedicated file units in previous sector
* Input     :
*              FILE_t *fp-file pointer
* Return   :BYTE number of removed file units
*******************************************************************/

BYTE fnDeleteFileLabel(FILE_t *fp)
{
 int label=fp->listp%16;
 DWORD offset=fp->listp/16;
 BYTE label_num1=0;
 currentcluster_t current_cluster={fp->up_folder,0};

 
 fnFAT32_SectorReader(current_cluster,offset);
 //insert remove flag
 fnIDE_WriteSectorByte(label*32,0xE5);
 while(1)
 { 
  // return label_num1 if go to the end of current directory
  if(label==0&&offset==0)
  {
   return label_num1;
  }
  label--;
  //do following stuffs when label reach to previous sector
  //write current sector and read previous sector, keep searching

  if(label<0)
  {
   fnFAT32_WriteSector(current_cluster,offset);
   offset--;
   label=15;
   fnFAT32_SectorReader(current_cluster,offset);
  }
  //delete previous label if it is valid file name unit.
  if((fnIDE_SectorByte(label*32)!=0xE5)&&(fnIDE_SectorByte(label*32+0x0B)==0x0F))
  {
   label_num1++;
   fnIDE_WriteSectorByte(label*32,0xE5);
  }
  else
  {
   break;
  }
 }
 //write back last modified sector
 fnFAT32_WriteSector(current_cluster,offset);
 return label_num1;
}

 

/******************************************************************
* Function     : fnFindEmptyLabel
* Description : search empty file units to store record of a new created file in up folder
* Input     :
*              DWORD startcluster -start sector of file
*              BYTE n - number of units in long file name
* Return   :WORD label offset
*******************************************************************/

WORD fnFindEmptyLabel(DWORD startcluster,BYTE n)
{
 DWORD labe_per_cluster=current_fs->bpb.sector_per_cluster*16;
 WORD label_offset=0;
 WORD  sector_offset=0;
 BYTE  idle_label=0;
 DWORD next_cluster;
 currentcluster_t current_cluster={startcluster,0};
 
 while(1)
 {
  if(label_offset%16==0)
  {
   //get next secotr
   current_cluster=fnFAT32_SectorReader(current_cluster,sector_offset);
   //create a new cluster for up folder if get no next sector
   if(current_cluster.value==0xFFFFFFFF)
   {
    next_cluster=fnFAT32_NextEmptyCluster(current_cluster.value);
    if(next_cluster==0xFFFFFFFF)
    {
     return 0xFFFF;
    }
    fnFAT32_EditFatChain(current_cluster.value,next_cluster);
    fnFAT32_EditFatChain(next_cluster,0x0FFFFFFF);
    current_cluster.value=next_cluster;
   }
   sector_offset++;
  }

  if((fnIDE_SectorByte(label_offset%16*32)==0xE5)||(fnIDE_SectorByte(label_offset%16*32)==0x00))
  {
   idle_label++;
  }
  else
  {
   idle_label=0;
  }
  if(idle_label>n)
  {
   break;
  }
  label_offset++;  
 }

 fnFAT32_UpdateFAT(current_cluster.value);
 return label_offset;
}

/******************************************************************
* Function     :  fnWriteFileLabel
* Description : write file infor. to up folder
* Input     :
*              FILE_t *fp - file pointer
*              file_lable_t - address of file infor. unit buffer
*             int label - address of file infor. unit
*             int label_num - number of long file name infor. unit
* Return   :BYTE 1 or 0-error
*******************************************************************/

BYTE fnWriteFileLabel(FILE_t *fp,file_label_t *buffer,int label,int label_num)
{
 WORD i,j,label_count=0,sector_offset=label/16;
 int label_offset=label%16;
 lfn_label_t *lfn_buffer;
 BYTE chksum;
 BYTE data_buffer[32];
 BYTE name_len=strlen(fp->filename);
 currentcluster_t current_cluster={fp->up_folder,0};
 
 lfn_buffer=(lfn_label_t *)malloc(sizeof(lfn_label_t));
 
 fnFAT32_SectorReader(current_cluster,sector_offset);

 fnIDE_WriteSectorData(label_offset*32,(BYTE *)buffer,32);
 
 if(label_num==0)
 {
  fnFAT32_WriteSector(current_cluster,sector_offset);
  free(lfn_buffer);
  return 1;
 }
 
 chksum=fnGetChksum(buffer->short_name);

 while(1)
 {
  label_offset--; 
  if(label_offset<0)
  {
   sector_offset--;
   label_offset=15;
   fnFAT32_WriteSector(current_cluster,sector_offset+1);
   fnFAT32_SectorReader(current_cluster,sector_offset);
  }
  
  i=13*label_count;
  for(j=0;j<5;j++)
  {
    
   if(i==name_len)
   {
    lfn_buffer->name1[j]=0x0000;
    i++;
   }
   else if(i>name_len)
   {
    lfn_buffer->name1[j]=0xFFFF;
   }
   else
   {
    lfn_buffer->name1[j]=(WORD)fp->filename[i++];
   }
  }
  for(j=0;j<6;j++)
  {
   if(i==name_len)
   {
    lfn_buffer->name2[j]=0x0000;
    i++;
   }
   else if(i>name_len)
   {
    lfn_buffer->name2[j]=0xFFFF;
   }
   else
   {
    lfn_buffer->name2[j]=(WORD)fp->filename[i++];
   }
  }
  for(j=0;j<2;j++)
  {
   if(i==name_len)
   {
    lfn_buffer->name3[j]=0x0000;
    i++;
   }
   else if(i>name_len)
   {
    lfn_buffer->name3[j]=0xFFFF;
   }
   else
   {
    lfn_buffer->name3[j]=(WORD)fp->filename[i++];
   }
  }
 
  if(label_count==label_num-1)
  {
   lfn_buffer->num=(label_count+1)|0x40;
  }
  else
  {
   lfn_buffer->num=(label_count+1);
  }
  lfn_buffer->flag=0x0F;
  lfn_buffer->reserve=0;
  lfn_buffer->chksum=chksum;
  lfn_buffer->startcluster=0;
  
  data_buffer[0]=lfn_buffer->num;
  memcpy(data_buffer+1,lfn_buffer->name1,13);
  memcpy(data_buffer+14,lfn_buffer->name2,18);
  
  fnIDE_WriteSectorData(label_offset*32,data_buffer,32);
  if(label_count==label_num-1)
  {
   break;
  }
  label_count++;
 }
 fnFAT32_WriteSector(current_cluster,sector_offset);  
 free(lfn_buffer);
 return 1;
}

/******************************************************************
* Function     :  fnGetShortNum
* Description : number files which have same short file names
* Input     :
*              FILE_t *fp - file pointer
*              BYTE *short_name - short file name
* Return   :BYTE serial number
*******************************************************************/

BYTE fnGetShortNum(FILE_t *fp,BYTE *short_name)
{
 BYTE item;
 WORD recordoffset=0;
 DWORD x=0;
 BYTE name[11];
 BYTE num=1,temp;;
 BYTE refind=0;
 currentcluster_t current_cluster={fp->up_folder,0};
  
 while (current_cluster.value!= 0xFFFFFFFF) // Do while not end of cluster chain
 {
  // Read Sector
  current_cluster = fnFAT32_SectorReader(current_cluster, x++);

  if (current_cluster.value!=0xFFFFFFFF)
  {
   for (item=0; item<=15;item++)
   {
    recordoffset = (32*item);
    if(((x*16+item)!=fp->listp)&&(fnIDE_SectorByte(recordoffset)!=0xE5))
    {
      fnIDE_SectorData(recordoffset,name,11);
      if(strncmp(short_name+8,name+8,3)!=0)
       continue;
      if((strncmp(short_name,name,4)==0)&&(name[4]=='~'))
      {
       temp=num%100;
       if((name[5]==(num/100+'0'))&&(name[6]==(temp/10+'0'))&&(name[7]==(temp%10+'0')))
       {
        num++;
        refind=1;
        break;
       }
      }
     }
    }
   }
   if(refind==1)
   {
    refind=0;
    current_cluster.value=fp->up_folder;
    current_cluster.offset=0;
    x=0;
   }
 }
          
 return num;
}

/******************************************************************
* Function     :   fnUpdateFILE
* Description : update file infor. including file name, file size, etc
* Input     :
*              FILE_t *fp - file pointer
* Return   :BYTE 1
*******************************************************************/

BYTE fnUpdateFILE(FILE_t *fp)
{
 int i,j;
 file_label_t *buffer;
 BYTE short_name[11]="           ";
 BYTE ext[256]="   ";
 BYTE name[256];
 int label_num1,label_num2,label,temp;
 DWORD offset;
 BYTE type=0;
 //type = 0 - normal short
 //type =1 - normal long
 //type=2 - short, caps
 //type=3 - short, blank
 
 currentcluster_t currentcluster={fp->up_folder,0};
 
 buffer=(file_label_t *)malloc(sizeof(file_label_t));
 fnFAT32_SectorReader(currentcluster,fp->listp/16);
 fnIDE_SectorData((fp->listp%16)*32,(BYTE *)buffer,32);

 //remove original file directory
 label_num1=fnDeleteFileLabel(fp);

 //get file name and extended file name
 for(i=strlen(fp->filename);i>0;i--)
 {
  if(fp->filename[i]=='.')
  {
   memcpy(ext,fp->filename+i+1,strlen(fp->filename)-i);
   memcpy(name,fp->filename,i);
   name[i]='\0';
   break;
  }
 }
 if(i==0)
 {
  memcpy(name,fp->filename,strlen(fp->filename)+1);
 }

 //get file type
 if((strlen(name)<=8)&&(strlen(ext)<=3))
 {
  type=0;
  label_num2=0;
  for(i=0;name[i]!='\0';i++)
  {
   if((name[i]<='Z'&&name[i]>='A'))
   {
    type=2;
    label_num2=1;
    break;
   }
   if(name[i]==' '||name[i]=='.')
   { 
    type=3;
    label_num2=1;
    break;
   }
  }
  for(i=0;ext[i]!='\0';i++)
  {
   if((ext[i]<='Z'&&ext[i]>='A'))
   {
    type=2;
    label_num2=1;
    break;
   }
  }
 }
 else
 {
  label_num2=(strlen(fp->filename)-1)/13+1;
  type=1;
 }
 
 //get file starting
 if(label_num2>label_num1)
 {
  label=fnFindEmptyLabel(fp->up_folder,label_num2);
  fp->listp=label;
 }
 else
 {
  label=fp->listp;
 }
 //get short file name with 'type'
 switch(type)
 {
  case 0:
  case 2:
  {
   memcpy(short_name,name,strlen(name));
   memcpy(short_name+8,ext,strlen(ext));
   for(i=0;i<11;i++)
   {
    if(short_name[i]!=' ')
    {
     if(short_name[i]<='z'&&short_name[i]>='a')
      short_name[i]=short_name[i]-0x20;
    }
   }
   break;
  }
  case 1:
  case 3:
  {
   if(strlen(ext)<=3)
   {
    memcpy(short_name+8,ext,strlen(ext));
   }
   else
   {
    memcpy(short_name+8,ext,3);
   }
   for(i=0,j=0;i<strlen(name);i++)
   {
    if(name[i]==' '||name[i]=='.')
     continue;
    short_name[j]=__toupper(name[i]);
    j++;
    if(j==4)
     break;
   }
   for(i=0,j=8;i<strlen(ext);i++)
   {
    if(ext[i]==' '||ext[i]=='.')
     continue;
    short_name[j]=__toupper(ext[i]);
    j++;
    if(j==11)
     break;
   }
   
   temp=fnGetShortNum(fp,short_name);
   short_name[4]='~';

   short_name[5]=temp/100+'0';
   temp=temp%100;
   short_name[6]=temp/10+'0';
   short_name[7]=temp%10+'0';
   
   for(i=0;i<11;i++)
   {
    if(short_name[i]!=' ')
    {
     if(short_name[i]<='z'&&short_name[i]>='a')
      short_name[i]=short_name[i]-0x20;
    }
   }
   
   break;
  }
 }

 //handle '.' &'..' directories
 if(strcmp(fp->filename,".")==0||strcmp(fp->filename,"..")==0)
 {
  for(i=0;i<11;i++)
   short_name[i]=0x20;
  memcpy(short_name,fp->filename,strlen(fp->filename)+1);
  label_num2=0;
  label=label-1;
 }
 
 memcpy(buffer->short_name,short_name,11);
 buffer->type = fp->type;
 buffer->filesize=fp->filesize;
 buffer->cluster_high=(WORD)fp->startcluster>>16;
 buffer->cluster_low=(WORD)fp->startcluster;
 buffer->create_time_10ms = 0;
 buffer->create_time = 0;
 buffer->create_date = 0;
 buffer->last_visit_date = 0;
 buffer->last_edit_time = 0;
 buffer->last_edit_date = 0;

 //write back undated file label to HD driver
 fnWriteFileLabel(fp,buffer,label,label_num2);
 
 free(buffer);
 return 1;
}


/******************************************************************
    创建一个文件
用途: 创建一个文件,赋文件指针
输入: DWORD startcluster 上一级目录起始扇区
 BYTE *name 文件名
输出: FILE_t * 文件指针
*********************************************************************/ 
FILE_t *fnCreateFile(DWORD startcluster,BYTE *name)
{
 FILE_t *fp;
 fp=(FILE_t *)malloc(sizeof(FILE_t));
 fp->listp=fnFindEmptyLabel(startcluster,0);
 if(fp->listp==0xFFFF)
 {
  return NULL;
 }
 fp->flag=MODE_OPEN;
 fp->startcluster=0;//=fnFAT32_NextEmptyCluster(2);
 //fnFAT32_EditFat(fp->startcluster,0x0FFFFFFF);
 fp->curp =0;
 memcpy(fp->filename,name,strlen(name)+1);
 fp->type = 0x20;
 fp->filesize =0; 
 fp->up_folder = startcluster;
 
 fnUpdateFILE(fp);

 
 
 return fp;
}

/******************************************************************
    创建一个目录
用途: 创建一个目录
输入: DWORD startcluster 上一级目录起始扇区
 BYTE *name 文件名
输出: void
******************************************************************/
BYTE fnCreateDir(DWORD startcluster,BYTE *name)
{
 FILE_t *fp;
 DWORD current_cluster;
 
 fp=(FILE_t *)malloc(sizeof(FILE_t));
 fp->listp=fnFindEmptyLabel(startcluster,0);
 if(fp->listp==0xFFFF)
 {
  return 0;
 }
 fp->flag=0;
 fp->startcluster=fnFAT32_NextEmptyCluster(2);
 fnFAT32_EditFat(fp->startcluster,0x0FFFFFFF);
 current_cluster= fp->startcluster;
 fp->curp =0;
 memcpy(fp->filename,name,strlen(name)+1);
 fp->type = FILE_ATTR_DIRECTORY;
 fp->filesize =0; 
 fp->up_folder = startcluster;
 
 fnUpdateFILE(fp);
 
 fp->listp=fnFindEmptyLabel(current_cluster,0);
 if(fp->listp==0xFFFF)
 {
  return 0;
 }
 fp->flag=0;
 fp->startcluster=current_cluster;
 fp->curp =0;
 memcpy(fp->filename,".",2);
 fp->type = FILE_ATTR_DIRECTORY;
 fp->filesize =0; 
 fp->up_folder = current_cluster;
 fnUpdateFILE(fp);
 
 fp->listp=fnFindEmptyLabel(current_cluster,0);
 if(fp->listp==0xFFFF)
 {
  return 0;
 }
 fp->flag=0;
 fp->startcluster=startcluster;
 fp->curp =0;
 memcpy(fp->filename,"..",3);
 fp->type = FILE_ATTR_DIRECTORY;
 fp->filesize =0; 
 fp->up_folder = current_cluster;
 fnUpdateFILE(fp);
 
 

 
 free(fp);
 return 1;

/******************************************************************
* Function     :   fnSearchFile
* Description : search files in dedicated directories (recursive function)
* Input     :
*              DWORD startcluster - starting sector of dedicated directory
*              BYTE *name - file name
*              BYTE level - directories depth
*              BYTE *num - number of searched files
*              FILELIST_t *fl - searched files in file list
* Return   :void
*******************************************************************/

void fnSearchFile(DWORD startcluster,BYTE * name,BYTE level,BYTE *num,FILELIST_t *fl)
{
 DWORD i=0,j=0;
 FILE_t *fp;
 FILELIST_t *filelist;
 
 fp=(FILE_t *)malloc(sizeof(FILE_t));
 if(level>5)
 {
  //do five level search here
  return;
 }

 //get files and directory infor. in current direcotry
 filelist=fnListDirectory(startcluster);
 while(i<filelist->num)
 {
  //do nothing with '.' & '..' direcotries
  if((strcmp(filelist->list[i]->filename,".")==0)||(strcmp(filelist->list[i]->filename,"..")==0))
  {
   i++;
   continue;
  }
  //do recursion to directory here
  if(filelist->list[i]->type&FILE_ATTR_DIRECTORY)
  {
   fnSearchFile(filelist->list[i]->startcluster,name,level,num,fl);
  }
  else
  {
   j=0;
   while(1)
    {
    //compare every character of file name, break is error or reach to end of file name
     if(__tolower(filelist->list[i]->filename[j])!=__tolower(name[j]))
     {
      break;
     }
     if(filelist->list[i]->filename[j]=='\0')
     {
      break;
     }
     j++;
    }
   //list file names if matched
   if((filelist->list[i]->filename[j]=='\0')&&(name[j]=='\0'))
   {
    if(*num>=255)
    {
     break;
    }
    memcpy(fp,filelist->list[i],sizeof(FILE_t));
    fl->list[*num]=fp;
    *num=(*num)+1;
   }
   else
   {
    i++;
    continue;
   }

  }
  i++;
 }
 for(i=0;i<filelist->num;i++)
 {
  free(filelist->list[i]);
 }
 free(filelist->list);
 free(filelist);
 __fclose(fp);
 return;
}


/******************************************************************
* Function     :   fnGetCurrentCluster
* Description : get current cluster
* Input     :
*              DWORD curp - file operating pointer
*              DWORD startcluster - starting cluster
* Return   :currentcluster_t - current cluster
*******************************************************************/
currentcluster_t fnGetCurrentCluster(DWORD curp,DWORD startcluster)
{
 DWORD i;
 DWORD cluster_chain=startcluster;
 DWORD offset=curp/(current_fs->bpb.byte_per_sector*current_fs->bpb.sector_per_cluster);
 currentcluster_t cluster;
 
 for(i=0;i<offset;i++)
 {
  cluster_chain=fnFAT32_FindNextCluster(cluster_chain);
  if(cluster_chain==0xFFFFFFFF)
   break;
 }
 cluster.value = cluster_chain;
 cluster.offset = i;
 return cluster;
}

               欢迎点击进入:TI德州中文网   (国内唯一针对TI应用的中文技术网站)    文章录入:admin    责任编辑:admin 
  • 上一篇文章:

  • 下一篇文章:
  • 发表评论】【加入收藏】【告诉好友】【打印此文】【关闭窗口
    最新热点 最新推荐 相关文章
    基于ADSP-BF533的最小系统设…
    基于ADSP-BF533处理器的去方…
    ADSP-BF533 IDE_Base(C)源代…
    ADSP-BF533 IDE Access(C)源…
    ADSP-BF533 FAT32 Base(C)源…
      网友评论:(只显示最新10条。评论内容只代表网友观点,与本站立场无关!)
    站长:61IC 湘ICP备05002478号