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

📄 ffindx.c

📁 嵌入式系统中文件系统源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
/*************************************************************
File Name: findx.C					     *
**************************************************************
Programmer: MSC
Last Modified Date: 1999/07/15
Compiler : Gnu Cross-compiler
Platform : X86 protection mode
Usage :
	int FAT_findfirst(unsigned char *target,
			  struct ffblk *result,
			  int attrib);
	int FAT_findnext(struct ffblk *result);
*************************************************************/

/*************************************************************
 		  	Header Files
**************************************************************/
#include <sys/syscall.h>
#include <sysvar.h>
//#include "../../RDebug/include/RDebug.h"

 #include "FileSys/include/FileSys.h"

#include "../include/fat1x.h"
#include "../include/findx.h"
#include "../include/cluster.h"
#include "../include/gb2uni.h"

#ifdef FAT_USE_PCMCIA
  /**** added by chilong ****/
  //#include "../pcm/cf_typedef.h"
  /**** added by chilong ****/

  #include "../include/ata_pcc.h"
#else
  #include "../include/ata_pcc.h"
#endif

#ifdef FAT_USE_UNICODE
  #include "../include/b52uni.h"
#endif

//#include <sys_info.h>


#ifdef FAT_ID



/* init.c */
extern unsigned long   	FATBytesPerCluster[];
extern unsigned short  	FATSecPerROOT[];
extern unsigned long  	FATRootBegin[];
extern unsigned char	FATType[];

extern int		FATDirSemaphoreID;

extern unsigned short	FATEndOfChain[];

/* fat1x.c */
extern struct FAT_FILE  **FATHandleTable;


/*************************************************************
Function : FAT_findfirst
Description:
	find the first file that match the requirement
Input:
	target - a wildcard that specifies the directory and files to search
	ffres - a structure to hold the results of the search
	attrib - the target attribute
Output:
	0	if a match has been found
	-1	if the searching failed
**************************************************************/
int FAT_findfirst(unsigned char *target, struct ffblk *ffres, int attrib)
{
  int status; 
	unsigned char umsb, ulsb, gbmsb, gblsb;
  

#ifdef FAT1X_DEBUG
  SprintStringLn("[FAT_findfirst]");
#endif

  FATErrno = 0;

  if (InitFAT == FALSE)
  {
	ffres->ff_reserved = 0;
	FATErrno = ERROR_FILE_SYSTEM_NOT_INIT;
	return -1;
  }

  sc_waitSemaphore(FATDirSemaphoreID);
                         
  status = FAT_findfirst_r(target, ffres, attrib);
                         
//	umsb = ffres->ff_name[0], ulsb = ffres->ff_name[1];
        
//	unicode_to_gb(umsb, ulsb, &gbmsb, &gblsb);

  sc_signalSemaphore(FATDirSemaphoreID);

  return status;
}


int FAT_findfirst_r(unsigned char *target, struct ffblk *ffres, int attrib)
{
  unsigned char *wildName;	/* the wildcard filename part */
  int i, j;
  int index = 0;		/* points to the '\\' between the above two parts */
  int status;
  unsigned short blkSize;	/* the size of a block (sector in root, cluster in sub-dir) */
  unsigned short *blkBuffer;	/* a buffer for root sectors */
  unsigned char *pBuffer;	/* a pointer for reading sector/cluster from disk */
  struct FAT_FILE *pfile;	/* a temp file handle for sub-dir searching */
  int availHandler;		/* an available handle for sub-dir searching */
  unsigned short cluster;	/* the target sub-dir cluster for wildcard name search */
  unsigned short prevCluster;	/* the previous cluster during wildcard compare */
  struct FAT_directory pEntry;	/* the dir entry with name matched the wildcard name */
  unsigned char entryAttr;	/* the attribute of the dir entry */
  unsigned char *path;		/* the path without drive name */
  short drive;			/* the target drive */
  unsigned char *fileName;	/* name part of the sub-dir part */
  struct FAT_FFInternal *ffInfo;	/* internal information for FAT_findnext */
#ifdef FAT_LFN
  struct FAT_LFNinfo longInfo;
#endif

#ifdef FAT1X_DEBUG
  SprintStringLn("[FAT_findfirst_r]");
#endif

  path = FAT_get_drive(target, &drive);

  if (drive == -1)
  {
	ffres->ff_reserved = 0;
	FATErrno = ERROR_INVALID_DRIVE;
	return -1;
  }

  /* separate the pathname into sub-dir part and filename part */
  /* e.g., "\\test1\\test2\\temp\\*.txt"   =>                  */
  /*       subDirName = "\\test1\\test2\\temp"                 */
  /*       fileName   = "*.txt"                                */
  while (path[index] != '\0')
	index++;
  while (index > 0 && path[index] != '\\')
	index--;
  /* index should now point at the '\\' between the two parts */

  wildName = path + index;
  if (*wildName == '\\')
	wildName++;

#ifdef FAT_LFN
  if ((fileName = (unsigned char *)ap_malloc(FAT_MAX_LFN_LENGTH * 2)) == NULL)
  {
	ffres->ff_reserved = 0;
	FATErrno = ERROR_ALLOC_MEM;
	return -1;
  }
  myMemSet(fileName, 0, FAT_MAX_LFN_LENGTH * 2);
#else
  if ((fileName = (unsigned char *)ap_malloc(13)) == NULL)
  {
	ffres->ff_reserved = 0;
	FATErrno = ERROR_ALLOC_MEM;
	return -1;
  }
  myMemSet(fileName, 0, 13);
#endif

  /* starting comparing attributes and filenames */
  if (index == 0)	/* find first in the root directory */
  {
	/* start searching for the filename in the root directory */
	/* no need to search for the sub-dir part */
	blkSize = SECTOR_SIZE;	/* root dir is handled sector by sector */
	if ((blkBuffer = (unsigned short *)ap_malloc(blkSize)) == NULL)
	{
		ap_free(fileName);
		ffres->ff_reserved = 0;
		FATErrno = ERROR_ALLOC_MEM;
		return -1;
	}

	/* check all root sectors */
	i = -1;
	for (;;)
	{
		i++;
		/* if all root sectors have been searched, then no match file is found */
		if (i == FATSecPerROOT[drive])
		{
			ffres->ff_reserved = 0;
			ap_free(blkBuffer);
			ap_free(fileName);
			FATErrno = ERROR_FILE_NOT_EXIST;
			return -1;
		}			
		/* read the current root sector */
		FAT_read_root_sector(drive, FATRootBegin[drive] + i, blkBuffer);
		pBuffer = (unsigned char *)blkBuffer;

		/* compare entry by entry in the sector */
		for (j = 0; j < blkSize; j += FAT_DIR_ENTRY_SIZE)
		{
			/* this entry and every following entry are empty => not found */
			if (*(pBuffer + j) == '\0')
			{
				ffres->ff_reserved = 0;
				ap_free(blkBuffer);
				ap_free(fileName);
				FATErrno = ERROR_FILE_NOT_EXIST;
				return -1;
			}

			/* skip this entry if it is an deleted entry */
			if (*(pBuffer + j) == 0xe5 || *(pBuffer + j) == '.')
				continue;

			/* compare the attribute of this entry with the given attribute */
			entryAttr = *(pBuffer + j + 11);

			// skip long directory entry
			if ((entryAttr & DA_VFAT) == DA_VFAT)
				continue;

			/* DA_READONLY and DA_ARCHIVE files can always be seen */
			/* DA_HIDDEN, DA_SYSTEM, DA_VOLUME, and DA_DIR are not */
			attrib = attrib | DA_READONLY;
			attrib = attrib | DA_ARCHIVE;

			/* go to next entry if the attributes unmatch */
			if ((entryAttr & attrib) != entryAttr)
				continue;

			/* marked by chilong 03/07/2002
			// only DIR are shown if DA_DIR is specified by user
			if ((attrib & DA_DIR) == DA_DIR)
				if ((entryAttr & DA_DIR) != DA_DIR)
					continue;
			   marked by chilong 03/07/2002 */
			
			/**** modified by MSC 03/07/2002 ****/
			if ((attrib & FF_DA_DIR_OR) == 0)
			{
				// only DIR are shown if DA_DIR is specified by user
				if ((attrib & DA_DIR) == DA_DIR)
					if ((entryAttr & DA_DIR) != DA_DIR)
						continue;
			}
			/**** modified by MSC 03/07/2002 ****/

			/* attributes match, compare filename with the wildcard name */
#ifdef FAT_LFN
			longInfo.startBlock = FATRootBegin[drive] + i;
			longInfo.startEntry = j;
			if (i == 0)
				longInfo.endBlock = 0;
			else
				longInfo.endBlock = FATRootBegin[drive] + i - 1;
			longInfo.endEntry = 0;
			status = FAT_getLongName(drive, 1, &longInfo, pBuffer + j, fileName);
			if (status == 1)
			{
				if (nameCompare(wildName, fileName, 1) == 1)
					status = 1;	// the long name (unicode) matches
				else
					status = -1;	// not match
			}
			if (status <= 0)
			{
				getShortName(pBuffer + j, fileName);
				if (nameCompare(wildName, fileName, 0) == 1)
					status = 0;	// the short name matches
				else
					status = -1;
			}	
#else
			getShortName(pBuffer + j, fileName);
			if (nameCompare(wildName, fileName, 0) == 1)
				status = 0;		// the short name matches
			else
				status = -1;
#endif

			if (status != -1)	/* found! */
			{
				// allocate the internal findfile structure, used by FAT_findnext()
				// this structure is deallocated by FAT_findclose()
				if ((ffInfo = (struct FAT_FFInternal *)ap_malloc(sizeof(struct FAT_FFInternal))) == NULL)
				{
					ffres->ff_reserved = 0;
					FATErrno = ERROR_ALLOC_MEM;
					ap_free(blkBuffer);
					ap_free(fileName);
					return -1;
				}
				myMemSet(ffInfo, 0, sizeof(struct FAT_FFInternal));

				/* fill in the FAT_FFInternal structure */
				ffInfo->drive = drive;
				ffInfo->attrib = attrib;
				/* the entry number, counting from the 1st root sector */
				ffInfo->nThEntry = (i * SECTOR_SIZE + j) / FAT_DIR_ENTRY_SIZE;
				/* the cluster number of the directory, 0 for root */
				ffInfo->cluster = 0;
				/* the wildcard name */
				copyName(wildName, ffInfo->wildname, 0);

				ffres->ff_reserved = (long)ffInfo;
				/* copy field from dir entry to result */
//				pEntry = (struct FAT_directory *)(pBuffer + j);
				FAT_load_dir_info(pBuffer + j, &pEntry);
				ffres->ff_attrib = pEntry.attribute;
				ffres->ff_ftime = pEntry.time;
				ffres->ff_fdate = pEntry.date;
				ffres->ff_fsize = pEntry.fsize;
				ffres->ff_drive = FAT_ID;
				/* copy the name from dir entry to result */
				// note that if status = 1, the name is in unicode
				//   otherwise the name is in big5 & ascii
				if (status == 1)
					copyName(fileName, ffres->ff_name, 1);
				else
					copyName(fileName, ffres->ff_name, 0);

				ap_free(blkBuffer);
				ap_free(fileName);
				return 0;
			} /* if loop status */
			/* not found, try next entry */
		} /* for loop j */
		/* not found in this sector, try next sector */
	} /* for loop infinite */
  } /* if loop index */
  else			/* find first in the sub-directory */
  {
	/* find the dir entry of the pathname before the wildcard */

	/* create a file handle for FAT_f_search */
	if ((pfile = (struct FAT_FILE *)ap_malloc(sizeof(struct FAT_FILE))) == NULL)
	{
		ffres->ff_reserved = 0;
		FATErrno = ERROR_ALLOC_MEM;
		ap_free(fileName);
		return -1;
  	}
	myMemSet(pfile, 0, sizeof(struct FAT_FILE));

//	availHandler = FAT_find_free_ftable_entry();
	availHandler = findFreeHandle();
	if (availHandler == -1)
	{
		ap_free(pfile);
		ap_free(fileName);
		ffres->ff_reserved = 0;
		FATErrno = ERROR_NO_HANDLE_AVAIL;
		return -1;
	}
	pfile->fhandle = availHandler;
	FATHandleTable[availHandler] = pfile;

	/* start searching */
	// prepare the pathname where the searching will be done
	// we want to search only the pathname before the wildcard name
	//   the last '\\' is temporary replaced by a '\0'
	//   for example:
	//	target = "c:\dir1\dir2\dir3\*.txt"
	//	path = "\dir1\dir2\dir3\*.txt"
	//	wildName = "*.txt"
	//	last '\\' to '\0' ==>	path = "\dir1\dir2\dir3"
	//				target = "c:\dir1\dir2\dir3"
	//				wildName = "*.txt"
	//   just remember to put '\\' back when the searching is done or error
	path[index] = '\0';

//	status = FAT_f_search(pfile, target);

#ifdef FAT_LFN
	status = FAT_f_search(pfile, target, &longInfo, 0);
#else
	status = FAT_f_search(pfile, target, 0);
#endif

	// reset the last '\\'
	path[index] = '\\';

	if (status == -1 || (pfile->dirEntry.attribute & DA_DIR) != DA_DIR)
	{
		ap_free(pfile);
		ap_free(fileName);
		FATHandleTable[availHandler] = NULL;
		ffres->ff_reserved = 0;
		FATErrno = ERROR_DIR_NOT_EXIST;
		return -1;
	}

	/* the sub-dir is found, start searching for the filename from the 1st entry */
	blkSize = FATBytesPerCluster[drive];	/* sub-dir is handled cluster by cluster */
	if ((blkBuffer = (unsigned short *)ap_malloc(blkSize)) == NULL)
	{
		ap_free(pfile);
		ap_free(fileName);
		FATHandleTable[availHandler] = NULL;
		ffres->ff_reserved = 0;
		FATErrno = ERROR_ALLOC_MEM;
		return -1;
	}

	/* read the starting cluster of the sub-dir */
	cluster = pfile->dirEntry.startCluster;
	prevCluster = 0;

	while (cluster < FATEndOfChain[FATType[drive]])
	{
		FAT_read_cluster(drive, cluster, blkBuffer);
		pBuffer = (unsigned char *)blkBuffer;

		/* compare entry by entry in the sector */
		for (j = 0; j < blkSize; j += FAT_DIR_ENTRY_SIZE)
		{
			/* this entry and every following entry are empty => not found */
			if (*(pBuffer + j) == '\0')
			{
				ap_free(blkBuffer);
				ap_free(pfile);
				ap_free(fileName);
				FATHandleTable[availHandler] = NULL;
				ffres->ff_reserved = 0;
				FATErrno = ERROR_FILE_NOT_EXIST;
				return -1;
			}

			/* skip this entry if it an deleted entry or "." or ".." */
			if (*(pBuffer + j) == 0xe5 || *(pBuffer + j) == '.')
				continue;

			entryAttr = *(pBuffer + j + 11);

			// skip long directory entry
			if ((entryAttr & DA_VFAT) == DA_VFAT)

⌨️ 快捷键说明

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