VDICore.h revision c1e8287e038e789c1eefcee00a2e63258ca22d48
/* $Id$ */
/** @file
* Virtual Disk Image (VDI), Core Code Header (internal).
*/
/*
* Copyright (C) 2006-2009 Sun Microsystems, Inc.
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
* General Public License (GPL) as published by the Free Software
* Foundation, in version 2 as it comes in the "COPYING" file of the
* VirtualBox OSE distribution. VirtualBox OSE is distributed in the
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
* Clara, CA 95054 USA or visit http://www.sun.com if you need
* additional information or have any questions.
*/
#ifndef __VDICore_h__
/*******************************************************************************
* Header Files *
*******************************************************************************/
#ifndef VBOX_VDICORE_VD
#else /* VBOX_VDICORE_VD */
#endif /* VBOX_VDICORE_VD */
/*******************************************************************************
* Constants And Macros, Structures and Typedefs *
*******************************************************************************/
/** Image info, not handled anyhow.
* Must be less than 64 bytes in length, including the trailing 0.
*/
#define VDI_IMAGE_FILE_INFO "<<< Sun VirtualBox Disk Image >>>\n"
/** The Sector size.
* Currently we support only 512 bytes sectors.
*/
#define VDI_GEOMETRY_SECTOR_SIZE (512)
/** 512 = 2^^9 */
#define VDI_GEOMETRY_SECTOR_SHIFT (9)
/**
* Harddisk geometry.
*/
#pragma pack(1)
typedef struct VDIDISKGEOMETRY
{
/** Cylinders. */
/** Heads. */
/** Sectors per track. */
/** Sector size. (bytes per sector) */
#pragma pack()
/** Image signature. */
#define VDI_IMAGE_SIGNATURE (0xbeda107f)
/**
* Pre-Header to be stored in image file - used for version control.
*/
#pragma pack(1)
typedef struct VDIPREHEADER
{
/** Just text info about image type, for eyes only. */
char szFileInfo[64];
/** The image signature (VDI_IMAGE_SIGNATURE). */
/** The image version (VDI_IMAGE_VERSION). */
#pragma pack()
/**
* Size of szComment field of HDD image header.
*/
#define VDI_IMAGE_COMMENT_SIZE 256
/**
* Header to be stored in image file, VDI_IMAGE_VERSION_MAJOR = 0.
* Prepended by VDIPREHEADER.
*/
#pragma pack(1)
typedef struct VDIHEADER0
{
/** The image type (VDI_IMAGE_TYPE_*). */
/** Image flags (VDI_IMAGE_FLAGS_*). */
/** Image comment. (UTF-8) */
char szComment[VDI_IMAGE_COMMENT_SIZE];
/** Legacy image geometry (previous code stored PCHS there). */
/** Size of disk (in bytes). */
/** Block size. (For instance VDI_IMAGE_BLOCK_SIZE.) */
/** Number of blocks. */
/** Number of allocated blocks. */
/** UUID of image. */
/** UUID of image's last modification. */
/** Only for secondary images - UUID of primary image. */
} VDIHEADER0, *PVDIHEADER0;
#pragma pack()
/**
* Header to be stored in image file, VDI_IMAGE_VERSION_MAJOR = 1,
* VDI_IMAGE_VERSION_MINOR = 1. Prepended by VDIPREHEADER.
*/
#pragma pack(1)
typedef struct VDIHEADER1
{
/** Size of this structure in bytes. */
/** The image type (VDI_IMAGE_TYPE_*). */
/** Image flags (VDI_IMAGE_FLAGS_*). */
/** Image comment. (UTF-8) */
char szComment[VDI_IMAGE_COMMENT_SIZE];
/** Offset of Blocks array from the begining of image file.
* Should be sector-aligned for HDD access optimization. */
/** Offset of image data from the begining of image file.
* Should be sector-aligned for HDD access optimization. */
/** Legacy image geometry (previous code stored PCHS there). */
/** Was BIOS HDD translation mode, now unused. */
/** Size of disk (in bytes). */
/** Block size. (For instance VDI_IMAGE_BLOCK_SIZE.) Should be a power of 2! */
/** Size of additional service information of every data block.
* Prepended before block data. May be 0.
* Should be a power of 2 and sector-aligned for optimization reasons. */
/** Number of blocks. */
/** Number of allocated blocks. */
/** UUID of image. */
/** UUID of image's last modification. */
/** Only for secondary images - UUID of previous image. */
/** Only for secondary images - UUID of previous image's last modification. */
} VDIHEADER1, *PVDIHEADER1;
#pragma pack()
/**
* Header to be stored in image file, VDI_IMAGE_VERSION_MAJOR = 1,
* VDI_IMAGE_VERSION_MINOR = 1, the slightly changed variant necessary as the
* old released code doesn't support changing the minor version at all.
*/
#pragma pack(1)
typedef struct VDIHEADER1PLUS
{
/** Size of this structure in bytes. */
/** The image type (VDI_IMAGE_TYPE_*). */
/** Image flags (VDI_IMAGE_FLAGS_*). */
/** Image comment. (UTF-8) */
char szComment[VDI_IMAGE_COMMENT_SIZE];
/** Offset of Blocks array from the begining of image file.
* Should be sector-aligned for HDD access optimization. */
/** Offset of image data from the begining of image file.
* Should be sector-aligned for HDD access optimization. */
/** Legacy image geometry (previous code stored PCHS there). */
/** Was BIOS HDD translation mode, now unused. */
/** Size of disk (in bytes). */
/** Block size. (For instance VDI_IMAGE_BLOCK_SIZE.) Should be a power of 2! */
/** Size of additional service information of every data block.
* Prepended before block data. May be 0.
* Should be a power of 2 and sector-aligned for optimization reasons. */
/** Number of blocks. */
/** Number of allocated blocks. */
/** UUID of image. */
/** UUID of image's last modification. */
/** Only for secondary images - UUID of previous image. */
/** Only for secondary images - UUID of previous image's last modification. */
/** LCHS image geometry (new field in VDI1.2 version. */
#pragma pack()
/**
* Header structure for all versions.
*/
typedef struct VDIHEADER
{
unsigned uVersion;
union
{
} u;
} VDIHEADER, *PVDIHEADER;
/** Block 'pointer'. */
typedef uint32_t VDIIMAGEBLOCKPOINTER;
/** Pointer to a block 'pointer'. */
typedef VDIIMAGEBLOCKPOINTER *PVDIIMAGEBLOCKPOINTER;
/**
* Block marked as free is not allocated in image file, read from this
* block may returns any random data.
*/
#define VDI_IMAGE_BLOCK_FREE ((VDIIMAGEBLOCKPOINTER)~0)
/**
* Block marked as zero is not allocated in image file, read from this
* block returns zeroes.
*/
/**
* Block 'pointer' >= VDI_IMAGE_BLOCK_UNALLOCATED indicates block is not
* allocated in image file.
*/
#ifdef VBOX_VDICORE_VD
/** @name VDI image types
* @{ */
typedef enum VDIIMAGETYPE
{
/** Normal dynamically growing base image file. */
/** Preallocated base image file of a fixed size. */
/** Dynamically growing image file for differencing support. */
/** First valid image type value. */
/** Last valid image type value. */
} VDIIMAGETYPE;
/** Pointer to VDI image type. */
typedef VDIIMAGETYPE *PVDIIMAGETYPE;
/** @} */
#endif /* VBOX_VDICORE_VD */
/*******************************************************************************
* Internal Functions for header access *
*******************************************************************************/
{
switch (GET_MAJOR_HEADER_VERSION(ph))
{
}
AssertFailed();
return (VDIIMAGETYPE)0;
}
#ifdef VBOX_VDICORE_VD
{
switch (GET_MAJOR_HEADER_VERSION(ph))
{
case 0:
/* VDI image flag conversion to VD image flags. */
case 1:
/* VDI image flag conversion to VD image flags. */
}
AssertFailed();
return 0;
}
#else /* !VBOX_VDICORE_VD */
{
switch (GET_MAJOR_HEADER_VERSION(ph))
{
}
AssertFailed();
return 0;
}
#endif /* !VBOX_VDICORE_VD */
{
switch (GET_MAJOR_HEADER_VERSION(ph))
{
}
AssertFailed();
return NULL;
}
{
switch (GET_MAJOR_HEADER_VERSION(ph))
{
case 0: return (sizeof(VDIPREHEADER) + sizeof(VDIHEADER0));
}
AssertFailed();
return 0;
}
{
switch (GET_MAJOR_HEADER_VERSION(ph))
{
case 0: return sizeof(VDIPREHEADER) + sizeof(VDIHEADER0) + \
}
AssertFailed();
return 0;
}
{
switch (GET_MAJOR_HEADER_VERSION(ph))
{
case 0: return NULL;
case 1:
switch (GET_MINOR_HEADER_VERSION(ph))
{
case 1:
return NULL;
else
}
}
AssertFailed();
return NULL;
}
{
switch (GET_MAJOR_HEADER_VERSION(ph))
{
}
AssertFailed();
return 0;
}
{
switch (GET_MAJOR_HEADER_VERSION(ph))
{
}
AssertFailed();
return 0;
}
{
switch (GET_MAJOR_HEADER_VERSION(ph))
{
case 0: return 0;
}
AssertFailed();
return 0;
}
{
switch (GET_MAJOR_HEADER_VERSION(ph))
{
}
AssertFailed();
return 0;
}
{
switch (GET_MAJOR_HEADER_VERSION(ph))
{
}
AssertFailed();
return 0;
}
{
switch (GET_MAJOR_HEADER_VERSION(ph))
{
}
AssertFailed();
}
{
switch (GET_MAJOR_HEADER_VERSION(ph))
{
}
AssertFailed();
return NULL;
}
{
switch (GET_MAJOR_HEADER_VERSION(ph))
{
}
AssertFailed();
return NULL;
}
{
switch (GET_MAJOR_HEADER_VERSION(ph))
{
}
AssertFailed();
return NULL;
}
{
switch (GET_MAJOR_HEADER_VERSION(ph))
{
}
AssertFailed();
return NULL;
}
#ifndef VBOX_VDICORE_VD
/**
* Default image block size, may be changed by setBlockSize/getBlockSize.
*
* Note: for speed reasons block size should be a power of 2 !
*/
#define VDI_IMAGE_DEFAULT_BLOCK_SIZE _1M
#endif /* !VBOX_VDICORE_VD */
#ifndef VBOX_VDICORE_VD
/**
* fModified bit flags.
*/
#define VDI_IMAGE_MODIFIED_FLAG RT_BIT(0)
#endif /* !VBOX_VDICORE_VD */
/**
* Image structure
*/
typedef struct VDIIMAGEDESC
{
#ifndef VBOX_VDICORE_VD
/** Link to parent image descriptor, if any. */
struct VDIIMAGEDESC *pPrev;
/** Link to child image descriptor, if any. */
struct VDIIMAGEDESC *pNext;
#endif /* !VBOX_VDICORE_VD */
#ifndef VBOX_WITH_NEW_IO_CODE
/** File handle. */
#else
/** Opaque storage handle. */
#endif
#ifndef VBOX_VDICORE_VD
/** True if the image is operating in readonly mode. */
bool fReadOnly;
/** Image open flags, VDI_OPEN_FLAGS_*. */
unsigned fOpen;
#else /* VBOX_VDICORE_VD */
/** Image open flags, VD__OPEN_FLAGS_*. */
unsigned uOpenFlags;
#endif /* VBOX_VDICORE_VD */
/** Image pre-header. */
/** Image header. */
/** Pointer to a block array. */
#ifndef VBOX_VDICORE_VD
/** fFlags copy from image header, for speed optimization. */
unsigned fFlags;
#else /* VBOX_VDICORE_VD */
/** fFlags copy from image header, for speed optimization. */
unsigned uImageFlags;
#endif /* VBOX_VDICORE_VD */
/** Start offset of block array in image file, here for speed optimization. */
unsigned offStartBlocks;
/** Start offset of data in image file, here for speed optimization. */
unsigned offStartData;
/** Block mask for getting the offset into a block from a byte hdd offset. */
unsigned uBlockMask;
/** Block shift value for converting byte hdd offset into paBlock index. */
unsigned uShiftOffset2Index;
#ifndef VBOX_VDICORE_VD
/** Block shift value for converting block index into offset in image. */
unsigned uShiftIndex2Offset;
#endif /* !VBOX_VDICORE_VD */
/** Offset of data from the beginning of block. */
unsigned offStartBlockData;
#ifndef VBOX_VDICORE_VD
/** Image is modified flags (VDI_IMAGE_MODIFIED*). */
unsigned fModified;
/** Container filename. (UTF-8)
* @todo Make this variable length to save a bunch of bytes. (low prio) */
char szFilename[RTPATH_MAX];
#else /* VBOX_VDICORE_VD */
/** Total size of image block (including the extra data). */
unsigned cbTotalBlockData;
/** Container filename. (UTF-8) */
const char *pszFilename;
/** Physical geometry of this image (never actually stored). */
/** Pointer to the per-disk VD interface list. */
/** Pointer to the per-image VD interface list. */
/** Error interface. */
/** Error interface callback table. */
# ifdef VBOX_WITH_NEW_IO_CODE
/** I/O interface. */
/** I/O interface callbacks. */
# endif
#endif /* VBOX_VDICORE_VD */
#ifndef VBOX_VDICORE_VD
/**
* Default work buffer size, may be changed by setBufferSize() method.
*
* For best speed performance it must be equal to image block size.
*/
#endif /* !VBOX_VDICORE_VD */
/** VDIDISK Signature. */
#define VDIDISK_SIGNATURE (0xbedafeda)
/**
* VBox HDD Container main structure, private part.
*/
struct VDIDISK
{
/** Structure signature (VDIDISK_SIGNATURE). */
/** Number of opened images. */
unsigned cImages;
/** Base image. */
/** Last opened image in the chain.
* The same as pBase if only one image is used or the last opened diff image. */
/** Default block size for newly created images. */
unsigned cbBlock;
/** Working buffer size, allocated only while committing data,
* copying block from primary image to secondary and saving previously
* zero block. Buffer deallocated after operation complete.
* @remark For best performance buffer size must be equal to image's
* block size, however it may be decreased for memory saving.
*/
unsigned cbBuf;
/** Flag whether zero writes should be handled normally or optimized
* away if possible. */
bool fHonorZeroWrites;
/** The media interface. */
/** Pointer to the driver instance. */
};
/*******************************************************************************
* Internal Functions *
*******************************************************************************/
#ifndef VBOX_VDICORE_VD
#endif /* !VBOX_VDICORE_VD */
#endif