[PATCH v3] ole32: Implement CreateObjrefMoniker().
Nikolay Sivov
nsivov at codeweavers.com
Wed Oct 13 11:50:56 CDT 2021
On 10/13/21 4:31 PM, Dmitry Timoshkov wrote:
> v3: Use separate implementation from pointer moniker.
>
> Signed-off-by: Dmitry Timoshkov <dmitry at baikal.ru>
> ---
> dlls/ole32/moniker.h | 4 +-
> dlls/ole32/ole32.spec | 2 +-
> dlls/ole32/ole32_objidl.idl | 6 +
> dlls/ole32/oleproxy.c | 13 +
> dlls/ole32/pointermoniker.c | 531 +++++++++++++++++++++++++++++++++++-
> dlls/ole32/tests/moniker.c | 221 ++++++++++++++-
> include/objidl.idl | 5 +-
> 7 files changed, 776 insertions(+), 6 deletions(-)
Does not have to be in the same file either. This will avoid multiple
*_impl_from_* helpers.
>
> +
> +static HRESULT WINAPI ObjrefMonikerImpl_Load(IMoniker *iface, IStream *stream)
> +{
> + TRACE("(%p)\n", 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;
> +}
Save() definitely works for objref moniker, so surely Load() is a stub too.
> +
> +static HRESULT WINAPI ObjrefMonikerImpl_GetSizeMax(IMoniker* iface, ULARGE_INTEGER *size)
> +{
> + TRACE("(%p,%p)\n", iface, size);
> +
> + if (!size)
> + return E_POINTER;
> +
> + size->u.LowPart = 0;
> + size->u.HighPart = 0;
> +
> + return E_NOTIMPL;
> +}
This is incorrect.
> +
> +static HRESULT WINAPI ObjrefMonikerImpl_BindToObject(IMoniker *iface, IBindCtx *pbc, IMoniker *left,
> + REFIID riid, void **result)
> +{
> + ObjrefMonikerImpl *moniker = objref_impl_from_IMoniker(iface);
> +
> + TRACE("(%p,%p,%p,%s,%p)\n", iface, pbc, left, debugstr_guid(riid), result);
> +
> + if (!moniker->pObject)
> + return E_UNEXPECTED;
> +
> + return IUnknown_QueryInterface(moniker->pObject, riid, result);
> +}
> +
> +static HRESULT WINAPI ObjrefMonikerImpl_BindToStorage(IMoniker *iface, IBindCtx *pbc, IMoniker *left,
> + REFIID riid, void **result)
> +{
> + ObjrefMonikerImpl *moniker = objref_impl_from_IMoniker(iface);
> +
> + TRACE("(%p,%p,%p,%s,%p)\n", iface, pbc, left, debugstr_guid(riid), result);
> +
> + if (!moniker->pObject)
> + return E_UNEXPECTED;
> +
> + return IUnknown_QueryInterface(moniker->pObject, riid, result);
> +}
> +
I suspect this is a difference how moniker was created. If it was loaded
from stream, you might not have a usable pObject, only referencing string.
This has to be tested.
> +}
> +
> +static HRESULT WINAPI ObjrefMonikerImpl_IsRunning(IMoniker *iface, IBindCtx *pbc, IMoniker *left,
> + IMoniker *running)
> +{
> + TRACE("(%p,%p,%p,%p)\n", iface, pbc, left, running);
> +
> + return S_OK;
> +}
Same here, see documentation page for it.
> +
> +static HRESULT WINAPI ObjrefMonikerImpl_GetTimeOfLastChange(IMoniker *iface,
> + IBindCtx *pbc, IMoniker *left, FILETIME *time)
> +{
> + TRACE("(%p,%p,%p,%p)\n", iface, pbc, left, time);
> + return MK_E_UNAVAILABLE;
> +}
> +
> +static HRESULT WINAPI ObjrefMonikerImpl_Inverse(IMoniker *iface, IMoniker **moniker)
> +{
> + TRACE("(%p,%p)\n", iface, moniker);
> +
> + return CreateAntiMoniker(moniker);
> +}
> +
> +static HRESULT WINAPI ObjrefMonikerImpl_CommonPrefixWith(IMoniker *iface, IMoniker *other, IMoniker **prefix)
> +{
> + TRACE("(%p,%p,%p)\n", iface, other, prefix);
> +
> + if (!prefix || !other)
> + return E_INVALIDARG;
> +
> + *prefix = NULL;
> +
> + if (ObjrefMonikerImpl_IsEqual(iface, other) == S_OK)
> + {
> + IMoniker_AddRef(iface);
> +
> + *prefix = iface;
> +
> + return MK_S_US;
> + }
> + else
> + return MK_E_NOPREFIX;
> +}
This one is documented differently, if you don't need it, just leave a stub.
> +
> +static HRESULT WINAPI ObjrefMonikerImpl_ParseDisplayName(IMoniker *iface, IBindCtx *pbc,
> + IMoniker *left, LPOLESTR name, ULONG *eaten, IMoniker **out)
> +{
> + ObjrefMonikerImpl *moniker = objref_impl_from_IMoniker(iface);
> + HRESULT hr;
> + IParseDisplayName *pdn;
> +
> + TRACE("(%p,%p,%p,%p,%p,%p)\n", iface, pbc, left, name, eaten, out);
> +
> + if (left)
> + return MK_E_SYNTAX;
> +
> + if (!moniker->pObject)
> + return E_UNEXPECTED;
> +
> + hr = IUnknown_QueryInterface(moniker->pObject, &IID_IParseDisplayName, (void **)&pdn);
> + if (FAILED(hr))
> + return hr;
> +
> + hr = IParseDisplayName_ParseDisplayName(pdn, pbc, name, eaten, out);
> + IParseDisplayName_Release(pdn);
> +
> + return hr;
> +}
Any evidence of it actually doing this? In general, let's leave more
stubs than copies of pointer moniker methods, unless it's clearly a
right thing to do. For BindTo* methods that I suspect you actually need,
calling then semi-stub is better.
More information about the wine-devel
mailing list