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

📄 fat.c

📁 编译后直接运行的MP3播放器全部C语言源代码 一个包含FAT文件系统、系统引导 Boot、FLASH Driver等内容的
💻 C
📖 第 1 页 / 共 5 页
字号:
    LDEBUGF("next_write_cluster(%x,%x)\n",file->firstcluster, oldcluster);    if (oldcluster)        cluster = get_next_cluster(oldcluster);    if (!cluster) {        if (oldcluster)            cluster = find_free_cluster(oldcluster+1);        else            cluster = find_free_cluster(fat_bpb.fsinfo.nextfree);        if (cluster) {            if (oldcluster)                update_fat_entry(oldcluster, cluster);             else                file->firstcluster = cluster;            update_fat_entry(cluster, FAT_EOF_MARK);        }        else {#ifdef TEST_FAT            if (fat_bpb.fsinfo.freecount>0)                panicf("There is free space, but find_free_cluster() "                       "didn't find it!\n");#endif            DEBUGF("next_write_cluster(): Disk full!\n");            return 0;        }    }    sector = cluster2sec(cluster);    if (sector<0)        return 0;    *newsector = sector;    return cluster;}static int transfer( unsigned int start, int count, char* buf, bool write ){    int rc;    LDEBUGF("transfer(s=%x, c=%x, %s)\n",start, count, write?"write":"read");    if (write) {        if (start < fat_bpb.firstdatasector)            panicf("Writing before data\n");        rc = ata_write_sectors(start, count, buf);    }    else        rc = ata_read_sectors(start, count, buf);    if (rc < 0) {        DEBUGF( "transfer() - Couldn't %s sector %x"                " (error code %d)\n",                 write ? "write":"read", start, rc);        return rc;    }    return 0;}int fat_readwrite( struct fat_file *file, int sectorcount,                    void* buf, bool write ){    int cluster = file->lastcluster;    int sector = file->lastsector;    int clusternum = file->clusternum;    int numsec = file->sectornum;    bool eof = file->eof;    int first=0, last=0;    int i;    int rc;    LDEBUGF( "fat_readwrite(file:%x,count:0x%x,buf:%x,%s)\n",             file->firstcluster,sectorcount,buf,write?"write":"read");    LDEBUGF( "fat_readwrite: sec=%x numsec=%d eof=%d\n",             sector,numsec, eof?1:0);    if ( eof && !write)        return 0;    /* find sequential sectors and write them all at once */    for (i=0; (i < sectorcount) && (sector > -1); i++ ) {        numsec++;        if ( numsec > (int)fat_bpb.bpb_secperclus || !cluster ) {            int oldcluster = cluster;            if (write)                cluster = next_write_cluster(file, cluster, &sector);            else {                cluster = get_next_cluster(cluster);                sector = cluster2sec(cluster);            }            clusternum++;            numsec=1;            if (!cluster) {                eof = true;                if ( write ) {                    /* remember last cluster, in case                        we want to append to the file */                    cluster = oldcluster;                    clusternum--;                    i = -1; /* Error code */                    break;                }            }            else                eof = false;        }        else {            if (sector)                sector++;            else {                /* look up first sector of file */                sector = cluster2sec(file->firstcluster);                numsec=1;            }        }        if (!first)            first = sector;        if ( ((sector != first) && (sector != last+1)) || /* not sequential */             (last-first+1 == 256) ) { /* max 256 sectors per ata request */            int count = last - first + 1;            rc = transfer( first + fat_bpb.startsector, count, buf, write );            if (rc < 0)                return rc * 10 - 1;            ((char*)buf) += count * SECTOR_SIZE;            first = sector;        }        if ((i == sectorcount-1) && /* last sector requested */            (!eof))        {            int count = sector - first + 1;            rc = transfer( first + fat_bpb.startsector, count, buf, write );            if (rc < 0)                return rc * 10 - 2;        }        last = sector;    }    file->lastcluster = cluster;    file->lastsector = sector;    file->clusternum = clusternum;    file->sectornum = numsec;    file->eof = eof;    /* if eof, don't report last block as read/written */    if (eof)        i--;    DEBUGF("Sectors written: %d\n", i);    return i;}int fat_seek(struct fat_file *file, unsigned int seeksector ){    int clusternum=0, numclusters=0, sectornum=0, sector=0;    int cluster = file->firstcluster;    int i;    file->eof = false;    if (seeksector) {        /* we need to find the sector BEFORE the requested, since           the file struct stores the last accessed sector */        seeksector--;        numclusters = clusternum = seeksector / fat_bpb.bpb_secperclus;        sectornum = seeksector % fat_bpb.bpb_secperclus;        if (file->clusternum && clusternum >= file->clusternum)        {            cluster = file->lastcluster;            numclusters -= file->clusternum;        }        for (i=0; i<numclusters; i++) {            cluster = get_next_cluster(cluster);            if (!cluster) {                DEBUGF("Seeking beyond the end of the file! "                       "(sector %d, cluster %d)\n", seeksector, i);                return -1;            }        }                sector = cluster2sec(cluster) + sectornum;    }    else {        sectornum = -1;    }    LDEBUGF("fat_seek(%x, %x) == %x, %x, %x\n",            file->firstcluster, seeksector, cluster, sector, sectornum);    file->lastcluster = cluster;    file->lastsector = sector;    file->clusternum = clusternum;    file->sectornum = sectornum + 1;    return 0;}int fat_opendir(struct fat_dir *dir, unsigned int startcluster){    int rc;    if (startcluster == 0)        startcluster = sec2cluster(fat_bpb.rootdirsector);    rc = fat_open(startcluster, &dir->file, NULL);    if(rc)    {        DEBUGF( "fat_opendir() - Couldn't open dir"                " (error code %d)\n", rc);        return rc * 10 - 1;    }    dir->entry = 0;    dir->sector = 0;    return 0;}/* convert from unicode to a single-byte charset */static void unicode2iso(unsigned char* unicode, unsigned char* iso, int count ){    int i;    for (i=0; i<count; i++) {        int x = i*2;        switch (unicode[x+1]) {            case 0x01: /* latin extended. convert to ISO 8859-2 */            case 0x02:                iso[i] = unicode2iso8859_2[unicode[x]];                break;            case 0x03: /* greek, convert to ISO 8859-7 */                iso[i] = unicode[x] + 0x30;                break;                /* Sergei says most russians use Win1251, so we will too.                   Win1251 differs from ISO 8859-5 by an offset of 0x10. */            case 0x04: /* cyrillic, convert to Win1251 */                switch (unicode[x]) {                    case 1:                        iso[i] = 168;                        break;                    case 81:                        iso[i] = 184;                        break;                    default:                        iso[i] = unicode[x] + 0xb0; /* 0xa0 for ISO 8859-5 */                        break;                }                break;            case 0x05: /* hebrew, convert to ISO 8859-8 */                iso[i] = unicode[x] + 0x10;                break;            case 0x06: /* arabic, convert to ISO 8859-6 */            case 0x0e: /* thai, convert to ISO 8859-11 */                iso[i] = unicode[x] + 0xa0;                break;            default:                iso[i] = unicode[x];                break;        }    }}int fat_getnext(struct fat_dir *dir, struct fat_direntry *entry){    bool done = false;    int i;    int rc;    unsigned char firstbyte;    int longarray[20];    int longs=0;    int sectoridx=0;    unsigned char* cached_buf = dir->sectorcache[0];    dir->entrycount = 0;    while(!done)    {        if ( !(dir->entry % DIR_ENTRIES_PER_SECTOR) || !dir->sector )        {            rc = fat_readwrite(&dir->file, 1, cached_buf, false);            if (rc == 0) {                /* eof */                entry->name[0] = 0;                break;            }            if (rc < 0) {                DEBUGF( "fat_getnext() - Couldn't read dir"                        " (error code %d)\n", rc);                return rc * 10 - 1;            }            dir->sector = dir->file.lastsector;        }        for (i = dir->entry % DIR_ENTRIES_PER_SECTOR;             i < DIR_ENTRIES_PER_SECTOR; i++)        {            unsigned int entrypos = i * DIR_ENTRY_SIZE;            firstbyte = cached_buf[entrypos];            dir->entry++;            if (firstbyte == 0xe5) {                /* free entry */                sectoridx = 0;                dir->entrycount = 0;                continue;            }            if (firstbyte == 0) {                /* last entry */                entry->name[0] = 0;                dir->entrycount = 0;                return 0;            }            dir->entrycount++;            /* longname entry? */            if ( ( cached_buf[entrypos + FATDIR_ATTR] &                   FAT_ATTR_LONG_NAME_MASK ) == FAT_ATTR_LONG_NAME ) {                longarray[longs++] = entrypos + sectoridx;            }            else {                if ( parse_direntry(entry,                                    &cached_buf[entrypos]) ) {                    /* don't return volume id entry */                    if ( entry->attr == FAT_ATTR_VOLUME_ID )                        continue;                    /* replace shortname with longname? */                    if ( longs ) {                        int j,l=0;                        /* iterate backwards through the dir entries */                        for (j=longs-1; j>=0; j--) {                            unsigned char* ptr = cached_buf;                            int index = longarray[j];                            /* current or cached sector? */                            if ( sectoridx >= SECTOR_SIZE ) {                                if ( sectoridx >= SECTOR_SIZE*2 ) {                                    if ( ( index >= SECTOR_SIZE ) &&                                         ( index < SECTOR_SIZE*2 ))                                        ptr = dir->sectorcache[1];                                    else                                        ptr = dir->sectorcache[2];                                }                                else {                                    if ( index < SECTOR_SIZE )                                        ptr = dir->sectorcache[1];                                }                                index &= SECTOR_SIZE-1;                            }                            /* names are stored in unicode, but we                               only grab the low byte (iso8859-1). */                            unicode2iso(ptr + index + 1, entry->name + l, 5);                            l+= 5;                            unicode2iso(ptr + index + 14, entry->name + l, 6);                            l+= 6;                            unicode2iso(ptr + index + 28, entry->name + l, 2);                            l+= 2;                        }                        entry->name[l]=0;                    }                    done = true;                    sectoridx = 0;                    i++;                    break;                }            }        }        /* save this sector, for longname use */        if ( sectoridx )            memcpy( dir->sectorcache[2], dir->sectorcache[0], SECTOR_SIZE );        else            memcpy( dir->sectorcache[1], dir->sectorcache[0], SECTOR_SIZE );        sectoridx += SECTOR_SIZE;    }    return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -