Signed-off-by: Zebediah Figura z.figura12@gmail.com --- v2: Actually test passing a "left" moniker, and fix a crash on winxp.
dlls/devenum/mediacatenum.c | 88 ++++++++++++++++-------------------- dlls/devenum/tests/devenum.c | 18 +++++++- 2 files changed, 56 insertions(+), 50 deletions(-)
diff --git a/dlls/devenum/mediacatenum.c b/dlls/devenum/mediacatenum.c index 15e5c9642cb..b03b17f945a 100644 --- a/dlls/devenum/mediacatenum.c +++ b/dlls/devenum/mediacatenum.c @@ -377,73 +377,63 @@ static HRESULT WINAPI moniker_GetSizeMax(IMoniker *iface, ULARGE_INTEGER *pcbSiz return S_OK; }
-static HRESULT WINAPI moniker_BindToObject(IMoniker *iface, IBindCtx *pbc, - IMoniker *pmkToLeft, REFIID riidResult, void **ppvResult) +static HRESULT WINAPI moniker_BindToObject(IMoniker *iface, IBindCtx *bind_ctx, + IMoniker *left, REFIID iid, void **out) { - struct moniker *This = impl_from_IMoniker(iface); - IUnknown * pObj = NULL; - IPropertyBag * pProp = NULL; - CLSID clsID; + struct moniker *moniker = impl_from_IMoniker(iface); + IPersistPropertyBag *persist_bag; + IPropertyBag *prop_bag; + IUnknown *unk; + CLSID clsid; VARIANT var; - HRESULT res = E_FAIL; + HRESULT hr;
- TRACE("(%p)->(%p, %p, %s, %p)\n", This, pbc, pmkToLeft, debugstr_guid(riidResult), ppvResult); + TRACE("moniker %p, bind_ctx %p, left %p, iid %s, out %p.\n", + moniker, bind_ctx, left, debugstr_guid(iid), out);
- if (!ppvResult) + if (!out) return E_POINTER;
VariantInit(&var); - *ppvResult = NULL; + *out = NULL;
- if(pmkToLeft==NULL) + if (FAILED(hr = IMoniker_BindToStorage(iface, NULL, NULL, &IID_IPropertyBag, (void **)&prop_bag))) + return hr; + + V_VT(&var) = VT_BSTR; + if (FAILED(hr = IPropertyBag_Read(prop_bag, L"CLSID", &var, NULL))) { - /* first activation of this class */ - LPVOID pvptr; - res=IMoniker_BindToStorage(iface, NULL, NULL, &IID_IPropertyBag, &pvptr); - pProp = pvptr; - if (SUCCEEDED(res)) - { - V_VT(&var) = VT_BSTR; - res = IPropertyBag_Read(pProp, clsidW, &var, NULL); - } - if (SUCCEEDED(res)) - { - res = CLSIDFromString(V_BSTR(&var), &clsID); - VariantClear(&var); - } - if (SUCCEEDED(res)) - { - res=CoCreateInstance(&clsID,NULL,CLSCTX_ALL,&IID_IUnknown,&pvptr); - pObj = pvptr; - } + IPropertyBag_Release(prop_bag); + return hr; }
- if (pObj!=NULL) + hr = CLSIDFromString(V_BSTR(&var), &clsid); + VariantClear(&var); + if (FAILED(hr)) { - /* get the requested interface from the loaded class */ - res = S_OK; - if (pProp) { - HRESULT res2; - LPVOID ppv = NULL; - res2 = IUnknown_QueryInterface(pObj, &IID_IPersistPropertyBag, &ppv); - if (SUCCEEDED(res2)) { - res = IPersistPropertyBag_Load((IPersistPropertyBag *) ppv, pProp, NULL); - IPersistPropertyBag_Release((IPersistPropertyBag *) ppv); - } - } - if (SUCCEEDED(res)) - res= IUnknown_QueryInterface(pObj,riidResult,ppvResult); - IUnknown_Release(pObj); + IPropertyBag_Release(prop_bag); + return hr; }
- if (pProp) + if (FAILED(hr = CoCreateInstance(&clsid, NULL, CLSCTX_ALL, &IID_IUnknown, (void **)&unk))) { - IPropertyBag_Release(pProp); + IPropertyBag_Release(prop_bag); + return hr; + } + + if (SUCCEEDED(IUnknown_QueryInterface(unk, &IID_IPersistPropertyBag, (void **)&persist_bag))) + { + hr = IPersistPropertyBag_Load(persist_bag, prop_bag, NULL); + IPersistPropertyBag_Release(persist_bag); }
- TRACE("<- 0x%x\n", res); + if (SUCCEEDED(hr)) + hr = IUnknown_QueryInterface(unk, iid, out);
- return res; + IUnknown_Release(unk); + IPropertyBag_Release(prop_bag); + + return hr; }
static HRESULT WINAPI moniker_BindToStorage(IMoniker *iface, IBindCtx *pbc, diff --git a/dlls/devenum/tests/devenum.c b/dlls/devenum/tests/devenum.c index 01e6be98da7..decc53ff814 100644 --- a/dlls/devenum/tests/devenum.c +++ b/dlls/devenum/tests/devenum.c @@ -46,8 +46,9 @@ static void test_devenum(void) GUID cat_guid, clsid; WCHAR *displayname; IBindCtx *bindctx; + HRESULT hr, hr2; + IUnknown *unk; VARIANT var; - HRESULT hr; int count;
hr = CoCreateInstance(&CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC, @@ -114,6 +115,21 @@ static void test_devenum(void) hr = IMoniker_BindToObject(moniker, NULL, NULL, &IID_IUnknown, NULL); ok(hr == E_POINTER, "got %#x\n", hr);
+ VariantClear(&var); + hr = IPropertyBag_Read(prop_bag, L"CLSID", &var, NULL); + /* Instantiating the WMT Screen Capture Filter crashes on Windows XP. */ + if (hr != S_OK || wcscmp(V_BSTR(&var), L"{31087270-D348-432C-899E-2D2F38FF29A0}")) + { + hr = IMoniker_BindToObject(moniker, NULL, NULL, &IID_IUnknown, (void **)&unk); + if (hr == S_OK) + IUnknown_Release(unk); + hr2 = IMoniker_BindToObject(moniker, NULL, (IMoniker *)0xdeadbeef, + &IID_IUnknown, (void **)&unk); + if (hr2 == S_OK) + IUnknown_Release(unk); + ok(hr2 == hr, "Expected hr %#x, got %#x.\n", hr, hr2); + } + hr = CreateBindCtx(0, &bindctx); ok(hr == S_OK, "Got hr %#x.\n", hr); hr = IMoniker_BindToStorage(moniker, bindctx, NULL, &IID_IPropertyBag, (LPVOID*)&prop_bag);
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/devenum/mediacatenum.c | 18 ++---------------- 1 file changed, 2 insertions(+), 16 deletions(-)
diff --git a/dlls/devenum/mediacatenum.c b/dlls/devenum/mediacatenum.c index b03b17f945a..d0c4a303b56 100644 --- a/dlls/devenum/mediacatenum.c +++ b/dlls/devenum/mediacatenum.c @@ -382,7 +382,6 @@ static HRESULT WINAPI moniker_BindToObject(IMoniker *iface, IBindCtx *bind_ctx, { struct moniker *moniker = impl_from_IMoniker(iface); IPersistPropertyBag *persist_bag; - IPropertyBag *prop_bag; IUnknown *unk; CLSID clsid; VARIANT var; @@ -397,33 +396,21 @@ static HRESULT WINAPI moniker_BindToObject(IMoniker *iface, IBindCtx *bind_ctx, VariantInit(&var); *out = NULL;
- if (FAILED(hr = IMoniker_BindToStorage(iface, NULL, NULL, &IID_IPropertyBag, (void **)&prop_bag))) - return hr; - V_VT(&var) = VT_BSTR; - if (FAILED(hr = IPropertyBag_Read(prop_bag, L"CLSID", &var, NULL))) - { - IPropertyBag_Release(prop_bag); + if (FAILED(hr = IPropertyBag_Read(&moniker->IPropertyBag_iface, L"CLSID", &var, NULL))) return hr; - }
hr = CLSIDFromString(V_BSTR(&var), &clsid); VariantClear(&var); if (FAILED(hr)) - { - IPropertyBag_Release(prop_bag); return hr; - }
if (FAILED(hr = CoCreateInstance(&clsid, NULL, CLSCTX_ALL, &IID_IUnknown, (void **)&unk))) - { - IPropertyBag_Release(prop_bag); return hr; - }
if (SUCCEEDED(IUnknown_QueryInterface(unk, &IID_IPersistPropertyBag, (void **)&persist_bag))) { - hr = IPersistPropertyBag_Load(persist_bag, prop_bag, NULL); + hr = IPersistPropertyBag_Load(persist_bag, &moniker->IPropertyBag_iface, NULL); IPersistPropertyBag_Release(persist_bag); }
@@ -431,7 +418,6 @@ static HRESULT WINAPI moniker_BindToObject(IMoniker *iface, IBindCtx *bind_ctx, hr = IUnknown_QueryInterface(unk, iid, out);
IUnknown_Release(unk); - IPropertyBag_Release(prop_bag);
return hr; }
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/devenum/Makefile.in | 2 +- dlls/devenum/devenum_private.h | 17 ++------- dlls/devenum/mediacatenum.c | 21 ++++++++--- dlls/devenum/tests/devenum.c | 66 +++++++++++++++++++++++++++++----- 4 files changed, 78 insertions(+), 28 deletions(-)
diff --git a/dlls/devenum/Makefile.in b/dlls/devenum/Makefile.in index d563b9a83e4..6ce1967a6dd 100644 --- a/dlls/devenum/Makefile.in +++ b/dlls/devenum/Makefile.in @@ -1,5 +1,5 @@ MODULE = devenum.dll -IMPORTS = strmiids uuid ole32 oleaut32 avicap32 winmm user32 advapi32 dsound msdmo +IMPORTS = dmoguids strmiids uuid ole32 oleaut32 avicap32 winmm user32 advapi32 dsound msdmo DELAYIMPORTS = msvfw32
EXTRADLLFLAGS = -mno-cygwin diff --git a/dlls/devenum/devenum_private.h b/dlls/devenum/devenum_private.h index 43a5a0c50e1..6bd3c7cac4f 100644 --- a/dlls/devenum/devenum_private.h +++ b/dlls/devenum/devenum_private.h @@ -22,21 +22,10 @@ * - Private file where devenum globals are declared */
-#include <stdarg.h> - -#include "windef.h" -#include "winbase.h" -#include "wingdi.h" -#include "winuser.h" -#include "winreg.h" -#include "winerror.h" - #define COBJMACROS - -#include "ole2.h" -#include "strmif.h" -#include "olectl.h" -#include "uuids.h" +#include "dshow.h" +#include "dmo.h" +#include "dmodshow.h"
/********************************************************************** * Dll lifetime tracking declaration for devenum.dll diff --git a/dlls/devenum/mediacatenum.c b/dlls/devenum/mediacatenum.c index d0c4a303b56..c0006ad53ef 100644 --- a/dlls/devenum/mediacatenum.c +++ b/dlls/devenum/mediacatenum.c @@ -23,9 +23,6 @@ */
#include "devenum_private.h" -#include "oleauto.h" -#include "ocidl.h" -#include "dmoreg.h"
#include "wine/debug.h"
@@ -393,9 +390,25 @@ static HRESULT WINAPI moniker_BindToObject(IMoniker *iface, IBindCtx *bind_ctx, if (!out) return E_POINTER;
- VariantInit(&var); *out = NULL;
+ if (moniker->type == DEVICE_DMO) + { + IDMOWrapperFilter *wrapper; + + if (FAILED(hr = CoCreateInstance(&CLSID_DMOWrapperFilter, NULL, + CLSCTX_INPROC_SERVER, &IID_IDMOWrapperFilter, (void **)&wrapper))) + return hr; + + if (SUCCEEDED(hr = IDMOWrapperFilter_Init(wrapper, &moniker->clsid, &moniker->class))) + { + hr = IDMOWrapperFilter_QueryInterface(wrapper, iid, out); + } + IDMOWrapperFilter_Release(wrapper); + return hr; + } + + VariantInit(&var); V_VT(&var) = VT_BSTR; if (FAILED(hr = IPropertyBag_Read(&moniker->IPropertyBag_iface, L"CLSID", &var, NULL))) return hr; diff --git a/dlls/devenum/tests/devenum.c b/dlls/devenum/tests/devenum.c index decc53ff814..93692f75e62 100644 --- a/dlls/devenum/tests/devenum.c +++ b/dlls/devenum/tests/devenum.c @@ -20,20 +20,15 @@
#define COBJMACROS
-#include <stdio.h> - -#include "wine/test.h" #include "initguid.h" -#include "ole2.h" -#include "strmif.h" -#include "uuids.h" -#include "vfwmsgs.h" -#include "mmsystem.h" +#include "dshow.h" +#include "dmo.h" +#include "dmodshow.h" #include "dsound.h" #include "mmddk.h" #include "vfw.h" -#include "dmoreg.h" #include "setupapi.h" +#include "wine/test.h"
DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0);
@@ -603,10 +598,15 @@ static void test_dmo(void) { IParseDisplayName *parser; IPropertyBag *prop_bag; + IBaseFilter *filter; + IMediaObject *dmo; + IEnumDMO *enumdmo; WCHAR buffer[200]; IMoniker *mon; VARIANT var; + WCHAR *name; HRESULT hr; + GUID clsid;
hr = CoCreateInstance(&CLSID_CDeviceMoniker, NULL, CLSCTX_INPROC, &IID_IParseDisplayName, (void **)&parser); ok(hr == S_OK, "Failed to create ParseDisplayName: %#x\n", hr); @@ -657,6 +657,54 @@ static void test_dmo(void) } IPropertyBag_Release(prop_bag); IMoniker_Release(mon); + + hr = DMOEnum(&DMOCATEGORY_AUDIO_DECODER, 0, 0, NULL, 0, NULL, &enumdmo); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + while (IEnumDMO_Next(enumdmo, 1, &clsid, &name, NULL) == S_OK) + { + wcscpy(buffer, L"@device:dmo:"); + StringFromGUID2(&clsid, buffer + wcslen(buffer), CHARS_IN_GUID); + StringFromGUID2(&DMOCATEGORY_AUDIO_DECODER, buffer + wcslen(buffer), CHARS_IN_GUID); + mon = check_display_name(parser, buffer); + ok(find_moniker(&DMOCATEGORY_AUDIO_DECODER, mon), "DMO was not found.\n"); + + hr = IMoniker_BindToStorage(mon, NULL, NULL, &IID_IPropertyBag, (void **)&prop_bag); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + VariantClear(&var); + hr = IPropertyBag_Read(prop_bag, L"FriendlyName", &var, NULL); + ok(hr == S_OK, "got %#x\n", hr); + ok(!wcscmp(V_BSTR(&var), name), "got %s\n", wine_dbgstr_w(V_BSTR(&var))); + + VariantClear(&var); + V_VT(&var) = VT_BSTR; + V_BSTR(&var) = SysAllocString(L"devenum test"); + hr = IPropertyBag_Write(prop_bag, L"FriendlyName", &var); + ok(hr == E_ACCESSDENIED, "Write failed: %#x\n", hr); + + VariantClear(&var); + hr = IPropertyBag_Read(prop_bag, L"CLSID", &var, NULL); + ok(hr == HRESULT_FROM_WIN32(ERROR_NOT_FOUND), "got %#x\n", hr); + + IPropertyBag_Release(prop_bag); + CoTaskMemFree(name); + + hr = IMoniker_BindToObject(mon, NULL, NULL, &IID_IBaseFilter, (void **)&filter); + ok(hr == S_OK, "got %#x\n", hr); + + hr = IBaseFilter_GetClassID(filter, &clsid); + ok(hr == S_OK, "got %#x\n", hr); + ok(IsEqualGUID(&clsid, &CLSID_DMOWrapperFilter), "Got CLSID %s.\n", debugstr_guid(&clsid)); + + hr = IBaseFilter_QueryInterface(filter, &IID_IMediaObject, (void **)&dmo); + ok(hr == S_OK, "got %#x\n", hr); + IMediaObject_Release(dmo); + + IBaseFilter_Release(filter); + } + IEnumDMO_Release(enumdmo); + IParseDisplayName_Release(parser); }