FF_Error_t FF_FindNext()

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() */