Esempio n. 1
0
/**
 * \ingroup fslib
 * Get the contents and flags of a specific file system block. Note that if the block contains
 * compressed data, then this function will return the compressed data with the RAW flag set. 
 * The uncompressed data can be obtained only from the file-level functions.
 *
 * @param a_fs The file system to read the block from.
 * @param a_fs_block The structure to write the block data into or NULL to have one created.
 * @param a_addr The file system address to read.
 * @param a_flags Flag to assign to the returned TSK_FS_BLOCK (use if you already have it as part of a block_walk-type scenario)
 * @return The TSK_FS_BLOCK with the data or NULL on error.  (If a_fs_block was not NULL, this will
 * be the same structure). 
 */
TSK_FS_BLOCK *
tsk_fs_block_get_flag(TSK_FS_INFO * a_fs, TSK_FS_BLOCK * a_fs_block,
    TSK_DADDR_T a_addr, TSK_FS_BLOCK_FLAG_ENUM a_flags)
{
    TSK_OFF_T offs;
    size_t len;

    if (a_fs == NULL) {
        tsk_error_reset();
        tsk_error_set_errno(TSK_ERR_FS_READ);
        tsk_error_set_errstr("tsk_fs_block_get: fs unallocated");
        return NULL;
    }
    if (a_fs_block == NULL) {
        a_fs_block = tsk_fs_block_alloc(a_fs);
    }
    else if ((a_fs_block->tag != TSK_FS_BLOCK_TAG)
        || (a_fs_block->buf == NULL)) {
        tsk_error_reset();
        tsk_error_set_errno(TSK_ERR_FS_READ);
        tsk_error_set_errstr("tsk_fs_block_get: fs_block unallocated");
        return NULL;
    }

    len = a_fs->block_size;

    if (a_addr > a_fs->last_block_act) {
        tsk_error_reset();
        tsk_error_set_errno(TSK_ERR_FS_READ);
        if (a_addr <= a_fs->last_block)
            tsk_error_set_errstr
                ("tsk_fs_block_get: Address missing in partial image: %"
                PRIuDADDR ")", a_addr);
        else
            tsk_error_set_errstr
                ("tsk_fs_block_get: Address is too large for image: %"
                PRIuDADDR ")", a_addr);
        return NULL;
    }

    a_fs_block->fs_info = a_fs;
    a_fs_block->addr = a_addr;
    a_fs_block->flags = a_flags;
    a_fs_block->flags |= TSK_FS_BLOCK_FLAG_RAW;
    offs = (TSK_OFF_T) a_addr *a_fs->block_size;

    if ((a_fs_block->flags & TSK_FS_BLOCK_FLAG_AONLY) == 0) {
        ssize_t cnt;
        cnt =
            tsk_img_read(a_fs->img_info, a_fs->offset + offs,
            a_fs_block->buf, len);
        if (cnt != (ssize_t)len) {
            return NULL;
        }
    }
    return a_fs_block;
}
Esempio n. 2
0
/** \internal
 *
 * return 1 on error and 0 on success
 */
uint8_t
tsk_fs_nofs_block_walk(TSK_FS_INFO * fs, TSK_DADDR_T a_start_blk,
    TSK_DADDR_T a_end_blk, TSK_FS_BLOCK_WALK_FLAG_ENUM a_flags,
    TSK_FS_BLOCK_WALK_CB a_action, void *a_ptr)
{
    TSK_FS_BLOCK *fs_block;
    TSK_DADDR_T addr;

    // clean up any error messages that are lying around
    tsk_error_reset();

    /*
     * Sanity checks.
     */
    if (a_start_blk < fs->first_block || a_start_blk > fs->last_block) {
        tsk_error_reset();
        tsk_error_set_errno(TSK_ERR_FS_WALK_RNG);
        tsk_error_set_errstr("nofs_block_walk: Start block number: %"
            PRIuDADDR, a_start_blk);
        return 1;
    }

    if (a_end_blk < fs->first_block || a_end_blk > fs->last_block
        || a_end_blk < a_start_blk) {
        tsk_error_reset();
        tsk_error_set_errno(TSK_ERR_FS_WALK_RNG);
        tsk_error_set_errstr("nofs_block_walk: Last block number: %"
            PRIuDADDR, a_end_blk);
        return 1;
    }

    /* 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);
    }

    /* All swap has is allocated blocks... exit if not wanted */
    if (!(a_flags & TSK_FS_BLOCK_FLAG_ALLOC)) {
        return 0;
    }

    if ((fs_block = tsk_fs_block_alloc(fs)) == NULL) {
        return 1;
    }

    for (addr = a_start_blk; addr <= a_end_blk; addr++) {
        int retval;

        if (tsk_fs_block_get(fs, fs_block, addr) == NULL) {
            tsk_error_set_errstr2("nofs_block_walk: Block %" PRIuDADDR,
                addr);
            tsk_fs_block_free(fs_block);
            return 1;
        }

        retval = a_action(fs_block, a_ptr);
        if (retval == TSK_WALK_STOP) {
            break;
        }
        else if (retval == TSK_WALK_ERROR) {
            tsk_fs_block_free(fs_block);
            return 1;
        }
    }

    /*
     * Cleanup.
     */
    tsk_fs_block_free(fs_block);
    return 0;
}