From b0300ce56483fb2f2a03de8aa216d41b0bfd034e Mon Sep 17 00:00:00 2001 From: Zebediah Figura Date: Tue, 6 Mar 2018 20:57:10 -0600 Subject: [PATCH] devenum: Correctly implement IMoniker::GetDisplayName(). Signed-off-by: Zebediah Figura Signed-off-by: Alexandre Julliard --- dlls/devenum/devenum_private.h | 1 + dlls/devenum/mediacatenum.c | 55 +++++++++++++++++++++++++--------- dlls/devenum/tests/devenum.c | 4 +-- 3 files changed, 44 insertions(+), 16 deletions(-) diff --git a/dlls/devenum/devenum_private.h b/dlls/devenum/devenum_private.h index 9a0b5ad7bf6..83d0ce398e1 100644 --- a/dlls/devenum/devenum_private.h +++ b/dlls/devenum/devenum_private.h @@ -95,6 +95,7 @@ static const WCHAR wszActiveMovieKey[] = {'S','o','f','t','w','a','r','e','\\', 'M','i','c','r','o','s','o','f','t','\\', 'A','c','t','i','v','e','M','o','v','i','e','\\', 'd','e','v','e','n','u','m','\\',0}; +static const WCHAR deviceW[] = {'@','d','e','v','i','c','e',':',0}; extern const WCHAR clsid_keyname[6] DECLSPEC_HIDDEN; diff --git a/dlls/devenum/mediacatenum.c b/dlls/devenum/mediacatenum.c index 0f38a0e24d5..0d4e01e5361 100644 --- a/dlls/devenum/mediacatenum.c +++ b/dlls/devenum/mediacatenum.c @@ -33,6 +33,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(devenum); typedef struct { IEnumMoniker IEnumMoniker_iface; + CLSID class; LONG ref; HKEY sw_key; DWORD sw_index; @@ -621,24 +622,35 @@ static HRESULT WINAPI DEVENUM_IMediaCatMoniker_RelativePathTo(IMoniker *iface, I static HRESULT WINAPI DEVENUM_IMediaCatMoniker_GetDisplayName(IMoniker *iface, IBindCtx *pbc, IMoniker *pmkToLeft, LPOLESTR *ppszDisplayName) { + static const WCHAR swW[] = {'s','w',':',0}; + static const WCHAR cmW[] = {'c','m',':',0}; MediaCatMoniker *This = impl_from_IMoniker(iface); - WCHAR wszBuffer[MAX_PATH]; - static const WCHAR wszFriendlyName[] = {'F','r','i','e','n','d','l','y','N','a','m','e',0}; - DWORD received = sizeof(wszBuffer); + WCHAR *buffer; TRACE("(%p)->(%p, %p, %p)\n", iface, pbc, pmkToLeft, ppszDisplayName); *ppszDisplayName = NULL; - /* FIXME: should this be the weird stuff we have to parse in IParseDisplayName? */ - if (RegQueryValueExW(This->hkey, wszFriendlyName, NULL, NULL, (LPBYTE)wszBuffer, &received) == ERROR_SUCCESS) - { - *ppszDisplayName = CoTaskMemAlloc(received); - strcpyW(*ppszDisplayName, wszBuffer); - return S_OK; - } + buffer = CoTaskMemAlloc((strlenW(deviceW) + 4 + (This->has_class ? CHARS_IN_GUID : 0) + + strlenW(This->name) + 1) * sizeof(WCHAR)); + if (!buffer) + return E_OUTOFMEMORY; - return E_FAIL; + strcpyW(buffer, deviceW); + if (This->type == DEVICE_FILTER) + strcatW(buffer, swW); + else if (This->type == DEVICE_CODEC) + strcatW(buffer, cmW); + + if (This->has_class) + { + StringFromGUID2(&This->class, buffer + strlenW(buffer), CHARS_IN_GUID); + strcatW(buffer, backslashW); + } + strcatW(buffer, This->name); + + *ppszDisplayName = buffer; + return S_OK; } static HRESULT WINAPI DEVENUM_IMediaCatMoniker_ParseDisplayName(IMoniker *iface, IBindCtx *pbc, @@ -782,6 +794,11 @@ static HRESULT WINAPI DEVENUM_IEnumMoniker_Next(IEnumMoniker *iface, ULONG celt, This->sw_index++; if ((res = RegOpenKeyExW(This->sw_key, buffer, 0, KEY_QUERY_VALUE, &hkey))) break; + + if (!(pMoniker = DEVENUM_IMediaCatMoniker_Construct())) + return E_OUTOFMEMORY; + + pMoniker->type = DEVICE_FILTER; } /* then try codecs */ else if (!(res = RegEnumKeyW(This->cm_key, This->cm_index, buffer, sizeof(buffer)/sizeof(WCHAR)))) @@ -790,14 +807,23 @@ static HRESULT WINAPI DEVENUM_IEnumMoniker_Next(IEnumMoniker *iface, ULONG celt, if ((res = RegOpenKeyExW(This->cm_key, buffer, 0, KEY_QUERY_VALUE, &hkey))) break; + + if (!(pMoniker = DEVENUM_IMediaCatMoniker_Construct())) + return E_OUTOFMEMORY; + + pMoniker->type = DEVICE_CODEC; } else break; - pMoniker = DEVENUM_IMediaCatMoniker_Construct(); - if (!pMoniker) + if (!(pMoniker->name = CoTaskMemAlloc((strlenW(buffer) + 1) * sizeof(WCHAR)))) + { + IMoniker_Release(&pMoniker->IMoniker_iface); return E_OUTOFMEMORY; - + } + strcpyW(pMoniker->name, buffer); + pMoniker->has_class = TRUE; + pMoniker->class = This->class; pMoniker->hkey = hkey; rgelt[fetched] = &pMoniker->IMoniker_iface; @@ -887,6 +913,7 @@ HRESULT create_EnumMoniker(REFCLSID class, IEnumMoniker **ppEnumMoniker) pEnumMoniker->ref = 1; pEnumMoniker->sw_index = 0; pEnumMoniker->cm_index = 0; + pEnumMoniker->class = *class; strcpyW(buffer, clsidW); StringFromGUID2(class, buffer + strlenW(buffer), CHARS_IN_GUID); diff --git a/dlls/devenum/tests/devenum.c b/dlls/devenum/tests/devenum.c index fe8cb2e1ffd..0437b6b230f 100644 --- a/dlls/devenum/tests/devenum.c +++ b/dlls/devenum/tests/devenum.c @@ -293,10 +293,8 @@ static IMoniker *check_display_name_(int line, IParseDisplayName *parser, WCHAR ok_(__FILE__, line)(hr == S_OK, "ParseDisplayName failed: %#x\n", hr); hr = IMoniker_GetDisplayName(mon, NULL, NULL, &str); -todo_wine { ok_(__FILE__, line)(hr == S_OK, "GetDisplayName failed: %#x\n", hr); ok_(__FILE__, line)(!lstrcmpW(str, buffer), "got %s\n", wine_dbgstr_w(str)); -} CoTaskMemFree(str); @@ -328,6 +326,7 @@ static void test_directshow_filter(void) mon = check_display_name(parser, buffer); /* Test writing and reading from the property bag */ +todo_wine ok(!find_moniker(&CLSID_AudioRendererCategory, mon), "filter should not be registered\n"); hr = IMoniker_BindToStorage(mon, NULL, NULL, &IID_IPropertyBag, (void **)&prop_bag); @@ -426,6 +425,7 @@ static void test_codec(void) mon = check_display_name(parser, buffer); /* Test writing and reading from the property bag */ +todo_wine ok(!find_moniker(&CLSID_AudioRendererCategory, mon), "codec should not be registered\n"); hr = IMoniker_BindToStorage(mon, NULL, NULL, &IID_IPropertyBag, (void **)&prop_bag);