ole32: Implement custom marshalling for pointer monikers.
Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
ef889fe654
commit
a3909647b2
|
@ -37,13 +37,14 @@
|
||||||
WINE_DEFAULT_DEBUG_CHANNEL(ole);
|
WINE_DEFAULT_DEBUG_CHANNEL(ole);
|
||||||
|
|
||||||
/* PointerMoniker data structure */
|
/* PointerMoniker data structure */
|
||||||
typedef struct PointerMonikerImpl{
|
typedef struct PointerMonikerImpl
|
||||||
|
{
|
||||||
IMoniker IMoniker_iface;
|
IMoniker IMoniker_iface;
|
||||||
|
IMarshal IMarshal_iface;
|
||||||
|
|
||||||
LONG ref; /* reference counter for this object */
|
LONG ref; /* reference counter for this object */
|
||||||
|
|
||||||
IUnknown *pObject; /* custom marshaler */
|
IUnknown *pObject;
|
||||||
} PointerMonikerImpl;
|
} PointerMonikerImpl;
|
||||||
|
|
||||||
static inline PointerMonikerImpl *impl_from_IMoniker(IMoniker *iface)
|
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);
|
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 PointerMonikerImpl *unsafe_impl_from_IMoniker(IMoniker *iface);
|
||||||
static HRESULT WINAPI
|
static HRESULT WINAPI
|
||||||
PointerMonikerImpl_QueryInterface(IMoniker* iface,REFIID riid,void** ppvObject)
|
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_IPersist, riid) ||
|
||||||
IsEqualIID(&IID_IPersistStream, riid) ||
|
IsEqualIID(&IID_IPersistStream, riid) ||
|
||||||
IsEqualIID(&IID_IMoniker, riid))
|
IsEqualIID(&IID_IMoniker, riid))
|
||||||
|
{
|
||||||
*ppvObject = iface;
|
*ppvObject = iface;
|
||||||
|
}
|
||||||
|
else if (IsEqualIID(&IID_IMarshal, riid))
|
||||||
|
*ppvObject = &This->IMarshal_iface;
|
||||||
|
|
||||||
/* Check that we obtained an interface.*/
|
/* Check that we obtained an interface.*/
|
||||||
if ((*ppvObject)==0)
|
if ((*ppvObject)==0)
|
||||||
|
@ -542,6 +552,117 @@ static PointerMonikerImpl *unsafe_impl_from_IMoniker(IMoniker *iface)
|
||||||
return CONTAINING_RECORD(iface, PointerMonikerImpl, 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)
|
* PointerMoniker_Construct (local function)
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
@ -549,8 +670,8 @@ static void PointerMonikerImpl_Construct(PointerMonikerImpl* This, IUnknown *pun
|
||||||
{
|
{
|
||||||
TRACE("(%p)\n",This);
|
TRACE("(%p)\n",This);
|
||||||
|
|
||||||
/* Initialize the virtual function table. */
|
|
||||||
This->IMoniker_iface.lpVtbl = &VT_PointerMonikerImpl;
|
This->IMoniker_iface.lpVtbl = &VT_PointerMonikerImpl;
|
||||||
|
This->IMarshal_iface.lpVtbl = &pointer_moniker_marshal_vtbl;
|
||||||
This->ref = 1;
|
This->ref = 1;
|
||||||
if (punk)
|
if (punk)
|
||||||
IUnknown_AddRef(punk);
|
IUnknown_AddRef(punk);
|
||||||
|
|
|
@ -2722,16 +2722,18 @@ todo_wine
|
||||||
static void test_pointer_moniker(void)
|
static void test_pointer_moniker(void)
|
||||||
{
|
{
|
||||||
IMoniker *moniker, *moniker2, *prefix, *inverse;
|
IMoniker *moniker, *moniker2, *prefix, *inverse;
|
||||||
|
DWORD moniker_type, hash, size;
|
||||||
IEnumMoniker *enummoniker;
|
IEnumMoniker *enummoniker;
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
DWORD moniker_type;
|
|
||||||
DWORD hash;
|
|
||||||
IBindCtx *bindctx;
|
IBindCtx *bindctx;
|
||||||
FILETIME filetime;
|
FILETIME filetime;
|
||||||
IUnknown *unknown;
|
IUnknown *unknown;
|
||||||
IStream *stream;
|
IStream *stream;
|
||||||
IROTData *rotdata;
|
IROTData *rotdata;
|
||||||
LPOLESTR display_name;
|
LPOLESTR display_name;
|
||||||
|
IMarshal *marshal;
|
||||||
|
LARGE_INTEGER pos;
|
||||||
|
CLSID clsid;
|
||||||
|
|
||||||
cLocks = 0;
|
cLocks = 0;
|
||||||
|
|
||||||
|
@ -2750,6 +2752,35 @@ todo_wine
|
||||||
IUnknown_Release(unknown);
|
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();
|
ok_more_than_one_lock();
|
||||||
|
|
||||||
/* Display Name */
|
/* Display Name */
|
||||||
|
@ -2821,7 +2852,8 @@ todo_wine
|
||||||
|
|
||||||
IMoniker_Release(moniker);
|
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);
|
hr = CreatePointerMoniker(NULL, &moniker);
|
||||||
ok_ole_success(hr, CreatePointerMoniker);
|
ok_ole_success(hr, CreatePointerMoniker);
|
||||||
|
|
Loading…
Reference in New Issue