Don't trash the dst variant if we can't do the type conversion.
Add a test for this.

diff --git a/dlls/oleaut32/tests/vartype.c b/dlls/oleaut32/tests/vartype.c
index 3f48c90..f9224c7 100644
--- a/dlls/oleaut32/tests/vartype.c
+++ b/dlls/oleaut32/tests/vartype.c
@@ -5304,6 +5304,30 @@
   ok(hRes == DISP_E_BADVARTYPE, "VariantChangeTypeEx should return DISP_E_BADVARTYPE\n");
 }
 
+/* Dst Variant should remain unchanged if VariantChangeType cannot convert */
+static void test_ChangeType_keep_dst()
+{
+     VARIANT v1, v2;
+     BSTR bstr;
+     WCHAR testW[] = {'t','e','s','t',0};
+     HRESULT hres;
+
+     bstr = SysAllocString(testW);
+     VariantClear(&v1);
+     VariantClear(&v2);
+     V_VT(&v1) = VT_BSTR;
+     V_BSTR(&v1) = bstr;
+     hres = VariantChangeTypeEx(&v1, &v1, 0, 0, VT_INT);
+     ok(hres == DISP_E_TYPEMISMATCH, "VariantChangeTypeEx returns %08lx\n", hres);
+     ok(V_VT(&v1) == VT_BSTR && V_BSTR(&v1) == bstr, "VariantChangeTypeEx changed dst variant\n");
+     V_VT(&v2) = VT_INT;
+     V_INT(&v2) = 4;
+     hres = VariantChangeTypeEx(&v2, &v1, 0, 0, VT_INT);
+     ok(hres == DISP_E_TYPEMISMATCH, "VariantChangeTypeEx returns %08lx\n", hres);
+     ok(V_VT(&v2) == VT_INT && V_INT(&v2) == 4, "VariantChangeTypeEx changed dst variant\n");     
+     SysFreeString(bstr);
+}
+
 START_TEST(vartype)
 {
   hOleaut32 = LoadLibraryA("oleaut32.dll");
@@ -5594,4 +5618,5 @@
   test_ClearCustData();
 
   test_NullByRef();
+  test_ChangeType_keep_dst();
 }
diff --git a/dlls/oleaut32/variant.c b/dlls/oleaut32/variant.c
index 61e8e76..da16f98 100644
--- a/dlls/oleaut32/variant.c
+++ b/dlls/oleaut32/variant.c
@@ -982,31 +982,35 @@
 
       if (SUCCEEDED(res))
       {
-        VARIANTARG vTmp;
+        VARIANTARG vTmp, vSrcDeref;
 
         if(V_VT(pvargSrc)&VT_BYREF && !V_BYREF(pvargSrc))
           res = DISP_E_TYPEMISMATCH;
         else
         {
           V_VT(&vTmp) = VT_EMPTY;
-          res = VariantCopyInd(&vTmp, pvargSrc);
+          V_VT(&vSrcDeref) = VT_EMPTY;
+          VariantClear(&vTmp);
+          VariantClear(&vSrcDeref);
         }
 
         if (SUCCEEDED(res))
         {
-          res = VariantClear(pvargDest);
-
+          res = VariantCopyInd(&vSrcDeref, pvargSrc);
           if (SUCCEEDED(res))
           {
-            if (V_ISARRAY(&vTmp) || (vt & VT_ARRAY))
-              res = VARIANT_CoerceArray(pvargDest, &vTmp, vt);
+            if (V_ISARRAY(&vSrcDeref) || (vt & VT_ARRAY))
+              res = VARIANT_CoerceArray(&vTmp, &vSrcDeref, vt);
             else
-              res = VARIANT_Coerce(pvargDest, lcid, wFlags, &vTmp, vt);
+              res = VARIANT_Coerce(&vTmp, lcid, wFlags, &vSrcDeref, vt);
 
-            if (SUCCEEDED(res))
-              V_VT(pvargDest) = vt;
+            if (SUCCEEDED(res)) {
+                V_VT(&vTmp) = vt;
+                VariantCopy(pvargDest, &vTmp);
+            }
+            VariantClear(&vTmp);
+            VariantClear(&vSrcDeref);
           }
-          VariantClear(&vTmp);
         }
       }
     }