diff --git a/dlls/oleaut32/tests/tmarshal.c b/dlls/oleaut32/tests/tmarshal.c index 0654622aa12..996c2da8152 100644 --- a/dlls/oleaut32/tests/tmarshal.c +++ b/dlls/oleaut32/tests/tmarshal.c @@ -898,11 +898,8 @@ static void test_typelibmarshal(void) "EXCEPINFO differs from expected: wCode = 0x%x, scode = 0x%08x\n", excepinfo.wCode, excepinfo.scode); - todo_wine - { - ok(V_VT(&varresult) == VT_I2, "V_VT(&varresult) was %d instead of VT_I2\n", V_VT(&varresult)); - ok(V_I2(&varresult) == 1234, "V_I2(&varresult) was %d instead of 1234\n", V_I2(&varresult)); - } + ok(V_VT(&varresult) == VT_I2, "V_VT(&varresult) was %d instead of VT_I2\n", V_VT(&varresult)); + ok(V_I2(&varresult) == 1234, "V_I2(&varresult) was %d instead of 1234\n", V_I2(&varresult)); VariantClear(&varresult); /* call Value with a VT_VARIANT|VT_BYREF type */ @@ -1033,10 +1030,7 @@ static void test_typelibmarshal(void) dispparams.rgdispidNamedArgs = NULL; dispparams.rgvarg = vararg; hr = IDispatch_Invoke(pDispatch, DISPID_TM_STATE, &IID_NULL, LOCALE_NEUTRAL, DISPATCH_PROPERTYGET, &dispparams, &varresult, &excepinfo, NULL); - todo_wine - { - ok(hr == DISP_E_NOTACOLLECTION, "IDispatch_Invoke should have returned DISP_E_NOTACOLLECTION instead of 0x%08x\n", hr); - } + ok(hr == DISP_E_NOTACOLLECTION, "IDispatch_Invoke should have returned DISP_E_NOTACOLLECTION instead of 0x%08x\n", hr); IDispatch_Release(pDispatch); IWidget_Release(pWidget); diff --git a/dlls/oleaut32/typelib.c b/dlls/oleaut32/typelib.c index 63ec3271550..50ddd2f512d 100644 --- a/dlls/oleaut32/typelib.c +++ b/dlls/oleaut32/typelib.c @@ -5519,6 +5519,19 @@ static HRESULT WINAPI ITypeInfo_fnInvoke( if (wParamFlags & PARAMFLAG_FRETVAL) { + /* under most conditions the caller is not allowed to + * pass in a dispparam arg in the index of what would be + * the retval parameter. however, there is an exception + * where the extra parameter is used in an extra + * IDispatch::Invoke below */ + if ((i < pDispParams->cArgs) && + ((func_desc->cParams != 1) || !pVarResult || + !(func_desc->invkind & INVOKE_PROPERTYGET))) + { + hres = DISP_E_BADPARAMCOUNT; + break; + } + /* note: this check is placed so that if the caller passes * in a VARIANTARG for the retval we just ignore it, like * native does */ @@ -5733,6 +5746,29 @@ static HRESULT WINAPI ITypeInfo_fnInvoke( VariantClear(&varresult); } + if (SUCCEEDED(hres) && pVarResult && (func_desc->cParams == 1) && + (wFlags == INVOKE_PROPERTYGET) && + (func_desc->lprgelemdescParam[0].u.paramdesc.wParamFlags & PARAMFLAG_FRETVAL) && + (pDispParams->cArgs != 0)) + { + if (V_VT(pVarResult) == VT_DISPATCH) + { + IDispatch *pDispatch = V_DISPATCH(pVarResult); + /* Note: not VariantClear; we still need the dispatch + * pointer to be valid */ + VariantInit(pVarResult); + hres = IDispatch_Invoke(pDispatch, DISPID_VALUE, &IID_NULL, + GetSystemDefaultLCID(), INVOKE_PROPERTYGET, + pDispParams, pVarResult, pExcepInfo, pArgErr); + IDispatch_Release(pDispatch); + } + else + { + VariantClear(pVarResult); + hres = DISP_E_NOTACOLLECTION; + } + } + func_fail: HeapFree(GetProcessHeap(), 0, buffer); break;