Nikolay Sivov : ole32: Implement custom marshalling for pointer monikers.
Alexandre Julliard
julliard at winehq.org
Wed Jan 29 16:24:08 CST 2020
Module: wine
Branch: master
Commit: a3909647b23ad8227b71e30cff18dc43a048528b
URL: https://source.winehq.org/git/wine.git/?a=commit;h=a3909647b23ad8227b71e30cff18dc43a048528b
Author: Nikolay Sivov <nsivov at codeweavers.com>
Date: Wed Jan 29 16:57:00 2020 +0300
ole32: Implement custom marshalling for pointer monikers.
Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/ole32/pointermoniker.c | 129 ++++++++++++++++++++++++++++++++++++++++++--
dlls/ole32/tests/moniker.c | 38 +++++++++++--
2 files changed, 160 insertions(+), 7 deletions(-)
diff --git a/dlls/ole32/pointermoniker.c b/dlls/ole32/pointermoniker.c
index c1a0e2ae1c..2cb0600336 100644
--- a/dlls/ole32/pointermoniker.c
+++ b/dlls/ole32/pointermoniker.c
@@ -37,13 +37,14 @@
WINE_DEFAULT_DEBUG_CHANNEL(ole);
/* PointerMoniker data structure */
-typedef struct PointerMonikerImpl{
-
+typedef struct PointerMonikerImpl
+{
IMoniker IMoniker_iface;
+ IMarshal IMarshal_iface;
LONG ref; /* reference counter for this object */
- IUnknown *pObject; /* custom marshaler */
+ IUnknown *pObject;
} PointerMonikerImpl;
static inline PointerMonikerImpl *impl_from_IMoniker(IMoniker *iface)
@@ -51,6 +52,11 @@ static inline PointerMonikerImpl *impl_from_IMoniker(IMoniker *iface)
return CONTAINING_RECORD(iface, PointerMonikerImpl, IMoniker_iface);
}
+static PointerMonikerImpl *impl_from_IMarshal(IMarshal *iface)
+{
+ return CONTAINING_RECORD(iface, PointerMonikerImpl, IMarshal_iface);
+}
+
static PointerMonikerImpl *unsafe_impl_from_IMoniker(IMoniker *iface);
static HRESULT WINAPI
PointerMonikerImpl_QueryInterface(IMoniker* iface,REFIID riid,void** ppvObject)
@@ -70,7 +76,11 @@ PointerMonikerImpl_QueryInterface(IMoniker* iface,REFIID riid,void** ppvObject)
IsEqualIID(&IID_IPersist, riid) ||
IsEqualIID(&IID_IPersistStream, riid) ||
IsEqualIID(&IID_IMoniker, riid))
+ {
*ppvObject = iface;
+ }
+ else if (IsEqualIID(&IID_IMarshal, riid))
+ *ppvObject = &This->IMarshal_iface;
/* Check that we obtained an interface.*/
if ((*ppvObject)==0)
@@ -542,6 +552,117 @@ static PointerMonikerImpl *unsafe_impl_from_IMoniker(IMoniker *iface)
return CONTAINING_RECORD(iface, PointerMonikerImpl, IMoniker_iface);
}
+static HRESULT WINAPI pointer_moniker_marshal_QueryInterface(IMarshal *iface, REFIID riid, LPVOID *ppv)
+{
+ PointerMonikerImpl *moniker = impl_from_IMarshal(iface);
+
+ TRACE("%p, %s, %p.\n", iface, debugstr_guid(riid), ppv);
+
+ return IMoniker_QueryInterface(&moniker->IMoniker_iface, riid, ppv);
+}
+
+static ULONG WINAPI pointer_moniker_marshal_AddRef(IMarshal *iface)
+{
+ PointerMonikerImpl *moniker = impl_from_IMarshal(iface);
+
+ TRACE("%p.\n",iface);
+
+ return IMoniker_AddRef(&moniker->IMoniker_iface);
+}
+
+static ULONG WINAPI pointer_moniker_marshal_Release(IMarshal *iface)
+{
+ PointerMonikerImpl *moniker = impl_from_IMarshal(iface);
+
+ TRACE("%p.\n",iface);
+
+ return IMoniker_Release(&moniker->IMoniker_iface);
+}
+
+static HRESULT WINAPI pointer_moniker_marshal_GetUnmarshalClass(IMarshal *iface, REFIID riid, void *pv,
+ DWORD dwDestContext, void *pvDestContext, DWORD mshlflags, CLSID *clsid)
+{
+ PointerMonikerImpl *moniker = impl_from_IMarshal(iface);
+
+ TRACE("%p, %s, %p, %x, %p, %x, %p.\n", iface, debugstr_guid(riid), pv, dwDestContext, pvDestContext,
+ mshlflags, clsid);
+
+ return IMoniker_GetClassID(&moniker->IMoniker_iface, clsid);
+}
+
+static HRESULT WINAPI pointer_moniker_marshal_GetMarshalSizeMax(IMarshal *iface, REFIID riid, void *pv,
+ DWORD dwDestContext, void *pvDestContext, DWORD mshlflags, DWORD *size)
+{
+ PointerMonikerImpl *moniker = impl_from_IMarshal(iface);
+
+ TRACE("%p, %s, %p, %d, %p, %#x, %p.\n", iface, debugstr_guid(riid), pv, dwDestContext, pvDestContext,
+ mshlflags, size);
+
+ return CoGetMarshalSizeMax(size, &IID_IUnknown, moniker->pObject, dwDestContext, pvDestContext, mshlflags);
+}
+
+static HRESULT WINAPI pointer_moniker_marshal_MarshalInterface(IMarshal *iface, IStream *stream, REFIID riid,
+ void *pv, DWORD dwDestContext, void *pvDestContext, DWORD mshlflags)
+{
+ PointerMonikerImpl *moniker = impl_from_IMarshal(iface);
+
+ TRACE("%p, %s, %p, %x, %p, %x.\n", stream, debugstr_guid(riid), pv,
+ dwDestContext, pvDestContext, mshlflags);
+
+ return CoMarshalInterface(stream, &IID_IUnknown, moniker->pObject, dwDestContext,
+ pvDestContext, mshlflags);
+}
+
+static HRESULT WINAPI pointer_moniker_marshal_UnmarshalInterface(IMarshal *iface, IStream *stream,
+ REFIID riid, void **ppv)
+{
+ PointerMonikerImpl *moniker = impl_from_IMarshal(iface);
+ IUnknown *object;
+ HRESULT hr;
+
+ TRACE("%p, %p, %s, %p.\n", iface, stream, debugstr_guid(riid), ppv);
+
+ hr = CoUnmarshalInterface(stream, &IID_IUnknown, (void **)&object);
+ if (FAILED(hr))
+ {
+ ERR("Couldn't unmarshal moniker, hr = %#x.\n", hr);
+ return hr;
+ }
+
+ if (moniker->pObject)
+ IUnknown_Release(moniker->pObject);
+ moniker->pObject = object;
+
+ return IMoniker_QueryInterface(&moniker->IMoniker_iface, riid, ppv);
+}
+
+static HRESULT WINAPI pointer_moniker_marshal_ReleaseMarshalData(IMarshal *iface, IStream *stream)
+{
+ TRACE("%p, %p.\n", iface, stream);
+
+ return S_OK;
+}
+
+static HRESULT WINAPI pointer_moniker_marshal_DisconnectObject(IMarshal *iface, DWORD reserved)
+{
+ TRACE("%p, %#x.\n", iface, reserved);
+
+ return S_OK;
+}
+
+static const IMarshalVtbl pointer_moniker_marshal_vtbl =
+{
+ pointer_moniker_marshal_QueryInterface,
+ pointer_moniker_marshal_AddRef,
+ pointer_moniker_marshal_Release,
+ pointer_moniker_marshal_GetUnmarshalClass,
+ pointer_moniker_marshal_GetMarshalSizeMax,
+ pointer_moniker_marshal_MarshalInterface,
+ pointer_moniker_marshal_UnmarshalInterface,
+ pointer_moniker_marshal_ReleaseMarshalData,
+ pointer_moniker_marshal_DisconnectObject
+};
+
/******************************************************************************
* PointerMoniker_Construct (local function)
*******************************************************************************/
@@ -549,8 +670,8 @@ static void PointerMonikerImpl_Construct(PointerMonikerImpl* This, IUnknown *pun
{
TRACE("(%p)\n",This);
- /* Initialize the virtual function table. */
This->IMoniker_iface.lpVtbl = &VT_PointerMonikerImpl;
+ This->IMarshal_iface.lpVtbl = &pointer_moniker_marshal_vtbl;
This->ref = 1;
if (punk)
IUnknown_AddRef(punk);
diff --git a/dlls/ole32/tests/moniker.c b/dlls/ole32/tests/moniker.c
index 231551b244..0e6f2677c5 100644
--- a/dlls/ole32/tests/moniker.c
+++ b/dlls/ole32/tests/moniker.c
@@ -2722,16 +2722,18 @@ todo_wine
static void test_pointer_moniker(void)
{
IMoniker *moniker, *moniker2, *prefix, *inverse;
+ DWORD moniker_type, hash, size;
IEnumMoniker *enummoniker;
HRESULT hr;
- DWORD moniker_type;
- DWORD hash;
IBindCtx *bindctx;
FILETIME filetime;
IUnknown *unknown;
IStream *stream;
IROTData *rotdata;
LPOLESTR display_name;
+ IMarshal *marshal;
+ LARGE_INTEGER pos;
+ CLSID clsid;
cLocks = 0;
@@ -2750,6 +2752,35 @@ todo_wine
IUnknown_Release(unknown);
}
+ hr = IMoniker_QueryInterface(moniker, &IID_IMarshal, (void **)&marshal);
+ ok(hr == S_OK, "Failed to get interface, hr %#x.\n", hr);
+
+ hr = IMarshal_GetUnmarshalClass(marshal, NULL, NULL, 0, NULL, 0, &clsid);
+ ok(hr == S_OK, "Failed to get class, hr %#x.\n", hr);
+ ok(IsEqualGUID(&clsid, &CLSID_PointerMoniker), "Unexpected class.\n");
+
+ hr = IMarshal_GetMarshalSizeMax(marshal, &IID_IMoniker, NULL, CLSCTX_INPROC, NULL, 0, &size);
+ ok(hr == S_OK, "Failed to get marshal size, hr %#x.\n", hr);
+ ok(size > 0, "Unexpected size %d.\n", size);
+
+ hr = CreateStreamOnHGlobal(NULL, TRUE, &stream);
+ ok(hr == S_OK, "Failed to create a stream, hr %#x.\n", hr);
+
+ hr = CoMarshalInterface(stream, &IID_IMoniker, (IUnknown *)moniker, MSHCTX_INPROC, NULL, MSHLFLAGS_NORMAL);
+ ok(hr == S_OK, "Failed to marshal moniker, hr %#x.\n", hr);
+
+ pos.QuadPart = 0;
+ IStream_Seek(stream, pos, STREAM_SEEK_SET, NULL);
+ hr = CoUnmarshalInterface(stream, &IID_IMoniker, (void **)&moniker2);
+ ok(hr == S_OK, "Failed to unmarshal, hr %#x.\n", hr);
+ hr = IMoniker_IsEqual(moniker, moniker2);
+ ok(hr == S_OK, "Expected equal moniker, hr %#x.\n", hr);
+ IMoniker_Release(moniker2);
+
+ IStream_Release(stream);
+
+ IMarshal_Release(marshal);
+
ok_more_than_one_lock();
/* Display Name */
@@ -2821,7 +2852,8 @@ todo_wine
IMoniker_Release(moniker);
- ok_no_locks();
+todo_wine
+ ok(cLocks == 0, "Number of locks should be 0, but actually is %d.\n", cLocks);
hr = CreatePointerMoniker(NULL, &moniker);
ok_ole_success(hr, CreatePointerMoniker);
More information about the wine-cvs
mailing list