📄 apfs_fat32_access.c
字号:
//-----------------------------------------------------------------------------
// This file is part of AP.FS
// AP.FS is a FAT32 file system face to the embedded system,It's target is to
// support the portable storage device such as SD Card,TF Card or USB Disc 's
// file system.
// please login www.another-prj.com to get more details.
// caiyuqing
// 2008-1-8
//-----------------------------------------------------------------------------
#include "apfs_fat32_definitions.h"
#include "apfs_fat32_access.h"
#include "apfs_fat32_base.h"
#include "apfs_fat32_opts.h"
#include "apfs_fat32_table.h"
// fats_internal_struct is a global symbol
struct fats_internal fats_internal_struct;
extern struct fat32 fat32_struct;
extern struct sector_buffer sector_buffer;
//-----------------------------------------------------------------------------
// apfs_init_fats_internal: init the fats_internal_struct
//-----------------------------------------------------------------------------
void apfs_init_fats_internal()
{
fats_internal_struct.sector_currently_loaded = 0xFFFFFFFF;
fats_internal_struct.next_free_cluster = 0xFFFFFFFF;
}
//-----------------------------------------------------------------------------
// apfs_fat32_sector_reader: From the provided startcluster and sector offset
// Returns True if success, returns False if not (including if read out of range)
//-----------------------------------------------------------------------------
BOOL apfs_fat32_sector_reader(UINT32 start_cluster, UINT32 offset)
{
UINT32 sector_to_read = 0;
UINT32 cluster_to_read = 0;
UINT32 cluster_chain = 0;
UINT32 i;
UINT32 lba;
// Set start of cluster chain to initial value
cluster_chain = start_cluster;
// Find parameters
cluster_to_read = offset / fat32_struct.sectors_per_cluster;
sector_to_read = offset % fat32_struct.sectors_per_cluster;
// Follow chain to find cluster to read
for(i=0; i<cluster_to_read; i++)
{
cluster_chain = apfs_fat32_find_next_cluster(cluster_chain);
}
// If end of cluster chain then return false
if(cluster_chain == 0xFFFFFFFF)
{
return FALSE;
}
// Calculate sector address
lba = apfs_fat32_lba_of_cluster(cluster_chain) + sector_to_read;
// Else read sector if not already loaded
if(lba != fats_internal_struct.sector_currently_loaded)
{
fats_internal_struct.sector_currently_loaded = lba;
return apfs_fat32_read_sector(fats_internal_struct.sector_currently_loaded,
fats_internal_struct.current_sector);
}
else
{
return TRUE;
}
}
//-----------------------------------------------------------------------------
// apfs_fat32_sector_writer: Write to the provided startcluster and sector offset
// Returns True if success, returns False if not
//-----------------------------------------------------------------------------
BOOL apfs_fat32_sector_writer(UINT32 start_cluster, UINT32 offset)
{
UINT32 sector_to_write = 0;
UINT32 cluster_to_write = 0;
UINT32 cluster_chain = 0;
UINT32 last_cluster_chain = 0xFFFFFFFF;
UINT32 i;
// Set start of cluster chain to initial value
cluster_chain = start_cluster;
// Find parameters
cluster_to_write = offset / fat32_struct.sectors_per_cluster;
sector_to_write = offset % fat32_struct.sectors_per_cluster;
// Follow chain to find cluster to read
for(i=0; i<cluster_to_write; i++)
{
// Find next link in the chain
last_cluster_chain = cluster_chain;
cluster_chain = apfs_fat32_find_next_cluster(cluster_chain);
// Dont keep following a dead end
if(cluster_chain == 0xFFFFFFFF)
{
break;
}
}
// If end of cluster chain
if(cluster_chain == 0xFFFFFFFF)
{
// Add another cluster to the last good cluster chain
if(!apfs_fat32_add_free_space_to_chain(&last_cluster_chain))
{
return FALSE;
}
cluster_chain = last_cluster_chain;
}
// Calculate write address
fats_internal_struct.sector_currently_loaded =
apfs_fat32_lba_of_cluster(cluster_chain) + sector_to_write;
// Write to disk
return apfs_fat32_write_sector(fats_internal_struct.sector_currently_loaded,
fats_internal_struct.current_sector);
}
//-----------------------------------------------------------------------------
// apfs_fat32_clean_cluster: Clean a cluster
//-----------------------------------------------------------------------------
#define FAT32_CLEAN_SECTOR(start_cluster, offset) \
UINT32 sector = apfs_fat32_lba_of_cluster(start_cluster) + offset;\
apfs_fat32_write_sector(sector, sector_buffer.zero_buf);
BOOL apfs_fat32_clean_cluster(UINT32 cluster)
{
int i ;
for( i = 0; i < fat32_struct.sectors_per_cluster; i++ )
{
FAT32_CLEAN_SECTOR(cluster, i);
}
return TRUE;
}
//-----------------------------------------------------------------------------
// apfs_fat32_get_root_cluster: Get the root dir cluster
//-----------------------------------------------------------------------------
UINT32 apfs_fat32_get_root_cluster()
{
return fat32_struct.rootdir_first_cluster;
}
//-----------------------------------------------------------------------------
// apfs_fat32_get_file_entry: Find the file entry for a filename
//-----------------------------------------------------------------------------
UINT32 apfs_fat32_get_file_entry(UINT32 cluster, char *name_to_find,
struct fat32_short_entry *sf_entry)
{
BYTE item=0;
UINT16 record_offset = 0;
BYTE i=0;
int x=0;
char long_file_name[MAX_LONG_FILENAME];
char short_file_name[13];
struct fat32_short_entry *entry;
// Clear the long file name cache
apfs_fat32_clear_entry_cache(TRUE);
while(TRUE)
{
// Read sector
if(apfs_fat32_sector_reader(cluster, x++))
{
// Analyse Sector
for(item = 0; item <= 15; item++)
{
record_offset = (32 * item);
// Overlay directory entry over buffer
entry = (struct fat32_short_entry*)(fats_internal_struct.current_sector +
record_offset);
// This entry is the last one in the cluster
if(apfs_fat32_entry_is_last(entry))
{
apfs_fat32_clear_entry_cache(FALSE);
return FALSE;
}
// This entry is empty
else if(apfs_fat32_entry_is_empty(entry))
{
apfs_fat32_clear_entry_cache(FALSE);
continue;
}
// This entry is a volume id
else if(apfs_fat32_entry_is_volume_id(entry))
{
apfs_fat32_clear_entry_cache(FALSE);
continue;
}
// This is a single short entry
else if(apfs_fat32_entry_is_single_short(entry))
{
memset(short_file_name, '\0', sizeof(short_file_name));
// Copy the name in the short entry to short_file_name
apfs_fat32_copy_short_name(short_file_name, entry->name);
// Compare names to see if they match
if(apfs_fat32_file_string_compare(short_file_name, name_to_find))
{
memcpy(sf_entry, entry, sizeof(struct fat32_short_entry));
return TRUE;
}
apfs_fat32_clear_entry_cache(FALSE);
}
// This is a long entry
else if(apfs_fat32_entry_is_long(entry))
{
apfs_fat32_fill_entry_cache(entry);
}
// This is a short entry,it is part of an entry set
else if(apfs_fat32_entry_is_short_with_long(entry) )
{
apfs_fat32_dump_entry_cache((BYTE*)long_file_name);
// Compare names to see if they match
if(apfs_fat32_file_string_compare(long_file_name, name_to_find))
{
memcpy(sf_entry, entry, sizeof(struct fat32_short_entry));
return TRUE;
}
apfs_fat32_clear_entry_cache(FALSE);
}
}
}
else
{
break;
}
}
return FALSE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -