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

📄 fat_file.c

📁 fat16文件系统源码。需要的请下
💻 C
📖 第 1 页 / 共 3 页
字号:

#define  FAT_GLOBAL

#include "type.h"
#include "global.h"
#include "hard.h"
#include "fat.h" 
#include "fat_h.h"   

#include <string.h>



//---------------------------------------------------------------------------------
void fat_read_sector(INT32U u32Sector)
{
   phy_read_open(u32Sector);
   phy_read_sector();
   phy_read_close();  
}



//---------------------------------------------------------------------------------
INT32U fat_U8_to_U32_LH(INT8U LSB, INT8U L, INT8U M, INT8U MSB)
{
   INT32U U32;
   
   U32 = ( ((INT32U)MSB) << 24 ) + ( ((INT32U)M) << 16 ) + ( ((INT32U)L) << 8 ) + LSB;
   return U32;
}


//---------------------------------------------------------------------------------
INT16U fat_U8_to_U16_LH(INT8U LSB, INT8U MSB)
{
   INT16U U16;
   
   U16 = ( ((INT16U)MSB) << 8 ) + LSB;
   return U16;
}



/*F**************************************************************************
* NAME: fat_initialize
*----------------------------------------------------------------------------
* PARAMS: none
*
* return:
*   - OK: intallation succeeded
*   - KO: - partition is not active
*         - FAT type is not FAT16 or FAT12
*         - MBR or PBR signatures are not correct
*         - low level read open failure
*----------------------------------------------------------------------------
* PURPOSE:
*   Install the fat system, read mbr, bootrecords...
*----------------------------------------------------------------------------
* NOTE:
*   if MBR not found, try to mount unpartitionned FAT
*   fat_ptr_fats = partition offset + nb_reserved_sector
*   fat_ptr_rdir = fat_ptr_fat + fat_size * nb_fat
*   fat_ptr_data = fat_ptr_rdir + nb_root_entries * 32 / sect_size
*----------------------------------------------------------------------------
* REQUIREMENTS:
*****************************************************************************/
Byte fat_initialize(void)
{          
	Byte i;
	Uint32 tot_sect;
	Uint32 fat_nb_sector;

  /* read and check usefull MBR info */
  /* go to the first partition field */
 //	fat_is_fat32 = 0;
 //	fat_is_fat16 = 0;

    fat_read_sector(MBR_ADDRESS);  // go to first partition entry

    /* check first partition state */
	if(gl_buffer[446]!=PARTITION_ACTIVE)
    {
       fat_ptr_fats = 0x00000000;            /* disk may not be partitionned */
    }
    else
    {
	     // ((Byte*)&fat_ptr_fats)[3] = gl_buffer[454];
	     // ((Byte*)&fat_ptr_fats)[2] = gl_buffer[455];
	     // ((Byte*)&fat_ptr_fats)[1] = gl_buffer[456];
	     // ((Byte*)&fat_ptr_fats)[0] = gl_buffer[457];  
	      
	      fat_ptr_fats = fat_U8_to_U32_LH(gl_buffer[454], gl_buffer[455], gl_buffer[456], gl_buffer[457]); 
	      
	      /* go to the MBR signature field */
	
	      if ((gl_buffer[510] != LOW(BR_SIGNATURE)) ||
	          (gl_buffer[511] != HIGH(BR_SIGNATURE)))    
	      {
	        fat_ptr_fats = 0x00000000;          /* disk may not be partitionned */
	      }
    }

    /* read and check usefull PBR info */
    fat_read_sector(fat_ptr_fats);

	//((Byte*)&fat_sector_size)[1] = gl_buffer[11];
	//((Byte*)&fat_sector_size)[0] = gl_buffer[12];
	
    fat_sector_size = fat_U8_to_U16_LH(gl_buffer[11], gl_buffer[12]);

    if((fat_sector_size != 512) && (fat_sector_size != 2048))
	{
	   if((gl_buffer[510] == 0x55) && (gl_buffer[511] == 0xaa))
	   {
	       Uint16 u16Count = 0;
	       while(1)
		   {
	          fat_read_sector(++ fat_ptr_fats);
	          
			  if((gl_buffer[0] == 0xeb)||(gl_buffer[0] == 0xe9))
			  {
			  	// ((Byte*)&fat_sector_size)[1] = gl_buffer[11];
		        // ((Byte*)&fat_sector_size)[0] = gl_buffer[12];
		         fat_sector_size = fat_U8_to_U16_LH(gl_buffer[11], gl_buffer[12]);
		         
	             if((fat_sector_size == 512)||(fat_sector_size == 2048))
				 {
                    break;
                 }
			  }
			  u16Count++;
			  if(u16Count == 0xFFFF)
			  {
                 break;
			  }
		   }
		}
	}

    /* read cluster size (in sector) */
    fat_cluster_size = gl_buffer[13]; //Hard_read_byte();
//    fat_cluster_mask = HIGH((Uint16)fat_cluster_size * fat_sector_size) - 1;
    /* compute FATs sector address: add reserved sector number */
    fat_ptr_fats += gl_buffer[14];
    fat_ptr_fats += ((Uint16)(gl_buffer[15])) << 8;  
    /* read number of FATs */
    i = gl_buffer[16];
    if (i == 2)
       fat_2_is_present = TRUE;
    else
      fat_2_is_present = FALSE;
    /* read number of dir entries  and compute rdir offset */
    

   // ((Byte*)&fat_ptr_data)[3] = gl_buffer[17];
   // ((Byte*)&fat_ptr_data)[2] = gl_buffer[18];
   // ((Byte*)&fat_ptr_data)[1] = 0;
   // ((Byte*)&fat_ptr_data)[0] = 0;
   
    fat_ptr_data = fat_U8_to_U32_LH(gl_buffer[17],gl_buffer[18],0,0); 

	fat_root_entries = (Uint16)(fat_ptr_data);

    fat_ptr_data = (fat_ptr_data * DIR_SIZE) /fat_sector_size;

	/* read number of sector in partition (<32Mb) */
	//((Byte*)&fat_nb_sector)[3] =  gl_buffer[19];
	//((Byte*)&fat_nb_sector)[2] =  gl_buffer[20];
	//((Byte*)&fat_nb_sector)[1] = 0x00;
	//((Byte*)&fat_nb_sector)[0] = 0x00;
	fat_nb_sector = fat_U8_to_U32_LH(gl_buffer[19],gl_buffer[20],0,0);
  
    /* read number of sector in partition (>32Mb) */
    //((Byte*)&fat_nb_sector)[3] += gl_buffer[32]; 
    //((Byte*)&fat_nb_sector)[2] += gl_buffer[33]; 
   // ((Byte*)&fat_nb_sector)[1] += gl_buffer[34]; 
   // ((Byte*)&fat_nb_sector)[0] += gl_buffer[35]; 
   
    fat_nb_sector = fat_U8_to_U32_LH(gl_buffer[32],gl_buffer[33],gl_buffer[34],gl_buffer[35]);
////////////////////////////////////////////////////////////////////////////////////
	//((Byte*)&fat_fat_size)[3] = gl_buffer[22]; 
   // ((Byte*)&fat_fat_size)[2] = gl_buffer[23]; 
    //((Byte*)&fat_fat_size)[1] = 0; 
   // ((Byte*)&fat_fat_size)[0] = 0;	
    fat_fat_size = fat_U8_to_U32_LH(gl_buffer[22],gl_buffer[23],0,0);

	if(fat_fat_size == 0)
	{
		//((Byte*)&fat_fat_size)[3] += gl_buffer[36]; 
	   // ((Byte*)&fat_fat_size)[2] += gl_buffer[37]; 
	   // ((Byte*)&fat_fat_size)[1] += gl_buffer[38]; 
	   // ((Byte*)&fat_fat_size)[0] += gl_buffer[39];
	   fat_fat_size = fat_U8_to_U32_LH(gl_buffer[36],gl_buffer[37],gl_buffer[38],gl_buffer[39]);
	   
	}
    
	fat_ptr_rdir = i * fat_fat_size;
	fat_ptr_rdir += fat_ptr_fats;
/////////////////////////////////////////////////////////////////////////////////////
    tot_sect = fat_nb_sector - (1 + (i * fat_fat_size) + fat_ptr_data);
    fat_count_of_clusters = tot_sect / fat_cluster_size;

    if (fat_count_of_clusters <= MAX_CLUSTERS12)
       fat_type_id = FAT_IS_12;
    else if (fat_count_of_clusters <= MAX_CLUSTERS16)
        fat_type_id = FAT_IS_16;
	else
	{
		fat_type_id = FAT_IS_32;
		
		//((Byte*)&fat32_root_cluster)[3] = gl_buffer[44];
		//((Byte*)&fat32_root_cluster)[2] = gl_buffer[45];
		//((Byte*)&fat32_root_cluster)[1] = gl_buffer[46];
		//((Byte*)&fat32_root_cluster)[0] = gl_buffer[47];
		fat32_root_cluster = fat_U8_to_U32_LH(gl_buffer[44],gl_buffer[45],gl_buffer[46],gl_buffer[47]);
	}
    /* else is FAT32 not supported */

    /* compute data sector address */
    fat_ptr_data += fat_ptr_rdir;

	fat_max_cluster_number = (Uint16)(104857600 /(((Uint32)fat_sector_size) * fat_cluster_size)) + 2;

//	fat_2_is_present = 0;	// improve speed

    /* go to the signature field */
    if(0x200 != fat_sector_size)
	     return KO;

     return OK;
}


/*F**************************************************************************
* NAME: fat_goto_rootdir
*----------------------------------------------------------------------------
* PARAMS: none
*----------------------------------------------------------------------------
* PURPOSE:
*   go to root diretory
*----------------------------------------------------------------------------
* REQUIREMENTS:
*****************************************************************************/
void fat_goto_rootdir(void)
{
	Byte i;
   	fat_dir_current_sect = fat_ptr_rdir;
   	fat_dclust_byte_count = 0;
   	fat_dir_sector_offset = 0;
    fat_fsave_read_handle = 0;
   	dir_is_root = TRUE;

	//init fsave struct
	fat_fsave_index = 0;
	for(i=0; i<MAX_SUBDIR_DEPTH; i++)
	{
		fat_fsave[i].index = 0;
		fat_fsave[i].file = SCAN_XXX;	
	}


#if COMPILE_FAT_32 == TRUE
	if(fat_type_id == FAT_IS_32)
	{
		fat_cache.current.start_cluster.l = fat32_root_cluster;
		fat_get_clusters(&dclusters, MAX_DIR_FRAGMENT_NUMBER);
	}
#endif
	
}

/*F**************************************************************************
* NAME: fat_get_dir_entry
*----------------------------------------------------------------------------
* PARAMS:
*   entry: directory entry structure
* return: none
*----------------------------------------------------------------------------
* PURPOSE:
*   Get from directory all information about a directory or file entry
*----------------------------------------------------------------------------
* 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;
	Byte    i;
	Uint16  num;
	Uint16  j;
	Byte flag;
	byte count;

  	num = fat_dir_sector_offset; /*number of bytes to seek in a cluster*/
  	flag = FALSE;
  	count = 0;

 	for (i=MAX_FILENAME_LEN; i!=0; lfn_name[--i] = '\0');

  	phy_read_sector();

  	//num = num%fat_sector_size;

  	while (!exit_flag)
  	/* loop while the entry is not a normal one. */
  	{
	    /* read the directory entry */
      	if(flag == TRUE)
      	{
		    if ((dir_is_root == TRUE)&&(fat_type_id != FAT_IS_32))
		    { 
				 if((num%fat_sector_size)==0)
				 {
				  	  //phy_read_open(fat_ptr_rdir+n);
					  phy_read_sector();
				      num=0;		
				 }
			}
		    else
		    { /* subdir can be fragmented -> dgetc() */
				 if(num % fat_sector_size == 0 )
				 {
			         fat_dgetsector();
					 num=0;
				 }
			}
      	}
      
        j = num;			  
	    num += DIR_SIZE;
        flag = TRUE;
        

       	/*computes gathered data        */
       	/* check if we have a LFN entry */
      	if (gl_buffer[11+j] != 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+j];
		          
		          	if (lfn_name[i] == ' ')
		          	{ /* space is end of name */
		            	break;
		          	}
		        }
		        /* append extension */
				if((gl_buffer[11+j] & ATTR_DIRECTORY )!= ATTR_DIRECTORY)
				{
			        lfn_name[i++] = '.';
				}
			    lfn_name[i++] = gl_buffer[8+j];
			    lfn_name[i++] = gl_buffer[9+j];
			    lfn_name[i++] = gl_buffer[10+j];

			    lfn_name[i] = '\0';        /* end of string */				
		  	}	        
	      	else
	      	{ // LFN name treatment //

               	i = 0;
			   	while((lfn_name[i] != '\0') && (lfn_name[i] != 0xff))
			   	{
			       	i++;
			   	}
			   	lfn_name[i] = '\0';
	      	}
	
	      	/* store extension */
	      	ext[0]= gl_buffer[8+j];
	      	ext[1]= gl_buffer[9+j];
	      	ext[2]= gl_buffer[10+j];
	
	      	/* standard computing for normal entry */
	      	entry->attributes = gl_buffer[11+j];
	      	entry->start_cluster.b[0] = gl_buffer[26+j];
			entry->start_cluster.b[1] = gl_buffer[27+j];
			entry->start_cluster.b[2] = gl_buffer[20+j];
			entry->start_cluster.b[3] = gl_buffer[21+j];
	      	//entry->start_cluster += ((Uint16) gl_buffer[27+j]) << 8;
	      	entry->size.b[0] = gl_buffer[28+j];
	      	entry->size.b[1] = gl_buffer[29+j];
	      	entry->size.b[2] = gl_buffer[30+j];
	      	entry->size.b[3] = gl_buffer[31+j];
	      	/* now it's time to stop */
	      	exit_flag = TRUE;

	  	}// end  if (name_buffer[11] != ATTR_LFN_ENTRY)
      	else
	  	{
          	lfn_entry_found = TRUE;
		  	//lfn_name[0] = 'L';
		  if(count < 5)
          {	
			  if((gl_buffer[0 + j] & LFN_SEQ_MASK) <= MAX_LFN_ENTRIES)
			  {
				  for(i=0; i<5; i++)
				  {
				     lfn_name[i*2 + 26*((gl_buffer[0+j] & LFN_SEQ_MASK) - 1) + 1] = gl_buffer[2*i + 1 +j];
				     lfn_name[i*2 + 26*((gl_buffer[0+j] & LFN_SEQ_MASK) - 1)] = gl_buffer[2*i + 2 +j];
				  }
				  for(i=0; i<6; i++)
				  {
				     lfn_name[i*2 + 10 + 26*((gl_buffer[0+j] & LFN_SEQ_MASK) - 1) + 1] = gl_buffer[2*i + 14 +j];
				     lfn_name[i*2 + 10 + 26*((gl_buffer[0+j] & LFN_SEQ_MASK) - 1)] = gl_buffer[2*i + 15 +j];
				  }
				  for(i=0; i<2; i++)
				  {
				     lfn_name[i*2 + 22 + 26*((gl_buffer[0+j] & LFN_SEQ_MASK) - 1) + 1] = gl_buffer[2*i + 28 +j];
				     lfn_name[i*2 + 22 + 26*((gl_buffer[0+j] & LFN_SEQ_MASK) - 1)] = gl_buffer[2*i + 29 +j];
				  }
			 }
		 }
          	count++;
	   	}                
    }//end while
   	phy_read_close();                        /* close physical read */

}




/*F**************************************************************************
* NAME: fat_dgetsector
*----------------------------------------------------------------------------
* PARAMS:
*
* return:
*----------------------------------------------------------------------------
* PURPOSE:
*   Return the directory data page at the current position
*----------------------------------------------------------------------------
* EXAMPLE:
*----------------------------------------------------------------------------
* NOTE:
*----------------------------------------------------------------------------
* REQUIREMENTS:
*****************************************************************************/ 
void fat_dgetsector (void)
{
  	Uint32 next_cluster;  
    /* new cluster in allocation list */
//  	if((fat_dclust_byte_count % (fat_sector_size * fat_cluster_size)) == 0 )
	if(((fat_dclust_byte_count / fat_sector_size) % fat_cluster_size) == 0 )
  	{
	    //fat_dclust_byte_count=0;
		/* extract if necessary the next cluster from the allocation list */
		if ((dclusters[fat_dchain_index].number == fat_dchain_nb_clust)&&(dclusters[0].number != 0))
		{ /* new fragment */
		  	fat_dchain_index++;
		  	fat_dchain_nb_clust = 1;
		  	next_cluster = dclusters[fat_dchain_index].cluster.l;
		  	fat_dir_current_sect = fat_ptr_data + ((Uint32)(next_cluster) * fat_cluster_size);
		  	phy_read_open(fat_dir_current_sect);
		}
		else
		{ /* no new fragment */
		  	if(dclusters[fat_dchain_index].number == 0)
		  	 	fat_dchain_nb_clust = 0;
		  	//next_cluster = dclusters[fat_dchain_index].cluster + fat_dchain_nb_clust;
		  	next_cluster = dclusters[fat_dchain_index].cluster.l + fat_dchain_nb_clust;
		  	fat_dir_current_sect = fat_ptr_data + ((Uint32)(next_cluster) * fat_cluster_size);
		  //if((fat_dchain_index == 0)&&(fat_dchain_nb_clust == 0))
          //{
			  phy_read_open(fat_dir_current_sect);
          //}

⌨️ 快捷键说明

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