diff --git a/src/namspace.c b/src/namspace.c index 6bd779d..25fd4b0 100644 --- a/src/namspace.c +++ b/src/namspace.c @@ -912,10 +912,32 @@ static int build_dos_name(DIR_BASE_ENTRY *e, uint8 *fname, int size_fname) { char *parent_unix; int result; + N_NW_PATH parent_path; + int plen; if (!e || !fname || size_fname < 2) return(0); - parent_unix = alloc_nwpath2unix(&(e->nwpath), 1|2); + /* + * e->nwpath.path contains the full entry path and e->nwpath.fn points to + * the last component inside that buffer. alloc_nwpath2unix(..., 1|2) + * only gives the parent if fn is behind path. For entries directly in the + * volume root fn == path, so the old code accidentally used the entry + * itself as parent. That made collision checks local to each directory and + * both "long directory name one" and "long directory name two" became + * LONG_DIR. + */ + memcpy(&parent_path, &(e->nwpath), sizeof(parent_path)); + if (e->nwpath.fn && e->nwpath.fn > e->nwpath.path) { + plen = (int)(e->nwpath.fn - e->nwpath.path); + if (plen > 0 && e->nwpath.path[plen-1] == '/') --plen; + memcpy(parent_path.path, e->nwpath.path, plen); + parent_path.path[plen] = '\0'; + } else { + parent_path.path[0] = '\0'; + } + parent_path.fn = parent_path.path + strlen((char*)parent_path.path); + + parent_unix = alloc_nwpath2unix(&parent_path, 2); result = build_dos_83_alias(get_volume_options(e->nwpath.volume), (uint8*)parent_unix, e->nwpath.fn,