Index: apps/playlist.c =================================================================== --- apps/playlist.c (revision 17675) +++ apps/playlist.c (working copy) @@ -2871,6 +2871,10 @@ { int result; +#ifdef HAVE_VOLUMELABEL + if (!file_exists(filename)) + return 0; +#endif if (!playlist) playlist = ¤t_playlist; Index: apps/tagcache.h =================================================================== --- apps/tagcache.h (revision 17675) +++ apps/tagcache.h (working copy) @@ -100,7 +100,11 @@ enum clause { clause_none, clause_is, clause_is_not, clause_gt, clause_gteq, clause_lt, clause_lteq, clause_contains, clause_not_contains, clause_begins_with, clause_not_begins_with, clause_ends_with, - clause_not_ends_with, clause_oneof }; + clause_not_ends_with, clause_oneof +#ifdef HAVE_VOLUMELABEL + , clause_mounted +#endif + }; struct tagcache_stat { bool initialized; /* Is tagcache currently busy? */ Index: apps/tagcache.c =================================================================== --- apps/tagcache.c (revision 17675) +++ apps/tagcache.c (working copy) @@ -853,6 +853,13 @@ return false; } +#ifdef HAVE_VOLUMELABEL +inline static bool str_mounted(const char *str, const char *dummy) +{ + return mounted(str); +} +#endif + static bool check_against_clause(long numeric, const char *str, const struct tagcache_search_clause *clause) { @@ -906,7 +913,10 @@ return !str_ends_with(str, clause->str); case clause_oneof: return str_oneof(str, clause->str); - +#ifdef HAVE_VOLUMELABEL + case clause_mounted: + return str_mounted(str, clause->str); +#endif default: logf("Incorrect tag: %d", clause->type); } @@ -3935,7 +3945,11 @@ if (dircache_is_enabled()) { dc = dircache_get_entry_ptr(buf); - if (dc == NULL) + if (dc == NULL +#ifdef HAVE_VOLUMELABEL + && mounted(buf) +#endif + ) { logf("Entry no longer valid."); logf("-> %s", buf); @@ -3956,7 +3970,11 @@ /* Check if entry has been removed. */ if (global_settings.tagcache_autoupdate) { - if (!file_exists(buf)) + if (!file_exists(buf) +#ifdef HAVE_VOLUMELABEL + && mounted(buf) +#endif + ) { logf("Entry no longer valid."); logf("-> %s", buf); @@ -4047,7 +4065,11 @@ continue; /* Now check if the file exists. */ - if (!file_exists(buf)) + if (!file_exists(buf) +#ifdef HAVE_VOLUMELABEL + && mounted(buf) +#endif + ) { logf("Entry no longer valid."); logf("-> %s / %d", buf, tfe.tag_length); Index: apps/tagtree.c =================================================================== --- apps/tagtree.c (revision 17675) +++ apps/tagtree.c (working copy) @@ -284,7 +284,9 @@ MATCH(condition, buf, "$", clause_ends_with); MATCH(condition, buf, "!$", clause_not_ends_with); MATCH(condition, buf, "@", clause_oneof); - +#ifdef HAVE_VOLUMELABEL + MATCH(condition, buf, "is", clause_mounted); +#endif return 0; } Index: firmware/common/dircache.c =================================================================== --- firmware/common/dircache.c (revision 17675) +++ firmware/common/dircache.c (working copy) @@ -294,8 +294,14 @@ if (volume > 0) { ce->d_name = ((char *)dircache_root+dircache_size); +#ifdef HAVE_VOLUMELABEL + strncpy(ce->d_name, fat_vol_name(volume), + sizeof(ce->d_name)); + ce->name_len = fat_vol_name_sz(volume); +#else snprintf(ce->d_name, VOL_ENUM_POS + 3, VOL_NAMES, volume); ce->name_len = VOL_ENUM_POS + 3; +#endif dircache_size += ce->name_len; ce->attribute = FAT_ATTR_DIRECTORY | FAT_ATTR_VOLUME; ce->size = 0; Index: firmware/common/dir_uncached.c =================================================================== --- firmware/common/dir_uncached.c (revision 17675) +++ firmware/common/dir_uncached.c (working copy) @@ -31,6 +31,29 @@ #ifdef HAVE_MULTIVOLUME +#ifdef HAVE_VOLUMELABEL +/* returns true, if the filename is on a mounted volume */ +int mounted(const char *file) +{ + const char *temp = file; + while (*temp == '/') /* skip all leading slashes */ + ++temp; + + if ( *temp != '<') + return true; + + int i; + for ( i=1; iattribute = FAT_ATTR_DIRECTORY | FAT_ATTR_VOLUME; +#ifdef HAVE_VOLUMELABEL + strncpy(theent->d_name, fat_vol_name(dir->volumecounter), + sizeof(theent->d_name)); +#else snprintf(theent->d_name, sizeof(theent->d_name), VOL_NAMES, dir->volumecounter); +#endif return theent; } } Index: firmware/drivers/fat.c =================================================================== --- firmware/drivers/fat.c (revision 17675) +++ firmware/drivers/fat.c (working copy) @@ -23,6 +23,7 @@ #include #include "fat.h" #include "ata.h" +#include "dir.h" #include "debug.h" #include "panic.h" #include "system.h" @@ -167,7 +168,11 @@ #ifdef HAVE_MULTIVOLUME int drive; /* on which physical device is this located */ bool mounted; /* flag if this volume is mounted */ +#ifdef HAVE_VOLUMELABEL + char mountpt[14]; /* mount point */ + int mountpt_sz; /* length of mount point name */ #endif +#endif }; static struct bpb fat_bpbs[NUM_VOLUMES]; /* mounted partition info */ @@ -279,6 +284,10 @@ for (i=0; ibpb_rootclus = 0 - dirclusters; /* backwards, before the data*/ fat_bpb->rootdiroffset = dirclusters * fat_bpb->bpb_secperclus - rootdirsectors; +#ifdef HAVE_VOLUMELABEL + snprintf(fat_bpb->mountpt, sizeof(fat_bpb->mountpt)-2, + "%s", buf + BS_VOLLAB); +#endif } else #endif /* #ifdef HAVE_FAT16SUPPORT */ @@ -401,6 +414,10 @@ fat_bpb->bpb_fsinfo = secmult * BYTES2INT16(buf,BPB_FSINFO); fat_bpb->rootdirsector = cluster2sec(IF_MV2(fat_bpb,) fat_bpb->bpb_rootclus); +#ifdef HAVE_VOLUMELABEL + snprintf(fat_bpb->mountpt, sizeof(fat_bpb->mountpt)-2, + "%s", buf + BS_32_VOLLAB); +#endif } rc = bpb_is_sane(IF_MV(fat_bpb)); @@ -445,7 +462,32 @@ #ifdef HAVE_MULTIVOLUME fat_bpb->mounted = true; +#ifdef HAVE_VOLUMELABEL +/* default if no volume label is found */ +/* should be refined, when there are several equal labels, + and/or we have a flag for using volume labels as mount points */ + if ( fat_bpb->mountpt[0] == 0 ) + { + snprintf(fat_bpb->mountpt,sizeof(fat_bpb->mountpt),VOL_NAMES,volume); + fat_bpb->mountpt_sz = strlen(fat_bpb->mountpt); + } + else + { + /* trim trailing blanks and add '<' and '>'*/ + char* c = fat_bpb->mountpt + strlen(fat_bpb->mountpt); + while ( (*c == 0 || *c == ' ') && c > fat_bpb->mountpt) + { + *c = 0; + c--; + } + memmove(fat_bpb->mountpt+1, fat_bpb->mountpt, + strlen(fat_bpb->mountpt)); + fat_bpb->mountpt[0] = '<'; + fat_bpb->mountpt[strlen(fat_bpb->mountpt)] = '>'; + fat_bpb->mountpt_sz = strlen(fat_bpb->mountpt); + } #endif +#endif return 0; } @@ -477,6 +519,10 @@ rc = 0; } fat_bpb->mounted = false; +#ifdef HAVE_VOLUMELABEL + memset(fat_bpb->mountpt,0,sizeof(fat_bpb->mountpt)); + fat_bpb->mountpt_sz = 0; +#endif return rc; } #endif /* #ifdef HAVE_HOTSWAP */ @@ -2517,4 +2563,16 @@ { return (volume