📄 bfsa_internal.c
字号:
// write fail, mark the cluster as bad cluster in fat
writeFatEntry(_freeCluster,BFSA_media.FATtype == BFSA_FAT12?BAD12:BAD16);
TRACE_DEBUG_L( "Bad cluster:%d\n\r",_currentCluster);
_freeCluster = 0;
}
else
{
// Cluster found and initialized
break;
}
}
}
return _freeCluster;
}
/*****************************************************************
*
*
* S U B - R O U T I N E : getNextCluster
*
*-----------------------------------------------------------------
*
* int getNextCluster(USHORT uCurrent)
*
* Object :
* This function returns the next cluster from the FAT for the
* current cluster.
*
* Argument:
* uCurrent :[IN] current cluster.
*
* Return value :
* the next cluster if any,
* 0 if there is no more cluster in chain
* on error :
* BAD_ARGUMENT
*
*****************************************************************/
ULONG getNextCluster(USHORT uCurrent)
{
ULONG status = BFSA_SUCCESS;
if (uCurrent > BFSA_media.MaxCluster)
{
status = BAD_ARGUMENT;
}
else
{
status = readFatEntry(uCurrent);
if( ((BFSA_media.FATtype == BFSA_FAT16)&&(status == EOC16 || status == 0xFFF8 || status == BAD16))
|| ((BFSA_media.FATtype == BFSA_FAT12)&&(status == EOC12 || status == 0x0FF8 || status == BAD12)) )
{
// No more Cluster in chain
status = BFSA_SUCCESS;
}
}
return( status );
}
/*****************************************************************
*
*
* S U B - R O U T I N E : isValidFileNameChar
*
*-----------------------------------------------------------------
*
* UCHAR isValidFileNameChar(char car)
*
* Object :
* This function returns TRUE if car is a valid character in a
* file name.
*
* Argument:
* car :[IN] character to test.
*
*****************************************************************/
#ifdef ADS_COMPIL
__inline
#else
inline
#endif
UCHAR isValidFileNameChar( char car )
{
UCHAR status = TRUE;
// Invalid char
if( (car < 0x20) && (car != 0x05) )
{
status = FALSE;
}
else
{
// Lower case not allowed
if( (car >= 'a') && (car <= 'z') )
{
status = FALSE;
}
else
{
// Invalid char
/* 0x22 : '"', 0x2A : '*', 0x2B : '+', 0x2C : ',', 0x2E : '.', 0x2F : '/' */
/* 0x3A : '', 0x3B : ';', 0x3C : '<', 0x3D : '=', 0x3E : '>', 0x3F : '?' */
/* 0x5B : '[', 0x5C : '\', 0x5D : ']', 0x7C : '|' */
if ( (car==0x22) || (car==0x2A) || (car==0x2B) || (car==0x2C) || (car==0x2E) || (car==0x2F)
|| (car==0x3A) || (car==0x3B) || (car==0x3C) || (car==0x3D) || (car==0x3E) || (car==0x3F)
|| (car==0x5B) || (car==0x5C) || (car==0x5D) || (car==0x7C) )
{
status = FALSE;
}
}
}
return( status );
}
/*****************************************************************
*
*
* S U B - R O U T I N E : isValidFileName
*
*-----------------------------------------------------------------
*
* UCHAR isValidFileName(char *fileName)
*
* Object :
* This function returns TRUE if the file name is valid.
*
* Argument:
* fileName :[IN] file name string.
*
*****************************************************************/
UCHAR isValidFileName(char *fileName)
{
UCHAR _c;
if (!fileName)
{
return FALSE;
}
if (*fileName == '.') // File name can't be only an extension
{
return FALSE;
}
// Filename
for (_c=0;
_c<8 && fileName[_c]!='\0' && fileName[_c]!='.';
_c++)
{
if (!isValidFileNameChar(fileName[_c]))
{
return FALSE;
}
}
if (fileName[_c]!='\0' && fileName[_c]!='.') // Wrong size
{
return FALSE;
}
// File extension
if (fileName[_c]=='.')
{
fileName = &fileName[_c+1];
for (_c=0;
_c<3 && fileName[_c]!='\0';
_c++)
{
if (!isValidFileNameChar(fileName[_c]))
{
return FALSE;
}
}
if (fileName[_c]!='\0') // Wrong extension size
{
return FALSE;
}
}
return TRUE;
}
/*****************************************************************
*
*
* S U B - R O U T I N E : padFileName
*
*-----------------------------------------------------------------
*
* void padFileName(const char *filename, char* strFileName)
*
* Object :
* This function add spaces to filename to have always a filename of 8+3 chars.
* Eg. filename = "test.exe", strFileName = "test exe"
*
* Argument:
* FileName :[IN] Valid Filename.
* strFileName :[OUT] filename padded, allocated by user to [8+3]
*
* Return value :
* returns First cluster of the file,
* or 0 if no matching file was found
*****************************************************************/
void padFileName(const char *filename, char* strFileName)
{
UCHAR i;
char *puc = strFileName;
if (!filename || !strFileName)
{
return;
}
for( i=0; i<8+3; i++ )
{
strFileName[i] = 0x20;
}
strFileName[8+3] = '\0';
for (i=0; i<BFSA_MAX_FILENAME_LEN && filename[i]!='\0'; i++)
{
if (filename[i]=='.')
{
puc = strFileName + 8; // The '.' is not retrived
}
else
{
*puc = filename[i];
puc++;
}
}
}
/*****************************************************************
*
*
* S U B - R O U T I N E : findEntry
*
*-----------------------------------------------------------------
*
* USHORT findEntry(char* fileName)
*
* Object :
* This function looks for a file in current directory.
*
* Argument:
* FileName :[IN] Valid Filename to find.
*
* Return value :
* returns entry address,
* or 0 if no matching file was found
*****************************************************************/
int findEntry(char *fileName)
{
UCHAR *_flashDirEnt = NULL; // Point to a directory entry DIR_Name
UCHAR pDirEnt[DIRECTORY_ENTRIE_SIZE];
USHORT _currentDirClus = BFSA_current_dir.DirStart;
USHORT _currentEntry;
USHORT _numberDirEntryPerCluster;
char strFileName[8+3+1] =""; // File name space padded.
char strFileName2[8+3+1]=""; // From entry
// Spaces pad the file
padFileName(fileName,strFileName);
// Compute the number max of Entries to look (by cluster)
if (BFSA_current_dir.IsRoot)
{
USHORT _RootSize = BFSA_media.numRootSectors * BFSA_media.bytesPerSector;
_numberDirEntryPerCluster = _RootSize/DIRECTORY_ENTRIE_SIZE;
}
else
{
_numberDirEntryPerCluster = BFSA_media.bytesPerSector*BFSA_media.SectPerCluster
/ DIRECTORY_ENTRIE_SIZE;
}
// Walk through the cluster chain of the directory
do
{
// Point to the start of current cluster of the directory
if (BFSA_current_dir.IsRoot)
{
_flashDirEnt = (UCHAR*)FlashBaseAdd + _currentDirClus*BFSA_media.bytesPerSector;
}
else
{
_flashDirEnt = (UCHAR*)FlashBaseAdd +
FIRST_SECTOR_DATACLUSTER(_currentDirClus)*BFSA_media.bytesPerSector;
}
// Walk through the directory entries of the current cluster to find the file
for (_currentEntry = 0;
_currentEntry < _numberDirEntryPerCluster;
_currentEntry++)
{
AT91F_ReadMedia((unsigned int)_flashDirEnt, DIRECTORY_ENTRIE_SIZE, pDirEnt);
if (*pDirEnt == 0x00) // no more directory entry
{
break;
}
if ( (pDirEnt[11]&BFSA_ATTR_LONG_NAME != BFSA_ATTR_LONG_NAME) // Don't look at Long names
&& !(pDirEnt[11]&BFSA_ATTR_VOLUME_ID) // neither VOLUME ID
&& *pDirEnt!=FREE_ENTRY_DIR // Free Entry
&& *pDirEnt!=FREE_ENTRY_DIR_2 // Free Entry
&& *pDirEnt!=FREE_ENTRY_DIR_AND_NO_ALLOCATED) // No more entry
{
// Get file name from entry
po_memcpy( strFileName2, pDirEnt, 11 );
strFileName2[11] = '\0';
if ( po_strcmp( strFileName2, strFileName ) == 0 )
{
// File found return the entry
return (int)_flashDirEnt;
}
}
// Next entry in the current cluster
_flashDirEnt += DIRECTORY_ENTRIE_SIZE;
}
if ( BFSA_current_dir.IsRoot )
{
// there only one cluster for root directory.
break;
}
AT91F_ReadMedia((unsigned int)_flashDirEnt, 1, pDirEnt);
if (*pDirEnt == 0)
{
// File found or no more allocated directory entries
break;
}
// Get the next cluster from FAT
_currentDirClus = getNextCluster(_currentDirClus);
}while (_currentDirClus != 0);
return 0;
}
/*****************************************************************
*
*
* S U B - R O U T I N E : findFile
*
*-----------------------------------------------------------------
*
* USHORT findFile(char* fileName)
*
* Object :
* This function looks for a file in current directory.
*
* Argument:
* FileName :[IN] Valid Filename to find.
*
* Return value :
* returns First cluster of the file,
* or 0 if no matching file was found
*****************************************************************/
USHORT findFile(const char* fileName)
{
USHORT _firstFileCluster = 0;
UCHAR *_pucEntry;
_pucEntry = (UCHAR*)findEntry ((char*)fileName);
if (_pucEntry)
{
// File found return the First Cluster
_firstFileCluster = *(_pucEntry+26)+*(_pucEntry+27)*0x100;
}
return _firstFileCluster;
}
/*****************************************************************
*
*
* S U B - R O U T I N E : addNewEntry
*
*-----------------------------------------------------------------
*
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -