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

📄 ext2fs.c

📁 linux下开发的针对所有磁盘的数据恢复的源码
💻 C
📖 第 1 页 / 共 5 页
字号:
        break;    case EXT2_IN_LNK:        fs_meta->type = TSK_FS_META_TYPE_LNK;        break;    case EXT2_IN_BLK:        fs_meta->type = TSK_FS_META_TYPE_BLK;        break;    case EXT2_IN_CHR:        fs_meta->type = TSK_FS_META_TYPE_CHR;        break;    case EXT2_IN_FIFO:        fs_meta->type = TSK_FS_META_TYPE_FIFO;        break;    default:        fs_meta->type = TSK_FS_META_TYPE_UNDEF;        break;    }    // set the mode    fs_meta->mode = 0;    if (tsk_getu16(fs->endian, in->i_mode) & EXT2_IN_ISUID)        fs_meta->mode |= TSK_FS_META_MODE_ISUID;    if (tsk_getu16(fs->endian, in->i_mode) & EXT2_IN_ISGID)        fs_meta->mode |= TSK_FS_META_MODE_ISGID;    if (tsk_getu16(fs->endian, in->i_mode) & EXT2_IN_ISVTX)        fs_meta->mode |= TSK_FS_META_MODE_ISVTX;    if (tsk_getu16(fs->endian, in->i_mode) & EXT2_IN_IRUSR)        fs_meta->mode |= TSK_FS_META_MODE_IRUSR;    if (tsk_getu16(fs->endian, in->i_mode) & EXT2_IN_IWUSR)        fs_meta->mode |= TSK_FS_META_MODE_IWUSR;    if (tsk_getu16(fs->endian, in->i_mode) & EXT2_IN_IXUSR)        fs_meta->mode |= TSK_FS_META_MODE_IXUSR;    if (tsk_getu16(fs->endian, in->i_mode) & EXT2_IN_IRGRP)        fs_meta->mode |= TSK_FS_META_MODE_IRGRP;    if (tsk_getu16(fs->endian, in->i_mode) & EXT2_IN_IWGRP)        fs_meta->mode |= TSK_FS_META_MODE_IWGRP;    if (tsk_getu16(fs->endian, in->i_mode) & EXT2_IN_IXGRP)        fs_meta->mode |= TSK_FS_META_MODE_IXGRP;    if (tsk_getu16(fs->endian, in->i_mode) & EXT2_IN_IROTH)        fs_meta->mode |= TSK_FS_META_MODE_IROTH;    if (tsk_getu16(fs->endian, in->i_mode) & EXT2_IN_IWOTH)        fs_meta->mode |= TSK_FS_META_MODE_IWOTH;    if (tsk_getu16(fs->endian, in->i_mode) & EXT2_IN_IXOTH)        fs_meta->mode |= TSK_FS_META_MODE_IXOTH;    fs_meta->nlink = tsk_getu16(fs->endian, in->i_nlink);    fs_meta->size = tsk_getu32(fs->endian, in->i_size);    fs_meta->addr = ext2fs->dino_inum;    /* the general size value in the inode is only 32-bits,     * but the i_dir_acl value is used for regular files to      * hold the upper 32-bits      *     * The RO_COMPAT_LARGE_FILE flag in the super block will identify     * if there are any large files in the file system     */    if ((fs_meta->type == TSK_FS_META_TYPE_REG) &&        (tsk_getu32(fs->endian, sb->s_feature_ro_compat) &            EXT2FS_FEATURE_RO_COMPAT_LARGE_FILE)) {        fs_meta->size +=            ((uint64_t) tsk_getu32(fs->endian, in->i_size_high) << 32);    }    fs_meta->uid =        tsk_getu16(fs->endian, in->i_uid) + (tsk_getu16(fs->endian,            in->i_uid_high) << 16);    fs_meta->gid =        tsk_getu16(fs->endian, in->i_gid) + (tsk_getu16(fs->endian,            in->i_gid_high) << 16);    fs_meta->mtime = tsk_getu32(fs->endian, in->i_mtime);    fs_meta->atime = tsk_getu32(fs->endian, in->i_atime);    fs_meta->ctime = tsk_getu32(fs->endian, in->i_ctime);    fs_meta->crtime = 0;    fs_meta->time2.ext2.dtime = tsk_getu32(fs->endian, in->i_dtime);    fs_meta->seq = 0;    if (fs_meta->link) {        free(fs_meta->link);        fs_meta->link = NULL;    }    if (fs_meta->content_len != EXT2FS_FILE_CONTENT_LEN) {        if ((fs_meta =                tsk_fs_meta_realloc(fs_meta,                    EXT2FS_FILE_CONTENT_LEN)) == NULL) {            return 1;        }    }    addr_ptr = (TSK_DADDR_T *) fs_meta->content_ptr;    for (i = 0; i < EXT2FS_NDADDR + EXT2FS_NIADDR; i++)        addr_ptr[i] = tsk_gets32(fs->endian, in->i_block[i]);    /* set the link string      * the size check prevents us from trying to allocate a huge amount of     * memory for a bad inode value     */    if ((fs_meta->type == TSK_FS_META_TYPE_LNK)        && (fs_meta->size < EXT2FS_MAXPATHLEN) && (fs_meta->size >= 0)) {        unsigned int count = 0;        int i;        if ((fs_meta->link =                tsk_malloc((size_t) (fs_meta->size + 1))) == NULL)            return 1;        /* it is located directly in the pointers */        if (fs_meta->size < 4 * (EXT2FS_NDADDR + EXT2FS_NIADDR)) {            unsigned int j;            for (i = 0; i < (EXT2FS_NDADDR + EXT2FS_NIADDR) &&                count < fs_meta->size; i++) {                char *a_ptr = (char *) &in->i_block[i];                for (j = 0; j < 4 && count < fs_meta->size; j++) {                    fs_meta->link[count++] = a_ptr[j];                }            }            fs_meta->link[count] = '\0';            /* clear the content pointer data to avoid the prog from reading them */            memset(fs_meta->content_ptr, 0, fs_meta->content_len);        }        /* it is in blocks */        else {            TSK_FS_INFO *fs = (TSK_FS_INFO *) & ext2fs->fs_info;            char *data_buf;            char *a_ptr = fs_meta->link;            TSK_DADDR_T *addr_ptr = fs_meta->content_ptr;;            if ((data_buf = tsk_malloc(fs->block_size)) == NULL)                return 1;            /* we only need to do the direct blocks due to the limit              * on path length */            for (i = 0; i < EXT2FS_NDADDR && count < fs_meta->size; i++) {                ssize_t cnt;                int read_count =                    (fs_meta->size - count <                    fs->block_size) ? (int) (fs_meta->size -                    count) : (int) (fs->block_size);                cnt = tsk_fs_read_block(fs,                    addr_ptr[i], data_buf, fs->block_size);                if (cnt != fs->block_size) {                    if (cnt >= 0) {                        tsk_error_reset();                        tsk_errno = TSK_ERR_FS_READ;                    }                    snprintf(tsk_errstr2, TSK_ERRSTR_L,                        "ext2fs_dinode_copy: symlink destination from %"                        PRIuDADDR, addr_ptr[i]);                    free(data_buf);                    return 1;                }                memcpy(a_ptr, data_buf, read_count);                count += read_count;                a_ptr = (char *) ((uintptr_t) a_ptr + count);            }            /* terminate the string */            *a_ptr = '\0';            free(data_buf);        }        /* Clean up name */        i = 0;        while (fs_meta->link[i] != '\0') {            if (TSK_IS_CNTRL(fs_meta->link[i]))                fs_meta->link[i] = '^';            i++;        }    }    /* Fill in the flags value */    grp_num = (EXT2_GRPNUM_T) ((ext2fs->dino_inum - fs->first_inum) /        tsk_getu32(fs->endian, ext2fs->fs->s_inodes_per_group));    if (ext2fs->imap_grp_num != grp_num) {        if (ext2fs_imap_load(ext2fs, grp_num)) {            return 1;        }    }    ibase =        grp_num * tsk_getu32(fs->endian,        ext2fs->fs->s_inodes_per_group) + fs->first_inum;    /*     * Apply the allocated/unallocated restriction.     */    fs_meta->flags = (isset(ext2fs->imap_buf, ext2fs->dino_inum - ibase) ?        TSK_FS_META_FLAG_ALLOC : TSK_FS_META_FLAG_UNALLOC);    /*     * Apply the used/unused restriction.     */    fs_meta->flags |= (fs_meta->ctime ?        TSK_FS_META_FLAG_USED : TSK_FS_META_FLAG_UNUSED);    return 0;}/* ext2fs_inode_lookup - lookup inode, external interface  * * Returns 1 on error and 0 on success *  */static uint8_text2fs_inode_lookup(TSK_FS_INFO * fs, TSK_FS_FILE * a_fs_file,    TSK_INUM_T inum){    EXT2FS_INFO *ext2fs = (EXT2FS_INFO *) fs;    if (a_fs_file == NULL) {        tsk_errno = TSK_ERR_FS_ARG;        snprintf(tsk_errstr, TSK_ERRSTR_L,            "ext2fs_inode_lookup: fs_file is NULL");        return 1;    }    if (a_fs_file->meta == NULL) {        if ((a_fs_file->meta =                tsk_fs_meta_alloc(EXT2FS_FILE_CONTENT_LEN)) == NULL)            return 1;    }    else {        tsk_fs_meta_reset(a_fs_file->meta);    }    // see if they are looking for the special "orphans" directory    if (inum == TSK_FS_ORPHANDIR_INUM(fs)) {        if (tsk_fs_dir_make_orphan_dir_meta(fs, a_fs_file->meta))            return 1;        else            return 0;    }    if (ext2fs_dinode_load(ext2fs, inum)) {        return 1;    }    if (ext2fs_dinode_copy(ext2fs, a_fs_file->meta)) {        return 1;    }    return 0;}/* ext2fs_inode_walk - inode iterator  * * flags used: TSK_FS_META_FLAG_USED, TSK_FS_META_FLAG_UNUSED, *  TSK_FS_META_FLAG_ALLOC, TSK_FS_META_FLAG_UNALLOC, TSK_FS_META_FLAG_ORPHAN * *  Return 1 on error and 0 on success*/uint8_text2fs_inode_walk(TSK_FS_INFO * fs, TSK_INUM_T start_inum,    TSK_INUM_T end_inum, TSK_FS_META_FLAG_ENUM flags,    TSK_FS_META_WALK_CB a_action, void *a_ptr){    char *myname = "extXfs_inode_walk";    EXT2FS_INFO *ext2fs = (EXT2FS_INFO *) fs;    EXT2_GRPNUM_T grp_num;    TSK_INUM_T inum;    TSK_INUM_T end_inum_tmp;    TSK_INUM_T ibase = 0;    TSK_FS_FILE *fs_file;    int myflags;    // clean up any error messages that are lying around    tsk_error_reset();    /*     * Sanity checks.     */    if (start_inum < fs->first_inum || start_inum > fs->last_inum) {        tsk_error_reset();        tsk_errno = TSK_ERR_FS_WALK_RNG;        snprintf(tsk_errstr, TSK_ERRSTR_L,            "%s: start inode: %" PRIuINUM "", myname, start_inum);        return 1;    }    if (end_inum < fs->first_inum || end_inum > fs->last_inum        || end_inum < start_inum) {        tsk_error_reset();        tsk_errno = TSK_ERR_FS_WALK_RNG;        snprintf(tsk_errstr, TSK_ERRSTR_L,            "%s: end inode: %" PRIuINUM "", myname, end_inum);        return 1;    }    /* If ORPHAN is wanted, then make sure that the flags are correct */    if (flags & TSK_FS_META_FLAG_ORPHAN) {        flags |= TSK_FS_META_FLAG_UNALLOC;        flags &= ~TSK_FS_META_FLAG_ALLOC;        flags |= TSK_FS_META_FLAG_USED;        flags &= ~TSK_FS_META_FLAG_UNUSED;    }    else {        if (((flags & TSK_FS_META_FLAG_ALLOC) == 0) &&            ((flags & TSK_FS_META_FLAG_UNALLOC) == 0)) {            flags |= (TSK_FS_META_FLAG_ALLOC | TSK_FS_META_FLAG_UNALLOC);        }        /* If neither of the USED or UNUSED flags are set, then set them         * both         */        if (((flags & TSK_FS_META_FLAG_USED) == 0) &&            ((flags & TSK_FS_META_FLAG_UNUSED) == 0)) {            flags |= (TSK_FS_META_FLAG_USED | TSK_FS_META_FLAG_UNUSED);        }    }    /* If we are looking for orphan files and have not yet filled     * in the list of unalloc inodes that are pointed to, then fill     * in the list     */    if ((flags & TSK_FS_META_FLAG_ORPHAN)        && (fs->list_inum_named == NULL)) {        if (tsk_fs_dir_load_inum_named(fs) != TSK_OK) {            strncat(tsk_errstr2,                " - ext2fs_inode_walk: identifying inodes allocated by file names",                TSK_ERRSTR_L);            return 1;        }    }    if ((fs_file = tsk_fs_file_alloc(fs)) == NULL)        return 1;    if ((fs_file->meta =            tsk_fs_meta_alloc(EXT2FS_FILE_CONTENT_LEN)) == NULL)        return 1;    // we need to handle fs->last_inum specially because it is for the     // virtual ORPHANS directory.  Handle it outside of the loop.    if (end_inum == TSK_FS_ORPHANDIR_INUM(fs))        end_inum_tmp = end_inum - 1;    else        end_inum_tmp = end_inum;    /*     * Iterate.     */    for (inum = start_inum; inum <= end_inum_tmp; inum++) {        int retval;        /*         * Be sure to use the proper group descriptor data. XXX Linux inodes         * start at 1, as in Fortran.         */        grp_num =            (EXT2_GRPNUM_T) ((inum - 1) / tsk_getu32(fs->endian,                ext2fs->fs->s_inodes_per_group));        if ((ext2fs->imap_buf == NULL)            || (ext2fs->imap_grp_num != grp_num)) {            if (ext2fs_imap_load(ext2fs, grp_num)) {                return 1;            }            ibase =                grp_num * tsk_getu32(fs->endian,                ext2fs->fs->s_inodes_per_group) + 1;        }        /* In case we didn't need to load it the bitmap */        else if (inum == start_inum) {            ibase =                grp_num * tsk_getu32(fs->endian,                ext2fs->fs->s_inodes_per_group) + 1;        }        /*         * Apply the allocated/unallocated restriction.         */        myflags = (isset(ext2fs->imap_buf, inum - ibase) ?            TSK_FS_META_FLAG_ALLOC : TSK_FS_META_FLAG_UNALLOC);        if ((flags & myflags) != myflags)            continue;        if (ext2fs_dinode_load(ext2fs, inum)) {            tsk_fs_file_close(fs_file);            return 1;        }

⌨️ 快捷键说明

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