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

📄 fat.c

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