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;
|
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,
|
||||||
{
|
{
|
||||||
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,
|
||||||
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,
|
||||||
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 @@
|
||||||
* 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 @@
|
||||||
#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)
|
||||||
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)
|
||||||
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");
|
||||||
|
|
Loading…
Reference in New Issue