|
@@ -869,6 +869,14 @@ static dir_entry *extract_vfat_name(fat_itr *itr)
|
|
|
return NULL;
|
|
|
}
|
|
|
|
|
|
+ /*
|
|
|
+ * We are now at the short file name entry.
|
|
|
+ * If it is marked as deleted, just skip it.
|
|
|
+ */
|
|
|
+ if (dent->name[0] == DELETED_FLAG ||
|
|
|
+ dent->name[0] == aRING)
|
|
|
+ return NULL;
|
|
|
+
|
|
|
itr->l_name[n] = '\0';
|
|
|
|
|
|
chksum = mkcksum(dent->name, dent->ext);
|
|
@@ -898,6 +906,16 @@ static int fat_itr_next(fat_itr *itr)
|
|
|
|
|
|
itr->name = NULL;
|
|
|
|
|
|
+ /*
|
|
|
+ * One logical directory entry consist of following slots:
|
|
|
+ * name[0] Attributes
|
|
|
+ * dent[N - N]: LFN[N - 1] N|0x40 ATTR_VFAT
|
|
|
+ * ...
|
|
|
+ * dent[N - 2]: LFN[1] 2 ATTR_VFAT
|
|
|
+ * dent[N - 1]: LFN[0] 1 ATTR_VFAT
|
|
|
+ * dent[N]: SFN ATTR_ARCH
|
|
|
+ */
|
|
|
+
|
|
|
while (1) {
|
|
|
dent = next_dent(itr);
|
|
|
if (!dent)
|
|
@@ -910,7 +928,17 @@ static int fat_itr_next(fat_itr *itr)
|
|
|
if (dent->attr & ATTR_VOLUME) {
|
|
|
if ((dent->attr & ATTR_VFAT) == ATTR_VFAT &&
|
|
|
(dent->name[0] & LAST_LONG_ENTRY_MASK)) {
|
|
|
+ /* long file name */
|
|
|
dent = extract_vfat_name(itr);
|
|
|
+ /*
|
|
|
+ * If succeeded, dent has a valid short file
|
|
|
+ * name entry for the current entry.
|
|
|
+ * If failed, itr points to a current bogus
|
|
|
+ * entry. So after fetching a next one,
|
|
|
+ * it may have a short file name entry
|
|
|
+ * for this bogus entry so that we can still
|
|
|
+ * check for a short name.
|
|
|
+ */
|
|
|
if (!dent)
|
|
|
continue;
|
|
|
itr->name = itr->l_name;
|
|
@@ -919,8 +947,11 @@ static int fat_itr_next(fat_itr *itr)
|
|
|
/* Volume label or VFAT entry, skip */
|
|
|
continue;
|
|
|
}
|
|
|
- }
|
|
|
+ } else if (!(dent->attr & ATTR_ARCH) &&
|
|
|
+ !(dent->attr & ATTR_DIR))
|
|
|
+ continue;
|
|
|
|
|
|
+ /* short file name */
|
|
|
break;
|
|
|
}
|
|
|
|