Author: fireball
Date: Mon Mar 27 20:44:53 2006
New Revision: 21399
URL:
http://svn.reactos.ru/svn/reactos?rev=21399&view=rev
Log:
- Sync oleaut32.dll to Wine-0.9.10
- Change related header files
Added:
trunk/reactos/dll/win32/oleaut32/oleaut32_Tr.rc
- copied unchanged from r21360, vendor/wine/dlls/oleaut32/current/oleaut32_Tr.rc
Modified:
trunk/reactos/dll/win32/oleaut32/connpt.c
trunk/reactos/dll/win32/oleaut32/hash.c
trunk/reactos/dll/win32/oleaut32/oleaut.c
trunk/reactos/dll/win32/oleaut32/oleaut32.rc
trunk/reactos/dll/win32/oleaut32/oleaut32.spec
trunk/reactos/dll/win32/oleaut32/olefont.c
trunk/reactos/dll/win32/oleaut32/olepicture.c
trunk/reactos/dll/win32/oleaut32/tmarshal.c
trunk/reactos/dll/win32/oleaut32/typelib.c
trunk/reactos/dll/win32/oleaut32/usrmarshal.c
trunk/reactos/dll/win32/oleaut32/varformat.c
trunk/reactos/dll/win32/oleaut32/variant.c
trunk/reactos/dll/win32/oleaut32/variant.h
trunk/reactos/dll/win32/oleaut32/vartype.c
trunk/reactos/include/oaidl.h
trunk/reactos/include/ocidl.h
trunk/reactos/include/olectl.h
trunk/reactos/include/olectlid.h
Modified: trunk/reactos/dll/win32/oleaut32/connpt.c
URL:
http://svn.reactos.ru/svn/reactos/trunk/reactos/dll/win32/oleaut32/connpt.c…
==============================================================================
--- trunk/reactos/dll/win32/oleaut32/connpt.c (original)
+++ trunk/reactos/dll/win32/oleaut32/connpt.c Mon Mar 27 20:44:53 2006
@@ -160,14 +160,10 @@
/*
* Compare the riid with the interface IDs implemented by this object.
*/
- if (memcmp(&IID_IUnknown, riid, sizeof(IID_IUnknown)) == 0)
- {
+ if (IsEqualIID(&IID_IUnknown, riid))
*ppvObject = (IConnectionPoint*)This;
- }
- else if (memcmp(&IID_IConnectionPoint, riid, sizeof(IID_IConnectionPoint)) == 0)
- {
+ else if (IsEqualIID(&IID_IConnectionPoint, riid))
*ppvObject = (IConnectionPoint*)This;
- }
/*
* Check that we obtained an interface.
@@ -433,14 +429,10 @@
/*
* Compare the riid with the interface IDs implemented by this object.
*/
- if (memcmp(&IID_IUnknown, riid, sizeof(IID_IUnknown)) == 0)
- {
+ if (IsEqualIID(&IID_IUnknown, riid))
*ppvObject = (IEnumConnections*)This;
- }
- else if (memcmp(&IID_IEnumConnections, riid, sizeof(IID_IEnumConnections)) == 0)
- {
+ else if (IsEqualIID(&IID_IEnumConnections, riid))
*ppvObject = (IEnumConnections*)This;
- }
/*
* Check that we obtained an interface.
Modified: trunk/reactos/dll/win32/oleaut32/hash.c
URL:
http://svn.reactos.ru/svn/reactos/trunk/reactos/dll/win32/oleaut32/hash.c?r…
==============================================================================
--- trunk/reactos/dll/win32/oleaut32/hash.c (original)
+++ trunk/reactos/dll/win32/oleaut32/hash.c Mon Mar 27 20:44:53 2006
@@ -539,8 +539,8 @@
case LANG_TATAR: case LANG_TELUGU: case LANG_THAI:
case LANG_UKRAINIAN: case LANG_URDU: case LANG_UZBEK:
case LANG_VIETNAMESE: case LANG_GAELIC: case LANG_MALTESE:
- case LANG_MAORI: case LANG_RHAETO_ROMANCE:
- case LANG_SAAMI: case LANG_SORBIAN: case LANG_SUTU:
+ case LANG_MAORI: case LANG_ROMANSH: case LANG_IRISH:
+ case LANG_SAMI: case LANG_UPPER_SORBIAN: case LANG_SUTU:
case LANG_TSONGA: case LANG_TSWANA: case LANG_VENDA:
case LANG_XHOSA: case LANG_ZULU: case LANG_ESPERANTO:
case LANG_WALON: case LANG_CORNISH: case LANG_WELSH:
Modified: trunk/reactos/dll/win32/oleaut32/oleaut.c
URL:
http://svn.reactos.ru/svn/reactos/trunk/reactos/dll/win32/oleaut32/oleaut.c…
==============================================================================
--- trunk/reactos/dll/win32/oleaut32/oleaut.c (original)
+++ trunk/reactos/dll/win32/oleaut32/oleaut.c Mon Mar 27 20:44:53 2006
@@ -446,8 +446,8 @@
BSTR_bCache = FALSE;
}
-static WCHAR _delimiter[2] = {'!',0}; /* default delimiter apparently */
-static WCHAR *pdelimiter = &_delimiter[0];
+static const WCHAR _delimiter[2] = {'!',0}; /* default delimiter apparently */
+static const WCHAR *pdelimiter = &_delimiter[0];
/***********************************************************************
* RegisterActiveObject (OLEAUT32.33)
Modified: trunk/reactos/dll/win32/oleaut32/oleaut32.rc
URL:
http://svn.reactos.ru/svn/reactos/trunk/reactos/dll/win32/oleaut32/oleaut32…
==============================================================================
--- trunk/reactos/dll/win32/oleaut32/oleaut32.rc (original)
+++ trunk/reactos/dll/win32/oleaut32/oleaut32.rc Mon Mar 27 20:44:53 2006
@@ -42,6 +42,7 @@
#include "oleaut32_Ru.rc"
#include "oleaut32_Sv.rc"
#include "oleaut32_Th.rc"
+#include "oleaut32_Tr.rc"
#include "oleaut32_Uk.rc"
/*
Modified: trunk/reactos/dll/win32/oleaut32/oleaut32.spec
URL:
http://svn.reactos.ru/svn/reactos/trunk/reactos/dll/win32/oleaut32/oleaut32…
==============================================================================
--- trunk/reactos/dll/win32/oleaut32/oleaut32.spec (original)
+++ trunk/reactos/dll/win32/oleaut32/oleaut32.spec Mon Mar 27 20:44:53 2006
@@ -111,7 +111,7 @@
112 stdcall VarBstrFromR8(double long long ptr)
113 stdcall VarBstrFromCy(double long long ptr)
114 stdcall VarBstrFromDate(double long long ptr)
-115 stub VarBstrFromDisp
+115 stdcall VarBstrFromDisp(ptr long long ptr)
116 stdcall VarBstrFromBool(long long long ptr)
117 stdcall VarFormatPercent(ptr long long long long long ptr)
118 stdcall VarBoolFromUI1(long ptr)
@@ -285,10 +285,10 @@
288 stdcall VARIANT_UserMarshal(ptr ptr ptr)
289 stdcall VARIANT_UserUnmarshal(ptr ptr ptr)
290 stdcall VARIANT_UserFree(ptr ptr)
-291 stub LPSAFEARRAY_UserSize
-292 stub LPSAFEARRAY_UserMarshal
-293 stub LPSAFEARRAY_UserUnmarshal
-294 stub LPSAFEARRAY_UserFree
+291 stdcall LPSAFEARRAY_UserSize(ptr long ptr)
+292 stdcall LPSAFEARRAY_UserMarshal(ptr ptr ptr)
+293 stdcall LPSAFEARRAY_UserUnmarshal(ptr ptr ptr)
+294 stdcall LPSAFEARRAY_UserFree(ptr ptr)
295 stub LPSAFEARRAY_Size
296 stub LPSAFEARRAY_Marshal
297 stub LPSAFEARRAY_Unmarshal
Modified: trunk/reactos/dll/win32/oleaut32/olefont.c
URL:
http://svn.reactos.ru/svn/reactos/trunk/reactos/dll/win32/oleaut32/olefont.…
==============================================================================
--- trunk/reactos/dll/win32/oleaut32/olefont.c (original)
+++ trunk/reactos/dll/win32/oleaut32/olefont.c Mon Mar 27 20:44:53 2006
@@ -40,6 +40,7 @@
#include "olectl.h"
#include "wine/debug.h"
#include "connpt.h" /* for CreateConnectionPoint */
+#include "oaidl.h"
WINE_DEFAULT_DEBUG_CHANNEL(ole);
@@ -95,7 +96,8 @@
long cyLogical;
long cyHimetric;
- IConnectionPoint *pCP;
+ IConnectionPoint *pPropertyNotifyCP;
+ IConnectionPoint *pFontEventsCP;
};
/*
@@ -378,24 +380,74 @@
*/
static void OLEFont_SendNotify(OLEFontImpl* this, DISPID dispID)
{
+ static const WCHAR wszName[] = {'N','a','m','e',0};
+ static const WCHAR wszSize[] = {'S','i','z','e',0};
+ static const WCHAR wszBold[] = {'B','o','l','d',0};
+ static const WCHAR wszItalic[] =
{'I','t','a','l','i','c',0};
+ static const WCHAR wszUnder[] =
{'U','n','d','e','r','l','i','n','e',0};
+ static const WCHAR wszStrike[] =
{'S','t','r','i','k','e','t','h','r','o','u','g','h',0};
+ static const WCHAR wszWeight[] =
{'W','e','i','g','h','t',0};
+ static const WCHAR wszCharset[] =
{'C','h','a','r','s','s','e','t',0};
+ static const LPCWSTR dispid_mapping[] =
+ {
+ wszName,
+ NULL,
+ wszSize,
+ wszBold,
+ wszItalic,
+ wszUnder,
+ wszStrike,
+ wszWeight,
+ wszCharset
+ };
+
IEnumConnections *pEnum;
CONNECTDATA CD;
HRESULT hres;
- hres = IConnectionPoint_EnumConnections(this->pCP, &pEnum);
- if (FAILED(hres)) /* When we have 0 connections. */
- return;
-
- while(IEnumConnections_Next(pEnum, 1, &CD, NULL) == S_OK) {
- IPropertyNotifySink *sink;
-
- IUnknown_QueryInterface(CD.pUnk, &IID_IPropertyNotifySink, (LPVOID)&sink);
- IPropertyNotifySink_OnChanged(sink, dispID);
- IPropertyNotifySink_Release(sink);
- IUnknown_Release(CD.pUnk);
+ hres = IConnectionPoint_EnumConnections(this->pPropertyNotifyCP, &pEnum);
+ if (SUCCEEDED(hres))
+ {
+ while(IEnumConnections_Next(pEnum, 1, &CD, NULL) == S_OK) {
+ IPropertyNotifySink *sink;
+
+ IUnknown_QueryInterface(CD.pUnk, &IID_IPropertyNotifySink, (LPVOID)&sink);
+ IPropertyNotifySink_OnChanged(sink, dispID);
+ IPropertyNotifySink_Release(sink);
+ IUnknown_Release(CD.pUnk);
+ }
+ IEnumConnections_Release(pEnum);
}
- IEnumConnections_Release(pEnum);
- return;
+
+ hres = IConnectionPoint_EnumConnections(this->pFontEventsCP, &pEnum);
+ if (SUCCEEDED(hres))
+ {
+ DISPPARAMS dispparams;
+ VARIANTARG vararg;
+
+ VariantInit(&vararg);
+ V_VT(&vararg) = VT_BSTR;
+ V_BSTR(&vararg) = SysAllocString(dispid_mapping[dispID]);
+
+ dispparams.cArgs = 1;
+ dispparams.cNamedArgs = 0;
+ dispparams.rgdispidNamedArgs = NULL;
+ dispparams.rgvarg = &vararg;
+
+ while(IEnumConnections_Next(pEnum, 1, &CD, NULL) == S_OK) {
+ IFontEventsDisp *disp;
+
+ IUnknown_QueryInterface(CD.pUnk, &IID_IFontEventsDisp, (LPVOID)&disp);
+ IDispatch_Invoke(disp, DISPID_FONT_CHANGED, &IID_NULL,
+ LOCALE_NEUTRAL, INVOKE_FUNC, &dispparams, NULL,
+ NULL, NULL);
+
+ IDispatch_Release(disp);
+ IUnknown_Release(CD.pUnk);
+ }
+ VariantClear(&vararg);
+ IEnumConnections_Release(pEnum);
+ }
}
/************************************************************************
@@ -459,7 +511,18 @@
newObject->fontLock = 0;
newObject->cyLogical = 72L;
newObject->cyHimetric = 2540L;
- CreateConnectionPoint((IUnknown*)newObject, &IID_IPropertyNotifySink,
&newObject->pCP);
+ newObject->pPropertyNotifyCP = NULL;
+ newObject->pFontEventsCP = NULL;
+
+ CreateConnectionPoint((IUnknown*)newObject, &IID_IPropertyNotifySink,
&newObject->pPropertyNotifyCP);
+ CreateConnectionPoint((IUnknown*)newObject, &IID_IFontEventsDisp,
&newObject->pFontEventsCP);
+
+ if (!newObject->pPropertyNotifyCP || !newObject->pFontEventsCP)
+ {
+ OLEFontImpl_Destroy(newObject);
+ return NULL;
+ }
+
TRACE("returning %p\n", newObject);
return newObject;
}
@@ -479,6 +542,11 @@
if (fontDesc->gdiFont!=0)
DeleteObject(fontDesc->gdiFont);
+
+ if (fontDesc->pPropertyNotifyCP)
+ IConnectionPoint_Release(fontDesc->pPropertyNotifyCP);
+ if (fontDesc->pFontEventsCP)
+ IConnectionPoint_Release(fontDesc->pFontEventsCP);
HeapFree(GetProcessHeap(), 0, fontDesc);
}
@@ -1041,6 +1109,17 @@
newObject->gdiFont = CreateFontIndirectW(&logFont);
+ /* create new connection points */
+ newObject->pPropertyNotifyCP = NULL;
+ newObject->pFontEventsCP = NULL;
+ CreateConnectionPoint((IUnknown*)newObject, &IID_IPropertyNotifySink,
&newObject->pPropertyNotifyCP);
+ CreateConnectionPoint((IUnknown*)newObject, &IID_IFontEventsDisp,
&newObject->pFontEventsCP);
+
+ if (!newObject->pPropertyNotifyCP || !newObject->pFontEventsCP)
+ {
+ OLEFontImpl_Destroy(newObject);
+ return E_OUTOFMEMORY;
+ }
/* The cloned object starts with a reference count of 1 */
newObject->ref = 1;
@@ -1839,12 +1918,17 @@
OLEFontImpl *this = impl_from_IConnectionPointContainer(iface);
TRACE("(%p)->(%s, %p): stub\n", this, debugstr_guid(riid), ppCp);
- if(memcmp(riid, &IID_IPropertyNotifySink, sizeof(IID_IPropertyNotifySink)) == 0) {
- return IConnectionPoint_QueryInterface(this->pCP, &IID_IConnectionPoint,
- (LPVOID)ppCp);
+ if(IsEqualIID(riid, &IID_IPropertyNotifySink)) {
+ return IConnectionPoint_QueryInterface(this->pPropertyNotifyCP,
+ &IID_IConnectionPoint,
+ (LPVOID)ppCp);
+ } else if(IsEqualIID(riid, &IID_IFontEventsDisp)) {
+ return IConnectionPoint_QueryInterface(this->pFontEventsCP,
+ &IID_IConnectionPoint,
+ (LPVOID)ppCp);
} else {
- FIXME("Tried to find connection point on %s\n", debugstr_guid(riid));
- return E_NOINTERFACE;
+ FIXME("no connection point for %s\n", debugstr_guid(riid));
+ return CONNECT_E_NOCONNECTION;
}
}
Modified: trunk/reactos/dll/win32/oleaut32/olepicture.c
URL:
http://svn.reactos.ru/svn/reactos/trunk/reactos/dll/win32/oleaut32/olepictu…
==============================================================================
--- trunk/reactos/dll/win32/oleaut32/olepicture.c (original)
+++ trunk/reactos/dll/win32/oleaut32/olepicture.c Mon Mar 27 20:44:53 2006
@@ -279,7 +279,13 @@
newObject->lpvtblIPersistStream = &OLEPictureImpl_IPersistStream_VTable;
newObject->lpvtblIConnectionPointContainer =
&OLEPictureImpl_IConnectionPointContainer_VTable;
+ newObject->pCP = NULL;
CreateConnectionPoint((IUnknown*)newObject,&IID_IPropertyNotifySink,&newObject->pCP);
+ if (!newObject->pCP)
+ {
+ HeapFree(GetProcessHeap(), 0, newObject);
+ return NULL;
+ }
/*
* Start with one reference count. The caller of this function
@@ -348,6 +354,9 @@
static void OLEPictureImpl_Destroy(OLEPictureImpl* Obj)
{
TRACE("(%p)\n", Obj);
+
+ if (Obj->pCP)
+ IConnectionPoint_Release(Obj->pCP);
if(Obj->fOwn) { /* We need to destroy the picture */
switch(Obj->desc.picType) {
@@ -377,7 +386,43 @@
HeapFree(GetProcessHeap(), 0, Obj);
}
-static ULONG WINAPI OLEPictureImpl_AddRef(IPicture* iface);
+
+/************************************************************************
+ * OLEPictureImpl_AddRef (IUnknown)
+ *
+ * See Windows documentation for more details on IUnknown methods.
+ */
+static ULONG WINAPI OLEPictureImpl_AddRef(
+ IPicture* iface)
+{
+ OLEPictureImpl *This = (OLEPictureImpl *)iface;
+ ULONG refCount = InterlockedIncrement(&This->ref);
+
+ TRACE("(%p)->(ref before=%ld)\n", This, refCount - 1);
+
+ return refCount;
+}
+
+/************************************************************************
+ * OLEPictureImpl_Release (IUnknown)
+ *
+ * See Windows documentation for more details on IUnknown methods.
+ */
+static ULONG WINAPI OLEPictureImpl_Release(
+ IPicture* iface)
+{
+ OLEPictureImpl *This = (OLEPictureImpl *)iface;
+ ULONG refCount = InterlockedDecrement(&This->ref);
+
+ TRACE("(%p)->(ref before=%ld)\n", This, refCount + 1);
+
+ /*
+ * If the reference count goes down to 0, perform suicide.
+ */
+ if (!refCount) OLEPictureImpl_Destroy(This);
+
+ return refCount;
+}
/************************************************************************
* OLEPictureImpl_QueryInterface (IUnknown)
@@ -447,6 +492,7 @@
return S_OK;
}
+
/***********************************************************************
* OLEPicture_SendNotify (internal)
*
@@ -471,44 +517,6 @@
IEnumConnections_Release(pEnum);
return;
}
-
-/************************************************************************
- * OLEPictureImpl_AddRef (IUnknown)
- *
- * See Windows documentation for more details on IUnknown methods.
- */
-static ULONG WINAPI OLEPictureImpl_AddRef(
- IPicture* iface)
-{
- OLEPictureImpl *This = (OLEPictureImpl *)iface;
- ULONG refCount = InterlockedIncrement(&This->ref);
-
- TRACE("(%p)->(ref before=%ld)\n", This, refCount - 1);
-
- return refCount;
-}
-
-/************************************************************************
- * OLEPictureImpl_Release (IUnknown)
- *
- * See Windows documentation for more details on IUnknown methods.
- */
-static ULONG WINAPI OLEPictureImpl_Release(
- IPicture* iface)
-{
- OLEPictureImpl *This = (OLEPictureImpl *)iface;
- ULONG refCount = InterlockedDecrement(&This->ref);
-
- TRACE("(%p)->(ref before=%ld)\n", This, refCount + 1);
-
- /*
- * If the reference count goes down to 0, perform suicide.
- */
- if (!refCount) OLEPictureImpl_Destroy(This);
-
- return refCount;
-}
-
/************************************************************************
* OLEPictureImpl_get_Handle
@@ -820,7 +828,6 @@
/************************************************************************
* IConnectionPointContainer
*/
-
static HRESULT WINAPI OLEPictureImpl_IConnectionPointContainer_QueryInterface(
IConnectionPointContainer* iface,
REFIID riid,
@@ -869,12 +876,15 @@
*ppCP = NULL;
if (IsEqualGUID(riid,&IID_IPropertyNotifySink))
return
IConnectionPoint_QueryInterface(This->pCP,&IID_IConnectionPoint,(LPVOID)ppCP);
- FIXME("tried to find connection point on %s?\n",debugstr_guid(riid));
- return 0x80040200;
-}
+ FIXME("no connection point for %s\n",debugstr_guid(riid));
+ return CONNECT_E_NOCONNECTION;
+}
+
+
/************************************************************************
* IPersistStream
*/
+
/************************************************************************
* OLEPictureImpl_IPersistStream_QueryInterface (IUnknown)
*
@@ -1043,137 +1053,9 @@
#endif /* HAVE_GIF_LIB_H */
-/************************************************************************
- * OLEPictureImpl_IPersistStream_Load (IUnknown)
- *
- * Loads the binary data from the IStream. Starts at current position.
- * There appears to be an 2 DWORD header:
- * DWORD magic;
- * DWORD len;
- *
- * Currently implemented: BITMAP, ICON, JPEG, GIF
- */
-static HRESULT WINAPI OLEPictureImpl_Load(IPersistStream* iface,IStream*pStm) {
- HRESULT hr = E_FAIL;
- BOOL headerisdata = FALSE;
- BOOL statfailed = FALSE;
- ULONG xread, toread;
- BYTE *xbuf;
- DWORD header[2];
- WORD magic;
- STATSTG statstg;
- OLEPictureImpl *This = impl_from_IPersistStream(iface);
-
- TRACE("(%p,%p)\n",This,pStm);
-
-
/****************************************************************************************
- * Part 1: Load the data
- */
- /* Sometimes we have a header, sometimes we don't. Apply some guesses to find
- * out whether we do.
- *
- * UPDATE: the IStream can be mapped to a plain file instead of a stream in a
- * compound file. This may explain most, if not all, of the cases of "no
- * header", and the header validation should take this into account.
- * At least in Visual Basic 6, resource streams, valid headers are
- * header[0] == "lt\0\0",
- * header[1] == length_of_stream.
- *
- * Also handle streams where we do not have a working "Stat" method by
- * reading all data until the end of the stream.
- */
- hr=IStream_Stat(pStm,&statstg,STATFLAG_NONAME);
- if (hr) {
- TRACE("stat failed with hres %lx, proceeding to read all data.\n",hr);
- statfailed = TRUE;
- /* we will read at least 8 byte ... just right below */
- statstg.cbSize.QuadPart = 8;
- }
- hr=IStream_Read(pStm,header,8,&xread);
- if (hr || xread!=8) {
- FIXME("Failure while reading picture header (hr is %lx, nread is
%ld).\n",hr,xread);
- return hr;
- }
-
- headerisdata = FALSE;
- xread = 0;
- if (!memcmp(&(header[0]),"lt\0\0", 4) && (header[1] <=
statstg.cbSize.QuadPart-8)) {
- toread = header[1];
- } else {
- if (!memcmp(&(header[0]), "GIF8", 4) || /* GIF header */
- !memcmp(&(header[0]), "BM", 2) || /* BMP header */
- !memcmp(&(header[0]), "\xff\xd8", 2) || /* JPEG header */
- (header[1] > statstg.cbSize.QuadPart)|| /* invalid size */
- (header[1]==0)
- ) {/* Incorrect header, assume none. */
- headerisdata = TRUE;
- toread = statstg.cbSize.QuadPart-8;
- xread = 8;
- } else {
- FIXME("Unknown stream header magic: %08lx\n", header[0]);
- toread = header[1];
- }
- }
-
- if (statfailed) { /* we don't know the size ... read all we get */
- int sizeinc = 4096;
- int origsize = sizeinc;
- ULONG nread = 42;
-
- TRACE("Reading all data from stream.\n");
- xbuf = HeapAlloc (GetProcessHeap(), HEAP_ZERO_MEMORY, origsize);
- if (headerisdata)
- memcpy (xbuf, &header, 8);
- while (1) {
- while (xread < origsize) {
- hr = IStream_Read(pStm,xbuf+xread,origsize-xread,&nread);
- xread+=nread;
- if (hr || !nread)
- break;
- }
- if (!nread || hr) /* done, or error */
- break;
- if (xread == origsize) {
- origsize += sizeinc;
- sizeinc = 2*sizeinc; /* exponential increase */
- xbuf = HeapReAlloc (GetProcessHeap(), HEAP_ZERO_MEMORY, xbuf, origsize);
- }
- }
- if (hr)
- TRACE("hr in no-stat loader case is %08lx\n", hr);
- TRACE("loaded %ld bytes.\n", xread);
- This->datalen = xread;
- This->data = xbuf;
- } else {
- This->datalen = toread+(headerisdata?8:0);
- xbuf = This->data = HeapAlloc (GetProcessHeap(), HEAP_ZERO_MEMORY,
This->datalen);
-
- if (headerisdata)
- memcpy (xbuf, &header, 8);
-
- while (xread < This->datalen) {
- ULONG nread;
- hr = IStream_Read(pStm,xbuf+xread,This->datalen-xread,&nread);
- xread+=nread;
- if (hr || !nread)
- break;
- }
- if (xread != This->datalen)
- FIXME("Could only read %ld of %d bytes out of
stream?\n",xread,This->datalen);
- }
- if (This->datalen == 0) { /* Marks the "NONE" picture */
- This->desc.picType = PICTYPE_NONE;
- return S_OK;
- }
-
-
-
/****************************************************************************************
- * Part 2: Process the loaded data
- */
-
- magic = xbuf[0] + (xbuf[1]<<8);
- switch (magic) {
- case 0x4947: { /* GIF */
+
+static HRESULT OLEPictureImpl_LoadGif(OLEPictureImpl *This, BYTE *xbuf, ULONG xread)
+{
#ifdef HAVE_GIF_LIB_H
struct gifdata gd;
GifFileType *gif;
@@ -1378,8 +1260,10 @@
FIXME("Trying to load GIF, but no support for libgif/libungif compiled
in.\n");
return E_FAIL;
#endif
- }
- case 0xd8ff: { /* JPEG */
+}
+
+static HRESULT OLEPictureImpl_LoadJpeg(OLEPictureImpl *This, BYTE *xbuf, ULONG xread)
+{
#ifdef HAVE_JPEGLIB_H
struct jpeg_decompress_struct jd;
struct jpeg_error_mgr jerr;
@@ -1475,15 +1359,16 @@
DeleteDC(hdcref);
This->desc.picType = PICTYPE_BITMAP;
OLEPictureImpl_SetBitmap(This);
- hr = S_OK;
HeapFree(GetProcessHeap(),0,bits);
+ return S_OK;
#else
ERR("Trying to load JPEG picture, but JPEG supported not compiled in.\n");
- hr = E_FAIL;
+ return E_FAIL;
#endif
- break;
- }
- case 0x4d42: { /* Bitmap */
+}
+
+static HRESULT OLEPictureImpl_LoadDIB(OLEPictureImpl *This, BYTE *xbuf, ULONG xread)
+{
BITMAPFILEHEADER *bfh = (BITMAPFILEHEADER*)xbuf;
BITMAPINFO *bi = (BITMAPINFO*)(bfh+1);
HDC hdcref;
@@ -1503,10 +1388,11 @@
DeleteDC(hdcref);
This->desc.picType = PICTYPE_BITMAP;
OLEPictureImpl_SetBitmap(This);
- hr = S_OK;
- break;
- }
- case 0x0000: { /* ICON , first word is dwReserved */
+ return S_OK;
+}
+
+static HRESULT OLEPictureImpl_LoadIcon(OLEPictureImpl *This, BYTE *xbuf, ULONG xread)
+{
HICON hicon;
CURSORICONFILEDIR *cifd = (CURSORICONFILEDIR*)xbuf;
HDC hdcRef;
@@ -1551,7 +1437,7 @@
);
if (!hicon) {
FIXME("CreateIcon failed.\n");
- hr = E_FAIL;
+ return E_FAIL;
} else {
This->desc.picType = PICTYPE_ICON;
This->desc.u.icon.hicon = hicon;
@@ -1561,8 +1447,151 @@
This->himetricWidth =(cifd->idEntries[i].bWidth *2540)/GetDeviceCaps(hdcRef,
LOGPIXELSX);
This->himetricHeight=(cifd->idEntries[i].bHeight*2540)/GetDeviceCaps(hdcRef,
LOGPIXELSY);
DeleteDC(hdcRef);
- hr = S_OK;
+ return S_OK;
}
+}
+
+/************************************************************************
+ * OLEPictureImpl_IPersistStream_Load (IUnknown)
+ *
+ * Loads the binary data from the IStream. Starts at current position.
+ * There appears to be an 2 DWORD header:
+ * DWORD magic;
+ * DWORD len;
+ *
+ * Currently implemented: BITMAP, ICON, JPEG, GIF
+ */
+static HRESULT WINAPI OLEPictureImpl_Load(IPersistStream* iface,IStream*pStm) {
+ HRESULT hr = E_FAIL;
+ BOOL headerisdata = FALSE;
+ BOOL statfailed = FALSE;
+ ULONG xread, toread;
+ BYTE *xbuf;
+ DWORD header[2];
+ WORD magic;
+ STATSTG statstg;
+ OLEPictureImpl *This = impl_from_IPersistStream(iface);
+
+ TRACE("(%p,%p)\n",This,pStm);
+
+
/****************************************************************************************
+ * Part 1: Load the data
+ */
+ /* Sometimes we have a header, sometimes we don't. Apply some guesses to find
+ * out whether we do.
+ *
+ * UPDATE: the IStream can be mapped to a plain file instead of a stream in a
+ * compound file. This may explain most, if not all, of the cases of "no
+ * header", and the header validation should take this into account.
+ * At least in Visual Basic 6, resource streams, valid headers are
+ * header[0] == "lt\0\0",
+ * header[1] == length_of_stream.
+ *
+ * Also handle streams where we do not have a working "Stat" method by
+ * reading all data until the end of the stream.
+ */
+ hr=IStream_Stat(pStm,&statstg,STATFLAG_NONAME);
+ if (hr) {
+ TRACE("stat failed with hres %lx, proceeding to read all data.\n",hr);
+ statfailed = TRUE;
+ /* we will read at least 8 byte ... just right below */
+ statstg.cbSize.QuadPart = 8;
+ }
+ hr=IStream_Read(pStm,header,8,&xread);
+ if (hr || xread!=8) {
+ FIXME("Failure while reading picture header (hr is %lx, nread is
%ld).\n",hr,xread);
+ return hr;
+ }
+
+ headerisdata = FALSE;
+ xread = 0;
+ if (!memcmp(&(header[0]),"lt\0\0", 4) && (header[1] <=
statstg.cbSize.QuadPart-8)) {
+ toread = header[1];
+ } else {
+ if (!memcmp(&(header[0]), "GIF8", 4) || /* GIF header */
+ !memcmp(&(header[0]), "BM", 2) || /* BMP header */
+ !memcmp(&(header[0]), "\xff\xd8", 2) || /* JPEG header */
+ (header[1] > statstg.cbSize.QuadPart)|| /* invalid size */
+ (header[1]==0)
+ ) {/* Incorrect header, assume none. */
+ headerisdata = TRUE;
+ toread = statstg.cbSize.QuadPart-8;
+ xread = 8;
+ } else {
+ FIXME("Unknown stream header magic: %08lx\n", header[0]);
+ toread = header[1];
+ }
+ }
+
+ if (statfailed) { /* we don't know the size ... read all we get */
+ int sizeinc = 4096;
+ int origsize = sizeinc;
+ ULONG nread = 42;
+
+ TRACE("Reading all data from stream.\n");
+ xbuf = HeapAlloc (GetProcessHeap(), HEAP_ZERO_MEMORY, origsize);
+ if (headerisdata)
+ memcpy (xbuf, &header, 8);
+ while (1) {
+ while (xread < origsize) {
+ hr = IStream_Read(pStm,xbuf+xread,origsize-xread,&nread);
+ xread+=nread;
+ if (hr || !nread)
+ break;
+ }
+ if (!nread || hr) /* done, or error */
+ break;
+ if (xread == origsize) {
+ origsize += sizeinc;
+ sizeinc = 2*sizeinc; /* exponential increase */
+ xbuf = HeapReAlloc (GetProcessHeap(), HEAP_ZERO_MEMORY, xbuf, origsize);
+ }
+ }
+ if (hr)
+ TRACE("hr in no-stat loader case is %08lx\n", hr);
+ TRACE("loaded %ld bytes.\n", xread);
+ This->datalen = xread;
+ This->data = xbuf;
+ } else {
+ This->datalen = toread+(headerisdata?8:0);
+ xbuf = This->data = HeapAlloc (GetProcessHeap(), HEAP_ZERO_MEMORY,
This->datalen);
+
+ if (headerisdata)
+ memcpy (xbuf, &header, 8);
+
+ while (xread < This->datalen) {
+ ULONG nread;
+ hr = IStream_Read(pStm,xbuf+xread,This->datalen-xread,&nread);
+ xread+=nread;
+ if (hr || !nread)
+ break;
+ }
+ if (xread != This->datalen)
+ FIXME("Could only read %ld of %d bytes out of
stream?\n",xread,This->datalen);
+ }
+ if (This->datalen == 0) { /* Marks the "NONE" picture */
+ This->desc.picType = PICTYPE_NONE;
+ return S_OK;
+ }
+
+
+
/****************************************************************************************
+ * Part 2: Process the loaded data
+ */
+
+ magic = xbuf[0] + (xbuf[1]<<8);
+ switch (magic) {
+ case 0x4947: /* GIF */
+ hr = OLEPictureImpl_LoadGif(This, xbuf, xread);
+ break;
+ case 0xd8ff: /* JPEG */
+ hr = OLEPictureImpl_LoadJpeg(This, xbuf, xread);
+ break;
+ case 0x4d42: /* Bitmap */
+ hr = OLEPictureImpl_LoadDIB(This, xbuf, xread);
+ break;
+ case 0x0000: { /* ICON , first word is dwReserved */
+ hr = OLEPictureImpl_LoadIcon(This, xbuf, xread);
break;
}
default:
@@ -1587,8 +1616,223 @@
return hr;
}
-static int serializeIcon(HICON hIcon, void ** ppBuffer, unsigned int * pLength);
-static int serializeBMP(HBITMAP hBitmap, void ** ppBuffer, unsigned int * pLength);
+static int serializeBMP(HBITMAP hBitmap, void ** ppBuffer, unsigned int * pLength)
+{
+ int iSuccess = 0;
+ HDC hDC;
+ BITMAPINFO * pInfoBitmap;
+ int iNumPaletteEntries;
+ unsigned char * pPixelData;
+ BITMAPFILEHEADER * pFileHeader;
+ BITMAPINFO * pInfoHeader;
+
+ pInfoBitmap = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
+ sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD));
+
+ /* Find out bitmap size and padded length */
+ hDC = GetDC(0);
+ pInfoBitmap->bmiHeader.biSize = sizeof(pInfoBitmap->bmiHeader);
+ GetDIBits(hDC, hBitmap, 0, 0, NULL, pInfoBitmap, DIB_RGB_COLORS);
+
+ /* Fetch bitmap palette & pixel data */
+
+ pPixelData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
pInfoBitmap->bmiHeader.biSizeImage);
+ GetDIBits(hDC, hBitmap, 0, pInfoBitmap->bmiHeader.biHeight, pPixelData,
pInfoBitmap, DIB_RGB_COLORS);
+
+ /* Calculate the total length required for the BMP data */
+ if (pInfoBitmap->bmiHeader.biClrUsed != 0) {
+ iNumPaletteEntries = pInfoBitmap->bmiHeader.biClrUsed;
+ if (iNumPaletteEntries > 256) iNumPaletteEntries = 256;
+ } else {
+ if (pInfoBitmap->bmiHeader.biBitCount <= 8)
+ iNumPaletteEntries = 1 << pInfoBitmap->bmiHeader.biBitCount;
+ else
+ iNumPaletteEntries = 0;
+ }
+ *pLength =
+ sizeof(BITMAPFILEHEADER) +
+ sizeof(BITMAPINFOHEADER) +
+ iNumPaletteEntries * sizeof(RGBQUAD) +
+ pInfoBitmap->bmiHeader.biSizeImage;
+ *ppBuffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, *pLength);
+
+ /* Fill the BITMAPFILEHEADER */
+ pFileHeader = (BITMAPFILEHEADER *)(*ppBuffer);
+ pFileHeader->bfType = 0x4d42;
+ pFileHeader->bfSize = *pLength;
+ pFileHeader->bfOffBits =
+ sizeof(BITMAPFILEHEADER) +
+ sizeof(BITMAPINFOHEADER) +
+ iNumPaletteEntries * sizeof(RGBQUAD);
+
+ /* Fill the BITMAPINFOHEADER and the palette data */
+ pInfoHeader = (BITMAPINFO *)((unsigned char *)(*ppBuffer) +
sizeof(BITMAPFILEHEADER));
+ memcpy(pInfoHeader, pInfoBitmap, sizeof(BITMAPINFOHEADER) + iNumPaletteEntries *
sizeof(RGBQUAD));
+ memcpy(
+ (unsigned char *)(*ppBuffer) +
+ sizeof(BITMAPFILEHEADER) +
+ sizeof(BITMAPINFOHEADER) +
+ iNumPaletteEntries * sizeof(RGBQUAD),
+ pPixelData, pInfoBitmap->bmiHeader.biSizeImage);
+ iSuccess = 1;
+
+ HeapFree(GetProcessHeap(), 0, pPixelData);
+ HeapFree(GetProcessHeap(), 0, pInfoBitmap);
+ return iSuccess;
+}
+
+static int serializeIcon(HICON hIcon, void ** ppBuffer, unsigned int * pLength)
+{
+ ICONINFO infoIcon;
+ int iSuccess = 0;
+
+ *ppBuffer = NULL; *pLength = 0;
+ if (GetIconInfo(hIcon, &infoIcon)) {
+ HDC hDC;
+ BITMAPINFO * pInfoBitmap;
+ unsigned char * pIconData = NULL;
+ unsigned int iDataSize = 0;
+
+ pInfoBitmap = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD));
+
+ /* Find out icon size */
+ hDC = GetDC(0);
+ pInfoBitmap->bmiHeader.biSize = sizeof(pInfoBitmap->bmiHeader);
+ GetDIBits(hDC, infoIcon.hbmColor, 0, 0, NULL, pInfoBitmap, DIB_RGB_COLORS);
+ if (1) {
+ /* Auxiliary pointers */
+ CURSORICONFILEDIR * pIconDir;
+ CURSORICONFILEDIRENTRY * pIconEntry;
+ BITMAPINFOHEADER * pIconBitmapHeader;
+ unsigned int iOffsetPalette;
+ unsigned int iOffsetColorData;
+ unsigned int iOffsetMaskData;
+
+ unsigned int iLengthScanLineColor;
+ unsigned int iLengthScanLineMask;
+ unsigned int iNumEntriesPalette;
+
+ iLengthScanLineMask = ((pInfoBitmap->bmiHeader.biWidth + 31) >> 5) <<
2;
+ iLengthScanLineColor = ((pInfoBitmap->bmiHeader.biWidth *
pInfoBitmap->bmiHeader.biBitCount + 31) >> 5) << 2;
+/*
+ FIXME("DEBUG: bitmap size is %d x %d\n",
+ pInfoBitmap->bmiHeader.biWidth,
+ pInfoBitmap->bmiHeader.biHeight);
+ FIXME("DEBUG: bitmap bpp is %d\n",
+ pInfoBitmap->bmiHeader.biBitCount);
+ FIXME("DEBUG: bitmap nplanes is %d\n",
+ pInfoBitmap->bmiHeader.biPlanes);
+ FIXME("DEBUG: bitmap biSizeImage is %lu\n",
+ pInfoBitmap->bmiHeader.biSizeImage);
+*/
+ /* Let's start with one CURSORICONFILEDIR and one CURSORICONFILEDIRENTRY */
+ iDataSize += 3 * sizeof(WORD) + sizeof(CURSORICONFILEDIRENTRY) +
sizeof(BITMAPINFOHEADER);
+ pIconData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, iDataSize);
+
+ /* Fill out the CURSORICONFILEDIR */
+ pIconDir = (CURSORICONFILEDIR *)pIconData;
+ pIconDir->idType = 1;
+ pIconDir->idCount = 1;
+
+ /* Fill out the CURSORICONFILEDIRENTRY */
+ pIconEntry = (CURSORICONFILEDIRENTRY *)(pIconData + 3 * sizeof(WORD));
+ pIconEntry->bWidth = (unsigned char)pInfoBitmap->bmiHeader.biWidth;
+ pIconEntry->bHeight = (unsigned char)pInfoBitmap->bmiHeader.biHeight;
+ pIconEntry->bColorCount =
+ (pInfoBitmap->bmiHeader.biBitCount < 8)
+ ? 1 << pInfoBitmap->bmiHeader.biBitCount
+ : 0;
+ pIconEntry->xHotspot = pInfoBitmap->bmiHeader.biPlanes;
+ pIconEntry->yHotspot = pInfoBitmap->bmiHeader.biBitCount;
+ pIconEntry->dwDIBSize = 0;
+ pIconEntry->dwDIBOffset = 3 * sizeof(WORD) + sizeof(CURSORICONFILEDIRENTRY);
+
+ /* Fill out the BITMAPINFOHEADER */
+ pIconBitmapHeader = (BITMAPINFOHEADER *)(pIconData + 3 * sizeof(WORD) +
sizeof(CURSORICONFILEDIRENTRY));
+ memcpy(pIconBitmapHeader, &pInfoBitmap->bmiHeader, sizeof(BITMAPINFOHEADER));
+
+ /* Find out whether a palette exists for the bitmap */
+ if ( (pInfoBitmap->bmiHeader.biBitCount == 16 &&
pInfoBitmap->bmiHeader.biCompression == BI_RGB)
+ || (pInfoBitmap->bmiHeader.biBitCount == 24)
+ || (pInfoBitmap->bmiHeader.biBitCount == 32 &&
pInfoBitmap->bmiHeader.biCompression == BI_RGB)) {
+ iNumEntriesPalette = pInfoBitmap->bmiHeader.biClrUsed;
+ if (iNumEntriesPalette > 256) iNumEntriesPalette = 256;
+ } else if ((pInfoBitmap->bmiHeader.biBitCount == 16 ||
pInfoBitmap->bmiHeader.biBitCount == 32)
+ && pInfoBitmap->bmiHeader.biCompression == BI_BITFIELDS) {
+ iNumEntriesPalette = 3;
+ } else if (pInfoBitmap->bmiHeader.biBitCount <= 8) {
+ iNumEntriesPalette = 1 << pInfoBitmap->bmiHeader.biBitCount;
+ } else {
+ iNumEntriesPalette = 0;
+ }
+
+ /* Add bitmap size and header size to icon data size. */
+ iOffsetPalette = iDataSize;
+ iDataSize += iNumEntriesPalette * sizeof(DWORD);
+ iOffsetColorData = iDataSize;
+ iDataSize += pIconBitmapHeader->biSizeImage;
+ iOffsetMaskData = iDataSize;
+ iDataSize += pIconBitmapHeader->biHeight * iLengthScanLineMask;
+ pIconBitmapHeader->biSizeImage += pIconBitmapHeader->biHeight *
iLengthScanLineMask;
+ pIconBitmapHeader->biHeight *= 2;
+ pIconData = HeapReAlloc(GetProcessHeap(), 0, pIconData, iDataSize);
+ pIconEntry = (CURSORICONFILEDIRENTRY *)(pIconData + 3 * sizeof(WORD));
+ pIconBitmapHeader = (BITMAPINFOHEADER *)(pIconData + 3 * sizeof(WORD) +
sizeof(CURSORICONFILEDIRENTRY));
+ pIconEntry->dwDIBSize = iDataSize - (3 * sizeof(WORD) +
sizeof(CURSORICONFILEDIRENTRY));
+
+ /* Get the actual bitmap data from the icon bitmap */
+ GetDIBits(hDC, infoIcon.hbmColor, 0, pInfoBitmap->bmiHeader.biHeight,
+ pIconData + iOffsetColorData, pInfoBitmap, DIB_RGB_COLORS);
+ if (iNumEntriesPalette > 0) {
+ memcpy(pIconData + iOffsetPalette, pInfoBitmap->bmiColors,
+ iNumEntriesPalette * sizeof(RGBQUAD));
+ }
+
+ /* Reset all values so that GetDIBits call succeeds */
+ memset(pIconData + iOffsetMaskData, 0, iDataSize - iOffsetMaskData);
+ memset(pInfoBitmap, 0, sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD));
+ pInfoBitmap->bmiHeader.biSize = sizeof(pInfoBitmap->bmiHeader);
+/*
+ if (!(GetDIBits(hDC, infoIcon.hbmMask, 0, 0, NULL, pInfoBitmap,
DIB_RGB_COLORS)
+ && GetDIBits(hDC, infoIcon.hbmMask, 0, pIconEntry->bHeight,
+ pIconData + iOffsetMaskData, pInfoBitmap, DIB_RGB_COLORS))) {
+
+ printf("ERROR: unable to get bitmap mask (error %lu)\n",
+ GetLastError());
+
+ }
+*/
+ GetDIBits(hDC, infoIcon.hbmMask, 0, 0, NULL, pInfoBitmap, DIB_RGB_COLORS);
+ GetDIBits(hDC, infoIcon.hbmMask, 0, pIconEntry->bHeight, pIconData +
iOffsetMaskData, pInfoBitmap, DIB_RGB_COLORS);
+
+ /* Write out everything produced so far to the stream */
+ *ppBuffer = pIconData; *pLength = iDataSize;
+ iSuccess = 1;
+ } else {
+/*
+ printf("ERROR: unable to get bitmap information via GetDIBits() (error
%lu)\n",
+ GetLastError());
+*/
+ }
+ /*
+ Remarks (from MSDN entry on GetIconInfo):
+
+ GetIconInfo creates bitmaps for the hbmMask and hbmColor
+ members of ICONINFO. The calling application must manage
+ these bitmaps and delete them when they are no longer
+ necessary.
+ */
+ if (hDC) ReleaseDC(0, hDC);
+ DeleteObject(infoIcon.hbmMask);
+ if (infoIcon.hbmColor) DeleteObject(infoIcon.hbmColor);
+ HeapFree(GetProcessHeap(), 0, pInfoBitmap);
+ } else {
+ printf("ERROR: Unable to get icon information (error %lu)\n",
+ GetLastError());
+ }
+ return iSuccess;
+}
+
static HRESULT WINAPI OLEPictureImpl_Save(
IPersistStream* iface,IStream*pStm,BOOL fClearDirty)
{
@@ -1696,223 +1940,6 @@
return hResult;
}
-static int serializeBMP(HBITMAP hBitmap, void ** ppBuffer, unsigned int * pLength)
-{
- int iSuccess = 0;
- HDC hDC;
- BITMAPINFO * pInfoBitmap;
- int iNumPaletteEntries;
- unsigned char * pPixelData;
- BITMAPFILEHEADER * pFileHeader;
- BITMAPINFO * pInfoHeader;
-
- pInfoBitmap = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
- sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD));
-
- /* Find out bitmap size and padded length */
- hDC = GetDC(0);
- pInfoBitmap->bmiHeader.biSize = sizeof(pInfoBitmap->bmiHeader);
- GetDIBits(hDC, hBitmap, 0, 0, NULL, pInfoBitmap, DIB_RGB_COLORS);
-
- /* Fetch bitmap palette & pixel data */
-
- pPixelData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
pInfoBitmap->bmiHeader.biSizeImage);
- GetDIBits(hDC, hBitmap, 0, pInfoBitmap->bmiHeader.biHeight, pPixelData,
pInfoBitmap, DIB_RGB_COLORS);
-
- /* Calculate the total length required for the BMP data */
- if (pInfoBitmap->bmiHeader.biClrUsed != 0) {
- iNumPaletteEntries = pInfoBitmap->bmiHeader.biClrUsed;
- if (iNumPaletteEntries > 256) iNumPaletteEntries = 256;
- } else {
- if (pInfoBitmap->bmiHeader.biBitCount <= 8)
- iNumPaletteEntries = 1 << pInfoBitmap->bmiHeader.biBitCount;
- else
- iNumPaletteEntries = 0;
- }
- *pLength =
- sizeof(BITMAPFILEHEADER) +
- sizeof(BITMAPINFOHEADER) +
- iNumPaletteEntries * sizeof(RGBQUAD) +
- pInfoBitmap->bmiHeader.biSizeImage;
- *ppBuffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, *pLength);
-
- /* Fill the BITMAPFILEHEADER */
- pFileHeader = (BITMAPFILEHEADER *)(*ppBuffer);
- pFileHeader->bfType = 0x4d42;
- pFileHeader->bfSize = *pLength;
- pFileHeader->bfOffBits =
- sizeof(BITMAPFILEHEADER) +
- sizeof(BITMAPINFOHEADER) +
- iNumPaletteEntries * sizeof(RGBQUAD);
-
- /* Fill the BITMAPINFOHEADER and the palette data */
- pInfoHeader = (BITMAPINFO *)((unsigned char *)(*ppBuffer) +
sizeof(BITMAPFILEHEADER));
- memcpy(pInfoHeader, pInfoBitmap, sizeof(BITMAPINFOHEADER) + iNumPaletteEntries *
sizeof(RGBQUAD));
- memcpy(
- (unsigned char *)(*ppBuffer) +
- sizeof(BITMAPFILEHEADER) +
- sizeof(BITMAPINFOHEADER) +
- iNumPaletteEntries * sizeof(RGBQUAD),
- pPixelData, pInfoBitmap->bmiHeader.biSizeImage);
- iSuccess = 1;
-
- HeapFree(GetProcessHeap(), 0, pPixelData);
- HeapFree(GetProcessHeap(), 0, pInfoBitmap);
- return iSuccess;
-}
-
-static int serializeIcon(HICON hIcon, void ** ppBuffer, unsigned int * pLength)
-{
- ICONINFO infoIcon;
- int iSuccess = 0;
-
- *ppBuffer = NULL; *pLength = 0;
- if (GetIconInfo(hIcon, &infoIcon)) {
- HDC hDC;
- BITMAPINFO * pInfoBitmap;
- unsigned char * pIconData = NULL;
- unsigned int iDataSize = 0;
-
- pInfoBitmap = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD));
-
- /* Find out icon size */
- hDC = GetDC(0);
- pInfoBitmap->bmiHeader.biSize = sizeof(pInfoBitmap->bmiHeader);
- GetDIBits(hDC, infoIcon.hbmColor, 0, 0, NULL, pInfoBitmap, DIB_RGB_COLORS);
- if (1) {
- /* Auxiliary pointers */
- CURSORICONFILEDIR * pIconDir;
- CURSORICONFILEDIRENTRY * pIconEntry;
- BITMAPINFOHEADER * pIconBitmapHeader;
- unsigned int iOffsetPalette;
- unsigned int iOffsetColorData;
- unsigned int iOffsetMaskData;
-
- unsigned int iLengthScanLineColor;
- unsigned int iLengthScanLineMask;
- unsigned int iNumEntriesPalette;
-
- iLengthScanLineMask = ((pInfoBitmap->bmiHeader.biWidth + 31) >> 5) <<
2;
- iLengthScanLineColor = ((pInfoBitmap->bmiHeader.biWidth *
pInfoBitmap->bmiHeader.biBitCount + 31) >> 5) << 2;
-/*
- FIXME("DEBUG: bitmap size is %d x %d\n",
- pInfoBitmap->bmiHeader.biWidth,
- pInfoBitmap->bmiHeader.biHeight);
- FIXME("DEBUG: bitmap bpp is %d\n",
- pInfoBitmap->bmiHeader.biBitCount);
- FIXME("DEBUG: bitmap nplanes is %d\n",
- pInfoBitmap->bmiHeader.biPlanes);
- FIXME("DEBUG: bitmap biSizeImage is %lu\n",
- pInfoBitmap->bmiHeader.biSizeImage);
-*/
- /* Let's start with one CURSORICONFILEDIR and one CURSORICONFILEDIRENTRY */
- iDataSize += 3 * sizeof(WORD) + sizeof(CURSORICONFILEDIRENTRY) +
sizeof(BITMAPINFOHEADER);
- pIconData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, iDataSize);
-
- /* Fill out the CURSORICONFILEDIR */
- pIconDir = (CURSORICONFILEDIR *)pIconData;
- pIconDir->idType = 1;
- pIconDir->idCount = 1;
-
- /* Fill out the CURSORICONFILEDIRENTRY */
- pIconEntry = (CURSORICONFILEDIRENTRY *)(pIconData + 3 * sizeof(WORD));
- pIconEntry->bWidth = (unsigned char)pInfoBitmap->bmiHeader.biWidth;
- pIconEntry->bHeight = (unsigned char)pInfoBitmap->bmiHeader.biHeight;
- pIconEntry->bColorCount =
- (pInfoBitmap->bmiHeader.biBitCount < 8)
- ? 1 << pInfoBitmap->bmiHeader.biBitCount
- : 0;
- pIconEntry->xHotspot = pInfoBitmap->bmiHeader.biPlanes;
- pIconEntry->yHotspot = pInfoBitmap->bmiHeader.biBitCount;
- pIconEntry->dwDIBSize = 0;
- pIconEntry->dwDIBOffset = 3 * sizeof(WORD) + sizeof(CURSORICONFILEDIRENTRY);
-
- /* Fill out the BITMAPINFOHEADER */
- pIconBitmapHeader = (BITMAPINFOHEADER *)(pIconData + 3 * sizeof(WORD) +
sizeof(CURSORICONFILEDIRENTRY));
- memcpy(pIconBitmapHeader, &pInfoBitmap->bmiHeader, sizeof(BITMAPINFOHEADER));
-
- /* Find out whether a palette exists for the bitmap */
- if ( (pInfoBitmap->bmiHeader.biBitCount == 16 &&
pInfoBitmap->bmiHeader.biCompression == BI_RGB)
- || (pInfoBitmap->bmiHeader.biBitCount == 24)
- || (pInfoBitmap->bmiHeader.biBitCount == 32 &&
pInfoBitmap->bmiHeader.biCompression == BI_RGB)) {
- iNumEntriesPalette = pInfoBitmap->bmiHeader.biClrUsed;
- if (iNumEntriesPalette > 256) iNumEntriesPalette = 256;
- } else if ((pInfoBitmap->bmiHeader.biBitCount == 16 ||
pInfoBitmap->bmiHeader.biBitCount == 32)
- && pInfoBitmap->bmiHeader.biCompression == BI_BITFIELDS) {
- iNumEntriesPalette = 3;
- } else if (pInfoBitmap->bmiHeader.biBitCount <= 8) {
- iNumEntriesPalette = 1 << pInfoBitmap->bmiHeader.biBitCount;
- } else {
- iNumEntriesPalette = 0;
- }
-
- /* Add bitmap size and header size to icon data size. */
- iOffsetPalette = iDataSize;
- iDataSize += iNumEntriesPalette * sizeof(DWORD);
- iOffsetColorData = iDataSize;
- iDataSize += pIconBitmapHeader->biSizeImage;
- iOffsetMaskData = iDataSize;
- iDataSize += pIconBitmapHeader->biHeight * iLengthScanLineMask;
- pIconBitmapHeader->biSizeImage += pIconBitmapHeader->biHeight *
iLengthScanLineMask;
- pIconBitmapHeader->biHeight *= 2;
- pIconData = HeapReAlloc(GetProcessHeap(), 0, pIconData, iDataSize);
- pIconEntry = (CURSORICONFILEDIRENTRY *)(pIconData + 3 * sizeof(WORD));
- pIconBitmapHeader = (BITMAPINFOHEADER *)(pIconData + 3 * sizeof(WORD) +
sizeof(CURSORICONFILEDIRENTRY));
- pIconEntry->dwDIBSize = iDataSize - (3 * sizeof(WORD) +
sizeof(CURSORICONFILEDIRENTRY));
-
- /* Get the actual bitmap data from the icon bitmap */
- GetDIBits(hDC, infoIcon.hbmColor, 0, pInfoBitmap->bmiHeader.biHeight,
- pIconData + iOffsetColorData, pInfoBitmap, DIB_RGB_COLORS);
- if (iNumEntriesPalette > 0) {
- memcpy(pIconData + iOffsetPalette, pInfoBitmap->bmiColors,
- iNumEntriesPalette * sizeof(RGBQUAD));
- }
-
- /* Reset all values so that GetDIBits call succeeds */
- memset(pIconData + iOffsetMaskData, 0, iDataSize - iOffsetMaskData);
- memset(pInfoBitmap, 0, sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD));
- pInfoBitmap->bmiHeader.biSize = sizeof(pInfoBitmap->bmiHeader);
-/*
- if (!(GetDIBits(hDC, infoIcon.hbmMask, 0, 0, NULL, pInfoBitmap,
DIB_RGB_COLORS)
- && GetDIBits(hDC, infoIcon.hbmMask, 0, pIconEntry->bHeight,
- pIconData + iOffsetMaskData, pInfoBitmap, DIB_RGB_COLORS))) {
-
- printf("ERROR: unable to get bitmap mask (error %lu)\n",
- GetLastError());
-
- }
-*/
- GetDIBits(hDC, infoIcon.hbmMask, 0, 0, NULL, pInfoBitmap, DIB_RGB_COLORS);
- GetDIBits(hDC, infoIcon.hbmMask, 0, pIconEntry->bHeight, pIconData +
iOffsetMaskData, pInfoBitmap, DIB_RGB_COLORS);
-
- /* Write out everything produced so far to the stream */
- *ppBuffer = pIconData; *pLength = iDataSize;
- iSuccess = 1;
- } else {
-/*
- printf("ERROR: unable to get bitmap information via GetDIBits() (error
%lu)\n",
- GetLastError());
-*/
- }
- /*
- Remarks (from MSDN entry on GetIconInfo):
-
- GetIconInfo creates bitmaps for the hbmMask and hbmColor
- members of ICONINFO. The calling application must manage
- these bitmaps and delete them when they are no longer
- necessary.
- */
- if (hDC) ReleaseDC(0, hDC);
- DeleteObject(infoIcon.hbmMask);
- if (infoIcon.hbmColor) DeleteObject(infoIcon.hbmColor);
- HeapFree(GetProcessHeap(), 0, pInfoBitmap);
- } else {
- printf("ERROR: Unable to get icon information (error %lu)\n",
- GetLastError());
- }
- return iSuccess;
-}
-
static HRESULT WINAPI OLEPictureImpl_GetSizeMax(
IPersistStream* iface,ULARGE_INTEGER*pcbSize)
{
@@ -1921,9 +1948,11 @@
return E_NOTIMPL;
}
+
/************************************************************************
* IDispatch
*/
+
/************************************************************************
* OLEPictureImpl_IDispatch_QueryInterface (IUnknown)
*
@@ -2029,12 +2058,31 @@
EXCEPINFO* pExepInfo,
UINT* puArgErr)
{
- FIXME("(dispid: %ld):Stub\n",dispIdMember);
-
- VariantInit(pVarResult);
- V_VT(pVarResult) = VT_BOOL;
- V_BOOL(pVarResult) = FALSE;
- return S_OK;
+ OLEPictureImpl *This = impl_from_IDispatch(iface);
+ if (dispIdMember == DISPID_PICT_TYPE)
+ {
+ TRACE("DISPID_PICT_TYPE\n");
+ if (!(wFlags & INVOKE_PROPERTYGET))
+ return DISP_E_PARAMNOTFOUND;
+ if (pDispParams->cArgs != 0)
+ return DISP_E_BADPARAMCOUNT;
+ if (pVarResult)
+ {
+ VariantInit(pVarResult);
+ V_VT(pVarResult) = VT_I2;
+ return OLEPictureImpl_get_Type((IPicture *)&This->lpVtbl,
&V_I2(pVarResult));
+ }
+ return S_OK;
+ }
+ else
+ {
+ FIXME("(dispid: %ld):Stub\n",dispIdMember);
+
+ VariantInit(pVarResult);
+ V_VT(pVarResult) = VT_BOOL;
+ V_BOOL(pVarResult) = FALSE;
+ return S_OK;
+ }
}
Modified: trunk/reactos/dll/win32/oleaut32/tmarshal.c
URL:
http://svn.reactos.ru/svn/reactos/trunk/reactos/dll/win32/oleaut32/tmarshal…
==============================================================================
--- trunk/reactos/dll/win32/oleaut32/tmarshal.c (original)
+++ trunk/reactos/dll/win32/oleaut32/tmarshal.c Mon Mar 27 20:44:53 2006
@@ -43,6 +43,7 @@
#include "ole2.h"
#include "typelib.h"
+#include "variant.h"
#include "wine/debug.h"
static const WCHAR IDispatchW[] = {
'I','D','i','s','p','a','t','c','h',0};
@@ -167,7 +168,7 @@
* can happen. S_OK to make sure we continue
* serializing.
*/
- ERR("pUnk is NULL?\n");
+ WARN("pUnk is NULL\n");
xsize = 0;
return xbuf_add(buf,(LPBYTE)&xsize,sizeof(xsize));
}
@@ -354,6 +355,7 @@
CRITICAL_SECTION crit;
IUnknown *outerunknown;
IDispatch *dispatch;
+ IRpcProxyBuffer *dispatch_proxy;
} TMProxyImpl;
static HRESULT WINAPI
@@ -390,7 +392,7 @@
if (!refCount)
{
- if (This->dispatch) IDispatch_Release(This->dispatch);
+ if (This->dispatch_proxy) IRpcProxyBuffer_Release(This->dispatch_proxy);
DeleteCriticalSection(&This->crit);
if (This->chanbuf) IRpcChannelBuffer_Release(This->chanbuf);
VirtualFree(This->asmstubs, 0, MEM_RELEASE);
@@ -414,6 +416,9 @@
LeaveCriticalSection(&This->crit);
+ if (This->dispatch_proxy)
+ IRpcProxyBuffer_Connect(This->dispatch_proxy, pRpcChannelBuffer);
+
return S_OK;
}
@@ -430,6 +435,9 @@
This->chanbuf = NULL;
LeaveCriticalSection(&This->crit);
+
+ if (This->dispatch_proxy)
+ IRpcProxyBuffer_Disconnect(This->dispatch_proxy);
}
@@ -501,13 +509,14 @@
{
HRESULT hres = S_OK;
- TRACE("(tdesc.vt %d)\n",tdesc->vt);
+ TRACE("(tdesc.vt %s)\n",debugstr_vt(tdesc->vt));
switch (tdesc->vt) {
case VT_EMPTY: /* nothing. empty variant for instance */
return S_OK;
case VT_I8:
case VT_UI8:
+ case VT_CY:
hres = S_OK;
if (debugout) TRACE_(olerelay)("%lx%lx",arg[0],arg[1]);
if (writeit)
@@ -515,6 +524,7 @@
return hres;
case VT_BOOL:
case VT_ERROR:
+ case VT_INT:
case VT_UINT:
case VT_I4:
case VT_R4:
@@ -550,7 +560,7 @@
VARIANT *vt = (VARIANT*)arg;
DWORD vttype = V_VT(vt);
- if (debugout) TRACE_(olerelay)("Vt(%ld)(",vttype);
+ if (debugout)
TRACE_(olerelay)("Vt(%s%s)(",debugstr_vt(vttype),debugstr_vf(vttype));
tdesc2.vt = vttype;
if (writeit) {
hres = xbuf_add(buf,(LPBYTE)&vttype,sizeof(vttype));
@@ -666,11 +676,15 @@
if (debugout) TRACE_(olerelay)("unk(0x%lx)",*arg);
if (writeit)
hres = _marshal_interface(buf,&IID_IUnknown,(LPUNKNOWN)*arg);
+ if (dealloc && *(IUnknown **)arg)
+ IUnknown_Release((LPUNKNOWN)*arg);
return hres;
case VT_DISPATCH:
if (debugout) TRACE_(olerelay)("idisp(0x%lx)",*arg);
if (writeit)
hres = _marshal_interface(buf,&IID_IDispatch,(LPUNKNOWN)*arg);
+ if (dealloc && *(IUnknown **)arg)
+ IUnknown_Release((LPUNKNOWN)*arg);
return hres;
case VT_VOID:
if (debugout) TRACE_(olerelay)("<void>");
@@ -761,7 +775,7 @@
if (debugout) TRACE_(olerelay)("[%ld]",adesc->rgbounds[i].cElements);
arrsize *= adesc->rgbounds[i].cElements;
}
- if (debugout) TRACE_(olerelay)("(vt %d)",adesc->tdescElem.vt);
+ if (debugout) TRACE_(olerelay)("(vt
%s)",debugstr_vt(adesc->tdescElem.vt));
if (debugout) TRACE_(olerelay)("[");
for (i=0;i<arrsize;i++) {
hres = serialize_param(tinfo, writeit, debugout, dealloc, &adesc->tdescElem,
(DWORD*)((LPBYTE)arg+i*_xsize(&adesc->tdescElem)), buf);
@@ -790,7 +804,7 @@
{
HRESULT hres = S_OK;
- TRACE("vt %d at %p\n",tdesc->vt,arg);
+ TRACE("vt %s at %p\n",debugstr_vt(tdesc->vt),arg);
while (1) {
switch (tdesc->vt) {
@@ -814,7 +828,7 @@
memset(&tdesc2,0,sizeof(tdesc2));
tdesc2.vt = vttype;
V_VT(vt) = vttype;
- if (debugout) TRACE_(olerelay)("Vt(%ld)(",vttype);
+ if (debugout)
TRACE_(olerelay)("Vt(%s%s)(",debugstr_vt(vttype),debugstr_vf(vttype));
hres = deserialize_param(tinfo, readit, debugout, alloc, &tdesc2,
(DWORD*)&(V_I4(vt)), buf);
TRACE_(olerelay)(")");
return hres;
@@ -825,6 +839,7 @@
}
case VT_I8:
case VT_UI8:
+ case VT_CY:
if (readit) {
hres = xbuf_get(buf,(LPBYTE)arg,8);
if (hres) ERR("Failed to read integer 8 byte\n");
@@ -834,6 +849,7 @@
case VT_ERROR:
case VT_BOOL:
case VT_I4:
+ case VT_INT:
case VT_UINT:
case VT_R4:
case VT_UI4:
@@ -1371,56 +1387,29 @@
static HRESULT WINAPI ProxyIDispatch_GetTypeInfoCount(LPDISPATCH iface, UINT * pctinfo)
{
TMProxyImpl *This = (TMProxyImpl *)iface;
- HRESULT hr;
TRACE("(%p)\n", pctinfo);
- if (!This->dispatch)
- {
- hr = IUnknown_QueryInterface(This->outerunknown, &IID_IDispatch,
- (LPVOID *)&This->dispatch);
- }
- if (This->dispatch)
- hr = IDispatch_GetTypeInfoCount(This->dispatch, pctinfo);
-
- return hr;
+ return IDispatch_GetTypeInfoCount(This->dispatch, pctinfo);
}
static HRESULT WINAPI ProxyIDispatch_GetTypeInfo(LPDISPATCH iface, UINT iTInfo, LCID
lcid, ITypeInfo** ppTInfo)
{
TMProxyImpl *This = (TMProxyImpl *)iface;
- HRESULT hr = S_OK;
TRACE("(%d, %lx, %p)\n", iTInfo, lcid, ppTInfo);
- if (!This->dispatch)
- {
- hr = IUnknown_QueryInterface(This->outerunknown, &IID_IDispatch,
- (LPVOID *)&This->dispatch);
- }
- if (This->dispatch)
- hr = IDispatch_GetTypeInfo(This->dispatch, iTInfo, lcid, ppTInfo);
-
- return hr;
+ return IDispatch_GetTypeInfo(This->dispatch, iTInfo, lcid, ppTInfo);
}
static HRESULT WINAPI ProxyIDispatch_GetIDsOfNames(LPDISPATCH iface, REFIID riid,
LPOLESTR * rgszNames, UINT cNames, LCID lcid, DISPID * rgDispId)
{
TMProxyImpl *This = (TMProxyImpl *)iface;
- HRESULT hr;
TRACE("(%s, %p, %d, 0x%lx, %p)\n", debugstr_guid(riid), rgszNames, cNames,
lcid, rgDispId);
- if (!This->dispatch)
- {
- hr = IUnknown_QueryInterface(This->outerunknown, &IID_IDispatch,
- (LPVOID *)&This->dispatch);
- }
- if (This->dispatch)
- hr = IDispatch_GetIDsOfNames(This->dispatch, riid, rgszNames,
- cNames, lcid, rgDispId);
-
- return hr;
+ return IDispatch_GetIDsOfNames(This->dispatch, riid, rgszNames,
+ cNames, lcid, rgDispId);
}
static HRESULT WINAPI ProxyIDispatch_Invoke(LPDISPATCH iface, DISPID dispIdMember, REFIID
riid, LCID lcid,
@@ -1428,21 +1417,25 @@
EXCEPINFO * pExcepInfo, UINT * puArgErr)
{
TMProxyImpl *This = (TMProxyImpl *)iface;
- HRESULT hr;
-
- TRACE("(%ld, %s, 0x%lx, 0x%x, %p, %p, %p, %p)\n", dispIdMember,
debugstr_guid(riid), lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
-
- if (!This->dispatch)
- {
- hr = IUnknown_QueryInterface(This->outerunknown, &IID_IDispatch,
- (LPVOID *)&This->dispatch);
- }
- if (This->dispatch)
- hr = IDispatch_Invoke(This->dispatch, dispIdMember, riid, lcid,
- wFlags, pDispParams, pVarResult, pExcepInfo,
- puArgErr);
-
- return hr;
+
+ TRACE("(%ld, %s, 0x%lx, 0x%x, %p, %p, %p, %p)\n", dispIdMember,
+ debugstr_guid(riid), lcid, wFlags, pDispParams, pVarResult,
+ pExcepInfo, puArgErr);
+
+ return IDispatch_Invoke(This->dispatch, dispIdMember, riid, lcid,
+ wFlags, pDispParams, pVarResult, pExcepInfo,
+ puArgErr);
+}
+
+static inline HRESULT get_facbuf_for_iid(REFIID riid, IPSFactoryBuffer **facbuf)
+{
+ HRESULT hr;
+ CLSID clsid;
+
+ if ((hr = CoGetPSClsid(riid, &clsid)))
+ return hr;
+ return CoGetClassObject(&clsid, CLSCTX_INPROC_SERVER, NULL,
+ &IID_IPSFactoryBuffer, (LPVOID*)facbuf);
}
static HRESULT WINAPI
@@ -1470,6 +1463,7 @@
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) {
@@ -1549,10 +1543,22 @@
{
if (typeattr->wTypeFlags & TYPEFLAG_FDISPATCHABLE)
{
- proxy->lpvtbl[3] = ProxyIDispatch_GetTypeInfoCount;
- proxy->lpvtbl[4] = ProxyIDispatch_GetTypeInfo;
- proxy->lpvtbl[5] = ProxyIDispatch_GetIDsOfNames;
- proxy->lpvtbl[6] = ProxyIDispatch_Invoke;
+ IPSFactoryBuffer *factory_buffer;
+ hres = get_facbuf_for_iid(&IID_IDispatch, &factory_buffer);
+ if (hres == S_OK)
+ {
+ hres = IPSFactoryBuffer_CreateProxy(factory_buffer, NULL,
+ &IID_IDispatch, &proxy->dispatch_proxy,
+ (void **)&proxy->dispatch);
+ IPSFactoryBuffer_Release(factory_buffer);
+ }
+ if (hres == S_OK)
+ {
+ proxy->lpvtbl[3] = ProxyIDispatch_GetTypeInfoCount;
+ proxy->lpvtbl[4] = ProxyIDispatch_GetTypeInfo;
+ proxy->lpvtbl[5] = ProxyIDispatch_GetIDsOfNames;
+ proxy->lpvtbl[6] = ProxyIDispatch_Invoke;
+ }
}
ITypeInfo_ReleaseTypeAttr(tinfo, typeattr);
}
@@ -1563,10 +1569,16 @@
proxy->tinfo = tinfo;
memcpy(&proxy->iid,riid,sizeof(*riid));
proxy->chanbuf = 0;
- *ppv = (LPVOID)proxy;
- *ppProxy = (IRpcProxyBuffer *)&(proxy->lpvtbl2);
- IUnknown_AddRef((IUnknown *)*ppv);
- return S_OK;
+ if (hres == S_OK)
+ {
+ *ppv = (LPVOID)proxy;
+ *ppProxy = (IRpcProxyBuffer *)&(proxy->lpvtbl2);
+ IUnknown_AddRef((IUnknown *)*ppv);
+ return S_OK;
+ }
+ else
+ TMProxyImpl_Release((IRpcProxyBuffer *)&proxy->lpvtbl2);
+ return hres;
}
typedef struct _TMStubImpl {
@@ -1576,6 +1588,7 @@
LPUNKNOWN pUnk;
ITypeInfo *tinfo;
IID iid;
+ IRpcStubBuffer *dispatch_stub;
} TMStubImpl;
static HRESULT WINAPI
@@ -1627,6 +1640,10 @@
IUnknown_AddRef(pUnkServer);
This->pUnk = pUnkServer;
+
+ if (This->dispatch_stub)
+ IRpcStubBuffer_Connect(This->dispatch_stub, pUnkServer);
+
return S_OK;
}
@@ -1642,6 +1659,9 @@
IUnknown_Release(This->pUnk);
This->pUnk = NULL;
}
+
+ if (This->dispatch_stub)
+ IRpcStubBuffer_Disconnect(This->dispatch_stub);
}
static HRESULT WINAPI
@@ -1659,18 +1679,21 @@
BSTR iname = NULL;
ITypeInfo *tinfo;
+ TRACE("...\n");
+
+ if (xmsg->iMethod < 3) {
+ ERR("IUnknown methods cannot be marshaled by the typelib
marshaler\n");
+ return E_UNEXPECTED;
+ }
+
+ if (This->dispatch_stub && xmsg->iMethod <
sizeof(IDispatchVtbl)/sizeof(void *))
+ return IRpcStubBuffer_Invoke(This->dispatch_stub, xmsg, rpcchanbuf);
+
memset(&buf,0,sizeof(buf));
buf.size = xmsg->cbBuffer;
buf.base = HeapAlloc(GetProcessHeap(), 0, xmsg->cbBuffer);
memcpy(buf.base, xmsg->Buffer, xmsg->cbBuffer);
buf.curoff = 0;
-
- TRACE("...\n");
-
- if (xmsg->iMethod < 3) {
- ERR("IUnknown methods cannot be marshaled by the typelib
marshaler\n");
- return E_UNEXPECTED;
- }
hres =
_get_funcdesc(This->tinfo,xmsg->iMethod,&tinfo,&fdesc,&iname,NULL);
if (hres) {
@@ -1830,25 +1853,48 @@
HRESULT hres;
ITypeInfo *tinfo;
TMStubImpl *stub;
+ TYPEATTR *typeattr;
TRACE("(%s,%p,%p)\n",debugstr_guid(riid),pUnkServer,ppStub);
+
hres = _get_typeinfo_for_iid(riid,&tinfo);
if (hres) {
ERR("No typeinfo for %s?\n",debugstr_guid(riid));
return hres;
}
+
stub = CoTaskMemAlloc(sizeof(TMStubImpl));
if (!stub)
return E_OUTOFMEMORY;
stub->lpvtbl = &tmstubvtbl;
stub->ref = 1;
stub->tinfo = tinfo;
+ stub->dispatch_stub = NULL;
memcpy(&(stub->iid),riid,sizeof(*riid));
hres = IRpcStubBuffer_Connect((LPRPCSTUBBUFFER)stub,pUnkServer);
*ppStub = (LPRPCSTUBBUFFER)stub;
TRACE("IRpcStubBuffer: %p\n", stub);
if (hres)
ERR("Connect to pUnkServer failed?\n");
+
+ /* if we derive from IDispatch then defer to its stub for some of its methods */
+ hres = ITypeInfo_GetTypeAttr(tinfo, &typeattr);
+ if (hres == S_OK)
+ {
+ if (typeattr->wTypeFlags & TYPEFLAG_FDISPATCHABLE)
+ {
+ IPSFactoryBuffer *factory_buffer;
+ hres = get_facbuf_for_iid(&IID_IDispatch, &factory_buffer);
+ if (hres == S_OK)
+ {
+ hres = IPSFactoryBuffer_CreateStub(factory_buffer, &IID_IDispatch,
+ pUnkServer, &stub->dispatch_stub);
+ IPSFactoryBuffer_Release(factory_buffer);
+ }
+ }
+ ITypeInfo_ReleaseTypeAttr(tinfo, typeattr);
+ }
+
return hres;
}
Modified: trunk/reactos/dll/win32/oleaut32/typelib.c
URL:
http://svn.reactos.ru/svn/reactos/trunk/reactos/dll/win32/oleaut32/typelib.…
==============================================================================
--- trunk/reactos/dll/win32/oleaut32/typelib.c (original)
+++ trunk/reactos/dll/win32/oleaut32/typelib.c Mon Mar 27 20:44:53 2006
@@ -196,7 +196,7 @@
return buffer;
}
-int TLB_ReadTypeLib(LPCWSTR file, INT index, ITypeLib2 **ppTypelib);
+static int TLB_ReadTypeLib(LPCWSTR pszFileName, LPWSTR pszPath, UINT cchPath, ITypeLib2
**ppTypeLib);
/****************************************************************************
@@ -333,38 +333,14 @@
REGKIND regkind, /* [in] Specify kind of registration */
ITypeLib **pptLib) /* [out] Pointer to pointer to loaded type library */
{
- WCHAR szPath[MAX_PATH+1], szFileCopy[MAX_PATH+1];
- WCHAR *pIndexStr;
+ WCHAR szPath[MAX_PATH+1];
HRESULT res;
- INT index = 1;
TRACE("(%s,%d,%p)\n",debugstr_w(szFile), regkind, pptLib);
- /* by default try and load using LoadLibrary (for builtin stdole32.tlb) */
- memcpy(szPath, szFile, (strlenW(szFile)+1)*sizeof(WCHAR));
-
*pptLib = NULL;
- if(!SearchPathW(NULL,szFile,NULL,sizeof(szPath)/sizeof(WCHAR),szPath,
- NULL)) {
-
- /* Look for a trailing '\\' followed by an index */
- pIndexStr = strrchrW(szFile, '\\');
- if(pIndexStr && pIndexStr != szFile && *++pIndexStr != '\0') {
- index = atoiW(pIndexStr);
- memcpy(szFileCopy, szFile,
- (pIndexStr - szFile - 1) * sizeof(WCHAR));
- szFileCopy[pIndexStr - szFile - 1] = '\0';
- if(!SearchPathW(NULL,szFileCopy,NULL,sizeof(szPath)/sizeof(WCHAR),
- szPath,NULL))
- return TYPE_E_CANTLOADLIBRARY;
- if (GetFileAttributesW(szFileCopy) & FILE_ATTRIBUTE_DIRECTORY)
- return TYPE_E_CANTLOADLIBRARY;
- }
- }
-
- TRACE("File %s index %d\n", debugstr_w(szPath), index);
-
- res = TLB_ReadTypeLib(szPath, index, (ITypeLib2**)pptLib);
+
+ res = TLB_ReadTypeLib(szFile, szPath, MAX_PATH + 1, (ITypeLib2**)pptLib);
if (SUCCEEDED(res))
switch(regkind)
@@ -1224,7 +1200,7 @@
}
else if (V_ISARRAY(pvar) || V_ISVECTOR(pvar))
{
- TRACE(",FIXME");
+ TRACE(",%p", V_ARRAY(pvar));
}
else switch (V_TYPE(pvar))
{
@@ -1988,9 +1964,10 @@
(*ppRefType)->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;
} else
- (*ppRefType)->index = impinfo.oGuid;
+ (*ppRefType)->index = impinfo.oGuid;
}else{
ERR("Cannot find a reference\n");
(*ppRefType)->reference=-1;
@@ -2033,6 +2010,7 @@
static ITypeInfoImpl * MSFT_DoTypeInfo(
TLBContext *pcx,
int count,
+ INT dispatch_href,
ITypeLibImpl * pLibInfo)
{
MSFT_TypeInfoBase tiBase;
@@ -2113,38 +2091,10 @@
ptiRet->impltypelist->hRef = tiBase.datatype1;
}
else
- { /* FIXME: This is a really bad hack to add IDispatch */
- const char* szStdOle = "stdole2.tlb\0";
- int nStdOleLen = strlen(szStdOle);
- TLBRefType **ppRef = &ptiRet->reflist;
-
- while(*ppRef) {
- if((*ppRef)->reference == -1)
- break;
- ppRef = &(*ppRef)->next;
- }
- if(!*ppRef) {
- *ppRef = TLB_Alloc(sizeof(**ppRef));
- (*ppRef)->guid = IID_IDispatch;
- (*ppRef)->reference = -1;
- (*ppRef)->index = TLB_REF_USE_GUID;
- (*ppRef)->pImpTLInfo = TLB_Alloc(sizeof(TLBImpLib));
- (*ppRef)->pImpTLInfo->guid = IID_StdOle;
- (*ppRef)->pImpTLInfo->name = SysAllocStringLen(NULL,
- nStdOleLen + 1);
-
- MultiByteToWideChar(CP_ACP,
- MB_PRECOMPOSED,
- szStdOle,
- -1,
- (*ppRef)->pImpTLInfo->name,
- SysStringLen((*ppRef)->pImpTLInfo->name));
-
- (*ppRef)->pImpTLInfo->lcid = 0;
- (*ppRef)->pImpTLInfo->wVersionMajor = 2;
- (*ppRef)->pImpTLInfo->wVersionMinor = 0;
- }
- }
+ {
+ MSFT_DoRefType(pcx, ptiRet, dispatch_href);
+ ptiRet->impltypelist->hRef = dispatch_href;
+ }
break;
default:
ptiRet->impltypelist=TLB_Alloc(sizeof(TLBImplType));
@@ -2188,22 +2138,50 @@
*/
#define MSFT_SIGNATURE 0x5446534D /* "MSFT" */
#define SLTG_SIGNATURE 0x47544c53 /* "SLTG" */
-int TLB_ReadTypeLib(LPCWSTR pszFileName, INT index, ITypeLib2 **ppTypeLib)
+static int TLB_ReadTypeLib(LPCWSTR pszFileName, LPWSTR pszPath, UINT cchPath, ITypeLib2
**ppTypeLib)
{
ITypeLibImpl *entry;
int ret = TYPE_E_CANTLOADLIBRARY;
- DWORD dwSignature = 0;
- HANDLE hFile;
-
- TRACE_(typelib)("%s:%d\n", debugstr_w(pszFileName), index);
+ INT index = 1;
+ HINSTANCE hinstDLL;
*ppTypeLib = NULL;
+
+ lstrcpynW(pszPath, pszFileName, cchPath);
+
+ /* first try loading as a dll and access the typelib as a resource */
+ hinstDLL = LoadLibraryExW(pszFileName, 0, DONT_RESOLVE_DLL_REFERENCES |
+ LOAD_LIBRARY_AS_DATAFILE | LOAD_WITH_ALTERED_SEARCH_PATH);
+ if (!hinstDLL)
+ {
+ /* it may have been specified with resource index appended to the
+ * path, so remove it and try again */
+ const WCHAR *pIndexStr = strrchrW(pszFileName, '\\');
+ if(pIndexStr && pIndexStr != pszFileName && *++pIndexStr !=
'\0')
+ {
+ index = atoiW(pIndexStr);
+ pszPath[pIndexStr - pszFileName - 1] = '\0';
+
+ hinstDLL = LoadLibraryExW(pszPath, 0, DONT_RESOLVE_DLL_REFERENCES |
+ LOAD_LIBRARY_AS_DATAFILE | LOAD_WITH_ALTERED_SEARCH_PATH);
+ }
+ }
+
+ /* get the path to the specified typelib file */
+ if (!hinstDLL)
+ {
+ /* otherwise, try loading as a regular file */
+ if (!SearchPathW(NULL, pszFileName, NULL, cchPath, pszPath, NULL))
+ return TYPE_E_CANTLOADLIBRARY;
+ }
+
+ TRACE_(typelib)("File %s index %d\n", debugstr_w(pszPath), index);
/* We look the path up in the typelib cache. If found, we just addref it, and return
the pointer. */
EnterCriticalSection(&cache_section);
for (entry = tlb_cache_first; entry != NULL; entry = entry->next)
{
- if (!strcmpiW(entry->path, pszFileName) && entry->index == index)
+ if (!strcmpiW(entry->path, pszPath) && entry->index == index)
{
TRACE("cache hit\n");
*ppTypeLib = (ITypeLib2*)entry;
@@ -2214,88 +2192,69 @@
}
LeaveCriticalSection(&cache_section);
- /* check the signature of the file */
- hFile = CreateFileW( pszFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING,
0, 0 );
- if (INVALID_HANDLE_VALUE != hFile)
- {
- HANDLE hMapping = CreateFileMappingW( hFile, NULL, PAGE_READONLY | SEC_COMMIT, 0,
0, NULL );
- if (hMapping)
- {
- LPVOID pBase = MapViewOfFile(hMapping, FILE_MAP_READ, 0, 0, 0);
- if(pBase)
- {
- /* retrieve file size */
- DWORD dwTLBLength = GetFileSize(hFile, NULL);
-
- /* first try to load as *.tlb */
- dwSignature = FromLEDWord(*((DWORD*) pBase));
- if ( dwSignature == MSFT_SIGNATURE)
- {
- *ppTypeLib = ITypeLib2_Constructor_MSFT(pBase, dwTLBLength);
- }
- else if ( dwSignature == SLTG_SIGNATURE)
- {
- *ppTypeLib = ITypeLib2_Constructor_SLTG(pBase, dwTLBLength);
- }
- UnmapViewOfFile(pBase);
- }
- CloseHandle(hMapping);
- }
- CloseHandle(hFile);
- }
- else
- {
- TRACE("not found, trying to load %s as library\n",
debugstr_w(pszFileName));
- }
-
- /* if the file is a DLL or not found, try loading it with LoadLibrary */
- if (((WORD)dwSignature == IMAGE_DOS_SIGNATURE) || (dwSignature == 0))
- {
- /* find the typelibrary resource*/
- HINSTANCE hinstDLL = LoadLibraryExW(pszFileName, 0, DONT_RESOLVE_DLL_REFERENCES|
-
LOAD_LIBRARY_AS_DATAFILE|LOAD_WITH_ALTERED_SEARCH_PATH);
- if (hinstDLL)
- {
+ /* now actually load and parse the typelib */
+ if (hinstDLL)
+ {
static const WCHAR TYPELIBW[] =
{'T','Y','P','E','L','I','B',0};
HRSRC hrsrc = FindResourceW(hinstDLL, MAKEINTRESOURCEW(index), TYPELIBW);
if (hrsrc)
{
- HGLOBAL hGlobal = LoadResource(hinstDLL, hrsrc);
- if (hGlobal)
- {
- LPVOID pBase = LockResource(hGlobal);
- DWORD dwTLBLength = SizeofResource(hinstDLL, hrsrc);
-
- if (pBase)
+ HGLOBAL hGlobal = LoadResource(hinstDLL, hrsrc);
+ if (hGlobal)
{
- /* try to load as incore resource */
- dwSignature = FromLEDWord(*((DWORD*) pBase));
- if ( dwSignature == MSFT_SIGNATURE)
- {
- *ppTypeLib = ITypeLib2_Constructor_MSFT(pBase, dwTLBLength);
- }
- else if ( dwSignature == SLTG_SIGNATURE)
- {
- *ppTypeLib = ITypeLib2_Constructor_SLTG(pBase, dwTLBLength);
- }
- else
- {
- FIXME("Header type magic 0x%08lx not
supported.\n",dwSignature);
- }
+ LPVOID pBase = LockResource(hGlobal);
+ DWORD dwTLBLength = SizeofResource(hinstDLL, hrsrc);
+
+ if (pBase)
+ {
+ /* try to load as incore resource */
+ DWORD dwSignature = FromLEDWord(*((DWORD*) pBase));
+ if (dwSignature == MSFT_SIGNATURE)
+ *ppTypeLib = ITypeLib2_Constructor_MSFT(pBase, dwTLBLength);
+ else if (dwSignature == SLTG_SIGNATURE)
+ *ppTypeLib = ITypeLib2_Constructor_SLTG(pBase, dwTLBLength);
+ else
+ FIXME("Header type magic 0x%08lx not
supported.\n",dwSignature);
+ }
+ FreeResource( hGlobal );
}
- FreeResource( hGlobal );
- }
}
FreeLibrary(hinstDLL);
- }
+ }
+ else
+ {
+ HANDLE hFile = CreateFileW(pszPath, GENERIC_READ, FILE_SHARE_READ, NULL,
OPEN_EXISTING, 0, 0 );
+ if (INVALID_HANDLE_VALUE != hFile)
+ {
+ HANDLE hMapping = CreateFileMappingW( hFile, NULL, PAGE_READONLY |
SEC_COMMIT, 0, 0, NULL );
+ if (hMapping)
+ {
+ LPVOID pBase = MapViewOfFile(hMapping, FILE_MAP_READ, 0, 0, 0);
+ if(pBase)
+ {
+ /* retrieve file size */
+ DWORD dwTLBLength = GetFileSize(hFile, NULL);
+ DWORD dwSignature = FromLEDWord(*((DWORD*) pBase));
+
+ if (dwSignature == MSFT_SIGNATURE)
+ *ppTypeLib = ITypeLib2_Constructor_MSFT(pBase, dwTLBLength);
+ else if (dwSignature == SLTG_SIGNATURE)
+ *ppTypeLib = ITypeLib2_Constructor_SLTG(pBase, dwTLBLength);
+
+ UnmapViewOfFile(pBase);
+ }
+ CloseHandle(hMapping);
+ }
+ CloseHandle(hFile);
+ }
}
if(*ppTypeLib) {
ITypeLibImpl *impl = (ITypeLibImpl*)*ppTypeLib;
TRACE("adding to cache\n");
- impl->path = HeapAlloc(GetProcessHeap(), 0, (strlenW(pszFileName)+1) *
sizeof(WCHAR));
- lstrcpyW(impl->path, pszFileName);
+ impl->path = HeapAlloc(GetProcessHeap(), 0, (strlenW(pszPath)+1) * sizeof(WCHAR));
+ lstrcpyW(impl->path, pszPath);
/* We should really canonicalise the path here. */
impl->index = index;
@@ -2314,6 +2273,20 @@
/*================== ITypeLib(2) Methods ===================================*/
+static ITypeLibImpl* TypeLibImpl_Constructor(void)
+{
+ ITypeLibImpl* pTypeLibImpl;
+
+ pTypeLibImpl = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(ITypeLibImpl));
+ if (!pTypeLibImpl) return NULL;
+
+ pTypeLibImpl->lpVtbl = &tlbvt;
+ pTypeLibImpl->lpVtblTypeComp = &tlbtcvt;
+ pTypeLibImpl->ref = 1;
+
+ return pTypeLibImpl;
+}
+
/****************************************************************************
* ITypeLib2_Constructor_MSFT
*
@@ -2329,12 +2302,8 @@
TRACE("%p, TLB length = %ld\n", pLib, dwTLBLength);
- pTypeLibImpl = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(ITypeLibImpl));
+ pTypeLibImpl = TypeLibImpl_Constructor();
if (!pTypeLibImpl) return NULL;
-
- pTypeLibImpl->lpVtbl = &tlbvt;
- pTypeLibImpl->lpVtblTypeComp = &tlbtcvt;
- pTypeLibImpl->ref = 1;
/* get pointer to beginning of typelib data */
cx.pos = 0;
@@ -2345,12 +2314,14 @@
/* read header */
MSFT_ReadLEDWords((void*)&tlbHeader, sizeof(tlbHeader), &cx, 0);
- TRACE("header:\n");
- TRACE("\tmagic1=0x%08x ,magic2=0x%08x\n",tlbHeader.magic1,tlbHeader.magic2
);
+ TRACE_(typelib)("header:\n");
+ TRACE_(typelib)("\tmagic1=0x%08x
,magic2=0x%08x\n",tlbHeader.magic1,tlbHeader.magic2 );
if (tlbHeader.magic1 != MSFT_SIGNATURE) {
FIXME("Header type magic 0x%08x not supported.\n",tlbHeader.magic1);
return NULL;
}
+ TRACE_(typelib)("\tdispatchpos = 0x%x\n", tlbHeader.dispatchpos);
+
/* there is a small amount of information here until the next important
* part:
* the segment directory . Try to calculate the amount of data */
@@ -2515,7 +2486,7 @@
for(i = 0; i<(int)tlbHeader.nrtypeinfos; i++)
{
- *ppTI = MSFT_DoTypeInfo(&cx, i, pTypeLibImpl);
+ *ppTI = MSFT_DoTypeInfo(&cx, i, tlbHeader.dispatchpos, pTypeLibImpl);
ppTI = &((*ppTI)->next);
(pTypeLibImpl->TypeInfoCount)++;
@@ -3155,11 +3126,9 @@
TRACE_(typelib)("%p, TLB length = %ld\n", pLib, dwTLBLength);
- pTypeLibImpl = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(ITypeLibImpl));
+
+ pTypeLibImpl = TypeLibImpl_Constructor();
if (!pTypeLibImpl) return NULL;
-
- pTypeLibImpl->lpVtbl = &tlbvt;
- pTypeLibImpl->ref = 1;
pHeader = pLib;
@@ -3475,13 +3444,16 @@
if (!ref)
{
/* remove cache entry */
- TRACE("removing from cache list\n");
- EnterCriticalSection(&cache_section);
- if (This->next) This->next->prev = This->prev;
- if (This->prev) This->prev->next = This->next;
- else tlb_cache_first = This->next;
- LeaveCriticalSection(&cache_section);
-
+ if(This->path)
+ {
+ TRACE("removing from cache list\n");
+ EnterCriticalSection(&cache_section);
+ if (This->next) This->next->prev = This->prev;
+ if (This->prev) This->prev->next = This->next;
+ else tlb_cache_first = This->next;
+ LeaveCriticalSection(&cache_section);
+ HeapFree(GetProcessHeap(), 0, This->path);
+ }
/* FIXME destroy child objects */
TRACE(" destroying ITypeLib(%p)\n",This);
@@ -4287,7 +4259,12 @@
it means that function is called by ITypeLib2_Release */
ITypeLib2_Release((ITypeLib2*)This->pTypeLib);
} else {
- FIXME("destroy child objects\n");
+ static int once = 0;
+ if (!once)
+ {
+ once = 1;
+ FIXME("destroy child objects\n");
+ }
TRACE("destroying ITypeInfo(%p)\n",This);
if (This->Name)
@@ -4623,8 +4600,8 @@
BSTR *rgBstrNames, UINT cMaxNames, UINT *pcNames)
{
ITypeInfoImpl *This = (ITypeInfoImpl *)iface;
- TLBFuncDesc * pFDesc;
- TLBVarDesc * pVDesc;
+ const TLBFuncDesc *pFDesc;
+ const TLBVarDesc *pVDesc;
int i;
TRACE("(%p) memid=0x%08lx Maxname=%d\n", This, memid, cMaxNames);
for(pFDesc=This->funclist; pFDesc && pFDesc->funcdesc.memid != memid;
pFDesc=pFDesc->next);
@@ -4693,7 +4670,7 @@
ITypeInfoImpl *This = (ITypeInfoImpl *)iface;
int i;
HRESULT hr = S_OK;
- TLBImplType *pImpl = This->impltypelist;
+ const TLBImplType *pImpl = This->impltypelist;
TRACE("(%p) index %d\n", This, index);
if (TRACE_ON(ole)) dump_TypeInfo(This);
@@ -4772,8 +4749,8 @@
LPOLESTR *rgszNames, UINT cNames, MEMBERID *pMemId)
{
ITypeInfoImpl *This = (ITypeInfoImpl *)iface;
- TLBFuncDesc * pFDesc;
- TLBVarDesc * pVDesc;
+ const TLBFuncDesc *pFDesc;
+ const TLBVarDesc *pVDesc;
HRESULT ret=S_OK;
int i;
@@ -4899,6 +4876,24 @@
case 17:
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]);
break;
+ case 18:
+ 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]);
+ break;
+ case 19:
+ 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]);
+ break;
+ case 20:
+ 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]);
+ break;
+ case 21:
+ 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]);
+ break;
+ case 22:
+ 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]);
+ break;
+ 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;
default:
FIXME("unsupported number of arguments %d in stdcall\n",nrargs);
res = -1;
@@ -4916,165 +4911,6 @@
extern int _argsize(DWORD vt);
-/****************************************************************************
- * Helper functions for Dispcall / Invoke, which copies one variant
- * with target type onto the argument stack.
- */
-static HRESULT
-_copy_arg( ITypeInfo2 *tinfo, TYPEDESC *tdesc,
- DWORD *argpos, VARIANT *arg, VARTYPE vt
-) {
- UINT arglen = _argsize(vt)*sizeof(DWORD);
- VARIANT va;
-
- if ((vt==VT_PTR) && tdesc && (tdesc->u.lptdesc->vt ==
VT_VARIANT)) {
- memcpy(argpos,&arg,sizeof(void*));
- return S_OK;
- }
-
- if (V_VT(arg) == vt) {
- memcpy(argpos, &V_I4(arg), arglen);
- return S_OK;
- }
-
- if (V_ISARRAY(arg) && (vt == VT_SAFEARRAY)) {
- memcpy(argpos, &V_ARRAY(arg), sizeof(SAFEARRAY*));
- return S_OK;
- }
-
- if (vt == VT_VARIANT) {
- memcpy(argpos, arg, arglen);
- return S_OK;
- }
- /* Deref BYREF vars if there is need */
- if(V_ISBYREF(arg) && ((V_VT(arg) & ~VT_BYREF)==vt)) {
- memcpy(argpos,(void*)V_I4(arg), arglen);
- return S_OK;
- }
- if (vt==VT_UNKNOWN && V_VT(arg)==VT_DISPATCH) {
- /* in this context, if the type lib specifies IUnknown*, giving an
- IDispatch* is correct; so, don't invoke VariantChangeType */
- memcpy(argpos,&V_I4(arg), arglen);
- return S_OK;
- }
- if ((vt == VT_PTR) && tdesc)
- return _copy_arg(tinfo, tdesc->u.lptdesc, argpos, arg, tdesc->u.lptdesc->vt);
-
- if ((vt == VT_USERDEFINED) && tdesc && tinfo) {
- ITypeInfo *tinfo2 = NULL;
- TYPEATTR *tattr = NULL;
- HRESULT hres;
-
- hres = ITypeInfo_GetRefTypeInfo(tinfo,tdesc->u.hreftype,&tinfo2);
- if (hres) {
- FIXME("Could not get typeinfo of hreftype %lx for VT_USERDEFINED, "
- "while coercing from vt 0x%x. Copying 4 byte.\n",
- tdesc->u.hreftype,V_VT(arg));
- memcpy(argpos, &V_I4(arg), 4);
- return S_OK;
- }
- hres = ITypeInfo_GetTypeAttr(tinfo2,&tattr);
- if( hres )
- {
- ERR("GetTypeAttr failed\n");
- ITypeInfo_Release(tinfo2);
- return hres;
- }
- switch (tattr->typekind) {
- case TKIND_ENUM:
- switch ( V_VT( arg ) ) {
- case VT_I2:
- *argpos = V_I2(arg);
- hres = S_OK;
- break;
- case VT_I4:
- memcpy(argpos, &V_I4(arg), 4);
- hres = S_OK;
- break;
- case VT_BYREF|VT_I4:
- memcpy(argpos, V_I4REF(arg), 4);
- hres = S_OK;
- break;
- default:
- FIXME("vt 0x%x -> TKIND_ENUM unhandled.\n",V_VT(arg));
- hres = E_FAIL;
- break;
- }
- break;
-
- case TKIND_ALIAS:
- tdesc = &(tattr->tdescAlias);
- hres = _copy_arg((ITypeInfo2*)tinfo2, tdesc, argpos, arg, tdesc->vt);
- break;
-
- case TKIND_INTERFACE:
- if (V_VT(arg) == VT_DISPATCH) {
- IDispatch *disp;
- if (IsEqualIID(&IID_IDispatch,&(tattr->guid))) {
- memcpy(argpos, &V_DISPATCH(arg), 4);
- hres = S_OK;
- break;
- }
- hres=IUnknown_QueryInterface(V_DISPATCH(arg),
- &IID_IDispatch,(LPVOID*)&disp);
- if (SUCCEEDED(hres)) {
- memcpy(argpos,&disp,4);
- IUnknown_Release(V_DISPATCH(arg));
- hres = S_OK;
- break;
- }
- FIXME("Failed to query IDispatch interface from %s while "
- "converting to
VT_DISPATCH!\n",debugstr_guid(&(tattr->guid)));
- hres = E_FAIL;
- break;
- }
- if (V_VT(arg) == VT_UNKNOWN) {
- memcpy(argpos, &V_UNKNOWN(arg), 4);
- hres = S_OK;
- break;
- }
- FIXME("vt 0x%x -> TKIND_INTERFACE(%s) unhandled\n",
- V_VT(arg),debugstr_guid(&(tattr->guid)));
- hres = E_FAIL;
- break;
-
- case TKIND_DISPATCH:
- if (V_VT(arg) == VT_DISPATCH) {
- memcpy(argpos, &V_DISPATCH(arg), 4);
- hres = S_OK;
- }
- else {
- hres = E_FAIL;
- FIXME("TKIND_DISPATCH unhandled for target vt 0x%x.\n",V_VT(arg));
- }
- break;
- case TKIND_RECORD:
- FIXME("TKIND_RECORD unhandled.\n");
- hres = E_FAIL;
- break;
- default:
- FIXME("TKIND %d unhandled.\n",tattr->typekind);
- hres = E_FAIL;
- break;
- }
- ITypeInfo_ReleaseTypeAttr(tinfo2, tattr);
- ITypeInfo_Release(tinfo2);
- return hres;
- }
-
- VariantInit(&va);
- if (VariantChangeType(&va,arg,0,vt)==S_OK) {
- memcpy(argpos,&V_I4(&va), arglen);
- FIXME("Should not use VariantChangeType here."
- " (conversion from 0x%x -> 0x%x) %08lx\n",
- V_VT(arg), vt, *argpos
- );
- return S_OK;
- }
- ERR("Set arg to disparg type 0x%x vs 0x%x\n",V_VT(arg),vt);
- return E_FAIL;
-}
-
static HRESULT userdefined_to_variantvt(ITypeInfo *tinfo, const TYPEDESC *tdesc, VARTYPE
*vt)
{
HRESULT hr = S_OK;
@@ -5144,7 +4980,7 @@
HRESULT hr = S_OK;
/* enforce only one level of pointer indirection */
- if (!(*vt & VT_BYREF) && (tdesc->vt == VT_PTR))
+ if (!(*vt & VT_BYREF) && !(*vt & VT_ARRAY) && (tdesc->vt
== VT_PTR))
{
tdesc = tdesc->u.lptdesc;
@@ -5181,9 +5017,17 @@
case VT_USERDEFINED:
hr = userdefined_to_variantvt(tinfo, tdesc, vt);
break;
+ case VT_VOID:
+ case VT_CARRAY:
case VT_PTR:
- ERR("cannot convert VT_PTR into variant VT\n");
- hr = E_FAIL;
+ case VT_LPSTR:
+ case VT_LPWSTR:
+ ERR("cannot convert type %d into variant VT\n", tdesc->vt);
+ hr = DISP_E_BADVARTYPE;
+ break;
+ case VT_SAFEARRAY:
+ *vt |= VT_ARRAY;
+ hr = typedescvt_to_variantvt(tinfo, tdesc->u.lptdesc, vt);
break;
default:
*vt |= tdesc->vt;
@@ -5229,10 +5073,6 @@
*|CC_MPWCDECL
*|CC_MPWPASCAL
*
- * BUGS
- * Native accepts arguments in the reverse order. I.e. the first item in the
- * prgpvarg array is the last argument in the C/C++ declaration of the
- * function to be called.
*/
HRESULT WINAPI
DispCallFunc(
@@ -5294,6 +5134,17 @@
HeapFree(GetProcessHeap(),0,args);
return S_OK;
}
+
+#define INVBUF_ELEMENT_SIZE \
+ (sizeof(VARIANTARG) + sizeof(VARIANTARG) + sizeof(VARIANTARG *) + sizeof(VARTYPE))
+#define INVBUF_GET_ARG_ARRAY(buffer, params) \
+ ((VARIANTARG *)(buffer))
+#define INVBUF_GET_MISSING_ARG_ARRAY(buffer, params) \
+ ((VARIANTARG *)((char *)(buffer) + sizeof(VARIANTARG) * (params)))
+#define INVBUF_GET_ARG_PTR_ARRAY(buffer, params) \
+ ((VARIANTARG **)((char *)(buffer) + (sizeof(VARIANTARG) + sizeof(VARIANTARG)) *
(params)))
+#define INVBUF_GET_ARG_TYPE_ARRAY(buffer, params) \
+ ((VARTYPE *)((char *)(buffer) + (sizeof(VARIANTARG) + sizeof(VARIANTARG) +
sizeof(VARIANTARG *)) * (params)))
static HRESULT WINAPI ITypeInfo_fnInvoke(
ITypeInfo2 *iface,
@@ -5335,163 +5186,179 @@
switch (func_desc->funckind) {
case FUNC_PUREVIRTUAL:
case FUNC_VIRTUAL: {
- DWORD res;
- int numargs, numargs2, argspos, args2pos;
- DWORD *args , *args2;
- VARIANT *rgvarg = HeapAlloc(GetProcessHeap(), 0, sizeof(VARIANT) *
func_desc->cParams);
- memcpy(rgvarg,pDispParams->rgvarg,sizeof(VARIANT)*pDispParams->cArgs);
+ void *buffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
INVBUF_ELEMENT_SIZE * func_desc->cParams);
+ VARIANT varresult;
+ VARIANT retval; /* pointer for storing byref retvals in */
+ VARIANTARG **prgpvarg = INVBUF_GET_ARG_PTR_ARRAY(buffer,
func_desc->cParams);
+ VARIANTARG *rgvarg = INVBUF_GET_ARG_ARRAY(buffer, func_desc->cParams);
+ VARTYPE *rgvt = INVBUF_GET_ARG_TYPE_ARRAY(buffer, func_desc->cParams);
hres = S_OK;
- numargs = 1; /* sizeof(thisptr) */
- numargs2 = 0;
for (i = 0; i < func_desc->cParams; i++)
{
TYPEDESC *tdesc = &func_desc->lprgelemdescParam[i].tdesc;
-
- numargs += _argsize(tdesc->vt);
- if (i>=pDispParams->cArgs) { /* arguments to return */
- if (tdesc->vt == VT_PTR) {
- numargs2 += _argsize(tdesc->u.lptdesc->vt);
- } else {
- FIXME("The variant type here should have been VT_PTR, not vt
%d\n", tdesc->vt);
- numargs2 += _argsize(tdesc->vt);
+ hres = typedescvt_to_variantvt((ITypeInfo *)iface, tdesc, &rgvt[i]);
+ if (FAILED(hres))
+ goto func_fail;
+ }
+
+ TRACE("changing args\n");
+ for (i = 0; i < func_desc->cParams; i++)
+ {
+ USHORT wParamFlags =
func_desc->lprgelemdescParam[i].u.paramdesc.wParamFlags;
+
+ if (wParamFlags & PARAMFLAG_FRETVAL)
+ {
+ /* note: this check is placed so that if the caller passes
+ * in a VARIANTARG for the retval we just ignore it, like
+ * native does */
+ if (i == func_desc->cParams - 1)
+ {
+ VARIANTARG *arg;
+ arg = prgpvarg[i] = &rgvarg[i];
+ memset(arg, 0, sizeof(*arg));
+ V_VT(arg) = rgvt[i];
+ memset(&retval, 0, sizeof(retval));
+ V_BYREF(arg) = &retval;
+ }
+ else
+ {
+ ERR("[retval] parameter must be the last parameter of the
method (%d/%d)\n", i, func_desc->cParams);
+ hres = E_UNEXPECTED;
+ break;
}
}
- }
-
- args = HeapAlloc(GetProcessHeap(),0,sizeof(DWORD)*numargs);
- args2 = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(DWORD)*numargs2);
-
- args[0] = (DWORD)pIUnk;
- argspos = 1; args2pos = 0;
- for (i = 0; i < func_desc->cParams; i++)
- {
- ELEMDESC *elemdesc = &(func_desc->lprgelemdescParam[i]);
- TYPEDESC *tdesc = &(elemdesc->tdesc);
- USHORT paramFlags = elemdesc->u.paramdesc.wParamFlags;
- int arglen = _argsize(tdesc->vt);
-
- if (i<pDispParams->cArgs)
+ else if (i < pDispParams->cArgs)
{
- VARIANT *arg = &rgvarg[pDispParams->cArgs-i-1];
-
- if (paramFlags & PARAMFLAG_FOPT) {
- if(i < func_desc->cParams - func_desc->cParamsOpt)
- ERR("Parameter has PARAMFLAG_FOPT flag but is not one of
last cParamOpt parameters\n");
- if(V_VT(arg) == VT_EMPTY
- || ((V_ISBYREF(arg)) && !V_BYREF(arg))) {
- /* FIXME: Documentation says that we do this when
parameter is left unspecified.
- How to determine it? */
-
- if(paramFlags & PARAMFLAG_FHASDEFAULT)
- FIXME("PARAMFLAG_FHASDEFAULT flag not
supported\n");
- V_VT(arg) = VT_ERROR;
- V_ERROR(arg) = DISP_E_PARAMNOTFOUND;
- arglen = _argsize(VT_ERROR);
- }
+ VARIANTARG *src_arg =
&pDispParams->rgvarg[pDispParams->cArgs - 1 - i];
+ V_VT(&rgvarg[i]) = V_VT(src_arg);
+ dump_Variant(src_arg);
+
+ /* FIXME: this doesn't work for VT_BYREF arguments if
+ * they are not the same type as in the paramdesc */
+ if ((rgvt[i] & VT_BYREF) && !V_ISBYREF(src_arg))
+ {
+ VARIANTARG *missing_arg = INVBUF_GET_MISSING_ARG_ARRAY(buffer,
func_desc->cParams);
+ V_VT(&missing_arg[i]) = V_VT(src_arg);
+ hres = VariantChangeType(&missing_arg[i], src_arg, 0, rgvt[i]
& ~VT_BYREF);
+ V_BYREF(&rgvarg[i]) = &V_NONE(&missing_arg[i]);
}
- hres = _copy_arg(iface, tdesc, &args[argspos], arg,
tdesc->vt);
- if (FAILED(hres)) goto func_fail;
- argspos += arglen;
+ else
+ hres = VariantChangeType(&rgvarg[i], src_arg, 0, rgvt[i]);
+
+ if (FAILED(hres))
+ {
+ ERR("failed to convert param %d to %s%s from %s%s\n",
i,
+ debugstr_vt(rgvt[i]), debugstr_vf(rgvt[i]),
+ debugstr_VT(src_arg), debugstr_VF(src_arg));
+ break;
+ }
+ V_VT(&rgvarg[i]) = rgvt[i];
+ prgpvarg[i] = &rgvarg[i];
}
- else if (paramFlags & PARAMFLAG_FOPT)
+ else if (wParamFlags & PARAMFLAG_FOPT)
{
- VARIANT *arg = &rgvarg[i];
-
- if (i < func_desc->cParams - func_desc->cParamsOpt)
- ERR("Parameter has PARAMFLAG_FOPT flag but is not one of
last cParamOpt parameters\n");
- if (paramFlags & PARAMFLAG_FHASDEFAULT)
- FIXME("PARAMFLAG_FHASDEFAULT flag not supported\n");
-
- V_VT(arg) = VT_ERROR;
- V_ERROR(arg) = DISP_E_PARAMNOTFOUND;
- arglen = _argsize(VT_ERROR);
- hres = _copy_arg(iface, tdesc, &args[argspos], arg,
tdesc->vt);
- if (FAILED(hres)) goto func_fail;
- argspos += arglen;
+ VARIANTARG *arg;
+ arg = prgpvarg[i] = &rgvarg[i];
+ if (wParamFlags & PARAMFLAG_FHASDEFAULT)
+ {
+ hres = VariantCopy(arg,
&func_desc->lprgelemdescParam[i].u.paramdesc.pparamdescex->varDefaultValue);
+ if (FAILED(hres))
+ break;
+ }
+ else
+ {
+ VARIANTARG *missing_arg = INVBUF_GET_MISSING_ARG_ARRAY(buffer,
func_desc->cParams);
+ V_VT(arg) = VT_VARIANT | VT_BYREF;
+ V_VARIANTREF(arg) = &missing_arg[i];
+ V_VT(V_VARIANTREF(arg)) = VT_ERROR;
+ V_ERROR(V_VARIANTREF(arg)) = DISP_E_PARAMNOTFOUND;
+ }
}
else
{
- if (tdesc->vt == VT_PTR)
- arglen = _argsize(tdesc->u.lptdesc->vt);
- else
- FIXME("set %d to pointer for get (type is
%d)\n",i,tdesc->vt);
-
- /* Supply pointers for the rest, so propertyget works*/
- args[argspos] = (DWORD)&args2[args2pos];
-
- /* If pointer to variant, pass reference it. */
- if ((tdesc->vt == VT_PTR) &&
- (tdesc->u.lptdesc->vt == VT_VARIANT) &&
- pVarResult
- )
- args[argspos]= (DWORD)pVarResult;
- argspos += 1;
- args2pos += arglen;
+ hres = DISP_E_BADPARAMCOUNT;
+ break;
}
}
+ if (FAILED(hres)) goto func_fail; /* FIXME: we don't free changed types
here */
if (func_desc->cParamsOpt < 0)
- FIXME("Does not support optional parameters (%d)\n",
func_desc->cParamsOpt);
-
- res = _invoke((*(FARPROC**)pIUnk)[func_desc->oVft/4],
- func_desc->callconv,
- numargs,
- args
- );
+ {
+ FIXME("Does not support safearray optional parameters\n");
+ hres = DISP_E_BADPARAMCOUNT;
+ goto func_fail; /* FIXME: we don't free changed types here */
+ }
+
+ V_VT(&varresult) = 0;
+ hres = typedescvt_to_variantvt((ITypeInfo *)iface,
&func_desc->elemdescFunc.tdesc, &V_VT(&varresult));
+ if (FAILED(hres)) goto func_fail; /* FIXME: we don't free changed types
here */
+
+ hres = DispCallFunc(pIUnk, func_desc->oVft, func_desc->callconv,
+ V_VT(&varresult), func_desc->cParams, rgvt,
+ prgpvarg, &varresult);
for (i = 0; i < func_desc->cParams; i++)
{
USHORT wParamFlags =
func_desc->lprgelemdescParam[i].u.paramdesc.wParamFlags;
if (wParamFlags & PARAMFLAG_FRETVAL)
{
- ELEMDESC *elemdesc = &func_desc->lprgelemdescParam[i];
- TYPEDESC *tdesc = &elemdesc->tdesc;
- VARIANTARG varresult;
- V_VT(&varresult) = 0;
- hres = typedescvt_to_variantvt((ITypeInfo *)iface, tdesc,
&V_VT(&varresult));
- if (hres)
- break;
- /* FIXME: this is really messy - we should keep the
- * args in VARIANTARGs rather than a DWORD array */
- memcpy(&V_UI4(&varresult), &args[i+1], sizeof(DWORD));
if (TRACE_ON(ole))
{
- TRACE("varresult: ");
- dump_Variant(&varresult);
+ TRACE("[retval] value: ");
+ dump_Variant(prgpvarg[i]);
}
if (pVarResult)
/* deref return value */
- hres = VariantCopyInd(pVarResult, &varresult);
+ hres = VariantCopyInd(pVarResult, prgpvarg[i]);
/* free data stored in varresult. Note that
* VariantClear doesn't do what we want because we are
* working with byref types. */
/* FIXME: clear safearrays, bstrs, records and
- * variants here too */
- if ((V_VT(&varresult) == (VT_UNKNOWN | VT_BYREF)) ||
- (V_VT(&varresult) == (VT_DISPATCH | VT_BYREF)))
+ * variants here too */
+ if ((V_VT(prgpvarg[i]) == (VT_UNKNOWN | VT_BYREF)) ||
+ (V_VT(prgpvarg[i]) == (VT_DISPATCH | VT_BYREF)))
{
- if(*V_UNKNOWNREF(&varresult))
- IUnknown_Release(*V_UNKNOWNREF(&varresult));
+ if(*V_UNKNOWNREF(prgpvarg[i]))
+ IUnknown_Release(*V_UNKNOWNREF(prgpvarg[i]));
}
break;
}
+ else if (i < pDispParams->cArgs)
+ {
+ if (wParamFlags & PARAMFLAG_FOUT)
+ {
+ hres =
VariantChangeType(&pDispParams->rgvarg[pDispParams->cArgs - 1 - i],
+ &rgvarg[i], 0,
+
V_VT(&pDispParams->rgvarg[pDispParams->cArgs - 1 - i]));
+ if (FAILED(hres))
+ {
+ ERR("failed to convert param %d to vt %d\n", i,
+ V_VT(&pDispParams->rgvarg[pDispParams->cArgs -
1 - i]));
+ break;
+ }
+ }
+ VariantClear(&rgvarg[i]);
+ }
+ else if (wParamFlags & PARAMFLAG_FOPT)
+ {
+ if (wParamFlags & PARAMFLAG_FHASDEFAULT)
+ VariantClear(&rgvarg[i]);
+ }
}
- if ((func_desc->elemdescFunc.tdesc.vt == VT_HRESULT) &&
FAILED(res))
+ if ((V_VT(&varresult) == VT_ERROR) &&
FAILED(V_ERROR(&varresult)))
{
- WARN("invoked function failed with error 0x%08lx\n", res);
+ WARN("invoked function failed with error 0x%08lx\n",
V_ERROR(&varresult));
hres = DISP_E_EXCEPTION;
- if (pExcepInfo) pExcepInfo->scode = res;
+ if (pExcepInfo) pExcepInfo->scode = V_ERROR(&varresult);
}
func_fail:
- HeapFree(GetProcessHeap(), 0, rgvarg);
- HeapFree(GetProcessHeap(),0,args2);
- HeapFree(GetProcessHeap(),0,args);
+ HeapFree(GetProcessHeap(), 0, buffer);
break;
- }
+ }
case FUNC_DISPATCH: {
IDispatch *disp;
@@ -5562,8 +5429,8 @@
DWORD *pdwHelpContext, BSTR *pBstrHelpFile)
{
ITypeInfoImpl *This = (ITypeInfoImpl *)iface;
- TLBFuncDesc * pFDesc;
- TLBVarDesc * pVDesc;
+ const TLBFuncDesc *pFDesc;
+ const TLBVarDesc *pVDesc;
TRACE("(%p) memid %ld Name(%p) DocString(%p)"
" HelpContext(%p) HelpFile(%p)\n",
This, memid, pBstrName, pBstrDocString, pdwHelpContext, pBstrHelpFile);
@@ -5613,7 +5480,7 @@
WORD *pwOrdinal)
{
ITypeInfoImpl *This = (ITypeInfoImpl *)iface;
- TLBFuncDesc *pFDesc;
+ const TLBFuncDesc *pFDesc;
TRACE("(%p)->(memid %lx, %d, %p, %p, %p)\n", This, memid, invKind,
pBstrDllName, pBstrName, pwOrdinal);
@@ -5947,7 +5814,7 @@
MEMBERID memid, INVOKEKIND invKind, UINT *pFuncIndex)
{
ITypeInfoImpl *This = (ITypeInfoImpl *)iface;
- TLBFuncDesc *pFuncInfo;
+ const TLBFuncDesc *pFuncInfo;
int i;
HRESULT result;
@@ -6171,8 +6038,8 @@
BSTR *pbstrHelpStringDll)
{
ITypeInfoImpl *This = (ITypeInfoImpl *)iface;
- TLBFuncDesc * pFDesc;
- TLBVarDesc * pVDesc;
+ const TLBFuncDesc *pFDesc;
+ const TLBVarDesc *pVDesc;
TRACE("(%p) memid %ld lcid(0x%lx) HelpString(%p) "
"HelpStringContext(%p) HelpStringDll(%p)\n",
This, memid, lcid, pbstrHelpString, pdwHelpStringContext,
@@ -6458,41 +6325,49 @@
LCID lcid, /* [I] Locale Id */
ITypeInfo **pptinfo) /* [O] Destination for created ITypeInfo object */
{
- ITypeInfoImpl *pTIImpl;
+ ITypeInfoImpl *pTIClass, *pTIIface;
+ ITypeLibImpl *pTypeLibImpl;
int param, func;
TLBFuncDesc **ppFuncDesc;
- pTIImpl = (ITypeInfoImpl*)ITypeInfo_Constructor();
- pTIImpl->pTypeLib = NULL;
- pTIImpl->index = 0;
- pTIImpl->Name = NULL;
- pTIImpl->dwHelpContext = -1;
- memset(&pTIImpl->TypeAttr.guid, 0, sizeof(GUID));
- pTIImpl->TypeAttr.lcid = lcid;
- pTIImpl->TypeAttr.typekind = TKIND_COCLASS;
- pTIImpl->TypeAttr.wMajorVerNum = 0;
- pTIImpl->TypeAttr.wMinorVerNum = 0;
- pTIImpl->TypeAttr.cbAlignment = 2;
- pTIImpl->TypeAttr.cbSizeInstance = -1;
- pTIImpl->TypeAttr.cbSizeVft = -1;
- pTIImpl->TypeAttr.cFuncs = 0;
- pTIImpl->TypeAttr.cImplTypes = 1;
- pTIImpl->TypeAttr.cVars = 0;
- pTIImpl->TypeAttr.wTypeFlags = 0;
-
- ppFuncDesc = &pTIImpl->funclist;
+ TRACE_(typelib)("\n");
+ pTypeLibImpl = TypeLibImpl_Constructor();
+ if (!pTypeLibImpl) return E_FAIL;
+
+ pTIIface = (ITypeInfoImpl*)ITypeInfo_Constructor();
+ pTIIface->pTypeLib = pTypeLibImpl;
+ pTIIface->index = 0;
+ pTIIface->Name = NULL;
+ pTIIface->dwHelpContext = -1;
+ memset(&pTIIface->TypeAttr.guid, 0, sizeof(GUID));
+ pTIIface->TypeAttr.lcid = lcid;
+ pTIIface->TypeAttr.typekind = TKIND_INTERFACE;
+ pTIIface->TypeAttr.wMajorVerNum = 0;
+ pTIIface->TypeAttr.wMinorVerNum = 0;
+ pTIIface->TypeAttr.cbAlignment = 2;
+ pTIIface->TypeAttr.cbSizeInstance = -1;
+ pTIIface->TypeAttr.cbSizeVft = -1;
+ pTIIface->TypeAttr.cFuncs = 0;
+ pTIIface->TypeAttr.cImplTypes = 0;
+ pTIIface->TypeAttr.cVars = 0;
+ pTIIface->TypeAttr.wTypeFlags = 0;
+
+ ppFuncDesc = &pTIIface->funclist;
for(func = 0; func < pidata->cMembers; func++) {
METHODDATA *md = pidata->pmethdata + func;
*ppFuncDesc = HeapAlloc(GetProcessHeap(), 0, sizeof(**ppFuncDesc));
(*ppFuncDesc)->Name = SysAllocString(md->szName);
(*ppFuncDesc)->funcdesc.memid = md->dispid;
+ (*ppFuncDesc)->funcdesc.funckind = FUNC_VIRTUAL;
(*ppFuncDesc)->funcdesc.invkind = md->wFlags;
(*ppFuncDesc)->funcdesc.callconv = md->cc;
(*ppFuncDesc)->funcdesc.cParams = md->cArgs;
(*ppFuncDesc)->funcdesc.cParamsOpt = 0;
- (*ppFuncDesc)->funcdesc.oVft = md->iMeth;
- (*ppFuncDesc)->funcdesc.wFuncFlags = 0; /*??*/
+ (*ppFuncDesc)->funcdesc.oVft = md->iMeth << 2;
+ (*ppFuncDesc)->funcdesc.wFuncFlags = 0;
(*ppFuncDesc)->funcdesc.elemdescFunc.tdesc.vt = md->vtReturn;
+ (*ppFuncDesc)->funcdesc.elemdescFunc.u.paramdesc.wParamFlags =
PARAMFLAG_NONE;
+ (*ppFuncDesc)->funcdesc.elemdescFunc.u.paramdesc.pparamdescex = NULL;
(*ppFuncDesc)->funcdesc.lprgelemdescParam = HeapAlloc(GetProcessHeap(),
HEAP_ZERO_MEMORY,
md->cArgs *
sizeof(ELEMDESC));
(*ppFuncDesc)->pParamDesc = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
@@ -6501,9 +6376,49 @@
(*ppFuncDesc)->funcdesc.lprgelemdescParam[param].tdesc.vt =
md->ppdata[param].vt;
(*ppFuncDesc)->pParamDesc[param].Name =
SysAllocString(md->ppdata[param].szName);
}
+ (*ppFuncDesc)->helpcontext = 0;
+ (*ppFuncDesc)->HelpStringContext = 0;
+ (*ppFuncDesc)->HelpString = NULL;
+ (*ppFuncDesc)->Entry = NULL;
+ (*ppFuncDesc)->ctCustData = 0;
+ (*ppFuncDesc)->pCustData = NULL;
+ (*ppFuncDesc)->next = NULL;
ppFuncDesc = &(*ppFuncDesc)->next;
- }
- *pptinfo = (ITypeInfo*)pTIImpl;
+ }
+
+ pTypeLibImpl->pTypeInfo = pTIIface;
+ pTypeLibImpl->TypeInfoCount++;
+
+ pTIClass = (ITypeInfoImpl*)ITypeInfo_Constructor();
+ pTIClass->pTypeLib = pTypeLibImpl;
+ pTIClass->index = 1;
+ pTIClass->Name = NULL;
+ pTIClass->dwHelpContext = -1;
+ memset(&pTIClass->TypeAttr.guid, 0, sizeof(GUID));
+ pTIClass->TypeAttr.lcid = lcid;
+ pTIClass->TypeAttr.typekind = TKIND_COCLASS;
+ pTIClass->TypeAttr.wMajorVerNum = 0;
+ pTIClass->TypeAttr.wMinorVerNum = 0;
+ pTIClass->TypeAttr.cbAlignment = 2;
+ pTIClass->TypeAttr.cbSizeInstance = -1;
+ pTIClass->TypeAttr.cbSizeVft = -1;
+ pTIClass->TypeAttr.cFuncs = 0;
+ pTIClass->TypeAttr.cImplTypes = 1;
+ pTIClass->TypeAttr.cVars = 0;
+ 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;
+
+ pTIIface->next = pTIClass;
+ pTypeLibImpl->TypeInfoCount++;
+
+ *pptinfo = (ITypeInfo*)pTIClass;
return S_OK;
}
@@ -6539,8 +6454,8 @@
BINDPTR * pBindPtr)
{
ITypeInfoImpl *This = info_impl_from_ITypeComp(iface);
- TLBFuncDesc * pFDesc;
- TLBVarDesc * pVDesc;
+ const TLBFuncDesc *pFDesc;
+ const TLBVarDesc *pVDesc;
TRACE("(%s, %lx, 0x%x, %p, %p, %p)\n", debugstr_w(szName), lHash, wFlags,
ppTInfo, pDescKind, pBindPtr);
Modified: trunk/reactos/dll/win32/oleaut32/usrmarshal.c
URL:
http://svn.reactos.ru/svn/reactos/trunk/reactos/dll/win32/oleaut32/usrmarsh…
==============================================================================
--- trunk/reactos/dll/win32/oleaut32/usrmarshal.c (original)
+++ trunk/reactos/dll/win32/oleaut32/usrmarshal.c Mon Mar 27 20:44:53 2006
@@ -60,6 +60,22 @@
{
return NdrDllGetClassObject(rclsid, riid, ppv, OLEAUT32_ProxyFileList,
&CLSID_PSDispatch, &PSFactoryBuffer);
+}
+
+static void dump_user_flags(unsigned long *pFlags)
+{
+ if (HIWORD(*pFlags) == NDR_LOCAL_DATA_REPRESENTATION)
+ TRACE("MAKELONG(NDR_LOCAL_REPRESENTATION, ");
+ else
+ TRACE("MAKELONG(0x%04x, ", HIWORD(*pFlags));
+ switch (LOWORD(*pFlags))
+ {
+ case MSHCTX_LOCAL: TRACE("MSHCTX_LOCAL)"); break;
+ case MSHCTX_NOSHAREDMEM: TRACE("MSHCTX_NOSHAREDMEM)"); break;
+ case MSHCTX_DIFFERENTMACHINE: TRACE("MSHCTX_DIFFERENTMACHINE)");
break;
+ case MSHCTX_INPROC: TRACE("MSHCTX_INPROC)"); break;
+ default: TRACE("%d)", LOWORD(*pFlags));
+ }
}
/* CLEANLOCALSTORAGE */
@@ -516,6 +532,402 @@
CoTaskMemFree(ref);
}
+/* LPSAFEARRAY */
+
+/* Get the number of cells in a SafeArray */
+static ULONG SAFEARRAY_GetCellCount(const SAFEARRAY *psa)
+{
+ const SAFEARRAYBOUND* psab = psa->rgsabound;
+ USHORT cCount = psa->cDims;
+ ULONG ulNumCells = 1;
+
+ while (cCount--)
+ {
+ /* This is a valid bordercase. See testcases. -Marcus */
+ if (!psab->cElements)
+ return 0;
+ ulNumCells *= psab->cElements;
+ psab++;
+ }
+ return ulNumCells;
+}
+
+static inline SF_TYPE SAFEARRAY_GetUnionType(SAFEARRAY *psa)
+{
+ VARTYPE vt;
+ HRESULT hr;
+
+ hr = SafeArrayGetVartype(psa, &vt);
+ if (FAILED(hr))
+ RpcRaiseException(hr);
+
+ if (psa->fFeatures & FADF_HAVEIID)
+ return SF_HAVEIID;
+
+ switch (vt)
+ {
+ case VT_I1:
+ case VT_UI1: return SF_I1;
+ case VT_BOOL:
+ case VT_I2:
+ case VT_UI2: return SF_I2;
+ case VT_INT:
+ case VT_UINT:
+ case VT_I4:
+ case VT_UI4:
+ case VT_R4: return SF_I4;
+ case VT_DATE:
+ case VT_CY:
+ case VT_R8:
+ case VT_I8:
+ case VT_UI8: return SF_I8;
+ case VT_INT_PTR:
+ case VT_UINT_PTR: return (sizeof(UINT_PTR) == 4 ? SF_I4 : SF_I8);
+ case VT_BSTR: return SF_BSTR;
+ case VT_DISPATCH: return SF_DISPATCH;
+ case VT_VARIANT: return SF_VARIANT;
+ case VT_UNKNOWN: return SF_UNKNOWN;
+ /* Note: Return a non-zero size to indicate vt is valid. The actual size
+ * of a UDT is taken from the result of IRecordInfo_GetSize().
+ */
+ case VT_RECORD: return SF_RECORD;
+ default: return SF_ERROR;
+ }
+}
+
+unsigned long WINAPI LPSAFEARRAY_UserSize(unsigned long *pFlags, unsigned long
StartingSize, LPSAFEARRAY *ppsa)
+{
+ unsigned long size = StartingSize;
+
+ TRACE("("); dump_user_flags(pFlags); TRACE(", %ld, %p\n",
StartingSize, *ppsa);
+
+ size += sizeof(ULONG_PTR);
+ if (*ppsa)
+ {
+ SAFEARRAY *psa = *ppsa;
+ ULONG ulCellCount = SAFEARRAY_GetCellCount(psa);
+ SF_TYPE sftype;
+ HRESULT hr;
+
+ size += sizeof(ULONG);
+ size += FIELD_OFFSET(struct _wireSAFEARRAY, uArrayStructs);
+
+ sftype = SAFEARRAY_GetUnionType(psa);
+ size += sizeof(ULONG);
+
+ size += sizeof(ULONG);
+ size += sizeof(ULONG_PTR);
+ if (sftype == SF_HAVEIID)
+ size += sizeof(IID);
+
+ size += sizeof(psa->rgsabound[0]) * psa->cDims;
+
+ size += sizeof(ULONG);
+
+ switch (sftype)
+ {
+ case SF_BSTR:
+ {
+ BSTR* lpBstr;
+
+ for (lpBstr = (BSTR*)psa->pvData; ulCellCount; ulCellCount--,
lpBstr++)
+ size = BSTR_UserSize(pFlags, size, lpBstr);
+
+ break;
+ }
+ case SF_DISPATCH:
+ case SF_UNKNOWN:
+ case SF_HAVEIID:
+ FIXME("size interfaces\n");
+ break;
+ case SF_VARIANT:
+ {
+ VARIANT* lpVariant;
+
+ for (lpVariant = (VARIANT*)psa->pvData; ulCellCount; ulCellCount--,
lpVariant++)
+ size = VARIANT_UserSize(pFlags, size, lpVariant);
+
+ break;
+ }
+ case SF_RECORD:
+ {
+ IRecordInfo* pRecInfo = NULL;
+
+ hr = SafeArrayGetRecordInfo(psa, &pRecInfo);
+ if (FAILED(hr))
+ RpcRaiseException(hr);
+
+ if (pRecInfo)
+ {
+ FIXME("size record info %p\n", pRecInfo);
+
+ IRecordInfo_Release(pRecInfo);
+ }
+ break;
+ }
+ case SF_I1:
+ case SF_I2:
+ case SF_I4:
+ case SF_I8:
+ size += ulCellCount * psa->cbElements;
+ break;
+ default:
+ break;
+ }
+
+ }
+
+ return size;
+}
+
+unsigned char * WINAPI LPSAFEARRAY_UserMarshal(unsigned long *pFlags, unsigned char
*Buffer, LPSAFEARRAY *ppsa)
+{
+ HRESULT hr;
+
+ TRACE("("); dump_user_flags(pFlags); TRACE(", %p, &%p\n",
Buffer, *ppsa);
+
+ *(ULONG_PTR *)Buffer = *ppsa ? TRUE : FALSE;
+ Buffer += sizeof(ULONG_PTR);
+ if (*ppsa)
+ {
+ VARTYPE vt;
+ SAFEARRAY *psa = *ppsa;
+ ULONG ulCellCount = SAFEARRAY_GetCellCount(psa);
+ wireSAFEARRAY wiresa;
+ SF_TYPE sftype;
+ GUID guid;
+
+ *(ULONG *)Buffer = psa->cDims;
+ Buffer += sizeof(ULONG);
+ wiresa = (wireSAFEARRAY)Buffer;
+ wiresa->cDims = psa->cDims;
+ wiresa->fFeatures = psa->fFeatures;
+ wiresa->cbElements = psa->cbElements;
+
+ hr = SafeArrayGetVartype(psa, &vt);
+ if (FAILED(hr))
+ RpcRaiseException(hr);
+ wiresa->cLocks = (USHORT)psa->cLocks | (vt << 16);
+
+ Buffer += FIELD_OFFSET(struct _wireSAFEARRAY, uArrayStructs);
+
+ sftype = SAFEARRAY_GetUnionType(psa);
+ *(ULONG *)Buffer = sftype;
+ Buffer += sizeof(ULONG);
+
+ *(ULONG *)Buffer = ulCellCount;
+ Buffer += sizeof(ULONG);
+ *(ULONG_PTR *)Buffer = (ULONG_PTR)psa->pvData;
+ Buffer += sizeof(ULONG_PTR);
+ if (sftype == SF_HAVEIID)
+ {
+ SafeArrayGetIID(psa, &guid);
+ memcpy(Buffer, &guid, sizeof(guid));
+ Buffer += sizeof(guid);
+ }
+
+ memcpy(Buffer, psa->rgsabound, sizeof(psa->rgsabound[0]) * psa->cDims);
+ Buffer += sizeof(psa->rgsabound[0]) * psa->cDims;
+
+ *(ULONG *)Buffer = ulCellCount;
+ Buffer += sizeof(ULONG);
+
+ if (psa->pvData)
+ {
+ switch (sftype)
+ {
+ case SF_BSTR:
+ {
+ BSTR* lpBstr;
+
+ for (lpBstr = (BSTR*)psa->pvData; ulCellCount; ulCellCount--,
lpBstr++)
+ Buffer = BSTR_UserMarshal(pFlags, Buffer, lpBstr);
+
+ break;
+ }
+ case SF_DISPATCH:
+ case SF_UNKNOWN:
+ case SF_HAVEIID:
+ FIXME("marshal interfaces\n");
+ break;
+ case SF_VARIANT:
+ {
+ VARIANT* lpVariant;
+
+ for (lpVariant = (VARIANT*)psa->pvData; ulCellCount;
ulCellCount--, lpVariant++)
+ Buffer = VARIANT_UserMarshal(pFlags, Buffer, lpVariant);
+
+ break;
+ }
+ case SF_RECORD:
+ {
+ IRecordInfo* pRecInfo = NULL;
+
+ hr = SafeArrayGetRecordInfo(psa, &pRecInfo);
+ if (FAILED(hr))
+ RpcRaiseException(hr);
+
+ if (pRecInfo)
+ {
+ FIXME("write record info %p\n", pRecInfo);
+
+ IRecordInfo_Release(pRecInfo);
+ }
+ break;
+ }
+ case SF_I1:
+ case SF_I2:
+ case SF_I4:
+ case SF_I8:
+ /* Just copy the data over */
+ memcpy(Buffer, psa->pvData, ulCellCount * psa->cbElements);
+ Buffer += ulCellCount * psa->cbElements;
+ break;
+ default:
+ break;
+ }
+ }
+
+ }
+ return Buffer;
+}
+
+#define FADF_AUTOSETFLAGS (FADF_HAVEIID | FADF_RECORD | FADF_HAVEVARTYPE | \
+ FADF_BSTR | FADF_UNKNOWN | FADF_DISPATCH | \
+ FADF_VARIANT | FADF_CREATEVECTOR)
+
+unsigned char * WINAPI LPSAFEARRAY_UserUnmarshal(unsigned long *pFlags, unsigned char
*Buffer, LPSAFEARRAY *ppsa)
+{
+ ULONG_PTR ptr;
+ wireSAFEARRAY wiresa;
+ ULONG cDims;
+ HRESULT hr;
+ SF_TYPE sftype;
+ ULONG cell_count;
+ GUID guid;
+ VARTYPE vt;
+ SAFEARRAYBOUND *wiresab;
+
+ TRACE("("); dump_user_flags(pFlags); TRACE(", %p, %p\n", Buffer,
ppsa);
+
+ ptr = *(ULONG_PTR *)Buffer;
+ Buffer += sizeof(ULONG_PTR);
+
+ if (!ptr)
+ {
+ *ppsa = NULL;
+
+ TRACE("NULL safe array unmarshaled\n");
+
+ return Buffer;
+ }
+
+ cDims = *(ULONG *)Buffer;
+ Buffer += sizeof(ULONG);
+
+ wiresa = (wireSAFEARRAY)Buffer;
+ Buffer += FIELD_OFFSET(struct _wireSAFEARRAY, uArrayStructs);
+
+ if (cDims != wiresa->cDims)
+ RpcRaiseException(RPC_S_INVALID_BOUND);
+
+ /* FIXME: there should be a limit on how large cDims can be */
+
+ vt = HIWORD(wiresa->cLocks);
+
+ sftype = *(ULONG *)Buffer;
+ Buffer += sizeof(ULONG);
+
+ cell_count = *(ULONG *)Buffer;
+ Buffer += sizeof(ULONG);
+ ptr = *(ULONG_PTR *)Buffer;
+ Buffer += sizeof(ULONG_PTR);
+ if (sftype == SF_HAVEIID)
+ {
+ memcpy(&guid, Buffer, sizeof(guid));
+ Buffer += sizeof(guid);
+ }
+
+ wiresab = (SAFEARRAYBOUND *)Buffer;
+ Buffer += sizeof(wiresab[0]) * wiresa->cDims;
+
+ *ppsa = SafeArrayCreateEx(vt, wiresa->cDims, wiresab, NULL);
+ if (!ppsa)
+ RpcRaiseException(E_OUTOFMEMORY);
+
+ /* be careful about which flags we set since they could be a security
+ * risk */
+ (*ppsa)->fFeatures = wiresa->fFeatures & ~(FADF_AUTOSETFLAGS);
+ /* FIXME: there should be a limit on how large wiresa->cbElements can be */
+ (*ppsa)->cbElements = wiresa->cbElements;
+ (*ppsa)->cLocks = LOWORD(wiresa->cLocks);
+
+ hr = SafeArrayAllocData(*ppsa);
+ if (FAILED(hr))
+ RpcRaiseException(hr);
+
+ if ((*(ULONG *)Buffer != cell_count) || (SAFEARRAY_GetCellCount(*ppsa) !=
cell_count))
+ RpcRaiseException(RPC_S_INVALID_BOUND);
+ Buffer += sizeof(ULONG);
+
+ if (ptr)
+ {
+ switch (sftype)
+ {
+ case SF_BSTR:
+ {
+ BSTR* lpBstr;
+
+ for (lpBstr = (BSTR*)(*ppsa)->pvData; cell_count; cell_count--,
lpBstr++)
+ Buffer = BSTR_UserUnmarshal(pFlags, Buffer, lpBstr);
+
+ break;
+ }
+ case SF_DISPATCH:
+ case SF_UNKNOWN:
+ case SF_HAVEIID:
+ FIXME("marshal interfaces\n");
+ break;
+ case SF_VARIANT:
+ {
+ VARIANT* lpVariant;
+
+ for (lpVariant = (VARIANT*)(*ppsa)->pvData; cell_count; cell_count--,
lpVariant++)
+ Buffer = VARIANT_UserUnmarshal(pFlags, Buffer, lpVariant);
+
+ break;
+ }
+ case SF_RECORD:
+ {
+ FIXME("set record info\n");
+
+ break;
+ }
+ case SF_I1:
+ case SF_I2:
+ case SF_I4:
+ case SF_I8:
+ /* Just copy the data over */
+ memcpy((*ppsa)->pvData, Buffer, cell_count * (*ppsa)->cbElements);
+ Buffer += cell_count * (*ppsa)->cbElements;
+ break;
+ default:
+ break;
+ }
+ }
+
+ TRACE("safe array unmarshaled: %p\n", *ppsa);
+
+ return Buffer;
+}
+
+void WINAPI LPSAFEARRAY_UserFree(unsigned long *pFlags, LPSAFEARRAY *ppsa)
+{
+ TRACE("("); dump_user_flags(pFlags); TRACE(", &%p\n",
*ppsa);
+
+ SafeArrayDestroy(*ppsa);
+}
+
/* IDispatch */
/* exactly how Invoke is marshalled is not very clear to me yet,
* but the way I've done it seems to work for me */
Modified: trunk/reactos/dll/win32/oleaut32/varformat.c
URL:
http://svn.reactos.ru/svn/reactos/trunk/reactos/dll/win32/oleaut32/varforma…
==============================================================================
--- trunk/reactos/dll/win32/oleaut32/varformat.c (original)
+++ trunk/reactos/dll/win32/oleaut32/varformat.c Mon Mar 27 20:44:53 2006
@@ -1983,7 +1983,7 @@
#define NUMBER_VTBITS (VTBIT_I1|VTBIT_UI1|VTBIT_I2|VTBIT_UI2| \
VTBIT_I4|VTBIT_UI4|VTBIT_I8|VTBIT_UI8| \
VTBIT_R4|VTBIT_R8|VTBIT_CY|VTBIT_DECIMAL| \
- (1<<VT_BOOL)|(1<<VT_INT)|(1<<VT_UINT))
+ VTBIT_BOOL|VTBIT_INT|VTBIT_UINT)
/**********************************************************************
* VarFormatFromTokens [OLEAUT32.139]
@@ -2006,6 +2006,9 @@
if (!pVarIn || !rgbTok)
return E_INVALIDARG;
+
+ if (V_VT(pVarIn) == VT_NULL)
+ return S_OK;
if (*rgbTok == FMT_TO_STRING || header->type == FMT_TYPE_GENERAL)
{
Modified: trunk/reactos/dll/win32/oleaut32/variant.c
URL:
http://svn.reactos.ru/svn/reactos/trunk/reactos/dll/win32/oleaut32/variant.…
==============================================================================
--- trunk/reactos/dll/win32/oleaut32/variant.c (original)
+++ trunk/reactos/dll/win32/oleaut32/variant.c Mon Mar 27 20:44:53 2006
@@ -2500,199 +2500,231 @@
return S_OK;
}
+/* Wrapper around VariantChangeTypeEx() which permits changing a
+ variant with VT_RESERVED flag set. Needed by VarCmp. */
+static HRESULT _VarChangeTypeExWrap (VARIANTARG* pvargDest,
+ VARIANTARG* pvargSrc, LCID lcid, USHORT wFlags, VARTYPE vt)
+{
+ HRESULT res;
+ VARTYPE flags;
+
+ flags = V_VT(pvargSrc) & ~VT_TYPEMASK;
+ V_VT(pvargSrc) &= ~VT_RESERVED;
+ res = VariantChangeTypeEx(pvargDest,pvargSrc,lcid,wFlags,vt);
+ V_VT(pvargSrc) |= flags;
+
+ return res;
+}
+
/**********************************************************************
* VarCmp [OLEAUT32.176]
*
- * flags can be:
- * NORM_IGNORECASE, NORM_IGNORENONSPACE, NORM_IGNORESYMBOLS
- * NORM_IGNOREWIDTH, NORM_IGNOREKANATYPE, NORM_IGNOREKASHIDA
- *
+ * Compare two variants.
+ *
+ * PARAMS
+ * left [I] First variant
+ * right [I] Second variant
+ * lcid [I] LCID (locale identifier) for the comparison
+ * flags [I] Flags to be used in the comparision:
+ * NORM_IGNORECASE, NORM_IGNORENONSPACE, NORM_IGNORESYMBOLS,
+ * NORM_IGNOREWIDTH, NORM_IGNOREKANATYPE, NORM_IGNOREKASHIDA
+ *
+ * RETURNS
+ * VARCMP_LT: left variant is less than right variant.
+ * VARCMP_EQ: input variants are equal.
+ * VARCMP_LT: left variant is greater than right variant.
+ * VARCMP_NULL: either one of the input variants is NULL.
+ * Failure: An HRESULT error code indicating the error.
+ *
+ * NOTES
+ * Native VarCmp up to and including WinXP dosn't like as input variants
+ * I1, UI2, VT_UI4, UI8 and UINT. INT is accepted only as left variant.
+ *
+ * If both input variants are ERROR then VARCMP_EQ will be returned, else
+ * an ERROR variant will trigger an error.
+ *
+ * Both input variants can have VT_RESERVED flag set which is ignored
+ * unless one and only one of the variants is a BSTR and the other one
+ * is not an EMPTY variant. All four VT_RESERVED combinations have a
+ * different meaning:
+ * - BSTR and other: BSTR is always greater than the other variant.
+ * - BSTR|VT_RESERVED and other: a string comparision is performed.
+ * - BSTR and other|VT_RESERVED: If the BSTR is a number a numeric
+ * comparision will take place else the BSTR is always greater.
+ * - BSTR|VT_RESERVED and other|VT_RESERVED: It seems that the other
+ * variant is ignored and the return value depends only on the sign
+ * of the BSTR if it is a number else the BSTR is always greater. A
+ * positive BSTR is greater, a negative one is smaller than the other
+ * variant.
+ *
+ * SEE
+ * VarBstrCmp for the lcid and flags usage.
*/
HRESULT WINAPI VarCmp(LPVARIANT left, LPVARIANT right, LCID lcid, DWORD flags)
{
- BOOL lOk = TRUE;
- BOOL rOk = TRUE;
- BOOL l_isR = FALSE;
- BOOL r_isR = FALSE;
- LONGLONG lVal = -1;
- LONGLONG rVal = -1;
- VARIANT rv,lv;
- DWORD xmask;
- HRESULT rc;
- double lDouble =0.0,rDouble=0.0;
+ VARTYPE lvt, rvt, vt;
+ VARIANT rv,lv;
+ DWORD xmask;
+ HRESULT rc;
TRACE("(%p->(%s%s),%p->(%s%s),0x%08lx,0x%08lx)\n", left,
debugstr_VT(left),
debugstr_VF(left), right, debugstr_VT(right), debugstr_VF(right), lcid,
flags);
- VariantInit(&lv);VariantInit(&rv);
- V_VT(right) &= ~0x8000; /* hack since we sometime get this flag. */
- V_VT(left) &= ~0x8000; /* hack since we sometime get this flag. */
-
- /* If either are null, then return VARCMP_NULL */
- if ((V_VT(left)&VT_TYPEMASK) == VT_NULL ||
- (V_VT(right)&VT_TYPEMASK) == VT_NULL)
+ lvt = V_VT(left) & VT_TYPEMASK;
+ rvt = V_VT(right) & VT_TYPEMASK;
+ xmask = (1 << lvt) | (1 << rvt);
+
+ /* If we have any flag set except VT_RESERVED bail out.
+ Same for the left input variant type > VT_INT and for the
+ right input variant type > VT_I8. Yes, VT_INT is only supported
+ as left variant. Go figure */
+ if (((V_VT(left) | V_VT(right)) & ~VT_TYPEMASK & ~VT_RESERVED) ||
+ lvt > VT_INT || rvt > VT_I8) {
+ return DISP_E_BADVARTYPE;
+ }
+
+ /* Don't ask me why but native VarCmp cannot handle: VT_I1, VT_UI2, VT_UI4,
+ VT_UINT and VT_UI8. Tested with DCOM98, Win2k, WinXP */
+ if (rvt == VT_INT || xmask & (VTBIT_I1 | VTBIT_UI2 | VTBIT_UI4 | VTBIT_UI8 |
+ VTBIT_DISPATCH | VTBIT_VARIANT | VTBIT_UNKNOWN | VTBIT_15))
+ return DISP_E_TYPEMISMATCH;
+
+ /* If both variants are VT_ERROR return VARCMP_EQ */
+ if (xmask == VTBIT_ERROR)
+ return VARCMP_EQ;
+ else if (xmask & VTBIT_ERROR)
+ return DISP_E_TYPEMISMATCH;
+
+ if (xmask & VTBIT_NULL)
return VARCMP_NULL;
- /* Strings - use VarBstrCmp */
- if ((V_VT(left)&VT_TYPEMASK) == VT_BSTR &&
- (V_VT(right)&VT_TYPEMASK) == VT_BSTR) {
+ VariantInit(&lv);
+ VariantInit(&rv);
+
+ /* Two BSTRs, ignore VT_RESERVED */
+ if (xmask == VTBIT_BSTR)
return VarBstrCmp(V_BSTR(left), V_BSTR(right), lcid, flags);
- }
-
- xmask =
(1<<(V_VT(left)&VT_TYPEMASK))|(1<<(V_VT(right)&VT_TYPEMASK));
- if (xmask & VTBIT_DECIMAL) {
- rc = VariantChangeType(&lv,left,0,VT_DECIMAL);
- if (FAILED(rc)) return rc;
- rc = VariantChangeType(&rv,right,0,VT_DECIMAL);
- if (FAILED(rc)) return rc;
- return VarDecCmp(&V_DECIMAL(&lv), &V_DECIMAL(&rv));
- }
- if (xmask & VTBIT_R8) {
- rc = VariantChangeType(&lv,left,0,VT_R8);
- if (FAILED(rc)) return rc;
- rc = VariantChangeType(&rv,right,0,VT_R8);
- if (FAILED(rc)) return rc;
-
- if (V_R8(&lv) == V_R8(&rv)) return VARCMP_EQ;
- if (V_R8(&lv) < V_R8(&rv)) return VARCMP_LT;
- if (V_R8(&lv) > V_R8(&rv)) return VARCMP_GT;
- return E_FAIL; /* can't get here */
- }
- if (xmask & VTBIT_R4) {
- rc = VariantChangeType(&lv,left,0,VT_R4);
- if (FAILED(rc)) return rc;
- rc = VariantChangeType(&rv,right,0,VT_R4);
- if (FAILED(rc)) return rc;
-
- if (V_R4(&lv) == V_R4(&rv)) return VARCMP_EQ;
- if (V_R4(&lv) < V_R4(&rv)) return VARCMP_LT;
- if (V_R4(&lv) > V_R4(&rv)) return VARCMP_GT;
- return E_FAIL; /* can't get here */
- }
-
- /* Integers - Ideally like to use VarDecCmp, but no Dec support yet
- Use LONGLONG to maximize ranges */
- lOk = TRUE;
- switch (V_VT(left)&VT_TYPEMASK) {
- case VT_I1 : lVal = V_I1(left); break;
- case VT_I2 : lVal = V_I2(left); break;
- case VT_I4 :
- case VT_INT : lVal = V_I4(left); break;
- case VT_UI1 : lVal = V_UI1(left); break;
- case VT_UI2 : lVal = V_UI2(left); break;
- case VT_UI4 :
- case VT_UINT : lVal = V_UI4(left); break;
- case VT_BOOL : lVal = V_BOOL(left); break;
- case VT_EMPTY : lVal = 0; break;
- case VT_R4 : lDouble = V_R4(left); lOk = FALSE; l_isR= TRUE; break;
- case VT_R8 : lDouble = V_R8(left); lOk = FALSE; l_isR= TRUE; break;
- default: lOk = FALSE;
- }
-
- rOk = TRUE;
- switch (V_VT(right)&VT_TYPEMASK) {
- case VT_I1 : rVal = V_I1(right); break;
- case VT_I2 : rVal = V_I2(right); break;
- case VT_I4 :
- case VT_INT : rVal = V_I4(right); break;
- case VT_UI1 : rVal = V_UI1(right); break;
- case VT_UI2 : rVal = V_UI2(right); break;
- case VT_UI4 :
- case VT_UINT : rVal = V_UI4(right); break;
- case VT_BOOL : rVal = V_BOOL(right); break;
- case VT_EMPTY : rVal = 0; break;
- case VT_R4 : rDouble = V_R4(right); rOk = FALSE;r_isR= TRUE; break;
- case VT_R8 : rDouble = V_R8(right); rOk = FALSE;r_isR= TRUE; break;
- default: rOk = FALSE;
- }
-
- if (lOk && rOk) {
- if (lVal < rVal) {
- return VARCMP_LT;
- } else if (lVal > rVal) {
- return VARCMP_GT;
+
+ /* A BSTR and an other variant; we have to take care of VT_RESERVED */
+ if (xmask & VTBIT_BSTR) {
+ VARIANT *bstrv, *nonbv;
+ VARTYPE nonbvt;
+ int swap = 0;
+
+ /* Swap the variants so the BSTR is always on the left */
+ if (lvt == VT_BSTR) {
+ bstrv = left;
+ nonbv = right;
+ nonbvt = rvt;
} else {
- return VARCMP_EQ;
+ swap = 1;
+ bstrv = right;
+ nonbv = left;
+ nonbvt = lvt;
}
- }
- else if (l_isR && r_isR) {
- if (lDouble < rDouble) {
- return VARCMP_LT;
- } else if (lDouble > rDouble) {
- return VARCMP_GT;
- } else {
- return VARCMP_EQ;
+
+ /* BSTR and EMPTY: ignore VT_RESERVED */
+ if (nonbvt == VT_EMPTY)
+ rc = (!V_BSTR(bstrv) || !*V_BSTR(bstrv)) ? VARCMP_EQ : VARCMP_GT;
+ else {
+ VARTYPE breserv = V_VT(bstrv) & ~VT_TYPEMASK;
+ VARTYPE nreserv = V_VT(nonbv) & ~VT_TYPEMASK;
+
+ if (!breserv && !nreserv)
+ /* No VT_RESERVED set ==> BSTR always greater */
+ rc = VARCMP_GT;
+ else if (breserv && !nreserv) {
+ /* BSTR has VT_RESERVED set. Do a string comparision */
+ rc = VariantChangeTypeEx(&rv,nonbv,lcid,0,VT_BSTR);
+ if (FAILED(rc))
+ return rc;
+ rc = VarBstrCmp(V_BSTR(bstrv), V_BSTR(&rv), lcid, flags);
+ } else if (V_BSTR(bstrv) && *V_BSTR(bstrv)) {
+ /* Non NULL nor empty BSTR */
+ /* If the BSTR is not a number the BSTR is greater */
+ rc = _VarChangeTypeExWrap(&lv,bstrv,lcid,0,VT_R8);
+ if (FAILED(rc))
+ rc = VARCMP_GT;
+ else if (breserv && nreserv)
+ /* FIXME: This is strange: with both VT_RESERVED set it
+ looks like the result depends only on the sign of
+ the BSTR number */
+ rc = (V_R8(&lv) >= 0) ? VARCMP_GT : VARCMP_LT;
+ else
+ /* Numeric comparision, will be handled below.
+ VARCMP_NULL used only to break out. */
+ rc = VARCMP_NULL;
+ VariantClear(&lv);
+ VariantClear(&rv);
+ } else
+ /* Empty or NULL BSTR */
+ rc = VARCMP_GT;
}
- }
- else if (lOk && r_isR) {
- if (lVal < rDouble) {
- return VARCMP_LT;
- } else if (lVal > rDouble) {
- return VARCMP_GT;
- } else {
- return VARCMP_EQ;
+ /* Fixup the return code if we swapped left and right */
+ if (swap) {
+ if (rc == VARCMP_GT)
+ rc = VARCMP_LT;
+ else if (rc == VARCMP_LT)
+ rc = VARCMP_GT;
}
- }
- else if (l_isR && rOk) {
- if (lDouble < rVal) {
- return VARCMP_LT;
- } else if (lDouble > rVal) {
- return VARCMP_GT;
- } else {
- return VARCMP_EQ;
- }
- }
- if ((V_VT(left)&VT_TYPEMASK) == VT_BSTR ) {
- if(((V_VT(right)&VT_TYPEMASK) == VT_EMPTY ) && !(V_BSTR(left))) {
- return VARCMP_EQ;
- } else {
- return VARCMP_GT;
- }
- }
- if ((V_VT(right)&VT_TYPEMASK) == VT_BSTR ) {
- if(((V_VT(left)&VT_TYPEMASK) == VT_EMPTY ) && !(V_BSTR(right))) {
- return VARCMP_EQ;
- } else {
- return VARCMP_LT;
- }
- }
- /* Dates */
- if ((V_VT(left)&VT_TYPEMASK) == VT_DATE &&
- (V_VT(right)&VT_TYPEMASK) == VT_DATE) {
-
- if (floor(V_DATE(left)) == floor(V_DATE(right))) {
- /* Due to floating point rounding errors, calculate varDate in whole numbers)
*/
- double wholePart = 0.0;
- double leftR;
- double rightR;
-
- /* Get the fraction * 24*60*60 to make it into whole seconds */
- wholePart = (double) floor( V_DATE(left) );
- if (wholePart == 0) wholePart = 1;
- leftR = floor(fmod( V_DATE(left), wholePart ) * (24*60*60));
-
- wholePart = (double) floor( V_DATE(right) );
- if (wholePart == 0) wholePart = 1;
- rightR = floor(fmod( V_DATE(right), wholePart ) * (24*60*60));
-
- if (leftR < rightR) {
- return VARCMP_LT;
- } else if (leftR > rightR) {
- return VARCMP_GT;
- } else {
- return VARCMP_EQ;
- }
-
- } else if (V_DATE(left) < V_DATE(right)) {
- return VARCMP_LT;
- } else if (V_DATE(left) > V_DATE(right)) {
- return VARCMP_GT;
- }
- }
- else if((V_VT(right)&VT_TYPEMASK) == VT_EMPTY)
- return VARCMP_GT;
- FIXME("VarCmp partial implementation, doesn't support %s /
%s\n",wine_vtypes[V_VT(left)], wine_vtypes[V_VT(right)]);
- return E_FAIL;
+ if (rc != VARCMP_NULL)
+ return rc;
+ }
+
+ if (xmask & VTBIT_DECIMAL)
+ vt = VT_DECIMAL;
+ else if (xmask & VTBIT_BSTR)
+ vt = VT_R8;
+ else if (xmask & VTBIT_R4)
+ vt = VT_R4;
+ else if (xmask & (VTBIT_R8 | VTBIT_DATE))
+ vt = VT_R8;
+ else if (xmask & VTBIT_CY)
+ vt = VT_CY;
+ else
+ /* default to I8 */
+ vt = VT_I8;
+
+ /* Coerce the variants */
+ rc = _VarChangeTypeExWrap(&lv,left,lcid,0,vt);
+ if (rc == DISP_E_OVERFLOW && vt != VT_R8) {
+ /* Overflow, change to R8 */
+ vt = VT_R8;
+ rc = _VarChangeTypeExWrap(&lv,left,lcid,0,vt);
+ }
+ if (FAILED(rc))
+ return rc;
+ rc = _VarChangeTypeExWrap(&rv,right,lcid,0,vt);
+ if (rc == DISP_E_OVERFLOW && vt != VT_R8) {
+ /* Overflow, change to R8 */
+ vt = VT_R8;
+ rc = _VarChangeTypeExWrap(&lv,left,lcid,0,vt);
+ if (FAILED(rc))
+ return rc;
+ rc = _VarChangeTypeExWrap(&rv,right,lcid,0,vt);
+ }
+ if (FAILED(rc))
+ return rc;
+
+#define _VARCMP(a,b) \
+ (((a) == (b)) ? VARCMP_EQ : (((a) < (b)) ? VARCMP_LT : VARCMP_GT))
+
+ switch (vt) {
+ case VT_CY:
+ return VarCyCmp(V_CY(&lv), V_CY(&rv));
+ case VT_DECIMAL:
+ return VarDecCmp(&V_DECIMAL(&lv), &V_DECIMAL(&rv));
+ case VT_I8:
+ return _VARCMP(V_I8(&lv), V_I8(&rv));
+ case VT_R4:
+ return _VARCMP(V_R4(&lv), V_R4(&rv));
+ case VT_R8:
+ return _VARCMP(V_R8(&lv), V_R8(&rv));
+ default:
+ /* We should never get here */
+ return E_FAIL;
+ }
+#undef _VARCMP
}
/**********************************************************************
@@ -2920,7 +2952,6 @@
/* Do the math */
hres = S_OK;
- V_VT(&tv) = tvt;
V_VT(result) = resvt;
switch (tvt) {
case VT_DECIMAL:
@@ -2941,10 +2972,13 @@
V_VT(result) = VT_R8;
V_R8(result) = r8res;
goto end;
- } else
+ } else {
+ V_VT(&tv) = tvt;
V_I8(&tv) = V_I8(&lv) + V_I8(&rv);
+ }
break;
case VT_R8:
+ V_VT(&tv) = tvt;
/* FIXME: overflow detection */
V_R8(&tv) = V_R8(&lv) + V_R8(&rv);
break;
@@ -3184,7 +3218,7 @@
found = TRUE;
resvt = VT_DECIMAL;
}
- if (!found && (((1<<lvt) | (1<<rvt)) &
(VTBIT_I1|VTBIT_I2|VTBIT_UI1|VTBIT_UI2|VTBIT_I4|VTBIT_UI4|(1<<VT_INT)|(1<<VT_UINT))))
{
+ if (!found && (((1<<lvt) | (1<<rvt)) &
(VTBIT_I1|VTBIT_I2|VTBIT_UI1|VTBIT_UI2|VTBIT_I4|VTBIT_UI4|VTBIT_INT|VTBIT_UINT))) {
found = TRUE;
resvt = VT_I4;
}
@@ -3253,7 +3287,7 @@
lvt = V_VT(left)&VT_TYPEMASK;
rvt = V_VT(right)&VT_TYPEMASK;
found = FALSE;resvt = VT_VOID;
- if (((1<<lvt) | (1<<rvt)) &
((1<<VT_DATE)|(1<<VT_R4)|(1<<VT_R8))) {
+ if (((1<<lvt) | (1<<rvt)) & (VTBIT_DATE|VTBIT_R4|VTBIT_R8)) {
found = TRUE;
resvt = VT_R8;
}
@@ -3261,7 +3295,7 @@
found = TRUE;
resvt = VT_DECIMAL;
}
- if (!found && (((1<<lvt) | (1<<rvt)) &
(VTBIT_I1|VTBIT_I2|VTBIT_UI1|VTBIT_UI2|VTBIT_I4|VTBIT_UI4|(1<<VT_INT)|(1<<VT_UINT))))
{
+ if (!found && (((1<<lvt) | (1<<rvt)) &
(VTBIT_I1|VTBIT_I2|VTBIT_UI1|VTBIT_UI2|VTBIT_I4|VTBIT_UI4|VTBIT_INT|VTBIT_UINT))) {
found = TRUE;
resvt = VT_I4;
}
Modified: trunk/reactos/dll/win32/oleaut32/variant.h
URL:
http://svn.reactos.ru/svn/reactos/trunk/reactos/dll/win32/oleaut32/variant.…
==============================================================================
--- trunk/reactos/dll/win32/oleaut32/variant.h (original)
+++ trunk/reactos/dll/win32/oleaut32/variant.h Mon Mar 27 20:44:53 2006
@@ -33,6 +33,20 @@
/* Get the extra flags from a variant pointer */
#define V_EXTRA_TYPE(v) (V_VT((v)) & VT_EXTRA_TYPE)
+
+/* Missing in Windows but useful VTBIT_* defines */
+#define VTBIT_BOOL (1 << VT_BSTR)
+#define VTBIT_BSTR (1 << VT_BSTR)
+#define VTBIT_DATE (1 << VT_DATE)
+#define VTBIT_DISPATCH (1 << VT_DISPATCH)
+#define VTBIT_EMPTY (1 << VT_EMPTY)
+#define VTBIT_ERROR (1 << VT_ERROR)
+#define VTBIT_INT (1 << VT_INT)
+#define VTBIT_NULL (1 << VT_NULL)
+#define VTBIT_UINT (1 << VT_UINT)
+#define VTBIT_UNKNOWN (1 << VT_UNKNOWN)
+#define VTBIT_VARIANT (1 << VT_VARIANT)
+#define VTBIT_15 (1 << 15) /* no variant type with this number */
extern const char* wine_vtypes[];
#define debugstr_vt(v) (((v)&VT_TYPEMASK) <= VT_CLSID ?
wine_vtypes[((v)&VT_TYPEMASK)] : \
Modified: trunk/reactos/dll/win32/oleaut32/vartype.c
URL:
http://svn.reactos.ru/svn/reactos/trunk/reactos/dll/win32/oleaut32/vartype.…
==============================================================================
--- trunk/reactos/dll/win32/oleaut32/vartype.c (original)
+++ trunk/reactos/dll/win32/oleaut32/vartype.c Mon Mar 27 20:44:53 2006
@@ -110,7 +110,8 @@
}
/* Coerce VT_DISPATCH to another type */
-static HRESULT VARIANT_FromDisp(IDispatch* pdispIn, LCID lcid, void* pOut, VARTYPE vt)
+static HRESULT VARIANT_FromDisp(IDispatch* pdispIn, LCID lcid, void* pOut,
+ VARTYPE vt, DWORD dwFlags)
{
static const DISPPARAMS emptyParams = { NULL, NULL, 0, 0 };
VARIANTARG srcVar, dstVar;
@@ -127,7 +128,7 @@
{
/* Convert the property to the requested type */
V_VT(&dstVar) = VT_EMPTY;
- hRet = VariantChangeTypeEx(&dstVar, &srcVar, lcid, 0, vt);
+ hRet = VariantChangeTypeEx(&dstVar, &srcVar, lcid, dwFlags, vt);
VariantClear(&srcVar);
if (SUCCEEDED(hRet))
@@ -448,7 +449,7 @@
*/
HRESULT WINAPI VarI1FromDisp(IDispatch* pdispIn, LCID lcid, signed char* pcOut)
{
- return VARIANT_FromDisp(pdispIn, lcid, pcOut, VT_I1);
+ return VARIANT_FromDisp(pdispIn, lcid, pcOut, VT_I1, 0);
}
/************************************************************************
@@ -741,7 +742,7 @@
*/
HRESULT WINAPI VarUI1FromDisp(IDispatch* pdispIn, LCID lcid, BYTE* pbOut)
{
- return VARIANT_FromDisp(pdispIn, lcid, pbOut, VT_UI1);
+ return VARIANT_FromDisp(pdispIn, lcid, pbOut, VT_UI1, 0);
}
/************************************************************************
@@ -1042,7 +1043,7 @@
*/
HRESULT WINAPI VarI2FromDisp(IDispatch* pdispIn, LCID lcid, SHORT* psOut)
{
- return VARIANT_FromDisp(pdispIn, lcid, psOut, VT_I2);
+ return VARIANT_FromDisp(pdispIn, lcid, psOut, VT_I2, 0);
}
/************************************************************************
@@ -1356,7 +1357,7 @@
*/
HRESULT WINAPI VarUI2FromDisp(IDispatch* pdispIn, LCID lcid, USHORT* pusOut)
{
- return VARIANT_FromDisp(pdispIn, lcid, pusOut, VT_UI2);
+ return VARIANT_FromDisp(pdispIn, lcid, pusOut, VT_UI2, 0);
}
/************************************************************************
@@ -1632,7 +1633,7 @@
*/
HRESULT WINAPI VarI4FromDisp(IDispatch* pdispIn, LCID lcid, LONG *piOut)
{
- return VARIANT_FromDisp(pdispIn, lcid, piOut, VT_I4);
+ return VARIANT_FromDisp(pdispIn, lcid, piOut, VT_I4, 0);
}
/************************************************************************
@@ -1941,7 +1942,7 @@
*/
HRESULT WINAPI VarUI4FromDisp(IDispatch* pdispIn, LCID lcid, ULONG *pulOut)
{
- return VARIANT_FromDisp(pdispIn, lcid, pulOut, VT_UI4);
+ return VARIANT_FromDisp(pdispIn, lcid, pulOut, VT_UI4, 0);
}
/************************************************************************
@@ -2248,7 +2249,7 @@
*/
HRESULT WINAPI VarI8FromDisp(IDispatch* pdispIn, LCID lcid, LONG64* pi64Out)
{
- return VARIANT_FromDisp(pdispIn, lcid, pi64Out, VT_I8);
+ return VARIANT_FromDisp(pdispIn, lcid, pi64Out, VT_I8, 0);
}
/************************************************************************
@@ -2576,7 +2577,7 @@
*/
HRESULT WINAPI VarUI8FromDisp(IDispatch* pdispIn, LCID lcid, ULONG64* pui64Out)
{
- return VARIANT_FromDisp(pdispIn, lcid, pui64Out, VT_UI8);
+ return VARIANT_FromDisp(pdispIn, lcid, pui64Out, VT_UI8, 0);
}
/************************************************************************
@@ -2851,7 +2852,7 @@
*/
HRESULT WINAPI VarR4FromDisp(IDispatch* pdispIn, LCID lcid, float *pFltOut)
{
- return VARIANT_FromDisp(pdispIn, lcid, pFltOut, VT_R4);
+ return VARIANT_FromDisp(pdispIn, lcid, pFltOut, VT_R4, 0);
}
/************************************************************************
@@ -3172,7 +3173,7 @@
*/
HRESULT WINAPI VarR8FromDisp(IDispatch* pdispIn, LCID lcid, double *pDblOut)
{
- return VARIANT_FromDisp(pdispIn, lcid, pDblOut, VT_R8);
+ return VARIANT_FromDisp(pdispIn, lcid, pDblOut, VT_R8, 0);
}
/************************************************************************
@@ -3594,7 +3595,7 @@
*/
HRESULT WINAPI VarCyFromDisp(IDispatch* pdispIn, LCID lcid, CY* pCyOut)
{
- return VARIANT_FromDisp(pdispIn, lcid, pCyOut, VT_CY);
+ return VARIANT_FromDisp(pdispIn, lcid, pCyOut, VT_CY, 0);
}
/************************************************************************
@@ -4265,7 +4266,7 @@
*/
HRESULT WINAPI VarDecFromDisp(IDispatch* pdispIn, LCID lcid, DECIMAL* pDecOut)
{
- return VARIANT_FromDisp(pdispIn, lcid, pDecOut, VT_DECIMAL);
+ return VARIANT_FromDisp(pdispIn, lcid, pDecOut, VT_DECIMAL, 0);
}
/************************************************************************
@@ -5806,7 +5807,7 @@
*/
HRESULT WINAPI VarBoolFromDisp(IDispatch* pdispIn, LCID lcid, VARIANT_BOOL *pBoolOut)
{
- return VARIANT_FromDisp(pdispIn, lcid, pBoolOut, VT_BOOL);
+ return VARIANT_FromDisp(pdispIn, lcid, pBoolOut, VT_BOOL, 0);
}
/************************************************************************
@@ -6544,6 +6545,27 @@
return VARIANT_BstrFromUInt(ullIn, lcid, dwFlags, pbstrOut);
}
+/************************************************************************
+ * VarBstrFromDisp (OLEAUT32.115)
+ *
+ * Convert a VT_DISPATCH to a BSTR.
+ *
+ * PARAMS
+ * pdispIn [I] Source
+ * lcid [I] LCID for conversion
+ * dwFlags [I] Flags controlling the conversion (VAR_ flags from "oleauto.h")
+ * pbstrOut [O] Destination
+ *
+ * RETURNS
+ * Success: S_OK.
+ * Failure: E_INVALIDARG, if the source value is invalid
+ * DISP_E_TYPEMISMATCH, if the type cannot be converted
+ */
+HRESULT WINAPI VarBstrFromDisp(IDispatch* pdispIn, LCID lcid, ULONG dwFlags, BSTR*
pbstrOut)
+{
+ return VARIANT_FromDisp(pdispIn, lcid, pbstrOut, VT_BSTR, dwFlags);
+}
+
/**********************************************************************
* VarBstrCat (OLEAUT32.313)
*
@@ -6727,7 +6749,7 @@
*/
HRESULT WINAPI VarDateFromDisp(IDispatch* pdispIn, LCID lcid, DATE* pdateOut)
{
- return VARIANT_FromDisp(pdispIn, lcid, pdateOut, VT_DATE);
+ return VARIANT_FromDisp(pdispIn, lcid, pdateOut, VT_DATE, 0);
}
/******************************************************************************
Modified: trunk/reactos/include/oaidl.h
URL:
http://svn.reactos.ru/svn/reactos/trunk/reactos/include/oaidl.h?rev=21399&a…
==============================================================================
--- trunk/reactos/include/oaidl.h (original)
+++ trunk/reactos/include/oaidl.h Mon Mar 27 20:44:53 2006
@@ -143,7 +143,9 @@
SF_BSTR=VT_BSTR,
SF_UNKNOWN=VT_UNKNOWN,
SF_DISPATCH=VT_DISPATCH,
- SF_VARIANT=VT_VARIANT
+ SF_VARIANT=VT_VARIANT,
+ SF_RECORD=VT_RECORD,
+ SF_HAVEIID=VT_UNKNOWN|VT_RESERVED,
}SF_TYPE;
typedef struct _wireBRECORD {
ULONG fFlags;
Modified: trunk/reactos/include/ocidl.h
URL:
http://svn.reactos.ru/svn/reactos/trunk/reactos/include/ocidl.h?rev=21399&a…
==============================================================================
--- trunk/reactos/include/ocidl.h (original)
+++ trunk/reactos/include/ocidl.h Mon Mar 27 20:44:53 2006
@@ -20,6 +20,7 @@
typedef interface IPropertyPageSite *LPPROPERTYPAGESITE;
typedef interface IFont *LPFONT;
typedef interface IFontDisp *LPFONTDISP;
+typedef interface IFontEventsDisp *LPFONTEVENTS;
typedef interface IOleUndoManager *LPOLEUNDOMANAGER;
typedef interface IQuickActivate *LPQUICKACTIVATE;
typedef interface IObjectWithSite *LPOBJECTWITHSITE;
@@ -638,6 +639,21 @@
};
#undef INTERFACE
+EXTERN_C const IID IID_IFontEventsDisp;
+#define INTERFACE IFontEventsDisp
+DECLARE_INTERFACE_(IFontEventsDisp,IDispatch)
+{
+ STDMETHOD(QueryInterface)(THIS_ REFIID,PVOID*) PURE;
+ STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+ STDMETHOD_(ULONG,Release)(THIS) PURE;
+ STDMETHOD(GetTypeInfoCount)(THIS_ UINT*) PURE;
+ STDMETHOD(GetTypeInfo)(THIS_ UINT,LCID,LPTYPEINFO*) PURE;
+ STDMETHOD(GetIDsOfNames)(THIS_ REFIID,LPOLESTR*,UINT,LCID,DISPID*) PURE;
+ STDMETHOD(Invoke)(THIS_ DISPID,REFIID,LCID,WORD,DISPPARAMS*,VARIANT*,EXCEPINFO*,UINT*)
PURE;
+ /*[id(0x9)]*/STDMETHOD(FontChanged)(THIS_ BSTR) PURE;
+};
+#undef INTERFACE
+
EXTERN_C const IID IID_IPicture;
#define INTERFACE IPicture
DECLARE_INTERFACE_(IPicture,IUnknown)
Modified: trunk/reactos/include/olectl.h
URL:
http://svn.reactos.ru/svn/reactos/trunk/reactos/include/olectl.h?rev=21399&…
==============================================================================
--- trunk/reactos/include/olectl.h (original)
+++ trunk/reactos/include/olectl.h Mon Mar 27 20:44:53 2006
@@ -218,6 +218,9 @@
#define DISPID_FONT_STRIKE 6
#define DISPID_FONT_WEIGHT 7
#define DISPID_FONT_CHARSET 8
+#define DISPID_FONT_CHANGED 9
+
+/* IPicture */
#define DISPID_PICT_HANDLE 0
#define DISPID_PICT_HPAL 2
#define DISPID_PICT_TYPE 3
Modified: trunk/reactos/include/olectlid.h
URL:
http://svn.reactos.ru/svn/reactos/trunk/reactos/include/olectlid.h?rev=2139…
==============================================================================
--- trunk/reactos/include/olectlid.h (original)
+++ trunk/reactos/include/olectlid.h Mon Mar 27 20:44:53 2006
@@ -40,6 +40,7 @@
extern const GUID CLSID_StdPicture;
extern const GUID IID_IFont;
extern const GUID IID_IFontDisp;
+extern const GUID IID_IFontEventsDisp;
extern const GUID IID_IPicture;
extern const GUID IID_IPictureDisp;
extern const GUID GUID_HIMETRIC;