📄 ffindx.c
字号:
/*************************************************************
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 + -