Alex Villacís Lasso : oleaut32: Support for VT_DISPATCH in VarSub.

Alexandre Julliard julliard at wine.codeweavers.com
Wed Jan 3 05:37:36 CST 2007


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

Author: Alex Villacís Lasso <a_villacis at palosanto.com>
Date:   Tue Jan  2 18:52:11 2007 -0500

oleaut32: Support for VT_DISPATCH in VarSub.

---

 dlls/oleaut32/variant.c |  130 ++++++++++++++++++++++++++++++++++++----------
 1 files changed, 101 insertions(+), 29 deletions(-)

diff --git a/dlls/oleaut32/variant.c b/dlls/oleaut32/variant.c
index 60af75d..7a7909e 100644
--- a/dlls/oleaut32/variant.c
+++ b/dlls/oleaut32/variant.c
@@ -3690,17 +3690,80 @@ HRESULT WINAPI VarSub(LPVARIANT left, LP
     VARTYPE leftvt,rightvt;
     VARTYPE rightExtraFlags,leftExtraFlags,ExtraFlags;
     VARIANT lv,rv;
+    VARIANT tempLeft, tempRight;
+
+    VariantInit(&lv);
+    VariantInit(&rv);
+    VariantInit(&tempLeft);
+    VariantInit(&tempRight);
 
     TRACE("(%p->(%s%s),%p->(%s%s),%p)\n", left, debugstr_VT(left),
           debugstr_VF(left), right, debugstr_VT(right), debugstr_VF(right), result);
 
+    if ((V_VT(left) & VT_TYPEMASK) == VT_DISPATCH &&
+        (V_VT(left)&(~VT_TYPEMASK)) == 0 &&
+        (V_VT(right) & VT_TYPEMASK) != VT_NULL)
+    {
+        if (NULL == V_DISPATCH(left)) {
+            if ((V_VT(right) & VT_TYPEMASK) >= VT_INT_PTR)
+                hres = DISP_E_BADVARTYPE;
+            else if ((V_VT(right) & VT_TYPEMASK) >= VT_UI8 &&
+                (V_VT(right) & VT_TYPEMASK) < VT_RECORD)
+                hres = DISP_E_BADVARTYPE;
+            else switch (V_VT(right) & VT_TYPEMASK)
+            {
+            case VT_VARIANT:
+            case VT_UNKNOWN:
+            case 15:
+            case VT_I1:
+            case VT_UI2:
+            case VT_UI4:
+                hres = DISP_E_BADVARTYPE;
+            }
+            if (FAILED(hres)) goto end;
+        }
+        hres = VARIANT_FetchDispatchValue(left, &tempLeft);
+        if (FAILED(hres)) goto end;
+        left = &tempLeft;
+    }
+    if ((V_VT(right) & VT_TYPEMASK) == VT_DISPATCH &&
+        (V_VT(right)&(~VT_TYPEMASK)) == 0 &&
+        (V_VT(left) & VT_TYPEMASK) != VT_NULL)
+    {
+        if (NULL == V_DISPATCH(right))
+        {
+            if ((V_VT(left) & VT_TYPEMASK) >= VT_INT_PTR)
+                hres = DISP_E_BADVARTYPE;
+            else if ((V_VT(left) & VT_TYPEMASK) >= VT_UI8 &&
+                (V_VT(left) & VT_TYPEMASK) < VT_RECORD)
+                hres = DISP_E_BADVARTYPE;
+            else switch (V_VT(left) & VT_TYPEMASK)
+            {
+            case VT_VARIANT:
+            case VT_UNKNOWN:
+            case 15:
+            case VT_I1:
+            case VT_UI2:
+            case VT_UI4:
+                hres = DISP_E_BADVARTYPE;
+            }
+            if (FAILED(hres)) goto end;
+        }
+        hres = VARIANT_FetchDispatchValue(right, &tempRight);
+        if (FAILED(hres)) goto end;
+        right = &tempRight;
+    }
+
     leftvt = V_VT(left)&VT_TYPEMASK;
     rightvt = V_VT(right)&VT_TYPEMASK;
     leftExtraFlags = V_VT(left)&(~VT_TYPEMASK);
     rightExtraFlags = V_VT(right)&(~VT_TYPEMASK);
 
     if (leftExtraFlags != rightExtraFlags)
-        return DISP_E_BADVARTYPE;
+    {
+        hres = DISP_E_BADVARTYPE;
+        goto end;
+    }
     ExtraFlags = leftExtraFlags;
 
     /* determine return type and return code */
@@ -3712,9 +3775,15 @@ HRESULT WINAPI VarSub(LPVARIANT left, LP
         ExtraFlags == VT_VECTOR ||
         ExtraFlags == VT_BYREF ||
         ExtraFlags == VT_RESERVED)
-        return DISP_E_BADVARTYPE;
+    {
+        hres = DISP_E_BADVARTYPE;
+        goto end;
+    }
     else if (ExtraFlags >= VT_ARRAY)
-        return DISP_E_TYPEMISMATCH;
+    {
+        hres = DISP_E_TYPEMISMATCH;
+        goto end;
+    }
     /* Native VarSub cannot handle: VT_I1, VT_UI2, VT_UI4,
        VT_INT, VT_UINT and VT_UI8. Tested with WinXP */
     else if (leftvt == VT_CLSID || rightvt == VT_CLSID ||
@@ -3729,34 +3798,44 @@ HRESULT WINAPI VarSub(LPVARIANT left, LP
         leftvt == VT_RECORD || rightvt == VT_RECORD)
     {
         if (leftvt == VT_RECORD && rightvt == VT_I8)
-            return DISP_E_TYPEMISMATCH;
+            hres = DISP_E_TYPEMISMATCH;
         else if (leftvt < VT_UI1 && rightvt == VT_RECORD)
-            return DISP_E_TYPEMISMATCH;
+            hres = DISP_E_TYPEMISMATCH;
         else if (leftvt >= VT_UI1 && rightvt == VT_RECORD)
-            return DISP_E_TYPEMISMATCH;
+            hres = DISP_E_TYPEMISMATCH;
         else if (leftvt == VT_RECORD && rightvt <= VT_UI1)
-            return DISP_E_TYPEMISMATCH;
+            hres = DISP_E_TYPEMISMATCH;
         else if (leftvt == VT_RECORD && rightvt > VT_UI1)
-            return DISP_E_BADVARTYPE;
+            hres = DISP_E_BADVARTYPE;
         else
-            return DISP_E_BADVARTYPE;
+            hres = DISP_E_BADVARTYPE;
+        goto end;
     }
     /*  The following flags/types are invalid for left variant */
     else if (!((leftvt <= VT_LPWSTR || leftvt == VT_RECORD ||
         leftvt == VT_CLSID) && leftvt != (VARTYPE)15 /* undefined vt */ &&
         (leftvt < VT_VOID || leftvt > VT_LPWSTR)))
-        return DISP_E_BADVARTYPE;
+    {
+        hres = DISP_E_BADVARTYPE;
+        goto end;
+    }
     /*  The following flags/types are invalid for right variant */
     else if (!((rightvt <= VT_LPWSTR || rightvt == VT_RECORD ||
         rightvt == VT_CLSID) && rightvt != (VARTYPE)15 /* undefined vt */ &&
         (rightvt < VT_VOID || rightvt > VT_LPWSTR)))
-        return DISP_E_BADVARTYPE;
+    {
+        hres = DISP_E_BADVARTYPE;
+        goto end;
+    }
     else if ((leftvt == VT_NULL && rightvt == VT_DISPATCH) ||
         (leftvt == VT_DISPATCH && rightvt == VT_NULL))
         resvt = VT_NULL;
     else if (leftvt == VT_DISPATCH || rightvt == VT_DISPATCH ||
         leftvt == VT_ERROR || rightvt == VT_ERROR)
-        return DISP_E_TYPEMISMATCH;
+    {
+        hres = DISP_E_TYPEMISMATCH;
+        goto end;
+    }
     else if (leftvt == VT_NULL || rightvt == VT_NULL)
         resvt = VT_NULL;
     else if ((leftvt == VT_EMPTY && rightvt == VT_BSTR) ||
@@ -3793,32 +3872,22 @@ HRESULT WINAPI VarSub(LPVARIANT left, LP
     else if (leftvt == VT_UI1 || rightvt == VT_UI1)
         resvt = VT_UI1;
     else
-        return DISP_E_TYPEMISMATCH;
-
-    VariantInit(&lv);
-    VariantInit(&rv);
+    {
+        hres = DISP_E_TYPEMISMATCH;
+        goto end;
+    }
 
     /* coerce to the result type */
     if (leftvt == VT_BSTR && rightvt == VT_DATE)
         hres = VariantChangeType(&lv, left, 0, VT_R8);
     else
         hres = VariantChangeType(&lv, left, 0, resvt);
-    if (hres != S_OK)
-    {
-        VariantClear(&lv);
-        VariantClear(&rv);
-        return hres;
-    }
+    if (hres != S_OK) goto end;
     if (leftvt == VT_DATE && rightvt == VT_BSTR)
         hres = VariantChangeType(&rv, right, 0, VT_R8);
     else
         hres = VariantChangeType(&rv, right, 0, resvt);
-    if (hres != S_OK)
-    {
-        VariantClear(&lv);
-        VariantClear(&rv);
-        return hres;
-    }
+    if (hres != S_OK) goto end;
 
     /* do the math */
     V_VT(result) = resvt;
@@ -3858,9 +3927,12 @@ HRESULT WINAPI VarSub(LPVARIANT left, LP
     break;
     }
 
+end:
     VariantClear(&lv);
     VariantClear(&rv);
-
+    VariantClear(&tempLeft);
+    VariantClear(&tempRight);
+    TRACE("returning 0x%8x (variant type %s)\n", hres, debugstr_VT(result));
     return hres;
 }
 




More information about the wine-cvs mailing list