Index: trunk/src/VBox/Main/src-client/ConsoleImpl.cpp
===================================================================
--- trunk/src/VBox/Main/src-client/ConsoleImpl.cpp	(revision 37661)
+++ trunk/src/VBox/Main/src-client/ConsoleImpl.cpp	(revision 37687)
@@ -3663,5 +3663,5 @@
  * Attach a new storage device to the VM.
  *
- * @param aMediumAttachment The medium attachmentwhich is added.
+ * @param aMediumAttachment The medium attachment which is added.
  * @param pVM               Safe VM handle.
  *
@@ -3908,5 +3908,5 @@
  * Attach a new storage device to the VM.
  *
- * @param aMediumAttachment The medium attachmentwhich is added.
+ * @param aMediumAttachment The medium attachment which is added.
  * @param pVM               Safe VM handle.
  *
@@ -4113,9 +4113,13 @@
     if (pLunL0)
     {
-            rc = PDMR3DeviceDetach(pVM, pcszDevice, uInstance, uLUN, 0);
-            if (rc == VERR_PDM_NO_DRIVER_ATTACHED_TO_LUN)
-                rc = VINF_SUCCESS;
-            AssertRCReturn(rc, rc);
-            CFGMR3RemoveNode(pLunL0);
+        rc = PDMR3DeviceDetach(pVM, pcszDevice, uInstance, uLUN, 0);
+        if (rc == VERR_PDM_NO_DRIVER_ATTACHED_TO_LUN)
+            rc = VINF_SUCCESS;
+        AssertRCReturn(rc, rc);
+        CFGMR3RemoveNode(pLunL0);
+
+        Utf8Str devicePath = Utf8StrFmt("%s/%u/LUN#%u", pcszDevice, uInstance, uLUN);
+        pConsole->mapMediumAttachments.erase(devicePath);
+
     }
     else
@@ -9466,4 +9470,15 @@
      * (The size of the LED array is iLastLUN - iFirstLUN + 1.) */
     RTUINT              iLastLUN;
+    /** Pointer to the driver instance. */
+    PPDMDRVINS          pDrvIns;
+    /** The Media Notify interface. */
+    PDMIMEDIANOTIFY     IMediaNotify;
+    /** Map for translating PDM storage controller/LUN information to
+     * IMediumAttachment references. */
+    Console::MediumAttachmentMap *pmapMediumAttachments;
+    /** Device name+instance for mapping */
+    char                *pszDeviceInstance;
+    /** Pointer to the Console object, for driver triggered activities. */
+    Console             *pConsole;
 } DRVMAINSTATUS, *PDRVMAINSTATUS;
 
@@ -9480,5 +9495,5 @@
 DECLCALLBACK(void) Console::drvStatus_UnitChanged(PPDMILEDCONNECTORS pInterface, unsigned iLUN)
 {
-    PDRVMAINSTATUS pData = (PDRVMAINSTATUS)(void *)pInterface;
+    PDRVMAINSTATUS pData = (PDRVMAINSTATUS)((uintptr_t)pInterface - RT_OFFSETOF(DRVMAINSTATUS, ILedConnectors));
     if (iLUN >= pData->iFirstLUN && iLUN <= pData->iLastLUN)
     {
@@ -9494,4 +9509,48 @@
 
 /**
+ * Notification about a medium eject.
+ *
+ * @returns VBox status.
+ * @param   pInterface      Pointer to the interface structure containing the called function pointer.
+ * @param   uLUN            The unit number.
+ */
+DECLCALLBACK(int) Console::drvStatus_MediumEjected(PPDMIMEDIANOTIFY pInterface, unsigned uLUN)
+{
+    PDRVMAINSTATUS pData = (PDRVMAINSTATUS)((uintptr_t)pInterface - RT_OFFSETOF(DRVMAINSTATUS, IMediaNotify));
+    PPDMDRVINS pDrvIns = pData->pDrvIns;
+    LogFunc(("uLUN=%d\n", uLUN));
+    if (pData->pmapMediumAttachments)
+    {
+        AutoWriteLock alock(pData->pConsole COMMA_LOCKVAL_SRC_POS);
+
+        ComPtr<IMediumAttachment> pMediumAtt;
+        Utf8Str devicePath = Utf8StrFmt("%s/LUN#%u", pData->pszDeviceInstance, uLUN);
+        Console::MediumAttachmentMap::const_iterator end = pData->pmapMediumAttachments->end();
+        Console::MediumAttachmentMap::const_iterator it = pData->pmapMediumAttachments->find(devicePath);
+        if (it != end)
+            pMediumAtt = it->second;
+        Assert(!pMediumAtt.isNull());
+        if (!pMediumAtt.isNull())
+        {
+            alock.release();
+
+            ComPtr<IMediumAttachment> pNewMediumAtt;
+            HRESULT rc = pData->pConsole->mControl->EjectMedium(pMediumAtt, pNewMediumAtt.asOutParam());
+            if (SUCCEEDED(rc))
+                fireMediumChangedEvent(pData->pConsole->mEventSource, pNewMediumAtt);
+
+            alock.acquire();
+            if (pNewMediumAtt != pMediumAtt)
+            {
+                pData->pmapMediumAttachments->erase(devicePath);
+                pData->pmapMediumAttachments->insert(std::make_pair(devicePath, pNewMediumAtt));
+            }
+        }
+    }
+    return VINF_SUCCESS;
+}
+
+
+/**
  * @interface_method_impl{PDMIBASE,pfnQueryInterface}
  */
@@ -9502,4 +9561,5 @@
     PDMIBASE_RETURN_INTERFACE(pszIID, PDMIBASE, &pDrvIns->IBase);
     PDMIBASE_RETURN_INTERFACE(pszIID, PDMILEDCONNECTORS, &pThis->ILedConnectors);
+    PDMIBASE_RETURN_INTERFACE(pszIID, PDMIMEDIANOTIFY, &pThis->IMediaNotify);
     return NULL;
 }
@@ -9541,5 +9601,5 @@
      * Validate configuration.
      */
-    if (!CFGMR3AreValuesValid(pCfg, "papLeds\0First\0Last\0"))
+    if (!CFGMR3AreValuesValid(pCfg, "papLeds\0pmapMediumAttachments\0DeviceInstance\0pConsole\0First\0Last\0"))
         return VERR_PDM_DRVINS_UNKNOWN_CFG_VALUES;
     AssertMsgReturn(PDMDrvHlpNoAttach(pDrvIns) == VERR_PDM_NO_ATTACHED_DRIVER,
@@ -9552,4 +9612,7 @@
     pDrvIns->IBase.pfnQueryInterface        = Console::drvStatus_QueryInterface;
     pData->ILedConnectors.pfnUnitChanged    = Console::drvStatus_UnitChanged;
+    pData->IMediaNotify.pfnEjected          = Console::drvStatus_MediumEjected;
+    pData->pDrvIns                          = pDrvIns;
+    pData->pszDeviceInstance                = NULL;
 
     /*
@@ -9561,4 +9624,26 @@
         AssertMsgFailed(("Configuration error: Failed to query the \"papLeds\" value! rc=%Rrc\n", rc));
         return rc;
+    }
+
+    rc = CFGMR3QueryPtrDef(pCfg, "pmapMediumAttachments", (void **)&pData->pmapMediumAttachments, NULL);
+    if (RT_FAILURE(rc))
+    {
+        AssertMsgFailed(("Configuration error: Failed to query the \"pmapMediumAttachments\" value! rc=%Rrc\n", rc));
+        return rc;
+    }
+    if (pData->pmapMediumAttachments)
+    {
+        rc = CFGMR3QueryStringAlloc(pCfg, "DeviceInstance", &pData->pszDeviceInstance);
+        if (RT_FAILURE(rc))
+        {
+            AssertMsgFailed(("Configuration error: Failed to query the \"DeviceInstance\" value! rc=%Rrc\n", rc));
+            return rc;
+        }
+        rc = CFGMR3QueryPtr(pCfg, "pConsole", (void **)&pData->pConsole);
+        if (RT_FAILURE(rc))
+        {
+            AssertMsgFailed(("Configuration error: Failed to query the \"pConsole\" value! rc=%Rrc\n", rc));
+            return rc;
+        }
     }
 
Index: trunk/src/VBox/Main/src-client/ConsoleImpl2.cpp
===================================================================
--- trunk/src/VBox/Main/src-client/ConsoleImpl2.cpp	(revision 37661)
+++ trunk/src/VBox/Main/src-client/ConsoleImpl2.cpp	(revision 37687)
@@ -573,4 +573,28 @@
 #endif
 
+
+void Console::attachStatusDriver(PCFGMNODE pCtlInst, PPDMLED *papLeds,
+                                 uint64_t uFirst, uint64_t uLast,
+                                 Console::MediumAttachmentMap *pmapMediumAttachments,
+                                 const char *pcszDevice, unsigned uInstance)
+{
+    PCFGMNODE pLunL0, pCfg;
+    InsertConfigNode(pCtlInst,  "LUN#999", &pLunL0);
+    InsertConfigString(pLunL0,  "Driver",               "MainStatus");
+    InsertConfigNode(pLunL0,    "Config", &pCfg);
+    InsertConfigInteger(pCfg,   "papLeds", (uintptr_t)papLeds);
+    if (pmapMediumAttachments)
+    {
+        InsertConfigInteger(pCfg,   "pmapMediumAttachments", (uintptr_t)pmapMediumAttachments);
+        InsertConfigInteger(pCfg,   "pConsole", (uintptr_t)this);
+        AssertPtr(pcszDevice);
+        Utf8Str deviceInstance = Utf8StrFmt("%s/%u", pcszDevice, uInstance);
+        InsertConfigString(pCfg,    "DeviceInstance", deviceInstance.c_str());
+    }
+    InsertConfigInteger(pCfg,   "First",    uFirst);
+    InsertConfigInteger(pCfg,   "Last",     uLast);
+}
+
+
 /**
  *  Construct the VM configuration tree (CFGM).
@@ -1482,11 +1506,6 @@
 
                     /* Attach the status driver */
-                    InsertConfigNode(pCtlInst, "LUN#999", &pLunL0);
-                    InsertConfigString(pLunL0, "Driver",               "MainStatus");
-                    InsertConfigNode(pLunL0,   "Config", &pCfg);
-                    InsertConfigInteger(pCfg,  "papLeds", (uintptr_t)&mapStorageLeds[iLedScsi]);
-                    InsertConfigInteger(pCfg,  "First",    0);
                     Assert(cLedScsi >= 16);
-                    InsertConfigInteger(pCfg,  "Last",     15);
+                    attachStatusDriver(pCtlInst, &mapStorageLeds[iLedScsi], 0, 15, &mapMediumAttachments, pszCtrlDev, ulInstance);
                     paLedDevType = &maStorageDevType[iLedScsi];
                     break;
@@ -1500,11 +1519,6 @@
 
                     /* Attach the status driver */
-                    InsertConfigNode(pCtlInst, "LUN#999", &pLunL0);
-                    InsertConfigString(pLunL0, "Driver",               "MainStatus");
-                    InsertConfigNode(pLunL0,   "Config", &pCfg);
-                    InsertConfigInteger(pCfg,  "papLeds", (uintptr_t)&mapStorageLeds[iLedScsi]);
-                    InsertConfigInteger(pCfg,  "First",    0);
                     Assert(cLedScsi >= 16);
-                    InsertConfigInteger(pCfg,  "Last",     15);
+                    attachStatusDriver(pCtlInst, &mapStorageLeds[iLedScsi], 0, 15, &mapMediumAttachments, pszCtrlDev, ulInstance);
                     paLedDevType = &maStorageDevType[iLedScsi];
                     break;
@@ -1544,11 +1558,6 @@
 
                     /* Attach the status driver */
-                    InsertConfigNode(pCtlInst, "LUN#999", &pLunL0);
-                    InsertConfigString(pLunL0, "Driver",               "MainStatus");
-                    InsertConfigNode(pLunL0,   "Config", &pCfg);
                     AssertRelease(cPorts <= cLedSata);
-                    InsertConfigInteger(pCfg,  "papLeds", (uintptr_t)&mapStorageLeds[iLedSata]);
-                    InsertConfigInteger(pCfg,  "First",    0);
-                    InsertConfigInteger(pCfg,  "Last",     cPorts - 1);
+                    attachStatusDriver(pCtlInst, &mapStorageLeds[iLedSata], 0, cPorts - 1, &mapMediumAttachments, pszCtrlDev, ulInstance);
                     paLedDevType = &maStorageDevType[iLedSata];
                     break;
@@ -1564,13 +1573,7 @@
                     hrc = BusMgr->assignPciDevice("piix3ide", pCtlInst);                               H();
                     InsertConfigString(pCfg,   "Type", controllerString(enmCtrlType));
-
                     /* Attach the status driver */
-                    InsertConfigNode(pCtlInst,    "LUN#999", &pLunL0);
-                    InsertConfigString(pLunL0, "Driver",               "MainStatus");
-                    InsertConfigNode(pLunL0,   "Config", &pCfg);
-                    InsertConfigInteger(pCfg,  "papLeds", (uintptr_t)&mapStorageLeds[iLedIde]);
-                    InsertConfigInteger(pCfg,  "First",    0);
                     Assert(cLedIde >= 4);
-                    InsertConfigInteger(pCfg,  "Last",     3);
+                    attachStatusDriver(pCtlInst, &mapStorageLeds[iLedIde], 0, 3, &mapMediumAttachments, pszCtrlDev, ulInstance);
                     paLedDevType = &maStorageDevType[iLedIde];
 
@@ -1594,11 +1597,6 @@
 
                     /* Attach the status driver */
-                    InsertConfigNode(pCtlInst, "LUN#999", &pLunL0);
-                    InsertConfigString(pLunL0, "Driver",               "MainStatus");
-                    InsertConfigNode(pLunL0,   "Config", &pCfg);
-                    InsertConfigInteger(pCfg,  "papLeds", (uintptr_t)&mapStorageLeds[iLedFloppy]);
-                    InsertConfigInteger(pCfg,  "First",    0);
-                    Assert(cLedFloppy >= 1);
-                    InsertConfigInteger(pCfg,  "Last",     0);
+                    Assert(cLedFloppy >= 2);
+                    attachStatusDriver(pCtlInst, &mapStorageLeds[iLedFloppy], 0, 1, &mapMediumAttachments, pszCtrlDev, ulInstance);
                     paLedDevType = &maStorageDevType[iLedFloppy];
                     break;
@@ -1613,11 +1611,6 @@
 
                     /* Attach the status driver */
-                    InsertConfigNode(pCtlInst, "LUN#999", &pLunL0);
-                    InsertConfigString(pLunL0, "Driver",               "MainStatus");
-                    InsertConfigNode(pLunL0,   "Config", &pCfg);
-                    InsertConfigInteger(pCfg,  "papLeds", (uintptr_t)&mapStorageLeds[iLedSas]);
-                    InsertConfigInteger(pCfg,  "First",    0);
                     Assert(cLedSas >= 8);
-                    InsertConfigInteger(pCfg,  "Last",     7);
+                    attachStatusDriver(pCtlInst, &mapStorageLeds[iLedSas], 0, 7, &mapMediumAttachments, pszCtrlDev, ulInstance);
                     paLedDevType = &maStorageDevType[iLedSas];
                     break;
@@ -1640,4 +1633,5 @@
             for (size_t j = 0; j < atts.size(); ++j)
             {
+                IMediumAttachment *pMediumAtt = atts[j];
                 rc = configMediumAttachment(pCtlInst,
                                             pszCtrlDev,
@@ -1649,5 +1643,5 @@
                                             0 /* uMergeSource */,
                                             0 /* uMergeTarget */,
-                                            atts[j],
+                                            pMediumAtt,
                                             mMachineState,
                                             NULL /* phrc */,
@@ -1844,8 +1838,5 @@
              * Attach the status driver.
              */
-            InsertConfigNode(pInst,    "LUN#999", &pLunL0);
-            InsertConfigString(pLunL0, "Driver",               "MainStatus");
-            InsertConfigNode(pLunL0,   "Config", &pCfg);
-            InsertConfigInteger(pCfg,  "papLeds", (uintptr_t)&mapNetworkLeds[ulInstance]);
+            attachStatusDriver(pInst, &mapNetworkLeds[ulInstance], 0, 0, NULL, NULL, 0);
 
             /*
@@ -2015,10 +2006,5 @@
          * Attach the status driver.
          */
-        InsertConfigNode(pInst,    "LUN#999", &pLunL0);
-        InsertConfigString(pLunL0, "Driver",               "MainStatus");
-        InsertConfigNode(pLunL0,   "Config", &pCfg);
-        InsertConfigInteger(pCfg,  "papLeds", (uintptr_t)&mapSharedFolderLed);
-        InsertConfigInteger(pCfg,  "First",    0);
-        InsertConfigInteger(pCfg,  "Last",     0);
+        attachStatusDriver(pInst, &mapSharedFolderLed, 0, 0, NULL, NULL, 0);
 
         /*
@@ -2188,10 +2174,5 @@
                  * Attach the status driver.
                  */
-                InsertConfigNode(pInst,    "LUN#999", &pLunL0);
-                InsertConfigString(pLunL0, "Driver",               "MainStatus");
-                InsertConfigNode(pLunL0,   "Config", &pCfg);
-                InsertConfigInteger(pCfg,  "papLeds", (uintptr_t)&mapUSBLed[0]);
-                InsertConfigInteger(pCfg,  "First",    0);
-                InsertConfigInteger(pCfg,  "Last",     0);
+                attachStatusDriver(pInst, &mapUSBLed[0], 0, 0, NULL, NULL, 0);
 
 #ifdef VBOX_WITH_EHCI
@@ -2226,10 +2207,5 @@
                          * Attach the status driver.
                          */
-                        InsertConfigNode(pInst,    "LUN#999", &pLunL0);
-                        InsertConfigString(pLunL0, "Driver",               "MainStatus");
-                        InsertConfigNode(pLunL0,   "Config", &pCfg);
-                        InsertConfigInteger(pCfg,  "papLeds", (uintptr_t)&mapUSBLed[1]);
-                        InsertConfigInteger(pCfg,  "First",    0);
-                        InsertConfigInteger(pCfg,  "Last",     0);
+                        attachStatusDriver(pInst, &mapUSBLed[1], 0, 0, NULL, NULL, 0);
                     }
 # ifdef VBOX_WITH_EXTPACK
@@ -2904,4 +2880,7 @@
 
         InsertConfigNode(pCtlInst, Utf8StrFmt("LUN#%u", uLUN).c_str(), &pLunL0);
+
+        Utf8Str devicePath = Utf8StrFmt("%s/%u/LUN#%u", pcszDevice, uInstance, uLUN);
+        mapMediumAttachments[devicePath] = pMediumAtt;
 
         /* SCSI has a another driver between device and block. */
@@ -3113,15 +3092,15 @@
 
         rc = configMedium(pLunL0,
-                        !!fPassthrough,
-                        lType,
-                        fUseHostIOCache,
-                        fBuiltinIoCache,
-                        fSetupMerge,
-                        uMergeSource,
-                        uMergeTarget,
-                        strBwGroup.isEmpty() ? NULL : Utf8Str(strBwGroup).c_str(),
-                        pMedium,
-                        aMachineState,
-                        phrc);
+                          !!fPassthrough,
+                          lType,
+                          fUseHostIOCache,
+                          fBuiltinIoCache,
+                          fSetupMerge,
+                          uMergeSource,
+                          uMergeTarget,
+                          strBwGroup.isEmpty() ? NULL : Utf8Str(strBwGroup).c_str(),
+                          pMedium,
+                          aMachineState,
+                          phrc);
         if (RT_FAILURE(rc))
             return rc;
