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(); }