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

📄 fat.c

📁 编译后直接运行的MP3播放器全部C语言源代码 一个包含FAT文件系统、系统引导 Boot、FLASH Driver等内容的
💻 C
📖 第 1 页 / 共 5 页
字号:
    return 0;}static int update_short_entry( struct fat_file* file, int size, int attr ){    unsigned char buf[SECTOR_SIZE];    int sector = file->direntry / DIR_ENTRIES_PER_SECTOR;    unsigned char* entry =        buf + DIR_ENTRY_SIZE * (file->direntry % DIR_ENTRIES_PER_SECTOR);    unsigned int* sizeptr;    unsigned short* clusptr;    struct fat_file dir;    int rc;    LDEBUGF("update_file_size(cluster:%x entry:%d size:%d)\n",            file->firstcluster, file->direntry, size);    /* create a temporary file handle for the dir holding this file */    rc = fat_open(file->dircluster, &dir, NULL);    if (rc < 0)        return rc * 10 - 1;    rc = fat_seek( &dir, sector );    if (rc<0)        return rc * 10 - 2;    rc = fat_readwrite(&dir, 1, buf, false);    if (rc < 1)        return rc * 10 - 3;    if (!entry[0] || entry[0] == 0xe5)        panicf("Updating size on empty dir entry %d\n", file->direntry);            entry[FATDIR_ATTR] = attr & 0xFF;    clusptr = (short*)(entry + FATDIR_FSTCLUSHI);    *clusptr = SWAB16(file->firstcluster >> 16);        clusptr = (short*)(entry + FATDIR_FSTCLUSLO);    *clusptr = SWAB16(file->firstcluster & 0xffff);    sizeptr = (int*)(entry + FATDIR_FILESIZE);    *sizeptr = SWAB32(size);    {#ifdef HAVE_RTC        unsigned short time = 0;        unsigned short date = 0;#else        /* get old time to increment from */        unsigned short time = SWAB16(*(unsigned short*)(entry + FATDIR_WRTTIME));        unsigned short date = SWAB16(*(unsigned short*)(entry + FATDIR_WRTDATE));#endif        fat_time(&date, &time, NULL);        *(unsigned short*)(entry + FATDIR_WRTTIME) = SWAB16(time);        *(unsigned short*)(entry + FATDIR_WRTDATE) = SWAB16(date);        *(unsigned short*)(entry + FATDIR_LSTACCDATE) = SWAB16(date);    }    rc = fat_seek( &dir, sector );    if (rc < 0)        return rc * 10 - 4;    rc = fat_readwrite(&dir, 1, buf, true);    if (rc < 1)        return rc * 10 - 5;    return 0;}static int parse_direntry(struct fat_direntry *de, unsigned char *buf){    int i=0,j=0;    memset(de, 0, sizeof(struct fat_direntry));    de->attr = buf[FATDIR_ATTR];    de->crttimetenth = buf[FATDIR_CRTTIMETENTH];    de->crtdate = BYTES2INT16(buf,FATDIR_CRTDATE);    de->crttime = BYTES2INT16(buf,FATDIR_CRTTIME);    de->wrtdate = BYTES2INT16(buf,FATDIR_WRTDATE);    de->wrttime = BYTES2INT16(buf,FATDIR_WRTTIME);    de->filesize = BYTES2INT32(buf,FATDIR_FILESIZE);    de->firstcluster = BYTES2INT16(buf,FATDIR_FSTCLUSLO) |                      (BYTES2INT16(buf,FATDIR_FSTCLUSHI) << 16);    /* fix the name */    for (i=0; (i<8) && (buf[FATDIR_NAME+i] != ' '); i++)        de->name[j++] = buf[FATDIR_NAME+i];    if ( buf[FATDIR_NAME+8] != ' ' ) {        de->name[j++] = '.';        for (i=8; (i<11) && (buf[FATDIR_NAME+i] != ' '); i++)            de->name[j++] = buf[FATDIR_NAME+i];    }    return 1;}int fat_open(unsigned int startcluster,             struct fat_file *file,             struct fat_dir* dir){    file->firstcluster = startcluster;    file->lastcluster = startcluster;    file->lastsector = 0;    file->clusternum = 0;    file->sectornum = 0;    file->eof = false;    /* remember where the file's dir entry is located */    if ( dir ) {        file->direntry = dir->entry - 1;        file->direntries = dir->entrycount;        file->dircluster = dir->file.firstcluster;    }    LDEBUGF("fat_open(%x), entry %d\n",startcluster,file->direntry);    return 0;}int fat_create_file(char* name,                    struct fat_file* file,                    struct fat_dir* dir){    int rc;    LDEBUGF("fat_create_file(\"%s\",%x,%x)\n",name,file,dir);    rc = add_dir_entry(dir, file, name, false, false);    if (!rc) {        file->firstcluster = 0;        file->lastcluster = 0;        file->lastsector = 0;        file->clusternum = 0;        file->sectornum = 0;        file->eof = false;    }    return rc;}int fat_create_dir(char* name,                   struct fat_dir* newdir,                   struct fat_dir* dir){    unsigned char buf[SECTOR_SIZE];    int i;    int sector;    int rc;    struct fat_file dummyfile;    LDEBUGF("fat_create_dir(\"%s\",%x,%x)\n",name,newdir,dir);    memset(newdir, 0, sizeof(struct fat_dir));    memset(&dummyfile, 0, sizeof(struct fat_file));    /* First, add the entry in the parent directory */    rc = add_dir_entry(dir, &newdir->file, name, true, false);    if (rc < 0)        return rc * 10 - 1;    /* Allocate a new cluster for the directory */    newdir->file.firstcluster = find_free_cluster(fat_bpb.fsinfo.nextfree);    if(newdir->file.firstcluster == 0)        return -1;    update_fat_entry(newdir->file.firstcluster, FAT_EOF_MARK);    /* Clear the entire cluster */    memset(buf, 0, sizeof buf);    sector = cluster2sec(newdir->file.firstcluster);    for(i = 0;i < (int)fat_bpb.bpb_secperclus;i++) {        rc = transfer( sector + fat_bpb.startsector + i, 1, buf, true );        if (rc < 0)            return rc * 10 - 2;    }        /* Then add the "." entry */    rc = add_dir_entry(newdir, &dummyfile, ".", true, true);    if (rc < 0)        return rc * 10 - 3;    dummyfile.firstcluster = newdir->file.firstcluster;    update_short_entry(&dummyfile, 0, FAT_ATTR_DIRECTORY);    /* and the ".." entry */    rc = add_dir_entry(newdir, &dummyfile, "..", true, true);    if (rc < 0)        return rc * 10 - 4;    /* The root cluster is cluster 0 in the ".." entry */    if(dir->file.firstcluster == fat_bpb.bpb_rootclus)        dummyfile.firstcluster = 0;    else        dummyfile.firstcluster = dir->file.firstcluster;    update_short_entry(&dummyfile, 0, FAT_ATTR_DIRECTORY);        /* Set the firstcluster field in the direntry */    update_short_entry(&newdir->file, 0, FAT_ATTR_DIRECTORY);        rc = flush_fat();    if (rc < 0)        return rc * 10 - 5;    return rc;}int fat_truncate(struct fat_file *file){    /* truncate trailing clusters */    int next;    int last = file->lastcluster;    LDEBUGF("fat_truncate(%x, %x)\n", file->firstcluster, last);    for ( last = get_next_cluster(last); last; last = next ) {        next = get_next_cluster(last);        update_fat_entry(last,0);    }    if (file->lastcluster)        update_fat_entry(file->lastcluster,FAT_EOF_MARK);    return 0;}int fat_closewrite(struct fat_file *file, int size, int attr){    int rc;    LDEBUGF("fat_closewrite(size=%d)\n",size);    if (!size) {        /* empty file */        if ( file->firstcluster ) {            update_fat_entry(file->firstcluster, 0);            file->firstcluster = 0;        }    }    if (file->dircluster) {        rc = update_short_entry(file, size, attr);        if (rc < 0)            return rc * 10 - 1;    }    flush_fat();#ifdef TEST_FAT    if ( file->firstcluster ) {        /* debug */        int count = 0;        int len;        int next;        for ( next = file->firstcluster; next;              next = get_next_cluster(next) )            LDEBUGF("cluster %d: %x\n", count++, next);        len = count * fat_bpb.bpb_secperclus * SECTOR_SIZE;        LDEBUGF("File is %d clusters (chainlen=%d, size=%d)\n",                count, len, size );        if ( len > size + fat_bpb.bpb_secperclus * SECTOR_SIZE)            panicf("Cluster chain is too long\n");        if ( len < size )            panicf("Cluster chain is too short\n");    }#endif    return 0;}static int free_direntries(int dircluster, int startentry, int numentries){    unsigned char buf[SECTOR_SIZE];    struct fat_file dir;    unsigned int entry = startentry - numentries + 1;    unsigned int sector = entry / DIR_ENTRIES_PER_SECTOR;    int i;    int rc;    /* create a temporary file handle for the dir holding this file */    rc = fat_open(dircluster, &dir, NULL);    if (rc < 0)        return rc * 10 - 1;    rc = fat_seek( &dir, sector );    if (rc < 0)        return rc * 10 - 2;    rc = fat_readwrite(&dir, 1, buf, false);    if (rc < 1)        return rc * 10 - 3;    for (i=0; i < numentries; i++) {        LDEBUGF("Clearing dir entry %d (%d/%d)\n",                entry, i+1, numentries);        buf[(entry % DIR_ENTRIES_PER_SECTOR) * DIR_ENTRY_SIZE] = 0xe5;        entry++;        if ( (entry % DIR_ENTRIES_PER_SECTOR) == 0 ) {            /* flush this sector */            rc = fat_seek(&dir, sector);            if (rc < 0)                return rc * 10 - 4;            rc = fat_readwrite(&dir, 1, buf, true);            if (rc < 1)                return rc * 10 - 5;            if ( i+1 < numentries ) {                /* read next sector */                rc = fat_readwrite(&dir, 1, buf, false);                if (rc < 1)                    return rc * 10 - 6;            }            sector++;        }    }    if ( entry % DIR_ENTRIES_PER_SECTOR ) {        /* flush this sector */        rc = fat_seek(&dir, sector);        if (rc < 0)            return rc * 10 - 7;                    rc = fat_readwrite(&dir, 1, buf, true);        if (rc < 1)            return rc * 10 - 8;    }    return 0;}int fat_remove(struct fat_file* file){    int next, last = file->firstcluster;    int rc;    LDEBUGF("fat_remove(%x)\n",last);    while ( last ) {        next = get_next_cluster(last);        update_fat_entry(last,0);        last = next;    }    if ( file->dircluster ) {        rc = free_direntries(file->dircluster,                              file->direntry,                              file->direntries);        if (rc < 0)            return rc * 10 - 1;    }    file->firstcluster = 0;    file->dircluster = 0;    return 0;}int fat_rename(struct fat_file* file,                unsigned char* newname,               int size,               int attr){    int rc;    struct fat_dir dir;    struct fat_file newfile = *file;    if ( !file->dircluster ) {        DEBUGF("File has no dir cluster!\n");        return -1;    }    /* create a temporary file handle */    rc = fat_opendir(&dir, file->dircluster);    if (rc < 0)        return rc * 10 - 2;    /* create new name */    rc = add_dir_entry(&dir, &newfile, newname, false, false);    if (rc < 0)        return rc * 10 - 3;    /* write size and cluster link */    rc = update_short_entry(&newfile, size, attr);    if (rc < 0)        return rc * 10 - 4;    /* remove old name */    rc = free_direntries(file->dircluster, file->direntry, file->direntries);    if (rc < 0)        return rc * 10 - 5;    rc = flush_fat();    if (rc < 0)        return rc * 10 - 6;    return 0;}static int next_write_cluster(struct fat_file* file,                              int oldcluster,                              int* newsector){    int cluster = 0;    int sector;

⌨️ 快捷键说明

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