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 4 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 FF_Error_t FF_MakeNameCompliant( FF_T_WCHAR * pcName );
#else
static void FF_MakeNameCompliant( char * pcName );
static FF_Error_t FF_MakeNameCompliant( char * pcName );
togrue marked this conversation as resolved.
Show resolved Hide resolved
#endif

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

static const uint8_t forbiddenChrs[] =
/* *INDENT-OFF* */
togrue marked this conversation as resolved.
Show resolved Hide resolved
#if ( ffconfigUNICODE_UTF16_SUPPORT != 0 )
static const FF_T_WCHAR forbiddenChrs[] =
#else
static const uint8_t forbiddenChrs[] =
#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 FF_Error_t FF_MakeNameCompliant( FF_T_WCHAR * pcName )
#else
static void FF_MakeNameCompliant( char * pcName )
static FF_Error_t FF_MakeNameCompliant( char * pcName )
#endif
/* *INDENT-ON* */
{
FF_Error_t xReturn = pdTRUE;
togrue marked this conversation as resolved.
Show resolved Hide resolved
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;
}
Expand All @@ -2903,11 +2910,12 @@ static const uint8_t forbiddenChrs[] =
{
if( *pcName == forbiddenChrs[ index ] )
{
*pcName = '_';
break;
xReturn = pdFALSE;
togrue marked this conversation as resolved.
Show resolved Hide resolved
}
}
}

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 ) )
togrue marked this conversation as resolved.
Show resolved Hide resolved
{
/* 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_CreateShortName( pxFindParams, pxDirEntry->pcFileName );
}

lFitShort = FF_FindShortName( pxIOManager, pxFindParams );

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

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

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

lFreeEntry = FF_FindFreeDirent( pxIOManager, pxFindParams, ( uint16_t ) xEntryCount );
/* Create the ShortName. */
FF_LockDirectory( pxIOManager );

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

#if ( ffconfigLFN_SUPPORT != 0 )
do
{
if( xLFNCount > 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 )
{
ucCheckSum = FF_CreateChkSum( pucEntryBuffer );
xReturn = FF_CreateLFNs( pxIOManager, ulDirCluster, pxDirEntry->pcFileName, ucCheckSum, ( uint16_t ) lFreeEntry );
FF_CreateShortName( pxFindParams, pxDirEntry->pcFileName );
}
}
#else
{
xLFNCount = 0;
}
#endif /* ffconfigLFN_SUPPORT */

if( FF_isERR( xReturn ) == pdFALSE )
{
#if ( ffconfigTIME_SUPPORT != 0 )
lFitShort = FF_FindShortName( pxIOManager, pxFindParams );

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

if( FF_isERR( lFitShort ) )
{
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 );
xReturn = lFitShort;
break;
}
#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 );
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;
}

xReturn = FF_InitEntryFetch( pxIOManager, ulDirCluster, &xFetchContext );
lFreeEntry = FF_FindFreeDirent( pxIOManager, pxFindParams, ( uint16_t ) xEntryCount );

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

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

#if ( ffconfigLFN_SUPPORT != 0 )
{
FF_Error_t xTempError;

xTempError = FF_CleanupEntryFetch( pxIOManager, &xFetchContext );

if( FF_isERR( xReturn ) == pdFALSE )
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( FF_isERR( xReturn ) == pdFALSE )
{
if( pxDirEntry != NULL )
{
pxDirEntry->usCurrentItem = ( uint16_t ) ( lFreeEntry + xLFNCount );
}
}
} /* if( FF_MakeNameCompliant( pxDirEntry->pcFileName ) ) */
else
{
if( pxDirEntry != NULL )
if( pxDirEntry->ucAttrib & FF_FAT_ATTR_DIR )
togrue marked this conversation as resolved.
Show resolved Hide resolved
togrue marked this conversation as resolved.
Show resolved Hide resolved
{
xReturn = FF_createERR( FF_ERR_DIR_INVALID_PATH, FF_CREATEDIRENT );
}
else
{
pxDirEntry->usCurrentItem = ( uint16_t ) ( lFreeEntry + xLFNCount );
xReturn = FF_createERR( FF_ERR_FILE_INVALID_PATH, FF_CREATEDIRENT );
}
}

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
Loading