Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Change the FF_MakeNameCompliant behavior #63

Merged
merged 16 commits into from
Feb 27, 2024
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
251 changes: 132 additions & 119 deletions ff_dir.c
Original file line number Diff line number Diff line change
Expand Up @@ -135,9 +135,9 @@ static BaseType_t FF_ValidShortChar( char cChar );
#endif /* if ( ffconfigLFN_SUPPORT != 0 ) */

#if ( ffconfigUNICODE_UTF16_SUPPORT != 0 )
static void FF_MakeNameCompliant( FF_T_WCHAR * pcName );
static BaseType_t FF_MakeNameCompliant( FF_T_WCHAR * pcName );
#else
static void FF_MakeNameCompliant( char * pcName );
static BaseType_t FF_MakeNameCompliant( char * pcName );
#endif

#if ( FF_NOSTRCASECMP == 0 )
Expand Down Expand Up @@ -2875,39 +2875,47 @@ FF_Error_t FF_ExtendDirectory( FF_IOManager_t * pxIOManager,
} /* FF_ExtendDirectory() */
/*-----------------------------------------------------------*/

static const uint8_t forbiddenChrs[] =
/* *INDENT-OFF* */
#if ( ffconfigUNICODE_UTF16_SUPPORT != 0 )
static const FF_T_WCHAR forbiddenChars[] =
#else
static const uint8_t forbiddenChars[] =
#endif
{
/* Windows says: don't use these characters: '\/:*?"<>|'
* " * / : < > ? '\' ? | */
0x22, 0x2A, 0x2F, 0x3A, 0x3C, 0x3E, 0x3F, 0x5C, 0x7F, 0x7C
};
/* *INDENT-ON* */

/* *INDENT-OFF* */
#if ( ffconfigUNICODE_UTF16_SUPPORT != 0 )
static void FF_MakeNameCompliant( FF_T_WCHAR * pcName )
static BaseType_t FF_MakeNameCompliant( FF_T_WCHAR * pcName )
#else
static void FF_MakeNameCompliant( char * pcName )
static BaseType_t FF_MakeNameCompliant( char * pcName )
#endif
/* *INDENT-ON* */
{
BaseType_t xReturn = pdTRUE;
BaseType_t index;

if( ( uint8_t ) pcName[ 0 ] == FF_FAT_DELETED ) /* Support Japanese KANJI symbol0xE5. */
if( ( uint8_t ) pcName[ 0 ] == FF_FAT_DELETED ) /* Support Japanese KANJI symbol 0xE5. */
{
pcName[ 0 ] = 0x05;
}

for( ; *pcName; pcName++ )
{
for( index = 0; index < ( BaseType_t ) sizeof( forbiddenChrs ); index++ )
for( index = 0; index < ( BaseType_t ) sizeof( forbiddenChars ); index++ )
{
if( *pcName == forbiddenChrs[ index ] )
if( *pcName == forbiddenChars[ index ] )
{
*pcName = '_';
break;
xReturn = pdFALSE;
}
}
}

return xReturn;
} /* FF_MakeNameCompliant() */
/*-----------------------------------------------------------*/

Expand Down Expand Up @@ -2941,160 +2949,165 @@ FF_Error_t FF_CreateDirent( FF_IOManager_t * pxIOManager,
/* Round-up the number of LFN's needed: */
xLFNCount = ( BaseType_t ) ( ( NameLen + 12 ) / 13 );

#if ( ffconfigUNICODE_UTF16_SUPPORT != 0 )
{
FF_MakeNameCompliant( pxDirEntry->pcFileName ); /* Ensure we don't break the Dir tables. */
}
#else
{
FF_MakeNameCompliant( pxDirEntry->pcFileName ); /* Ensure we don't break the Dir tables. */
}
#endif
memset( pucEntryBuffer, 0, sizeof( pucEntryBuffer ) );

#if ( ffconfigLFN_SUPPORT != 0 )
{
/* Create and push the LFN's. */
/* Find enough places for the LFNs and the ShortName. */
xEntryCount = xLFNCount + 1;
}
#else
{
xEntryCount = 1;
}
#endif

/* Create the ShortName. */
FF_LockDirectory( pxIOManager );

do
if( FF_MakeNameCompliant( pxDirEntry->pcFileName ) == pdFALSE )
{
/* Open a do {} while( pdFALSE ) loop to allow the use of break statements. */
/* As FF_FindShortName( ) can fail, it should be called before finding a free directory entry. */
if( ( pxFindParams->ulFlags & FIND_FLAG_SHORTNAME_SET ) == 0 )
if( ( pxDirEntry->ucAttrib & FF_FAT_ATTR_DIR ) != 0U )
{
FF_CreateShortName( pxFindParams, pxDirEntry->pcFileName );
xReturn = FF_createERR( FF_ERR_DIR_INVALID_PATH, FF_CREATEDIRENT );
}

lFitShort = FF_FindShortName( pxIOManager, pxFindParams );

memcpy( pucEntryBuffer, pxFindParams->pcEntryBuffer, sizeof( pucEntryBuffer ) );

if( FF_isERR( lFitShort ) )
{
xReturn = lFitShort;
break;
}

if( lFitShort != 0 )
{
/* There is no need to create a LFN entry because the file name
* fits into a normal 32-byte entry.. */
xLFNCount = 0;
xEntryCount = 1;
}

lFreeEntry = FF_FindFreeDirent( pxIOManager, pxFindParams, ( uint16_t ) xEntryCount );

if( FF_isERR( lFreeEntry ) )
else
{
xReturn = lFreeEntry;
break;
xReturn = FF_createERR( FF_ERR_FILE_INVALID_PATH, FF_CREATEDIRENT );
}
}
else
{
memset( pucEntryBuffer, 0, sizeof( pucEntryBuffer ) );

#if ( ffconfigLFN_SUPPORT != 0 )
{
if( xLFNCount > 0 )
{
ucCheckSum = FF_CreateChkSum( pucEntryBuffer );
xReturn = FF_CreateLFNs( pxIOManager, ulDirCluster, pxDirEntry->pcFileName, ucCheckSum, ( uint16_t ) lFreeEntry );
}
/* Create and push the LFN's. */
/* Find enough places for the LFNs and the ShortName. */
xEntryCount = xLFNCount + 1;
}
#else
{
xLFNCount = 0;
xEntryCount = 1;
}
#endif /* ffconfigLFN_SUPPORT */
#endif

if( FF_isERR( xReturn ) == pdFALSE )
/* Create the ShortName. */
FF_LockDirectory( pxIOManager );

do
{
#if ( ffconfigTIME_SUPPORT != 0 )
/* Open a do {} while( pdFALSE ) loop to allow the use of break statements. */
/* As FF_FindShortName( ) can fail, it should be called before finding a free directory entry. */
if( ( pxFindParams->ulFlags & FIND_FLAG_SHORTNAME_SET ) == 0 )
{
FF_GetSystemTime( &pxDirEntry->xCreateTime ); /* Date and Time Created. */
pxDirEntry->xModifiedTime = pxDirEntry->xCreateTime; /* Date and Time Modified. */
pxDirEntry->xAccessedTime = pxDirEntry->xCreateTime; /* Date of Last Access. */
FF_PlaceTime( pucEntryBuffer, FF_FAT_DIRENT_CREATE_TIME, &pxDirEntry->xCreateTime );
FF_PlaceDate( pucEntryBuffer, FF_FAT_DIRENT_CREATE_DATE, &pxDirEntry->xCreateTime );
FF_PlaceTime( pucEntryBuffer, FF_FAT_DIRENT_LASTMOD_TIME, &pxDirEntry->xModifiedTime );
FF_PlaceDate( pucEntryBuffer, FF_FAT_DIRENT_LASTMOD_DATE, &pxDirEntry->xModifiedTime );
FF_CreateShortName( pxFindParams, pxDirEntry->pcFileName );
}
#endif /* ffconfigTIME_SUPPORT */

FF_putChar( pucEntryBuffer, FF_FAT_DIRENT_ATTRIB, pxDirEntry->ucAttrib );
#if ( ffconfigSHORTNAME_CASE != 0 )
FF_putChar( pucEntryBuffer, FF_FAT_CASE_OFFS, ( uint32_t ) lFitShort & ( FF_FAT_CASE_ATTR_BASE | FF_FAT_CASE_ATTR_EXT ) );
#endif
FF_putShort( pucEntryBuffer, FF_FAT_DIRENT_CLUS_HIGH, ( uint16_t ) ( pxDirEntry->ulObjectCluster >> 16 ) );
FF_putShort( pucEntryBuffer, FF_FAT_DIRENT_CLUS_LOW, ( uint16_t ) ( pxDirEntry->ulObjectCluster ) );
FF_putLong( pucEntryBuffer, FF_FAT_DIRENT_FILESIZE, pxDirEntry->ulFileSize );
lFitShort = FF_FindShortName( pxIOManager, pxFindParams );

xReturn = FF_InitEntryFetch( pxIOManager, ulDirCluster, &xFetchContext );
memcpy( pucEntryBuffer, pxFindParams->pcEntryBuffer, sizeof( pucEntryBuffer ) );

if( FF_isERR( xReturn ) )
if( FF_isERR( lFitShort ) )
{
xReturn = lFitShort;
break;
}

xReturn = FF_PushEntryWithContext( pxIOManager, ( uint16_t ) ( lFreeEntry + xLFNCount ), &xFetchContext, pucEntryBuffer );

if( lFitShort != 0 )
{
FF_Error_t xTempError;
/* There is no need to create a LFN entry because the file name
* fits into a normal 32-byte entry.. */
xLFNCount = 0;
xEntryCount = 1;
}

xTempError = FF_CleanupEntryFetch( pxIOManager, &xFetchContext );
lFreeEntry = FF_FindFreeDirent( pxIOManager, pxFindParams, ( uint16_t ) xEntryCount );

if( FF_isERR( xReturn ) == pdFALSE )
if( FF_isERR( lFreeEntry ) )
{
xReturn = lFreeEntry;
break;
}

#if ( ffconfigLFN_SUPPORT != 0 )
{
if( xLFNCount > 0 )
{
xReturn = xTempError;
ucCheckSum = FF_CreateChkSum( pucEntryBuffer );
xReturn = FF_CreateLFNs( pxIOManager, ulDirCluster, pxDirEntry->pcFileName, ucCheckSum, ( uint16_t ) lFreeEntry );
}
}

if( FF_isERR( xReturn ) )
#else
{
break;
xLFNCount = 0;
}
#endif /* ffconfigLFN_SUPPORT */

#if ( ffconfigHASH_CACHE != 0 )
if( FF_isERR( xReturn ) == pdFALSE )
{
if( FF_DirHashed( pxIOManager, ulDirCluster ) == pdFALSE )
#if ( ffconfigTIME_SUPPORT != 0 )
{
FF_GetSystemTime( &pxDirEntry->xCreateTime ); /* Date and Time Created. */
pxDirEntry->xModifiedTime = pxDirEntry->xCreateTime; /* Date and Time Modified. */
pxDirEntry->xAccessedTime = pxDirEntry->xCreateTime; /* Date of Last Access. */
FF_PlaceTime( pucEntryBuffer, FF_FAT_DIRENT_CREATE_TIME, &pxDirEntry->xCreateTime );
FF_PlaceDate( pucEntryBuffer, FF_FAT_DIRENT_CREATE_DATE, &pxDirEntry->xCreateTime );
FF_PlaceTime( pucEntryBuffer, FF_FAT_DIRENT_LASTMOD_TIME, &pxDirEntry->xModifiedTime );
FF_PlaceDate( pucEntryBuffer, FF_FAT_DIRENT_LASTMOD_DATE, &pxDirEntry->xModifiedTime );
}
#endif /* ffconfigTIME_SUPPORT */

FF_putChar( pucEntryBuffer, FF_FAT_DIRENT_ATTRIB, pxDirEntry->ucAttrib );
#if ( ffconfigSHORTNAME_CASE != 0 )
FF_putChar( pucEntryBuffer, FF_FAT_CASE_OFFS, ( uint32_t ) lFitShort & ( FF_FAT_CASE_ATTR_BASE | FF_FAT_CASE_ATTR_EXT ) );
#endif
FF_putShort( pucEntryBuffer, FF_FAT_DIRENT_CLUS_HIGH, ( uint16_t ) ( pxDirEntry->ulObjectCluster >> 16 ) );
FF_putShort( pucEntryBuffer, FF_FAT_DIRENT_CLUS_LOW, ( uint16_t ) ( pxDirEntry->ulObjectCluster ) );
FF_putLong( pucEntryBuffer, FF_FAT_DIRENT_FILESIZE, pxDirEntry->ulFileSize );

xReturn = FF_InitEntryFetch( pxIOManager, ulDirCluster, &xFetchContext );

if( FF_isERR( xReturn ) )
{
break;
}

xReturn = FF_PushEntryWithContext( pxIOManager, ( uint16_t ) ( lFreeEntry + xLFNCount ), &xFetchContext, pucEntryBuffer );

{
/* Hash the directory. */
FF_HashDir( pxIOManager, ulDirCluster );
FF_Error_t xTempError;

xTempError = FF_CleanupEntryFetch( pxIOManager, &xFetchContext );

if( FF_isERR( xReturn ) == pdFALSE )
{
xReturn = xTempError;
}
}

memcpy( pcShortName, pucEntryBuffer, 11 );
FF_ProcessShortName( pcShortName ); /* Format the shortname to 8.3. */
#if ( ffconfigHASH_FUNCTION == CRC16 )
if( FF_isERR( xReturn ) )
{
FF_AddDirentHash( pxIOManager, ulDirCluster, ( uint32_t ) FF_GetCRC16( ( uint8_t * ) pcShortName, ( uint32_t ) strlen( pcShortName ) ) );
break;
}
#elif ( ffconfigHASH_FUNCTION == CRC8 )

#if ( ffconfigHASH_CACHE != 0 )
{
FF_AddDirentHash( pxIOManager, ulDirCluster, ( uint32_t ) FF_GetCRC8( ( uint8_t * ) pcShortName, strlen( pcShortName ) ) );
if( FF_DirHashed( pxIOManager, ulDirCluster ) == pdFALSE )
{
/* Hash the directory. */
FF_HashDir( pxIOManager, ulDirCluster );
}

memcpy( pcShortName, pucEntryBuffer, 11 );
FF_ProcessShortName( pcShortName ); /* Format the shortname to 8.3. */
#if ( ffconfigHASH_FUNCTION == CRC16 )
{
FF_AddDirentHash( pxIOManager, ulDirCluster, ( uint32_t ) FF_GetCRC16( ( uint8_t * ) pcShortName, ( uint32_t ) strlen( pcShortName ) ) );
}
#elif ( ffconfigHASH_FUNCTION == CRC8 )
{
FF_AddDirentHash( pxIOManager, ulDirCluster, ( uint32_t ) FF_GetCRC8( ( uint8_t * ) pcShortName, strlen( pcShortName ) ) );
}
#endif /* ffconfigHASH_FUNCTION */
}
#endif /* ffconfigHASH_FUNCTION */
#endif /* ffconfigHASH_CACHE*/
}
#endif /* ffconfigHASH_CACHE*/
}
}
while( pdFALSE );
while( pdFALSE );

FF_UnlockDirectory( pxIOManager );
FF_UnlockDirectory( pxIOManager );

if( FF_isERR( xReturn ) == pdFALSE )
{
if( pxDirEntry != NULL )
if( FF_isERR( xReturn ) == pdFALSE )
{
pxDirEntry->usCurrentItem = ( uint16_t ) ( lFreeEntry + xLFNCount );
if( pxDirEntry != NULL )
{
pxDirEntry->usCurrentItem = ( uint16_t ) ( lFreeEntry + xLFNCount );
}
}
}

Expand Down
1 change: 1 addition & 0 deletions include/ff_error.h
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@
#define FF_MKDIR ( ( 12 << FF_FUNCTION_SHIFT ) | FF_MODULE_DIR )
#define FF_TRAVERSE ( ( 13 << FF_FUNCTION_SHIFT ) | FF_MODULE_DIR )
#define FF_FINDDIR ( ( 14 << FF_FUNCTION_SHIFT ) | FF_MODULE_DIR )
#define FF_CREATEDIRENT ( ( 15 << FF_FUNCTION_SHIFT ) | FF_MODULE_DIR )

/*----- FF_FILE - The FreeRTOS+FAT file handling routines. */
#define FF_GETMODEBITS ( ( 1 << FF_FUNCTION_SHIFT ) | FF_MODULE_FILE )
Expand Down