Zebediah Figura : devenum: Register waveIn devices as codec devices.
Alexandre Julliard
julliard at winehq.org
Mon Apr 2 16:32:51 CDT 2018
Module: wine
Branch: master
Commit: c64f6ad08d70efd3d9329f6e96f7066b870dbccc
URL: https://source.winehq.org/git/wine.git/?a=commit;h=c64f6ad08d70efd3d9329f6e96f7066b870dbccc
Author: Zebediah Figura <z.figura12 at gmail.com>
Date: Sat Mar 31 16:25:16 2018 -0500
devenum: Register waveIn devices as codec devices.
Signed-off-by: Zebediah Figura <z.figura12 at gmail.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/devenum/createdevenum.c | 131 ++++++++++++++++++++++---------------------
dlls/devenum/tests/devenum.c | 87 ++++++++++++++++++++++++++++
2 files changed, 154 insertions(+), 64 deletions(-)
diff --git a/dlls/devenum/createdevenum.c b/dlls/devenum/createdevenum.c
index e3fe049..3eab18e 100644
--- a/dlls/devenum/createdevenum.c
+++ b/dlls/devenum/createdevenum.c
@@ -52,7 +52,6 @@ static const WCHAR wszDirection[] = {'D','i','r','e','c','t','i','o','n',0};
static const WCHAR wszIsRendered[] = {'I','s','R','e','n','d','e','r','e','d',0};
static const WCHAR wszTypes[] = {'T','y','p','e','s',0};
static const WCHAR wszFriendlyName[] = {'F','r','i','e','n','d','l','y','N','a','m','e',0};
-static const WCHAR wszWaveInID[] = {'W','a','v','e','I','n','I','D',0};
static const WCHAR wszFilterData[] = {'F','i','l','t','e','r','D','a','t','a',0};
static ULONG WINAPI DEVENUM_ICreateDevEnum_AddRef(ICreateDevEnum * iface);
@@ -673,6 +672,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 +761,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 +898,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();
}
More information about the wine-cvs
mailing list