in ff_dir.c [2916:3104]
FF_Error_t FF_CreateDirent( FF_IOManager_t * pxIOManager,
FF_FindParams_t * pxFindParams,
FF_DirEnt_t * pxDirEntry )
{
uint8_t pucEntryBuffer[ FF_SIZEOF_DIRECTORY_ENTRY ];
BaseType_t xLFNCount;
int32_t lFreeEntry = 0L;
FF_Error_t xReturn = FF_ERR_NONE;
BaseType_t xEntryCount;
FF_FetchContext_t xFetchContext;
uint32_t ulDirCluster = pxFindParams->ulDirCluster;
int32_t lFitShort;
#if ( ffconfigHASH_CACHE != 0 )
char pcShortName[ 13 ];
#endif
#if ( ffconfigUNICODE_UTF16_SUPPORT != 0 )
uint16_t NameLen = ( uint16_t ) wcslen( pxDirEntry->pcFileName );
#else
uint16_t NameLen = ( uint16_t ) strlen( pxDirEntry->pcFileName );
#endif
#if ( ffconfigLFN_SUPPORT != 0 )
uint8_t ucCheckSum;
#endif
/* 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
{
/* 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 ) );
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 ) )
{
xReturn = lFreeEntry;
break;
}
#if ( ffconfigLFN_SUPPORT != 0 )
{
if( xLFNCount > 0 )
{
ucCheckSum = FF_CreateChkSum( pucEntryBuffer );
xReturn = FF_CreateLFNs( pxIOManager, ulDirCluster, pxDirEntry->pcFileName, ucCheckSum, ( uint16_t ) lFreeEntry );
}
}
#else
{
xLFNCount = 0;
}
#endif /* ffconfigLFN_SUPPORT */
if( FF_isERR( xReturn ) == 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 );
{
FF_Error_t xTempError;
xTempError = FF_CleanupEntryFetch( pxIOManager, &xFetchContext );
if( FF_isERR( xReturn ) == pdFALSE )
{
xReturn = xTempError;
}
}
if( FF_isERR( xReturn ) )
{
break;
}
#if ( ffconfigHASH_CACHE != 0 )
{
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, strlen( pcShortName ) ) );
}
#elif ( ffconfigHASH_FUNCTION == CRC8 )
{
FF_AddDirentHash( pxIOManager, ulDirCluster, ( uint32_t ) FF_GetCRC8( ( uint8_t * ) pcShortName, strlen( pcShortName ) ) );
}
#endif /* ffconfigHASH_FUNCTION */
}
#endif /* ffconfigHASH_CACHE*/
}
}
while( pdFALSE );
FF_UnlockDirectory( pxIOManager );
if( FF_isERR( xReturn ) == pdFALSE )
{
if( pxDirEntry != NULL )
{
pxDirEntry->usCurrentItem = ( uint16_t ) ( lFreeEntry + xLFNCount );
}
}
return xReturn;
} /* FF_CreateDirent() */