Jacek Caban : mshtml: Support argument type conversion for functions with dual interface arguments.
Alexandre Julliard
julliard at winehq.org
Mon Apr 15 16:26:41 CDT 2019
Module: wine
Branch: master
Commit: 0a942e5d49908fe918e43d5ed0ae755c09e69a81
URL: https://source.winehq.org/git/wine.git/?a=commit;h=0a942e5d49908fe918e43d5ed0ae755c09e69a81
Author: Jacek Caban <jacek at codeweavers.com>
Date: Mon Apr 15 16:39:10 2019 +0200
mshtml: Support argument type conversion for functions with dual interface arguments.
Signed-off-by: Jacek Caban <jacek at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/mshtml/dispex.c | 46 +++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 45 insertions(+), 1 deletion(-)
diff --git a/dlls/mshtml/dispex.c b/dlls/mshtml/dispex.c
index 81a74b7..30b3580 100644
--- a/dlls/mshtml/dispex.c
+++ b/dlls/mshtml/dispex.c
@@ -49,6 +49,7 @@ static CRITICAL_SECTION cs_dispex_static_data = { &cs_dispex_static_data_dbg, -1
static const WCHAR objectW[] = {'[','o','b','j','e','c','t',']',0};
typedef struct {
+ IID iid;
VARIANT default_value;
} func_arg_info_t;
@@ -317,7 +318,31 @@ static void add_func_info(dispex_data_t *data, tid_t tid, const FUNCDESC *desc,
}
for(i=0; i < info->argc; i++) {
- if(!is_arg_type_supported(info->arg_types[i])) {
+ TYPEDESC *tdesc = &desc->lprgelemdescParam[i].tdesc;
+ if(tdesc->vt == VT_PTR && tdesc->u.lptdesc->vt == VT_USERDEFINED) {
+ ITypeInfo *ref_type_info;
+ TYPEATTR *attr;
+
+ hres = ITypeInfo_GetRefTypeInfo(dti, tdesc->u.lptdesc->u.hreftype, &ref_type_info);
+ if(FAILED(hres)) {
+ ERR("Coulg not get referenced type info: %08x\n", hres);
+ return;
+ }
+
+ hres = ITypeInfo_GetTypeAttr(ref_type_info, &attr);
+ if(SUCCEEDED(hres)) {
+ assert(attr->typekind == TKIND_DISPATCH);
+ info->arg_info[i].iid = attr->guid;
+ ITypeInfo_ReleaseTypeAttr(ref_type_info, attr);
+ }else {
+ ERR("GetTypeAttr failed: %08x\n", hres);
+ }
+ ITypeInfo_Release(ref_type_info);
+ if(FAILED(hres))
+ return;
+ info->arg_types[i] = VT_DISPATCH;
+ }else if(!is_arg_type_supported(info->arg_types[i])) {
+ TRACE("%s: unsupported arg type %s\n", debugstr_w(info->name), debugstr_vt(info->arg_types[i]));
return; /* Fallback to ITypeInfo for unsupported arg types */
}
@@ -1124,6 +1149,7 @@ static HRESULT invoke_builtin_function(DispatchEx *This, func_info_t *func, DISP
return hres;
for(i=0; i < func->argc; i++) {
+ BOOL own_value = FALSE;
if(i >= dp->cArgs) {
/* use default value */
arg_ptrs[i] = &func->arg_info[i].default_value;
@@ -1137,6 +1163,24 @@ static HRESULT invoke_builtin_function(DispatchEx *This, func_info_t *func, DISP
if(FAILED(hres))
break;
arg_ptrs[i] = arg_buf + nconv++;
+ own_value = TRUE;
+ }
+
+ if(func->arg_types[i] == VT_DISPATCH && !IsEqualGUID(&func->arg_info[i].iid, &IID_NULL)
+ && V_DISPATCH(arg_ptrs[i])) {
+ IDispatch *iface;
+ if(!own_value) {
+ arg_buf[nconv] = *arg_ptrs[i];
+ arg_ptrs[i] = arg_buf + nconv++;
+ }
+ hres = IDispatch_QueryInterface(V_DISPATCH(arg_ptrs[i]), &func->arg_info[i].iid, (void**)&iface);
+ if(FAILED(hres)) {
+ WARN("Could not get %s iface: %08x\n", debugstr_guid(&func->arg_info[i].iid), hres);
+ break;
+ }
+ if(own_value)
+ IDispatch_Release(V_DISPATCH(arg_ptrs[i]));
+ V_DISPATCH(arg_ptrs[i]) = iface;
}
}
More information about the wine-cvs
mailing list