⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fat.c

📁 基于s3c2440的U盘读写程序
💻 C
📖 第 1 页 / 共 3 页
字号:
            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 + -