https://git.reactos.org/?p=reactos.git;a=commitdiff;h=2b57c9f47d3a943706179de14791747b5169bc9d

commit 2b57c9f47d3a943706179de14791747b5169bc9d
Author:     Timo Kreuzer <timo.kreu...@reactos.org>
AuthorDate: Sun Jan 28 17:05:15 2018 +0100
Commit:     Timo Kreuzer <timo.kreu...@reactos.org>
CommitDate: Mon Jan 29 23:31:08 2018 +0100

    Revert "[OLEAUT32] Sync with Wine 3.0. CORE-14225"
    
    This reverts commit 13fd286c1840f80c0fca1dbfedd600a0f8a4478b.
    
    The "sync" zapped a lot of fixes, in particular 64 bit compatibility.
---
 dll/win32/oleaut32/oleaut.c     |   2 +-
 dll/win32/oleaut32/olepicture.c | 355 ++++++++++++++++----------
 dll/win32/oleaut32/tmarshal.c   | 216 ++++++++++++----
 dll/win32/oleaut32/typelib.c    | 536 +++++++++++++++++++---------------------
 dll/win32/oleaut32/typelib.h    |   6 +-
 dll/win32/oleaut32/variant.c    |  14 +-
 dll/win32/oleaut32/vartype.c    |   2 +-
 media/doc/README.WINE           |   2 +-
 8 files changed, 659 insertions(+), 474 deletions(-)

diff --git a/dll/win32/oleaut32/oleaut.c b/dll/win32/oleaut32/oleaut.c
index 0c3679491c..349a64da61 100644
--- a/dll/win32/oleaut32/oleaut.c
+++ b/dll/win32/oleaut32/oleaut.c
@@ -100,7 +100,7 @@ static inline size_t bstr_alloc_size(size_t size)
 
 static inline bstr_t *bstr_from_str(BSTR str)
 {
-    return CONTAINING_RECORD(str, bstr_t, u.str);
+    return CONTAINING_RECORD((void *)str, bstr_t, u.str);
 }
 
 static inline bstr_cache_entry_t *get_cache_entry_from_idx(unsigned cache_idx)
diff --git a/dll/win32/oleaut32/olepicture.c b/dll/win32/oleaut32/olepicture.c
index b687fdf201..878fd18292 100644
--- a/dll/win32/oleaut32/olepicture.c
+++ b/dll/win32/oleaut32/olepicture.c
@@ -246,6 +246,18 @@ static void OLEPictureImpl_SetIcon(OLEPictureImpl * This)
     }
 }
 
+static void OLEPictureImpl_SetEMF(OLEPictureImpl *This)
+{
+    ENHMETAHEADER emh;
+
+    GetEnhMetaFileHeader(This->desc.u.emf.hemf, sizeof(emh), &emh);
+
+    This->origWidth = 0;
+    This->origHeight = 0;
+    This->himetricWidth = emh.rclFrame.right - emh.rclFrame.left;
+    This->himetricHeight = emh.rclFrame.bottom - emh.rclFrame.top;
+}
+
 /************************************************************************
  * OLEPictureImpl_Construct
  *
@@ -327,7 +339,11 @@ static OLEPictureImpl* OLEPictureImpl_Construct(LPPICTDESC 
pictDesc, BOOL fOwn)
       case PICTYPE_ICON:
         OLEPictureImpl_SetIcon(newObject);
         break;
+
       case PICTYPE_ENHMETAFILE:
+        OLEPictureImpl_SetEMF(newObject);
+        break;
+
       default:
        FIXME("Unsupported type %d\n", pictDesc->picType);
        newObject->himetricWidth = newObject->himetricHeight = 0;
@@ -813,19 +829,6 @@ static HRESULT WINAPI 
OLEPictureImpl_PictureChanged(IPicture *iface)
   return S_OK;
 }
 
-/************************************************************************
- * OLEPictureImpl_SaveAsFile
- */
-static HRESULT WINAPI OLEPictureImpl_SaveAsFile(IPicture *iface,
-                                               IStream *pstream,
-                                               BOOL SaveMemCopy,
-                                               LONG *pcbSize)
-{
-  OLEPictureImpl *This = impl_from_IPicture(iface);
-  FIXME("(%p)->(%p, %d, %p), hacked stub.\n", This, pstream, SaveMemCopy, 
pcbSize);
-  return IStream_Write(pstream,This->data,This->datalen,(ULONG*)pcbSize);
-}
-
 /************************************************************************
  * OLEPictureImpl_get_Attributes
  */
@@ -975,40 +978,13 @@ static HRESULT WINAPI OLEPictureImpl_IsDirty(
   return E_NOTIMPL;
 }
 
-static HRESULT OLEPictureImpl_LoadDIB(OLEPictureImpl *This, BYTE *xbuf, ULONG 
xread)
-{
-    BITMAPFILEHEADER   *bfh = (BITMAPFILEHEADER*)xbuf;
-    BITMAPINFO         *bi = (BITMAPINFO*)(bfh+1);
-    HDC                        hdcref;
-
-    /* Does not matter whether this is a coreheader or not, we only use
-     * components which are in both
-     */
-    hdcref = GetDC(0);
-    This->desc.u.bmp.hbitmap = CreateDIBitmap(
-       hdcref,
-       &(bi->bmiHeader),
-       CBM_INIT,
-       xbuf+bfh->bfOffBits,
-       bi,
-       DIB_RGB_COLORS
-    );
-    ReleaseDC(0, hdcref);
-    if (This->desc.u.bmp.hbitmap == 0)
-        return E_FAIL;
-    This->desc.picType = PICTYPE_BITMAP;
-    OLEPictureImpl_SetBitmap(This);
-    return S_OK;
-}
-
 static HRESULT OLEPictureImpl_LoadWICSource(OLEPictureImpl *This, 
IWICBitmapSource *src)
 {
     HRESULT hr;
     BITMAPINFOHEADER bih;
-    HDC hdcref;
     UINT width, height;
     UINT stride, buffersize;
-    LPBYTE bits=NULL;
+    BYTE *bits, *mask = NULL;
     WICRect rc;
     IWICBitmapSource *real_source;
     UINT x, y;
@@ -1036,34 +1012,28 @@ static HRESULT 
OLEPictureImpl_LoadWICSource(OLEPictureImpl *This, IWICBitmapSour
     stride = 4 * width;
     buffersize = stride * height;
 
-    bits = HeapAlloc(GetProcessHeap(), 0, buffersize);
-    if (!bits)
+    mask = HeapAlloc(GetProcessHeap(), 0, buffersize);
+    if (!mask)
     {
         hr = E_OUTOFMEMORY;
         goto end;
     }
 
+    This->desc.u.bmp.hbitmap = CreateDIBSection(0, (BITMAPINFO*)&bih, 
DIB_RGB_COLORS, (void **)&bits, NULL, 0);
+    if (This->desc.u.bmp.hbitmap == 0)
+    {
+        hr = E_FAIL;
+        goto end;
+    }
+
     rc.X = 0;
     rc.Y = 0;
     rc.Width = width;
     rc.Height = height;
     hr = IWICBitmapSource_CopyPixels(real_source, &rc, stride, buffersize, 
bits);
     if (FAILED(hr))
-        goto end;
-
-    hdcref = GetDC(0);
-    This->desc.u.bmp.hbitmap = CreateDIBitmap(
-        hdcref,
-        &bih,
-        CBM_INIT,
-        bits,
-        (BITMAPINFO*)&bih,
-        DIB_RGB_COLORS);
-
-    if (This->desc.u.bmp.hbitmap == 0)
     {
-        hr = E_FAIL;
-        ReleaseDC(0, hdcref);
+        DeleteObject(This->desc.u.bmp.hbitmap);
         goto end;
     }
 
@@ -1077,23 +1047,25 @@ static HRESULT 
OLEPictureImpl_LoadWICSource(OLEPictureImpl *This, IWICBitmapSour
             if((*pixel & 0x80000000) == 0)
             {
                 has_alpha = TRUE;
-                *pixel = black;
+                *(DWORD *)(mask + stride * y + 4 * x) = black;
             }
             else
-                *pixel = white;
+                *(DWORD *)(mask + stride * y + 4 * x) = white;
         }
     }
 
     if (has_alpha)
     {
-        HDC hdcBmp, hdcXor, hdcMask;
+        HDC hdcref, hdcBmp, hdcXor, hdcMask;
         HBITMAP hbmoldBmp, hbmoldXor, hbmoldMask;
 
+        hdcref = GetDC(0);
+
         This->hbmXor = CreateDIBitmap(
             hdcref,
             &bih,
             CBM_INIT,
-            bits,
+            mask,
             (BITMAPINFO*)&bih,
             DIB_RGB_COLORS
         );
@@ -1118,12 +1090,11 @@ static HRESULT 
OLEPictureImpl_LoadWICSource(OLEPictureImpl *This, IWICBitmapSour
         DeleteDC(hdcBmp);
         DeleteDC(hdcXor);
         DeleteDC(hdcMask);
+        ReleaseDC(0, hdcref);
     }
 
-    ReleaseDC(0, hdcref);
-
 end:
-    HeapFree(GetProcessHeap(), 0, bits);
+    HeapFree(GetProcessHeap(), 0, mask);
     IWICBitmapSource_Release(real_source);
     return hr;
 }
@@ -1487,7 +1458,7 @@ static HRESULT WINAPI OLEPictureImpl_Load(IPersistStream* 
iface, IStream *pStm)
     hr = OLEPictureImpl_LoadWICDecoder(This, &CLSID_WICJpegDecoder, xbuf, 
xread);
     break;
   case BITMAP_FORMAT_BMP: /* Bitmap */
-    hr = OLEPictureImpl_LoadDIB(This, xbuf, xread);
+    hr = OLEPictureImpl_LoadWICDecoder(This, &CLSID_WICBmpDecoder, xbuf, 
xread);
     break;
   case BITMAP_FORMAT_PNG: /* PNG */
     hr = OLEPictureImpl_LoadWICDecoder(This, &CLSID_WICPngDecoder, xbuf, 
xread);
@@ -1742,6 +1713,17 @@ static BOOL serializeIcon(HICON hIcon, void ** ppBuffer, 
unsigned int * pLength)
         return success;
 }
 
+static BOOL serializeEMF(HENHMETAFILE hemf, void **buf, unsigned *size)
+{
+    *size = GetEnhMetaFileBits(hemf, 0, NULL);
+    if (!*size) return FALSE;
+
+    *buf = HeapAlloc(GetProcessHeap(), 0, *size);
+    if (!*buf) return FALSE;
+
+    return GetEnhMetaFileBits(hemf, *size, *buf) != 0;
+}
+
 static HRESULT WINAPI OLEPictureImpl_Save(
   IPersistStream* iface,IStream*pStm,BOOL fClearDirty)
 {
@@ -1817,12 +1799,31 @@ static HRESULT WINAPI OLEPictureImpl_Save(
         IStream_Write(pStm, This->data, This->datalen, &dummy);
         hResult = S_OK;
         break;
+
+    case PICTYPE_ENHMETAFILE:
+        if (This->bIsDirty || !This->data)
+        {
+            serializeResult = serializeEMF(This->desc.u.emf.hemf, &pIconData, 
&iDataSize);
+            if (!serializeResult)
+            {
+                hResult = E_FAIL;
+                break;
+            }
+
+            HeapFree(GetProcessHeap(), 0, This->data);
+            This->data = pIconData;
+            This->datalen = iDataSize;
+        }
+        header[0] = 0x0000746c;
+        header[1] = This->datalen;
+        IStream_Write(pStm, header, 2 * sizeof(DWORD), &dummy);
+        IStream_Write(pStm, This->data, This->datalen, &dummy);
+        hResult = S_OK;
+        break;
+
     case PICTYPE_METAFILE:
         FIXME("(%p,%p,%d), PICTYPE_METAFILE not 
implemented!\n",This,pStm,fClearDirty);
         break;
-    case PICTYPE_ENHMETAFILE:
-        FIXME("(%p,%p,%d),PICTYPE_ENHMETAFILE not 
implemented!\n",This,pStm,fClearDirty);
-        break;
     default:
         FIXME("(%p,%p,%d), [unknown type] not 
implemented!\n",This,pStm,fClearDirty);
         break;
@@ -1839,6 +1840,98 @@ static HRESULT WINAPI OLEPictureImpl_GetSizeMax(
   return E_NOTIMPL;
 }
 
+/************************************************************************
+ * OLEPictureImpl_SaveAsFile
+ */
+static HRESULT WINAPI OLEPictureImpl_SaveAsFile(IPicture *iface,
+    IStream *stream, BOOL mem_copy, LONG *size)
+{
+    OLEPictureImpl *This = impl_from_IPicture(iface);
+    void *data;
+    unsigned data_size;
+    ULONG written;
+    HRESULT hr;
+
+    FIXME("(%p)->(%p,%d,%p): semi-stub\n", This, stream, mem_copy, size);
+
+    switch (This->desc.picType)
+    {
+    case PICTYPE_NONE:
+        return S_OK;
+
+    case PICTYPE_ICON:
+        if (!mem_copy) return E_FAIL;
+
+        if (This->bIsDirty || !This->data)
+        {
+            if (!serializeIcon(This->desc.u.icon.hicon, &data, &data_size))
+                return E_FAIL;
+            HeapFree(GetProcessHeap(), 0, This->data);
+            This->data = data;
+            This->datalen = data_size;
+        }
+        hr = IStream_Write(stream, This->data, This->datalen, &written);
+        if (hr == S_OK && size) *size = written;
+        return hr;
+
+    case PICTYPE_BITMAP:
+        if (!mem_copy) return E_FAIL;
+
+        if (This->bIsDirty || !This->data)
+        {
+            switch (This->keepOrigFormat ? This->loadtime_format : 
BITMAP_FORMAT_BMP)
+            {
+            case BITMAP_FORMAT_BMP:
+                if (!serializeBMP(This->desc.u.bmp.hbitmap, &data, &data_size))
+                    return E_FAIL;
+                break;
+            case BITMAP_FORMAT_JPEG:
+                FIXME("BITMAP_FORMAT_JPEG is not implemented\n");
+                return E_NOTIMPL;
+            case BITMAP_FORMAT_GIF:
+                FIXME("BITMAP_FORMAT_GIF is not implemented\n");
+                return E_NOTIMPL;
+            case BITMAP_FORMAT_PNG:
+                FIXME("BITMAP_FORMAT_PNG is not implemented\n");
+                return E_NOTIMPL;
+            default:
+                FIXME("PICTYPE_BITMAP/%#x is not implemented\n", 
This->loadtime_format);
+                return E_NOTIMPL;
+            }
+
+            HeapFree(GetProcessHeap(), 0, This->data);
+            This->data = data;
+            This->datalen = data_size;
+        }
+        hr = IStream_Write(stream, This->data, This->datalen, &written);
+        if (hr == S_OK && size) *size = written;
+        return hr;
+
+    case PICTYPE_METAFILE:
+        FIXME("PICTYPE_METAFILE is not implemented\n");
+        return E_NOTIMPL;
+
+    case PICTYPE_ENHMETAFILE:
+        if (!mem_copy) return E_FAIL;
+
+        if (This->bIsDirty || !This->data)
+        {
+            if (!serializeEMF(This->desc.u.emf.hemf, &data, &data_size))
+                return E_FAIL;
+            HeapFree(GetProcessHeap(), 0, This->data);
+            This->data = data;
+            This->datalen = data_size;
+        }
+        hr = IStream_Write(stream, This->data, This->datalen, &written);
+        if (hr == S_OK && size) *size = written;
+        return hr;
+
+    default:
+        FIXME("%#x is not implemented\n", This->desc.picType);
+        break;
+    }
+    return E_NOTIMPL;
+}
 
 /************************************************************************
  *    IDispatch
@@ -2295,13 +2388,70 @@ HRESULT WINAPI OleLoadPictureEx( LPSTREAM lpstream, 
LONG lSize, BOOL fRunmode,
   return hr;
 }
 
+static HRESULT create_stream(const WCHAR *filename, IStream **stream)
+{
+    HANDLE hFile;
+    DWORD dwFileSize;
+    HGLOBAL hGlobal = NULL;
+    DWORD dwBytesRead;
+    HRESULT hr = S_OK;
+
+    hFile = CreateFileW(filename, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, 
NULL);
+    if (hFile == INVALID_HANDLE_VALUE)
+        return HRESULT_FROM_WIN32(GetLastError());
+
+    dwFileSize = GetFileSize(hFile, NULL);
+    if (dwFileSize != INVALID_FILE_SIZE)
+    {
+        hGlobal = GlobalAlloc(GMEM_FIXED, dwFileSize);
+        if (!hGlobal)
+            hr = E_OUTOFMEMORY;
+        else
+        {
+            if (!ReadFile(hFile, hGlobal, dwFileSize, &dwBytesRead, NULL))
+            {
+                GlobalFree(hGlobal);
+                hr = HRESULT_FROM_WIN32(GetLastError());
+            }
+        }
+    }
+
+    CloseHandle(hFile);
+
+    if (FAILED(hr)) return hr;
+
+    hr = CreateStreamOnHGlobal(hGlobal, TRUE, stream);
+    if (FAILED(hr))
+        GlobalFree(hGlobal);
+
+    return hr;
+}
+
 /***********************************************************************
  * OleLoadPictureFile (OLEAUT32.422)
  */
-HRESULT WINAPI OleLoadPictureFile(VARIANT file, LPDISPATCH *picture)
+HRESULT WINAPI OleLoadPictureFile(VARIANT filename, IDispatch **picture)
 {
-    FIXME("(%s %p): stub\n", wine_dbgstr_variant(&file), picture);
-    return E_NOTIMPL;
+    IStream *stream;
+    HRESULT hr;
+
+    TRACE("(%s,%p)\n", wine_dbgstr_variant(&filename), picture);
+
+    if (V_VT(&filename) != VT_BSTR)
+        return CTL_E_FILENOTFOUND;
+
+    hr = create_stream(V_BSTR(&filename), &stream);
+    if (hr != S_OK)
+    {
+        if (hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND))
+            return CTL_E_FILENOTFOUND;
+
+        return CTL_E_PATHFILEACCESSERROR;
+    }
+
+    hr = OleLoadPicture(stream, 0, FALSE, &IID_IDispatch, (void **)picture);
+    IStream_Release(stream);
+    return hr;
 }
 
 /***********************************************************************
@@ -2321,16 +2471,8 @@ HRESULT WINAPI OleLoadPicturePath( LPOLESTR szURLorPath, 
LPUNKNOWN punkCaller,
                LPVOID *ppvRet )
 {
   static const WCHAR file[] = { 'f','i','l','e',':',0 };
-  IPicture *ipicture;
-  HANDLE hFile;
-  DWORD dwFileSize;
-  HGLOBAL hGlobal = NULL;
-  DWORD dwBytesRead;
   IStream *stream;
-  BOOL bRead;
-  IPersistStream *pStream;
   HRESULT hRes;
-  HRESULT init_res;
   WCHAR *file_candidate;
   WCHAR path_buf[MAX_PATH];
 
@@ -2358,36 +2500,9 @@ HRESULT WINAPI OleLoadPicturePath( LPOLESTR szURLorPath, 
LPUNKNOWN punkCaller,
 
   /* Handle candidate DOS paths separately. */
   if (file_candidate[1] == ':') {
-      hFile = CreateFileW(file_candidate, GENERIC_READ, 0, NULL, OPEN_EXISTING,
-                          0, NULL);
-      if (hFile == INVALID_HANDLE_VALUE)
-          return INET_E_RESOURCE_NOT_FOUND;
-
-      dwFileSize = GetFileSize(hFile, NULL);
-      if (dwFileSize != INVALID_FILE_SIZE )
-      {
-         hGlobal = GlobalAlloc(GMEM_FIXED,dwFileSize);
-         if ( hGlobal)
-         {
-             bRead = ReadFile(hFile, hGlobal, dwFileSize, &dwBytesRead, NULL) 
&& dwBytesRead == dwFileSize;
-             if (!bRead)
-             {
-                 GlobalFree(hGlobal);
-                 hGlobal = 0;
-             }
-         }
-      }
-      CloseHandle(hFile);
-      
-      if (!hGlobal)
+      hRes = create_stream(file_candidate, &stream);
+      if (FAILED(hRes))
          return INET_E_RESOURCE_NOT_FOUND;
-
-      hRes = CreateStreamOnHGlobal(hGlobal, TRUE, &stream);
-      if (FAILED(hRes)) 
-      {
-         GlobalFree(hGlobal);
-         return hRes;
-      }
   } else {
       IMoniker *pmnk;
       IBindCtx *pbc;
@@ -2407,32 +2522,10 @@ HRESULT WINAPI OleLoadPicturePath( LPOLESTR 
szURLorPath, LPUNKNOWN punkCaller,
          return hRes;
   }
 
-  init_res = CoInitialize(NULL);
-
-  hRes = CoCreateInstance(&CLSID_StdPicture, punkCaller, CLSCTX_INPROC_SERVER,
-                          &IID_IPicture, (LPVOID*)&ipicture);
-  if (SUCCEEDED(hRes)) {
-      hRes = IPicture_QueryInterface(ipicture, &IID_IPersistStream, 
(LPVOID*)&pStream);
-
-      if (SUCCEEDED(hRes)) {
-          hRes = IPersistStream_Load(pStream, stream);
-
-          if (SUCCEEDED(hRes)) {
-              hRes = IPicture_QueryInterface(ipicture, riid, ppvRet);
-
-              if (FAILED(hRes))
-                  ERR("Failed to get interface %s from IPicture.\n", 
debugstr_guid(riid));
-          }
-          IPersistStream_Release(pStream);
-      }
-      IPicture_Release(ipicture);
-  }
+  hRes = OleLoadPicture(stream, 0, FALSE, riid, ppvRet);
 
   IStream_Release(stream);
 
-  if (SUCCEEDED(init_res))
-      CoUninitialize();
-
   return hRes;
 }
 
diff --git a/dll/win32/oleaut32/tmarshal.c b/dll/win32/oleaut32/tmarshal.c
index ca8c0db150..7a085f1fa2 100644
--- a/dll/win32/oleaut32/tmarshal.c
+++ b/dll/win32/oleaut32/tmarshal.c
@@ -471,7 +471,6 @@ static HRESULT num_of_funcs(ITypeInfo *tinfo, unsigned int 
*num,
 #ifdef __i386__
 
 #include "pshpack1.h"
-
 typedef struct _TMAsmProxy {
     DWORD      lealeax;
     BYTE       pushleax;
@@ -483,7 +482,30 @@ typedef struct _TMAsmProxy {
     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__ */
@@ -619,42 +641,51 @@ static const IRpcProxyBufferVtbl tmproxyvtable = {
     TMProxyImpl_Disconnect
 };
 
-/* how much space do we use on stack in DWORD steps. */
+/* 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:
-       return 8/sizeof(DWORD);
+        ret = 8;
+        break;
     case VT_R8:
-        return sizeof(double)/sizeof(DWORD);
+        ret = sizeof(double);
+        break;
     case VT_CY:
-        return sizeof(CY)/sizeof(DWORD);
+        ret = sizeof(CY);
+        break;
     case VT_DATE:
-       return sizeof(DATE)/sizeof(DWORD);
+        ret = sizeof(DATE);
+        break;
     case VT_DECIMAL:
-        return (sizeof(DECIMAL)+3)/sizeof(DWORD);
+        ret = sizeof(DECIMAL);
+        break;
     case VT_VARIANT:
-       return (sizeof(VARIANT)+3)/sizeof(DWORD);
+        ret = sizeof(VARIANT);
+        break;
     case VT_USERDEFINED:
     {
         ITypeInfo *tinfo2;
         TYPEATTR *tattr;
         HRESULT hres;
-        DWORD ret;
 
         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+3)/sizeof(DWORD);
+        ret = tattr->cbSizeInstance;
         ITypeInfo_ReleaseTypeAttr(tinfo2, tattr);
         ITypeInfo_Release(tinfo2);
-        return ret;
+        break;
     }
     default:
-       return 1;
+        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) */
@@ -703,7 +734,7 @@ _xsize(const TYPEDESC *td, ITypeInfo *tinfo) {
         return ret;
     }
     default:
-       return 4;
+       return sizeof(DWORD_PTR);
     }
 }
 
@@ -722,7 +753,7 @@ serialize_param(
     BOOL               debugout,
     BOOL               dealloc,
     TYPEDESC           *tdesc,
-    DWORD              *arg,
+    DWORD_PTR          *arg,
     marshal_state      *buf)
 {
     HRESULT hres = S_OK;
@@ -741,7 +772,7 @@ serialize_param(
     case VT_R8:
     case VT_CY:
        hres = S_OK;
-       if (debugout) TRACE_(olerelay)("%x%x\n",arg[0],arg[1]);
+       if (debugout) TRACE_(olerelay)("%s\n", wine_dbgstr_longlong(*(ULONGLONG 
*)arg));
        if (writeit)
            hres = xbuf_add(buf,(LPBYTE)arg,8);
        return hres;
@@ -752,7 +783,7 @@ serialize_param(
     case VT_R4:
     case VT_UI4:
        hres = S_OK;
-       if (debugout) TRACE_(olerelay)("%x\n",*arg);
+       if (debugout) TRACE_(olerelay)("%x\n", *(DWORD *)arg);
        if (writeit)
            hres = xbuf_add(buf,(LPBYTE)arg,sizeof(DWORD));
        return hres;
@@ -760,14 +791,14 @@ serialize_param(
     case VT_UI2:
     case VT_BOOL:
        hres = S_OK;
-       if (debugout) TRACE_(olerelay)("%04x\n",*arg & 0xffff);
+       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",*arg & 0xff);
+       if (debugout) TRACE_(olerelay)("%02x\n", *(BYTE *)arg);
        if (writeit)
            hres = xbuf_add(buf,(LPBYTE)arg,sizeof(DWORD));
        return hres;
@@ -837,7 +868,9 @@ serialize_param(
                         return hres;
                     }
                     ITypeInfo_GetTypeAttr(tinfo2,&tattr);
-                    derefhere = (tattr->typekind != TKIND_DISPATCH && 
tattr->typekind != TKIND_INTERFACE);
+                    derefhere = (tattr->typekind != TKIND_DISPATCH &&
+                                 tattr->typekind != TKIND_INTERFACE &&
+                                 tattr->typekind != TKIND_COCLASS);
                 }
                 break;
            case TKIND_ENUM:    /* confirmed */
@@ -845,6 +878,7 @@ serialize_param(
                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:
@@ -867,19 +901,19 @@ serialize_param(
            if (debugout) TRACE_(olerelay)("NULL");
            return S_OK;
        }
-       hres = 
serialize_param(tinfo,writeit,debugout,dealloc,tdesc->u.lptdesc,(DWORD*)*arg,buf);
+       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%x)",*arg);
+       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%x)",*arg);
+       if (debugout) TRACE_(olerelay)("idisp(0x%lx)", *arg);
        if (writeit)
            hres = _marshal_interface(buf,&IID_IDispatch,(LPUNKNOWN)*arg);
        if (dealloc && *(IUnknown **)arg)
@@ -906,6 +940,36 @@ serialize_param(
            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)("{");
@@ -927,7 +991,7 @@ serialize_param(
                    debugout,
                    dealloc,
                    tdesc2,
-                   (DWORD*)(((LPBYTE)arg)+vdesc->u.oInst),
+                   (DWORD_PTR *)(((LPBYTE)arg)+vdesc->u.oInst),
                    buf
                );
                 ITypeInfo_ReleaseVarDesc(tinfo2, vdesc);
@@ -944,7 +1008,7 @@ serialize_param(
            break;
        case TKIND_ENUM:
            hres = S_OK;
-           if (debugout) TRACE_(olerelay)("%x",*arg);
+           if (debugout) TRACE_(olerelay)("%x", *(DWORD *)arg);
            if (writeit)
                hres = xbuf_add(buf,(LPBYTE)arg,sizeof(DWORD));
            break;
@@ -970,7 +1034,7 @@ serialize_param(
        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*)((LPBYTE)base+i*_xsize(&adesc->tdescElem, tinfo)), 
buf);
+           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)(",");
@@ -1009,7 +1073,7 @@ deserialize_param(
     BOOL               debugout,
     BOOL               alloc,
     TYPEDESC           *tdesc,
-    DWORD              *arg,
+    DWORD_PTR          *arg,
     marshal_state      *buf)
 {
     HRESULT hres = S_OK;
@@ -1042,7 +1106,7 @@ deserialize_param(
                hres = xbuf_get(buf,(LPBYTE)arg,8);
                if (hres) ERR("Failed to read integer 8 byte\n");
            }
-           if (debugout) TRACE_(olerelay)("%x%x",arg[0],arg[1]);
+           if (debugout) TRACE_(olerelay)("%s", 
wine_dbgstr_longlong(*(ULONGLONG *)arg));
            return hres;
         case VT_ERROR:
         case VT_I4:
@@ -1054,7 +1118,7 @@ deserialize_param(
                hres = xbuf_get(buf,(LPBYTE)arg,sizeof(DWORD));
                if (hres) ERR("Failed to read integer 4 byte\n");
            }
-           if (debugout) TRACE_(olerelay)("%x",*arg);
+           if (debugout) TRACE_(olerelay)("%x", *(DWORD *)arg);
            return hres;
         case VT_I2:
         case VT_UI2:
@@ -1065,7 +1129,7 @@ deserialize_param(
                if (hres) ERR("Failed to read integer 4 byte\n");
                else memcpy(arg,&x,2);
            }
-           if (debugout) TRACE_(olerelay)("%04x",*arg & 0xffff);
+           if (debugout) TRACE_(olerelay)("%04x", *(WORD *)arg);
            return hres;
         case VT_I1:
        case VT_UI1:
@@ -1075,7 +1139,7 @@ deserialize_param(
                if (hres) ERR("Failed to read integer 4 byte\n");
                else memcpy(arg,&x,1);
            }
-           if (debugout) TRACE_(olerelay)("%02x",*arg & 0xff);
+           if (debugout) TRACE_(olerelay)("%02x", *(BYTE *)arg);
            return hres;
        case VT_BSTR: {
            if (readit)
@@ -1115,7 +1179,9 @@ deserialize_param(
                             return hres;
                         }
                         ITypeInfo_GetTypeAttr(tinfo2,&tattr);
-                        derefhere = (tattr->typekind != TKIND_DISPATCH && 
tattr->typekind != TKIND_INTERFACE);
+                        derefhere = (tattr->typekind != TKIND_DISPATCH &&
+                                     tattr->typekind != TKIND_INTERFACE &&
+                                     tattr->typekind != TKIND_COCLASS);
                     }
                     break;
                case TKIND_ENUM:        /* confirmed */
@@ -1123,6 +1189,7 @@ deserialize_param(
                    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:
@@ -1151,17 +1218,17 @@ deserialize_param(
            if (alloc) {
                /* Allocate space for the referenced struct */
                if (derefhere)
-                   
*arg=(DWORD)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,_xsize(tdesc->u.lptdesc,
 tinfo));
+                   
*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, (LPDWORD)*arg, buf);
+               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)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(DWORD));
+               
*arg=(DWORD_PTR)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(DWORD_PTR));
            hres = S_OK;
            if (readit)
                hres = _unmarshal_interface(buf,&IID_IUnknown,(LPUNKNOWN*)arg);
@@ -1197,6 +1264,34 @@ deserialize_param(
                    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;
 
@@ -1217,7 +1312,7 @@ deserialize_param(
                            debugout,
                            alloc,
                            &vdesc->elemdescVar.tdesc,
-                           (DWORD*)(((LPBYTE)arg)+vdesc->u.oInst),
+                           (DWORD_PTR *)(((LPBYTE)arg)+vdesc->u.oInst),
                            buf
                        );
                         ITypeInfo_ReleaseVarDesc(tinfo2, vdesc);
@@ -1234,7 +1329,7 @@ deserialize_param(
                        hres = xbuf_get(buf,(LPBYTE)arg,sizeof(DWORD));
                        if (hres) ERR("Failed to read enum (4 byte)\n");
                    }
-                   if (debugout) TRACE_(olerelay)("%x",*arg);
+                   if (debugout) TRACE_(olerelay)("%x", *(DWORD *)arg);
                    break;
                default:
                    ERR("Unhandled typekind %d\n",tattr->typekind);
@@ -1260,7 +1355,7 @@ deserialize_param(
             if (_passbyref(&adesc->tdescElem, tinfo))
             {
                base = 
HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,_xsize(tdesc->u.lptdesc, tinfo) * 
arrsize);
-                *arg = (DWORD) base;
+                *arg = (DWORD_PTR)base;
             }
            for (i=0;i<arrsize;i++)
                deserialize_param(
@@ -1269,7 +1364,7 @@ deserialize_param(
                    debugout,
                    alloc,
                    &adesc->tdescElem,
-                   (DWORD*)(base + i*_xsize(&adesc->tdescElem, tinfo)),
+                   (DWORD_PTR *)(base + i*_xsize(&adesc->tdescElem, tinfo)),
                    buf
                );
            return S_OK;
@@ -1399,7 +1494,7 @@ static inline BOOL is_out_elem(const ELEMDESC *elem)
 static DWORD WINAPI xCall(int method, void **args)
 {
     TMProxyImpl *tpinfo = args[0];
-    DWORD *xargs;
+    DWORD_PTR *xargs;
     const FUNCDESC     *fdesc;
     HRESULT            hres;
     int                        i;
@@ -1459,7 +1554,7 @@ static DWORD WINAPI xCall(int method, void **args)
     if (nrofnames > sizeof(names)/sizeof(names[0]))
        ERR("Need more names!\n");
 
-    xargs = (DWORD *)(args + 1);
+    xargs = (DWORD_PTR *)(args + 1);
     for (i=0;i<fdesc->cParams;i++) {
        ELEMDESC        *elem = fdesc->lprgelemdescParam+i;
        if (TRACE_ON(olerelay)) {
@@ -1526,7 +1621,7 @@ static DWORD WINAPI xCall(int method, void **args)
     buf.curoff = 0;
 
     /* generic deserializer using typelib description */
-    xargs = (DWORD *)(args + 1);
+    xargs = (DWORD_PTR *)(args + 1);
     status = S_OK;
     for (i=0;i<fdesc->cParams;i++) {
        ELEMDESC        *elem = fdesc->lprgelemdescParam+i;
@@ -1822,6 +1917,34 @@ static HRESULT init_proxy_entry_point(TMProxyImpl 
*proxy, unsigned int num)
     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;
@@ -2048,12 +2171,13 @@ static HRESULT WINAPI
 TMStubImpl_Invoke(
     LPRPCSTUBBUFFER iface, RPCOLEMESSAGE* xmsg,IRpcChannelBuffer*rpcchanbuf)
 {
-#ifdef __i386__
+#if defined(__i386__) || defined(__x86_64__)
     int                i;
     const FUNCDESC *fdesc;
     TMStubImpl *This = impl_from_IRpcStubBuffer(iface);
     HRESULT    hres;
-    DWORD      *args = NULL, res, *xargs, nrofargs;
+    DWORD_PTR   *args = NULL, *xargs;
+    DWORD      res, nrofargs;
     marshal_state      buf;
     UINT       nrofnames = 0;
     BSTR       names[10];
@@ -2118,7 +2242,7 @@ TMStubImpl_Invoke(
     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));
+    args = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 
(nrofargs+1)*sizeof(DWORD_PTR));
     if (!args)
     {
         hres = E_OUTOFMEMORY;
@@ -2146,12 +2270,12 @@ TMStubImpl_Invoke(
        }
     }
 
-    args[0] = (DWORD)This->pUnk;
+    args[0] = (DWORD_PTR)This->pUnk;
 
     __TRY
     {
         res = _invoke(
-            (*((FARPROC**)args[0]))[fdesc->oVft/4],
+            (*((FARPROC**)args[0]))[fdesc->oVft / sizeof(DWORD_PTR)],
             fdesc->callconv,
             (xargs-args),
             args
diff --git a/dll/win32/oleaut32/typelib.c b/dll/win32/oleaut32/typelib.c
index 0d2376ce49..4f2fa47924 100644
--- a/dll/win32/oleaut32/typelib.c
+++ b/dll/win32/oleaut32/typelib.c
@@ -403,11 +403,21 @@ HRESULT WINAPI QueryPathOfRegTypeLib( REFGUID guid, WORD 
wMaj, WORD wMin, LCID l
  *    Success: S_OK
  *    Failure: Status
  */
-HRESULT WINAPI CreateTypeLib(
-       SYSKIND syskind, LPCOLESTR szFile, ICreateTypeLib** ppctlib
-) {
-    FIXME("(%d,%s,%p), stub!\n",syskind,debugstr_w(szFile),ppctlib);
-    return E_FAIL;
+HRESULT WINAPI CreateTypeLib(SYSKIND syskind, LPCOLESTR file, ICreateTypeLib 
**ctlib)
+{
+    ICreateTypeLib2 *typelib2;
+    HRESULT hres;
+
+    FIXME("(%d, %s, %p): forwarding to CreateTypeLib2\n", syskind, 
debugstr_w(file), ctlib);
+
+    hres = CreateTypeLib2(syskind, file, &typelib2);
+    if(SUCCEEDED(hres))
+    {
+        hres = ICreateTypeLib2_QueryInterface(typelib2, &IID_ICreateTypeLib, 
(void **)&ctlib);
+        ICreateTypeLib2_Release(typelib2);
+    }
+
+    return hres;
 }
 
 /******************************************************************************
@@ -3491,6 +3501,10 @@ static ITypeLib2* ITypeLib2_Constructor_MSFT(LPVOID 
pLib, DWORD dwTLBLength)
     /* name, eventually add to a hash table */
     pTypeLibImpl->Name = MSFT_ReadName(&cx, tlbHeader.NameOffset);
 
+    TRACE("%s, syskind %d, version %d.%d, flags %04x\n",
+        debugstr_w(pTypeLibImpl->Name->str), pTypeLibImpl->syskind,
+        pTypeLibImpl->ver_major, pTypeLibImpl->ver_minor, 
pTypeLibImpl->libflags);
+
     /* help info */
     pTypeLibImpl->DocString = MSFT_ReadString(&cx, tlbHeader.helpstring);
     pTypeLibImpl->HelpFile = MSFT_ReadString(&cx, tlbHeader.helpfile);
@@ -3661,6 +3675,87 @@ static BOOL TLB_GUIDFromString(const char *str, GUID 
*guid)
   return TRUE;
 }
 
+struct bitstream
+{
+    const BYTE *buffer;
+    DWORD       length;
+    WORD        current;
+};
+
+static const char *lookup_code(const BYTE *table, DWORD table_size, struct 
bitstream *bits)
+{
+    const BYTE *p = table;
+
+    while (p < table + table_size && *p == 0x80)
+    {
+        if (p + 2 >= table + table_size) return NULL;
+
+        if (!(bits->current & 0xff))
+        {
+            if (!bits->length) return NULL;
+            bits->current = (*bits->buffer << 8) | 1;
+            bits->buffer++;
+            bits->length--;
+        }
+
+        if (bits->current & 0x8000)
+        {
+            p += 3;
+        }
+        else
+        {
+            p = table + (*(p + 2) | (*(p + 1) << 8));
+        }
+
+        bits->current <<= 1;
+    }
+
+    if (p + 1 < table + table_size && *(p + 1))
+    {
+        /* FIXME: Whats the meaning of *p? */
+        const BYTE *q = p + 1;
+        while (q < table + table_size && *q) q++;
+        return (q < table + table_size) ? (const char *)(p + 1) : NULL;
+    }
+
+    return NULL;
+}
+
+static const TLBString *decode_string(const BYTE *table, const char *stream, 
DWORD stream_length, ITypeLibImpl *lib)
+{
+    DWORD buf_size, table_size;
+    const char *p;
+    struct bitstream bits;
+    BSTR buf;
+    TLBString *tlbstr;
+
+    if (!stream_length) return NULL;
+
+    bits.buffer = (const BYTE *)stream;
+    bits.length = stream_length;
+    bits.current = 0;
+
+    buf_size = *(const WORD *)table;
+    table += sizeof(WORD);
+    table_size = *(const DWORD *)table;
+    table += sizeof(DWORD);
+
+    buf = SysAllocStringLen(NULL, buf_size);
+    buf[0] = 0;
+
+    while ((p = lookup_code(table, table_size, &bits)))
+    {
+        static const WCHAR spaceW[] = { ' ',0 };
+        if (buf[0]) strcatW(buf, spaceW);
+        MultiByteToWideChar(CP_ACP, 0, p, -1, buf + strlenW(buf), buf_size - 
strlenW(buf));
+    }
+
+    tlbstr = TLB_append_str(&lib->string_list, buf);
+    SysFreeString(buf);
+
+    return tlbstr;
+}
+
 static WORD SLTG_ReadString(const char *ptr, const TLBString **pStr, 
ITypeLibImpl *lib)
 {
     WORD bytelen;
@@ -3992,7 +4087,7 @@ static char *SLTG_DoImpls(char *pBlk, ITypeInfoImpl *pTI,
 }
 
 static void SLTG_DoVars(char *pBlk, char *pFirstItem, ITypeInfoImpl *pTI, 
unsigned short cVars,
-                       const char *pNameTable, const sltg_ref_lookup_t 
*ref_lookup)
+                       const char *pNameTable, const sltg_ref_lookup_t 
*ref_lookup, const BYTE *hlp_strings)
 {
   TLBVarDesc *pVarDesc;
   const TLBString *prevName = NULL;
@@ -4022,6 +4117,12 @@ static void SLTG_DoVars(char *pBlk, char *pFirstItem, 
ITypeInfoImpl *pTI, unsign
       TRACE_(typelib)("byte_offs = 0x%x\n", pItem->byte_offs);
       TRACE_(typelib)("memid = 0x%x\n", pItem->memid);
 
+      if (pItem->helpstring != 0xffff)
+      {
+          pVarDesc->HelpString = decode_string(hlp_strings, pBlk + 
pItem->helpstring, pNameTable - pBlk, pTI->pTypeLib);
+          TRACE_(typelib)("helpstring = %s\n", 
debugstr_w(pVarDesc->HelpString->str));
+      }
+
       if(pItem->flags & 0x02)
          pType = &pItem->type;
       else
@@ -4103,7 +4204,8 @@ static void SLTG_DoVars(char *pBlk, char *pFirstItem, 
ITypeInfoImpl *pTI, unsign
 }
 
 static void SLTG_DoFuncs(char *pBlk, char *pFirstItem, ITypeInfoImpl *pTI,
-                        unsigned short cFuncs, char *pNameTable, const 
sltg_ref_lookup_t *ref_lookup)
+                        unsigned short cFuncs, char *pNameTable, const 
sltg_ref_lookup_t *ref_lookup,
+                        const BYTE *hlp_strings)
 {
     SLTG_Function *pFunc;
     unsigned short i;
@@ -4140,6 +4242,8 @@ static void SLTG_DoFuncs(char *pBlk, char *pFirstItem, 
ITypeInfoImpl *pTI,
        pFuncDesc->funcdesc.cParams = pFunc->nacc >> 3;
        pFuncDesc->funcdesc.cParamsOpt = (pFunc->retnextopt & 0x7e) >> 1;
        pFuncDesc->funcdesc.oVft = pFunc->vtblpos & ~1;
+        if (pFunc->helpstring != 0xffff)
+            pFuncDesc->HelpString = decode_string(hlp_strings, pBlk + 
pFunc->helpstring, pNameTable - pBlk, pTI->pTypeLib);
 
        if(pFunc->magic & SLTG_FUNCTION_FLAGS_PRESENT)
            pFuncDesc->funcdesc.wFuncFlags = pFunc->funcflags;
@@ -4158,7 +4262,7 @@ static void SLTG_DoFuncs(char *pBlk, char *pFirstItem, 
ITypeInfoImpl *pTI,
        pArg = (WORD*)(pBlk + pFunc->arg_off);
 
        for(param = 0; param < pFuncDesc->funcdesc.cParams; param++) {
-           char *paramName = pNameTable + *pArg;
+           char *paramName = pNameTable + (*pArg & ~1);
            BOOL HaveOffs;
            /* If arg type follows then paramName points to the 2nd
               letter of the name, else the next WORD is an offset to
@@ -4169,26 +4273,21 @@ static void SLTG_DoFuncs(char *pBlk, char *pFirstItem, 
ITypeInfoImpl *pTI,
               meaning that the next WORD is the type, the latter
               meaning that the next WORD is an offset to the type. */
 
-           HaveOffs = FALSE;
-           if(*pArg == 0xffff)
-               paramName = NULL;
-           else if(*pArg == 0xfffe) {
+           if(*pArg == 0xffff || *pArg == 0xfffe)
                paramName = NULL;
-               HaveOffs = TRUE;
-           }
-           else if(paramName[-1] && !isalnum(paramName[-1]))
-               HaveOffs = TRUE;
 
+           HaveOffs = !(*pArg & 1);
            pArg++;
 
+            TRACE_(typelib)("param %d: paramName %s, *pArg %#x\n",
+                param, debugstr_a(paramName), *pArg);
+
            if(HaveOffs) { /* the next word is an offset to type */
                pType = (WORD*)(pBlk + *pArg);
                SLTG_DoElem(pType, pBlk,
                            &pFuncDesc->funcdesc.lprgelemdescParam[param], 
ref_lookup);
                pArg++;
            } else {
-               if(paramName)
-                 paramName--;
                pArg = SLTG_DoElem(pArg, pBlk,
                                    
&pFuncDesc->funcdesc.lprgelemdescParam[param], ref_lookup);
            }
@@ -4232,7 +4331,7 @@ static void SLTG_ProcessCoClass(char *pBlk, ITypeInfoImpl 
*pTI,
 
 static void SLTG_ProcessInterface(char *pBlk, ITypeInfoImpl *pTI,
                                  char *pNameTable, SLTG_TypeInfoHeader 
*pTIHeader,
-                                 const SLTG_TypeInfoTail *pTITail)
+                                 const SLTG_TypeInfoTail *pTITail, const BYTE 
*hlp_strings)
 {
     char *pFirstItem;
     sltg_ref_lookup_t *ref_lookup = NULL;
@@ -4249,7 +4348,7 @@ static void SLTG_ProcessInterface(char *pBlk, 
ITypeInfoImpl *pTI,
     }
 
     if (pTITail->funcs_off != 0xffff)
-        SLTG_DoFuncs(pBlk, pBlk + pTITail->funcs_off, pTI, pTITail->cFuncs, 
pNameTable, ref_lookup);
+        SLTG_DoFuncs(pBlk, pBlk + pTITail->funcs_off, pTI, pTITail->cFuncs, 
pNameTable, ref_lookup, hlp_strings);
 
     heap_free(ref_lookup);
 
@@ -4259,9 +4358,9 @@ static void SLTG_ProcessInterface(char *pBlk, 
ITypeInfoImpl *pTI,
 
 static void SLTG_ProcessRecord(char *pBlk, ITypeInfoImpl *pTI,
                               const char *pNameTable, SLTG_TypeInfoHeader 
*pTIHeader,
-                              const SLTG_TypeInfoTail *pTITail)
+                              const SLTG_TypeInfoTail *pTITail, const BYTE 
*hlp_strings)
 {
-  SLTG_DoVars(pBlk, pBlk + pTITail->vars_off, pTI, pTITail->cVars, pNameTable, 
NULL);
+  SLTG_DoVars(pBlk, pBlk + pTITail->vars_off, pTI, pTITail->cVars, pNameTable, 
NULL, hlp_strings);
 }
 
 static void SLTG_ProcessAlias(char *pBlk, ITypeInfoImpl *pTI,
@@ -4294,7 +4393,7 @@ static void SLTG_ProcessAlias(char *pBlk, ITypeInfoImpl 
*pTI,
 
 static void SLTG_ProcessDispatch(char *pBlk, ITypeInfoImpl *pTI,
                                 char *pNameTable, SLTG_TypeInfoHeader 
*pTIHeader,
-                                const SLTG_TypeInfoTail *pTITail)
+                                const SLTG_TypeInfoTail *pTITail, const BYTE 
*hlp_strings)
 {
   sltg_ref_lookup_t *ref_lookup = NULL;
   if (pTIHeader->href_table != 0xffffffff)
@@ -4302,10 +4401,10 @@ static void SLTG_ProcessDispatch(char *pBlk, 
ITypeInfoImpl *pTI,
                                   pNameTable);
 
   if (pTITail->vars_off != 0xffff)
-    SLTG_DoVars(pBlk, pBlk + pTITail->vars_off, pTI, pTITail->cVars, 
pNameTable, ref_lookup);
+    SLTG_DoVars(pBlk, pBlk + pTITail->vars_off, pTI, pTITail->cVars, 
pNameTable, ref_lookup, hlp_strings);
 
   if (pTITail->funcs_off != 0xffff)
-    SLTG_DoFuncs(pBlk, pBlk + pTITail->funcs_off, pTI, pTITail->cFuncs, 
pNameTable, ref_lookup);
+    SLTG_DoFuncs(pBlk, pBlk + pTITail->funcs_off, pTI, pTITail->cFuncs, 
pNameTable, ref_lookup, hlp_strings);
 
   if (pTITail->impls_off != 0xffff)
     SLTG_DoImpls(pBlk + pTITail->impls_off, pTI, FALSE, ref_lookup);
@@ -4322,14 +4421,14 @@ static void SLTG_ProcessDispatch(char *pBlk, 
ITypeInfoImpl *pTI,
 
 static void SLTG_ProcessEnum(char *pBlk, ITypeInfoImpl *pTI,
                             const char *pNameTable, SLTG_TypeInfoHeader 
*pTIHeader,
-                            const SLTG_TypeInfoTail *pTITail)
+                            const SLTG_TypeInfoTail *pTITail, const BYTE 
*hlp_strings)
 {
-  SLTG_DoVars(pBlk, pBlk + pTITail->vars_off, pTI, pTITail->cVars, pNameTable, 
NULL);
+  SLTG_DoVars(pBlk, pBlk + pTITail->vars_off, pTI, pTITail->cVars, pNameTable, 
NULL, hlp_strings);
 }
 
 static void SLTG_ProcessModule(char *pBlk, ITypeInfoImpl *pTI,
                               char *pNameTable, SLTG_TypeInfoHeader *pTIHeader,
-                              const SLTG_TypeInfoTail *pTITail)
+                              const SLTG_TypeInfoTail *pTITail, const BYTE 
*hlp_strings)
 {
   sltg_ref_lookup_t *ref_lookup = NULL;
   if (pTIHeader->href_table != 0xffffffff)
@@ -4337,10 +4436,10 @@ static void SLTG_ProcessModule(char *pBlk, 
ITypeInfoImpl *pTI,
                                   pNameTable);
 
   if (pTITail->vars_off != 0xffff)
-    SLTG_DoVars(pBlk, pBlk + pTITail->vars_off, pTI, pTITail->cVars, 
pNameTable, ref_lookup);
+    SLTG_DoVars(pBlk, pBlk + pTITail->vars_off, pTI, pTITail->cVars, 
pNameTable, ref_lookup, hlp_strings);
 
   if (pTITail->funcs_off != 0xffff)
-    SLTG_DoFuncs(pBlk, pBlk + pTITail->funcs_off, pTI, pTITail->cFuncs, 
pNameTable, ref_lookup);
+    SLTG_DoFuncs(pBlk, pBlk + pTITail->funcs_off, pTI, pTITail->cFuncs, 
pNameTable, ref_lookup, hlp_strings);
   heap_free(ref_lookup);
   if (TRACE_ON(typelib))
     dump_TypeInfo(pTI);
@@ -4349,17 +4448,17 @@ static void SLTG_ProcessModule(char *pBlk, 
ITypeInfoImpl *pTI,
 /* Because SLTG_OtherTypeInfo is such a painful struct, we make a more
    manageable copy of it into this */
 typedef struct {
-  WORD small_no;
   char *index_name;
   char *other_name;
   WORD res1a;
   WORD name_offs;
-  WORD more_bytes;
+  WORD hlpstr_len;
   char *extra;
   WORD res20;
   DWORD helpcontext;
   WORD res26;
   GUID uuid;
+  WORD typekind;
 } SLTG_InternalOtherTypeInfo;
 
 /****************************************************************************
@@ -4378,8 +4477,8 @@ static ITypeLib2* ITypeLib2_Constructor_SLTG(LPVOID pLib, 
DWORD dwTLBLength)
     LPVOID pBlk, pFirstBlk;
     SLTG_LibBlk *pLibBlk;
     SLTG_InternalOtherTypeInfo *pOtherTypeInfoBlks;
-    char *pAfterOTIBlks = NULL;
     char *pNameTable, *ptr;
+    const BYTE *hlp_strings;
     int i;
     DWORD len, order;
     ITypeInfoImpl **ppTypeInfoImpl;
@@ -4445,53 +4544,55 @@ static ITypeLib2* ITypeLib2_Constructor_SLTG(LPVOID 
pLib, DWORD dwTLBLength)
     len += 0x40;
 
     /* And now TypeInfoCount of SLTG_OtherTypeInfo */
+    pTypeLibImpl->TypeInfoCount = *(WORD *)((char *)pLibBlk + len);
+    len += sizeof(WORD);
 
     pOtherTypeInfoBlks = heap_alloc_zero(sizeof(*pOtherTypeInfoBlks) * 
pTypeLibImpl->TypeInfoCount);
 
-
     ptr = (char*)pLibBlk + len;
 
     for(i = 0; i < pTypeLibImpl->TypeInfoCount; i++) {
        WORD w, extra;
        len = 0;
 
-       pOtherTypeInfoBlks[i].small_no = *(WORD*)ptr;
-
-       w = *(WORD*)(ptr + 2);
+       w = *(WORD*)ptr;
        if(w != 0xffff) {
            len += w;
            pOtherTypeInfoBlks[i].index_name = heap_alloc(w+1);
-           memcpy(pOtherTypeInfoBlks[i].index_name, ptr + 4, w);
+           memcpy(pOtherTypeInfoBlks[i].index_name, ptr + 2, w);
            pOtherTypeInfoBlks[i].index_name[w] = '\0';
        }
-       w = *(WORD*)(ptr + 4 + len);
+       w = *(WORD*)(ptr + 2 + len);
        if(w != 0xffff) {
-           TRACE_(typelib)("\twith %s\n", debugstr_an(ptr + 6 + len, w));
-           len += w;
+           TRACE_(typelib)("\twith %s\n", debugstr_an(ptr + 4 + len, w));
            pOtherTypeInfoBlks[i].other_name = heap_alloc(w+1);
-           memcpy(pOtherTypeInfoBlks[i].other_name, ptr + 6 + len, w);
+           memcpy(pOtherTypeInfoBlks[i].other_name, ptr + 4 + len, w);
            pOtherTypeInfoBlks[i].other_name[w] = '\0';
+           len += w;
        }
-       pOtherTypeInfoBlks[i].res1a = *(WORD*)(ptr + len + 6);
-       pOtherTypeInfoBlks[i].name_offs = *(WORD*)(ptr + len + 8);
-       extra = pOtherTypeInfoBlks[i].more_bytes = *(WORD*)(ptr + 10 + len);
+       pOtherTypeInfoBlks[i].res1a = *(WORD*)(ptr + 4 + len);
+       pOtherTypeInfoBlks[i].name_offs = *(WORD*)(ptr + 6 + len);
+       extra = pOtherTypeInfoBlks[i].hlpstr_len = *(WORD*)(ptr + 8 + len);
        if(extra) {
            pOtherTypeInfoBlks[i].extra = heap_alloc(extra);
-           memcpy(pOtherTypeInfoBlks[i].extra, ptr + 12, extra);
+           memcpy(pOtherTypeInfoBlks[i].extra, ptr + 10 + len, extra);
            len += extra;
        }
-       pOtherTypeInfoBlks[i].res20 = *(WORD*)(ptr + 12 + len);
-       pOtherTypeInfoBlks[i].helpcontext = *(DWORD*)(ptr + 14 + len);
-       pOtherTypeInfoBlks[i].res26 = *(WORD*)(ptr + 18 + len);
-       memcpy(&pOtherTypeInfoBlks[i].uuid, ptr + 20 + len, sizeof(GUID));
+       pOtherTypeInfoBlks[i].res20 = *(WORD*)(ptr + 10 + len);
+       pOtherTypeInfoBlks[i].helpcontext = *(DWORD*)(ptr + 12 + len);
+       pOtherTypeInfoBlks[i].res26 = *(WORD*)(ptr + 16 + len);
+       memcpy(&pOtherTypeInfoBlks[i].uuid, ptr + 18 + len, sizeof(GUID));
+       pOtherTypeInfoBlks[i].typekind = *(WORD*)(ptr + 18 + sizeof(GUID) + 
len);
        len += sizeof(SLTG_OtherTypeInfo);
        ptr += len;
     }
 
-    pAfterOTIBlks = ptr;
+    /* Get the next DWORD */
+    len = *(DWORD*)ptr;
 
-    /* Skip this WORD and get the next DWORD */
-    len = *(DWORD*)(pAfterOTIBlks + 2);
+    hlp_strings = (const BYTE *)ptr + sizeof(DWORD);
+    TRACE("max help string length %#x, help strings length %#x\n",
+        *(WORD *)hlp_strings, *(DWORD *)(hlp_strings + 2));
 
     /* Now add this to pLibBLk look at what we're pointing at and
        possibly add 0x20, then add 0x216, sprinkle a bit a magic
@@ -4557,6 +4658,7 @@ static ITypeLib2* ITypeLib2_Constructor_SLTG(LPVOID pLib, 
DWORD dwTLBLength)
       (*ppTypeInfoImpl)->index = i;
       (*ppTypeInfoImpl)->Name = SLTG_ReadName(pNameTable, 
pOtherTypeInfoBlks[i].name_offs, pTypeLibImpl);
       (*ppTypeInfoImpl)->dwHelpContext = pOtherTypeInfoBlks[i].helpcontext;
+      (*ppTypeInfoImpl)->DocString = decode_string(hlp_strings, 
pOtherTypeInfoBlks[i].extra, pOtherTypeInfoBlks[i].hlpstr_len, pTypeLibImpl);
       (*ppTypeInfoImpl)->guid = TLB_append_guid(&pTypeLibImpl->guid_list, 
&pOtherTypeInfoBlks[i].uuid, 2);
       (*ppTypeInfoImpl)->typeattr.typekind = pTIHeader->typekind;
       (*ppTypeInfoImpl)->typeattr.wMajorVerNum = pTIHeader->major_version;
@@ -4589,17 +4691,17 @@ static ITypeLib2* ITypeLib2_Constructor_SLTG(LPVOID 
pLib, DWORD dwTLBLength)
       switch(pTIHeader->typekind) {
       case TKIND_ENUM:
        SLTG_ProcessEnum((char *)(pMemHeader + 1), *ppTypeInfoImpl, pNameTable,
-                         pTIHeader, pTITail);
+                         pTIHeader, pTITail, hlp_strings);
        break;
 
       case TKIND_RECORD:
        SLTG_ProcessRecord((char *)(pMemHeader + 1), *ppTypeInfoImpl, 
pNameTable,
-                           pTIHeader, pTITail);
+                           pTIHeader, pTITail, hlp_strings);
        break;
 
       case TKIND_INTERFACE:
        SLTG_ProcessInterface((char *)(pMemHeader + 1), *ppTypeInfoImpl, 
pNameTable,
-                              pTIHeader, pTITail);
+                              pTIHeader, pTITail, hlp_strings);
        break;
 
       case TKIND_COCLASS:
@@ -4614,12 +4716,12 @@ static ITypeLib2* ITypeLib2_Constructor_SLTG(LPVOID 
pLib, DWORD dwTLBLength)
 
       case TKIND_DISPATCH:
        SLTG_ProcessDispatch((char *)(pMemHeader + 1), *ppTypeInfoImpl, 
pNameTable,
-                             pTIHeader, pTITail);
+                             pTIHeader, pTITail, hlp_strings);
        break;
 
       case TKIND_MODULE:
        SLTG_ProcessModule((char *)(pMemHeader + 1), *ppTypeInfoImpl, 
pNameTable,
-                           pTIHeader, pTITail);
+                           pTIHeader, pTITail, hlp_strings);
        break;
 
       default:
@@ -6328,15 +6430,15 @@ static double (* const 
call_double_method)(void*,int,const DWORD*,int*) = (void
  * 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 *args) {
+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("%08x,",args[i]);
+       for (i=0;i<min(nrargs,30);i++) TRACE("%08lx,",args[i]);
        if (nrargs > 30) TRACE("...");
        TRACE(")\n");
     }
@@ -6344,7 +6446,7 @@ _invoke(FARPROC func,CALLCONV callconv, int nrargs, DWORD 
*args) {
     switch (callconv) {
     case CC_STDCALL:
     case CC_CDECL:
-        res = call_method( func, nrargs, args, &stack_offset );
+        res = call_method(func, nrargs, (DWORD *)args, &stack_offset);
        break;
     default:
        FIXME("unsupported calling convention %d\n",callconv);
@@ -6401,43 +6503,33 @@ __ASM_GLOBAL_FUNC( call_method,
 /* same function but returning floating point */
 static double (CDECL * const call_double_method)(void*,int,const DWORD_PTR*) = 
(void *)call_method;
 
-#elif defined(__arm__)
-
-extern LONGLONG CDECL call_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
-                     * r2 = *stk_args (pointer to 'nb_stk_args' DWORD values 
to push on stack)
-                     * r3 = *reg_args (pointer to 8, 64-bit d0-d7 (double) 
values OR as 16, 32-bit s0-s15 (float) values, followed by 4, 32-bit (DWORD) 
r0-r3 values)
-                     */
-
-                    "push {fp, lr}\n\t"             /* Save frame pointer and 
return address (stack still aligned to 8 bytes) */
-                    "mov fp, sp\n\t"                /* Save stack pointer as 
our frame for cleaning the stack on return */
-
-                    "lsls r1, r1, #2\n\t"           /* r1 = nb_stk_args * 
sizeof(DWORD) */
-                    "beq 1f\n\t"                    /* Skip allocation if no 
stack args */
-                    "add r2, r2, r1\n"              /* Calculate ending 
address of incoming stack data */
-                    "2:\tldr ip, [r2, #-4]!\n\t"    /* Get next value */
-                    "str ip, [sp, #-4]!\n\t"        /* Push it on the stack */
-                    "subs r1, r1, #4\n\t"           /* Decrement count */
-                    "bgt 2b\n\t"                    /* Loop till done */
-
-                    "1:\n\t"
-#ifndef __SOFTFP__
-                    "vldm r3!, {s0-s15}\n\t"        /* Load the s0-s15/d0-d7 
arguments */
-#endif
-                    "mov ip, r0\n\t"                /* Save the function call 
address to ip before we nuke r0 with arguments to pass */
-                    "ldm r3, {r0-r3}\n\t"           /* Load the r0-r3 
arguments */
+DWORD _invoke(FARPROC func, CALLCONV callconv, int nrargs, DWORD_PTR *args)
+{
+    DWORD res;
 
-                    "blx ip\n\t"                    /* Call the target 
function */
+    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");
+    }
 
-                    "mov sp, fp\n\t"                /* Clean the stack using 
fp */
-                    "pop {fp, pc}\n\t"              /* Restore fp and return */
-                )
+    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;
+    }
 
-/* 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;
+    TRACE("returns %08x\n", res);
+    return res;
+}
 
 #endif  /* __x86_64__ */
 
@@ -6470,6 +6562,7 @@ static HRESULT userdefined_to_variantvt(ITypeInfo *tinfo, 
const TYPEDESC *tdesc,
         break;
 
     case TKIND_ALIAS:
+        tdesc = &tattr->tdescAlias;
         hr = typedescvt_to_variantvt(tinfo2, &tattr->tdescAlias, vt);
         break;
 
@@ -6575,13 +6668,13 @@ static HRESULT typedescvt_to_variantvt(ITypeInfo 
*tinfo, const TYPEDESC *tdesc,
     return hr;
 }
 
-static HRESULT get_iface_guid(ITypeInfo *tinfo, const TYPEDESC *tdesc, GUID 
*guid)
+static HRESULT get_iface_guid(ITypeInfo *tinfo, HREFTYPE href, GUID *guid)
 {
     ITypeInfo *tinfo2;
     TYPEATTR *tattr;
     HRESULT hres;
 
-    hres = ITypeInfo_GetRefTypeInfo(tinfo, tdesc->u.hreftype, &tinfo2);
+    hres = ITypeInfo_GetRefTypeInfo(tinfo, href, &tinfo2);
     if(FAILED(hres))
         return hres;
 
@@ -6593,7 +6686,7 @@ static HRESULT get_iface_guid(ITypeInfo *tinfo, const 
TYPEDESC *tdesc, GUID *gui
 
     switch(tattr->typekind) {
     case TKIND_ALIAS:
-        hres = get_iface_guid(tinfo2, &tattr->tdescAlias, guid);
+        hres = get_iface_guid(tinfo2, tattr->tdescAlias.u.hreftype, guid);
         break;
 
     case TKIND_INTERFACE:
@@ -6601,6 +6694,21 @@ static HRESULT get_iface_guid(ITypeInfo *tinfo, const 
TYPEDESC *tdesc, GUID *gui
         *guid = tattr->guid;
         break;
 
+    case TKIND_COCLASS: {
+        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)) 
break;
+
+        if(i < tattr->cImplTypes) {
+            hres = ITypeInfo_GetRefTypeOfImplType(tinfo2, i, &href);
+            if(SUCCEEDED(hres)) hres = get_iface_guid(tinfo2, href, guid);
+        } else hres = E_UNEXPECTED;
+        break;
+    }
+
     default:
         ERR("Unexpected typekind %d\n", tattr->typekind);
         hres = E_UNEXPECTED;
@@ -6728,8 +6836,17 @@ DispCallFunc(
         break;
     case VT_DECIMAL:
     case VT_VARIANT:
-        args[0] = (DWORD)pvargResult;  /* arg 0 is a pointer to the result */
-        call_method( func, argspos, args, &stack_offset );
+        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 );
+        }
         break;
     case VT_I8:
     case VT_UI8:
@@ -6814,8 +6931,17 @@ DispCallFunc(
         break;
     case VT_DECIMAL:
     case VT_VARIANT:
-        args[0] = (DWORD_PTR)pvargResult;  /* arg 0 is a pointer to the result 
*/
-        call_method( func, argspos, args );
+        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 );
+        }
         break;
     case VT_HRESULT:
         WARN("invalid return type %u\n", vtReturn);
@@ -6830,182 +6956,6 @@ DispCallFunc(
     TRACE("retval: %s\n", debugstr_variant(pvargResult));
     return S_OK;
 
-#elif defined(__arm__)
-    int argspos;
-    void *func;
-    UINT i;
-    DWORD *args;
-    struct {
-#ifndef __SOFTFP__
-        union {
-            float s[16];
-            double d[8];
-        } sd;
-#endif
-        DWORD r[4];
-    } regs;
-    int rcount;     /* 32-bit register index count */
-#ifndef __SOFTFP__
-    int scount = 0; /* single-precision float register index count */
-    int dcount = 0; /* double-precision float register index count */
-#endif
-
-    TRACE("(%p, %ld, %d, %d, %d, %p, %p, %p (vt=%d))\n",
-        pvInstance, oVft, cc, vtReturn, cActuals, prgvt, prgpvarg, 
pvargResult, V_VT(pvargResult));
-
-    if (cc != CC_STDCALL && cc != CC_CDECL)
-    {
-        FIXME("unsupported calling convention %d\n",cc);
-        return E_INVALIDARG;
-    }
-
-    argspos = 0;
-    rcount = 0;
-
-    /* Determine if we need to pass a pointer for the return value as arg 0.  
If so, do that */
-    /*  first as it will need to be in the 'r' registers:                      
              */
-    switch (vtReturn)
-    {
-    case VT_DECIMAL:
-    case VT_VARIANT:
-        regs.r[rcount++] = (DWORD)pvargResult;  /* arg 0 is a pointer to the 
result */
-        break;
-    case VT_HRESULT:
-        WARN("invalid return type %u\n", vtReturn);
-        return E_INVALIDARG;
-    default:                    /* And all others are in 'r', 's', or 'd' 
registers or have no return value */
-        break;
-    }
-
-    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 );
-
-    for (i = 0; i < cActuals; i++)
-    {
-        VARIANT *arg = prgpvarg[i];
-        DWORD *pdwarg = (DWORD *)(arg);     /* a reinterpret_cast of the 
variant, used for copying structures when they are split between registers and 
stack */
-        int ntemp;              /* Used for counting words split between 
registers and stack */
-
-        switch (prgvt[i])
-        {
-        case VT_EMPTY:
-            break;
-        case VT_R8:             /* these must be 8-byte aligned, and put in 
'd' regs or stack, as they are double-floats */
-        case VT_DATE:
-#ifndef __SOFTFP__
-            dcount = max( (scount + 1) / 2, dcount );
-            if (dcount < 8)
-            {
-                regs.sd.d[dcount++] = V_R8(arg);
-            }
-            else
-            {
-                argspos += (argspos % 2);   /* align argspos to 8-bytes */
-                memcpy( &args[argspos], &V_R8(arg), sizeof(V_R8(arg)) );
-                argspos += sizeof(V_R8(arg)) / sizeof(DWORD);
-            }
-            break;
-#endif
-        case VT_I8:             /* these must be 8-byte aligned, and put in 
'r' regs or stack, as they are long-longs */
-        case VT_UI8:
-        case VT_CY:
-            if (rcount < 3)
-            {
-                rcount += (rcount % 2);     /* align rcount to 8-byte register 
pair */
-                memcpy( &regs.r[rcount], &V_UI8(arg), sizeof(V_UI8(arg)) );
-                rcount += sizeof(V_UI8(arg)) / sizeof(DWORD);
-            }
-            else
-            {
-                rcount = 4;                 /* Make sure we flag that all 'r' 
regs are full */
-                argspos += (argspos % 2);   /* align argspos to 8-bytes */
-                memcpy( &args[argspos], &V_UI8(arg), sizeof(V_UI8(arg)) );
-                argspos += sizeof(V_UI8(arg)) / sizeof(DWORD);
-            }
-            break;
-        case VT_DECIMAL:        /* these structures are 8-byte aligned, and 
put in 'r' regs or stack, can be split between the two */
-        case VT_VARIANT:
-            /* 8-byte align 'r' and/or stack: */
-            if (rcount < 3)
-                rcount += (rcount % 2);
-            else
-            {
-                rcount = 4;
-                argspos += (argspos % 2);
-            }
-            ntemp = sizeof(*arg) / sizeof(DWORD);
-            while (ntemp > 0)
-            {
-                if (rcount < 4)
-                    regs.r[rcount++] = *pdwarg++;
-                else
-                    args[argspos++] = *pdwarg++;
-                --ntemp;
-            }
-            break;
-        case VT_BOOL:  /* VT_BOOL is 16-bit but BOOL is 32-bit, needs to be 
extended */
-            if (rcount < 4)
-                regs.r[rcount++] = V_BOOL(arg);
-            else
-                args[argspos++] = V_BOOL(arg);
-            break;
-        case VT_R4:             /* these must be 4-byte aligned, and put in 
's' regs or stack, as they are single-floats */
-#ifndef __SOFTFP__
-            if (!(scount % 2)) scount = max( scount, dcount * 2 );
-            if (scount < 16)
-                regs.sd.s[scount++] = V_R4(arg);
-            else
-                args[argspos++] = V_UI4(arg);
-            break;
-#endif
-        default:
-            if (rcount < 4)
-                regs.r[rcount++] = V_UI4(arg);
-            else
-                args[argspos++] = V_UI4(arg);
-            break;
-        }
-        TRACE("arg %u: type %s %s\n", i, debugstr_vt(prgvt[i]), 
debugstr_variant(arg));
-    }
-
-    argspos += (argspos % 2);   /* Make sure stack function alignment is 
8-byte */
-
-    switch (vtReturn)
-    {
-    case VT_EMPTY:      /* EMPTY = no return value */
-    case VT_DECIMAL:    /* DECIMAL and VARIANT already have a pointer argument 
passed (see above) */
-    case VT_VARIANT:
-        call_method( func, argspos, args, (DWORD*)&regs );
-        break;
-    case VT_R4:
-        V_R4(pvargResult) = call_float_method( func, argspos, args, 
(DWORD*)&regs );
-        break;
-    case VT_R8:
-    case VT_DATE:
-        V_R8(pvargResult) = call_double_method( func, argspos, args, 
(DWORD*)&regs );
-        break;
-    case VT_I8:
-    case VT_UI8:
-    case VT_CY:
-        V_UI8(pvargResult) = call_method( func, argspos, args, (DWORD*)&regs );
-        break;
-    default:
-        V_UI4(pvargResult) = call_method( func, argspos, args, (DWORD*)&regs );
-        break;
-    }
-    heap_free( args );
-    if (vtReturn != VT_VARIANT) V_VT(pvargResult) = vtReturn;
-    TRACE("retval: %s\n", debugstr_variant(pvargResult));
-    return S_OK;
-
 #else
     FIXME( "(%p, %ld, %d, %d, %d, %p, %p, %p (vt=%d)): not implemented for 
this CPU\n",
            pvInstance, oVft, cc, vtReturn, cActuals, prgvt, prgpvarg, 
pvargResult, V_VT(pvargResult));
@@ -7099,6 +7049,7 @@ static HRESULT WINAPI ITypeInfo_fnInvoke(
             UINT cNamedArgs = pDispParams->cNamedArgs;
             DISPID *rgdispidNamedArgs = pDispParams->rgdispidNamedArgs;
             UINT vargs_converted=0;
+            ULONG_PTR offset;
 
             hres = S_OK;
 
@@ -7196,7 +7147,8 @@ static HRESULT WINAPI ITypeInfo_fnInvoke(
                         break;
                     }
                 }
-                else if (src_arg)
+                else if (src_arg && !((wParamFlags & PARAMFLAG_FOPT) &&
+                         V_VT(src_arg) == VT_ERROR && V_ERROR(src_arg) == 
DISP_E_PARAMNOTFOUND))
                 {
                     TRACE("%s\n", debugstr_variant(src_arg));
 
@@ -7295,7 +7247,10 @@ static HRESULT WINAPI ITypeInfo_fnInvoke(
                         IUnknown *userdefined_iface;
                         GUID guid;
 
-                        hres = get_iface_guid((ITypeInfo*)iface, tdesc->vt == 
VT_PTR ? tdesc->u.lptdesc : tdesc, &guid);
+                        if (tdesc->vt == VT_PTR)
+                            tdesc = tdesc->u.lptdesc;
+
+                        hres = get_iface_guid((ITypeInfo*)iface, 
tdesc->u.hreftype, &guid);
                         if(FAILED(hres))
                             break;
 
@@ -7343,7 +7298,11 @@ static HRESULT WINAPI ITypeInfo_fnInvoke(
                     break;
                 }
             }
-            if (FAILED(hres)) goto func_fail; /* FIXME: we don't free changed 
types here */
+            if (FAILED(hres))
+            {
+                ERR("failed: %08x\n", hres);
+                goto func_fail; /* FIXME: we don't free changed types here */
+            }
 
             /* VT_VOID is a special case for return types, so it is not
              * handled in the general function */
@@ -7356,7 +7315,16 @@ static HRESULT WINAPI ITypeInfo_fnInvoke(
                 if (FAILED(hres)) goto func_fail; /* FIXME: we don't free 
changed types here */
             }
 
-            hres = DispCallFunc(pIUnk, func_desc->oVft & 0xFFFC, 
func_desc->callconv,
+            offset = func_desc->oVft & 0xFFFC;
+#ifdef _WIN64
+            if (This->pTypeLib->syskind == SYS_WIN32)
+            {
+                offset *= 2;
+                TRACE("extended offset to %#lx for SYS_WIN32\n", offset);
+            }
+#endif
+            TRACE("func_desc->oVft %#x, offset %#lx\n", func_desc->oVft, 
offset);
+            hres = DispCallFunc(pIUnk, offset, func_desc->callconv,
                                 V_VT(&varresult), func_desc->cParams, rgvt,
                                 prgpvarg, &varresult);
 
@@ -7483,7 +7451,7 @@ static HRESULT WINAPI ITypeInfo_fnInvoke(
                      * pointer to be valid */
                     VariantInit(pVarResult);
                     hres = IDispatch_Invoke(pDispatch, DISPID_VALUE, &IID_NULL,
-                        GetSystemDefaultLCID(), wFlags,
+                        GetSystemDefaultLCID(), INVOKE_PROPERTYGET,
                         pDispParams, pVarResult, pExcepInfo, pArgErr);
                     IDispatch_Release(pDispatch);
                 }
diff --git a/dll/win32/oleaut32/typelib.h b/dll/win32/oleaut32/typelib.h
index 37561807f8..100e15a145 100644
--- a/dll/win32/oleaut32/typelib.h
+++ b/dll/win32/oleaut32/typelib.h
@@ -381,18 +381,18 @@ typedef struct {
 /* we then get 0x40 bytes worth of 0xffff or small numbers followed by
    nrOfFileBlks - 2 of these */
 typedef struct {
-       WORD small_no;
        SLTG_Name index_name; /* This refers to a name in the directory */
        SLTG_Name other_name; /* Another one of these weird names */
        WORD res1a;           /* 0xffff */
        WORD name_offs;       /* offset to name in name table */
-       WORD more_bytes;      /* if this is non-zero we get this many
+       WORD hlpstr_len;      /* if this is non-zero we get this many
                                 bytes before the next element, which seem
                                 to reference the docstring of the type ? */
        WORD res20;           /* 0xffff */
        DWORD helpcontext;
        WORD res26;           /* 0xffff */
         GUID uuid;
+        WORD typekind;
 } SLTG_OtherTypeInfo;
 
 /* Next we get WORD 0x0003 followed by a DWORD which if we add to
@@ -612,7 +612,7 @@ static inline BOOL heap_free( LPVOID mem )
 
 HRESULT ITypeInfoImpl_GetInternalFuncDesc( ITypeInfo *iface, UINT index, const 
FUNCDESC **ppFuncDesc ) DECLSPEC_HIDDEN;
 
-extern DWORD _invoke(FARPROC func,CALLCONV callconv, int nrargs, DWORD *args) 
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;
 
diff --git a/dll/win32/oleaut32/variant.c b/dll/win32/oleaut32/variant.c
index 3d0840e801..05818bcfd6 100644
--- a/dll/win32/oleaut32/variant.c
+++ b/dll/win32/oleaut32/variant.c
@@ -2145,7 +2145,7 @@ HRESULT WINAPI VarNumFromParseNum(NUMPARSE *pNumprs, BYTE 
*rgbDig,
         multiplier10, divisor10);
 
   if (dwVtBits & (INTEGER_VTBITS|VTBIT_DECIMAL) &&
-      (!fractionalDigits || !(dwVtBits & (REAL_VTBITS|VTBIT_DECIMAL))))
+      (!fractionalDigits || !(dwVtBits & 
(REAL_VTBITS|VTBIT_CY|VTBIT_DECIMAL))))
   {
     /* We have one or more integer output choices, and either:
      *  1) An integer input value, or
@@ -2259,7 +2259,7 @@ HRESULT WINAPI VarNumFromParseNum(NUMPARSE *pNumprs, BYTE 
*rgbDig,
           V_I8(pVarDst) = -ul64;
           return S_OK;
         }
-        else if ((dwVtBits & (REAL_VTBITS|VTBIT_DECIMAL)) == VTBIT_DECIMAL)
+        else if ((dwVtBits & REAL_VTBITS) == VTBIT_DECIMAL)
         {
           /* Decimal is only output choice left - fast path */
           V_VT(pVarDst) = VT_DECIMAL;
@@ -2321,7 +2321,7 @@ HRESULT WINAPI VarNumFromParseNum(NUMPARSE *pNumprs, BYTE 
*rgbDig,
         V_UI8(pVarDst) = ul64;
         return S_OK;
       }
-      else if ((dwVtBits & (REAL_VTBITS|VTBIT_DECIMAL)) == VTBIT_DECIMAL)
+      else if ((dwVtBits & REAL_VTBITS) == VTBIT_DECIMAL)
       {
         /* Decimal is only output choice left - fast path */
         V_VT(pVarDst) = VT_DECIMAL;
@@ -2376,8 +2376,8 @@ HRESULT WINAPI VarNumFromParseNum(NUMPARSE *pNumprs, BYTE 
*rgbDig,
     {
       if (whole < dblMinimums[10] && whole != 0)
       {
-        whole = 0; /* ignore underflow */
-        divisor10 = 0;
+        dwVtBits &= ~(VTBIT_R4|VTBIT_R8|VTBIT_CY); /* Underflow */
+        bOverflow = TRUE;
         break;
       }
       whole = whole / dblMultipliers[10];
@@ -2387,8 +2387,8 @@ HRESULT WINAPI VarNumFromParseNum(NUMPARSE *pNumprs, BYTE 
*rgbDig,
     {
       if (whole < dblMinimums[divisor10] && whole != 0)
       {
-        whole = 0; /* ignore underflow */
-        divisor10 = 0;
+        dwVtBits &= ~(VTBIT_R4|VTBIT_R8|VTBIT_CY); /* Underflow */
+        bOverflow = TRUE;
       }
       else
         whole = whole / dblMultipliers[divisor10];
diff --git a/dll/win32/oleaut32/vartype.c b/dll/win32/oleaut32/vartype.c
index 70b1b63dd9..3d07a277a4 100644
--- a/dll/win32/oleaut32/vartype.c
+++ b/dll/win32/oleaut32/vartype.c
@@ -5362,7 +5362,7 @@ static HRESULT VARIANT_DI_normalize(VARIANT_DI * val, int 
exponent2, BOOL isDoub
        end of the bit representation, down to the precision guaranteed by the
        floating point number. */
     if (isDouble) {
-        while (exponent10 < 0 && (val->bitsnum[2] != 0 || (val->bitsnum[1] & 
0xFFE00000) != 0)) {
+        while (exponent10 < 0 && (val->bitsnum[2] != 0 || (val->bitsnum[2] == 
0 && (val->bitsnum[1] & 0xFFE00000) != 0))) {
             int rem10;
 
             rem10 = VARIANT_int_divbychar(val->bitsnum, 3, 10);
diff --git a/media/doc/README.WINE b/media/doc/README.WINE
index 9bab464f27..5cafdae121 100644
--- a/media/doc/README.WINE
+++ b/media/doc/README.WINE
@@ -141,7 +141,7 @@ reactos/dll/win32/odbc32              # Synced to 
WineStaging-2.9. Depends on po
 reactos/dll/win32/odbccp32            # Synced to WineStaging-2.9
 reactos/dll/win32/ole32               # Synced to Wine-3.0
 reactos/dll/win32/oleacc              # Synced to WineStaging-2.9
-reactos/dll/win32/oleaut32            # Synced to Wine-3.0
+reactos/dll/win32/oleaut32            # Synced to WineStaging-2.16
 reactos/dll/win32/olecli32            # Synced to WineStaging-2.9
 reactos/dll/win32/oledlg              # Synced to WineStaging-2.9
 reactos/dll/win32/olepro32            # Synced to WineStaging-2.9

Reply via email to