Nikolay Sivov : ole32: Fix IsRunning() for item moniker.

Alexandre Julliard julliard at winehq.org
Tue Jan 28 15:35:25 CST 2020


Module: wine
Branch: master
Commit: 25ad349d30a4db3ac5f9f3b75740f1ab019df434
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=25ad349d30a4db3ac5f9f3b75740f1ab019df434

Author: Nikolay Sivov <nsivov at codeweavers.com>
Date:   Tue Jan 28 10:32:20 2020 +0300

ole32: Fix IsRunning() for item moniker.

Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/ole32/itemmoniker.c   | 70 ++++++++++++++++++++++------------------------
 dlls/ole32/tests/moniker.c | 66 +++++++++++++++++++++++++++++++++++++++----
 2 files changed, 95 insertions(+), 41 deletions(-)

diff --git a/dlls/ole32/itemmoniker.c b/dlls/ole32/itemmoniker.c
index 7ebfaea6b6..111b111a1a 100644
--- a/dlls/ole32/itemmoniker.c
+++ b/dlls/ole32/itemmoniker.c
@@ -648,53 +648,51 @@ static HRESULT WINAPI ItemMonikerImpl_Hash(IMoniker* iface,DWORD* pdwHash)
 /******************************************************************************
  *        ItemMoniker_IsRunning
  ******************************************************************************/
-static HRESULT WINAPI ItemMonikerImpl_IsRunning(IMoniker* iface,
-                                                IBindCtx* pbc,
-                                                IMoniker* pmkToLeft,
-                                                IMoniker* pmkNewlyRunning)
+static HRESULT WINAPI ItemMonikerImpl_IsRunning(IMoniker *iface, IBindCtx *pbc, IMoniker *pmkToLeft,
+        IMoniker *pmkNewlyRunning)
 {
-    ItemMonikerImpl *This = impl_from_IMoniker(iface);
+    ItemMonikerImpl *moniker = impl_from_IMoniker(iface);
+    IOleItemContainer *container;
     IRunningObjectTable* rot;
-    HRESULT res;
-    IOleItemContainer *poic=0;
+    HRESULT hr;
 
     TRACE("(%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,pmkNewlyRunning);
 
-    /* If pmkToLeft is NULL, this method returns TRUE if pmkNewlyRunning is non-NULL and is equal to this */
-    /* moniker. Otherwise, the method checks the ROT to see whether this moniker is running.              */
-    if (pmkToLeft==NULL)
-        if ((pmkNewlyRunning!=NULL)&&(IMoniker_IsEqual(pmkNewlyRunning,iface)==S_OK))
-            return S_OK;
-        else {
-            if (pbc==NULL)
-                return E_INVALIDARG;
-
-            res=IBindCtx_GetRunningObjectTable(pbc,&rot);
-
-            if (FAILED(res))
-                return res;
-
-            res = IRunningObjectTable_IsRunning(rot,iface);
+    if (!pbc)
+        return E_INVALIDARG;
 
-            IRunningObjectTable_Release(rot);
+    if (!pmkToLeft)
+    {
+        if (pmkNewlyRunning)
+        {
+            return IMoniker_IsEqual(iface, pmkNewlyRunning);
         }
-    else{
-
-        /* If pmkToLeft is non-NULL, the method calls IMoniker::BindToObject on the pmkToLeft parameter,         */
-        /* requesting an IOleItemContainer interface pointer. The method then calls IOleItemContainer::IsRunning,*/
-        /* passing the string contained within this moniker. */
-
-        res=IMoniker_BindToObject(pmkToLeft,pbc,NULL,&IID_IOleItemContainer,(void**)&poic);
-
-        if (SUCCEEDED(res)){
-
-            res=IOleItemContainer_IsRunning(poic,This->itemName);
+        else
+        {
+            hr = IBindCtx_GetRunningObjectTable(pbc, &rot);
+            if (SUCCEEDED(hr))
+            {
+                hr = IRunningObjectTable_IsRunning(rot, iface);
+                IRunningObjectTable_Release(rot);
+            }
+        }
+    }
+    else
+    {
+        /* Container itself must be running too. */
+        hr = IMoniker_IsRunning(pmkToLeft, pbc, NULL, NULL);
+        if (hr != S_OK)
+            return hr;
 
-            IOleItemContainer_Release(poic);
+        hr = IMoniker_BindToObject(pmkToLeft, pbc, NULL, &IID_IOleItemContainer, (void **)&container);
+        if (SUCCEEDED(hr))
+        {
+            hr = IOleItemContainer_IsRunning(container, moniker->itemName);
+            IOleItemContainer_Release(container);
         }
     }
 
-    return res;
+    return hr;
 }
 
 /******************************************************************************
diff --git a/dlls/ole32/tests/moniker.c b/dlls/ole32/tests/moniker.c
index 8b150738b2..7d4c8224ad 100644
--- a/dlls/ole32/tests/moniker.c
+++ b/dlls/ole32/tests/moniker.c
@@ -385,6 +385,7 @@ static HRESULT WINAPI test_item_container_GetObjectStorage(IOleItemContainer *if
 
 static HRESULT WINAPI test_item_container_IsRunning(IOleItemContainer *iface, LPOLESTR item)
 {
+    ok(0, "Unexpected call.\n");
     return E_NOTIMPL;
 }
 
@@ -569,7 +570,7 @@ Moniker_IsRunning(IMoniker* iface, IBindCtx* pbc, IMoniker* pmkToLeft,
                           IMoniker* pmkNewlyRunning)
 {
     CHECK_EXPECTED_METHOD("Moniker_IsRunning");
-    return E_NOTIMPL;
+    return 0x8beef000;
 }
 
 static HRESULT WINAPI
@@ -1999,6 +2000,11 @@ static void test_item_moniker(void)
         { L"%", L"A", 0x41 },
         { L"%", L"a", 0x41 },
     };
+    static const char *methods_isrunning[] =
+    {
+        "Moniker_IsRunning",
+        NULL
+    };
     IMoniker *moniker, *moniker2, *reduced;
     HRESULT hr;
     DWORD moniker_type, i;
@@ -2012,10 +2018,12 @@ static void test_item_moniker(void)
     struct test_moniker *container_moniker;
     WCHAR displayname[16] = L"display name";
     IEnumMoniker *enummoniker;
+    IRunningObjectTable *rot;
     WCHAR *display_name;
     BIND_OPTS bind_opts;
     LARGE_INTEGER pos;
     IStream *stream;
+    DWORD cookie;
 
     hr = CreateItemMoniker(NULL, wszObjectName, &moniker);
     ok(hr == S_OK, "Failed to create item moniker, hr %#x.\n", hr);
@@ -2139,19 +2147,65 @@ todo_wine
         "dwMkSys != MKSYS_ITEMMONIKER, instead was 0x%08x\n",
         moniker_type);
 
+    container_moniker = create_test_moniker();
+
     /* IsRunning test */
     hr = IMoniker_IsRunning(moniker, NULL, NULL, NULL);
     ok(hr == E_INVALIDARG, "IMoniker_IsRunning should return E_INVALIDARG, not 0x%08x\n", hr);
 
+    hr = IMoniker_IsRunning(moniker, NULL, &container_moniker->IMoniker_iface, NULL);
+    ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
+
     hr = IMoniker_IsRunning(moniker, bindctx, NULL, NULL);
     ok(hr == S_FALSE, "IMoniker_IsRunning should return S_FALSE, not 0x%08x\n", hr);
 
+    hr = CreateItemMoniker(wszDelimiter, wszObjectName, &moniker2);
+    ok(hr == S_OK, "Failed to create a moniker, hr %#x.\n", hr);
+    hr = IMoniker_IsRunning(moniker, bindctx, NULL, moniker2);
+    ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+    IMoniker_Release(moniker2);
+
+    /* Different moniker as newly running. */
+    hr = CreateItemMoniker(wszDelimiter, L"Item123", &moniker2);
+    ok(hr == S_OK, "Failed to create a moniker, hr %#x.\n", hr);
+
+    hr = IMoniker_IsRunning(moniker, bindctx, NULL, moniker2);
+    ok(hr == S_FALSE, "Unexpected hr %#x.\n", hr);
+
+    hr = IBindCtx_GetRunningObjectTable(bindctx, &rot);
+    ok(hr == S_OK, "Failed to get ROT, hr %#x.\n", hr);
+
+    hr = IRunningObjectTable_Register(rot, ROTFLAGS_REGISTRATIONKEEPSALIVE, (IUnknown *)moniker, moniker, &cookie);
+    ok(hr == S_OK, "Failed to register, hr %#x.\n", hr);
+
+    hr = IRunningObjectTable_IsRunning(rot, moniker);
+    ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+
+    hr = IMoniker_IsRunning(moniker, bindctx, NULL, moniker2);
+    ok(hr == S_FALSE, "Unexpected hr %#x.\n", hr);
+
+    hr = IMoniker_IsRunning(moniker, bindctx, NULL, NULL);
+    ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+
+    hr = IRunningObjectTable_Revoke(rot, cookie);
+    ok(hr == S_OK, "Failed to revoke registration, hr %#x.\n", hr);
+
+    IRunningObjectTable_Release(rot);
+
+    expected_method_list = methods_isrunning;
+    hr = IMoniker_IsRunning(moniker, bindctx, &container_moniker->IMoniker_iface, NULL);
+    ok(hr == 0x8beef000, "Unexpected hr %#x.\n", hr);
+
+    expected_method_list = methods_isrunning;
+    hr = IMoniker_IsRunning(moniker, bindctx, &container_moniker->IMoniker_iface, moniker2);
+    ok(hr == 0x8beef000, "Unexpected hr %#x.\n", hr);
+
+    IMoniker_Release(moniker2);
+
     /* BindToObject() */
     hr = IMoniker_BindToObject(moniker, bindctx, NULL, &IID_IUnknown, (void **)&unknown);
     ok(hr == E_INVALIDARG, "IMoniker_BindToStorage should return E_INVALIDARG, not 0x%08x\n", hr);
 
-    container_moniker = create_test_moniker();
-
     hr = IMoniker_BindToObject(moniker, bindctx, &container_moniker->IMoniker_iface, &IID_IUnknown, (void **)&unknown);
     ok(hr == (0x8bee0000 | BINDSPEED_INDEFINITE), "Unexpected hr %#x.\n", hr);
 
@@ -2275,6 +2329,9 @@ todo_wine
         expected_item_moniker_comparison_data6, sizeof(expected_item_moniker_comparison_data6),
         34, L"");
 
+    hr = CoCreateInstance(&CLSID_ItemMoniker, (IUnknown *)moniker, CLSCTX_SERVER, &IID_IMoniker, (void **)&moniker2);
+    ok(FAILED(hr), "Unexpected hr %#x.\n", hr);
+
     IMoniker_Release(moniker);
 }
 
@@ -2622,8 +2679,7 @@ todo_wine
     ok(hr == E_INVALIDARG, "IMoniker_IsRunning should return E_INVALIDARG, not 0x%08x\n", hr);
 
     hr = IMoniker_IsRunning(moniker, bindctx, NULL, NULL);
-    todo_wine
-    ok(hr == S_FALSE, "IMoniker_IsRunning should return S_FALSE, not 0x%08x\n", hr);
+    ok(hr == S_FALSE, "Unexpected hr %#x.\n", hr);
 
     hr = IMoniker_GetTimeOfLastChange(moniker, bindctx, NULL, &filetime);
     ok(hr == MK_E_NOTBINDABLE, "IMoniker_GetTimeOfLastChange should return MK_E_NOTBINDABLE, not 0x%08x\n", hr);




More information about the wine-cvs mailing list