Browse Source

🐛 Fix Long FIlename lookup (#25598)

Eduard Sukharev 1 year ago
parent
commit
06d9a2ff8f

+ 3 - 2
Marlin/src/inc/Conditionals_post.h

@@ -3262,10 +3262,11 @@
 
 // Number of VFAT entries used. Each entry has 13 UTF-16 characters
 #if ANY(SCROLL_LONG_FILENAMES, HAS_DWIN_E3V2, TFT_COLOR_UI)
-  #define MAX_VFAT_ENTRIES 5
+  #define VFAT_ENTRIES_LIMIT 5
 #else
-  #define MAX_VFAT_ENTRIES 2
+  #define VFAT_ENTRIES_LIMIT 2
 #endif
+#define MAX_VFAT_ENTRIES 20 // by VFAT specs to fit LFN of length 255
 
 // Nozzle park for Delta
 #if BOTH(NOZZLE_PARK_FEATURE, DELTA)

+ 2 - 2
Marlin/src/inc/SanityCheck.h

@@ -1048,9 +1048,9 @@ static_assert(X_MAX_LENGTH >= X_BED_SIZE, "Movement bounds (X_MIN_POS, X_MAX_POS
   #if ENABLED(SDSORT_CACHE_NAMES) && DISABLED(SDSORT_DYNAMIC_RAM)
     #if SDSORT_CACHE_VFATS < 2
       #error "SDSORT_CACHE_VFATS must be 2 or greater!"
-    #elif SDSORT_CACHE_VFATS > MAX_VFAT_ENTRIES
+    #elif SDSORT_CACHE_VFATS > VFAT_ENTRIES_LIMIT
       #undef SDSORT_CACHE_VFATS
-      #define SDSORT_CACHE_VFATS MAX_VFAT_ENTRIES
+      #define SDSORT_CACHE_VFATS VFAT_ENTRIES_LIMIT
       #define SDSORT_CACHE_VFATS_WARNING 1
     #endif
   #endif

+ 1 - 1
Marlin/src/inc/Warnings.cpp

@@ -810,7 +810,7 @@
 #endif
 
 #if SDSORT_CACHE_VFATS_WARNING
-  #warning "SDSORT_CACHE_VFATS has been reduced to MAX_VFAT_ENTRIES."
+  #warning "SDSORT_CACHE_VFATS has been reduced to VFAT_ENTRIES_LIMIT."
 #endif
 #if SDSORT_CACHE_LPC1768_WARNING
   #warning "SDCARD_SORT_ALPHA sub-options overridden for LPC1768 with DOGM LCD SCK overlap."

+ 4 - 3
Marlin/src/sd/SdBaseFile.cpp

@@ -1003,7 +1003,8 @@ bool SdBaseFile::openNext(SdBaseFile *dirFile, uint8_t oflag) {
   bool SdBaseFile::isDirLFN(const dir_t* dir) {
     if (DIR_IS_LONG_NAME(dir)) {
       vfat_t *VFAT = (vfat_t*)dir;
-      // Sanity-check the VFAT entry. The first cluster is always set to zero. And the sequence number should be higher than 0
+      // Sanity-check the VFAT entry. The first cluster is always set to zero.
+      // The sequence number should be higher than 0 and lower than maximum allowed by VFAT spec
       if ((VFAT->firstClusterLow == 0) && WITHIN((VFAT->sequenceNumber & 0x1F), 1, MAX_VFAT_ENTRIES)) return true;
     }
     return false;
@@ -1463,7 +1464,7 @@ int8_t SdBaseFile::readDir(dir_t *dir, char * const longFilename) {
         // Sanity-check the VFAT entry. The first cluster is always set to zero. And the sequence number should be higher than 0
         if (VFAT->firstClusterLow == 0) {
           const uint8_t seq = VFAT->sequenceNumber & 0x1F;
-          if (WITHIN(seq, 1, MAX_VFAT_ENTRIES)) {
+          if (WITHIN(seq, 1, VFAT_ENTRIES_LIMIT)) {
             if (seq == 1) {
               checksum = VFAT->checksum;
               checksum_error = 0;
@@ -1627,7 +1628,7 @@ bool SdBaseFile::remove() {
     // Check if the entry has a LFN
     bool lastEntry = false;
     // loop back to search for any LFN entries related to this file
-    LOOP_S_LE_N(sequenceNumber, 1, MAX_VFAT_ENTRIES) {
+    LOOP_S_LE_N(sequenceNumber, 1, VFAT_ENTRIES_LIMIT) {
       dirIndex_ = (dirIndex_ - 1) & 0xF;
       if (dirBlock_ == 0) break;
       if (dirIndex_ == 0xF) dirBlock_--;

+ 1 - 1
Marlin/src/sd/SdFatConfig.h

@@ -109,4 +109,4 @@
 #define LONG_FILENAME_CHARSIZE TERN(UTF_FILENAME_SUPPORT, 2, 1)
 
 // Total bytes needed to store a single long filename
-#define LONG_FILENAME_LENGTH (FILENAME_LENGTH * LONG_FILENAME_CHARSIZE * MAX_VFAT_ENTRIES + 1)
+#define LONG_FILENAME_LENGTH (FILENAME_LENGTH * LONG_FILENAME_CHARSIZE * VFAT_ENTRIES_LIMIT + 1)