oleaut32: Fix memory leaks in ITypeInfo_fnInvoke.
This commit is contained in:
parent
6d7572c0e7
commit
99d9983b61
|
@ -6146,7 +6146,8 @@ static HRESULT WINAPI ITypeInfo_fnInvoke(
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
VARIANTARG *missing_arg = INVBUF_GET_MISSING_ARG_ARRAY(buffer, func_desc->cParams);
|
VARIANTARG *missing_arg = INVBUF_GET_MISSING_ARG_ARRAY(buffer, func_desc->cParams);
|
||||||
hres = VariantCopy(&missing_arg[i], src_arg);
|
if (wParamFlags & PARAMFLAG_FIN)
|
||||||
|
hres = VariantCopy(&missing_arg[i], src_arg);
|
||||||
V_VARIANTREF(&rgvarg[i]) = &missing_arg[i];
|
V_VARIANTREF(&rgvarg[i]) = &missing_arg[i];
|
||||||
}
|
}
|
||||||
V_VT(&rgvarg[i]) = rgvt[i];
|
V_VT(&rgvarg[i]) = rgvt[i];
|
||||||
|
@ -6184,8 +6185,10 @@ static HRESULT WINAPI ITypeInfo_fnInvoke(
|
||||||
else if ((rgvt[i] & VT_BYREF) && !V_ISBYREF(src_arg))
|
else if ((rgvt[i] & VT_BYREF) && !V_ISBYREF(src_arg))
|
||||||
{
|
{
|
||||||
VARIANTARG *missing_arg = INVBUF_GET_MISSING_ARG_ARRAY(buffer, func_desc->cParams);
|
VARIANTARG *missing_arg = INVBUF_GET_MISSING_ARG_ARRAY(buffer, func_desc->cParams);
|
||||||
V_VT(&missing_arg[i]) = V_VT(src_arg);
|
if (wParamFlags & PARAMFLAG_FIN)
|
||||||
hres = VariantChangeType(&missing_arg[i], src_arg, 0, rgvt[i] & ~VT_BYREF);
|
hres = VariantChangeType(&missing_arg[i], src_arg, 0, rgvt[i] & ~VT_BYREF);
|
||||||
|
else
|
||||||
|
V_VT(&missing_arg[i]) = rgvt[i] & ~VT_BYREF;
|
||||||
V_BYREF(&rgvarg[i]) = &V_NONE(&missing_arg[i]);
|
V_BYREF(&rgvarg[i]) = &V_NONE(&missing_arg[i]);
|
||||||
V_VT(&rgvarg[i]) = rgvt[i];
|
V_VT(&rgvarg[i]) = rgvt[i];
|
||||||
}
|
}
|
||||||
|
@ -6268,6 +6271,7 @@ static HRESULT WINAPI ITypeInfo_fnInvoke(
|
||||||
for (i = 0; i < func_desc->cParams; i++)
|
for (i = 0; i < func_desc->cParams; i++)
|
||||||
{
|
{
|
||||||
USHORT wParamFlags = func_desc->lprgelemdescParam[i].u.paramdesc.wParamFlags;
|
USHORT wParamFlags = func_desc->lprgelemdescParam[i].u.paramdesc.wParamFlags;
|
||||||
|
VARIANTARG *missing_arg = INVBUF_GET_MISSING_ARG_ARRAY(buffer, func_desc->cParams);
|
||||||
|
|
||||||
if (wParamFlags & PARAMFLAG_FLCID)
|
if (wParamFlags & PARAMFLAG_FLCID)
|
||||||
continue;
|
continue;
|
||||||
|
@ -6286,33 +6290,23 @@ static HRESULT WINAPI ITypeInfo_fnInvoke(
|
||||||
hres = VariantCopyInd(pVarResult, prgpvarg[i]);
|
hres = VariantCopyInd(pVarResult, prgpvarg[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* free data stored in varresult. Note that
|
VARIANT_ClearInd(prgpvarg[i]);
|
||||||
* VariantClear doesn't do what we want because we are
|
|
||||||
* working with byref types. */
|
|
||||||
/* FIXME: clear safearrays, bstrs, records and
|
|
||||||
* variants here too */
|
|
||||||
if ((V_VT(prgpvarg[i]) == (VT_UNKNOWN | VT_BYREF)) ||
|
|
||||||
(V_VT(prgpvarg[i]) == (VT_DISPATCH | VT_BYREF)))
|
|
||||||
{
|
|
||||||
if(*V_UNKNOWNREF(prgpvarg[i]))
|
|
||||||
IUnknown_Release(*V_UNKNOWNREF(prgpvarg[i]));
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
else if (vargs_converted < pDispParams->cArgs)
|
else if (vargs_converted < pDispParams->cArgs)
|
||||||
{
|
{
|
||||||
|
VARIANTARG *arg = &pDispParams->rgvarg[pDispParams->cArgs - 1 - vargs_converted];
|
||||||
if (wParamFlags & PARAMFLAG_FOUT)
|
if (wParamFlags & PARAMFLAG_FOUT)
|
||||||
{
|
{
|
||||||
VARIANTARG *arg = &pDispParams->rgvarg[pDispParams->cArgs - 1 - vargs_converted];
|
if ((rgvt[i] & VT_BYREF) && !(V_VT(arg) & VT_BYREF))
|
||||||
|
{
|
||||||
if ((rgvt[i] == VT_BYREF) && (V_VT(arg) != VT_BYREF))
|
|
||||||
hres = VariantChangeType(arg, &rgvarg[i], 0, V_VT(arg));
|
hres = VariantChangeType(arg, &rgvarg[i], 0, V_VT(arg));
|
||||||
|
|
||||||
if (FAILED(hres))
|
if (FAILED(hres))
|
||||||
{
|
{
|
||||||
ERR("failed to convert param %d to vt %d\n", i,
|
ERR("failed to convert param %d to vt %d\n", i,
|
||||||
V_VT(&pDispParams->rgvarg[pDispParams->cArgs - 1 - vargs_converted]));
|
V_VT(&pDispParams->rgvarg[pDispParams->cArgs - 1 - vargs_converted]));
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (V_VT(prgpvarg[i]) == (VT_VARIANT | VT_ARRAY) &&
|
else if (V_VT(prgpvarg[i]) == (VT_VARIANT | VT_ARRAY) &&
|
||||||
|
@ -6351,6 +6345,8 @@ static HRESULT WINAPI ITypeInfo_fnInvoke(
|
||||||
if (wParamFlags & PARAMFLAG_FHASDEFAULT)
|
if (wParamFlags & PARAMFLAG_FHASDEFAULT)
|
||||||
VariantClear(&rgvarg[i]);
|
VariantClear(&rgvarg[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VariantClear(&missing_arg[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((V_VT(&varresult) == VT_ERROR) && FAILED(V_ERROR(&varresult)))
|
if ((V_VT(&varresult) == VT_ERROR) && FAILED(V_ERROR(&varresult)))
|
||||||
|
|
|
@ -578,6 +578,66 @@ void WINAPI VariantInit(VARIANTARG* pVarg)
|
||||||
V_VT(pVarg) = VT_EMPTY; /* Native doesn't set any other fields */
|
V_VT(pVarg) = VT_EMPTY; /* Native doesn't set any other fields */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
HRESULT VARIANT_ClearInd(VARIANTARG *pVarg)
|
||||||
|
{
|
||||||
|
HRESULT hres;
|
||||||
|
|
||||||
|
TRACE("(%p->(%s%s))\n", pVarg, debugstr_VT(pVarg), debugstr_VF(pVarg));
|
||||||
|
|
||||||
|
hres = VARIANT_ValidateType(V_VT(pVarg));
|
||||||
|
if (FAILED(hres))
|
||||||
|
return hres;
|
||||||
|
|
||||||
|
switch (V_VT(pVarg))
|
||||||
|
{
|
||||||
|
case VT_DISPATCH:
|
||||||
|
case VT_UNKNOWN:
|
||||||
|
if (V_UNKNOWN(pVarg))
|
||||||
|
IUnknown_Release(V_UNKNOWN(pVarg));
|
||||||
|
break;
|
||||||
|
case VT_UNKNOWN | VT_BYREF:
|
||||||
|
case VT_DISPATCH | VT_BYREF:
|
||||||
|
if(*V_UNKNOWNREF(pVarg))
|
||||||
|
IUnknown_Release(*V_UNKNOWNREF(pVarg));
|
||||||
|
break;
|
||||||
|
case VT_BSTR:
|
||||||
|
SysFreeString(V_BSTR(pVarg));
|
||||||
|
break;
|
||||||
|
case VT_BSTR | VT_BYREF:
|
||||||
|
SysFreeString(*V_BSTRREF(pVarg));
|
||||||
|
break;
|
||||||
|
case VT_VARIANT | VT_BYREF:
|
||||||
|
VariantClear(V_VARIANTREF(pVarg));
|
||||||
|
break;
|
||||||
|
case VT_RECORD:
|
||||||
|
case VT_RECORD | VT_BYREF:
|
||||||
|
{
|
||||||
|
struct __tagBRECORD* pBr = &V_UNION(pVarg,brecVal);
|
||||||
|
if (pBr->pRecInfo)
|
||||||
|
{
|
||||||
|
IRecordInfo_RecordClear(pBr->pRecInfo, pBr->pvRecord);
|
||||||
|
IRecordInfo_Release(pBr->pRecInfo);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
if (V_ISARRAY(pVarg) || (V_VT(pVarg) & ~VT_BYREF) == VT_SAFEARRAY)
|
||||||
|
{
|
||||||
|
if (V_ISBYREF(pVarg))
|
||||||
|
{
|
||||||
|
if (*V_ARRAYREF(pVarg))
|
||||||
|
hres = SafeArrayDestroy(*V_ARRAYREF(pVarg));
|
||||||
|
}
|
||||||
|
else if (V_ARRAY(pVarg))
|
||||||
|
hres = SafeArrayDestroy(V_ARRAY(pVarg));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
V_VT(pVarg) = VT_EMPTY;
|
||||||
|
return hres;
|
||||||
|
}
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* VariantClear [OLEAUT32.9]
|
* VariantClear [OLEAUT32.9]
|
||||||
*
|
*
|
||||||
|
|
|
@ -126,3 +126,4 @@ typedef struct tagVARIANT_NUMBER_CHARS
|
||||||
|
|
||||||
|
|
||||||
BOOL VARIANT_GetLocalisedText(LANGID, DWORD, WCHAR *);
|
BOOL VARIANT_GetLocalisedText(LANGID, DWORD, WCHAR *);
|
||||||
|
HRESULT VARIANT_ClearInd(VARIANTARG *);
|
||||||
|
|
Loading…
Reference in New Issue