Index: trunk/include/iprt/dvm.h
===================================================================
--- trunk/include/iprt/dvm.h	(revision 40026)
+++ trunk/include/iprt/dvm.h	(revision 40027)
@@ -77,4 +77,17 @@
 } RTDVMVOLTYPE;
 
+/** @defgroup grp_dvm_flags     Flags used by RTDvmCreate.
+ * @{ */
+/** DVM flags - Blocks are always marked as unused if the volume has
+ *              no block status callback set.
+ *              The default is to mark them as used. */
+#define DVM_FLAGS_NO_STATUS_CALLBACK_MARK_AS_UNUSED    RT_BIT_32(0)
+/** DVM flags - Space which is unused in the map will be marked as used
+ *              when calling RTDvmMapQueryBlockStatus(). */
+#define DVM_FLAGS_UNUSED_SPACE_MARK_AS_USED            RT_BIT_32(1)
+/** Mask of all valid flags. */
+#define DVM_FLAGS_MASK (DVM_FLAGS_NO_STATUS_CALLBACK_MARK_AS_UNUSED | DVM_FLAGS_UNUSED_SPACE_MARK_AS_USED)
+/** @}  */
+
 
 /** @defgroup grp_dvm_vol_flags     Volume flags used by DVMVolumeGetFlags.
@@ -125,4 +138,18 @@
 /** Pointer to a read callback. */
 typedef FNDVMWRITE *PFNDVMWRITE;
+
+/**
+ * Callback for querying the block allocation status of a volume.
+ *
+ * @returns IPRT status code.
+ * @param   pvUser         Opaque user data passed when setting the callback.
+ * @param   off            Offset relative to the start of the volume.
+ * @param   cb             Range to check in bytes.
+ * @param   pfAllocated    Where to store the allocation status on success.
+ */
+typedef DECLCALLBACK(int) FNDVMVOLUMEQUERYBLOCKSTATUS(void *pvUser, uint64_t off,
+                                                      uint64_t cb, bool *pfAllocated);
+/** Pointer to a query block allocation status callback. */
+typedef FNDVMVOLUMEQUERYBLOCKSTATUS *PFNDVMVOLUMEQUERYBLOCKSTATUS;
 
 /**
@@ -138,9 +165,11 @@
  * @param   cbDisk      Size of the underlying disk in bytes.
  * @param   cbSector    Size of one sector in bytes.
+ * @param   fFlags      Combination of RTDVM_FLAGS_*
  * @param   pvUser      Opaque user data passed to the callbacks.
  */
 RTDECL(int) RTDvmCreate(PRTDVM phVolMgr, PFNDVMREAD pfnRead,
                         PFNDVMWRITE pfnWrite, uint64_t cbDisk,
-                        uint64_t cbSector, void *pvUser);
+                        uint64_t cbSector, uint32_t fFlags,
+                        void *pvUser);
 
 /**
@@ -225,4 +254,18 @@
 
 /**
+ * Returns whether the given block on the disk is in use.
+ *
+ * @returns IPRT status code.
+ * @param   hVolMgr         The volume manager handler.
+ * @param   off             The start offset to check for.
+ * @param   cb              The range in bytes to check.
+ * @param   pfAllocated     Where to store the status on success.
+ *
+ * @remark This method will return true even if a part of the range is not in use.
+ */
+RTDECL(int) RTDvmMapQueryBlockStatus(RTDVM hVolMgr, uint64_t off, uint64_t cb,
+                                     bool *pfAllocated);
+
+/**
  * Retains a valid volume handle.
  *
@@ -239,4 +282,18 @@
  */
 RTDECL(uint32_t) RTDvmVolumeRelease(RTDVMVOLUME hVol);
+
+/**
+ * Sets the callback to query the block allocation status for a volume.
+ * This overwrites any other callback set previously.
+ *
+ * @returns nothing.
+ * @param   hVol                   The volume handle.
+ * @param   pfnQueryBlockStatus    The callback to set. Can be NULL to disable
+ *                                 a previous callback.
+ * @param   pvUser                 Opaque user data passed in the callback.
+ */
+RTDECL(void) RTDvmVolumeSetQueryBlockStatusCallback(RTDVMVOLUME hVol,
+                                                    PFNDVMVOLUMEQUERYBLOCKSTATUS pfnQueryBlockStatus,
+                                                    void *pvUser);
 
 /**
Index: trunk/include/iprt/mangling.h
===================================================================
--- trunk/include/iprt/mangling.h	(revision 40026)
+++ trunk/include/iprt/mangling.h	(revision 40027)
@@ -410,4 +410,5 @@
 # define RTDvmMapGetValidVolumes                        RT_MANGLER(RTDvmMapGetValidVolumes)
 # define RTDvmMapGetMaxVolumes                          RT_MANGLER(RTDvmMapGetMaxVolumes)
+# define RTDvmMapQueryBlockStatus                       RT_MANGLER(RTDvmMapQueryBlockStatus)
 # define RTDvmMapQueryFirstVolume                       RT_MANGLER(RTDvmMapQueryFirstVolume)
 # define RTDvmMapQueryNextVolume                        RT_MANGLER(RTDvmMapQueryNextVolume)
@@ -420,4 +421,5 @@
 # define RTDvmVolumeRead                                RT_MANGLER(RTDvmVolumeRead)
 # define RTDvmVolumeWrite                               RT_MANGLER(RTDvmVolumeWrite)
+# define RTDvmVolumeSetQueryBlockStatusCallback         RT_MANGLER(RTDvmVolumeSetQueryBlockStatusCallback)
 # define RTDvmVolumeTypeGetDescr                        RT_MANGLER(RTDvmVolumeTypeGetDescr)
 # define RTEnvClone                                     RT_MANGLER(RTEnvClone)
Index: trunk/src/VBox/Runtime/common/dvm/dvm.cpp
===================================================================
--- trunk/src/VBox/Runtime/common/dvm/dvm.cpp	(revision 40026)
+++ trunk/src/VBox/Runtime/common/dvm/dvm.cpp	(revision 40027)
@@ -36,4 +36,5 @@
 #include <iprt/asm.h>
 #include <iprt/string.h>
+#include <iprt/list.h>
 #include "internal/dvm.h"
 
@@ -55,6 +56,10 @@
     /** The format specific volume manager data. */
     RTDVMFMT          hVolMgrFmt;
+    /** Flags passed on manager creation. */
+    uint32_t          fFlags;
     /** Reference counter. */
     uint32_t volatile cRefs;
+    /** List of recognised volumes (RTDVMVOLUMEINTERNAL). */
+    RTLISTANCHOR      VolumeList;
 } RTDVMINTERNAL;
 /** Pointer to an internal volume manager. */
@@ -67,11 +72,17 @@
 {
     /** The DVM volume magic (RTDVMVOLUME_MAGIC). */
-    uint32_t          u32Magic;
+    uint32_t                      u32Magic;
+    /** Node for the volume list. */
+    RTLISTNODE                    VolumeNode;
     /** Pointer to the owning volume manager. */
-    PRTDVMINTERNAL    pVolMgr;
+    PRTDVMINTERNAL                pVolMgr;
     /** Format specific volume data. */
-    RTDVMVOLUMEFMT    hVolFmt;
+    RTDVMVOLUMEFMT                hVolFmt;
+    /** Set block status.callback */
+    PFNDVMVOLUMEQUERYBLOCKSTATUS  pfnQueryBlockStatus;
+    /** Opaque user data. */
+    void                         *pvUser;
     /** Reference counter. */
-    uint32_t volatile cRefs;
+    uint32_t volatile             cRefs;
 } RTDVMVOLUMEINTERNAL;
 /** Pointer to an internal volume. */
@@ -118,10 +129,67 @@
 };
 
+/**
+ * Creates a new volume.
+ *
+ * @returns IPRT status code.
+ * @param   pThis    The DVM map instance.
+ * @param   hVolFmt  The format specific volume handle.
+ * @param   phVol    Where to store the generic volume handle on success.
+ */
+static int rtDvmVolumeCreate(PRTDVMINTERNAL pThis, RTDVMVOLUMEFMT hVolFmt,
+                             PRTDVMVOLUME phVol)
+{
+    int rc = VINF_SUCCESS;
+    PRTDVMVOLUMEINTERNAL pVol = NULL;
+
+    pVol = (PRTDVMVOLUMEINTERNAL)RTMemAllocZ(sizeof(RTDVMVOLUMEINTERNAL));
+    if (VALID_PTR(pVol))
+    {
+        pVol->u32Magic = RTDVMVOLUME_MAGIC;
+        pVol->cRefs    = 0;
+        pVol->pVolMgr  = pThis;
+        pVol->hVolFmt  = hVolFmt;
+
+        *phVol = pVol;
+    }
+    else
+        rc = VERR_NO_MEMORY;
+
+    return rc;
+}
+
+/**
+ * Destroys a volume handle.
+ *
+ * @param   pThis               The volume to destroy.
+ */
+static void rtDvmVolumeDestroy(PRTDVMVOLUMEINTERNAL pThis)
+{
+    PRTDVMINTERNAL pVolMgr = pThis->pVolMgr;
+
+    AssertPtr(pVolMgr);
+
+    /* Close the volume. */
+    pVolMgr->pDvmFmtOps->pfnVolumeClose(pThis->hVolFmt);
+
+    pThis->u32Magic = RTDVMVOLUME_MAGIC_DEAD;
+    pThis->pVolMgr  = NULL;
+    pThis->hVolFmt  = NIL_RTDVMVOLUMEFMT;
+    RTMemFree(pThis);
+
+    /* Release the reference of the volume manager. */
+    RTDvmRelease(pVolMgr);
+}
+
 RTDECL(int) RTDvmCreate(PRTDVM phVolMgr, PFNDVMREAD pfnRead,
                         PFNDVMWRITE pfnWrite, uint64_t cbDisk,
-                        uint64_t cbSector, void *pvUser)
+                        uint64_t cbSector, uint32_t fFlags, void *pvUser)
 {
     int rc = VINF_SUCCESS;
     PRTDVMINTERNAL pThis;
+
+    AssertMsgReturn(!(fFlags & ~DVM_FLAGS_MASK),
+                    ("Invalid flags given %#x\n", fFlags),
+                    VERR_INVALID_PARAMETER);
 
     pThis = (PRTDVMINTERNAL)RTMemAllocZ(sizeof(RTDVMINTERNAL));
@@ -136,5 +204,7 @@
         pThis->pDvmFmtOps       = NULL;
         pThis->hVolMgrFmt       = NIL_RTDVMFMT;
+        pThis->fFlags           = fFlags;
         pThis->cRefs            = 1;
+        RTListInit(&pThis->VolumeList);
         *phVolMgr = pThis;
     }
@@ -232,5 +302,59 @@
             rc = pDvmFmtOpsMatch->pfnOpen(&pThis->DvmDisk, &pThis->hVolMgrFmt);
             if (RT_SUCCESS(rc))
+            {
+                uint32_t cVols;
+
                 pThis->pDvmFmtOps = pDvmFmtOpsMatch;
+
+                cVols = pThis->pDvmFmtOps->pfnGetValidVolumes(pThis->hVolMgrFmt);
+
+                /* Construct volume list. */
+                if (cVols)
+                {
+                    PRTDVMVOLUMEINTERNAL pVol = NULL;
+                    RTDVMVOLUMEFMT hVolFmt = NIL_RTDVMVOLUMEFMT;
+
+                    rc = pThis->pDvmFmtOps->pfnQueryFirstVolume(pThis->hVolMgrFmt, &hVolFmt);
+                    if (RT_SUCCESS(rc))
+                    {
+                        rc = rtDvmVolumeCreate(pThis, hVolFmt, &pVol);
+                        if (RT_FAILURE(rc))
+                            pThis->pDvmFmtOps->pfnVolumeClose(hVolFmt);
+                    }
+
+                    if (RT_SUCCESS(rc))
+                    {
+                        cVols--;
+                        RTListAppend(&pThis->VolumeList, &pVol->VolumeNode);
+
+                        while (   cVols > 0
+                               && RT_SUCCESS(rc))
+                        {
+                            rc = pThis->pDvmFmtOps->pfnQueryNextVolume(pThis->hVolMgrFmt, pVol->hVolFmt, &hVolFmt);
+                            if (RT_SUCCESS(rc))
+                            {
+                                rc = rtDvmVolumeCreate(pThis, hVolFmt, &pVol);
+                                if (RT_FAILURE(rc))
+                                    pThis->pDvmFmtOps->pfnVolumeClose(hVolFmt);
+                                else
+                                    RTListAppend(&pThis->VolumeList, &pVol->VolumeNode);
+                                cVols--;
+                            }
+                        }
+                    }
+
+                    if (RT_FAILURE(rc))
+                    {
+                        PRTDVMVOLUMEINTERNAL pItNext, pIt;
+
+                        /* Remove all entries. */
+                        RTListForEachSafe(&pThis->VolumeList, pIt, pItNext, RTDVMVOLUMEINTERNAL, VolumeNode)
+                        {
+                            RTListNodeRemove(&pIt->VolumeNode);
+                            rtDvmVolumeDestroy(pIt);
+                        }
+                    }
+                }
+            }
         }
         else
@@ -243,5 +367,5 @@
 RTDECL(int) RTDvmMapInitialize(RTDVM hVolMgr, const char *pszFmt)
 {
-    int rc = VINF_SUCCESS;
+    int rc = VERR_NOT_SUPPORTED;
     PRTDVMINTERNAL pThis = hVolMgr;
     AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
@@ -297,31 +421,7 @@
 }
 
-static int rtDvmVolumeCreate(PRTDVMINTERNAL pThis, RTDVMVOLUMEFMT hVolFmt,
-                             PRTDVMVOLUME phVol)
-{
-    int rc = VINF_SUCCESS;
-    PRTDVMVOLUMEINTERNAL pVol = NULL;
-
-    pVol = (PRTDVMVOLUMEINTERNAL)RTMemAllocZ(sizeof(RTDVMVOLUMEINTERNAL));
-    if (VALID_PTR(pVol))
-    {
-        pVol->u32Magic = RTDVMVOLUME_MAGIC;
-        pVol->cRefs    = 1;
-        pVol->pVolMgr  = pThis;
-        pVol->hVolFmt  = hVolFmt;
-
-        /* Reference the volume manager. */
-        RTDvmRetain(pThis);
-        *phVol = pVol;
-    }
-    else
-        rc = VERR_NO_MEMORY;
-
-    return rc;
-}
-
 RTDECL(int) RTDvmMapQueryFirstVolume(RTDVM hVolMgr, PRTDVMVOLUME phVol)
 {
-    int rc = VINF_SUCCESS;
+    int rc = VERR_DVM_MAP_EMPTY;
     PRTDVMINTERNAL pThis = hVolMgr;
     AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
@@ -330,11 +430,10 @@
     AssertPtrReturn(phVol, VERR_INVALID_POINTER);
 
-    RTDVMVOLUMEFMT hVolFmt = NIL_RTDVMVOLUMEFMT;
-    rc = pThis->pDvmFmtOps->pfnQueryFirstVolume(pThis->hVolMgrFmt, &hVolFmt);
-    if (RT_SUCCESS(rc))
-    {
-        rc = rtDvmVolumeCreate(pThis, hVolFmt, phVol);
-        if (RT_FAILURE(rc))
-            pThis->pDvmFmtOps->pfnVolumeClose(hVolFmt);
+    PRTDVMVOLUMEINTERNAL pVol = RTListGetFirst(&pThis->VolumeList, RTDVMVOLUMEINTERNAL, VolumeNode);
+    if (pVol)
+    {
+        rc = VINF_SUCCESS;
+        RTDvmVolumeRetain(pVol);
+        *phVol = pVol;
     }
 
@@ -344,5 +443,5 @@
 RTDECL(int) RTDvmMapQueryNextVolume(RTDVM hVolMgr, RTDVMVOLUME hVol, PRTDVMVOLUME phVolNext)
 {
-    int rc = VINF_SUCCESS;
+    int rc = VERR_DVM_MAP_NO_VOLUME;
     PRTDVMINTERNAL       pThis = hVolMgr;
     PRTDVMVOLUMEINTERNAL pVol = hVol;
@@ -354,12 +453,82 @@
     AssertPtrReturn(phVolNext, VERR_INVALID_POINTER);
 
-    RTDVMVOLUMEFMT hVolFmtNext = NIL_RTDVMVOLUMEFMT;
-    rc = pThis->pDvmFmtOps->pfnQueryNextVolume(pThis->hVolMgrFmt, pVol->hVolFmt, &hVolFmtNext);
-    if (RT_SUCCESS(rc))
-    {
-        rc = rtDvmVolumeCreate(pThis, hVolFmtNext, phVolNext);
-        if (RT_FAILURE(rc))
-            pThis->pDvmFmtOps->pfnVolumeClose(hVolFmtNext);
-    }
+    PRTDVMVOLUMEINTERNAL pVolNext = RTListGetNext(&pThis->VolumeList, pVol,
+                                                  RTDVMVOLUMEINTERNAL, VolumeNode);
+    if (pVolNext)
+    {
+        rc = VINF_SUCCESS;
+        RTDvmVolumeRetain(pVolNext);
+        *phVolNext = pVolNext;
+    }
+
+    return rc;
+}
+
+RTDECL(int) RTDvmMapQueryBlockStatus(RTDVM hVolMgr, uint64_t off, uint64_t cb,
+                                     bool *pfAllocated)
+{
+    int rc = VINF_SUCCESS;
+    bool fAllocated = false;
+    PRTDVMINTERNAL       pThis = hVolMgr;
+    AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
+    AssertPtrReturn(pfAllocated, VERR_INVALID_POINTER);
+    AssertReturn(pThis->u32Magic == RTDVM_MAGIC, VERR_INVALID_HANDLE);
+    AssertReturn(pThis->hVolMgrFmt != NIL_RTDVMFMT, VERR_INVALID_HANDLE);
+    AssertReturn(off + cb <= pThis->DvmDisk.cbDisk * pThis->DvmDisk.cbSector,
+                 VERR_INVALID_PARAMETER);
+
+    while (   cb > 0
+           && !fAllocated)
+    {
+        PRTDVMVOLUMEINTERNAL pVol;
+        bool fVolFound = false;
+        size_t cbIntersect;
+        uint64_t offVol;
+
+        /*
+         * Search through all volumes. It is not possible to
+         * get all start sectors and sizes of all volumes here
+         * because volumes can be scattered around the disk for certain formats.
+         * Linux LVM is one example, extents of logical volumes don't need to be
+         * contigous on the medium.
+         */
+        RTListForEach(&pThis->VolumeList, pVol, RTDVMVOLUMEINTERNAL, VolumeNode)
+        {
+            bool fIntersect = pThis->pDvmFmtOps->pfnVolumeIsRangeIntersecting(pVol->hVolFmt, off,
+                                                                              cb, &offVol,
+                                                                              &cbIntersect);
+            if (fIntersect)
+            {
+                fVolFound = true;
+                if (pVol->pfnQueryBlockStatus)
+                {
+                    bool fVolAllocated = true;
+
+                    rc = pVol->pfnQueryBlockStatus(pVol->pvUser, offVol, cbIntersect,
+                                                   &fVolAllocated);
+                    if (RT_FAILURE(rc))
+                        break;
+                }
+                else if (!(pThis->fFlags & DVM_FLAGS_NO_STATUS_CALLBACK_MARK_AS_UNUSED))
+                    fAllocated = true;
+                /* else, flag is set, continue. */
+
+                cb  -= cbIntersect;
+                off += cbIntersect;
+                break;
+            }
+        }
+
+        if (!fVolFound)
+        {
+            if (pThis->fFlags & DVM_FLAGS_UNUSED_SPACE_MARK_AS_USED)
+                fAllocated = true;
+
+            cb  -= pThis->DvmDisk.cbSector;
+            off += pThis->DvmDisk.cbSector;
+        }
+    }
+
+    *pfAllocated = fAllocated;
 
     return rc;
@@ -373,29 +542,8 @@
 
     uint32_t cRefs = ASMAtomicIncU32(&pThis->cRefs);
-    AssertMsg(cRefs > 1 && cRefs < _1M, ("%#x %p\n", cRefs, pThis));
+    AssertMsg(cRefs >= 1 && cRefs < _1M, ("%#x %p\n", cRefs, pThis));
+    if (cRefs == 1)
+        RTDvmRetain(pThis->pVolMgr);
     return cRefs;
-}
-
-/**
- * Destroys a volume handle.
- *
- * @param   pThis               The volume to destroy.
- */
-static void rtDvmVolumeDestroy(PRTDVMVOLUMEINTERNAL pThis)
-{
-    PRTDVMINTERNAL pVolMgr = pThis->pVolMgr;
-
-    AssertPtr(pVolMgr);
-
-    /* Close the volume. */
-    pVolMgr->pDvmFmtOps->pfnVolumeClose(pThis->hVolFmt);
-
-    pThis->u32Magic = RTDVMVOLUME_MAGIC_DEAD;
-    pThis->pVolMgr  = NULL;
-    pThis->hVolFmt  = NIL_RTDVMVOLUMEFMT;
-    RTMemFree(pThis);
-
-    /* Release the reference of the volume manager. */
-    RTDvmRelease(pVolMgr);
 }
 
@@ -411,6 +559,22 @@
     AssertMsg(cRefs < _1M, ("%#x %p\n", cRefs, pThis));
     if (cRefs == 0)
-        rtDvmVolumeDestroy(pThis);
+    {
+        /* Release the volume manager. */
+        pThis->pfnQueryBlockStatus = NULL;
+        RTDvmRelease(pThis->pVolMgr);
+    }
     return cRefs;
+}
+
+RTDECL(void) RTDvmVolumeSetQueryBlockStatusCallback(RTDVMVOLUME hVol,
+                                                    PFNDVMVOLUMEQUERYBLOCKSTATUS pfnQueryBlockStatus,
+                                                    void *pvUser)
+{
+    PRTDVMVOLUMEINTERNAL pThis = hVol;
+    AssertPtrReturnVoid(pThis);
+    AssertReturnVoid(pThis->u32Magic == RTDVMVOLUME_MAGIC);
+
+    pThis->pfnQueryBlockStatus = pfnQueryBlockStatus;
+    pThis->pvUser = pvUser;
 }
 
Index: trunk/src/VBox/Runtime/common/dvm/dvmbsdlabel.cpp
===================================================================
--- trunk/src/VBox/Runtime/common/dvm/dvmbsdlabel.cpp	(revision 40026)
+++ trunk/src/VBox/Runtime/common/dvm/dvmbsdlabel.cpp	(revision 40027)
@@ -466,4 +466,22 @@
 }
 
+DECLCALLBACK(bool) rtDvmFmtBsdLblVolumeIsRangeIntersecting(RTDVMVOLUMEFMT hVolFmt,
+                                                           uint64_t offStart, size_t cbRange,
+                                                           uint64_t *poffVol,
+                                                           size_t *pcbIntersect)
+{
+    bool fIntersect = false;
+    PRTDVMVOLUMEFMTINTERNAL pVol = hVolFmt;
+
+    if (RTDVM_RANGE_IS_INTERSECTING(pVol->offStart, pVol->cbVolume, offStart))
+    {
+        fIntersect    = true;
+        *poffVol      = offStart - pVol->offStart;
+        *pcbIntersect = RT_MIN(cbRange, pVol->offStart + pVol->cbVolume - offStart);
+    }
+
+    return fIntersect;
+}
+
 DECLCALLBACK(int) rtDvmFmtBsdLblVolumeRead(RTDVMVOLUMEFMT hVolFmt, uint64_t off, void *pvBuf, size_t cbRead)
 {
@@ -512,4 +530,6 @@
     /* pfnVolumeGetFlags */
     rtDvmFmtBsdLblVolumeGetFlags,
+    /* pfnVolumeIsRangeIntersecting */
+    rtDvmFmtBsdLblVolumeIsRangeIntersecting,
     /* pfnVolumeRead */
     rtDvmFmtBsdLblVolumeRead,
Index: trunk/src/VBox/Runtime/common/dvm/dvmgpt.cpp
===================================================================
--- trunk/src/VBox/Runtime/common/dvm/dvmgpt.cpp	(revision 40026)
+++ trunk/src/VBox/Runtime/common/dvm/dvmgpt.cpp	(revision 40027)
@@ -482,4 +482,22 @@
     NOREF(hVolFmt); /* No supported flags for now. */
     return 0;
+}
+
+DECLCALLBACK(bool) rtDvmFmtGptVolumeIsRangeIntersecting(RTDVMVOLUMEFMT hVolFmt,
+                                                        uint64_t offStart, size_t cbRange,
+                                                        uint64_t *poffVol,
+                                                        size_t *pcbIntersect)
+{
+    bool fIntersect = false;
+    PRTDVMVOLUMEFMTINTERNAL pVol = hVolFmt;
+
+    if (RTDVM_RANGE_IS_INTERSECTING(pVol->offStart, pVol->cbVolume, offStart))
+    {
+        fIntersect    = true;
+        *poffVol      = offStart - pVol->offStart;
+        *pcbIntersect = RT_MIN(cbRange, pVol->offStart + pVol->cbVolume - offStart);
+    }
+
+    return fIntersect;
 }
 
@@ -530,4 +548,6 @@
     /* pfnVolumeGetFlags */
     rtDvmFmtGptVolumeGetFlags,
+    /* pfnVolumeIsRangeIntersecting */
+    rtDvmFmtGptVolumeIsRangeIntersecting,
     /* pfnVolumeRead */
     rtDvmFmtGptVolumeRead,
Index: trunk/src/VBox/Runtime/common/dvm/dvmmbr.cpp
===================================================================
--- trunk/src/VBox/Runtime/common/dvm/dvmmbr.cpp	(revision 40026)
+++ trunk/src/VBox/Runtime/common/dvm/dvmmbr.cpp	(revision 40027)
@@ -351,4 +351,22 @@
 
     return fFlags;
+}
+
+DECLCALLBACK(bool) rtDvmFmtMbrVolumeIsRangeIntersecting(RTDVMVOLUMEFMT hVolFmt,
+                                                        uint64_t offStart, size_t cbRange,
+                                                        uint64_t *poffVol,
+                                                        size_t *pcbIntersect)
+{
+    bool fIntersect = false;
+    PRTDVMVOLUMEFMTINTERNAL pVol = hVolFmt;
+
+    if (RTDVM_RANGE_IS_INTERSECTING(pVol->offStart, pVol->cbVolume, offStart))
+    {
+        fIntersect    = true;
+        *poffVol      = offStart - pVol->offStart;
+        *pcbIntersect = RT_MIN(cbRange, pVol->offStart + pVol->cbVolume - offStart);
+    }
+
+    return fIntersect;
 }
 
@@ -399,4 +417,6 @@
     /* pfnVolumeGetFlags */
     rtDvmFmtMbrVolumeGetFlags,
+    /* pfnVOlumeIsRangeIntersecting */
+    rtDvmFmtMbrVolumeIsRangeIntersecting,
     /* pfnVolumeRead */
     rtDvmFmtMbrVolumeRead,
Index: trunk/src/VBox/Runtime/testcase/tstRTDvm.cpp
===================================================================
--- trunk/src/VBox/Runtime/testcase/tstRTDvm.cpp	(revision 40026)
+++ trunk/src/VBox/Runtime/testcase/tstRTDvm.cpp	(revision 40027)
@@ -92,5 +92,5 @@
     RTTestSubF(hTest, "Create DVM");
     RTDVM hVolMgr;
-    rc = RTDvmCreate(&hVolMgr, dvmDiskRead, dvmDiskWrite, cb, 512, pDisk);
+    rc = RTDvmCreate(&hVolMgr, dvmDiskRead, dvmDiskWrite, cb, 512, 0, pDisk);
     if (RT_FAILURE(rc))
     {
