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

📄 apfs_fat32_access.c

📁 一个可以在开发板上运行的fat文件系统,是在windows平台下开发的,是学习文件系统的好帮手
💻 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 + -