Nikolay Sivov : ole32: Lock item container on ParseDisplayName().

Alexandre Julliard julliard at winehq.org
Thu Jan 23 15:48:49 CST 2020


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

Author: Nikolay Sivov <nsivov at codeweavers.com>
Date:   Thu Jan 23 02:03:04 2020 +0300

ole32: Lock item container on ParseDisplayName().

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

---

 dlls/ole32/itemmoniker.c | 92 ++++++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 86 insertions(+), 6 deletions(-)

diff --git a/dlls/ole32/itemmoniker.c b/dlls/ole32/itemmoniker.c
index 0063c323bc..dc7026c4fc 100644
--- a/dlls/ole32/itemmoniker.c
+++ b/dlls/ole32/itemmoniker.c
@@ -57,6 +57,84 @@ static inline ItemMonikerImpl *impl_from_IROTData(IROTData *iface)
     return CONTAINING_RECORD(iface, ItemMonikerImpl, IROTData_iface);
 }
 
+struct container_lock
+{
+    IUnknown IUnknown_iface;
+    LONG refcount;
+    IOleItemContainer *container;
+};
+
+static struct container_lock *impl_lock_from_IUnknown(IUnknown *iface)
+{
+    return CONTAINING_RECORD(iface, struct container_lock, IUnknown_iface);
+}
+
+static HRESULT WINAPI container_lock_QueryInterface(IUnknown *iface, REFIID riid, void **obj)
+{
+    if (IsEqualIID(riid, &IID_IUnknown))
+    {
+        *obj = iface;
+        IUnknown_AddRef(iface);
+        return S_OK;
+    }
+
+    WARN("Unsupported interface %s.\n", debugstr_guid(riid));
+    *obj = NULL;
+    return E_NOINTERFACE;
+}
+
+static ULONG WINAPI container_lock_AddRef(IUnknown *iface)
+{
+    struct container_lock *lock = impl_lock_from_IUnknown(iface);
+    return InterlockedIncrement(&lock->refcount);
+}
+
+static ULONG WINAPI container_lock_Release(IUnknown *iface)
+{
+    struct container_lock *lock = impl_lock_from_IUnknown(iface);
+    ULONG refcount = InterlockedDecrement(&lock->refcount);
+
+    if (!refcount)
+    {
+        IOleItemContainer_LockContainer(lock->container, FALSE);
+        IOleItemContainer_Release(lock->container);
+        heap_free(lock);
+    }
+
+    return refcount;
+}
+
+static const IUnknownVtbl container_lock_vtbl =
+{
+    container_lock_QueryInterface,
+    container_lock_AddRef,
+    container_lock_Release,
+};
+
+static HRESULT set_container_lock(IOleItemContainer *container, IBindCtx *pbc)
+{
+    struct container_lock *lock;
+    HRESULT hr;
+
+    if (!(lock = heap_alloc(sizeof(*lock))))
+        return E_OUTOFMEMORY;
+
+    if (FAILED(hr = IOleItemContainer_LockContainer(container, TRUE)))
+    {
+        heap_free(lock);
+        return hr;
+    }
+
+    lock->IUnknown_iface.lpVtbl = &container_lock_vtbl;
+    lock->refcount = 1;
+    lock->container = container;
+    IOleItemContainer_AddRef(lock->container);
+
+    hr = IBindCtx_RegisterObjectBound(pbc, &lock->IUnknown_iface);
+    IUnknown_Release(&lock->IUnknown_iface);
+    return hr;
+}
+
 static HRESULT ItemMonikerImpl_Destroy(ItemMonikerImpl* iface);
 
 /*******************************************************************************
@@ -787,13 +865,15 @@ static HRESULT WINAPI ItemMonikerImpl_ParseDisplayName(IMoniker *iface, IBindCtx
     hr = IMoniker_BindToObject(pmkToLeft, pbc, NULL, &IID_IOleItemContainer, (void **)&container);
     if (SUCCEEDED(hr))
     {
-        hr = IOleItemContainer_GetObject(container, This->itemName, get_bind_speed_from_bindctx(pbc), pbc,
-                &IID_IParseDisplayName, (void **)&parser);
-        if (SUCCEEDED(hr))
+        if (SUCCEEDED(hr = set_container_lock(container, pbc)))
         {
-            hr = IParseDisplayName_ParseDisplayName(parser, pbc, displayname, eaten, ppmkOut);
-
-            IParseDisplayName_Release(parser);
+            hr = IOleItemContainer_GetObject(container, This->itemName, get_bind_speed_from_bindctx(pbc), pbc,
+                    &IID_IParseDisplayName, (void **)&parser);
+            if (SUCCEEDED(hr))
+            {
+                hr = IParseDisplayName_ParseDisplayName(parser, pbc, displayname, eaten, ppmkOut);
+                IParseDisplayName_Release(parser);
+            }
         }
         IOleItemContainer_Release(container);
     }




More information about the wine-cvs mailing list