diff options
Diffstat (limited to 'block-bochs.c')
-rw-r--r-- | block-bochs.c | 40 |
1 files changed, 35 insertions, 5 deletions
diff --git a/block-bochs.c b/block-bochs.c index febb4d3fd6..35e2a6cf01 100644 --- a/block-bochs.c +++ b/block-bochs.c @@ -28,7 +28,8 @@ /**************************************************************/ #define HEADER_MAGIC "Bochs Virtual HD Image" -#define HEADER_VERSION 0x00010000 +#define HEADER_VERSION 0x00020000 +#define HEADER_V1 0x00010000 #define HEADER_SIZE 512 #define REDOLOG_TYPE "Redolog" @@ -37,7 +38,7 @@ // not allocated: 0xffffffff // always little-endian -struct bochs_header { +struct bochs_header_v1 { char magic[32]; // "Bochs Virtual HD Image" char type[16]; // "Redolog" char subtype[16]; // "Undoable" / "Volatile" / "Growing" @@ -56,6 +57,27 @@ struct bochs_header { } extra; }; +// always little-endian +struct bochs_header { + char magic[32]; // "Bochs Virtual HD Image" + char type[16]; // "Redolog" + char subtype[16]; // "Undoable" / "Volatile" / "Growing" + uint32_t version; + uint32_t header; // size of header + + union { + struct { + uint32_t catalog; // num of entries + uint32_t bitmap; // bitmap size + uint32_t extent; // extent size + uint32_t reserved; // for ??? + uint64_t disk; // disk size + char padding[HEADER_SIZE - 64 - 8 - 24]; + } redolog; + char padding[HEADER_SIZE - 64 - 8]; + } extra; +}; + typedef struct BDRVBochsState { int fd; @@ -79,7 +101,8 @@ static int bochs_probe(const uint8_t *buf, int buf_size, const char *filename) if (!strcmp(bochs->magic, HEADER_MAGIC) && !strcmp(bochs->type, REDOLOG_TYPE) && !strcmp(bochs->subtype, GROWING_TYPE) && - (le32_to_cpu(bochs->version) == HEADER_VERSION)) + ((le32_to_cpu(bochs->version) == HEADER_VERSION) || + (le32_to_cpu(bochs->version) == HEADER_V1))) return 100; return 0; @@ -90,6 +113,7 @@ static int bochs_open(BlockDriverState *bs, const char *filename, int flags) BDRVBochsState *s = bs->opaque; int fd, i; struct bochs_header bochs; + struct bochs_header_v1 header_v1; fd = open(filename, O_RDWR | O_BINARY); if (fd < 0) { @@ -109,11 +133,17 @@ static int bochs_open(BlockDriverState *bs, const char *filename, int flags) if (strcmp(bochs.magic, HEADER_MAGIC) || strcmp(bochs.type, REDOLOG_TYPE) || strcmp(bochs.subtype, GROWING_TYPE) || - (le32_to_cpu(bochs.version) != HEADER_VERSION)) { + ((le32_to_cpu(bochs.version) != HEADER_VERSION) && + (le32_to_cpu(bochs.version) != HEADER_V1))) { goto fail; } - bs->total_sectors = le64_to_cpu(bochs.extra.redolog.disk) / 512; + if (le32_to_cpu(bochs.version) == HEADER_V1) { + memcpy(&header_v1, &bochs, sizeof(bochs)); + bs->total_sectors = le64_to_cpu(header_v1.extra.redolog.disk) / 512; + } else { + bs->total_sectors = le64_to_cpu(bochs.extra.redolog.disk) / 512; + } lseek(s->fd, le32_to_cpu(bochs.header), SEEK_SET); |