Hi, With stricter checking on the copy argument loop for ITypeLib::Invoke we need some more VT_USERDEFINED <-> VT_DISPATCH converters. Some kind of InstallShield v6 installers do that. :/ Ciao, Marcus Changelog: Convert VT_DISPATCH variants into VT_USERDEFINED/TKIND_DISPATCH and TKIND_INTERFACE targets, Query IID_IDispatch if necessary. Index: dlls/oleaut32/typelib.c =================================================================== RCS file: /home/wine/wine/dlls/oleaut32/typelib.c,v retrieving revision 1.87 diff -u -u -r1.87 typelib.c --- dlls/oleaut32/typelib.c 7 Jan 2003 20:36:24 -0000 1.87 +++ dlls/oleaut32/typelib.c 10 Jan 2003 23:29:51 -0000 @@ -4241,10 +4241,33 @@ return hres; case TKIND_INTERFACE: - FIXME("TKIND_INTERFACE unhandled.\n"); + if (V_VT(arg) == VT_DISPATCH) { + IDispatch *disp; + if (IsEqualIID(&IID_IDispatch,&(tattr->guid))) { + memcpy(argpos, &V_UNION(arg,pdispVal), 4); + return S_OK; + } + hres=IUnknown_QueryInterface(V_UNION(arg,pdispVal),&IID_IDispatch,(LPVOID*)&disp); + if (SUCCEEDED(hres)) { + memcpy(argpos,&disp,4); + IUnknown_Release(V_UNION(arg,pdispVal)); + return S_OK; + } + FIXME("Failed to query IDispatch interface from %s while converting to VT_DISPATCH!\n",debugstr_guid(&(tattr->guid))); + return E_FAIL; + } + if (V_VT(arg) == VT_UNKNOWN) { + memcpy(argpos, &V_UNION(arg,punkVal), 4); + return S_OK; + } + FIXME("vt 0x%x -> TKIND_INTERFACE(%s) unhandled\n",V_VT(arg),debugstr_guid(&(tattr->guid))); break; case TKIND_DISPATCH: - FIXME("TKIND_DISPATCH unhandled.\n"); + if (V_VT(arg) == VT_DISPATCH) { + memcpy(argpos, &V_UNION(arg,pdispVal), 4); + return S_OK; + } + FIXME("TKIND_DISPATCH unhandled for target vt 0x%x.\n",V_VT(arg)); break; case TKIND_RECORD: FIXME("TKIND_RECORD unhandled.\n");