Newer
Older
vvd / src / vdisk / vdi.h
@dd86k dd86k on 25 Sep 2020 2 KB misc.
/**
 * VDI: Virtualbox DIsk
 * 
 * https://forums.virtualbox.org/viewtopic.php?t=8046
 */

#include <stdint.h>
#include "../uid.h"

#define VDI_SIGNATURE	"<<< Oracle VM VirtualBox Disk Image >>>\n"
#define VDI_SIGNATURE_OLDER	"<<< InnoTek VirtualBox Disk Image >>>\n"

/**
 * Block marked as free is not allocated in image file, read from this
 * block may returns any random data.
 */
static const uint32_t VDI_BLOCK_FREE = 0xffffffff;

/**
 * Block marked as zero is not allocated in image file, read from this
 * block returns zeroes.
 */
static const uint32_t VDI_BLOCK_ZERO = 0xfffffffe;

enum {
	VDI_HEADER_MAGIC	= 0xBEDA107F,
	VDI_SIGNATURE_SIZE	= 64,
	VDI_COMMENT_SIZE	= 256,

	VDI_DISK_DYN	= 1,
	VDI_DISK_FIXED	= 2,
	VDI_DISK_UNDO	= 3,
	VDI_DISK_DIFF	= 4,

	VDI_BLOCKSIZE	= 1024 * 1024,	// Typical block size, 1 MiB
};

typedef struct {
	uint32_t cCylinders;
	uint32_t cHeads;
	uint32_t cSectors;
	uint32_t cbSector;
} VDIDISKGEOMETRY;

typedef struct { // Excludes char[64] at start
	uint32_t magic;
	uint16_t majorv;
	uint16_t minorv;
} VDI_HDR;

typedef struct { // v0.0
	uint32_t type;
	uint32_t fFlags;
	uint8_t  szComment[VDI_COMMENT_SIZE];
	VDIDISKGEOMETRY LegacyGeometry;
	uint64_t disksize;
	uint32_t blocksize;
	uint32_t blockstotal;
	uint32_t blocksalloc;
	UID      uuidCreate;
	UID      uuidModify;
	UID      uuidLinkage;
} VDIHEADER0;

typedef struct { // v1.1
	uint32_t hdrsize;
	uint32_t type;
	uint32_t fFlags;
	uint8_t  szComment[VDI_COMMENT_SIZE];
	uint32_t offBlocks;	// Byte offset to BAT
	uint32_t offData;	// Byte offset to first block
	VDIDISKGEOMETRY LegacyGeometry;
	uint32_t u32Dummy;	// Used to be translation value for geometry
	uint64_t disksize;
	uint32_t blocksize;	// Block size in bytes
	uint32_t blocksextra;
	uint32_t blockstotal;	// Total amount of blocks
	uint32_t blocksalloc;
	UID      uuidCreate;
	UID      uuidModify;
	UID      uuidLinkage;
	UID      uuidParentModify;
	uint32_t cCylinders;	// v1.1
	uint32_t cHeads;	// v1.1
	uint32_t cSectors;	// v1.1
	uint32_t cbSector;	// v1.1
//	uint8_t  pad[40];
} VDIHEADER1;

struct VDISK;

int vdisk_vdi_open(struct VDISK *vd, uint32_t flags, uint32_t internal);

int vdisk_vdi_read_sector(struct VDISK *vd, void *buffer, uint64_t index);

int vdisk_vdi_compact(struct VDISK *vd, void(*cb)(uint32_t type, void *data));