[OLEAUT32]
authorAmine Khaldi <amine.khaldi@reactos.org>
Fri, 3 Oct 2014 17:10:15 +0000 (17:10 +0000)
committerAmine Khaldi <amine.khaldi@reactos.org>
Fri, 3 Oct 2014 17:10:15 +0000 (17:10 +0000)
* Sync with Wine 1.7.27.
CORE-8540

svn path=/trunk/; revision=64505

reactos/dll/win32/oleaut32/recinfo.c
reactos/dll/win32/oleaut32/tmarshal.c
reactos/dll/win32/oleaut32/typelib.c
reactos/dll/win32/oleaut32/varformat.c
reactos/dll/win32/oleaut32/variant.c
reactos/dll/win32/oleaut32/variant.h
reactos/dll/win32/oleaut32/vartype.c
reactos/media/doc/README.WINE

index f10755e..607cf6f 100644 (file)
@@ -166,7 +166,7 @@ static ULONG WINAPI IRecordInfoImpl_Release(IRecordInfo *iface)
         int i;
         for(i=0; i<This->n_vars; i++)
             SysFreeString(This->fields[i].name);
-        HeapFree(GetProcessHeap(), 0, This->name);
+        SysFreeString(This->name);
         HeapFree(GetProcessHeap(), 0, This->fields);
         ITypeInfo_Release(This->pTypeInfo);
         HeapFree(GetProcessHeap(), 0, This);
index 4064796..bef37bc 100644 (file)
@@ -248,11 +248,13 @@ static HRESULT
 _get_typeinfo_for_iid(REFIID riid, ITypeInfo**ti) {
     HRESULT    hres;
     HKEY       ikey;
+    REGSAM     opposite = (sizeof(void*) == 8) ? KEY_WOW64_32KEY : KEY_WOW64_64KEY;
+    BOOL       is_wow64;
     char       tlguid[200],typelibkey[300],interfacekey[300],ver[100];
     char       tlfn[260];
     OLECHAR    tlfnW[260];
     DWORD      tlguidlen, verlen, type;
-    LONG       tlfnlen;
+    LONG       tlfnlen, err;
     ITypeLib   *tl;
 
     sprintf( interfacekey, "Interface\\{%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}\\Typelib",
@@ -261,9 +263,14 @@ _get_typeinfo_for_iid(REFIID riid, ITypeInfo**ti) {
        riid->Data4[4], riid->Data4[5], riid->Data4[6], riid->Data4[7]
     );
 
-    if (RegOpenKeyA(HKEY_CLASSES_ROOT,interfacekey,&ikey)) {
-       ERR("No %s key found.\n",interfacekey);
-               return E_FAIL;
+    err = RegOpenKeyExA(HKEY_CLASSES_ROOT,interfacekey,0,KEY_READ,&ikey);
+    if (err && (opposite == KEY_WOW64_32KEY || (IsWow64Process(GetCurrentProcess(), &is_wow64)
+                                                && is_wow64))) {
+        err = RegOpenKeyExA(HKEY_CLASSES_ROOT,interfacekey,0,KEY_READ|opposite,&ikey);
+    }
+    if (err) {
+        ERR("No %s key found.\n",interfacekey);
+        return E_FAIL;
     }
     tlguidlen = sizeof(tlguid);
     if (RegQueryValueExA(ikey,NULL,NULL,&type,(LPBYTE)tlguid,&tlguidlen)) {
@@ -694,7 +701,7 @@ serialize_param(
            hres = xbuf_add(buf,(LPBYTE)arg,sizeof(DWORD));
        return hres;
     case VT_VARIANT: {
-        if (debugout) TRACE_(olerelay)("Vt(%s%s)(",debugstr_vt(V_VT((VARIANT *)arg)),debugstr_vf(V_VT((VARIANT *)arg)));
+        if (debugout) TRACE_(olerelay)("%s", debugstr_variant((VARIANT *)arg));
         if (writeit)
         {
             ULONG flags = MAKELONG(MSHCTX_DIFFERENTMACHINE, NDR_LOCAL_DATA_REPRESENTATION);
index 95d2986..0a91a20 100644 (file)
@@ -581,12 +581,17 @@ HRESULT WINAPI LoadRegTypeLib(
             TLIBATTR *attr;
 
             res = ITypeLib_GetLibAttr(*ppTLib, &attr);
-            if (res == S_OK && (attr->wMajorVerNum != wVerMajor || attr->wMinorVerNum < wVerMinor))
+            if (res == S_OK)
             {
+                BOOL mismatch = attr->wMajorVerNum != wVerMajor || attr->wMinorVerNum < wVerMinor;
                 ITypeLib_ReleaseTLibAttr(*ppTLib, attr);
-                ITypeLib_Release(*ppTLib);
-                *ppTLib = NULL;
-                res = TYPE_E_LIBNOTREGISTERED;
+
+                if (mismatch)
+                {
+                    ITypeLib_Release(*ppTLib);
+                    *ppTLib = NULL;
+                    res = TYPE_E_LIBNOTREGISTERED;
+                }
             }
         }
     }
@@ -872,6 +877,24 @@ HRESULT WINAPI RegisterTypeLib(
     return res;
 }
 
+static void TLB_unregister_interface(GUID *guid, REGSAM flag)
+{
+    WCHAR subKeyName[50];
+    HKEY subKey;
+
+    /* the path to the type */
+    get_interface_key( guid, subKeyName );
+
+    /* Delete its bits */
+    if (RegOpenKeyExW(HKEY_CLASSES_ROOT, subKeyName, 0, KEY_WRITE | flag, &subKey) != ERROR_SUCCESS)
+        return;
+
+    RegDeleteKeyW(subKey, ProxyStubClsidW);
+    RegDeleteKeyW(subKey, ProxyStubClsid32W);
+    RegDeleteKeyW(subKey, TypeLibW);
+    RegCloseKey(subKey);
+    RegDeleteKeyExW(HKEY_CLASSES_ROOT, subKeyName, flag, 0);
+}
 
 /******************************************************************************
  *     UnRegisterTypeLib       [OLEAUT32.186]
@@ -897,7 +920,6 @@ HRESULT WINAPI UnRegisterTypeLib(
     DWORD i = 0;
     BOOL deleteOtherStuff;
     HKEY key = NULL;
-    HKEY subKey = NULL;
     TYPEATTR* typeAttr = NULL;
     TYPEKIND kind;
     ITypeInfo* typeInfo = NULL;
@@ -956,19 +978,16 @@ HRESULT WINAPI UnRegisterTypeLib(
         if ((kind == TKIND_INTERFACE && (typeAttr->wTypeFlags & TYPEFLAG_FOLEAUTOMATION)) ||
             kind == TKIND_DISPATCH)
         {
-            /* the path to the type */
-            get_interface_key( &typeAttr->guid, subKeyName );
+            BOOL is_wow64;
+            REGSAM opposite = (sizeof(void*) == 8 ? KEY_WOW64_32KEY : KEY_WOW64_64KEY);
 
-            /* Delete its bits */
-            if (RegOpenKeyExW(HKEY_CLASSES_ROOT, subKeyName, 0, KEY_WRITE, &subKey) != ERROR_SUCCESS)
-                goto enddeleteloop;
+            TLB_unregister_interface(&typeAttr->guid, 0);
 
-            RegDeleteKeyW(subKey, ProxyStubClsidW);
-            RegDeleteKeyW(subKey, ProxyStubClsid32W);
-            RegDeleteKeyW(subKey, TypeLibW);
-            RegCloseKey(subKey);
-            subKey = NULL;
-            RegDeleteKeyW(HKEY_CLASSES_ROOT, subKeyName);
+            /* unregister TLBs into the opposite registry view, too */
+            if(opposite == KEY_WOW64_32KEY ||
+               (IsWow64Process(GetCurrentProcess(), &is_wow64) && is_wow64)) {
+                TLB_unregister_interface(&typeAttr->guid, opposite);
+            }
         }
 
 enddeleteloop:
@@ -1014,7 +1033,6 @@ enddeleteloop:
 end:
     SysFreeString(tlibPath);
     if (typeLib) ITypeLib_Release(typeLib);
-    if (subKey) RegCloseKey(subKey);
     if (key) RegCloseKey(key);
     return result;
 }
@@ -1571,61 +1589,6 @@ static void dump_TLBImplType(const TLBImplType * impl, UINT n)
     }
 }
 
-static void dump_Variant(const VARIANT * pvar)
-{
-    SYSTEMTIME st;
-
-    TRACE("%p->{%s%s", pvar, debugstr_VT(pvar), debugstr_VF(pvar));
-
-    if (pvar)
-    {
-      if (V_ISBYREF(pvar) || V_TYPE(pvar) == VT_UNKNOWN ||
-          V_TYPE(pvar) == VT_DISPATCH || V_TYPE(pvar) == VT_RECORD)
-      {
-        TRACE(",%p", V_BYREF(pvar));
-      }
-      else if (V_ISARRAY(pvar) || V_ISVECTOR(pvar))
-      {
-        TRACE(",%p", V_ARRAY(pvar));
-      }
-      else switch (V_TYPE(pvar))
-      {
-      case VT_I1:   TRACE(",%d", V_I1(pvar)); break;
-      case VT_UI1:  TRACE(",%d", V_UI1(pvar)); break;
-      case VT_I2:   TRACE(",%d", V_I2(pvar)); break;
-      case VT_UI2:  TRACE(",%d", V_UI2(pvar)); break;
-      case VT_INT:
-      case VT_I4:   TRACE(",%d", V_I4(pvar)); break;
-      case VT_UINT:
-      case VT_UI4:  TRACE(",%d", V_UI4(pvar)); break;
-      case VT_I8:   TRACE(",0x%08x,0x%08x", (ULONG)(V_I8(pvar) >> 32),
-                          (ULONG)(V_I8(pvar) & 0xffffffff)); break;
-      case VT_UI8:  TRACE(",0x%08x,0x%08x", (ULONG)(V_UI8(pvar) >> 32),
-                          (ULONG)(V_UI8(pvar) & 0xffffffff)); break;
-      case VT_R4:   TRACE(",%3.3e", V_R4(pvar)); break;
-      case VT_R8:   TRACE(",%3.3e", V_R8(pvar)); break;
-      case VT_BOOL: TRACE(",%s", V_BOOL(pvar) ? "TRUE" : "FALSE"); break;
-      case VT_BSTR: TRACE(",%s", debugstr_w(V_BSTR(pvar))); break;
-      case VT_CY:   TRACE(",0x%08x,0x%08x", V_CY(pvar).s.Hi,
-                           V_CY(pvar).s.Lo); break;
-      case VT_DATE:
-        if(!VariantTimeToSystemTime(V_DATE(pvar), &st))
-          TRACE(",<invalid>");
-        else
-          TRACE(",%04d/%02d/%02d %02d:%02d:%02d", st.wYear, st.wMonth, st.wDay,
-                st.wHour, st.wMinute, st.wSecond);
-        break;
-      case VT_ERROR:
-      case VT_VOID:
-      case VT_USERDEFINED:
-      case VT_EMPTY:
-      case VT_NULL:  break;
-      default:       TRACE(",?"); break;
-      }
-    }
-    TRACE("}\n");
-}
-
 static void dump_DispParms(const DISPPARAMS * pdp)
 {
     unsigned int index;
@@ -1643,7 +1606,7 @@ static void dump_DispParms(const DISPPARAMS * pdp)
     {
         TRACE("args:\n");
         for (index = 0; index < pdp->cArgs; index++)
-            dump_Variant( &pdp->rgvarg[index] );
+            TRACE("  [%d] %s\n", index, debugstr_variant(pdp->rgvarg+index));
     }
 }
 
@@ -6832,8 +6795,7 @@ DispCallFunc(
             args[argspos++] = V_UI4(arg);
             break;
         }
-        TRACE("arg %u: type %d\n",i,prgvt[i]);
-        dump_Variant(arg);
+        TRACE("arg %u: type %s %s\n", i, debugstr_vt(prgvt[i]), debugstr_variant(arg));
     }
 
     switch (vtReturn)
@@ -6873,7 +6835,7 @@ DispCallFunc(
         return DISP_E_BADCALLEE;
     }
     if (vtReturn != VT_VARIANT) V_VT(pvargResult) = vtReturn;
-    TRACE("retval: "); dump_Variant(pvargResult);
+    TRACE("retval: %s\n", debugstr_variant(pvargResult));
     return S_OK;
 
 #elif defined(__x86_64__)
@@ -6922,8 +6884,7 @@ DispCallFunc(
             args[argspos++] = V_UI8(arg);
             break;
         }
-        TRACE("arg %u: type %d\n",i,prgvt[i]);
-        dump_Variant(arg);
+        TRACE("arg %u: type %s %s\n", i, debugstr_vt(prgvt[i]), debugstr_variant(arg));
     }
 
     switch (vtReturn)
@@ -6950,7 +6911,7 @@ DispCallFunc(
     }
     heap_free( args );
     if (vtReturn != VT_VARIANT) V_VT(pvargResult) = vtReturn;
-    TRACE("retval: "); dump_Variant(pvargResult);
+    TRACE("retval: %s\n", debugstr_variant(pvargResult));
     return S_OK;
 
 #else
@@ -7145,7 +7106,7 @@ static HRESULT WINAPI ITypeInfo_fnInvoke(
                 }
                 else if (src_arg)
                 {
-                    dump_Variant(src_arg);
+                    TRACE("%s\n", debugstr_variant(src_arg));
 
                     if(rgvt[i]!=V_VT(src_arg))
                     {
@@ -7222,9 +7183,8 @@ static HRESULT WINAPI ITypeInfo_fnInvoke(
 
                         if (FAILED(hres))
                         {
-                            ERR("failed to convert param %d to %s%s from %s%s\n", i,
-                                debugstr_vt(rgvt[i]), debugstr_vf(rgvt[i]),
-                                debugstr_VT(src_arg), debugstr_VF(src_arg));
+                            ERR("failed to convert param %d to %s from %s\n", i,
+                                debugstr_vt(rgvt[i]), debugstr_variant(src_arg));
                             break;
                         }
                         prgpvarg[i] = &rgvarg[i];
@@ -7316,11 +7276,7 @@ static HRESULT WINAPI ITypeInfo_fnInvoke(
                     continue;
                 else if (wParamFlags & PARAMFLAG_FRETVAL)
                 {
-                    if (TRACE_ON(ole))
-                    {
-                        TRACE("[retval] value: ");
-                        dump_Variant(prgpvarg[i]);
-                    }
+                    TRACE("[retval] value: %s\n", debugstr_variant(prgpvarg[i]));
 
                     if (pVarResult)
                     {
@@ -7409,8 +7365,7 @@ static HRESULT WINAPI ITypeInfo_fnInvoke(
             }
             if (V_VT(&varresult) != VT_ERROR)
             {
-                TRACE("varresult value: ");
-                dump_Variant(&varresult);
+                TRACE("varresult value: %s\n", debugstr_variant(&varresult));
 
                 if (pVarResult)
                 {
index 7d092ee..3973742 100644 (file)
@@ -1187,9 +1187,8 @@ static HRESULT VARIANT_FormatNumber(LPVARIANT pVarIn, LPOLESTR lpszFormat,
   const BYTE* pToken = NULL;
   HRESULT hRes = S_OK;
 
-  TRACE("(%p->(%s%s),%s,%p,0x%08x,%p,0x%08x)\n", pVarIn, debugstr_VT(pVarIn),
-        debugstr_VF(pVarIn), debugstr_w(lpszFormat), rgbTok, dwFlags, pbstrOut,
-        lcid);
+  TRACE("(%s,%s,%p,0x%08x,%p,0x%08x)\n", debugstr_variant(pVarIn), debugstr_w(lpszFormat),
+        rgbTok, dwFlags, pbstrOut, lcid);
 
   V_VT(&vString) = VT_EMPTY;
   V_VT(&vBool) = VT_BOOL;
@@ -1598,9 +1597,8 @@ static HRESULT VARIANT_FormatDate(LPVARIANT pVarIn, LPOLESTR lpszFormat,
   const BYTE* pToken = NULL;
   HRESULT hRes;
 
-  TRACE("(%p->(%s%s),%s,%p,0x%08x,%p,0x%08x)\n", pVarIn, debugstr_VT(pVarIn),
-        debugstr_VF(pVarIn), debugstr_w(lpszFormat), rgbTok, dwFlags, pbstrOut,
-        lcid);
+  TRACE("(%s,%s,%p,0x%08x,%p,0x%08x)\n", debugstr_variant(pVarIn),
+        debugstr_w(lpszFormat), rgbTok, dwFlags, pbstrOut, lcid);
 
   V_VT(&vDate) = VT_EMPTY;
 
@@ -1940,9 +1938,8 @@ static HRESULT VARIANT_FormatString(LPVARIANT pVarIn, LPOLESTR lpszFormat,
   BOOL bUpper = FALSE;
   HRESULT hRes = S_OK;
 
-  TRACE("(%p->(%s%s),%s,%p,0x%08x,%p,0x%08x)\n", pVarIn, debugstr_VT(pVarIn),
-        debugstr_VF(pVarIn), debugstr_w(lpszFormat), rgbTok, dwFlags, pbstrOut,
-        lcid);
+  TRACE("%s,%s,%p,0x%08x,%p,0x%08x)\n", debugstr_variant(pVarIn), debugstr_w(lpszFormat),
+        rgbTok, dwFlags, pbstrOut, lcid);
 
   V_VT(&vStr) = VT_EMPTY;
 
@@ -2154,9 +2151,8 @@ HRESULT WINAPI VarFormat(LPVARIANT pVarIn, LPOLESTR lpszFormat,
   BYTE buff[256];
   HRESULT hres;
 
-  TRACE("(%p->(%s%s),%s,%d,%d,0x%08x,%p)\n", pVarIn, debugstr_VT(pVarIn),
-        debugstr_VF(pVarIn), debugstr_w(lpszFormat), nFirstDay, nFirstWeek,
-        dwFlags, pbstrOut);
+  TRACE("(%s,%s,%d,%d,0x%08x,%p)\n", debugstr_variant(pVarIn), debugstr_w(lpszFormat),
+        nFirstDay, nFirstWeek, dwFlags, pbstrOut);
 
   if (!pbstrOut)
     return E_INVALIDARG;
@@ -2205,8 +2201,7 @@ HRESULT WINAPI VarFormatDateTime(LPVARIANT pVarIn, INT nFormat, ULONG dwFlags, B
   static WCHAR szEmpty[] = { '\0' };
   const BYTE* lpFmt = NULL;
 
-  TRACE("(%p->(%s%s),%d,0x%08x,%p)\n", pVarIn, debugstr_VT(pVarIn),
-        debugstr_VF(pVarIn), nFormat, dwFlags, pbstrOut);
+  TRACE("%s,%d,0x%08x,%p)\n", debugstr_variant(pVarIn), nFormat, dwFlags, pbstrOut);
 
   if (!pVarIn || !pbstrOut || nFormat < 0 || nFormat > 4)
     return E_INVALIDARG;
@@ -2258,8 +2253,8 @@ HRESULT WINAPI VarFormatNumber(LPVARIANT pVarIn, INT nDigits, INT nLeading, INT
   HRESULT hRet;
   VARIANT vStr;
 
-  TRACE("(%p->(%s%s),%d,%d,%d,%d,0x%08x,%p)\n", pVarIn, debugstr_VT(pVarIn),
-        debugstr_VF(pVarIn), nDigits, nLeading, nParens, nGrouping, dwFlags, pbstrOut);
+  TRACE("(%s,%d,%d,%d,%d,0x%08x,%p)\n", debugstr_variant(pVarIn), nDigits, nLeading,
+        nParens, nGrouping, dwFlags, pbstrOut);
 
   if (!pVarIn || !pbstrOut || nDigits > 9)
     return E_INVALIDARG;
@@ -2369,9 +2364,8 @@ HRESULT WINAPI VarFormatPercent(LPVARIANT pVarIn, INT nDigits, INT nLeading, INT
   HRESULT hRet;
   VARIANT vDbl;
 
-  TRACE("(%p->(%s%s),%d,%d,%d,%d,0x%08x,%p)\n", pVarIn, debugstr_VT(pVarIn),
-        debugstr_VF(pVarIn), nDigits, nLeading, nParens, nGrouping,
-        dwFlags, pbstrOut);
+  TRACE("(%s,%d,%d,%d,%d,0x%08x,%p)\n", debugstr_variant(pVarIn), nDigits, nLeading,
+        nParens, nGrouping, dwFlags, pbstrOut);
 
   if (!pVarIn || !pbstrOut || nDigits > 9)
     return E_INVALIDARG;
@@ -2443,8 +2437,8 @@ HRESULT WINAPI VarFormatCurrency(LPVARIANT pVarIn, INT nDigits, INT nLeading,
   HRESULT hRet;
   VARIANT vStr;
 
-  TRACE("(%p->(%s%s),%d,%d,%d,%d,0x%08x,%p)\n", pVarIn, debugstr_VT(pVarIn),
-        debugstr_VF(pVarIn), nDigits, nLeading, nParens, nGrouping, dwFlags, pbstrOut);
+  TRACE("(%s,%d,%d,%d,%d,0x%08x,%p)\n", debugstr_variant(pVarIn), nDigits, nLeading,
+        nParens, nGrouping, dwFlags, pbstrOut);
 
   if (!pVarIn || !pbstrOut || nDigits > 9)
     return E_INVALIDARG;
index e6f6372..3c7e810 100644 (file)
@@ -29,7 +29,7 @@
 
 WINE_DEFAULT_DEBUG_CHANNEL(variant);
 
-const char * const wine_vtypes[VT_CLSID+1] =
+static const char * const variant_types[] =
 {
   "VT_EMPTY","VT_NULL","VT_I2","VT_I4","VT_R4","VT_R8","VT_CY","VT_DATE",
   "VT_BSTR","VT_DISPATCH","VT_ERROR","VT_BOOL","VT_VARIANT","VT_UNKNOWN",
@@ -39,10 +39,11 @@ const char * const wine_vtypes[VT_CLSID+1] =
   "VT_RECORD","VT_INT_PTR","VT_UINT_PTR","39","40","41","42","43","44","45",
   "46","47","48","49","50","51","52","53","54","55","56","57","58","59","60",
   "61","62","63","VT_FILETIME","VT_BLOB","VT_STREAM","VT_STORAGE",
-  "VT_STREAMED_OBJECT","VT_STORED_OBJECT","VT_BLOB_OBJECT","VT_CF","VT_CLSID"
+  "VT_STREAMED_OBJECT","VT_STORED_OBJECT","VT_BLOB_OBJECT","VT_CF","VT_CLSID",
+  "VT_VERSIONED_STREAM"
 };
 
-const char * const wine_vflags[16] =
+static const char * const variant_flags[16] =
 {
  "",
  "|VT_VECTOR",
@@ -52,14 +53,14 @@ const char * const wine_vflags[16] =
  "|VT_VECTOR|VT_ARRAY",
  "|VT_ARRAY|VT_BYREF",
  "|VT_VECTOR|VT_ARRAY|VT_BYREF",
- "|VT_HARDTYPE",
- "|VT_VECTOR|VT_HARDTYPE",
- "|VT_ARRAY|VT_HARDTYPE",
- "|VT_VECTOR|VT_ARRAY|VT_HARDTYPE",
- "|VT_BYREF|VT_HARDTYPE",
- "|VT_VECTOR|VT_ARRAY|VT_HARDTYPE",
- "|VT_ARRAY|VT_BYREF|VT_HARDTYPE",
- "|VT_VECTOR|VT_ARRAY|VT_BYREF|VT_HARDTYPE",
+ "|VT_RESERVED",
+ "|VT_VECTOR|VT_RESERVED",
+ "|VT_ARRAY|VT_RESERVED",
+ "|VT_VECTOR|VT_ARRAY|VT_RESERVED",
+ "|VT_BYREF|VT_RESERVED",
+ "|VT_VECTOR|VT_ARRAY|VT_RESERVED",
+ "|VT_ARRAY|VT_BYREF|VT_RESERVED",
+ "|VT_VECTOR|VT_ARRAY|VT_BYREF|VT_RESERVED",
 };
 
 /* Convert a variant from one type to another */
@@ -70,9 +71,8 @@ static inline HRESULT VARIANT_Coerce(VARIANTARG* pd, LCID lcid, USHORT wFlags,
   VARTYPE vtFrom =  V_TYPE(ps);
   DWORD dwFlags = 0;
 
-  TRACE("(%p->(%s%s),0x%08x,0x%04x,%p->(%s%s),%s%s)\n", pd, debugstr_VT(pd),
-        debugstr_VF(pd), lcid, wFlags, ps, debugstr_VT(ps), debugstr_VF(ps),
-        debugstr_vt(vt), debugstr_vf(vt));
+  TRACE("(%s,0x%08x,0x%04x,%s,%s)\n", debugstr_variant(pd), lcid, wFlags,
+        debugstr_variant(ps), debugstr_vt(vt));
 
   if (vt == VT_BSTR || vtFrom == VT_BSTR)
   {
@@ -567,7 +567,7 @@ HRESULT VARIANT_ClearInd(VARIANTARG *pVarg)
 {
     HRESULT hres;
 
-    TRACE("(%p->(%s%s))\n", pVarg, debugstr_VT(pVarg), debugstr_VF(pVarg));
+    TRACE("(%s)\n", debugstr_variant(pVarg));
 
     hres = VARIANT_ValidateType(V_VT(pVarg));
     if (FAILED(hres))
@@ -639,7 +639,7 @@ HRESULT WINAPI VariantClear(VARIANTARG* pVarg)
 {
   HRESULT hres;
 
-  TRACE("(%p->(%s%s))\n", pVarg, debugstr_VT(pVarg), debugstr_VF(pVarg));
+  TRACE("(%s)\n", debugstr_variant(pVarg));
 
   hres = VARIANT_ValidateType(V_VT(pVarg));
 
@@ -739,9 +739,7 @@ HRESULT WINAPI VariantCopy(VARIANTARG* pvargDest, VARIANTARG* pvargSrc)
 {
   HRESULT hres = S_OK;
 
-  TRACE("(%p->(%s%s),%p->(%s%s))\n", pvargDest, debugstr_VT(pvargDest),
-        debugstr_VF(pvargDest), pvargSrc, debugstr_VT(pvargSrc),
-        debugstr_VF(pvargSrc));
+  TRACE("(%s,%s)\n", debugstr_variant(pvargDest), debugstr_variant(pvargSrc));
 
   if (V_TYPE(pvargSrc) == VT_CLSID || /* VT_CLSID is a special case */
       FAILED(VARIANT_ValidateType(V_VT(pvargSrc))))
@@ -804,7 +802,7 @@ static inline size_t VARIANT_DataSize(const VARIANT* pv)
   case VT_CY:    return sizeof(CY);
   case VT_ERROR: return sizeof(SCODE);
   }
-  TRACE("Shouldn't be called for vt %s%s!\n", debugstr_VT(pv), debugstr_VF(pv));
+  TRACE("Shouldn't be called for variant %s!\n", debugstr_variant(pv));
   return 0;
 }
 
@@ -842,9 +840,7 @@ HRESULT WINAPI VariantCopyInd(VARIANT* pvargDest, VARIANTARG* pvargSrc)
   VARTYPE vt;
   HRESULT hres = S_OK;
 
-  TRACE("(%p->(%s%s),%p->(%s%s))\n", pvargDest, debugstr_VT(pvargDest),
-        debugstr_VF(pvargDest), pvargSrc, debugstr_VT(pvargSrc),
-        debugstr_VF(pvargSrc));
+  TRACE("(%s,%s)\n", debugstr_variant(pvargDest), debugstr_variant(pvargSrc));
 
   if (!V_ISBYREF(pvargSrc))
     return VariantCopy(pvargDest, pvargSrc);
@@ -930,8 +926,7 @@ VariantCopyInd_Return:
   if (pSrc != pvargSrc)
     VariantClear(pSrc);
 
-  TRACE("returning 0x%08x, %p->(%s%s)\n", hres, pvargDest,
-        debugstr_VT(pvargDest), debugstr_VF(pvargDest));
+  TRACE("returning 0x%08x, %s\n", hres, debugstr_variant(pvargDest));
   return hres;
 }
 
@@ -985,10 +980,8 @@ HRESULT WINAPI VariantChangeTypeEx(VARIANTARG* pvargDest, VARIANTARG* pvargSrc,
 {
   HRESULT res = S_OK;
 
-  TRACE("(%p->(%s%s),%p->(%s%s),0x%08x,0x%04x,%s%s)\n", pvargDest,
-        debugstr_VT(pvargDest), debugstr_VF(pvargDest), pvargSrc,
-        debugstr_VT(pvargSrc), debugstr_VF(pvargSrc), lcid, wFlags,
-        debugstr_vt(vt), debugstr_vf(vt));
+  TRACE("(%s,%s,0x%08x,0x%04x,%s)\n", debugstr_variant(pvargDest),
+        debugstr_variant(pvargSrc), lcid, wFlags, debugstr_vt(vt));
 
   if (vt == VT_CLSID)
     res = DISP_E_BADVARTYPE;
@@ -1026,7 +1019,7 @@ HRESULT WINAPI VariantChangeTypeEx(VARIANTARG* pvargDest, VARIANTARG* pvargSrc,
 
             if (SUCCEEDED(res)) {
                 V_VT(&vTmp) = vt;
-                VariantCopy(pvargDest, &vTmp);
+                res = VariantCopy(pvargDest, &vTmp);
             }
             VariantClear(&vTmp);
             VariantClear(&vSrcDeref);
@@ -1036,8 +1029,7 @@ HRESULT WINAPI VariantChangeTypeEx(VARIANTARG* pvargDest, VARIANTARG* pvargSrc,
     }
   }
 
-  TRACE("returning 0x%08x, %p->(%s%s)\n", res, pvargDest,
-        debugstr_VT(pvargDest), debugstr_VF(pvargDest));
+  TRACE("returning 0x%08x, %s\n", res, debugstr_variant(pvargDest));
   return res;
 }
 
@@ -1343,7 +1335,7 @@ INT WINAPI VariantTimeToSystemTime(double dateIn, LPSYSTEMTIME lpSt)
 HRESULT WINAPI VarDateFromUdateEx(UDATE *pUdateIn, LCID lcid, ULONG dwFlags, DATE *pDateOut)
 {
   UDATE ud;
-  double dateVal, dateSign;
+  double dateVal = 0;
 
   TRACE("(%p->%d/%d/%d %d:%d:%d:%d %d %d,0x%08x,0x%08x,%p)\n", pUdateIn,
         pUdateIn->st.wMonth, pUdateIn->st.wDay, pUdateIn->st.wYear,
@@ -1353,6 +1345,8 @@ HRESULT WINAPI VarDateFromUdateEx(UDATE *pUdateIn, LCID lcid, ULONG dwFlags, DAT
 
   if (lcid != MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT))
     FIXME("lcid possibly not handled, treating as en-us\n");
+  if (dwFlags & ~(VAR_TIMEVALUEONLY|VAR_DATEVALUEONLY))
+    FIXME("unsupported flags: %x\n", dwFlags);
 
   ud = *pUdateIn;
 
@@ -1363,15 +1357,18 @@ HRESULT WINAPI VarDateFromUdateEx(UDATE *pUdateIn, LCID lcid, ULONG dwFlags, DAT
     return E_INVALIDARG;
 
   /* Date */
-  dateVal = VARIANT_DateFromJulian(VARIANT_JulianFromDMY(ud.st.wYear, ud.st.wMonth, ud.st.wDay));
+  if (!(dwFlags & VAR_TIMEVALUEONLY))
+    dateVal = VARIANT_DateFromJulian(VARIANT_JulianFromDMY(ud.st.wYear, ud.st.wMonth, ud.st.wDay));
 
-  /* Sign */
-  dateSign = (dateVal < 0.0) ? -1.0 : 1.0;
+  if ((dwFlags & VAR_TIMEVALUEONLY) || !(dwFlags & VAR_DATEVALUEONLY))
+  {
+    double dateSign = (dateVal < 0.0) ? -1.0 : 1.0;
 
-  /* Time */
-  dateVal += ud.st.wHour / 24.0 * dateSign;
-  dateVal += ud.st.wMinute / 1440.0 * dateSign;
-  dateVal += ud.st.wSecond / 86400.0 * dateSign;
+    /* Time */
+    dateVal += ud.st.wHour / 24.0 * dateSign;
+    dateVal += ud.st.wMinute / 1440.0 * dateSign;
+    dateVal += ud.st.wSecond / 86400.0 * dateSign;
+  }
 
   TRACE("Returning %g\n", dateVal);
   *pDateOut = dateVal;
@@ -2517,8 +2514,7 @@ HRESULT WINAPI VarCat(LPVARIANT left, LPVARIANT right, LPVARIANT out)
     leftvt = V_VT(left);
     rightvt = V_VT(right);
 
-    TRACE("(%p->(%s%s),%p->(%s%s),%p)\n", left, debugstr_VT(left),
-          debugstr_VF(left), right, debugstr_VT(right), debugstr_VF(right), out);
+    TRACE("%s,%s,%p)\n", debugstr_variant(left), debugstr_variant(right), out);
 
     if (!str_true[0]) {
         VARIANT_GetLocalisedText(LOCALE_USER_DEFAULT, IDS_FALSE, str_false);
@@ -2761,8 +2757,7 @@ HRESULT WINAPI VarCmp(LPVARIANT left, LPVARIANT right, LCID lcid, DWORD flags)
     DWORD       xmask;
     HRESULT     rc;
 
-    TRACE("(%p->(%s%s),%p->(%s%s),0x%08x,0x%08x)\n", left, debugstr_VT(left),
-          debugstr_VF(left), right, debugstr_VT(right), debugstr_VF(right), lcid, flags);
+    TRACE("(%s,%s,0x%08x,0x%08x)\n", debugstr_variant(left), debugstr_variant(right), lcid, flags);
 
     lvt = V_VT(left) & VT_TYPEMASK;
     rvt = V_VT(right) & VT_TYPEMASK;
@@ -2966,8 +2961,7 @@ HRESULT WINAPI VarAnd(LPVARIANT left, LPVARIANT right, LPVARIANT result)
     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);
+    TRACE("(%s,%s,%p)\n", debugstr_variant(left), debugstr_variant(right), result);
 
     /* Handle VT_DISPATCH by storing and taking address of returned value */
     if ((V_VT(left) & VT_TYPEMASK) == VT_DISPATCH)
@@ -3012,7 +3006,6 @@ HRESULT WINAPI VarAnd(LPVARIANT left, LPVARIANT right, LPVARIANT result)
     else if (leftvt == VT_I4 || rightvt == VT_I4 ||
         leftvt == VT_UINT || rightvt == VT_UINT ||
         leftvt == VT_INT || rightvt == VT_INT ||
-        leftvt == VT_UINT || rightvt == VT_UINT ||
         leftvt == VT_R4 || rightvt == VT_R4 ||
         leftvt == VT_R8 || rightvt == VT_R8 ||
         leftvt == VT_CY || rightvt == VT_CY ||
@@ -3221,9 +3214,7 @@ HRESULT WINAPI VarAdd(LPVARIANT left, LPVARIANT right, LPVARIANT result)
         vt_ERROR, vt_ERROR, vt_UI1, vt_ERROR, vt_ERROR, vt_I8
     };
 
-    TRACE("(%p->(%s%s),%p->(%s%s),%p)\n", left, debugstr_VT(left),
-          debugstr_VF(left), right, debugstr_VT(right), debugstr_VF(right),
-          result);
+    TRACE("(%s,%s,%p)\n", debugstr_variant(left), debugstr_variant(right), result);
 
     VariantInit(&lv);
     VariantInit(&rv);
@@ -3377,7 +3368,7 @@ end:
     VariantClear(&tv);
     VariantClear(&tempLeft);
     VariantClear(&tempRight);
-    TRACE("returning 0x%8x (variant type %s)\n", hres, debugstr_VT(result));
+    TRACE("returning 0x%8x %s\n", hres, debugstr_variant(result));
     return hres;
 }
 
@@ -3434,9 +3425,7 @@ HRESULT WINAPI VarMul(LPVARIANT left, LPVARIANT right, LPVARIANT result)
         vt_ERROR, vt_ERROR, vt_UI1, vt_ERROR, vt_ERROR, vt_I8
     };
 
-    TRACE("(%p->(%s%s),%p->(%s%s),%p)\n", left, debugstr_VT(left),
-          debugstr_VF(left), right, debugstr_VT(right), debugstr_VF(right),
-          result);
+    TRACE("(%s,%s,%p)\n", debugstr_variant(left), debugstr_variant(right), result);
 
     VariantInit(&lv);
     VariantInit(&rv);
@@ -3568,7 +3557,7 @@ end:
     VariantClear(&tv);
     VariantClear(&tempLeft);
     VariantClear(&tempRight);
-    TRACE("returning 0x%8x (variant type %s)\n", hres, debugstr_VT(result));
+    TRACE("returning 0x%8x %s\n", hres, debugstr_variant(result));
     return hres;
 }
 
@@ -3600,8 +3589,7 @@ HRESULT WINAPI VarDiv(LPVARIANT left, LPVARIANT right, LPVARIANT result)
     VariantInit(&lv);
     VariantInit(&rv);
 
-    TRACE("(%p->(%s%s),%p->(%s%s),%p)\n", left, debugstr_VT(left),
-          debugstr_VF(left), right, debugstr_VT(right), debugstr_VF(right), result);
+    TRACE("(%s,%s,%p)\n", debugstr_variant(left), debugstr_variant(right), result);
 
     /* Handle VT_DISPATCH by storing and taking address of returned value */
     if ((V_VT(left) & VT_TYPEMASK) == VT_DISPATCH)
@@ -3731,7 +3719,7 @@ end:
     VariantClear(&rv);
     VariantClear(&tempLeft);
     VariantClear(&tempRight);
-    TRACE("returning 0x%8x (variant type %s)\n", hres, debugstr_VT(result));
+    TRACE("returning 0x%8x %s\n", hres, debugstr_variant(result));
     return hres;
 }
 
@@ -3763,8 +3751,7 @@ HRESULT WINAPI VarSub(LPVARIANT left, LPVARIANT right, LPVARIANT result)
     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);
+    TRACE("(%s,%s,%p)\n", debugstr_variant(left), debugstr_variant(right), result);
 
     if ((V_VT(left) & VT_TYPEMASK) == VT_DISPATCH &&
         (V_VT(left)&(~VT_TYPEMASK)) == 0 &&
@@ -3998,7 +3985,7 @@ end:
     VariantClear(&rv);
     VariantClear(&tempLeft);
     VariantClear(&tempRight);
-    TRACE("returning 0x%8x (variant type %s)\n", hres, debugstr_VT(result));
+    TRACE("returning 0x%8x %s\n", hres, debugstr_variant(result));
     return hres;
 }
 
@@ -4034,9 +4021,7 @@ HRESULT WINAPI VarOr(LPVARIANT pVarLeft, LPVARIANT pVarRight, LPVARIANT pVarOut)
     VariantInit(&varRight);
     VariantInit(&varStr);
 
-    TRACE("(%p->(%s%s),%p->(%s%s),%p)\n", pVarLeft, debugstr_VT(pVarLeft),
-          debugstr_VF(pVarLeft), pVarRight, debugstr_VT(pVarRight),
-          debugstr_VF(pVarRight), pVarOut);
+    TRACE("(%s,%s,%p)\n", debugstr_variant(pVarLeft), debugstr_variant(pVarRight), pVarOut);
 
     /* Handle VT_DISPATCH by storing and taking address of returned value */
     if ((V_VT(pVarLeft) & VT_TYPEMASK) == VT_DISPATCH)
@@ -4343,8 +4328,7 @@ HRESULT WINAPI VarAbs(LPVARIANT pVarIn, LPVARIANT pVarOut)
 
     VariantInit(&temp);
 
-    TRACE("(%p->(%s%s),%p)\n", pVarIn, debugstr_VT(pVarIn),
-          debugstr_VF(pVarIn), pVarOut);
+    TRACE("(%s,%p)\n", debugstr_variant(pVarIn), pVarOut);
 
     /* Handle VT_DISPATCH by storing and taking address of returned value */
     if ((V_VT(pVarIn) & VT_TYPEMASK) == VT_DISPATCH && ((V_VT(pVarIn) & ~VT_TYPEMASK) == 0))
@@ -4447,8 +4431,7 @@ HRESULT WINAPI VarFix(LPVARIANT pVarIn, LPVARIANT pVarOut)
 
     VariantInit(&temp);
 
-    TRACE("(%p->(%s%s),%p)\n", pVarIn, debugstr_VT(pVarIn),
-          debugstr_VF(pVarIn), pVarOut);
+    TRACE("(%s,%p)\n", debugstr_variant(pVarIn), pVarOut);
 
     /* Handle VT_DISPATCH by storing and taking address of returned value */
     if ((V_VT(pVarIn) & VT_TYPEMASK) == VT_DISPATCH && ((V_VT(pVarIn) & ~VT_TYPEMASK) == 0))
@@ -4554,8 +4537,7 @@ HRESULT WINAPI VarInt(LPVARIANT pVarIn, LPVARIANT pVarOut)
 
     VariantInit(&temp);
 
-    TRACE("(%p->(%s%s),%p)\n", pVarIn, debugstr_VT(pVarIn),
-          debugstr_VF(pVarIn), pVarOut);
+    TRACE("(%s,%p)\n", debugstr_variant(pVarIn), pVarOut);
 
     /* Handle VT_DISPATCH by storing and taking address of returned value */
     if ((V_VT(pVarIn) & VT_TYPEMASK) == VT_DISPATCH && ((V_VT(pVarIn) & ~VT_TYPEMASK) == 0))
@@ -4629,9 +4611,7 @@ HRESULT WINAPI VarXor(LPVARIANT pVarLeft, LPVARIANT pVarRight, LPVARIANT pVarOut
     double d;
     HRESULT hRet;
 
-    TRACE("(%p->(%s%s),%p->(%s%s),%p)\n", pVarLeft, debugstr_VT(pVarLeft),
-          debugstr_VF(pVarLeft), pVarRight, debugstr_VT(pVarRight),
-          debugstr_VF(pVarRight), pVarOut);
+    TRACE("(%s,%s,%p)\n", debugstr_variant(pVarLeft), debugstr_variant(pVarRight), pVarOut);
 
     if (V_EXTRA_TYPE(pVarLeft) || V_EXTRA_TYPE(pVarRight) ||
         V_VT(pVarLeft) > VT_UINT || V_VT(pVarRight) > VT_UINT ||
@@ -4808,9 +4788,7 @@ HRESULT WINAPI VarEqv(LPVARIANT pVarLeft, LPVARIANT pVarRight, LPVARIANT pVarOut
 {
     HRESULT hRet;
 
-    TRACE("(%p->(%s%s),%p->(%s%s),%p)\n", pVarLeft, debugstr_VT(pVarLeft),
-          debugstr_VF(pVarLeft), pVarRight, debugstr_VT(pVarRight),
-          debugstr_VF(pVarRight), pVarOut);
+    TRACE("(%s,%s,%p)\n", debugstr_variant(pVarLeft), debugstr_variant(pVarRight), pVarOut);
 
     hRet = VarXor(pVarLeft, pVarRight, pVarOut);
     if (SUCCEEDED(hRet))
@@ -4867,8 +4845,7 @@ HRESULT WINAPI VarNeg(LPVARIANT pVarIn, LPVARIANT pVarOut)
 
     VariantInit(&temp);
 
-    TRACE("(%p->(%s%s),%p)\n", pVarIn, debugstr_VT(pVarIn),
-          debugstr_VF(pVarIn), pVarOut);
+    TRACE("(%s,%p)\n", debugstr_variant(pVarIn), pVarOut);
 
     /* Handle VT_DISPATCH by storing and taking address of returned value */
     if ((V_VT(pVarIn) & VT_TYPEMASK) == VT_DISPATCH && ((V_VT(pVarIn) & ~VT_TYPEMASK) == 0))
@@ -4997,8 +4974,7 @@ HRESULT WINAPI VarNot(LPVARIANT pVarIn, LPVARIANT pVarOut)
 
     VariantInit(&temp);
 
-    TRACE("(%p->(%s%s),%p)\n", pVarIn, debugstr_VT(pVarIn),
-          debugstr_VF(pVarIn), pVarOut);
+    TRACE("(%s,%p)\n", debugstr_variant(pVarIn), pVarOut);
 
     /* Handle VT_DISPATCH by storing and taking address of returned value */
     if ((V_VT(pVarIn) & VT_TYPEMASK) == VT_DISPATCH && ((V_VT(pVarIn) & ~VT_TYPEMASK) == 0))
@@ -5122,7 +5098,7 @@ HRESULT WINAPI VarRound(LPVARIANT pVarIn, int deci, LPVARIANT pVarOut)
 
     VariantInit(&temp);
 
-    TRACE("(%p->(%s%s),%d)\n", pVarIn, debugstr_VT(pVarIn), debugstr_VF(pVarIn), deci);
+    TRACE("(%s,%d)\n", debugstr_variant(pVarIn), deci);
 
     /* Handle VT_DISPATCH by storing and taking address of returned value */
     if ((V_VT(pVarIn) & VT_TYPEMASK) == VT_DISPATCH && ((V_VT(pVarIn) & ~VT_TYPEMASK) == 0))
@@ -5227,10 +5203,7 @@ VarRound_Exit:
       V_VT(pVarOut) = VT_EMPTY;
     VariantClear(&temp);
 
-    TRACE("returning 0x%08x (%s%s),%f\n", hRet, debugstr_VT(pVarOut),
-       debugstr_VF(pVarOut), (V_VT(pVarOut) == VT_R4) ? V_R4(pVarOut) :
-       (V_VT(pVarOut) == VT_R8) ? V_R8(pVarOut) : 0);
-
+    TRACE("returning 0x%08x %s\n", hRet, debugstr_variant(pVarOut));
     return hRet;
 }
 
@@ -5260,8 +5233,7 @@ HRESULT WINAPI VarIdiv(LPVARIANT left, LPVARIANT right, LPVARIANT result)
     VARIANT lv,rv;
     VARIANT tempLeft, 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);
+    TRACE("(%s,%s,%p)\n", debugstr_variant(left), debugstr_variant(right), result);
 
     VariantInit(&lv);
     VariantInit(&rv);
@@ -5419,8 +5391,7 @@ HRESULT WINAPI VarMod(LPVARIANT left, LPVARIANT right, LPVARIANT result)
     VariantInit(&lv);
     VariantInit(&rv);
 
-    TRACE("(%p->(%s%s),%p->(%s%s),%p)\n", left, debugstr_VT(left),
-                 debugstr_VF(left), right, debugstr_VT(right), debugstr_VF(right), result);
+    TRACE("(%s,%s,%p)\n", debugstr_variant(left), debugstr_variant(right), result);
 
     /* Handle VT_DISPATCH by storing and taking address of returned value */
     if ((V_VT(left) & VT_TYPEMASK) == VT_DISPATCH)
@@ -5658,8 +5629,7 @@ HRESULT WINAPI VarPow(LPVARIANT left, LPVARIANT right, LPVARIANT result)
     VARTYPE rightExtraFlags,leftExtraFlags,ExtraFlags;
     VARIANT tempLeft, 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);
+    TRACE("(%s,%s,%p)\n", debugstr_variant(left), debugstr_variant(right), result);
 
     VariantInit(&dl);
     VariantInit(&dr);
@@ -5779,8 +5749,7 @@ HRESULT WINAPI VarImp(LPVARIANT left, LPVARIANT right, LPVARIANT result)
     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);
+    TRACE("(%s,%s,%p)\n", debugstr_variant(left), debugstr_variant(right), result);
 
     /* Handle VT_DISPATCH by storing and taking address of returned value */
     if ((V_VT(left) & VT_TYPEMASK) == VT_DISPATCH)
index dceac5c..79239f8 100644 (file)
 #define VTBIT_VARIANT   (1 << VT_VARIANT)
 #define VTBIT_15        (1 << 15)        /* no variant type with this number */
 
-extern const char * const wine_vtypes[] DECLSPEC_HIDDEN;
-#define debugstr_vt(v) (((v)&VT_TYPEMASK) <= VT_CLSID ? wine_vtypes[((v)&VT_TYPEMASK)] : \
-  ((v)&VT_TYPEMASK) == VT_BSTR_BLOB ? "VT_BSTR_BLOB": "Invalid")
-#define debugstr_VT(v) (!(v) ? "(null)" : debugstr_vt(V_TYPE((v))))
-
-extern const char * const wine_vflags[] DECLSPEC_HIDDEN;
-#define debugstr_vf(v) (wine_vflags[((v)&VT_EXTRA_TYPE)>>12])
-#define debugstr_VF(v) (!(v) ? "(null)" : debugstr_vf(V_EXTRA_TYPE(v)))
-
 /* Size constraints */
 #define I1_MAX   0x7f
 #define I1_MIN   ((-I1_MAX)-1)
index a310387..5a8f0d1 100644 (file)
@@ -4154,6 +4154,8 @@ static HRESULT VARIANT_DI_FromR4(float source, VARIANT_DI * dest);
 static HRESULT VARIANT_DI_FromR8(double source, VARIANT_DI * dest);
 static void VARIANT_DIFromDec(const DECIMAL * from, VARIANT_DI * to);
 static void VARIANT_DecFromDI(const VARIANT_DI * from, DECIMAL * to);
+static unsigned char VARIANT_int_divbychar(DWORD * p, unsigned int n, unsigned char divisor);
+static BOOL VARIANT_int_iszero(const DWORD * p, unsigned int n);
 
 /************************************************************************
  * VarDecFromR4 (OLEAUT32.193)
@@ -4429,12 +4431,13 @@ HRESULT WINAPI VarDecFromUI8(ULONG64 ullIn, DECIMAL* pDecOut)
 /* Make two DECIMALS the same scale; used by math functions below */
 static HRESULT VARIANT_DecScale(const DECIMAL** ppDecLeft,
                                 const DECIMAL** ppDecRight,
-                                DECIMAL* pDecOut)
+                                DECIMAL pDecOut[2])
 {
   static DECIMAL scaleFactor;
+  unsigned char remainder;
   DECIMAL decTemp;
+  VARIANT_DI di;
   int scaleAmount, i;
-  HRESULT hRet = S_OK;
 
   if (DEC_SIGN(*ppDecLeft) & ~DECIMAL_NEG || DEC_SIGN(*ppDecRight) & ~DECIMAL_NEG)
     return E_INVALIDARG;
@@ -4449,27 +4452,62 @@ static HRESULT VARIANT_DecScale(const DECIMAL** ppDecLeft,
   if (scaleAmount > 0)
   {
     decTemp = *(*ppDecRight); /* Left is bigger - scale the right hand side */
-    *ppDecRight = pDecOut;
+    *ppDecRight = &pDecOut[0];
   }
   else
   {
     decTemp = *(*ppDecLeft); /* Right is bigger - scale the left hand side */
-    *ppDecLeft = pDecOut;
-    i = scaleAmount = -scaleAmount;
+    *ppDecLeft  = &pDecOut[0];
+    i = -scaleAmount;
   }
 
-  if (DEC_SCALE(&decTemp) + scaleAmount > DEC_MAX_SCALE)
-    return DISP_E_OVERFLOW; /* Can't scale up */
+  /* Multiply up the value to be scaled by the correct amount (if possible) */
+  while (i > 0 && SUCCEEDED(VarDecMul(&decTemp, &scaleFactor, &pDecOut[0])))
+  {
+    decTemp = pDecOut[0];
+    i--;
+  }
 
-  /* Multiply up the value to be scaled by the correct amount */
-  while (SUCCEEDED(hRet) && i--)
+  if (!i)
   {
-    /* Note we are multiplying by a value with a scale of 0, so we don't recurse */
-    hRet = VarDecMul(&decTemp, &scaleFactor, pDecOut);
-    decTemp = *pDecOut;
+    DEC_SCALE(&pDecOut[0]) += (scaleAmount > 0) ? scaleAmount : (-scaleAmount);
+    return S_OK; /* Same scale */
   }
-  DEC_SCALE(pDecOut) += scaleAmount; /* Set the new scale */
-  return hRet;
+
+  /* Scaling further not possible, reduce accuracy of other argument */
+  pDecOut[0] = decTemp;
+  if (scaleAmount > 0)
+  {
+    DEC_SCALE(&pDecOut[0]) += scaleAmount - i;
+    VARIANT_DIFromDec(*ppDecLeft, &di);
+    *ppDecLeft = &pDecOut[1];
+  }
+  else
+  {
+    DEC_SCALE(&pDecOut[0]) += (-scaleAmount) - i;
+    VARIANT_DIFromDec(*ppDecRight, &di);
+    *ppDecRight = &pDecOut[1];
+  }
+
+  di.scale -= i;
+  remainder = 0;
+  while (i-- > 0 && !VARIANT_int_iszero(di.bitsnum, sizeof(di.bitsnum)/sizeof(DWORD)))
+  {
+    remainder = VARIANT_int_divbychar(di.bitsnum, sizeof(di.bitsnum)/sizeof(DWORD), 10);
+    if (remainder > 0) WARN("losing significant digits (remainder %u)...\n", remainder);
+  }
+
+  /* round up the result - native oleaut32 does this */
+  if (remainder >= 5) {
+      for (remainder = 1, i = 0; i < sizeof(di.bitsnum)/sizeof(DWORD) && remainder; i++) {
+          ULONGLONG digit = di.bitsnum[i] + 1;
+          remainder = (digit > 0xFFFFFFFF) ? 1 : 0;
+          di.bitsnum[i] = digit & 0xFFFFFFFF;
+      }
+  }
+
+  VARIANT_DecFromDI(&di, &pDecOut[1]);
+  return S_OK;
 }
 
 /* Add two unsigned 32 bit values with overflow */
@@ -4544,9 +4582,9 @@ static inline int VARIANT_DecCmp(const DECIMAL *pDecLeft, const DECIMAL *pDecRig
 HRESULT WINAPI VarDecAdd(const DECIMAL* pDecLeft, const DECIMAL* pDecRight, DECIMAL* pDecOut)
 {
   HRESULT hRet;
-  DECIMAL scaled;
+  DECIMAL scaled[2];
 
-  hRet = VARIANT_DecScale(&pDecLeft, &pDecRight, &scaled);
+  hRet = VARIANT_DecScale(&pDecLeft, &pDecRight, scaled);
 
   if (SUCCEEDED(hRet))
   {
index 4d0db59..d860bc1 100644 (file)
@@ -152,7 +152,7 @@ reactos/dll/win32/odbc32              # Synced to Wine-1.7.17. Depends on port o
 reactos/dll/win32/odbccp32            # Synced to Wine-1.7.17
 reactos/dll/win32/ole32               # Synced to Wine-1.7.27
 reactos/dll/win32/oleacc              # Synced to Wine-1.7.27
-reactos/dll/win32/oleaut32            # Synced to Wine-1.7.17
+reactos/dll/win32/oleaut32            # Synced to Wine-1.7.27
 reactos/dll/win32/olecli32            # Synced to Wine-1.7.17
 reactos/dll/win32/oledlg              # Synced to Wine-1.7.17
 reactos/dll/win32/olepro32            # Synced to Wine-1.7.17