Jacek Caban : vbscript: Added property invoke implementation.

Alexandre Julliard julliard at winehq.org
Fri Sep 16 13:28:32 CDT 2011


Module: wine
Branch: master
Commit: e843608748b3d6cfdc3af6aa6f577ab706f31c65
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=e843608748b3d6cfdc3af6aa6f577ab706f31c65

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Fri Sep 16 13:27:48 2011 +0200

vbscript: Added property invoke implementation.

---

 dlls/vbscript/tests/lang.vbs |   16 ++++++++++
 dlls/vbscript/tests/run.c    |   30 ++++++++++++++++++
 dlls/vbscript/vbdisp.c       |   68 ++++++++++++++++++++++++++++++++++++++++--
 dlls/vbscript/vbscript.h     |    1 +
 4 files changed, 112 insertions(+), 3 deletions(-)

diff --git a/dlls/vbscript/tests/lang.vbs b/dlls/vbscript/tests/lang.vbs
index 3f9f73e..e29a20f 100644
--- a/dlls/vbscript/tests/lang.vbs
+++ b/dlls/vbscript/tests/lang.vbs
@@ -404,6 +404,14 @@ Class TestClass
     Public Sub publicSub
     End Sub
 
+    Public Sub setPrivateProp(x)
+        privateProp = x
+    End Sub
+
+    Function getPrivateProp
+        getPrivateProp = privateProp
+    End Function
+
     Private Sub privateSub
     End Sub
 End Class
@@ -419,4 +427,12 @@ obj.publicSub()
 Call obj.publicSub
 Call obj.publicFunction()
 
+Call ok(getVT(obj.publicProp) = "VT_EMPTY", "getVT(obj.publicProp) = " & getVT(obj.publicProp))
+obj.publicProp = 3
+Call ok(obj.publicProp = 3, "obj.publicProp = " & obj.publicProp)
+obj.publicProp() = 3
+
+Call obj.setPrivateProp(6)
+Call ok(obj.getPrivateProp = 6, "obj.getPrivateProp = " & obj.getPrivateProp)
+
 reportSuccess()
diff --git a/dlls/vbscript/tests/run.c b/dlls/vbscript/tests/run.c
index 4fd46c9..f524b81 100644
--- a/dlls/vbscript/tests/run.c
+++ b/dlls/vbscript/tests/run.c
@@ -188,6 +188,36 @@ static void test_disp(IDispatch *disp)
     SysFreeString(str);
     ok(hres == S_OK, "GetDispID(publicProp2) failed: %08x\n", hres);
 
+    hres = IDispatchEx_InvokeEx(dispex, public_prop_id, 0, DISPATCH_PROPERTYGET|DISPATCH_METHOD, &dp, &v, &ei, NULL);
+    ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
+    ok(V_VT(&v) == VT_EMPTY, "V_VT(v) = %d\n", V_VT(&v));
+
+    V_VT(args) = VT_BOOL;
+    V_BOOL(args) = VARIANT_TRUE;
+    dp.cArgs = dp.cNamedArgs = 1;
+    V_VT(&v) = VT_BOOL;
+    hres = IDispatchEx_InvokeEx(dispex, public_prop_id, 0, DISPATCH_PROPERTYPUT, &dp, &v, &ei, NULL);
+    ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
+    ok(V_VT(&v) == VT_EMPTY, "V_VT(v) = %d\n", V_VT(&v));
+
+    dp.cArgs = dp.cNamedArgs = 0;
+    hres = IDispatchEx_InvokeEx(dispex, public_prop_id, 0, DISPATCH_PROPERTYGET|DISPATCH_METHOD, &dp, &v, &ei, NULL);
+   ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
+    ok(V_VT(&v) == VT_BOOL, "V_VT(v) = %d\n", V_VT(&v));
+    ok(V_BOOL(&v), "V_BOOL(v) = %x\n", V_BOOL(&v));
+
+    dp.cArgs = 1;
+    hres = IDispatchEx_InvokeEx(dispex, public_prop_id, 0, DISPATCH_PROPERTYGET|DISPATCH_METHOD, &dp, &v, &ei, NULL);
+    ok(hres == DISP_E_MEMBERNOTFOUND, "InvokeEx failed: %08x, expected DISP_E_MEMBERNOTFOUND\n", hres);
+    ok(V_VT(&v) == VT_EMPTY, "V_VT(v) = %d\n", V_VT(&v));
+
+    V_VT(args) = VT_BOOL;
+    V_BOOL(args) = VARIANT_FALSE;
+    dp.cArgs = 1;
+    V_VT(&v) = VT_BOOL;
+    hres = IDispatchEx_InvokeEx(dispex, public_prop_id, 0, DISPATCH_PROPERTYPUT, &dp, NULL, &ei, NULL);
+    ok(hres == DISP_E_PARAMNOTOPTIONAL, "InvokeEx failed: %08x, expected DISP_E_PARAMNOTOPTIONAL\n", hres);
+
     str = a2bstr("publicFunction");
     hres = IDispatchEx_GetDispID(dispex, str, fdexNameCaseInsensitive, &public_func_id);
     SysFreeString(str);
diff --git a/dlls/vbscript/vbdisp.c b/dlls/vbscript/vbdisp.c
index 2d0540f..e9bcb2a 100644
--- a/dlls/vbscript/vbdisp.c
+++ b/dlls/vbscript/vbdisp.c
@@ -67,6 +67,64 @@ HRESULT vbdisp_get_id(vbdisp_t *This, BSTR name, BOOL search_private, DISPID *id
     return DISP_E_UNKNOWNNAME;
 }
 
+static VARIANT *get_propput_arg(const DISPPARAMS *dp)
+{
+    unsigned i;
+
+    for(i=0; i < dp->cNamedArgs; i++) {
+        if(dp->rgdispidNamedArgs[i] == DISPID_PROPERTYPUT)
+            return dp->rgvarg+i;
+    }
+
+    return NULL;
+}
+
+static HRESULT invoke_variant_prop(vbdisp_t *This, VARIANT *v, WORD flags, DISPPARAMS *dp, VARIANT *res)
+{
+    HRESULT hres;
+
+    switch(flags) {
+    case DISPATCH_PROPERTYGET|DISPATCH_METHOD:
+        if(dp->cArgs) {
+            WARN("called with arguments\n");
+            return DISP_E_MEMBERNOTFOUND; /* That's what tests show */
+        }
+
+        hres = VariantCopy(res, v);
+        break;
+
+    case DISPATCH_PROPERTYPUT: {
+        VARIANT *put_val;
+
+        put_val = get_propput_arg(dp);
+        if(!put_val) {
+            WARN("no value to set\n");
+            return DISP_E_PARAMNOTOPTIONAL;
+        }
+
+        if(res)
+            V_VT(res) = VT_EMPTY;
+
+        hres = VariantCopy(v, put_val);
+        break;
+    }
+
+    default:
+        FIXME("unimplemented flags %x\n", flags);
+        return E_NOTIMPL;
+    }
+
+    return hres;
+}
+
+static void clean_props(vbdisp_t *This)
+{
+    unsigned i;
+
+    for(i=0; i < This->desc->prop_cnt; i++)
+        VariantClear(This->props+i);
+}
+
 static inline vbdisp_t *impl_from_IDispatchEx(IDispatchEx *iface)
 {
     return CONTAINING_RECORD(iface, vbdisp_t, IDispatchEx_iface);
@@ -110,8 +168,10 @@ static ULONG WINAPI DispatchEx_Release(IDispatchEx *iface)
     vbdisp_t *This = impl_from_IDispatchEx(iface);
     LONG ref = InterlockedIncrement(&This->ref);
 
-    if(!ref)
+    if(!ref) {
+        clean_props(This);
         heap_free(This);
+    }
 
     return ref;
 }
@@ -200,7 +260,9 @@ static HRESULT WINAPI DispatchEx_InvokeEx(IDispatchEx *iface, DISPID id, LCID lc
         }
     }
 
-    FIXME("not implemented for non-function ids\n");
+    if(id < This->desc->prop_cnt + This->desc->func_cnt)
+        return invoke_variant_prop(This, This->props+(id-This->desc->func_cnt), wFlags, pdp, pvarRes);
+
     return DISP_E_MEMBERNOTFOUND;
 }
 
@@ -275,7 +337,7 @@ HRESULT create_vbdisp(const class_desc_t *desc, vbdisp_t **ret)
 {
     vbdisp_t *vbdisp;
 
-    vbdisp = heap_alloc_zero(sizeof(*vbdisp));
+    vbdisp = heap_alloc_zero(sizeof(*vbdisp) + (desc->prop_cnt-1)*sizeof(VARIANT));
     if(!vbdisp)
         return E_OUTOFMEMORY;
 
diff --git a/dlls/vbscript/vbscript.h b/dlls/vbscript/vbscript.h
index d886a4e..ce1fa01 100644
--- a/dlls/vbscript/vbscript.h
+++ b/dlls/vbscript/vbscript.h
@@ -89,6 +89,7 @@ typedef struct {
     LONG ref;
 
     const class_desc_t *desc;
+    VARIANT props[1];
 } vbdisp_t;
 
 HRESULT create_vbdisp(const class_desc_t*,vbdisp_t**);




More information about the wine-cvs mailing list