ole32: Lock item container on ParseDisplayName().
Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
1f648ddd7a
commit
91fadaad98
|
@ -57,6 +57,84 @@ static inline ItemMonikerImpl *impl_from_IROTData(IROTData *iface)
|
||||||
return CONTAINING_RECORD(iface, ItemMonikerImpl, 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);
|
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);
|
hr = IMoniker_BindToObject(pmkToLeft, pbc, NULL, &IID_IOleItemContainer, (void **)&container);
|
||||||
if (SUCCEEDED(hr))
|
if (SUCCEEDED(hr))
|
||||||
{
|
{
|
||||||
hr = IOleItemContainer_GetObject(container, This->itemName, get_bind_speed_from_bindctx(pbc), pbc,
|
if (SUCCEEDED(hr = set_container_lock(container, pbc)))
|
||||||
&IID_IParseDisplayName, (void **)&parser);
|
|
||||||
if (SUCCEEDED(hr))
|
|
||||||
{
|
{
|
||||||
hr = IParseDisplayName_ParseDisplayName(parser, pbc, displayname, eaten, ppmkOut);
|
hr = IOleItemContainer_GetObject(container, This->itemName, get_bind_speed_from_bindctx(pbc), pbc,
|
||||||
|
&IID_IParseDisplayName, (void **)&parser);
|
||||||
IParseDisplayName_Release(parser);
|
if (SUCCEEDED(hr))
|
||||||
|
{
|
||||||
|
hr = IParseDisplayName_ParseDisplayName(parser, pbc, displayname, eaten, ppmkOut);
|
||||||
|
IParseDisplayName_Release(parser);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
IOleItemContainer_Release(container);
|
IOleItemContainer_Release(container);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue