Commit c8c6cc97 authored by Andrew Eikum's avatar Andrew Eikum Committed by Alexandre Julliard

dsound: Always enumerate the default device first.

parent f05a8f89
...@@ -478,6 +478,47 @@ HRESULT get_mmdevice(EDataFlow flow, const GUID *tgt, IMMDevice **device) ...@@ -478,6 +478,47 @@ HRESULT get_mmdevice(EDataFlow flow, const GUID *tgt, IMMDevice **device)
return DSERR_INVALIDPARAM; 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_FALSE means the callback returned FALSE at some point
* S_OK means the callback always returned TRUE */ * S_OK means the callback always returned TRUE */
HRESULT enumerate_mmdevices(EDataFlow flow, GUID *guids, HRESULT enumerate_mmdevices(EDataFlow flow, GUID *guids,
...@@ -485,7 +526,8 @@ HRESULT enumerate_mmdevices(EDataFlow flow, GUID *guids, ...@@ -485,7 +526,8 @@ HRESULT enumerate_mmdevices(EDataFlow flow, GUID *guids,
{ {
IMMDeviceEnumerator *devenum; IMMDeviceEnumerator *devenum;
IMMDeviceCollection *coll; IMMDeviceCollection *coll;
UINT count, i; IMMDevice *defdev = NULL;
UINT count, i, n;
BOOL keep_going; BOOL keep_going;
HRESULT hr; HRESULT hr;
...@@ -514,14 +556,24 @@ HRESULT enumerate_mmdevices(EDataFlow flow, GUID *guids, ...@@ -514,14 +556,24 @@ HRESULT enumerate_mmdevices(EDataFlow flow, GUID *guids,
if(count == 0) if(count == 0)
return DS_OK; return DS_OK;
TRACE("Calling back with NULL (%s)\n", wine_dbgstr_w(primary_desc));
keep_going = cb(NULL, primary_desc, empty_drv, user); 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){ for(i = 0; keep_going && i < count; ++i){
IMMDevice *device; IMMDevice *device;
IPropertyStore *ps;
PROPVARIANT pv;
PropVariantInit(&pv);
hr = IMMDeviceCollection_Item(coll, i, &device); hr = IMMDeviceCollection_Item(coll, i, &device);
if(FAILED(hr)){ if(FAILED(hr)){
...@@ -529,36 +581,16 @@ HRESULT enumerate_mmdevices(EDataFlow flow, GUID *guids, ...@@ -529,36 +581,16 @@ HRESULT enumerate_mmdevices(EDataFlow flow, GUID *guids,
continue; continue;
} }
hr = IMMDevice_OpenPropertyStore(device, STGM_READ, &ps); if(device != defdev){
if(FAILED(hr)){ send_device(device, &guids[n], cb, user);
IMMDevice_Release(device); ++n;
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;
} }
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); IMMDevice_Release(device);
} }
if(defdev)
IMMDevice_Release(defdev);
IMMDeviceCollection_Release(coll); IMMDeviceCollection_Release(coll);
return (keep_going == TRUE) ? S_OK : S_FALSE; return (keep_going == TRUE) ? S_OK : S_FALSE;
......
...@@ -25,6 +25,8 @@ ...@@ -25,6 +25,8 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/ */
#define COBJMACROS
#define NONAMELESSUNION
#include <windows.h> #include <windows.h>
#include <stdio.h> #include <stdio.h>
...@@ -35,6 +37,13 @@ ...@@ -35,6 +37,13 @@
#include "ks.h" #include "ks.h"
#include "ksmedia.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" #include "dsound_test.h"
static HRESULT (WINAPI *pDirectSoundEnumerateA)(LPDSENUMCALLBACKA,LPVOID)=NULL; static HRESULT (WINAPI *pDirectSoundEnumerateA)(LPDSENUMCALLBACKA,LPVOID)=NULL;
...@@ -1043,6 +1052,70 @@ static void test_hw_buffers(void) ...@@ -1043,6 +1052,70 @@ static void test_hw_buffers(void)
IDirectSound8_Release(ds); 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) START_TEST(dsound8)
{ {
HMODULE hDsound; HMODULE hDsound;
...@@ -1062,6 +1135,7 @@ START_TEST(dsound8) ...@@ -1062,6 +1135,7 @@ START_TEST(dsound8)
IDirectSound8_tests(); IDirectSound8_tests();
dsound8_tests(); dsound8_tests();
test_hw_buffers(); test_hw_buffers();
test_first_device();
} }
else else
skip("dsound8 test skipped\n"); skip("dsound8 test skipped\n");
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment