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

📄 fat.c

📁 编译后直接运行的MP3播放器全部C语言源代码 一个包含FAT文件系统、系统引导 Boot、FLASH Driver等内容的
💻 C
📖 第 1 页 / 共 5 页
字号:
                        year++;                    }                }                *date = (year << 9) | (month << 5) | day;            }        }    }    if (tenth)        *tenth = 0;#endif /* HAVE_RTC */}static int write_long_name(struct fat_file* file,                           unsigned int firstentry,                           unsigned int numentries,                           unsigned char* name,                           unsigned char* shortname,                           bool is_directory){    unsigned char buf[SECTOR_SIZE];    unsigned char* entry;    unsigned int idx = firstentry % DIR_ENTRIES_PER_SECTOR;    unsigned int sector = firstentry / DIR_ENTRIES_PER_SECTOR;    unsigned int i, j=0;    unsigned char chksum = 0;    int nameidx=0, namelen = strlen(name);    int rc;    LDEBUGF("write_long_name(file:%x, first:%d, num:%d, name:%s)\n",            file->firstcluster, firstentry, numentries, name);    rc = fat_seek(file, sector);    if (rc<0)        return rc * 10 - 1;    rc = fat_readwrite(file, 1, buf, false);    if (rc<1)        return rc * 10 - 2;    /* calculate shortname checksum */    for (i=11; i>0; i--)        chksum = ((chksum & 1) ? 0x80 : 0) + (chksum >> 1) + shortname[j++];    /* calc position of last name segment */    if ( namelen > NAME_BYTES_PER_ENTRY )        for (nameidx=0;             nameidx < (namelen - NAME_BYTES_PER_ENTRY);             nameidx += NAME_BYTES_PER_ENTRY);    for (i=0; i < numentries; i++) {        /* new sector? */        if ( idx >= DIR_ENTRIES_PER_SECTOR ) {            /* update current sector */            rc = fat_seek(file, sector);            if (rc<0)                return rc * 10 - 3;            rc = fat_readwrite(file, 1, buf, true);            if (rc<1)                return rc * 10 - 4;            /* read next sector */            rc = fat_readwrite(file, 1, buf, false);            if (rc<0) {                LDEBUGF("Failed writing new sector: %d\n",rc);                return rc * 10 - 5;            }            if (rc==0)                /* end of dir */                memset(buf, 0, sizeof buf);            sector++;            idx = 0;        }        entry = buf + idx * DIR_ENTRY_SIZE;        /* verify this entry is free */        if (entry[0] && entry[0] != 0xe5 )            panicf("Dir entry %d in sector %x is not free! "                   "%02x %02x %02x %02x",                   idx, sector,                   entry[0], entry[1], entry[2], entry[3]);        memset(entry, 0, DIR_ENTRY_SIZE);        if ( i+1 < numentries ) {            /* longname entry */            int k, l = nameidx;            entry[FATLONG_ORDER] = numentries-i-1;            if (i==0) {                /* mark this as last long entry */                entry[FATLONG_ORDER] |= 0x40;                /* pad name with 0xffff  */                for (k=1; k<12; k++) entry[k] = 0xff;                for (k=14; k<26; k++) entry[k] = 0xff;                for (k=28; k<32; k++) entry[k] = 0xff;            };            /* set name */            for (k=0; k<5 && l <= namelen; k++) {                entry[k*2 + 1] = name[l++];                entry[k*2 + 2] = 0;            }            for (k=0; k<6 && l <= namelen; k++) {                entry[k*2 + 14] = name[l++];                entry[k*2 + 15] = 0;            }            for (k=0; k<2 && l <= namelen; k++) {                entry[k*2 + 28] = name[l++];                entry[k*2 + 29] = 0;            }            entry[FATDIR_ATTR] = FAT_ATTR_LONG_NAME;            entry[FATDIR_FSTCLUSLO] = 0;            entry[FATLONG_TYPE] = 0;            entry[FATLONG_CHKSUM] = chksum;            LDEBUGF("Longname entry %d: %.13s\n", idx, name+nameidx);        }        else {            /* shortname entry */            unsigned short date=0, time=0, tenth=0;            LDEBUGF("Shortname entry: %.13s\n", shortname);            strncpy(entry + FATDIR_NAME, shortname, 11);            entry[FATDIR_ATTR] = is_directory?FAT_ATTR_DIRECTORY:0;            entry[FATDIR_NTRES] = 0;            fat_time(&date, &time, &tenth);            entry[FATDIR_CRTTIMETENTH] = tenth;            *(unsigned short*)(entry + FATDIR_CRTTIME) = SWAB16(time);            *(unsigned short*)(entry + FATDIR_WRTTIME) = SWAB16(time);            *(unsigned short*)(entry + FATDIR_CRTDATE) = SWAB16(date);            *(unsigned short*)(entry + FATDIR_WRTDATE) = SWAB16(date);            *(unsigned short*)(entry + FATDIR_LSTACCDATE) = SWAB16(date);        }        idx++;        nameidx -= NAME_BYTES_PER_ENTRY;    }    /* update last sector */    rc = fat_seek(file, sector);    if (rc<0)        return rc * 10 - 6;    rc = fat_readwrite(file, 1, buf, true);    if (rc<1)        return rc * 10 - 7;        return 0;}static int add_dir_entry(struct fat_dir* dir,                         struct fat_file* file,                         char* name,                         bool is_directory,                         bool dotdir){    unsigned char buf[SECTOR_SIZE];    unsigned char shortname[16];    int rc;    unsigned int sector;    bool done = false;    bool eof = false;    bool last = false;    int entries_needed, entries_found = 0;    int namelen = strlen(name);    int firstentry;    LDEBUGF( "add_dir_entry(%s,%x)\n",             name, file->firstcluster);    /* The "." and ".." directory entries must not be long names */    if(dotdir) {        int i;        strncpy(shortname, name, 16);        for(i = strlen(shortname);i < 12;i++)            shortname[i] = ' ';                entries_needed = 1;    } else {        /* create dos name */        rc = create_dos_name(name, shortname);        if (rc < 0)            return rc * 10 - 0;        /* one dir entry needed for every 13 bytes of filename,           plus one entry for the short name */        entries_needed = namelen / NAME_BYTES_PER_ENTRY + 1;        if (namelen % NAME_BYTES_PER_ENTRY)            entries_needed++;    } restart:    firstentry = 0;    rc = fat_seek(&dir->file, 0);    if (rc < 0)        return rc * 10 - 1;    for (sector=0; !done; sector++)    {        unsigned int i;        rc = 0;        if (!eof) {            rc = fat_readwrite(&dir->file, 1, buf, false);        }        if (rc == 0) {            /* eof: add new sector */            eof = true;            memset(buf, 0, sizeof buf);            LDEBUGF("Adding new sector to dir\n");            rc = fat_seek(&dir->file, sector);            if (rc < 0)                return rc * 10 - 2;            /* add sectors (we must clear the whole cluster) */            do {                rc = fat_readwrite(&dir->file, 1, buf, true);                if (rc < 1)                    return rc * 10 - 3;            } while (dir->file.sectornum < (int)fat_bpb.bpb_secperclus);        }        if (rc < 0) {            DEBUGF( "add_dir_entry() - Couldn't read dir"                    " (error code %d)\n", rc);            return rc * 10 - 4;        }        /* look for free slots */        for (i=0; i < DIR_ENTRIES_PER_SECTOR && !done; i++)        {            unsigned char firstbyte = buf[i * DIR_ENTRY_SIZE];            switch (firstbyte) {            case 0: /* end of dir */                entries_found = entries_needed;                LDEBUGF("Found last entry %d\n",                         sector * DIR_ENTRIES_PER_SECTOR + i);                done = true;                break;            case 0xe5: /* free entry */                entries_found++;                LDEBUGF("Found free entry %d (%d/%d)\n",                        sector * DIR_ENTRIES_PER_SECTOR + i,                        entries_found, entries_needed);                break;            default:                entries_found = 0;                /* check that our intended shortname doesn't already exist */                if (!strncmp(shortname, buf + i * DIR_ENTRY_SIZE, 12)) {                    /* filename exists already. make a new one */                    snprintf(shortname+8, 4, "%03X", (unsigned)rand() & 0xfff);                    LDEBUGF("Duplicate shortname, changing to %s\n",                            shortname);                    /* name has changed, we need to restart search */                    goto restart;                }                break;            }            if (!firstentry && (entries_found == entries_needed)) {                firstentry = sector * DIR_ENTRIES_PER_SECTOR + i;                /* if we're not extending the dir,                   we must go back to first free entry */                if (done)                    last = true;                else                    firstentry -= (entries_needed - 1);            }        }    }    sector = firstentry / DIR_ENTRIES_PER_SECTOR;    LDEBUGF("Adding longname to entry %d in sector %d\n",            firstentry, sector);    rc = write_long_name(&dir->file, firstentry,                          entries_needed, name, shortname, is_directory);    if (rc < 0)        return rc * 10 - 5;    /* remember where the shortname dir entry is located */    file->direntry = firstentry + entries_needed - 1;    file->direntries = entries_needed;    file->dircluster = dir->file.firstcluster;    LDEBUGF("Added new dir entry %d, using %d slots.\n",            file->direntry, file->direntries);    /* advance the end-of-dir marker? */    if (last)    {        unsigned int lastentry = firstentry + entries_needed;        LDEBUGF("Updating end-of-dir entry %d\n",lastentry);        if (lastentry % DIR_ENTRIES_PER_SECTOR)        {            int idx = (lastentry % DIR_ENTRIES_PER_SECTOR) * DIR_ENTRY_SIZE;            rc = fat_seek(&dir->file, lastentry / DIR_ENTRIES_PER_SECTOR);            if (rc < 0)                return rc * 10 - 6;            rc = fat_readwrite(&dir->file, 1, buf, false);            if (rc < 1)                return rc * 10 - 7;            /* clear last entry */            buf[idx] = 0;            rc = fat_seek(&dir->file, lastentry / DIR_ENTRIES_PER_SECTOR);            if (rc < 0)                return rc * 10 - 8;                        /* we must clear entire last cluster */            do {                rc = fat_readwrite(&dir->file, 1, buf, true);                if (rc < 1)                    return rc * 10 - 9;                memset(buf, 0, sizeof buf);            } while (dir->file.sectornum < (int)fat_bpb.bpb_secperclus);        }        else        {            /* add a new sector/cluster for last entry */            memset(buf, 0, sizeof buf);            do {                rc = fat_readwrite(&dir->file, 1, buf, true);                if (rc < 1)                    return rc * 10 - 9; /* Same error code as above, can't be                                           more than -9 */            } while (dir->file.sectornum < (int)fat_bpb.bpb_secperclus);        }    }    return 0;}unsigned char char2dos(unsigned char c){    switch(c)    {        case 0xe5: /* Special kanji character */            c = 0x05;            break;        case 0x20:        case 0x22:        case 0x2a:        case 0x2b:        case 0x2c:        case 0x2e:        case 0x3a:        case 0x3b:        case 0x3c:        case 0x3d:        case 0x3e:        case 0x3f:        case 0x5b:        case 0x5c:        case 0x5d:        case 0x7c:            /* Illegal name */            c = 0;            break;                        default:            if(c < 0x20)            {                /* Illegal name */                c = 0;            }            break;    }    return c;}static int create_dos_name(unsigned char *name, unsigned char *newname){    int i,j;    /* Name part */    for (i=0, j=0; name[i] && (j < 8); i++)    {        unsigned char c = char2dos(name[i]);        if (c)            newname[j++] = toupper(c);    }    while (j < 8)        newname[j++] = ' ';    /* Extension part */    snprintf(newname+8, 4, "%03X", (unsigned)rand() & 0xfff);

⌨️ 快捷键说明

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