[OLEAUT32] Sync with Wine Staging 4.18. CORE-16441
authorAmine Khaldi <amine.khaldi@reactos.org>
Sat, 23 Nov 2019 11:05:03 +0000 (12:05 +0100)
committerAmine Khaldi <amine.khaldi@reactos.org>
Sat, 23 Nov 2019 11:05:03 +0000 (12:05 +0100)
12 files changed:
dll/win32/oleaut32/dispatch.c
dll/win32/oleaut32/oleaut.c
dll/win32/oleaut32/olefont.c
dll/win32/oleaut32/olepicture.c
dll/win32/oleaut32/precomp.h
dll/win32/oleaut32/recinfo.c
dll/win32/oleaut32/safearray.c
dll/win32/oleaut32/typelib.c
dll/win32/oleaut32/varformat.c
dll/win32/oleaut32/variant.c
dll/win32/oleaut32/vartype.c
media/doc/README.WINE

index a666d3d..7e6398a 100644 (file)
@@ -19,8 +19,6 @@
  *
  */
 
-#include "config.h"
-
 #include <stdlib.h>
 #include <string.h>
 #include <stdarg.h>
index ae76d24..87606bb 100644 (file)
@@ -18,8 +18,6 @@
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
-#include "config.h"
-
 #include <stdarg.h>
 #include <stdio.h>
 #include <string.h>
@@ -41,7 +39,6 @@
 #include "oleaut32_oaidl.h"
 
 #include "wine/debug.h"
-#include "wine/unicode.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(ole);
 WINE_DECLARE_DEBUG_CHANNEL(heap);
@@ -877,7 +874,7 @@ static HRESULT reg_get_typelib_module(REFIID iid, WCHAR *module, DWORD len)
     sprintf(typelibkey, "Typelib\\%s\\%s\\0\\win%u", tlguid, ver, sizeof(void *) == 8 ? 64 : 32);
 #else
     snprintf(typelibkey, sizeof(typelibkey), "Typelib\\%s\\%s\\0\\win%u", tlguid, ver, sizeof(void *) == 8 ? 64 : 32);
-#endif // __REACTOS__
+#endif /* __REACTOS__ */
     tlfnlen = sizeof(tlfn);
     if (RegQueryValueA(HKEY_CLASSES_ROOT, typelibkey, tlfn, &tlfnlen))
     {
@@ -927,7 +924,7 @@ static HRESULT get_typeinfo_for_iid(REFIID iid, ITypeInfo **typeinfo)
     return hr;
 }
 
-static HRESULT WINAPI typelib_ps_QueryInterface(IPSFactoryBuffer *iface, REFIID iid, void **out)
+static HRESULT WINAPI dispatch_typelib_ps_QueryInterface(IPSFactoryBuffer *iface, REFIID iid, void **out)
 {
     if (IsEqualIID(iid, &IID_IPSFactoryBuffer) || IsEqualIID(iid, &IID_IUnknown))
     {
@@ -940,135 +937,121 @@ static HRESULT WINAPI typelib_ps_QueryInterface(IPSFactoryBuffer *iface, REFIID
     return E_NOINTERFACE;
 }
 
-static ULONG WINAPI typelib_ps_AddRef(IPSFactoryBuffer *iface)
+static ULONG WINAPI dispatch_typelib_ps_AddRef(IPSFactoryBuffer *iface)
 {
     return 2;
 }
 
-static ULONG WINAPI typelib_ps_Release(IPSFactoryBuffer *iface)
+static ULONG WINAPI dispatch_typelib_ps_Release(IPSFactoryBuffer *iface)
 {
     return 1;
 }
 
-static HRESULT WINAPI typelib_ps_CreateProxy(IPSFactoryBuffer *iface,
-    IUnknown *outer, REFIID iid, IRpcProxyBuffer **proxy, void **out)
+static HRESULT dispatch_create_proxy(IUnknown *outer, IRpcProxyBuffer **proxy, void **out)
 {
-    ITypeInfo *typeinfo;
+    IPSFactoryBuffer *factory;
     HRESULT hr;
 
-    hr = get_typeinfo_for_iid(iid, &typeinfo);
+    hr = OLEAUTPS_DllGetClassObject(&CLSID_PSFactoryBuffer, &IID_IPSFactoryBuffer, (void **)&factory);
     if (FAILED(hr)) return hr;
 
-    hr = CreateProxyFromTypeInfo(typeinfo, outer, iid, proxy, out);
-    if (FAILED(hr))
-        ERR("Failed to create proxy, hr %#x.\n", hr);
-
-    ITypeInfo_Release(typeinfo);
+    hr = IPSFactoryBuffer_CreateProxy(factory, outer, &IID_IDispatch, proxy, out);
+    IPSFactoryBuffer_Release(factory);
     return hr;
 }
 
-static HRESULT WINAPI typelib_ps_CreateStub(IPSFactoryBuffer *iface, REFIID iid,
-    IUnknown *server, IRpcStubBuffer **stub)
+static HRESULT WINAPI dispatch_typelib_ps_CreateProxy(IPSFactoryBuffer *iface,
+    IUnknown *outer, REFIID iid, IRpcProxyBuffer **proxy, void **out)
 {
     ITypeInfo *typeinfo;
+    TYPEATTR *attr;
     HRESULT hr;
 
+    if (IsEqualGUID(iid, &IID_IDispatch))
+        return dispatch_create_proxy(outer, proxy, out);
+
     hr = get_typeinfo_for_iid(iid, &typeinfo);
     if (FAILED(hr)) return hr;
 
-    hr = CreateStubFromTypeInfo(typeinfo, iid, server, stub);
+    hr = ITypeInfo_GetTypeAttr(typeinfo, &attr);
     if (FAILED(hr))
-        ERR("Failed to create stub, hr %#x.\n", hr);
-
-    ITypeInfo_Release(typeinfo);
-    return hr;
-}
-
-static const IPSFactoryBufferVtbl typelib_ps_vtbl =
-{
-    typelib_ps_QueryInterface,
-    typelib_ps_AddRef,
-    typelib_ps_Release,
-    typelib_ps_CreateProxy,
-    typelib_ps_CreateStub,
-};
-
-static IPSFactoryBuffer typelib_ps = { &typelib_ps_vtbl };
-
-extern void _get_STDFONT_CF(LPVOID *);
-extern void _get_STDPIC_CF(LPVOID *);
-
-static HRESULT WINAPI PSDispatchFacBuf_QueryInterface(IPSFactoryBuffer *iface, REFIID riid, void **ppv)
-{
-    if (IsEqualIID(riid, &IID_IUnknown) ||
-        IsEqualIID(riid, &IID_IPSFactoryBuffer))
     {
-        IPSFactoryBuffer_AddRef(iface);
-        *ppv = iface;
-        return S_OK;
+        ITypeInfo_Release(typeinfo);
+        return hr;
     }
-    return E_NOINTERFACE;
-}
 
-static ULONG WINAPI PSDispatchFacBuf_AddRef(IPSFactoryBuffer *iface)
-{
-    return 2;
-}
+    if (attr->typekind == TKIND_INTERFACE || (attr->wTypeFlags & TYPEFLAG_FDUAL))
+        hr = CreateProxyFromTypeInfo(typeinfo, outer, iid, proxy, out);
+    else
+        hr = dispatch_create_proxy(outer, proxy, out);
 
-static ULONG WINAPI PSDispatchFacBuf_Release(IPSFactoryBuffer *iface)
-{
-    return 1;
+    if (FAILED(hr))
+        ERR("Failed to create proxy, hr %#x.\n", hr);
+
+    ITypeInfo_ReleaseTypeAttr(typeinfo, attr);
+    ITypeInfo_Release(typeinfo);
+    return hr;
 }
 
-static HRESULT WINAPI PSDispatchFacBuf_CreateProxy(IPSFactoryBuffer *iface,
-    IUnknown *outer, REFIID iid, IRpcProxyBuffer **proxy, void **obj)
+static HRESULT dispatch_create_stub(IUnknown *server, IRpcStubBuffer **stub)
 {
     IPSFactoryBuffer *factory;
     HRESULT hr;
 
-    if (IsEqualIID(iid, &IID_IDispatch))
-    {
-        hr = OLEAUTPS_DllGetClassObject(&CLSID_PSFactoryBuffer, &IID_IPSFactoryBuffer, (void **)&factory);
-        if (FAILED(hr)) return hr;
+    hr = OLEAUTPS_DllGetClassObject(&CLSID_PSFactoryBuffer, &IID_IPSFactoryBuffer, (void **)&factory);
+    if (FAILED(hr)) return hr;
 
-        hr = IPSFactoryBuffer_CreateProxy(factory, outer, iid, proxy, obj);
-        IPSFactoryBuffer_Release(factory);
-        return hr;
-    }
-    else
-        return IPSFactoryBuffer_CreateProxy(&typelib_ps, outer, iid, proxy, obj);
+    hr = IPSFactoryBuffer_CreateStub(factory, &IID_IDispatch, server, stub);
+    IPSFactoryBuffer_Release(factory);
+    return hr;
 }
 
-static HRESULT WINAPI PSDispatchFacBuf_CreateStub(IPSFactoryBuffer *iface,
+static HRESULT WINAPI dispatch_typelib_ps_CreateStub(IPSFactoryBuffer *iface,
     REFIID iid, IUnknown *server, IRpcStubBuffer **stub)
 {
-    IPSFactoryBuffer *factory;
+    ITypeInfo *typeinfo;
+    TYPEATTR *attr;
     HRESULT hr;
 
-    if (IsEqualIID(iid, &IID_IDispatch))
-    {
-        hr = OLEAUTPS_DllGetClassObject(&CLSID_PSFactoryBuffer, &IID_IPSFactoryBuffer, (void **)&factory);
-        if (FAILED(hr)) return hr;
+    if (IsEqualGUID(iid, &IID_IDispatch))
+        return dispatch_create_stub(server, stub);
+
+    hr = get_typeinfo_for_iid(iid, &typeinfo);
+    if (FAILED(hr)) return hr;
 
-        hr = IPSFactoryBuffer_CreateStub(factory, iid, server, stub);
-        IPSFactoryBuffer_Release(factory);
+    hr = ITypeInfo_GetTypeAttr(typeinfo, &attr);
+    if (FAILED(hr))
+    {
+        ITypeInfo_Release(typeinfo);
         return hr;
     }
+
+    if (attr->typekind == TKIND_INTERFACE || (attr->wTypeFlags & TYPEFLAG_FDUAL))
+        hr = CreateStubFromTypeInfo(typeinfo, iid, server, stub);
     else
-        return IPSFactoryBuffer_CreateStub(&typelib_ps, iid, server, stub);
+        hr = dispatch_create_stub(server, stub);
+
+    if (FAILED(hr))
+        ERR("Failed to create proxy, hr %#x.\n", hr);
+
+    ITypeInfo_ReleaseTypeAttr(typeinfo, attr);
+    ITypeInfo_Release(typeinfo);
+    return hr;
 }
 
-static const IPSFactoryBufferVtbl PSDispatchFacBuf_Vtbl =
+static const IPSFactoryBufferVtbl dispatch_typelib_ps_vtbl =
 {
-    PSDispatchFacBuf_QueryInterface,
-    PSDispatchFacBuf_AddRef,
-    PSDispatchFacBuf_Release,
-    PSDispatchFacBuf_CreateProxy,
-    PSDispatchFacBuf_CreateStub
+    dispatch_typelib_ps_QueryInterface,
+    dispatch_typelib_ps_AddRef,
+    dispatch_typelib_ps_Release,
+    dispatch_typelib_ps_CreateProxy,
+    dispatch_typelib_ps_CreateStub,
 };
 
-/* This is the whole PSFactoryBuffer object, just the vtableptr */
-static const IPSFactoryBufferVtbl *pPSDispatchFacBuf = &PSDispatchFacBuf_Vtbl;
+static IPSFactoryBuffer dispatch_typelib_ps = { &dispatch_typelib_ps_vtbl };
+
+extern void _get_STDFONT_CF(LPVOID *);
+extern void _get_STDPIC_CF(LPVOID *);
 
 /***********************************************************************
  *             DllGetClassObject (OLEAUT32.@)
@@ -1090,14 +1073,9 @@ HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID iid, LPVOID *ppv)
            return S_OK;
        }
     }
-    if (IsEqualCLSID(rclsid, &CLSID_PSDispatch) && IsEqualIID(iid, &IID_IPSFactoryBuffer)) {
-        *ppv = &pPSDispatchFacBuf;
-        IPSFactoryBuffer_AddRef((IPSFactoryBuffer *)*ppv);
-        return S_OK;
-    }
 
-    if (IsEqualGUID(rclsid, &CLSID_PSOAInterface))
-        return IPSFactoryBuffer_QueryInterface(&typelib_ps, iid, ppv);
+    if (IsEqualGUID(rclsid, &CLSID_PSDispatch) || IsEqualGUID(rclsid, &CLSID_PSOAInterface))
+        return IPSFactoryBuffer_QueryInterface(&dispatch_typelib_ps, iid, ppv);
 
     if (IsEqualCLSID(rclsid, &CLSID_PSTypeComp) ||
         IsEqualCLSID(rclsid, &CLSID_PSTypeInfo) ||
index 9628dc0..b82ffbf 100644 (file)
@@ -35,7 +35,6 @@
 #include "wingdi.h"
 #include "winuser.h"
 #include "wine/list.h"
-#include "wine/unicode.h"
 #include "objbase.h"
 #include "oleauto.h"    /* for SysAllocString(....) */
 #include "ole2.h"
@@ -230,7 +229,7 @@ static HRESULT dec_ext_ref(HFONT hfont)
 static WCHAR *strdupW(const WCHAR* str)
 {
     WCHAR *ret;
-    DWORD size = (strlenW(str) + 1) * sizeof(WCHAR);
+    DWORD size = (lstrlenW(str) + 1) * sizeof(WCHAR);
 
     ret = HeapAlloc(GetProcessHeap(), 0, size);
     if(ret)
@@ -1063,8 +1062,8 @@ static HRESULT WINAPI OLEFontImpl_IsEqual(
     return S_FALSE;
 
   /* Check from string */
-  left_len = strlenW(left->description.lpstrName);
-  right_len = strlenW(right->description.lpstrName);
+  left_len = lstrlenW(left->description.lpstrName);
+  right_len = lstrlenW(right->description.lpstrName);
   ret = CompareStringW(0,0,left->description.lpstrName, left_len,
     right->description.lpstrName, right_len);
   if (ret != CSTR_EQUAL)
@@ -1727,7 +1726,7 @@ static HRESULT WINAPI OLEFontImpl_Save(
   /* FontName */
   if (this->description.lpstrName)
     string_size = WideCharToMultiByte( CP_ACP, 0, this->description.lpstrName,
-                                       strlenW(this->description.lpstrName), NULL, 0, NULL, NULL );
+                                       lstrlenW(this->description.lpstrName), NULL, 0, NULL, NULL );
   else
     string_size = 0;
 
@@ -1738,7 +1737,7 @@ static HRESULT WINAPI OLEFontImpl_Save(
   {
       if (!(writeBuffer = HeapAlloc( GetProcessHeap(), 0, string_size ))) return E_OUTOFMEMORY;
       WideCharToMultiByte( CP_ACP, 0, this->description.lpstrName,
-                           strlenW(this->description.lpstrName),
+                           lstrlenW(this->description.lpstrName),
                            writeBuffer, string_size, NULL, NULL );
 
       IStream_Write(pOutStream, writeBuffer, string_size, &written);
@@ -1774,7 +1773,7 @@ static HRESULT WINAPI OLEFontImpl_GetSizeMax(
 
   if (this->description.lpstrName!=0)
       pcbSize->u.LowPart += WideCharToMultiByte( CP_ACP, 0, this->description.lpstrName,
-                                                 strlenW(this->description.lpstrName),
+                                                 lstrlenW(this->description.lpstrName),
                                                  NULL, 0, NULL, NULL );
 
   return S_OK;
index 702fcde..05dd10b 100644 (file)
  *
  */
 
-#include "config.h"
-#include "wine/port.h"
-
-#ifdef HAVE_UNISTD_H
-# include <unistd.h>
-#endif
 #include <stdarg.h>
 #include <stdio.h>
 #include <string.h>
@@ -62,8 +56,6 @@
 #include "initguid.h"
 #include "wincodec.h"
 #include "wine/debug.h"
-#include "wine/unicode.h"
-#include "wine/library.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(olepicture);
 
@@ -2522,7 +2514,7 @@ HRESULT WINAPI OleLoadPicturePath( LPOLESTR szURLorPath, LPUNKNOWN punkCaller,
   *ppvRet = NULL;
 
   /* Convert file URLs to DOS paths. */
-  if (strncmpW(szURLorPath, file, 5) == 0) {
+  if (wcsncmp(szURLorPath, file, 5) == 0) {
       DWORD size;
       hRes = CoInternetParseUrl(szURLorPath, PARSE_PATH_FROM_URL, 0, path_buf,
                                 ARRAY_SIZE(path_buf), &size, 0);
index c5d3cb1..4e80f66 100644 (file)
@@ -2,8 +2,6 @@
 #ifndef _OLEAUT32_PCH_
 #define _OLEAUT32_PCH_
 
-#include <config.h>
-
 #include <stdarg.h>
 #include <stdio.h>
 
 #include <winbase.h>
 #include <wingdi.h>
 #include <winreg.h>
+#include <winnls.h>
 #include <ole2.h>
 #include <olectl.h>
 
 #include <wine/debug.h>
 #include <wine/list.h>
-#include <wine/unicode.h>
 
 #include "connpt.h"
 #include "variant.h"
index ec65a52..44d4659 100644 (file)
@@ -28,7 +28,6 @@
 #include "oleauto.h"
 #include "variant.h"
 
-#include "wine/unicode.h"
 #include "wine/debug.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(ole);
@@ -402,7 +401,7 @@ static HRESULT WINAPI IRecordInfoImpl_GetField(IRecordInfo *iface, PVOID pvData,
         return E_INVALIDARG;
 
     for(i=0; i<This->n_vars; i++)
-        if(!strcmpW(This->fields[i].name, szFieldName))
+        if(!wcscmp(This->fields[i].name, szFieldName))
             break;
     if(i == This->n_vars)
         return TYPE_E_FIELDNOTFOUND;
@@ -424,7 +423,7 @@ static HRESULT WINAPI IRecordInfoImpl_GetFieldNoCopy(IRecordInfo *iface, PVOID p
         return E_INVALIDARG;
 
     for(i=0; i<This->n_vars; i++)
-        if(!strcmpW(This->fields[i].name, szFieldName))
+        if(!wcscmp(This->fields[i].name, szFieldName))
             break;
     if(i == This->n_vars)
         return TYPE_E_FIELDNOTFOUND;
@@ -455,7 +454,7 @@ static HRESULT WINAPI IRecordInfoImpl_PutField(IRecordInfo *iface, ULONG wFlags,
     }
 
     for(i=0; i<This->n_vars; i++)
-        if(!strcmpW(This->fields[i].name, szFieldName))
+        if(!wcscmp(This->fields[i].name, szFieldName))
             break;
     if(i == This->n_vars)
         return TYPE_E_FIELDNOTFOUND;
@@ -477,7 +476,7 @@ static HRESULT WINAPI IRecordInfoImpl_PutFieldNoCopy(IRecordInfo *iface, ULONG w
         return E_INVALIDARG;
 
     for(i=0; i<This->n_vars; i++)
-        if(!strcmpW(This->fields[i].name, szFieldName))
+        if(!wcscmp(This->fields[i].name, szFieldName))
             break;
     if(i == This->n_vars)
         return TYPE_E_FIELDNOTFOUND;
index 64a5ab9..0b76935 100644 (file)
@@ -31,8 +31,6 @@
  *  0x10: SAFEARRAYBOUNDS[0...]
  */
 
-#include "config.h"
-
 #include <string.h>
 #include <stdarg.h>
 #include <stdio.h>
@@ -525,8 +523,8 @@ HRESULT WINAPI SafeArrayAllocDescriptorEx(VARTYPE vt, UINT cDims, SAFEARRAY **pp
   ULONG cbElements;
   HRESULT hRet;
 
-  TRACE("(%d->%s,%d,%p)\n", vt, debugstr_vt(vt), cDims, ppsaOut);
-    
+  TRACE("(%s,%u,%p)\n", debugstr_vt(vt), cDims, ppsaOut);
+
   cbElements = SAFEARRAY_GetVTSize(vt);
   if (!cbElements)
     WARN("Creating a descriptor with an invalid VARTYPE!\n");
@@ -601,7 +599,7 @@ HRESULT WINAPI SafeArrayAllocData(SAFEARRAY *psa)
  */
 SAFEARRAY* WINAPI SafeArrayCreate(VARTYPE vt, UINT cDims, SAFEARRAYBOUND *rgsabound)
 {
-  TRACE("(%d->%s,%d,%p)\n", vt, debugstr_vt(vt), cDims, rgsabound);
+  TRACE("(%s,%u,%p)\n", debugstr_vt(vt), cDims, rgsabound);
 
   if (vt == VT_RECORD)
     return NULL;
@@ -633,7 +631,7 @@ SAFEARRAY* WINAPI SafeArrayCreateEx(VARTYPE vt, UINT cDims, SAFEARRAYBOUND *rgsa
   IRecordInfo* iRecInfo = pvExtra;
   SAFEARRAY* psa;
  
-  TRACE("(%d->%s,%d,%p,%p)\n", vt, debugstr_vt(vt), cDims, rgsabound, pvExtra);
+  TRACE("(%s,%u,%p,%p)\n", debugstr_vt(vt), cDims, rgsabound, pvExtra);
  
   if (vt == VT_RECORD)
   {
@@ -678,8 +676,8 @@ SAFEARRAY* WINAPI SafeArrayCreateEx(VARTYPE vt, UINT cDims, SAFEARRAYBOUND *rgsa
  */
 SAFEARRAY* WINAPI SafeArrayCreateVector(VARTYPE vt, LONG lLbound, ULONG cElements)
 {
-  TRACE("(%d->%s,%d,%d\n", vt, debugstr_vt(vt), lLbound, cElements);
-    
+  TRACE("(%s,%d,%u)\n", debugstr_vt(vt), lLbound, cElements);
+
   if (vt == VT_RECORD)
     return NULL;
 
@@ -710,8 +708,8 @@ SAFEARRAY* WINAPI SafeArrayCreateVectorEx(VARTYPE vt, LONG lLbound, ULONG cEleme
   IRecordInfo* iRecInfo = pvExtra;
   SAFEARRAY* psa;
 
TRACE("(%d->%s,%d,%d,%p\n", vt, debugstr_vt(vt), lLbound, cElements, pvExtra);
 TRACE("(%s,%d,%u,%p)\n", debugstr_vt(vt), lLbound, cElements, pvExtra);
+
   if (vt == VT_RECORD)
   {
     if  (!iRecInfo)
index 6ed9ce9..76e5e7f 100644 (file)
@@ -47,9 +47,6 @@
  *
  */
 
-#include "config.h"
-#include "wine/port.h"
-
 #include <stdlib.h>
 #include <string.h>
 #include <stdarg.h>
 #include "winternl.h"
 #include "lzexpand.h"
 
-#include "wine/unicode.h"
 #include "objbase.h"
 #include "typelib.h"
 #include "wine/debug.h"
 #include "variant.h"
+#include "wine/asm.h"
 #include "wine/heap.h"
 #include "wine/list.h"
 
@@ -182,7 +179,7 @@ static BOOL find_typelib_key( REFGUID guid, WORD *wMaj, WORD *wMin )
     HKEY hkey;
 
     memcpy( buffer, typelibW, sizeof(typelibW) );
-    StringFromGUID2( guid, buffer + strlenW(buffer), 40 );
+    StringFromGUID2( guid, buffer + lstrlenW(buffer), 40 );
 
     if (RegOpenKeyExW( HKEY_CLASSES_ROOT, buffer, 0, KEY_READ, &hkey ) != ERROR_SUCCESS)
         return FALSE;
@@ -246,8 +243,8 @@ static WCHAR *get_typelib_key( REFGUID guid, WORD wMaj, WORD wMin, WCHAR *buffer
     static const WCHAR VersionFormatW[] = {'\\','%','x','.','%','x',0};
 
     memcpy( buffer, TypelibW, sizeof(TypelibW) );
-    StringFromGUID2( guid, buffer + strlenW(buffer), 40 );
-    sprintfW( buffer + strlenW(buffer), VersionFormatW, wMaj, wMin );
+    StringFromGUID2( guid, buffer + lstrlenW(buffer), 40 );
+    swprintf( buffer + lstrlenW(buffer), VersionFormatW, wMaj, wMin );
     return buffer;
 }
 
@@ -258,7 +255,7 @@ static WCHAR *get_interface_key( REFGUID guid, WCHAR *buffer )
     static const WCHAR InterfaceW[] = {'I','n','t','e','r','f','a','c','e','\\',0};
 
     memcpy( buffer, InterfaceW, sizeof(InterfaceW) );
-    StringFromGUID2( guid, buffer + strlenW(buffer), 40 );
+    StringFromGUID2( guid, buffer + lstrlenW(buffer), 40 );
     return buffer;
 }
 
@@ -271,12 +268,12 @@ static WCHAR *get_lcid_subkey( LCID lcid, SYSKIND syskind, WCHAR *buffer )
     static const WCHAR win32W[] = {'w','i','n','3','2',0};
     static const WCHAR win64W[] = {'w','i','n','6','4',0};
 
-    sprintfW( buffer, LcidFormatW, lcid );
+    swprintf( buffer, LcidFormatW, lcid );
     switch(syskind)
     {
-    case SYS_WIN16: strcatW( buffer, win16W ); break;
-    case SYS_WIN32: strcatW( buffer, win32W ); break;
-    case SYS_WIN64: strcatW( buffer, win64W ); break;
+    case SYS_WIN16: lstrcatW( buffer, win16W ); break;
+    case SYS_WIN32: lstrcatW( buffer, win32W ); break;
+    case SYS_WIN64: lstrcatW( buffer, win64W ); break;
     default:
         TRACE("Typelib is for unsupported syskind %i\n", syskind);
         return NULL;
@@ -588,29 +585,39 @@ static void TLB_register_interface(TLIBATTR *libattr, LPOLESTR name, TYPEATTR *t
     WCHAR keyName[60];
     HKEY key, subKey;
 
-    static const WCHAR PSOA[] = {'{','0','0','0','2','0','4','2','4','-',
-                                 '0','0','0','0','-','0','0','0','0','-','C','0','0','0','-',
-                                 '0','0','0','0','0','0','0','0','0','0','4','6','}',0};
+    static const WCHAR typelib_proxy_clsid[] = {'{','0','0','0','2','0','4','2','4','-',
+            '0','0','0','0','-','0','0','0','0','-','C','0','0','0','-',
+            '0','0','0','0','0','0','0','0','0','0','4','6','}',0};
+    static const WCHAR dispatch_proxy_clsid[] = {'{','0','0','0','2','0','4','2','0','-',
+            '0','0','0','0','-','0','0','0','0','-','C','0','0','0','-',
+            '0','0','0','0','0','0','0','0','0','0','4','6','}',0};
 
     get_interface_key( &tattr->guid, keyName );
     if (RegCreateKeyExW(HKEY_CLASSES_ROOT, keyName, 0, NULL, 0,
                         KEY_WRITE | flag, NULL, &key, NULL) == ERROR_SUCCESS)
     {
+        const WCHAR *proxy_clsid;
+
+        if (tattr->typekind == TKIND_INTERFACE || (tattr->wTypeFlags & TYPEFLAG_FDUAL))
+            proxy_clsid = typelib_proxy_clsid;
+        else
+            proxy_clsid = dispatch_proxy_clsid;
+
         if (name)
             RegSetValueExW(key, NULL, 0, REG_SZ,
-                           (BYTE *)name, (strlenW(name)+1) * sizeof(OLECHAR));
+                           (BYTE *)name, (lstrlenW(name)+1) * sizeof(OLECHAR));
 
         if (RegCreateKeyExW(key, ProxyStubClsidW, 0, NULL, 0,
             KEY_WRITE | flag, NULL, &subKey, NULL) == ERROR_SUCCESS) {
             RegSetValueExW(subKey, NULL, 0, REG_SZ,
-                           (const BYTE *)PSOA, sizeof PSOA);
+                           (const BYTE *)proxy_clsid, sizeof(typelib_proxy_clsid));
             RegCloseKey(subKey);
         }
 
         if (RegCreateKeyExW(key, ProxyStubClsid32W, 0, NULL, 0,
             KEY_WRITE | flag, NULL, &subKey, NULL) == ERROR_SUCCESS) {
             RegSetValueExW(subKey, NULL, 0, REG_SZ,
-                           (const BYTE *)PSOA, sizeof PSOA);
+                           (const BYTE *)proxy_clsid, sizeof(typelib_proxy_clsid));
             RegCloseKey(subKey);
         }
 
@@ -623,10 +630,10 @@ static void TLB_register_interface(TLIBATTR *libattr, LPOLESTR name, TYPEATTR *t
 
             StringFromGUID2(&libattr->guid, buffer, 40);
             RegSetValueExW(subKey, NULL, 0, REG_SZ,
-                           (BYTE *)buffer, (strlenW(buffer)+1) * sizeof(WCHAR));
-            sprintfW(buffer, fmtver, libattr->wMajorVerNum, libattr->wMinorVerNum);
+                           (BYTE *)buffer, (lstrlenW(buffer)+1) * sizeof(WCHAR));
+            swprintf(buffer, fmtver, libattr->wMajorVerNum, libattr->wMinorVerNum);
             RegSetValueExW(subKey, VersionW, 0, REG_SZ,
-                           (BYTE*)buffer, (strlenW(buffer)+1) * sizeof(WCHAR));
+                           (BYTE*)buffer, (lstrlenW(buffer)+1) * sizeof(WCHAR));
             RegCloseKey(subKey);
         }
 
@@ -646,11 +653,7 @@ static void TLB_register_interface(TLIBATTR *libattr, LPOLESTR name, TYPEATTR *t
  *    Success: S_OK
  *    Failure: Status
  */
-HRESULT WINAPI RegisterTypeLib(
-     ITypeLib * ptlib,     /* [in] Pointer to the library*/
-     OLECHAR * szFullPath, /* [in] full Path of the library*/
-     OLECHAR * szHelpDir)  /* [in] dir to the helpfile for the library,
-                                                        may be NULL*/
+HRESULT WINAPI RegisterTypeLib(ITypeLib *ptlib, const WCHAR *szFullPath, const WCHAR *szHelpDir)
 {
     HRESULT res;
     TLIBATTR *attr;
@@ -714,9 +717,9 @@ HRESULT WINAPI RegisterTypeLib(
             /* FIXME: is %u correct? */
             static const WCHAR formatW[] = {'%','u',0};
             WCHAR buf[20];
-            sprintfW(buf, formatW, attr->wLibFlags);
+            swprintf(buf, formatW, attr->wLibFlags);
             if (RegSetValueExW(subKey, NULL, 0, REG_SZ,
-                               (BYTE *)buf, (strlenW(buf) + 1)*sizeof(WCHAR) ) != ERROR_SUCCESS)
+                               (BYTE *)buf, (lstrlenW(buf) + 1)*sizeof(WCHAR) ) != ERROR_SUCCESS)
                 res = E_FAIL;
 
             RegCloseKey(subKey);
@@ -728,19 +731,18 @@ HRESULT WINAPI RegisterTypeLib(
         if (res == S_OK && RegCreateKeyExW(key, HELPDIRW, 0, NULL, 0,
             KEY_WRITE, NULL, &subKey, &disposition) == ERROR_SUCCESS)
         {
-            BOOL freeHelpDir = FALSE;
+            BSTR freeHelpDir = NULL;
             OLECHAR* pIndexStr;
 
             /* if we created a new key, and helpDir was null, set the helpdir
                to the directory which contains the typelib. However,
                if we just opened an existing key, we leave the helpdir alone */
             if ((disposition == REG_CREATED_NEW_KEY) && (szHelpDir == NULL)) {
-                szHelpDir = SysAllocString(szFullPath);
-                pIndexStr = strrchrW(szHelpDir, '\\');
+                szHelpDir = freeHelpDir = SysAllocString(szFullPath);
+                pIndexStr = wcsrchr(szHelpDir, '\\');
                 if (pIndexStr) {
                     *pIndexStr = 0;
                 }
-                freeHelpDir = TRUE;
             }
 
             /* if we have an szHelpDir, set it! */
@@ -751,10 +753,8 @@ HRESULT WINAPI RegisterTypeLib(
                 }
             }
 
-            /* tidy up */
-            if (freeHelpDir) SysFreeString(szHelpDir);
+            SysFreeString(freeHelpDir);
             RegCloseKey(subKey);
-
         } else {
             res = E_FAIL;
         }
@@ -974,7 +974,7 @@ enddeleteloop:
     /* Now, delete the type library path subkey */
     get_lcid_subkey( lcid, syskind, subKeyName );
     RegDeleteKeyW(key, subKeyName);
-    *strrchrW( subKeyName, '\\' ) = 0;  /* remove last path component */
+    *wcsrchr( subKeyName, '\\' ) = 0;  /* remove last path component */
     RegDeleteKeyW(key, subKeyName);
 
     /* check if there is anything besides the FLAGS/HELPDIR keys.
@@ -986,8 +986,8 @@ enddeleteloop:
         tmpLength = ARRAY_SIZE(subKeyName);
 
         /* if its not FLAGS or HELPDIR, then we must keep the rest of the key */
-        if (!strcmpW(subKeyName, FLAGSW)) continue;
-        if (!strcmpW(subKeyName, HELPDIRW)) continue;
+        if (!wcscmp(subKeyName, FLAGSW)) continue;
+        if (!wcscmp(subKeyName, HELPDIRW)) continue;
         deleteOtherStuff = FALSE;
         break;
     }
@@ -1000,7 +1000,7 @@ enddeleteloop:
         key = NULL;
 
         RegDeleteKeyW(HKEY_CLASSES_ROOT, keyName);
-        *strrchrW( keyName, '\\' ) = 0;  /* remove last path component */
+        *wcsrchr( keyName, '\\' ) = 0;  /* remove last path component */
         RegDeleteKeyW(HKEY_CLASSES_ROOT, keyName);
     }
 
@@ -1889,7 +1889,7 @@ static TLBString *TLB_append_str(struct list *string_list, BSTR new_str)
         return NULL;
 
     LIST_FOR_EACH_ENTRY(str, string_list, TLBString, entry) {
-        if (strcmpW(str->str, new_str) == 0)
+        if (wcscmp(str->str, new_str) == 0)
             return str;
     }
 
@@ -3090,7 +3090,7 @@ static BOOL find_ne_resource( HFILE lzfd, LPCSTR typeid, LPCSTR resid,
             if (!(typeInfo->type_id & 0x8000))
             {
                 BYTE *p = resTab + typeInfo->type_id;
-                if ((*p == len) && !strncasecmp( (char*)p+1, typeid, len )) goto found_type;
+                if ((*p == len) && !_strnicmp( (char*)p+1, typeid, len )) goto found_type;
             }
             typeInfo = (NE_TYPEINFO *)((char *)(typeInfo + 1) +
                                        typeInfo->count * sizeof(NE_NAMEINFO));
@@ -3120,7 +3120,7 @@ static BOOL find_ne_resource( HFILE lzfd, LPCSTR typeid, LPCSTR resid,
         {
             BYTE *p = resTab + nameInfo->id;
             if (nameInfo->id & 0x8000) continue;
-            if ((*p == len) && !strncasecmp( (char*)p+1, resid, len )) goto found_name;
+            if ((*p == len) && !_strnicmp( (char*)p+1, resid, len )) goto found_name;
         }
     }
     else  /* numeric resource id */
@@ -3296,11 +3296,11 @@ static HRESULT TLB_ReadTypeLib(LPCWSTR pszFileName, LPWSTR pszPath, UINT cchPath
 
     *ppTypeLib = NULL;
 
-    index_str = strrchrW(pszFileName, '\\');
+    index_str = wcsrchr(pszFileName, '\\');
     if(index_str && *++index_str != '\0')
     {
         LPWSTR end_ptr;
-        LONG idx = strtolW(index_str, &end_ptr, 10);
+        LONG idx = wcstol(index_str, &end_ptr, 10);
         if(*end_ptr == '\0')
         {
             int str_len = index_str - pszFileName - 1;
@@ -3313,7 +3313,7 @@ static HRESULT TLB_ReadTypeLib(LPCWSTR pszFileName, LPWSTR pszPath, UINT cchPath
 
     if(!SearchPathW(NULL, file, NULL, cchPath, pszPath, NULL))
     {
-        if(strchrW(file, '\\'))
+        if(wcschr(file, '\\'))
         {
             lstrcpyW(pszPath, file);
         }
@@ -3321,7 +3321,7 @@ static HRESULT TLB_ReadTypeLib(LPCWSTR pszFileName, LPWSTR pszPath, UINT cchPath
         {
             int len = GetSystemDirectoryW(pszPath, cchPath);
             pszPath[len] = '\\';
-            memcpy(pszPath + len + 1, file, (strlenW(file) + 1) * sizeof(WCHAR));
+            memcpy(pszPath + len + 1, file, (lstrlenW(file) + 1) * sizeof(WCHAR));
         }
     }
 
@@ -3359,7 +3359,7 @@ static HRESULT TLB_ReadTypeLib(LPCWSTR pszFileName, LPWSTR pszPath, UINT cchPath
     EnterCriticalSection(&cache_section);
     LIST_FOR_EACH_ENTRY(entry, &tlb_cache, ITypeLibImpl, entry)
     {
-        if (!strcmpiW(entry->path, pszPath) && entry->index == index)
+        if (!wcsicmp(entry->path, pszPath) && entry->index == index)
         {
             TRACE("cache hit\n");
             *ppTypeLib = &entry->ITypeLib2_iface;
@@ -3401,7 +3401,7 @@ static HRESULT TLB_ReadTypeLib(LPCWSTR pszFileName, LPWSTR pszPath, UINT cchPath
        ITypeLibImpl *impl = impl_from_ITypeLib2(*ppTypeLib);
 
        TRACE("adding to cache\n");
-       impl->path = heap_alloc((strlenW(pszPath)+1) * sizeof(WCHAR));
+       impl->path = heap_alloc((lstrlenW(pszPath)+1) * sizeof(WCHAR));
        lstrcpyW(impl->path, pszPath);
        /* We should really canonicalise the path here. */
         impl->index = index;
@@ -3764,8 +3764,8 @@ static const TLBString *decode_string(const BYTE *table, const char *stream, DWO
     while ((p = lookup_code(table, table_size, &bits)))
     {
         static const WCHAR spaceW[] = { ' ',0 };
-        if (buf[0]) strcatW(buf, spaceW);
-        MultiByteToWideChar(CP_ACP, 0, p, -1, buf + strlenW(buf), buf_size - strlenW(buf));
+        if (buf[0]) lstrcatW(buf, spaceW);
+        MultiByteToWideChar(CP_ACP, 0, p, -1, buf + lstrlenW(buf), buf_size - lstrlenW(buf));
     }
 
     tlbstr = TLB_append_str(&lib->string_list, buf);
@@ -5468,7 +5468,7 @@ static HRESULT WINAPI ITypeLibComp_fnBind(
         if ((pTypeInfo->typeattr.typekind == TKIND_ENUM) ||
             (pTypeInfo->typeattr.typekind == TKIND_MODULE))
         {
-            if (pTypeInfo->Name && !strcmpW(pTypeInfo->Name->str, szName))
+            if (pTypeInfo->Name && !wcscmp(pTypeInfo->Name->str, szName))
             {
                 *pDescKind = DESCKIND_TYPECOMP;
                 pBindPtr->lptcomp = &pTypeInfo->ITypeComp_iface;
@@ -6114,7 +6114,7 @@ static HRESULT TLB_AllocAndInitVarDesc( const VARDESC *src, VARDESC **dest_ptr )
     SIZE_T size = sizeof(*src);
     HRESULT hr;
 
-    if (src->lpstrSchema) size += (strlenW(src->lpstrSchema) + 1) * sizeof(WCHAR);
+    if (src->lpstrSchema) size += (lstrlenW(src->lpstrSchema) + 1) * sizeof(WCHAR);
     if (src->varkind == VAR_CONST)
         size += sizeof(VARIANT);
     size += TLB_SizeElemDesc(&src->elemdescVar);
@@ -6128,7 +6128,7 @@ static HRESULT TLB_AllocAndInitVarDesc( const VARDESC *src, VARDESC **dest_ptr )
     {
         int len;
         dest->lpstrSchema = (LPOLESTR)buffer;
-        len = strlenW(src->lpstrSchema);
+        len = lstrlenW(src->lpstrSchema);
         memcpy(dest->lpstrSchema, src->lpstrSchema, (len + 1) * sizeof(WCHAR));
         buffer += (len + 1) * sizeof(WCHAR);
     }
@@ -6443,20 +6443,133 @@ __ASM_GLOBAL_FUNC( call_method,
 __ASM_GLOBAL_FUNC( call_double_method,
                    "jmp " __ASM_NAME("call_method") )
 
+HRESULT WINAPI DispCallFunc( void* pvInstance, ULONG_PTR oVft, CALLCONV cc, VARTYPE vtReturn,
+                             UINT cActuals, VARTYPE* prgvt, VARIANTARG** prgpvarg, VARIANT* pvargResult )
+{
+    int argspos = 0, stack_offset;
+    void *func;
+    UINT i;
+    DWORD *args;
+
+    TRACE("(%p, %ld, %d, %d, %d, %p, %p, %p (vt=%d))\n",
+        pvInstance, oVft, cc, vtReturn, cActuals, prgvt, prgpvarg,
+        pvargResult, V_VT(pvargResult));
+
+    if (cc != CC_STDCALL && cc != CC_CDECL)
+    {
+        FIXME("unsupported calling convention %d\n",cc);
+        return E_INVALIDARG;
+    }
+
+    /* maximum size for an argument is sizeof(VARIANT) */
+    args = heap_alloc(sizeof(VARIANT) * cActuals + sizeof(DWORD) * 2 );
+
+    if (pvInstance)
+    {
+        const FARPROC *vtable = *(FARPROC **)pvInstance;
+        func = vtable[oVft/sizeof(void *)];
+        args[argspos++] = (DWORD)pvInstance; /* the This pointer is always the first parameter */
+    }
+    else func = (void *)oVft;
+
+    switch (vtReturn)
+    {
+    case VT_DECIMAL:
+    case VT_VARIANT:
+        args[argspos++] = (DWORD)pvargResult;  /* arg 0 is a pointer to the result */
+        break;
+    case VT_HRESULT:
+        WARN("invalid return type %u\n", vtReturn);
+        heap_free( args );
+        return E_INVALIDARG;
+    default:
+        break;
+    }
+
+    for (i = 0; i < cActuals; i++)
+    {
+        VARIANT *arg = prgpvarg[i];
+
+        switch (prgvt[i])
+        {
+        case VT_EMPTY:
+            break;
+        case VT_I8:
+        case VT_UI8:
+        case VT_R8:
+        case VT_DATE:
+        case VT_CY:
+            memcpy( &args[argspos], &V_I8(arg), sizeof(V_I8(arg)) );
+            argspos += sizeof(V_I8(arg)) / sizeof(DWORD);
+            break;
+        case VT_DECIMAL:
+        case VT_VARIANT:
+            memcpy( &args[argspos], arg, sizeof(*arg) );
+            argspos += sizeof(*arg) / sizeof(DWORD);
+            break;
+        case VT_BOOL:  /* VT_BOOL is 16-bit but BOOL is 32-bit, needs to be extended */
+            args[argspos++] = V_BOOL(arg);
+            break;
+        default:
+            args[argspos++] = V_UI4(arg);
+            break;
+        }
+        TRACE("arg %u: type %s %s\n", i, debugstr_vt(prgvt[i]), debugstr_variant(arg));
+    }
+
+    switch (vtReturn)
+    {
+    case VT_EMPTY:
+    case VT_DECIMAL:
+    case VT_VARIANT:
+        call_method( func, argspos, args, &stack_offset );
+        break;
+    case VT_R4:
+        V_R4(pvargResult) = call_double_method( func, argspos, args, &stack_offset );
+        break;
+    case VT_R8:
+    case VT_DATE:
+        V_R8(pvargResult) = call_double_method( func, argspos, args, &stack_offset );
+        break;
+    case VT_I8:
+    case VT_UI8:
+    case VT_CY:
+        V_UI8(pvargResult) = call_method( func, argspos, args, &stack_offset );
+        break;
+    default:
+        V_UI4(pvargResult) = call_method( func, argspos, args, &stack_offset );
+        break;
+    }
+    heap_free( args );
+    if (stack_offset && cc == CC_STDCALL)
+    {
+        WARN( "stack pointer off by %d\n", stack_offset );
+        return DISP_E_BADCALLEE;
+    }
+    if (vtReturn != VT_VARIANT) V_VT(pvargResult) = vtReturn;
+    TRACE("retval: %s\n", debugstr_variant(pvargResult));
+    return S_OK;
+}
+
 #elif defined(__x86_64__)
 
 extern DWORD_PTR CDECL call_method( void *func, int nb_args, const DWORD_PTR *args );
 extern double CDECL call_double_method( void *func, int nb_args, const DWORD_PTR *args );
 __ASM_GLOBAL_FUNC( call_method,
                    "pushq %rbp\n\t"
+                   __ASM_SEH(".seh_pushreg %rbp\n\t")
                    __ASM_CFI(".cfi_adjust_cfa_offset 8\n\t")
                    __ASM_CFI(".cfi_rel_offset %rbp,0\n\t")
                    "movq %rsp,%rbp\n\t"
+                   __ASM_SEH(".seh_setframe %rbp,0\n\t")
                    __ASM_CFI(".cfi_def_cfa_register %rbp\n\t")
                    "pushq %rsi\n\t"
+                   __ASM_SEH(".seh_pushreg %rsi\n\t")
                    __ASM_CFI(".cfi_rel_offset %rsi,-8\n\t")
                    "pushq %rdi\n\t"
+                   __ASM_SEH(".seh_pushreg %rdi\n\t")
                    __ASM_CFI(".cfi_rel_offset %rdi,-16\n\t")
+                   __ASM_SEH(".seh_endprologue\n\t")
                    "movq %rcx,%rax\n\t"
                    "movq $4,%rcx\n\t"
                    "cmp %rcx,%rdx\n\t"
@@ -6489,6 +6602,92 @@ __ASM_GLOBAL_FUNC( call_method,
 __ASM_GLOBAL_FUNC( call_double_method,
                    "jmp " __ASM_NAME("call_method") )
 
+HRESULT WINAPI DispCallFunc( void* pvInstance, ULONG_PTR oVft, CALLCONV cc, VARTYPE vtReturn,
+                             UINT cActuals, VARTYPE* prgvt, VARIANTARG** prgpvarg, VARIANT* pvargResult )
+{
+    int argspos = 0;
+    UINT i;
+    DWORD_PTR *args;
+    void *func;
+
+    TRACE("(%p, %ld, %d, %d, %d, %p, %p, %p (vt=%d))\n",
+          pvInstance, oVft, cc, vtReturn, cActuals, prgvt, prgpvarg,
+          pvargResult, V_VT(pvargResult));
+
+    if (cc != CC_STDCALL && cc != CC_CDECL)
+    {
+       FIXME("unsupported calling convention %d\n",cc);
+        return E_INVALIDARG;
+    }
+
+    /* maximum size for an argument is sizeof(DWORD_PTR) */
+    args = heap_alloc( sizeof(DWORD_PTR) * (cActuals + 2) );
+
+    if (pvInstance)
+    {
+        const FARPROC *vtable = *(FARPROC **)pvInstance;
+        func = vtable[oVft/sizeof(void *)];
+        args[argspos++] = (DWORD_PTR)pvInstance; /* the This pointer is always the first parameter */
+    }
+    else func = (void *)oVft;
+
+    switch (vtReturn)
+    {
+    case VT_DECIMAL:
+    case VT_VARIANT:
+        args[argspos++] = (DWORD_PTR)pvargResult;  /* arg 0 is a pointer to the result */
+        break;
+    case VT_HRESULT:
+        WARN("invalid return type %u\n", vtReturn);
+        heap_free( args );
+        return E_INVALIDARG;
+    default:
+        break;
+    }
+
+    for (i = 0; i < cActuals; i++)
+    {
+        VARIANT *arg = prgpvarg[i];
+
+        switch (prgvt[i])
+        {
+        case VT_DECIMAL:
+        case VT_VARIANT:
+            args[argspos++] = (ULONG_PTR)arg;
+            break;
+        case VT_BOOL:  /* VT_BOOL is 16-bit but BOOL is 32-bit, needs to be extended */
+            args[argspos++] = V_BOOL(arg);
+            break;
+        default:
+            args[argspos++] = V_UI8(arg);
+            break;
+        }
+        TRACE("arg %u: type %s %s\n", i, debugstr_vt(prgvt[i]), debugstr_variant(arg));
+    }
+
+    switch (vtReturn)
+    {
+    case VT_R4:
+        V_R4(pvargResult) = call_double_method( func, argspos, args );
+        break;
+    case VT_R8:
+    case VT_DATE:
+        V_R8(pvargResult) = call_double_method( func, argspos, args );
+        break;
+    case VT_DECIMAL:
+    case VT_VARIANT:
+        call_method( func, argspos, args );
+        break;
+    default:
+        V_UI8(pvargResult) = call_method( func, argspos, args );
+        break;
+    }
+    heap_free( args );
+    if (vtReturn != VT_VARIANT) V_VT(pvargResult) = vtReturn;
+    TRACE("retval: %s\n", debugstr_variant(pvargResult));
+    return S_OK;
+}
+
 #elif defined(__arm__)
 
 extern LONGLONG CDECL call_method( void *func, int nb_stk_args, const DWORD *stk_args, const DWORD *reg_args );
@@ -6529,36 +6728,384 @@ __ASM_GLOBAL_FUNC( call_float_method,
 __ASM_GLOBAL_FUNC( call_double_method,
                    "b " __ASM_NAME("call_method") )
 
-#endif  /* __arm__ */
-
-static HRESULT userdefined_to_variantvt(ITypeInfo *tinfo, const TYPEDESC *tdesc, VARTYPE *vt)
+HRESULT WINAPI DispCallFunc( void* pvInstance, ULONG_PTR oVft, CALLCONV cc, VARTYPE vtReturn,
+                             UINT cActuals, VARTYPE* prgvt, VARIANTARG** prgpvarg, VARIANT* pvargResult )
 {
-    HRESULT hr = S_OK;
-    ITypeInfo *tinfo2 = NULL;
-    TYPEATTR *tattr = NULL;
+    int argspos;
+    void *func;
+    UINT i;
+    DWORD *args;
+    struct {
+#ifndef __SOFTFP__
+        union {
+            float s[16];
+            double d[8];
+        } sd;
+#endif
+        DWORD r[4];
+    } regs;
+    int rcount;     /* 32-bit register index count */
+#ifndef __SOFTFP__
+    int scount = 0; /* single-precision float register index count */
+    int dcount = 0; /* double-precision float register index count */
+#endif
 
-    hr = ITypeInfo_GetRefTypeInfo(tinfo, tdesc->u.hreftype, &tinfo2);
-    if (hr)
+    TRACE("(%p, %ld, %d, %d, %d, %p, %p, %p (vt=%d))\n",
+        pvInstance, oVft, cc, vtReturn, cActuals, prgvt, prgpvarg, pvargResult, V_VT(pvargResult));
+
+    if (cc != CC_STDCALL && cc != CC_CDECL)
     {
-        ERR("Could not get typeinfo of hreftype %x for VT_USERDEFINED, "
-            "hr = 0x%08x\n",
-              tdesc->u.hreftype, hr);
-        return hr;
+        FIXME("unsupported calling convention %d\n",cc);
+        return E_INVALIDARG;
     }
-    hr = ITypeInfo_GetTypeAttr(tinfo2, &tattr);
-    if (hr)
+
+    argspos = 0;
+    rcount = 0;
+
+    if (pvInstance)
     {
-        ERR("ITypeInfo_GetTypeAttr failed, hr = 0x%08x\n", hr);
-        ITypeInfo_Release(tinfo2);
-        return hr;
+        const FARPROC *vtable = *(FARPROC **)pvInstance;
+        func = vtable[oVft/sizeof(void *)];
+        regs.r[rcount++] = (DWORD)pvInstance; /* the This pointer is always the first parameter */
     }
+    else func = (void *)oVft;
 
-    switch (tattr->typekind)
+    /* Determine if we need to pass a pointer for the return value as arg 0.  If so, do that */
+    /*  first as it will need to be in the 'r' registers:                                    */
+    switch (vtReturn)
     {
-    case TKIND_ENUM:
-        *vt |= VT_I4;
-        break;
-
+    case VT_DECIMAL:
+    case VT_VARIANT:
+        regs.r[rcount++] = (DWORD)pvargResult;  /* arg 0 is a pointer to the result */
+        break;
+    case VT_HRESULT:
+        WARN("invalid return type %u\n", vtReturn);
+        return E_INVALIDARG;
+    default:                    /* And all others are in 'r', 's', or 'd' registers or have no return value */
+        break;
+    }
+
+    /* maximum size for an argument is sizeof(VARIANT).  Also allow for return pointer and stack alignment. */
+    args = heap_alloc( sizeof(VARIANT) * cActuals + sizeof(DWORD) * 4 );
+
+    for (i = 0; i < cActuals; i++)
+    {
+        VARIANT *arg = prgpvarg[i];
+        DWORD *pdwarg = (DWORD *)(arg);     /* a reinterpret_cast of the variant, used for copying structures when they are split between registers and stack */
+        int ntemp;              /* Used for counting words split between registers and stack */
+
+        switch (prgvt[i])
+        {
+        case VT_EMPTY:
+            break;
+        case VT_R8:             /* these must be 8-byte aligned, and put in 'd' regs or stack, as they are double-floats */
+        case VT_DATE:
+#ifndef __SOFTFP__
+            dcount = max( (scount + 1) / 2, dcount );
+            if (dcount < 8)
+            {
+                regs.sd.d[dcount++] = V_R8(arg);
+            }
+            else
+            {
+                argspos += (argspos % 2);   /* align argspos to 8-bytes */
+                memcpy( &args[argspos], &V_R8(arg), sizeof(V_R8(arg)) );
+                argspos += sizeof(V_R8(arg)) / sizeof(DWORD);
+            }
+            break;
+#endif
+        case VT_I8:             /* these must be 8-byte aligned, and put in 'r' regs or stack, as they are long-longs */
+        case VT_UI8:
+        case VT_CY:
+            if (rcount < 3)
+            {
+                rcount += (rcount % 2);     /* align rcount to 8-byte register pair */
+                memcpy( &regs.r[rcount], &V_UI8(arg), sizeof(V_UI8(arg)) );
+                rcount += sizeof(V_UI8(arg)) / sizeof(DWORD);
+            }
+            else
+            {
+                rcount = 4;                 /* Make sure we flag that all 'r' regs are full */
+                argspos += (argspos % 2);   /* align argspos to 8-bytes */
+                memcpy( &args[argspos], &V_UI8(arg), sizeof(V_UI8(arg)) );
+                argspos += sizeof(V_UI8(arg)) / sizeof(DWORD);
+            }
+            break;
+        case VT_DECIMAL:        /* these structures are 8-byte aligned, and put in 'r' regs or stack, can be split between the two */
+        case VT_VARIANT:
+            /* 8-byte align 'r' and/or stack: */
+            if (rcount < 3)
+                rcount += (rcount % 2);
+            else
+            {
+                rcount = 4;
+                argspos += (argspos % 2);
+            }
+            ntemp = sizeof(*arg) / sizeof(DWORD);
+            while (ntemp > 0)
+            {
+                if (rcount < 4)
+                    regs.r[rcount++] = *pdwarg++;
+                else
+                    args[argspos++] = *pdwarg++;
+                --ntemp;
+            }
+            break;
+        case VT_BOOL:  /* VT_BOOL is 16-bit but BOOL is 32-bit, needs to be extended */
+            if (rcount < 4)
+                regs.r[rcount++] = V_BOOL(arg);
+            else
+                args[argspos++] = V_BOOL(arg);
+            break;
+        case VT_R4:             /* these must be 4-byte aligned, and put in 's' regs or stack, as they are single-floats */
+#ifndef __SOFTFP__
+            if (!(scount % 2)) scount = max( scount, dcount * 2 );
+            if (scount < 16)
+                regs.sd.s[scount++] = V_R4(arg);
+            else
+                args[argspos++] = V_UI4(arg);
+            break;
+#endif
+        default:
+            if (rcount < 4)
+                regs.r[rcount++] = V_UI4(arg);
+            else
+                args[argspos++] = V_UI4(arg);
+            break;
+        }
+        TRACE("arg %u: type %s %s\n", i, debugstr_vt(prgvt[i]), debugstr_variant(arg));
+    }
+
+    argspos += (argspos % 2);   /* Make sure stack function alignment is 8-byte */
+
+    switch (vtReturn)
+    {
+    case VT_EMPTY:      /* EMPTY = no return value */
+    case VT_DECIMAL:    /* DECIMAL and VARIANT already have a pointer argument passed (see above) */
+    case VT_VARIANT:
+        call_method( func, argspos, args, (DWORD*)&regs );
+        break;
+    case VT_R4:
+        V_R4(pvargResult) = call_float_method( func, argspos, args, (DWORD*)&regs );
+        break;
+    case VT_R8:
+    case VT_DATE:
+        V_R8(pvargResult) = call_double_method( func, argspos, args, (DWORD*)&regs );
+        break;
+    case VT_I8:
+    case VT_UI8:
+    case VT_CY:
+        V_UI8(pvargResult) = call_method( func, argspos, args, (DWORD*)&regs );
+        break;
+    default:
+        V_UI4(pvargResult) = call_method( func, argspos, args, (DWORD*)&regs );
+        break;
+    }
+    heap_free( args );
+    if (vtReturn != VT_VARIANT) V_VT(pvargResult) = vtReturn;
+    TRACE("retval: %s\n", debugstr_variant(pvargResult));
+    return S_OK;
+}
+
+#elif defined(__aarch64__)
+
+extern DWORD_PTR CDECL call_method( void *func, int nb_stk_args, const DWORD_PTR *stk_args, const DWORD_PTR *reg_args );
+extern float CDECL call_float_method( void *func, int nb_stk_args, const DWORD_PTR *stk_args, const DWORD_PTR *reg_args );
+extern double CDECL call_double_method( void *func, int nb_stk_args, const DWORD_PTR *stk_args, const DWORD_PTR *reg_args );
+__ASM_GLOBAL_FUNC( call_method,
+                   "stp x29, x30, [sp, #-16]!\n\t"
+                   "mov x29, sp\n\t"
+                   "sub sp, sp, x1, lsl #3\n\t"
+                   "cbz x1, 2f\n"
+                   "1:\tsub x1, x1, #1\n\t"
+                   "ldr x4, [x2, x1, lsl #3]\n\t"
+                   "str x4, [sp, x1, lsl #3]\n\t"
+                   "cbnz x1, 1b\n"
+                   "2:\tmov x16, x0\n\t"
+                   "mov x9, x3\n\t"
+                   "ldp d0, d1, [x9]\n\t"
+                   "ldp d2, d3, [x9, #0x10]\n\t"
+                   "ldp d4, d5, [x9, #0x20]\n\t"
+                   "ldp d6, d7, [x9, #0x30]\n\t"
+                   "ldp x0, x1, [x9, #0x40]\n\t"
+                   "ldp x2, x3, [x9, #0x50]\n\t"
+                   "ldp x4, x5, [x9, #0x60]\n\t"
+                   "ldp x6, x7, [x9, #0x70]\n\t"
+                   "ldr x8, [x9, #0x80]\n\t"
+                   "blr x16\n\t"
+                   "mov sp, x29\n\t"
+                   "ldp x29, x30, [sp], #16\n\t"
+                   "ret" )
+__ASM_GLOBAL_FUNC( call_float_method,
+                   "b " __ASM_NAME("call_method") )
+__ASM_GLOBAL_FUNC( call_double_method,
+                   "b " __ASM_NAME("call_method") )
+
+HRESULT WINAPI DispCallFunc( void *instance, ULONG_PTR offset, CALLCONV cc, VARTYPE ret_type, UINT count,
+                             VARTYPE *types, VARIANTARG **vargs, VARIANT *result )
+{
+    int argspos;
+    void *func;
+    UINT i;
+    DWORD_PTR *args;
+    struct
+    {
+        union
+        {
+            float f;
+            double d;
+        } fp[8];
+        DWORD_PTR x[9];
+    } regs;
+    int rcount;      /* 64-bit register index count */
+    int fpcount = 0; /* float register index count */
+
+    TRACE("(%p, %ld, %d, %d, %d, %p, %p, %p (vt=%d))\n",
+          instance, offset, cc, ret_type, count, types, vargs, result, V_VT(result));
+
+    if (cc != CC_STDCALL && cc != CC_CDECL)
+    {
+        FIXME("unsupported calling convention %d\n",cc);
+        return E_INVALIDARG;
+    }
+
+    argspos = 0;
+    rcount = 0;
+
+    if (instance)
+    {
+        const FARPROC *vtable = *(FARPROC **)instance;
+        func = vtable[offset/sizeof(void *)];
+        regs.x[rcount++] = (DWORD_PTR)instance; /* the This pointer is always the first parameter */
+    }
+    else func = (void *)offset;
+
+    /* Determine if we need to pass a pointer for the return value as arg 0.  If so, do that */
+    /*  first as it will need to be in the 'x' registers:                                    */
+    switch (ret_type)
+    {
+    case VT_DECIMAL:
+    case VT_VARIANT:
+        regs.x[8] = (DWORD_PTR)result;  /* x8 is a pointer to the result */
+        break;
+    case VT_HRESULT:
+        WARN("invalid return type %u\n", ret_type);
+        return E_INVALIDARG;
+    default:
+        break;
+    }
+
+    /* maximum size for an argument is sizeof(VARIANT).  Also allow for return pointer and stack alignment. */
+    args = heap_alloc( sizeof(VARIANT) * count + sizeof(DWORD_PTR) * 4 );
+
+    for (i = 0; i < count; i++)
+    {
+        VARIANT *arg = vargs[i];
+
+        switch (types[i])
+        {
+        case VT_EMPTY:
+            break;
+        case VT_R4:
+            if (fpcount < 8) regs.fp[fpcount++].f = V_R4(arg);
+            else *(float *)&args[argspos++] = V_R4(arg);
+            break;
+        case VT_R8:
+        case VT_DATE:
+            if (fpcount < 8) regs.fp[fpcount++].d = V_R8(arg);
+            else *(double *)&args[argspos++] = V_R8(arg);
+            break;
+        case VT_DECIMAL:
+        case VT_VARIANT:
+            if (rcount < 7)
+            {
+                memcpy( &regs.x[rcount], arg, sizeof(*arg) );
+                rcount += 2;
+            }
+            else
+            {
+                memcpy( &args[argspos], arg, sizeof(*arg) );
+                argspos += 2;
+            }
+            break;
+        case VT_BOOL:  /* VT_BOOL is 16-bit but BOOL is 32-bit, needs to be extended */
+            if (rcount < 8) regs.x[rcount++] = V_BOOL(arg);
+            else args[argspos++] = V_BOOL(arg);
+            break;
+        default:
+            if (rcount < 8) regs.x[rcount++] = V_UI8(arg);
+            else args[argspos++] = V_UI8(arg);
+            break;
+        }
+        TRACE("arg %u: type %s %s\n", i, debugstr_vt(types[i]), debugstr_variant(arg));
+    }
+
+    argspos += (argspos % 2);   /* Make sure stack function alignment is 16-byte */
+
+    switch (ret_type)
+    {
+    case VT_EMPTY:      /* EMPTY = no return value */
+    case VT_DECIMAL:    /* DECIMAL and VARIANT already have a pointer argument passed (see above) */
+    case VT_VARIANT:
+        call_method( func, argspos, args, (DWORD_PTR *)&regs );
+        break;
+    case VT_R4:
+        V_R4(result) = call_float_method( func, argspos, args, (DWORD_PTR *)&regs );
+        break;
+    case VT_R8:
+    case VT_DATE:
+        V_R8(result) = call_double_method( func, argspos, args, (DWORD_PTR *)&regs );
+        break;
+    default:
+        V_UI8(result) = call_method( func, argspos, args, (DWORD_PTR *)&regs );
+        break;
+    }
+    heap_free( args );
+    if (ret_type != VT_VARIANT) V_VT(result) = ret_type;
+    TRACE("retval: %s\n", debugstr_variant(result));
+    return S_OK;
+}
+
+#else  /* __aarch64__ */
+
+HRESULT WINAPI DispCallFunc( void* pvInstance, ULONG_PTR oVft, CALLCONV cc, VARTYPE vtReturn,
+                             UINT cActuals, VARTYPE* prgvt, VARIANTARG** prgpvarg, VARIANT* pvargResult )
+{
+    FIXME( "(%p, %ld, %d, %d, %d, %p, %p, %p (vt=%d)): not implemented for this CPU\n",
+           pvInstance, oVft, cc, vtReturn, cActuals, prgvt, prgpvarg, pvargResult, V_VT(pvargResult));
+    return E_NOTIMPL;
+}
+
+#endif
+
+static HRESULT userdefined_to_variantvt(ITypeInfo *tinfo, const TYPEDESC *tdesc, VARTYPE *vt)
+{
+    HRESULT hr = S_OK;
+    ITypeInfo *tinfo2 = NULL;
+    TYPEATTR *tattr = NULL;
+
+    hr = ITypeInfo_GetRefTypeInfo(tinfo, tdesc->u.hreftype, &tinfo2);
+    if (hr)
+    {
+        ERR("Could not get typeinfo of hreftype %x for VT_USERDEFINED, "
+            "hr = 0x%08x\n",
+              tdesc->u.hreftype, hr);
+        return hr;
+    }
+    hr = ITypeInfo_GetTypeAttr(tinfo2, &tattr);
+    if (hr)
+    {
+        ERR("ITypeInfo_GetTypeAttr failed, hr = 0x%08x\n", hr);
+        ITypeInfo_Release(tinfo2);
+        return hr;
+    }
+
+    switch (tattr->typekind)
+    {
+    case TKIND_ENUM:
+        *vt |= VT_I4;
+        break;
+
     case TKIND_ALIAS:
         hr = typedescvt_to_variantvt(tinfo2, &tattr->tdescAlias, vt);
         break;
@@ -6718,420 +7265,6 @@ static HRESULT get_iface_guid(ITypeInfo *tinfo, HREFTYPE href, GUID *guid)
     return hres;
 }
 
-/***********************************************************************
- *             DispCallFunc (OLEAUT32.@)
- *
- * Invokes a function of the specified calling convention, passing the
- * specified arguments and returns the result.
- *
- * PARAMS
- *  pvInstance  [I] Optional pointer to the instance whose function to invoke.
- *  oVft        [I] The offset in the vtable. See notes.
- *  cc          [I] Calling convention of the function to call.
- *  vtReturn    [I] The return type of the function.
- *  cActuals    [I] Number of parameters.
- *  prgvt       [I] The types of the parameters to pass. This is used for sizing only.
- *  prgpvarg    [I] The arguments to pass.
- *  pvargResult [O] The return value of the function. Can be NULL.
- *
- * RETURNS
- *  Success: S_OK.
- *  Failure: HRESULT code.
- *
- * NOTES
- *  The HRESULT return value of this function is not affected by the return
- *  value of the user supplied function, which is returned in pvargResult.
- *
- *  If pvInstance is NULL then a non-object function is to be called and oVft
- *  is the address of the function to call.
- *
- * The cc parameter can be one of the following values:
- *|CC_FASTCALL
- *|CC_CDECL
- *|CC_PASCAL
- *|CC_STDCALL
- *|CC_FPFASTCALL
- *|CC_SYSCALL
- *|CC_MPWCDECL
- *|CC_MPWPASCAL
- *
- */
-HRESULT WINAPI
-DispCallFunc(
-    void* pvInstance, ULONG_PTR oVft, CALLCONV cc, VARTYPE vtReturn, UINT cActuals,
-    VARTYPE* prgvt, VARIANTARG** prgpvarg, VARIANT* pvargResult)
-{
-#ifdef __i386__
-    int argspos = 0, stack_offset;
-    void *func;
-    UINT i;
-    DWORD *args;
-
-    TRACE("(%p, %ld, %d, %d, %d, %p, %p, %p (vt=%d))\n",
-        pvInstance, oVft, cc, vtReturn, cActuals, prgvt, prgpvarg,
-        pvargResult, V_VT(pvargResult));
-
-    if (cc != CC_STDCALL && cc != CC_CDECL)
-    {
-        FIXME("unsupported calling convention %d\n",cc);
-        return E_INVALIDARG;
-    }
-
-    /* maximum size for an argument is sizeof(VARIANT) */
-    args = heap_alloc(sizeof(VARIANT) * cActuals + sizeof(DWORD) * 2 );
-
-    if (pvInstance)
-    {
-        const FARPROC *vtable = *(FARPROC **)pvInstance;
-        func = vtable[oVft/sizeof(void *)];
-        args[argspos++] = (DWORD)pvInstance; /* the This pointer is always the first parameter */
-    }
-    else func = (void *)oVft;
-
-    switch (vtReturn)
-    {
-    case VT_DECIMAL:
-    case VT_VARIANT:
-        args[argspos++] = (DWORD)pvargResult;  /* arg 0 is a pointer to the result */
-        break;
-    case VT_HRESULT:
-        WARN("invalid return type %u\n", vtReturn);
-        heap_free( args );
-        return E_INVALIDARG;
-    default:
-        break;
-    }
-
-    for (i = 0; i < cActuals; i++)
-    {
-        VARIANT *arg = prgpvarg[i];
-
-        switch (prgvt[i])
-        {
-        case VT_EMPTY:
-            break;
-        case VT_I8:
-        case VT_UI8:
-        case VT_R8:
-        case VT_DATE:
-        case VT_CY:
-            memcpy( &args[argspos], &V_I8(arg), sizeof(V_I8(arg)) );
-            argspos += sizeof(V_I8(arg)) / sizeof(DWORD);
-            break;
-        case VT_DECIMAL:
-        case VT_VARIANT:
-            memcpy( &args[argspos], arg, sizeof(*arg) );
-            argspos += sizeof(*arg) / sizeof(DWORD);
-            break;
-        case VT_BOOL:  /* VT_BOOL is 16-bit but BOOL is 32-bit, needs to be extended */
-            args[argspos++] = V_BOOL(arg);
-            break;
-        default:
-            args[argspos++] = V_UI4(arg);
-            break;
-        }
-        TRACE("arg %u: type %s %s\n", i, debugstr_vt(prgvt[i]), debugstr_variant(arg));
-    }
-
-    switch (vtReturn)
-    {
-    case VT_EMPTY:
-    case VT_DECIMAL:
-    case VT_VARIANT:
-        call_method( func, argspos, args, &stack_offset );
-        break;
-    case VT_R4:
-        V_R4(pvargResult) = call_double_method( func, argspos, args, &stack_offset );
-        break;
-    case VT_R8:
-    case VT_DATE:
-        V_R8(pvargResult) = call_double_method( func, argspos, args, &stack_offset );
-        break;
-    case VT_I8:
-    case VT_UI8:
-    case VT_CY:
-        V_UI8(pvargResult) = call_method( func, argspos, args, &stack_offset );
-        break;
-    default:
-        V_UI4(pvargResult) = call_method( func, argspos, args, &stack_offset );
-        break;
-    }
-    heap_free( args );
-    if (stack_offset && cc == CC_STDCALL)
-    {
-        WARN( "stack pointer off by %d\n", stack_offset );
-        return DISP_E_BADCALLEE;
-    }
-    if (vtReturn != VT_VARIANT) V_VT(pvargResult) = vtReturn;
-    TRACE("retval: %s\n", debugstr_variant(pvargResult));
-    return S_OK;
-
-#elif defined(__x86_64__)
-    int argspos = 0;
-    UINT i;
-    DWORD_PTR *args;
-    void *func;
-
-    TRACE("(%p, %ld, %d, %d, %d, %p, %p, %p (vt=%d))\n",
-          pvInstance, oVft, cc, vtReturn, cActuals, prgvt, prgpvarg,
-          pvargResult, V_VT(pvargResult));
-
-    if (cc != CC_STDCALL && cc != CC_CDECL)
-    {
-       FIXME("unsupported calling convention %d\n",cc);
-        return E_INVALIDARG;
-    }
-
-    /* maximum size for an argument is sizeof(DWORD_PTR) */
-    args = heap_alloc( sizeof(DWORD_PTR) * (cActuals + 2) );
-
-    if (pvInstance)
-    {
-        const FARPROC *vtable = *(FARPROC **)pvInstance;
-        func = vtable[oVft/sizeof(void *)];
-        args[argspos++] = (DWORD_PTR)pvInstance; /* the This pointer is always the first parameter */
-    }
-    else func = (void *)oVft;
-
-    switch (vtReturn)
-    {
-    case VT_DECIMAL:
-    case VT_VARIANT:
-        args[argspos++] = (DWORD_PTR)pvargResult;  /* arg 0 is a pointer to the result */
-        break;
-    case VT_HRESULT:
-        WARN("invalid return type %u\n", vtReturn);
-        heap_free( args );
-        return E_INVALIDARG;
-    default:
-        break;
-    }
-
-    for (i = 0; i < cActuals; i++)
-    {
-        VARIANT *arg = prgpvarg[i];
-
-        switch (prgvt[i])
-        {
-        case VT_DECIMAL:
-        case VT_VARIANT:
-            args[argspos++] = (ULONG_PTR)arg;
-            break;
-        case VT_BOOL:  /* VT_BOOL is 16-bit but BOOL is 32-bit, needs to be extended */
-            args[argspos++] = V_BOOL(arg);
-            break;
-        default:
-            args[argspos++] = V_UI8(arg);
-            break;
-        }
-        TRACE("arg %u: type %s %s\n", i, debugstr_vt(prgvt[i]), debugstr_variant(arg));
-    }
-
-    switch (vtReturn)
-    {
-    case VT_R4:
-        V_R4(pvargResult) = call_double_method( func, argspos, args );
-        break;
-    case VT_R8:
-    case VT_DATE:
-        V_R8(pvargResult) = call_double_method( func, argspos, args );
-        break;
-    case VT_DECIMAL:
-    case VT_VARIANT:
-        call_method( func, argspos, args );
-        break;
-    default:
-        V_UI8(pvargResult) = call_method( func, argspos, args );
-        break;
-    }
-    heap_free( args );
-    if (vtReturn != VT_VARIANT) V_VT(pvargResult) = vtReturn;
-    TRACE("retval: %s\n", debugstr_variant(pvargResult));
-    return S_OK;
-
-#elif defined(__arm__)
-    int argspos;
-    void *func;
-    UINT i;
-    DWORD *args;
-    struct {
-#ifndef __SOFTFP__
-        union {
-            float s[16];
-            double d[8];
-        } sd;
-#endif
-        DWORD r[4];
-    } regs;
-    int rcount;     /* 32-bit register index count */
-#ifndef __SOFTFP__
-    int scount = 0; /* single-precision float register index count */
-    int dcount = 0; /* double-precision float register index count */
-#endif
-
-    TRACE("(%p, %ld, %d, %d, %d, %p, %p, %p (vt=%d))\n",
-        pvInstance, oVft, cc, vtReturn, cActuals, prgvt, prgpvarg, pvargResult, V_VT(pvargResult));
-
-    if (cc != CC_STDCALL && cc != CC_CDECL)
-    {
-        FIXME("unsupported calling convention %d\n",cc);
-        return E_INVALIDARG;
-    }
-
-    argspos = 0;
-    rcount = 0;
-
-    if (pvInstance)
-    {
-        const FARPROC *vtable = *(FARPROC **)pvInstance;
-        func = vtable[oVft/sizeof(void *)];
-        regs.r[rcount++] = (DWORD)pvInstance; /* the This pointer is always the first parameter */
-    }
-    else func = (void *)oVft;
-
-    /* Determine if we need to pass a pointer for the return value as arg 0.  If so, do that */
-    /*  first as it will need to be in the 'r' registers:                                    */
-    switch (vtReturn)
-    {
-    case VT_DECIMAL:
-    case VT_VARIANT:
-        regs.r[rcount++] = (DWORD)pvargResult;  /* arg 0 is a pointer to the result */
-        break;
-    case VT_HRESULT:
-        WARN("invalid return type %u\n", vtReturn);
-        return E_INVALIDARG;
-    default:                    /* And all others are in 'r', 's', or 'd' registers or have no return value */
-        break;
-    }
-
-    /* maximum size for an argument is sizeof(VARIANT).  Also allow for return pointer and stack alignment. */
-    args = heap_alloc( sizeof(VARIANT) * cActuals + sizeof(DWORD) * 4 );
-
-    for (i = 0; i < cActuals; i++)
-    {
-        VARIANT *arg = prgpvarg[i];
-        DWORD *pdwarg = (DWORD *)(arg);     /* a reinterpret_cast of the variant, used for copying structures when they are split between registers and stack */
-        int ntemp;              /* Used for counting words split between registers and stack */
-
-        switch (prgvt[i])
-        {
-        case VT_EMPTY:
-            break;
-        case VT_R8:             /* these must be 8-byte aligned, and put in 'd' regs or stack, as they are double-floats */
-        case VT_DATE:
-#ifndef __SOFTFP__
-            dcount = max( (scount + 1) / 2, dcount );
-            if (dcount < 8)
-            {
-                regs.sd.d[dcount++] = V_R8(arg);
-            }
-            else
-            {
-                argspos += (argspos % 2);   /* align argspos to 8-bytes */
-                memcpy( &args[argspos], &V_R8(arg), sizeof(V_R8(arg)) );
-                argspos += sizeof(V_R8(arg)) / sizeof(DWORD);
-            }
-            break;
-#endif
-        case VT_I8:             /* these must be 8-byte aligned, and put in 'r' regs or stack, as they are long-longs */
-        case VT_UI8:
-        case VT_CY:
-            if (rcount < 3)
-            {
-                rcount += (rcount % 2);     /* align rcount to 8-byte register pair */
-                memcpy( &regs.r[rcount], &V_UI8(arg), sizeof(V_UI8(arg)) );
-                rcount += sizeof(V_UI8(arg)) / sizeof(DWORD);
-            }
-            else
-            {
-                rcount = 4;                 /* Make sure we flag that all 'r' regs are full */
-                argspos += (argspos % 2);   /* align argspos to 8-bytes */
-                memcpy( &args[argspos], &V_UI8(arg), sizeof(V_UI8(arg)) );
-                argspos += sizeof(V_UI8(arg)) / sizeof(DWORD);
-            }
-            break;
-        case VT_DECIMAL:        /* these structures are 8-byte aligned, and put in 'r' regs or stack, can be split between the two */
-        case VT_VARIANT:
-            /* 8-byte align 'r' and/or stack: */
-            if (rcount < 3)
-                rcount += (rcount % 2);
-            else
-            {
-                rcount = 4;
-                argspos += (argspos % 2);
-            }
-            ntemp = sizeof(*arg) / sizeof(DWORD);
-            while (ntemp > 0)
-            {
-                if (rcount < 4)
-                    regs.r[rcount++] = *pdwarg++;
-                else
-                    args[argspos++] = *pdwarg++;
-                --ntemp;
-            }
-            break;
-        case VT_BOOL:  /* VT_BOOL is 16-bit but BOOL is 32-bit, needs to be extended */
-            if (rcount < 4)
-                regs.r[rcount++] = V_BOOL(arg);
-            else
-                args[argspos++] = V_BOOL(arg);
-            break;
-        case VT_R4:             /* these must be 4-byte aligned, and put in 's' regs or stack, as they are single-floats */
-#ifndef __SOFTFP__
-            if (!(scount % 2)) scount = max( scount, dcount * 2 );
-            if (scount < 16)
-                regs.sd.s[scount++] = V_R4(arg);
-            else
-                args[argspos++] = V_UI4(arg);
-            break;
-#endif
-        default:
-            if (rcount < 4)
-                regs.r[rcount++] = V_UI4(arg);
-            else
-                args[argspos++] = V_UI4(arg);
-            break;
-        }
-        TRACE("arg %u: type %s %s\n", i, debugstr_vt(prgvt[i]), debugstr_variant(arg));
-    }
-
-    argspos += (argspos % 2);   /* Make sure stack function alignment is 8-byte */
-
-    switch (vtReturn)
-    {
-    case VT_EMPTY:      /* EMPTY = no return value */
-    case VT_DECIMAL:    /* DECIMAL and VARIANT already have a pointer argument passed (see above) */
-    case VT_VARIANT:
-        call_method( func, argspos, args, (DWORD*)&regs );
-        break;
-    case VT_R4:
-        V_R4(pvargResult) = call_float_method( func, argspos, args, (DWORD*)&regs );
-        break;
-    case VT_R8:
-    case VT_DATE:
-        V_R8(pvargResult) = call_double_method( func, argspos, args, (DWORD*)&regs );
-        break;
-    case VT_I8:
-    case VT_UI8:
-    case VT_CY:
-        V_UI8(pvargResult) = call_method( func, argspos, args, (DWORD*)&regs );
-        break;
-    default:
-        V_UI4(pvargResult) = call_method( func, argspos, args, (DWORD*)&regs );
-        break;
-    }
-    heap_free( args );
-    if (vtReturn != VT_VARIANT) V_VT(pvargResult) = vtReturn;
-    TRACE("retval: %s\n", debugstr_variant(pvargResult));
-    return S_OK;
-
-#else
-    FIXME( "(%p, %ld, %d, %d, %d, %p, %p, %p (vt=%d)): not implemented for this CPU\n",
-           pvInstance, oVft, cc, vtReturn, cActuals, prgvt, prgpvarg, pvargResult, V_VT(pvargResult));
-    return E_NOTIMPL;
-#endif
-}
-
 static inline BOOL func_restricted( const FUNCDESC *desc )
 {
     return (desc->wFuncFlags & FUNCFLAG_FRESTRICTED) && (desc->memid >= 0);
@@ -7850,7 +7983,7 @@ static BOOL CALLBACK search_res_tlb(HMODULE hModule, LPCWSTR lpszType, LPWSTR lp
     if (!(len = GetModuleFileNameW(hModule, szPath, MAX_PATH)))
         return TRUE;
 
-    if (snprintfW(szPath + len, ARRAY_SIZE(szPath) - len, formatW, LOWORD(lpszName)) < 0)
+    if (swprintf(szPath + len, formatW, LOWORD(lpszName)) < 0)
         return TRUE;
 
     ret = LoadTypeLibEx(szPath, REGKIND_NONE, &pTLib);
@@ -9167,7 +9300,7 @@ static HRESULT WMSFT_compile_strings(ITypeLibImpl *This,
     LIST_FOR_EACH_ENTRY(str, &This->string_list, TLBString, entry) {
         int size;
 
-        size = WideCharToMultiByte(CP_ACP, 0, str->str, strlenW(str->str), NULL, 0, NULL, NULL);
+        size = WideCharToMultiByte(CP_ACP, 0, str->str, lstrlenW(str->str), NULL, 0, NULL, NULL);
         if (size == 0)
             return E_UNEXPECTED;
 
@@ -9190,7 +9323,7 @@ static HRESULT WMSFT_compile_strings(ITypeLibImpl *This,
     LIST_FOR_EACH_ENTRY(str, &This->string_list, TLBString, entry) {
         int size;
 
-        size = WideCharToMultiByte(CP_ACP, 0, str->str, strlenW(str->str),
+        size = WideCharToMultiByte(CP_ACP, 0, str->str, lstrlenW(str->str),
                 data + sizeof(INT16), file->string_seg.len - last_offs - sizeof(INT16), NULL, NULL);
         if (size == 0) {
             heap_free(file->string_seg.data);
@@ -9225,7 +9358,7 @@ static HRESULT WMSFT_compile_names(ITypeLibImpl *This,
     LIST_FOR_EACH_ENTRY(str, &This->name_list, TLBString, entry) {
         int size;
 
-        size = strlenW(str->str);
+        size = lstrlenW(str->str);
         file->header.nametablechars += size;
         file->header.nametablecount++;
 
@@ -9254,7 +9387,7 @@ static HRESULT WMSFT_compile_names(ITypeLibImpl *This,
         int size, hash;
         MSFT_NameIntro *intro = (MSFT_NameIntro*)data;
 
-        size = WideCharToMultiByte(CP_ACP, 0, str->str, strlenW(str->str),
+        size = WideCharToMultiByte(CP_ACP, 0, str->str, lstrlenW(str->str),
                 data + sizeof(MSFT_NameIntro),
                 file->name_seg.len - last_offs - sizeof(MSFT_NameIntro), NULL, NULL);
         if (size == 0) {
@@ -10019,12 +10152,12 @@ static void WMSFT_compile_impfile(ITypeLibImpl *This, WMSFT_TLBFile *file)
         int size = 0;
 
         if(implib->name){
-            WCHAR *path = strrchrW(implib->name, '\\');
+            WCHAR *path = wcsrchr(implib->name, '\\');
             if(path)
                 ++path;
             else
                 path = implib->name;
-            size = WideCharToMultiByte(CP_ACP, 0, path, strlenW(path), NULL, 0, NULL, NULL);
+            size = WideCharToMultiByte(CP_ACP, 0, path, lstrlenW(path), NULL, 0, NULL, NULL);
             if (size == 0)
                 ERR("failed to convert wide string: %s\n", debugstr_w(path));
         }
@@ -10051,12 +10184,12 @@ static void WMSFT_compile_impfile(ITypeLibImpl *This, WMSFT_TLBFile *file)
         data += sizeof(WMSFT_ImpFile);
 
         if(implib->name){
-            WCHAR *path= strrchrW(implib->name, '\\');
+            WCHAR *path= wcsrchr(implib->name, '\\');
             if(path)
                 ++path;
             else
                 path = implib->name;
-            strlen = WideCharToMultiByte(CP_ACP, 0, path, strlenW(path),
+            strlen = WideCharToMultiByte(CP_ACP, 0, path, lstrlenW(path),
                     data + sizeof(INT16), file->impfile_seg.len - last_offs - sizeof(INT16), NULL, NULL);
             if (strlen == 0)
                 ERR("failed to convert wide string: %s\n", debugstr_w(path));
@@ -10999,7 +11132,7 @@ static HRESULT WINAPI ICreateTypeInfo2_fnSetFuncAndParamNames(ICreateTypeInfo2 *
 
     for(i = 0; i < This->typeattr.cFuncs; ++i) {
         TLBFuncDesc *iter = &This->funcdescs[i];
-        if (iter->Name && !strcmpW(TLB_get_bstr(iter->Name), *names)) {
+        if (iter->Name && !wcscmp(TLB_get_bstr(iter->Name), *names)) {
             if (iter->funcdesc.invkind & (INVOKE_PROPERTYPUT | INVOKE_PROPERTYPUTREF | INVOKE_PROPERTYGET) &&
                     func_desc->funcdesc.invkind & (INVOKE_PROPERTYPUT | INVOKE_PROPERTYPUTREF | INVOKE_PROPERTYGET) &&
                     func_desc->funcdesc.invkind != iter->funcdesc.invkind)
index 470ea4e..591093d 100644 (file)
@@ -25,8 +25,6 @@
  *  Please submit a test case if you find a difference.
  */
 
-#include "config.h"
-
 #include <string.h>
 #include <stdlib.h>
 #include <stdarg.h>
@@ -34,7 +32,6 @@
 
 #include "windef.h"
 #include "winbase.h"
-#include "wine/unicode.h"
 #include "winerror.h"
 #include "variant.h"
 #include "wine/debug.h"
@@ -438,9 +435,9 @@ static const NAMED_FORMAT VARIANT_NamedFormats[] =
 };
 typedef const NAMED_FORMAT *LPCNAMED_FORMAT;
 
-static int FormatCompareFn(const void *l, const void *r)
+static int __cdecl FormatCompareFn(const void *l, const void *r)
 {
-  return strcmpiW(((LPCNAMED_FORMAT)l)->name, ((LPCNAMED_FORMAT)r)->name);
+  return wcsicmp(((LPCNAMED_FORMAT)l)->name, ((LPCNAMED_FORMAT)r)->name);
 }
 
 static inline const BYTE *VARIANT_GetNamedFormat(LPCWSTR lpszFormat)
@@ -763,7 +760,7 @@ HRESULT WINAPI VarTokenizeFormatString(LPOLESTR lpszFormat, LPBYTE rgbTok,
       TRACE("time sep\n");
     }
     else if ((*pFormat == 'a' || *pFormat == 'A') &&
-              !strncmpiW(pFormat, szAMPM, ARRAY_SIZE(szAMPM)))
+              !_wcsnicmp(pFormat, szAMPM, ARRAY_SIZE(szAMPM)))
     {
       /* Date formats: System AM/PM designation
        * Other formats: Literal
@@ -772,7 +769,7 @@ HRESULT WINAPI VarTokenizeFormatString(LPOLESTR lpszFormat, LPBYTE rgbTok,
       header->type = FMT_TYPE_DATE;
       NEED_SPACE(sizeof(BYTE));
       pFormat += ARRAY_SIZE(szAMPM);
-      if (!strncmpW(pFormat, szampm, ARRAY_SIZE(szampm)))
+      if (!wcsncmp(pFormat, szampm, ARRAY_SIZE(szampm)))
         *pOut++ = FMT_DATE_AMPM_SYS2;
       else
         *pOut++ = FMT_DATE_AMPM_SYS1;
@@ -810,7 +807,7 @@ HRESULT WINAPI VarTokenizeFormatString(LPOLESTR lpszFormat, LPBYTE rgbTok,
         *pLastHours = *pLastHours + 2;
       TRACE("A/P\n");
     }
-    else if (*pFormat == 'a' && !strncmpW(pFormat, szamSlashpm, ARRAY_SIZE(szamSlashpm)))
+    else if (*pFormat == 'a' && !wcsncmp(pFormat, szamSlashpm, ARRAY_SIZE(szamSlashpm)))
     {
       /* Date formats: lowercase AM or PM designation
        * Other formats: Literal
@@ -824,7 +821,7 @@ HRESULT WINAPI VarTokenizeFormatString(LPOLESTR lpszFormat, LPBYTE rgbTok,
         *pLastHours = *pLastHours + 2;
       TRACE("AM/PM\n");
     }
-    else if (*pFormat == 'A' && !strncmpW(pFormat, szAMSlashPM, ARRAY_SIZE(szAMSlashPM)))
+    else if (*pFormat == 'A' && !wcsncmp(pFormat, szAMSlashPM, ARRAY_SIZE(szAMSlashPM)))
     {
       /* Date formats: Uppercase AM or PM designation
        * Other formats: Literal
@@ -986,7 +983,7 @@ HRESULT WINAPI VarTokenizeFormatString(LPOLESTR lpszFormat, LPBYTE rgbTok,
       fmt_state &= ~FMT_STATE_OPEN_COPY;
     }
     else if ((*pFormat == 't' || *pFormat == 'T') &&
-              !strncmpiW(pFormat, szTTTTT, ARRAY_SIZE(szTTTTT)))
+              !_wcsnicmp(pFormat, szTTTTT, ARRAY_SIZE(szTTTTT)))
     {
       /* Date formats: System time specifier
        * Other formats: Literal
@@ -1376,7 +1373,7 @@ VARIANT_FormatNumber_Bool:
         hRes = VarBstrFromBool(V_BOOL(&vBool), lcid, boolFlag, &boolStr);
         if (SUCCEEDED(hRes))
         {
-          strcpyW(pBuff, boolStr);
+          lstrcpyW(pBuff, boolStr);
           SysFreeString(boolStr);
           while (*pBuff)
             pBuff++;
@@ -1418,13 +1415,13 @@ VARIANT_FormatNumber_Bool:
       if (exponent < 0)
       {
         *pBuff++ = '-';
-        sprintfW(pBuff, szPercentZeroStar_d, pToken[1], -exponent);
+        swprintf(pBuff, szPercentZeroStar_d, pToken[1], -exponent);
       }
       else
       {
         if (*pToken == FMT_NUM_EXP_POS_L || *pToken == FMT_NUM_EXP_POS_U)
           *pBuff++ = '+';
-        sprintfW(pBuff, szPercentZeroStar_d, pToken[1], exponent);
+        swprintf(pBuff, szPercentZeroStar_d, pToken[1], exponent);
       }
       while (*pBuff)
         pBuff++;
@@ -1897,7 +1894,7 @@ static HRESULT VARIANT_FormatDate(LPVARIANT pVarIn, LPOLESTR lpszFormat,
     }
     else if (szPrintFmt)
     {
-      sprintfW(pBuff, szPrintFmt, dwVal);
+      swprintf(pBuff, szPrintFmt, dwVal);
       while (*pBuff)
         pBuff++;
     }
@@ -1956,7 +1953,7 @@ static HRESULT VARIANT_FormatString(LPVARIANT pVarIn, LPOLESTR lpszFormat,
   pSrc = V_BSTR(&vStr);
   if ((strHeader->flags & (FMT_FLAG_LT|FMT_FLAG_GT)) == FMT_FLAG_GT)
     bUpper = TRUE;
-  blanks_first = strHeader->copy_chars - strlenW(pSrc);
+  blanks_first = strHeader->copy_chars - lstrlenW(pSrc);
   pToken = (const BYTE*)strHeader + sizeof(FMT_DATE_HEADER);
 
   while (*pToken != FMT_GEN_END)
@@ -1997,9 +1994,9 @@ static HRESULT VARIANT_FormatString(LPVARIANT pVarIn, LPOLESTR lpszFormat,
       while (dwCount > 0 && *pSrc)
       {
         if (bUpper)
-          *pBuff++ = toupperW(*pSrc);
+          *pBuff++ = towupper(*pSrc);
         else
-          *pBuff++ = tolowerW(*pSrc);
+          *pBuff++ = towlower(*pSrc);
         dwCount--;
         pSrc++;
       }
@@ -2025,9 +2022,9 @@ VARIANT_FormatString_Exit:
   while (*pSrc)
   {
     if (bUpper)
-      *pBuff++ = toupperW(*pSrc);
+      *pBuff++ = towupper(*pSrc);
     else
-      *pBuff++ = tolowerW(*pSrc);
+      *pBuff++ = towlower(*pSrc);
     pSrc++;
   }
   VariantClear(&vStr);
@@ -2284,9 +2281,9 @@ HRESULT WINAPI VarFormatNumber(LPVARIANT pVarIn, INT nDigits, INT nLeading, INT
 
     if (nGrouping == -2)
     {
-      WCHAR grouping[16];
+      WCHAR grouping[10];
       grouping[2] = '\0';
-      GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SDECIMAL, grouping, ARRAY_SIZE(grouping));
+      GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SGROUPING, grouping, ARRAY_SIZE(grouping));
       numfmt.Grouping = grouping[2] == '2' ? 32 : grouping[0] - '0';
     }
     else if (nGrouping == -1)
@@ -2380,12 +2377,12 @@ HRESULT WINAPI VarFormatPercent(LPVARIANT pVarIn, INT nDigits, INT nLeading, INT
 
       if (SUCCEEDED(hRet))
       {
-        DWORD dwLen = strlenW(*pbstrOut);
+        DWORD dwLen = lstrlenW(*pbstrOut);
         BOOL bBracket = (*pbstrOut)[dwLen] == ')';
 
         dwLen -= bBracket;
         memcpy(buff, *pbstrOut, dwLen * sizeof(WCHAR));
-        strcpyW(buff + dwLen, bBracket ? szPercentBracket : szPercent);
+        lstrcpyW(buff + dwLen, bBracket ? szPercentBracket : szPercent);
         SysFreeString(*pbstrOut);
         *pbstrOut = SysAllocString(buff);
         if (!*pbstrOut)
@@ -2443,7 +2440,7 @@ HRESULT WINAPI VarFormatCurrency(LPVARIANT pVarIn, INT nDigits, INT nLeading,
 
   if (SUCCEEDED(hRet))
   {
-    WCHAR buff[256], decimal[8], thousands[8], currency[8];
+    WCHAR buff[256], decimal[8], thousands[4], currency[13];
     CURRENCYFMTW numfmt;
 
     if (nDigits < 0)
@@ -2460,9 +2457,9 @@ HRESULT WINAPI VarFormatCurrency(LPVARIANT pVarIn, INT nDigits, INT nLeading,
 
     if (nGrouping == -2)
     {
-      WCHAR grouping[16];
+      WCHAR grouping[10];
       grouping[2] = '\0';
-      GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SDECIMAL, grouping, ARRAY_SIZE(grouping));
+      GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SGROUPING, grouping, ARRAY_SIZE(grouping));
       numfmt.Grouping = grouping[2] == '2' ? 32 : grouping[0] - '0';
     }
     else if (nGrouping == -1)
@@ -2482,9 +2479,9 @@ HRESULT WINAPI VarFormatCurrency(LPVARIANT pVarIn, INT nDigits, INT nLeading,
     numfmt.lpDecimalSep = decimal;
     GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SDECIMAL, decimal, ARRAY_SIZE(decimal));
     numfmt.lpThousandSep = thousands;
-    GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SDECIMAL, thousands, ARRAY_SIZE(thousands));
+    GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_STHOUSAND, thousands, ARRAY_SIZE(thousands));
     numfmt.lpCurrencySymbol = currency;
-    GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SDECIMAL, currency, ARRAY_SIZE(currency));
+    GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SCURRENCY, currency, ARRAY_SIZE(currency));
 
     /* use NLS as per VarFormatNumber() */
     if (GetCurrencyFormatW(LOCALE_USER_DEFAULT, 0, V_BSTR(&vStr), &numfmt, buff, ARRAY_SIZE(buff)))
index fcbef53..ce96ba1 100644 (file)
@@ -25,8 +25,6 @@
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
-#include "config.h"
-
 #include <string.h>
 #include <stdlib.h>
 #include <stdarg.h>
@@ -37,7 +35,6 @@
 
 #include "windef.h"
 #include "winbase.h"
-#include "wine/unicode.h"
 #include "winerror.h"
 #include "variant.h"
 #include "resource.h"
@@ -1635,14 +1632,14 @@ HRESULT WINAPI VarParseNumFromStr(OLECHAR *lpszStr, LCID lcid, ULONG dwFlags,
   /* First consume all the leading symbols and space from the string */
   while (1)
   {
-    if (pNumprs->dwInFlags & NUMPRS_LEADING_WHITE && isspaceW(*lpszStr))
+    if (pNumprs->dwInFlags & NUMPRS_LEADING_WHITE && iswspace(*lpszStr))
     {
       pNumprs->dwOutFlags |= NUMPRS_LEADING_WHITE;
       do
       {
         cchUsed++;
         lpszStr++;
-      } while (isspaceW(*lpszStr));
+      } while (iswspace(*lpszStr));
     }
     else if (pNumprs->dwInFlags & NUMPRS_LEADING_PLUS &&
              *lpszStr == chars.cPositiveSymbol &&
@@ -1717,14 +1714,14 @@ HRESULT WINAPI VarParseNumFromStr(OLECHAR *lpszStr, LCID lcid, ULONG dwFlags,
 
   while (*lpszStr)
   {
-    if (isdigitW(*lpszStr))
+    if (iswdigit(*lpszStr))
     {
       if (dwState & B_PROCESSING_EXPONENT)
       {
         int exponentSize = 0;
         if (dwState & B_EXPONENT_START)
         {
-          if (!isdigitW(*lpszStr))
+          if (!iswdigit(*lpszStr))
             break; /* No exponent digits - invalid */
           while (*lpszStr == '0')
           {
@@ -1734,7 +1731,7 @@ HRESULT WINAPI VarParseNumFromStr(OLECHAR *lpszStr, LCID lcid, ULONG dwFlags,
           }
         }
 
-        while (isdigitW(*lpszStr))
+        while (iswdigit(*lpszStr))
         {
           exponentSize *= 10;
           exponentSize += *lpszStr - '0';
@@ -1906,14 +1903,14 @@ HRESULT WINAPI VarParseNumFromStr(OLECHAR *lpszStr, LCID lcid, ULONG dwFlags,
   /* Consume any trailing symbols and space */
   while (1)
   {
-    if ((pNumprs->dwInFlags & NUMPRS_TRAILING_WHITE) && isspaceW(*lpszStr))
+    if ((pNumprs->dwInFlags & NUMPRS_TRAILING_WHITE) && iswspace(*lpszStr))
     {
       pNumprs->dwOutFlags |= NUMPRS_TRAILING_WHITE;
       do
       {
         cchUsed++;
         lpszStr++;
-      } while (isspaceW(*lpszStr));
+      } while (iswspace(*lpszStr));
     }
     else if (pNumprs->dwInFlags & NUMPRS_TRAILING_PLUS &&
              !(pNumprs->dwOutFlags & NUMPRS_LEADING_PLUS) &&
@@ -5138,7 +5135,9 @@ HRESULT WINAPI VarRound(LPVARIANT pVarIn, int deci, LPVARIANT pVarOut)
     {
         double dbl;
 
-        VarR8FromDec(&V_DECIMAL(pVarIn), &dbl);
+        hRet = VarR8FromDec(&V_DECIMAL(pVarIn), &dbl);
+        if (FAILED(hRet))
+            break;
 
         if (dbl>0.0f)
             dbl = floor(dbl*pow(10,deci)+0.5);
@@ -5146,7 +5145,7 @@ HRESULT WINAPI VarRound(LPVARIANT pVarIn, int deci, LPVARIANT pVarOut)
             dbl = ceil(dbl*pow(10,deci)-0.5);
 
         V_VT(pVarOut)=VT_DECIMAL;
-        VarDecFromR8(dbl, &V_DECIMAL(pVarOut));
+        hRet = VarDecFromR8(dbl, &V_DECIMAL(pVarOut));
         break;
     }
     /* cases we don't know yet */
index 067d515..cf18d7d 100644 (file)
@@ -22,8 +22,9 @@
 #define NONAMELESSUNION
 #define NONAMELESSSTRUCT
 
+#include <wchar.h>
+
 #include "wine/debug.h"
-#include "wine/unicode.h"
 #include "winbase.h"
 #include "winuser.h"
 #include "winnt.h"
@@ -6150,13 +6151,13 @@ VarBoolFromStr_CheckLocalised:
   if (VARIANT_GetLocalisedText(langId, IDS_TRUE, szBuff))
   {
     /* Compare against localised strings, ignoring case */
-    if (!strcmpiW(strIn, szBuff))
+    if (!wcsicmp(strIn, szBuff))
     {
       *pBoolOut = VARIANT_TRUE; /* Matched localised 'true' text */
       return hRes;
     }
     VARIANT_GetLocalisedText(langId, IDS_FALSE, szBuff);
-    if (!strcmpiW(strIn, szBuff))
+    if (!wcsicmp(strIn, szBuff))
     {
       *pBoolOut = VARIANT_FALSE; /* Matched localised 'false' text */
       return hRes;
@@ -6171,9 +6172,9 @@ VarBoolFromStr_CheckLocalised:
   }
 
   /* All checks against localised text have failed, try #TRUE#/#FALSE# */
-  if (!strcmpW(strIn, szFalse))
+  if (!wcscmp(strIn, szFalse))
     *pBoolOut = VARIANT_FALSE;
-  else if (!strcmpW(strIn, szTrue))
+  else if (!wcscmp(strIn, szTrue))
     *pBoolOut = VARIANT_TRUE;
   else
   {
@@ -6356,7 +6357,7 @@ static BSTR VARIANT_MakeBstr(LCID lcid, DWORD dwFlags, WCHAR *szOut)
                      szOut, NULL, szConverted, ARRAY_SIZE(szConverted));
     szOut = szConverted;
   }
-  return SysAllocStringByteLen((LPCSTR)szOut, strlenW(szOut) * sizeof(WCHAR));
+  return SysAllocStringByteLen((LPCSTR)szOut, lstrlenW(szOut) * sizeof(WCHAR));
 }
 
 /* Create a (possibly localised) BSTR from a UI8 and sign */
@@ -6487,8 +6488,8 @@ static BSTR VARIANT_BstrReplaceDecimal(const WCHAR * buff, LCID lcid, ULONG dwFl
     minFormat.NegativeOrder = 1; /* NLS_NEG_LEFT */
 
     /* count number of decimal digits in string */
-    p = strchrW( buff, '.' );
-    if (p) minFormat.NumDigits = strlenW(p + 1);
+    p = wcschr( buff, '.' );
+    if (p) minFormat.NumDigits = lstrlenW(p + 1);
 
     numbuff[0] = '\0';
     if (!GetNumberFormatW(lcid, 0, buff, &minFormat, numbuff, ARRAY_SIZE(numbuff)))
@@ -6513,7 +6514,7 @@ static HRESULT VARIANT_BstrFromReal(DOUBLE dblIn, LCID lcid, ULONG dwFlags,
   if (!pbstrOut)
     return E_INVALIDARG;
 
-  sprintfW( buff, lpszFormat, dblIn );
+  swprintf( buff, lpszFormat, dblIn );
 
   /* Negative zeroes are disallowed (some applications depend on this).
      If buff starts with a minus, and then nothing follows but zeroes
@@ -6523,7 +6524,7 @@ static HRESULT VARIANT_BstrFromReal(DOUBLE dblIn, LCID lcid, ULONG dwFlags,
   if (buff[0] == '-')
   {
     static const WCHAR szAccept[] = {'0', '.', '\0'};
-    if (strlenW(buff + 1) == strspnW(buff + 1, szAccept))
+    if (lstrlenW(buff + 1) == wcsspn(buff + 1, szAccept))
     { buff[0] = '0'; buff[1] = '\0'; }
   }
 
@@ -6814,7 +6815,7 @@ HRESULT WINAPI VarBstrFromDate(DATE dateIn, LCID lcid, ULONG dwFlags, BSTR* pbst
 
   if (!(dwFlags & VAR_DATEVALUEONLY))
   {
-    time = date + strlenW(date);
+    time = date + lstrlenW(date);
     if (time != date)
       *time++ = ' ';
     if (!GetTimeFormatW(lcid, dwFormatFlags, &st, NULL, time, ARRAY_SIZE(date)-(time-date)))
@@ -7658,25 +7659,25 @@ HRESULT WINAPI VarDateFromStr(OLECHAR* strIn, LCID lcid, ULONG dwFlags, DATE* pd
   /* Parse the string into our structure */
   while (*strIn)
   {
-    if (isdigitW(*strIn))
+    if (iswdigit(*strIn))
     {
       if (dp.dwCount >= 6)
       {
         hRet = DISP_E_TYPEMISMATCH;
         break;
       }
-      dp.dwValues[dp.dwCount] = strtoulW(strIn, &strIn, 10);
+      dp.dwValues[dp.dwCount] = wcstoul(strIn, &strIn, 10);
       dp.dwCount++;
       strIn--;
     }
-    else if (isalphaW(*strIn))
+    else if (iswalpha(*strIn))
     {
       BOOL bFound = FALSE;
 
       for (i = 0; i < ARRAY_SIZE(tokens); i++)
       {
-        DWORD dwLen = strlenW(tokens[i]);
-        if (dwLen && !strncmpiW(strIn, tokens[i], dwLen))
+        DWORD dwLen = lstrlenW(tokens[i]);
+        if (dwLen && !_wcsnicmp(strIn, tokens[i], dwLen))
         {
           if (i <= 25)
           {
@@ -7755,7 +7756,7 @@ HRESULT WINAPI VarDateFromStr(OLECHAR* strIn, LCID lcid, ULONG dwFlags, DATE* pd
       else
         dp.dwFlags[dp.dwCount - 1] |= DP_DATESEP;
     }
-    else if (*strIn == ',' || isspaceW(*strIn))
+    else if (*strIn == ',' || iswspace(*strIn))
     {
       if (*strIn == ',' && !strIn[1])
         hRet = DISP_E_TYPEMISMATCH;
index 2d0c7cc..ab5540d 100644 (file)
@@ -142,7 +142,7 @@ dll/win32/odbc32              # Synced to WineStaging-4.18. Depends on port of L
 dll/win32/odbccp32            # Synced to WineStaging-4.18
 dll/win32/ole32               # Synced to WineStaging-4.18
 dll/win32/oleacc              # Synced to WineStaging-4.18
-dll/win32/oleaut32            # Synced to WineStaging-4.0
+dll/win32/oleaut32            # Synced to WineStaging-4.18
 dll/win32/olecli32            # Synced to WineStaging-3.3
 dll/win32/oledlg              # Synced to WineStaging-4.0
 dll/win32/olepro32            # Synced to WineStaging-3.3