Nikolay Sivov : ole32/itemmoniker: Always use generic composition in ComposeWith().

Alexandre Julliard julliard at winehq.org
Fri Sep 24 15:31:59 CDT 2021


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

Author: Nikolay Sivov <nsivov at codeweavers.com>
Date:   Fri Sep 24 15:51:41 2021 +0300

ole32/itemmoniker: Always use generic composition in ComposeWith().

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

---

 dlls/ole32/itemmoniker.c   | 76 ++++++------------------------------
 dlls/ole32/tests/moniker.c | 97 +++++++++++++++++++++++++++-------------------
 2 files changed, 68 insertions(+), 105 deletions(-)

diff --git a/dlls/ole32/itemmoniker.c b/dlls/ole32/itemmoniker.c
index c42cc75c224..770b042aac7 100644
--- a/dlls/ole32/itemmoniker.c
+++ b/dlls/ole32/itemmoniker.c
@@ -511,77 +511,23 @@ static HRESULT WINAPI ItemMonikerImpl_Reduce(IMoniker* iface,
 
     return MK_S_REDUCED_TO_SELF;
 }
-/******************************************************************************
- *        ItemMoniker_ComposeWith
- ******************************************************************************/
-static HRESULT WINAPI ItemMonikerImpl_ComposeWith(IMoniker* iface,
-                                                  IMoniker* pmkRight,
-                                                  BOOL fOnlyIfNotGeneric,
-                                                  IMoniker** ppmkComposite)
-{
-    HRESULT res=S_OK;
-    DWORD mkSys,mkSys2, order;
-    IEnumMoniker* penumMk=0;
-    IMoniker *pmostLeftMk=0;
-    IMoniker* tempMkComposite=0;
-
-    TRACE("(%p,%p,%d,%p)\n",iface,pmkRight,fOnlyIfNotGeneric,ppmkComposite);
-
-    if ((ppmkComposite==NULL)||(pmkRight==NULL))
-	return E_POINTER;
-
-    *ppmkComposite=0;
-
-    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){
-
-            res=IMoniker_Enum(pmkRight,TRUE,&penumMk);
-
-            if (FAILED(res))
-                return res;
-
-            res=IEnumMoniker_Next(penumMk,1,&pmostLeftMk,NULL);
-
-            IMoniker_IsSystemMoniker(pmostLeftMk,&mkSys2);
 
-            if(mkSys2==MKSYS_ANTIMONIKER){
-
-                IMoniker_Release(pmostLeftMk);
+static HRESULT WINAPI ItemMonikerImpl_ComposeWith(IMoniker *iface, IMoniker *right,
+        BOOL only_if_not_generic, IMoniker **result)
+{
+    DWORD order;
 
-                tempMkComposite=iface;
-                IMoniker_AddRef(iface);
+    TRACE("%p, %p, %d, %p\n", iface, right, only_if_not_generic, result);
 
-                while(IEnumMoniker_Next(penumMk,1,&pmostLeftMk,NULL)==S_OK){
+    if (!result || !right)
+        return E_POINTER;
 
-                    res=CreateGenericComposite(tempMkComposite,pmostLeftMk,ppmkComposite);
+    *result = NULL;
 
-                    IMoniker_Release(tempMkComposite);
-                    IMoniker_Release(pmostLeftMk);
+    if (is_anti_moniker(right, &order))
+        return order > 1 ? create_anti_moniker(order - 1, result) : S_OK;
 
-                    tempMkComposite=*ppmkComposite;
-                    IMoniker_AddRef(tempMkComposite);
-                }
-                return res;
-            }
-            else
-                return CreateGenericComposite(iface,pmkRight,ppmkComposite);
-         }
-         /* If pmkRight is not an anti-moniker, the method combines the two monikers into a generic
-          composite if fOnlyIfNotGeneric is FALSE; if fOnlyIfNotGeneric is TRUE, the method returns
-          a NULL moniker and a return value of MK_E_NEEDGENERIC */
-          else
-            if (!fOnlyIfNotGeneric)
-                return CreateGenericComposite(iface,pmkRight,ppmkComposite);
-
-            else
-                return MK_E_NEEDGENERIC;
+    return only_if_not_generic ? MK_E_NEEDGENERIC : CreateGenericComposite(iface, right, result);
 }
 
 /******************************************************************************
diff --git a/dlls/ole32/tests/moniker.c b/dlls/ole32/tests/moniker.c
index 4d40dcb6e4b..1b44c80fe45 100644
--- a/dlls/ole32/tests/moniker.c
+++ b/dlls/ole32/tests/moniker.c
@@ -127,6 +127,43 @@ static IMoniker *create_antimoniker(DWORD level)
     return moniker;
 }
 
+static HRESULT create_moniker_from_desc(const char *desc, unsigned int *eaten,
+        IMoniker **moniker)
+{
+    IMoniker *left, *right;
+    WCHAR nameW[3];
+    HRESULT hr;
+
+    desc += *eaten;
+
+    switch (*desc)
+    {
+        case 'I':
+            nameW[0] = desc[0];
+            nameW[1] = desc[1];
+            nameW[2] = 0;
+            *eaten += 2;
+            return CreateItemMoniker(L"!", nameW, moniker);
+        case 'A':
+            *eaten += 2;
+            *moniker = create_antimoniker(desc[1] - '0');
+            return S_OK;
+        case 'C':
+            (*eaten)++;
+            hr = create_moniker_from_desc(desc, eaten, &left);
+            ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+            hr = create_moniker_from_desc(desc, eaten, &right);
+            ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+            hr = CreateGenericComposite(left, right, moniker);
+            IMoniker_Release(left);
+            IMoniker_Release(right);
+            return hr;
+        default:
+            ok(0, "Unexpected description %s.\n", desc);
+            return E_NOTIMPL;
+    }
+}
+
 static SIZE_T round_global_size(SIZE_T size)
 {
     static SIZE_T global_size_alignment = -1;
@@ -2267,7 +2304,7 @@ static void test_item_moniker(void)
         "Moniker_IsRunning",
         NULL
     };
-    IMoniker *moniker, *moniker2, *moniker3, *reduced, *anti, *inverse;
+    IMoniker *moniker, *moniker2, *moniker3, *reduced, *anti, *inverse, *c;
     DWORD i, hash, eaten, cookie;
     HRESULT hr;
     IBindCtx *bindctx;
@@ -2589,7 +2626,7 @@ todo_wine
     ok(!moniker2, "Unexpected pointer.\n");
     IMoniker_Release(anti);
 
-    /* I + A2 -> (A) */
+    /* I + A2 -> A */
     anti = create_antimoniker(2);
     hr = IMoniker_ComposeWith(moniker, anti, TRUE, &moniker2);
     ok(hr == S_OK, "Failed to compose, hr %#x.\n", hr);
@@ -2601,6 +2638,24 @@ todo_wine
 
     IMoniker_Release(anti);
 
+    /* I + (A,A3) -> A3 */
+
+    /* Simplification has to through generic composite logic,
+       even when resolved to non-composite, generic composite option has to be enabled. */
+    eaten = 0;
+    hr = create_moniker_from_desc("CA1A3", &eaten, &c);
+    ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+    hr = IMoniker_ComposeWith(moniker, c, TRUE, &moniker2);
+    ok(hr == MK_E_NEEDGENERIC, "Unexpected hr %#x.\n", hr);
+    hr = IMoniker_ComposeWith(moniker, c, FALSE, &moniker2);
+    ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+    TEST_MONIKER_TYPE(moniker2, MKSYS_ANTIMONIKER);
+    hr = IMoniker_Hash(moniker2, &hash);
+    ok(hr == S_OK, "Failed to get hash, hr %#x.\n", hr);
+    ok(hash == 0x80000003, "Unexpected hash.\n");
+    IMoniker_Release(moniker2);
+    IMoniker_Release(c);
+
     IMoniker_Release(moniker);
 
     /* CommonPrefixWith */
@@ -2893,43 +2948,6 @@ todo_wine
     IMoniker_Release(moniker2);
 }
 
-static HRESULT create_moniker_from_desc(const char *desc, unsigned int *eaten,
-        IMoniker **moniker)
-{
-    IMoniker *left, *right;
-    WCHAR nameW[3];
-    HRESULT hr;
-
-    desc += *eaten;
-
-    switch (*desc)
-    {
-        case 'I':
-            nameW[0] = desc[0];
-            nameW[1] = desc[1];
-            nameW[2] = 0;
-            *eaten += 2;
-            return CreateItemMoniker(L"!", nameW, moniker);
-        case 'A':
-            *eaten += 2;
-            *moniker = create_antimoniker(desc[1] - '0');
-            return S_OK;
-        case 'C':
-            (*eaten)++;
-            hr = create_moniker_from_desc(desc, eaten, &left);
-            ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
-            hr = create_moniker_from_desc(desc, eaten, &right);
-            ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
-            hr = CreateGenericComposite(left, right, moniker);
-            IMoniker_Release(left);
-            IMoniker_Release(right);
-            return hr;
-        default:
-            ok(0, "Unexpected description %s.\n", desc);
-            return E_NOTIMPL;
-    }
-}
-
 static void test_generic_composite_moniker(void)
 {
     static const struct simplify_test
@@ -3154,7 +3172,6 @@ todo_wine
 
     /* See if non-generic composition is possible */
     hr = IMoniker_ComposeWith(moniker1, moniker, TRUE, &moniker2);
-todo_wine
     ok(hr == MK_E_NEEDGENERIC, "Unexpected hr %#x.\n", hr);
 
     hr = IBindCtx_GetRunningObjectTable(bindctx, &rot);




More information about the wine-cvs mailing list