Sync to Wine-20050419:
Daniel Remenak <dtremenak(a)gmail.com>
- Implemented VarIdiv.
- Return DISP_E_DIVBYZERO instead of crashing when asked to divide a
variant by zero.
- Remove unused variable in _copy_arg.
Marcus Meissner <meissner(a)suse.de>
- Serialize NULL pointer interfaces correctly.
- Fixed VT_BSTR|VT_BYREF marshalling.
- Added VT_I4|VT_BYREF marshalling.
- Fixed ppvObject serializer (deref twice instead of once).
- Actually pass back return value of remote call in type marshaller.
- Format VT_UI1, VT_I1, VT_UI2, VT_I2 correctly.
- Added IDispatch::GetIDsOfNames() special case serializing.
- Handle VT_PTR / NULL marshalling correctly.
Mike Hearn <mike(a)navi.cx>
- Fix BSTR tracing in the typelib marshaller.
- Fix PARAMFLAG_FOUT typo in the tmarshaller.
Mike Hearn <mh(a)codeweavers.com>
Robert Shearman <rob(a)codeweavers.com>
- Implement VT_BYREF | VT_BSTR marshalling.
- Add more integer types for marshaling and unmarshaling.
- Implement VT_BYREF | VT_BSTR unmarshaling.
- Don't allocate memory for TKIND_DISPATCH/TKIND_INTERFACE
unmarshaling as it will be lost in the success case and interferes
with the failure case.
Robert Shearman <rob(a)codeweavers.com>
- Add outer unknown support for typelib marshaler.
Jakob Eriksson <jakov(a)vmlinux.org>
- Get rid of HeapAlloc casts.
Francois Gouget <fgouget(a)free.fr>
- Assorted spelling fixes.
Alex Villacis Lasso <a_villacis(a)palosanto.com>
- Fix leftover negative sign in height parameter for transparent
bitmap.
- Properly announce whether bitmap is transparent in get_Attributes.
- GIF transparency is now palette-index based, instead of RGB based.
- Keep original bitmap and XOR mask separate, so that get_Handle
returns original bitmap.
- Initialize [orig|himetric][Width|Height] for PICTYPE_ICON case.
- Fix failure to notice the use of a GIF palette index greater or equal
to 128 for transparency.
- After Float->string conversion via sprintfW(), VarDecFromR[4|8] is
forced to use US locale for string->Decimal conversion, to agree with
sprintfW().
Modified: trunk/reactos/lib/oleaut32/oleaut.c
Modified: trunk/reactos/lib/oleaut32/oleaut32.spec
Modified: trunk/reactos/lib/oleaut32/olepicture.c
Modified: trunk/reactos/lib/oleaut32/safearray.c
Modified: trunk/reactos/lib/oleaut32/tmarshal.c
Modified: trunk/reactos/lib/oleaut32/typelib.c
Modified: trunk/reactos/lib/oleaut32/typelib.h
Modified: trunk/reactos/lib/oleaut32/variant.c
Modified: trunk/reactos/lib/oleaut32/vartype.c
_____
Modified: trunk/reactos/lib/oleaut32/oleaut.c
--- trunk/reactos/lib/oleaut32/oleaut.c 2005-05-05 18:16:09 UTC (rev
15010)
+++ trunk/reactos/lib/oleaut32/oleaut.c 2005-05-05 18:29:41 UTC (rev
15011)
@@ -235,9 +235,8 @@
* buffer for the character count and an extra character at the
* end for the NULL.
*/
- newBuffer = (DWORD*)HeapAlloc(GetProcessHeap(),
- 0,
- bufferSize + sizeof(WCHAR) +
sizeof(DWORD));
+ newBuffer = HeapAlloc(GetProcessHeap(), 0,
+ bufferSize + sizeof(WCHAR) + sizeof(DWORD));
/*
* If the memory allocation failed, return a null pointer.
@@ -350,9 +349,8 @@
* buffer for the character count and an extra character at the
* end for the NULL.
*/
- newBuffer = (DWORD*)HeapAlloc(GetProcessHeap(),
- 0,
- len + sizeof(WCHAR) + sizeof(DWORD));
+ newBuffer = HeapAlloc(GetProcessHeap(), 0,
+ len + sizeof(WCHAR) + sizeof(DWORD));
/*
* If the memory allocation failed, return a null pointer.
_____
Modified: trunk/reactos/lib/oleaut32/oleaut32.spec
--- trunk/reactos/lib/oleaut32/oleaut32.spec 2005-05-05 18:16:09 UTC
(rev 15010)
+++ trunk/reactos/lib/oleaut32/oleaut32.spec 2005-05-05 18:29:41 UTC
(rev 15011)
@@ -148,7 +148,7 @@
149 stdcall SysStringByteLen(ptr)
150 stdcall SysAllocStringByteLen(ptr long)
152 stdcall VarEqv(ptr ptr ptr)
-153 stub VarIdiv # stdcall (ptr ptr ptr)
+153 stdcall VarIdiv(ptr ptr ptr)
154 stub VarImp # stdcall (ptr ptr ptr)
155 stdcall VarMod(ptr ptr ptr)
156 stdcall VarMul(ptr ptr ptr)
_____
Modified: trunk/reactos/lib/oleaut32/olepicture.c
--- trunk/reactos/lib/oleaut32/olepicture.c 2005-05-05 18:16:09 UTC
(rev 15010)
+++ trunk/reactos/lib/oleaut32/olepicture.c 2005-05-05 18:29:41 UTC
(rev 15011)
@@ -185,6 +185,36 @@
DeleteDC(hdcRef);
}
+static void OLEPictureImpl_SetIcon(OLEPictureImpl * This)
+{
+ ICONINFO infoIcon;
+
+ TRACE("icon handle %p\n", This->desc.u.icon.hicon);
+ if (GetIconInfo(This->desc.u.icon.hicon, &infoIcon)) {
+ HDC hdcRef;
+ BITMAP bm;
+
+ TRACE("bitmap handle for icon is %p\n", infoIcon.hbmColor);
+ if(GetObjectA(infoIcon.hbmColor ? infoIcon.hbmColor :
infoIcon.hbmMask, sizeof(bm), &bm) != sizeof(bm)) {
+ ERR("GetObject fails on icon bitmap\n");
+ return;
+ }
+
+ This->origWidth = bm.bmWidth;
+ This->origHeight = infoIcon.hbmColor ? bm.bmHeight :
bm.bmHeight / 2;
+ /* see comment on HIMETRIC on OLEPictureImpl_SetBitmap() */
+ hdcRef = GetDC(0);
+ This->himetricWidth = (This->origWidth
*2540)/GetDeviceCaps(hdcRef, LOGPIXELSX);
+ This->himetricHeight= (This->origHeight
*2540)/GetDeviceCaps(hdcRef, LOGPIXELSY);
+ ReleaseDC(0, hdcRef);
+
+ DeleteObject(infoIcon.hbmMask);
+ if (infoIcon.hbmColor) DeleteObject(infoIcon.hbmColor);
+ } else {
+ ERR("GetIconInfo() fails on icon %p\n",
This->desc.u.icon.hicon);
+ }
+}
+
/***********************************************************************
*
* OLEPictureImpl_Construct
*
@@ -260,6 +290,8 @@
break;
case PICTYPE_ICON:
+ OLEPictureImpl_SetIcon(newObject);
+ break;
case PICTYPE_ENHMETAFILE:
default:
FIXME("Unsupported type %d\n", pictDesc->picType);
@@ -1071,7 +1103,7 @@
eb = si->ExtensionBlocks + i;
if (eb->Function == 0xF9 && eb->ByteCount == 4) {
if ((eb->Bytes[0] & 1) == 1) {
- transparent = eb->Bytes[3];
+ transparent = (unsigned char)eb->Bytes[3];
}
}
}
@@ -1145,7 +1177,7 @@
This->hbmMask = CreateBitmap(bmi->bmiHeader.biWidth,
bmi->bmiHeader.biHeight, 1, 1, NULL);
- hOldbitmap = SelectObject(hdc,This->desc.u.bmp.hbitmap);
+ hOldbitmap = SelectObject(hdc,This->desc.u.bmp.hbitmap);
hOldbitmapmask = SelectObject(hdcMask, This->hbmMask);
SetBkColor(hdc, This->rgbTrans);
BitBlt(hdcMask, 0, 0, bmi->bmiHeader.biWidth,
bmi->bmiHeader.biHeight, hdc, 0, 0, SRCCOPY);
@@ -1501,7 +1533,7 @@
BITMAPFILEHEADER * pFileHeader;
BITMAPINFO * pInfoHeader;
- pInfoBitmap = (BITMAPINFO *)HeapAlloc(GetProcessHeap(),
HEAP_ZERO_MEMORY,
+ pInfoBitmap = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD));
/* Find out bitmap size and padded length */
@@ -1511,8 +1543,7 @@
/* Fetch bitmap palette & pixel data */
- pPixelData = (unsigned char *)HeapAlloc(GetProcessHeap(),
HEAP_ZERO_MEMORY,
- pInfoBitmap->bmiHeader.biSizeImage);
+ 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 */
@@ -1530,7 +1561,7 @@
sizeof(BITMAPINFOHEADER) +
iNumPaletteEntries * sizeof(RGBQUAD) +
pInfoBitmap->bmiHeader.biSizeImage;
- *ppBuffer = (void *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
*pLength);
+ *ppBuffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
*pLength);
/* Fill the BITMAPFILEHEADER */
pFileHeader = (BITMAPFILEHEADER *)(*ppBuffer);
@@ -1569,7 +1600,7 @@
unsigned char * pIconData = NULL;
unsigned int iDataSize = 0;
- pInfoBitmap = (BITMAPINFO *)HeapAlloc(GetProcessHeap(),
HEAP_ZERO_MEMORY, sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD));
+ pInfoBitmap = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD));
/* Find out icon size */
hDC = GetDC(0);
@@ -1603,7 +1634,7 @@
*/
/* Let's start with one CURSORICONFILEDIR and
one CURSORICONFILEDIRENTRY */
iDataSize += 3 * sizeof(WORD) +
sizeof(CURSORICONFILEDIRENTRY) + sizeof(BITMAPINFOHEADER);
- pIconData = (unsigned char
*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, iDataSize);
+ pIconData = HeapAlloc(GetProcessHeap(),
HEAP_ZERO_MEMORY, iDataSize);
/* Fill out the CURSORICONFILEDIR */
pIconDir = (CURSORICONFILEDIR *)pIconData;
@@ -1651,7 +1682,7 @@
iDataSize += pIconBitmapHeader->biHeight *
iLengthScanLineMask;
pIconBitmapHeader->biSizeImage +=
pIconBitmapHeader->biHeight * iLengthScanLineMask;
pIconBitmapHeader->biHeight *= 2;
- pIconData = (unsigned char
*)HeapReAlloc(GetProcessHeap(), 0, pIconData, iDataSize);
+ 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));
_____
Modified: trunk/reactos/lib/oleaut32/safearray.c
--- trunk/reactos/lib/oleaut32/safearray.c 2005-05-05 18:16:09 UTC
(rev 15010)
+++ trunk/reactos/lib/oleaut32/safearray.c 2005-05-05 18:29:41 UTC
(rev 15011)
@@ -647,7 +647,7 @@
/***********************************************************************
*
* SafeArrayCreateVector (OLEAUT32.411)
*
- * Create a one dimensional, contigous SafeArray.
+ * Create a one dimensional, contiguous SafeArray.
*
* PARAMS
* vt [I] Type to store in the safe array
@@ -674,7 +674,7 @@
/***********************************************************************
*
* SafeArrayCreateVectorEx (OLEAUT32.411)
*
- * Create a one dimensional, contigous SafeArray.
+ * Create a one dimensional, contiguous SafeArray.
*
* PARAMS
* vt [I] Type to store in the safe array
_____
Modified: trunk/reactos/lib/oleaut32/tmarshal.c
--- trunk/reactos/lib/oleaut32/tmarshal.c 2005-05-05 18:16:09 UTC
(rev 15010)
+++ trunk/reactos/lib/oleaut32/tmarshal.c 2005-05-05 18:29:41 UTC
(rev 15011)
@@ -1,7 +1,7 @@
/*
* TYPELIB Marshaler
*
- * Copyright 2002 Marcus Meissner
+ * Copyright 2002,2005 Marcus Meissner
*
* The olerelay debug channel allows you to see calls marshalled by
* the typelib marshaller. It is not a generic COM relaying system.
@@ -48,6 +48,8 @@
static const WCHAR riidW[5] = {'r','i','i','d',0};
static const WCHAR pdispparamsW[] =
{'p','d','i','s','p','p','a','r','a','m','s',0};
static const WCHAR ppvObjectW[] =
{'p','p','v','O','b','j','e','c','t',0};
+static const WCHAR IDispatchW[] = {
'I','D','i','s','p','a','t','c','h',0};
+static const WCHAR GetIDsOfNamesW[] = {
'G','e','t','I','D','s','O','f','N','a','m','e','s',0};
WINE_DEFAULT_DEBUG_CHANNEL(ole);
WINE_DECLARE_DEBUG_CHANNEL(olerelay);
@@ -167,12 +169,19 @@
DWORD xsize;
HRESULT hres;
- hres = E_FAIL;
if (!pUnk) {
+ /* this is valid, if for instance we serialize
+ * a VT_DISPATCH with NULL ptr which apparently
+ * can happen. S_OK to make sure we continue
+ * serializing.
+ */
ERR("pUnk is NULL?\n");
- goto fail;
+ xsize = 0;
+ return xbuf_add(buf,(LPBYTE)&xsize,sizeof(xsize));
}
+ hres = E_FAIL;
+
TRACE("...%s...\n",debugstr_guid(riid));
hres = IUnknown_QueryInterface(pUnk,riid,(LPVOID*)&newiface);
if (hres) {
@@ -355,6 +364,7 @@
IRpcChannelBuffer* chanbuf;
IID iid;
CRITICAL_SECTION crit;
+ IUnknown *outerunknown;
} TMProxyImpl;
static HRESULT WINAPI
@@ -499,17 +509,36 @@
return S_OK;
case VT_BOOL:
case VT_ERROR:
- case VT_UI4:
case VT_UINT:
case VT_I4:
case VT_R4:
+ case VT_UI4:
+ hres = S_OK;
+ if (debugout) TRACE_(olerelay)("%lx",*arg);
+ if (writeit)
+ hres = xbuf_add(buf,(LPBYTE)arg,sizeof(DWORD));
+ return hres;
+ case VT_I2:
case VT_UI2:
+ hres = S_OK;
+ if (debugout) TRACE_(olerelay)("%04lx",*arg & 0xffff);
+ if (writeit)
+ hres = xbuf_add(buf,(LPBYTE)arg,sizeof(DWORD));
+ return hres;
+ case VT_I1:
case VT_UI1:
hres = S_OK;
- if (debugout) TRACE_(olerelay)("%lx",*arg);
+ if (debugout) TRACE_(olerelay)("%02lx",*arg & 0xff);
if (writeit)
hres = xbuf_add(buf,(LPBYTE)arg,sizeof(DWORD));
return hres;
+ case VT_I4|VT_BYREF:
+ hres = S_OK;
+ if (debugout) TRACE_(olerelay)("&0x%lx",*arg);
+ if (writeit)
+ hres = xbuf_add(buf,(LPBYTE)(DWORD*)*arg,sizeof(DWORD));
+ /* do not dealloc at this time */
+ return hres;
case VT_VARIANT: {
TYPEDESC tdesc2;
VARIANT *vt = (VARIANT*)arg;
@@ -526,10 +555,34 @@
if (debugout) TRACE_(olerelay)(")");
return hres;
}
+ case VT_BSTR|VT_BYREF: {
+ if (debugout) TRACE_(olerelay)("[byref]'%s'", *(BSTR*)*arg ?
relaystr(*((BSTR*)*arg)) : "<bstr NULL>");
+ if (writeit) {
+ /* ptr to ptr to magic widestring, basically */
+ BSTR *bstr = (BSTR *) *arg;
+ if (!*bstr) {
+ /* -1 means "null string" which is equivalent to empty
string */
+ DWORD fakelen = -1;
+ xbuf_add(buf, (LPBYTE)&fakelen,4);
+ } else {
+ /* BSTRs store the length behind the first character */
+ DWORD *len = ((DWORD *)(*bstr))-1;
+ hres = xbuf_add(buf, (LPBYTE) len, *len + 4);
+ if (hres) return hres;
+ }
+ }
+
+ if (dealloc && arg) {
+ BSTR *str = *((BSTR **)arg);
+ SysFreeString(*str);
+ }
+ return S_OK;
+ }
+
case VT_BSTR: {
if (debugout) {
- if (arg)
- TRACE_(olerelay)("%s",relaystr((BSTR)*arg));
+ if (*arg)
+ TRACE_(olerelay)("%s",relaystr((WCHAR*)*arg));
else
TRACE_(olerelay)("<bstr NULL>");
}
@@ -556,12 +609,12 @@
DWORD cookie;
if (debugout) TRACE_(olerelay)("*");
- if (writeit) {
- cookie = *arg ? 0x42424242 : 0;
- hres = xbuf_add(buf,(LPBYTE)&cookie,sizeof(cookie));
- if (hres)
- return hres;
- }
+ /* Write always, so the other side knows when it gets a NULL
pointer.
+ */
+ cookie = *arg ? 0x42424242 : 0;
+ hres = xbuf_add(buf,(LPBYTE)&cookie,sizeof(cookie));
+ if (hres)
+ return hres;
if (!*arg) {
if (debugout) TRACE_(olerelay)("NULL");
return S_OK;
@@ -660,6 +713,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)("[");
for (i=0;i<arrsize;i++) {
hres = serialize_param(tinfo, writeit, debugout, dealloc,
&adesc->tdescElem, (DWORD*)((LPBYTE)arg+i*_xsize(&adesc->tdescElem)),
buf);
@@ -676,7 +730,169 @@
}
}
+/* IDL desc:
+ * HRESULT GetIDsOfNames(
+ * [in] REFIID riid, args[1]
+ * [in, size_is(cNames)] LPOLESTR *rgszNames, args[2]
+ * [in] UINT cNames, args[3]
+ * [in] LCID lcid, args[4]
+ * [out, size_is(cNames)] DISPID *rgDispId); args[5]
+ *
+ * line format:
+ * IID iid;
+ * DWORD cNames;
+ * LPOLESTR rgszNames[cNames];
+ * DWORD bytestrlen (incl 0)
+ * BYTE data[bytestrlen] (incl 0)
+ * LCID
+ */
static HRESULT
+serialize_IDispatch_GetIDsOfNames(
+ BOOL inputparams,
+ BOOL debugout,
+ DWORD *args,
+ marshal_state *buf)
+{
+ HRESULT hres;
+ DWORD cNames = args[2];
+ LPOLESTR *rgszNames = (LPOLESTR*)args[1];
+ int i;
+
+ if (inputparams) {
+ if (debugout)
TRACE_(olerelay)("riid=%s,",debugstr_guid((REFIID)args[0]));
+ hres = xbuf_add(buf, (LPBYTE)args[0], sizeof(IID));
+ if (hres) {
+ FIXME("serialize of IID failed.\n");
+ return hres;
+ }
+ if (debugout) TRACE_(olerelay)("cNames=%ld,",cNames);
+ hres = xbuf_add(buf, (LPBYTE)&cNames, sizeof(DWORD));
+ if (hres) {
+ FIXME("serialize of cNames failed.\n");
+ return hres;
+ }
+ if (debugout) TRACE_(olerelay)("rgszNames=[");
+ for (i=0;i<cNames;i++) {
+ DWORD len = 2*(lstrlenW(rgszNames[i])+1);
+
+ if (debugout)
TRACE_(olerelay)("%s,",relaystr(rgszNames[i]));
+ hres = xbuf_add(buf, (LPBYTE)&len, sizeof(DWORD));
+ if (hres) {
+ FIXME("serialize of len failed.\n");
+ return hres;
+ }
+ hres = xbuf_add(buf, (LPBYTE)rgszNames[i], len);
+ if (hres) {
+ FIXME("serialize of rgszNames[i] failed.\n");
+ return hres;
+ }
+ }
+ if (debugout) TRACE_(olerelay)("],lcid=%04lx)",args[3]);
+ hres = xbuf_add(buf, (LPBYTE)&args[3], sizeof(DWORD));
+ if (hres) {
+ FIXME("serialize of lcid failed.\n");
+ return hres;
+ }
+ } else {
+ DISPID *rgDispId = (DISPID*)args[4];
+
+ hres = xbuf_add(buf, (LPBYTE)rgDispId, sizeof(DISPID) * cNames);
+ if (hres) {
+ FIXME("serialize of rgDispId failed.\n");
+ return hres;
+ }
+ if (debugout) {
+
TRACE_(olerelay)("riid=[in],rgszNames=[in],cNames=[in],rgDispId=[");
+ for (i=0;i<cNames;i++)
+ TRACE_(olerelay)("%08lx,",rgDispId[i]);
+ TRACE_(olerelay)("])");
+ }
+ HeapFree(GetProcessHeap(),0,(IID*)args[0]);
+ rgszNames = (LPOLESTR*)args[1];
+ for (i=0;i<cNames;i++)
HeapFree(GetProcessHeap(),0,rgszNames[i]);
+ HeapFree(GetProcessHeap(),0,rgszNames);
+ HeapFree(GetProcessHeap(),0,rgDispId);
+ }
+ return S_OK;
+}
+
+static HRESULT
+deserialize_IDispatch_GetIDsOfNames(
+ BOOL inputparams,
+ BOOL debugout,
+ DWORD *args,
+ marshal_state *buf)
+{
+ HRESULT hres;
+ DWORD cNames;
+ LPOLESTR *rgszNames;
+ int i;
+
+ if (inputparams) {
+ args[0] = (DWORD)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
sizeof(IID));
+ if (!args[0]) return E_FAIL;
+ hres = xbuf_get(buf, (LPBYTE)args[0], sizeof(IID));
+ if (hres) {
+ FIXME("deserialize of IID failed.\n");
+ return hres;
+ }
+ if (debugout)
TRACE_(olerelay)("riid=%s,",debugstr_guid((REFIID)args[0]));
+
+ hres = xbuf_get(buf, (LPBYTE)&cNames, sizeof(DWORD));
+ if (hres) {
+ FIXME("deserialize of cNames failed.\n");
+ return hres;
+ }
+ args[2] = cNames;
+ if (debugout) TRACE_(olerelay)("cNames=%ld,",cNames);
+ if (debugout) TRACE_(olerelay)("rgszNames=[");
+ rgszNames =
HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(LPOLESTR) * cNames);
+ if (!rgszNames) return E_FAIL;
+ args[1] = (DWORD)rgszNames;
+ for (i=0;i<cNames;i++) {
+ DWORD len;
+
+ hres = xbuf_get(buf, (LPBYTE)&len, sizeof(DWORD));
+ if (hres) {
+ FIXME("serialize of len failed.\n");
+ return hres;
+ }
+ rgszNames[i] = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
len);
+ if (!rgszNames[i]) {
+ FIXME("heapalloc of %ld bytes failed\n", len);
+ return E_FAIL;
+ }
+ hres = xbuf_get(buf, (LPBYTE)rgszNames[i], len);
+ if (hres) {
+ FIXME("serialize of rgszNames[i] failed.\n");
+ return hres;
+ }
+ if (debugout)
TRACE_(olerelay)("%s,",relaystr(rgszNames[i]));
+ }
+ hres = xbuf_get(buf, (LPBYTE)&args[3], sizeof(DWORD));
+ if (hres) {
+ FIXME("deserialize of lcid failed.\n");
+ return hres;
+ }
+ if (debugout)
TRACE_(olerelay)("],lcid=%04lx,rgDispId=[out])",args[3]);
+ args[4] =
(DWORD)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(DISPID) *
cNames);
+ } else {
+ hres = xbuf_get(buf, (LPBYTE)args[4], sizeof(DISPID) * args[2]);
+ if (hres) {
+ FIXME("serialize of rgDispId failed.\n");
+ return hres;
+ }
+ if (debugout) {
+ TRACE_(olerelay)("dispid=[");
+ for (i=0;i<args[2];i++)
+ TRACE_(olerelay)("%08lx,",((DISPID*)args[4])[i]);
+ TRACE_(olerelay)("])");
+ }
+ }
+ return S_OK;
+}
+
+static HRESULT
serialize_LPVOID_ptr(
ITypeInfo *tinfo,
BOOL writeit,
@@ -696,13 +912,13 @@
FIXME("ppvObject not expressed as VT_PTR -> VT_PTR ->
VT_VOID?\n");
return E_FAIL;
}
- cookie = (*arg) ? 0x42424242: 0x0;
+ cookie = (*(DWORD*)*arg) ? 0x42424242: 0x0;
if (writeit) {
hres = xbuf_add(buf, (LPVOID)&cookie, sizeof(cookie));
if (hres)
return hres;
}
- if (!*arg) {
+ if (!*(DWORD*)*arg) {
if (debugout) TRACE_(olerelay)("<lpvoid NULL>");
return S_OK;
}
@@ -849,15 +1065,79 @@
}
}
case VT_ERROR:
- case VT_BOOL: case VT_I4: case VT_UI4: case VT_UINT: case VT_R4:
- case VT_UI2:
- case VT_UI1:
+ case VT_BOOL:
+ case VT_I4:
+ case VT_UINT:
+ case VT_R4:
+ case VT_UI4:
if (readit) {
hres = xbuf_get(buf,(LPBYTE)arg,sizeof(DWORD));
if (hres) ERR("Failed to read integer 4 byte\n");
}
if (debugout) TRACE_(olerelay)("%lx",*arg);
return hres;
+ case VT_I2:
+ case VT_UI2:
+ if (readit) {
+ DWORD x;
+ hres = xbuf_get(buf,(LPBYTE)&x,sizeof(DWORD));
+ if (hres) ERR("Failed to read integer 4 byte\n");
+ memcpy(arg,&x,2);
+ }
+ if (debugout) TRACE_(olerelay)("%04lx",*arg & 0xffff);
+ return hres;
+ case VT_I1:
+ case VT_UI1:
+ if (readit) {
+ DWORD x;
+ hres = xbuf_get(buf,(LPBYTE)&x,sizeof(DWORD));
+ if (hres) ERR("Failed to read integer 4 byte\n");
+ memcpy(arg,&x,1);
+ }
+ if (debugout) TRACE_(olerelay)("%02lx",*arg & 0xff);
+ return hres;
+ case VT_I4|VT_BYREF:
+ hres = S_OK;
+ if (alloc)
+ *arg =
(DWORD)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(DWORD));
+ if (readit) {
+ hres = xbuf_get(buf,(LPBYTE)*arg,sizeof(DWORD));
+ if (hres) ERR("Failed to read integer 4 byte\n");
+ }
+ if (debugout) TRACE_(olerelay)("&0x%lx",*(DWORD*)*arg);
+ return hres;
+ case VT_BSTR|VT_BYREF: {
+ BSTR **bstr = (BSTR **)arg;
+ WCHAR *str;
+ DWORD len;
+
+ if (readit) {
+ hres = xbuf_get(buf,(LPBYTE)&len,sizeof(DWORD));
+ if (hres) {
+ ERR("failed to read bstr klen\n");
+ return hres;
+ }
+ if (len == -1) {
+ *bstr = CoTaskMemAlloc(sizeof(BSTR *));
+ **bstr = NULL;
+ if (debugout) TRACE_(olerelay)("<bstr NULL>");
+ } else {
+ str =
HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,len+sizeof(WCHAR));
+ hres = xbuf_get(buf,(LPBYTE)str,len);
+ if (hres) {
+ ERR("Failed to read BSTR.\n");
+ return hres;
+ }
+ *bstr = CoTaskMemAlloc(sizeof(BSTR *));
+ **bstr = SysAllocStringLen(str,len);
+ if (debugout) TRACE_(olerelay)("%s",relaystr(str));
+ HeapFree(GetProcessHeap(),0,str);
+ }
+ } else {
+ *bstr = NULL;
+ }
+ return S_OK;
+ }
case VT_BSTR: {
WCHAR *str;
DWORD len;
@@ -889,24 +1169,26 @@
}
case VT_PTR: {
DWORD cookie;
- BOOL derefhere = 0;
+ BOOL derefhere = 0;
derefhere = (tdesc->u.lptdesc->vt != VT_USERDEFINED);
-
- if (readit) {
- hres = xbuf_get(buf,(LPBYTE)&cookie,sizeof(cookie));
- if (hres) {
- ERR("Failed to load pointer cookie.\n");
- return hres;
- }
- if (cookie != 0x42424242) {
- if (debugout) TRACE_(olerelay)("NULL");
- *arg = 0;
- return S_OK;
- }
- if (debugout) TRACE_(olerelay)("*");
+ /* read it in all cases, we need to know if we have
+ * NULL pointer or not.
+ */
+ hres = xbuf_get(buf,(LPBYTE)&cookie,sizeof(cookie));
+ if (hres) {
+ ERR("Failed to load pointer cookie.\n");
+ return hres;
}
+ if (cookie != 0x42424242) {
+ /* we read a NULL ptr from the remote side */
+ if (debugout) TRACE_(olerelay)("NULL");
+ *arg = 0;
+ return S_OK;
+ }
+ if (debugout) TRACE_(olerelay)("*");
if (alloc) {
+ /* Allocate space for the referenced struct */
if (derefhere)
*arg=(DWORD)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,_xsize(tdesc->u.
lptdesc));
}
@@ -948,8 +1230,6 @@
if (hres) {
ERR("Could not get typeattr in VT_USERDEFINED.\n");
} else {
- if (alloc)
- *arg =
(DWORD)HeapAlloc(GetProcessHeap(),0,tattr->cbSizeInstance);
switch (tattr->typekind) {
case TKIND_DISPATCH:
case TKIND_INTERFACE:
@@ -959,6 +1239,9 @@
case TKIND_RECORD: {
int i;
+ if (alloc)
+ *arg =
(DWORD)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,tattr->cbSizeInstance
);
+
if (debugout) TRACE_(olerelay)("{");
for (i=0;i<tattr->cVars;i++) {
VARDESC *vdesc;
@@ -1056,8 +1339,10 @@
}
if (readit) {
hres = _unmarshal_interface(buf,&buf->iid,(LPUNKNOWN*)*arg);
- if (hres)
+ if (hres) {
+ FIXME("_unmarshal_interface of %s , %p failed with %lx\n",
debugstr_guid(&buf->iid), (LPUNKNOWN*)*arg, hres);
return hres;
+ }
}
if (debugout) TRACE_(olerelay)("ppv(%p)",(LPVOID)*arg);
return S_OK;
@@ -1209,6 +1494,8 @@
BSTR fname,iname;
BSTR names[10];
int nrofnames;
+ int is_idispatch_getidsofnames = 0;
+ DWORD remoteresult = 0;
EnterCriticalSection(&tpinfo->crit);
@@ -1235,9 +1522,35 @@
else
TRACE_(olerelay)("%d",method);
TRACE_(olerelay)("(");
- if (iname) SysFreeString(iname);
- if (fname) SysFreeString(fname);
}
+ if (iname && fname && !lstrcmpW(iname,IDispatchW) &&
!lstrcmpW(fname,GetIDsOfNamesW))
+ is_idispatch_getidsofnames = 1;
+
+ if (iname) SysFreeString(iname);
+ if (fname) SysFreeString(fname);
+
+ memset(&buf,0,sizeof(buf));
+ buf.iid = IID_IUnknown;
+
+ /* Special IDispatch::GetIDsOfNames() serializer */
+ if (is_idispatch_getidsofnames) {
+ hres =
serialize_IDispatch_GetIDsOfNames(TRUE,relaydeb,args,&buf);
+ if (hres != S_OK) {
+ FIXME("serialize of IDispatch::GetIDsOfNames failed!\n");
+ return hres;
+ }
+ goto afterserialize;
+ }
+
+ /* special QueryInterface serialize */
+ if (method == 0) {
+ xbuf_add(&buf,(LPBYTE)args[0],sizeof(IID));
+ if (relaydeb)
TRACE_(olerelay)("riid=%s,[out])",debugstr_guid((REFIID)args[0]));
+ goto afterserialize;
+ }
+
+ /* normal typelib driven serializing */
+
/* Need them for hack below */
memset(names,0,sizeof(names));
if
(ITypeInfo_GetNames(tpinfo->tinfo,fdesc->memid,names,sizeof(names)/sizeo
f(names[0]),&nrofnames))
@@ -1245,62 +1558,42 @@
if (nrofnames > sizeof(names)/sizeof(names[0]))
ERR("Need more names!\n");
- memset(&buf,0,sizeof(buf));
- buf.iid = IID_IUnknown;
- if (method == 0) {
- xbuf_add(&buf,(LPBYTE)args[0],sizeof(IID));
- if (relaydeb)
TRACE_(olerelay)("riid=%s,[out]",debugstr_guid((REFIID)args[0]));
- } else {
- xargs = args;
- for (i=0;i<fdesc->cParams;i++) {
- ELEMDESC *elem = fdesc->lprgelemdescParam+i;
- BOOL isserialized = FALSE;
- if (relaydeb) {
- if (i) TRACE_(olerelay)(",");
- if (i+1<nrofnames && names[i+1])
- TRACE_(olerelay)("%s=",relaystr(names[i+1]));
- }
- /* No need to marshal other data than FIN */
- if (!(elem->u.paramdesc.wParamFlags & PARAMFLAG_FIN)) {
- xargs+=_argsize(elem->tdesc.vt);
- if (relaydeb) TRACE_(olerelay)("[out]");
- continue;
- }
- if (((i+1)<nrofnames) && !IsBadStringPtrW(names[i+1],1)) {
- /* If the parameter is 'riid', we use it as interface
IID
- * for a later ppvObject serialization.
- */
- buf.thisisiid = !lstrcmpW(names[i+1],riidW);
+ xargs = args;
+ for (i=0;i<fdesc->cParams;i++) {
+ ELEMDESC *elem = fdesc->lprgelemdescParam+i;
+ BOOL isserialized = FALSE;
+ if (relaydeb) {
+ if (i) TRACE_(olerelay)(",");
+ if (i+1<nrofnames && names[i+1])
+ TRACE_(olerelay)("%s=",relaystr(names[i+1]));
+ }
+ /* No need to marshal other data than FIN and any VT_PTR. */
+ if (!(elem->u.paramdesc.wParamFlags & PARAMFLAG_FIN) &&
(elem->tdesc.vt != VT_PTR)) {
+ xargs+=_argsize(elem->tdesc.vt);
+ if (relaydeb) TRACE_(olerelay)("[out]");
+ continue;
+ }
+ if (((i+1)<nrofnames) && !IsBadStringPtrW(names[i+1],1)) {
+ /* If the parameter is 'riid', we use it as interface IID
+ * for a later ppvObject serialization.
+ */
+ buf.thisisiid = !lstrcmpW(names[i+1],riidW);
- /* DISPPARAMS* needs special serializer */
- if (!lstrcmpW(names[i+1],pdispparamsW)) {
- hres = serialize_DISPPARAM_ptr(
- tpinfo->tinfo,
- elem->u.paramdesc.wParamFlags & PARAMFLAG_FIN,
- relaydeb,
- FALSE,
- &elem->tdesc,
- xargs,
- &buf
- );
- isserialized = TRUE;
- }
- if (!lstrcmpW(names[i+1],ppvObjectW)) {
- hres = serialize_LPVOID_ptr(
- tpinfo->tinfo,
- elem->u.paramdesc.wParamFlags & PARAMFLAG_FIN,
- relaydeb,
- FALSE,
- &elem->tdesc,
- xargs,
- &buf
- );
- if (hres == S_OK)
- isserialized = TRUE;
- }
+ /* DISPPARAMS* needs special serializer */
+ if (!lstrcmpW(names[i+1],pdispparamsW)) {
+ hres = serialize_DISPPARAM_ptr(
+ tpinfo->tinfo,
+ elem->u.paramdesc.wParamFlags & PARAMFLAG_FIN,
+ relaydeb,
+ FALSE,
+ &elem->tdesc,
+ xargs,
+ &buf
+ );
+ isserialized = TRUE;
}
- if (!isserialized)
- hres = serialize_param(
+ if (!lstrcmpW(names[i+1],ppvObjectW)) {
+ hres = serialize_LPVOID_ptr(
tpinfo->tinfo,
elem->u.paramdesc.wParamFlags & PARAMFLAG_FIN,
relaydeb,
@@ -1309,15 +1602,30 @@
xargs,
&buf
);
-
- if (hres) {
- ERR("Failed to serialize param, hres %lx\n",hres);
- break;
+ if (hres == S_OK)
+ isserialized = TRUE;
}
- xargs+=_argsize(elem->tdesc.vt);
}
+ if (!isserialized)
+ hres = serialize_param(
+ tpinfo->tinfo,
+ elem->u.paramdesc.wParamFlags & PARAMFLAG_FIN,
+ relaydeb,
+ FALSE,
+ &elem->tdesc,
+ xargs,
+ &buf
+ );
+
+ if (hres) {
+ ERR("Failed to serialize param, hres %lx\n",hres);
+ break;
+ }
+ xargs+=_argsize(elem->tdesc.vt);
}
if (relaydeb) TRACE_(olerelay)(")");
+
+afterserialize:
memset(&msg,0,sizeof(msg));
msg.cbBuffer = buf.curoff;
msg.iMethod = method;
@@ -1336,7 +1644,7 @@
return hres;
}
- if (relaydeb) TRACE_(olerelay)(" = %08lx (",status);
+ if (relaydeb) TRACE_(olerelay)(" status = %08lx (",status);
if (buf.base)
buf.base =
HeapReAlloc(GetProcessHeap(),0,buf.base,msg.cbBuffer);
else
@@ -1344,88 +1652,145 @@
buf.size = msg.cbBuffer;
memcpy(buf.base,msg.Buffer,buf.size);
buf.curoff = 0;
+
+ /* Special IDispatch::GetIDsOfNames() deserializer */
+ if (is_idispatch_getidsofnames) {
+ hres =
deserialize_IDispatch_GetIDsOfNames(FALSE,relaydeb,args,&buf);
+ if (hres != S_OK) {
+ FIXME("deserialize of IDispatch::GetIDsOfNames failed!\n");
+ return hres;
+ }
+ goto after_deserialize;
+ }
+ /* Special QueryInterface deserializer */
if (method == 0) {
_unmarshal_interface(&buf,(REFIID)args[0],(LPUNKNOWN*)args[1]);
if (relaydeb) TRACE_(olerelay)("[in],%p",*((DWORD**)args[1]));
- } else {
- xargs = args;
- for (i=0;i<fdesc->cParams;i++) {
- ELEMDESC *elem = fdesc->lprgelemdescParam+i;
- BOOL isdeserialized = FALSE;
+ goto after_deserialize;
+ }
- if (relaydeb) {
- if (i) TRACE_(olerelay)(",");
- if (i+1<nrofnames && names[i+1])
TRACE_(olerelay)("%s=",relaystr(names[i+1]));
- }
- /* No need to marshal other data than FOUT I think */
- if (!(elem->u.paramdesc.wParamFlags & PARAMFLAG_FOUT)) {
- xargs += _argsize(elem->tdesc.vt);
- if (relaydeb) TRACE_(olerelay)("[in]");
- continue;
- }
- if (((i+1)<nrofnames) && !IsBadStringPtrW(names[i+1],1)) {
- /* If the parameter is 'riid', we use it as interface
IID
- * for a later ppvObject serialization.
- */
- buf.thisisiid = !lstrcmpW(names[i+1],riidW);
+ /* generic deserializer using typelib description */
+ xargs = args;
+ status = S_OK;
+ for (i=0;i<fdesc->cParams;i++) {
+ ELEMDESC *elem = fdesc->lprgelemdescParam+i;
+ BOOL isdeserialized = FALSE;
- /* deserialize DISPPARAM */
- if (!lstrcmpW(names[i+1],pdispparamsW)) {
- hres = deserialize_DISPPARAM_ptr(
- tpinfo->tinfo,
- elem->u.paramdesc.wParamFlags & PARAMFLAG_FOUT,
- relaydeb,
- FALSE,
- &(elem->tdesc),
- xargs,
- &buf
- );
- if (hres) {
- ERR("Failed to deserialize DISPPARAM*, hres
%lx\n",hres);
- break;
- }
- isdeserialized = TRUE;
+ if (relaydeb) {
+ if (i) TRACE_(olerelay)(",");
+ if (i+1<nrofnames && names[i+1])
TRACE_(olerelay)("%s=",relaystr(names[i+1]));
+ }
+ /* No need to marshal other data than FOUT and any VT_PTR */
+ if (!(elem->u.paramdesc.wParamFlags & PARAMFLAG_FOUT) &&
(elem->tdesc.vt != VT_PTR)) {
+ xargs += _argsize(elem->tdesc.vt);
+ if (relaydeb) TRACE_(olerelay)("[in]");
+ continue;
+ }
+ if (((i+1)<nrofnames) && !IsBadStringPtrW(names[i+1],1)) {
+ /* If the parameter is 'riid', we use it as interface IID
+ * for a later ppvObject serialization.
+ */
+ buf.thisisiid = !lstrcmpW(names[i+1],riidW);
+
+ /* deserialize DISPPARAM */
+ if (!lstrcmpW(names[i+1],pdispparamsW)) {
+ hres = deserialize_DISPPARAM_ptr(
+ tpinfo->tinfo,
+ elem->u.paramdesc.wParamFlags & PARAMFLAG_FOUT,
+ relaydeb,
+ FALSE,
+ &(elem->tdesc),
+ xargs,
+ &buf
+ );
+ if (hres) {
+ ERR("Failed to deserialize DISPPARAM*, hres
%lx\n",hres);
+ break;
}
- if (!lstrcmpW(names[i+1],ppvObjectW)) {
- hres = deserialize_LPVOID_ptr(
- tpinfo->tinfo,
- elem->u.paramdesc.wParamFlags & PARAMFLAG_FOUT,
- relaydeb,
- FALSE,
- &elem->tdesc,
- xargs,
- &buf
- );
- if (hres == S_OK)
- isdeserialized = TRUE;
- }
+ isdeserialized = TRUE;
}
- if (!isdeserialized)
- hres = deserialize_param(
+ if (!lstrcmpW(names[i+1],ppvObjectW)) {
+ hres = deserialize_LPVOID_ptr(
tpinfo->tinfo,
elem->u.paramdesc.wParamFlags & PARAMFLAG_FOUT,
relaydeb,
FALSE,
- &(elem->tdesc),
+ &elem->tdesc,
xargs,
&buf
);
- if (hres) {
- ERR("Failed to unmarshall param, hres %lx\n",hres);
- status = hres;
- break;
+ if (hres == S_OK)
+ isdeserialized = TRUE;
[truncated at 1000 lines; 474 more skipped]