Sync to Wine-20050419: Daniel Remenak dtremenak@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@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@navi.cx - Fix BSTR tracing in the typelib marshaller. - Fix PARAMFLAG_FOUT typo in the tmarshaller. Mike Hearn mh@codeweavers.com Robert Shearman rob@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@codeweavers.com - Add outer unknown support for typelib marshaler. Jakob Eriksson jakov@vmlinux.org - Get rid of HeapAlloc casts. Francois Gouget fgouget@free.fr - Assorted spelling fixes. Alex Villacis Lasso a_villacis@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]