devenum: Implement enumerating DMOs.

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-06-24 17:20:30 -05:00 committed by Alexandre Julliard
parent 0da4892b45
commit e119f245f1
2 changed files with 49 additions and 10 deletions

View File

@ -36,6 +36,7 @@ typedef struct
IEnumMoniker IEnumMoniker_iface; IEnumMoniker IEnumMoniker_iface;
CLSID class; CLSID class;
LONG ref; LONG ref;
IEnumDMO *dmo_enum;
HKEY sw_key; HKEY sw_key;
DWORD sw_index; DWORD sw_index;
HKEY cm_key; HKEY cm_key;
@ -845,6 +846,7 @@ static ULONG WINAPI DEVENUM_IEnumMoniker_Release(IEnumMoniker *iface)
if (!ref) if (!ref)
{ {
IEnumDMO_Release(This->dmo_enum);
RegCloseKey(This->sw_key); RegCloseKey(This->sw_key);
RegCloseKey(This->cm_key); RegCloseKey(This->cm_key);
CoTaskMemFree(This); CoTaskMemFree(This);
@ -862,16 +864,31 @@ static HRESULT WINAPI DEVENUM_IEnumMoniker_Next(IEnumMoniker *iface, ULONG celt,
LONG res; LONG res;
ULONG fetched = 0; ULONG fetched = 0;
MediaCatMoniker * pMoniker; MediaCatMoniker * pMoniker;
WCHAR *name;
CLSID clsid;
HRESULT hr;
HKEY hkey; HKEY hkey;
TRACE("(%p)->(%d, %p, %p)\n", iface, celt, rgelt, pceltFetched); TRACE("(%p)->(%d, %p, %p)\n", iface, celt, rgelt, pceltFetched);
while (fetched < celt) while (fetched < celt)
{ {
/* FIXME: try PNP devices and DMOs first */ /* FIXME: try PNP devices first */
/* try DMOs */
if ((hr = IEnumDMO_Next(This->dmo_enum, 1, &clsid, &name, NULL)) == S_OK)
{
if (!(pMoniker = DEVENUM_IMediaCatMoniker_Construct()))
return E_OUTOFMEMORY;
pMoniker->type = DEVICE_DMO;
pMoniker->clsid = clsid;
StringFromGUID2(&clsid, buffer, CHARS_IN_GUID);
StringFromGUID2(&This->class, buffer + CHARS_IN_GUID - 1, CHARS_IN_GUID);
}
/* try DirectShow filters */ /* try DirectShow filters */
if (!(res = RegEnumKeyW(This->sw_key, This->sw_index, buffer, sizeof(buffer)/sizeof(WCHAR)))) else if (!(res = RegEnumKeyW(This->sw_key, This->sw_index, buffer, sizeof(buffer)/sizeof(WCHAR))))
{ {
This->sw_index++; This->sw_index++;
if ((res = RegOpenKeyExW(This->sw_key, buffer, 0, KEY_QUERY_VALUE, &hkey))) if ((res = RegOpenKeyExW(This->sw_key, buffer, 0, KEY_QUERY_VALUE, &hkey)))
@ -881,6 +898,13 @@ static HRESULT WINAPI DEVENUM_IEnumMoniker_Next(IEnumMoniker *iface, ULONG celt,
return E_OUTOFMEMORY; return E_OUTOFMEMORY;
pMoniker->type = DEVICE_FILTER; pMoniker->type = DEVICE_FILTER;
if (!(pMoniker->name = CoTaskMemAlloc((strlenW(buffer) + 1) * sizeof(WCHAR))))
{
IMoniker_Release(&pMoniker->IMoniker_iface);
return E_OUTOFMEMORY;
}
strcpyW(pMoniker->name, buffer);
} }
/* then try codecs */ /* then try codecs */
else if (!(res = RegEnumKeyW(This->cm_key, This->cm_index, buffer, sizeof(buffer)/sizeof(WCHAR)))) else if (!(res = RegEnumKeyW(This->cm_key, This->cm_index, buffer, sizeof(buffer)/sizeof(WCHAR))))
@ -894,9 +918,6 @@ static HRESULT WINAPI DEVENUM_IEnumMoniker_Next(IEnumMoniker *iface, ULONG celt,
return E_OUTOFMEMORY; return E_OUTOFMEMORY;
pMoniker->type = DEVICE_CODEC; pMoniker->type = DEVICE_CODEC;
}
else
break;
if (!(pMoniker->name = CoTaskMemAlloc((strlenW(buffer) + 1) * sizeof(WCHAR)))) if (!(pMoniker->name = CoTaskMemAlloc((strlenW(buffer) + 1) * sizeof(WCHAR))))
{ {
@ -904,6 +925,10 @@ static HRESULT WINAPI DEVENUM_IEnumMoniker_Next(IEnumMoniker *iface, ULONG celt,
return E_OUTOFMEMORY; return E_OUTOFMEMORY;
} }
strcpyW(pMoniker->name, buffer); strcpyW(pMoniker->name, buffer);
}
else
break;
pMoniker->has_class = TRUE; pMoniker->has_class = TRUE;
pMoniker->class = This->class; pMoniker->class = This->class;
@ -930,10 +955,13 @@ static HRESULT WINAPI DEVENUM_IEnumMoniker_Skip(IEnumMoniker *iface, ULONG celt)
while (celt--) while (celt--)
{ {
/* FIXME: try PNP devices and DMOs first */ /* FIXME: try PNP devices first */
/* try DMOs */
if (IEnumDMO_Skip(This->dmo_enum, 1) == S_OK)
;
/* try DirectShow filters */ /* try DirectShow filters */
if (RegEnumKeyW(This->sw_key, This->sw_index, NULL, 0) != ERROR_NO_MORE_ITEMS) else if (RegEnumKeyW(This->sw_key, This->sw_index, NULL, 0) != ERROR_NO_MORE_ITEMS)
{ {
This->sw_index++; This->sw_index++;
} }
@ -955,6 +983,7 @@ static HRESULT WINAPI DEVENUM_IEnumMoniker_Reset(IEnumMoniker *iface)
TRACE("(%p)->()\n", iface); TRACE("(%p)->()\n", iface);
IEnumDMO_Reset(This->dmo_enum);
This->sw_index = 0; This->sw_index = 0;
This->cm_index = 0; This->cm_index = 0;
@ -986,6 +1015,7 @@ HRESULT create_EnumMoniker(REFCLSID class, IEnumMoniker **ppEnumMoniker)
{ {
EnumMonikerImpl * pEnumMoniker = CoTaskMemAlloc(sizeof(EnumMonikerImpl)); EnumMonikerImpl * pEnumMoniker = CoTaskMemAlloc(sizeof(EnumMonikerImpl));
WCHAR buffer[78]; WCHAR buffer[78];
HRESULT hr;
if (!pEnumMoniker) if (!pEnumMoniker)
return E_OUTOFMEMORY; return E_OUTOFMEMORY;
@ -1007,6 +1037,13 @@ HRESULT create_EnumMoniker(REFCLSID class, IEnumMoniker **ppEnumMoniker)
if (RegOpenKeyExW(HKEY_CURRENT_USER, buffer, 0, KEY_ENUMERATE_SUB_KEYS, &pEnumMoniker->cm_key)) if (RegOpenKeyExW(HKEY_CURRENT_USER, buffer, 0, KEY_ENUMERATE_SUB_KEYS, &pEnumMoniker->cm_key))
pEnumMoniker->cm_key = NULL; pEnumMoniker->cm_key = NULL;
hr = DMOEnum(class, 0, 0, NULL, 0, NULL, &pEnumMoniker->dmo_enum);
if (FAILED(hr))
{
IEnumMoniker_Release(&pEnumMoniker->IEnumMoniker_iface);
return hr;
}
*ppEnumMoniker = &pEnumMoniker->IEnumMoniker_iface; *ppEnumMoniker = &pEnumMoniker->IEnumMoniker_iface;
DEVENUM_LockModule(); DEVENUM_LockModule();

View File

@ -525,6 +525,8 @@ static void test_dmo(void)
{ {
ok(hr == S_OK, "got %#x\n", hr); ok(hr == S_OK, "got %#x\n", hr);
ok(find_moniker(&CLSID_AudioRendererCategory, mon), "DMO should be registered\n");
VariantClear(&var); VariantClear(&var);
hr = IPropertyBag_Read(prop_bag, friendly_name, &var, NULL); hr = IPropertyBag_Read(prop_bag, friendly_name, &var, NULL);
ok(hr == S_OK, "got %#x\n", hr); ok(hr == S_OK, "got %#x\n", hr);