[PATCH 0/1] MR10601: oleaut32: Propagate dispatch errors from VARIANT_FromDisp.
When IDispatch::Invoke(DISPID_VALUE) fails in VARIANT_FromDisp, propagate FACILITY_DISPATCH errors (like DISP_E_MEMBERNOTFOUND) instead of always replacing them with DISP_E_TYPEMISMATCH. This matches Windows behavior where accessing the default property of a dispatch object without one returns error 438 through VariantChangeType, not error 13. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/10601
From: Francis De Brabandere <francisdb@gmail.com> When IDispatch::Invoke(DISPID_VALUE) fails in VARIANT_FromDisp, propagate FACILITY_DISPATCH errors (like DISP_E_MEMBERNOTFOUND) instead of always replacing them with DISP_E_TYPEMISMATCH. This matches Windows behavior where accessing the default property of a dispatch object without one returns error 438 through VariantChangeType, not error 13. --- dlls/oleaut32/tests/vartype.c | 20 +++++++++++++++++++- dlls/oleaut32/vartype.c | 2 +- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/dlls/oleaut32/tests/vartype.c b/dlls/oleaut32/tests/vartype.c index dfa614d3fc6..45e8c41b40b 100644 --- a/dlls/oleaut32/tests/vartype.c +++ b/dlls/oleaut32/tests/vartype.c @@ -295,6 +295,7 @@ typedef struct LONG ref; VARTYPE vt; BOOL bFailInvoke; + HRESULT failhr; } DummyDispatch; static inline DummyDispatch *impl_from_IDispatch(IDispatch *iface) @@ -376,7 +377,7 @@ static HRESULT WINAPI DummyDispatch_Invoke(IDispatch *iface, ok(arg_err == NULL, "got %p\n", arg_err); if (This->bFailInvoke) - return E_OUTOFMEMORY; + return This->failhr ? This->failhr : E_OUTOFMEMORY; V_VT(res) = This->vt; if (This->vt == VT_UI1) @@ -920,6 +921,23 @@ static void test_VarUI1FromDisp(void) ok(hres == DISP_E_TYPEMISMATCH, "got 0x%08lx\n", hres); ok(V_VT(&vDst) == VT_EMPTY, "got %d\n", V_VT(&vDst)); CHECK_CALLED(dispatch_invoke); + + /* DISP_E_MEMBERNOTFOUND from Invoke should be propagated, not replaced */ + dispatch.failhr = DISP_E_MEMBERNOTFOUND; + + SET_EXPECT(dispatch_invoke); + out = 10; + hres = VarUI1FromDisp(&dispatch.IDispatch_iface, in, &out); + ok(hres == DISP_E_MEMBERNOTFOUND, "got 0x%08lx\n", hres); + ok(out == 10, "got %d\n", out); + CHECK_CALLED(dispatch_invoke); + + SET_EXPECT(dispatch_invoke); + V_VT(&vDst) = VT_EMPTY; + hres = VariantChangeTypeEx(&vDst, &vSrc, in, 0, VT_BSTR); + ok(hres == DISP_E_MEMBERNOTFOUND, "got 0x%08lx\n", hres); + ok(V_VT(&vDst) == VT_EMPTY, "got %d\n", V_VT(&vDst)); + CHECK_CALLED(dispatch_invoke); } static void test_VarUI1Copy(void) diff --git a/dlls/oleaut32/vartype.c b/dlls/oleaut32/vartype.c index 9fad7485a2d..4ddd21c669a 100644 --- a/dlls/oleaut32/vartype.c +++ b/dlls/oleaut32/vartype.c @@ -131,7 +131,7 @@ static HRESULT VARIANT_FromDisp(IDispatch* pdispIn, LCID lcid, void* pOut, if (SUCCEEDED(hRet)) VARIANT_CopyData(&dstVar, vt, pOut); } - else + else if (HRESULT_FACILITY(hRet) != FACILITY_DISPATCH) hRet = DISP_E_TYPEMISMATCH; return hRet; } -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10601
participants (2)
-
Francis De Brabandere -
Francis De Brabandere (@francisdb)