[PATCH v2 1/3] devenum: Ignore the "left" parameter to IMoniker::BindToObject().

Zebediah Figura z.figura12 at gmail.com
Thu Apr 16 14:46:04 CDT 2020


Signed-off-by: Zebediah Figura <z.figura12 at 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);
-- 
2.26.0




More information about the wine-devel mailing list