📄 fscan.c
字号:
}
myMemSet(fileName, 0, FAT_MAX_LFN_LENGTH * 2);
#else
if ((fileName = (unsigned char *)ap_malloc(13)) == NULL)
{
FATErrno = ERROR_ALLOC_MEM;
return -1;
}
myMemSet(fileName, 0, 13);
#endif
#ifdef FAT_LFN
if (strlen((const char *)upperDir) == 1)
status = FAT_getLongName(drive, 1, longInfo, (unsigned char *)entry, fileName);
else
status = FAT_getLongName(drive, 0, longInfo, (unsigned char *)entry, fileName);
if (status != 1)
{
// not a long filename
// copy the file name from dir entry to buffer
pIndex = 0;
for (i = 0; i < FAT_FILE_NAME_LENGTH; i++)
{
if (entry->name[i] == ' ')
break;
fileName[pIndex++] = entry->name[i];
}
fileName[pIndex++] = '.';
for (i = 0; i < FAT_EXT_NAME_LENGTH; i++)
{
if (entry->ext[i] == ' ')
break;
fileName[pIndex++] = entry->ext[i];
}
if (fileName[pIndex - 1] == '.')
fileName[pIndex - 1] = '\0';
else
fileName[pIndex] = '\0';
}
else if (status == -1)
{
ap_free(fileName);
return -1;
}
// else
// unicodeToASCII(fileName);
#else
// copy the file name from dir entry to buffer
pIndex = 0;
for (i = 0; i < FAT_FILE_NAME_LENGTH; i++)
{
if (entry->name[i] == ' ')
break;
fileName[pIndex++] = entry->name[i];
}
fileName[pIndex++] = '.';
for (i = 0; i < FAT_EXT_NAME_LENGTH; i++)
{
if (entry->ext[i] == ' ')
break;
fileName[pIndex++] = entry->ext[i];
}
if (fileName[pIndex - 1] == '.')
fileName[pIndex - 1] = '\0';
else
fileName[pIndex] = '\0';
#endif
// if this entry is a sub-dir, information is inserted to the dirList and is
// proceeded after all files in the same dir level are done checking
if ((entry->attribute & DA_DIR) == DA_DIR)
{
if (echo == ECHO_ON)
{
printString("[DIR] ");
printString((char *)upperDir);
printString((char *)fileName);
}
// this is a sub-directory, check if it is valid
// (1) check the starting cluster of the sub-directory
if ((entry->startCluster >= FATTotalCluster[drive] + 2) ||
(entry->startCluster < 2))
{
// cluster number out of bound => unrecoverable error
if (echo == ECHO_ON)
printStringLn(" [INVALID STARTING CLUSTER]");
#ifdef FAT_LFN
if (autoFix == 1)
{
if (strlen((const char *)upperDir) == 1)
{
if (FAT_deleteLongName(drive, 1, longInfo, blockBuffer) != 1)
{
printStringLn("Delete long filename error!");
ap_free(fileName);
return -1;
}
}
else
{
if (FAT_deleteLongName(drive, 0, longInfo, blockBuffer) != 1)
{
printStringLn("Delete long filename error!");
ap_free(fileName);
return -1;
}
}
}
#else
entry->name[0] = FAT_DELETED_ENTRY;
#endif
ap_free(fileName);
fileErrCount++;
return 1;
}
// (2) check if the 1st and 2nd entries in the sub-directory
if ((dirBuf = (unsigned short *)ap_malloc(FATBytesPerCluster[drive])) == NULL)
{
FATErrno = ERROR_ALLOC_MEM;
ap_free(fileName);
return -1;
}
pBuf = (unsigned char *)dirBuf;
if (FAT_read_cluster(drive, entry->startCluster, dirBuf) == -1)
{
FATErrno = ERROR_ATA_READ;
ap_free(fileName);
ap_free(dirBuf);
return -1;
}
if (pBuf[0] != '.' || pBuf[1] != ' ' ||
pBuf[0 + FAT_DIR_ENTRY_SIZE] != '.' || pBuf[1 + FAT_DIR_ENTRY_SIZE] != '.')
{
// the 1st and 2nd entries of the directory is not "." and ".."
if (echo == ECHO_ON)
printStringLn(" [INVALID DIRECTORY (. AND ..)]");
#ifdef FAT_LFN
if (autoFix == 1)
{
if (strlen((const char *)upperDir) == 1)
{
if (FAT_deleteLongName(drive, 1, longInfo, blockBuffer) != 1)
{
printStringLn("Delete long filename error!");
ap_free(fileName);
ap_free(dirBuf);
return -1;
}
}
else
{
if (FAT_deleteLongName(drive, 0, longInfo, blockBuffer) != 1)
{
printStringLn("Delete long filename error!");
ap_free(fileName);
ap_free(dirBuf);
return -1;
}
}
}
#else
entry->name[0] = FAT_DELETED_ENTRY;
#endif
fileErrCount++;
ap_free(fileName);
ap_free(dirBuf);
return 1;
}
if (echo == ECHO_ON)
printStringLn(" [OK]");
ap_free(dirBuf);
// this dir entry is ok, insert it to the dir list
if ((mydir = (struct scan_dir *)ap_malloc(sizeof(struct scan_dir))) == NULL)
{
FATErrno = ERROR_ALLOC_MEM;
ap_free(fileName);
return -1;
}
// this buffer is free after it has been removed from the dir list
// copy the name of the upper directory
pIndex = 0;
while (upperDir[pIndex] != 0)
{
mydir->pathName[pIndex] = upperDir[pIndex];
pIndex++;
}
// copy the 8.3 name of the dir
i = 0;
while (fileName[i] != 0)
mydir->pathName[pIndex++] = fileName[i++];
mydir->pathName[pIndex++] = '\\';
mydir->pathName[pIndex] = '\0';
mydir->startCluster = entry->startCluster;
if (insertTo(&dirList, (void *)mydir) == FAIL)
{
FATErrno = ERROR_OPERATING_SYSTEM_ERROR;
ap_free(mydir);
ap_free(fileName);
return -1;
}
ap_free(fileName);
return 0;
}
// this is a file, starting checking
// print filename
if (echo == ECHO_ON)
{
printString("[FILE] ");
printString((char *)upperDir);
printString((char *)fileName);
}
if ((entry->startCluster >= FATTotalCluster[drive] + 2) || (entry->startCluster < 2))
{
// cluster number out of bound => unrecoverable error
if (echo == ECHO_ON)
printStringLn(" [INVALID STARTING CLUSTER]");
#ifdef FAT_LFN
if (autoFix == 1)
{
if (strlen((const char *)upperDir) == 1)
{
if (FAT_deleteLongName(drive, 1, longInfo, blockBuffer) != 1)
{
printStringLn("Delete long filename error!");
ap_free(fileName);
return -1;
}
}
else
{
if (FAT_deleteLongName(drive, 0, longInfo, blockBuffer) != 1)
{
printStringLn("Delete long filename error!");
ap_free(fileName);
return -1;
}
}
}
#else
entry->name[0] = FAT_DELETED_ENTRY;
#endif
fileErrCount++;
ap_free(fileName);
return 1;
}
clusterNO = (unsigned short)(entry->fsize / FATBytesPerCluster[drive]);
remains = (unsigned short)(entry->fsize % FATBytesPerCluster[drive]);
if (remains != 0)
clusterNO++;
// check FAT1 (FATBuf)
traceCluster = entry->startCluster;
pBuf = (unsigned char *) FATBuf;
for (i = 1; i < clusterNO; i++)
{
// get next cluster in the chain
// fat12
if (FATType[drive] == PART_DOS2_FAT)
{
if ((traceCluster & 0x0001) == 0x0001)
{
// part1 // part2
tempCluster = ((unsigned short)pBuf[(traceCluster * 3 / 2) + 1] << 4) + ((pBuf[traceCluster * 3 / 2] & 0xF0) >> 4);
// clear this FAT entry since it has already been handled
// part1
pBuf[traceCluster * 3 / 2] &= 0x0F;
// part2
pBuf[(traceCluster * 3 / 2) + 1] = 0x0;
}
else
{
// part2 // part1
tempCluster = (((unsigned short)pBuf[(traceCluster * 3 / 2) + 1] & 0x0F) << 8) + pBuf[traceCluster * 3 / 2];
// clear this FAT entry since it has already been handled
// part1
pBuf[traceCluster * 3 / 2] &= 0x0;
// part2
pBuf[(traceCluster * 3 / 2) + 1] &= 0xF0;
}
}
// fat16
else
{
tempCluster = FATBuf[traceCluster];
// clear this FAT entry since it has already been handled
FATBuf[traceCluster] = 0x0;
}
// check if the cluster is valid
if (tempCluster >= FATTotalCluster[drive] + 2 || tempCluster < 2)
{
if (autoFix == 1)
FAT_write_fat_cluster(drive, traceCluster, FATEndOfChain[FATType[drive]]);
entry->fsize = i * FATBytesPerCluster[drive];
if (echo == ECHO_ON)
{
printStringLn(" [FILE SIZE AND CLUSTER CHAIN UNMATCH]");
}
fileErrCount++;
ap_free(fileName);
return 1;
}
traceCluster = tempCluster;
}
// fat12
if (FATType[drive] == PART_DOS2_FAT)
{
if ((traceCluster & 0x0001) == 0x0001)
{
// part1 // part2
tempCluster = ((unsigned short)pBuf[(traceCluster * 3 / 2) + 1] << 4) + ((pBuf[traceCluster * 3 / 2] & 0xF0) >> 4);
// clear this FAT entry since it has already been handled
// part1
pBuf[traceCluster * 3 / 2] &= 0x0F;
// part2
pBuf[(traceCluster * 3 / 2) + 1] = 0x0;
}
else
{
// part2 // part1
tempCluster = (((unsigned short)pBuf[(traceCluster * 3 / 2) + 1] & 0x0F) << 8) + pBuf[traceCluster * 3 / 2];
// clear this FAT entry since it has already been handled
// part1
pBuf[traceCluster * 3 / 2] &= 0x0;
// part2
pBuf[(traceCluster * 3 / 2) + 1] &= 0xF0;
}
}
// fat16
else
{
tempCluster = FATBuf[traceCluster];
// clear this FAT entry since it has already been handled
FATBuf[traceCluster] = 0x0;
}
if (tempCluster < FATEndOfChain[FATType[drive]])
{
if (autoFix == 1)
FAT_write_fat_cluster(drive, traceCluster, FATEndOfChain[FATType[drive]]);
if (echo == ECHO_ON)
printStringLn(" [FILE SIZE AND CLUSTER CHAIN UNMATCH]");
fileErrCount++;
ap_free(fileName);
return 1;
}
if (echo == ECHO_ON)
printStringLn(" [OK]");
ap_free(fileName);
return 0;
}
/*************************************************************
Fuction : checkDir
Check the integrity of a sub-directory
Input:
drive - the target drive
name - the complete pathname of the target sub-directory
head - the head cluster in the cluster chain of the target sub-directory
Output:
0: SUCCESS
1: directory has error
-1: FAILURE (check FATErrno)
**************************************************************/
//int checkDir(unsigned char *name, unsigned short head)
int FAT_checkDir(int drive, unsigned char *name, unsigned short head)
{
int i;
int status;
unsigned short *dirBuf;
unsigned char *pBuf;
unsigned short traceCluster, tempCluster;
char changed = 0;
char noMore = 0;
unsigned char *pFatBuf;
#ifdef FAT_LFN
struct FAT_LFNinfo longInfo;
unsigned short prevCluster = 0;
#endif
if ((dirBuf = (unsigned short *)ap_malloc(FATBytesPerCluster[drive])) == NULL)
{
FATErrno = ERROR_ALLOC_MEM;
return -1;
}
pBuf = (unsigned char *)dirBuf;
traceCluster = head;
pFatBuf = (unsigned char*)FATBuf;
while (traceCluster < FATEndOfChain[FATType[drive]])
{
changed = 0;
// get the cluster of the sub-directory
if (FAT_read_cluster(drive, traceCluster, dirBuf) == -1)
{
FATErrno = ERROR_ATA_READ;
ap_free(dirBuf);
return -1;
}
for (i = 0; i < FATBytesPerCluster[drive]; i += FAT_DIR_ENTRY_SIZE)
{
if (*(pBuf + i) == '\0')
{
noMore = 1; // no more entry after empty one
break;
}
else
{
#ifdef FAT_LFN
longInfo.startBlock = traceCluster;
longInfo.startEntry = i;
longInfo.endBlock = prevCluster;
longInfo.endEntry = 0;
status = FAT_checkEntry(drive, name, (struct FAT_directory *)(pBuf + i), &longInfo, dirBuf);
#else
status = FAT_checkEntry(drive, name, (struct FAT_directory *)(pBuf + i));
#endif
if (status == -1)
{
ap_free(dirBuf);
// system error checking file
return -1;
}
else if (status == 1)
{
// The entry has unrecoverable error and has been deleted,
// but the actual disk writing is not yet done
// Note that the cluster chain has not been cleared and
// becomes unchained, will be handled in next phase
changed = 1; // this sector has been changed
}
}
}
#ifdef FAT_LFN
#else
// if the dir entries have been changed and the automatic fix is enabled,
// actually write the changes to the disk
if (changed == 1 && autoFix == 1)
{
if (FAT_write_cluster(drive, traceCluster, dirBuf) == ATA_FAILURE)
{
FATErrno = ERROR_ATA_WRITE;
ap_free(dirBuf);
return -1;
}
}
#endif
// fat12
if (FATType[drive] == PART_DOS2_FAT)
{
if ((traceCluster & 0x0001) == 0x0001)
{
// part1 // part2
tempCluster = ((unsigned short)pFatBuf[(traceCluster * 3 / 2) + 1] << 4) + ((pFatBuf[traceCluster * 3 / 2] & 0xF0) >> 4);
// clear this FAT entry since it has already been handled
// part1
pFatBuf[traceCluster * 3 / 2] &= 0x0F;
// part2
pFatBuf[(traceCluster * 3 / 2) + 1] = 0x0;
}
else
{
// part2 // part1
tempCluster = (((unsigned short)pFatBuf[(traceCluster * 3 / 2) + 1] & 0x0F) << 8) + pFatBuf[traceCluster * 3 / 2];
// clear this FAT entry since it has already been handled
// part1
pFatBuf[traceCluster * 3 / 2] &= 0x0;
// part2
pFatBuf[(traceCluster * 3 / 2) + 1] &= 0xF0;
}
}
else
{
tempCluster = FATBuf[traceCluster];
// clear this FAT entry since it has already been handled
FATBuf[traceCluster] = 0x0;
}
// get next cluster in the chain
// tempCluster = FATBuf[traceCluster];
// clear this FAT entry since it has already been proceeded
// FATBuf[traceCluster] = 0x0;
// empty dir entry found, see if the cluster chain actually ends at this cluster
if (noMore == 1)
{
if (tempCluster < FATEndOfChain[FATType[drive]])
{
// there should be no more cluster but the cluster chain is not end yet
if (echo == ECHO_ON)
{
printString("[DIR] ");
printString((char *)name);
printStringLn(" [CLUSTER CHAIN INCORRECT]");
}
if (autoFix == 1)
{
// well, fix this error by giving the chain a real end
FAT_write_fat_cluster(drive, traceCluster, FATEndOfChain[FATType[drive]]);
}
fileErrCount++;
ap_free(dirBuf);
return 1;
}
}
if (tempCluster >= FATEndOfChain[FATType[drive]])
break;
// check if the cluster is valid
if (tempCluster >= FATTotalCluster[drive] + 2 || tempCluster < 2)
{
if (autoFix == 1)
FAT_write_fat_cluster(drive, traceCluster, FATEndOfChain[FATType[drive]]);
if (echo == ECHO_ON)
{
printString("[DIR] ");
printString((char *)name);
printStringLn(" [INCORRECT CLUSTER CHAIN]");
}
fileErrCount++;
ap_free(dirBuf);
return 1;
}
#ifdef FAT_LFN
prevCluster = traceCluster;
#endif
traceCluster = tempCluster;
}
ap_free(dirBuf);
return 0;
}
#endif // FAT_ID
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -