Index: /trunk/src/VBox/Devices/Audio/DrvHostAudioDSound.cpp
===================================================================
--- /trunk/src/VBox/Devices/Audio/DrvHostAudioDSound.cpp	(revision 88538)
+++ /trunk/src/VBox/Devices/Audio/DrvHostAudioDSound.cpp	(revision 88539)
@@ -708,10 +708,11 @@
  * @param   lpContext           Pointer to PDSOUNDENUMCBCTX context for storing the enumerated information.
  *
- * @note    Carbon copy of dsoundDevicesEnumCbCapture with OUT direction.
- */
-static BOOL CALLBACK dsoundDevicesEnumCbPlayback(LPGUID pGUID, LPCWSTR pwszDescription, LPCWSTR pwszModule, PVOID lpContext)
+ * @note    Carbon copy of drvHostDSoundEnumOldStyleCaptureCallback with OUT direction.
+ */
+static BOOL CALLBACK drvHostDSoundEnumOldStylePlaybackCallback(LPGUID pGUID, LPCWSTR pwszDescription,
+                                                               LPCWSTR pwszModule, PVOID lpContext)
 {
     PDSOUNDENUMCBCTX pEnumCtx = (PDSOUNDENUMCBCTX)lpContext;
-    AssertPtrReturn(pEnumCtx , FALSE);
+    AssertPtrReturn(pEnumCtx, FALSE);
 
     PPDMAUDIOHOSTENUM pDevEnm = pEnumCtx->pDevEnm;
@@ -768,10 +769,11 @@
  * @param   lpContext           Pointer to PDSOUNDENUMCBCTX context for storing the enumerated information.
  *
- * @note    Carbon copy of dsoundDevicesEnumCbPlayback with IN direction.
- */
-static BOOL CALLBACK dsoundDevicesEnumCbCapture(LPGUID pGUID, LPCWSTR pwszDescription, LPCWSTR pwszModule, PVOID lpContext)
+ * @note    Carbon copy of drvHostDSoundEnumOldStylePlaybackCallback with IN direction.
+ */
+static BOOL CALLBACK drvHostDSoundEnumOldStyleCaptureCallback(LPGUID pGUID, LPCWSTR pwszDescription,
+                                                              LPCWSTR pwszModule, PVOID lpContext)
 {
     PDSOUNDENUMCBCTX pEnumCtx = (PDSOUNDENUMCBCTX )lpContext;
-    AssertPtrReturn(pEnumCtx , FALSE);
+    AssertPtrReturn(pEnumCtx, FALSE);
 
     PPDMAUDIOHOSTENUM pDevEnm = pEnumCtx->pDevEnm;
@@ -820,11 +822,9 @@
  *
  * @returns VBox status code.
- * @param   pThis               Host audio driver instance.
  * @param   pDev                Audio device to query information for.
  */
-static int dsoundDeviceQueryInfo(PDRVHOSTDSOUND pThis, PDSOUNDDEV pDev)
-{
-    AssertPtrReturn(pThis, VERR_INVALID_POINTER);
-    AssertPtrReturn(pDev,  VERR_INVALID_POINTER);
+static int drvHostDSoundEnumOldStyleQueryDeviceInfo(PDSOUNDDEV pDev)
+{
+    AssertPtr(pDev);
     int rc;
 
@@ -926,5 +926,5 @@
  * @param   fDefault    Whether it's the default device.
  */
-static int dsoundDeviceNewStyleAdd(PPDMAUDIOHOSTENUM pDevEnm, IMMDevice *pDevice, EDataFlow enmType, bool fDefault)
+static int drvHostDSoundEnumNewStyleAdd(PPDMAUDIOHOSTENUM pDevEnm, IMMDevice *pDevice, EDataFlow enmType, bool fDefault)
 {
     int rc = VINF_SUCCESS; /* ignore most errors */
@@ -1023,12 +1023,8 @@
  *
  * @return  VBox status code.
- * @param   pThis               Host audio driver instance.
  * @param   pDevEnm             Where to store the enumerated devices.
  */
-static int dsoundDevicesEnumerate(PDRVHOSTDSOUND pThis, PPDMAUDIOHOSTENUM pDevEnm)
-{
-    AssertPtrReturn(pThis, VERR_INVALID_POINTER);
-    AssertPtrReturn(pThis, VERR_INVALID_POINTER);
-
+static int drvHostDSoundEnumerateDevices(PPDMAUDIOHOSTENUM pDevEnm)
+{
     DSLOG(("DSound: Enumerating devices ...\n"));
 
@@ -1050,5 +1046,5 @@
             hrc = pEnumerator->GetDefaultAudioEndpoint(enmType, eMultimedia, &pDefaultDevice);
             if (SUCCEEDED(hrc))
-                rc = dsoundDeviceNewStyleAdd(pDevEnm, pDefaultDevice, enmType, true);
+                rc = drvHostDSoundEnumNewStyleAdd(pDevEnm, pDefaultDevice, enmType, true);
             else
                 pDefaultDevice = NULL;
@@ -1070,5 +1066,5 @@
                         {
                             if (pDevice != pDefaultDevice)
-                                rc = dsoundDeviceNewStyleAdd(pDevEnm, pDevice, enmType, false);
+                                rc = drvHostDSoundEnumNewStyleAdd(pDevEnm, pDevice, enmType, false);
                             pDevice->Release();
                         }
@@ -1092,66 +1088,75 @@
 
     /*
-     * Fall back on dsound.
+     * Fall back to dsound.
      */
-    RTLDRMOD hDSound = NULL;
-    int rc = RTLdrLoadSystem("dsound.dll", true /*fNoUnload*/, &hDSound);
-    if (RT_SUCCESS(rc))
-    {
-        DSOUNDENUMCBCTX EnumCtx;
-        EnumCtx.fFlags  = 0;
-        EnumCtx.pDevEnm = pDevEnm;
-
-        /*
-         * Enumerate playback devices.
-         */
-        PFNDIRECTSOUNDENUMERATEW pfnDirectSoundEnumerateW = NULL;
-        rc = RTLdrGetSymbol(hDSound, "DirectSoundEnumerateW", (void**)&pfnDirectSoundEnumerateW);
+    /* Resolve symbols once. */
+    static PFNDIRECTSOUNDENUMERATEW        volatile s_pfnDirectSoundEnumerateW        = NULL;
+    static PFNDIRECTSOUNDCAPTUREENUMERATEW volatile s_pfnDirectSoundCaptureEnumerateW = NULL;
+
+    PFNDIRECTSOUNDENUMERATEW        pfnDirectSoundEnumerateW          = s_pfnDirectSoundEnumerateW;
+    PFNDIRECTSOUNDCAPTUREENUMERATEW pfnDirectSoundCaptureEnumerateW   = s_pfnDirectSoundCaptureEnumerateW;
+    if (!pfnDirectSoundEnumerateW || !pfnDirectSoundCaptureEnumerateW)
+    {
+        RTLDRMOD hModDSound = NIL_RTLDRMOD;
+        int rc = RTLdrLoadSystem("dsound.dll", true /*fNoUnload*/, &hModDSound);
         if (RT_SUCCESS(rc))
         {
-            DSLOG(("DSound: Enumerating playback devices ...\n"));
-
-            HRESULT hr = pfnDirectSoundEnumerateW(&dsoundDevicesEnumCbPlayback, &EnumCtx);
-            if (FAILED(hr))
-                LogRel(("DSound: Error enumerating host playback devices: %Rhrc\n", hr));
+            rc = RTLdrGetSymbol(hModDSound, "DirectSoundEnumerateW", (void **)&pfnDirectSoundEnumerateW);
+            if (RT_SUCCESS(rc))
+                s_pfnDirectSoundEnumerateW = pfnDirectSoundEnumerateW;
+            else
+                LogRel(("DSound: Failed to get dsound.dll export DirectSoundEnumerateW: %Rrc\n", rc));
+
+            rc = RTLdrGetSymbol(hModDSound, "DirectSoundCaptureEnumerateW", (void **)&pfnDirectSoundCaptureEnumerateW);
+            if (RT_SUCCESS(rc))
+                s_pfnDirectSoundCaptureEnumerateW = pfnDirectSoundCaptureEnumerateW;
+            else
+                LogRel(("DSound: Failed to get dsound.dll export DirectSoundCaptureEnumerateW: %Rrc\n", rc));
+            RTLdrClose(hModDSound);
         }
         else
-            LogRel(("DSound: Error starting to enumerate host playback devices: %Rrc\n", rc));
-
-        /*
-         * Enumerate capture devices.
-         */
-        PFNDIRECTSOUNDCAPTUREENUMERATEW pfnDirectSoundCaptureEnumerateW = NULL;
-        rc = RTLdrGetSymbol(hDSound, "DirectSoundCaptureEnumerateW", (void**)&pfnDirectSoundCaptureEnumerateW);
-        if (RT_SUCCESS(rc))
-        {
-            DSLOG(("DSound: Enumerating capture devices ...\n"));
-
-            HRESULT hr = pfnDirectSoundCaptureEnumerateW(&dsoundDevicesEnumCbCapture, &EnumCtx);
-            if (FAILED(hr))
-                LogRel(("DSound: Error enumerating host capture devices: %Rhrc\n", hr));
-        }
-        else
-            LogRel(("DSound: Error starting to enumerate host capture devices: %Rrc\n", rc));
-
-        /*
-         * Query Information from all enumerated devices.
-         */
-        PDSOUNDDEV pDev;
-        RTListForEach(&pDevEnm->LstDevices, pDev, DSOUNDDEV, Core.ListEntry)
-        {
-            dsoundDeviceQueryInfo(pThis, pDev); /* ignore rc */
-        }
-
-        RTLdrClose(hDSound);
+            LogRel(("DSound: Unable to load dsound.dll for enumerating devices: %Rrc\n", rc));
+        if (!pfnDirectSoundEnumerateW && !pfnDirectSoundCaptureEnumerateW)
+            return rc;
+    }
+
+    /* Common callback context for both playback and capture enumerations: */
+    DSOUNDENUMCBCTX EnumCtx;
+    EnumCtx.fFlags  = 0;
+    EnumCtx.pDevEnm = pDevEnm;
+
+    /* Enumerate playback devices. */
+    if (pfnDirectSoundEnumerateW)
+    {
+        DSLOG(("DSound: Enumerating playback devices ...\n"));
+        HRESULT hr = pfnDirectSoundEnumerateW(&drvHostDSoundEnumOldStylePlaybackCallback, &EnumCtx);
+        if (FAILED(hr))
+            LogRel(("DSound: Error enumerating host playback devices: %Rhrc\n", hr));
+    }
+
+    /* Enumerate capture devices. */
+    if (pfnDirectSoundCaptureEnumerateW)
+    {
+        DSLOG(("DSound: Enumerating capture devices ...\n"));
+        HRESULT hr = pfnDirectSoundCaptureEnumerateW(&drvHostDSoundEnumOldStyleCaptureCallback, &EnumCtx);
+        if (FAILED(hr))
+            LogRel(("DSound: Error enumerating host capture devices: %Rhrc\n", hr));
     }
     else
-    {
-        /* No dsound.dll on this system. */
-        LogRel(("DSound: Could not load dsound.dll for enumerating devices: %Rrc\n", rc));
+        LogRel(("DSound: Error starting to enumerate host capture devices: %Rrc\n", rc));
+
+    /*
+     * Query Information for all enumerated devices.
+     * Note! This is problematic to do from the enumeration callbacks.
+     */
+    PDSOUNDDEV pDev;
+    RTListForEach(&pDevEnm->LstDevices, pDev, DSOUNDDEV, Core.ListEntry)
+    {
+        drvHostDSoundEnumOldStylQueryDeviceInfo(pDev); /* ignore rc */
     }
 
     DSLOG(("DSound: Enumerating devices done\n"));
 
-    return rc;
+    return VINF_SUCCESS;
 }
 
@@ -1162,20 +1167,11 @@
 static DECLCALLBACK(int) drvHostDSoundHA_GetDevices(PPDMIHOSTAUDIO pInterface, PPDMAUDIOHOSTENUM pDeviceEnum)
 {
-    AssertPtrReturn(pInterface,  VERR_INVALID_POINTER);
+    RT_NOREF(pInterface);
     AssertPtrReturn(pDeviceEnum, VERR_INVALID_POINTER);
 
-    PDRVHOSTDSOUND pThis = PDMIHOSTAUDIO_2_DRVHOSTDSOUND(pInterface);
-
-    int rc = RTCritSectEnter(&pThis->CritSect);
-    if (RT_SUCCESS(rc))
-    {
-        PDMAudioHostEnumInit(pDeviceEnum);
-        rc = dsoundDevicesEnumerate(pThis, pDeviceEnum);
-        if (RT_FAILURE(rc))
-            PDMAudioHostEnumDelete(pDeviceEnum);
-
-        int rc2 = RTCritSectLeave(&pThis->CritSect);
-        AssertRC(rc2);
-    }
+    PDMAudioHostEnumInit(pDeviceEnum);
+    int rc = drvHostDSoundEnumerateDevices(pDeviceEnum);
+    if (RT_FAILURE(rc))
+        PDMAudioHostEnumDelete(pDeviceEnum);
 
     LogFlowFunc(("Returning %Rrc\n", rc));
@@ -1496,7 +1492,4 @@
     AssertPtrReturn(pCfgReq,   E_POINTER);
     AssertPtrReturn(pCfgAcq,   E_POINTER);
-
-/** @todo r=bird: I cannot see any code populating pCfgAcq... */
-
     LogFlowFuncEnter();
 
@@ -1527,8 +1520,5 @@
            wfx.cbSize));
 
-    /** @todo r=bird: Why is this called every time?  It triggers a device
-     * enumeration. Andy claimed on IRC that enumeration was only done once...
-     * It's generally a 'ing waste of time here too, as we dont really use any of
-     * the information we gather there. */
+    /* Waste some time: */
     dsoundUpdateStatusInternal(pThis);
 
