oleaut32: Free allocated memory on typelib and typeinfo destruction.
This commit is contained in:
parent
d1b15c8ed7
commit
b3d024a7bb
|
@ -999,6 +999,7 @@ typedef struct tagITypeInfoImpl
|
||||||
const ITypeInfo2Vtbl *lpVtbl;
|
const ITypeInfo2Vtbl *lpVtbl;
|
||||||
const ITypeCompVtbl *lpVtblTypeComp;
|
const ITypeCompVtbl *lpVtblTypeComp;
|
||||||
LONG ref;
|
LONG ref;
|
||||||
|
BOOL no_free_data; /* don't free data structurees */
|
||||||
TYPEATTR TypeAttr ; /* _lots_ of type information. */
|
TYPEATTR TypeAttr ; /* _lots_ of type information. */
|
||||||
ITypeLibImpl * pTypeLib; /* back pointer to typelib */
|
ITypeLibImpl * pTypeLib; /* back pointer to typelib */
|
||||||
int index; /* index in this typelib; */
|
int index; /* index in this typelib; */
|
||||||
|
@ -3546,6 +3547,9 @@ static ULONG WINAPI ITypeLib2_fnRelease( ITypeLib2 *iface)
|
||||||
|
|
||||||
if (!ref)
|
if (!ref)
|
||||||
{
|
{
|
||||||
|
TLBImpLib *pImpLib, *pImpLibNext;
|
||||||
|
TLBCustData *pCustData, *pCustDataNext;
|
||||||
|
|
||||||
/* remove cache entry */
|
/* remove cache entry */
|
||||||
if(This->path)
|
if(This->path)
|
||||||
{
|
{
|
||||||
|
@ -3557,7 +3561,6 @@ static ULONG WINAPI ITypeLib2_fnRelease( ITypeLib2 *iface)
|
||||||
LeaveCriticalSection(&cache_section);
|
LeaveCriticalSection(&cache_section);
|
||||||
HeapFree(GetProcessHeap(), 0, This->path);
|
HeapFree(GetProcessHeap(), 0, This->path);
|
||||||
}
|
}
|
||||||
/* FIXME destroy child objects */
|
|
||||||
TRACE(" destroying ITypeLib(%p)\n",This);
|
TRACE(" destroying ITypeLib(%p)\n",This);
|
||||||
|
|
||||||
if (This->Name)
|
if (This->Name)
|
||||||
|
@ -3584,6 +3587,25 @@ static ULONG WINAPI ITypeLib2_fnRelease( ITypeLib2 *iface)
|
||||||
This->HelpStringDll = NULL;
|
This->HelpStringDll = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (pCustData = This->pCustData; pCustData; pCustData = pCustDataNext)
|
||||||
|
{
|
||||||
|
VariantClear(&pCustData->data);
|
||||||
|
|
||||||
|
pCustDataNext = pCustData->next;
|
||||||
|
TLB_Free(pCustData);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* FIXME: free arrays inside elements of This->pTypeDesc */
|
||||||
|
TLB_Free(This->pTypeDesc);
|
||||||
|
|
||||||
|
for (pImpLib = This->pImpLibs; pImpLib; pImpLib = pImpLibNext)
|
||||||
|
{
|
||||||
|
TLB_Free(pImpLib->name);
|
||||||
|
|
||||||
|
pImpLibNext = pImpLib->next;
|
||||||
|
TLB_Free(pImpLib);
|
||||||
|
}
|
||||||
|
|
||||||
if (This->pTypeInfo) /* can be NULL */
|
if (This->pTypeInfo) /* can be NULL */
|
||||||
ITypeInfo_Release((ITypeInfo*) This->pTypeInfo);
|
ITypeInfo_Release((ITypeInfo*) This->pTypeInfo);
|
||||||
HeapFree(GetProcessHeap(),0,This);
|
HeapFree(GetProcessHeap(),0,This);
|
||||||
|
@ -4367,14 +4389,17 @@ static ULONG WINAPI ITypeInfo_fnRelease(ITypeInfo2 *iface)
|
||||||
it means that function is called by ITypeLib2_Release */
|
it means that function is called by ITypeLib2_Release */
|
||||||
ITypeLib2_Release((ITypeLib2*)This->pTypeLib);
|
ITypeLib2_Release((ITypeLib2*)This->pTypeLib);
|
||||||
} else {
|
} else {
|
||||||
static int once = 0;
|
TLBFuncDesc *pFInfo, *pFInfoNext;
|
||||||
if (!once)
|
TLBVarDesc *pVInfo, *pVInfoNext;
|
||||||
{
|
TLBImplType *pImpl, *pImplNext;
|
||||||
once = 1;
|
TLBRefType *pRefType,*pRefTypeNext;
|
||||||
FIXME("destroy child objects\n");
|
TLBCustData *pCustData, *pCustDataNext;
|
||||||
}
|
|
||||||
|
|
||||||
TRACE("destroying ITypeInfo(%p)\n",This);
|
TRACE("destroying ITypeInfo(%p)\n",This);
|
||||||
|
|
||||||
|
if (This->no_free_data)
|
||||||
|
goto finish_free;
|
||||||
|
|
||||||
if (This->Name)
|
if (This->Name)
|
||||||
{
|
{
|
||||||
SysFreeString(This->Name);
|
SysFreeString(This->Name);
|
||||||
|
@ -4393,6 +4418,65 @@ static ULONG WINAPI ITypeInfo_fnRelease(ITypeInfo2 *iface)
|
||||||
This->DllName = 0;
|
This->DllName = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (pFInfo = This->funclist; pFInfo; pFInfo = pFInfoNext)
|
||||||
|
{
|
||||||
|
UINT i;
|
||||||
|
for(i = 0;i < pFInfo->funcdesc.cParams; i++)
|
||||||
|
{
|
||||||
|
ELEMDESC *elemdesc = &pFInfo->funcdesc.lprgelemdescParam[i];
|
||||||
|
if (elemdesc->u.paramdesc.wParamFlags & PARAMFLAG_FHASDEFAULT)
|
||||||
|
{
|
||||||
|
VariantClear(&elemdesc->u.paramdesc.pparamdescex->varDefaultValue);
|
||||||
|
TLB_Free(elemdesc->u.paramdesc.pparamdescex);
|
||||||
|
}
|
||||||
|
SysFreeString(pFInfo->pParamDesc[i].Name);
|
||||||
|
}
|
||||||
|
TLB_Free(pFInfo->funcdesc.lprgelemdescParam);
|
||||||
|
TLB_Free(pFInfo->pParamDesc);
|
||||||
|
for (pCustData = This->pCustData; pCustData; pCustData = pCustDataNext)
|
||||||
|
{
|
||||||
|
VariantClear(&pCustData->data);
|
||||||
|
|
||||||
|
pCustDataNext = pCustData->next;
|
||||||
|
TLB_Free(pCustData);
|
||||||
|
}
|
||||||
|
SysFreeString(pFInfo->HelpString);
|
||||||
|
SysFreeString(pFInfo->Name);
|
||||||
|
|
||||||
|
pFInfoNext = pFInfo->next;
|
||||||
|
TLB_Free(pFInfo);
|
||||||
|
}
|
||||||
|
for (pVInfo = This->varlist; pVInfo; pVInfo = pVInfoNext)
|
||||||
|
{
|
||||||
|
if (pVInfo->vardesc.varkind == VAR_CONST)
|
||||||
|
{
|
||||||
|
VariantClear(pVInfo->vardesc.u.lpvarValue);
|
||||||
|
TLB_Free(pVInfo->vardesc.u.lpvarValue);
|
||||||
|
}
|
||||||
|
SysFreeString(pVInfo->Name);
|
||||||
|
pVInfoNext = pVInfo->next;
|
||||||
|
TLB_Free(pVInfo);
|
||||||
|
}
|
||||||
|
for(pImpl = This->impltypelist; pImpl; pImpl = pImplNext)
|
||||||
|
{
|
||||||
|
for (pCustData = pImpl->pCustData; pCustData; pCustData = pCustDataNext)
|
||||||
|
{
|
||||||
|
VariantClear(&pCustData->data);
|
||||||
|
|
||||||
|
pCustDataNext = pCustData->next;
|
||||||
|
TLB_Free(pCustData);
|
||||||
|
}
|
||||||
|
pImplNext = pImpl->next;
|
||||||
|
TLB_Free(pImpl);
|
||||||
|
}
|
||||||
|
for(pRefType = This->reflist; pRefType; pRefType = pRefTypeNext)
|
||||||
|
{
|
||||||
|
pRefTypeNext = pRefType->next;
|
||||||
|
TLB_Free(pRefType);
|
||||||
|
}
|
||||||
|
TLB_Free(This->pCustData);
|
||||||
|
|
||||||
|
finish_free:
|
||||||
if (This->next)
|
if (This->next)
|
||||||
{
|
{
|
||||||
ITypeInfo_Release((ITypeInfo*)This->next);
|
ITypeInfo_Release((ITypeInfo*)This->next);
|
||||||
|
@ -5783,14 +5867,21 @@ static HRESULT WINAPI ITypeInfo_fnGetRefTypeInfo(
|
||||||
* copy the contents of the structs.
|
* copy the contents of the structs.
|
||||||
*/
|
*/
|
||||||
*pTypeInfoImpl = *This;
|
*pTypeInfoImpl = *This;
|
||||||
pTypeInfoImpl->ref = 1;
|
pTypeInfoImpl->ref = 0;
|
||||||
|
|
||||||
/* change the type to interface */
|
/* change the type to interface */
|
||||||
pTypeInfoImpl->TypeAttr.typekind = TKIND_INTERFACE;
|
pTypeInfoImpl->TypeAttr.typekind = TKIND_INTERFACE;
|
||||||
|
|
||||||
*ppTInfo = (ITypeInfo*) pTypeInfoImpl;
|
*ppTInfo = (ITypeInfo*) pTypeInfoImpl;
|
||||||
|
|
||||||
ITypeInfo_AddRef((ITypeInfo*) pTypeInfoImpl);
|
/* we use data structures from This, so we need to keep a reference
|
||||||
|
* to it to stop it being destroyed and signal to the new instance to
|
||||||
|
* not free its data structures when it is destroyed */
|
||||||
|
pTypeInfoImpl->no_free_data = TRUE;
|
||||||
|
pTypeInfoImpl->next = This;
|
||||||
|
ITypeInfo_AddRef((ITypeInfo*) This);
|
||||||
|
|
||||||
|
ITypeInfo_AddRef(*ppTInfo);
|
||||||
|
|
||||||
result = S_OK;
|
result = S_OK;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue