Alistair Leslie-Hughes : oleaut32: Improve support for IDispatch in VarCat.

Alexandre Julliard julliard at winehq.org
Sun Mar 18 09:02:33 CDT 2018


Module: wine
Branch: oldstable
Commit: 2310d5a278341d7ea1ec1f65d7bce0b9276d0d34
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=2310d5a278341d7ea1ec1f65d7bce0b9276d0d34

Author: Alistair Leslie-Hughes <leslie_alistair at hotmail.com>
Date:   Tue Jun 13 22:35:06 2017 +0000

oleaut32: Improve support for IDispatch in VarCat.

Signed-off-by: Alistair Leslie-Hughes <leslie_alistair at hotmail.com>
Signed-off-by: Jacek Caban <jacek at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
(cherry picked from commit 538e46adea88a3d6bdadd7f762eb620cd11cbeef)
Signed-off-by: Michael Stefaniuc <mstefani at winehq.org>

---

 dlls/oleaut32/tests/vartest.c |  20 ++++++--
 dlls/oleaut32/variant.c       | 103 ++++++++++++++++++++++++------------------
 2 files changed, 76 insertions(+), 47 deletions(-)

diff --git a/dlls/oleaut32/tests/vartest.c b/dlls/oleaut32/tests/vartest.c
index a271c50..d8a6ebf 100644
--- a/dlls/oleaut32/tests/vartest.c
+++ b/dlls/oleaut32/tests/vartest.c
@@ -6093,7 +6093,7 @@ static void test_VarCat(void)
 
     SET_EXPECT(dispatch_invoke);
     hres = VarCat(&left, &right, &result);
-    todo_wine ok(hres == S_OK, "got 0x%08x\n", hres);
+    ok(hres == S_OK, "got 0x%08x\n", hres);
     ok(V_VT(&result) == VT_BSTR, "got %d\n", V_VT(&result));
     ok(SysStringLen(V_BSTR(&result)) == 0, "got %d\n", SysStringLen(V_BSTR(&result)));
     CHECK_CALLED(dispatch_invoke);
@@ -6108,7 +6108,7 @@ static void test_VarCat(void)
 
     SET_EXPECT(dispatch_invoke);
     hres = VarCat(&left, &right, &result);
-    todo_wine ok(hres == S_OK, "got 0x%08x\n", hres);
+    ok(hres == S_OK, "got 0x%08x\n", hres);
     ok(V_VT(&result) == VT_BSTR, "got %d\n", V_VT(&result));
     ok(SysStringLen(V_BSTR(&result)) == 0, "got %d\n", SysStringLen(V_BSTR(&result)));
     CHECK_CALLED(dispatch_invoke);
@@ -6140,7 +6140,21 @@ static void test_VarCat(void)
 
     SET_EXPECT(dispatch_invoke);
     hres = VarCat(&left, &right, &result);
-    todo_wine ok(hres == E_OUTOFMEMORY, "got 0x%08x\n", hres);
+    ok(hres == E_OUTOFMEMORY, "got 0x%08x\n", hres);
+    CHECK_CALLED(dispatch_invoke);
+
+    VariantClear(&left);
+    VariantClear(&right);
+    VariantClear(&result);
+
+    init_test_dispatch(VT_NULL, &dispatch);
+    dispatch.result = DISP_E_TYPEMISMATCH;
+    V_VT(&right) = VT_DISPATCH;
+    V_DISPATCH(&right) = &dispatch.IDispatch_iface;
+
+    SET_EXPECT(dispatch_invoke);
+    hres = VarCat(&left, &right, &result);
+    ok(hres == DISP_E_TYPEMISMATCH, "got 0x%08x\n", hres);
     CHECK_CALLED(dispatch_invoke);
 
     VariantClear(&left);
diff --git a/dlls/oleaut32/variant.c b/dlls/oleaut32/variant.c
index 2dcded5..ee203d7 100644
--- a/dlls/oleaut32/variant.c
+++ b/dlls/oleaut32/variant.c
@@ -515,6 +515,22 @@ static inline HRESULT VARIANT_CoerceArray(VARIANTARG* pd, VARIANTARG* ps, VARTYP
   return DISP_E_TYPEMISMATCH;
 }
 
+static HRESULT VARIANT_FetchDispatchValue(LPVARIANT pvDispatch, LPVARIANT pValue)
+{
+    HRESULT hres;
+    static DISPPARAMS emptyParams = { NULL, NULL, 0, 0 };
+
+    if ((V_VT(pvDispatch) & VT_TYPEMASK) == VT_DISPATCH) {
+        if (NULL == V_DISPATCH(pvDispatch)) return DISP_E_TYPEMISMATCH;
+        hres = IDispatch_Invoke(V_DISPATCH(pvDispatch), DISPID_VALUE, &IID_NULL,
+            LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET, &emptyParams, pValue,
+            NULL, NULL);
+    } else {
+        hres = DISP_E_TYPEMISMATCH;
+    }
+    return hres;
+}
+
 /******************************************************************************
  * Check if a variants type is valid.
  */
@@ -2503,7 +2519,7 @@ HRESULT WINAPI VarCat(LPVARIANT left, LPVARIANT right, LPVARIANT out)
 {
     VARTYPE leftvt,rightvt,resultvt;
     HRESULT hres;
-    static const WCHAR sz_empty[] = {'\0'};
+
     leftvt = V_VT(left);
     rightvt = V_VT(right);
 
@@ -2581,64 +2597,79 @@ HRESULT WINAPI VarCat(LPVARIANT left, LPVARIANT right, LPVARIANT out)
     else
     {
         VARIANT bstrvar_left, bstrvar_right;
+        VARIANT *tmp;
+        VARIANT fetched;
+
         V_VT(out) = VT_BSTR;
 
         VariantInit(&bstrvar_left);
         VariantInit(&bstrvar_right);
+        VariantInit(&fetched);
 
         /* Convert left side variant to string */
         if (leftvt != VT_BSTR)
         {
-            /* Fill with empty string for later concat with right side */
-            if (leftvt == VT_NULL)
+            tmp = left;
+
+            if(leftvt == VT_DISPATCH)
             {
-                V_VT(&bstrvar_left) = VT_BSTR;
-                V_BSTR(&bstrvar_left) = SysAllocString(sz_empty);
+                hres = VARIANT_FetchDispatchValue(left, &fetched);
+                if(FAILED(hres))
+                    goto failed;
+
+                tmp = &fetched;
             }
-            else
+
+            hres = VariantChangeTypeEx(&bstrvar_left,tmp,0,VARIANT_ALPHABOOL|VARIANT_LOCALBOOL,VT_BSTR);
+            VariantClear(&fetched);
+            if (hres == DISP_E_TYPEMISMATCH)
             {
-                hres = VariantChangeTypeEx(&bstrvar_left,left,0,VARIANT_ALPHABOOL|VARIANT_LOCALBOOL,VT_BSTR);
-                if (hres != S_OK) {
-                    VariantClear(&bstrvar_left);
-                    VariantClear(&bstrvar_right);
-                    return hres;
-                }
+                V_VT(&bstrvar_left) = VT_BSTR;
+                V_BSTR(&bstrvar_left) = SysAllocStringLen(NULL, 0);
             }
+            else if(hres != S_OK)
+                goto failed;
         }
 
         /* convert right side variant to string */
         if (rightvt != VT_BSTR)
         {
-            /* Fill with empty string for later concat with right side */
-            if (rightvt == VT_NULL)
+            tmp = right;
+
+            if(rightvt == VT_DISPATCH)
             {
-                V_VT(&bstrvar_right) = VT_BSTR;
-                V_BSTR(&bstrvar_right) = SysAllocString(sz_empty);
+                hres = VARIANT_FetchDispatchValue(right, &fetched);
+                if(FAILED(hres))
+                    goto failed;
+
+                tmp = &fetched;
             }
-            else
+
+            hres = VariantChangeTypeEx(&bstrvar_right,tmp,0,VARIANT_ALPHABOOL|VARIANT_LOCALBOOL,VT_BSTR);
+            VariantClear(&fetched);
+            if (hres == DISP_E_TYPEMISMATCH)
             {
-                hres = VariantChangeTypeEx(&bstrvar_right,right,0,VARIANT_ALPHABOOL|VARIANT_LOCALBOOL,VT_BSTR);
-                if (hres != S_OK) {
-                    VariantClear(&bstrvar_left);
-                    VariantClear(&bstrvar_right);
-                    return hres;
-                }
+                V_VT(&bstrvar_right) = VT_BSTR;
+                V_BSTR(&bstrvar_right) = SysAllocStringLen(NULL, 0);
             }
+            else if(hres != S_OK)
+                goto failed;
         }
 
         /* Concat the resulting strings together */
         if (leftvt == VT_BSTR && rightvt == VT_BSTR)
-            VarBstrCat (V_BSTR(left), V_BSTR(right), &V_BSTR(out));
+            hres = VarBstrCat (V_BSTR(left), V_BSTR(right), &V_BSTR(out));
         else if (leftvt != VT_BSTR && rightvt != VT_BSTR)
-            VarBstrCat (V_BSTR(&bstrvar_left), V_BSTR(&bstrvar_right), &V_BSTR(out));
+            hres = VarBstrCat (V_BSTR(&bstrvar_left), V_BSTR(&bstrvar_right), &V_BSTR(out));
         else if (leftvt != VT_BSTR && rightvt == VT_BSTR)
-            VarBstrCat (V_BSTR(&bstrvar_left), V_BSTR(right), &V_BSTR(out));
+            hres = VarBstrCat (V_BSTR(&bstrvar_left), V_BSTR(right), &V_BSTR(out));
         else if (leftvt == VT_BSTR && rightvt != VT_BSTR)
-            VarBstrCat (V_BSTR(left), V_BSTR(&bstrvar_right), &V_BSTR(out));
+            hres = VarBstrCat (V_BSTR(left), V_BSTR(&bstrvar_right), &V_BSTR(out));
 
+failed:
         VariantClear(&bstrvar_left);
         VariantClear(&bstrvar_right);
-        return S_OK;
+        return hres;
     }
 }
 
@@ -2865,22 +2896,6 @@ HRESULT WINAPI VarCmp(LPVARIANT left, LPVARIANT right, LCID lcid, DWORD flags)
 #undef _VARCMP
 }
 
-static HRESULT VARIANT_FetchDispatchValue(LPVARIANT pvDispatch, LPVARIANT pValue)
-{
-    HRESULT hres;
-    static DISPPARAMS emptyParams = { NULL, NULL, 0, 0 };
-
-    if ((V_VT(pvDispatch) & VT_TYPEMASK) == VT_DISPATCH) {
-        if (NULL == V_DISPATCH(pvDispatch)) return DISP_E_TYPEMISMATCH;
-        hres = IDispatch_Invoke(V_DISPATCH(pvDispatch), DISPID_VALUE, &IID_NULL,
-            LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET, &emptyParams, pValue,
-            NULL, NULL);
-    } else {
-        hres = DISP_E_TYPEMISMATCH;
-    }
-    return hres;
-}
-
 /**********************************************************************
  *              VarAnd [OLEAUT32.142]
  *




More information about the wine-cvs mailing list