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

📄 iso9660.c

📁 linux下开发的针对所有磁盘的数据恢复的源码
💻 C
📖 第 1 页 / 共 5 页
字号:
    return count;}/**  * Load the raw "inode" into the cached buffer (iso->dinode) * * dinode_load (for now) does not check for extended attribute records... * my issue is I dont have an iso9660 image with extended attr recs, so I * can't test/debug, etc * * @returns 1 if not found and 0 on succuss */uint8_tiso9660_dinode_load(ISO_INFO * iso, TSK_INUM_T inum){    iso9660_inode_node *n;    if (tsk_verbose)        tsk_fprintf(stderr, "iso9660_dinode_load: iso: %lu"            " inum: %" PRIuINUM "\n", (uintptr_t) iso, inum);    n = iso->in_list;    while (n && (n->inum != inum))        n = n->next;    if (n) {        memcpy(iso->dinode, &n->inode, sizeof(iso9660_inode));        iso->dinum = inum;        return 0;    }    else {        return 1;    }}static uint16_tisomode2tskmode(uint16_t a_mode){    uint16_t mode = 0;    if (a_mode & ISO_EA_IRUSR)        mode |= TSK_FS_META_MODE_IRUSR;    if (a_mode & ISO_EA_IWUSR)        mode |= TSK_FS_META_MODE_IWUSR;    if (a_mode & ISO_EA_IXUSR)        mode |= TSK_FS_META_MODE_IXUSR;    if (a_mode & ISO_EA_IRGRP)        mode |= TSK_FS_META_MODE_IRGRP;    if (a_mode & ISO_EA_IWGRP)        mode |= TSK_FS_META_MODE_IWGRP;    if (a_mode & ISO_EA_IXGRP)        mode |= TSK_FS_META_MODE_IXGRP;    if (a_mode & ISO_EA_IROTH)        mode |= TSK_FS_META_MODE_IROTH;    if (a_mode & ISO_EA_IWOTH)        mode |= TSK_FS_META_MODE_IWOTH;    if (a_mode & ISO_EA_IXOTH)        mode |= TSK_FS_META_MODE_IXOTH;    return mode;}/** * Copies cached disk inode into generic structure.  * * @returns 1 on error and 0 on success */static uint8_tiso9660_dinode_copy(ISO_INFO * iso, TSK_FS_META * fs_meta){    TSK_FS_INFO *fs = (TSK_FS_INFO *) & iso->fs_info;    struct tm t;    if (tsk_verbose)        tsk_fprintf(stderr, "iso9660_dinode_copy: iso: %lu"            " inode: %lu\n", (uintptr_t) iso, (uintptr_t) fs_meta);    if (fs_meta == NULL) {        tsk_errno = TSK_ERR_FS_ARG;        snprintf(tsk_errstr, TSK_ERRSTR_L,            "iso9660_dinode_copy: fs_file or meta is NULL");        return 1;    }    fs_meta->attr_state = TSK_FS_META_ATTR_EMPTY;    if (fs_meta->attr) {        tsk_fs_attrlist_markunused(fs_meta->attr);    }    if (fs_meta->content_len < ISO9660_FILE_CONTENT_LEN) {        if ((fs_meta =                tsk_fs_meta_realloc(fs_meta,                    ISO9660_FILE_CONTENT_LEN)) == NULL) {            return 1;        }    }    fs_meta->addr = iso->dinum;    fs_meta->size = tsk_getu32(fs->endian, iso->dinode->dr.data_len_m);    memset(&t, 0, sizeof(struct tm));    t.tm_sec = iso->dinode->dr.rec_time.sec;    t.tm_min = iso->dinode->dr.rec_time.min;    t.tm_hour = iso->dinode->dr.rec_time.hour;    t.tm_mday = iso->dinode->dr.rec_time.day;    t.tm_mon = iso->dinode->dr.rec_time.month - 1;    t.tm_year = iso->dinode->dr.rec_time.year;    //gmt_hrdiff = iso->dinode->dr.rec_time.gmt_off * 15 / 60;    fs_meta->crtime = mktime(&t);    fs_meta->mtime = fs_meta->atime = fs_meta->ctime = 0;    if (iso->dinode->dr.flags & ISO9660_FLAG_DIR)        fs_meta->type = TSK_FS_META_TYPE_DIR;    else        fs_meta->type = TSK_FS_META_TYPE_REG;    if (iso->dinode->ea) {        fs_meta->uid = tsk_getu32(fs->endian, iso->dinode->ea->uid);        fs_meta->gid = tsk_getu32(fs->endian, iso->dinode->ea->gid);        fs_meta->mode =            isomode2tskmode(tsk_getu16(fs->endian, iso->dinode->ea->mode));        fs_meta->nlink = 1;    }    else {        fs_meta->uid = 0;        fs_meta->gid = 0;        fs_meta->mode = 0;        fs_meta->nlink = 1;    }    ((TSK_DADDR_T *) fs_meta->content_ptr)[0] =        (TSK_DADDR_T) tsk_getu32(fs->endian, iso->dinode->dr.ext_loc_m);    fs_meta->flags = TSK_FS_META_FLAG_ALLOC;    return 0;}static uint8_tiso9660_inode_lookup(TSK_FS_INFO * fs, TSK_FS_FILE * a_fs_file,    TSK_INUM_T inum){    ISO_INFO *iso = (ISO_INFO *) fs;    if (tsk_verbose)        tsk_fprintf(stderr, "iso9660_inode_lookup: iso: %lu"            " inum: %" PRIuINUM "\n", (uintptr_t) iso, inum);    if (a_fs_file == NULL) {        tsk_errno = TSK_ERR_FS_ARG;        snprintf(tsk_errstr, TSK_ERRSTR_L,            "iso9660_inode_lookup: fs_file is NULL");        return 1;    }    // load the inode into the ISO buffer    if (iso9660_dinode_load(iso, inum)) {        return 1;    }    if (a_fs_file->meta == NULL) {        if ((a_fs_file->meta =                tsk_fs_meta_alloc(ISO9660_FILE_CONTENT_LEN)) == NULL)            return 1;    }    else {        tsk_fs_meta_reset(a_fs_file->meta);    }    // copy into the FS_META structure    if (iso9660_dinode_copy(iso, a_fs_file->meta)) {        return 1;    }    return 0;}uint8_tiso9660_inode_walk(TSK_FS_INFO * fs, TSK_INUM_T start, TSK_INUM_T last,    TSK_FS_META_FLAG_ENUM flags, TSK_FS_META_WALK_CB action, void *ptr){    char *myname = "iso9660_inode_walk";    ISO_INFO *iso = (ISO_INFO *) fs;    TSK_INUM_T inum;    TSK_FS_FILE *fs_file;    int myflags;    // clean up any error messages that are lying around    tsk_error_reset();    if (tsk_verbose)        tsk_fprintf(stderr, "iso9660_inode_walk: iso: %lu"            " start: %" PRIuINUM " last: %" PRIuINUM " flags: %d"            " action: %lu ptr: %lu\n",            (uintptr_t) fs, start, last, flags, (uintptr_t) action,            (uintptr_t) ptr);    myflags = TSK_FS_META_FLAG_ALLOC;    /*     * Sanity checks.     */    if (start < fs->first_inum || start > 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);        return 1;    }    if (last < fs->first_inum || last > fs->last_inum || last < start) {        tsk_error_reset();        tsk_errno = TSK_ERR_FS_WALK_RNG;        snprintf(tsk_errstr, TSK_ERRSTR_L,            "%s: End inode: %" PRIuINUM "", myname, last);        return 1;    }    if (flags & TSK_FS_META_FLAG_ORPHAN) {        return 0;    }    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 ((fs_file = tsk_fs_file_alloc(fs)) == NULL)        return 1;    if ((fs_file->meta =            tsk_fs_meta_alloc(ISO9660_FILE_CONTENT_LEN)) == NULL)        return 1;    /*     * Iterate.     */    for (inum = start; inum <= last; inum++) {        int retval;        if (iso9660_dinode_load(iso, inum)) {            tsk_fs_file_close(fs_file);            return 1;        }        if ((flags & myflags) != myflags)            continue;        if (iso9660_dinode_copy(iso, fs_file->meta))            return 1;        retval = action(fs_file, ptr);        if (retval == TSK_WALK_ERROR) {            tsk_fs_file_close(fs_file);            return 1;        }        else if (retval == TSK_WALK_STOP) {            break;        }    }    /*     * Cleanup.     */    tsk_fs_file_close(fs_file);    return 0;}// @@@ Doesn' thit seem to ignore interleave?/* return 1 if block is allocated in a file's extent, return 0 otherwise */static intiso9660_is_block_alloc(TSK_FS_INFO * fs, TSK_DADDR_T blk_num){    ISO_INFO *iso = (ISO_INFO *) fs;    iso9660_inode_node *in_node;    if (tsk_verbose)        tsk_fprintf(stderr, "iso9660_is_block_alloc: fs: %lu"            " blk_num: %" PRIuDADDR "\n", (uintptr_t) fs, blk_num);    for (in_node = iso->in_list; in_node; in_node = in_node->next) {        TSK_DADDR_T first_block = in_node->offset / fs->block_size;        TSK_DADDR_T file_size =            tsk_getu32(fs->endian, in_node->inode.dr.data_len_m);        TSK_DADDR_T last_block =            first_block + (file_size / fs->block_size);        if (file_size % fs->block_size)            last_block++;        if ((blk_num >= first_block) && (blk_num <= last_block))            return 1;    }    return 0;}TSK_FS_BLOCK_FLAG_ENUMiso9660_block_getflags(TSK_FS_INFO * a_fs, TSK_DADDR_T a_addr){    return (iso9660_is_block_alloc(a_fs, a_addr)) ?        TSK_FS_BLOCK_FLAG_ALLOC : TSK_FS_BLOCK_FLAG_UNALLOC;}/* flags: TSK_FS_BLOCK_FLAG_ALLOC and FS_FLAG_UNALLOC * ISO9660 has a LOT of very sparse meta, so in this function a block is only * checked to see if it is part of an inode's extent */uint8_tiso9660_block_walk(TSK_FS_INFO * fs, TSK_DADDR_T start, TSK_DADDR_T last,    TSK_FS_BLOCK_WALK_FLAG_ENUM flags, TSK_FS_BLOCK_WALK_CB action,    void *ptr){    char *myname = "iso9660_block_walk";    TSK_DADDR_T addr;    TSK_FS_BLOCK *fs_block;    // clean up any error messages that are lying around    tsk_error_reset();    if (tsk_verbose)        tsk_fprintf(stderr, "iso9660_block_walk: fs: %lu"            " start: %" PRIuDADDR " last: %" PRIuDADDR " flags: %d"            " action: %lu ptr: %lu\n",            (uintptr_t) fs, start, last, flags, (uintptr_t) action,            (uintptr_t) ptr);    /*     * Sanity checks.     */    if (start < fs->first_block || start > fs->last_block) {        tsk_error_reset();        tsk_errno = TSK_ERR_FS_WALK_RNG;        snprintf(tsk_errstr, TSK_ERRSTR_L,            "%s: Start block: %" PRIuDADDR "", myname, start);        return 1;    }    if (last < fs->first_block || last > fs->last_block) {        tsk_error_reset();        tsk_errno = TSK_ERR_FS_WALK_RNG;        snprintf(tsk_errstr, TSK_ERRSTR_L,            "%s: End block: %" PRIuDADDR "", myname, last);        return 1;    }    /* Sanity check on flags -- make sure at least one ALLOC is set */    if (((flags & TSK_FS_BLOCK_WALK_FLAG_ALLOC) == 0) &&        ((flags & TSK_FS_BLOCK_WALK_FLAG_UNALLOC) == 0)) {        flags |=            (TSK_FS_BLOCK_WALK_FLAG_ALLOC |            TSK_FS_BLOCK_WALK_FLAG_UNALLOC);    }    if (((flags & TSK_FS_BLOCK_WALK_FLAG_META) == 0) &&        ((flags & TSK_FS_BLOCK_WALK_FLAG_CONT) == 0)) {        flags |=            (TSK_FS_BLOCK_WALK_FLAG_CONT | TSK_FS_BLOCK_WALK_FLAG_META);    }    if ((fs_block = tsk_fs_block_alloc(fs)) == NULL) {        return 1;    }    if (tsk_verbose)        tsk_fprintf(stderr,            "isofs_block_walk: Block Walking %" PRIuDADDR " to %" PRIuDADDR            "\n", start, last);    /* cycle through block addresses */    for (addr = start; addr <= last; addr++) {        int retval;        int myflags = iso9660_block_getflags(fs, addr);        // test if we should call the callback with this one        if ((myflags & TSK_FS_BLOCK_FLAG_ALLOC)            && (!(flags & TSK_FS_BLOCK_WALK_FLAG_ALLOC)))            continue;        else if ((myflags & TSK_FS_BLOCK_FLAG_UNALLOC)            && (!(flags & TSK_FS_BLOCK_WALK_FLAG_UNALLOC)))            continue;        if (tsk_fs_block_get(fs, fs_block, addr) == NULL) {            snprintf(tsk_errstr2, TSK_ERRSTR_L, "iso_block_walk");            tsk_fs_block_free(fs_block);            return 1;        }        retval = action(fs_block, ptr);        if (retval == TSK_WALK_ERROR) {            tsk_fs_block_free(fs_block);            return 1;        }        else if (retval == TSK_WALK_STOP) {            break;        }    }

⌨️ 快捷键说明

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