Index: /trunk/include/VBox/vmm/pdmaudioifs.h
===================================================================
--- /trunk/include/VBox/vmm/pdmaudioifs.h	(revision 88043)
+++ /trunk/include/VBox/vmm/pdmaudioifs.h	(revision 88044)
@@ -352,9 +352,9 @@
 /**
  * Audio device info (enumeration result).
- * @sa PDMAUDIODEVICEENUM, PDMIHOSTAUDIO::pfnGetDevices
+ * @sa PDMAUDIOHOSTENUM, PDMIHOSTAUDIO::pfnGetDevices
  */
 typedef struct PDMAUDIODEVICE
 {
-    /** List entry (like PDMAUDIODEVICEENUM::LstDevices). */
+    /** List entry (like PDMAUDIOHOSTENUM::LstDevices). */
     RTLISTNODE          Node;
     /** Magic value (PDMAUDIODEVICE_MAGIC). */
@@ -404,19 +404,25 @@
 
 /**
- * An audio device enumeration result.
+ * A host audio device enumeration result.
  *
  * @sa PDMIHOSTAUDIO::pfnGetDevices
  */
-typedef struct PDMAUDIODEVICEENUM
-{
+typedef struct PDMAUDIOHOSTENUM
+{
+    /** Magic value (PDMAUDIOHOSTENUM_MAGIC). */
+    uint32_t        uMagic;
+    /** Number of audio devices in the list. */
+    uint32_t        cDevices;
     /** List of audio devices (PDMAUDIODEVICE). */
     RTLISTANCHOR    LstDevices;
-    /** Number of audio devices in the list. */
-    uint32_t        cDevices;
-} PDMAUDIODEVICEENUM;
+} PDMAUDIOHOSTENUM;
 /** Pointer to an audio device enumeration result. */
-typedef PDMAUDIODEVICEENUM *PPDMAUDIODEVICEENUM;
+typedef PDMAUDIOHOSTENUM *PPDMAUDIOHOSTENUM;
 /** Pointer to a const audio device enumeration result. */
-typedef PDMAUDIODEVICEENUM const *PCPDMAUDIODEVICEENUM;
+typedef PDMAUDIOHOSTENUM const *PCPDMAUDIOHOSTENUM;
+
+/** Magic for the host audio device enumeration. (Herbert Jeffrey "Herbie" Hancock) */
+#define PDMAUDIOHOSTENUM_MAGIC      UINT32_C(0x19400412)
+
 
 /**
@@ -1652,5 +1658,5 @@
      * @param   pDeviceEnum         Where to return the enumerated audio devices.
      */
-    DECLR3CALLBACKMEMBER(int, pfnGetDevices, (PPDMIHOSTAUDIO pInterface, PPDMAUDIODEVICEENUM pDeviceEnum));
+    DECLR3CALLBACKMEMBER(int, pfnGetDevices, (PPDMIHOSTAUDIO pInterface, PPDMAUDIOHOSTENUM pDeviceEnum));
 
     /**
Index: /trunk/src/VBox/Devices/Audio/DrvAudio.cpp
===================================================================
--- /trunk/src/VBox/Devices/Audio/DrvAudio.cpp	(revision 88043)
+++ /trunk/src/VBox/Devices/Audio/DrvAudio.cpp	(revision 88044)
@@ -51,5 +51,5 @@
 *********************************************************************************************************************************/
 #ifdef VBOX_WITH_AUDIO_ENUM
-static int drvAudioDevicesEnumerateInternal(PDRVAUDIO pThis, bool fLog, PPDMAUDIODEVICEENUM pDevEnum);
+static int drvAudioDevicesEnumerateInternal(PDRVAUDIO pThis, bool fLog, PPDMAUDIOHOSTENUM pDevEnum);
 #endif
 
@@ -2153,5 +2153,5 @@
  * @param   pDevEnum            Where to store the device enumeration.
  */
-static int drvAudioDevicesEnumerateInternal(PDRVAUDIO pThis, bool fLog, PPDMAUDIODEVICEENUM pDevEnum)
+static int drvAudioDevicesEnumerateInternal(PDRVAUDIO pThis, bool fLog, PPDMAUDIOHOSTENUM pDevEnum)
 {
     AssertReturn(RTCritSectIsOwned(&pThis->CritSect) == false, VERR_WRONG_ORDER);
@@ -2164,5 +2164,5 @@
     if (pThis->pHostDrvAudio->pfnGetDevices)
     {
-        PDMAUDIODEVICEENUM DevEnum;
+        PDMAUDIOHOSTENUM DevEnum;
         rc = pThis->pHostDrvAudio->pfnGetDevices(pThis->pHostDrvAudio, &DevEnum);
         if (RT_SUCCESS(rc))
@@ -2190,7 +2190,7 @@
 
             if (pDevEnum)
-                rc = DrvAudioHlpDeviceEnumCopy(pDevEnum, &DevEnum);
-
-            DrvAudioHlpDeviceEnumFree(&DevEnum);
+                rc = PDMAudioHostEnumCopy(pDevEnum, &DevEnum, PDMAUDIODIR_INVALID /*all*/, true /*fOnlyCoreData*/);
+
+            PDMAudioHostEnumDelete(&DevEnum);
         }
         else
Index: /trunk/src/VBox/Devices/Audio/DrvAudio.h
===================================================================
--- /trunk/src/VBox/Devices/Audio/DrvAudio.h	(revision 88043)
+++ /trunk/src/VBox/Devices/Audio/DrvAudio.h	(revision 88044)
@@ -211,18 +211,17 @@
 PPDMAUDIODEVICE PDMAudioDeviceAlloc(size_t cb);
 void            PDMAudioDeviceFree(PPDMAUDIODEVICE pDev);
-PPDMAUDIODEVICE PDMAudioDeviceDup(const PPDMAUDIODEVICE pDev, bool fCopyUserData);
+PPDMAUDIODEVICE PDMAudioDeviceDup(const PPDMAUDIODEVICE pDev, bool fOnlyCoreData);
 /** @}  */
 
 /** @name Audio device enumeration methods.
  * @{ */
-int DrvAudioHlpDeviceEnumInit(PPDMAUDIODEVICEENUM pDevEnm);
-void DrvAudioHlpDeviceEnumFree(PPDMAUDIODEVICEENUM pDevEnm);
-int DrvAudioHlpDeviceEnumAdd(PPDMAUDIODEVICEENUM pDevEnm, PPDMAUDIODEVICE pDev);
-/*PPDMAUDIODEVICEENUM DrvAudioHlpDeviceEnumDup(const PPDMAUDIODEVICEENUM pDevEnm); - unused */
-int DrvAudioHlpDeviceEnumCopy(PPDMAUDIODEVICEENUM pDstDevEnm, PCPDMAUDIODEVICEENUM pSrcDevEnm);
-int DrvAudioHlpDeviceEnumCopyEx(PPDMAUDIODEVICEENUM pDstDevEnm, PCPDMAUDIODEVICEENUM pSrcDevEnm, PDMAUDIODIR enmUsage, bool fCopyUserData);
-PPDMAUDIODEVICE DrvAudioHlpDeviceEnumGetDefaultDevice(PCPDMAUDIODEVICEENUM pDevEnm, PDMAUDIODIR enmDir);
-uint32_t    DrvAudioHlpDeviceEnumGetDeviceCount(PCPDMAUDIODEVICEENUM pDevEnm, PDMAUDIODIR enmUsage);
-void        DrvAudioHlpDeviceEnumLog(PCPDMAUDIODEVICEENUM pDevEnm, const char *pszDesc);
+void            PDMAudioHostEnumInit(PPDMAUDIOHOSTENUM pDevEnm);
+void            PDMAudioHostEnumDelete(PPDMAUDIOHOSTENUM pDevEnm);
+void            PDMAudioHostEnumAppend(PPDMAUDIOHOSTENUM pDevEnm, PPDMAUDIODEVICE pDev);
+int             PDMAudioHostEnumCopy(PPDMAUDIOHOSTENUM pDstDevEnm, PCPDMAUDIOHOSTENUM pSrcDevEnm,
+                                     PDMAUDIODIR enmUsage, bool fOnlyCoreData);
+PPDMAUDIODEVICE PDMAudioHostEnumGetDefault(PCPDMAUDIOHOSTENUM pDevEnm, PDMAUDIODIR enmDir);
+uint32_t        PDMAudioHostEnumCountMatching(PCPDMAUDIOHOSTENUM pDevEnm, PDMAUDIODIR enmUsage);
+void            PDMAudioHostEnumLog(PCPDMAUDIOHOSTENUM pDevEnm, const char *pszDesc);
 /** @}  */
 
Index: /trunk/src/VBox/Devices/Audio/DrvAudioCommon.cpp
===================================================================
--- /trunk/src/VBox/Devices/Audio/DrvAudioCommon.cpp	(revision 88043)
+++ /trunk/src/VBox/Devices/Audio/DrvAudioCommon.cpp	(revision 88044)
@@ -193,13 +193,13 @@
  * @returns Duplicated audio device entry on success, or NULL on failure.
  * @param   pDev            The audio device enum entry to duplicate.
- * @param   fCopyUserData   Whether to also copy the user data portion or not.
- */
-PPDMAUDIODEVICE PDMAudioDeviceDup(PPDMAUDIODEVICE pDev, bool fCopyUserData)
+ * @param   fOnlyCoreData
+ */
+PPDMAUDIODEVICE PDMAudioDeviceDup(PPDMAUDIODEVICE pDev, bool fOnlyCoreData)
 {
     AssertPtrReturn(pDev, NULL);
     Assert(pDev->uMagic == PDMAUDIODEVICE_MAGIC);
-    Assert(!fCopyUserData || !(pDev->fFlags & PDMAUDIODEV_FLAGS_NO_DUP));
-
-    uint32_t cbToDup = fCopyUserData ? pDev->cbSelf : sizeof(PDMAUDIODEVICE);
+    Assert(fOnlyCoreData || !(pDev->fFlags & PDMAUDIODEV_FLAGS_NO_DUP));
+
+    uint32_t cbToDup = fOnlyCoreData ? sizeof(PDMAUDIODEVICE) : pDev->cbSelf;
     AssertReturn(cbToDup >= sizeof(*pDev), NULL);
 
@@ -216,42 +216,48 @@
 
 /**
- * Initializes an audio device enumeration structure.
- *
- * @returns IPRT status code.
- * @param   pDevEnm             Device enumeration to initialize.
- */
-int DrvAudioHlpDeviceEnumInit(PPDMAUDIODEVICEENUM pDevEnm)
-{
-    AssertPtrReturn(pDevEnm, VERR_INVALID_POINTER);
-
+ * Initializes a host audio device enumeration.
+ *
+ * @param   pDevEnm     The enumeration to initialize.
+ */
+void PDMAudioHostEnumInit(PPDMAUDIOHOSTENUM pDevEnm)
+{
+    AssertPtr(pDevEnm);
+
+    pDevEnm->uMagic   = PDMAUDIOHOSTENUM_MAGIC;
+    pDevEnm->cDevices = 0;
     RTListInit(&pDevEnm->LstDevices);
-    pDevEnm->cDevices = 0;
-
-    return VINF_SUCCESS;
-}
-
-/**
- * Frees audio device enumeration data.
- *
- * @param pDevEnm               Device enumeration to destroy.
- */
-void DrvAudioHlpDeviceEnumFree(PPDMAUDIODEVICEENUM pDevEnm)
-{
-    if (!pDevEnm)
-        return;
-
-    PPDMAUDIODEVICE pDev, pDevNext;
-    RTListForEachSafe(&pDevEnm->LstDevices, pDev, pDevNext, PDMAUDIODEVICE, Node)
-    {
-        RTListNodeRemove(&pDev->Node);
-
-        PDMAudioDeviceFree(pDev);
-
-        pDevEnm->cDevices--;
-    }
-
-    /* Sanity. */
-    Assert(RTListIsEmpty(&pDevEnm->LstDevices));
-    Assert(pDevEnm->cDevices == 0);
+}
+
+/**
+ * Deletes the host audio device enumeration and frees all device entries
+ * associated with it.
+ *
+ * The user must call PDMAudioHostEnumInit again to use it again.
+ *
+ * @param   pDevEnm     The host audio device enumeration to delete.
+ */
+void PDMAudioHostEnumDelete(PPDMAUDIOHOSTENUM pDevEnm)
+{
+    if (pDevEnm)
+    {
+        AssertPtr(pDevEnm);
+        AssertReturnVoid(pDevEnm->uMagic == PDMAUDIOHOSTENUM_MAGIC);
+
+        PPDMAUDIODEVICE pDev, pDevNext;
+        RTListForEachSafe(&pDevEnm->LstDevices, pDev, pDevNext, PDMAUDIODEVICE, Node)
+        {
+            RTListNodeRemove(&pDev->Node);
+
+            PDMAudioDeviceFree(pDev);
+
+            pDevEnm->cDevices--;
+        }
+
+        /* Sanity. */
+        Assert(RTListIsEmpty(&pDevEnm->LstDevices));
+        Assert(pDevEnm->cDevices == 0);
+
+        pDevEnm->uMagic = ~PDMAUDIOHOSTENUM_MAGIC;
+    }
 }
 
@@ -259,81 +265,37 @@
  * Adds an audio device to a device enumeration.
  *
- * @return IPRT status code.
  * @param  pDevEnm              Device enumeration to add device to.
  * @param  pDev                 Device to add. The pointer will be owned by the device enumeration  then.
  */
-int DrvAudioHlpDeviceEnumAdd(PPDMAUDIODEVICEENUM pDevEnm, PPDMAUDIODEVICE pDev)
-{
-    AssertPtrReturn(pDevEnm, VERR_INVALID_POINTER);
-    AssertPtrReturn(pDev,    VERR_INVALID_POINTER);
+void PDMAudioHostEnumAppend(PPDMAUDIOHOSTENUM pDevEnm, PPDMAUDIODEVICE pDev)
+{
+    AssertPtr(pDevEnm);
+    AssertPtr(pDev);
+    Assert(pDevEnm->uMagic == PDMAUDIOHOSTENUM_MAGIC);
 
     RTListAppend(&pDevEnm->LstDevices, &pDev->Node);
     pDevEnm->cDevices++;
-
-    return VINF_SUCCESS;
-}
-
-#if 0 /* unused, duplicated by copy  */
-/**
- * Duplicates a device enumeration.
- *
- * @returns Duplicated device enumeration, or NULL on failure.
- *          Must be free'd with DrvAudioHlpDeviceEnumFree().
- * @param   pDevEnm             Device enumeration to duplicate.
- */
-PPDMAUDIODEVICEENUM DrvAudioHlpDeviceEnumDup(const PPDMAUDIODEVICEENUM pDevEnm)
-{
-    AssertPtrReturn(pDevEnm, NULL);
-
-    PPDMAUDIODEVICEENUM pDevEnmDup = (PPDMAUDIODEVICEENUM)RTMemAlloc(sizeof(PDMAUDIODEVICEENUM));
-    if (!pDevEnmDup)
-        return NULL;
-
-    int rc2 = DrvAudioHlpDeviceEnumInit(pDevEnmDup);
-    AssertRC(rc2);
-
-    PPDMAUDIODEVICE pDev;
-    RTListForEach(&pDevEnm->LstDevices, pDev, PDMAUDIODEVICE, Node)
-    {
-        PPDMAUDIODEVICE pDevDup = PDMAudioDeviceDup(pDev, true /* fCopyUserData */);
-        if (!pDevDup)
-        {
-            rc2 = VERR_NO_MEMORY;
-            break;
-        }
-
-        rc2 = DrvAudioHlpDeviceEnumAdd(pDevEnmDup, pDevDup);
-        if (RT_FAILURE(rc2))
-        {
-            PDMAudioDeviceFree(pDevDup);
-            break;
-        }
-    }
-
-    if (RT_FAILURE(rc2))
-    {
-        DrvAudioHlpDeviceEnumFree(pDevEnmDup);
-        pDevEnmDup = NULL;
-    }
-
-    return pDevEnmDup;
-}
-#endif /* unused */
-
-/**
- * Copies device enumeration entries from the source to the destination enumeration.
+}
+
+/**
+ * Appends copies of matching host device entries from one to another enumeration.
  *
  * @returns IPRT status code.
- * @param   pDstDevEnm          Destination enumeration to store enumeration entries into.
- * @param   pSrcDevEnm          Source enumeration to use.
- * @param   enmUsage            The usage to match for copying.  Use
- *                              PDMAUDIODIR_INVALID to match all entries.
- * @param   fCopyUserData       Whether to also copy the user data portion or not.
- */
-int DrvAudioHlpDeviceEnumCopyEx(PPDMAUDIODEVICEENUM pDstDevEnm, PCPDMAUDIODEVICEENUM pSrcDevEnm,
-                                PDMAUDIODIR enmUsage, bool fCopyUserData)
+ * @param   pDstDevEnm      The target to append copies of matching device to.
+ * @param   pSrcDevEnm      The source to copy matching devices from.
+ * @param   enmUsage        The usage to match for copying.
+ *                          Use PDMAUDIODIR_INVALID to match all entries.
+ * @param   fOnlyCoreData   Set this to only copy the PDMAUDIODEVICE part.
+ *                          Careful with passing @c false here as not all
+ *                          backends have data that can be copied.
+ */
+int PDMAudioHostEnumCopy(PPDMAUDIOHOSTENUM pDstDevEnm, PCPDMAUDIOHOSTENUM pSrcDevEnm,
+                         PDMAUDIODIR enmUsage, bool fOnlyCoreData)
 {
     AssertPtrReturn(pDstDevEnm, VERR_INVALID_POINTER);
+    AssertReturn(pDstDevEnm->uMagic == PDMAUDIOHOSTENUM_MAGIC, VERR_WRONG_ORDER);
+
     AssertPtrReturn(pSrcDevEnm, VERR_INVALID_POINTER);
+    AssertReturn(pSrcDevEnm->uMagic == PDMAUDIOHOSTENUM_MAGIC, VERR_WRONG_ORDER);
 
     PPDMAUDIODEVICE pSrcDev;
@@ -343,28 +305,12 @@
             || enmUsage == PDMAUDIODIR_INVALID /*all*/)
         {
-            PPDMAUDIODEVICE pDstDev = PDMAudioDeviceDup(pSrcDev, fCopyUserData);
+            PPDMAUDIODEVICE pDstDev = PDMAudioDeviceDup(pSrcDev, fOnlyCoreData);
             AssertReturn(pDstDev, VERR_NO_MEMORY);
 
-            int rc = DrvAudioHlpDeviceEnumAdd(pDstDevEnm, pDstDev);
-            AssertRCReturnStmt(rc, PDMAudioDeviceFree(pDstDev), VERR_NO_MEMORY);
+            PDMAudioHostEnumAppend(pDstDevEnm, pDstDev);
         }
     }
 
     return VINF_SUCCESS;
-}
-
-/**
- * Copies all device enumeration entries from the source to the destination enumeration.
- *
- * @note Does *not* copy the user-specific data assigned to a device enumeration
- *       entry. To do so, use DrvAudioHlpDeviceEnumCopyEx().
- *
- * @returns IPRT status code.
- * @param   pDstDevEnm          Destination enumeration to store enumeration entries into.
- * @param   pSrcDevEnm          Source enumeration to use.
- */
-int DrvAudioHlpDeviceEnumCopy(PPDMAUDIODEVICEENUM pDstDevEnm, PCPDMAUDIODEVICEENUM pSrcDevEnm)
-{
-    return DrvAudioHlpDeviceEnumCopyEx(pDstDevEnm, pSrcDevEnm, PDMAUDIODIR_INVALID /*all*/, false /* fCopyUserData */);
 }
 
@@ -381,7 +327,8 @@
  *                      PDMAUDIODEV_FLAGS_DEFAULT set.
  */
-PPDMAUDIODEVICE DrvAudioHlpDeviceEnumGetDefaultDevice(PCPDMAUDIODEVICEENUM pDevEnm, PDMAUDIODIR enmUsage)
+PPDMAUDIODEVICE PDMAudioHostEnumGetDefault(PCPDMAUDIOHOSTENUM pDevEnm, PDMAUDIODIR enmUsage)
 {
     AssertPtrReturn(pDevEnm, NULL);
+    AssertReturn(pDevEnm->uMagic == PDMAUDIOHOSTENUM_MAGIC, NULL);
 
     PPDMAUDIODEVICE pDev;
@@ -391,5 +338,5 @@
         {
             if (   enmUsage == pDev->enmUsage
-                || enmUsage  == PDMAUDIODIR_INVALID)
+                || enmUsage == PDMAUDIODIR_INVALID)
                 return pDev;
         }
@@ -407,7 +354,8 @@
  *                      Pass PDMAUDIODIR_INVALID to get the total number of devices.
  */
-uint32_t DrvAudioHlpDeviceEnumGetDeviceCount(PCPDMAUDIODEVICEENUM pDevEnm, PDMAUDIODIR enmUsage)
+uint32_t PDMAudioHostEnumCountMatching(PCPDMAUDIOHOSTENUM pDevEnm, PDMAUDIODIR enmUsage)
 {
     AssertPtrReturn(pDevEnm, 0);
+    AssertReturn(pDevEnm->uMagic == PDMAUDIOHOSTENUM_MAGIC, 0);
 
     if (enmUsage == PDMAUDIODIR_INVALID)
@@ -431,8 +379,9 @@
  * @param  pszDesc  Logging description (prefix).
  */
-void DrvAudioHlpDeviceEnumLog(PCPDMAUDIODEVICEENUM pDevEnm, const char *pszDesc)
-{
+void PDMAudioHostEnumLog(PCPDMAUDIOHOSTENUM pDevEnm, const char *pszDesc)
+{
+    AssertPtrReturnVoid(pDevEnm);
     AssertPtrReturnVoid(pszDesc);
-    AssertPtrReturnVoid(pDevEnm);
+    AssertReturnVoid(pDevEnm->uMagic == PDMAUDIOHOSTENUM_MAGIC);
 
     LogFunc(("%s: %RU32 devices\n", pszDesc, pDevEnm->cDevices));
Index: /trunk/src/VBox/Devices/Audio/DrvHostCoreAudio.cpp
===================================================================
--- /trunk/src/VBox/Devices/Audio/DrvHostCoreAudio.cpp	(revision 88043)
+++ /trunk/src/VBox/Devices/Audio/DrvHostCoreAudio.cpp	(revision 88044)
@@ -100,5 +100,5 @@
     RTCRITSECT              CritSect;
     /** Current (last reported) device enumeration. */
-    PDMAUDIODEVICEENUM      Devices;
+    PDMAUDIOHOSTENUM      Devices;
     /** Pointer to the currently used input device in the device enumeration.
      *  Can be NULL if none assigned. */
@@ -487,5 +487,5 @@
  * @param   pDevEnm             Where to store the enumerated devices.
  */
-static int coreAudioDevicesEnumerate(PDRVHOSTCOREAUDIO pThis, PDMAUDIODIR enmUsage, PPDMAUDIODEVICEENUM pDevEnm)
+static int coreAudioDevicesEnumerate(PDRVHOSTCOREAUDIO pThis, PDMAUDIODIR enmUsage, PPDMAUDIOHOSTENUM pDevEnm)
 {
     AssertPtrReturn(pThis,   VERR_INVALID_POINTER);
@@ -533,7 +533,5 @@
             break;
 
-        rc = DrvAudioHlpDeviceEnumInit(pDevEnm);
-        if (RT_FAILURE(rc))
-            break;
+        PDMAudioHostEnumInit(pDevEnm);
 
         UInt16 cDevices = uSize / sizeof(AudioDeviceID);
@@ -663,7 +661,5 @@
 
             /* Add the device to the enumeration. */
-            rc = DrvAudioHlpDeviceEnumAdd(pDevEnm, &pDev->Core);
-            if (RT_FAILURE(rc))
-                break;
+            PDMAudioHostEnumAppend(pDevEnm, &pDev->Core);
 
             /* NULL device pointer because it's now part of the device enumeration. */
@@ -683,9 +679,9 @@
 #ifdef LOG_ENABLED
         LogFunc(("Devices for pDevEnm=%p, enmUsage=%RU32:\n", pDevEnm, enmUsage));
-        DrvAudioHlpDeviceEnumLog(pDevEnm, "Core Audio");
+        PDMAudioHostEnumLog(pDevEnm, "Core Audio");
 #endif
     }
     else
-        DrvAudioHlpDeviceEnumFree(pDevEnm);
+        PDMAudioHostEnumDelete(pDevEnm);
 
     LogFlowFuncLeaveRC(rc);
@@ -704,5 +700,5 @@
  * @param   deviceID              Device ID to search.
  */
-bool coreAudioDevicesHasDevice(PPDMAUDIODEVICEENUM pEnmSrc, AudioDeviceID deviceID)
+bool coreAudioDevicesHasDevice(PPDMAUDIOHOSTENUM pEnmSrc, AudioDeviceID deviceID)
 {
     PCOREAUDIODEVICEDATA pDevSrc;
@@ -725,11 +721,11 @@
  * @param   pEnmDst             Where to store the device enumeration list.
  */
-int coreAudioDevicesEnumerateAll(PDRVHOSTCOREAUDIO pThis, PPDMAUDIODEVICEENUM pEnmDst)
-{
-    PDMAUDIODEVICEENUM devEnmIn;
+int coreAudioDevicesEnumerateAll(PDRVHOSTCOREAUDIO pThis, PPDMAUDIOHOSTENUM pEnmDst)
+{
+    PDMAUDIOHOSTENUM devEnmIn;
     int rc = coreAudioDevicesEnumerate(pThis, PDMAUDIODIR_IN, &devEnmIn);
     if (RT_SUCCESS(rc))
     {
-        PDMAUDIODEVICEENUM devEnmOut;
+        PDMAUDIOHOSTENUM devEnmOut;
         rc = coreAudioDevicesEnumerate(pThis, PDMAUDIODIR_OUT, &devEnmOut);
         if (RT_SUCCESS(rc))
@@ -742,11 +738,68 @@
              * at the same time.
              */
-
-            rc = DrvAudioHlpDeviceEnumInit(pEnmDst);
+            PDMAudioHostEnumInit(pEnmDst);
+            PCOREAUDIODEVICEDATA pDevSrcIn;
+            RTListForEach(&devEnmIn.LstDevices, pDevSrcIn, COREAUDIODEVICEDATA, Core.Node)
+            {
+                PCOREAUDIODEVICEDATA pDevDst = (PCOREAUDIODEVICEDATA)PDMAudioDeviceAlloc(sizeof(*pDevDst));
+                if (!pDevDst)
+                {
+                    rc = VERR_NO_MEMORY;
+                    break;
+                }
+
+                coreAudioDeviceDataInit(pDevDst, pDevSrcIn->deviceID, true /* fIsInput */, pThis);
+
+                RTStrCopy(pDevDst->Core.szName, sizeof(pDevDst->Core.szName), pDevSrcIn->Core.szName);
+
+                pDevDst->Core.enmUsage          = PDMAUDIODIR_IN; /* Input device by default (simplex). */
+                pDevDst->Core.cMaxInputChannels = pDevSrcIn->Core.cMaxInputChannels;
+
+                /* Handle flags. */
+                if (pDevSrcIn->Core.fFlags & PDMAUDIODEV_FLAGS_DEFAULT)
+                    pDevDst->Core.fFlags |= PDMAUDIODEV_FLAGS_DEFAULT;
+                /** @todo Handle hot plugging? */
+
+                /*
+                 * Now search through the list of all found output devices and check if we found
+                 * an output device with the same device ID as the currently handled input device.
+                 *
+                 * If found, this means we have to treat that device as a duplex device then.
+                 */
+                PCOREAUDIODEVICEDATA pDevSrcOut;
+                RTListForEach(&devEnmOut.LstDevices, pDevSrcOut, COREAUDIODEVICEDATA, Core.Node)
+                {
+                    if (pDevSrcIn->deviceID == pDevSrcOut->deviceID)
+                    {
+                        pDevDst->Core.enmUsage           = PDMAUDIODIR_DUPLEX;
+                        pDevDst->Core.cMaxOutputChannels = pDevSrcOut->Core.cMaxOutputChannels;
+
+                        if (pDevSrcOut->Core.fFlags & PDMAUDIODEV_FLAGS_DEFAULT)
+                            pDevDst->Core.fFlags |= PDMAUDIODEV_FLAGS_DEFAULT;
+                        break;
+                    }
+                }
+
+                if (RT_SUCCESS(rc))
+                    PDMAudioHostEnumAppend(pEnmDst, &pDevDst->Core);
+                else
+                {
+                    PDMAudioDeviceFree(&pDevDst->Core);
+                    pDevDst = NULL;
+                }
+            }
+
             if (RT_SUCCESS(rc))
             {
-                PCOREAUDIODEVICEDATA pDevSrcIn;
-                RTListForEach(&devEnmIn.LstDevices, pDevSrcIn, COREAUDIODEVICEDATA, Core.Node)
+                /*
+                 * As a last step, add all remaining output devices which have not been handled in the loop above,
+                 * that is, all output devices which operate in simplex mode.
+                 */
+                PCOREAUDIODEVICEDATA pDevSrcOut;
+                RTListForEach(&devEnmOut.LstDevices, pDevSrcOut, COREAUDIODEVICEDATA, Core.Node)
                 {
+                    if (coreAudioDevicesHasDevice(pEnmDst, pDevSrcOut->deviceID))
+                        continue; /* Already in our list, skip. */
+
                     PCOREAUDIODEVICEDATA pDevDst = (PCOREAUDIODEVICEDATA)PDMAudioDeviceAlloc(sizeof(*pDevDst));
                     if (!pDevDst)
@@ -756,100 +809,34 @@
                     }
 
-                    coreAudioDeviceDataInit(pDevDst, pDevSrcIn->deviceID, true /* fIsInput */, pThis);
-
-                    RTStrCopy(pDevDst->Core.szName, sizeof(pDevDst->Core.szName), pDevSrcIn->Core.szName);
-
-                    pDevDst->Core.enmUsage          = PDMAUDIODIR_IN; /* Input device by default (simplex). */
-                    pDevDst->Core.cMaxInputChannels = pDevSrcIn->Core.cMaxInputChannels;
+                    coreAudioDeviceDataInit(pDevDst, pDevSrcOut->deviceID, false /* fIsInput */, pThis);
+
+                    RTStrCopy(pDevDst->Core.szName, sizeof(pDevDst->Core.szName), pDevSrcOut->Core.szName);
+
+                    pDevDst->Core.enmUsage           = PDMAUDIODIR_OUT;
+                    pDevDst->Core.cMaxOutputChannels = pDevSrcOut->Core.cMaxOutputChannels;
+
+                    pDevDst->deviceID       = pDevSrcOut->deviceID;
 
                     /* Handle flags. */
-                    if (pDevSrcIn->Core.fFlags & PDMAUDIODEV_FLAGS_DEFAULT)
+                    if (pDevSrcOut->Core.fFlags & PDMAUDIODEV_FLAGS_DEFAULT)
                         pDevDst->Core.fFlags |= PDMAUDIODEV_FLAGS_DEFAULT;
                     /** @todo Handle hot plugging? */
 
-                    /*
-                     * Now search through the list of all found output devices and check if we found
-                     * an output device with the same device ID as the currently handled input device.
-                     *
-                     * If found, this means we have to treat that device as a duplex device then.
-                     */
-                    PCOREAUDIODEVICEDATA pDevSrcOut;
-                    RTListForEach(&devEnmOut.LstDevices, pDevSrcOut, COREAUDIODEVICEDATA, Core.Node)
-                    {
-                        if (pDevSrcIn->deviceID == pDevSrcOut->deviceID)
-                        {
-                            pDevDst->Core.enmUsage           = PDMAUDIODIR_DUPLEX;
-                            pDevDst->Core.cMaxOutputChannels = pDevSrcOut->Core.cMaxOutputChannels;
-
-                            if (pDevSrcOut->Core.fFlags & PDMAUDIODEV_FLAGS_DEFAULT)
-                                pDevDst->Core.fFlags |= PDMAUDIODEV_FLAGS_DEFAULT;
-                            break;
-                        }
-                    }
-
-                    if (RT_SUCCESS(rc))
-                        rc = DrvAudioHlpDeviceEnumAdd(pEnmDst, &pDevDst->Core);
-                    else
-                    {
-                        PDMAudioDeviceFree(&pDevDst->Core);
-                        pDevDst = NULL;
-                    }
+                    PDMAudioHostEnumAppend(pEnmDst, &pDevDst->Core);
                 }
-
-                if (RT_SUCCESS(rc))
-                {
-                    /*
-                     * As a last step, add all remaining output devices which have not been handled in the loop above,
-                     * that is, all output devices which operate in simplex mode.
-                     */
-                    PCOREAUDIODEVICEDATA pDevSrcOut;
-                    RTListForEach(&devEnmOut.LstDevices, pDevSrcOut, COREAUDIODEVICEDATA, Core.Node)
-                    {
-                        if (coreAudioDevicesHasDevice(pEnmDst, pDevSrcOut->deviceID))
-                            continue; /* Already in our list, skip. */
-
-                        PCOREAUDIODEVICEDATA pDevDst = (PCOREAUDIODEVICEDATA)PDMAudioDeviceAlloc(sizeof(*pDevDst));
-                        if (!pDevDst)
-                        {
-                            rc = VERR_NO_MEMORY;
-                            break;
-                        }
-
-                        coreAudioDeviceDataInit(pDevDst, pDevSrcOut->deviceID, false /* fIsInput */, pThis);
-
-                        RTStrCopy(pDevDst->Core.szName, sizeof(pDevDst->Core.szName), pDevSrcOut->Core.szName);
-
-                        pDevDst->Core.enmUsage           = PDMAUDIODIR_OUT;
-                        pDevDst->Core.cMaxOutputChannels = pDevSrcOut->Core.cMaxOutputChannels;
-
-                        pDevDst->deviceID       = pDevSrcOut->deviceID;
-
-                        /* Handle flags. */
-                        if (pDevSrcOut->Core.fFlags & PDMAUDIODEV_FLAGS_DEFAULT)
-                            pDevDst->Core.fFlags |= PDMAUDIODEV_FLAGS_DEFAULT;
-                        /** @todo Handle hot plugging? */
-
-                        rc = DrvAudioHlpDeviceEnumAdd(pEnmDst, &pDevDst->Core);
-                        if (RT_FAILURE(rc))
-                        {
-                            PDMAudioDeviceFree(&pDevDst->Core);
-                            break;
-                        }
-                    }
-                }
-
-                if (RT_FAILURE(rc))
-                    DrvAudioHlpDeviceEnumFree(pEnmDst);
             }
 
-            DrvAudioHlpDeviceEnumFree(&devEnmOut);
-        }
-
-        DrvAudioHlpDeviceEnumFree(&devEnmIn);
+            if (RT_FAILURE(rc))
+                PDMAudioHostEnumDelete(pEnmDst);
+
+            PDMAudioHostEnumDelete(&devEnmOut);
+        }
+
+        PDMAudioHostEnumDelete(&devEnmIn);
     }
 
 #ifdef LOG_ENABLED
     if (RT_SUCCESS(rc))
-        DrvAudioHlpDeviceEnumLog(pEnmDst, "Core Audio (Final)");
+        PDMAudioHostEnumLog(pEnmDst, "Core Audio (Final)");
 #endif
 
@@ -1841,5 +1828,5 @@
 
     /* Remove old / stale device entries. */
-    DrvAudioHlpDeviceEnumFree(&pThis->Devices);
+    PDMAudioHostEnumDelete(&pThis->Devices);
 
     /* Enumerate all devices internally. */
@@ -1850,5 +1837,5 @@
          * Default input device.
          */
-        pThis->pDefaultDevIn = (PCOREAUDIODEVICEDATA)DrvAudioHlpDeviceEnumGetDefaultDevice(&pThis->Devices, PDMAUDIODIR_IN);
+        pThis->pDefaultDevIn = (PCOREAUDIODEVICEDATA)PDMAudioHostEnumGetDefault(&pThis->Devices, PDMAUDIODIR_IN);
         if (pThis->pDefaultDevIn)
         {
@@ -1863,5 +1850,5 @@
          * Default output device.
          */
-        pThis->pDefaultDevOut = (PCOREAUDIODEVICEDATA)DrvAudioHlpDeviceEnumGetDefaultDevice(&pThis->Devices, PDMAUDIODIR_OUT);
+        pThis->pDefaultDevOut = (PCOREAUDIODEVICEDATA)PDMAudioHostEnumGetDefault(&pThis->Devices, PDMAUDIODIR_OUT);
         if (pThis->pDefaultDevOut)
         {
@@ -2167,6 +2154,6 @@
 
     /* For Core Audio we provide one stream per device for now. */
-    pBackendCfg->cMaxStreamsIn  = DrvAudioHlpDeviceEnumGetDeviceCount(&pThis->Devices, PDMAUDIODIR_IN);
-    pBackendCfg->cMaxStreamsOut = DrvAudioHlpDeviceEnumGetDeviceCount(&pThis->Devices, PDMAUDIODIR_OUT);
+    pBackendCfg->cMaxStreamsIn  = PDMAudioHostEnumCountMatching(&pThis->Devices, PDMAUDIODIR_IN);
+    pBackendCfg->cMaxStreamsOut = PDMAudioHostEnumCountMatching(&pThis->Devices, PDMAUDIODIR_OUT);
 
     LogFlowFunc(("Returning %Rrc\n", VINF_SUCCESS));
@@ -2178,5 +2165,5 @@
  * @interface_method_impl{PDMIHOSTAUDIO,pfnGetDevices}
  */
-static DECLCALLBACK(int) drvHostCoreAudioHA_GetDevices(PPDMIHOSTAUDIO pInterface, PPDMAUDIODEVICEENUM pDeviceEnum)
+static DECLCALLBACK(int) drvHostCoreAudioHA_GetDevices(PPDMIHOSTAUDIO pInterface, PPDMAUDIOHOSTENUM pDeviceEnum)
 {
     AssertPtrReturn(pInterface,  VERR_INVALID_POINTER);
@@ -2194,10 +2181,8 @@
             {
                 /* Return a copy with only PDMAUDIODEVICE, none of the extra bits in COREAUDIODEVICEDATA. */
-                rc = DrvAudioHlpDeviceEnumInit(pDeviceEnum);
-                if (RT_SUCCESS(rc))
-                    rc = DrvAudioHlpDeviceEnumCopy(pDeviceEnum, &pThis->Devices);
-
+                PDMAudioHostEnumInit(pDeviceEnum);
+                rc = PDMAudioHostEnumCopy(pDeviceEnum, &pThis->Devices, PDMAUDIODIR_INVALID /*all*/, true /*fOnlyCoreData*/);
                 if (RT_FAILURE(rc))
-                    DrvAudioHlpDeviceEnumFree(pDeviceEnum);
+                    PDMAudioHostEnumDelete(pDeviceEnum);
             }
         }
@@ -2497,11 +2482,7 @@
     PDRVHOSTCOREAUDIO pThis = PDMIHOSTAUDIO_2_DRVHOSTCOREAUDIO(pInterface);
 
-    int rc = DrvAudioHlpDeviceEnumInit(&pThis->Devices);
-    if (RT_SUCCESS(rc))
-    {
-        /* Do the first (initial) internal device enumeration. */
-        rc = coreAudioEnumerateDevices(pThis);
-    }
-
+    PDMAudioHostEnumInit(&pThis->Devices);
+    /* Do the first (initial) internal device enumeration. */
+    int rc = coreAudioEnumerateDevices(pThis);
     if (RT_SUCCESS(rc))
     {
Index: /trunk/src/VBox/Devices/Audio/DrvHostDSound.cpp
===================================================================
--- /trunk/src/VBox/Devices/Audio/DrvHostDSound.cpp	(revision 88043)
+++ /trunk/src/VBox/Devices/Audio/DrvHostDSound.cpp	(revision 88044)
@@ -200,5 +200,5 @@
     uint32_t            fFlags;
     /** Pointer to device list to populate. */
-    PPDMAUDIODEVICEENUM pDevEnm;
+    PPDMAUDIOHOSTENUM pDevEnm;
 } DSOUNDENUMCBCTX, *PDSOUNDENUMCBCTX;
 
@@ -214,5 +214,5 @@
     DSOUNDHOSTCFG               Cfg;
     /** List of devices of last enumeration. */
-    PDMAUDIODEVICEENUM          DeviceEnum;
+    PDMAUDIOHOSTENUM          DeviceEnum;
     /** Whether this backend supports any audio input. */
     bool                        fEnabledIn;
@@ -246,5 +246,5 @@
 static HRESULT  directSoundCaptureStop(PDRVHOSTDSOUND pThis, PDSOUNDSTREAM pStreamDS, bool fFlush);
 
-static int      dsoundDevicesEnumerate(PDRVHOSTDSOUND pThis, PDMAUDIODEVICEENUM pDevEnm, uint32_t fEnum);
+static int      dsoundDevicesEnumerate(PDRVHOSTDSOUND pThis, PDMAUDIOHOSTENUM pDevEnm, uint32_t fEnum);
 
 static int      dsoundStreamEnable(PDRVHOSTDSOUND pThis, PDSOUNDSTREAM pStreamDS, bool fEnable);
@@ -1577,5 +1577,5 @@
     AssertPtrReturn(pEnumCtx , FALSE);
 
-    PPDMAUDIODEVICEENUM pDevEnm = pEnumCtx->pDevEnm;
+    PPDMAUDIOHOSTENUM pDevEnm = pEnumCtx->pDevEnm;
     AssertPtrReturn(pDevEnm, FALSE);
 
@@ -1604,12 +1604,10 @@
                 memcpy(&pDev->Guid, pGUID, sizeof(pDev->Guid));
 
-            rc = DrvAudioHlpDeviceEnumAdd(pDevEnm, &pDev->Core);
-            if (RT_SUCCESS(rc))
-            {
-                /* Note: Querying the actual device information will be done at some
-                 *       later point in time outside this enumeration callback to prevent
-                 *       DSound hangs. */
-                return TRUE;
-            }
+            PDMAudioHostEnumAppend(pDevEnm, &pDev->Core);
+
+            /* Note: Querying the actual device information will be done at some
+             *       later point in time outside this enumeration callback to prevent
+             *       DSound hangs. */
+            return TRUE;
         }
         PDMAudioDeviceFree(&pDev->Core);
@@ -1638,5 +1636,5 @@
     AssertPtrReturn(pEnumCtx , FALSE);
 
-    PPDMAUDIODEVICEENUM pDevEnm = pEnumCtx->pDevEnm;
+    PPDMAUDIOHOSTENUM pDevEnm = pEnumCtx->pDevEnm;
     AssertPtrReturn(pDevEnm, FALSE);
 
@@ -1662,12 +1660,10 @@
                 memcpy(&pDev->Guid, pGUID, sizeof(pDev->Guid));
 
-            rc = DrvAudioHlpDeviceEnumAdd(pDevEnm, &pDev->Core);
-            if (RT_SUCCESS(rc))
-            {
-                /* Note: Querying the actual device information will be done at some
-                 *       later point in time outside this enumeration callback to prevent
-                 *       DSound hangs. */
-                return TRUE;
-            }
+            PDMAudioHostEnumAppend(pDevEnm, &pDev->Core);
+
+            /* Note: Querying the actual device information will be done at some
+             *       later point in time outside this enumeration callback to prevent
+             *       DSound hangs. */
+            return TRUE;
         }
         PDMAudioDeviceFree(&pDev->Core);
@@ -1787,5 +1783,5 @@
  * @param   pDevEnm             Where to store the enumerated devices.
  */
-static int dsoundDevicesEnumerate(PDRVHOSTDSOUND pThis, PPDMAUDIODEVICEENUM pDevEnm)
+static int dsoundDevicesEnumerate(PDRVHOSTDSOUND pThis, PPDMAUDIOHOSTENUM pDevEnm)
 {
     AssertPtrReturn(pThis, VERR_INVALID_POINTER);
@@ -1880,6 +1876,6 @@
         }
 #endif
-        pThis->fEnabledIn  = DrvAudioHlpDeviceEnumGetDeviceCount(&pThis->DeviceEnum, PDMAUDIODIR_IN)  != 0;
-        pThis->fEnabledOut = DrvAudioHlpDeviceEnumGetDeviceCount(&pThis->DeviceEnum, PDMAUDIODIR_OUT) != 0;
+        pThis->fEnabledIn  = PDMAudioHostEnumCountMatching(&pThis->DeviceEnum, PDMAUDIODIR_IN)  != 0;
+        pThis->fEnabledOut = PDMAudioHostEnumCountMatching(&pThis->DeviceEnum, PDMAUDIODIR_OUT) != 0;
     }
 
@@ -2234,5 +2230,5 @@
  * @interface_method_impl{PDMIHOSTAUDIO,pfnGetDevices}
  */
-static DECLCALLBACK(int) drvHostDSoundHA_GetDevices(PPDMIHOSTAUDIO pInterface, PPDMAUDIODEVICEENUM pDeviceEnum)
+static DECLCALLBACK(int) drvHostDSoundHA_GetDevices(PPDMIHOSTAUDIO pInterface, PPDMAUDIOHOSTENUM pDeviceEnum)
 {
     AssertPtrReturn(pInterface,  VERR_INVALID_POINTER);
@@ -2244,11 +2240,8 @@
     if (RT_SUCCESS(rc))
     {
-        rc = DrvAudioHlpDeviceEnumInit(pDeviceEnum);
-        if (RT_SUCCESS(rc))
-        {
-            rc = dsoundDevicesEnumerate(pThis, pDeviceEnum);
-            if (RT_FAILURE(rc))
-                DrvAudioHlpDeviceEnumFree(pDeviceEnum);
-        }
+        PDMAudioHostEnumInit(pDeviceEnum);
+        rc = dsoundDevicesEnumerate(pThis, pDeviceEnum);
+        if (RT_FAILURE(rc))
+            PDMAudioHostEnumDelete(pDeviceEnum);
 
         int rc2 = RTCritSectLeave(&pThis->CritSect);
@@ -2630,5 +2623,5 @@
 #endif
 
-    DrvAudioHlpDeviceEnumFree(&pThis->DeviceEnum);
+    PDMAudioHostEnumDelete(&pThis->DeviceEnum);
 
     if (pThis->pDrvIns)
@@ -2697,5 +2690,5 @@
      * Init the static parts.
      */
-    DrvAudioHlpDeviceEnumInit(&pThis->DeviceEnum);
+    PDMAudioHostEnumInit(&pThis->DeviceEnum);
 
     pThis->fEnabledIn  = false;
