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/dispatc…
==============================================================================
--- 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.…
==============================================================================
--- 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/oleaut3…
==============================================================================
--- 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/oleaut3…
==============================================================================
--- 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/oleaut3…
==============================================================================
--- 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/oleaut3…
==============================================================================
--- 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/oleaut3…
==============================================================================
--- 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/oleaut3…
==============================================================================
--- 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/olepict…
==============================================================================
--- 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/safearr…
==============================================================================
--- 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/tmarsha…
==============================================================================
--- 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/typelib…
==============================================================================
--- 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/typelib…
==============================================================================
--- 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/usrmars…
==============================================================================
--- 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))