dsound: Always enumerate the default device first.
This commit is contained in:
parent
f05a8f89f4
commit
c8c6cc97bc
|
@ -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;
|
||||
if(device != defdev){
|
||||
send_device(device, &guids[n], cb, user);
|
||||
++n;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
if(defdev)
|
||||
IMMDevice_Release(defdev);
|
||||
IMMDeviceCollection_Release(coll);
|
||||
|
||||
return (keep_going == TRUE) ? S_OK : S_FALSE;
|
||||
|
|
|
@ -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");
|
||||
|
|
Loading…
Reference in New Issue