Index: /trunk/include/VBox/VBoxHDD.h
===================================================================
--- /trunk/include/VBox/VBoxHDD.h	(revision 22965)
+++ /trunk/include/VBox/VBoxHDD.h	(revision 22966)
@@ -415,4 +415,8 @@
 typedef FNVDCOMPLETED *PFNVDCOMPLETED;
 
+/** Open the storage readonly. */
+#define VD_INTERFACEASYNCIO_OPEN_FLAGS_READONLY RT_BIT(0)
+/** Create the storage backend if it doesn't exist. */
+#define VD_INTERFACEASYNCIO_OPEN_FLAGS_CREATE RT_BIT(1)
 
 /**
@@ -439,5 +443,6 @@
      * @param   pvUser          The opaque data passed on container creation.
      * @param   pszLocation     Name of the location to open.
-     * @param   fReadonly       Whether to open the storage medium read only.
+     * @param   uOpenFlags      Flags for opening the backend.
+     *                          See VD_INTERFACEASYNCIO_OPEN_FLAGS_* #defines
      * @param   pfnCompleted    The callabck which is called whenever a task
      *                          completed. The backend has to pass the user data
@@ -447,5 +452,5 @@
      * @param   ppStorage       Where to store the opaque storage handle.
      */
-    DECLR3CALLBACKMEMBER(int, pfnOpen, (void *pvUser, const char *pszLocation, bool fReadonly,
+    DECLR3CALLBACKMEMBER(int, pfnOpen, (void *pvUser, const char *pszLocation, unsigned uOpenFlags,
                                         PFNVDCOMPLETED pfnCompleted, void **ppStorage));
 
@@ -468,4 +473,15 @@
      */
     DECLR3CALLBACKMEMBER(int, pfnGetSize, (void *pvUser, void *pStorage, uint64_t *pcbSize));
+
+    /**
+     * Sets the size of the opened storage backend if possible.
+     *
+     * @return  VBox status code.
+     * @retval  VERR_NOT_SUPPORTED if the backend does not support this operation.
+     * @param   pvUser          The opaque data passed on container creation.
+     * @param   pStorage        The opaque storage handle to close.
+     * @param   cbSize          The new size of the image.
+     */
+    DECLR3CALLBACKMEMBER(int, pfnSetSize, (void *pvUser, void *pStorage, uint64_t cbSize));
 
     /**
Index: /trunk/src/VBox/Devices/Storage/DrvVD.cpp
===================================================================
--- /trunk/src/VBox/Devices/Storage/DrvVD.cpp	(revision 22965)
+++ /trunk/src/VBox/Devices/Storage/DrvVD.cpp	(revision 22966)
@@ -209,27 +209,31 @@
     PVBOXDISK pThis = PDMINS_2_DATA(pDrvIns, PVBOXDISK);
     PDRVVDSTORAGEBACKEND pStorageBackend = (PDRVVDSTORAGEBACKEND)pvTemplateUser;
-    int rc = VINF_VD_ASYNC_IO_FINISHED;
-    void *pvCallerUser = NULL;
 
     if (pStorageBackend->fSyncIoPending)
     {
-        pStorageBackend->fSyncIoPending;
+        pStorageBackend->fSyncIoPending = false;
         RTSemEventSignal(pStorageBackend->EventSem);
     }
-    else if (pStorageBackend->pfnCompleted)
-        rc = pStorageBackend->pfnCompleted(pvUser, &pvCallerUser);
     else
-        pvCallerUser = pvUser;
-
-    if (rc == VINF_VD_ASYNC_IO_FINISHED)
-    {
-        rc = pThis->pDrvMediaAsyncPort->pfnTransferCompleteNotify(pThis->pDrvMediaAsyncPort, pvCallerUser);
-        AssertRC(rc);
-    }
-    else
-        AssertMsg(rc == VERR_VD_ASYNC_IO_IN_PROGRESS, ("Invalid return code from disk backend rc=%Rrc\n", rc));
-}
-
-static DECLCALLBACK(int) drvvdAsyncIOOpen(void *pvUser, const char *pszLocation, bool fReadonly,
+    {
+        int rc = VINF_VD_ASYNC_IO_FINISHED;
+        void *pvCallerUser = NULL;
+
+        if (pStorageBackend->pfnCompleted)
+            rc = pStorageBackend->pfnCompleted(pvUser, &pvCallerUser);
+        else
+            pvCallerUser = pvUser;
+
+        if (rc == VINF_VD_ASYNC_IO_FINISHED)
+        {
+            rc = pThis->pDrvMediaAsyncPort->pfnTransferCompleteNotify(pThis->pDrvMediaAsyncPort, pvCallerUser);
+            AssertRC(rc);
+        }
+        else
+            AssertMsg(rc == VERR_VD_ASYNC_IO_IN_PROGRESS, ("Invalid return code from disk backend rc=%Rrc\n", rc));
+    }
+}
+
+static DECLCALLBACK(int) drvvdAsyncIOOpen(void *pvUser, const char *pszLocation, unsigned uOpenFlags,
                                           PFNVDCOMPLETED pfnCompleted, void **ppStorage)
 {
@@ -251,5 +255,5 @@
             {
                 rc = PDMR3AsyncCompletionEpCreateForFile(&pStorageBackend->pEndpoint, pszLocation,
-                                                         fReadonly
+                                                         uOpenFlags & VD_INTERFACEASYNCIO_OPEN_FLAGS_READONLY
                                                          ? PDMACEP_FILE_FLAGS_READ_ONLY | PDMACEP_FILE_FLAGS_CACHING
                                                          : PDMACEP_FILE_FLAGS_CACHING,
@@ -292,4 +296,12 @@
 
     return PDMR3AsyncCompletionEpGetSize(pStorageBackend->pEndpoint, pcbSize);
+}
+
+static DECLCALLBACK(int) drvvdAsyncIOSetSize(void *pvUser, void *pStorage, uint64_t cbSize)
+{
+    PVBOXDISK pDrvVD = (PVBOXDISK)pvUser;
+    PDRVVDSTORAGEBACKEND pStorageBackend = (PDRVVDSTORAGEBACKEND)pStorage;
+
+    return VERR_NOT_SUPPORTED;
 }
 
@@ -846,4 +858,5 @@
     pThis->VDIAsyncIOCallbacks.pfnClose                = drvvdAsyncIOClose;
     pThis->VDIAsyncIOCallbacks.pfnGetSize              = drvvdAsyncIOGetSize;
+    pThis->VDIAsyncIOCallbacks.pfnSetSize              = drvvdAsyncIOSetSize;
     pThis->VDIAsyncIOCallbacks.pfnReadSync             = drvvdAsyncIOReadSync;
     pThis->VDIAsyncIOCallbacks.pfnWriteSync            = drvvdAsyncIOWriteSync;
@@ -871,42 +884,4 @@
     /* Try to attach async media port interface above.*/
     pThis->pDrvMediaAsyncPort = (PPDMIMEDIAASYNCPORT)pDrvIns->pUpBase->pfnQueryInterface(pDrvIns->pUpBase, PDMINTERFACE_MEDIA_ASYNC_PORT);
-
-    /*
-     * Attach the async transport driver below if the device above us implements the
-     * async interface.
-     */
-    if (pThis->pDrvMediaAsyncPort)
-    {
-        /* Try to attach the driver. */
-        PPDMIBASE pBase;
-
-        rc = PDMDrvHlpAttach(pDrvIns, fFlags, &pBase);
-        if (rc == VERR_PDM_NO_ATTACHED_DRIVER)
-        {
-            /*
-             * Though the device supports async I/O there is no transport driver
-             * which processes async requests.
-             * Revert to non async I/O.
-             */
-            rc = VINF_SUCCESS;
-            pThis->pDrvMediaAsyncPort = NULL;
-            pThis->fAsyncIOSupported = false;
-        }
-        else if (RT_FAILURE(rc))
-        {
-            AssertMsgFailed(("Failed to attach async transport driver below rc=%Rrc\n", rc));
-        }
-        else
-        {
-            /*
-             * The device supports async I/O and we successfully attached the transport driver.
-             * Indicate that async I/O is supported for now as we check if the image backend supports
-             * it later.
-             */
-            pThis->fAsyncIOSupported = true;
-
-            /** @todo: Use PDM async completion manager */
-        }
-    }
 
     /*
@@ -1042,4 +1017,7 @@
     }
 
+    if (pThis->pDrvMediaAsyncPort)
+        pThis->fAsyncIOSupported = true;
+
     while (pCurNode && RT_SUCCESS(rc))
     {
@@ -1086,5 +1064,5 @@
         if (fHonorZeroWrites)
             uOpenFlags |= VD_OPEN_FLAGS_HONOR_ZEROES;
-        if (pThis->pDrvMediaAsyncPort)
+        if (pThis->fAsyncIOSupported)
             uOpenFlags |= VD_OPEN_FLAGS_ASYNC_IO;
 
@@ -1094,4 +1072,5 @@
         {
             /* Seems async I/O is not supported by the backend, open in normal mode. */
+            pThis->fAsyncIOSupported = false;
             uOpenFlags &= ~VD_OPEN_FLAGS_ASYNC_IO;
             rc = VDOpen(pThis->pDisk, pszFormat, pszName, uOpenFlags, pImage->pVDIfsImage);
@@ -1149,42 +1128,4 @@
     else
     {
-        /*
-         * Check if every opened image supports async I/O.
-         * If not we revert to non async I/O.
-         */
-        if (pThis->fAsyncIOSupported)
-        {
-            for (unsigned i = 0; i < VDGetCount(pThis->pDisk); i++)
-            {
-                VDBACKENDINFO vdBackendInfo;
-
-                rc = VDBackendInfoSingle(pThis->pDisk, i, &vdBackendInfo);
-                AssertRC(rc);
-
-                if (vdBackendInfo.uBackendCaps & VD_CAP_ASYNC)
-                {
-                    /*
-                     * Backend indicates support for at least some files.
-                     * Check if current file is supported with async I/O)
-                     */
-                    rc = VDImageIsAsyncIOSupported(pThis->pDisk, i, &pThis->fAsyncIOSupported);
-                    AssertRC(rc);
-
-                    /*
-                     * Check if current image is supported.
-                     * If not we can stop checking because
-                     * at least one does not support it.
-                     */
-                    if (!pThis->fAsyncIOSupported)
-                        break;
-                }
-                else
-                {
-                    pThis->fAsyncIOSupported = false;
-                    break;
-                }
-            }
-        }
-
         /* Switch to runtime error facility. */
         pThis->fErrorUseRuntime = true;
Index: /trunk/src/VBox/Devices/Storage/ParallelsHDDCore.cpp
===================================================================
--- /trunk/src/VBox/Devices/Storage/ParallelsHDDCore.cpp	(revision 22965)
+++ /trunk/src/VBox/Devices/Storage/ParallelsHDDCore.cpp	(revision 22966)
@@ -70,9 +70,20 @@
     /** Error interface callbacks. */
     PVDINTERFACEERROR   pInterfaceErrorCallbacks;
+#ifdef VBOX_WITH_NEW_IO_CODE
+    /** Async I/O interface. */
+    PVDINTERFACE        pInterfaceAsyncIO;
+    /** Async I/O interface callbacks. */
+    PVDINTERFACEASYNCIO pInterfaceAsyncIOCallbacks;
+#endif
 
     /** Image file name. */
     const char         *pszFilename;
-    /** File handle. */
+#ifndef VBOX_WITH_NEW_IO_CODE
+    /** File descriptor. */
     RTFILE              File;
+#else
+    /** Opaque storage handle. */
+    void               *pvStorage;
+#endif
     /** Open flags passed by VBoxHD layer. */
     unsigned            uOpenFlags;
@@ -125,8 +136,151 @@
 }
 
+static int parallelsFileOpen(PPARALLELSIMAGE pImage, bool fReadonly, bool fCreate)
+{
+    int rc = VINF_SUCCESS;
+
+    AssertMsg(!(fReadonly && fCreate), ("Image can't be opened readonly while being created\n"));
+
+#ifndef VBOX_WITH_NEW_IO_CODE
+    unsigned uFileFlags = fReadonly ? RTFILE_O_READ      | RTFILE_O_DENY_NONE
+                                    : RTFILE_O_READWRITE | RTFILE_O_DENY_WRITE;
+
+    if (fCreate)
+        uFileFlags |= RTFILE_O_CREATE;
+    else
+        uFileFlags |= RTFILE_O_OPEN;
+
+    rc = RTFileOpen(&pImage->File, pImage->pszFilename, uFileFlags);
+#else
+
+    unsigned uOpenFlags = fReadonly ? VD_INTERFACEASYNCIO_OPEN_FLAGS_READONLY : 0;
+
+    if (fCreate)
+        uOpenFlags |= VD_INTERFACEASYNCIO_OPEN_FLAGS_CREATE;
+
+    rc = pImage->pInterfaceAsyncIOCallbacks->pfnOpen(pImage->pInterfaceAsyncIO->pvUser,
+                                                     pImage->pszFilename,
+                                                     uOpenFlags,
+                                                     NULL, &pImage->pvStorage);
+#endif
+
+    return rc;
+}
+
+static int parallelsFileClose(PPARALLELSIMAGE pImage)
+{
+    int rc = VINF_SUCCESS;
+
+#ifndef VBOX_WITH_NEW_IO_CODE
+    if (pImage->File != NIL_RTFILE)
+        rc = RTFileClose(pImage->File);
+
+    pImage->File = NIL_RTFILE;
+#else
+    if (pImage->pvStorage)
+        rc = pImage->pInterfaceAsyncIOCallbacks->pfnClose(pImage->pInterfaceAsyncIO->pvUser,
+                                                          pImage->pvStorage);
+
+    pImage->pvStorage = NULL;
+#endif
+
+    return rc;
+}
+
+static int parallelsFileFlushSync(PPARALLELSIMAGE pImage)
+{
+    int rc = VINF_SUCCESS;
+
+#ifndef VBOX_WITH_NEW_IO_CODE
+    rc = RTFileFlush(pImage->File);
+#else
+    if (pImage->pvStorage)
+        rc = pImage->pInterfaceAsyncIOCallbacks->pfnFlushSync(pImage->pInterfaceAsyncIO->pvUser,
+                                                              pImage->pvStorage);
+#endif
+
+    return rc;
+}
+
+static int parallelsFileGetSize(PPARALLELSIMAGE pImage, uint64_t *pcbSize)
+{
+    int rc = VINF_SUCCESS;
+
+#ifndef VBOX_WITH_NEW_IO_CODE
+    rc = RTFileGetSize(pImage->File, pcbSize);
+#else
+    if (pImage->pvStorage)
+        rc = pImage->pInterfaceAsyncIOCallbacks->pfnGetSize(pImage->pInterfaceAsyncIO->pvUser,
+                                                            pImage->pvStorage,
+                                                            pcbSize);
+#endif
+
+    return rc;
+
+}
+
+static int parallelsFileSetSize(PPARALLELSIMAGE pImage, uint64_t cbSize)
+{
+    int rc = VINF_SUCCESS;
+
+#ifndef VBOX_WITH_NEW_IO_CODE
+    rc = RTFileSetSize(pImage->File, cbSize);
+#else
+    if (pImage->pvStorage)
+        rc = pImage->pInterfaceAsyncIOCallbacks->pfnSetSize(pImage->pInterfaceAsyncIO->pvUser,
+                                                            pImage->pvStorage,
+                                                            cbSize);
+#endif
+
+    return rc;
+}
+
+
+static int parallelsFileWriteSync(PPARALLELSIMAGE pImage, uint64_t off, const void *pcvBuf, size_t cbWrite, size_t *pcbWritten)
+{
+    int rc = VINF_SUCCESS;
+
+#ifndef VBOX_WITH_NEW_IO_CODE
+    rc = RTFileWriteAt(pImage->File, off, pcvBuf, cbWrite, pcbWritten);
+#else
+    if (pImage->pvStorage)
+        rc = pImage->pInterfaceAsyncIOCallbacks->pfnWriteSync(pImage->pInterfaceAsyncIO->pvUser,
+                                                              pImage->pvStorage,
+                                                              off, cbWrite, pcvBuf,
+                                                              pcbWritten);
+#endif
+
+    return rc;
+}
+
+static int parallelsFileReadSync(PPARALLELSIMAGE pImage, uint64_t off, void *pvBuf, size_t cbRead, size_t *pcbRead)
+{
+    int rc = VINF_SUCCESS;
+
+#ifndef VBOX_WITH_NEW_IO_CODE
+    rc = RTFileReadAt(pImage->File, off, pvBuf, cbRead, pcbRead);
+#else
+    if (pImage->pvStorage)
+        rc = pImage->pInterfaceAsyncIOCallbacks->pfnReadSync(pImage->pInterfaceAsyncIO->pvUser,
+                                                             pImage->pvStorage,
+                                                             off, cbRead, pvBuf,
+                                                             pcbRead);
+#endif
+
+    return rc;
+}
+
+static bool parallelsFileOpened(PPARALLELSIMAGE pImage)
+{
+#ifndef VBOX_WITH_NEW_IO_CODE
+    return pImage->File != NIL_RTFILE;
+#else
+    return pImage->pvStorage != NULL;
+#endif
+}
+
 static int parallelsOpenImage(PPARALLELSIMAGE pImage, unsigned uOpenFlags)
 {
     int rc = VINF_SUCCESS;
-    RTFILE File;
     ParallelsHeader parallelsHeader;
 
@@ -136,19 +290,22 @@
         pImage->pInterfaceErrorCallbacks = VDGetInterfaceError(pImage->pInterfaceError);
 
-    rc = RTFileOpen(&File, pImage->pszFilename,
-                    uOpenFlags & VD_OPEN_FLAGS_READONLY
-                     ? RTFILE_O_READ      | RTFILE_O_OPEN | RTFILE_O_DENY_NONE
-                     : RTFILE_O_READWRITE | RTFILE_O_OPEN | RTFILE_O_DENY_WRITE);
+#ifdef VBOX_WITH_NEW_IO_CODE
+    /* Try to get async I/O interface. */
+    pImage->pInterfaceAsyncIO = VDInterfaceGet(pImage->pVDIfsDisk, VDINTERFACETYPE_ASYNCIO);
+    AssertPtr(pImage->pInterfaceAsyncIO);
+    pImage->pInterfaceAsyncIOCallbacks = VDGetInterfaceAsyncIO(pImage->pInterfaceAsyncIO);
+    AssertPtr(pImage->pInterfaceAsyncIOCallbacks);
+#endif
+
+    rc = parallelsFileOpen(pImage, !!(uOpenFlags & VD_OPEN_FLAGS_READONLY), false);
     if (RT_FAILURE(rc))
         goto out;
 
-    pImage->File = File;
-
-    rc = RTFileGetSize(pImage->File, &pImage->cbFileCurrent);
+    rc = parallelsFileGetSize(pImage, &pImage->cbFileCurrent);
     if (RT_FAILURE(rc))
         goto out;
     AssertMsg(pImage->cbFileCurrent % 512 == 0, ("File size is not a multiple of 512\n"));
 
-    rc = RTFileReadAt(File, 0, &parallelsHeader, sizeof(ParallelsHeader), NULL);
+    rc = parallelsFileReadSync(pImage, 0, &parallelsHeader, sizeof(parallelsHeader), NULL);
     if (RT_FAILURE(rc))
         goto out;
@@ -198,6 +355,8 @@
         }
 
-        rc = RTFileReadAt(File, sizeof(ParallelsHeader), pImage->pAllocationBitmap,
-                          pImage->cAllocationBitmapEntries * sizeof(uint32_t), NULL);
+        rc = parallelsFileReadSync(pImage, sizeof(ParallelsHeader),
+                                   pImage->pAllocationBitmap,
+                                   pImage->cAllocationBitmapEntries * sizeof(uint32_t),
+                                   NULL);
         if (RT_FAILURE(rc))
             goto out;
@@ -223,8 +382,8 @@
         pImage->fAllocationBitmapChanged = false;
         /* Write the allocation bitmap to the file. */
-        rc = RTFileWriteAt(pImage->File, sizeof(ParallelsHeader),
-                           pImage->pAllocationBitmap,
-                           pImage->cAllocationBitmapEntries * sizeof(uint32_t),
-                           NULL);
+        rc = parallelsFileWriteSync(pImage, sizeof(ParallelsHeader),
+                                    pImage->pAllocationBitmap,
+                                    pImage->cAllocationBitmapEntries * sizeof(uint32_t),
+                                    NULL);
         if (RT_FAILURE(rc))
             return rc;
@@ -232,5 +391,5 @@
 
     /* Flush file. */
-    rc = RTFileFlush(pImage->File);
+    rc = parallelsFileFlushSync(pImage);
 
     LogFlowFunc(("returns %Rrc\n", rc));
@@ -245,6 +404,6 @@
         RTMemFree(pImage->pAllocationBitmap);
 
-    if (pImage->File != NIL_RTFILE)
-        RTFileClose(pImage->File);
+    if (parallelsFileOpened(pImage))
+        parallelsFileClose(pImage);
 }
 
@@ -340,5 +499,9 @@
     }
 
+#ifndef VBOX_WITH_NEW_IO_CODE
     pImage->File = NIL_RTFILE;
+#else
+    pImage->pvStorage = NULL;
+#endif
     pImage->fAllocationBitmapChanged = false;
     pImage->pszFilename = pszFilename;
@@ -408,5 +571,6 @@
     if (pImage->uImageFlags & VD_IMAGE_FLAGS_FIXED)
     {
-        rc = RTFileReadAt(pImage->File, uOffset, pvBuf, cbToRead, NULL);
+        rc = parallelsFileReadSync(pImage, uOffset,
+                                   pvBuf, cbToRead, NULL);
     }
     else
@@ -427,5 +591,6 @@
         {
             uOffsetInFile = (pImage->pAllocationBitmap[iIndexInAllocationTable] + uSector) * 512;
-            rc = RTFileReadAt(pImage->File, uOffsetInFile, pvBuf, cbToRead, NULL);
+            rc = parallelsFileReadSync(pImage, uOffsetInFile,
+                                       pvBuf, cbToRead, NULL);
         }
     }
@@ -455,5 +620,6 @@
     if (pImage->uImageFlags & VD_IMAGE_FLAGS_FIXED)
     {
-        rc = RTFileWriteAt(pImage->File, uOffset, pvBuf, cbToWrite, NULL);
+        rc = parallelsFileWriteSync(pImage, uOffset,
+                                    pvBuf, cbToWrite, NULL);
     }
     else
@@ -474,11 +640,29 @@
             pImage->cbFileCurrent += pImage->PCHSGeometry.cSectors * 512;
             pImage->fAllocationBitmapChanged = true;
-            rc = RTFileSetSize(pImage->File, pImage->cbFileCurrent);
-            if (RT_FAILURE(rc))
-                return rc;
-        }
-
-        uOffsetInFile = (pImage->pAllocationBitmap[iIndexInAllocationTable] + uSector) * 512;
-        rc = RTFileWriteAt(pImage->File, uOffsetInFile, pvBuf, cbToWrite, NULL);
+
+            uint8_t *pNewBlock = (uint8_t *)RTMemAllocZ(pImage->PCHSGeometry.cSectors * 512);
+
+            if (!pNewBlock)
+                return VERR_NO_MEMORY;
+
+            uOffsetInFile = (uint64_t)pImage->pAllocationBitmap[iIndexInAllocationTable] * 512;
+            memcpy(pNewBlock + (uOffset - ((uint64_t)iIndexInAllocationTable * pImage->PCHSGeometry.cSectors * 512)),
+                   pvBuf, cbToWrite);
+
+            /*
+             * Write the new block at the current end of the file.
+             */
+            rc = parallelsFileWriteSync(pImage, uOffsetInFile,
+                                        pNewBlock,
+                                        pImage->PCHSGeometry.cSectors * 512, NULL);
+
+            RTMemFree(pNewBlock);
+        }
+        else
+        {
+            uOffsetInFile = (pImage->pAllocationBitmap[iIndexInAllocationTable] + uSector) * 512;
+            rc = parallelsFileWriteSync(pImage, uOffsetInFile,
+                                        pvBuf, cbToWrite, NULL);
+        }
     }
 
@@ -543,8 +727,6 @@
     if (pImage)
     {
-        if (pImage->File != NIL_RTFILE)
-        {
-            RTFileGetSize(pImage->File, &cb);
-        }
+        if (parallelsFileOpened(pImage))
+            cb = pImage->cbFileCurrent;
     }
 
Index: /trunk/src/VBox/Devices/Storage/RawHDDCore.cpp
===================================================================
--- /trunk/src/VBox/Devices/Storage/RawHDDCore.cpp	(revision 22965)
+++ /trunk/src/VBox/Devices/Storage/RawHDDCore.cpp	(revision 22966)
@@ -44,6 +44,11 @@
     /** Base image name. */
     const char      *pszFilename;
+#ifndef VBOX_WITH_NEW_IO_CODE
     /** File descriptor. */
     RTFILE          File;
+#else
+    /** Opaque storage handle. */
+    void           *pvStorage;
+#endif
 
     /** Pointer to the per-disk VD interface list. */
@@ -54,4 +59,10 @@
     /** Opaque data for error callback. */
     PVDINTERFACEERROR pInterfaceErrorCallbacks;
+#ifdef VBOX_WITH_NEW_IO_CODE
+    /** Async I/O interface. */
+    PVDINTERFACE        pInterfaceAsyncIO;
+    /** Async I/O interface callbacks. */
+    PVDINTERFACEASYNCIO pInterfaceAsyncIOCallbacks;
+#endif
 
     /** Open flags passed by VBoxHD layer. */
@@ -104,4 +115,148 @@
 }
 
+static int rawFileOpen(PRAWIMAGE pImage, bool fReadonly, bool fCreate)
+{
+    int rc = VINF_SUCCESS;
+
+    AssertMsg(!(fReadonly && fCreate), ("Image can't be opened readonly while being created\n"));
+
+#ifndef VBOX_WITH_NEW_IO_CODE
+    unsigned uFileFlags = fReadonly ? RTFILE_O_READ      | RTFILE_O_DENY_NONE
+                                    : RTFILE_O_READWRITE | RTFILE_O_DENY_WRITE;
+
+    if (fCreate)
+        uFileFlags |= RTFILE_O_CREATE;
+    else
+        uFileFlags |= RTFILE_O_OPEN;
+
+    rc = RTFileOpen(&pImage->File, pImage->pszFilename, uFileFlags);
+#else
+
+    unsigned uOpenFlags = fReadonly ? VD_INTERFACEASYNCIO_OPEN_FLAGS_READONLY : 0;
+
+    if (fCreate)
+        uOpenFlags |= VD_INTERFACEASYNCIO_OPEN_FLAGS_CREATE;
+
+    rc = pImage->pInterfaceAsyncIOCallbacks->pfnOpen(pImage->pInterfaceAsyncIO->pvUser,
+                                                     pImage->pszFilename,
+                                                     uOpenFlags,
+                                                     NULL, &pImage->pvStorage);
+#endif
+
+    return rc;
+}
+
+static int rawFileClose(PRAWIMAGE pImage)
+{
+    int rc = VINF_SUCCESS;
+
+#ifndef VBOX_WITH_NEW_IO_CODE
+    if (pImage->File != NIL_RTFILE)
+        rc = RTFileClose(pImage->File);
+
+    pImage->File = NIL_RTFILE;
+#else
+    if (pImage->pvStorage)
+        rc = pImage->pInterfaceAsyncIOCallbacks->pfnClose(pImage->pInterfaceAsyncIO->pvUser,
+                                                          pImage->pvStorage);
+
+    pImage->pvStorage = NULL;
+#endif
+
+    return rc;
+}
+
+static int rawFileFlushSync(PRAWIMAGE pImage)
+{
+    int rc = VINF_SUCCESS;
+
+#ifndef VBOX_WITH_NEW_IO_CODE
+    rc = RTFileFlush(pImage->File);
+#else
+    if (pImage->pvStorage)
+        rc = pImage->pInterfaceAsyncIOCallbacks->pfnFlushSync(pImage->pInterfaceAsyncIO->pvUser,
+                                                              pImage->pvStorage);
+#endif
+
+    return rc;
+}
+
+static int rawFileGetSize(PRAWIMAGE pImage, uint64_t *pcbSize)
+{
+    int rc = VINF_SUCCESS;
+
+#ifndef VBOX_WITH_NEW_IO_CODE
+    rc = RTFileGetSize(pImage->File, pcbSize);
+#else
+    if (pImage->pvStorage)
+        rc = pImage->pInterfaceAsyncIOCallbacks->pfnGetSize(pImage->pInterfaceAsyncIO->pvUser,
+                                                            pImage->pvStorage,
+                                                            pcbSize);
+#endif
+
+    return rc;
+
+}
+
+static int rawFileSetSize(PRAWIMAGE pImage, uint64_t cbSize)
+{
+    int rc = VINF_SUCCESS;
+
+#ifndef VBOX_WITH_NEW_IO_CODE
+    rc = RTFileSetSize(pImage->File, cbSize);
+#else
+    if (pImage->pvStorage)
+        rc = pImage->pInterfaceAsyncIOCallbacks->pfnSetSize(pImage->pInterfaceAsyncIO->pvUser,
+                                                            pImage->pvStorage,
+                                                            cbSize);
+#endif
+
+    return rc;
+}
+
+
+static int rawFileWriteSync(PRAWIMAGE pImage, uint64_t off, const void *pcvBuf, size_t cbWrite, size_t *pcbWritten)
+{
+    int rc = VINF_SUCCESS;
+
+#ifndef VBOX_WITH_NEW_IO_CODE
+    rc = RTFileWriteAt(pImage->File, off, pcvBuf, cbWrite, pcbWritten);
+#else
+    if (pImage->pvStorage)
+        rc = pImage->pInterfaceAsyncIOCallbacks->pfnWriteSync(pImage->pInterfaceAsyncIO->pvUser,
+                                                              pImage->pvStorage,
+                                                              off, cbWrite, pcvBuf,
+                                                              pcbWritten);
+#endif
+
+    return rc;
+}
+
+static int rawFileReadSync(PRAWIMAGE pImage, uint64_t off, void *pvBuf, size_t cbRead, size_t *pcbRead)
+{
+    int rc = VINF_SUCCESS;
+
+#ifndef VBOX_WITH_NEW_IO_CODE
+    rc = RTFileReadAt(pImage->File, off, pvBuf, cbRead, pcbRead);
+#else
+    if (pImage->pvStorage)
+        rc = pImage->pInterfaceAsyncIOCallbacks->pfnReadSync(pImage->pInterfaceAsyncIO->pvUser,
+                                                             pImage->pvStorage,
+                                                             off, cbRead, pvBuf,
+                                                             pcbRead);
+#endif
+
+    return rc;
+}
+
+static bool rawFileOpened(PRAWIMAGE pImage)
+{
+#ifndef VBOX_WITH_NEW_IO_CODE
+    return pImage->File != NIL_RTFILE;
+#else
+    return pImage->pvStorage != NULL;
+#endif
+}
+
 /**
  * Internal: Open an image, constructing all necessary data structures.
@@ -110,5 +265,4 @@
 {
     int rc;
-    RTFILE File;
 
     if (uOpenFlags & VD_OPEN_FLAGS_ASYNC_IO)
@@ -121,11 +275,16 @@
         pImage->pInterfaceErrorCallbacks = VDGetInterfaceError(pImage->pInterfaceError);
 
+#ifdef VBOX_WITH_NEW_IO_CODE
+    /* Try to get async I/O interface. */
+    pImage->pInterfaceAsyncIO = VDInterfaceGet(pImage->pVDIfsDisk, VDINTERFACETYPE_ASYNCIO);
+    AssertPtr(pImage->pInterfaceAsyncIO);
+    pImage->pInterfaceAsyncIOCallbacks = VDGetInterfaceAsyncIO(pImage->pInterfaceAsyncIO);
+    AssertPtr(pImage->pInterfaceAsyncIOCallbacks);
+#endif
+
     /*
      * Open the image.
      */
-    rc = RTFileOpen(&File, pImage->pszFilename,
-                    uOpenFlags & VD_OPEN_FLAGS_READONLY
-                     ? RTFILE_O_READ      | RTFILE_O_OPEN | RTFILE_O_DENY_NONE
-                     : RTFILE_O_READWRITE | RTFILE_O_OPEN | RTFILE_O_DENY_WRITE);
+    rc = rawFileOpen(pImage, !!(uOpenFlags & VD_OPEN_FLAGS_READONLY), false);
     if (RT_FAILURE(rc))
     {
@@ -134,7 +293,6 @@
         goto out;
     }
-    pImage->File = File;
-
-    rc = RTFileGetSize(pImage->File, &pImage->cbSize);
+
+    rc = rawFileGetSize(pImage, &pImage->cbSize);
     if (RT_FAILURE(rc))
         goto out;
@@ -163,5 +321,4 @@
 {
     int rc;
-    RTFILE File;
     RTFOFF cbFree = 0;
     uint64_t uOff;
@@ -184,7 +341,14 @@
         pImage->pInterfaceErrorCallbacks = VDGetInterfaceError(pImage->pInterfaceError);
 
+#ifdef VBOX_WITH_NEW_IO_CODE
+    /* Try to get async I/O interface. */
+    pImage->pInterfaceAsyncIO = VDInterfaceGet(pImage->pVDIfsDisk, VDINTERFACETYPE_ASYNCIO);
+    AssertPtr(pImage->pInterfaceAsyncIO);
+    pImage->pInterfaceAsyncIOCallbacks = VDGetInterfaceAsyncIO(pImage->pInterfaceAsyncIO);
+    AssertPtr(pImage->pInterfaceAsyncIOCallbacks);
+#endif
+
     /* Create image file. */
-    rc = RTFileOpen(&File, pImage->pszFilename,
-                    RTFILE_O_READWRITE | RTFILE_O_CREATE | RTFILE_O_DENY_ALL);
+    rc = rawFileOpen(pImage, false, true);
     if (RT_FAILURE(rc))
     {
@@ -192,5 +356,4 @@
         goto out;
     }
-    pImage->File = File;
 
     /* Check the free space on the disk and leave early if there is not
@@ -205,5 +368,5 @@
     /* Allocate & commit whole file if fixed image, it must be more
      * effective than expanding file by write operations. */
-    rc = RTFileSetSize(File, cbSize);
+    rc = rawFileSetSize(pImage, cbSize);
     if (RT_FAILURE(rc))
     {
@@ -229,5 +392,5 @@
         unsigned cbChunk = (unsigned)RT_MIN(cbSize, cbBuf);
 
-        rc = RTFileWriteAt(File, uOff, pvBuf, cbChunk, NULL);
+        rc = rawFileWriteSync(pImage, uOff, pvBuf, cbChunk, NULL);
         if (RT_FAILURE(rc))
         {
@@ -275,10 +438,9 @@
     Assert(pImage);
 
-    if (pImage->File != NIL_RTFILE)
+    if (rawFileOpened(pImage))
     {
         if (!(pImage->uOpenFlags & VD_OPEN_FLAGS_READONLY))
             rawFlushImage(pImage);
-        RTFileClose(pImage->File);
-        pImage->File = NIL_RTFILE;
+        rawFileClose(pImage);
     }
     if (fDelete && pImage->pszFilename)
@@ -293,7 +455,7 @@
     int rc = VINF_SUCCESS;
 
-    if (   pImage->File != NIL_RTFILE
+    if (   rawFileOpened(pImage)
         && !(pImage->uOpenFlags & VD_OPEN_FLAGS_READONLY))
-        rc = RTFileFlush(pImage->File);
+        rc = rawFileFlushSync(pImage);
 
     return rc;
@@ -354,5 +516,9 @@
     }
     pImage->pszFilename = pszFilename;
+#ifndef VBOX_WITH_NEW_IO_CODE
     pImage->File = NIL_RTFILE;
+#else
+    pImage->pvStorage = NULL;
+#endif
     pImage->pVDIfsDisk = pVDIfsDisk;
 
@@ -417,5 +583,9 @@
     }
     pImage->pszFilename = pszFilename;
+#ifndef VBOX_WITH_NEW_IO_CODE
     pImage->File = NIL_RTFILE;
+#else
+    pImage->pvStorage = NULL;
+#endif
     pImage->pVDIfsDisk = pVDIfsDisk;
 
@@ -487,5 +657,5 @@
     }
 
-    rc = RTFileReadAt(pImage->File, uOffset, pvBuf, cbToRead, NULL);
+    rc = rawFileReadSync(pImage, uOffset, pvBuf, cbToRead, NULL);
     *pcbActuallyRead = cbToRead;
 
@@ -521,5 +691,5 @@
     }
 
-    rc = RTFileWriteAt(pImage->File, uOffset, pvBuf, cbToWrite, NULL);
+    rc = rawFileWriteSync(pImage, uOffset, pvBuf, cbToWrite, NULL);
     if (pcbWriteProcess)
         *pcbWriteProcess = cbToWrite;
@@ -582,7 +752,7 @@
     {
         uint64_t cbFile;
-        if (pImage->File != NIL_RTFILE)
+        if (rawFileOpened(pImage))
         {
-            int rc = RTFileGetSize(pImage->File, &cbFile);
+            int rc = rawFileGetSize(pImage, &cbFile);
             if (RT_SUCCESS(rc))
                 cb += cbFile;
Index: /trunk/src/VBox/Devices/Storage/VBoxHDD.cpp
===================================================================
--- /trunk/src/VBox/Devices/Storage/VBoxHDD.cpp	(revision 22965)
+++ /trunk/src/VBox/Devices/Storage/VBoxHDD.cpp	(revision 22966)
@@ -47,4 +47,17 @@
 /** Buffer size used for merging images. */
 #define VD_MERGE_BUFFER_SIZE    (16 * _1M)
+
+/**
+ * VD async I/O interface storage descriptor.
+ */
+typedef struct VDIASYNCIOSTORAGE
+{
+    /** File handle. */
+    RTFILE         File;
+    /** Completion callback. */
+    PFNVDCOMPLETED pfnCompleted;
+    /** Thread for async access. */
+    RTTHREAD       ThreadAsync;
+} VDIASYNCIOSTORAGE, *PVDIASYNCIOSTORAGE;
 
 /**
@@ -116,4 +129,9 @@
     /** Pointer to the error interface we use if available. */
     PVDINTERFACEERROR   pInterfaceErrorCallbacks;
+
+    /** Fallback async interface. */
+    VDINTERFACE         VDIAsyncIO;
+    /** Fallback async I/O interface callback table. */
+    VDINTERFACEASYNCIO  VDIAsyncIOCallbacks;
 };
 
@@ -708,4 +726,136 @@
 
 /**
+ * VD async I/O interface open callback.
+ */
+static int vdAsyncIOOpen(void *pvUser, const char *pszLocation, unsigned uOpenFlags,
+                         PFNVDCOMPLETED pfnCompleted, void **ppStorage)
+{
+    PVDIASYNCIOSTORAGE pStorage = (PVDIASYNCIOSTORAGE)RTMemAllocZ(sizeof(VDIASYNCIOSTORAGE));
+
+    if (!pStorage)
+        return VERR_NO_MEMORY;
+
+    pStorage->pfnCompleted = pfnCompleted;
+
+    unsigned uFlags = 0;
+
+    if (uOpenFlags & VD_INTERFACEASYNCIO_OPEN_FLAGS_READONLY)
+        uFlags |= RTFILE_O_READ | RTFILE_O_DENY_NONE;
+    else
+        uFlags |= RTFILE_O_READWRITE | RTFILE_O_DENY_WRITE;
+
+    if (uOpenFlags & VD_INTERFACEASYNCIO_OPEN_FLAGS_CREATE)
+        uFlags |= RTFILE_O_CREATE;
+    else
+        uFlags |= RTFILE_O_OPEN;
+
+    /* Open the file. */
+    int rc = RTFileOpen(&pStorage->File, pszLocation, uFlags);
+    if (RT_SUCCESS(rc))
+    {
+        *ppStorage = pStorage;
+        return VINF_SUCCESS;
+    }
+
+    RTMemFree(pStorage);
+    return rc;
+}
+
+/**
+ * VD async I/O interface close callback.
+ */
+static int vdAsyncIOClose(void *pvUser, void *pvStorage)
+{
+    PVDIASYNCIOSTORAGE pStorage = (PVDIASYNCIOSTORAGE)pvStorage;
+
+    RTFileClose(pStorage->File);
+    RTMemFree(pStorage);
+    return VINF_SUCCESS;
+}
+
+/**
+ * VD async I/O interface callback for retrieving the file size.
+ */
+static int vdAsyncIOGetSize(void *pvUser, void *pvStorage, uint64_t *pcbSize)
+{
+    PVDIASYNCIOSTORAGE pStorage = (PVDIASYNCIOSTORAGE)pvStorage;
+
+    return RTFileGetSize(pStorage->File, pcbSize);
+}
+
+/**
+ * VD async I/O interface callback for setting the file size.
+ */
+static int vdAsyncIOSetSize(void *pvUser, void *pvStorage, uint64_t cbSize)
+{
+    PVDIASYNCIOSTORAGE pStorage = (PVDIASYNCIOSTORAGE)pvStorage;
+
+    return RTFileSetSize(pStorage->File, cbSize);
+}
+
+/**
+ * VD async I/O interface callback for a synchronous write to the file.
+ */
+static int vdAsyncIOWriteSync(void *pvUser, void *pvStorage, uint64_t uOffset,
+                             size_t cbWrite, const void *pvBuf, size_t *pcbWritten)
+{
+    PVDIASYNCIOSTORAGE pStorage = (PVDIASYNCIOSTORAGE)pvStorage;
+
+    return RTFileWriteAt(pStorage->File, uOffset, pvBuf, cbWrite, pcbWritten);
+}
+
+/**
+ * VD async I/O interface callback for a synchronous read from the file.
+ */
+static int vdAsyncIOReadSync(void *pvUser, void *pvStorage, uint64_t uOffset,
+                             size_t cbRead, void *pvBuf, size_t *pcbRead)
+{
+    PVDIASYNCIOSTORAGE pStorage = (PVDIASYNCIOSTORAGE)pvStorage;
+
+    return RTFileReadAt(pStorage->File, uOffset, pvBuf, cbRead, pcbRead);
+}
+
+/**
+ * VD async I/O interface callback for a synchronous flush of the file data.
+ */
+static int vdAsyncIOFlushSync(void *pvUser, void *pvStorage)
+{
+    PVDIASYNCIOSTORAGE pStorage = (PVDIASYNCIOSTORAGE)pvStorage;
+
+    return RTFileFlush(pStorage->File);
+}
+
+/**
+ * VD async I/O interface callback for a asynchronous read from the file.
+ */
+static int vdAsyncIOReadAsync(void *pvUser, void *pStorage, uint64_t uOffset,
+                              PCPDMDATASEG paSegments, size_t cSegments,
+                              size_t cbRead, void *pvCompletion,
+                              void **ppTask)
+{
+    return VERR_NOT_IMPLEMENTED;
+}
+
+/**
+ * VD async I/O interface callback for a asynchronous write to the file.
+ */
+static int vdAsyncIOWriteAsync(void *pvUser, void *pStorage, uint64_t uOffset,
+                               PCPDMDATASEG paSegments, size_t cSegments,
+                               size_t cbWrite, void *pvCompletion,
+                               void **ppTask)
+{
+    return VERR_NOT_IMPLEMENTED;
+}
+
+/**
+ * VD async I/O interface callback for a asynchronous flush of the file data.
+ */
+static int vdAsyncIOFlushAsync(void *pvUser, void *pStorage,
+                               void *pvCompletion, void **ppTask)
+{
+    return VERR_NOT_IMPLEMENTED;
+}
+
+/**
  * internal: send output to the log (unconditionally).
  */
@@ -894,4 +1044,26 @@
             if (pDisk->pInterfaceError)
                 pDisk->pInterfaceErrorCallbacks = VDGetInterfaceError(pDisk->pInterfaceError);
+
+            /* Use the fallback async I/O interface if the caller doesn't provide one. */
+            PVDINTERFACE pVDIfAsyncIO = VDInterfaceGet(pVDIfsDisk, VDINTERFACETYPE_ASYNCIO);
+            if (!pVDIfAsyncIO)
+            {
+                pDisk->VDIAsyncIOCallbacks.cbSize        = sizeof(VDINTERFACEASYNCIO);
+                pDisk->VDIAsyncIOCallbacks.enmInterface  = VDINTERFACETYPE_ASYNCIO;
+                pDisk->VDIAsyncIOCallbacks.pfnOpen       = vdAsyncIOOpen;
+                pDisk->VDIAsyncIOCallbacks.pfnClose      = vdAsyncIOClose;
+                pDisk->VDIAsyncIOCallbacks.pfnGetSize    = vdAsyncIOGetSize;
+                pDisk->VDIAsyncIOCallbacks.pfnSetSize    = vdAsyncIOSetSize;
+                pDisk->VDIAsyncIOCallbacks.pfnReadSync   = vdAsyncIOReadSync;
+                pDisk->VDIAsyncIOCallbacks.pfnWriteSync  = vdAsyncIOWriteSync;
+                pDisk->VDIAsyncIOCallbacks.pfnFlushSync  = vdAsyncIOFlushSync;
+                pDisk->VDIAsyncIOCallbacks.pfnReadAsync  = vdAsyncIOReadAsync;
+                pDisk->VDIAsyncIOCallbacks.pfnWriteAsync = vdAsyncIOWriteAsync;
+                pDisk->VDIAsyncIOCallbacks.pfnFlushAsync = vdAsyncIOFlushAsync;
+                rc = VDInterfaceAdd(&pDisk->VDIAsyncIO, "VD_AsyncIO", VDINTERFACETYPE_ASYNCIO,
+                                    &pDisk->VDIAsyncIOCallbacks, pDisk, &pDisk->pVDIfsDisk);
+                AssertRC(rc);
+            }
+
             *ppDisk = pDisk;
         }
Index: /trunk/src/VBox/Devices/Storage/VDICore.h
===================================================================
--- /trunk/src/VBox/Devices/Storage/VDICore.h	(revision 22965)
+++ /trunk/src/VBox/Devices/Storage/VDICore.h	(revision 22966)
@@ -528,6 +528,11 @@
     struct VDIIMAGEDESC    *pNext;
 #endif /* !VBOX_VDICORE_VD */
+#ifndef VBOX_WITH_NEW_IO_CODE
     /** File handle. */
     RTFILE                  File;
+#else
+    /** Opaque storage handle. */
+    void                   *pvStorage;
+#endif
 #ifndef VBOX_VDICORE_VD
     /** True if the image is operating in readonly mode. */
@@ -585,4 +590,10 @@
     /** Error interface callback table. */
     PVDINTERFACEERROR       pInterfaceErrorCallbacks;
+# ifdef VBOX_WITH_NEW_IO_CODE
+    /** Async I/O interface. */
+    PVDINTERFACE        pInterfaceAsyncIO;
+    /** Async I/O interface callbacks. */
+    PVDINTERFACEASYNCIO pInterfaceAsyncIOCallbacks;
+# endif
 #endif /* VBOX_VDICORE_VD */
 } VDIIMAGEDESC, *PVDIIMAGEDESC;
Index: /trunk/src/VBox/Devices/Storage/VDIHDDCore.cpp
===================================================================
--- /trunk/src/VBox/Devices/Storage/VDIHDDCore.cpp	(revision 22965)
+++ /trunk/src/VBox/Devices/Storage/VDIHDDCore.cpp	(revision 22966)
@@ -82,4 +82,147 @@
 
 
+static int vdiFileOpen(PVDIIMAGEDESC pImage, bool fReadonly, bool fCreate)
+{
+    int rc = VINF_SUCCESS;
+
+    AssertMsg(!(fReadonly && fCreate), ("Image can't be opened readonly whilebeing created\n"));
+
+#ifndef VBOX_WITH_NEW_IO_CODE
+    unsigned uFileFlags = fReadonly ? RTFILE_O_READ      | RTFILE_O_DENY_NONE
+                                    : RTFILE_O_READWRITE | RTFILE_O_DENY_WRITE;
+
+    if (fCreate)
+        uFileFlags |= RTFILE_O_CREATE;
+    else
+        uFileFlags |= RTFILE_O_OPEN;
+
+    rc = RTFileOpen(&pImage->File, pImage->pszFilename, uFileFlags);
+#else
+
+    unsigned uOpenFlags = fReadonly ? VD_INTERFACEASYNCIO_OPEN_FLAGS_READONLY : 0;
+
+    if (fCreate)
+        uOpenFlags |= VD_INTERFACEASYNCIO_OPEN_FLAGS_CREATE;
+
+    rc = pImage->pInterfaceAsyncIOCallbacks->pfnOpen(pImage->pInterfaceAsyncIO->pvUser,
+                                                     pImage->pszFilename,
+                                                     uOpenFlags,
+                                                     NULL, &pImage->pvStorage);
+#endif
+
+    return rc;
+}
+
+static int vdiFileClose(PVDIIMAGEDESC pImage)
+{
+    int rc = VINF_SUCCESS;
+
+#ifndef VBOX_WITH_NEW_IO_CODE
+    if (pImage->File != NIL_RTFILE)
+        rc = RTFileClose(pImage->File);
+
+    pImage->File = NIL_RTFILE;
+#else
+    if (pImage->pvStorage)
+        rc = pImage->pInterfaceAsyncIOCallbacks->pfnClose(pImage->pInterfaceAsyncIO->pvUser,
+                                                          pImage->pvStorage);
+
+    pImage->pvStorage = NULL;
+#endif
+
+    return rc;
+}
+
+static int vdiFileFlushSync(PVDIIMAGEDESC pImage)
+{
+    int rc = VINF_SUCCESS;
+
+#ifndef VBOX_WITH_NEW_IO_CODE
+    rc = RTFileFlush(pImage->File);
+#else
+    if (pImage->pvStorage)
+        rc = pImage->pInterfaceAsyncIOCallbacks->pfnFlushSync(pImage->pInterfaceAsyncIO->pvUser,
+                                                              pImage->pvStorage);
+#endif
+
+    return rc;
+}
+
+static int vdiFileGetSize(PVDIIMAGEDESC pImage, uint64_t *pcbSize)
+{
+    int rc = VINF_SUCCESS;
+
+#ifndef VBOX_WITH_NEW_IO_CODE
+    rc = RTFileGetSize(pImage->File, pcbSize);
+#else
+    if (pImage->pvStorage)
+        rc = pImage->pInterfaceAsyncIOCallbacks->pfnGetSize(pImage->pInterfaceAsyncIO->pvUser,
+                                                            pImage->pvStorage,
+                                                            pcbSize);
+#endif
+
+    return rc;
+}
+
+static int vdiFileSetSize(PVDIIMAGEDESC pImage, uint64_t cbSize)
+{
+    int rc = VINF_SUCCESS;
+
+#ifndef VBOX_WITH_NEW_IO_CODE
+    rc = RTFileSetSize(pImage->File, cbSize);
+#else
+    if (pImage->pvStorage)
+        rc = pImage->pInterfaceAsyncIOCallbacks->pfnSetSize(pImage->pInterfaceAsyncIO->pvUser,
+                                                            pImage->pvStorage,
+                                                            cbSize);
+#endif
+
+    return rc;
+}
+
+static int vdiFileWriteSync(PVDIIMAGEDESC pImage, uint64_t off, const void *pcvBuf, size_t cbWrite, size_t *pcbWritten)
+{
+    int rc = VINF_SUCCESS;
+
+#ifndef VBOX_WITH_NEW_IO_CODE
+    rc = RTFileWriteAt(pImage->File, off, pcvBuf, cbWrite, pcbWritten);
+#else
+    if (pImage->pvStorage)
+        rc = pImage->pInterfaceAsyncIOCallbacks->pfnWriteSync(pImage->pInterfaceAsyncIO->pvUser,
+                                                              pImage->pvStorage,
+                                                              off, cbWrite, pcvBuf,
+                                                              pcbWritten);
+#endif
+
+    return rc;
+}
+
+static int vdiFileReadSync(PVDIIMAGEDESC pImage, uint64_t off, void *pvBuf, size_t cbRead, size_t *pcbRead)
+{
+    int rc = VINF_SUCCESS;
+
+#ifndef VBOX_WITH_NEW_IO_CODE
+    rc = RTFileReadAt(pImage->File, off, pvBuf, cbRead, pcbRead);
+#else
+    if (pImage->pvStorage)
+        rc = pImage->pInterfaceAsyncIOCallbacks->pfnReadSync(pImage->pInterfaceAsyncIO->pvUser,
+                                                             pImage->pvStorage,
+                                                             off, cbRead, pvBuf,
+                                                             pcbRead);
+#endif
+
+    return rc;
+}
+
+static bool vdiFileOpened(PVDIIMAGEDESC pImage)
+{
+#ifndef VBOX_WITH_NEW_IO_CODE
+    return pImage->File != NIL_RTFILE;
+#else
+    return pImage->pvStorage != NULL;
+#endif
+}
+
+
 /**
  * internal: return power of 2 or 0 if num error.
@@ -415,6 +558,5 @@
 
     /* Create image file. */
-    rc = RTFileOpen(&File, pImage->pszFilename,
-                    RTFILE_O_READWRITE | RTFILE_O_CREATE | RTFILE_O_DENY_ALL);
+    rc = vdiFileOpen(pImage, false /* fReadonly */, true /* fCreate */);
     if (RT_FAILURE(rc))
     {
@@ -422,5 +564,4 @@
         goto out;
     }
-    pImage->File = File;
 
     cbTotal =   pImage->offStartData
@@ -446,10 +587,10 @@
          * effective than expanding file by write operations.
          */
-        rc = RTFileSetSize(File, cbTotal);
+        rc = vdiFileSetSize(pImage, cbTotal);
     }
     else
     {
         /* Set file size to hold header and blocks array. */
-        rc = RTFileSetSize(pImage->File, pImage->offStartData);
+        rc = vdiFileSetSize(pImage, pImage->offStartData);
     }
     if (RT_FAILURE(rc))
@@ -466,5 +607,5 @@
 
     /* Write pre-header. */
-    rc = RTFileWriteAt(File, 0, &pImage->PreHeader, sizeof(pImage->PreHeader), NULL);
+    rc = vdiFileWriteSync(pImage, 0, &pImage->PreHeader, sizeof(pImage->PreHeader), NULL);
     if (RT_FAILURE(rc))
     {
@@ -474,5 +615,5 @@
 
     /* Write header. */
-    rc = RTFileWriteAt(File, sizeof(pImage->PreHeader), &pImage->Header.u.v1plus, sizeof(pImage->Header.u.v1plus), NULL);
+    rc = vdiFileWriteSync(pImage, sizeof(pImage->PreHeader), &pImage->Header.u.v1plus, sizeof(pImage->Header.u.v1plus), NULL);
     if (RT_FAILURE(rc))
     {
@@ -481,8 +622,8 @@
     }
 
-    rc = RTFileWriteAt(File, pImage->offStartBlocks,
-                       pImage->paBlocks,
-                       getImageBlocks(&pImage->Header) * sizeof(VDIIMAGEBLOCKPOINTER),
-                       NULL);
+    rc = vdiFileWriteSync(pImage, pImage->offStartBlocks,
+                          pImage->paBlocks,
+                          getImageBlocks(&pImage->Header) * sizeof(VDIIMAGEBLOCKPOINTER),
+                          NULL);
     if (RT_FAILURE(rc))
     {
@@ -516,6 +657,6 @@
             unsigned cbChunk = (unsigned)RT_MIN(cbFill, cbBuf);
 
-            rc = RTFileWriteAt(File, pImage->offStartData + uOff,
-                               pvBuf, cbChunk, NULL);
+            rc = vdiFileWriteSync(pImage, pImage->offStartData + uOff,
+                                  pvBuf, cbChunk, NULL);
             if (RT_FAILURE(rc))
             {
@@ -554,5 +695,4 @@
 {
     int rc;
-    RTFILE File;
 
     if (uOpenFlags & VD_OPEN_FLAGS_ASYNC_IO)
@@ -565,11 +705,16 @@
         pImage->pInterfaceErrorCallbacks = VDGetInterfaceError(pImage->pInterfaceError);
 
+#ifdef VBOX_WITH_NEW_IO_CODE
+    /* Try to get async I/O interface. */
+    pImage->pInterfaceAsyncIO = VDInterfaceGet(pImage->pVDIfsDisk, VDINTERFACETYPE_ASYNCIO);
+    AssertPtr(pImage->pInterfaceAsyncIO);
+    pImage->pInterfaceAsyncIOCallbacks = VDGetInterfaceAsyncIO(pImage->pInterfaceAsyncIO);
+    AssertPtr(pImage->pInterfaceAsyncIOCallbacks);
+#endif
+
     /*
      * Open the image.
      */
-    rc = RTFileOpen(&File, pImage->pszFilename,
-                    uOpenFlags & VD_OPEN_FLAGS_READONLY
-                     ? RTFILE_O_READ      | RTFILE_O_OPEN | RTFILE_O_DENY_NONE
-                     : RTFILE_O_READWRITE | RTFILE_O_OPEN | RTFILE_O_DENY_NONE);
+    rc = vdiFileOpen(pImage, !!(uOpenFlags & VD_OPEN_FLAGS_READONLY), false /* fCreate */);
     if (RT_FAILURE(rc))
     {
@@ -578,9 +723,8 @@
         goto out;
     }
-    pImage->File = File;
 
     /* Read pre-header. */
-    rc = RTFileReadAt(File, 0, &pImage->PreHeader, sizeof(pImage->PreHeader),
-                      NULL);
+    rc = vdiFileReadSync(pImage, 0, &pImage->PreHeader, sizeof(pImage->PreHeader),
+                         NULL);
     if (RT_FAILURE(rc))
     {
@@ -600,7 +744,7 @@
     {
         case 0:
-            rc = RTFileReadAt(File, sizeof(pImage->PreHeader),
-                              &pImage->Header.u.v0, sizeof(pImage->Header.u.v0),
-                              NULL);
+            rc = vdiFileReadSync(pImage, sizeof(pImage->PreHeader),
+                                 &pImage->Header.u.v0, sizeof(pImage->Header.u.v0),
+                                 NULL);
             if (RT_FAILURE(rc))
             {
@@ -610,7 +754,7 @@
             break;
         case 1:
-            rc = RTFileReadAt(File, sizeof(pImage->PreHeader),
-                              &pImage->Header.u.v1, sizeof(pImage->Header.u.v1),
-                              NULL);
+            rc = vdiFileReadSync(pImage, sizeof(pImage->PreHeader),
+                                 &pImage->Header.u.v1, sizeof(pImage->Header.u.v1),
+                                 NULL);
             if (RT_FAILURE(rc))
             {
@@ -635,5 +779,5 @@
             {
                 /* Read the actual VDI 1.1+ header completely. */
-                rc = RTFileReadAt(File, sizeof(pImage->PreHeader), &pImage->Header.u.v1plus, sizeof(pImage->Header.u.v1plus), NULL);
+                rc = vdiFileReadSync(pImage, sizeof(pImage->PreHeader), &pImage->Header.u.v1plus, sizeof(pImage->Header.u.v1plus), NULL);
                 if (RT_FAILURE(rc))
                 {
@@ -667,7 +811,7 @@
 
     /* Read blocks array. */
-    rc = RTFileReadAt(pImage->File, pImage->offStartBlocks, pImage->paBlocks,
-                      getImageBlocks(&pImage->Header) * sizeof(VDIIMAGEBLOCKPOINTER),
-                      NULL);
+    rc = vdiFileReadSync(pImage, pImage->offStartBlocks, pImage->paBlocks,
+                         getImageBlocks(&pImage->Header) * sizeof(VDIIMAGEBLOCKPOINTER),
+                         NULL);
 
 out:
@@ -686,11 +830,11 @@
     {
         case 0:
-            rc = RTFileWriteAt(pImage->File, sizeof(VDIPREHEADER), &pImage->Header.u.v0, sizeof(pImage->Header.u.v0), NULL);
+            rc = vdiFileWriteSync(pImage, sizeof(VDIPREHEADER), &pImage->Header.u.v0, sizeof(pImage->Header.u.v0), NULL);
             break;
         case 1:
             if (pImage->Header.u.v1plus.cbHeader < sizeof(pImage->Header.u.v1plus))
-                rc = RTFileWriteAt(pImage->File, sizeof(VDIPREHEADER), &pImage->Header.u.v1, sizeof(pImage->Header.u.v1), NULL);
+                rc = vdiFileWriteSync(pImage, sizeof(VDIPREHEADER), &pImage->Header.u.v1, sizeof(pImage->Header.u.v1), NULL);
             else
-                rc = RTFileWriteAt(pImage->File, sizeof(VDIPREHEADER), &pImage->Header.u.v1plus, sizeof(pImage->Header.u.v1plus), NULL);
+                rc = vdiFileWriteSync(pImage, sizeof(VDIPREHEADER), &pImage->Header.u.v1plus, sizeof(pImage->Header.u.v1plus), NULL);
             break;
         default:
@@ -712,9 +856,9 @@
     {
         /* write only one block pointer. */
-        rc = RTFileWriteAt(pImage->File,
-                           pImage->offStartBlocks + uBlock * sizeof(VDIIMAGEBLOCKPOINTER),
-                           &pImage->paBlocks[uBlock],
-                           sizeof(VDIIMAGEBLOCKPOINTER),
-                           NULL);
+        rc = vdiFileWriteSync(pImage,
+                              pImage->offStartBlocks + uBlock * sizeof(VDIIMAGEBLOCKPOINTER),
+                              &pImage->paBlocks[uBlock],
+                              sizeof(VDIIMAGEBLOCKPOINTER),
+                              NULL);
         AssertMsgRC(rc, ("vdiUpdateBlockInfo failed to update block=%u, filename=\"%s\", rc=%Rrc\n",
                          uBlock, pImage->pszFilename, rc));
@@ -734,5 +878,5 @@
         AssertMsgRC(rc, ("vdiUpdateHeader() failed, filename=\"%s\", rc=%Rrc\n",
                          pImage->pszFilename, rc));
-        RTFileFlush(pImage->File);
+        vdiFileFlushSync(pImage);
     }
 }
@@ -746,9 +890,8 @@
     AssertPtr(pImage);
 
-    if (pImage->File != NIL_RTFILE)
+    if (vdiFileOpened(pImage))
     {
         vdiFlushImage(pImage);
-        RTFileClose(pImage->File);
-        pImage->File = NIL_RTFILE;
+        vdiFileClose(pImage);
     }
     if (pImage->paBlocks)
@@ -783,5 +926,9 @@
     }
     pImage->pszFilename = pszFilename;
+#ifndef VBOX_WITH_NEW_IO_CODE
     pImage->File = NIL_RTFILE;
+#else
+    pImage->pvStorage = NULL;
+#endif
     pImage->paBlocks = NULL;
     pImage->pVDIfsDisk = NULL;
@@ -827,5 +974,9 @@
     }
     pImage->pszFilename = pszFilename;
+#ifndef VBOX_WITH_NEW_IO_CODE
     pImage->File = NIL_RTFILE;
+#else
+    pImage->pvStorage = NULL;
+#endif
     pImage->paBlocks = NULL;
     pImage->pVDIfsDisk = pVDIfsDisk;
@@ -901,5 +1052,9 @@
     }
     pImage->pszFilename = pszFilename;
+#ifndef VBOX_WITH_NEW_IO_CODE
     pImage->File = NIL_RTFILE;
+#else
+    pImage->pvStorage = NULL;
+#endif
     pImage->paBlocks = NULL;
     pImage->pVDIfsDisk = pVDIfsDisk;
@@ -1035,5 +1190,5 @@
         uint64_t u64Offset = (uint64_t)pImage->paBlocks[uBlock] * pImage->cbTotalBlockData
                            + (pImage->offStartData + pImage->offStartBlockData + offRead);
-        rc = RTFileReadAt(pImage->File, u64Offset, pvBuf, cbToRead, NULL);
+        rc = vdiFileReadSync(pImage, u64Offset, pvBuf, cbToRead, NULL);
     }
 
@@ -1115,5 +1270,5 @@
                 uint64_t u64Offset = (uint64_t)cBlocksAllocated * pImage->cbTotalBlockData
                                    + (pImage->offStartData + pImage->offStartBlockData);
-                rc = RTFileWriteAt(pImage->File, u64Offset, pvBuf, cbToWrite, NULL);
+                rc = vdiFileWriteSync(pImage, u64Offset, pvBuf, cbToWrite, NULL);
                 if (RT_FAILURE(rc))
                     goto out;
@@ -1142,5 +1297,5 @@
             uint64_t u64Offset = (uint64_t)pImage->paBlocks[uBlock] * pImage->cbTotalBlockData
                                + (pImage->offStartData + pImage->offStartBlockData + offWrite);
-            rc = RTFileWriteAt(pImage->File, u64Offset, pvBuf, cbToWrite, NULL);
+            rc = vdiFileWriteSync(pImage, u64Offset, pvBuf, cbToWrite, NULL);
         }
     } while (0);
@@ -1216,7 +1371,7 @@
     {
         uint64_t cbFile;
-        if (pImage->File != NIL_RTFILE)
-        {
-            int rc = RTFileGetSize(pImage->File, &cbFile);
+        if (vdiFileOpened(pImage))
+        {
+            int rc = vdiFileGetSize(pImage, &cbFile);
             if (RT_SUCCESS(rc))
                 cb += cbFile;
@@ -1721,4 +1876,5 @@
     PVDIIMAGEDESC pImage = (PVDIIMAGEDESC)pBackendData;
 
+#ifndef VBOX_WITH_NEW_IO_CODE
     pImage->pInterfaceErrorCallbacks->pfnMessage(pImage->pInterfaceError->pvUser, "Dumping VDI image \"%s\" mode=%s uOpenFlags=%X File=%08X\n",
                 pImage->pszFilename,
@@ -1726,4 +1882,11 @@
                 pImage->uOpenFlags,
                 pImage->File);
+#else
+    pImage->pInterfaceErrorCallbacks->pfnMessage(pImage->pInterfaceError->pvUser, "Dumping VDI image \"%s\" mode=%s uOpenFlags=%X File=%#p\n",
+                pImage->pszFilename,
+                (pImage->uOpenFlags & VD_OPEN_FLAGS_READONLY) ? "r/o" : "r/w",
+                pImage->uOpenFlags,
+                pImage->pvStorage);
+#endif
     pImage->pInterfaceErrorCallbacks->pfnMessage(pImage->pInterfaceError->pvUser, "Header: Version=%08X Type=%X Flags=%X Size=%llu\n",
                 pImage->PreHeader.u32Version,
@@ -1889,5 +2052,5 @@
 
         uint64_t cbFile;
-        rc = RTFileGetSize(pImage->File, &cbFile);
+        rc = vdiFileGetSize(pImage, &cbFile);
         AssertRCBreak(rc);
         unsigned cBlocksAllocated = (unsigned)((cbFile - pImage->offStartData - pImage->offStartBlockData) >> pImage->uShiftOffset2Index);
@@ -1952,5 +2115,5 @@
                 uint64_t u64Offset = (uint64_t)ptrBlock * pImage->cbTotalBlockData
                                    + (pImage->offStartData + pImage->offStartBlockData);
-                rc = RTFileReadAt(pImage->File, u64Offset, pvTmp, cbBlock, NULL);
+                rc = vdiFileReadSync(pImage, u64Offset, pvTmp, cbBlock, NULL);
                 if (RT_FAILURE(rc))
                     break;
@@ -2015,8 +2178,8 @@
                 uint64_t u64Offset = (uint64_t)uBlockUsedPos * pImage->cbTotalBlockData
                                    + (pImage->offStartData + pImage->offStartBlockData);
-                rc = RTFileReadAt(pImage->File, u64Offset, pvTmp, cbBlock, NULL);
+                rc = vdiFileReadSync(pImage, u64Offset, pvTmp, cbBlock, NULL);
                 u64Offset = (uint64_t)i * pImage->cbTotalBlockData
                           + (pImage->offStartData + pImage->offStartBlockData);
-                rc = RTFileWriteAt(pImage->File, u64Offset, pvTmp, cbBlock, NULL);
+                rc = vdiFileWriteSync(pImage, u64Offset, pvTmp, cbBlock, NULL);
                 pImage->paBlocks[uBlockData] = i;
                 setImageBlocksAllocated(&pImage->Header, cBlocksAllocated - cBlocksMoved);
@@ -2046,5 +2209,5 @@
 
         /* Truncate the image to the proper size to finish compacting. */
-        rc = RTFileSetSize(pImage->File,
+        rc = vdiFileSetSize(pImage,
                            (uint64_t)uBlockUsedPos * pImage->cbTotalBlockData
                            + (pImage->offStartData + pImage->offStartBlockData));
Index: /trunk/src/VBox/Devices/Storage/VHDHDDCore.cpp
===================================================================
--- /trunk/src/VBox/Devices/Storage/VHDHDDCore.cpp	(revision 22965)
+++ /trunk/src/VBox/Devices/Storage/VHDHDDCore.cpp	(revision 22966)
@@ -130,6 +130,11 @@
     /** Base image name. */
     const char      *pszFilename;
+#ifndef VBOX_WITH_NEW_IO_CODE
     /** Descriptor file if applicable. */
     RTFILE          File;
+#else
+    /** Opaque storage handle. */
+    void           *pvStorage;
+#endif
 
     /** Pointer to the per-disk VD interface list. */
@@ -139,4 +144,10 @@
     /** Error interface callback table. */
     PVDINTERFACEERROR pInterfaceErrorCallbacks;
+#ifdef VBOX_WITH_NEW_IO_CODE
+    /** Async I/O interface. */
+    PVDINTERFACE        pInterfaceAsyncIO;
+    /** Async I/O interface callbacks. */
+    PVDINTERFACEASYNCIO pInterfaceAsyncIOCallbacks;
+#endif
 
     /** Open flags passed by VBoxHD layer. */
@@ -208,4 +219,148 @@
 static int vhdLoadDynamicDisk(PVHDIMAGE pImage, uint64_t uDynamicDiskHeaderOffset);
 
+static int vhdFileOpen(PVHDIMAGE pImage, bool fReadonly, bool fCreate)
+{
+    int rc = VINF_SUCCESS;
+
+    AssertMsg(!(fReadonly && fCreate), ("Image can't be opened readonly while being created\n"));
+
+#ifndef VBOX_WITH_NEW_IO_CODE
+    unsigned uFileFlags = fReadonly ? RTFILE_O_READ      | RTFILE_O_DENY_NONE
+                                    : RTFILE_O_READWRITE | RTFILE_O_DENY_WRITE;
+
+    if (fCreate)
+        uFileFlags |= RTFILE_O_CREATE;
+    else
+        uFileFlags |= RTFILE_O_OPEN;
+
+    rc = RTFileOpen(&pImage->File, pImage->pszFilename, uFileFlags);
+#else
+
+    unsigned uOpenFlags = fReadonly ? VD_INTERFACEASYNCIO_OPEN_FLAGS_READONLY : 0;
+
+    if (fCreate)
+        uOpenFlags |= VD_INTERFACEASYNCIO_OPEN_FLAGS_CREATE;
+
+    rc = pImage->pInterfaceAsyncIOCallbacks->pfnOpen(pImage->pInterfaceAsyncIO->pvUser,
+                                                     pImage->pszFilename,
+                                                     uOpenFlags,
+                                                     NULL, &pImage->pvStorage);
+#endif
+
+    return rc;
+}
+
+static int vhdFileClose(PVHDIMAGE pImage)
+{
+    int rc = VINF_SUCCESS;
+
+#ifndef VBOX_WITH_NEW_IO_CODE
+    if (pImage->File != NIL_RTFILE)
+        rc = RTFileClose(pImage->File);
+
+    pImage->File = NIL_RTFILE;
+#else
+    if (pImage->pvStorage)
+        rc = pImage->pInterfaceAsyncIOCallbacks->pfnClose(pImage->pInterfaceAsyncIO->pvUser,
+                                                          pImage->pvStorage);
+
+    pImage->pvStorage = NULL;
+#endif
+
+    return rc;
+}
+
+static int vhdFileFlushSync(PVHDIMAGE pImage)
+{
+    int rc = VINF_SUCCESS;
+
+#ifndef VBOX_WITH_NEW_IO_CODE
+    rc = RTFileFlush(pImage->File);
+#else
+    if (pImage->pvStorage)
+        rc = pImage->pInterfaceAsyncIOCallbacks->pfnFlushSync(pImage->pInterfaceAsyncIO->pvUser,
+                                                              pImage->pvStorage);
+#endif
+
+    return rc;
+}
+
+static int vhdFileGetSize(PVHDIMAGE pImage, uint64_t *pcbSize)
+{
+    int rc = VINF_SUCCESS;
+
+#ifndef VBOX_WITH_NEW_IO_CODE
+    rc = RTFileGetSize(pImage->File, pcbSize);
+#else
+    if (pImage->pvStorage)
+        rc = pImage->pInterfaceAsyncIOCallbacks->pfnGetSize(pImage->pInterfaceAsyncIO->pvUser,
+                                                            pImage->pvStorage,
+                                                            pcbSize);
+#endif
+
+    return rc;
+
+}
+
+static int vhdFileSetSize(PVHDIMAGE pImage, uint64_t cbSize)
+{
+    int rc = VINF_SUCCESS;
+
+#ifndef VBOX_WITH_NEW_IO_CODE
+    rc = RTFileSetSize(pImage->File, cbSize);
+#else
+    if (pImage->pvStorage)
+        rc = pImage->pInterfaceAsyncIOCallbacks->pfnSetSize(pImage->pInterfaceAsyncIO->pvUser,
+                                                            pImage->pvStorage,
+                                                            cbSize);
+#endif
+
+    return rc;
+}
+
+
+static int vhdFileWriteSync(PVHDIMAGE pImage, uint64_t off, const void *pcvBuf, size_t cbWrite, size_t *pcbWritten)
+{
+    int rc = VINF_SUCCESS;
+
+#ifndef VBOX_WITH_NEW_IO_CODE
+    rc = RTFileWriteAt(pImage->File, off, pcvBuf, cbWrite, pcbWritten);
+#else
+    if (pImage->pvStorage)
+        rc = pImage->pInterfaceAsyncIOCallbacks->pfnWriteSync(pImage->pInterfaceAsyncIO->pvUser,
+                                                              pImage->pvStorage,
+                                                              off, cbWrite, pcvBuf,
+                                                              pcbWritten);
+#endif
+
+    return rc;
+}
+
+static int vhdFileReadSync(PVHDIMAGE pImage, uint64_t off, void *pvBuf, size_t cbRead, size_t *pcbRead)
+{
+    int rc = VINF_SUCCESS;
+
+#ifndef VBOX_WITH_NEW_IO_CODE
+    rc = RTFileReadAt(pImage->File, off, pvBuf, cbRead, pcbRead);
+#else
+    if (pImage->pvStorage)
+        rc = pImage->pInterfaceAsyncIOCallbacks->pfnReadSync(pImage->pInterfaceAsyncIO->pvUser,
+                                                             pImage->pvStorage,
+                                                             off, cbRead, pvBuf,
+                                                             pcbRead);
+#endif
+
+    return rc;
+}
+
+static bool vhdFileOpened(PVHDIMAGE pImage)
+{
+#ifndef VBOX_WITH_NEW_IO_CODE
+    return pImage->File != NIL_RTFILE;
+#else
+    return pImage->pvStorage != NULL;
+#endif
+}
+
 /* 946684800 is a number of seconds between 1/1/1970 and 1/1/2000 */
 #define VHD_TO_UNIX_EPOCH_SECONDS UINT64_C(946684800)
@@ -338,6 +493,6 @@
             goto out;
     }
-    rc = RTFileWriteAt(pImage->File, RT_BE2H_U64(pLocator->u64DataOffset), pvBuf,
-                       RT_BE2H_U32(pLocator->u32DataSpace) * VHD_SECTOR_SIZE, NULL);
+    rc = vhdFileWriteSync(pImage, RT_BE2H_U64(pLocator->u64DataOffset), pvBuf,
+                          RT_BE2H_U32(pLocator->u32DataSpace) * VHD_SECTOR_SIZE, NULL);
 
 out:
@@ -358,5 +513,5 @@
         return VERR_VD_NOT_OPENED;
 
-    rc = RTFileReadAt(pImage->File, pImage->u64DataOffset, &ddh, sizeof(ddh), NULL);
+    rc = vhdFileReadSync(pImage, pImage->u64DataOffset, &ddh, sizeof(ddh), NULL);
     if (RT_FAILURE(rc))
         return rc;
@@ -403,10 +558,10 @@
     ddh.Checksum = 0;
     ddh.Checksum = RT_H2BE_U32(vhdChecksum(&ddh, sizeof(ddh)));
-    rc = RTFileWriteAt(pImage->File, pImage->u64DataOffset, &ddh, sizeof(ddh), NULL);
+    rc = vhdFileWriteSync(pImage, pImage->u64DataOffset, &ddh, sizeof(ddh), NULL);
     if (RT_FAILURE(rc))
         return rc;
 
     /* Update the VHD footer copy. */
-    rc = RTFileWriteAt(pImage->File, 0, &pImage->vhdFooterCopy, sizeof(VHDFooter), NULL);
+    rc = vhdFileWriteSync(pImage, 0, &pImage->vhdFooterCopy, sizeof(VHDFooter), NULL);
 
 out:
@@ -417,5 +572,4 @@
 static int vhdOpenImage(PVHDIMAGE pImage, unsigned uOpenFlags)
 {
-    RTFILE File;
     uint64_t FileSize;
     VHDFooter vhdFooter;
@@ -430,10 +584,16 @@
         pImage->pInterfaceErrorCallbacks = VDGetInterfaceError(pImage->pInterfaceError);
 
+#ifdef VBOX_WITH_NEW_IO_CODE
+    /* Try to get async I/O interface. */
+    pImage->pInterfaceAsyncIO = VDInterfaceGet(pImage->pVDIfsDisk, VDINTERFACETYPE_ASYNCIO);
+    AssertPtr(pImage->pInterfaceAsyncIO);
+    pImage->pInterfaceAsyncIOCallbacks = VDGetInterfaceAsyncIO(pImage->pInterfaceAsyncIO);
+    AssertPtr(pImage->pInterfaceAsyncIOCallbacks);
+#endif
+
     /*
      * Open the image.
      */
-    int rc = RTFileOpen(&File, pImage->pszFilename, uOpenFlags & VD_OPEN_FLAGS_READONLY
-                    ? RTFILE_O_READ      | RTFILE_O_OPEN | RTFILE_O_DENY_NONE
-                    : RTFILE_O_READWRITE | RTFILE_O_OPEN | RTFILE_O_DENY_WRITE);
+    int rc = vhdFileOpen(pImage, !!(uOpenFlags & VD_OPEN_FLAGS_READONLY), false);
     if (RT_FAILURE(rc))
     {
@@ -442,11 +602,10 @@
         return rc;
     }
-    pImage->File = File;
-
-    rc = RTFileGetSize(File, &FileSize);
+
+    rc = vhdFileGetSize(pImage, &FileSize);
     pImage->FileSize = FileSize;
     pImage->uCurrentEndOfFile = FileSize - sizeof(VHDFooter);
 
-    rc = RTFileReadAt(File, pImage->uCurrentEndOfFile, &vhdFooter, sizeof(VHDFooter), NULL);
+    rc = vhdFileReadSync(pImage, pImage->uCurrentEndOfFile, &vhdFooter, sizeof(VHDFooter), NULL);
     if (memcmp(vhdFooter.Cookie, VHD_FOOTER_COOKIE, VHD_FOOTER_COOKIE_SIZE) != 0)
         return VERR_VD_VHD_INVALID_HEADER;
@@ -524,5 +683,9 @@
     }
     pImage->pszFilename = pszFilename;
+#ifndef VBOX_WITH_NEW_IO_CODE
     pImage->File = NIL_RTFILE;
+#else
+    pImage->pvStorage != NULL;
+#endif
     pImage->pVDIfsDisk = pVDIfsDisk;
 
@@ -546,5 +709,5 @@
      * Read the dynamic disk header.
      */
-    rc = RTFileReadAt(pImage->File, uDynamicDiskHeaderOffset, &vhdDynamicDiskHeader, sizeof(VHDDynamicDiskHeader), NULL);
+    rc = vhdFileReadSync(pImage, uDynamicDiskHeaderOffset, &vhdDynamicDiskHeader, sizeof(VHDDynamicDiskHeader), NULL);
     if (memcmp(vhdDynamicDiskHeader.Cookie, VHD_DYNAMIC_DISK_HEADER_COOKIE, VHD_DYNAMIC_DISK_HEADER_COOKIE_SIZE) != 0)
         return VERR_INVALID_PARAMETER;
@@ -581,5 +744,5 @@
     LogFlowFunc(("uBlockAllocationTableOffset=%llu\n", uBlockAllocationTableOffset));
     pImage->uBlockAllocationTableOffset = uBlockAllocationTableOffset;
-    rc = RTFileReadAt(pImage->File, uBlockAllocationTableOffset, pBlockAllocationTable, pImage->cBlockAllocationTableEntries * sizeof(uint32_t), NULL);
+    rc = vhdFileReadSync(pImage, uBlockAllocationTableOffset, pBlockAllocationTable, pImage->cBlockAllocationTableEntries * sizeof(uint32_t), NULL);
     pImage->uDataBlockStart = uBlockAllocationTableOffset + pImage->cBlockAllocationTableEntries * sizeof(uint32_t);
     LogFlowFunc(("uDataBlockStart=%llu\n", pImage->uDataBlockStart));
@@ -793,9 +956,7 @@
     if (RT_FAILURE(rc))
         goto out;
-    RTFileClose(pImage->File);
+    vhdFileClose(pImage);
     pImage->uOpenFlags = uOpenFlags;
-    rc = RTFileOpen(&pImage->File, pImage->pszFilename, uOpenFlags & VD_OPEN_FLAGS_READONLY
-            ? RTFILE_O_READ      | RTFILE_O_OPEN | RTFILE_O_DENY_NONE
-            : RTFILE_O_READWRITE | RTFILE_O_OPEN | RTFILE_O_DENY_WRITE);
+    rc = vhdFileOpen(pImage, !!(uOpenFlags & VD_OPEN_FLAGS_READONLY), false);
 
 out:
@@ -822,5 +983,5 @@
     /* Close the file. vhdFreeImage would additionally free pImage. */
     vhdFlush(pImage);
-    RTFileClose(pImage->File);
+    vhdFileClose(pImage);
 
     /* Rename the file. */
@@ -878,5 +1039,5 @@
     {
         vhdFlush(pImage);
-        RTFileClose(pImage->File);
+        vhdFileClose(pImage);
         vhdFreeImageMemory(pImage);
     }
@@ -898,5 +1059,5 @@
         {
             /* No point in updating the file that is deleted anyway. */
-            RTFileClose(pImage->File);
+            vhdFileClose(pImage);
             RTFileDelete(pImage->pszFilename);
             vhdFreeImageMemory(pImage);
@@ -994,7 +1155,7 @@
 
         /* Read in the block's bitmap. */
-        rc = RTFileReadAt(pImage->File,
-                          ((uint64_t)pImage->pBlockAllocationTable[cBlockAllocationTableEntry]) * VHD_SECTOR_SIZE,
-                          pImage->pu8Bitmap, pImage->cbDataBlockBitmap, NULL);
+        rc = vhdFileReadSync(pImage,
+                             ((uint64_t)pImage->pBlockAllocationTable[cBlockAllocationTableEntry]) * VHD_SECTOR_SIZE,
+                             pImage->pu8Bitmap, pImage->cbDataBlockBitmap, NULL);
         if (RT_SUCCESS(rc))
         {
@@ -1021,5 +1182,5 @@
 
                 LogFlowFunc(("uVhdOffset=%llu cbRead=%u\n", uVhdOffset, cbRead));
-                rc = RTFileReadAt(pImage->File, uVhdOffset, pvBuf, cbRead, NULL);
+                rc = vhdFileReadSync(pImage, uVhdOffset, pvBuf, cbRead, NULL);
             }
             else
@@ -1053,5 +1214,5 @@
     else
     {
-        rc = RTFileReadAt(pImage->File, uOffset, pvBuf, cbRead, NULL);
+        rc = vhdFileReadSync(pImage, uOffset, pvBuf, cbRead, NULL);
     }
 
@@ -1124,5 +1285,5 @@
              * Write the new block at the current end of the file.
              */
-            rc = RTFileWriteAt(pImage->File, pImage->uCurrentEndOfFile, pNewBlock, cbNewBlock, NULL);
+            rc = vhdFileWriteSync(pImage, pImage->uCurrentEndOfFile, pNewBlock, cbNewBlock, NULL);
 
             /*
@@ -1140,8 +1301,8 @@
 
         /* Write data. */
-        RTFileWriteAt(pImage->File, uVhdOffset, pvBuf, cbToWrite, NULL);
+        vhdFileWriteSync(pImage, uVhdOffset, pvBuf, cbToWrite, NULL);
 
         /* Read in the block's bitmap. */
-        rc = RTFileReadAt(pImage->File,
+        rc = vhdFileReadSync(pImage,
             ((uint64_t)pImage->pBlockAllocationTable[cBlockAllocationTableEntry]) * VHD_SECTOR_SIZE,
             pImage->pu8Bitmap, pImage->cbDataBlockBitmap, NULL);
@@ -1156,5 +1317,5 @@
 
             /* Write the bitmap back. */
-            rc = RTFileWriteAt(pImage->File,
+            rc = vhdFileWriteSync(pImage,
                 ((uint64_t)pImage->pBlockAllocationTable[cBlockAllocationTableEntry]) * VHD_SECTOR_SIZE,
                 pImage->pu8Bitmap, pImage->cbDataBlockBitmap, NULL);
@@ -1163,5 +1324,5 @@
     else
     {
-        rc = RTFileWriteAt(pImage->File, uOffset, pvBuf, cbToWrite, NULL);
+        rc = vhdFileWriteSync(pImage, uOffset, pvBuf, cbToWrite, NULL);
     }
 
@@ -1204,6 +1365,6 @@
          * Write the block allocation table after the copy of the disk footer and the dynamic disk header.
          */
-        RTFileWriteAt(pImage->File, pImage->uBlockAllocationTableOffset, pBlockAllocationTableToWrite, cbBlockAllocationTableToWrite, NULL);
-        RTFileWriteAt(pImage->File, pImage->uCurrentEndOfFile, &pImage->vhdFooterCopy, sizeof(VHDFooter), NULL);
+        vhdFileWriteSync(pImage, pImage->uBlockAllocationTableOffset, pBlockAllocationTableToWrite, cbBlockAllocationTableToWrite, NULL);
+        vhdFileWriteSync(pImage, pImage->uCurrentEndOfFile, &pImage->vhdFooterCopy, sizeof(VHDFooter), NULL);
         if (pImage->fDynHdrNeedsUpdate)
             vhdDynamicHeaderUpdate(pImage);
@@ -1211,5 +1372,5 @@
     }
 
-    int rc = RTFileFlush(pImage->File);
+    int rc = vhdFileFlushSync(pImage);
 
     return rc;
@@ -1240,5 +1401,5 @@
     {
         uint64_t cb;
-        int rc = RTFileGetSize(pImage->File, &cb);
+        int rc = vhdFileGetSize(pImage, &cb);
         if (RT_SUCCESS(rc))
             return cb;
@@ -1391,5 +1552,5 @@
     AssertPtr(pImage);
 
-    if (pImage && pImage->File != NIL_RTFILE)
+    if (pImage && vhdFileOpened(pImage))
     {
         if (!(pImage->uImageFlags & VD_IMAGE_FLAGS_FIXED))
@@ -1546,4 +1707,5 @@
     VHDDynamicDiskHeader DynamicDiskHeader;
     uint32_t u32BlockAllocationTableSectors;
+    void    *pvTmp = NULL;
 
     memset(&DynamicDiskHeader, 0, sizeof(DynamicDiskHeader));
@@ -1574,7 +1736,17 @@
         pImage->uBlockAllocationTableOffset + u32BlockAllocationTableSectors * VHD_SECTOR_SIZE);
 
-    rc = RTFileSetSize(pImage->File, pImage->uCurrentEndOfFile + sizeof(VHDFooter));
+    /* Set dynamic image size. */
+    pvTmp = RTMemTmpAllocZ(pImage->uCurrentEndOfFile + sizeof(VHDFooter));
+    if (!pvTmp)
+        return vhdError(pImage, VERR_NO_MEMORY, RT_SRC_POS, N_("VHD: cannot set the file size for '%s'"), pImage->pszFilename);
+
+    rc = vhdFileWriteSync(pImage, 0, pvTmp, pImage->uCurrentEndOfFile + sizeof(VHDFooter), NULL);
     if (RT_FAILURE(rc))
+    {
+        RTMemTmpFree(pvTmp);
         return vhdError(pImage, rc, RT_SRC_POS, N_("VHD: cannot set the file size for '%s'"), pImage->pszFilename);
+    }
+
+    RTMemTmpFree(pvTmp);
 
     /* Initialize and write the dynamic disk header. */
@@ -1589,11 +1761,11 @@
     DynamicDiskHeader.Checksum = RT_H2BE_U32(vhdChecksum(&DynamicDiskHeader, sizeof(DynamicDiskHeader)));
 
-    rc = RTFileWriteAt(pImage->File, sizeof(VHDFooter), &DynamicDiskHeader, sizeof(DynamicDiskHeader), NULL);
+    rc = vhdFileWriteSync(pImage, sizeof(VHDFooter), &DynamicDiskHeader, sizeof(DynamicDiskHeader), NULL);
     if (RT_FAILURE(rc))
         return vhdError(pImage, rc, RT_SRC_POS, N_("VHD: cannot write dynamic disk header to image '%s'"), pImage->pszFilename);
 
     /* Write BAT. */
-    rc = RTFileWriteAt(pImage->File, pImage->uBlockAllocationTableOffset, pImage->pBlockAllocationTable,
-                       pImage->cBlockAllocationTableEntries * sizeof(uint32_t), NULL);
+    rc = vhdFileWriteSync(pImage, pImage->uBlockAllocationTableOffset, pImage->pBlockAllocationTable,
+                          pImage->cBlockAllocationTableEntries * sizeof(uint32_t), NULL);
     if (RT_FAILURE(rc))
         return vhdError(pImage, rc, RT_SRC_POS, N_("VHD: cannot write BAT to image '%s'"), pImage->pszFilename);
@@ -1625,10 +1797,8 @@
         pImage->pInterfaceErrorCallbacks = VDGetInterfaceError(pImage->pInterfaceError);
 
-    /* Create image file. */
-    rc = RTFileOpen(&File, pImage->pszFilename,
-                    RTFILE_O_READWRITE | RTFILE_O_CREATE | RTFILE_O_DENY_ALL);
+    rc = vhdFileOpen(pImage, false /* fReadonly */, true /* fCreate */);
     if (RT_FAILURE(rc))
         return vhdError(pImage, rc, RT_SRC_POS, N_("VHD: cannot create image '%s'"), pImage->pszFilename);
-    pImage->File = File;
+
 
     pImage->cbSize = cbSize;
@@ -1670,5 +1840,5 @@
         /** @todo r=klaus replace this with actual data writes, see the experience
          * with VDI files on Windows, can cause long freezes when writing. */
-        rc = RTFileSetSize(File, pImage->uCurrentEndOfFile + sizeof(VHDFooter));
+        rc = vhdFileSetSize(pImage, pImage->uCurrentEndOfFile + sizeof(VHDFooter));
         if (RT_FAILURE(rc))
         {
@@ -1714,5 +1884,5 @@
 
     /* Store the footer */
-    rc = RTFileWriteAt(File, pImage->uCurrentEndOfFile, &Footer, sizeof(Footer), NULL);
+    rc = vhdFileWriteSync(pImage, pImage->uCurrentEndOfFile, &Footer, sizeof(Footer), NULL);
     if (RT_FAILURE(rc))
     {
@@ -1725,5 +1895,5 @@
     {
         /* Write the copy of the footer. */
-        rc = RTFileWriteAt(File, 0, &Footer, sizeof(Footer), NULL);
+        rc = vhdFileWriteSync(pImage, 0, &Footer, sizeof(Footer), NULL);
         if (RT_FAILURE(rc))
         {
@@ -1781,6 +1951,18 @@
     }
     pImage->pszFilename = pszFilename;
+#ifndef VBOX_WITH_NEW_IO_CODE
     pImage->File = NIL_RTFILE;
-    pImage->pVDIfsDisk = NULL;
+#else
+    pImage->pvStorage = NULL;
+#endif
+    pImage->pVDIfsDisk = pVDIfsDisk;
+
+#ifdef VBOX_WITH_NEW_IO_CODE
+    /* Try to get async I/O interface. */
+    pImage->pInterfaceAsyncIO = VDInterfaceGet(pImage->pVDIfsDisk, VDINTERFACETYPE_ASYNCIO);
+    AssertPtr(pImage->pInterfaceAsyncIO);
+    pImage->pInterfaceAsyncIOCallbacks = VDGetInterfaceAsyncIO(pImage->pInterfaceAsyncIO);
+    AssertPtr(pImage->pInterfaceAsyncIOCallbacks);
+#endif
 
     rc = vhdCreateImage(pImage, cbSize, uImageFlags, pszComment,
@@ -1828,5 +2010,17 @@
         RTFSOBJINFO info;
 
+#ifndef VBOX_WITH_NEW_IO_CODE
         rc = RTFileQueryInfo(pImage->File, &info, RTFSOBJATTRADD_NOTHING);
+#else
+        /* Interface doesn't provide such a feature. */
+        RTFILE File;
+        rc = RTFileOpen(&File, pImage->pszFilename, RTFILE_O_OPEN | RTFILE_O_READ);
+        if (RT_SUCCESS(rc))
+        {
+            rc = RTFileQueryInfo(File, &info, RTFSOBJATTRADD_NOTHING);
+            RTFileClose(File);
+        }
+#endif
+
         *pTimeStamp = info.ModificationTime;
     }
Index: /trunk/src/VBox/Devices/Storage/VmdkHDDCore.cpp
===================================================================
--- /trunk/src/VBox/Devices/Storage/VmdkHDDCore.cpp	(revision 22965)
+++ /trunk/src/VBox/Devices/Storage/VmdkHDDCore.cpp	(revision 22966)
@@ -582,6 +582,6 @@
                                                          pszFilename,
                                                          pImage->uOpenFlags & VD_OPEN_FLAGS_READONLY
-                                                           ? true
-                                                           : false,
+                                                           ? VD_INTERFACEASYNCIO_OPEN_FLAGS_READONLY
+                                                           : 0,
                                                          NULL,
                                                          &pVmdkFile->pStorage);
@@ -700,8 +700,11 @@
 DECLINLINE(int) vmdkFileGetSize(PVMDKFILE pVmdkFile, uint64_t *pcbSize)
 {
+    PVMDKIMAGE pImage = pVmdkFile->pImage;
+
     if (pVmdkFile->fAsyncIO)
     {
-        AssertMsgFailed(("TODO\n"));
-        return 0;
+        return pImage->pInterfaceAsyncIOCallbacks->pfnGetSize(pImage->pInterfaceAsyncIO->pvUser,
+                                                              pVmdkFile->pStorage,
+                                                              pcbSize);
     }
     else
@@ -714,8 +717,11 @@
 DECLINLINE(int) vmdkFileSetSize(PVMDKFILE pVmdkFile, uint64_t cbSize)
 {
+    PVMDKIMAGE pImage = pVmdkFile->pImage;
+
     if (pVmdkFile->fAsyncIO)
     {
-        AssertMsgFailed(("TODO\n"));
-        return VERR_NOT_SUPPORTED;
+        return pImage->pInterfaceAsyncIOCallbacks->pfnSetSize(pImage->pInterfaceAsyncIO->pvUser,
+                                                              pVmdkFile->pStorage,
+                                                              cbSize);
     }
     else
@@ -5814,5 +5820,5 @@
             {
                 /* Check for enough room first. */
-                if (RT_LIKELY(cSegments >= pImage->cSegments))
+                if (RT_UNLIKELY(cSegments >= pImage->cSegments))
                 {
                     /* We reached maximum, resize array. Try to realloc memory first. */
@@ -5942,5 +5948,5 @@
             {
                 /* Check for enough room first. */
-                if (RT_LIKELY(cSegments >= pImage->cSegments))
+                if (RT_UNLIKELY(cSegments >= pImage->cSegments))
                 {
                     /* We reached maximum, resize array. Try to realloc memory first. */
