⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fat.c

📁 fat16文件系统源码。需要的请下
💻 C
📖 第 1 页 / 共 3 页
字号:
  {
    /* extract if necessary the next cluster from the allocation list */
    if (dclusters[fat_dchain_index].number == fat_dchain_nb_clust)
    { /* new fragment */
      fat_dchain_index++;
      fat_dchain_nb_clust = 1;
      Hard_read_close();
      Hard_read_open(fat_ptr_data + ((Uint32)(dclusters[fat_dchain_index].cluster) * fat_cluster_size));
      fat_dir_current_sect = fat_ptr_data + ((Uint32)(dclusters[fat_dchain_index].cluster) * fat_cluster_size);
    }
    else
    { /* no new fragment */
      fat_dir_current_sect = fat_ptr_data + ((Uint32)(dclusters[fat_dchain_index].cluster + fat_dchain_nb_clust) * fat_cluster_size);
      fat_dchain_nb_clust++;                /* one more cluster read */
    }
  }
  fat_dclust_byte_count++;                  /* one more byte read */
  return Hard_read_byte();
}



/*F**************************************************************************
* NAME: fat_check_ext
*----------------------------------------------------------------------------
* PARAMS:
*
* return:
*----------------------------------------------------------------------------
* PURPOSE:
*   Return the type of the file
*----------------------------------------------------------------------------
* EXAMPLE:
*----------------------------------------------------------------------------
* NOTE:
*----------------------------------------------------------------------------
* REQUIREMENTS:
*****************************************************************************/
Byte fat_check_ext (void)
{
  if ((fat_cache.current.attributes & ATTR_DIRECTORY) == ATTR_DIRECTORY)
  {
    return FILE_DIR;
  }
  else
  {
    if ((ext[0] == 'M') &&
        (ext[1] == 'P') &&
        (ext[2] == '3'))
    {
      return FILE_MP3;
    }
    else if ((ext[0] == 'W') &&
             (ext[1] == 'A') &&
             (ext[2] == 'V'))
    {
        return FILE_WAV;
    }
    else if ((ext[0] == 'S') &&
             (ext[1] == 'Y') &&
             (ext[2] == 'S'))
    {
          return FILE_SYS;
    }
    else if ((ext[0] == 'W') &&
             (ext[1] == 'M') &&
             (ext[2] == 'A'))
    {
         return FILE_WMA;
    }
    else if ((ext[0] == 'M') &&
             (ext[1] == 'I') &&
             (ext[2] == 'D'))
    {
         return FILE_MID;
    }
    else
    {
          return FILE_XXX;
    }
  }
}


/*F**************************************************************************
* NAME: fat_get_dir_entry
*----------------------------------------------------------------------------
* PARAMS:
*   entry: directory entry structure
*
* return:
*----------------------------------------------------------------------------
* PURPOSE:
*   Get from directory all information about a directory or file entry
*----------------------------------------------------------------------------
* EXAMPLE:
*----------------------------------------------------------------------------
* NOTE:
*   This function reads directly datas from sectors
*   It automaticaly computes difference between LFN and normal entries
*----------------------------------------------------------------------------
* REQUIREMENTS:
*****************************************************************************/
void fat_get_dir_entry (fat_st_dir_entry  *entry)
{
Byte     exit_flag = FALSE;
Byte     lfn_entry_found = FALSE;
INT16U     i;

  for(i=0; i<100; i++)
     lfn_name[i] = '\0';

  while (!exit_flag)
  /* loop while the entry is not a normal one. */
  {
    /* read the directory entry */
    if (dir_is_root == TRUE)
    { /* root dir is linear -> Hard_read_byte() */
      for (i = 0; i < DIR_SIZE; i++)
        gl_buffer[i] = Hard_read_byte();
    }
    else
    { /* subdir can be fragmented -> dgetc() */
      for (i = 0; i < DIR_SIZE; i++)
        gl_buffer[i] = fat_dgetc();
    }

    /*computes gathered data*/
    /* check if we have a LFN entry */
    if (gl_buffer[11] != ATTR_LFN_ENTRY)
    {
      if (!lfn_entry_found)
      {
        /* true DOS 8.3 entry format */
        for (i = 0; i < 8; i++)
        {
          lfn_name[i] = gl_buffer[i];
          
          if (lfn_name[i] == ' ')
          { /* space is end of name */
            break;
          }
        }
        /* append extension */
        lfn_name[i++] = '.';
        lfn_name[i++] = gl_buffer[8];
        lfn_name[i++] = gl_buffer[9];
        lfn_name[i++] = gl_buffer[10];

        for (; i != 14; i++)
        {
          lfn_name[i] = ' ';       /* append spaces for display reason */
        }
        lfn_name[i] = '\0';        /* end of string */
      }
        
      else
      { /* LFN name treatment */
        i = 0;
        /* search for the end of the string */
        while (lfn_name[i] != '\0')
        { 
          i++;
        }
        if (i <= 14)
        { /* append spaces for display reason (no scrolling) */
          while (i != 14)
          {
            lfn_name[i++] = ' ';
          }
        }
        else
        { /* append beginning of name to ease scrolling display */
          lfn_name[i++] = ' ';
          lfn_name[i++] = ' ';
          lfn_name[i++] = lfn_name[0];
          lfn_name[i++] = lfn_name[1];
          lfn_name[i++] = lfn_name[2];
          lfn_name[i++] = lfn_name[3];
          lfn_name[i++] = lfn_name[4];
          lfn_name[i++] = lfn_name[5];
          lfn_name[i++] = lfn_name[6];
          lfn_name[i++] = lfn_name[7];
          lfn_name[i++] = lfn_name[8];
          lfn_name[i++] = lfn_name[9];
          lfn_name[i++] = lfn_name[10];
          lfn_name[i++] = lfn_name[11];
          lfn_name[i++] = lfn_name[12];
        }
        lfn_name[i] = '\0';        /* end of name */
      }

      /* store extension */
      ext[0]= gl_buffer[8];
      ext[1]= gl_buffer[9];
      ext[2]= gl_buffer[10];

      /* standard computing for normal entry */
      entry->attributes = gl_buffer[11];
      entry->start_cluster = gl_buffer[26];
      entry->start_cluster += ((Uint16) gl_buffer[27]) << 8;
      entry->size.b[3] = gl_buffer[28];
      entry->size.b[2] = gl_buffer[29];
      entry->size.b[1] = gl_buffer[30];
      entry->size.b[0] = gl_buffer[31];
      /* now it's time to stop */
      exit_flag = TRUE;
    }
    else
    { /* LFN entry format */
      lfn_entry_found = TRUE;             /* a 8.3 name will follow */

      if ((gl_buffer[0] & LFN_SEQ_MASK) <= MAX_LFN_ENTRIES)   
      {                         /* Maximum number of entries for LFN? */
        for (i = 0; i < 5; i++)
		 {
	     // song_name[i] = gl_buffer[2*i + 1]+gl_buffer[2*i + 1 + 1]*256;
          lfn_name[i + 13*((gl_buffer[0] & LFN_SEQ_MASK) - 1)] = gl_buffer[2*i + 1];
		  }
        for (i = 0; i < 6; i++)
		 {
		 // song_name[i + 5] = gl_buffer[2*i + 14]+gl_buffer[2*i + 14 + 1]*256;
          lfn_name[i + 5 + 13*((gl_buffer[0] & LFN_SEQ_MASK) - 1)] = gl_buffer[2*i + 14];
		 }
        for (i = 0; i < 2; i++)
		 {
          lfn_name[i + 11 + 13*((gl_buffer[0] & LFN_SEQ_MASK) - 1)] = gl_buffer[2*i + 28];
		 }
      }
    }
  }  
  Hard_read_close();                        /* close physical read */
}


/*F**************************************************************************
* NAME: fat_get_dir_file_list
*----------------------------------------------------------------------------
* PARAMS:
*   id: file extension to select
*
* return:
*----------------------------------------------------------------------------
* PURPOSE:
*   Construct the file directory list
*----------------------------------------------------------------------------
* EXAMPLE:
*----------------------------------------------------------------------------
* NOTE:
*   The value are relative position with the previous file.
*   Call to this function assume that the dir fragment chain has been created
*----------------------------------------------------------------------------
* REQUIREMENTS:
*   Maximum of 256 entries between 2 authorized file (id extension)
*   because the relative position is stored on one byte.
*   To allow more than 256 entries (-> 32768), change type of
*   fat_dir_entry_list[] from Byte to Uint16 (no overflow management)
*   and change MAX_DIRECTORY_GAP_FILE from 255 to 32767
*****************************************************************************/
void fat_get_dir_file_list (Byte id)
{
Uint16 index;                               /* chain index */
Uint16 counter_entry;                       /* entry counter: 0..MAX_DIRECTORY_FILE */
Uint16 entry_pos;                           /* relative entry position */
Uint16 entry_pos_saved;                     /* used when the file is not the id etension */
Byte   i;
   
  index = 0;
  fat_dir_list_last = 0;
  counter_entry = 0;
  entry_pos = 0;   
  fat_dir_start_sect = fat_dir_current_sect;
  fat_dir_current_offs = 0;

  Hard_read_open(fat_dir_start_sect);
  
  do /* scan all entries */
  {
    if (dir_is_root == TRUE)
    { /* root dir is linear -> Hard_read_byte() */
      for (i = 0; i < DIR_SIZE; i++)
        gl_buffer[i] = Hard_read_byte();
    }
    else
    { /* subdir can be fragmented -> dgetc() */
      for (i = 0; i < DIR_SIZE; i++)
        gl_buffer[i] = fat_dgetc();
    }
    counter_entry++;                          /* increase the # entry         */

    if ((gl_buffer[0] != FILE_DELETED) && (gl_buffer[0] != FILE_NOT_EXIST))
    { /* Existing file ? */ 
      fat_dir_entry_list[index] = entry_pos;  /* save the relative position   */

      entry_pos_saved = entry_pos;
      entry_pos = 1;                          /* reset the relative position  */
      index++;                                /* increase the index           */

      while (gl_buffer[11] == ATTR_LFN_ENTRY) /* LFN entry ?                  */
      {                                       /* then read all the LFN entry  */
        if (dir_is_root == TRUE)
        { /* root dir is linear -> Hard_read_byte() */
          for (i = 0; i < DIR_SIZE; i++)
            gl_buffer[i] = Hard_read_byte();
        }
        else
        { /* subdir can be fragmented -> dgetc() */
          for (i = 0; i < DIR_SIZE; i++)
            gl_buffer[i] = fat_dgetc();
        }

        counter_entry++;                    /* increase the # entry */
        entry_pos++;                        /* increase the relative position */
                                            /* for the next file */
      }

      /* filter on the file type */
      fat_cache.current.attributes = gl_buffer[11];
      ext[0] = gl_buffer[8];
      ext[1] = gl_buffer[9];
      ext[2] = gl_buffer[10];
      if ((fat_check_ext() & id) == FILE_XXX)
      {                                     /* Don't valid the entry */
        index--;                                              
        entry_pos += entry_pos_saved;
      }
    }
    else   /* Not an existing file */    
      entry_pos++;

    fat_dir_list_last = index;              /* update last file index */
    /* For sub-directory, there is no logical limit for the number of entries */
    /* In order to detect the last file, we check gl_buffer[0]                */
    /* We can put in the chain directory MAX_DIRECTORY_FILE selected file     */
    if (gl_buffer[0] == FILE_NOT_EXIST)
      index = MAX_DIRECTORY_FILE;
    /* Overflow of entry_pos */
    if (entry_pos > MAX_DIRECTORY_GAP_FILE)
      index = MAX_DIRECTORY_FILE;
    /* For Root directory, the maximum entries is 512!                        */
    if ((dir_is_root == TRUE) && (counter_entry == MAX_DIRECTORY_FILE))
      index = MAX_DIRECTORY_FILE;

    if (dir_is_root == FALSE)
    {
      /* check if we are at the end of the directory */
    //  if ((((Byte*)&fat_dclust_byte_count)[1] == 0x00) &&
    //     ((((Byte*)&fat_dclust_byte_count)[0] & fat_cluster_mask) == 0x00) && 
    
        if( ((Byte)(fat_dclust_byte_count) == 0x00) && 
            ((((Byte)(fat_dclust_byte_count >> 8)) & fat_cluster_mask) == 0x00) &&
            (fat_last_dclust_index == fat_dchain_index) 
          )
      
        index = MAX_DIRECTORY_FILE;
    }
  }
  while (index < MAX_DIRECTORY_FILE);

  fat_dir_current_sect = fat_dir_start_sect;
  Hard_read_close();
}



/*F**************************************************************************
* NAME: fat_get_root_directory
*----------------------------------------------------------------------------
* PARAMS:
*   id: file extension to select
*
* return:
*   - OK: file available
*   - KO: no requested file found
*   - KO: low_level memory error
*----------------------------------------------------------------------------
* PURPOSE:
*   Select first available file/dir in root diretory
*----------------------------------------------------------------------------
* EXAMPLE:
*----------------------------------------------------------------------------
* NOTE:
*   Fill all the cache information for the first time
*----------------------------------------------------------------------------
* REQUIREMENTS:
*****************************************************************************/
Byte fat_get_root_directory (Byte id)
{
  /* select first root dir entry */
  fat_dir_current_sect = fat_ptr_rdir;
  fat_dclust_byte_count = 0;
  dir_is_root = TRUE;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -