FF_Error_t FF_MkDir()

in ff_dir.c [3202:3405]


    FF_Error_t FF_MkDir( FF_IOManager_t * pxIOManager,
                         const FF_T_WCHAR * pcPath )
#else
    FF_Error_t FF_MkDir( FF_IOManager_t * pxIOManager,
                         const char * pcPath )
#endif
{
    FF_DirEnt_t xMyDirectory;

    #if ( ffconfigUNICODE_UTF16_SUPPORT != 0 )
        const FF_T_WCHAR * pcDirName;
    #else
        const char * pcDirName;
    #endif
    uint8_t pucEntryBuffer[ FF_SIZEOF_DIRECTORY_ENTRY ];
    uint32_t ulObjectCluster;
    BaseType_t xIndex;
    FF_Error_t xError = FF_ERR_NONE;

    FF_FindParams_t xFindParams;

    memset( &xFindParams, '\0', sizeof( xFindParams ) );
    /* Inform the functions that the entry will be created if not found */
    xFindParams.ulFlags |= FIND_FLAG_CREATE_FLAG;

    /* Open a do {} while ( pdFALSE ) loop */
    do
    {
        if( pxIOManager == NULL )
        {
            xError = ( FF_Error_t ) ( FF_ERR_NULL_POINTER | FF_MKDIR );
            break;
        }

        #if ( ffconfigREMOVABLE_MEDIA != 0 )
            if( ( pxIOManager->ucFlags & FF_IOMAN_DEVICE_IS_EXTRACTED ) != 0 )
            {
                xError = ( FF_Error_t ) ( FF_ERR_IOMAN_DRIVER_NOMEDIUM | FF_MKDIR );
                break;
            }
        #endif /* ffconfigREMOVABLE_MEDIA */

        #if ( ffconfigUNICODE_UTF16_SUPPORT != 0 )
            {
                xIndex = ( BaseType_t ) wcslen( pcPath );
            }
        #else
            {
                xIndex = ( BaseType_t ) strlen( pcPath );
            }
        #endif

        /* Find the last slash in the path. */
        while( xIndex != 0 )
        {
            if( ( pcPath[ xIndex ] == '\\' ) || ( pcPath[ xIndex ] == '/' ) )
            {
                break;
            }

            xIndex--;
        }

        pcDirName = pcPath + xIndex + 1;

        if( xIndex == 0 )
        {
            xIndex = 1;
        }

        if( pcDirName[ 0 ] == '\0' )
        {
            xError = ( FF_ERR_DIR_OBJECT_EXISTS | FF_MKDIR );
            break;
        }

        xFindParams.ulDirCluster = FF_FindDir( pxIOManager, pcPath, ( uint16_t ) xIndex, &xError );

        if( FF_isERR( xError ) )
        {
            break;
        }

        if( xFindParams.ulDirCluster == 0UL )
        {
            xError = ( FF_Error_t ) ( FF_ERR_DIR_INVALID_PATH | FF_MKDIR );
            break;
        }

        memset( &xMyDirectory, '\0', sizeof( xMyDirectory ) );

        /* Will set flags FIND_FLAG_FITS_SHORT and FIND_FLAG_SIZE_OK */
        FF_CreateShortName( &xFindParams, pcDirName );

        if( FF_FindEntryInDir( pxIOManager, &xFindParams, pcDirName, 0x00, &xMyDirectory, &xError ) )
        {
            if( FF_isERR( xError ) == pdFALSE )
            {
                xError = ( FF_Error_t ) ( FF_ERR_DIR_OBJECT_EXISTS | FF_MKDIR );
            }

            break;
        }

        if( ( FF_isERR( xError ) ) && ( FF_GETERROR( xError ) != FF_ERR_DIR_END_OF_DIR ) )
        {
            break;
        }

        #if ( ffconfigUNICODE_UTF16_SUPPORT != 0 )
            {
                wcsncpy( xMyDirectory.pcFileName, pcDirName, ffconfigMAX_FILENAME );
            }
        #else
            {
                strncpy( xMyDirectory.pcFileName, pcDirName, ffconfigMAX_FILENAME );
            }
        #endif

        xMyDirectory.ulFileSize = 0;
        xMyDirectory.ucAttrib = FF_FAT_ATTR_DIR;
        xMyDirectory.ulObjectCluster = FF_CreateClusterChain( pxIOManager, &xError );

        /* Give all entries a proper time stamp, looks nicer than 1 Jan 1970 */
        #if ( ffconfigTIME_SUPPORT != 0 )
            {
                FF_GetSystemTime( &xMyDirectory.xCreateTime );
                FF_GetSystemTime( &xMyDirectory.xModifiedTime );
            }
        #endif

        if( FF_isERR( xError ) )
        {
            break;
        }

        if( xMyDirectory.ulObjectCluster == 0UL )
        {
            /* Couldn't allocate any space for the dir! */
            xError = ( FF_Error_t ) ( FF_ERR_DIR_EXTEND_FAILED | FF_MKDIR );
            break;
        }

        xError = FF_ClearCluster( pxIOManager, xMyDirectory.ulObjectCluster );

        if( FF_isERR( xError ) == pdFALSE )
        {
            xError = FF_CreateDirent( pxIOManager, &xFindParams, &xMyDirectory );
        }

        if( FF_isERR( xError ) )
        {
            FF_LockFAT( pxIOManager );
            {
                FF_UnlinkClusterChain( pxIOManager, xMyDirectory.ulObjectCluster, 0 );
            }
            FF_UnlockFAT( pxIOManager );
            FF_FlushCache( pxIOManager );   /* Don't override error. */
            break;
        }

        /* Write 8.3 entry "." */
        pucEntryBuffer[ 0 ] = '.';
        /* folowed by 10 spaces: */
        memset( pucEntryBuffer + 1, ' ', 10 );
        /* Clear the rest of the structure. */
        memset( pucEntryBuffer + 11, 0, FF_SIZEOF_DIRECTORY_ENTRY - 11 );

        ulObjectCluster = xMyDirectory.ulObjectCluster;
        xError = FF_PutEntry( pxIOManager, ( uint16_t ) 0u, ulObjectCluster, &xMyDirectory, pucEntryBuffer );

        if( FF_isERR( xError ) == pdFALSE )
        {
            pucEntryBuffer[ 1 ] = '.';

            if( xFindParams.ulDirCluster == pxIOManager->xPartition.ulRootDirCluster )
            {
                xMyDirectory.ulObjectCluster = 0;
            }
            else
            {
                xMyDirectory.ulObjectCluster = xFindParams.ulDirCluster;
            }

            xError = FF_PutEntry( pxIOManager, 1u, ulObjectCluster, &xMyDirectory, pucEntryBuffer );

            xMyDirectory.ulObjectCluster = ulObjectCluster;
        }

        if( FF_isERR( xError ) )
        {
            FF_LockFAT( pxIOManager );
            {
                FF_UnlinkClusterChain( pxIOManager, xMyDirectory.ulObjectCluster, 0 );
            }
            FF_UnlockFAT( pxIOManager );
        }

        FF_FlushCache( pxIOManager );
    }
    while( pdFALSE );

    return xError;
}   /* FF_MkDir() */