Revision b9fa33a6

b/block-vpc.c
31 31
//#define CACHE
32 32

  
33 33
// always big-endian
34
struct vpc_subheader {
35
    char magic[8]; // "conectix" / "cxsparse"
36
    union {
37
	struct {
38
	    uint32_t unk1[2];
39
	    uint32_t unk2; // always zero?
40
	    uint32_t subheader_offset;
41
	    uint32_t unk3; // some size?
42
	    char creator[4]; // "vpc "
43
	    uint16_t major;
44
	    uint16_t minor;
45
	    char guest[4]; // "Wi2k"
46
	    uint32_t unk4[7];
47
	    uint8_t vnet_id[16]; // virtual network id, purpose unknown
48
	    // next 16 longs are used, but dunno the purpose
49
	    // next 6 longs unknown, following 7 long maybe a serial
50
	    char padding[HEADER_SIZE - 84];
51
	} main;
52
	struct {
53
	    uint32_t unk1[2]; // all bits set
54
	    uint32_t unk2; // always zero?
55
	    uint32_t pagetable_offset;
56
	    uint32_t unk3;
57
	    uint32_t pagetable_entries; // 32bit/entry
58
	    uint32_t pageentry_size; // 512*8*512
59
	    uint32_t nb_sectors;
60
	    char padding[HEADER_SIZE - 40];
61
	} sparse;
62
	char padding[HEADER_SIZE - 8];
63
    } type;
34
struct vhd_footer {
35
    char creator[8]; // "conectix
36
    uint32_t unk1[2];
37
    uint32_t unk2; // always zero?
38
    uint32_t subheader_offset;
39
    uint32_t unk3; // some size?
40
    char creator_app[4]; // "vpc "
41
    uint16_t major;
42
    uint16_t minor;
43
    char guest[4]; // "Wi2k"
44
    uint32_t unk4[7];
45
    uint8_t vnet_id[16]; // virtual network id, purpose unknown
46
    // next 16 longs are used, but dunno the purpose
47
    // next 6 longs unknown, following 7 long maybe a serial
48
};
49

  
50
struct vhd_dyndisk_header {
51
    char magic[8]; // "cxsparse"
52
    uint32_t unk1[2]; // all bits set
53
    uint32_t unk2; // always zero?
54
    uint32_t pagetable_offset;
55
    uint32_t unk3;
56
    uint32_t pagetable_entries; // 32bit/entry
57
    uint32_t pageentry_size; // 512*8*512
58
    uint32_t nb_sectors;
64 59
};
65 60

  
66 61
typedef struct BDRVVPCState {
......
90 85
{
91 86
    BDRVVPCState *s = bs->opaque;
92 87
    int fd, i;
93
    struct vpc_subheader header;
88
    struct vhd_footer* footer;
89
    struct vhd_dyndisk_header* dyndisk_header;
90
    uint8_t buf[HEADER_SIZE];
94 91

  
95 92
    fd = open(filename, O_RDONLY | O_BINARY);
96 93
    if (fd < 0)
......
100 97

  
101 98
    s->fd = fd;
102 99

  
103
    if (read(fd, &header, HEADER_SIZE) != HEADER_SIZE)
100
    if (read(fd, buf, HEADER_SIZE) != HEADER_SIZE)
104 101
        goto fail;
105 102

  
106
    if (strncmp(header.magic, "conectix", 8))
103
    footer = (struct vhd_footer*) buf;
104
    if (strncmp(footer->creator, "conectix", 8))
107 105
        goto fail;
108
    lseek(s->fd, be32_to_cpu(header.type.main.subheader_offset), SEEK_SET);
109 106

  
110
    if (read(fd, &header, HEADER_SIZE) != HEADER_SIZE)
107
    lseek(s->fd, be32_to_cpu(footer->subheader_offset), SEEK_SET);
108
    if (read(fd, buf, HEADER_SIZE) != HEADER_SIZE)
111 109
        goto fail;
112 110

  
113
    if (strncmp(header.magic, "cxsparse", 8))
114
	goto fail;
111
    footer = NULL;
112
    dyndisk_header = (struct vhd_dyndisk_header*) buf;
113

  
114
    if (strncmp(dyndisk_header->magic, "cxsparse", 8))
115
        goto fail;
115 116

  
116
    bs->total_sectors = ((uint64_t)be32_to_cpu(header.type.sparse.pagetable_entries) *
117
			be32_to_cpu(header.type.sparse.pageentry_size)) / 512;
117
    bs->total_sectors = ((uint64_t)be32_to_cpu(dyndisk_header->pagetable_entries) *
118
			be32_to_cpu(dyndisk_header->pageentry_size)) / 512;
118 119

  
119
    lseek(s->fd, be32_to_cpu(header.type.sparse.pagetable_offset), SEEK_SET);
120
    lseek(s->fd, be32_to_cpu(dyndisk_header->pagetable_offset), SEEK_SET);
120 121

  
121
    s->pagetable_entries = be32_to_cpu(header.type.sparse.pagetable_entries);
122
    s->pagetable_entries = be32_to_cpu(dyndisk_header->pagetable_entries);
122 123
    s->pagetable = qemu_malloc(s->pagetable_entries * 4);
123 124
    if (!s->pagetable)
124 125
	goto fail;
......
128 129
    for (i = 0; i < s->pagetable_entries; i++)
129 130
	be32_to_cpus(&s->pagetable[i]);
130 131

  
131
    s->pageentry_size = be32_to_cpu(header.type.sparse.pageentry_size);
132
    s->pageentry_size = be32_to_cpu(dyndisk_header->pageentry_size);
132 133
#ifdef CACHE
133 134
    s->pageentry_u8 = qemu_malloc(512);
134 135
    if (!s->pageentry_u8)

Also available in: Unified diff