Index: trunk/include/VBox/vmm/pdmifs.h
===================================================================
--- trunk/include/VBox/vmm/pdmifs.h	(revision 59247)
+++ trunk/include/VBox/vmm/pdmifs.h	(revision 59248)
@@ -1018,27 +1018,177 @@
 
 
-/** Pointer to a block port interface. */
-typedef struct PDMIBLOCKPORT *PPDMIBLOCKPORT;
-/**
- * Block notify interface (down).
- * Pair with PDMIBLOCK.
- */
-typedef struct PDMIBLOCKPORT
-{
-    /**
-     * Returns the storage controller name, instance and LUN of the attached medium.
-     *
-     * @returns VBox status.
+/** Pointer to a mount interface. */
+typedef struct PDMIMOUNTNOTIFY *PPDMIMOUNTNOTIFY;
+/**
+ * Block interface (up).
+ * Pair with PDMIMOUNT.
+ */
+typedef struct PDMIMOUNTNOTIFY
+{
+    /**
+     * Called when a media is mounted.
+     *
+     * @param   pInterface      Pointer to the interface structure containing the called function pointer.
+     * @thread  The emulation thread.
+     */
+    DECLR3CALLBACKMEMBER(void, pfnMountNotify,(PPDMIMOUNTNOTIFY pInterface));
+
+    /**
+     * Called when a media is unmounted
+     * @param   pInterface      Pointer to the interface structure containing the called function pointer.
+     * @thread  The emulation thread.
+     */
+    DECLR3CALLBACKMEMBER(void, pfnUnmountNotify,(PPDMIMOUNTNOTIFY pInterface));
+} PDMIMOUNTNOTIFY;
+/** PDMIMOUNTNOTIFY interface ID. */
+#define PDMIMOUNTNOTIFY_IID                     "fa143ac9-9fc6-498e-997f-945380a558f9"
+
+
+/** Pointer to mount interface. */
+typedef struct PDMIMOUNT *PPDMIMOUNT;
+/**
+ * Mount interface (down).
+ * Pair with PDMIMOUNTNOTIFY.
+ */
+typedef struct PDMIMOUNT
+{
+    /**
+     * Unmount the media.
+     *
+     * The driver will validate and pass it on. On the rebounce it will decide whether or not to detach it self.
+     *
+     * @returns VBox status code.
+     * @param   pInterface      Pointer to the interface structure containing the called function pointer.
+     * @thread  The emulation thread.
+     * @param   fForce          Force the unmount, even for locked media.
+     * @param   fEject          Eject the medium. Only relevant for host drives.
+     * @thread  The emulation thread.
+     */
+    DECLR3CALLBACKMEMBER(int, pfnUnmount,(PPDMIMOUNT pInterface, bool fForce, bool fEject));
+
+    /**
+     * Checks if a media is mounted.
+     *
+     * @returns true if mounted.
+     * @returns false if not mounted.
+     * @param   pInterface      Pointer to the interface structure containing the called function pointer.
+     * @thread  Any thread.
+     */
+    DECLR3CALLBACKMEMBER(bool, pfnIsMounted,(PPDMIMOUNT pInterface));
+
+    /**
+     * Locks the media, preventing any unmounting of it.
+     *
+     * @returns VBox status code.
+     * @param   pInterface      Pointer to the interface structure containing the called function pointer.
+     * @thread  The emulation thread.
+     */
+    DECLR3CALLBACKMEMBER(int, pfnLock,(PPDMIMOUNT pInterface));
+
+    /**
+     * Unlocks the media, canceling previous calls to pfnLock().
+     *
+     * @returns VBox status code.
+     * @param   pInterface      Pointer to the interface structure containing the called function pointer.
+     * @thread  The emulation thread.
+     */
+    DECLR3CALLBACKMEMBER(int, pfnUnlock,(PPDMIMOUNT pInterface));
+
+    /**
+     * Checks if a media is locked.
+     *
+     * @returns true if locked.
+     * @returns false if not locked.
+     * @param   pInterface      Pointer to the interface structure containing the called function pointer.
+     * @thread  Any thread.
+     */
+    DECLR3CALLBACKMEMBER(bool, pfnIsLocked,(PPDMIMOUNT pInterface));
+} PDMIMOUNT;
+/** PDMIMOUNT interface ID. */
+#define PDMIMOUNT_IID                           "34fc7a4c-623a-4806-a6bf-5be1be33c99f"
+
+/** Pointer to a secret key interface. */
+typedef struct PDMISECKEY *PPDMISECKEY;
+
+/**
+ * Secret key interface to retrieve secret keys.
+ */
+typedef struct PDMISECKEY
+{
+    /**
+     * Retains a key identified by the ID. The caller will only hold a reference
+     * to the key and must not modify the key buffer in any way.
+     *
+     * @returns VBox status code.
      * @param   pInterface      Pointer to this interface.
-     * @param   ppcszController Where to store the name of the storage controller.
-     * @param   piInstance      Where to store the instance number of the controller.
-     * @param   piLUN           Where to store the LUN of the attached device.
-     */
-    DECLR3CALLBACKMEMBER(int, pfnQueryDeviceLocation, (PPDMIBLOCKPORT pInterface, const char **ppcszController,
-                                                       uint32_t *piInstance, uint32_t *piLUN));
-
-} PDMIBLOCKPORT;
-/** PDMIBLOCKPORT interface ID. */
-#define PDMIBLOCKPORT_IID                 "bbbed4cf-0862-4ffd-b60c-f7a65ef8e8ff"
+     * @param   pszId           The alias/id for the key to retrieve.
+     * @param   ppbKey          Where to store the pointer to the key buffer on success.
+     * @param   pcbKey          Where to store the size of the key in bytes on success.
+     */
+    DECLR3CALLBACKMEMBER(int, pfnKeyRetain, (PPDMISECKEY pInterface, const char *pszId,
+                                             const uint8_t **pbKey, size_t *pcbKey));
+
+    /**
+     * Releases one reference of the key identified by the given identifier.
+     * The caller must not access the key buffer after calling this operation.
+     *
+     * @returns VBox status code.
+     * @param   pInterface      Pointer to this interface.
+     * @param   pszId          The alias/id for the key to release.
+     *
+     * @note: It is advised to release the key whenever it is not used anymore so the entity
+     *        storing the key can do anything to make retrieving the key from memory more
+     *        difficult like scrambling the memory buffer for instance.
+     */
+    DECLR3CALLBACKMEMBER(int, pfnKeyRelease, (PPDMISECKEY pInterface, const char *pszId));
+
+    /**
+     * Retains a password identified by the ID. The caller will only hold a reference
+     * to the password and must not modify the buffer in any way.
+     *
+     * @returns VBox status code.
+     * @param   pInterface      Pointer to this interface.
+     * @param   pszId           The alias/id for the password to retrieve.
+     * @param   ppszPassword    Where to store the pointer to the password on success.
+     */
+    DECLR3CALLBACKMEMBER(int, pfnPasswordRetain, (PPDMISECKEY pInterface, const char *pszId,
+                                                  const char **ppszPassword));
+
+    /**
+     * Releases one reference of the password identified by the given identifier.
+     * The caller must not access the password after calling this operation.
+     *
+     * @returns VBox status code.
+     * @param   pInterface      Pointer to this interface.
+     * @param   pszId           The alias/id for the password to release.
+     *
+     * @note: It is advised to release the password whenever it is not used anymore so the entity
+     *        storing the password can do anything to make retrieving the password from memory more
+     *        difficult like scrambling the memory buffer for instance.
+     */
+    DECLR3CALLBACKMEMBER(int, pfnPasswordRelease, (PPDMISECKEY pInterface, const char *pszId));
+} PDMISECKEY;
+/** PDMISECKEY interface ID. */
+#define PDMISECKEY_IID                           "3d698355-d995-453d-960f-31566a891df2"
+
+/** Pointer to a secret key helper interface. */
+typedef struct PDMISECKEYHLP *PPDMISECKEYHLP;
+
+/**
+ * Secret key helper interface for non critical functionality.
+ */
+typedef struct PDMISECKEYHLP
+{
+    /**
+     * Notifies the interface provider that a key couldn't be retrieved from the key store.
+     *
+     * @returns VBox status code.
+     * @param   pInterface      Pointer to this interface.
+     */
+    DECLR3CALLBACKMEMBER(int, pfnKeyMissingNotify, (PPDMISECKEYHLP pInterface));
+
+} PDMISECKEYHLP;
+/** PDMISECKEY interface ID. */
+#define PDMISECKEYHLP_IID                        "7be96168-4156-40ac-86d2-3073bf8b318e"
 
 
@@ -1056,403 +1206,46 @@
 
 /**
- * Block drive type.
- */
-typedef enum PDMBLOCKTYPE
+ * Media type.
+ */
+typedef enum PDMMEDIATYPE
 {
     /** Error (for the query function). */
-    PDMBLOCKTYPE_ERROR = 1,
+    PDMMEDIATYPE_ERROR = 1,
     /** 360KB 5 1/4" floppy drive. */
-    PDMBLOCKTYPE_FLOPPY_360,
+    PDMMEDIATYPE_FLOPPY_360,
     /** 720KB 3 1/2" floppy drive. */
-    PDMBLOCKTYPE_FLOPPY_720,
+    PDMMEDIATYPE_FLOPPY_720,
     /** 1.2MB 5 1/4" floppy drive. */
-    PDMBLOCKTYPE_FLOPPY_1_20,
+    PDMMEDIATYPE_FLOPPY_1_20,
     /** 1.44MB 3 1/2" floppy drive. */
-    PDMBLOCKTYPE_FLOPPY_1_44,
+    PDMMEDIATYPE_FLOPPY_1_44,
     /** 2.88MB 3 1/2" floppy drive. */
-    PDMBLOCKTYPE_FLOPPY_2_88,
+    PDMMEDIATYPE_FLOPPY_2_88,
     /** Fake drive that can take up to 15.6 MB images.
      * C=255, H=2, S=63.  */
-    PDMBLOCKTYPE_FLOPPY_FAKE_15_6,
+    PDMMEDIATYPE_FLOPPY_FAKE_15_6,
     /** Fake drive that can take up to 63.5 MB images.
      * C=255, H=2, S=255.  */
-    PDMBLOCKTYPE_FLOPPY_FAKE_63_5,
+    PDMMEDIATYPE_FLOPPY_FAKE_63_5,
     /** CDROM drive. */
-    PDMBLOCKTYPE_CDROM,
+    PDMMEDIATYPE_CDROM,
     /** DVD drive. */
-    PDMBLOCKTYPE_DVD,
+    PDMMEDIATYPE_DVD,
     /** Hard disk drive. */
-    PDMBLOCKTYPE_HARD_DISK
-} PDMBLOCKTYPE;
+    PDMMEDIATYPE_HARD_DISK
+} PDMMEDIATYPE;
 
 /** Check if the given block type is a floppy. */
-#define PDMBLOCKTYPE_IS_FLOPPY(a_enmType) ( (a_enmType) >= PDMBLOCKTYPE_FLOPPY_360 && (a_enmType) <= PDMBLOCKTYPE_FLOPPY_2_88 )
-
-/**
- * Block raw command data transfer direction.
- */
-typedef enum PDMBLOCKTXDIR
-{
-    PDMBLOCKTXDIR_NONE = 0,
-    PDMBLOCKTXDIR_FROM_DEVICE,
-    PDMBLOCKTXDIR_TO_DEVICE
-} PDMBLOCKTXDIR;
-
-
-/** Pointer to a block interface. */
-typedef struct PDMIBLOCK *PPDMIBLOCK;
-/**
- * Block interface (up).
- * Pair with PDMIBLOCKPORT.
- */
-typedef struct PDMIBLOCK
-{
-    /**
-     * Read bits.
-     *
-     * @returns VBox status code.
-     * @param   pInterface      Pointer to the interface structure containing the called function pointer.
-     * @param   off             Offset to start reading from. The offset must be aligned to a sector boundary.
-     * @param   pvBuf           Where to store the read bits.
-     * @param   cbRead          Number of bytes to read. Must be aligned to a sector boundary.
-     * @thread  Any thread.
-     */
-    DECLR3CALLBACKMEMBER(int, pfnRead,(PPDMIBLOCK pInterface, uint64_t off, void *pvBuf, size_t cbRead));
-
-    /**
-     * Read bits - version for DevPcBios.
-     *
-     * @returns VBox status code.
-     * @param   pInterface      Pointer to the interface structure containing the called function pointer.
-     * @param   off             Offset to start reading from. The offset must be aligned to a sector boundary.
-     * @param   pvBuf           Where to store the read bits.
-     * @param   cbRead          Number of bytes to read. Must be aligned to a sector boundary.
-     * @thread  Any thread.
-     *
-     * @note: Special version of pfnRead which doesn't try to suspend the VM when the DEKs for encrypted disks
-     *        are missing but just returns an error.
-     */
-    DECLR3CALLBACKMEMBER(int, pfnReadPcBios,(PPDMIBLOCK pInterface, uint64_t off, void *pvBuf, size_t cbRead));
-
-    /**
-     * Write bits.
-     *
-     * @returns VBox status code.
-     * @param   pInterface      Pointer to the interface structure containing the called function pointer.
-     * @param   off             Offset to start writing at. The offset must be aligned to a sector boundary.
-     * @param   pvBuf           Where to store the write bits.
-     * @param   cbWrite         Number of bytes to write. Must be aligned to a sector boundary.
-     * @thread  Any thread.
-     */
-    DECLR3CALLBACKMEMBER(int, pfnWrite,(PPDMIBLOCK pInterface, uint64_t off, const void *pvBuf, size_t cbWrite));
-
-    /**
-     * Make sure that the bits written are actually on the storage medium.
-     *
-     * @returns VBox status code.
-     * @param   pInterface      Pointer to the interface structure containing the called function pointer.
-     * @thread  Any thread.
-     */
-    DECLR3CALLBACKMEMBER(int, pfnFlush,(PPDMIBLOCK pInterface));
-
-    /**
-     * Send a raw command to the underlying device (CDROM).
-     * This method is optional (i.e. the function pointer may be NULL).
-     *
-     * @returns VBox status code.
-     * @param   pInterface      Pointer to the interface structure containing the called function pointer.
-     * @param   pbCmd           Offset to start reading from.
-     * @param   enmTxDir        Direction of transfer.
-     * @param   pvBuf           Pointer tp the transfer buffer.
-     * @param   cbBuf           Size of the transfer buffer.
-     * @param   pbSenseKey      Status of the command (when return value is VERR_DEV_IO_ERROR).
-     * @param   cTimeoutMillies Command timeout in milliseconds.
-     * @thread  Any thread.
-     */
-    DECLR3CALLBACKMEMBER(int, pfnSendCmd,(PPDMIBLOCK pInterface, const uint8_t *pbCmd, PDMBLOCKTXDIR enmTxDir, void *pvBuf, uint32_t *pcbBuf, uint8_t *pabSense, size_t cbSense, uint32_t cTimeoutMillies));
-
-    /**
-     * Merge medium contents during a live snapshot deletion.
-     *
-     * @returns VBox status code.
-     * @param   pInterface      Pointer to the interface structure containing the called function pointer.
-     * @param   pfnProgress     Function pointer for progress notification.
-     * @param   pvUser          Opaque user data for progress notification.
-     * @thread  Any thread.
-     */
-    DECLR3CALLBACKMEMBER(int, pfnMerge,(PPDMIBLOCK pInterface, PFNSIMPLEPROGRESS pfnProgress, void *pvUser));
-
-    /**
-     * Check if the media is readonly or not.
-     *
-     * @returns true if readonly.
-     * @returns false if read/write.
-     * @param   pInterface      Pointer to the interface structure containing the called function pointer.
-     * @thread  Any thread.
-     */
-    DECLR3CALLBACKMEMBER(bool, pfnIsReadOnly,(PPDMIBLOCK pInterface));
-
-    /**
-     * Gets the media size in bytes.
-     *
-     * @returns Media size in bytes.
-     * @param   pInterface      Pointer to the interface structure containing the called function pointer.
-     * @thread  Any thread.
-     */
-    DECLR3CALLBACKMEMBER(uint64_t, pfnGetSize,(PPDMIBLOCK pInterface));
-
-    /**
-     * Gets the media sector size in bytes.
-     *
-     * @returns Media sector size in bytes.
-     * @param   pInterface      Pointer to the interface structure containing the called function pointer.
-     * @thread  Any thread.
-     */
-    DECLR3CALLBACKMEMBER(uint32_t, pfnGetSectorSize,(PPDMIBLOCK pInterface));
-
-    /**
-     * Gets the block drive type.
-     *
-     * @returns block drive type.
-     * @param   pInterface      Pointer to the interface structure containing the called function pointer.
-     * @thread  Any thread.
-     */
-    DECLR3CALLBACKMEMBER(PDMBLOCKTYPE, pfnGetType,(PPDMIBLOCK pInterface));
-
-    /**
-     * Gets the UUID of the block drive.
-     * Don't return the media UUID if it's removable.
-     *
-     * @returns VBox status code.
-     * @param   pInterface      Pointer to the interface structure containing the called function pointer.
-     * @param   pUuid           Where to store the UUID on success.
-     * @thread  Any thread.
-     */
-    DECLR3CALLBACKMEMBER(int, pfnGetUuid,(PPDMIBLOCK pInterface, PRTUUID pUuid));
-
-    /**
-     * Discards the given range.
-     *
-     * @returns VBox status code.
-     * @param   pInterface      Pointer to the interface structure containing the called function pointer.
-     * @param   paRanges        Array of ranges to discard.
-     * @param   cRanges         Number of entries in the array.
-     * @thread  Any thread.
-     */
-    DECLR3CALLBACKMEMBER(int, pfnDiscard,(PPDMIBLOCK pInterface, PCRTRANGE paRanges, unsigned cRanges));
-
-    /**
-     * Allocate buffer memory which is suitable for I/O and might have special proerties for secure
-     * environments (non-pageable memory for sensitive data which should not end up on the disk).
-     *
-     * @returns VBox status code.
-     * @param   pInterface      Pointer to the interface structure containing the called function pointer.
-     * @param   cb              Amount of memory to allocate.
-     * @param   ppvNew          Where to store the pointer to the buffer on success.
-     */
-    DECLR3CALLBACKMEMBER(int, pfnIoBufAlloc, (PPDMIBLOCK pInterface, size_t cb, void **ppvNew));
-
-    /**
-     * Free memory allocated with PDMIBLOCK::pfnIoBufAlloc().
-     *
-     * @returns VBox status code.
-     * @param   pInterface      Pointer to the interface structure containing the called function pointer.
-     * @param   pv              Pointer to the memory to free.
-     * @param   cb              Amount of bytes given in PDMIBLOCK::pfnIoBufAlloc().
-     */
-    DECLR3CALLBACKMEMBER(int, pfnIoBufFree, (PPDMIBLOCK pInterface, void *pv, size_t cb));
-
-} PDMIBLOCK;
-/** PDMIBLOCK interface ID. */
-#define PDMIBLOCK_IID                           "4e804e8e-3c01-4f20-98d9-a30ece8ec9f5"
-
-
-/** Pointer to a mount interface. */
-typedef struct PDMIMOUNTNOTIFY *PPDMIMOUNTNOTIFY;
-/**
- * Block interface (up).
- * Pair with PDMIMOUNT.
- */
-typedef struct PDMIMOUNTNOTIFY
-{
-    /**
-     * Called when a media is mounted.
-     *
-     * @param   pInterface      Pointer to the interface structure containing the called function pointer.
-     * @thread  The emulation thread.
-     */
-    DECLR3CALLBACKMEMBER(void, pfnMountNotify,(PPDMIMOUNTNOTIFY pInterface));
-
-    /**
-     * Called when a media is unmounted
-     * @param   pInterface      Pointer to the interface structure containing the called function pointer.
-     * @thread  The emulation thread.
-     */
-    DECLR3CALLBACKMEMBER(void, pfnUnmountNotify,(PPDMIMOUNTNOTIFY pInterface));
-} PDMIMOUNTNOTIFY;
-/** PDMIMOUNTNOTIFY interface ID. */
-#define PDMIMOUNTNOTIFY_IID                     "fa143ac9-9fc6-498e-997f-945380a558f9"
-
-
-/** Pointer to mount interface. */
-typedef struct PDMIMOUNT *PPDMIMOUNT;
-/**
- * Mount interface (down).
- * Pair with PDMIMOUNTNOTIFY.
- */
-typedef struct PDMIMOUNT
-{
-    /**
-     * Mount a media.
-     *
-     * This will not unmount any currently mounted media!
-     *
-     * @returns VBox status code.
-     * @param   pInterface      Pointer to the interface structure containing the called function pointer.
-     * @param   pszFilename     Pointer to filename. If this is NULL it assumed that the caller have
-     *                          constructed a configuration which can be attached to the bottom driver.
-     * @param   pszCoreDriver   Core driver name. NULL will cause autodetection. Ignored if pszFilanem is NULL.
-     * @thread  The emulation thread.
-     */
-    DECLR3CALLBACKMEMBER(int, pfnMount,(PPDMIMOUNT pInterface, const char *pszFilename, const char *pszCoreDriver));
-
-    /**
-     * Unmount the media.
-     *
-     * The driver will validate and pass it on. On the rebounce it will decide whether or not to detach it self.
-     *
-     * @returns VBox status code.
-     * @param   pInterface      Pointer to the interface structure containing the called function pointer.
-     * @thread  The emulation thread.
-     * @param   fForce          Force the unmount, even for locked media.
-     * @param   fEject          Eject the medium. Only relevant for host drives.
-     * @thread  The emulation thread.
-     */
-    DECLR3CALLBACKMEMBER(int, pfnUnmount,(PPDMIMOUNT pInterface, bool fForce, bool fEject));
-
-    /**
-     * Checks if a media is mounted.
-     *
-     * @returns true if mounted.
-     * @returns false if not mounted.
-     * @param   pInterface      Pointer to the interface structure containing the called function pointer.
-     * @thread  Any thread.
-     */
-    DECLR3CALLBACKMEMBER(bool, pfnIsMounted,(PPDMIMOUNT pInterface));
-
-    /**
-     * Locks the media, preventing any unmounting of it.
-     *
-     * @returns VBox status code.
-     * @param   pInterface      Pointer to the interface structure containing the called function pointer.
-     * @thread  The emulation thread.
-     */
-    DECLR3CALLBACKMEMBER(int, pfnLock,(PPDMIMOUNT pInterface));
-
-    /**
-     * Unlocks the media, canceling previous calls to pfnLock().
-     *
-     * @returns VBox status code.
-     * @param   pInterface      Pointer to the interface structure containing the called function pointer.
-     * @thread  The emulation thread.
-     */
-    DECLR3CALLBACKMEMBER(int, pfnUnlock,(PPDMIMOUNT pInterface));
-
-    /**
-     * Checks if a media is locked.
-     *
-     * @returns true if locked.
-     * @returns false if not locked.
-     * @param   pInterface      Pointer to the interface structure containing the called function pointer.
-     * @thread  Any thread.
-     */
-    DECLR3CALLBACKMEMBER(bool, pfnIsLocked,(PPDMIMOUNT pInterface));
-} PDMIMOUNT;
-/** PDMIMOUNT interface ID. */
-#define PDMIMOUNT_IID                           "34fc7a4c-623a-4806-a6bf-5be1be33c99f"
-
-/** Pointer to a secret key interface. */
-typedef struct PDMISECKEY *PPDMISECKEY;
-
-/**
- * Secret key interface to retrieve secret keys.
- */
-typedef struct PDMISECKEY
-{
-    /**
-     * Retains a key identified by the ID. The caller will only hold a reference
-     * to the key and must not modify the key buffer in any way.
-     *
-     * @returns VBox status code.
-     * @param   pInterface      Pointer to this interface.
-     * @param   pszId           The alias/id for the key to retrieve.
-     * @param   ppbKey          Where to store the pointer to the key buffer on success.
-     * @param   pcbKey          Where to store the size of the key in bytes on success.
-     */
-    DECLR3CALLBACKMEMBER(int, pfnKeyRetain, (PPDMISECKEY pInterface, const char *pszId,
-                                             const uint8_t **pbKey, size_t *pcbKey));
-
-    /**
-     * Releases one reference of the key identified by the given identifier.
-     * The caller must not access the key buffer after calling this operation.
-     *
-     * @returns VBox status code.
-     * @param   pInterface      Pointer to this interface.
-     * @param   pszId          The alias/id for the key to release.
-     *
-     * @note: It is advised to release the key whenever it is not used anymore so the entity
-     *        storing the key can do anything to make retrieving the key from memory more
-     *        difficult like scrambling the memory buffer for instance.
-     */
-    DECLR3CALLBACKMEMBER(int, pfnKeyRelease, (PPDMISECKEY pInterface, const char *pszId));
-
-    /**
-     * Retains a password identified by the ID. The caller will only hold a reference
-     * to the password and must not modify the buffer in any way.
-     *
-     * @returns VBox status code.
-     * @param   pInterface      Pointer to this interface.
-     * @param   pszId           The alias/id for the password to retrieve.
-     * @param   ppszPassword    Where to store the pointer to the password on success.
-     */
-    DECLR3CALLBACKMEMBER(int, pfnPasswordRetain, (PPDMISECKEY pInterface, const char *pszId,
-                                                  const char **ppszPassword));
-
-    /**
-     * Releases one reference of the password identified by the given identifier.
-     * The caller must not access the password after calling this operation.
-     *
-     * @returns VBox status code.
-     * @param   pInterface      Pointer to this interface.
-     * @param   pszId           The alias/id for the password to release.
-     *
-     * @note: It is advised to release the password whenever it is not used anymore so the entity
-     *        storing the password can do anything to make retrieving the password from memory more
-     *        difficult like scrambling the memory buffer for instance.
-     */
-    DECLR3CALLBACKMEMBER(int, pfnPasswordRelease, (PPDMISECKEY pInterface, const char *pszId));
-} PDMISECKEY;
-/** PDMISECKEY interface ID. */
-#define PDMISECKEY_IID                           "3d698355-d995-453d-960f-31566a891df2"
-
-/** Pointer to a secret key helper interface. */
-typedef struct PDMISECKEYHLP *PPDMISECKEYHLP;
-
-/**
- * Secret key helper interface for non critical functionality.
- */
-typedef struct PDMISECKEYHLP
-{
-    /**
-     * Notifies the interface provider that a key couldn't be retrieved from the key store.
-     *
-     * @returns VBox status code.
-     * @param   pInterface      Pointer to this interface.
-     */
-    DECLR3CALLBACKMEMBER(int, pfnKeyMissingNotify, (PPDMISECKEYHLP pInterface));
-
-} PDMISECKEYHLP;
-/** PDMISECKEY interface ID. */
-#define PDMISECKEYHLP_IID                        "7be96168-4156-40ac-86d2-3073bf8b318e"
+#define PDMMEDIATYPE_IS_FLOPPY(a_enmType) ( (a_enmType) >= PDMMEDIATYPE_FLOPPY_360 && (a_enmType) <= PDMMEDIATYPE_FLOPPY_2_88 )
+
+/**
+ * Raw command data transfer direction.
+ */
+typedef enum PDMMEDIATXDIR
+{
+    PDMMEDIATXDIR_NONE = 0,
+    PDMMEDIATXDIR_FROM_DEVICE,
+    PDMMEDIATXDIR_TO_DEVICE
+} PDMMEDIATXDIR;
 
 /**
@@ -1501,5 +1294,4 @@
 /**
  * Media interface (up).
- * Makes up the foundation for PDMIBLOCK and PDMIBLOCKBIOS.
  * Pairs with PDMIMEDIAPORT.
  */
@@ -1553,4 +1345,20 @@
      */
     DECLR3CALLBACKMEMBER(int, pfnFlush,(PPDMIMEDIA pInterface));
+
+    /**
+     * Send a raw command to the underlying device (CDROM).
+     * This method is optional (i.e. the function pointer may be NULL).
+     *
+     * @returns VBox status code.
+     * @param   pInterface      Pointer to the interface structure containing the called function pointer.
+     * @param   pbCmd           Offset to start reading from.
+     * @param   enmTxDir        Direction of transfer.
+     * @param   pvBuf           Pointer tp the transfer buffer.
+     * @param   cbBuf           Size of the transfer buffer.
+     * @param   pbSenseKey      Status of the command (when return value is VERR_DEV_IO_ERROR).
+     * @param   cTimeoutMillies Command timeout in milliseconds.
+     * @thread  Any thread.
+     */
+    DECLR3CALLBACKMEMBER(int, pfnSendCmd,(PPDMIMEDIA pInterface, const uint8_t *pbCmd, PDMMEDIATXDIR enmTxDir, void *pvBuf, uint32_t *pcbBuf, uint8_t *pabSense, size_t cbSense, uint32_t cTimeoutMillies));
 
     /**
@@ -1664,4 +1472,23 @@
 
     /**
+     * Checks if the device should be visible to the BIOS or not.
+     *
+     * @returns true if the device is visible to the BIOS.
+     * @returns false if the device is not visible to the BIOS.
+     * @param   pInterface      Pointer to the interface structure containing the called function pointer.
+     * @thread  Any thread.
+     */
+    DECLR3CALLBACKMEMBER(bool, pfnBiosIsVisible,(PPDMIMEDIA pInterface));
+
+    /**
+     * Gets the media type.
+     *
+     * @returns media type.
+     * @param   pInterface      Pointer to the interface structure containing the called function pointer.
+     * @thread  Any thread.
+     */
+    DECLR3CALLBACKMEMBER(PDMMEDIATYPE, pfnGetType,(PPDMIMEDIA pInterface));
+
+    /**
      * Gets the UUID of the media drive.
      *
@@ -1707,199 +1534,5 @@
 } PDMIMEDIA;
 /** PDMIMEDIA interface ID. */
-#define PDMIMEDIA_IID                           "d8997ad8-4dda-4352-aa99-99bf87d54102"
-
-
-/** Pointer to a block BIOS interface. */
-typedef struct PDMIBLOCKBIOS *PPDMIBLOCKBIOS;
-/**
- * Media BIOS interface (Up / External).
- * The interface the getting and setting properties which the BIOS/CMOS care about.
- */
-typedef struct PDMIBLOCKBIOS
-{
-    /**
-     * Get stored media geometry (physical CHS, PCHS) - BIOS property.
-     * This is an optional feature of a media.
-     *
-     * @returns VBox status code.
-     * @returns VERR_NOT_IMPLEMENTED if the media doesn't support storing the geometry.
-     * @returns VERR_PDM_GEOMETRY_NOT_SET if the geometry hasn't been set using pfnSetPCHSGeometry() yet.
-     * @param   pInterface      Pointer to the interface structure containing the called function pointer.
-     * @param   pPCHSGeometry   Pointer to PCHS geometry (cylinders/heads/sectors).
-     * @remark  This has no influence on the read/write operations.
-     * @thread  Any thread.
-     */
-    DECLR3CALLBACKMEMBER(int, pfnGetPCHSGeometry,(PPDMIBLOCKBIOS pInterface, PPDMMEDIAGEOMETRY pPCHSGeometry));
-
-    /**
-     * Store the media geometry (physical CHS, PCHS) - BIOS property.
-     * This is an optional feature of a media.
-     *
-     * @returns VBox status code.
-     * @returns VERR_NOT_IMPLEMENTED if the media doesn't support storing the geometry.
-     * @param   pInterface      Pointer to the interface structure containing the called function pointer.
-     * @param   pPCHSGeometry   Pointer to PCHS geometry (cylinders/heads/sectors).
-     * @remark  This has no influence on the read/write operations.
-     * @thread  The emulation thread.
-     */
-    DECLR3CALLBACKMEMBER(int, pfnSetPCHSGeometry,(PPDMIBLOCKBIOS pInterface, PCPDMMEDIAGEOMETRY pPCHSGeometry));
-
-    /**
-     * Get stored media geometry (logical CHS, LCHS) - BIOS property.
-     * This is an optional feature of a media.
-     *
-     * @returns VBox status code.
-     * @returns VERR_NOT_IMPLEMENTED if the media doesn't support storing the geometry.
-     * @returns VERR_PDM_GEOMETRY_NOT_SET if the geometry hasn't been set using pfnSetLCHSGeometry() yet.
-     * @param   pInterface      Pointer to the interface structure containing the called function pointer.
-     * @param   pLCHSGeometry   Pointer to LCHS geometry (cylinders/heads/sectors).
-     * @remark  This has no influence on the read/write operations.
-     * @thread  Any thread.
-     */
-    DECLR3CALLBACKMEMBER(int, pfnGetLCHSGeometry,(PPDMIBLOCKBIOS pInterface, PPDMMEDIAGEOMETRY pLCHSGeometry));
-
-    /**
-     * Store the media geometry (logical CHS, LCHS) - BIOS property.
-     * This is an optional feature of a media.
-     *
-     * @returns VBox status code.
-     * @returns VERR_NOT_IMPLEMENTED if the media doesn't support storing the geometry.
-     * @param   pInterface      Pointer to the interface structure containing the called function pointer.
-     * @param   pLCHSGeometry   Pointer to LCHS geometry (cylinders/heads/sectors).
-     * @remark  This has no influence on the read/write operations.
-     * @thread  The emulation thread.
-     */
-    DECLR3CALLBACKMEMBER(int, pfnSetLCHSGeometry,(PPDMIBLOCKBIOS pInterface, PCPDMMEDIAGEOMETRY pLCHSGeometry));
-
-    /**
-     * Checks if the device should be visible to the BIOS or not.
-     *
-     * @returns true if the device is visible to the BIOS.
-     * @returns false if the device is not visible to the BIOS.
-     * @param   pInterface      Pointer to the interface structure containing the called function pointer.
-     * @thread  Any thread.
-     */
-    DECLR3CALLBACKMEMBER(bool, pfnIsVisible,(PPDMIBLOCKBIOS pInterface));
-
-    /**
-     * Gets the block drive type.
-     *
-     * @returns block drive type.
-     * @param   pInterface      Pointer to the interface structure containing the called function pointer.
-     * @thread  Any thread.
-     */
-    DECLR3CALLBACKMEMBER(PDMBLOCKTYPE, pfnGetType,(PPDMIBLOCKBIOS pInterface));
-
-} PDMIBLOCKBIOS;
-/** PDMIBLOCKBIOS interface ID. */
-#define PDMIBLOCKBIOS_IID                       "477c3eee-a48d-48a9-82fd-2a54de16b2e9"
-
-
-/** Pointer to a static block core driver interface. */
-typedef struct PDMIMEDIASTATIC *PPDMIMEDIASTATIC;
-/**
- * Static block core driver interface.
- */
-typedef struct PDMIMEDIASTATIC
-{
-    /**
-     * Check if the specified file is a format which the core driver can handle.
-     *
-     * @returns true / false accordingly.
-     * @param   pInterface      Pointer to the interface structure containing the called function pointer.
-     * @param   pszFilename     Name of the file to probe.
-     */
-    DECLR3CALLBACKMEMBER(bool, pfnCanHandle,(PPDMIMEDIASTATIC pInterface, const char *pszFilename));
-} PDMIMEDIASTATIC;
-
-
-
-
-
-/** Pointer to an asynchronous block notify interface. */
-typedef struct PDMIBLOCKASYNCPORT *PPDMIBLOCKASYNCPORT;
-/**
- * Asynchronous block notify interface (up).
- * Pair with PDMIBLOCKASYNC.
- */
-typedef struct PDMIBLOCKASYNCPORT
-{
-    /**
-     * Notify completion of an asynchronous transfer.
-     *
-     * @returns VBox status code.
-     * @param   pInterface      Pointer to the interface structure containing the called function pointer.
-     * @param   pvUser          The user argument given in pfnStartWrite/Read.
-     * @param   rcReq           IPRT Status code of the completed request.
-     * @thread  Any thread.
-     */
-    DECLR3CALLBACKMEMBER(int, pfnTransferCompleteNotify, (PPDMIBLOCKASYNCPORT pInterface, void *pvUser, int rcReq));
-} PDMIBLOCKASYNCPORT;
-/** PDMIBLOCKASYNCPORT interface ID. */
-#define PDMIBLOCKASYNCPORT_IID                  "e3bdc0cb-9d99-41dd-8eec-0dc8cf5b2a92"
-
-
-
-/** Pointer to an asynchronous block interface. */
-typedef struct PDMIBLOCKASYNC *PPDMIBLOCKASYNC;
-/**
- * Asynchronous block interface (down).
- * Pair with PDMIBLOCKASYNCPORT.
- */
-typedef struct PDMIBLOCKASYNC
-{
-    /**
-     * Start reading task.
-     *
-     * @returns VBox status code.
-     * @param   pInterface      Pointer to the interface structure containing the called function pointer.
-     * @param   off             Offset to start reading from.c
-     * @param   paSegs          Pointer to the S/G segment array.
-     * @param   cSegs           Number of entries in the array.
-     * @param   cbRead          Number of bytes to read. Must be aligned to a sector boundary.
-     * @param   pvUser          User argument which is returned in completion callback.
-     * @thread  Any thread.
-     */
-    DECLR3CALLBACKMEMBER(int, pfnStartRead,(PPDMIBLOCKASYNC pInterface, uint64_t off, PCRTSGSEG paSegs, unsigned cSegs, size_t cbRead, void *pvUser));
-
-    /**
-     * Write bits.
-     *
-     * @returns VBox status code.
-     * @param   pInterface      Pointer to the interface structure containing the called function pointer.
-     * @param   off             Offset to start writing at. The offset must be aligned to a sector boundary.
-     * @param   paSegs          Pointer to the S/G segment array.
-     * @param   cSegs           Number of entries in the array.
-     * @param   cbWrite         Number of bytes to write. Must be aligned to a sector boundary.
-     * @param   pvUser          User argument which is returned in completion callback.
-     * @thread  Any thread.
-     */
-    DECLR3CALLBACKMEMBER(int, pfnStartWrite,(PPDMIBLOCKASYNC pInterface, uint64_t off, PCRTSGSEG paSegs, unsigned cSegs, size_t cbWrite, void *pvUser));
-
-    /**
-     * Flush everything to disk.
-     *
-     * @returns VBox status code.
-     * @param   pInterface      Pointer to the interface structure containing the called function pointer.
-     * @param   pvUser          User argument which is returned in completion callback.
-     * @thread  Any thread.
-     */
-    DECLR3CALLBACKMEMBER(int, pfnStartFlush,(PPDMIBLOCKASYNC pInterface, void *pvUser));
-
-    /**
-     * Discards the given range.
-     *
-     * @returns VBox status code.
-     * @param   pInterface      Pointer to the interface structure containing the called function pointer.
-     * @param   paRanges        Array of ranges to discard.
-     * @param   cRanges         Number of entries in the array.
-     * @param   pvUser          User argument which is returned in completion callback.
-     * @thread  Any thread.
-     */
-    DECLR3CALLBACKMEMBER(int, pfnStartDiscard,(PPDMIBLOCKASYNC pInterface, PCRTRANGE paRanges, unsigned cRanges, void *pvUser));
-
-} PDMIBLOCKASYNC;
-/** PDMIBLOCKASYNC interface ID. */
-#define PDMIBLOCKASYNC_IID                      "a921dd96-1748-4ecd-941e-d5f3cd4c8fe4"
+#define PDMIMEDIA_IID                           "352f2fa2-52c0-4e51-ba3c-9f59b7043218"
 
 
Index: trunk/src/VBox/Devices/Makefile.kmk
===================================================================
--- trunk/src/VBox/Devices/Makefile.kmk	(revision 59247)
+++ trunk/src/VBox/Devices/Makefile.kmk	(revision 59248)
@@ -173,7 +173,4 @@
  	Serial/DrvTCP.cpp \
  	Serial/DrvRawFile.cpp \
- 	Storage/DrvBlock.cpp \
- 	Storage/DrvMediaISO.cpp \
- 	Storage/DrvRawImage.cpp \
  	Storage/Debug.cpp \
  	Storage/DrvVD.cpp \
Index: trunk/src/VBox/Devices/PC/DevPcBios.cpp
===================================================================
--- trunk/src/VBox/Devices/PC/DevPcBios.cpp	(revision 59247)
+++ trunk/src/VBox/Devices/PC/DevPcBios.cpp	(revision 59248)
@@ -291,5 +291,5 @@
  * @param   pLCHSGeometry   Where to return the disk geometry on success
  */
-static int biosGuessDiskLCHS(PPDMIBLOCK pBlock, PPDMMEDIAGEOMETRY pLCHSGeometry)
+static int biosGuessDiskLCHS(PPDMIMEDIA pMedia, PPDMMEDIAGEOMETRY pLCHSGeometry)
 {
     uint8_t aMBR[512], *p;
@@ -297,7 +297,7 @@
     uint32_t iEndHead, iEndSector, cLCHSCylinders, cLCHSHeads, cLCHSSectors;
 
-    if (!pBlock)
+    if (!pMedia)
         return VERR_INVALID_PARAMETER;
-    rc = pBlock->pfnReadPcBios(pBlock, 0, aMBR, sizeof(aMBR));
+    rc = pMedia->pfnReadPcBios(pMedia, 0, aMBR, sizeof(aMBR));
     if (RT_FAILURE(rc))
         return rc;
@@ -316,5 +316,5 @@
             cLCHSHeads = iEndHead + 1;
             cLCHSSectors = iEndSector;
-            cLCHSCylinders = RT_MIN(1024, pBlock->pfnGetSize(pBlock) / (512 * cLCHSHeads * cLCHSSectors));
+            cLCHSCylinders = RT_MIN(1024, pMedia->pfnGetSize(pMedia) / (512 * cLCHSHeads * cLCHSSectors));
             if (cLCHSCylinders >= 1)
             {
@@ -397,10 +397,10 @@
  * @param   pLCHSGeometry Where to store the geometry settings.
  */
-static int setLogicalDiskGeometry(PPDMIBASE pBase, PPDMIBLOCKBIOS pHardDisk, PPDMMEDIAGEOMETRY pLCHSGeometry)
+static int setLogicalDiskGeometry(PPDMIBASE pBase, PPDMIMEDIA pHardDisk, PPDMMEDIAGEOMETRY pLCHSGeometry)
 {
     PDMMEDIAGEOMETRY LCHSGeometry;
     int rc = VINF_SUCCESS;
 
-    rc = pHardDisk->pfnGetLCHSGeometry(pHardDisk, &LCHSGeometry);
+    rc = pHardDisk->pfnBiosGetLCHSGeometry(pHardDisk, &LCHSGeometry);
     if (   rc == VERR_PDM_GEOMETRY_NOT_SET
         || LCHSGeometry.cCylinders == 0
@@ -410,12 +410,10 @@
         || LCHSGeometry.cSectors > 63)
     {
-        PPDMIBLOCK pBlock;
-        pBlock = PDMIBASE_QUERY_INTERFACE(pBase, PDMIBLOCK);
         /* No LCHS geometry, autodetect and set. */
-        rc = biosGuessDiskLCHS(pBlock, &LCHSGeometry);
+        rc = biosGuessDiskLCHS(pHardDisk, &LCHSGeometry);
         if (RT_FAILURE(rc))
         {
             /* Try if PCHS geometry works, otherwise fall back. */
-            rc = pHardDisk->pfnGetPCHSGeometry(pHardDisk, &LCHSGeometry);
+            rc = pHardDisk->pfnBiosGetPCHSGeometry(pHardDisk, &LCHSGeometry);
         }
         if (   RT_FAILURE(rc)
@@ -427,5 +425,5 @@
             || LCHSGeometry.cSectors > 63)
         {
-            uint64_t cSectors = pBlock->pfnGetSize(pBlock) / 512;
+            uint64_t cSectors = pHardDisk->pfnGetSize(pHardDisk) / 512;
             if (cSectors / 16 / 63 <= 1024)
             {
@@ -456,5 +454,5 @@
 
         }
-        rc = pHardDisk->pfnSetLCHSGeometry(pHardDisk, &LCHSGeometry);
+        rc = pHardDisk->pfnBiosSetLCHSGeometry(pHardDisk, &LCHSGeometry);
         if (rc == VERR_VD_IMAGE_READ_ONLY)
         {
@@ -483,10 +481,10 @@
  * @param   pLCHSGeometry Where to store the geometry settings.
  */
-static int getLogicalDiskGeometry(PPDMIBLOCKBIOS pHardDisk, PPDMMEDIAGEOMETRY pLCHSGeometry)
+static int getLogicalDiskGeometry(PPDMIMEDIA pHardDisk, PPDMMEDIAGEOMETRY pLCHSGeometry)
 {
     PDMMEDIAGEOMETRY LCHSGeometry;
     int rc = VINF_SUCCESS;
 
-    rc = pHardDisk->pfnGetLCHSGeometry(pHardDisk, &LCHSGeometry);
+    rc = pHardDisk->pfnBiosGetLCHSGeometry(pHardDisk, &LCHSGeometry);
     if (   rc == VERR_PDM_GEOMETRY_NOT_SET
         || LCHSGeometry.cCylinders == 0
@@ -549,5 +547,5 @@
     unsigned        i;
     PUVM            pUVM = PDMDevHlpGetUVM(pDevIns); AssertRelease(pUVM);
-    PPDMIBLOCKBIOS  apHDs[4] = {0};
+    PPDMIMEDIA      apHDs[4] = {0};
     LogFlow(("pcbiosInitComplete:\n"));
 
@@ -642,5 +640,5 @@
         if (RT_SUCCESS(rc))
         {
-            PPDMIBLOCKBIOS pFD = PDMIBASE_QUERY_INTERFACE(pBase, PDMIBLOCKBIOS);
+            PPDMIMEDIA pFD = PDMIBASE_QUERY_INTERFACE(pBase, PDMIMEDIA);
             if (pFD)
             {
@@ -649,11 +647,11 @@
                 switch (pFD->pfnGetType(pFD))
                 {
-                    case PDMBLOCKTYPE_FLOPPY_360:       u32 |= 1  << cShift; break;
-                    case PDMBLOCKTYPE_FLOPPY_1_20:      u32 |= 2  << cShift; break;
-                    case PDMBLOCKTYPE_FLOPPY_720:       u32 |= 3  << cShift; break;
-                    case PDMBLOCKTYPE_FLOPPY_1_44:      u32 |= 4  << cShift; break;
-                    case PDMBLOCKTYPE_FLOPPY_2_88:      u32 |= 5  << cShift; break;
-                    case PDMBLOCKTYPE_FLOPPY_FAKE_15_6: u32 |= 14 << cShift; break;
-                    case PDMBLOCKTYPE_FLOPPY_FAKE_63_5: u32 |= 15 << cShift; break;
+                    case PDMMEDIATYPE_FLOPPY_360:       u32 |= 1  << cShift; break;
+                    case PDMMEDIATYPE_FLOPPY_1_20:      u32 |= 2  << cShift; break;
+                    case PDMMEDIATYPE_FLOPPY_720:       u32 |= 3  << cShift; break;
+                    case PDMMEDIATYPE_FLOPPY_1_44:      u32 |= 4  << cShift; break;
+                    case PDMMEDIATYPE_FLOPPY_2_88:      u32 |= 5  << cShift; break;
+                    case PDMMEDIATYPE_FLOPPY_FAKE_15_6: u32 |= 14 << cShift; break;
+                    case PDMMEDIATYPE_FLOPPY_FAKE_63_5: u32 |= 15 << cShift; break;
                     default:                        AssertFailed(); break;
                 }
@@ -683,8 +681,8 @@
         int rc = PDMR3QueryLun(pUVM, pThis->pszHDDevice, 0, i, &pBase);
         if (RT_SUCCESS(rc))
-            apHDs[i] = PDMIBASE_QUERY_INTERFACE(pBase, PDMIBLOCKBIOS);
+            apHDs[i] = PDMIBASE_QUERY_INTERFACE(pBase, PDMIMEDIA);
         if (   apHDs[i]
-            && (   apHDs[i]->pfnGetType(apHDs[i]) != PDMBLOCKTYPE_HARD_DISK
-                || !apHDs[i]->pfnIsVisible(apHDs[i])))
+            && (   apHDs[i]->pfnGetType(apHDs[i]) != PDMMEDIATYPE_HARD_DISK
+                || !apHDs[i]->pfnBiosIsVisible(apHDs[i])))
             apHDs[i] = NULL;
         if (apHDs[i])
@@ -744,8 +742,8 @@
             int rc = PDMR3QueryLun(pUVM, pThis->pszSataDevice, 0, pThis->iSataHDLUN[i], &pBase);
             if (RT_SUCCESS(rc))
-                apHDs[i] = PDMIBASE_QUERY_INTERFACE(pBase, PDMIBLOCKBIOS);
+                apHDs[i] = PDMIBASE_QUERY_INTERFACE(pBase, PDMIMEDIA);
             if (   apHDs[i]
-                && (   apHDs[i]->pfnGetType(apHDs[i]) != PDMBLOCKTYPE_HARD_DISK
-                    || !apHDs[i]->pfnIsVisible(apHDs[i])))
+                && (   apHDs[i]->pfnGetType(apHDs[i]) != PDMMEDIATYPE_HARD_DISK
+                    || !apHDs[i]->pfnBiosIsVisible(apHDs[i])))
                 apHDs[i] = NULL;
             if (apHDs[i])
@@ -798,8 +796,8 @@
             int rc = PDMR3QueryLun(pUVM, pThis->pszScsiDevice, 0, pThis->iScsiHDLUN[i], &pBase);
             if (RT_SUCCESS(rc))
-                apHDs[i] = PDMIBASE_QUERY_INTERFACE(pBase, PDMIBLOCKBIOS);
+                apHDs[i] = PDMIBASE_QUERY_INTERFACE(pBase, PDMIMEDIA);
             if (   apHDs[i]
-                && (   apHDs[i]->pfnGetType(apHDs[i]) != PDMBLOCKTYPE_HARD_DISK
-                    || !apHDs[i]->pfnIsVisible(apHDs[i])))
+                && (   apHDs[i]->pfnGetType(apHDs[i]) != PDMMEDIATYPE_HARD_DISK
+                    || !apHDs[i]->pfnBiosIsVisible(apHDs[i])))
                 apHDs[i] = NULL;
             if (apHDs[i])
Index: trunk/src/VBox/Devices/Storage/DevAHCI.cpp
===================================================================
--- trunk/src/VBox/Devices/Storage/DevAHCI.cpp	(revision 59247)
+++ trunk/src/VBox/Devices/Storage/DevAHCI.cpp	(revision 59248)
@@ -375,6 +375,6 @@
 /**
  * @implements PDMIBASE
- * @implements PDMIBLOCKPORT
- * @implements PDMIBLOCKASYNCPORT
+ * @implements PDMIMEDIAPORT
+ * @implements PDMIMEDIAASYNCPORT
  * @implements PDMIMOUNTNOTIFY
  */
@@ -505,9 +505,7 @@
     R3PTRTYPE(PPDMIBASE)            pDrvBase;
     /** Pointer to the attached driver's block interface. */
-    R3PTRTYPE(PPDMIBLOCK)           pDrvBlock;
+    R3PTRTYPE(PPDMIMEDIA)           pDrvMedia;
     /** Pointer to the attached driver's async block interface. */
-    R3PTRTYPE(PPDMIBLOCKASYNC)      pDrvBlockAsync;
-    /** Pointer to the attached driver's block bios interface. */
-    R3PTRTYPE(PPDMIBLOCKBIOS)       pDrvBlockBios;
+    R3PTRTYPE(PPDMIMEDIAASYNC)      pDrvMediaAsync;
     /** Pointer to the attached driver's mount interface. */
     R3PTRTYPE(PPDMIMOUNT)           pDrvMount;
@@ -515,7 +513,7 @@
     PDMIBASE                        IBase;
     /** The block port interface. */
-    PDMIBLOCKPORT                   IPort;
+    PDMIMEDIAPORT                   IPort;
     /** The optional block async port interface. */
-    PDMIBLOCKASYNCPORT              IPortAsync;
+    PDMIMEDIAASYNCPORT              IPortAsync;
     /** The mount notify interface. */
     PDMIMOUNTNOTIFY                 IMountNotify;
@@ -971,5 +969,5 @@
 #define PDMIMOUNTNOTIFY_2_PAHCIPORT(pInterface)  ( (PAHCIPort)((uintptr_t)(pInterface) - RT_OFFSETOF(AHCIPort, IMountNotify)) )
 #define PDMIBASE_2_PAHCIPORT(pInterface)         ( (PAHCIPort)((uintptr_t)(pInterface) - RT_OFFSETOF(AHCIPort, IBase)) )
-#define PDMIBLOCKPORT_2_PAHCIPORT(pInterface)    ( (PAHCIPort)((uintptr_t)(pInterface) - RT_OFFSETOF(AHCIPort, IPort)) )
+#define PDMIMEDIAPORT_2_PAHCIPORT(pInterface)    ( (PAHCIPort)((uintptr_t)(pInterface) - RT_OFFSETOF(AHCIPort, IPort)) )
 #define PDMIBASE_2_PAHCI(pInterface)             ( (PAHCI)((uintptr_t)(pInterface) - RT_OFFSETOF(AHCI, IBase)) )
 #define PDMILEDPORTS_2_PAHCI(pInterface)         ( (PAHCI)((uintptr_t)(pInterface) - RT_OFFSETOF(AHCI, ILeds)) )
@@ -2670,6 +2668,6 @@
     PAHCIPort pAhciPort = PDMIBASE_2_PAHCIPORT(pInterface);
     PDMIBASE_RETURN_INTERFACE(pszIID, PDMIBASE, &pAhciPort->IBase);
-    PDMIBASE_RETURN_INTERFACE(pszIID, PDMIBLOCKPORT, &pAhciPort->IPort);
-    PDMIBASE_RETURN_INTERFACE(pszIID, PDMIBLOCKASYNCPORT, &pAhciPort->IPortAsync);
+    PDMIBASE_RETURN_INTERFACE(pszIID, PDMIMEDIAPORT, &pAhciPort->IPort);
+    PDMIBASE_RETURN_INTERFACE(pszIID, PDMIMEDIAASYNCPORT, &pAhciPort->IPortAsync);
     PDMIBASE_RETURN_INTERFACE(pszIID, PDMIMOUNTNOTIFY, &pAhciPort->IMountNotify);
     return NULL;
@@ -2677,10 +2675,10 @@
 
 /**
- * @interface_method_impl{PDMIBLOCKPORT,pfnQueryDeviceLocation}
- */
-static DECLCALLBACK(int) ahciR3PortQueryDeviceLocation(PPDMIBLOCKPORT pInterface, const char **ppcszController,
+ * @interface_method_impl{PDMIMEDIAPORT,pfnQueryDeviceLocation}
+ */
+static DECLCALLBACK(int) ahciR3PortQueryDeviceLocation(PPDMIMEDIAPORT pInterface, const char **ppcszController,
                                                        uint32_t *piInstance, uint32_t *piLUN)
 {
-    PAHCIPort pAhciPort = PDMIBLOCKPORT_2_PAHCIPORT(pInterface);
+    PAHCIPort pAhciPort = PDMIMEDIAPORT_2_PAHCIPORT(pInterface);
     PPDMDEVINS pDevIns = pAhciPort->CTX_SUFF(pDevIns);
 
@@ -3099,7 +3097,7 @@
     p[67] = RT_H2LE_U16(120); /* minimum PIO cycle time without flow control */
     p[68] = RT_H2LE_U16(120); /* minimum PIO cycle time with IORDY flow control */
-    if (   pAhciPort->pDrvBlock->pfnDiscard
+    if (   pAhciPort->pDrvMedia->pfnDiscard
         || ( pAhciPort->fAsyncInterface
-            && pAhciPort->pDrvBlockAsync->pfnStartDiscard)
+            && pAhciPort->pDrvMediaAsync->pfnStartDiscard)
         || pAhciPort->cbSector != 512
         || pAhciPort->fNonRotational)
@@ -3142,7 +3140,7 @@
         p[217] = RT_H2LE_U16(1); /* Non-rotational medium */
 
-    if (   pAhciPort->pDrvBlock->pfnDiscard
+    if (   pAhciPort->pDrvMedia->pfnDiscard
         || (   pAhciPort->fAsyncInterface
-            && pAhciPort->pDrvBlockAsync->pfnStartDiscard)) /** @todo: Set bit 14 in word 69 too? (Deterministic read after TRIM). */
+            && pAhciPort->pDrvMediaAsync->pfnStartDiscard)) /** @todo: Set bit 14 in word 69 too? (Deterministic read after TRIM). */
         p[169] = RT_H2LE_U16(1); /* DATA SET MANAGEMENT command supported. */
 
@@ -4041,9 +4039,9 @@
                     break;
             }
-            rc = pAhciPort->pDrvBlock->pfnSendCmd(pAhciPort->pDrvBlock,
+            rc = pAhciPort->pDrvMedia->pfnSendCmd(pAhciPort->pDrvMedia,
                                                   aATAPICmd,
                                                   pAhciReq->enmTxDir == AHCITXDIR_READ
-                                                  ? PDMBLOCKTXDIR_FROM_DEVICE
-                                                  : PDMBLOCKTXDIR_TO_DEVICE,
+                                                  ? PDMMEDIATXDIR_FROM_DEVICE
+                                                  : PDMMEDIATXDIR_TO_DEVICE,
                                                   pbBuf,
                                                   &cbCurrTX,
@@ -4059,16 +4057,16 @@
     else
     {
-        PDMBLOCKTXDIR enmBlockTxDir = PDMBLOCKTXDIR_NONE;
+        PDMMEDIATXDIR enmBlockTxDir = PDMMEDIATXDIR_NONE;
 
         if (pAhciReq->enmTxDir == AHCITXDIR_READ)
-            enmBlockTxDir = PDMBLOCKTXDIR_FROM_DEVICE;
+            enmBlockTxDir = PDMMEDIATXDIR_FROM_DEVICE;
         else if (pAhciReq->enmTxDir == AHCITXDIR_WRITE)
-            enmBlockTxDir = PDMBLOCKTXDIR_TO_DEVICE;
+            enmBlockTxDir = PDMMEDIATXDIR_TO_DEVICE;
         else if (pAhciReq->enmTxDir == AHCITXDIR_NONE)
-            enmBlockTxDir = PDMBLOCKTXDIR_NONE;
+            enmBlockTxDir = PDMMEDIATXDIR_NONE;
         else
             AssertMsgFailed(("Invalid transfer direction %d\n", pAhciReq->enmTxDir));
 
-        rc = pAhciPort->pDrvBlock->pfnSendCmd(pAhciPort->pDrvBlock,
+        rc = pAhciPort->pDrvMedia->pfnSendCmd(pAhciPort->pDrvMedia,
                                               pAhciReq->aATAPICmd,
                                               enmBlockTxDir,
@@ -5476,9 +5474,9 @@
     {
         if (pAhciReq->cbAlloc)
-            pAhciPort->pDrvBlock->pfnIoBufFree(pAhciPort->pDrvBlock, pAhciReq->pvAlloc, pAhciReq->cbAlloc);
+            pAhciPort->pDrvMedia->pfnIoBufFree(pAhciPort->pDrvMedia, pAhciReq->pvAlloc, pAhciReq->cbAlloc);
 
         pAhciReq->pvAlloc = NULL;
         pAhciReq->cbAlloc = RT_ALIGN_Z(cb, _4K);
-        int rc = pAhciPort->pDrvBlock->pfnIoBufAlloc(pAhciPort->pDrvBlock, pAhciReq->cbAlloc, &pAhciReq->pvAlloc);
+        int rc = pAhciPort->pDrvMedia->pfnIoBufAlloc(pAhciPort->pDrvMedia, pAhciReq->cbAlloc, &pAhciReq->pvAlloc);
         if (RT_FAILURE(rc))
             pAhciReq->pvAlloc = NULL;
@@ -5507,5 +5505,5 @@
         if (pAhciReq->cbAlloc)
         {
-            pAhciPort->pDrvBlock->pfnIoBufFree(pAhciPort->pDrvBlock, pAhciReq->pvAlloc, pAhciReq->cbAlloc);
+            pAhciPort->pDrvMedia->pfnIoBufFree(pAhciPort->pDrvMedia, pAhciReq->pvAlloc, pAhciReq->cbAlloc);
             pAhciReq->cbAlloc = 0;
             pAhciReq->cAllocTooMuch = 0;
@@ -5760,8 +5758,8 @@
 }
 
-/* -=-=-=-=- IBlockAsyncPort -=-=-=-=- */
-
-/** Makes a PAHCIPort out of a PPDMIBLOCKASYNCPORT. */
-#define PDMIBLOCKASYNCPORT_2_PAHCIPORT(pInterface)    ( (PAHCIPort)((uintptr_t)pInterface - RT_OFFSETOF(AHCIPort, IPortAsync)) )
+/* -=-=-=-=- IMediaAsyncPort -=-=-=-=- */
+
+/** Makes a PAHCIPort out of a PPDMIMEDIAASYNCPORT. */
+#define PDMIMEDIAASYNCPORT_2_PAHCIPORT(pInterface)    ( (PAHCIPort)((uintptr_t)pInterface - RT_OFFSETOF(AHCIPort, IPortAsync)) )
 
 static void ahciWarningDiskFull(PPDMDEVINS pDevIns)
@@ -6242,7 +6240,7 @@
  * @param   rcReq        IPRT Status code of the completed request.
  */
-static DECLCALLBACK(int) ahciR3TransferCompleteNotify(PPDMIBLOCKASYNCPORT pInterface, void *pvUser, int rcReq)
-{
-    PAHCIPort pAhciPort = PDMIBLOCKASYNCPORT_2_PAHCIPORT(pInterface);
+static DECLCALLBACK(int) ahciR3TransferCompleteNotify(PPDMIMEDIAASYNCPORT pInterface, void *pvUser, int rcReq)
+{
+    PAHCIPort pAhciPort = PDMIMEDIAASYNCPORT_2_PAHCIPORT(pInterface);
     PAHCIREQ pAhciReq = (PAHCIREQ)pvUser;
 
@@ -6275,5 +6273,5 @@
         case ATA_IDENTIFY_DEVICE:
         {
-            if (pAhciPort->pDrvBlock && !pAhciPort->fATAPI)
+            if (pAhciPort->pDrvMedia && !pAhciPort->fATAPI)
             {
                 uint16_t u16Temp[256];
@@ -6526,7 +6524,7 @@
         {
             if (   (   !pAhciPort->fAsyncInterface
-                    && pAhciPort->pDrvBlock->pfnDiscard)
+                    && pAhciPort->pDrvMedia->pfnDiscard)
                 || (   pAhciPort->fAsyncInterface
-                    && pAhciPort->pDrvBlockAsync->pfnStartDiscard))
+                    && pAhciPort->pDrvMediaAsync->pfnStartDiscard))
             {
                 /* Check that the trim bit is set and all other bits are 0. */
@@ -6672,5 +6670,5 @@
         if (enmTxDir == AHCITXDIR_FLUSH)
         {
-            rc = pAhciPort->pDrvBlockAsync->pfnStartFlush(pAhciPort->pDrvBlockAsync,
+            rc = pAhciPort->pDrvMediaAsync->pfnStartFlush(pAhciPort->pDrvMediaAsync,
                                                           pAhciReq);
         }
@@ -6681,5 +6679,5 @@
             {
                 pAhciPort->Led.Asserted.s.fWriting = pAhciPort->Led.Actual.s.fWriting = 1;
-                rc = pAhciPort->pDrvBlockAsync->pfnStartDiscard(pAhciPort->pDrvBlockAsync, pAhciReq->u.Trim.paRanges,
+                rc = pAhciPort->pDrvMediaAsync->pfnStartDiscard(pAhciPort->pDrvMediaAsync, pAhciReq->u.Trim.paRanges,
                                                                 pAhciReq->u.Trim.cRanges, pAhciReq);
             }
@@ -6688,5 +6686,5 @@
         {
             pAhciPort->Led.Asserted.s.fReading = pAhciPort->Led.Actual.s.fReading = 1;
-            rc = pAhciPort->pDrvBlockAsync->pfnStartRead(pAhciPort->pDrvBlockAsync, pAhciReq->uOffset,
+            rc = pAhciPort->pDrvMediaAsync->pfnStartRead(pAhciPort->pDrvMediaAsync, pAhciReq->uOffset,
                                                          &pAhciReq->u.Io.DataSeg, 1,
                                                          pAhciReq->cbTransfer,
@@ -6696,5 +6694,5 @@
         {
             pAhciPort->Led.Asserted.s.fWriting = pAhciPort->Led.Actual.s.fWriting = 1;
-            rc = pAhciPort->pDrvBlockAsync->pfnStartWrite(pAhciPort->pDrvBlockAsync, pAhciReq->uOffset,
+            rc = pAhciPort->pDrvMediaAsync->pfnStartWrite(pAhciPort->pDrvMediaAsync, pAhciReq->uOffset,
                                                           &pAhciReq->u.Io.DataSeg, 1,
                                                           pAhciReq->cbTransfer,
@@ -6709,5 +6707,5 @@
     {
         if (enmTxDir == AHCITXDIR_FLUSH)
-            rc = pAhciPort->pDrvBlock->pfnFlush(pAhciPort->pDrvBlock);
+            rc = pAhciPort->pDrvMedia->pfnFlush(pAhciPort->pDrvMedia);
         else if (enmTxDir == AHCITXDIR_TRIM)
         {
@@ -6716,5 +6714,5 @@
             {
                 pAhciPort->Led.Asserted.s.fWriting = pAhciPort->Led.Actual.s.fWriting = 1;
-                rc = pAhciPort->pDrvBlock->pfnDiscard(pAhciPort->pDrvBlock, pAhciReq->u.Trim.paRanges,
+                rc = pAhciPort->pDrvMedia->pfnDiscard(pAhciPort->pDrvMedia, pAhciReq->u.Trim.paRanges,
                                                       pAhciReq->u.Trim.cRanges);
                 pAhciPort->Led.Asserted.s.fWriting = pAhciPort->Led.Actual.s.fWriting = 0;
@@ -6724,5 +6722,5 @@
         {
             pAhciPort->Led.Asserted.s.fReading = pAhciPort->Led.Actual.s.fReading = 1;
-            rc = pAhciPort->pDrvBlock->pfnRead(pAhciPort->pDrvBlock, pAhciReq->uOffset,
+            rc = pAhciPort->pDrvMedia->pfnRead(pAhciPort->pDrvMedia, pAhciReq->uOffset,
                                                pAhciReq->u.Io.DataSeg.pvSeg,
                                                pAhciReq->cbTransfer);
@@ -6732,5 +6730,5 @@
         {
             pAhciPort->Led.Asserted.s.fWriting = pAhciPort->Led.Actual.s.fWriting = 1;
-            rc = pAhciPort->pDrvBlock->pfnWrite(pAhciPort->pDrvBlock, pAhciReq->uOffset,
+            rc = pAhciPort->pDrvMedia->pfnWrite(pAhciPort->pDrvMedia, pAhciReq->uOffset,
                                                 pAhciReq->u.Io.DataSeg.pvSeg,
                                                 pAhciReq->cbTransfer);
@@ -7601,10 +7599,10 @@
 
     /* Ignore the call if we're called while being attached. */
-    if (!pAhciPort->pDrvBlock)
+    if (!pAhciPort->pDrvMedia)
         return;
 
     if (pAhciPort->fATAPI)
     {
-        pAhciPort->cTotalSectors = pAhciPort->pDrvBlock->pfnGetSize(pAhciPort->pDrvBlock) / 2048;
+        pAhciPort->cTotalSectors = pAhciPort->pDrvMedia->pfnGetSize(pAhciPort->pDrvMedia) / 2048;
 
         LogRel(("AHCI: LUN#%d: CD/DVD, total number of sectors %Ld, passthrough unchanged\n", pAhciPort->iLUN, pAhciPort->cTotalSectors));
@@ -7662,35 +7660,29 @@
 {
     int          rc = VINF_SUCCESS;
-    PDMBLOCKTYPE enmType;
+    PDMMEDIATYPE enmType;
 
     /*
      * Query the block and blockbios interfaces.
      */
-    pAhciPort->pDrvBlock = PDMIBASE_QUERY_INTERFACE(pAhciPort->pDrvBase, PDMIBLOCK);
-    if (!pAhciPort->pDrvBlock)
+    pAhciPort->pDrvMedia = PDMIBASE_QUERY_INTERFACE(pAhciPort->pDrvBase, PDMIMEDIA);
+    if (!pAhciPort->pDrvMedia)
     {
         AssertMsgFailed(("Configuration error: LUN#%d hasn't a block interface!\n", pAhciPort->iLUN));
         return VERR_PDM_MISSING_INTERFACE;
     }
-    pAhciPort->pDrvBlockBios = PDMIBASE_QUERY_INTERFACE(pAhciPort->pDrvBase, PDMIBLOCKBIOS);
-    if (!pAhciPort->pDrvBlockBios)
-    {
-        AssertMsgFailed(("Configuration error: LUN#%d hasn't a block BIOS interface!\n", pAhciPort->iLUN));
-        return VERR_PDM_MISSING_INTERFACE;
-    }
 
     pAhciPort->pDrvMount = PDMIBASE_QUERY_INTERFACE(pAhciPort->pDrvBase, PDMIMOUNT);
 
     /* Try to get the optional async block interface. */
-    pAhciPort->pDrvBlockAsync = PDMIBASE_QUERY_INTERFACE(pAhciPort->pDrvBase, PDMIBLOCKASYNC);
+    pAhciPort->pDrvMediaAsync = PDMIBASE_QUERY_INTERFACE(pAhciPort->pDrvBase, PDMIMEDIAASYNC);
 
     /*
      * Validate type.
      */
-    enmType = pAhciPort->pDrvBlock->pfnGetType(pAhciPort->pDrvBlock);
-
-    if (   enmType != PDMBLOCKTYPE_HARD_DISK
-        && enmType != PDMBLOCKTYPE_CDROM
-        && enmType != PDMBLOCKTYPE_DVD)
+    enmType = pAhciPort->pDrvMedia->pfnGetType(pAhciPort->pDrvMedia);
+
+    if (   enmType != PDMMEDIATYPE_HARD_DISK
+        && enmType != PDMMEDIATYPE_CDROM
+        && enmType != PDMMEDIATYPE_DVD)
     {
         AssertMsgFailed(("Configuration error: LUN#%d isn't a disk or cd/dvd. enmType=%d\n", pAhciPort->iLUN, enmType));
@@ -7698,5 +7690,5 @@
     }
 
-    if (   (enmType == PDMBLOCKTYPE_CDROM || enmType == PDMBLOCKTYPE_DVD)
+    if (   (enmType == PDMMEDIATYPE_CDROM || enmType == PDMMEDIATYPE_DVD)
         && !pAhciPort->pDrvMount)
     {
@@ -7704,6 +7696,6 @@
         return VERR_INTERNAL_ERROR;
     }
-    pAhciPort->fATAPI = (enmType == PDMBLOCKTYPE_CDROM || enmType == PDMBLOCKTYPE_DVD);
-    pAhciPort->fATAPIPassthrough = pAhciPort->fATAPI ? (pAhciPort->pDrvBlock->pfnSendCmd != NULL) : false;
+    pAhciPort->fATAPI = (enmType == PDMMEDIATYPE_CDROM || enmType == PDMMEDIATYPE_DVD);
+    pAhciPort->fATAPIPassthrough = pAhciPort->fATAPI ? (pAhciPort->pDrvMedia->pfnSendCmd != NULL) : false;
 
     rc = RTCritSectInit(&pAhciPort->CritSectReqsFree);
@@ -7721,5 +7713,5 @@
     if (pAhciPort->fATAPI)
     {
-        pAhciPort->cTotalSectors = pAhciPort->pDrvBlock->pfnGetSize(pAhciPort->pDrvBlock) / 2048;
+        pAhciPort->cTotalSectors = pAhciPort->pDrvMedia->pfnGetSize(pAhciPort->pDrvMedia) / 2048;
         pAhciPort->PCHSGeometry.cCylinders = 0;
         pAhciPort->PCHSGeometry.cHeads     = 0;
@@ -7730,8 +7722,7 @@
     else
     {
-        pAhciPort->cbSector = pAhciPort->pDrvBlock->pfnGetSectorSize(pAhciPort->pDrvBlock);
-        pAhciPort->cTotalSectors = pAhciPort->pDrvBlock->pfnGetSize(pAhciPort->pDrvBlock) / pAhciPort->cbSector;
-        rc = pAhciPort->pDrvBlockBios->pfnGetPCHSGeometry(pAhciPort->pDrvBlockBios,
-                                                          &pAhciPort->PCHSGeometry);
+        pAhciPort->cbSector = pAhciPort->pDrvMedia->pfnGetSectorSize(pAhciPort->pDrvMedia);
+        pAhciPort->cTotalSectors = pAhciPort->pDrvMedia->pfnGetSize(pAhciPort->pDrvMedia) / pAhciPort->cbSector;
+        rc = pAhciPort->pDrvMedia->pfnBiosGetPCHSGeometry(pAhciPort->pDrvMedia, &pAhciPort->PCHSGeometry);
         if (rc == VERR_PDM_MEDIA_NOT_MOUNTED)
         {
@@ -7756,6 +7747,5 @@
             pAhciPort->PCHSGeometry.cSectors = 63;
             /* Set the disk geometry information. Ignore errors. */
-            pAhciPort->pDrvBlockBios->pfnSetPCHSGeometry(pAhciPort->pDrvBlockBios,
-                                                         &pAhciPort->PCHSGeometry);
+            pAhciPort->pDrvMedia->pfnBiosSetPCHSGeometry(pAhciPort->pDrvMedia, &pAhciPort->PCHSGeometry);
             rc = VINF_SUCCESS;
         }
@@ -7764,5 +7754,5 @@
                  pAhciPort->PCHSGeometry.cHeads, pAhciPort->PCHSGeometry.cSectors,
                  pAhciPort->cTotalSectors));
-        if (pAhciPort->pDrvBlock->pfnDiscard)
+        if (pAhciPort->pDrvMedia->pfnDiscard)
             LogRel(("AHCI: LUN#%d: Enabled TRIM support\n", pAhciPort->iLUN));
     }
@@ -7879,6 +7869,6 @@
     RTUUID Uuid;
 
-    if (pAhciPort->pDrvBlock)
-        rc = pAhciPort->pDrvBlock->pfnGetUuid(pAhciPort->pDrvBlock, &Uuid);
+    if (pAhciPort->pDrvMedia)
+        rc = pAhciPort->pDrvMedia->pfnGetUuid(pAhciPort->pDrvMedia, &Uuid);
     else
         RTUuidClear(&Uuid);
@@ -8056,7 +8046,6 @@
      */
     pAhciPort->pDrvBase = NULL;
-    pAhciPort->pDrvBlock = NULL;
-    pAhciPort->pDrvBlockAsync = NULL;
-    pAhciPort->pDrvBlockBios = NULL;
+    pAhciPort->pDrvMedia = NULL;
+    pAhciPort->pDrvMediaAsync = NULL;
 }
 
@@ -8083,6 +8072,6 @@
     AssertMsg(iLUN < pThis->cPortsImpl, ("iLUN=%u", iLUN));
     AssertRelease(!pAhciPort->pDrvBase);
-    AssertRelease(!pAhciPort->pDrvBlock);
-    AssertRelease(!pAhciPort->pDrvBlockAsync);
+    AssertRelease(!pAhciPort->pDrvMedia);
+    AssertRelease(!pAhciPort->pDrvMediaAsync);
     Assert(pAhciPort->iLUN == iLUN);
 
@@ -8113,5 +8102,5 @@
     {
         pAhciPort->pDrvBase = NULL;
-        pAhciPort->pDrvBlock = NULL;
+        pAhciPort->pDrvMedia = NULL;
     }
     else
@@ -8120,5 +8109,5 @@
         RTStrPrintf(szName, sizeof(szName), "Port%d", iLUN);
 
-        if (   pAhciPort->pDrvBlockAsync
+        if (   pAhciPort->pDrvMediaAsync
             && !pAhciPort->fATAPI)
             pAhciPort->fAsyncInterface = true;
@@ -8618,5 +8607,5 @@
              * Otherwise we use a event semaphore and a async I/O thread which processes them.
              */
-            if (pAhciPort->pDrvBlockAsync && pThis->fUseAsyncInterfaceIfAvailable)
+            if (pAhciPort->pDrvMediaAsync && pThis->fUseAsyncInterfaceIfAvailable)
             {
                 LogRel(("AHCI: LUN#%d: using async I/O\n", pAhciPort->iLUN));
Index: trunk/src/VBox/Devices/Storage/DevATA.cpp
===================================================================
--- trunk/src/VBox/Devices/Storage/DevATA.cpp	(revision 59247)
+++ trunk/src/VBox/Devices/Storage/DevATA.cpp	(revision 59248)
@@ -277,7 +277,5 @@
     R3PTRTYPE(PPDMIBASE)            pDrvBase;
     /** Pointer to the attached driver's block interface. */
-    R3PTRTYPE(PPDMIBLOCK)           pDrvBlock;
-    /** Pointer to the attached driver's block bios interface. */
-    R3PTRTYPE(PPDMIBLOCKBIOS)       pDrvBlockBios;
+    R3PTRTYPE(PPDMIMEDIA)           pDrvMedia;
     /** Pointer to the attached driver's mount interface.
      * This is NULL if the driver isn't a removable unit. */
@@ -286,5 +284,5 @@
     PDMIBASE                        IBase;
     /** The block port interface. */
-    PDMIBLOCKPORT                   IPort;
+    PDMIMEDIAPORT                   IPort;
     /** The mount notify interface. */
     PDMIMOUNTNOTIFY                 IMountNotify;
@@ -510,5 +508,5 @@
 #define PDMIBASE_2_PCIATASTATE(pInterface)      ( (PCIATAState *)((uintptr_t)(pInterface) - RT_OFFSETOF(PCIATAState, IBase)) )
 #define PDMILEDPORTS_2_PCIATASTATE(pInterface)  ( (PCIATAState *)((uintptr_t)(pInterface) - RT_OFFSETOF(PCIATAState, ILeds)) )
-#define PDMIBLOCKPORT_2_ATASTATE(pInterface)    ( (ATADevState *)((uintptr_t)(pInterface) - RT_OFFSETOF(ATADevState, IPort)) )
+#define PDMIMEDIAPORT_2_ATASTATE(pInterface)    ( (ATADevState *)((uintptr_t)(pInterface) - RT_OFFSETOF(ATADevState, IPort)) )
 #define PDMIMOUNT_2_ATASTATE(pInterface)        ( (ATADevState *)((uintptr_t)(pInterface) - RT_OFFSETOF(ATADevState, IMount)) )
 #define PDMIMOUNTNOTIFY_2_ATASTATE(pInterface)  ( (ATADevState *)((uintptr_t)(pInterface) - RT_OFFSETOF(ATADevState, IMountNotify)) )
@@ -521,5 +519,5 @@
 #define CONTROLLER_2_DEVINS(pController)       ( (pController)->CTX_SUFF(pDevIns) )
 #define PDMIBASE_2_ATASTATE(pInterface)        ( (ATADevState *)((uintptr_t)(pInterface) - RT_OFFSETOF(ATADevState, IBase)) )
-#define PDMIBLOCKPORT_2_ATASTATE(pInterface)   ( (ATADevState *)((uintptr_t)(pInterface) - RT_OFFSETOF(ATADevState, IPort)) )
+#define PDMIMEDIAPORT_2_ATASTATE(pInterface)   ( (ATADevState *)((uintptr_t)(pInterface) - RT_OFFSETOF(ATADevState, IPort)) )
 
 #ifndef VBOX_DEVICE_STRUCT_TESTCASE
@@ -1210,5 +1208,5 @@
     s->iIOBufferCur = 0;
     s->iIOBufferEnd = 0;
-    s->uTxDir = PDMBLOCKTXDIR_NONE;
+    s->uTxDir = PDMMEDIATXDIR_NONE;
     s->iBeginTransfer = ATAFN_BT_NULL;
     s->iSourceSink = ATAFN_SS_NULL;
@@ -1232,5 +1230,5 @@
     uint16_t *p;
 
-    Assert(s->uTxDir == PDMBLOCKTXDIR_FROM_DEVICE);
+    Assert(s->uTxDir == PDMMEDIATXDIR_FROM_DEVICE);
     Assert(s->cbElementaryTransfer == 512);
 
@@ -1286,5 +1284,5 @@
     p[67] = RT_H2LE_U16(120); /* minimum PIO cycle time without flow control */
     p[68] = RT_H2LE_U16(120); /* minimum PIO cycle time with IORDY flow control */
-    if (   s->pDrvBlock->pfnDiscard
+    if (   s->pDrvMedia->pfnDiscard
         || s->cbSector != 512
         || s->fNonRotational)
@@ -1329,5 +1327,5 @@
     }
 
-    if (s->pDrvBlock->pfnDiscard) /** @todo: Set bit 14 in word 69 too? (Deterministic read after TRIM). */
+    if (s->pDrvMedia->pfnDiscard) /** @todo: Set bit 14 in word 69 too? (Deterministic read after TRIM). */
         p[169] = RT_H2LE_U16(1); /* DATA SET MANAGEMENT command supported. */
     if (s->fNonRotational)
@@ -1346,5 +1344,5 @@
     int rc;
 
-    Assert(s->uTxDir == PDMBLOCKTXDIR_NONE);
+    Assert(s->uTxDir == PDMMEDIATXDIR_NONE);
     Assert(!s->cbElementaryTransfer);
 
@@ -1352,5 +1350,5 @@
 
     STAM_PROFILE_START(&s->StatFlushes, f);
-    rc = s->pDrvBlock->pfnFlush(s->pDrvBlock);
+    rc = s->pDrvMedia->pfnFlush(s->pDrvMedia);
     AssertRC(rc);
     STAM_PROFILE_STOP(&s->StatFlushes, f);
@@ -1367,5 +1365,5 @@
     uint16_t *p;
 
-    Assert(s->uTxDir == PDMBLOCKTXDIR_FROM_DEVICE);
+    Assert(s->uTxDir == PDMMEDIATXDIR_FROM_DEVICE);
     Assert(s->cbElementaryTransfer == 512);
 
@@ -1436,5 +1434,5 @@
         s->uATARegHCyl = 0xeb;
     }
-    else if (s->pDrvBlock)
+    else if (s->pDrvMedia)
     {
         s->uATARegLCyl = 0;
@@ -1592,5 +1590,5 @@
     STAM_PROFILE_ADV_START(&s->StatReads, r);
     s->Led.Asserted.s.fReading = s->Led.Actual.s.fReading = 1;
-    rc = s->pDrvBlock->pfnRead(s->pDrvBlock, u64Sector * s->cbSector, pvBuf, cSectors * s->cbSector);
+    rc = s->pDrvMedia->pfnRead(s->pDrvMedia, u64Sector * s->cbSector, pvBuf, cSectors * s->cbSector);
     s->Led.Actual.s.fReading = 0;
     STAM_PROFILE_ADV_STOP(&s->StatReads, r);
@@ -1626,5 +1624,5 @@
         STAM_PROFILE_ADV_START(&s->StatInstrVDWrites, vw);
 # endif
-    rc = s->pDrvBlock->pfnWrite(s->pDrvBlock, u64Sector * s->cbSector, pvBuf, cSectors * s->cbSector);
+    rc = s->pDrvMedia->pfnWrite(s->pDrvMedia, u64Sector * s->cbSector, pvBuf, cSectors * s->cbSector);
 # ifdef VBOX_INSTRUMENT_DMA_WRITES
     if (s->fDMA)
@@ -1659,5 +1657,5 @@
     else
         s->cbElementaryTransfer = cSectors * s->cbSector;
-    if (s->uTxDir == PDMBLOCKTXDIR_TO_DEVICE)
+    if (s->uTxDir == PDMMEDIATXDIR_TO_DEVICE)
         ataR3CmdOK(s, 0);
 }
@@ -1745,5 +1743,5 @@
     ataSetStatusValue(s, ATA_STAT_READY);
     s->uATARegNSector = (s->uATARegNSector & ~7)
-        | ((s->uTxDir != PDMBLOCKTXDIR_TO_DEVICE) ? ATAPI_INT_REASON_IO : 0)
+        | ((s->uTxDir != PDMMEDIATXDIR_TO_DEVICE) ? ATAPI_INT_REASON_IO : 0)
         | (!s->cbTotalTransfer ? ATAPI_INT_REASON_CD : 0);
     Log2(("%s: interrupt reason %#04x\n", __FUNCTION__, s->uATARegNSector));
@@ -1770,5 +1768,5 @@
     s->iIOBufferCur = 0;
     s->iIOBufferEnd = 0;
-    s->uTxDir = PDMBLOCKTXDIR_NONE;
+    s->uTxDir = PDMMEDIATXDIR_NONE;
     s->iBeginTransfer = ATAFN_BT_NULL;
     s->iSourceSink = ATAFN_SS_NULL;
@@ -1796,5 +1794,5 @@
     s->cbAtapiPassthroughTransfer = s->cbTotalTransfer;
     s->cbPIOTransferLimit = s->uATARegLCyl | (s->uATARegHCyl << 8);
-    if (s->uTxDir == PDMBLOCKTXDIR_TO_DEVICE)
+    if (s->uTxDir == PDMMEDIATXDIR_TO_DEVICE)
         atapiR3CmdOK(s);
 }
@@ -1808,5 +1806,5 @@
      * and replies. */
 # if 0
-    if (s->uTxDir == PDMBLOCKTXDIR_TO_DEVICE)
+    if (s->uTxDir == PDMMEDIATXDIR_TO_DEVICE)
     {
         uint8_t cmd = s->aATAPICmd[0];
@@ -1830,5 +1828,5 @@
             aModeSenseCmd[8] = cbTransfer & 0xff;
             aModeSenseCmd[9] = 0; /* control */
-            rc = s->pDrvBlock->pfnSendCmd(s->pDrvBlock, aModeSenseCmd, PDMBLOCKTXDIR_FROM_DEVICE, aModeSenseResult, &cbTransfer, &uDummySense, 500);
+            rc = s->pDrvMedia->pfnSendCmd(s->pDrvMedia, aModeSenseCmd, PDMMEDIATXDIR_FROM_DEVICE, aModeSenseResult, &cbTransfer, &uDummySense, 500);
             if (RT_FAILURE(rc))
             {
@@ -1871,5 +1869,5 @@
             s->cbTotalTransfer *= s->cbATAPISector;
             if (s->cbTotalTransfer == 0)
-                s->uTxDir = PDMBLOCKTXDIR_NONE;
+                s->uTxDir = PDMMEDIATXDIR_NONE;
         }
     }
@@ -1884,5 +1882,5 @@
     uint32_t cbTransfer, cSectors;
 
-    Assert(s->uTxDir == PDMBLOCKTXDIR_FROM_DEVICE);
+    Assert(s->uTxDir == PDMMEDIATXDIR_FROM_DEVICE);
     cbTransfer = RT_MIN(s->cbTotalTransfer, s->cbIOBuffer);
     cSectors = cbTransfer / s->cbATAPISector;
@@ -1897,5 +1895,5 @@
     {
         case 2048:
-            rc = s->pDrvBlock->pfnRead(s->pDrvBlock, (uint64_t)s->iATAPILBA * s->cbATAPISector, s->CTX_SUFF(pbIOBuffer), s->cbATAPISector * cSectors);
+            rc = s->pDrvMedia->pfnRead(s->pDrvMedia, (uint64_t)s->iATAPILBA * s->cbATAPISector, s->CTX_SUFF(pbIOBuffer), s->cbATAPISector * cSectors);
             break;
         case 2352:
@@ -1915,5 +1913,5 @@
                 *pbBuf++ = 0x01; /* mode 1 data */
                 /* data */
-                rc = s->pDrvBlock->pfnRead(s->pDrvBlock, (uint64_t)i * 2048, pbBuf, 2048);
+                rc = s->pDrvMedia->pfnRead(s->pDrvMedia, (uint64_t)i * 2048, pbBuf, 2048);
                 if (RT_FAILURE(rc))
                     break;
@@ -1986,5 +1984,5 @@
     cbTransfer = RT_MIN(s->cbAtapiPassthroughTransfer, s->cbIOBuffer);
 
-    if (s->uTxDir == PDMBLOCKTXDIR_TO_DEVICE)
+    if (s->uTxDir == PDMMEDIATXDIR_TO_DEVICE)
         Log3(("ATAPI PT data write (%d): %.*Rhxs\n", cbTransfer, cbTransfer, s->CTX_SUFF(pbIOBuffer)));
 
@@ -1993,5 +1991,5 @@
     if (cbTransfer >= 2048)
     {
-        if (s->uTxDir != PDMBLOCKTXDIR_TO_DEVICE)
+        if (s->uTxDir != PDMMEDIATXDIR_TO_DEVICE)
         {
             s->Led.Asserted.s.fReading = s->Led.Actual.s.fReading = 1;
@@ -2117,5 +2115,5 @@
                     break;
             }
-            rc = s->pDrvBlock->pfnSendCmd(s->pDrvBlock, aATAPICmd, (PDMBLOCKTXDIR)s->uTxDir, pbBuf, &cbCurrTX, abATAPISense, sizeof(abATAPISense), 30000 /**< @todo timeout */);
+            rc = s->pDrvMedia->pfnSendCmd(s->pDrvMedia, aATAPICmd, (PDMMEDIATXDIR)s->uTxDir, pbBuf, &cbCurrTX, abATAPISense, sizeof(abATAPISense), 30000 /**< @todo timeout */);
             if (rc != VINF_SUCCESS)
                 break;
@@ -2158,5 +2156,5 @@
     }
     else
-        rc = s->pDrvBlock->pfnSendCmd(s->pDrvBlock, s->aATAPICmd, (PDMBLOCKTXDIR)s->uTxDir, s->CTX_SUFF(pbIOBuffer), &cbTransfer, abATAPISense, sizeof(abATAPISense), 30000 /**< @todo timeout */);
+        rc = s->pDrvMedia->pfnSendCmd(s->pDrvMedia, s->aATAPICmd, (PDMMEDIATXDIR)s->uTxDir, s->CTX_SUFF(pbIOBuffer), &cbTransfer, abATAPISense, sizeof(abATAPISense), 30000 /**< @todo timeout */);
     if (pProf) { STAM_PROFILE_ADV_STOP(pProf, b); }
 
@@ -2168,5 +2166,5 @@
     if (cbTransfer >= 2048)
     {
-        if (s->uTxDir != PDMBLOCKTXDIR_TO_DEVICE)
+        if (s->uTxDir != PDMMEDIATXDIR_TO_DEVICE)
         {
             s->Led.Actual.s.fReading = 0;
@@ -2208,5 +2206,5 @@
         }
 
-        if (s->uTxDir == PDMBLOCKTXDIR_FROM_DEVICE)
+        if (s->uTxDir == PDMMEDIATXDIR_FROM_DEVICE)
         {
             Assert(cbTransfer <= s->cbAtapiPassthroughTransfer);
@@ -2433,5 +2431,5 @@
     s->iATAPILBA = iATAPILBA;
     s->cbATAPISector = cbSector;
-    ataR3StartTransfer(s, cSectors * cbSector, PDMBLOCKTXDIR_FROM_DEVICE, ATAFN_BT_ATAPI_CMD, ATAFN_SS_ATAPI_READ, true);
+    ataR3StartTransfer(s, cSectors * cbSector, PDMMEDIATXDIR_FROM_DEVICE, ATAFN_BT_ATAPI_CMD, ATAFN_SS_ATAPI_READ, true);
     return false;
 }
@@ -2442,5 +2440,5 @@
     uint8_t *pbBuf = s->CTX_SUFF(pbIOBuffer);
 
-    Assert(s->uTxDir == PDMBLOCKTXDIR_FROM_DEVICE);
+    Assert(s->uTxDir == PDMMEDIATXDIR_FROM_DEVICE);
     Assert(s->cbElementaryTransfer <= 8);
     ataH2BE_U32(pbBuf, s->cTotalSectors - 1);
@@ -2456,5 +2454,5 @@
     uint8_t *pbBuf = s->CTX_SUFF(pbIOBuffer);
 
-    Assert(s->uTxDir == PDMBLOCKTXDIR_FROM_DEVICE);
+    Assert(s->uTxDir == PDMMEDIATXDIR_FROM_DEVICE);
     Assert(s->cbElementaryTransfer <= 34);
     memset(pbBuf, '\0', 34);
@@ -2482,5 +2480,5 @@
     uint8_t *pbBuf = s->CTX_SUFF(pbIOBuffer);
 
-    Assert(s->uTxDir == PDMBLOCKTXDIR_FROM_DEVICE);
+    Assert(s->uTxDir == PDMMEDIATXDIR_FROM_DEVICE);
     Assert(s->cbElementaryTransfer <= 36);
     /* Accept address/number type of 1 only, and only track 1 exists. */
@@ -2630,5 +2628,5 @@
     uint16_t u16Sfn = ataBE2H_U16(&s->aATAPICmd[2]);
 
-    Assert(s->uTxDir == PDMBLOCKTXDIR_FROM_DEVICE);
+    Assert(s->uTxDir == PDMMEDIATXDIR_FROM_DEVICE);
     Assert(s->cbElementaryTransfer <= 80);
     /* Accept valid request types only, and only starting feature 0. */
@@ -2694,5 +2692,5 @@
     uint8_t *pbBuf = s->CTX_SUFF(pbIOBuffer);
 
-    Assert(s->uTxDir == PDMBLOCKTXDIR_FROM_DEVICE);
+    Assert(s->uTxDir == PDMMEDIATXDIR_FROM_DEVICE);
     Assert(s->cbElementaryTransfer <= 8);
 
@@ -2769,5 +2767,5 @@
     uint8_t *pbBuf = s->CTX_SUFF(pbIOBuffer);
 
-    Assert(s->uTxDir == PDMBLOCKTXDIR_FROM_DEVICE);
+    Assert(s->uTxDir == PDMMEDIATXDIR_FROM_DEVICE);
     Assert(s->cbElementaryTransfer <= 36);
     pbBuf[0] = 0x05; /* CD-ROM */
@@ -2797,5 +2795,5 @@
     uint8_t *pbBuf = s->CTX_SUFF(pbIOBuffer);
 
-    Assert(s->uTxDir == PDMBLOCKTXDIR_FROM_DEVICE);
+    Assert(s->uTxDir == PDMMEDIATXDIR_FROM_DEVICE);
     Assert(s->cbElementaryTransfer <= 16);
     ataH2BE_U16(&pbBuf[0], 16 + 6);
@@ -2825,5 +2823,5 @@
     uint8_t *pbBuf = s->CTX_SUFF(pbIOBuffer);
 
-    Assert(s->uTxDir == PDMBLOCKTXDIR_FROM_DEVICE);
+    Assert(s->uTxDir == PDMMEDIATXDIR_FROM_DEVICE);
     Assert(s->cbElementaryTransfer <= 40);
     ataH2BE_U16(&pbBuf[0], 38);
@@ -2873,5 +2871,5 @@
     uint8_t *pbBuf = s->CTX_SUFF(pbIOBuffer);
 
-    Assert(s->uTxDir == PDMBLOCKTXDIR_FROM_DEVICE);
+    Assert(s->uTxDir == PDMMEDIATXDIR_FROM_DEVICE);
     memset(pbBuf, '\0', s->cbElementaryTransfer);
     memcpy(pbBuf, s->abATAPISense, RT_MIN(s->cbElementaryTransfer, sizeof(s->abATAPISense)));
@@ -2886,5 +2884,5 @@
     uint8_t *pbBuf = s->CTX_SUFF(pbIOBuffer);
 
-    Assert(s->uTxDir == PDMBLOCKTXDIR_FROM_DEVICE);
+    Assert(s->uTxDir == PDMMEDIATXDIR_FROM_DEVICE);
     Assert(s->cbElementaryTransfer <= 8);
     ataH2BE_U16(pbBuf, 0);
@@ -2907,5 +2905,5 @@
     uint32_t cbSize;
 
-    Assert(s->uTxDir == PDMBLOCKTXDIR_FROM_DEVICE);
+    Assert(s->uTxDir == PDMMEDIATXDIR_FROM_DEVICE);
     fMSF = (s->aATAPICmd[1] >> 1) & 1;
     iStartTrack = s->aATAPICmd[6];
@@ -2968,5 +2966,5 @@
     bool fMSF;
 
-    Assert(s->uTxDir == PDMBLOCKTXDIR_FROM_DEVICE);
+    Assert(s->uTxDir == PDMMEDIATXDIR_FROM_DEVICE);
     Assert(s->cbElementaryTransfer <= 12);
     fMSF = (s->aATAPICmd[1] >> 1) & 1;
@@ -3001,5 +2999,5 @@
     uint32_t cbSize;
 
-    Assert(s->uTxDir == PDMBLOCKTXDIR_FROM_DEVICE);
+    Assert(s->uTxDir == PDMMEDIATXDIR_FROM_DEVICE);
     fMSF = (s->aATAPICmd[1] >> 1) & 1;
     iStartTrack = s->aATAPICmd[6];
@@ -3107,5 +3105,5 @@
         case SCSI_GET_EVENT_STATUS_NOTIFICATION:
             cbMax = ataBE2H_U16(pbPacket + 7);
-            ataR3StartTransfer(s, RT_MIN(cbMax, 8), PDMBLOCKTXDIR_FROM_DEVICE, ATAFN_BT_ATAPI_CMD, ATAFN_SS_ATAPI_GET_EVENT_STATUS_NOTIFICATION, true);
+            ataR3StartTransfer(s, RT_MIN(cbMax, 8), PDMMEDIATXDIR_FROM_DEVICE, ATAFN_BT_ATAPI_CMD, ATAFN_SS_ATAPI_GET_EVENT_STATUS_NOTIFICATION, true);
             break;
         case SCSI_MODE_SENSE_10:
@@ -3121,8 +3119,8 @@
                     {
                         case SCSI_MODEPAGE_ERROR_RECOVERY:
-                            ataR3StartTransfer(s, RT_MIN(cbMax, 16), PDMBLOCKTXDIR_FROM_DEVICE, ATAFN_BT_ATAPI_CMD, ATAFN_SS_ATAPI_MODE_SENSE_ERROR_RECOVERY, true);
+                            ataR3StartTransfer(s, RT_MIN(cbMax, 16), PDMMEDIATXDIR_FROM_DEVICE, ATAFN_BT_ATAPI_CMD, ATAFN_SS_ATAPI_MODE_SENSE_ERROR_RECOVERY, true);
                             break;
                         case SCSI_MODEPAGE_CD_STATUS:
-                            ataR3StartTransfer(s, RT_MIN(cbMax, 40), PDMBLOCKTXDIR_FROM_DEVICE, ATAFN_BT_ATAPI_CMD, ATAFN_SS_ATAPI_MODE_SENSE_CD_STATUS, true);
+                            ataR3StartTransfer(s, RT_MIN(cbMax, 40), PDMMEDIATXDIR_FROM_DEVICE, ATAFN_BT_ATAPI_CMD, ATAFN_SS_ATAPI_MODE_SENSE_CD_STATUS, true);
                             break;
                         default:
@@ -3143,5 +3141,5 @@
         case SCSI_REQUEST_SENSE:
             cbMax = pbPacket[4];
-            ataR3StartTransfer(s, RT_MIN(cbMax, 18), PDMBLOCKTXDIR_FROM_DEVICE, ATAFN_BT_ATAPI_CMD, ATAFN_SS_ATAPI_REQUEST_SENSE, true);
+            ataR3StartTransfer(s, RT_MIN(cbMax, 18), PDMMEDIATXDIR_FROM_DEVICE, ATAFN_BT_ATAPI_CMD, ATAFN_SS_ATAPI_REQUEST_SENSE, true);
             break;
         case SCSI_PREVENT_ALLOW_MEDIUM_REMOVAL:
@@ -3340,5 +3338,5 @@
         {
             cbMax = ataBE2H_U16(pbPacket + 8);
-            ataR3StartTransfer(s, RT_MIN(cbMax, 8), PDMBLOCKTXDIR_FROM_DEVICE, ATAFN_BT_ATAPI_CMD, ATAFN_SS_ATAPI_MECHANISM_STATUS, true);
+            ataR3StartTransfer(s, RT_MIN(cbMax, 8), PDMMEDIATXDIR_FROM_DEVICE, ATAFN_BT_ATAPI_CMD, ATAFN_SS_ATAPI_MECHANISM_STATUS, true);
             break;
         }
@@ -3366,11 +3364,11 @@
             {
                 case 0:
-                    ataR3StartTransfer(s, cbMax, PDMBLOCKTXDIR_FROM_DEVICE, ATAFN_BT_ATAPI_CMD, ATAFN_SS_ATAPI_READ_TOC_NORMAL, true);
+                    ataR3StartTransfer(s, cbMax, PDMMEDIATXDIR_FROM_DEVICE, ATAFN_BT_ATAPI_CMD, ATAFN_SS_ATAPI_READ_TOC_NORMAL, true);
                     break;
                 case 1:
-                    ataR3StartTransfer(s, RT_MIN(cbMax, 12), PDMBLOCKTXDIR_FROM_DEVICE, ATAFN_BT_ATAPI_CMD, ATAFN_SS_ATAPI_READ_TOC_MULTI, true);
+                    ataR3StartTransfer(s, RT_MIN(cbMax, 12), PDMMEDIATXDIR_FROM_DEVICE, ATAFN_BT_ATAPI_CMD, ATAFN_SS_ATAPI_READ_TOC_MULTI, true);
                     break;
                 case 2:
-                    ataR3StartTransfer(s, cbMax, PDMBLOCKTXDIR_FROM_DEVICE, ATAFN_BT_ATAPI_CMD, ATAFN_SS_ATAPI_READ_TOC_RAW, true);
+                    ataR3StartTransfer(s, cbMax, PDMMEDIATXDIR_FROM_DEVICE, ATAFN_BT_ATAPI_CMD, ATAFN_SS_ATAPI_READ_TOC_RAW, true);
                     break;
                 default:
@@ -3393,5 +3391,5 @@
                 break;
             }
-            ataR3StartTransfer(s, 8, PDMBLOCKTXDIR_FROM_DEVICE, ATAFN_BT_ATAPI_CMD, ATAFN_SS_ATAPI_READ_CAPACITY, true);
+            ataR3StartTransfer(s, 8, PDMMEDIATXDIR_FROM_DEVICE, ATAFN_BT_ATAPI_CMD, ATAFN_SS_ATAPI_READ_CAPACITY, true);
             break;
         case SCSI_READ_DISC_INFORMATION:
@@ -3408,5 +3406,5 @@
             }
             cbMax = ataBE2H_U16(pbPacket + 7);
-            ataR3StartTransfer(s, RT_MIN(cbMax, 34), PDMBLOCKTXDIR_FROM_DEVICE, ATAFN_BT_ATAPI_CMD, ATAFN_SS_ATAPI_READ_DISC_INFORMATION, true);
+            ataR3StartTransfer(s, RT_MIN(cbMax, 34), PDMMEDIATXDIR_FROM_DEVICE, ATAFN_BT_ATAPI_CMD, ATAFN_SS_ATAPI_READ_DISC_INFORMATION, true);
             break;
         case SCSI_READ_TRACK_INFORMATION:
@@ -3423,19 +3421,19 @@
             }
             cbMax = ataBE2H_U16(pbPacket + 7);
-            ataR3StartTransfer(s, RT_MIN(cbMax, 36), PDMBLOCKTXDIR_FROM_DEVICE, ATAFN_BT_ATAPI_CMD, ATAFN_SS_ATAPI_READ_TRACK_INFORMATION, true);
+            ataR3StartTransfer(s, RT_MIN(cbMax, 36), PDMMEDIATXDIR_FROM_DEVICE, ATAFN_BT_ATAPI_CMD, ATAFN_SS_ATAPI_READ_TRACK_INFORMATION, true);
             break;
         case SCSI_GET_CONFIGURATION:
             /* No media change stuff here, it can confuse Linux guests. */
             cbMax = ataBE2H_U16(pbPacket + 7);
-            ataR3StartTransfer(s, RT_MIN(cbMax, 80), PDMBLOCKTXDIR_FROM_DEVICE, ATAFN_BT_ATAPI_CMD, ATAFN_SS_ATAPI_GET_CONFIGURATION, true);
+            ataR3StartTransfer(s, RT_MIN(cbMax, 80), PDMMEDIATXDIR_FROM_DEVICE, ATAFN_BT_ATAPI_CMD, ATAFN_SS_ATAPI_GET_CONFIGURATION, true);
             break;
         case SCSI_INQUIRY:
             cbMax = ataBE2H_U16(pbPacket + 3);
-            ataR3StartTransfer(s, RT_MIN(cbMax, 36), PDMBLOCKTXDIR_FROM_DEVICE, ATAFN_BT_ATAPI_CMD, ATAFN_SS_ATAPI_INQUIRY, true);
+            ataR3StartTransfer(s, RT_MIN(cbMax, 36), PDMMEDIATXDIR_FROM_DEVICE, ATAFN_BT_ATAPI_CMD, ATAFN_SS_ATAPI_INQUIRY, true);
             break;
         case SCSI_READ_DVD_STRUCTURE:
         {
             cbMax = ataBE2H_U16(pbPacket + 8);
-            ataR3StartTransfer(s, RT_MIN(cbMax, 4), PDMBLOCKTXDIR_FROM_DEVICE, ATAFN_BT_ATAPI_CMD, ATAFN_SS_ATAPI_READ_DVD_STRUCTURE, true);
+            ataR3StartTransfer(s, RT_MIN(cbMax, 4), PDMMEDIATXDIR_FROM_DEVICE, ATAFN_BT_ATAPI_CMD, ATAFN_SS_ATAPI_READ_DVD_STRUCTURE, true);
             break;
         }
@@ -3456,5 +3454,5 @@
     uint32_t cSectors, iATAPILBA;
     uint32_t cbTransfer = 0;
-    PDMBLOCKTXDIR uTxDir = PDMBLOCKTXDIR_NONE;
+    PDMMEDIATXDIR uTxDir = PDMMEDIATXDIR_NONE;
 
     pbPacket = s->aATAPICmd;
@@ -3470,13 +3468,13 @@
             cbTransfer = ataBE2H_U16(pbPacket + 7);
             Log2(("ATAPI PT: lba %d\n", iATAPILBA));
-            uTxDir = PDMBLOCKTXDIR_TO_DEVICE;
+            uTxDir = PDMMEDIATXDIR_TO_DEVICE;
             goto sendcmd;
         case SCSI_FORMAT_UNIT:
             cbTransfer = s->uATARegLCyl | (s->uATARegHCyl << 8); /* use ATAPI transfer length */
-            uTxDir = PDMBLOCKTXDIR_TO_DEVICE;
+            uTxDir = PDMMEDIATXDIR_TO_DEVICE;
             goto sendcmd;
         case SCSI_GET_CONFIGURATION:
             cbTransfer = ataBE2H_U16(pbPacket + 7);
-            uTxDir = PDMBLOCKTXDIR_FROM_DEVICE;
+            uTxDir = PDMMEDIATXDIR_FROM_DEVICE;
             goto sendcmd;
         case SCSI_GET_EVENT_STATUS_NOTIFICATION:
@@ -3484,16 +3482,16 @@
             if (ASMAtomicReadU32(&s->MediaEventStatus) != ATA_EVENT_STATUS_UNCHANGED)
             {
-                ataR3StartTransfer(s, RT_MIN(cbTransfer, 8), PDMBLOCKTXDIR_FROM_DEVICE, ATAFN_BT_ATAPI_CMD, ATAFN_SS_ATAPI_GET_EVENT_STATUS_NOTIFICATION, true);
+                ataR3StartTransfer(s, RT_MIN(cbTransfer, 8), PDMMEDIATXDIR_FROM_DEVICE, ATAFN_BT_ATAPI_CMD, ATAFN_SS_ATAPI_GET_EVENT_STATUS_NOTIFICATION, true);
                 break;
             }
-            uTxDir = PDMBLOCKTXDIR_FROM_DEVICE;
+            uTxDir = PDMMEDIATXDIR_FROM_DEVICE;
             goto sendcmd;
         case SCSI_GET_PERFORMANCE:
             cbTransfer = s->uATARegLCyl | (s->uATARegHCyl << 8); /* use ATAPI transfer length */
-            uTxDir = PDMBLOCKTXDIR_FROM_DEVICE;
+            uTxDir = PDMMEDIATXDIR_FROM_DEVICE;
             goto sendcmd;
         case SCSI_INQUIRY:
             cbTransfer = ataBE2H_U16(pbPacket + 3);
-            uTxDir = PDMBLOCKTXDIR_FROM_DEVICE;
+            uTxDir = PDMMEDIATXDIR_FROM_DEVICE;
             goto sendcmd;
         case SCSI_LOAD_UNLOAD_MEDIUM:
@@ -3501,13 +3499,13 @@
         case SCSI_MECHANISM_STATUS:
             cbTransfer = ataBE2H_U16(pbPacket + 8);
-            uTxDir = PDMBLOCKTXDIR_FROM_DEVICE;
+            uTxDir = PDMMEDIATXDIR_FROM_DEVICE;
             goto sendcmd;
         case SCSI_MODE_SELECT_10:
             cbTransfer = ataBE2H_U16(pbPacket + 7);
-            uTxDir = PDMBLOCKTXDIR_TO_DEVICE;
+            uTxDir = PDMMEDIATXDIR_TO_DEVICE;
             goto sendcmd;
         case SCSI_MODE_SENSE_10:
             cbTransfer = ataBE2H_U16(pbPacket + 7);
-            uTxDir = PDMBLOCKTXDIR_FROM_DEVICE;
+            uTxDir = PDMMEDIATXDIR_FROM_DEVICE;
             goto sendcmd;
         case SCSI_PAUSE_RESUME:
@@ -3528,5 +3526,5 @@
             s->cbATAPISector = 2048;
             cbTransfer = cSectors * s->cbATAPISector;
-            uTxDir = PDMBLOCKTXDIR_FROM_DEVICE;
+            uTxDir = PDMMEDIATXDIR_FROM_DEVICE;
             goto sendcmd;
         case SCSI_READ_12:
@@ -3536,17 +3534,17 @@
             s->cbATAPISector = 2048;
             cbTransfer = cSectors * s->cbATAPISector;
-            uTxDir = PDMBLOCKTXDIR_FROM_DEVICE;
+            uTxDir = PDMMEDIATXDIR_FROM_DEVICE;
             goto sendcmd;
         case SCSI_READ_BUFFER:
             cbTransfer = ataBE2H_U24(pbPacket + 6);
-            uTxDir = PDMBLOCKTXDIR_FROM_DEVICE;
+            uTxDir = PDMMEDIATXDIR_FROM_DEVICE;
             goto sendcmd;
         case SCSI_READ_BUFFER_CAPACITY:
             cbTransfer = ataBE2H_U16(pbPacket + 7);
-            uTxDir = PDMBLOCKTXDIR_FROM_DEVICE;
+            uTxDir = PDMMEDIATXDIR_FROM_DEVICE;
             goto sendcmd;
         case SCSI_READ_CAPACITY:
             cbTransfer = 8;
-            uTxDir = PDMBLOCKTXDIR_FROM_DEVICE;
+            uTxDir = PDMMEDIATXDIR_FROM_DEVICE;
             goto sendcmd;
         case SCSI_READ_CD:
@@ -3600,30 +3598,30 @@
                 cbTransfer = cSectors * s->cbATAPISector;
             }
-            uTxDir = PDMBLOCKTXDIR_FROM_DEVICE;
+            uTxDir = PDMMEDIATXDIR_FROM_DEVICE;
             goto sendcmd;
         }
         case SCSI_READ_DISC_INFORMATION:
             cbTransfer = ataBE2H_U16(pbPacket + 7);
-            uTxDir = PDMBLOCKTXDIR_FROM_DEVICE;
+            uTxDir = PDMMEDIATXDIR_FROM_DEVICE;
             goto sendcmd;
         case SCSI_READ_DVD_STRUCTURE:
             cbTransfer = ataBE2H_U16(pbPacket + 8);
-            uTxDir = PDMBLOCKTXDIR_FROM_DEVICE;
+            uTxDir = PDMMEDIATXDIR_FROM_DEVICE;
             goto sendcmd;
         case SCSI_READ_FORMAT_CAPACITIES:
             cbTransfer = ataBE2H_U16(pbPacket + 7);
-            uTxDir = PDMBLOCKTXDIR_FROM_DEVICE;
+            uTxDir = PDMMEDIATXDIR_FROM_DEVICE;
             goto sendcmd;
         case SCSI_READ_SUBCHANNEL:
             cbTransfer = ataBE2H_U16(pbPacket + 7);
-            uTxDir = PDMBLOCKTXDIR_FROM_DEVICE;
+            uTxDir = PDMMEDIATXDIR_FROM_DEVICE;
             goto sendcmd;
         case SCSI_READ_TOC_PMA_ATIP:
             cbTransfer = ataBE2H_U16(pbPacket + 7);
-            uTxDir = PDMBLOCKTXDIR_FROM_DEVICE;
+            uTxDir = PDMMEDIATXDIR_FROM_DEVICE;
             goto sendcmd;
         case SCSI_READ_TRACK_INFORMATION:
             cbTransfer = ataBE2H_U16(pbPacket + 7);
-            uTxDir = PDMBLOCKTXDIR_FROM_DEVICE;
+            uTxDir = PDMMEDIATXDIR_FROM_DEVICE;
             goto sendcmd;
         case SCSI_REPAIR_TRACK:
@@ -3631,5 +3629,5 @@
         case SCSI_REPORT_KEY:
             cbTransfer = ataBE2H_U16(pbPacket + 8);
-            uTxDir = PDMBLOCKTXDIR_FROM_DEVICE;
+            uTxDir = PDMMEDIATXDIR_FROM_DEVICE;
             goto sendcmd;
         case SCSI_REQUEST_SENSE:
@@ -3637,8 +3635,8 @@
             if ((s->abATAPISense[2] & 0x0f) != SCSI_SENSE_NONE)
             {
-                ataR3StartTransfer(s, RT_MIN(cbTransfer, 18), PDMBLOCKTXDIR_FROM_DEVICE, ATAFN_BT_ATAPI_CMD, ATAFN_SS_ATAPI_REQUEST_SENSE, true);
+                ataR3StartTransfer(s, RT_MIN(cbTransfer, 18), PDMMEDIATXDIR_FROM_DEVICE, ATAFN_BT_ATAPI_CMD, ATAFN_SS_ATAPI_REQUEST_SENSE, true);
                 break;
             }
-            uTxDir = PDMBLOCKTXDIR_FROM_DEVICE;
+            uTxDir = PDMMEDIATXDIR_FROM_DEVICE;
             goto sendcmd;
         case SCSI_RESERVE_TRACK:
@@ -3650,21 +3648,21 @@
         case SCSI_SEND_CUE_SHEET:
             cbTransfer = ataBE2H_U24(pbPacket + 6);
-            uTxDir = PDMBLOCKTXDIR_TO_DEVICE;
+            uTxDir = PDMMEDIATXDIR_TO_DEVICE;
             goto sendcmd;
         case SCSI_SEND_DVD_STRUCTURE:
             cbTransfer = ataBE2H_U16(pbPacket + 8);
-            uTxDir = PDMBLOCKTXDIR_TO_DEVICE;
+            uTxDir = PDMMEDIATXDIR_TO_DEVICE;
             goto sendcmd;
         case SCSI_SEND_EVENT:
             cbTransfer = ataBE2H_U16(pbPacket + 8);
-            uTxDir = PDMBLOCKTXDIR_TO_DEVICE;
+            uTxDir = PDMMEDIATXDIR_TO_DEVICE;
             goto sendcmd;
         case SCSI_SEND_KEY:
             cbTransfer = ataBE2H_U16(pbPacket + 8);
-            uTxDir = PDMBLOCKTXDIR_TO_DEVICE;
+            uTxDir = PDMMEDIATXDIR_TO_DEVICE;
             goto sendcmd;
         case SCSI_SEND_OPC_INFORMATION:
             cbTransfer = ataBE2H_U16(pbPacket + 7);
-            uTxDir = PDMBLOCKTXDIR_TO_DEVICE;
+            uTxDir = PDMMEDIATXDIR_TO_DEVICE;
             goto sendcmd;
         case SCSI_SET_CD_SPEED:
@@ -3674,5 +3672,5 @@
         case SCSI_SET_STREAMING:
             cbTransfer = ataBE2H_U16(pbPacket + 9);
-            uTxDir = PDMBLOCKTXDIR_TO_DEVICE;
+            uTxDir = PDMMEDIATXDIR_TO_DEVICE;
             goto sendcmd;
         case SCSI_START_STOP_UNIT:
@@ -3696,5 +3694,5 @@
             Log2(("ATAPI PT: lba %d sectors %d sector size %d\n", iATAPILBA, cSectors, s->cbATAPISector));
             cbTransfer = cSectors * s->cbATAPISector;
-            uTxDir = PDMBLOCKTXDIR_TO_DEVICE;
+            uTxDir = PDMMEDIATXDIR_TO_DEVICE;
             goto sendcmd;
         case SCSI_WRITE_12:
@@ -3707,5 +3705,5 @@
             Log2(("ATAPI PT: lba %d sectors %d sector size %d\n", iATAPILBA, cSectors, s->cbATAPISector));
             cbTransfer = cSectors * s->cbATAPISector;
-            uTxDir = PDMBLOCKTXDIR_TO_DEVICE;
+            uTxDir = PDMMEDIATXDIR_TO_DEVICE;
             goto sendcmd;
         case SCSI_WRITE_BUFFER:
@@ -3723,5 +3721,5 @@
                 default:
                     cbTransfer = ataBE2H_U16(pbPacket + 6);
-                    uTxDir = PDMBLOCKTXDIR_TO_DEVICE;
+                    uTxDir = PDMMEDIATXDIR_TO_DEVICE;
                     goto sendcmd;
             }
@@ -3729,5 +3727,5 @@
         case SCSI_REPORT_LUNS: /* Not part of MMC-3, but used by Windows. */
             cbTransfer = ataBE2H_U32(pbPacket + 6);
-            uTxDir = PDMBLOCKTXDIR_FROM_DEVICE;
+            uTxDir = PDMMEDIATXDIR_FROM_DEVICE;
             goto sendcmd;
         case SCSI_REZERO_UNIT:
@@ -3751,5 +3749,5 @@
             Log2(("ATAPI PT: max size %d\n", cbTransfer));
             if (cbTransfer == 0)
-                uTxDir = PDMBLOCKTXDIR_NONE;
+                uTxDir = PDMMEDIATXDIR_NONE;
             ataR3StartTransfer(s, cbTransfer, uTxDir, ATAFN_BT_ATAPI_PASSTHROUGH_CMD, ATAFN_SS_ATAPI_PASSTHROUGH, true);
     }
@@ -3780,5 +3778,5 @@
     s->fDMA = !!(s->uATARegFeature & 1);
     memcpy(s->aATAPICmd, s->CTX_SUFF(pbIOBuffer), ATAPI_PACKET_SIZE);
-    s->uTxDir = PDMBLOCKTXDIR_NONE;
+    s->uTxDir = PDMMEDIATXDIR_NONE;
     s->cbTotalTransfer = 0;
     s->cbElementaryTransfer = 0;
@@ -3834,11 +3832,11 @@
 
     /* Ignore the call if we're called while being attached. */
-    if (!pIf->pDrvBlock)
+    if (!pIf->pDrvMedia)
         return;
 
     if (pIf->fATAPI)
-        pIf->cTotalSectors = pIf->pDrvBlock->pfnGetSize(pIf->pDrvBlock) / 2048;
+        pIf->cTotalSectors = pIf->pDrvMedia->pfnGetSize(pIf->pDrvMedia) / 2048;
     else
-        pIf->cTotalSectors = pIf->pDrvBlock->pfnGetSize(pIf->pDrvBlock) / pIf->cbSector;
+        pIf->cTotalSectors = pIf->pDrvMedia->pfnGetSize(pIf->pDrvMedia) / pIf->cbSector;
 
     LogRel(("PIIX3 ATA: LUN#%d: CD/DVD, total number of sectors %Ld, passthrough unchanged\n", pIf->iLUN, pIf->cTotalSectors));
@@ -3932,5 +3930,5 @@
 
     s->Led.Asserted.s.fWriting = s->Led.Actual.s.fWriting = 1;
-    rc = s->pDrvBlock->pfnDiscard(s->pDrvBlock, &TrimRange, 1);
+    rc = s->pDrvMedia->pfnDiscard(s->pDrvMedia, &TrimRange, 1);
     s->Led.Actual.s.fWriting = 0;
 
@@ -4019,6 +4017,6 @@
     {
         case ATA_IDENTIFY_DEVICE:
-            if (s->pDrvBlock && !s->fATAPI)
-                ataR3StartTransfer(s, 512, PDMBLOCKTXDIR_FROM_DEVICE, ATAFN_BT_NULL, ATAFN_SS_IDENTIFY, false);
+            if (s->pDrvMedia && !s->fATAPI)
+                ataR3StartTransfer(s, 512, PDMMEDIATXDIR_FROM_DEVICE, ATAFN_BT_NULL, ATAFN_SS_IDENTIFY, false);
             else
             {
@@ -4065,8 +4063,8 @@
         case ATA_READ_SECTORS:
         case ATA_READ_SECTORS_WITHOUT_RETRIES:
-            if (!s->pDrvBlock || s->fATAPI)
+            if (!s->pDrvMedia || s->fATAPI)
                 goto abort_cmd;
             s->cSectorsPerIRQ = 1;
-            ataR3StartTransfer(s, ataR3GetNSectors(s) * s->cbSector, PDMBLOCKTXDIR_FROM_DEVICE, ATAFN_BT_READ_WRITE_SECTORS, ATAFN_SS_READ_SECTORS, false);
+            ataR3StartTransfer(s, ataR3GetNSectors(s) * s->cbSector, PDMMEDIATXDIR_FROM_DEVICE, ATAFN_BT_READ_WRITE_SECTORS, ATAFN_SS_READ_SECTORS, false);
             break;
         case ATA_WRITE_SECTORS_EXT:
@@ -4074,24 +4072,24 @@
         case ATA_WRITE_SECTORS:
         case ATA_WRITE_SECTORS_WITHOUT_RETRIES:
-            if (!s->pDrvBlock || s->fATAPI)
+            if (!s->pDrvMedia || s->fATAPI)
                 goto abort_cmd;
             s->cSectorsPerIRQ = 1;
-            ataR3StartTransfer(s, ataR3GetNSectors(s) * s->cbSector, PDMBLOCKTXDIR_TO_DEVICE, ATAFN_BT_READ_WRITE_SECTORS, ATAFN_SS_WRITE_SECTORS, false);
+            ataR3StartTransfer(s, ataR3GetNSectors(s) * s->cbSector, PDMMEDIATXDIR_TO_DEVICE, ATAFN_BT_READ_WRITE_SECTORS, ATAFN_SS_WRITE_SECTORS, false);
             break;
         case ATA_READ_MULTIPLE_EXT:
             s->fLBA48 = true;
         case ATA_READ_MULTIPLE:
-            if (!s->pDrvBlock || !s->cMultSectors || s->fATAPI)
+            if (!s->pDrvMedia || !s->cMultSectors || s->fATAPI)
                 goto abort_cmd;
             s->cSectorsPerIRQ = s->cMultSectors;
-            ataR3StartTransfer(s, ataR3GetNSectors(s) * s->cbSector, PDMBLOCKTXDIR_FROM_DEVICE, ATAFN_BT_READ_WRITE_SECTORS, ATAFN_SS_READ_SECTORS, false);
+            ataR3StartTransfer(s, ataR3GetNSectors(s) * s->cbSector, PDMMEDIATXDIR_FROM_DEVICE, ATAFN_BT_READ_WRITE_SECTORS, ATAFN_SS_READ_SECTORS, false);
             break;
         case ATA_WRITE_MULTIPLE_EXT:
             s->fLBA48 = true;
         case ATA_WRITE_MULTIPLE:
-            if (!s->pDrvBlock || !s->cMultSectors || s->fATAPI)
+            if (!s->pDrvMedia || !s->cMultSectors || s->fATAPI)
                 goto abort_cmd;
             s->cSectorsPerIRQ = s->cMultSectors;
-            ataR3StartTransfer(s, ataR3GetNSectors(s) * s->cbSector, PDMBLOCKTXDIR_TO_DEVICE, ATAFN_BT_READ_WRITE_SECTORS, ATAFN_SS_WRITE_SECTORS, false);
+            ataR3StartTransfer(s, ataR3GetNSectors(s) * s->cbSector, PDMMEDIATXDIR_TO_DEVICE, ATAFN_BT_READ_WRITE_SECTORS, ATAFN_SS_WRITE_SECTORS, false);
             break;
         case ATA_READ_DMA_EXT:
@@ -4099,9 +4097,9 @@
         case ATA_READ_DMA:
         case ATA_READ_DMA_WITHOUT_RETRIES:
-            if (!s->pDrvBlock || s->fATAPI)
+            if (!s->pDrvMedia || s->fATAPI)
                 goto abort_cmd;
             s->cSectorsPerIRQ = ATA_MAX_MULT_SECTORS;
             s->fDMA = true;
-            ataR3StartTransfer(s, ataR3GetNSectors(s) * s->cbSector, PDMBLOCKTXDIR_FROM_DEVICE, ATAFN_BT_READ_WRITE_SECTORS, ATAFN_SS_READ_SECTORS, false);
+            ataR3StartTransfer(s, ataR3GetNSectors(s) * s->cbSector, PDMMEDIATXDIR_FROM_DEVICE, ATAFN_BT_READ_WRITE_SECTORS, ATAFN_SS_READ_SECTORS, false);
             break;
         case ATA_WRITE_DMA_EXT:
@@ -4109,9 +4107,9 @@
         case ATA_WRITE_DMA:
         case ATA_WRITE_DMA_WITHOUT_RETRIES:
-            if (!s->pDrvBlock || s->fATAPI)
+            if (!s->pDrvMedia || s->fATAPI)
                 goto abort_cmd;
             s->cSectorsPerIRQ = ATA_MAX_MULT_SECTORS;
             s->fDMA = true;
-            ataR3StartTransfer(s, ataR3GetNSectors(s) * s->cbSector, PDMBLOCKTXDIR_TO_DEVICE, ATAFN_BT_READ_WRITE_SECTORS, ATAFN_SS_WRITE_SECTORS, false);
+            ataR3StartTransfer(s, ataR3GetNSectors(s) * s->cbSector, PDMMEDIATXDIR_TO_DEVICE, ATAFN_BT_READ_WRITE_SECTORS, ATAFN_SS_WRITE_SECTORS, false);
             break;
         case ATA_READ_NATIVE_MAX_ADDRESS_EXT:
@@ -4137,5 +4135,5 @@
         case ATA_SET_FEATURES:
             Log2(("%s: feature=%#x\n", __FUNCTION__, s->uATARegFeature));
-            if (!s->pDrvBlock)
+            if (!s->pDrvMedia)
                 goto abort_cmd;
             switch (s->uATARegFeature)
@@ -4170,5 +4168,5 @@
                     /* As per the ATA/ATAPI-6 specs, a write cache disable
                      * command MUST flush the write buffers to disc. */
-                    ataR3StartTransfer(s, 0, PDMBLOCKTXDIR_NONE, ATAFN_BT_NULL, ATAFN_SS_FLUSH, false);
+                    ataR3StartTransfer(s, 0, PDMMEDIATXDIR_NONE, ATAFN_BT_NULL, ATAFN_SS_FLUSH, false);
                     break;
                 case 0x03: { /* set transfer mode */
@@ -4205,7 +4203,7 @@
         case ATA_FLUSH_CACHE_EXT:
         case ATA_FLUSH_CACHE:
-            if (!s->pDrvBlock || s->fATAPI)
+            if (!s->pDrvMedia || s->fATAPI)
                 goto abort_cmd;
-            ataR3StartTransfer(s, 0, PDMBLOCKTXDIR_NONE, ATAFN_BT_NULL, ATAFN_SS_FLUSH, false);
+            ataR3StartTransfer(s, 0, PDMMEDIATXDIR_NONE, ATAFN_BT_NULL, ATAFN_SS_FLUSH, false);
             break;
         case ATA_STANDBY_IMMEDIATE:
@@ -4224,5 +4222,5 @@
         case ATA_IDENTIFY_PACKET_DEVICE:
             if (s->fATAPI)
-                ataR3StartTransfer(s, 512, PDMBLOCKTXDIR_FROM_DEVICE, ATAFN_BT_NULL, ATAFN_SS_ATAPI_IDENTIFY, false);
+                ataR3StartTransfer(s, 512, PDMMEDIATXDIR_FROM_DEVICE, ATAFN_BT_NULL, ATAFN_SS_ATAPI_IDENTIFY, false);
             else
             {
@@ -4232,5 +4230,5 @@
             break;
         case ATA_EXECUTE_DEVICE_DIAGNOSTIC:
-            ataR3StartTransfer(s, 0, PDMBLOCKTXDIR_NONE, ATAFN_BT_NULL, ATAFN_SS_EXECUTE_DEVICE_DIAGNOSTIC, false);
+            ataR3StartTransfer(s, 0, PDMMEDIATXDIR_NONE, ATAFN_BT_NULL, ATAFN_SS_EXECUTE_DEVICE_DIAGNOSTIC, false);
             break;
         case ATA_DEVICE_RESET:
@@ -4246,8 +4244,8 @@
             if (s->uATARegFeature & 0x02)
                 goto abort_cmd;
-            ataR3StartTransfer(s, ATAPI_PACKET_SIZE, PDMBLOCKTXDIR_TO_DEVICE, ATAFN_BT_PACKET, ATAFN_SS_PACKET, false);
+            ataR3StartTransfer(s, ATAPI_PACKET_SIZE, PDMMEDIATXDIR_TO_DEVICE, ATAFN_BT_PACKET, ATAFN_SS_PACKET, false);
             break;
         case ATA_DATA_SET_MANAGEMENT:
-            if (!s->pDrvBlock || !s->pDrvBlock->pfnDiscard)
+            if (!s->pDrvMedia || !s->pDrvMedia->pfnDiscard)
                 goto abort_cmd;
             if (   !(s->uATARegFeature & UINT8_C(0x01))
@@ -4255,5 +4253,5 @@
                 goto abort_cmd;
             s->fDMA = true;
-            ataR3StartTransfer(s, (s->uATARegNSectorHOB << 8 | s->uATARegNSector) * s->cbSector, PDMBLOCKTXDIR_TO_DEVICE, ATAFN_BT_NULL, ATAFN_SS_TRIM, false);
+            ataR3StartTransfer(s, (s->uATARegNSectorHOB << 8 | s->uATARegNSector) * s->cbSector, PDMMEDIATXDIR_TO_DEVICE, ATAFN_BT_NULL, ATAFN_SS_TRIM, false);
             break;
         default:
@@ -4385,5 +4383,5 @@
         case 7: /* command */
             /* ignore commands to non-existent device */
-            if (pCtl->iSelectedIf && !pCtl->aIfs[pCtl->iSelectedIf].pDrvBlock)
+            if (pCtl->iSelectedIf && !pCtl->aIfs[pCtl->iSelectedIf].pDrvMedia)
                 break;
 #ifndef IN_RING3
@@ -4405,9 +4403,9 @@
 
     /* Check if the guest is reading from a non-existent device. */
-    if (!s->pDrvBlock)
+    if (!s->pDrvMedia)
     {
         if (pCtl->iSelectedIf)  /* Device 1 selected, Device 0 responding for it. */
         {
-            if (!pCtl->aIfs[0].pDrvBlock)   /** @todo this case should never get here! */
+            if (!pCtl->aIfs[0].pDrvMedia)   /** @todo this case should never get here! */
             {
                 Log2(("%s: addr=%#x: no device on channel\n", __FUNCTION__, addr));
@@ -4440,5 +4438,5 @@
              * the feature register (write-only), so it seems that it's not
              * necessary to support the usual HOB readback here. */
-            if (!s->pDrvBlock)
+            if (!s->pDrvMedia)
                 val = 0;
             else
@@ -4473,5 +4471,5 @@
              * one drive attached to the controller. It is common between
              * both drives anyway (completely identical content). */
-            if (!pCtl->aIfs[0].pDrvBlock && !pCtl->aIfs[1].pDrvBlock)
+            if (!pCtl->aIfs[0].pDrvMedia && !pCtl->aIfs[1].pDrvMedia)
                 val = 0;
             else
@@ -4484,5 +4482,5 @@
             static unsigned cBusy = 0;
 
-            if (!s->pDrvBlock)
+            if (!s->pDrvMedia)
                 val = 0;
             else
@@ -4569,7 +4567,7 @@
     //@todo: The handler should not be even registered if there
     // is no device on an IDE channel.
-    if (!pCtl->aIfs[0].pDrvBlock && !pCtl->aIfs[1].pDrvBlock)
+    if (!pCtl->aIfs[0].pDrvMedia && !pCtl->aIfs[1].pDrvMedia)
         val = 0xff;
-    else if (pCtl->iSelectedIf == 1 && !s->pDrvBlock)
+    else if (pCtl->iSelectedIf == 1 && !s->pDrvMedia)
         val = 0;    /* Device 1 selected, Device 0 responding for it. */
     else
@@ -4701,5 +4699,5 @@
     {
 # ifdef IN_RING3
-        LogRel(("PIIX3 ATA: LUN#%d: %s data in the middle of a PIO transfer - VERY SLOW\n", s->iLUN, s->uTxDir == PDMBLOCKTXDIR_FROM_DEVICE ? "loading" : "storing"));
+        LogRel(("PIIX3 ATA: LUN#%d: %s data in the middle of a PIO transfer - VERY SLOW\n", s->iLUN, s->uTxDir == PDMMEDIATXDIR_FROM_DEVICE ? "loading" : "storing"));
         /* Any guest OS that triggers this case has a pathetic ATA driver.
          * In a real system it would block the CPU via IORDY, here we do it
@@ -4729,9 +4727,9 @@
             ataHCPIOTransferLimitATAPI(s);
 
-        if (s->uTxDir == PDMBLOCKTXDIR_TO_DEVICE && s->cbElementaryTransfer > s->cbTotalTransfer)
+        if (s->uTxDir == PDMMEDIATXDIR_TO_DEVICE && s->cbElementaryTransfer > s->cbTotalTransfer)
             s->cbElementaryTransfer = s->cbTotalTransfer;
 
         Log2(("%s: %s tx_size=%d elem_tx_size=%d index=%d end=%d\n",
-             __FUNCTION__, s->uTxDir == PDMBLOCKTXDIR_FROM_DEVICE ? "T2I" : "I2T",
+             __FUNCTION__, s->uTxDir == PDMMEDIATXDIR_FROM_DEVICE ? "T2I" : "I2T",
              s->cbTotalTransfer, s->cbElementaryTransfer,
              s->iIOBufferCur, s->iIOBufferEnd));
@@ -4740,5 +4738,5 @@
         s->iIOBufferCur += s->cbElementaryTransfer;
 
-        if (s->uTxDir == PDMBLOCKTXDIR_FROM_DEVICE && s->cbElementaryTransfer > s->cbTotalTransfer)
+        if (s->uTxDir == PDMMEDIATXDIR_FROM_DEVICE && s->cbElementaryTransfer > s->cbTotalTransfer)
             s->cbElementaryTransfer = s->cbTotalTransfer;
     }
@@ -4758,5 +4756,5 @@
     }
 
-    if (   s->uTxDir == PDMBLOCKTXDIR_TO_DEVICE
+    if (   s->uTxDir == PDMMEDIATXDIR_TO_DEVICE
         || (   s->iSourceSink != ATAFN_SS_NULL
             && s->iIOBufferCur >= s->iIOBufferEnd))
@@ -4898,5 +4896,5 @@
         if (s->iIOBufferPIODataStart < s->iIOBufferPIODataEnd)
         {
-            Assert(s->uTxDir == PDMBLOCKTXDIR_TO_DEVICE);
+            Assert(s->uTxDir == PDMMEDIATXDIR_TO_DEVICE);
             uint8_t       *pbDst = s->CTX_SUFF(pbIOBuffer) + s->iIOBufferPIODataStart;
             uint8_t const *pbSrc = (uint8_t const *)&u32;
@@ -4915,5 +4913,5 @@
             if (s->iIOBufferPIODataStart + cb < s->iIOBufferPIODataEnd)
                 ataCopyPioData124(s, pbDst, pbSrc, cb);
-            else if (s->uTxDir == PDMBLOCKTXDIR_TO_DEVICE) /* paranoia */
+            else if (s->uTxDir == PDMMEDIATXDIR_TO_DEVICE) /* paranoia */
             {
                 ataCopyPioData124(s, pbDst, pbSrc, cb);
@@ -4970,5 +4968,5 @@
         if (s->iIOBufferPIODataStart < s->iIOBufferPIODataEnd)
         {
-            Assert(s->uTxDir == PDMBLOCKTXDIR_FROM_DEVICE);
+            Assert(s->uTxDir == PDMMEDIATXDIR_FROM_DEVICE);
             uint8_t const *pbSrc = s->CTX_SUFF(pbIOBuffer) + s->iIOBufferPIODataStart;
             uint8_t       *pbDst = (uint8_t *)pu32;
@@ -5227,5 +5225,5 @@
     uint32_t iIOBufferCur, iIOBufferEnd;
     uint32_t dmalen;
-    PDMBLOCKTXDIR uTxDir;
+    PDMMEDIATXDIR uTxDir;
     bool fLastDesc = false;
 
@@ -5235,5 +5233,5 @@
     if (RT_LIKELY(!fRedo))
         Assert(s->cbTotalTransfer);
-    uTxDir = (PDMBLOCKTXDIR)s->uTxDir;
+    uTxDir = (PDMMEDIATXDIR)s->uTxDir;
     cbTotalTransfer = s->cbTotalTransfer;
     cbElementaryTransfer = s->cbElementaryTransfer;
@@ -5247,5 +5245,5 @@
 
     Log2(("%s: %s tx_size=%d elem_tx_size=%d index=%d end=%d\n",
-         __FUNCTION__, uTxDir == PDMBLOCKTXDIR_FROM_DEVICE ? "T2I" : "I2T",
+         __FUNCTION__, uTxDir == PDMMEDIATXDIR_FROM_DEVICE ? "T2I" : "I2T",
          cbTotalTransfer, cbElementaryTransfer,
          iIOBufferCur, iIOBufferEnd));
@@ -5285,5 +5283,5 @@
                 PCIATAState *pATAState = PDMINS_2_DATA(pDevIns, PCIATAState *);
                 AssertPtr(pATAState);
-                if (uTxDir == PDMBLOCKTXDIR_FROM_DEVICE)
+                if (uTxDir == PDMMEDIATXDIR_FROM_DEVICE)
                     PDMDevHlpPCIPhysWrite(pDevIns, pBuffer, s->CTX_SUFF(pbIOBuffer) + iIOBufferCur, dmalen);
                 else
@@ -5296,7 +5294,7 @@
             }
             if (    iIOBufferCur == iIOBufferEnd
-                &&  (uTxDir == PDMBLOCKTXDIR_TO_DEVICE || cbTotalTransfer))
+                &&  (uTxDir == PDMMEDIATXDIR_TO_DEVICE || cbTotalTransfer))
             {
-                if (uTxDir == PDMBLOCKTXDIR_FROM_DEVICE && cbElementaryTransfer > cbTotalTransfer)
+                if (uTxDir == PDMMEDIATXDIR_FROM_DEVICE && cbElementaryTransfer > cbTotalTransfer)
                     cbElementaryTransfer = cbTotalTransfer;
 
@@ -5331,5 +5329,5 @@
                         cbElementaryTransfer = s->cbElementaryTransfer;
 
-                        if (uTxDir == PDMBLOCKTXDIR_TO_DEVICE && cbElementaryTransfer > cbTotalTransfer)
+                        if (uTxDir == PDMMEDIATXDIR_TO_DEVICE && cbElementaryTransfer > cbTotalTransfer)
                             cbElementaryTransfer = cbTotalTransfer;
                         iIOBufferCur = 0;
@@ -5550,5 +5548,5 @@
                     g_apfnBeginTransFuncs[s->iBeginTransfer](s);
                     s->iBeginTransfer = ATAFN_BT_NULL;
-                    if (s->uTxDir != PDMBLOCKTXDIR_FROM_DEVICE)
+                    if (s->uTxDir != PDMMEDIATXDIR_FROM_DEVICE)
                         s->iIOBufferEnd = s->cbElementaryTransfer;
                 }
@@ -5560,5 +5558,5 @@
                 s->iIOBufferCur = 0;
 
-                if (s->uTxDir != PDMBLOCKTXDIR_TO_DEVICE)
+                if (s->uTxDir != PDMMEDIATXDIR_TO_DEVICE)
                 {
                     if (s->iSourceSink != ATAFN_SS_NULL)
@@ -5607,5 +5605,5 @@
                     else
                     {
-                        Assert(s->uTxDir == PDMBLOCKTXDIR_NONE); /* Any transfer which has an initial transfer size of 0 must be marked as such. */
+                        Assert(s->uTxDir == PDMMEDIATXDIR_NONE); /* Any transfer which has an initial transfer size of 0 must be marked as such. */
                         /* Finish DMA transfer. */
                         ataR3DMATransferStop(s);
@@ -5620,8 +5618,8 @@
                         ataHCPIOTransfer(pCtl);
                         Assert(!pCtl->fRedo);
-                        if (s->fATAPITransfer || s->uTxDir != PDMBLOCKTXDIR_TO_DEVICE)
+                        if (s->fATAPITransfer || s->uTxDir != PDMMEDIATXDIR_TO_DEVICE)
                             ataHCSetIRQ(s);
 
-                        if (s->uTxDir == PDMBLOCKTXDIR_TO_DEVICE || s->iSourceSink != ATAFN_SS_NULL)
+                        if (s->uTxDir == PDMMEDIATXDIR_TO_DEVICE || s->iSourceSink != ATAFN_SS_NULL)
                         {
                             /* Write operations and not yet finished transfers
@@ -5644,5 +5642,5 @@
                     else
                     {
-                        Assert(s->uTxDir == PDMBLOCKTXDIR_NONE); /* Any transfer which has an initial transfer size of 0 must be marked as such. */
+                        Assert(s->uTxDir == PDMMEDIATXDIR_NONE); /* Any transfer which has an initial transfer size of 0 must be marked as such. */
                         /* Finish PIO transfer. */
                         ataHCPIOTransfer(pCtl);
@@ -5661,5 +5659,5 @@
                 ATAFNSS iOriginalSourceSink = (ATAFNSS)s->iSourceSink; /* Used by the hack below, but gets reset by then. */
 
-                if (s->uTxDir == PDMBLOCKTXDIR_FROM_DEVICE)
+                if (s->uTxDir == PDMMEDIATXDIR_FROM_DEVICE)
                     AssertRelease(bm->u8Cmd & BM_CMD_WRITE);
                 else
@@ -5749,5 +5747,5 @@
                     ataHCSetIRQ(s);
 
-                    if (s->uTxDir == PDMBLOCKTXDIR_TO_DEVICE || s->iSourceSink != ATAFN_SS_NULL)
+                    if (s->uTxDir == PDMMEDIATXDIR_TO_DEVICE || s->iSourceSink != ATAFN_SS_NULL)
                     {
                         /* Write operations and not yet finished transfers
@@ -5774,5 +5772,5 @@
                     if (    !pCtl->fChainedTransfer
                         &&  !s->fATAPITransfer
-                        &&  s->uTxDir != PDMBLOCKTXDIR_FROM_DEVICE)
+                        &&  s->uTxDir != PDMMEDIATXDIR_FROM_DEVICE)
                     {
                             ataHCSetIRQ(s);
@@ -6186,5 +6184,5 @@
     ATADevState *pIf = PDMIBASE_2_ATASTATE(pInterface);
     PDMIBASE_RETURN_INTERFACE(pszIID, PDMIBASE, &pIf->IBase);
-    PDMIBASE_RETURN_INTERFACE(pszIID, PDMIBLOCKPORT, &pIf->IPort);
+    PDMIBASE_RETURN_INTERFACE(pszIID, PDMIMEDIAPORT, &pIf->IPort);
     PDMIBASE_RETURN_INTERFACE(pszIID, PDMIMOUNTNOTIFY, &pIf->IMountNotify);
     return NULL;
@@ -6195,10 +6193,10 @@
 
 /**
- * @interface_method_impl{PDMIBLOCKPORT,pfnQueryDeviceLocation}
+ * @interface_method_impl{PDMIMEDIAPORT,pfnQueryDeviceLocation}
  */
-static DECLCALLBACK(int) ataR3QueryDeviceLocation(PPDMIBLOCKPORT pInterface, const char **ppcszController,
+static DECLCALLBACK(int) ataR3QueryDeviceLocation(PPDMIMEDIAPORT pInterface, const char **ppcszController,
                                                   uint32_t *piInstance, uint32_t *piLUN)
 {
-    ATADevState *pIf = PDMIBLOCKPORT_2_ATASTATE(pInterface);
+    ATADevState *pIf = PDMIMEDIAPORT_2_ATASTATE(pInterface);
     PPDMDEVINS pDevIns = pIf->CTX_SUFF(pDevIns);
 
@@ -6387,6 +6385,5 @@
      */
     pIf->pDrvBase = NULL;
-    pIf->pDrvBlock = NULL;
-    pIf->pDrvBlockBios = NULL;
+    pIf->pDrvMedia = NULL;
     pIf->pDrvMount = NULL;
 
@@ -6408,11 +6405,11 @@
 {
     int             rc = VINF_SUCCESS;
-    PDMBLOCKTYPE    enmType;
+    PDMMEDIATYPE    enmType;
 
     /*
      * Query Block, Bios and Mount interfaces.
      */
-    pIf->pDrvBlock = PDMIBASE_QUERY_INTERFACE(pIf->pDrvBase, PDMIBLOCK);
-    if (!pIf->pDrvBlock)
+    pIf->pDrvMedia = PDMIBASE_QUERY_INTERFACE(pIf->pDrvBase, PDMIMEDIA);
+    if (!pIf->pDrvMedia)
     {
         AssertMsgFailed(("Configuration error: LUN#%d hasn't a block interface!\n", pIf->iLUN));
@@ -6420,11 +6417,4 @@
     }
 
-    /** @todo implement the BIOS invisible code path. */
-    pIf->pDrvBlockBios = PDMIBASE_QUERY_INTERFACE(pIf->pDrvBase, PDMIBLOCKBIOS);
-    if (!pIf->pDrvBlockBios)
-    {
-        AssertMsgFailed(("Configuration error: LUN#%d hasn't a block BIOS interface!\n", pIf->iLUN));
-        return VERR_PDM_MISSING_INTERFACE;
-    }
     pIf->pDrvMount = PDMIBASE_QUERY_INTERFACE(pIf->pDrvBase, PDMIMOUNT);
 
@@ -6432,14 +6422,14 @@
      * Validate type.
      */
-    enmType = pIf->pDrvBlock->pfnGetType(pIf->pDrvBlock);
-    if (    enmType != PDMBLOCKTYPE_CDROM
-        &&  enmType != PDMBLOCKTYPE_DVD
-        &&  enmType != PDMBLOCKTYPE_HARD_DISK)
+    enmType = pIf->pDrvMedia->pfnGetType(pIf->pDrvMedia);
+    if (    enmType != PDMMEDIATYPE_CDROM
+        &&  enmType != PDMMEDIATYPE_DVD
+        &&  enmType != PDMMEDIATYPE_HARD_DISK)
     {
         AssertMsgFailed(("Configuration error: LUN#%d isn't a disk or cd/dvd-rom. enmType=%d\n", pIf->iLUN, enmType));
         return VERR_PDM_UNSUPPORTED_BLOCK_TYPE;
     }
-    if (    (   enmType == PDMBLOCKTYPE_DVD
-             || enmType == PDMBLOCKTYPE_CDROM)
+    if (    (   enmType == PDMMEDIATYPE_DVD
+             || enmType == PDMMEDIATYPE_CDROM)
         &&  !pIf->pDrvMount)
     {
@@ -6447,6 +6437,6 @@
         return VERR_INTERNAL_ERROR;
     }
-    pIf->fATAPI = enmType == PDMBLOCKTYPE_DVD || enmType == PDMBLOCKTYPE_CDROM;
-    pIf->fATAPIPassthrough = pIf->fATAPI ? (pIf->pDrvBlock->pfnSendCmd != NULL) : false;
+    pIf->fATAPI = enmType == PDMMEDIATYPE_DVD || enmType == PDMMEDIATYPE_CDROM;
+    pIf->fATAPIPassthrough = pIf->fATAPI ? (pIf->pDrvMedia->pfnSendCmd != NULL) : false;
 
     /*
@@ -6456,5 +6446,5 @@
         pIf->cbSector = 2048;
     else
-        pIf->cbSector = pIf->pDrvBlock->pfnGetSectorSize(pIf->pDrvBlock);
+        pIf->cbSector = pIf->pDrvMedia->pfnGetSectorSize(pIf->pDrvMedia);
 
     PVM pVM = PDMDevHlpGetVM(pDevIns);
@@ -6490,5 +6480,5 @@
     if (pIf->fATAPI)
     {
-        pIf->cTotalSectors = pIf->pDrvBlock->pfnGetSize(pIf->pDrvBlock) / pIf->cbSector;
+        pIf->cTotalSectors = pIf->pDrvMedia->pfnGetSize(pIf->pDrvMedia) / pIf->cbSector;
         pIf->PCHSGeometry.cCylinders = 0; /* dummy */
         pIf->PCHSGeometry.cHeads     = 0; /* dummy */
@@ -6498,7 +6488,6 @@
     else
     {
-        pIf->cTotalSectors = pIf->pDrvBlock->pfnGetSize(pIf->pDrvBlock) / pIf->cbSector;
-        rc = pIf->pDrvBlockBios->pfnGetPCHSGeometry(pIf->pDrvBlockBios,
-                                                    &pIf->PCHSGeometry);
+        pIf->cTotalSectors = pIf->pDrvMedia->pfnGetSize(pIf->pDrvMedia) / pIf->cbSector;
+        rc = pIf->pDrvMedia->pfnBiosGetPCHSGeometry(pIf->pDrvMedia, &pIf->PCHSGeometry);
         if (rc == VERR_PDM_MEDIA_NOT_MOUNTED)
         {
@@ -6524,11 +6513,10 @@
             pIf->PCHSGeometry.cSectors = 63;
             /* Set the disk geometry information. Ignore errors. */
-            pIf->pDrvBlockBios->pfnSetPCHSGeometry(pIf->pDrvBlockBios,
-                                                   &pIf->PCHSGeometry);
+            pIf->pDrvMedia->pfnBiosSetPCHSGeometry(pIf->pDrvMedia, &pIf->PCHSGeometry);
             rc = VINF_SUCCESS;
         }
         LogRel(("PIIX3 ATA: LUN#%d: disk, PCHS=%u/%u/%u, total number of sectors %Ld\n", pIf->iLUN, pIf->PCHSGeometry.cCylinders, pIf->PCHSGeometry.cHeads, pIf->PCHSGeometry.cSectors, pIf->cTotalSectors));
 
-        if (pIf->pDrvBlock->pfnDiscard)
+        if (pIf->pDrvMedia->pfnDiscard)
             LogRel(("PIIX3 ATA: LUN#%d: TRIM enabled\n", pIf->iLUN));
     }
@@ -6572,5 +6560,5 @@
     /* the usual paranoia */
     AssertRelease(!pIf->pDrvBase);
-    AssertRelease(!pIf->pDrvBlock);
+    AssertRelease(!pIf->pDrvMedia);
     Assert(ATADEVSTATE_2_CONTROLLER(pIf) == pCtl);
     Assert(pIf->iLUN == iLUN);
@@ -6596,5 +6584,5 @@
     {
         pIf->pDrvBase = NULL;
-        pIf->pDrvBlock = NULL;
+        pIf->pDrvMedia = NULL;
     }
     return rc;
@@ -7692,6 +7680,6 @@
                     char szSerial[ATA_SERIAL_NUMBER_LENGTH+1];
                     RTUUID Uuid;
-                    if (pIf->pDrvBlock)
-                        rc = pIf->pDrvBlock->pfnGetUuid(pIf->pDrvBlock, &Uuid);
+                    if (pIf->pDrvMedia)
+                        rc = pIf->pDrvMedia->pfnGetUuid(pIf->pDrvMedia, &Uuid);
                     else
                         RTUuidClear(&Uuid);
@@ -7794,5 +7782,5 @@
             {
                 pIf->pDrvBase = NULL;
-                pIf->pDrvBlock = NULL;
+                pIf->pDrvMedia = NULL;
                 pIf->cbIOBuffer = 0;
                 pIf->pbIOBufferR3 = NULL;
Index: trunk/src/VBox/Devices/Storage/DevFdc.cpp
===================================================================
--- trunk/src/VBox/Devices/Storage/DevFdc.cpp	(revision 59247)
+++ trunk/src/VBox/Devices/Storage/DevFdc.cpp	(revision 59248)
@@ -141,5 +141,5 @@
  *
  * @implements  PDMIBASE
- * @implements  PDMIBLOCKPORT
+ * @implements  PDMIMEDIAPORT
  * @implements  PDMIMOUNTNOTIFY
  */
@@ -151,7 +151,5 @@
     R3PTRTYPE(PPDMIBASE)            pDrvBase;
     /** Pointer to the attached driver's block interface. */
-    R3PTRTYPE(PPDMIBLOCK)           pDrvBlock;
-    /** Pointer to the attached driver's block bios interface. */
-    R3PTRTYPE(PPDMIBLOCKBIOS)       pDrvBlockBios;
+    R3PTRTYPE(PPDMIMEDIA)           pDrvMedia;
     /** Pointer to the attached driver's mount interface.
      * This is NULL if the driver isn't a removable unit. */
@@ -160,5 +158,5 @@
     PDMIBASE                        IBase;
     /** The block port interface. */
-    PDMIBLOCKPORT                   IPort;
+    PDMIMEDIAPORT                   IPort;
     /** The mount notify interface. */
     PDMIMOUNTNOTIFY                 IMountNotify;
@@ -196,24 +194,24 @@
     if (fInit) {
         /* Fixate the drive type at init time if possible. */
-        if (drv->pDrvBlock) {
-            PDMBLOCKTYPE enmType = drv->pDrvBlock->pfnGetType(drv->pDrvBlock);
+        if (drv->pDrvMedia) {
+            PDMMEDIATYPE enmType = drv->pDrvMedia->pfnGetType(drv->pDrvMedia);
             switch (enmType) {
-                case PDMBLOCKTYPE_FLOPPY_360:
-                case PDMBLOCKTYPE_FLOPPY_1_20:
+                case PDMMEDIATYPE_FLOPPY_360:
+                case PDMMEDIATYPE_FLOPPY_1_20:
                     drv->drive = FDRIVE_DRV_120;
                     break;
-                case PDMBLOCKTYPE_FLOPPY_720:
-                case PDMBLOCKTYPE_FLOPPY_1_44:
+                case PDMMEDIATYPE_FLOPPY_720:
+                case PDMMEDIATYPE_FLOPPY_1_44:
                     drv->drive = FDRIVE_DRV_144;
                     break;
                 default:
                     AssertFailed();
-                case PDMBLOCKTYPE_FLOPPY_2_88:
+                case PDMMEDIATYPE_FLOPPY_2_88:
                     drv->drive = FDRIVE_DRV_288;
                     break;
-                case PDMBLOCKTYPE_FLOPPY_FAKE_15_6:
+                case PDMMEDIATYPE_FLOPPY_FAKE_15_6:
                     drv->drive = FDRIVE_DRV_FAKE_15_6;
                     break;
-                case PDMBLOCKTYPE_FLOPPY_FAKE_63_5:
+                case PDMMEDIATYPE_FLOPPY_FAKE_63_5:
                     drv->drive = FDRIVE_DRV_FAKE_63_5;
                     break;
@@ -439,8 +437,8 @@
         bdrv_get_geometry_hint(drv->bs, &nb_heads, &max_track, &last_sect);
 #else /* VBOX */
-    if (   drv->pDrvBlock
+    if (   drv->pDrvMedia
         && drv->pDrvMount
         && drv->pDrvMount->pfnIsMounted (drv->pDrvMount)) {
-        ro = drv->pDrvBlock->pfnIsReadOnly (drv->pDrvBlock);
+        ro = drv->pDrvMedia->pfnIsReadOnly (drv->pDrvMedia);
         nb_heads = max_track = last_sect = 0;
 #endif /* VBOX */
@@ -453,5 +451,5 @@
 #else /* VBOX */
             {
-                uint64_t size2 = drv->pDrvBlock->pfnGetSize (drv->pDrvBlock);
+                uint64_t size2 = drv->pDrvMedia->pfnGetSize (drv->pDrvMedia);
                 nb_sectors = size2 / FD_SECTOR_LEN;
             }
@@ -884,5 +882,5 @@
     fdctrl->srb = 0xc0;
 #ifdef VBOX
-    if (!fdctrl->drives[1].pDrvBlock)
+    if (!fdctrl->drives[1].pDrvMedia)
 #else
     if (!fdctrl->drives[1].bs)
@@ -1501,5 +1499,5 @@
     drv->Led.Asserted.s.fWriting = drv->Led.Actual.s.fWriting = 1;
 
-    rc = drv->pDrvBlock->pfnWrite(drv->pDrvBlock, sector_num * FD_SECTOR_LEN,
+    rc = drv->pDrvMedia->pfnWrite(drv->pDrvMedia, sector_num * FD_SECTOR_LEN,
                                   buf, nb_sectors * FD_SECTOR_LEN);
 
@@ -1517,5 +1515,5 @@
     drv->Led.Asserted.s.fReading = drv->Led.Actual.s.fReading = 1;
 
-    rc = drv->pDrvBlock->pfnRead(drv->pDrvBlock, sector_num * FD_SECTOR_LEN,
+    rc = drv->pDrvMedia->pfnRead(drv->pDrvMedia, sector_num * FD_SECTOR_LEN,
                                  buf, nb_sectors * FD_SECTOR_LEN);
 
@@ -1567,5 +1565,5 @@
     if (cur_drv->bs == NULL)
 #else  /* !VBOX */
-    if (cur_drv->pDrvBlock == NULL)
+    if (cur_drv->pDrvMedia == NULL)
 #endif
     {
@@ -1861,5 +1859,5 @@
     memset(fdctrl->fifo, 0, FD_SECTOR_LEN);
 #ifdef VBOX
-    if (cur_drv->pDrvBlock) {
+    if (cur_drv->pDrvMedia) {
         rc = blk_write(cur_drv, fd_sector(cur_drv), fdctrl->fifo, 1);
         if (RT_FAILURE (rc)) {
@@ -2644,5 +2642,5 @@
 
     PDMIBASE_RETURN_INTERFACE(pszIID, PDMIBASE, &pDrv->IBase);
-    PDMIBASE_RETURN_INTERFACE(pszIID, PDMIBLOCKPORT, &pDrv->IPort);
+    PDMIBASE_RETURN_INTERFACE(pszIID, PDMIMEDIAPORT, &pDrv->IPort);
     PDMIBASE_RETURN_INTERFACE(pszIID, PDMIMOUNTNOTIFY, &pDrv->IMountNotify);
     return NULL;
@@ -2706,18 +2704,11 @@
     rc = PDMDevHlpDriverAttach (pDevIns, drv->iLUN, &drv->IBase, &drv->pDrvBase, s_apszDesc[drv->iLUN]);
     if (RT_SUCCESS (rc)) {
-        drv->pDrvBlock = PDMIBASE_QUERY_INTERFACE(drv->pDrvBase, PDMIBLOCK);
-        if (drv->pDrvBlock) {
-            drv->pDrvBlockBios = PDMIBASE_QUERY_INTERFACE(drv->pDrvBase, PDMIBLOCKBIOS);
-            if (drv->pDrvBlockBios) {
-                drv->pDrvMount = PDMIBASE_QUERY_INTERFACE(drv->pDrvBase, PDMIMOUNT);
-                if (drv->pDrvMount) {
-                    fd_init(drv, fInit);
-                } else {
-                    AssertMsgFailed (("Configuration error: LUN#%d without mountable interface!\n", drv->iLUN));
-                    rc = VERR_PDM_MISSING_INTERFACE;
-                }
-
+        drv->pDrvMedia = PDMIBASE_QUERY_INTERFACE(drv->pDrvBase, PDMIMEDIA);
+        if (drv->pDrvMedia) {
+            drv->pDrvMount = PDMIBASE_QUERY_INTERFACE(drv->pDrvBase, PDMIMOUNT);
+            if (drv->pDrvMount) {
+                fd_init(drv, fInit);
             } else {
-                AssertMsgFailed (("Configuration error: LUN#%d hasn't a block BIOS interface!\n", drv->iLUN));
+                AssertMsgFailed (("Configuration error: LUN#%d without mountable interface!\n", drv->iLUN));
                 rc = VERR_PDM_MISSING_INTERFACE;
             }
@@ -2746,6 +2737,5 @@
     if (RT_FAILURE (rc)) {
         drv->pDrvBase = NULL;
-        drv->pDrvBlock = NULL;
-        drv->pDrvBlockBios = NULL;
+        drv->pDrvMedia = NULL;
         drv->pDrvMount = NULL;
     }
@@ -2787,6 +2777,5 @@
     /* the usual paranoia */
     AssertRelease (!drv->pDrvBase);
-    AssertRelease (!drv->pDrvBlock);
-    AssertRelease (!drv->pDrvBlockBios);
+    AssertRelease (!drv->pDrvMedia);
     AssertRelease (!drv->pDrvMount);
 
@@ -2820,6 +2809,5 @@
             fdrive_t *drv = &pThis->drives[iLUN];
             drv->pDrvBase = NULL;
-            drv->pDrvBlock = NULL;
-            drv->pDrvBlockBios = NULL;
+            drv->pDrvMedia = NULL;
             drv->pDrvMount = NULL;
             break;
Index: trunk/src/VBox/Devices/Storage/DrvBlock.cpp
===================================================================
--- trunk/src/VBox/Devices/Storage/DrvBlock.cpp	(revision 59247)
+++ 	(revision )
@@ -1,1206 +1,0 @@
-/* $Id$ */
-/** @file
- * VBox storage devices: Generic block driver
- */
-
-/*
- * Copyright (C) 2006-2015 Oracle Corporation
- *
- * This file is part of VirtualBox Open Source Edition (OSE), as
- * available from http://www.virtualbox.org. This file is free software;
- * you can redistribute it and/or modify it under the terms of the GNU
- * General Public License (GPL) as published by the Free Software
- * Foundation, in version 2 as it comes in the "COPYING" file of the
- * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
- * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
- */
-
-
-/*********************************************************************************************************************************
-*   Header Files                                                                                                                 *
-*********************************************************************************************************************************/
-#define LOG_GROUP LOG_GROUP_DRV_BLOCK
-#include <VBox/vmm/pdmdrv.h>
-#include <iprt/assert.h>
-#include <iprt/string.h>
-#include <iprt/uuid.h>
-
-#include "VBoxDD.h"
-
-
-/** @def VBOX_PERIODIC_FLUSH
- * Enable support for periodically flushing the VDI to disk. This may prove
- * useful for those nasty problems with the ultra-slow host filesystems.
- * If this is enabled, it can be configured via the CFGM key
- * "VBoxInternal/Devices/piix3ide/0/LUN#<x>/Config/FlushInterval". <x>
- * must be replaced with the correct LUN number of the disk that should
- * do the periodic flushes. The value of the key is the number of bytes
- * written between flushes. A value of 0 (the default) denotes no flushes. */
-#define VBOX_PERIODIC_FLUSH
-
-/** @def VBOX_IGNORE_FLUSH
- * Enable support for ignoring VDI flush requests. This can be useful for
- * filesystems that show bad guest IDE write performance (especially with
- * Windows guests). NOTE that this does not disable the flushes caused by
- * the periodic flush cache feature above.
- * If this feature is enabled, it can be configured via the CFGM key
- * "VBoxInternal/Devices/piix3ide/0/LUN#<x>/Config/IgnoreFlush". <x>
- * must be replaced with the correct LUN number of the disk that should
- * ignore flush requests. The value of the key is a boolean. The default
- * is to ignore flushes, i.e. true. */
-#define VBOX_IGNORE_FLUSH
-
-
-/*********************************************************************************************************************************
-*   Structures and Typedefs                                                                                                      *
-*********************************************************************************************************************************/
-/**
- * Block driver instance data.
- *
- * @implements  PDMIBLOCK
- * @implements  PDMIBLOCKBIOS
- * @implements  PDMIMOUNT
- * @implements  PDMIMEDIAASYNCPORT
- * @implements  PDMIBLOCKASYNC
- */
-typedef struct DRVBLOCK
-{
-    /** Pointer driver instance. */
-    PPDMDRVINS              pDrvIns;
-    /** Drive type. */
-    PDMBLOCKTYPE            enmType;
-    /** Locked indicator. */
-    bool                    fLocked;
-    /** Mountable indicator. */
-    bool                    fMountable;
-    /** Visible to the BIOS. */
-    bool                    fBiosVisible;
-#ifdef VBOX_PERIODIC_FLUSH
-    /** HACK: Configuration value for number of bytes written after which to flush. */
-    uint32_t                cbFlushInterval;
-    /** HACK: Current count for the number of bytes written since the last flush. */
-    uint32_t                cbDataWritten;
-#endif /* VBOX_PERIODIC_FLUSH */
-#ifdef VBOX_IGNORE_FLUSH
-    /** HACK: Disable flushes for this drive. */
-    bool                    fIgnoreFlush;
-    /** Disable async flushes for this drive. */
-    bool                    fIgnoreFlushAsync;
-#endif /* VBOX_IGNORE_FLUSH */
-    /** Pointer to the media driver below us.
-     * This is NULL if the media is not mounted. */
-    PPDMIMEDIA              pDrvMedia;
-    /** Pointer to the block port interface above us. */
-    PPDMIBLOCKPORT          pDrvBlockPort;
-    /** Pointer to the mount notify interface above us. */
-    PPDMIMOUNTNOTIFY        pDrvMountNotify;
-    /** Our block interface. */
-    PDMIBLOCK               IBlock;
-    /** Our block interface. */
-    PDMIBLOCKBIOS           IBlockBios;
-    /** Our mountable interface. */
-    PDMIMOUNT               IMount;
-    /** Our media port interface. */
-    PDMIMEDIAPORT           IMediaPort;
-
-    /** Pointer to the async media driver below us.
-     * This is NULL if the media is not mounted. */
-    PPDMIMEDIAASYNC         pDrvMediaAsync;
-    /** Our media async port. */
-    PDMIMEDIAASYNCPORT      IMediaAsyncPort;
-    /** Pointer to the async block port interface above us. */
-    PPDMIBLOCKASYNCPORT     pDrvBlockAsyncPort;
-    /** Our async block interface. */
-    PDMIBLOCKASYNC          IBlockAsync;
-
-    /** Uuid of the drive. */
-    RTUUID                  Uuid;
-
-    /** BIOS PCHS Geometry. */
-    PDMMEDIAGEOMETRY        PCHSGeometry;
-    /** BIOS LCHS Geometry. */
-    PDMMEDIAGEOMETRY        LCHSGeometry;
-} DRVBLOCK, *PDRVBLOCK;
-
-
-/* -=-=-=-=- IBlock -=-=-=-=- */
-
-/** Makes a PDRVBLOCK out of a PPDMIBLOCK. */
-#define PDMIBLOCK_2_DRVBLOCK(pInterface)        ( (PDRVBLOCK)((uintptr_t)pInterface - RT_OFFSETOF(DRVBLOCK, IBlock)) )
-
-/** @copydoc PDMIBLOCK::pfnRead */
-static DECLCALLBACK(int) drvblockRead(PPDMIBLOCK pInterface, uint64_t off, void *pvBuf, size_t cbRead)
-{
-    PDRVBLOCK pThis = PDMIBLOCK_2_DRVBLOCK(pInterface);
-
-    /*
-     * Check the state.
-     */
-    if (!pThis->pDrvMedia)
-    {
-        AssertMsgFailed(("Invalid state! Not mounted!\n"));
-        return VERR_PDM_MEDIA_NOT_MOUNTED;
-    }
-
-    int rc = pThis->pDrvMedia->pfnRead(pThis->pDrvMedia, off, pvBuf, cbRead);
-    return rc;
-}
-
-
-/** @copydoc PDMIBLOCK::pfnReadPcBios */
-static DECLCALLBACK(int) drvblockReadPcBios(PPDMIBLOCK pInterface, uint64_t off, void *pvBuf, size_t cbRead)
-{
-    PDRVBLOCK pThis = PDMIBLOCK_2_DRVBLOCK(pInterface);
-
-    /*
-     * Check the state.
-     */
-    if (!pThis->pDrvMedia)
-    {
-        AssertMsgFailed(("Invalid state! Not mounted!\n"));
-        return VERR_PDM_MEDIA_NOT_MOUNTED;
-    }
-
-    int rc = pThis->pDrvMedia->pfnReadPcBios(pThis->pDrvMedia, off, pvBuf, cbRead);
-    return rc;
-}
-
-
-/** @copydoc PDMIBLOCK::pfnWrite */
-static DECLCALLBACK(int) drvblockWrite(PPDMIBLOCK pInterface, uint64_t off, const void *pvBuf, size_t cbWrite)
-{
-    PDRVBLOCK pThis = PDMIBLOCK_2_DRVBLOCK(pInterface);
-
-    /*
-     * Check the state.
-     */
-    if (!pThis->pDrvMedia)
-    {
-        AssertMsgFailed(("Invalid state! Not mounted!\n"));
-        return VERR_PDM_MEDIA_NOT_MOUNTED;
-    }
-
-    /* Set an FTM checkpoint as this operation changes the state permanently. */
-    PDMDrvHlpFTSetCheckpoint(pThis->pDrvIns, FTMCHECKPOINTTYPE_STORAGE);
-
-    int rc = pThis->pDrvMedia->pfnWrite(pThis->pDrvMedia, off, pvBuf, cbWrite);
-#ifdef VBOX_PERIODIC_FLUSH
-    if (pThis->cbFlushInterval)
-    {
-        pThis->cbDataWritten += (uint32_t)cbWrite;
-        if (pThis->cbDataWritten > pThis->cbFlushInterval)
-        {
-            pThis->cbDataWritten = 0;
-            pThis->pDrvMedia->pfnFlush(pThis->pDrvMedia);
-        }
-    }
-#endif /* VBOX_PERIODIC_FLUSH */
-
-    return rc;
-}
-
-
-/** @copydoc PDMIBLOCK::pfnFlush */
-static DECLCALLBACK(int) drvblockFlush(PPDMIBLOCK pInterface)
-{
-    PDRVBLOCK pThis = PDMIBLOCK_2_DRVBLOCK(pInterface);
-
-    /*
-     * Check the state.
-     */
-    if (!pThis->pDrvMedia)
-    {
-        AssertMsgFailed(("Invalid state! Not mounted!\n"));
-        return VERR_PDM_MEDIA_NOT_MOUNTED;
-    }
-
-#ifdef VBOX_IGNORE_FLUSH
-    if (pThis->fIgnoreFlush)
-        return VINF_SUCCESS;
-#endif /* VBOX_IGNORE_FLUSH */
-
-    int rc = pThis->pDrvMedia->pfnFlush(pThis->pDrvMedia);
-    if (rc == VERR_NOT_IMPLEMENTED)
-        rc = VINF_SUCCESS;
-    return rc;
-}
-
-
-/** @copydoc PDMIBLOCK::pfnMerge */
-static DECLCALLBACK(int) drvblockMerge(PPDMIBLOCK pInterface,
-                                       PFNSIMPLEPROGRESS pfnProgress,
-                                       void *pvUser)
-{
-    PDRVBLOCK pThis = PDMIBLOCK_2_DRVBLOCK(pInterface);
-
-    /*
-     * Check the state.
-     */
-    if (!pThis->pDrvMedia)
-    {
-        AssertMsgFailed(("Invalid state! Not mounted!\n"));
-        return VERR_PDM_MEDIA_NOT_MOUNTED;
-    }
-
-    if (!pThis->pDrvMedia->pfnMerge)
-        return VERR_NOT_SUPPORTED;
-
-    int rc = pThis->pDrvMedia->pfnMerge(pThis->pDrvMedia, pfnProgress, pvUser);
-    return rc;
-}
-
-
-/** @copydoc PDMIBLOCK::pfnIsReadOnly */
-static DECLCALLBACK(bool) drvblockIsReadOnly(PPDMIBLOCK pInterface)
-{
-    PDRVBLOCK pThis = PDMIBLOCK_2_DRVBLOCK(pInterface);
-
-    /*
-     * Check the state.
-     */
-    if (!pThis->pDrvMedia)
-        return false;
-
-    bool fRc = pThis->pDrvMedia->pfnIsReadOnly(pThis->pDrvMedia);
-    return fRc;
-}
-
-
-/** @copydoc PDMIBLOCK::pfnGetSize */
-static DECLCALLBACK(uint64_t) drvblockGetSize(PPDMIBLOCK pInterface)
-{
-    PDRVBLOCK pThis = PDMIBLOCK_2_DRVBLOCK(pInterface);
-
-    /*
-     * Check the state.
-     */
-    if (!pThis->pDrvMedia)
-        return 0;
-
-    uint64_t cb = pThis->pDrvMedia->pfnGetSize(pThis->pDrvMedia);
-    LogFlow(("drvblockGetSize: returns %llu\n", cb));
-    return cb;
-}
-
-
-/** @copydoc PDMIBLOCK::pfnGetSize */
-static DECLCALLBACK(uint32_t) drvblockGetSectorSize(PPDMIBLOCK pInterface)
-{
-    PDRVBLOCK pThis = PDMIBLOCK_2_DRVBLOCK(pInterface);
-
-    /*
-     * Check the state.
-     */
-    if (!pThis->pDrvMedia)
-        return 0;
-
-    uint32_t cb = pThis->pDrvMedia->pfnGetSectorSize(pThis->pDrvMedia);
-    LogFlowFunc(("returns %u\n", cb));
-    return cb;
-}
-
-
-/** @copydoc PDMIBLOCK::pfnGetType */
-static DECLCALLBACK(PDMBLOCKTYPE) drvblockGetType(PPDMIBLOCK pInterface)
-{
-    PDRVBLOCK pThis = PDMIBLOCK_2_DRVBLOCK(pInterface);
-    LogFlow(("drvblockGetType: returns %d\n", pThis->enmType));
-    return pThis->enmType;
-}
-
-
-/** @copydoc PDMIBLOCK::pfnGetUuid */
-static DECLCALLBACK(int) drvblockGetUuid(PPDMIBLOCK pInterface, PRTUUID pUuid)
-{
-    PDRVBLOCK pThis = PDMIBLOCK_2_DRVBLOCK(pInterface);
-
-    /*
-     * Copy the uuid.
-     */
-    *pUuid = pThis->Uuid;
-    return VINF_SUCCESS;
-}
-
-static DECLCALLBACK(int) drvblockDiscard(PPDMIBLOCK pInterface, PCRTRANGE paRanges, unsigned cRanges)
-{
-    PDRVBLOCK pThis = PDMIBLOCK_2_DRVBLOCK(pInterface);
-
-    return pThis->pDrvMedia->pfnDiscard(pThis->pDrvMedia, paRanges, cRanges);
-}
-
-/** @copydoc PDMIBLOCK::pfnIoBufAlloc */
-static DECLCALLBACK(int) drvblockIoBufAlloc(PPDMIBLOCK pInterface, size_t cb, void **ppvNew)
-{
-    PDRVBLOCK pThis = PDMIBLOCK_2_DRVBLOCK(pInterface);
-
-    return pThis->pDrvMedia->pfnIoBufAlloc(pThis->pDrvMedia, cb, ppvNew);
-}
-
-/** @copydoc PDMIBLOCK::pfnIoBufFree */
-static DECLCALLBACK(int) drvblockIoBufFree(PPDMIBLOCK pInterface, void *pv, size_t cb)
-{
-    PDRVBLOCK pThis = PDMIBLOCK_2_DRVBLOCK(pInterface);
-
-    return pThis->pDrvMedia->pfnIoBufFree(pThis->pDrvMedia, pv, cb);
-}
-
-/* -=-=-=-=- IBlockAsync -=-=-=-=- */
-
-/** Makes a PDRVBLOCK out of a PPDMIBLOCKASYNC. */
-#define PDMIBLOCKASYNC_2_DRVBLOCK(pInterface)        ( (PDRVBLOCK)((uintptr_t)pInterface - RT_OFFSETOF(DRVBLOCK, IBlockAsync)) )
-
-/** @copydoc PDMIBLOCKASYNC::pfnStartRead */
-static DECLCALLBACK(int) drvblockAsyncReadStart(PPDMIBLOCKASYNC pInterface, uint64_t off, PCRTSGSEG pSeg, unsigned cSeg, size_t cbRead, void *pvUser)
-{
-    PDRVBLOCK pThis = PDMIBLOCKASYNC_2_DRVBLOCK(pInterface);
-
-    /*
-     * Check the state.
-     */
-    if (!pThis->pDrvMediaAsync)
-    {
-        AssertMsgFailed(("Invalid state! Not mounted!\n"));
-        return VERR_PDM_MEDIA_NOT_MOUNTED;
-    }
-
-    int rc = pThis->pDrvMediaAsync->pfnStartRead(pThis->pDrvMediaAsync, off, pSeg, cSeg, cbRead, pvUser);
-    return rc;
-}
-
-
-/** @copydoc PDMIBLOCKASYNC::pfnStartWrite */
-static DECLCALLBACK(int) drvblockAsyncWriteStart(PPDMIBLOCKASYNC pInterface, uint64_t off, PCRTSGSEG pSeg, unsigned cSeg, size_t cbWrite, void *pvUser)
-{
-    PDRVBLOCK pThis = PDMIBLOCKASYNC_2_DRVBLOCK(pInterface);
-
-    /*
-     * Check the state.
-     */
-    if (!pThis->pDrvMediaAsync)
-    {
-        AssertMsgFailed(("Invalid state! Not mounted!\n"));
-        return VERR_PDM_MEDIA_NOT_MOUNTED;
-    }
-
-    int rc = pThis->pDrvMediaAsync->pfnStartWrite(pThis->pDrvMediaAsync, off, pSeg, cSeg, cbWrite, pvUser);
-
-    return rc;
-}
-
-
-/** @copydoc PDMIBLOCKASYNC::pfnStartFlush */
-static DECLCALLBACK(int) drvblockAsyncFlushStart(PPDMIBLOCKASYNC pInterface, void *pvUser)
-{
-    PDRVBLOCK pThis = PDMIBLOCKASYNC_2_DRVBLOCK(pInterface);
-
-    /*
-     * Check the state.
-     */
-    if (!pThis->pDrvMediaAsync)
-    {
-        AssertMsgFailed(("Invalid state! Not mounted!\n"));
-        return VERR_PDM_MEDIA_NOT_MOUNTED;
-    }
-
-#ifdef VBOX_IGNORE_FLUSH
-    if (pThis->fIgnoreFlushAsync)
-        return VINF_VD_ASYNC_IO_FINISHED;
-#endif /* VBOX_IGNORE_FLUSH */
-
-    int rc = pThis->pDrvMediaAsync->pfnStartFlush(pThis->pDrvMediaAsync, pvUser);
-
-    return rc;
-}
-
-
-/** @copydoc PDMIBLOCKASYNC::pfnStartDiscard */
-static DECLCALLBACK(int) drvblockStartDiscard(PPDMIBLOCKASYNC pInterface, PCRTRANGE paRanges, unsigned cRanges, void *pvUser)
-{
-    PDRVBLOCK pThis = PDMIBLOCKASYNC_2_DRVBLOCK(pInterface);
-
-    /*
-     * Check the state.
-     */
-    if (!pThis->pDrvMediaAsync)
-    {
-        AssertMsgFailed(("Invalid state! Not mounted!\n"));
-        return VERR_PDM_MEDIA_NOT_MOUNTED;
-    }
-
-    return pThis->pDrvMediaAsync->pfnStartDiscard(pThis->pDrvMediaAsync, paRanges, cRanges, pvUser);
-}
-
-/* -=-=-=-=- IMediaAsyncPort -=-=-=-=- */
-
-/** Makes a PDRVBLOCKASYNC out of a PPDMIMEDIAASYNCPORT. */
-#define PDMIMEDIAASYNCPORT_2_DRVBLOCK(pInterface)    ( (PDRVBLOCK((uintptr_t)pInterface - RT_OFFSETOF(DRVBLOCK, IMediaAsyncPort))) )
-
-static DECLCALLBACK(int) drvblockAsyncTransferCompleteNotify(PPDMIMEDIAASYNCPORT pInterface, void *pvUser, int rcReq)
-{
-    PDRVBLOCK pThis = PDMIMEDIAASYNCPORT_2_DRVBLOCK(pInterface);
-
-    return pThis->pDrvBlockAsyncPort->pfnTransferCompleteNotify(pThis->pDrvBlockAsyncPort, pvUser, rcReq);
-}
-
-/* -=-=-=-=- IBlockBios -=-=-=-=- */
-
-/** Makes a PDRVBLOCK out of a PPDMIBLOCKBIOS. */
-#define PDMIBLOCKBIOS_2_DRVBLOCK(pInterface)    ( (PDRVBLOCK((uintptr_t)pInterface - RT_OFFSETOF(DRVBLOCK, IBlockBios))) )
-
-
-/** @copydoc PDMIBLOCKBIOS::pfnGetPCHSGeometry */
-static DECLCALLBACK(int) drvblockGetPCHSGeometry(PPDMIBLOCKBIOS pInterface, PPDMMEDIAGEOMETRY pPCHSGeometry)
-{
-    PDRVBLOCK pThis = PDMIBLOCKBIOS_2_DRVBLOCK(pInterface);
-
-    /*
-     * Check the state.
-     */
-    if (!pThis->pDrvMedia)
-        return VERR_PDM_MEDIA_NOT_MOUNTED;
-
-    /*
-     * Use configured/cached values if present.
-     */
-    if (    pThis->PCHSGeometry.cCylinders > 0
-        &&  pThis->PCHSGeometry.cHeads > 0
-        &&  pThis->PCHSGeometry.cSectors > 0)
-    {
-        *pPCHSGeometry = pThis->PCHSGeometry;
-        LogFlow(("%s: returns VINF_SUCCESS {%d,%d,%d}\n", __FUNCTION__, pThis->PCHSGeometry.cCylinders, pThis->PCHSGeometry.cHeads, pThis->PCHSGeometry.cSectors));
-        return VINF_SUCCESS;
-    }
-
-    /*
-     * Call media.
-     */
-    int rc = pThis->pDrvMedia->pfnBiosGetPCHSGeometry(pThis->pDrvMedia, &pThis->PCHSGeometry);
-
-    if (RT_SUCCESS(rc))
-    {
-        *pPCHSGeometry = pThis->PCHSGeometry;
-        LogFlow(("%s: returns %Rrc {%d,%d,%d}\n", __FUNCTION__, rc, pThis->PCHSGeometry.cCylinders, pThis->PCHSGeometry.cHeads, pThis->PCHSGeometry.cSectors));
-    }
-    else if (rc == VERR_NOT_IMPLEMENTED)
-    {
-        rc = VERR_PDM_GEOMETRY_NOT_SET;
-        LogFlow(("%s: returns %Rrc\n", __FUNCTION__, rc));
-    }
-    return rc;
-}
-
-
-/** @copydoc PDMIBLOCKBIOS::pfnSetPCHSGeometry */
-static DECLCALLBACK(int) drvblockSetPCHSGeometry(PPDMIBLOCKBIOS pInterface, PCPDMMEDIAGEOMETRY pPCHSGeometry)
-{
-    LogFlow(("%s: cCylinders=%d cHeads=%d cSectors=%d\n", __FUNCTION__, pPCHSGeometry->cCylinders, pPCHSGeometry->cHeads, pPCHSGeometry->cSectors));
-    PDRVBLOCK pThis = PDMIBLOCKBIOS_2_DRVBLOCK(pInterface);
-
-    /*
-     * Check the state.
-     */
-    if (!pThis->pDrvMedia)
-    {
-        AssertMsgFailed(("Invalid state! Not mounted!\n"));
-        return VERR_PDM_MEDIA_NOT_MOUNTED;
-    }
-
-    /*
-     * Call media. Ignore the not implemented return code.
-     */
-    int rc = pThis->pDrvMedia->pfnBiosSetPCHSGeometry(pThis->pDrvMedia, pPCHSGeometry);
-
-    if (    RT_SUCCESS(rc)
-        ||  rc == VERR_NOT_IMPLEMENTED)
-    {
-        pThis->PCHSGeometry = *pPCHSGeometry;
-        rc = VINF_SUCCESS;
-    }
-    return rc;
-}
-
-
-/** @copydoc PDMIBLOCKBIOS::pfnGetLCHSGeometry */
-static DECLCALLBACK(int) drvblockGetLCHSGeometry(PPDMIBLOCKBIOS pInterface, PPDMMEDIAGEOMETRY pLCHSGeometry)
-{
-    PDRVBLOCK pThis = PDMIBLOCKBIOS_2_DRVBLOCK(pInterface);
-
-    /*
-     * Check the state.
-     */
-    if (!pThis->pDrvMedia)
-        return VERR_PDM_MEDIA_NOT_MOUNTED;
-
-    /*
-     * Use configured/cached values if present.
-     */
-    if (    pThis->LCHSGeometry.cCylinders > 0
-        &&  pThis->LCHSGeometry.cHeads > 0
-        &&  pThis->LCHSGeometry.cSectors > 0)
-    {
-        *pLCHSGeometry = pThis->LCHSGeometry;
-        LogFlow(("%s: returns VINF_SUCCESS {%d,%d,%d}\n", __FUNCTION__, pThis->LCHSGeometry.cCylinders, pThis->LCHSGeometry.cHeads, pThis->LCHSGeometry.cSectors));
-        return VINF_SUCCESS;
-    }
-
-    /*
-     * Call media.
-     */
-    int rc = pThis->pDrvMedia->pfnBiosGetLCHSGeometry(pThis->pDrvMedia, &pThis->LCHSGeometry);
-
-    if (RT_SUCCESS(rc))
-    {
-        *pLCHSGeometry = pThis->LCHSGeometry;
-        LogFlow(("%s: returns %Rrc {%d,%d,%d}\n", __FUNCTION__, rc, pThis->LCHSGeometry.cCylinders, pThis->LCHSGeometry.cHeads, pThis->LCHSGeometry.cSectors));
-    }
-    else if (rc == VERR_NOT_IMPLEMENTED)
-    {
-        rc = VERR_PDM_GEOMETRY_NOT_SET;
-        LogFlow(("%s: returns %Rrc\n", __FUNCTION__, rc));
-    }
-    return rc;
-}
-
-
-/** @copydoc PDMIBLOCKBIOS::pfnSetLCHSGeometry */
-static DECLCALLBACK(int) drvblockSetLCHSGeometry(PPDMIBLOCKBIOS pInterface, PCPDMMEDIAGEOMETRY pLCHSGeometry)
-{
-    LogFlow(("%s: cCylinders=%d cHeads=%d cSectors=%d\n", __FUNCTION__, pLCHSGeometry->cCylinders, pLCHSGeometry->cHeads, pLCHSGeometry->cSectors));
-    PDRVBLOCK pThis = PDMIBLOCKBIOS_2_DRVBLOCK(pInterface);
-
-    /*
-     * Check the state.
-     */
-    if (!pThis->pDrvMedia)
-    {
-        AssertMsgFailed(("Invalid state! Not mounted!\n"));
-        return VERR_PDM_MEDIA_NOT_MOUNTED;
-    }
-
-    /*
-     * Call media. Ignore the not implemented return code.
-     */
-    int rc = pThis->pDrvMedia->pfnBiosSetLCHSGeometry(pThis->pDrvMedia, pLCHSGeometry);
-
-    if (    RT_SUCCESS(rc)
-        ||  rc == VERR_NOT_IMPLEMENTED)
-    {
-        pThis->LCHSGeometry = *pLCHSGeometry;
-        rc = VINF_SUCCESS;
-    }
-    return rc;
-}
-
-
-/** @copydoc PDMIBLOCKBIOS::pfnIsVisible */
-static DECLCALLBACK(bool) drvblockIsVisible(PPDMIBLOCKBIOS pInterface)
-{
-    PDRVBLOCK pThis = PDMIBLOCKBIOS_2_DRVBLOCK(pInterface);
-    LogFlow(("drvblockIsVisible: returns %d\n", pThis->fBiosVisible));
-    return pThis->fBiosVisible;
-}
-
-
-/** @copydoc PDMIBLOCKBIOS::pfnGetType */
-static DECLCALLBACK(PDMBLOCKTYPE) drvblockBiosGetType(PPDMIBLOCKBIOS pInterface)
-{
-    PDRVBLOCK pThis = PDMIBLOCKBIOS_2_DRVBLOCK(pInterface);
-    LogFlow(("drvblockBiosGetType: returns %d\n", pThis->enmType));
-    return pThis->enmType;
-}
-
-
-
-/* -=-=-=-=- IMount -=-=-=-=- */
-
-/** Makes a PDRVBLOCK out of a PPDMIMOUNT. */
-#define PDMIMOUNT_2_DRVBLOCK(pInterface)        ( (PDRVBLOCK)((uintptr_t)pInterface - RT_OFFSETOF(DRVBLOCK, IMount)) )
-
-
-/** @copydoc PDMIMOUNT::pfnMount */
-static DECLCALLBACK(int) drvblockMount(PPDMIMOUNT pInterface, const char *pszFilename, const char *pszCoreDriver)
-{
-    LogFlow(("drvblockMount: pszFilename=%p:{%s} pszCoreDriver=%p:{%s}\n", pszFilename, pszFilename, pszCoreDriver, pszCoreDriver));
-    PDRVBLOCK pThis = PDMIMOUNT_2_DRVBLOCK(pInterface);
-
-    /*
-     * Validate state.
-     */
-    if (pThis->pDrvMedia)
-    {
-        AssertMsgFailed(("Already mounted\n"));
-        return VERR_PDM_MEDIA_MOUNTED;
-    }
-
-    /*
-     * Prepare configuration.
-     */
-    if (pszFilename)
-    {
-        int rc = PDMDrvHlpMountPrepare(pThis->pDrvIns, pszFilename, pszCoreDriver);
-        if (RT_FAILURE(rc))
-        {
-            Log(("drvblockMount: Prepare failed for \"%s\" rc=%Rrc\n", pszFilename, rc));
-            return rc;
-        }
-    }
-
-    /*
-     * Attach the media driver and query it's interface.
-     */
-    uint32_t fTachFlags = 0; /** @todo figure attachment flags for mount. */
-    PPDMIBASE pBase;
-    int rc = PDMDrvHlpAttach(pThis->pDrvIns, fTachFlags, &pBase);
-    if (RT_FAILURE(rc))
-    {
-        Log(("drvblockMount: Attach failed rc=%Rrc\n", rc));
-        return rc;
-    }
-
-    pThis->pDrvMedia = PDMIBASE_QUERY_INTERFACE(pBase, PDMIMEDIA);
-    if (pThis->pDrvMedia)
-    {
-        /** @todo r=klaus missing async handling, this is just a band aid to
-         * avoid using stale information */
-        pThis->pDrvMediaAsync = NULL;
-
-        /*
-         * Initialize state.
-         */
-        pThis->fLocked = false;
-        pThis->PCHSGeometry.cCylinders  = 0;
-        pThis->PCHSGeometry.cHeads      = 0;
-        pThis->PCHSGeometry.cSectors    = 0;
-        pThis->LCHSGeometry.cCylinders  = 0;
-        pThis->LCHSGeometry.cHeads      = 0;
-        pThis->LCHSGeometry.cSectors    = 0;
-#ifdef VBOX_PERIODIC_FLUSH
-        pThis->cbDataWritten = 0;
-#endif /* VBOX_PERIODIC_FLUSH */
-
-        /*
-         * Notify driver/device above us.
-         */
-        if (pThis->pDrvMountNotify)
-            pThis->pDrvMountNotify->pfnMountNotify(pThis->pDrvMountNotify);
-        Log(("drvblockMount: Success\n"));
-        return VINF_SUCCESS;
-    }
-    else
-        rc = VERR_PDM_MISSING_INTERFACE_BELOW;
-
-    /*
-     * Failed, detatch the media driver.
-     */
-    AssertMsgFailed(("No media interface!\n"));
-    int rc2 = PDMDrvHlpDetach(pThis->pDrvIns, fTachFlags);
-    AssertRC(rc2);
-    pThis->pDrvMedia = NULL;
-    return rc;
-}
-
-
-/** @copydoc PDMIMOUNT::pfnUnmount */
-static DECLCALLBACK(int) drvblockUnmount(PPDMIMOUNT pInterface, bool fForce, bool fEject)
-{
-    PDRVBLOCK pThis = PDMIMOUNT_2_DRVBLOCK(pInterface);
-
-    /*
-     * Validate state.
-     */
-    if (!pThis->pDrvMedia)
-    {
-        Log(("drvblockUmount: Not mounted\n"));
-        return VERR_PDM_MEDIA_NOT_MOUNTED;
-    }
-    if (pThis->fLocked && !fForce)
-    {
-        Log(("drvblockUmount: Locked\n"));
-        return VERR_PDM_MEDIA_LOCKED;
-    }
-
-    /* Media is no longer locked even if it was previously. */
-    pThis->fLocked = false;
-
-    /*
-     * Detach the media driver and query it's interface.
-     */
-    int rc = PDMDrvHlpDetach(pThis->pDrvIns, 0 /*fFlags*/);
-    if (RT_FAILURE(rc))
-    {
-        Log(("drvblockUnmount: Detach failed rc=%Rrc\n", rc));
-        return rc;
-    }
-    Assert(!pThis->pDrvMedia);
-
-    /*
-     * Notify driver/device above us.
-     */
-    if (pThis->pDrvMountNotify)
-        pThis->pDrvMountNotify->pfnUnmountNotify(pThis->pDrvMountNotify);
-    Log(("drvblockUnmount: success\n"));
-    return VINF_SUCCESS;
-}
-
-
-/** @copydoc PDMIMOUNT::pfnIsMounted */
-static DECLCALLBACK(bool) drvblockIsMounted(PPDMIMOUNT pInterface)
-{
-    PDRVBLOCK pThis = PDMIMOUNT_2_DRVBLOCK(pInterface);
-    return pThis->pDrvMedia != NULL;
-}
-
-/** @copydoc PDMIMOUNT::pfnLock */
-static DECLCALLBACK(int) drvblockLock(PPDMIMOUNT pInterface)
-{
-    PDRVBLOCK pThis = PDMIMOUNT_2_DRVBLOCK(pInterface);
-    Log(("drvblockLock: %d -> %d\n", pThis->fLocked, true));
-    pThis->fLocked = true;
-    return VINF_SUCCESS;
-}
-
-/** @copydoc PDMIMOUNT::pfnUnlock */
-static DECLCALLBACK(int) drvblockUnlock(PPDMIMOUNT pInterface)
-{
-    PDRVBLOCK pThis = PDMIMOUNT_2_DRVBLOCK(pInterface);
-    Log(("drvblockUnlock: %d -> %d\n", pThis->fLocked, false));
-    pThis->fLocked = false;
-    return VINF_SUCCESS;
-}
-
-/** @copydoc PDMIMOUNT::pfnIsLocked */
-static DECLCALLBACK(bool) drvblockIsLocked(PPDMIMOUNT pInterface)
-{
-    PDRVBLOCK pThis = PDMIMOUNT_2_DRVBLOCK(pInterface);
-    return pThis->fLocked;
-}
-
-
-
-/* -=-=-=-=- IMediaPort -=-=-=-=- */
-
-/** Makes a PDRVBLOCK out of a PPDMIMEDIAPORT. */
-#define PDMIMEDIAPORT_2_DRVBLOCK(pInterface)    ( (PDRVBLOCK((uintptr_t)pInterface - RT_OFFSETOF(DRVBLOCK, IMediaPort))) )
-
-/**
- * @interface_method_impl{PDMIMEDIAPORT,pfnQueryDeviceLocation}
- */
-static DECLCALLBACK(int) drvblockQueryDeviceLocation(PPDMIMEDIAPORT pInterface, const char **ppcszController,
-                                                     uint32_t *piInstance, uint32_t *piLUN)
-{
-    PDRVBLOCK pThis = PDMIMEDIAPORT_2_DRVBLOCK(pInterface);
-
-    return pThis->pDrvBlockPort->pfnQueryDeviceLocation(pThis->pDrvBlockPort, ppcszController,
-                                                        piInstance, piLUN);
-}
-
-/* -=-=-=-=- IBase -=-=-=-=- */
-
-/**
- * @interface_method_impl{PDMIBASE,pfnQueryInterface}
- */
-static DECLCALLBACK(void *)  drvblockQueryInterface(PPDMIBASE pInterface, const char *pszIID)
-{
-    PPDMDRVINS  pDrvIns = PDMIBASE_2_PDMDRV(pInterface);
-    PDRVBLOCK   pThis = PDMINS_2_DATA(pDrvIns, PDRVBLOCK);
-
-    PDMIBASE_RETURN_INTERFACE(pszIID, PDMIBASE, &pDrvIns->IBase);
-    PDMIBASE_RETURN_INTERFACE(pszIID, PDMIBLOCK, &pThis->IBlock);
-    PDMIBASE_RETURN_INTERFACE(pszIID, PDMIBLOCKBIOS, pThis->fBiosVisible ? &pThis->IBlockBios : NULL);
-    PDMIBASE_RETURN_INTERFACE(pszIID, PDMIMOUNT, pThis->fMountable ? &pThis->IMount : NULL);
-    PDMIBASE_RETURN_INTERFACE(pszIID, PDMIBLOCKASYNC, pThis->pDrvMediaAsync ? &pThis->IBlockAsync : NULL);
-    PDMIBASE_RETURN_INTERFACE(pszIID, PDMIMEDIAASYNCPORT, pThis->pDrvBlockAsyncPort ? &pThis->IMediaAsyncPort : NULL);
-    PDMIBASE_RETURN_INTERFACE(pszIID, PDMIMEDIAPORT, &pThis->IMediaPort);
-    return NULL;
-}
-
-
-/* -=-=-=-=- driver interface -=-=-=-=- */
-
-/**
- * @callback_method_impl{FNPDMDRVDETACH}
- */
-static DECLCALLBACK(void)  drvblockDetach(PPDMDRVINS pDrvIns, uint32_t fFlags)
-{
-    PDRVBLOCK pThis = PDMINS_2_DATA(pDrvIns, PDRVBLOCK);
-    pThis->pDrvMedia = NULL;
-    pThis->pDrvMediaAsync = NULL;
-    NOREF(fFlags);
-}
-
-
-/**
- * Reset notification.
- *
- * @returns VBox status code.
- * @param   pDevIns     The driver instance data.
- */
-static DECLCALLBACK(void)  drvblockReset(PPDMDRVINS pDrvIns)
-{
-    PDRVBLOCK pThis = PDMINS_2_DATA(pDrvIns, PDRVBLOCK);
-
-    pThis->fLocked = false;
-}
-
-
-/**
- * Translates a PDMBLOCKTYPE value into a string.
- *
- * @returns Read only string.
- * @param   enmType             The type value.
- */
-static const char *drvblockGetTypeName(PDMBLOCKTYPE enmType)
-{
-    switch (enmType)
-    {
-        case PDMBLOCKTYPE_ERROR:                return "ERROR";
-        case PDMBLOCKTYPE_FLOPPY_360:           return "FLOPPY_360";
-        case PDMBLOCKTYPE_FLOPPY_720:           return "FLOPPY_720";
-        case PDMBLOCKTYPE_FLOPPY_1_20:          return "FLOPPY_1_20";
-        case PDMBLOCKTYPE_FLOPPY_1_44:          return "FLOPPY_1_44";
-        case PDMBLOCKTYPE_FLOPPY_2_88:          return "FLOPPY_2_88";
-        case PDMBLOCKTYPE_FLOPPY_FAKE_15_6:     return "FLOPPY_FAKE_15_6";
-        case PDMBLOCKTYPE_FLOPPY_FAKE_63_5:     return "FLOPPY_FAKE_63_5";
-        case PDMBLOCKTYPE_CDROM:                return "CDROM";
-        case PDMBLOCKTYPE_DVD:                  return "DVD";
-        case PDMBLOCKTYPE_HARD_DISK:            return "HARD_DISK";
-        default:                                return "Unknown";
-
-    }
-}
-
-
-/**
- * Construct a block driver instance.
- *
- * @copydoc FNPDMDRVCONSTRUCT
- */
-static DECLCALLBACK(int) drvblockConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfg, uint32_t fFlags)
-{
-    PDRVBLOCK pThis = PDMINS_2_DATA(pDrvIns, PDRVBLOCK);
-    LogFlow(("drvblockConstruct: iInstance=%d\n", pDrvIns->iInstance));
-    PDMDRV_CHECK_VERSIONS_RETURN(pDrvIns);
-
-    /*
-     * Validate configuration.
-     */
-#if defined(VBOX_PERIODIC_FLUSH) || defined(VBOX_IGNORE_FLUSH)
-    if (!CFGMR3AreValuesValid(pCfg, "Type\0Locked\0BIOSVisible\0AttachFailError\0Cylinders\0Heads\0Sectors\0Mountable\0FlushInterval\0IgnoreFlush\0IgnoreFlushAsync\0"))
-#else /* !(VBOX_PERIODIC_FLUSH || VBOX_IGNORE_FLUSH) */
-    if (!CFGMR3AreValuesValid(pCfg, "Type\0Locked\0BIOSVisible\0AttachFailError\0Cylinders\0Heads\0Sectors\0Mountable\0"))
-#endif /* !(VBOX_PERIODIC_FLUSH || VBOX_IGNORE_FLUSH) */
-        return VERR_PDM_DRVINS_UNKNOWN_CFG_VALUES;
-
-    /*
-     * Initialize most of the data members.
-     */
-    pThis->pDrvIns                          = pDrvIns;
-
-    /* IBase. */
-    pDrvIns->IBase.pfnQueryInterface        = drvblockQueryInterface;
-
-    /* IBlock. */
-    pThis->IBlock.pfnRead                   = drvblockRead;
-    pThis->IBlock.pfnReadPcBios             = drvblockReadPcBios;
-    pThis->IBlock.pfnWrite                  = drvblockWrite;
-    pThis->IBlock.pfnFlush                  = drvblockFlush;
-    pThis->IBlock.pfnMerge                  = drvblockMerge;
-    pThis->IBlock.pfnIsReadOnly             = drvblockIsReadOnly;
-    pThis->IBlock.pfnGetSize                = drvblockGetSize;
-    pThis->IBlock.pfnGetSectorSize          = drvblockGetSectorSize;
-    pThis->IBlock.pfnGetType                = drvblockGetType;
-    pThis->IBlock.pfnGetUuid                = drvblockGetUuid;
-    pThis->IBlock.pfnIoBufAlloc             = drvblockIoBufAlloc;
-    pThis->IBlock.pfnIoBufFree              = drvblockIoBufFree;
-
-    /* IBlockBios. */
-    pThis->IBlockBios.pfnGetPCHSGeometry    = drvblockGetPCHSGeometry;
-    pThis->IBlockBios.pfnSetPCHSGeometry    = drvblockSetPCHSGeometry;
-    pThis->IBlockBios.pfnGetLCHSGeometry    = drvblockGetLCHSGeometry;
-    pThis->IBlockBios.pfnSetLCHSGeometry    = drvblockSetLCHSGeometry;
-    pThis->IBlockBios.pfnIsVisible          = drvblockIsVisible;
-    pThis->IBlockBios.pfnGetType            = drvblockBiosGetType;
-
-    /* IMount. */
-    pThis->IMount.pfnMount                  = drvblockMount;
-    pThis->IMount.pfnUnmount                = drvblockUnmount;
-    pThis->IMount.pfnIsMounted              = drvblockIsMounted;
-    pThis->IMount.pfnLock                   = drvblockLock;
-    pThis->IMount.pfnUnlock                 = drvblockUnlock;
-    pThis->IMount.pfnIsLocked               = drvblockIsLocked;
-
-    /* IBlockAsync. */
-    pThis->IBlockAsync.pfnStartRead         = drvblockAsyncReadStart;
-    pThis->IBlockAsync.pfnStartWrite        = drvblockAsyncWriteStart;
-    pThis->IBlockAsync.pfnStartFlush        = drvblockAsyncFlushStart;
-
-    /* IMediaAsyncPort. */
-    pThis->IMediaAsyncPort.pfnTransferCompleteNotify  = drvblockAsyncTransferCompleteNotify;
-
-    /* IMediaPort */
-    pThis->IMediaPort.pfnQueryDeviceLocation = drvblockQueryDeviceLocation;
-
-    /*
-     * Get the IBlockPort & IMountNotify interfaces of the above driver/device.
-     */
-    pThis->pDrvBlockPort = PDMIBASE_QUERY_INTERFACE(pDrvIns->pUpBase, PDMIBLOCKPORT);
-    if (!pThis->pDrvBlockPort)
-        return PDMDRV_SET_ERROR(pDrvIns, VERR_PDM_MISSING_INTERFACE_ABOVE,
-                                N_("No block port interface above"));
-
-    /* Try to get the optional async block port interface above. */
-    pThis->pDrvBlockAsyncPort = PDMIBASE_QUERY_INTERFACE(pDrvIns->pUpBase, PDMIBLOCKASYNCPORT);
-    pThis->pDrvMountNotify    = PDMIBASE_QUERY_INTERFACE(pDrvIns->pUpBase, PDMIMOUNTNOTIFY);
-
-    /*
-     * Query configuration.
-     */
-    /* type */
-    char *psz;
-    int rc = CFGMR3QueryStringAlloc(pCfg, "Type", &psz);
-    if (RT_FAILURE(rc))
-        return PDMDRV_SET_ERROR(pDrvIns, VERR_PDM_BLOCK_NO_TYPE, N_("Failed to obtain the type"));
-    if (!strcmp(psz, "HardDisk"))
-        pThis->enmType = PDMBLOCKTYPE_HARD_DISK;
-    else if (!strcmp(psz, "DVD"))
-        pThis->enmType = PDMBLOCKTYPE_DVD;
-    else if (!strcmp(psz, "CDROM"))
-        pThis->enmType = PDMBLOCKTYPE_CDROM;
-    else if (!strcmp(psz, "Floppy 2.88"))
-        pThis->enmType = PDMBLOCKTYPE_FLOPPY_2_88;
-    else if (!strcmp(psz, "Floppy 1.44"))
-        pThis->enmType = PDMBLOCKTYPE_FLOPPY_1_44;
-    else if (!strcmp(psz, "Floppy 1.20"))
-        pThis->enmType = PDMBLOCKTYPE_FLOPPY_1_20;
-    else if (!strcmp(psz, "Floppy 720"))
-        pThis->enmType = PDMBLOCKTYPE_FLOPPY_720;
-    else if (!strcmp(psz, "Floppy 360"))
-        pThis->enmType = PDMBLOCKTYPE_FLOPPY_360;
-    else if (!strcmp(psz, "Floppy 15.6"))
-        pThis->enmType = PDMBLOCKTYPE_FLOPPY_FAKE_15_6;
-    else if (!strcmp(psz, "Floppy 63.5"))
-        pThis->enmType = PDMBLOCKTYPE_FLOPPY_FAKE_63_5;
-    else
-    {
-        PDMDrvHlpVMSetError(pDrvIns, VERR_PDM_BLOCK_UNKNOWN_TYPE, RT_SRC_POS,
-                            N_("Unknown type \"%s\""), psz);
-        MMR3HeapFree(psz);
-        return VERR_PDM_BLOCK_UNKNOWN_TYPE;
-    }
-    Log2(("drvblockConstruct: enmType=%d\n", pThis->enmType));
-    MMR3HeapFree(psz); psz = NULL;
-
-    /* Mountable */
-    rc = CFGMR3QueryBoolDef(pCfg, "Mountable", &pThis->fMountable, false);
-    if (RT_FAILURE(rc))
-        return PDMDRV_SET_ERROR(pDrvIns, rc, N_("Failed to query \"Mountable\" from the config"));
-
-    /* Locked */
-    rc = CFGMR3QueryBoolDef(pCfg, "Locked", &pThis->fLocked, false);
-    if (RT_FAILURE(rc))
-        return PDMDRV_SET_ERROR(pDrvIns, rc, N_("Failed to query \"Locked\" from the config"));
-
-    /* BIOS visible */
-    rc = CFGMR3QueryBoolDef(pCfg, "BIOSVisible", &pThis->fBiosVisible, true);
-    if (RT_FAILURE(rc))
-        return PDMDRV_SET_ERROR(pDrvIns, rc, N_("Failed to query \"BIOSVisible\" from the config"));
-
-    /** @todo AttachFailError is currently completely ignored. */
-
-    /* Cylinders */
-    rc = CFGMR3QueryU32Def(pCfg, "Cylinders", &pThis->LCHSGeometry.cCylinders, 0);
-    if (RT_FAILURE(rc))
-        return PDMDRV_SET_ERROR(pDrvIns, rc, N_("Failed to query \"Cylinders\" from the config"));
-
-    /* Heads */
-    rc = CFGMR3QueryU32Def(pCfg, "Heads", &pThis->LCHSGeometry.cHeads, 0);
-    if (RT_FAILURE(rc))
-        return PDMDRV_SET_ERROR(pDrvIns, rc, N_("Failed to query \"Heads\" from the config"));
-
-    /* Sectors */
-    rc = CFGMR3QueryU32Def(pCfg, "Sectors", &pThis->LCHSGeometry.cSectors, 0);
-    if (RT_FAILURE(rc))
-        return PDMDRV_SET_ERROR(pDrvIns, rc, N_("Failed to query \"Sectors\" from the config"));
-
-    /* Uuid */
-    rc = CFGMR3QueryStringAlloc(pCfg, "Uuid", &psz);
-    if (rc == VERR_CFGM_VALUE_NOT_FOUND)
-        RTUuidClear(&pThis->Uuid);
-    else if (RT_SUCCESS(rc))
-    {
-        rc = RTUuidFromStr(&pThis->Uuid, psz);
-        if (RT_FAILURE(rc))
-        {
-            PDMDrvHlpVMSetError(pDrvIns, rc, RT_SRC_POS, N_("Uuid from string failed on \"%s\""), psz);
-            MMR3HeapFree(psz);
-            return rc;
-        }
-        MMR3HeapFree(psz); psz = NULL;
-    }
-    else
-        return PDMDRV_SET_ERROR(pDrvIns, rc, N_("Failed to query \"Uuid\" from the config"));
-
-#ifdef VBOX_PERIODIC_FLUSH
-    rc = CFGMR3QueryU32Def(pCfg, "FlushInterval", &pThis->cbFlushInterval, 0);
-    if (RT_FAILURE(rc))
-        return PDMDRV_SET_ERROR(pDrvIns, rc, N_("Failed to query \"FlushInterval\" from the config"));
-#endif /* VBOX_PERIODIC_FLUSH */
-
-#ifdef VBOX_IGNORE_FLUSH
-    rc = CFGMR3QueryBoolDef(pCfg, "IgnoreFlush", &pThis->fIgnoreFlush, true);
-    if (RT_FAILURE(rc))
-        return PDMDRV_SET_ERROR(pDrvIns, rc, N_("Failed to query \"IgnoreFlush\" from the config"));
-
-    if (pThis->fIgnoreFlush)
-        LogRel(("DrvBlock: Flushes will be ignored\n"));
-    else
-        LogRel(("DrvBlock: Flushes will be passed to the disk\n"));
-
-    rc = CFGMR3QueryBoolDef(pCfg, "IgnoreFlushAsync", &pThis->fIgnoreFlushAsync, false);
-    if (RT_FAILURE(rc))
-        return PDMDRV_SET_ERROR(pDrvIns, rc, N_("Failed to query \"IgnoreFlushAsync\" from the config"));
-
-    if (pThis->fIgnoreFlushAsync)
-        LogRel(("DrvBlock: Async flushes will be ignored\n"));
-    else
-        LogRel(("DrvBlock: Async flushes will be passed to the disk\n"));
-#endif /* VBOX_IGNORE_FLUSH */
-
-    /*
-     * Try attach driver below and query it's media interface.
-     */
-    PPDMIBASE pBase;
-    rc = PDMDrvHlpAttach(pDrvIns, fFlags, &pBase);
-    if (    rc == VERR_PDM_NO_ATTACHED_DRIVER
-        &&  pThis->enmType != PDMBLOCKTYPE_HARD_DISK)
-        return VINF_SUCCESS;
-    if (RT_FAILURE(rc))
-        return PDMDrvHlpVMSetError(pDrvIns, rc, RT_SRC_POS,
-                                   N_("Failed to attach driver below us! %Rrf"), rc);
-
-    pThis->pDrvMedia = PDMIBASE_QUERY_INTERFACE(pBase, PDMIMEDIA);
-    if (!pThis->pDrvMedia)
-        return PDMDRV_SET_ERROR(pDrvIns, VERR_PDM_MISSING_INTERFACE_BELOW,
-                                N_("No media or async media interface below"));
-
-    /* Try to get the optional async interface. */
-    pThis->pDrvMediaAsync = PDMIBASE_QUERY_INTERFACE(pBase, PDMIMEDIAASYNC);
-
-    if (pThis->pDrvMedia->pfnDiscard)
-        pThis->IBlock.pfnDiscard = drvblockDiscard;
-
-    if (   pThis->pDrvMediaAsync
-        && pThis->pDrvMediaAsync->pfnStartDiscard)
-        pThis->IBlockAsync.pfnStartDiscard = drvblockStartDiscard;
-
-    if (RTUuidIsNull(&pThis->Uuid))
-    {
-        if (pThis->enmType == PDMBLOCKTYPE_HARD_DISK)
-            pThis->pDrvMedia->pfnGetUuid(pThis->pDrvMedia, &pThis->Uuid);
-    }
-
-    /*
-     * Automatically upgrade the floppy drive if the specified one is too
-     * small to represent the whole boot time image. (We cannot do this later
-     * since the BIOS (and others) gets the info via CMOS.)
-     *
-     * This trick should make 2.88 images as well as the fake 15.6 and 63.5 MB
-     * images despite the hardcoded default 1.44 drive.
-     */
-    if (   PDMBLOCKTYPE_IS_FLOPPY(pThis->enmType)
-        && pThis->pDrvMedia)
-    {
-        uint64_t     const cbFloppyImg = pThis->pDrvMedia->pfnGetSize(pThis->pDrvMedia);
-        PDMBLOCKTYPE const enmCfgType  = pThis->enmType;
-        switch (enmCfgType)
-        {
-            default:
-                AssertFailed();
-            case PDMBLOCKTYPE_FLOPPY_360:
-                if (cbFloppyImg > 40 * 2 * 9 * 512)
-                    pThis->enmType = PDMBLOCKTYPE_FLOPPY_360;
-                /* fall thru */
-            case PDMBLOCKTYPE_FLOPPY_720:
-                if (cbFloppyImg > 80 * 2 * 14 * 512)
-                    pThis->enmType = PDMBLOCKTYPE_FLOPPY_1_20;
-                /* fall thru */
-            case PDMBLOCKTYPE_FLOPPY_1_20:
-                if (cbFloppyImg > 80 * 2 * 20 * 512)
-                    pThis->enmType = PDMBLOCKTYPE_FLOPPY_1_44;
-                /* fall thru */
-            case PDMBLOCKTYPE_FLOPPY_1_44:
-                if (cbFloppyImg > 80 * 2 * 24 * 512)
-                    pThis->enmType = PDMBLOCKTYPE_FLOPPY_2_88;
-                /* fall thru */
-            case PDMBLOCKTYPE_FLOPPY_2_88:
-                if (cbFloppyImg > 80 * 2 * 48 * 512)
-                    pThis->enmType = PDMBLOCKTYPE_FLOPPY_FAKE_15_6;
-                /* fall thru */
-            case PDMBLOCKTYPE_FLOPPY_FAKE_15_6:
-                if (cbFloppyImg > 255 * 2 * 63 * 512)
-                    pThis->enmType = PDMBLOCKTYPE_FLOPPY_FAKE_63_5;
-            case PDMBLOCKTYPE_FLOPPY_FAKE_63_5:
-                if (cbFloppyImg > 255 * 2 * 255 * 512)
-                    LogRel(("Warning: Floppy image is larger that 63.5 MB! (%llu bytes)\n", cbFloppyImg));
-                break;
-        }
-        if (pThis->enmType != enmCfgType)
-            LogRel(("Automatically upgraded floppy drive from %s to %s to better support the %u byte image\n",
-                    drvblockGetTypeName(enmCfgType), drvblockGetTypeName(pThis->enmType), cbFloppyImg));
-    }
-
-    return VINF_SUCCESS;
-}
-
-
-/**
- * Block driver registration record.
- */
-const PDMDRVREG g_DrvBlock =
-{
-    /* u32Version */
-    PDM_DRVREG_VERSION,
-    /* szName */
-    "Block",
-    /* szRCMod */
-    "",
-    /* szR0Mod */
-    "",
-    /* pszDescription */
-    "Generic block driver.",
-    /* fFlags */
-    PDM_DRVREG_FLAGS_HOST_BITS_DEFAULT,
-    /* fClass. */
-    PDM_DRVREG_CLASS_BLOCK,
-    /* cMaxInstances */
-    ~0U,
-    /* cbInstance */
-    sizeof(DRVBLOCK),
-    /* pfnConstruct */
-    drvblockConstruct,
-    /* pfnDestruct */
-    NULL,
-    /* pfnRelocate */
-    NULL,
-    /* pfnIOCtl */
-    NULL,
-    /* pfnPowerOn */
-    NULL,
-    /* pfnReset */
-    drvblockReset,
-    /* pfnSuspend */
-    NULL,
-    /* pfnResume */
-    NULL,
-    /* pfnAttach */
-    NULL,
-    /* pfnDetach */
-    drvblockDetach,
-    /* pfnPowerOff */
-    NULL,
-    /* pfnSoftReset */
-    NULL,
-    /* u32EndVersion */
-    PDM_DRVREG_VERSION
-};
-
Index: trunk/src/VBox/Devices/Storage/DrvHostBase.cpp
===================================================================
--- trunk/src/VBox/Devices/Storage/DrvHostBase.cpp	(revision 59247)
+++ trunk/src/VBox/Devices/Storage/DrvHostBase.cpp	(revision 59248)
@@ -133,7 +133,7 @@
 
 /** @copydoc PDMIBLOCK::pfnRead */
-static DECLCALLBACK(int) drvHostBaseRead(PPDMIBLOCK pInterface, uint64_t off, void *pvBuf, size_t cbRead)
-{
-    PDRVHOSTBASE pThis = PDMIBLOCK_2_DRVHOSTBASE(pInterface);
+static DECLCALLBACK(int) drvHostBaseRead(PPDMIMEDIA pInterface, uint64_t off, void *pvBuf, size_t cbRead)
+{
+    PDRVHOSTBASE pThis = PDMIMEDIA_2_DRVHOSTBASE(pInterface);
     LogFlow(("%s-%d: drvHostBaseRead: off=%#llx pvBuf=%p cbRead=%#x (%s)\n",
              pThis->pDrvIns->pReg->szName, pThis->pDrvIns->iInstance, off, pvBuf, cbRead, pThis->pszDevice));
@@ -209,7 +209,7 @@
 
 /** @copydoc PDMIBLOCK::pfnWrite */
-static DECLCALLBACK(int) drvHostBaseWrite(PPDMIBLOCK pInterface, uint64_t off, const void *pvBuf, size_t cbWrite)
-{
-    PDRVHOSTBASE pThis = PDMIBLOCK_2_DRVHOSTBASE(pInterface);
+static DECLCALLBACK(int) drvHostBaseWrite(PPDMIMEDIA pInterface, uint64_t off, const void *pvBuf, size_t cbWrite)
+{
+    PDRVHOSTBASE pThis = PDMIMEDIA_2_DRVHOSTBASE(pInterface);
     LogFlow(("%s-%d: drvHostBaseWrite: off=%#llx pvBuf=%p cbWrite=%#x (%s)\n",
              pThis->pDrvIns->pReg->szName, pThis->pDrvIns->iInstance, off, pvBuf, cbWrite, pThis->pszDevice));
@@ -255,8 +255,8 @@
 
 /** @copydoc PDMIBLOCK::pfnFlush */
-static DECLCALLBACK(int) drvHostBaseFlush(PPDMIBLOCK pInterface)
+static DECLCALLBACK(int) drvHostBaseFlush(PPDMIMEDIA pInterface)
 {
     int rc;
-    PDRVHOSTBASE pThis = PDMIBLOCK_2_DRVHOSTBASE(pInterface);
+    PDRVHOSTBASE pThis = PDMIMEDIA_2_DRVHOSTBASE(pInterface);
     LogFlow(("%s-%d: drvHostBaseFlush: (%s)\n",
              pThis->pDrvIns->pReg->szName, pThis->pDrvIns->iInstance, pThis->pszDevice));
@@ -282,7 +282,7 @@
 
 /** @copydoc PDMIBLOCK::pfnIsReadOnly */
-static DECLCALLBACK(bool) drvHostBaseIsReadOnly(PPDMIBLOCK pInterface)
-{
-    PDRVHOSTBASE pThis = PDMIBLOCK_2_DRVHOSTBASE(pInterface);
+static DECLCALLBACK(bool) drvHostBaseIsReadOnly(PPDMIMEDIA pInterface)
+{
+    PDRVHOSTBASE pThis = PDMIMEDIA_2_DRVHOSTBASE(pInterface);
     return pThis->fReadOnly;
 }
@@ -290,7 +290,7 @@
 
 /** @copydoc PDMIBLOCK::pfnGetSize */
-static DECLCALLBACK(uint64_t) drvHostBaseGetSize(PPDMIBLOCK pInterface)
-{
-    PDRVHOSTBASE pThis = PDMIBLOCK_2_DRVHOSTBASE(pInterface);
+static DECLCALLBACK(uint64_t) drvHostBaseGetSize(PPDMIMEDIA pInterface)
+{
+    PDRVHOSTBASE pThis = PDMIMEDIA_2_DRVHOSTBASE(pInterface);
     RTCritSectEnter(&pThis->CritSect);
 
@@ -306,7 +306,7 @@
 
 /** @copydoc PDMIBLOCK::pfnGetType */
-static DECLCALLBACK(PDMBLOCKTYPE) drvHostBaseGetType(PPDMIBLOCK pInterface)
-{
-    PDRVHOSTBASE pThis = PDMIBLOCK_2_DRVHOSTBASE(pInterface);
+static DECLCALLBACK(PDMMEDIATYPE) drvHostBaseGetType(PPDMIMEDIA pInterface)
+{
+    PDRVHOSTBASE pThis = PDMIMEDIA_2_DRVHOSTBASE(pInterface);
     LogFlow(("%s-%d: drvHostBaseGetType: returns %d\n", pThis->pDrvIns->pReg->szName, pThis->pDrvIns->iInstance, pThis->enmType));
     return pThis->enmType;
@@ -315,7 +315,7 @@
 
 /** @copydoc PDMIBLOCK::pfnGetUuid */
-static DECLCALLBACK(int) drvHostBaseGetUuid(PPDMIBLOCK pInterface, PRTUUID pUuid)
-{
-    PDRVHOSTBASE pThis = PDMIBLOCK_2_DRVHOSTBASE(pInterface);
+static DECLCALLBACK(int) drvHostBaseGetUuid(PPDMIMEDIA pInterface, PRTUUID pUuid)
+{
+    PDRVHOSTBASE pThis = PDMIMEDIA_2_DRVHOSTBASE(pInterface);
 
     *pUuid = pThis->Uuid;
@@ -327,9 +327,9 @@
 
 /** @copydoc PDMIBLOCK::pfnIoBufAlloc */
-static DECLCALLBACK(int) drvHostBaseIoBufAlloc(PPDMIBLOCK pInterface, size_t cb, void **ppvNew)
+static DECLCALLBACK(int) drvHostBaseIoBufAlloc(PPDMIMEDIA pInterface, size_t cb, void **ppvNew)
 {
     LogFlowFunc(("\n"));
     int rc;
-    PDRVHOSTBASE pThis = PDMIBLOCK_2_DRVHOSTBASE(pInterface);
+    PDRVHOSTBASE pThis = PDMIMEDIA_2_DRVHOSTBASE(pInterface);
 
     void *pvNew = RTMemAlloc(cb);
@@ -347,9 +347,9 @@
 
 /** @copydoc PDMIBLOCK::pfnIoBufFree */
-static DECLCALLBACK(int) drvHostBaseIoBufFree(PPDMIBLOCK pInterface, void *pv, size_t cb)
+static DECLCALLBACK(int) drvHostBaseIoBufFree(PPDMIMEDIA pInterface, void *pv, size_t cb)
 {
     LogFlowFunc(("\n"));
     int rc = VINF_SUCCESS;
-    PDRVHOSTBASE pThis = PDMIBLOCK_2_DRVHOSTBASE(pInterface);
+    PDRVHOSTBASE pThis = PDMIMEDIA_2_DRVHOSTBASE(pInterface);
 
     NOREF(cb);
@@ -361,15 +361,8 @@
 
 
-
-/* -=-=-=-=- IBlockBios -=-=-=-=- */
-
-/** Makes a PDRVHOSTBASE out of a PPDMIBLOCKBIOS. */
-#define PDMIBLOCKBIOS_2_DRVHOSTBASE(pInterface)    ( (PDRVHOSTBASE((uintptr_t)pInterface - RT_OFFSETOF(DRVHOSTBASE, IBlockBios))) )
-
-
-/** @copydoc PDMIBLOCKBIOS::pfnGetPCHSGeometry */
-static DECLCALLBACK(int) drvHostBaseGetPCHSGeometry(PPDMIBLOCKBIOS pInterface, PPDMMEDIAGEOMETRY pPCHSGeometry)
-{
-    PDRVHOSTBASE pThis =  PDMIBLOCKBIOS_2_DRVHOSTBASE(pInterface);
+/** @copydoc PDMIBLOCKBIOS::pfnBiosGetPCHSGeometry */
+static DECLCALLBACK(int) drvHostBaseGetPCHSGeometry(PPDMIMEDIA pInterface, PPDMMEDIAGEOMETRY pPCHSGeometry)
+{
+    PDRVHOSTBASE pThis =  PDMIMEDIA_2_DRVHOSTBASE(pInterface);
     RTCritSectEnter(&pThis->CritSect);
 
@@ -396,8 +389,8 @@
 
 
-/** @copydoc PDMIBLOCKBIOS::pfnSetPCHSGeometry */
-static DECLCALLBACK(int) drvHostBaseSetPCHSGeometry(PPDMIBLOCKBIOS pInterface, PCPDMMEDIAGEOMETRY pPCHSGeometry)
-{
-    PDRVHOSTBASE pThis = PDMIBLOCKBIOS_2_DRVHOSTBASE(pInterface);
+/** @copydoc PDMIBLOCKBIOS::pfnBiosSetPCHSGeometry */
+static DECLCALLBACK(int) drvHostBaseSetPCHSGeometry(PPDMIMEDIA pInterface, PCPDMMEDIAGEOMETRY pPCHSGeometry)
+{
+    PDRVHOSTBASE pThis =  PDMIMEDIA_2_DRVHOSTBASE(pInterface);
     LogFlow(("%s-%d: %s: cCylinders=%d cHeads=%d cSectors=%d\n",
              pThis->pDrvIns->pReg->szName, pThis->pDrvIns->iInstance, __FUNCTION__, pPCHSGeometry->cCylinders, pPCHSGeometry->cHeads, pPCHSGeometry->cSectors));
@@ -421,7 +414,7 @@
 
 /** @copydoc PDMIBLOCKBIOS::pfnGetLCHSGeometry */
-static DECLCALLBACK(int) drvHostBaseGetLCHSGeometry(PPDMIBLOCKBIOS pInterface, PPDMMEDIAGEOMETRY pLCHSGeometry)
-{
-    PDRVHOSTBASE pThis =  PDMIBLOCKBIOS_2_DRVHOSTBASE(pInterface);
+static DECLCALLBACK(int) drvHostBaseGetLCHSGeometry(PPDMIMEDIA pInterface, PPDMMEDIAGEOMETRY pLCHSGeometry)
+{
+    PDRVHOSTBASE pThis =  PDMIMEDIA_2_DRVHOSTBASE(pInterface);
     RTCritSectEnter(&pThis->CritSect);
 
@@ -449,7 +442,7 @@
 
 /** @copydoc PDMIBLOCKBIOS::pfnSetLCHSGeometry */
-static DECLCALLBACK(int) drvHostBaseSetLCHSGeometry(PPDMIBLOCKBIOS pInterface, PCPDMMEDIAGEOMETRY pLCHSGeometry)
-{
-    PDRVHOSTBASE pThis = PDMIBLOCKBIOS_2_DRVHOSTBASE(pInterface);
+static DECLCALLBACK(int) drvHostBaseSetLCHSGeometry(PPDMIMEDIA pInterface, PCPDMMEDIAGEOMETRY pLCHSGeometry)
+{
+    PDRVHOSTBASE pThis =  PDMIMEDIA_2_DRVHOSTBASE(pInterface);
     LogFlow(("%s-%d: %s: cCylinders=%d cHeads=%d cSectors=%d\n",
              pThis->pDrvIns->pReg->szName, pThis->pDrvIns->iInstance, __FUNCTION__, pLCHSGeometry->cCylinders, pLCHSGeometry->cHeads, pLCHSGeometry->cSectors));
@@ -473,30 +466,13 @@
 
 /** @copydoc PDMIBLOCKBIOS::pfnIsVisible */
-static DECLCALLBACK(bool) drvHostBaseIsVisible(PPDMIBLOCKBIOS pInterface)
-{
-    PDRVHOSTBASE pThis = PDMIBLOCKBIOS_2_DRVHOSTBASE(pInterface);
+static DECLCALLBACK(bool) drvHostBaseIsVisible(PPDMIMEDIA pInterface)
+{
+    PDRVHOSTBASE pThis =  PDMIMEDIA_2_DRVHOSTBASE(pInterface);
     return pThis->fBiosVisible;
 }
 
 
-/** @copydoc PDMIBLOCKBIOS::pfnGetType */
-static DECLCALLBACK(PDMBLOCKTYPE) drvHostBaseBiosGetType(PPDMIBLOCKBIOS pInterface)
-{
-    PDRVHOSTBASE pThis = PDMIBLOCKBIOS_2_DRVHOSTBASE(pInterface);
-    return pThis->enmType;
-}
-
-
 
 /* -=-=-=-=- IMount -=-=-=-=- */
-
-/** @copydoc PDMIMOUNT::pfnMount */
-static DECLCALLBACK(int) drvHostBaseMount(PPDMIMOUNT pInterface, const char *pszFilename, const char *pszCoreDriver)
-{
-    /* We're not mountable. */
-    AssertMsgFailed(("drvHostBaseMount: This shouldn't be called!\n"));
-    return VERR_PDM_MEDIA_MOUNTED;
-}
-
 
 /** @copydoc PDMIMOUNT::pfnUnmount */
@@ -622,6 +598,5 @@
 
     PDMIBASE_RETURN_INTERFACE(pszIID, PDMIBASE, &pDrvIns->IBase);
-    PDMIBASE_RETURN_INTERFACE(pszIID, PDMIBLOCK, &pThis->IBlock);
-    PDMIBASE_RETURN_INTERFACE(pszIID, PDMIBLOCKBIOS, pThis->fBiosVisible ? &pThis->IBlockBios : NULL);
+    PDMIBASE_RETURN_INTERFACE(pszIID, PDMIMEDIA, &pThis->IMedia);
     PDMIBASE_RETURN_INTERFACE(pszIID, PDMIMOUNT, &pThis->IMount);
     return NULL;
@@ -1887,5 +1862,5 @@
  * @param   enmType         Device type.
  */
-int DRVHostBaseInitData(PPDMDRVINS pDrvIns, PCFGMNODE pCfg, PDMBLOCKTYPE enmType)
+int DRVHostBaseInitData(PPDMDRVINS pDrvIns, PCFGMNODE pCfg, PDMMEDIATYPE enmType)
 {
     PDRVHOSTBASE pThis = PDMINS_2_DATA(pDrvIns, PDRVHOSTBASE);
@@ -1920,25 +1895,21 @@
     pDrvIns->IBase.pfnQueryInterface        = drvHostBaseQueryInterface;
 
-    /* IBlock. */
-    pThis->IBlock.pfnRead                   = drvHostBaseRead;
-    pThis->IBlock.pfnWrite                  = drvHostBaseWrite;
-    pThis->IBlock.pfnFlush                  = drvHostBaseFlush;
-    pThis->IBlock.pfnIsReadOnly             = drvHostBaseIsReadOnly;
-    pThis->IBlock.pfnGetSize                = drvHostBaseGetSize;
-    pThis->IBlock.pfnGetType                = drvHostBaseGetType;
-    pThis->IBlock.pfnGetUuid                = drvHostBaseGetUuid;
-    pThis->IBlock.pfnIoBufAlloc             = drvHostBaseIoBufAlloc;
-    pThis->IBlock.pfnIoBufFree              = drvHostBaseIoBufFree;
-
-    /* IBlockBios. */
-    pThis->IBlockBios.pfnGetPCHSGeometry    = drvHostBaseGetPCHSGeometry;
-    pThis->IBlockBios.pfnSetPCHSGeometry    = drvHostBaseSetPCHSGeometry;
-    pThis->IBlockBios.pfnGetLCHSGeometry    = drvHostBaseGetLCHSGeometry;
-    pThis->IBlockBios.pfnSetLCHSGeometry    = drvHostBaseSetLCHSGeometry;
-    pThis->IBlockBios.pfnIsVisible          = drvHostBaseIsVisible;
-    pThis->IBlockBios.pfnGetType            = drvHostBaseBiosGetType;
+    /* IMedia. */
+    pThis->IMedia.pfnRead                   = drvHostBaseRead;
+    pThis->IMedia.pfnWrite                  = drvHostBaseWrite;
+    pThis->IMedia.pfnFlush                  = drvHostBaseFlush;
+    pThis->IMedia.pfnIsReadOnly             = drvHostBaseIsReadOnly;
+    pThis->IMedia.pfnGetSize                = drvHostBaseGetSize;
+    pThis->IMedia.pfnGetType                = drvHostBaseGetType;
+    pThis->IMedia.pfnGetUuid                = drvHostBaseGetUuid;
+    pThis->IMedia.pfnIoBufAlloc             = drvHostBaseIoBufAlloc;
+    pThis->IMedia.pfnIoBufFree              = drvHostBaseIoBufFree;
+    pThis->IMedia.pfnBiosGetPCHSGeometry    = drvHostBaseGetPCHSGeometry;
+    pThis->IMedia.pfnBiosSetPCHSGeometry    = drvHostBaseSetPCHSGeometry;
+    pThis->IMedia.pfnBiosGetLCHSGeometry    = drvHostBaseGetLCHSGeometry;
+    pThis->IMedia.pfnBiosSetLCHSGeometry    = drvHostBaseSetLCHSGeometry;
+    pThis->IMedia.pfnBiosIsVisible          = drvHostBaseIsVisible;
 
     /* IMount. */
-    pThis->IMount.pfnMount                  = drvHostBaseMount;
     pThis->IMount.pfnUnmount                = drvHostBaseUnmount;
     pThis->IMount.pfnIsMounted              = drvHostBaseIsMounted;
@@ -1950,8 +1921,8 @@
      * Get the IBlockPort & IMountNotify interfaces of the above driver/device.
      */
-    pThis->pDrvBlockPort = PDMIBASE_QUERY_INTERFACE(pDrvIns->pUpBase, PDMIBLOCKPORT);
-    if (!pThis->pDrvBlockPort)
-    {
-        AssertMsgFailed(("Configuration error: No block port interface above!\n"));
+    pThis->pDrvMediaPort = PDMIBASE_QUERY_INTERFACE(pDrvIns->pUpBase, PDMIMEDIAPORT);
+    if (!pThis->pDrvMediaPort)
+    {
+        AssertMsgFailed(("Configuration error: No media port interface above!\n"));
         return VERR_PDM_MISSING_INTERFACE_ABOVE;
     }
@@ -1985,5 +1956,5 @@
     rc = CFGMR3QueryBool(pCfg, "ReadOnly", &pThis->fReadOnlyConfig);
     if (rc == VERR_CFGM_VALUE_NOT_FOUND)
-        pThis->fReadOnlyConfig = enmType == PDMBLOCKTYPE_DVD || enmType == PDMBLOCKTYPE_CDROM ? true : false;
+        pThis->fReadOnlyConfig = enmType == PDMMEDIATYPE_DVD || enmType == PDMMEDIATYPE_CDROM ? true : false;
     else if (RT_FAILURE(rc))
     {
@@ -2112,11 +2083,11 @@
     switch (pThis->enmType)
     {
-        case PDMBLOCKTYPE_FLOPPY_360:
-        case PDMBLOCKTYPE_FLOPPY_720:
-        case PDMBLOCKTYPE_FLOPPY_1_20:
-        case PDMBLOCKTYPE_FLOPPY_1_44:
-        case PDMBLOCKTYPE_FLOPPY_2_88:
-        case PDMBLOCKTYPE_FLOPPY_FAKE_15_6:
-        case PDMBLOCKTYPE_FLOPPY_FAKE_63_5:
+        case PDMMEDIATYPE_FLOPPY_360:
+        case PDMMEDIATYPE_FLOPPY_720:
+        case PDMMEDIATYPE_FLOPPY_1_20:
+        case PDMMEDIATYPE_FLOPPY_1_44:
+        case PDMMEDIATYPE_FLOPPY_2_88:
+        case PDMMEDIATYPE_FLOPPY_FAKE_15_6:
+        case PDMMEDIATYPE_FLOPPY_FAKE_63_5:
             if (uDriveType != DRIVE_REMOVABLE)
             {
@@ -2126,6 +2097,6 @@
             }
             break;
-        case PDMBLOCKTYPE_CDROM:
-        case PDMBLOCKTYPE_DVD:
+        case PDMMEDIATYPE_CDROM:
+        case PDMMEDIATYPE_DVD:
             if (uDriveType != DRIVE_CDROM)
             {
@@ -2135,5 +2106,5 @@
             }
             break;
-        case PDMBLOCKTYPE_HARD_DISK:
+        case PDMMEDIATYPE_HARD_DISK:
         default:
             AssertMsgFailed(("enmType=%d\n", pThis->enmType));
@@ -2171,5 +2142,5 @@
          * "media" - actually a complete drive in this case.
          */
-        pThis->IBlock.pfnSendCmd = NULL;
+        pThis->IMedia.pfnSendCmd = NULL;
         AssertMsgFailed(("Could not open host device %s, rc=%Rrc\n", pszDevice, rc));
         switch (rc)
Index: trunk/src/VBox/Devices/Storage/DrvHostBase.h
===================================================================
--- trunk/src/VBox/Devices/Storage/DrvHostBase.h	(revision 59247)
+++ trunk/src/VBox/Devices/Storage/DrvHostBase.h	(revision 59248)
@@ -41,5 +41,5 @@
     PPDMDRVINS              pDrvIns;
     /** Drive type. */
-    PDMBLOCKTYPE            enmType;
+    PDMMEDIATYPE            enmType;
     /** Visible to the BIOS. */
     bool                    fBiosVisible;
@@ -64,11 +64,9 @@
 
     /** Pointer to the block port interface above us. */
-    PPDMIBLOCKPORT          pDrvBlockPort;
+    PPDMIMEDIAPORT          pDrvMediaPort;
     /** Pointer to the mount notify interface above us. */
     PPDMIMOUNTNOTIFY        pDrvMountNotify;
-    /** Our block interface. */
-    PDMIBLOCK               IBlock;
-    /** Our block interface. */
-    PDMIBLOCKBIOS           IBlockBios;
+    /** Our media interface. */
+    PDMIMEDIA               IMedia;
     /** Our mountable interface. */
     PDMIMOUNT               IMount;
@@ -181,5 +179,5 @@
 
 
-int DRVHostBaseInitData(PPDMDRVINS pDrvIns, PCFGMNODE pCfg, PDMBLOCKTYPE enmType);
+int DRVHostBaseInitData(PPDMDRVINS pDrvIns, PCFGMNODE pCfg, PDMMEDIATYPE enmType);
 int DRVHostBaseInitFinish(PDRVHOSTBASE pThis);
 int DRVHostBaseMediaPresent(PDRVHOSTBASE pThis);
@@ -195,6 +193,6 @@
 #define PDMIMOUNT_2_DRVHOSTBASE(pInterface)        ( (PDRVHOSTBASE)((uintptr_t)pInterface - RT_OFFSETOF(DRVHOSTBASE, IMount)) )
 
-/** Makes a PDRVHOSTBASE out of a PPDMIBLOCK. */
-#define PDMIBLOCK_2_DRVHOSTBASE(pInterface)        ( (PDRVHOSTBASE)((uintptr_t)pInterface - RT_OFFSETOF(DRVHOSTBASE, IBlock)) )
+/** Makes a PDRVHOSTBASE out of a PPDMIMEDIA. */
+#define PDMIMEDIA_2_DRVHOSTBASE(pInterface)        ( (PDRVHOSTBASE)((uintptr_t)pInterface - RT_OFFSETOF(DRVHOSTBASE, IMedia)) )
 
 RT_C_DECLS_END
Index: trunk/src/VBox/Devices/Storage/DrvHostDVD.cpp
===================================================================
--- trunk/src/VBox/Devices/Storage/DrvHostDVD.cpp	(revision 59247)
+++ trunk/src/VBox/Devices/Storage/DrvHostDVD.cpp	(revision 59248)
@@ -151,5 +151,5 @@
                 0,0,0,0,0,0,0,0,0,0
             };
-            rc = DRVHostBaseScsiCmd(pThis, abCmd, 6, PDMBLOCKTXDIR_NONE, NULL, NULL, NULL, 0, 0);
+            rc = DRVHostBaseScsiCmd(pThis, abCmd, 6, PDMMEDIATXDIR_NONE, NULL, NULL, NULL, 0, 0);
 
 #elif defined(RT_OS_LINUX)
@@ -241,5 +241,5 @@
         0,0,0,0,0,0,0,0,0,0
     };
-    int rc = DRVHostBaseScsiCmd(pThis, abCmd, 6, PDMBLOCKTXDIR_NONE, NULL, NULL, NULL, 0, 0);
+    int rc = DRVHostBaseScsiCmd(pThis, abCmd, 6, PDMMEDIATXDIR_NONE, NULL, NULL, NULL, 0, 0);
 
 #elif defined(RT_OS_LINUX)
@@ -335,5 +335,5 @@
     uint8_t abCmd[16] = { SCSI_TEST_UNIT_READY, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 };
     uint8_t abSense[32];
-    int rc2 = DRVHostBaseScsiCmd(pThis, abCmd, 6, PDMBLOCKTXDIR_NONE, NULL, NULL, abSense, sizeof(abSense), 0);
+    int rc2 = DRVHostBaseScsiCmd(pThis, abCmd, 6, PDMMEDIATXDIR_NONE, NULL, NULL, abSense, sizeof(abSense), 0);
     if (RT_SUCCESS(rc2))
         fMediaPresent = true;
@@ -414,10 +414,10 @@
 
 
-/** @copydoc PDMIBLOCK::pfnSendCmd */
-static DECLCALLBACK(int) drvHostDvdSendCmd(PPDMIBLOCK pInterface, const uint8_t *pbCmd,
-                                           PDMBLOCKTXDIR enmTxDir, void *pvBuf, uint32_t *pcbBuf,
+/** @copydoc PDMIMEDIA::pfnSendCmd */
+static DECLCALLBACK(int) drvHostDvdSendCmd(PPDMIMEDIA pInterface, const uint8_t *pbCmd,
+                                           PDMMEDIATXDIR enmTxDir, void *pvBuf, uint32_t *pcbBuf,
                                            uint8_t *pabSense, size_t cbSense, uint32_t cTimeoutMillies)
 {
-    PDRVHOSTBASE pThis = PDMIBLOCK_2_DRVHOSTBASE(pInterface);
+    PDRVHOSTBASE pThis = PDMIMEDIA_2_DRVHOSTBASE(pInterface);
     int rc;
     LogFlow(("%s: cmd[0]=%#04x txdir=%d pcbBuf=%d timeout=%d\n", __FUNCTION__, pbCmd[0], enmTxDir, *pcbBuf, cTimeoutMillies));
@@ -428,7 +428,7 @@
      * The command seems to be 12 bytes long, the docs a bit copy&pasty on the command length point...
      */
-    if (enmTxDir == PDMBLOCKTXDIR_FROM_DEVICE)
+    if (enmTxDir == PDMMEDIATXDIR_FROM_DEVICE)
         memset(pvBuf, '\0', *pcbBuf); /* we got read size, but zero it anyway. */
-    rc = DRVHostBaseScsiCmd(pThis, pbCmd, 12, PDMBLOCKTXDIR_FROM_DEVICE, pvBuf, pcbBuf, pabSense, cbSense, cTimeoutMillies);
+    rc = DRVHostBaseScsiCmd(pThis, pbCmd, 12, PDMMEDIATXDIR_FROM_DEVICE, pvBuf, pcbBuf, pabSense, cbSense, cTimeoutMillies);
     if (rc == VERR_UNRESOLVED_ERROR)
         /* sense information set */
@@ -441,9 +441,9 @@
     switch (enmTxDir)
     {
-        case PDMBLOCKTXDIR_NONE:
+        case PDMMEDIATXDIR_NONE:
             Assert(*pcbBuf == 0);
             direction = CGC_DATA_NONE;
             break;
-        case PDMBLOCKTXDIR_FROM_DEVICE:
+        case PDMMEDIATXDIR_FROM_DEVICE:
             Assert(*pcbBuf != 0);
             Assert(*pcbBuf <= SCSI_MAX_BUFFER_SIZE);
@@ -458,5 +458,5 @@
             direction = CGC_DATA_READ;
             break;
-        case PDMBLOCKTXDIR_TO_DEVICE:
+        case PDMMEDIATXDIR_TO_DEVICE:
             Assert(*pcbBuf != 0);
             Assert(*pcbBuf <= SCSI_MAX_BUFFER_SIZE);
@@ -495,5 +495,5 @@
     switch (enmTxDir)
     {
-        case PDMBLOCKTXDIR_FROM_DEVICE:
+        case PDMMEDIATXDIR_FROM_DEVICE:
             memcpy(pvBuf, pThis->pbDoubleBuffer, *pcbBuf);
             break;
@@ -514,5 +514,5 @@
     switch (enmTxDir)
     {
-        case PDMBLOCKTXDIR_NONE:
+        case PDMMEDIATXDIR_NONE:
             Assert(*pcbBuf == 0);
             usc.uscsi_flags = USCSI_READ;
@@ -520,5 +520,5 @@
             break;
 
-        case PDMBLOCKTXDIR_FROM_DEVICE:
+        case PDMMEDIATXDIR_FROM_DEVICE:
             Assert(*pcbBuf != 0);
             /* Make sure that the buffer is clear for commands reading
@@ -532,5 +532,5 @@
             usc.uscsi_flags = USCSI_READ;
             break;
-        case PDMBLOCKTXDIR_TO_DEVICE:
+        case PDMMEDIATXDIR_TO_DEVICE:
             Assert(*pcbBuf != 0);
             usc.uscsi_flags = USCSI_WRITE;
@@ -581,8 +581,8 @@
     switch (enmTxDir)
     {
-        case PDMBLOCKTXDIR_NONE:
+        case PDMMEDIATXDIR_NONE:
             direction = SCSI_IOCTL_DATA_UNSPECIFIED;
             break;
-        case PDMBLOCKTXDIR_FROM_DEVICE:
+        case PDMMEDIATXDIR_FROM_DEVICE:
             Assert(*pcbBuf != 0);
             /* Make sure that the buffer is clear for commands reading
@@ -596,5 +596,5 @@
             direction = SCSI_IOCTL_DATA_IN;
             break;
-        case PDMBLOCKTXDIR_TO_DEVICE:
+        case PDMMEDIATXDIR_TO_DEVICE:
             direction = SCSI_IOCTL_DATA_OUT;
             break;
@@ -754,5 +754,5 @@
      * Init instance data.
      */
-    int rc = DRVHostBaseInitData(pDrvIns, pCfg, PDMBLOCKTYPE_DVD);
+    int rc = DRVHostBaseInitData(pDrvIns, pCfg, PDMMEDIATYPE_DVD);
     if (RT_SUCCESS(rc))
     {
@@ -775,5 +775,5 @@
             if (RT_SUCCESS(rc) && fPassthrough)
             {
-                pThis->IBlock.pfnSendCmd = drvHostDvdSendCmd;
+                pThis->IMedia.pfnSendCmd = drvHostDvdSendCmd;
                 /* Passthrough requires opening the device in R/W mode. */
                 pThis->fReadOnlyConfig = false;
Index: trunk/src/VBox/Devices/Storage/DrvHostFloppy.cpp
===================================================================
--- trunk/src/VBox/Devices/Storage/DrvHostFloppy.cpp	(revision 59247)
+++ trunk/src/VBox/Devices/Storage/DrvHostFloppy.cpp	(revision 59248)
@@ -188,5 +188,5 @@
      * Init instance data.
      */
-    int rc = DRVHostBaseInitData(pDrvIns, pCfg, PDMBLOCKTYPE_FLOPPY_1_44);
+    int rc = DRVHostBaseInitData(pDrvIns, pCfg, PDMMEDIATYPE_FLOPPY_1_44);
     if (RT_SUCCESS(rc))
     {
Index: trunk/src/VBox/Devices/Storage/DrvMediaISO.cpp
===================================================================
--- trunk/src/VBox/Devices/Storage/DrvMediaISO.cpp	(revision 59247)
+++ 	(revision )
@@ -1,323 +1,0 @@
-/* $Id$ */
-/** @file
- * VBox storage devices: ISO image media driver
- */
-
-/*
- * Copyright (C) 2006-2015 Oracle Corporation
- *
- * This file is part of VirtualBox Open Source Edition (OSE), as
- * available from http://www.virtualbox.org. This file is free software;
- * you can redistribute it and/or modify it under the terms of the GNU
- * General Public License (GPL) as published by the Free Software
- * Foundation, in version 2 as it comes in the "COPYING" file of the
- * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
- * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
- */
-
-
-/*********************************************************************************************************************************
-*   Header Files                                                                                                                 *
-*********************************************************************************************************************************/
-#define LOG_GROUP LOG_GROUP_DRV_ISO
-#include <VBox/vmm/pdmdrv.h>
-#include <iprt/assert.h>
-#include <iprt/file.h>
-#include <iprt/string.h>
-#include <iprt/uuid.h>
-
-#include "VBoxDD.h"
-
-
-/*********************************************************************************************************************************
-*   Defined Constants And Macros                                                                                                 *
-*********************************************************************************************************************************/
-/** Converts a pointer to MEDIAISO::IMedia to a PRDVMEDIAISO. */
-#define PDMIMEDIA_2_DRVMEDIAISO(pInterface) ( (PDRVMEDIAISO)((uintptr_t)pInterface - RT_OFFSETOF(DRVMEDIAISO, IMedia)) )
-
-
-/*********************************************************************************************************************************
-*   Structures and Typedefs                                                                                                      *
-*********************************************************************************************************************************/
-/**
- * Block driver instance data.
- *
- * @implements PDMIMEDIA
- */
-typedef struct DRVMEDIAISO
-{
-    /** The media interface. */
-    PDMIMEDIA       IMedia;
-    /** Pointer to the driver instance. */
-    PPDMDRVINS      pDrvIns;
-    /** Pointer to the filename. (Freed by MM) */
-    char           *pszFilename;
-    /** File handle of the ISO file. */
-    RTFILE          hFile;
-} DRVMEDIAISO, *PDRVMEDIAISO;
-
-
-
-/* -=-=-=-=- PDMIMEDIA -=-=-=-=- */
-
-/** @copydoc PDMIMEDIA::pfnGetSize */
-static DECLCALLBACK(uint64_t) drvMediaISOGetSize(PPDMIMEDIA pInterface)
-{
-    PDRVMEDIAISO pThis = PDMIMEDIA_2_DRVMEDIAISO(pInterface);
-    LogFlow(("drvMediaISOGetSize: '%s'\n", pThis->pszFilename));
-
-    uint64_t cbFile;
-    int rc = RTFileGetSize(pThis->hFile, &cbFile);
-    if (RT_SUCCESS(rc))
-    {
-        LogFlow(("drvMediaISOGetSize: returns %lld (%s)\n", cbFile, pThis->pszFilename));
-        return cbFile;
-    }
-
-    AssertMsgFailed(("Error querying ISO file size, rc=%Rrc. (%s)\n", rc, pThis->pszFilename));
-    return 0;
-}
-
-
-/** @copydoc PDMIMEDIA::pfnBiosGetPCHSGeometry */
-static DECLCALLBACK(int) drvMediaISOBiosGetPCHSGeometry(PPDMIMEDIA pInterface, PPDMMEDIAGEOMETRY pPCHSGeometry)
-{
-    return VERR_NOT_IMPLEMENTED;
-}
-
-
-/** @copydoc PDMIMEDIA::pfnBiosSetPCHSGeometry */
-static DECLCALLBACK(int) drvMediaISOBiosSetPCHSGeometry(PPDMIMEDIA pInterface, PCPDMMEDIAGEOMETRY pPCHSGeometry)
-{
-    return VERR_NOT_IMPLEMENTED;
-}
-
-
-/** @copydoc PDMIMEDIA::pfnBiosGetLCHSGeometry */
-static DECLCALLBACK(int) drvMediaISOBiosGetLCHSGeometry(PPDMIMEDIA pInterface, PPDMMEDIAGEOMETRY pLCHSGeometry)
-{
-    return VERR_NOT_IMPLEMENTED;
-}
-
-
-/** @copydoc PDMIMEDIA::pfnBiosSetLCHSGeometry */
-static DECLCALLBACK(int) drvMediaISOBiosSetLCHSGeometry(PPDMIMEDIA pInterface, PCPDMMEDIAGEOMETRY pLCHSGeometry)
-{
-    return VERR_NOT_IMPLEMENTED;
-}
-
-
-/**
- * Read bits.
- *
- * @see PDMIMEDIA::pfnRead for details.
- */
-static DECLCALLBACK(int) drvMediaISORead(PPDMIMEDIA pInterface, uint64_t off, void *pvBuf, size_t cbRead)
-{
-    PDRVMEDIAISO pThis = PDMIMEDIA_2_DRVMEDIAISO(pInterface);
-    LogFlow(("drvMediaISORead: off=%#llx pvBuf=%p cbRead=%#x (%s)\n", off, pvBuf, cbRead, pThis->pszFilename));
-
-    Assert(pThis->hFile != NIL_RTFILE);
-    Assert(pvBuf);
-
-    /*
-     * Seek to the position and read.
-     */
-    int rc = RTFileReadAt(pThis->hFile, off, pvBuf, cbRead, NULL);
-    if (RT_SUCCESS(rc))
-        Log2(("drvMediaISORead: off=%#llx pvBuf=%p cbRead=%#x (%s)\n"
-              "%16.*Rhxd\n",
-              off, pvBuf, cbRead, pThis->pszFilename,
-              cbRead, pvBuf));
-    else
-        AssertMsgFailed(("RTFileReadAt(%RTfile, %#llx, %p, %#x) -> %Rrc ('%s')\n",
-                         pThis->hFile, off, pvBuf, cbRead, rc, pThis->pszFilename));
-    LogFlow(("drvMediaISORead: returns %Rrc\n", rc));
-    return rc;
-}
-
-
-/** @copydoc PDMIMEDIA::pfnWrite */
-static DECLCALLBACK(int) drvMediaISOWrite(PPDMIMEDIA pInterface, uint64_t off, const void *pvBuf, size_t cbWrite)
-{
-    AssertMsgFailed(("Attempt to write to an ISO file!\n"));
-    return VERR_NOT_IMPLEMENTED;
-}
-
-
-/** @copydoc PDMIMEDIA::pfnFlush */
-static DECLCALLBACK(int) drvMediaISOFlush(PPDMIMEDIA pInterface)
-{
-    /* No buffered data that still needs to be written. */
-    return VINF_SUCCESS;
-}
-
-
-/** @copydoc PDMIMEDIA::pfnGetUuid */
-static DECLCALLBACK(int) drvMediaISOGetUuid(PPDMIMEDIA pInterface, PRTUUID pUuid)
-{
-    LogFlow(("drvMediaISOGetUuid: returns VERR_NOT_IMPLEMENTED\n"));
-    return VERR_NOT_IMPLEMENTED;
-}
-
-
-/** @copydoc PDMIMEDIA::pfnIsReadOnly */
-static DECLCALLBACK(bool) drvMediaISOIsReadOnly(PPDMIMEDIA pInterface)
-{
-    return true;
-}
-
-/* -=-=-=-=- PDMIBASE -=-=-=-=- */
-
-/**
- * @interface_method_impl{PDMIBASE,pfnQueryInterface}
- */
-static DECLCALLBACK(void *) drvMediaISOQueryInterface(PPDMIBASE pInterface, const char *pszIID)
-{
-    PPDMDRVINS pDrvIns = PDMIBASE_2_PDMDRV(pInterface);
-    PDRVMEDIAISO pThis = PDMINS_2_DATA(pDrvIns, PDRVMEDIAISO);
-    PDMIBASE_RETURN_INTERFACE(pszIID, PDMIBASE, &pDrvIns->IBase);
-    PDMIBASE_RETURN_INTERFACE(pszIID, PDMIMEDIA, &pThis->IMedia);
-    return NULL;
-}
-
-/* -=-=-=-=- PDMDRVREG -=-=-=-=- */
-
-/**
- * Destruct a driver instance.
- *
- * Most VM resources are freed by the VM. This callback is provided so that any non-VM
- * resources can be freed correctly.
- *
- * @param   pDrvIns     The driver instance data.
- */
-static DECLCALLBACK(void) drvMediaISODestruct(PPDMDRVINS pDrvIns)
-{
-    PDRVMEDIAISO pThis = PDMINS_2_DATA(pDrvIns, PDRVMEDIAISO);
-    LogFlow(("drvMediaISODestruct: '%s'\n", pThis->pszFilename));
-    PDMDRV_CHECK_VERSIONS_RETURN_VOID(pDrvIns);
-
-    if (pThis->hFile != NIL_RTFILE)
-    {
-        RTFileClose(pThis->hFile);
-        pThis->hFile = NIL_RTFILE;
-    }
-
-    if (pThis->pszFilename)
-    {
-        MMR3HeapFree(pThis->pszFilename);
-        pThis->pszFilename = NULL;
-    }
-}
-
-
-/**
- * Construct a ISO media driver instance.
- *
- * @copydoc FNPDMDRVCONSTRUCT
- */
-static DECLCALLBACK(int) drvMediaISOConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfg, uint32_t fFlags)
-{
-    PDRVMEDIAISO pThis = PDMINS_2_DATA(pDrvIns, PDRVMEDIAISO);
-    PDMDRV_CHECK_VERSIONS_RETURN(pDrvIns);
-
-    /*
-     * Init the static parts.
-     */
-    pThis->pDrvIns                      = pDrvIns;
-    pThis->hFile                        = NIL_RTFILE;
-    /* IBase */
-    pDrvIns->IBase.pfnQueryInterface    = drvMediaISOQueryInterface;
-    /* IMedia */
-    pThis->IMedia.pfnRead               = drvMediaISORead;
-    pThis->IMedia.pfnWrite              = drvMediaISOWrite;
-    pThis->IMedia.pfnFlush              = drvMediaISOFlush;
-    pThis->IMedia.pfnGetSize            = drvMediaISOGetSize;
-    pThis->IMedia.pfnGetUuid            = drvMediaISOGetUuid;
-    pThis->IMedia.pfnIsReadOnly         = drvMediaISOIsReadOnly;
-    pThis->IMedia.pfnBiosGetPCHSGeometry = drvMediaISOBiosGetPCHSGeometry;
-    pThis->IMedia.pfnBiosSetPCHSGeometry = drvMediaISOBiosSetPCHSGeometry;
-    pThis->IMedia.pfnBiosGetLCHSGeometry = drvMediaISOBiosGetLCHSGeometry;
-    pThis->IMedia.pfnBiosSetLCHSGeometry = drvMediaISOBiosSetLCHSGeometry;
-
-    /*
-     * Read the configuration.
-     */
-    if (!CFGMR3AreValuesValid(pCfg, "Path\0"))
-        return VERR_PDM_DRVINS_UNKNOWN_CFG_VALUES;
-
-    char *pszName;
-    int rc = CFGMR3QueryStringAlloc(pCfg, "Path", &pszName);
-    if (RT_FAILURE(rc))
-        return PDMDRV_SET_ERROR(pDrvIns, rc, N_("Failed to query \"Path\" from the config"));
-
-    /*
-     * Open the image.
-     */
-    rc = RTFileOpen(&pThis->hFile, pszName, RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_WRITE);
-    if (RT_SUCCESS(rc))
-    {
-        LogFlow(("drvMediaISOConstruct: ISO image '%s' opened successfully.\n", pszName));
-        pThis->pszFilename = pszName;
-    }
-    else
-    {
-        PDMDrvHlpVMSetError(pDrvIns, rc, RT_SRC_POS, N_("Failed to open ISO file \"%s\""), pszName);
-        MMR3HeapFree(pszName);
-    }
-
-    return rc;
-}
-
-
-/**
- * ISO media driver registration record.
- */
-const PDMDRVREG g_DrvMediaISO =
-{
-    /* u32Version */
-    PDM_DRVREG_VERSION,
-    /* szName */
-    "MediaISO",
-    /* szRCMod */
-    "",
-    /* szR0Mod */
-    "",
-    /* pszDescription */
-    "ISO media access driver.",
-    /* fFlags */
-    PDM_DRVREG_FLAGS_HOST_BITS_DEFAULT,
-    /* fClass. */
-    PDM_DRVREG_CLASS_MEDIA,
-    /* cMaxInstances */
-    ~0U,
-    /* cbInstance */
-    sizeof(DRVMEDIAISO),
-    /* pfnConstruct */
-    drvMediaISOConstruct,
-    /* pfnDestruct */
-    drvMediaISODestruct,
-    /* pfnRelocate */
-    NULL,
-    /* pfnIOCtl */
-    NULL,
-    /* pfnPowerOn */
-    NULL,
-    /* pfnReset */
-    NULL,
-    /* pfnSuspend */
-    NULL,
-    /* pfnResume */
-    NULL,
-    /* pfnAttach */
-    NULL,
-    /* pfnDetach */
-    NULL,
-    /* pfnPowerOff */
-    NULL,
-    /* pfnSoftReset */
-    NULL,
-    /* u32EndVersion */
-    PDM_DRVREG_VERSION
-};
-
Index: trunk/src/VBox/Devices/Storage/DrvRawImage.cpp
===================================================================
--- trunk/src/VBox/Devices/Storage/DrvRawImage.cpp	(revision 59247)
+++ 	(revision )
@@ -1,373 +1,0 @@
-/* $Id$ */
-/** @file
- * VBox storage devices: Raw image driver
- */
-
-/*
- * Copyright (C) 2006-2015 Oracle Corporation
- *
- * This file is part of VirtualBox Open Source Edition (OSE), as
- * available from http://www.virtualbox.org. This file is free software;
- * you can redistribute it and/or modify it under the terms of the GNU
- * General Public License (GPL) as published by the Free Software
- * Foundation, in version 2 as it comes in the "COPYING" file of the
- * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
- * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
- */
-
-
-/*********************************************************************************************************************************
-*   Header Files                                                                                                                 *
-*********************************************************************************************************************************/
-#define LOG_GROUP LOG_GROUP_DRV_RAW_IMAGE
-#include <VBox/vmm/pdmdrv.h>
-#include <iprt/assert.h>
-#include <iprt/file.h>
-#include <iprt/string.h>
-#include <iprt/uuid.h>
-
-#include "VBoxDD.h"
-
-
-/*********************************************************************************************************************************
-*   Structures and Typedefs                                                                                                      *
-*********************************************************************************************************************************/
-/**
- * Block driver instance data.
- *
- * @implements  PDMIMEDIA
- */
-typedef struct DRVRAWIMAGE
-{
-    /** The media interface. */
-    PDMIMEDIA       IMedia;
-    /** Pointer to the driver instance. */
-    PPDMDRVINS      pDrvIns;
-    /** Pointer to the filename. (Freed by MM) */
-    char           *pszFilename;
-    /** File handle of the raw image file. */
-    RTFILE          hFile;
-    /** True if the image is operating in readonly mode. */
-    bool            fReadOnly;
-} DRVRAWIMAGE, *PDRVRAWIMAGE;
-
-
-
-/* -=-=-=-=- PDMIMEDIA -=-=-=-=- */
-
-/** @copydoc PDMIMEDIA::pfnGetSize */
-static DECLCALLBACK(uint64_t) drvRawImageGetSize(PPDMIMEDIA pInterface)
-{
-    PDRVRAWIMAGE pThis = RT_FROM_MEMBER(pInterface, DRVRAWIMAGE, IMedia);
-    LogFlow(("drvRawImageGetSize: '%s'\n", pThis->pszFilename));
-
-    uint64_t cbFile;
-    int rc = RTFileGetSize(pThis->hFile, &cbFile);
-    if (RT_SUCCESS(rc))
-    {
-        LogFlow(("drvRawImageGetSize: returns %lld (%s)\n", cbFile, pThis->pszFilename));
-        return cbFile;
-    }
-
-    AssertMsgFailed(("Error querying Raw image file size, rc=%Rrc. (%s)\n", rc, pThis->pszFilename));
-    return 0;
-}
-
-
-/** @copydoc PDMIMEDIA::pfnBiosGetPCHSGeometry */
-static DECLCALLBACK(int) drvRawImageBiosGetPCHSGeometry(PPDMIMEDIA pInterface, PPDMMEDIAGEOMETRY pPCHSGeometry)
-{
-    return VERR_NOT_IMPLEMENTED;
-}
-
-
-/** @copydoc PDMIMEDIA::pfnBiosSetPCHSGeometry */
-static DECLCALLBACK(int) drvRawImageBiosSetPCHSGeometry(PPDMIMEDIA pInterface, PCPDMMEDIAGEOMETRY pPCHSGeometry)
-{
-    return VERR_NOT_IMPLEMENTED;
-}
-
-
-/** @copydoc PDMIMEDIA::pfnBiosGetLCHSGeometry */
-static DECLCALLBACK(int) drvRawImageBiosGetLCHSGeometry(PPDMIMEDIA pInterface, PPDMMEDIAGEOMETRY pLCHSGeometry)
-{
-    return VERR_NOT_IMPLEMENTED;
-}
-
-
-/** @copydoc PDMIMEDIA::pfnBiosSetLCHSGeometry */
-static DECLCALLBACK(int) drvRawImageBiosSetLCHSGeometry(PPDMIMEDIA pInterface, PCPDMMEDIAGEOMETRY pLCHSGeometry)
-{
-    return VERR_NOT_IMPLEMENTED;
-}
-
-
-/**
- * Read bits.
- *
- * @see PDMIMEDIA::pfnRead for details.
- */
-static DECLCALLBACK(int) drvRawImageRead(PPDMIMEDIA pInterface, uint64_t off, void *pvBuf, size_t cbRead)
-{
-    PDRVRAWIMAGE pThis = RT_FROM_MEMBER(pInterface, DRVRAWIMAGE, IMedia);
-    LogFlow(("drvRawImageRead: off=%#llx pvBuf=%p cbRead=%#x (%s)\n", off, pvBuf, cbRead, pThis->pszFilename));
-
-    Assert(pThis->hFile != NIL_RTFILE);
-    Assert(pvBuf);
-
-    /*
-     * Seek to the position and read.
-     */
-    int rc = RTFileSeek(pThis->hFile, off, RTFILE_SEEK_BEGIN, NULL);
-    if (RT_SUCCESS(rc))
-    {
-        rc = RTFileRead(pThis->hFile, pvBuf, cbRead, NULL);
-        if (RT_SUCCESS(rc))
-        {
-            Log2(("drvRawImageRead: off=%#llx pvBuf=%p cbRead=%#x (%s)\n"
-                  "%16.*Rhxd\n",
-                  off, pvBuf, cbRead, pThis->pszFilename,
-                  cbRead, pvBuf));
-        }
-        else
-            AssertMsgFailed(("RTFileRead(%RTfile, %p, %#x) -> %Rrc (off=%#llx '%s')\n",
-                             pThis->hFile, pvBuf, cbRead, rc, off, pThis->pszFilename));
-    }
-    else
-        AssertMsgFailed(("RTFileSeek(%RTfile,%#llx,) -> %Rrc\n", pThis->hFile, off, rc));
-    LogFlow(("drvRawImageRead: returns %Rrc\n", rc));
-    return rc;
-}
-
-
-/** @copydoc PDMIMEDIA::pfnWrite */
-static DECLCALLBACK(int) drvRawImageWrite(PPDMIMEDIA pInterface, uint64_t off, const void *pvBuf, size_t cbWrite)
-{
-    PDRVRAWIMAGE pThis = RT_FROM_MEMBER(pInterface, DRVRAWIMAGE, IMedia);
-    LogFlow(("drvRawImageWrite: off=%#llx pvBuf=%p cbWrite=%#x (%s)\n", off, pvBuf, cbWrite, pThis->pszFilename));
-
-    Assert(pThis->hFile != NIL_RTFILE);
-    Assert(pvBuf);
-
-    /*
-     * Seek to the position and write.
-     */
-    int rc = RTFileSeek(pThis->hFile, off, RTFILE_SEEK_BEGIN, NULL);
-    if (RT_SUCCESS(rc))
-    {
-        rc = RTFileWrite(pThis->hFile, pvBuf, cbWrite, NULL);
-        if (RT_SUCCESS(rc))
-        {
-            Log2(("drvRawImageWrite: off=%#llx pvBuf=%p cbWrite=%#x (%s)\n"
-                  "%16.*Rhxd\n",
-                  off, pvBuf, cbWrite, pThis->pszFilename,
-                  cbWrite, pvBuf));
-        }
-        else
-            AssertMsgFailed(("RTFileWrite(%RTfile, %p, %#x) -> %Rrc (off=%#llx '%s')\n",
-                             pThis->hFile, pvBuf, cbWrite, rc, off, pThis->pszFilename));
-    }
-    else
-        AssertMsgFailed(("RTFileSeek(%RTfile,%#llx,) -> %Rrc\n", pThis->hFile, off, rc));
-    LogFlow(("drvRawImageWrite: returns %Rrc\n", rc));
-    return rc;
-}
-
-
-/** @copydoc PDMIMEDIA::pfnFlush */
-static DECLCALLBACK(int) drvRawImageFlush(PPDMIMEDIA pInterface)
-{
-    PDRVRAWIMAGE pThis = RT_FROM_MEMBER(pInterface, DRVRAWIMAGE, IMedia);
-    LogFlow(("drvRawImageFlush: (%s)\n", pThis->pszFilename));
-
-    Assert(pThis->hFile != NIL_RTFILE);
-    int rc = RTFileFlush(pThis->hFile);
-    LogFlow(("drvRawImageFlush: returns %Rrc\n", rc));
-    return rc;
-}
-
-
-/** @copydoc PDMIMEDIA::pfnGetUuid */
-static DECLCALLBACK(int) drvRawImageGetUuid(PPDMIMEDIA pInterface, PRTUUID pUuid)
-{
-    LogFlow(("drvRawImageGetUuid: returns VERR_NOT_IMPLEMENTED\n"));
-    return VERR_NOT_IMPLEMENTED;
-}
-
-
-/** @copydoc PDMIMEDIA::pfnIsReadOnly */
-static DECLCALLBACK(bool) drvRawImageIsReadOnly(PPDMIMEDIA pInterface)
-{
-    PDRVRAWIMAGE pThis = RT_FROM_MEMBER(pInterface, DRVRAWIMAGE, IMedia);
-    return pThis->fReadOnly;
-}
-
-
-/* -=-=-=-=- PDMIBASE -=-=-=-=- */
-
-/**
- * @interface_method_impl{PDMIBASE,pfnQueryInterface}
- */
-static DECLCALLBACK(void *) drvRawImageQueryInterface(PPDMIBASE pInterface, const char *pszIID)
-{
-    PPDMDRVINS      pDrvIns = PDMIBASE_2_PDMDRV(pInterface);
-    PDRVRAWIMAGE    pThis   = PDMINS_2_DATA(pDrvIns, PDRVRAWIMAGE);
-
-    PDMIBASE_RETURN_INTERFACE(pszIID, PDMIBASE, &pDrvIns->IBase);
-    PDMIBASE_RETURN_INTERFACE(pszIID, PDMIMEDIA, &pThis->IMedia);
-    return NULL;
-}
-
-/* -=-=-=-=- PDMDRVREG -=-=-=-=- */
-
-/**
- * Destruct a driver instance.
- *
- * Most VM resources are freed by the VM. This callback is provided so that any non-VM
- * resources can be freed correctly.
- *
- * @param   pDrvIns     The driver instance data.
- */
-static DECLCALLBACK(void) drvRawImageDestruct(PPDMDRVINS pDrvIns)
-{
-    PDRVRAWIMAGE pThis = PDMINS_2_DATA(pDrvIns, PDRVRAWIMAGE);
-    LogFlow(("drvRawImageDestruct: '%s'\n", pThis->pszFilename));
-    PDMDRV_CHECK_VERSIONS_RETURN_VOID(pDrvIns);
-
-    if (pThis->hFile != NIL_RTFILE)
-    {
-        RTFileClose(pThis->hFile);
-        pThis->hFile = NIL_RTFILE;
-    }
-
-    if (pThis->pszFilename)
-    {
-        MMR3HeapFree(pThis->pszFilename);
-        pThis->pszFilename = NULL;
-    }
-}
-
-
-/**
- * Construct a raw image driver instance.
- *
- * @copydoc FNPDMDRVCONSTRUCT
- */
-static DECLCALLBACK(int) drvRawImageConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfg, uint32_t fFlags)
-{
-    PDRVRAWIMAGE pThis = PDMINS_2_DATA(pDrvIns, PDRVRAWIMAGE);
-    PDMDRV_CHECK_VERSIONS_RETURN(pDrvIns);
-
-    /*
-     * Init the static parts.
-     */
-    pThis->pDrvIns                      = pDrvIns;
-    pThis->hFile                        = NIL_RTFILE;
-    /* IBase */
-    pDrvIns->IBase.pfnQueryInterface    = drvRawImageQueryInterface;
-    /* IMedia */
-    pThis->IMedia.pfnRead               = drvRawImageRead;
-    pThis->IMedia.pfnWrite              = drvRawImageWrite;
-    pThis->IMedia.pfnFlush              = drvRawImageFlush;
-    pThis->IMedia.pfnGetSize            = drvRawImageGetSize;
-    pThis->IMedia.pfnGetUuid            = drvRawImageGetUuid;
-    pThis->IMedia.pfnIsReadOnly         = drvRawImageIsReadOnly;
-    pThis->IMedia.pfnBiosGetPCHSGeometry = drvRawImageBiosGetPCHSGeometry;
-    pThis->IMedia.pfnBiosSetPCHSGeometry = drvRawImageBiosSetPCHSGeometry;
-    pThis->IMedia.pfnBiosGetLCHSGeometry = drvRawImageBiosGetLCHSGeometry;
-    pThis->IMedia.pfnBiosSetLCHSGeometry = drvRawImageBiosSetLCHSGeometry;
-
-    /*
-     * Read the configuration.
-     */
-    if (!CFGMR3AreValuesValid(pCfg, "Path\0"))
-        return VERR_PDM_DRVINS_UNKNOWN_CFG_VALUES;
-
-    char *pszName;
-    int rc = CFGMR3QueryStringAlloc(pCfg, "Path", &pszName);
-    if (RT_FAILURE(rc))
-    {
-        AssertMsgFailed(("Configuration error: query for \"Path\" string return %Rrc.\n", rc));
-        return rc;
-    }
-
-    /*
-     * Open the image.
-     */
-    rc = RTFileOpen(&pThis->hFile, pszName, RTFILE_O_READWRITE | RTFILE_O_OPEN | RTFILE_O_DENY_NONE);
-    if (RT_SUCCESS(rc))
-    {
-        LogFlow(("drvRawImageConstruct: Raw image '%s' opened successfully.\n", pszName));
-        pThis->pszFilename = pszName;
-        pThis->fReadOnly = false;
-    }
-    else
-    {
-        rc = RTFileOpen(&pThis->hFile, pszName, RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_NONE);
-        if (RT_SUCCESS(rc))
-        {
-            LogFlow(("drvRawImageConstruct: Raw image '%s' opened successfully.\n", pszName));
-            pThis->pszFilename = pszName;
-            pThis->fReadOnly = true;
-        }
-        else
-        {
-            AssertMsgFailed(("Could not open Raw image file %s, rc=%Rrc\n", pszName, rc));
-            MMR3HeapFree(pszName);
-        }
-    }
-
-    return rc;
-}
-
-
-/**
- * Raw image driver registration record.
- */
-const PDMDRVREG g_DrvRawImage =
-{
-    /* u32Version */
-    PDM_DRVREG_VERSION,
-    /* szName */
-    "RawImage",
-    /* szRCMod */
-    "",
-    /* szR0Mod */
-    "",
-    /* pszDescription */
-    "Raw image access driver.",
-    /* fFlags */
-    PDM_DRVREG_FLAGS_HOST_BITS_DEFAULT,
-    /* fClass. */
-    PDM_DRVREG_CLASS_MEDIA,
-    /* cMaxInstances */
-    ~0U,
-    /* cbInstance */
-    sizeof(DRVRAWIMAGE),
-    /* pfnConstruct */
-    drvRawImageConstruct,
-    /* pfnDestruct */
-    drvRawImageDestruct,
-    /* pfnRelocate */
-    NULL,
-    /* pfnIOCtl */
-    NULL,
-    /* pfnPowerOn */
-    NULL,
-    /* pfnReset */
-    NULL,
-    /* pfnSuspend */
-    NULL,
-    /* pfnResume */
-    NULL,
-    /* pfnAttach */
-    NULL,
-    /* pfnDetach */
-    NULL,
-    /* pfnPowerOff */
-    NULL,
-    /* pfnSoftReset */
-    NULL,
-    /* u32EndVersion */
-    PDM_DRVREG_VERSION
-};
Index: trunk/src/VBox/Devices/Storage/DrvSCSI.cpp
===================================================================
--- trunk/src/VBox/Devices/Storage/DrvSCSI.cpp	(revision 59247)
+++ trunk/src/VBox/Devices/Storage/DrvSCSI.cpp	(revision 59248)
@@ -44,5 +44,5 @@
  *
  * @implements  PDMISCSICONNECTOR
- * @implements  PDMIBLOCKASYNCPORT
+ * @implements  PDMIMEDIAASYNCPORT
  * @implements  PDMIMOUNTNOTIFY
  */
@@ -55,9 +55,7 @@
     PPDMIBASE               pDrvBase;
     /** Pointer to the attached driver's block interface. */
-    PPDMIBLOCK              pDrvBlock;
+    PPDMIMEDIA              pDrvMedia;
     /** Pointer to the attached driver's async block interface. */
-    PPDMIBLOCKASYNC         pDrvBlockAsync;
-    /** Pointer to the attached driver's block bios interface. */
-    PPDMIBLOCKBIOS          pDrvBlockBios;
+    PPDMIMEDIAASYNC         pDrvMediaAsync;
     /** Pointer to the attached driver's mount interface. */
     PPDMIMOUNT              pDrvMount;
@@ -68,8 +66,8 @@
     /** The scsi connector interface .*/
     PDMISCSICONNECTOR       ISCSIConnector;
-    /** The block port interface. */
-    PDMIBLOCKPORT           IPort;
-    /** The optional block async port interface. */
-    PDMIBLOCKASYNCPORT      IPortAsync;
+    /** The media port interface. */
+    PDMIMEDIAPORT           IPort;
+    /** The optional media async port interface. */
+    PDMIMEDIAASYNCPORT      IPortAsync;
     /** The mount notify interface. */
     PDMIMOUNTNOTIFY         IMountNotify;
@@ -113,9 +111,9 @@
 #define PDMISCSICONNECTOR_2_DRVSCSI(pInterface)  ( (PDRVSCSI)((uintptr_t)pInterface - RT_OFFSETOF(DRVSCSI, ISCSIConnector)) )
 /** Converts a pointer to DRVSCSI::IPortAsync to a PDRVSCSI. */
-#define PDMIBLOCKASYNCPORT_2_DRVSCSI(pInterface) ( (PDRVSCSI)((uintptr_t)pInterface - RT_OFFSETOF(DRVSCSI, IPortAsync)) )
+#define PDMIMEDIAASYNCPORT_2_DRVSCSI(pInterface) ( (PDRVSCSI)((uintptr_t)pInterface - RT_OFFSETOF(DRVSCSI, IPortAsync)) )
 /** Converts a pointer to DRVSCSI::IMountNotify to PDRVSCSI. */
 #define PDMIMOUNTNOTIFY_2_DRVSCSI(pInterface)    ( (PDRVSCSI)((uintptr_t)pInterface - RT_OFFSETOF(DRVSCSI, IMountNotify)) )
 /** Converts a pointer to DRVSCSI::IPort to a PDRVSCSI. */
-#define PDMIBLOCKPORT_2_DRVSCSI(pInterface)      ( (PDRVSCSI)((uintptr_t)pInterface - RT_OFFSETOF(DRVSCSI, IPort)) )
+#define PDMIMEDIAPORT_2_DRVSCSI(pInterface)      ( (PDRVSCSI)((uintptr_t)pInterface - RT_OFFSETOF(DRVSCSI, IPort)) )
 
 static bool drvscsiIsRedoPossible(int rc)
@@ -142,5 +140,5 @@
         case VSCSIIOREQTXDIR_FLUSH:
         {
-            rc = pThis->pDrvBlock->pfnFlush(pThis->pDrvBlock);
+            rc = pThis->pDrvMedia->pfnFlush(pThis->pDrvMedia);
             if (   RT_FAILURE(rc)
                 && pThis->cErrors++ < MAX_LOG_REL_ERRORS)
@@ -171,5 +169,5 @@
                 {
                     pThis->pLed->Asserted.s.fReading = pThis->pLed->Actual.s.fReading = 1;
-                    rc = pThis->pDrvBlock->pfnRead(pThis->pDrvBlock, uOffset,
+                    rc = pThis->pDrvMedia->pfnRead(pThis->pDrvMedia, uOffset,
                                                     paSeg->pvSeg, cbProcess);
                     pThis->pLed->Actual.s.fReading = 0;
@@ -181,5 +179,5 @@
                 {
                     pThis->pLed->Asserted.s.fWriting = pThis->pLed->Actual.s.fWriting = 1;
-                    rc = pThis->pDrvBlock->pfnWrite(pThis->pDrvBlock, uOffset,
+                    rc = pThis->pDrvMedia->pfnWrite(pThis->pDrvMedia, uOffset,
                                                     paSeg->pvSeg, cbProcess);
                     pThis->pLed->Actual.s.fWriting = 0;
@@ -217,5 +215,5 @@
 
             pThis->pLed->Asserted.s.fWriting = pThis->pLed->Actual.s.fWriting = 1;
-            rc = pThis->pDrvBlock->pfnDiscard(pThis->pDrvBlock, paRanges, cRanges);
+            rc = pThis->pDrvMedia->pfnDiscard(pThis->pDrvMedia, paRanges, cRanges);
             pThis->pLed->Actual.s.fWriting = 0;
 
@@ -243,5 +241,5 @@
     PDRVSCSI pThis = (PDRVSCSI)pvScsiLunUser;
 
-    *pcbSize = pThis->pDrvBlock->pfnGetSize(pThis->pDrvBlock);
+    *pcbSize = pThis->pDrvMedia->pfnGetSize(pThis->pDrvMedia);
 
     return VINF_SUCCESS;
@@ -253,5 +251,5 @@
     PDRVSCSI pThis = (PDRVSCSI)pvScsiLunUser;
 
-    *pcbSectorSize = pThis->pDrvBlock->pfnGetSectorSize(pThis->pDrvBlock);
+    *pcbSectorSize = pThis->pDrvMedia->pfnGetSectorSize(pThis->pDrvMedia);
 
     return VINF_SUCCESS;
@@ -269,7 +267,7 @@
 }
 
-static DECLCALLBACK(int) drvscsiTransferCompleteNotify(PPDMIBLOCKASYNCPORT pInterface, void *pvUser, int rc)
-{
-    PDRVSCSI pThis = PDMIBLOCKASYNCPORT_2_DRVSCSI(pInterface);
+static DECLCALLBACK(int) drvscsiTransferCompleteNotify(PPDMIMEDIAASYNCPORT pInterface, void *pvUser, int rc)
+{
+    PDRVSCSI pThis = PDMIMEDIAASYNCPORT_2_DRVSCSI(pInterface);
     VSCSIIOREQ hVScsiIoReq = (VSCSIIOREQ)pvUser;
     VSCSIIOREQTXDIR enmTxDir = VSCSIIoReqTxDirGet(hVScsiIoReq);
@@ -332,5 +330,5 @@
     PDRVSCSI pThis = (PDRVSCSI)pvScsiLunUser;
 
-    if (pThis->pDrvBlockAsync)
+    if (pThis->pDrvMediaAsync)
     {
         /* async I/O path. */
@@ -345,5 +343,5 @@
             case VSCSIIOREQTXDIR_FLUSH:
             {
-                rc = pThis->pDrvBlockAsync->pfnStartFlush(pThis->pDrvBlockAsync, hVScsiIoReq);
+                rc = pThis->pDrvMediaAsync->pfnStartFlush(pThis->pDrvMediaAsync, hVScsiIoReq);
                 if (   RT_FAILURE(rc)
                     && rc != VERR_VD_ASYNC_IO_IN_PROGRESS
@@ -362,5 +360,5 @@
 
                 pThis->pLed->Asserted.s.fWriting = pThis->pLed->Actual.s.fWriting = 1;
-                rc = pThis->pDrvBlockAsync->pfnStartDiscard(pThis->pDrvBlockAsync, paRanges, cRanges, hVScsiIoReq);
+                rc = pThis->pDrvMediaAsync->pfnStartDiscard(pThis->pDrvMediaAsync, paRanges, cRanges, hVScsiIoReq);
                 if (   RT_FAILURE(rc)
                     && rc != VERR_VD_ASYNC_IO_IN_PROGRESS
@@ -386,5 +384,5 @@
                 {
                     pThis->pLed->Asserted.s.fReading = pThis->pLed->Actual.s.fReading = 1;
-                    rc = pThis->pDrvBlockAsync->pfnStartRead(pThis->pDrvBlockAsync, uOffset,
+                    rc = pThis->pDrvMediaAsync->pfnStartRead(pThis->pDrvMediaAsync, uOffset,
                                                              paSeg, cSeg, cbTransfer,
                                                              hVScsiIoReq);
@@ -394,5 +392,5 @@
                 {
                     pThis->pLed->Asserted.s.fWriting = pThis->pLed->Actual.s.fWriting = 1;
-                    rc = pThis->pDrvBlockAsync->pfnStartWrite(pThis->pDrvBlockAsync, uOffset,
+                    rc = pThis->pDrvMediaAsync->pfnStartWrite(pThis->pDrvMediaAsync, uOffset,
                                                               paSeg, cSeg, cbTransfer,
                                                               hVScsiIoReq);
@@ -464,7 +462,7 @@
     *pfFeatures = 0;
 
-    if (   pThis->pDrvBlock->pfnDiscard
-        || (   pThis->pDrvBlockAsync
-            && pThis->pDrvBlockAsync->pfnStartDiscard))
+    if (   pThis->pDrvMedia->pfnDiscard
+        || (   pThis->pDrvMediaAsync
+            && pThis->pDrvMediaAsync->pfnStartDiscard))
         *pfFeatures |= VSCSI_LUN_FEATURE_UNMAP;
 
@@ -682,17 +680,16 @@
 
     PDMIBASE_RETURN_INTERFACE(pszIID, PDMIMOUNT, pThis->pDrvMount);
-    PDMIBASE_RETURN_INTERFACE(pszIID, PDMIBLOCKBIOS, pThis->pDrvBlockBios);
     PDMIBASE_RETURN_INTERFACE(pszIID, PDMIBASE, &pDrvIns->IBase);
     PDMIBASE_RETURN_INTERFACE(pszIID, PDMISCSICONNECTOR, &pThis->ISCSIConnector);
-    PDMIBASE_RETURN_INTERFACE(pszIID, PDMIBLOCKPORT, &pThis->IPort);
+    PDMIBASE_RETURN_INTERFACE(pszIID, PDMIMEDIAPORT, &pThis->IPort);
     PDMIBASE_RETURN_INTERFACE(pszIID, PDMIMOUNTNOTIFY, &pThis->IMountNotify);
-    PDMIBASE_RETURN_INTERFACE(pszIID, PDMIBLOCKASYNCPORT, &pThis->IPortAsync);
+    PDMIBASE_RETURN_INTERFACE(pszIID, PDMIMEDIAASYNCPORT, &pThis->IPortAsync);
     return NULL;
 }
 
-static DECLCALLBACK(int) drvscsiQueryDeviceLocation(PPDMIBLOCKPORT pInterface, const char **ppcszController,
+static DECLCALLBACK(int) drvscsiQueryDeviceLocation(PPDMIMEDIAPORT pInterface, const char **ppcszController,
                                                     uint32_t *piInstance, uint32_t *piLUN)
 {
-    PDRVSCSI pThis = PDMIBLOCKPORT_2_DRVSCSI(pInterface);
+    PDRVSCSI pThis = PDMIMEDIAPORT_2_DRVSCSI(pInterface);
 
     return pThis->pDevScsiPort->pfnQueryDeviceLocation(pThis->pDevScsiPort, ppcszController,
@@ -711,5 +708,5 @@
 
     /* Ignore the call if we're called while being attached. */
-    if (!pThis->pDrvBlock)
+    if (!pThis->pDrvMedia)
         return;
 
@@ -742,5 +739,5 @@
     PDRVSCSI pThis = PDMINS_2_DATA(pDrvIns, PDRVSCSI);
 
-    if (!pThis->pDrvBlockAsync)
+    if (!pThis->pDrvMediaAsync)
     {
         if (pThis->hQueueRequests != NIL_RTREQQUEUE)
@@ -790,5 +787,5 @@
     PDRVSCSI pThis = PDMINS_2_DATA(pDrvIns, PDRVSCSI);
 
-    if (pThis->pDrvBlockAsync)
+    if (pThis->pDrvMediaAsync)
     {
         if (pThis->StatIoDepth > 0)
@@ -833,5 +830,5 @@
     PDRVSCSI pThis = PDMINS_2_DATA(pDrvIns, PDRVSCSI);
 
-    if (pThis->pDrvBlockAsync)
+    if (pThis->pDrvMediaAsync)
     {
         if (pThis->StatIoDepth > 0)
@@ -967,31 +964,25 @@
      * Query the block and blockbios interfaces.
      */
-    pThis->pDrvBlock = PDMIBASE_QUERY_INTERFACE(pThis->pDrvBase, PDMIBLOCK);
-    if (!pThis->pDrvBlock)
+    pThis->pDrvMedia = PDMIBASE_QUERY_INTERFACE(pThis->pDrvBase, PDMIMEDIA);
+    if (!pThis->pDrvMedia)
     {
         AssertMsgFailed(("Configuration error: No block interface!\n"));
         return VERR_PDM_MISSING_INTERFACE;
     }
-    pThis->pDrvBlockBios = PDMIBASE_QUERY_INTERFACE(pThis->pDrvBase, PDMIBLOCKBIOS);
-    if (!pThis->pDrvBlockBios)
-    {
-        AssertMsgFailed(("Configuration error: No block BIOS interface!\n"));
-        return VERR_PDM_MISSING_INTERFACE;
-    }
 
     pThis->pDrvMount = PDMIBASE_QUERY_INTERFACE(pThis->pDrvBase, PDMIMOUNT);
 
     /* Try to get the optional async block interface. */
-    pThis->pDrvBlockAsync = PDMIBASE_QUERY_INTERFACE(pThis->pDrvBase, PDMIBLOCKASYNC);
-
-    PDMBLOCKTYPE enmType = pThis->pDrvBlock->pfnGetType(pThis->pDrvBlock);
+    pThis->pDrvMediaAsync = PDMIBASE_QUERY_INTERFACE(pThis->pDrvBase, PDMIMEDIAASYNC);
+
+    PDMMEDIATYPE enmType = pThis->pDrvMedia->pfnGetType(pThis->pDrvMedia);
     VSCSILUNTYPE enmLunType;
     switch (enmType)
     {
-    case PDMBLOCKTYPE_HARD_DISK:
+    case PDMMEDIATYPE_HARD_DISK:
         enmLunType = VSCSILUNTYPE_SBC;
         break;
-    case PDMBLOCKTYPE_CDROM:
-    case PDMBLOCKTYPE_DVD:
+    case PDMMEDIATYPE_CDROM:
+    case PDMMEDIATYPE_DVD:
         enmLunType = VSCSILUNTYPE_MMC;
         break;
@@ -1001,6 +992,6 @@
                                    enmType);
     }
-    if (    (   enmType == PDMBLOCKTYPE_DVD
-             || enmType == PDMBLOCKTYPE_CDROM)
+    if (    (   enmType == PDMMEDIATYPE_DVD
+             || enmType == PDMMEDIATYPE_CDROM)
         &&  !pThis->pDrvMount)
     {
@@ -1028,5 +1019,5 @@
     if (pThis->pDrvMount)
     {
-        if (pThis->pDrvBlock->pfnGetSize(pThis->pDrvBlock))
+        if (pThis->pDrvMedia->pfnGetSize(pThis->pDrvMedia))
         {
             rc = VINF_SUCCESS; VSCSILunMountNotify(pThis->hVScsiLun);
@@ -1061,5 +1052,5 @@
     pThis->StatIoDepth = 0;
 
-    if (!pThis->pDrvBlockAsync)
+    if (!pThis->pDrvMediaAsync)
     {
         /* Create request queue. */
@@ -1076,7 +1067,7 @@
         LogRel(("SCSI#%d: using async I/O\n", pDrvIns->iInstance));
 
-    if (   pThis->pDrvBlock->pfnDiscard
-        || (   pThis->pDrvBlockAsync
-            && pThis->pDrvBlockAsync->pfnStartDiscard))
+    if (   pThis->pDrvMedia->pfnDiscard
+        || (   pThis->pDrvMediaAsync
+            && pThis->pDrvMediaAsync->pfnStartDiscard))
         LogRel(("SCSI#%d: Enabled UNMAP support\n", pDrvIns->iInstance));
 
Index: trunk/src/VBox/Devices/Storage/DrvVD.cpp
===================================================================
--- trunk/src/VBox/Devices/Storage/DrvVD.cpp	(revision 59247)
+++ trunk/src/VBox/Devices/Storage/DrvVD.cpp	(revision 59248)
@@ -62,4 +62,26 @@
 
 
+/** @def VBOX_PERIODIC_FLUSH
+ * Enable support for periodically flushing the VDI to disk. This may prove
+ * useful for those nasty problems with the ultra-slow host filesystems.
+ * If this is enabled, it can be configured via the CFGM key
+ * "VBoxInternal/Devices/piix3ide/0/LUN#<x>/Config/FlushInterval". <x>
+ * must be replaced with the correct LUN number of the disk that should
+ * do the periodic flushes. The value of the key is the number of bytes
+ * written between flushes. A value of 0 (the default) denotes no flushes. */
+#define VBOX_PERIODIC_FLUSH
+
+/** @def VBOX_IGNORE_FLUSH
+ * Enable support for ignoring VDI flush requests. This can be useful for
+ * filesystems that show bad guest IDE write performance (especially with
+ * Windows guests). NOTE that this does not disable the flushes caused by
+ * the periodic flush cache feature above.
+ * If this feature is enabled, it can be configured via the CFGM key
+ * "VBoxInternal/Devices/piix3ide/0/LUN#<x>/Config/IgnoreFlush". <x>
+ * must be replaced with the correct LUN number of the disk that should
+ * ignore flush requests. The value of the key is a boolean. The default
+ * is to ignore flushes, i.e. true. */
+#define VBOX_IGNORE_FLUSH
+
 /*********************************************************************************************************************************
 *   Defined types, constants and macros                                                                                          *
@@ -116,4 +138,5 @@
  * @implements  PDMIMEDIA
  * @implements  PDMIMEDIAASYNC
+ * @implements  PDMIMOUNT
  * @implements  VDINTERFACEERROR
  * @implements  VDINTERFACETCPNET
@@ -192,4 +215,35 @@
     HBDMGR                   hHbdMgr;
 
+    /** Drive type. */
+    PDMMEDIATYPE            enmType;
+    /** Locked indicator. */
+    bool                    fLocked;
+    /** Mountable indicator. */
+    bool                    fMountable;
+    /** Visible to the BIOS. */
+    bool                    fBiosVisible;
+#ifdef VBOX_PERIODIC_FLUSH
+    /** HACK: Configuration value for number of bytes written after which to flush. */
+    uint32_t                cbFlushInterval;
+    /** HACK: Current count for the number of bytes written since the last flush. */
+    uint32_t                cbDataWritten;
+#endif /* VBOX_PERIODIC_FLUSH */
+#ifdef VBOX_IGNORE_FLUSH
+    /** HACK: Disable flushes for this drive. */
+    bool                    fIgnoreFlush;
+    /** Disable async flushes for this drive. */
+    bool                    fIgnoreFlushAsync;
+#endif /* VBOX_IGNORE_FLUSH */
+    /** Our mountable interface. */
+    PDMIMOUNT               IMount;
+    /** Pointer to the mount notify interface above us. */
+    PPDMIMOUNTNOTIFY        pDrvMountNotify;
+    /** Uuid of the drive. */
+    RTUUID                  Uuid;
+    /** BIOS PCHS Geometry. */
+    PDMMEDIAGEOMETRY        PCHSGeometry;
+    /** BIOS LCHS Geometry. */
+    PDMMEDIAGEOMETRY        LCHSGeometry;
+
     /** Cryptographic support
      * @{ */
@@ -256,5 +310,6 @@
 {
     int rc = VINF_SUCCESS;
-    if (!VDIsReadOnly(pThis->pDisk))
+    if (   pThis->pDisk
+        && !VDIsReadOnly(pThis->pDisk))
     {
         unsigned uOpenFlags;
@@ -1643,4 +1698,13 @@
     PVBOXDISK pThis = PDMIMEDIA_2_VBOXDISK(pInterface);
 
+    /*
+     * Check the state.
+     */
+    if (!pThis->pDisk)
+    {
+        AssertMsgFailed(("Invalid state! Not mounted!\n"));
+        return VERR_PDM_MEDIA_NOT_MOUNTED;
+    }
+
     rc = drvvdKeyCheckPrereqs(pThis);
     if (RT_FAILURE(rc))
@@ -1697,4 +1761,13 @@
     PVBOXDISK pThis = PDMIMEDIA_2_VBOXDISK(pInterface);
 
+    /*
+     * Check the state.
+     */
+    if (!pThis->pDisk)
+    {
+        AssertMsgFailed(("Invalid state! Not mounted!\n"));
+        return VERR_PDM_MEDIA_NOT_MOUNTED;
+    }
+
     if (   pThis->pCfgCrypto
         && !pThis->pIfSecKey)
@@ -1753,4 +1826,16 @@
           off, pvBuf, cbWrite, cbWrite, pvBuf));
 
+    /*
+     * Check the state.
+     */
+    if (!pThis->pDisk)
+    {
+        AssertMsgFailed(("Invalid state! Not mounted!\n"));
+        return VERR_PDM_MEDIA_NOT_MOUNTED;
+    }
+
+    /* Set an FTM checkpoint as this operation changes the state permanently. */
+    PDMDrvHlpFTSetCheckpoint(pThis->pDrvIns, FTMCHECKPOINTTYPE_STORAGE);
+
     int rc = drvvdKeyCheckPrereqs(pThis);
     if (RT_FAILURE(rc))
@@ -1765,4 +1850,16 @@
 
     rc = VDWrite(pThis->pDisk, off, pvBuf, cbWrite);
+#ifdef VBOX_PERIODIC_FLUSH
+    if (pThis->cbFlushInterval)
+    {
+        pThis->cbDataWritten += (uint32_t)cbWrite;
+        if (pThis->cbDataWritten > pThis->cbFlushInterval)
+        {
+            pThis->cbDataWritten = 0;
+            VDFlush(pThis->pDisk);
+        }
+    }
+#endif /* VBOX_PERIODIC_FLUSH */
+
     LogFlowFunc(("returns %Rrc\n", rc));
     return rc;
@@ -1774,4 +1871,19 @@
     LogFlowFunc(("\n"));
     PVBOXDISK pThis = PDMIMEDIA_2_VBOXDISK(pInterface);
+
+    /*
+     * Check the state.
+     */
+    if (!pThis->pDisk)
+    {
+        AssertMsgFailed(("Invalid state! Not mounted!\n"));
+        return VERR_PDM_MEDIA_NOT_MOUNTED;
+    }
+
+#ifdef VBOX_IGNORE_FLUSH
+    if (pThis->fIgnoreFlush)
+        return VINF_SUCCESS;
+#endif /* VBOX_IGNORE_FLUSH */
+
     int rc = VDFlush(pThis->pDisk);
     LogFlowFunc(("returns %Rrc\n", rc));
@@ -1787,4 +1899,13 @@
     PVBOXDISK pThis = PDMIMEDIA_2_VBOXDISK(pInterface);
     int rc = VINF_SUCCESS;
+
+    /*
+     * Check the state.
+     */
+    if (!pThis->pDisk)
+    {
+        AssertMsgFailed(("Invalid state! Not mounted!\n"));
+        return VERR_PDM_MEDIA_NOT_MOUNTED;
+    }
 
     /* Note: There is an unavoidable race between destruction and another
@@ -1868,4 +1989,11 @@
     LogFlowFunc(("\n"));
     PVBOXDISK pThis = PDMIMEDIA_2_VBOXDISK(pInterface);
+
+    /*
+     * Check the state.
+     */
+    if (!pThis->pDisk)
+        return 0;
+
     uint64_t cb = VDGetSize(pThis->pDisk, VD_LAST_IMAGE);
     LogFlowFunc(("returns %#llx (%llu)\n", cb, cb));
@@ -1878,4 +2006,11 @@
     LogFlowFunc(("\n"));
     PVBOXDISK pThis = PDMIMEDIA_2_VBOXDISK(pInterface);
+
+    /*
+     * Check the state.
+     */
+    if (!pThis->pDisk)
+        return 0;
+
     uint32_t cb = VDGetSectorSize(pThis->pDisk, VD_LAST_IMAGE);
     LogFlowFunc(("returns %u\n", cb));
@@ -1888,4 +2023,11 @@
     LogFlowFunc(("\n"));
     PVBOXDISK pThis = PDMIMEDIA_2_VBOXDISK(pInterface);
+
+    /*
+     * Check the state.
+     */
+    if (!pThis->pDisk)
+        return false;
+
     bool f = VDIsReadOnly(pThis->pDisk);
     LogFlowFunc(("returns %d\n", f));
@@ -1900,4 +2042,23 @@
     PVBOXDISK pThis = PDMIMEDIA_2_VBOXDISK(pInterface);
     VDGEOMETRY geo;
+
+    /*
+     * Check the state.
+     */
+    if (!pThis->pDisk)
+        return VERR_PDM_MEDIA_NOT_MOUNTED;
+
+    /*
+     * Use configured/cached values if present.
+     */
+    if (    pThis->PCHSGeometry.cCylinders > 0
+        &&  pThis->PCHSGeometry.cHeads > 0
+        &&  pThis->PCHSGeometry.cSectors > 0)
+    {
+        *pPCHSGeometry = pThis->PCHSGeometry;
+        LogFlow(("%s: returns VINF_SUCCESS {%d,%d,%d}\n", __FUNCTION__, pThis->PCHSGeometry.cCylinders, pThis->PCHSGeometry.cHeads, pThis->PCHSGeometry.cSectors));
+        return VINF_SUCCESS;
+    }
+
     int rc = VDGetPCHSGeometry(pThis->pDisk, VD_LAST_IMAGE, &geo);
     if (RT_SUCCESS(rc))
@@ -1906,4 +2067,5 @@
         pPCHSGeometry->cHeads = geo.cHeads;
         pPCHSGeometry->cSectors = geo.cSectors;
+        pThis->PCHSGeometry = *pPCHSGeometry;
     }
     else
@@ -1925,4 +2087,14 @@
     PVBOXDISK pThis = PDMIMEDIA_2_VBOXDISK(pInterface);
     VDGEOMETRY geo;
+
+    /*
+     * Check the state.
+     */
+    if (!pThis->pDisk)
+    {
+        AssertMsgFailed(("Invalid state! Not mounted!\n"));
+        return VERR_PDM_MEDIA_NOT_MOUNTED;
+    }
+
     geo.cCylinders = pPCHSGeometry->cCylinders;
     geo.cHeads = pPCHSGeometry->cHeads;
@@ -1931,4 +2103,6 @@
     if (rc == VERR_VD_GEOMETRY_NOT_SET)
         rc = VERR_PDM_GEOMETRY_NOT_SET;
+    if (RT_SUCCESS(rc))
+        pThis->PCHSGeometry = *pPCHSGeometry;
     LogFlowFunc(("returns %Rrc\n", rc));
     return rc;
@@ -1942,4 +2116,23 @@
     PVBOXDISK pThis = PDMIMEDIA_2_VBOXDISK(pInterface);
     VDGEOMETRY geo;
+
+    /*
+     * Check the state.
+     */
+    if (!pThis->pDisk)
+        return VERR_PDM_MEDIA_NOT_MOUNTED;
+
+    /*
+     * Use configured/cached values if present.
+     */
+    if (    pThis->LCHSGeometry.cCylinders > 0
+        &&  pThis->LCHSGeometry.cHeads > 0
+        &&  pThis->LCHSGeometry.cSectors > 0)
+    {
+        *pLCHSGeometry = pThis->LCHSGeometry;
+        LogFlow(("%s: returns VINF_SUCCESS {%d,%d,%d}\n", __FUNCTION__, pThis->LCHSGeometry.cCylinders, pThis->LCHSGeometry.cHeads, pThis->LCHSGeometry.cSectors));
+        return VINF_SUCCESS;
+    }
+
     int rc = VDGetLCHSGeometry(pThis->pDisk, VD_LAST_IMAGE, &geo);
     if (RT_SUCCESS(rc))
@@ -1948,4 +2141,5 @@
         pLCHSGeometry->cHeads = geo.cHeads;
         pLCHSGeometry->cSectors = geo.cSectors;
+        pThis->LCHSGeometry = *pLCHSGeometry;
     }
     else
@@ -1967,4 +2161,14 @@
     PVBOXDISK pThis = PDMIMEDIA_2_VBOXDISK(pInterface);
     VDGEOMETRY geo;
+
+    /*
+     * Check the state.
+     */
+    if (!pThis->pDisk)
+    {
+        AssertMsgFailed(("Invalid state! Not mounted!\n"));
+        return VERR_PDM_MEDIA_NOT_MOUNTED;
+    }
+
     geo.cCylinders = pLCHSGeometry->cCylinders;
     geo.cHeads = pLCHSGeometry->cHeads;
@@ -1973,8 +2177,26 @@
     if (rc == VERR_VD_GEOMETRY_NOT_SET)
         rc = VERR_PDM_GEOMETRY_NOT_SET;
+    if (RT_SUCCESS(rc))
+        pThis->LCHSGeometry = *pLCHSGeometry;
     LogFlowFunc(("returns %Rrc\n", rc));
     return rc;
 }
 
+/** @interface_method_impl{PDMIMEDIA,pfnBiosIsVisible} */
+static DECLCALLBACK(bool) drvvdBiosIsVisible(PPDMIMEDIA pInterface)
+{
+    PVBOXDISK pThis = PDMIMEDIA_2_VBOXDISK(pInterface);
+    LogFlow(("drvvdBiosIsVisible: returns %d\n", pThis->fBiosVisible));
+    return pThis->fBiosVisible;
+}
+
+/** @interface_method_impl{PDMIMEDIA,pfnGetType} */
+static DECLCALLBACK(PDMMEDIATYPE) drvvdGetType(PPDMIMEDIA pInterface)
+{
+    PVBOXDISK pThis = PDMIMEDIA_2_VBOXDISK(pInterface);
+    LogFlow(("drvvdBiosIsVisible: returns %d\n", pThis->fBiosVisible));
+    return pThis->enmType;
+}
+
 /** @interface_method_impl{PDMIMEDIA,pfnGetUuid} */
 static DECLCALLBACK(int) drvvdGetUuid(PPDMIMEDIA pInterface, PRTUUID pUuid)
@@ -1982,7 +2204,11 @@
     LogFlowFunc(("\n"));
     PVBOXDISK pThis = PDMIMEDIA_2_VBOXDISK(pInterface);
-    int rc = VDGetUuid(pThis->pDisk, 0, pUuid);
-    LogFlowFunc(("returns %Rrc ({%RTuuid})\n", rc, pUuid));
-    return rc;
+
+    /*
+     * Copy the uuid.
+     */
+    *pUuid = pThis->Uuid;
+    LogFlowFunc(("returns {%RTuuid}\n", pUuid));
+    return VINF_SUCCESS;
 }
 
@@ -2044,4 +2270,70 @@
 
 
+/* -=-=-=-=- IMount -=-=-=-=- */
+
+/** @copydoc PDMIMOUNT::pfnUnmount */
+static DECLCALLBACK(int) drvvdUnmount(PPDMIMOUNT pInterface, bool fForce, bool fEject)
+{
+    PVBOXDISK pThis = RT_FROM_MEMBER(pInterface, VBOXDISK, IMount);
+
+    /*
+     * Validate state.
+     */
+    if (!pThis->pDisk)
+    {
+        Log(("drvvdUnmount: Not mounted\n"));
+        return VERR_PDM_MEDIA_NOT_MOUNTED;
+    }
+    if (pThis->fLocked && !fForce)
+    {
+        Log(("drvvdUnmount: Locked\n"));
+        return VERR_PDM_MEDIA_LOCKED;
+    }
+
+    /* Media is no longer locked even if it was previously. */
+    pThis->fLocked = false;
+
+    /*
+     * Notify driver/device above us.
+     */
+    if (pThis->pDrvMountNotify)
+        pThis->pDrvMountNotify->pfnUnmountNotify(pThis->pDrvMountNotify);
+    Log(("drvblockUnmount: success\n"));
+    return VINF_SUCCESS;
+}
+
+
+/** @copydoc PDMIMOUNT::pfnIsMounted */
+static DECLCALLBACK(bool) drvvdIsMounted(PPDMIMOUNT pInterface)
+{
+    PVBOXDISK pThis = RT_FROM_MEMBER(pInterface, VBOXDISK, IMount);
+    return pThis->pDisk != NULL;
+}
+
+/** @copydoc PDMIMOUNT::pfnLock */
+static DECLCALLBACK(int) drvvdLock(PPDMIMOUNT pInterface)
+{
+    PVBOXDISK pThis = RT_FROM_MEMBER(pInterface, VBOXDISK, IMount);
+    Log(("drvblockLock: %d -> %d\n", pThis->fLocked, true));
+    pThis->fLocked = true;
+    return VINF_SUCCESS;
+}
+
+/** @copydoc PDMIMOUNT::pfnUnlock */
+static DECLCALLBACK(int) drvvdUnlock(PPDMIMOUNT pInterface)
+{
+    PVBOXDISK pThis = RT_FROM_MEMBER(pInterface, VBOXDISK, IMount);
+    Log(("drvblockUnlock: %d -> %d\n", pThis->fLocked, false));
+    pThis->fLocked = false;
+    return VINF_SUCCESS;
+}
+
+/** @copydoc PDMIMOUNT::pfnIsLocked */
+static DECLCALLBACK(bool) drvvdIsLocked(PPDMIMOUNT pInterface)
+{
+    PVBOXDISK pThis = RT_FROM_MEMBER(pInterface, VBOXDISK, IMount);
+    return pThis->fLocked;
+}
+
 /*********************************************************************************************************************************
 *   Async Media interface methods                                                                                                *
@@ -2070,4 +2362,13 @@
     int rc = VINF_SUCCESS;
     PVBOXDISK pThis = PDMIMEDIAASYNC_2_VBOXDISK(pInterface);
+
+    /*
+     * Check the state.
+     */
+    if (!pThis->pDisk)
+    {
+        AssertMsgFailed(("Invalid state! Not mounted!\n"));
+        return VERR_PDM_MEDIA_NOT_MOUNTED;
+    }
 
     rc = drvvdKeyCheckPrereqs(pThis);
@@ -2104,4 +2405,13 @@
     PVBOXDISK pThis = PDMIMEDIAASYNC_2_VBOXDISK(pInterface);
 
+    /*
+     * Check the state.
+     */
+    if (!pThis->pDisk)
+    {
+        AssertMsgFailed(("Invalid state! Not mounted!\n"));
+        return VERR_PDM_MEDIA_NOT_MOUNTED;
+    }
+
     rc = drvvdKeyCheckPrereqs(pThis);
     if (RT_FAILURE(rc))
@@ -2135,4 +2445,18 @@
     PVBOXDISK pThis = PDMIMEDIAASYNC_2_VBOXDISK(pInterface);
 
+    /*
+     * Check the state.
+     */
+    if (!pThis->pDisk)
+    {
+        AssertMsgFailed(("Invalid state! Not mounted!\n"));
+        return VERR_PDM_MEDIA_NOT_MOUNTED;
+    }
+
+#ifdef VBOX_IGNORE_FLUSH
+    if (pThis->fIgnoreFlushAsync)
+        return VINF_VD_ASYNC_IO_FINISHED;
+#endif /* VBOX_IGNORE_FLUSH */
+
     if (!pThis->pBlkCache)
         rc = VDAsyncFlush(pThis->pDisk, drvvdAsyncReqComplete, pThis, pvUser);
@@ -2157,4 +2481,13 @@
     LogFlowFunc(("paRanges=%#p cRanges=%u pvUser=%#p\n",
                  paRanges, cRanges, pvUser));
+
+    /*
+     * Check the state.
+     */
+    if (!pThis->pDisk)
+    {
+        AssertMsgFailed(("Invalid state! Not mounted!\n"));
+        return VERR_PDM_MEDIA_NOT_MOUNTED;
+    }
 
     if (!pThis->pBlkCache)
@@ -2309,4 +2642,82 @@
 
 
+/**
+ * Translates a PDMMEDIATYPE value into a string.
+ *
+ * @returns Read only string.
+ * @param   enmType             The type value.
+ */
+static const char *drvvdGetTypeName(PDMMEDIATYPE enmType)
+{
+    switch (enmType)
+    {
+        case PDMMEDIATYPE_ERROR:                return "ERROR";
+        case PDMMEDIATYPE_FLOPPY_360:           return "FLOPPY_360";
+        case PDMMEDIATYPE_FLOPPY_720:           return "FLOPPY_720";
+        case PDMMEDIATYPE_FLOPPY_1_20:          return "FLOPPY_1_20";
+        case PDMMEDIATYPE_FLOPPY_1_44:          return "FLOPPY_1_44";
+        case PDMMEDIATYPE_FLOPPY_2_88:          return "FLOPPY_2_88";
+        case PDMMEDIATYPE_FLOPPY_FAKE_15_6:     return "FLOPPY_FAKE_15_6";
+        case PDMMEDIATYPE_FLOPPY_FAKE_63_5:     return "FLOPPY_FAKE_63_5";
+        case PDMMEDIATYPE_CDROM:                return "CDROM";
+        case PDMMEDIATYPE_DVD:                  return "DVD";
+        case PDMMEDIATYPE_HARD_DISK:            return "HARD_DISK";
+        default:                                return "Unknown";
+    }
+}
+
+/**
+ * Returns the appropriate PDMMEDIATYPE for t he given string.
+ *
+ * @returns PDMMEDIATYPE
+ * @param   pszType    The string representation of the media type.
+ */
+static PDMMEDIATYPE drvvdGetMediaTypeFromString(const char *pszType)
+{
+    PDMMEDIATYPE enmType = PDMMEDIATYPE_ERROR;
+
+    if (!strcmp(pszType, "HardDisk"))
+        enmType = PDMMEDIATYPE_HARD_DISK;
+    else if (!strcmp(pszType, "DVD"))
+        enmType = PDMMEDIATYPE_DVD;
+    else if (!strcmp(pszType, "CDROM"))
+        enmType = PDMMEDIATYPE_CDROM;
+    else if (!strcmp(pszType, "Floppy 2.88"))
+        enmType = PDMMEDIATYPE_FLOPPY_2_88;
+    else if (!strcmp(pszType, "Floppy 1.44"))
+        enmType = PDMMEDIATYPE_FLOPPY_1_44;
+    else if (!strcmp(pszType, "Floppy 1.20"))
+        enmType = PDMMEDIATYPE_FLOPPY_1_20;
+    else if (!strcmp(pszType, "Floppy 720"))
+        enmType = PDMMEDIATYPE_FLOPPY_720;
+    else if (!strcmp(pszType, "Floppy 360"))
+        enmType = PDMMEDIATYPE_FLOPPY_360;
+    else if (!strcmp(pszType, "Floppy 15.6"))
+        enmType = PDMMEDIATYPE_FLOPPY_FAKE_15_6;
+    else if (!strcmp(pszType, "Floppy 63.5"))
+        enmType = PDMMEDIATYPE_FLOPPY_FAKE_63_5;
+
+    return enmType;
+}
+
+/**
+ * Converts PDMMEDIATYPE to the appropriate VDTYPE.
+ *
+ * @returns The VDTYPE.
+ * @param   enmType    The PDMMEDIATYPE to convert from.
+ */
+static VDTYPE drvvdGetVDFromMediaType(PDMMEDIATYPE enmType)
+{
+    if (PDMMEDIATYPE_IS_FLOPPY(enmType))
+        return VDTYPE_FLOPPY;
+    else if (enmType == PDMMEDIATYPE_DVD || enmType == PDMMEDIATYPE_CDROM)
+        return VDTYPE_DVD;
+    else if (enmType == PDMMEDIATYPE_HARD_DISK)
+        return VDTYPE_HDD;
+
+    AssertMsgFailed(("Invalid media type %d{%s} given!\n", enmType, drvvdGetTypeName(enmType)));
+    return VDTYPE_HDD;
+}
+
 /*********************************************************************************************************************************
 *   Base interface methods                                                                                                       *
@@ -2323,4 +2734,5 @@
     PDMIBASE_RETURN_INTERFACE(pszIID, PDMIBASE, &pDrvIns->IBase);
     PDMIBASE_RETURN_INTERFACE(pszIID, PDMIMEDIA, &pThis->IMedia);
+    PDMIBASE_RETURN_INTERFACE(pszIID, PDMIMOUNT, pThis->fMountable ? &pThis->IMount : NULL);
     PDMIBASE_RETURN_INTERFACE(pszIID, PDMIMEDIAASYNC, pThis->fAsyncIOSupported ? &pThis->IMediaAsync : NULL);
     return NULL;
@@ -2593,8 +3005,18 @@
     pThis->IMedia.pfnBiosGetLCHSGeometry = drvvdBiosGetLCHSGeometry;
     pThis->IMedia.pfnBiosSetLCHSGeometry = drvvdBiosSetLCHSGeometry;
+    pThis->IMedia.pfnBiosIsVisible       = drvvdBiosIsVisible;
+    pThis->IMedia.pfnGetType             = drvvdGetType;
     pThis->IMedia.pfnGetUuid             = drvvdGetUuid;
     pThis->IMedia.pfnDiscard             = drvvdDiscard;
     pThis->IMedia.pfnIoBufAlloc          = drvvdIoBufAlloc;
     pThis->IMedia.pfnIoBufFree           = drvvdIoBufFree;
+    pThis->IMedia.pfnSendCmd             = NULL;
+
+    /* IMount */
+    pThis->IMount.pfnUnmount                = drvvdUnmount;
+    pThis->IMount.pfnIsMounted              = drvvdIsMounted;
+    pThis->IMount.pfnLock                   = drvvdLock;
+    pThis->IMount.pfnUnlock                 = drvvdUnlock;
+    pThis->IMount.pfnIsLocked               = drvvdIsLocked;
 
     /* IMediaAsync */
@@ -2623,4 +3045,5 @@
     /* Try to attach async media port interface above.*/
     pThis->pDrvMediaAsyncPort = PDMIBASE_QUERY_INTERFACE(pDrvIns->pUpBase, PDMIMEDIAASYNCPORT);
+    pThis->pDrvMountNotify    = PDMIBASE_QUERY_INTERFACE(pDrvIns->pUpBase, PDMIMOUNTNOTIFY);
 
     /* Before we access any VD API load all given plugins. */
@@ -2639,7 +3062,7 @@
     bool        fInformAboutZeroBlocks = false;
     bool        fSkipConsistencyChecks = false;
+    bool        fEmptyDrive            = false;
     unsigned    iLevel = 0;
     PCFGMNODE   pCurNode = pCfg;
-    VDTYPE      enmType = VDTYPE_HDD;
 
     for (;;)
@@ -2657,5 +3080,11 @@
                                           "SetupMerge\0MergeSource\0MergeTarget\0BwGroup\0Type\0BlockCache\0"
                                           "CachePath\0CacheFormat\0Discard\0InformAboutZeroBlocks\0"
-                                          "SkipConsistencyChecks\0");
+                                          "SkipConsistencyChecks\0"
+                                          "SubType\0Locked\0BIOSVisible\0Cylinders\0Heads\0Sectors\0Mountable\0"
+                                          "EmptyDrive\0"
+#if defined(VBOX_PERIODIC_FLUSH) || defined(VBOX_IGNORE_FLUSH)
+                                          "FlushInterval\0IgnoreFlush\0IgnoreFlushAsync\0"
+#endif /* !(VBOX_PERIODIC_FLUSH || VBOX_IGNORE_FLUSH) */
+                                           );
         }
         else
@@ -2807,23 +3236,15 @@
             }
 
-            char *psz;
-            rc = CFGMR3QueryStringAlloc(pCfg, "Type", &psz);
+            char *psz = NULL;
+           rc = CFGMR3QueryStringAlloc(pCfg, "Type", &psz);
             if (RT_FAILURE(rc))
-            {
-                rc = PDMDRV_SET_ERROR(pDrvIns, VERR_PDM_BLOCK_NO_TYPE, N_("Failed to obtain the type"));
-                break;
-            }
-            else if (!strcmp(psz, "HardDisk"))
-                enmType = VDTYPE_HDD;
-            else if (!strcmp(psz, "DVD"))
-                enmType = VDTYPE_DVD;
-            else if (!strcmp(psz, "Floppy"))
-                enmType = VDTYPE_FLOPPY;
-            else
-            {
-                rc = PDMDrvHlpVMSetError(pDrvIns, VERR_PDM_BLOCK_UNKNOWN_TYPE, RT_SRC_POS,
-                                         N_("Unknown type \"%s\""), psz);
+                return PDMDRV_SET_ERROR(pDrvIns, VERR_PDM_BLOCK_NO_TYPE, N_("Failed to obtain the sub type"));
+            pThis->enmType = drvvdGetMediaTypeFromString(psz);
+            if (pThis->enmType == PDMMEDIATYPE_ERROR)
+            {
+                PDMDrvHlpVMSetError(pDrvIns, VERR_PDM_BLOCK_UNKNOWN_TYPE, RT_SRC_POS,
+                                    N_("Unknown type \"%s\""), psz);
                 MMR3HeapFree(psz);
-                break;
+                return VERR_PDM_BLOCK_UNKNOWN_TYPE;
             }
             MMR3HeapFree(psz); psz = NULL;
@@ -2849,4 +3270,86 @@
                 }
             }
+
+            /* Mountable */
+            rc = CFGMR3QueryBoolDef(pCfg, "Mountable", &pThis->fMountable, false);
+            if (RT_FAILURE(rc))
+                return PDMDRV_SET_ERROR(pDrvIns, rc, N_("Failed to query \"Mountable\" from the config"));
+
+            /* Locked */
+            rc = CFGMR3QueryBoolDef(pCfg, "Locked", &pThis->fLocked, false);
+            if (RT_FAILURE(rc))
+                return PDMDRV_SET_ERROR(pDrvIns, rc, N_("Failed to query \"Locked\" from the config"));
+
+            /* BIOS visible */
+            rc = CFGMR3QueryBoolDef(pCfg, "BIOSVisible", &pThis->fBiosVisible, true);
+            if (RT_FAILURE(rc))
+                return PDMDRV_SET_ERROR(pDrvIns, rc, N_("Failed to query \"BIOSVisible\" from the config"));
+
+            /* Cylinders */
+            rc = CFGMR3QueryU32Def(pCfg, "Cylinders", &pThis->LCHSGeometry.cCylinders, 0);
+            if (RT_FAILURE(rc))
+                return PDMDRV_SET_ERROR(pDrvIns, rc, N_("Failed to query \"Cylinders\" from the config"));
+
+            /* Heads */
+            rc = CFGMR3QueryU32Def(pCfg, "Heads", &pThis->LCHSGeometry.cHeads, 0);
+            if (RT_FAILURE(rc))
+                return PDMDRV_SET_ERROR(pDrvIns, rc, N_("Failed to query \"Heads\" from the config"));
+
+            /* Sectors */
+            rc = CFGMR3QueryU32Def(pCfg, "Sectors", &pThis->LCHSGeometry.cSectors, 0);
+            if (RT_FAILURE(rc))
+                return PDMDRV_SET_ERROR(pDrvIns, rc, N_("Failed to query \"Sectors\" from the config"));
+
+            /* Uuid */
+            rc = CFGMR3QueryStringAlloc(pCfg, "Uuid", &psz);
+            if (rc == VERR_CFGM_VALUE_NOT_FOUND)
+                RTUuidClear(&pThis->Uuid);
+            else if (RT_SUCCESS(rc))
+            {
+                rc = RTUuidFromStr(&pThis->Uuid, psz);
+                if (RT_FAILURE(rc))
+                {
+                    PDMDrvHlpVMSetError(pDrvIns, rc, RT_SRC_POS, N_("Uuid from string failed on \"%s\""), psz);
+                    MMR3HeapFree(psz);
+                    return rc;
+                }
+                MMR3HeapFree(psz); psz = NULL;
+            }
+            else
+                return PDMDRV_SET_ERROR(pDrvIns, rc, N_("Failed to query \"Uuid\" from the config"));
+
+#ifdef VBOX_PERIODIC_FLUSH
+            rc = CFGMR3QueryU32Def(pCfg, "FlushInterval", &pThis->cbFlushInterval, 0);
+            if (RT_FAILURE(rc))
+                return PDMDRV_SET_ERROR(pDrvIns, rc, N_("Failed to query \"FlushInterval\" from the config"));
+#endif /* VBOX_PERIODIC_FLUSH */
+
+#ifdef VBOX_IGNORE_FLUSH
+            rc = CFGMR3QueryBoolDef(pCfg, "IgnoreFlush", &pThis->fIgnoreFlush, true);
+            if (RT_FAILURE(rc))
+                return PDMDRV_SET_ERROR(pDrvIns, rc, N_("Failed to query \"IgnoreFlush\" from the config"));
+
+            if (pThis->fIgnoreFlush)
+                LogRel(("DrvVD: Flushes will be ignored\n"));
+            else
+                LogRel(("DrvVD: Flushes will be passed to the disk\n"));
+
+            rc = CFGMR3QueryBoolDef(pCfg, "IgnoreFlushAsync", &pThis->fIgnoreFlushAsync, false);
+            if (RT_FAILURE(rc))
+                return PDMDRV_SET_ERROR(pDrvIns, rc, N_("Failed to query \"IgnoreFlushAsync\" from the config"));
+
+            if (pThis->fIgnoreFlushAsync)
+                LogRel(("DrvVD: Async flushes will be ignored\n"));
+            else
+                LogRel(("DrvVD: Async flushes will be passed to the disk\n"));
+#endif /* VBOX_IGNORE_FLUSH */
+
+            rc = CFGMR3QueryBoolDef(pCurNode, "EmptyDrive", &fEmptyDrive, false);
+            if (RT_FAILURE(rc))
+            {
+                rc = PDMDRV_SET_ERROR(pDrvIns, rc,
+                                      N_("DrvVD: Configuration error: Querying \"EmptyDrive\" as boolean failed"));
+                break;
+            }
         }
 
@@ -2858,470 +3361,526 @@
     }
 
-    /*
-     * Create the image container and the necessary interfaces.
-     */
-    if (RT_SUCCESS(rc))
+    if (!fEmptyDrive)
     {
         /*
-         * The image has a bandwidth group but the host cache is enabled.
-         * Use the async I/O framework but tell it to enable the host cache.
+         * Create the image container and the necessary interfaces.
          */
-        if (!fUseNewIo && pThis->pszBwGroup)
-        {
-            pThis->fAsyncIoWithHostCache = true;
-            fUseNewIo = true;
-        }
-
-        /** @todo quick hack to work around problems in the async I/O
-         * implementation (rw semaphore thread ownership problem)
-         * while a merge is running. Remove once this is fixed. */
-        if (pThis->fMergePending)
-            fUseNewIo = false;
-
-        if (RT_SUCCESS(rc) && pThis->fMergePending)
-        {
-            rc = RTSemFastMutexCreate(&pThis->MergeCompleteMutex);
-            if (RT_SUCCESS(rc))
-                rc = RTSemRWCreate(&pThis->MergeLock);
-            if (RT_SUCCESS(rc))
-            {
-                pThis->VDIfThreadSync.pfnStartRead   = drvvdThreadStartRead;
-                pThis->VDIfThreadSync.pfnFinishRead  = drvvdThreadFinishRead;
-                pThis->VDIfThreadSync.pfnStartWrite  = drvvdThreadStartWrite;
-                pThis->VDIfThreadSync.pfnFinishWrite = drvvdThreadFinishWrite;
-
-                rc = VDInterfaceAdd(&pThis->VDIfThreadSync.Core, "DrvVD_ThreadSync", VDINTERFACETYPE_THREADSYNC,
-                                    pThis, sizeof(VDINTERFACETHREADSYNC), &pThis->pVDIfsDisk);
-            }
-            else
-            {
-                rc = PDMDRV_SET_ERROR(pDrvIns, rc,
-                                      N_("DrvVD: Failed to create semaphores for \"MergePending\""));
-            }
-        }
-
         if (RT_SUCCESS(rc))
         {
-            rc = VDCreate(pThis->pVDIfsDisk, enmType, &pThis->pDisk);
-            /* Error message is already set correctly. */
-        }
-    }
-
-    if (pThis->pDrvMediaAsyncPort && fUseNewIo)
-        pThis->fAsyncIOSupported = true;
-
-    uint64_t tsStart = RTTimeNanoTS();
-
-    unsigned iImageIdx = 0;
-    while (pCurNode && RT_SUCCESS(rc))
-    {
-        /* Allocate per-image data. */
-        PVBOXIMAGE pImage = drvvdNewImage(pThis);
-        if (!pImage)
-        {
-            rc = VERR_NO_MEMORY;
-            break;
-        }
-
-        /*
-         * Read the image configuration.
-         */
-        rc = CFGMR3QueryStringAlloc(pCurNode, "Path", &pszName);
-        if (RT_FAILURE(rc))
-        {
-            rc = PDMDRV_SET_ERROR(pDrvIns, rc,
-                                  N_("DrvVD: Configuration error: Querying \"Path\" as string failed"));
-            break;
-        }
-
-        rc = CFGMR3QueryStringAlloc(pCurNode, "Format", &pszFormat);
-        if (RT_FAILURE(rc))
-        {
-            rc = PDMDRV_SET_ERROR(pDrvIns, rc,
-                                  N_("DrvVD: Configuration error: Querying \"Format\" as string failed"));
-            break;
-        }
-
-        bool fMergeSource;
-        rc = CFGMR3QueryBoolDef(pCurNode, "MergeSource", &fMergeSource, false);
-        if (RT_FAILURE(rc))
-        {
-            rc = PDMDRV_SET_ERROR(pDrvIns, rc,
-                                  N_("DrvVD: Configuration error: Querying \"MergeSource\" as boolean failed"));
-            break;
-        }
-        if (fMergeSource)
-        {
-            if (pThis->uMergeSource == VD_LAST_IMAGE)
-                pThis->uMergeSource = iImageIdx;
-            else
-            {
-                rc = PDMDRV_SET_ERROR(pDrvIns, VERR_PDM_DRIVER_INVALID_PROPERTIES,
-                                      N_("DrvVD: Configuration error: Multiple \"MergeSource\" occurrences"));
-                break;
-            }
-        }
-
-        bool fMergeTarget;
-        rc = CFGMR3QueryBoolDef(pCurNode, "MergeTarget", &fMergeTarget, false);
-        if (RT_FAILURE(rc))
-        {
-            rc = PDMDRV_SET_ERROR(pDrvIns, rc,
-                                  N_("DrvVD: Configuration error: Querying \"MergeTarget\" as boolean failed"));
-            break;
-        }
-        if (fMergeTarget)
-        {
-            if (pThis->uMergeTarget == VD_LAST_IMAGE)
-                pThis->uMergeTarget = iImageIdx;
-            else
-            {
-                rc = PDMDRV_SET_ERROR(pDrvIns, VERR_PDM_DRIVER_INVALID_PROPERTIES,
-                                      N_("DrvVD: Configuration error: Multiple \"MergeTarget\" occurrences"));
-                break;
-            }
-        }
-
-        PCFGMNODE pCfgVDConfig = CFGMR3GetChild(pCurNode, "VDConfig");
-        pImage->VDIfConfig.pfnAreKeysValid = drvvdCfgAreKeysValid;
-        pImage->VDIfConfig.pfnQuerySize    = drvvdCfgQuerySize;
-        pImage->VDIfConfig.pfnQuery        = drvvdCfgQuery;
-        pImage->VDIfConfig.pfnQueryBytes   = NULL;
-        rc = VDInterfaceAdd(&pImage->VDIfConfig.Core, "DrvVD_Config", VDINTERFACETYPE_CONFIG,
-                            pCfgVDConfig, sizeof(VDINTERFACECONFIG), &pImage->pVDIfsImage);
-        AssertRC(rc);
-
-        /* Check VDConfig for encryption config. */
-        if (pCfgVDConfig)
-            pThis->pCfgCrypto = CFGMR3GetChild(pCfgVDConfig, "CRYPT");
-
-        if (pThis->pCfgCrypto)
-        {
-            /* Setup VDConfig interface for disk encryption support. */
-            pThis->VDIfCfg.pfnAreKeysValid  = drvvdCfgAreKeysValid;
-            pThis->VDIfCfg.pfnQuerySize     = drvvdCfgQuerySize;
-            pThis->VDIfCfg.pfnQuery         = drvvdCfgQuery;
-            pThis->VDIfCfg.pfnQueryBytes    = NULL;
-
-            pThis->VDIfCrypto.pfnKeyRetain               = drvvdCryptoKeyRetain;
-            pThis->VDIfCrypto.pfnKeyRelease              = drvvdCryptoKeyRelease;
-            pThis->VDIfCrypto.pfnKeyStorePasswordRetain  = drvvdCryptoKeyStorePasswordRetain;
-            pThis->VDIfCrypto.pfnKeyStorePasswordRelease = drvvdCryptoKeyStorePasswordRelease;
-        }
-
-        /* Unconditionally insert the TCPNET interface, don't bother to check
-         * if an image really needs it. Will be ignored. Since the TCPNET
-         * interface is per image we could make this more flexible in the
-         * future if we want to. */
-        /* Construct TCPNET callback table depending on the config. This is
-         * done unconditionally, as uninterested backends will ignore it. */
-        if (fHostIP)
-        {
-            pImage->VDIfTcpNet.pfnSocketCreate = drvvdTcpSocketCreate;
-            pImage->VDIfTcpNet.pfnSocketDestroy = drvvdTcpSocketDestroy;
-            pImage->VDIfTcpNet.pfnClientConnect = drvvdTcpClientConnect;
-            pImage->VDIfTcpNet.pfnIsClientConnected = drvvdTcpIsClientConnected;
-            pImage->VDIfTcpNet.pfnClientClose = drvvdTcpClientClose;
-            pImage->VDIfTcpNet.pfnSelectOne = drvvdTcpSelectOne;
-            pImage->VDIfTcpNet.pfnRead = drvvdTcpRead;
-            pImage->VDIfTcpNet.pfnWrite = drvvdTcpWrite;
-            pImage->VDIfTcpNet.pfnSgWrite = drvvdTcpSgWrite;
-            pImage->VDIfTcpNet.pfnReadNB = drvvdTcpReadNB;
-            pImage->VDIfTcpNet.pfnWriteNB = drvvdTcpWriteNB;
-            pImage->VDIfTcpNet.pfnSgWriteNB = drvvdTcpSgWriteNB;
-            pImage->VDIfTcpNet.pfnFlush = drvvdTcpFlush;
-            pImage->VDIfTcpNet.pfnSetSendCoalescing = drvvdTcpSetSendCoalescing;
-            pImage->VDIfTcpNet.pfnGetLocalAddress = drvvdTcpGetLocalAddress;
-            pImage->VDIfTcpNet.pfnGetPeerAddress = drvvdTcpGetPeerAddress;
-
             /*
-             * There is a 15ms delay between receiving the data and marking the socket
-             * as readable on Windows XP which hurts async I/O performance of
-             * TCP backends badly. Provide a different select method without
-             * using poll on XP.
-             * This is only used on XP because it is not as efficient as the one using poll
-             * and all other Windows versions are working fine.
+             * The image has a bandwidth group but the host cache is enabled.
+             * Use the async I/O framework but tell it to enable the host cache.
              */
-            char szOS[64];
-            memset(szOS, 0, sizeof(szOS));
-            rc = RTSystemQueryOSInfo(RTSYSOSINFO_PRODUCT, &szOS[0], sizeof(szOS));
-
-            if (RT_SUCCESS(rc) && !strncmp(szOS, "Windows XP", 10))
-            {
-                LogRel(("VD: Detected Windows XP, disabled poll based waiting for TCP\n"));
-                pImage->VDIfTcpNet.pfnSelectOneEx = drvvdTcpSelectOneExNoPoll;
-            }
-            else
-                pImage->VDIfTcpNet.pfnSelectOneEx = drvvdTcpSelectOneExPoll;
-
-            pImage->VDIfTcpNet.pfnPoke = drvvdTcpPoke;
-        }
-        else
-        {
-#ifndef VBOX_WITH_INIP
-            rc = PDMDrvHlpVMSetError(pDrvIns, VERR_PDM_DRVINS_UNKNOWN_CFG_VALUES,
-                                     RT_SRC_POS, N_("DrvVD: Configuration error: TCP over Internal Networking not compiled in"));
-#else /* VBOX_WITH_INIP */
-            pImage->VDIfTcpNet.pfnSocketCreate = drvvdINIPSocketCreate;
-            pImage->VDIfTcpNet.pfnSocketDestroy = drvvdINIPSocketDestroy;
-            pImage->VDIfTcpNet.pfnClientConnect = drvvdINIPClientConnect;
-            pImage->VDIfTcpNet.pfnClientClose = drvvdINIPClientClose;
-            pImage->VDIfTcpNet.pfnIsClientConnected = drvvdINIPIsClientConnected;
-            pImage->VDIfTcpNet.pfnSelectOne = drvvdINIPSelectOne;
-            pImage->VDIfTcpNet.pfnRead = drvvdINIPRead;
-            pImage->VDIfTcpNet.pfnWrite = drvvdINIPWrite;
-            pImage->VDIfTcpNet.pfnSgWrite = drvvdINIPSgWrite;
-            pImage->VDIfTcpNet.pfnFlush = drvvdINIPFlush;
-            pImage->VDIfTcpNet.pfnSetSendCoalescing = drvvdINIPSetSendCoalescing;
-            pImage->VDIfTcpNet.pfnGetLocalAddress = drvvdINIPGetLocalAddress;
-            pImage->VDIfTcpNet.pfnGetPeerAddress = drvvdINIPGetPeerAddress;
-            pImage->VDIfTcpNet.pfnSelectOneEx = drvvdINIPSelectOneEx;
-            pImage->VDIfTcpNet.pfnPoke = drvvdINIPPoke;
-#endif /* VBOX_WITH_INIP */
-        }
-        rc = VDInterfaceAdd(&pImage->VDIfTcpNet.Core, "DrvVD_TCPNET",
-                            VDINTERFACETYPE_TCPNET, NULL,
-                            sizeof(VDINTERFACETCPNET), &pImage->pVDIfsImage);
-        AssertRC(rc);
-
-        /* Insert the custom I/O interface only if we're told to use new IO.
-         * Since the I/O interface is per image we could make this more
-         * flexible in the future if we want to. */
-        if (fUseNewIo)
-        {
-#ifdef VBOX_WITH_PDM_ASYNC_COMPLETION
-            pImage->VDIfIo.pfnOpen       = drvvdAsyncIOOpen;
-            pImage->VDIfIo.pfnClose      = drvvdAsyncIOClose;
-            pImage->VDIfIo.pfnGetSize    = drvvdAsyncIOGetSize;
-            pImage->VDIfIo.pfnSetSize    = drvvdAsyncIOSetSize;
-            pImage->VDIfIo.pfnReadSync   = drvvdAsyncIOReadSync;
-            pImage->VDIfIo.pfnWriteSync  = drvvdAsyncIOWriteSync;
-            pImage->VDIfIo.pfnFlushSync  = drvvdAsyncIOFlushSync;
-            pImage->VDIfIo.pfnReadAsync  = drvvdAsyncIOReadAsync;
-            pImage->VDIfIo.pfnWriteAsync = drvvdAsyncIOWriteAsync;
-            pImage->VDIfIo.pfnFlushAsync = drvvdAsyncIOFlushAsync;
-#else /* !VBOX_WITH_PDM_ASYNC_COMPLETION */
-            rc = PDMDrvHlpVMSetError(pDrvIns, VERR_PDM_DRVINS_UNKNOWN_CFG_VALUES,
-                                     RT_SRC_POS, N_("DrvVD: Configuration error: Async Completion Framework not compiled in"));
-#endif /* !VBOX_WITH_PDM_ASYNC_COMPLETION */
-            if (RT_SUCCESS(rc))
-                rc = VDInterfaceAdd(&pImage->VDIfIo.Core, "DrvVD_IO", VDINTERFACETYPE_IO,
-                                    pThis, sizeof(VDINTERFACEIO), &pImage->pVDIfsImage);
-            AssertRC(rc);
-        }
-
-        /*
-         * Open the image.
-         */
-        unsigned uOpenFlags;
-        if (fReadOnly || pThis->fTempReadOnly || iLevel != 0)
-            uOpenFlags = VD_OPEN_FLAGS_READONLY;
-        else
-            uOpenFlags = VD_OPEN_FLAGS_NORMAL;
-        if (fHonorZeroWrites)
-            uOpenFlags |= VD_OPEN_FLAGS_HONOR_ZEROES;
-        if (pThis->fAsyncIOSupported)
-            uOpenFlags |= VD_OPEN_FLAGS_ASYNC_IO;
-        if (pThis->fShareable)
-            uOpenFlags |= VD_OPEN_FLAGS_SHAREABLE;
-        if (fDiscard && iLevel == 0)
-            uOpenFlags |= VD_OPEN_FLAGS_DISCARD;
-        if (fInformAboutZeroBlocks)
-            uOpenFlags |= VD_OPEN_FLAGS_INFORM_ABOUT_ZERO_BLOCKS;
-        if (   (uOpenFlags & VD_OPEN_FLAGS_READONLY)
-            && fSkipConsistencyChecks)
-            uOpenFlags |= VD_OPEN_FLAGS_SKIP_CONSISTENCY_CHECKS;
-
-        /* Try to open backend in async I/O mode first. */
-        rc = VDOpen(pThis->pDisk, pszFormat, pszName, uOpenFlags, pImage->pVDIfsImage);
-        if (rc == VERR_NOT_SUPPORTED)
-        {
-            pThis->fAsyncIOSupported = false;
-            uOpenFlags &= ~VD_OPEN_FLAGS_ASYNC_IO;
-            rc = VDOpen(pThis->pDisk, pszFormat, pszName, uOpenFlags, pImage->pVDIfsImage);
-        }
-
-        if (rc == VERR_VD_DISCARD_NOT_SUPPORTED)
-        {
-            fDiscard = false;
-            uOpenFlags &= ~VD_OPEN_FLAGS_DISCARD;
-            rc = VDOpen(pThis->pDisk, pszFormat, pszName, uOpenFlags, pImage->pVDIfsImage);
-        }
-
-        if (!fDiscard)
-        {
-            pThis->IMedia.pfnDiscard = NULL;
-            pThis->IMediaAsync.pfnStartDiscard = NULL;
-        }
-
-        if (RT_SUCCESS(rc))
-        {
-            LogFunc(("%d - Opened '%s' in %s mode\n",
-                     iLevel, pszName,
-                     VDIsReadOnly(pThis->pDisk) ? "read-only" : "read-write"));
-            if (  VDIsReadOnly(pThis->pDisk)
-                && !fReadOnly
-                && !fMaybeReadOnly
-                && !pThis->fTempReadOnly
-                && iLevel == 0)
-            {
-                rc = PDMDrvHlpVMSetError(pDrvIns, VERR_VD_IMAGE_READ_ONLY, RT_SRC_POS,
-                                         N_("Failed to open image '%s' for writing due to wrong permissions"),
-                                         pszName);
-                break;
-            }
-        }
-        else
-        {
-           rc = PDMDrvHlpVMSetError(pDrvIns, rc, RT_SRC_POS,
-                                    N_("Failed to open image '%s' in %s mode"), pszName,
-                                    (uOpenFlags & VD_OPEN_FLAGS_READONLY) ? "read-only" : "read-write");
-           break;
-        }
-
-
-        MMR3HeapFree(pszName);
-        pszName = NULL;
-        MMR3HeapFree(pszFormat);
-        pszFormat = NULL;
-
-        /* next */
-        iLevel--;
-        iImageIdx++;
-        pCurNode = CFGMR3GetParent(pCurNode);
-    }
-
-    LogRel(("VD: Opening the disk took %lld ns\n", RTTimeNanoTS() - tsStart));
-
-    /* Open the cache image if set. */
-    if (   RT_SUCCESS(rc)
-        && RT_VALID_PTR(pszCachePath))
-    {
-        /* Insert the custom I/O interface only if we're told to use new IO.
-         * Since the I/O interface is per image we could make this more
-         * flexible in the future if we want to. */
-        if (fUseNewIo)
-        {
-#ifdef VBOX_WITH_PDM_ASYNC_COMPLETION
-            pThis->VDIfIoCache.pfnOpen       = drvvdAsyncIOOpen;
-            pThis->VDIfIoCache.pfnClose      = drvvdAsyncIOClose;
-            pThis->VDIfIoCache.pfnGetSize    = drvvdAsyncIOGetSize;
-            pThis->VDIfIoCache.pfnSetSize    = drvvdAsyncIOSetSize;
-            pThis->VDIfIoCache.pfnReadSync   = drvvdAsyncIOReadSync;
-            pThis->VDIfIoCache.pfnWriteSync  = drvvdAsyncIOWriteSync;
-            pThis->VDIfIoCache.pfnFlushSync  = drvvdAsyncIOFlushSync;
-            pThis->VDIfIoCache.pfnReadAsync  = drvvdAsyncIOReadAsync;
-            pThis->VDIfIoCache.pfnWriteAsync = drvvdAsyncIOWriteAsync;
-            pThis->VDIfIoCache.pfnFlushAsync = drvvdAsyncIOFlushAsync;
-#else /* !VBOX_WITH_PDM_ASYNC_COMPLETION */
-            rc = PDMDrvHlpVMSetError(pDrvIns, VERR_PDM_DRVINS_UNKNOWN_CFG_VALUES,
-                                     RT_SRC_POS, N_("DrvVD: Configuration error: Async Completion Framework not compiled in"));
-#endif /* !VBOX_WITH_PDM_ASYNC_COMPLETION */
-            if (RT_SUCCESS(rc))
-                rc = VDInterfaceAdd(&pThis->VDIfIoCache.Core, "DrvVD_IO", VDINTERFACETYPE_IO,
-                                    pThis, sizeof(VDINTERFACEIO), &pThis->pVDIfsCache);
-            AssertRC(rc);
-        }
-
-        rc = VDCacheOpen(pThis->pDisk, pszCacheFormat, pszCachePath, VD_OPEN_FLAGS_NORMAL, pThis->pVDIfsCache);
-        if (RT_FAILURE(rc))
-            rc = PDMDRV_SET_ERROR(pDrvIns, rc, N_("DrvVD: Could not open cache image"));
-    }
-
-    if (RT_VALID_PTR(pszCachePath))
-        MMR3HeapFree(pszCachePath);
-    if (RT_VALID_PTR(pszCacheFormat))
-        MMR3HeapFree(pszCacheFormat);
-
-    if (   RT_SUCCESS(rc)
-        && pThis->fMergePending
-        && (   pThis->uMergeSource == VD_LAST_IMAGE
-            || pThis->uMergeTarget == VD_LAST_IMAGE))
-    {
-        rc = PDMDRV_SET_ERROR(pDrvIns, VERR_PDM_DRIVER_INVALID_PROPERTIES,
-                              N_("DrvVD: Configuration error: Inconsistent image merge data"));
-    }
-
-    /* Create the block cache if enabled. */
-    if (   fUseBlockCache
-        && !pThis->fShareable
-        && !fDiscard
-        && !pThis->pCfgCrypto /* Disk encryption disables the block cache for security reasons */
-        && RT_SUCCESS(rc))
-    {
-        /*
-         * We need a unique ID for the block cache (to identify the owner of data
-         * blocks in a saved state). UUIDs are not really suitable because
-         * there are image formats which don't support them. Furthermore it is
-         * possible that a new diff image was attached after a saved state
-         * which changes the UUID.
-         * However the device "name + device instance + LUN" triple the disk is
-         * attached to is always constant for saved states.
-         */
-        char *pszId = NULL;
-        uint32_t iInstance, iLUN;
-        const char *pcszController;
-
-        rc = pThis->pDrvMediaPort->pfnQueryDeviceLocation(pThis->pDrvMediaPort, &pcszController,
-                                                          &iInstance, &iLUN);
-        if (RT_FAILURE(rc))
-            rc = PDMDRV_SET_ERROR(pDrvIns, VERR_PDM_DRIVER_INVALID_PROPERTIES,
-                                  N_("DrvVD: Configuration error: Could not query device data"));
-        else
-        {
-            int cbStr = RTStrAPrintf(&pszId, "%s-%d-%d", pcszController, iInstance, iLUN);
-
-            if (cbStr > 0)
-            {
-                rc = PDMDrvHlpBlkCacheRetain(pDrvIns, &pThis->pBlkCache,
-                                             drvvdBlkCacheXferComplete,
-                                             drvvdBlkCacheXferEnqueue,
-                                             drvvdBlkCacheXferEnqueueDiscard,
-                                             pszId);
-                if (rc == VERR_NOT_SUPPORTED)
+            if (!fUseNewIo && pThis->pszBwGroup)
+            {
+                pThis->fAsyncIoWithHostCache = true;
+                fUseNewIo = true;
+            }
+
+            /** @todo quick hack to work around problems in the async I/O
+             * implementation (rw semaphore thread ownership problem)
+             * while a merge is running. Remove once this is fixed. */
+            if (pThis->fMergePending)
+                fUseNewIo = false;
+
+            if (RT_SUCCESS(rc) && pThis->fMergePending)
+            {
+                rc = RTSemFastMutexCreate(&pThis->MergeCompleteMutex);
+                if (RT_SUCCESS(rc))
+                    rc = RTSemRWCreate(&pThis->MergeLock);
+                if (RT_SUCCESS(rc))
                 {
-                    LogRel(("VD: Block cache is not supported\n"));
-                    rc = VINF_SUCCESS;
+                    pThis->VDIfThreadSync.pfnStartRead   = drvvdThreadStartRead;
+                    pThis->VDIfThreadSync.pfnFinishRead  = drvvdThreadFinishRead;
+                    pThis->VDIfThreadSync.pfnStartWrite  = drvvdThreadStartWrite;
+                    pThis->VDIfThreadSync.pfnFinishWrite = drvvdThreadFinishWrite;
+
+                    rc = VDInterfaceAdd(&pThis->VDIfThreadSync.Core, "DrvVD_ThreadSync", VDINTERFACETYPE_THREADSYNC,
+                                        pThis, sizeof(VDINTERFACETHREADSYNC), &pThis->pVDIfsDisk);
                 }
                 else
-                    AssertRC(rc);
-
-                RTStrFree(pszId);
+                {
+                    rc = PDMDRV_SET_ERROR(pDrvIns, rc,
+                                          N_("DrvVD: Failed to create semaphores for \"MergePending\""));
+                }
+            }
+
+            if (RT_SUCCESS(rc))
+            {
+                rc = VDCreate(pThis->pVDIfsDisk, drvvdGetVDFromMediaType(pThis->enmType), &pThis->pDisk);
+                /* Error message is already set correctly. */
+            }
+        }
+
+        if (pThis->pDrvMediaAsyncPort && fUseNewIo)
+            pThis->fAsyncIOSupported = true;
+
+        uint64_t tsStart = RTTimeNanoTS();
+
+        unsigned iImageIdx = 0;
+        while (pCurNode && RT_SUCCESS(rc))
+        {
+            /* Allocate per-image data. */
+            PVBOXIMAGE pImage = drvvdNewImage(pThis);
+            if (!pImage)
+            {
+                rc = VERR_NO_MEMORY;
+                break;
+            }
+
+            /*
+             * Read the image configuration.
+             */
+            rc = CFGMR3QueryStringAlloc(pCurNode, "Path", &pszName);
+            if (RT_FAILURE(rc))
+            {
+                rc = PDMDRV_SET_ERROR(pDrvIns, rc,
+                                      N_("DrvVD: Configuration error: Querying \"Path\" as string failed"));
+                break;
+            }
+
+            rc = CFGMR3QueryStringAlloc(pCurNode, "Format", &pszFormat);
+            if (RT_FAILURE(rc))
+            {
+                rc = PDMDRV_SET_ERROR(pDrvIns, rc,
+                                      N_("DrvVD: Configuration error: Querying \"Format\" as string failed"));
+                break;
+            }
+
+            bool fMergeSource;
+            rc = CFGMR3QueryBoolDef(pCurNode, "MergeSource", &fMergeSource, false);
+            if (RT_FAILURE(rc))
+            {
+                rc = PDMDRV_SET_ERROR(pDrvIns, rc,
+                                      N_("DrvVD: Configuration error: Querying \"MergeSource\" as boolean failed"));
+                break;
+            }
+            if (fMergeSource)
+            {
+                if (pThis->uMergeSource == VD_LAST_IMAGE)
+                    pThis->uMergeSource = iImageIdx;
+                else
+                {
+                    rc = PDMDRV_SET_ERROR(pDrvIns, VERR_PDM_DRIVER_INVALID_PROPERTIES,
+                                          N_("DrvVD: Configuration error: Multiple \"MergeSource\" occurrences"));
+                    break;
+                }
+            }
+
+            bool fMergeTarget;
+            rc = CFGMR3QueryBoolDef(pCurNode, "MergeTarget", &fMergeTarget, false);
+            if (RT_FAILURE(rc))
+            {
+                rc = PDMDRV_SET_ERROR(pDrvIns, rc,
+                                      N_("DrvVD: Configuration error: Querying \"MergeTarget\" as boolean failed"));
+                break;
+            }
+            if (fMergeTarget)
+            {
+                if (pThis->uMergeTarget == VD_LAST_IMAGE)
+                    pThis->uMergeTarget = iImageIdx;
+                else
+                {
+                    rc = PDMDRV_SET_ERROR(pDrvIns, VERR_PDM_DRIVER_INVALID_PROPERTIES,
+                                          N_("DrvVD: Configuration error: Multiple \"MergeTarget\" occurrences"));
+                    break;
+                }
+            }
+
+            PCFGMNODE pCfgVDConfig = CFGMR3GetChild(pCurNode, "VDConfig");
+            pImage->VDIfConfig.pfnAreKeysValid = drvvdCfgAreKeysValid;
+            pImage->VDIfConfig.pfnQuerySize    = drvvdCfgQuerySize;
+            pImage->VDIfConfig.pfnQuery        = drvvdCfgQuery;
+            pImage->VDIfConfig.pfnQueryBytes   = NULL;
+            rc = VDInterfaceAdd(&pImage->VDIfConfig.Core, "DrvVD_Config", VDINTERFACETYPE_CONFIG,
+                                pCfgVDConfig, sizeof(VDINTERFACECONFIG), &pImage->pVDIfsImage);
+            AssertRC(rc);
+
+            /* Check VDConfig for encryption config. */
+            if (pCfgVDConfig)
+                pThis->pCfgCrypto = CFGMR3GetChild(pCfgVDConfig, "CRYPT");
+
+            if (pThis->pCfgCrypto)
+            {
+                /* Setup VDConfig interface for disk encryption support. */
+                pThis->VDIfCfg.pfnAreKeysValid  = drvvdCfgAreKeysValid;
+                pThis->VDIfCfg.pfnQuerySize     = drvvdCfgQuerySize;
+                pThis->VDIfCfg.pfnQuery         = drvvdCfgQuery;
+                pThis->VDIfCfg.pfnQueryBytes    = NULL;
+
+                pThis->VDIfCrypto.pfnKeyRetain               = drvvdCryptoKeyRetain;
+                pThis->VDIfCrypto.pfnKeyRelease              = drvvdCryptoKeyRelease;
+                pThis->VDIfCrypto.pfnKeyStorePasswordRetain  = drvvdCryptoKeyStorePasswordRetain;
+                pThis->VDIfCrypto.pfnKeyStorePasswordRelease = drvvdCryptoKeyStorePasswordRelease;
+            }
+
+            /* Unconditionally insert the TCPNET interface, don't bother to check
+             * if an image really needs it. Will be ignored. Since the TCPNET
+             * interface is per image we could make this more flexible in the
+             * future if we want to. */
+            /* Construct TCPNET callback table depending on the config. This is
+             * done unconditionally, as uninterested backends will ignore it. */
+            if (fHostIP)
+            {
+                pImage->VDIfTcpNet.pfnSocketCreate = drvvdTcpSocketCreate;
+                pImage->VDIfTcpNet.pfnSocketDestroy = drvvdTcpSocketDestroy;
+                pImage->VDIfTcpNet.pfnClientConnect = drvvdTcpClientConnect;
+                pImage->VDIfTcpNet.pfnIsClientConnected = drvvdTcpIsClientConnected;
+                pImage->VDIfTcpNet.pfnClientClose = drvvdTcpClientClose;
+                pImage->VDIfTcpNet.pfnSelectOne = drvvdTcpSelectOne;
+                pImage->VDIfTcpNet.pfnRead = drvvdTcpRead;
+                pImage->VDIfTcpNet.pfnWrite = drvvdTcpWrite;
+                pImage->VDIfTcpNet.pfnSgWrite = drvvdTcpSgWrite;
+                pImage->VDIfTcpNet.pfnReadNB = drvvdTcpReadNB;
+                pImage->VDIfTcpNet.pfnWriteNB = drvvdTcpWriteNB;
+                pImage->VDIfTcpNet.pfnSgWriteNB = drvvdTcpSgWriteNB;
+                pImage->VDIfTcpNet.pfnFlush = drvvdTcpFlush;
+                pImage->VDIfTcpNet.pfnSetSendCoalescing = drvvdTcpSetSendCoalescing;
+                pImage->VDIfTcpNet.pfnGetLocalAddress = drvvdTcpGetLocalAddress;
+                pImage->VDIfTcpNet.pfnGetPeerAddress = drvvdTcpGetPeerAddress;
+
+                /*
+                 * There is a 15ms delay between receiving the data and marking the socket
+                 * as readable on Windows XP which hurts async I/O performance of
+                 * TCP backends badly. Provide a different select method without
+                 * using poll on XP.
+                 * This is only used on XP because it is not as efficient as the one using poll
+                 * and all other Windows versions are working fine.
+                 */
+                char szOS[64];
+                memset(szOS, 0, sizeof(szOS));
+                rc = RTSystemQueryOSInfo(RTSYSOSINFO_PRODUCT, &szOS[0], sizeof(szOS));
+
+                if (RT_SUCCESS(rc) && !strncmp(szOS, "Windows XP", 10))
+                {
+                    LogRel(("VD: Detected Windows XP, disabled poll based waiting for TCP\n"));
+                    pImage->VDIfTcpNet.pfnSelectOneEx = drvvdTcpSelectOneExNoPoll;
+                }
+                else
+                    pImage->VDIfTcpNet.pfnSelectOneEx = drvvdTcpSelectOneExPoll;
+
+                pImage->VDIfTcpNet.pfnPoke = drvvdTcpPoke;
             }
             else
+            {
+#ifndef VBOX_WITH_INIP
+                rc = PDMDrvHlpVMSetError(pDrvIns, VERR_PDM_DRVINS_UNKNOWN_CFG_VALUES,
+                                         RT_SRC_POS, N_("DrvVD: Configuration error: TCP over Internal Networking not compiled in"));
+#else /* VBOX_WITH_INIP */
+                pImage->VDIfTcpNet.pfnSocketCreate = drvvdINIPSocketCreate;
+                pImage->VDIfTcpNet.pfnSocketDestroy = drvvdINIPSocketDestroy;
+                pImage->VDIfTcpNet.pfnClientConnect = drvvdINIPClientConnect;
+                pImage->VDIfTcpNet.pfnClientClose = drvvdINIPClientClose;
+                pImage->VDIfTcpNet.pfnIsClientConnected = drvvdINIPIsClientConnected;
+                pImage->VDIfTcpNet.pfnSelectOne = drvvdINIPSelectOne;
+                pImage->VDIfTcpNet.pfnRead = drvvdINIPRead;
+                pImage->VDIfTcpNet.pfnWrite = drvvdINIPWrite;
+                pImage->VDIfTcpNet.pfnSgWrite = drvvdINIPSgWrite;
+                pImage->VDIfTcpNet.pfnFlush = drvvdINIPFlush;
+                pImage->VDIfTcpNet.pfnSetSendCoalescing = drvvdINIPSetSendCoalescing;
+                pImage->VDIfTcpNet.pfnGetLocalAddress = drvvdINIPGetLocalAddress;
+                pImage->VDIfTcpNet.pfnGetPeerAddress = drvvdINIPGetPeerAddress;
+                pImage->VDIfTcpNet.pfnSelectOneEx = drvvdINIPSelectOneEx;
+                pImage->VDIfTcpNet.pfnPoke = drvvdINIPPoke;
+#endif /* VBOX_WITH_INIP */
+            }
+            rc = VDInterfaceAdd(&pImage->VDIfTcpNet.Core, "DrvVD_TCPNET",
+                                VDINTERFACETYPE_TCPNET, NULL,
+                                sizeof(VDINTERFACETCPNET), &pImage->pVDIfsImage);
+            AssertRC(rc);
+
+            /* Insert the custom I/O interface only if we're told to use new IO.
+             * Since the I/O interface is per image we could make this more
+             * flexible in the future if we want to. */
+            if (fUseNewIo)
+            {
+#ifdef VBOX_WITH_PDM_ASYNC_COMPLETION
+                pImage->VDIfIo.pfnOpen       = drvvdAsyncIOOpen;
+                pImage->VDIfIo.pfnClose      = drvvdAsyncIOClose;
+                pImage->VDIfIo.pfnGetSize    = drvvdAsyncIOGetSize;
+                pImage->VDIfIo.pfnSetSize    = drvvdAsyncIOSetSize;
+                pImage->VDIfIo.pfnReadSync   = drvvdAsyncIOReadSync;
+                pImage->VDIfIo.pfnWriteSync  = drvvdAsyncIOWriteSync;
+                pImage->VDIfIo.pfnFlushSync  = drvvdAsyncIOFlushSync;
+                pImage->VDIfIo.pfnReadAsync  = drvvdAsyncIOReadAsync;
+                pImage->VDIfIo.pfnWriteAsync = drvvdAsyncIOWriteAsync;
+                pImage->VDIfIo.pfnFlushAsync = drvvdAsyncIOFlushAsync;
+#else /* !VBOX_WITH_PDM_ASYNC_COMPLETION */
+                rc = PDMDrvHlpVMSetError(pDrvIns, VERR_PDM_DRVINS_UNKNOWN_CFG_VALUES,
+                                         RT_SRC_POS, N_("DrvVD: Configuration error: Async Completion Framework not compiled in"));
+#endif /* !VBOX_WITH_PDM_ASYNC_COMPLETION */
+                if (RT_SUCCESS(rc))
+                    rc = VDInterfaceAdd(&pImage->VDIfIo.Core, "DrvVD_IO", VDINTERFACETYPE_IO,
+                                        pThis, sizeof(VDINTERFACEIO), &pImage->pVDIfsImage);
+                AssertRC(rc);
+            }
+
+            /*
+             * Open the image.
+             */
+            unsigned uOpenFlags;
+            if (fReadOnly || pThis->fTempReadOnly || iLevel != 0)
+                uOpenFlags = VD_OPEN_FLAGS_READONLY;
+            else
+                uOpenFlags = VD_OPEN_FLAGS_NORMAL;
+            if (fHonorZeroWrites)
+                uOpenFlags |= VD_OPEN_FLAGS_HONOR_ZEROES;
+            if (pThis->fAsyncIOSupported)
+                uOpenFlags |= VD_OPEN_FLAGS_ASYNC_IO;
+            if (pThis->fShareable)
+                uOpenFlags |= VD_OPEN_FLAGS_SHAREABLE;
+            if (fDiscard && iLevel == 0)
+                uOpenFlags |= VD_OPEN_FLAGS_DISCARD;
+            if (fInformAboutZeroBlocks)
+                uOpenFlags |= VD_OPEN_FLAGS_INFORM_ABOUT_ZERO_BLOCKS;
+            if (   (uOpenFlags & VD_OPEN_FLAGS_READONLY)
+                && fSkipConsistencyChecks)
+                uOpenFlags |= VD_OPEN_FLAGS_SKIP_CONSISTENCY_CHECKS;
+
+            /* Try to open backend in async I/O mode first. */
+            rc = VDOpen(pThis->pDisk, pszFormat, pszName, uOpenFlags, pImage->pVDIfsImage);
+            if (rc == VERR_NOT_SUPPORTED)
+            {
+                pThis->fAsyncIOSupported = false;
+                uOpenFlags &= ~VD_OPEN_FLAGS_ASYNC_IO;
+                rc = VDOpen(pThis->pDisk, pszFormat, pszName, uOpenFlags, pImage->pVDIfsImage);
+            }
+
+            if (rc == VERR_VD_DISCARD_NOT_SUPPORTED)
+            {
+                fDiscard = false;
+                uOpenFlags &= ~VD_OPEN_FLAGS_DISCARD;
+                rc = VDOpen(pThis->pDisk, pszFormat, pszName, uOpenFlags, pImage->pVDIfsImage);
+            }
+
+            if (!fDiscard)
+            {
+                pThis->IMedia.pfnDiscard = NULL;
+                pThis->IMediaAsync.pfnStartDiscard = NULL;
+            }
+
+            if (RT_SUCCESS(rc))
+            {
+                LogFunc(("%d - Opened '%s' in %s mode\n",
+                         iLevel, pszName,
+                         VDIsReadOnly(pThis->pDisk) ? "read-only" : "read-write"));
+                if (  VDIsReadOnly(pThis->pDisk)
+                    && !fReadOnly
+                    && !fMaybeReadOnly
+                    && !pThis->fTempReadOnly
+                    && iLevel == 0)
+                {
+                    rc = PDMDrvHlpVMSetError(pDrvIns, VERR_VD_IMAGE_READ_ONLY, RT_SRC_POS,
+                                             N_("Failed to open image '%s' for writing due to wrong permissions"),
+                                             pszName);
+                    break;
+                }
+            }
+            else
+            {
+               rc = PDMDrvHlpVMSetError(pDrvIns, rc, RT_SRC_POS,
+                                        N_("Failed to open image '%s' in %s mode"), pszName,
+                                        (uOpenFlags & VD_OPEN_FLAGS_READONLY) ? "read-only" : "read-write");
+               break;
+            }
+
+            MMR3HeapFree(pszName);
+            pszName = NULL;
+            MMR3HeapFree(pszFormat);
+            pszFormat = NULL;
+
+            /* next */
+            iLevel--;
+            iImageIdx++;
+            pCurNode = CFGMR3GetParent(pCurNode);
+        }
+
+        LogRel(("VD: Opening the disk took %lld ns\n", RTTimeNanoTS() - tsStart));
+
+        /* Open the cache image if set. */
+        if (   RT_SUCCESS(rc)
+            && RT_VALID_PTR(pszCachePath))
+        {
+            /* Insert the custom I/O interface only if we're told to use new IO.
+             * Since the I/O interface is per image we could make this more
+             * flexible in the future if we want to. */
+            if (fUseNewIo)
+            {
+#ifdef VBOX_WITH_PDM_ASYNC_COMPLETION
+                pThis->VDIfIoCache.pfnOpen       = drvvdAsyncIOOpen;
+                pThis->VDIfIoCache.pfnClose      = drvvdAsyncIOClose;
+                pThis->VDIfIoCache.pfnGetSize    = drvvdAsyncIOGetSize;
+                pThis->VDIfIoCache.pfnSetSize    = drvvdAsyncIOSetSize;
+                pThis->VDIfIoCache.pfnReadSync   = drvvdAsyncIOReadSync;
+                pThis->VDIfIoCache.pfnWriteSync  = drvvdAsyncIOWriteSync;
+                pThis->VDIfIoCache.pfnFlushSync  = drvvdAsyncIOFlushSync;
+                pThis->VDIfIoCache.pfnReadAsync  = drvvdAsyncIOReadAsync;
+                pThis->VDIfIoCache.pfnWriteAsync = drvvdAsyncIOWriteAsync;
+                pThis->VDIfIoCache.pfnFlushAsync = drvvdAsyncIOFlushAsync;
+#else /* !VBOX_WITH_PDM_ASYNC_COMPLETION */
+                rc = PDMDrvHlpVMSetError(pDrvIns, VERR_PDM_DRVINS_UNKNOWN_CFG_VALUES,
+                                         RT_SRC_POS, N_("DrvVD: Configuration error: Async Completion Framework not compiled in"));
+#endif /* !VBOX_WITH_PDM_ASYNC_COMPLETION */
+                if (RT_SUCCESS(rc))
+                    rc = VDInterfaceAdd(&pThis->VDIfIoCache.Core, "DrvVD_IO", VDINTERFACETYPE_IO,
+                                        pThis, sizeof(VDINTERFACEIO), &pThis->pVDIfsCache);
+                AssertRC(rc);
+            }
+
+            rc = VDCacheOpen(pThis->pDisk, pszCacheFormat, pszCachePath, VD_OPEN_FLAGS_NORMAL, pThis->pVDIfsCache);
+            if (RT_FAILURE(rc))
+                rc = PDMDRV_SET_ERROR(pDrvIns, rc, N_("DrvVD: Could not open cache image"));
+        }
+
+        if (RT_VALID_PTR(pszCachePath))
+            MMR3HeapFree(pszCachePath);
+        if (RT_VALID_PTR(pszCacheFormat))
+            MMR3HeapFree(pszCacheFormat);
+
+        if (   RT_SUCCESS(rc)
+            && pThis->fMergePending
+            && (   pThis->uMergeSource == VD_LAST_IMAGE
+                || pThis->uMergeTarget == VD_LAST_IMAGE))
+        {
+            rc = PDMDRV_SET_ERROR(pDrvIns, VERR_PDM_DRIVER_INVALID_PROPERTIES,
+                                  N_("DrvVD: Configuration error: Inconsistent image merge data"));
+        }
+
+        /* Create the block cache if enabled. */
+        if (   fUseBlockCache
+            && !pThis->fShareable
+            && !fDiscard
+            && !pThis->pCfgCrypto /* Disk encryption disables the block cache for security reasons */
+            && RT_SUCCESS(rc))
+        {
+            /*
+             * We need a unique ID for the block cache (to identify the owner of data
+             * blocks in a saved state). UUIDs are not really suitable because
+             * there are image formats which don't support them. Furthermore it is
+             * possible that a new diff image was attached after a saved state
+             * which changes the UUID.
+             * However the device "name + device instance + LUN" triple the disk is
+             * attached to is always constant for saved states.
+             */
+            char *pszId = NULL;
+            uint32_t iInstance, iLUN;
+            const char *pcszController;
+
+            rc = pThis->pDrvMediaPort->pfnQueryDeviceLocation(pThis->pDrvMediaPort, &pcszController,
+                                                              &iInstance, &iLUN);
+            if (RT_FAILURE(rc))
                 rc = PDMDRV_SET_ERROR(pDrvIns, VERR_PDM_DRIVER_INVALID_PROPERTIES,
-                                      N_("DrvVD: Out of memory when creating block cache"));
+                                      N_("DrvVD: Configuration error: Could not query device data"));
+            else
+            {
+                int cbStr = RTStrAPrintf(&pszId, "%s-%d-%d", pcszController, iInstance, iLUN);
+
+                if (cbStr > 0)
+                {
+                    rc = PDMDrvHlpBlkCacheRetain(pDrvIns, &pThis->pBlkCache,
+                                                 drvvdBlkCacheXferComplete,
+                                                 drvvdBlkCacheXferEnqueue,
+                                                 drvvdBlkCacheXferEnqueueDiscard,
+                                                 pszId);
+                    if (rc == VERR_NOT_SUPPORTED)
+                    {
+                        LogRel(("VD: Block cache is not supported\n"));
+                        rc = VINF_SUCCESS;
+                    }
+                    else
+                        AssertRC(rc);
+
+                    RTStrFree(pszId);
+                }
+                else
+                    rc = PDMDRV_SET_ERROR(pDrvIns, VERR_PDM_DRIVER_INVALID_PROPERTIES,
+                                          N_("DrvVD: Out of memory when creating block cache"));
+            }
         }
-    }
-
-    if (RT_SUCCESS(rc))
-        rc = drvvdSetupFilters(pThis, pCfg);
-
-    /*
-     * Register a load-done callback so we can undo TempReadOnly config before
-     * we get to drvvdResume.  Autoamtically deregistered upon destruction.
-     */
-    if (RT_SUCCESS(rc))
-        rc = PDMDrvHlpSSMRegisterEx(pDrvIns, 0 /* version */, 0 /* cbGuess */,
-                                    NULL /*pfnLivePrep*/, NULL /*pfnLiveExec*/, NULL /*pfnLiveVote*/,
-                                    NULL /*pfnSavePrep*/, NULL /*pfnSaveExec*/, NULL /*pfnSaveDone*/,
-                                    NULL /*pfnDonePrep*/, NULL /*pfnLoadExec*/, drvvdLoadDone);
-
-    /* Setup the boot acceleration stuff if enabled. */
-    if (RT_SUCCESS(rc) && pThis->fBootAccelEnabled)
-    {
-        pThis->cbDisk = VDGetSize(pThis->pDisk, VD_LAST_IMAGE);
-        Assert(pThis->cbDisk > 0);
-        pThis->pbData = (uint8_t *)RTMemAllocZ(pThis->cbBootAccelBuffer);
-        if (pThis->pbData)
+
+        if (RT_SUCCESS(rc))
+            rc = drvvdSetupFilters(pThis, pCfg);
+
+        /*
+         * Register a load-done callback so we can undo TempReadOnly config before
+         * we get to drvvdResume.  Autoamtically deregistered upon destruction.
+         */
+        if (RT_SUCCESS(rc))
+            rc = PDMDrvHlpSSMRegisterEx(pDrvIns, 0 /* version */, 0 /* cbGuess */,
+                                        NULL /*pfnLivePrep*/, NULL /*pfnLiveExec*/, NULL /*pfnLiveVote*/,
+                                        NULL /*pfnSavePrep*/, NULL /*pfnSaveExec*/, NULL /*pfnSaveDone*/,
+                                        NULL /*pfnDonePrep*/, NULL /*pfnLoadExec*/, drvvdLoadDone);
+
+        /* Setup the boot acceleration stuff if enabled. */
+        if (RT_SUCCESS(rc) && pThis->fBootAccelEnabled)
         {
-            pThis->fBootAccelActive = true;
-            pThis->offDisk          = 0;
-            pThis->cbDataValid      = 0;
-            LogRel(("VD: Boot acceleration enabled\n"));
+            pThis->cbDisk = VDGetSize(pThis->pDisk, VD_LAST_IMAGE);
+            Assert(pThis->cbDisk > 0);
+            pThis->pbData = (uint8_t *)RTMemAllocZ(pThis->cbBootAccelBuffer);
+            if (pThis->pbData)
+            {
+                pThis->fBootAccelActive = true;
+                pThis->offDisk          = 0;
+                pThis->cbDataValid      = 0;
+                LogRel(("VD: Boot acceleration enabled\n"));
+            }
+            else
+                LogRel(("VD: Boot acceleration, out of memory, disabled\n"));
         }
-        else
-            LogRel(("VD: Boot acceleration, out of memory, disabled\n"));
-    }
+
+        if (   RTUuidIsNull(&pThis->Uuid)
+            && pThis->enmType == PDMMEDIATYPE_HARD_DISK)
+            rc = VDGetUuid(pThis->pDisk, 0, &pThis->Uuid);
+
+        /*
+         * Automatically upgrade the floppy drive if the specified one is too
+         * small to represent the whole boot time image. (We cannot do this later
+         * since the BIOS (and others) gets the info via CMOS.)
+         *
+         * This trick should make 2.88 images as well as the fake 15.6 and 63.5 MB
+         * images despite the hardcoded default 1.44 drive.
+         */
+        if (   PDMMEDIATYPE_IS_FLOPPY(pThis->enmType)
+            && pThis->pDisk)
+        {
+            uint64_t     const cbFloppyImg = VDGetSize(pThis->pDisk, VD_LAST_IMAGE);
+            PDMMEDIATYPE const enmCfgType  = pThis->enmType;
+            switch (enmCfgType)
+            {
+                default:
+                    AssertFailed();
+                case PDMMEDIATYPE_FLOPPY_360:
+                    if (cbFloppyImg > 40 * 2 * 9 * 512)
+                        pThis->enmType = PDMMEDIATYPE_FLOPPY_720;
+                    /* fall thru */
+                case PDMMEDIATYPE_FLOPPY_720:
+                    if (cbFloppyImg > 80 * 2 * 14 * 512)
+                        pThis->enmType = PDMMEDIATYPE_FLOPPY_1_20;
+                    /* fall thru */
+                case PDMMEDIATYPE_FLOPPY_1_20:
+                    if (cbFloppyImg > 80 * 2 * 20 * 512)
+                        pThis->enmType = PDMMEDIATYPE_FLOPPY_1_44;
+                    /* fall thru */
+                case PDMMEDIATYPE_FLOPPY_1_44:
+                    if (cbFloppyImg > 80 * 2 * 24 * 512)
+                        pThis->enmType = PDMMEDIATYPE_FLOPPY_2_88;
+                    /* fall thru */
+                case PDMMEDIATYPE_FLOPPY_2_88:
+                    if (cbFloppyImg > 80 * 2 * 48 * 512)
+                        pThis->enmType = PDMMEDIATYPE_FLOPPY_FAKE_15_6;
+                    /* fall thru */
+                case PDMMEDIATYPE_FLOPPY_FAKE_15_6:
+                    if (cbFloppyImg > 255 * 2 * 63 * 512)
+                        pThis->enmType = PDMMEDIATYPE_FLOPPY_FAKE_63_5;
+                case PDMMEDIATYPE_FLOPPY_FAKE_63_5:
+                    if (cbFloppyImg > 255 * 2 * 255 * 512)
+                        LogRel(("Warning: Floppy image is larger that 63.5 MB! (%llu bytes)\n", cbFloppyImg));
+                    break;
+            }
+            if (pThis->enmType != enmCfgType)
+                LogRel(("DrvVD: Automatically upgraded floppy drive from %s to %s to better support the %u byte image\n",
+                        drvvdGetTypeName(enmCfgType), drvvdGetTypeName(pThis->enmType), cbFloppyImg));
+        }
+    } /* !fEmptyDrive */
 
     if (RT_FAILURE(rc))
Index: trunk/src/VBox/Devices/build/VBoxDD.cpp
===================================================================
--- trunk/src/VBox/Devices/build/VBoxDD.cpp	(revision 59247)
+++ trunk/src/VBox/Devices/build/VBoxDD.cpp	(revision 59248)
@@ -222,7 +222,4 @@
     if (RT_FAILURE(rc))
         return rc;
-    rc = pCallbacks->pfnRegister(pCallbacks, &g_DrvBlock);
-    if (RT_FAILURE(rc))
-        return rc;
     rc = pCallbacks->pfnRegister(pCallbacks, &g_DrvVD);
     if (RT_FAILURE(rc))
@@ -238,10 +235,4 @@
         return rc;
 #endif
-    rc = pCallbacks->pfnRegister(pCallbacks, &g_DrvMediaISO);
-    if (RT_FAILURE(rc))
-        return rc;
-    rc = pCallbacks->pfnRegister(pCallbacks, &g_DrvRawImage);
-    if (RT_FAILURE(rc))
-        return rc;
     rc = pCallbacks->pfnRegister(pCallbacks, &g_DrvNAT);
     if (RT_FAILURE(rc))
Index: trunk/src/VBox/Devices/build/VBoxDD.h
===================================================================
--- trunk/src/VBox/Devices/build/VBoxDD.h	(revision 59247)
+++ trunk/src/VBox/Devices/build/VBoxDD.h	(revision 59248)
@@ -92,11 +92,8 @@
 extern const PDMDRVREG g_DrvMouseQueue;
 extern const PDMDRVREG g_DrvKeyboardQueue;
-extern const PDMDRVREG g_DrvBlock;
 extern const PDMDRVREG g_DrvVBoxHDD;
 extern const PDMDRVREG g_DrvVD;
 extern const PDMDRVREG g_DrvHostDVD;
 extern const PDMDRVREG g_DrvHostFloppy;
-extern const PDMDRVREG g_DrvMediaISO;
-extern const PDMDRVREG g_DrvRawImage;
 extern const PDMDRVREG g_DrvISCSI;
 extern const PDMDRVREG g_DrvISCSITransportTcp;
Index: trunk/src/VBox/Devices/testcase/tstDeviceStructSizeRC.cpp
===================================================================
--- trunk/src/VBox/Devices/testcase/tstDeviceStructSizeRC.cpp	(revision 59247)
+++ trunk/src/VBox/Devices/testcase/tstDeviceStructSizeRC.cpp	(revision 59248)
@@ -892,6 +892,5 @@
     GEN_CHECK_OFF(ATADevState, cErrors);
     GEN_CHECK_OFF(ATADevState, pDrvBase);
-    GEN_CHECK_OFF(ATADevState, pDrvBlock);
-    GEN_CHECK_OFF(ATADevState, pDrvBlockBios);
+    GEN_CHECK_OFF(ATADevState, pDrvMedia);
     GEN_CHECK_OFF(ATADevState, pDrvMount);
     GEN_CHECK_OFF(ATADevState, IBase);
@@ -1349,7 +1348,6 @@
     GEN_CHECK_OFF(AHCIPort, u32CurrentCommandSlot);
     GEN_CHECK_OFF(AHCIPort, pDrvBase);
-    GEN_CHECK_OFF(AHCIPort, pDrvBlock);
-    GEN_CHECK_OFF(AHCIPort, pDrvBlockAsync);
-    GEN_CHECK_OFF(AHCIPort, pDrvBlockBios);
+    GEN_CHECK_OFF(AHCIPort, pDrvMedia);
+    GEN_CHECK_OFF(AHCIPort, pDrvMediaAsync);
     GEN_CHECK_OFF(AHCIPort, pDrvMount);
     GEN_CHECK_OFF(AHCIPort, IBase);
Index: trunk/src/VBox/Main/src-client/ConsoleImpl2.cpp
===================================================================
--- trunk/src/VBox/Main/src-client/ConsoleImpl2.cpp	(revision 59247)
+++ trunk/src/VBox/Main/src-client/ConsoleImpl2.cpp	(revision 59248)
@@ -4294,5 +4294,13 @@
         else
         {
-            InsertConfigString(pLunL0, "Driver", "Block");
+#if 0 /* Enable for I/O debugging */
+            InsertConfigNode(pLunL0, "AttachedDriver", &pLunL0);
+            InsertConfigString(pLunL0, "Driver", "DiskIntegrity");
+            InsertConfigNode(pLunL0, "Config", &pCfg);
+            InsertConfigInteger(pCfg, "CheckConsistency", 0);
+            InsertConfigInteger(pCfg, "CheckDoubleCompletions", 1);
+#endif
+
+            InsertConfigString(pLunL0, "Driver", "VD");
             InsertConfigNode(pLunL0, "Config", &pCfg);
             switch (enmType)
@@ -4350,16 +4358,4 @@
                 /* Index of last image */
                 uImage--;
-
-#if 0 /* Enable for I/O debugging */
-                InsertConfigNode(pLunL0, "AttachedDriver", &pLunL0);
-                InsertConfigString(pLunL0, "Driver", "DiskIntegrity");
-                InsertConfigNode(pLunL0, "Config", &pCfg);
-                InsertConfigInteger(pCfg, "CheckConsistency", 0);
-                InsertConfigInteger(pCfg, "CheckDoubleCompletions", 1);
-#endif
-
-                InsertConfigNode(pLunL0, "AttachedDriver", &pLunL1);
-                InsertConfigString(pLunL1, "Driver", "VD");
-                InsertConfigNode(pLunL1, "Config", &pCfg);
 
 # ifdef VBOX_WITH_EXTPACK
@@ -4436,17 +4432,4 @@
                 }
 
-                switch (enmType)
-                {
-                    case DeviceType_DVD:
-                        InsertConfigString(pCfg, "Type", "DVD");
-                        break;
-                    case DeviceType_Floppy:
-                        InsertConfigString(pCfg, "Type", "Floppy");
-                        break;
-                    case DeviceType_HardDisk:
-                    default:
-                        InsertConfigString(pCfg, "Type", "HardDisk");
-                }
-
                 if (pcszBwGroup)
                     InsertConfigString(pCfg, "BwGroup", pcszBwGroup);
@@ -4500,4 +4483,11 @@
                 if (fEncrypted)
                     m_cDisksEncrypted++;
+            }
+            else
+            {
+                /* Set empty drive flag for DVD or floppy without media. */
+                if (   enmType == DeviceType_DVD
+                    || enmType == DeviceType_Floppy)
+                    InsertConfigInteger(pCfg, "EmptyDrive", 1);
             }
         }
