static int vmdk_open(BlockDriverState *bs, const char *filename, int flags)

{

    BDRVVmdkState *s = bs->opaque;

    uint32_t magic;

    int l1_size, i, ret;



    if (parent_open)

        // Parent must be opened as RO.

        flags = BDRV_O_RDONLY;

    fprintf(stderr, "(VMDK) image open: flags=0x%x filename=%s\n", flags, bs->filename);



    ret = bdrv_file_open(&s->hd, filename, flags | BDRV_O_AUTOGROW);

    if (ret < 0)

        return ret;

    if (bdrv_pread(s->hd, 0, &magic, sizeof(magic)) != sizeof(magic))

        goto fail;



    magic = be32_to_cpu(magic);

    if (magic == VMDK3_MAGIC) {

        VMDK3Header header;



        if (bdrv_pread(s->hd, sizeof(magic), &header, sizeof(header)) != sizeof(header))

            goto fail;

        s->cluster_sectors = le32_to_cpu(header.granularity);

        s->l2_size = 1 << 9;

        s->l1_size = 1 << 6;

        bs->total_sectors = le32_to_cpu(header.disk_sectors);

        s->l1_table_offset = le32_to_cpu(header.l1dir_offset) << 9;

        s->l1_backup_table_offset = 0;

        s->l1_entry_sectors = s->l2_size * s->cluster_sectors;

    } else if (magic == VMDK4_MAGIC) {

        VMDK4Header header;



        if (bdrv_pread(s->hd, sizeof(magic), &header, sizeof(header)) != sizeof(header))

            goto fail;

        bs->total_sectors = le64_to_cpu(header.capacity);

        s->cluster_sectors = le64_to_cpu(header.granularity);

        s->l2_size = le32_to_cpu(header.num_gtes_per_gte);

        s->l1_entry_sectors = s->l2_size * s->cluster_sectors;

        if (s->l1_entry_sectors <= 0)

            goto fail;

        s->l1_size = (bs->total_sectors + s->l1_entry_sectors - 1)

            / s->l1_entry_sectors;

        s->l1_table_offset = le64_to_cpu(header.rgd_offset) << 9;

        s->l1_backup_table_offset = le64_to_cpu(header.gd_offset) << 9;



        if (parent_open)

            s->is_parent = 1;

        else

            s->is_parent = 0;



        // try to open parent images, if exist

        if (vmdk_parent_open(bs, filename) != 0)

            goto fail;

        // write the CID once after the image creation

        s->parent_cid = vmdk_read_cid(bs,1);

    } else {

        goto fail;

    }



    /* read the L1 table */

    l1_size = s->l1_size * sizeof(uint32_t);

    s->l1_table = qemu_malloc(l1_size);

    if (!s->l1_table)

        goto fail;

    if (bdrv_pread(s->hd, s->l1_table_offset, s->l1_table, l1_size) != l1_size)

        goto fail;

    for(i = 0; i < s->l1_size; i++) {

        le32_to_cpus(&s->l1_table[i]);

    }



    if (s->l1_backup_table_offset) {

        s->l1_backup_table = qemu_malloc(l1_size);

        if (!s->l1_backup_table)

            goto fail;

        if (bdrv_pread(s->hd, s->l1_backup_table_offset, s->l1_backup_table, l1_size) != l1_size)

            goto fail;

        for(i = 0; i < s->l1_size; i++) {

            le32_to_cpus(&s->l1_backup_table[i]);

        }

    }



    s->l2_cache = qemu_malloc(s->l2_size * L2_CACHE_SIZE * sizeof(uint32_t));

    if (!s->l2_cache)

        goto fail;

    return 0;

 fail:

    qemu_free(s->l1_backup_table);

    qemu_free(s->l1_table);

    qemu_free(s->l2_cache);

    bdrv_delete(s->hd);

    return -1;

}

static int vmdk_open(BlockDriverState *bs, const char *filename, int flags)

{

    BDRVVmdkState *s = bs->opaque;

    uint32_t magic;

    int l1_size, i, ret;



    if (parent_open)

        

        flags = BDRV_O_RDONLY;

    fprintf(stderr, "(VMDK) image open: flags=0x%x filename=%s\n", flags, bs->filename);



    ret = bdrv_file_open(&s->hd, filename, flags | BDRV_O_AUTOGROW);

    if (ret < 0)

        return ret;

    if (bdrv_pread(s->hd, 0, &magic, sizeof(magic)) != sizeof(magic))

        goto fail;



    magic = be32_to_cpu(magic);

    if (magic == VMDK3_MAGIC) {

        VMDK3Header header;



        if (bdrv_pread(s->hd, sizeof(magic), &header, sizeof(header)) != sizeof(header))

            goto fail;

        s->cluster_sectors = le32_to_cpu(header.granularity);

        s->l2_size = 1 << 9;

        s->l1_size = 1 << 6;

        bs->total_sectors = le32_to_cpu(header.disk_sectors);

        s->l1_table_offset = le32_to_cpu(header.l1dir_offset) << 9;

        s->l1_backup_table_offset = 0;

        s->l1_entry_sectors = s->l2_size * s->cluster_sectors;

    } else if (magic == VMDK4_MAGIC) {

        VMDK4Header header;



        if (bdrv_pread(s->hd, sizeof(magic), &header, sizeof(header)) != sizeof(header))

            goto fail;

        bs->total_sectors = le64_to_cpu(header.capacity);

        s->cluster_sectors = le64_to_cpu(header.granularity);

        s->l2_size = le32_to_cpu(header.num_gtes_per_gte);

        s->l1_entry_sectors = s->l2_size * s->cluster_sectors;

        if (s->l1_entry_sectors <= 0)

            goto fail;

        s->l1_size = (bs->total_sectors + s->l1_entry_sectors - 1)

            / s->l1_entry_sectors;

        s->l1_table_offset = le64_to_cpu(header.rgd_offset) << 9;

        s->l1_backup_table_offset = le64_to_cpu(header.gd_offset) << 9;



        if (parent_open)

            s->is_parent = 1;

        else

            s->is_parent = 0;



        

        if (vmdk_parent_open(bs, filename) != 0)

            goto fail;

        

        s->parent_cid = vmdk_read_cid(bs,1);

    } else {

        goto fail;

    }



    

    l1_size = s->l1_size * sizeof(uint32_t);

    s->l1_table = qemu_malloc(l1_size);

    if (!s->l1_table)

        goto fail;

    if (bdrv_pread(s->hd, s->l1_table_offset, s->l1_table, l1_size) != l1_size)

        goto fail;

    for(i = 0; i < s->l1_size; i++) {

        le32_to_cpus(&s->l1_table[i]);

    }



    if (s->l1_backup_table_offset) {

        s->l1_backup_table = qemu_malloc(l1_size);

        if (!s->l1_backup_table)

            goto fail;

        if (bdrv_pread(s->hd, s->l1_backup_table_offset, s->l1_backup_table, l1_size) != l1_size)

            goto fail;

        for(i = 0; i < s->l1_size; i++) {

            le32_to_cpus(&s->l1_backup_table[i]);

        }

    }



    s->l2_cache = qemu_malloc(s->l2_size * L2_CACHE_SIZE * sizeof(uint32_t));

    if (!s->l2_cache)

        goto fail;

    return 0;

 fail:

    qemu_free(s->l1_backup_table);

    qemu_free(s->l1_table);

    qemu_free(s->l2_cache);

    bdrv_delete(s->hd);

    return -1;

}

    ret = bdrv_file_open(&s->hd, filename, flags | BDRV_O_AUTOGROW);     ret = bdrv_file_open(&s->hd, filename, flags | BDRV_O_AUTOGROW);     ret = bdrv_file_open(&s->hd, filename, flags | BDRV_O_AUTOGROW);     return 0;     return 0;
static int FUNC_0(BlockDriverState *VAR_0, const char *VAR_1, int VAR_2)

{

    BDRVVmdkState *s = VAR_0->opaque;

    uint32_t magic;

    int VAR_3, VAR_4, VAR_5;



    if (parent_open)

        

        VAR_2 = BDRV_O_RDONLY;

    fprintf(stderr, "(VMDK) image open: VAR_2=0x%x VAR_1=%s\n", VAR_2, VAR_0->VAR_1);



    VAR_5 = bdrv_file_open(&s->hd, VAR_1, VAR_2 | BDRV_O_AUTOGROW);

    if (VAR_5 < 0)

        return VAR_5;

    if (bdrv_pread(s->hd, 0, &magic, sizeof(magic)) != sizeof(magic))

        goto fail;



    magic = be32_to_cpu(magic);

    if (magic == VMDK3_MAGIC) {

        VMDK3Header header;



        if (bdrv_pread(s->hd, sizeof(magic), &header, sizeof(header)) != sizeof(header))

            goto fail;

        s->cluster_sectors = le32_to_cpu(header.granularity);

        s->l2_size = 1 << 9;

        s->VAR_3 = 1 << 6;

        VAR_0->total_sectors = le32_to_cpu(header.disk_sectors);

        s->l1_table_offset = le32_to_cpu(header.l1dir_offset) << 9;

        s->l1_backup_table_offset = 0;

        s->l1_entry_sectors = s->l2_size * s->cluster_sectors;

    } else if (magic == VMDK4_MAGIC) {

        VMDK4Header header;



        if (bdrv_pread(s->hd, sizeof(magic), &header, sizeof(header)) != sizeof(header))

            goto fail;

        VAR_0->total_sectors = le64_to_cpu(header.capacity);

        s->cluster_sectors = le64_to_cpu(header.granularity);

        s->l2_size = le32_to_cpu(header.num_gtes_per_gte);

        s->l1_entry_sectors = s->l2_size * s->cluster_sectors;

        if (s->l1_entry_sectors <= 0)

            goto fail;

        s->VAR_3 = (VAR_0->total_sectors + s->l1_entry_sectors - 1)

            / s->l1_entry_sectors;

        s->l1_table_offset = le64_to_cpu(header.rgd_offset) << 9;

        s->l1_backup_table_offset = le64_to_cpu(header.gd_offset) << 9;



        if (parent_open)

            s->is_parent = 1;

        else

            s->is_parent = 0;



        

        if (vmdk_parent_open(VAR_0, VAR_1) != 0)

            goto fail;

        

        s->parent_cid = vmdk_read_cid(VAR_0,1);

    } else {

        goto fail;

    }



    

    VAR_3 = s->VAR_3 * sizeof(uint32_t);

    s->l1_table = qemu_malloc(VAR_3);

    if (!s->l1_table)

        goto fail;

    if (bdrv_pread(s->hd, s->l1_table_offset, s->l1_table, VAR_3) != VAR_3)

        goto fail;

    for(VAR_4 = 0; VAR_4 < s->VAR_3; VAR_4++) {

        le32_to_cpus(&s->l1_table[VAR_4]);

    }



    if (s->l1_backup_table_offset) {

        s->l1_backup_table = qemu_malloc(VAR_3);

        if (!s->l1_backup_table)

            goto fail;

        if (bdrv_pread(s->hd, s->l1_backup_table_offset, s->l1_backup_table, VAR_3) != VAR_3)

            goto fail;

        for(VAR_4 = 0; VAR_4 < s->VAR_3; VAR_4++) {

            le32_to_cpus(&s->l1_backup_table[VAR_4]);

        }

    }



    s->l2_cache = qemu_malloc(s->l2_size * L2_CACHE_SIZE * sizeof(uint32_t));

    if (!s->l2_cache)

        goto fail;

    return 0;

 fail:

    qemu_free(s->l1_backup_table);

    qemu_free(s->l1_table);

    qemu_free(s->l2_cache);

    bdrv_delete(s->hd);

    return -1;

}

static int FUNC_0(BlockDriverState *VAR_0, const char *VAR_1, int VAR_2)
{ BDRVVmdkState *s = VAR_0->opaque; uint32_t magic; int VAR_3, VAR_4, VAR_5; if (parent_open)
VAR_2 = BDRV_O_RDONLY; fprintf(stderr, "(VMDK) image open: VAR_2=0x%x VAR_1=%s\n", VAR_2, VAR_0->VAR_1); VAR_5 = bdrv_file_open(&s->hd, VAR_1, VAR_2 | BDRV_O_AUTOGROW); if (VAR_5 < 0)
return VAR_5; if (bdrv_pread(s->hd, 0, &magic, sizeof(magic)) != sizeof(magic))
goto fail; magic = be32_to_cpu(magic); if (magic == VMDK3_MAGIC) { VMDK3Header header; if (bdrv_pread(s->hd, sizeof(magic), &header, sizeof(header)) != sizeof(header))
goto fail; s->cluster_sectors = le32_to_cpu(header.granularity); s->l2_size = 1 << 9; s->VAR_3 = 1 << 6; VAR_0->total_sectors = le32_to_cpu(header.disk_sectors); s->l1_table_offset = le32_to_cpu(header.l1dir_offset) << 9; s->l1_backup_table_offset = 0; s->l1_entry_sectors = s->l2_size * s->cluster_sectors; } else if (magic == VMDK4_MAGIC) { VMDK4Header header; if (bdrv_pread(s->hd, sizeof(magic), &header, sizeof(header)) != sizeof(header))
goto fail; VAR_0->total_sectors = le64_to_cpu(header.capacity); s->cluster_sectors = le64_to_cpu(header.granularity); s->l2_size = le32_to_cpu(header.num_gtes_per_gte); s->l1_entry_sectors = s->l2_size * s->cluster_sectors; if (s->l1_entry_sectors <= 0)
goto fail; s->VAR_3 = (VAR_0->total_sectors + s->l1_entry_sectors - 1)
/ s->l1_entry_sectors; s->l1_table_offset = le64_to_cpu(header.rgd_offset) << 9; s->l1_backup_table_offset = le64_to_cpu(header.gd_offset) << 9; if (parent_open)
s->is_parent = 1; else
s->is_parent = 0; if (vmdk_parent_open(VAR_0, VAR_1) != 0)
goto fail; s->parent_cid = vmdk_read_cid(VAR_0,1); } else { goto fail; } VAR_3 = s->VAR_3 * sizeof(uint32_t); s->l1_table = qemu_malloc(VAR_3); if (!s->l1_table)
goto fail; if (bdrv_pread(s->hd, s->l1_table_offset, s->l1_table, VAR_3) != VAR_3)
goto fail; for(VAR_4 = 0; VAR_4 < s->VAR_3; VAR_4++) { le32_to_cpus(&s->l1_table[VAR_4]); } if (s->l1_backup_table_offset) { s->l1_backup_table = qemu_malloc(VAR_3); if (!s->l1_backup_table)
goto fail; if (bdrv_pread(s->hd, s->l1_backup_table_offset, s->l1_backup_table, VAR_3) != VAR_3)
goto fail; for(VAR_4 = 0; VAR_4 < s->VAR_3; VAR_4++) { le32_to_cpus(&s->l1_backup_table[VAR_4]); } } s->l2_cache = qemu_malloc(s->l2_size * L2_CACHE_SIZE * sizeof(uint32_t)); if (!s->l2_cache)
goto fail; return 0; fail:
qemu_free(s->l1_backup_table); qemu_free(s->l1_table); qemu_free(s->l2_cache); bdrv_delete(s->hd); return -1; }