ole32: Add CreateObjrefMoniker() stub implementation..

Signed-off-by: Dmitry Timoshkov <dmitry@baikal.ru>
Signed-off-by: Huw Davies <huw@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Dmitry Timoshkov 2021-11-22 10:48:29 +03:00 committed by Alexandre Julliard
parent 5cc085975f
commit 21cf2dd15f
7 changed files with 691 additions and 6 deletions

View File

@ -26,15 +26,17 @@
DEFINE_OLEGUID( CLSID_FileMoniker, 0x303, 0, 0 );
DEFINE_OLEGUID( CLSID_ItemMoniker, 0x304, 0, 0 );
DEFINE_OLEGUID( CLSID_AntiMoniker, 0x305, 0, 0 );
DEFINE_OLEGUID( CLSID_PointerMoniker, 0x306, 0, 0 );
DEFINE_OLEGUID( CLSID_CompositeMoniker, 0x309, 0, 0 );
DEFINE_OLEGUID( CLSID_ClassMoniker, 0x31a, 0, 0 );
DEFINE_OLEGUID( CLSID_PointerMoniker, 0x306, 0, 0 );
DEFINE_OLEGUID( CLSID_ObjrefMoniker, 0x327, 0, 0 );
HRESULT WINAPI FileMoniker_CreateInstance(IClassFactory *iface, IUnknown *pUnk, REFIID riid, void **ppv);
HRESULT WINAPI ItemMoniker_CreateInstance(IClassFactory *iface, IUnknown *pUnk, REFIID riid, void **ppv);
HRESULT WINAPI AntiMoniker_CreateInstance(IClassFactory *iface, IUnknown *pUnk, REFIID riid, void **ppv);
HRESULT WINAPI CompositeMoniker_CreateInstance(IClassFactory *iface, IUnknown *pUnk, REFIID riid, void **ppv);
HRESULT WINAPI ClassMoniker_CreateInstance(IClassFactory *iface, IUnknown *pUnk, REFIID riid, void **ppv);
HRESULT WINAPI ObjrefMoniker_CreateInstance(IClassFactory *iface, IUnknown *pUnk, REFIID riid, void **ppv);
HRESULT WINAPI PointerMoniker_CreateInstance(IClassFactory *iface, IUnknown *pUnk, REFIID riid, void **ppv);
HRESULT WINAPI ComCat_CreateInstance(IClassFactory *iface, IUnknown *pUnk, REFIID riid, void **ppv);

View File

@ -103,7 +103,7 @@
@ stdcall CreateGenericComposite(ptr ptr ptr)
@ stdcall CreateILockBytesOnHGlobal(ptr long ptr)
@ stdcall CreateItemMoniker(wstr wstr ptr)
@ stub CreateObjrefMoniker
@ stdcall CreateObjrefMoniker(ptr ptr)
@ stdcall CreateOleAdviseHolder(ptr)
@ stdcall CreatePointerMoniker(ptr ptr)
@ stdcall CreateStreamOnHGlobal(ptr long ptr) combase.CreateStreamOnHGlobal

View File

@ -105,6 +105,12 @@ coclass ClassMoniker { interface IMoniker; }
]
coclass PSFactoryBuffer { interface IFactoryBuffer; }
[
threading(both),
uuid(00000327-0000-0000-c000-000000000046)
]
coclass ObjrefMoniker { interface IMoniker; }
[
helpstring("Component Categories Manager"),
threading(both),

View File

@ -137,6 +137,17 @@ static const IClassFactoryVtbl PointerMonikerCFVtbl =
static IClassFactory PointerMonikerCF = { &PointerMonikerCFVtbl };
static const IClassFactoryVtbl ObjrefMonikerCFVtbl =
{
ClassFactory_QueryInterface,
ClassFactory_AddRef,
ClassFactory_Release,
ObjrefMoniker_CreateInstance,
ClassFactory_LockServer
};
static IClassFactory ObjrefMonikerCF = { &ObjrefMonikerCFVtbl };
static const IClassFactoryVtbl ComCatCFVtbl =
{
ClassFactory_QueryInterface,
@ -198,6 +209,8 @@ HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID iid,LPVOID *ppv)
return IClassFactory_QueryInterface(&CompositeMonikerCF, iid, ppv);
if (IsEqualCLSID(rclsid, &CLSID_ClassMoniker))
return IClassFactory_QueryInterface(&ClassMonikerCF, iid, ppv);
if (IsEqualCLSID(rclsid, &CLSID_ObjrefMoniker))
return IClassFactory_QueryInterface(&ObjrefMonikerCF, iid, ppv);
if (IsEqualCLSID(rclsid, &CLSID_PointerMoniker))
return IClassFactory_QueryInterface(&PointerMonikerCF, iid, ppv);
if (IsEqualGUID(rclsid, &CLSID_StdComponentCategoriesMgr))

View File

@ -1,5 +1,5 @@
/*
* Pointer Moniker Implementation
* Pointer and Objref Monikers Implementation
*
* Copyright 1999 Noomen Hamza
* Copyright 2008 Robert Shearman (for CodeWeavers)
@ -641,3 +641,419 @@ HRESULT WINAPI PointerMoniker_CreateInstance(IClassFactory *iface,
return hr;
}
/* ObjrefMoniker implementation */
typedef struct
{
IMoniker IMoniker_iface;
IMarshal IMarshal_iface;
LONG refcount;
IUnknown *pObject;
} ObjrefMonikerImpl;
static inline ObjrefMonikerImpl *objref_impl_from_IMoniker(IMoniker *iface)
{
return CONTAINING_RECORD(iface, ObjrefMonikerImpl, IMoniker_iface);
}
static ObjrefMonikerImpl *objref_impl_from_IMarshal(IMarshal *iface)
{
return CONTAINING_RECORD(iface, ObjrefMonikerImpl, IMarshal_iface);
}
static HRESULT WINAPI ObjrefMonikerImpl_QueryInterface(IMoniker *iface, REFIID iid, void **obj)
{
ObjrefMonikerImpl *moniker = objref_impl_from_IMoniker(iface);
TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), obj);
if (!obj)
return E_INVALIDARG;
*obj = 0;
if (IsEqualIID(iid, &IID_IUnknown) ||
IsEqualIID(iid, &IID_IPersist) ||
IsEqualIID(iid, &IID_IPersistStream) ||
IsEqualIID(iid, &IID_IMoniker) ||
IsEqualGUID(iid, &CLSID_ObjrefMoniker) ||
IsEqualGUID(iid, &CLSID_PointerMoniker))
{
*obj = iface;
}
else if (IsEqualIID(iid, &IID_IMarshal))
*obj = &moniker->IMarshal_iface;
else
return E_NOINTERFACE;
IMoniker_AddRef(iface);
return S_OK;
}
static ULONG WINAPI ObjrefMonikerImpl_AddRef(IMoniker *iface)
{
ObjrefMonikerImpl *moniker = objref_impl_from_IMoniker(iface);
ULONG refcount = InterlockedIncrement(&moniker->refcount);
TRACE("%p, refcount %u\n", iface, refcount);
return refcount;
}
static ULONG WINAPI ObjrefMonikerImpl_Release(IMoniker *iface)
{
ObjrefMonikerImpl *moniker = objref_impl_from_IMoniker(iface);
ULONG refcount = InterlockedDecrement(&moniker->refcount);
TRACE("%p, refcount %u\n", iface, refcount);
if (!refcount)
{
if (moniker->pObject) IUnknown_Release(moniker->pObject);
heap_free(moniker);
}
return refcount;
}
static HRESULT WINAPI ObjrefMonikerImpl_GetClassID(IMoniker *iface, CLSID *clsid)
{
TRACE("(%p,%p)\n", iface, clsid);
if (!clsid)
return E_POINTER;
*clsid = CLSID_ObjrefMoniker;
return S_OK;
}
static HRESULT WINAPI ObjrefMonikerImpl_IsDirty(IMoniker *iface)
{
FIXME("(%p): stub\n", iface);
return S_FALSE;
}
static HRESULT WINAPI ObjrefMonikerImpl_Load(IMoniker *iface, IStream *stream)
{
FIXME("(%p,%p): stub\n", iface, stream);
return E_NOTIMPL;
}
static HRESULT WINAPI ObjrefMonikerImpl_Save(IMoniker *iface, IStream *stream, BOOL dirty)
{
FIXME("(%p,%p,%d): stub\n", iface, stream, dirty);
return E_NOTIMPL;
}
static HRESULT WINAPI ObjrefMonikerImpl_GetSizeMax(IMoniker *iface, ULARGE_INTEGER *size)
{
FIXME("(%p,%p): stub\n", iface, size);
return E_NOTIMPL;
}
static HRESULT WINAPI ObjrefMonikerImpl_BindToObject(IMoniker *iface, IBindCtx *pbc, IMoniker *left,
REFIID riid, void **result)
{
FIXME("(%p,%p,%p,%s,%p): stub\n", iface, pbc, left, debugstr_guid(riid), result);
return E_NOTIMPL;
}
static HRESULT WINAPI ObjrefMonikerImpl_BindToStorage(IMoniker *iface, IBindCtx *pbc, IMoniker *left,
REFIID riid, void **result)
{
FIXME("(%p,%p,%p,%s,%p): stub\n", iface, pbc, left, debugstr_guid(riid), result);
return E_NOTIMPL;
}
static HRESULT WINAPI ObjrefMonikerImpl_Reduce(IMoniker *iface, IBindCtx *pbc, DWORD howfar,
IMoniker **left, IMoniker **reduced)
{
FIXME("(%p,%p,%d,%p,%p): stub\n", iface, pbc, howfar, left, reduced);
return E_NOTIMPL;
}
static HRESULT WINAPI ObjrefMonikerImpl_ComposeWith(IMoniker *iface, IMoniker *right,
BOOL only_if_not_generic, IMoniker **result)
{
FIXME("(%p,%p,%d,%p): stub\n", iface, right, only_if_not_generic, result);
return E_NOTIMPL;
}
static HRESULT WINAPI ObjrefMonikerImpl_Enum(IMoniker *iface, BOOL forward, IEnumMoniker **enummoniker)
{
TRACE("(%p,%d,%p)\n", iface, forward, enummoniker);
if (!enummoniker)
return E_POINTER;
*enummoniker = NULL;
return S_OK;
}
static HRESULT WINAPI ObjrefMonikerImpl_IsEqual(IMoniker *iface, IMoniker *other)
{
FIXME("(%p,%p): stub\n", iface, other);
return E_NOTIMPL;
}
static HRESULT WINAPI ObjrefMonikerImpl_Hash(IMoniker *iface, DWORD *hash)
{
ObjrefMonikerImpl *moniker = objref_impl_from_IMoniker(iface);
TRACE("(%p,%p)\n", iface, hash);
if (!hash)
return E_POINTER;
*hash = PtrToUlong(moniker->pObject);
return S_OK;
}
static HRESULT WINAPI ObjrefMonikerImpl_IsRunning(IMoniker *iface, IBindCtx *pbc, IMoniker *left,
IMoniker *running)
{
FIXME("(%p,%p,%p,%p): stub\n", iface, pbc, left, running);
return E_NOTIMPL;
}
static HRESULT WINAPI ObjrefMonikerImpl_GetTimeOfLastChange(IMoniker *iface,
IBindCtx *pbc, IMoniker *left, FILETIME *time)
{
FIXME("(%p,%p,%p,%p): stub\n", iface, pbc, left, time);
return MK_E_UNAVAILABLE;
}
static HRESULT WINAPI ObjrefMonikerImpl_Inverse(IMoniker *iface, IMoniker **moniker)
{
FIXME("(%p,%p): stub\n", iface, moniker);
return E_NOTIMPL;
}
static HRESULT WINAPI ObjrefMonikerImpl_CommonPrefixWith(IMoniker *iface, IMoniker *other, IMoniker **prefix)
{
FIXME("(%p,%p,%p): stub\n", iface, other, prefix);
return E_NOTIMPL;
}
static HRESULT WINAPI ObjrefMonikerImpl_RelativePathTo(IMoniker *iface, IMoniker *other, IMoniker **result)
{
FIXME("(%p,%p,%p): stub\n", iface, other, result);
return E_NOTIMPL;
}
static HRESULT WINAPI ObjrefMonikerImpl_GetDisplayName(IMoniker *iface, IBindCtx *pbc,
IMoniker *left, LPOLESTR *name)
{
FIXME("(%p,%p,%p,%p): stub\n", iface, pbc, left, name);
return E_NOTIMPL;
}
static HRESULT WINAPI ObjrefMonikerImpl_ParseDisplayName(IMoniker *iface, IBindCtx *pbc,
IMoniker *left, LPOLESTR name, ULONG *eaten, IMoniker **out)
{
FIXME("(%p,%p,%p,%p,%p,%p): stub\n", iface, pbc, left, name, eaten, out);
return E_NOTIMPL;
}
static HRESULT WINAPI ObjrefMonikerImpl_IsSystemMoniker(IMoniker *iface, DWORD *mksys)
{
TRACE("(%p,%p)\n", iface, mksys);
if (!mksys)
return E_POINTER;
*mksys = MKSYS_OBJREFMONIKER;
return S_OK;
}
static const IMonikerVtbl VT_ObjrefMonikerImpl =
{
ObjrefMonikerImpl_QueryInterface,
ObjrefMonikerImpl_AddRef,
ObjrefMonikerImpl_Release,
ObjrefMonikerImpl_GetClassID,
ObjrefMonikerImpl_IsDirty,
ObjrefMonikerImpl_Load,
ObjrefMonikerImpl_Save,
ObjrefMonikerImpl_GetSizeMax,
ObjrefMonikerImpl_BindToObject,
ObjrefMonikerImpl_BindToStorage,
ObjrefMonikerImpl_Reduce,
ObjrefMonikerImpl_ComposeWith,
ObjrefMonikerImpl_Enum,
ObjrefMonikerImpl_IsEqual,
ObjrefMonikerImpl_Hash,
ObjrefMonikerImpl_IsRunning,
ObjrefMonikerImpl_GetTimeOfLastChange,
ObjrefMonikerImpl_Inverse,
ObjrefMonikerImpl_CommonPrefixWith,
ObjrefMonikerImpl_RelativePathTo,
ObjrefMonikerImpl_GetDisplayName,
ObjrefMonikerImpl_ParseDisplayName,
ObjrefMonikerImpl_IsSystemMoniker
};
static HRESULT WINAPI objref_moniker_marshal_QueryInterface(IMarshal *iface, REFIID riid, LPVOID *ppv)
{
ObjrefMonikerImpl *moniker = objref_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 objref_moniker_marshal_AddRef(IMarshal *iface)
{
ObjrefMonikerImpl *moniker = objref_impl_from_IMarshal(iface);
TRACE("(%p)\n", iface);
return IMoniker_AddRef(&moniker->IMoniker_iface);
}
static ULONG WINAPI objref_moniker_marshal_Release(IMarshal *iface)
{
ObjrefMonikerImpl *moniker = objref_impl_from_IMarshal(iface);
TRACE("(%p)\n", iface);
return IMoniker_Release(&moniker->IMoniker_iface);
}
static HRESULT WINAPI objref_moniker_marshal_GetUnmarshalClass(IMarshal *iface, REFIID riid, void *pv,
DWORD dwDestContext, void *pvDestContext, DWORD mshlflags, CLSID *clsid)
{
ObjrefMonikerImpl *moniker = objref_impl_from_IMarshal(iface);
TRACE("(%p,%s,%p,%08x,%p,%x,%p)\n", iface, debugstr_guid(riid), pv, dwDestContext, pvDestContext,
mshlflags, clsid);
return IMoniker_GetClassID(&moniker->IMoniker_iface, clsid);
}
static HRESULT WINAPI objref_moniker_marshal_GetMarshalSizeMax(IMarshal *iface, REFIID riid, void *pv,
DWORD dwDestContext, void *pvDestContext, DWORD mshlflags, DWORD *size)
{
ObjrefMonikerImpl *moniker = objref_impl_from_IMarshal(iface);
TRACE("(%p,%s,%p,%08x,%p,%08x,%p)\n", iface, debugstr_guid(riid), pv, dwDestContext, pvDestContext,
mshlflags, size);
return CoGetMarshalSizeMax(size, &IID_IUnknown, moniker->pObject, dwDestContext, pvDestContext, mshlflags);
}
static HRESULT WINAPI objref_moniker_marshal_MarshalInterface(IMarshal *iface, IStream *stream, REFIID riid,
void *pv, DWORD dwDestContext, void *pvDestContext, DWORD mshlflags)
{
ObjrefMonikerImpl *moniker = objref_impl_from_IMarshal(iface);
TRACE("(%p,%s,%p,%08x,%p,%08x)\n", stream, debugstr_guid(riid), pv, dwDestContext, pvDestContext, mshlflags);
return CoMarshalInterface(stream, &IID_IUnknown, moniker->pObject, dwDestContext, pvDestContext, mshlflags);
}
static HRESULT WINAPI objref_moniker_marshal_UnmarshalInterface(IMarshal *iface, IStream *stream,
REFIID riid, void **ppv)
{
ObjrefMonikerImpl *moniker = objref_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 objref_moniker_marshal_ReleaseMarshalData(IMarshal *iface, IStream *stream)
{
TRACE("(%p,%p)\n", iface, stream);
return S_OK;
}
static HRESULT WINAPI objref_moniker_marshal_DisconnectObject(IMarshal *iface, DWORD reserved)
{
TRACE("(%p,%08x)\n", iface, reserved);
return S_OK;
}
static const IMarshalVtbl objref_moniker_marshal_vtbl =
{
objref_moniker_marshal_QueryInterface,
objref_moniker_marshal_AddRef,
objref_moniker_marshal_Release,
objref_moniker_marshal_GetUnmarshalClass,
objref_moniker_marshal_GetMarshalSizeMax,
objref_moniker_marshal_MarshalInterface,
objref_moniker_marshal_UnmarshalInterface,
objref_moniker_marshal_ReleaseMarshalData,
objref_moniker_marshal_DisconnectObject
};
/***********************************************************************
* CreateObjrefMoniker (OLE32.@)
*/
HRESULT WINAPI CreateObjrefMoniker(IUnknown *obj, IMoniker **ret)
{
ObjrefMonikerImpl *moniker;
TRACE("(%p,%p)\n", obj, ret);
if (!ret)
return E_INVALIDARG;
moniker = heap_alloc(sizeof(*moniker));
if (!moniker)
{
*ret = NULL;
return E_OUTOFMEMORY;
}
moniker->IMoniker_iface.lpVtbl = &VT_ObjrefMonikerImpl;
moniker->IMarshal_iface.lpVtbl = &objref_moniker_marshal_vtbl;
moniker->refcount = 1;
moniker->pObject = obj;
if (moniker->pObject)
IUnknown_AddRef(moniker->pObject);
*ret = &moniker->IMoniker_iface;
return S_OK;
}
HRESULT WINAPI ObjrefMoniker_CreateInstance(IClassFactory *iface, IUnknown *unk, REFIID iid, void **obj)
{
IMoniker *moniker;
HRESULT hr;
TRACE("(%p,%s,%p)\n", unk, debugstr_guid(iid), obj);
*obj = NULL;
if (unk)
return CLASS_E_NOAGGREGATION;
hr = CreateObjrefMoniker(NULL, &moniker);
if (FAILED(hr))
return hr;
hr = IMoniker_QueryInterface(moniker, iid, obj);
IMoniker_Release(moniker);
return hr;
}

View File

@ -82,9 +82,10 @@ static const CLSID CLSID_TestMoniker =
DEFINE_OLEGUID(CLSID_FileMoniker, 0x303, 0, 0);
DEFINE_OLEGUID(CLSID_ItemMoniker, 0x304, 0, 0);
DEFINE_OLEGUID(CLSID_AntiMoniker, 0x305, 0, 0);
DEFINE_OLEGUID(CLSID_PointerMoniker, 0x306, 0, 0);
DEFINE_OLEGUID(CLSID_CompositeMoniker, 0x309, 0, 0);
DEFINE_OLEGUID(CLSID_ClassMoniker, 0x31a, 0, 0);
DEFINE_OLEGUID(CLSID_PointerMoniker, 0x306, 0, 0);
DEFINE_OLEGUID(CLSID_ObjrefMoniker, 0x327, 0, 0);
#define TEST_MONIKER_TYPE_TODO(m,t) _test_moniker_type(m, t, TRUE, __LINE__)
#define TEST_MONIKER_TYPE(m,t) _test_moniker_type(m, t, FALSE, __LINE__)
@ -3861,7 +3862,7 @@ todo_wine
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");
ok(IsEqualGUID(&clsid, &CLSID_PointerMoniker), "Unexpected class %s.\n", wine_dbgstr_guid(&clsid));
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);
@ -4076,6 +4077,249 @@ todo_wine
IMoniker_Release(moniker);
}
static void test_objref_moniker(void)
{
IMoniker *moniker, *moniker2, *prefix, *inverse, *anti;
struct test_factory factory;
IEnumMoniker *enummoniker;
DWORD hash, size;
HRESULT hr;
IBindCtx *bindctx;
FILETIME filetime;
IUnknown *unknown;
IStream *stream;
IROTData *rotdata;
LPOLESTR display_name;
IMarshal *marshal;
LARGE_INTEGER pos;
CLSID clsid;
test_factory_init(&factory);
hr = CreateObjrefMoniker((IUnknown *)&factory.IClassFactory_iface, NULL);
ok(hr == E_INVALIDARG, "Unexpected hr %#x\n", hr);
hr = CreateObjrefMoniker((IUnknown *)&factory.IClassFactory_iface, &moniker);
ok(hr == S_OK, "Unexpected hr %#x\n", hr);
hr = IMoniker_QueryInterface(moniker, &IID_IMoniker, NULL);
ok(hr == E_INVALIDARG, "Unexpected hr %#x\n", hr);
hr = IMoniker_QueryInterface(moniker, &CLSID_PointerMoniker, (void **)&unknown);
ok(unknown == (IUnknown *)moniker, "Unexpected interface\n");
IUnknown_Release(unknown);
hr = IMoniker_QueryInterface(moniker, &CLSID_ObjrefMoniker, (void **)&unknown);
ok(unknown == (IUnknown *)moniker, "Unexpected interface\n");
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_ObjrefMoniker), "Unexpected class %s\n", wine_dbgstr_guid(&clsid));
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);
todo_wine
ok(hr == S_OK, "Expected equal moniker, hr %#x\n", hr);
IMoniker_Release(moniker2);
IStream_Release(stream);
IMarshal_Release(marshal);
ok(factory.refcount > 1, "Unexpected factory refcount %u\n", factory.refcount);
/* Display Name */
hr = CreateBindCtx(0, &bindctx);
ok(hr == S_OK, "CreateBindCtx failed: 0x%08x\n", hr);
hr = IMoniker_GetDisplayName(moniker, bindctx, NULL, &display_name);
todo_wine
ok(hr == S_OK, "IMoniker_GetDisplayName failed: 0x%08x\n", hr);
IBindCtx_Release(bindctx);
hr = IMoniker_IsDirty(moniker);
ok(hr == S_FALSE, "IMoniker_IsDirty should return S_FALSE, not 0x%08x\n", hr);
/* IROTData::GetComparisonData test */
hr = IMoniker_QueryInterface(moniker, &IID_IROTData, (void **)&rotdata);
ok(hr == E_NOINTERFACE, "IMoniker_QueryInterface(IID_IROTData) should have returned E_NOINTERFACE instead of 0x%08x\n", hr);
/* Saving */
hr = CreateStreamOnHGlobal(NULL, TRUE, &stream);
ok(hr == S_OK, "CreateStreamOnHGlobal failed: 0x%08x\n", hr);
hr = IMoniker_Save(moniker, stream, TRUE);
todo_wine
ok(hr == S_OK, "IMoniker_Save failed: 0x%08x\n", hr);
IStream_Release(stream);
/* Hashing */
hr = IMoniker_Hash(moniker, &hash);
ok(hr == S_OK, "IMoniker_Hash failed: 0x%08x\n", hr);
ok(hash == PtrToUlong(&factory.IClassFactory_iface), "Unexpected hash value %#x\n", hash);
/* IsSystemMoniker test */
TEST_MONIKER_TYPE(moniker, MKSYS_OBJREFMONIKER);
hr = IMoniker_Inverse(moniker, &inverse);
todo_wine
ok(hr == S_OK, "Failed to get inverse, hr %#x\n", hr);
if (hr == S_OK)
{
TEST_MONIKER_TYPE(inverse, MKSYS_ANTIMONIKER);
IMoniker_Release(inverse);
}
hr = CreateBindCtx(0, &bindctx);
ok(hr == S_OK, "CreateBindCtx failed: 0x%08x\n", hr);
/* IsRunning test */
hr = IMoniker_IsRunning(moniker, bindctx, NULL, NULL);
todo_wine
ok(hr == S_OK, "IMoniker_IsRunning should return S_OK, not 0x%08x\n", hr);
hr = IMoniker_GetTimeOfLastChange(moniker, bindctx, NULL, &filetime);
ok(hr == MK_E_UNAVAILABLE, "IMoniker_GetTimeOfLastChange should return MK_E_UNAVAILABLE, not 0x%08x\n", hr);
hr = IMoniker_BindToObject(moniker, bindctx, NULL, &IID_IUnknown, (void **)&unknown);
todo_wine
ok(hr == S_OK, "IMoniker_BindToObject failed: 0x%08x\n", hr);
if (hr == S_OK)
IUnknown_Release(unknown);
hr = IMoniker_BindToStorage(moniker, bindctx, NULL, &IID_IUnknown, (void **)&unknown);
todo_wine
ok(hr == S_OK, "IMoniker_BindToObject failed: 0x%08x\n", hr);
if (hr == S_OK)
IUnknown_Release(unknown);
IMoniker_Release(moniker);
todo_wine
ok(factory.refcount > 1, "Unexpected factory refcount %u\n", factory.refcount);
hr = CreateObjrefMoniker(NULL, &moniker);
ok(hr == S_OK, "CreateObjrefMoniker failed, hr %#x\n", hr);
hr = IMoniker_BindToObject(moniker, bindctx, NULL, &IID_IUnknown, (void **)&unknown);
todo_wine
ok(hr == E_UNEXPECTED, "IMoniker_BindToObject should have returned E_UNEXPECTED instead of 0x%08x\n", hr);
hr = IMoniker_BindToStorage(moniker, bindctx, NULL, &IID_IUnknown, (void **)&unknown);
todo_wine
ok(hr == E_UNEXPECTED, "IMoniker_BindToStorage should have returned E_UNEXPECTED instead of 0x%08x\n", hr);
IBindCtx_Release(bindctx);
/* Enum() */
enummoniker = (void *)0xdeadbeef;
hr = IMoniker_Enum(moniker, TRUE, &enummoniker);
ok(hr == S_OK, "Unexpected hr %#x\n", hr);
ok(enummoniker == NULL, "got %p\n", enummoniker);
enummoniker = (void *)0xdeadbeef;
hr = IMoniker_Enum(moniker, FALSE, &enummoniker);
ok(hr == S_OK, "Unexpected hr %#x\n", hr);
ok(enummoniker == NULL, "got %p\n", enummoniker);
IMoniker_Release(moniker);
/* CommonPrefixWith() */
hr = CreateObjrefMoniker((IUnknown *)&factory.IClassFactory_iface, &moniker);
ok(hr == S_OK, "CreateObjrefMoniker failed: hr %#x\n", hr);
hr = CreateObjrefMoniker((IUnknown *)&factory.IClassFactory_iface, &moniker2);
ok(hr == S_OK, "CreateObjrefMoniker failed: hr %#x\n", hr);
hr = IMoniker_IsEqual(moniker, NULL);
todo_wine
ok(hr == E_INVALIDARG, "Unexpected hr %#x\n", hr);
hr = IMoniker_IsEqual(moniker, moniker2);
todo_wine
ok(hr == S_OK, "Unexpected hr %#x\n", hr);
hr = IMoniker_CommonPrefixWith(moniker, moniker2, NULL);
todo_wine
ok(hr == E_INVALIDARG, "Unexpected hr %#x\n", hr);
hr = IMoniker_CommonPrefixWith(moniker, NULL, &prefix);
todo_wine
ok(hr == E_INVALIDARG, "Unexpected hr %#x\n", hr);
hr = IMoniker_CommonPrefixWith(moniker, moniker2, &prefix);
todo_wine
ok(hr == MK_S_US, "Unexpected hr %#x\n", hr);
if (hr == S_OK)
{
ok(prefix == moniker, "Unexpected pointer\n");
IMoniker_Release(prefix);
}
IMoniker_Release(moniker2);
hr = CreateObjrefMoniker((IUnknown *)moniker, &moniker2);
ok(hr == S_OK, "Failed to create moniker, hr %#x\n", hr);
hr = IMoniker_IsEqual(moniker, moniker2);
todo_wine
ok(hr == S_FALSE, "Unexpected hr %#x\n", hr);
hr = IMoniker_CommonPrefixWith(moniker, moniker2, &prefix);
todo_wine
ok(hr == MK_E_NOPREFIX, "Unexpected hr %#x\n", hr);
IMoniker_Release(moniker2);
/* ComposeWith() */
/* P + A -> () */
anti = create_antimoniker(1);
hr = IMoniker_ComposeWith(moniker, anti, TRUE, &moniker2);
todo_wine
ok(hr == S_OK, "Failed to compose, hr %#x\n", hr);
if (hr == S_OK)
ok(!moniker2, "Unexpected pointer\n");
IMoniker_Release(anti);
/* P + A2 -> A */
anti = create_antimoniker(2);
hr = IMoniker_ComposeWith(moniker, anti, TRUE, &moniker2);
todo_wine
ok(hr == S_OK, "Failed to compose, hr %#x\n", hr);
if (hr == S_OK)
{
TEST_MONIKER_TYPE(moniker2, MKSYS_ANTIMONIKER);
IMoniker_Release(moniker2);
}
IMoniker_Release(anti);
IMoniker_Release(moniker);
}
static void test_bind_context(void)
{
IRunningObjectTable *rot, *rot2;
@ -4385,6 +4629,7 @@ START_TEST(moniker)
test_anti_moniker();
test_generic_composite_moniker();
test_pointer_moniker();
test_objref_moniker();
test_save_load_filemoniker();
test_MonikerCommonPrefixWith();

View File

@ -330,7 +330,10 @@ interface IMoniker : IPersistStream
MKSYS_ITEMMONIKER = 4,
MKSYS_POINTERMONIKER = 5,
/* MKSYS_URLMONIKER = 6, */ /* defined in urlmon.idl */
MKSYS_CLASSMONIKER = 7
MKSYS_CLASSMONIKER = 7,
MKSYS_OBJREFMONIKER = 8,
MKSYS_SESSIONMONIKER = 9,
MKSYS_LUAMONIKER = 10
} MKSYS;
typedef [v1_enum] enum tagMKREDUCE {