Revert "[OLEAUT32] Sync with Wine 3.0. CORE-14225"

This reverts commit 13fd286c18.

The "sync" zapped a lot of fixes, in particular 64 bit compatibility.
This commit is contained in:
Timo Kreuzer 2018-01-28 17:05:15 +01:00
parent 4a5b30ee1f
commit 2b57c9f47d
8 changed files with 659 additions and 474 deletions

View file

@ -100,7 +100,7 @@ static inline size_t bstr_alloc_size(size_t size)
static inline bstr_t *bstr_from_str(BSTR str) static inline bstr_t *bstr_from_str(BSTR str)
{ {
return CONTAINING_RECORD(str, bstr_t, u.str); return CONTAINING_RECORD((void *)str, bstr_t, u.str);
} }
static inline bstr_cache_entry_t *get_cache_entry_from_idx(unsigned cache_idx) static inline bstr_cache_entry_t *get_cache_entry_from_idx(unsigned cache_idx)

View file

@ -246,6 +246,18 @@ static void OLEPictureImpl_SetIcon(OLEPictureImpl * This)
} }
} }
static void OLEPictureImpl_SetEMF(OLEPictureImpl *This)
{
ENHMETAHEADER emh;
GetEnhMetaFileHeader(This->desc.u.emf.hemf, sizeof(emh), &emh);
This->origWidth = 0;
This->origHeight = 0;
This->himetricWidth = emh.rclFrame.right - emh.rclFrame.left;
This->himetricHeight = emh.rclFrame.bottom - emh.rclFrame.top;
}
/************************************************************************ /************************************************************************
* OLEPictureImpl_Construct * OLEPictureImpl_Construct
* *
@ -327,7 +339,11 @@ static OLEPictureImpl* OLEPictureImpl_Construct(LPPICTDESC pictDesc, BOOL fOwn)
case PICTYPE_ICON: case PICTYPE_ICON:
OLEPictureImpl_SetIcon(newObject); OLEPictureImpl_SetIcon(newObject);
break; break;
case PICTYPE_ENHMETAFILE: case PICTYPE_ENHMETAFILE:
OLEPictureImpl_SetEMF(newObject);
break;
default: default:
FIXME("Unsupported type %d\n", pictDesc->picType); FIXME("Unsupported type %d\n", pictDesc->picType);
newObject->himetricWidth = newObject->himetricHeight = 0; newObject->himetricWidth = newObject->himetricHeight = 0;
@ -813,19 +829,6 @@ static HRESULT WINAPI OLEPictureImpl_PictureChanged(IPicture *iface)
return S_OK; return S_OK;
} }
/************************************************************************
* OLEPictureImpl_SaveAsFile
*/
static HRESULT WINAPI OLEPictureImpl_SaveAsFile(IPicture *iface,
IStream *pstream,
BOOL SaveMemCopy,
LONG *pcbSize)
{
OLEPictureImpl *This = impl_from_IPicture(iface);
FIXME("(%p)->(%p, %d, %p), hacked stub.\n", This, pstream, SaveMemCopy, pcbSize);
return IStream_Write(pstream,This->data,This->datalen,(ULONG*)pcbSize);
}
/************************************************************************ /************************************************************************
* OLEPictureImpl_get_Attributes * OLEPictureImpl_get_Attributes
*/ */
@ -975,40 +978,13 @@ static HRESULT WINAPI OLEPictureImpl_IsDirty(
return E_NOTIMPL; return E_NOTIMPL;
} }
static HRESULT OLEPictureImpl_LoadDIB(OLEPictureImpl *This, BYTE *xbuf, ULONG xread)
{
BITMAPFILEHEADER *bfh = (BITMAPFILEHEADER*)xbuf;
BITMAPINFO *bi = (BITMAPINFO*)(bfh+1);
HDC hdcref;
/* Does not matter whether this is a coreheader or not, we only use
* components which are in both
*/
hdcref = GetDC(0);
This->desc.u.bmp.hbitmap = CreateDIBitmap(
hdcref,
&(bi->bmiHeader),
CBM_INIT,
xbuf+bfh->bfOffBits,
bi,
DIB_RGB_COLORS
);
ReleaseDC(0, hdcref);
if (This->desc.u.bmp.hbitmap == 0)
return E_FAIL;
This->desc.picType = PICTYPE_BITMAP;
OLEPictureImpl_SetBitmap(This);
return S_OK;
}
static HRESULT OLEPictureImpl_LoadWICSource(OLEPictureImpl *This, IWICBitmapSource *src) static HRESULT OLEPictureImpl_LoadWICSource(OLEPictureImpl *This, IWICBitmapSource *src)
{ {
HRESULT hr; HRESULT hr;
BITMAPINFOHEADER bih; BITMAPINFOHEADER bih;
HDC hdcref;
UINT width, height; UINT width, height;
UINT stride, buffersize; UINT stride, buffersize;
LPBYTE bits=NULL; BYTE *bits, *mask = NULL;
WICRect rc; WICRect rc;
IWICBitmapSource *real_source; IWICBitmapSource *real_source;
UINT x, y; UINT x, y;
@ -1036,34 +1012,28 @@ static HRESULT OLEPictureImpl_LoadWICSource(OLEPictureImpl *This, IWICBitmapSour
stride = 4 * width; stride = 4 * width;
buffersize = stride * height; buffersize = stride * height;
bits = HeapAlloc(GetProcessHeap(), 0, buffersize); mask = HeapAlloc(GetProcessHeap(), 0, buffersize);
if (!bits) if (!mask)
{ {
hr = E_OUTOFMEMORY; hr = E_OUTOFMEMORY;
goto end; goto end;
} }
This->desc.u.bmp.hbitmap = CreateDIBSection(0, (BITMAPINFO*)&bih, DIB_RGB_COLORS, (void **)&bits, NULL, 0);
if (This->desc.u.bmp.hbitmap == 0)
{
hr = E_FAIL;
goto end;
}
rc.X = 0; rc.X = 0;
rc.Y = 0; rc.Y = 0;
rc.Width = width; rc.Width = width;
rc.Height = height; rc.Height = height;
hr = IWICBitmapSource_CopyPixels(real_source, &rc, stride, buffersize, bits); hr = IWICBitmapSource_CopyPixels(real_source, &rc, stride, buffersize, bits);
if (FAILED(hr)) if (FAILED(hr))
goto end;
hdcref = GetDC(0);
This->desc.u.bmp.hbitmap = CreateDIBitmap(
hdcref,
&bih,
CBM_INIT,
bits,
(BITMAPINFO*)&bih,
DIB_RGB_COLORS);
if (This->desc.u.bmp.hbitmap == 0)
{ {
hr = E_FAIL; DeleteObject(This->desc.u.bmp.hbitmap);
ReleaseDC(0, hdcref);
goto end; goto end;
} }
@ -1077,23 +1047,25 @@ static HRESULT OLEPictureImpl_LoadWICSource(OLEPictureImpl *This, IWICBitmapSour
if((*pixel & 0x80000000) == 0) if((*pixel & 0x80000000) == 0)
{ {
has_alpha = TRUE; has_alpha = TRUE;
*pixel = black; *(DWORD *)(mask + stride * y + 4 * x) = black;
} }
else else
*pixel = white; *(DWORD *)(mask + stride * y + 4 * x) = white;
} }
} }
if (has_alpha) if (has_alpha)
{ {
HDC hdcBmp, hdcXor, hdcMask; HDC hdcref, hdcBmp, hdcXor, hdcMask;
HBITMAP hbmoldBmp, hbmoldXor, hbmoldMask; HBITMAP hbmoldBmp, hbmoldXor, hbmoldMask;
hdcref = GetDC(0);
This->hbmXor = CreateDIBitmap( This->hbmXor = CreateDIBitmap(
hdcref, hdcref,
&bih, &bih,
CBM_INIT, CBM_INIT,
bits, mask,
(BITMAPINFO*)&bih, (BITMAPINFO*)&bih,
DIB_RGB_COLORS DIB_RGB_COLORS
); );
@ -1118,12 +1090,11 @@ static HRESULT OLEPictureImpl_LoadWICSource(OLEPictureImpl *This, IWICBitmapSour
DeleteDC(hdcBmp); DeleteDC(hdcBmp);
DeleteDC(hdcXor); DeleteDC(hdcXor);
DeleteDC(hdcMask); DeleteDC(hdcMask);
ReleaseDC(0, hdcref);
} }
ReleaseDC(0, hdcref);
end: end:
HeapFree(GetProcessHeap(), 0, bits); HeapFree(GetProcessHeap(), 0, mask);
IWICBitmapSource_Release(real_source); IWICBitmapSource_Release(real_source);
return hr; return hr;
} }
@ -1487,7 +1458,7 @@ static HRESULT WINAPI OLEPictureImpl_Load(IPersistStream* iface, IStream *pStm)
hr = OLEPictureImpl_LoadWICDecoder(This, &CLSID_WICJpegDecoder, xbuf, xread); hr = OLEPictureImpl_LoadWICDecoder(This, &CLSID_WICJpegDecoder, xbuf, xread);
break; break;
case BITMAP_FORMAT_BMP: /* Bitmap */ case BITMAP_FORMAT_BMP: /* Bitmap */
hr = OLEPictureImpl_LoadDIB(This, xbuf, xread); hr = OLEPictureImpl_LoadWICDecoder(This, &CLSID_WICBmpDecoder, xbuf, xread);
break; break;
case BITMAP_FORMAT_PNG: /* PNG */ case BITMAP_FORMAT_PNG: /* PNG */
hr = OLEPictureImpl_LoadWICDecoder(This, &CLSID_WICPngDecoder, xbuf, xread); hr = OLEPictureImpl_LoadWICDecoder(This, &CLSID_WICPngDecoder, xbuf, xread);
@ -1742,6 +1713,17 @@ static BOOL serializeIcon(HICON hIcon, void ** ppBuffer, unsigned int * pLength)
return success; return success;
} }
static BOOL serializeEMF(HENHMETAFILE hemf, void **buf, unsigned *size)
{
*size = GetEnhMetaFileBits(hemf, 0, NULL);
if (!*size) return FALSE;
*buf = HeapAlloc(GetProcessHeap(), 0, *size);
if (!*buf) return FALSE;
return GetEnhMetaFileBits(hemf, *size, *buf) != 0;
}
static HRESULT WINAPI OLEPictureImpl_Save( static HRESULT WINAPI OLEPictureImpl_Save(
IPersistStream* iface,IStream*pStm,BOOL fClearDirty) IPersistStream* iface,IStream*pStm,BOOL fClearDirty)
{ {
@ -1817,12 +1799,31 @@ static HRESULT WINAPI OLEPictureImpl_Save(
IStream_Write(pStm, This->data, This->datalen, &dummy); IStream_Write(pStm, This->data, This->datalen, &dummy);
hResult = S_OK; hResult = S_OK;
break; break;
case PICTYPE_ENHMETAFILE:
if (This->bIsDirty || !This->data)
{
serializeResult = serializeEMF(This->desc.u.emf.hemf, &pIconData, &iDataSize);
if (!serializeResult)
{
hResult = E_FAIL;
break;
}
HeapFree(GetProcessHeap(), 0, This->data);
This->data = pIconData;
This->datalen = iDataSize;
}
header[0] = 0x0000746c;
header[1] = This->datalen;
IStream_Write(pStm, header, 2 * sizeof(DWORD), &dummy);
IStream_Write(pStm, This->data, This->datalen, &dummy);
hResult = S_OK;
break;
case PICTYPE_METAFILE: case PICTYPE_METAFILE:
FIXME("(%p,%p,%d), PICTYPE_METAFILE not implemented!\n",This,pStm,fClearDirty); FIXME("(%p,%p,%d), PICTYPE_METAFILE not implemented!\n",This,pStm,fClearDirty);
break; break;
case PICTYPE_ENHMETAFILE:
FIXME("(%p,%p,%d),PICTYPE_ENHMETAFILE not implemented!\n",This,pStm,fClearDirty);
break;
default: default:
FIXME("(%p,%p,%d), [unknown type] not implemented!\n",This,pStm,fClearDirty); FIXME("(%p,%p,%d), [unknown type] not implemented!\n",This,pStm,fClearDirty);
break; break;
@ -1839,6 +1840,98 @@ static HRESULT WINAPI OLEPictureImpl_GetSizeMax(
return E_NOTIMPL; return E_NOTIMPL;
} }
/************************************************************************
* OLEPictureImpl_SaveAsFile
*/
static HRESULT WINAPI OLEPictureImpl_SaveAsFile(IPicture *iface,
IStream *stream, BOOL mem_copy, LONG *size)
{
OLEPictureImpl *This = impl_from_IPicture(iface);
void *data;
unsigned data_size;
ULONG written;
HRESULT hr;
FIXME("(%p)->(%p,%d,%p): semi-stub\n", This, stream, mem_copy, size);
switch (This->desc.picType)
{
case PICTYPE_NONE:
return S_OK;
case PICTYPE_ICON:
if (!mem_copy) return E_FAIL;
if (This->bIsDirty || !This->data)
{
if (!serializeIcon(This->desc.u.icon.hicon, &data, &data_size))
return E_FAIL;
HeapFree(GetProcessHeap(), 0, This->data);
This->data = data;
This->datalen = data_size;
}
hr = IStream_Write(stream, This->data, This->datalen, &written);
if (hr == S_OK && size) *size = written;
return hr;
case PICTYPE_BITMAP:
if (!mem_copy) return E_FAIL;
if (This->bIsDirty || !This->data)
{
switch (This->keepOrigFormat ? This->loadtime_format : BITMAP_FORMAT_BMP)
{
case BITMAP_FORMAT_BMP:
if (!serializeBMP(This->desc.u.bmp.hbitmap, &data, &data_size))
return E_FAIL;
break;
case BITMAP_FORMAT_JPEG:
FIXME("BITMAP_FORMAT_JPEG is not implemented\n");
return E_NOTIMPL;
case BITMAP_FORMAT_GIF:
FIXME("BITMAP_FORMAT_GIF is not implemented\n");
return E_NOTIMPL;
case BITMAP_FORMAT_PNG:
FIXME("BITMAP_FORMAT_PNG is not implemented\n");
return E_NOTIMPL;
default:
FIXME("PICTYPE_BITMAP/%#x is not implemented\n", This->loadtime_format);
return E_NOTIMPL;
}
HeapFree(GetProcessHeap(), 0, This->data);
This->data = data;
This->datalen = data_size;
}
hr = IStream_Write(stream, This->data, This->datalen, &written);
if (hr == S_OK && size) *size = written;
return hr;
case PICTYPE_METAFILE:
FIXME("PICTYPE_METAFILE is not implemented\n");
return E_NOTIMPL;
case PICTYPE_ENHMETAFILE:
if (!mem_copy) return E_FAIL;
if (This->bIsDirty || !This->data)
{
if (!serializeEMF(This->desc.u.emf.hemf, &data, &data_size))
return E_FAIL;
HeapFree(GetProcessHeap(), 0, This->data);
This->data = data;
This->datalen = data_size;
}
hr = IStream_Write(stream, This->data, This->datalen, &written);
if (hr == S_OK && size) *size = written;
return hr;
default:
FIXME("%#x is not implemented\n", This->desc.picType);
break;
}
return E_NOTIMPL;
}
/************************************************************************ /************************************************************************
* IDispatch * IDispatch
@ -2295,13 +2388,70 @@ HRESULT WINAPI OleLoadPictureEx( LPSTREAM lpstream, LONG lSize, BOOL fRunmode,
return hr; return hr;
} }
static HRESULT create_stream(const WCHAR *filename, IStream **stream)
{
HANDLE hFile;
DWORD dwFileSize;
HGLOBAL hGlobal = NULL;
DWORD dwBytesRead;
HRESULT hr = S_OK;
hFile = CreateFileW(filename, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
if (hFile == INVALID_HANDLE_VALUE)
return HRESULT_FROM_WIN32(GetLastError());
dwFileSize = GetFileSize(hFile, NULL);
if (dwFileSize != INVALID_FILE_SIZE)
{
hGlobal = GlobalAlloc(GMEM_FIXED, dwFileSize);
if (!hGlobal)
hr = E_OUTOFMEMORY;
else
{
if (!ReadFile(hFile, hGlobal, dwFileSize, &dwBytesRead, NULL))
{
GlobalFree(hGlobal);
hr = HRESULT_FROM_WIN32(GetLastError());
}
}
}
CloseHandle(hFile);
if (FAILED(hr)) return hr;
hr = CreateStreamOnHGlobal(hGlobal, TRUE, stream);
if (FAILED(hr))
GlobalFree(hGlobal);
return hr;
}
/*********************************************************************** /***********************************************************************
* OleLoadPictureFile (OLEAUT32.422) * OleLoadPictureFile (OLEAUT32.422)
*/ */
HRESULT WINAPI OleLoadPictureFile(VARIANT file, LPDISPATCH *picture) HRESULT WINAPI OleLoadPictureFile(VARIANT filename, IDispatch **picture)
{ {
FIXME("(%s %p): stub\n", wine_dbgstr_variant(&file), picture); IStream *stream;
return E_NOTIMPL; HRESULT hr;
TRACE("(%s,%p)\n", wine_dbgstr_variant(&filename), picture);
if (V_VT(&filename) != VT_BSTR)
return CTL_E_FILENOTFOUND;
hr = create_stream(V_BSTR(&filename), &stream);
if (hr != S_OK)
{
if (hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND))
return CTL_E_FILENOTFOUND;
return CTL_E_PATHFILEACCESSERROR;
}
hr = OleLoadPicture(stream, 0, FALSE, &IID_IDispatch, (void **)picture);
IStream_Release(stream);
return hr;
} }
/*********************************************************************** /***********************************************************************
@ -2321,16 +2471,8 @@ HRESULT WINAPI OleLoadPicturePath( LPOLESTR szURLorPath, LPUNKNOWN punkCaller,
LPVOID *ppvRet ) LPVOID *ppvRet )
{ {
static const WCHAR file[] = { 'f','i','l','e',':',0 }; static const WCHAR file[] = { 'f','i','l','e',':',0 };
IPicture *ipicture;
HANDLE hFile;
DWORD dwFileSize;
HGLOBAL hGlobal = NULL;
DWORD dwBytesRead;
IStream *stream; IStream *stream;
BOOL bRead;
IPersistStream *pStream;
HRESULT hRes; HRESULT hRes;
HRESULT init_res;
WCHAR *file_candidate; WCHAR *file_candidate;
WCHAR path_buf[MAX_PATH]; WCHAR path_buf[MAX_PATH];
@ -2358,36 +2500,9 @@ HRESULT WINAPI OleLoadPicturePath( LPOLESTR szURLorPath, LPUNKNOWN punkCaller,
/* Handle candidate DOS paths separately. */ /* Handle candidate DOS paths separately. */
if (file_candidate[1] == ':') { if (file_candidate[1] == ':') {
hFile = CreateFileW(file_candidate, GENERIC_READ, 0, NULL, OPEN_EXISTING, hRes = create_stream(file_candidate, &stream);
0, NULL); if (FAILED(hRes))
if (hFile == INVALID_HANDLE_VALUE)
return INET_E_RESOURCE_NOT_FOUND;
dwFileSize = GetFileSize(hFile, NULL);
if (dwFileSize != INVALID_FILE_SIZE )
{
hGlobal = GlobalAlloc(GMEM_FIXED,dwFileSize);
if ( hGlobal)
{
bRead = ReadFile(hFile, hGlobal, dwFileSize, &dwBytesRead, NULL) && dwBytesRead == dwFileSize;
if (!bRead)
{
GlobalFree(hGlobal);
hGlobal = 0;
}
}
}
CloseHandle(hFile);
if (!hGlobal)
return INET_E_RESOURCE_NOT_FOUND; return INET_E_RESOURCE_NOT_FOUND;
hRes = CreateStreamOnHGlobal(hGlobal, TRUE, &stream);
if (FAILED(hRes))
{
GlobalFree(hGlobal);
return hRes;
}
} else { } else {
IMoniker *pmnk; IMoniker *pmnk;
IBindCtx *pbc; IBindCtx *pbc;
@ -2407,32 +2522,10 @@ HRESULT WINAPI OleLoadPicturePath( LPOLESTR szURLorPath, LPUNKNOWN punkCaller,
return hRes; return hRes;
} }
init_res = CoInitialize(NULL); hRes = OleLoadPicture(stream, 0, FALSE, riid, ppvRet);
hRes = CoCreateInstance(&CLSID_StdPicture, punkCaller, CLSCTX_INPROC_SERVER,
&IID_IPicture, (LPVOID*)&ipicture);
if (SUCCEEDED(hRes)) {
hRes = IPicture_QueryInterface(ipicture, &IID_IPersistStream, (LPVOID*)&pStream);
if (SUCCEEDED(hRes)) {
hRes = IPersistStream_Load(pStream, stream);
if (SUCCEEDED(hRes)) {
hRes = IPicture_QueryInterface(ipicture, riid, ppvRet);
if (FAILED(hRes))
ERR("Failed to get interface %s from IPicture.\n", debugstr_guid(riid));
}
IPersistStream_Release(pStream);
}
IPicture_Release(ipicture);
}
IStream_Release(stream); IStream_Release(stream);
if (SUCCEEDED(init_res))
CoUninitialize();
return hRes; return hRes;
} }

View file

@ -471,7 +471,6 @@ static HRESULT num_of_funcs(ITypeInfo *tinfo, unsigned int *num,
#ifdef __i386__ #ifdef __i386__
#include "pshpack1.h" #include "pshpack1.h"
typedef struct _TMAsmProxy { typedef struct _TMAsmProxy {
DWORD lealeax; DWORD lealeax;
BYTE pushleax; BYTE pushleax;
@ -483,7 +482,30 @@ typedef struct _TMAsmProxy {
WORD bytestopop; WORD bytestopop;
WORD nop; WORD nop;
} TMAsmProxy; } TMAsmProxy;
#include "poppack.h"
#elif defined(__x86_64__)
#include "pshpack1.h"
typedef struct _TMAsmProxy {
BYTE pushq_rbp;
BYTE movq_rsp_rbp[3];
DWORD subq_0x20_rsp;
DWORD movq_rcx_0x10rbp;
DWORD movq_rdx_0x18rbp;
DWORD movq_r8_0x20rbp;
DWORD movq_r9_0x28rbp;
BYTE movq_rcx[3];
DWORD nr;
DWORD leaq_0x10rbp_rdx;
WORD movq_rax;
void *xcall;
WORD callq_rax;
BYTE movq_rbp_rsp[3];
BYTE popq_rbp;
BYTE ret;
DWORD nop;
} TMAsmProxy;
#include "poppack.h" #include "poppack.h"
#else /* __i386__ */ #else /* __i386__ */
@ -619,42 +641,51 @@ static const IRpcProxyBufferVtbl tmproxyvtable = {
TMProxyImpl_Disconnect TMProxyImpl_Disconnect
}; };
/* how much space do we use on stack in DWORD steps. */ /* how much space do we use on stack in DWORD_PTR steps. */
static int static int
_argsize(TYPEDESC *tdesc, ITypeInfo *tinfo) { _argsize(TYPEDESC *tdesc, ITypeInfo *tinfo) {
DWORD ret;
switch (tdesc->vt) { switch (tdesc->vt) {
case VT_I8: case VT_I8:
case VT_UI8: case VT_UI8:
return 8/sizeof(DWORD); ret = 8;
break;
case VT_R8: case VT_R8:
return sizeof(double)/sizeof(DWORD); ret = sizeof(double);
break;
case VT_CY: case VT_CY:
return sizeof(CY)/sizeof(DWORD); ret = sizeof(CY);
break;
case VT_DATE: case VT_DATE:
return sizeof(DATE)/sizeof(DWORD); ret = sizeof(DATE);
break;
case VT_DECIMAL: case VT_DECIMAL:
return (sizeof(DECIMAL)+3)/sizeof(DWORD); ret = sizeof(DECIMAL);
break;
case VT_VARIANT: case VT_VARIANT:
return (sizeof(VARIANT)+3)/sizeof(DWORD); ret = sizeof(VARIANT);
break;
case VT_USERDEFINED: case VT_USERDEFINED:
{ {
ITypeInfo *tinfo2; ITypeInfo *tinfo2;
TYPEATTR *tattr; TYPEATTR *tattr;
HRESULT hres; HRESULT hres;
DWORD ret;
hres = ITypeInfo_GetRefTypeInfo(tinfo,tdesc->u.hreftype,&tinfo2); hres = ITypeInfo_GetRefTypeInfo(tinfo,tdesc->u.hreftype,&tinfo2);
if (FAILED(hres)) if (FAILED(hres))
return 0; /* should fail critically in serialize_param */ return 0; /* should fail critically in serialize_param */
ITypeInfo_GetTypeAttr(tinfo2,&tattr); ITypeInfo_GetTypeAttr(tinfo2,&tattr);
ret = (tattr->cbSizeInstance+3)/sizeof(DWORD); ret = tattr->cbSizeInstance;
ITypeInfo_ReleaseTypeAttr(tinfo2, tattr); ITypeInfo_ReleaseTypeAttr(tinfo2, tattr);
ITypeInfo_Release(tinfo2); ITypeInfo_Release(tinfo2);
return ret; break;
} }
default: default:
return 1; ret = sizeof(DWORD_PTR);
break;
} }
return (ret + sizeof(DWORD_PTR) - 1) / sizeof(DWORD_PTR);
} }
/* how much space do we use on the heap (in bytes) */ /* how much space do we use on the heap (in bytes) */
@ -703,7 +734,7 @@ _xsize(const TYPEDESC *td, ITypeInfo *tinfo) {
return ret; return ret;
} }
default: default:
return 4; return sizeof(DWORD_PTR);
} }
} }
@ -722,7 +753,7 @@ serialize_param(
BOOL debugout, BOOL debugout,
BOOL dealloc, BOOL dealloc,
TYPEDESC *tdesc, TYPEDESC *tdesc,
DWORD *arg, DWORD_PTR *arg,
marshal_state *buf) marshal_state *buf)
{ {
HRESULT hres = S_OK; HRESULT hres = S_OK;
@ -741,7 +772,7 @@ serialize_param(
case VT_R8: case VT_R8:
case VT_CY: case VT_CY:
hres = S_OK; hres = S_OK;
if (debugout) TRACE_(olerelay)("%x%x\n",arg[0],arg[1]); if (debugout) TRACE_(olerelay)("%s\n", wine_dbgstr_longlong(*(ULONGLONG *)arg));
if (writeit) if (writeit)
hres = xbuf_add(buf,(LPBYTE)arg,8); hres = xbuf_add(buf,(LPBYTE)arg,8);
return hres; return hres;
@ -752,7 +783,7 @@ serialize_param(
case VT_R4: case VT_R4:
case VT_UI4: case VT_UI4:
hres = S_OK; hres = S_OK;
if (debugout) TRACE_(olerelay)("%x\n",*arg); if (debugout) TRACE_(olerelay)("%x\n", *(DWORD *)arg);
if (writeit) if (writeit)
hres = xbuf_add(buf,(LPBYTE)arg,sizeof(DWORD)); hres = xbuf_add(buf,(LPBYTE)arg,sizeof(DWORD));
return hres; return hres;
@ -760,14 +791,14 @@ serialize_param(
case VT_UI2: case VT_UI2:
case VT_BOOL: case VT_BOOL:
hres = S_OK; hres = S_OK;
if (debugout) TRACE_(olerelay)("%04x\n",*arg & 0xffff); if (debugout) TRACE_(olerelay)("%04x\n", *(WORD *)arg);
if (writeit) if (writeit)
hres = xbuf_add(buf,(LPBYTE)arg,sizeof(DWORD)); hres = xbuf_add(buf,(LPBYTE)arg,sizeof(DWORD));
return hres; return hres;
case VT_I1: case VT_I1:
case VT_UI1: case VT_UI1:
hres = S_OK; hres = S_OK;
if (debugout) TRACE_(olerelay)("%02x\n",*arg & 0xff); if (debugout) TRACE_(olerelay)("%02x\n", *(BYTE *)arg);
if (writeit) if (writeit)
hres = xbuf_add(buf,(LPBYTE)arg,sizeof(DWORD)); hres = xbuf_add(buf,(LPBYTE)arg,sizeof(DWORD));
return hres; return hres;
@ -837,7 +868,9 @@ serialize_param(
return hres; return hres;
} }
ITypeInfo_GetTypeAttr(tinfo2,&tattr); ITypeInfo_GetTypeAttr(tinfo2,&tattr);
derefhere = (tattr->typekind != TKIND_DISPATCH && tattr->typekind != TKIND_INTERFACE); derefhere = (tattr->typekind != TKIND_DISPATCH &&
tattr->typekind != TKIND_INTERFACE &&
tattr->typekind != TKIND_COCLASS);
} }
break; break;
case TKIND_ENUM: /* confirmed */ case TKIND_ENUM: /* confirmed */
@ -845,6 +878,7 @@ serialize_param(
break; break;
case TKIND_DISPATCH: /* will be done in VT_USERDEFINED case */ case TKIND_DISPATCH: /* will be done in VT_USERDEFINED case */
case TKIND_INTERFACE: /* will be done in VT_USERDEFINED case */ case TKIND_INTERFACE: /* will be done in VT_USERDEFINED case */
case TKIND_COCLASS: /* will be done in VT_USERDEFINED case */
derefhere=FALSE; derefhere=FALSE;
break; break;
default: default:
@ -867,19 +901,19 @@ serialize_param(
if (debugout) TRACE_(olerelay)("NULL"); if (debugout) TRACE_(olerelay)("NULL");
return S_OK; return S_OK;
} }
hres = serialize_param(tinfo,writeit,debugout,dealloc,tdesc->u.lptdesc,(DWORD*)*arg,buf); hres = serialize_param(tinfo,writeit,debugout,dealloc,tdesc->u.lptdesc,(DWORD_PTR *)*arg,buf);
if (derefhere && dealloc) HeapFree(GetProcessHeap(),0,(LPVOID)*arg); if (derefhere && dealloc) HeapFree(GetProcessHeap(),0,(LPVOID)*arg);
return hres; return hres;
} }
case VT_UNKNOWN: case VT_UNKNOWN:
if (debugout) TRACE_(olerelay)("unk(0x%x)",*arg); if (debugout) TRACE_(olerelay)("unk(0x%lx)", *arg);
if (writeit) if (writeit)
hres = _marshal_interface(buf,&IID_IUnknown,(LPUNKNOWN)*arg); hres = _marshal_interface(buf,&IID_IUnknown,(LPUNKNOWN)*arg);
if (dealloc && *(IUnknown **)arg) if (dealloc && *(IUnknown **)arg)
IUnknown_Release((LPUNKNOWN)*arg); IUnknown_Release((LPUNKNOWN)*arg);
return hres; return hres;
case VT_DISPATCH: case VT_DISPATCH:
if (debugout) TRACE_(olerelay)("idisp(0x%x)",*arg); if (debugout) TRACE_(olerelay)("idisp(0x%lx)", *arg);
if (writeit) if (writeit)
hres = _marshal_interface(buf,&IID_IDispatch,(LPUNKNOWN)*arg); hres = _marshal_interface(buf,&IID_IDispatch,(LPUNKNOWN)*arg);
if (dealloc && *(IUnknown **)arg) if (dealloc && *(IUnknown **)arg)
@ -906,6 +940,36 @@ serialize_param(
if (dealloc) if (dealloc)
IUnknown_Release((LPUNKNOWN)arg); IUnknown_Release((LPUNKNOWN)arg);
break; break;
case TKIND_COCLASS: {
GUID iid = tattr->guid;
unsigned int i;
int type_flags;
for(i = 0; i < tattr->cImplTypes; i++) {
if(SUCCEEDED(ITypeInfo_GetImplTypeFlags(tinfo2, i, &type_flags)) &&
type_flags == (IMPLTYPEFLAG_FSOURCE|IMPLTYPEFLAG_FDEFAULT)) {
ITypeInfo *tinfo3;
TYPEATTR *tattr2;
HREFTYPE href;
if(FAILED(ITypeInfo_GetRefTypeOfImplType(tinfo2, i, &href)))
break;
if(FAILED(ITypeInfo_GetRefTypeInfo(tinfo2, href, &tinfo3)))
break;
if(SUCCEEDED(ITypeInfo_GetTypeAttr(tinfo3, &tattr2))) {
iid = tattr2->guid;
ITypeInfo_ReleaseTypeAttr(tinfo3, tattr2);
}
ITypeInfo_Release(tinfo3);
break;
}
}
if(writeit)
hres=_marshal_interface(buf, &iid, (LPUNKNOWN)arg);
if(dealloc)
IUnknown_Release((LPUNKNOWN)arg);
break;
}
case TKIND_RECORD: { case TKIND_RECORD: {
int i; int i;
if (debugout) TRACE_(olerelay)("{"); if (debugout) TRACE_(olerelay)("{");
@ -927,7 +991,7 @@ serialize_param(
debugout, debugout,
dealloc, dealloc,
tdesc2, tdesc2,
(DWORD*)(((LPBYTE)arg)+vdesc->u.oInst), (DWORD_PTR *)(((LPBYTE)arg)+vdesc->u.oInst),
buf buf
); );
ITypeInfo_ReleaseVarDesc(tinfo2, vdesc); ITypeInfo_ReleaseVarDesc(tinfo2, vdesc);
@ -944,7 +1008,7 @@ serialize_param(
break; break;
case TKIND_ENUM: case TKIND_ENUM:
hres = S_OK; hres = S_OK;
if (debugout) TRACE_(olerelay)("%x",*arg); if (debugout) TRACE_(olerelay)("%x", *(DWORD *)arg);
if (writeit) if (writeit)
hres = xbuf_add(buf,(LPBYTE)arg,sizeof(DWORD)); hres = xbuf_add(buf,(LPBYTE)arg,sizeof(DWORD));
break; break;
@ -970,7 +1034,7 @@ serialize_param(
if (debugout) TRACE_(olerelay)("["); if (debugout) TRACE_(olerelay)("[");
for (i=0;i<arrsize;i++) { for (i=0;i<arrsize;i++) {
LPBYTE base = _passbyref(&adesc->tdescElem, tinfo) ? (LPBYTE) *arg : (LPBYTE) arg; LPBYTE base = _passbyref(&adesc->tdescElem, tinfo) ? (LPBYTE) *arg : (LPBYTE) arg;
hres = serialize_param(tinfo, writeit, debugout, dealloc, &adesc->tdescElem, (DWORD*)((LPBYTE)base+i*_xsize(&adesc->tdescElem, tinfo)), buf); hres = serialize_param(tinfo, writeit, debugout, dealloc, &adesc->tdescElem, (DWORD_PTR *)((LPBYTE)base+i*_xsize(&adesc->tdescElem, tinfo)), buf);
if (hres) if (hres)
return hres; return hres;
if (debugout && (i<arrsize-1)) TRACE_(olerelay)(","); if (debugout && (i<arrsize-1)) TRACE_(olerelay)(",");
@ -1009,7 +1073,7 @@ deserialize_param(
BOOL debugout, BOOL debugout,
BOOL alloc, BOOL alloc,
TYPEDESC *tdesc, TYPEDESC *tdesc,
DWORD *arg, DWORD_PTR *arg,
marshal_state *buf) marshal_state *buf)
{ {
HRESULT hres = S_OK; HRESULT hres = S_OK;
@ -1042,7 +1106,7 @@ deserialize_param(
hres = xbuf_get(buf,(LPBYTE)arg,8); hres = xbuf_get(buf,(LPBYTE)arg,8);
if (hres) ERR("Failed to read integer 8 byte\n"); if (hres) ERR("Failed to read integer 8 byte\n");
} }
if (debugout) TRACE_(olerelay)("%x%x",arg[0],arg[1]); if (debugout) TRACE_(olerelay)("%s", wine_dbgstr_longlong(*(ULONGLONG *)arg));
return hres; return hres;
case VT_ERROR: case VT_ERROR:
case VT_I4: case VT_I4:
@ -1054,7 +1118,7 @@ deserialize_param(
hres = xbuf_get(buf,(LPBYTE)arg,sizeof(DWORD)); hres = xbuf_get(buf,(LPBYTE)arg,sizeof(DWORD));
if (hres) ERR("Failed to read integer 4 byte\n"); if (hres) ERR("Failed to read integer 4 byte\n");
} }
if (debugout) TRACE_(olerelay)("%x",*arg); if (debugout) TRACE_(olerelay)("%x", *(DWORD *)arg);
return hres; return hres;
case VT_I2: case VT_I2:
case VT_UI2: case VT_UI2:
@ -1065,7 +1129,7 @@ deserialize_param(
if (hres) ERR("Failed to read integer 4 byte\n"); if (hres) ERR("Failed to read integer 4 byte\n");
else memcpy(arg,&x,2); else memcpy(arg,&x,2);
} }
if (debugout) TRACE_(olerelay)("%04x",*arg & 0xffff); if (debugout) TRACE_(olerelay)("%04x", *(WORD *)arg);
return hres; return hres;
case VT_I1: case VT_I1:
case VT_UI1: case VT_UI1:
@ -1075,7 +1139,7 @@ deserialize_param(
if (hres) ERR("Failed to read integer 4 byte\n"); if (hres) ERR("Failed to read integer 4 byte\n");
else memcpy(arg,&x,1); else memcpy(arg,&x,1);
} }
if (debugout) TRACE_(olerelay)("%02x",*arg & 0xff); if (debugout) TRACE_(olerelay)("%02x", *(BYTE *)arg);
return hres; return hres;
case VT_BSTR: { case VT_BSTR: {
if (readit) if (readit)
@ -1115,7 +1179,9 @@ deserialize_param(
return hres; return hres;
} }
ITypeInfo_GetTypeAttr(tinfo2,&tattr); ITypeInfo_GetTypeAttr(tinfo2,&tattr);
derefhere = (tattr->typekind != TKIND_DISPATCH && tattr->typekind != TKIND_INTERFACE); derefhere = (tattr->typekind != TKIND_DISPATCH &&
tattr->typekind != TKIND_INTERFACE &&
tattr->typekind != TKIND_COCLASS);
} }
break; break;
case TKIND_ENUM: /* confirmed */ case TKIND_ENUM: /* confirmed */
@ -1123,6 +1189,7 @@ deserialize_param(
break; break;
case TKIND_DISPATCH: /* will be done in VT_USERDEFINED case */ case TKIND_DISPATCH: /* will be done in VT_USERDEFINED case */
case TKIND_INTERFACE: /* will be done in VT_USERDEFINED case */ case TKIND_INTERFACE: /* will be done in VT_USERDEFINED case */
case TKIND_COCLASS: /* will be done in VT_USERDEFINED case */
derefhere=FALSE; derefhere=FALSE;
break; break;
default: default:
@ -1151,17 +1218,17 @@ deserialize_param(
if (alloc) { if (alloc) {
/* Allocate space for the referenced struct */ /* Allocate space for the referenced struct */
if (derefhere) if (derefhere)
*arg=(DWORD)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,_xsize(tdesc->u.lptdesc, tinfo)); *arg=(DWORD_PTR)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,_xsize(tdesc->u.lptdesc, tinfo));
} }
if (derefhere) if (derefhere)
return deserialize_param(tinfo, readit, debugout, alloc, tdesc->u.lptdesc, (LPDWORD)*arg, buf); return deserialize_param(tinfo, readit, debugout, alloc, tdesc->u.lptdesc, (DWORD_PTR *)*arg, buf);
else else
return deserialize_param(tinfo, readit, debugout, alloc, tdesc->u.lptdesc, arg, buf); return deserialize_param(tinfo, readit, debugout, alloc, tdesc->u.lptdesc, arg, buf);
} }
case VT_UNKNOWN: case VT_UNKNOWN:
/* FIXME: UNKNOWN is unknown ..., but allocate 4 byte for it */ /* FIXME: UNKNOWN is unknown ..., but allocate 4 byte for it */
if (alloc) if (alloc)
*arg=(DWORD)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(DWORD)); *arg=(DWORD_PTR)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(DWORD_PTR));
hres = S_OK; hres = S_OK;
if (readit) if (readit)
hres = _unmarshal_interface(buf,&IID_IUnknown,(LPUNKNOWN*)arg); hres = _unmarshal_interface(buf,&IID_IUnknown,(LPUNKNOWN*)arg);
@ -1197,6 +1264,34 @@ deserialize_param(
if (readit) if (readit)
hres = _unmarshal_interface(buf,&(tattr->guid),(LPUNKNOWN*)arg); hres = _unmarshal_interface(buf,&(tattr->guid),(LPUNKNOWN*)arg);
break; break;
case TKIND_COCLASS: {
GUID iid = tattr->guid;
unsigned int i;
int type_flags;
for(i = 0; i < tattr->cImplTypes; i++) {
if(SUCCEEDED(ITypeInfo_GetImplTypeFlags(tinfo2, i, &type_flags)) &&
type_flags == (IMPLTYPEFLAG_FSOURCE|IMPLTYPEFLAG_FDEFAULT)) {
ITypeInfo *tinfo3;
TYPEATTR *tattr2;
HREFTYPE href;
if(FAILED(ITypeInfo_GetRefTypeOfImplType(tinfo2, i, &href)))
break;
if(FAILED(ITypeInfo_GetRefTypeInfo(tinfo2, href, &tinfo3)))
break;
if(SUCCEEDED(ITypeInfo_GetTypeAttr(tinfo3, &tattr2))) {
iid = tattr2->guid;
ITypeInfo_ReleaseTypeAttr(tinfo3, tattr2);
}
ITypeInfo_Release(tinfo3);
break;
}
}
if(readit)
hres = _unmarshal_interface(buf, &iid, (LPUNKNOWN*)arg);
break;
}
case TKIND_RECORD: { case TKIND_RECORD: {
int i; int i;
@ -1217,7 +1312,7 @@ deserialize_param(
debugout, debugout,
alloc, alloc,
&vdesc->elemdescVar.tdesc, &vdesc->elemdescVar.tdesc,
(DWORD*)(((LPBYTE)arg)+vdesc->u.oInst), (DWORD_PTR *)(((LPBYTE)arg)+vdesc->u.oInst),
buf buf
); );
ITypeInfo_ReleaseVarDesc(tinfo2, vdesc); ITypeInfo_ReleaseVarDesc(tinfo2, vdesc);
@ -1234,7 +1329,7 @@ deserialize_param(
hres = xbuf_get(buf,(LPBYTE)arg,sizeof(DWORD)); hres = xbuf_get(buf,(LPBYTE)arg,sizeof(DWORD));
if (hres) ERR("Failed to read enum (4 byte)\n"); if (hres) ERR("Failed to read enum (4 byte)\n");
} }
if (debugout) TRACE_(olerelay)("%x",*arg); if (debugout) TRACE_(olerelay)("%x", *(DWORD *)arg);
break; break;
default: default:
ERR("Unhandled typekind %d\n",tattr->typekind); ERR("Unhandled typekind %d\n",tattr->typekind);
@ -1260,7 +1355,7 @@ deserialize_param(
if (_passbyref(&adesc->tdescElem, tinfo)) if (_passbyref(&adesc->tdescElem, tinfo))
{ {
base = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,_xsize(tdesc->u.lptdesc, tinfo) * arrsize); base = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,_xsize(tdesc->u.lptdesc, tinfo) * arrsize);
*arg = (DWORD) base; *arg = (DWORD_PTR)base;
} }
for (i=0;i<arrsize;i++) for (i=0;i<arrsize;i++)
deserialize_param( deserialize_param(
@ -1269,7 +1364,7 @@ deserialize_param(
debugout, debugout,
alloc, alloc,
&adesc->tdescElem, &adesc->tdescElem,
(DWORD*)(base + i*_xsize(&adesc->tdescElem, tinfo)), (DWORD_PTR *)(base + i*_xsize(&adesc->tdescElem, tinfo)),
buf buf
); );
return S_OK; return S_OK;
@ -1399,7 +1494,7 @@ static inline BOOL is_out_elem(const ELEMDESC *elem)
static DWORD WINAPI xCall(int method, void **args) static DWORD WINAPI xCall(int method, void **args)
{ {
TMProxyImpl *tpinfo = args[0]; TMProxyImpl *tpinfo = args[0];
DWORD *xargs; DWORD_PTR *xargs;
const FUNCDESC *fdesc; const FUNCDESC *fdesc;
HRESULT hres; HRESULT hres;
int i; int i;
@ -1459,7 +1554,7 @@ static DWORD WINAPI xCall(int method, void **args)
if (nrofnames > sizeof(names)/sizeof(names[0])) if (nrofnames > sizeof(names)/sizeof(names[0]))
ERR("Need more names!\n"); ERR("Need more names!\n");
xargs = (DWORD *)(args + 1); xargs = (DWORD_PTR *)(args + 1);
for (i=0;i<fdesc->cParams;i++) { for (i=0;i<fdesc->cParams;i++) {
ELEMDESC *elem = fdesc->lprgelemdescParam+i; ELEMDESC *elem = fdesc->lprgelemdescParam+i;
if (TRACE_ON(olerelay)) { if (TRACE_ON(olerelay)) {
@ -1526,7 +1621,7 @@ static DWORD WINAPI xCall(int method, void **args)
buf.curoff = 0; buf.curoff = 0;
/* generic deserializer using typelib description */ /* generic deserializer using typelib description */
xargs = (DWORD *)(args + 1); xargs = (DWORD_PTR *)(args + 1);
status = S_OK; status = S_OK;
for (i=0;i<fdesc->cParams;i++) { for (i=0;i<fdesc->cParams;i++) {
ELEMDESC *elem = fdesc->lprgelemdescParam+i; ELEMDESC *elem = fdesc->lprgelemdescParam+i;
@ -1822,6 +1917,34 @@ static HRESULT init_proxy_entry_point(TMProxyImpl *proxy, unsigned int num)
xasm->bytestopop = nrofargs * 4; xasm->bytestopop = nrofargs * 4;
xasm->nop = 0x9090; xasm->nop = 0x9090;
proxy->lpvtbl[fdesc->oVft / sizeof(void *)] = xasm; proxy->lpvtbl[fdesc->oVft / sizeof(void *)] = xasm;
#elif defined(__x86_64__)
xasm->pushq_rbp = 0x55; /* pushq %rbp */
xasm->movq_rsp_rbp[0] = 0x48; /* movq %rsp,%rbp */
xasm->movq_rsp_rbp[1] = 0x89;
xasm->movq_rsp_rbp[2] = 0xe5;
xasm->subq_0x20_rsp = 0x20ec8348; /* subq 0x20,%rsp */
xasm->movq_rcx_0x10rbp = 0x104d8948; /* movq %rcx,0x10(%rbp) */
xasm->movq_rdx_0x18rbp = 0x18558948; /* movq %rdx,0x18(%rbp) */
xasm->movq_r8_0x20rbp = 0x2045894c; /* movq %r8,0x20(%rbp) */
xasm->movq_r9_0x28rbp = 0x284d894c; /* movq %r9,0x28(%rbp) */
xasm->movq_rcx[0] = 0x48; /* movq <num>,%rcx */
xasm->movq_rcx[1] = 0xc7;
xasm->movq_rcx[2] = 0xc1;
xasm->nr = num;
xasm->leaq_0x10rbp_rdx = 0x10558d48; /* leaq 0x10(%rbp),%rdx */
xasm->movq_rax = 0xb848; /* movq <xCall>,%rax */
xasm->xcall = xCall;
xasm->callq_rax = 0xd0ff; /* callq *%rax */
xasm->movq_rbp_rsp[0] = 0x48; /* movq %rbp,%rsp */
xasm->movq_rbp_rsp[1] = 0x89;
xasm->movq_rbp_rsp[2] = 0xec;
xasm->popq_rbp = 0x5d; /* popq %rbp */
xasm->ret = 0xc3; /* ret */
xasm->nop = 0x90909090; /* nop */
proxy->lpvtbl[fdesc->oVft / sizeof(void *)] = xasm;
#else #else
FIXME("not implemented on non i386\n"); FIXME("not implemented on non i386\n");
return E_FAIL; return E_FAIL;
@ -2048,12 +2171,13 @@ static HRESULT WINAPI
TMStubImpl_Invoke( TMStubImpl_Invoke(
LPRPCSTUBBUFFER iface, RPCOLEMESSAGE* xmsg,IRpcChannelBuffer*rpcchanbuf) LPRPCSTUBBUFFER iface, RPCOLEMESSAGE* xmsg,IRpcChannelBuffer*rpcchanbuf)
{ {
#ifdef __i386__ #if defined(__i386__) || defined(__x86_64__)
int i; int i;
const FUNCDESC *fdesc; const FUNCDESC *fdesc;
TMStubImpl *This = impl_from_IRpcStubBuffer(iface); TMStubImpl *This = impl_from_IRpcStubBuffer(iface);
HRESULT hres; HRESULT hres;
DWORD *args = NULL, res, *xargs, nrofargs; DWORD_PTR *args = NULL, *xargs;
DWORD res, nrofargs;
marshal_state buf; marshal_state buf;
UINT nrofnames = 0; UINT nrofnames = 0;
BSTR names[10]; BSTR names[10];
@ -2118,7 +2242,7 @@ TMStubImpl_Invoke(
nrofargs = 0; nrofargs = 0;
for (i=0;i<fdesc->cParams;i++) for (i=0;i<fdesc->cParams;i++)
nrofargs += _argsize(&fdesc->lprgelemdescParam[i].tdesc, tinfo); nrofargs += _argsize(&fdesc->lprgelemdescParam[i].tdesc, tinfo);
args = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,(nrofargs+1)*sizeof(DWORD)); args = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (nrofargs+1)*sizeof(DWORD_PTR));
if (!args) if (!args)
{ {
hres = E_OUTOFMEMORY; hres = E_OUTOFMEMORY;
@ -2146,12 +2270,12 @@ TMStubImpl_Invoke(
} }
} }
args[0] = (DWORD)This->pUnk; args[0] = (DWORD_PTR)This->pUnk;
__TRY __TRY
{ {
res = _invoke( res = _invoke(
(*((FARPROC**)args[0]))[fdesc->oVft/4], (*((FARPROC**)args[0]))[fdesc->oVft / sizeof(DWORD_PTR)],
fdesc->callconv, fdesc->callconv,
(xargs-args), (xargs-args),
args args

View file

@ -403,11 +403,21 @@ HRESULT WINAPI QueryPathOfRegTypeLib( REFGUID guid, WORD wMaj, WORD wMin, LCID l
* Success: S_OK * Success: S_OK
* Failure: Status * Failure: Status
*/ */
HRESULT WINAPI CreateTypeLib( HRESULT WINAPI CreateTypeLib(SYSKIND syskind, LPCOLESTR file, ICreateTypeLib **ctlib)
SYSKIND syskind, LPCOLESTR szFile, ICreateTypeLib** ppctlib {
) { ICreateTypeLib2 *typelib2;
FIXME("(%d,%s,%p), stub!\n",syskind,debugstr_w(szFile),ppctlib); HRESULT hres;
return E_FAIL;
FIXME("(%d, %s, %p): forwarding to CreateTypeLib2\n", syskind, debugstr_w(file), ctlib);
hres = CreateTypeLib2(syskind, file, &typelib2);
if(SUCCEEDED(hres))
{
hres = ICreateTypeLib2_QueryInterface(typelib2, &IID_ICreateTypeLib, (void **)&ctlib);
ICreateTypeLib2_Release(typelib2);
}
return hres;
} }
/****************************************************************************** /******************************************************************************
@ -3491,6 +3501,10 @@ static ITypeLib2* ITypeLib2_Constructor_MSFT(LPVOID pLib, DWORD dwTLBLength)
/* name, eventually add to a hash table */ /* name, eventually add to a hash table */
pTypeLibImpl->Name = MSFT_ReadName(&cx, tlbHeader.NameOffset); pTypeLibImpl->Name = MSFT_ReadName(&cx, tlbHeader.NameOffset);
TRACE("%s, syskind %d, version %d.%d, flags %04x\n",
debugstr_w(pTypeLibImpl->Name->str), pTypeLibImpl->syskind,
pTypeLibImpl->ver_major, pTypeLibImpl->ver_minor, pTypeLibImpl->libflags);
/* help info */ /* help info */
pTypeLibImpl->DocString = MSFT_ReadString(&cx, tlbHeader.helpstring); pTypeLibImpl->DocString = MSFT_ReadString(&cx, tlbHeader.helpstring);
pTypeLibImpl->HelpFile = MSFT_ReadString(&cx, tlbHeader.helpfile); pTypeLibImpl->HelpFile = MSFT_ReadString(&cx, tlbHeader.helpfile);
@ -3661,6 +3675,87 @@ static BOOL TLB_GUIDFromString(const char *str, GUID *guid)
return TRUE; return TRUE;
} }
struct bitstream
{
const BYTE *buffer;
DWORD length;
WORD current;
};
static const char *lookup_code(const BYTE *table, DWORD table_size, struct bitstream *bits)
{
const BYTE *p = table;
while (p < table + table_size && *p == 0x80)
{
if (p + 2 >= table + table_size) return NULL;
if (!(bits->current & 0xff))
{
if (!bits->length) return NULL;
bits->current = (*bits->buffer << 8) | 1;
bits->buffer++;
bits->length--;
}
if (bits->current & 0x8000)
{
p += 3;
}
else
{
p = table + (*(p + 2) | (*(p + 1) << 8));
}
bits->current <<= 1;
}
if (p + 1 < table + table_size && *(p + 1))
{
/* FIXME: Whats the meaning of *p? */
const BYTE *q = p + 1;
while (q < table + table_size && *q) q++;
return (q < table + table_size) ? (const char *)(p + 1) : NULL;
}
return NULL;
}
static const TLBString *decode_string(const BYTE *table, const char *stream, DWORD stream_length, ITypeLibImpl *lib)
{
DWORD buf_size, table_size;
const char *p;
struct bitstream bits;
BSTR buf;
TLBString *tlbstr;
if (!stream_length) return NULL;
bits.buffer = (const BYTE *)stream;
bits.length = stream_length;
bits.current = 0;
buf_size = *(const WORD *)table;
table += sizeof(WORD);
table_size = *(const DWORD *)table;
table += sizeof(DWORD);
buf = SysAllocStringLen(NULL, buf_size);
buf[0] = 0;
while ((p = lookup_code(table, table_size, &bits)))
{
static const WCHAR spaceW[] = { ' ',0 };
if (buf[0]) strcatW(buf, spaceW);
MultiByteToWideChar(CP_ACP, 0, p, -1, buf + strlenW(buf), buf_size - strlenW(buf));
}
tlbstr = TLB_append_str(&lib->string_list, buf);
SysFreeString(buf);
return tlbstr;
}
static WORD SLTG_ReadString(const char *ptr, const TLBString **pStr, ITypeLibImpl *lib) static WORD SLTG_ReadString(const char *ptr, const TLBString **pStr, ITypeLibImpl *lib)
{ {
WORD bytelen; WORD bytelen;
@ -3992,7 +4087,7 @@ static char *SLTG_DoImpls(char *pBlk, ITypeInfoImpl *pTI,
} }
static void SLTG_DoVars(char *pBlk, char *pFirstItem, ITypeInfoImpl *pTI, unsigned short cVars, static void SLTG_DoVars(char *pBlk, char *pFirstItem, ITypeInfoImpl *pTI, unsigned short cVars,
const char *pNameTable, const sltg_ref_lookup_t *ref_lookup) const char *pNameTable, const sltg_ref_lookup_t *ref_lookup, const BYTE *hlp_strings)
{ {
TLBVarDesc *pVarDesc; TLBVarDesc *pVarDesc;
const TLBString *prevName = NULL; const TLBString *prevName = NULL;
@ -4022,6 +4117,12 @@ static void SLTG_DoVars(char *pBlk, char *pFirstItem, ITypeInfoImpl *pTI, unsign
TRACE_(typelib)("byte_offs = 0x%x\n", pItem->byte_offs); TRACE_(typelib)("byte_offs = 0x%x\n", pItem->byte_offs);
TRACE_(typelib)("memid = 0x%x\n", pItem->memid); TRACE_(typelib)("memid = 0x%x\n", pItem->memid);
if (pItem->helpstring != 0xffff)
{
pVarDesc->HelpString = decode_string(hlp_strings, pBlk + pItem->helpstring, pNameTable - pBlk, pTI->pTypeLib);
TRACE_(typelib)("helpstring = %s\n", debugstr_w(pVarDesc->HelpString->str));
}
if(pItem->flags & 0x02) if(pItem->flags & 0x02)
pType = &pItem->type; pType = &pItem->type;
else else
@ -4103,7 +4204,8 @@ static void SLTG_DoVars(char *pBlk, char *pFirstItem, ITypeInfoImpl *pTI, unsign
} }
static void SLTG_DoFuncs(char *pBlk, char *pFirstItem, ITypeInfoImpl *pTI, static void SLTG_DoFuncs(char *pBlk, char *pFirstItem, ITypeInfoImpl *pTI,
unsigned short cFuncs, char *pNameTable, const sltg_ref_lookup_t *ref_lookup) unsigned short cFuncs, char *pNameTable, const sltg_ref_lookup_t *ref_lookup,
const BYTE *hlp_strings)
{ {
SLTG_Function *pFunc; SLTG_Function *pFunc;
unsigned short i; unsigned short i;
@ -4140,6 +4242,8 @@ static void SLTG_DoFuncs(char *pBlk, char *pFirstItem, ITypeInfoImpl *pTI,
pFuncDesc->funcdesc.cParams = pFunc->nacc >> 3; pFuncDesc->funcdesc.cParams = pFunc->nacc >> 3;
pFuncDesc->funcdesc.cParamsOpt = (pFunc->retnextopt & 0x7e) >> 1; pFuncDesc->funcdesc.cParamsOpt = (pFunc->retnextopt & 0x7e) >> 1;
pFuncDesc->funcdesc.oVft = pFunc->vtblpos & ~1; pFuncDesc->funcdesc.oVft = pFunc->vtblpos & ~1;
if (pFunc->helpstring != 0xffff)
pFuncDesc->HelpString = decode_string(hlp_strings, pBlk + pFunc->helpstring, pNameTable - pBlk, pTI->pTypeLib);
if(pFunc->magic & SLTG_FUNCTION_FLAGS_PRESENT) if(pFunc->magic & SLTG_FUNCTION_FLAGS_PRESENT)
pFuncDesc->funcdesc.wFuncFlags = pFunc->funcflags; pFuncDesc->funcdesc.wFuncFlags = pFunc->funcflags;
@ -4158,7 +4262,7 @@ static void SLTG_DoFuncs(char *pBlk, char *pFirstItem, ITypeInfoImpl *pTI,
pArg = (WORD*)(pBlk + pFunc->arg_off); pArg = (WORD*)(pBlk + pFunc->arg_off);
for(param = 0; param < pFuncDesc->funcdesc.cParams; param++) { for(param = 0; param < pFuncDesc->funcdesc.cParams; param++) {
char *paramName = pNameTable + *pArg; char *paramName = pNameTable + (*pArg & ~1);
BOOL HaveOffs; BOOL HaveOffs;
/* If arg type follows then paramName points to the 2nd /* If arg type follows then paramName points to the 2nd
letter of the name, else the next WORD is an offset to letter of the name, else the next WORD is an offset to
@ -4169,26 +4273,21 @@ static void SLTG_DoFuncs(char *pBlk, char *pFirstItem, ITypeInfoImpl *pTI,
meaning that the next WORD is the type, the latter meaning that the next WORD is the type, the latter
meaning that the next WORD is an offset to the type. */ meaning that the next WORD is an offset to the type. */
HaveOffs = FALSE; if(*pArg == 0xffff || *pArg == 0xfffe)
if(*pArg == 0xffff)
paramName = NULL; paramName = NULL;
else if(*pArg == 0xfffe) {
paramName = NULL;
HaveOffs = TRUE;
}
else if(paramName[-1] && !isalnum(paramName[-1]))
HaveOffs = TRUE;
HaveOffs = !(*pArg & 1);
pArg++; pArg++;
TRACE_(typelib)("param %d: paramName %s, *pArg %#x\n",
param, debugstr_a(paramName), *pArg);
if(HaveOffs) { /* the next word is an offset to type */ if(HaveOffs) { /* the next word is an offset to type */
pType = (WORD*)(pBlk + *pArg); pType = (WORD*)(pBlk + *pArg);
SLTG_DoElem(pType, pBlk, SLTG_DoElem(pType, pBlk,
&pFuncDesc->funcdesc.lprgelemdescParam[param], ref_lookup); &pFuncDesc->funcdesc.lprgelemdescParam[param], ref_lookup);
pArg++; pArg++;
} else { } else {
if(paramName)
paramName--;
pArg = SLTG_DoElem(pArg, pBlk, pArg = SLTG_DoElem(pArg, pBlk,
&pFuncDesc->funcdesc.lprgelemdescParam[param], ref_lookup); &pFuncDesc->funcdesc.lprgelemdescParam[param], ref_lookup);
} }
@ -4232,7 +4331,7 @@ static void SLTG_ProcessCoClass(char *pBlk, ITypeInfoImpl *pTI,
static void SLTG_ProcessInterface(char *pBlk, ITypeInfoImpl *pTI, static void SLTG_ProcessInterface(char *pBlk, ITypeInfoImpl *pTI,
char *pNameTable, SLTG_TypeInfoHeader *pTIHeader, char *pNameTable, SLTG_TypeInfoHeader *pTIHeader,
const SLTG_TypeInfoTail *pTITail) const SLTG_TypeInfoTail *pTITail, const BYTE *hlp_strings)
{ {
char *pFirstItem; char *pFirstItem;
sltg_ref_lookup_t *ref_lookup = NULL; sltg_ref_lookup_t *ref_lookup = NULL;
@ -4249,7 +4348,7 @@ static void SLTG_ProcessInterface(char *pBlk, ITypeInfoImpl *pTI,
} }
if (pTITail->funcs_off != 0xffff) if (pTITail->funcs_off != 0xffff)
SLTG_DoFuncs(pBlk, pBlk + pTITail->funcs_off, pTI, pTITail->cFuncs, pNameTable, ref_lookup); SLTG_DoFuncs(pBlk, pBlk + pTITail->funcs_off, pTI, pTITail->cFuncs, pNameTable, ref_lookup, hlp_strings);
heap_free(ref_lookup); heap_free(ref_lookup);
@ -4259,9 +4358,9 @@ static void SLTG_ProcessInterface(char *pBlk, ITypeInfoImpl *pTI,
static void SLTG_ProcessRecord(char *pBlk, ITypeInfoImpl *pTI, static void SLTG_ProcessRecord(char *pBlk, ITypeInfoImpl *pTI,
const char *pNameTable, SLTG_TypeInfoHeader *pTIHeader, const char *pNameTable, SLTG_TypeInfoHeader *pTIHeader,
const SLTG_TypeInfoTail *pTITail) const SLTG_TypeInfoTail *pTITail, const BYTE *hlp_strings)
{ {
SLTG_DoVars(pBlk, pBlk + pTITail->vars_off, pTI, pTITail->cVars, pNameTable, NULL); SLTG_DoVars(pBlk, pBlk + pTITail->vars_off, pTI, pTITail->cVars, pNameTable, NULL, hlp_strings);
} }
static void SLTG_ProcessAlias(char *pBlk, ITypeInfoImpl *pTI, static void SLTG_ProcessAlias(char *pBlk, ITypeInfoImpl *pTI,
@ -4294,7 +4393,7 @@ static void SLTG_ProcessAlias(char *pBlk, ITypeInfoImpl *pTI,
static void SLTG_ProcessDispatch(char *pBlk, ITypeInfoImpl *pTI, static void SLTG_ProcessDispatch(char *pBlk, ITypeInfoImpl *pTI,
char *pNameTable, SLTG_TypeInfoHeader *pTIHeader, char *pNameTable, SLTG_TypeInfoHeader *pTIHeader,
const SLTG_TypeInfoTail *pTITail) const SLTG_TypeInfoTail *pTITail, const BYTE *hlp_strings)
{ {
sltg_ref_lookup_t *ref_lookup = NULL; sltg_ref_lookup_t *ref_lookup = NULL;
if (pTIHeader->href_table != 0xffffffff) if (pTIHeader->href_table != 0xffffffff)
@ -4302,10 +4401,10 @@ static void SLTG_ProcessDispatch(char *pBlk, ITypeInfoImpl *pTI,
pNameTable); pNameTable);
if (pTITail->vars_off != 0xffff) if (pTITail->vars_off != 0xffff)
SLTG_DoVars(pBlk, pBlk + pTITail->vars_off, pTI, pTITail->cVars, pNameTable, ref_lookup); SLTG_DoVars(pBlk, pBlk + pTITail->vars_off, pTI, pTITail->cVars, pNameTable, ref_lookup, hlp_strings);
if (pTITail->funcs_off != 0xffff) if (pTITail->funcs_off != 0xffff)
SLTG_DoFuncs(pBlk, pBlk + pTITail->funcs_off, pTI, pTITail->cFuncs, pNameTable, ref_lookup); SLTG_DoFuncs(pBlk, pBlk + pTITail->funcs_off, pTI, pTITail->cFuncs, pNameTable, ref_lookup, hlp_strings);
if (pTITail->impls_off != 0xffff) if (pTITail->impls_off != 0xffff)
SLTG_DoImpls(pBlk + pTITail->impls_off, pTI, FALSE, ref_lookup); SLTG_DoImpls(pBlk + pTITail->impls_off, pTI, FALSE, ref_lookup);
@ -4322,14 +4421,14 @@ static void SLTG_ProcessDispatch(char *pBlk, ITypeInfoImpl *pTI,
static void SLTG_ProcessEnum(char *pBlk, ITypeInfoImpl *pTI, static void SLTG_ProcessEnum(char *pBlk, ITypeInfoImpl *pTI,
const char *pNameTable, SLTG_TypeInfoHeader *pTIHeader, const char *pNameTable, SLTG_TypeInfoHeader *pTIHeader,
const SLTG_TypeInfoTail *pTITail) const SLTG_TypeInfoTail *pTITail, const BYTE *hlp_strings)
{ {
SLTG_DoVars(pBlk, pBlk + pTITail->vars_off, pTI, pTITail->cVars, pNameTable, NULL); SLTG_DoVars(pBlk, pBlk + pTITail->vars_off, pTI, pTITail->cVars, pNameTable, NULL, hlp_strings);
} }
static void SLTG_ProcessModule(char *pBlk, ITypeInfoImpl *pTI, static void SLTG_ProcessModule(char *pBlk, ITypeInfoImpl *pTI,
char *pNameTable, SLTG_TypeInfoHeader *pTIHeader, char *pNameTable, SLTG_TypeInfoHeader *pTIHeader,
const SLTG_TypeInfoTail *pTITail) const SLTG_TypeInfoTail *pTITail, const BYTE *hlp_strings)
{ {
sltg_ref_lookup_t *ref_lookup = NULL; sltg_ref_lookup_t *ref_lookup = NULL;
if (pTIHeader->href_table != 0xffffffff) if (pTIHeader->href_table != 0xffffffff)
@ -4337,10 +4436,10 @@ static void SLTG_ProcessModule(char *pBlk, ITypeInfoImpl *pTI,
pNameTable); pNameTable);
if (pTITail->vars_off != 0xffff) if (pTITail->vars_off != 0xffff)
SLTG_DoVars(pBlk, pBlk + pTITail->vars_off, pTI, pTITail->cVars, pNameTable, ref_lookup); SLTG_DoVars(pBlk, pBlk + pTITail->vars_off, pTI, pTITail->cVars, pNameTable, ref_lookup, hlp_strings);
if (pTITail->funcs_off != 0xffff) if (pTITail->funcs_off != 0xffff)
SLTG_DoFuncs(pBlk, pBlk + pTITail->funcs_off, pTI, pTITail->cFuncs, pNameTable, ref_lookup); SLTG_DoFuncs(pBlk, pBlk + pTITail->funcs_off, pTI, pTITail->cFuncs, pNameTable, ref_lookup, hlp_strings);
heap_free(ref_lookup); heap_free(ref_lookup);
if (TRACE_ON(typelib)) if (TRACE_ON(typelib))
dump_TypeInfo(pTI); dump_TypeInfo(pTI);
@ -4349,17 +4448,17 @@ static void SLTG_ProcessModule(char *pBlk, ITypeInfoImpl *pTI,
/* Because SLTG_OtherTypeInfo is such a painful struct, we make a more /* Because SLTG_OtherTypeInfo is such a painful struct, we make a more
manageable copy of it into this */ manageable copy of it into this */
typedef struct { typedef struct {
WORD small_no;
char *index_name; char *index_name;
char *other_name; char *other_name;
WORD res1a; WORD res1a;
WORD name_offs; WORD name_offs;
WORD more_bytes; WORD hlpstr_len;
char *extra; char *extra;
WORD res20; WORD res20;
DWORD helpcontext; DWORD helpcontext;
WORD res26; WORD res26;
GUID uuid; GUID uuid;
WORD typekind;
} SLTG_InternalOtherTypeInfo; } SLTG_InternalOtherTypeInfo;
/**************************************************************************** /****************************************************************************
@ -4378,8 +4477,8 @@ static ITypeLib2* ITypeLib2_Constructor_SLTG(LPVOID pLib, DWORD dwTLBLength)
LPVOID pBlk, pFirstBlk; LPVOID pBlk, pFirstBlk;
SLTG_LibBlk *pLibBlk; SLTG_LibBlk *pLibBlk;
SLTG_InternalOtherTypeInfo *pOtherTypeInfoBlks; SLTG_InternalOtherTypeInfo *pOtherTypeInfoBlks;
char *pAfterOTIBlks = NULL;
char *pNameTable, *ptr; char *pNameTable, *ptr;
const BYTE *hlp_strings;
int i; int i;
DWORD len, order; DWORD len, order;
ITypeInfoImpl **ppTypeInfoImpl; ITypeInfoImpl **ppTypeInfoImpl;
@ -4445,53 +4544,55 @@ static ITypeLib2* ITypeLib2_Constructor_SLTG(LPVOID pLib, DWORD dwTLBLength)
len += 0x40; len += 0x40;
/* And now TypeInfoCount of SLTG_OtherTypeInfo */ /* And now TypeInfoCount of SLTG_OtherTypeInfo */
pTypeLibImpl->TypeInfoCount = *(WORD *)((char *)pLibBlk + len);
len += sizeof(WORD);
pOtherTypeInfoBlks = heap_alloc_zero(sizeof(*pOtherTypeInfoBlks) * pTypeLibImpl->TypeInfoCount); pOtherTypeInfoBlks = heap_alloc_zero(sizeof(*pOtherTypeInfoBlks) * pTypeLibImpl->TypeInfoCount);
ptr = (char*)pLibBlk + len; ptr = (char*)pLibBlk + len;
for(i = 0; i < pTypeLibImpl->TypeInfoCount; i++) { for(i = 0; i < pTypeLibImpl->TypeInfoCount; i++) {
WORD w, extra; WORD w, extra;
len = 0; len = 0;
pOtherTypeInfoBlks[i].small_no = *(WORD*)ptr; w = *(WORD*)ptr;
w = *(WORD*)(ptr + 2);
if(w != 0xffff) { if(w != 0xffff) {
len += w; len += w;
pOtherTypeInfoBlks[i].index_name = heap_alloc(w+1); pOtherTypeInfoBlks[i].index_name = heap_alloc(w+1);
memcpy(pOtherTypeInfoBlks[i].index_name, ptr + 4, w); memcpy(pOtherTypeInfoBlks[i].index_name, ptr + 2, w);
pOtherTypeInfoBlks[i].index_name[w] = '\0'; pOtherTypeInfoBlks[i].index_name[w] = '\0';
} }
w = *(WORD*)(ptr + 4 + len); w = *(WORD*)(ptr + 2 + len);
if(w != 0xffff) { if(w != 0xffff) {
TRACE_(typelib)("\twith %s\n", debugstr_an(ptr + 6 + len, w)); TRACE_(typelib)("\twith %s\n", debugstr_an(ptr + 4 + len, w));
len += w;
pOtherTypeInfoBlks[i].other_name = heap_alloc(w+1); pOtherTypeInfoBlks[i].other_name = heap_alloc(w+1);
memcpy(pOtherTypeInfoBlks[i].other_name, ptr + 6 + len, w); memcpy(pOtherTypeInfoBlks[i].other_name, ptr + 4 + len, w);
pOtherTypeInfoBlks[i].other_name[w] = '\0'; pOtherTypeInfoBlks[i].other_name[w] = '\0';
len += w;
} }
pOtherTypeInfoBlks[i].res1a = *(WORD*)(ptr + len + 6); pOtherTypeInfoBlks[i].res1a = *(WORD*)(ptr + 4 + len);
pOtherTypeInfoBlks[i].name_offs = *(WORD*)(ptr + len + 8); pOtherTypeInfoBlks[i].name_offs = *(WORD*)(ptr + 6 + len);
extra = pOtherTypeInfoBlks[i].more_bytes = *(WORD*)(ptr + 10 + len); extra = pOtherTypeInfoBlks[i].hlpstr_len = *(WORD*)(ptr + 8 + len);
if(extra) { if(extra) {
pOtherTypeInfoBlks[i].extra = heap_alloc(extra); pOtherTypeInfoBlks[i].extra = heap_alloc(extra);
memcpy(pOtherTypeInfoBlks[i].extra, ptr + 12, extra); memcpy(pOtherTypeInfoBlks[i].extra, ptr + 10 + len, extra);
len += extra; len += extra;
} }
pOtherTypeInfoBlks[i].res20 = *(WORD*)(ptr + 12 + len); pOtherTypeInfoBlks[i].res20 = *(WORD*)(ptr + 10 + len);
pOtherTypeInfoBlks[i].helpcontext = *(DWORD*)(ptr + 14 + len); pOtherTypeInfoBlks[i].helpcontext = *(DWORD*)(ptr + 12 + len);
pOtherTypeInfoBlks[i].res26 = *(WORD*)(ptr + 18 + len); pOtherTypeInfoBlks[i].res26 = *(WORD*)(ptr + 16 + len);
memcpy(&pOtherTypeInfoBlks[i].uuid, ptr + 20 + len, sizeof(GUID)); memcpy(&pOtherTypeInfoBlks[i].uuid, ptr + 18 + len, sizeof(GUID));
pOtherTypeInfoBlks[i].typekind = *(WORD*)(ptr + 18 + sizeof(GUID) + len);
len += sizeof(SLTG_OtherTypeInfo); len += sizeof(SLTG_OtherTypeInfo);
ptr += len; ptr += len;
} }
pAfterOTIBlks = ptr; /* Get the next DWORD */
len = *(DWORD*)ptr;
/* Skip this WORD and get the next DWORD */ hlp_strings = (const BYTE *)ptr + sizeof(DWORD);
len = *(DWORD*)(pAfterOTIBlks + 2); TRACE("max help string length %#x, help strings length %#x\n",
*(WORD *)hlp_strings, *(DWORD *)(hlp_strings + 2));
/* Now add this to pLibBLk look at what we're pointing at and /* Now add this to pLibBLk look at what we're pointing at and
possibly add 0x20, then add 0x216, sprinkle a bit a magic possibly add 0x20, then add 0x216, sprinkle a bit a magic
@ -4557,6 +4658,7 @@ static ITypeLib2* ITypeLib2_Constructor_SLTG(LPVOID pLib, DWORD dwTLBLength)
(*ppTypeInfoImpl)->index = i; (*ppTypeInfoImpl)->index = i;
(*ppTypeInfoImpl)->Name = SLTG_ReadName(pNameTable, pOtherTypeInfoBlks[i].name_offs, pTypeLibImpl); (*ppTypeInfoImpl)->Name = SLTG_ReadName(pNameTable, pOtherTypeInfoBlks[i].name_offs, pTypeLibImpl);
(*ppTypeInfoImpl)->dwHelpContext = pOtherTypeInfoBlks[i].helpcontext; (*ppTypeInfoImpl)->dwHelpContext = pOtherTypeInfoBlks[i].helpcontext;
(*ppTypeInfoImpl)->DocString = decode_string(hlp_strings, pOtherTypeInfoBlks[i].extra, pOtherTypeInfoBlks[i].hlpstr_len, pTypeLibImpl);
(*ppTypeInfoImpl)->guid = TLB_append_guid(&pTypeLibImpl->guid_list, &pOtherTypeInfoBlks[i].uuid, 2); (*ppTypeInfoImpl)->guid = TLB_append_guid(&pTypeLibImpl->guid_list, &pOtherTypeInfoBlks[i].uuid, 2);
(*ppTypeInfoImpl)->typeattr.typekind = pTIHeader->typekind; (*ppTypeInfoImpl)->typeattr.typekind = pTIHeader->typekind;
(*ppTypeInfoImpl)->typeattr.wMajorVerNum = pTIHeader->major_version; (*ppTypeInfoImpl)->typeattr.wMajorVerNum = pTIHeader->major_version;
@ -4589,17 +4691,17 @@ static ITypeLib2* ITypeLib2_Constructor_SLTG(LPVOID pLib, DWORD dwTLBLength)
switch(pTIHeader->typekind) { switch(pTIHeader->typekind) {
case TKIND_ENUM: case TKIND_ENUM:
SLTG_ProcessEnum((char *)(pMemHeader + 1), *ppTypeInfoImpl, pNameTable, SLTG_ProcessEnum((char *)(pMemHeader + 1), *ppTypeInfoImpl, pNameTable,
pTIHeader, pTITail); pTIHeader, pTITail, hlp_strings);
break; break;
case TKIND_RECORD: case TKIND_RECORD:
SLTG_ProcessRecord((char *)(pMemHeader + 1), *ppTypeInfoImpl, pNameTable, SLTG_ProcessRecord((char *)(pMemHeader + 1), *ppTypeInfoImpl, pNameTable,
pTIHeader, pTITail); pTIHeader, pTITail, hlp_strings);
break; break;
case TKIND_INTERFACE: case TKIND_INTERFACE:
SLTG_ProcessInterface((char *)(pMemHeader + 1), *ppTypeInfoImpl, pNameTable, SLTG_ProcessInterface((char *)(pMemHeader + 1), *ppTypeInfoImpl, pNameTable,
pTIHeader, pTITail); pTIHeader, pTITail, hlp_strings);
break; break;
case TKIND_COCLASS: case TKIND_COCLASS:
@ -4614,12 +4716,12 @@ static ITypeLib2* ITypeLib2_Constructor_SLTG(LPVOID pLib, DWORD dwTLBLength)
case TKIND_DISPATCH: case TKIND_DISPATCH:
SLTG_ProcessDispatch((char *)(pMemHeader + 1), *ppTypeInfoImpl, pNameTable, SLTG_ProcessDispatch((char *)(pMemHeader + 1), *ppTypeInfoImpl, pNameTable,
pTIHeader, pTITail); pTIHeader, pTITail, hlp_strings);
break; break;
case TKIND_MODULE: case TKIND_MODULE:
SLTG_ProcessModule((char *)(pMemHeader + 1), *ppTypeInfoImpl, pNameTable, SLTG_ProcessModule((char *)(pMemHeader + 1), *ppTypeInfoImpl, pNameTable,
pTIHeader, pTITail); pTIHeader, pTITail, hlp_strings);
break; break;
default: default:
@ -6328,15 +6430,15 @@ static double (* const call_double_method)(void*,int,const DWORD*,int*) = (void
* Invokes a method, or accesses a property of an object, that implements the * Invokes a method, or accesses a property of an object, that implements the
* interface described by the type description. * interface described by the type description.
*/ */
DWORD DWORD _invoke(FARPROC func, CALLCONV callconv, int nrargs, DWORD_PTR *args)
_invoke(FARPROC func,CALLCONV callconv, int nrargs, DWORD *args) { {
DWORD res; DWORD res;
int stack_offset; int stack_offset;
if (TRACE_ON(ole)) { if (TRACE_ON(ole)) {
int i; int i;
TRACE("Calling %p(",func); TRACE("Calling %p(",func);
for (i=0;i<min(nrargs,30);i++) TRACE("%08x,",args[i]); for (i=0;i<min(nrargs,30);i++) TRACE("%08lx,",args[i]);
if (nrargs > 30) TRACE("..."); if (nrargs > 30) TRACE("...");
TRACE(")\n"); TRACE(")\n");
} }
@ -6344,7 +6446,7 @@ _invoke(FARPROC func,CALLCONV callconv, int nrargs, DWORD *args) {
switch (callconv) { switch (callconv) {
case CC_STDCALL: case CC_STDCALL:
case CC_CDECL: case CC_CDECL:
res = call_method( func, nrargs, args, &stack_offset ); res = call_method(func, nrargs, (DWORD *)args, &stack_offset);
break; break;
default: default:
FIXME("unsupported calling convention %d\n",callconv); FIXME("unsupported calling convention %d\n",callconv);
@ -6401,43 +6503,33 @@ __ASM_GLOBAL_FUNC( call_method,
/* same function but returning floating point */ /* same function but returning floating point */
static double (CDECL * const call_double_method)(void*,int,const DWORD_PTR*) = (void *)call_method; static double (CDECL * const call_double_method)(void*,int,const DWORD_PTR*) = (void *)call_method;
#elif defined(__arm__) DWORD _invoke(FARPROC func, CALLCONV callconv, int nrargs, DWORD_PTR *args)
{
DWORD res;
extern LONGLONG CDECL call_method( void *func, int nb_stk_args, const DWORD *stk_args, const DWORD *reg_args ); if (TRACE_ON(ole))
__ASM_GLOBAL_FUNC( call_method, {
/* r0 = *func int i;
* r1 = nb_stk_args TRACE("Calling %p(", func);
* r2 = *stk_args (pointer to 'nb_stk_args' DWORD values to push on stack) for (i=0; i<min(nrargs, 30); i++) TRACE("%016lx,", args[i]);
* r3 = *reg_args (pointer to 8, 64-bit d0-d7 (double) values OR as 16, 32-bit s0-s15 (float) values, followed by 4, 32-bit (DWORD) r0-r3 values) if (nrargs > 30) TRACE("...");
*/ TRACE(")\n");
}
"push {fp, lr}\n\t" /* Save frame pointer and return address (stack still aligned to 8 bytes) */ switch (callconv) {
"mov fp, sp\n\t" /* Save stack pointer as our frame for cleaning the stack on return */ case CC_STDCALL:
case CC_CDECL:
res = call_method(func, nrargs, args);
break;
default:
FIXME("unsupported calling convention %d\n", callconv);
res = -1;
break;
}
"lsls r1, r1, #2\n\t" /* r1 = nb_stk_args * sizeof(DWORD) */ TRACE("returns %08x\n", res);
"beq 1f\n\t" /* Skip allocation if no stack args */ return res;
"add r2, r2, r1\n" /* Calculate ending address of incoming stack data */ }
"2:\tldr ip, [r2, #-4]!\n\t" /* Get next value */
"str ip, [sp, #-4]!\n\t" /* Push it on the stack */
"subs r1, r1, #4\n\t" /* Decrement count */
"bgt 2b\n\t" /* Loop till done */
"1:\n\t"
#ifndef __SOFTFP__
"vldm r3!, {s0-s15}\n\t" /* Load the s0-s15/d0-d7 arguments */
#endif
"mov ip, r0\n\t" /* Save the function call address to ip before we nuke r0 with arguments to pass */
"ldm r3, {r0-r3}\n\t" /* Load the r0-r3 arguments */
"blx ip\n\t" /* Call the target function */
"mov sp, fp\n\t" /* Clean the stack using fp */
"pop {fp, pc}\n\t" /* Restore fp and return */
)
/* same function but returning single/double floating point */
static float (CDECL * const call_float_method)(void *, int, const DWORD *, const DWORD *) = (void *)call_method;
static double (CDECL * const call_double_method)(void *, int, const DWORD *, const DWORD *) = (void *)call_method;
#endif /* __x86_64__ */ #endif /* __x86_64__ */
@ -6470,6 +6562,7 @@ static HRESULT userdefined_to_variantvt(ITypeInfo *tinfo, const TYPEDESC *tdesc,
break; break;
case TKIND_ALIAS: case TKIND_ALIAS:
tdesc = &tattr->tdescAlias;
hr = typedescvt_to_variantvt(tinfo2, &tattr->tdescAlias, vt); hr = typedescvt_to_variantvt(tinfo2, &tattr->tdescAlias, vt);
break; break;
@ -6575,13 +6668,13 @@ static HRESULT typedescvt_to_variantvt(ITypeInfo *tinfo, const TYPEDESC *tdesc,
return hr; return hr;
} }
static HRESULT get_iface_guid(ITypeInfo *tinfo, const TYPEDESC *tdesc, GUID *guid) static HRESULT get_iface_guid(ITypeInfo *tinfo, HREFTYPE href, GUID *guid)
{ {
ITypeInfo *tinfo2; ITypeInfo *tinfo2;
TYPEATTR *tattr; TYPEATTR *tattr;
HRESULT hres; HRESULT hres;
hres = ITypeInfo_GetRefTypeInfo(tinfo, tdesc->u.hreftype, &tinfo2); hres = ITypeInfo_GetRefTypeInfo(tinfo, href, &tinfo2);
if(FAILED(hres)) if(FAILED(hres))
return hres; return hres;
@ -6593,7 +6686,7 @@ static HRESULT get_iface_guid(ITypeInfo *tinfo, const TYPEDESC *tdesc, GUID *gui
switch(tattr->typekind) { switch(tattr->typekind) {
case TKIND_ALIAS: case TKIND_ALIAS:
hres = get_iface_guid(tinfo2, &tattr->tdescAlias, guid); hres = get_iface_guid(tinfo2, tattr->tdescAlias.u.hreftype, guid);
break; break;
case TKIND_INTERFACE: case TKIND_INTERFACE:
@ -6601,6 +6694,21 @@ static HRESULT get_iface_guid(ITypeInfo *tinfo, const TYPEDESC *tdesc, GUID *gui
*guid = tattr->guid; *guid = tattr->guid;
break; break;
case TKIND_COCLASS: {
unsigned int i;
int type_flags;
for(i = 0; i < tattr->cImplTypes; i++)
if(SUCCEEDED(ITypeInfo_GetImplTypeFlags(tinfo2, i, &type_flags)) &&
type_flags == (IMPLTYPEFLAG_FSOURCE|IMPLTYPEFLAG_FDEFAULT)) break;
if(i < tattr->cImplTypes) {
hres = ITypeInfo_GetRefTypeOfImplType(tinfo2, i, &href);
if(SUCCEEDED(hres)) hres = get_iface_guid(tinfo2, href, guid);
} else hres = E_UNEXPECTED;
break;
}
default: default:
ERR("Unexpected typekind %d\n", tattr->typekind); ERR("Unexpected typekind %d\n", tattr->typekind);
hres = E_UNEXPECTED; hres = E_UNEXPECTED;
@ -6728,8 +6836,17 @@ DispCallFunc(
break; break;
case VT_DECIMAL: case VT_DECIMAL:
case VT_VARIANT: case VT_VARIANT:
args[0] = (DWORD)pvargResult; /* arg 0 is a pointer to the result */ if (pvInstance)
call_method( func, argspos, args, &stack_offset ); {
args[0] = (DWORD)pvInstance; /* arg 0 is a pointer to the instance */
args[1] = (DWORD)pvargResult; /* arg 1 is a pointer to the result */
call_method( func, argspos, args, &stack_offset );
}
else
{
args[0] = (DWORD)pvargResult; /* arg 0 is a pointer to the result */
call_method( func, argspos, args, &stack_offset );
}
break; break;
case VT_I8: case VT_I8:
case VT_UI8: case VT_UI8:
@ -6814,8 +6931,17 @@ DispCallFunc(
break; break;
case VT_DECIMAL: case VT_DECIMAL:
case VT_VARIANT: case VT_VARIANT:
args[0] = (DWORD_PTR)pvargResult; /* arg 0 is a pointer to the result */ if (pvInstance)
call_method( func, argspos, args ); {
args[0] = (DWORD_PTR)pvInstance; /* arg 0 is a pointer to the instance */
args[1] = (DWORD_PTR)pvargResult; /* arg 1 is a pointer to the result */
call_method( func, argspos, args );
}
else
{
args[0] = (DWORD_PTR)pvargResult; /* arg 0 is a pointer to the result */
call_method( func, argspos, args );
}
break; break;
case VT_HRESULT: case VT_HRESULT:
WARN("invalid return type %u\n", vtReturn); WARN("invalid return type %u\n", vtReturn);
@ -6830,182 +6956,6 @@ DispCallFunc(
TRACE("retval: %s\n", debugstr_variant(pvargResult)); TRACE("retval: %s\n", debugstr_variant(pvargResult));
return S_OK; return S_OK;
#elif defined(__arm__)
int argspos;
void *func;
UINT i;
DWORD *args;
struct {
#ifndef __SOFTFP__
union {
float s[16];
double d[8];
} sd;
#endif
DWORD r[4];
} regs;
int rcount; /* 32-bit register index count */
#ifndef __SOFTFP__
int scount = 0; /* single-precision float register index count */
int dcount = 0; /* double-precision float register index count */
#endif
TRACE("(%p, %ld, %d, %d, %d, %p, %p, %p (vt=%d))\n",
pvInstance, oVft, cc, vtReturn, cActuals, prgvt, prgpvarg, pvargResult, V_VT(pvargResult));
if (cc != CC_STDCALL && cc != CC_CDECL)
{
FIXME("unsupported calling convention %d\n",cc);
return E_INVALIDARG;
}
argspos = 0;
rcount = 0;
/* Determine if we need to pass a pointer for the return value as arg 0. If so, do that */
/* first as it will need to be in the 'r' registers: */
switch (vtReturn)
{
case VT_DECIMAL:
case VT_VARIANT:
regs.r[rcount++] = (DWORD)pvargResult; /* arg 0 is a pointer to the result */
break;
case VT_HRESULT:
WARN("invalid return type %u\n", vtReturn);
return E_INVALIDARG;
default: /* And all others are in 'r', 's', or 'd' registers or have no return value */
break;
}
if (pvInstance)
{
const FARPROC *vtable = *(FARPROC **)pvInstance;
func = vtable[oVft/sizeof(void *)];
regs.r[rcount++] = (DWORD)pvInstance; /* the This pointer is always the first parameter */
}
else func = (void *)oVft;
/* maximum size for an argument is sizeof(VARIANT). Also allow for return pointer and stack alignment. */
args = heap_alloc( sizeof(VARIANT) * cActuals + sizeof(DWORD) * 4 );
for (i = 0; i < cActuals; i++)
{
VARIANT *arg = prgpvarg[i];
DWORD *pdwarg = (DWORD *)(arg); /* a reinterpret_cast of the variant, used for copying structures when they are split between registers and stack */
int ntemp; /* Used for counting words split between registers and stack */
switch (prgvt[i])
{
case VT_EMPTY:
break;
case VT_R8: /* these must be 8-byte aligned, and put in 'd' regs or stack, as they are double-floats */
case VT_DATE:
#ifndef __SOFTFP__
dcount = max( (scount + 1) / 2, dcount );
if (dcount < 8)
{
regs.sd.d[dcount++] = V_R8(arg);
}
else
{
argspos += (argspos % 2); /* align argspos to 8-bytes */
memcpy( &args[argspos], &V_R8(arg), sizeof(V_R8(arg)) );
argspos += sizeof(V_R8(arg)) / sizeof(DWORD);
}
break;
#endif
case VT_I8: /* these must be 8-byte aligned, and put in 'r' regs or stack, as they are long-longs */
case VT_UI8:
case VT_CY:
if (rcount < 3)
{
rcount += (rcount % 2); /* align rcount to 8-byte register pair */
memcpy( &regs.r[rcount], &V_UI8(arg), sizeof(V_UI8(arg)) );
rcount += sizeof(V_UI8(arg)) / sizeof(DWORD);
}
else
{
rcount = 4; /* Make sure we flag that all 'r' regs are full */
argspos += (argspos % 2); /* align argspos to 8-bytes */
memcpy( &args[argspos], &V_UI8(arg), sizeof(V_UI8(arg)) );
argspos += sizeof(V_UI8(arg)) / sizeof(DWORD);
}
break;
case VT_DECIMAL: /* these structures are 8-byte aligned, and put in 'r' regs or stack, can be split between the two */
case VT_VARIANT:
/* 8-byte align 'r' and/or stack: */
if (rcount < 3)
rcount += (rcount % 2);
else
{
rcount = 4;
argspos += (argspos % 2);
}
ntemp = sizeof(*arg) / sizeof(DWORD);
while (ntemp > 0)
{
if (rcount < 4)
regs.r[rcount++] = *pdwarg++;
else
args[argspos++] = *pdwarg++;
--ntemp;
}
break;
case VT_BOOL: /* VT_BOOL is 16-bit but BOOL is 32-bit, needs to be extended */
if (rcount < 4)
regs.r[rcount++] = V_BOOL(arg);
else
args[argspos++] = V_BOOL(arg);
break;
case VT_R4: /* these must be 4-byte aligned, and put in 's' regs or stack, as they are single-floats */
#ifndef __SOFTFP__
if (!(scount % 2)) scount = max( scount, dcount * 2 );
if (scount < 16)
regs.sd.s[scount++] = V_R4(arg);
else
args[argspos++] = V_UI4(arg);
break;
#endif
default:
if (rcount < 4)
regs.r[rcount++] = V_UI4(arg);
else
args[argspos++] = V_UI4(arg);
break;
}
TRACE("arg %u: type %s %s\n", i, debugstr_vt(prgvt[i]), debugstr_variant(arg));
}
argspos += (argspos % 2); /* Make sure stack function alignment is 8-byte */
switch (vtReturn)
{
case VT_EMPTY: /* EMPTY = no return value */
case VT_DECIMAL: /* DECIMAL and VARIANT already have a pointer argument passed (see above) */
case VT_VARIANT:
call_method( func, argspos, args, (DWORD*)&regs );
break;
case VT_R4:
V_R4(pvargResult) = call_float_method( func, argspos, args, (DWORD*)&regs );
break;
case VT_R8:
case VT_DATE:
V_R8(pvargResult) = call_double_method( func, argspos, args, (DWORD*)&regs );
break;
case VT_I8:
case VT_UI8:
case VT_CY:
V_UI8(pvargResult) = call_method( func, argspos, args, (DWORD*)&regs );
break;
default:
V_UI4(pvargResult) = call_method( func, argspos, args, (DWORD*)&regs );
break;
}
heap_free( args );
if (vtReturn != VT_VARIANT) V_VT(pvargResult) = vtReturn;
TRACE("retval: %s\n", debugstr_variant(pvargResult));
return S_OK;
#else #else
FIXME( "(%p, %ld, %d, %d, %d, %p, %p, %p (vt=%d)): not implemented for this CPU\n", FIXME( "(%p, %ld, %d, %d, %d, %p, %p, %p (vt=%d)): not implemented for this CPU\n",
pvInstance, oVft, cc, vtReturn, cActuals, prgvt, prgpvarg, pvargResult, V_VT(pvargResult)); pvInstance, oVft, cc, vtReturn, cActuals, prgvt, prgpvarg, pvargResult, V_VT(pvargResult));
@ -7099,6 +7049,7 @@ static HRESULT WINAPI ITypeInfo_fnInvoke(
UINT cNamedArgs = pDispParams->cNamedArgs; UINT cNamedArgs = pDispParams->cNamedArgs;
DISPID *rgdispidNamedArgs = pDispParams->rgdispidNamedArgs; DISPID *rgdispidNamedArgs = pDispParams->rgdispidNamedArgs;
UINT vargs_converted=0; UINT vargs_converted=0;
ULONG_PTR offset;
hres = S_OK; hres = S_OK;
@ -7196,7 +7147,8 @@ static HRESULT WINAPI ITypeInfo_fnInvoke(
break; break;
} }
} }
else if (src_arg) else if (src_arg && !((wParamFlags & PARAMFLAG_FOPT) &&
V_VT(src_arg) == VT_ERROR && V_ERROR(src_arg) == DISP_E_PARAMNOTFOUND))
{ {
TRACE("%s\n", debugstr_variant(src_arg)); TRACE("%s\n", debugstr_variant(src_arg));
@ -7295,7 +7247,10 @@ static HRESULT WINAPI ITypeInfo_fnInvoke(
IUnknown *userdefined_iface; IUnknown *userdefined_iface;
GUID guid; GUID guid;
hres = get_iface_guid((ITypeInfo*)iface, tdesc->vt == VT_PTR ? tdesc->u.lptdesc : tdesc, &guid); if (tdesc->vt == VT_PTR)
tdesc = tdesc->u.lptdesc;
hres = get_iface_guid((ITypeInfo*)iface, tdesc->u.hreftype, &guid);
if(FAILED(hres)) if(FAILED(hres))
break; break;
@ -7343,7 +7298,11 @@ static HRESULT WINAPI ITypeInfo_fnInvoke(
break; break;
} }
} }
if (FAILED(hres)) goto func_fail; /* FIXME: we don't free changed types here */ if (FAILED(hres))
{
ERR("failed: %08x\n", hres);
goto func_fail; /* FIXME: we don't free changed types here */
}
/* VT_VOID is a special case for return types, so it is not /* VT_VOID is a special case for return types, so it is not
* handled in the general function */ * handled in the general function */
@ -7356,7 +7315,16 @@ static HRESULT WINAPI ITypeInfo_fnInvoke(
if (FAILED(hres)) goto func_fail; /* FIXME: we don't free changed types here */ if (FAILED(hres)) goto func_fail; /* FIXME: we don't free changed types here */
} }
hres = DispCallFunc(pIUnk, func_desc->oVft & 0xFFFC, func_desc->callconv, offset = func_desc->oVft & 0xFFFC;
#ifdef _WIN64
if (This->pTypeLib->syskind == SYS_WIN32)
{
offset *= 2;
TRACE("extended offset to %#lx for SYS_WIN32\n", offset);
}
#endif
TRACE("func_desc->oVft %#x, offset %#lx\n", func_desc->oVft, offset);
hres = DispCallFunc(pIUnk, offset, func_desc->callconv,
V_VT(&varresult), func_desc->cParams, rgvt, V_VT(&varresult), func_desc->cParams, rgvt,
prgpvarg, &varresult); prgpvarg, &varresult);
@ -7483,7 +7451,7 @@ static HRESULT WINAPI ITypeInfo_fnInvoke(
* pointer to be valid */ * pointer to be valid */
VariantInit(pVarResult); VariantInit(pVarResult);
hres = IDispatch_Invoke(pDispatch, DISPID_VALUE, &IID_NULL, hres = IDispatch_Invoke(pDispatch, DISPID_VALUE, &IID_NULL,
GetSystemDefaultLCID(), wFlags, GetSystemDefaultLCID(), INVOKE_PROPERTYGET,
pDispParams, pVarResult, pExcepInfo, pArgErr); pDispParams, pVarResult, pExcepInfo, pArgErr);
IDispatch_Release(pDispatch); IDispatch_Release(pDispatch);
} }

View file

@ -381,18 +381,18 @@ typedef struct {
/* we then get 0x40 bytes worth of 0xffff or small numbers followed by /* we then get 0x40 bytes worth of 0xffff or small numbers followed by
nrOfFileBlks - 2 of these */ nrOfFileBlks - 2 of these */
typedef struct { typedef struct {
WORD small_no;
SLTG_Name index_name; /* This refers to a name in the directory */ SLTG_Name index_name; /* This refers to a name in the directory */
SLTG_Name other_name; /* Another one of these weird names */ SLTG_Name other_name; /* Another one of these weird names */
WORD res1a; /* 0xffff */ WORD res1a; /* 0xffff */
WORD name_offs; /* offset to name in name table */ WORD name_offs; /* offset to name in name table */
WORD more_bytes; /* if this is non-zero we get this many WORD hlpstr_len; /* if this is non-zero we get this many
bytes before the next element, which seem bytes before the next element, which seem
to reference the docstring of the type ? */ to reference the docstring of the type ? */
WORD res20; /* 0xffff */ WORD res20; /* 0xffff */
DWORD helpcontext; DWORD helpcontext;
WORD res26; /* 0xffff */ WORD res26; /* 0xffff */
GUID uuid; GUID uuid;
WORD typekind;
} SLTG_OtherTypeInfo; } SLTG_OtherTypeInfo;
/* Next we get WORD 0x0003 followed by a DWORD which if we add to /* Next we get WORD 0x0003 followed by a DWORD which if we add to
@ -612,7 +612,7 @@ static inline BOOL heap_free( LPVOID mem )
HRESULT ITypeInfoImpl_GetInternalFuncDesc( ITypeInfo *iface, UINT index, const FUNCDESC **ppFuncDesc ) DECLSPEC_HIDDEN; HRESULT ITypeInfoImpl_GetInternalFuncDesc( ITypeInfo *iface, UINT index, const FUNCDESC **ppFuncDesc ) DECLSPEC_HIDDEN;
extern DWORD _invoke(FARPROC func,CALLCONV callconv, int nrargs, DWORD *args) DECLSPEC_HIDDEN; extern DWORD _invoke(FARPROC func, CALLCONV callconv, int nrargs, DWORD_PTR *args) DECLSPEC_HIDDEN;
HRESULT TMARSHAL_DllGetClassObject(REFCLSID rclsid, REFIID iid,LPVOID *ppv) DECLSPEC_HIDDEN; HRESULT TMARSHAL_DllGetClassObject(REFCLSID rclsid, REFIID iid,LPVOID *ppv) DECLSPEC_HIDDEN;

View file

@ -2145,7 +2145,7 @@ HRESULT WINAPI VarNumFromParseNum(NUMPARSE *pNumprs, BYTE *rgbDig,
multiplier10, divisor10); multiplier10, divisor10);
if (dwVtBits & (INTEGER_VTBITS|VTBIT_DECIMAL) && if (dwVtBits & (INTEGER_VTBITS|VTBIT_DECIMAL) &&
(!fractionalDigits || !(dwVtBits & (REAL_VTBITS|VTBIT_DECIMAL)))) (!fractionalDigits || !(dwVtBits & (REAL_VTBITS|VTBIT_CY|VTBIT_DECIMAL))))
{ {
/* We have one or more integer output choices, and either: /* We have one or more integer output choices, and either:
* 1) An integer input value, or * 1) An integer input value, or
@ -2259,7 +2259,7 @@ HRESULT WINAPI VarNumFromParseNum(NUMPARSE *pNumprs, BYTE *rgbDig,
V_I8(pVarDst) = -ul64; V_I8(pVarDst) = -ul64;
return S_OK; return S_OK;
} }
else if ((dwVtBits & (REAL_VTBITS|VTBIT_DECIMAL)) == VTBIT_DECIMAL) else if ((dwVtBits & REAL_VTBITS) == VTBIT_DECIMAL)
{ {
/* Decimal is only output choice left - fast path */ /* Decimal is only output choice left - fast path */
V_VT(pVarDst) = VT_DECIMAL; V_VT(pVarDst) = VT_DECIMAL;
@ -2321,7 +2321,7 @@ HRESULT WINAPI VarNumFromParseNum(NUMPARSE *pNumprs, BYTE *rgbDig,
V_UI8(pVarDst) = ul64; V_UI8(pVarDst) = ul64;
return S_OK; return S_OK;
} }
else if ((dwVtBits & (REAL_VTBITS|VTBIT_DECIMAL)) == VTBIT_DECIMAL) else if ((dwVtBits & REAL_VTBITS) == VTBIT_DECIMAL)
{ {
/* Decimal is only output choice left - fast path */ /* Decimal is only output choice left - fast path */
V_VT(pVarDst) = VT_DECIMAL; V_VT(pVarDst) = VT_DECIMAL;
@ -2376,8 +2376,8 @@ HRESULT WINAPI VarNumFromParseNum(NUMPARSE *pNumprs, BYTE *rgbDig,
{ {
if (whole < dblMinimums[10] && whole != 0) if (whole < dblMinimums[10] && whole != 0)
{ {
whole = 0; /* ignore underflow */ dwVtBits &= ~(VTBIT_R4|VTBIT_R8|VTBIT_CY); /* Underflow */
divisor10 = 0; bOverflow = TRUE;
break; break;
} }
whole = whole / dblMultipliers[10]; whole = whole / dblMultipliers[10];
@ -2387,8 +2387,8 @@ HRESULT WINAPI VarNumFromParseNum(NUMPARSE *pNumprs, BYTE *rgbDig,
{ {
if (whole < dblMinimums[divisor10] && whole != 0) if (whole < dblMinimums[divisor10] && whole != 0)
{ {
whole = 0; /* ignore underflow */ dwVtBits &= ~(VTBIT_R4|VTBIT_R8|VTBIT_CY); /* Underflow */
divisor10 = 0; bOverflow = TRUE;
} }
else else
whole = whole / dblMultipliers[divisor10]; whole = whole / dblMultipliers[divisor10];

View file

@ -5362,7 +5362,7 @@ static HRESULT VARIANT_DI_normalize(VARIANT_DI * val, int exponent2, BOOL isDoub
end of the bit representation, down to the precision guaranteed by the end of the bit representation, down to the precision guaranteed by the
floating point number. */ floating point number. */
if (isDouble) { if (isDouble) {
while (exponent10 < 0 && (val->bitsnum[2] != 0 || (val->bitsnum[1] & 0xFFE00000) != 0)) { while (exponent10 < 0 && (val->bitsnum[2] != 0 || (val->bitsnum[2] == 0 && (val->bitsnum[1] & 0xFFE00000) != 0))) {
int rem10; int rem10;
rem10 = VARIANT_int_divbychar(val->bitsnum, 3, 10); rem10 = VARIANT_int_divbychar(val->bitsnum, 3, 10);

View file

@ -141,7 +141,7 @@ reactos/dll/win32/odbc32 # Synced to WineStaging-2.9. Depends on po
reactos/dll/win32/odbccp32 # Synced to WineStaging-2.9 reactos/dll/win32/odbccp32 # Synced to WineStaging-2.9
reactos/dll/win32/ole32 # Synced to Wine-3.0 reactos/dll/win32/ole32 # Synced to Wine-3.0
reactos/dll/win32/oleacc # Synced to WineStaging-2.9 reactos/dll/win32/oleacc # Synced to WineStaging-2.9
reactos/dll/win32/oleaut32 # Synced to Wine-3.0 reactos/dll/win32/oleaut32 # Synced to WineStaging-2.16
reactos/dll/win32/olecli32 # Synced to WineStaging-2.9 reactos/dll/win32/olecli32 # Synced to WineStaging-2.9
reactos/dll/win32/oledlg # Synced to WineStaging-2.9 reactos/dll/win32/oledlg # Synced to WineStaging-2.9
reactos/dll/win32/olepro32 # Synced to WineStaging-2.9 reactos/dll/win32/olepro32 # Synced to WineStaging-2.9