static int
get_vfatname (fsdata *mydata, int curclust, __u8 *cluster,
- dir_entry **retdent, char *l_name)
+ dir_entry *retdent, char *l_name)
{
dir_entry *realdent;
- dir_slot *slotptr = (dir_slot *)(*retdent);
- __u8 *nextclust = cluster + mydata->clust_size * SECTOR_SIZE;
+ dir_slot *slotptr = (dir_slot *)retdent;
+ __u8 *buflimit = cluster + ((curclust == 0) ?
+ LINEAR_PREFETCH_SIZE :
+ (mydata->clust_size * SECTOR_SIZE)
+ );
__u8 counter = (slotptr->id & ~LAST_LONG_ENTRY_MASK) & 0xff;
int idx = 0;
- while ((__u8 *)slotptr < nextclust) {
+ if (counter > VFAT_MAXSEQ) {
+ debug("Error: VFAT name is too long\n");
+ return -1;
+ }
+
+ while ((__u8 *)slotptr < buflimit) {
if (counter == 0)
break;
if (((slotptr->id & ~LAST_LONG_ENTRY_MASK) & 0xff) != counter)
counter--;
}
- if ((__u8 *)slotptr >= nextclust) {
+ if ((__u8 *)slotptr >= buflimit) {
dir_slot *slotptr2;
- slotptr--;
+ if (curclust == 0)
+ return -1;
curclust = get_fatent(mydata, curclust);
if (CHECK_CLUST(curclust, mydata->fatsize)) {
debug("curclust: 0x%x\n", curclust);
}
slotptr2 = (dir_slot *)get_vfatname_block;
- while (slotptr2->id > 0x01)
+ while (counter > 0) {
+ if (((slotptr2->id & ~LAST_LONG_ENTRY_MASK)
+ & 0xff) != counter)
+ return -1;
slotptr2++;
+ counter--;
+ }
/* Save the real directory entry */
- realdent = (dir_entry *)slotptr2 + 1;
- while ((__u8 *)slotptr2 >= get_vfatname_block) {
- slot2str(slotptr2, l_name, &idx);
+ realdent = (dir_entry *)slotptr2;
+ while ((__u8 *)slotptr2 > get_vfatname_block) {
slotptr2--;
+ slot2str(slotptr2, l_name, &idx);
}
} else {
/* Save the real directory entry */
downcase(l_name);
/* Return the real directory entry */
- *retdent = realdent;
+ memcpy(retdent, realdent, sizeof(dir_entry));
return 0;
}
int dols)
{
__u16 prevcksum = 0xffff;
- __u32 curclust = startsect;
+ __u32 curclust = START(retdent);
int files = 0, dirs = 0;
debug("get_dentfromdir: %s\n", filename);
int i;
- if (disk_read(curclust, mydata->clust_size,
- get_dentfromdir_block) < 0) {
- printf("Error: reading directory block\n");
+ if (get_cluster(mydata, curclust, get_dentfromdir_block,
+ mydata->clust_size * SECTOR_SIZE) != 0) {
+ debug("Error: reading directory block\n");
return NULL;
}
dentptr = (dir_entry *)get_dentfromdir_block;
for (i = 0; i < DIRENTSPERCLUST; i++) {
- char s_name[14], l_name[256];
+ char s_name[14], l_name[VFAT_MAXLEN_BYTES];
l_name[0] = '\0';
if (dentptr->name[0] == DELETED_FLAG) {
prevcksum = ((dir_slot *)dentptr)->alias_checksum;
get_vfatname(mydata, curclust,
get_dentfromdir_block,
- &dentptr, l_name);
+ dentptr, l_name);
if (dols) {
int isdir;
char dirc;
FAT2CPU32(dentptr->size),
(dentptr->attr & ATTR_DIR) ? "(DIR)" : "");
- return dentptr;
+ return retdent;
}
curclust = get_fatent(mydata, curclust);
debug("FAT read sect=%d, clust_size=%d, DIRENTSPERBLOCK=%d\n",
cursect, mydata->clust_size, DIRENTSPERBLOCK);
- if (disk_read(cursect, mydata->clust_size, do_fat_read_block) < 0) {
+ if (disk_read(cursect,
+ (mydata->fatsize == 32) ?
+ (mydata->clust_size) :
+ LINEAR_PREFETCH_SIZE / SECTOR_SIZE,
+ do_fat_read_block) < 0) {
debug("Error: reading rootdir block\n");
return -1;
}
dentptr = (dir_entry *) do_fat_read_block;
for (i = 0; i < DIRENTSPERBLOCK; i++) {
- char s_name[14], l_name[256];
+ char s_name[14], l_name[VFAT_MAXLEN_BYTES];
l_name[0] = '\0';
+ if (dentptr->name[0] == DELETED_FLAG) {
+ dentptr++;
+ continue;
+ }
if ((dentptr->attr & ATTR_VOLUME)) {
#ifdef CONFIG_SUPPORT_VFAT
if ((dentptr->attr & ATTR_VFAT) &&
prevcksum =
((dir_slot *)dentptr)->alias_checksum;
- get_vfatname(mydata, 0,
+ get_vfatname(mydata,
+ (mydata->fatsize == 32) ?
+ root_cluster :
+ 0,
do_fat_read_block,
- &dentptr, l_name);
+ dentptr, l_name);
if (dols == LS_ROOT) {
char dirc;