[prev in list] [next in list] [prev in thread] [next in thread]
List: wine-devel
Subject: [PATCH v2 4/4] devenum: Register VFW codecs as codec devices.
From: Zebediah Figura <z.figura12 () gmail ! com>
Date: 2018-03-31 21:25:18
Message-ID: 1522531518-18146-5-git-send-email-z.figura12 () gmail ! com
[Download RAW message or body]
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();
}
--
2.7.4
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic