Index: firmware/drivers/fat.c =================================================================== --- firmware/drivers/fat.c (revision 13750) +++ 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]; @@ -1903,10 +1905,47 @@ rc = free_direntries(file); if (rc < 0) return rc * 10 - 6; + + /* 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, file->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; + + /* assume that ".." is entry 2 in the dir */ + dirent = (struct fat_direntry*)(buf + DIR_ENTRY_SIZE); + if(strncmp(".. ", dirent->name, 11)) + { + /*gui_syncsplash(HZ, dirent->name);*/ + return rc * 10 - 8; + } + + 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; + } + rc = flush_fat(IF_MV(fat_bpb)); if (rc < 0) - return rc * 10 - 7; + return rc * 10 - 9; return 0; }