Bochs/bochs/iodev/hdimage/vpc-img.h
Volker Ruppert 698afee9aa undoable / volatile mode: added support for other types of r/o base images.
These hdimage modes are now supported: flat, sparse, growing, vmware3, vmware4
und vpc. The image mode is auto-detected, so no change of configuration syntax
is necessary (TODO: documentation update). Example:

ata0-master: type=disk, mode=volatile, path=vmware4-test.img
2012-10-07 18:36:22 +00:00

176 lines
4.7 KiB
C++

/////////////////////////////////////////////////////////////////////////
// $Id$
/////////////////////////////////////////////////////////////////////////
//
// Block driver for Connectix / Microsoft Virtual PC images (ported from QEMU)
//
// Copyright (c) 2005 Alex Beregszaszi
// Copyright (c) 2009 Kevin Wolf <kwolf@suse.de>
// Copyright (C) 2012 The Bochs Project
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
/////////////////////////////////////////////////////////////////////////
#ifndef BX_VPCIMG_H
#define BX_VPCIMG_H
#define HEADER_SIZE 512
enum vhd_type {
VHD_FIXED = 2,
VHD_DYNAMIC = 3,
VHD_DIFFERENCING = 4,
};
#if defined(_MSC_VER) && (_MSC_VER<1300)
#pragma pack(push, 1)
#elif defined(__MWERKS__) && defined(macintosh)
#pragma options align=packed
#endif
// always big-endian
typedef
#if defined(_MSC_VER) && (_MSC_VER>=1300)
__declspec(align(1))
#endif
struct vhd_footer_t {
Bit8u creator[8]; // "conectix"
Bit32u features;
Bit32u version;
// Offset of next header structure, 0xFFFFFFFF if none
Bit64u data_offset;
// Seconds since Jan 1, 2000 0:00:00 (UTC)
Bit32u timestamp;
Bit8u creator_app[4]; // "vpc "
Bit16u major;
Bit16u minor;
Bit8u creator_os[4]; // "Wi2k"
Bit64u orig_size;
Bit64u size;
Bit16u cyls;
Bit8u heads;
Bit8u secs_per_cyl;
Bit32u type;
// Checksum of the Hard Disk Footer ("one's complement of the sum of all
// the bytes in the footer without the checksum field")
Bit32u checksum;
// UUID used to identify a parent hard disk (backing file)
Bit8u uuid[16];
Bit8u in_saved_state;
}
#if !defined(_MSC_VER)
GCC_ATTRIBUTE((packed))
#endif
vhd_footer_t;
typedef
#if defined(_MSC_VER) && (_MSC_VER>=1300)
__declspec(align(1))
#endif
struct vhd_dyndisk_header_t {
Bit8u magic[8]; // "cxsparse"
// Offset of next header structure, 0xFFFFFFFF if none
Bit64u data_offset;
// Offset of the Block Allocation Table (BAT)
Bit64u table_offset;
Bit32u version;
Bit32u max_table_entries; // 32bit/entry
// 2 MB by default, must be a power of two
Bit32u block_size;
Bit32u checksum;
Bit8u parent_uuid[16];
Bit32u parent_timestamp;
Bit32u reserved;
// Backing file name (in UTF-16)
Bit8u parent_name[512];
struct {
Bit32u platform;
Bit32u data_space;
Bit32u data_length;
Bit32u reserved;
Bit64u data_offset;
} parent_locator[8];
}
#if !defined(_MSC_VER)
GCC_ATTRIBUTE((packed))
#endif
vhd_dyndisk_header_t;
#if defined(_MSC_VER) && (_MSC_VER<1300)
#pragma pack(pop)
#elif defined(__MWERKS__) && defined(macintosh)
#pragma options align=reset
#endif
class vpc_image_t : public device_image_t
{
public:
int open(const char* pathname, int flags);
void close();
Bit64s lseek(Bit64s offset, int whence);
ssize_t read(void* buf, size_t count);
ssize_t write(const void* buf, size_t count);
Bit32u get_capabilities();
static int check_format(int fd, Bit64u imgsize);
bx_bool save_state(const char *backup_fname);
void restore_state(const char *backup_fname);
private:
Bit32u vpc_checksum(Bit8u *buf, size_t size);
Bit64s get_sector_offset(Bit64s sector_num, int write);
int rewrite_footer(void);
Bit64s alloc_block(Bit64s sector_num);
int fd;
Bit64s sector_count;
Bit64s cur_sector;
Bit8u footer_buf[HEADER_SIZE];
Bit64u free_data_block_offset;
int max_table_entries;
Bit64u bat_offset;
Bit64u last_bitmap_offset;
Bit32u *pagetable;
Bit32u block_size;
Bit32u bitmap_size;
const char *pathname;
};
#endif