Exemplo n.º 1
0
//*****************************************************************************
//
//! Maps a path string containing mount point names to a path suitable for
//! use in calls to the FatFs APIs.
//!
//! \param pcPath points to a string containing a path in the namespace
//! defined by the mount information passed to fs_init().
//! \param pcMapped points to a buffer into which the mapped path string will
//! be written.
//! \param iLen is the size, in bytes, of the buffer pointed to by pcMapped.
//!
//! This function may be used by applications which want to make use of FatFs
//! functions which are not directly mapped by the fswrapper layer.  A path
//! in the namespace defined by the mount points passed to function fs_init()
//! is translated to an equivalent path in the FatFs namespace and this may
//! then be used in a direct call to functions such as f_opendir() or
//! f_getfree().
//!
//! \return Returns \b true on success or \b false if fs_init() has not
//! been called, if the path provided maps to an internal file system image
//! rather than a FatFs logical drive or if the buffer pointed to by
//! \e pcMapped is too small to fit the output string.
//
//*****************************************************************************
bool
fs_map_path(const char *pcPath, char *pcMapped, int iLen)
{
    char *pcFSFilename;
    uint32_t ui32MountIndex;
    int iCount;

    //
    // If no mount points have been defined, return an error.
    //
    if(!g_psMountPoints)
    {
        return(false);
    }

    //
    // Find which mount point we need to use to satisfy this file open request.
    //
    ui32MountIndex = fs_find_mount_index(pcPath, &pcFSFilename);

    //
    // If we got a bad mount index or the index returned represents a mount
    // point that is not in the FAT file system, return an error.
    //
    if((ui32MountIndex == BAD_MOUNT_INDEX) ||
       (g_psMountPoints[ui32MountIndex].pui8FSImage))
    {
        //
        // We can't map the mount index so return an error.
        //
        return(false);
    }

    //
    // Now we can generate the FatFs namespace path string.
    //
    iCount = usnprintf(pcMapped, iLen, "%d:%s",
                       g_psMountPoints[ui32MountIndex].ui32DriveNum,
                       pcFSFilename);

    //
    // Tell the user how we got on.  The count returned by usnprintf is the
    // number of characters that should have been written, excluding the
    // terminating NULL so we use this to check for overflow of the output
    // buffer.
    //
    return((iLen >= (iCount + 1)) ? true : false);
}
Exemplo n.º 2
0
//*****************************************************************************
//
//! Opens a file.
//!
//! \param pcName points to a NULL terminated string containing the path and
//! file name to open.
//!
//! This function opens a file and returns a handle allowing it to be read.
//!
//! \return Returns a valid file handle on success or NULL on failure.
//
//*****************************************************************************
struct fs_file *
fs_open(char *pcName)
{
    const struct fsdata_file *ptTree;
    const struct fsdata_file *ptEnd;
    struct fs_file *ptFile = NULL;
    fs_wrapper_data *pWrapper;
    FRESULT fresult = FR_OK;
    tBoolean bPosInd = false;
    char *pcFSFilename;
    char *pcFilename;
    unsigned long ulLength;

    //
    // Allocate memory for the file system structure.
    //
    ptFile = mem_malloc(sizeof(struct fs_file));
    if(NULL == ptFile)
    {
        return(NULL);
    }

    //
    // Allocate memory for our internal control structure.
    //
    ptFile->pextension = mem_malloc(sizeof(fs_wrapper_data));
    pWrapper = (fs_wrapper_data *)ptFile->pextension;

    if(NULL == pWrapper)
    {
        return(NULL);
    }

    //
    // Find which mount point we need to use to satisfy this file open request.
    //
    pWrapper->ulMountIndex = fs_find_mount_index(pcName, &pcFSFilename);
    if(pWrapper->ulMountIndex == BAD_MOUNT_INDEX)
    {
        //
        // We can't map the mount index so return an error.
        //
        mem_free(pWrapper);
        mem_free(ptFile);
        return(NULL);
    }

    //
    // Enable access to the physical medium if we have been provided with
    // a callback for this.
    //
    if(g_psMountPoints[pWrapper->ulMountIndex].pfnEnable)
    {
        g_psMountPoints[pWrapper->ulMountIndex].pfnEnable(
                                                pWrapper->ulMountIndex);
    }

    //
    // Are we opening a file on an internal file system image?
    //
    if(g_psMountPoints[pWrapper->ulMountIndex].pcFSImage)
    {
        //
        // Initialize the file system tree pointer to the root of the linked
        // list for this mount point's file system image.
        //
        ptTree = (const struct fsdata_file *)
                  g_psMountPoints[pWrapper->ulMountIndex].pcFSImage;

        //
        // Which type of file system are we dealing with?
        //
        if(ptTree->next == FILE_SYSTEM_MARKER)
        {
            //
            // If we found the marker, this is a position independent file
            // system image.  Remember this and fix up the pointer to the
            // first descriptor by skipping over the 4 byte marker and the
            // 4 byte image size entry.  We also keep track of where the file
            // system image ends since this allows us to do a bit more error
            // checking later.
            //
            bPosInd = true;
            ulLength = *(unsigned long *)((unsigned char *)ptTree + 4);
            ptTree = (struct fsdata_file *)((char *)ptTree + 8);
            ptEnd = (struct fsdata_file *)((char *)ptTree + ulLength);
        }

        //
        // Begin processing the linked list, looking for the requested file
        // name.
        //
        while(NULL != ptTree)
        {
            //
            // Compare the requested file "name" to the file name in the
            // current node.
            //
            if(strncmp(pcFSFilename, FS_POINTER(ptTree, ptTree->name, bPosInd),
                       ptTree->len) == 0)
            {
                //
                // Fill in the data pointer and length values from the
                // linked list node.
                //
                ptFile->data = FS_POINTER(ptTree, ptTree->data, bPosInd);
                ptFile->len = ptTree->len;

                //
                // For now, we setup the read index to the end of the file,
                // indicating that all data has been read.  This indicates that
                // all the data is currently available in a contiguous block
                // of memory (which is always the case with an internal file
                // system image).
                //
                ptFile->index = ptTree->len;

                //
                // We are not using a FAT file system file and don't need to
                // remap the filename so set these pointers to NULL.
                //
                pWrapper->pFATFile = NULL;

                //
                // Exit the loop and return the file system pointer.
                //
                break;
            }

            //
            // If we get here, we did not find the file at this node of the
            // linked list.  Get the next element in the list.  We can't just
            // assign ptTree from ptTree->next since this will give us the
            // wrong pointer for a position independent image (where the values
            // in the structure are offsets from the start of the file
            // descriptor, not absolute pointers) but we do know that a 0 in
            // the "next" field does indicate that this is the last file so we
            // can use that info to force the loop to exit at the end.
            //
            if(ptTree->next == 0)
            {
                ptTree = NULL;
            }
            else
            {
                ptTree = (struct fsdata_file *)FS_POINTER(ptTree, ptTree->next,
                                                          bPosInd);

                //
                // If this is a position independent file system image, we can
                // also check that the new node is within the image. If it
                // isn't, the image is corrupted to stop the search.
                //
                if(bPosInd && (ptTree >= ptEnd))
                {
                    ptTree = NULL;
                }
            }
        }

        //
        // If we didn't find the file, ptTee will be NULL.  Make sure we
        // return a NULL pointer if this happens.
        //
        if(NULL == ptTree)
        {
            mem_free(ptFile->pextension);
            mem_free(ptFile);
            ptFile = NULL;
        }
    }
    else
    {
        //
        // This file is on the FAT file system.
        //

        //
        // Allocate memory for the Fat File system handle.
        //
        pWrapper->pFATFile = mem_malloc(sizeof(FIL));
        if(NULL == pWrapper->pFATFile)
        {
            mem_free(ptFile->pextension);
            mem_free(ptFile);
            ptFile = NULL;
        }
        else
        {
            //
            // Reformat the filename to start with the FAT logical drive number.
            //
            pcFilename = mem_malloc(strlen(pcFSFilename) + 16);
            if(!pcFilename)
            {
                //
                // Can't allocate temporary storage for the reformatted
                // filename!
                //
                mem_free(pWrapper->pFATFile);
                mem_free(ptFile->pextension);
                mem_free(ptFile);
                ptFile = NULL;
            }
            else
            {
                usprintf(pcFilename, "%d:%s",
                         g_psMountPoints[pWrapper->ulMountIndex].ulDriveNum,
                         pcFSFilename);
                //
                // Attempt to open the file on the Fat File System.
                //
                fresult = f_open(pWrapper->pFATFile, pcFilename, FA_READ);

                //
                // Free the filename storage
                //
                mem_free(pcFilename);

                //
                // Did we open the file correctly?
                //
                if(FR_OK == fresult)
                {
                    //
                    // Yes - fill in the file structure to indicate that a
                    // FAT file is in use.
                    //
                    ptFile->data = NULL;
                    ptFile->len = NULL;
                    ptFile->index = NULL;
                }
                else
                {
                    //
                    // If we get here, we failed to find the file on the FAT
                    // file system so free up the FAT handle/object.
                    //
                    mem_free(pWrapper->pFATFile);
                    mem_free(pWrapper);
                    mem_free(ptFile);
                    ptFile = NULL;
                }
            }
        }
    }

    //
    // Disable access to the physical medium if we have been provided with
    // a callback for this.
    //
    if(g_psMountPoints[pWrapper->ulMountIndex].pfnDisable)
    {
        g_psMountPoints[pWrapper->ulMountIndex].pfnDisable(
                                                       pWrapper->ulMountIndex);
    }

    return(ptFile);
}