Nikolay Sivov : ole32: Fix (pointer moniker + antimoniker) composing.

Alexandre Julliard julliard at winehq.org
Wed Jan 29 16:24:08 CST 2020


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

Author: Nikolay Sivov <nsivov at codeweavers.com>
Date:   Wed Jan 29 16:57:03 2020 +0300

ole32: Fix (pointer moniker + antimoniker) composing.

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

---

 dlls/ole32/antimoniker.c    | 17 ++++++++++++++++-
 dlls/ole32/moniker.h        |  2 ++
 dlls/ole32/pointermoniker.c | 15 ++++++++-------
 dlls/ole32/tests/moniker.c  |  6 +-----
 4 files changed, 27 insertions(+), 13 deletions(-)

diff --git a/dlls/ole32/antimoniker.c b/dlls/ole32/antimoniker.c
index 93d6ab9d56..6efd4ae853 100644
--- a/dlls/ole32/antimoniker.c
+++ b/dlls/ole32/antimoniker.c
@@ -56,6 +56,21 @@ static inline AntiMonikerImpl *impl_from_IROTData(IROTData *iface)
 
 static AntiMonikerImpl *unsafe_impl_from_IMoniker(IMoniker *iface);
 
+BOOL is_anti_moniker(IMoniker *iface, DWORD *order)
+{
+    AntiMonikerImpl *moniker = unsafe_impl_from_IMoniker(iface);
+
+    if (!moniker)
+    {
+        *order = 0;
+        return FALSE;
+    }
+
+    *order = moniker->count;
+
+    return TRUE;
+}
+
 /*******************************************************************************
  *        AntiMoniker_QueryInterface
  *******************************************************************************/
@@ -607,7 +622,7 @@ static const IROTDataVtbl VT_ROTDataImpl =
     AntiMonikerROTDataImpl_GetComparisonData
 };
 
-static HRESULT create_anti_moniker(DWORD order, IMoniker **ret)
+HRESULT create_anti_moniker(DWORD order, IMoniker **ret)
 {
     AntiMonikerImpl *moniker;
 
diff --git a/dlls/ole32/moniker.h b/dlls/ole32/moniker.h
index eaeed54a4e..995e0459e5 100644
--- a/dlls/ole32/moniker.h
+++ b/dlls/ole32/moniker.h
@@ -48,5 +48,7 @@ HRESULT ClassMoniker_CreateFromDisplayName(LPBC pbc, LPCOLESTR szDisplayName,
 
 HRESULT MonikerMarshal_Create(IMoniker *inner, IUnknown **outer) DECLSPEC_HIDDEN;
 
+BOOL is_anti_moniker(IMoniker *iface, DWORD *order) DECLSPEC_HIDDEN;
+HRESULT create_anti_moniker(DWORD order, IMoniker **ret) DECLSPEC_HIDDEN;
 
 #endif /* __WINE_MONIKER_H__ */
diff --git a/dlls/ole32/pointermoniker.c b/dlls/ole32/pointermoniker.c
index 2cb0600336..a16a56a098 100644
--- a/dlls/ole32/pointermoniker.c
+++ b/dlls/ole32/pointermoniker.c
@@ -262,7 +262,7 @@ PointerMonikerImpl_ComposeWith(IMoniker* iface, IMoniker* pmkRight,
 {
 
     HRESULT res=S_OK;
-    DWORD mkSys,mkSys2;
+    DWORD mkSys,mkSys2, order;
     IEnumMoniker* penumMk=0;
     IMoniker *pmostLeftMk=0;
     IMoniker* tempMkComposite=0;
@@ -274,15 +274,15 @@ PointerMonikerImpl_ComposeWith(IMoniker* iface, IMoniker* pmkRight,
 
     *ppmkComposite=0;
 
-    IMoniker_IsSystemMoniker(pmkRight,&mkSys);
-
-    /* If pmkRight is an anti-moniker, the returned moniker is NULL */
-    if(mkSys==MKSYS_ANTIMONIKER)
-        return res;
-
+    if (is_anti_moniker(pmkRight, &order))
+    {
+        return order > 1 ? create_anti_moniker(order - 1, ppmkComposite) : S_OK;
+    }
     else
+    {
         /* if pmkRight is a composite whose leftmost component is an anti-moniker,           */
         /* the returned moniker is the composite after the leftmost anti-moniker is removed. */
+        IMoniker_IsSystemMoniker(pmkRight,&mkSys);
 
          if(mkSys==MKSYS_GENERICCOMPOSITE){
 
@@ -326,6 +326,7 @@ PointerMonikerImpl_ComposeWith(IMoniker* iface, IMoniker* pmkRight,
 
             else
                 return MK_E_NEEDGENERIC;
+    }
 }
 
 /******************************************************************************
diff --git a/dlls/ole32/tests/moniker.c b/dlls/ole32/tests/moniker.c
index f5f69870bf..61aa0b4a96 100644
--- a/dlls/ole32/tests/moniker.c
+++ b/dlls/ole32/tests/moniker.c
@@ -3072,13 +3072,9 @@ todo_wine
     anti = create_antimoniker(2);
     hr = IMoniker_ComposeWith(moniker, anti, TRUE, &moniker2);
     ok(hr == S_OK, "Failed to compose, hr %#x.\n", hr);
-todo_wine
-    ok(!!moniker2, "Unexpected pointer.\n");
-if (moniker2)
-{
     TEST_MONIKER_TYPE(moniker2, MKSYS_ANTIMONIKER);
     IMoniker_Release(moniker2);
-}
+
     IMoniker_Release(anti);
 
     IMoniker_Release(moniker);




More information about the wine-cvs mailing list