Index: /trunk/include/VBox/vd-image-backend.h
===================================================================
--- /trunk/include/VBox/vd-image-backend.h	(revision 66485)
+++ /trunk/include/VBox/vd-image-backend.h	(revision 66486)
@@ -260,20 +260,4 @@
 
     /**
-     * Get the sector size of a disk image.
-     *
-     * @returns size of disk image in bytes.
-     * @param   pBackendData    Opaque state data for this image.
-     */
-    DECLR3CALLBACKMEMBER(uint32_t, pfnGetSectorSize, (void *pBackendData));
-
-    /**
-     * Get the capacity of a disk image.
-     *
-     * @returns size of disk image in bytes.
-     * @param   pBackendData    Opaque state data for this image.
-     */
-    DECLR3CALLBACKMEMBER(uint64_t, pfnGetSize, (void *pBackendData));
-
-    /**
      * Get the file size of a disk image.
      *
@@ -608,5 +592,5 @@
 
 /** The current version of the VDIMAGEBACKEND structure. */
-#define VD_IMGBACKEND_VERSION                   VD_VERSION_MAKE(0xff01, 2, 0)
+#define VD_IMGBACKEND_VERSION                   VD_VERSION_MAKE(0xff01, 3, 0)
 
 /** @copydoc VDIMAGEBACKEND::pfnComposeLocation */
Index: /trunk/include/VBox/vdmedia.h
===================================================================
--- /trunk/include/VBox/vdmedia.h	(revision 66485)
+++ /trunk/include/VBox/vdmedia.h	(revision 66486)
@@ -188,5 +188,5 @@
     uint32_t                 cRegions;
     /** Region descriptors - variable in size. */
-    VDREGIONDESC             aRegions[RT_FLEXIBLE_ARRAY];
+    VDREGIONDESC             aRegions[RT_FLEXIBLE_ARRAY_NESTED];
 } VDREGIONLIST;
 /** Pointer to a region list. */
Index: /trunk/src/VBox/Storage/CUE.cpp
===================================================================
--- /trunk/src/VBox/Storage/CUE.cpp	(revision 66485)
+++ /trunk/src/VBox/Storage/CUE.cpp	(revision 66486)
@@ -1590,32 +1590,4 @@
 }
 
-/** @copydoc VDIMAGEBACKEND::pfnGetSectorSize */
-static DECLCALLBACK(uint32_t) cueGetSectorSize(void *pBackendData)
-{
-    LogFlowFunc(("pBackendData=%#p\n", pBackendData));
-    PCUEIMAGE pThis = (PCUEIMAGE)pBackendData;
-    uint32_t cb = 0;
-
-    AssertPtrReturn(pThis, 0);
-
-    LogFlowFunc(("returns %u\n", cb));
-    return cb;
-}
-
-/** @copydoc VDIMAGEBACKEND::pfnGetSize */
-static DECLCALLBACK(uint64_t) cueGetSize(void *pBackendData)
-{
-    LogFlowFunc(("pBackendData=%#p\n", pBackendData));
-    PCUEIMAGE pThis = (PCUEIMAGE)pBackendData;
-
-    AssertPtrReturn(pThis, 0);
-
-    PCVDREGIONDESC pRegion = &pThis->pRegionList->aRegions[pThis->pRegionList->cRegions - 1];
-    uint64_t cb = pRegion->offRegion + pRegion->cRegionBlocksOrBytes;
-
-    LogFlowFunc(("returns %llu\n", cb));
-    return cb;
-}
-
 /** @copydoc VDIMAGEBACKEND::pfnGetFileSize */
 static DECLCALLBACK(uint64_t) cueGetFileSize(void *pBackendData)
@@ -2015,8 +1987,4 @@
     /* pfnGetVersion */
     cueGetVersion,
-    /* pfnGetSectorSize */
-    cueGetSectorSize,
-    /* pfnGetSize */
-    cueGetSize,
     /* pfnGetFileSize */
     cueGetFileSize,
Index: /trunk/src/VBox/Storage/DMG.cpp
===================================================================
--- /trunk/src/VBox/Storage/DMG.cpp	(revision 66485)
+++ /trunk/src/VBox/Storage/DMG.cpp	(revision 66486)
@@ -371,4 +371,6 @@
     /** Size of the buffer. */
     size_t              cbDecompExtent;
+    /** The static region list. */
+    VDREGIONLIST        RegionList;
 } DMGIMAGE;
 /** Pointer to an instance of the DMG Image Interpreter. */
@@ -1717,5 +1719,19 @@
     RTMemFree(pszXml);
 
-    if (RT_FAILURE(rc))
+    if (RT_SUCCESS(rc))
+    {
+        PVDREGIONDESC pRegion = &pThis->RegionList.aRegions[0];
+        pThis->RegionList.fFlags   = 0;
+        pThis->RegionList.cRegions = 1;
+
+        pRegion->offRegion            = 0; /* Disk start. */
+        pRegion->cbBlock              = 2048;
+        pRegion->enmDataForm          = VDREGIONDATAFORM_RAW;
+        pRegion->enmMetadataForm      = VDREGIONMETADATAFORM_NONE;
+        pRegion->cbData               = 2048;
+        pRegion->cbMetadata           = 0;
+        pRegion->cRegionBlocksOrBytes = pThis->cbSize;
+    }
+    else
         dmgFreeImage(pThis, false);
     return rc;
@@ -1855,5 +1871,5 @@
      */
     int rc = VERR_NO_MEMORY;
-    PDMGIMAGE pThis = (PDMGIMAGE)RTMemAllocZ(sizeof(*pThis));
+    PDMGIMAGE pThis = (PDMGIMAGE)RTMemAllocZ(RT_UOFFSETOF(DMGIMAGE, RegionList.aRegions[1]));
     if (pThis)
     {
@@ -2057,36 +2073,4 @@
 }
 
-/** @interface_method_impl{VDIMAGEBACKEND,pfnGetSectorSize} */
-static DECLCALLBACK(uint32_t) dmgGetSectorSize(void *pBackendData)
-{
-    LogFlowFunc(("pBackendData=%#p\n", pBackendData));
-    PDMGIMAGE pThis = (PDMGIMAGE)pBackendData;
-
-    AssertPtrReturn(pThis, 0);
-
-    uint32_t cb = 0;
-    if (pThis->pStorage || pThis->hDmgFileInXar != NIL_RTVFSFILE)
-        cb = 2048;
-
-    LogFlowFunc(("returns %u\n", cb));
-    return cb;
-}
-
-/** @interface_method_impl{VDIMAGEBACKEND,pfnGetSize} */
-static DECLCALLBACK(uint64_t) dmgGetSize(void *pBackendData)
-{
-    LogFlowFunc(("pBackendData=%#p\n", pBackendData));
-    PDMGIMAGE pThis = (PDMGIMAGE)pBackendData;
-
-    AssertPtrReturn(pThis, 0);
-
-    uint64_t cb = 0;
-    if (pThis->pStorage || pThis->hDmgFileInXar != NIL_RTVFSFILE)
-        cb = pThis->cbSize;
-
-    LogFlowFunc(("returns %llu\n", cb));
-    return cb;
-}
-
 /** @interface_method_impl{VDIMAGEBACKEND,pfnGetFileSize} */
 static DECLCALLBACK(uint64_t) dmgGetFileSize(void *pBackendData)
@@ -2181,4 +2165,28 @@
     LogFlowFunc(("returns %Rrc\n", rc));
     return rc;
+}
+
+/** @copydoc VDIMAGEBACKEND::pfnQueryRegions */
+static DECLCALLBACK(int) dmgQueryRegions(void *pBackendData, PCVDREGIONLIST *ppRegionList)
+{
+    LogFlowFunc(("pBackendData=%#p ppRegionList=%#p\n", pBackendData, ppRegionList));
+    PDMGIMAGE pThis = (PDMGIMAGE)pBackendData;
+
+    AssertPtrReturn(pThis, VERR_VD_NOT_OPENED);
+
+    *ppRegionList = &pThis->RegionList;
+    LogFlowFunc(("returns %Rrc\n", VINF_SUCCESS));
+    return VINF_SUCCESS;
+}
+
+/** @copydoc VDIMAGEBACKEND::pfnRegionListRelease */
+static DECLCALLBACK(void) dmgRegionListRelease(void *pBackendData, PCVDREGIONLIST pRegionList)
+{
+    RT_NOREF1(pRegionList);
+    LogFlowFunc(("pBackendData=%#p pRegionList=%#p\n", pBackendData, pRegionList));
+    PDMGIMAGE pThis = (PDMGIMAGE)pBackendData;
+    AssertPtr(pThis); RT_NOREF(pThis);
+
+    /* Nothing to do here. */
 }
 
@@ -2441,8 +2449,4 @@
     /* pfnGetVersion */
     dmgGetVersion,
-    /* pfnGetSectorSize */
-    dmgGetSectorSize,
-    /* pfnGetSize */
-    dmgGetSize,
     /* pfnGetFileSize */
     dmgGetFileSize,
@@ -2456,7 +2460,7 @@
     dmgSetLCHSGeometry,
     /* pfnQueryRegions */
-    NULL,
+    dmgQueryRegions,
     /* pfnRegionListRelease */
-    NULL,
+    dmgRegionListRelease,
     /* pfnGetImageFlags */
     dmgGetImageFlags,
Index: /trunk/src/VBox/Storage/ISCSI.cpp
===================================================================
--- /trunk/src/VBox/Storage/ISCSI.cpp	(revision 66485)
+++ /trunk/src/VBox/Storage/ISCSI.cpp	(revision 66486)
@@ -620,4 +620,6 @@
     /** Release log counter. */
     unsigned            cLogRelErrors;
+    /** The static region list. */
+    VDREGIONLIST        RegionList;
 } ISCSIIMAGE;
 
@@ -4684,5 +4686,19 @@
     }
 
-    if (RT_FAILURE(rc))
+    if (RT_SUCCESS(rc))
+    {
+        PVDREGIONDESC pRegion = &pImage->RegionList.aRegions[0];
+        pImage->RegionList.fFlags   = 0;
+        pImage->RegionList.cRegions = 1;
+
+        pRegion->offRegion            = 0; /* Disk start. */
+        pRegion->cbBlock              = pImage->cbSector;
+        pRegion->enmDataForm          = VDREGIONDATAFORM_RAW;
+        pRegion->enmMetadataForm      = VDREGIONMETADATAFORM_NONE;
+        pRegion->cbData               = pImage->cbSector;
+        pRegion->cbMetadata           = 0;
+        pRegion->cRegionBlocksOrBytes = pImage->cbSize;
+    }
+    else
         iscsiFreeImage(pImage, false);
     return rc;
@@ -4720,5 +4736,5 @@
     AssertReturn((VALID_PTR(pszFilename) && *pszFilename), VERR_INVALID_PARAMETER);
 
-    PISCSIIMAGE pImage = (PISCSIIMAGE)RTMemAllocZ(sizeof(ISCSIIMAGE));
+    PISCSIIMAGE pImage = (PISCSIIMAGE)RTMemAllocZ(RT_UOFFSETOF(ISCSIIMAGE, RegionList.aRegions[1]));
     if (RT_LIKELY(pImage))
     {
@@ -5113,26 +5129,4 @@
 }
 
-/** @copydoc VDIMAGEBACKEND::pfnGetSectorSize */
-static DECLCALLBACK(uint32_t) iscsiGetSectorSize(void *pBackendData)
-{
-    LogFlowFunc(("pBackendData=%#p\n", pBackendData));
-    PISCSIIMAGE pImage = (PISCSIIMAGE)pBackendData;
-
-    AssertPtrReturn(pImage, 0);
-
-    return pImage->cbSector;
-}
-
-/** @copydoc VDIMAGEBACKEND::pfnGetSize */
-static DECLCALLBACK(uint64_t) iscsiGetSize(void *pBackendData)
-{
-    LogFlowFunc(("pBackendData=%#p\n", pBackendData));
-    PISCSIIMAGE pImage = (PISCSIIMAGE)pBackendData;
-
-    AssertPtrReturn(pImage, 0);
-
-    return pImage->cbSize;
-}
-
 /** @copydoc VDIMAGEBACKEND::pfnGetFileSize */
 static DECLCALLBACK(uint64_t) iscsiGetFileSize(void *pBackendData)
@@ -5210,4 +5204,28 @@
     LogFlowFunc(("returns %Rrc\n", rc));
     return rc;
+}
+
+/** @copydoc VDIMAGEBACKEND::pfnQueryRegions */
+static DECLCALLBACK(int) iscsiQueryRegions(void *pBackendData, PCVDREGIONLIST *ppRegionList)
+{
+    LogFlowFunc(("pBackendData=%#p ppRegionList=%#p\n", pBackendData, ppRegionList));
+    PISCSIIMAGE pImage = (PISCSIIMAGE)pBackendData;
+
+    AssertPtrReturn(pImage, VERR_VD_NOT_OPENED);
+
+    *ppRegionList = &pImage->RegionList;
+    LogFlowFunc(("returns %Rrc\n", VINF_SUCCESS));
+    return VINF_SUCCESS;
+}
+
+/** @copydoc VDIMAGEBACKEND::pfnRegionListRelease */
+static DECLCALLBACK(void) iscsiRegionListRelease(void *pBackendData, PCVDREGIONLIST pRegionList)
+{
+    RT_NOREF1(pRegionList);
+    LogFlowFunc(("pBackendData=%#p pRegionList=%#p\n", pBackendData, pRegionList));
+    PISCSIIMAGE pImage = (PISCSIIMAGE)pBackendData;
+    AssertPtr(pImage); RT_NOREF(pImage);
+
+    /* Nothing to do here. */
 }
 
@@ -5528,8 +5546,4 @@
     /* pfnGetVersion */
     iscsiGetVersion,
-    /* pfnGetSectorSize */
-    iscsiGetSectorSize,
-    /* pfnGetSize */
-    iscsiGetSize,
     /* pfnGetFileSize */
     iscsiGetFileSize,
@@ -5543,7 +5557,7 @@
     iscsiSetLCHSGeometry,
     /* pfnQueryRegions */
-    NULL,
+    iscsiQueryRegions,
     /* pfnRegionListRelease */
-    NULL,
+    iscsiRegionListRelease,
     /* pfnGetImageFlags */
     iscsiGetImageFlags,
Index: /trunk/src/VBox/Storage/Parallels.cpp
===================================================================
--- /trunk/src/VBox/Storage/Parallels.cpp	(revision 66485)
+++ /trunk/src/VBox/Storage/Parallels.cpp	(revision 66486)
@@ -96,4 +96,6 @@
     /** Current file size. */
     uint64_t            cbFileCurrent;
+    /** The static region list. */
+    VDREGIONLIST        RegionList;
 } PARALLELSIMAGE, *PPARALLELSIMAGE;
 
@@ -248,4 +250,19 @@
     }
 
+    if (RT_SUCCESS(rc))
+    {
+        PVDREGIONDESC pRegion = &pImage->RegionList.aRegions[0];
+        pImage->RegionList.fFlags   = 0;
+        pImage->RegionList.cRegions = 1;
+
+        pRegion->offRegion            = 0; /* Disk start. */
+        pRegion->cbBlock              = 512;
+        pRegion->enmDataForm          = VDREGIONDATAFORM_RAW;
+        pRegion->enmMetadataForm      = VDREGIONMETADATAFORM_NONE;
+        pRegion->cbData               = 512;
+        pRegion->cbMetadata           = 0;
+        pRegion->cRegionBlocksOrBytes = pImage->cbSize;
+    }
+
     LogFlowFunc(("returns %Rrc\n", rc));
     return rc;
@@ -336,5 +353,19 @@
         pfnProgress(pvUser, uPercentStart + uPercentSpan);
 
-    if (RT_FAILURE(rc))
+    if (RT_SUCCESS(rc))
+    {
+        PVDREGIONDESC pRegion = &pImage->RegionList.aRegions[0];
+        pImage->RegionList.fFlags   = 0;
+        pImage->RegionList.cRegions = 1;
+
+        pRegion->offRegion            = 0; /* Disk start. */
+        pRegion->cbBlock              = 512;
+        pRegion->enmDataForm          = VDREGIONDATAFORM_RAW;
+        pRegion->enmMetadataForm      = VDREGIONMETADATAFORM_NONE;
+        pRegion->cbData               = 512;
+        pRegion->cbMetadata           = 0;
+        pRegion->cRegionBlocksOrBytes = pImage->cbSize;
+    }
+    else
         parallelsFreeImage(pImage, rc != VERR_ALREADY_EXISTS);
     return rc;
@@ -417,5 +448,5 @@
     AssertReturn(VALID_PTR(pszFilename) && *pszFilename, VERR_INVALID_PARAMETER);
 
-    pImage = (PPARALLELSIMAGE)RTMemAllocZ(sizeof(PARALLELSIMAGE));
+    pImage = (PPARALLELSIMAGE)RTMemAllocZ(RT_UOFFSETOF(PARALLELSIMAGE, RegionList.aRegions[1]));
     if (RT_LIKELY(pImage))
     {
@@ -476,5 +507,5 @@
     }
 
-    pImage = (PPARALLELSIMAGE)RTMemAllocZ(sizeof(PARALLELSIMAGE));
+    pImage = (PPARALLELSIMAGE)RTMemAllocZ(RT_UOFFSETOF(PARALLELSIMAGE, RegionList.aRegions[1]));
     if (RT_LIKELY(pImage))
     {
@@ -715,36 +746,4 @@
 }
 
-/** @copydoc VDIMAGEBACKEND::pfnGetSectorSize */
-static DECLCALLBACK(uint32_t) parallelsGetSectorSize(void *pBackendData)
-{
-    LogFlowFunc(("pBackendData=%#p\n", pBackendData));
-    PPARALLELSIMAGE pImage = (PPARALLELSIMAGE)pBackendData;
-    uint32_t cb = 0;
-
-    AssertPtrReturn(pImage, 0);
-
-    if (pImage->pStorage)
-        cb = 512;
-
-    LogFlowFunc(("returns %llu\n", cb));
-    return cb;
-}
-
-/** @copydoc VDIMAGEBACKEND::pfnGetSize */
-static DECLCALLBACK(uint64_t) parallelsGetSize(void *pBackendData)
-{
-    LogFlowFunc(("pBackendData=%#p\n", pBackendData));
-    PPARALLELSIMAGE pImage = (PPARALLELSIMAGE)pBackendData;
-    uint64_t cb = 0;
-
-    AssertPtrReturn(pImage, 0);
-
-    if (pImage->pStorage)
-        cb = pImage->cbSize;
-
-    LogFlowFunc(("returns %llu\n", cb));
-    return cb;
-}
-
 /** @copydoc VDIMAGEBACKEND::pfnGetFileSize */
 static DECLCALLBACK(uint64_t) parallelsGetFileSize(void *pBackendData)
@@ -838,4 +837,28 @@
     LogFlowFunc(("returns %Rrc\n", rc));
     return rc;
+}
+
+/** @copydoc VDIMAGEBACKEND::pfnQueryRegions */
+static DECLCALLBACK(int) parallelsQueryRegions(void *pBackendData, PCVDREGIONLIST *ppRegionList)
+{
+    LogFlowFunc(("pBackendData=%#p ppRegionList=%#p\n", pBackendData, ppRegionList));
+    PPARALLELSIMAGE pThis = (PPARALLELSIMAGE)pBackendData;
+
+    AssertPtrReturn(pThis, VERR_VD_NOT_OPENED);
+
+    *ppRegionList = &pThis->RegionList;
+    LogFlowFunc(("returns %Rrc\n", VINF_SUCCESS));
+    return VINF_SUCCESS;
+}
+
+/** @copydoc VDIMAGEBACKEND::pfnRegionListRelease */
+static DECLCALLBACK(void) parallelsRegionListRelease(void *pBackendData, PCVDREGIONLIST pRegionList)
+{
+    RT_NOREF1(pRegionList);
+    LogFlowFunc(("pBackendData=%#p pRegionList=%#p\n", pBackendData, pRegionList));
+    PPARALLELSIMAGE pThis = (PPARALLELSIMAGE)pBackendData;
+    AssertPtr(pThis); RT_NOREF(pThis);
+
+    /* Nothing to do here. */
 }
 
@@ -1099,8 +1122,4 @@
     /* pfnGetVersion */
     parallelsGetVersion,
-    /* pfnGetSectorSize */
-    parallelsGetSectorSize,
-    /* pfnGetSize */
-    parallelsGetSize,
     /* pfnGetFileSize */
     parallelsGetFileSize,
@@ -1114,7 +1133,7 @@
     parallelsSetLCHSGeometry,
     /* pfnQueryRegions */
-    NULL,
+    parallelsQueryRegions,
     /* pfnRegionListRelease */
-    NULL,
+    parallelsRegionListRelease,
     /* pfnGetImageFlags */
     parallelsGetImageFlags,
Index: /trunk/src/VBox/Storage/QCOW.cpp
===================================================================
--- /trunk/src/VBox/Storage/QCOW.cpp	(revision 66485)
+++ /trunk/src/VBox/Storage/QCOW.cpp	(revision 66486)
@@ -251,5 +251,6 @@
      * (can be only one at a time). */
     PQCOWL2CACHEENTRY   pL2TblAlloc;
-
+    /** The static region list. */
+    VDREGIONLIST        RegionList;
 } QCOWIMAGE, *PQCOWIMAGE;
 
@@ -1227,5 +1228,19 @@
                        pImage->pszFilename);
 
-    if (RT_FAILURE(rc))
+    if (RT_SUCCESS(rc))
+    {
+        PVDREGIONDESC pRegion = &pImage->RegionList.aRegions[0];
+        pImage->RegionList.fFlags   = 0;
+        pImage->RegionList.cRegions = 1;
+
+        pRegion->offRegion            = 0; /* Disk start. */
+        pRegion->cbBlock              = 512;
+        pRegion->enmDataForm          = VDREGIONDATAFORM_RAW;
+        pRegion->enmMetadataForm      = VDREGIONMETADATAFORM_NONE;
+        pRegion->cbData               = 512;
+        pRegion->cbMetadata           = 0;
+        pRegion->cRegionBlocksOrBytes = pImage->cbSize;
+    }
+    else
         qcowFreeImage(pImage, false);
     return rc;
@@ -1308,5 +1323,19 @@
         vdIfProgress(pIfProgress, uPercentStart + uPercentSpan);
 
-    if (RT_FAILURE(rc))
+    if (RT_SUCCESS(rc))
+    {
+        PVDREGIONDESC pRegion = &pImage->RegionList.aRegions[0];
+        pImage->RegionList.fFlags   = 0;
+        pImage->RegionList.cRegions = 1;
+
+        pRegion->offRegion            = 0; /* Disk start. */
+        pRegion->cbBlock              = 512;
+        pRegion->enmDataForm          = VDREGIONDATAFORM_RAW;
+        pRegion->enmMetadataForm      = VDREGIONMETADATAFORM_NONE;
+        pRegion->cbData               = 512;
+        pRegion->cbMetadata           = 0;
+        pRegion->cRegionBlocksOrBytes = pImage->cbSize;
+    }
+    else
         qcowFreeImage(pImage, rc != VERR_ALREADY_EXISTS);
     return rc;
@@ -1528,5 +1557,5 @@
     AssertReturn((VALID_PTR(pszFilename) && *pszFilename), VERR_INVALID_PARAMETER);
 
-    PQCOWIMAGE pImage = (PQCOWIMAGE)RTMemAllocZ(sizeof(QCOWIMAGE));
+    PQCOWIMAGE pImage = (PQCOWIMAGE)RTMemAllocZ(RT_UOFFSETOF(QCOWIMAGE, RegionList.aRegions[1]));
     if (RT_LIKELY(pImage))
     {
@@ -1575,5 +1604,5 @@
                  && VALID_PTR(pLCHSGeometry), VERR_INVALID_PARAMETER);
 
-    PQCOWIMAGE pImage = (PQCOWIMAGE)RTMemAllocZ(sizeof(QCOWIMAGE));
+    PQCOWIMAGE pImage = (PQCOWIMAGE)RTMemAllocZ(RT_UOFFSETOF(QCOWIMAGE, RegionList.aRegions[1]));
     if (RT_LIKELY(pImage))
     {
@@ -1918,36 +1947,4 @@
 }
 
-/** @copydoc VDIMAGEBACKEND::pfnGetSectorSize */
-static DECLCALLBACK(uint32_t) qcowGetSectorSize(void *pBackendData)
-{
-    LogFlowFunc(("pBackendData=%#p\n", pBackendData));
-    PQCOWIMAGE pImage = (PQCOWIMAGE)pBackendData;
-    uint32_t cb = 0;
-
-    AssertPtrReturn(pImage, 0);
-
-    if (pImage->pStorage)
-        cb = 512;
-
-    LogFlowFunc(("returns %u\n", cb));
-    return cb;
-}
-
-/** @copydoc VDIMAGEBACKEND::pfnGetSize */
-static DECLCALLBACK(uint64_t) qcowGetSize(void *pBackendData)
-{
-    LogFlowFunc(("pBackendData=%#p\n", pBackendData));
-    PQCOWIMAGE pImage = (PQCOWIMAGE)pBackendData;
-    uint64_t cb = 0;
-
-    AssertPtrReturn(pImage, 0);
-
-    if (pImage->pStorage)
-        cb = pImage->cbSize;
-
-    LogFlowFunc(("returns %llu\n", cb));
-    return cb;
-}
-
 /** @copydoc VDIMAGEBACKEND::pfnGetFileSize */
 static DECLCALLBACK(uint64_t) qcowGetFileSize(void *pBackendData)
@@ -2044,4 +2041,28 @@
     LogFlowFunc(("returns %Rrc\n", rc));
     return rc;
+}
+
+/** @copydoc VDIMAGEBACKEND::pfnQueryRegions */
+static DECLCALLBACK(int) qcowQueryRegions(void *pBackendData, PCVDREGIONLIST *ppRegionList)
+{
+    LogFlowFunc(("pBackendData=%#p ppRegionList=%#p\n", pBackendData, ppRegionList));
+    PQCOWIMAGE pThis = (PQCOWIMAGE)pBackendData;
+
+    AssertPtrReturn(pThis, VERR_VD_NOT_OPENED);
+
+    *ppRegionList = &pThis->RegionList;
+    LogFlowFunc(("returns %Rrc\n", VINF_SUCCESS));
+    return VINF_SUCCESS;
+}
+
+/** @copydoc VDIMAGEBACKEND::pfnRegionListRelease */
+static DECLCALLBACK(void) qcowRegionListRelease(void *pBackendData, PCVDREGIONLIST pRegionList)
+{
+    RT_NOREF1(pRegionList);
+    LogFlowFunc(("pBackendData=%#p pRegionList=%#p\n", pBackendData, pRegionList));
+    PQCOWIMAGE pThis = (PQCOWIMAGE)pBackendData;
+    AssertPtr(pThis); RT_NOREF(pThis);
+
+    /* Nothing to do here. */
 }
 
@@ -2369,8 +2390,4 @@
     /* pfnGetVersion */
     qcowGetVersion,
-    /* pfnGetSectorSize */
-    qcowGetSectorSize,
-    /* pfnGetSize */
-    qcowGetSize,
     /* pfnGetFileSize */
     qcowGetFileSize,
@@ -2384,7 +2401,7 @@
     qcowSetLCHSGeometry,
     /* pfnQueryRegions */
-    NULL,
+    qcowQueryRegions,
     /* pfnRegionListRelease */
-    NULL,
+    qcowRegionListRelease,
     /* pfnGetImageFlags */
     qcowGetImageFlags,
Index: /trunk/src/VBox/Storage/QED.cpp
===================================================================
--- /trunk/src/VBox/Storage/QED.cpp	(revision 66485)
+++ /trunk/src/VBox/Storage/QED.cpp	(revision 66486)
@@ -217,5 +217,6 @@
     /** The LRU L2 entry list used for eviction. */
     RTLISTNODE          ListLru;
-
+    /** The static region list. */
+    VDREGIONLIST        RegionList;
 } QEDIMAGE, *PQEDIMAGE;
 
@@ -1242,5 +1243,19 @@
                        pImage->pszFilename);
 
-    if (RT_FAILURE(rc))
+    if (RT_SUCCESS(rc))
+    {
+        PVDREGIONDESC pRegion = &pImage->RegionList.aRegions[0];
+        pImage->RegionList.fFlags   = 0;
+        pImage->RegionList.cRegions = 1;
+
+        pRegion->offRegion            = 0; /* Disk start. */
+        pRegion->cbBlock              = 512;
+        pRegion->enmDataForm          = VDREGIONDATAFORM_RAW;
+        pRegion->enmMetadataForm      = VDREGIONMETADATAFORM_NONE;
+        pRegion->cbData               = 512;
+        pRegion->cbMetadata           = 0;
+        pRegion->cRegionBlocksOrBytes = pImage->cbSize;
+    }
+    else
         qedFreeImage(pImage, false);
     return rc;
@@ -1312,5 +1327,19 @@
 
     if (RT_SUCCESS(rc))
+    {
+        PVDREGIONDESC pRegion = &pImage->RegionList.aRegions[0];
+        pImage->RegionList.fFlags   = 0;
+        pImage->RegionList.cRegions = 1;
+
+        pRegion->offRegion            = 0; /* Disk start. */
+        pRegion->cbBlock              = 512;
+        pRegion->enmDataForm          = VDREGIONDATAFORM_RAW;
+        pRegion->enmMetadataForm      = VDREGIONMETADATAFORM_NONE;
+        pRegion->cbData               = 512;
+        pRegion->cbMetadata           = 0;
+        pRegion->cRegionBlocksOrBytes = pImage->cbSize;
+
         vdIfProgress(pIfProgress, uPercentStart + uPercentSpan);
+    }
     else
         qedFreeImage(pImage, rc != VERR_ALREADY_EXISTS);
@@ -1532,5 +1561,5 @@
     AssertReturn((VALID_PTR(pszFilename) && *pszFilename), VERR_INVALID_PARAMETER);
 
-    PQEDIMAGE pImage = (PQEDIMAGE)RTMemAllocZ(sizeof(QEDIMAGE));
+    PQEDIMAGE pImage = (PQEDIMAGE)RTMemAllocZ(RT_UOFFSETOF(QEDIMAGE, RegionList.aRegions[1]));
     if (RT_LIKELY(pImage))
     {
@@ -1579,5 +1608,5 @@
                  && VALID_PTR(pLCHSGeometry), VERR_INVALID_PARAMETER);
 
-    PQEDIMAGE pImage = (PQEDIMAGE)RTMemAllocZ(sizeof(QEDIMAGE));
+    PQEDIMAGE pImage = (PQEDIMAGE)RTMemAllocZ(RT_UOFFSETOF(QEDIMAGE, RegionList.aRegions[1]));
     if (RT_LIKELY(pImage))
     {
@@ -1925,36 +1954,4 @@
 }
 
-/** @copydoc VDIMAGEBACKEND::pfnGetSectorSize */
-static DECLCALLBACK(uint32_t) qedGetSectorSize(void *pBackendData)
-{
-    LogFlowFunc(("pBackendData=%#p\n", pBackendData));
-    PQEDIMAGE pImage = (PQEDIMAGE)pBackendData;
-    uint32_t cb = 0;
-
-    AssertPtrReturn(pImage, 0);
-
-    if (pImage->pStorage)
-        cb = 512;
-
-    LogFlowFunc(("returns %u\n", cb));
-    return cb;
-}
-
-/** @copydoc VDIMAGEBACKEND::pfnGetSize */
-static DECLCALLBACK(uint64_t) qedGetSize(void *pBackendData)
-{
-    LogFlowFunc(("pBackendData=%#p\n", pBackendData));
-    PQEDIMAGE pImage = (PQEDIMAGE)pBackendData;
-    uint64_t cb = 0;
-
-    AssertPtrReturn(pImage, 0);
-
-    if (pImage->pStorage)
-        cb = pImage->cbSize;
-
-    LogFlowFunc(("returns %llu\n", cb));
-    return cb;
-}
-
 /** @copydoc VDIMAGEBACKEND::pfnGetFileSize */
 static DECLCALLBACK(uint64_t) qedGetFileSize(void *pBackendData)
@@ -2053,4 +2050,28 @@
     LogFlowFunc(("returns %Rrc\n", rc));
     return rc;
+}
+
+/** @copydoc VDIMAGEBACKEND::pfnQueryRegions */
+static DECLCALLBACK(int) qedQueryRegions(void *pBackendData, PCVDREGIONLIST *ppRegionList)
+{
+    LogFlowFunc(("pBackendData=%#p ppRegionList=%#p\n", pBackendData, ppRegionList));
+    PQEDIMAGE pThis = (PQEDIMAGE)pBackendData;
+
+    AssertPtrReturn(pThis, VERR_VD_NOT_OPENED);
+
+    *ppRegionList = &pThis->RegionList;
+    LogFlowFunc(("returns %Rrc\n", VINF_SUCCESS));
+    return VINF_SUCCESS;
+}
+
+/** @copydoc VDIMAGEBACKEND::pfnRegionListRelease */
+static DECLCALLBACK(void) qedRegionListRelease(void *pBackendData, PCVDREGIONLIST pRegionList)
+{
+    RT_NOREF1(pRegionList);
+    LogFlowFunc(("pBackendData=%#p pRegionList=%#p\n", pBackendData, pRegionList));
+    PQEDIMAGE pThis = (PQEDIMAGE)pBackendData;
+    AssertPtr(pThis); RT_NOREF(pThis);
+
+    /* Nothing to do here. */
 }
 
@@ -2422,8 +2443,4 @@
     /* pfnGetVersion */
     qedGetVersion,
-    /* pfnGetSectorSize */
-    qedGetSectorSize,
-    /* pfnGetSize */
-    qedGetSize,
     /* pfnGetFileSize */
     qedGetFileSize,
@@ -2437,7 +2454,7 @@
     qedSetLCHSGeometry,
     /* pfnQueryRegions */
-    NULL,
+    qedQueryRegions,
     /* pfnRegionListRelease */
-    NULL,
+    qedRegionListRelease,
     /* pfnGetImageFlags */
     qedGetImageFlags,
Index: /trunk/src/VBox/Storage/RAW.cpp
===================================================================
--- /trunk/src/VBox/Storage/RAW.cpp	(revision 66485)
+++ /trunk/src/VBox/Storage/RAW.cpp	(revision 66486)
@@ -71,4 +71,6 @@
     /** Sector size of the image. */
     uint32_t            cbSector;
+    /** The static region list. */
+    VDREGIONLIST        RegionList;
 } RAWIMAGE, *PRAWIMAGE;
 
@@ -210,5 +212,19 @@
      *       choice of retrying the open if it failed. */
 
-    if (RT_FAILURE(rc))
+    if (RT_SUCCESS(rc))
+    {
+        PVDREGIONDESC pRegion = &pImage->RegionList.aRegions[0];
+        pImage->RegionList.fFlags   = 0;
+        pImage->RegionList.cRegions = 1;
+
+        pRegion->offRegion            = 0; /* Disk start. */
+        pRegion->cbBlock              = pImage->cbSector;
+        pRegion->enmDataForm          = VDREGIONDATAFORM_RAW;
+        pRegion->enmMetadataForm      = VDREGIONMETADATAFORM_NONE;
+        pRegion->cbData               = pImage->cbSector;
+        pRegion->cbMetadata           = 0;
+        pRegion->cRegionBlocksOrBytes = pImage->cbSize;
+    }
+    else
         rawFreeImage(pImage, false);
     return rc;
@@ -282,5 +298,19 @@
 
     if (RT_SUCCESS(rc))
+    {
+        PVDREGIONDESC pRegion = &pImage->RegionList.aRegions[0];
+        pImage->RegionList.fFlags   = 0;
+        pImage->RegionList.cRegions = 1;
+
+        pRegion->offRegion            = 0; /* Disk start. */
+        pRegion->cbBlock              = pImage->cbSector;
+        pRegion->enmDataForm          = VDREGIONDATAFORM_RAW;
+        pRegion->enmMetadataForm      = VDREGIONMETADATAFORM_NONE;
+        pRegion->cbData               = pImage->cbSector;
+        pRegion->cbMetadata           = 0;
+        pRegion->cRegionBlocksOrBytes = pImage->cbSize;
+
         vdIfProgress(pIfProgress, uPercentStart + uPercentSpan);
+    }
 
     if (RT_FAILURE(rc))
@@ -382,5 +412,5 @@
     AssertReturn((VALID_PTR(pszFilename) && *pszFilename), VERR_INVALID_PARAMETER);
 
-    pImage = (PRAWIMAGE)RTMemAllocZ(sizeof(RAWIMAGE));
+    pImage = (PRAWIMAGE)RTMemAllocZ(RT_UOFFSETOF(RAWIMAGE, RegionList.aRegions[1]));
     if (RT_LIKELY(pImage))
     {
@@ -438,5 +468,5 @@
                  && VALID_PTR(pLCHSGeometry), VERR_INVALID_PARAMETER);
 
-    PRAWIMAGE pImage = (PRAWIMAGE)RTMemAllocZ(sizeof(RAWIMAGE));
+    PRAWIMAGE pImage = (PRAWIMAGE)RTMemAllocZ(RT_UOFFSETOF(RAWIMAGE, RegionList.aRegions[1]));
     if (RT_LIKELY(pImage))
     {
@@ -602,36 +632,4 @@
 }
 
-/** @copydoc VDIMAGEBACKEND::pfnGetSize */
-static DECLCALLBACK(uint32_t) rawGetSectorSize(void *pBackendData)
-{
-    LogFlowFunc(("pBackendData=%#p\n", pBackendData));
-    PRAWIMAGE pImage = (PRAWIMAGE)pBackendData;
-    uint32_t cb = 0;
-
-    AssertPtrReturn(pImage, 0);
-
-    if (pImage->pStorage)
-        cb = pImage->cbSector;
-
-    LogFlowFunc(("returns %u\n", cb));
-    return cb;
-}
-
-/** @copydoc VDIMAGEBACKEND::pfnGetSize */
-static DECLCALLBACK(uint64_t) rawGetSize(void *pBackendData)
-{
-    LogFlowFunc(("pBackendData=%#p\n", pBackendData));
-    PRAWIMAGE pImage = (PRAWIMAGE)pBackendData;
-    uint64_t cb = 0;
-
-    AssertPtrReturn(pImage, 0);
-
-    if (pImage->pStorage)
-        cb = pImage->cbSize;
-
-    LogFlowFunc(("returns %llu\n", cb));
-    return cb;
-}
-
 /** @copydoc VDIMAGEBACKEND::pfnGetFileSize */
 static DECLCALLBACK(uint64_t) rawGetFileSize(void *pBackendData)
@@ -730,4 +728,28 @@
     LogFlowFunc(("returns %Rrc\n", rc));
     return rc;
+}
+
+/** @copydoc VDIMAGEBACKEND::pfnQueryRegions */
+static DECLCALLBACK(int) rawQueryRegions(void *pBackendData, PCVDREGIONLIST *ppRegionList)
+{
+    LogFlowFunc(("pBackendData=%#p ppRegionList=%#p\n", pBackendData, ppRegionList));
+    PRAWIMAGE pThis = (PRAWIMAGE)pBackendData;
+
+    AssertPtrReturn(pThis, VERR_VD_NOT_OPENED);
+
+    *ppRegionList = &pThis->RegionList;
+    LogFlowFunc(("returns %Rrc\n", VINF_SUCCESS));
+    return VINF_SUCCESS;
+}
+
+/** @copydoc VDIMAGEBACKEND::pfnRegionListRelease */
+static DECLCALLBACK(void) rawRegionListRelease(void *pBackendData, PCVDREGIONLIST pRegionList)
+{
+    RT_NOREF1(pRegionList);
+    LogFlowFunc(("pBackendData=%#p pRegionList=%#p\n", pBackendData, pRegionList));
+    PRAWIMAGE pThis = (PRAWIMAGE)pBackendData;
+    AssertPtr(pThis); RT_NOREF(pThis);
+
+    /* Nothing to do here. */
 }
 
@@ -993,8 +1015,4 @@
     /* pfnGetVersion */
     rawGetVersion,
-    /* pfnGetSectorSize */
-    rawGetSectorSize,
-    /* pfnGetSize */
-    rawGetSize,
     /* pfnGetFileSize */
     rawGetFileSize,
@@ -1008,7 +1026,7 @@
     rawSetLCHSGeometry,
     /* pfnQueryRegions */
-    NULL,
+    rawQueryRegions,
     /* pfnRegionListRelease */
-    NULL,
+    rawRegionListRelease,
     /* pfnGetImageFlags */
     rawGetImageFlags,
Index: /trunk/src/VBox/Storage/VD.cpp
===================================================================
--- /trunk/src/VBox/Storage/VD.cpp	(revision 66485)
+++ /trunk/src/VBox/Storage/VD.cpp	(revision 66486)
@@ -531,4 +531,92 @@
     }
     return pImage;
+}
+
+/**
+ * Creates a new region list from the given one converting to match the flags if necessary.
+ *
+ * @returns VBox status code.
+ * @param   pRegionList     The region list to convert from.
+ * @param   fFlags          The flags for the new region list.
+ * @param   ppRegionList    Where to store the new region list on success.
+ */
+static int vdRegionListConv(PCVDREGIONLIST pRegionList, uint32_t fFlags, PPVDREGIONLIST ppRegionList)
+{
+    int rc = VINF_SUCCESS;
+    PVDREGIONLIST pRegionListNew = (PVDREGIONLIST)RTMemDup(pRegionList, RT_UOFFSETOF(VDREGIONLIST, aRegions[pRegionList->cRegions]));
+    if (RT_LIKELY(pRegionListNew))
+    {
+        /* Do we have to convert anything? */
+        if (pRegionList->fFlags != fFlags)
+        {
+            uint64_t offRegionNext = 0;
+
+            pRegionListNew->fFlags = fFlags;
+            for (unsigned i = 0; i < pRegionListNew->cRegions; i++)
+            {
+                PVDREGIONDESC pRegion = &pRegionListNew->aRegions[i];
+
+                if (   (fFlags & VD_REGION_LIST_F_LOC_SIZE_BLOCKS)
+                    && !(pRegionList->fFlags & VD_REGION_LIST_F_LOC_SIZE_BLOCKS))
+                {
+                    Assert(!(pRegion->cRegionBlocksOrBytes % pRegion->cbBlock));
+
+                    /* Convert from bytes to logical blocks. */
+                    pRegion->offRegion            = offRegionNext;
+                    pRegion->cRegionBlocksOrBytes = pRegion->cRegionBlocksOrBytes / pRegion->cbBlock;
+                    offRegionNext += pRegion->cRegionBlocksOrBytes;
+                }
+                else
+                {
+                    /* Convert from logical blocks to bytes. */
+                    pRegion->offRegion            = offRegionNext;
+                    pRegion->cRegionBlocksOrBytes = pRegion->cRegionBlocksOrBytes * pRegion->cbBlock;
+                    offRegionNext += pRegion->cRegionBlocksOrBytes;
+                }
+            }
+        }
+
+        *ppRegionList = pRegionListNew;
+    }
+    else
+        rc = VERR_NO_MEMORY;
+
+    return rc;
+}
+
+/**
+ * Returns the virtual size of the image in bytes.
+ *
+ * @returns Size of the given image in bytes.
+ * @param   
+ */
+static uint64_t vdImageGetSize(PVDIMAGE pImage)
+{
+    uint64_t cbImage = 0;
+    PCVDREGIONLIST pRegionList = NULL;
+    int rc = pImage->Backend->pfnQueryRegions(pImage->pBackendData, &pRegionList);
+    if (RT_SUCCESS(rc))
+    {
+        if (pRegionList->fFlags & VD_REGION_LIST_F_LOC_SIZE_BLOCKS)
+        {
+            PVDREGIONLIST pRegionListConv = NULL;
+            rc = vdRegionListConv(pRegionList, 0, &pRegionListConv);
+            if (RT_SUCCESS(rc))
+            {
+                for (uint32_t i = 0; i < pRegionListConv->cRegions; i++)
+                    cbImage += pRegionListConv->aRegions[i].cRegionBlocksOrBytes;
+
+                VDRegionListFree(pRegionListConv);
+            }
+        }
+        else
+            for (uint32_t i = 0; i < pRegionList->cRegions; i++)
+                cbImage += pRegionList->aRegions[i].cRegionBlocksOrBytes;
+
+        AssertPtr(pImage->Backend->pfnRegionListRelease);
+        pImage->Backend->pfnRegionListRelease(pImage->pBackendData, pRegionList);
+    }
+
+    return cbImage;
 }
 
@@ -4591,8 +4679,20 @@
     PVDIO    pVDIo = (PVDIO)pvUser;
     PVDISK pDisk = pVDIo->pDisk;
+    size_t cbSector = 0;
 
     PVDIMAGE pImage = vdGetImageByNumber(pDisk, VD_LAST_IMAGE);
     AssertPtrReturn(pImage, 0);
-    return pImage->Backend->pfnGetSectorSize(pImage->pBackendData);
+
+    PCVDREGIONLIST pRegionList = NULL;
+    int rc = pImage->Backend->pfnQueryRegions(pImage->pBackendData, &pRegionList);
+    if (RT_SUCCESS(rc))
+    {
+        cbSector = pRegionList->aRegions[0].cbBlock;
+
+        AssertPtr(pImage->Backend->pfnRegionListRelease);
+        pImage->Backend->pfnRegionListRelease(pImage->pBackendData, pRegionList);
+    }
+
+    return cbSector;
 }
 
@@ -4896,56 +4996,4 @@
 
     RTSemEventSignal(hEvent);
-}
-
-/**
- * Creates a new region list from the given one converting to match the flags if necessary.
- *
- * @returns VBox status code.
- * @param   pRegionList     The region list to convert from.
- * @param   fFlags          The flags for the new region list.
- * @param   ppRegionList    Where to store the new region list on success.
- */
-static int vdRegionListConv(PCVDREGIONLIST pRegionList, uint32_t fFlags, PPVDREGIONLIST ppRegionList)
-{
-    int rc = VINF_SUCCESS;
-    PVDREGIONLIST pRegionListNew = (PVDREGIONLIST)RTMemDup(pRegionList, RT_UOFFSETOF(VDREGIONLIST, aRegions[pRegionList->cRegions]));
-    if (RT_LIKELY(pRegionListNew))
-    {
-        /* Do we have to convert anything? */
-        if (pRegionList->fFlags != fFlags)
-        {
-            uint64_t offRegionNext = 0;
-
-            pRegionListNew->fFlags = fFlags;
-            for (unsigned i = 0; i < pRegionListNew->cRegions; i++)
-            {
-                PVDREGIONDESC pRegion = &pRegionListNew->aRegions[i];
-
-                if (   (fFlags & VD_REGION_LIST_F_LOC_SIZE_BLOCKS)
-                    && !(pRegionList->fFlags & VD_REGION_LIST_F_LOC_SIZE_BLOCKS))
-                {
-                    Assert(!(pRegion->cRegionBlocksOrBytes % pRegion->cbBlock));
-
-                    /* Convert from bytes to logical blocks. */
-                    pRegion->offRegion            = offRegionNext;
-                    pRegion->cRegionBlocksOrBytes = pRegion->cRegionBlocksOrBytes / pRegion->cbBlock;
-                    offRegionNext += pRegion->cRegionBlocksOrBytes;
-                }
-                else
-                {
-                    /* Convert from logical blocks to bytes. */
-                    pRegion->offRegion            = offRegionNext;
-                    pRegion->cRegionBlocksOrBytes = pRegion->cRegionBlocksOrBytes * pRegion->cbBlock;
-                    offRegionNext += pRegion->cRegionBlocksOrBytes;
-                }
-            }
-        }
-
-        *ppRegionList = pRegionListNew;
-    }
-    else
-        rc = VERR_NO_MEMORY;
-
-    return rc;
 }
 
@@ -5729,5 +5777,5 @@
 
         /* Cache disk information. */
-        pDisk->cbSize = pImage->Backend->pfnGetSize(pImage->pBackendData);
+        pDisk->cbSize = vdImageGetSize(pImage);
 
         /* Cache PCHS geometry. */
@@ -6305,5 +6353,5 @@
         {
             /* Cache disk information. */
-            pDisk->cbSize = pImage->Backend->pfnGetSize(pImage->pBackendData);
+            pDisk->cbSize = vdImageGetSize(pImage);
 
             /* Cache PCHS geometry. */
@@ -6941,5 +6989,5 @@
 
         /* Get size of destination image. */
-        uint64_t cbSize = pImageTo->Backend->pfnGetSize(pImageTo->pBackendData);
+        uint64_t cbSize = vdImageGetSize(pImageTo);
         rc2 = vdThreadFinishWrite(pDisk);
         AssertRC(rc2);
@@ -7418,5 +7466,5 @@
 
         uint64_t cbSizeFrom;
-        cbSizeFrom = pImageFrom->Backend->pfnGetSize(pImageFrom->pBackendData);
+        cbSizeFrom = vdImageGetSize(pImageFrom);
         if (cbSizeFrom == 0)
         {
@@ -7521,5 +7569,5 @@
 
             uint64_t cbSizeTo;
-            cbSizeTo = pImageTo->Backend->pfnGetSize(pImageTo->pBackendData);
+            cbSizeTo = vdImageGetSize(pImageTo);
             if (cbSizeTo == 0)
             {
@@ -8012,5 +8060,5 @@
             {
                 /* Get size of image. */
-                uint64_t cbSize = pImage->Backend->pfnGetSize(pImage->pBackendData);
+                uint64_t cbSize = vdImageGetSize(pImage);
                 uint64_t cbSizeFile = pImage->Backend->pfnGetFileSize(pImage->pBackendData);
                 uint64_t cbFileWritten = 0;
@@ -8188,5 +8236,5 @@
 
         /* Cache disk information. */
-        pDisk->cbSize = pImage->Backend->pfnGetSize(pImage->pBackendData);
+        pDisk->cbSize = vdImageGetSize(pImage);
 
         /* Cache PCHS geometry. */
@@ -8751,5 +8799,15 @@
         PVDIMAGE pImage = vdGetImageByNumber(pDisk, nImage);
         AssertPtrBreakStmt(pImage, cbSector = 0);
-        cbSector = pImage->Backend->pfnGetSectorSize(pImage->pBackendData);
+
+        PCVDREGIONLIST pRegionList = NULL;
+        int rc = pImage->Backend->pfnQueryRegions(pImage->pBackendData, &pRegionList);
+        if (RT_SUCCESS(rc))
+        {
+            AssertBreakStmt(pRegionList->cRegions == 1, cbSector = 0);
+            cbSector = pRegionList->aRegions[0].cbBlock;
+
+            AssertPtr(pImage->Backend->pfnRegionListRelease);
+            pImage->Backend->pfnRegionListRelease(pImage->pBackendData, pRegionList);
+        }
     } while (0);
 
@@ -8791,5 +8849,6 @@
         PVDIMAGE pImage = vdGetImageByNumber(pDisk, nImage);
         AssertPtrBreakStmt(pImage, cbSize = 0);
-        cbSize = pImage->Backend->pfnGetSize(pImage->pBackendData);
+
+        cbSize = vdImageGetSize(pImage);
     } while (0);
 
@@ -9219,55 +9278,12 @@
         AssertPtrBreakStmt(pImage, rc = VERR_VD_IMAGE_NOT_FOUND);
 
-        if (pImage->Backend->pfnQueryRegions)
-        {
-            PCVDREGIONLIST pRegionList = NULL;
-            rc = pImage->Backend->pfnQueryRegions(pImage->pBackendData, &pRegionList);
-            if (RT_SUCCESS(rc))
-            {
-                rc = vdRegionListConv(pRegionList, fFlags, ppRegionList);
-
-                AssertPtr(pImage->Backend->pfnRegionListRelease);
-                pImage->Backend->pfnRegionListRelease(pImage->pBackendData, pRegionList);
-            }
-        }
-        else
-            rc = VERR_NOT_SUPPORTED;
-
-        if (rc == VERR_NOT_SUPPORTED)
-        {
-            /*
-             * Create a list with a single region containing the data gathered from the
-             * image and sector size.
-             */
-            PVDREGIONLIST pRegionList = (PVDREGIONLIST)RTMemAllocZ(RT_UOFFSETOF(VDREGIONLIST, aRegions[1]));
-            if (RT_LIKELY(pRegionList))
-            {
-                uint32_t cbSector = pImage->Backend->pfnGetSectorSize(pImage->pBackendData);
-                uint64_t cbImage = pImage->Backend->pfnGetSize(pImage->pBackendData);
-
-                pRegionList->cRegions = 1;
-                pRegionList->fFlags   = fFlags;
-
-                /*
-                 * Single region starting at the first byte/block covering the whole image,
-                 * block size equals sector size and contains no metadata.
-                 */
-                PVDREGIONDESC pRegion = &pRegionList->aRegions[0];
-                pRegion->offRegion       = 0; /* Disk start. */
-                pRegion->cbBlock         = cbSector;
-                pRegion->enmDataForm     = VDREGIONDATAFORM_RAW;
-                pRegion->enmMetadataForm = VDREGIONMETADATAFORM_NONE;
-                pRegion->cbData          = cbSector;
-                pRegion->cbMetadata      = 0;
-                if (fFlags & VD_REGION_LIST_F_LOC_SIZE_BLOCKS)
-                    pRegion->cRegionBlocksOrBytes = cbImage / cbSector;
-                else
-                    pRegion->cRegionBlocksOrBytes = cbImage;
-
-                *ppRegionList  = pRegionList;
-                rc = VINF_SUCCESS;
-            }
-            else
-                rc = VERR_NO_MEMORY;
+        PCVDREGIONLIST pRegionList = NULL;
+        rc = pImage->Backend->pfnQueryRegions(pImage->pBackendData, &pRegionList);
+        if (RT_SUCCESS(rc))
+        {
+            rc = vdRegionListConv(pRegionList, fFlags, ppRegionList);
+
+            AssertPtr(pImage->Backend->pfnRegionListRelease);
+            pImage->Backend->pfnRegionListRelease(pImage->pBackendData, pRegionList);
         }
     } while (0);
Index: /trunk/src/VBox/Storage/VDI.cpp
===================================================================
--- /trunk/src/VBox/Storage/VDI.cpp	(revision 66485)
+++ /trunk/src/VBox/Storage/VDI.cpp	(revision 66486)
@@ -731,5 +731,19 @@
 
     if (RT_SUCCESS(rc))
+    {
+        PVDREGIONDESC pRegion = &pImage->RegionList.aRegions[0];
+        pImage->RegionList.fFlags   = 0;
+        pImage->RegionList.cRegions = 1;
+
+        pRegion->offRegion            = 0; /* Disk start. */
+        pRegion->cbBlock              = 512;
+        pRegion->enmDataForm          = VDREGIONDATAFORM_RAW;
+        pRegion->enmMetadataForm      = VDREGIONMETADATAFORM_NONE;
+        pRegion->cbData               = 512;
+        pRegion->cbMetadata           = 0;
+        pRegion->cRegionBlocksOrBytes = getImageDiskSize(&pImage->Header);
+
         vdIfProgress(pIfProgress, uPercentStart + uPercentSpan);
+    }
 
     if (RT_FAILURE(rc))
@@ -962,5 +976,19 @@
      *       choice of retrying the open if it failed. */
 
-    if (RT_FAILURE(rc))
+    if (RT_SUCCESS(rc))
+    {
+        PVDREGIONDESC pRegion = &pImage->RegionList.aRegions[0];
+        pImage->RegionList.fFlags   = 0;
+        pImage->RegionList.cRegions = 1;
+
+        pRegion->offRegion            = 0; /* Disk start. */
+        pRegion->cbBlock              = 512;
+        pRegion->enmDataForm          = VDREGIONDATAFORM_RAW;
+        pRegion->enmMetadataForm      = VDREGIONMETADATAFORM_NONE;
+        pRegion->cbData               = 512;
+        pRegion->cbMetadata           = 0;
+        pRegion->cRegionBlocksOrBytes = getImageDiskSize(&pImage->Header);
+    }
+    else
         vdiFreeImage(pImage, false);
     return rc;
@@ -1391,5 +1419,5 @@
     AssertReturn((VALID_PTR(pszFilename) && *pszFilename), VERR_INVALID_PARAMETER);
 
-    PVDIIMAGEDESC pImage = (PVDIIMAGEDESC)RTMemAllocZ(sizeof(VDIIMAGEDESC));
+    PVDIIMAGEDESC pImage = (PVDIIMAGEDESC)RTMemAllocZ(RT_UOFFSETOF(VDIIMAGEDESC, RegionList.aRegions[1]));
     if (RT_LIKELY(pImage))
     {
@@ -1447,5 +1475,5 @@
                  && VALID_PTR(pLCHSGeometry), VERR_INVALID_PARAMETER);
 
-    PVDIIMAGEDESC pImage = (PVDIIMAGEDESC)RTMemAllocZ(sizeof(VDIIMAGEDESC));
+    PVDIIMAGEDESC pImage = (PVDIIMAGEDESC)RTMemAllocZ(RT_UOFFSETOF(VDIIMAGEDESC, RegionList.aRegions[1]));
     if (RT_LIKELY(pImage))
     {
@@ -1736,32 +1764,4 @@
 }
 
-/** @copydoc VDIMAGEBACKEND::pfnGetSectorSize */
-static DECLCALLBACK(uint32_t) vdiGetSectorSize(void *pBackendData)
-{
-    LogFlowFunc(("pBackendData=%#p\n", pBackendData));
-    PVDIIMAGEDESC pImage = (PVDIIMAGEDESC)pBackendData;
-    uint64_t cbSector = 0;
-
-    AssertPtrReturn(pImage, 0);
-
-    if (pImage->pStorage)
-        cbSector = 512;
-
-    LogFlowFunc(("returns %zu\n", cbSector));
-    return cbSector;
-}
-
-/** @copydoc VDIMAGEBACKEND::pfnGetSize */
-static DECLCALLBACK(uint64_t) vdiGetSize(void *pBackendData)
-{
-    LogFlowFunc(("pBackendData=%#p\n", pBackendData));
-    PVDIIMAGEDESC pImage = (PVDIIMAGEDESC)pBackendData;
-
-    AssertPtrReturn(pImage, 0);
-
-    LogFlowFunc(("returns %llu\n", getImageDiskSize(&pImage->Header)));
-    return getImageDiskSize(&pImage->Header);
-}
-
 /** @copydoc VDIMAGEBACKEND::pfnGetFileSize */
 static DECLCALLBACK(uint64_t) vdiGetFileSize(void *pBackendData)
@@ -1881,4 +1881,28 @@
     LogFlowFunc(("returns %Rrc\n", rc));
     return rc;
+}
+
+/** @copydoc VDIMAGEBACKEND::pfnQueryRegions */
+static DECLCALLBACK(int) vdiQueryRegions(void *pBackendData, PCVDREGIONLIST *ppRegionList)
+{
+    LogFlowFunc(("pBackendData=%#p ppRegionList=%#p\n", pBackendData, ppRegionList));
+    PVDIIMAGEDESC pThis = (PVDIIMAGEDESC)pBackendData;
+
+    AssertPtrReturn(pThis, VERR_VD_NOT_OPENED);
+
+    *ppRegionList = &pThis->RegionList;
+    LogFlowFunc(("returns %Rrc\n", VINF_SUCCESS));
+    return VINF_SUCCESS;
+}
+
+/** @copydoc VDIMAGEBACKEND::pfnRegionListRelease */
+static DECLCALLBACK(void) vdiRegionListRelease(void *pBackendData, PCVDREGIONLIST pRegionList)
+{
+    RT_NOREF1(pRegionList);
+    LogFlowFunc(("pBackendData=%#p pRegionList=%#p\n", pBackendData, pRegionList));
+    PVDIIMAGEDESC pThis = (PVDIIMAGEDESC)pBackendData;
+    AssertPtr(pThis); RT_NOREF(pThis);
+
+    /* Nothing to do here. */
 }
 
@@ -3124,8 +3148,4 @@
     /* pfnGetVersion */
     vdiGetVersion,
-    /* pfnGetSectorSize */
-    vdiGetSectorSize,
-    /* pfnGetSize */
-    vdiGetSize,
     /* pfnGetFileSize */
     vdiGetFileSize,
@@ -3139,7 +3159,7 @@
     vdiSetLCHSGeometry,
     /* pfnQueryRegions */
-    NULL,
+    vdiQueryRegions,
     /* pfnRegionListRelease */
-    NULL,
+    vdiRegionListRelease,
     /* pfnGetImageFlags */
     vdiGetImageFlags,
Index: /trunk/src/VBox/Storage/VDICore.h
===================================================================
--- /trunk/src/VBox/Storage/VDICore.h	(revision 66485)
+++ /trunk/src/VBox/Storage/VDICore.h	(revision 66486)
@@ -564,4 +564,6 @@
     /** Current size of the image (used for range validation when reading). */
     uint64_t                cbImage;
+    /** The static region list. */
+    VDREGIONLIST            RegionList;
 } VDIIMAGEDESC, *PVDIIMAGEDESC;
 
Index: /trunk/src/VBox/Storage/VDInternal.h
===================================================================
--- /trunk/src/VBox/Storage/VDInternal.h	(revision 66485)
+++ /trunk/src/VBox/Storage/VDInternal.h	(revision 66486)
@@ -272,4 +272,8 @@
 DECLHIDDEN(int)      vdFindFilterBackend(const char *pszFilter, PCVDFILTERBACKEND *ppBackend);
 
+DECLHIDDEN(int)      vdIoIterQueryStartNext(VDIOITER hVdIoIter, uint64_t *pu64Start);
+DECLHIDDEN(int)      vdIoIterQuerySegSizeByStart(VDIOITER hVdIoIter, uint64_t u64Start, size_t *pcRegSize);
+DECLHIDDEN(int)      vdIoIterAdvance(VDIOITER hVdIoIter, uint64_t cBlocksOrBytes);
+
 #endif /* !___VDInternal_h */
 
Index: /trunk/src/VBox/Storage/VHD.cpp
===================================================================
--- /trunk/src/VBox/Storage/VHD.cpp	(revision 66485)
+++ /trunk/src/VBox/Storage/VHD.cpp	(revision 66486)
@@ -188,4 +188,6 @@
     /** Flag to force dynamic disk header update. */
     bool            fDynHdrNeedsUpdate;
+    /** The static region list. */
+    VDREGIONLIST    RegionList;
 } VHDIMAGE, *PVHDIMAGE;
 
@@ -892,5 +894,19 @@
         rc = vhdLoadDynamicDisk(pImage, pImage->u64DataOffset);
 
-    if (RT_FAILURE(rc))
+    if (RT_SUCCESS(rc))
+    {
+        PVDREGIONDESC pRegion = &pImage->RegionList.aRegions[0];
+        pImage->RegionList.fFlags   = 0;
+        pImage->RegionList.cRegions = 1;
+
+        pRegion->offRegion            = 0; /* Disk start. */
+        pRegion->cbBlock              = 512;
+        pRegion->enmDataForm          = VDREGIONDATAFORM_RAW;
+        pRegion->enmMetadataForm      = VDREGIONMETADATAFORM_NONE;
+        pRegion->cbData               = 512;
+        pRegion->cbMetadata           = 0;
+        pRegion->cRegionBlocksOrBytes = pImage->cbSize;
+    }
+    else
         vhdFreeImage(pImage, false);
     return rc;
@@ -1230,5 +1246,19 @@
         vdIfProgress(pIfProgress, uPercentStart + uPercentSpan);
 
-    if (RT_FAILURE(rc))
+    if (RT_SUCCESS(rc))
+    {
+        PVDREGIONDESC pRegion = &pImage->RegionList.aRegions[0];
+        pImage->RegionList.fFlags   = 0;
+        pImage->RegionList.cRegions = 1;
+
+        pRegion->offRegion            = 0; /* Disk start. */
+        pRegion->cbBlock              = 512;
+        pRegion->enmDataForm          = VDREGIONDATAFORM_RAW;
+        pRegion->enmMetadataForm      = VDREGIONMETADATAFORM_NONE;
+        pRegion->cbData               = 512;
+        pRegion->cbMetadata           = 0;
+        pRegion->cRegionBlocksOrBytes = pImage->cbSize;
+    }
+    else
         vhdFreeImage(pImage, rc != VERR_ALREADY_EXISTS);
     return rc;
@@ -1307,5 +1337,5 @@
     AssertReturn((VALID_PTR(pszFilename) && *pszFilename), VERR_INVALID_PARAMETER);
 
-    PVHDIMAGE pImage = (PVHDIMAGE)RTMemAllocZ(sizeof(VHDIMAGE));
+    PVHDIMAGE pImage = (PVHDIMAGE)RTMemAllocZ(RT_UOFFSETOF(VHDIMAGE, RegionList.aRegions[1]));
     if (RT_LIKELY(pImage))
     {
@@ -1355,5 +1385,5 @@
     /** @todo Check the values of other params */
 
-    PVHDIMAGE pImage = (PVHDIMAGE)RTMemAllocZ(sizeof(VHDIMAGE));
+    PVHDIMAGE pImage = (PVHDIMAGE)RTMemAllocZ(RT_UOFFSETOF(VHDIMAGE, RegionList.aRegions[1]));
     if (RT_LIKELY(pImage))
     {
@@ -1829,36 +1859,4 @@
 }
 
-/** @interface_method_impl{VDIMAGEBACKEND,pfnGetSectorSize} */
-static DECLCALLBACK(uint32_t) vhdGetSectorSize(void *pBackendData)
-{
-    LogFlowFunc(("pBackendData=%#p\n", pBackendData));
-    PVHDIMAGE pImage = (PVHDIMAGE)pBackendData;
-    uint32_t cb = 0;
-
-    AssertPtrReturn(pImage, 0);
-
-    if (pImage->pStorage)
-        cb = VHD_SECTOR_SIZE;
-
-    LogFlowFunc(("returns %zu\n", cb));
-    return cb;
-}
-
-/** @interface_method_impl{VDIMAGEBACKEND,pfnGetSize} */
-static DECLCALLBACK(uint64_t) vhdGetSize(void *pBackendData)
-{
-    LogFlowFunc(("pBackendData=%#p\n", pBackendData));
-    PVHDIMAGE pImage = (PVHDIMAGE)pBackendData;
-    uint64_t cb = 0;
-
-    AssertPtr(pImage);
-
-    if (pImage && pImage->pStorage)
-        cb = pImage->cbSize;
-
-    LogFlowFunc(("returns %llu\n", cb));
-    return cb;
-}
-
 /** @interface_method_impl{VDIMAGEBACKEND,pfnGetFileSize} */
 static DECLCALLBACK(uint64_t) vhdGetFileSize(void *pBackendData)
@@ -1949,4 +1947,28 @@
     LogFlowFunc(("returns %Rrc\n", rc));
     return rc;
+}
+
+/** @copydoc VDIMAGEBACKEND::pfnQueryRegions */
+static DECLCALLBACK(int) vhdQueryRegions(void *pBackendData, PCVDREGIONLIST *ppRegionList)
+{
+    LogFlowFunc(("pBackendData=%#p ppRegionList=%#p\n", pBackendData, ppRegionList));
+    PVHDIMAGE pThis = (PVHDIMAGE)pBackendData;
+
+    AssertPtrReturn(pThis, VERR_VD_NOT_OPENED);
+
+    *ppRegionList = &pThis->RegionList;
+    LogFlowFunc(("returns %Rrc\n", VINF_SUCCESS));
+    return VINF_SUCCESS;
+}
+
+/** @copydoc VDIMAGEBACKEND::pfnRegionListRelease */
+static DECLCALLBACK(void) vhdRegionListRelease(void *pBackendData, PCVDREGIONLIST pRegionList)
+{
+    RT_NOREF1(pRegionList);
+    LogFlowFunc(("pBackendData=%#p pRegionList=%#p\n", pBackendData, pRegionList));
+    PVHDIMAGE pThis = (PVHDIMAGE)pBackendData;
+    AssertPtr(pThis); RT_NOREF(pThis);
+
+    /* Nothing to do here. */
 }
 
@@ -3044,8 +3066,4 @@
     /* pfnGetVersion */
     vhdGetVersion,
-    /* pfnGetSectorSize */
-    vhdGetSectorSize,
-    /* pfnGetSize */
-    vhdGetSize,
     /* pfnGetFileSize */
     vhdGetFileSize,
@@ -3059,7 +3077,7 @@
     vhdSetLCHSGeometry,
     /* pfnQueryRegions */
-    NULL,
+    vhdQueryRegions,
     /* pfnRegionListRelease */
-    NULL,
+    vhdRegionListRelease,
     /* pfnGetImageFlags */
     vhdGetImageFlags,
Index: /trunk/src/VBox/Storage/VHDX.cpp
===================================================================
--- /trunk/src/VBox/Storage/VHDX.cpp	(revision 66485)
+++ /trunk/src/VBox/Storage/VHDX.cpp	(revision 66486)
@@ -550,5 +550,6 @@
     /** Chunk ratio. */
     uint32_t            uChunkRatio;
-
+    /** The static region list. */
+    VDREGIONLIST        RegionList;
 } VHDXIMAGE, *PVHDXIMAGE;
 
@@ -1744,5 +1745,19 @@
     }
 
-    if (RT_FAILURE(rc))
+    if (RT_SUCCESS(rc))
+    {
+        PVDREGIONDESC pRegion = &pImage->RegionList.aRegions[0];
+        pImage->RegionList.fFlags   = 0;
+        pImage->RegionList.cRegions = 1;
+
+        pRegion->offRegion            = 0; /* Disk start. */
+        pRegion->cbBlock              = pImage->cbLogicalSector;
+        pRegion->enmDataForm          = VDREGIONDATAFORM_RAW;
+        pRegion->enmMetadataForm      = VDREGIONMETADATAFORM_NONE;
+        pRegion->cbData               = pImage->cbLogicalSector;
+        pRegion->cbMetadata           = 0;
+        pRegion->cRegionBlocksOrBytes = pImage->cbSize;
+    }
+    else
         vhdxFreeImage(pImage, false);
 
@@ -1828,5 +1843,5 @@
     else
     {
-        pImage = (PVHDXIMAGE)RTMemAllocZ(sizeof(VHDXIMAGE));
+        pImage = (PVHDXIMAGE)RTMemAllocZ(RT_UOFFSETOF(VHDXIMAGE, RegionList.aRegions[1]));
         if (!pImage)
             rc = VERR_NO_MEMORY;
@@ -2042,36 +2057,4 @@
 }
 
-/** @copydoc VDIMAGEBACKEND::pfnGetSectorSize */
-static DECLCALLBACK(uint32_t) vhdxGetSectorSize(void *pBackendData)
-{
-    LogFlowFunc(("pBackendData=%#p\n", pBackendData));
-    PVHDXIMAGE pImage = (PVHDXIMAGE)pBackendData;
-    uint32_t cb = 0;
-
-    AssertPtr(pImage);
-
-    if (pImage && pImage->pStorage)
-        cb = pImage->cbLogicalSector;
-
-    LogFlowFunc(("returns %u\n", cb));
-    return cb;
-}
-
-/** @copydoc VDIMAGEBACKEND::pfnGetSize */
-static DECLCALLBACK(uint64_t) vhdxGetSize(void *pBackendData)
-{
-    LogFlowFunc(("pBackendData=%#p\n", pBackendData));
-    PVHDXIMAGE pImage = (PVHDXIMAGE)pBackendData;
-    uint64_t cb = 0;
-
-    AssertPtr(pImage);
-
-    if (pImage && pImage->pStorage)
-        cb = pImage->cbSize;
-
-    LogFlowFunc(("returns %llu\n", cb));
-    return cb;
-}
-
 /** @copydoc VDIMAGEBACKEND::pfnGetFileSize */
 static DECLCALLBACK(uint64_t) vhdxGetFileSize(void *pBackendData)
@@ -2195,4 +2178,28 @@
     LogFlowFunc(("returns %Rrc\n", rc));
     return rc;
+}
+
+/** @copydoc VDIMAGEBACKEND::pfnQueryRegions */
+static DECLCALLBACK(int) vhdxQueryRegions(void *pBackendData, PCVDREGIONLIST *ppRegionList)
+{
+    LogFlowFunc(("pBackendData=%#p ppRegionList=%#p\n", pBackendData, ppRegionList));
+    PVHDXIMAGE pThis = (PVHDXIMAGE)pBackendData;
+
+    AssertPtrReturn(pThis, VERR_VD_NOT_OPENED);
+
+    *ppRegionList = &pThis->RegionList;
+    LogFlowFunc(("returns %Rrc\n", VINF_SUCCESS));
+    return VINF_SUCCESS;
+}
+
+/** @copydoc VDIMAGEBACKEND::pfnRegionListRelease */
+static DECLCALLBACK(void) vhdxRegionListRelease(void *pBackendData, PCVDREGIONLIST pRegionList)
+{
+    RT_NOREF1(pRegionList);
+    LogFlowFunc(("pBackendData=%#p pRegionList=%#p\n", pBackendData, pRegionList));
+    PVHDXIMAGE pThis = (PVHDXIMAGE)pBackendData;
+    AssertPtr(pThis); RT_NOREF(pThis);
+
+    /* Nothing to do here. */
 }
 
@@ -2520,8 +2527,4 @@
     /* pfnGetVersion */
     vhdxGetVersion,
-    /* pfnGetSectorSize */
-    vhdxGetSectorSize,
-    /* pfnGetSize */
-    vhdxGetSize,
     /* pfnGetFileSize */
     vhdxGetFileSize,
@@ -2535,7 +2538,7 @@
     vhdxSetLCHSGeometry,
     /* pfnQueryRegions */
-    NULL,
+    vhdxQueryRegions,
     /* pfnRegionListRelease */
-    NULL,
+    vhdxRegionListRelease,
     /* pfnGetImageFlags */
     vhdxGetImageFlags,
Index: /trunk/src/VBox/Storage/VMDK.cpp
===================================================================
--- /trunk/src/VBox/Storage/VMDK.cpp	(revision 66485)
+++ /trunk/src/VBox/Storage/VMDK.cpp	(revision 66486)
@@ -436,4 +436,6 @@
     /** Parsed descriptor file content. */
     VMDKDESCRIPTOR  Descriptor;
+    /** The static region list. */
+    VDREGIONLIST    RegionList;
 } VMDKIMAGE;
 
@@ -3340,5 +3342,19 @@
      *       choice of retrying the open if it failed. */
 
-    if (RT_FAILURE(rc))
+    if (RT_SUCCESS(rc))
+    {
+        PVDREGIONDESC pRegion = &pImage->RegionList.aRegions[0];
+        pImage->RegionList.fFlags   = 0;
+        pImage->RegionList.cRegions = 1;
+
+        pRegion->offRegion            = 0; /* Disk start. */
+        pRegion->cbBlock              = 512;
+        pRegion->enmDataForm          = VDREGIONDATAFORM_RAW;
+        pRegion->enmMetadataForm      = VDREGIONMETADATAFORM_NONE;
+        pRegion->cbData               = 512;
+        pRegion->cbMetadata           = 0;
+        pRegion->cRegionBlocksOrBytes = pImage->cbSize;
+    }
+    else
         vmdkFreeImage(pImage, false);
     return rc;
@@ -4053,5 +4069,19 @@
 
     if (RT_SUCCESS(rc))
+    {
+        PVDREGIONDESC pRegion = &pImage->RegionList.aRegions[0];
+        pImage->RegionList.fFlags   = 0;
+        pImage->RegionList.cRegions = 1;
+
+        pRegion->offRegion            = 0; /* Disk start. */
+        pRegion->cbBlock              = 512;
+        pRegion->enmDataForm          = VDREGIONDATAFORM_RAW;
+        pRegion->enmMetadataForm      = VDREGIONMETADATAFORM_NONE;
+        pRegion->cbData               = 512;
+        pRegion->cbMetadata           = 0;
+        pRegion->cRegionBlocksOrBytes = pImage->cbSize;
+
         vdIfProgress(pIfProgress, uPercentStart + uPercentSpan);
+    }
     else
         vmdkFreeImage(pImage, rc != VERR_ALREADY_EXISTS);
@@ -5198,5 +5228,5 @@
     AssertReturn((VALID_PTR(pszFilename) && *pszFilename), VERR_INVALID_PARAMETER);
 
-    PVMDKIMAGE pImage = (PVMDKIMAGE)RTMemAllocZ(sizeof(VMDKIMAGE));
+    PVMDKIMAGE pImage = (PVMDKIMAGE)RTMemAllocZ(RT_UOFFSETOF(VMDKIMAGE, RegionList.aRegions[1]));
     if (RT_LIKELY(pImage))
     {
@@ -5259,5 +5289,5 @@
                  && VALID_PTR(pLCHSGeometry), VERR_INVALID_PARAMETER);
 
-    PVMDKIMAGE pImage = (PVMDKIMAGE)RTMemAllocZ(sizeof(VMDKIMAGE));
+    PVMDKIMAGE pImage = (PVMDKIMAGE)RTMemAllocZ(RT_UOFFSETOF(VMDKIMAGE, RegionList.aRegions[1]));
     if (RT_LIKELY(pImage))
     {
@@ -5913,26 +5943,4 @@
 }
 
-/** @copydoc VDIMAGEBACKEND::pfnGetSectorSize */
-static DECLCALLBACK(uint32_t) vmdkGetSectorSize(void *pBackendData)
-{
-    LogFlowFunc(("pBackendData=%#p\n", pBackendData));
-    PVMDKIMAGE pImage = (PVMDKIMAGE)pBackendData;
-
-    AssertPtrReturn(pImage, 0);
-
-    return 512;
-}
-
-/** @copydoc VDIMAGEBACKEND::pfnGetSize */
-static DECLCALLBACK(uint64_t) vmdkGetSize(void *pBackendData)
-{
-    LogFlowFunc(("pBackendData=%#p\n", pBackendData));
-    PVMDKIMAGE pImage = (PVMDKIMAGE)pBackendData;
-
-    AssertPtrReturn(pImage, 0);
-
-    return pImage->cbSize;
-}
-
 /** @copydoc VDIMAGEBACKEND::pfnGetFileSize */
 static DECLCALLBACK(uint64_t) vmdkGetFileSize(void *pBackendData)
@@ -6056,4 +6064,28 @@
     LogFlowFunc(("returns %Rrc\n", rc));
     return rc;
+}
+
+/** @copydoc VDIMAGEBACKEND::pfnQueryRegions */
+static DECLCALLBACK(int) vmdkQueryRegions(void *pBackendData, PCVDREGIONLIST *ppRegionList)
+{
+    LogFlowFunc(("pBackendData=%#p ppRegionList=%#p\n", pBackendData, ppRegionList));
+    PVMDKIMAGE pThis = (PVMDKIMAGE)pBackendData;
+
+    AssertPtrReturn(pThis, VERR_VD_NOT_OPENED);
+
+    *ppRegionList = &pThis->RegionList;
+    LogFlowFunc(("returns %Rrc\n", VINF_SUCCESS));
+    return VINF_SUCCESS;
+}
+
+/** @copydoc VDIMAGEBACKEND::pfnRegionListRelease */
+static DECLCALLBACK(void) vmdkRegionListRelease(void *pBackendData, PCVDREGIONLIST pRegionList)
+{
+    RT_NOREF1(pRegionList);
+    LogFlowFunc(("pBackendData=%#p pRegionList=%#p\n", pBackendData, pRegionList));
+    PVMDKIMAGE pThis = (PVMDKIMAGE)pBackendData;
+    AssertPtr(pThis); RT_NOREF(pThis);
+
+    /* Nothing to do here. */
 }
 
@@ -6401,8 +6433,4 @@
     /* pfnGetVersion */
     vmdkGetVersion,
-    /* pfnGetSectorSize */
-    vmdkGetSectorSize,
-    /* pfnGetSize */
-    vmdkGetSize,
     /* pfnGetFileSize */
     vmdkGetFileSize,
@@ -6416,7 +6444,7 @@
     vmdkSetLCHSGeometry,
     /* pfnQueryRegions */
-    NULL,
+    vmdkQueryRegions,
     /* pfnRegionListRelease */
-    NULL,
+    vmdkRegionListRelease,
     /* pfnGetImageFlags */
     vmdkGetImageFlags,
