📄 fat.c
字号:
FAT_DPRINT("\nfat32_length:");
for(i=0;i<1;i++)
FAT_DPRINT("%0x ",bs->fat32_length);
//__u16 flags; /* Bit 8: fat mirroring, low 4: active fat */
FAT_DPRINT("\nflags:");
for(i=0;i<1;i++)
FAT_DPRINT("%0x ",bs->flags);
//__u8 version[2]; /* Filesystem version */
FAT_DPRINT("\nversion[2]:");
for(i=0;i<2;i++)
FAT_DPRINT("%0x ",bs->version[i]);
//__u32 root_cluster; /* First cluster in root directory */
FAT_DPRINT("\nroot_cluster:");
for(i=0;i<1;i++)
FAT_DPRINT("%0x ",bs->root_cluster);
//__u16 info_sector; /* Filesystem info sector */
FAT_DPRINT("\ninfo_sector:");
for(i=0;i<1;i++)
FAT_DPRINT("%0x ",bs->info_sector);
//__u16 backup_boot; /* Backup boot sector */
FAT_DPRINT("\nbackup_boot:");
for(i=0;i<1;i++)
FAT_DPRINT("%0x ",bs->backup_boot);
//__u16 reserved2[6]; /* Unused */
FAT_DPRINT("\nUnused:");
for(i=0;i<6;i++)
FAT_DPRINT("%0x ",bs->reserved2[i]);
FAT_DPRINT("\n");
bs->reserved = FAT2CPU16(bs->reserved);
bs->fat_length = FAT2CPU16(bs->fat_length);
bs->secs_track = FAT2CPU16(bs->secs_track);
bs->heads = FAT2CPU16(bs->heads);
#if 0 /* UNUSED */
bs->hidden = FAT2CPU32(bs->hidden);
#endif
bs->total_sect = FAT2CPU32(bs->total_sect);
/* FAT32 entries */
if (bs->fat_length == 0)
{
/* Assume FAT32 */
bs->fat32_length = FAT2CPU32(bs->fat32_length);
bs->flags = FAT2CPU16(bs->flags);
bs->root_cluster = FAT2CPU32(bs->root_cluster);
bs->info_sector = FAT2CPU16(bs->info_sector);
bs->backup_boot = FAT2CPU16(bs->backup_boot);
vistart = (volume_info*) (block + sizeof(boot_sector));
*fatsize = 32;
}
else
{
vistart = (volume_info*) &(bs->fat32_length);
*fatsize = 0;
}
memcpy(volinfo, vistart, sizeof(volume_info));
/* Terminate fs_type string. Writing past the end of vistart
is ok - it's just the buffer. */
vistart->fs_type[8] = '\0';
if (*fatsize == 32)
{
if (compare_sign(FAT32_SIGN, vistart->fs_type) == 0)
{
return 0;
}
}
else
{
if (compare_sign(FAT12_SIGN, vistart->fs_type) == 0)
{
*fatsize = 12;
return 0;
}
if (compare_sign(FAT16_SIGN, vistart->fs_type) == 0)
{
*fatsize = 16;
return 0;
}
}
FAT_DPRINT("Error: broken fs_type sign\n");
return -1;
}
__u8 do_fat_read_block[MAX_CLUSTSIZE]; /* Block buffer */
long do_fat_read (const char *filename, void *buffer, unsigned long maxsize,
int dols,unsigned long addr)
{
#if CONFIG_NIOS /* NIOS CPU cannot access big automatic arrays */
static
#endif
char fnamecopy[2048];
boot_sector bs;
volume_info volinfo;
fsdata datablock;
fsdata *mydata = &datablock;
dir_entry *dentptr;
__u16 prevcksum = 0xffff;
char *subname = "";
int rootdir_size, cursect;
int idx, isdir = 0;
int files = 0, dirs = 0;
long ret = 0;
int firsttime;
if (read_bootsectandvi (&bs, &volinfo, &mydata->fatsize))
{
FAT_DPRINT ("Error: reading boot sector\n");
return -1;
}
if (mydata->fatsize == 32)
{
mydata->fatlength = bs.fat32_length;
FAT_DPRINT ("mydata->fatsize == 32\n");
}
else
{
mydata->fatlength = bs.fat_length;
FAT_DPRINT ("mydata->fatsize == 16\n");
}
mydata->fat_sect = bs.reserved;
cursect = mydata->rootdir_sect
= mydata->fat_sect + mydata->fatlength * bs.fats;
mydata->clust_size = bs.cluster_size;
if (mydata->fatsize == 32)
{
rootdir_size = mydata->clust_size;
mydata->data_begin = mydata->rootdir_sect /* + rootdir_size */
- (mydata->clust_size * 2);
}
else
{
rootdir_size = ((bs.dir_entries[1] * (int) 256 + bs.dir_entries[0])
* sizeof (dir_entry)) / SECTOR_SIZE;
mydata->data_begin = mydata->rootdir_sect + rootdir_size
- (mydata->clust_size * 2);
}
mydata->fatbufnum = -1;
FAT_DPRINT ("FAT%d, fatlength: %d\n", mydata->fatsize,
mydata->fatlength);
FAT_DPRINT ("Rootdir begins at sector: %d, offset: %x, size: %d\n"
"Data begins at: %d\n",
mydata->rootdir_sect, mydata->rootdir_sect * SECTOR_SIZE,
rootdir_size, mydata->data_begin);
FAT_DPRINT ("Cluster size: %d\n", mydata->clust_size);
/* "cwd" is always the root... */
while (ISDIRDELIM (*filename))
filename++;
/* Make a copy of the filename and convert it to lowercase */
strcpy (fnamecopy, filename);
downcase (fnamecopy);
if (*fnamecopy == '\0')
{
if (!dols)
return -1;
dols = LS_ROOT;
}
else if ((idx = dirdelim (fnamecopy)) >= 0)
{
isdir = 1;
fnamecopy[idx] = '\0';
subname = fnamecopy + idx + 1;
/* Handle multiple delimiters */
while (ISDIRDELIM (*subname))
subname++;
}
else if (dols)
{
isdir = 1;
}
FAT_DPRINT ("isdir=%d \n",isdir);
while (1)
{
int i;
if (disk_read (cursect, mydata->clust_size, do_fat_read_block) < 0)
{
FAT_DPRINT ("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];
l_name[0] = '\0';
if ((dentptr->attr & ATTR_VOLUME))
{
#ifdef CONFIG_SUPPORT_VFAT
if ((dentptr->attr & ATTR_VFAT) &&
(dentptr->name[0] & LAST_LONG_ENTRY_MASK))
{
prevcksum = ((dir_slot *) dentptr)->alias_checksum;
get_vfatname (mydata, 0, do_fat_read_block, dentptr, l_name);
if (dols == LS_ROOT)
{
int isdir = (dentptr->attr & ATTR_DIR);
char dirc;
int doit = 0;
if (isdir)
{
dirs++;
dirc = '/';
doit = 1;
}
else
{
dirc = ' ';
if (l_name[0] != 0)
{
files++;
doit = 1;
}
}
if (doit)
{
if (dirc == ' ')
{
FAT_DPRINT(" %8ld %s%c\n",
(long) FAT2CPU32 (dentptr->size),
l_name, dirc);
}
else
{
FAT_DPRINT(" %s%c\n", l_name, dirc);
}
}
dentptr++;
continue;
}
FAT_DPRINT ("Rootvfatname: |%s|\n", l_name);
}
else
#endif
{
/* Volume label or VFAT entry */
dentptr++;
continue;
}
}
else if (dentptr->name[0] == 0)
{
FAT_DPRINT ("RootDentname == NULL - %d\n", i);
if (dols == LS_ROOT)
{
FAT_DPRINT("\n%d file(s), %d dir(s)\n\n", files, dirs);
return 0;
}
return -1;
}
#ifdef CONFIG_SUPPORT_VFAT
else if (dols == LS_ROOT
&& mkcksum (dentptr->name) == prevcksum)
{
dentptr++;
continue;
}
#endif
get_name (dentptr, s_name);
if (dols == LS_ROOT)
{
int isdir = (dentptr->attr & ATTR_DIR);
char dirc;
int doit = 0;
if (isdir)
{
dirc = '/';
if (s_name[0] != 0)
{
dirs++;
doit = 1;
}
}
else
{
dirc = ' ';
if (s_name[0] != 0)
{
files++;
doit = 1;
}
}
if (doit)
{
if (dirc == ' ')
{
FAT_DPRINT(" %8ld %s%c\n",
(long) FAT2CPU32 (dentptr->size), s_name,
dirc);
}
else
{
FAT_DPRINT(" %s%c\n", s_name, dirc);
}
}
dentptr++;
continue;
}
if (strcmp (fnamecopy, s_name) && strcmp (fnamecopy, l_name))
{
FAT_DPRINT ("RootMismatch: |%s|%s|\n", s_name, l_name);
dentptr++;
continue;
}
if (isdir && !(dentptr->attr & ATTR_DIR))
return -1;
FAT_DPRINT ("RootName: %s", s_name);
FAT_DPRINT (", start: 0x%x", START (dentptr));
FAT_DPRINT (", size: 0x%x %s\n",
FAT2CPU32 (dentptr->size), isdir ? "(DIR)" : "");
goto rootdir_done; /* We got a match */
}
cursect++;
}
rootdir_done:
firsttime = 1;
while (isdir)
{
int startsect = mydata->data_begin
+ START (dentptr) * mydata->clust_size;
dir_entry dent;
char *nextname = NULL;
dent = *dentptr;
dentptr = &dent;
idx = dirdelim (subname);
if (idx >= 0)
{
subname[idx] = '\0';
nextname = subname + idx + 1;
/* Handle multiple delimiters */
while (ISDIRDELIM (*nextname))
nextname++;
if (dols && *nextname == '\0')
firsttime = 0;
}
else
{
if (dols && firsttime)
{
firsttime = 0;
}
else
{
isdir = 0;
}
}
if (get_dentfromdir (mydata, startsect, subname, dentptr,
isdir ? 0 : dols) == NULL)
{
if (dols && !isdir)
return 0;
return -1;
}
if (idx >= 0)
{
if (!(dentptr->attr & ATTR_DIR))
return -1;
subname = nextname;
}
}
ret = get_contents (mydata, dentptr, buffer, maxsize,addr);
FAT_DPRINT ("Size: %d, got: %ld\n", FAT2CPU32 (dentptr->size), ret);
return ret;
}
int
file_fat_detectfs(void)
{
boot_sector bs;
volume_info volinfo;
int fatsize;
char vol_label[12];
if(cur_dev==NULL)
{
FAT_DPRINT("No current device\n");
return 1;
}
s_UartPrint("Interface: ");
switch(cur_dev->if_type)
{
case IF_TYPE_IDE : FAT_DPRINT("IDE"); break;
case IF_TYPE_SCSI : FAT_DPRINT("SCSI"); break;
case IF_TYPE_ATAPI : FAT_DPRINT("ATAPI"); break;
case IF_TYPE_USB : FAT_DPRINT("USB"); break;
case IF_TYPE_DOC : FAT_DPRINT("DOC"); break;
case IF_TYPE_MMC : FAT_DPRINT("MMC"); break;
default : FAT_DPRINT("Unknown");
}
FAT_DPRINT("\n Device %d: ",cur_dev->dev);
dev_print(cur_dev);
if(read_bootsectandvi(&bs, &volinfo, &fatsize))
{
FAT_DPRINT("\nNo valid FAT fs found\n");
return 1;
}
memcpy (vol_label, volinfo.volume_label, 11);
vol_label[11] = '\0';
volinfo.fs_type[5]='\0';
FAT_DPRINT("Partition %d: Filesystem: %s \"%s\"\n",cur_part,volinfo.fs_type,vol_label);
return 0;
}
int
file_fat_ls(const char *dir)
{
return do_fat_read(dir, NULL, 0, LS_YES,0);
}
long
file_fat_read(const char *filename, void *buffer, unsigned long maxsize,unsigned long addr)
{
FAT_DPRINT("reading %s\n",filename);
return do_fat_read(filename, buffer, maxsize, LS_NO,addr);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -