mirror of
https://github.com/reactos/reactos.git
synced 2024-07-05 12:15:46 +00:00
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(). svn path=/trunk/; revision=15011
This commit is contained in:
parent
61e422828e
commit
df82a2a2a8
|
@ -235,8 +235,7 @@ BSTR WINAPI SysAllocStringLen(const OLECHAR *str, unsigned int len)
|
|||
* buffer for the character count and an extra character at the
|
||||
* end for the NULL.
|
||||
*/
|
||||
newBuffer = (DWORD*)HeapAlloc(GetProcessHeap(),
|
||||
0,
|
||||
newBuffer = HeapAlloc(GetProcessHeap(), 0,
|
||||
bufferSize + sizeof(WCHAR) + sizeof(DWORD));
|
||||
|
||||
/*
|
||||
|
@ -350,8 +349,7 @@ BSTR WINAPI SysAllocStringByteLen(LPCSTR str, UINT len)
|
|||
* buffer for the character count and an extra character at the
|
||||
* end for the NULL.
|
||||
*/
|
||||
newBuffer = (DWORD*)HeapAlloc(GetProcessHeap(),
|
||||
0,
|
||||
newBuffer = HeapAlloc(GetProcessHeap(), 0,
|
||||
len + sizeof(WCHAR) + sizeof(DWORD));
|
||||
|
||||
/*
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -185,6 +185,36 @@ static void OLEPictureImpl_SetBitmap(OLEPictureImpl*This) {
|
|||
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 @@ static OLEPictureImpl* OLEPictureImpl_Construct(LPPICTDESC pictDesc, BOOL fOwn)
|
|||
break;
|
||||
|
||||
case PICTYPE_ICON:
|
||||
OLEPictureImpl_SetIcon(newObject);
|
||||
break;
|
||||
case PICTYPE_ENHMETAFILE:
|
||||
default:
|
||||
FIXME("Unsupported type %d\n", pictDesc->picType);
|
||||
|
@ -1071,7 +1103,7 @@ static HRESULT WINAPI OLEPictureImpl_Load(IPersistStream* iface,IStream*pStm) {
|
|||
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];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1501,7 +1533,7 @@ static int serializeBMP(HBITMAP hBitmap, void ** ppBuffer, unsigned int * pLengt
|
|||
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 @@ static int serializeBMP(HBITMAP hBitmap, void ** ppBuffer, unsigned int * pLengt
|
|||
|
||||
/* 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 @@ static int serializeBMP(HBITMAP hBitmap, void ** ppBuffer, unsigned int * pLengt
|
|||
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 @@ static int serializeIcon(HICON hIcon, void ** ppBuffer, unsigned int * pLength)
|
|||
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 @@ static int serializeIcon(HICON hIcon, void ** ppBuffer, unsigned int * pLength)
|
|||
*/
|
||||
/* 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 @@ static int serializeIcon(HICON hIcon, void ** ppBuffer, unsigned int * pLength)
|
|||
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));
|
||||
|
|
|
@ -647,7 +647,7 @@ SAFEARRAY* WINAPI SafeArrayCreateEx(VARTYPE vt, UINT cDims, SAFEARRAYBOUND *rgsa
|
|||
/************************************************************************
|
||||
* 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 @@ SAFEARRAY* WINAPI SafeArrayCreateVector(VARTYPE vt, LONG lLbound, ULONG cElement
|
|||
/************************************************************************
|
||||
* 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
|
||||
|
|
|
@ -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 @@ _marshal_interface(marshal_state *buf, REFIID riid, LPUNKNOWN pUnk) {
|
|||
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 @@ typedef struct _TMProxyImpl {
|
|||
IRpcChannelBuffer* chanbuf;
|
||||
IID iid;
|
||||
CRITICAL_SECTION crit;
|
||||
IUnknown *outerunknown;
|
||||
} TMProxyImpl;
|
||||
|
||||
static HRESULT WINAPI
|
||||
|
@ -499,17 +509,36 @@ serialize_param(
|
|||
return S_OK;
|
||||
case VT_BOOL:
|
||||
case VT_ERROR:
|
||||
case VT_UI4:
|
||||
case VT_UINT:
|
||||
case VT_I4:
|
||||
case VT_R4:
|
||||
case VT_UI2:
|
||||
case VT_UI1:
|
||||
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)("%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 @@ serialize_param(
|
|||
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 @@ serialize_param(
|
|||
DWORD cookie;
|
||||
|
||||
if (debugout) TRACE_(olerelay)("*");
|
||||
if (writeit) {
|
||||
/* 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 @@ serialize_param(
|
|||
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,6 +730,168 @@ serialize_param(
|
|||
}
|
||||
}
|
||||
|
||||
/* 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,
|
||||
|
@ -696,13 +912,13 @@ serialize_LPVOID_ptr(
|
|||
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 @@ deserialize_param(
|
|||
}
|
||||
}
|
||||
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;
|
||||
|
@ -892,21 +1172,23 @@ deserialize_param(
|
|||
BOOL derefhere = 0;
|
||||
|
||||
derefhere = (tdesc->u.lptdesc->vt != VT_USERDEFINED);
|
||||
|
||||
if (readit) {
|
||||
/* 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 @@ deserialize_param(
|
|||
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 @@ deserialize_param(
|
|||
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,9 +1339,11 @@ deserialize_LPVOID_ptr(
|
|||
}
|
||||
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 @@ xCall(LPVOID retptr, int method, TMProxyImpl *tpinfo /*, args */)
|
|||
BSTR fname,iname;
|
||||
BSTR names[10];
|
||||
int nrofnames;
|
||||
int is_idispatch_getidsofnames = 0;
|
||||
DWORD remoteresult = 0;
|
||||
|
||||
EnterCriticalSection(&tpinfo->crit);
|
||||
|
||||
|
@ -1235,9 +1522,35 @@ xCall(LPVOID retptr, int method, TMProxyImpl *tpinfo /*, args */)
|
|||
else
|
||||
TRACE_(olerelay)("%d",method);
|
||||
TRACE_(olerelay)("(");
|
||||
}
|
||||
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)/sizeof(names[0]),&nrofnames))
|
||||
|
@ -1245,12 +1558,6 @@ xCall(LPVOID retptr, int method, TMProxyImpl *tpinfo /*, args */)
|
|||
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;
|
||||
|
@ -1260,8 +1567,8 @@ xCall(LPVOID retptr, int method, TMProxyImpl *tpinfo /*, args */)
|
|||
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)) {
|
||||
/* 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;
|
||||
|
@ -1316,8 +1623,9 @@ xCall(LPVOID retptr, int method, TMProxyImpl *tpinfo /*, args */)
|
|||
}
|
||||
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 @@ xCall(LPVOID retptr, int method, TMProxyImpl *tpinfo /*, args */)
|
|||
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,11 +1652,26 @@ xCall(LPVOID retptr, int method, TMProxyImpl *tpinfo /*, args */)
|
|||
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 {
|
||||
goto after_deserialize;
|
||||
}
|
||||
|
||||
/* 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;
|
||||
|
@ -1357,8 +1680,8 @@ xCall(LPVOID retptr, int method, TMProxyImpl *tpinfo /*, args */)
|
|||
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)) {
|
||||
/* 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;
|
||||
|
@ -1417,13 +1740,55 @@ xCall(LPVOID retptr, int method, TMProxyImpl *tpinfo /*, args */)
|
|||
}
|
||||
xargs += _argsize(elem->tdesc.vt);
|
||||
}
|
||||
}
|
||||
if (relaydeb) TRACE_(olerelay)(")\n");
|
||||
HeapFree(GetProcessHeap(),0,buf.base);
|
||||
|
||||
LeaveCriticalSection(&tpinfo->crit);
|
||||
after_deserialize:
|
||||
hres = xbuf_get(&buf, (LPBYTE)&remoteresult, sizeof(DWORD));
|
||||
if (hres != S_OK)
|
||||
return hres;
|
||||
if (relaydeb) TRACE_(olerelay)(") = %08lx\n", remoteresult);
|
||||
|
||||
if (status != S_OK) /* OLE/COM internal error */
|
||||
return status;
|
||||
|
||||
HeapFree(GetProcessHeap(),0,buf.base);
|
||||
LeaveCriticalSection(&tpinfo->crit);
|
||||
return remoteresult;
|
||||
}
|
||||
|
||||
HRESULT WINAPI ProxyIUnknown_QueryInterface(IUnknown *iface, REFIID riid, void **ppv)
|
||||
{
|
||||
TMProxyImpl *proxy = (TMProxyImpl *)iface;
|
||||
|
||||
TRACE("(%s, %p)\n", debugstr_guid(riid), ppv);
|
||||
|
||||
if (proxy->outerunknown)
|
||||
return IUnknown_QueryInterface(proxy->outerunknown, riid, ppv);
|
||||
|
||||
FIXME("No interface\n");
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
ULONG WINAPI ProxyIUnknown_AddRef(IUnknown *iface)
|
||||
{
|
||||
TMProxyImpl *proxy = (TMProxyImpl *)iface;
|
||||
|
||||
TRACE("\n");
|
||||
|
||||
if (proxy->outerunknown)
|
||||
return IUnknown_AddRef(proxy->outerunknown);
|
||||
|
||||
return 2; /* FIXME */
|
||||
}
|
||||
|
||||
ULONG WINAPI ProxyIUnknown_Release(IUnknown *iface)
|
||||
{
|
||||
TMProxyImpl *proxy = (TMProxyImpl *)iface;
|
||||
|
||||
TRACE("\n");
|
||||
|
||||
if (proxy->outerunknown)
|
||||
return IUnknown_Release(proxy->outerunknown);
|
||||
|
||||
return 1; /* FIXME */
|
||||
}
|
||||
|
||||
static HRESULT WINAPI
|
||||
|
@ -1449,6 +1814,7 @@ PSFacBuf_CreateProxy(
|
|||
|
||||
assert(sizeof(TMAsmProxy) == 12);
|
||||
|
||||
proxy->outerunknown = pUnkOuter;
|
||||
proxy->asmstubs = VirtualAlloc(NULL, sizeof(TMAsmProxy) * nroffuncs, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
|
||||
if (!proxy->asmstubs) {
|
||||
ERR("Could not commit pages for proxy thunks\n");
|
||||
|
@ -1460,17 +1826,22 @@ PSFacBuf_CreateProxy(
|
|||
|
||||
proxy->lpvtbl = HeapAlloc(GetProcessHeap(),0,sizeof(LPBYTE)*nroffuncs);
|
||||
for (i=0;i<nroffuncs;i++) {
|
||||
int nrofargs;
|
||||
TMAsmProxy *xasm = proxy->asmstubs+i;
|
||||
|
||||
/* nrofargs without This */
|
||||
switch (i) {
|
||||
case 0: nrofargs = 2;
|
||||
case 0:
|
||||
proxy->lpvtbl[i] = ProxyIUnknown_QueryInterface;
|
||||
break;
|
||||
case 1: case 2: nrofargs = 0;
|
||||
case 1:
|
||||
proxy->lpvtbl[i] = ProxyIUnknown_AddRef;
|
||||
break;
|
||||
case 2:
|
||||
proxy->lpvtbl[i] = ProxyIUnknown_Release;
|
||||
break;
|
||||
default: {
|
||||
int j;
|
||||
/* nrofargs without This */
|
||||
int nrofargs;
|
||||
hres = _get_funcdesc(tinfo,i,&fdesc,NULL,NULL);
|
||||
if (hres) {
|
||||
ERR("GetFuncDesc %lx should not fail here.\n",hres);
|
||||
|
@ -1485,9 +1856,6 @@ PSFacBuf_CreateProxy(
|
|||
ERR("calling convention is not stdcall????\n");
|
||||
return E_FAIL;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* popl %eax - return ptr
|
||||
* pushl <nr>
|
||||
* pushl %eax
|
||||
|
@ -1507,6 +1875,9 @@ PSFacBuf_CreateProxy(
|
|||
xasm->lret = 0xc2;
|
||||
xasm->bytestopop= (nrofargs+2)*4; /* pop args, This, iMethod */
|
||||
proxy->lpvtbl[i] = xasm;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
proxy->lpvtbl2 = &tmproxyvtable;
|
||||
/* 1 reference for the proxy and 1 for the object */
|
||||
|
@ -1603,6 +1974,8 @@ TMStubImpl_Invoke(
|
|||
marshal_state buf;
|
||||
int nrofnames;
|
||||
BSTR names[10];
|
||||
BSTR fname = NULL,iname = NULL;
|
||||
BOOL is_idispatch_getidsofnames = 0;
|
||||
|
||||
memset(&buf,0,sizeof(buf));
|
||||
buf.size = xmsg->cbBuffer;
|
||||
|
@ -1622,11 +1995,18 @@ TMStubImpl_Invoke(
|
|||
xmsg->cbBuffer = buf.size;
|
||||
return hres;
|
||||
}
|
||||
hres = _get_funcdesc(This->tinfo,xmsg->iMethod,&fdesc,NULL,NULL);
|
||||
hres = _get_funcdesc(This->tinfo,xmsg->iMethod,&fdesc,&iname,&fname);
|
||||
if (hres) {
|
||||
ERR("GetFuncDesc on method %ld failed with %lx\n",xmsg->iMethod,hres);
|
||||
return hres;
|
||||
}
|
||||
|
||||
if (iname && fname && !lstrcmpW(iname, IDispatchW) && !lstrcmpW(fname, GetIDsOfNamesW))
|
||||
is_idispatch_getidsofnames = 1;
|
||||
|
||||
if (iname) SysFreeString (iname);
|
||||
if (fname) SysFreeString (fname);
|
||||
|
||||
/* Need them for hack below */
|
||||
memset(names,0,sizeof(names));
|
||||
ITypeInfo_GetNames(This->tinfo,fdesc->memid,names,sizeof(names)/sizeof(names[0]),&nrofnames);
|
||||
|
@ -1641,6 +2021,16 @@ TMStubImpl_Invoke(
|
|||
args = HeapAlloc(GetProcessHeap(),0,(nrofargs+1)*sizeof(DWORD));
|
||||
if (!args) return E_OUTOFMEMORY;
|
||||
|
||||
if (is_idispatch_getidsofnames) {
|
||||
hres = deserialize_IDispatch_GetIDsOfNames(TRUE,FALSE,args+1,&buf);
|
||||
if (hres != S_OK) {
|
||||
FIXME("deserialize_IDispatch_GetIDsOfNames failed!\n");
|
||||
return hres;
|
||||
}
|
||||
xargs = args+1+5;
|
||||
goto afterdeserialize;
|
||||
}
|
||||
|
||||
/* Allocate all stuff used by call. */
|
||||
xargs = args+1;
|
||||
for (i=0;i<fdesc->cParams;i++) {
|
||||
|
@ -1673,7 +2063,7 @@ TMStubImpl_Invoke(
|
|||
if (!lstrcmpW(names[i+1],ppvObjectW)) {
|
||||
hres = deserialize_LPVOID_ptr(
|
||||
This->tinfo,
|
||||
elem->u.paramdesc.wParamFlags & PARAMFLAG_FOUT,
|
||||
elem->u.paramdesc.wParamFlags & PARAMFLAG_FIN,
|
||||
FALSE,
|
||||
TRUE,
|
||||
&elem->tdesc,
|
||||
|
@ -1700,9 +2090,10 @@ TMStubImpl_Invoke(
|
|||
break;
|
||||
}
|
||||
}
|
||||
afterdeserialize:
|
||||
hres = IUnknown_QueryInterface(This->pUnk,&(This->iid),(LPVOID*)&(args[0]));
|
||||
if (hres) {
|
||||
ERR("Does not support iface %s\n",debugstr_guid(&(This->iid)));
|
||||
ERR("Does not support iface %s, returning %lx\n",debugstr_guid(&(This->iid)), hres);
|
||||
return hres;
|
||||
}
|
||||
res = _invoke(
|
||||
|
@ -1713,6 +2104,16 @@ TMStubImpl_Invoke(
|
|||
);
|
||||
IUnknown_Release((LPUNKNOWN)args[0]);
|
||||
buf.curoff = 0;
|
||||
|
||||
/* special IDispatch::GetIDsOfNames serializer */
|
||||
if (is_idispatch_getidsofnames) {
|
||||
hres = serialize_IDispatch_GetIDsOfNames(FALSE,FALSE,args+1,&buf);
|
||||
if (hres != S_OK) {
|
||||
FIXME("serialize of IDispatch::GetIDsOfNames failed!\n");
|
||||
return hres;
|
||||
}
|
||||
goto afterserialize;
|
||||
}
|
||||
xargs = args+1;
|
||||
for (i=0;i<fdesc->cParams;i++) {
|
||||
ELEMDESC *elem = fdesc->lprgelemdescParam+i;
|
||||
|
@ -1767,11 +2168,16 @@ TMStubImpl_Invoke(
|
|||
break;
|
||||
}
|
||||
}
|
||||
afterserialize:
|
||||
hres = xbuf_add (&buf, (LPBYTE)&res, sizeof(DWORD));
|
||||
if (hres != S_OK)
|
||||
return hres;
|
||||
|
||||
/* might need to use IRpcChannelBuffer_GetBuffer ? */
|
||||
xmsg->cbBuffer = buf.curoff;
|
||||
xmsg->Buffer = buf.base;
|
||||
HeapFree(GetProcessHeap(),0,args);
|
||||
return res;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static LPRPCSTUBBUFFER WINAPI
|
||||
|
|
|
@ -1625,25 +1625,25 @@ MSFT_DoFuncs(TLBContext* pcx,
|
|||
* member information is stored in a data structure at offset
|
||||
* indicated by the memoffset field of the typeinfo structure
|
||||
* There are several distinctive parts.
|
||||
* the first part starts with a field that holds the total length
|
||||
* The first part starts with a field that holds the total length
|
||||
* of this (first) part excluding this field. Then follow the records,
|
||||
* for each member there is one record.
|
||||
*
|
||||
* First entry is always the length of the record (including this
|
||||
* The first entry is always the length of the record (including this
|
||||
* length word).
|
||||
* Rest of the record depends on the type of the member. If there is
|
||||
* a field indicating the member type (function variable intereface etc)
|
||||
* The rest of the record depends on the type of the member. If there is
|
||||
* a field indicating the member type (function, variable, interface, etc)
|
||||
* I have not found it yet. At this time we depend on the information
|
||||
* in the type info and the usual order how things are stored.
|
||||
*
|
||||
* Second follows an array sized nrMEM*sizeof(INT) with a memeber id
|
||||
* Second follows an array sized nrMEM*sizeof(INT) with a member id
|
||||
* for each member;
|
||||
*
|
||||
* Third is a equal sized array with file offsets to the name entry
|
||||
* Third is an equal sized array with file offsets to the name entry
|
||||
* of each member.
|
||||
*
|
||||
* Forth and last (?) part is an array with offsets to the records in the
|
||||
* first part of this file segment.
|
||||
* The fourth and last (?) part is an array with offsets to the records
|
||||
* in the first part of this file segment.
|
||||
*/
|
||||
|
||||
int infolen, nameoffset, reclength, nrattributes, i;
|
||||
|
@ -4516,7 +4516,6 @@ _copy_arg( ITypeInfo2 *tinfo, TYPEDESC *tdesc,
|
|||
DWORD *argpos, VARIANT *arg, VARTYPE vt
|
||||
) {
|
||||
UINT arglen = _argsize(vt)*sizeof(DWORD);
|
||||
VARTYPE oldvt;
|
||||
VARIANT va;
|
||||
|
||||
if ((vt==VT_PTR) && tdesc && (tdesc->u.lptdesc->vt == VT_VARIANT)) {
|
||||
|
@ -4650,7 +4649,6 @@ _copy_arg( ITypeInfo2 *tinfo, TYPEDESC *tdesc,
|
|||
return hres;
|
||||
}
|
||||
|
||||
oldvt = V_VT(arg);
|
||||
VariantInit(&va);
|
||||
if (VariantChangeType(&va,arg,0,vt)==S_OK) {
|
||||
memcpy(argpos,&V_I4(&va), arglen);
|
||||
|
@ -4687,7 +4685,7 @@ DispCallFunc(
|
|||
dump_Variant(prgpvarg[i]);
|
||||
argsize += _argsize(prgvt[i]);
|
||||
}
|
||||
args = (DWORD*)HeapAlloc(GetProcessHeap(),0,sizeof(DWORD)*argsize);
|
||||
args = HeapAlloc(GetProcessHeap(),0,sizeof(DWORD)*argsize);
|
||||
args[0] = (DWORD)pvInstance; /* this is the fake IDispatch interface pointer */
|
||||
argspos = 1;
|
||||
for (i=0;i<cActuals;i++) {
|
||||
|
@ -4760,8 +4758,8 @@ static HRESULT WINAPI ITypeInfo_fnInvoke(
|
|||
}
|
||||
}
|
||||
|
||||
args = (DWORD*)HeapAlloc(GetProcessHeap(),0,sizeof(DWORD)*numargs);
|
||||
args2 = (DWORD*)HeapAlloc(GetProcessHeap(),0,sizeof(DWORD)*numargs2);
|
||||
args = HeapAlloc(GetProcessHeap(),0,sizeof(DWORD)*numargs);
|
||||
args2 = HeapAlloc(GetProcessHeap(),0,sizeof(DWORD)*numargs2);
|
||||
|
||||
args[0] = (DWORD)pIUnk;
|
||||
argspos = 1; args2pos = 0;
|
||||
|
|
|
@ -169,7 +169,7 @@ typedef struct tagMSFT_ImpInfo {
|
|||
/* function description data */
|
||||
typedef struct {
|
||||
/* INT recsize; record size including some xtra stuff */
|
||||
INT DataType; /* data type of the memeber, eg return of function */
|
||||
INT DataType; /* data type of the member, eg return of function */
|
||||
INT Flags; /* something to do with attribute flags (LOWORD) */
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
INT16 funcdescsize; /* size of reconstituted FUNCDESC and related structs */
|
||||
|
@ -184,7 +184,7 @@ typedef struct {
|
|||
/* bit 3 that parameter has default values */
|
||||
/* calling convention (bits 4-7 ) */
|
||||
/* bit 8 indicates that custom data is present */
|
||||
/* Invokation kind (bits 9-12 ) */
|
||||
/* Invocation kind (bits 9-12 ) */
|
||||
/* function kind (eg virtual), bits 13-15 */
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
INT16 nroargs; /* nr of optional arguments */
|
||||
|
|
|
@ -3,6 +3,8 @@
|
|||
*
|
||||
* Copyright 1998 Jean-Claude Cote
|
||||
* Copyright 2003 Jon Griffiths
|
||||
* Copyright 2005 Daniel Remenak
|
||||
*
|
||||
* The alorithm for conversion from Julian days to day/month/year is based on
|
||||
* that devised by Henry Fliegel, as implemented in PostgreSQL, which is
|
||||
* Copyright 1994-7 Regents of the University of California
|
||||
|
@ -3008,11 +3010,13 @@ HRESULT WINAPI VarDiv(LPVARIANT left, LPVARIANT right, LPVARIANT result)
|
|||
}
|
||||
switch (resvt) {
|
||||
case VT_R8:
|
||||
if (V_R8(&rv) == 0) return DISP_E_DIVBYZERO;
|
||||
V_VT(result) = resvt;
|
||||
V_R8(result) = V_R8(&lv) / V_R8(&rv);
|
||||
rc = S_OK;
|
||||
break;
|
||||
case VT_I4:
|
||||
if (V_I4(&rv) == 0) return DISP_E_DIVBYZERO;
|
||||
V_VT(result) = resvt;
|
||||
V_I4(result) = V_I4(&lv) / V_I4(&rv);
|
||||
rc = S_OK;
|
||||
|
@ -4155,9 +4159,57 @@ HRESULT WINAPI VarRound(LPVARIANT pVarIn, int deci, LPVARIANT pVarOut)
|
|||
return hRet;
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
* VarIdiv [OLEAUT32.153]
|
||||
*
|
||||
* Converts input variants to integers and divides them.
|
||||
*
|
||||
* PARAMS
|
||||
* left [I] Left hand variant
|
||||
* right [I] Right hand variant
|
||||
* result [O] Destination for quotient
|
||||
*
|
||||
* RETURNS
|
||||
* Success: S_OK. result contains the quotient.
|
||||
* Failure: An HRESULT error code indicating the error.
|
||||
*
|
||||
* NOTES
|
||||
* If either expression is null, null is returned, as per MSDN
|
||||
*/
|
||||
HRESULT WINAPI VarIdiv(LPVARIANT left, LPVARIANT right, LPVARIANT result)
|
||||
{
|
||||
VARIANT lv, rv;
|
||||
HRESULT hr;
|
||||
|
||||
VariantInit(&lv);
|
||||
VariantInit(&rv);
|
||||
|
||||
if ((V_VT(left) == VT_NULL) || (V_VT(right) == VT_NULL)) {
|
||||
hr = VariantChangeType(result, result, 0, VT_NULL);
|
||||
if (FAILED(hr)) {
|
||||
/* This should never happen */
|
||||
FIXME("Failed to convert return value to VT_NULL.\n");
|
||||
return hr;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
hr = VariantChangeType(&lv, left, 0, VT_I4);
|
||||
if (FAILED(hr)) {
|
||||
return hr;
|
||||
}
|
||||
hr = VariantChangeType(&rv, right, 0, VT_I4);
|
||||
if (FAILED(hr)) {
|
||||
return hr;
|
||||
}
|
||||
|
||||
hr = VarDiv(&lv, &rv, result);
|
||||
return hr;
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* VarMod [OLEAUT32.154]
|
||||
* VarMod [OLEAUT32.155]
|
||||
*
|
||||
* Perform the modulus operation of the right hand variant on the left
|
||||
*
|
||||
|
|
|
@ -3990,6 +3990,8 @@ HRESULT WINAPI VarDecFromI4(LONG lIn, DECIMAL* pDecOut)
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
#define LOCALE_EN_US (MAKELCID(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),SORT_DEFAULT))
|
||||
|
||||
/************************************************************************
|
||||
* VarDecFromR4 (OLEAUT32.193)
|
||||
*
|
||||
|
@ -4007,7 +4009,7 @@ HRESULT WINAPI VarDecFromR4(FLOAT fltIn, DECIMAL* pDecOut)
|
|||
WCHAR buff[256];
|
||||
|
||||
sprintfW( buff, szFloatFormatW, fltIn );
|
||||
return _VarDecFromStr(buff, LOCALE_SYSTEM_DEFAULT, 0, pDecOut);
|
||||
return _VarDecFromStr(buff, LOCALE_EN_US, 0, pDecOut);
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
|
@ -4027,7 +4029,7 @@ HRESULT WINAPI VarDecFromR8(double dblIn, DECIMAL* pDecOut)
|
|||
WCHAR buff[256];
|
||||
|
||||
sprintfW( buff, szDoubleFormatW, dblIn );
|
||||
return _VarDecFromStr(buff, LOCALE_USER_DEFAULT, 0, pDecOut);
|
||||
return _VarDecFromStr(buff, LOCALE_EN_US, 0, pDecOut);
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
|
|
Loading…
Reference in a new issue