diff options
Diffstat (limited to 'src/VBox/Storage/DMG.cpp')
-rw-r--r-- | src/VBox/Storage/DMG.cpp | 663 |
1 files changed, 446 insertions, 217 deletions
diff --git a/src/VBox/Storage/DMG.cpp b/src/VBox/Storage/DMG.cpp index 39fe1587..b5f22f0f 100644 --- a/src/VBox/Storage/DMG.cpp +++ b/src/VBox/Storage/DMG.cpp @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2010 Oracle Corporation + * Copyright (C) 2010-2013 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -20,19 +20,30 @@ *******************************************************************************/ #define LOG_GROUP LOG_GROUP_VD_DMG #include <VBox/vd-plugin.h> +#include <VBox/vd-ifs.h> #include <VBox/log.h> #include <VBox/err.h> -#include <iprt/assert.h> + #include <iprt/asm.h> -#include <iprt/mem.h> +#include <iprt/alloca.h> +#include <iprt/assert.h> +#include <iprt/base64.h> #include <iprt/ctype.h> +#include <iprt/mem.h> #include <iprt/string.h> -#include <iprt/base64.h> #include <iprt/zip.h> +#include <iprt/formats/xar.h> + /******************************************************************************* * Structures and Typedefs * *******************************************************************************/ +#if 0 +/** @def VBOX_WITH_DIRECT_XAR_ACCESS + * When defined, we will use RTVfs to access the XAR file instead of going + * the slightly longer way thru the VFS -> VD wrapper. */ +# define VBOX_WITH_DIRECT_XAR_ACCESS +#endif /** Sector size, multiply with all sector counts to get number of bytes. */ #define DMG_SECTOR_SIZE 512 @@ -310,8 +321,16 @@ typedef struct DMGIMAGE PVDINTERFACE pVDIfsImage; /** Error interface. */ PVDINTERFACEERROR pIfError; - /** I/O interface. */ - PVDINTERFACEIOINT pIfIo; + /** I/O interface - careful accessing this because of hDmgFileInXar. */ + PVDINTERFACEIOINT pIfIoXxx; + + + /** The VFS file handle for a DMG within a XAR archive. */ + RTVFSFILE hDmgFileInXar; + /** XAR file system stream handle. + * Sitting on this isn't really necessary, but insurance against the XAR code + * changes making back references from child objects to the stream itself. */ + RTVFSFSSTREAM hXarFss; /** Flags the image was opened with. */ uint32_t uOpenFlags; @@ -392,9 +411,6 @@ typedef struct DMGINFLATESTATE } \ } while (0) -/** VBoxDMG: Unable to parse the XML. */ -#define VERR_VD_DMG_XML_PARSE_ERROR (-3280) - /******************************************************************************* * Static Variables * @@ -420,6 +436,73 @@ static void dmgUdifCkSumHost2FileEndian(PDMGUDIFCKSUM pCkSum); static void dmgUdifCkSumFile2HostEndian(PDMGUDIFCKSUM pCkSum); static bool dmgUdifCkSumIsValid(PCDMGUDIFCKSUM pCkSum, const char *pszPrefix); + + +/** + * vdIfIoIntFileReadSync / RTVfsFileReadAt wrapper. + */ +static int dmgWrapFileReadSync(PDMGIMAGE pThis, RTFOFF off, void *pvBuf, size_t cbToRead) +{ + int rc; + if (pThis->hDmgFileInXar == NIL_RTVFSFILE) + rc = vdIfIoIntFileReadSync(pThis->pIfIoXxx, pThis->pStorage, off, pvBuf, cbToRead); + else + rc = RTVfsFileReadAt(pThis->hDmgFileInXar, off, pvBuf, cbToRead, NULL); + return rc; +} + +/** + * vdIfIoIntFileReadUser / RTVfsFileReadAt wrapper. + */ +static int dmgWrapFileReadUser(PDMGIMAGE pThis, RTFOFF off, PVDIOCTX pIoCtx, size_t cbToRead) +{ + int rc; + if (pThis->hDmgFileInXar == NIL_RTVFSFILE) + rc = vdIfIoIntFileReadUser(pThis->pIfIoXxx, pThis->pStorage, off, pIoCtx, cbToRead); + else + { + /* + * Alloate a temporary buffer on the stack or heap and use + * vdIfIoIntIoCtxCopyTo to work the context. + * + * The I/O context stuff seems too complicated and undocument that I'm + * not going to bother trying to implement this efficiently right now. + */ + void *pvFree = NULL; + void *pvBuf; + if (cbToRead < _32K) + pvBuf = alloca(cbToRead); + else + pvFree = pvBuf = RTMemTmpAlloc(cbToRead); + if (pvBuf) + { + rc = RTVfsFileReadAt(pThis->hDmgFileInXar, off, pvBuf, cbToRead, NULL); + if (RT_SUCCESS(rc)) + vdIfIoIntIoCtxCopyTo(pThis->pIfIoXxx, pIoCtx, pvBuf, cbToRead); + if (pvFree) + RTMemTmpFree(pvFree); + } + else + rc = VERR_NO_TMP_MEMORY; + } + return rc; +} + +/** + * vdIfIoIntFileGetSize / RTVfsFileGetSize wrapper. + */ +static int dmgWrapFileGetSize(PDMGIMAGE pThis, uint64_t *pcbFile) +{ + int rc; + if (pThis->hDmgFileInXar == NIL_RTVFSFILE) + rc = vdIfIoIntFileGetSize(pThis->pIfIoXxx, pThis->pStorage, pcbFile); + else + rc = RTVfsFileGetSize(pThis->hDmgFileInXar, pcbFile); + return rc; +} + + + static DECLCALLBACK(int) dmgFileInflateHelper(void *pvUser, void *pvBuf, size_t cbBuf, size_t *pcbBuf) { DMGINFLATESTATE *pInflateState = (DMGINFLATESTATE *)pvUser; @@ -434,10 +517,7 @@ static DECLCALLBACK(int) dmgFileInflateHelper(void *pvUser, void *pvBuf, size_t return VINF_SUCCESS; } cbBuf = RT_MIN(cbBuf, pInflateState->cbSize); - int rc = vdIfIoIntFileReadSync(pInflateState->pImage->pIfIo, - pInflateState->pImage->pStorage, - pInflateState->uFileOffset, - pvBuf, cbBuf, NULL); + int rc = dmgWrapFileReadSync(pInflateState->pImage, pInflateState->uFileOffset, pvBuf, cbBuf); if (RT_FAILURE(rc)) return rc; pInflateState->uFileOffset += cbBuf; @@ -712,10 +792,11 @@ static int dmgFlushImage(PDMGIMAGE pThis) { int rc = VINF_SUCCESS; - if ( pThis->pStorage + if ( pThis + && (pThis->pStorage || pThis->hDmgFileInXar != NIL_RTVFSFILE) && !(pThis->uOpenFlags & VD_OPEN_FLAGS_READONLY)) { - /* @todo handle writable files, update checksums etc. */ + /** @todo handle writable files, update checksums etc. */ } return rc; @@ -734,13 +815,19 @@ static int dmgFreeImage(PDMGIMAGE pThis, bool fDelete) * not signalled as an error. After all nothing bad happens. */ if (pThis) { + RTVfsFileRelease(pThis->hDmgFileInXar); + pThis->hDmgFileInXar = NIL_RTVFSFILE; + + RTVfsFsStrmRelease(pThis->hXarFss); + pThis->hXarFss = NIL_RTVFSFSSTREAM; + if (pThis->pStorage) { /* No point updating the file that is deleted anyway. */ if (!fDelete) dmgFlushImage(pThis); - vdIfIoIntFileClose(pThis->pIfIo, pThis->pStorage); + rc = vdIfIoIntFileClose(pThis->pIfIoXxx, pThis->pStorage); pThis->pStorage = NULL; } @@ -765,7 +852,7 @@ static int dmgFreeImage(PDMGIMAGE pThis, bool fDelete) } if (fDelete && pThis->pszFilename) - vdIfIoIntFileDelete(pThis->pIfIo, pThis->pszFilename); + vdIfIoIntFileDelete(pThis->pIfIoXxx, pThis->pszFilename); if (pThis->pvDecompExtent) { @@ -773,7 +860,6 @@ static int dmgFreeImage(PDMGIMAGE pThis, bool fDelete) pThis->pvDecompExtent = NULL; pThis->cbDecompExtent = 0; } - } LogFlowFunc(("returns %Rrc\n", rc)); @@ -1356,6 +1442,103 @@ static int dmgBlkxParse(PDMGIMAGE pThis, PDMGBLKX pBlkx) return rc; } + +/** + * Worker for dmgOpenImage that tries to open a DMG inside a XAR file. + * + * We'll select the first .dmg inside the archive that we can get a file + * interface to. + * + * @returns VBox status code. + * @param fOpen Flags for defining the open type. + * @param pVDIfIoInt The internal VD I/O interface to use. + * @param pvStorage The storage pointer that goes with @a pVDIfsIo. + * @param pszFilename The input filename, optional. + * @param phXarFss Where to return the XAR file system stream handle on + * success + * @param phDmgFileInXar Where to return the VFS handle to the DMG file + * within the XAR image on success. + * + * @remarks Not using the PDMGIMAGE structure directly here because the function + * is being in serveral places. + */ +static int dmgOpenImageWithinXar(uint32_t fOpen, PVDINTERFACEIOINT pVDIfIoInt, void *pvStorage, const char *pszFilename, + PRTVFSFSSTREAM phXarFss, PRTVFSFILE phDmgFileInXar) +{ + /* + * Open the XAR file stream. + */ + RTVFSFILE hVfsFile; +#ifdef VBOX_WITH_DIRECT_XAR_ACCESS + int rc = RTVfsFileOpenNormal(pszFilename, fOpen, &hVfsFile); +#else + int rc = VDIfCreateVfsFile(NULL, pVDIfIoInt, pvStorage, fOpen, &hVfsFile); +#endif + if (RT_FAILURE(rc)) + return rc; + + RTVFSIOSTREAM hVfsIos = RTVfsFileToIoStream(hVfsFile); + RTVfsFileRelease(hVfsFile); + + RTVFSFSSTREAM hXarFss; + rc = RTZipXarFsStreamFromIoStream(hVfsIos, 0 /*fFlags*/, &hXarFss); + RTVfsIoStrmRelease(hVfsIos); + if (RT_FAILURE(rc)) + return rc; + + /* + * Look for a DMG in the stream that we can use. + */ + for (;;) + { + char *pszName; + RTVFSOBJTYPE enmType; + RTVFSOBJ hVfsObj; + rc = RTVfsFsStrmNext(hXarFss, &pszName, &enmType, &hVfsObj); + if (RT_FAILURE(rc)) + break; + + /* It must be a file object so it can be seeked, this also implies that + it's uncompressed. Then it must have the .dmg suffix. */ + if (enmType == RTVFSOBJTYPE_FILE) + { + size_t cchName = strlen(pszName); + const char *pszSuff = pszName + cchName - 4; + if ( cchName >= 4 + && pszSuff[0] == '.' + && (pszSuff[1] == 'd' || pszSuff[1] == 'D') + && (pszSuff[2] == 'm' || pszSuff[2] == 'M') + && (pszSuff[3] == 'g' || pszSuff[3] == 'G')) + { + RTVFSFILE hDmgFileInXar = RTVfsObjToFile(hVfsObj); + AssertBreakStmt(hDmgFileInXar != NIL_RTVFSFILE, rc = VERR_INTERNAL_ERROR_3); + + if (pszFilename) + DMG_PRINTF(("DMG: Using '%s' within XAR file '%s'...\n", pszName, pszFilename)); + *phXarFss = hXarFss; + *phDmgFileInXar = hDmgFileInXar; + + RTStrFree(pszName); + RTVfsObjRelease(hVfsObj); + + return VINF_SUCCESS; + } + } + + /* Release the current return values. */ + RTStrFree(pszName); + RTVfsObjRelease(hVfsObj); + } + + /* Not found or some kind of error. */ + RTVfsFsStrmRelease(hXarFss); + if (rc == VERR_EOF) + rc = VERR_VD_DMG_NOT_FOUND_INSIDE_XAR; + AssertStmt(RT_FAILURE_NP(rc), rc = VERR_INTERNAL_ERROR_4); + return rc; +} + + /** * Worker for dmgOpen that reads in and validates all the necessary * structures from the image. @@ -1369,12 +1552,13 @@ static int dmgOpenImage(PDMGIMAGE pThis, unsigned uOpenFlags) pThis->uOpenFlags = uOpenFlags; pThis->pIfError = VDIfErrorGet(pThis->pVDIfsDisk); - pThis->pIfIo = VDIfIoIntGet(pThis->pVDIfsImage); - AssertPtrReturn(pThis->pIfIo, VERR_INVALID_PARAMETER); + pThis->pIfIoXxx = VDIfIoIntGet(pThis->pVDIfsImage); + pThis->hDmgFileInXar = NIL_RTVFSFILE; + pThis->hXarFss = NIL_RTVFSFSSTREAM; + AssertPtrReturn(pThis->pIfIoXxx, VERR_INVALID_PARAMETER); - int rc = vdIfIoIntFileOpen(pThis->pIfIo, pThis->pszFilename, - VDOpenFlagsToFileOpenFlags(uOpenFlags, - false /* fCreate */), + int rc = vdIfIoIntFileOpen(pThis->pIfIoXxx, pThis->pszFilename, + VDOpenFlagsToFileOpenFlags(uOpenFlags, false /* fCreate */), &pThis->pStorage); if (RT_FAILURE(rc)) { @@ -1384,16 +1568,47 @@ static int dmgOpenImage(PDMGIMAGE pThis, unsigned uOpenFlags) } /* + * Check for XAR archive. + */ + uint32_t u32XarMagic; + rc = dmgWrapFileReadSync(pThis, 0, &u32XarMagic, sizeof(u32XarMagic)); + if (RT_FAILURE(rc)) + return rc; + if (u32XarMagic == XAR_HEADER_MAGIC) + { + rc = dmgOpenImageWithinXar(VDOpenFlagsToFileOpenFlags(uOpenFlags, false /* fCreate */), + pThis->pIfIoXxx, + pThis->pStorage, + pThis->pszFilename, + &pThis->hXarFss, &pThis->hDmgFileInXar); + if (RT_FAILURE(rc)) + return rc; +#ifdef VBOX_WITH_DIRECT_XAR_ACCESS + vdIfIoIntFileClose(pThis->pIfIoXxx, pThis->pStorage); + pThis->pStorage = NULL; +#endif + } +#if 0 /* This is for testing whether the VFS wrappers actually works. */ + else + { + rc = RTVfsFileOpenNormal(pThis->pszFilename, VDOpenFlagsToFileOpenFlags(uOpenFlags, false /* fCreate */), + &pThis->hDmgFileInXar); + if (RT_FAILURE(rc)) + return rc; + vdIfIoIntFileClose(pThis->pIfIoXxx, pThis->pStorage); + pThis->pStorage = NULL; + } +#endif + + /* * Read the footer. */ - rc = vdIfIoIntFileGetSize(pThis->pIfIo, pThis->pStorage, &pThis->cbFile); + rc = dmgWrapFileGetSize(pThis, &pThis->cbFile); if (RT_FAILURE(rc)) return rc; if (pThis->cbFile < 1024) return VERR_VD_DMG_INVALID_HEADER; - rc = vdIfIoIntFileReadSync(pThis->pIfIo, pThis->pStorage, - pThis->cbFile - sizeof(pThis->Ftr), - &pThis->Ftr, sizeof(pThis->Ftr), NULL); + rc = dmgWrapFileReadSync(pThis, pThis->cbFile - sizeof(pThis->Ftr), &pThis->Ftr, sizeof(pThis->Ftr)); if (RT_FAILURE(rc)) return rc; dmgUdifFtrFile2HostEndian(&pThis->Ftr); @@ -1423,8 +1638,7 @@ static int dmgOpenImage(PDMGIMAGE pThis, unsigned uOpenFlags) char *pszXml = (char *)RTMemAlloc(cchXml + 1); if (!pszXml) return VERR_NO_MEMORY; - rc = vdIfIoIntFileReadSync(pThis->pIfIo, pThis->pStorage, pThis->Ftr.offXml, - pszXml, cchXml, NULL); + rc = dmgWrapFileReadSync(pThis, pThis->Ftr.offXml, pszXml, cchXml); if (RT_SUCCESS(rc)) { pszXml[cchXml] = '\0'; @@ -1488,94 +1702,112 @@ static int dmgOpenImage(PDMGIMAGE pThis, unsigned uOpenFlags) } -/** @copydoc VBOXHDDBACKEND::pfnCheckIfValid */ -static int dmgCheckIfValid(const char *pszFilename, PVDINTERFACE pVDIfsDisk, - PVDINTERFACE pVDIfsImage, VDTYPE *penmType) +/** @interface_method_impl{VBOXHDDBACKEND,pfnCheckIfValid} */ +static DECLCALLBACK(int) dmgCheckIfValid(const char *pszFilename, PVDINTERFACE pVDIfsDisk, + PVDINTERFACE pVDIfsImage, VDTYPE *penmType) { LogFlowFunc(("pszFilename=\"%s\" pVDIfsDisk=%#p pVDIfsImage=%#p penmType=%#p\n", pszFilename, pVDIfsDisk, pVDIfsImage, penmType)); - int rc; - PVDIOSTORAGE pStorage; - uint64_t cbFile, offFtr = 0; - DMGUDIF Ftr; PVDINTERFACEIOINT pIfIo = VDIfIoIntGet(pVDIfsImage); AssertPtrReturn(pIfIo, VERR_INVALID_PARAMETER); /* - * Open the file and read the footer. + * Open the file and check for XAR. */ - rc = vdIfIoIntFileOpen(pIfIo, pszFilename, - VDOpenFlagsToFileOpenFlags(VD_OPEN_FLAGS_READONLY, - false /* fCreate */), - &pStorage); - if (RT_SUCCESS(rc)) - rc = vdIfIoIntFileGetSize(pIfIo, pStorage, &cbFile); - if (RT_SUCCESS(rc)) + PVDIOSTORAGE pStorage = NULL; + int rc = vdIfIoIntFileOpen(pIfIo, pszFilename, + VDOpenFlagsToFileOpenFlags(VD_OPEN_FLAGS_READONLY, false /* fCreate */), + &pStorage); + if (RT_FAILURE(rc)) { - offFtr = cbFile - sizeof(Ftr); - rc = vdIfIoIntFileReadSync(pIfIo, pStorage, offFtr, &Ftr, sizeof(Ftr), NULL); + LogFlowFunc(("returns %Rrc (error opening file)\n", rc)); + return rc; } - else + + /* + * Check for XAR file. + */ + RTVFSFSSTREAM hXarFss = NIL_RTVFSFSSTREAM; + RTVFSFILE hDmgFileInXar = NIL_RTVFSFILE; + uint32_t u32XarMagic; + rc = vdIfIoIntFileReadSync(pIfIo, pStorage, 0, &u32XarMagic, sizeof(u32XarMagic)); + if ( RT_SUCCESS(rc) + && u32XarMagic == XAR_HEADER_MAGIC) { - vdIfIoIntFileClose(pIfIo, pStorage); - rc = VERR_VD_DMG_INVALID_HEADER; + rc = dmgOpenImageWithinXar(RTFILE_O_OPEN | RTFILE_O_READ | RTFILE_O_DENY_WRITE, + pIfIo, pStorage, pszFilename, + &hXarFss, &hDmgFileInXar); + if (RT_FAILURE(rc)) + return rc; } + /* + * Read the DMG footer. + */ + uint64_t cbFile; + if (hDmgFileInXar == NIL_RTVFSFILE) + rc = vdIfIoIntFileGetSize(pIfIo, pStorage, &cbFile); + else + rc = RTVfsFileGetSize(hDmgFileInXar, &cbFile); if (RT_SUCCESS(rc)) { - /* - * Do we recognize this stuff? Does it look valid? - */ - if ( Ftr.u32Magic == RT_H2BE_U32(DMGUDIF_MAGIC) - && Ftr.u32Version == RT_H2BE_U32(DMGUDIF_VER_CURRENT) - && Ftr.cbFooter == RT_H2BE_U32(sizeof(Ftr))) + DMGUDIF Ftr; + uint64_t offFtr = cbFile - sizeof(Ftr); + if (hDmgFileInXar == NIL_RTVFSFILE) + rc = vdIfIoIntFileReadSync(pIfIo, pStorage, offFtr, &Ftr, sizeof(Ftr)); + else + rc = RTVfsFileReadAt(hDmgFileInXar, offFtr, &Ftr, sizeof(Ftr), NULL); + if (RT_SUCCESS(rc)) { - dmgUdifFtrFile2HostEndian(&Ftr); - if (dmgUdifFtrIsValid(&Ftr, offFtr)) + /* + * Do we recognize this stuff? Does it look valid? + */ + if ( Ftr.u32Magic == RT_H2BE_U32_C(DMGUDIF_MAGIC) + && Ftr.u32Version == RT_H2BE_U32_C(DMGUDIF_VER_CURRENT) + && Ftr.cbFooter == RT_H2BE_U32_C(sizeof(Ftr))) { - rc = VINF_SUCCESS; - *penmType = VDTYPE_DVD; + dmgUdifFtrFile2HostEndian(&Ftr); + if (dmgUdifFtrIsValid(&Ftr, offFtr)) + { + rc = VINF_SUCCESS; + *penmType = VDTYPE_DVD; + } + else + { + DMG_PRINTF(("Bad DMG: '%s' offFtr=%RTfoff\n", pszFilename, offFtr)); + rc = VERR_VD_DMG_INVALID_HEADER; + } } else - { - DMG_PRINTF(("Bad DMG: '%s' offFtr=%RTfoff\n", pszFilename, offFtr)); rc = VERR_VD_DMG_INVALID_HEADER; - } } - else - rc = VERR_VD_DMG_INVALID_HEADER; } + else + rc = VERR_VD_DMG_INVALID_HEADER; + /* Clean up. */ + RTVfsFileRelease(hDmgFileInXar); + RTVfsFsStrmRelease(hXarFss); vdIfIoIntFileClose(pIfIo, pStorage); LogFlowFunc(("returns %Rrc\n", rc)); return rc; } -/** @copydoc VBOXHDDBACKEND::pfnOpen */ -static int dmgOpen(const char *pszFilename, unsigned uOpenFlags, - PVDINTERFACE pVDIfsDisk, PVDINTERFACE pVDIfsImage, - VDTYPE enmType, void **ppBackendData) +/** @interface_method_impl{VBOXHDDBACKEND,pfnOpen} */ +static DECLCALLBACK(int) dmgOpen(const char *pszFilename, unsigned uOpenFlags, + PVDINTERFACE pVDIfsDisk, PVDINTERFACE pVDIfsImage, + VDTYPE enmType, void **ppBackendData) { LogFlowFunc(("pszFilename=\"%s\" uOpenFlags=%#x pVDIfsDisk=%#p pVDIfsImage=%#p ppBackendData=%#p\n", pszFilename, uOpenFlags, pVDIfsDisk, pVDIfsImage, ppBackendData)); - int rc = VINF_SUCCESS; - PDMGIMAGE pThis; /* Check open flags. All valid flags are (in principle) supported. */ - if (uOpenFlags & ~VD_OPEN_FLAGS_MASK) - { - rc = VERR_INVALID_PARAMETER; - goto out; - } + AssertReturn(!(uOpenFlags & ~VD_OPEN_FLAGS_MASK), VERR_INVALID_PARAMETER); /* Check remaining arguments. */ - if ( !VALID_PTR(pszFilename) - || !*pszFilename) - { - rc = VERR_INVALID_PARAMETER; - goto out; - } + AssertPtrReturn(pszFilename, VERR_INVALID_POINTER); + AssertReturn(*pszFilename, VERR_INVALID_PARAMETER); /* * Reject combinations we don't currently support. @@ -1587,45 +1819,42 @@ static int dmgOpen(const char *pszFilename, unsigned uOpenFlags, if ( !(uOpenFlags & VD_OPEN_FLAGS_READONLY) || (uOpenFlags & VD_OPEN_FLAGS_ASYNC_IO)) { - rc = VERR_NOT_SUPPORTED; - goto out; + LogFlowFunc(("Unsupported flag(s): %#x\n", uOpenFlags)); + return VERR_INVALID_PARAMETER; } /* * Create the basic instance data structure and open the file, * then hand it over to a worker function that does all the rest. */ - pThis = (PDMGIMAGE)RTMemAllocZ(sizeof(*pThis)); - if (!pThis) + int rc = VERR_NO_MEMORY; + PDMGIMAGE pThis = (PDMGIMAGE)RTMemAllocZ(sizeof(*pThis)); + if (pThis) { - rc = VERR_NO_MEMORY; - goto out; - } + pThis->pszFilename = pszFilename; + pThis->pStorage = NULL; + pThis->pVDIfsDisk = pVDIfsDisk; + pThis->pVDIfsImage = pVDIfsImage; - pThis->pszFilename = pszFilename; - pThis->pStorage = NULL; - pThis->pVDIfsDisk = pVDIfsDisk; - pThis->pVDIfsImage = pVDIfsImage; - - rc = dmgOpenImage(pThis, uOpenFlags); - if (RT_SUCCESS(rc)) - *ppBackendData = pThis; - else - RTMemFree(pThis); + rc = dmgOpenImage(pThis, uOpenFlags); + if (RT_SUCCESS(rc)) + *ppBackendData = pThis; + else + RTMemFree(pThis); + } -out: LogFlowFunc(("returns %Rrc (pBackendData=%#p)\n", rc, *ppBackendData)); return rc; } -/** @copydoc VBOXHDDBACKEND::pfnCreate */ -static int dmgCreate(const char *pszFilename, uint64_t cbSize, - unsigned uImageFlags, const char *pszComment, - PCVDGEOMETRY pPCHSGeometry, PCVDGEOMETRY pLCHSGeometry, - PCRTUUID pUuid, unsigned uOpenFlags, - unsigned uPercentStart, unsigned uPercentSpan, - PVDINTERFACE pVDIfsDisk, PVDINTERFACE pVDIfsImage, - PVDINTERFACE pVDIfsOperation, void **ppBackendData) +/** @interface_method_impl{VBOXHDDBACKEND,pfnCreate} */ +static DECLCALLBACK(int) dmgCreate(const char *pszFilename, uint64_t cbSize, + unsigned uImageFlags, const char *pszComment, + PCVDGEOMETRY pPCHSGeometry, PCVDGEOMETRY pLCHSGeometry, + PCRTUUID pUuid, unsigned uOpenFlags, + unsigned uPercentStart, unsigned uPercentSpan, + PVDINTERFACE pVDIfsDisk, PVDINTERFACE pVDIfsImage, + PVDINTERFACE pVDIfsOperation, void **ppBackendData) { 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", pszFilename, cbSize, uImageFlags, pszComment, pPCHSGeometry, pLCHSGeometry, pUuid, uOpenFlags, uPercentStart, uPercentSpan, pVDIfsDisk, pVDIfsImage, pVDIfsOperation, ppBackendData)); int rc = VERR_NOT_SUPPORTED; @@ -1634,7 +1863,7 @@ static int dmgCreate(const char *pszFilename, uint64_t cbSize, return rc; } -/** @copydoc VBOXHDDBACKEND::pfnRename */ +/** @interface_method_impl{VBOXHDDBACKEND,pfnRename} */ static int dmgRename(void *pBackendData, const char *pszFilename) { LogFlowFunc(("pBackendData=%#p pszFilename=%#p\n", pBackendData, pszFilename)); @@ -1644,25 +1873,25 @@ static int dmgRename(void *pBackendData, const char *pszFilename) return rc; } -/** @copydoc VBOXHDDBACKEND::pfnClose */ -static int dmgClose(void *pBackendData, bool fDelete) +/** @interface_method_impl{VBOXHDDBACKEND,pfnClose} */ +static DECLCALLBACK(int) dmgClose(void *pBackendData, bool fDelete) { LogFlowFunc(("pBackendData=%#p fDelete=%d\n", pBackendData, fDelete)); PDMGIMAGE pThis = (PDMGIMAGE)pBackendData; - int rc; - rc = dmgFreeImage(pThis, fDelete); + int rc = dmgFreeImage(pThis, fDelete); RTMemFree(pThis); LogFlowFunc(("returns %Rrc\n", rc)); return rc; } -/** @copydoc VBOXHDDBACKEND::pfnRead */ -static int dmgRead(void *pBackendData, uint64_t uOffset, void *pvBuf, - size_t cbToRead, size_t *pcbActuallyRead) +/** @interface_method_impl{VBOXHDDBACKEND,pfnRead} */ +static DECLCALLBACK(int) dmgRead(void *pBackendData, uint64_t uOffset, size_t cbToRead, + PVDIOCTX pIoCtx, size_t *pcbActuallyRead) { - LogFlowFunc(("pBackendData=%#p uOffset=%llu pvBuf=%#p cbToRead=%zu pcbActuallyRead=%#p\n", pBackendData, uOffset, pvBuf, cbToRead, pcbActuallyRead)); + LogFlowFunc(("pBackendData=%#p uOffset=%llu pIoCtx=%#p cbToRead=%zu pcbActuallyRead=%#p\n", + pBackendData, uOffset, pIoCtx, cbToRead, pcbActuallyRead)); PDMGIMAGE pThis = (PDMGIMAGE)pBackendData; PDMGEXTENT pExtent = NULL; int rc = VINF_SUCCESS; @@ -1674,8 +1903,8 @@ static int dmgRead(void *pBackendData, uint64_t uOffset, void *pvBuf, if ( uOffset + cbToRead > pThis->cbSize || cbToRead == 0) { - rc = VERR_INVALID_PARAMETER; - goto out; + LogFlowFunc(("returns VERR_INVALID_PARAMETER\n")); + return VERR_INVALID_PARAMETER; } pExtent = dmgExtentGetFromOffset(pThis, DMG_BYTE2BLOCK(uOffset)); @@ -1691,14 +1920,12 @@ static int dmgRead(void *pBackendData, uint64_t uOffset, void *pvBuf, { case DMGEXTENTTYPE_RAW: { - rc = vdIfIoIntFileReadSync(pThis->pIfIo, pThis->pStorage, - pExtent->offFileStart + DMG_BLOCK2BYTE(uExtentRel), - pvBuf, cbToRead, NULL); + rc = dmgWrapFileReadUser(pThis, pExtent->offFileStart + DMG_BLOCK2BYTE(uExtentRel), pIoCtx, cbToRead); break; } case DMGEXTENTTYPE_ZERO: { - memset(pvBuf, 0, cbToRead); + vdIfIoIntIoCtxSet(pThis->pIfIoXxx, pIoCtx, 0, cbToRead); break; } case DMGEXTENTTYPE_COMP_ZLIB: @@ -1728,7 +1955,9 @@ static int dmgRead(void *pBackendData, uint64_t uOffset, void *pvBuf, } if (RT_SUCCESS(rc)) - memcpy(pvBuf, (uint8_t *)pThis->pvDecompExtent + DMG_BLOCK2BYTE(uExtentRel), cbToRead); + vdIfIoIntIoCtxCopyTo(pThis->pIfIoXxx, pIoCtx, + (uint8_t *)pThis->pvDecompExtent + DMG_BLOCK2BYTE(uExtentRel), + cbToRead); break; } default: @@ -1741,18 +1970,17 @@ static int dmgRead(void *pBackendData, uint64_t uOffset, void *pvBuf, else rc = VERR_INVALID_PARAMETER; -out: LogFlowFunc(("returns %Rrc\n", rc)); return rc; } -/** @copydoc VBOXHDDBACKEND::pfnWrite */ -static int dmgWrite(void *pBackendData, uint64_t uOffset, const void *pvBuf, - size_t cbToWrite, size_t *pcbWriteProcess, - size_t *pcbPreRead, size_t *pcbPostRead, unsigned fWrite) +/** @interface_method_impl{VBOXHDDBACKEND,pfnWrite} */ +static DECLCALLBACK(int) dmgWrite(void *pBackendData, uint64_t uOffset, size_t cbToWrite, + PVDIOCTX pIoCtx, size_t *pcbWriteProcess, size_t *pcbPreRead, + size_t *pcbPostRead, unsigned fWrite) { - LogFlowFunc(("pBackendData=%#p uOffset=%llu pvBuf=%#p cbToWrite=%zu pcbWriteProcess=%#p pcbPreRead=%#p pcbPostRead=%#p\n", - pBackendData, uOffset, pvBuf, cbToWrite, pcbWriteProcess, pcbPreRead, pcbPostRead)); + LogFlowFunc(("pBackendData=%#p uOffset=%llu pIoCtx=%#p cbToWrite=%zu pcbWriteProcess=%#p pcbPreRead=%#p pcbPostRead=%#p\n", + pBackendData, uOffset, pIoCtx, cbToWrite, pcbWriteProcess, pcbPreRead, pcbPostRead)); PDMGIMAGE pThis = (PDMGIMAGE)pBackendData; int rc = VERR_NOT_IMPLEMENTED; @@ -1760,21 +1988,17 @@ static int dmgWrite(void *pBackendData, uint64_t uOffset, const void *pvBuf, Assert(uOffset % 512 == 0); Assert(cbToWrite % 512 == 0); - if (pThis->uOpenFlags & VD_OPEN_FLAGS_READONLY) - { + if (!(pThis->uOpenFlags & VD_OPEN_FLAGS_READONLY)) + AssertMsgFailed(("Not implemented\n")); + else rc = VERR_VD_IMAGE_READ_ONLY; - goto out; - } - - AssertMsgFailed(("Not implemented\n")); -out: LogFlowFunc(("returns %Rrc\n", rc)); return rc; } -/** @copydoc VBOXHDDBACKEND::pfnFlush */ -static int dmgFlush(void *pBackendData) +/** @interface_method_impl{VBOXHDDBACKEND,pfnFlush} */ +static DECLCALLBACK(int) dmgFlush(void *pBackendData, PVDIOCTX pIoCtx) { LogFlowFunc(("pBackendData=%#p\n", pBackendData)); PDMGIMAGE pThis = (PDMGIMAGE)pBackendData; @@ -1788,8 +2012,8 @@ static int dmgFlush(void *pBackendData) return rc; } -/** @copydoc VBOXHDDBACKEND::pfnGetVersion */ -static unsigned dmgGetVersion(void *pBackendData) +/** @interface_method_impl{VBOXHDDBACKEND,pfnGetVersion} */ +static DECLCALLBACK(unsigned) dmgGetVersion(void *pBackendData) { LogFlowFunc(("pBackendData=%#p\n", pBackendData)); PDMGIMAGE pThis = (PDMGIMAGE)pBackendData; @@ -1802,8 +2026,24 @@ static unsigned dmgGetVersion(void *pBackendData) return 0; } -/** @copydoc VBOXHDDBACKEND::pfnGetSize */ -static uint64_t dmgGetSize(void *pBackendData) +/** @interface_method_impl{VBOXHDDBACKEND,pfnGetSectorSize} */ +static DECLCALLBACK(uint32_t) dmgGetSectorSize(void *pBackendData) +{ + LogFlowFunc(("pBackendData=%#p\n", pBackendData)); + PDMGIMAGE pThis = (PDMGIMAGE)pBackendData; + uint32_t cb = 0; + + AssertPtr(pThis); + + if (pThis && (pThis->pStorage || pThis->hDmgFileInXar != NIL_RTVFSFILE)) + cb = 2048; + + LogFlowFunc(("returns %u\n", cb)); + return cb; +} + +/** @interface_method_impl{VBOXHDDBACKEND,pfnGetSize} */ +static DECLCALLBACK(uint64_t) dmgGetSize(void *pBackendData) { LogFlowFunc(("pBackendData=%#p\n", pBackendData)); PDMGIMAGE pThis = (PDMGIMAGE)pBackendData; @@ -1811,15 +2051,15 @@ static uint64_t dmgGetSize(void *pBackendData) AssertPtr(pThis); - if (pThis && pThis->pStorage) + if (pThis && (pThis->pStorage || pThis->hDmgFileInXar != NIL_RTVFSFILE)) cb = pThis->cbSize; LogFlowFunc(("returns %llu\n", cb)); return cb; } -/** @copydoc VBOXHDDBACKEND::pfnGetFileSize */ -static uint64_t dmgGetFileSize(void *pBackendData) +/** @interface_method_impl{VBOXHDDBACKEND,pfnGetFileSize} */ +static DECLCALLBACK(uint64_t) dmgGetFileSize(void *pBackendData) { LogFlowFunc(("pBackendData=%#p\n", pBackendData)); PDMGIMAGE pThis = (PDMGIMAGE)pBackendData; @@ -1827,23 +2067,20 @@ static uint64_t dmgGetFileSize(void *pBackendData) AssertPtr(pThis); - if (pThis) + if (pThis && (pThis->pStorage || pThis->hDmgFileInXar != NIL_RTVFSFILE)) { uint64_t cbFile; - if (pThis->pStorage) - { - int rc = vdIfIoIntFileGetSize(pThis->pIfIo, pThis->pStorage, &cbFile); - if (RT_SUCCESS(rc)) - cb = cbFile; - } + int rc = dmgWrapFileGetSize(pThis, &cbFile); + if (RT_SUCCESS(rc)) + cb = cbFile; } LogFlowFunc(("returns %lld\n", cb)); return cb; } -/** @copydoc VBOXHDDBACKEND::pfnGetPCHSGeometry */ -static int dmgGetPCHSGeometry(void *pBackendData, PVDGEOMETRY pPCHSGeometry) +/** @interface_method_impl{VBOXHDDBACKEND,pfnGetPCHSGeometry} */ +static DECLCALLBACK(int) dmgGetPCHSGeometry(void *pBackendData, PVDGEOMETRY pPCHSGeometry) { LogFlowFunc(("pBackendData=%#p pPCHSGeometry=%#p\n", pBackendData, pPCHSGeometry)); PDMGIMAGE pThis = (PDMGIMAGE)pBackendData; @@ -1868,8 +2105,8 @@ static int dmgGetPCHSGeometry(void *pBackendData, PVDGEOMETRY pPCHSGeometry) return rc; } -/** @copydoc VBOXHDDBACKEND::pfnSetPCHSGeometry */ -static int dmgSetPCHSGeometry(void *pBackendData, PCVDGEOMETRY pPCHSGeometry) +/** @interface_method_impl{VBOXHDDBACKEND,pfnSetPCHSGeometry} */ +static DECLCALLBACK(int) dmgSetPCHSGeometry(void *pBackendData, PCVDGEOMETRY pPCHSGeometry) { LogFlowFunc(("pBackendData=%#p pPCHSGeometry=%#p PCHS=%u/%u/%u\n", pBackendData, pPCHSGeometry, pPCHSGeometry->cCylinders, pPCHSGeometry->cHeads, pPCHSGeometry->cSectors)); @@ -1880,25 +2117,23 @@ static int dmgSetPCHSGeometry(void *pBackendData, PCVDGEOMETRY pPCHSGeometry) if (pThis) { - if (pThis->uOpenFlags & VD_OPEN_FLAGS_READONLY) + if (!(pThis->uOpenFlags & VD_OPEN_FLAGS_READONLY)) { - rc = VERR_VD_IMAGE_READ_ONLY; - goto out; + pThis->PCHSGeometry = *pPCHSGeometry; + rc = VINF_SUCCESS; } - - pThis->PCHSGeometry = *pPCHSGeometry; - rc = VINF_SUCCESS; + else + rc = VERR_VD_IMAGE_READ_ONLY; } else rc = VERR_VD_NOT_OPENED; -out: LogFlowFunc(("returns %Rrc\n", rc)); return rc; } -/** @copydoc VBOXHDDBACKEND::pfnGetLCHSGeometry */ -static int dmgGetLCHSGeometry(void *pBackendData, PVDGEOMETRY pLCHSGeometry) +/** @interface_method_impl{VBOXHDDBACKEND,pfnGetLCHSGeometry} */ +static DECLCALLBACK(int) dmgGetLCHSGeometry(void *pBackendData, PVDGEOMETRY pLCHSGeometry) { LogFlowFunc(("pBackendData=%#p pLCHSGeometry=%#p\n", pBackendData, pLCHSGeometry)); PDMGIMAGE pThis = (PDMGIMAGE)pBackendData; @@ -1923,8 +2158,8 @@ static int dmgGetLCHSGeometry(void *pBackendData, PVDGEOMETRY pLCHSGeometry) return rc; } -/** @copydoc VBOXHDDBACKEND::pfnSetLCHSGeometry */ -static int dmgSetLCHSGeometry(void *pBackendData, PCVDGEOMETRY pLCHSGeometry) +/** @interface_method_impl{VBOXHDDBACKEND,pfnSetLCHSGeometry} */ +static DECLCALLBACK(int) dmgSetLCHSGeometry(void *pBackendData, PCVDGEOMETRY pLCHSGeometry) { LogFlowFunc(("pBackendData=%#p pLCHSGeometry=%#p LCHS=%u/%u/%u\n", pBackendData, pLCHSGeometry, pLCHSGeometry->cCylinders, pLCHSGeometry->cHeads, pLCHSGeometry->cSectors)); @@ -1935,25 +2170,23 @@ static int dmgSetLCHSGeometry(void *pBackendData, PCVDGEOMETRY pLCHSGeometry) if (pThis) { - if (pThis->uOpenFlags & VD_OPEN_FLAGS_READONLY) + if (!(pThis->uOpenFlags & VD_OPEN_FLAGS_READONLY)) { - rc = VERR_VD_IMAGE_READ_ONLY; - goto out; + pThis->LCHSGeometry = *pLCHSGeometry; + rc = VINF_SUCCESS; } - - pThis->LCHSGeometry = *pLCHSGeometry; - rc = VINF_SUCCESS; + else + rc = VERR_VD_IMAGE_READ_ONLY; } else rc = VERR_VD_NOT_OPENED; -out: LogFlowFunc(("returns %Rrc\n", rc)); return rc; } -/** @copydoc VBOXHDDBACKEND::pfnGetImageFlags */ -static unsigned dmgGetImageFlags(void *pBackendData) +/** @interface_method_impl{VBOXHDDBACKEND,pfnGetImageFlags} */ +static DECLCALLBACK(unsigned) dmgGetImageFlags(void *pBackendData) { LogFlowFunc(("pBackendData=%#p\n", pBackendData)); PDMGIMAGE pThis = (PDMGIMAGE)pBackendData; @@ -1970,8 +2203,8 @@ static unsigned dmgGetImageFlags(void *pBackendData) return uImageFlags; } -/** @copydoc VBOXHDDBACKEND::pfnGetOpenFlags */ -static unsigned dmgGetOpenFlags(void *pBackendData) +/** @interface_method_impl{VBOXHDDBACKEND,pfnGetOpenFlags} */ +static DECLCALLBACK(unsigned) dmgGetOpenFlags(void *pBackendData) { LogFlowFunc(("pBackendData=%#p\n", pBackendData)); PDMGIMAGE pThis = (PDMGIMAGE)pBackendData; @@ -1988,15 +2221,17 @@ static unsigned dmgGetOpenFlags(void *pBackendData) return uOpenFlags; } -/** @copydoc VBOXHDDBACKEND::pfnSetOpenFlags */ -static int dmgSetOpenFlags(void *pBackendData, unsigned uOpenFlags) +/** @interface_method_impl{VBOXHDDBACKEND,pfnSetOpenFlags} */ +static DECLCALLBACK(int) dmgSetOpenFlags(void *pBackendData, unsigned uOpenFlags) { LogFlowFunc(("pBackendData=%#p\n uOpenFlags=%#x", pBackendData, uOpenFlags)); PDMGIMAGE pThis = (PDMGIMAGE)pBackendData; int rc; /* Image must be opened and the new flags must be valid. */ - if (!pThis || (uOpenFlags & ~(VD_OPEN_FLAGS_READONLY | VD_OPEN_FLAGS_INFO | VD_OPEN_FLAGS_SHAREABLE | VD_OPEN_FLAGS_SEQUENTIAL))) + if (!pThis || (uOpenFlags & ~( VD_OPEN_FLAGS_READONLY | VD_OPEN_FLAGS_INFO + | VD_OPEN_FLAGS_SHAREABLE | VD_OPEN_FLAGS_SEQUENTIAL + | VD_OPEN_FLAGS_SKIP_CONSISTENCY_CHECKS))) { rc = VERR_INVALID_PARAMETER; goto out; @@ -2013,9 +2248,8 @@ out: return rc; } -/** @copydoc VBOXHDDBACKEND::pfnGetComment */ -static int dmgGetComment(void *pBackendData, char *pszComment, - size_t cbComment) +/** @interface_method_impl{VBOXHDDBACKEND,pfnGetComment} */ +static DECLCALLBACK(int) dmgGetComment(void *pBackendData, char *pszComment, size_t cbComment) { LogFlowFunc(("pBackendData=%#p pszComment=%#p cbComment=%zu\n", pBackendData, pszComment, cbComment)); PDMGIMAGE pThis = (PDMGIMAGE)pBackendData; @@ -2032,8 +2266,8 @@ static int dmgGetComment(void *pBackendData, char *pszComment, return rc; } -/** @copydoc VBOXHDDBACKEND::pfnSetComment */ -static int dmgSetComment(void *pBackendData, const char *pszComment) +/** @interface_method_impl{VBOXHDDBACKEND,pfnSetComment} */ +static DECLCALLBACK(int) dmgSetComment(void *pBackendData, const char *pszComment) { LogFlowFunc(("pBackendData=%#p pszComment=\"%s\"\n", pBackendData, pszComment)); PDMGIMAGE pImage = (PDMGIMAGE)pBackendData; @@ -2055,8 +2289,8 @@ static int dmgSetComment(void *pBackendData, const char *pszComment) return rc; } -/** @copydoc VBOXHDDBACKEND::pfnGetUuid */ -static int dmgGetUuid(void *pBackendData, PRTUUID pUuid) +/** @interface_method_impl{VBOXHDDBACKEND,pfnGetUuid} */ +static DECLCALLBACK(int) dmgGetUuid(void *pBackendData, PRTUUID pUuid) { LogFlowFunc(("pBackendData=%#p pUuid=%#p\n", pBackendData, pUuid)); PDMGIMAGE pThis = (PDMGIMAGE)pBackendData; @@ -2073,8 +2307,8 @@ static int dmgGetUuid(void *pBackendData, PRTUUID pUuid) return rc; } -/** @copydoc VBOXHDDBACKEND::pfnSetUuid */ -static int dmgSetUuid(void *pBackendData, PCRTUUID pUuid) +/** @interface_method_impl{VBOXHDDBACKEND,pfnSetUuid} */ +static DECLCALLBACK(int) dmgSetUuid(void *pBackendData, PCRTUUID pUuid) { LogFlowFunc(("pBackendData=%#p Uuid=%RTuuid\n", pBackendData, pUuid)); PDMGIMAGE pThis = (PDMGIMAGE)pBackendData; @@ -2097,8 +2331,8 @@ static int dmgSetUuid(void *pBackendData, PCRTUUID pUuid) return rc; } -/** @copydoc VBOXHDDBACKEND::pfnGetModificationUuid */ -static int dmgGetModificationUuid(void *pBackendData, PRTUUID pUuid) +/** @interface_method_impl{VBOXHDDBACKEND,pfnGetModificationUuid} */ +static DECLCALLBACK(int) dmgGetModificationUuid(void *pBackendData, PRTUUID pUuid) { LogFlowFunc(("pBackendData=%#p pUuid=%#p\n", pBackendData, pUuid)); PDMGIMAGE pThis = (PDMGIMAGE)pBackendData; @@ -2115,8 +2349,8 @@ static int dmgGetModificationUuid(void *pBackendData, PRTUUID pUuid) return rc; } -/** @copydoc VBOXHDDBACKEND::pfnSetModificationUuid */ -static int dmgSetModificationUuid(void *pBackendData, PCRTUUID pUuid) +/** @interface_method_impl{VBOXHDDBACKEND,pfnSetModificationUuid} */ +static DECLCALLBACK(int) dmgSetModificationUuid(void *pBackendData, PCRTUUID pUuid) { LogFlowFunc(("pBackendData=%#p Uuid=%RTuuid\n", pBackendData, pUuid)); PDMGIMAGE pThis = (PDMGIMAGE)pBackendData; @@ -2138,8 +2372,8 @@ static int dmgSetModificationUuid(void *pBackendData, PCRTUUID pUuid) return rc; } -/** @copydoc VBOXHDDBACKEND::pfnGetParentUuid */ -static int dmgGetParentUuid(void *pBackendData, PRTUUID pUuid) +/** @interface_method_impl{VBOXHDDBACKEND,pfnGetParentUuid} */ +static DECLCALLBACK(int) dmgGetParentUuid(void *pBackendData, PRTUUID pUuid) { LogFlowFunc(("pBackendData=%#p pUuid=%#p\n", pBackendData, pUuid)); PDMGIMAGE pThis = (PDMGIMAGE)pBackendData; @@ -2156,8 +2390,8 @@ static int dmgGetParentUuid(void *pBackendData, PRTUUID pUuid) return rc; } -/** @copydoc VBOXHDDBACKEND::pfnSetParentUuid */ -static int dmgSetParentUuid(void *pBackendData, PCRTUUID pUuid) +/** @interface_method_impl{VBOXHDDBACKEND,pfnSetParentUuid} */ +static DECLCALLBACK(int) dmgSetParentUuid(void *pBackendData, PCRTUUID pUuid) { LogFlowFunc(("pBackendData=%#p Uuid=%RTuuid\n", pBackendData, pUuid)); PDMGIMAGE pThis = (PDMGIMAGE)pBackendData; @@ -2179,8 +2413,8 @@ static int dmgSetParentUuid(void *pBackendData, PCRTUUID pUuid) return rc; } -/** @copydoc VBOXHDDBACKEND::pfnGetParentModificationUuid */ -static int dmgGetParentModificationUuid(void *pBackendData, PRTUUID pUuid) +/** @interface_method_impl{VBOXHDDBACKEND,pfnGetParentModificationUuid} */ +static DECLCALLBACK(int) dmgGetParentModificationUuid(void *pBackendData, PRTUUID pUuid) { LogFlowFunc(("pBackendData=%#p pUuid=%#p\n", pBackendData, pUuid)); PDMGIMAGE pThis = (PDMGIMAGE)pBackendData; @@ -2197,8 +2431,8 @@ static int dmgGetParentModificationUuid(void *pBackendData, PRTUUID pUuid) return rc; } -/** @copydoc VBOXHDDBACKEND::pfnSetParentModificationUuid */ -static int dmgSetParentModificationUuid(void *pBackendData, PCRTUUID pUuid) +/** @interface_method_impl{VBOXHDDBACKEND,pfnSetParentModificationUuid} */ +static DECLCALLBACK(int) dmgSetParentModificationUuid(void *pBackendData, PCRTUUID pUuid) { LogFlowFunc(("pBackendData=%#p Uuid=%RTuuid\n", pBackendData, pUuid)); PDMGIMAGE pThis = (PDMGIMAGE)pBackendData; @@ -2220,18 +2454,18 @@ static int dmgSetParentModificationUuid(void *pBackendData, PCRTUUID pUuid) return rc; } -/** @copydoc VBOXHDDBACKEND::pfnDump */ -static void dmgDump(void *pBackendData) +/** @interface_method_impl{VBOXHDDBACKEND,pfnDump} */ +static DECLCALLBACK(void) dmgDump(void *pBackendData) { PDMGIMAGE pThis = (PDMGIMAGE)pBackendData; AssertPtr(pThis); if (pThis) { - vdIfErrorMessage(pThis->pIfError, "Header: Geometry PCHS=%u/%u/%u LCHS=%u/%u/%u cbSector=%llu\n", + vdIfErrorMessage(pThis->pIfError, "Header: Geometry PCHS=%u/%u/%u LCHS=%u/%u/%u cSectors=%llu\n", pThis->PCHSGeometry.cCylinders, pThis->PCHSGeometry.cHeads, pThis->PCHSGeometry.cSectors, pThis->LCHSGeometry.cCylinders, pThis->LCHSGeometry.cHeads, pThis->LCHSGeometry.cSectors, - pThis->cbSize / 512); + pThis->cbSize / DMG_SECTOR_SIZE); } } @@ -2266,8 +2500,12 @@ VBOXHDDBACKEND g_DmgBackend = dmgWrite, /* pfnFlush */ dmgFlush, + /* pfnDiscard */ + NULL, /* pfnGetVersion */ dmgGetVersion, + /* pfnGetSectorSize */ + dmgGetSectorSize, /* pfnGetSize */ dmgGetSize, /* pfnGetFileSize */ @@ -2318,12 +2556,6 @@ VBOXHDDBACKEND g_DmgBackend = NULL, /* pfnSetParentFilename */ NULL, - /* pfnAsyncRead */ - NULL, - /* pfnAsyncWrite */ - NULL, - /* pfnAsyncFlush */ - NULL, /* pfnComposeLocation */ genericFileComposeLocation, /* pfnComposeName */ @@ -2332,10 +2564,7 @@ VBOXHDDBACKEND g_DmgBackend = NULL, /* pfnResize */ NULL, - /* pfnDiscard */ - NULL, - /* pfnAsyncDiscard */ - NULL, /* pfnRepair */ NULL }; + |