ole32: Fix circular reference count in default handler objects.

This is caused by caching a pointer and reference to the data cache's
IPersistStorage interface without managing reference counts
appropriately.
This commit is contained in:
Rob Shearman 2009-11-24 14:06:57 +00:00 committed by Alexandre Julliard
parent 4b1d527b15
commit 6592c25bc7
1 changed files with 22 additions and 0 deletions

View File

@ -1960,9 +1960,21 @@ static DefaultHandler* DefaultHandler_Construct(
&IID_IUnknown,
(void**)&This->dataCache);
if(SUCCEEDED(hr))
{
hr = IUnknown_QueryInterface(This->dataCache, &IID_IPersistStorage, (void**)&This->dataCache_PersistStg);
/* keeping a reference to This->dataCache_PersistStg causes us to keep a
* reference on the outer object */
if (SUCCEEDED(hr))
IUnknown_Release(This->outerUnknown);
else
IUnknown_Release(This->dataCache);
}
if(FAILED(hr))
{
ERR("Unexpected error creating data cache\n");
HeapFree(GetProcessHeap(), 0, This);
return NULL;
}
This->clsid = *clsid;
This->clientSite = NULL;
@ -2009,6 +2021,13 @@ static DefaultHandler* DefaultHandler_Construct(
static void DefaultHandler_Destroy(
DefaultHandler* This)
{
TRACE("(%p)\n", This);
/* AddRef/Release may be called on this object during destruction.
* Prevent the object being destroyed recursively by artificially raising
* the reference count. */
This->ref = 10000;
/* release delegates */
DefaultHandler_Stop(This);
release_delegates(This);
@ -2020,6 +2039,9 @@ static void DefaultHandler_Destroy(
if (This->dataCache)
{
/* to balance out the release of dataCache_PersistStg which will result
* in a reference being released from the outer unknown */
IUnknown_AddRef(This->outerUnknown);
IPersistStorage_Release(This->dataCache_PersistStg);
IUnknown_Release(This->dataCache);
This->dataCache_PersistStg = NULL;