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

📄 apfs_fat32_misc.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_misc.h"
#include "apfs_fat32_base.h"

struct fat32_long_file_name fat32_long_file_name_list;

//-----------------------------------------------------------------------------
// apfs_fat32_clear_entry_cache: Clear long file name cache
//-----------------------------------------------------------------------------
void apfs_fat32_clear_entry_cache(BOOL clr)
{
	int i;
	fat32_long_file_name_list.no_of_strings = 0;

	// Zero out buffer also
	if(clr)
	{
		for(i=0; i < MAX_LONGFILENAME_ENTRIES; i++)
		{
			memset(fat32_long_file_name_list.string[i], 0x00, 13);
		}
	}
}
//-----------------------------------------------------------------------------
// apfs_fat32_fill_entry_cache: Function extracts long file name text from sector 
// at a specific offset
//-----------------------------------------------------------------------------
void apfs_fat32_fill_entry_cache(BYTE *entry)
{
	BYTE index, i;
	index = entry[0] & 0x0F;//LDIR_Ord

	if(fat32_long_file_name_list.no_of_strings == 0) 
	{
		fat32_long_file_name_list.no_of_strings = index;
	}

	fat32_long_file_name_list.string[index-1][0] = entry[1];
	fat32_long_file_name_list.string[index-1][1] = entry[3];
	fat32_long_file_name_list.string[index-1][2] = entry[5];
	fat32_long_file_name_list.string[index-1][3] = entry[7];
	fat32_long_file_name_list.string[index-1][4] = entry[9];
	fat32_long_file_name_list.string[index-1][5] = entry[0x0E];
	fat32_long_file_name_list.string[index-1][6] = entry[0x10];
	fat32_long_file_name_list.string[index-1][7] = entry[0x12];
	fat32_long_file_name_list.string[index-1][8] = entry[0x14];
	fat32_long_file_name_list.string[index-1][9] = entry[0x16];
	fat32_long_file_name_list.string[index-1][10] = entry[0x18];		 		  		  	 		 
	fat32_long_file_name_list.string[index-1][11] = entry[0x1C];
	fat32_long_file_name_list.string[index-1][12] = entry[0x1E];

	for(i=0; i<13; i++)
	{
		if(fat32_long_file_name_list.string[index-1][i] == 0xFF)
		{
			fat32_long_file_name_list.string[index-1][i] = 0x20; // Replace with spaces
		}
	}
}
//-----------------------------------------------------------------------------
// apfs_fat32_dump_entry_cache: Get a copy of the long filename to into a string buffer
//-----------------------------------------------------------------------------
void apfs_fat32_dump_entry_cache(BYTE *str)
{
	int i,index;
	int count = 0;

	// Copy long filename from LFN Cache into a string
	for(index=0; index < fat32_long_file_name_list.no_of_strings; index++)
	{
		for(i = 0; i < 13; i++)
		{
			str[count++] = fat32_long_file_name_list.string[index][i];
		}
	}
	
	str[count] = '\0';
}

//-----------------------------------------------------------------------------
// apfs_fat32_entry_is_empty: Check the entry if it is empty
//-----------------------------------------------------------------------------
BOOL apfs_fat32_entry_is_empty(struct fat32_short_entry *entry)
{
	if(entry->name[0] == FILE_HEADER_DELETED)
	{
		return TRUE;
	}
	else
	{
		return FALSE;
	}
}
//-----------------------------------------------------------------------------
// apfs_fat32_entry_is_last: Check the entry if it is the last 
// one in the cluster
//-----------------------------------------------------------------------------
BOOL apfs_fat32_entry_is_last(struct fat32_short_entry *entry)
{
	if(entry->name[0] == FILE_HEADER_BLANK)
	{
		return TRUE;
	}
	else
	{
		return FALSE;
	}
}
//-----------------------------------------------------------------------------
// apfs_fat32_entry_is_last: Check the entry if it is the last 
// one in the cluster
//-----------------------------------------------------------------------------
BOOL apfs_fat32_entry_is_volume_id(struct fat32_short_entry *entry)
{
	if(entry->attr == FILE_ATTR_VOLUME_ID)
	{
		return TRUE;
	}
	else
	{
		return FALSE;
	}
}
//-----------------------------------------------------------------------------
// apfs_fat32_entry_is_single_short: Check the entry if it is a single 
// short entry
//-----------------------------------------------------------------------------
BOOL apfs_fat32_entry_is_single_short(struct fat32_short_entry *entry)
{
	if((entry->attr != FILE_ATTR_LFN_TEXT) && 
		(fat32_long_file_name_list.no_of_strings == 0))
	{
		return TRUE;
	}
	else
	{
		return FALSE;
	}}
//-----------------------------------------------------------------------------
// apfs_fat32_entry_is_short_with_long: Check the entry if it is a short entry
// associat with long entry
//-----------------------------------------------------------------------------
BOOL apfs_fat32_entry_is_short_with_long(struct fat32_short_entry *entry)
{
	if((entry->attr != FILE_ATTR_LFN_TEXT) && 
		fat32_long_file_name_list.no_of_strings != 0)
	{
		return TRUE;
	}
	else
	{
		return FALSE;
	}
}
//-----------------------------------------------------------------------------
// apfs_fat32_entry_is_long: Check the entry if it is a long entry
//-----------------------------------------------------------------------------
BOOL apfs_fat32_entry_is_long(struct fat32_short_entry *entry)
{
	if(entry->attr == FILE_ATTR_LFN_TEXT)
	{
		return TRUE;
	}
	else
	{
		return FALSE;
	}
}

//-----------------------------------------------------------------------------
// apfs_fat32_dir_entry: Returns 1 if a directory
//-----------------------------------------------------------------------------
int apfs_fat32_dir_entry(struct fat32_short_entry *entry)
{
	if(entry->attr == FILE_TYPE_DIR)
	{
		return 1;
	}
	else
	{
		return 0;
	}
}
//-----------------------------------------------------------------------------
// apfs_fat32_file_entry: Returns 1 is a file entry
//-----------------------------------------------------------------------------
int apfs_fat32_file_entry(struct fat32_short_entry *entry)
{
	if(entry->attr == FILE_TYPE_FILE) 
	{
		return 1;
	}
	else
	{
		return 0;
	}
}
//-----------------------------------------------------------------------------
// apfs_fat32_lfn_to_entry_count:
//-----------------------------------------------------------------------------
int apfs_fat32_lfn_to_entry_count(char *filename)
{
	// 13 characters entries
	int length = (int)strlen(filename);
	int entriesRequired = length / 13;

	// Remainder
	if((length % 13) != 0)
	{
		entriesRequired++;
	}

	return entriesRequired;
}
//-----------------------------------------------------------------------------
// apfs_fat32_fill_lfn_entry:
//-----------------------------------------------------------------------------
void apfs_fat32_fill_lfn_entry(char *filename, BYTE *buffer, int entry, BYTE sfnChk)
{
	int i;
	int nameIndexes[] = {1,3,5,7,9,0x0E,0x10,0x12,0x14,0x16,0x18,0x1C,0x1E};

	// 13 characters entries
	int length = (int)strlen(filename);
	int entriesRequired = apfs_fat32_lfn_to_entry_count(filename);

	// Filename offset
	int start = entry * 13;

	// Initialise to zeros
	memset(buffer, 0x00, 32);

	// LFN entry number
	buffer[0] = (BYTE)(((entriesRequired - 1) == entry) ? (0x40|(entry + 1)) : (entry + 1));

	// LFN flag
	buffer[11] = 0x0F;

	// Checksum of short filename
	buffer[13] = sfnChk;

	// Copy to buffer
	for(i = 0; i < 13; i++)
	{
		if((start + i) < length)
		{
			buffer[nameIndexes[i]] = filename[start+i];
		}
		else if((start + i) == length)
		{
			buffer[nameIndexes[i]] = 0x00;
		}
		else
		{
			buffer[nameIndexes[i]] = 0xFF;
			buffer[nameIndexes[i] + 1] = 0xFF;
		}
	}
}
//-----------------------------------------------------------------------------
// FATMisc_Create_sfn_entry: Create the short filename directory entry
//-----------------------------------------------------------------------------
void apfs_fat32_create_sfn_entry(char *shortfilename, UINT32 size, 
							UINT32 startCluster, struct fat32_short_entry *entry,
							unsigned char attr)
{
	int i;

	// Copy short filename
	for(i = 0; i < 11; i++)
	{
		entry->name[i] = shortfilename[i];
	}
	// Unless we have a RTC we might as well set these to 1980
	entry->crt_time_tenth = 0x00;
	entry->crt_time[1] = entry->crt_time[0] = 0x00;
	entry->crt_date[1] = 0x00;
	entry->crt_date[0] = 0x20;
	entry->lst_acc_date[1] = 0x00;
	entry->lst_acc_date[0] = 0x20;
	entry->wrt_time[1] = entry->wrt_time[0] = 0x00;
	entry->wrt_date[1] = 0x00;
	entry->wrt_date[0] = 0x20;	

	entry->attr = attr;
	entry->ntres = 0x00;

	entry->fst_clus_hi = (UINT16)((startCluster>>16) & 0xFFFF);
	entry->fst_clus_lo = (UINT16)((startCluster>>0) & 0xFFFF);
	entry->file_size = size;
}
//-----------------------------------------------------------------------------
// apfs_fat32_generate_tail:
// sfn_input = Input short filename, spaced format & in upper case
// sfn_output = Output short filename with tail
//-----------------------------------------------------------------------------
BOOL apfs_fat32_generate_tail(char *sfn_output, char *sfn_input, UINT32 tailNum)
{
	int tail_chars;
	char tail_str[8];

	if(tailNum > 99999)
	{
		return FALSE;
	}
	// Convert to number
	memset(tail_str, 0x00, sizeof(tail_str)); 
	tail_str[0] = '~';
	itoa(tailNum, tail_str+1, 10);
	
	// Copy in base filename
    memcpy(sfn_output, sfn_input, 11);
	   
	// Overwrite with tail
	tail_chars = (int)strlen(tail_str);
	memcpy(sfn_output + (8 - tail_chars), tail_str, tail_chars);

	return TRUE;
}

⌨️ 快捷键说明

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