📄 fat.c
字号:
return -1;
}
FAT_DPRINT("step5: actsize=%d endclust=%d \n",actsize,endclust);
if((addroffset+actsize)>addr)
{
offset=0;
if(addr>addroffset) offset=addr-addroffset;
memcpy(buffer,tempbuffer+offset,actsize-offset);
gotsize += (int)(actsize-offset);
buffer+=actsize-offset;
}
addroffset+=actsize;
filesize -= actsize;
//actsize= filesize;
//gotsize += (int)actsize;
//filesize -= actsize;
//buffer += actsize;
curclust = get_fatent(mydata, endclust);
if (curclust <= 0x0001 || curclust >= 0xfff0)
{
FAT_DPRINT("curclust: 0x%x\n", curclust);
FAT_ERROR("Invalid FAT entry\n");
return gotsize;
}
actsize=bytesperclust;
endclust=curclust;
}
while (1);
}
#ifdef CONFIG_SUPPORT_VFAT
/*
* Extract the file name information from 'slotptr' into 'l_name',
* starting at l_name[*idx].
* Return 1 if terminator (zero byte) is found, 0 otherwise.
*/
static int
slot2str(dir_slot *slotptr, char *l_name, int *idx)
{
int j;
for (j = 0; j <= 8; j += 2)
{
l_name[*idx] = slotptr->name0_4[j];
if (l_name[*idx] == 0x00) return 1;
(*idx)++;
}
for (j = 0; j <= 10; j += 2)
{
l_name[*idx] = slotptr->name5_10[j];
if (l_name[*idx] == 0x00) return 1;
(*idx)++;
}
for (j = 0; j <= 2; j += 2)
{
l_name[*idx] = slotptr->name11_12[j];
if (l_name[*idx] == 0x00) return 1;
(*idx)++;
}
return 0;
}
/*
* Extract the full long filename starting at 'retdent' (which is really
* a slot) into 'l_name'. If successful also copy the real directory entry
* into 'retdent'
* Return 0 on success, -1 otherwise.
*/
__u8 get_vfatname_block[MAX_CLUSTSIZE];
static int
get_vfatname(fsdata *mydata, int curclust, __u8 *cluster,
dir_entry *retdent, char *l_name)
{
dir_entry *realdent;
dir_slot *slotptr = (dir_slot*) retdent;
__u8 *nextclust = cluster + mydata->clust_size * SECTOR_SIZE;
__u8 counter = (slotptr->id & ~LAST_LONG_ENTRY_MASK) & 0xff;
int idx = 0;
while ((__u8*)slotptr < nextclust)
{
if (counter == 0) break;
if (((slotptr->id & ~LAST_LONG_ENTRY_MASK) & 0xff) != counter)
return -1;
slotptr++;
counter--;
}
if ((__u8*)slotptr >= nextclust)
{
dir_slot *slotptr2;
slotptr--;
curclust = get_fatent(mydata, curclust);
if (curclust <= 0x0001 || curclust >= 0xfff0)
{
FAT_DPRINT("curclust: 0x%x\n", curclust);
FAT_ERROR("Invalid FAT entry\n");
return -1;
}
if (get_cluster(mydata, curclust, get_vfatname_block,
mydata->clust_size * SECTOR_SIZE) != 0)
{
FAT_DPRINT("Error: reading directory block\n");
return -1;
}
slotptr2 = (dir_slot*) get_vfatname_block;
while (slotptr2->id > 0x01)
{
slotptr2++;
}
/* Save the real directory entry */
realdent = (dir_entry*)slotptr2 + 1;
while ((__u8*)slotptr2 >= get_vfatname_block)
{
slot2str(slotptr2, l_name, &idx);
slotptr2--;
}
}
else
{
/* Save the real directory entry */
realdent = (dir_entry*)slotptr;
}
do
{
slotptr--;
if (slot2str(slotptr, l_name, &idx)) break;
}
while (!(slotptr->id & LAST_LONG_ENTRY_MASK));
l_name[idx] = '\0';
if (*l_name == DELETED_FLAG) *l_name = '\0';
else if (*l_name == aRING) *l_name = '?';
downcase(l_name);
/* Return the real directory entry */
memcpy(retdent, realdent, sizeof(dir_entry));
return 0;
}
/* Calculate short name checksum */
static __u8
mkcksum(const char *str)
{
int i;
__u8 ret = 0;
for (i = 0; i < 11; i++)
{
ret = (((ret&1)<<7)|((ret&0xfe)>>1)) + str[i];
}
return ret;
}
#endif
/*
* Get the directory entry associated with 'filename' from the directory
* starting at 'startsect'
*/
__u8 get_dentfromdir_block[MAX_CLUSTSIZE];
static dir_entry *get_dentfromdir (fsdata * mydata, int startsect,
char *filename, dir_entry * retdent,
int dols)
{
__u16 prevcksum = 0xffff;
__u32 curclust = START (retdent);
int files = 0, dirs = 0;
FAT_DPRINT ("get_dentfromdir: %s\n", filename);
while (1)
{
dir_entry *dentptr;
int i;
if (get_cluster (mydata, curclust, get_dentfromdir_block,
mydata->clust_size * SECTOR_SIZE) != 0)
{
FAT_DPRINT ("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];
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) &&
(dentptr->name[0] & LAST_LONG_ENTRY_MASK))
{
prevcksum = ((dir_slot *) dentptr)
->alias_checksum;
get_vfatname (mydata, curclust, get_dentfromdir_block,
dentptr, l_name);
if (dols)
{
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 ("vfatname: |%s|\n", l_name);
}
else
#endif
{
/* Volume label or VFAT entry */
dentptr++;
continue;
}
}
if (dentptr->name[0] == 0)
{
if (dols)
{
FAT_DPRINT("\n%d file(s), %d dir(s)\n\n", files, dirs);
}
FAT_DPRINT ("Dentname == NULL - %d\n", i);
return NULL;
}
#ifdef CONFIG_SUPPORT_VFAT
if (dols && mkcksum (dentptr->name) == prevcksum)
{
dentptr++;
continue;
}
#endif
get_name (dentptr, s_name);
if (dols)
{
int isdir = (dentptr->attr & ATTR_DIR);
char dirc;
int doit = 0;
if (isdir)
{
dirs++;
dirc = '/';
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 (filename, s_name) && strcmp (filename, l_name))
{
FAT_DPRINT ("Mismatch: |%s|%s|\n", s_name, l_name);
dentptr++;
continue;
}
memcpy (retdent, dentptr, sizeof (dir_entry));
FAT_DPRINT ("DentName: %s", s_name);
FAT_DPRINT (", start: 0x%x", START (dentptr));
FAT_DPRINT (", size: 0x%x %s\n",
FAT2CPU32 (dentptr->size),
(dentptr->attr & ATTR_DIR) ? "(DIR)" : "");
return retdent;
}
curclust = get_fatent (mydata, curclust);
if (curclust <= 0x0001 || curclust >= 0xfff0)
{
FAT_DPRINT ("curclust: 0x%x\n", curclust);
FAT_ERROR ("Invalid FAT entry\n");
return NULL;
}
}
return NULL;
}
/*
* Read boot sector and volume info from a FAT filesystem
*/
static int
read_bootsectandvi(boot_sector *bs, volume_info *volinfo, int *fatsize)
{
__u8 block[FS_BLOCK_SIZE];
volume_info *vistart;
int i,j;
if (disk_read(0, 1, block) < 0)
{
FAT_DPRINT("Error: reading block\n");
return -1;
}
memcpy(bs, block, sizeof(boot_sector));
for(i=0;i<FS_BLOCK_SIZE;i++)
{
if(i%0x10==0)
{
FAT_DPRINT("[%03x]: ",i);
//FAT_DPRINT("[%03x]:%02x ", i,buffer[i]);
}
FAT_DPRINT("%02x ",block[i]);
if((i+1)%0x10==0&&(i-0xf)>=0)
{
FAT_DPRINT(": ");
for(j=i-0xf;j<=i;j++)
{
if(block[j]=='\n')
FAT_DPRINT(" ");
else
FAT_DPRINT("%c ",block[j]);
}
FAT_DPRINT("\n");
}
}
/* Bootstrap code */
FAT_DPRINT("\nignored[3]:");
for(i=0;i<3;i++)
FAT_DPRINT("%02x ",bs->ignored[i]);
/* Name of fs */
FAT_DPRINT("\nsystem_id[8]:");
for(i=0;i<8;i++)
FAT_DPRINT("%02x ",bs->system_id[i]);
//__u8 sector_size[2]; /* Bytes/sector */
FAT_DPRINT("\nsector_size[2]:");
for(i=0;i<2;i++)
FAT_DPRINT("%02x ",bs->sector_size[i]);
//__u8 cluster_size; /* Sectors/cluster */
FAT_DPRINT("\ncluster_size:");
for(i=0;i<1;i++)
FAT_DPRINT("%02x ",bs->cluster_size);
//__u16 reserved; /* Number of reserved sectors */
FAT_DPRINT("\nreserved:");
for(i=0;i<1;i++)
FAT_DPRINT("%0x ",bs->reserved);
//__u8 fats; /* Number of FATs */
FAT_DPRINT("\nfats:");
for(i=0;i<1;i++)
FAT_DPRINT("%0x ",bs->fats);
//__u8 dir_entries[2]; /* Number of root directory entries */
FAT_DPRINT("\ndir_entries[2]:");
for(i=0;i<2;i++)
FAT_DPRINT("%0x ",bs->dir_entries[i]);
//__u8 sectors[2]; /* Number of sectors */
FAT_DPRINT("\nsectors[2]:");
for(i=0;i<2;i++)
FAT_DPRINT("%0x ",bs->sectors[i]);
// __u8 media; /* Media code */
FAT_DPRINT("\nmedia:");
for(i=0;i<1;i++)
FAT_DPRINT("%0x ",bs->media);
//__u16 fat_length; /* Sectors/FAT */
FAT_DPRINT("\nfat_length:");
for(i=0;i<1;i++)
FAT_DPRINT("%0x ",bs->fat_length);
//__u16 secs_track; /* Sectors/track */
FAT_DPRINT("\nsecs_track:");
for(i=0;i<1;i++)
FAT_DPRINT("%0x ",bs->secs_track);
//__u16 heads; /* Number of heads */
FAT_DPRINT("\nheads:");
for(i=0;i<1;i++)
FAT_DPRINT("%0x ",bs->heads);
//__u32 hidden; /* Number of hidden sectors */
FAT_DPRINT("\nhidden:");
for(i=0;i<1;i++)
FAT_DPRINT("%0x ",bs->hidden);
//__u32 total_sect; /* Number of sectors (if sectors == 0) */
FAT_DPRINT("\ntotal_sect:");
for(i=0;i<1;i++)
FAT_DPRINT("%0x ",bs->total_sect);
/* FAT32 only */
//__u32 fat32_length; /* Sectors/FAT */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -