Andrew Eikum : dsound: Always enumerate the default device first.
Alexandre Julliard
julliard at winehq.org
Fri Oct 21 11:01:59 CDT 2011
Module: wine
Branch: master
Commit: c8c6cc97bcaab5441ea200041bb7cc99c4ba01fb
URL: http://source.winehq.org/git/wine.git/?a=commit;h=c8c6cc97bcaab5441ea200041bb7cc99c4ba01fb
Author: Andrew Eikum <aeikum at codeweavers.com>
Date: Thu Oct 20 15:15:09 2011 -0500
dsound: Always enumerate the default device first.
---
dlls/dsound/dsound_main.c | 92 +++++++++++++++++++++++++++++--------------
dlls/dsound/tests/dsound8.c | 74 ++++++++++++++++++++++++++++++++++
2 files changed, 136 insertions(+), 30 deletions(-)
diff --git a/dlls/dsound/dsound_main.c b/dlls/dsound/dsound_main.c
index 02edf88..c5b6dce 100644
--- a/dlls/dsound/dsound_main.c
+++ b/dlls/dsound/dsound_main.c
@@ -478,6 +478,47 @@ HRESULT get_mmdevice(EDataFlow flow, const GUID *tgt, IMMDevice **device)
return DSERR_INVALIDPARAM;
}
+static BOOL send_device(IMMDevice *device, GUID *guid,
+ LPDSENUMCALLBACKW cb, void *user)
+{
+ IPropertyStore *ps;
+ PROPVARIANT pv;
+ BOOL keep_going;
+ HRESULT hr;
+
+ PropVariantInit(&pv);
+
+ hr = IMMDevice_OpenPropertyStore(device, STGM_READ, &ps);
+ if(FAILED(hr)){
+ WARN("OpenPropertyStore failed: %08x\n", hr);
+ return TRUE;
+ }
+
+ hr = get_mmdevice_guid(device, ps, guid);
+ if(FAILED(hr)){
+ IPropertyStore_Release(ps);
+ return TRUE;
+ }
+
+ hr = IPropertyStore_GetValue(ps,
+ (const PROPERTYKEY *)&DEVPKEY_Device_FriendlyName, &pv);
+ if(FAILED(hr)){
+ IPropertyStore_Release(ps);
+ WARN("GetValue(FriendlyName) failed: %08x\n", hr);
+ return TRUE;
+ }
+
+ TRACE("Calling back with %s (%s)\n", wine_dbgstr_guid(guid),
+ wine_dbgstr_w(pv.u.pwszVal));
+
+ keep_going = cb(guid, pv.u.pwszVal, wine_vxd_drv, user);
+
+ PropVariantClear(&pv);
+ IPropertyStore_Release(ps);
+
+ return keep_going;
+}
+
/* S_FALSE means the callback returned FALSE at some point
* S_OK means the callback always returned TRUE */
HRESULT enumerate_mmdevices(EDataFlow flow, GUID *guids,
@@ -485,7 +526,8 @@ HRESULT enumerate_mmdevices(EDataFlow flow, GUID *guids,
{
IMMDeviceEnumerator *devenum;
IMMDeviceCollection *coll;
- UINT count, i;
+ IMMDevice *defdev = NULL;
+ UINT count, i, n;
BOOL keep_going;
HRESULT hr;
@@ -514,14 +556,24 @@ HRESULT enumerate_mmdevices(EDataFlow flow, GUID *guids,
if(count == 0)
return DS_OK;
+ TRACE("Calling back with NULL (%s)\n", wine_dbgstr_w(primary_desc));
keep_going = cb(NULL, primary_desc, empty_drv, user);
+ /* always send the default device first */
+ if(keep_going){
+ hr = IMMDeviceEnumerator_GetDefaultAudioEndpoint(devenum, flow,
+ eMultimedia, &defdev);
+ if(FAILED(hr)){
+ defdev = NULL;
+ n = 0;
+ }else{
+ keep_going = send_device(defdev, &guids[0], cb, user);
+ n = 1;
+ }
+ }
+
for(i = 0; keep_going && i < count; ++i){
IMMDevice *device;
- IPropertyStore *ps;
- PROPVARIANT pv;
-
- PropVariantInit(&pv);
hr = IMMDeviceCollection_Item(coll, i, &device);
if(FAILED(hr)){
@@ -529,36 +581,16 @@ HRESULT enumerate_mmdevices(EDataFlow flow, GUID *guids,
continue;
}
- hr = IMMDevice_OpenPropertyStore(device, STGM_READ, &ps);
- if(FAILED(hr)){
- IMMDevice_Release(device);
- WARN("OpenPropertyStore failed: %08x\n", hr);
- continue;
- }
-
- hr = get_mmdevice_guid(device, ps, &guids[i]);
- if(FAILED(hr)){
- IPropertyStore_Release(ps);
- IMMDevice_Release(device);
- continue;
+ if(device != defdev){
+ send_device(device, &guids[n], cb, user);
+ ++n;
}
- hr = IPropertyStore_GetValue(ps,
- (const PROPERTYKEY *)&DEVPKEY_Device_FriendlyName, &pv);
- if(FAILED(hr)){
- IPropertyStore_Release(ps);
- IMMDevice_Release(device);
- WARN("GetValue(FriendlyName) failed: %08x\n", hr);
- continue;
- }
-
- keep_going = cb(&guids[i], pv.u.pwszVal, wine_vxd_drv, user);
-
- PropVariantClear(&pv);
- IPropertyStore_Release(ps);
IMMDevice_Release(device);
}
+ if(defdev)
+ IMMDevice_Release(defdev);
IMMDeviceCollection_Release(coll);
return (keep_going == TRUE) ? S_OK : S_FALSE;
diff --git a/dlls/dsound/tests/dsound8.c b/dlls/dsound/tests/dsound8.c
index 9489970..c1e672f 100644
--- a/dlls/dsound/tests/dsound8.c
+++ b/dlls/dsound/tests/dsound8.c
@@ -25,6 +25,8 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
+#define COBJMACROS
+#define NONAMELESSUNION
#include <windows.h>
#include <stdio.h>
@@ -35,6 +37,13 @@
#include "ks.h"
#include "ksmedia.h"
+#include "initguid.h"
+#include "wingdi.h"
+#include "mmdeviceapi.h"
+#include "audioclient.h"
+#include "propkey.h"
+#include "devpkey.h"
+
#include "dsound_test.h"
static HRESULT (WINAPI *pDirectSoundEnumerateA)(LPDSENUMCALLBACKA,LPVOID)=NULL;
@@ -1043,6 +1052,70 @@ static void test_hw_buffers(void)
IDirectSound8_Release(ds);
}
+static struct {
+ UINT dev_count;
+ GUID guid;
+} default_info = { 0 };
+
+static BOOL WINAPI default_device_cb(GUID *guid, const char *desc,
+ const char *module, void *user)
+{
+ trace("guid: %p, desc: %s\n", guid, desc);
+ if(!guid)
+ ok(default_info.dev_count == 0, "Got NULL GUID not in first position\n");
+ else{
+ if(default_info.dev_count == 0){
+ ok(IsEqualGUID(guid, &default_info.guid), "Expected default device GUID\n");
+ }else{
+ ok(!IsEqualGUID(guid, &default_info.guid), "Got default GUID at unexpected location: %u\n",
+ default_info.dev_count);
+ }
+
+ /* only count real devices */
+ ++default_info.dev_count;
+ }
+
+ return TRUE;
+}
+
+static void test_first_device(void)
+{
+ IMMDeviceEnumerator *devenum;
+ IMMDevice *defdev;
+ IPropertyStore *ps;
+ PROPVARIANT pv;
+ HRESULT hr;
+
+ hr = CoCreateInstance(&CLSID_MMDeviceEnumerator, NULL,
+ CLSCTX_INPROC_SERVER, &IID_IMMDeviceEnumerator, (void**)&devenum);
+ if(FAILED(hr)){
+ win_skip("MMDevAPI is not available, skipping default device test\n");
+ return;
+ }
+
+ hr = IMMDeviceEnumerator_GetDefaultAudioEndpoint(devenum, eRender,
+ eMultimedia, &defdev);
+ ok(hr == S_OK, "GetDefaultAudioEndpoint failed: %08x\n", hr);
+
+ hr = IMMDevice_OpenPropertyStore(defdev, STGM_READ, &ps);
+ ok(hr == S_OK, "OpenPropertyStore failed: %08x\n", hr);
+
+ PropVariantInit(&pv);
+
+ hr = IPropertyStore_GetValue(ps, &PKEY_AudioEndpoint_GUID, &pv);
+ ok(hr == S_OK, "GetValue failed: %08x\n", hr);
+
+ CLSIDFromString(pv.u.pwszVal, &default_info.guid);
+
+ PropVariantClear(&pv);
+ IPropertyStore_Release(ps);
+ IMMDevice_Release(defdev);
+ IMMDeviceEnumerator_Release(devenum);
+
+ hr = pDirectSoundEnumerateA(&default_device_cb, NULL);
+ ok(hr == S_OK, "DirectSoundEnumerateA failed: %08x\n", hr);
+}
+
START_TEST(dsound8)
{
HMODULE hDsound;
@@ -1062,6 +1135,7 @@ START_TEST(dsound8)
IDirectSound8_tests();
dsound8_tests();
test_hw_buffers();
+ test_first_device();
}
else
skip("dsound8 test skipped\n");
More information about the wine-cvs
mailing list