[ros-diffs] [winesync] 27914: Autosyncing with Wine HEAD

winesync at svn.reactos.org winesync at svn.reactos.org
Fri Jul 27 11:59:17 CEST 2007


Author: winesync
Date: Fri Jul 27 13:59:17 2007
New Revision: 27914

URL: http://svn.reactos.org/svn/reactos?rev=27914&view=rev
Log:
Autosyncing with Wine HEAD

Modified:
    trunk/reactos/dll/win32/oleaut32/dispatch.c
    trunk/reactos/dll/win32/oleaut32/oleaut.c
    trunk/reactos/dll/win32/oleaut32/oleaut32_En.rc
    trunk/reactos/dll/win32/oleaut32/oleaut32_Ko.rc
    trunk/reactos/dll/win32/oleaut32/oleaut32_No.rc
    trunk/reactos/dll/win32/oleaut32/oleaut32_Pt.rc
    trunk/reactos/dll/win32/oleaut32/oleaut32_Sv.rc
    trunk/reactos/dll/win32/oleaut32/oleaut32_ros.diff
    trunk/reactos/dll/win32/oleaut32/olefont.c
    trunk/reactos/dll/win32/oleaut32/olepicture.c
    trunk/reactos/dll/win32/oleaut32/safearray.c
    trunk/reactos/dll/win32/oleaut32/tmarshal.c
    trunk/reactos/dll/win32/oleaut32/typelib.c
    trunk/reactos/dll/win32/oleaut32/typelib16.c
    trunk/reactos/dll/win32/oleaut32/typelib2.c
    trunk/reactos/dll/win32/oleaut32/usrmarshal.c
    trunk/reactos/dll/win32/oleaut32/variant.c
    trunk/reactos/dll/win32/oleaut32/vartype.c

Modified: trunk/reactos/dll/win32/oleaut32/dispatch.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/oleaut32/dispatch.c?rev=27914&r1=27913&r2=27914&view=diff
==============================================================================
--- trunk/reactos/dll/win32/oleaut32/dispatch.c (original)
+++ trunk/reactos/dll/win32/oleaut32/dispatch.c Fri Jul 27 13:59:17 2007
@@ -34,8 +34,6 @@
 #include "objbase.h"
 #include "oleauto.h"
 #include "winerror.h"
-#include "winreg.h"
-#include "winnls.h"         /* for PRIMARYLANGID */
 
 #include "wine/debug.h"
 

Modified: trunk/reactos/dll/win32/oleaut32/oleaut.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/oleaut32/oleaut.c?rev=27914&r1=27913&r2=27914&view=diff
==============================================================================
--- trunk/reactos/dll/win32/oleaut32/oleaut.c (original)
+++ trunk/reactos/dll/win32/oleaut32/oleaut.c Fri Jul 27 13:59:17 2007
@@ -266,7 +266,7 @@
      * string.
      */
     stringBuffer = (WCHAR*)newBuffer;
-    stringBuffer[len] = L'\0';
+    stringBuffer[len] = '\0';
 
     return (LPWSTR)stringBuffer;
 }
@@ -691,8 +691,8 @@
 
 extern HRESULT OLEAUTPS_DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv);
 
-extern void _get_STDFONT_CF(LPVOID);
-extern void _get_STDPIC_CF(LPVOID);
+extern void _get_STDFONT_CF(LPVOID *);
+extern void _get_STDPIC_CF(LPVOID *);
 
 static HRESULT WINAPI PSDispatchFacBuf_QueryInterface(IPSFactoryBuffer *iface, REFIID riid, void **ppv)
 {

Modified: trunk/reactos/dll/win32/oleaut32/oleaut32_En.rc
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/oleaut32/oleaut32_En.rc?rev=27914&r1=27913&r2=27914&view=diff
==============================================================================
--- trunk/reactos/dll/win32/oleaut32/oleaut32_En.rc (original)
+++ trunk/reactos/dll/win32/oleaut32/oleaut32_En.rc Fri Jul 27 13:59:17 2007
@@ -18,7 +18,7 @@
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
-LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+LANGUAGE LANG_ENGLISH, SUBLANG_DEFAULT
 
 STRINGTABLE DISCARDABLE
 {

Modified: trunk/reactos/dll/win32/oleaut32/oleaut32_Ko.rc
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/oleaut32/oleaut32_Ko.rc?rev=27914&r1=27913&r2=27914&view=diff
==============================================================================
--- trunk/reactos/dll/win32/oleaut32/oleaut32_Ko.rc (original)
+++ trunk/reactos/dll/win32/oleaut32/oleaut32_Ko.rc Fri Jul 27 13:59:17 2007
@@ -18,7 +18,7 @@
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
-LANGUAGE LANG_KOREAN, SUBLANG_DEFAULT
+LANGUAGE LANG_KOREAN, SUBLANG_NEUTRAL
 
 STRINGTABLE DISCARDABLE
 {

Modified: trunk/reactos/dll/win32/oleaut32/oleaut32_No.rc
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/oleaut32/oleaut32_No.rc?rev=27914&r1=27913&r2=27914&view=diff
==============================================================================
--- trunk/reactos/dll/win32/oleaut32/oleaut32_No.rc (original)
+++ trunk/reactos/dll/win32/oleaut32/oleaut32_No.rc Fri Jul 27 13:59:17 2007
@@ -18,7 +18,7 @@
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
-LANGUAGE LANG_NORWEGIAN, SUBLANG_NEUTRAL
+LANGUAGE LANG_NORWEGIAN, SUBLANG_NORWEGIAN_BOKMAL
 
 STRINGTABLE DISCARDABLE
 {

Modified: trunk/reactos/dll/win32/oleaut32/oleaut32_Pt.rc
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/oleaut32/oleaut32_Pt.rc?rev=27914&r1=27913&r2=27914&view=diff
==============================================================================
--- trunk/reactos/dll/win32/oleaut32/oleaut32_Pt.rc (original)
+++ trunk/reactos/dll/win32/oleaut32/oleaut32_Pt.rc Fri Jul 27 13:59:17 2007
@@ -18,7 +18,7 @@
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
-LANGUAGE LANG_PORTUGUESE, SUBLANG_NEUTRAL
+LANGUAGE LANG_PORTUGUESE, SUBLANG_PORTUGUESE_BRAZILIAN
 
 STRINGTABLE DISCARDABLE
 {

Modified: trunk/reactos/dll/win32/oleaut32/oleaut32_Sv.rc
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/oleaut32/oleaut32_Sv.rc?rev=27914&r1=27913&r2=27914&view=diff
==============================================================================
--- trunk/reactos/dll/win32/oleaut32/oleaut32_Sv.rc (original)
+++ trunk/reactos/dll/win32/oleaut32/oleaut32_Sv.rc Fri Jul 27 13:59:17 2007
@@ -18,7 +18,7 @@
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
-LANGUAGE LANG_SWEDISH, SUBLANG_NEUTRAL
+LANGUAGE LANG_SWEDISH, SUBLANG_DEFAULT
 
 STRINGTABLE DISCARDABLE
 {

Modified: trunk/reactos/dll/win32/oleaut32/oleaut32_ros.diff
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/oleaut32/oleaut32_ros.diff?rev=27914&r1=27913&r2=27914&view=diff
==============================================================================
--- trunk/reactos/dll/win32/oleaut32/oleaut32_ros.diff (original)
+++ trunk/reactos/dll/win32/oleaut32/oleaut32_ros.diff Fri Jul 27 13:59:17 2007
@@ -39,7 +39,7 @@
 --- oleaut32_Ja.rc	(revision 23782)
 +++ oleaut32_Ja.rc	(working copy)
 @@ -0,0 +1,11 @@
-+LANGUAGE LANG_JAPANESE, SUBLANG_NEUTRAL
++LANGUAGE LANG_JAPANESE, SUBLANG_DEFAULT
 +
 +STRINGTABLE DISCARDABLE
 +{
@@ -109,3 +109,15 @@
  
  /*
   * FIXME:
+Index: oleaut32.rbuild
+===================================================================
+--- oleaut32.rbuild	(revision 23782)
++++ oleaut32.rbuild	(working copy)
+@@ -20,6 +20,7 @@
+ 	<library>comctl32</library>
+ 	<library>urlmon</library>
+ 	<library>uuid</library>
++	<library>pseh</library>
+ 	<file>connpt.c</file>
+ 	<file>dispatch.c</file>
+ 	<file>hash.c</file>

Modified: trunk/reactos/dll/win32/oleaut32/olefont.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/oleaut32/olefont.c?rev=27914&r1=27913&r2=27914&view=diff
==============================================================================
--- trunk/reactos/dll/win32/oleaut32/olefont.c (original)
+++ trunk/reactos/dll/win32/oleaut32/olefont.c Fri Jul 27 13:59:17 2007
@@ -176,7 +176,7 @@
  * Prototypes for the implementation functions for the IFont
  * interface
  */
-static OLEFontImpl* OLEFontImpl_Construct(LPFONTDESC fontDesc);
+static OLEFontImpl* OLEFontImpl_Construct(const FONTDESC *fontDesc);
 static void         OLEFontImpl_Destroy(OLEFontImpl* fontDesc);
 static ULONG        WINAPI OLEFontImpl_AddRef(IFont* iface);
 
@@ -2201,7 +2201,7 @@
  * The caller of this method must release the object when it's
  * done with it.
  */
-static OLEFontImpl* OLEFontImpl_Construct(LPFONTDESC fontDesc)
+static OLEFontImpl* OLEFontImpl_Construct(const FONTDESC *fontDesc)
 {
   OLEFontImpl* newObject = 0;
 

Modified: trunk/reactos/dll/win32/oleaut32/olepicture.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/oleaut32/olepicture.c?rev=27914&r1=27913&r2=27914&view=diff
==============================================================================
--- trunk/reactos/dll/win32/oleaut32/olepicture.c (original)
+++ trunk/reactos/dll/win32/oleaut32/olepicture.c Fri Jul 27 13:59:17 2007
@@ -67,7 +67,7 @@
 
 #include "wine/wingdi16.h"
 
-#ifdef HAVE_JPEGLIB_H
+#ifdef SONAME_LIBJPEG
 /* This is a hack, so jpeglib.h does not redefine INT32 and the like*/
 #define XMD_H
 #define UINT8 JPEG_UINT8
@@ -77,9 +77,11 @@
 # include <jpeglib.h>
 #undef jpeg_boolean
 #undef UINT16
-#ifndef SONAME_LIBJPEG
-#define SONAME_LIBJPEG "libjpeg.so"
 #endif
+
+#ifdef HAVE_PNG_H
+#undef FAR
+#include <png.h>
 #endif
 
 #include "ungif.h"
@@ -365,6 +367,7 @@
       DeleteEnhMetaFile(Obj->desc.u.emf.hemf);
       break;
     case PICTYPE_NONE:
+    case PICTYPE_UNINITIALIZED:
       /* Nothing to do */
       break;
     default:
@@ -505,6 +508,7 @@
   TRACE("(%p)->(%p)\n", This, phandle);
   switch(This->desc.picType) {
   case PICTYPE_NONE:
+  case PICTYPE_UNINITIALIZED:
     *phandle = 0;
     break;
   case PICTYPE_BITMAP:
@@ -674,7 +678,16 @@
     break;
 
   case PICTYPE_METAFILE:
+    PlayMetaFile(hdc, This->desc.u.wmf.hmeta);
+    break;
+
   case PICTYPE_ENHMETAFILE:
+  {
+    RECT rc = { x, y, cx, cy };
+    PlayEnhMetaFile(hdc, This->desc.u.emf.hemf, &rc);
+    break;
+  }
+
   default:
     FIXME("type %d not implemented\n", This->desc.picType);
     return E_NOTIMPL;
@@ -795,6 +808,7 @@
   switch (This->desc.picType) {
   case PICTYPE_BITMAP: 	if (This->hbmMask) *pdwAttr = PICTURE_TRANSPARENT; break;	/* not 'truly' scalable, see MSDN. */
   case PICTYPE_ICON: *pdwAttr     = PICTURE_TRANSPARENT;break;
+  case PICTYPE_ENHMETAFILE: /* fall through */
   case PICTYPE_METAFILE: *pdwAttr = PICTURE_TRANSPARENT|PICTURE_SCALABLE;break;
   default:FIXME("Unknown pictype %d\n",This->desc.picType);break;
   }
@@ -925,7 +939,7 @@
   return E_NOTIMPL;
 }
 
-#ifdef HAVE_JPEGLIB_H
+#ifdef SONAME_LIBJPEG
 
 static void *libjpeg_handle;
 #define MAKE_FUNCPTR(f) static typeof(f) * p##f
@@ -979,7 +993,7 @@
     return FALSE;
 }
 static void _jpeg_term_source(j_decompress_ptr cinfo) { }
-#endif /* HAVE_JPEGLIB_H */
+#endif /* SONAME_LIBJPEG */
 
 struct gifdata {
     unsigned char *data;
@@ -1198,7 +1212,7 @@
 
 static HRESULT OLEPictureImpl_LoadJpeg(OLEPictureImpl *This, BYTE *xbuf, ULONG xread)
 {
-#ifdef HAVE_JPEGLIB_H
+#ifdef SONAME_LIBJPEG
     struct jpeg_decompress_struct	jd;
     struct jpeg_error_mgr		jerr;
     int					ret;
@@ -1324,6 +1338,193 @@
     OLEPictureImpl_SetBitmap(This);
     return S_OK;
 }
+
+/*****************************************************
+*   start of PNG-specific code
+*   currently only supports colortype PNG_COLOR_TYPE_RGB
+*/
+#ifdef SONAME_LIBPNG
+typedef struct{
+    ULONG position;
+    ULONG size;
+    BYTE * buff;
+} png_io;
+
+static void png_stream_read_data(png_structp png_ptr, png_bytep data,
+    png_size_t length)
+{
+    png_io * io_ptr = png_ptr->io_ptr;
+
+    if(length + io_ptr->position > io_ptr->size){
+        length = io_ptr->size - io_ptr->position;
+    }
+
+    memcpy(data, io_ptr->buff + io_ptr->position, length);
+
+    io_ptr->position += length;
+}
+
+static void *libpng_handle;
+#define MAKE_FUNCPTR(f) static typeof(f) * p##f
+MAKE_FUNCPTR(png_create_read_struct);
+MAKE_FUNCPTR(png_create_info_struct);
+MAKE_FUNCPTR(png_set_read_fn);
+MAKE_FUNCPTR(png_read_info);
+MAKE_FUNCPTR(png_read_image);
+MAKE_FUNCPTR(png_get_rowbytes);
+MAKE_FUNCPTR(png_set_bgr);
+MAKE_FUNCPTR(png_destroy_read_struct);
+MAKE_FUNCPTR(png_set_palette_to_rgb);
+MAKE_FUNCPTR(png_read_update_info);
+#undef MAKE_FUNCPTR
+
+static void *load_libpng(void)
+{
+    if((libpng_handle = wine_dlopen(SONAME_LIBPNG, RTLD_NOW, NULL, 0)) != NULL) {
+
+#define LOAD_FUNCPTR(f) \
+    if((p##f = wine_dlsym(libpng_handle, #f, NULL, 0)) == NULL) { \
+        libpng_handle = NULL; \
+        return NULL; \
+    }
+        LOAD_FUNCPTR(png_create_read_struct);
+        LOAD_FUNCPTR(png_create_info_struct);
+        LOAD_FUNCPTR(png_set_read_fn);
+        LOAD_FUNCPTR(png_read_info);
+        LOAD_FUNCPTR(png_read_image);
+        LOAD_FUNCPTR(png_get_rowbytes);
+        LOAD_FUNCPTR(png_set_bgr);
+        LOAD_FUNCPTR(png_destroy_read_struct);
+        LOAD_FUNCPTR(png_set_palette_to_rgb);
+        LOAD_FUNCPTR(png_read_update_info);
+
+#undef LOAD_FUNCPTR
+    }
+    return libpng_handle;
+}
+#endif /* SONAME_LIBPNG */
+
+static HRESULT OLEPictureImpl_LoadPNG(OLEPictureImpl *This, BYTE *xbuf, ULONG xread)
+{
+#ifdef SONAME_LIBPNG
+    png_io              io;
+    png_structp         png_ptr = NULL;
+    png_infop           info_ptr = NULL;
+    INT                 row, rowsize, height, width;
+    png_bytep*          row_pointers = NULL;
+    png_bytep           pngdata = NULL;
+    BITMAPINFOHEADER    bmi;
+    HDC                 hdcref = NULL;
+    HRESULT             ret;
+    BOOL                set_bgr = FALSE;
+
+    if(!libpng_handle) {
+        if(!load_libpng()) {
+            ERR("Failed reading PNG because unable to find %s\n",SONAME_LIBPNG);
+            return E_FAIL;
+        }
+    }
+
+    io.size     = xread;
+    io.position = 0;
+    io.buff     = xbuf;
+
+    png_ptr = ppng_create_read_struct(PNG_LIBPNG_VER_STRING,
+        NULL, NULL, NULL);
+
+    if(setjmp(png_jmpbuf(png_ptr))){
+        TRACE("Error in libpng\n");
+        ret = E_FAIL;
+        goto pngend;
+    }
+
+    info_ptr = ppng_create_info_struct(png_ptr);
+    ppng_set_read_fn(png_ptr, &io, png_stream_read_data);
+    ppng_read_info(png_ptr, info_ptr);
+
+    if(!(png_ptr->color_type == PNG_COLOR_TYPE_RGB ||
+         png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)){
+        FIXME("Unsupported .PNG type: %d\n", png_ptr->color_type);
+        ret = E_FAIL;
+        goto pngend;
+    }
+
+    if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE){
+        ppng_set_palette_to_rgb(png_ptr);
+        set_bgr = TRUE;
+    }
+
+    if (png_ptr->color_type == PNG_COLOR_TYPE_RGB ||
+        png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA ||
+        set_bgr){
+        ppng_set_bgr(png_ptr);
+    }
+
+    ppng_read_update_info(png_ptr, info_ptr);
+
+    rowsize = ppng_get_rowbytes(png_ptr, info_ptr);
+    /* align rowsize to 4-byte boundary */
+    rowsize = (rowsize + 3) & ~3;
+    height = info_ptr->height;
+    width = info_ptr->width;
+
+    pngdata = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, height * rowsize);
+    row_pointers = HeapAlloc(GetProcessHeap(), 0, height * (sizeof(VOID *)));
+
+    if(!pngdata || !row_pointers){
+        ret = E_FAIL;
+        goto pngend;
+    }
+
+    for (row = 0; row < height; row++){
+        row_pointers[row] = pngdata + row * rowsize;
+    }
+
+    ppng_read_image(png_ptr, row_pointers);
+
+    bmi.biSize          = sizeof(bmi);
+    bmi.biWidth         = width;
+    bmi.biHeight        = -height;
+    bmi.biPlanes        = 1;
+    bmi.biBitCount      = info_ptr->channels * 8;
+    bmi.biCompression   = BI_RGB;
+    bmi.biSizeImage     = height * rowsize;
+    bmi.biXPelsPerMeter = 0;
+    bmi.biYPelsPerMeter = 0;
+    bmi.biClrUsed       = 0;
+    bmi.biClrImportant  = 0;
+
+    hdcref = GetDC(0);
+    This->desc.u.bmp.hbitmap = CreateDIBitmap(
+        hdcref,
+        &bmi,
+        CBM_INIT,
+        pngdata,
+        (BITMAPINFO*)&bmi,
+        DIB_RGB_COLORS
+    );
+    ReleaseDC(0, hdcref);
+    This->desc.picType = PICTYPE_BITMAP;
+    OLEPictureImpl_SetBitmap(This);
+    ret = S_OK;
+
+pngend:
+    if(png_ptr)
+        ppng_destroy_read_struct(&png_ptr,
+                                (info_ptr ? &info_ptr : (png_infopp) NULL),
+                                (png_infopp)NULL);
+    HeapFree(GetProcessHeap(), 0, row_pointers);
+    HeapFree(GetProcessHeap(), 0, pngdata);
+    return ret;
+#else /* SONAME_LIBPNG */
+    ERR("Trying to load PNG picture, but PNG supported not compiled in.\n");
+    return E_FAIL;
+#endif
+}
+
+/*****************************************************
+*   start of Icon-specific code
+*/
 
 static HRESULT OLEPictureImpl_LoadIcon(OLEPictureImpl *This, BYTE *xbuf, ULONG xread)
 {
@@ -1385,6 +1586,43 @@
     }
 }
 
+static HRESULT OLEPictureImpl_LoadMetafile(OLEPictureImpl *This,
+                                           const BYTE *data, ULONG size)
+{
+    HMETAFILE hmf;
+    HENHMETAFILE hemf;
+
+    /* SetMetaFileBitsEx performs data check on its own */
+    hmf = SetMetaFileBitsEx(size, data);
+    if (hmf)
+    {
+        This->desc.picType = PICTYPE_METAFILE;
+        This->desc.u.wmf.hmeta = hmf;
+        This->desc.u.wmf.xExt = 0;
+        This->desc.u.wmf.yExt = 0;
+
+        This->origWidth = 0;
+        This->origHeight = 0;
+        This->himetricWidth = 0;
+        This->himetricHeight = 0;
+
+        return S_OK;
+    }
+
+    hemf = SetEnhMetaFileBits(size, data);
+    if (!hemf) return E_FAIL;
+
+    This->desc.picType = PICTYPE_ENHMETAFILE;
+    This->desc.u.emf.hemf = hemf;
+
+    This->origWidth = 0;
+    This->origHeight = 0;
+    This->himetricWidth = 0;
+    This->himetricHeight = 0;
+
+    return S_OK;
+}
+
 /************************************************************************
  * OLEPictureImpl_IPersistStream_Load (IUnknown)
  *
@@ -1393,7 +1631,7 @@
  * 	DWORD magic;
  * 	DWORD len;
  *
- * Currently implemented: BITMAP, ICON, JPEG, GIF
+ * Currently implemented: BITMAP, ICON, JPEG, GIF, WMF, EMF
  */
 static HRESULT WINAPI OLEPictureImpl_Load(IPersistStream* iface,IStream*pStm) {
   HRESULT	hr = E_FAIL;
@@ -1527,6 +1765,8 @@
    */
 
   magic = xbuf[0] + (xbuf[1]<<8);
+  This->loadtime_format = magic;
+
   switch (magic) {
   case 0x4947: /* GIF */
     hr = OLEPictureImpl_LoadGif(This, xbuf, xread);
@@ -1537,6 +1777,9 @@
   case 0x4d42: /* Bitmap */
     hr = OLEPictureImpl_LoadDIB(This, xbuf, xread);
     break;
+  case 0x5089: /* PNG */
+    hr = OLEPictureImpl_LoadPNG(This, xbuf, xread);
+    break;
   case 0x0000: { /* ICON , first word is dwReserved */
     hr = OLEPictureImpl_LoadIcon(This, xbuf, xread);
     break;
@@ -1544,6 +1787,11 @@
   default:
   {
     unsigned int i;
+
+    /* let's see if it's a metafile */
+    hr = OLEPictureImpl_LoadMetafile(This, xbuf, xread);
+    if (hr == S_OK) break;
+
     FIXME("Unknown magic %04x, %d read bytes:\n",magic,xread);
     hr=E_FAIL;
     for (i=0;i<xread+8;i++) {
@@ -1826,6 +2074,9 @@
                 break;
             case 0x4947:
                 FIXME("(%p,%p,%d), PICTYPE_BITMAP (format GIF) not implemented!\n",This,pStm,fClearDirty);
+                break;
+            case 0x5089:
+                FIXME("(%p,%p,%d), PICTYPE_BITMAP (format PNG) not implemented!\n",This,pStm,fClearDirty);
                 break;
             default:
                 FIXME("(%p,%p,%d), PICTYPE_BITMAP (format UNKNOWN, using BMP?) not implemented!\n",This,pStm,fClearDirty);

Modified: trunk/reactos/dll/win32/oleaut32/safearray.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/oleaut32/safearray.c?rev=27914&r1=27913&r2=27914&view=diff
==============================================================================
--- trunk/reactos/dll/win32/oleaut32/safearray.c (original)
+++ trunk/reactos/dll/win32/oleaut32/safearray.c Fri Jul 27 13:59:17 2007
@@ -204,7 +204,7 @@
 }
 
 /* Create an array */
-static SAFEARRAY* SAFEARRAY_Create(VARTYPE vt, UINT cDims, SAFEARRAYBOUND *rgsabound, ULONG ulSize)
+static SAFEARRAY* SAFEARRAY_Create(VARTYPE vt, UINT cDims, const SAFEARRAYBOUND *rgsabound, ULONG ulSize)
 {
   SAFEARRAY *psa = NULL;
   int i;

Modified: trunk/reactos/dll/win32/oleaut32/tmarshal.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/oleaut32/tmarshal.c?rev=27914&r1=27913&r2=27914&view=diff
==============================================================================
--- trunk/reactos/dll/win32/oleaut32/tmarshal.c (original)
+++ trunk/reactos/dll/win32/oleaut32/tmarshal.c Fri Jul 27 13:59:17 2007
@@ -40,7 +40,6 @@
 #include "winnls.h"
 #include "winreg.h"
 #include "winuser.h"
-#include "excpt.h"
 
 #include "ole2.h"
 #include "propidl.h" /* for LPSAFEARRAY_User* functions */
@@ -97,7 +96,7 @@
 }
 
 static HRESULT
-xbuf_add(marshal_state *buf, LPBYTE stuff, DWORD size)
+xbuf_add(marshal_state *buf, const BYTE *stuff, DWORD size)
 {
     HRESULT hr;
 
@@ -286,14 +285,12 @@
 	ERR("No %s key found.\n",interfacekey);
        	return E_FAIL;
     }
-    type = (1<<REG_SZ);
     tlguidlen = sizeof(tlguid);
     if (RegQueryValueExA(ikey,NULL,NULL,&type,(LPBYTE)tlguid,&tlguidlen)) {
 	ERR("Getting typelib guid failed.\n");
 	RegCloseKey(ikey);
 	return E_FAIL;
     }
-    type = (1<<REG_SZ);
     verlen = sizeof(ver);
     if (RegQueryValueExA(ikey,"Version",NULL,&type,(LPBYTE)ver,&verlen)) {
 	ERR("Could not get version value?\n");
@@ -323,49 +320,49 @@
     return hres;
 }
 
-/* Determine nr of functions. Since we use the toplevel interface and all
- * inherited ones have lower numbers, we are ok to not to descent into
- * the inheritance tree I think.
+/*
+ * Determine the number of functions including all inherited functions.
+ * Note for non-dual dispinterfaces we simply return the size of IDispatch.
  */
-static int _nroffuncs(ITypeInfo *tinfo) {
-    int 	n, i, j;
-    const FUNCDESC *fdesc;
-    HRESULT	hres;
+static HRESULT num_of_funcs(ITypeInfo *tinfo, unsigned int *num)
+{
+    HRESULT hres;
     TYPEATTR *attr;
     ITypeInfo *tinfo2;
 
-    n=0;
+    *num = 0;
     hres = ITypeInfo_GetTypeAttr(tinfo, &attr);
     if (hres) {
         ERR("GetTypeAttr failed with %x\n",hres);
         return hres;
     }
-    /* look in inherited ifaces. */
-    for (j=0;j<attr->cImplTypes;j++) {
+
+    if(attr->typekind == TKIND_DISPATCH && (attr->wTypeFlags & TYPEFLAG_FDUAL))
+    {
         HREFTYPE href;
-        hres = ITypeInfo_GetRefTypeOfImplType(tinfo, j, &href);
-        if (hres) {
-            ERR("Did not find a reftype for interface offset %d?\n",j);
-            break;
+        hres = ITypeInfo_GetRefTypeOfImplType(tinfo, -1, &href);
+        if(FAILED(hres))
+        {
+            ERR("Unable to get interface href from dual dispinterface\n");
+            goto end;
         }
         hres = ITypeInfo_GetRefTypeInfo(tinfo, href, &tinfo2);
-        if (hres) {
-            ERR("Did not find a typeinfo for reftype %d?\n",href);
-            continue;
+        if(FAILED(hres))
+        {
+            ERR("Unable to get interface from dual dispinterface\n");
+            goto end;
         }
-        n += _nroffuncs(tinfo2);
+        hres = num_of_funcs(tinfo2, num);
         ITypeInfo_Release(tinfo2);
     }
+    else
+    {
+        *num = attr->cbSizeVft / 4;
+    }
+
+ end:
     ITypeInfo_ReleaseTypeAttr(tinfo, attr);
-    i = 0;
-    while (1) {
-	hres = ITypeInfoImpl_GetInternalFuncDesc(tinfo,i,&fdesc);
-	if (hres)
-	    return n;
-	n++;
-	i++;
-    }
-    /*NOTREACHED*/
+    return hres;
 }
 
 #ifdef __i386__
@@ -526,7 +523,7 @@
 }
 
 static int
-_xsize(TYPEDESC *td) {
+_xsize(const TYPEDESC *td) {
     switch (td->vt) {
     case VT_DATE:
 	return sizeof(DATE);
@@ -534,7 +531,7 @@
 	return sizeof(VARIANT)+3;
     case VT_CARRAY: {
 	int i, arrsize = 1;
-	ARRAYDESC *adesc = td->u.lpadesc;
+	const ARRAYDESC *adesc = td->u.lpadesc;
 
 	for (i=0;i<adesc->cDims;i++)
 	    arrsize *= adesc->rgbounds[i].cElements;
@@ -1198,63 +1195,99 @@
     }
 }
 
-/* Searches function, also in inherited interfaces */
-static HRESULT
-_get_funcdesc(
-    ITypeInfo *tinfo, int iMethod, ITypeInfo **tactual, const FUNCDESC **fdesc, BSTR *iname, BSTR *fname)
-{
-    int i = 0, j = 0;
-    HRESULT hres;
+/* 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;
-
-    while (1) {
-	hres = ITypeInfoImpl_GetInternalFuncDesc(tinfo, i, fdesc);
-
-	if (hres) {
-	    ITypeInfo	*tinfo2;
-	    HREFTYPE	href;
-	    TYPEATTR	*attr;
-
-	    hres = ITypeInfo_GetTypeAttr(tinfo, &attr);
-	    if (hres) {
-		ERR("GetTypeAttr failed with %x\n",hres);
-		return hres;
-	    }
-	    /* Not found, so look in inherited ifaces. */
-	    for (j=0;j<attr->cImplTypes;j++) {
-		hres = ITypeInfo_GetRefTypeOfImplType(tinfo, j, &href);
-		if (hres) {
-		    ERR("Did not find a reftype for interface offset %d?\n",j);
-		    break;
-		}
-		hres = ITypeInfo_GetRefTypeInfo(tinfo, href, &tinfo2);
-		if (hres) {
-		    ERR("Did not find a typeinfo for reftype %d?\n",href);
-		    continue;
-		}
-		hres = _get_funcdesc(tinfo2,iMethod,tactual,fdesc,iname,fname);
-		ITypeInfo_Release(tinfo2);
-		if (!hres) {
-		    ITypeInfo_ReleaseTypeAttr(tinfo, attr);
-		    return S_OK;
-                }
-	    }
-	    ITypeInfo_ReleaseTypeAttr(tinfo, attr);
-	    return hres;
-	}
-	if (((*fdesc)->oVft/4) == iMethod) {
-	    if (fname)
-		ITypeInfo_GetDocumentation(tinfo,(*fdesc)->memid,fname,NULL,NULL,NULL);
-	    if (iname)
-		ITypeInfo_GetDocumentation(tinfo,-1,iname,NULL,NULL,NULL);
-	    *tactual = tinfo;
-	    ITypeInfo_AddRef(*tactual);
-	    return S_OK;
-	}
-	i++;
-    }
+    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)
@@ -1286,10 +1319,9 @@
 
     EnterCriticalSection(&tpinfo->crit);
 
-    hres = _get_funcdesc(tpinfo->tinfo,method,&tinfo,&fdesc,&iname,&fname);
+    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);
-        ITypeInfo_Release(tinfo);
         LeaveCriticalSection(&tpinfo->crit);
         return E_FAIL;
     }
@@ -1639,84 +1671,32 @@
                              &IID_IPSFactoryBuffer, (LPVOID*)facbuf);
 }
 
-static HRESULT WINAPI
-PSFacBuf_CreateProxy(
-    LPPSFACTORYBUFFER iface, IUnknown* pUnkOuter, REFIID riid,
-    IRpcProxyBuffer **ppProxy, LPVOID *ppv)
-{
-    HRESULT	hres;
-    ITypeInfo	*tinfo;
-    int		i, nroffuncs;
+static HRESULT init_proxy_entry_point(TMProxyImpl *proxy, unsigned int num)
+{
+    int j;
+    /* nrofargs without This */
+    int nrofargs;
+    ITypeInfo *tinfo2;
+    TMAsmProxy	*xasm = proxy->asmstubs + num;
+    HRESULT hres;
     const FUNCDESC *fdesc;
-    TMProxyImpl	*proxy;
-    TYPEATTR	*typeattr;
-
-    TRACE("(...%s...)\n",debugstr_guid(riid));
-    hres = _get_typeinfo_for_iid(riid,&tinfo);
+
+    hres = get_funcdesc(proxy->tinfo, num, &tinfo2, &fdesc, NULL, NULL, NULL);
     if (hres) {
-	ERR("No typeinfo for %s?\n",debugstr_guid(riid));
-	return hres;
-    }
-    nroffuncs = _nroffuncs(tinfo);
-    proxy = CoTaskMemAlloc(sizeof(TMProxyImpl));
-    if (!proxy) return E_OUTOFMEMORY;
-
-    assert(sizeof(TMAsmProxy) == 12);
-
-    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->lpvtbl2	= &tmproxyvtable;
-    /* one reference for the proxy */
-    proxy->ref		= 1;
-    proxy->tinfo	= tinfo;
-    memcpy(&proxy->iid,riid,sizeof(*riid));
-    proxy->chanbuf      = 0;
-
-    InitializeCriticalSection(&proxy->crit);
-    proxy->crit.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": TMProxyImpl.crit");
-
-    proxy->lpvtbl = HeapAlloc(GetProcessHeap(),0,sizeof(LPBYTE)*nroffuncs);
-    for (i=0;i<nroffuncs;i++) {
-	TMAsmProxy	*xasm = proxy->asmstubs+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;
-	default: {
-		int j;
-		/* nrofargs without This */
-		int nrofargs;
-                ITypeInfo *tinfo2;
-		hres = _get_funcdesc(tinfo,i,&tinfo2,&fdesc,NULL,NULL);
-                ITypeInfo_Release(tinfo2);
-		if (hres) {
-		    ERR("GetFuncDesc %x should not fail here.\n",hres);
-		    return hres;
-		}
-		/* some args take more than 4 byte on the stack */
-		nrofargs = 0;
-		for (j=0;j<fdesc->cParams;j++)
-		    nrofargs += _argsize(fdesc->lprgelemdescParam[j].tdesc.vt);
+        ERR("GetFuncDesc %x should not fail here.\n",hres);
+        return hres;
+    }
+    ITypeInfo_Release(tinfo2);
+    /* some args take more than 4 byte on the stack */
+    nrofargs = 0;
+    for (j=0;j<fdesc->cParams;j++)
+        nrofargs += _argsize(fdesc->lprgelemdescParam[j].tdesc.vt);
 
 #ifdef __i386__
-		if (fdesc->callconv != CC_STDCALL) {
-		    ERR("calling convention is not stdcall????\n");
-		    return E_FAIL;
-		}
+    if (fdesc->callconv != CC_STDCALL) {
+        ERR("calling convention is not stdcall????\n");
+        return E_FAIL;
+    }
 /* popl %eax	-	return ptr
  * pushl <nr>
  * pushl %eax
@@ -1726,24 +1706,74 @@
  *
  * arg3 arg2 arg1 <method> <returnptr>
  */
-		xasm->popleax	= 0x58;
-		xasm->pushlval	= 0x6a;
-		xasm->nr	= i;
-		xasm->pushleax	= 0x50;
-		xasm->lcall	= 0xe8;	/* relative jump */
-		xasm->xcall	= (DWORD)xCall;
-		xasm->xcall     -= (DWORD)&(xasm->lret);
-		xasm->lret	= 0xc2;
-		xasm->bytestopop= (nrofargs+2)*4; /* pop args, This, iMethod */
-		proxy->lpvtbl[i] = xasm;
-		break;
+    xasm->popleax       = 0x58;
+    xasm->pushlval      = 0x6a;
+    xasm->nr            = num;
+    xasm->pushleax      = 0x50;
+    xasm->lcall         = 0xe8; /* relative jump */
+    xasm->xcall         = (DWORD)xCall;
+    xasm->xcall        -= (DWORD)&(xasm->lret);
+    xasm->lret          = 0xc2;
+    xasm->bytestopop    = (nrofargs+2)*4; /* pop args, This, iMethod */
+    proxy->lpvtbl[num]  = xasm;
 #else
-                FIXME("not implemented on non i386\n");
-                return E_FAIL;
+    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;
+    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);
+    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;
+
+    assert(sizeof(TMAsmProxy) == 12);
+
+    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->lpvtbl2	= &tmproxyvtable;
+    /* one reference for the proxy */
+    proxy->ref		= 1;
+    proxy->tinfo	= tinfo;
+    memcpy(&proxy->iid,riid,sizeof(*riid));
+    proxy->chanbuf      = 0;
+
+    InitializeCriticalSection(&proxy->crit);
+    proxy->crit.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": TMProxyImpl.crit");
+
+    proxy->lpvtbl = HeapAlloc(GetProcessHeap(),0,sizeof(LPBYTE)*nroffuncs);
 
     /* if we derive from IDispatch then defer to its proxy for its methods */
     hres = ITypeInfo_GetTypeAttr(tinfo, &typeattr);
@@ -1767,13 +1797,59 @@
             }
             if (hres == S_OK)
             {
-                proxy->lpvtbl[3] = ProxyIDispatch_GetTypeInfoCount;
-                proxy->lpvtbl[4] = ProxyIDispatch_GetTypeInfo;
-                proxy->lpvtbl[5] = ProxyIDispatch_GetIDsOfNames;
-                proxy->lpvtbl[6] = ProxyIDispatch_Invoke;
+                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);
+                    if(FAILED(hres)) return hres;
+                }
+                else proxy->lpvtbl[3] = ProxyIDispatch_GetTypeInfoCount;
+                break;
+        case 4:
+                if(!defer_to_dispatch)
+                {
+                    hres = init_proxy_entry_point(proxy, i);
+                    if(FAILED(hres)) return hres;
+                }
+                else proxy->lpvtbl[4] = ProxyIDispatch_GetTypeInfo;
+                break;
+        case 5:
+                if(!defer_to_dispatch)
+                {
+                    hres = init_proxy_entry_point(proxy, i);
+                    if(FAILED(hres)) return hres;
+                }
+                else proxy->lpvtbl[5] = ProxyIDispatch_GetIDsOfNames;
+                break;
+        case 6:
+                if(!defer_to_dispatch)
+                {
+                    hres = init_proxy_entry_point(proxy, i);
+                    if(FAILED(hres)) return hres;
+                }
+                else proxy->lpvtbl[6] = ProxyIDispatch_Invoke;
+                break;
+	default:
+                hres = init_proxy_entry_point(proxy, i);
+                if(FAILED(hres)) return hres;
+	}
     }
 
     if (hres == S_OK)
@@ -1917,7 +1993,7 @@
     memcpy(buf.base, xmsg->Buffer, xmsg->cbBuffer);
     buf.curoff	= 0;
 
-    hres = _get_funcdesc(This->tinfo,xmsg->iMethod,&tinfo,&fdesc,&iname,NULL);
+    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;

Modified: trunk/reactos/dll/win32/oleaut32/typelib.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/oleaut32/typelib.c?rev=27914&r1=27913&r2=27914&view=diff
==============================================================================
--- trunk/reactos/dll/win32/oleaut32/typelib.c (original)
+++ trunk/reactos/dll/win32/oleaut32/typelib.c Fri Jul 27 13:59:17 2007
@@ -70,6 +70,7 @@
 #include "typelib.h"
 #include "wine/debug.h"
 #include "variant.h"
+#include "wine/list.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(ole);
 WINE_DECLARE_DEBUG_CHANNEL(typelib);
@@ -103,6 +104,8 @@
 #define FromLEDWord(X) (X)
 #endif
 
+#define DISPATCH_HREF_OFFSET 0x01000000
+#define DISPATCH_HREF_MASK   0xff000000
 
 /****************************************************************************
  *              FromLExxx
@@ -894,8 +897,11 @@
     TLBImpLib   * pImpLibs;     /* linked list to all imported typelibs */
     int ctTypeDesc;             /* number of items in type desc array */
     TYPEDESC * pTypeDesc;       /* array of TypeDescriptions found in the
-				   library. Only used while read MSFT
+				   library. Only used while reading MSFT
 				   typelibs */
+    struct list ref_list;       /* list of ref types in this typelib */
+    HREFTYPE dispatch_href;     /* reference to IDispatch, -1 if unused */
+
 
     /* typelibs are cached, keyed by path and index, so store the linked list info within them */
     struct tagITypeLibImpl *next, *prev;
@@ -932,7 +938,7 @@
 			       TLB_REF_INTERNAL for internal refs
 			       TLB_REF_NOT_FOUND for broken refs */
 
-    struct tagTLBRefType * next;
+    struct list entry;
 } TLBRefType;
 
 #define TLB_REF_USE_GUID -2
@@ -1015,7 +1021,6 @@
     /* Implemented Interfaces  */
     TLBImplType * impltypelist;
 
-    TLBRefType * reflist;
     int ctCustData;
     TLBCustData * pCustData;        /* linked list to cust data; */
     struct tagITypeInfoImpl * next;
@@ -1042,7 +1047,7 @@
 } TLBContext;
 
 
-static void MSFT_DoRefType(TLBContext *pcx, ITypeInfoImpl *pTI, int offset);
+static void MSFT_DoRefType(TLBContext *pcx, ITypeLibImpl *pTL, int offset);
 
 /*
  debug
@@ -1200,23 +1205,24 @@
 		    import->wVersionMinor, import->lcid, import->offset);
 }
 
-static void dump_TLBRefType(const TLBRefType * prt)
-{
-	while (prt)
-	{
-	  TRACE_(typelib)("href:0x%08x\n", prt->reference);
-	  if(prt->index == -1)
-	    TRACE_(typelib)("%s\n", debugstr_guid(&(prt->guid)));
-	  else
-	    TRACE_(typelib)("type no: %d\n", prt->index);
-
-	  if(prt->pImpTLInfo != TLB_REF_INTERNAL &&
-	     prt->pImpTLInfo != TLB_REF_NOT_FOUND) {
-	      TRACE_(typelib)("in lib\n");
-	      dump_TLBImpLib(prt->pImpTLInfo);
-	  }
-	  prt = prt->next;
-	};
+static void dump_TLBRefType(const ITypeLibImpl *pTL)
+{
+    TLBRefType *ref;
+
+    LIST_FOR_EACH_ENTRY(ref, &pTL->ref_list, TLBRefType, entry)
+    {
+        TRACE_(typelib)("href:0x%08x\n", ref->reference);
+        if(ref->index == -1)
+	    TRACE_(typelib)("%s\n", debugstr_guid(&(ref->guid)));
+        else
+	    TRACE_(typelib)("type no: %d\n", ref->index);
+
+        if(ref->pImpTLInfo != TLB_REF_INTERNAL && ref->pImpTLInfo != TLB_REF_NOT_FOUND)
+        {
+            TRACE_(typelib)("in lib\n");
+            dump_TLBImpLib(ref->pImpTLInfo);
+        }
+    }
 }
 
 static void dump_TLBImplType(const TLBImplType * impl)
@@ -1630,7 +1636,7 @@
             MSFT_Read(ptr, size, pcx, DO_NOT_SEEK);/* read string (ANSI) */
             V_BSTR(pVar)=SysAllocStringLen(NULL,size);
             /* FIXME: do we need a AtoW conversion here? */
-            V_UNION(pVar, bstrVal[size])=L'\0';
+            V_UNION(pVar, bstrVal[size])='\0';
             while(size--) V_UNION(pVar, bstrVal[size])=ptr[size];
             TLB_Free(ptr);
 	}
@@ -1697,7 +1703,7 @@
         *pTd=pcx->pLibInfo->pTypeDesc[type/(2*sizeof(INT))];
 
     if(pTd->vt == VT_USERDEFINED)
-      MSFT_DoRefType(pcx, pTI, pTd->u.hreftype);
+      MSFT_DoRefType(pcx, pTI->pTypeLib, pTd->u.hreftype);
 
     TRACE_(typelib)("vt type = %X\n", pTd->vt);
 }
@@ -1718,7 +1724,7 @@
             break;
 
         case VT_USERDEFINED:
-            MSFT_DoRefType(pcx, pTI,
+            MSFT_DoRefType(pcx, pTI->pTypeLib,
                            lpTypeDesc->u.hreftype);
 
             lpTypeDesc = NULL;
@@ -2002,22 +2008,21 @@
  * in the typelib, it's just an (file) offset in the type info base dir.
  * If comes from import, it's an offset+1 in the ImpInfo table
  * */
-static void MSFT_DoRefType(TLBContext *pcx, ITypeInfoImpl *pTI,
+static void MSFT_DoRefType(TLBContext *pcx, ITypeLibImpl *pTL,
                           int offset)
 {
     int j;
-    TLBRefType **ppRefType = &pTI->reflist;
+    TLBRefType *ref;
 
     TRACE_(typelib)("TLB context %p, TLB offset %x\n", pcx, offset);
 
-    while(*ppRefType) {
-        if((*ppRefType)->reference == offset)
-	    return;
-	ppRefType = &(*ppRefType)->next;
-    }
-
-    *ppRefType = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
-			   sizeof(**ppRefType));
+    LIST_FOR_EACH_ENTRY(ref, &pTL->ref_list, TLBRefType, entry)
+    {
+        if(ref->reference == offset) return;
+    }
+
+    ref = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*ref));
+    list_add_tail(&pTL->ref_list, &ref->entry);
 
     if(!MSFT_HREFTYPE_INTHISFILE( offset)) {
         /* external typelib */
@@ -2033,24 +2038,24 @@
             pImpLib=pImpLib->next;
         }
         if(pImpLib){
-            (*ppRefType)->reference=offset;
-            (*ppRefType)->pImpTLInfo = pImpLib;
+            ref->reference = offset;
+            ref->pImpTLInfo = pImpLib;
             if(impinfo.flags & MSFT_IMPINFO_OFFSET_IS_GUID) {
-                MSFT_ReadGuid(&(*ppRefType)->guid, impinfo.oGuid, pcx);
-                TRACE("importing by guid %s\n", debugstr_guid(&(*ppRefType)->guid));
-                (*ppRefType)->index = TLB_REF_USE_GUID;
+                MSFT_ReadGuid(&ref->guid, impinfo.oGuid, pcx);
+                TRACE("importing by guid %s\n", debugstr_guid(&ref->guid));
+                ref->index = TLB_REF_USE_GUID;
             } else
-                (*ppRefType)->index = impinfo.oGuid;
+                ref->index = impinfo.oGuid;
         }else{
             ERR("Cannot find a reference\n");
-            (*ppRefType)->reference=-1;
-            (*ppRefType)->pImpTLInfo=TLB_REF_NOT_FOUND;
+            ref->reference = -1;
+            ref->pImpTLInfo = TLB_REF_NOT_FOUND;
         }
     }else{
         /* in this typelib */
-        (*ppRefType)->index = MSFT_HREFTYPE_INDEX(offset);
-        (*ppRefType)->reference=offset;
-        (*ppRefType)->pImpTLInfo=TLB_REF_INTERNAL;
+        ref->index = MSFT_HREFTYPE_INDEX(offset);
+        ref->reference = offset;
+        ref->pImpTLInfo = TLB_REF_INTERNAL;
     }
 }
 
@@ -2068,7 +2073,7 @@
         if(offset<0) break; /* paranoia */
         *ppImpl=TLB_Alloc(sizeof(**ppImpl));
         MSFT_ReadLEDWords(&refrec,sizeof(refrec),pcx,offset+pcx->pTblDir->pRefTab.offset);
-        MSFT_DoRefType(pcx, pTI, refrec.reftype);
+        MSFT_DoRefType(pcx, pTI->pTypeLib, refrec.reftype);
 	(*ppImpl)->hRef = refrec.reftype;
 	(*ppImpl)->implflags=refrec.flags;
         (*ppImpl)->ctCustData=
@@ -2083,7 +2088,6 @@
 static ITypeInfoImpl * MSFT_DoTypeInfo(
     TLBContext *pcx,
     int count,
-    INT dispatch_href,
     ITypeLibImpl * pLibInfo)
 {
     MSFT_TypeInfoBase tiBase;
@@ -2153,22 +2157,22 @@
                 tiBase.datatype1);
             break;
         case TKIND_DISPATCH:
-            ptiRet->impltypelist=TLB_Alloc(sizeof(TLBImplType));
+            /* This is not -1 when the interface is a non-base dual interface or
+               when a dispinterface wraps an interface ie the idl 'dispinterface x {interface y;};'.
+               Note however that GetRefTypeOfImplType(0) always returns a ref to IDispatch and
+               not this interface.
+            */
 
             if (tiBase.datatype1 != -1)
             {
-              MSFT_DoRefType(pcx, ptiRet, tiBase.datatype1);
-	      ptiRet->impltypelist->hRef = tiBase.datatype1;
+                ptiRet->impltypelist = TLB_Alloc(sizeof(TLBImplType));
+                ptiRet->impltypelist->hRef = tiBase.datatype1;
+                MSFT_DoRefType(pcx, pLibInfo, tiBase.datatype1);
             }
-            else
-	    {
-              MSFT_DoRefType(pcx, ptiRet, dispatch_href);
-              ptiRet->impltypelist->hRef = dispatch_href;
-            }
-            break;
+          break;
         default:
             ptiRet->impltypelist=TLB_Alloc(sizeof(TLBImplType));
-            MSFT_DoRefType(pcx, ptiRet, tiBase.datatype1);
+            MSFT_DoRefType(pcx, pLibInfo, tiBase.datatype1);
 	    ptiRet->impltypelist->hRef = tiBase.datatype1;
             break;
        }
@@ -2361,6 +2365,9 @@
     pTypeLibImpl->lpVtbl = &tlbvt;
     pTypeLibImpl->lpVtblTypeComp = &tlbtcvt;
     pTypeLibImpl->ref = 1;
+
+    list_init(&pTypeLibImpl->ref_list);
+    pTypeLibImpl->dispatch_href = -1;
 
     return pTypeLibImpl;
 }
@@ -2556,6 +2563,10 @@
         }
     }
 
+    pTypeLibImpl->dispatch_href = tlbHeader.dispatchpos;
+    if(pTypeLibImpl->dispatch_href != -1)
+        MSFT_DoRefType(&cx, pTypeLibImpl, pTypeLibImpl->dispatch_href);
+
     /* type info's */
     if(tlbHeader.nrtypeinfos >= 0 )
     {
@@ -2565,7 +2576,7 @@
 
         for(i = 0; i<(int)tlbHeader.nrtypeinfos; i++)
         {
-            *ppTI = MSFT_DoTypeInfo(&cx, i, tlbHeader.dispatchpos, pTypeLibImpl);
+            *ppTI = MSFT_DoTypeInfo(&cx, i, pTypeLibImpl);
 
             ppTI = &((*ppTI)->next);
             (pTypeLibImpl->TypeInfoCount)++;
@@ -2693,7 +2704,27 @@
     return ptr - (char*)pLibBlk;
 }
 
-static WORD *SLTG_DoType(WORD *pType, char *pBlk, TYPEDESC *pTD)
+/* stores a mapping between the sltg typeinfo's references and the typelib's HREFTYPEs */
+typedef struct
+{
+    unsigned int num;
+    HREFTYPE refs[1];
+} sltg_ref_lookup_t;
+
+static HRESULT sltg_get_typelib_ref(sltg_ref_lookup_t *table, DWORD typeinfo_ref, HREFTYPE *typelib_ref)
+{
+    if(typeinfo_ref < table->num)
+    {
+        *typelib_ref = table->refs[typeinfo_ref];
+        return S_OK;
+    }
+
+    ERR("Unable to find reference\n");
+    *typelib_ref = -1;
+    return E_FAIL;
+}
+
+static WORD *SLTG_DoType(WORD *pType, char *pBlk, TYPEDESC *pTD, sltg_ref_lookup_t *ref_lookup)
 {
     BOOL done = FALSE;
 
@@ -2714,7 +2745,7 @@
 
 	case VT_USERDEFINED:
 	    pTD->vt = VT_USERDEFINED;
-	    pTD->u.hreftype = *(++pType) / 4;
+            sltg_get_typelib_ref(ref_lookup, *(++pType) / 4, &pTD->u.hreftype);
 	    done = TRUE;
 	    break;
 
@@ -2759,7 +2790,7 @@
     return pType;
 }
 
-static WORD *SLTG_DoElem(WORD *pType, char *pBlk, ELEMDESC *pElem)
+static WORD *SLTG_DoElem(WORD *pType, char *pBlk, ELEMDESC *pElem, sltg_ref_lookup_t *ref_lookup)
 {
     /* Handle [in/out] first */
     if((*pType & 0xc000) == 0xc000)
@@ -2777,36 +2808,44 @@
     if(*pType & 0x80)
         pElem->u.paramdesc.wParamFlags |= PARAMFLAG_FRETVAL;
 
-    return SLTG_DoType(pType, pBlk, &pElem->tdesc);
-}
-
-
-static void SLTG_DoRefs(SLTG_RefInfo *pRef, ITypeInfoImpl *pTI,
+    return SLTG_DoType(pType, pBlk, &pElem->tdesc, ref_lookup);
+}
+
+
+static sltg_ref_lookup_t *SLTG_DoRefs(SLTG_RefInfo *pRef, ITypeLibImpl *pTL,
 			char *pNameTable)
 {
     int ref;
     char *name;
-    TLBRefType **ppRefType;
+    TLBRefType *ref_type;
+    sltg_ref_lookup_t *table;
+    HREFTYPE typelib_ref;
 
     if(pRef->magic != SLTG_REF_MAGIC) {
         FIXME("Ref magic = %x\n", pRef->magic);
-	return;
+	return NULL;
     }
     name = ( (char*)(&pRef->names) + pRef->number);
 
-    ppRefType = &pTI->reflist;
+    table = HeapAlloc(GetProcessHeap(), 0, sizeof(*table) + ((pRef->number >> 3) - 1) * sizeof(table->refs[0]));
+    table->num = pRef->number >> 3;
+
+    /* FIXME should scan the existing list and reuse matching refs added by previous typeinfos */
+
+    /* We don't want the first href to be 0 */
+    typelib_ref = (list_count(&pTL->ref_list) + 1) << 2;
+
     for(ref = 0; ref < pRef->number >> 3; ref++) {
         char *refname;
 	unsigned int lib_offs, type_num;
 
-	*ppRefType = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
-			       sizeof(**ppRefType));
+	ref_type = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*ref_type));
 
 	name += SLTG_ReadStringA(name, &refname);
 	if(sscanf(refname, "*\\R%x*#%x", &lib_offs, &type_num) != 2)
 	    FIXME("Can't sscanf ref\n");
 	if(lib_offs != 0xffff) {
-	    TLBImpLib **import = &pTI->pTypeLib->pImpLibs;
+	    TLBImpLib **import = &pTL->pImpLibs;
 
 	    while(*import) {
 	        if((*import)->offset == lib_offs)
@@ -2835,23 +2874,32 @@
 		fname[len-1] = '\0';
 		(*import)->name = TLB_MultiByteToBSTR(fname);
 	    }
-	    (*ppRefType)->pImpTLInfo = *import;
+	    ref_type->pImpTLInfo = *import;
+
+            /* Store a reference to IDispatch */
+            if(pTL->dispatch_href == -1 && IsEqualGUID(&(*import)->guid, &IID_StdOle) && type_num == 4)
+                pTL->dispatch_href = typelib_ref;
+
 	} else { /* internal ref */
-	  (*ppRefType)->pImpTLInfo = TLB_REF_INTERNAL;
+	  ref_type->pImpTLInfo = TLB_REF_INTERNAL;
 	}
-	(*ppRefType)->reference = ref;
-	(*ppRefType)->index = type_num;
+	ref_type->reference = typelib_ref;
+	ref_type->index = type_num;
 
 	HeapFree(GetProcessHeap(), 0, refname);
-	ppRefType = &(*ppRefType)->next;
+        list_add_tail(&pTL->ref_list, &ref_type->entry);
+
+        table->refs[ref] = typelib_ref;
+        typelib_ref += 4;
     }
     if((BYTE)*name != SLTG_REF_MAGIC)
       FIXME("End of ref block magic = %x\n", *name);
-    dump_TLBRefType(pTI->reflist);
+    dump_TLBRefType(pTL);
+    return table;
 }
 
 static char *SLTG_DoImpls(char *pBlk, ITypeInfoImpl *pTI,
-			  BOOL OneOnly)
+			  BOOL OneOnly, sltg_ref_lookup_t *ref_lookup)
 {
     SLTG_ImplInfo *info;
     TLBImplType **ppImplType = &pTI->impltypelist;
@@ -2866,7 +2914,7 @@
     while(1) {
 	*ppImplType = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
 				sizeof(**ppImplType));
-	(*ppImplType)->hRef = info->ref;
+        sltg_get_typelib_ref(ref_lookup, info->ref, &(*ppImplType)->hRef);
 	(*ppImplType)->implflags = info->impltypeflags;
 	pTI->TypeAttr.cImplTypes++;
 	ppImplType = &(*ppImplType)->next;
@@ -2881,7 +2929,7 @@
     return (char*)info;
 }
 
-static void SLTG_DoVars(char *pBlk, char *pFirstItem, ITypeInfoImpl *pTI, unsigned short cVars, char *pNameTable)
+static void SLTG_DoVars(char *pBlk, char *pFirstItem, ITypeInfoImpl *pTI, unsigned short cVars, char *pNameTable, sltg_ref_lookup_t *ref_lookup)
 {
   TLBVarDesc **ppVarDesc = &pTI->varlist;
   BSTR bstrPrevName = NULL;
@@ -2945,7 +2993,7 @@
         FIXME_(typelib)("unhandled flags = %02x\n", pItem->flags & ~0xd2);
 
       SLTG_DoElem(pType, pBlk,
-		  &(*ppVarDesc)->vardesc.elemdescVar);
+		  &(*ppVarDesc)->vardesc.elemdescVar, ref_lookup);
 
       dump_TypeDesc(&(*ppVarDesc)->vardesc.elemdescVar.tdesc, buf);
 
@@ -2955,7 +3003,7 @@
   pTI->TypeAttr.cVars = cVars;
 }
 
-static void SLTG_DoFuncs(char *pBlk, char *pFirstItem, ITypeInfoImpl *pTI, unsigned short cFuncs, char *pNameTable)
+static void SLTG_DoFuncs(char *pBlk, char *pFirstItem, ITypeInfoImpl *pTI, unsigned short cFuncs, char *pNameTable, sltg_ref_lookup_t *ref_lookup)
 {
     SLTG_Function *pFunc;
     unsigned short i;
@@ -3003,7 +3051,7 @@
 	else
 	    pType = (WORD*)(pBlk + pFunc->rettype);
 
-	SLTG_DoElem(pType, pBlk, &(*ppFuncDesc)->funcdesc.elemdescFunc);
+	SLTG_DoElem(pType, pBlk, &(*ppFuncDesc)->funcdesc.elemdescFunc, ref_lookup);
 
 	(*ppFuncDesc)->funcdesc.lprgelemdescParam =
 	  HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
@@ -3041,13 +3089,13 @@
 	    if(HaveOffs) { /* the next word is an offset to type */
 	        pType = (WORD*)(pBlk + *pArg);
 		SLTG_DoElem(pType, pBlk,
-			    &(*ppFuncDesc)->funcdesc.lprgelemdescParam[param]);
+			    &(*ppFuncDesc)->funcdesc.lprgelemdescParam[param], ref_lookup);
 		pArg++;
 	    } else {
 		if(paramName)
 		  paramName--;
 		pArg = SLTG_DoElem(pArg, pBlk,
-			   &(*ppFuncDesc)->funcdesc.lprgelemdescParam[param]);
+                                   &(*ppFuncDesc)->funcdesc.lprgelemdescParam[param], ref_lookup);
 	    }
 
 	    /* Are we an optional param ? */
@@ -3072,17 +3120,19 @@
 				SLTG_TypeInfoTail *pTITail)
 {
     char *pFirstItem, *pNextItem;
+    sltg_ref_lookup_t *ref_lookup = NULL;
 
     if(pTIHeader->href_table != 0xffffffff) {
-        SLTG_DoRefs((SLTG_RefInfo*)((char *)pTIHeader + pTIHeader->href_table), pTI,
+        ref_lookup = SLTG_DoRefs((SLTG_RefInfo*)((char *)pTIHeader + pTIHeader->href_table), pTI->pTypeLib,
 		    pNameTable);
     }
 
     pFirstItem = pNextItem = pBlk;
 
     if(*(WORD*)pFirstItem == SLTG_IMPL_MAGIC) {
-        pNextItem = SLTG_DoImpls(pFirstItem, pTI, FALSE);
-    }
+        pNextItem = SLTG_DoImpls(pFirstItem, pTI, FALSE, ref_lookup);
+    }
+    HeapFree(GetProcessHeap(), 0, ref_lookup);
 }
 
 
@@ -3091,20 +3141,23 @@
 				  SLTG_TypeInfoTail *pTITail)
 {
     char *pFirstItem, *pNextItem;
+    sltg_ref_lookup_t *ref_lookup = NULL;
 
     if(pTIHeader->href_table != 0xffffffff) {
-        SLTG_DoRefs((SLTG_RefInfo*)((char *)pTIHeader + pTIHeader->href_table), pTI,
+        ref_lookup = SLTG_DoRefs((SLTG_RefInfo*)((char *)pTIHeader + pTIHeader->href_table), pTI->pTypeLib,
 		    pNameTable);
     }
 
     pFirstItem = pNextItem = pBlk;
 
     if(*(WORD*)pFirstItem == SLTG_IMPL_MAGIC) {
-        pNextItem = SLTG_DoImpls(pFirstItem, pTI, TRUE);
+        pNextItem = SLTG_DoImpls(pFirstItem, pTI, TRUE, ref_lookup);
     }
 
     if (pTITail->funcs_off != 0xffff)
-        SLTG_DoFuncs(pBlk, pBlk + pTITail->funcs_off, pTI, pTITail->cFuncs, pNameTable);
+        SLTG_DoFuncs(pBlk, pBlk + pTITail->funcs_off, pTI, pTITail->cFuncs, pNameTable, ref_lookup);
+
+    HeapFree(GetProcessHeap(), 0, ref_lookup);
 
     if (TRACE_ON(typelib))
         dump_TLBFuncDesc(pTI->funclist);
@@ -3114,7 +3167,7 @@
 			       char *pNameTable, SLTG_TypeInfoHeader *pTIHeader,
 			       SLTG_TypeInfoTail *pTITail)
 {
-  SLTG_DoVars(pBlk, pBlk + pTITail->vars_off, pTI, pTITail->cVars, pNameTable);
+  SLTG_DoVars(pBlk, pBlk + pTITail->vars_off, pTI, pTITail->cVars, pNameTable, NULL);
 }
 
 static void SLTG_ProcessAlias(char *pBlk, ITypeInfoImpl *pTI,
@@ -3122,6 +3175,7 @@
 			      SLTG_TypeInfoTail *pTITail)
 {
   WORD *pType;
+  sltg_ref_lookup_t *ref_lookup = NULL;
 
   if (pTITail->simple_alias) {
     /* if simple alias, no more processing required */
@@ -3130,35 +3184,39 @@
   }
 
   if(pTIHeader->href_table != 0xffffffff) {
-      SLTG_DoRefs((SLTG_RefInfo*)((char *)pTIHeader + pTIHeader->href_table), pTI,
+      ref_lookup = SLTG_DoRefs((SLTG_RefInfo*)((char *)pTIHeader + pTIHeader->href_table), pTI->pTypeLib,
 		  pNameTable);
   }
 
   /* otherwise it is an offset to a type */
   pType = (WORD *)(pBlk + pTITail->tdescalias_vt);
 
-  SLTG_DoType(pType, pBlk, &pTI->TypeAttr.tdescAlias);
+  SLTG_DoType(pType, pBlk, &pTI->TypeAttr.tdescAlias, ref_lookup);
+
+  HeapFree(GetProcessHeap(), 0, ref_lookup);
 }
 
 static void SLTG_ProcessDispatch(char *pBlk, ITypeInfoImpl *pTI,
 				 char *pNameTable, SLTG_TypeInfoHeader *pTIHeader,
 				 SLTG_TypeInfoTail *pTITail)
 {
+  sltg_ref_lookup_t *ref_lookup = NULL;
   if (pTIHeader->href_table != 0xffffffff)
-      SLTG_DoRefs((SLTG_RefInfo*)((char *)pTIHeader + pTIHeader->href_table), pTI,
+      ref_lookup = SLTG_DoRefs((SLTG_RefInfo*)((char *)pTIHeader + pTIHeader->href_table), pTI->pTypeLib,
                                   pNameTable);
 
   if (pTITail->vars_off != 0xffff)
-    SLTG_DoVars(pBlk, pBlk + pTITail->vars_off, pTI, pTITail->cVars, pNameTable);
+    SLTG_DoVars(pBlk, pBlk + pTITail->vars_off, pTI, pTITail->cVars, pNameTable, ref_lookup);
 
   if (pTITail->funcs_off != 0xffff)
-    SLTG_DoFuncs(pBlk, pBlk + pTITail->funcs_off, pTI, pTITail->cFuncs, pNameTable);
+    SLTG_DoFuncs(pBlk, pBlk + pTITail->funcs_off, pTI, pTITail->cFuncs, pNameTable, ref_lookup);
 
   /* this is necessary to cope with MSFT typelibs that set cFuncs to the number
    * of dispinterface functons including the IDispatch ones, so
    * ITypeInfo::GetFuncDesc takes the real value for cFuncs from cbSizeVft */
   pTI->TypeAttr.cbSizeVft = pTI->TypeAttr.cFuncs * sizeof(void *);
 
+  HeapFree(GetProcessHeap(), 0, ref_lookup);
   if (TRACE_ON(typelib))
       dump_TLBFuncDesc(pTI->funclist);
 }
@@ -3167,22 +3225,24 @@
 			     char *pNameTable, SLTG_TypeInfoHeader *pTIHeader,
                              SLTG_TypeInfoTail *pTITail)
 {
-  SLTG_DoVars(pBlk, pBlk + pTITail->vars_off, pTI, pTITail->cVars, pNameTable);
+  SLTG_DoVars(pBlk, pBlk + pTITail->vars_off, pTI, pTITail->cVars, pNameTable, NULL);
 }
 
 static void SLTG_ProcessModule(char *pBlk, ITypeInfoImpl *pTI,
 			       char *pNameTable, SLTG_TypeInfoHeader *pTIHeader,
 			       SLTG_TypeInfoTail *pTITail)
 {
+  sltg_ref_lookup_t *ref_lookup = NULL;
   if (pTIHeader->href_table != 0xffffffff)
-      SLTG_DoRefs((SLTG_RefInfo*)((char *)pTIHeader + pTIHeader->href_table), pTI,
+      ref_lookup = SLTG_DoRefs((SLTG_RefInfo*)((char *)pTIHeader + pTIHeader->href_table), pTI->pTypeLib,
                                   pNameTable);
 
   if (pTITail->vars_off != 0xffff)
-    SLTG_DoVars(pBlk, pBlk + pTITail->vars_off, pTI, pTITail->cVars, pNameTable);
+    SLTG_DoVars(pBlk, pBlk + pTITail->vars_off, pTI, pTITail->cVars, pNameTable, ref_lookup);
 
   if (pTITail->funcs_off != 0xffff)
-    SLTG_DoFuncs(pBlk, pBlk + pTITail->funcs_off, pTI, pTITail->cFuncs, pNameTable);
+    SLTG_DoFuncs(pBlk, pBlk + pTITail->funcs_off, pTI, pTITail->cFuncs, pNameTable, ref_lookup);
+  HeapFree(GetProcessHeap(), 0, ref_lookup);
 }
 
 /* Because SLTG_OtherTypeInfo is such a painful struct, we make a more
@@ -3553,6 +3613,8 @@
     {
       TLBImpLib *pImpLib, *pImpLibNext;
       TLBCustData *pCustData, *pCustDataNext;
+      TLBRefType *ref_type;
+      void *cursor2;
       int i;
 
       /* remove cache entry */
@@ -3614,6 +3676,12 @@
 
           pImpLibNext = pImpLib->next;
           TLB_Free(pImpLib);
+      }
+
+      LIST_FOR_EACH_ENTRY_SAFE(ref_type, cursor2, &This->ref_list, TLBRefType, entry)
+      {
+          list_remove(&ref_type->entry);
+          TLB_Free(ref_type);
       }
 
       if (This->pTypeInfo) /* can be NULL */
@@ -4402,7 +4470,6 @@
       TLBFuncDesc *pFInfo, *pFInfoNext;
       TLBVarDesc *pVInfo, *pVInfoNext;
       TLBImplType *pImpl, *pImplNext;
-      TLBRefType *pRefType,*pRefTypeNext;
       TLBCustData *pCustData, *pCustDataNext;
 
       TRACE("destroying ITypeInfo(%p)\n",This);
@@ -4481,11 +4548,6 @@
           pImplNext = pImpl->next;
           TLB_Free(pImpl);
       }
-      for(pRefType = This->reflist; pRefType; pRefType = pRefTypeNext)
-      {
-          pRefTypeNext = pRefType->next;
-          TLB_Free(pRefType);
-      }
       TLB_Free(This->pCustData);
 
 finish_free:
@@ -4690,47 +4752,47 @@
         return S_OK;
     }
 
-    return E_INVALIDARG;
+    return TYPE_E_ELEMENTNOTFOUND;
 }
 
 /* internal function to make the inherited interfaces' methods appear
  * part of the interface */
 static HRESULT ITypeInfoImpl_GetInternalDispatchFuncDesc( ITypeInfo *iface,
-    UINT index, const FUNCDESC **ppFuncDesc, UINT *funcs)
+    UINT index, const FUNCDESC **ppFuncDesc, UINT *funcs, UINT *hrefoffset)
 {
     ITypeInfoImpl *This = (ITypeInfoImpl *)iface;
     HRESULT hr;
-    UINT i;
     UINT implemented_funcs = 0;
 
     if (funcs)
         *funcs = 0;
-
-    for (i = 0; i < This->TypeAttr.cImplTypes; i++)
-    {
-        HREFTYPE href;
+    else
+        *hrefoffset = DISPATCH_HREF_OFFSET;
+
+    if(This->impltypelist)
+    {
         ITypeInfo *pSubTypeInfo;
         UINT sub_funcs;
 
-        hr = ITypeInfo_GetRefTypeOfImplType(iface, i, &href);
-        if (FAILED(hr))
-            return hr;
-        hr = ITypeInfo_GetRefTypeInfo(iface, href, &pSubTypeInfo);
+        hr = ITypeInfo_GetRefTypeInfo(iface, This->impltypelist->hRef, &pSubTypeInfo);
         if (FAILED(hr))
             return hr;
 
         hr = ITypeInfoImpl_GetInternalDispatchFuncDesc(pSubTypeInfo,
                                                        index,
                                                        ppFuncDesc,
-                                                       &sub_funcs);
+                                                       &sub_funcs, hrefoffset);
         implemented_funcs += sub_funcs;
         ITypeInfo_Release(pSubTypeInfo);
         if (SUCCEEDED(hr))
             return hr;
+        *hrefoffset += DISPATCH_HREF_OFFSET;
     }
 
     if (funcs)
         *funcs = implemented_funcs + This->TypeAttr.cFuncs;
+    else
+        *hrefoffset = 0;
     
     if (index < implemented_funcs)
         return E_INVALIDARG;
@@ -4738,6 +4800,37 @@
                                              ppFuncDesc);
 }
 
+static inline void ITypeInfoImpl_ElemDescAddHrefOffset( LPELEMDESC pElemDesc, UINT hrefoffset)
+{
+    TYPEDESC *pTypeDesc = &pElemDesc->tdesc;
+    while (TRUE)
+    {
+        switch (pTypeDesc->vt)
+        {
+        case VT_USERDEFINED:
+            pTypeDesc->u.hreftype += hrefoffset;
+            return;
+        case VT_PTR:
+        case VT_SAFEARRAY:
+            pTypeDesc = pTypeDesc->u.lptdesc;
+            break;
+        case VT_CARRAY:
+            pTypeDesc = &pTypeDesc->u.lpadesc->tdescElem;
+            break;
+        default:
+            return;
+        }
+    }
+}
+
+static inline void ITypeInfoImpl_FuncDescAddHrefOffset( LPFUNCDESC pFuncDesc, UINT hrefoffset)
+{
+    SHORT i;
+    for (i = 0; i < pFuncDesc->cParams; i++)
+        ITypeInfoImpl_ElemDescAddHrefOffset(&pFuncDesc->lprgelemdescParam[i], hrefoffset);
+    ITypeInfoImpl_ElemDescAddHrefOffset(&pFuncDesc->elemdescFunc, hrefoffset);
+}
+
 /* ITypeInfo::GetFuncDesc
  *
  * Retrieves the FUNCDESC structure that contains information about a
@@ -4750,13 +4843,14 @@
     ITypeInfoImpl *This = (ITypeInfoImpl *)iface;
     const FUNCDESC *internal_funcdesc;
     HRESULT hr;
+    UINT hrefoffset = 0;
 
     TRACE("(%p) index %d\n", This, index);
 
-    if ((This->TypeAttr.typekind == TKIND_DISPATCH) &&
-        (This->TypeAttr.wTypeFlags & TYPEFLAG_FDUAL))
+    if (This->TypeAttr.typekind == TKIND_DISPATCH)
         hr = ITypeInfoImpl_GetInternalDispatchFuncDesc((ITypeInfo *)iface, index,
-                                                       &internal_funcdesc, NULL);
+                                                       &internal_funcdesc, NULL,
+                                                       &hrefoffset);
     else
         hr = ITypeInfoImpl_GetInternalFuncDesc((ITypeInfo *)iface, index,
                                                &internal_funcdesc);
@@ -4766,10 +4860,16 @@
         return hr;
     }
 
-    return TLB_AllocAndInitFuncDesc(
+    hr = TLB_AllocAndInitFuncDesc(
         internal_funcdesc,
         ppFuncDesc,
         This->TypeAttr.typekind == TKIND_DISPATCH);
+
+    if ((This->TypeAttr.typekind == TKIND_DISPATCH) && hrefoffset)
+        ITypeInfoImpl_FuncDescAddHrefOffset(*ppFuncDesc, hrefoffset);
+
+    TRACE("-- 0x%08x\n", hr);
+    return hr;
 }
 
 static HRESULT TLB_AllocAndInitVarDesc( const VARDESC *src, VARDESC **dest_ptr )
@@ -4885,7 +4985,7 @@
       }
       else
       {
-        if(This->TypeAttr.cImplTypes &&
+        if(This->impltypelist &&
 	   (This->TypeAttr.typekind==TKIND_INTERFACE || This->TypeAttr.typekind==TKIND_DISPATCH)) {
           /* recursive search */
           ITypeInfo *pTInfo;
@@ -4950,6 +5050,11 @@
         hr = TYPE_E_ELEMENTNOTFOUND;
       }
     }
+    else if(index == 0 && This->TypeAttr.typekind == TKIND_DISPATCH)
+    {
+      /* All TKIND_DISPATCHs are made to look like they inherit from IDispatch */
+      *pRefType = This->pTypeLib->dispatch_href;
+    }
     else
     {
       /* get element n from linked list */
@@ -5043,7 +5148,7 @@
         }
     }
     /* not found, see if it can be found in an inherited interface */
-    if(This->TypeAttr.cImplTypes) {
+    if(This->impltypelist) {
         /* recursive search */
         ITypeInfo *pTInfo;
         ret=ITypeInfo_GetRefTypeInfo(iface,
@@ -5151,6 +5256,27 @@
 	case 23:
 		res = func(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8],args[9],args[10],args[11],args[12],args[13],args[14],args[15],args[16],args[17],args[18],args[19],args[20],args[21],args[22]);
 		break;
+	case 24:
+                res = func(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8],args[9],args[10],args[11],args[12],args[13],args[14],args[15],args[16],args[17],args[18],args[19],args[20],args[21],args[22],args[23]);
+                break;
+	case 25:
+                res = func(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8],args[9],args[10],args[11],args[12],args[13],args[14],args[15],args[16],args[17],args[18],args[19],args[20],args[21],args[22],args[23],args[24]);
+                break;
+	case 26:
+                res = func(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8],args[9],args[10],args[11],args[12],args[13],args[14],args[15],args[16],args[17],args[18],args[19],args[20],args[21],args[22],args[23],args[24],args[25]);
+                break;
+	case 27:
+                res = func(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8],args[9],args[10],args[11],args[12],args[13],args[14],args[15],args[16],args[17],args[18],args[19],args[20],args[21],args[22],args[23],args[24],args[25],args[26]);
+                break;
+	case 28:
+                res = func(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8],args[9],args[10],args[11],args[12],args[13],args[14],args[15],args[16],args[17],args[18],args[19],args[20],args[21],args[22],args[23],args[24],args[25],args[26],args[27]);
+                break;
+	case 29:
+                res = func(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8],args[9],args[10],args[11],args[12],args[13],args[14],args[15],args[16],args[17],args[18],args[19],args[20],args[21],args[22],args[23],args[24],args[25],args[26],args[27],args[28]);
+                break;
+	case 30:
+                res = func(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8],args[9],args[10],args[11],args[12],args[13],args[14],args[15],args[16],args[17],args[18],args[19],args[20],args[21],args[22],args[23],args[24],args[25],args[26],args[27],args[28],args[29]);
+                break;
 	default:
 		FIXME("unsupported number of arguments %d in stdcall\n",nrargs);
 		res = -1;
@@ -5202,7 +5328,7 @@
         break;
 
     case TKIND_INTERFACE:
-        if (IsEqualIID(&IID_IDispatch, &tattr->guid))
+        if (tattr->wTypeFlags & TYPEFLAG_FDISPATCHABLE)
            *vt |= VT_DISPATCH;
         else
            *vt |= VT_UNKNOWN;
@@ -5489,6 +5615,13 @@
                 rgdispidNamedArgs++;
             }
 
+            if (func_desc->cParamsOpt < 0 && cNamedArgs)
+            {
+                ERR("functions with the vararg attribute do not support named arguments\n");
+                hres = DISP_E_NONAMEDARGS;
+                goto func_fail;
+            }
+
             for (i = 0; i < func_desc->cParams; i++)
             {
                 TYPEDESC *tdesc = &func_desc->lprgelemdescParam[i].tdesc;
@@ -5567,6 +5700,36 @@
                             hres = VariantCopy(&missing_arg[i], src_arg);
                             V_VARIANTREF(&rgvarg[i]) = &missing_arg[i];
                         }
+                        V_VT(&rgvarg[i]) = rgvt[i];
+                    }
+                    else if (rgvt[i] == (VT_VARIANT | VT_ARRAY) && func_desc->cParamsOpt < 0 && i == func_desc->cParams-1)
+                    {
+                        SAFEARRAY *a;
+                        SAFEARRAYBOUND bound;
+                        VARIANT *v;
+                        LONG j;
+                        bound.lLbound = 0;
+                        bound.cElements = pDispParams->cArgs-i;
+                        if (!(a = SafeArrayCreate(VT_VARIANT, 1, &bound)))
+                        {
+                            ERR("SafeArrayCreate failed\n");
+                            break;
+                        }
+                        hres = SafeArrayAccessData(a, (LPVOID)&v);
+                        if (hres != S_OK)
+                        {
+                            ERR("SafeArrayAccessData failed with %x\n", hres);
+                            break;
+                        }
+                        for (j = 0; j < bound.cElements; j++)
+                            VariantCopy(&v[j], &pDispParams->rgvarg[pDispParams->cArgs - 1 - i - j]);
+                        hres = SafeArrayUnaccessData(a);
+                        if (hres != S_OK)
+                        {
+                            ERR("SafeArrayUnaccessData failed with %x\n", hres);
+                            break;
+                        }
+                        V_ARRAY(&rgvarg[i]) = a;
                         V_VT(&rgvarg[i]) = rgvt[i];
                     }
                     else if ((rgvt[i] & VT_BYREF) && !V_ISBYREF(src_arg))
@@ -5635,12 +5798,6 @@
                 }
             }
             if (FAILED(hres)) goto func_fail; /* FIXME: we don't free changed types here */
-            if (func_desc->cParamsOpt < 0)
-            {
-                FIXME("Does not support safearray optional parameters\n");
-                hres = DISP_E_BADPARAMCOUNT;
-                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 */
@@ -5704,6 +5861,34 @@
                             break;
                         }
                     }
+                    else if (V_VT(prgpvarg[i]) == (VT_VARIANT | VT_ARRAY) &&
+                             func_desc->cParamsOpt < 0 &&
+                             i == func_desc->cParams-1)
+                    {
+                        SAFEARRAY *a = V_ARRAY(prgpvarg[i]);
+                        LONG j, ubound;
+                        VARIANT *v;
+                        hres = SafeArrayGetUBound(a, 1, &ubound);
+                        if (hres != S_OK)
+                        {
+                            ERR("SafeArrayGetUBound failed with %x\n", hres);
+                            break;
+                        }
+                        hres = SafeArrayAccessData(a, (LPVOID)&v);
+                        if (hres != S_OK)
+                        {
+                            ERR("SafeArrayAccessData failed with %x\n", hres);
+                            break;
+                        }
+                        for (j = 0; j <= ubound; j++)
+                            VariantClear(&v[j]);
+                        hres = SafeArrayUnaccessData(a);
+                        if (hres != S_OK)
+                        {
+                            ERR("SafeArrayUnaccessData failed with %x\n", hres);
+                            break;
+                        }
+                    }
                     VariantClear(&rgvarg[i]);
                 }
                 else if (wParamFlags & PARAMFLAG_FOPT)
@@ -5747,7 +5932,7 @@
             }
 
             if (SUCCEEDED(hres) && pVarResult && (func_desc->cParams == 1) &&
-                (wFlags == INVOKE_PROPERTYGET) &&
+                (func_desc->invkind & INVOKE_PROPERTYGET) &&
                 (func_desc->lprgelemdescParam[0].u.paramdesc.wParamFlags & PARAMFLAG_FRETVAL) &&
                 (pDispParams->cArgs != 0))
             {
@@ -5814,11 +5999,10 @@
     /* not found, look for it in inherited interfaces */
     ITypeInfo2_GetTypeKind(iface, &type_kind);
     if(type_kind == TKIND_INTERFACE || type_kind == TKIND_DISPATCH) {
-        HREFTYPE ref_type;
-        if(SUCCEEDED(ITypeInfo2_GetRefTypeOfImplType(iface, 0, &ref_type))) {
+        if(This->impltypelist) {
             /* recursive search */
             ITypeInfo *pTInfo;
-            hres = ITypeInfo_GetRefTypeInfo(iface, ref_type, &pTInfo);
+            hres = ITypeInfo_GetRefTypeInfo(iface, This->impltypelist->hRef, &pTInfo);
             if(SUCCEEDED(hres)){
                 hres = ITypeInfo_Invoke(pTInfo,pIUnk,memid,wFlags,pDispParams,pVarResult,pExcepInfo,pArgErr);
                 ITypeInfo_Release(pTInfo);
@@ -5881,7 +6065,7 @@
         }
     }
 
-    if(This->TypeAttr.cImplTypes &&
+    if(This->impltypelist &&
        (This->TypeAttr.typekind==TKIND_INTERFACE || This->TypeAttr.typekind==TKIND_DISPATCH)) {
         /* recursive search */
         ITypeInfo *pTInfo;
@@ -5947,6 +6131,38 @@
     return TYPE_E_ELEMENTNOTFOUND;
 }
 
+/* internal function to make the inherited interfaces' methods appear
+ * part of the interface */
+static HRESULT ITypeInfoImpl_GetDispatchRefTypeInfo( ITypeInfo *iface,
+    HREFTYPE *hRefType, ITypeInfo  **ppTInfo)
+{
+    ITypeInfoImpl *This = (ITypeInfoImpl *)iface;
+    HRESULT hr;
+
+    TRACE("%p, 0x%x\n", iface, *hRefType);
+
+    if (This->impltypelist && (*hRefType & DISPATCH_HREF_MASK))
+    {
+        ITypeInfo *pSubTypeInfo;
+
+        hr = ITypeInfo_GetRefTypeInfo(iface, This->impltypelist->hRef, &pSubTypeInfo);
+        if (FAILED(hr))
+            return hr;
+
+        hr = ITypeInfoImpl_GetDispatchRefTypeInfo(pSubTypeInfo,
+                                                  hRefType, ppTInfo);
+        ITypeInfo_Release(pSubTypeInfo);
+        if (SUCCEEDED(hr))
+            return hr;
+    }
+    *hRefType -= DISPATCH_HREF_OFFSET;
+
+    if (!(*hRefType & DISPATCH_HREF_MASK))
+        return ITypeInfo_GetRefTypeInfo(iface, *hRefType, ppTInfo);
+    else
+        return E_FAIL;
+}
+
 /* ITypeInfo::GetRefTypeInfo
  *
  * If a type description references other type descriptions, it retrieves
@@ -5967,8 +6183,8 @@
         result = S_OK;
     }
     else if (hRefType == -1 &&
-	(((ITypeInfoImpl*) This)->TypeAttr.typekind   == TKIND_DISPATCH) &&
-	(((ITypeInfoImpl*) This)->TypeAttr.wTypeFlags &  TYPEFLAG_FDUAL))
+	(This->TypeAttr.typekind   == TKIND_DISPATCH) &&
+	(This->TypeAttr.wTypeFlags &  TYPEFLAG_FDUAL))
     {
 	  /* when we meet a DUAL dispinterface, we must create the interface
 	  * version of it.
@@ -5998,52 +6214,62 @@
 
 	  result = S_OK;
 
+    } else if ((hRefType != -1) && (hRefType & DISPATCH_HREF_MASK) &&
+        (This->TypeAttr.typekind   == TKIND_DISPATCH) &&
+	(This->TypeAttr.wTypeFlags &  TYPEFLAG_FDUAL))
+    {
+        HREFTYPE href_dispatch = hRefType;
+        result = ITypeInfoImpl_GetDispatchRefTypeInfo((ITypeInfo *)iface, &href_dispatch, ppTInfo);
     } else {
-        TLBRefType *pRefType;
-        for(pRefType = This->reflist; pRefType; pRefType = pRefType->next) {
-	    if(pRefType->reference == hRefType)
-	        break;
-	}
-	if(!pRefType)
-	  FIXME("Can't find pRefType for ref %x\n", hRefType);
-	if(pRefType && hRefType != -1) {
+        TLBRefType *ref_type;
+        LIST_FOR_EACH_ENTRY(ref_type, &This->pTypeLib->ref_list, TLBRefType, entry)
+        {
+            if(ref_type->reference == hRefType)
+                break;
+        }
+        if(&ref_type->entry == &This->pTypeLib->ref_list)
+        {
+            FIXME("Can't find pRefType for ref %x\n", hRefType);
+            goto end;
+        }
+        if(hRefType != -1) {
             ITypeLib *pTLib = NULL;
 
-	    if(pRefType->pImpTLInfo == TLB_REF_INTERNAL) {
+            if(ref_type->pImpTLInfo == TLB_REF_INTERNAL) {
 	        UINT Index;
 		result = ITypeInfo_GetContainingTypeLib(iface, &pTLib, &Index);
 	    } else {
-	        if(pRefType->pImpTLInfo->pImpTypeLib) {
+                if(ref_type->pImpTLInfo->pImpTypeLib) {
 		    TRACE("typeinfo in imported typelib that is already loaded\n");
-		    pTLib = (ITypeLib*)pRefType->pImpTLInfo->pImpTypeLib;
+                    pTLib = (ITypeLib*)ref_type->pImpTLInfo->pImpTypeLib;
 		    ITypeLib2_AddRef((ITypeLib*) pTLib);
 		    result = S_OK;
 		} else {
 		    TRACE("typeinfo in imported typelib that isn't already loaded\n");
-		    result = LoadRegTypeLib( &pRefType->pImpTLInfo->guid,
-					     pRefType->pImpTLInfo->wVersionMajor,
-					     pRefType->pImpTLInfo->wVersionMinor,
-					     pRefType->pImpTLInfo->lcid,
+                    result = LoadRegTypeLib( &ref_type->pImpTLInfo->guid,
+                                             ref_type->pImpTLInfo->wVersionMajor,
+                                             ref_type->pImpTLInfo->wVersionMinor,
+                                             ref_type->pImpTLInfo->lcid,
 					     &pTLib);
 
 		    if(!SUCCEEDED(result)) {
-		        BSTR libnam=SysAllocString(pRefType->pImpTLInfo->name);
+                        BSTR libnam=SysAllocString(ref_type->pImpTLInfo->name);
 			result=LoadTypeLib(libnam, &pTLib);
 			SysFreeString(libnam);
 		    }
 		    if(SUCCEEDED(result)) {
-		        pRefType->pImpTLInfo->pImpTypeLib = (ITypeLibImpl*)pTLib;
+                        ref_type->pImpTLInfo->pImpTypeLib = (ITypeLibImpl*)pTLib;
 			ITypeLib2_AddRef(pTLib);
 		    }
 		}
 	    }
 	    if(SUCCEEDED(result)) {
-	        if(pRefType->index == TLB_REF_USE_GUID)
+                if(ref_type->index == TLB_REF_USE_GUID)
 		    result = ITypeLib2_GetTypeInfoOfGuid(pTLib,
-							 &pRefType->guid,
+                                                         &ref_type->guid,
 							 ppTInfo);
 		else
-		    result = ITypeLib2_GetTypeInfo(pTLib, pRefType->index,
+                    result = ITypeLib2_GetTypeInfo(pTLib, ref_type->index,
 						   ppTInfo);
 	    }
 	    if (pTLib != NULL)
@@ -6051,6 +6277,7 @@
 	}
     }
 
+end:
     TRACE("(%p) hreftype 0x%04x loaded %s (%p)\n", This, hRefType,
           SUCCEEDED(result)? "SUCCESS":"FAILURE", *ppTInfo);
     return result;
@@ -6809,6 +7036,7 @@
     ITypeLibImpl *pTypeLibImpl;
     int param, func;
     TLBFuncDesc **ppFuncDesc;
+    TLBRefType *ref;
 
     TRACE("\n");
     pTypeLibImpl = TypeLibImpl_Constructor();
@@ -6865,6 +7093,7 @@
         (*ppFuncDesc)->ctCustData = 0;
         (*ppFuncDesc)->pCustData = NULL;
         (*ppFuncDesc)->next = NULL;
+        pTIIface->TypeAttr.cFuncs++;
         ppFuncDesc = &(*ppFuncDesc)->next;
     }
 
@@ -6892,12 +7121,13 @@
     pTIClass->TypeAttr.wTypeFlags = 0;
 
     pTIClass->impltypelist = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*pTIClass->impltypelist));
-    pTIClass->impltypelist->hRef = 1;
-
-    pTIClass->reflist = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*pTIClass->reflist));
-    pTIClass->reflist->index = 0;
-    pTIClass->reflist->reference = 1;
-    pTIClass->reflist->pImpTLInfo = TLB_REF_INTERNAL;
+    pTIClass->impltypelist->hRef = 0;
+
+    ref = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*ref));
+    ref->index = 0;
+    ref->reference = 0;
+    ref->pImpTLInfo = TLB_REF_INTERNAL;
+    list_add_head(&pTypeLibImpl->ref_list, &ref->entry);
 
     dump_TypeInfo(pTIClass);
 
@@ -6989,7 +7219,7 @@
         }
     }
     /* FIXME: search each inherited interface, not just the first */
-    if (hr == DISP_E_MEMBERNOTFOUND && This->TypeAttr.cImplTypes) {
+    if (hr == DISP_E_MEMBERNOTFOUND && This->impltypelist) {
         /* recursive search */
         ITypeInfo *pTInfo;
         ITypeComp *pTComp;

Modified: trunk/reactos/dll/win32/oleaut32/typelib16.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/oleaut32/typelib16.c?rev=27914&r1=27913&r2=27914&view=diff
==============================================================================
--- trunk/reactos/dll/win32/oleaut32/typelib16.c (original)
+++ trunk/reactos/dll/win32/oleaut32/typelib16.c Fri Jul 27 13:59:17 2007
@@ -33,7 +33,6 @@
 #include "winerror.h"
 #include "windef.h"
 #include "winbase.h"
-#include "winnls.h"
 #include "winreg.h"
 #include "winuser.h"
 

Modified: trunk/reactos/dll/win32/oleaut32/typelib2.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/oleaut32/typelib2.c?rev=27914&r1=27913&r2=27914&view=diff
==============================================================================
--- trunk/reactos/dll/win32/oleaut32/typelib2.c (original)
+++ trunk/reactos/dll/win32/oleaut32/typelib2.c Fri Jul 27 13:59:17 2007
@@ -43,7 +43,6 @@
 #include "windef.h"
 #include "winbase.h"
 #include "winnls.h"
-#include "winreg.h"
 #include "winuser.h"
 
 #include "wine/unicode.h"

Modified: trunk/reactos/dll/win32/oleaut32/usrmarshal.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/oleaut32/usrmarshal.c?rev=27914&r1=27913&r2=27914&view=diff
==============================================================================
--- trunk/reactos/dll/win32/oleaut32/usrmarshal.c (original)
+++ trunk/reactos/dll/win32/oleaut32/usrmarshal.c Fri Jul 27 13:59:17 2007
@@ -277,14 +277,14 @@
     return 7;
 }
 
-static unsigned interface_variant_size(ULONG *pFlags, REFIID riid, VARIANT *pvar)
+static unsigned interface_variant_size(ULONG *pFlags, REFIID riid, IUnknown *punk)
 {
   ULONG size;
   HRESULT hr;
   /* find the buffer size of the marshalled dispatch interface */
-  hr = CoGetMarshalSizeMax(&size, riid, V_UNKNOWN(pvar), LOWORD(*pFlags), NULL, MSHLFLAGS_NORMAL);
+  hr = CoGetMarshalSizeMax(&size, riid, punk, LOWORD(*pFlags), NULL, MSHLFLAGS_NORMAL);
   if (FAILED(hr)) {
-    if (!V_DISPATCH(pvar))
+    if (!punk)
       WARN("NULL dispatch pointer\n");
     else
       ERR("Dispatch variant buffer size calculation failed, HRESULT=0x%x\n", hr);
@@ -313,9 +313,13 @@
   case VT_VARIANT | VT_BYREF:
     return VARIANT_UserSize(pFlags, Start, V_VARIANTREF(pvar));
   case VT_UNKNOWN:
-    return Start + interface_variant_size(pFlags, &IID_IUnknown, pvar);
+    return Start + interface_variant_size(pFlags, &IID_IUnknown, V_UNKNOWN(pvar));
+  case VT_UNKNOWN | VT_BYREF:
+    return Start + interface_variant_size(pFlags, &IID_IUnknown, *V_UNKNOWNREF(pvar));
   case VT_DISPATCH:
-    return Start + interface_variant_size(pFlags, &IID_IDispatch, pvar);
+    return Start + interface_variant_size(pFlags, &IID_IDispatch, (IUnknown*)V_DISPATCH(pvar));
+  case VT_DISPATCH | VT_BYREF:
+    return Start + interface_variant_size(pFlags, &IID_IDispatch, (IUnknown*)*V_DISPATCHREF(pvar));
   case VT_RECORD:
     FIXME("wire-size record\n");
     return Start;
@@ -329,7 +333,7 @@
 }
 
 /* helper: called for VT_DISPATCH variants to marshal the IDispatch* into the buffer. returns Buffer on failure, new position otherwise */
-static unsigned char* interface_variant_marshal(ULONG *pFlags, unsigned char *Buffer, REFIID riid, VARIANT *pvar)
+static unsigned char* interface_variant_marshal(ULONG *pFlags, unsigned char *Buffer, REFIID riid, IUnknown *punk)
 {
   IStream *working; 
   HGLOBAL working_mem;
@@ -338,7 +342,7 @@
   ULONG size;
   HRESULT hr;
   
-  TRACE("pFlags=%d, Buffer=%p, pvar=%p\n", *pFlags, Buffer, pvar);
+  TRACE("pFlags=%d, Buffer=%p, pUnk=%p\n", *pFlags, Buffer, punk);
 
   oldpos = Buffer;
   
@@ -348,7 +352,7 @@
    * but that would be overkill here, hence this implementation. We save the size because the unmarshal
    * code has no way to know how long the marshalled buffer is. */
 
-  size = wire_extra_user_size(pFlags, 0, pvar);
+  size = interface_variant_size(pFlags, riid, punk);
   
   working_mem = GlobalAlloc(0, size);
   if (!working_mem) return oldpos;
@@ -359,7 +363,7 @@
     return oldpos;
   }
   
-  hr = CoMarshalInterface(working, riid, V_UNKNOWN(pvar), LOWORD(*pFlags), NULL, MSHLFLAGS_NORMAL);
+  hr = CoMarshalInterface(working, riid, punk, LOWORD(*pFlags), NULL, MSHLFLAGS_NORMAL);
   if (hr != S_OK) {
     IStream_Release(working); /* this also releases the hglobal */
     return oldpos;
@@ -378,7 +382,7 @@
 }
 
 /* helper: called for VT_DISPATCH / VT_UNKNOWN variants to unmarshal the buffer. returns Buffer on failure, new position otherwise */
-static unsigned char *interface_variant_unmarshal(ULONG *pFlags, unsigned char *Buffer, REFIID riid, VARIANT *pvar)
+static unsigned char *interface_variant_unmarshal(ULONG *pFlags, unsigned char *Buffer, REFIID riid, IUnknown **ppunk)
 {
   IStream *working;
   HGLOBAL working_mem;
@@ -387,10 +391,10 @@
   ULONG size;
   HRESULT hr;
   
-  TRACE("pFlags=%d, Buffer=%p, pvar=%p\n", *pFlags, Buffer, pvar);
+  TRACE("pFlags=%d, Buffer=%p, ppUnk=%p\n", *pFlags, Buffer, ppunk);
 
   oldpos = Buffer;
-  
+
   /* get the buffersize */
   memcpy(&size, Buffer, sizeof(ULONG));
   TRACE("buffersize=%d\n", size);
@@ -410,7 +414,7 @@
   memcpy(working_memlocked, Buffer + sizeof(ULONG), size);
   GlobalUnlock(working_mem);
 
-  hr = CoUnmarshalInterface(working, riid, (void**)&V_UNKNOWN(pvar));
+  hr = CoUnmarshalInterface(working, riid, (void**)ppunk);
   if (hr != S_OK) {
     IStream_Release(working);
     return oldpos;
@@ -520,16 +524,21 @@
         case VT_VARIANT | VT_BYREF:
             Pos = VARIANT_UserMarshal(pFlags, Pos, V_VARIANTREF(pvar));
             break;
-        case VT_DISPATCH | VT_BYREF:
-            FIXME("handle DISPATCH by ref\n");
-            break;
         case VT_UNKNOWN:
             /* this should probably call WdtpInterfacePointer_UserMarshal in ole32.dll */
-            Pos = interface_variant_marshal(pFlags, Pos, &IID_IUnknown, pvar);
+            Pos = interface_variant_marshal(pFlags, Pos, &IID_IUnknown, V_UNKNOWN(pvar));
+            break;
+        case VT_UNKNOWN | VT_BYREF:
+            /* this should probably call WdtpInterfacePointer_UserMarshal in ole32.dll */
+            Pos = interface_variant_marshal(pFlags, Pos, &IID_IUnknown, *V_UNKNOWNREF(pvar));
             break;
         case VT_DISPATCH:
             /* this should probably call WdtpInterfacePointer_UserMarshal in ole32.dll */
-            Pos = interface_variant_marshal(pFlags, Pos, &IID_IDispatch, pvar);
+            Pos = interface_variant_marshal(pFlags, Pos, &IID_IDispatch, (IUnknown*)V_DISPATCH(pvar));
+            break;
+        case VT_DISPATCH | VT_BYREF:
+            /* this should probably call WdtpInterfacePointer_UserMarshal in ole32.dll */
+            Pos = interface_variant_marshal(pFlags, Pos, &IID_IDispatch, (IUnknown*)*V_DISPATCHREF(pvar));
             break;
         case VT_RECORD:
             FIXME("handle BRECORD by val\n");
@@ -609,16 +618,21 @@
         case VT_VARIANT | VT_BYREF:
             Pos = VARIANT_UserUnmarshal(pFlags, Pos, V_VARIANTREF(pvar));
             break;
-        case VT_DISPATCH | VT_BYREF:
-            FIXME("handle DISPATCH by ref\n");
-            break;
         case VT_UNKNOWN:
             /* this should probably call WdtpInterfacePointer_UserUnmarshal in ole32.dll */
-            Pos = interface_variant_unmarshal(pFlags, Pos, &IID_IUnknown, pvar);
+            Pos = interface_variant_unmarshal(pFlags, Pos, &IID_IUnknown, &V_UNKNOWN(pvar));
+            break;
+        case VT_UNKNOWN | VT_BYREF:
+            /* this should probably call WdtpInterfacePointer_UserUnmarshal in ole32.dll */
+            Pos = interface_variant_unmarshal(pFlags, Pos, &IID_IUnknown, V_UNKNOWNREF(pvar));
             break;
         case VT_DISPATCH:
             /* this should probably call WdtpInterfacePointer_UserUnmarshal in ole32.dll */
-            Pos = interface_variant_unmarshal(pFlags, Pos, &IID_IDispatch, pvar);
+            Pos = interface_variant_unmarshal(pFlags, Pos, &IID_IDispatch, (IUnknown**)&V_DISPATCH(pvar));
+            break;
+        case VT_DISPATCH | VT_BYREF:
+            /* this should probably call WdtpInterfacePointer_UserUnmarshal in ole32.dll */
+            Pos = interface_variant_unmarshal(pFlags, Pos, &IID_IDispatch, (IUnknown**)V_DISPATCHREF(pvar));
             break;
         case VT_RECORD:
             FIXME("handle BRECORD by val\n");
@@ -697,6 +711,8 @@
     hr = SafeArrayGetVartype(psa, &vt);
     if (FAILED(hr))
     {
+        if(psa->fFeatures & FADF_VARIANT) return SF_VARIANT;
+
         switch(psa->cbElements)
         {
         case 1: vt = VT_I1; break;

Modified: trunk/reactos/dll/win32/oleaut32/variant.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/oleaut32/variant.c?rev=27914&r1=27913&r2=27914&view=diff
==============================================================================
--- trunk/reactos/dll/win32/oleaut32/variant.c (original)
+++ trunk/reactos/dll/win32/oleaut32/variant.c Fri Jul 27 13:59:17 2007
@@ -2929,7 +2929,7 @@
     }
     ExtraFlags = leftExtraFlags;
 
-    /* Native VarAnd always returns a error when using any extra
+    /* Native VarAnd always returns an error when using extra
      * flags or if the variant combination is I8 and INT.
      */
     if ((leftvt == VT_I8 && rightvt == VT_INT) ||
@@ -3563,7 +3563,7 @@
     }
     ExtraFlags = leftExtraFlags;
 
-    /* Native VarDiv always returns a error when using any extra flags */
+    /* Native VarDiv always returns an error when using extra flags */
     if (ExtraFlags != 0)
     {
         hres = DISP_E_BADVARTYPE;
@@ -4273,15 +4273,28 @@
 {
     VARIANT varIn;
     HRESULT hRet = S_OK;
+    VARIANT temp;
+
+    VariantInit(&temp);
 
     TRACE("(%p->(%s%s),%p)\n", pVarIn, debugstr_VT(pVarIn),
           debugstr_VF(pVarIn), pVarOut);
+
+    /* Handle VT_DISPATCH by storing and taking address of returned value */
+    if ((V_VT(pVarIn) & VT_TYPEMASK) == VT_DISPATCH && ((V_VT(pVarIn) & ~VT_TYPEMASK) == 0))
+    {
+        hRet = VARIANT_FetchDispatchValue(pVarIn, &temp);
+        if (FAILED(hRet)) goto VarAbs_Exit;
+        pVarIn = &temp;
+    }
 
     if (V_ISARRAY(pVarIn) || V_VT(pVarIn) == VT_UNKNOWN ||
         V_VT(pVarIn) == VT_DISPATCH || V_VT(pVarIn) == VT_RECORD ||
         V_VT(pVarIn) == VT_ERROR)
-        return DISP_E_TYPEMISMATCH;
-
+    {
+        hRet = DISP_E_TYPEMISMATCH;
+        goto VarAbs_Exit;
+    }
     *pVarOut = *pVarIn; /* Shallow copy the value, and invert it if needed */
 
 #define ABS_CASE(typ,min) \
@@ -4331,6 +4344,8 @@
         hRet = DISP_E_BADVARTYPE;
     }
 
+VarAbs_Exit:
+    VariantClear(&temp);
     return hRet;
 }
 
@@ -4362,10 +4377,20 @@
 HRESULT WINAPI VarFix(LPVARIANT pVarIn, LPVARIANT pVarOut)
 {
     HRESULT hRet = S_OK;
+    VARIANT temp;
+
+    VariantInit(&temp);
 
     TRACE("(%p->(%s%s),%p)\n", pVarIn, debugstr_VT(pVarIn),
           debugstr_VF(pVarIn), pVarOut);
 
+    /* Handle VT_DISPATCH by storing and taking address of returned value */
+    if ((V_VT(pVarIn) & VT_TYPEMASK) == VT_DISPATCH && ((V_VT(pVarIn) & ~VT_TYPEMASK) == 0))
+    {
+        hRet = VARIANT_FetchDispatchValue(pVarIn, &temp);
+        if (FAILED(hRet)) goto VarFix_Exit;
+        pVarIn = &temp;
+    }
     V_VT(pVarOut) = V_VT(pVarIn);
 
     switch (V_VT(pVarIn))
@@ -4423,8 +4448,10 @@
         else
             hRet = DISP_E_TYPEMISMATCH;
     }
+VarFix_Exit:
     if (FAILED(hRet))
       V_VT(pVarOut) = VT_EMPTY;
+    VariantClear(&temp);
 
     return hRet;
 }
@@ -4457,10 +4484,20 @@
 HRESULT WINAPI VarInt(LPVARIANT pVarIn, LPVARIANT pVarOut)
 {
     HRESULT hRet = S_OK;
+    VARIANT temp;
+
+    VariantInit(&temp);
 
     TRACE("(%p->(%s%s),%p)\n", pVarIn, debugstr_VT(pVarIn),
           debugstr_VF(pVarIn), pVarOut);
 
+    /* Handle VT_DISPATCH by storing and taking address of returned value */
+    if ((V_VT(pVarIn) & VT_TYPEMASK) == VT_DISPATCH && ((V_VT(pVarIn) & ~VT_TYPEMASK) == 0))
+    {
+        hRet = VARIANT_FetchDispatchValue(pVarIn, &temp);
+        if (FAILED(hRet)) goto VarInt_Exit;
+        pVarIn = &temp;
+    }
     V_VT(pVarOut) = V_VT(pVarIn);
 
     switch (V_VT(pVarIn))
@@ -4484,8 +4521,10 @@
         hRet = VarDecInt(&V_DECIMAL(pVarIn), &V_DECIMAL(pVarOut));
         break;
     default:
-        return VarFix(pVarIn, pVarOut);
-    }
+        hRet = VarFix(pVarIn, pVarOut);
+    }
+VarInt_Exit:
+    VariantClear(&temp);
 
     return hRet;
 }
@@ -4758,10 +4797,20 @@
 HRESULT WINAPI VarNeg(LPVARIANT pVarIn, LPVARIANT pVarOut)
 {
     HRESULT hRet = S_OK;
+    VARIANT temp;
+
+    VariantInit(&temp);
 
     TRACE("(%p->(%s%s),%p)\n", pVarIn, debugstr_VT(pVarIn),
           debugstr_VF(pVarIn), pVarOut);
 
+    /* Handle VT_DISPATCH by storing and taking address of returned value */
+    if ((V_VT(pVarIn) & VT_TYPEMASK) == VT_DISPATCH && ((V_VT(pVarIn) & ~VT_TYPEMASK) == 0))
+    {
+        hRet = VARIANT_FetchDispatchValue(pVarIn, &temp);
+        if (FAILED(hRet)) goto VarNeg_Exit;
+        pVarIn = &temp;
+    }
     V_VT(pVarOut) = V_VT(pVarIn);
 
     switch (V_VT(pVarIn))
@@ -4833,8 +4882,10 @@
         else
             hRet = DISP_E_TYPEMISMATCH;
     }
+VarNeg_Exit:
     if (FAILED(hRet))
       V_VT(pVarOut) = VT_EMPTY;
+    VariantClear(&temp);
 
     return hRet;
 }
@@ -4876,9 +4927,20 @@
 {
     VARIANT varIn;
     HRESULT hRet = S_OK;
+    VARIANT temp;
+
+    VariantInit(&temp);
 
     TRACE("(%p->(%s%s),%p)\n", pVarIn, debugstr_VT(pVarIn),
           debugstr_VF(pVarIn), pVarOut);
+
+    /* Handle VT_DISPATCH by storing and taking address of returned value */
+    if ((V_VT(pVarIn) & VT_TYPEMASK) == VT_DISPATCH && ((V_VT(pVarIn) & ~VT_TYPEMASK) == 0))
+    {
+        hRet = VARIANT_FetchDispatchValue(pVarIn, &temp);
+        if (FAILED(hRet)) goto VarNot_Exit;
+        pVarIn = &temp;
+    }
 
     V_VT(pVarOut) = V_VT(pVarIn);
 
@@ -4951,8 +5013,10 @@
         else
             hRet = DISP_E_TYPEMISMATCH;
     }
+VarNot_Exit:
     if (FAILED(hRet))
       V_VT(pVarOut) = VT_EMPTY;
+    VariantClear(&temp);
 
     return hRet;
 }
@@ -4981,8 +5045,19 @@
     VARIANT varIn;
     HRESULT hRet = S_OK;
     float factor;
+    VARIANT temp;
+
+    VariantInit(&temp);
 
     TRACE("(%p->(%s%s),%d)\n", pVarIn, debugstr_VT(pVarIn), debugstr_VF(pVarIn), deci);
+
+    /* Handle VT_DISPATCH by storing and taking address of returned value */
+    if ((V_VT(pVarIn) & VT_TYPEMASK) == VT_DISPATCH && ((V_VT(pVarIn) & ~VT_TYPEMASK) == 0))
+    {
+        hRet = VARIANT_FetchDispatchValue(pVarIn, &temp);
+        if (FAILED(hRet)) goto VarRound_Exit;
+        pVarIn = &temp;
+    }
 
     switch (V_VT(pVarIn))
     {
@@ -5074,9 +5149,10 @@
 		V_VT(pVarIn) & VT_TYPEMASK, deci);
 	hRet = DISP_E_BADVARTYPE;
     }
-
+VarRound_Exit:
     if (FAILED(hRet))
       V_VT(pVarOut) = VT_EMPTY;
+    VariantClear(&temp);
 
     TRACE("returning 0x%08x (%s%s),%f\n", hRet, debugstr_VT(pVarOut),
 	debugstr_VF(pVarOut), (V_VT(pVarOut) == VT_R4) ? V_R4(pVarOut) :
@@ -5131,7 +5207,7 @@
     }
     ExtraFlags = leftExtraFlags;
 
-    /* Native VarIdiv always returns a error when using any extra
+    /* Native VarIdiv always returns an error when using extra
      * flags or if the variant combination is I8 and INT.
      */
     if ((leftvt == VT_I8 && rightvt == VT_INT) ||
@@ -5543,7 +5619,7 @@
     }
     ExtraFlags = leftExtraFlags;
 
-    /* Native VarPow always returns a error when using any extra flags */
+    /* Native VarPow always returns an error when using extra flags */
     if (ExtraFlags != 0)
     {
         hr = DISP_E_BADVARTYPE;
@@ -5659,7 +5735,7 @@
     }
     ExtraFlags = leftExtraFlags;
 
-    /* Native VarImp always returns a error when using any extra
+    /* Native VarImp always returns an error when using extra
      * flags or if the variants are I8 and INT.
      */
     if ((leftvt == VT_I8 && rightvt == VT_INT) ||

Modified: trunk/reactos/dll/win32/oleaut32/vartype.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/oleaut32/vartype.c?rev=27914&r1=27913&r2=27914&view=diff
==============================================================================
--- trunk/reactos/dll/win32/oleaut32/vartype.c (original)
+++ trunk/reactos/dll/win32/oleaut32/vartype.c Fri Jul 27 13:59:17 2007
@@ -3523,7 +3523,6 @@
 
   if (result_fpstatus & 0x9) /* Overflow | Invalid */
     return DISP_E_OVERFLOW;
-  return S_OK;
 #else
   /* This version produces slightly different results for boundary cases */
   if (dblIn < -922337203685477.5807 || dblIn >= 922337203685477.5807)
@@ -7425,7 +7424,7 @@
   /* Parse the string into our structure */
   while (*strIn)
   {
-    if (dp.dwCount > 6)
+    if (dp.dwCount >= 6)
       break;
 
     if (isdigitW(*strIn))




More information about the Ros-diffs mailing list