[PATCH 06/13] oleaut32: Fix rewriting FUNCDESC to FUNC_DISPATCH.
Puetz Kevin A
PuetzKevinA at JohnDeere.com
Thu Aug 6 23:11:08 CDT 2020
A [retval] parameter overwrites any return type, not just HRESULT.
But HRESULT is special even without a [retval] to replace it;
it's translated into pExcepInfo and so the return type becomes void.
[lcid] parameters are supplied from IDispatch::Invoke's parameters,
rather than via DISPPARAMS::rgvargs[] and should also be removed
from the FUNC_DISPATCH translation.
This rewriting should occur only for functions not originally
defined as FUNC_DISPACH (e.g. inherited or [dual]).
A FUNCDESC originally declared as a dispinterface is left as-is,
and might e.g. return HRESULT.
When GetFuncDesc removes parameters in this fashion,
GetNames must also omit their names to match cParams.
FUNC_DISPATCH from dispinterface should have oVft == 0
(a dispinterface has no vtbl beyond IDispatch itself)
Add examples in test_tlb which exercise FUNCDESC rewriting in:
1. dispinterface FUNC_DISPATCH declarations
2. dual interface
3. dispinterface which implements another interface
Signed-off-by: Kevin Puetz <PuetzKevinA at JohnDeere.com>
---
dlls/oleaut32/tests/test_tlb.idl | 36 ++
dlls/oleaut32/tests/typelib.c | 653 +++++++++++++++++++++++++++++++
dlls/oleaut32/typelib.c | 96 +++--
3 files changed, 757 insertions(+), 28 deletions(-)
diff --git a/dlls/oleaut32/tests/test_tlb.idl b/dlls/oleaut32/tests/test_tlb.idl
index ad35af40c3..b8fecc9a01 100644
--- a/dlls/oleaut32/tests/test_tlb.idl
+++ b/dlls/oleaut32/tests/test_tlb.idl
@@ -134,4 +134,40 @@ library Test
HRESULT test5(e value);
HRESULT test6(f value);
}
+
+ [uuid(2d4430d5-99ea-4645-85f0-c5814b72804b)]
+ dispinterface ITestDispatch
+ {
+ properties:
+ [id(10)] int property_int;
+ [id(11)] HRESULT property_HRESULT;
+
+ methods:
+ [id(1)] void test_void();
+ [id(2)] void test_void_retval([out,retval] double* ret);
+ [id(3)] HRESULT test_HRESULT();
+ [id(4)] HRESULT test_HRESULT_retval([out,retval] double* ret);
+ [id(5)] int test_int();
+ [id(6)] int test_int_retval([out,retval] double* ret);
+ [id(7)] double parse_lcid([in] BSTR x, [lcid] long lcid);
+
+ }
+
+ [uuid(79ca07f9-ac22-44ac-9aaf-811f45412293), dual]
+ interface ITestDispDual : IDispatch
+ {
+ [id(1)] void test_void();
+ [id(2)] void test_void_retval([out,retval] double* ret);
+ [id(3)] HRESULT test_HRESULT();
+ [id(4)] HRESULT test_HRESULT_retval([out,retval] double* ret);
+ [id(5)] int test_int();
+ [id(6)] int test_int_retval([out,retval] double* ret);
+ [id(7)] HRESULT parse_lcid([in] BSTR x, [lcid] long lcid, [out,retval] double *ret);
+ }
+
+ [uuid(cdb105e3-24fb-4ae6-b826-801b7b2a0a07)]
+ dispinterface ITestDispInherit
+ {
+ interface ITestDispDual;
+ }
}
diff --git a/dlls/oleaut32/tests/typelib.c b/dlls/oleaut32/tests/typelib.c
index 2f23949c7d..d4b573eb7a 100644
--- a/dlls/oleaut32/tests/typelib.c
+++ b/dlls/oleaut32/tests/typelib.c
@@ -5277,6 +5277,659 @@ static const type_info info[] = {
},
},
{ /* vars */ },
+},
+{
+ "ITestDispatch",
+ "{2d4430d5-99ea-4645-85f0-c5814b72804b}",
+ /*kind*/ TKIND_DISPATCH, /*flags*/ TYPEFLAG_FDISPATCHABLE, /*align*/ TYPE_ALIGNMENT(ITestDispatch*), /*size*/ sizeof(ITestDispatch*),
+ /*helpctx*/ 0x0000, /*version*/ 0x00000000, /*#vtbl*/ 7, /*#func*/ 7, /*#var*/ 2,
+ { /* funcs */
+ {
+ /*id*/ 0x1, /*func*/ FUNC_DISPATCH, /*inv*/ INVOKE_FUNC, /*call*/ CC_STDCALL,
+ /*#param*/ 0, /*#opt*/ 0, /*vtbl*/ 0, /*#scodes*/ 0, /*flags*/ 0,
+ {VT_VOID, -1, PARAMFLAG_NONE}, /* ret */
+ { /* params */
+ {-1, 0, 0}
+ },
+ { /* names */
+ "test_void",
+ NULL,
+ },
+ },
+ {
+ /*id*/ 0x2, /*func*/ FUNC_DISPATCH, /*inv*/ INVOKE_FUNC, /*call*/ CC_STDCALL,
+ /*#param*/ 1, /*#opt*/ 0, /*vtbl*/ 0, /*#scodes*/ 0, /*flags*/ 0,
+ {VT_VOID, -1, PARAMFLAG_NONE}, /* ret */
+ { /* params */
+ {VT_PTR, -1, PARAMFLAG_FOUT|PARAMFLAG_FRETVAL},
+ {-1, 0, 0}
+ },
+ { /* names */
+ "test_void_retval",
+ "ret",
+ NULL,
+ },
+ },
+ {
+ /*id*/ 0x3, /*func*/ FUNC_DISPATCH, /*inv*/ INVOKE_FUNC, /*call*/ CC_STDCALL,
+ /*#param*/ 0, /*#opt*/ 0, /*vtbl*/ 0, /*#scodes*/ 0, /*flags*/ 0,
+ {VT_HRESULT, -1, PARAMFLAG_NONE}, /* ret */
+ { /* params */
+ {-1, 0, 0}
+ },
+ { /* names */
+ "test_HRESULT",
+ NULL,
+ },
+ },
+ {
+ /*id*/ 0x4, /*func*/ FUNC_DISPATCH, /*inv*/ INVOKE_FUNC, /*call*/ CC_STDCALL,
+ /*#param*/ 1, /*#opt*/ 0, /*vtbl*/ 0, /*#scodes*/ 0, /*flags*/ 0,
+ {VT_HRESULT, -1, PARAMFLAG_NONE}, /* ret */
+ { /* params */
+ {VT_PTR, -1, PARAMFLAG_FOUT|PARAMFLAG_FRETVAL},
+ {-1, 0, 0}
+ },
+ { /* names */
+ "test_HRESULT_retval",
+ "ret",
+ NULL,
+ },
+ },
+ {
+ /*id*/ 0x5, /*func*/ FUNC_DISPATCH, /*inv*/ INVOKE_FUNC, /*call*/ CC_STDCALL,
+ /*#param*/ 0, /*#opt*/ 0, /*vtbl*/ 0, /*#scodes*/ 0, /*flags*/ 0,
+ {VT_INT, -1, PARAMFLAG_NONE}, /* ret */
+ { /* params */
+ {-1, 0, 0}
+ },
+ { /* names */
+ "test_int",
+ NULL,
+ },
+ },
+ {
+ /*id*/ 0x6, /*func*/ FUNC_DISPATCH, /*inv*/ INVOKE_FUNC, /*call*/ CC_STDCALL,
+ /*#param*/ 1, /*#opt*/ 0, /*vtbl*/ 0, /*#scodes*/ 0, /*flags*/ 0,
+ {VT_INT, -1, PARAMFLAG_NONE}, /* ret */
+ { /* params */
+ {VT_PTR, -1, PARAMFLAG_FOUT|PARAMFLAG_FRETVAL},
+ {-1, 0, 0}
+ },
+ { /* names */
+ "test_int_retval",
+ "ret",
+ NULL,
+ },
+ },
+ {
+ /*id*/ 0x7, /*func*/ FUNC_DISPATCH, /*inv*/ INVOKE_FUNC, /*call*/ CC_STDCALL,
+ /*#param*/ 2, /*#opt*/ 0, /*vtbl*/ 0, /*#scodes*/ 0, /*flags*/ 0,
+ {VT_R8, -1, PARAMFLAG_NONE}, /* ret */
+ { /* params */
+ {VT_BSTR, -1, PARAMFLAG_FIN},
+ {VT_I4, -1, PARAMFLAG_FLCID},
+ {-1, 0, 0}
+ },
+ { /* names */
+ "parse_lcid",
+ "x",
+ "lcid",
+ NULL,
+ },
+ },
+ },
+ { /* vars */
+ {
+ /*id*/ 0xa, /*name*/ "property_int", /*flags*/ 0, /*kind*/ VAR_DISPATCH,
+ { /* DUMMYUNIONNAME unused*/ },
+ {VT_INT, -1, PARAMFLAG_NONE}, /* ret */
+ },
+ {
+ /*id*/ 0xb, /*name*/ "property_HRESULT", /*flags*/ 0, /*kind*/ VAR_DISPATCH,
+ { /* DUMMYUNIONNAME unused*/ },
+ {VT_HRESULT, -1, PARAMFLAG_NONE}, /* ret */
+ },
+ },
+},
+{
+ "ITestDispDual",
+ "{79ca07f9-ac22-44ac-9aaf-811f45412293}",
+ /*kind*/ TKIND_DISPATCH, /*flags*/ TYPEFLAG_FDISPATCHABLE|TYPEFLAG_FDUAL, /*align*/ TYPE_ALIGNMENT(ITestDispDual*), /*size*/ sizeof(ITestDispDual*),
+ /*helpctx*/ 0x0000, /*version*/ 0x00000000, /*#vtbl*/ 7, /*#func*/ 14, /*#var*/ 0,
+ { /* funcs */
+ {
+ /*id*/ 0x60000000, /*func*/ FUNC_DISPATCH, /*inv*/ INVOKE_FUNC, /*call*/ CC_STDCALL,
+ /*#param*/ 2, /*#opt*/ 0, /*vtbl*/ 0, /*#scodes*/ 0, /*flags*/ FUNCFLAG_FRESTRICTED,
+ {VT_VOID, -1, PARAMFLAG_NONE}, /* ret */
+ { /* params */
+ {VT_PTR, -1, PARAMFLAG_FIN},
+ {VT_PTR, -1, PARAMFLAG_FOUT},
+ {-1, 0, 0}
+ },
+ { /* names */
+ "QueryInterface",
+ "riid",
+ "ppvObj",
+ NULL,
+ },
+ },
+ {
+ /*id*/ 0x60000001, /*func*/ FUNC_DISPATCH, /*inv*/ INVOKE_FUNC, /*call*/ CC_STDCALL,
+ /*#param*/ 0, /*#opt*/ 0, /*vtbl*/ 1, /*#scodes*/ 0, /*flags*/ FUNCFLAG_FRESTRICTED,
+ {VT_UI4, -1, PARAMFLAG_NONE}, /* ret */
+ { /* params */
+ {-1, 0, 0}
+ },
+ { /* names */
+ "AddRef",
+ NULL,
+ },
+ },
+ {
+ /*id*/ 0x60000002, /*func*/ FUNC_DISPATCH, /*inv*/ INVOKE_FUNC, /*call*/ CC_STDCALL,
+ /*#param*/ 0, /*#opt*/ 0, /*vtbl*/ 2, /*#scodes*/ 0, /*flags*/ FUNCFLAG_FRESTRICTED,
+ {VT_UI4, -1, PARAMFLAG_NONE}, /* ret */
+ { /* params */
+ {-1, 0, 0}
+ },
+ { /* names */
+ "Release",
+ NULL,
+ },
+ },
+ {
+ /*id*/ 0x60010000, /*func*/ FUNC_DISPATCH, /*inv*/ INVOKE_FUNC, /*call*/ CC_STDCALL,
+ /*#param*/ 1, /*#opt*/ 0, /*vtbl*/ 3, /*#scodes*/ 0, /*flags*/ FUNCFLAG_FRESTRICTED,
+ {VT_VOID, -1, PARAMFLAG_NONE}, /* ret */
+ { /* params */
+ {VT_PTR, -1, PARAMFLAG_FOUT},
+ {-1, 0, 0}
+ },
+ { /* names */
+ "GetTypeInfoCount",
+ "pctinfo",
+ NULL,
+ },
+ },
+ {
+ /*id*/ 0x60010001, /*func*/ FUNC_DISPATCH, /*inv*/ INVOKE_FUNC, /*call*/ CC_STDCALL,
+ /*#param*/ 3, /*#opt*/ 0, /*vtbl*/ 4, /*#scodes*/ 0, /*flags*/ FUNCFLAG_FRESTRICTED,
+ {VT_VOID, -1, PARAMFLAG_NONE}, /* ret */
+ { /* params */
+ {VT_UINT, -1, PARAMFLAG_FIN},
+ {VT_UI4, -1, PARAMFLAG_FIN},
+ {VT_PTR, -1, PARAMFLAG_FOUT},
+ {-1, 0, 0}
+ },
+ { /* names */
+ "GetTypeInfo",
+ "itinfo",
+ "lcid",
+ "pptinfo",
+ NULL,
+ },
+ },
+ {
+ /*id*/ 0x60010002, /*func*/ FUNC_DISPATCH, /*inv*/ INVOKE_FUNC, /*call*/ CC_STDCALL,
+ /*#param*/ 5, /*#opt*/ 0, /*vtbl*/ 5, /*#scodes*/ 0, /*flags*/ FUNCFLAG_FRESTRICTED,
+ {VT_VOID, -1, PARAMFLAG_NONE}, /* ret */
+ { /* params */
+ {VT_PTR, -1, PARAMFLAG_FIN},
+ {VT_PTR, -1, PARAMFLAG_FIN},
+ {VT_UINT, -1, PARAMFLAG_FIN},
+ {VT_UI4, -1, PARAMFLAG_FIN},
+ {VT_PTR, -1, PARAMFLAG_FOUT},
+ {-1, 0, 0}
+ },
+ { /* names */
+ "GetIDsOfNames",
+ "riid",
+ "rgszNames",
+ "cNames",
+ "lcid",
+ "rgdispid",
+ NULL,
+ },
+ },
+ {
+ /*id*/ 0x60010003, /*func*/ FUNC_DISPATCH, /*inv*/ INVOKE_FUNC, /*call*/ CC_STDCALL,
+ /*#param*/ 8, /*#opt*/ 0, /*vtbl*/ 6, /*#scodes*/ 0, /*flags*/ FUNCFLAG_FRESTRICTED,
+ {VT_VOID, -1, PARAMFLAG_NONE}, /* ret */
+ { /* params */
+ {VT_I4, -1, PARAMFLAG_FIN},
+ {VT_PTR, -1, PARAMFLAG_FIN},
+ {VT_UI4, -1, PARAMFLAG_FIN},
+ {VT_UI2, -1, PARAMFLAG_FIN},
+ {VT_PTR, -1, PARAMFLAG_FIN},
+ {VT_PTR, -1, PARAMFLAG_FOUT},
+ {VT_PTR, -1, PARAMFLAG_FOUT},
+ {VT_PTR, -1, PARAMFLAG_FOUT},
+ {-1, 0, 0}
+ },
+ { /* names */
+ "Invoke",
+ "dispidMember",
+ "riid",
+ "lcid",
+ "wFlags",
+ "pdispparams",
+ "pvarResult",
+ "pexcepinfo",
+ "puArgErr",
+ NULL,
+ },
+ },
+ {
+ /*id*/ 0x1, /*func*/ FUNC_DISPATCH, /*inv*/ INVOKE_FUNC, /*call*/ CC_STDCALL,
+ /*#param*/ 0, /*#opt*/ 0, /*vtbl*/ 7, /*#scodes*/ 0, /*flags*/ 0,
+ {VT_VOID, -1, PARAMFLAG_NONE}, /* ret */
+ { /* params */
+ {-1, 0, 0}
+ },
+ { /* names */
+ "test_void",
+ NULL,
+ },
+ },
+ {
+ /*id*/ 0x2, /*func*/ FUNC_DISPATCH, /*inv*/ INVOKE_FUNC, /*call*/ CC_STDCALL,
+ /*#param*/ 0, /*#opt*/ 0, /*vtbl*/ 8, /*#scodes*/ 0, /*flags*/ 0,
+ {VT_R8, -1, PARAMFLAG_NONE}, /* ret */
+ { /* params */
+ {-1, 0, 0}
+ },
+ { /* names */
+ "test_void_retval",
+ NULL,
+ },
+ },
+ {
+ /*id*/ 0x3, /*func*/ FUNC_DISPATCH, /*inv*/ INVOKE_FUNC, /*call*/ CC_STDCALL,
+ /*#param*/ 0, /*#opt*/ 0, /*vtbl*/ 9, /*#scodes*/ 0, /*flags*/ 0,
+ {VT_VOID, -1, PARAMFLAG_NONE}, /* ret */
+ { /* params */
+ {-1, 0, 0}
+ },
+ { /* names */
+ "test_HRESULT",
+ NULL,
+ },
+ },
+ {
+ /*id*/ 0x4, /*func*/ FUNC_DISPATCH, /*inv*/ INVOKE_FUNC, /*call*/ CC_STDCALL,
+ /*#param*/ 0, /*#opt*/ 0, /*vtbl*/ 10, /*#scodes*/ 0, /*flags*/ 0,
+ {VT_R8, -1, PARAMFLAG_NONE}, /* ret */
+ { /* params */
+ {-1, 0, 0}
+ },
+ { /* names */
+ "test_HRESULT_retval",
+ NULL,
+ },
+ },
+ {
+ /*id*/ 0x5, /*func*/ FUNC_DISPATCH, /*inv*/ INVOKE_FUNC, /*call*/ CC_STDCALL,
+ /*#param*/ 0, /*#opt*/ 0, /*vtbl*/ 11, /*#scodes*/ 0, /*flags*/ 0,
+ {VT_INT, -1, PARAMFLAG_NONE}, /* ret */
+ { /* params */
+ {-1, 0, 0}
+ },
+ { /* names */
+ "test_int",
+ NULL,
+ },
+ },
+ {
+ /*id*/ 0x6, /*func*/ FUNC_DISPATCH, /*inv*/ INVOKE_FUNC, /*call*/ CC_STDCALL,
+ /*#param*/ 0, /*#opt*/ 0, /*vtbl*/ 12, /*#scodes*/ 0, /*flags*/ 0,
+ {VT_R8, -1, PARAMFLAG_NONE}, /* ret */
+ { /* params */
+ {-1, 0, 0}
+ },
+ { /* names */
+ "test_int_retval",
+ NULL,
+ },
+ },
+ {
+ /*id*/ 0x7, /*func*/ FUNC_DISPATCH, /*inv*/ INVOKE_FUNC, /*call*/ CC_STDCALL,
+ /*#param*/ 1, /*#opt*/ 0, /*vtbl*/ 13, /*#scodes*/ 0, /*flags*/ 0,
+ {VT_R8, -1, PARAMFLAG_NONE}, /* ret */
+ { /* params */
+ {VT_BSTR, -1, PARAMFLAG_FIN},
+ {-1, 0, 0}
+ },
+ { /* names */
+ "parse_lcid",
+ "x",
+ NULL,
+ },
+ },
+ },
+ { /* vars */ },
+},
+{
+ "ITestDispDual",
+ "{79ca07f9-ac22-44ac-9aaf-811f45412293}",
+ /*kind*/ TKIND_INTERFACE, /*flags*/ TYPEFLAG_FDISPATCHABLE|TYPEFLAG_FOLEAUTOMATION|TYPEFLAG_FDUAL, /*align*/ TYPE_ALIGNMENT(ITestDispDual*), /*size*/ sizeof(ITestDispDual*),
+ /*helpctx*/ 0x0000, /*version*/ 0x00000000, /*#vtbl*/ 14, /*#func*/ 7, /*#var*/ 0,
+ { /* funcs */
+ {
+ /*id*/ 0x1, /*func*/ FUNC_PUREVIRTUAL, /*inv*/ INVOKE_FUNC, /*call*/ CC_STDCALL,
+ /*#param*/ 0, /*#opt*/ 0, /*vtbl*/ 7, /*#scodes*/ 0, /*flags*/ 0,
+ {VT_VOID, -1, PARAMFLAG_NONE}, /* ret */
+ { /* params */
+ {-1, 0, 0}
+ },
+ { /* names */
+ "test_void",
+ NULL,
+ },
+ },
+ {
+ /*id*/ 0x2, /*func*/ FUNC_PUREVIRTUAL, /*inv*/ INVOKE_FUNC, /*call*/ CC_STDCALL,
+ /*#param*/ 1, /*#opt*/ 0, /*vtbl*/ 8, /*#scodes*/ 0, /*flags*/ 0,
+ {VT_VOID, -1, PARAMFLAG_NONE}, /* ret */
+ { /* params */
+ {VT_PTR, -1, PARAMFLAG_FOUT|PARAMFLAG_FRETVAL},
+ {-1, 0, 0}
+ },
+ { /* names */
+ "test_void_retval",
+ "ret",
+ NULL,
+ },
+ },
+ {
+ /*id*/ 0x3, /*func*/ FUNC_PUREVIRTUAL, /*inv*/ INVOKE_FUNC, /*call*/ CC_STDCALL,
+ /*#param*/ 0, /*#opt*/ 0, /*vtbl*/ 9, /*#scodes*/ 0, /*flags*/ 0,
+ {VT_HRESULT, -1, PARAMFLAG_NONE}, /* ret */
+ { /* params */
+ {-1, 0, 0}
+ },
+ { /* names */
+ "test_HRESULT",
+ NULL,
+ },
+ },
+ {
+ /*id*/ 0x4, /*func*/ FUNC_PUREVIRTUAL, /*inv*/ INVOKE_FUNC, /*call*/ CC_STDCALL,
+ /*#param*/ 1, /*#opt*/ 0, /*vtbl*/ 10, /*#scodes*/ 0, /*flags*/ 0,
+ {VT_HRESULT, -1, PARAMFLAG_NONE}, /* ret */
+ { /* params */
+ {VT_PTR, -1, PARAMFLAG_FOUT|PARAMFLAG_FRETVAL},
+ {-1, 0, 0}
+ },
+ { /* names */
+ "test_HRESULT_retval",
+ "ret",
+ NULL,
+ },
+ },
+ {
+ /*id*/ 0x5, /*func*/ FUNC_PUREVIRTUAL, /*inv*/ INVOKE_FUNC, /*call*/ CC_STDCALL,
+ /*#param*/ 0, /*#opt*/ 0, /*vtbl*/ 11, /*#scodes*/ 0, /*flags*/ 0,
+ {VT_INT, -1, PARAMFLAG_NONE}, /* ret */
+ { /* params */
+ {-1, 0, 0}
+ },
+ { /* names */
+ "test_int",
+ NULL,
+ },
+ },
+ {
+ /*id*/ 0x6, /*func*/ FUNC_PUREVIRTUAL, /*inv*/ INVOKE_FUNC, /*call*/ CC_STDCALL,
+ /*#param*/ 1, /*#opt*/ 0, /*vtbl*/ 12, /*#scodes*/ 0, /*flags*/ 0,
+ {VT_INT, -1, PARAMFLAG_NONE}, /* ret */
+ { /* params */
+ {VT_PTR, -1, PARAMFLAG_FOUT|PARAMFLAG_FRETVAL},
+ {-1, 0, 0}
+ },
+ { /* names */
+ "test_int_retval",
+ "ret",
+ NULL,
+ },
+ },
+ {
+ /*id*/ 0x7, /*func*/ FUNC_PUREVIRTUAL, /*inv*/ INVOKE_FUNC, /*call*/ CC_STDCALL,
+ /*#param*/ 3, /*#opt*/ 0, /*vtbl*/ 13, /*#scodes*/ 0, /*flags*/ 0,
+ {VT_HRESULT, -1, PARAMFLAG_NONE}, /* ret */
+ { /* params */
+ {VT_BSTR, -1, PARAMFLAG_FIN},
+ {VT_I4, -1, PARAMFLAG_FLCID},
+ {VT_PTR, -1, PARAMFLAG_FOUT|PARAMFLAG_FRETVAL},
+ {-1, 0, 0}
+ },
+ { /* names */
+ "parse_lcid",
+ "x",
+ "lcid",
+ "ret",
+ NULL,
+ },
+ },
+ },
+ { /* vars */ },
+},
+{
+ "ITestDispInherit",
+ "{cdb105e3-24fb-4ae6-b826-801b7b2a0a07}",
+ /*kind*/ TKIND_DISPATCH, /*flags*/ TYPEFLAG_FDISPATCHABLE, /*align*/ TYPE_ALIGNMENT(ITestDispInherit*), /*size*/ sizeof(ITestDispInherit*),
+ /*helpctx*/ 0x0000, /*version*/ 0x00000000, /*#vtbl*/ 7, /*#func*/ 14, /*#var*/ 0,
+ { /* funcs */
+ {
+ /*id*/ 0x60000000, /*func*/ FUNC_DISPATCH, /*inv*/ INVOKE_FUNC, /*call*/ CC_STDCALL,
+ /*#param*/ 2, /*#opt*/ 0, /*vtbl*/ 0, /*#scodes*/ 0, /*flags*/ FUNCFLAG_FRESTRICTED,
+ {VT_VOID, -1, PARAMFLAG_NONE}, /* ret */
+ { /* params */
+ {VT_PTR, -1, PARAMFLAG_FIN},
+ {VT_PTR, -1, PARAMFLAG_FOUT},
+ {-1, 0, 0}
+ },
+ { /* names */
+ "QueryInterface",
+ "riid",
+ "ppvObj",
+ NULL,
+ },
+ },
+ {
+ /*id*/ 0x60000001, /*func*/ FUNC_DISPATCH, /*inv*/ INVOKE_FUNC, /*call*/ CC_STDCALL,
+ /*#param*/ 0, /*#opt*/ 0, /*vtbl*/ 1, /*#scodes*/ 0, /*flags*/ FUNCFLAG_FRESTRICTED,
+ {VT_UI4, -1, PARAMFLAG_NONE}, /* ret */
+ { /* params */
+ {-1, 0, 0}
+ },
+ { /* names */
+ "AddRef",
+ NULL,
+ },
+ },
+ {
+ /*id*/ 0x60000002, /*func*/ FUNC_DISPATCH, /*inv*/ INVOKE_FUNC, /*call*/ CC_STDCALL,
+ /*#param*/ 0, /*#opt*/ 0, /*vtbl*/ 2, /*#scodes*/ 0, /*flags*/ FUNCFLAG_FRESTRICTED,
+ {VT_UI4, -1, PARAMFLAG_NONE}, /* ret */
+ { /* params */
+ {-1, 0, 0}
+ },
+ { /* names */
+ "Release",
+ NULL,
+ },
+ },
+ {
+ /*id*/ 0x60010000, /*func*/ FUNC_DISPATCH, /*inv*/ INVOKE_FUNC, /*call*/ CC_STDCALL,
+ /*#param*/ 1, /*#opt*/ 0, /*vtbl*/ 3, /*#scodes*/ 0, /*flags*/ FUNCFLAG_FRESTRICTED,
+ {VT_VOID, -1, PARAMFLAG_NONE}, /* ret */
+ { /* params */
+ {VT_PTR, -1, PARAMFLAG_FOUT},
+ {-1, 0, 0}
+ },
+ { /* names */
+ "GetTypeInfoCount",
+ "pctinfo",
+ NULL,
+ },
+ },
+ {
+ /*id*/ 0x60010001, /*func*/ FUNC_DISPATCH, /*inv*/ INVOKE_FUNC, /*call*/ CC_STDCALL,
+ /*#param*/ 3, /*#opt*/ 0, /*vtbl*/ 4, /*#scodes*/ 0, /*flags*/ FUNCFLAG_FRESTRICTED,
+ {VT_VOID, -1, PARAMFLAG_NONE}, /* ret */
+ { /* params */
+ {VT_UINT, -1, PARAMFLAG_FIN},
+ {VT_UI4, -1, PARAMFLAG_FIN},
+ {VT_PTR, -1, PARAMFLAG_FOUT},
+ {-1, 0, 0}
+ },
+ { /* names */
+ "GetTypeInfo",
+ "itinfo",
+ "lcid",
+ "pptinfo",
+ NULL,
+ },
+ },
+ {
+ /*id*/ 0x60010002, /*func*/ FUNC_DISPATCH, /*inv*/ INVOKE_FUNC, /*call*/ CC_STDCALL,
+ /*#param*/ 5, /*#opt*/ 0, /*vtbl*/ 5, /*#scodes*/ 0, /*flags*/ FUNCFLAG_FRESTRICTED,
+ {VT_VOID, -1, PARAMFLAG_NONE}, /* ret */
+ { /* params */
+ {VT_PTR, -1, PARAMFLAG_FIN},
+ {VT_PTR, -1, PARAMFLAG_FIN},
+ {VT_UINT, -1, PARAMFLAG_FIN},
+ {VT_UI4, -1, PARAMFLAG_FIN},
+ {VT_PTR, -1, PARAMFLAG_FOUT},
+ {-1, 0, 0}
+ },
+ { /* names */
+ "GetIDsOfNames",
+ "riid",
+ "rgszNames",
+ "cNames",
+ "lcid",
+ "rgdispid",
+ NULL,
+ },
+ },
+ {
+ /*id*/ 0x60010003, /*func*/ FUNC_DISPATCH, /*inv*/ INVOKE_FUNC, /*call*/ CC_STDCALL,
+ /*#param*/ 8, /*#opt*/ 0, /*vtbl*/ 6, /*#scodes*/ 0, /*flags*/ FUNCFLAG_FRESTRICTED,
+ {VT_VOID, -1, PARAMFLAG_NONE}, /* ret */
+ { /* params */
+ {VT_I4, -1, PARAMFLAG_FIN},
+ {VT_PTR, -1, PARAMFLAG_FIN},
+ {VT_UI4, -1, PARAMFLAG_FIN},
+ {VT_UI2, -1, PARAMFLAG_FIN},
+ {VT_PTR, -1, PARAMFLAG_FIN},
+ {VT_PTR, -1, PARAMFLAG_FOUT},
+ {VT_PTR, -1, PARAMFLAG_FOUT},
+ {VT_PTR, -1, PARAMFLAG_FOUT},
+ {-1, 0, 0}
+ },
+ { /* names */
+ "Invoke",
+ "dispidMember",
+ "riid",
+ "lcid",
+ "wFlags",
+ "pdispparams",
+ "pvarResult",
+ "pexcepinfo",
+ "puArgErr",
+ NULL,
+ },
+ },
+ {
+ /*id*/ 0x1, /*func*/ FUNC_DISPATCH, /*inv*/ INVOKE_FUNC, /*call*/ CC_STDCALL,
+ /*#param*/ 0, /*#opt*/ 0, /*vtbl*/ 7, /*#scodes*/ 0, /*flags*/ 0,
+ {VT_VOID, -1, PARAMFLAG_NONE}, /* ret */
+ { /* params */
+ {-1, 0, 0}
+ },
+ { /* names */
+ "test_void",
+ NULL,
+ },
+ },
+ {
+ /*id*/ 0x2, /*func*/ FUNC_DISPATCH, /*inv*/ INVOKE_FUNC, /*call*/ CC_STDCALL,
+ /*#param*/ 0, /*#opt*/ 0, /*vtbl*/ 8, /*#scodes*/ 0, /*flags*/ 0,
+ {VT_R8, -1, PARAMFLAG_NONE}, /* ret */
+ { /* params */
+ {-1, 0, 0}
+ },
+ { /* names */
+ "test_void_retval",
+ NULL,
+ },
+ },
+ {
+ /*id*/ 0x3, /*func*/ FUNC_DISPATCH, /*inv*/ INVOKE_FUNC, /*call*/ CC_STDCALL,
+ /*#param*/ 0, /*#opt*/ 0, /*vtbl*/ 9, /*#scodes*/ 0, /*flags*/ 0,
+ {VT_VOID, -1, PARAMFLAG_NONE}, /* ret */
+ { /* params */
+ {-1, 0, 0}
+ },
+ { /* names */
+ "test_HRESULT",
+ NULL,
+ },
+ },
+ {
+ /*id*/ 0x4, /*func*/ FUNC_DISPATCH, /*inv*/ INVOKE_FUNC, /*call*/ CC_STDCALL,
+ /*#param*/ 0, /*#opt*/ 0, /*vtbl*/ 10, /*#scodes*/ 0, /*flags*/ 0,
+ {VT_R8, -1, PARAMFLAG_NONE}, /* ret */
+ { /* params */
+ {-1, 0, 0}
+ },
+ { /* names */
+ "test_HRESULT_retval",
+ NULL,
+ },
+ },
+ {
+ /*id*/ 0x5, /*func*/ FUNC_DISPATCH, /*inv*/ INVOKE_FUNC, /*call*/ CC_STDCALL,
+ /*#param*/ 0, /*#opt*/ 0, /*vtbl*/ 11, /*#scodes*/ 0, /*flags*/ 0,
+ {VT_INT, -1, PARAMFLAG_NONE}, /* ret */
+ { /* params */
+ {-1, 0, 0}
+ },
+ { /* names */
+ "test_int",
+ NULL,
+ },
+ },
+ {
+ /*id*/ 0x6, /*func*/ FUNC_DISPATCH, /*inv*/ INVOKE_FUNC, /*call*/ CC_STDCALL,
+ /*#param*/ 0, /*#opt*/ 0, /*vtbl*/ 12, /*#scodes*/ 0, /*flags*/ 0,
+ {VT_R8, -1, PARAMFLAG_NONE}, /* ret */
+ { /* params */
+ {-1, 0, 0}
+ },
+ { /* names */
+ "test_int_retval",
+ NULL,
+ },
+ },
+ {
+ /*id*/ 0x7, /*func*/ FUNC_DISPATCH, /*inv*/ INVOKE_FUNC, /*call*/ CC_STDCALL,
+ /*#param*/ 1, /*#opt*/ 0, /*vtbl*/ 13, /*#scodes*/ 0, /*flags*/ 0,
+ {VT_R8, -1, PARAMFLAG_NONE}, /* ret */
+ { /* params */
+ {VT_BSTR, -1, PARAMFLAG_FIN},
+ {-1, 0, 0}
+ },
+ { /* names */
+ "parse_lcid",
+ "x",
+ NULL,
+ },
+ },
+ },
+ { /* vars */ },
}
};
diff --git a/dlls/oleaut32/typelib.c b/dlls/oleaut32/typelib.c
index 06667850a3..2f7ce53b1c 100644
--- a/dlls/oleaut32/typelib.c
+++ b/dlls/oleaut32/typelib.c
@@ -2465,7 +2465,11 @@ MSFT_DoFuncs(TLBContext* pcx,
ptfd->funcdesc.callconv = (pFuncRec->FKCCIC) >> 8 & 0xF;
ptfd->funcdesc.cParams = pFuncRec->nrargs ;
ptfd->funcdesc.cParamsOpt = pFuncRec->nroargs ;
- ptfd->funcdesc.oVft = (pFuncRec->VtableOffset & ~1) * sizeof(void *) / pTI->pTypeLib->ptr_size;
+ if(ptfd->funcdesc.funckind == FUNC_DISPATCH) {
+ ptfd->funcdesc.oVft = 0;
+ } else {
+ ptfd->funcdesc.oVft = (pFuncRec->VtableOffset & ~1) * sizeof(void *) / pTI->pTypeLib->ptr_size;
+ }
ptfd->funcdesc.wFuncFlags = LOWORD(pFuncRec->Flags) ;
/* nameoffset is sometimes -1 on the second half of a propget/propput
@@ -4179,7 +4183,11 @@ static void SLTG_DoFuncs(char *pBlk, char *pFirstItem, ITypeInfoImpl *pTI,
pFuncDesc->funcdesc.callconv = pFunc->nacc & 0x7;
pFuncDesc->funcdesc.cParams = pFunc->nacc >> 3;
pFuncDesc->funcdesc.cParamsOpt = (pFunc->retnextopt & 0x7e) >> 1;
- pFuncDesc->funcdesc.oVft = (pFunc->vtblpos & ~1) * sizeof(void *) / pTI->pTypeLib->ptr_size;
+ if (pFuncDesc->funcdesc.funckind == FUNC_DISPATCH) {
+ pFuncDesc->funcdesc.oVft = 0;
+ } else {
+ pFuncDesc->funcdesc.oVft = (pFunc->vtblpos & ~1) * sizeof(void *) / pTI->pTypeLib->ptr_size;
+ }
if(pFunc->magic & SLTG_FUNCTION_FLAGS_PRESENT)
pFuncDesc->funcdesc.wFuncFlags = pFunc->funcflags;
@@ -5849,11 +5857,13 @@ static HRESULT TLB_AllocAndInitFuncDesc( const FUNCDESC *src, FUNCDESC **dest_pt
} else
dest->lprgelemdescParam = NULL;
- /* special treatment for dispinterfaces: this makes functions appear
- * to return their [retval] value when it is really returning an
- * HRESULT */
- if (dispinterface && dest->elemdescFunc.tdesc.vt == VT_HRESULT)
+ /* special treatment for dispinterface FUNCDESC based on an interface FUNCDESC.
+ * This accounts for several arguments that are seperate in the signature of
+ * IDispatch::Invoke, rather than passed in DISPPARAMS::rgvarg[] */
+ if (dispinterface && (src->funckind != FUNC_DISPATCH))
{
+ /* functions that have a [retval] parameter return this value into pVarResult.
+ * [retval] is always the last parameter (if present) */
if (dest->cParams &&
(dest->lprgelemdescParam[dest->cParams - 1].u.paramdesc.wParamFlags & PARAMFLAG_FRETVAL))
{
@@ -5866,19 +5876,28 @@ static HRESULT TLB_AllocAndInitFuncDesc( const FUNCDESC *src, FUNCDESC **dest_pt
return E_UNEXPECTED;
}
- /* copy last parameter to the return value. we are using a flat
- * buffer so there is no danger of leaking memory in
- * elemdescFunc */
+ /* the type pointed to by this [retval] becomes elemdescFunc,
+ * i.e. functions signature's return type (replacing HRESULT/void/anything else)
+ * We are using a flat buffer so there is no danger of leaking memory */
dest->elemdescFunc.tdesc = *elemdesc->tdesc.u.lptdesc;
/* remove the last parameter */
dest->cParams--;
}
- else
- /* otherwise this function is made to appear to have no return
- * value */
+ else if (dest->elemdescFunc.tdesc.vt == VT_HRESULT)
+ /* Even if not otherwise replaced (by [retval],
+ * HRESULT is returned in pExcepInfo->scode, not pVarResult.
+ * So the function signature should show no return value. */
dest->elemdescFunc.tdesc.vt = VT_VOID;
+ /* The now-last (except [retval], removed above) parameter might be labeled [lcid].
+ * If so it will be supplied from Invoke(lcid), so also not via DISPPARAMS::rgvarg */
+ if (dest->cParams &&
+ (dest->lprgelemdescParam[dest->cParams - 1].u.paramdesc.wParamFlags & PARAMFLAG_FLCID))
+ {
+ /* remove the last parameter */
+ dest->cParams--;
+ }
}
*dest_ptr = dest;
@@ -6105,36 +6124,38 @@ static HRESULT WINAPI ITypeInfo_fnGetVarDesc( ITypeInfo2 *iface, UINT index,
return TLB_AllocAndInitVarDesc(&pVDesc->vardesc, ppVarDesc);
}
-/* ITypeInfo_GetNames
- *
- * Retrieves the variable with the specified member ID (or the name of the
- * property or method and its parameters) that correspond to the specified
- * function ID.
- */
-static HRESULT WINAPI ITypeInfo_fnGetNames( ITypeInfo2 *iface, MEMBERID memid,
- BSTR *rgBstrNames, UINT cMaxNames, UINT *pcNames)
+/* internal function to make the inherited interfaces' methods appear
+ * part of the interface, remembering if the top-level was dispinterface */
+static HRESULT ITypeInfoImpl_GetNames( ITypeInfo *iface,
+ MEMBERID memid, BSTR *rgBstrNames, UINT cMaxNames, UINT *pcNames,
+ BOOL dispinterface)
{
- ITypeInfoImpl *This = impl_from_ITypeInfo2(iface);
+ ITypeInfoImpl *This = impl_from_ITypeInfo(iface);
const TLBFuncDesc *pFDesc;
const TLBVarDesc *pVDesc;
int i;
- TRACE("(%p) memid=0x%08x Maxname=%d\n", This, memid, cMaxNames);
-
- if(!rgBstrNames)
- return E_INVALIDARG;
*pcNames = 0;
pFDesc = TLB_get_funcdesc_by_memberid(This, memid);
if(pFDesc)
{
+ UINT cParams = pFDesc->funcdesc.cParams;
if(!cMaxNames || !pFDesc->Name)
return S_OK;
*rgBstrNames = SysAllocString(TLB_get_bstr(pFDesc->Name));
++(*pcNames);
- for(i = 0; i < pFDesc->funcdesc.cParams; ++i){
+ if(dispinterface && (pFDesc->funcdesc.funckind != FUNC_DISPATCH)) {
+ /* match the rewriting of special trailing parameters in TLB_AllocAndInitFuncDesc; */
+ if ((cParams > 0) && (pFDesc->funcdesc.lprgelemdescParam[cParams - 1].u.paramdesc.wParamFlags & PARAMFLAG_FRETVAL))
+ --cParams; /* Invoke(pVarResult) supplies the [retval] parameter, so its hidden from DISPPARAMS*/
+ if ((cParams > 0) && (pFDesc->funcdesc.lprgelemdescParam[cParams - 1].u.paramdesc.wParamFlags & PARAMFLAG_FLCID))
+ --cParams; /* Invoke(lcid) supplies the [lcid] parameter, so its hidden from DISPPARAMS */
+ }
+
+ for(i = 0; i < cParams; ++i) {
if(*pcNames >= cMaxNames || !pFDesc->pParamDesc[i].Name)
return S_OK;
rgBstrNames[*pcNames] = SysAllocString(TLB_get_bstr(pFDesc->pParamDesc[i].Name));
@@ -6156,10 +6177,10 @@ static HRESULT WINAPI ITypeInfo_fnGetNames( ITypeInfo2 *iface, MEMBERID memid,
/* recursive search */
ITypeInfo *pTInfo;
HRESULT result;
- result = ITypeInfo2_GetRefTypeInfo(iface, This->impltypes[0].hRef, &pTInfo);
+ result = ITypeInfo_GetRefTypeInfo(iface, This->impltypes[0].hRef, &pTInfo);
if(SUCCEEDED(result))
{
- result=ITypeInfo_GetNames(pTInfo, memid, rgBstrNames, cMaxNames, pcNames);
+ result=ITypeInfoImpl_GetNames(pTInfo, memid, rgBstrNames, cMaxNames, pcNames, dispinterface);
ITypeInfo_Release(pTInfo);
return result;
}
@@ -6175,6 +6196,25 @@ static HRESULT WINAPI ITypeInfo_fnGetNames( ITypeInfo2 *iface, MEMBERID memid,
return S_OK;
}
+/* ITypeInfo_GetNames
+ *
+ * Retrieves the variable with the specified member ID (or the name of the
+ * property or method and its parameters) that correspond to the specified
+ * function ID.
+ */
+static HRESULT WINAPI ITypeInfo_fnGetNames( ITypeInfo2 *iface, MEMBERID memid,
+ BSTR *rgBstrNames, UINT cMaxNames, UINT *pcNames)
+{
+ ITypeInfoImpl *This = impl_from_ITypeInfo2(iface);
+ TRACE("(%p) memid=0x%08x Maxname=%d\n", This, memid, cMaxNames);
+
+ if(!rgBstrNames)
+ return E_INVALIDARG;
+
+ return ITypeInfoImpl_GetNames((ITypeInfo *)iface,
+ memid, rgBstrNames, cMaxNames, pcNames,
+ This->typeattr.typekind == TKIND_DISPATCH);
+}
/* ITypeInfo::GetRefTypeOfImplType
*
More information about the wine-devel
mailing list