[PATCH v2 3/4] devenum: Register midiOut devices as codec devices.
Zebediah Figura
z.figura12 at gmail.com
Sat Mar 31 16:25:17 CDT 2018
Signed-off-by: Zebediah Figura <z.figura12 at 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();
}
--
2.7.4
More information about the wine-devel
mailing list