diff --git a/dlls/devenum/mediacatenum.c b/dlls/devenum/mediacatenum.c index 07dcb1438f7..6f0209f39b1 100644 --- a/dlls/devenum/mediacatenum.c +++ b/dlls/devenum/mediacatenum.c @@ -33,7 +33,7 @@ typedef struct IEnumMoniker IEnumMoniker_iface; CLSID class; LONG ref; - IEnumDMO *dmo_enum; + IEnumDMO *dmo_enum, *dmo_enum2; HKEY sw_key; DWORD sw_index; HKEY cm_key; @@ -786,7 +786,10 @@ static ULONG WINAPI enum_moniker_Release(IEnumMoniker *iface) 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->cm_key); free(This); @@ -796,6 +799,26 @@ static ULONG WINAPI enum_moniker_Release(IEnumMoniker *iface) 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, ULONG *pceltFetched) { @@ -804,8 +827,6 @@ static HRESULT WINAPI enum_moniker_Next(IEnumMoniker *iface, ULONG celt, IMonike struct moniker *moniker; LONG res; ULONG fetched = 0; - HRESULT hr; - GUID clsid; HKEY hkey; 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 */ /* try DMOs */ - if ((hr = IEnumDMO_Next(This->dmo_enum, 1, &clsid, NULL, NULL)) == S_OK) - { - moniker = dmo_moniker_create(This->class, clsid); - } + if ((moniker = get_dmo_moniker(This))) + ; /* try DirectShow filters */ 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 */ /* 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 */ 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); - 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->cm_index = 0; @@ -926,7 +950,6 @@ HRESULT enum_moniker_create(REFCLSID class, IEnumMoniker **out) { EnumMonikerImpl *object; WCHAR buffer[78]; - HRESULT hr; if (!(object = calloc(1, sizeof(*object)))) 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)) object->cm_key = NULL; - hr = DMOEnum(class, 0, 0, NULL, 0, NULL, &object->dmo_enum); - if (FAILED(hr)) + if (IsEqualGUID(class, &CLSID_LegacyAmFilterCategory)) { - if (object->cm_key) - RegCloseKey(object->cm_key); - if (object->sw_key) - RegCloseKey(object->sw_key); - free(object); - return hr; + if (FAILED(DMOEnum(&DMOCATEGORY_AUDIO_DECODER, 0, 0, NULL, 0, NULL, &object->dmo_enum))) + object->dmo_enum = NULL; + if (FAILED(DMOEnum(&DMOCATEGORY_VIDEO_DECODER, 0, 0, NULL, 0, NULL, &object->dmo_enum2))) + object->dmo_enum2 = NULL; + } + else + { + if (FAILED(DMOEnum(class, 0, 0, NULL, 0, NULL, &object->dmo_enum))) + object->dmo_enum = NULL; } *out = &object->IEnumMoniker_iface; diff --git a/dlls/devenum/tests/devenum.c b/dlls/devenum/tests/devenum.c index 93692f75e62..3e0d6f57dc3 100644 --- a/dlls/devenum/tests/devenum.c +++ b/dlls/devenum/tests/devenum.c @@ -245,16 +245,18 @@ static BOOL find_moniker(const GUID *class, IMoniker *needle) BOOL found = FALSE; CoCreateInstance(&CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC, &IID_ICreateDevEnum, (void **)&devenum); - ICreateDevEnum_CreateClassEnumerator(devenum, class, &enum_mon, 0); - while (!found && IEnumMoniker_Next(enum_mon, 1, &mon, NULL) == S_OK) + if (ICreateDevEnum_CreateClassEnumerator(devenum, class, &enum_mon, 0) == S_OK) { - if (IMoniker_IsEqual(mon, needle) == S_OK) - found = TRUE; + while (!found && IEnumMoniker_Next(enum_mon, 1, &mon, NULL) == S_OK) + { + 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); return found; } @@ -594,7 +596,7 @@ static void test_codec(void) IParseDisplayName_Release(parser); } -static void test_dmo(void) +static void test_dmo(const GUID *dmo_category, const GUID *enum_category) { IParseDisplayName *parser; IPropertyBag *prop_bag; @@ -613,10 +615,10 @@ static void test_dmo(void) wcscpy(buffer, L"@device:dmo:"); 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); - 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); 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); 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) { 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); 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); 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); } IPropertyBag_Release(prop_bag); @@ -1168,7 +1170,9 @@ START_TEST(devenum) test_register_filter(); test_directshow_filter(); 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(); hr = DirectSoundEnumerateW(test_dsound, NULL);