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

📄 fatfs.c

📁 linux下开发的针对所有磁盘的数据恢复的源码
💻 C
📖 第 1 页 / 共 4 页
字号:
        return 1;    }    if (tsk_verbose)        tsk_fprintf(stderr,            "fatfs_block_walk: Block Walking %" PRIuDADDR " to %"            PRIuDADDR "\n", a_start_blk, a_end_blk);    /* Sanity check on a_flags -- make sure at least one ALLOC is set */    if (((a_flags & TSK_FS_BLOCK_WALK_FLAG_ALLOC) == 0) &&        ((a_flags & TSK_FS_BLOCK_WALK_FLAG_UNALLOC) == 0)) {        a_flags |=            (TSK_FS_BLOCK_WALK_FLAG_ALLOC |            TSK_FS_BLOCK_WALK_FLAG_UNALLOC);    }    if (((a_flags & TSK_FS_BLOCK_WALK_FLAG_META) == 0) &&        ((a_flags & TSK_FS_BLOCK_WALK_FLAG_CONT) == 0)) {        a_flags |=            (TSK_FS_BLOCK_WALK_FLAG_CONT | TSK_FS_BLOCK_WALK_FLAG_META);    }    if ((fs_block = tsk_fs_block_alloc(fs)) == NULL) {        return 1;    }    /* cycle through the sectors.  We do the sectors before the first     * cluster seperate from the data area */    addr = a_start_blk;    /* Before the data area beings (FAT, root directory etc.) */    if ((a_start_blk < fatfs->firstclustsect)        && (a_flags & TSK_FS_BLOCK_WALK_FLAG_ALLOC)) {        if (tsk_verbose)            tsk_fprintf(stderr,                "fatfs_block_walk: Walking non-data area (pre %"                PRIuDADDR "\n", fatfs->firstclustsect);        if ((data_buf = (char *) tsk_malloc(fs->block_size * 8)) == NULL) {            tsk_fs_block_free(fs_block);            return 1;        }        /* Read 8 sectors at a time to be faster */        for (; addr < fatfs->firstclustsect && addr <= a_end_blk;) {            cnt =                tsk_fs_read_block(fs, addr, data_buf, fs->block_size * 8);            if (cnt != fs->block_size * 8) {                if (cnt >= 0) {                    tsk_error_reset();                    tsk_errno = TSK_ERR_FS_READ;                }                snprintf(tsk_errstr2, TSK_ERRSTR_L,                    "fatfs_block_walk: pre-data area block: %"                    PRIuDADDR, addr);                free(data_buf);                tsk_fs_block_free(fs_block);                return 1;            }            /* Process the sectors until we get to the clusters,              * end of target, or end of buffer */            for (i = 0;                i < 8 && (addr) <= a_end_blk                && (addr) < fatfs->firstclustsect; i++, addr++) {                int retval;                myflags = TSK_FS_BLOCK_FLAG_ALLOC;                /* stuff before the first data sector is the                  * FAT and boot sector */                if (addr < fatfs->firstdatasect)                    myflags |= TSK_FS_BLOCK_FLAG_META;                /* This must be the root directory for FAT12/16 */                else                    myflags |= TSK_FS_BLOCK_FLAG_CONT;                // test this sector (we already tested ALLOC)                if ((myflags & TSK_FS_BLOCK_FLAG_META)                    && (!(a_flags & TSK_FS_BLOCK_WALK_FLAG_META)))                    continue;                else if ((myflags & TSK_FS_BLOCK_FLAG_CONT)                    && (!(a_flags & TSK_FS_BLOCK_WALK_FLAG_CONT)))                    continue;                tsk_fs_block_set(fs, fs_block, addr,                    myflags | TSK_FS_BLOCK_FLAG_RAW,                    &data_buf[i * fs->block_size]);                retval = a_action(fs_block, a_ptr);                if (retval == TSK_WALK_STOP) {                    free(data_buf);                    tsk_fs_block_free(fs_block);                    return 0;                }                else if (retval == TSK_WALK_ERROR) {                    free(data_buf);                    tsk_fs_block_free(fs_block);                    return 1;                }            }        }        free(data_buf);        /* Was that it? */        if (addr >= a_end_blk) {            tsk_fs_block_free(fs_block);            return 0;        }    }    /* Reset the first sector to the start of the data area if we did     * not examine it - the next calculation will screw up otherwise */    else if (addr < fatfs->firstclustsect) {        addr = fatfs->firstclustsect;    }    /* Now we read in the clusters in cluster-sized chunks,     * sectors are too small     */    /* Determine the base sector of the cluster where the first      * sector is located */    addr = FATFS_CLUST_2_SECT(fatfs, (FATFS_SECT_2_CLUST(fatfs, addr)));    if ((data_buf = tsk_malloc(fs->block_size * fatfs->csize)) == NULL) {        tsk_fs_block_free(fs_block);        return 1;    }    if (tsk_verbose)        tsk_fprintf(stderr,            "fatfs_block_walk: Walking data area blocks (%" PRIuDADDR            " to %" PRIuDADDR ")\n", addr, a_end_blk);    for (; addr <= a_end_blk; addr += fatfs->csize) {        int retval;        size_t read_size;        /* Identify its allocation status */        retval = fatfs_is_sectalloc(fatfs, addr);        if (retval == -1) {            free(data_buf);            tsk_fs_block_free(fs_block);            return 1;        }        else if (retval == 1) {            myflags = TSK_FS_BLOCK_FLAG_ALLOC;        }        else {            myflags = TSK_FS_BLOCK_FLAG_UNALLOC;        }        /* At this point, there should be no more meta - just content */        myflags |= TSK_FS_BLOCK_FLAG_CONT;        // test if we should call the callback with this one        if ((myflags & TSK_FS_BLOCK_FLAG_CONT)            && (!(a_flags & TSK_FS_BLOCK_WALK_FLAG_CONT)))            continue;        else if ((myflags & TSK_FS_BLOCK_FLAG_ALLOC)            && (!(a_flags & TSK_FS_BLOCK_WALK_FLAG_ALLOC)))            continue;        else if ((myflags & TSK_FS_BLOCK_FLAG_UNALLOC)            && (!(a_flags & TSK_FS_BLOCK_WALK_FLAG_UNALLOC)))            continue;        /* The final cluster may not be full */        if (a_end_blk - addr + 1 < fatfs->csize)            read_size = (size_t) (a_end_blk - addr + 1);        else            read_size = fatfs->csize;        cnt = tsk_fs_read_block            (fs, addr, data_buf, fs->block_size * read_size);        if (cnt != fs->block_size * read_size) {            if (cnt >= 0) {                tsk_error_reset();                tsk_errno = TSK_ERR_FS_READ;            }            snprintf(tsk_errstr2, TSK_ERRSTR_L,                "fatfs_block_walk: block: %" PRIuDADDR, addr);            free(data_buf);            tsk_fs_block_free(fs_block);            return 1;        }        /* go through each sector in the cluster */        for (i = 0; i < read_size; i++) {            int retval;            if (addr + i < a_start_blk)                continue;            else if (addr + i > a_end_blk)                break;            tsk_fs_block_set(fs, fs_block, addr + i,                myflags | TSK_FS_BLOCK_FLAG_RAW,                &data_buf[i * fs->block_size]);            retval = a_action(fs_block, a_ptr);            if (retval == TSK_WALK_STOP) {                free(data_buf);                tsk_fs_block_free(fs_block);                return 0;            }            else if (retval == TSK_WALK_ERROR) {                free(data_buf);                tsk_fs_block_free(fs_block);                return 1;            }        }    }    free(data_buf);    tsk_fs_block_free(fs_block);    return 0;}/* return 1 on error and 0 on success */static uint8_tfatfs_fscheck(TSK_FS_INFO * fs, FILE * hFile){    tsk_error_reset();    tsk_errno = TSK_ERR_FS_UNSUPFUNC;    snprintf(tsk_errstr, TSK_ERRSTR_L,        "fscheck not implemented for FAT yet");    return 1;    /* Check that allocated dentries point to start of allcated cluster chain */    /* Size of file is consistent with cluster chain length */    /* Allocated cluster chains have a corresponding alloc dentry */    /* Non file dentries have no clusters */    /* Only one volume label */    /* Dump Bad Sector Addresses */    /* Dump unused sector addresses      * Reserved area, end of FAT, end of Data Area */}/** * Print details about the file system to a file handle.  * * @param fs File system to print details on * @param hFile File handle to print text to *  * @returns 1 on error and 0 on success */static uint8_tfatfs_fsstat(TSK_FS_INFO * fs, FILE * hFile){    unsigned int i;    int a;    TSK_DADDR_T next, snext, sstart, send;    FATFS_INFO *fatfs = (FATFS_INFO *) fs;    fatfs_sb *sb = fatfs->sb;    char *data_buf;    fatfs_dentry *de;    ssize_t cnt;    // clean up any error messages that are lying around    tsk_error_reset();    if ((data_buf = (char *) tsk_malloc(fatfs->ssize)) == NULL) {        return 1;    }    /* Read the root directory sector so that we can get the volume     * label from it */    cnt = tsk_fs_read_block(fs, fatfs->rootsect, data_buf, fatfs->ssize);    if (cnt != fatfs->ssize) {        if (cnt >= 0) {            tsk_error_reset();            tsk_errno = TSK_ERR_FS_READ;        }        snprintf(tsk_errstr2, TSK_ERRSTR_L,            "fatfs_fsstat: root directory: %" PRIuDADDR, fatfs->rootsect);        free(data_buf);        return 1;    }    /* Find the dentry that is set as the volume label */    de = (fatfs_dentry *) data_buf;    for (i = 0; i < fatfs->ssize; i += sizeof(*de)) {        if (de->attrib == FATFS_ATTR_VOLUME)            break;        de++;    }    /* If we didn't find it, then reset de */    if (de->attrib != FATFS_ATTR_VOLUME)        de = NULL;    /* Print the general file system information */    tsk_fprintf(hFile, "FILE SYSTEM INFORMATION\n");    tsk_fprintf(hFile, "--------------------------------------------\n");    tsk_fprintf(hFile, "File System Type: FAT");    if (fs->ftype == TSK_FS_TYPE_FAT12)        tsk_fprintf(hFile, "12\n");    else if (fs->ftype == TSK_FS_TYPE_FAT16)        tsk_fprintf(hFile, "16\n");    else if (fs->ftype == TSK_FS_TYPE_FAT32)        tsk_fprintf(hFile, "32\n");    else        tsk_fprintf(hFile, "\n");    tsk_fprintf(hFile, "\nOEM Name: %c%c%c%c%c%c%c%c\n", sb->oemname[0],        sb->oemname[1], sb->oemname[2], sb->oemname[3], sb->oemname[4],        sb->oemname[5], sb->oemname[6], sb->oemname[7]);    if (fatfs->fs_info.ftype != TSK_FS_TYPE_FAT32) {        tsk_fprintf(hFile, "Volume ID: 0x%" PRIx32 "\n",            tsk_getu32(fs->endian, sb->a.f16.vol_id));        tsk_fprintf(hFile,            "Volume Label (Boot Sector): %c%c%c%c%c%c%c%c%c%c%c\n",            sb->a.f16.vol_lab[0], sb->a.f16.vol_lab[1],            sb->a.f16.vol_lab[2], sb->a.f16.vol_lab[3],            sb->a.f16.vol_lab[4], sb->a.f16.vol_lab[5],            sb->a.f16.vol_lab[6], sb->a.f16.vol_lab[7],            sb->a.f16.vol_lab[8], sb->a.f16.vol_lab[9],            sb->a.f16.vol_lab[10]);        if ((de) && (de->name)) {            tsk_fprintf(hFile,                "Volume Label (Root Directory): %c%c%c%c%c%c%c%c%c%c%c\n",                de->name[0], de->name[1], de->name[2], de->name[3],                de->name[4], de->name[5], de->name[6], de->name[7],                de->name[8], de->name[9], de->name[10]);        }        else {            tsk_fprintf(hFile, "Volume Label (Root Directory):\n");        }        tsk_fprintf(hFile, "File System Type Label: %c%c%c%c%c%c%c%c\n",            sb->a.f16.fs_type[0], sb->a.f16.fs_type[1],            sb->a.f16.fs_type[2], sb->a.f16.fs_type[3],            sb->a.f16.fs_type[4], sb->a.f16.fs_type[5],            sb->a.f16.fs_type[6], sb->a.f16.fs_type[7]);    }    else {        char *fat_fsinfo_buf;        fatfs_fsinfo *fat_info;        if ((fat_fsinfo_buf = (char *)                tsk_malloc(sizeof(fatfs_fsinfo))) == NULL) {            free(data_buf);            return 1;        }        tsk_fprintf(hFile, "Volume ID: 0x%" PRIx32 "\n",            tsk_getu32(fs->endian, sb->a.f32.vol_id));        tsk_fprintf(hFile,            "Volume Label (Boot Sector): %c%c%c%c%c%c%c%c%c%c%c\n",            sb->a.f32.vol_lab[0], sb->a.f32.vol_lab[1],            sb->a.f32.vol_lab[2], sb->a.f32.vol_lab[3],            sb->a.f32.vol_lab[4], sb->a.f32.vol_lab[5],            sb->a.f32.vol_lab[6], sb->a.f32.vol_lab[7],            sb->a.f32.vol_lab[8], sb->a.f32.vol_lab[9],            sb->a.f32.vol_lab[10]);        if ((de) && (de->name)) {            tsk_fprintf(hFile,                "Volume Label (Root Directory): %c%c%c%c%c%c%c%c%c%c%c\n",                de->name[0], de->name[1], de->name[2], de->name[3],                de->name[4], de->name[5], de->name[6], de->name[7],                de->name[8], de->name[9], de->name[10]);        }        else {            tsk_fprintf(hFile, "Volume Label (Root Directory):\n");        }        tsk_fprintf(hFile, "File System Type Label: %c%c%c%c%c%c%c%c\n",            sb->a.f32.fs_type[0], sb->a.f32.fs_type[1],            sb->a.f32.fs_type[2], sb->a.f32.fs_type[3],            sb->a.f32.fs_type[4], sb->a.f32.fs_type[5],            sb->a.f32.fs_type[6], sb->a.f32.fs_type[7]);        /* Process the FS info */        if (tsk_getu16(fs->endian, sb->a.f32.fsinfo)) {            cnt =                tsk_fs_read_block(fs, (TSK_DADDR_T) tsk_getu16(fs->endian,                    sb->a.f32.fsinfo), fat_fsinfo_buf,                sizeof(fatfs_fsinfo));            if (cnt != sizeof(fatfs_fsinfo)) {                if (cnt >= 0) {                    tsk_error_reset();                    tsk_errno = TSK_ERR_FS_READ;                }                snprintf(tsk_errstr2, TSK_ERRSTR_L,                    "fatfs_fsstat: TSK_FS_TYPE_FAT32 FSINFO block: %"                    PRIuDADDR, (TSK_DADDR_T) tsk_getu16(fs->endian,                        sb->a.f32.fsinfo));                free(data_buf);

⌨️ 快捷键说明

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