devenum: Map CLSID_LegacyAmFilterCategory to DMOCATEGORY_AUDIO_DECODER and DMOCATEGORY_VIDEO_DECODER.

Signed-off-by: Zebediah Figura <z.figura12@gmail.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
feature/deterministic
Zebediah Figura 2020-05-13 17:03:08 -05:00 committed by Alexandre Julliard
parent af68dafc63
commit 90a99806ac
2 changed files with 62 additions and 33 deletions

View File

@ -33,7 +33,7 @@ typedef struct
IEnumMoniker IEnumMoniker_iface; IEnumMoniker IEnumMoniker_iface;
CLSID class; CLSID class;
LONG ref; LONG ref;
IEnumDMO *dmo_enum; IEnumDMO *dmo_enum, *dmo_enum2;
HKEY sw_key; HKEY sw_key;
DWORD sw_index; DWORD sw_index;
HKEY cm_key; HKEY cm_key;
@ -786,7 +786,10 @@ static ULONG WINAPI enum_moniker_Release(IEnumMoniker *iface)
if (!ref) if (!ref)
{ {
IEnumDMO_Release(This->dmo_enum); if (This->dmo_enum)
IEnumDMO_Release(This->dmo_enum);
if (This->dmo_enum2)
IEnumDMO_Release(This->dmo_enum2);
RegCloseKey(This->sw_key); RegCloseKey(This->sw_key);
RegCloseKey(This->cm_key); RegCloseKey(This->cm_key);
free(This); free(This);
@ -796,6 +799,26 @@ static ULONG WINAPI enum_moniker_Release(IEnumMoniker *iface)
return ref; return ref;
} }
static struct moniker *get_dmo_moniker(EnumMonikerImpl *enum_moniker)
{
GUID clsid;
if (IsEqualGUID(&enum_moniker->class, &CLSID_LegacyAmFilterCategory))
{
if (enum_moniker->dmo_enum && IEnumDMO_Next(enum_moniker->dmo_enum, 1, &clsid, NULL, NULL) == S_OK)
return dmo_moniker_create(DMOCATEGORY_AUDIO_DECODER, clsid);
if (enum_moniker->dmo_enum2 && IEnumDMO_Next(enum_moniker->dmo_enum2, 1, &clsid, NULL, NULL) == S_OK)
return dmo_moniker_create(DMOCATEGORY_VIDEO_DECODER, clsid);
}
else
{
if (enum_moniker->dmo_enum && IEnumDMO_Next(enum_moniker->dmo_enum, 1, &clsid, NULL, NULL) == S_OK)
return dmo_moniker_create(enum_moniker->class, clsid);
}
return NULL;
}
static HRESULT WINAPI enum_moniker_Next(IEnumMoniker *iface, ULONG celt, IMoniker **rgelt, static HRESULT WINAPI enum_moniker_Next(IEnumMoniker *iface, ULONG celt, IMoniker **rgelt,
ULONG *pceltFetched) ULONG *pceltFetched)
{ {
@ -804,8 +827,6 @@ static HRESULT WINAPI enum_moniker_Next(IEnumMoniker *iface, ULONG celt, IMonike
struct moniker *moniker; struct moniker *moniker;
LONG res; LONG res;
ULONG fetched = 0; ULONG fetched = 0;
HRESULT hr;
GUID clsid;
HKEY hkey; HKEY hkey;
TRACE("(%p)->(%d, %p, %p)\n", iface, celt, rgelt, pceltFetched); TRACE("(%p)->(%d, %p, %p)\n", iface, celt, rgelt, pceltFetched);
@ -815,10 +836,8 @@ static HRESULT WINAPI enum_moniker_Next(IEnumMoniker *iface, ULONG celt, IMonike
/* FIXME: try PNP devices first */ /* FIXME: try PNP devices first */
/* try DMOs */ /* try DMOs */
if ((hr = IEnumDMO_Next(This->dmo_enum, 1, &clsid, NULL, NULL)) == S_OK) if ((moniker = get_dmo_moniker(This)))
{ ;
moniker = dmo_moniker_create(This->class, clsid);
}
/* try DirectShow filters */ /* try DirectShow filters */
else if (!(res = RegEnumKeyW(This->sw_key, This->sw_index, buffer, ARRAY_SIZE(buffer)))) else if (!(res = RegEnumKeyW(This->sw_key, This->sw_index, buffer, ARRAY_SIZE(buffer))))
{ {
@ -869,7 +888,9 @@ static HRESULT WINAPI enum_moniker_Skip(IEnumMoniker *iface, ULONG celt)
/* FIXME: try PNP devices first */ /* FIXME: try PNP devices first */
/* try DMOs */ /* try DMOs */
if (IEnumDMO_Skip(This->dmo_enum, 1) == S_OK) if (This->dmo_enum && IEnumDMO_Skip(This->dmo_enum, 1) == S_OK)
;
else if (This->dmo_enum2 && IEnumDMO_Skip(This->dmo_enum2, 1) == S_OK)
; ;
/* try DirectShow filters */ /* try DirectShow filters */
else 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)
@ -894,7 +915,10 @@ static HRESULT WINAPI enum_moniker_Reset(IEnumMoniker *iface)
TRACE("(%p)->()\n", iface); TRACE("(%p)->()\n", iface);
IEnumDMO_Reset(This->dmo_enum); if (This->dmo_enum)
IEnumDMO_Reset(This->dmo_enum);
if (This->dmo_enum2)
IEnumDMO_Reset(This->dmo_enum2);
This->sw_index = 0; This->sw_index = 0;
This->cm_index = 0; This->cm_index = 0;
@ -926,7 +950,6 @@ HRESULT enum_moniker_create(REFCLSID class, IEnumMoniker **out)
{ {
EnumMonikerImpl *object; EnumMonikerImpl *object;
WCHAR buffer[78]; WCHAR buffer[78];
HRESULT hr;
if (!(object = calloc(1, sizeof(*object)))) if (!(object = calloc(1, sizeof(*object))))
return E_OUTOFMEMORY; return E_OUTOFMEMORY;
@ -947,15 +970,17 @@ HRESULT enum_moniker_create(REFCLSID class, IEnumMoniker **out)
if (RegOpenKeyExW(HKEY_CURRENT_USER, buffer, 0, KEY_ENUMERATE_SUB_KEYS, &object->cm_key)) if (RegOpenKeyExW(HKEY_CURRENT_USER, buffer, 0, KEY_ENUMERATE_SUB_KEYS, &object->cm_key))
object->cm_key = NULL; object->cm_key = NULL;
hr = DMOEnum(class, 0, 0, NULL, 0, NULL, &object->dmo_enum); if (IsEqualGUID(class, &CLSID_LegacyAmFilterCategory))
if (FAILED(hr))
{ {
if (object->cm_key) if (FAILED(DMOEnum(&DMOCATEGORY_AUDIO_DECODER, 0, 0, NULL, 0, NULL, &object->dmo_enum)))
RegCloseKey(object->cm_key); object->dmo_enum = NULL;
if (object->sw_key) if (FAILED(DMOEnum(&DMOCATEGORY_VIDEO_DECODER, 0, 0, NULL, 0, NULL, &object->dmo_enum2)))
RegCloseKey(object->sw_key); object->dmo_enum2 = NULL;
free(object); }
return hr; else
{
if (FAILED(DMOEnum(class, 0, 0, NULL, 0, NULL, &object->dmo_enum)))
object->dmo_enum = NULL;
} }
*out = &object->IEnumMoniker_iface; *out = &object->IEnumMoniker_iface;

View File

@ -245,16 +245,18 @@ static BOOL find_moniker(const GUID *class, IMoniker *needle)
BOOL found = FALSE; BOOL found = FALSE;
CoCreateInstance(&CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC, &IID_ICreateDevEnum, (void **)&devenum); CoCreateInstance(&CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC, &IID_ICreateDevEnum, (void **)&devenum);
ICreateDevEnum_CreateClassEnumerator(devenum, class, &enum_mon, 0); if (ICreateDevEnum_CreateClassEnumerator(devenum, class, &enum_mon, 0) == S_OK)
while (!found && IEnumMoniker_Next(enum_mon, 1, &mon, NULL) == S_OK)
{ {
if (IMoniker_IsEqual(mon, needle) == S_OK) while (!found && IEnumMoniker_Next(enum_mon, 1, &mon, NULL) == S_OK)
found = TRUE; {
if (IMoniker_IsEqual(mon, needle) == S_OK)
found = TRUE;
IMoniker_Release(mon); IMoniker_Release(mon);
}
IEnumMoniker_Release(enum_mon);
} }
IEnumMoniker_Release(enum_mon);
ICreateDevEnum_Release(devenum); ICreateDevEnum_Release(devenum);
return found; return found;
} }
@ -594,7 +596,7 @@ static void test_codec(void)
IParseDisplayName_Release(parser); IParseDisplayName_Release(parser);
} }
static void test_dmo(void) static void test_dmo(const GUID *dmo_category, const GUID *enum_category)
{ {
IParseDisplayName *parser; IParseDisplayName *parser;
IPropertyBag *prop_bag; IPropertyBag *prop_bag;
@ -613,10 +615,10 @@ static void test_dmo(void)
wcscpy(buffer, L"@device:dmo:"); wcscpy(buffer, L"@device:dmo:");
StringFromGUID2(&CLSID_TestFilter, buffer + wcslen(buffer), CHARS_IN_GUID); StringFromGUID2(&CLSID_TestFilter, buffer + wcslen(buffer), CHARS_IN_GUID);
StringFromGUID2(&CLSID_AudioRendererCategory, buffer + wcslen(buffer), CHARS_IN_GUID); StringFromGUID2(dmo_category, buffer + wcslen(buffer), CHARS_IN_GUID);
mon = check_display_name(parser, buffer); mon = check_display_name(parser, buffer);
ok(!find_moniker(&CLSID_AudioRendererCategory, mon), "DMO should not be registered\n"); ok(!find_moniker(enum_category, mon), "DMO should not be registered\n");
hr = IMoniker_BindToStorage(mon, NULL, NULL, &IID_IPropertyBag, (void **)&prop_bag); hr = IMoniker_BindToStorage(mon, NULL, NULL, &IID_IPropertyBag, (void **)&prop_bag);
ok(hr == S_OK, "got %#x\n", hr); ok(hr == S_OK, "got %#x\n", hr);
@ -630,12 +632,12 @@ static void test_dmo(void)
hr = IPropertyBag_Write(prop_bag, L"FriendlyName", &var); hr = IPropertyBag_Write(prop_bag, L"FriendlyName", &var);
ok(hr == E_ACCESSDENIED, "Write failed: %#x\n", hr); ok(hr == E_ACCESSDENIED, "Write failed: %#x\n", hr);
hr = DMORegister(L"devenum test", &CLSID_TestFilter, &CLSID_AudioRendererCategory, 0, 0, NULL, 0, NULL); hr = DMORegister(L"devenum test", &CLSID_TestFilter, dmo_category, 0, 0, NULL, 0, NULL);
if (hr != E_FAIL) if (hr != E_FAIL)
{ {
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"); ok(find_moniker(enum_category, mon), "DMO should be registered\n");
VariantClear(&var); VariantClear(&var);
hr = IPropertyBag_Read(prop_bag, L"FriendlyName", &var, NULL); hr = IPropertyBag_Read(prop_bag, L"FriendlyName", &var, NULL);
@ -652,7 +654,7 @@ static void test_dmo(void)
hr = IPropertyBag_Read(prop_bag, L"CLSID", &var, NULL); hr = IPropertyBag_Read(prop_bag, L"CLSID", &var, NULL);
ok(hr == HRESULT_FROM_WIN32(ERROR_NOT_FOUND), "got %#x\n", hr); ok(hr == HRESULT_FROM_WIN32(ERROR_NOT_FOUND), "got %#x\n", hr);
hr = DMOUnregister(&CLSID_TestFilter, &CLSID_AudioRendererCategory); hr = DMOUnregister(&CLSID_TestFilter, dmo_category);
ok(hr == S_OK, "got %#x\n", hr); ok(hr == S_OK, "got %#x\n", hr);
} }
IPropertyBag_Release(prop_bag); IPropertyBag_Release(prop_bag);
@ -1168,7 +1170,9 @@ START_TEST(devenum)
test_register_filter(); test_register_filter();
test_directshow_filter(); test_directshow_filter();
test_codec(); test_codec();
test_dmo(); test_dmo(&DMOCATEGORY_AUDIO_DECODER, &CLSID_LegacyAmFilterCategory);
test_dmo(&DMOCATEGORY_VIDEO_DECODER, &CLSID_LegacyAmFilterCategory);
test_dmo(&DMOCATEGORY_VIDEO_DECODER, &DMOCATEGORY_VIDEO_DECODER);
test_legacy_filter(); test_legacy_filter();
hr = DirectSoundEnumerateW(test_dsound, NULL); hr = DirectSoundEnumerateW(test_dsound, NULL);