https://git.reactos.org/?p=reactos.git;a=commitdiff;h=5db885cae7050f4699938…
commit 5db885cae7050f46999387ffd88ea6b8a1d512be
Author: Amine Khaldi <amine.khaldi(a)reactos.org>
AuthorDate: Tue Jan 29 13:18:42 2019 +0100
Commit: Amine Khaldi <amine.khaldi(a)reactos.org>
CommitDate: Tue Jan 29 13:18:42 2019 +0100
[OLEAUT32] Sync with Wine Staging 4.0. CORE-15682
---
dll/win32/oleaut32/CMakeLists.txt | 1 -
dll/win32/oleaut32/msvc.S | 5 +
dll/win32/oleaut32/oleaut.c | 294 ++++-
dll/win32/oleaut32/olefont.c | 4 +-
dll/win32/oleaut32/olepicture.c | 196 +--
dll/win32/oleaut32/safearray.c | 2 +-
dll/win32/oleaut32/tmarshal.c | 2480 -------------------------------------
dll/win32/oleaut32/typelib.c | 222 ++--
dll/win32/oleaut32/typelib.h | 23 +-
dll/win32/oleaut32/usrmarshal.c | 6 +-
dll/win32/oleaut32/varformat.c | 66 +-
dll/win32/oleaut32/variant.c | 24 +-
dll/win32/oleaut32/vartype.c | 131 +-
media/doc/README.WINE | 2 +-
sdk/include/psdk/oleauto.h | 24 +-
15 files changed, 585 insertions(+), 2895 deletions(-)
diff --git a/dll/win32/oleaut32/CMakeLists.txt b/dll/win32/oleaut32/CMakeLists.txt
index 26c2149a2a..1eae81ee81 100644
--- a/dll/win32/oleaut32/CMakeLists.txt
+++ b/dll/win32/oleaut32/CMakeLists.txt
@@ -25,7 +25,6 @@ list(APPEND SOURCE
olepropframe.c
recinfo.c
safearray.c
- tmarshal.c
typelib.c
usrmarshal.c
varformat.c
diff --git a/dll/win32/oleaut32/msvc.S b/dll/win32/oleaut32/msvc.S
index ddb3fa8d6e..0d088d3e8c 100644
--- a/dll/win32/oleaut32/msvc.S
+++ b/dll/win32/oleaut32/msvc.S
@@ -49,6 +49,11 @@ cm1:
pop esi
pop ebp
ret
+
+PUBLIC _call_double_method
+_call_double_method:
+ jmp _call_method
+
#endif
END
diff --git a/dll/win32/oleaut32/oleaut.c b/dll/win32/oleaut32/oleaut.c
index ee3ff27336..8c5d68fee2 100644
--- a/dll/win32/oleaut32/oleaut.c
+++ b/dll/win32/oleaut32/oleaut.c
@@ -21,6 +21,7 @@
#include "config.h"
#include <stdarg.h>
+#include <stdio.h>
#include <string.h>
#include <limits.h>
@@ -122,9 +123,7 @@ static inline bstr_t *bstr_from_str(BSTR str)
static inline bstr_cache_entry_t *get_cache_entry_from_idx(unsigned cache_idx)
{
- return bstr_cache_enabled && cache_idx <
sizeof(bstr_cache)/sizeof(*bstr_cache)
- ? bstr_cache + cache_idx
- : NULL;
+ return bstr_cache_enabled && cache_idx < ARRAY_SIZE(bstr_cache) ?
bstr_cache + cache_idx : NULL;
}
static inline bstr_cache_entry_t *get_cache_entry(size_t size)
@@ -272,7 +271,7 @@ static inline IMalloc *get_malloc(void)
* See BSTR.
* str may be NULL, in which case this function does nothing.
*/
-void WINAPI SysFreeString(BSTR str)
+void WINAPI DECLSPEC_HOTPATCH SysFreeString(BSTR str)
{
bstr_cache_entry_t *cache_entry;
bstr_t *bstr;
@@ -304,7 +303,7 @@ void WINAPI SysFreeString(BSTR str)
}
}
- if(cache_entry->cnt <
sizeof(cache_entry->buf)/sizeof(*cache_entry->buf)) {
+ if(cache_entry->cnt < ARRAY_SIZE(cache_entry->buf)) {
cache_entry->buf[(cache_entry->head+cache_entry->cnt) %
BUCKET_BUFFER_SIZE] = bstr;
cache_entry->cnt++;
@@ -429,7 +428,7 @@ int WINAPI SysReAllocStringLen(BSTR* old, const OLECHAR* str, unsigned
int len)
* without checking for a terminating NUL.
* See BSTR.
*/
-BSTR WINAPI SysAllocStringByteLen(LPCSTR str, UINT len)
+BSTR WINAPI DECLSPEC_HOTPATCH SysAllocStringByteLen(LPCSTR str, UINT len)
{
bstr_t *bstr;
@@ -768,6 +767,230 @@ extern BOOL WINAPI OLEAUTPS_DllMain(HINSTANCE, DWORD, LPVOID)
DECLSPEC_HIDDEN;
extern HRESULT WINAPI OLEAUTPS_DllRegisterServer(void) DECLSPEC_HIDDEN;
extern HRESULT WINAPI OLEAUTPS_DllUnregisterServer(void) DECLSPEC_HIDDEN;
+extern HRESULT WINAPI CreateProxyFromTypeInfo(ITypeInfo *typeinfo,
+ IUnknown *outer, REFIID iid, IRpcProxyBuffer **proxy, void **obj);
+extern HRESULT WINAPI CreateStubFromTypeInfo(ITypeInfo *typeinfo, REFIID iid,
+ IUnknown *server, IRpcStubBuffer **stub);
+
+struct ifacepsredirect_data
+{
+ ULONG size;
+ DWORD mask;
+ GUID iid;
+ ULONG nummethods;
+ GUID tlbid;
+ GUID base;
+ ULONG name_len;
+ ULONG name_offset;
+};
+
+struct tlibredirect_data
+{
+ ULONG size;
+ DWORD res;
+ ULONG name_len;
+ ULONG name_offset;
+ LANGID langid;
+ WORD flags;
+ ULONG help_len;
+ ULONG help_offset;
+ WORD major_version;
+ WORD minor_version;
+};
+
+static BOOL actctx_get_typelib_module(REFIID iid, WCHAR *module, DWORD len)
+{
+ struct ifacepsredirect_data *iface;
+ struct tlibredirect_data *tlib;
+ ACTCTX_SECTION_KEYED_DATA data;
+ WCHAR *ptrW;
+
+ data.cbSize = sizeof(data);
+ if (!FindActCtxSectionGuid(0, NULL,
ACTIVATION_CONTEXT_SECTION_COM_INTERFACE_REDIRECTION,
+ iid, &data))
+ return FALSE;
+
+ iface = (struct ifacepsredirect_data *)data.lpData;
+ if (!FindActCtxSectionGuid(0, NULL,
ACTIVATION_CONTEXT_SECTION_COM_TYPE_LIBRARY_REDIRECTION,
+ &iface->tlbid, &data))
+ return FALSE;
+
+ tlib = (struct tlibredirect_data *)data.lpData;
+ ptrW = (WCHAR *)((BYTE *)data.lpSectionBase + tlib->name_offset);
+
+ if (tlib->name_len/sizeof(WCHAR) >= len)
+ {
+ ERR("need larger module buffer, %u\n", tlib->name_len);
+ return FALSE;
+ }
+
+ memcpy(module, ptrW, tlib->name_len);
+ module[tlib->name_len/sizeof(WCHAR)] = 0;
+ return TRUE;
+}
+
+static HRESULT reg_get_typelib_module(REFIID iid, WCHAR *module, DWORD len)
+{
+ REGSAM opposite = (sizeof(void*) == 8) ? KEY_WOW64_32KEY : KEY_WOW64_64KEY;
+ char tlguid[200], typelibkey[300], interfacekey[300], ver[100], tlfn[260];
+ DWORD tlguidlen, verlen, type;
+ LONG tlfnlen, err;
+ BOOL is_wow64;
+ HKEY ikey;
+
+ sprintf( interfacekey,
"Interface\\{%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}\\Typelib",
+ iid->Data1, iid->Data2, iid->Data3,
+ iid->Data4[0], iid->Data4[1], iid->Data4[2], iid->Data4[3],
+ iid->Data4[4], iid->Data4[5], iid->Data4[6], iid->Data4[7]
+ );
+
+ err = RegOpenKeyExA(HKEY_CLASSES_ROOT,interfacekey,0,KEY_READ,&ikey);
+ if (err && (opposite == KEY_WOW64_32KEY ||
(IsWow64Process(GetCurrentProcess(), &is_wow64)
+ && is_wow64)))
+ err =
RegOpenKeyExA(HKEY_CLASSES_ROOT,interfacekey,0,KEY_READ|opposite,&ikey);
+
+ if (err)
+ {
+ ERR("No %s key found.\n", interfacekey);
+ return E_FAIL;
+ }
+
+ tlguidlen = sizeof(tlguid);
+ if (RegQueryValueExA(ikey, NULL, NULL, &type, (BYTE *)tlguid, &tlguidlen))
+ {
+ ERR("Getting typelib guid failed.\n");
+ RegCloseKey(ikey);
+ return E_FAIL;
+ }
+
+ verlen = sizeof(ver);
+ if (RegQueryValueExA(ikey, "Version", NULL, &type, (BYTE *)ver,
&verlen))
+ {
+ ERR("Could not get version value?\n");
+ RegCloseKey(ikey);
+ return E_FAIL;
+ }
+
+ RegCloseKey(ikey);
+
+ sprintf(typelibkey, "Typelib\\%s\\%s\\0\\win%u", tlguid, ver, sizeof(void
*) == 8 ? 64 : 32);
+ tlfnlen = sizeof(tlfn);
+ if (RegQueryValueA(HKEY_CLASSES_ROOT, typelibkey, tlfn, &tlfnlen))
+ {
+#ifdef _WIN64
+ sprintf(typelibkey, "Typelib\\%s\\%s\\0\\win32", tlguid, ver);
+ tlfnlen = sizeof(tlfn);
+ if (RegQueryValueA(HKEY_CLASSES_ROOT, typelibkey, tlfn, &tlfnlen))
+ {
+#endif
+ ERR("Could not get typelib fn?\n");
+ return E_FAIL;
+#ifdef _WIN64
+ }
+#endif
+ }
+ MultiByteToWideChar(CP_ACP, 0, tlfn, -1, module, len);
+ return S_OK;
+}
+
+static HRESULT get_typeinfo_for_iid(REFIID iid, ITypeInfo **typeinfo)
+{
+ WCHAR module[MAX_PATH];
+ ITypeLib *typelib;
+ HRESULT hr;
+
+ *typeinfo = NULL;
+
+ module[0] = 0;
+ if (!actctx_get_typelib_module(iid, module, ARRAY_SIZE(module)))
+ {
+ hr = reg_get_typelib_module(iid, module, ARRAY_SIZE(module));
+ if (FAILED(hr))
+ return hr;
+ }
+
+ hr = LoadTypeLib(module, &typelib);
+ if (hr != S_OK) {
+ ERR("Failed to load typelib for %s, but it should be there.\n",
debugstr_guid(iid));
+ return hr;
+ }
+
+ hr = ITypeLib_GetTypeInfoOfGuid(typelib, iid, typeinfo);
+ ITypeLib_Release(typelib);
+ if (hr != S_OK)
+ ERR("typelib does not contain info for %s\n", debugstr_guid(iid));
+
+ return hr;
+}
+
+static HRESULT WINAPI typelib_ps_QueryInterface(IPSFactoryBuffer *iface, REFIID iid, void
**out)
+{
+ if (IsEqualIID(iid, &IID_IPSFactoryBuffer) || IsEqualIID(iid,
&IID_IUnknown))
+ {
+ *out = iface;
+ return S_OK;
+ }
+
+ FIXME("No interface for %s.\n", debugstr_guid(iid));
+ *out = NULL;
+ return E_NOINTERFACE;
+}
+
+static ULONG WINAPI typelib_ps_AddRef(IPSFactoryBuffer *iface)
+{
+ return 2;
+}
+
+static ULONG WINAPI typelib_ps_Release(IPSFactoryBuffer *iface)
+{
+ return 1;
+}
+
+static HRESULT WINAPI typelib_ps_CreateProxy(IPSFactoryBuffer *iface,
+ IUnknown *outer, REFIID iid, IRpcProxyBuffer **proxy, void **out)
+{
+ ITypeInfo *typeinfo;
+ HRESULT hr;
+
+ hr = get_typeinfo_for_iid(iid, &typeinfo);
+ if (FAILED(hr)) return hr;
+
+ hr = CreateProxyFromTypeInfo(typeinfo, outer, iid, proxy, out);
+ if (FAILED(hr))
+ ERR("Failed to create proxy, hr %#x.\n", hr);
+
+ ITypeInfo_Release(typeinfo);
+ return hr;
+}
+
+static HRESULT WINAPI typelib_ps_CreateStub(IPSFactoryBuffer *iface, REFIID iid,
+ IUnknown *server, IRpcStubBuffer **stub)
+{
+ ITypeInfo *typeinfo;
+ HRESULT hr;
+
+ hr = get_typeinfo_for_iid(iid, &typeinfo);
+ if (FAILED(hr)) return hr;
+
+ hr = CreateStubFromTypeInfo(typeinfo, iid, server, stub);
+ if (FAILED(hr))
+ ERR("Failed to create stub, hr %#x.\n", hr);
+
+ ITypeInfo_Release(typeinfo);
+ return hr;
+}
+
+static const IPSFactoryBufferVtbl typelib_ps_vtbl =
+{
+ typelib_ps_QueryInterface,
+ typelib_ps_AddRef,
+ typelib_ps_Release,
+ typelib_ps_CreateProxy,
+ typelib_ps_CreateStub,
+};
+
+static IPSFactoryBuffer typelib_ps = { &typelib_ps_vtbl };
+
extern void _get_STDFONT_CF(LPVOID *);
extern void _get_STDPIC_CF(LPVOID *);
@@ -793,40 +1016,42 @@ static ULONG WINAPI PSDispatchFacBuf_Release(IPSFactoryBuffer
*iface)
return 1;
}
-static HRESULT WINAPI PSDispatchFacBuf_CreateProxy(IPSFactoryBuffer *iface, IUnknown
*pUnkOuter, REFIID riid, IRpcProxyBuffer **ppProxy, void **ppv)
+static HRESULT WINAPI PSDispatchFacBuf_CreateProxy(IPSFactoryBuffer *iface,
+ IUnknown *outer, REFIID iid, IRpcProxyBuffer **proxy, void **obj)
{
- IPSFactoryBuffer *pPSFB;
+ IPSFactoryBuffer *factory;
HRESULT hr;
- if (IsEqualIID(riid, &IID_IDispatch))
- hr = OLEAUTPS_DllGetClassObject(&CLSID_PSFactoryBuffer,
&IID_IPSFactoryBuffer, (void **)&pPSFB);
- else
- hr = TMARSHAL_DllGetClassObject(&CLSID_PSOAInterface,
&IID_IPSFactoryBuffer, (void **)&pPSFB);
-
- if (FAILED(hr)) return hr;
-
- hr = IPSFactoryBuffer_CreateProxy(pPSFB, pUnkOuter, riid, ppProxy, ppv);
+ if (IsEqualIID(iid, &IID_IDispatch))
+ {
+ hr = OLEAUTPS_DllGetClassObject(&CLSID_PSFactoryBuffer,
&IID_IPSFactoryBuffer, (void **)&factory);
+ if (FAILED(hr)) return hr;
- IPSFactoryBuffer_Release(pPSFB);
- return hr;
+ hr = IPSFactoryBuffer_CreateProxy(factory, outer, iid, proxy, obj);
+ IPSFactoryBuffer_Release(factory);
+ return hr;
+ }
+ else
+ return IPSFactoryBuffer_CreateProxy(&typelib_ps, outer, iid, proxy, obj);
}
-static HRESULT WINAPI PSDispatchFacBuf_CreateStub(IPSFactoryBuffer *iface, REFIID riid,
IUnknown *pUnkOuter, IRpcStubBuffer **ppStub)
+static HRESULT WINAPI PSDispatchFacBuf_CreateStub(IPSFactoryBuffer *iface,
+ REFIID iid, IUnknown *server, IRpcStubBuffer **stub)
{
- IPSFactoryBuffer *pPSFB;
+ IPSFactoryBuffer *factory;
HRESULT hr;
- if (IsEqualIID(riid, &IID_IDispatch))
- hr = OLEAUTPS_DllGetClassObject(&CLSID_PSFactoryBuffer,
&IID_IPSFactoryBuffer, (void **)&pPSFB);
- else
- hr = TMARSHAL_DllGetClassObject(&CLSID_PSOAInterface,
&IID_IPSFactoryBuffer, (void **)&pPSFB);
-
- if (FAILED(hr)) return hr;
-
- hr = IPSFactoryBuffer_CreateStub(pPSFB, riid, pUnkOuter, ppStub);
+ if (IsEqualIID(iid, &IID_IDispatch))
+ {
+ hr = OLEAUTPS_DllGetClassObject(&CLSID_PSFactoryBuffer,
&IID_IPSFactoryBuffer, (void **)&factory);
+ if (FAILED(hr)) return hr;
- IPSFactoryBuffer_Release(pPSFB);
- return hr;
+ hr = IPSFactoryBuffer_CreateStub(factory, iid, server, stub);
+ IPSFactoryBuffer_Release(factory);
+ return hr;
+ }
+ else
+ return IPSFactoryBuffer_CreateStub(&typelib_ps, iid, server, stub);
}
static const IPSFactoryBufferVtbl PSDispatchFacBuf_Vtbl =
@@ -866,11 +1091,10 @@ HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID iid,
LPVOID *ppv)
IPSFactoryBuffer_AddRef((IPSFactoryBuffer *)*ppv);
return S_OK;
}
- if (IsEqualGUID(rclsid,&CLSID_PSOAInterface)) {
- if (S_OK==TMARSHAL_DllGetClassObject(rclsid,iid,ppv))
- return S_OK;
- /*FALLTHROUGH*/
- }
+
+ if (IsEqualGUID(rclsid, &CLSID_PSOAInterface))
+ return IPSFactoryBuffer_QueryInterface(&typelib_ps, iid, ppv);
+
if (IsEqualCLSID(rclsid, &CLSID_PSTypeComp) ||
IsEqualCLSID(rclsid, &CLSID_PSTypeInfo) ||
IsEqualCLSID(rclsid, &CLSID_PSTypeLib) ||
diff --git a/dll/win32/oleaut32/olefont.c b/dll/win32/oleaut32/olefont.c
index c20093c702..9628dc091e 100644
--- a/dll/win32/oleaut32/olefont.c
+++ b/dll/win32/oleaut32/olefont.c
@@ -591,7 +591,7 @@ static void realize_font(OLEFontImpl *This)
if(This->gdiFont)
{
old_font = SelectObject(hdc, This->gdiFont);
- GetTextFaceW(hdc, sizeof(text_face) / sizeof(text_face[0]), text_face);
+ GetTextFaceW(hdc, ARRAY_SIZE(text_face), text_face);
SelectObject(hdc, old_font);
dec_int_ref(This->gdiFont);
This->gdiFont = 0;
@@ -645,7 +645,7 @@ static void realize_font(OLEFontImpl *This)
/* Fixup the name and charset properties so that they match the
selected font */
old_font = SelectObject(get_dc(), This->gdiFont);
- GetTextFaceW(hdc, sizeof(text_face) / sizeof(text_face[0]), text_face);
+ GetTextFaceW(hdc, ARRAY_SIZE(text_face), text_face);
if(lstrcmpiW(text_face, This->description.lpstrName))
{
HeapFree(GetProcessHeap(), 0, This->description.lpstrName);
diff --git a/dll/win32/oleaut32/olepicture.c b/dll/win32/oleaut32/olepicture.c
index 96304e0644..702fcde86d 100644
--- a/dll/win32/oleaut32/olepicture.c
+++ b/dll/win32/oleaut32/olepicture.c
@@ -287,9 +287,10 @@ static void OLEPictureImpl_SetEMF(OLEPictureImpl *This)
* The caller of this method must release the object when it's
* done with it.
*/
-static OLEPictureImpl* OLEPictureImpl_Construct(LPPICTDESC pictDesc, BOOL fOwn)
+static HRESULT OLEPictureImpl_Construct(LPPICTDESC pictDesc, BOOL fOwn, OLEPictureImpl
**pict)
{
- OLEPictureImpl* newObject = 0;
+ OLEPictureImpl *newObject;
+ HRESULT hr;
if (pictDesc)
TRACE("(%p) type = %d\n", pictDesc, pictDesc->picType);
@@ -298,9 +299,8 @@ static OLEPictureImpl* OLEPictureImpl_Construct(LPPICTDESC pictDesc,
BOOL fOwn)
* Allocate space for the object.
*/
newObject = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(OLEPictureImpl));
-
- if (newObject==0)
- return newObject;
+ if (!newObject)
+ return E_OUTOFMEMORY;
/*
* Initialize the virtual function table.
@@ -311,12 +311,12 @@ static OLEPictureImpl* OLEPictureImpl_Construct(LPPICTDESC pictDesc,
BOOL fOwn)
newObject->IConnectionPointContainer_iface.lpVtbl =
&OLEPictureImpl_IConnectionPointContainer_VTable;
newObject->pCP = NULL;
- CreateConnectionPoint((IUnknown*)&newObject->IPicture_iface,
&IID_IPropertyNotifySink,
+ hr = CreateConnectionPoint((IUnknown*)&newObject->IPicture_iface,
&IID_IPropertyNotifySink,
&newObject->pCP);
- if (!newObject->pCP)
+ if (hr != S_OK)
{
HeapFree(GetProcessHeap(), 0, newObject);
- return NULL;
+ return hr;
}
/*
@@ -365,16 +365,17 @@ static OLEPictureImpl* OLEPictureImpl_Construct(LPPICTDESC pictDesc,
BOOL fOwn)
break;
default:
- FIXME("Unsupported type %d\n", pictDesc->picType);
- newObject->himetricWidth = newObject->himetricHeight = 0;
- break;
+ WARN("Unsupported type %d\n", pictDesc->picType);
+ IPicture_Release(&newObject->IPicture_iface);
+ return E_UNEXPECTED;
}
} else {
newObject->desc.picType = PICTYPE_UNINITIALIZED;
}
TRACE("returning %p\n", newObject);
- return newObject;
+ *pict = newObject;
+ return S_OK;
}
/************************************************************************
@@ -565,37 +566,19 @@ static HRESULT WINAPI OLEPictureImpl_get_Handle(IPicture *iface,
static HRESULT WINAPI OLEPictureImpl_get_hPal(IPicture *iface,
OLE_HANDLE *phandle)
{
- OLEPictureImpl *This = impl_from_IPicture(iface);
- HRESULT hres;
- TRACE("(%p)->(%p)\n", This, phandle);
+ OLEPictureImpl *This = impl_from_IPicture(iface);
- if (!phandle)
- return E_POINTER;
+ TRACE("(%p)->(%p)\n", This, phandle);
- switch (This->desc.picType) {
- case (UINT)PICTYPE_UNINITIALIZED:
- case PICTYPE_NONE:
- *phandle = 0;
- hres = S_FALSE;
- break;
- case PICTYPE_BITMAP:
- *phandle = HandleToUlong(This->desc.u.bmp.hpal);
- hres = S_OK;
- break;
- case PICTYPE_METAFILE:
- hres = E_FAIL;
- break;
- case PICTYPE_ICON:
- case PICTYPE_ENHMETAFILE:
- default:
- FIXME("unimplemented for type %d. Returning 0 palette.\n",
- This->desc.picType);
- *phandle = 0;
- hres = S_OK;
- }
+ if (!phandle) return E_POINTER;
- TRACE("returning 0x%08x, palette handle %08x\n", hres, *phandle);
- return hres;
+ if (This->desc.picType == PICTYPE_BITMAP)
+ {
+ *phandle = HandleToUlong(This->desc.u.bmp.hpal);
+ return S_OK;
+ }
+
+ return E_FAIL;
}
/************************************************************************
@@ -638,6 +621,48 @@ static HRESULT WINAPI OLEPictureImpl_get_Height(IPicture *iface,
return S_OK;
}
+static void render_masked_bitmap(OLEPictureImpl *This, HDC hdc,
+ LONG x, LONG y, LONG cx, LONG cy, OLE_XPOS_HIMETRIC xSrc, OLE_YPOS_HIMETRIC ySrc,
+ OLE_XSIZE_HIMETRIC cxSrc, OLE_YSIZE_HIMETRIC cySrc, HBITMAP hbmMask, HBITMAP hbmXor)
+{
+ HDC hdcBmp;
+
+ /* Set a mapping mode that maps bitmap pixels into HIMETRIC units.
+ * NB y-axis gets flipped
+ */
+
+ hdcBmp = CreateCompatibleDC(0);
+ SetMapMode(hdcBmp, MM_ANISOTROPIC);
+ SetWindowOrgEx(hdcBmp, 0, 0, NULL);
+ SetWindowExtEx(hdcBmp, This->himetricWidth, This->himetricHeight, NULL);
+ SetViewportOrgEx(hdcBmp, 0, This->origHeight, NULL);
+ SetViewportExtEx(hdcBmp, This->origWidth, -This->origHeight, NULL);
+
+ if (hbmMask)
+ {
+ SetBkColor(hdc, RGB(255, 255, 255));
+ SetTextColor(hdc, RGB(0, 0, 0));
+
+ SelectObject(hdcBmp, hbmMask);
+ StretchBlt(hdc, x, y, cx, cy, hdcBmp, xSrc, ySrc, cxSrc, cySrc, SRCAND);
+
+ if (hbmXor)
+ {
+ SelectObject(hdcBmp, hbmXor);
+ StretchBlt(hdc, x, y, cx, cy, hdcBmp, xSrc, ySrc, cxSrc, cySrc, SRCPAINT);
+ }
+ else StretchBlt(hdc, x, y, cx, cy, hdcBmp, xSrc, ySrc - This->himetricHeight,
+ cxSrc, cySrc, SRCPAINT);
+ }
+ else
+ {
+ SelectObject(hdcBmp, hbmXor);
+ StretchBlt(hdc, x, y, cx, cy, hdcBmp, xSrc, ySrc, cxSrc, cySrc, SRCCOPY);
+ }
+
+ DeleteDC(hdcBmp);
+}
+
/************************************************************************
* OLEPictureImpl_Render
*/
@@ -671,52 +696,37 @@ static HRESULT WINAPI OLEPictureImpl_Render(IPicture *iface, HDC
hdc,
/* nothing to do */
return S_OK;
case PICTYPE_BITMAP:
- {
- HBITMAP hbmpOld;
- HDC hdcBmp;
-
- /* Set a mapping mode that maps bitmap pixels into HIMETRIC units.
- NB y-axis gets flipped */
-
- hdcBmp = CreateCompatibleDC(0);
- SetMapMode(hdcBmp, MM_ANISOTROPIC);
- SetWindowOrgEx(hdcBmp, 0, 0, NULL);
- SetWindowExtEx(hdcBmp, This->himetricWidth, This->himetricHeight, NULL);
- SetViewportOrgEx(hdcBmp, 0, This->origHeight, NULL);
- SetViewportExtEx(hdcBmp, This->origWidth, -This->origHeight, NULL);
-
- if (This->hbmMask) {
- HDC hdcMask = CreateCompatibleDC(0);
- HBITMAP hOldbm = SelectObject(hdcMask, This->hbmMask);
-
- hbmpOld = SelectObject(hdcBmp, This->hbmXor);
-
- SetMapMode(hdcMask, MM_ANISOTROPIC);
- SetWindowOrgEx(hdcMask, 0, 0, NULL);
- SetWindowExtEx(hdcMask, This->himetricWidth, This->himetricHeight, NULL);
- SetViewportOrgEx(hdcMask, 0, This->origHeight, NULL);
- SetViewportExtEx(hdcMask, This->origWidth, -This->origHeight, NULL);
-
- SetBkColor(hdc, RGB(255, 255, 255));
- SetTextColor(hdc, RGB(0, 0, 0));
- StretchBlt(hdc, x, y, cx, cy, hdcMask, xSrc, ySrc, cxSrc, cySrc, SRCAND);
- StretchBlt(hdc, x, y, cx, cy, hdcBmp, xSrc, ySrc, cxSrc, cySrc, SRCPAINT);
-
- SelectObject(hdcMask, hOldbm);
- DeleteDC(hdcMask);
- } else {
- hbmpOld = SelectObject(hdcBmp, This->desc.u.bmp.hbitmap);
- StretchBlt(hdc, x, y, cx, cy, hdcBmp, xSrc, ySrc, cxSrc, cySrc, SRCCOPY);
- }
+ {
+ HBITMAP hbmMask, hbmXor;
- SelectObject(hdcBmp, hbmpOld);
- DeleteDC(hdcBmp);
+ if (This->hbmMask)
+ {
+ hbmMask = This->hbmMask;
+ hbmXor = This->hbmXor;
}
+ else
+ {
+ hbmMask = 0;
+ hbmXor = This->desc.u.bmp.hbitmap;
+ }
+
+ render_masked_bitmap(This, hdc, x, y, cx, cy, xSrc, ySrc, cxSrc, cySrc, hbmMask,
hbmXor);
break;
+ }
+
case PICTYPE_ICON:
- FIXME("Not quite correct implementation of rendering icons...\n");
- DrawIconEx(hdc, x, y, This->desc.u.icon.hicon, cx, cy, 0, NULL, DI_NORMAL);
+ {
+ ICONINFO info;
+
+ if (!GetIconInfo(This->desc.u.icon.hicon, &info))
+ return E_FAIL;
+
+ render_masked_bitmap(This, hdc, x, y, cx, cy, xSrc, ySrc, cxSrc, cySrc, info.hbmMask,
info.hbmColor);
+
+ DeleteObject(info.hbmMask);
+ if (info.hbmColor) DeleteObject(info.hbmColor);
break;
+ }
case PICTYPE_METAFILE:
{
@@ -767,10 +777,18 @@ static HRESULT WINAPI OLEPictureImpl_Render(IPicture *iface, HDC
hdc,
static HRESULT WINAPI OLEPictureImpl_set_hPal(IPicture *iface,
OLE_HANDLE hpal)
{
- OLEPictureImpl *This = impl_from_IPicture(iface);
- FIXME("(%p)->(%08x): stub\n", This, hpal);
- OLEPicture_SendNotify(This,DISPID_PICT_HPAL);
- return E_NOTIMPL;
+ OLEPictureImpl *This = impl_from_IPicture(iface);
+
+ TRACE("(%p)->(%08x)\n", This, hpal);
+
+ if (This->desc.picType == PICTYPE_BITMAP)
+ {
+ This->desc.u.bmp.hpal = ULongToHandle(hpal);
+ OLEPicture_SendNotify(This,DISPID_PICT_HPAL);
+ return S_OK;
+ }
+
+ return E_FAIL;
}
/************************************************************************
@@ -2310,10 +2328,8 @@ HRESULT WINAPI OleCreatePictureIndirect(LPPICTDESC lpPictDesc,
REFIID riid,
*ppvObj = NULL;
- newPict = OLEPictureImpl_Construct(lpPictDesc, Own);
-
- if (newPict == NULL)
- return E_OUTOFMEMORY;
+ hr = OLEPictureImpl_Construct(lpPictDesc, Own, &newPict);
+ if (hr != S_OK) return hr;
/*
* Make sure it supports the interface required by the caller.
@@ -2509,7 +2525,7 @@ HRESULT WINAPI OleLoadPicturePath( LPOLESTR szURLorPath, LPUNKNOWN
punkCaller,
if (strncmpW(szURLorPath, file, 5) == 0) {
DWORD size;
hRes = CoInternetParseUrl(szURLorPath, PARSE_PATH_FROM_URL, 0, path_buf,
- sizeof(path_buf)/sizeof(WCHAR), &size, 0);
+ ARRAY_SIZE(path_buf), &size, 0);
if (FAILED(hRes))
return hRes;
diff --git a/dll/win32/oleaut32/safearray.c b/dll/win32/oleaut32/safearray.c
index 01dbfc3417..64a5ab94d5 100644
--- a/dll/win32/oleaut32/safearray.c
+++ b/dll/win32/oleaut32/safearray.c
@@ -289,7 +289,7 @@ static HRESULT SAFEARRAY_DestroyData(SAFEARRAY *psa, ULONG
ulStartCell)
ULONG ulCellCount = SAFEARRAY_GetCellCount(psa);
if (ulStartCell > ulCellCount) {
- FIXME("unexpted ulcellcount %d, start %d\n",ulCellCount,ulStartCell);
+ FIXME("unexpected ulCellCount %d, start %d\n",ulCellCount,ulStartCell);
return E_UNEXPECTED;
}
diff --git a/dll/win32/oleaut32/tmarshal.c b/dll/win32/oleaut32/tmarshal.c
deleted file mode 100644
index 7530f66c9b..0000000000
--- a/dll/win32/oleaut32/tmarshal.c
+++ /dev/null
@@ -1,2480 +0,0 @@
-/*
- * TYPELIB Marshaler
- *
- * Copyright 2002,2005 Marcus Meissner
- *
- * The olerelay debug channel allows you to see calls marshalled by
- * the typelib marshaller. It is not a generic COM relaying system.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "config.h"
-#include "wine/port.h"
-
-#include <assert.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdarg.h>
-#include <stdio.h>
-#include <ctype.h>
-
-#define COBJMACROS
-#define NONAMELESSUNION
-
-#include "winerror.h"
-#include "windef.h"
-#include "winbase.h"
-#include "winnls.h"
-#include "winreg.h"
-#include "winuser.h"
-
-#include "ole2.h"
-#include "propidl.h" /* for LPSAFEARRAY_User* functions */
-#include "typelib.h"
-#include "variant.h"
-#include "wine/debug.h"
-#include "wine/exception.h"
-
-static const WCHAR IDispatchW[] = {
'I','D','i','s','p','a','t','c','h',0};
-
-WINE_DEFAULT_DEBUG_CHANNEL(ole);
-WINE_DECLARE_DEBUG_CHANNEL(olerelay);
-
-static HRESULT TMarshalDispatchChannel_Create(
- IRpcChannelBuffer *pDelegateChannel, REFIID tmarshal_riid,
- IRpcChannelBuffer **ppChannel);
-
-typedef struct _marshal_state {
- LPBYTE base;
- int size;
- int curoff;
-} marshal_state;
-
-/* used in the olerelay code to avoid having the L"" stuff added by debugstr_w
*/
-static char *relaystr(WCHAR *in) {
- char *tmp = (char *)debugstr_w(in);
- tmp += 2;
- tmp[strlen(tmp)-1] = '\0';
- return tmp;
-}
-
-static HRESULT
-xbuf_resize(marshal_state *buf, DWORD newsize)
-{
- if(buf->size >= newsize)
- return S_FALSE;
-
- if(buf->base)
- {
- newsize = max(newsize, buf->size * 2);
- buf->base = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, buf->base,
newsize);
- if(!buf->base)
- return E_OUTOFMEMORY;
- }
- else
- {
- newsize = max(newsize, 256);
- buf->base = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, newsize);
- if(!buf->base)
- return E_OUTOFMEMORY;
- }
- buf->size = newsize;
- return S_OK;
-}
-
-static HRESULT
-xbuf_add(marshal_state *buf, const BYTE *stuff, DWORD size)
-{
- HRESULT hr;
-
- if(buf->size - buf->curoff < size)
- {
- hr = xbuf_resize(buf, buf->size + size);
- if(FAILED(hr)) return hr;
- }
- memcpy(buf->base+buf->curoff,stuff,size);
- buf->curoff += size;
- return S_OK;
-}
-
-static HRESULT
-xbuf_get(marshal_state *buf, LPBYTE stuff, DWORD size) {
- if (buf->size < buf->curoff+size) return E_FAIL;
- memcpy(stuff,buf->base+buf->curoff,size);
- buf->curoff += size;
- return S_OK;
-}
-
-static HRESULT
-xbuf_skip(marshal_state *buf, DWORD size) {
- if (buf->size < buf->curoff+size) return E_FAIL;
- buf->curoff += size;
- return S_OK;
-}
-
-static HRESULT
-_unmarshal_interface(marshal_state *buf, REFIID riid, LPUNKNOWN *pUnk) {
- IStream *pStm;
- ULARGE_INTEGER newpos;
- LARGE_INTEGER seekto;
- ULONG res;
- HRESULT hres;
- DWORD xsize;
-
- TRACE("...%s...\n",debugstr_guid(riid));
-
- *pUnk = NULL;
- hres = xbuf_get(buf,(LPBYTE)&xsize,sizeof(xsize));
- if (hres) {
- ERR("xbuf_get failed\n");
- return hres;
- }
-
- if (xsize == 0) return S_OK;
-
- hres = CreateStreamOnHGlobal(0,TRUE,&pStm);
- if (hres) {
- ERR("Stream create failed %x\n",hres);
- return hres;
- }
-
- hres = IStream_Write(pStm,buf->base+buf->curoff,xsize,&res);
- if (hres) {
- ERR("stream write %x\n",hres);
- IStream_Release(pStm);
- return hres;
- }
-
- memset(&seekto,0,sizeof(seekto));
- hres = IStream_Seek(pStm,seekto,SEEK_SET,&newpos);
- if (hres) {
- ERR("Failed Seek %x\n",hres);
- IStream_Release(pStm);
- return hres;
- }
-
- hres = CoUnmarshalInterface(pStm,riid,(LPVOID*)pUnk);
- if (hres) {
- ERR("Unmarshalling interface %s failed with %x\n",debugstr_guid(riid),hres);
- IStream_Release(pStm);
- return hres;
- }
-
- IStream_Release(pStm);
- return xbuf_skip(buf,xsize);
-}
-
-static HRESULT
-_marshal_interface(marshal_state *buf, REFIID riid, LPUNKNOWN pUnk) {
- LPBYTE tempbuf = NULL;
- IStream *pStm = NULL;
- STATSTG ststg;
- ULARGE_INTEGER newpos;
- LARGE_INTEGER seekto;
- ULONG res;
- DWORD xsize;
- HRESULT hres;
-
- if (!pUnk) {
- /* this is valid, if for instance we serialize
- * a VT_DISPATCH with NULL ptr which apparently
- * can happen. S_OK to make sure we continue
- * serializing.
- */
- WARN("pUnk is NULL\n");
- xsize = 0;
- return xbuf_add(buf,(LPBYTE)&xsize,sizeof(xsize));
- }
-
- TRACE("...%s...\n",debugstr_guid(riid));
-
- hres = CreateStreamOnHGlobal(0,TRUE,&pStm);
- if (hres) {
- ERR("Stream create failed %x\n",hres);
- goto fail;
- }
-
- hres = CoMarshalInterface(pStm,riid,pUnk,0,NULL,0);
- if (hres) {
- ERR("Marshalling interface %s failed with %x\n", debugstr_guid(riid), hres);
- goto fail;
- }
-
- hres = IStream_Stat(pStm,&ststg,STATFLAG_NONAME);
- if (hres) {
- ERR("Stream stat failed\n");
- goto fail;
- }
-
- tempbuf = HeapAlloc(GetProcessHeap(), 0, ststg.cbSize.u.LowPart);
- memset(&seekto,0,sizeof(seekto));
- hres = IStream_Seek(pStm,seekto,SEEK_SET,&newpos);
- if (hres) {
- ERR("Failed Seek %x\n",hres);
- goto fail;
- }
-
- hres = IStream_Read(pStm,tempbuf,ststg.cbSize.u.LowPart,&res);
- if (hres) {
- ERR("Failed Read %x\n",hres);
- goto fail;
- }
-
- xsize = ststg.cbSize.u.LowPart;
- xbuf_add(buf,(LPBYTE)&xsize,sizeof(xsize));
- hres = xbuf_add(buf,tempbuf,ststg.cbSize.u.LowPart);
-
- HeapFree(GetProcessHeap(),0,tempbuf);
- IStream_Release(pStm);
-
- return hres;
-
-fail:
- xsize = 0;
- xbuf_add(buf,(LPBYTE)&xsize,sizeof(xsize));
- if (pStm) IStream_Release(pStm);
- HeapFree(GetProcessHeap(), 0, tempbuf);
- return hres;
-}
-
-/********************* OLE Proxy/Stub Factory ********************************/
-static HRESULT WINAPI
-PSFacBuf_QueryInterface(LPPSFACTORYBUFFER iface, REFIID iid, LPVOID *ppv) {
- if (IsEqualIID(iid,&IID_IPSFactoryBuffer)||IsEqualIID(iid,&IID_IUnknown)) {
- *ppv = iface;
- /* No ref counting, static class */
- return S_OK;
- }
- FIXME("(%s) unknown IID?\n",debugstr_guid(iid));
- return E_NOINTERFACE;
-}
-
-static ULONG WINAPI PSFacBuf_AddRef(LPPSFACTORYBUFFER iface) { return 2; }
-static ULONG WINAPI PSFacBuf_Release(LPPSFACTORYBUFFER iface) { return 1; }
-
-struct ifacepsredirect_data
-{
- ULONG size;
- DWORD mask;
- GUID iid;
- ULONG nummethods;
- GUID tlbid;
- GUID base;
- ULONG name_len;
- ULONG name_offset;
-};
-
-struct tlibredirect_data
-{
- ULONG size;
- DWORD res;
- ULONG name_len;
- ULONG name_offset;
- LANGID langid;
- WORD flags;
- ULONG help_len;
- ULONG help_offset;
- WORD major_version;
- WORD minor_version;
-};
-
-static BOOL actctx_get_typelib_module(REFIID riid, WCHAR *module, DWORD len)
-{
- struct ifacepsredirect_data *iface;
- struct tlibredirect_data *tlib;
- ACTCTX_SECTION_KEYED_DATA data;
- WCHAR *ptrW;
-
- data.cbSize = sizeof(data);
- if (!FindActCtxSectionGuid(0, NULL,
ACTIVATION_CONTEXT_SECTION_COM_INTERFACE_REDIRECTION,
- riid, &data))
- return FALSE;
-
- iface = (struct ifacepsredirect_data*)data.lpData;
- if (!FindActCtxSectionGuid(0, NULL,
ACTIVATION_CONTEXT_SECTION_COM_TYPE_LIBRARY_REDIRECTION,
- &iface->tlbid, &data))
- return FALSE;
-
- tlib = (struct tlibredirect_data*)data.lpData;
- ptrW = (WCHAR*)((BYTE*)data.lpSectionBase + tlib->name_offset);
-
- if (tlib->name_len/sizeof(WCHAR) >= len) {
- ERR("need larger module buffer, %u\n", tlib->name_len);
- return FALSE;
- }
-
- memcpy(module, ptrW, tlib->name_len);
- module[tlib->name_len/sizeof(WCHAR)] = 0;
- return TRUE;
-}
-
-static HRESULT reg_get_typelib_module(REFIID riid, WCHAR *module, DWORD len)
-{
- HKEY ikey;
- REGSAM opposite = (sizeof(void*) == 8) ? KEY_WOW64_32KEY : KEY_WOW64_64KEY;
- BOOL is_wow64;
- char tlguid[200],typelibkey[300],interfacekey[300],ver[100];
- char tlfn[260];
- DWORD tlguidlen, verlen, type;
- LONG tlfnlen, err;
-
- sprintf( interfacekey,
"Interface\\{%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}\\Typelib",
- riid->Data1, riid->Data2, riid->Data3,
- riid->Data4[0], riid->Data4[1], riid->Data4[2], riid->Data4[3],
- riid->Data4[4], riid->Data4[5], riid->Data4[6], riid->Data4[7]
- );
-
- err = RegOpenKeyExA(HKEY_CLASSES_ROOT,interfacekey,0,KEY_READ,&ikey);
- if (err && (opposite == KEY_WOW64_32KEY ||
(IsWow64Process(GetCurrentProcess(), &is_wow64)
- && is_wow64))) {
- err =
RegOpenKeyExA(HKEY_CLASSES_ROOT,interfacekey,0,KEY_READ|opposite,&ikey);
- }
- if (err) {
- ERR("No %s key found.\n",interfacekey);
- return E_FAIL;
- }
- tlguidlen = sizeof(tlguid);
- if (RegQueryValueExA(ikey,NULL,NULL,&type,(LPBYTE)tlguid,&tlguidlen)) {
- ERR("Getting typelib guid failed.\n");
- RegCloseKey(ikey);
- return E_FAIL;
- }
- verlen = sizeof(ver);
- if
(RegQueryValueExA(ikey,"Version",NULL,&type,(LPBYTE)ver,&verlen)) {
- ERR("Could not get version value?\n");
- RegCloseKey(ikey);
- return E_FAIL;
- }
- RegCloseKey(ikey);
- sprintf(typelibkey,"Typelib\\%s\\%s\\0\\win%u",tlguid,ver,(sizeof(void*) ==
8) ? 64 : 32);
- tlfnlen = sizeof(tlfn);
- if (RegQueryValueA(HKEY_CLASSES_ROOT,typelibkey,tlfn,&tlfnlen)) {
-#ifdef _WIN64
- sprintf(typelibkey,"Typelib\\%s\\%s\\0\\win32",tlguid,ver);
- tlfnlen = sizeof(tlfn);
- if (RegQueryValueA(HKEY_CLASSES_ROOT,typelibkey,tlfn,&tlfnlen)) {
-#endif
- ERR("Could not get typelib fn?\n");
- return E_FAIL;
-#ifdef _WIN64
- }
-#endif
- }
- MultiByteToWideChar(CP_ACP, 0, tlfn, -1, module, len);
- return S_OK;
-}
-
-static HRESULT
-_get_typeinfo_for_iid(REFIID riid, ITypeInfo **typeinfo)
-{
- OLECHAR moduleW[260];
- ITypeLib *typelib;
- HRESULT hres;
-
- *typeinfo = NULL;
-
- moduleW[0] = 0;
- if (!actctx_get_typelib_module(riid, moduleW, sizeof(moduleW)/sizeof(moduleW[0]))) {
- hres = reg_get_typelib_module(riid, moduleW,
sizeof(moduleW)/sizeof(moduleW[0]));
- if (FAILED(hres))
- return hres;
- }
-
- hres = LoadTypeLib(moduleW, &typelib);
- if (hres != S_OK) {
- ERR("Failed to load typelib for %s, but it should be
there.\n",debugstr_guid(riid));
- return hres;
- }
-
- hres = ITypeLib_GetTypeInfoOfGuid(typelib, riid, typeinfo);
- ITypeLib_Release(typelib);
- if (hres != S_OK)
- ERR("typelib does not contain info for %s\n", debugstr_guid(riid));
-
- return hres;
-}
-
-/*
- * Determine the number of functions including all inherited functions
- * and well as the size of the vtbl.
- * Note for non-dual dispinterfaces we simply return the size of IDispatch.
- */
-static HRESULT num_of_funcs(ITypeInfo *tinfo, unsigned int *num,
- unsigned int *vtbl_size)
-{
- HRESULT hr;
- TYPEATTR *attr;
- ITypeInfo *tinfo2;
- UINT inherited_funcs = 0, i;
-
- *num = 0;
- if(vtbl_size) *vtbl_size = 0;
-
- hr = ITypeInfo_GetTypeAttr(tinfo, &attr);
- if (hr)
- {
- ERR("GetTypeAttr failed with %x\n", hr);
- return hr;
- }
-
- if(attr->typekind == TKIND_DISPATCH)
- {
- if(attr->wTypeFlags & TYPEFLAG_FDUAL)
- {
- HREFTYPE href;
-
- ITypeInfo_ReleaseTypeAttr(tinfo, attr);
- hr = ITypeInfo_GetRefTypeOfImplType(tinfo, -1, &href);
- if(FAILED(hr))
- {
- ERR("Unable to get interface href from dual dispinterface\n");
- return hr;
- }
- hr = ITypeInfo_GetRefTypeInfo(tinfo, href, &tinfo2);
- if(FAILED(hr))
- {
- ERR("Unable to get interface from dual dispinterface\n");
- return hr;
- }
- hr = num_of_funcs(tinfo2, num, vtbl_size);
- ITypeInfo_Release(tinfo2);
- return hr;
- }
- else /* non-dual dispinterface */
- {
- /* These will be the size of IDispatchVtbl */
- *num = attr->cbSizeVft / sizeof(void *);
- if(vtbl_size) *vtbl_size = attr->cbSizeVft;
- ITypeInfo_ReleaseTypeAttr(tinfo, attr);
- return hr;
- }
- }
-
- for (i = 0; i < attr->cImplTypes; i++)
- {
- HREFTYPE href;
- ITypeInfo *pSubTypeInfo;
- UINT sub_funcs;
-
- hr = ITypeInfo_GetRefTypeOfImplType(tinfo, i, &href);
- if (FAILED(hr)) goto end;
- hr = ITypeInfo_GetRefTypeInfo(tinfo, href, &pSubTypeInfo);
- if (FAILED(hr)) goto end;
-
- hr = num_of_funcs(pSubTypeInfo, &sub_funcs, NULL);
- ITypeInfo_Release(pSubTypeInfo);
-
- if(FAILED(hr)) goto end;
- inherited_funcs += sub_funcs;
- }
-
- *num = inherited_funcs + attr->cFuncs;
- if(vtbl_size) *vtbl_size = attr->cbSizeVft;
-
- end:
- ITypeInfo_ReleaseTypeAttr(tinfo, attr);
- return hr;
-}
-
-#ifdef __i386__
-
-#include "pshpack1.h"
-typedef struct _TMAsmProxy {
- DWORD lealeax;
- BYTE pushleax;
- BYTE pushlval;
- DWORD nr;
- BYTE lcall;
- DWORD xcall;
- BYTE lret;
- WORD bytestopop;
- WORD nop;
-} 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"
-
-#else /* __i386__ */
-#ifdef _MSC_VER
-#pragma message("You need to implement stubless proxies for your
architecture")
-#else
-# warning You need to implement stubless proxies for your architecture
-#endif
-typedef struct _TMAsmProxy {
- char a;
-} TMAsmProxy;
-#endif
-
-typedef struct _TMProxyImpl {
- LPVOID *lpvtbl;
- IRpcProxyBuffer IRpcProxyBuffer_iface;
- LONG ref;
-
- TMAsmProxy *asmstubs;
- ITypeInfo* tinfo;
- IRpcChannelBuffer* chanbuf;
- IID iid;
- CRITICAL_SECTION crit;
- IUnknown *outerunknown;
- IDispatch *dispatch;
- IRpcProxyBuffer *dispatch_proxy;
-} TMProxyImpl;
-
-static inline TMProxyImpl *impl_from_IRpcProxyBuffer( IRpcProxyBuffer *iface )
-{
- return CONTAINING_RECORD(iface, TMProxyImpl, IRpcProxyBuffer_iface);
-}
-
-static HRESULT WINAPI
-TMProxyImpl_QueryInterface(LPRPCPROXYBUFFER iface, REFIID riid, LPVOID *ppv)
-{
- TRACE("()\n");
- if (IsEqualIID(riid,&IID_IUnknown)||IsEqualIID(riid,&IID_IRpcProxyBuffer)) {
- *ppv = iface;
- IRpcProxyBuffer_AddRef(iface);
- return S_OK;
- }
- FIXME("no interface for %s\n",debugstr_guid(riid));
- return E_NOINTERFACE;
-}
-
-static ULONG WINAPI
-TMProxyImpl_AddRef(LPRPCPROXYBUFFER iface)
-{
- TMProxyImpl *This = impl_from_IRpcProxyBuffer( iface );
- ULONG refCount = InterlockedIncrement(&This->ref);
-
- TRACE("(%p)->(ref before=%u)\n",This, refCount - 1);
-
- return refCount;
-}
-
-static ULONG WINAPI
-TMProxyImpl_Release(LPRPCPROXYBUFFER iface)
-{
- TMProxyImpl *This = impl_from_IRpcProxyBuffer( iface );
- ULONG refCount = InterlockedDecrement(&This->ref);
-
- TRACE("(%p)->(ref before=%u)\n",This, refCount + 1);
-
- if (!refCount)
- {
- if (This->dispatch_proxy) IRpcProxyBuffer_Release(This->dispatch_proxy);
- This->crit.DebugInfo->Spare[0] = 0;
- DeleteCriticalSection(&This->crit);
- if (This->chanbuf) IRpcChannelBuffer_Release(This->chanbuf);
- VirtualFree(This->asmstubs, 0, MEM_RELEASE);
- HeapFree(GetProcessHeap(), 0, This->lpvtbl);
- ITypeInfo_Release(This->tinfo);
- CoTaskMemFree(This);
- }
- return refCount;
-}
-
-static HRESULT WINAPI
-TMProxyImpl_Connect(
- LPRPCPROXYBUFFER iface,IRpcChannelBuffer* pRpcChannelBuffer)
-{
- TMProxyImpl *This = impl_from_IRpcProxyBuffer( iface );
-
- TRACE("(%p)\n", pRpcChannelBuffer);
-
- EnterCriticalSection(&This->crit);
-
- IRpcChannelBuffer_AddRef(pRpcChannelBuffer);
- This->chanbuf = pRpcChannelBuffer;
-
- LeaveCriticalSection(&This->crit);
-
- if (This->dispatch_proxy)
- {
- IRpcChannelBuffer *pDelegateChannel;
- HRESULT hr = TMarshalDispatchChannel_Create(pRpcChannelBuffer, &This->iid,
&pDelegateChannel);
- if (FAILED(hr))
- return hr;
- hr = IRpcProxyBuffer_Connect(This->dispatch_proxy, pDelegateChannel);
- IRpcChannelBuffer_Release(pDelegateChannel);
- return hr;
- }
-
- return S_OK;
-}
-
-static void WINAPI
-TMProxyImpl_Disconnect(LPRPCPROXYBUFFER iface)
-{
- TMProxyImpl *This = impl_from_IRpcProxyBuffer( iface );
-
- TRACE("()\n");
-
- EnterCriticalSection(&This->crit);
-
- IRpcChannelBuffer_Release(This->chanbuf);
- This->chanbuf = NULL;
-
- LeaveCriticalSection(&This->crit);
-
- if (This->dispatch_proxy)
- IRpcProxyBuffer_Disconnect(This->dispatch_proxy);
-}
-
-
-static const IRpcProxyBufferVtbl tmproxyvtable = {
- TMProxyImpl_QueryInterface,
- TMProxyImpl_AddRef,
- TMProxyImpl_Release,
- TMProxyImpl_Connect,
- TMProxyImpl_Disconnect
-};
-
-/* how much space do we use on stack in DWORD_PTR steps. */
-static int
-_argsize(TYPEDESC *tdesc, ITypeInfo *tinfo) {
- DWORD ret;
- switch (tdesc->vt) {
- case VT_I8:
- case VT_UI8:
- ret = 8;
- break;
- case VT_R8:
- ret = sizeof(double);
- break;
- case VT_CY:
- ret = sizeof(CY);
- break;
- case VT_DATE:
- ret = sizeof(DATE);
- break;
- case VT_DECIMAL:
- ret = sizeof(DECIMAL);
- break;
- case VT_VARIANT:
- ret = sizeof(VARIANT);
- break;
- case VT_USERDEFINED:
- {
- ITypeInfo *tinfo2;
- TYPEATTR *tattr;
- HRESULT hres;
-
- hres = ITypeInfo_GetRefTypeInfo(tinfo,tdesc->u.hreftype,&tinfo2);
- if (FAILED(hres))
- return 0; /* should fail critically in serialize_param */
- ITypeInfo_GetTypeAttr(tinfo2,&tattr);
- ret = tattr->cbSizeInstance;
- ITypeInfo_ReleaseTypeAttr(tinfo2, tattr);
- ITypeInfo_Release(tinfo2);
- break;
- }
- default:
- 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) */
-static int
-_xsize(const TYPEDESC *td, ITypeInfo *tinfo) {
- switch (td->vt) {
- case VT_DATE:
- return sizeof(DATE);
- case VT_CY:
- return sizeof(CY);
- case VT_VARIANT:
- return sizeof(VARIANT);
- case VT_CARRAY: {
- int i, arrsize = 1;
- const ARRAYDESC *adesc = td->u.lpadesc;
-
- for (i=0;i<adesc->cDims;i++)
- arrsize *= adesc->rgbounds[i].cElements;
- return arrsize*_xsize(&adesc->tdescElem, tinfo);
- }
- case VT_UI8:
- case VT_I8:
- case VT_R8:
- return 8;
- case VT_UI2:
- case VT_I2:
- case VT_BOOL:
- return 2;
- case VT_UI1:
- case VT_I1:
- return 1;
- case VT_USERDEFINED:
- {
- ITypeInfo *tinfo2;
- TYPEATTR *tattr;
- HRESULT hres;
- DWORD ret;
-
- hres = ITypeInfo_GetRefTypeInfo(tinfo,td->u.hreftype,&tinfo2);
- if (FAILED(hres))
- return 0;
- ITypeInfo_GetTypeAttr(tinfo2,&tattr);
- ret = tattr->cbSizeInstance;
- ITypeInfo_ReleaseTypeAttr(tinfo2, tattr);
- ITypeInfo_Release(tinfo2);
- return ret;
- }
- default:
- return sizeof(DWORD_PTR);
- }
-}
-
-/* Whether we pass this type by reference or by value */
-static BOOL
-_passbyref(const TYPEDESC *td, ITypeInfo *tinfo) {
- return (td->vt == VT_USERDEFINED ||
- td->vt == VT_VARIANT ||
- td->vt == VT_PTR);
-}
-
-static HRESULT
-serialize_param(
- ITypeInfo *tinfo,
- BOOL writeit,
- BOOL debugout,
- BOOL dealloc,
- TYPEDESC *tdesc,
- DWORD_PTR *arg,
- marshal_state *buf)
-{
- HRESULT hres = S_OK;
- VARTYPE vartype;
-
- TRACE("(tdesc.vt %s)\n",debugstr_vt(tdesc->vt));
-
- vartype = tdesc->vt;
- if ((vartype & 0xf000) == VT_ARRAY)
- vartype = VT_SAFEARRAY;
-
- switch (vartype) {
- case VT_DATE:
- case VT_I8:
- case VT_UI8:
- case VT_R8:
- case VT_CY:
- hres = S_OK;
- if (debugout) TRACE_(olerelay)("%s\n", wine_dbgstr_longlong(*(ULONGLONG
*)arg));
- if (writeit)
- hres = xbuf_add(buf,(LPBYTE)arg,8);
- return hres;
- case VT_ERROR:
- case VT_INT:
- case VT_UINT:
- case VT_I4:
- case VT_R4:
- case VT_UI4:
- hres = S_OK;
- if (debugout) TRACE_(olerelay)("%x\n", *(DWORD *)arg);
- if (writeit)
- hres = xbuf_add(buf,(LPBYTE)arg,sizeof(DWORD));
- return hres;
- case VT_I2:
- case VT_UI2:
- case VT_BOOL:
- hres = S_OK;
- if (debugout) TRACE_(olerelay)("%04x\n", *(WORD *)arg);
- if (writeit)
- hres = xbuf_add(buf,(LPBYTE)arg,sizeof(DWORD));
- return hres;
- case VT_I1:
- case VT_UI1:
- hres = S_OK;
- if (debugout) TRACE_(olerelay)("%02x\n", *(BYTE *)arg);
- if (writeit)
- hres = xbuf_add(buf,(LPBYTE)arg,sizeof(DWORD));
- return hres;
- case VT_VARIANT: {
- if (debugout) TRACE_(olerelay)("%s", debugstr_variant((VARIANT
*)arg));
- if (writeit)
- {
- ULONG flags = MAKELONG(MSHCTX_DIFFERENTMACHINE,
NDR_LOCAL_DATA_REPRESENTATION);
- ULONG size = VARIANT_UserSize(&flags, buf->curoff, (VARIANT *)arg);
- xbuf_resize(buf, size);
- VARIANT_UserMarshal(&flags, buf->base + buf->curoff, (VARIANT
*)arg);
- buf->curoff = size;
- }
- if (dealloc)
- {
- ULONG flags = MAKELONG(MSHCTX_DIFFERENTMACHINE,
NDR_LOCAL_DATA_REPRESENTATION);
- VARIANT_UserFree(&flags, (VARIANT *)arg);
- }
- return S_OK;
- }
- case VT_BSTR: {
- if (writeit && debugout) {
- if (*arg)
- TRACE_(olerelay)("%s",relaystr((WCHAR*)*arg));
- else
- TRACE_(olerelay)("<bstr NULL>");
- }
- if (writeit)
- {
- ULONG flags = MAKELONG(MSHCTX_DIFFERENTMACHINE,
NDR_LOCAL_DATA_REPRESENTATION);
- ULONG size = BSTR_UserSize(&flags, buf->curoff, (BSTR *)arg);
- xbuf_resize(buf, size);
- BSTR_UserMarshal(&flags, buf->base + buf->curoff, (BSTR *)arg);
- buf->curoff = size;
- }
- if (dealloc)
- {
- ULONG flags = MAKELONG(MSHCTX_DIFFERENTMACHINE,
NDR_LOCAL_DATA_REPRESENTATION);
- BSTR_UserFree(&flags, (BSTR *)arg);
- }
- return S_OK;
- }
- case VT_PTR: {
- DWORD cookie;
- BOOL derefhere = TRUE;
-
- if (tdesc->u.lptdesc->vt == VT_USERDEFINED) {
- ITypeInfo *tinfo2;
- TYPEATTR *tattr;
-
- hres =
ITypeInfo_GetRefTypeInfo(tinfo,tdesc->u.lptdesc->u.hreftype,&tinfo2);
- if (hres) {
- ERR("Could not get typeinfo of hreftype %x for
VT_USERDEFINED.\n",tdesc->u.lptdesc->u.hreftype);
- return hres;
- }
- ITypeInfo_GetTypeAttr(tinfo2,&tattr);
- switch (tattr->typekind) {
- case TKIND_ALIAS:
- if (tattr->tdescAlias.vt == VT_USERDEFINED)
- {
- DWORD href = tattr->tdescAlias.u.hreftype;
- ITypeInfo_ReleaseTypeAttr(tinfo, tattr);
- ITypeInfo_Release(tinfo2);
- hres = ITypeInfo_GetRefTypeInfo(tinfo,href,&tinfo2);
- if (hres) {
- ERR("Could not get typeinfo of hreftype %x for
VT_USERDEFINED.\n",tdesc->u.lptdesc->u.hreftype);
- return hres;
- }
- ITypeInfo_GetTypeAttr(tinfo2,&tattr);
- derefhere = (tattr->typekind != TKIND_DISPATCH &&
- tattr->typekind != TKIND_INTERFACE &&
- tattr->typekind != TKIND_COCLASS);
- }
- break;
- case TKIND_ENUM: /* confirmed */
- case TKIND_RECORD: /* FIXME: mostly untested */
- break;
- case TKIND_DISPATCH: /* 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;
- break;
- default:
- FIXME("unhandled switch cases tattr->typekind %d\n", tattr->typekind);
- derefhere=FALSE;
- break;
- }
- ITypeInfo_ReleaseTypeAttr(tinfo, tattr);
- ITypeInfo_Release(tinfo2);
- }
-
- if (debugout) TRACE_(olerelay)("*");
- /* Write always, so the other side knows when it gets a NULL pointer.
- */
- cookie = *arg ? 0x42424242 : 0;
- hres = xbuf_add(buf,(LPBYTE)&cookie,sizeof(cookie));
- if (hres)
- return hres;
- if (!*arg) {
- if (debugout) TRACE_(olerelay)("NULL");
- return S_OK;
- }
- hres = serialize_param(tinfo,writeit,debugout,dealloc,tdesc->u.lptdesc,(DWORD_PTR
*)*arg,buf);
- if (derefhere && dealloc) HeapFree(GetProcessHeap(),0,(LPVOID)*arg);
- return hres;
- }
- case VT_UNKNOWN:
- if (debugout) TRACE_(olerelay)("unk(0x%lx)", *arg);
- if (writeit)
- hres = _marshal_interface(buf,&IID_IUnknown,(LPUNKNOWN)*arg);
- if (dealloc && *(IUnknown **)arg)
- IUnknown_Release((LPUNKNOWN)*arg);
- return hres;
- case VT_DISPATCH:
- if (debugout) TRACE_(olerelay)("idisp(0x%lx)", *arg);
- if (writeit)
- hres = _marshal_interface(buf,&IID_IDispatch,(LPUNKNOWN)*arg);
- if (dealloc && *(IUnknown **)arg)
- IUnknown_Release((LPUNKNOWN)*arg);
- return hres;
- case VT_VOID:
- if (debugout) TRACE_(olerelay)("<void>");
- return S_OK;
- case VT_USERDEFINED: {
- ITypeInfo *tinfo2;
- TYPEATTR *tattr;
-
- hres = ITypeInfo_GetRefTypeInfo(tinfo,tdesc->u.hreftype,&tinfo2);
- if (hres) {
- ERR("Could not get typeinfo of hreftype %x for
VT_USERDEFINED.\n",tdesc->u.hreftype);
- return hres;
- }
- ITypeInfo_GetTypeAttr(tinfo2,&tattr);
- switch (tattr->typekind) {
- case TKIND_DISPATCH:
- case TKIND_INTERFACE:
- if (writeit)
- hres=_marshal_interface(buf,&(tattr->guid),(LPUNKNOWN)arg);
- if (dealloc)
- IUnknown_Release((LPUNKNOWN)arg);
- 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: {
- int i;
- if (debugout) TRACE_(olerelay)("{");
- for (i=0;i<tattr->cVars;i++) {
- VARDESC *vdesc;
- ELEMDESC *elem2;
- TYPEDESC *tdesc2;
-
- hres = ITypeInfo_GetVarDesc(tinfo2, i, &vdesc);
- if (hres) {
- ERR("Could not get vardesc of %d\n",i);
- return hres;
- }
- elem2 = &vdesc->elemdescVar;
- tdesc2 = &elem2->tdesc;
- hres = serialize_param(
- tinfo2,
- writeit,
- debugout,
- dealloc,
- tdesc2,
- (DWORD_PTR *)(((LPBYTE)arg)+vdesc->u.oInst),
- buf
- );
- ITypeInfo_ReleaseVarDesc(tinfo2, vdesc);
- if (hres!=S_OK)
- return hres;
- if (debugout && (i<(tattr->cVars-1)))
- TRACE_(olerelay)(",");
- }
- if (debugout) TRACE_(olerelay)("}");
- break;
- }
- case TKIND_ALIAS:
- hres =
serialize_param(tinfo2,writeit,debugout,dealloc,&tattr->tdescAlias,arg,buf);
- break;
- case TKIND_ENUM:
- hres = S_OK;
- if (debugout) TRACE_(olerelay)("%x", *(DWORD *)arg);
- if (writeit)
- hres = xbuf_add(buf,(LPBYTE)arg,sizeof(DWORD));
- break;
- default:
- FIXME("Unhandled typekind %d\n",tattr->typekind);
- hres = E_FAIL;
- break;
- }
- ITypeInfo_ReleaseTypeAttr(tinfo2, tattr);
- ITypeInfo_Release(tinfo2);
- return hres;
- }
- case VT_CARRAY: {
- ARRAYDESC *adesc = tdesc->u.lpadesc;
- int i, arrsize = 1;
-
- if (debugout) TRACE_(olerelay)("carr");
- for (i=0;i<adesc->cDims;i++) {
- if (debugout) TRACE_(olerelay)("[%d]",adesc->rgbounds[i].cElements);
- arrsize *= adesc->rgbounds[i].cElements;
- }
- if (debugout) TRACE_(olerelay)("(vt
%s)",debugstr_vt(adesc->tdescElem.vt));
- if (debugout) TRACE_(olerelay)("[");
- for (i=0;i<arrsize;i++) {
- LPBYTE base = _passbyref(&adesc->tdescElem, tinfo) ? (LPBYTE) *arg :
(LPBYTE) arg;
- hres = serialize_param(tinfo, writeit, debugout, dealloc, &adesc->tdescElem,
(DWORD_PTR *)((LPBYTE)base+i*_xsize(&adesc->tdescElem, tinfo)), buf);
- if (hres)
- return hres;
- if (debugout && (i<arrsize-1)) TRACE_(olerelay)(",");
- }
- if (debugout) TRACE_(olerelay)("]");
- if (dealloc)
- HeapFree(GetProcessHeap(), 0, *(void **)arg);
- return S_OK;
- }
- case VT_SAFEARRAY: {
- if (writeit)
- {
- ULONG flags = MAKELONG(MSHCTX_DIFFERENTMACHINE,
NDR_LOCAL_DATA_REPRESENTATION);
- ULONG size = LPSAFEARRAY_UserSize(&flags, buf->curoff, (LPSAFEARRAY
*)arg);
- xbuf_resize(buf, size);
- LPSAFEARRAY_UserMarshal(&flags, buf->base + buf->curoff,
(LPSAFEARRAY *)arg);
- buf->curoff = size;
- }
- if (dealloc)
- {
- ULONG flags = MAKELONG(MSHCTX_DIFFERENTMACHINE,
NDR_LOCAL_DATA_REPRESENTATION);
- LPSAFEARRAY_UserFree(&flags, (LPSAFEARRAY *)arg);
- }
- return S_OK;
- }
- default:
- ERR("Unhandled marshal type %d.\n",tdesc->vt);
- return S_OK;
- }
-}
-
-static HRESULT
-deserialize_param(
- ITypeInfo *tinfo,
- BOOL readit,
- BOOL debugout,
- BOOL alloc,
- TYPEDESC *tdesc,
- DWORD_PTR *arg,
- marshal_state *buf)
-{
- HRESULT hres = S_OK;
- VARTYPE vartype;
-
- TRACE("vt %s at %p\n",debugstr_vt(tdesc->vt),arg);
-
- vartype = tdesc->vt;
- if ((vartype & 0xf000) == VT_ARRAY)
- vartype = VT_SAFEARRAY;
-
- while (1) {
- switch (vartype) {
- case VT_VARIANT: {
- if (readit)
- {
- ULONG flags = MAKELONG(MSHCTX_DIFFERENTMACHINE, NDR_LOCAL_DATA_REPRESENTATION);
- unsigned char *buffer;
- buffer = VARIANT_UserUnmarshal(&flags, buf->base + buf->curoff, (VARIANT
*)arg);
- buf->curoff = buffer - buf->base;
- }
- return S_OK;
- }
- case VT_DATE:
- case VT_I8:
- case VT_UI8:
- case VT_R8:
- case VT_CY:
- if (readit) {
- hres = xbuf_get(buf,(LPBYTE)arg,8);
- if (hres) ERR("Failed to read integer 8 byte\n");
- }
- if (debugout) TRACE_(olerelay)("%s", wine_dbgstr_longlong(*(ULONGLONG
*)arg));
- return hres;
- case VT_ERROR:
- case VT_I4:
- case VT_INT:
- case VT_UINT:
- case VT_R4:
- case VT_UI4:
- if (readit) {
- hres = xbuf_get(buf,(LPBYTE)arg,sizeof(DWORD));
- if (hres) ERR("Failed to read integer 4 byte\n");
- }
- if (debugout) TRACE_(olerelay)("%x", *(DWORD *)arg);
- return hres;
- case VT_I2:
- case VT_UI2:
- case VT_BOOL:
- if (readit) {
- DWORD x;
- hres = xbuf_get(buf,(LPBYTE)&x,sizeof(DWORD));
- if (hres) ERR("Failed to read integer 4 byte\n");
- else memcpy(arg,&x,2);
- }
- if (debugout) TRACE_(olerelay)("%04x", *(WORD *)arg);
- return hres;
- case VT_I1:
- case VT_UI1:
- if (readit) {
- DWORD x;
- hres = xbuf_get(buf,(LPBYTE)&x,sizeof(DWORD));
- if (hres) ERR("Failed to read integer 4 byte\n");
- else memcpy(arg,&x,1);
- }
- if (debugout) TRACE_(olerelay)("%02x", *(BYTE *)arg);
- return hres;
- case VT_BSTR: {
- if (readit)
- {
- ULONG flags = MAKELONG(MSHCTX_DIFFERENTMACHINE, NDR_LOCAL_DATA_REPRESENTATION);
- unsigned char *buffer;
- buffer = BSTR_UserUnmarshal(&flags, buf->base + buf->curoff, (BSTR *)arg);
- buf->curoff = buffer - buf->base;
- if (debugout) TRACE_(olerelay)("%s",debugstr_w(*(BSTR *)arg));
- }
- return S_OK;
- }
- case VT_PTR: {
- DWORD cookie;
- BOOL derefhere = TRUE;
-
- if (tdesc->u.lptdesc->vt == VT_USERDEFINED) {
- ITypeInfo *tinfo2;
- TYPEATTR *tattr;
-
- hres = ITypeInfo_GetRefTypeInfo(tinfo,tdesc->u.lptdesc->u.hreftype,&tinfo2);
- if (hres) {
- ERR("Could not get typeinfo of hreftype %x for
VT_USERDEFINED.\n",tdesc->u.lptdesc->u.hreftype);
- return hres;
- }
- ITypeInfo_GetTypeAttr(tinfo2,&tattr);
- switch (tattr->typekind) {
- case TKIND_ALIAS:
- if (tattr->tdescAlias.vt == VT_USERDEFINED)
- {
- DWORD href = tattr->tdescAlias.u.hreftype;
- ITypeInfo_ReleaseTypeAttr(tinfo, tattr);
- ITypeInfo_Release(tinfo2);
- hres = ITypeInfo_GetRefTypeInfo(tinfo,href,&tinfo2);
- if (hres) {
- ERR("Could not get typeinfo of hreftype %x for
VT_USERDEFINED.\n",tdesc->u.lptdesc->u.hreftype);
- return hres;
- }
- ITypeInfo_GetTypeAttr(tinfo2,&tattr);
- derefhere = (tattr->typekind != TKIND_DISPATCH &&
- tattr->typekind != TKIND_INTERFACE &&
- tattr->typekind != TKIND_COCLASS);
- }
- break;
- case TKIND_ENUM: /* confirmed */
- case TKIND_RECORD: /* FIXME: mostly untested */
- break;
- case TKIND_DISPATCH: /* 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;
- break;
- default:
- FIXME("unhandled switch cases tattr->typekind %d\n",
tattr->typekind);
- derefhere=FALSE;
- break;
- }
- ITypeInfo_ReleaseTypeAttr(tinfo2, tattr);
- ITypeInfo_Release(tinfo2);
- }
- /* read it in all cases, we need to know if we have
- * NULL pointer or not.
- */
- hres = xbuf_get(buf,(LPBYTE)&cookie,sizeof(cookie));
- if (hres) {
- ERR("Failed to load pointer cookie.\n");
- return hres;
- }
- if (cookie != 0x42424242) {
- /* we read a NULL ptr from the remote side */
- if (debugout) TRACE_(olerelay)("NULL");
- *arg = 0;
- return S_OK;
- }
- if (debugout) TRACE_(olerelay)("*");
- if (alloc) {
- /* Allocate space for the referenced struct */
- if (derefhere)
-
*arg=(DWORD_PTR)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,_xsize(tdesc->u.lptdesc,
tinfo));
- }
- if (derefhere)
- return deserialize_param(tinfo, readit, debugout, alloc, tdesc->u.lptdesc,
(DWORD_PTR *)*arg, buf);
- else
- return deserialize_param(tinfo, readit, debugout, alloc, tdesc->u.lptdesc, arg,
buf);
- }
- case VT_UNKNOWN:
- /* FIXME: UNKNOWN is unknown ..., but allocate 4 byte for it */
- if (alloc)
- *arg=(DWORD_PTR)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(DWORD_PTR));
- hres = S_OK;
- if (readit)
- hres = _unmarshal_interface(buf,&IID_IUnknown,(LPUNKNOWN*)arg);
- if (debugout)
- TRACE_(olerelay)("unk(%p)",arg);
- return hres;
- case VT_DISPATCH:
- hres = S_OK;
- if (readit)
- hres = _unmarshal_interface(buf,&IID_IDispatch,(LPUNKNOWN*)arg);
- if (debugout)
- TRACE_(olerelay)("idisp(%p)",arg);
- return hres;
- case VT_VOID:
- if (debugout) TRACE_(olerelay)("<void>");
- return S_OK;
- case VT_USERDEFINED: {
- ITypeInfo *tinfo2;
- TYPEATTR *tattr;
-
- hres = ITypeInfo_GetRefTypeInfo(tinfo,tdesc->u.hreftype,&tinfo2);
- if (hres) {
- ERR("Could not get typeinfo of hreftype %x for
VT_USERDEFINED.\n",tdesc->u.hreftype);
- return hres;
- }
- hres = ITypeInfo_GetTypeAttr(tinfo2,&tattr);
- if (hres) {
- ERR("Could not get typeattr in VT_USERDEFINED.\n");
- } else {
- switch (tattr->typekind) {
- case TKIND_DISPATCH:
- case TKIND_INTERFACE:
- if (readit)
- hres = _unmarshal_interface(buf,&(tattr->guid),(LPUNKNOWN*)arg);
- 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: {
- int i;
-
- if (debugout) TRACE_(olerelay)("{");
- for (i=0;i<tattr->cVars;i++) {
- VARDESC *vdesc;
-
- hres = ITypeInfo_GetVarDesc(tinfo2, i, &vdesc);
- if (hres) {
- ERR("Could not get vardesc of %d\n",i);
- ITypeInfo_ReleaseTypeAttr(tinfo2, tattr);
- ITypeInfo_Release(tinfo2);
- return hres;
- }
- hres = deserialize_param(
- tinfo2,
- readit,
- debugout,
- alloc,
- &vdesc->elemdescVar.tdesc,
- (DWORD_PTR *)(((LPBYTE)arg)+vdesc->u.oInst),
- buf
- );
- ITypeInfo_ReleaseVarDesc(tinfo2, vdesc);
- if (debugout && (i<tattr->cVars-1))
TRACE_(olerelay)(",");
- }
- if (debugout) TRACE_(olerelay)("}");
- break;
- }
- case TKIND_ALIAS:
- hres =
deserialize_param(tinfo2,readit,debugout,alloc,&tattr->tdescAlias,arg,buf);
- break;
- case TKIND_ENUM:
- if (readit) {
- hres = xbuf_get(buf,(LPBYTE)arg,sizeof(DWORD));
- if (hres) ERR("Failed to read enum (4 byte)\n");
- }
- if (debugout) TRACE_(olerelay)("%x", *(DWORD *)arg);
- break;
- default:
- ERR("Unhandled typekind %d\n",tattr->typekind);
- hres = E_FAIL;
- break;
- }
- ITypeInfo_ReleaseTypeAttr(tinfo2, tattr);
- }
- if (hres)
- ERR("failed to stuballoc in TKIND_RECORD.\n");
- ITypeInfo_Release(tinfo2);
- return hres;
- }
- case VT_CARRAY: {
- /* arg is pointing to the start of the array. */
- LPBYTE base = (LPBYTE) arg;
- ARRAYDESC *adesc = tdesc->u.lpadesc;
- int arrsize,i;
- arrsize = 1;
- if (adesc->cDims > 1) FIXME("cDims > 1 in VT_CARRAY. Does it
work?\n");
- for (i=0;i<adesc->cDims;i++)
- arrsize *= adesc->rgbounds[i].cElements;
- if (_passbyref(&adesc->tdescElem, tinfo))
- {
- base = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,_xsize(tdesc->u.lptdesc,
tinfo) * arrsize);
- *arg = (DWORD_PTR)base;
- }
- for (i=0;i<arrsize;i++)
- deserialize_param(
- tinfo,
- readit,
- debugout,
- alloc,
- &adesc->tdescElem,
- (DWORD_PTR *)(base + i*_xsize(&adesc->tdescElem, tinfo)),
- buf
- );
- return S_OK;
- }
- case VT_SAFEARRAY: {
- if (readit)
- {
- ULONG flags = MAKELONG(MSHCTX_DIFFERENTMACHINE, NDR_LOCAL_DATA_REPRESENTATION);
- unsigned char *buffer;
- buffer = LPSAFEARRAY_UserUnmarshal(&flags, buf->base + buf->curoff,
(LPSAFEARRAY *)arg);
- buf->curoff = buffer - buf->base;
- }
- return S_OK;
- }
- default:
- ERR("No handler for VT type %d!\n",tdesc->vt);
- return S_OK;
- }
- }
-}
-
-/* Retrieves a function's funcdesc, searching back into inherited interfaces. */
-static HRESULT get_funcdesc(ITypeInfo *tinfo, int iMethod, ITypeInfo **tactual, const
FUNCDESC **fdesc,
- BSTR *iname, BSTR *fname, UINT *num)
-{
- HRESULT hr;
- UINT i, impl_types;
- UINT inherited_funcs = 0;
- TYPEATTR *attr;
-
- if (fname) *fname = NULL;
- if (iname) *iname = NULL;
- if (num) *num = 0;
- *tactual = NULL;
-
- hr = ITypeInfo_GetTypeAttr(tinfo, &attr);
- if (FAILED(hr))
- {
- ERR("GetTypeAttr failed with %x\n",hr);
- return hr;
- }
-
- if(attr->typekind == TKIND_DISPATCH)
- {
- if(attr->wTypeFlags & TYPEFLAG_FDUAL)
- {
- HREFTYPE href;
- ITypeInfo *tinfo2;
-
- hr = ITypeInfo_GetRefTypeOfImplType(tinfo, -1, &href);
- if(FAILED(hr))
- {
- ERR("Cannot get interface href from dual dispinterface\n");
- ITypeInfo_ReleaseTypeAttr(tinfo, attr);
- return hr;
- }
- hr = ITypeInfo_GetRefTypeInfo(tinfo, href, &tinfo2);
- if(FAILED(hr))
- {
- ERR("Cannot get interface from dual dispinterface\n");
- ITypeInfo_ReleaseTypeAttr(tinfo, attr);
- return hr;
- }
- hr = get_funcdesc(tinfo2, iMethod, tactual, fdesc, iname, fname, num);
- ITypeInfo_Release(tinfo2);
- ITypeInfo_ReleaseTypeAttr(tinfo, attr);
- return hr;
- }
- ERR("Shouldn't be called with a non-dual dispinterface\n");
- return E_FAIL;
- }
-
- impl_types = attr->cImplTypes;
- ITypeInfo_ReleaseTypeAttr(tinfo, attr);
-
- for (i = 0; i < impl_types; i++)
- {
- HREFTYPE href;
- ITypeInfo *pSubTypeInfo;
- UINT sub_funcs;
-
- hr = ITypeInfo_GetRefTypeOfImplType(tinfo, i, &href);
- if (FAILED(hr)) return hr;
- hr = ITypeInfo_GetRefTypeInfo(tinfo, href, &pSubTypeInfo);
- if (FAILED(hr)) return hr;
-
- hr = get_funcdesc(pSubTypeInfo, iMethod, tactual, fdesc, iname, fname,
&sub_funcs);
- inherited_funcs += sub_funcs;
- ITypeInfo_Release(pSubTypeInfo);
- if(SUCCEEDED(hr)) return hr;
- }
- if(iMethod < inherited_funcs)
- {
- ERR("shouldn't be here\n");
- return E_INVALIDARG;
- }
-
- for(i = inherited_funcs; i <= iMethod; i++)
- {
- hr = ITypeInfoImpl_GetInternalFuncDesc(tinfo, i - inherited_funcs, fdesc);
- if(FAILED(hr))
- {
- if(num) *num = i;
- return hr;
- }
- }
-
- /* found it. We don't care about num so zero it */
- if(num) *num = 0;
- *tactual = tinfo;
- ITypeInfo_AddRef(*tactual);
- if (fname)
ITypeInfo_GetDocumentation(tinfo,(*fdesc)->memid,fname,NULL,NULL,NULL);
- if (iname) ITypeInfo_GetDocumentation(tinfo,-1,iname,NULL,NULL,NULL);
- return S_OK;
-}
-
-static inline BOOL is_in_elem(const ELEMDESC *elem)
-{
- return (elem->u.paramdesc.wParamFlags & PARAMFLAG_FIN ||
!elem->u.paramdesc.wParamFlags);
-}
-
-static inline BOOL is_out_elem(const ELEMDESC *elem)
-{
- return (elem->u.paramdesc.wParamFlags & PARAMFLAG_FOUT ||
!elem->u.paramdesc.wParamFlags);
-}
-
-static DWORD WINAPI xCall(int method, void **args)
-{
- TMProxyImpl *tpinfo = args[0];
- DWORD_PTR *xargs;
- const FUNCDESC *fdesc;
- HRESULT hres;
- int i;
- marshal_state buf;
- RPCOLEMESSAGE msg;
- ULONG status;
- BSTR fname,iname;
- BSTR names[10];
- UINT nrofnames;
- DWORD remoteresult = 0;
- ITypeInfo *tinfo;
- IRpcChannelBuffer *chanbuf;
-
- EnterCriticalSection(&tpinfo->crit);
-
- hres =
get_funcdesc(tpinfo->tinfo,method,&tinfo,&fdesc,&iname,&fname,NULL);
- if (hres) {
- ERR("Did not find typeinfo/funcdesc entry for method %d!\n",method);
- LeaveCriticalSection(&tpinfo->crit);
- return E_FAIL;
- }
-
- if (!tpinfo->chanbuf)
- {
- WARN("Tried to use disconnected proxy\n");
- ITypeInfo_Release(tinfo);
- LeaveCriticalSection(&tpinfo->crit);
- return RPC_E_DISCONNECTED;
- }
- chanbuf = tpinfo->chanbuf;
- IRpcChannelBuffer_AddRef(chanbuf);
-
- LeaveCriticalSection(&tpinfo->crit);
-
- if (TRACE_ON(olerelay)) {
- TRACE_(olerelay)("->");
- if (iname)
- TRACE_(olerelay)("%s:",relaystr(iname));
- if (fname)
- TRACE_(olerelay)("%s(%d)",relaystr(fname),method);
- else
- TRACE_(olerelay)("%d",method);
- TRACE_(olerelay)("(");
- }
-
- SysFreeString(iname);
- SysFreeString(fname);
-
- memset(&buf,0,sizeof(buf));
-
- /* normal typelib driven serializing */
-
- /* Need them for hack below */
- memset(names,0,sizeof(names));
- if
(ITypeInfo_GetNames(tinfo,fdesc->memid,names,sizeof(names)/sizeof(names[0]),&nrofnames))
- nrofnames = 0;
- if (nrofnames > sizeof(names)/sizeof(names[0]))
- ERR("Need more names!\n");
-
- xargs = (DWORD_PTR *)(args + 1);
- for (i=0;i<fdesc->cParams;i++) {
- ELEMDESC *elem = fdesc->lprgelemdescParam+i;
- if (TRACE_ON(olerelay)) {
- if (i) TRACE_(olerelay)(",");
- if (i+1<nrofnames && names[i+1])
- TRACE_(olerelay)("%s=",relaystr(names[i+1]));
- }
- /* No need to marshal other data than FIN and any VT_PTR. */
- if (!is_in_elem(elem))
- {
- if (elem->tdesc.vt != VT_PTR)
- {
- xargs+=_argsize(&elem->tdesc, tinfo);
- TRACE_(olerelay)("[out]");
- continue;
- }
- else
- {
- memset( *(void **)xargs, 0, _xsize( elem->tdesc.u.lptdesc, tinfo ) );
- }
- }
-
- hres = serialize_param(
- tinfo,
- is_in_elem(elem),
- TRACE_ON(olerelay),
- FALSE,
- &elem->tdesc,
- xargs,
- &buf
- );
-
- if (hres) {
- ERR("Failed to serialize param, hres %x\n",hres);
- break;
- }
- xargs+=_argsize(&elem->tdesc, tinfo);
- }
- TRACE_(olerelay)(")");
-
- memset(&msg,0,sizeof(msg));
- msg.cbBuffer = buf.curoff;
- msg.iMethod = method;
- hres = IRpcChannelBuffer_GetBuffer(chanbuf,&msg,&(tpinfo->iid));
- if (hres) {
- ERR("RpcChannelBuffer GetBuffer failed, %x\n",hres);
- goto exit;
- }
- memcpy(msg.Buffer,buf.base,buf.curoff);
- TRACE_(olerelay)("\n");
- hres = IRpcChannelBuffer_SendReceive(chanbuf,&msg,&status);
- if (hres) {
- ERR("RpcChannelBuffer SendReceive failed, %x\n",hres);
- goto exit;
- }
-
- TRACE_(olerelay)(" status = %08x (",status);
- if (buf.base)
- buf.base = HeapReAlloc(GetProcessHeap(),0,buf.base,msg.cbBuffer);
- else
- buf.base = HeapAlloc(GetProcessHeap(),0,msg.cbBuffer);
- buf.size = msg.cbBuffer;
- memcpy(buf.base,msg.Buffer,buf.size);
- buf.curoff = 0;
-
- /* generic deserializer using typelib description */
- xargs = (DWORD_PTR *)(args + 1);
- status = S_OK;
- for (i=0;i<fdesc->cParams;i++) {
- ELEMDESC *elem = fdesc->lprgelemdescParam+i;
-
- if (i) TRACE_(olerelay)(",");
- if (i+1<nrofnames && names[i+1])
TRACE_(olerelay)("%s=",relaystr(names[i+1]));
-
- /* No need to marshal other data than FOUT and any VT_PTR */
- if (!is_out_elem(elem) && (elem->tdesc.vt != VT_PTR)) {
- xargs += _argsize(&elem->tdesc, tinfo);
- TRACE_(olerelay)("[in]");
- continue;
- }
- hres = deserialize_param(
- tinfo,
- is_out_elem(elem),
- TRACE_ON(olerelay),
- FALSE,
- &(elem->tdesc),
- xargs,
- &buf
- );
- if (hres) {
- ERR("Failed to unmarshall param, hres %x\n",hres);
- status = hres;
- break;
- }
- xargs += _argsize(&elem->tdesc, tinfo);
- }
-
- hres = xbuf_get(&buf, (LPBYTE)&remoteresult, sizeof(DWORD));
- if (hres != S_OK)
- goto exit;
- TRACE_(olerelay)(") = %08x\n", remoteresult);
-
- hres = remoteresult;
-
-exit:
- IRpcChannelBuffer_FreeBuffer(chanbuf,&msg);
- for (i = 0; i < nrofnames; i++)
- SysFreeString(names[i]);
- HeapFree(GetProcessHeap(),0,buf.base);
- IRpcChannelBuffer_Release(chanbuf);
- ITypeInfo_Release(tinfo);
- TRACE("-- 0x%08x\n", hres);
- return hres;
-}
-
-static HRESULT WINAPI ProxyIUnknown_QueryInterface(IUnknown *iface, REFIID riid, void
**ppv)
-{
- TMProxyImpl *proxy = (TMProxyImpl *)iface;
-
- TRACE("(%s, %p)\n", debugstr_guid(riid), ppv);
-
- if (proxy->outerunknown)
- return IUnknown_QueryInterface(proxy->outerunknown, riid, ppv);
-
- FIXME("No interface\n");
- return E_NOINTERFACE;
-}
-
-static ULONG WINAPI ProxyIUnknown_AddRef(IUnknown *iface)
-{
- TMProxyImpl *proxy = (TMProxyImpl *)iface;
-
- TRACE("\n");
-
- if (proxy->outerunknown)
- return IUnknown_AddRef(proxy->outerunknown);
-
- return 2; /* FIXME */
-}
-
-static ULONG WINAPI ProxyIUnknown_Release(IUnknown *iface)
-{
- TMProxyImpl *proxy = (TMProxyImpl *)iface;
-
- TRACE("\n");
-
- if (proxy->outerunknown)
- return IUnknown_Release(proxy->outerunknown);
-
- return 1; /* FIXME */
-}
-
-static HRESULT WINAPI ProxyIDispatch_GetTypeInfoCount(LPDISPATCH iface, UINT * pctinfo)
-{
- TMProxyImpl *This = (TMProxyImpl *)iface;
-
- TRACE("(%p)\n", pctinfo);
-
- return IDispatch_GetTypeInfoCount(This->dispatch, pctinfo);
-}
-
-static HRESULT WINAPI ProxyIDispatch_GetTypeInfo(LPDISPATCH iface, UINT iTInfo, LCID
lcid, ITypeInfo** ppTInfo)
-{
- TMProxyImpl *This = (TMProxyImpl *)iface;
-
- TRACE("(%d, %x, %p)\n", iTInfo, lcid, ppTInfo);
-
- return IDispatch_GetTypeInfo(This->dispatch, iTInfo, lcid, ppTInfo);
-}
-
-static HRESULT WINAPI ProxyIDispatch_GetIDsOfNames(LPDISPATCH iface, REFIID riid,
LPOLESTR * rgszNames, UINT cNames, LCID lcid, DISPID * rgDispId)
-{
- TMProxyImpl *This = (TMProxyImpl *)iface;
-
- TRACE("(%s, %p, %d, 0x%x, %p)\n", debugstr_guid(riid), rgszNames, cNames,
lcid, rgDispId);
-
- return IDispatch_GetIDsOfNames(This->dispatch, riid, rgszNames,
- cNames, lcid, rgDispId);
-}
-
-static HRESULT WINAPI ProxyIDispatch_Invoke(LPDISPATCH iface, DISPID dispIdMember, REFIID
riid, LCID lcid,
- WORD wFlags, DISPPARAMS * pDispParams,
VARIANT * pVarResult,
- EXCEPINFO * pExcepInfo, UINT * puArgErr)
-{
- TMProxyImpl *This = (TMProxyImpl *)iface;
-
- TRACE("(%d, %s, 0x%x, 0x%x, %p, %p, %p, %p)\n", dispIdMember,
- debugstr_guid(riid), lcid, wFlags, pDispParams, pVarResult,
- pExcepInfo, puArgErr);
-
- return IDispatch_Invoke(This->dispatch, dispIdMember, riid, lcid,
- wFlags, pDispParams, pVarResult, pExcepInfo,
- puArgErr);
-}
-
-typedef struct
-{
- IRpcChannelBuffer IRpcChannelBuffer_iface;
- LONG refs;
- /* the IDispatch-derived interface we are handling */
- IID tmarshal_iid;
- IRpcChannelBuffer *pDelegateChannel;
-} TMarshalDispatchChannel;
-
-static inline TMarshalDispatchChannel *impl_from_IRpcChannelBuffer(IRpcChannelBuffer
*iface)
-{
- return CONTAINING_RECORD(iface, TMarshalDispatchChannel, IRpcChannelBuffer_iface);
-}
-
-static HRESULT WINAPI TMarshalDispatchChannel_QueryInterface(IRpcChannelBuffer *iface,
REFIID riid, LPVOID *ppv)
-{
- *ppv = NULL;
- if (IsEqualIID(riid,&IID_IRpcChannelBuffer) ||
IsEqualIID(riid,&IID_IUnknown))
- {
- *ppv = iface;
- IRpcChannelBuffer_AddRef(iface);
- return S_OK;
- }
- return E_NOINTERFACE;
-}
-
-static ULONG WINAPI TMarshalDispatchChannel_AddRef(LPRPCCHANNELBUFFER iface)
-{
- TMarshalDispatchChannel *This = impl_from_IRpcChannelBuffer(iface);
- return InterlockedIncrement(&This->refs);
-}
-
-static ULONG WINAPI TMarshalDispatchChannel_Release(LPRPCCHANNELBUFFER iface)
-{
- TMarshalDispatchChannel *This = impl_from_IRpcChannelBuffer(iface);
- ULONG ref;
-
- ref = InterlockedDecrement(&This->refs);
- if (ref)
- return ref;
-
- IRpcChannelBuffer_Release(This->pDelegateChannel);
- HeapFree(GetProcessHeap(), 0, This);
- return 0;
-}
-
-static HRESULT WINAPI TMarshalDispatchChannel_GetBuffer(LPRPCCHANNELBUFFER iface,
RPCOLEMESSAGE* olemsg, REFIID riid)
-{
- TMarshalDispatchChannel *This = impl_from_IRpcChannelBuffer(iface);
- TRACE("(%p, %s)\n", olemsg, debugstr_guid(riid));
- /* Note: we are pretending to invoke a method on the interface identified
- * by tmarshal_iid so that we can re-use the IDispatch proxy/stub code
- * without the RPC runtime getting confused by not exporting an IDispatch interface
*/
- return IRpcChannelBuffer_GetBuffer(This->pDelegateChannel, olemsg,
&This->tmarshal_iid);
-}
-
-static HRESULT WINAPI TMarshalDispatchChannel_SendReceive(LPRPCCHANNELBUFFER iface,
RPCOLEMESSAGE *olemsg, ULONG *pstatus)
-{
- TMarshalDispatchChannel *This = impl_from_IRpcChannelBuffer(iface);
- TRACE("(%p, %p)\n", olemsg, pstatus);
- return IRpcChannelBuffer_SendReceive(This->pDelegateChannel, olemsg, pstatus);
-}
-
-static HRESULT WINAPI TMarshalDispatchChannel_FreeBuffer(LPRPCCHANNELBUFFER iface,
RPCOLEMESSAGE* olemsg)
-{
- TMarshalDispatchChannel *This = impl_from_IRpcChannelBuffer(iface);
- TRACE("(%p)\n", olemsg);
- return IRpcChannelBuffer_FreeBuffer(This->pDelegateChannel, olemsg);
-}
-
-static HRESULT WINAPI TMarshalDispatchChannel_GetDestCtx(LPRPCCHANNELBUFFER iface, DWORD*
pdwDestContext, void** ppvDestContext)
-{
- TMarshalDispatchChannel *This = impl_from_IRpcChannelBuffer(iface);
- TRACE("(%p,%p)\n", pdwDestContext, ppvDestContext);
- return IRpcChannelBuffer_GetDestCtx(This->pDelegateChannel, pdwDestContext,
ppvDestContext);
-}
-
-static HRESULT WINAPI TMarshalDispatchChannel_IsConnected(LPRPCCHANNELBUFFER iface)
-{
- TMarshalDispatchChannel *This = impl_from_IRpcChannelBuffer(iface);
- TRACE("()\n");
- return IRpcChannelBuffer_IsConnected(This->pDelegateChannel);
-}
-
-static const IRpcChannelBufferVtbl TMarshalDispatchChannelVtbl =
-{
- TMarshalDispatchChannel_QueryInterface,
- TMarshalDispatchChannel_AddRef,
- TMarshalDispatchChannel_Release,
- TMarshalDispatchChannel_GetBuffer,
- TMarshalDispatchChannel_SendReceive,
- TMarshalDispatchChannel_FreeBuffer,
- TMarshalDispatchChannel_GetDestCtx,
- TMarshalDispatchChannel_IsConnected
-};
-
-static HRESULT TMarshalDispatchChannel_Create(
- IRpcChannelBuffer *pDelegateChannel, REFIID tmarshal_riid,
- IRpcChannelBuffer **ppChannel)
-{
- TMarshalDispatchChannel *This = HeapAlloc(GetProcessHeap(), 0, sizeof(*This));
- if (!This)
- return E_OUTOFMEMORY;
-
- This->IRpcChannelBuffer_iface.lpVtbl = &TMarshalDispatchChannelVtbl;
- This->refs = 1;
- IRpcChannelBuffer_AddRef(pDelegateChannel);
- This->pDelegateChannel = pDelegateChannel;
- This->tmarshal_iid = *tmarshal_riid;
-
- *ppChannel = &This->IRpcChannelBuffer_iface;
- return S_OK;
-}
-
-
-static inline HRESULT get_facbuf_for_iid(REFIID riid, IPSFactoryBuffer **facbuf)
-{
- HRESULT hr;
- CLSID clsid;
-
- if ((hr = CoGetPSClsid(riid, &clsid)))
- return hr;
- return CoGetClassObject(&clsid, CLSCTX_INPROC_SERVER, NULL,
- &IID_IPSFactoryBuffer, (LPVOID*)facbuf);
-}
-
-static HRESULT init_proxy_entry_point(TMProxyImpl *proxy, unsigned int num)
-{
- int j;
- /* nrofargs including This */
- int nrofargs = 1;
- ITypeInfo *tinfo2;
- TMAsmProxy *xasm = proxy->asmstubs + num;
- HRESULT hres;
- const FUNCDESC *fdesc;
-
- hres = get_funcdesc(proxy->tinfo, num, &tinfo2, &fdesc, NULL, NULL,
NULL);
- if (hres) {
- ERR("GetFuncDesc %x should not fail here.\n",hres);
- return hres;
- }
- ITypeInfo_Release(tinfo2);
- /* some args take more than 4 byte on the stack */
- for (j=0;j<fdesc->cParams;j++)
- nrofargs += _argsize(&fdesc->lprgelemdescParam[j].tdesc,
proxy->tinfo);
-
-#ifdef __i386__
- if (fdesc->callconv != CC_STDCALL) {
- ERR("calling convention is not stdcall????\n");
- return E_FAIL;
- }
-/* leal 4(%esp),%eax
- * pushl %eax
- * pushl <nr>
- * call xCall
- * lret <nr>
- */
- xasm->lealeax = 0x0424448d;
- xasm->pushleax = 0x50;
- xasm->pushlval = 0x68;
- xasm->nr = num;
- xasm->lcall = 0xe8;
- xasm->xcall = (char *)xCall - (char *)&xasm->lret;
- xasm->lret = 0xc2;
- xasm->bytestopop = nrofargs * 4;
- xasm->nop = 0x9090;
- 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
- FIXME("not implemented on non i386\n");
- return E_FAIL;
-#endif
- return S_OK;
-}
-
-static HRESULT WINAPI
-PSFacBuf_CreateProxy(
- LPPSFACTORYBUFFER iface, IUnknown* pUnkOuter, REFIID riid,
- IRpcProxyBuffer **ppProxy, LPVOID *ppv)
-{
- HRESULT hres;
- ITypeInfo *tinfo;
- unsigned int i, nroffuncs, vtbl_size;
- TMProxyImpl *proxy;
- TYPEATTR *typeattr;
- BOOL defer_to_dispatch = FALSE;
-
- TRACE("(...%s...)\n",debugstr_guid(riid));
- hres = _get_typeinfo_for_iid(riid,&tinfo);
- if (hres) {
- ERR("No typeinfo for %s?\n",debugstr_guid(riid));
- return hres;
- }
-
- hres = num_of_funcs(tinfo, &nroffuncs, &vtbl_size);
- TRACE("Got %d funcs, vtbl size %d\n", nroffuncs, vtbl_size);
-
- if (FAILED(hres)) {
- ERR("Cannot get number of functions for typeinfo
%s\n",debugstr_guid(riid));
- ITypeInfo_Release(tinfo);
- return hres;
- }
-
- proxy = CoTaskMemAlloc(sizeof(TMProxyImpl));
- if (!proxy) return E_OUTOFMEMORY;
-
- proxy->dispatch = NULL;
- proxy->dispatch_proxy = NULL;
- proxy->outerunknown = pUnkOuter;
- proxy->asmstubs = VirtualAlloc(NULL, sizeof(TMAsmProxy) * nroffuncs, MEM_COMMIT,
PAGE_EXECUTE_READWRITE);
- if (!proxy->asmstubs) {
- ERR("Could not commit pages for proxy thunks\n");
- CoTaskMemFree(proxy);
- return E_OUTOFMEMORY;
- }
- proxy->IRpcProxyBuffer_iface.lpVtbl = &tmproxyvtable;
- /* one reference for the proxy */
- proxy->ref = 1;
- proxy->tinfo = tinfo;
- proxy->iid = *riid;
- proxy->chanbuf = 0;
-
- InitializeCriticalSection(&proxy->crit);
- proxy->crit.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ":
TMProxyImpl.crit");
-
- proxy->lpvtbl = HeapAlloc(GetProcessHeap(), 0, vtbl_size);
-
- /* if we derive from IDispatch then defer to its proxy for its methods */
- hres = ITypeInfo_GetTypeAttr(tinfo, &typeattr);
- if (hres == S_OK)
- {
- if (typeattr->wTypeFlags & TYPEFLAG_FDISPATCHABLE)
- {
- IPSFactoryBuffer *factory_buffer;
- hres = get_facbuf_for_iid(&IID_IDispatch, &factory_buffer);
- if (hres == S_OK)
- {
- hres = IPSFactoryBuffer_CreateProxy(factory_buffer, NULL,
- &IID_IDispatch, &proxy->dispatch_proxy,
- (void **)&proxy->dispatch);
- IPSFactoryBuffer_Release(factory_buffer);
- }
- if ((hres == S_OK) && (nroffuncs < 7))
- {
- ERR("nroffuncs calculated incorrectly (%d)\n", nroffuncs);
- hres = E_UNEXPECTED;
- }
- if (hres == S_OK)
- {
- defer_to_dispatch = TRUE;
- }
- }
- ITypeInfo_ReleaseTypeAttr(tinfo, typeattr);
- }
-
- for (i=0;i<nroffuncs;i++) {
- switch (i) {
- case 0:
- proxy->lpvtbl[i] = ProxyIUnknown_QueryInterface;
- break;
- case 1:
- proxy->lpvtbl[i] = ProxyIUnknown_AddRef;
- break;
- case 2:
- proxy->lpvtbl[i] = ProxyIUnknown_Release;
- break;
- case 3:
- if(!defer_to_dispatch) hres = init_proxy_entry_point(proxy, i);
- else proxy->lpvtbl[3] = ProxyIDispatch_GetTypeInfoCount;
- break;
- case 4:
- if(!defer_to_dispatch) hres = init_proxy_entry_point(proxy, i);
- else proxy->lpvtbl[4] = ProxyIDispatch_GetTypeInfo;
- break;
- case 5:
- if(!defer_to_dispatch) hres = init_proxy_entry_point(proxy, i);
- else proxy->lpvtbl[5] = ProxyIDispatch_GetIDsOfNames;
- break;
- case 6:
- if(!defer_to_dispatch) hres = init_proxy_entry_point(proxy, i);
- else proxy->lpvtbl[6] = ProxyIDispatch_Invoke;
- break;
- default:
- hres = init_proxy_entry_point(proxy, i);
- }
- }
-
- if (hres == S_OK)
- {
- *ppv = proxy;
- *ppProxy = &proxy->IRpcProxyBuffer_iface;
- IUnknown_AddRef((IUnknown *)*ppv);
- return S_OK;
- }
- else
- TMProxyImpl_Release(&proxy->IRpcProxyBuffer_iface);
- return hres;
-}
-
-typedef struct _TMStubImpl {
- IRpcStubBuffer IRpcStubBuffer_iface;
- LONG ref;
-
- LPUNKNOWN pUnk;
- ITypeInfo *tinfo;
- IID iid;
- IRpcStubBuffer *dispatch_stub;
- BOOL dispatch_derivative;
-} TMStubImpl;
-
-static inline TMStubImpl *impl_from_IRpcStubBuffer(IRpcStubBuffer *iface)
-{
- return CONTAINING_RECORD(iface, TMStubImpl, IRpcStubBuffer_iface);
-}
-
-static HRESULT WINAPI
-TMStubImpl_QueryInterface(LPRPCSTUBBUFFER iface, REFIID riid, LPVOID *ppv)
-{
- if (IsEqualIID(riid,&IID_IRpcStubBuffer)||IsEqualIID(riid,&IID_IUnknown)){
- *ppv = iface;
- IRpcStubBuffer_AddRef(iface);
- return S_OK;
- }
- FIXME("%s, not supported IID.\n",debugstr_guid(riid));
- return E_NOINTERFACE;
-}
-
-static ULONG WINAPI
-TMStubImpl_AddRef(LPRPCSTUBBUFFER iface)
-{
- TMStubImpl *This = impl_from_IRpcStubBuffer(iface);
- ULONG refCount = InterlockedIncrement(&This->ref);
-
- TRACE("(%p)->(ref before=%u)\n", This, refCount - 1);
-
- return refCount;
-}
-
-static ULONG WINAPI
-TMStubImpl_Release(LPRPCSTUBBUFFER iface)
-{
- TMStubImpl *This = impl_from_IRpcStubBuffer(iface);
- ULONG refCount = InterlockedDecrement(&This->ref);
-
- TRACE("(%p)->(ref before=%u)\n", This, refCount + 1);
-
- if (!refCount)
- {
- IRpcStubBuffer_Disconnect(iface);
- ITypeInfo_Release(This->tinfo);
- if (This->dispatch_stub)
- IRpcStubBuffer_Release(This->dispatch_stub);
- CoTaskMemFree(This);
- }
- return refCount;
-}
-
-static HRESULT WINAPI
-TMStubImpl_Connect(LPRPCSTUBBUFFER iface, LPUNKNOWN pUnkServer)
-{
- TMStubImpl *This = impl_from_IRpcStubBuffer(iface);
-
- TRACE("(%p)->(%p)\n", This, pUnkServer);
-
- IUnknown_AddRef(pUnkServer);
- This->pUnk = pUnkServer;
-
- if (This->dispatch_stub)
- IRpcStubBuffer_Connect(This->dispatch_stub, pUnkServer);
-
- return S_OK;
-}
-
-static void WINAPI
-TMStubImpl_Disconnect(LPRPCSTUBBUFFER iface)
-{
- TMStubImpl *This = impl_from_IRpcStubBuffer(iface);
-
- TRACE("(%p)->()\n", This);
-
- if (This->pUnk)
- {
- IUnknown_Release(This->pUnk);
- This->pUnk = NULL;
- }
-
- if (This->dispatch_stub)
- IRpcStubBuffer_Disconnect(This->dispatch_stub);
-}
-
-static HRESULT WINAPI
-TMStubImpl_Invoke(
- LPRPCSTUBBUFFER iface, RPCOLEMESSAGE* xmsg,IRpcChannelBuffer*rpcchanbuf)
-{
-#if defined(__i386__) || defined(__x86_64__)
- int i;
- const FUNCDESC *fdesc;
- TMStubImpl *This = impl_from_IRpcStubBuffer(iface);
- HRESULT hres;
- DWORD_PTR *args = NULL, *xargs;
- DWORD res, nrofargs;
- marshal_state buf;
- UINT nrofnames = 0;
- BSTR names[10];
- BSTR iname = NULL;
- ITypeInfo *tinfo = NULL;
-
- TRACE("...\n");
-
- if (xmsg->iMethod < 3) {
- ERR("IUnknown methods cannot be marshaled by the typelib
marshaler\n");
- return E_UNEXPECTED;
- }
-
- if (This->dispatch_derivative && xmsg->iMethod <
sizeof(IDispatchVtbl)/sizeof(void *))
- {
- if (!This->dispatch_stub)
- {
- IPSFactoryBuffer *factory_buffer;
- hres = get_facbuf_for_iid(&IID_IDispatch, &factory_buffer);
- if (hres == S_OK)
- {
- hres = IPSFactoryBuffer_CreateStub(factory_buffer, &IID_IDispatch,
- This->pUnk, &This->dispatch_stub);
- IPSFactoryBuffer_Release(factory_buffer);
- }
- if (hres != S_OK)
- return hres;
- }
- return IRpcStubBuffer_Invoke(This->dispatch_stub, xmsg, rpcchanbuf);
- }
-
- memset(&buf,0,sizeof(buf));
- buf.size = xmsg->cbBuffer;
- buf.base = HeapAlloc(GetProcessHeap(), 0, xmsg->cbBuffer);
- memcpy(buf.base, xmsg->Buffer, xmsg->cbBuffer);
- buf.curoff = 0;
-
- hres =
get_funcdesc(This->tinfo,xmsg->iMethod,&tinfo,&fdesc,&iname,NULL,NULL);
- if (hres) {
- ERR("GetFuncDesc on method %d failed with %x\n",xmsg->iMethod,hres);
- return hres;
- }
-
- if (iname && !lstrcmpW(iname, IDispatchW))
- {
- ERR("IDispatch cannot be marshaled by the typelib marshaler\n");
- hres = E_UNEXPECTED;
- SysFreeString (iname);
- goto exit;
- }
-
- SysFreeString (iname);
-
- /* Need them for hack below */
- memset(names,0,sizeof(names));
-
ITypeInfo_GetNames(tinfo,fdesc->memid,names,sizeof(names)/sizeof(names[0]),&nrofnames);
- if (nrofnames > sizeof(names)/sizeof(names[0])) {
- ERR("Need more names!\n");
- }
-
- /*dump_FUNCDESC(fdesc);*/
- nrofargs = 0;
- for (i=0;i<fdesc->cParams;i++)
- nrofargs += _argsize(&fdesc->lprgelemdescParam[i].tdesc, tinfo);
- args = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
(nrofargs+1)*sizeof(DWORD_PTR));
- if (!args)
- {
- hres = E_OUTOFMEMORY;
- goto exit;
- }
-
- /* Allocate all stuff used by call. */
- xargs = args+1;
- for (i=0;i<fdesc->cParams;i++) {
- ELEMDESC *elem = fdesc->lprgelemdescParam+i;
-
- hres = deserialize_param(
- tinfo,
- is_in_elem(elem),
- FALSE,
- TRUE,
- &(elem->tdesc),
- xargs,
- &buf
- );
- xargs += _argsize(&elem->tdesc, tinfo);
- if (hres) {
- ERR("Failed to deserialize param %s, hres
%x\n",relaystr(names[i+1]),hres);
- break;
- }
- }
-
- args[0] = (DWORD_PTR)This->pUnk;
-
- __TRY
- {
- res = _invoke(
- (*((FARPROC**)args[0]))[fdesc->oVft / sizeof(DWORD_PTR)],
- fdesc->callconv,
- (xargs-args),
- args
- );
- }
- __EXCEPT_ALL
- {
- DWORD dwExceptionCode = GetExceptionCode();
- ERR("invoke call failed with exception 0x%08x (%d)\n", dwExceptionCode,
dwExceptionCode);
- if (FAILED(dwExceptionCode))
- hres = dwExceptionCode;
- else
- hres = HRESULT_FROM_WIN32(dwExceptionCode);
- }
- __ENDTRY
-
- if (hres != S_OK)
- goto exit;
-
- buf.curoff = 0;
-
- xargs = args+1;
- for (i=0;i<fdesc->cParams;i++) {
- ELEMDESC *elem = fdesc->lprgelemdescParam+i;
- hres = serialize_param(
- tinfo,
- is_out_elem(elem),
- FALSE,
- TRUE,
- &elem->tdesc,
- xargs,
- &buf
- );
- xargs += _argsize(&elem->tdesc, tinfo);
- if (hres) {
- ERR("Failed to stuballoc param, hres %x\n",hres);
- break;
- }
- }
-
- hres = xbuf_add (&buf, (LPBYTE)&res, sizeof(DWORD));
-
- if (hres != S_OK)
- goto exit;
-
- xmsg->cbBuffer = buf.curoff;
- hres = IRpcChannelBuffer_GetBuffer(rpcchanbuf, xmsg, &This->iid);
- if (hres != S_OK)
- ERR("IRpcChannelBuffer_GetBuffer failed with error 0x%08x\n", hres);
-
- if (hres == S_OK)
- memcpy(xmsg->Buffer, buf.base, buf.curoff);
-
-exit:
- for (i = 0; i < nrofnames; i++)
- SysFreeString(names[i]);
-
- ITypeInfo_Release(tinfo);
- HeapFree(GetProcessHeap(), 0, args);
-
- HeapFree(GetProcessHeap(), 0, buf.base);
-
- TRACE("returning\n");
- return hres;
-#else
- FIXME( "not implemented on non-i386\n" );
- return E_FAIL;
-#endif
-}
-
-static LPRPCSTUBBUFFER WINAPI
-TMStubImpl_IsIIDSupported(LPRPCSTUBBUFFER iface, REFIID riid) {
- FIXME("Huh (%s)?\n",debugstr_guid(riid));
- return NULL;
-}
-
-static ULONG WINAPI
-TMStubImpl_CountRefs(LPRPCSTUBBUFFER iface) {
- TMStubImpl *This = impl_from_IRpcStubBuffer(iface);
-
- FIXME("()\n");
- return This->ref; /*FIXME? */
-}
-
-static HRESULT WINAPI
-TMStubImpl_DebugServerQueryInterface(LPRPCSTUBBUFFER iface, LPVOID *ppv) {
- return E_NOTIMPL;
-}
-
-static void WINAPI
-TMStubImpl_DebugServerRelease(LPRPCSTUBBUFFER iface, LPVOID ppv) {
- return;
-}
-
-static const IRpcStubBufferVtbl tmstubvtbl = {
- TMStubImpl_QueryInterface,
- TMStubImpl_AddRef,
- TMStubImpl_Release,
- TMStubImpl_Connect,
- TMStubImpl_Disconnect,
- TMStubImpl_Invoke,
- TMStubImpl_IsIIDSupported,
- TMStubImpl_CountRefs,
- TMStubImpl_DebugServerQueryInterface,
- TMStubImpl_DebugServerRelease
-};
-
-static HRESULT WINAPI
-PSFacBuf_CreateStub(
- LPPSFACTORYBUFFER iface, REFIID riid,IUnknown *pUnkServer,
- IRpcStubBuffer** ppStub
-) {
- HRESULT hres;
- ITypeInfo *tinfo;
- TMStubImpl *stub;
- TYPEATTR *typeattr;
- IUnknown *obj;
-
- TRACE("(%s,%p,%p)\n",debugstr_guid(riid),pUnkServer,ppStub);
-
- hres = _get_typeinfo_for_iid(riid,&tinfo);
- if (hres) {
- ERR("No typeinfo for %s?\n",debugstr_guid(riid));
- return hres;
- }
-
- /* FIXME: This is not exactly right. We should probably call QI later. */
- hres = IUnknown_QueryInterface(pUnkServer, riid, (void**)&obj);
- if (FAILED(hres)) {
- WARN("Could not get %s iface: %08x\n", debugstr_guid(riid), hres);
- obj = pUnkServer;
- IUnknown_AddRef(obj);
- }
-
- stub = CoTaskMemAlloc(sizeof(TMStubImpl));
- if (!stub) {
- IUnknown_Release(obj);
- return E_OUTOFMEMORY;
- }
- stub->IRpcStubBuffer_iface.lpVtbl = &tmstubvtbl;
- stub->ref = 1;
- stub->tinfo = tinfo;
- stub->dispatch_stub = NULL;
- stub->dispatch_derivative = FALSE;
- stub->iid = *riid;
- hres = IRpcStubBuffer_Connect(&stub->IRpcStubBuffer_iface, obj);
- *ppStub = &stub->IRpcStubBuffer_iface;
- TRACE("IRpcStubBuffer: %p\n", stub);
- if (hres)
- ERR("Connect to pUnkServer failed?\n");
-
- /* if we derive from IDispatch then defer to its stub for some of its methods */
- hres = ITypeInfo_GetTypeAttr(tinfo, &typeattr);
- if (hres == S_OK)
- {
- if (typeattr->wTypeFlags & TYPEFLAG_FDISPATCHABLE)
- stub->dispatch_derivative = TRUE;
- ITypeInfo_ReleaseTypeAttr(tinfo, typeattr);
- }
-
- IUnknown_Release(obj);
- return hres;
-}
-
-static const IPSFactoryBufferVtbl psfacbufvtbl = {
- PSFacBuf_QueryInterface,
- PSFacBuf_AddRef,
- PSFacBuf_Release,
- PSFacBuf_CreateProxy,
- PSFacBuf_CreateStub
-};
-
-static IPSFactoryBuffer psfac = { &psfacbufvtbl };
-
-/***********************************************************************
- * TMARSHAL_DllGetClassObject
- */
-HRESULT TMARSHAL_DllGetClassObject(REFCLSID rclsid, REFIID iid, void **ppv)
-{
- return IPSFactoryBuffer_QueryInterface(&psfac, iid, ppv);
-}
diff --git a/dll/win32/oleaut32/typelib.c b/dll/win32/oleaut32/typelib.c
index 4a609d7050..6ed9ce9eb7 100644
--- a/dll/win32/oleaut32/typelib.c
+++ b/dll/win32/oleaut32/typelib.c
@@ -328,7 +328,7 @@ static HRESULT query_typelib_path( REFGUID guid, WORD wMaj, WORD
wMin,
return TYPE_E_LIBNOTREGISTERED;
nameW = (WCHAR*)((BYTE*)data.lpSectionBase + tlib->name_offset);
- len = SearchPathW( NULL, nameW, NULL, sizeof(Path)/sizeof(WCHAR), Path, NULL
);
+ len = SearchPathW( NULL, nameW, NULL, ARRAY_SIZE( Path ), Path, NULL );
if (!len) return TYPE_E_LIBNOTREGISTERED;
TRACE_(typelib)("got path from context %s\n", debugstr_w(Path));
@@ -979,11 +979,11 @@ enddeleteloop:
/* check if there is anything besides the FLAGS/HELPDIR keys.
If there is, we don't delete them */
- tmpLength = sizeof(subKeyName)/sizeof(WCHAR);
+ tmpLength = ARRAY_SIZE(subKeyName);
deleteOtherStuff = TRUE;
i = 0;
while(RegEnumKeyExW(key, i++, subKeyName, &tmpLength, NULL, NULL, NULL, NULL) ==
ERROR_SUCCESS) {
- tmpLength = sizeof(subKeyName)/sizeof(WCHAR);
+ tmpLength = ARRAY_SIZE(subKeyName);
/* if its not FLAGS or HELPDIR, then we must keep the rest of the key */
if (!strcmpW(subKeyName, FLAGSW)) continue;
@@ -2685,7 +2685,7 @@ static ITypeInfoImpl * MSFT_DoTypeInfo(
ptiRet->typeattr.wMajorVerNum = LOWORD(tiBase.version);
ptiRet->typeattr.wMinorVerNum = HIWORD(tiBase.version);
ptiRet->typeattr.cImplTypes = tiBase.cImplTypes;
- ptiRet->typeattr.cbSizeVft = tiBase.cbSizeVft; /* FIXME: this is only the non
inherited part */
+ ptiRet->typeattr.cbSizeVft = tiBase.cbSizeVft;
if (ptiRet->typeattr.typekind == TKIND_ALIAS) {
TYPEDESC tmp;
MSFT_GetTdesc(pcx, tiBase.datatype1, &tmp);
@@ -6405,6 +6405,7 @@ static HRESULT WINAPI ITypeInfo_fnGetIDsOfNames( ITypeInfo2 *iface,
#ifdef __i386__
extern LONGLONG call_method( void *func, int nb_args, const DWORD *args, int
*stack_offset );
+extern double call_double_method( void *func, int nb_args, const DWORD *args, int
*stack_offset );
__ASM_GLOBAL_FUNC( call_method,
"pushl %ebp\n\t"
__ASM_CFI(".cfi_adjust_cfa_offset 4\n\t")
@@ -6439,45 +6440,13 @@ __ASM_GLOBAL_FUNC( call_method,
__ASM_CFI(".cfi_def_cfa %esp,4\n\t")
__ASM_CFI(".cfi_same_value %ebp\n\t")
"ret" )
-
-/* same function but returning floating point */
-static double (* const call_double_method)(void*,int,const DWORD*,int*) = (void
*)call_method;
-
-/* ITypeInfo::Invoke
- *
- * Invokes a method, or accesses a property of an object, that implements the
- * interface described by the type description.
- */
-DWORD _invoke(FARPROC func, CALLCONV callconv, int nrargs, DWORD_PTR *args)
-{
- DWORD res;
- int stack_offset;
-
- if (TRACE_ON(ole)) {
- int i;
- TRACE("Calling %p(",func);
- for (i=0;i<min(nrargs,30);i++) TRACE("%08lx,",args[i]);
- if (nrargs > 30) TRACE("...");
- TRACE(")\n");
- }
-
- switch (callconv) {
- case CC_STDCALL:
- case CC_CDECL:
- res = call_method(func, nrargs, (DWORD *)args, &stack_offset);
- break;
- default:
- FIXME("unsupported calling convention %d\n",callconv);
- res = -1;
- break;
- }
- TRACE("returns %08x\n",res);
- return res;
-}
+__ASM_GLOBAL_FUNC( call_double_method,
+ "jmp " __ASM_NAME("call_method") )
#elif defined(__x86_64__)
extern DWORD_PTR CDECL call_method( void *func, int nb_args, const DWORD_PTR *args );
+extern double CDECL call_double_method( void *func, int nb_args, const DWORD_PTR *args
);
__ASM_GLOBAL_FUNC( call_method,
"pushq %rbp\n\t"
__ASM_CFI(".cfi_adjust_cfa_offset 8\n\t")
@@ -6517,41 +6486,14 @@ __ASM_GLOBAL_FUNC( call_method,
__ASM_CFI(".cfi_adjust_cfa_offset -8\n\t")
__ASM_CFI(".cfi_same_value %rbp\n\t")
"ret")
-
-/* same function but returning floating point */
-static double (CDECL * const call_double_method)(void*,int,const DWORD_PTR*) = (void
*)call_method;
-
-DWORD _invoke(FARPROC func, CALLCONV callconv, int nrargs, DWORD_PTR *args)
-{
- DWORD res;
-
- if (TRACE_ON(ole))
- {
- int i;
- TRACE("Calling %p(", func);
- for (i=0; i<min(nrargs, 30); i++) TRACE("%016lx,", args[i]);
- if (nrargs > 30) TRACE("...");
- TRACE(")\n");
- }
-
- switch (callconv) {
- case CC_STDCALL:
- case CC_CDECL:
- res = call_method(func, nrargs, args);
- break;
- default:
- FIXME("unsupported calling convention %d\n", callconv);
- res = -1;
- break;
- }
-
- TRACE("returns %08x\n", res);
- return res;
-}
+__ASM_GLOBAL_FUNC( call_double_method,
+ "jmp " __ASM_NAME("call_method") )
#elif defined(__arm__)
extern LONGLONG CDECL call_method( void *func, int nb_stk_args, const DWORD *stk_args,
const DWORD *reg_args );
+extern float CDECL call_float_method( void *func, int nb_stk_args, const DWORD *stk_args,
const DWORD *reg_args );
+extern double CDECL call_double_method( void *func, int nb_stk_args, const DWORD
*stk_args, const DWORD *reg_args );
__ASM_GLOBAL_FUNC( call_method,
/* r0 = *func
* r1 = nb_stk_args
@@ -6582,12 +6524,12 @@ __ASM_GLOBAL_FUNC( call_method,
"mov sp, fp\n\t" /* Clean the stack using fp
*/
"pop {fp, pc}\n\t" /* Restore fp and return
*/
)
+__ASM_GLOBAL_FUNC( call_float_method,
+ "b " __ASM_NAME("call_method") )
+__ASM_GLOBAL_FUNC( call_double_method,
+ "b " __ASM_NAME("call_method") )
-/* 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 /* __arm__ */
static HRESULT userdefined_to_variantvt(ITypeInfo *tinfo, const TYPEDESC *tdesc, VARTYPE
*vt)
{
@@ -6728,6 +6670,7 @@ static HRESULT get_iface_guid(ITypeInfo *tinfo, HREFTYPE href, GUID
*guid)
ITypeInfo *tinfo2;
TYPEATTR *tattr;
HRESULT hres;
+ int flags, i;
hres = ITypeInfo_GetRefTypeInfo(tinfo, href, &tinfo2);
if(FAILED(hres))
@@ -6749,20 +6692,21 @@ static HRESULT get_iface_guid(ITypeInfo *tinfo, HREFTYPE href,
GUID *guid)
*guid = tattr->guid;
break;
- case TKIND_COCLASS: {
- unsigned int i;
- int type_flags;
+ case TKIND_COCLASS:
+ for (i = 0; i < tattr->cImplTypes; i++)
+ {
+ ITypeInfo_GetImplTypeFlags(tinfo2, i, &flags);
+ if (flags & IMPLTYPEFLAG_FDEFAULT)
+ break;
+ }
- 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)
+ i = 0;
- if(i < tattr->cImplTypes) {
- hres = ITypeInfo_GetRefTypeOfImplType(tinfo2, i, &href);
- if(SUCCEEDED(hres)) hres = get_iface_guid(tinfo2, href, guid);
- } else hres = E_UNEXPECTED;
+ hres = ITypeInfo_GetRefTypeOfImplType(tinfo2, i, &href);
+ if (SUCCEEDED(hres))
+ hres = get_iface_guid(tinfo2, href, guid);
break;
- }
default:
ERR("Unexpected typekind %d\n", tattr->typekind);
@@ -6818,7 +6762,7 @@ DispCallFunc(
VARTYPE* prgvt, VARIANTARG** prgpvarg, VARIANT* pvargResult)
{
#ifdef __i386__
- int argspos, stack_offset;
+ int argspos = 0, stack_offset;
void *func;
UINT i;
DWORD *args;
@@ -6836,8 +6780,6 @@ DispCallFunc(
/* maximum size for an argument is sizeof(VARIANT) */
args = heap_alloc(sizeof(VARIANT) * cActuals + sizeof(DWORD) * 2 );
- /* start at 1 in case we need to pass a pointer to the return value as arg 0 */
- argspos = 1;
if (pvInstance)
{
const FARPROC *vtable = *(FARPROC **)pvInstance;
@@ -6846,6 +6788,20 @@ DispCallFunc(
}
else func = (void *)oVft;
+ switch (vtReturn)
+ {
+ case VT_DECIMAL:
+ case VT_VARIANT:
+ args[argspos++] = (DWORD)pvargResult; /* arg 0 is a pointer to the result */
+ break;
+ case VT_HRESULT:
+ WARN("invalid return type %u\n", vtReturn);
+ heap_free( args );
+ return E_INVALIDARG;
+ default:
+ break;
+ }
+
for (i = 0; i < cActuals; i++)
{
VARIANT *arg = prgpvarg[i];
@@ -6880,40 +6836,24 @@ DispCallFunc(
switch (vtReturn)
{
case VT_EMPTY:
- call_method( func, argspos - 1, args + 1, &stack_offset );
+ case VT_DECIMAL:
+ case VT_VARIANT:
+ call_method( func, argspos, args, &stack_offset );
break;
case VT_R4:
- V_R4(pvargResult) = call_double_method( func, argspos - 1, args + 1,
&stack_offset );
+ V_R4(pvargResult) = call_double_method( func, argspos, args, &stack_offset
);
break;
case VT_R8:
case VT_DATE:
- V_R8(pvargResult) = call_double_method( func, argspos - 1, args + 1,
&stack_offset );
- break;
- case VT_DECIMAL:
- case VT_VARIANT:
- if (pvInstance)
- {
- 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 );
- }
+ V_R8(pvargResult) = call_double_method( func, argspos, args, &stack_offset
);
break;
case VT_I8:
case VT_UI8:
case VT_CY:
- V_UI8(pvargResult) = call_method( func, argspos - 1, args + 1, &stack_offset
);
+ V_UI8(pvargResult) = call_method( func, argspos, args, &stack_offset );
break;
- case VT_HRESULT:
- WARN("invalid return type %u\n", vtReturn);
- heap_free( args );
- return E_INVALIDARG;
default:
- V_UI4(pvargResult) = call_method( func, argspos - 1, args + 1, &stack_offset
);
+ V_UI4(pvargResult) = call_method( func, argspos, args, &stack_offset );
break;
}
heap_free( args );
@@ -6927,7 +6867,7 @@ DispCallFunc(
return S_OK;
#elif defined(__x86_64__)
- int argspos;
+ int argspos = 0;
UINT i;
DWORD_PTR *args;
void *func;
@@ -6945,8 +6885,6 @@ DispCallFunc(
/* maximum size for an argument is sizeof(DWORD_PTR) */
args = heap_alloc( sizeof(DWORD_PTR) * (cActuals + 2) );
- /* start at 1 in case we need to pass a pointer to the return value as arg 0 */
- argspos = 1;
if (pvInstance)
{
const FARPROC *vtable = *(FARPROC **)pvInstance;
@@ -6955,6 +6893,20 @@ DispCallFunc(
}
else func = (void *)oVft;
+ switch (vtReturn)
+ {
+ case VT_DECIMAL:
+ case VT_VARIANT:
+ args[argspos++] = (DWORD_PTR)pvargResult; /* arg 0 is a pointer to the result
*/
+ break;
+ case VT_HRESULT:
+ WARN("invalid return type %u\n", vtReturn);
+ heap_free( args );
+ return E_INVALIDARG;
+ default:
+ break;
+ }
+
for (i = 0; i < cActuals; i++)
{
VARIANT *arg = prgpvarg[i];
@@ -6978,32 +6930,18 @@ DispCallFunc(
switch (vtReturn)
{
case VT_R4:
- V_R4(pvargResult) = call_double_method( func, argspos - 1, args + 1 );
+ V_R4(pvargResult) = call_double_method( func, argspos, args );
break;
case VT_R8:
case VT_DATE:
- V_R8(pvargResult) = call_double_method( func, argspos - 1, args + 1 );
+ V_R8(pvargResult) = call_double_method( func, argspos, args );
break;
case VT_DECIMAL:
case VT_VARIANT:
- if (pvInstance)
- {
- 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 );
- }
+ call_method( func, argspos, args );
break;
- case VT_HRESULT:
- WARN("invalid return type %u\n", vtReturn);
- heap_free( args );
- return E_INVALIDARG;
default:
- V_UI8(pvargResult) = call_method( func, argspos - 1, args + 1 );
+ V_UI8(pvargResult) = call_method( func, argspos, args );
break;
}
heap_free( args );
@@ -7043,6 +6981,14 @@ DispCallFunc(
argspos = 0;
rcount = 0;
+ 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;
+
/* 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)
@@ -7058,14 +7004,6 @@ DispCallFunc(
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 );
@@ -7912,7 +7850,7 @@ static BOOL CALLBACK search_res_tlb(HMODULE hModule, LPCWSTR
lpszType, LPWSTR lp
if (!(len = GetModuleFileNameW(hModule, szPath, MAX_PATH)))
return TRUE;
- if (snprintfW(szPath + len, sizeof(szPath)/sizeof(WCHAR) - len, formatW,
LOWORD(lpszName)) < 0)
+ if (snprintfW(szPath + len, ARRAY_SIZE(szPath) - len, formatW, LOWORD(lpszName)) <
0)
return TRUE;
ret = LoadTypeLibEx(szPath, REGKIND_NONE, &pTLib);
diff --git a/dll/win32/oleaut32/typelib.h b/dll/win32/oleaut32/typelib.h
index bfea174bc0..4ab8055bd2 100644
--- a/dll/win32/oleaut32/typelib.h
+++ b/dll/win32/oleaut32/typelib.h
@@ -142,11 +142,11 @@ typedef struct tagMSFT_TypeInfoBase {
INT helpcontext; /* */
INT oCustData; /* offset in customer data table */
#ifdef WORDS_BIGENDIAN
- INT16 cbSizeVft; /* virtual table size, not including inherits */
+ INT16 cbSizeVft; /* virtual table size, including inherits */
INT16 cImplTypes; /* nr of implemented interfaces */
#else
INT16 cImplTypes; /* nr of implemented interfaces */
- INT16 cbSizeVft; /* virtual table size, not including inherits */
+ INT16 cbSizeVft; /* virtual table size, including inherits */
#endif
/*050*/ INT size; /* size in bytes, at least for structures */
/* FIXME: name of this field */
@@ -155,10 +155,8 @@ typedef struct tagMSFT_TypeInfoBase {
/* if coclass: offset in reftable */
/* if interface: reference to inherited if */
/* if module: offset to dllname in name table */
- INT datatype2; /* if 0x8000, entry above is valid */
- /* actually dunno */
- /* else it is zero? */
- /* if interface: inheritance level | no of inherited
funcs */
+ INT datatype2; /* for interfaces: hiword is num of inherited funcs */
+ /* loword is num of inherited interfaces
*/
INT res18; /* always? 0 */
/*060*/ INT res19; /* always? -1 */
} MSFT_TypeInfoBase;
@@ -281,9 +279,10 @@ typedef struct {
to the typeinfo itself or to a member of
the typeinfo */
INT next_hash; /* offset to next name in the hash bucket */
- INT namelen; /* only lower 8 bits are valid,
- lower-middle 8 bits are unknown (flags?),
- upper 16 bits are hash code */
+ INT namelen; /* only lower 8 bits are valid */
+ /* 0x1000 if name is only used once as a variable name */
+ /* 0x2000 if name is a variable in an enumeration */
+ /* 0x3800 if name is typeinfo name */
} MSFT_NameIntro;
/* the custom data table directory has entries like this */
typedef struct {
@@ -596,12 +595,6 @@ WORD typeofarray
#include "poppack.h"
-HRESULT ITypeInfoImpl_GetInternalFuncDesc( ITypeInfo *iface, UINT index, const FUNCDESC
**ppFuncDesc ) 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;
-
/* The OLE Automation ProxyStub Interface Class (aka Typelib Marshaler) */
DEFINE_OLEGUID( CLSID_PSDispatch, 0x00020420, 0x0000, 0x0000 );
DEFINE_OLEGUID( CLSID_PSEnumVariant, 0x00020421, 0x0000, 0x0000 );
diff --git a/dll/win32/oleaut32/usrmarshal.c b/dll/win32/oleaut32/usrmarshal.c
index da524c85eb..163b48f6f4 100644
--- a/dll/win32/oleaut32/usrmarshal.c
+++ b/dll/win32/oleaut32/usrmarshal.c
@@ -227,6 +227,9 @@ unsigned int get_type_size(ULONG *pFlags, VARTYPE vt)
case VT_INT:
case VT_UINT:
return sizeof(INT);
+ case VT_I8:
+ case VT_UI8:
+ return sizeof(LONGLONG);
case VT_R4:
return sizeof(FLOAT);
case VT_R8:
@@ -644,7 +647,8 @@ void WINAPI VARIANT_UserFree(ULONG *pFlags, VARIANT *pvar)
break;
case VT_UNKNOWN | VT_BYREF:
case VT_DISPATCH | VT_BYREF:
- IUnknown_Release(*V_UNKNOWNREF(pvar));
+ if (*V_UNKNOWNREF(pvar))
+ IUnknown_Release(*V_UNKNOWNREF(pvar));
break;
}
}
diff --git a/dll/win32/oleaut32/varformat.c b/dll/win32/oleaut32/varformat.c
index 696763e7ed..470ea4e01b 100644
--- a/dll/win32/oleaut32/varformat.c
+++ b/dll/win32/oleaut32/varformat.c
@@ -449,8 +449,7 @@ static inline const BYTE *VARIANT_GetNamedFormat(LPCWSTR lpszFormat)
LPCNAMED_FORMAT fmt;
key.name = lpszFormat;
- fmt = bsearch(&key, VARIANT_NamedFormats,
- sizeof(VARIANT_NamedFormats)/sizeof(NAMED_FORMAT),
+ fmt = bsearch(&key, VARIANT_NamedFormats, ARRAY_SIZE(VARIANT_NamedFormats),
sizeof(NAMED_FORMAT), FormatCompareFn);
return fmt ? fmt->format : NULL;
}
@@ -764,7 +763,7 @@ HRESULT WINAPI VarTokenizeFormatString(LPOLESTR lpszFormat, LPBYTE
rgbTok,
TRACE("time sep\n");
}
else if ((*pFormat == 'a' || *pFormat == 'A') &&
- !strncmpiW(pFormat, szAMPM, sizeof(szAMPM)/sizeof(WCHAR)))
+ !strncmpiW(pFormat, szAMPM, ARRAY_SIZE(szAMPM)))
{
/* Date formats: System AM/PM designation
* Other formats: Literal
@@ -772,8 +771,8 @@ HRESULT WINAPI VarTokenizeFormatString(LPOLESTR lpszFormat, LPBYTE
rgbTok,
*/
header->type = FMT_TYPE_DATE;
NEED_SPACE(sizeof(BYTE));
- pFormat += sizeof(szAMPM)/sizeof(WCHAR);
- if (!strncmpW(pFormat, szampm, sizeof(szampm)/sizeof(WCHAR)))
+ pFormat += ARRAY_SIZE(szAMPM);
+ if (!strncmpW(pFormat, szampm, ARRAY_SIZE(szampm)))
*pOut++ = FMT_DATE_AMPM_SYS2;
else
*pOut++ = FMT_DATE_AMPM_SYS1;
@@ -811,8 +810,7 @@ HRESULT WINAPI VarTokenizeFormatString(LPOLESTR lpszFormat, LPBYTE
rgbTok,
*pLastHours = *pLastHours + 2;
TRACE("A/P\n");
}
- else if (*pFormat == 'a' &&
- !strncmpW(pFormat, szamSlashpm, sizeof(szamSlashpm)/sizeof(WCHAR)))
+ else if (*pFormat == 'a' && !strncmpW(pFormat, szamSlashpm,
ARRAY_SIZE(szamSlashpm)))
{
/* Date formats: lowercase AM or PM designation
* Other formats: Literal
@@ -820,14 +818,13 @@ HRESULT WINAPI VarTokenizeFormatString(LPOLESTR lpszFormat, LPBYTE
rgbTok,
*/
header->type = FMT_TYPE_DATE;
NEED_SPACE(sizeof(BYTE));
- pFormat += sizeof(szamSlashpm)/sizeof(WCHAR);
+ pFormat += ARRAY_SIZE(szamSlashpm);
*pOut++ = FMT_DATE_AMPM_LOWER;
if (pLastHours)
*pLastHours = *pLastHours + 2;
TRACE("AM/PM\n");
}
- else if (*pFormat == 'A' &&
- !strncmpW(pFormat, szAMSlashPM, sizeof(szAMSlashPM)/sizeof(WCHAR)))
+ else if (*pFormat == 'A' && !strncmpW(pFormat, szAMSlashPM,
ARRAY_SIZE(szAMSlashPM)))
{
/* Date formats: Uppercase AM or PM designation
* Other formats: Literal
@@ -835,7 +832,7 @@ HRESULT WINAPI VarTokenizeFormatString(LPOLESTR lpszFormat, LPBYTE
rgbTok,
*/
header->type = FMT_TYPE_DATE;
NEED_SPACE(sizeof(BYTE));
- pFormat += sizeof(szAMSlashPM)/sizeof(WCHAR);
+ pFormat += ARRAY_SIZE(szAMSlashPM);
*pOut++ = FMT_DATE_AMPM_UPPER;
TRACE("AM/PM\n");
}
@@ -847,7 +844,7 @@ HRESULT WINAPI VarTokenizeFormatString(LPOLESTR lpszFormat, LPBYTE
rgbTok,
*/
header->type = FMT_TYPE_DATE;
NEED_SPACE(sizeof(BYTE));
- pFormat += sizeof(szAMSlashPM)/sizeof(WCHAR);
+ pFormat += ARRAY_SIZE(szAMSlashPM);
*pOut++ = FMT_DATE_GENERAL;
TRACE("gen date\n");
}
@@ -989,14 +986,14 @@ HRESULT WINAPI VarTokenizeFormatString(LPOLESTR lpszFormat, LPBYTE
rgbTok,
fmt_state &= ~FMT_STATE_OPEN_COPY;
}
else if ((*pFormat == 't' || *pFormat == 'T') &&
- !strncmpiW(pFormat, szTTTTT, sizeof(szTTTTT)/sizeof(WCHAR)))
+ !strncmpiW(pFormat, szTTTTT, ARRAY_SIZE(szTTTTT)))
{
/* Date formats: System time specifier
* Other formats: Literal
* Types the format if found
*/
header->type = FMT_TYPE_DATE;
- pFormat += sizeof(szTTTTT)/sizeof(WCHAR);
+ pFormat += ARRAY_SIZE(szTTTTT);
NEED_SPACE(sizeof(BYTE));
*pOut++ = FMT_DATE_TIME_SYS;
fmt_state &= ~FMT_STATE_OPEN_COPY;
@@ -1316,8 +1313,7 @@ static HRESULT VARIANT_FormatNumber(LPVARIANT pVarIn, LPOLESTR
lpszFormat,
if (numHeader->flags & FMT_FLAG_THOUSANDS)
{
- if (!GetLocaleInfoW(lcid, LOCALE_STHOUSAND, thousandSeparator,
- sizeof(thousandSeparator)/sizeof(WCHAR)))
+ if (!GetLocaleInfoW(lcid, LOCALE_STHOUSAND, thousandSeparator,
ARRAY_SIZE(thousandSeparator)))
{
thousandSeparator[0] = ',';
thousandSeparator[1] = 0;
@@ -1555,8 +1551,7 @@ VARIANT_FormatNumber_Bool:
}
if (localeValue)
{
- if (GetLocaleInfoW(lcid, localeValue, pBuff,
- sizeof(buff)/sizeof(WCHAR)-(pBuff-buff)))
+ if (GetLocaleInfoW(lcid, localeValue, pBuff, ARRAY_SIZE(buff)-(pBuff-buff)))
{
TRACE("added %s\n", debugstr_w(pBuff));
while (*pBuff)
@@ -1875,8 +1870,7 @@ static HRESULT VARIANT_FormatDate(LPVARIANT pVarIn, LPOLESTR
lpszFormat,
if (localeValue)
{
*pBuff = '\0';
- if (GetLocaleInfoW(lcid, localeValue, pBuff,
- sizeof(buff)/sizeof(WCHAR)-(pBuff-buff)))
+ if (GetLocaleInfoW(lcid, localeValue, pBuff, ARRAY_SIZE(buff)-(pBuff-buff)))
{
TRACE("added %s\n", debugstr_w(pBuff));
while (*pBuff)
@@ -1892,9 +1886,8 @@ static HRESULT VARIANT_FormatDate(LPVARIANT pVarIn, LPOLESTR
lpszFormat,
{
WCHAR fmt_buff[80];
- if (!GetLocaleInfoW(lcid, dwFmt, fmt_buff, sizeof(fmt_buff)/sizeof(WCHAR)) ||
- !get_date_format(lcid, 0, &udate.st, fmt_buff, pBuff,
- sizeof(buff)/sizeof(WCHAR)-(pBuff-buff)))
+ if (!GetLocaleInfoW(lcid, dwFmt, fmt_buff, ARRAY_SIZE(fmt_buff)) ||
+ !get_date_format(lcid, 0, &udate.st, fmt_buff, pBuff,
ARRAY_SIZE(buff)-(pBuff-buff)))
{
hRes = E_INVALIDARG;
goto VARIANT_FormatDate_Exit;
@@ -2293,8 +2286,7 @@ HRESULT WINAPI VarFormatNumber(LPVARIANT pVarIn, INT nDigits, INT
nLeading, INT
{
WCHAR grouping[16];
grouping[2] = '\0';
- GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SDECIMAL, grouping,
- sizeof(grouping)/sizeof(WCHAR));
+ GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SDECIMAL, grouping,
ARRAY_SIZE(grouping));
numfmt.Grouping = grouping[2] == '2' ? 32 : grouping[0] - '0';
}
else if (nGrouping == -1)
@@ -2310,14 +2302,11 @@ HRESULT WINAPI VarFormatNumber(LPVARIANT pVarIn, INT nDigits, INT
nLeading, INT
numfmt.NegativeOrder = 1; /* 1 = "-xxx" */
numfmt.lpDecimalSep = decimal;
- GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SDECIMAL, decimal,
- sizeof(decimal)/sizeof(WCHAR));
+ GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SDECIMAL, decimal, ARRAY_SIZE(decimal));
numfmt.lpThousandSep = thousands;
- GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_STHOUSAND, thousands,
- sizeof(thousands)/sizeof(WCHAR));
+ GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_STHOUSAND, thousands,
ARRAY_SIZE(thousands));
- if (GetNumberFormatW(LOCALE_USER_DEFAULT, 0, V_BSTR(&vStr), &numfmt,
- buff, sizeof(buff)/sizeof(WCHAR)))
+ if (GetNumberFormatW(LOCALE_USER_DEFAULT, 0, V_BSTR(&vStr), &numfmt, buff,
ARRAY_SIZE(buff)))
{
*pbstrOut = SysAllocString(buff);
if (!*pbstrOut)
@@ -2473,8 +2462,7 @@ HRESULT WINAPI VarFormatCurrency(LPVARIANT pVarIn, INT nDigits, INT
nLeading,
{
WCHAR grouping[16];
grouping[2] = '\0';
- GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SDECIMAL, grouping,
- sizeof(grouping)/sizeof(WCHAR));
+ GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SDECIMAL, grouping,
ARRAY_SIZE(grouping));
numfmt.Grouping = grouping[2] == '2' ? 32 : grouping[0] - '0';
}
else if (nGrouping == -1)
@@ -2492,18 +2480,14 @@ HRESULT WINAPI VarFormatCurrency(LPVARIANT pVarIn, INT nDigits,
INT nLeading,
GETLOCALENUMBER(LOCALE_ICURRENCY, PositiveOrder);
numfmt.lpDecimalSep = decimal;
- GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SDECIMAL, decimal,
- sizeof(decimal)/sizeof(WCHAR));
+ GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SDECIMAL, decimal, ARRAY_SIZE(decimal));
numfmt.lpThousandSep = thousands;
- GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SDECIMAL, thousands,
- sizeof(thousands)/sizeof(WCHAR));
+ GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SDECIMAL, thousands,
ARRAY_SIZE(thousands));
numfmt.lpCurrencySymbol = currency;
- GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SDECIMAL, currency,
- sizeof(currency)/sizeof(WCHAR));
+ GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SDECIMAL, currency,
ARRAY_SIZE(currency));
/* use NLS as per VarFormatNumber() */
- if (GetCurrencyFormatW(LOCALE_USER_DEFAULT, 0, V_BSTR(&vStr), &numfmt,
- buff, sizeof(buff)/sizeof(WCHAR)))
+ if (GetCurrencyFormatW(LOCALE_USER_DEFAULT, 0, V_BSTR(&vStr), &numfmt, buff,
ARRAY_SIZE(buff)))
{
*pbstrOut = SysAllocString(buff);
if (!*pbstrOut)
diff --git a/dll/win32/oleaut32/variant.c b/dll/win32/oleaut32/variant.c
index b9cf4b0a00..fcbef5317f 100644
--- a/dll/win32/oleaut32/variant.c
+++ b/dll/win32/oleaut32/variant.c
@@ -648,7 +648,7 @@ HRESULT VARIANT_ClearInd(VARIANTARG *pVarg)
* Success: S_OK. Any previous value in pVarg is freed and its type is set to VT_EMPTY.
* Failure: DISP_E_BADVARTYPE, if the variant is not a valid variant type.
*/
-HRESULT WINAPI VariantClear(VARIANTARG* pVarg)
+HRESULT WINAPI DECLSPEC_HOTPATCH VariantClear(VARIANTARG* pVarg)
{
HRESULT hres;
@@ -962,8 +962,8 @@ VariantCopyInd_Return:
* The LCID used for the conversion is LOCALE_USER_DEFAULT.
* See VariantChangeTypeEx.
*/
-HRESULT WINAPI VariantChangeType(VARIANTARG* pvargDest, VARIANTARG* pvargSrc,
- USHORT wFlags, VARTYPE vt)
+HRESULT WINAPI DECLSPEC_HOTPATCH VariantChangeType(VARIANTARG* pvargDest, VARIANTARG*
pvargSrc,
+ USHORT wFlags, VARTYPE vt)
{
return VariantChangeTypeEx( pvargDest, pvargSrc, LOCALE_USER_DEFAULT, wFlags, vt );
}
@@ -1549,7 +1549,7 @@ static void VARIANT_GetLocalisedNumberChars(VARIANT_NUMBER_CHARS
*lpChars, LCID
/* Local currency symbols are often 2 characters */
lpChars->cCurrencyLocal2 = '\0';
- switch(GetLocaleInfoW(lcid, lctype|LOCALE_SCURRENCY, buff,
sizeof(buff)/sizeof(WCHAR)))
+ switch(GetLocaleInfoW(lcid, lctype|LOCALE_SCURRENCY, buff, ARRAY_SIZE(buff)))
{
case 3: lpChars->cCurrencyLocal2 = buff[1]; /* Fall through */
case 2: lpChars->cCurrencyLocal = buff[0];
@@ -1610,7 +1610,7 @@ HRESULT WINAPI VarParseNumFromStr(OLECHAR *lpszStr, LCID lcid, ULONG
dwFlags,
VARIANT_NUMBER_CHARS chars;
BYTE rgbTmp[1024];
DWORD dwState = B_EXPONENT_START|B_INEXACT_ZEROS;
- int iMaxDigits = sizeof(rgbTmp) / sizeof(BYTE);
+ int iMaxDigits = ARRAY_SIZE(rgbTmp);
int cchUsed = 0;
TRACE("(%s,%d,0x%08x,%p,%p)\n", debugstr_w(lpszStr), lcid, dwFlags, pNumprs,
rgbDig);
@@ -5134,7 +5134,21 @@ HRESULT WINAPI VarRound(LPVARIANT pVarIn, int deci, LPVARIANT
pVarOut)
}
V_VT(pVarOut) = V_VT(pVarIn);
break;
+ case VT_DECIMAL:
+ {
+ double dbl;
+ VarR8FromDec(&V_DECIMAL(pVarIn), &dbl);
+
+ if (dbl>0.0f)
+ dbl = floor(dbl*pow(10,deci)+0.5);
+ else
+ dbl = ceil(dbl*pow(10,deci)-0.5);
+
+ V_VT(pVarOut)=VT_DECIMAL;
+ VarDecFromR8(dbl, &V_DECIMAL(pVarOut));
+ break;
+ }
/* cases we don't know yet */
default:
FIXME("unimplemented part, V_VT(pVarIn) == 0x%X, deci == %d\n",
diff --git a/dll/win32/oleaut32/vartype.c b/dll/win32/oleaut32/vartype.c
index 9e271be5a2..067d515e34 100644
--- a/dll/win32/oleaut32/vartype.c
+++ b/dll/win32/oleaut32/vartype.c
@@ -95,7 +95,7 @@ static HRESULT VARIANT_NumberFromBstr(OLECHAR* pStrIn, LCID lcid, ULONG
ulFlags,
BYTE rgb[1024];
/* Use VarParseNumFromStr/VarNumFromParseNum as MSDN indicates */
- np.cDig = sizeof(rgb) / sizeof(BYTE);
+ np.cDig = ARRAY_SIZE(rgb);
np.dwInFlags = NUMPRS_STD;
hRet = VarParseNumFromStr(pStrIn, lcid, ulFlags, &np, rgb);
@@ -3781,7 +3781,7 @@ HRESULT WINAPI VarCyFromUI8(ULONG64 ullIn, CY* pCyOut)
* Success: S_OK.
* Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
*/
-HRESULT WINAPI VarCyAdd(const CY cyLeft, const CY cyRight, CY* pCyOut)
+HRESULT WINAPI VarCyAdd(CY cyLeft, CY cyRight, CY* pCyOut)
{
double l,r;
_VarR8FromCy(cyLeft, &l);
@@ -3804,7 +3804,7 @@ HRESULT WINAPI VarCyAdd(const CY cyLeft, const CY cyRight, CY*
pCyOut)
* Success: S_OK.
* Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
*/
-HRESULT WINAPI VarCyMul(const CY cyLeft, CY cyRight, CY* pCyOut)
+HRESULT WINAPI VarCyMul(CY cyLeft, CY cyRight, CY* pCyOut)
{
double l,r;
_VarR8FromCy(cyLeft, &l);
@@ -3827,7 +3827,7 @@ HRESULT WINAPI VarCyMul(const CY cyLeft, CY cyRight, CY* pCyOut)
* Success: S_OK.
* Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
*/
-HRESULT WINAPI VarCyMulI4(const CY cyLeft, LONG lRight, CY* pCyOut)
+HRESULT WINAPI VarCyMulI4(CY cyLeft, LONG lRight, CY* pCyOut)
{
double d;
@@ -3850,7 +3850,7 @@ HRESULT WINAPI VarCyMulI4(const CY cyLeft, LONG lRight, CY* pCyOut)
* Success: S_OK.
* Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
*/
-HRESULT WINAPI VarCySub(const CY cyLeft, const CY cyRight, CY* pCyOut)
+HRESULT WINAPI VarCySub(CY cyLeft, CY cyRight, CY* pCyOut)
{
double l,r;
_VarR8FromCy(cyLeft, &l);
@@ -3872,7 +3872,7 @@ HRESULT WINAPI VarCySub(const CY cyLeft, const CY cyRight, CY*
pCyOut)
* Success: S_OK. pCyOut contains the absolute value.
* Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
*/
-HRESULT WINAPI VarCyAbs(const CY cyIn, CY* pCyOut)
+HRESULT WINAPI VarCyAbs(CY cyIn, CY* pCyOut)
{
if (cyIn.s.Hi == (int)0x80000000 && !cyIn.s.Lo)
return DISP_E_OVERFLOW;
@@ -3898,7 +3898,7 @@ HRESULT WINAPI VarCyAbs(const CY cyIn, CY* pCyOut)
* - The difference between this function and VarCyInt() is that VarCyInt() rounds
* negative numbers away from 0, while this function rounds them towards zero.
*/
-HRESULT WINAPI VarCyFix(const CY cyIn, CY* pCyOut)
+HRESULT WINAPI VarCyFix(CY cyIn, CY* pCyOut)
{
pCyOut->int64 = cyIn.int64 / CY_MULTIPLIER;
pCyOut->int64 *= CY_MULTIPLIER;
@@ -3922,7 +3922,7 @@ HRESULT WINAPI VarCyFix(const CY cyIn, CY* pCyOut)
* - The difference between this function and VarCyFix() is that VarCyFix() rounds
* negative numbers towards 0, while this function rounds them away from zero.
*/
-HRESULT WINAPI VarCyInt(const CY cyIn, CY* pCyOut)
+HRESULT WINAPI VarCyInt(CY cyIn, CY* pCyOut)
{
pCyOut->int64 = cyIn.int64 / CY_MULTIPLIER;
pCyOut->int64 *= CY_MULTIPLIER;
@@ -3947,7 +3947,7 @@ HRESULT WINAPI VarCyInt(const CY cyIn, CY* pCyOut)
* Success: S_OK.
* Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
*/
-HRESULT WINAPI VarCyNeg(const CY cyIn, CY* pCyOut)
+HRESULT WINAPI VarCyNeg(CY cyIn, CY* pCyOut)
{
if (cyIn.s.Hi == (int)0x80000000 && !cyIn.s.Lo)
return DISP_E_OVERFLOW;
@@ -3970,7 +3970,7 @@ HRESULT WINAPI VarCyNeg(const CY cyIn, CY* pCyOut)
* Success: S_OK.
* Failure: E_INVALIDARG, if cDecimals is less than 0.
*/
-HRESULT WINAPI VarCyRound(const CY cyIn, int cDecimals, CY* pCyOut)
+HRESULT WINAPI VarCyRound(CY cyIn, int cDecimals, CY* pCyOut)
{
if (cDecimals < 0)
return E_INVALIDARG;
@@ -4008,7 +4008,7 @@ HRESULT WINAPI VarCyRound(const CY cyIn, int cDecimals, CY* pCyOut)
* compare is less, equal or greater than source respectively.
* Failure: DISP_E_OVERFLOW, if overflow occurs during the comparison
*/
-HRESULT WINAPI VarCyCmp(const CY cyLeft, const CY cyRight)
+HRESULT WINAPI VarCyCmp(CY cyLeft, CY cyRight)
{
HRESULT hRet;
CY result;
@@ -4042,7 +4042,7 @@ HRESULT WINAPI VarCyCmp(const CY cyLeft, const CY cyRight)
* less than, equal to or greater than cyLeft respectively.
* Failure: DISP_E_OVERFLOW, if overflow occurs during the comparison
*/
-HRESULT WINAPI VarCyCmpR8(const CY cyLeft, double dblRight)
+HRESULT WINAPI VarCyCmpR8(CY cyLeft, double dblRight)
{
HRESULT hRet;
CY cyRight;
@@ -4069,7 +4069,7 @@ HRESULT WINAPI VarCyCmpR8(const CY cyLeft, double dblRight)
* Success: S_OK.
* Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
*/
-HRESULT WINAPI VarCyMulI8(const CY cyLeft, LONG64 llRight, CY* pCyOut)
+HRESULT WINAPI VarCyMulI8(CY cyLeft, LONG64 llRight, CY* pCyOut)
{
double d;
@@ -4496,15 +4496,15 @@ static HRESULT VARIANT_DecScale(const DECIMAL** ppDecLeft,
di.scale -= i;
remainder = 0;
- while (i-- > 0 && !VARIANT_int_iszero(di.bitsnum,
sizeof(di.bitsnum)/sizeof(DWORD)))
+ while (i-- > 0 && !VARIANT_int_iszero(di.bitsnum, ARRAY_SIZE(di.bitsnum)))
{
- remainder = VARIANT_int_divbychar(di.bitsnum, sizeof(di.bitsnum)/sizeof(DWORD), 10);
+ remainder = VARIANT_int_divbychar(di.bitsnum, ARRAY_SIZE(di.bitsnum), 10);
if (remainder > 0) WARN("losing significant digits (remainder %u)...\n",
remainder);
}
/* round up the result - native oleaut32 does this */
if (remainder >= 5) {
- for (remainder = 1, i = 0; i < sizeof(di.bitsnum)/sizeof(DWORD) &&
remainder; i++) {
+ for (remainder = 1, i = 0; i < ARRAY_SIZE(di.bitsnum) && remainder; i++)
{
ULONGLONG digit = di.bitsnum[i] + 1;
remainder = (digit > 0xFFFFFFFF) ? 1 : 0;
di.bitsnum[i] = digit & 0xFFFFFFFF;
@@ -4743,7 +4743,7 @@ static int VARIANT_DI_mul(const VARIANT_DI * a, const VARIANT_DI *
b, VARIANT_DI
memset(running, 0, sizeof(running));
/* count number of leading zero-bytes in operand A */
- for (mulstart = sizeof(a->bitsnum)/sizeof(DWORD) - 1; mulstart >= 0 &&
!a->bitsnum[mulstart]; mulstart--);
+ for (mulstart = ARRAY_SIZE(a->bitsnum) - 1; mulstart >= 0 &&
!a->bitsnum[mulstart]; mulstart--);
if (mulstart < 0) {
/* result is 0, because operand A is 0 */
result->scale = 0;
@@ -4757,7 +4757,7 @@ static int VARIANT_DI_mul(const VARIANT_DI * a, const VARIANT_DI *
b, VARIANT_DI
ULONG iOverflowMul;
int iB;
- for (iOverflowMul = 0, iB = 0; iB < sizeof(b->bitsnum)/sizeof(DWORD);
iB++) {
+ for (iOverflowMul = 0, iB = 0; iB < ARRAY_SIZE(b->bitsnum); iB++) {
ULONG iRV;
int iR;
@@ -4789,11 +4789,10 @@ static int VARIANT_DI_mul(const VARIANT_DI * a, const VARIANT_DI *
b, VARIANT_DI
This operation *will* lose significant digits of the result because
all the factors of 10 were consumed by the previous operation.
*/
- while (result->scale > 0 && !VARIANT_int_iszero(
- running + sizeof(result->bitsnum) / sizeof(DWORD),
- (sizeof(running) - sizeof(result->bitsnum)) / sizeof(DWORD))) {
-
- remainder = VARIANT_int_divbychar(running, sizeof(running) / sizeof(DWORD),
10);
+ while (result->scale > 0 && !VARIANT_int_iszero(running +
ARRAY_SIZE(result->bitsnum),
+ ARRAY_SIZE(running) - ARRAY_SIZE(result->bitsnum))) {
+
+ remainder = VARIANT_int_divbychar(running, ARRAY_SIZE(running), 10);
if (remainder > 0) WARN("losing significant digits (remainder
%u)...\n", remainder);
result->scale--;
}
@@ -4801,7 +4800,7 @@ static int VARIANT_DI_mul(const VARIANT_DI * a, const VARIANT_DI *
b, VARIANT_DI
/* round up the result - native oleaut32 does this */
if (remainder >= 5) {
unsigned int i;
- for (remainder = 1, i = 0; i < sizeof(running)/sizeof(DWORD) &&
remainder; i++) {
+ for (remainder = 1, i = 0; i < ARRAY_SIZE(running) && remainder;
i++) {
ULONGLONG digit = running[i] + 1;
remainder = (digit > 0xFFFFFFFF) ? 1 : 0;
running[i] = digit & 0xFFFFFFFF;
@@ -4811,9 +4810,8 @@ static int VARIANT_DI_mul(const VARIANT_DI * a, const VARIANT_DI *
b, VARIANT_DI
/* Signal overflow if scale == 0 and 256-bit result still overflows,
and copy result bits into result structure
*/
- r_overflow = !VARIANT_int_iszero(
- running + sizeof(result->bitsnum)/sizeof(DWORD),
- (sizeof(running) - sizeof(result->bitsnum))/sizeof(DWORD));
+ r_overflow = !VARIANT_int_iszero(running + ARRAY_SIZE(result->bitsnum),
+ ARRAY_SIZE(running) - ARRAY_SIZE(result->bitsnum));
memcpy(result->bitsnum, running, sizeof(result->bitsnum));
}
return r_overflow;
@@ -4831,7 +4829,7 @@ static BOOL VARIANT_DI_tostringW(const VARIANT_DI * a, WCHAR * s,
unsigned int n
unsigned int i;
/* place negative sign */
- if (!VARIANT_int_iszero(a->bitsnum, sizeof(a->bitsnum) / sizeof(DWORD))
&& a->sign) {
+ if (!VARIANT_int_iszero(a->bitsnum, ARRAY_SIZE(a->bitsnum)) &&
a->sign) {
if (n > 0) {
*s++ = '-';
n--;
@@ -4849,8 +4847,8 @@ static BOOL VARIANT_DI_tostringW(const VARIANT_DI * a, WCHAR * s,
unsigned int n
i = 0;
memcpy(quotient, a->bitsnum, sizeof(a->bitsnum));
- while (!overflow && !VARIANT_int_iszero(quotient, sizeof(quotient) /
sizeof(DWORD))) {
- remainder = VARIANT_int_divbychar(quotient, sizeof(quotient) / sizeof(DWORD),
10);
+ while (!overflow && !VARIANT_int_iszero(quotient, ARRAY_SIZE(quotient))) {
+ remainder = VARIANT_int_divbychar(quotient, ARRAY_SIZE(quotient), 10);
if (i + 2 > n) {
overflow = TRUE;
} else {
@@ -4859,7 +4857,7 @@ static BOOL VARIANT_DI_tostringW(const VARIANT_DI * a, WCHAR * s,
unsigned int n
}
}
- if (!overflow && !VARIANT_int_iszero(a->bitsnum, sizeof(a->bitsnum) /
sizeof(DWORD))) {
+ if (!overflow && !VARIANT_int_iszero(a->bitsnum,
ARRAY_SIZE(a->bitsnum))) {
/* reverse order of digits */
WCHAR * x = s; WCHAR * y = s + i - 1;
@@ -5175,10 +5173,10 @@ static HRESULT VARIANT_DI_div(const VARIANT_DI * dividend, const
VARIANT_DI * di
{
HRESULT r_overflow = S_OK;
- if (VARIANT_int_iszero(divisor->bitsnum,
sizeof(divisor->bitsnum)/sizeof(DWORD))) {
+ if (VARIANT_int_iszero(divisor->bitsnum, ARRAY_SIZE(divisor->bitsnum))) {
/* division by 0 */
r_overflow = DISP_E_DIVBYZERO;
- } else if (VARIANT_int_iszero(dividend->bitsnum,
sizeof(dividend->bitsnum)/sizeof(DWORD))) {
+ } else if (VARIANT_int_iszero(dividend->bitsnum,
ARRAY_SIZE(dividend->bitsnum))) {
VARIANT_DI_clear(quotient);
} else {
int quotientscale, remainderscale, tempquotientscale;
@@ -5208,17 +5206,14 @@ static HRESULT VARIANT_DI_div(const VARIANT_DI * dividend, const
VARIANT_DI * di
memset(remainderplusquotient, 0, sizeof(remainderplusquotient));
memcpy(remainderplusquotient, dividend->bitsnum,
sizeof(dividend->bitsnum));
do {
- VARIANT_int_div(
- remainderplusquotient, 4,
- divisor->bitsnum, sizeof(divisor->bitsnum)/sizeof(DWORD));
- underflow = VARIANT_int_addlossy(
- quotient->bitsnum, "ientscale, sizeof(quotient->bitsnum) /
sizeof(DWORD),
- remainderplusquotient, &tempquotientscale, 4);
+ VARIANT_int_div(remainderplusquotient, 4, divisor->bitsnum,
ARRAY_SIZE(divisor->bitsnum));
+ underflow = VARIANT_int_addlossy( quotient->bitsnum, "ientscale,
+ ARRAY_SIZE(quotient->bitsnum), remainderplusquotient,
&tempquotientscale, 4);
if (round_remainder) {
if(remainderplusquotient[4] >= 5){
unsigned int i;
unsigned char remainder = 1;
- for (i = 0; i < sizeof(quotient->bitsnum) / sizeof(DWORD)
&& remainder; i++) {
+ for (i = 0; i < ARRAY_SIZE(quotient->bitsnum) &&
remainder; i++) {
ULONGLONG digit = quotient->bitsnum[i] + 1;
remainder = (digit > 0xFFFFFFFF) ? 1 : 0;
quotient->bitsnum[i] = digit & 0xFFFFFFFF;
@@ -5239,9 +5234,9 @@ static HRESULT VARIANT_DI_div(const VARIANT_DI * dividend, const
VARIANT_DI * di
while (r_overflow == S_OK && quotientscale < 0) {
memset(remainderplusquotient, 0, sizeof(remainderplusquotient));
memcpy(remainderplusquotient, quotient->bitsnum,
sizeof(quotient->bitsnum));
- VARIANT_int_mulbychar(remainderplusquotient,
sizeof(remainderplusquotient)/sizeof(DWORD), 10);
- if (VARIANT_int_iszero(remainderplusquotient +
sizeof(quotient->bitsnum)/sizeof(DWORD),
- (sizeof(remainderplusquotient) -
sizeof(quotient->bitsnum))/sizeof(DWORD))) {
+ VARIANT_int_mulbychar(remainderplusquotient,
ARRAY_SIZE(remainderplusquotient), 10);
+ if (VARIANT_int_iszero(remainderplusquotient +
ARRAY_SIZE(quotient->bitsnum),
+ ARRAY_SIZE(remainderplusquotient) - ARRAY_SIZE(quotient->bitsnum))) {
quotientscale++;
memcpy(quotient->bitsnum, remainderplusquotient,
sizeof(quotient->bitsnum));
} else r_overflow = DISP_E_OVERFLOW;
@@ -5562,9 +5557,9 @@ static HRESULT VARIANT_do_division(const DECIMAL *pDecLeft, const
DECIMAL *pDecR
WARN("result scale is %u, scaling (with loss of significant
digits)...\n",
di_result.scale);
while (di_result.scale > DEC_MAX_SCALE &&
- !VARIANT_int_iszero(di_result.bitsnum, sizeof(di_result.bitsnum) /
sizeof(DWORD)))
+ !VARIANT_int_iszero(di_result.bitsnum, ARRAY_SIZE(di_result.bitsnum)))
{
- remainder = VARIANT_int_divbychar(di_result.bitsnum,
sizeof(di_result.bitsnum) / sizeof(DWORD), 10);
+ remainder = VARIANT_int_divbychar(di_result.bitsnum,
ARRAY_SIZE(di_result.bitsnum), 10);
di_result.scale--;
}
if (di_result.scale > DEC_MAX_SCALE)
@@ -5576,7 +5571,7 @@ static HRESULT VARIANT_do_division(const DECIMAL *pDecLeft, const
DECIMAL *pDecR
else if (remainder >= 5) /* round up result - native oleaut32 does this */
{
unsigned int i;
- for (remainder = 1, i = 0; i < sizeof(di_result.bitsnum) / sizeof(DWORD)
&& remainder; i++) {
+ for (remainder = 1, i = 0; i < ARRAY_SIZE(di_result.bitsnum) &&
remainder; i++) {
ULONGLONG digit = di_result.bitsnum[i] + 1;
remainder = (digit > 0xFFFFFFFF) ? 1 : 0;
di_result.bitsnum[i] = digit & 0xFFFFFFFF;
@@ -5648,9 +5643,9 @@ HRESULT WINAPI VarDecMul(const DECIMAL* pDecLeft, const DECIMAL*
pDecRight, DECI
WARN("result scale is %u, scaling (with loss of significant
digits)...\n",
di_result.scale);
while (di_result.scale > DEC_MAX_SCALE &&
- !VARIANT_int_iszero(di_result.bitsnum,
sizeof(di_result.bitsnum)/sizeof(DWORD)))
+ !VARIANT_int_iszero(di_result.bitsnum, ARRAY_SIZE(di_result.bitsnum)))
{
- VARIANT_int_divbychar(di_result.bitsnum, sizeof(di_result.bitsnum)/sizeof(DWORD),
10);
+ VARIANT_int_divbychar(di_result.bitsnum, ARRAY_SIZE(di_result.bitsnum), 10);
di_result.scale--;
}
if (di_result.scale > DEC_MAX_SCALE)
@@ -6357,9 +6352,8 @@ static BSTR VARIANT_MakeBstr(LCID lcid, DWORD dwFlags, WCHAR
*szOut)
{
/* Format the number for the locale */
szConverted[0] = '\0';
- GetNumberFormatW(lcid,
- dwFlags & LOCALE_NOUSEROVERRIDE,
- szOut, NULL, szConverted, sizeof(szConverted)/sizeof(WCHAR));
+ GetNumberFormatW(lcid, dwFlags & LOCALE_NOUSEROVERRIDE,
+ szOut, NULL, szConverted, ARRAY_SIZE(szConverted));
szOut = szConverted;
}
return SysAllocStringByteLen((LPCSTR)szOut, strlenW(szOut) * sizeof(WCHAR));
@@ -6368,7 +6362,7 @@ static BSTR VARIANT_MakeBstr(LCID lcid, DWORD dwFlags, WCHAR
*szOut)
/* Create a (possibly localised) BSTR from a UI8 and sign */
static HRESULT VARIANT_BstrFromUInt(ULONG64 ulVal, LCID lcid, DWORD dwFlags, BSTR
*pbstrOut)
{
- WCHAR szBuff[64], *szOut = szBuff + sizeof(szBuff)/sizeof(WCHAR) - 1;
+ WCHAR szBuff[64], *szOut = szBuff + ARRAY_SIZE(szBuff) - 1;
if (!pbstrOut)
return E_INVALIDARG;
@@ -6453,7 +6447,7 @@ HRESULT WINAPI VarBstrFromI4(LONG lIn, LCID lcid, ULONG dwFlags,
BSTR* pbstrOut)
if (lIn < 0)
{
- ul64 = (ULONG)-lIn;
+ ul64 = -(LONG64)lIn;
dwFlags |= VAR_NEGATIVE;
}
return VARIANT_BstrFromUInt(ul64, lcid, dwFlags, pbstrOut);
@@ -6472,7 +6466,7 @@ static BSTR VARIANT_BstrReplaceDecimal(const WCHAR * buff, LCID
lcid, ULONG dwFl
appropriate NUMBERFMTW structure to do the job via GetNumberFormatW().
*/
GetLocaleInfoW(lcid, LOCALE_SDECIMAL | (dwFlags & LOCALE_NOUSEROVERRIDE),
- lpDecimalSep, sizeof(lpDecimalSep) / sizeof(WCHAR));
+ lpDecimalSep, ARRAY_SIZE(lpDecimalSep));
if (lpDecimalSep[0] == '.' && lpDecimalSep[1] == '\0')
{
/* locale is compatible with English - return original string */
@@ -6497,7 +6491,7 @@ static BSTR VARIANT_BstrReplaceDecimal(const WCHAR * buff, LCID
lcid, ULONG dwFl
if (p) minFormat.NumDigits = strlenW(p + 1);
numbuff[0] = '\0';
- if (!GetNumberFormatW(lcid, 0, buff, &minFormat, numbuff, sizeof(numbuff) /
sizeof(WCHAR)))
+ if (!GetNumberFormatW(lcid, 0, buff, &minFormat, numbuff, ARRAY_SIZE(numbuff)))
{
WARN("GetNumberFormatW() failed, returning raw number string
instead\n");
bstrOut = SysAllocString(buff);
@@ -6528,7 +6522,7 @@ static HRESULT VARIANT_BstrFromReal(DOUBLE dblIn, LCID lcid, ULONG
dwFlags,
*/
if (buff[0] == '-')
{
- const WCHAR szAccept[] = {'0', '.', '\0'};
+ static const WCHAR szAccept[] = {'0', '.', '\0'};
if (strlenW(buff + 1) == strspnW(buff + 1, szAccept))
{ buff[0] = '0'; buff[1] = '\0'; }
}
@@ -6541,7 +6535,7 @@ static HRESULT VARIANT_BstrFromReal(DOUBLE dblIn, LCID lcid, ULONG
dwFlags,
/* Format the number for the locale */
numbuff[0] = '\0';
GetNumberFormatW(lcid, dwFlags & LOCALE_NOUSEROVERRIDE,
- buff, NULL, numbuff, sizeof(numbuff) / sizeof(WCHAR));
+ buff, NULL, numbuff, ARRAY_SIZE(numbuff));
TRACE("created NLS string %s\n", debugstr_w(numbuff));
*pbstrOut = SysAllocString(numbuff);
}
@@ -6632,7 +6626,7 @@ HRESULT WINAPI VarBstrFromCy(CY cyIn, LCID lcid, ULONG dwFlags, BSTR
*pbstrOut)
VARIANT_int_add(decVal.bitsnum, 3, &one, 1);
}
decVal.bitsnum[2] = 0;
- VARIANT_DI_tostringW(&decVal, buff, sizeof(buff)/sizeof(buff[0]));
+ VARIANT_DI_tostringW(&decVal, buff, ARRAY_SIZE(buff));
if (dwFlags & LOCALE_USE_NLS)
{
@@ -6641,7 +6635,7 @@ HRESULT WINAPI VarBstrFromCy(CY cyIn, LCID lcid, ULONG dwFlags, BSTR
*pbstrOut)
/* Format the currency for the locale */
cybuff[0] = '\0';
GetCurrencyFormatW(lcid, dwFlags & LOCALE_NOUSEROVERRIDE,
- buff, NULL, cybuff, sizeof(cybuff) / sizeof(WCHAR));
+ buff, NULL, cybuff, ARRAY_SIZE(cybuff));
*pbstrOut = SysAllocString(cybuff);
}
else
@@ -6814,8 +6808,8 @@ HRESULT WINAPI VarBstrFromDate(DATE dateIn, LCID lcid, ULONG
dwFlags, BSTR* pbst
if (dwFlags & VAR_TIMEVALUEONLY)
date[0] = '\0';
else
- if (!GetLocaleInfoW(lcid, LOCALE_SSHORTDATE, fmt_buff,
sizeof(fmt_buff)/sizeof(WCHAR)) ||
- !get_date_format(lcid, dwFlags, &st, fmt_buff, date,
sizeof(date)/sizeof(WCHAR)))
+ if (!GetLocaleInfoW(lcid, LOCALE_SSHORTDATE, fmt_buff, ARRAY_SIZE(fmt_buff)) ||
+ !get_date_format(lcid, dwFlags, &st, fmt_buff, date, ARRAY_SIZE(date)))
return E_INVALIDARG;
if (!(dwFlags & VAR_DATEVALUEONLY))
@@ -6823,8 +6817,7 @@ HRESULT WINAPI VarBstrFromDate(DATE dateIn, LCID lcid, ULONG
dwFlags, BSTR* pbst
time = date + strlenW(date);
if (time != date)
*time++ = ' ';
- if (!GetTimeFormatW(lcid, dwFormatFlags, &st, NULL, time,
- sizeof(date)/sizeof(WCHAR)-(time-date)))
+ if (!GetTimeFormatW(lcid, dwFormatFlags, &st, NULL, time,
ARRAY_SIZE(date)-(time-date)))
return E_INVALIDARG;
}
@@ -7012,7 +7005,7 @@ HRESULT WINAPI VarBstrFromDec(DECIMAL* pDecIn, LCID lcid, ULONG
dwFlags, BSTR* p
/* Format the number for the locale */
numbuff[0] = '\0';
GetNumberFormatW(lcid, dwFlags & LOCALE_NOUSEROVERRIDE,
- buff, NULL, numbuff, sizeof(numbuff) / sizeof(WCHAR));
+ buff, NULL, numbuff, ARRAY_SIZE(numbuff));
TRACE("created NLS string %s\n", debugstr_w(numbuff));
*pbstrOut = SysAllocString(numbuff);
}
@@ -7625,7 +7618,7 @@ HRESULT WINAPI VarDateFromStr(OLECHAR* strIn, LCID lcid, ULONG
dwFlags, DATE* pd
1,2,3,4,5,6,7,8,9,10,11,12,13
};
unsigned int i;
- BSTR tokens[sizeof(ParseDateTokens)/sizeof(ParseDateTokens[0])];
+ BSTR tokens[ARRAY_SIZE(ParseDateTokens)];
DATEPARSE dp;
DWORD dwDateSeps = 0, iDate = 0;
HRESULT hRet = S_OK;
@@ -7648,7 +7641,7 @@ HRESULT WINAPI VarDateFromStr(OLECHAR* strIn, LCID lcid, ULONG
dwFlags, DATE* pd
TRACE("iDate is %d\n", iDate);
/* Get the month/day/am/pm tokens for this locale */
- for (i = 0; i < sizeof(tokens)/sizeof(tokens[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(tokens); i++)
{
WCHAR buff[128];
LCTYPE lctype = ParseDateTokens[i] | (dwFlags & LOCALE_NOUSEROVERRIDE);
@@ -7657,7 +7650,7 @@ HRESULT WINAPI VarDateFromStr(OLECHAR* strIn, LCID lcid, ULONG
dwFlags, DATE* pd
* GetAltMonthNames(). We should really cache these strings too.
*/
buff[0] = '\0';
- GetLocaleInfoW(lcid, lctype, buff, sizeof(buff)/sizeof(WCHAR));
+ GetLocaleInfoW(lcid, lctype, buff, ARRAY_SIZE(buff));
tokens[i] = SysAllocString(buff);
TRACE("token %d is %s\n", i, debugstr_w(tokens[i]));
}
@@ -7680,7 +7673,7 @@ HRESULT WINAPI VarDateFromStr(OLECHAR* strIn, LCID lcid, ULONG
dwFlags, DATE* pd
{
BOOL bFound = FALSE;
- for (i = 0; i < sizeof(tokens)/sizeof(tokens[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(tokens); i++)
{
DWORD dwLen = strlenW(tokens[i]);
if (dwLen && !strncmpiW(strIn, tokens[i], dwLen))
@@ -7940,7 +7933,7 @@ HRESULT WINAPI VarDateFromStr(OLECHAR* strIn, LCID lcid, ULONG
dwFlags, DATE* pd
}
}
- for (i = 0; i < sizeof(tokens)/sizeof(tokens[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(tokens); i++)
SysFreeString(tokens[i]);
return hRet;
}
diff --git a/media/doc/README.WINE b/media/doc/README.WINE
index f31f2105ac..27033f2a31 100644
--- a/media/doc/README.WINE
+++ b/media/doc/README.WINE
@@ -141,7 +141,7 @@ reactos/dll/win32/odbc32 # Synced to WineStaging-4.0.
Depends on po
reactos/dll/win32/odbccp32 # Synced to WineStaging-4.0
reactos/dll/win32/ole32 # Synced to WineStaging-4.0
reactos/dll/win32/oleacc # Synced to WineStaging-4.0
-reactos/dll/win32/oleaut32 # Synced to WineStaging-3.3
+reactos/dll/win32/oleaut32 # Synced to WineStaging-4.0
reactos/dll/win32/olecli32 # Synced to WineStaging-3.3
reactos/dll/win32/oledlg # Synced to WineStaging-3.3
reactos/dll/win32/olepro32 # Synced to WineStaging-3.3
diff --git a/sdk/include/psdk/oleauto.h b/sdk/include/psdk/oleauto.h
index ac3a92b67d..8221129727 100644
--- a/sdk/include/psdk/oleauto.h
+++ b/sdk/include/psdk/oleauto.h
@@ -676,18 +676,18 @@ HRESULT WINAPI VarDecNeg(_In_ const DECIMAL*, _Out_ DECIMAL*);
HRESULT WINAPI VarDecRound(_In_ const DECIMAL*, int, _Out_ DECIMAL*);
HRESULT WINAPI VarDecSub(_In_ const DECIMAL*, _In_ const DECIMAL*, _Out_ DECIMAL*);
-HRESULT WINAPI VarCyAbs(_In_ const CY, _Out_ CY*);
-HRESULT WINAPI VarCyAdd(_In_ const CY, _In_ const CY, _Out_ CY*);
-HRESULT WINAPI VarCyCmp(_In_ const CY, _In_ const CY);
-HRESULT WINAPI VarCyCmpR8(_In_ const CY, _In_ DOUBLE);
-HRESULT WINAPI VarCyFix(_In_ const CY, _Out_ CY*);
-HRESULT WINAPI VarCyInt(_In_ const CY, _Out_ CY*);
-HRESULT WINAPI VarCyMul(_In_ const CY, _In_ CY, _Out_ CY*);
-HRESULT WINAPI VarCyMulI4(_In_ const CY, _In_ LONG, _Out_ CY*);
-HRESULT WINAPI VarCyMulI8(_In_ const CY, _In_ LONG64, _Out_ CY*);
-HRESULT WINAPI VarCyNeg(_In_ const CY, _Out_ CY*);
-HRESULT WINAPI VarCyRound(_In_ const CY, _In_ INT, _Out_ CY*);
-HRESULT WINAPI VarCySub(_In_ const CY, _In_ const CY, _Out_ CY*);
+HRESULT WINAPI VarCyAbs(_In_ CY, _Out_ CY*);
+HRESULT WINAPI VarCyAdd(_In_ CY, _In_ CY, _Out_ CY*);
+HRESULT WINAPI VarCyCmp(_In_ CY, _In_ CY);
+HRESULT WINAPI VarCyCmpR8(_In_ CY, _In_ DOUBLE);
+HRESULT WINAPI VarCyFix(_In_ CY, _Out_ CY*);
+HRESULT WINAPI VarCyInt(_In_ CY, _Out_ CY*);
+HRESULT WINAPI VarCyMul(_In_ CY, _In_ CY, _Out_ CY*);
+HRESULT WINAPI VarCyMulI4(_In_ CY, _In_ LONG, _Out_ CY*);
+HRESULT WINAPI VarCyMulI8(_In_ CY, _In_ LONG64, _Out_ CY*);
+HRESULT WINAPI VarCyNeg(_In_ CY, _Out_ CY*);
+HRESULT WINAPI VarCyRound(_In_ CY, _In_ INT, _Out_ CY*);
+HRESULT WINAPI VarCySub(_In_ CY, _In_ CY, _Out_ CY*);
HRESULT WINAPI VarAdd(_In_ LPVARIANT, _In_ LPVARIANT, _Out_ LPVARIANT);
HRESULT WINAPI VarAnd(_In_ LPVARIANT, _In_ LPVARIANT, _Out_ LPVARIANT);