VDI.cpp revision 09d56a9b9fa06bf43bd63fe74826595355ae7b18
18572N/A * available from http://www.virtualbox.org. This file is free software;
#include "VDICore.h"
const char *pszFormat, ...)
return rc;
return rc;
cbRead);
void *pvCompleteUser)
void *pvCompleteUser)
void *pvCompleteUser)
if (pImage)
if (!fDelete)
return rc;
if (uNumber == 0)
unsigned uPower2 = 0;
uPower2++;
return VERR_VD_VDI_INVALID_HEADER;
return VERR_VD_VDI_UNSUPPORTED_VERSION;
return VINF_SUCCESS;
return VDI_IMAGE_TYPE_FIXED;
return VDI_IMAGE_TYPE_DIFF;
return VDI_IMAGE_TYPE_NORMAL;
switch (enmType)
case VDI_IMAGE_TYPE_NORMAL:
return VD_IMAGE_FLAGS_NONE;
case VDI_IMAGE_TYPE_FIXED:
return VD_IMAGE_FLAGS_FIXED;
case VDI_IMAGE_TYPE_DIFF:
return VD_IMAGE_FLAGS_DIFF;
return VD_IMAGE_FLAGS_NONE;
#ifdef VBOX_STRICT
if (pszComment)
pHeader->u.v1plus.offBlocks = RT_ALIGN_32(sizeof(VDIPREHEADER) + sizeof(VDIHEADER1PLUS), VDI_DATA_ALIGN);
pHeader->u.v1plus.offData = RT_ALIGN_32(pHeader->u.v1plus.offBlocks + (pHeader->u.v1plus.cBlocks * sizeof(VDIIMAGEBLOCKPOINTER)), VDI_DATA_ALIGN);
return VERR_VD_VDI_INVALID_HEADER;
return VERR_VD_VDI_INVALID_HEADER;
if (getImageDataOffset(pHeader) < (getImageBlocksOffset(pHeader) + getImageBlocks(pHeader) * sizeof(VDIIMAGEBLOCKPOINTER)))
getImageDataOffset(pHeader), getImageBlocksOffset(pHeader) + getImageBlocks(pHeader) * sizeof(VDIIMAGEBLOCKPOINTER)));
return VERR_VD_VDI_INVALID_HEADER;
return VERR_VD_VDI_UNSUPPORTED_VERSION;
bool fFailed = false;
fFailed = true;
fFailed = true;
fFailed = true;
fFailed = true;
fFailed = true;
fFailed = true;
fFailed = true;
fFailed = true;
fFailed = true;
unsigned uPercentSpan)
int rc;
rc = vdiError(pImage, VERR_VD_VDI_COMMENT_TOO_LONG, RT_SRC_POS, N_("VDI: comment is too long for '%s'"), pImage->pszFilename);
goto out;
pImage->paBlocks = (PVDIIMAGEBLOCKPOINTER)RTMemAlloc(sizeof(VDIIMAGEBLOCKPOINTER) * getImageBlocks(&pImage->Header));
goto out;
goto out;
rc = vdiError(pImage, VERR_DISK_FULL, RT_SRC_POS, N_("VDI: disk would overflow creating image '%s'"), pImage->pszFilename);
goto out;
rc = vdiError(pImage, rc, RT_SRC_POS, N_("VDI: setting image size failed for '%s'"), pImage->pszFilename);
goto out;
rc = vdiError(pImage, rc, RT_SRC_POS, N_("VDI: writing pre-header failed for '%s'"), pImage->pszFilename);
goto out;
rc = vdiError(pImage, rc, RT_SRC_POS, N_("VDI: writing header failed for '%s'"), pImage->pszFilename);
goto out;
NULL);
rc = vdiError(pImage, rc, RT_SRC_POS, N_("VDI: writing block pointers failed for '%s'"), pImage->pszFilename);
goto out;
if (!pvBuf)
goto out;
uOff = 0;
rc = vdiError(pImage, rc, RT_SRC_POS, N_("VDI: writing block failed for '%s'"), pImage->pszFilename);
goto out;
if (pfnProgress)
goto out;
out:
return rc;
int rc;
goto out;
goto out;
goto out;
NULL);
rc = vdiError(pImage, rc, RT_SRC_POS, N_("VDI: error reading v0 header in '%s'"), pImage->pszFilename);
goto out;
NULL);
rc = vdiError(pImage, rc, RT_SRC_POS, N_("VDI: error reading v1 header in '%s'"), pImage->pszFilename);
goto out;
rc = vdiError(pImage, rc, RT_SRC_POS, N_("VDI: error reading v1.1+ header in '%s'"), pImage->pszFilename);
goto out;
rc = vdiError(pImage, VERR_VD_VDI_UNSUPPORTED_VERSION, RT_SRC_POS, N_("VDI: unsupported major version %u in '%s'"), GET_MAJOR_HEADER_VERSION(&pImage->Header), pImage->pszFilename);
goto out;
rc = vdiError(pImage, VERR_VD_VDI_INVALID_HEADER, RT_SRC_POS, N_("VDI: invalid header in '%s'"), pImage->pszFilename);
goto out;
pImage->paBlocks = (PVDIIMAGEBLOCKPOINTER)RTMemAlloc(sizeof(VDIIMAGEBLOCKPOINTER) * getImageBlocks(&pImage->Header));
goto out;
NULL);
out:
return rc;
int rc;
NULL);
NULL);
NULL);
return rc;
int rc;
return rc;
NULL);
return rc;
sizeof(VDIIMAGEBLOCKPOINTER),
return rc;
return rc;
|| !*pszFilename)
goto out;
if (!pImage)
goto out;
out:
return rc;
LogFlowFunc(("pszFilename=\"%s\" uOpenFlags=%#x pVDIfsDisk=%#p pVDIfsImage=%#p ppBackendData=%#p\n", pszFilename, uOpenFlags, pVDIfsDisk, pVDIfsImage, ppBackendData));
int rc;
goto out;
|| !*pszFilename)
goto out;
if (!pImage)
goto out;
out:
return rc;
LogFlowFunc(("pszFilename=\"%s\" cbSize=%llu uImageFlags=%#x pszComment=\"%s\" pPCHSGeometry=%#p pLCHSGeometry=%#p Uuid=%RTuuid uOpenFlags=%#x uPercentStart=%u uPercentSpan=%u pVDIfsDisk=%#p pVDIfsImage=%#p pVDIfsOperation=%#p ppBackendData=%#p\n", pszFilename, cbSize, uImageFlags, pszComment, pPCHSGeometry, pLCHSGeometry, pUuid, uOpenFlags, uPercentStart, uPercentSpan, pVDIfsDisk, pVDIfsImage, pVDIfsOperation, ppBackendData));
int rc;
if (pIfProgress)
if (pCbProgress)
goto out;
goto out;
if ( !cbSize
goto out;
|| !*pszFilename
goto out;
if (!pImage)
goto out;
goto out;
out:
return rc;
if ( !pImage
|| !pszFilename
|| !*pszFilename)
goto out;
goto out;
goto out;
out:
return rc;
int rc;
return rc;
LogFlowFunc(("pBackendData=%#p uOffset=%llu pvBuf=%#p cbToRead=%zu pcbActuallyRead=%#p\n", pBackendData, uOffset, pvBuf, cbToRead, pcbActuallyRead));
unsigned uBlock;
unsigned offRead;
int rc;
|| !cbToRead)
goto out;
if (pcbActuallyRead)
out:
return rc;
LogFlowFunc(("pBackendData=%#p uOffset=%llu pvBuf=%#p cbToWrite=%zu pcbWriteProcess=%#p pcbPreRead=%#p pcbPostRead=%#p\n", pBackendData, uOffset, pvBuf, cbToWrite, pcbWriteProcess, pcbPreRead, pcbPostRead));
unsigned uBlock;
unsigned offWrite;
goto out;
goto out;
goto out;
goto out;
*pcbPreRead = 0;
*pcbPostRead = 0;
if (pcbWriteProcess)
out:
return rc;
return rc;
unsigned uVersion;
if (pImage)
uVersion = 0;
return uVersion;
if (pImage)
cbSize = 0;
return cbSize;
if (pImage)
return cb;
int rc;
if (pImage)
LogFlowFunc(("returns %Rrc (PCHS=%u/%u/%u)\n", rc, pPCHSGeometry->cCylinders, pPCHSGeometry->cHeads, pPCHSGeometry->cSectors));
return rc;
LogFlowFunc(("pBackendData=%#p pPCHSGeometry=%#p PCHS=%u/%u/%u\n", pBackendData, pPCHSGeometry, pPCHSGeometry->cCylinders, pPCHSGeometry->cHeads, pPCHSGeometry->cSectors));
int rc;
if (pImage)
goto out;
out:
return rc;
int rc;
if (pImage)
if (!pGeometry)
LogFlowFunc(("returns %Rrc (LCHS=%u/%u/%u)\n", rc, pLCHSGeometry->cCylinders, pLCHSGeometry->cHeads, pLCHSGeometry->cSectors));
return rc;
LogFlowFunc(("pBackendData=%#p pLCHSGeometry=%#p LCHS=%u/%u/%u\n", pBackendData, pLCHSGeometry, pLCHSGeometry->cCylinders, pLCHSGeometry->cHeads, pLCHSGeometry->cSectors));
int rc;
if (pImage)
goto out;
if (pGeometry)
out:
return rc;
unsigned uImageFlags;
if (pImage)
uImageFlags = 0;
return uImageFlags;
unsigned uOpenFlags;
if (pImage)
uOpenFlags = 0;
return uOpenFlags;
int rc;
const char *pszFilename;
if (!pImage || (uOpenFlags & ~(VD_OPEN_FLAGS_READONLY | VD_OPEN_FLAGS_INFO | VD_OPEN_FLAGS_ASYNC_IO | VD_OPEN_FLAGS_SHAREABLE | VD_OPEN_FLAGS_SEQUENTIAL)))
goto out;
goto out;
out:
return rc;
LogFlowFunc(("pBackendData=%#p pszComment=%#p cbComment=%zu\n", pBackendData, pszComment, cbComment));
if (pImage)
cb--;
return rc;
int rc;
if (pImage)
goto out;
out:
return rc;
int rc;
if (pImage)
return rc;
if (pImage)
return rc;
int rc;
if (pImage)
return rc;
if (pImage)
return rc;
int rc;
if (pImage)
return rc;
if (pImage)
return rc;
int rc;
if (pImage)
return rc;
if (pImage)
return rc;
if (pg)
vdiMessage(pImage, "Header: uuidModification={%RTuuid}\n", getImageModificationUUID(&pImage->Header));
vdiMessage(pImage, "Header: uuidParentModification={%RTuuid}\n", getImageParentModificationUUID(&pImage->Header));
vdiMessage(pImage, "Image: uBlockMask=%08X cbTotalBlockData=%u uShiftOffset2Index=%u offStartBlockData=%u\n",
cBadBlocks++;
if (cBadBlocks)
unsigned uBlock;
unsigned offRead;
int rc;
|| !cbToRead)
goto out;
if (pcbActuallyRead)
out:
return rc;
LogFlowFunc(("pBackendData=%#p uOffset=%llu pIoCtx=%#p cbToWrite=%zu pcbWriteProcess=%#p pcbPreRead=%#p pcbPostRead=%#p\n",
unsigned uBlock;
unsigned offWrite;
goto out;
goto out;
goto out;
goto out;
*pcbPreRead = 0;
*pcbPostRead = 0;
if (pcbWriteProcess)
out:
return rc;
return rc;
if (pIfParentState)
if (pCbParentState)
if (pIfProgress)
if (pCbProgress)
unsigned cBlocks;
unsigned cBlocksToMove = 0;
if (pfnParentRead)
unsigned cBlocksAllocated = (unsigned)((cbFile - pImage->offStartData - pImage->offStartBlockData) >> pImage->uShiftOffset2Index);
if (cBlocksAllocated == 0)
for (unsigned i = 0; i < cBlocksAllocated; i++)
for (unsigned i = 0; i < cBlocks; i++)
for (unsigned i = 0; i < cBlocks; i++)
else if (pfnParentRead)
unsigned cBlocksMoved = 0;
for (unsigned i = 0; i < cBlocksAllocated; i++)
if (uBlockUsedPos == i)
cBlocksMoved++;
if (paBlocks2)
if (pvTmp)
if (pvBuf)
return rc;
if (pIfProgress)
if (pCbProgress)
unsigned cBlocksAllocated = getImageBlocksAllocated(&pImage->Header); /** < Blocks currently allocated, doesn't change during resize */
uint32_t cBlocksNew = cbSize / getImageBlockSize(&pImage->Header); /** < New number of blocks in the image after the resize */
cBlocksNew++;
uint64_t cbBlockspaceNew = cBlocksNew * sizeof(VDIIMAGEBLOCKPOINTER); /** < Required space for the block array after the resize. */
uint64_t offStartDataNew = RT_ALIGN_32(pImage->offStartBlocks + cbBlockspaceNew, VDI_DATA_ALIGN); /** < New start offset for block data after the resize */
&& cBlocksAllocated > 0)
cBlocksReloc++;
if (!pvBuf)
if (!pvZero)
for (unsigned i = 0; i < cBlocksReloc; i++)
uBlock++;
if (pvBuf)
if (pvZero)
PVDIIMAGEBLOCKPOINTER paBlocksNew = (PVDIIMAGEBLOCKPOINTER)RTMemRealloc(pImage->paBlocks, cbBlockspaceNew);
if (paBlocksNew)
if (pGeometry)
return rc;
sizeof(VBOXHDDBACKEND),
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,