static int vpc_create(const char *filename, QEMUOptionParameter *options)

{

    uint8_t buf[1024];

    struct vhd_footer *footer = (struct vhd_footer *) buf;

    QEMUOptionParameter *disk_type_param;

    int fd, i;

    uint16_t cyls = 0;

    uint8_t heads = 0;

    uint8_t secs_per_cyl = 0;

    int64_t total_sectors;

    int64_t total_size;

    int disk_type;

    int ret = -EIO;



    /* Read out options */

    total_size = get_option_parameter(options, BLOCK_OPT_SIZE)->value.n;



    disk_type_param = get_option_parameter(options, BLOCK_OPT_SUBFMT);

    if (disk_type_param && disk_type_param->value.s) {

        if (!strcmp(disk_type_param->value.s, "dynamic")) {

            disk_type = VHD_DYNAMIC;

        } else if (!strcmp(disk_type_param->value.s, "fixed")) {

            disk_type = VHD_FIXED;

        } else {

            return -EINVAL;

        }

    } else {

        disk_type = VHD_DYNAMIC;

    }



    /* Create the file */

    fd = qemu_open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0644);

    if (fd < 0) {

        return -EIO;

    }



    /*

     * Calculate matching total_size and geometry. Increase the number of

     * sectors requested until we get enough (or fail). This ensures that

     * qemu-img convert doesn't truncate images, but rather rounds up.

     */

    total_sectors = total_size / BDRV_SECTOR_SIZE;

    for (i = 0; total_sectors > (int64_t)cyls * heads * secs_per_cyl; i++) {

        if (calculate_geometry(total_sectors + i, &cyls, &heads,

                               &secs_per_cyl))

        {

            ret = -EFBIG;

            goto fail;

        }

    }



    total_sectors = (int64_t) cyls * heads * secs_per_cyl;



    /* Prepare the Hard Disk Footer */

    memset(buf, 0, 1024);



    memcpy(footer->creator, "conectix", 8);

    /* TODO Check if "qemu" creator_app is ok for VPC */

    memcpy(footer->creator_app, "qemu", 4);

    memcpy(footer->creator_os, "Wi2k", 4);



    footer->features = be32_to_cpu(0x02);

    footer->version = be32_to_cpu(0x00010000);

    if (disk_type == VHD_DYNAMIC) {

        footer->data_offset = be64_to_cpu(HEADER_SIZE);

    } else {

        footer->data_offset = be64_to_cpu(0xFFFFFFFFFFFFFFFFULL);

    }

    footer->timestamp = be32_to_cpu(time(NULL) - VHD_TIMESTAMP_BASE);



    /* Version of Virtual PC 2007 */

    footer->major = be16_to_cpu(0x0005);

    footer->minor = be16_to_cpu(0x0003);

    if (disk_type == VHD_DYNAMIC) {

        footer->orig_size = be64_to_cpu(total_sectors * 512);

        footer->size = be64_to_cpu(total_sectors * 512);

    } else {

        footer->orig_size = be64_to_cpu(total_size);

        footer->size = be64_to_cpu(total_size);

    }

    footer->cyls = be16_to_cpu(cyls);

    footer->heads = heads;

    footer->secs_per_cyl = secs_per_cyl;



    footer->type = be32_to_cpu(disk_type);



    /* TODO uuid is missing */



    footer->checksum = be32_to_cpu(vpc_checksum(buf, HEADER_SIZE));



    if (disk_type == VHD_DYNAMIC) {

        ret = create_dynamic_disk(fd, buf, total_sectors);

    } else {

        ret = create_fixed_disk(fd, buf, total_size);

    }



 fail:

    qemu_close(fd);

    return ret;

}

static int vpc_create(const char *filename, QEMUOptionParameter *options)

{

    uint8_t buf[1024];

    struct vhd_footer *footer = (struct vhd_footer *) buf;

    QEMUOptionParameter *disk_type_param;

    int fd, i;

    uint16_t cyls = 0;

    uint8_t heads = 0;

    uint8_t secs_per_cyl = 0;

    int64_t total_sectors;

    int64_t total_size;

    int disk_type;

    int ret = -EIO;



    

    total_size = get_option_parameter(options, BLOCK_OPT_SIZE)->value.n;



    disk_type_param = get_option_parameter(options, BLOCK_OPT_SUBFMT);

    if (disk_type_param && disk_type_param->value.s) {

        if (!strcmp(disk_type_param->value.s, "dynamic")) {

            disk_type = VHD_DYNAMIC;

        } else if (!strcmp(disk_type_param->value.s, "fixed")) {

            disk_type = VHD_FIXED;

        } else {

            return -EINVAL;

        }

    } else {

        disk_type = VHD_DYNAMIC;

    }



    

    fd = qemu_open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0644);

    if (fd < 0) {

        return -EIO;

    }



    









    total_sectors = total_size / BDRV_SECTOR_SIZE;

    for (i = 0; total_sectors > (int64_t)cyls * heads * secs_per_cyl; i++) {

        if (calculate_geometry(total_sectors + i, &cyls, &heads,

                               &secs_per_cyl))

        {

            ret = -EFBIG;

            goto fail;

        }

    }



    total_sectors = (int64_t) cyls * heads * secs_per_cyl;



    

    memset(buf, 0, 1024);



    memcpy(footer->creator, "conectix", 8);

    

    memcpy(footer->creator_app, "qemu", 4);

    memcpy(footer->creator_os, "Wi2k", 4);



    footer->features = be32_to_cpu(0x02);

    footer->version = be32_to_cpu(0x00010000);

    if (disk_type == VHD_DYNAMIC) {

        footer->data_offset = be64_to_cpu(HEADER_SIZE);

    } else {

        footer->data_offset = be64_to_cpu(0xFFFFFFFFFFFFFFFFULL);

    }

    footer->timestamp = be32_to_cpu(time(NULL) - VHD_TIMESTAMP_BASE);



    

    footer->major = be16_to_cpu(0x0005);

    footer->minor = be16_to_cpu(0x0003);

    if (disk_type == VHD_DYNAMIC) {

        footer->orig_size = be64_to_cpu(total_sectors * 512);

        footer->size = be64_to_cpu(total_sectors * 512);

    } else {

        footer->orig_size = be64_to_cpu(total_size);

        footer->size = be64_to_cpu(total_size);

    }

    footer->cyls = be16_to_cpu(cyls);

    footer->heads = heads;

    footer->secs_per_cyl = secs_per_cyl;



    footer->type = be32_to_cpu(disk_type);



    



    footer->checksum = be32_to_cpu(vpc_checksum(buf, HEADER_SIZE));



    if (disk_type == VHD_DYNAMIC) {

        ret = create_dynamic_disk(fd, buf, total_sectors);

    } else {

        ret = create_fixed_disk(fd, buf, total_size);

    }



 fail:

    qemu_close(fd);

    return ret;

}

static int FUNC_0(const char *VAR_0, QEMUOptionParameter *VAR_1)

{

    uint8_t buf[1024];

    struct vhd_footer *VAR_2 = (struct vhd_footer *) buf;

    QEMUOptionParameter *disk_type_param;

    int VAR_3, VAR_4;

    uint16_t cyls = 0;

    uint8_t heads = 0;

    uint8_t secs_per_cyl = 0;

    int64_t total_sectors;

    int64_t total_size;

    int VAR_5;

    int VAR_6 = -EIO;



    

    total_size = get_option_parameter(VAR_1, BLOCK_OPT_SIZE)->value.n;



    disk_type_param = get_option_parameter(VAR_1, BLOCK_OPT_SUBFMT);

    if (disk_type_param && disk_type_param->value.s) {

        if (!strcmp(disk_type_param->value.s, "dynamic")) {

            VAR_5 = VHD_DYNAMIC;

        } else if (!strcmp(disk_type_param->value.s, "fixed")) {

            VAR_5 = VHD_FIXED;

        } else {

            return -EINVAL;

        }

    } else {

        VAR_5 = VHD_DYNAMIC;

    }



    

    VAR_3 = qemu_open(VAR_0, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0644);

    if (VAR_3 < 0) {

        return -EIO;

    }



    









    total_sectors = total_size / BDRV_SECTOR_SIZE;

    for (VAR_4 = 0; total_sectors > (int64_t)cyls * heads * secs_per_cyl; VAR_4++) {

        if (calculate_geometry(total_sectors + VAR_4, &cyls, &heads,

                               &secs_per_cyl))

        {

            VAR_6 = -EFBIG;

            goto fail;

        }

    }



    total_sectors = (int64_t) cyls * heads * secs_per_cyl;



    

    memset(buf, 0, 1024);



    memcpy(VAR_2->creator, "conectix", 8);

    

    memcpy(VAR_2->creator_app, "qemu", 4);

    memcpy(VAR_2->creator_os, "Wi2k", 4);



    VAR_2->features = be32_to_cpu(0x02);

    VAR_2->version = be32_to_cpu(0x00010000);

    if (VAR_5 == VHD_DYNAMIC) {

        VAR_2->data_offset = be64_to_cpu(HEADER_SIZE);

    } else {

        VAR_2->data_offset = be64_to_cpu(0xFFFFFFFFFFFFFFFFULL);

    }

    VAR_2->timestamp = be32_to_cpu(time(NULL) - VHD_TIMESTAMP_BASE);



    

    VAR_2->major = be16_to_cpu(0x0005);

    VAR_2->minor = be16_to_cpu(0x0003);

    if (VAR_5 == VHD_DYNAMIC) {

        VAR_2->orig_size = be64_to_cpu(total_sectors * 512);

        VAR_2->size = be64_to_cpu(total_sectors * 512);

    } else {

        VAR_2->orig_size = be64_to_cpu(total_size);

        VAR_2->size = be64_to_cpu(total_size);

    }

    VAR_2->cyls = be16_to_cpu(cyls);

    VAR_2->heads = heads;

    VAR_2->secs_per_cyl = secs_per_cyl;



    VAR_2->type = be32_to_cpu(VAR_5);



    



    VAR_2->checksum = be32_to_cpu(vpc_checksum(buf, HEADER_SIZE));



    if (VAR_5 == VHD_DYNAMIC) {

        VAR_6 = create_dynamic_disk(VAR_3, buf, total_sectors);

    } else {

        VAR_6 = create_fixed_disk(VAR_3, buf, total_size);

    }



 fail:

    qemu_close(VAR_3);

    return VAR_6;

}

static int FUNC_0(const char *VAR_0, QEMUOptionParameter *VAR_1)
{ uint8_t buf[1024]; struct vhd_footer *VAR_2 = (struct vhd_footer *) buf; QEMUOptionParameter *disk_type_param; int VAR_3, VAR_4; uint16_t cyls = 0; uint8_t heads = 0; uint8_t secs_per_cyl = 0; int64_t total_sectors; int64_t total_size; int VAR_5; int VAR_6 = -EIO; total_size = get_option_parameter(VAR_1, BLOCK_OPT_SIZE)->value.n; disk_type_param = get_option_parameter(VAR_1, BLOCK_OPT_SUBFMT); if (disk_type_param && disk_type_param->value.s) { if (!strcmp(disk_type_param->value.s, "dynamic")) { VAR_5 = VHD_DYNAMIC; } else if (!strcmp(disk_type_param->value.s, "fixed")) { VAR_5 = VHD_FIXED; } else { return -EINVAL; } } else { VAR_5 = VHD_DYNAMIC; } VAR_3 = qemu_open(VAR_0, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0644); if (VAR_3 < 0) { return -EIO; } total_sectors = total_size / BDRV_SECTOR_SIZE; for (VAR_4 = 0; total_sectors > (int64_t)cyls * heads * secs_per_cyl; VAR_4++) { if (calculate_geometry(total_sectors + VAR_4, &cyls, &heads,
&secs_per_cyl))
{ VAR_6 = -EFBIG; goto fail; } } total_sectors = (int64_t) cyls * heads * secs_per_cyl; memset(buf, 0, 1024); memcpy(VAR_2->creator, "conectix", 8); memcpy(VAR_2->creator_app, "qemu", 4); memcpy(VAR_2->creator_os, "Wi2k", 4); VAR_2->features = be32_to_cpu(0x02); VAR_2->version = be32_to_cpu(0x00010000); if (VAR_5 == VHD_DYNAMIC) { VAR_2->data_offset = be64_to_cpu(HEADER_SIZE); } else { VAR_2->data_offset = be64_to_cpu(0xFFFFFFFFFFFFFFFFULL); } VAR_2->timestamp = be32_to_cpu(time(NULL) - VHD_TIMESTAMP_BASE); VAR_2->major = be16_to_cpu(0x0005); VAR_2->minor = be16_to_cpu(0x0003); if (VAR_5 == VHD_DYNAMIC) { VAR_2->orig_size = be64_to_cpu(total_sectors * 512); VAR_2->size = be64_to_cpu(total_sectors * 512); } else { VAR_2->orig_size = be64_to_cpu(total_size); VAR_2->size = be64_to_cpu(total_size); } VAR_2->cyls = be16_to_cpu(cyls); VAR_2->heads = heads; VAR_2->secs_per_cyl = secs_per_cyl; VAR_2->type = be32_to_cpu(VAR_5); VAR_2->checksum = be32_to_cpu(vpc_checksum(buf, HEADER_SIZE)); if (VAR_5 == VHD_DYNAMIC) { VAR_6 = create_dynamic_disk(VAR_3, buf, total_sectors); } else { VAR_6 = create_fixed_disk(VAR_3, buf, total_size); } fail:
qemu_close(VAR_3); return VAR_6; }