mirror of
https://github.com/reactos/reactos.git
synced 2024-07-02 02:34:53 +00:00
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:
parent
4a5b30ee1f
commit
2b57c9f47d
|
@ -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)
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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( ®s.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*)®s );
|
|
||||||
break;
|
|
||||||
case VT_R4:
|
|
||||||
V_R4(pvargResult) = call_float_method( func, argspos, args, (DWORD*)®s );
|
|
||||||
break;
|
|
||||||
case VT_R8:
|
|
||||||
case VT_DATE:
|
|
||||||
V_R8(pvargResult) = call_double_method( func, argspos, args, (DWORD*)®s );
|
|
||||||
break;
|
|
||||||
case VT_I8:
|
|
||||||
case VT_UI8:
|
|
||||||
case VT_CY:
|
|
||||||
V_UI8(pvargResult) = call_method( func, argspos, args, (DWORD*)®s );
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
V_UI4(pvargResult) = call_method( func, argspos, args, (DWORD*)®s );
|
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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];
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue