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

📄 fs_attr.c

📁 linux下开发的针对所有磁盘的数据恢复的源码
💻 C
📖 第 1 页 / 共 3 页
字号:
            "Null fs_attr in tsk_fs_attr_add_run");        return 1;    }    // we only support the case of a null run if it is the only run...    if (a_data_run_new == NULL) {        tsk_error_reset();        tsk_errno = TSK_ERR_FS_ARG;        snprintf(tsk_errstr, TSK_ERRSTR_L,            "tsk_fs_attr_put_run: Error, NULL run added to existing attribute");        return 1;    }    run_len = 0;    data_run_cur = a_data_run_new;    while (data_run_cur) {        run_len += data_run_cur->len;        data_run_cur = data_run_cur->next;    }    /* First thing, is to check if we can just add it to the end */    if ((a_fs_attr->nrd.run_end)        && (a_fs_attr->nrd.run_end->offset + a_fs_attr->nrd.run_end->len ==            a_data_run_new->offset)) {        a_fs_attr->nrd.run_end->next = a_data_run_new;        a_fs_attr->nrd.initsize += (run_len * a_fs->block_size);        // update the pointer to the end of the list        while (a_fs_attr->nrd.run_end->next)            a_fs_attr->nrd.run_end = a_fs_attr->nrd.run_end->next;        /* return head of a_fs_attr list */        return 0;    }    data_run_cur = a_fs_attr->nrd.run;    data_run_prev = NULL;    while (data_run_cur) {        /* Do we replace this filler spot? */        if (data_run_cur->flags & TSK_FS_ATTR_RUN_FLAG_FILLER) {            /* This should never happen because we always add              * the filler to start from VCN 0 */            if (data_run_cur->offset > a_data_run_new->offset) {                tsk_error_reset();                tsk_errno = TSK_ERR_FS_ARG;                snprintf(tsk_errstr, TSK_ERRSTR_L,                    "tsk_fs_attr_put_run: could not add data_run");                return 1;            }            /* Check if the new run starts inside of this filler. */            if (data_run_cur->offset + data_run_cur->len >                a_data_run_new->offset) {                TSK_FS_ATTR_RUN *endrun;                /* if the new starts at the same as the filler,                  * replace the pointer */                if (data_run_cur->offset == a_data_run_new->offset) {                    if (data_run_prev)                        data_run_prev->next = a_data_run_new;                    else                        a_fs_attr->nrd.run = a_data_run_new;                }                /* The new run does not start at the begining of                 * the filler, so make a new start filler                 */                else {                    TSK_FS_ATTR_RUN *newfill = tsk_fs_attr_run_alloc();                    if (newfill == NULL)                        return 1;                    if (data_run_prev)                        data_run_prev->next = newfill;                    else                        a_fs_attr->nrd.run = newfill;                    newfill->next = a_data_run_new;                    newfill->len =                        a_data_run_new->offset - data_run_cur->offset;                    newfill->offset = data_run_cur->offset;                    newfill->flags = TSK_FS_ATTR_RUN_FLAG_FILLER;                    data_run_cur->len -= newfill->len;                }                /* get to the end of the run that we are trying to add */                endrun = a_data_run_new;                while (endrun->next)                    endrun = endrun->next;                /* if the filler is the same size as the                 * new one, replace it                  */                if (run_len == data_run_cur->len) {                    endrun->next = data_run_cur->next;                    // update the pointer to the end of the list (if we are the end)                    if (endrun->next == NULL)                        a_fs_attr->nrd.run_end = endrun;                    free(data_run_cur);                }                /* else adjust the last filler entry */                else {                    endrun->next = data_run_cur;                    data_run_cur->len -= run_len;                }                return 0;            }        }        data_run_prev = data_run_cur;        data_run_cur = data_run_cur->next;    }    /*      * There is no filler holding the location of this run, so     * we will add it to the end of the list      *      * we got here because it did not fit in the current list or     * because the current list is NULL     *     * At this point data_run_prev is the end of the existing list or     * 0 if there is no list     */    /* this is an error condition.       * it means that we are currently at a greater VCN than     * what we are inserting, but we never found the filler     * for where we were to insert     */    if ((data_run_prev)        && (data_run_prev->offset + data_run_prev->len >            a_data_run_new->offset)) {        /* MAYBE this is because of a duplicate entry .. */        if ((data_run_prev->addr == a_data_run_new->addr) &&            (data_run_prev->len == a_data_run_new->len)) {            // @@@ Sould be we freeing this....?  What if the caller tries to write ti it?            tsk_fs_attr_run_free(a_data_run_new);            return 0;        }        tsk_error_reset();        tsk_errno = TSK_ERR_FS_ARG;        snprintf(tsk_errstr, TSK_ERRSTR_L,            "fs_attr_run: error adding aditional run: %" PRIuDADDR            ", Previous %" PRIuDADDR " -> %" PRIuDADDR "   Current %"            PRIuDADDR " -> %" PRIuDADDR "\n", a_data_run_new->offset,            data_run_prev->addr, data_run_prev->len, a_data_run_new->addr,            a_data_run_new->len);        return 1;    }    /* we should add it right here */    else if (((data_run_prev)            && (data_run_prev->offset + data_run_prev->len ==                a_data_run_new->offset))        || (a_data_run_new->offset == 0)) {        if (data_run_prev)            data_run_prev->next = a_data_run_new;        else            a_fs_attr->nrd.run = a_data_run_new;    }    /* we need to make a filler before it */    else {        TSK_FS_ATTR_RUN *tmprun = tsk_fs_attr_run_alloc();        if (tmprun == NULL)            return 1;        if (data_run_prev) {            data_run_prev->next = tmprun;            tmprun->offset = data_run_prev->offset + data_run_prev->len;        }        else {            a_fs_attr->nrd.run = tmprun;        }        tmprun->len = a_data_run_new->offset - tmprun->offset;        tmprun->flags = TSK_FS_ATTR_RUN_FLAG_FILLER;        tmprun->next = a_data_run_new;        /* Adjust the length of the TSK_FS_ATTR structure to reflect the          * new FILLER run         */        a_fs_attr->nrd.initsize += (tmprun->len * a_fs->block_size);    }    /* Adjust the length of the TSK_FS_ATTR structure to reflect the      * new run     */    a_fs_attr->nrd.initsize += (run_len * a_fs->block_size);    // update the pointer to the end of the list    a_fs_attr->nrd.run_end = a_data_run_new;    while (a_fs_attr->nrd.run_end->next)        a_fs_attr->nrd.run_end = a_fs_attr->nrd.run_end->next;    return 0;}/** * Append a data run to the end of the attribute and update its offset * value.  This ignores the offset in the data run and blindly appends. * * @param a_fs File system run is from * @param a_fs_attr Data attribute to append to * @param a_data_run Data run to append. */voidtsk_fs_attr_append_run(TSK_FS_INFO * a_fs, TSK_FS_ATTR * a_fs_attr,    TSK_FS_ATTR_RUN * a_data_run){    TSK_FS_ATTR_RUN *data_run_cur;    if ((a_fs_attr == NULL) || (a_data_run == NULL)) {        return;    }    if (a_fs_attr->nrd.run == NULL) {        a_fs_attr->nrd.run = a_data_run;        a_data_run->offset = 0;    }    else {        // just in case this was not updated        if ((a_fs_attr->nrd.run_end == NULL)            || (a_fs_attr->nrd.run_end->next != NULL)) {            data_run_cur = a_fs_attr->nrd.run;            while (data_run_cur->next) {                data_run_cur = data_run_cur->next;            }            a_fs_attr->nrd.run_end = data_run_cur;        }        a_fs_attr->nrd.run_end->next = a_data_run;        a_data_run->offset =            a_fs_attr->nrd.run_end->offset + a_fs_attr->nrd.run_end->len;    }    // update the rest of the offsets in the run (if any exist)    data_run_cur = a_data_run;    a_fs_attr->nrd.initsize += (data_run_cur->len * a_fs->block_size);    while (data_run_cur->next) {        data_run_cur->next->offset =            data_run_cur->offset + data_run_cur->len;        a_fs_attr->nrd.initsize +=            (data_run_cur->next->len * a_fs->block_size);        a_fs_attr->nrd.run_end = data_run_cur->next;        data_run_cur = data_run_cur->next;    }}/** \internal * Processes a resident TSK_FS_ATTR structure and calls the callback with the associated * data. The size of the buffer in the callback will be block_size at max.  * * @param a_fs File system being analyzed * @param fs_attr Resident data structure to be walked * @param a_flags Flags for walking * @param a_action Callback action * @param a_ptr Pointer to data that is passed to callback * @returns 1 on error or 0 on success */static uint8_ttsk_fs_attr_walk_res(const TSK_FS_ATTR * fs_attr,    TSK_FS_FILE_WALK_FLAG_ENUM a_flags, TSK_FS_FILE_WALK_CB a_action,    void *a_ptr){    char *buf = NULL;    int myflags;    int retval;    size_t buf_len = 0;    TSK_OFF_T off;    size_t read_len;    TSK_FS_INFO *fs;    fs = fs_attr->fs_file->fs_info;    if ((fs_attr->flags & TSK_FS_ATTR_RES) == 0) {        tsk_errno = TSK_ERR_FS_ARG;        snprintf(tsk_errstr, TSK_ERRSTR_L,            "tsk_fs_file_walk_res: called with non-resident data");        return 1;    }    /* Allocate a buffer that is at most a block size in length */    if ((a_flags & TSK_FS_FILE_WALK_FLAG_AONLY) == 0) {        buf_len = (size_t) fs_attr->size;        if (buf_len > fs->block_size)            buf_len = fs->block_size;        if ((buf = tsk_malloc(buf_len)) == NULL) {            return 1;        }    }    myflags =        TSK_FS_BLOCK_FLAG_CONT | TSK_FS_BLOCK_FLAG_ALLOC |        TSK_FS_BLOCK_FLAG_RES;    // Call the callback in (at max) block-sized chunks.    retval = TSK_WALK_CONT;    for (off = 0; off < fs_attr->size; off += read_len) {        if (fs_attr->size - off > buf_len)            read_len = buf_len;        else            read_len = (size_t) (fs_attr->size - off);        if (buf) {            // wipe rest of buffer if we are not going to read into all of it            if (read_len != buf_len)                memset(&buf[read_len], 0, buf_len - read_len);            memcpy(buf, &fs_attr->rd.buf[off], read_len);        }        retval =            a_action(fs_attr->fs_file, off, 0, buf, read_len, myflags,            a_ptr);        if (retval != TSK_WALK_CONT)            break;    }    if (buf)        free(buf);    if (retval == TSK_WALK_ERROR)        return 1;    else        return 0;}/** \internal * Processes a non-resident TSK_FS_ATTR structure and calls the callback with the associated * data.  * * @param fs_attr Resident data structure to be walked * @param a_flags Flags for walking * @param a_action Callback action * @param a_ptr Pointer to data that is passed to callback * @returns 1 on error or 0 on success */static uint8_ttsk_fs_attr_walk_nonres(const TSK_FS_ATTR * fs_attr,    TSK_FS_FILE_WALK_FLAG_ENUM a_flags, TSK_FS_FILE_WALK_CB a_action,    void *a_ptr){    char *buf = NULL;    TSK_OFF_T tot_size;    TSK_OFF_T off = 0;    TSK_FS_ATTR_RUN *fs_attr_run;    int retval;    uint32_t skip_remain;    TSK_FS_INFO *fs = fs_attr->fs_file->fs_info;    uint8_t stop_loop = 0;    if ((fs_attr->flags & TSK_FS_ATTR_NONRES) == 0) {        tsk_errno = TSK_ERR_FS_ARG;        snprintf(tsk_errstr, TSK_ERRSTR_L,            "tsk_fs_file_walk_nonres: called with non-non-resident data");        return 1;    }    /* if we want the slack space too, then use the allocsize  */    if (a_flags & TSK_FS_FILE_WALK_FLAG_SLACK)        tot_size = fs_attr->nrd.allocsize;    else        tot_size = fs_attr->size;    skip_remain = fs_attr->nrd.skiplen;    if ((a_flags & TSK_FS_FILE_WALK_FLAG_AONLY) == 0) {        if ((buf = (char *) tsk_malloc(fs->block_size)) == NULL) {            return 1;        }    }    /* cycle through the number of runs we have */    retval = TSK_WALK_CONT;

⌨️ 快捷键说明

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