Nikolay Sivov : ole32/composite: Do not rely on antimoniker composition in ParseDisplayName().

Alexandre Julliard julliard at winehq.org
Thu Sep 23 15:35:05 CDT 2021


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

Author: Nikolay Sivov <nsivov at codeweavers.com>
Date:   Thu Sep 23 13:53:11 2021 +0300

ole32/composite: Do not rely on antimoniker composition in ParseDisplayName().

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

---

 dlls/ole32/compositemoniker.c | 81 ++++++++++++++++++++++++++++++++-----------
 1 file changed, 61 insertions(+), 20 deletions(-)

diff --git a/dlls/ole32/compositemoniker.c b/dlls/ole32/compositemoniker.c
index 7abbd51090f..0dbe27f4c76 100644
--- a/dlls/ole32/compositemoniker.c
+++ b/dlls/ole32/compositemoniker.c
@@ -87,6 +87,7 @@ static inline EnumMonikerImpl *impl_from_IEnumMoniker(IEnumMoniker *iface)
 }
 
 static HRESULT EnumMonikerImpl_CreateEnumMoniker(IMoniker** tabMoniker,ULONG tabSize,ULONG currentPos,BOOL leftToRight,IEnumMoniker ** ppmk);
+static HRESULT composite_get_rightmost(CompositeMonikerImpl *composite, IMoniker **left, IMoniker **rightmost);
 
 /*******************************************************************************
  *        CompositeMoniker_QueryInterface
@@ -1132,30 +1133,28 @@ static HRESULT WINAPI CompositeMonikerImpl_GetDisplayName(IMoniker *iface, IBind
     return S_OK;
 }
 
-/******************************************************************************
- *        CompositeMoniker_ParseDisplayName
- ******************************************************************************/
-static HRESULT WINAPI
-CompositeMonikerImpl_ParseDisplayName(IMoniker* iface, IBindCtx* pbc,
-               IMoniker* pmkToLeft, LPOLESTR pszDisplayName, ULONG* pchEaten,
-               IMoniker** ppmkOut)
+static HRESULT WINAPI CompositeMonikerImpl_ParseDisplayName(IMoniker *iface, IBindCtx *pbc,
+        IMoniker *pmkToLeft, LPOLESTR name, ULONG *eaten, IMoniker **result)
 {
-    IEnumMoniker *enumMoniker;
-    IMoniker *tempMk,*rightMostMk,*antiMk;
-    /* This method recursively calls IMoniker::ParseDisplayName on the rightmost component of the composite,*/
-    /* passing everything else as the pmkToLeft parameter for that call. */
+    CompositeMonikerImpl *moniker = impl_from_IMoniker(iface);
+    IMoniker *left, *rightmost;
+    HRESULT hr;
 
-    /* get the most right moniker */
-    IMoniker_Enum(iface,FALSE,&enumMoniker);
-    IEnumMoniker_Next(enumMoniker,1,&rightMostMk,NULL);
-    IEnumMoniker_Release(enumMoniker);
+    TRACE("%p, %p, %p, %s, %p, %p.\n", iface, pbc, pmkToLeft, debugstr_w(name), eaten, result);
 
-    /* get the left moniker */
-    CreateAntiMoniker(&antiMk);
-    IMoniker_ComposeWith(iface,antiMk,0,&tempMk);
-    IMoniker_Release(antiMk);
+    if (!pbc)
+        return E_INVALIDARG;
 
-    return IMoniker_ParseDisplayName(rightMostMk,pbc,tempMk,pszDisplayName,pchEaten,ppmkOut);
+    if (FAILED(hr = composite_get_rightmost(moniker, &left, &rightmost)))
+        return hr;
+
+    /* Let rightmost component parse the name, using what's left of the composite as a left side. */
+    hr = IMoniker_ParseDisplayName(rightmost, pbc, left, name, eaten, result);
+
+    IMoniker_Release(left);
+    IMoniker_Release(rightmost);
+
+    return hr;
 }
 
 /******************************************************************************
@@ -1830,6 +1829,48 @@ static void moniker_get_tree_comp_count(const struct comp_node *root, unsigned i
     moniker_get_tree_comp_count(root->right, count);
 }
 
+static HRESULT composite_get_rightmost(CompositeMonikerImpl *composite, IMoniker **left, IMoniker **rightmost)
+{
+    struct comp_node *root, *node;
+    unsigned int count;
+    HRESULT hr;
+
+    /* Shortcut for trivial case when right component is non-composite */
+    if (!unsafe_impl_from_IMoniker(composite->right))
+    {
+        *left = composite->left;
+        IMoniker_AddRef(*left);
+        *rightmost = composite->right;
+        IMoniker_AddRef(*rightmost);
+        return S_OK;
+    }
+
+    *left = *rightmost = NULL;
+
+    if (FAILED(hr = moniker_get_tree_representation(&composite->IMoniker_iface, NULL, &root)))
+        return hr;
+
+    if (!(node = moniker_tree_get_rightmost(root)))
+    {
+        WARN("Couldn't get right most component.\n");
+        return E_FAIL;
+    }
+
+    *rightmost = node->moniker;
+    IMoniker_AddRef(*rightmost);
+    moniker_tree_discard(node, TRUE);
+
+    hr = moniker_create_from_tree(root, &count, left);
+    moniker_tree_release(root);
+    if (FAILED(hr))
+    {
+        IMoniker_Release(*rightmost);
+        *rightmost = NULL;
+    }
+
+    return hr;
+}
+
 static HRESULT moniker_simplify_composition(IMoniker *left, IMoniker *right,
         unsigned int *count, IMoniker **new_left, IMoniker **new_right)
 {




More information about the wine-cvs mailing list