📄 fat.c
字号:
/*-----------------------------------------------------------------
FAT_GetFileCreationTime
Get the creation time of the last file found or openned.
time_t return OUT: the file's creation time
-----------------------------------------------------------------*/
time_t FAT_GetFileCreationTime (void)
{
// Read in the last accessed directory entry
disc_ReadSector ((wrkDirCluster == FAT16_ROOT_DIR_CLUSTER ? filesysRootDir : FAT_ClustToSect(wrkDirCluster)) + wrkDirSector, globalBuffer);
return FAT_FileTimeToCTime(((DIR_ENT*)globalBuffer)[wrkDirOffset].cTime, ((DIR_ENT*)globalBuffer)[wrkDirOffset].cDate);
}
/*-----------------------------------------------------------------
FAT_GetFileLastWriteTime
Get the creation time of the last file found or openned.
time_t return OUT: the file's creation time
-----------------------------------------------------------------*/
time_t FAT_GetFileLastWriteTime (void)
{
// Read in the last accessed directory entry
disc_ReadSector ((wrkDirCluster == FAT16_ROOT_DIR_CLUSTER ? filesysRootDir : FAT_ClustToSect(wrkDirCluster)) + wrkDirSector, globalBuffer);
return FAT_FileTimeToCTime(((DIR_ENT*)globalBuffer)[wrkDirOffset].mTime, ((DIR_ENT*)globalBuffer)[wrkDirOffset].mDate);
}
#endif
/*-----------------------------------------------------------------
FAT_DirEntFromPath
Finds the directory entry for a file or directory from a path
Path separator is a forward slash /
const char* path: IN null terminated string of path.
DIR_ENT return OUT: dirEntry of found file. First char will be FILE_FREE
if the file was not found
-----------------------------------------------------------------*/
DIR_ENT FAT_DirEntFromPath (const char* path)
{
int pathPos;
char name[MAX_FILENAME_LENGTH];
char alias[13];
int namePos;
char found, notFound;
DIR_ENT dirEntry;
unsigned int dirCluster;
char flagLFN, dotSeen;
// Start at beginning of path
pathPos = 0;
if (path[pathPos] == '/')
{
dirCluster = filesysRootDirClus; // Start at root directory
}
else
{
dirCluster = curWorkDirCluster; // Start at current working dir
}
// Eat any slash /
while ((path[pathPos] == '/') && (path[pathPos] != '\0'))
{
pathPos++;
}
// Search until can't continue
found = false;
notFound = false;
while (!notFound && !found)
{
flagLFN = false;
// Copy name from path
namePos = 0;
if ((path[pathPos] == '.') && ((path[pathPos + 1] == '\0') || (path[pathPos + 1] == '/'))) {
// Dot entry
name[namePos++] = '.';
pathPos++;
} else if ((path[pathPos] == '.') && (path[pathPos + 1] == '.') && ((path[pathPos + 2] == '\0') || (path[pathPos + 2] == '/'))){
// Double dot entry
name[namePos++] = '.';
pathPos++;
name[namePos++] = '.';
pathPos++;
} else {
// Copy name from path
if (path[pathPos] == '.') {
flagLFN = true;
}
dotSeen = false;
while ((namePos < MAX_FILENAME_LENGTH - 1) && (path[pathPos] != '\0') && (path[pathPos] != '/'))
{
name[namePos] = ucase(path[pathPos]);
if ((name[namePos] <= ' ') || ((name[namePos] >= ':') && (name[namePos] <= '?'))) // Invalid character
{
flagLFN = true;
}
if (name[namePos] == '.') {
if (!dotSeen) {
dotSeen = true;
} else {
flagLFN = true;
}
}
namePos++;
pathPos++;
}
// Check if a long filename was specified
if (namePos > 12)
{
flagLFN = true;
}
}
// Add end of string char
name[namePos] = '\0';
// Move through path to correct place
while ((path[pathPos] != '/') && (path[pathPos] != '\0'))
pathPos++;
// Eat any slash /
while ((path[pathPos] == '/') && (path[pathPos] != '\0'))
{
pathPos++;
}
// Search current Dir for correct entry
dirEntry = FAT_GetDirEntry (dirCluster, 1, SEEK_SET);
while ( !found && !notFound)
{
// Match filename
found = true;
for (namePos = 0; (namePos < MAX_FILENAME_LENGTH) && found && (name[namePos] != '\0') && (lfnName[namePos] != '\0'); namePos++)
{
if (name[namePos] != ucase(lfnName[namePos]))
{
found = false;
}
}
if ((name[namePos] == '\0') != (lfnName[namePos] == '\0'))
{
found = false;
}
// Check against alias as well.
if (!found)
{
FAT_GetFilename(dirEntry, alias);
found = true;
for (namePos = 0; (namePos < 13) && found && (name[namePos] != '\0') && (alias[namePos] != '\0'); namePos++)
{
if (name[namePos] != ucase(alias[namePos]))
{
found = false;
}
}
if ((name[namePos] == '\0') != (alias[namePos] == '\0'))
{
found = false;
}
}
if (dirEntry.name[0] == FILE_FREE)
// Couldn't find specified file
{
found = false;
notFound = true;
}
if (!found && !notFound)
{
dirEntry = FAT_GetDirEntry (dirCluster, 1, SEEK_CUR);
}
}
if (found && ((dirEntry.attrib & ATTRIB_DIR) == ATTRIB_DIR) && (path[pathPos] != '\0'))
// It has found a directory from within the path that needs to be followed
{
found = false;
dirCluster = dirEntry.startCluster | (dirEntry.startClusterHigh << 16);
}
}
if (notFound)
{
dirEntry.name[0] = FILE_FREE;
dirEntry.attrib = 0x00;
}
return (dirEntry);
}
#ifdef CAN_WRITE_TO_DISC
/*-----------------------------------------------------------------
FAT_AddDirEntry
Creates a new dir entry for a file
Path separator is a forward slash /
const char* path: IN null terminated string of path to file.
DIR_ENT newDirEntry IN: The directory entry to use.
int file IN: The file being added (optional, use -1 if not used)
char return OUT: true if successful
-----------------------------------------------------------------*/
char FAT_AddDirEntry (const char* path, DIR_ENT newDirEntry)
{
char filename[MAX_FILENAME_LENGTH];
int filePos, pathPos, aliasPos;
char tempChar;
char flagLFN, dotSeen;
char fileAlias[13] = {0};
int tailNum;
unsigned char chkSum = 0;
unsigned int oldWorkDirCluster;
DIR_ENT* dirEntries = (DIR_ENT*)globalBuffer;
unsigned int dirCluster;
int secOffset;
int entryOffset;
//int maxSectors;
unsigned int firstSector;
DIR_ENT_LFN lfnEntry;
int lfnPos = 0;
int dirEntryLength = 0;
int dirEntryRemain = 0;
unsigned int tempDirCluster;
int tempSecOffset;
int tempEntryOffset;
char dirEndFlag = false;
int i;
// Store current working directory
oldWorkDirCluster = curWorkDirCluster;
// Find filename within path and change to correct directory
if (path[0] == '/')
{
curWorkDirCluster = filesysRootDirClus;
}
pathPos = 0;
filePos = 0;
flagLFN = false;
while (path[pathPos + filePos] != '\0')
{
if (path[pathPos + filePos] == '/')
{
filename[filePos] = '\0';
if (FAT_chdir(filename) == false)
{
curWorkDirCluster = oldWorkDirCluster;
return false; // Couldn't change directory
}
pathPos += filePos + 1;
filePos = 0;
}
filename[filePos] = path[pathPos + filePos];
filePos++;
}
// Skip over last slashes
while (path[pathPos] == '/')
pathPos++;
// Check if the filename has a leading "."
// If so, it is an LFN
if (path[pathPos] == '.') {
flagLFN = true;
}
// Copy name from path
filePos = 0;
dotSeen = false;
while ((filePos < MAX_FILENAME_LENGTH - 1) && (path[pathPos] != '\0'))
{
filename[filePos] = path[pathPos];
if ((filename[filePos] <= ' ') || ((filename[filePos] >= ':') && (filename[filePos] <= '?'))) // Invalid character
{
flagLFN = true;
}
if (filename[filePos] == '.') {
if (!dotSeen) {
dotSeen = true;
} else {
flagLFN = true;
}
}
filePos++;
pathPos++;
if ((filePos > 8) && !dotSeen) {
flagLFN = true;
}
}
if (filePos == 0) // No filename
{
return false;
}
// Check if a long filename was specified
if (filePos > 12)
{
flagLFN = true;
}
// Check if extension is > 3 characters long
if (!flagLFN && (strrchr (filename, '.') != NULL) && (strlen(strrchr(filename, '.')) > 4)) {
flagLFN = true;
}
lfnPos = (filePos - 1) / 13;
// Add end of string char
filename[filePos++] = '\0';
// Clear remaining chars
while (filePos < MAX_FILENAME_LENGTH)
filename[filePos++] = 0x01; // Set for LFN compatibility
if (flagLFN)
{
// Generate short filename - always a 2 digit number for tail
// Get first 5 chars of alias from LFN
aliasPos = 0;
filePos = 0;
if (filename[filePos] == '.') {
filePos++;
}
for ( ; (aliasPos < 5) && (filename[filePos] != '\0') && (filename[filePos] != '.') ; filePos++)
{
tempChar = ucase(filename[filePos]);
if (((tempChar > ' ' && tempChar < ':') || tempChar > '?') && tempChar != '.')
fileAlias[aliasPos++] = tempChar;
}
// Pad Alias with underscores
while (aliasPos < 5)
fileAlias[aliasPos++] = '_';
fileAlias[5] = '~';
fileAlias[8] = '.';
fileAlias[9] = ' ';
fileAlias[10] = ' ';
fileAlias[11] = ' ';
if (strchr (filename, '.') != NULL) {
while(filename[filePos] != '\0')
{
filePos++;
if (filename[filePos] == '.')
{
pathPos = filePos;
}
}
filePos = pathPos + 1; //pathPos is used as a temporary variable
// Copy first 3 characters of extension
for (aliasPos = 9; (aliasPos < 12) && (filename[filePos] != '\0'); filePos++)
{
tempChar = ucase(filename[filePos]);
if ((tempChar > ' ' && tempChar < ':') || tempChar > '?')
fileAlias[aliasPos++] = tempChar;
}
} else {
aliasPos = 9;
}
// Pad Alias extension with spaces
while (aliasPos < 12)
fileAlias[aliasPos++] = ' ';
fileAlias[12] = '\0';
// Get a valid tail number
tailNum = 0;
do {
tailNum++;
fileAlias[6] = 0x30 + ((tailNum / 10) % 10); // 10's digit
fileAlias[7] = 0x30 + (tailNum % 10); // 1's digit
} while ((FAT_DirEntFromPath(fileAlias).name[0] != FILE_FREE) && (tailNum < 100));
if (tailNum < 100) // Found an alias not being used
{
// Calculate file checksum
chkSum = 0;
for (aliasPos=0; aliasPos < 12; aliasPos++)
{
// Skip '.'
if (fileAlias[aliasPos] == '.')
aliasPos++;
// NOTE: The operation is an unsigned char rotate right
chkSum = ((chkSum & 1) ? 0x80 : 0) + (chkSum >> 1) + fileAlias[aliasPos];
}
}
else // Couldn't find a valid alias
{
return false;
}
dirEntryLength = lfnPos + 2;
}
else // Its not a long file name
{
// Just copy alias straight from filename
for (aliasPos = 0; aliasPos < 13; aliasPos++)
{
tempChar = ucase(filename[aliasPos]);
if ((tempChar > ' ' && tempChar < ':') || tempChar > '?')
fileAlias[aliasPos] = tempChar;
}
fileAlias[12] = '\0';
lfnPos = -1;
dirEntryLength = 1;
}
// Change dirEntry name to match alias
for (aliasPos = 0; ((fileAlias[aliasPos] != '.') && (fileAlias[aliasPos] != '\0') && (aliasPos < 8)); aliasPos++)
{
newDirEntry.name[aliasPos] = fileAlias[aliasPos];
}
while (aliasPos < 8)
{
newDirEntry.name[aliasPos++] = ' ';
}
aliasPos = 0;
while ((fileAlias[aliasPos] != '.') && (fileAlias[aliasPos] != '\0'))
aliasPos++;
filePos = 0;
while (( filePos < 3 ) && (fileAlias[aliasPos] != '\0'))
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -