📄 fat.c
字号:
{
tempChar = fileAlias[aliasPos++];
if ((tempChar > ' ' && tempChar < ':' && tempChar!='.') || tempChar > '?')
newDirEntry.ext[filePos++] = tempChar;
}
while (filePos < 3)
{
newDirEntry.ext[filePos++] = ' ';
}
// Scan Dir for free entry
dirCluster = curWorkDirCluster;
secOffset = 0;
entryOffset = 0;
//maxSectors = (dirCluster == FAT16_ROOT_DIR_CLUSTER ? (filesysData - filesysRootDir) : filesysSecPerClus);
firstSector = (dirCluster == FAT16_ROOT_DIR_CLUSTER ? filesysRootDir : FAT_ClustToSect(dirCluster));
disc_ReadSector (firstSector + secOffset, dirEntries);
dirEntryRemain = dirEntryLength;
tempDirCluster = dirCluster;
tempSecOffset = secOffset;
tempEntryOffset = entryOffset;
// Search for a large enough space to fit in new directory entry
while ((dirEntries[entryOffset].name[0] != FILE_LAST) && (dirEntryRemain > 0))
{
entryOffset++;
if (entryOffset == BYTE_PER_READ / sizeof (DIR_ENT))
{
entryOffset = 0;
secOffset++;
if ((secOffset == filesysSecPerClus) && (dirCluster != FAT16_ROOT_DIR_CLUSTER))
{
secOffset = 0;
if (FAT_NextCluster(dirCluster) == CLUSTER_EOF)
{
dirCluster = FAT_LinkFreeCluster(dirCluster);
dirEntries[0].name[0] = FILE_LAST;
}
else
{
dirCluster = FAT_NextCluster(dirCluster);
}
firstSector = FAT_ClustToSect(dirCluster);
}
else if ((dirCluster == FAT16_ROOT_DIR_CLUSTER) && (secOffset == (filesysData - filesysRootDir)))
{
return false; // Got to end of root dir - can't fit in more files
}
disc_ReadSector (firstSector + secOffset, dirEntries);
}
if ((dirEntries[entryOffset].name[0] == FILE_FREE) || (dirEntries[entryOffset].name[0] == FILE_LAST) )
{
dirEntryRemain--;
} else {
dirEntryRemain = dirEntryLength;
tempDirCluster = dirCluster;
tempSecOffset = secOffset;
tempEntryOffset = entryOffset;
}
}
// Modifying the last directory is a special case - have to erase following entries
if (dirEntries[entryOffset].name[0] == FILE_LAST)
{
dirEndFlag = true;
}
// Recall last used entry
dirCluster = tempDirCluster;
secOffset = tempSecOffset;
entryOffset = tempEntryOffset;
dirEntryRemain = dirEntryLength;
// Re-read in first sector that will be written to
if (dirEndFlag && (entryOffset == 0)) {
memset (dirEntries, FILE_LAST, BYTE_PER_READ);
} else {
disc_ReadSector (firstSector + secOffset, dirEntries);
}
// Add new directory entry
while (dirEntryRemain > 0)
{
// Move to next entry, first pass advances from last used entry
entryOffset++;
if (entryOffset == BYTE_PER_READ / sizeof (DIR_ENT))
{
// Write out the current sector if we need to
entryOffset = 0;
if (dirEntryRemain < dirEntryLength) // Don't write out sector on first pass
{
disc_WriteSector (firstSector + secOffset, dirEntries);
}
secOffset++;
if ((secOffset == filesysSecPerClus) && (dirCluster != FAT16_ROOT_DIR_CLUSTER))
{
secOffset = 0;
if (FAT_NextCluster(dirCluster) == CLUSTER_EOF)
{
dirCluster = FAT_LinkFreeCluster(dirCluster);
dirEntries[0].name[0] = FILE_LAST;
}
else
{
dirCluster = FAT_NextCluster(dirCluster);
}
firstSector = FAT_ClustToSect(dirCluster);
}
else if ((dirCluster == FAT16_ROOT_DIR_CLUSTER) && (secOffset == (filesysData - filesysRootDir)))
{
return false; // Got to end of root dir - can't fit in more files
}
if (dirEndFlag)
{
memset (dirEntries, FILE_LAST, BYTE_PER_READ);
} else {
disc_ReadSector (firstSector + secOffset, dirEntries);
}
}
// Generate LFN entries
if (lfnPos >= 0)
{
lfnEntry.ordinal = (lfnPos + 1) | (dirEntryRemain == dirEntryLength ? LFN_END : 0);
for (i = 0; i < 13; i++) {
if (filename [lfnPos * 13 + i] == 0x01) {
((unsigned char*)&lfnEntry)[(int)lfn_offset_table[i]] = 0xff;
((unsigned char*)&lfnEntry)[(int)(lfn_offset_table[i]) + 1] = 0xff;
} else {
((unsigned char*)&lfnEntry)[(int)lfn_offset_table[i]] = filename [lfnPos * 13 + i];
((unsigned char*)&lfnEntry)[(int)(lfn_offset_table[i]) + 1] = 0x00;
}
}
lfnEntry.checkSum = chkSum;
lfnEntry.flag = ATTRIB_LFN;
lfnEntry.reserved1 = 0;
lfnEntry.reserved2 = 0;
*((DIR_ENT_LFN*)&dirEntries[entryOffset]) = lfnEntry;
lfnPos --;
lfnEntry.ordinal = 0;
} // end writing long filename entries
else
{
dirEntries[entryOffset] = newDirEntry;
if (dirEndFlag && (entryOffset < (BYTE_PER_READ / sizeof (DIR_ENT))) )
dirEntries[entryOffset+1].name[0] = FILE_LAST;
}
dirEntryRemain--;
}
// Write directory back to disk
disc_WriteSector (firstSector + secOffset, dirEntries);
// Change back to Working DIR
curWorkDirCluster = oldWorkDirCluster;
return true;
}
#endif
/*-----------------------------------------------------------------
FAT_FindNextFile
Gets the name of the next directory entry
(can be a file or subdirectory)
char* filename: OUT filename, must be at least 13 chars long
FILE_TYPE return: OUT returns FT_NONE if failed,
FT_FILE if it found a file and FT_DIR if it found a directory
-----------------------------------------------------------------*/
FILE_TYPE FAT_FindNextFile(char* filename)
{
// Get the next directory entry
DIR_ENT file;
file = FAT_GetDirEntry (curWorkDirCluster, 1, SEEK_CUR);
if (file.name[0] == FILE_FREE)
{
return FT_NONE; // Did not find a file
}
// Get the filename
if (filename != NULL)
FAT_GetFilename (file, filename);
if ((file.attrib & ATTRIB_DIR) != 0)
{
return FT_DIR; // Found a directory
}
else
{
return FT_FILE; // Found a file
}
}
/*-----------------------------------------------------------------
FAT_FindFirstFile
Gets the name of the first directory entry and resets the count
(can be a file or subdirectory)
char* filename: OUT filename, must be at least 13 chars long
FILE_TYPE return: OUT returns FT_NONE if failed,
FT_FILE if it found a file and FT_DIR if it found a directory
-----------------------------------------------------------------*/
FILE_TYPE FAT_FindFirstFile(char* filename)
{
// Get the first directory entry
DIR_ENT file;
file = FAT_GetDirEntry (curWorkDirCluster, 1, SEEK_SET);
if (file.name[0] == FILE_FREE)
{
return FT_NONE; // Did not find a file
}
// Get the filename
if (filename != NULL)
FAT_GetFilename (file, filename);
if ((file.attrib & ATTRIB_DIR) != 0)
{
return FT_DIR; // Found a directory
}
else
{
return FT_FILE; // Found a file
}
}
/*-----------------------------------------------------------------
FAT_FindFirstFileLFN
Gets the long file name of the first directory entry and resets
the count (can be a file or subdirectory)
char* lfn: OUT long file name, must be at least 256 chars long
FILE_TYPE return: OUT returns FT_NONE if failed,
FT_FILE if it found a file and FT_DIR if it found a directory
-----------------------------------------------------------------*/
FILE_TYPE FAT_FindFirstFileLFN(char* lfn)
{
FILE_TYPE type;
type = FAT_FindFirstFile(NULL);
FAT_GetLongFilename (lfn);
return type;
}
/*-----------------------------------------------------------------
FAT_FindNextFileLFN
Gets the long file name of the next directory entry
(can be a file or subdirectory)
char* lfn: OUT long file name, must be at least 256 chars long
FILE_TYPE return: OUT returns FT_NONE if failed,
FT_FILE if it found a file and FT_DIR if it found a directory
-----------------------------------------------------------------*/
FILE_TYPE FAT_FindNextFileLFN(char* lfn)
{
FILE_TYPE type;
type = FAT_FindNextFile(NULL);
FAT_GetLongFilename (lfn);
return type;
}
/*-----------------------------------------------------------------
FAT_FileExists
Returns the type of file
char* filename: IN filename of the file to look for
FILE_TYPE return: OUT returns FT_NONE if there is now file with
that name, FT_FILE if it is a file and FT_DIR if it is a directory
-----------------------------------------------------------------*/
FILE_TYPE FAT_FileExists(const char* filename)
{
DIR_ENT dirEntry;
// Get the dirEntry for the path specified
dirEntry = FAT_DirEntFromPath (filename);
if (dirEntry.name[0] == FILE_FREE)
{
return FT_NONE;
}
else if (dirEntry.attrib & ATTRIB_DIR)
{
return FT_DIR;
}
else
{
return FT_FILE;
}
}
/*-----------------------------------------------------------------
FAT_GetFileSystemType
FS_TYPE return: OUT returns the current file system type
-----------------------------------------------------------------*/
FS_TYPE FAT_GetFileSystemType (void)
{
return filesysType;
}
/*-----------------------------------------------------------------
FAT_GetFileSystemTotalSize
unsigned int return: OUT returns the total disk space (used + free)
-----------------------------------------------------------------*/
unsigned int FAT_GetFileSystemTotalSize (void)
{
return filesysTotalSize;
}
/*-----------------------------------------------------------------
FAT_chdir
Changes the current working directory
const char* path: IN null terminated string of directory separated by
forward slashes, / is root
char return: OUT returns true if successful
-----------------------------------------------------------------*/
char FAT_chdir (const char* path)
{
DIR_ENT dir;
if (path[0] == '/' && path[1] == '\0')
{
curWorkDirCluster = filesysRootDirClus;
return true;
}
if (path[0] == '\0') // Return true if changing relative to nothing
{
return true;
}
dir = FAT_DirEntFromPath (path);
if (((dir.attrib & ATTRIB_DIR) == ATTRIB_DIR) && (dir.name[0] != FILE_FREE))
{
// Change directory
curWorkDirCluster = dir.startCluster | (dir.startClusterHigh << 16);
// Move to correct cluster for root directory
if (curWorkDirCluster == FAT16_ROOT_DIR_CLUSTER)
{
curWorkDirCluster = filesysRootDirClus;
}
// Reset file position in directory
wrkDirCluster = curWorkDirCluster;
wrkDirSector = 0;
wrkDirOffset = -1;
return true;
}
else
{
// Couldn't change directory - wrong path specified
return false;
}
}
/*-----------------------------------------------------------------
FAT_fopen(filename, mode)
Opens a file
const char* path: IN null terminated string of filename and path
separated by forward slashes, / is root
const char* mode: IN mode to open file in
Supported modes: "r", "r+", "w", "w+", "a", "a+", don't use
"b" or "t" in any mode, as all files are openned in binary mode
FAT_FILE* return: OUT handle to open file, returns NULL if the file
couldn't be openned
-----------------------------------------------------------------*/
FAT_FILE* FAT_fopen(const char* path, const char* mode)
{
int fileNum;
FAT_FILE* file;
DIR_ENT dirEntry;
#ifdef CAN_WRITE_TO_DISC
unsigned int startCluster;
int clusCount;
#endif
char* pchTemp;
// Check that a valid mode was specified
pchTemp = strpbrk ( mode, "rRwWaA" );
if (pchTemp == NULL)
{
return NULL;
}
if (strpbrk ( pchTemp+1, "rRwWaA" ) != NULL)
{
return NULL;
}
// Get the dirEntry for the path specified
dirEntry = FAT_DirEntFromPath (path);
// Check that it is not a directory
if (dirEntry.attrib & ATTRIB_DIR)
{
return NULL;
}
#ifdef CAN_WRITE_TO_DISC
// Check that it is not a read only file being openned in a writing mode
if ( (strpbrk(mode, "wWaA+") != NULL) && (dirEntry.attrib & ATTRIB_RO))
{
return NULL;
}
#else
if ( (strpbrk(mode, "wWaA+") != NULL))
{
return NULL;
}
#endif
// Find a free file buffer
for (fileNum = 0; (fileNum < MAX_FILES_OPEN) && (openFiles[fileNum].inUse == true); fileNum++);
if (fileNum == MAX_FILES_OPEN) // No free files
{
return NULL;
}
file = &openFiles[fileNum];
// Remember where directory entry was
file->dirEntSector = (wrkDirCluster == FAT16_ROOT_DIR_CLUSTER ? filesysRootDir : FAT_ClustToSect(wrkDirCluster)) + wrkDirSector;
file->dirEntOffset = wrkDirOffset;
if ( strpbrk(mode, "rR") != NULL ) //(ucase(mode[0]) == 'R')
{
if (dirEntry.name[0] == FILE_FREE) // File must exist
{
r
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -