#include <exports.h>
#include <fat.h>
#include <fs.h>
+#include <log.h>
#include <asm/byteorder.h>
#include <part.h>
#include <malloc.h>
#include <memalign.h>
+#include <asm/cache.h>
#include <linux/compiler.h>
#include <linux/ctype.h>
}
static struct blk_desc *cur_dev;
-static disk_partition_t cur_part_info;
+static struct disk_partition cur_part_info;
#define DOS_BOOT_MAGIC_OFFSET 0x1fe
#define DOS_FS_TYPE_OFFSET 0x36
return ret;
}
-int fat_set_blk_dev(struct blk_desc *dev_desc, disk_partition_t *info)
+int fat_set_blk_dev(struct blk_desc *dev_desc, struct disk_partition *info)
{
ALLOC_CACHE_ALIGN_BUFFER(unsigned char, buffer, dev_desc->blksz);
int fat_register_device(struct blk_desc *dev_desc, int part_no)
{
- disk_partition_t info;
+ struct disk_partition info;
/* First close any currently found FAT filesystem */
cur_dev = NULL;
}
} else {
idx = size / mydata->sect_size;
- ret = disk_read(startsect, idx, buffer);
+ if (idx == 0)
+ ret = 0;
+ else
+ ret = disk_read(startsect, idx, buffer);
if (ret != idx) {
debug("Error reading data (got %d)\n", ret);
return -1;
return 0;
}
-/*
+/**
+ * get_contents() - read from file
+ *
* Read at most 'maxsize' bytes from 'pos' in the file associated with 'dentptr'
- * into 'buffer'.
- * Update the number of bytes read in *gotsize or return -1 on fatal errors.
+ * into 'buffer'. Update the number of bytes read in *gotsize or return -1 on
+ * fatal errors.
+ *
+ * @mydata: file system description
+ * @dentprt: directory entry pointer
+ * @pos: position from where to read
+ * @buffer: buffer into which to read
+ * @maxsize: maximum number of bytes to read
+ * @gotsize: number of bytes actually read
+ * Return: -1 on error, otherwise 0
*/
static int get_contents(fsdata *mydata, dir_entry *dentptr, loff_t pos,
__u8 *buffer, loff_t maxsize, loff_t *gotsize)
curclust = get_fatent(mydata, curclust);
if (CHECK_CLUST(curclust, mydata->fatsize)) {
debug("curclust: 0x%x\n", curclust);
- debug("Invalid FAT entry\n");
- return 0;
+ printf("Invalid FAT entry\n");
+ return -1;
}
actsize += bytesperclust;
}
tmp_buffer = malloc_cache_aligned(actsize);
if (!tmp_buffer) {
debug("Error: allocating buffer\n");
- return -ENOMEM;
+ return -1;
}
if (get_cluster(mydata, curclust, tmp_buffer, actsize) != 0) {
curclust = get_fatent(mydata, curclust);
if (CHECK_CLUST(curclust, mydata->fatsize)) {
debug("curclust: 0x%x\n", curclust);
- debug("Invalid FAT entry\n");
- return 0;
+ printf("Invalid FAT entry\n");
+ return -1;
}
}
goto getit;
if (CHECK_CLUST(newclust, mydata->fatsize)) {
debug("curclust: 0x%x\n", newclust);
- debug("Invalid FAT entry\n");
- return 0;
+ printf("Invalid FAT entry\n");
+ return -1;
}
endclust = newclust;
actsize += bytesperclust;
if (CHECK_CLUST(curclust, mydata->fatsize)) {
debug("curclust: 0x%x\n", curclust);
printf("Invalid FAT entry\n");
- return 0;
+ return -1;
}
actsize = bytesperclust;
endclust = curclust;
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);
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)
return 0;
- if (dent->name[0] == DELETED_FLAG ||
- dent->name[0] == aRING)
+ if (dent->name[0] == DELETED_FLAG)
continue;
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;
}
}
+ /* short file name */
break;
}