Index: firmware/drivers/fat.c =================================================================== --- firmware/drivers/fat.c (revision 13762) +++ firmware/drivers/fat.c (working copy) @@ -1870,6 +1870,8 @@ int rc; struct fat_dir olddir; struct fat_file newfile = *file; + unsigned char buf[SECTOR_SIZE]; + struct fat_direntry* dirent; #ifdef HAVE_MULTIVOLUME struct bpb* fat_bpb = &fat_bpbs[file->volume]; @@ -1889,6 +1891,11 @@ if (rc < 0) return rc * 10 - 3; + /* let's debug */ + //gui_syncsplash(10*HZ, "dir: 0x%X", file->firstcluster); + //gui_syncsplash(10*HZ, "oldpar: 0x%X", olddir.file.firstcluster); + //gui_syncsplash(10*HZ, "newpar: 0x%X", dir->file.firstcluster); + /* create new name */ rc = add_dir_entry(dir, &newfile, newname, false, false); if (rc < 0) @@ -1906,8 +1913,60 @@ rc = flush_fat(IF_MV(fat_bpb)); if (rc < 0) - return rc * 10 - 7; + return rc * 10 - 9; + /* let's debug */ + //gui_syncsplash(10*HZ, "nf fc: 0x%X", newfile.firstcluster); + //gui_syncsplash(10*HZ, "nf par: 0x%X", newfile.dircluster); + + /* if renaming a directory, update the .. entry to make sure + it points to its parent directory */ + if(FAT_ATTR_DIRECTORY == attr) { + + /* first open the dir that was renamed, reusing the olddir struct */ + rc = fat_opendir(IF_MV2(file->volume,) &olddir, newfile.firstcluster, NULL); + if (rc < 0) + return rc * 10 - 7; + + /* get the dir entry */ + rc = fat_seek(&olddir.file, 0); + if (rc < 0) + return rc * 10 - 7; + + rc = fat_readwrite(&olddir.file, 1, buf, false); + if (rc < 0) + return rc * 10 - 7; + + /* let's debug */ + dirent = (struct fat_direntry*)(buf + 0*DIR_ENTRY_SIZE); /* . */ + if(strncmp(". ", dirent->name, 11)) + { + return rc * 10 - 8; + } + //gui_syncsplash(1*HZ, dirent->name); + //gui_syncsplash(10*HZ, "fc: 0x%X", dirent->firstcluster); + dirent->firstcluster = newfile.firstcluster; + + /* assume that ".." is entry 2 in the dir */ + dirent = (struct fat_direntry*)(buf + DIR_ENTRY_SIZE); + if(strncmp(".. ", dirent->name, 11)) + { + return rc * 10 - 8; + } + //gui_syncsplash(1*HZ, dirent->name); + //gui_syncsplash(10*HZ, "fc: 0x%X", dirent->firstcluster); + dirent->firstcluster = dir->file.firstcluster; + + rc = fat_seek(&olddir.file, 0); + if (rc < 0) + return rc * 10 - 7; + + /* write back this sector */ + rc = fat_readwrite(&olddir.file, 1, buf, true); + if (rc < 1) + return rc * 10 - 8; + } + return 0; }