Index: trunk/src/VBox/Devices/Audio/DevIchAc97.cpp
===================================================================
--- trunk/src/VBox/Devices/Audio/DevIchAc97.cpp	(revision 59343)
+++ trunk/src/VBox/Devices/Audio/DevIchAc97.cpp	(revision 59348)
@@ -315,6 +315,7 @@
     uint8_t                            uLUN;
     uint8_t                            Padding[5];
-    /** Audio connector interface to the underlying
-     *  host backend. */
+    /** Pointer to attached driver base interface. */
+    R3PTRTYPE(PPDMIBASE)               pDrvBase;
+    /** Audio connector interface to the underlying host backend. */
     R3PTRTYPE(PPDMIAUDIOCONNECTOR)     pConnector;
     /** Stream for line input. */
@@ -372,6 +373,4 @@
     uint8_t                 silence[128];
     int                     bup_flag;
-    /** Pointer to the attached audio driver. */
-    PPDMIBASE               pDrvBase;
     /** The base interface for LUN\#0. */
     PDMIBASE                IBase;
@@ -2191,8 +2190,4 @@
     PAC97STATE pThis = PDMINS_2_DATA(pDevIns, PAC97STATE);
 
-    AssertMsgReturn(fFlags & PDM_TACH_FLAGS_NOT_HOT_PLUG,
-                    ("AC'97 device does not support hotplugging\n"),
-                    VERR_INVALID_PARAMETER);
-
     /*
      * Attach driver.
@@ -2200,10 +2195,11 @@
     char *pszDesc = NULL;
     if (RTStrAPrintf(&pszDesc, "Audio driver port (AC'97) for LUN #%u", uLUN) <= 0)
-        AssertMsgReturn(pszDesc,
-                        ("Not enough memory for AC'97 driver port description of LUN #%u\n", uLUN),
-                        VERR_NO_MEMORY);
-
+        AssertReleaseMsgReturn(pszDesc,
+                               ("Not enough memory for AC'97 driver port description of LUN #%u\n", uLUN),
+                               VERR_NO_MEMORY);
+
+    PPDMIBASE pDrvBase;
     int rc = PDMDevHlpDriverAttach(pDevIns, uLUN,
-                                   &pThis->IBase, &pThis->pDrvBase, pszDesc);
+                                   &pThis->IBase, &pDrvBase, pszDesc);
     if (RT_SUCCESS(rc))
     {
@@ -2211,10 +2207,9 @@
         if (pDrv)
         {
-            pDrv->pConnector = PDMIBASE_QUERY_INTERFACE(pThis->pDrvBase, PDMIAUDIOCONNECTOR);
-            AssertMsg(pDrv->pConnector != NULL,
-                      ("Configuration error: LUN #%u has no host audio interface, rc=%Rrc\n",
-                      uLUN, rc));
+            pDrv->pDrvBase   = pDrvBase;
+            pDrv->pConnector = PDMIBASE_QUERY_INTERFACE(pDrvBase, PDMIAUDIOCONNECTOR);
+            AssertMsg(pDrv->pConnector != NULL, ("Configuration error: LUN #%u has no host audio interface, rc=%Rrc\n", uLUN, rc));
             pDrv->pAC97State = pThis;
-            pDrv->uLUN = uLUN;
+            pDrv->uLUN       = uLUN;
 
             /*
@@ -2241,5 +2236,10 @@
                         uLUN, pszDesc, rc));
 
-    RTStrFree(pszDesc);
+    if (RT_FAILURE(rc))
+    {
+        /* Only free this string on failure;
+         * must remain valid for the live of the driver instance. */
+        RTStrFree(pszDesc);
+    }
 
     LogFunc(("iLUN=%u, fFlags=0x%x, rc=%Rrc\n", uLUN, fFlags, rc));
@@ -2247,4 +2247,54 @@
 }
 
+static void ichac97Detach(PPDMDEVINS pDevIns, unsigned uLUN, uint32_t fFlags)
+{
+    LogFunc(("iLUN=%u, fFlags=0x%x\n", uLUN, fFlags));
+}
+
+static int ichac97Reattach(PAC97STATE pThis, PCFGMNODE pCfg, PAC97DRIVER pDrv, const char *pszDriver)
+{
+    AssertPtrReturn(pThis,     VERR_INVALID_POINTER);
+    AssertPtrReturn(pCfg,      VERR_INVALID_POINTER);
+    AssertPtrReturn(pDrv,      VERR_INVALID_POINTER);
+    AssertPtrReturn(pszDriver, VERR_INVALID_POINTER);
+
+    PVM pVM = PDMDevHlpGetVM(pThis->pDevInsR3);
+    PCFGMNODE pRoot = CFGMR3GetRoot(pVM);
+    PCFGMNODE pDev0 = CFGMR3GetChild(pRoot, "Devices/ichac97/0/");
+
+    /* Remove LUN branch. */
+    CFGMR3RemoveNode(CFGMR3GetChildF(pDev0, "LUN#%u/", pDrv->uLUN));
+
+    int rc = PDMDevHlpDriverDetach(pThis->pDevInsR3, PDMIBASE_2_PDMDRV(pDrv->pDrvBase), 0 /* fFlags */);
+    if (RT_FAILURE(rc))
+        return rc;
+
+#define RC_CHECK() if (RT_FAILURE(rc)) { AssertReleaseRC(rc); break; }
+
+    do
+    {
+        PCFGMNODE pLunL0;
+        rc = CFGMR3InsertNodeF(pDev0, &pLunL0, "LUN#%u/", pDrv->uLUN);  RC_CHECK();
+        rc = CFGMR3InsertString(pLunL0, "Driver",       "AUDIO");       RC_CHECK();
+        rc = CFGMR3InsertNode(pLunL0,   "Config/",       NULL);         RC_CHECK();
+
+        PCFGMNODE pLunL1, pLunL2;
+        rc = CFGMR3InsertNode  (pLunL0, "AttachedDriver/", &pLunL1);    RC_CHECK();
+        rc = CFGMR3InsertNode  (pLunL1,  "Config/",        &pLunL2);    RC_CHECK();
+        rc = CFGMR3InsertString(pLunL1,  "Driver",          pszDriver); RC_CHECK();
+
+        rc = CFGMR3InsertString(pLunL2, "AudioDriver", pszDriver);      RC_CHECK();
+
+    } while (0);
+
+    if (RT_SUCCESS(rc))
+        rc = ichac97Attach(pThis->pDevInsR3, pDrv->uLUN, 0 /* fFlags */);
+
+    LogFunc(("pThis=%p, uLUN=%u, pszDriver=%s, rc=%Rrc\n", pThis, pDrv->uLUN, pszDriver, rc));
+
+#undef RC_CHECK
+
+    return rc;
+}
 
 /**
@@ -2373,5 +2423,5 @@
     {
         LogFunc(("Trying to attach driver for LUN #%RU8 ...\n", uLUN));
-        rc = ichac97Attach(pDevIns, uLUN, PDM_TACH_FLAGS_NOT_HOT_PLUG);
+        rc = ichac97Attach(pDevIns, uLUN, 0 /* fFlags */);
         if (RT_FAILURE(rc))
         {
@@ -2450,11 +2500,8 @@
             if (cFailed == 3)
             {
-                LogRel(("AC97: Falling back to NULL driver (no sound audible)\n"));
+                LogRel(("AC97: Falling back to NULL backend (no sound audible)\n"));
 
                 ichac97Reset(pDevIns);
-
-                /* Was not able initialize *any* stream.
-                 * Select the NULL audio driver instead. */
-                pCon->pfnInitNull(pCon);
+                ichac97Reattach(pThis, pCfg, pDrv, "NullAudio");
 
                 PDMDevHlpVMSetRuntimeError(pDevIns, 0 /*fFlags*/, "HostAudioNotResponding",
@@ -2606,7 +2653,7 @@
     NULL,
     /* pfnAttach */
-    NULL,
+    ichac97Attach,
     /* pfnDetach */
-    NULL,
+    ichac97Detach,
     /* pfnQueryInterface. */
     NULL,
Index: trunk/src/VBox/Devices/Audio/DevIchHda.cpp
===================================================================
--- trunk/src/VBox/Devices/Audio/DevIchHda.cpp	(revision 59343)
+++ trunk/src/VBox/Devices/Audio/DevIchHda.cpp	(revision 59348)
@@ -658,6 +658,7 @@
     /** LUN to which this driver has been assigned. */
     uint8_t                            uLUN;
-    /** Audio connector interface to the underlying
-     *  host backend. */
+    /** Pointer to attached driver base interface. */
+    R3PTRTYPE(PPDMIBASE)               pDrvBase;
+    /** Audio connector interface to the underlying host backend. */
     R3PTRTYPE(PPDMIAUDIOCONNECTOR)     pConnector;
     /** Stream for line input. */
@@ -684,6 +685,4 @@
     /** Padding for alignment. */
     uint32_t                           u32Padding;
-    /** Pointer to the attached audio driver. */
-    R3PTRTYPE(PPDMIBASE)               pDrvBase;
     /** The base interface for LUN\#0. */
     PDMIBASE                           IBase;
@@ -4323,8 +4322,4 @@
     PHDASTATE pThis = PDMINS_2_DATA(pDevIns, PHDASTATE);
 
-    AssertMsgReturn(fFlags & PDM_TACH_FLAGS_NOT_HOT_PLUG,
-                    ("HDA device does not support hotplugging\n"),
-                    VERR_INVALID_PARAMETER);
-
     /*
      * Attach driver.
@@ -4332,10 +4327,11 @@
     char *pszDesc = NULL;
     if (RTStrAPrintf(&pszDesc, "Audio driver port (HDA) for LUN#%u", uLUN) <= 0)
-        AssertMsgReturn(pszDesc,
-                        ("Not enough memory for HDA driver port description of LUN #%u\n", uLUN),
-                        VERR_NO_MEMORY);
-
+        AssertReleaseMsgReturn(pszDesc,
+                               ("Not enough memory for HDA driver port description of LUN #%u\n", uLUN),
+                               VERR_NO_MEMORY);
+
+    PPDMIBASE pDrvBase;
     int rc = PDMDevHlpDriverAttach(pDevIns, uLUN,
-                                   &pThis->IBase, &pThis->pDrvBase, pszDesc);
+                                   &pThis->IBase, &pDrvBase, pszDesc);
     if (RT_SUCCESS(rc))
     {
@@ -4343,5 +4339,6 @@
         if (pDrv)
         {
-            pDrv->pConnector = PDMIBASE_QUERY_INTERFACE(pThis->pDrvBase, PDMIAUDIOCONNECTOR);
+            pDrv->pDrvBase   = pDrvBase;
+            pDrv->pConnector = PDMIBASE_QUERY_INTERFACE(pDrvBase, PDMIAUDIOCONNECTOR);
             AssertMsg(pDrv->pConnector != NULL, ("Configuration error: LUN#%u has no host audio interface, rc=%Rrc\n", uLUN, rc));
             pDrv->pHDAState  = pThis;
@@ -4363,6 +4360,5 @@
             rc = VERR_NO_MEMORY;
     }
-    else if (   rc == VERR_PDM_NO_ATTACHED_DRIVER
-             || rc == VERR_PDM_CFG_MISSING_DRIVER_NAME)
+    else if (rc == VERR_PDM_NO_ATTACHED_DRIVER)
     {
         LogFunc(("No attached driver for LUN #%u\n", uLUN));
@@ -4372,5 +4368,10 @@
                         uLUN, pszDesc, rc));
 
-    RTStrFree(pszDesc);
+    if (RT_FAILURE(rc))
+    {
+        /* Only free this string on failure;
+         * must remain valid for the live of the driver instance. */
+        RTStrFree(pszDesc);
+    }
 
     LogFunc(("uLUN=%u, fFlags=0x%x, rc=%Rrc\n", uLUN, fFlags, rc));
@@ -4378,9 +4379,53 @@
 }
 
-static DECLCALLBACK(void) hdaDetach(PPDMDEVINS pDevIns, unsigned iLUN, uint32_t fFlags)
-{
-    NOREF(pDevIns); NOREF(iLUN); NOREF(fFlags);
-
-    LogFlowFuncEnter();
+static DECLCALLBACK(void) hdaDetach(PPDMDEVINS pDevIns, unsigned uLUN, uint32_t fFlags)
+{
+    LogFunc(("iLUN=%u, fFlags=0x%x\n", uLUN, fFlags));
+}
+
+static int hdaReattach(PHDASTATE pThis, PCFGMNODE pCfg, PHDADRIVER pDrv, const char *pszDriver)
+{
+    AssertPtrReturn(pThis,     VERR_INVALID_POINTER);
+    AssertPtrReturn(pCfg,      VERR_INVALID_POINTER);
+    AssertPtrReturn(pDrv,      VERR_INVALID_POINTER);
+    AssertPtrReturn(pszDriver, VERR_INVALID_POINTER);
+
+    PVM pVM = PDMDevHlpGetVM(pThis->pDevInsR3);
+    PCFGMNODE pRoot = CFGMR3GetRoot(pVM);
+    PCFGMNODE pDev0 = CFGMR3GetChild(pRoot, "Devices/hda/0/");
+
+    /* Remove LUN branch. */
+    CFGMR3RemoveNode(CFGMR3GetChildF(pDev0, "LUN#%u/", pDrv->uLUN));
+
+    int rc = PDMDevHlpDriverDetach(pThis->pDevInsR3, PDMIBASE_2_PDMDRV(pDrv->pDrvBase), 0 /* fFlags */);
+    if (RT_FAILURE(rc))
+        return rc;
+
+#define RC_CHECK() if (RT_FAILURE(rc)) { AssertReleaseRC(rc); break; }
+
+    do
+    {
+        PCFGMNODE pLunL0;
+        rc = CFGMR3InsertNodeF(pDev0, &pLunL0, "LUN#%u/", pDrv->uLUN);  RC_CHECK();
+        rc = CFGMR3InsertString(pLunL0, "Driver",       "AUDIO");       RC_CHECK();
+        rc = CFGMR3InsertNode(pLunL0,   "Config/",       NULL);         RC_CHECK();
+
+        PCFGMNODE pLunL1, pLunL2;
+        rc = CFGMR3InsertNode  (pLunL0, "AttachedDriver/", &pLunL1);    RC_CHECK();
+        rc = CFGMR3InsertNode  (pLunL1,  "Config/",        &pLunL2);    RC_CHECK();
+        rc = CFGMR3InsertString(pLunL1,  "Driver",          pszDriver); RC_CHECK();
+
+        rc = CFGMR3InsertString(pLunL2, "AudioDriver", pszDriver);      RC_CHECK();
+
+    } while (0);
+
+    if (RT_SUCCESS(rc))
+        rc = hdaAttach(pThis->pDevInsR3, pDrv->uLUN, 0 /* fFlags */);
+
+    LogFunc(("pThis=%p, uLUN=%u, pszDriver=%s, rc=%Rrc\n", pThis, pDrv->uLUN, pszDriver, rc));
+
+#undef RC_CHECK
+
+    return rc;
 }
 
@@ -4388,5 +4433,5 @@
  * @interface_method_impl{PDMDEVREG,pfnConstruct}
  */
-static DECLCALLBACK(int) hdaConstruct(PPDMDEVINS pDevIns, int iInstance, PCFGMNODE pCfgHandle)
+static DECLCALLBACK(int) hdaConstruct(PPDMDEVINS pDevIns, int iInstance, PCFGMNODE pCfg)
 {
     PHDASTATE pThis = PDMINS_2_DATA(pDevIns, PHDASTATE);
@@ -4397,15 +4442,15 @@
      * Validations.
      */
-    if (!CFGMR3AreValuesValid(pCfgHandle, "R0Enabled\0"
-                                          "RCEnabled\0"
-                                          "TimerHz\0"))
+    if (!CFGMR3AreValuesValid(pCfg, "R0Enabled\0"
+                                    "RCEnabled\0"
+                                    "TimerHz\0"))
         return PDMDEV_SET_ERROR(pDevIns, VERR_PDM_DEVINS_UNKNOWN_CFG_VALUES,
                                 N_ ("Invalid configuration for the Intel HDA device"));
 
-    int rc = CFGMR3QueryBoolDef(pCfgHandle, "RCEnabled", &pThis->fRCEnabled, false);
+    int rc = CFGMR3QueryBoolDef(pCfg, "RCEnabled", &pThis->fRCEnabled, false);
     if (RT_FAILURE(rc))
         return PDMDEV_SET_ERROR(pDevIns, rc,
                                 N_("HDA configuration error: failed to read RCEnabled as boolean"));
-    rc = CFGMR3QueryBoolDef(pCfgHandle, "R0Enabled", &pThis->fR0Enabled, false);
+    rc = CFGMR3QueryBoolDef(pCfg, "R0Enabled", &pThis->fR0Enabled, false);
     if (RT_FAILURE(rc))
         return PDMDEV_SET_ERROR(pDevIns, rc,
@@ -4413,5 +4458,5 @@
 #ifndef VBOX_WITH_AUDIO_CALLBACKS
     uint16_t uTimerHz;
-    rc = CFGMR3QueryU16Def(pCfgHandle, "TimerHz", &uTimerHz, 200 /* Hz */);
+    rc = CFGMR3QueryU16Def(pCfg, "TimerHz", &uTimerHz, 200 /* Hz */);
     if (RT_FAILURE(rc))
         return PDMDEV_SET_ERROR(pDevIns, rc,
@@ -4540,5 +4585,5 @@
     {
         LogFunc(("Trying to attach driver for LUN #%RU32 ...\n", uLUN));
-        rc = hdaAttach(pDevIns, uLUN, PDM_TACH_FLAGS_NOT_HOT_PLUG);
+        rc = hdaAttach(pDevIns, uLUN, 0 /* fFlags */);
         if (RT_FAILURE(rc))
         {
@@ -4607,5 +4652,5 @@
 
         /* Construct the codec. */
-        rc = hdaCodecConstruct(pDevIns, pThis->pCodec, 0 /* Codec index */, pCfgHandle);
+        rc = hdaCodecConstruct(pDevIns, pThis->pCodec, 0 /* Codec index */, pCfg);
         if (RT_FAILURE(rc))
             AssertRCReturn(rc, rc);
@@ -4629,4 +4674,75 @@
         rc = hdaStreamCreate(&pThis->StrmStOut);
         AssertRC(rc);
+
+        PHDADRIVER pDrv;
+        RTListForEach(&pThis->lstDrv, pDrv, HDADRIVER, Node)
+        {
+            /*
+             * Only primary drivers are critical for the VM to run. Everything else
+             * might not worth showing an own error message box in the GUI.
+             */
+            if (!(pDrv->Flags & PDMAUDIODRVFLAG_PRIMARY))
+                continue;
+
+            PPDMIAUDIOCONNECTOR pCon = pDrv->pConnector;
+            AssertPtr(pCon);
+
+            uint8_t cFailed = 0;
+            if (!pCon->pfnIsValidIn (pCon, pDrv->LineIn.pStrmIn))
+                cFailed++;
+#ifdef VBOX_WITH_HDA_MIC_IN
+            if (!pCon->pfnIsValidIn (pCon, pDrv->MicIn.pStrmIn))
+                cFailed++;
+#endif
+            if (!pCon->pfnIsValidOut(pCon, pDrv->Out.pStrmOut))
+                cFailed++;
+
+#ifdef VBOX_WITH_HDA_MIC_IN
+            if (cFailed == 3)
+#else
+            if (cFailed == 2)
+#endif
+            {
+                LogRel(("HDA: Falling back to NULL backend (no sound audible)\n"));
+
+                hdaReset(pDevIns);
+                hdaReattach(pThis, pCfg, pDrv, "NullAudio");
+
+                PDMDevHlpVMSetRuntimeError(pDevIns, 0 /*fFlags*/, "HostAudioNotResponding",
+                    N_("No audio devices could be opened. Selecting the NULL audio backend "
+                       "with the consequence that no sound is audible"));
+            }
+            else if (cFailed)
+            {
+                if (!pDrv->pConnector->pfnIsValidIn (pDrv->pConnector, pDrv->LineIn.pStrmIn))
+                    LogRel(("HDA: WARNING: Unable to open PCM line input for LUN #%RU32!\n",       pDrv->uLUN));
+#ifdef VBOX_WITH_HDA_MIC_IN
+                if (!pDrv->pConnector->pfnIsValidIn (pDrv->pConnector, pDrv->MicIn.pStrmIn))
+                    LogRel(("HDA: WARNING: Unable to open PCM microphone input for LUN #%RU32!\n", pDrv->uLUN));
+#endif
+                if (!pDrv->pConnector->pfnIsValidOut(pDrv->pConnector, pDrv->Out.pStrmOut))
+                    LogRel(("HDA: WARNING: Unable to open PCM output for LUN #%RU32!\n",           pDrv->uLUN));
+
+                char   szMissingStreams[255];
+                size_t len = 0;
+                if (!pCon->pfnIsValidIn (pCon, pDrv->LineIn.pStrmIn))
+                    len = RTStrPrintf(szMissingStreams,
+                                      sizeof(szMissingStreams), "PCM Input");
+#ifdef VBOX_WITH_HDA_MIC_IN
+                if (!pCon->pfnIsValidIn (pCon, pDrv->MicIn.pStrmIn))
+                    len += RTStrPrintf(szMissingStreams + len,
+                                       sizeof(szMissingStreams) - len, len ? ", PCM Microphone" : "PCM Microphone");
+#endif
+                if (!pCon->pfnIsValidOut(pCon, pDrv->Out.pStrmOut))
+                    len += RTStrPrintf(szMissingStreams + len,
+                                       sizeof(szMissingStreams) - len, len ? ", PCM Output" : "PCM Output");
+
+                PDMDevHlpVMSetRuntimeError(pDevIns, 0 /*fFlags*/, "HostAudioNotResponding",
+                    N_("Some HDA audio streams (%s) could not be opened. Guest applications generating audio "
+                    "output or depending on audio input may hang. Make sure your host audio device "
+                    "is working properly. Check the logfile for error messages of the audio "
+                    "subsystem"), szMissingStreams);
+            }
+        }
     }
 
@@ -4819,7 +4935,7 @@
     NULL,
     /* pfnAttach */
-    NULL,
+    hdaAttach,
     /* pfnDetach */
-    NULL,
+    hdaDetach,
     /* pfnQueryInterface. */
     NULL,
Index: trunk/src/VBox/Devices/Audio/DevSB16.cpp
===================================================================
--- trunk/src/VBox/Devices/Audio/DevSB16.cpp	(revision 59343)
+++ trunk/src/VBox/Devices/Audio/DevSB16.cpp	(revision 59348)
@@ -98,6 +98,7 @@
     uint8_t                            uLUN;
     uint8_t                            Padding[5];
-    /** Audio connector interface to the underlying
-     *  host backend. */
+    /** Pointer to attached driver base interface. */
+    R3PTRTYPE(PPDMIBASE)               pDrvBase;
+    /** Audio connector interface to the underlying host backend. */
     R3PTRTYPE(PPDMIAUDIOCONNECTOR)     pConnector;
     /** Stream for output. */
@@ -109,5 +110,5 @@
 #ifdef VBOX
     /** Pointer to the device instance. */
-    PPDMDEVINSR3        pDevIns;
+    PPDMDEVINSR3        pDevInsR3;
     /** Pointer to the connector of the attached audio driver. */
     PPDMIAUDIOCONNECTOR pDrv;
@@ -179,8 +180,7 @@
     uint64_t                       uTimerTSIO;
 #endif
-    PTMTIMER  pTimerIRQ;
-    PPDMIBASE pDrvBase;
-    /** LUN\#0: Base interface. */
-    PDMIBASE  IBase;
+    PTMTIMER                       pTimerIRQ;
+    /** The base interface for LUN\#0. */
+    PDMIBASE                       IBase;
 
     /* mixer state */
@@ -207,8 +207,4 @@
     PSB16STATE pThis = PDMINS_2_DATA(pDevIns, PSB16STATE);
 
-    AssertMsgReturn(fFlags & PDM_TACH_FLAGS_NOT_HOT_PLUG,
-                    ("AC'97 device does not support hotplugging\n"),
-                    VERR_INVALID_PARAMETER);
-
     /*
      * Attach driver.
@@ -216,10 +212,11 @@
     char *pszDesc = NULL;
     if (RTStrAPrintf(&pszDesc, "Audio driver port (SB16) for LUN #%u", uLUN) <= 0)
-        AssertMsgReturn(pszDesc,
-                        ("Not enough memory for SB16 driver port description of LUN #%u\n", uLUN),
-                        VERR_NO_MEMORY);
-
+        AssertReleaseMsgReturn(pszDesc,
+                               ("Not enough memory for SB16 driver port description of LUN #%u\n", uLUN),
+                               VERR_NO_MEMORY);
+
+    PPDMIBASE pDrvBase;
     int rc = PDMDevHlpDriverAttach(pDevIns, uLUN,
-                                   &pThis->IBase, &pThis->pDrvBase, pszDesc);
+                                   &pThis->IBase, &pDrvBase, pszDesc);
     if (RT_SUCCESS(rc))
     {
@@ -227,10 +224,9 @@
         if (pDrv)
         {
-            pDrv->pConnector = PDMIBASE_QUERY_INTERFACE(pThis->pDrvBase, PDMIAUDIOCONNECTOR);
-            AssertMsg(pDrv->pConnector != NULL,
-                      ("Configuration error: LUN #%u has no host audio interface, rc=%Rrc\n",
-                      uLUN, rc));
+            pDrv->pDrvBase   = pDrvBase;
+            pDrv->pConnector = PDMIBASE_QUERY_INTERFACE(pDrvBase, PDMIAUDIOCONNECTOR);
+            AssertMsg(pDrv->pConnector != NULL, ("Configuration error: LUN #%u has no host audio interface, rc=%Rrc\n", uLUN, rc));
             pDrv->pSB16State = pThis;
-            pDrv->uLUN = uLUN;
+            pDrv->uLUN       = uLUN;
 
             /*
@@ -257,7 +253,63 @@
                         uLUN, pszDesc, rc));
 
-    RTStrFree(pszDesc);
+    if (RT_FAILURE(rc))
+    {
+        /* Only free this string on failure;
+         * must remain valid for the live of the driver instance. */
+        RTStrFree(pszDesc);
+    }
 
     LogFunc(("iLUN=%u, fFlags=0x%x, rc=%Rrc\n", uLUN, fFlags, rc));
+    return rc;
+}
+
+static void sb16Detach(PPDMDEVINS pDevIns, unsigned uLUN, uint32_t fFlags)
+{
+    LogFunc(("iLUN=%u, fFlags=0x%x\n", uLUN, fFlags));
+}
+
+static int sb16Reattach(PSB16STATE pThis, PCFGMNODE pCfg, PSB16DRIVER pDrv, const char *pszDriver)
+{
+    AssertPtrReturn(pThis,     VERR_INVALID_POINTER);
+    AssertPtrReturn(pCfg,      VERR_INVALID_POINTER);
+    AssertPtrReturn(pDrv,      VERR_INVALID_POINTER);
+    AssertPtrReturn(pszDriver, VERR_INVALID_POINTER);
+
+    PVM pVM = PDMDevHlpGetVM(pThis->pDevInsR3);
+    PCFGMNODE pRoot = CFGMR3GetRoot(pVM);
+    PCFGMNODE pDev0 = CFGMR3GetChild(pRoot, "Devices/SB16/0/");
+
+    /* Remove LUN branch. */
+    CFGMR3RemoveNode(CFGMR3GetChildF(pDev0, "LUN#%u/", pDrv->uLUN));
+
+    int rc = PDMDevHlpDriverDetach(pThis->pDevInsR3, PDMIBASE_2_PDMDRV(pDrv->pDrvBase), 0 /* fFlags */);
+    if (RT_FAILURE(rc))
+        return rc;
+
+#define RC_CHECK() if (RT_FAILURE(rc)) { AssertReleaseRC(rc); break; }
+
+    do
+    {
+        PCFGMNODE pLunL0;
+        rc = CFGMR3InsertNodeF(pDev0, &pLunL0, "LUN#%u/", pDrv->uLUN);  RC_CHECK();
+        rc = CFGMR3InsertString(pLunL0, "Driver",       "AUDIO");       RC_CHECK();
+        rc = CFGMR3InsertNode(pLunL0,   "Config/",       NULL);         RC_CHECK();
+
+        PCFGMNODE pLunL1, pLunL2;
+        rc = CFGMR3InsertNode  (pLunL0, "AttachedDriver/", &pLunL1);    RC_CHECK();
+        rc = CFGMR3InsertNode  (pLunL1,  "Config/",        &pLunL2);    RC_CHECK();
+        rc = CFGMR3InsertString(pLunL1,  "Driver",          pszDriver); RC_CHECK();
+
+        rc = CFGMR3InsertString(pLunL2, "AudioDriver", pszDriver);      RC_CHECK();
+
+    } while (0);
+
+    if (RT_SUCCESS(rc))
+        rc = sb16Attach(pThis->pDevInsR3, pDrv->uLUN, 0 /* fFlags */);
+
+    LogFunc(("pThis=%p, uLUN=%u, pszDriver=%s, rc=%Rrc\n", pThis, pDrv->uLUN, pszDriver, rc));
+
+#undef RC_CHECK
+
     return rc;
 }
@@ -336,6 +388,6 @@
     if (hold)
     {
-        PDMDevHlpDMASetDREQ (pThis->pDevIns, dma, 1);
-        PDMDevHlpDMASchedule (pThis->pDevIns);
+        PDMDevHlpDMASetDREQ (pThis->pDevInsR3, dma, 1);
+        PDMDevHlpDMASchedule (pThis->pDevInsR3);
         RTListForEach(&pThis->lstDrv, pDrv, SB16DRIVER, Node)
             pDrv->pConnector->pfnEnableOut(pDrv->pConnector,
@@ -344,5 +396,5 @@
     else
     {
-        PDMDevHlpDMASetDREQ (pThis->pDevIns, dma, 0);
+        PDMDevHlpDMASetDREQ (pThis->pDevInsR3, dma, 0);
         RTListForEach(&pThis->lstDrv, pDrv, SB16DRIVER, Node)
             pDrv->pConnector->pfnEnableOut(pDrv->pConnector,
@@ -355,5 +407,5 @@
     PSB16STATE pThis = (PSB16STATE)pvThis;
     pThis->can_write = 1;
-    PDMDevHlpISASetIrq(pThis->pDevIns, pThis->irq, 1);
+    PDMDevHlpISASetIrq(pThis->pDevInsR3, pThis->irq, 1);
 }
 
@@ -747,5 +799,5 @@
                 dsp_out_data(pThis, 0xaa);
                 pThis->mixer_regs[0x82] |= (cmd == 0xf2) ? 1 : 2;
-                PDMDevHlpISASetIrq(pThis->pDevIns, pThis->irq, 1);
+                PDMDevHlpISASetIrq(pThis->pDevInsR3, pThis->irq, 1);
                 break;
 
@@ -920,5 +972,5 @@
             ticks = (bytes * TMTimerGetFreq(pThis->pTimerIRQ)) / freq;
             if (ticks < TMTimerGetFreq(pThis->pTimerIRQ) / 1024)
-                PDMDevHlpISASetIrq(pThis->pDevIns, pThis->irq, 1);
+                PDMDevHlpISASetIrq(pThis->pDevInsR3, pThis->irq, 1);
             else
                 TMTimerSet(pThis->pTimerIRQ, TMTimerGet(pThis->pTimerIRQ) + ticks);
@@ -1024,9 +1076,9 @@
 static void sb16Reset(PSB16STATE pThis)
 {
-    PDMDevHlpISASetIrq(pThis->pDevIns, pThis->irq, 0);
+    PDMDevHlpISASetIrq(pThis->pDevInsR3, pThis->irq, 0);
     if (pThis->dma_auto)
     {
-        PDMDevHlpISASetIrq(pThis->pDevIns, pThis->irq, 1);
-        PDMDevHlpISASetIrq(pThis->pDevIns, pThis->irq, 0);
+        PDMDevHlpISASetIrq(pThis->pDevInsR3, pThis->irq, 1);
+        PDMDevHlpISASetIrq(pThis->pDevInsR3, pThis->irq, 0);
     }
 
@@ -1067,5 +1119,5 @@
                         {
                             pThis->highspeed = 0;
-                            PDMDevHlpISASetIrq(pThis->pDevIns, pThis->irq, 0);
+                            PDMDevHlpISASetIrq(pThis->pDevInsR3, pThis->irq, 0);
                             sb16Control(pThis, 0);
                         }
@@ -1191,5 +1243,5 @@
                 ack = 1;
                 pThis->mixer_regs[0x82] &= ~1;
-                PDMDevHlpISASetIrq(pThis->pDevIns, pThis->irq, 0);
+                PDMDevHlpISASetIrq(pThis->pDevInsR3, pThis->irq, 0);
             }
             break;
@@ -1201,5 +1253,5 @@
                 ack = 1;
                 pThis->mixer_regs[0x82] &= ~2;
-               PDMDevHlpISASetIrq(pThis->pDevIns, pThis->irq, 0);
+               PDMDevHlpISASetIrq(pThis->pDevInsR3, pThis->irq, 0);
             }
             break;
@@ -1529,5 +1581,5 @@
             cbToRead = sizeof(tmpbuf);
 
-        int rc = PDMDevHlpDMAReadMemory(pThis->pDevIns, nchan, tmpbuf, dma_pos, cbToRead, &cbRead);
+        int rc = PDMDevHlpDMAReadMemory(pThis->pDevInsR3, nchan, tmpbuf, dma_pos, cbToRead, &cbRead);
         AssertMsgRC(rc, ("DMAReadMemory -> %Rrc\n", rc));
 
@@ -1622,5 +1674,5 @@
     {
         pThis->mixer_regs[0x82] |= (nchan & 4) ? 2 : 1;
-        PDMDevHlpISASetIrq(pThis->pDevIns, pThis->irq, 1);
+        PDMDevHlpISASetIrq(pThis->pDevInsR3, pThis->irq, 1);
         if (0 == pThis->dma_auto)
         {
@@ -1730,5 +1782,5 @@
 
         /* New space available, see if we can transfer more. */
-        PDMDevHlpDMASchedule(pThis->pDevIns);
+        PDMDevHlpDMASchedule(pThis->pDevInsR3);
     }
 
@@ -1962,7 +2014,8 @@
     PSB16DRIVER pDrv;
     uint8_t uLUN = 0;
-    char *pszDesc;
+
     RTListForEach(&pThis->lstDrv, pDrv, SB16DRIVER, Node)
     {
+        char *pszDesc;
         if (RTStrAPrintf(&pszDesc, "[LUN#%RU8] sb16.po", uLUN) <= 0)
         {
@@ -1993,4 +2046,5 @@
         uLUN++;
     }
+
     /* Ensure volume gets propagated. */
     AudioMixerInvalidate(pThis->pMixer);
@@ -2009,5 +2063,5 @@
      * sure there's no interrupt or DMA activity.
      */
-    PDMDevHlpISASetIrq(pThis->pDevIns, pThis->irq, 0);
+    PDMDevHlpISASetIrq(pThis->pDevInsR3, pThis->irq, 0);
 
     pThis->mixer_regs[0x82] = 0;
@@ -2067,5 +2121,5 @@
 }
 
-static DECLCALLBACK(int) sb16Construct(PPDMDEVINS pDevIns, int iInstance, PCFGMNODE pCfgHandle)
+static DECLCALLBACK(int) sb16Construct(PPDMDEVINS pDevIns, int iInstance, PCFGMNODE pCfg)
 {
     PSB16STATE pThis = PDMINS_2_DATA(pDevIns, PSB16STATE);
@@ -2076,5 +2130,5 @@
     Assert(iInstance == 0);
     PDMDEV_CHECK_VERSIONS_RETURN(pDevIns);
-    if (!CFGMR3AreValuesValid(pCfgHandle,
+    if (!CFGMR3AreValuesValid(pCfg,
                               "IRQ\0"
                               "DMA\0"
@@ -2089,5 +2143,5 @@
      * Read config data.
      */
-    int rc = CFGMR3QuerySIntDef(pCfgHandle, "IRQ", &pThis->irq, 5);
+    int rc = CFGMR3QuerySIntDef(pCfg, "IRQ", &pThis->irq, 5);
     if (RT_FAILURE(rc))
         return PDMDEV_SET_ERROR(pDevIns, rc,
@@ -2095,5 +2149,5 @@
     pThis->irqCfg  = pThis->irq;
 
-    rc = CFGMR3QuerySIntDef(pCfgHandle, "DMA", &pThis->dma, 1);
+    rc = CFGMR3QuerySIntDef(pCfg, "DMA", &pThis->dma, 1);
     if (RT_FAILURE(rc))
         return PDMDEV_SET_ERROR(pDevIns, rc,
@@ -2101,5 +2155,5 @@
     pThis->dmaCfg  = pThis->dma;
 
-    rc = CFGMR3QuerySIntDef(pCfgHandle, "DMA16", &pThis->hdma, 5);
+    rc = CFGMR3QuerySIntDef(pCfg, "DMA16", &pThis->hdma, 5);
     if (RT_FAILURE(rc))
         return PDMDEV_SET_ERROR(pDevIns, rc,
@@ -2108,5 +2162,5 @@
 
     RTIOPORT Port;
-    rc = CFGMR3QueryPortDef(pCfgHandle, "Port", &Port, 0x220);
+    rc = CFGMR3QueryPortDef(pCfg, "Port", &Port, 0x220);
     if (RT_FAILURE(rc))
         return PDMDEV_SET_ERROR(pDevIns, rc,
@@ -2116,5 +2170,5 @@
 
     uint16_t u16Version;
-    rc = CFGMR3QueryU16Def(pCfgHandle, "Version", &u16Version, 0x0405);
+    rc = CFGMR3QueryU16Def(pCfg, "Version", &u16Version, 0x0405);
     if (RT_FAILURE(rc))
         return PDMDEV_SET_ERROR(pDevIns, rc,
@@ -2123,5 +2177,5 @@
 #ifndef VBOX_WITH_AUDIO_CALLBACKS
     uint16_t uTimerHz;
-    rc = CFGMR3QueryU16Def(pCfgHandle, "TimerHz", &uTimerHz, 200 /* Hz */);
+    rc = CFGMR3QueryU16Def(pCfg, "TimerHz", &uTimerHz, 200 /* Hz */);
     if (RT_FAILURE(rc))
         return PDMDEV_SET_ERROR(pDevIns, rc,
@@ -2135,5 +2189,5 @@
      * Init instance data.
      */
-    pThis->pDevIns                 = pDevIns;
+    pThis->pDevInsR3               = pDevIns;
     pThis->IBase.pfnQueryInterface = sb16QueryInterface;
     pThis->cmd                     = -1;
@@ -2187,5 +2241,5 @@
     {
         LogFunc(("Trying to attach driver for LUN #%RU8 ...\n", uLUN));
-        rc = sb16Attach(pDevIns, uLUN, PDM_TACH_FLAGS_NOT_HOT_PLUG);
+        rc = sb16Attach(pDevIns, uLUN, 0 /* fFlags */);
         if (RT_FAILURE(rc))
         {
@@ -2201,4 +2255,34 @@
 
     sb16ResetLegacy(pThis);
+
+    PSB16DRIVER pDrv;
+    RTListForEach(&pThis->lstDrv, pDrv, SB16DRIVER, Node)
+    {
+        /*
+         * Only primary drivers are critical for the VM to run. Everything else
+         * might not worth showing an own error message box in the GUI.
+         */
+        if (!(pDrv->Flags & PDMAUDIODRVFLAG_PRIMARY))
+            continue;
+
+        PPDMIAUDIOCONNECTOR pCon = pDrv->pConnector;
+        AssertPtr(pCon);
+
+        uint8_t cFailed = 0;
+        if (!pCon->pfnIsValidOut(pCon, pDrv->Out.pStrmOut))
+            cFailed++;
+
+        if (cFailed)
+        {
+            LogRel(("SB16: Falling back to NULL backend (no sound audible)\n"));
+
+            sb16ResetLegacy(pThis);
+            sb16Reattach(pThis, pCfg, pDrv, "NullAudio");
+
+            PDMDevHlpVMSetRuntimeError(pDevIns, 0 /*fFlags*/, "HostAudioNotResponding",
+                N_("No audio devices could be opened. Selecting the NULL audio backend "
+                   "with the consequence that no sound is audible"));
+        }
+    }
 
 #ifndef VBOX_WITH_AUDIO_CALLBACKS
@@ -2222,4 +2306,6 @@
     if (RT_SUCCESS(rc))
     {
+        /** @todo Merge this callback registration with the validation block above once
+         *  this becomes the standard. */
         PSB16DRIVER pDrv;
         RTListForEach(&pThis->lstDrv, pDrv, SB16DRIVER, Node)
@@ -2291,7 +2377,7 @@
     NULL,
     /* pfnAttach */
-    NULL,
+    sb16Attach,
     /* pfnDetach */
-    NULL,
+    sb16Detach,
     /* pfnQueryInterface */
     NULL,
Index: trunk/src/VBox/Devices/Audio/DrvAudio.cpp
===================================================================
--- trunk/src/VBox/Devices/Audio/DrvAudio.cpp	(revision 59343)
+++ trunk/src/VBox/Devices/Audio/DrvAudio.cpp	(revision 59348)
@@ -1728,15 +1728,4 @@
 }
 
-static DECLCALLBACK(int) drvAudioInitNull(PPDMIAUDIOCONNECTOR pInterface)
-{
-    PDRVAUDIO pThis = PDMIAUDIOCONNECTOR_2_DRVAUDIO(pInterface);
-    NOREF(pThis);
-
-    LogRel(("Audio: Using NULL driver; no sound will be audible\n"));
-
-    /* Nothing to do here yet. */
-    return VINF_SUCCESS;
-}
-
 static DECLCALLBACK(int) drvAudioRead(PPDMIAUDIOCONNECTOR pInterface, PPDMAUDIOGSTSTRMIN pGstStrmIn,
                                       void *pvBuf, uint32_t cbBuf, uint32_t *pcbRead)
@@ -2169,5 +2158,4 @@
     pThis->IAudioConnector.pfnIsValidIn              = drvAudioIsValidIn;
     pThis->IAudioConnector.pfnIsValidOut             = drvAudioIsValidOut;
-    pThis->IAudioConnector.pfnInitNull               = drvAudioInitNull;
     pThis->IAudioConnector.pfnEnableOut              = drvAudioEnableOut;
     pThis->IAudioConnector.pfnEnableIn               = drvAudioEnableIn;
