devenum: Factor friendly name and CLSID registration into register_codec().

Signed-off-by: Zebediah Figura <z.figura12@gmail.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Zebediah Figura 2018-09-22 20:31:55 -05:00 committed by Alexandre Julliard
parent 1606dd39e2
commit 9ebbcb4f47
1 changed files with 98 additions and 209 deletions

View File

@ -104,11 +104,16 @@ static ULONG WINAPI DEVENUM_ICreateDevEnum_Release(ICreateDevEnum * iface)
return 1; /* non-heap based object */ return 1; /* non-heap based object */
} }
static HRESULT register_codec(const CLSID *class, const WCHAR *name, IMoniker **ret) static HRESULT register_codec(const GUID *class, const WCHAR *name,
const GUID *clsid, const WCHAR *friendly_name, IPropertyBag **ret)
{ {
static const WCHAR deviceW[] = {'@','d','e','v','i','c','e',':','c','m',':',0}; static const WCHAR deviceW[] = {'@','d','e','v','i','c','e',':','c','m',':',0};
WCHAR guidstr[CHARS_IN_GUID];
IParseDisplayName *parser; IParseDisplayName *parser;
IPropertyBag *propbag;
IMoniker *mon;
WCHAR *buffer; WCHAR *buffer;
VARIANT var;
ULONG eaten; ULONG eaten;
HRESULT hr; HRESULT hr;
@ -128,10 +133,36 @@ static HRESULT register_codec(const CLSID *class, const WCHAR *name, IMoniker **
strcatW(buffer, backslashW); strcatW(buffer, backslashW);
strcatW(buffer, name); strcatW(buffer, name);
hr = IParseDisplayName_ParseDisplayName(parser, NULL, buffer, &eaten, ret); IParseDisplayName_ParseDisplayName(parser, NULL, buffer, &eaten, &mon);
IParseDisplayName_Release(parser); IParseDisplayName_Release(parser);
heap_free(buffer); heap_free(buffer);
return hr;
IMoniker_BindToStorage(mon, NULL, NULL, &IID_IPropertyBag, (void **)&propbag);
IMoniker_Release(mon);
V_VT(&var) = VT_BSTR;
V_BSTR(&var) = SysAllocString(friendly_name);
hr = IPropertyBag_Write(propbag, wszFriendlyName, &var);
VariantClear(&var);
if (FAILED(hr))
{
IPropertyBag_Release(propbag);
return hr;
}
V_VT(&var) = VT_BSTR;
StringFromGUID2(clsid, guidstr, ARRAY_SIZE(guidstr));
V_BSTR(&var) = SysAllocString(guidstr);
hr = IPropertyBag_Write(propbag, clsidW, &var);
VariantClear(&var);
if (FAILED(hr))
{
IPropertyBag_Release(propbag);
return hr;
}
*ret = propbag;
return S_OK;
} }
static void DEVENUM_ReadPinTypes(HKEY hkeyPinKey, REGFILTERPINS2 *rgPin) static void DEVENUM_ReadPinTypes(HKEY hkeyPinKey, REGFILTERPINS2 *rgPin)
@ -412,15 +443,18 @@ static void register_legacy_filters(void)
IPropertyBag *prop_bag = NULL; IPropertyBag *prop_bag = NULL;
WCHAR wszRegKey[MAX_PATH]; WCHAR wszRegKey[MAX_PATH];
HKEY classkey = NULL; HKEY classkey = NULL;
IMoniker *mon = NULL;
VARIANT var = {};
REGFILTER2 rgf2; REGFILTER2 rgf2;
DWORD Type, len; DWORD Type, len;
GUID clsid;
if (RegEnumKeyExW(hkeyFilter, i, wszFilterSubkeyName, &cName, NULL, NULL, NULL, NULL) != ERROR_SUCCESS) continue; if (RegEnumKeyExW(hkeyFilter, i, wszFilterSubkeyName, &cName, NULL, NULL, NULL, NULL) != ERROR_SUCCESS) continue;
TRACE("Registering %s\n", debugstr_w(wszFilterSubkeyName)); TRACE("Registering %s\n", debugstr_w(wszFilterSubkeyName));
hr = CLSIDFromString(wszFilterSubkeyName, &clsid);
if (FAILED(hr))
continue;
strcpyW(wszRegKey, clsidW); strcpyW(wszRegKey, clsidW);
strcatW(wszRegKey, backslashW); strcatW(wszRegKey, backslashW);
strcatW(wszRegKey, wszFilterSubkeyName); strcatW(wszRegKey, wszFilterSubkeyName);
@ -428,40 +462,30 @@ static void register_legacy_filters(void)
if (RegOpenKeyExW(HKEY_CLASSES_ROOT, wszRegKey, 0, KEY_READ, &classkey) != ERROR_SUCCESS) if (RegOpenKeyExW(HKEY_CLASSES_ROOT, wszRegKey, 0, KEY_READ, &classkey) != ERROR_SUCCESS)
continue; continue;
hr = register_codec(&CLSID_LegacyAmFilterCategory, wszFilterSubkeyName, &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 */
len = 0; len = 0;
V_VT(&var) = VT_BSTR;
if (!RegQueryValueExW(classkey, NULL, NULL, &Type, NULL, &len)) if (!RegQueryValueExW(classkey, NULL, NULL, &Type, NULL, &len))
{ {
WCHAR *friendlyname = heap_alloc(len); WCHAR *friendlyname = heap_alloc(len);
if (!friendlyname) if (!friendlyname)
goto cleanup; {
RegCloseKey(classkey);
continue;
}
RegQueryValueExW(classkey, NULL, NULL, &Type, (BYTE *)friendlyname, &len); RegQueryValueExW(classkey, NULL, NULL, &Type, (BYTE *)friendlyname, &len);
V_BSTR(&var) = SysAllocStringLen(friendlyname, len/sizeof(WCHAR));
hr = register_codec(&CLSID_LegacyAmFilterCategory, wszFilterSubkeyName,
&clsid, friendlyname, &prop_bag);
heap_free(friendlyname); heap_free(friendlyname);
} }
else else
V_BSTR(&var) = SysAllocString(wszFilterSubkeyName); hr = register_codec(&CLSID_LegacyAmFilterCategory, wszFilterSubkeyName,
&clsid, wszFilterSubkeyName, &prop_bag);
if (!V_BSTR(&var)) if (FAILED(hr))
goto cleanup; {
hr = IPropertyBag_Write(prop_bag, wszFriendlyName, &var); RegCloseKey(classkey);
if (FAILED(hr)) goto cleanup; continue;
VariantClear(&var); }
/* write clsid */
V_VT(&var) = VT_BSTR;
if (!(V_BSTR(&var) = SysAllocString(wszFilterSubkeyName)))
goto cleanup;
hr = IPropertyBag_Write(prop_bag, clsidW, &var);
if (FAILED(hr)) goto cleanup;
VariantClear(&var);
/* write filter data */ /* write filter data */
rgf2.dwMerit = MERIT_NORMAL; rgf2.dwMerit = MERIT_NORMAL;
@ -473,11 +497,8 @@ static void register_legacy_filters(void)
write_filter_data(prop_bag, &rgf2); write_filter_data(prop_bag, &rgf2);
cleanup: IPropertyBag_Release(prop_bag);
if (prop_bag) IPropertyBag_Release(prop_bag);
if (mon) IMoniker_Release(mon);
RegCloseKey(classkey); RegCloseKey(classkey);
VariantClear(&var);
free_regfilter2(&rgf2); free_regfilter2(&rgf2);
} }
} }
@ -495,50 +516,30 @@ static BOOL CALLBACK register_dsound_devices(GUID *guid, const WCHAR *desc, cons
REGPINTYPES rgtypes = {0}; REGPINTYPES rgtypes = {0};
REGFILTER2 rgf = {0}; REGFILTER2 rgf = {0};
WCHAR clsid[CHARS_IN_GUID]; WCHAR clsid[CHARS_IN_GUID];
IMoniker *mon = NULL;
VARIANT var; VARIANT var;
HRESULT hr; HRESULT hr;
hr = DEVENUM_CreateAMCategoryKey(&CLSID_AudioRendererCategory); hr = DEVENUM_CreateAMCategoryKey(&CLSID_AudioRendererCategory);
if (FAILED(hr)) goto cleanup; if (FAILED(hr))
return FALSE;
V_VT(&var) = VT_BSTR;
if (guid) if (guid)
{ {
WCHAR *name = heap_alloc(sizeof(defaultW) + strlenW(desc) * sizeof(WCHAR)); WCHAR *name = heap_alloc(sizeof(defaultW) + strlenW(desc) * sizeof(WCHAR));
if (!name) if (!name)
goto cleanup; return FALSE;
strcpyW(name, directsoundW); strcpyW(name, directsoundW);
strcatW(name, desc); strcatW(name, desc);
V_BSTR(&var) = SysAllocString(name); hr = register_codec(&CLSID_AudioRendererCategory, name,
&CLSID_DSoundRender, name, &prop_bag);
heap_free(name); heap_free(name);
} }
else else
V_BSTR(&var) = SysAllocString(defaultW); hr = register_codec(&CLSID_AudioRendererCategory, defaultW,
&CLSID_DSoundRender, defaultW, &prop_bag);
if (!V_BSTR(&var)) if (FAILED(hr))
goto cleanup; return FALSE;
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_DSoundRender, clsid, CHARS_IN_GUID);
if (!(V_BSTR(&var) = SysAllocString(clsid)))
goto cleanup;
hr = IPropertyBag_Write(prop_bag, clsidW, &var);
if (FAILED(hr)) goto cleanup;
VariantClear(&var);
/* write filter data */ /* write filter data */
rgf.dwVersion = 2; rgf.dwVersion = 2;
@ -557,16 +558,11 @@ static BOOL CALLBACK register_dsound_devices(GUID *guid, const WCHAR *desc, cons
/* write DSound guid */ /* write DSound guid */
V_VT(&var) = VT_BSTR; V_VT(&var) = VT_BSTR;
StringFromGUID2(guid ? guid : &GUID_NULL, clsid, CHARS_IN_GUID); StringFromGUID2(guid ? guid : &GUID_NULL, clsid, CHARS_IN_GUID);
if (!(V_BSTR(&var) = SysAllocString(clsid))) if ((V_BSTR(&var) = SysAllocString(clsid)))
goto cleanup; hr = IPropertyBag_Write(prop_bag, dsguidW, &var);
hr = IPropertyBag_Write(prop_bag, dsguidW, &var);
if (FAILED(hr)) goto cleanup;
cleanup:
VariantClear(&var); VariantClear(&var);
if (prop_bag) IPropertyBag_Release(prop_bag); IPropertyBag_Release(prop_bag);
if (mon) IMoniker_Release(mon);
return TRUE; return TRUE;
} }
@ -578,9 +574,8 @@ static void register_waveout_devices(void)
REGFILTERPINS2 rgpins = {0}; REGFILTERPINS2 rgpins = {0};
REGPINTYPES rgtypes = {0}; REGPINTYPES rgtypes = {0};
REGFILTER2 rgf = {0}; REGFILTER2 rgf = {0};
WCHAR clsid[CHARS_IN_GUID];
IMoniker *mon = NULL;
WAVEOUTCAPSW caps; WAVEOUTCAPSW caps;
const WCHAR *name;
int i, count; int i, count;
VARIANT var; VARIANT var;
HRESULT hr; HRESULT hr;
@ -594,34 +589,12 @@ static void register_waveout_devices(void)
{ {
waveOutGetDevCapsW(i, &caps, sizeof(caps)); waveOutGetDevCapsW(i, &caps, sizeof(caps));
V_VT(&var) = VT_BSTR; name = (i == -1) ? defaultW : caps.szPname;
if (i == -1) /* WAVE_MAPPER */ hr = register_codec(&CLSID_AudioRendererCategory, name,
V_BSTR(&var) = SysAllocString(defaultW); &CLSID_AudioRender, name, &prop_bag);
else if (FAILED(hr))
V_BSTR(&var) = SysAllocString(caps.szPname); continue;
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, clsidW, &var);
if (FAILED(hr)) goto cleanup;
VariantClear(&var);
/* write filter data */ /* write filter data */
rgf.dwVersion = 2; rgf.dwVersion = 2;
@ -639,13 +612,10 @@ static void register_waveout_devices(void)
/* write WaveOutId */ /* write WaveOutId */
V_VT(&var) = VT_I4; V_VT(&var) = VT_I4;
V_I4(&var) = i; V_I4(&var) = i;
hr = IPropertyBag_Write(prop_bag, waveoutidW, &var); IPropertyBag_Write(prop_bag, waveoutidW, &var);
if (FAILED(hr)) goto cleanup;
cleanup:
VariantClear(&var); VariantClear(&var);
if (prop_bag) IPropertyBag_Release(prop_bag); if (prop_bag) IPropertyBag_Release(prop_bag);
if (mon) IMoniker_Release(mon);
} }
} }
@ -654,8 +624,6 @@ static void register_wavein_devices(void)
static const WCHAR waveinidW[] = {'W','a','v','e','I','n','I','d',0}; static const WCHAR waveinidW[] = {'W','a','v','e','I','n','I','d',0};
IPropertyBag *prop_bag = NULL; IPropertyBag *prop_bag = NULL;
REGFILTER2 rgf = {0}; REGFILTER2 rgf = {0};
WCHAR clsid[CHARS_IN_GUID];
IMoniker *mon = NULL;
WAVEINCAPSW caps; WAVEINCAPSW caps;
int i, count; int i, count;
VARIANT var; VARIANT var;
@ -670,31 +638,10 @@ static void register_wavein_devices(void)
{ {
waveInGetDevCapsW(i, &caps, sizeof(caps)); waveInGetDevCapsW(i, &caps, sizeof(caps));
V_VT(&var) = VT_BSTR; hr = register_codec(&CLSID_AudioInputDeviceCategory, caps.szPname,
&CLSID_AudioRecord, caps.szPname, &prop_bag);
V_BSTR(&var) = SysAllocString(caps.szPname); if (FAILED(hr))
if (!(V_BSTR(&var))) continue;
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, clsidW, &var);
if (FAILED(hr)) goto cleanup;
VariantClear(&var);
/* write filter data */ /* write filter data */
rgf.dwVersion = 2; rgf.dwVersion = 2;
@ -705,13 +652,10 @@ static void register_wavein_devices(void)
/* write WaveInId */ /* write WaveInId */
V_VT(&var) = VT_I4; V_VT(&var) = VT_I4;
V_I4(&var) = i; V_I4(&var) = i;
hr = IPropertyBag_Write(prop_bag, waveinidW, &var); IPropertyBag_Write(prop_bag, waveinidW, &var);
if (FAILED(hr)) goto cleanup;
cleanup:
VariantClear(&var); VariantClear(&var);
if (prop_bag) IPropertyBag_Release(prop_bag); IPropertyBag_Release(prop_bag);
if (mon) IMoniker_Release(mon);
} }
} }
@ -723,9 +667,8 @@ static void register_midiout_devices(void)
REGFILTERPINS2 rgpins = {0}; REGFILTERPINS2 rgpins = {0};
REGPINTYPES rgtypes = {0}; REGPINTYPES rgtypes = {0};
REGFILTER2 rgf = {0}; REGFILTER2 rgf = {0};
WCHAR clsid[CHARS_IN_GUID];
IMoniker *mon = NULL;
MIDIOUTCAPSW caps; MIDIOUTCAPSW caps;
const WCHAR *name;
int i, count; int i, count;
VARIANT var; VARIANT var;
HRESULT hr; HRESULT hr;
@ -739,34 +682,12 @@ static void register_midiout_devices(void)
{ {
midiOutGetDevCapsW(i, &caps, sizeof(caps)); midiOutGetDevCapsW(i, &caps, sizeof(caps));
V_VT(&var) = VT_BSTR; name = (i == -1) ? defaultW : caps.szPname;
if (i == -1) /* MIDI_MAPPER */ hr = register_codec(&CLSID_MidiRendererCategory, name,
V_BSTR(&var) = SysAllocString(defaultW); &CLSID_AVIMIDIRender, name, &prop_bag);
else if (FAILED(hr))
V_BSTR(&var) = SysAllocString(caps.szPname); continue;
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, clsidW, &var);
if (FAILED(hr)) goto cleanup;
VariantClear(&var);
/* write filter data */ /* write filter data */
rgf.dwVersion = 2; rgf.dwVersion = 2;
@ -784,13 +705,10 @@ static void register_midiout_devices(void)
/* write MidiOutId */ /* write MidiOutId */
V_VT(&var) = VT_I4; V_VT(&var) = VT_I4;
V_I4(&var) = i; V_I4(&var) = i;
hr = IPropertyBag_Write(prop_bag, midioutidW, &var); IPropertyBag_Write(prop_bag, midioutidW, &var);
if (FAILED(hr)) goto cleanup;
cleanup:
VariantClear(&var); VariantClear(&var);
if (prop_bag) IPropertyBag_Release(prop_bag); IPropertyBag_Release(prop_bag);
if (mon) IMoniker_Release(mon);
} }
} }
@ -801,8 +719,6 @@ static void register_vfw_codecs(void)
IPropertyBag *prop_bag = NULL; IPropertyBag *prop_bag = NULL;
REGPINTYPES rgtypes[2]; REGPINTYPES rgtypes[2];
REGFILTER2 rgf; REGFILTER2 rgf;
WCHAR clsid[CHARS_IN_GUID];
IMoniker *mon = NULL;
GUID typeguid; GUID typeguid;
ICINFO info; ICINFO info;
VARIANT var; VARIANT var;
@ -822,40 +738,10 @@ static void register_vfw_codecs(void)
ICGetInfo(hic, &info, sizeof(info)); ICGetInfo(hic, &info, sizeof(info));
ICClose(hic); ICClose(hic);
V_VT(&var) = VT_BSTR; hr = register_codec(&CLSID_VideoCompressorCategory, name,
&CLSID_AVICo, info.szDescription, &prop_bag);
V_BSTR(&var) = SysAllocString(name); if (FAILED(hr))
if (!(V_BSTR(&var))) continue;
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, clsidW, &var);
if (FAILED(hr)) goto cleanup;
VariantClear(&var);
/* write filter data */ /* write filter data */
rgf.dwVersion = 2; rgf.dwVersion = 2;
@ -877,10 +763,13 @@ static void register_vfw_codecs(void)
write_filter_data(prop_bag, &rgf); write_filter_data(prop_bag, &rgf);
cleanup: /* write WaveInId */
V_VT(&var) = VT_BSTR;
V_BSTR(&var) = SysAllocString(name);
IPropertyBag_Write(prop_bag, fcchandlerW, &var);
VariantClear(&var); VariantClear(&var);
if (prop_bag) IPropertyBag_Release(prop_bag); IPropertyBag_Release(prop_bag);
if (mon) IMoniker_Release(mon);
} }
} }