📄 fatlite.c
字号:
}
if (j < PATH_CHARACTERS_MAX_NUM)
buff[j++] = 0;
else
ret = flPathTooLong;
return ret;
}
#endif /* FL_NO_LONG_FILENAMES_SUPPORT */
/*----------------------------------------------------------------------*/
/* d i s m o u n t V o l u m e */
/* */
/* Closing all files. */
/* */
/* Parameters: */
/* vol : Pointer identifying drive */
/* */
/* Returns: */
/* FLStatus : 0 on success, otherwise failed */
/*----------------------------------------------------------------------*/
FLStatus dismountFS(Volume vol,FLStatus status)
{
FLDword i;
if(vol.flags & VOLUME_MOUNTED)
{
#ifndef FL_READ_ONLY
if (status == flOK)
checkStatus(flushBuffer(&vol));
#endif
/* Close or discard all files and make them available */
for (i = 0; i < (FLDword)FL_FILES; i++)
{
if (fileTable[i].fileVol == &vol)
{
if (fileTable[i].flags & FILE_IS_OPEN)
{
closeFile(&fileTable[i]);
}
else
{
fileTable[i].flags = 0;
}
}
}
#ifndef FL_NO_SURE_FS_SUPPORT
/* Reset global attention flag */
checkStatus( setGlobalAttentionFlag( &vol, RESET_GLOBAL_ATTENTION_FLAG));
checkStatus( flushBuffer( &vol));
#endif /* FL_NO_SURE_FS_SUPPORT */
vol.volBuffer.sectorNo = UNASSIGNED_SECTOR; /* Current sector no. (none) */
vol.volBuffer.dirty = vol.volBuffer.checkPoint = FALSE;
vol.flags &= ~VOLUME_MOUNTED;
}
return flOK;
}
#ifndef FL_READ_ONLY
/*----------------------------------------------------------------------*/
/* f l u s h B u f f e r */
/* */
/* Writes the buffer contents if it is dirty. */
/* */
/* If this is a FAT sector, all FAT copies are written. */
/* */
/* Parameters: */
/* vol : Pointer identifying drive */
/* */
/* Returns: */
/* FLStatus : 0 on success, otherwise failed */
/*----------------------------------------------------------------------*/
FLStatus flushBuffer(Volume vol)
{
if (vol.volBuffer.dirty) {
FLStatus status;
Volume *bufferOwner = &vol;
status = (*bufferOwner).tl.writeSector((*bufferOwner).tl.rec, vol.volBuffer.sectorNo,
vol.volBuffer.flData);
if (status == flOK) {
if ((vol.volBuffer.sectorNo >= (*bufferOwner).firstFATSectorNo) &&
(vol.volBuffer.sectorNo < (*bufferOwner).secondFATSectorNo))
{
unsigned i;
for (i = 1; i < (*bufferOwner).numberOfFATS; i++)
checkStatus((*bufferOwner).tl.writeSector((*bufferOwner).tl.rec,
vol.volBuffer.sectorNo + i * (*bufferOwner).sectorsPerFAT,
vol.volBuffer.flData));
}
}
else
{
vol.volBuffer.sectorNo = UNASSIGNED_SECTOR;
}
vol.volBuffer.dirty = vol.volBuffer.checkPoint = FALSE;
return status;
}
else
return flOK;
}
/*----------------------------------------------------------------------*/
/* u p d a t e S e c t o r */
/* */
/* Prepares a sector for update in the buffer */
/* */
/* Parameters: */
/* vol : Pointer identifying drive */
/* sectorNo : Sector no. to read */
/* read : Whether to initialize buffer by reading, or */
/* clearing */
/* */
/* Returns: */
/* FLStatus : 0 on success, otherwise failed */
/*----------------------------------------------------------------------*/
static FLStatus updateSector(Volume vol, SectorNo sectorNo, FLBoolean read)
{
if ((sectorNo != vol.volBuffer.sectorNo) || (((void *)&vol) != vol.volBuffer.owner)) {
const void FAR0 *mappedSector;
checkStatus(flushBuffer(&vol));
vol.volBuffer.sectorNo = sectorNo;
vol.volBuffer.owner = (void *)&vol;
if (read) {
mappedSector = vol.tl.mapSector(vol.tl.rec,sectorNo,NULL);
if (mappedSector) {
if(mappedSector==dataErrorToken)
return flDataError;
tffscpy(vol.volBuffer.flData,mappedSector,FL_SECTOR_SIZE);
}
else
return flSectorNotFound;
}
else
tffsset(vol.volBuffer.flData,0,FL_SECTOR_SIZE);
}
vol.volBuffer.dirty = TRUE;
return flOK;
}
#endif /* FL_READ_ONLY */
/*----------------------------------------------------------------------*/
/* f i r s t S e c t o r O f C l u s t e r */
/* */
/* Get sector no. corresponding to cluster no. */
/* */
/* Parameters: */
/* vol : Pointer identifying drive */
/* cluster : Cluster no. */
/* */
/* Returns: */
/* first sector no. of cluster */
/*----------------------------------------------------------------------*/
static SectorNo firstSectorOfCluster(Volume vol, unsigned cluster)
{
return (SectorNo) (cluster - FL_FIRST_VALID_CLUSTER) * vol.sectorsPerCluster +
vol.firstDataSectorNo;
}
/*--------------------------------------------------------------------------
* g e t D i r E n t r y
* Provides read-only copy of a directory entry. In case of LFN (long file names)
* it will contain short form entry.
* Input: file - file belonging to directory entry
* Return: [DirectoryEntry *] - address of the directory entry
*---------------------------------------------------------------------------*/
static const DirectoryEntry FAR0 *getDirEntry(File *file)
{
return (DirectoryEntry FAR0 *) findSector(file->fileVol,file->directorySector) +
file->directoryIndex;
}
#ifndef FL_READ_ONLY
/*----------------------------------------------------------------------*/
/* g e t D i r E n t r y F o r U p d a t e */
/* */
/* Read a directory sector into the sector buffer and point to an */
/* entry, with the intention of modifying it. */
/* The buffer will be flushed on operation exit. */
/* */
/* Parameters: */
/* vol : Pointer identifying drive */
/* file : File belonging to directory entry */
/* */
/* Returns: */
/* FLStatus : 0 on success, otherwise failed */
/* dirEntry : Pointer to directory entry in buffer */
/*----------------------------------------------------------------------*/
static FLStatus getDirEntryForUpdate(File *file, DirectoryEntry * *dirEntry)
{
Volume vol = file->fileVol;
checkStatus(updateSector(file->fileVol,file->directorySector,TRUE));
*dirEntry = directory + file->directoryIndex;
vol.volBuffer.checkPoint = TRUE;
return flOK;
}
#endif /* FL_READ_ONLY */
/*----------------------------------------------------------------------*/
/* s e t C u r r e n t D a t e T i m e */
/* */
/* Set current time/date in directory entry */
/* */
/* Parameters: */
/* dirEntry : Pointer to directory entry */
/* */
/*----------------------------------------------------------------------*/
static void setCurrentDateTime(DirectoryEntry *dirEntry)
{
toLE2(dirEntry->updateTime,flCurrentTime());
toLE2(dirEntry->updateDate,flCurrentDate());
}
/*----------------------------------------------------------------------*/
/* g e t F A T e n t r y */
/* */
/* Get an entry from the FAT. The 1st FAT copy is used. */
/* */
/* Parameters: */
/* vol : Pointer identifying drive */
/* cluster : Cluster no. of enrty. */
/* */
/* Returns: */
/* Value of FAT entry. */
/*----------------------------------------------------------------------*/
static FLStatus getFATentry(Volume vol, unsigned* entry)
{
unsigned cluster = *entry;
LEushort FAR0 *fat16Sector;
unsigned fatSectorNo = vol.firstFATSectorNo;
#ifdef FAT_12BIT
if (vol.flags & VOLUME_12BIT_FAT)
fatSectorNo += (cluster * 3) >> (FL_SECTOR_SIZE_BITS + 1);
else
#endif
fatSectorNo += cluster >> (FL_SECTOR_SIZE_BITS - 1);
#ifndef FL_READ_ONLY
if (!vol.volBuffer.dirty) {
/* If the buffer is free, use it to store this FAT sector */
checkStatus(updateSector(&vol,fatSectorNo,TRUE));
vol.volBuffer.dirty = FALSE;
}
#endif /* FL_READ_ONLY */
fat16Sector = (LEushort FAR0 *) findSector(&vol,fatSectorNo);
if(fat16Sector==NULL)
return flSectorNotFound;
if((void FAR0 *)fat16Sector==dataErrorToken)
return flDataError;
#ifdef FAT_12BIT
if (vol.flags & VOLUME_12BIT_FAT) {
FLByte FAR0 *fat12Sector = (FLByte FAR0 *) fat16Sector;
unsigned halfByteOffset = (cluster * 3) & (FL_SECTOR_SIZE * 2 - 1);
FLByte firstByte = fat12Sector[halfByteOffset / 2];
halfByteOffset += 2;
if (halfByteOffset >= FL_SECTOR_SIZE * 2) {
/* Entry continues on the next sector. What a mess */
halfByteOffset -= FL_SECTOR_SIZE * 2;
fat12Sector = (FLByte FAR0 *) findSector(&vol,fatSectorNo + 1);
if(fat12Sector==NULL)
return flSectorNotFound;
if(fat12Sector==dataErrorToken)
return flDataError;
}
if (halfByteOffset & 1)
*entry = ((firstByte & 0xf0) >> 4) + (fat12Sector[halfByteOffset / 2] << 4);
else
*entry = firstByte + ((fat12Sector[halfByteOffset / 2] & 0xf) << 8);
if (*entry == 0xfff) /* in 12-bit fat, 0xfff marks the last cluster */
*entry = FAT_LAST_CLUSTER; /* return 0xffff instead */
return flOK;
}
else {
#endif
*entry = LE2(fat16Sector[cluster & (FL_SECTOR_SIZE / 2 - 1)]);
return flOK;
#ifdef FAT_12BIT
}
#endif
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -