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