/var/www/restricted/ssh/stm32/www/stm32circle/ STM CircleOS forum / DFS_OpenDir bugs and fixes

Username:     
Password:     
             

Forum

# 1   2010-06-21 10:25:02 DFS_OpenDir bugs and fixes

diabolo38
Member
Registered: 2010-03-12
Posts: 50

DFS_OpenDir bugs and fixes

The status return code is  assuming dirinfo->currentcluster to be 0 if no matching dir was found on the search loop but for fat32 FAT232 dirinfo->currentcluster  is actualy not 0
So DFS_OpenDir always (almost always)  return an "OK" status when opening a non fat32 root dir even if it actually failed to open it !!

here is  the code with a possible fixes  note  it come for 3.8  version as i' did not switch to 3.82 because of quite many fixes i have on a few overs os files sad

Code:

NODEBUG uint32_t DFS_OpenDir(PVOLINFO volinfo, uint8_t *dirname, PDIRINFO dirinfo)
{
    /* Default behavior is a regular search for existing entries*/
    dirinfo->flags = 0;
    u8 c = *dirname;
// ms fix for fat32 
    int  Found=0;

/*    if (!DFS_strlen((u8 *) dirname) || (DFS_strlen((u8 *) dirname) == 1 && dirname[0] == DIR_SEPARATOR))   // YRT20080204*/
    if (!my_strlen((u8 *) dirname) || (my_strlen((u8 *) dirname) == 1 && dirname[0] == DIR_SEPARATOR))
    {
        if (volinfo->filesystem == FAT32) {
            dirinfo->currentcluster = volinfo->rootdir;
            dirinfo->currentsector = 0;
            dirinfo->currententry = 0;

            /* read first sector of directory*/
            return DFS_ReadSector(volinfo->unit, dirinfo->scratch, volinfo->dataarea + ((volinfo->rootdir - 2) * volinfo->secperclus), 1);
        }
        else {
            dirinfo->currentcluster = 0;
            dirinfo->currentsector = 0;
            dirinfo->currententry = 0;

            /* read first sector of directory*/
            return DFS_ReadSector(volinfo->unit, dirinfo->scratch, volinfo->rootdir, 1);
        }
    }

    /* This is not the root directory. We need to find the start of this subdirectory.*/
    /* We do this by devious means, using our own companion function DFS_GetNext.*/
    else {
        uint8_t tmpfn[12];
        uint8_t *ptr = dirname;
        uint32_t result;
        DIRENT de;

        if (volinfo->filesystem == FAT32) {
            dirinfo->currentcluster = volinfo->rootdir;
            dirinfo->currentsector = 0;
            dirinfo->currententry = 0;

            /* read first sector of directory*/
            if (DFS_ReadSector(volinfo->unit, dirinfo->scratch, volinfo->dataarea + ((volinfo->rootdir - 2) * volinfo->secperclus), 1))
                return DFS_ERRMISC;
        }
        else {
            dirinfo->currentcluster = 0;
            dirinfo->currentsector = 0;
            dirinfo->currententry = 0;

            /* read first sector of directory*/
            if (DFS_ReadSector(volinfo->unit, dirinfo->scratch, volinfo->rootdir, 1))
                return DFS_ERRMISC;
        }

        /* skip leading path separators*/
        while (*ptr == DIR_SEPARATOR && *ptr)
            ptr++;

        /* Scan the path from left to right, finding the start cluster of each entry*/
        /* Observe that this code is inelegant, but obviates the need for recursion.*/
        while (*ptr) 
            {
        
            DFS_CanonicalToDir(tmpfn, ptr);
            
            de.name[0] = 0;
            
            Found=0;//ms  open dir fat32 fix

            do {
                result = DFS_GetNext(volinfo, dirinfo, &de);
            } while (!result && DFS_memcmp(de.name, tmpfn, 11));

            if (!DFS_memcmp(de.name, tmpfn, 11) && ((de.attr & ATTR_DIRECTORY) == ATTR_DIRECTORY)) {
                if (volinfo->filesystem == FAT32) {
                    dirinfo->currentcluster = (uint32_t) de.startclus_l_l |
                      ((uint32_t) de.startclus_l_h) << 8 |
                      ((uint32_t) de.startclus_h_l) << 16 |
                      ((uint32_t) de.startclus_h_h) << 24;
                }
                else {
                    dirinfo->currentcluster = (uint32_t) de.startclus_l_l |
                      ((uint32_t) de.startclus_l_h) << 8;
                }
                dirinfo->currentsector = 0;
                dirinfo->currententry = 0;
                Found=1; //ms fix  for fat32 
                if (DFS_ReadSector(volinfo->unit, dirinfo->scratch, volinfo->dataarea + ((dirinfo->currentcluster - 2) * volinfo->secperclus), 1))
                    return DFS_ERRMISC;
            }
            else if (!DFS_memcmp(de.name, tmpfn, 11) && !(de.attr & ATTR_DIRECTORY))
                return DFS_NOTFOUND;

            /* seek to next item in list*/
            while (*ptr != DIR_SEPARATOR && *ptr)
                ptr++;
            if (*ptr == DIR_SEPARATOR)
                ptr++;
        }

//        if (!dirinfo->currentcluster) 
        if (!Found)
            return DFS_NOTFOUND;
    }
    return DFS_OK;
}

Offline

 

# 2   2010-06-21 10:29:24 DFS_OpenDir bugs and fixes

yrt
Administrator
From: Grenoble-France
Registered: 2008-06-11
Posts: 520
Website

Re: DFS_OpenDir bugs and fixes

Hi diabolo38,

It would be interesting that you share the few fixes you made on OS files wink.
Thanks

Yves

Offline

 

# 3   2010-06-21 10:38:32 DFS_OpenDir bugs and fixes

diabolo38
Member
Registered: 2010-03-12
Posts: 50

Re: DFS_OpenDir bugs and fixes

the overs fixes in FS/DFS are the one for directory create posted by ntrf  http://www.stm32circle.com/forum/viewtopic.php?id=1096
The over fixes and "hack" are on LCD/DRAW (no fsmc+extended drawable area) those are quite specific to my needs ...

Offline

 

# 4   2010-06-21 11:45:47 DFS_OpenDir bugs and fixes

diabolo38
Member
Registered: 2010-03-12
Posts: 50

Re: DFS_OpenDir bugs and fixes

I believe there 's still an issue on  the code
if you wan to open  dir "c"  subidr "a/b"  so  OpenDir("a/b/c")  and have a file named "c"  in root " /c"  or  "/a/c"  then it will wrongly fail  cos of

Code:

 if (!DFS_memcmp(de.name, tmpfn, 11) && !(de.attr & ATTR_DIRECTORY))
                return DFS_NOTFOUND;

should be changed to something like

Code:

 if (!DFS_memcmp(de.name, tmpfn, 11) && !(de.attr & ATTR_DIRECTORY) &&  !(*ptr) )
                return DFS_NOTFOUND;

Offline

 

Board footer