in ff_dir.c [1783:1996]
FF_Error_t FF_FindNext( FF_IOManager_t * pxIOManager,
FF_DirEnt_t * pxDirEntry )
{
FF_Error_t xError;
BaseType_t xLFNCount;
const uint8_t * pucEntryBuffer = NULL;
#if ( ffconfigFINDAPI_ALLOW_WILDCARDS != 0 )
BaseType_t b;
#endif
if( pxIOManager == NULL )
{
xError = ( FF_Error_t ) ( FF_ERR_NULL_POINTER | FF_FINDNEXT );
}
#if ( ffconfigREMOVABLE_MEDIA != 0 )
else if( ( pxIOManager->ucFlags & FF_IOMAN_DEVICE_IS_EXTRACTED ) != 0 )
{
xError = ( FF_Error_t ) ( FF_ERR_IOMAN_DRIVER_NOMEDIUM | FF_FINDNEXT );
}
#endif /* ffconfigREMOVABLE_MEDIA */
else
{
xError = FF_ERR_NONE;
for( ; pxDirEntry->usCurrentItem < FF_MAX_ENTRIES_PER_DIRECTORY; pxDirEntry->usCurrentItem++ )
{
if( ( pucEntryBuffer == NULL ) ||
( pucEntryBuffer >= ( pxDirEntry->xFetchContext.pxBuffer->pucBuffer + ( pxIOManager->usSectorSize - FF_SIZEOF_DIRECTORY_ENTRY ) ) ) )
{
xError = FF_FetchEntryWithContext( pxIOManager, pxDirEntry->usCurrentItem, &( pxDirEntry->xFetchContext ), NULL );
if( FF_isERR( xError ) )
{
break;
}
if( pucEntryBuffer == NULL )
{
pucEntryBuffer = pxDirEntry->xFetchContext.pxBuffer->pucBuffer +
( FF_SIZEOF_DIRECTORY_ENTRY * ( pxDirEntry->usCurrentItem % ( pxIOManager->usSectorSize / FF_SIZEOF_DIRECTORY_ENTRY ) ) );
}
else
{
pucEntryBuffer = pxDirEntry->xFetchContext.pxBuffer->pucBuffer;
}
}
else
{
pucEntryBuffer += FF_SIZEOF_DIRECTORY_ENTRY;
}
if( FF_isDeleted( pucEntryBuffer ) != pdFALSE )
{
/* The entry is not in use or deleted. */
continue;
}
if( FF_isEndOfDir( pucEntryBuffer ) )
{
/* End of directory, generate a pseudo error 'DIR_END_OF_DIR'. */
xError = ( FF_Error_t ) ( FF_ERR_DIR_END_OF_DIR | FF_FINDNEXT );
break;
}
pxDirEntry->ucAttrib = FF_getChar( pucEntryBuffer, ( uint16_t ) ( FF_FAT_DIRENT_ATTRIB ) );
if( ( pxDirEntry->ucAttrib & FF_FAT_ATTR_LFN ) == FF_FAT_ATTR_LFN )
{
/* LFN Processing. */
xLFNCount = ( BaseType_t ) ( pucEntryBuffer[ 0 ] & ~0x40 );
/* Get the shortname and check if it is marked deleted. */
#if ( ffconfigLFN_SUPPORT != 0 )
{
/* Reserve 32 bytes to hold one directory entry. */
uint8_t Buffer[ FF_SIZEOF_DIRECTORY_ENTRY ];
/* Fetch the shortname, and get it's checksum, or for a deleted item with
* orphaned LFN entries. */
xError = FF_FetchEntryWithContext( pxIOManager, ( uint32_t ) ( pxDirEntry->usCurrentItem + xLFNCount ), &pxDirEntry->xFetchContext, Buffer );
if( FF_isERR( xError ) )
{
break;
}
if( FF_isDeleted( Buffer ) == pdFALSE )
{
xError = FF_PopulateLongDirent( pxIOManager, pxDirEntry, pxDirEntry->usCurrentItem, &pxDirEntry->xFetchContext );
if( FF_isERR( xError ) )
{
break;
}
#if ( ffconfigINCLUDE_SHORT_NAME != 0 )
{
pxDirEntry->ucAttrib |= FF_FAT_ATTR_IS_LFN;
}
#endif
#if ( ffconfigFINDAPI_ALLOW_WILDCARDS != 0 )
{
#if ( ffconfigUNICODE_UTF16_SUPPORT != 0 )
if( wcscmp( pxDirEntry->pcWildCard, L"" ) )
#else
if( pxDirEntry->pcWildCard[ 0 ] )
#endif
{
b = FF_wildcompare( pxDirEntry->pcWildCard, pxDirEntry->pcFileName );
if( pxDirEntry->xInvertWildCard != pdFALSE )
{
b = !b;
}
if( b != 0 )
{
break;
}
/* 'usCurrentItem' has already incremented by FF_PopulateLongDirent(),
* this loop will incremente it again. */
pxDirEntry->usCurrentItem -= 1;
/* xFetchContext/usCurrentItem have changed. Update
* 'pucEntryBuffer' to point to the current buffer position. */
pucEntryBuffer = pxDirEntry->xFetchContext.pxBuffer->pucBuffer +
( FF_SIZEOF_DIRECTORY_ENTRY * ( pxDirEntry->usCurrentItem % ( pxIOManager->usSectorSize / FF_SIZEOF_DIRECTORY_ENTRY ) ) );
}
else
{
break;
}
}
#else /* ffconfigFINDAPI_ALLOW_WILDCARDS == 0 */
{
/* usCurrentItem has been incremented by FF_PopulateLongDirent().
* Entry will be returned. */
break;
}
#endif /* if ( ffconfigFINDAPI_ALLOW_WILDCARDS != 0 ) */
}
}
#else /* ffconfigLFN_SUPPORT */
{
/* Increment 'usCurrentItem' with (xLFNCount-1),
* the loop will do an extra increment. */
pxDirEntry->usCurrentItem += ( xLFNCount - 1 );
}
#endif /* ffconfigLFN_SUPPORT */
} /* ( ( pxDirEntry->ucAttrib & FF_FAT_ATTR_LFN ) == FF_FAT_ATTR_LFN ) */
else if( ( pxDirEntry->ucAttrib & FF_FAT_ATTR_VOLID ) != FF_FAT_ATTR_VOLID )
{
/* If it's not a LFN entry, neither a Volume ID, it is a normal short name entry. */
FF_PopulateShortDirent( pxIOManager, pxDirEntry, pucEntryBuffer );
#if ( ffconfigSHORTNAME_CASE != 0 )
{
/* Apply NT/XP+ bits to get correct case. */
FF_CaseShortName( pxDirEntry->pcFileName, FF_getChar( pucEntryBuffer, FF_FAT_CASE_OFFS ) );
}
#endif
#if ( ffconfigFINDAPI_ALLOW_WILDCARDS != 0 )
{
if( pxDirEntry->pcWildCard[ 0 ] )
{
b = FF_wildcompare( pxDirEntry->pcWildCard, pxDirEntry->pcFileName );
if( pxDirEntry->xInvertWildCard != pdFALSE )
{
b = !b;
}
if( b != 0 )
{
pxDirEntry->usCurrentItem += 1;
break;
}
}
else
{
pxDirEntry->usCurrentItem += 1;
break;
}
}
#else /* ffconfigFINDAPI_ALLOW_WILDCARDS */
{
pxDirEntry->usCurrentItem += 1;
break;
}
#endif /* if ( ffconfigFINDAPI_ALLOW_WILDCARDS != 0 ) */
}
} /* for ( ; pxDirEntry->usCurrentItem < FF_MAX_ENTRIES_PER_DIRECTORY; pxDirEntry->usCurrentItem++ ) */
if( pxDirEntry->usCurrentItem == FF_MAX_ENTRIES_PER_DIRECTORY )
{
xError = ( FF_Error_t ) ( FF_ERR_DIR_END_OF_DIR | FF_FINDNEXT );
}
{
FF_Error_t xTempError;
xTempError = FF_CleanupEntryFetch( pxIOManager, &pxDirEntry->xFetchContext );
if( FF_isERR( xError ) == pdFALSE )
{
xError = xTempError;
}
}
}
return xError;
} /* FF_FindNext() */