Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/devenum/createdevenum.c | 131 +++++++++++++++++++++++++---------------- dlls/devenum/devenum.rc | 1 - dlls/devenum/devenum_private.h | 1 - dlls/devenum/tests/Makefile.in | 2 +- dlls/devenum/tests/devenum.c | 109 ++++++++++++++++++++++++++++++++++ 5 files changed, 190 insertions(+), 54 deletions(-)
diff --git a/dlls/devenum/createdevenum.c b/dlls/devenum/createdevenum.c index 6884ffc..e3fe049 100644 --- a/dlls/devenum/createdevenum.c +++ b/dlls/devenum/createdevenum.c @@ -594,6 +594,85 @@ cleanup: return TRUE; }
+static void register_waveout_devices(void) +{ + static const WCHAR defaultW[] = {'D','e','f','a','u','l','t',' ','W','a','v','e','O','u','t',' ','D','e','v','i','c','e',0}; + static const WCHAR waveoutidW[] = {'W','a','v','e','O','u','t','I','d',0}; + IPropertyBag *prop_bag = NULL; + REGFILTERPINS2 rgpins = {0}; + REGPINTYPES rgtypes = {0}; + REGFILTER2 rgf = {0}; + WCHAR clsid[CHARS_IN_GUID]; + IMoniker *mon = NULL; + WAVEOUTCAPSW caps; + int i, count; + VARIANT var; + HRESULT hr; + + hr = DEVENUM_CreateAMCategoryKey(&CLSID_AudioRendererCategory); + if (FAILED(hr)) return; + + count = waveOutGetNumDevs(); + + for (i = -1; i < count; i++) + { + waveOutGetDevCapsW(i, &caps, sizeof(caps)); + + V_VT(&var) = VT_BSTR; + + if (i == -1) /* WAVE_MAPPER */ + V_BSTR(&var) = SysAllocString(defaultW); + else + V_BSTR(&var) = SysAllocString(caps.szPname); + if (!(V_BSTR(&var))) + goto cleanup; + + hr = register_codec(&CLSID_AudioRendererCategory, V_BSTR(&var), &mon); + if (FAILED(hr)) goto cleanup; + + hr = IMoniker_BindToStorage(mon, NULL, NULL, &IID_IPropertyBag, (void **)&prop_bag); + if (FAILED(hr)) goto cleanup; + + /* write friendly name */ + hr = IPropertyBag_Write(prop_bag, wszFriendlyName, &var); + if (FAILED(hr)) goto cleanup; + VariantClear(&var); + + /* write clsid */ + V_VT(&var) = VT_BSTR; + StringFromGUID2(&CLSID_AudioRender, clsid, CHARS_IN_GUID); + if (!(V_BSTR(&var) = SysAllocString(clsid))) + goto cleanup; + hr = IPropertyBag_Write(prop_bag, clsid_keyname, &var); + if (FAILED(hr)) goto cleanup; + VariantClear(&var); + + /* write filter data */ + rgf.dwVersion = 2; + rgf.dwMerit = MERIT_DO_NOT_USE; + rgf.u.s2.cPins2 = 1; + rgf.u.s2.rgPins2 = &rgpins; + rgpins.dwFlags = REG_PINFLAG_B_RENDERER; + rgpins.nMediaTypes = 1; + rgpins.lpMediaType = &rgtypes; + rgtypes.clsMajorType = &MEDIATYPE_Audio; + rgtypes.clsMinorType = &MEDIASUBTYPE_NULL; + + write_filter_data(prop_bag, &rgf); + + /* write WaveOutId */ + V_VT(&var) = VT_I4; + V_I4(&var) = i; + hr = IPropertyBag_Write(prop_bag, waveoutidW, &var); + if (FAILED(hr)) goto cleanup; + +cleanup: + VariantClear(&var); + if (prop_bag) IPropertyBag_Release(prop_bag); + if (mon) IMoniker_Release(mon); + } +} + /********************************************************************** * DEVENUM_ICreateDevEnum_CreateClassEnumerator */ @@ -616,6 +695,7 @@ static HRESULT WINAPI DEVENUM_ICreateDevEnum_CreateClassEnumerator( register_legacy_filters(); hr = DirectSoundEnumerateW(®ister_dsound_devices, NULL); if (FAILED(hr)) return hr; + register_waveout_devices();
return create_EnumMoniker(clsidDeviceClass, ppEnumMoniker); } @@ -752,62 +832,11 @@ static HRESULT register_codecs(void) if (SUCCEEDED(res)) { UINT i; - WAVEOUTCAPSW wocaps; WAVEINCAPSW wicaps; MIDIOUTCAPSW mocaps; REGPINTYPES * pTypes; IPropertyBag * pPropBag = NULL;
- numDevs = waveOutGetNumDevs(); - - res = DEVENUM_CreateAMCategoryKey(&CLSID_AudioRendererCategory); - if (FAILED(res)) /* can't register any devices in this category */ - numDevs = 0; - - rfp2.dwFlags = REG_PINFLAG_B_RENDERER; - for (i = 0; i < numDevs; i++) - { - if (waveOutGetDevCapsW(i, &wocaps, sizeof(WAVEOUTCAPSW)) - == MMSYSERR_NOERROR) - { - IMoniker * pMoniker = NULL; - - rfp2.nMediaTypes = 1; - pTypes = CoTaskMemAlloc(rfp2.nMediaTypes * sizeof(REGPINTYPES)); - if (!pTypes) - { - IFilterMapper2_Release(pMapper); - return E_OUTOFMEMORY; - } - /* FIXME: Native devenum seems to register a lot more types for - * DSound than we do. Not sure what purpose they serve */ - pTypes[0].clsMajorType = &MEDIATYPE_Audio; - pTypes[0].clsMinorType = &MEDIASUBTYPE_PCM; - - rfp2.lpMediaType = pTypes; - - res = IFilterMapper2_RegisterFilter(pMapper, - &CLSID_AudioRender, - wocaps.szPname, - &pMoniker, - &CLSID_AudioRendererCategory, - wocaps.szPname, - &rf2); - - /* FIXME: do additional stuff with IMoniker here, depending on what RegisterFilter does */ - - if (pMoniker) - IMoniker_Release(pMoniker); - - if (i == iDefaultDevice) - { - FIXME("Default device\n"); - } - - CoTaskMemFree(pTypes); - } - } - numDevs = waveInGetNumDevs();
res = DEVENUM_CreateAMCategoryKey(&CLSID_AudioInputDeviceCategory); diff --git a/dlls/devenum/devenum.rc b/dlls/devenum/devenum.rc index d9262e1..95e39d6 100644 --- a/dlls/devenum/devenum.rc +++ b/dlls/devenum/devenum.rc @@ -29,7 +29,6 @@ LANGUAGE LANG_ENGLISH, SUBLANG_DEFAULT
STRINGTABLE { - IDS_DEVENUM_WODEFAULT "Default WaveOut Device" IDS_DEVENUM_MIDEFAULT "Default MidiOut Device" }
diff --git a/dlls/devenum/devenum_private.h b/dlls/devenum/devenum_private.h index 93147ad..c891083 100644 --- a/dlls/devenum/devenum_private.h +++ b/dlls/devenum/devenum_private.h @@ -101,7 +101,6 @@ extern const WCHAR clsid_keyname[6] DECLSPEC_HIDDEN; /********************************************************************** * Resource IDs */ -#define IDS_DEVENUM_WODEFAULT 9 #define IDS_DEVENUM_MIDEFAULT 10 #define IDS_DEVENUM_KSDEFAULT 11 #define IDS_DEVENUM_KS 12 diff --git a/dlls/devenum/tests/Makefile.in b/dlls/devenum/tests/Makefile.in index 028ba27..a673f20 100644 --- a/dlls/devenum/tests/Makefile.in +++ b/dlls/devenum/tests/Makefile.in @@ -1,5 +1,5 @@ TESTDLL = devenum.dll -IMPORTS = advapi32 dsound oleaut32 ole32 +IMPORTS = advapi32 dsound oleaut32 ole32 winmm
C_SRCS = \ devenum.c diff --git a/dlls/devenum/tests/devenum.c b/dlls/devenum/tests/devenum.c index c4bf8af..79f5ed8 100644 --- a/dlls/devenum/tests/devenum.c +++ b/dlls/devenum/tests/devenum.c @@ -30,6 +30,7 @@ #include "vfwmsgs.h" #include "mmsystem.h" #include "dsound.h" +#include "mmddk.h"
DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0);
@@ -37,11 +38,25 @@ static const WCHAR friendly_name[] = {'F','r','i','e','n','d','l','y','N','a','m static const WCHAR fcc_handlerW[] = {'F','c','c','H','a','n','d','l','e','r',0}; static const WCHAR deviceW[] = {'@','d','e','v','i','c','e',':',0}; static const WCHAR clsidW[] = {'C','L','S','I','D',0}; +static const WCHAR waveW[] = {'w','a','v','e',':',0}; static const WCHAR mrleW[] = {'m','r','l','e',0}; static const WCHAR swW[] = {'s','w',':',0}; static const WCHAR cmW[] = {'c','m',':',0}; static const WCHAR backslashW[] = {'\',0};
+static inline WCHAR *strchrW( const WCHAR *str, WCHAR ch ) +{ + do { if (*str == ch) return (WCHAR *)str; } while (*str++); + return NULL; +} + +static inline int strncmpW( const WCHAR *str1, const WCHAR *str2, int n ) +{ + if (n <= 0) return 0; + while ((--n > 0) && *str1 && (*str1 == *str2)) { str1++; str2++; } + return *str1 - *str2; +} + static void test_devenum(IBindCtx *bind_ctx) { IEnumMoniker *enum_cat, *enum_moniker; @@ -618,6 +633,99 @@ static BOOL CALLBACK test_dsound(GUID *guid, const WCHAR *desc, const WCHAR *mod return TRUE; }
+static void test_waveout(void) +{ + static const WCHAR defaultW[] = {'D','e','f','a','u','l','t',' ','W','a','v','e','O','u','t',' ','D','e','v','i','c','e',0}; + static const WCHAR waveoutidW[] = {'W','a','v','e','O','u','t','I','d',0}; + IParseDisplayName *parser; + IPropertyBag *prop_bag; + IMoniker *mon; + WCHAR endpoint[200]; + WAVEOUTCAPSW caps; + WCHAR buffer[200]; + const WCHAR *name; + MMRESULT mmr; + int count, i; + VARIANT var; + HRESULT hr; + + hr = CoCreateInstance(&CLSID_CDeviceMoniker, NULL, CLSCTX_INPROC, &IID_IParseDisplayName, (void **)&parser); + ok(hr == S_OK, "Failed to create ParseDisplayName: %#x\n", hr); + + count = waveOutGetNumDevs(); + + for (i = -1; i < count; i++) + { + waveOutGetDevCapsW(i, &caps, sizeof(caps)); + + if (i == -1) /* WAVE_MAPPER */ + name = defaultW; + else + name = caps.szPname; + + lstrcpyW(buffer, deviceW); + lstrcatW(buffer, cmW); + StringFromGUID2(&CLSID_AudioRendererCategory, buffer + lstrlenW(buffer), CHARS_IN_GUID); + lstrcatW(buffer, backslashW); + lstrcatW(buffer, name); + + mon = check_display_name(parser, buffer); + + hr = IMoniker_BindToStorage(mon, NULL, NULL, &IID_IPropertyBag, (void **)&prop_bag); + ok(hr == S_OK, "BindToStorage failed: %#x\n", hr); + + VariantInit(&var); + hr = IPropertyBag_Read(prop_bag, friendly_name, &var, NULL); + if (hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)) + { + IPropertyBag_Release(prop_bag); + IMoniker_Release(mon); + + /* Win8+ uses the endpoint GUID instead of the device name */ + mmr = waveOutMessage((HWAVEOUT)(DWORD_PTR) i, DRV_QUERYFUNCTIONINSTANCEID, + (DWORD_PTR) endpoint, sizeof(endpoint)); + ok(!mmr, "waveOutMessage failed: %u\n", mmr); + + lstrcpyW(buffer, deviceW); + lstrcatW(buffer, cmW); + StringFromGUID2(&CLSID_AudioRendererCategory, buffer + lstrlenW(buffer), CHARS_IN_GUID); + lstrcatW(buffer, backslashW); + lstrcatW(buffer, waveW); + lstrcatW(buffer, strchrW(endpoint, '}') + 2); + + mon = check_display_name(parser, buffer); + + hr = IMoniker_BindToStorage(mon, NULL, NULL, &IID_IPropertyBag, (void **)&prop_bag); + ok(hr == S_OK, "BindToStorage failed: %#x\n", hr); + + hr = IPropertyBag_Read(prop_bag, friendly_name, &var, NULL); + } + ok(hr == S_OK, "Read failed: %#x\n", hr); + + ok(!strncmpW(name, V_BSTR(&var), lstrlenW(name)), "expected %s, got %s\n", + wine_dbgstr_w(name), wine_dbgstr_w(V_BSTR(&var))); + + VariantClear(&var); + hr = IPropertyBag_Read(prop_bag, clsidW, &var, NULL); + ok(hr == S_OK, "Read failed: %#x\n", hr); + + StringFromGUID2(&CLSID_AudioRender, buffer, CHARS_IN_GUID); + ok(!lstrcmpW(buffer, V_BSTR(&var)), "expected %s, got %s\n", + wine_dbgstr_w(buffer), wine_dbgstr_w(V_BSTR(&var))); + + VariantClear(&var); + hr = IPropertyBag_Read(prop_bag, waveoutidW, &var, NULL); + ok(hr == S_OK, "Read failed: %#x\n", hr); + + ok(V_I4(&var) == i, "expected %d, got %d\n", i, V_I4(&var)); + + IPropertyBag_Release(prop_bag); + IMoniker_Release(mon); + } + + IParseDisplayName_Release(parser); +} + START_TEST(devenum) { IBindCtx *bind_ctx = NULL; @@ -643,6 +751,7 @@ START_TEST(devenum) test_legacy_filter(); hr = DirectSoundEnumerateW(test_dsound, NULL); ok(hr == S_OK, "got %#x\n", hr); + test_waveout();
CoUninitialize(); }
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/dsound/tests/capture.c | 4 ++-- dlls/dsound/tests/ds3d.c | 30 +++++++++--------------------- dlls/dsound/tests/ds3d8.c | 11 ----------- dlls/dsound/tests/dsound.c | 5 +++-- dlls/dsound/tests/dsound8.c | 34 +++++++++++++++++----------------- dlls/dsound/tests/duplex.c | 6 +++--- 6 files changed, 34 insertions(+), 56 deletions(-)
diff --git a/dlls/dsound/tests/capture.c b/dlls/dsound/tests/capture.c index 4eae28b..a23d1eb 100644 --- a/dlls/dsound/tests/capture.c +++ b/dlls/dsound/tests/capture.c @@ -114,7 +114,7 @@ static void IDirectSoundCapture_test(LPDIRECTSOUNDCAPTURE dsco, ok(rc==DS_OK, "IDirectSoundCapture_QueryInterface(IID_IUnknown) " "failed: %08x\n", rc); if (rc==DS_OK) - IDirectSoundCapture_Release(unknown); + IUnknown_Release(unknown);
rc=IDirectSoundCapture_QueryInterface(dsco, &IID_IDirectSoundCapture, (LPVOID*)&dsc); @@ -162,7 +162,7 @@ static void IDirectSoundCapture_test(LPDIRECTSOUNDCAPTURE dsco, ZeroMemory(&dsccaps, sizeof(dsccaps));
/* DSOUND: Error: Invalid caps buffer */ - rc=IDirectSound_GetCaps(dsco, &dsccaps); + rc=IDirectSoundCapture_GetCaps(dsco, &dsccaps); ok(rc==DSERR_INVALIDPARAM, "IDirectSound_GetCaps() " "should have returned DSERR_INVALIDPARAM, returned: %08x\n", rc);
diff --git a/dlls/dsound/tests/ds3d.c b/dlls/dsound/tests/ds3d.c index 6c12f71..d4356c2 100644 --- a/dlls/dsound/tests/ds3d.c +++ b/dlls/dsound/tests/ds3d.c @@ -535,18 +535,6 @@ void test_buffer(LPDIRECTSOUND dso, LPDIRECTSOUNDBUFFER *dsbo, ok(ref==1,"IDirectSoundBuffer_Release() has %d references, " "should have 1\n",ref);
- temp_buffer=NULL; - rc=IDirectSound3DBuffer_QueryInterface(*dsbo, - &IID_IDirectSoundBuffer, - (LPVOID *)&temp_buffer); - ok(rc==DS_OK && temp_buffer!=NULL, - "IDirectSound3DBuffer_QueryInterface() failed: %08x\n", rc); - ok(temp_buffer==*dsbo,"COM interface broken: %p != %p\n", - temp_buffer,*dsbo); - ref=IDirectSoundBuffer_Release(temp_buffer); - ok(ref==1,"IDirectSoundBuffer_Release() has %d references, " - "should have 1\n",ref); - ref=IDirectSoundBuffer_Release(*dsbo); ok(ref==0,"IDirectSoundBuffer_Release() has %d references, " "should have 0\n",ref); @@ -1193,6 +1181,8 @@ static HRESULT test_primary_3d_with_listener(LPGUID lpGuid) if (rc==DS_OK && primary!=NULL) { LPDIRECTSOUND3DLISTENER listener=NULL; LPDIRECTSOUNDBUFFER temp_buffer=NULL; + IKsPropertySet *propset; + rc=IDirectSoundBuffer_QueryInterface(primary, &IID_IDirectSound3DListener,(void **)&listener); ok(rc==DS_OK && listener!=NULL,"IDirectSoundBuffer_QueryInterface() " @@ -1231,11 +1221,10 @@ static HRESULT test_primary_3d_with_listener(LPGUID lpGuid)
temp_buffer = NULL; rc = IDirectSound3DListener_QueryInterface(listener, &IID_IKsPropertySet, - (void **)&temp_buffer); - ok(rc==DS_OK && temp_buffer!=NULL, + (void **)&propset); + ok(rc == DS_OK && propset != NULL, "IDirectSound3DListener_QueryInterface didn't handle IKsPropertySet: ret = %08x\n", rc); - if(temp_buffer) - IKsPropertySet_Release(temp_buffer); + IKsPropertySet_Release(propset); }
/* Testing the reference counting */ @@ -1244,12 +1233,11 @@ static HRESULT test_primary_3d_with_listener(LPGUID lpGuid) "references, should have 0\n",ref); }
- temp_buffer = NULL; - rc = IDirectSoundBuffer_QueryInterface(primary, &IID_IKsPropertySet, (void **)&temp_buffer); - ok(rc==DS_OK && temp_buffer!=NULL, + propset = NULL; + rc = IDirectSoundBuffer_QueryInterface(primary, &IID_IKsPropertySet, (void **)&propset); + ok(rc == DS_OK && propset != NULL, "IDirectSoundBuffer_QueryInterface didn't handle IKsPropertySet on primary buffer: ret = %08x\n", rc); - if(temp_buffer) - IKsPropertySet_Release(temp_buffer); + IKsPropertySet_Release(propset);
/* Testing the reference counting */ ref=IDirectSoundBuffer_Release(primary); diff --git a/dlls/dsound/tests/ds3d8.c b/dlls/dsound/tests/ds3d8.c index 25eb010..00340af 100644 --- a/dlls/dsound/tests/ds3d8.c +++ b/dlls/dsound/tests/ds3d8.c @@ -371,17 +371,6 @@ void test_buffer8(LPDIRECTSOUND8 dso, LPDIRECTSOUNDBUFFER * dsbo, ok(ref==1,"IDirectSoundBuffer_Release() has %d references, " "should have 1\n",ref);
- temp_buffer=NULL; - rc=IDirectSound3DBuffer_QueryInterface(*dsbo, &IID_IDirectSoundBuffer, - (LPVOID *)&temp_buffer); - ok(rc==DS_OK && temp_buffer!=NULL, - "IDirectSound3DBuffer_QueryInterface() failed: %08x\n", rc); - ok(temp_buffer==*dsbo,"COM interface broken: %p != %p\n", - temp_buffer,*dsbo); - ref=IDirectSoundBuffer_Release(temp_buffer); - ok(ref==1,"IDirectSoundBuffer_Release() has %d references, " - "should have 1\n",ref); - ref=IDirectSoundBuffer_Release(*dsbo); ok(ref==0,"IDirectSoundBuffer_Release() has %d references, " "should have 0\n",ref); diff --git a/dlls/dsound/tests/dsound.c b/dlls/dsound/tests/dsound.c index 1ccb8f9..07c8908 100644 --- a/dlls/dsound/tests/dsound.c +++ b/dlls/dsound/tests/dsound.c @@ -30,6 +30,7 @@
#include "wine/test.h" #include "mmsystem.h" +#define COBJMACROS #include "dsound.h" #include "dsconf.h" #include "initguid.h" @@ -61,7 +62,7 @@ static void IDirectSound_test(LPDIRECTSOUND dso, BOOL initialized, rc=IDirectSound_QueryInterface(dso,&IID_IUnknown,(LPVOID*)&unknown); ok(rc==DS_OK,"IDirectSound_QueryInterface(IID_IUnknown) failed: %08x\n", rc); if (rc==DS_OK) - IDirectSound_Release(unknown); + IUnknown_Release(unknown);
rc=IDirectSound_QueryInterface(dso,&IID_IDirectSound,(LPVOID*)&ds); ok(rc==DS_OK,"IDirectSound_QueryInterface(IID_IDirectSound) failed: %08x\n", rc); @@ -337,7 +338,7 @@ static HRESULT test_dsound(LPGUID lpGuid) "buffer %08x\n",rc); if (rc==DS_OK && secondary!=NULL) { LPDIRECTSOUND3DBUFFER buffer3d; - rc=IDirectSound_QueryInterface(secondary, &IID_IDirectSound3DBuffer, + rc = IDirectSoundBuffer_QueryInterface(secondary, &IID_IDirectSound3DBuffer, (void **)&buffer3d); ok(rc==DS_OK && buffer3d!=NULL,"IDirectSound_QueryInterface() " "failed: %08x\n",rc); diff --git a/dlls/dsound/tests/dsound8.c b/dlls/dsound/tests/dsound8.c index 53b3d47..a6e3f12 100644 --- a/dlls/dsound/tests/dsound8.c +++ b/dlls/dsound/tests/dsound8.c @@ -72,7 +72,7 @@ static void IDirectSound8_test(LPDIRECTSOUND8 dso, BOOL initialized, rc=IDirectSound8_QueryInterface(dso,&IID_IUnknown,(LPVOID*)&unknown); ok(rc==DS_OK,"IDirectSound8_QueryInterface(IID_IUnknown) failed: %08x\n", rc); if (rc==DS_OK) - IDirectSound8_Release(unknown); + IUnknown_Release(unknown);
rc=IDirectSound8_QueryInterface(dso,&IID_IDirectSound,(LPVOID*)&ds); ok(rc==DS_OK,"IDirectSound8_QueryInterface(IID_IDirectSound) failed: %08x\n", rc); @@ -353,7 +353,7 @@ static HRESULT test_dsound8(LPGUID lpGuid) if (rc==DS_OK && secondary!=NULL) { LPDIRECTSOUND3DBUFFER buffer3d; LPDIRECTSOUNDBUFFER8 buffer8; - rc=IDirectSound8_QueryInterface(secondary, + rc=IDirectSoundBuffer_QueryInterface(secondary, &IID_IDirectSound3DBuffer, (void **)&buffer3d); ok(rc==DS_OK && buffer3d!=NULL, @@ -363,7 +363,7 @@ static HRESULT test_dsound8(LPGUID lpGuid) ok(ref==2,"IDirectSound3DBuffer_AddRef() has %d references, " "should have 2\n",ref); } - rc=IDirectSound8_QueryInterface(secondary, + rc=IDirectSoundBuffer_QueryInterface(secondary, &IID_IDirectSoundBuffer8, (void **)&buffer8); if (rc==DS_OK && buffer8!=NULL) { @@ -645,7 +645,7 @@ static HRESULT test_primary_secondary8(LPGUID lpGuid) wfx.nSamplesPerSec,wfx.wBitsPerSample,wfx.nChannels,format_tags[tag], wfx2.nSamplesPerSec,wfx2.wBitsPerSample,wfx2.nChannels); } - rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL); + rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL); ok(rc==DS_OK && secondary!=NULL, "IDirectSound_CreateSoundBuffer() failed to create a secondary " "buffer %08x\n",rc); @@ -756,7 +756,7 @@ static HRESULT test_secondary8(LPGUID lpGuid) bufdesc.dwBufferBytes=align(wfx.nAvgBytesPerSec*BUFFER_LEN/1000, wfx.nBlockAlign); bufdesc.lpwfxFormat=&wfx; - rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL); + rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL); if (wfx.wBitsPerSample != 8 && wfx.wBitsPerSample != 16) ok(((rc == DSERR_CONTROLUNAVAIL || rc == DSERR_INVALIDCALL || rc == DSERR_INVALIDPARAM /* 2003 */) && !secondary) || rc == DS_OK, /* driver dependent? */ @@ -779,7 +779,7 @@ static HRESULT test_secondary8(LPGUID lpGuid) wfxe.Samples.wValidBitsPerSample = wfx.wBitsPerSample; wfxe.dwChannelMask = (wfx.nChannels == 1 ? KSAUDIO_SPEAKER_MONO : KSAUDIO_SPEAKER_STEREO);
- rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL); + rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL); ok(rc==DSERR_INVALIDPARAM && !secondary, "IDirectSound_CreateSoundBuffer() returned: %08x %p\n", rc, secondary); @@ -791,7 +791,7 @@ static HRESULT test_secondary8(LPGUID lpGuid)
wfxe.Format.cbSize = sizeof(wfxe) - sizeof(wfx) + 1;
- rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL); + rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL); ok(((rc==DSERR_CONTROLUNAVAIL || rc==DSERR_INVALIDCALL /* 2003 */ || rc==DSERR_INVALIDPARAM) && !secondary) || rc==DS_OK /* driver dependent? */, "IDirectSound_CreateSoundBuffer() returned: %08x %p\n", @@ -804,7 +804,7 @@ static HRESULT test_secondary8(LPGUID lpGuid)
wfxe.Format.cbSize = sizeof(wfxe) - sizeof(wfx); wfxe.SubFormat = GUID_NULL; - rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL); + rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL); ok((rc==DSERR_INVALIDPARAM || rc==DSERR_INVALIDCALL) && !secondary, "IDirectSound_CreateSoundBuffer() returned: %08x %p\n", rc, secondary); @@ -815,7 +815,7 @@ static HRESULT test_secondary8(LPGUID lpGuid) }
wfxe.Format.cbSize = sizeof(wfxe); - rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL); + rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL); ok((rc==DSERR_CONTROLUNAVAIL || rc==DSERR_INVALIDCALL || rc==DSERR_INVALIDPARAM) && !secondary, "IDirectSound_CreateSoundBuffer() returned: %08x %p\n", rc, secondary); @@ -826,7 +826,7 @@ static HRESULT test_secondary8(LPGUID lpGuid) }
wfxe.SubFormat = (format_tags[tag] == WAVE_FORMAT_PCM ? KSDATAFORMAT_SUBTYPE_PCM : KSDATAFORMAT_SUBTYPE_IEEE_FLOAT); - rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL); + rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL); ok(rc==DS_OK && secondary, "IDirectSound_CreateSoundBuffer() returned: %08x %p\n", rc, secondary); @@ -837,7 +837,7 @@ static HRESULT test_secondary8(LPGUID lpGuid) }
wfxe.Format.cbSize = sizeof(wfxe) + 1; - rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL); + rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL); ok(((rc==DSERR_CONTROLUNAVAIL || rc==DSERR_INVALIDCALL /* 2003 */ || rc==DSERR_INVALIDPARAM) && !secondary) || rc==DS_OK /* driver dependent? */, "IDirectSound_CreateSoundBuffer() returned: %08x %p\n", @@ -850,7 +850,7 @@ static HRESULT test_secondary8(LPGUID lpGuid)
wfxe.Format.cbSize = sizeof(wfxe) - sizeof(wfx); ++wfxe.Samples.wValidBitsPerSample; - rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL); + rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL); ok(rc==DSERR_INVALIDPARAM && !secondary, "IDirectSound_CreateSoundBuffer() returned: %08x %p\n", rc, secondary); @@ -862,7 +862,7 @@ static HRESULT test_secondary8(LPGUID lpGuid) --wfxe.Samples.wValidBitsPerSample;
wfxe.Samples.wValidBitsPerSample = 0; - rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL); + rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL); ok(rc==DS_OK && secondary, "IDirectSound_CreateSoundBuffer() returned: %08x %p\n", rc, secondary); @@ -873,7 +873,7 @@ static HRESULT test_secondary8(LPGUID lpGuid) } wfxe.Samples.wValidBitsPerSample = wfxe.Format.wBitsPerSample;
- rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL); + rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL); ok(rc==DS_OK && secondary!=NULL, "IDirectSound_CreateSoundBuffer() failed to create a secondary " "buffer %08x\n",rc); @@ -1162,7 +1162,7 @@ static void test_COM(void) ok(hr == S_OK, "QueryInterface for IID_IUnknown failed: %08x\n", hr); refcount = IUnknown_AddRef(unk); ok(refcount == 2, "refcount == %u, expected 2\n", refcount); - hr = IDirectSound_QueryInterface(ds8, &IID_IUnknown, (void**)&unk8); + hr = IDirectSound8_QueryInterface(ds8, &IID_IUnknown, (void**)&unk8); ok(hr == S_OK, "QueryInterface for IID_IUnknown failed: %08x\n", hr); refcount = IUnknown_AddRef(unk8); ok(refcount == 4, "refcount == %u, expected 4\n", refcount); @@ -1194,7 +1194,7 @@ static void test_effects(void) rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_PRIORITY); ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel() failed: %08x\n", rc); if (rc!=DS_OK) { - IDirectSound_Release(dso); + IDirectSound8_Release(dso); return; }
@@ -1372,7 +1372,7 @@ static void test_effects(void) IDirectSoundBuffer_Release(primary); }
- while (IDirectSound_Release(dso)); + while (IDirectSound8_Release(dso)); }
START_TEST(dsound8) diff --git a/dlls/dsound/tests/duplex.c b/dlls/dsound/tests/duplex.c index ecdebdc..b770515 100644 --- a/dlls/dsound/tests/duplex.c +++ b/dlls/dsound/tests/duplex.c @@ -49,7 +49,7 @@ static void IDirectSoundFullDuplex_test(LPDIRECTSOUNDFULLDUPLEX dsfdo, rc=IDirectSoundFullDuplex_QueryInterface(dsfdo,&IID_IUnknown,(LPVOID*)&unknown); ok(rc==DS_OK,"IDirectSoundFullDuplex_QueryInterface(IID_IUnknown) failed: %08x\n", rc); if (rc==DS_OK) { - ref=IDirectSoundFullDuplex_Release(unknown); + ref = IUnknown_Release(unknown); ok(ref==0, "IDirectSoundFullDuplex_Release() has %d references, " "should have 0\n", ref); } @@ -94,7 +94,7 @@ static void IDirectSoundFullDuplex_test(LPDIRECTSOUNDFULLDUPLEX dsfdo, "failed: %08x\n",rc); if (rc==DS_OK) { ok(dsfdo==dsfd, "different interfaces\n"); - ref=IDirectSound8_Release(dsfd); + ref=IDirectSoundFullDuplex_Release(dsfd); ok(ref==1, "IDirectSoundFullDuplex_Release() has %d references, should have 1\n", ref); }
@@ -319,7 +319,7 @@ static void test_COM(void) ok(refcount == 2, "refcount == %u, expected 2\n", refcount); refcount = IDirectSoundFullDuplex_AddRef(dsfd); ok(refcount == 4, "refcount == %u, expected 4\n", refcount); - hr = IDirectSoundCapture_QueryInterface(ds8, &IID_IUnknown, (void**)&unk8); + hr = IDirectSound8_QueryInterface(ds8, &IID_IUnknown, (void**)&unk8); ok(hr == S_OK, "QueryInterface for IID_IUnknown failed: %08x\n", hr); ok(unk == unk8, "Got different IUnknown when QI'ing IDirectSoundFullDuplex and IDirectSoundCapture\n");
Hi,
While running your changed tests on Windows, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check? Full results can be found at https://testbot.winehq.org/JobDetails.pl?Key=37351
Your paranoid android.
=== w864 (32 bit dsound) === TestBot process died unexpectedly
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/devenum/createdevenum.c | 130 ++++++++++++++++++++++--------------------- dlls/devenum/tests/devenum.c | 87 +++++++++++++++++++++++++++++ 2 files changed, 154 insertions(+), 63 deletions(-)
diff --git a/dlls/devenum/createdevenum.c b/dlls/devenum/createdevenum.c index e3fe049..9be34d7 100644 --- a/dlls/devenum/createdevenum.c +++ b/dlls/devenum/createdevenum.c @@ -673,6 +673,72 @@ cleanup: } }
+static void register_wavein_devices(void) +{ + static const WCHAR waveinidW[] = {'W','a','v','e','I','n','I','d',0}; + IPropertyBag *prop_bag = NULL; + REGFILTER2 rgf = {0}; + WCHAR clsid[CHARS_IN_GUID]; + IMoniker *mon = NULL; + WAVEINCAPSW caps; + int i, count; + VARIANT var; + HRESULT hr; + + hr = DEVENUM_CreateAMCategoryKey(&CLSID_AudioRendererCategory); + if (FAILED(hr)) return; + + count = waveInGetNumDevs(); + + for (i = 0; i < count; i++) + { + waveInGetDevCapsW(i, &caps, sizeof(caps)); + + V_VT(&var) = VT_BSTR; + + V_BSTR(&var) = SysAllocString(caps.szPname); + if (!(V_BSTR(&var))) + goto cleanup; + + hr = register_codec(&CLSID_AudioInputDeviceCategory, V_BSTR(&var), &mon); + if (FAILED(hr)) goto cleanup; + + hr = IMoniker_BindToStorage(mon, NULL, NULL, &IID_IPropertyBag, (void **)&prop_bag); + if (FAILED(hr)) goto cleanup; + + /* write friendly name */ + hr = IPropertyBag_Write(prop_bag, wszFriendlyName, &var); + if (FAILED(hr)) goto cleanup; + VariantClear(&var); + + /* write clsid */ + V_VT(&var) = VT_BSTR; + StringFromGUID2(&CLSID_AudioRecord, clsid, CHARS_IN_GUID); + if (!(V_BSTR(&var) = SysAllocString(clsid))) + goto cleanup; + hr = IPropertyBag_Write(prop_bag, clsid_keyname, &var); + if (FAILED(hr)) goto cleanup; + VariantClear(&var); + + /* write filter data */ + rgf.dwVersion = 2; + rgf.dwMerit = MERIT_DO_NOT_USE; + + write_filter_data(prop_bag, &rgf); + + /* write WaveInId */ + V_VT(&var) = VT_I4; + V_I4(&var) = i; + hr = IPropertyBag_Write(prop_bag, waveinidW, &var); + if (FAILED(hr)) goto cleanup; + +cleanup: + VariantClear(&var); + if (prop_bag) IPropertyBag_Release(prop_bag); + if (mon) IMoniker_Release(mon); + } +} + /********************************************************************** * DEVENUM_ICreateDevEnum_CreateClassEnumerator */ @@ -696,6 +762,7 @@ static HRESULT WINAPI DEVENUM_ICreateDevEnum_CreateClassEnumerator( hr = DirectSoundEnumerateW(®ister_dsound_devices, NULL); if (FAILED(hr)) return hr; register_waveout_devices(); + register_wavein_devices();
return create_EnumMoniker(clsidDeviceClass, ppEnumMoniker); } @@ -832,73 +899,10 @@ static HRESULT register_codecs(void) if (SUCCEEDED(res)) { UINT i; - WAVEINCAPSW wicaps; MIDIOUTCAPSW mocaps; REGPINTYPES * pTypes; IPropertyBag * pPropBag = NULL;
- numDevs = waveInGetNumDevs(); - - res = DEVENUM_CreateAMCategoryKey(&CLSID_AudioInputDeviceCategory); - if (FAILED(res)) /* can't register any devices in this category */ - numDevs = 0; - - rfp2.dwFlags = REG_PINFLAG_B_OUTPUT; - for (i = 0; i < numDevs; i++) - { - if (waveInGetDevCapsW(i, &wicaps, sizeof(WAVEINCAPSW)) - == MMSYSERR_NOERROR) - { - IMoniker * pMoniker = NULL; - - rfp2.nMediaTypes = 1; - pTypes = CoTaskMemAlloc(rfp2.nMediaTypes * sizeof(REGPINTYPES)); - if (!pTypes) - { - IFilterMapper2_Release(pMapper); - return E_OUTOFMEMORY; - } - - /* FIXME: Not sure if these are correct */ - pTypes[0].clsMajorType = &MEDIATYPE_Audio; - pTypes[0].clsMinorType = &MEDIASUBTYPE_PCM; - - rfp2.lpMediaType = pTypes; - - res = IFilterMapper2_RegisterFilter(pMapper, - &CLSID_AudioRecord, - wicaps.szPname, - &pMoniker, - &CLSID_AudioInputDeviceCategory, - wicaps.szPname, - &rf2); - - - if (pMoniker) { - VARIANT var; - - V_VT(&var) = VT_I4; - V_I4(&var) = i; - res = IMoniker_BindToStorage(pMoniker, NULL, NULL, &IID_IPropertyBag, (LPVOID)&pPropBag); - if (SUCCEEDED(res)) - res = IPropertyBag_Write(pPropBag, wszWaveInID, &var); - else - pPropBag = NULL; - - V_VT(&var) = VT_LPWSTR; - V_BSTR(&var) = wicaps.szPname; - if (SUCCEEDED(res)) - res = IPropertyBag_Write(pPropBag, wszFriendlyName, &var); - - if (pPropBag) - IPropertyBag_Release(pPropBag); - IMoniker_Release(pMoniker); - } - - CoTaskMemFree(pTypes); - } - } - numDevs = midiOutGetNumDevs();
res = DEVENUM_CreateAMCategoryKey(&CLSID_MidiRendererCategory); diff --git a/dlls/devenum/tests/devenum.c b/dlls/devenum/tests/devenum.c index 79f5ed8..3f66237 100644 --- a/dlls/devenum/tests/devenum.c +++ b/dlls/devenum/tests/devenum.c @@ -726,6 +726,92 @@ static void test_waveout(void) IParseDisplayName_Release(parser); }
+static void test_wavein(void) +{ + static const WCHAR waveinidW[] = {'W','a','v','e','I','n','I','d',0}; + IParseDisplayName *parser; + IPropertyBag *prop_bag; + IMoniker *mon; + WCHAR endpoint[200]; + WCHAR buffer[200]; + WAVEINCAPSW caps; + MMRESULT mmr; + int count, i; + VARIANT var; + HRESULT hr; + + hr = CoCreateInstance(&CLSID_CDeviceMoniker, NULL, CLSCTX_INPROC, &IID_IParseDisplayName, (void **)&parser); + ok(hr == S_OK, "Failed to create ParseDisplayName: %#x\n", hr); + + count = waveInGetNumDevs(); + + for (i = 0; i < count; i++) + { + waveInGetDevCapsW(i, &caps, sizeof(caps)); + + lstrcpyW(buffer, deviceW); + lstrcatW(buffer, cmW); + StringFromGUID2(&CLSID_AudioInputDeviceCategory, buffer + lstrlenW(buffer), CHARS_IN_GUID); + lstrcatW(buffer, backslashW); + lstrcatW(buffer, caps.szPname); + + mon = check_display_name(parser, buffer); + + hr = IMoniker_BindToStorage(mon, NULL, NULL, &IID_IPropertyBag, (void **)&prop_bag); + ok(hr == S_OK, "BindToStorage failed: %#x\n", hr); + + VariantInit(&var); + hr = IPropertyBag_Read(prop_bag, friendly_name, &var, NULL); + if (hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)) + { + IPropertyBag_Release(prop_bag); + IMoniker_Release(mon); + + /* Win8+ uses the endpoint GUID instead of the device name */ + mmr = waveInMessage((HWAVEIN)(DWORD_PTR) i, DRV_QUERYFUNCTIONINSTANCEID, + (DWORD_PTR) endpoint, sizeof(endpoint)); + ok(!mmr, "waveInMessage failed: %u\n", mmr); + + lstrcpyW(buffer, deviceW); + lstrcatW(buffer, cmW); + StringFromGUID2(&CLSID_AudioInputDeviceCategory, buffer + lstrlenW(buffer), CHARS_IN_GUID); + lstrcatW(buffer, backslashW); + lstrcatW(buffer, waveW); + lstrcatW(buffer, strchrW(endpoint, '}') + 2); + + mon = check_display_name(parser, buffer); + + hr = IMoniker_BindToStorage(mon, NULL, NULL, &IID_IPropertyBag, (void **)&prop_bag); + ok(hr == S_OK, "BindToStorage failed: %#x\n", hr); + + hr = IPropertyBag_Read(prop_bag, friendly_name, &var, NULL); + } + ok(hr == S_OK, "Read failed: %#x\n", hr); + + ok(!strncmpW(caps.szPname, V_BSTR(&var), lstrlenW(caps.szPname)), "expected %s, got %s\n", + wine_dbgstr_w(caps.szPname), wine_dbgstr_w(V_BSTR(&var))); + + VariantClear(&var); + hr = IPropertyBag_Read(prop_bag, clsidW, &var, NULL); + ok(hr == S_OK, "Read failed: %#x\n", hr); + + StringFromGUID2(&CLSID_AudioRecord, buffer, CHARS_IN_GUID); + ok(!lstrcmpW(buffer, V_BSTR(&var)), "expected %s, got %s\n", + wine_dbgstr_w(buffer), wine_dbgstr_w(V_BSTR(&var))); + + VariantClear(&var); + hr = IPropertyBag_Read(prop_bag, waveinidW, &var, NULL); + ok(hr == S_OK, "Read failed: %#x\n", hr); + + ok(V_I4(&var) == i, "expected %d, got %d\n", i, V_I4(&var)); + + IPropertyBag_Release(prop_bag); + IMoniker_Release(mon); + } + + IParseDisplayName_Release(parser); +} + START_TEST(devenum) { IBindCtx *bind_ctx = NULL; @@ -752,6 +838,7 @@ START_TEST(devenum) hr = DirectSoundEnumerateW(test_dsound, NULL); ok(hr == S_OK, "got %#x\n", hr); test_waveout(); + test_wavein();
CoUninitialize(); }
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/devenum/createdevenum.c | 132 +++++++++++++++++++++++++---------------- dlls/devenum/devenum.rc | 9 --- dlls/devenum/devenum_private.h | 7 --- dlls/devenum/tests/devenum.c | 68 +++++++++++++++++++++ 4 files changed, 148 insertions(+), 68 deletions(-)
diff --git a/dlls/devenum/createdevenum.c b/dlls/devenum/createdevenum.c index 9be34d7..677336c 100644 --- a/dlls/devenum/createdevenum.c +++ b/dlls/devenum/createdevenum.c @@ -739,6 +739,85 @@ cleanup: } }
+static void register_midiout_devices(void) +{ + static const WCHAR defaultW[] = {'D','e','f','a','u','l','t',' ','M','i','d','i','O','u','t',' ','D','e','v','i','c','e',0}; + static const WCHAR midioutidW[] = {'M','i','d','i','O','u','t','I','d',0}; + IPropertyBag *prop_bag = NULL; + REGFILTERPINS2 rgpins = {0}; + REGPINTYPES rgtypes = {0}; + REGFILTER2 rgf = {0}; + WCHAR clsid[CHARS_IN_GUID]; + IMoniker *mon = NULL; + MIDIOUTCAPSW caps; + int i, count; + VARIANT var; + HRESULT hr; + + hr = DEVENUM_CreateAMCategoryKey(&CLSID_AudioRendererCategory); + if (FAILED(hr)) return; + + count = midiOutGetNumDevs(); + + for (i = -1; i < count; i++) + { + midiOutGetDevCapsW(i, &caps, sizeof(caps)); + + V_VT(&var) = VT_BSTR; + + if (i == -1) /* MIDI_MAPPER */ + V_BSTR(&var) = SysAllocString(defaultW); + else + V_BSTR(&var) = SysAllocString(caps.szPname); + if (!(V_BSTR(&var))) + goto cleanup; + + hr = register_codec(&CLSID_MidiRendererCategory, V_BSTR(&var), &mon); + if (FAILED(hr)) goto cleanup; + + hr = IMoniker_BindToStorage(mon, NULL, NULL, &IID_IPropertyBag, (void **)&prop_bag); + if (FAILED(hr)) goto cleanup; + + /* write friendly name */ + hr = IPropertyBag_Write(prop_bag, wszFriendlyName, &var); + if (FAILED(hr)) goto cleanup; + VariantClear(&var); + + /* write clsid */ + V_VT(&var) = VT_BSTR; + StringFromGUID2(&CLSID_AVIMIDIRender, clsid, CHARS_IN_GUID); + if (!(V_BSTR(&var) = SysAllocString(clsid))) + goto cleanup; + hr = IPropertyBag_Write(prop_bag, clsid_keyname, &var); + if (FAILED(hr)) goto cleanup; + VariantClear(&var); + + /* write filter data */ + rgf.dwVersion = 2; + rgf.dwMerit = (i == -1) ? MERIT_PREFERRED : MERIT_DO_NOT_USE; + rgf.u.s2.cPins2 = 1; + rgf.u.s2.rgPins2 = &rgpins; + rgpins.dwFlags = REG_PINFLAG_B_RENDERER; + rgpins.nMediaTypes = 1; + rgpins.lpMediaType = &rgtypes; + rgtypes.clsMajorType = &MEDIATYPE_Midi; + rgtypes.clsMinorType = &MEDIASUBTYPE_NULL; + + write_filter_data(prop_bag, &rgf); + + /* write MidiOutId */ + V_VT(&var) = VT_I4; + V_I4(&var) = i; + hr = IPropertyBag_Write(prop_bag, midioutidW, &var); + if (FAILED(hr)) goto cleanup; + +cleanup: + VariantClear(&var); + if (prop_bag) IPropertyBag_Release(prop_bag); + if (mon) IMoniker_Release(mon); + } +} + /********************************************************************** * DEVENUM_ICreateDevEnum_CreateClassEnumerator */ @@ -763,6 +842,7 @@ static HRESULT WINAPI DEVENUM_ICreateDevEnum_CreateClassEnumerator( if (FAILED(hr)) return hr; register_waveout_devices(); register_wavein_devices(); + register_midiout_devices();
return create_EnumMoniker(clsidDeviceClass, ppEnumMoniker); } @@ -858,7 +938,6 @@ static HRESULT register_codecs(void) HRESULT res; WCHAR class[CHARS_IN_GUID]; DWORD iDefaultDevice = -1; - UINT numDevs; IFilterMapper2 * pMapper = NULL; REGFILTER2 rf2; REGFILTERPINS2 rfp2; @@ -899,60 +978,9 @@ static HRESULT register_codecs(void) if (SUCCEEDED(res)) { UINT i; - MIDIOUTCAPSW mocaps; REGPINTYPES * pTypes; IPropertyBag * pPropBag = NULL;
- numDevs = midiOutGetNumDevs(); - - res = DEVENUM_CreateAMCategoryKey(&CLSID_MidiRendererCategory); - if (FAILED(res)) /* can't register any devices in this category */ - numDevs = 0; - - rfp2.dwFlags = REG_PINFLAG_B_RENDERER; - for (i = 0; i < numDevs; i++) - { - if (midiOutGetDevCapsW(i, &mocaps, sizeof(MIDIOUTCAPSW)) - == MMSYSERR_NOERROR) - { - IMoniker * pMoniker = NULL; - - rfp2.nMediaTypes = 1; - pTypes = CoTaskMemAlloc(rfp2.nMediaTypes * sizeof(REGPINTYPES)); - if (!pTypes) - { - IFilterMapper2_Release(pMapper); - return E_OUTOFMEMORY; - } - - /* FIXME: Not sure if these are correct */ - pTypes[0].clsMajorType = &MEDIATYPE_Midi; - pTypes[0].clsMinorType = &MEDIASUBTYPE_None; - - rfp2.lpMediaType = pTypes; - - res = IFilterMapper2_RegisterFilter(pMapper, - &CLSID_AVIMIDIRender, - mocaps.szPname, - &pMoniker, - &CLSID_MidiRendererCategory, - mocaps.szPname, - &rf2); - - /* FIXME: do additional stuff with IMoniker here, depending on what RegisterFilter does */ - /* Native version sets MidiOutId */ - - if (pMoniker) - IMoniker_Release(pMoniker); - - if (i == iDefaultDevice) - { - FIXME("Default device\n"); - } - - CoTaskMemFree(pTypes); - } - } res = DEVENUM_CreateAMCategoryKey(&CLSID_VideoInputDeviceCategory); if (SUCCEEDED(res)) for (i = 0; i < 10; i++) diff --git a/dlls/devenum/devenum.rc b/dlls/devenum/devenum.rc index 95e39d6..24da9b8 100644 --- a/dlls/devenum/devenum.rc +++ b/dlls/devenum/devenum.rc @@ -23,15 +23,6 @@ #include "winnls.h" #include "devenum_private.h"
-#pragma makedep po - -LANGUAGE LANG_ENGLISH, SUBLANG_DEFAULT - -STRINGTABLE -{ - IDS_DEVENUM_MIDEFAULT "Default MidiOut Device" -} - LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
#define WINE_FILEDESCRIPTION_STR "Wine Device Enumerator Library" diff --git a/dlls/devenum/devenum_private.h b/dlls/devenum/devenum_private.h index c891083..d4e1141 100644 --- a/dlls/devenum/devenum_private.h +++ b/dlls/devenum/devenum_private.h @@ -97,10 +97,3 @@ static const WCHAR wszActiveMovieKey[] = {'S','o','f','t','w','a','r','e','\', static const WCHAR deviceW[] = {'@','d','e','v','i','c','e',':',0};
extern const WCHAR clsid_keyname[6] DECLSPEC_HIDDEN; - -/********************************************************************** - * Resource IDs - */ -#define IDS_DEVENUM_MIDEFAULT 10 -#define IDS_DEVENUM_KSDEFAULT 11 -#define IDS_DEVENUM_KS 12 diff --git a/dlls/devenum/tests/devenum.c b/dlls/devenum/tests/devenum.c index 3f66237..d9ea5e9 100644 --- a/dlls/devenum/tests/devenum.c +++ b/dlls/devenum/tests/devenum.c @@ -812,6 +812,73 @@ static void test_wavein(void) IParseDisplayName_Release(parser); }
+static void test_midiout(void) +{ + static const WCHAR defaultW[] = {'D','e','f','a','u','l','t',' ','M','i','d','i','O','u','t',' ','D','e','v','i','c','e',0}; + static const WCHAR midioutidW[] = {'M','i','d','i','O','u','t','I','d',0}; + IParseDisplayName *parser; + IPropertyBag *prop_bag; + IMoniker *mon; + MIDIOUTCAPSW caps; + WCHAR buffer[200]; + const WCHAR *name; + int count, i; + VARIANT var; + HRESULT hr; + + hr = CoCreateInstance(&CLSID_CDeviceMoniker, NULL, CLSCTX_INPROC, &IID_IParseDisplayName, (void **)&parser); + ok(hr == S_OK, "Failed to create ParseDisplayName: %#x\n", hr); + + count = midiOutGetNumDevs(); + + for (i = -1; i < count; i++) + { + midiOutGetDevCapsW(i, &caps, sizeof(caps)); + + if (i == -1) /* MIDI_MAPPER */ + name = defaultW; + else + name = caps.szPname; + + lstrcpyW(buffer, deviceW); + lstrcatW(buffer, cmW); + StringFromGUID2(&CLSID_MidiRendererCategory, buffer + lstrlenW(buffer), CHARS_IN_GUID); + lstrcatW(buffer, backslashW); + lstrcatW(buffer, name); + + mon = check_display_name(parser, buffer); + + hr = IMoniker_BindToStorage(mon, NULL, NULL, &IID_IPropertyBag, (void **)&prop_bag); + ok(hr == S_OK, "BindToStorage failed: %#x\n", hr); + + VariantInit(&var); + hr = IPropertyBag_Read(prop_bag, friendly_name, &var, NULL); + ok(hr == S_OK, "Read failed: %#x\n", hr); + + ok(!lstrcmpW(name, V_BSTR(&var)), "expected %s, got %s\n", + wine_dbgstr_w(name), wine_dbgstr_w(V_BSTR(&var))); + + VariantClear(&var); + hr = IPropertyBag_Read(prop_bag, clsidW, &var, NULL); + ok(hr == S_OK, "Read failed: %#x\n", hr); + + StringFromGUID2(&CLSID_AVIMIDIRender, buffer, CHARS_IN_GUID); + ok(!lstrcmpW(buffer, V_BSTR(&var)), "expected %s, got %s\n", + wine_dbgstr_w(buffer), wine_dbgstr_w(V_BSTR(&var))); + + VariantClear(&var); + hr = IPropertyBag_Read(prop_bag, midioutidW, &var, NULL); + ok(hr == S_OK, "Read failed: %#x\n", hr); + + ok(V_I4(&var) == i, "expected %d, got %d\n", i, V_I4(&var)); + + IPropertyBag_Release(prop_bag); + IMoniker_Release(mon); + } + + IParseDisplayName_Release(parser); +} + START_TEST(devenum) { IBindCtx *bind_ctx = NULL; @@ -839,6 +906,7 @@ START_TEST(devenum) ok(hr == S_OK, "got %#x\n", hr); test_waveout(); test_wavein(); + test_midiout();
CoUninitialize(); }
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- v2: fix test failures on 64-bit
dlls/devenum/createdevenum.c | 153 ++++++++++++++++++++++++----------------- dlls/devenum/tests/Makefile.in | 2 +- dlls/devenum/tests/devenum.c | 72 +++++++++++++++++++ 3 files changed, 164 insertions(+), 63 deletions(-)
diff --git a/dlls/devenum/createdevenum.c b/dlls/devenum/createdevenum.c index 677336c..2427469 100644 --- a/dlls/devenum/createdevenum.c +++ b/dlls/devenum/createdevenum.c @@ -107,28 +107,6 @@ static ULONG WINAPI DEVENUM_ICreateDevEnum_Release(ICreateDevEnum * iface) return 1; /* non-heap based object */ }
-static HKEY open_special_category_key(const CLSID *clsid, BOOL create) -{ - WCHAR key_name[sizeof(wszActiveMovieKey)/sizeof(WCHAR) + CHARS_IN_GUID-1]; - HKEY ret; - LONG res; - - strcpyW(key_name, wszActiveMovieKey); - if (!StringFromGUID2(clsid, key_name + sizeof(wszActiveMovieKey)/sizeof(WCHAR)-1, CHARS_IN_GUID)) - return NULL; - - if(create) - res = RegCreateKeyW(HKEY_CURRENT_USER, key_name, &ret); - else - res = RegOpenKeyExW(HKEY_CURRENT_USER, key_name, 0, KEY_READ, &ret); - if (res != ERROR_SUCCESS) { - WARN("Could not open %s\n", debugstr_w(key_name)); - return NULL; - } - - return ret; -} - static HRESULT register_codec(const CLSID *class, const WCHAR *name, IMoniker **ret) { static const WCHAR deviceW[] = {'@','d','e','v','i','c','e',':','c','m',':',0}; @@ -818,6 +796,96 @@ cleanup: } }
+static void register_vfw_codecs(void) +{ + static const WCHAR fcchandlerW[] = {'F','c','c','H','a','n','d','l','e','r',0}; + REGFILTERPINS2 rgpins[2] = {0}; + IPropertyBag *prop_bag = NULL; + REGPINTYPES rgtypes[2] = {0}; + REGFILTER2 rgf = {0}; + WCHAR clsid[CHARS_IN_GUID]; + IMoniker *mon = NULL; + GUID typeguid; + ICINFO info; + VARIANT var; + HRESULT hr; + int i = 0; + HIC hic; + + hr = DEVENUM_CreateAMCategoryKey(&CLSID_AudioRendererCategory); + if (FAILED(hr)) return; + + while (ICInfo(ICTYPE_VIDEO, i++, &info)) + { + WCHAR name[5] = {LOBYTE(LOWORD(info.fccHandler)), HIBYTE(LOWORD(info.fccHandler)), + LOBYTE(HIWORD(info.fccHandler)), HIBYTE(HIWORD(info.fccHandler))}; + + hic = ICOpen(ICTYPE_VIDEO, info.fccHandler, ICMODE_QUERY); + ICGetInfo(hic, &info, sizeof(info)); + ICClose(hic); + + V_VT(&var) = VT_BSTR; + + V_BSTR(&var) = SysAllocString(name); + if (!(V_BSTR(&var))) + goto cleanup; + + hr = register_codec(&CLSID_VideoCompressorCategory, V_BSTR(&var), &mon); + if (FAILED(hr)) goto cleanup; + + hr = IMoniker_BindToStorage(mon, NULL, NULL, &IID_IPropertyBag, (void **)&prop_bag); + if (FAILED(hr)) goto cleanup; + + /* write WaveInId */ + hr = IPropertyBag_Write(prop_bag, fcchandlerW, &var); + if (FAILED(hr)) goto cleanup; + VariantClear(&var); + + /* write friendly name */ + V_VT(&var) = VT_BSTR; + if (!(V_BSTR(&var) = SysAllocString(info.szDescription))) + goto cleanup; + + hr = IPropertyBag_Write(prop_bag, wszFriendlyName, &var); + if (FAILED(hr)) goto cleanup; + VariantClear(&var); + + /* write clsid */ + V_VT(&var) = VT_BSTR; + StringFromGUID2(&CLSID_AVICo, clsid, CHARS_IN_GUID); + if (!(V_BSTR(&var) = SysAllocString(clsid))) + goto cleanup; + hr = IPropertyBag_Write(prop_bag, clsid_keyname, &var); + if (FAILED(hr)) goto cleanup; + VariantClear(&var); + + /* write filter data */ + rgf.dwVersion = 2; + rgf.dwMerit = MERIT_DO_NOT_USE; + rgf.u.s2.cPins2 = 2; + rgf.u.s2.rgPins2 = rgpins; + rgpins[0].dwFlags = 0; + rgpins[0].nMediaTypes = 1; + rgpins[0].lpMediaType = &rgtypes[0]; + rgtypes[0].clsMajorType = &MEDIATYPE_Video; + typeguid = MEDIASUBTYPE_PCM; + typeguid.Data1 = info.fccHandler; + rgtypes[0].clsMinorType = &typeguid; + rgpins[1].dwFlags = REG_PINFLAG_B_OUTPUT; + rgpins[1].nMediaTypes = 1; + rgpins[1].lpMediaType = &rgtypes[1]; + rgtypes[1].clsMajorType = &MEDIATYPE_Video; + rgtypes[1].clsMinorType = &GUID_NULL; + + write_filter_data(prop_bag, &rgf); + +cleanup: + VariantClear(&var); + if (prop_bag) IPropertyBag_Release(prop_bag); + if (mon) IMoniker_Release(mon); + } +} + /********************************************************************** * DEVENUM_ICreateDevEnum_CreateClassEnumerator */ @@ -843,6 +911,7 @@ static HRESULT WINAPI DEVENUM_ICreateDevEnum_CreateClassEnumerator( register_waveout_devices(); register_wavein_devices(); register_midiout_devices(); + register_vfw_codecs();
return create_EnumMoniker(clsidDeviceClass, ppEnumMoniker); } @@ -895,44 +964,6 @@ static HRESULT DEVENUM_CreateAMCategoryKey(const CLSID * clsidCategory) return res; }
-static void register_vfw_codecs(void) -{ - WCHAR avico_clsid_str[CHARS_IN_GUID]; - HKEY basekey, key; - ICINFO icinfo; - DWORD i, res; - - static const WCHAR CLSIDW[] = {'C','L','S','I','D',0}; - static const WCHAR FccHandlerW[] = {'F','c','c','H','a','n','d','l','e','r',0}; - static const WCHAR FriendlyNameW[] = {'F','r','i','e','n','d','l','y','N','a','m','e',0}; - - StringFromGUID2(&CLSID_AVICo, avico_clsid_str, sizeof(avico_clsid_str)/sizeof(WCHAR)); - - basekey = open_special_category_key(&CLSID_VideoCompressorCategory, TRUE); - if(!basekey) { - ERR("Could not create key\n"); - return; - } - - for(i=0; ICInfo(FCC('v','i','d','c'), i, &icinfo); i++) { - WCHAR fcc_str[5] = {LOBYTE(LOWORD(icinfo.fccHandler)), HIBYTE(LOWORD(icinfo.fccHandler)), - LOBYTE(HIWORD(icinfo.fccHandler)), HIBYTE(HIWORD(icinfo.fccHandler))}; - - res = RegCreateKeyW(basekey, fcc_str, &key); - if(res != ERROR_SUCCESS) - continue; - - RegSetValueExW(key, CLSIDW, 0, REG_SZ, (const BYTE*)avico_clsid_str, sizeof(avico_clsid_str)); - RegSetValueExW(key, FccHandlerW, 0, REG_SZ, (const BYTE*)fcc_str, sizeof(fcc_str)); - RegSetValueExW(key, FriendlyNameW, 0, REG_SZ, (const BYTE*)icinfo.szName, (strlenW(icinfo.szName)+1)*sizeof(WCHAR)); - /* FIXME: Set ClassManagerFlags and FilterData values */ - - RegCloseKey(key); - } - - RegCloseKey(basekey); -} - static HRESULT register_codecs(void) { HRESULT res; @@ -1038,7 +1069,5 @@ static HRESULT register_codecs(void) if (pMapper) IFilterMapper2_Release(pMapper);
- register_vfw_codecs(); - return res; } diff --git a/dlls/devenum/tests/Makefile.in b/dlls/devenum/tests/Makefile.in index a673f20..b268adf 100644 --- a/dlls/devenum/tests/Makefile.in +++ b/dlls/devenum/tests/Makefile.in @@ -1,5 +1,5 @@ TESTDLL = devenum.dll -IMPORTS = advapi32 dsound oleaut32 ole32 winmm +IMPORTS = advapi32 dsound msvfw32 oleaut32 ole32 winmm
C_SRCS = \ devenum.c diff --git a/dlls/devenum/tests/devenum.c b/dlls/devenum/tests/devenum.c index d9ea5e9..293ba8d 100644 --- a/dlls/devenum/tests/devenum.c +++ b/dlls/devenum/tests/devenum.c @@ -31,6 +31,7 @@ #include "mmsystem.h" #include "dsound.h" #include "mmddk.h" +#include "vfw.h"
DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0);
@@ -879,6 +880,76 @@ static void test_midiout(void) IParseDisplayName_Release(parser); }
+static void test_vfw(void) +{ + static const WCHAR fcchandlerW[] = {'F','c','c','H','a','n','d','l','e','r',0}; + IParseDisplayName *parser; + IPropertyBag *prop_bag; + IMoniker *mon; + WCHAR buffer[200]; + ICINFO info; + VARIANT var; + HRESULT hr; + int i = 0; + HIC hic; + + if (broken(sizeof(void *) == 8)) + { + win_skip("VFW codecs are not enumerated on 64-bit Windows\n"); + return; + } + + hr = CoCreateInstance(&CLSID_CDeviceMoniker, NULL, CLSCTX_INPROC, &IID_IParseDisplayName, (void **)&parser); + ok(hr == S_OK, "Failed to create ParseDisplayName: %#x\n", hr); + + while (ICInfo(ICTYPE_VIDEO, i++, &info)) + { + WCHAR name[5] = {LOBYTE(LOWORD(info.fccHandler)), HIBYTE(LOWORD(info.fccHandler)), + LOBYTE(HIWORD(info.fccHandler)), HIBYTE(HIWORD(info.fccHandler))}; + + hic = ICOpen(ICTYPE_VIDEO, info.fccHandler, ICMODE_QUERY); + ICGetInfo(hic, &info, sizeof(info)); + ICClose(hic); + + lstrcpyW(buffer, deviceW); + lstrcatW(buffer, cmW); + StringFromGUID2(&CLSID_VideoCompressorCategory, buffer + lstrlenW(buffer), CHARS_IN_GUID); + lstrcatW(buffer, backslashW); + lstrcatW(buffer, name); + + mon = check_display_name(parser, buffer); + + hr = IMoniker_BindToStorage(mon, NULL, NULL, &IID_IPropertyBag, (void **)&prop_bag); + ok(hr == S_OK, "BindToStorage failed: %#x\n", hr); + + VariantInit(&var); + hr = IPropertyBag_Read(prop_bag, friendly_name, &var, NULL); + ok(hr == S_OK, "Read failed: %#x\n", hr); + + ok(!lstrcmpW(info.szDescription, V_BSTR(&var)), "expected %s, got %s\n", + wine_dbgstr_w(info.szDescription), wine_dbgstr_w(V_BSTR(&var))); + + VariantClear(&var); + hr = IPropertyBag_Read(prop_bag, clsidW, &var, NULL); + ok(hr == S_OK, "Read failed: %#x\n", hr); + + StringFromGUID2(&CLSID_AVICo, buffer, CHARS_IN_GUID); + ok(!lstrcmpW(buffer, V_BSTR(&var)), "expected %s, got %s\n", + wine_dbgstr_w(buffer), wine_dbgstr_w(V_BSTR(&var))); + + VariantClear(&var); + hr = IPropertyBag_Read(prop_bag, fcchandlerW, &var, NULL); + ok(hr == S_OK, "Read failed: %#x\n", hr); + ok(!lstrcmpW(name, V_BSTR(&var)), "expected %s, got %s\n", + wine_dbgstr_w(name), wine_dbgstr_w(V_BSTR(&var))); + + IPropertyBag_Release(prop_bag); + IMoniker_Release(mon); + } + + IParseDisplayName_Release(parser); +} + START_TEST(devenum) { IBindCtx *bind_ctx = NULL; @@ -907,6 +978,7 @@ START_TEST(devenum) test_waveout(); test_wavein(); test_midiout(); + test_vfw();
CoUninitialize(); }