[OLEAUT32] Sync with Wine Staging 4.0. CORE-15682
authorAmine Khaldi <amine.khaldi@reactos.org>
Tue, 29 Jan 2019 12:18:42 +0000 (13:18 +0100)
committerAmine Khaldi <amine.khaldi@reactos.org>
Tue, 29 Jan 2019 12:18:42 +0000 (13:18 +0100)
15 files changed:
dll/win32/oleaut32/CMakeLists.txt
dll/win32/oleaut32/msvc.S
dll/win32/oleaut32/oleaut.c
dll/win32/oleaut32/olefont.c
dll/win32/oleaut32/olepicture.c
dll/win32/oleaut32/safearray.c
dll/win32/oleaut32/tmarshal.c [deleted file]
dll/win32/oleaut32/typelib.c
dll/win32/oleaut32/typelib.h
dll/win32/oleaut32/usrmarshal.c
dll/win32/oleaut32/varformat.c
dll/win32/oleaut32/variant.c
dll/win32/oleaut32/vartype.c
media/doc/README.WINE
sdk/include/psdk/oleauto.h

index 26c2149..1eae81e 100644 (file)
@@ -25,7 +25,6 @@ list(APPEND SOURCE
     olepropframe.c
     recinfo.c
     safearray.c
     olepropframe.c
     recinfo.c
     safearray.c
-    tmarshal.c
     typelib.c
     usrmarshal.c
     varformat.c
     typelib.c
     usrmarshal.c
     varformat.c
index ddb3fa8..0d088d3 100644 (file)
@@ -49,6 +49,11 @@ cm1:
     pop esi
     pop ebp
     ret
     pop esi
     pop ebp
     ret
+
+PUBLIC _call_double_method
+_call_double_method:
+    jmp _call_method
+
 #endif
 
     END
 #endif
 
     END
index ee3ff27..8c5d68f 100644 (file)
@@ -21,6 +21,7 @@
 #include "config.h"
 
 #include <stdarg.h>
 #include "config.h"
 
 #include <stdarg.h>
+#include <stdio.h>
 #include <string.h>
 #include <limits.h>
 
 #include <string.h>
 #include <limits.h>
 
@@ -122,9 +123,7 @@ static inline bstr_t *bstr_from_str(BSTR str)
 
 static inline bstr_cache_entry_t *get_cache_entry_from_idx(unsigned cache_idx)
 {
 
 static inline bstr_cache_entry_t *get_cache_entry_from_idx(unsigned cache_idx)
 {
-    return bstr_cache_enabled && cache_idx < sizeof(bstr_cache)/sizeof(*bstr_cache)
-        ? bstr_cache + cache_idx
-        : NULL;
+    return bstr_cache_enabled && cache_idx < ARRAY_SIZE(bstr_cache) ? bstr_cache + cache_idx : NULL;
 }
 
 static inline bstr_cache_entry_t *get_cache_entry(size_t size)
 }
 
 static inline bstr_cache_entry_t *get_cache_entry(size_t size)
@@ -272,7 +271,7 @@ static inline IMalloc *get_malloc(void)
  *  See BSTR.
  *  str may be NULL, in which case this function does nothing.
  */
  *  See BSTR.
  *  str may be NULL, in which case this function does nothing.
  */
-void WINAPI SysFreeString(BSTR str)
+void WINAPI DECLSPEC_HOTPATCH SysFreeString(BSTR str)
 {
     bstr_cache_entry_t *cache_entry;
     bstr_t *bstr;
 {
     bstr_cache_entry_t *cache_entry;
     bstr_t *bstr;
@@ -304,7 +303,7 @@ void WINAPI SysFreeString(BSTR str)
             }
         }
 
             }
         }
 
-        if(cache_entry->cnt < sizeof(cache_entry->buf)/sizeof(*cache_entry->buf)) {
+        if(cache_entry->cnt < ARRAY_SIZE(cache_entry->buf)) {
             cache_entry->buf[(cache_entry->head+cache_entry->cnt) % BUCKET_BUFFER_SIZE] = bstr;
             cache_entry->cnt++;
 
             cache_entry->buf[(cache_entry->head+cache_entry->cnt) % BUCKET_BUFFER_SIZE] = bstr;
             cache_entry->cnt++;
 
@@ -429,7 +428,7 @@ int WINAPI SysReAllocStringLen(BSTR* old, const OLECHAR* str, unsigned int len)
  *  without checking for a terminating NUL.
  *  See BSTR.
  */
  *  without checking for a terminating NUL.
  *  See BSTR.
  */
-BSTR WINAPI SysAllocStringByteLen(LPCSTR str, UINT len)
+BSTR WINAPI DECLSPEC_HOTPATCH SysAllocStringByteLen(LPCSTR str, UINT len)
 {
     bstr_t *bstr;
 
 {
     bstr_t *bstr;
 
@@ -768,6 +767,230 @@ extern BOOL WINAPI OLEAUTPS_DllMain(HINSTANCE, DWORD, LPVOID) DECLSPEC_HIDDEN;
 extern HRESULT WINAPI OLEAUTPS_DllRegisterServer(void) DECLSPEC_HIDDEN;
 extern HRESULT WINAPI OLEAUTPS_DllUnregisterServer(void) DECLSPEC_HIDDEN;
 
 extern HRESULT WINAPI OLEAUTPS_DllRegisterServer(void) DECLSPEC_HIDDEN;
 extern HRESULT WINAPI OLEAUTPS_DllUnregisterServer(void) DECLSPEC_HIDDEN;
 
+extern HRESULT WINAPI CreateProxyFromTypeInfo(ITypeInfo *typeinfo,
+        IUnknown *outer, REFIID iid, IRpcProxyBuffer **proxy, void **obj);
+extern HRESULT WINAPI CreateStubFromTypeInfo(ITypeInfo *typeinfo, REFIID iid,
+        IUnknown *server, IRpcStubBuffer **stub);
+
+struct ifacepsredirect_data
+{
+    ULONG size;
+    DWORD mask;
+    GUID  iid;
+    ULONG nummethods;
+    GUID  tlbid;
+    GUID  base;
+    ULONG name_len;
+    ULONG name_offset;
+};
+
+struct tlibredirect_data
+{
+    ULONG  size;
+    DWORD  res;
+    ULONG  name_len;
+    ULONG  name_offset;
+    LANGID langid;
+    WORD   flags;
+    ULONG  help_len;
+    ULONG  help_offset;
+    WORD   major_version;
+    WORD   minor_version;
+};
+
+static BOOL actctx_get_typelib_module(REFIID iid, WCHAR *module, DWORD len)
+{
+    struct ifacepsredirect_data *iface;
+    struct tlibredirect_data *tlib;
+    ACTCTX_SECTION_KEYED_DATA data;
+    WCHAR *ptrW;
+
+    data.cbSize = sizeof(data);
+    if (!FindActCtxSectionGuid(0, NULL, ACTIVATION_CONTEXT_SECTION_COM_INTERFACE_REDIRECTION,
+            iid, &data))
+        return FALSE;
+
+    iface = (struct ifacepsredirect_data *)data.lpData;
+    if (!FindActCtxSectionGuid(0, NULL, ACTIVATION_CONTEXT_SECTION_COM_TYPE_LIBRARY_REDIRECTION,
+            &iface->tlbid, &data))
+        return FALSE;
+
+    tlib = (struct tlibredirect_data *)data.lpData;
+    ptrW = (WCHAR *)((BYTE *)data.lpSectionBase + tlib->name_offset);
+
+    if (tlib->name_len/sizeof(WCHAR) >= len)
+    {
+        ERR("need larger module buffer, %u\n", tlib->name_len);
+        return FALSE;
+    }
+
+    memcpy(module, ptrW, tlib->name_len);
+    module[tlib->name_len/sizeof(WCHAR)] = 0;
+    return TRUE;
+}
+
+static HRESULT reg_get_typelib_module(REFIID iid, WCHAR *module, DWORD len)
+{
+    REGSAM opposite = (sizeof(void*) == 8) ? KEY_WOW64_32KEY : KEY_WOW64_64KEY;
+    char tlguid[200], typelibkey[300], interfacekey[300], ver[100], tlfn[260];
+    DWORD tlguidlen, verlen, type;
+    LONG tlfnlen, err;
+    BOOL is_wow64;
+    HKEY ikey;
+
+    sprintf( interfacekey, "Interface\\{%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}\\Typelib",
+        iid->Data1, iid->Data2, iid->Data3,
+        iid->Data4[0], iid->Data4[1], iid->Data4[2], iid->Data4[3],
+        iid->Data4[4], iid->Data4[5], iid->Data4[6], iid->Data4[7]
+    );
+
+    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, (BYTE *)tlguid, &tlguidlen))
+    {
+        ERR("Getting typelib guid failed.\n");
+        RegCloseKey(ikey);
+        return E_FAIL;
+    }
+
+    verlen = sizeof(ver);
+    if (RegQueryValueExA(ikey, "Version", NULL, &type, (BYTE *)ver, &verlen))
+    {
+        ERR("Could not get version value?\n");
+        RegCloseKey(ikey);
+        return E_FAIL;
+    }
+
+    RegCloseKey(ikey);
+
+    sprintf(typelibkey, "Typelib\\%s\\%s\\0\\win%u", tlguid, ver, sizeof(void *) == 8 ? 64 : 32);
+    tlfnlen = sizeof(tlfn);
+    if (RegQueryValueA(HKEY_CLASSES_ROOT, typelibkey, tlfn, &tlfnlen))
+    {
+#ifdef _WIN64
+        sprintf(typelibkey, "Typelib\\%s\\%s\\0\\win32", tlguid, ver);
+        tlfnlen = sizeof(tlfn);
+        if (RegQueryValueA(HKEY_CLASSES_ROOT, typelibkey, tlfn, &tlfnlen))
+        {
+#endif
+            ERR("Could not get typelib fn?\n");
+            return E_FAIL;
+#ifdef _WIN64
+        }
+#endif
+    }
+    MultiByteToWideChar(CP_ACP, 0, tlfn, -1, module, len);
+    return S_OK;
+}
+
+static HRESULT get_typeinfo_for_iid(REFIID iid, ITypeInfo **typeinfo)
+{
+    WCHAR module[MAX_PATH];
+    ITypeLib *typelib;
+    HRESULT hr;
+
+    *typeinfo = NULL;
+
+    module[0] = 0;
+    if (!actctx_get_typelib_module(iid, module, ARRAY_SIZE(module)))
+    {
+        hr = reg_get_typelib_module(iid, module, ARRAY_SIZE(module));
+        if (FAILED(hr))
+            return hr;
+    }
+
+    hr = LoadTypeLib(module, &typelib);
+    if (hr != S_OK) {
+        ERR("Failed to load typelib for %s, but it should be there.\n", debugstr_guid(iid));
+        return hr;
+    }
+
+    hr = ITypeLib_GetTypeInfoOfGuid(typelib, iid, typeinfo);
+    ITypeLib_Release(typelib);
+    if (hr != S_OK)
+        ERR("typelib does not contain info for %s\n", debugstr_guid(iid));
+
+    return hr;
+}
+
+static HRESULT WINAPI typelib_ps_QueryInterface(IPSFactoryBuffer *iface, REFIID iid, void **out)
+{
+    if (IsEqualIID(iid, &IID_IPSFactoryBuffer) || IsEqualIID(iid, &IID_IUnknown))
+    {
+        *out = iface;
+        return S_OK;
+    }
+
+    FIXME("No interface for %s.\n", debugstr_guid(iid));
+    *out = NULL;
+    return E_NOINTERFACE;
+}
+
+static ULONG WINAPI typelib_ps_AddRef(IPSFactoryBuffer *iface)
+{
+    return 2;
+}
+
+static ULONG WINAPI typelib_ps_Release(IPSFactoryBuffer *iface)
+{
+    return 1;
+}
+
+static HRESULT WINAPI typelib_ps_CreateProxy(IPSFactoryBuffer *iface,
+    IUnknown *outer, REFIID iid, IRpcProxyBuffer **proxy, void **out)
+{
+    ITypeInfo *typeinfo;
+    HRESULT hr;
+
+    hr = get_typeinfo_for_iid(iid, &typeinfo);
+    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);
+    return hr;
+}
+
+static HRESULT WINAPI typelib_ps_CreateStub(IPSFactoryBuffer *iface, REFIID iid,
+    IUnknown *server, IRpcStubBuffer **stub)
+{
+    ITypeInfo *typeinfo;
+    HRESULT hr;
+
+    hr = get_typeinfo_for_iid(iid, &typeinfo);
+    if (FAILED(hr)) return hr;
+
+    hr = CreateStubFromTypeInfo(typeinfo, iid, server, stub);
+    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 *);
 
 extern void _get_STDFONT_CF(LPVOID *);
 extern void _get_STDPIC_CF(LPVOID *);
 
@@ -793,40 +1016,42 @@ static ULONG WINAPI PSDispatchFacBuf_Release(IPSFactoryBuffer *iface)
     return 1;
 }
 
     return 1;
 }
 
-static HRESULT WINAPI PSDispatchFacBuf_CreateProxy(IPSFactoryBuffer *iface, IUnknown *pUnkOuter, REFIID riid, IRpcProxyBuffer **ppProxy, void **ppv)
+static HRESULT WINAPI PSDispatchFacBuf_CreateProxy(IPSFactoryBuffer *iface,
+    IUnknown *outer, REFIID iid, IRpcProxyBuffer **proxy, void **obj)
 {
 {
-    IPSFactoryBuffer *pPSFB;
+    IPSFactoryBuffer *factory;
     HRESULT hr;
 
     HRESULT hr;
 
-    if (IsEqualIID(riid, &IID_IDispatch))
-        hr = OLEAUTPS_DllGetClassObject(&CLSID_PSFactoryBuffer, &IID_IPSFactoryBuffer, (void **)&pPSFB);
-    else
-        hr = TMARSHAL_DllGetClassObject(&CLSID_PSOAInterface, &IID_IPSFactoryBuffer, (void **)&pPSFB);
-
-    if (FAILED(hr)) return hr;
-
-    hr = IPSFactoryBuffer_CreateProxy(pPSFB, pUnkOuter, riid, ppProxy, ppv);
+    if (IsEqualIID(iid, &IID_IDispatch))
+    {
+        hr = OLEAUTPS_DllGetClassObject(&CLSID_PSFactoryBuffer, &IID_IPSFactoryBuffer, (void **)&factory);
+        if (FAILED(hr)) return hr;
 
 
-    IPSFactoryBuffer_Release(pPSFB);
-    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);
 }
 
 }
 
-static HRESULT WINAPI PSDispatchFacBuf_CreateStub(IPSFactoryBuffer *iface, REFIID riid, IUnknown *pUnkOuter, IRpcStubBuffer **ppStub)
+static HRESULT WINAPI PSDispatchFacBuf_CreateStub(IPSFactoryBuffer *iface,
+    REFIID iid, IUnknown *server, IRpcStubBuffer **stub)
 {
 {
-    IPSFactoryBuffer *pPSFB;
+    IPSFactoryBuffer *factory;
     HRESULT hr;
 
     HRESULT hr;
 
-    if (IsEqualIID(riid, &IID_IDispatch))
-        hr = OLEAUTPS_DllGetClassObject(&CLSID_PSFactoryBuffer, &IID_IPSFactoryBuffer, (void **)&pPSFB);
-    else
-        hr = TMARSHAL_DllGetClassObject(&CLSID_PSOAInterface, &IID_IPSFactoryBuffer, (void **)&pPSFB);
-
-    if (FAILED(hr)) return hr;
-
-    hr = IPSFactoryBuffer_CreateStub(pPSFB, riid, pUnkOuter, ppStub);
+    if (IsEqualIID(iid, &IID_IDispatch))
+    {
+        hr = OLEAUTPS_DllGetClassObject(&CLSID_PSFactoryBuffer, &IID_IPSFactoryBuffer, (void **)&factory);
+        if (FAILED(hr)) return hr;
 
 
-    IPSFactoryBuffer_Release(pPSFB);
-    return hr;
+        hr = IPSFactoryBuffer_CreateStub(factory, iid, server, stub);
+        IPSFactoryBuffer_Release(factory);
+        return hr;
+    }
+    else
+        return IPSFactoryBuffer_CreateStub(&typelib_ps, iid, server, stub);
 }
 
 static const IPSFactoryBufferVtbl PSDispatchFacBuf_Vtbl =
 }
 
 static const IPSFactoryBufferVtbl PSDispatchFacBuf_Vtbl =
@@ -866,11 +1091,10 @@ HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID iid, LPVOID *ppv)
         IPSFactoryBuffer_AddRef((IPSFactoryBuffer *)*ppv);
         return S_OK;
     }
         IPSFactoryBuffer_AddRef((IPSFactoryBuffer *)*ppv);
         return S_OK;
     }
-    if (IsEqualGUID(rclsid,&CLSID_PSOAInterface)) {
-       if (S_OK==TMARSHAL_DllGetClassObject(rclsid,iid,ppv))
-           return S_OK;
-       /*FALLTHROUGH*/
-    }
+
+    if (IsEqualGUID(rclsid, &CLSID_PSOAInterface))
+        return IPSFactoryBuffer_QueryInterface(&typelib_ps, iid, ppv);
+
     if (IsEqualCLSID(rclsid, &CLSID_PSTypeComp) ||
         IsEqualCLSID(rclsid, &CLSID_PSTypeInfo) ||
         IsEqualCLSID(rclsid, &CLSID_PSTypeLib) ||
     if (IsEqualCLSID(rclsid, &CLSID_PSTypeComp) ||
         IsEqualCLSID(rclsid, &CLSID_PSTypeInfo) ||
         IsEqualCLSID(rclsid, &CLSID_PSTypeLib) ||
index c20093c..9628dc0 100644 (file)
@@ -591,7 +591,7 @@ static void realize_font(OLEFontImpl *This)
     if(This->gdiFont)
     {
         old_font = SelectObject(hdc, This->gdiFont);
     if(This->gdiFont)
     {
         old_font = SelectObject(hdc, This->gdiFont);
-        GetTextFaceW(hdc, sizeof(text_face) / sizeof(text_face[0]), text_face);
+        GetTextFaceW(hdc, ARRAY_SIZE(text_face), text_face);
         SelectObject(hdc, old_font);
         dec_int_ref(This->gdiFont);
         This->gdiFont = 0;
         SelectObject(hdc, old_font);
         dec_int_ref(This->gdiFont);
         This->gdiFont = 0;
@@ -645,7 +645,7 @@ static void realize_font(OLEFontImpl *This)
     /* Fixup the name and charset properties so that they match the
        selected font */
     old_font = SelectObject(get_dc(), This->gdiFont);
     /* Fixup the name and charset properties so that they match the
        selected font */
     old_font = SelectObject(get_dc(), This->gdiFont);
-    GetTextFaceW(hdc, sizeof(text_face) / sizeof(text_face[0]), text_face);
+    GetTextFaceW(hdc, ARRAY_SIZE(text_face), text_face);
     if(lstrcmpiW(text_face, This->description.lpstrName))
     {
         HeapFree(GetProcessHeap(), 0, This->description.lpstrName);
     if(lstrcmpiW(text_face, This->description.lpstrName))
     {
         HeapFree(GetProcessHeap(), 0, This->description.lpstrName);
index 96304e0..702fcde 100644 (file)
@@ -287,9 +287,10 @@ static void OLEPictureImpl_SetEMF(OLEPictureImpl *This)
  * The caller of this method must release the object when it's
  * done with it.
  */
  * The caller of this method must release the object when it's
  * done with it.
  */
-static OLEPictureImpl* OLEPictureImpl_Construct(LPPICTDESC pictDesc, BOOL fOwn)
+static HRESULT OLEPictureImpl_Construct(LPPICTDESC pictDesc, BOOL fOwn, OLEPictureImpl **pict)
 {
 {
-  OLEPictureImpl* newObject = 0;
+  OLEPictureImpl *newObject;
+  HRESULT hr;
 
   if (pictDesc)
       TRACE("(%p) type = %d\n", pictDesc, pictDesc->picType);
 
   if (pictDesc)
       TRACE("(%p) type = %d\n", pictDesc, pictDesc->picType);
@@ -298,9 +299,8 @@ static OLEPictureImpl* OLEPictureImpl_Construct(LPPICTDESC pictDesc, BOOL fOwn)
    * Allocate space for the object.
    */
   newObject = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(OLEPictureImpl));
    * Allocate space for the object.
    */
   newObject = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(OLEPictureImpl));
-
-  if (newObject==0)
-    return newObject;
+  if (!newObject)
+    return E_OUTOFMEMORY;
 
   /*
    * Initialize the virtual function table.
 
   /*
    * Initialize the virtual function table.
@@ -311,12 +311,12 @@ static OLEPictureImpl* OLEPictureImpl_Construct(LPPICTDESC pictDesc, BOOL fOwn)
   newObject->IConnectionPointContainer_iface.lpVtbl = &OLEPictureImpl_IConnectionPointContainer_VTable;
 
   newObject->pCP = NULL;
   newObject->IConnectionPointContainer_iface.lpVtbl = &OLEPictureImpl_IConnectionPointContainer_VTable;
 
   newObject->pCP = NULL;
-  CreateConnectionPoint((IUnknown*)&newObject->IPicture_iface, &IID_IPropertyNotifySink,
+  hr = CreateConnectionPoint((IUnknown*)&newObject->IPicture_iface, &IID_IPropertyNotifySink,
                         &newObject->pCP);
                         &newObject->pCP);
-  if (!newObject->pCP)
+  if (hr != S_OK)
   {
     HeapFree(GetProcessHeap(), 0, newObject);
   {
     HeapFree(GetProcessHeap(), 0, newObject);
-    return NULL;
+    return hr;
   }
 
   /*
   }
 
   /*
@@ -365,16 +365,17 @@ static OLEPictureImpl* OLEPictureImpl_Construct(LPPICTDESC pictDesc, BOOL fOwn)
         break;
 
       default:
         break;
 
       default:
-       FIXME("Unsupported type %d\n", pictDesc->picType);
-       newObject->himetricWidth = newObject->himetricHeight = 0;
-       break;
+        WARN("Unsupported type %d\n", pictDesc->picType);
+        IPicture_Release(&newObject->IPicture_iface);
+        return E_UNEXPECTED;
       }
   } else {
       newObject->desc.picType = PICTYPE_UNINITIALIZED;
   }
 
   TRACE("returning %p\n", newObject);
       }
   } else {
       newObject->desc.picType = PICTYPE_UNINITIALIZED;
   }
 
   TRACE("returning %p\n", newObject);
-  return newObject;
+  *pict = newObject;
+  return S_OK;
 }
 
 /************************************************************************
 }
 
 /************************************************************************
@@ -565,37 +566,19 @@ static HRESULT WINAPI OLEPictureImpl_get_Handle(IPicture *iface,
 static HRESULT WINAPI OLEPictureImpl_get_hPal(IPicture *iface,
                                              OLE_HANDLE *phandle)
 {
 static HRESULT WINAPI OLEPictureImpl_get_hPal(IPicture *iface,
                                              OLE_HANDLE *phandle)
 {
-  OLEPictureImpl *This = impl_from_IPicture(iface);
-  HRESULT hres;
-  TRACE("(%p)->(%p)\n", This, phandle);
+    OLEPictureImpl *This = impl_from_IPicture(iface);
 
 
-  if (!phandle)
-    return E_POINTER;
+    TRACE("(%p)->(%p)\n", This, phandle);
 
 
-  switch (This->desc.picType) {
-    case (UINT)PICTYPE_UNINITIALIZED:
-    case PICTYPE_NONE:
-      *phandle = 0;
-      hres = S_FALSE;
-      break;
-    case PICTYPE_BITMAP:
-      *phandle = HandleToUlong(This->desc.u.bmp.hpal);
-      hres = S_OK;
-      break;
-    case PICTYPE_METAFILE:
-      hres = E_FAIL;
-      break;
-    case PICTYPE_ICON:
-    case PICTYPE_ENHMETAFILE:
-    default:
-      FIXME("unimplemented for type %d. Returning 0 palette.\n",
-           This->desc.picType);
-      *phandle = 0;
-      hres = S_OK;
-  }
+    if (!phandle) return E_POINTER;
 
 
-  TRACE("returning 0x%08x, palette handle %08x\n", hres, *phandle);
-  return hres;
+    if (This->desc.picType == PICTYPE_BITMAP)
+    {
+        *phandle = HandleToUlong(This->desc.u.bmp.hpal);
+        return S_OK;
+    }
+
+    return E_FAIL;
 }
 
 /************************************************************************
 }
 
 /************************************************************************
@@ -638,6 +621,48 @@ static HRESULT WINAPI OLEPictureImpl_get_Height(IPicture *iface,
   return S_OK;
 }
 
   return S_OK;
 }
 
+static void render_masked_bitmap(OLEPictureImpl *This, HDC hdc,
+    LONG x, LONG y, LONG cx, LONG cy, OLE_XPOS_HIMETRIC xSrc, OLE_YPOS_HIMETRIC ySrc,
+    OLE_XSIZE_HIMETRIC cxSrc, OLE_YSIZE_HIMETRIC cySrc, HBITMAP hbmMask, HBITMAP hbmXor)
+{
+    HDC hdcBmp;
+
+    /* Set a mapping mode that maps bitmap pixels into HIMETRIC units.
+     * NB y-axis gets flipped
+     */
+
+    hdcBmp = CreateCompatibleDC(0);
+    SetMapMode(hdcBmp, MM_ANISOTROPIC);
+    SetWindowOrgEx(hdcBmp, 0, 0, NULL);
+    SetWindowExtEx(hdcBmp, This->himetricWidth, This->himetricHeight, NULL);
+    SetViewportOrgEx(hdcBmp, 0, This->origHeight, NULL);
+    SetViewportExtEx(hdcBmp, This->origWidth, -This->origHeight, NULL);
+
+    if (hbmMask)
+    {
+        SetBkColor(hdc, RGB(255, 255, 255));
+        SetTextColor(hdc, RGB(0, 0, 0));
+
+        SelectObject(hdcBmp, hbmMask);
+        StretchBlt(hdc, x, y, cx, cy, hdcBmp, xSrc, ySrc, cxSrc, cySrc, SRCAND);
+
+        if (hbmXor)
+        {
+            SelectObject(hdcBmp, hbmXor);
+            StretchBlt(hdc, x, y, cx, cy, hdcBmp, xSrc, ySrc, cxSrc, cySrc, SRCPAINT);
+        }
+        else StretchBlt(hdc, x, y, cx, cy, hdcBmp, xSrc, ySrc - This->himetricHeight,
+                        cxSrc, cySrc, SRCPAINT);
+    }
+    else
+    {
+        SelectObject(hdcBmp, hbmXor);
+        StretchBlt(hdc, x, y, cx, cy, hdcBmp, xSrc, ySrc, cxSrc, cySrc, SRCCOPY);
+    }
+
+    DeleteDC(hdcBmp);
+}
+
 /************************************************************************
  * OLEPictureImpl_Render
  */
 /************************************************************************
  * OLEPictureImpl_Render
  */
@@ -671,52 +696,37 @@ static HRESULT WINAPI OLEPictureImpl_Render(IPicture *iface, HDC hdc,
     /* nothing to do */
     return S_OK;
   case PICTYPE_BITMAP:
     /* nothing to do */
     return S_OK;
   case PICTYPE_BITMAP:
-    {
-      HBITMAP hbmpOld;
-      HDC hdcBmp;
-
-      /* Set a mapping mode that maps bitmap pixels into HIMETRIC units.
-         NB y-axis gets flipped */
-
-      hdcBmp = CreateCompatibleDC(0);
-      SetMapMode(hdcBmp, MM_ANISOTROPIC);
-      SetWindowOrgEx(hdcBmp, 0, 0, NULL);
-      SetWindowExtEx(hdcBmp, This->himetricWidth, This->himetricHeight, NULL);
-      SetViewportOrgEx(hdcBmp, 0, This->origHeight, NULL);
-      SetViewportExtEx(hdcBmp, This->origWidth, -This->origHeight, NULL);
-
-      if (This->hbmMask) {
-         HDC hdcMask = CreateCompatibleDC(0);
-         HBITMAP hOldbm = SelectObject(hdcMask, This->hbmMask);
-
-          hbmpOld = SelectObject(hdcBmp, This->hbmXor);
-
-         SetMapMode(hdcMask, MM_ANISOTROPIC);
-         SetWindowOrgEx(hdcMask, 0, 0, NULL);
-         SetWindowExtEx(hdcMask, This->himetricWidth, This->himetricHeight, NULL);
-         SetViewportOrgEx(hdcMask, 0, This->origHeight, NULL);
-         SetViewportExtEx(hdcMask, This->origWidth, -This->origHeight, NULL);
-         
-         SetBkColor(hdc, RGB(255, 255, 255));    
-         SetTextColor(hdc, RGB(0, 0, 0));        
-         StretchBlt(hdc, x, y, cx, cy, hdcMask, xSrc, ySrc, cxSrc, cySrc, SRCAND); 
-         StretchBlt(hdc, x, y, cx, cy, hdcBmp, xSrc, ySrc, cxSrc, cySrc, SRCPAINT);
-
-         SelectObject(hdcMask, hOldbm);
-         DeleteDC(hdcMask);
-      } else {
-          hbmpOld = SelectObject(hdcBmp, This->desc.u.bmp.hbitmap);
-         StretchBlt(hdc, x, y, cx, cy, hdcBmp, xSrc, ySrc, cxSrc, cySrc, SRCCOPY);
-      }
+  {
+    HBITMAP hbmMask, hbmXor;
 
 
-      SelectObject(hdcBmp, hbmpOld);
-      DeleteDC(hdcBmp);
+    if (This->hbmMask)
+    {
+        hbmMask = This->hbmMask;
+        hbmXor = This->hbmXor;
     }
     }
+    else
+    {
+        hbmMask = 0;
+        hbmXor = This->desc.u.bmp.hbitmap;
+    }
+
+    render_masked_bitmap(This, hdc, x, y, cx, cy, xSrc, ySrc, cxSrc, cySrc, hbmMask, hbmXor);
     break;
     break;
+  }
+
   case PICTYPE_ICON:
   case PICTYPE_ICON:
-    FIXME("Not quite correct implementation of rendering icons...\n");
-    DrawIconEx(hdc, x, y, This->desc.u.icon.hicon, cx, cy, 0, NULL, DI_NORMAL);
+  {
+    ICONINFO info;
+
+    if (!GetIconInfo(This->desc.u.icon.hicon, &info))
+        return E_FAIL;
+
+    render_masked_bitmap(This, hdc, x, y, cx, cy, xSrc, ySrc, cxSrc, cySrc, info.hbmMask, info.hbmColor);
+
+    DeleteObject(info.hbmMask);
+    if (info.hbmColor) DeleteObject(info.hbmColor);
     break;
     break;
+  }
 
   case PICTYPE_METAFILE:
   {
 
   case PICTYPE_METAFILE:
   {
@@ -767,10 +777,18 @@ static HRESULT WINAPI OLEPictureImpl_Render(IPicture *iface, HDC hdc,
 static HRESULT WINAPI OLEPictureImpl_set_hPal(IPicture *iface,
                                              OLE_HANDLE hpal)
 {
 static HRESULT WINAPI OLEPictureImpl_set_hPal(IPicture *iface,
                                              OLE_HANDLE hpal)
 {
-  OLEPictureImpl *This = impl_from_IPicture(iface);
-  FIXME("(%p)->(%08x): stub\n", This, hpal);
-  OLEPicture_SendNotify(This,DISPID_PICT_HPAL);
-  return E_NOTIMPL;
+    OLEPictureImpl *This = impl_from_IPicture(iface);
+
+    TRACE("(%p)->(%08x)\n", This, hpal);
+
+    if (This->desc.picType == PICTYPE_BITMAP)
+    {
+        This->desc.u.bmp.hpal = ULongToHandle(hpal);
+        OLEPicture_SendNotify(This,DISPID_PICT_HPAL);
+        return S_OK;
+    }
+
+    return E_FAIL;
 }
 
 /************************************************************************
 }
 
 /************************************************************************
@@ -2310,10 +2328,8 @@ HRESULT WINAPI OleCreatePictureIndirect(LPPICTDESC lpPictDesc, REFIID riid,
 
   *ppvObj = NULL;
 
 
   *ppvObj = NULL;
 
-  newPict = OLEPictureImpl_Construct(lpPictDesc, Own);
-
-  if (newPict == NULL)
-    return E_OUTOFMEMORY;
+  hr = OLEPictureImpl_Construct(lpPictDesc, Own, &newPict);
+  if (hr != S_OK) return hr;
 
   /*
    * Make sure it supports the interface required by the caller.
 
   /*
    * Make sure it supports the interface required by the caller.
@@ -2509,7 +2525,7 @@ HRESULT WINAPI OleLoadPicturePath( LPOLESTR szURLorPath, LPUNKNOWN punkCaller,
   if (strncmpW(szURLorPath, file, 5) == 0) {
       DWORD size;
       hRes = CoInternetParseUrl(szURLorPath, PARSE_PATH_FROM_URL, 0, path_buf,
   if (strncmpW(szURLorPath, file, 5) == 0) {
       DWORD size;
       hRes = CoInternetParseUrl(szURLorPath, PARSE_PATH_FROM_URL, 0, path_buf,
-                                sizeof(path_buf)/sizeof(WCHAR), &size, 0);
+                                ARRAY_SIZE(path_buf), &size, 0);
       if (FAILED(hRes))
           return hRes;
 
       if (FAILED(hRes))
           return hRes;
 
index 01dbfc3..64a5ab9 100644 (file)
@@ -289,7 +289,7 @@ static HRESULT SAFEARRAY_DestroyData(SAFEARRAY *psa, ULONG ulStartCell)
     ULONG ulCellCount = SAFEARRAY_GetCellCount(psa);
 
     if (ulStartCell > ulCellCount) {
     ULONG ulCellCount = SAFEARRAY_GetCellCount(psa);
 
     if (ulStartCell > ulCellCount) {
-      FIXME("unexpted ulcellcount %d, start %d\n",ulCellCount,ulStartCell);
+      FIXME("unexpected ulCellCount %d, start %d\n",ulCellCount,ulStartCell);
       return E_UNEXPECTED;
     }
 
       return E_UNEXPECTED;
     }
 
diff --git a/dll/win32/oleaut32/tmarshal.c b/dll/win32/oleaut32/tmarshal.c
deleted file mode 100644 (file)
index 7530f66..0000000
+++ /dev/null
@@ -1,2480 +0,0 @@
-/*
- *     TYPELIB Marshaler
- *
- *     Copyright 2002,2005     Marcus Meissner
- *
- * The olerelay debug channel allows you to see calls marshalled by
- * the typelib marshaller. It is not a generic COM relaying system.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "config.h"
-#include "wine/port.h"
-
-#include <assert.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdarg.h>
-#include <stdio.h>
-#include <ctype.h>
-
-#define COBJMACROS
-#define NONAMELESSUNION
-
-#include "winerror.h"
-#include "windef.h"
-#include "winbase.h"
-#include "winnls.h"
-#include "winreg.h"
-#include "winuser.h"
-
-#include "ole2.h"
-#include "propidl.h" /* for LPSAFEARRAY_User* functions */
-#include "typelib.h"
-#include "variant.h"
-#include "wine/debug.h"
-#include "wine/exception.h"
-
-static const WCHAR IDispatchW[] = { 'I','D','i','s','p','a','t','c','h',0};
-
-WINE_DEFAULT_DEBUG_CHANNEL(ole);
-WINE_DECLARE_DEBUG_CHANNEL(olerelay);
-
-static HRESULT TMarshalDispatchChannel_Create(
-    IRpcChannelBuffer *pDelegateChannel, REFIID tmarshal_riid,
-    IRpcChannelBuffer **ppChannel);
-
-typedef struct _marshal_state {
-    LPBYTE     base;
-    int                size;
-    int                curoff;
-} marshal_state;
-
-/* used in the olerelay code to avoid having the L"" stuff added by debugstr_w */
-static char *relaystr(WCHAR *in) {
-    char *tmp = (char *)debugstr_w(in);
-    tmp += 2;
-    tmp[strlen(tmp)-1] = '\0';
-    return tmp;
-}
-
-static HRESULT
-xbuf_resize(marshal_state *buf, DWORD newsize)
-{
-    if(buf->size >= newsize)
-        return S_FALSE;
-
-    if(buf->base)
-    {
-        newsize = max(newsize, buf->size * 2);
-        buf->base = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, buf->base, newsize);
-        if(!buf->base)
-            return E_OUTOFMEMORY;
-    }
-    else
-    {
-        newsize = max(newsize, 256);
-        buf->base = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, newsize);
-        if(!buf->base)
-            return E_OUTOFMEMORY;
-    }
-    buf->size = newsize;
-    return S_OK;
-}
-
-static HRESULT
-xbuf_add(marshal_state *buf, const BYTE *stuff, DWORD size)
-{
-    HRESULT hr;
-
-    if(buf->size - buf->curoff < size)
-    {
-        hr = xbuf_resize(buf, buf->size + size);
-        if(FAILED(hr)) return hr;
-    }
-    memcpy(buf->base+buf->curoff,stuff,size);
-    buf->curoff += size;
-    return S_OK;
-}
-
-static HRESULT
-xbuf_get(marshal_state *buf, LPBYTE stuff, DWORD size) {
-    if (buf->size < buf->curoff+size) return E_FAIL;
-    memcpy(stuff,buf->base+buf->curoff,size);
-    buf->curoff += size;
-    return S_OK;
-}
-
-static HRESULT
-xbuf_skip(marshal_state *buf, DWORD size) {
-    if (buf->size < buf->curoff+size) return E_FAIL;
-    buf->curoff += size;
-    return S_OK;
-}
-
-static HRESULT
-_unmarshal_interface(marshal_state *buf, REFIID riid, LPUNKNOWN *pUnk) {
-    IStream            *pStm;
-    ULARGE_INTEGER     newpos;
-    LARGE_INTEGER      seekto;
-    ULONG              res;
-    HRESULT            hres;
-    DWORD              xsize;
-
-    TRACE("...%s...\n",debugstr_guid(riid));
-    
-    *pUnk = NULL;
-    hres = xbuf_get(buf,(LPBYTE)&xsize,sizeof(xsize));
-    if (hres) {
-        ERR("xbuf_get failed\n");
-        return hres;
-    }
-    
-    if (xsize == 0) return S_OK;
-    
-    hres = CreateStreamOnHGlobal(0,TRUE,&pStm);
-    if (hres) {
-       ERR("Stream create failed %x\n",hres);
-       return hres;
-    }
-    
-    hres = IStream_Write(pStm,buf->base+buf->curoff,xsize,&res);
-    if (hres) {
-        ERR("stream write %x\n",hres);
-        IStream_Release(pStm);
-        return hres;
-    }
-    
-    memset(&seekto,0,sizeof(seekto));
-    hres = IStream_Seek(pStm,seekto,SEEK_SET,&newpos);
-    if (hres) {
-        ERR("Failed Seek %x\n",hres);
-        IStream_Release(pStm);
-        return hres;
-    }
-    
-    hres = CoUnmarshalInterface(pStm,riid,(LPVOID*)pUnk);
-    if (hres) {
-       ERR("Unmarshalling interface %s failed with %x\n",debugstr_guid(riid),hres);
-       IStream_Release(pStm);
-       return hres;
-    }
-    
-    IStream_Release(pStm);
-    return xbuf_skip(buf,xsize);
-}
-
-static HRESULT
-_marshal_interface(marshal_state *buf, REFIID riid, LPUNKNOWN pUnk) {
-    LPBYTE             tempbuf = NULL;
-    IStream            *pStm = NULL;
-    STATSTG            ststg;
-    ULARGE_INTEGER     newpos;
-    LARGE_INTEGER      seekto;
-    ULONG              res;
-    DWORD              xsize;
-    HRESULT            hres;
-
-    if (!pUnk) {
-       /* this is valid, if for instance we serialize
-        * a VT_DISPATCH with NULL ptr which apparently
-        * can happen. S_OK to make sure we continue
-        * serializing.
-        */
-        WARN("pUnk is NULL\n");
-        xsize = 0;
-        return xbuf_add(buf,(LPBYTE)&xsize,sizeof(xsize));
-    }
-
-    TRACE("...%s...\n",debugstr_guid(riid));
-    
-    hres = CreateStreamOnHGlobal(0,TRUE,&pStm);
-    if (hres) {
-       ERR("Stream create failed %x\n",hres);
-       goto fail;
-    }
-    
-    hres = CoMarshalInterface(pStm,riid,pUnk,0,NULL,0);
-    if (hres) {
-       ERR("Marshalling interface %s failed with %x\n", debugstr_guid(riid), hres);
-       goto fail;
-    }
-    
-    hres = IStream_Stat(pStm,&ststg,STATFLAG_NONAME);
-    if (hres) {
-        ERR("Stream stat failed\n");
-        goto fail;
-    }
-    
-    tempbuf = HeapAlloc(GetProcessHeap(), 0, ststg.cbSize.u.LowPart);
-    memset(&seekto,0,sizeof(seekto));
-    hres = IStream_Seek(pStm,seekto,SEEK_SET,&newpos);
-    if (hres) {
-        ERR("Failed Seek %x\n",hres);
-        goto fail;
-    }
-    
-    hres = IStream_Read(pStm,tempbuf,ststg.cbSize.u.LowPart,&res);
-    if (hres) {
-        ERR("Failed Read %x\n",hres);
-        goto fail;
-    }
-    
-    xsize = ststg.cbSize.u.LowPart;
-    xbuf_add(buf,(LPBYTE)&xsize,sizeof(xsize));
-    hres = xbuf_add(buf,tempbuf,ststg.cbSize.u.LowPart);
-    
-    HeapFree(GetProcessHeap(),0,tempbuf);
-    IStream_Release(pStm);
-    
-    return hres;
-    
-fail:
-    xsize = 0;
-    xbuf_add(buf,(LPBYTE)&xsize,sizeof(xsize));
-    if (pStm) IStream_Release(pStm);
-    HeapFree(GetProcessHeap(), 0, tempbuf);
-    return hres;
-}
-
-/********************* OLE Proxy/Stub Factory ********************************/
-static HRESULT WINAPI
-PSFacBuf_QueryInterface(LPPSFACTORYBUFFER iface, REFIID iid, LPVOID *ppv) {
-    if (IsEqualIID(iid,&IID_IPSFactoryBuffer)||IsEqualIID(iid,&IID_IUnknown)) {
-        *ppv = iface;
-       /* No ref counting, static class */
-       return S_OK;
-    }
-    FIXME("(%s) unknown IID?\n",debugstr_guid(iid));
-    return E_NOINTERFACE;
-}
-
-static ULONG WINAPI PSFacBuf_AddRef(LPPSFACTORYBUFFER iface) { return 2; }
-static ULONG WINAPI PSFacBuf_Release(LPPSFACTORYBUFFER iface) { return 1; }
-
-struct ifacepsredirect_data
-{
-    ULONG size;
-    DWORD mask;
-    GUID  iid;
-    ULONG nummethods;
-    GUID  tlbid;
-    GUID  base;
-    ULONG name_len;
-    ULONG name_offset;
-};
-
-struct tlibredirect_data
-{
-    ULONG  size;
-    DWORD  res;
-    ULONG  name_len;
-    ULONG  name_offset;
-    LANGID langid;
-    WORD   flags;
-    ULONG  help_len;
-    ULONG  help_offset;
-    WORD   major_version;
-    WORD   minor_version;
-};
-
-static BOOL actctx_get_typelib_module(REFIID riid, WCHAR *module, DWORD len)
-{
-    struct ifacepsredirect_data *iface;
-    struct tlibredirect_data *tlib;
-    ACTCTX_SECTION_KEYED_DATA data;
-    WCHAR *ptrW;
-
-    data.cbSize = sizeof(data);
-    if (!FindActCtxSectionGuid(0, NULL, ACTIVATION_CONTEXT_SECTION_COM_INTERFACE_REDIRECTION,
-            riid, &data))
-        return FALSE;
-
-    iface = (struct ifacepsredirect_data*)data.lpData;
-    if (!FindActCtxSectionGuid(0, NULL, ACTIVATION_CONTEXT_SECTION_COM_TYPE_LIBRARY_REDIRECTION,
-            &iface->tlbid, &data))
-        return FALSE;
-
-    tlib = (struct tlibredirect_data*)data.lpData;
-    ptrW = (WCHAR*)((BYTE*)data.lpSectionBase + tlib->name_offset);
-
-    if (tlib->name_len/sizeof(WCHAR) >= len) {
-        ERR("need larger module buffer, %u\n", tlib->name_len);
-        return FALSE;
-    }
-
-    memcpy(module, ptrW, tlib->name_len);
-    module[tlib->name_len/sizeof(WCHAR)] = 0;
-    return TRUE;
-}
-
-static HRESULT reg_get_typelib_module(REFIID riid, WCHAR *module, DWORD len)
-{
-    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];
-    DWORD      tlguidlen, verlen, type;
-    LONG       tlfnlen, err;
-
-    sprintf( interfacekey, "Interface\\{%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}\\Typelib",
-       riid->Data1, riid->Data2, riid->Data3,
-       riid->Data4[0], riid->Data4[1], riid->Data4[2], riid->Data4[3],
-       riid->Data4[4], riid->Data4[5], riid->Data4[6], riid->Data4[7]
-    );
-
-    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)) {
-       ERR("Getting typelib guid failed.\n");
-       RegCloseKey(ikey);
-       return E_FAIL;
-    }
-    verlen = sizeof(ver);
-    if (RegQueryValueExA(ikey,"Version",NULL,&type,(LPBYTE)ver,&verlen)) {
-       ERR("Could not get version value?\n");
-       RegCloseKey(ikey);
-       return E_FAIL;
-    }
-    RegCloseKey(ikey);
-    sprintf(typelibkey,"Typelib\\%s\\%s\\0\\win%u",tlguid,ver,(sizeof(void*) == 8) ? 64 : 32);
-    tlfnlen = sizeof(tlfn);
-    if (RegQueryValueA(HKEY_CLASSES_ROOT,typelibkey,tlfn,&tlfnlen)) {
-#ifdef _WIN64
-        sprintf(typelibkey,"Typelib\\%s\\%s\\0\\win32",tlguid,ver);
-        tlfnlen = sizeof(tlfn);
-        if (RegQueryValueA(HKEY_CLASSES_ROOT,typelibkey,tlfn,&tlfnlen)) {
-#endif
-            ERR("Could not get typelib fn?\n");
-            return E_FAIL;
-#ifdef _WIN64
-        }
-#endif
-    }
-    MultiByteToWideChar(CP_ACP, 0, tlfn, -1, module, len);
-    return S_OK;
-}
-
-static HRESULT
-_get_typeinfo_for_iid(REFIID riid, ITypeInfo **typeinfo)
-{
-    OLECHAR   moduleW[260];
-    ITypeLib *typelib;
-    HRESULT   hres;
-
-    *typeinfo = NULL;
-
-    moduleW[0] = 0;
-    if (!actctx_get_typelib_module(riid, moduleW, sizeof(moduleW)/sizeof(moduleW[0]))) {
-        hres = reg_get_typelib_module(riid, moduleW, sizeof(moduleW)/sizeof(moduleW[0]));
-        if (FAILED(hres))
-            return hres;
-    }
-
-    hres = LoadTypeLib(moduleW, &typelib);
-    if (hres != S_OK) {
-       ERR("Failed to load typelib for %s, but it should be there.\n",debugstr_guid(riid));
-       return hres;
-    }
-
-    hres = ITypeLib_GetTypeInfoOfGuid(typelib, riid, typeinfo);
-    ITypeLib_Release(typelib);
-    if (hres != S_OK)
-       ERR("typelib does not contain info for %s\n", debugstr_guid(riid));
-
-    return hres;
-}
-
-/*
- * Determine the number of functions including all inherited functions
- * and well as the size of the vtbl.
- * Note for non-dual dispinterfaces we simply return the size of IDispatch.
- */
-static HRESULT num_of_funcs(ITypeInfo *tinfo, unsigned int *num,
-                            unsigned int *vtbl_size)
-{
-    HRESULT hr;
-    TYPEATTR *attr;
-    ITypeInfo *tinfo2;
-    UINT inherited_funcs = 0, i;
-
-    *num = 0;
-    if(vtbl_size) *vtbl_size = 0;
-
-    hr = ITypeInfo_GetTypeAttr(tinfo, &attr);
-    if (hr)
-    {
-        ERR("GetTypeAttr failed with %x\n", hr);
-        return hr;
-    }
-
-    if(attr->typekind == TKIND_DISPATCH)
-    {
-        if(attr->wTypeFlags & TYPEFLAG_FDUAL)
-        {
-            HREFTYPE href;
-
-            ITypeInfo_ReleaseTypeAttr(tinfo, attr);
-            hr = ITypeInfo_GetRefTypeOfImplType(tinfo, -1, &href);
-            if(FAILED(hr))
-            {
-                ERR("Unable to get interface href from dual dispinterface\n");
-                return hr;
-            }
-            hr = ITypeInfo_GetRefTypeInfo(tinfo, href, &tinfo2);
-            if(FAILED(hr))
-            {
-                ERR("Unable to get interface from dual dispinterface\n");
-                return hr;
-            }
-            hr = num_of_funcs(tinfo2, num, vtbl_size);
-            ITypeInfo_Release(tinfo2);
-            return hr;
-        }
-        else /* non-dual dispinterface */
-        {
-            /* These will be the size of IDispatchVtbl */
-            *num = attr->cbSizeVft / sizeof(void *);
-            if(vtbl_size) *vtbl_size = attr->cbSizeVft;
-            ITypeInfo_ReleaseTypeAttr(tinfo, attr);
-            return hr;
-        }
-    }
-
-    for (i = 0; i < attr->cImplTypes; i++)
-    {
-        HREFTYPE href;
-        ITypeInfo *pSubTypeInfo;
-        UINT sub_funcs;
-
-        hr = ITypeInfo_GetRefTypeOfImplType(tinfo, i, &href);
-        if (FAILED(hr)) goto end;
-        hr = ITypeInfo_GetRefTypeInfo(tinfo, href, &pSubTypeInfo);
-        if (FAILED(hr)) goto end;
-
-        hr = num_of_funcs(pSubTypeInfo, &sub_funcs, NULL);
-        ITypeInfo_Release(pSubTypeInfo);
-
-        if(FAILED(hr)) goto end;
-        inherited_funcs += sub_funcs;
-    }
-
-    *num = inherited_funcs + attr->cFuncs;
-    if(vtbl_size) *vtbl_size = attr->cbSizeVft;
-
- end:
-    ITypeInfo_ReleaseTypeAttr(tinfo, attr);
-    return hr;
-}
-
-#ifdef __i386__
-
-#include "pshpack1.h"
-typedef struct _TMAsmProxy {
-    DWORD      lealeax;
-    BYTE       pushleax;
-    BYTE       pushlval;
-    DWORD      nr;
-    BYTE       lcall;
-    DWORD      xcall;
-    BYTE       lret;
-    WORD       bytestopop;
-    WORD       nop;
-} TMAsmProxy;
-#include "poppack.h"
-
-#elif defined(__x86_64__)
-
-#include "pshpack1.h"
-typedef struct _TMAsmProxy {
-    BYTE    pushq_rbp;
-    BYTE    movq_rsp_rbp[3];
-    DWORD   subq_0x20_rsp;
-    DWORD   movq_rcx_0x10rbp;
-    DWORD   movq_rdx_0x18rbp;
-    DWORD   movq_r8_0x20rbp;
-    DWORD   movq_r9_0x28rbp;
-    BYTE    movq_rcx[3];
-    DWORD   nr;
-    DWORD   leaq_0x10rbp_rdx;
-    WORD    movq_rax;
-    void   *xcall;
-    WORD    callq_rax;
-    BYTE    movq_rbp_rsp[3];
-    BYTE    popq_rbp;
-    BYTE    ret;
-    DWORD   nop;
-} TMAsmProxy;
-#include "poppack.h"
-
-#else /* __i386__ */
-#ifdef _MSC_VER
-#pragma message("You need to implement stubless proxies for your architecture")
-#else
-# warning You need to implement stubless proxies for your architecture
-#endif
-typedef struct _TMAsmProxy {
-    char a;
-} TMAsmProxy;
-#endif
-
-typedef struct _TMProxyImpl {
-    LPVOID                             *lpvtbl;
-    IRpcProxyBuffer                     IRpcProxyBuffer_iface;
-    LONG                               ref;
-
-    TMAsmProxy                         *asmstubs;
-    ITypeInfo*                         tinfo;
-    IRpcChannelBuffer*                 chanbuf;
-    IID                                        iid;
-    CRITICAL_SECTION   crit;
-    IUnknown                           *outerunknown;
-    IDispatch                          *dispatch;
-    IRpcProxyBuffer                    *dispatch_proxy;
-} TMProxyImpl;
-
-static inline TMProxyImpl *impl_from_IRpcProxyBuffer( IRpcProxyBuffer *iface )
-{
-    return CONTAINING_RECORD(iface, TMProxyImpl, IRpcProxyBuffer_iface);
-}
-
-static HRESULT WINAPI
-TMProxyImpl_QueryInterface(LPRPCPROXYBUFFER iface, REFIID riid, LPVOID *ppv)
-{
-    TRACE("()\n");
-    if (IsEqualIID(riid,&IID_IUnknown)||IsEqualIID(riid,&IID_IRpcProxyBuffer)) {
-        *ppv = iface;
-        IRpcProxyBuffer_AddRef(iface);
-        return S_OK;
-    }
-    FIXME("no interface for %s\n",debugstr_guid(riid));
-    return E_NOINTERFACE;
-}
-
-static ULONG WINAPI
-TMProxyImpl_AddRef(LPRPCPROXYBUFFER iface)
-{
-    TMProxyImpl *This = impl_from_IRpcProxyBuffer( iface );
-    ULONG refCount = InterlockedIncrement(&This->ref);
-
-    TRACE("(%p)->(ref before=%u)\n",This, refCount - 1);
-
-    return refCount;
-}
-
-static ULONG WINAPI
-TMProxyImpl_Release(LPRPCPROXYBUFFER iface)
-{
-    TMProxyImpl *This = impl_from_IRpcProxyBuffer( iface );
-    ULONG refCount = InterlockedDecrement(&This->ref);
-
-    TRACE("(%p)->(ref before=%u)\n",This, refCount + 1);
-
-    if (!refCount)
-    {
-        if (This->dispatch_proxy) IRpcProxyBuffer_Release(This->dispatch_proxy);
-        This->crit.DebugInfo->Spare[0] = 0;
-        DeleteCriticalSection(&This->crit);
-        if (This->chanbuf) IRpcChannelBuffer_Release(This->chanbuf);
-        VirtualFree(This->asmstubs, 0, MEM_RELEASE);
-        HeapFree(GetProcessHeap(), 0, This->lpvtbl);
-        ITypeInfo_Release(This->tinfo);
-        CoTaskMemFree(This);
-    }
-    return refCount;
-}
-
-static HRESULT WINAPI
-TMProxyImpl_Connect(
-    LPRPCPROXYBUFFER iface,IRpcChannelBuffer* pRpcChannelBuffer)
-{
-    TMProxyImpl *This = impl_from_IRpcProxyBuffer( iface );
-
-    TRACE("(%p)\n", pRpcChannelBuffer);
-
-    EnterCriticalSection(&This->crit);
-
-    IRpcChannelBuffer_AddRef(pRpcChannelBuffer);
-    This->chanbuf = pRpcChannelBuffer;
-
-    LeaveCriticalSection(&This->crit);
-
-    if (This->dispatch_proxy)
-    {
-        IRpcChannelBuffer *pDelegateChannel;
-        HRESULT hr = TMarshalDispatchChannel_Create(pRpcChannelBuffer, &This->iid, &pDelegateChannel);
-        if (FAILED(hr))
-            return hr;
-        hr = IRpcProxyBuffer_Connect(This->dispatch_proxy, pDelegateChannel);
-        IRpcChannelBuffer_Release(pDelegateChannel);
-        return hr;
-    }
-
-    return S_OK;
-}
-
-static void WINAPI
-TMProxyImpl_Disconnect(LPRPCPROXYBUFFER iface)
-{
-    TMProxyImpl *This = impl_from_IRpcProxyBuffer( iface );
-
-    TRACE("()\n");
-
-    EnterCriticalSection(&This->crit);
-
-    IRpcChannelBuffer_Release(This->chanbuf);
-    This->chanbuf = NULL;
-
-    LeaveCriticalSection(&This->crit);
-
-    if (This->dispatch_proxy)
-        IRpcProxyBuffer_Disconnect(This->dispatch_proxy);
-}
-
-
-static const IRpcProxyBufferVtbl tmproxyvtable = {
-    TMProxyImpl_QueryInterface,
-    TMProxyImpl_AddRef,
-    TMProxyImpl_Release,
-    TMProxyImpl_Connect,
-    TMProxyImpl_Disconnect
-};
-
-/* how much space do we use on stack in DWORD_PTR steps. */
-static int
-_argsize(TYPEDESC *tdesc, ITypeInfo *tinfo) {
-    DWORD ret;
-    switch (tdesc->vt) {
-    case VT_I8:
-    case VT_UI8:
-        ret = 8;
-        break;
-    case VT_R8:
-        ret = sizeof(double);
-        break;
-    case VT_CY:
-        ret = sizeof(CY);
-        break;
-    case VT_DATE:
-        ret = sizeof(DATE);
-        break;
-    case VT_DECIMAL:
-        ret = sizeof(DECIMAL);
-        break;
-    case VT_VARIANT:
-        ret = sizeof(VARIANT);
-        break;
-    case VT_USERDEFINED:
-    {
-        ITypeInfo *tinfo2;
-        TYPEATTR *tattr;
-        HRESULT hres;
-
-        hres = ITypeInfo_GetRefTypeInfo(tinfo,tdesc->u.hreftype,&tinfo2);
-        if (FAILED(hres))
-            return 0; /* should fail critically in serialize_param */
-        ITypeInfo_GetTypeAttr(tinfo2,&tattr);
-        ret = tattr->cbSizeInstance;
-        ITypeInfo_ReleaseTypeAttr(tinfo2, tattr);
-        ITypeInfo_Release(tinfo2);
-        break;
-    }
-    default:
-        ret = sizeof(DWORD_PTR);
-        break;
-    }
-
-    return (ret + sizeof(DWORD_PTR) - 1) / sizeof(DWORD_PTR);
-}
-
-/* how much space do we use on the heap (in bytes) */
-static int
-_xsize(const TYPEDESC *td, ITypeInfo *tinfo) {
-    switch (td->vt) {
-    case VT_DATE:
-       return sizeof(DATE);
-    case VT_CY:
-        return sizeof(CY);
-    case VT_VARIANT:
-       return sizeof(VARIANT);
-    case VT_CARRAY: {
-       int i, arrsize = 1;
-       const ARRAYDESC *adesc = td->u.lpadesc;
-
-       for (i=0;i<adesc->cDims;i++)
-           arrsize *= adesc->rgbounds[i].cElements;
-       return arrsize*_xsize(&adesc->tdescElem, tinfo);
-    }
-    case VT_UI8:
-    case VT_I8:
-    case VT_R8:
-       return 8;
-    case VT_UI2:
-    case VT_I2:
-    case VT_BOOL:
-       return 2;
-    case VT_UI1:
-    case VT_I1:
-       return 1;
-    case VT_USERDEFINED:
-    {
-        ITypeInfo *tinfo2;
-        TYPEATTR *tattr;
-        HRESULT hres;
-        DWORD ret;
-
-        hres = ITypeInfo_GetRefTypeInfo(tinfo,td->u.hreftype,&tinfo2);
-        if (FAILED(hres))
-            return 0;
-        ITypeInfo_GetTypeAttr(tinfo2,&tattr);
-        ret = tattr->cbSizeInstance;
-        ITypeInfo_ReleaseTypeAttr(tinfo2, tattr);
-        ITypeInfo_Release(tinfo2);
-        return ret;
-    }
-    default:
-       return sizeof(DWORD_PTR);
-    }
-}
-
-/* Whether we pass this type by reference or by value */
-static BOOL
-_passbyref(const TYPEDESC *td, ITypeInfo *tinfo) {
-    return (td->vt == VT_USERDEFINED ||
-            td->vt == VT_VARIANT     ||
-            td->vt == VT_PTR);
-}
-
-static HRESULT
-serialize_param(
-    ITypeInfo          *tinfo,
-    BOOL               writeit,
-    BOOL               debugout,
-    BOOL               dealloc,
-    TYPEDESC           *tdesc,
-    DWORD_PTR          *arg,
-    marshal_state      *buf)
-{
-    HRESULT hres = S_OK;
-    VARTYPE vartype;
-
-    TRACE("(tdesc.vt %s)\n",debugstr_vt(tdesc->vt));
-
-    vartype = tdesc->vt;
-    if ((vartype & 0xf000) == VT_ARRAY)
-        vartype = VT_SAFEARRAY;
-
-    switch (vartype) {
-    case VT_DATE:
-    case VT_I8:
-    case VT_UI8:
-    case VT_R8:
-    case VT_CY:
-       hres = S_OK;
-       if (debugout) TRACE_(olerelay)("%s\n", wine_dbgstr_longlong(*(ULONGLONG *)arg));
-       if (writeit)
-           hres = xbuf_add(buf,(LPBYTE)arg,8);
-       return hres;
-    case VT_ERROR:
-    case VT_INT:
-    case VT_UINT:
-    case VT_I4:
-    case VT_R4:
-    case VT_UI4:
-       hres = S_OK;
-       if (debugout) TRACE_(olerelay)("%x\n", *(DWORD *)arg);
-       if (writeit)
-           hres = xbuf_add(buf,(LPBYTE)arg,sizeof(DWORD));
-       return hres;
-    case VT_I2:
-    case VT_UI2:
-    case VT_BOOL:
-       hres = S_OK;
-       if (debugout) TRACE_(olerelay)("%04x\n", *(WORD *)arg);
-       if (writeit)
-           hres = xbuf_add(buf,(LPBYTE)arg,sizeof(DWORD));
-       return hres;
-    case VT_I1:
-    case VT_UI1:
-       hres = S_OK;
-       if (debugout) TRACE_(olerelay)("%02x\n", *(BYTE *)arg);
-       if (writeit)
-           hres = xbuf_add(buf,(LPBYTE)arg,sizeof(DWORD));
-       return hres;
-    case VT_VARIANT: {
-        if (debugout) TRACE_(olerelay)("%s", debugstr_variant((VARIANT *)arg));
-        if (writeit)
-        {
-            ULONG flags = MAKELONG(MSHCTX_DIFFERENTMACHINE, NDR_LOCAL_DATA_REPRESENTATION);
-            ULONG size = VARIANT_UserSize(&flags, buf->curoff, (VARIANT *)arg);
-            xbuf_resize(buf, size);
-            VARIANT_UserMarshal(&flags, buf->base + buf->curoff, (VARIANT *)arg);
-            buf->curoff = size;
-        }
-        if (dealloc)
-        {
-            ULONG flags = MAKELONG(MSHCTX_DIFFERENTMACHINE, NDR_LOCAL_DATA_REPRESENTATION);
-            VARIANT_UserFree(&flags, (VARIANT *)arg);
-        }
-        return S_OK;
-    }
-    case VT_BSTR: {
-       if (writeit && debugout) {
-           if (*arg)
-                   TRACE_(olerelay)("%s",relaystr((WCHAR*)*arg));
-           else
-                   TRACE_(olerelay)("<bstr NULL>");
-       }
-        if (writeit)
-        {
-            ULONG flags = MAKELONG(MSHCTX_DIFFERENTMACHINE, NDR_LOCAL_DATA_REPRESENTATION);
-            ULONG size = BSTR_UserSize(&flags, buf->curoff, (BSTR *)arg);
-            xbuf_resize(buf, size);
-            BSTR_UserMarshal(&flags, buf->base + buf->curoff, (BSTR *)arg);
-            buf->curoff = size;
-        }
-        if (dealloc)
-        {
-            ULONG flags = MAKELONG(MSHCTX_DIFFERENTMACHINE, NDR_LOCAL_DATA_REPRESENTATION);
-            BSTR_UserFree(&flags, (BSTR *)arg);
-        }
-        return S_OK;
-    }
-    case VT_PTR: {
-       DWORD cookie;
-       BOOL        derefhere = TRUE;
-
-       if (tdesc->u.lptdesc->vt == VT_USERDEFINED) {
-           ITypeInfo   *tinfo2;
-           TYPEATTR    *tattr;
-
-           hres = ITypeInfo_GetRefTypeInfo(tinfo,tdesc->u.lptdesc->u.hreftype,&tinfo2);
-           if (hres) {
-               ERR("Could not get typeinfo of hreftype %x for VT_USERDEFINED.\n",tdesc->u.lptdesc->u.hreftype);
-               return hres;
-           }
-           ITypeInfo_GetTypeAttr(tinfo2,&tattr);
-           switch (tattr->typekind) {
-            case TKIND_ALIAS:
-                if (tattr->tdescAlias.vt == VT_USERDEFINED)
-                {
-                    DWORD href = tattr->tdescAlias.u.hreftype;
-                    ITypeInfo_ReleaseTypeAttr(tinfo, tattr);
-                    ITypeInfo_Release(tinfo2);
-                    hres = ITypeInfo_GetRefTypeInfo(tinfo,href,&tinfo2);
-                    if (hres) {
-                        ERR("Could not get typeinfo of hreftype %x for VT_USERDEFINED.\n",tdesc->u.lptdesc->u.hreftype);
-                        return hres;
-                    }
-                    ITypeInfo_GetTypeAttr(tinfo2,&tattr);
-                    derefhere = (tattr->typekind != TKIND_DISPATCH &&
-                                 tattr->typekind != TKIND_INTERFACE &&
-                                 tattr->typekind != TKIND_COCLASS);
-                }
-                break;
-           case TKIND_ENUM:    /* confirmed */
-           case TKIND_RECORD:  /* FIXME: mostly untested */
-               break;
-           case TKIND_DISPATCH:        /* will be done in VT_USERDEFINED case */
-           case TKIND_INTERFACE:       /* will be done in VT_USERDEFINED case */
-            case TKIND_COCLASS:         /* will be done in VT_USERDEFINED case */
-               derefhere=FALSE;
-               break;
-           default:
-               FIXME("unhandled switch cases tattr->typekind %d\n", tattr->typekind);
-               derefhere=FALSE;
-               break;
-           }
-           ITypeInfo_ReleaseTypeAttr(tinfo, tattr);
-           ITypeInfo_Release(tinfo2);
-       }
-
-       if (debugout) TRACE_(olerelay)("*");
-       /* Write always, so the other side knows when it gets a NULL pointer.
-        */
-       cookie = *arg ? 0x42424242 : 0;
-       hres = xbuf_add(buf,(LPBYTE)&cookie,sizeof(cookie));
-       if (hres)
-           return hres;
-       if (!*arg) {
-           if (debugout) TRACE_(olerelay)("NULL");
-           return S_OK;
-       }
-       hres = serialize_param(tinfo,writeit,debugout,dealloc,tdesc->u.lptdesc,(DWORD_PTR *)*arg,buf);
-       if (derefhere && dealloc) HeapFree(GetProcessHeap(),0,(LPVOID)*arg);
-       return hres;
-    }
-    case VT_UNKNOWN:
-       if (debugout) TRACE_(olerelay)("unk(0x%lx)", *arg);
-       if (writeit)
-           hres = _marshal_interface(buf,&IID_IUnknown,(LPUNKNOWN)*arg);
-       if (dealloc && *(IUnknown **)arg)
-           IUnknown_Release((LPUNKNOWN)*arg);
-       return hres;
-    case VT_DISPATCH:
-       if (debugout) TRACE_(olerelay)("idisp(0x%lx)", *arg);
-       if (writeit)
-           hres = _marshal_interface(buf,&IID_IDispatch,(LPUNKNOWN)*arg);
-       if (dealloc && *(IUnknown **)arg)
-           IUnknown_Release((LPUNKNOWN)*arg);
-       return hres;
-    case VT_VOID:
-       if (debugout) TRACE_(olerelay)("<void>");
-       return S_OK;
-    case VT_USERDEFINED: {
-       ITypeInfo       *tinfo2;
-       TYPEATTR        *tattr;
-
-       hres = ITypeInfo_GetRefTypeInfo(tinfo,tdesc->u.hreftype,&tinfo2);
-       if (hres) {
-           ERR("Could not get typeinfo of hreftype %x for VT_USERDEFINED.\n",tdesc->u.hreftype);
-           return hres;
-       }
-       ITypeInfo_GetTypeAttr(tinfo2,&tattr);
-       switch (tattr->typekind) {
-       case TKIND_DISPATCH:
-       case TKIND_INTERFACE:
-           if (writeit)
-              hres=_marshal_interface(buf,&(tattr->guid),(LPUNKNOWN)arg);
-           if (dealloc)
-               IUnknown_Release((LPUNKNOWN)arg);
-           break;
-        case TKIND_COCLASS: {
-            GUID iid = tattr->guid;
-            unsigned int i;
-            int type_flags;
-
-            for(i = 0; i < tattr->cImplTypes; i++) {
-                if(SUCCEEDED(ITypeInfo_GetImplTypeFlags(tinfo2, i, &type_flags)) &&
-                   type_flags == (IMPLTYPEFLAG_FSOURCE|IMPLTYPEFLAG_FDEFAULT)) {
-                    ITypeInfo *tinfo3;
-                    TYPEATTR *tattr2;
-                    HREFTYPE href;
-                    if(FAILED(ITypeInfo_GetRefTypeOfImplType(tinfo2, i, &href)))
-                        break;
-                    if(FAILED(ITypeInfo_GetRefTypeInfo(tinfo2, href, &tinfo3)))
-                        break;
-                    if(SUCCEEDED(ITypeInfo_GetTypeAttr(tinfo3, &tattr2))) {
-                        iid = tattr2->guid;
-                        ITypeInfo_ReleaseTypeAttr(tinfo3, tattr2);
-                    }
-                    ITypeInfo_Release(tinfo3);
-                    break;
-                }
-            }
-
-            if(writeit)
-                hres=_marshal_interface(buf, &iid, (LPUNKNOWN)arg);
-            if(dealloc)
-                IUnknown_Release((LPUNKNOWN)arg);
-            break;
-        }
-       case TKIND_RECORD: {
-           int i;
-           if (debugout) TRACE_(olerelay)("{");
-           for (i=0;i<tattr->cVars;i++) {
-               VARDESC *vdesc;
-               ELEMDESC *elem2;
-               TYPEDESC *tdesc2;
-
-               hres = ITypeInfo_GetVarDesc(tinfo2, i, &vdesc);
-               if (hres) {
-                   ERR("Could not get vardesc of %d\n",i);
-                   return hres;
-               }
-               elem2 = &vdesc->elemdescVar;
-               tdesc2 = &elem2->tdesc;
-               hres = serialize_param(
-                   tinfo2,
-                   writeit,
-                   debugout,
-                   dealloc,
-                   tdesc2,
-                   (DWORD_PTR *)(((LPBYTE)arg)+vdesc->u.oInst),
-                   buf
-               );
-                ITypeInfo_ReleaseVarDesc(tinfo2, vdesc);
-               if (hres!=S_OK)
-                   return hres;
-               if (debugout && (i<(tattr->cVars-1)))
-                   TRACE_(olerelay)(",");
-           }
-           if (debugout) TRACE_(olerelay)("}");
-           break;
-       }
-       case TKIND_ALIAS:
-           hres = serialize_param(tinfo2,writeit,debugout,dealloc,&tattr->tdescAlias,arg,buf);
-           break;
-       case TKIND_ENUM:
-           hres = S_OK;
-           if (debugout) TRACE_(olerelay)("%x", *(DWORD *)arg);
-           if (writeit)
-               hres = xbuf_add(buf,(LPBYTE)arg,sizeof(DWORD));
-           break;
-       default:
-           FIXME("Unhandled typekind %d\n",tattr->typekind);
-           hres = E_FAIL;
-           break;
-       }
-       ITypeInfo_ReleaseTypeAttr(tinfo2, tattr);
-       ITypeInfo_Release(tinfo2);
-       return hres;
-    }
-    case VT_CARRAY: {
-       ARRAYDESC *adesc = tdesc->u.lpadesc;
-       int i, arrsize = 1;
-
-       if (debugout) TRACE_(olerelay)("carr");
-       for (i=0;i<adesc->cDims;i++) {
-           if (debugout) TRACE_(olerelay)("[%d]",adesc->rgbounds[i].cElements);
-           arrsize *= adesc->rgbounds[i].cElements;
-       }
-       if (debugout) TRACE_(olerelay)("(vt %s)",debugstr_vt(adesc->tdescElem.vt));
-       if (debugout) TRACE_(olerelay)("[");
-       for (i=0;i<arrsize;i++) {
-            LPBYTE base = _passbyref(&adesc->tdescElem, tinfo) ? (LPBYTE) *arg : (LPBYTE) arg;
-           hres = serialize_param(tinfo, writeit, debugout, dealloc, &adesc->tdescElem, (DWORD_PTR *)((LPBYTE)base+i*_xsize(&adesc->tdescElem, tinfo)), buf);
-           if (hres)
-               return hres;
-           if (debugout && (i<arrsize-1)) TRACE_(olerelay)(",");
-       }
-       if (debugout) TRACE_(olerelay)("]");
-       if (dealloc)
-           HeapFree(GetProcessHeap(), 0, *(void **)arg);
-       return S_OK;
-    }
-    case VT_SAFEARRAY: {
-        if (writeit)
-        {
-            ULONG flags = MAKELONG(MSHCTX_DIFFERENTMACHINE, NDR_LOCAL_DATA_REPRESENTATION);
-            ULONG size = LPSAFEARRAY_UserSize(&flags, buf->curoff, (LPSAFEARRAY *)arg);
-            xbuf_resize(buf, size);
-            LPSAFEARRAY_UserMarshal(&flags, buf->base + buf->curoff, (LPSAFEARRAY *)arg);
-            buf->curoff = size;
-        }
-        if (dealloc)
-        {
-            ULONG flags = MAKELONG(MSHCTX_DIFFERENTMACHINE, NDR_LOCAL_DATA_REPRESENTATION);
-            LPSAFEARRAY_UserFree(&flags, (LPSAFEARRAY *)arg);
-        }
-        return S_OK;
-    }
-    default:
-       ERR("Unhandled marshal type %d.\n",tdesc->vt);
-       return S_OK;
-    }
-}
-
-static HRESULT
-deserialize_param(
-    ITypeInfo          *tinfo,
-    BOOL               readit,
-    BOOL               debugout,
-    BOOL               alloc,
-    TYPEDESC           *tdesc,
-    DWORD_PTR          *arg,
-    marshal_state      *buf)
-{
-    HRESULT hres = S_OK;
-    VARTYPE vartype;
-
-    TRACE("vt %s at %p\n",debugstr_vt(tdesc->vt),arg);
-
-    vartype = tdesc->vt;
-    if ((vartype & 0xf000) == VT_ARRAY)
-        vartype = VT_SAFEARRAY;
-
-    while (1) {
-       switch (vartype) {
-       case VT_VARIANT: {
-           if (readit)
-           {
-               ULONG flags = MAKELONG(MSHCTX_DIFFERENTMACHINE, NDR_LOCAL_DATA_REPRESENTATION);
-               unsigned char *buffer;
-               buffer = VARIANT_UserUnmarshal(&flags, buf->base + buf->curoff, (VARIANT *)arg);
-               buf->curoff = buffer - buf->base;
-           }
-           return S_OK;
-       }
-        case VT_DATE:
-        case VT_I8:
-        case VT_UI8:
-        case VT_R8:
-        case VT_CY:
-           if (readit) {
-               hres = xbuf_get(buf,(LPBYTE)arg,8);
-               if (hres) ERR("Failed to read integer 8 byte\n");
-           }
-           if (debugout) TRACE_(olerelay)("%s", wine_dbgstr_longlong(*(ULONGLONG *)arg));
-           return hres;
-        case VT_ERROR:
-        case VT_I4:
-        case VT_INT:
-        case VT_UINT:
-        case VT_R4:
-        case VT_UI4:
-           if (readit) {
-               hres = xbuf_get(buf,(LPBYTE)arg,sizeof(DWORD));
-               if (hres) ERR("Failed to read integer 4 byte\n");
-           }
-           if (debugout) TRACE_(olerelay)("%x", *(DWORD *)arg);
-           return hres;
-        case VT_I2:
-        case VT_UI2:
-        case VT_BOOL:
-           if (readit) {
-               DWORD x;
-               hres = xbuf_get(buf,(LPBYTE)&x,sizeof(DWORD));
-               if (hres) ERR("Failed to read integer 4 byte\n");
-               else memcpy(arg,&x,2);
-           }
-           if (debugout) TRACE_(olerelay)("%04x", *(WORD *)arg);
-           return hres;
-        case VT_I1:
-       case VT_UI1:
-           if (readit) {
-               DWORD x;
-               hres = xbuf_get(buf,(LPBYTE)&x,sizeof(DWORD));
-               if (hres) ERR("Failed to read integer 4 byte\n");
-               else memcpy(arg,&x,1);
-           }
-           if (debugout) TRACE_(olerelay)("%02x", *(BYTE *)arg);
-           return hres;
-       case VT_BSTR: {
-           if (readit)
-           {
-               ULONG flags = MAKELONG(MSHCTX_DIFFERENTMACHINE, NDR_LOCAL_DATA_REPRESENTATION);
-               unsigned char *buffer;
-               buffer = BSTR_UserUnmarshal(&flags, buf->base + buf->curoff, (BSTR *)arg);
-               buf->curoff = buffer - buf->base;
-               if (debugout) TRACE_(olerelay)("%s",debugstr_w(*(BSTR *)arg));
-           }
-           return S_OK;
-       }
-       case VT_PTR: {
-           DWORD       cookie;
-           BOOL        derefhere = TRUE;
-
-           if (tdesc->u.lptdesc->vt == VT_USERDEFINED) {
-               ITypeInfo       *tinfo2;
-               TYPEATTR        *tattr;
-
-               hres = ITypeInfo_GetRefTypeInfo(tinfo,tdesc->u.lptdesc->u.hreftype,&tinfo2);
-               if (hres) {
-                   ERR("Could not get typeinfo of hreftype %x for VT_USERDEFINED.\n",tdesc->u.lptdesc->u.hreftype);
-                   return hres;
-               }
-               ITypeInfo_GetTypeAttr(tinfo2,&tattr);
-               switch (tattr->typekind) {
-                case TKIND_ALIAS:
-                    if (tattr->tdescAlias.vt == VT_USERDEFINED)
-                    {
-                        DWORD href = tattr->tdescAlias.u.hreftype;
-                        ITypeInfo_ReleaseTypeAttr(tinfo, tattr);
-                        ITypeInfo_Release(tinfo2);
-                        hres = ITypeInfo_GetRefTypeInfo(tinfo,href,&tinfo2);
-                        if (hres) {
-                            ERR("Could not get typeinfo of hreftype %x for VT_USERDEFINED.\n",tdesc->u.lptdesc->u.hreftype);
-                            return hres;
-                        }
-                        ITypeInfo_GetTypeAttr(tinfo2,&tattr);
-                        derefhere = (tattr->typekind != TKIND_DISPATCH &&
-                                     tattr->typekind != TKIND_INTERFACE &&
-                                     tattr->typekind != TKIND_COCLASS);
-                    }
-                    break;
-               case TKIND_ENUM:        /* confirmed */
-               case TKIND_RECORD:      /* FIXME: mostly untested */
-                   break;
-               case TKIND_DISPATCH:    /* will be done in VT_USERDEFINED case */
-               case TKIND_INTERFACE:   /* will be done in VT_USERDEFINED case */
-                case TKIND_COCLASS:     /* will be done in VT_USERDEFINED case */
-                   derefhere=FALSE;
-                   break;
-               default:
-                   FIXME("unhandled switch cases tattr->typekind %d\n", tattr->typekind);
-                   derefhere=FALSE;
-                   break;
-               }
-               ITypeInfo_ReleaseTypeAttr(tinfo2, tattr);
-               ITypeInfo_Release(tinfo2);
-           }
-           /* read it in all cases, we need to know if we have 
-            * NULL pointer or not.
-            */
-           hres = xbuf_get(buf,(LPBYTE)&cookie,sizeof(cookie));
-           if (hres) {
-               ERR("Failed to load pointer cookie.\n");
-               return hres;
-           }
-           if (cookie != 0x42424242) {
-               /* we read a NULL ptr from the remote side */
-               if (debugout) TRACE_(olerelay)("NULL");
-               *arg = 0;
-               return S_OK;
-           }
-           if (debugout) TRACE_(olerelay)("*");
-           if (alloc) {
-               /* Allocate space for the referenced struct */
-               if (derefhere)
-                   *arg=(DWORD_PTR)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,_xsize(tdesc->u.lptdesc, tinfo));
-           }
-           if (derefhere)
-               return deserialize_param(tinfo, readit, debugout, alloc, tdesc->u.lptdesc, (DWORD_PTR *)*arg, buf);
-           else
-               return deserialize_param(tinfo, readit, debugout, alloc, tdesc->u.lptdesc, arg, buf);
-        }
-       case VT_UNKNOWN:
-           /* FIXME: UNKNOWN is unknown ..., but allocate 4 byte for it */
-           if (alloc)
-               *arg=(DWORD_PTR)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(DWORD_PTR));
-           hres = S_OK;
-           if (readit)
-               hres = _unmarshal_interface(buf,&IID_IUnknown,(LPUNKNOWN*)arg);
-           if (debugout)
-               TRACE_(olerelay)("unk(%p)",arg);
-           return hres;
-       case VT_DISPATCH:
-           hres = S_OK;
-           if (readit)
-               hres = _unmarshal_interface(buf,&IID_IDispatch,(LPUNKNOWN*)arg);
-           if (debugout)
-               TRACE_(olerelay)("idisp(%p)",arg);
-           return hres;
-       case VT_VOID:
-           if (debugout) TRACE_(olerelay)("<void>");
-           return S_OK;
-       case VT_USERDEFINED: {
-           ITypeInfo   *tinfo2;
-           TYPEATTR    *tattr;
-
-           hres = ITypeInfo_GetRefTypeInfo(tinfo,tdesc->u.hreftype,&tinfo2);
-           if (hres) {
-               ERR("Could not get typeinfo of hreftype %x for VT_USERDEFINED.\n",tdesc->u.hreftype);
-               return hres;
-           }
-           hres = ITypeInfo_GetTypeAttr(tinfo2,&tattr);
-           if (hres) {
-               ERR("Could not get typeattr in VT_USERDEFINED.\n");
-           } else {
-               switch (tattr->typekind) {
-               case TKIND_DISPATCH:
-               case TKIND_INTERFACE:
-                   if (readit)
-                       hres = _unmarshal_interface(buf,&(tattr->guid),(LPUNKNOWN*)arg);
-                   break;
-                case TKIND_COCLASS: {
-                    GUID iid = tattr->guid;
-                    unsigned int i;
-                    int type_flags;
-
-                    for(i = 0; i < tattr->cImplTypes; i++) {
-                        if(SUCCEEDED(ITypeInfo_GetImplTypeFlags(tinfo2, i, &type_flags)) &&
-                           type_flags == (IMPLTYPEFLAG_FSOURCE|IMPLTYPEFLAG_FDEFAULT)) {
-                            ITypeInfo *tinfo3;
-                            TYPEATTR *tattr2;
-                            HREFTYPE href;
-                            if(FAILED(ITypeInfo_GetRefTypeOfImplType(tinfo2, i, &href)))
-                                break;
-                            if(FAILED(ITypeInfo_GetRefTypeInfo(tinfo2, href, &tinfo3)))
-                                break;
-                            if(SUCCEEDED(ITypeInfo_GetTypeAttr(tinfo3, &tattr2))) {
-                                iid = tattr2->guid;
-                                ITypeInfo_ReleaseTypeAttr(tinfo3, tattr2);
-                            }
-                            ITypeInfo_Release(tinfo3);
-                            break;
-                        }
-                    }
-
-                    if(readit)
-                        hres = _unmarshal_interface(buf, &iid, (LPUNKNOWN*)arg);
-                    break;
-                }
-               case TKIND_RECORD: {
-                   int i;
-
-                   if (debugout) TRACE_(olerelay)("{");
-                   for (i=0;i<tattr->cVars;i++) {
-                       VARDESC *vdesc;
-
-                       hres = ITypeInfo_GetVarDesc(tinfo2, i, &vdesc);
-                       if (hres) {
-                           ERR("Could not get vardesc of %d\n",i);
-                           ITypeInfo_ReleaseTypeAttr(tinfo2, tattr);
-                           ITypeInfo_Release(tinfo2);
-                           return hres;
-                       }
-                       hres = deserialize_param(
-                           tinfo2,
-                           readit,
-                           debugout,
-                           alloc,
-                           &vdesc->elemdescVar.tdesc,
-                           (DWORD_PTR *)(((LPBYTE)arg)+vdesc->u.oInst),
-                           buf
-                       );
-                        ITypeInfo_ReleaseVarDesc(tinfo2, vdesc);
-                       if (debugout && (i<tattr->cVars-1)) TRACE_(olerelay)(",");
-                   }
-                   if (debugout) TRACE_(olerelay)("}");
-                   break;
-               }
-               case TKIND_ALIAS:
-                   hres = deserialize_param(tinfo2,readit,debugout,alloc,&tattr->tdescAlias,arg,buf);
-                   break;
-               case TKIND_ENUM:
-                   if (readit) {
-                       hres = xbuf_get(buf,(LPBYTE)arg,sizeof(DWORD));
-                       if (hres) ERR("Failed to read enum (4 byte)\n");
-                   }
-                   if (debugout) TRACE_(olerelay)("%x", *(DWORD *)arg);
-                   break;
-               default:
-                   ERR("Unhandled typekind %d\n",tattr->typekind);
-                   hres = E_FAIL;
-                   break;
-               }
-               ITypeInfo_ReleaseTypeAttr(tinfo2, tattr);
-           }
-           if (hres)
-               ERR("failed to stuballoc in TKIND_RECORD.\n");
-           ITypeInfo_Release(tinfo2);
-           return hres;
-       }
-       case VT_CARRAY: {
-           /* arg is pointing to the start of the array. */
-            LPBYTE base = (LPBYTE) arg;
-           ARRAYDESC *adesc = tdesc->u.lpadesc;
-           int         arrsize,i;
-           arrsize = 1;
-           if (adesc->cDims > 1) FIXME("cDims > 1 in VT_CARRAY. Does it work?\n");
-           for (i=0;i<adesc->cDims;i++)
-               arrsize *= adesc->rgbounds[i].cElements;
-            if (_passbyref(&adesc->tdescElem, tinfo))
-            {
-               base = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,_xsize(tdesc->u.lptdesc, tinfo) * arrsize);
-                *arg = (DWORD_PTR)base;
-            }
-           for (i=0;i<arrsize;i++)
-               deserialize_param(
-                   tinfo,
-                   readit,
-                   debugout,
-                   alloc,
-                   &adesc->tdescElem,
-                   (DWORD_PTR *)(base + i*_xsize(&adesc->tdescElem, tinfo)),
-                   buf
-               );
-           return S_OK;
-       }
-        case VT_SAFEARRAY: {
-           if (readit)
-           {
-               ULONG flags = MAKELONG(MSHCTX_DIFFERENTMACHINE, NDR_LOCAL_DATA_REPRESENTATION);
-               unsigned char *buffer;
-               buffer = LPSAFEARRAY_UserUnmarshal(&flags, buf->base + buf->curoff, (LPSAFEARRAY *)arg);
-               buf->curoff = buffer - buf->base;
-           }
-           return S_OK;
-       }
-       default:
-           ERR("No handler for VT type %d!\n",tdesc->vt);
-           return S_OK;
-       }
-    }
-}
-
-/* Retrieves a function's funcdesc, searching back into inherited interfaces. */
-static HRESULT get_funcdesc(ITypeInfo *tinfo, int iMethod, ITypeInfo **tactual, const FUNCDESC **fdesc,
-                            BSTR *iname, BSTR *fname, UINT *num)
-{
-    HRESULT hr;
-    UINT i, impl_types;
-    UINT inherited_funcs = 0;
-    TYPEATTR *attr;
-
-    if (fname) *fname = NULL;
-    if (iname) *iname = NULL;
-    if (num) *num = 0;
-    *tactual = NULL;
-
-    hr = ITypeInfo_GetTypeAttr(tinfo, &attr);
-    if (FAILED(hr))
-    {
-        ERR("GetTypeAttr failed with %x\n",hr);
-        return hr;
-    }
-
-    if(attr->typekind == TKIND_DISPATCH)
-    {
-        if(attr->wTypeFlags & TYPEFLAG_FDUAL)
-        {
-            HREFTYPE href;
-            ITypeInfo *tinfo2;
-
-            hr = ITypeInfo_GetRefTypeOfImplType(tinfo, -1, &href);
-            if(FAILED(hr))
-            {
-                ERR("Cannot get interface href from dual dispinterface\n");
-                ITypeInfo_ReleaseTypeAttr(tinfo, attr);
-                return hr;
-            }
-            hr = ITypeInfo_GetRefTypeInfo(tinfo, href, &tinfo2);
-            if(FAILED(hr))
-            {
-                ERR("Cannot get interface from dual dispinterface\n");
-                ITypeInfo_ReleaseTypeAttr(tinfo, attr);
-                return hr;
-            }
-            hr = get_funcdesc(tinfo2, iMethod, tactual, fdesc, iname, fname, num);
-            ITypeInfo_Release(tinfo2);
-            ITypeInfo_ReleaseTypeAttr(tinfo, attr);
-            return hr;
-        }
-        ERR("Shouldn't be called with a non-dual dispinterface\n");
-        return E_FAIL;
-    }
-
-    impl_types = attr->cImplTypes;
-    ITypeInfo_ReleaseTypeAttr(tinfo, attr);
-
-    for (i = 0; i < impl_types; i++)
-    {
-        HREFTYPE href;
-        ITypeInfo *pSubTypeInfo;
-        UINT sub_funcs;
-
-        hr = ITypeInfo_GetRefTypeOfImplType(tinfo, i, &href);
-        if (FAILED(hr)) return hr;
-        hr = ITypeInfo_GetRefTypeInfo(tinfo, href, &pSubTypeInfo);
-        if (FAILED(hr)) return hr;
-
-        hr = get_funcdesc(pSubTypeInfo, iMethod, tactual, fdesc, iname, fname, &sub_funcs);
-        inherited_funcs += sub_funcs;
-        ITypeInfo_Release(pSubTypeInfo);
-        if(SUCCEEDED(hr)) return hr;
-    }
-    if(iMethod < inherited_funcs)
-    {
-        ERR("shouldn't be here\n");
-        return E_INVALIDARG;
-    }
-
-    for(i = inherited_funcs; i <= iMethod; i++)
-    {
-        hr = ITypeInfoImpl_GetInternalFuncDesc(tinfo, i - inherited_funcs, fdesc);
-        if(FAILED(hr))
-        {
-            if(num) *num = i;
-            return hr;
-        }
-    }
-
-    /* found it. We don't care about num so zero it */
-    if(num) *num = 0;
-    *tactual = tinfo;
-    ITypeInfo_AddRef(*tactual);
-    if (fname) ITypeInfo_GetDocumentation(tinfo,(*fdesc)->memid,fname,NULL,NULL,NULL);
-    if (iname) ITypeInfo_GetDocumentation(tinfo,-1,iname,NULL,NULL,NULL);
-    return S_OK;
-}
-
-static inline BOOL is_in_elem(const ELEMDESC *elem)
-{
-    return (elem->u.paramdesc.wParamFlags & PARAMFLAG_FIN || !elem->u.paramdesc.wParamFlags);
-}
-
-static inline BOOL is_out_elem(const ELEMDESC *elem)
-{
-    return (elem->u.paramdesc.wParamFlags & PARAMFLAG_FOUT || !elem->u.paramdesc.wParamFlags);
-}
-
-static DWORD WINAPI xCall(int method, void **args)
-{
-    TMProxyImpl *tpinfo = args[0];
-    DWORD_PTR *xargs;
-    const FUNCDESC     *fdesc;
-    HRESULT            hres;
-    int                        i;
-    marshal_state      buf;
-    RPCOLEMESSAGE      msg;
-    ULONG              status;
-    BSTR               fname,iname;
-    BSTR               names[10];
-    UINT               nrofnames;
-    DWORD              remoteresult = 0;
-    ITypeInfo          *tinfo;
-    IRpcChannelBuffer *chanbuf;
-
-    EnterCriticalSection(&tpinfo->crit);
-
-    hres = get_funcdesc(tpinfo->tinfo,method,&tinfo,&fdesc,&iname,&fname,NULL);
-    if (hres) {
-        ERR("Did not find typeinfo/funcdesc entry for method %d!\n",method);
-        LeaveCriticalSection(&tpinfo->crit);
-        return E_FAIL;
-    }
-
-    if (!tpinfo->chanbuf)
-    {
-        WARN("Tried to use disconnected proxy\n");
-        ITypeInfo_Release(tinfo);
-        LeaveCriticalSection(&tpinfo->crit);
-        return RPC_E_DISCONNECTED;
-    }
-    chanbuf = tpinfo->chanbuf;
-    IRpcChannelBuffer_AddRef(chanbuf);
-
-    LeaveCriticalSection(&tpinfo->crit);
-
-    if (TRACE_ON(olerelay)) {
-       TRACE_(olerelay)("->");
-       if (iname)
-           TRACE_(olerelay)("%s:",relaystr(iname));
-       if (fname)
-           TRACE_(olerelay)("%s(%d)",relaystr(fname),method);
-       else
-           TRACE_(olerelay)("%d",method);
-       TRACE_(olerelay)("(");
-    }
-
-    SysFreeString(iname);
-    SysFreeString(fname);
-
-    memset(&buf,0,sizeof(buf));
-
-    /* normal typelib driven serializing */
-
-    /* Need them for hack below */
-    memset(names,0,sizeof(names));
-    if (ITypeInfo_GetNames(tinfo,fdesc->memid,names,sizeof(names)/sizeof(names[0]),&nrofnames))
-       nrofnames = 0;
-    if (nrofnames > sizeof(names)/sizeof(names[0]))
-       ERR("Need more names!\n");
-
-    xargs = (DWORD_PTR *)(args + 1);
-    for (i=0;i<fdesc->cParams;i++) {
-       ELEMDESC        *elem = fdesc->lprgelemdescParam+i;
-       if (TRACE_ON(olerelay)) {
-           if (i) TRACE_(olerelay)(",");
-           if (i+1<nrofnames && names[i+1])
-               TRACE_(olerelay)("%s=",relaystr(names[i+1]));
-       }
-       /* No need to marshal other data than FIN and any VT_PTR. */
-        if (!is_in_elem(elem))
-        {
-            if (elem->tdesc.vt != VT_PTR)
-            {
-                xargs+=_argsize(&elem->tdesc, tinfo);
-                TRACE_(olerelay)("[out]");
-                continue;
-            }
-            else
-            {
-                memset( *(void **)xargs, 0, _xsize( elem->tdesc.u.lptdesc, tinfo ) );
-            }
-        }
-
-       hres = serialize_param(
-           tinfo,
-           is_in_elem(elem),
-           TRACE_ON(olerelay),
-           FALSE,
-           &elem->tdesc,
-           xargs,
-           &buf
-       );
-
-       if (hres) {
-           ERR("Failed to serialize param, hres %x\n",hres);
-           break;
-       }
-       xargs+=_argsize(&elem->tdesc, tinfo);
-    }
-    TRACE_(olerelay)(")");
-
-    memset(&msg,0,sizeof(msg));
-    msg.cbBuffer = buf.curoff;
-    msg.iMethod  = method;
-    hres = IRpcChannelBuffer_GetBuffer(chanbuf,&msg,&(tpinfo->iid));
-    if (hres) {
-       ERR("RpcChannelBuffer GetBuffer failed, %x\n",hres);
-       goto exit;
-    }
-    memcpy(msg.Buffer,buf.base,buf.curoff);
-    TRACE_(olerelay)("\n");
-    hres = IRpcChannelBuffer_SendReceive(chanbuf,&msg,&status);
-    if (hres) {
-       ERR("RpcChannelBuffer SendReceive failed, %x\n",hres);
-       goto exit;
-    }
-
-    TRACE_(olerelay)(" status = %08x (",status);
-    if (buf.base)
-       buf.base = HeapReAlloc(GetProcessHeap(),0,buf.base,msg.cbBuffer);
-    else
-       buf.base = HeapAlloc(GetProcessHeap(),0,msg.cbBuffer);
-    buf.size = msg.cbBuffer;
-    memcpy(buf.base,msg.Buffer,buf.size);
-    buf.curoff = 0;
-
-    /* generic deserializer using typelib description */
-    xargs = (DWORD_PTR *)(args + 1);
-    status = S_OK;
-    for (i=0;i<fdesc->cParams;i++) {
-       ELEMDESC        *elem = fdesc->lprgelemdescParam+i;
-
-        if (i) TRACE_(olerelay)(",");
-        if (i+1<nrofnames && names[i+1]) TRACE_(olerelay)("%s=",relaystr(names[i+1]));
-
-       /* No need to marshal other data than FOUT and any VT_PTR */
-       if (!is_out_elem(elem) && (elem->tdesc.vt != VT_PTR)) {
-           xargs += _argsize(&elem->tdesc, tinfo);
-           TRACE_(olerelay)("[in]");
-           continue;
-       }
-       hres = deserialize_param(
-           tinfo,
-           is_out_elem(elem),
-           TRACE_ON(olerelay),
-           FALSE,
-           &(elem->tdesc),
-           xargs,
-           &buf
-        );
-       if (hres) {
-           ERR("Failed to unmarshall param, hres %x\n",hres);
-           status = hres;
-           break;
-       }
-       xargs += _argsize(&elem->tdesc, tinfo);
-    }
-
-    hres = xbuf_get(&buf, (LPBYTE)&remoteresult, sizeof(DWORD));
-    if (hres != S_OK)
-        goto exit;
-    TRACE_(olerelay)(") = %08x\n", remoteresult);
-
-    hres = remoteresult;
-
-exit:
-    IRpcChannelBuffer_FreeBuffer(chanbuf,&msg);
-    for (i = 0; i < nrofnames; i++)
-        SysFreeString(names[i]);
-    HeapFree(GetProcessHeap(),0,buf.base);
-    IRpcChannelBuffer_Release(chanbuf);
-    ITypeInfo_Release(tinfo);
-    TRACE("-- 0x%08x\n", hres);
-    return hres;
-}
-
-static HRESULT WINAPI ProxyIUnknown_QueryInterface(IUnknown *iface, REFIID riid, void **ppv)
-{
-    TMProxyImpl *proxy = (TMProxyImpl *)iface;
-
-    TRACE("(%s, %p)\n", debugstr_guid(riid), ppv);
-
-    if (proxy->outerunknown)
-        return IUnknown_QueryInterface(proxy->outerunknown, riid, ppv);
-
-    FIXME("No interface\n");
-    return E_NOINTERFACE;
-}
-
-static ULONG WINAPI ProxyIUnknown_AddRef(IUnknown *iface)
-{
-    TMProxyImpl *proxy = (TMProxyImpl *)iface;
-
-    TRACE("\n");
-
-    if (proxy->outerunknown)
-        return IUnknown_AddRef(proxy->outerunknown);
-
-    return 2; /* FIXME */
-}
-
-static ULONG WINAPI ProxyIUnknown_Release(IUnknown *iface)
-{
-    TMProxyImpl *proxy = (TMProxyImpl *)iface;
-
-    TRACE("\n");
-
-    if (proxy->outerunknown)
-        return IUnknown_Release(proxy->outerunknown);
-
-    return 1; /* FIXME */
-}
-
-static HRESULT WINAPI ProxyIDispatch_GetTypeInfoCount(LPDISPATCH iface, UINT * pctinfo)
-{
-    TMProxyImpl *This = (TMProxyImpl *)iface;
-
-    TRACE("(%p)\n", pctinfo);
-
-    return IDispatch_GetTypeInfoCount(This->dispatch, pctinfo);
-}
-
-static HRESULT WINAPI ProxyIDispatch_GetTypeInfo(LPDISPATCH iface, UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo)
-{
-    TMProxyImpl *This = (TMProxyImpl *)iface;
-
-    TRACE("(%d, %x, %p)\n", iTInfo, lcid, ppTInfo);
-
-    return IDispatch_GetTypeInfo(This->dispatch, iTInfo, lcid, ppTInfo);
-}
-
-static HRESULT WINAPI ProxyIDispatch_GetIDsOfNames(LPDISPATCH iface, REFIID riid, LPOLESTR * rgszNames, UINT cNames, LCID lcid, DISPID * rgDispId)
-{
-    TMProxyImpl *This = (TMProxyImpl *)iface;
-
-    TRACE("(%s, %p, %d, 0x%x, %p)\n", debugstr_guid(riid), rgszNames, cNames, lcid, rgDispId);
-
-    return IDispatch_GetIDsOfNames(This->dispatch, riid, rgszNames,
-                                   cNames, lcid, rgDispId);
-}
-
-static HRESULT WINAPI ProxyIDispatch_Invoke(LPDISPATCH iface, DISPID dispIdMember, REFIID riid, LCID lcid,
-                                            WORD wFlags, DISPPARAMS * pDispParams, VARIANT * pVarResult,
-                                            EXCEPINFO * pExcepInfo, UINT * puArgErr)
-{
-    TMProxyImpl *This = (TMProxyImpl *)iface;
-
-    TRACE("(%d, %s, 0x%x, 0x%x, %p, %p, %p, %p)\n", dispIdMember,
-          debugstr_guid(riid), lcid, wFlags, pDispParams, pVarResult,
-          pExcepInfo, puArgErr);
-
-    return IDispatch_Invoke(This->dispatch, dispIdMember, riid, lcid,
-                            wFlags, pDispParams, pVarResult, pExcepInfo,
-                            puArgErr);
-}
-
-typedef struct
-{
-    IRpcChannelBuffer     IRpcChannelBuffer_iface;
-    LONG                  refs;
-    /* the IDispatch-derived interface we are handling */
-    IID                   tmarshal_iid;
-    IRpcChannelBuffer    *pDelegateChannel;
-} TMarshalDispatchChannel;
-
-static inline TMarshalDispatchChannel *impl_from_IRpcChannelBuffer(IRpcChannelBuffer *iface)
-{
-    return CONTAINING_RECORD(iface, TMarshalDispatchChannel, IRpcChannelBuffer_iface);
-}
-
-static HRESULT WINAPI TMarshalDispatchChannel_QueryInterface(IRpcChannelBuffer *iface, REFIID riid, LPVOID *ppv)
-{
-    *ppv = NULL;
-    if (IsEqualIID(riid,&IID_IRpcChannelBuffer) || IsEqualIID(riid,&IID_IUnknown))
-    {
-        *ppv = iface;
-        IRpcChannelBuffer_AddRef(iface);
-        return S_OK;
-    }
-    return E_NOINTERFACE;
-}
-
-static ULONG WINAPI TMarshalDispatchChannel_AddRef(LPRPCCHANNELBUFFER iface)
-{
-    TMarshalDispatchChannel *This = impl_from_IRpcChannelBuffer(iface);
-    return InterlockedIncrement(&This->refs);
-}
-
-static ULONG WINAPI TMarshalDispatchChannel_Release(LPRPCCHANNELBUFFER iface)
-{
-    TMarshalDispatchChannel *This = impl_from_IRpcChannelBuffer(iface);
-    ULONG ref;
-
-    ref = InterlockedDecrement(&This->refs);
-    if (ref)
-        return ref;
-
-    IRpcChannelBuffer_Release(This->pDelegateChannel);
-    HeapFree(GetProcessHeap(), 0, This);
-    return 0;
-}
-
-static HRESULT WINAPI TMarshalDispatchChannel_GetBuffer(LPRPCCHANNELBUFFER iface, RPCOLEMESSAGE* olemsg, REFIID riid)
-{
-    TMarshalDispatchChannel *This = impl_from_IRpcChannelBuffer(iface);
-    TRACE("(%p, %s)\n", olemsg, debugstr_guid(riid));
-    /* Note: we are pretending to invoke a method on the interface identified
-     * by tmarshal_iid so that we can re-use the IDispatch proxy/stub code
-     * without the RPC runtime getting confused by not exporting an IDispatch interface */
-    return IRpcChannelBuffer_GetBuffer(This->pDelegateChannel, olemsg, &This->tmarshal_iid);
-}
-
-static HRESULT WINAPI TMarshalDispatchChannel_SendReceive(LPRPCCHANNELBUFFER iface, RPCOLEMESSAGE *olemsg, ULONG *pstatus)
-{
-    TMarshalDispatchChannel *This = impl_from_IRpcChannelBuffer(iface);
-    TRACE("(%p, %p)\n", olemsg, pstatus);
-    return IRpcChannelBuffer_SendReceive(This->pDelegateChannel, olemsg, pstatus);
-}
-
-static HRESULT WINAPI TMarshalDispatchChannel_FreeBuffer(LPRPCCHANNELBUFFER iface, RPCOLEMESSAGE* olemsg)
-{
-    TMarshalDispatchChannel *This = impl_from_IRpcChannelBuffer(iface);
-    TRACE("(%p)\n", olemsg);
-    return IRpcChannelBuffer_FreeBuffer(This->pDelegateChannel, olemsg);
-}
-
-static HRESULT WINAPI TMarshalDispatchChannel_GetDestCtx(LPRPCCHANNELBUFFER iface, DWORD* pdwDestContext, void** ppvDestContext)
-{
-    TMarshalDispatchChannel *This = impl_from_IRpcChannelBuffer(iface);
-    TRACE("(%p,%p)\n", pdwDestContext, ppvDestContext);
-    return IRpcChannelBuffer_GetDestCtx(This->pDelegateChannel, pdwDestContext, ppvDestContext);
-}
-
-static HRESULT WINAPI TMarshalDispatchChannel_IsConnected(LPRPCCHANNELBUFFER iface)
-{
-    TMarshalDispatchChannel *This = impl_from_IRpcChannelBuffer(iface);
-    TRACE("()\n");
-    return IRpcChannelBuffer_IsConnected(This->pDelegateChannel);
-}
-
-static const IRpcChannelBufferVtbl TMarshalDispatchChannelVtbl =
-{
-    TMarshalDispatchChannel_QueryInterface,
-    TMarshalDispatchChannel_AddRef,
-    TMarshalDispatchChannel_Release,
-    TMarshalDispatchChannel_GetBuffer,
-    TMarshalDispatchChannel_SendReceive,
-    TMarshalDispatchChannel_FreeBuffer,
-    TMarshalDispatchChannel_GetDestCtx,
-    TMarshalDispatchChannel_IsConnected
-};
-
-static HRESULT TMarshalDispatchChannel_Create(
-    IRpcChannelBuffer *pDelegateChannel, REFIID tmarshal_riid,
-    IRpcChannelBuffer **ppChannel)
-{
-    TMarshalDispatchChannel *This = HeapAlloc(GetProcessHeap(), 0, sizeof(*This));
-    if (!This)
-        return E_OUTOFMEMORY;
-
-    This->IRpcChannelBuffer_iface.lpVtbl = &TMarshalDispatchChannelVtbl;
-    This->refs = 1;
-    IRpcChannelBuffer_AddRef(pDelegateChannel);
-    This->pDelegateChannel = pDelegateChannel;
-    This->tmarshal_iid = *tmarshal_riid;
-
-    *ppChannel = &This->IRpcChannelBuffer_iface;
-    return S_OK;
-}
-
-
-static inline HRESULT get_facbuf_for_iid(REFIID riid, IPSFactoryBuffer **facbuf)
-{
-    HRESULT       hr;
-    CLSID         clsid;
-
-    if ((hr = CoGetPSClsid(riid, &clsid)))
-        return hr;
-    return CoGetClassObject(&clsid, CLSCTX_INPROC_SERVER, NULL,
-                             &IID_IPSFactoryBuffer, (LPVOID*)facbuf);
-}
-
-static HRESULT init_proxy_entry_point(TMProxyImpl *proxy, unsigned int num)
-{
-    int j;
-    /* nrofargs including This */
-    int nrofargs = 1;
-    ITypeInfo *tinfo2;
-    TMAsmProxy *xasm = proxy->asmstubs + num;
-    HRESULT hres;
-    const FUNCDESC *fdesc;
-
-    hres = get_funcdesc(proxy->tinfo, num, &tinfo2, &fdesc, NULL, NULL, NULL);
-    if (hres) {
-        ERR("GetFuncDesc %x should not fail here.\n",hres);
-        return hres;
-    }
-    ITypeInfo_Release(tinfo2);
-    /* some args take more than 4 byte on the stack */
-    for (j=0;j<fdesc->cParams;j++)
-        nrofargs += _argsize(&fdesc->lprgelemdescParam[j].tdesc, proxy->tinfo);
-
-#ifdef __i386__
-    if (fdesc->callconv != CC_STDCALL) {
-        ERR("calling convention is not stdcall????\n");
-        return E_FAIL;
-    }
-/* leal 4(%esp),%eax
- * pushl %eax
- * pushl <nr>
- * call xCall
- * lret <nr>
- */
-    xasm->lealeax       = 0x0424448d;
-    xasm->pushleax      = 0x50;
-    xasm->pushlval      = 0x68;
-    xasm->nr            = num;
-    xasm->lcall         = 0xe8;
-    xasm->xcall         = (char *)xCall - (char *)&xasm->lret;
-    xasm->lret          = 0xc2;
-    xasm->bytestopop    = nrofargs * 4;
-    xasm->nop           = 0x9090;
-    proxy->lpvtbl[fdesc->oVft / sizeof(void *)] = xasm;
-
-#elif defined(__x86_64__)
-
-    xasm->pushq_rbp         = 0x55;         /* pushq %rbp */
-    xasm->movq_rsp_rbp[0]   = 0x48;         /* movq %rsp,%rbp */
-    xasm->movq_rsp_rbp[1]   = 0x89;
-    xasm->movq_rsp_rbp[2]   = 0xe5;
-    xasm->subq_0x20_rsp     = 0x20ec8348;   /* subq 0x20,%rsp */
-    xasm->movq_rcx_0x10rbp  = 0x104d8948;   /* movq %rcx,0x10(%rbp) */
-    xasm->movq_rdx_0x18rbp  = 0x18558948;   /* movq %rdx,0x18(%rbp) */
-    xasm->movq_r8_0x20rbp   = 0x2045894c;   /* movq %r8,0x20(%rbp) */
-    xasm->movq_r9_0x28rbp   = 0x284d894c;   /* movq %r9,0x28(%rbp) */
-    xasm->movq_rcx[0]       = 0x48;         /* movq <num>,%rcx */
-    xasm->movq_rcx[1]       = 0xc7;
-    xasm->movq_rcx[2]       = 0xc1;
-    xasm->nr                = num;
-    xasm->leaq_0x10rbp_rdx  = 0x10558d48;   /* leaq 0x10(%rbp),%rdx */
-    xasm->movq_rax          = 0xb848;       /* movq <xCall>,%rax */
-    xasm->xcall             = xCall;
-    xasm->callq_rax         = 0xd0ff;       /* callq *%rax */
-    xasm->movq_rbp_rsp[0]   = 0x48;         /* movq %rbp,%rsp */
-    xasm->movq_rbp_rsp[1]   = 0x89;
-    xasm->movq_rbp_rsp[2]   = 0xec;
-    xasm->popq_rbp          = 0x5d;         /* popq %rbp */
-    xasm->ret               = 0xc3;         /* ret */
-    xasm->nop               = 0x90909090;   /* nop */
-    proxy->lpvtbl[fdesc->oVft / sizeof(void *)] = xasm;
-
-#else
-    FIXME("not implemented on non i386\n");
-    return E_FAIL;
-#endif
-    return S_OK;
-}
-
-static HRESULT WINAPI
-PSFacBuf_CreateProxy(
-    LPPSFACTORYBUFFER iface, IUnknown* pUnkOuter, REFIID riid,
-    IRpcProxyBuffer **ppProxy, LPVOID *ppv)
-{
-    HRESULT    hres;
-    ITypeInfo  *tinfo;
-    unsigned int i, nroffuncs, vtbl_size;
-    TMProxyImpl        *proxy;
-    TYPEATTR   *typeattr;
-    BOOL        defer_to_dispatch = FALSE;
-
-    TRACE("(...%s...)\n",debugstr_guid(riid));
-    hres = _get_typeinfo_for_iid(riid,&tinfo);
-    if (hres) {
-       ERR("No typeinfo for %s?\n",debugstr_guid(riid));
-       return hres;
-    }
-
-    hres = num_of_funcs(tinfo, &nroffuncs, &vtbl_size);
-    TRACE("Got %d funcs, vtbl size %d\n", nroffuncs, vtbl_size);
-
-    if (FAILED(hres)) {
-        ERR("Cannot get number of functions for typeinfo %s\n",debugstr_guid(riid));
-        ITypeInfo_Release(tinfo);
-        return hres;
-    }
-
-    proxy = CoTaskMemAlloc(sizeof(TMProxyImpl));
-    if (!proxy) return E_OUTOFMEMORY;
-
-    proxy->dispatch = NULL;
-    proxy->dispatch_proxy = NULL;
-    proxy->outerunknown = pUnkOuter;
-    proxy->asmstubs = VirtualAlloc(NULL, sizeof(TMAsmProxy) * nroffuncs, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
-    if (!proxy->asmstubs) {
-        ERR("Could not commit pages for proxy thunks\n");
-        CoTaskMemFree(proxy);
-        return E_OUTOFMEMORY;
-    }
-    proxy->IRpcProxyBuffer_iface.lpVtbl = &tmproxyvtable;
-    /* one reference for the proxy */
-    proxy->ref         = 1;
-    proxy->tinfo       = tinfo;
-    proxy->iid         = *riid;
-    proxy->chanbuf      = 0;
-
-    InitializeCriticalSection(&proxy->crit);
-    proxy->crit.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": TMProxyImpl.crit");
-
-    proxy->lpvtbl = HeapAlloc(GetProcessHeap(), 0, vtbl_size);
-
-    /* if we derive from IDispatch then defer to its proxy for its methods */
-    hres = ITypeInfo_GetTypeAttr(tinfo, &typeattr);
-    if (hres == S_OK)
-    {
-        if (typeattr->wTypeFlags & TYPEFLAG_FDISPATCHABLE)
-        {
-            IPSFactoryBuffer *factory_buffer;
-            hres = get_facbuf_for_iid(&IID_IDispatch, &factory_buffer);
-            if (hres == S_OK)
-            {
-                hres = IPSFactoryBuffer_CreateProxy(factory_buffer, NULL,
-                    &IID_IDispatch, &proxy->dispatch_proxy,
-                    (void **)&proxy->dispatch);
-                IPSFactoryBuffer_Release(factory_buffer);
-            }
-            if ((hres == S_OK) && (nroffuncs < 7))
-            {
-                ERR("nroffuncs calculated incorrectly (%d)\n", nroffuncs);
-                hres = E_UNEXPECTED;
-            }
-            if (hres == S_OK)
-            {
-                defer_to_dispatch = TRUE;
-            }
-        }
-        ITypeInfo_ReleaseTypeAttr(tinfo, typeattr);
-    }
-
-    for (i=0;i<nroffuncs;i++) {
-       switch (i) {
-       case 0:
-               proxy->lpvtbl[i] = ProxyIUnknown_QueryInterface;
-               break;
-       case 1:
-               proxy->lpvtbl[i] = ProxyIUnknown_AddRef;
-               break;
-       case 2:
-               proxy->lpvtbl[i] = ProxyIUnknown_Release;
-               break;
-        case 3:
-                if(!defer_to_dispatch) hres = init_proxy_entry_point(proxy, i);
-                else proxy->lpvtbl[3] = ProxyIDispatch_GetTypeInfoCount;
-                break;
-        case 4:
-                if(!defer_to_dispatch) hres = init_proxy_entry_point(proxy, i);
-                else proxy->lpvtbl[4] = ProxyIDispatch_GetTypeInfo;
-                break;
-        case 5:
-                if(!defer_to_dispatch) hres = init_proxy_entry_point(proxy, i);
-                else proxy->lpvtbl[5] = ProxyIDispatch_GetIDsOfNames;
-                break;
-        case 6:
-                if(!defer_to_dispatch) hres = init_proxy_entry_point(proxy, i);
-                else proxy->lpvtbl[6] = ProxyIDispatch_Invoke;
-                break;
-       default:
-                hres = init_proxy_entry_point(proxy, i);
-       }
-    }
-
-    if (hres == S_OK)
-    {
-        *ppv = proxy;
-        *ppProxy = &proxy->IRpcProxyBuffer_iface;
-        IUnknown_AddRef((IUnknown *)*ppv);
-        return S_OK;
-    }
-    else
-        TMProxyImpl_Release(&proxy->IRpcProxyBuffer_iface);
-    return hres;
-}
-
-typedef struct _TMStubImpl {
-    IRpcStubBuffer              IRpcStubBuffer_iface;
-    LONG                       ref;
-
-    LPUNKNOWN                  pUnk;
-    ITypeInfo                  *tinfo;
-    IID                                iid;
-    IRpcStubBuffer             *dispatch_stub;
-    BOOL                       dispatch_derivative;
-} TMStubImpl;
-
-static inline TMStubImpl *impl_from_IRpcStubBuffer(IRpcStubBuffer *iface)
-{
-    return CONTAINING_RECORD(iface, TMStubImpl, IRpcStubBuffer_iface);
-}
-
-static HRESULT WINAPI
-TMStubImpl_QueryInterface(LPRPCSTUBBUFFER iface, REFIID riid, LPVOID *ppv)
-{
-    if (IsEqualIID(riid,&IID_IRpcStubBuffer)||IsEqualIID(riid,&IID_IUnknown)){
-        *ppv = iface;
-       IRpcStubBuffer_AddRef(iface);
-       return S_OK;
-    }
-    FIXME("%s, not supported IID.\n",debugstr_guid(riid));
-    return E_NOINTERFACE;
-}
-
-static ULONG WINAPI
-TMStubImpl_AddRef(LPRPCSTUBBUFFER iface)
-{
-    TMStubImpl *This = impl_from_IRpcStubBuffer(iface);
-    ULONG refCount = InterlockedIncrement(&This->ref);
-
-    TRACE("(%p)->(ref before=%u)\n", This, refCount - 1);
-
-    return refCount;
-}
-
-static ULONG WINAPI
-TMStubImpl_Release(LPRPCSTUBBUFFER iface)
-{
-    TMStubImpl *This = impl_from_IRpcStubBuffer(iface);
-    ULONG refCount = InterlockedDecrement(&This->ref);
-
-    TRACE("(%p)->(ref before=%u)\n", This, refCount + 1);
-
-    if (!refCount)
-    {
-        IRpcStubBuffer_Disconnect(iface);
-        ITypeInfo_Release(This->tinfo);
-        if (This->dispatch_stub)
-            IRpcStubBuffer_Release(This->dispatch_stub);
-        CoTaskMemFree(This);
-    }
-    return refCount;
-}
-
-static HRESULT WINAPI
-TMStubImpl_Connect(LPRPCSTUBBUFFER iface, LPUNKNOWN pUnkServer)
-{
-    TMStubImpl *This = impl_from_IRpcStubBuffer(iface);
-
-    TRACE("(%p)->(%p)\n", This, pUnkServer);
-
-    IUnknown_AddRef(pUnkServer);
-    This->pUnk = pUnkServer;
-
-    if (This->dispatch_stub)
-        IRpcStubBuffer_Connect(This->dispatch_stub, pUnkServer);
-
-    return S_OK;
-}
-
-static void WINAPI
-TMStubImpl_Disconnect(LPRPCSTUBBUFFER iface)
-{
-    TMStubImpl *This = impl_from_IRpcStubBuffer(iface);
-
-    TRACE("(%p)->()\n", This);
-
-    if (This->pUnk)
-    {
-        IUnknown_Release(This->pUnk);
-        This->pUnk = NULL;
-    }
-
-    if (This->dispatch_stub)
-        IRpcStubBuffer_Disconnect(This->dispatch_stub);
-}
-
-static HRESULT WINAPI
-TMStubImpl_Invoke(
-    LPRPCSTUBBUFFER iface, RPCOLEMESSAGE* xmsg,IRpcChannelBuffer*rpcchanbuf)
-{
-#if defined(__i386__) || defined(__x86_64__)
-    int                i;
-    const FUNCDESC *fdesc;
-    TMStubImpl *This = impl_from_IRpcStubBuffer(iface);
-    HRESULT    hres;
-    DWORD_PTR   *args = NULL, *xargs;
-    DWORD      res, nrofargs;
-    marshal_state      buf;
-    UINT       nrofnames = 0;
-    BSTR       names[10];
-    BSTR       iname = NULL;
-    ITypeInfo  *tinfo = NULL;
-
-    TRACE("...\n");
-
-    if (xmsg->iMethod < 3) {
-        ERR("IUnknown methods cannot be marshaled by the typelib marshaler\n");
-        return E_UNEXPECTED;
-    }
-
-    if (This->dispatch_derivative && xmsg->iMethod < sizeof(IDispatchVtbl)/sizeof(void *))
-    {
-        if (!This->dispatch_stub)
-        {
-            IPSFactoryBuffer *factory_buffer;
-            hres = get_facbuf_for_iid(&IID_IDispatch, &factory_buffer);
-            if (hres == S_OK)
-            {
-                hres = IPSFactoryBuffer_CreateStub(factory_buffer, &IID_IDispatch,
-                    This->pUnk, &This->dispatch_stub);
-                IPSFactoryBuffer_Release(factory_buffer);
-            }
-            if (hres != S_OK)
-                return hres;
-        }
-        return IRpcStubBuffer_Invoke(This->dispatch_stub, xmsg, rpcchanbuf);
-    }
-
-    memset(&buf,0,sizeof(buf));
-    buf.size   = xmsg->cbBuffer;
-    buf.base   = HeapAlloc(GetProcessHeap(), 0, xmsg->cbBuffer);
-    memcpy(buf.base, xmsg->Buffer, xmsg->cbBuffer);
-    buf.curoff = 0;
-
-    hres = get_funcdesc(This->tinfo,xmsg->iMethod,&tinfo,&fdesc,&iname,NULL,NULL);
-    if (hres) {
-       ERR("GetFuncDesc on method %d failed with %x\n",xmsg->iMethod,hres);
-       return hres;
-    }
-
-    if (iname && !lstrcmpW(iname, IDispatchW))
-    {
-        ERR("IDispatch cannot be marshaled by the typelib marshaler\n");
-        hres = E_UNEXPECTED;
-        SysFreeString (iname);
-        goto exit;
-    }
-
-    SysFreeString (iname);
-
-    /* Need them for hack below */
-    memset(names,0,sizeof(names));
-    ITypeInfo_GetNames(tinfo,fdesc->memid,names,sizeof(names)/sizeof(names[0]),&nrofnames);
-    if (nrofnames > sizeof(names)/sizeof(names[0])) {
-       ERR("Need more names!\n");
-    }
-
-    /*dump_FUNCDESC(fdesc);*/
-    nrofargs = 0;
-    for (i=0;i<fdesc->cParams;i++)
-       nrofargs += _argsize(&fdesc->lprgelemdescParam[i].tdesc, tinfo);
-    args = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (nrofargs+1)*sizeof(DWORD_PTR));
-    if (!args)
-    {
-        hres = E_OUTOFMEMORY;
-        goto exit;
-    }
-
-    /* Allocate all stuff used by call. */
-    xargs = args+1;
-    for (i=0;i<fdesc->cParams;i++) {
-       ELEMDESC        *elem = fdesc->lprgelemdescParam+i;
-
-       hres = deserialize_param(
-          tinfo,
-          is_in_elem(elem),
-          FALSE,
-          TRUE,
-          &(elem->tdesc),
-          xargs,
-          &buf
-       );
-       xargs += _argsize(&elem->tdesc, tinfo);
-       if (hres) {
-           ERR("Failed to deserialize param %s, hres %x\n",relaystr(names[i+1]),hres);
-           break;
-       }
-    }
-
-    args[0] = (DWORD_PTR)This->pUnk;
-
-    __TRY
-    {
-        res = _invoke(
-            (*((FARPROC**)args[0]))[fdesc->oVft / sizeof(DWORD_PTR)],
-            fdesc->callconv,
-            (xargs-args),
-            args
-        );
-    }
-    __EXCEPT_ALL
-    {
-        DWORD dwExceptionCode = GetExceptionCode();
-        ERR("invoke call failed with exception 0x%08x (%d)\n", dwExceptionCode, dwExceptionCode);
-        if (FAILED(dwExceptionCode))
-            hres = dwExceptionCode;
-        else
-            hres = HRESULT_FROM_WIN32(dwExceptionCode);
-    }
-    __ENDTRY
-
-    if (hres != S_OK)
-        goto exit;
-
-    buf.curoff = 0;
-
-    xargs = args+1;
-    for (i=0;i<fdesc->cParams;i++) {
-       ELEMDESC        *elem = fdesc->lprgelemdescParam+i;
-       hres = serialize_param(
-          tinfo,
-          is_out_elem(elem),
-          FALSE,
-          TRUE,
-          &elem->tdesc,
-          xargs,
-          &buf
-       );
-       xargs += _argsize(&elem->tdesc, tinfo);
-       if (hres) {
-           ERR("Failed to stuballoc param, hres %x\n",hres);
-           break;
-       }
-    }
-
-    hres = xbuf_add (&buf, (LPBYTE)&res, sizeof(DWORD));
-
-    if (hres != S_OK)
-        goto exit;
-
-    xmsg->cbBuffer     = buf.curoff;
-    hres = IRpcChannelBuffer_GetBuffer(rpcchanbuf, xmsg, &This->iid);
-    if (hres != S_OK)
-        ERR("IRpcChannelBuffer_GetBuffer failed with error 0x%08x\n", hres);
-
-    if (hres == S_OK)
-        memcpy(xmsg->Buffer, buf.base, buf.curoff);
-
-exit:
-    for (i = 0; i < nrofnames; i++)
-        SysFreeString(names[i]);
-
-    ITypeInfo_Release(tinfo);
-    HeapFree(GetProcessHeap(), 0, args);
-
-    HeapFree(GetProcessHeap(), 0, buf.base);
-
-    TRACE("returning\n");
-    return hres;
-#else
-    FIXME( "not implemented on non-i386\n" );
-    return E_FAIL;
-#endif
-}
-
-static LPRPCSTUBBUFFER WINAPI
-TMStubImpl_IsIIDSupported(LPRPCSTUBBUFFER iface, REFIID riid) {
-    FIXME("Huh (%s)?\n",debugstr_guid(riid));
-    return NULL;
-}
-
-static ULONG WINAPI
-TMStubImpl_CountRefs(LPRPCSTUBBUFFER iface) {
-    TMStubImpl *This = impl_from_IRpcStubBuffer(iface);
-
-    FIXME("()\n");
-    return This->ref; /*FIXME? */
-}
-
-static HRESULT WINAPI
-TMStubImpl_DebugServerQueryInterface(LPRPCSTUBBUFFER iface, LPVOID *ppv) {
-    return E_NOTIMPL;
-}
-
-static void WINAPI
-TMStubImpl_DebugServerRelease(LPRPCSTUBBUFFER iface, LPVOID ppv) {
-    return;
-}
-
-static const IRpcStubBufferVtbl tmstubvtbl = {
-    TMStubImpl_QueryInterface,
-    TMStubImpl_AddRef,
-    TMStubImpl_Release,
-    TMStubImpl_Connect,
-    TMStubImpl_Disconnect,
-    TMStubImpl_Invoke,
-    TMStubImpl_IsIIDSupported,
-    TMStubImpl_CountRefs,
-    TMStubImpl_DebugServerQueryInterface,
-    TMStubImpl_DebugServerRelease
-};
-
-static HRESULT WINAPI
-PSFacBuf_CreateStub(
-    LPPSFACTORYBUFFER iface, REFIID riid,IUnknown *pUnkServer,
-    IRpcStubBuffer** ppStub
-) {
-    HRESULT hres;
-    ITypeInfo  *tinfo;
-    TMStubImpl *stub;
-    TYPEATTR *typeattr;
-    IUnknown *obj;
-
-    TRACE("(%s,%p,%p)\n",debugstr_guid(riid),pUnkServer,ppStub);
-
-    hres = _get_typeinfo_for_iid(riid,&tinfo);
-    if (hres) {
-       ERR("No typeinfo for %s?\n",debugstr_guid(riid));
-       return hres;
-    }
-
-    /* FIXME: This is not exactly right. We should probably call QI later. */
-    hres = IUnknown_QueryInterface(pUnkServer, riid, (void**)&obj);
-    if (FAILED(hres)) {
-        WARN("Could not get %s iface: %08x\n", debugstr_guid(riid), hres);
-        obj = pUnkServer;
-        IUnknown_AddRef(obj);
-    }
-
-    stub = CoTaskMemAlloc(sizeof(TMStubImpl));
-    if (!stub) {
-        IUnknown_Release(obj);
-       return E_OUTOFMEMORY;
-    }
-    stub->IRpcStubBuffer_iface.lpVtbl = &tmstubvtbl;
-    stub->ref          = 1;
-    stub->tinfo                = tinfo;
-    stub->dispatch_stub = NULL;
-    stub->dispatch_derivative = FALSE;
-    stub->iid          = *riid;
-    hres = IRpcStubBuffer_Connect(&stub->IRpcStubBuffer_iface, obj);
-    *ppStub = &stub->IRpcStubBuffer_iface;
-    TRACE("IRpcStubBuffer: %p\n", stub);
-    if (hres)
-       ERR("Connect to pUnkServer failed?\n");
-
-    /* if we derive from IDispatch then defer to its stub for some of its methods */
-    hres = ITypeInfo_GetTypeAttr(tinfo, &typeattr);
-    if (hres == S_OK)
-    {
-        if (typeattr->wTypeFlags & TYPEFLAG_FDISPATCHABLE)
-            stub->dispatch_derivative = TRUE;
-        ITypeInfo_ReleaseTypeAttr(tinfo, typeattr);
-    }
-
-    IUnknown_Release(obj);
-    return hres;
-}
-
-static const IPSFactoryBufferVtbl psfacbufvtbl = {
-    PSFacBuf_QueryInterface,
-    PSFacBuf_AddRef,
-    PSFacBuf_Release,
-    PSFacBuf_CreateProxy,
-    PSFacBuf_CreateStub
-};
-
-static IPSFactoryBuffer psfac = { &psfacbufvtbl };
-
-/***********************************************************************
- *           TMARSHAL_DllGetClassObject
- */
-HRESULT TMARSHAL_DllGetClassObject(REFCLSID rclsid, REFIID iid, void **ppv)
-{
-    return IPSFactoryBuffer_QueryInterface(&psfac, iid, ppv);
-}
index 4a609d7..6ed9ce9 100644 (file)
@@ -328,7 +328,7 @@ static HRESULT query_typelib_path( REFGUID guid, WORD wMaj, WORD wMin,
                 return TYPE_E_LIBNOTREGISTERED;
 
             nameW = (WCHAR*)((BYTE*)data.lpSectionBase + tlib->name_offset);
                 return TYPE_E_LIBNOTREGISTERED;
 
             nameW = (WCHAR*)((BYTE*)data.lpSectionBase + tlib->name_offset);
-            len = SearchPathW( NULL, nameW, NULL, sizeof(Path)/sizeof(WCHAR), Path, NULL );
+            len = SearchPathW( NULL, nameW, NULL, ARRAY_SIZE( Path ), Path, NULL );
             if (!len) return TYPE_E_LIBNOTREGISTERED;
 
             TRACE_(typelib)("got path from context %s\n", debugstr_w(Path));
             if (!len) return TYPE_E_LIBNOTREGISTERED;
 
             TRACE_(typelib)("got path from context %s\n", debugstr_w(Path));
@@ -979,11 +979,11 @@ enddeleteloop:
 
     /* check if there is anything besides the FLAGS/HELPDIR keys.
        If there is, we don't delete them */
 
     /* check if there is anything besides the FLAGS/HELPDIR keys.
        If there is, we don't delete them */
-    tmpLength = sizeof(subKeyName)/sizeof(WCHAR);
+    tmpLength = ARRAY_SIZE(subKeyName);
     deleteOtherStuff = TRUE;
     i = 0;
     while(RegEnumKeyExW(key, i++, subKeyName, &tmpLength, NULL, NULL, NULL, NULL) == ERROR_SUCCESS) {
     deleteOtherStuff = TRUE;
     i = 0;
     while(RegEnumKeyExW(key, i++, subKeyName, &tmpLength, NULL, NULL, NULL, NULL) == ERROR_SUCCESS) {
-        tmpLength = sizeof(subKeyName)/sizeof(WCHAR);
+        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 its not FLAGS or HELPDIR, then we must keep the rest of the key */
         if (!strcmpW(subKeyName, FLAGSW)) continue;
@@ -2685,7 +2685,7 @@ static ITypeInfoImpl * MSFT_DoTypeInfo(
     ptiRet->typeattr.wMajorVerNum = LOWORD(tiBase.version);
     ptiRet->typeattr.wMinorVerNum = HIWORD(tiBase.version);
     ptiRet->typeattr.cImplTypes = tiBase.cImplTypes;
     ptiRet->typeattr.wMajorVerNum = LOWORD(tiBase.version);
     ptiRet->typeattr.wMinorVerNum = HIWORD(tiBase.version);
     ptiRet->typeattr.cImplTypes = tiBase.cImplTypes;
-    ptiRet->typeattr.cbSizeVft = tiBase.cbSizeVft; /* FIXME: this is only the non inherited part */
+    ptiRet->typeattr.cbSizeVft = tiBase.cbSizeVft;
     if (ptiRet->typeattr.typekind == TKIND_ALIAS) {
         TYPEDESC tmp;
         MSFT_GetTdesc(pcx, tiBase.datatype1, &tmp);
     if (ptiRet->typeattr.typekind == TKIND_ALIAS) {
         TYPEDESC tmp;
         MSFT_GetTdesc(pcx, tiBase.datatype1, &tmp);
@@ -6405,6 +6405,7 @@ static HRESULT WINAPI ITypeInfo_fnGetIDsOfNames( ITypeInfo2 *iface,
 #ifdef __i386__
 
 extern LONGLONG call_method( void *func, int nb_args, const DWORD *args, int *stack_offset );
 #ifdef __i386__
 
 extern LONGLONG call_method( void *func, int nb_args, const DWORD *args, int *stack_offset );
+extern double call_double_method( void *func, int nb_args, const DWORD *args, int *stack_offset );
 __ASM_GLOBAL_FUNC( call_method,
                    "pushl %ebp\n\t"
                    __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t")
 __ASM_GLOBAL_FUNC( call_method,
                    "pushl %ebp\n\t"
                    __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t")
@@ -6439,45 +6440,13 @@ __ASM_GLOBAL_FUNC( call_method,
                    __ASM_CFI(".cfi_def_cfa %esp,4\n\t")
                    __ASM_CFI(".cfi_same_value %ebp\n\t")
                    "ret" )
                    __ASM_CFI(".cfi_def_cfa %esp,4\n\t")
                    __ASM_CFI(".cfi_same_value %ebp\n\t")
                    "ret" )
-
-/* same function but returning floating point */
-static double (* const call_double_method)(void*,int,const DWORD*,int*) = (void *)call_method;
-
-/* ITypeInfo::Invoke
- *
- * Invokes a method, or accesses a property of an object, that implements the
- * interface described by the type description.
- */
-DWORD _invoke(FARPROC func, CALLCONV callconv, int nrargs, DWORD_PTR *args)
-{
-    DWORD res;
-    int stack_offset;
-
-    if (TRACE_ON(ole)) {
-       int i;
-       TRACE("Calling %p(",func);
-       for (i=0;i<min(nrargs,30);i++) TRACE("%08lx,",args[i]);
-       if (nrargs > 30) TRACE("...");
-       TRACE(")\n");
-    }
-
-    switch (callconv) {
-    case CC_STDCALL:
-    case CC_CDECL:
-        res = call_method(func, nrargs, (DWORD *)args, &stack_offset);
-       break;
-    default:
-       FIXME("unsupported calling convention %d\n",callconv);
-       res = -1;
-       break;
-    }
-    TRACE("returns %08x\n",res);
-    return res;
-}
+__ASM_GLOBAL_FUNC( call_double_method,
+                   "jmp " __ASM_NAME("call_method") )
 
 #elif defined(__x86_64__)
 
 extern DWORD_PTR CDECL call_method( void *func, int nb_args, const DWORD_PTR *args );
 
 #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_CFI(".cfi_adjust_cfa_offset 8\n\t")
 __ASM_GLOBAL_FUNC( call_method,
                    "pushq %rbp\n\t"
                    __ASM_CFI(".cfi_adjust_cfa_offset 8\n\t")
@@ -6517,41 +6486,14 @@ __ASM_GLOBAL_FUNC( call_method,
                    __ASM_CFI(".cfi_adjust_cfa_offset -8\n\t")
                    __ASM_CFI(".cfi_same_value %rbp\n\t")
                    "ret")
                    __ASM_CFI(".cfi_adjust_cfa_offset -8\n\t")
                    __ASM_CFI(".cfi_same_value %rbp\n\t")
                    "ret")
-
-/* same function but returning floating point */
-static double (CDECL * const call_double_method)(void*,int,const DWORD_PTR*) = (void *)call_method;
-
-DWORD _invoke(FARPROC func, CALLCONV callconv, int nrargs, DWORD_PTR *args)
-{
-    DWORD res;
-
-    if (TRACE_ON(ole))
-    {
-        int i;
-        TRACE("Calling %p(", func);
-        for (i=0; i<min(nrargs, 30); i++) TRACE("%016lx,", args[i]);
-        if (nrargs > 30) TRACE("...");
-        TRACE(")\n");
-    }
-
-    switch (callconv) {
-    case CC_STDCALL:
-    case CC_CDECL:
-        res = call_method(func, nrargs, args);
-        break;
-    default:
-        FIXME("unsupported calling convention %d\n", callconv);
-        res = -1;
-        break;
-    }
-
-    TRACE("returns %08x\n", res);
-    return res;
-}
+__ASM_GLOBAL_FUNC( call_double_method,
+                   "jmp " __ASM_NAME("call_method") )
 
 #elif defined(__arm__)
 
 extern LONGLONG CDECL call_method( void *func, int nb_stk_args, const DWORD *stk_args, const DWORD *reg_args );
 
 #elif defined(__arm__)
 
 extern LONGLONG CDECL call_method( void *func, int nb_stk_args, const DWORD *stk_args, const DWORD *reg_args );
+extern float CDECL call_float_method( void *func, int nb_stk_args, const DWORD *stk_args, const DWORD *reg_args );
+extern double CDECL call_double_method( void *func, int nb_stk_args, const DWORD *stk_args, const DWORD *reg_args );
 __ASM_GLOBAL_FUNC( call_method,
                     /* r0 = *func
                      * r1 = nb_stk_args
 __ASM_GLOBAL_FUNC( call_method,
                     /* r0 = *func
                      * r1 = nb_stk_args
@@ -6582,12 +6524,12 @@ __ASM_GLOBAL_FUNC( call_method,
                     "mov sp, fp\n\t"                /* Clean the stack using fp */
                     "pop {fp, pc}\n\t"              /* Restore fp and return */
                 )
                     "mov sp, fp\n\t"                /* Clean the stack using fp */
                     "pop {fp, pc}\n\t"              /* Restore fp and return */
                 )
+__ASM_GLOBAL_FUNC( call_float_method,
+                   "b " __ASM_NAME("call_method") )
+__ASM_GLOBAL_FUNC( call_double_method,
+                   "b " __ASM_NAME("call_method") )
 
 
-/* same function but returning single/double floating point */
-static float (CDECL * const call_float_method)(void *, int, const DWORD *, const DWORD *) = (void *)call_method;
-static double (CDECL * const call_double_method)(void *, int, const DWORD *, const DWORD *) = (void *)call_method;
-
-#endif  /* __x86_64__ */
+#endif  /* __arm__ */
 
 static HRESULT userdefined_to_variantvt(ITypeInfo *tinfo, const TYPEDESC *tdesc, VARTYPE *vt)
 {
 
 static HRESULT userdefined_to_variantvt(ITypeInfo *tinfo, const TYPEDESC *tdesc, VARTYPE *vt)
 {
@@ -6728,6 +6670,7 @@ static HRESULT get_iface_guid(ITypeInfo *tinfo, HREFTYPE href, GUID *guid)
     ITypeInfo *tinfo2;
     TYPEATTR *tattr;
     HRESULT hres;
     ITypeInfo *tinfo2;
     TYPEATTR *tattr;
     HRESULT hres;
+    int flags, i;
 
     hres = ITypeInfo_GetRefTypeInfo(tinfo, href, &tinfo2);
     if(FAILED(hres))
 
     hres = ITypeInfo_GetRefTypeInfo(tinfo, href, &tinfo2);
     if(FAILED(hres))
@@ -6749,20 +6692,21 @@ static HRESULT get_iface_guid(ITypeInfo *tinfo, HREFTYPE href, GUID *guid)
         *guid = tattr->guid;
         break;
 
         *guid = tattr->guid;
         break;
 
-    case TKIND_COCLASS: {
-        unsigned int i;
-        int type_flags;
+    case TKIND_COCLASS:
+        for (i = 0; i < tattr->cImplTypes; i++)
+        {
+            ITypeInfo_GetImplTypeFlags(tinfo2, i, &flags);
+            if (flags & IMPLTYPEFLAG_FDEFAULT)
+                break;
+        }
 
 
-        for(i = 0; i < tattr->cImplTypes; i++)
-            if(SUCCEEDED(ITypeInfo_GetImplTypeFlags(tinfo2, i, &type_flags)) &&
-               type_flags == (IMPLTYPEFLAG_FSOURCE|IMPLTYPEFLAG_FDEFAULT)) break;
+        if (i == tattr->cImplTypes)
+            i = 0;
 
 
-        if(i < tattr->cImplTypes) {
-            hres = ITypeInfo_GetRefTypeOfImplType(tinfo2, i, &href);
-            if(SUCCEEDED(hres)) hres = get_iface_guid(tinfo2, href, guid);
-        } else hres = E_UNEXPECTED;
+        hres = ITypeInfo_GetRefTypeOfImplType(tinfo2, i, &href);
+        if (SUCCEEDED(hres))
+            hres = get_iface_guid(tinfo2, href, guid);
         break;
         break;
-    }
 
     default:
         ERR("Unexpected typekind %d\n", tattr->typekind);
 
     default:
         ERR("Unexpected typekind %d\n", tattr->typekind);
@@ -6818,7 +6762,7 @@ DispCallFunc(
     VARTYPE* prgvt, VARIANTARG** prgpvarg, VARIANT* pvargResult)
 {
 #ifdef __i386__
     VARTYPE* prgvt, VARIANTARG** prgpvarg, VARIANT* pvargResult)
 {
 #ifdef __i386__
-    int argspos, stack_offset;
+    int argspos = 0, stack_offset;
     void *func;
     UINT i;
     DWORD *args;
     void *func;
     UINT i;
     DWORD *args;
@@ -6836,8 +6780,6 @@ DispCallFunc(
     /* maximum size for an argument is sizeof(VARIANT) */
     args = heap_alloc(sizeof(VARIANT) * cActuals + sizeof(DWORD) * 2 );
 
     /* maximum size for an argument is sizeof(VARIANT) */
     args = heap_alloc(sizeof(VARIANT) * cActuals + sizeof(DWORD) * 2 );
 
-    /* start at 1 in case we need to pass a pointer to the return value as arg 0 */
-    argspos = 1;
     if (pvInstance)
     {
         const FARPROC *vtable = *(FARPROC **)pvInstance;
     if (pvInstance)
     {
         const FARPROC *vtable = *(FARPROC **)pvInstance;
@@ -6846,6 +6788,20 @@ DispCallFunc(
     }
     else func = (void *)oVft;
 
     }
     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];
     for (i = 0; i < cActuals; i++)
     {
         VARIANT *arg = prgpvarg[i];
@@ -6880,40 +6836,24 @@ DispCallFunc(
     switch (vtReturn)
     {
     case VT_EMPTY:
     switch (vtReturn)
     {
     case VT_EMPTY:
-        call_method( func, argspos - 1, args + 1, &stack_offset );
+    case VT_DECIMAL:
+    case VT_VARIANT:
+        call_method( func, argspos, args, &stack_offset );
         break;
     case VT_R4:
         break;
     case VT_R4:
-        V_R4(pvargResult) = call_double_method( func, argspos - 1, args + 1, &stack_offset );
+        V_R4(pvargResult) = call_double_method( func, argspos, args, &stack_offset );
         break;
     case VT_R8:
     case VT_DATE:
         break;
     case VT_R8:
     case VT_DATE:
-        V_R8(pvargResult) = call_double_method( func, argspos - 1, args + 1, &stack_offset );
-        break;
-    case VT_DECIMAL:
-    case VT_VARIANT:
-        if (pvInstance)
-        {
-            args[0] = (DWORD)pvInstance;  /* arg 0 is a pointer to the instance */
-            args[1] = (DWORD)pvargResult; /* arg 1 is a pointer to the result */
-            call_method( func, argspos, args, &stack_offset );
-        }
-        else
-        {
-            args[0] = (DWORD)pvargResult;  /* arg 0 is a pointer to the result */
-            call_method( func, argspos, args, &stack_offset );
-        }
+        V_R8(pvargResult) = call_double_method( func, argspos, args, &stack_offset );
         break;
     case VT_I8:
     case VT_UI8:
     case VT_CY:
         break;
     case VT_I8:
     case VT_UI8:
     case VT_CY:
-        V_UI8(pvargResult) = call_method( func, argspos - 1, args + 1, &stack_offset );
+        V_UI8(pvargResult) = call_method( func, argspos, args, &stack_offset );
         break;
         break;
-    case VT_HRESULT:
-        WARN("invalid return type %u\n", vtReturn);
-        heap_free( args );
-        return E_INVALIDARG;
     default:
     default:
-        V_UI4(pvargResult) = call_method( func, argspos - 1, args + 1, &stack_offset );
+        V_UI4(pvargResult) = call_method( func, argspos, args, &stack_offset );
         break;
     }
     heap_free( args );
         break;
     }
     heap_free( args );
@@ -6927,7 +6867,7 @@ DispCallFunc(
     return S_OK;
 
 #elif defined(__x86_64__)
     return S_OK;
 
 #elif defined(__x86_64__)
-    int argspos;
+    int argspos = 0;
     UINT i;
     DWORD_PTR *args;
     void *func;
     UINT i;
     DWORD_PTR *args;
     void *func;
@@ -6945,8 +6885,6 @@ DispCallFunc(
     /* maximum size for an argument is sizeof(DWORD_PTR) */
     args = heap_alloc( sizeof(DWORD_PTR) * (cActuals + 2) );
 
     /* maximum size for an argument is sizeof(DWORD_PTR) */
     args = heap_alloc( sizeof(DWORD_PTR) * (cActuals + 2) );
 
-    /* start at 1 in case we need to pass a pointer to the return value as arg 0 */
-    argspos = 1;
     if (pvInstance)
     {
         const FARPROC *vtable = *(FARPROC **)pvInstance;
     if (pvInstance)
     {
         const FARPROC *vtable = *(FARPROC **)pvInstance;
@@ -6955,6 +6893,20 @@ DispCallFunc(
     }
     else func = (void *)oVft;
 
     }
     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];
     for (i = 0; i < cActuals; i++)
     {
         VARIANT *arg = prgpvarg[i];
@@ -6978,32 +6930,18 @@ DispCallFunc(
     switch (vtReturn)
     {
     case VT_R4:
     switch (vtReturn)
     {
     case VT_R4:
-        V_R4(pvargResult) = call_double_method( func, argspos - 1, args + 1 );
+        V_R4(pvargResult) = call_double_method( func, argspos, args );
         break;
     case VT_R8:
     case VT_DATE:
         break;
     case VT_R8:
     case VT_DATE:
-        V_R8(pvargResult) = call_double_method( func, argspos - 1, args + 1 );
+        V_R8(pvargResult) = call_double_method( func, argspos, args );
         break;
     case VT_DECIMAL:
     case VT_VARIANT:
         break;
     case VT_DECIMAL:
     case VT_VARIANT:
-        if (pvInstance)
-        {
-            args[0] = (DWORD_PTR)pvInstance;  /* arg 0 is a pointer to the instance */
-            args[1] = (DWORD_PTR)pvargResult; /* arg 1 is a pointer to the result */
-            call_method( func, argspos, args );
-        }
-        else
-        {
-            args[0] = (DWORD_PTR)pvargResult;  /* arg 0 is a pointer to the result */
-            call_method( func, argspos, args );
-        }
+        call_method( func, argspos, args );
         break;
         break;
-    case VT_HRESULT:
-        WARN("invalid return type %u\n", vtReturn);
-        heap_free( args );
-        return E_INVALIDARG;
     default:
     default:
-        V_UI8(pvargResult) = call_method( func, argspos - 1, args + 1 );
+        V_UI8(pvargResult) = call_method( func, argspos, args );
         break;
     }
     heap_free( args );
         break;
     }
     heap_free( args );
@@ -7043,6 +6981,14 @@ DispCallFunc(
     argspos = 0;
     rcount = 0;
 
     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)
     /* 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)
@@ -7058,14 +7004,6 @@ DispCallFunc(
         break;
     }
 
         break;
     }
 
-    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;
-
     /* 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 );
 
     /* 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 );
 
@@ -7912,7 +7850,7 @@ static BOOL CALLBACK search_res_tlb(HMODULE hModule, LPCWSTR lpszType, LPWSTR lp
     if (!(len = GetModuleFileNameW(hModule, szPath, MAX_PATH)))
         return TRUE;
 
     if (!(len = GetModuleFileNameW(hModule, szPath, MAX_PATH)))
         return TRUE;
 
-    if (snprintfW(szPath + len, sizeof(szPath)/sizeof(WCHAR) - len, formatW, LOWORD(lpszName)) < 0)
+    if (snprintfW(szPath + len, ARRAY_SIZE(szPath) - len, formatW, LOWORD(lpszName)) < 0)
         return TRUE;
 
     ret = LoadTypeLibEx(szPath, REGKIND_NONE, &pTLib);
         return TRUE;
 
     ret = LoadTypeLibEx(szPath, REGKIND_NONE, &pTLib);
index bfea174..4ab8055 100644 (file)
@@ -142,11 +142,11 @@ typedef struct tagMSFT_TypeInfoBase {
         INT     helpcontext;    /* */
         INT     oCustData;          /* offset in customer data table */
 #ifdef WORDS_BIGENDIAN
         INT     helpcontext;    /* */
         INT     oCustData;          /* offset in customer data table */
 #ifdef WORDS_BIGENDIAN
-        INT16   cbSizeVft;      /* virtual table size, not including inherits */
+        INT16   cbSizeVft;      /* virtual table size, including inherits */
         INT16   cImplTypes;     /* nr of implemented interfaces */
 #else
         INT16   cImplTypes;     /* nr of implemented interfaces */
         INT16   cImplTypes;     /* nr of implemented interfaces */
 #else
         INT16   cImplTypes;     /* nr of implemented interfaces */
-        INT16   cbSizeVft;      /* virtual table size, not including inherits */
+        INT16   cbSizeVft;      /* virtual table size, including inherits */
 #endif
 /*050*/ INT     size;           /* size in bytes, at least for structures */
         /* FIXME: name of this field */
 #endif
 /*050*/ INT     size;           /* size in bytes, at least for structures */
         /* FIXME: name of this field */
@@ -155,10 +155,8 @@ typedef struct tagMSFT_TypeInfoBase {
                                 /* if coclass: offset in reftable */
                                 /* if interface: reference to inherited if */
                                 /* if module: offset to dllname in name table */
                                 /* if coclass: offset in reftable */
                                 /* if interface: reference to inherited if */
                                 /* if module: offset to dllname in name table */
-        INT     datatype2;      /* if 0x8000, entry above is valid */
-                                /* actually dunno */
-                                /* else it is zero? */
-                                /* if interface: inheritance level | no of inherited funcs */
+        INT     datatype2;      /* for interfaces: hiword is num of inherited funcs */
+                                /*                 loword is num of inherited interfaces */
         INT     res18;          /* always? 0 */
 /*060*/ INT     res19;          /* always? -1 */
 } MSFT_TypeInfoBase;
         INT     res18;          /* always? 0 */
 /*060*/ INT     res19;          /* always? -1 */
 } MSFT_TypeInfoBase;
@@ -281,9 +279,10 @@ typedef struct {
                           to the typeinfo itself or to a member of
                           the typeinfo */
     INT   next_hash;    /* offset to next name in the hash bucket */
                           to the typeinfo itself or to a member of
                           the typeinfo */
     INT   next_hash;    /* offset to next name in the hash bucket */
-    INT   namelen;      /* only lower 8 bits are valid,
-                          lower-middle 8 bits are unknown (flags?),
-                          upper 16 bits are hash code */
+    INT   namelen;      /* only lower 8 bits are valid */
+                        /* 0x1000 if name is only used once as a variable name */
+                        /* 0x2000 if name is a variable in an enumeration */
+                        /* 0x3800 if name is typeinfo name */
 } MSFT_NameIntro;
 /* the custom data table directory has entries like this */
 typedef struct {
 } MSFT_NameIntro;
 /* the custom data table directory has entries like this */
 typedef struct {
@@ -596,12 +595,6 @@ WORD typeofarray
 
 #include "poppack.h"
 
 
 #include "poppack.h"
 
-HRESULT ITypeInfoImpl_GetInternalFuncDesc( ITypeInfo *iface, UINT index, const FUNCDESC **ppFuncDesc ) DECLSPEC_HIDDEN;
-
-extern DWORD _invoke(FARPROC func, CALLCONV callconv, int nrargs, DWORD_PTR *args) DECLSPEC_HIDDEN;
-
-HRESULT TMARSHAL_DllGetClassObject(REFCLSID rclsid, REFIID iid,LPVOID *ppv) DECLSPEC_HIDDEN;
-
 /* The OLE Automation ProxyStub Interface Class (aka Typelib Marshaler) */
 DEFINE_OLEGUID( CLSID_PSDispatch,    0x00020420, 0x0000, 0x0000 );
 DEFINE_OLEGUID( CLSID_PSEnumVariant, 0x00020421, 0x0000, 0x0000 );
 /* The OLE Automation ProxyStub Interface Class (aka Typelib Marshaler) */
 DEFINE_OLEGUID( CLSID_PSDispatch,    0x00020420, 0x0000, 0x0000 );
 DEFINE_OLEGUID( CLSID_PSEnumVariant, 0x00020421, 0x0000, 0x0000 );
index da524c8..163b48f 100644 (file)
@@ -227,6 +227,9 @@ unsigned int get_type_size(ULONG *pFlags, VARTYPE vt)
     case VT_INT:
     case VT_UINT:
         return sizeof(INT);
     case VT_INT:
     case VT_UINT:
         return sizeof(INT);
+    case VT_I8:
+    case VT_UI8:
+        return sizeof(LONGLONG);
     case VT_R4:
         return sizeof(FLOAT);
     case VT_R8:
     case VT_R4:
         return sizeof(FLOAT);
     case VT_R8:
@@ -644,7 +647,8 @@ void WINAPI VARIANT_UserFree(ULONG *pFlags, VARIANT *pvar)
       break;
     case VT_UNKNOWN | VT_BYREF:
     case VT_DISPATCH | VT_BYREF:
       break;
     case VT_UNKNOWN | VT_BYREF:
     case VT_DISPATCH | VT_BYREF:
-      IUnknown_Release(*V_UNKNOWNREF(pvar));
+      if (*V_UNKNOWNREF(pvar))
+        IUnknown_Release(*V_UNKNOWNREF(pvar));
       break;
     }
   }
       break;
     }
   }
index 696763e..470ea4e 100644 (file)
@@ -449,8 +449,7 @@ static inline const BYTE *VARIANT_GetNamedFormat(LPCWSTR lpszFormat)
   LPCNAMED_FORMAT fmt;
 
   key.name = lpszFormat;
   LPCNAMED_FORMAT fmt;
 
   key.name = lpszFormat;
-  fmt = bsearch(&key, VARIANT_NamedFormats,
-                                 sizeof(VARIANT_NamedFormats)/sizeof(NAMED_FORMAT),
+  fmt = bsearch(&key, VARIANT_NamedFormats, ARRAY_SIZE(VARIANT_NamedFormats),
                                  sizeof(NAMED_FORMAT), FormatCompareFn);
   return fmt ? fmt->format : NULL;
 }
                                  sizeof(NAMED_FORMAT), FormatCompareFn);
   return fmt ? fmt->format : NULL;
 }
@@ -764,7 +763,7 @@ HRESULT WINAPI VarTokenizeFormatString(LPOLESTR lpszFormat, LPBYTE rgbTok,
       TRACE("time sep\n");
     }
     else if ((*pFormat == 'a' || *pFormat == 'A') &&
       TRACE("time sep\n");
     }
     else if ((*pFormat == 'a' || *pFormat == 'A') &&
-              !strncmpiW(pFormat, szAMPM, sizeof(szAMPM)/sizeof(WCHAR)))
+              !strncmpiW(pFormat, szAMPM, ARRAY_SIZE(szAMPM)))
     {
       /* Date formats: System AM/PM designation
        * Other formats: Literal
     {
       /* Date formats: System AM/PM designation
        * Other formats: Literal
@@ -772,8 +771,8 @@ HRESULT WINAPI VarTokenizeFormatString(LPOLESTR lpszFormat, LPBYTE rgbTok,
        */
       header->type = FMT_TYPE_DATE;
       NEED_SPACE(sizeof(BYTE));
        */
       header->type = FMT_TYPE_DATE;
       NEED_SPACE(sizeof(BYTE));
-      pFormat += sizeof(szAMPM)/sizeof(WCHAR);
-      if (!strncmpW(pFormat, szampm, sizeof(szampm)/sizeof(WCHAR)))
+      pFormat += ARRAY_SIZE(szAMPM);
+      if (!strncmpW(pFormat, szampm, ARRAY_SIZE(szampm)))
         *pOut++ = FMT_DATE_AMPM_SYS2;
       else
         *pOut++ = FMT_DATE_AMPM_SYS1;
         *pOut++ = FMT_DATE_AMPM_SYS2;
       else
         *pOut++ = FMT_DATE_AMPM_SYS1;
@@ -811,8 +810,7 @@ HRESULT WINAPI VarTokenizeFormatString(LPOLESTR lpszFormat, LPBYTE rgbTok,
         *pLastHours = *pLastHours + 2;
       TRACE("A/P\n");
     }
         *pLastHours = *pLastHours + 2;
       TRACE("A/P\n");
     }
-    else if (*pFormat == 'a' &&
-              !strncmpW(pFormat, szamSlashpm, sizeof(szamSlashpm)/sizeof(WCHAR)))
+    else if (*pFormat == 'a' && !strncmpW(pFormat, szamSlashpm, ARRAY_SIZE(szamSlashpm)))
     {
       /* Date formats: lowercase AM or PM designation
        * Other formats: Literal
     {
       /* Date formats: lowercase AM or PM designation
        * Other formats: Literal
@@ -820,14 +818,13 @@ HRESULT WINAPI VarTokenizeFormatString(LPOLESTR lpszFormat, LPBYTE rgbTok,
        */
       header->type = FMT_TYPE_DATE;
       NEED_SPACE(sizeof(BYTE));
        */
       header->type = FMT_TYPE_DATE;
       NEED_SPACE(sizeof(BYTE));
-      pFormat += sizeof(szamSlashpm)/sizeof(WCHAR);
+      pFormat += ARRAY_SIZE(szamSlashpm);
       *pOut++ = FMT_DATE_AMPM_LOWER;
       if (pLastHours)
         *pLastHours = *pLastHours + 2;
       TRACE("AM/PM\n");
     }
       *pOut++ = FMT_DATE_AMPM_LOWER;
       if (pLastHours)
         *pLastHours = *pLastHours + 2;
       TRACE("AM/PM\n");
     }
-    else if (*pFormat == 'A' &&
-              !strncmpW(pFormat, szAMSlashPM, sizeof(szAMSlashPM)/sizeof(WCHAR)))
+    else if (*pFormat == 'A' && !strncmpW(pFormat, szAMSlashPM, ARRAY_SIZE(szAMSlashPM)))
     {
       /* Date formats: Uppercase AM or PM designation
        * Other formats: Literal
     {
       /* Date formats: Uppercase AM or PM designation
        * Other formats: Literal
@@ -835,7 +832,7 @@ HRESULT WINAPI VarTokenizeFormatString(LPOLESTR lpszFormat, LPBYTE rgbTok,
        */
       header->type = FMT_TYPE_DATE;
       NEED_SPACE(sizeof(BYTE));
        */
       header->type = FMT_TYPE_DATE;
       NEED_SPACE(sizeof(BYTE));
-      pFormat += sizeof(szAMSlashPM)/sizeof(WCHAR);
+      pFormat += ARRAY_SIZE(szAMSlashPM);
       *pOut++ = FMT_DATE_AMPM_UPPER;
       TRACE("AM/PM\n");
     }
       *pOut++ = FMT_DATE_AMPM_UPPER;
       TRACE("AM/PM\n");
     }
@@ -847,7 +844,7 @@ HRESULT WINAPI VarTokenizeFormatString(LPOLESTR lpszFormat, LPBYTE rgbTok,
        */
       header->type = FMT_TYPE_DATE;
       NEED_SPACE(sizeof(BYTE));
        */
       header->type = FMT_TYPE_DATE;
       NEED_SPACE(sizeof(BYTE));
-      pFormat += sizeof(szAMSlashPM)/sizeof(WCHAR);
+      pFormat += ARRAY_SIZE(szAMSlashPM);
       *pOut++ = FMT_DATE_GENERAL;
       TRACE("gen date\n");
     }
       *pOut++ = FMT_DATE_GENERAL;
       TRACE("gen date\n");
     }
@@ -989,14 +986,14 @@ HRESULT WINAPI VarTokenizeFormatString(LPOLESTR lpszFormat, LPBYTE rgbTok,
       fmt_state &= ~FMT_STATE_OPEN_COPY;
     }
     else if ((*pFormat == 't' || *pFormat == 'T') &&
       fmt_state &= ~FMT_STATE_OPEN_COPY;
     }
     else if ((*pFormat == 't' || *pFormat == 'T') &&
-              !strncmpiW(pFormat, szTTTTT, sizeof(szTTTTT)/sizeof(WCHAR)))
+              !strncmpiW(pFormat, szTTTTT, ARRAY_SIZE(szTTTTT)))
     {
       /* Date formats: System time specifier
        * Other formats: Literal
        * Types the format if found
        */
       header->type = FMT_TYPE_DATE;
     {
       /* Date formats: System time specifier
        * Other formats: Literal
        * Types the format if found
        */
       header->type = FMT_TYPE_DATE;
-      pFormat += sizeof(szTTTTT)/sizeof(WCHAR);
+      pFormat += ARRAY_SIZE(szTTTTT);
       NEED_SPACE(sizeof(BYTE));
       *pOut++ = FMT_DATE_TIME_SYS;
       fmt_state &= ~FMT_STATE_OPEN_COPY;
       NEED_SPACE(sizeof(BYTE));
       *pOut++ = FMT_DATE_TIME_SYS;
       fmt_state &= ~FMT_STATE_OPEN_COPY;
@@ -1316,8 +1313,7 @@ static HRESULT VARIANT_FormatNumber(LPVARIANT pVarIn, LPOLESTR lpszFormat,
 
   if (numHeader->flags & FMT_FLAG_THOUSANDS)
   {
 
   if (numHeader->flags & FMT_FLAG_THOUSANDS)
   {
-    if (!GetLocaleInfoW(lcid, LOCALE_STHOUSAND, thousandSeparator,
-                        sizeof(thousandSeparator)/sizeof(WCHAR)))
+    if (!GetLocaleInfoW(lcid, LOCALE_STHOUSAND, thousandSeparator, ARRAY_SIZE(thousandSeparator)))
     {
       thousandSeparator[0] = ',';
       thousandSeparator[1] = 0;
     {
       thousandSeparator[0] = ',';
       thousandSeparator[1] = 0;
@@ -1555,8 +1551,7 @@ VARIANT_FormatNumber_Bool:
     }
     if (localeValue)
     {
     }
     if (localeValue)
     {
-      if (GetLocaleInfoW(lcid, localeValue, pBuff, 
-                         sizeof(buff)/sizeof(WCHAR)-(pBuff-buff)))
+      if (GetLocaleInfoW(lcid, localeValue, pBuff, ARRAY_SIZE(buff)-(pBuff-buff)))
       {
         TRACE("added %s\n", debugstr_w(pBuff));
         while (*pBuff)
       {
         TRACE("added %s\n", debugstr_w(pBuff));
         while (*pBuff)
@@ -1875,8 +1870,7 @@ static HRESULT VARIANT_FormatDate(LPVARIANT pVarIn, LPOLESTR lpszFormat,
     if (localeValue)
     {
       *pBuff = '\0';
     if (localeValue)
     {
       *pBuff = '\0';
-      if (GetLocaleInfoW(lcid, localeValue, pBuff,
-          sizeof(buff)/sizeof(WCHAR)-(pBuff-buff)))
+      if (GetLocaleInfoW(lcid, localeValue, pBuff, ARRAY_SIZE(buff)-(pBuff-buff)))
       {
         TRACE("added %s\n", debugstr_w(pBuff));
         while (*pBuff)
       {
         TRACE("added %s\n", debugstr_w(pBuff));
         while (*pBuff)
@@ -1892,9 +1886,8 @@ static HRESULT VARIANT_FormatDate(LPVARIANT pVarIn, LPOLESTR lpszFormat,
     {
       WCHAR fmt_buff[80];
 
     {
       WCHAR fmt_buff[80];
 
-      if (!GetLocaleInfoW(lcid, dwFmt, fmt_buff, sizeof(fmt_buff)/sizeof(WCHAR)) ||
-          !get_date_format(lcid, 0, &udate.st, fmt_buff, pBuff,
-                          sizeof(buff)/sizeof(WCHAR)-(pBuff-buff)))
+      if (!GetLocaleInfoW(lcid, dwFmt, fmt_buff, ARRAY_SIZE(fmt_buff)) ||
+          !get_date_format(lcid, 0, &udate.st, fmt_buff, pBuff, ARRAY_SIZE(buff)-(pBuff-buff)))
       {
         hRes = E_INVALIDARG;
         goto VARIANT_FormatDate_Exit;
       {
         hRes = E_INVALIDARG;
         goto VARIANT_FormatDate_Exit;
@@ -2293,8 +2286,7 @@ HRESULT WINAPI VarFormatNumber(LPVARIANT pVarIn, INT nDigits, INT nLeading, INT
     {
       WCHAR grouping[16];
       grouping[2] = '\0';
     {
       WCHAR grouping[16];
       grouping[2] = '\0';
-      GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SDECIMAL, grouping,
-                     sizeof(grouping)/sizeof(WCHAR));
+      GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SDECIMAL, grouping, ARRAY_SIZE(grouping));
       numfmt.Grouping = grouping[2] == '2' ? 32 : grouping[0] - '0';
     }
     else if (nGrouping == -1)
       numfmt.Grouping = grouping[2] == '2' ? 32 : grouping[0] - '0';
     }
     else if (nGrouping == -1)
@@ -2310,14 +2302,11 @@ HRESULT WINAPI VarFormatNumber(LPVARIANT pVarIn, INT nDigits, INT nLeading, INT
       numfmt.NegativeOrder = 1; /* 1 = "-xxx" */
 
     numfmt.lpDecimalSep = decimal;
       numfmt.NegativeOrder = 1; /* 1 = "-xxx" */
 
     numfmt.lpDecimalSep = decimal;
-    GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SDECIMAL, decimal,
-                   sizeof(decimal)/sizeof(WCHAR));
+    GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SDECIMAL, decimal, ARRAY_SIZE(decimal));
     numfmt.lpThousandSep = thousands;
     numfmt.lpThousandSep = thousands;
-    GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_STHOUSAND, thousands,
-                   sizeof(thousands)/sizeof(WCHAR));
+    GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_STHOUSAND, thousands, ARRAY_SIZE(thousands));
 
 
-    if (GetNumberFormatW(LOCALE_USER_DEFAULT, 0, V_BSTR(&vStr), &numfmt,
-                         buff, sizeof(buff)/sizeof(WCHAR)))
+    if (GetNumberFormatW(LOCALE_USER_DEFAULT, 0, V_BSTR(&vStr), &numfmt, buff, ARRAY_SIZE(buff)))
     {
       *pbstrOut = SysAllocString(buff);
       if (!*pbstrOut)
     {
       *pbstrOut = SysAllocString(buff);
       if (!*pbstrOut)
@@ -2473,8 +2462,7 @@ HRESULT WINAPI VarFormatCurrency(LPVARIANT pVarIn, INT nDigits, INT nLeading,
     {
       WCHAR grouping[16];
       grouping[2] = '\0';
     {
       WCHAR grouping[16];
       grouping[2] = '\0';
-      GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SDECIMAL, grouping,
-                     sizeof(grouping)/sizeof(WCHAR));
+      GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SDECIMAL, grouping, ARRAY_SIZE(grouping));
       numfmt.Grouping = grouping[2] == '2' ? 32 : grouping[0] - '0';
     }
     else if (nGrouping == -1)
       numfmt.Grouping = grouping[2] == '2' ? 32 : grouping[0] - '0';
     }
     else if (nGrouping == -1)
@@ -2492,18 +2480,14 @@ HRESULT WINAPI VarFormatCurrency(LPVARIANT pVarIn, INT nDigits, INT nLeading,
     GETLOCALENUMBER(LOCALE_ICURRENCY, PositiveOrder);
 
     numfmt.lpDecimalSep = decimal;
     GETLOCALENUMBER(LOCALE_ICURRENCY, PositiveOrder);
 
     numfmt.lpDecimalSep = decimal;
-    GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SDECIMAL, decimal,
-                   sizeof(decimal)/sizeof(WCHAR));
+    GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SDECIMAL, decimal, ARRAY_SIZE(decimal));
     numfmt.lpThousandSep = thousands;
     numfmt.lpThousandSep = thousands;
-    GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SDECIMAL, thousands,
-                   sizeof(thousands)/sizeof(WCHAR));
+    GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SDECIMAL, thousands, ARRAY_SIZE(thousands));
     numfmt.lpCurrencySymbol = currency;
     numfmt.lpCurrencySymbol = currency;
-    GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SDECIMAL, currency,
-                   sizeof(currency)/sizeof(WCHAR));
+    GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SDECIMAL, currency, ARRAY_SIZE(currency));
 
     /* use NLS as per VarFormatNumber() */
 
     /* use NLS as per VarFormatNumber() */
-    if (GetCurrencyFormatW(LOCALE_USER_DEFAULT, 0, V_BSTR(&vStr), &numfmt,
-                           buff, sizeof(buff)/sizeof(WCHAR)))
+    if (GetCurrencyFormatW(LOCALE_USER_DEFAULT, 0, V_BSTR(&vStr), &numfmt, buff, ARRAY_SIZE(buff)))
     {
       *pbstrOut = SysAllocString(buff);
       if (!*pbstrOut)
     {
       *pbstrOut = SysAllocString(buff);
       if (!*pbstrOut)
index b9cf4b0..fcbef53 100644 (file)
@@ -648,7 +648,7 @@ HRESULT VARIANT_ClearInd(VARIANTARG *pVarg)
  *  Success: S_OK. Any previous value in pVarg is freed and its type is set to VT_EMPTY.
  *  Failure: DISP_E_BADVARTYPE, if the variant is not a valid variant type.
  */
  *  Success: S_OK. Any previous value in pVarg is freed and its type is set to VT_EMPTY.
  *  Failure: DISP_E_BADVARTYPE, if the variant is not a valid variant type.
  */
-HRESULT WINAPI VariantClear(VARIANTARG* pVarg)
+HRESULT WINAPI DECLSPEC_HOTPATCH VariantClear(VARIANTARG* pVarg)
 {
   HRESULT hres;
 
 {
   HRESULT hres;
 
@@ -962,8 +962,8 @@ VariantCopyInd_Return:
  *  The LCID used for the conversion is LOCALE_USER_DEFAULT.
  *  See VariantChangeTypeEx.
  */
  *  The LCID used for the conversion is LOCALE_USER_DEFAULT.
  *  See VariantChangeTypeEx.
  */
-HRESULT WINAPI VariantChangeType(VARIANTARG* pvargDest, VARIANTARG* pvargSrc,
-                                 USHORT wFlags, VARTYPE vt)
+HRESULT WINAPI DECLSPEC_HOTPATCH VariantChangeType(VARIANTARG* pvargDest, VARIANTARG* pvargSrc,
+                                                   USHORT wFlags, VARTYPE vt)
 {
   return VariantChangeTypeEx( pvargDest, pvargSrc, LOCALE_USER_DEFAULT, wFlags, vt );
 }
 {
   return VariantChangeTypeEx( pvargDest, pvargSrc, LOCALE_USER_DEFAULT, wFlags, vt );
 }
@@ -1549,7 +1549,7 @@ static void VARIANT_GetLocalisedNumberChars(VARIANT_NUMBER_CHARS *lpChars, LCID
 
   /* Local currency symbols are often 2 characters */
   lpChars->cCurrencyLocal2 = '\0';
 
   /* Local currency symbols are often 2 characters */
   lpChars->cCurrencyLocal2 = '\0';
-  switch(GetLocaleInfoW(lcid, lctype|LOCALE_SCURRENCY, buff, sizeof(buff)/sizeof(WCHAR)))
+  switch(GetLocaleInfoW(lcid, lctype|LOCALE_SCURRENCY, buff, ARRAY_SIZE(buff)))
   {
     case 3: lpChars->cCurrencyLocal2 = buff[1]; /* Fall through */
     case 2: lpChars->cCurrencyLocal  = buff[0];
   {
     case 3: lpChars->cCurrencyLocal2 = buff[1]; /* Fall through */
     case 2: lpChars->cCurrencyLocal  = buff[0];
@@ -1610,7 +1610,7 @@ HRESULT WINAPI VarParseNumFromStr(OLECHAR *lpszStr, LCID lcid, ULONG dwFlags,
   VARIANT_NUMBER_CHARS chars;
   BYTE rgbTmp[1024];
   DWORD dwState = B_EXPONENT_START|B_INEXACT_ZEROS;
   VARIANT_NUMBER_CHARS chars;
   BYTE rgbTmp[1024];
   DWORD dwState = B_EXPONENT_START|B_INEXACT_ZEROS;
-  int iMaxDigits = sizeof(rgbTmp) / sizeof(BYTE);
+  int iMaxDigits = ARRAY_SIZE(rgbTmp);
   int cchUsed = 0;
 
   TRACE("(%s,%d,0x%08x,%p,%p)\n", debugstr_w(lpszStr), lcid, dwFlags, pNumprs, rgbDig);
   int cchUsed = 0;
 
   TRACE("(%s,%d,0x%08x,%p,%p)\n", debugstr_w(lpszStr), lcid, dwFlags, pNumprs, rgbDig);
@@ -5134,7 +5134,21 @@ HRESULT WINAPI VarRound(LPVARIANT pVarIn, int deci, LPVARIANT pVarOut)
        }
        V_VT(pVarOut) = V_VT(pVarIn);
        break;
        }
        V_VT(pVarOut) = V_VT(pVarIn);
        break;
+    case VT_DECIMAL:
+    {
+        double dbl;
 
 
+        VarR8FromDec(&V_DECIMAL(pVarIn), &dbl);
+
+        if (dbl>0.0f)
+            dbl = floor(dbl*pow(10,deci)+0.5);
+        else
+            dbl = ceil(dbl*pow(10,deci)-0.5);
+
+        V_VT(pVarOut)=VT_DECIMAL;
+        VarDecFromR8(dbl, &V_DECIMAL(pVarOut));
+        break;
+    }
     /* cases we don't know yet */
     default:
        FIXME("unimplemented part, V_VT(pVarIn) == 0x%X, deci == %d\n",
     /* cases we don't know yet */
     default:
        FIXME("unimplemented part, V_VT(pVarIn) == 0x%X, deci == %d\n",
index 9e271be..067d515 100644 (file)
@@ -95,7 +95,7 @@ static HRESULT VARIANT_NumberFromBstr(OLECHAR* pStrIn, LCID lcid, ULONG ulFlags,
   BYTE rgb[1024];
 
   /* Use VarParseNumFromStr/VarNumFromParseNum as MSDN indicates */
   BYTE rgb[1024];
 
   /* Use VarParseNumFromStr/VarNumFromParseNum as MSDN indicates */
-  np.cDig = sizeof(rgb) / sizeof(BYTE);
+  np.cDig = ARRAY_SIZE(rgb);
   np.dwInFlags = NUMPRS_STD;
 
   hRet = VarParseNumFromStr(pStrIn, lcid, ulFlags, &np, rgb);
   np.dwInFlags = NUMPRS_STD;
 
   hRet = VarParseNumFromStr(pStrIn, lcid, ulFlags, &np, rgb);
@@ -3781,7 +3781,7 @@ HRESULT WINAPI VarCyFromUI8(ULONG64 ullIn, CY* pCyOut)
  *  Success: S_OK.
  *  Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
  */
  *  Success: S_OK.
  *  Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
  */
-HRESULT WINAPI VarCyAdd(const CY cyLeft, const CY cyRight, CY* pCyOut)
+HRESULT WINAPI VarCyAdd(CY cyLeft, CY cyRight, CY* pCyOut)
 {
   double l,r;
   _VarR8FromCy(cyLeft, &l);
 {
   double l,r;
   _VarR8FromCy(cyLeft, &l);
@@ -3804,7 +3804,7 @@ HRESULT WINAPI VarCyAdd(const CY cyLeft, const CY cyRight, CY* pCyOut)
  *  Success: S_OK.
  *  Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
  */
  *  Success: S_OK.
  *  Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
  */
-HRESULT WINAPI VarCyMul(const CY cyLeft, CY cyRight, CY* pCyOut)
+HRESULT WINAPI VarCyMul(CY cyLeft, CY cyRight, CY* pCyOut)
 {
   double l,r;
   _VarR8FromCy(cyLeft, &l);
 {
   double l,r;
   _VarR8FromCy(cyLeft, &l);
@@ -3827,7 +3827,7 @@ HRESULT WINAPI VarCyMul(const CY cyLeft, CY cyRight, CY* pCyOut)
  *  Success: S_OK.
  *  Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
  */
  *  Success: S_OK.
  *  Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
  */
-HRESULT WINAPI VarCyMulI4(const CY cyLeft, LONG lRight, CY* pCyOut)
+HRESULT WINAPI VarCyMulI4(CY cyLeft, LONG lRight, CY* pCyOut)
 {
   double d;
 
 {
   double d;
 
@@ -3850,7 +3850,7 @@ HRESULT WINAPI VarCyMulI4(const CY cyLeft, LONG lRight, CY* pCyOut)
  *  Success: S_OK.
  *  Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
  */
  *  Success: S_OK.
  *  Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
  */
-HRESULT WINAPI VarCySub(const CY cyLeft, const CY cyRight, CY* pCyOut)
+HRESULT WINAPI VarCySub(CY cyLeft, CY cyRight, CY* pCyOut)
 {
   double l,r;
   _VarR8FromCy(cyLeft, &l);
 {
   double l,r;
   _VarR8FromCy(cyLeft, &l);
@@ -3872,7 +3872,7 @@ HRESULT WINAPI VarCySub(const CY cyLeft, const CY cyRight, CY* pCyOut)
  *  Success: S_OK. pCyOut contains the absolute value.
  *  Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
  */
  *  Success: S_OK. pCyOut contains the absolute value.
  *  Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
  */
-HRESULT WINAPI VarCyAbs(const CY cyIn, CY* pCyOut)
+HRESULT WINAPI VarCyAbs(CY cyIn, CY* pCyOut)
 {
   if (cyIn.s.Hi == (int)0x80000000 && !cyIn.s.Lo)
     return DISP_E_OVERFLOW;
 {
   if (cyIn.s.Hi == (int)0x80000000 && !cyIn.s.Lo)
     return DISP_E_OVERFLOW;
@@ -3898,7 +3898,7 @@ HRESULT WINAPI VarCyAbs(const CY cyIn, CY* pCyOut)
  *  - The difference between this function and VarCyInt() is that VarCyInt() rounds
  *    negative numbers away from 0, while this function rounds them towards zero.
  */
  *  - The difference between this function and VarCyInt() is that VarCyInt() rounds
  *    negative numbers away from 0, while this function rounds them towards zero.
  */
-HRESULT WINAPI VarCyFix(const CY cyIn, CY* pCyOut)
+HRESULT WINAPI VarCyFix(CY cyIn, CY* pCyOut)
 {
   pCyOut->int64 = cyIn.int64 / CY_MULTIPLIER;
   pCyOut->int64 *= CY_MULTIPLIER;
 {
   pCyOut->int64 = cyIn.int64 / CY_MULTIPLIER;
   pCyOut->int64 *= CY_MULTIPLIER;
@@ -3922,7 +3922,7 @@ HRESULT WINAPI VarCyFix(const CY cyIn, CY* pCyOut)
  *  - The difference between this function and VarCyFix() is that VarCyFix() rounds
  *    negative numbers towards 0, while this function rounds them away from zero.
  */
  *  - The difference between this function and VarCyFix() is that VarCyFix() rounds
  *    negative numbers towards 0, while this function rounds them away from zero.
  */
-HRESULT WINAPI VarCyInt(const CY cyIn, CY* pCyOut)
+HRESULT WINAPI VarCyInt(CY cyIn, CY* pCyOut)
 {
   pCyOut->int64 = cyIn.int64 / CY_MULTIPLIER;
   pCyOut->int64 *= CY_MULTIPLIER;
 {
   pCyOut->int64 = cyIn.int64 / CY_MULTIPLIER;
   pCyOut->int64 *= CY_MULTIPLIER;
@@ -3947,7 +3947,7 @@ HRESULT WINAPI VarCyInt(const CY cyIn, CY* pCyOut)
  *  Success: S_OK.
  *  Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
  */
  *  Success: S_OK.
  *  Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
  */
-HRESULT WINAPI VarCyNeg(const CY cyIn, CY* pCyOut)
+HRESULT WINAPI VarCyNeg(CY cyIn, CY* pCyOut)
 {
   if (cyIn.s.Hi == (int)0x80000000 && !cyIn.s.Lo)
     return DISP_E_OVERFLOW;
 {
   if (cyIn.s.Hi == (int)0x80000000 && !cyIn.s.Lo)
     return DISP_E_OVERFLOW;
@@ -3970,7 +3970,7 @@ HRESULT WINAPI VarCyNeg(const CY cyIn, CY* pCyOut)
  *  Success: S_OK.
  *  Failure: E_INVALIDARG, if cDecimals is less than 0.
  */
  *  Success: S_OK.
  *  Failure: E_INVALIDARG, if cDecimals is less than 0.
  */
-HRESULT WINAPI VarCyRound(const CY cyIn, int cDecimals, CY* pCyOut)
+HRESULT WINAPI VarCyRound(CY cyIn, int cDecimals, CY* pCyOut)
 {
   if (cDecimals < 0)
     return E_INVALIDARG;
 {
   if (cDecimals < 0)
     return E_INVALIDARG;
@@ -4008,7 +4008,7 @@ HRESULT WINAPI VarCyRound(const CY cyIn, int cDecimals, CY* pCyOut)
  *           compare is less, equal or greater than source respectively.
  *  Failure: DISP_E_OVERFLOW, if overflow occurs during the comparison
  */
  *           compare is less, equal or greater than source respectively.
  *  Failure: DISP_E_OVERFLOW, if overflow occurs during the comparison
  */
-HRESULT WINAPI VarCyCmp(const CY cyLeft, const CY cyRight)
+HRESULT WINAPI VarCyCmp(CY cyLeft, CY cyRight)
 {
   HRESULT hRet;
   CY result;
 {
   HRESULT hRet;
   CY result;
@@ -4042,7 +4042,7 @@ HRESULT WINAPI VarCyCmp(const CY cyLeft, const CY cyRight)
  *           less than, equal to or greater than cyLeft respectively.
  *  Failure: DISP_E_OVERFLOW, if overflow occurs during the comparison
  */
  *           less than, equal to or greater than cyLeft respectively.
  *  Failure: DISP_E_OVERFLOW, if overflow occurs during the comparison
  */
-HRESULT WINAPI VarCyCmpR8(const CY cyLeft, double dblRight)
+HRESULT WINAPI VarCyCmpR8(CY cyLeft, double dblRight)
 {
   HRESULT hRet;
   CY cyRight;
 {
   HRESULT hRet;
   CY cyRight;
@@ -4069,7 +4069,7 @@ HRESULT WINAPI VarCyCmpR8(const CY cyLeft, double dblRight)
  *  Success: S_OK.
  *  Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
  */
  *  Success: S_OK.
  *  Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
  */
-HRESULT WINAPI VarCyMulI8(const CY cyLeft, LONG64 llRight, CY* pCyOut)
+HRESULT WINAPI VarCyMulI8(CY cyLeft, LONG64 llRight, CY* pCyOut)
 {
   double d;
 
 {
   double d;
 
@@ -4496,15 +4496,15 @@ static HRESULT VARIANT_DecScale(const DECIMAL** ppDecLeft,
 
   di.scale -= i;
   remainder = 0;
 
   di.scale -= i;
   remainder = 0;
-  while (i-- > 0 && !VARIANT_int_iszero(di.bitsnum, sizeof(di.bitsnum)/sizeof(DWORD)))
+  while (i-- > 0 && !VARIANT_int_iszero(di.bitsnum, ARRAY_SIZE(di.bitsnum)))
   {
   {
-    remainder = VARIANT_int_divbychar(di.bitsnum, sizeof(di.bitsnum)/sizeof(DWORD), 10);
+    remainder = VARIANT_int_divbychar(di.bitsnum, ARRAY_SIZE(di.bitsnum), 10);
     if (remainder > 0) WARN("losing significant digits (remainder %u)...\n", remainder);
   }
 
   /* round up the result - native oleaut32 does this */
   if (remainder >= 5) {
     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++) {
+      for (remainder = 1, i = 0; i < ARRAY_SIZE(di.bitsnum) && remainder; i++) {
           ULONGLONG digit = di.bitsnum[i] + 1;
           remainder = (digit > 0xFFFFFFFF) ? 1 : 0;
           di.bitsnum[i] = digit & 0xFFFFFFFF;
           ULONGLONG digit = di.bitsnum[i] + 1;
           remainder = (digit > 0xFFFFFFFF) ? 1 : 0;
           di.bitsnum[i] = digit & 0xFFFFFFFF;
@@ -4743,7 +4743,7 @@ static int VARIANT_DI_mul(const VARIANT_DI * a, const VARIANT_DI * b, VARIANT_DI
     memset(running, 0, sizeof(running));
 
     /* count number of leading zero-bytes in operand A */
     memset(running, 0, sizeof(running));
 
     /* count number of leading zero-bytes in operand A */
-    for (mulstart = sizeof(a->bitsnum)/sizeof(DWORD) - 1; mulstart >= 0 && !a->bitsnum[mulstart]; mulstart--);
+    for (mulstart = ARRAY_SIZE(a->bitsnum) - 1; mulstart >= 0 && !a->bitsnum[mulstart]; mulstart--);
     if (mulstart < 0) {
         /* result is 0, because operand A is 0 */
         result->scale = 0;
     if (mulstart < 0) {
         /* result is 0, because operand A is 0 */
         result->scale = 0;
@@ -4757,7 +4757,7 @@ static int VARIANT_DI_mul(const VARIANT_DI * a, const VARIANT_DI * b, VARIANT_DI
             ULONG iOverflowMul;
             int iB;
             
             ULONG iOverflowMul;
             int iB;
             
-            for (iOverflowMul = 0, iB = 0; iB < sizeof(b->bitsnum)/sizeof(DWORD); iB++) {
+            for (iOverflowMul = 0, iB = 0; iB < ARRAY_SIZE(b->bitsnum); iB++) {
                 ULONG iRV;
                 int iR;
                 
                 ULONG iRV;
                 int iR;
                 
@@ -4789,11 +4789,10 @@ static int VARIANT_DI_mul(const VARIANT_DI * a, const VARIANT_DI * b, VARIANT_DI
            This operation *will* lose significant digits of the result because
            all the factors of 10 were consumed by the previous operation.
         */
            This operation *will* lose significant digits of the result because
            all the factors of 10 were consumed by the previous operation.
         */
-        while (result->scale > 0 && !VARIANT_int_iszero(
-            running + sizeof(result->bitsnum) / sizeof(DWORD),
-            (sizeof(running) - sizeof(result->bitsnum)) / sizeof(DWORD))) {
-            
-            remainder = VARIANT_int_divbychar(running, sizeof(running) / sizeof(DWORD), 10);
+        while (result->scale > 0 && !VARIANT_int_iszero(running + ARRAY_SIZE(result->bitsnum),
+            ARRAY_SIZE(running) - ARRAY_SIZE(result->bitsnum))) {
+
+            remainder = VARIANT_int_divbychar(running, ARRAY_SIZE(running), 10);
             if (remainder > 0) WARN("losing significant digits (remainder %u)...\n", remainder);
             result->scale--;
         }
             if (remainder > 0) WARN("losing significant digits (remainder %u)...\n", remainder);
             result->scale--;
         }
@@ -4801,7 +4800,7 @@ static int VARIANT_DI_mul(const VARIANT_DI * a, const VARIANT_DI * b, VARIANT_DI
         /* round up the result - native oleaut32 does this */
         if (remainder >= 5) {
             unsigned int i;
         /* round up the result - native oleaut32 does this */
         if (remainder >= 5) {
             unsigned int i;
-            for (remainder = 1, i = 0; i < sizeof(running)/sizeof(DWORD) && remainder; i++) {
+            for (remainder = 1, i = 0; i < ARRAY_SIZE(running) && remainder; i++) {
                 ULONGLONG digit = running[i] + 1;
                 remainder = (digit > 0xFFFFFFFF) ? 1 : 0;
                 running[i] = digit & 0xFFFFFFFF;
                 ULONGLONG digit = running[i] + 1;
                 remainder = (digit > 0xFFFFFFFF) ? 1 : 0;
                 running[i] = digit & 0xFFFFFFFF;
@@ -4811,9 +4810,8 @@ static int VARIANT_DI_mul(const VARIANT_DI * a, const VARIANT_DI * b, VARIANT_DI
         /* Signal overflow if scale == 0 and 256-bit result still overflows,
            and copy result bits into result structure
         */
         /* Signal overflow if scale == 0 and 256-bit result still overflows,
            and copy result bits into result structure
         */
-        r_overflow = !VARIANT_int_iszero(
-            running + sizeof(result->bitsnum)/sizeof(DWORD), 
-            (sizeof(running) - sizeof(result->bitsnum))/sizeof(DWORD));
+        r_overflow = !VARIANT_int_iszero(running + ARRAY_SIZE(result->bitsnum),
+            ARRAY_SIZE(running) - ARRAY_SIZE(result->bitsnum));
         memcpy(result->bitsnum, running, sizeof(result->bitsnum));
     }
     return r_overflow;
         memcpy(result->bitsnum, running, sizeof(result->bitsnum));
     }
     return r_overflow;
@@ -4831,7 +4829,7 @@ static BOOL VARIANT_DI_tostringW(const VARIANT_DI * a, WCHAR * s, unsigned int n
     unsigned int i;
 
     /* place negative sign */
     unsigned int i;
 
     /* place negative sign */
-    if (!VARIANT_int_iszero(a->bitsnum, sizeof(a->bitsnum) / sizeof(DWORD)) && a->sign) {
+    if (!VARIANT_int_iszero(a->bitsnum, ARRAY_SIZE(a->bitsnum)) && a->sign) {
         if (n > 0) {
             *s++ = '-';
             n--;
         if (n > 0) {
             *s++ = '-';
             n--;
@@ -4849,8 +4847,8 @@ static BOOL VARIANT_DI_tostringW(const VARIANT_DI * a, WCHAR * s, unsigned int n
 
     i = 0;
     memcpy(quotient, a->bitsnum, sizeof(a->bitsnum));
 
     i = 0;
     memcpy(quotient, a->bitsnum, sizeof(a->bitsnum));
-    while (!overflow && !VARIANT_int_iszero(quotient, sizeof(quotient) / sizeof(DWORD))) {
-        remainder = VARIANT_int_divbychar(quotient, sizeof(quotient) / sizeof(DWORD), 10);
+    while (!overflow && !VARIANT_int_iszero(quotient, ARRAY_SIZE(quotient))) {
+        remainder = VARIANT_int_divbychar(quotient, ARRAY_SIZE(quotient), 10);
         if (i + 2 > n) {
             overflow = TRUE;
         } else {
         if (i + 2 > n) {
             overflow = TRUE;
         } else {
@@ -4859,7 +4857,7 @@ static BOOL VARIANT_DI_tostringW(const VARIANT_DI * a, WCHAR * s, unsigned int n
         }
     }
 
         }
     }
 
-    if (!overflow && !VARIANT_int_iszero(a->bitsnum, sizeof(a->bitsnum) / sizeof(DWORD))) {
+    if (!overflow && !VARIANT_int_iszero(a->bitsnum, ARRAY_SIZE(a->bitsnum))) {
 
         /* reverse order of digits */
         WCHAR * x = s; WCHAR * y = s + i - 1;
 
         /* reverse order of digits */
         WCHAR * x = s; WCHAR * y = s + i - 1;
@@ -5175,10 +5173,10 @@ static HRESULT VARIANT_DI_div(const VARIANT_DI * dividend, const VARIANT_DI * di
 {
     HRESULT r_overflow = S_OK;
 
 {
     HRESULT r_overflow = S_OK;
 
-    if (VARIANT_int_iszero(divisor->bitsnum, sizeof(divisor->bitsnum)/sizeof(DWORD))) {
+    if (VARIANT_int_iszero(divisor->bitsnum, ARRAY_SIZE(divisor->bitsnum))) {
         /* division by 0 */
         r_overflow = DISP_E_DIVBYZERO;
         /* division by 0 */
         r_overflow = DISP_E_DIVBYZERO;
-    } else if (VARIANT_int_iszero(dividend->bitsnum, sizeof(dividend->bitsnum)/sizeof(DWORD))) {
+    } else if (VARIANT_int_iszero(dividend->bitsnum, ARRAY_SIZE(dividend->bitsnum))) {
         VARIANT_DI_clear(quotient);
     } else {
         int quotientscale, remainderscale, tempquotientscale;
         VARIANT_DI_clear(quotient);
     } else {
         int quotientscale, remainderscale, tempquotientscale;
@@ -5208,17 +5206,14 @@ static HRESULT VARIANT_DI_div(const VARIANT_DI * dividend, const VARIANT_DI * di
         memset(remainderplusquotient, 0, sizeof(remainderplusquotient));
         memcpy(remainderplusquotient, dividend->bitsnum, sizeof(dividend->bitsnum));
         do {
         memset(remainderplusquotient, 0, sizeof(remainderplusquotient));
         memcpy(remainderplusquotient, dividend->bitsnum, sizeof(dividend->bitsnum));
         do {
-            VARIANT_int_div(
-                remainderplusquotient, 4,
-                divisor->bitsnum, sizeof(divisor->bitsnum)/sizeof(DWORD));
-            underflow = VARIANT_int_addlossy(
-                quotient->bitsnum, &quotientscale, sizeof(quotient->bitsnum) / sizeof(DWORD),
-                remainderplusquotient, &tempquotientscale, 4);
+            VARIANT_int_div(remainderplusquotient, 4, divisor->bitsnum, ARRAY_SIZE(divisor->bitsnum));
+            underflow = VARIANT_int_addlossy( quotient->bitsnum, &quotientscale,
+                ARRAY_SIZE(quotient->bitsnum), remainderplusquotient, &tempquotientscale, 4);
             if (round_remainder) {
                 if(remainderplusquotient[4] >= 5){
                     unsigned int i;
                     unsigned char remainder = 1;
             if (round_remainder) {
                 if(remainderplusquotient[4] >= 5){
                     unsigned int i;
                     unsigned char remainder = 1;
-                    for (i = 0; i < sizeof(quotient->bitsnum) / sizeof(DWORD) && remainder; i++) {
+                    for (i = 0; i < ARRAY_SIZE(quotient->bitsnum) && remainder; i++) {
                         ULONGLONG digit = quotient->bitsnum[i] + 1;
                         remainder = (digit > 0xFFFFFFFF) ? 1 : 0;
                         quotient->bitsnum[i] = digit & 0xFFFFFFFF;
                         ULONGLONG digit = quotient->bitsnum[i] + 1;
                         remainder = (digit > 0xFFFFFFFF) ? 1 : 0;
                         quotient->bitsnum[i] = digit & 0xFFFFFFFF;
@@ -5239,9 +5234,9 @@ static HRESULT VARIANT_DI_div(const VARIANT_DI * dividend, const VARIANT_DI * di
         while (r_overflow == S_OK && quotientscale < 0) {
             memset(remainderplusquotient, 0, sizeof(remainderplusquotient));
             memcpy(remainderplusquotient, quotient->bitsnum, sizeof(quotient->bitsnum));
         while (r_overflow == S_OK && quotientscale < 0) {
             memset(remainderplusquotient, 0, sizeof(remainderplusquotient));
             memcpy(remainderplusquotient, quotient->bitsnum, sizeof(quotient->bitsnum));
-            VARIANT_int_mulbychar(remainderplusquotient, sizeof(remainderplusquotient)/sizeof(DWORD), 10);
-            if (VARIANT_int_iszero(remainderplusquotient + sizeof(quotient->bitsnum)/sizeof(DWORD),
-                (sizeof(remainderplusquotient) - sizeof(quotient->bitsnum))/sizeof(DWORD))) {
+            VARIANT_int_mulbychar(remainderplusquotient, ARRAY_SIZE(remainderplusquotient), 10);
+            if (VARIANT_int_iszero(remainderplusquotient + ARRAY_SIZE(quotient->bitsnum),
+                ARRAY_SIZE(remainderplusquotient) - ARRAY_SIZE(quotient->bitsnum))) {
                 quotientscale++;
                 memcpy(quotient->bitsnum, remainderplusquotient, sizeof(quotient->bitsnum));
             } else r_overflow = DISP_E_OVERFLOW;
                 quotientscale++;
                 memcpy(quotient->bitsnum, remainderplusquotient, sizeof(quotient->bitsnum));
             } else r_overflow = DISP_E_OVERFLOW;
@@ -5562,9 +5557,9 @@ static HRESULT VARIANT_do_division(const DECIMAL *pDecLeft, const DECIMAL *pDecR
         WARN("result scale is %u, scaling (with loss of significant digits)...\n",
             di_result.scale);
         while (di_result.scale > DEC_MAX_SCALE && 
         WARN("result scale is %u, scaling (with loss of significant digits)...\n",
             di_result.scale);
         while (di_result.scale > DEC_MAX_SCALE && 
-               !VARIANT_int_iszero(di_result.bitsnum, sizeof(di_result.bitsnum) / sizeof(DWORD)))
+               !VARIANT_int_iszero(di_result.bitsnum, ARRAY_SIZE(di_result.bitsnum)))
         {
         {
-            remainder = VARIANT_int_divbychar(di_result.bitsnum, sizeof(di_result.bitsnum) / sizeof(DWORD), 10);
+            remainder = VARIANT_int_divbychar(di_result.bitsnum, ARRAY_SIZE(di_result.bitsnum), 10);
             di_result.scale--;
         }
         if (di_result.scale > DEC_MAX_SCALE)
             di_result.scale--;
         }
         if (di_result.scale > DEC_MAX_SCALE)
@@ -5576,7 +5571,7 @@ static HRESULT VARIANT_do_division(const DECIMAL *pDecLeft, const DECIMAL *pDecR
         else if (remainder >= 5)    /* round up result - native oleaut32 does this */
         {
             unsigned int i;
         else if (remainder >= 5)    /* round up result - native oleaut32 does this */
         {
             unsigned int i;
-            for (remainder = 1, i = 0; i < sizeof(di_result.bitsnum) / sizeof(DWORD) && remainder; i++) {
+            for (remainder = 1, i = 0; i < ARRAY_SIZE(di_result.bitsnum) && remainder; i++) {
                 ULONGLONG digit = di_result.bitsnum[i] + 1;
                 remainder = (digit > 0xFFFFFFFF) ? 1 : 0;
                 di_result.bitsnum[i] = digit & 0xFFFFFFFF;
                 ULONGLONG digit = di_result.bitsnum[i] + 1;
                 remainder = (digit > 0xFFFFFFFF) ? 1 : 0;
                 di_result.bitsnum[i] = digit & 0xFFFFFFFF;
@@ -5648,9 +5643,9 @@ HRESULT WINAPI VarDecMul(const DECIMAL* pDecLeft, const DECIMAL* pDecRight, DECI
       WARN("result scale is %u, scaling (with loss of significant digits)...\n",
           di_result.scale);
       while (di_result.scale > DEC_MAX_SCALE && 
       WARN("result scale is %u, scaling (with loss of significant digits)...\n",
           di_result.scale);
       while (di_result.scale > DEC_MAX_SCALE && 
-            !VARIANT_int_iszero(di_result.bitsnum, sizeof(di_result.bitsnum)/sizeof(DWORD)))
+            !VARIANT_int_iszero(di_result.bitsnum, ARRAY_SIZE(di_result.bitsnum)))
       {
       {
-        VARIANT_int_divbychar(di_result.bitsnum, sizeof(di_result.bitsnum)/sizeof(DWORD), 10);
+        VARIANT_int_divbychar(di_result.bitsnum, ARRAY_SIZE(di_result.bitsnum), 10);
         di_result.scale--;
       }
       if (di_result.scale > DEC_MAX_SCALE)
         di_result.scale--;
       }
       if (di_result.scale > DEC_MAX_SCALE)
@@ -6357,9 +6352,8 @@ static BSTR VARIANT_MakeBstr(LCID lcid, DWORD dwFlags, WCHAR *szOut)
   {
     /* Format the number for the locale */
     szConverted[0] = '\0';
   {
     /* Format the number for the locale */
     szConverted[0] = '\0';
-    GetNumberFormatW(lcid,
-                     dwFlags & LOCALE_NOUSEROVERRIDE,
-                     szOut, NULL, szConverted, sizeof(szConverted)/sizeof(WCHAR));
+    GetNumberFormatW(lcid, dwFlags & LOCALE_NOUSEROVERRIDE,
+                     szOut, NULL, szConverted, ARRAY_SIZE(szConverted));
     szOut = szConverted;
   }
   return SysAllocStringByteLen((LPCSTR)szOut, strlenW(szOut) * sizeof(WCHAR));
     szOut = szConverted;
   }
   return SysAllocStringByteLen((LPCSTR)szOut, strlenW(szOut) * sizeof(WCHAR));
@@ -6368,7 +6362,7 @@ static BSTR VARIANT_MakeBstr(LCID lcid, DWORD dwFlags, WCHAR *szOut)
 /* Create a (possibly localised) BSTR from a UI8 and sign */
 static HRESULT VARIANT_BstrFromUInt(ULONG64 ulVal, LCID lcid, DWORD dwFlags, BSTR *pbstrOut)
 {
 /* Create a (possibly localised) BSTR from a UI8 and sign */
 static HRESULT VARIANT_BstrFromUInt(ULONG64 ulVal, LCID lcid, DWORD dwFlags, BSTR *pbstrOut)
 {
-  WCHAR szBuff[64], *szOut = szBuff + sizeof(szBuff)/sizeof(WCHAR) - 1;
+  WCHAR szBuff[64], *szOut = szBuff + ARRAY_SIZE(szBuff) - 1;
 
   if (!pbstrOut)
     return E_INVALIDARG;
 
   if (!pbstrOut)
     return E_INVALIDARG;
@@ -6453,7 +6447,7 @@ HRESULT WINAPI VarBstrFromI4(LONG lIn, LCID lcid, ULONG dwFlags, BSTR* pbstrOut)
 
   if (lIn < 0)
   {
 
   if (lIn < 0)
   {
-    ul64 = (ULONG)-lIn;
+    ul64 = -(LONG64)lIn;
     dwFlags |= VAR_NEGATIVE;
   }
   return VARIANT_BstrFromUInt(ul64, lcid, dwFlags, pbstrOut);
     dwFlags |= VAR_NEGATIVE;
   }
   return VARIANT_BstrFromUInt(ul64, lcid, dwFlags, pbstrOut);
@@ -6472,7 +6466,7 @@ static BSTR VARIANT_BstrReplaceDecimal(const WCHAR * buff, LCID lcid, ULONG dwFl
      appropriate NUMBERFMTW structure to do the job via GetNumberFormatW().
    */
   GetLocaleInfoW(lcid, LOCALE_SDECIMAL | (dwFlags & LOCALE_NOUSEROVERRIDE),
      appropriate NUMBERFMTW structure to do the job via GetNumberFormatW().
    */
   GetLocaleInfoW(lcid, LOCALE_SDECIMAL | (dwFlags & LOCALE_NOUSEROVERRIDE),
-                 lpDecimalSep, sizeof(lpDecimalSep) / sizeof(WCHAR));
+                 lpDecimalSep, ARRAY_SIZE(lpDecimalSep));
   if (lpDecimalSep[0] == '.' && lpDecimalSep[1] == '\0')
   {
     /* locale is compatible with English - return original string */
   if (lpDecimalSep[0] == '.' && lpDecimalSep[1] == '\0')
   {
     /* locale is compatible with English - return original string */
@@ -6497,7 +6491,7 @@ static BSTR VARIANT_BstrReplaceDecimal(const WCHAR * buff, LCID lcid, ULONG dwFl
     if (p) minFormat.NumDigits = strlenW(p + 1);
 
     numbuff[0] = '\0';
     if (p) minFormat.NumDigits = strlenW(p + 1);
 
     numbuff[0] = '\0';
-    if (!GetNumberFormatW(lcid, 0, buff, &minFormat, numbuff, sizeof(numbuff) / sizeof(WCHAR)))
+    if (!GetNumberFormatW(lcid, 0, buff, &minFormat, numbuff, ARRAY_SIZE(numbuff)))
     {
       WARN("GetNumberFormatW() failed, returning raw number string instead\n");
       bstrOut = SysAllocString(buff);
     {
       WARN("GetNumberFormatW() failed, returning raw number string instead\n");
       bstrOut = SysAllocString(buff);
@@ -6528,7 +6522,7 @@ static HRESULT VARIANT_BstrFromReal(DOUBLE dblIn, LCID lcid, ULONG dwFlags,
    */
   if (buff[0] == '-')
   {
    */
   if (buff[0] == '-')
   {
-    const WCHAR szAccept[] = {'0', '.', '\0'};
+    static const WCHAR szAccept[] = {'0', '.', '\0'};
     if (strlenW(buff + 1) == strspnW(buff + 1, szAccept))
     { buff[0] = '0'; buff[1] = '\0'; }
   }
     if (strlenW(buff + 1) == strspnW(buff + 1, szAccept))
     { buff[0] = '0'; buff[1] = '\0'; }
   }
@@ -6541,7 +6535,7 @@ static HRESULT VARIANT_BstrFromReal(DOUBLE dblIn, LCID lcid, ULONG dwFlags,
     /* Format the number for the locale */
     numbuff[0] = '\0';
     GetNumberFormatW(lcid, dwFlags & LOCALE_NOUSEROVERRIDE,
     /* Format the number for the locale */
     numbuff[0] = '\0';
     GetNumberFormatW(lcid, dwFlags & LOCALE_NOUSEROVERRIDE,
-                     buff, NULL, numbuff, sizeof(numbuff) / sizeof(WCHAR));
+                     buff, NULL, numbuff, ARRAY_SIZE(numbuff));
     TRACE("created NLS string %s\n", debugstr_w(numbuff));
     *pbstrOut = SysAllocString(numbuff);
   }
     TRACE("created NLS string %s\n", debugstr_w(numbuff));
     *pbstrOut = SysAllocString(numbuff);
   }
@@ -6632,7 +6626,7 @@ HRESULT WINAPI VarBstrFromCy(CY cyIn, LCID lcid, ULONG dwFlags, BSTR *pbstrOut)
     VARIANT_int_add(decVal.bitsnum, 3, &one, 1);
   }
   decVal.bitsnum[2] = 0;
     VARIANT_int_add(decVal.bitsnum, 3, &one, 1);
   }
   decVal.bitsnum[2] = 0;
-  VARIANT_DI_tostringW(&decVal, buff, sizeof(buff)/sizeof(buff[0]));
+  VARIANT_DI_tostringW(&decVal, buff, ARRAY_SIZE(buff));
 
   if (dwFlags & LOCALE_USE_NLS)
   {
 
   if (dwFlags & LOCALE_USE_NLS)
   {
@@ -6641,7 +6635,7 @@ HRESULT WINAPI VarBstrFromCy(CY cyIn, LCID lcid, ULONG dwFlags, BSTR *pbstrOut)
     /* Format the currency for the locale */
     cybuff[0] = '\0';
     GetCurrencyFormatW(lcid, dwFlags & LOCALE_NOUSEROVERRIDE,
     /* Format the currency for the locale */
     cybuff[0] = '\0';
     GetCurrencyFormatW(lcid, dwFlags & LOCALE_NOUSEROVERRIDE,
-                       buff, NULL, cybuff, sizeof(cybuff) / sizeof(WCHAR));
+                       buff, NULL, cybuff, ARRAY_SIZE(cybuff));
     *pbstrOut = SysAllocString(cybuff);
   }
   else
     *pbstrOut = SysAllocString(cybuff);
   }
   else
@@ -6814,8 +6808,8 @@ HRESULT WINAPI VarBstrFromDate(DATE dateIn, LCID lcid, ULONG dwFlags, BSTR* pbst
   if (dwFlags & VAR_TIMEVALUEONLY)
     date[0] = '\0';
   else
   if (dwFlags & VAR_TIMEVALUEONLY)
     date[0] = '\0';
   else
-    if (!GetLocaleInfoW(lcid, LOCALE_SSHORTDATE, fmt_buff, sizeof(fmt_buff)/sizeof(WCHAR)) ||
-        !get_date_format(lcid, dwFlags, &st, fmt_buff, date, sizeof(date)/sizeof(WCHAR)))
+    if (!GetLocaleInfoW(lcid, LOCALE_SSHORTDATE, fmt_buff, ARRAY_SIZE(fmt_buff)) ||
+        !get_date_format(lcid, dwFlags, &st, fmt_buff, date, ARRAY_SIZE(date)))
       return E_INVALIDARG;
 
   if (!(dwFlags & VAR_DATEVALUEONLY))
       return E_INVALIDARG;
 
   if (!(dwFlags & VAR_DATEVALUEONLY))
@@ -6823,8 +6817,7 @@ HRESULT WINAPI VarBstrFromDate(DATE dateIn, LCID lcid, ULONG dwFlags, BSTR* pbst
     time = date + strlenW(date);
     if (time != date)
       *time++ = ' ';
     time = date + strlenW(date);
     if (time != date)
       *time++ = ' ';
-    if (!GetTimeFormatW(lcid, dwFormatFlags, &st, NULL, time,
-                        sizeof(date)/sizeof(WCHAR)-(time-date)))
+    if (!GetTimeFormatW(lcid, dwFormatFlags, &st, NULL, time, ARRAY_SIZE(date)-(time-date)))
       return E_INVALIDARG;
   }
 
       return E_INVALIDARG;
   }
 
@@ -7012,7 +7005,7 @@ HRESULT WINAPI VarBstrFromDec(DECIMAL* pDecIn, LCID lcid, ULONG dwFlags, BSTR* p
     /* Format the number for the locale */
     numbuff[0] = '\0';
     GetNumberFormatW(lcid, dwFlags & LOCALE_NOUSEROVERRIDE,
     /* Format the number for the locale */
     numbuff[0] = '\0';
     GetNumberFormatW(lcid, dwFlags & LOCALE_NOUSEROVERRIDE,
-                     buff, NULL, numbuff, sizeof(numbuff) / sizeof(WCHAR));
+                     buff, NULL, numbuff, ARRAY_SIZE(numbuff));
     TRACE("created NLS string %s\n", debugstr_w(numbuff));
     *pbstrOut = SysAllocString(numbuff);
   }
     TRACE("created NLS string %s\n", debugstr_w(numbuff));
     *pbstrOut = SysAllocString(numbuff);
   }
@@ -7625,7 +7618,7 @@ HRESULT WINAPI VarDateFromStr(OLECHAR* strIn, LCID lcid, ULONG dwFlags, DATE* pd
     1,2,3,4,5,6,7,8,9,10,11,12,13
   };
   unsigned int i;
     1,2,3,4,5,6,7,8,9,10,11,12,13
   };
   unsigned int i;
-  BSTR tokens[sizeof(ParseDateTokens)/sizeof(ParseDateTokens[0])];
+  BSTR tokens[ARRAY_SIZE(ParseDateTokens)];
   DATEPARSE dp;
   DWORD dwDateSeps = 0, iDate = 0;
   HRESULT hRet = S_OK;
   DATEPARSE dp;
   DWORD dwDateSeps = 0, iDate = 0;
   HRESULT hRet = S_OK;
@@ -7648,7 +7641,7 @@ HRESULT WINAPI VarDateFromStr(OLECHAR* strIn, LCID lcid, ULONG dwFlags, DATE* pd
   TRACE("iDate is %d\n", iDate);
 
   /* Get the month/day/am/pm tokens for this locale */
   TRACE("iDate is %d\n", iDate);
 
   /* Get the month/day/am/pm tokens for this locale */
-  for (i = 0; i < sizeof(tokens)/sizeof(tokens[0]); i++)
+  for (i = 0; i < ARRAY_SIZE(tokens); i++)
   {
     WCHAR buff[128];
     LCTYPE lctype =  ParseDateTokens[i] | (dwFlags & LOCALE_NOUSEROVERRIDE);
   {
     WCHAR buff[128];
     LCTYPE lctype =  ParseDateTokens[i] | (dwFlags & LOCALE_NOUSEROVERRIDE);
@@ -7657,7 +7650,7 @@ HRESULT WINAPI VarDateFromStr(OLECHAR* strIn, LCID lcid, ULONG dwFlags, DATE* pd
      *        GetAltMonthNames(). We should really cache these strings too.
      */
     buff[0] = '\0';
      *        GetAltMonthNames(). We should really cache these strings too.
      */
     buff[0] = '\0';
-    GetLocaleInfoW(lcid, lctype, buff, sizeof(buff)/sizeof(WCHAR));
+    GetLocaleInfoW(lcid, lctype, buff, ARRAY_SIZE(buff));
     tokens[i] = SysAllocString(buff);
     TRACE("token %d is %s\n", i, debugstr_w(tokens[i]));
   }
     tokens[i] = SysAllocString(buff);
     TRACE("token %d is %s\n", i, debugstr_w(tokens[i]));
   }
@@ -7680,7 +7673,7 @@ HRESULT WINAPI VarDateFromStr(OLECHAR* strIn, LCID lcid, ULONG dwFlags, DATE* pd
     {
       BOOL bFound = FALSE;
 
     {
       BOOL bFound = FALSE;
 
-      for (i = 0; i < sizeof(tokens)/sizeof(tokens[0]); i++)
+      for (i = 0; i < ARRAY_SIZE(tokens); i++)
       {
         DWORD dwLen = strlenW(tokens[i]);
         if (dwLen && !strncmpiW(strIn, tokens[i], dwLen))
       {
         DWORD dwLen = strlenW(tokens[i]);
         if (dwLen && !strncmpiW(strIn, tokens[i], dwLen))
@@ -7940,7 +7933,7 @@ HRESULT WINAPI VarDateFromStr(OLECHAR* strIn, LCID lcid, ULONG dwFlags, DATE* pd
     }
   }
 
     }
   }
 
-  for (i = 0; i < sizeof(tokens)/sizeof(tokens[0]); i++)
+  for (i = 0; i < ARRAY_SIZE(tokens); i++)
     SysFreeString(tokens[i]);
   return hRet;
 }
     SysFreeString(tokens[i]);
   return hRet;
 }
index f31f210..27033f2 100644 (file)
@@ -141,7 +141,7 @@ reactos/dll/win32/odbc32              # Synced to WineStaging-4.0. Depends on po
 reactos/dll/win32/odbccp32            # Synced to WineStaging-4.0
 reactos/dll/win32/ole32               # Synced to WineStaging-4.0
 reactos/dll/win32/oleacc              # Synced to WineStaging-4.0
 reactos/dll/win32/odbccp32            # Synced to WineStaging-4.0
 reactos/dll/win32/ole32               # Synced to WineStaging-4.0
 reactos/dll/win32/oleacc              # Synced to WineStaging-4.0
-reactos/dll/win32/oleaut32            # Synced to WineStaging-3.3
+reactos/dll/win32/oleaut32            # Synced to WineStaging-4.0
 reactos/dll/win32/olecli32            # Synced to WineStaging-3.3
 reactos/dll/win32/oledlg              # Synced to WineStaging-3.3
 reactos/dll/win32/olepro32            # Synced to WineStaging-3.3
 reactos/dll/win32/olecli32            # Synced to WineStaging-3.3
 reactos/dll/win32/oledlg              # Synced to WineStaging-3.3
 reactos/dll/win32/olepro32            # Synced to WineStaging-3.3
index ac3a92b..8221129 100644 (file)
@@ -676,18 +676,18 @@ HRESULT WINAPI VarDecNeg(_In_ const DECIMAL*, _Out_ DECIMAL*);
 HRESULT WINAPI VarDecRound(_In_ const DECIMAL*, int, _Out_ DECIMAL*);
 HRESULT WINAPI VarDecSub(_In_ const DECIMAL*, _In_ const DECIMAL*, _Out_ DECIMAL*);
 
 HRESULT WINAPI VarDecRound(_In_ const DECIMAL*, int, _Out_ DECIMAL*);
 HRESULT WINAPI VarDecSub(_In_ const DECIMAL*, _In_ const DECIMAL*, _Out_ DECIMAL*);
 
-HRESULT WINAPI VarCyAbs(_In_ const CY, _Out_ CY*);
-HRESULT WINAPI VarCyAdd(_In_ const CY, _In_ const CY, _Out_ CY*);
-HRESULT WINAPI VarCyCmp(_In_ const CY, _In_ const CY);
-HRESULT WINAPI VarCyCmpR8(_In_ const CY, _In_ DOUBLE);
-HRESULT WINAPI VarCyFix(_In_ const CY, _Out_ CY*);
-HRESULT WINAPI VarCyInt(_In_ const CY, _Out_ CY*);
-HRESULT WINAPI VarCyMul(_In_ const CY, _In_ CY, _Out_ CY*);
-HRESULT WINAPI VarCyMulI4(_In_ const CY, _In_ LONG, _Out_ CY*);
-HRESULT WINAPI VarCyMulI8(_In_ const CY, _In_ LONG64, _Out_ CY*);
-HRESULT WINAPI VarCyNeg(_In_ const CY, _Out_ CY*);
-HRESULT WINAPI VarCyRound(_In_ const CY, _In_ INT, _Out_ CY*);
-HRESULT WINAPI VarCySub(_In_ const CY, _In_ const CY, _Out_ CY*);
+HRESULT WINAPI VarCyAbs(_In_ CY, _Out_ CY*);
+HRESULT WINAPI VarCyAdd(_In_ CY, _In_ CY, _Out_ CY*);
+HRESULT WINAPI VarCyCmp(_In_ CY, _In_ CY);
+HRESULT WINAPI VarCyCmpR8(_In_ CY, _In_ DOUBLE);
+HRESULT WINAPI VarCyFix(_In_ CY, _Out_ CY*);
+HRESULT WINAPI VarCyInt(_In_ CY, _Out_ CY*);
+HRESULT WINAPI VarCyMul(_In_ CY, _In_ CY, _Out_ CY*);
+HRESULT WINAPI VarCyMulI4(_In_ CY, _In_ LONG, _Out_ CY*);
+HRESULT WINAPI VarCyMulI8(_In_ CY, _In_ LONG64, _Out_ CY*);
+HRESULT WINAPI VarCyNeg(_In_ CY, _Out_ CY*);
+HRESULT WINAPI VarCyRound(_In_ CY, _In_ INT, _Out_ CY*);
+HRESULT WINAPI VarCySub(_In_ CY, _In_ CY, _Out_ CY*);
 
 HRESULT WINAPI VarAdd(_In_ LPVARIANT, _In_ LPVARIANT, _Out_ LPVARIANT);
 HRESULT WINAPI VarAnd(_In_ LPVARIANT, _In_ LPVARIANT, _Out_ LPVARIANT);
 
 HRESULT WINAPI VarAdd(_In_ LPVARIANT, _In_ LPVARIANT, _Out_ LPVARIANT);
 HRESULT WINAPI VarAnd(_In_ LPVARIANT, _In_ LPVARIANT, _Out_ LPVARIANT);