Beispiel #1
0
static int cloop_open(BlockDriverState *bs, const char *filename, int flags)
{
    BDRVCloopState *s = bs->opaque;
    uint32_t offsets_size,max_compressed_block_size=1,i;

    s->fd = open(filename, O_RDONLY | O_BINARY);
    if (s->fd < 0)
        return -errno;
    bs->read_only = 1;

    /* read header */
    if(lseek(s->fd,128,SEEK_SET)<0) {
cloop_close:
	close(s->fd);
	return -1;
    }
    if(qemu_read_ok(s->fd,&s->block_size,4)<0)
	goto cloop_close;
    s->block_size=be32_to_cpu(s->block_size);
    if(qemu_read_ok(s->fd,&s->n_blocks,4)<0)
	goto cloop_close;
    s->n_blocks=be32_to_cpu(s->n_blocks);

    /* read offsets */
    offsets_size=s->n_blocks*sizeof(uint64_t);
    if(!(s->offsets=(uint64_t*)malloc(offsets_size)))
	goto cloop_close;
    if(qemu_read_ok(s->fd,s->offsets,offsets_size)<0)
	goto cloop_close;
    for(i=0;i<s->n_blocks;i++) {
	s->offsets[i]=be64_to_cpu(s->offsets[i]);
	if(i>0) {
	    uint32_t size=s->offsets[i]-s->offsets[i-1];
	    if(size>max_compressed_block_size)
		max_compressed_block_size=size;
	}
    }

    /* initialize zlib engine */
    if(!(s->compressed_block = malloc(max_compressed_block_size+1)))
	goto cloop_close;
    if(!(s->uncompressed_block = malloc(s->block_size)))
	goto cloop_close;
    if(inflateInit(&s->zstream) != Z_OK)
	goto cloop_close;
    s->current_block=s->n_blocks;

    s->sectors_per_block = s->block_size/512;
    bs->total_sectors = s->n_blocks*s->sectors_per_block;
    return 0;
}
Beispiel #2
0
static inline int cloop_read_block(BDRVCloopState *s,int block_num)
{
    if(s->current_block != block_num) {
	int ret;
        uint32_t bytes = s->offsets[block_num+1]-s->offsets[block_num];

	lseek(s->fd, s->offsets[block_num], SEEK_SET);
        ret = qemu_read_ok(s->fd, s->compressed_block, bytes);
        if (ret < 0)
            return -1;

	s->zstream.next_in = s->compressed_block;
	s->zstream.avail_in = bytes;
	s->zstream.next_out = s->uncompressed_block;
	s->zstream.avail_out = s->block_size;
	ret = inflateReset(&s->zstream);
	if(ret != Z_OK)
	    return -1;
	ret = inflate(&s->zstream, Z_FINISH);
	if(ret != Z_STREAM_END || s->zstream.total_out != s->block_size)
	    return -1;

	s->current_block = block_num;
    }
    return 0;
}
Beispiel #3
0
static off_t read_off(int fd)
{
	uint64_t buffer;
	if(qemu_read_ok(fd,&buffer,8)<0)
		return 0;
	return be64_to_cpu(buffer);
}
Beispiel #4
0
static off_t read_uint32(int fd)
{
	uint32_t buffer;
	if(qemu_read_ok(fd,&buffer,4)<0)
		return 0;
	return be32_to_cpu(buffer);
}
Beispiel #5
0
static inline int dmg_read_chunk(BDRVDMGState *s,int sector_num)
{
    if(!is_sector_in_chunk(s,s->current_chunk,sector_num)) {
	int ret;
	uint32_t chunk = search_chunk(s,sector_num);

	if(chunk>=s->n_chunks)
	    return -1;

	s->current_chunk = s->n_chunks;
	switch(s->types[chunk]) {
	case 0x80000005: { /* zlib compressed */
	    ret = lseek(s->fd, s->offsets[chunk], SEEK_SET);
	    if(ret<0)
		return -1;

	    /* we need to buffer, because only the chunk as whole can be
	     * inflated. */
	    ret = qemu_read_ok(s->fd, s->compressed_chunk, s->lengths[chunk]);
	    if (ret < 0)
	        return -1;

	    s->zstream.next_in = s->compressed_chunk;
	    s->zstream.avail_in = s->lengths[chunk];
	    s->zstream.next_out = s->uncompressed_chunk;
	    s->zstream.avail_out = 512*s->sectorcounts[chunk];
	    ret = inflateReset(&s->zstream);
	    if(ret != Z_OK)
		return -1;
	    ret = inflate(&s->zstream, Z_FINISH);
	    if(ret != Z_STREAM_END || s->zstream.total_out != 512*s->sectorcounts[chunk])
		return -1;
	    break; }
	case 1: /* copy */
	    ret = qemu_read_ok(s->fd, s->uncompressed_chunk, s->lengths[chunk]);
	    if (ret < 0)
		return -1;
	    break;
	case 2: /* zero */
	    memset(s->uncompressed_chunk, 0, 512*s->sectorcounts[chunk]);
	    break;
	}
	s->current_chunk = chunk;
    }
    return 0;
}