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

📄 fat_find.c

📁 ucFS的加强版,含完整代码
💻 C
📖 第 1 页 / 共 3 页
字号:
#include "fs_conf.h"
#include "fs_port.h"

#include "fs_dev.h"
#include "fs_api.h"
#include "fs_fsl.h"
#include "fs_int.h"
#include "fs_os.h"
#include "fs_lbl.h"
#include "fs_fat.h"
#include "fs_clib.h"

#include "Fat_find.h"


FS_u16 g_search_tmp_name[260];

FS_u16 g_search_wide_name[260];

FS_i32 FS__fat_find_dir_ex(int Idx, FS_u32 Unit, FS_u8 *pDirName,
							  FS_u16 name_len, FS_u32 DirStart, FS_u32 DirSize)
{
   FS_u16 len;
   char dname[12];
   FS_i32 dstart = 0;

   if(FS__CLIB_strlen(pDirName) > 11 || FS__CLIB_check_wchar(pDirName))
   {
      len = FS__CLIB_str2wstr(g_search_wide_name,pDirName,name_len);
      dstart = FS__fat_find_dir_long(Idx,Unit,g_search_wide_name,len,DirStart,DirSize);
   }
   else
   {
      FS__fat_make_realname(dname,pDirName);
      dstart = FS__fat_find_dir_short(Idx,Unit,g_search_wide_name,11,DirStart,DirSize);
   }

   return dstart;
}


FS_i32 FS__fat_find_dir_long(int Idx, FS_u32 Unit, FS_u16 *pDirName,
							 FS_u16 name_len, FS_u32 DirStart, FS_u32 DirSize)
{
	FS__fat_dentry_type *s;
	FS_u32 dstart;
	FS_u32 i;
	FS_u32 dsec;
	FS_u32 fatsize;
	
	int err;
	int c;
	char *buffer;
	
	FS_u16 str_count;
	
	FS_u16 *str_cur;
	FS_u16 *str_last;
	
	FS_u16 str_state;
	FS_u16 *buf;

	FS_u8  checksum;
    
	FS_u8  short_checksum;
	FS_i16 short_loop;


	str_state = 0; //0 - reset, 1 - connecting

    /* Find directory */
    buffer = FS__fat_malloc(FS_FAT_SEC_SIZE);
    
	if (!buffer)
	{
		return 0;
    }
    
    /* Read directory */
    for (i = 0; i < DirSize; i++)
	{
		dsec = FS__fat_dir_realsec(Idx, Unit, DirStart, i);
		
		if (dsec == 0)
		{
			FS__fat_free(buffer);
			return 0;
		}
		
		err = FS__lb_read(FS__pDevInfo[Idx].devdriver, Unit, dsec, (void*)buffer);
		
		if (err < 0)
		{
			FS__fat_free(buffer);
			return 0;
		}
		
		s = (FS__fat_dentry_type*)buffer;
		
		for(; s < (FS__fat_dentry_type*)(buffer + FS_FAT_SEC_SIZE); s++)
		{
			if(str_state == 0)
			{
				if(s->data[11] != FS_FAT_ATTR_LONGNAME)
					continue;
				
				if(!(s->data[0] & 0x40)) //end idx
					continue;

				FS__CLIB_memset(g_search_tmp_name,0,sizeof(g_search_tmp_name));
				str_count = 0;
				str_last = str_cur = g_search_tmp_name;
				checksum = s->data[13];
				
				str_state = 1;
			}
			
			if(str_state == 1)
			{
				if(s->data[11] != FS_FAT_ATTR_LONGNAME)
				{
					str_state = 0;
					continue;
				}

				if(checksum != s->data[13])
				{
					str_state = 0;
					continue;
				}
				
				buf = &s->data[28];
				*str_cur++ = buf[1];
				*str_cur++ = buf[0];
				
				buf = &s->data[14];
				*str_cur++ = buf[5];
				*str_cur++ = buf[4];
				*str_cur++ = buf[3];
				*str_cur++ = buf[2];
				*str_cur++ = buf[1];
				*str_cur++ = buf[0];

				buf = &s->data[1];
				
				*str_cur++ = buf[4];
				*str_cur++ = buf[3];
				*str_cur++ = buf[2];
				*str_cur++ = buf[1];
				*str_cur++ = buf[0];

// 				FS__CLIB_memcpy(str_cur,&s->data[28],sizeof(FS_u16)*2);
// 				str_cur += 2;
// 				FS__CLIB_memcpy(str_cur,&s->data[14],sizeof(FS_u16)*6);
// 				str_cur += 6;
// 				FS__CLIB_memcpy(str_cur,&s->data[1],sizeof(FS_u16)*5);
// 				str_cur += 5;
				
				if(str_cur - g_search_tmp_name > 255)
				{
				   str_state = 0;
				   continue;
				}

			    if(s->data[0] & 0x01) //first
				{
					str_state = 2;
				    continue;
				}
			}

			if(str_state == 2)
			{
                if(FS__CLIB_wstrncmp_r(pDirName,str_cur-1,name_len) != 0)
                {
					str_state = 0;
					continue;
				}
				
				if(!(s->data[11] & FS_FAT_ATTR_DIRECTORY))
				{
					FS__fat_free(buffer);
					return 0;
				}

				if(s->data[0] == 0xE5 || s->data[0] == 0x00)
				{
					FS__fat_free(buffer);
					return 0;
				}
              
				short_loop = 0;
				short_checksum = 0;
				
				for (short_loop = 11; short_loop > 0; short_loop--)
					short_checksum = ((short_checksum & 1) ? 0x80 : 0) + (short_checksum >> 1) + s->data[11 - short_loop];
				
				if(checksum != short_checksum)
				{
					FS__fat_free(buffer);
					return 0;
				}
                
                break;
			}
		}
		
		if (s < (FS__fat_dentry_type*)(buffer + FS_FAT_SEC_SIZE))
		{
			/* Entry found. Return number of 1st block of the directory */
			FS__fat_free(buffer);
			dstart  = (FS_u32)s->data[26];
			dstart += (FS_u32)0x100UL * s->data[27];
			dstart += (FS_u32)0x10000UL * s->data[20];
			dstart += (FS_u32)0x1000000UL * s->data[21];
			return dstart;
		}
    }
    
	dstart = 0;
    FS__fat_free(buffer);
	
  return dstart;
}

FS_i32 FS__fat_find_dir_short(int Idx, FS_u32 Unit, FS_u8 *pDirName,
							 FS_u16 name_len, FS_u32 DirStart, FS_u32 DirSize)
{
	FS__fat_dentry_type *s;
	FS_u32 dstart;
	FS_u32 i;
	FS_u32 dsec;
	FS_u32 fatsize;
	
	int err;
	int c;
	char *buffer;
	
    /* Find directory */
    buffer = FS__fat_malloc(FS_FAT_SEC_SIZE);
    
	if (!buffer)
	{
		return 0;
    }
    
    /* Read directory */
    for (i = 0; i < DirSize; i++)
	{
		dsec = FS__fat_dir_realsec(Idx, Unit, DirStart, i);
		
		if (dsec == 0)
		{
			FS__fat_free(buffer);
			return 0;
		}
		
		err = FS__lb_read(FS__pDevInfo[Idx].devdriver, Unit, dsec, (void*)buffer);
		
		if (err < 0)
		{
			FS__fat_free(buffer);
			return 0;
		}
		
		s = (FS__fat_dentry_type*)buffer;
		
		for(; s < (FS__fat_dentry_type*)(buffer + FS_FAT_SEC_SIZE); s++)
		{
			if(!(s->data[11] & FS_FAT_ATTR_DIRECTORY))
				continue;
			
			if(s->data[11] == FS_FAT_ATTR_LONGNAME)
				continue;

			if(s->data[0] == 0xE5)
				continue;

			if(s->data[0] == 0x00)
			{
				FS__fat_free(buffer);
				return 0;
			}

			if(FS__CLIB_strncmp(pDirName,s->data,name_len) != 0)
				continue;
			  
			break;
		}
		
		if (s < (FS__fat_dentry_type*)(buffer + FS_FAT_SEC_SIZE))
		{
			/* Entry found. Return number of 1st block of the directory */
			FS__fat_free(buffer);
			dstart  = (FS_u32)s->data[26];
			dstart += (FS_u32)0x100UL * s->data[27];
			dstart += (FS_u32)0x10000UL * s->data[20];
			dstart += (FS_u32)0x1000000UL * s->data[21];
			return dstart;
		}
    }
	
	dstart = 0;
    FS__fat_free(buffer);
	
	return dstart;
}


FS_i32 _FS_fat_find_file_ex(int Idx, FS_u32 Unit, const char *pFileName,
						   FS__fat_dentry_type *pDirEntry,
						   FS_u32 DirStart, FS_u32 DirSize)
{
	FS_u16 len;
	char dname[12];
	FS_i32 dstart = 0;
	
	len = FS__CLIB_strlen(pFileName);
	
	if(len > 11 || FS__CLIB_check_wchar(pFileName))
	{
		len = FS__CLIB_str2wstr(g_search_wide_name,pFileName,len);
		dstart = _FS_fat_find_file_long(Idx,Unit,g_search_wide_name,len,pDirEntry,DirStart,DirSize);
	}
	else
	{
		FS__fat_make_realname(dname,pFileName);
		dstart = _FS_fat_find_file_short(Idx,Unit,g_search_wide_name,11,pDirEntry,DirStart,DirSize);
	}
	
	return dstart;
}

static FS_i32 _FS_fat_find_file_long(int Idx, FS_u32 Unit, const short *pFileName,
								FS_u16 name_len, FS__fat_dentry_type *pDirEntry,
								FS_u32 DirStart, FS_u32 DirSize)
{
	FS__fat_dentry_type *s;
	FS_u32 i;
	FS_u32 dsec;
	int len;
	int err;
	int c;
	char *buffer;
	 
    FS_u16 str_count;
	
	FS_u16 *str_cur;
	FS_u16 *str_last;
	
	FS_u16 str_state;
	FS_u16 *buf;
	
	FS_u8  checksum;
    
	FS_u8  short_checksum;
	FS_i16 short_loop;
	
	str_state = 0;

	buffer = FS__fat_malloc(FS_FAT_SEC_SIZE);
	
	if (!buffer)
	{
		return -1;
	}
	
	/* Read directory */
	for (i = 0; i < DirSize; i++) 
	{
		dsec = FS__fat_dir_realsec(Idx, Unit, DirStart, i);
		
		if (dsec == 0) 
		{
			FS__fat_free(buffer);
			return -1;
		}
		
		err = FS__lb_read(FS__pDevInfo[Idx].devdriver, Unit, dsec, (void*)buffer);
		
		if (err < 0)
		{
			FS__fat_free(buffer);
			return -1;
		}
		
		s = (FS__fat_dentry_type*)buffer;
		
		for(; s < (FS__fat_dentry_type*)(buffer + FS_FAT_SEC_SIZE); s++)
		{
			if(str_state == 0)
			{
				if(s->data[11] != FS_FAT_ATTR_LONGNAME)
					continue;
				
				if(!(s->data[0] & 0x40)) //end idx
					continue;
				
				FS__CLIB_memset(g_search_tmp_name,0,sizeof(g_search_tmp_name));
				str_count = 0;
				str_last = str_cur = g_search_tmp_name;
				checksum = s->data[13];
				
				str_state = 1;
			}
			
			if(str_state == 1)
			{
				if(s->data[11] != FS_FAT_ATTR_LONGNAME)
				{
					str_state = 0;
					continue;
				}
				
				if(checksum != s->data[13])
				{
					str_state = 0;
					continue;
				}
				
				buf = &s->data[28];
				*str_cur++ = buf[1];
				*str_cur++ = buf[0];
				
				buf = &s->data[14];
				*str_cur++ = buf[5];
				*str_cur++ = buf[4];
				*str_cur++ = buf[3];
				*str_cur++ = buf[2];
				*str_cur++ = buf[1];
				*str_cur++ = buf[0];
				
				buf = &s->data[1];
				
				*str_cur++ = buf[4];
				*str_cur++ = buf[3];
				*str_cur++ = buf[2];
				*str_cur++ = buf[1];
				*str_cur++ = buf[0];
				
				if(str_cur - g_search_tmp_name > 255)
				{
					str_state = 0;
					continue;
				}
				
				if(s->data[0] & 0x01) //first
				{
					str_state = 2;
					continue;
				}
			}
			
			if(str_state == 2)
			{
				if(FS__CLIB_wstrncmp_r(pFileName,str_cur - 1,name_len) != 0)
				{
					str_state = 0;
					continue;
				}
				
				if(s->data[11] & FS_FAT_ATTR_DIRECTORY) //must not be directory
				{
					FS__fat_free(buffer);
					return 0;
				}

				if(s->data[0] == 0xE5 || s->data[0] == 0x00)
				{
					FS__fat_free(buffer);
					return 0;
				}
				
				short_loop = 0;
				short_checksum = 0;
				
				for (short_loop = 11; short_loop > 0; short_loop--)
					short_checksum = ((short_checksum & 1) ? 0x80 : 0) + (short_checksum >> 1) + s->data[11 - short_loop];
				
				if(checksum != short_checksum)
				{
					FS__fat_free(buffer);
					return 0;
				}
				
				break;
			}
		}	
		
		if (s < (FS__fat_dentry_type*)(buffer + FS_FAT_SEC_SIZE)) 
		{
			/* Entry found. Return number of 1st block of the file */
			if (pDirEntry)
			{
				FS__CLIB_memcpy(pDirEntry, s, sizeof(FS__fat_dentry_type));
			}
			
			FS__fat_free(buffer);
			dsec  = (FS_u32)s->data[26];
			dsec += (FS_u32)s->data[27] * 0x100UL;
			dsec += (FS_u32)s->data[20] * 0x10000UL;
			dsec += (FS_u32)s->data[21] * 0x1000000UL;
			
			return ((FS_i32)dsec);
		}
	}
	FS__fat_free(buffer);
	return -1;
}

static FS_i32 _FS_fat_find_file_short(int Idx, FS_u32 Unit, const short *pFileName,
								FS_u16 name_len, FS__fat_dentry_type *pDirEntry,
								FS_u32 DirStart, FS_u32 DirSize)
{
	FS__fat_dentry_type *s;
	FS_u32 i;
	FS_u32 dsec;
	int len;
	int err;
	int c;
	char *buffer;
	 
 	buffer = FS__fat_malloc(FS_FAT_SEC_SIZE);
	
	if (!buffer)
	{
		return -1;
	}
	
	/* Read directory */
	for (i = 0; i < DirSize; i++) 
	{
		dsec = FS__fat_dir_realsec(Idx, Unit, DirStart, i);
		
		if (dsec == 0) 
		{
			FS__fat_free(buffer);
			return -1;
		}
		
		err = FS__lb_read(FS__pDevInfo[Idx].devdriver, Unit, dsec, (void*)buffer);
		
		if (err < 0)
		{
			FS__fat_free(buffer);
			return -1;
		}
		
		s = (FS__fat_dentry_type*)buffer;
		
		for(; s < (FS__fat_dentry_type*)(buffer + FS_FAT_SEC_SIZE); s++)
		{
			if(s->data[11] & FS_FAT_ATTR_DIRECTORY)
				continue;
			
			if(s->data[11] == FS_FAT_ATTR_LONGNAME)
				continue;
			
			if(s->data[0] == 0xE5)
				continue;
			
			if(s->data[0] == 0x00)
			{
				FS__fat_free(buffer);
				return 0;
			}
			
			if(FS__CLIB_strncmp(pFileName,s->data,name_len) != 0)
				continue;
			
			break;
		}
		
		if (s < (FS__fat_dentry_type*)(buffer + FS_FAT_SEC_SIZE)) 
		{
			/* Entry found. Return number of 1st block of the file */
			if (pDirEntry)
			{
				FS__CLIB_memcpy(pDirEntry, s, sizeof(FS__fat_dentry_type));
			}
			
			FS__fat_free(buffer);
			dsec  = (FS_u32)s->data[26];
			dsec += (FS_u32)s->data[27] * 0x100UL;
			dsec += (FS_u32)s->data[20] * 0x10000UL;
			dsec += (FS_u32)s->data[21] * 0x1000000UL;
			
			return ((FS_i32)dsec);
		}
	}
	FS__fat_free(buffer);
	return -1;
}

//////////////////////////////////////////////////////////////////////////
FS_i32 _FS_fat_del_unit_ex(int Idx, FS_u32 Unit, const char *pName,
						   FS__fat_dentry_type *pDirEntry,
						   FS_u32 DirStart, FS_u32 DirSize,FS_u8 unit_attr)
{
	FS_u16 len;
	char dname[12];
	FS_i32 dstart = 0;
	
	len = FS__CLIB_strlen(pName);
	
	if(len > 11 || FS__CLIB_check_wchar(pName))
	{
		len = FS__CLIB_str2wstr(g_search_wide_name,pName,len);
		dstart = _FS_fat_del_unit_long(Idx,Unit,g_search_wide_name,len,pDirEntry,DirStart,DirSize);
	}
	else
	{
		FS__fat_make_realname(dname,pName);
		dstart = _FS_fat_del_unit_short(Idx,Unit,g_search_wide_name,11,pDirEntry,DirStart,DirSize);
	}
	
	return dstart;
}

static FS_i32 _FS_fat_del_unit_long(int Idx, FS_u32 Unit, const short *pName,
								FS_u16 name_len, FS__fat_dentry_type *pDirEntry,
								FS_u32 DirStart, FS_u32 DirSize,FS_u8 unit_attr)
{
	FS__fat_dentry_type *s;
	FS_u32 i;
	FS_u32 dsec;
	
	FS_u32 long_start;
    FS_u16 long_cnt;
	FS_u16 long_offs;
	FS_u16 long_state;

	int len;
	int err;
	int c;
	char *buffer;
	 

⌨️ 快捷键说明

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