Andrew Eikum : mmdevapi: Only enumerate devices that can be opened during initialization.

Alexandre Julliard julliard at winehq.org
Thu Jul 14 13:08:15 CDT 2011


Module: wine
Branch: master
Commit: 2174717fbd01565f7ba1596078cf0c0ccfc02504
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=2174717fbd01565f7ba1596078cf0c0ccfc02504

Author: Andrew Eikum <aeikum at codeweavers.com>
Date:   Wed Jul 13 14:30:45 2011 -0500

mmdevapi: Only enumerate devices that can be opened during initialization.

---

 dlls/winealsa.drv/mmdevdrv.c |   18 +++++++++++++++---
 dlls/wineoss.drv/mmdevdrv.c  |   12 ++++++++++++
 2 files changed, 27 insertions(+), 3 deletions(-)

diff --git a/dlls/winealsa.drv/mmdevdrv.c b/dlls/winealsa.drv/mmdevdrv.c
index eda8435..080887a 100644
--- a/dlls/winealsa.drv/mmdevdrv.c
+++ b/dlls/winealsa.drv/mmdevdrv.c
@@ -229,19 +229,22 @@ static HRESULT alsa_get_card_devices(EDataFlow flow, WCHAR **ids, char **keys,
     static const WCHAR dashW[] = {' ','-',' ',0};
     int err, device;
     snd_pcm_info_t *info;
+    snd_pcm_stream_t stream = (flow == eRender ? SND_PCM_STREAM_PLAYBACK :
+        SND_PCM_STREAM_CAPTURE);
 
     info = HeapAlloc(GetProcessHeap(), 0, snd_pcm_info_sizeof());
     if(!info)
         return E_OUTOFMEMORY;
 
     snd_pcm_info_set_subdevice(info, 0);
-    snd_pcm_info_set_stream(info,
-            flow == eRender ? SND_PCM_STREAM_PLAYBACK : SND_PCM_STREAM_CAPTURE);
+    snd_pcm_info_set_stream(info, stream);
 
     device = -1;
     for(err = snd_ctl_pcm_next_device(ctl, &device); device != -1 && err >= 0;
             err = snd_ctl_pcm_next_device(ctl, &device)){
         const char *devname;
+        char devnode[32];
+        snd_pcm_t *handle;
 
         snd_pcm_info_set_device(info, device);
 
@@ -255,6 +258,15 @@ static HRESULT alsa_get_card_devices(EDataFlow flow, WCHAR **ids, char **keys,
             continue;
         }
 
+        sprintf(devnode, "hw:%d,%d", card, device);
+        if((err = snd_pcm_open(&handle, devnode, stream, SND_PCM_NONBLOCK)) < 0){
+            WARN("The device \"%s\" failed to open, pretending it doesn't exist: %d (%s)\n",
+                    devnode, err, snd_strerror(err));
+            continue;
+        }
+
+        snd_pcm_close(handle);
+
         if(ids && keys){
             DWORD len, cardlen;
 
@@ -286,7 +298,7 @@ static HRESULT alsa_get_card_devices(EDataFlow flow, WCHAR **ids, char **keys,
                 HeapFree(GetProcessHeap(), 0, ids[*num]);
                 return E_OUTOFMEMORY;
             }
-            sprintf(keys[*num], "hw:%d,%d", card, device);
+            memcpy(keys[*num], devnode, sizeof(devnode));
         }
 
         ++(*num);
diff --git a/dlls/wineoss.drv/mmdevdrv.c b/dlls/wineoss.drv/mmdevdrv.c
index 2b631f9..32e9354 100644
--- a/dlls/wineoss.drv/mmdevdrv.c
+++ b/dlls/wineoss.drv/mmdevdrv.c
@@ -285,6 +285,7 @@ HRESULT WINAPI AUDDRV_GetEndpointIDs(EDataFlow flow, WCHAR ***ids, void ***keys,
     *def_index = -1;
     for(i = 0; i < sysinfo.numaudios; ++i){
         oss_audioinfo ai = {0};
+        int fd;
 
         ai.dev = i;
         if(ioctl(mixer_fd, SNDCTL_AUDIOINFO, &ai) < 0){
@@ -293,6 +294,17 @@ HRESULT WINAPI AUDDRV_GetEndpointIDs(EDataFlow flow, WCHAR ***ids, void ***keys,
             continue;
         }
 
+        if(flow == eRender)
+            fd = open(ai.devnode, O_WRONLY, 0);
+        else
+            fd = open(ai.devnode, O_RDONLY, 0);
+        if(fd < 0){
+            WARN("Opening device \"%s\" failed, pretending it doesn't exist: %d (%s)",
+                    ai.devnode, errno, strerror(errno));
+            continue;
+        }
+        close(fd);
+
         if((flow == eCapture && (ai.caps & PCM_CAP_INPUT)) ||
                 (flow == eRender && (ai.caps & PCM_CAP_OUTPUT))){
             size_t len;




More information about the wine-cvs mailing list