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