static int dmg_open(BlockDriverState *bs, QDict *options, int flags,
                    Error **errp)
{
    BDRVDMGState *s = bs->opaque;
    uint64_t info_begin, info_end, last_in_offset, last_out_offset;
    uint32_t count, tmp;
    uint32_t max_compressed_size = 1, max_sectors_per_chunk = 1, i;
    int64_t offset;
    int ret;
    bs->read_only = 1;
    s->n_chunks = 0;
    s->offsets = s->lengths = s->sectors = s->sectorcounts = NULL;
    /* read offset of info blocks */
    offset = bdrv_getlength(bs->file);
    if (offset < 0) {
        ret = offset;
    offset -= 0x1d8;
    ret = read_uint64(bs, offset, &info_begin);
    if (ret < 0) {
    } else if (info_begin == 0) {
    ret = read_uint32(bs, info_begin, &tmp);
    if (ret < 0) {
    } else if (tmp != 0x100) {
    ret = read_uint32(bs, info_begin + 4, &count);
    if (ret < 0) {
    } else if (count == 0) {
    info_end = info_begin + count;
    offset = info_begin + 0x100;
    /* read offsets */
    last_in_offset = last_out_offset = 0;
    while (offset < info_end) {
        uint32_t type;
        ret = read_uint32(bs, offset, &count);
        if (ret < 0) {
        } else if (count == 0) {
        offset += 4;
        ret = read_uint32(bs, offset, &type);
        if (ret < 0) {
        if (type == 0x6d697368 && count >= 244) {
            size_t new_size;
            uint32_t chunk_count;
            offset += 4;
            offset += 200;
            chunk_count = (count - 204) / 40;
            new_size = sizeof(uint64_t) * (s->n_chunks + chunk_count);
            s->types = g_realloc(s->types, new_size / 2);
            s->offsets = g_realloc(s->offsets, new_size);
            s->lengths = g_realloc(s->lengths, new_size);
            s->sectors = g_realloc(s->sectors, new_size);
            s->sectorcounts = g_realloc(s->sectorcounts, new_size);
            for (i = s->n_chunks; i < s->n_chunks + chunk_count; i++) {
                ret = read_uint32(bs, offset, &s->types[i]);
                if (ret < 0) {
                offset += 4;
                if (s->types[i] != 0x80000005 && s->types[i] != 1 &&
                    s->types[i] != 2) {
                    if (s->types[i] == 0xffffffff && i > 0) {
                        last_in_offset = s->offsets[i - 1] + s->lengths[i - 1];
                        last_out_offset = s->sectors[i - 1] +
                                          s->sectorcounts[i - 1];
                    chunk_count--;
                    i--;
                    offset += 36;
                    continue;
                offset += 4;
                ret = read_uint64(bs, offset, &s->sectors[i]);
                if (ret < 0) {
                s->sectors[i] += last_out_offset;
                offset += 8;
                ret = read_uint64(bs, offset, &s->sectorcounts[i]);
                if (ret < 0) {
                offset += 8;
                if (s->sectorcounts[i] > DMG_SECTORCOUNTS_MAX) {
                    error_report("sector count %" PRIu64 " for chunk %u is "
                                 "larger than max (%u)",
                                 s->sectorcounts[i], i, DMG_SECTORCOUNTS_MAX);
                ret = read_uint64(bs, offset, &s->offsets[i]);
                if (ret < 0) {
                s->offsets[i] += last_in_offset;
                offset += 8;
                ret = read_uint64(bs, offset, &s->lengths[i]);
                if (ret < 0) {
                offset += 8;
                if (s->lengths[i] > max_compressed_size) {
                    max_compressed_size = s->lengths[i];
                if (s->sectorcounts[i] > max_sectors_per_chunk) {
                    max_sectors_per_chunk = s->sectorcounts[i];
            s->n_chunks += chunk_count;
    /* initialize zlib engine */
    s->compressed_chunk = g_malloc(max_compressed_size + 1);
    s->uncompressed_chunk = g_malloc(512 * max_sectors_per_chunk);
    if (inflateInit(&s->zstream) != Z_OK) {
    s->current_chunk = s->n_chunks;
    qemu_co_mutex_init(&s->lock);
    return 0;
fail:
    g_free(s->types);
    g_free(s->offsets);
    g_free(s->lengths);
    g_free(s->sectors);
    g_free(s->sectorcounts);
    g_free(s->compressed_chunk);
    g_free(s->uncompressed_chunk);
    return ret;
static int dmg_open(BlockDriverState *bs, QDict *options, int flags,
                    Error **errp)
{
    BDRVDMGState *s = bs->opaque;
    uint64_t info_begin, info_end, last_in_offset, last_out_offset;
    uint32_t count, tmp;
    uint32_t max_compressed_size = 1, max_sectors_per_chunk = 1, i;
    int64_t offset;
    int ret;
    bs->read_only = 1;
    s->n_chunks = 0;
    s->offsets = s->lengths = s->sectors = s->sectorcounts = NULL;
    
    offset = bdrv_getlength(bs->file);
    if (offset < 0) {
        ret = offset;
    offset -= 0x1d8;
    ret = read_uint64(bs, offset, &info_begin);
    if (ret < 0) {
    } else if (info_begin == 0) {
    ret = read_uint32(bs, info_begin, &tmp);
    if (ret < 0) {
    } else if (tmp != 0x100) {
    ret = read_uint32(bs, info_begin + 4, &count);
    if (ret < 0) {
    } else if (count == 0) {
    info_end = info_begin + count;
    offset = info_begin + 0x100;
    
    last_in_offset = last_out_offset = 0;
    while (offset < info_end) {
        uint32_t type;
        ret = read_uint32(bs, offset, &count);
        if (ret < 0) {
        } else if (count == 0) {
        offset += 4;
        ret = read_uint32(bs, offset, &type);
        if (ret < 0) {
        if (type == 0x6d697368 && count >= 244) {
            size_t new_size;
            uint32_t chunk_count;
            offset += 4;
            offset += 200;
            chunk_count = (count - 204) / 40;
            new_size = sizeof(uint64_t) * (s->n_chunks + chunk_count);
            s->types = g_realloc(s->types, new_size / 2);
            s->offsets = g_realloc(s->offsets, new_size);
            s->lengths = g_realloc(s->lengths, new_size);
            s->sectors = g_realloc(s->sectors, new_size);
            s->sectorcounts = g_realloc(s->sectorcounts, new_size);
            for (i = s->n_chunks; i < s->n_chunks + chunk_count; i++) {
                ret = read_uint32(bs, offset, &s->types[i]);
                if (ret < 0) {
                offset += 4;
                if (s->types[i] != 0x80000005 && s->types[i] != 1 &&
                    s->types[i] != 2) {
                    if (s->types[i] == 0xffffffff && i > 0) {
                        last_in_offset = s->offsets[i - 1] + s->lengths[i - 1];
                        last_out_offset = s->sectors[i - 1] +
                                          s->sectorcounts[i - 1];
                    chunk_count--;
                    i--;
                    offset += 36;
                    continue;
                offset += 4;
                ret = read_uint64(bs, offset, &s->sectors[i]);
                if (ret < 0) {
                s->sectors[i] += last_out_offset;
                offset += 8;
                ret = read_uint64(bs, offset, &s->sectorcounts[i]);
                if (ret < 0) {
                offset += 8;
                if (s->sectorcounts[i] > DMG_SECTORCOUNTS_MAX) {
                    error_report("sector count %" PRIu64 " for chunk %u is "
                                 "larger than max (%u)",
                                 s->sectorcounts[i], i, DMG_SECTORCOUNTS_MAX);
                ret = read_uint64(bs, offset, &s->offsets[i]);
                if (ret < 0) {
                s->offsets[i] += last_in_offset;
                offset += 8;
                ret = read_uint64(bs, offset, &s->lengths[i]);
                if (ret < 0) {
                offset += 8;
                if (s->lengths[i] > max_compressed_size) {
                    max_compressed_size = s->lengths[i];
                if (s->sectorcounts[i] > max_sectors_per_chunk) {
                    max_sectors_per_chunk = s->sectorcounts[i];
            s->n_chunks += chunk_count;
    
    s->compressed_chunk = g_malloc(max_compressed_size + 1);
    s->uncompressed_chunk = g_malloc(512 * max_sectors_per_chunk);
    if (inflateInit(&s->zstream) != Z_OK) {
    s->current_chunk = s->n_chunks;
    qemu_co_mutex_init(&s->lock);
    return 0;
fail:
    g_free(s->types);
    g_free(s->offsets);
    g_free(s->lengths);
    g_free(s->sectors);
    g_free(s->sectorcounts);
    g_free(s->compressed_chunk);
    g_free(s->uncompressed_chunk);
    return ret;
static int FUNC_0(BlockDriverState *VAR_0, QDict *VAR_1, int VAR_2,
                    Error **VAR_3)
{
    BDRVDMGState *s = VAR_0->opaque;
    uint64_t info_begin, info_end, last_in_offset, last_out_offset;
    uint32_t count, tmp;
    uint32_t max_compressed_size = 1, max_sectors_per_chunk = 1, i;
    int64_t offset;
    int VAR_4;
    VAR_0->read_only = 1;
    s->n_chunks = 0;
    s->offsets = s->lengths = s->sectors = s->sectorcounts = NULL;
    
    offset = bdrv_getlength(VAR_0->file);
    if (offset < 0) {
        VAR_4 = offset;
    offset -= 0x1d8;
    VAR_4 = read_uint64(VAR_0, offset, &info_begin);
    if (VAR_4 < 0) {
    } else if (info_begin == 0) {
    VAR_4 = read_uint32(VAR_0, info_begin, &tmp);
    if (VAR_4 < 0) {
    } else if (tmp != 0x100) {
    VAR_4 = read_uint32(VAR_0, info_begin + 4, &count);
    if (VAR_4 < 0) {
    } else if (count == 0) {
    info_end = info_begin + count;
    offset = info_begin + 0x100;
    
    last_in_offset = last_out_offset = 0;
    while (offset < info_end) {
        uint32_t type;
        VAR_4 = read_uint32(VAR_0, offset, &count);
        if (VAR_4 < 0) {
        } else if (count == 0) {
        offset += 4;
        VAR_4 = read_uint32(VAR_0, offset, &type);
        if (VAR_4 < 0) {
        if (type == 0x6d697368 && count >= 244) {
            size_t new_size;
            uint32_t chunk_count;
            offset += 4;
            offset += 200;
            chunk_count = (count - 204) / 40;
            new_size = sizeof(uint64_t) * (s->n_chunks + chunk_count);
            s->types = g_realloc(s->types, new_size / 2);
            s->offsets = g_realloc(s->offsets, new_size);
            s->lengths = g_realloc(s->lengths, new_size);
            s->sectors = g_realloc(s->sectors, new_size);
            s->sectorcounts = g_realloc(s->sectorcounts, new_size);
            for (i = s->n_chunks; i < s->n_chunks + chunk_count; i++) {
                VAR_4 = read_uint32(VAR_0, offset, &s->types[i]);
                if (VAR_4 < 0) {
                offset += 4;
                if (s->types[i] != 0x80000005 && s->types[i] != 1 &&
                    s->types[i] != 2) {
                    if (s->types[i] == 0xffffffff && i > 0) {
                        last_in_offset = s->offsets[i - 1] + s->lengths[i - 1];
                        last_out_offset = s->sectors[i - 1] +
                                          s->sectorcounts[i - 1];
                    chunk_count--;
                    i--;
                    offset += 36;
                    continue;
                offset += 4;
                VAR_4 = read_uint64(VAR_0, offset, &s->sectors[i]);
                if (VAR_4 < 0) {
                s->sectors[i] += last_out_offset;
                offset += 8;
                VAR_4 = read_uint64(VAR_0, offset, &s->sectorcounts[i]);
                if (VAR_4 < 0) {
                offset += 8;
                if (s->sectorcounts[i] > DMG_SECTORCOUNTS_MAX) {
                    error_report("sector count %" PRIu64 " for chunk %u is "
                                 "larger than max (%u)",
                                 s->sectorcounts[i], i, DMG_SECTORCOUNTS_MAX);
                VAR_4 = read_uint64(VAR_0, offset, &s->offsets[i]);
                if (VAR_4 < 0) {
                s->offsets[i] += last_in_offset;
                offset += 8;
                VAR_4 = read_uint64(VAR_0, offset, &s->lengths[i]);
                if (VAR_4 < 0) {
                offset += 8;
                if (s->lengths[i] > max_compressed_size) {
                    max_compressed_size = s->lengths[i];
                if (s->sectorcounts[i] > max_sectors_per_chunk) {
                    max_sectors_per_chunk = s->sectorcounts[i];
            s->n_chunks += chunk_count;
    
    s->compressed_chunk = g_malloc(max_compressed_size + 1);
    s->uncompressed_chunk = g_malloc(512 * max_sectors_per_chunk);
    if (inflateInit(&s->zstream) != Z_OK) {
    s->current_chunk = s->n_chunks;
    qemu_co_mutex_init(&s->lock);
    return 0;
fail:
    g_free(s->types);
    g_free(s->offsets);
    g_free(s->lengths);
    g_free(s->sectors);
    g_free(s->sectorcounts);
    g_free(s->compressed_chunk);
    g_free(s->uncompressed_chunk);
    return VAR_4;
static int FUNC_0(BlockDriverState *VAR_0, QDict *VAR_1, int VAR_2,
Error **VAR_3)
{ BDRVDMGState *s = VAR_0->opaque; uint64_t info_begin, info_end, last_in_offset, last_out_offset; uint32_t count, tmp; uint32_t max_compressed_size = 1, max_sectors_per_chunk = 1, i; int64_t offset; int VAR_4; VAR_0->read_only = 1; s->n_chunks = 0; s->offsets = s->lengths = s->sectors = s->sectorcounts = NULL; offset = bdrv_getlength(VAR_0->file); if (offset < 0) { VAR_4 = offset; offset -= 0x1d8; VAR_4 = read_uint64(VAR_0, offset, &info_begin); if (VAR_4 < 0) { } else if (info_begin == 0) { VAR_4 = read_uint32(VAR_0, info_begin, &tmp); if (VAR_4 < 0) { } else if (tmp != 0x100) { VAR_4 = read_uint32(VAR_0, info_begin + 4, &count); if (VAR_4 < 0) { } else if (count == 0) { info_end = info_begin + count; offset = info_begin + 0x100; last_in_offset = last_out_offset = 0; while (offset < info_end) { uint32_t type; VAR_4 = read_uint32(VAR_0, offset, &count); if (VAR_4 < 0) { } else if (count == 0) { offset += 4; VAR_4 = read_uint32(VAR_0, offset, &type); if (VAR_4 < 0) { if (type == 0x6d697368 && count >= 244) { size_t new_size; uint32_t chunk_count; offset += 4; offset += 200; chunk_count = (count - 204) / 40; new_size = sizeof(uint64_t) * (s->n_chunks + chunk_count); s->types = g_realloc(s->types, new_size / 2); s->offsets = g_realloc(s->offsets, new_size); s->lengths = g_realloc(s->lengths, new_size); s->sectors = g_realloc(s->sectors, new_size); s->sectorcounts = g_realloc(s->sectorcounts, new_size); for (i = s->n_chunks; i < s->n_chunks + chunk_count; i++) { VAR_4 = read_uint32(VAR_0, offset, &s->types[i]); if (VAR_4 < 0) { offset += 4; if (s->types[i] != 0x80000005 && s->types[i] != 1 &&
s->types[i] != 2) { if (s->types[i] == 0xffffffff && i > 0) { last_in_offset = s->offsets[i - 1] + s->lengths[i - 1]; last_out_offset = s->sectors[i - 1] +
s->sectorcounts[i - 1]; chunk_count--; i--; offset += 36; continue; offset += 4; VAR_4 = read_uint64(VAR_0, offset, &s->sectors[i]); if (VAR_4 < 0) { s->sectors[i] += last_out_offset; offset += 8; VAR_4 = read_uint64(VAR_0, offset, &s->sectorcounts[i]); if (VAR_4 < 0) { offset += 8; if (s->sectorcounts[i] > DMG_SECTORCOUNTS_MAX) { error_report("sector count %" PRIu64 " for chunk %u is "
"larger than max (%u)",
s->sectorcounts[i], i, DMG_SECTORCOUNTS_MAX); VAR_4 = read_uint64(VAR_0, offset, &s->offsets[i]); if (VAR_4 < 0) { s->offsets[i] += last_in_offset; offset += 8; VAR_4 = read_uint64(VAR_0, offset, &s->lengths[i]); if (VAR_4 < 0) { offset += 8; if (s->lengths[i] > max_compressed_size) { max_compressed_size = s->lengths[i]; if (s->sectorcounts[i] > max_sectors_per_chunk) { max_sectors_per_chunk = s->sectorcounts[i]; s->n_chunks += chunk_count; s->compressed_chunk = g_malloc(max_compressed_size + 1); s->uncompressed_chunk = g_malloc(512 * max_sectors_per_chunk); if (inflateInit(&s->zstream) != Z_OK) { s->current_chunk = s->n_chunks; qemu_co_mutex_init(&s->lock); return 0; fail:
g_free(s->types); g_free(s->offsets); g_free(s->lengths); g_free(s->sectors); g_free(s->sectorcounts); g_free(s->compressed_chunk); g_free(s->uncompressed_chunk); return VAR_4;