| Код | 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) continue; /* compare the attribute of this entry with the given attribute */ /* 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; // only DIR are shown if DA_DIR is specified by user if ((attrib & DA_DIR) == DA_DIR) if ((entryAttr & DA_DIR) != DA_DIR) continue; /* attributes match, compare filename with the wildcard name */ #ifdef FAT_LFN longInfo.startBlock = cluster; longInfo.startEntry = j; longInfo.endBlock = prevCluster; longInfo.endEntry = 0; status = FAT_getLongName(drive, 0, &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) { ap_free(blkBuffer); ap_free(pfile); ap_free(fileName); FATHandleTable[availHandler] = NULL; ffres->ff_reserved = 0; FATErrno = ERROR_ALLOC_MEM; 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 = j / FAT_DIR_ENTRY_SIZE; /* the cluster number of the directory, 0 for root */ ffInfo->cluster = cluster; /* the wildcard name */ copyName(wildName, ffInfo->wildname, 0); // fill in the ffblk structure ffres->ff_reserved = (long)ffInfo; // 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(pfile); ap_free(fileName); FATHandleTable[availHandler] = NULL; return 0; } /* if loop status */ /* not found, try next entry */ } /* for loop j */ /* not found in this cluster, try next cluster in the chain */ prevCluster = cluster; cluster = FAT_read_fat_cluster(drive, cluster); } /* all clusters in the chain have been searched, file not found */ ap_free(blkBuffer); ap_free(pfile); ap_free(fileName); FATHandleTable[availHandler] = NULL; ffres->ff_reserved = 0; FATErrno = ERROR_FILE_NOT_EXIST; return -1; } }
|
Добавлено через 1 минуту и 36 секунд и только не надо говорить, что функция мол не та, не родная или еще что-то в этом духе.. |