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... ============================================================================== --- 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... ============================================================================== --- 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... ============================================================================== --- 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... ============================================================================== --- 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... ============================================================================== --- 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... ============================================================================== --- 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... ============================================================================== --- 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... ============================================================================== --- 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.... ============================================================================== --- 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/olepictu... ============================================================================== --- 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/safearra... ============================================================================== --- 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... ============================================================================== --- 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.... ============================================================================== --- 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/typelib1... ============================================================================== --- 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... ============================================================================== --- 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/usrmarsh... ============================================================================== --- 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.... ============================================================================== --- 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.... ============================================================================== --- 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))