📄 fat_file.c
字号:
#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 + -