Index: firmware/drivers/fat.c =================================================================== --- firmware/drivers/fat.c (revision 13791) +++ firmware/drivers/fat.c (working copy) @@ -1863,6 +1863,9 @@ int rc; struct fat_dir olddir; struct fat_file newfile = *file; + unsigned char buf[SECTOR_SIZE]; + unsigned char* entry = NULL; + unsigned short* clusptr; #ifdef HAVE_MULTIVOLUME struct bpb* fat_bpb = &fat_bpbs[file->volume]; @@ -1870,6 +1873,8 @@ DEBUGF("No rename across volumes!\n"); return -1; } +#else + struct bpb* fat_bpb = &fat_bpbs[0]; #endif if ( !file->dircluster ) { @@ -1899,8 +1904,51 @@ rc = flush_fat(IF_MV(fat_bpb)); if (rc < 0) - return rc * 10 - 7; + return rc * 10 - 9; + /* if renaming a directory, update the .. entry to make sure + it points to its parent directory */ + if(FAT_ATTR_DIRECTORY == attr) { + /* 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; + +// if(strncmp(".. ", dirent->name, 11)) +// { +// return rc * 10 - 8; +// } +// if(dir->file.firstcluster == fat_bpb->bpb_rootclus) +// dirent->firstcluster = 0; +// else +// dirent->firstcluster = dir->file.firstcluster; + entry = buf + DIR_ENTRY_SIZE; // assume entry 2 (yes this hack must be fixed) + + clusptr = (short*)(entry + FATDIR_FSTCLUSHI); + *clusptr = htole16(dir->file.firstcluster >> 16); + + clusptr = (short*)(entry + FATDIR_FSTCLUSLO); + *clusptr = htole16(dir->file.firstcluster & 0xffff); + + 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; }