mshtml: Implement MediaQueryList's matches prop.
[wine.git] / dlls / ole32 / pointermoniker.c
blob0beab94c649fc2b62a900c0d5d1e079c3a38e20d
1 /*
2 * Pointer and Objref Monikers Implementation
4 * Copyright 1999 Noomen Hamza
5 * Copyright 2008 Robert Shearman (for CodeWeavers)
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 #include <stdarg.h>
23 #include <string.h>
25 #define COBJMACROS
26 #define NONAMELESSUNION
28 #include "windef.h"
29 #include "winbase.h"
30 #include "winerror.h"
31 #include "winuser.h"
32 #include "objbase.h"
33 #include "oleidl.h"
34 #include "wine/debug.h"
35 #include "wine/heap.h"
36 #include "moniker.h"
38 WINE_DEFAULT_DEBUG_CHANNEL(ole);
40 /* PointerMoniker data structure */
41 typedef struct PointerMonikerImpl
43 IMoniker IMoniker_iface;
44 IMarshal IMarshal_iface;
46 LONG refcount;
48 IUnknown *pObject;
49 } PointerMonikerImpl;
51 static inline PointerMonikerImpl *impl_from_IMoniker(IMoniker *iface)
53 return CONTAINING_RECORD(iface, PointerMonikerImpl, IMoniker_iface);
56 static PointerMonikerImpl *impl_from_IMarshal(IMarshal *iface)
58 return CONTAINING_RECORD(iface, PointerMonikerImpl, IMarshal_iface);
61 static PointerMonikerImpl *unsafe_impl_from_IMoniker(IMoniker *iface);
63 static HRESULT WINAPI PointerMonikerImpl_QueryInterface(IMoniker *iface, REFIID riid, void **ppvObject)
65 PointerMonikerImpl *moniker = impl_from_IMoniker(iface);
67 TRACE("%p, %s, %p.\n", iface, debugstr_guid(riid), ppvObject);
69 if (!ppvObject)
70 return E_INVALIDARG;
72 *ppvObject = 0;
74 if (IsEqualIID(&IID_IUnknown, riid) ||
75 IsEqualIID(&IID_IPersist, riid) ||
76 IsEqualIID(&IID_IPersistStream, riid) ||
77 IsEqualIID(&IID_IMoniker, riid) ||
78 IsEqualGUID(&CLSID_PointerMoniker, riid))
80 *ppvObject = iface;
82 else if (IsEqualIID(&IID_IMarshal, riid))
83 *ppvObject = &moniker->IMarshal_iface;
85 if (!*ppvObject)
86 return E_NOINTERFACE;
88 IMoniker_AddRef(iface);
90 return S_OK;
93 static ULONG WINAPI PointerMonikerImpl_AddRef(IMoniker *iface)
95 PointerMonikerImpl *moniker = impl_from_IMoniker(iface);
96 ULONG refcount = InterlockedIncrement(&moniker->refcount);
98 TRACE("%p, refcount %lu.\n", iface, refcount);
100 return refcount;
103 static ULONG WINAPI PointerMonikerImpl_Release(IMoniker *iface)
105 PointerMonikerImpl *moniker = impl_from_IMoniker(iface);
106 ULONG refcount = InterlockedDecrement(&moniker->refcount);
108 TRACE("%p, refcount %lu.\n", iface, refcount);
110 if (!refcount)
112 if (moniker->pObject) IUnknown_Release(moniker->pObject);
113 heap_free(moniker);
116 return refcount;
119 /******************************************************************************
120 * PointerMoniker_GetClassID
121 ******************************************************************************/
122 static HRESULT WINAPI
123 PointerMonikerImpl_GetClassID(IMoniker* iface,CLSID *pClassID)
125 TRACE("(%p,%p)\n",iface,pClassID);
127 if (pClassID==NULL)
128 return E_POINTER;
130 *pClassID = CLSID_PointerMoniker;
132 return S_OK;
135 /******************************************************************************
136 * PointerMoniker_IsDirty
137 ******************************************************************************/
138 static HRESULT WINAPI
139 PointerMonikerImpl_IsDirty(IMoniker* iface)
141 /* Note that the OLE-provided implementations of the IPersistStream::IsDirty
142 method in the OLE-provided moniker interfaces always return S_FALSE because
143 their internal state never changes. */
145 TRACE("(%p)\n",iface);
147 return S_FALSE;
150 /******************************************************************************
151 * PointerMoniker_Load
152 ******************************************************************************/
153 static HRESULT WINAPI
154 PointerMonikerImpl_Load(IMoniker* iface,IStream* pStm)
156 TRACE("(%p)\n", pStm);
158 return E_NOTIMPL;
161 /******************************************************************************
162 * PointerMoniker_Save
163 ******************************************************************************/
164 static HRESULT WINAPI
165 PointerMonikerImpl_Save(IMoniker* iface, IStream* pStm, BOOL fClearDirty)
167 TRACE("(%p, %d)\n", pStm, fClearDirty);
169 return E_NOTIMPL;
172 /******************************************************************************
173 * PointerMoniker_GetSizeMax
175 * PARAMS
176 * pcbSize [out] Pointer to size of stream needed to save object
177 ******************************************************************************/
178 static HRESULT WINAPI
179 PointerMonikerImpl_GetSizeMax(IMoniker* iface, ULARGE_INTEGER* pcbSize)
181 TRACE("(%p,%p)\n",iface,pcbSize);
183 if (!pcbSize)
184 return E_POINTER;
186 pcbSize->u.LowPart = 0;
187 pcbSize->u.HighPart = 0;
189 return E_NOTIMPL;
192 /******************************************************************************
193 * PointerMoniker_BindToObject
194 ******************************************************************************/
195 static HRESULT WINAPI
196 PointerMonikerImpl_BindToObject(IMoniker* iface, IBindCtx* pbc, IMoniker* pmkToLeft,
197 REFIID riid, VOID** ppvResult)
199 PointerMonikerImpl *This = impl_from_IMoniker(iface);
201 TRACE("(%p,%p,%p,%s,%p)\n",iface,pbc,pmkToLeft,debugstr_guid(riid),ppvResult);
203 if (!This->pObject)
204 return E_UNEXPECTED;
206 return IUnknown_QueryInterface(This->pObject, riid, ppvResult);
209 /******************************************************************************
210 * PointerMoniker_BindToStorage
211 ******************************************************************************/
212 static HRESULT WINAPI
213 PointerMonikerImpl_BindToStorage(IMoniker* iface, IBindCtx* pbc, IMoniker* pmkToLeft,
214 REFIID riid, VOID** ppvResult)
216 PointerMonikerImpl *This = impl_from_IMoniker(iface);
218 TRACE("(%p,%p,%p,%s,%p)\n",iface,pbc,pmkToLeft,debugstr_guid(riid),ppvResult);
220 if (!This->pObject)
221 return E_UNEXPECTED;
223 return IUnknown_QueryInterface(This->pObject, riid, ppvResult);
226 /******************************************************************************
227 * PointerMoniker_Reduce
228 ******************************************************************************/
229 static HRESULT WINAPI
230 PointerMonikerImpl_Reduce(IMoniker* iface, IBindCtx* pbc, DWORD dwReduceHowFar,
231 IMoniker** ppmkToLeft, IMoniker** ppmkReduced)
233 TRACE("%p, %p, %ld, %p, %p.\n", iface, pbc, dwReduceHowFar, ppmkToLeft, ppmkReduced);
235 if (ppmkReduced==NULL)
236 return E_POINTER;
238 PointerMonikerImpl_AddRef(iface);
240 *ppmkReduced=iface;
242 return MK_S_REDUCED_TO_SELF;
245 static HRESULT WINAPI PointerMonikerImpl_ComposeWith(IMoniker *iface, IMoniker *right,
246 BOOL only_if_not_generic, IMoniker **result)
248 DWORD order;
250 TRACE("%p, %p, %d, %p.\n", iface, right, only_if_not_generic, result);
252 if (!result || !right)
253 return E_POINTER;
255 *result = NULL;
257 if (is_anti_moniker(right, &order))
258 return order > 1 ? create_anti_moniker(order - 1, result) : S_OK;
260 return only_if_not_generic ? MK_E_NEEDGENERIC : CreateGenericComposite(iface, right, result);
263 /******************************************************************************
264 * PointerMoniker_Enum
265 ******************************************************************************/
266 static HRESULT WINAPI PointerMonikerImpl_Enum(IMoniker *iface, BOOL fForward, IEnumMoniker **ppenumMoniker)
268 TRACE("%p, %d, %p.\n", iface, fForward, ppenumMoniker);
270 if (!ppenumMoniker)
271 return E_POINTER;
273 *ppenumMoniker = NULL;
275 return E_NOTIMPL;
278 /******************************************************************************
279 * PointerMoniker_IsEqual
280 ******************************************************************************/
281 static HRESULT WINAPI PointerMonikerImpl_IsEqual(IMoniker *iface, IMoniker *other)
283 PointerMonikerImpl *moniker = impl_from_IMoniker(iface), *other_moniker;
285 TRACE("%p, %p.\n", iface, other);
287 if (!other)
288 return E_INVALIDARG;
290 other_moniker = unsafe_impl_from_IMoniker(other);
291 if (!other_moniker)
292 return S_FALSE;
294 return moniker->pObject == other_moniker->pObject ? S_OK : S_FALSE;
297 /******************************************************************************
298 * PointerMoniker_Hash
299 ******************************************************************************/
300 static HRESULT WINAPI PointerMonikerImpl_Hash(IMoniker* iface,DWORD* pdwHash)
302 PointerMonikerImpl *This = impl_from_IMoniker(iface);
304 if (pdwHash==NULL)
305 return E_POINTER;
307 *pdwHash = PtrToUlong(This->pObject);
309 return S_OK;
312 /******************************************************************************
313 * PointerMoniker_IsRunning
314 ******************************************************************************/
315 static HRESULT WINAPI
316 PointerMonikerImpl_IsRunning(IMoniker* iface, IBindCtx* pbc, IMoniker* pmkToLeft,
317 IMoniker* pmkNewlyRunning)
319 TRACE("(%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,pmkNewlyRunning);
321 return S_OK;
324 /******************************************************************************
325 * PointerMoniker_GetTimeOfLastChange
326 ******************************************************************************/
327 static HRESULT WINAPI PointerMonikerImpl_GetTimeOfLastChange(IMoniker* iface,
328 IBindCtx* pbc,
329 IMoniker* pmkToLeft,
330 FILETIME* pAntiTime)
332 TRACE("(%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,pAntiTime);
333 return E_NOTIMPL;
336 /******************************************************************************
337 * PointerMoniker_Inverse
338 ******************************************************************************/
339 static HRESULT WINAPI
340 PointerMonikerImpl_Inverse(IMoniker* iface,IMoniker** ppmk)
342 TRACE("(%p,%p)\n",iface,ppmk);
344 return CreateAntiMoniker(ppmk);
347 /******************************************************************************
348 * PointerMoniker_CommonPrefixWith
349 ******************************************************************************/
350 static HRESULT WINAPI PointerMonikerImpl_CommonPrefixWith(IMoniker *iface, IMoniker *other, IMoniker **prefix)
352 TRACE("%p, %p, %p.\n", iface, other, prefix);
354 if (!prefix || !other)
355 return E_INVALIDARG;
357 *prefix = NULL;
359 if (PointerMonikerImpl_IsEqual(iface, other) == S_OK)
361 IMoniker_AddRef(iface);
363 *prefix = iface;
365 return MK_S_US;
367 else
368 return MK_E_NOPREFIX;
371 static HRESULT WINAPI PointerMonikerImpl_RelativePathTo(IMoniker *iface, IMoniker *other, IMoniker **result)
373 TRACE("%p, %p, %p.\n", iface, other, result);
375 if (!result)
376 return E_INVALIDARG;
378 *result = NULL;
380 return other ? E_NOTIMPL : E_INVALIDARG;
383 static HRESULT WINAPI PointerMonikerImpl_GetDisplayName(IMoniker *iface, IBindCtx *pbc,
384 IMoniker *toleft, LPOLESTR *name)
386 TRACE("%p, %p, %p, %p.\n", iface, pbc, toleft, name);
388 if (!name || !pbc)
390 if (name) *name = NULL;
391 return E_INVALIDARG;
394 return E_NOTIMPL;
397 /******************************************************************************
398 * PointerMoniker_ParseDisplayName
399 ******************************************************************************/
400 static HRESULT WINAPI
401 PointerMonikerImpl_ParseDisplayName(IMoniker* iface, IBindCtx* pbc,
402 IMoniker* pmkToLeft, LPOLESTR pszDisplayName,
403 ULONG* pchEaten, IMoniker** ppmkOut)
405 PointerMonikerImpl *This = impl_from_IMoniker(iface);
406 HRESULT hr;
407 IParseDisplayName *pPDN;
409 TRACE("(%p,%p,%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,pszDisplayName,pchEaten,ppmkOut);
411 if (pmkToLeft)
412 return MK_E_SYNTAX;
414 if (!This->pObject)
415 return E_UNEXPECTED;
417 hr = IUnknown_QueryInterface(This->pObject, &IID_IParseDisplayName, (void **)&pPDN);
418 if (FAILED(hr))
419 return hr;
421 hr = IParseDisplayName_ParseDisplayName(pPDN, pbc, pszDisplayName, pchEaten, ppmkOut);
422 IParseDisplayName_Release(pPDN);
424 return hr;
427 /******************************************************************************
428 * PointerMoniker_IsSystemMoniker
429 ******************************************************************************/
430 static HRESULT WINAPI
431 PointerMonikerImpl_IsSystemMoniker(IMoniker* iface,DWORD* pwdMksys)
433 TRACE("(%p,%p)\n",iface,pwdMksys);
435 if (!pwdMksys)
436 return E_POINTER;
438 *pwdMksys = MKSYS_POINTERMONIKER;
440 return S_OK;
443 /********************************************************************************/
444 /* Virtual function table for the PointerMonikerImpl class which include IPersist,*/
445 /* IPersistStream and IMoniker functions. */
446 static const IMonikerVtbl VT_PointerMonikerImpl =
448 PointerMonikerImpl_QueryInterface,
449 PointerMonikerImpl_AddRef,
450 PointerMonikerImpl_Release,
451 PointerMonikerImpl_GetClassID,
452 PointerMonikerImpl_IsDirty,
453 PointerMonikerImpl_Load,
454 PointerMonikerImpl_Save,
455 PointerMonikerImpl_GetSizeMax,
456 PointerMonikerImpl_BindToObject,
457 PointerMonikerImpl_BindToStorage,
458 PointerMonikerImpl_Reduce,
459 PointerMonikerImpl_ComposeWith,
460 PointerMonikerImpl_Enum,
461 PointerMonikerImpl_IsEqual,
462 PointerMonikerImpl_Hash,
463 PointerMonikerImpl_IsRunning,
464 PointerMonikerImpl_GetTimeOfLastChange,
465 PointerMonikerImpl_Inverse,
466 PointerMonikerImpl_CommonPrefixWith,
467 PointerMonikerImpl_RelativePathTo,
468 PointerMonikerImpl_GetDisplayName,
469 PointerMonikerImpl_ParseDisplayName,
470 PointerMonikerImpl_IsSystemMoniker
473 static PointerMonikerImpl *unsafe_impl_from_IMoniker(IMoniker *iface)
475 if (iface->lpVtbl != &VT_PointerMonikerImpl)
476 return NULL;
477 return CONTAINING_RECORD(iface, PointerMonikerImpl, IMoniker_iface);
480 static HRESULT WINAPI pointer_moniker_marshal_QueryInterface(IMarshal *iface, REFIID riid, LPVOID *ppv)
482 PointerMonikerImpl *moniker = impl_from_IMarshal(iface);
484 TRACE("%p, %s, %p.\n", iface, debugstr_guid(riid), ppv);
486 return IMoniker_QueryInterface(&moniker->IMoniker_iface, riid, ppv);
489 static ULONG WINAPI pointer_moniker_marshal_AddRef(IMarshal *iface)
491 PointerMonikerImpl *moniker = impl_from_IMarshal(iface);
493 TRACE("%p.\n",iface);
495 return IMoniker_AddRef(&moniker->IMoniker_iface);
498 static ULONG WINAPI pointer_moniker_marshal_Release(IMarshal *iface)
500 PointerMonikerImpl *moniker = impl_from_IMarshal(iface);
502 TRACE("%p.\n",iface);
504 return IMoniker_Release(&moniker->IMoniker_iface);
507 static HRESULT WINAPI pointer_moniker_marshal_GetUnmarshalClass(IMarshal *iface, REFIID riid, void *pv,
508 DWORD dwDestContext, void *pvDestContext, DWORD mshlflags, CLSID *clsid)
510 PointerMonikerImpl *moniker = impl_from_IMarshal(iface);
512 TRACE("%p, %s, %p, %lx, %p, %lx, %p.\n", iface, debugstr_guid(riid), pv, dwDestContext, pvDestContext,
513 mshlflags, clsid);
515 return IMoniker_GetClassID(&moniker->IMoniker_iface, clsid);
518 static HRESULT WINAPI pointer_moniker_marshal_GetMarshalSizeMax(IMarshal *iface, REFIID riid, void *pv,
519 DWORD dwDestContext, void *pvDestContext, DWORD mshlflags, DWORD *size)
521 PointerMonikerImpl *moniker = impl_from_IMarshal(iface);
523 TRACE("%p, %s, %p, %ld, %p, %#lx, %p.\n", iface, debugstr_guid(riid), pv, dwDestContext, pvDestContext,
524 mshlflags, size);
526 return CoGetMarshalSizeMax(size, &IID_IUnknown, moniker->pObject, dwDestContext, pvDestContext, mshlflags);
529 static HRESULT WINAPI pointer_moniker_marshal_MarshalInterface(IMarshal *iface, IStream *stream, REFIID riid,
530 void *pv, DWORD dwDestContext, void *pvDestContext, DWORD mshlflags)
532 PointerMonikerImpl *moniker = impl_from_IMarshal(iface);
534 TRACE("%p, %s, %p, %lx, %p, %lx.\n", stream, debugstr_guid(riid), pv,
535 dwDestContext, pvDestContext, mshlflags);
537 return CoMarshalInterface(stream, &IID_IUnknown, moniker->pObject, dwDestContext,
538 pvDestContext, mshlflags);
541 static HRESULT WINAPI pointer_moniker_marshal_UnmarshalInterface(IMarshal *iface, IStream *stream,
542 REFIID riid, void **ppv)
544 PointerMonikerImpl *moniker = impl_from_IMarshal(iface);
545 IUnknown *object;
546 HRESULT hr;
548 TRACE("%p, %p, %s, %p.\n", iface, stream, debugstr_guid(riid), ppv);
550 hr = CoUnmarshalInterface(stream, &IID_IUnknown, (void **)&object);
551 if (FAILED(hr))
553 ERR("Couldn't unmarshal moniker, hr = %#lx.\n", hr);
554 return hr;
557 if (moniker->pObject)
558 IUnknown_Release(moniker->pObject);
559 moniker->pObject = object;
561 return IMoniker_QueryInterface(&moniker->IMoniker_iface, riid, ppv);
564 static HRESULT WINAPI pointer_moniker_marshal_ReleaseMarshalData(IMarshal *iface, IStream *stream)
566 TRACE("%p, %p.\n", iface, stream);
568 return S_OK;
571 static HRESULT WINAPI pointer_moniker_marshal_DisconnectObject(IMarshal *iface, DWORD reserved)
573 TRACE("%p, %#lx.\n", iface, reserved);
575 return S_OK;
578 static const IMarshalVtbl pointer_moniker_marshal_vtbl =
580 pointer_moniker_marshal_QueryInterface,
581 pointer_moniker_marshal_AddRef,
582 pointer_moniker_marshal_Release,
583 pointer_moniker_marshal_GetUnmarshalClass,
584 pointer_moniker_marshal_GetMarshalSizeMax,
585 pointer_moniker_marshal_MarshalInterface,
586 pointer_moniker_marshal_UnmarshalInterface,
587 pointer_moniker_marshal_ReleaseMarshalData,
588 pointer_moniker_marshal_DisconnectObject
591 /***********************************************************************
592 * CreatePointerMoniker (OLE32.@)
594 HRESULT WINAPI CreatePointerMoniker(IUnknown *object, IMoniker **ret)
596 PointerMonikerImpl *moniker;
598 TRACE("(%p, %p)\n", object, ret);
600 if (!ret)
601 return E_INVALIDARG;
603 moniker = heap_alloc(sizeof(*moniker));
604 if (!moniker)
606 *ret = NULL;
607 return E_OUTOFMEMORY;
610 moniker->IMoniker_iface.lpVtbl = &VT_PointerMonikerImpl;
611 moniker->IMarshal_iface.lpVtbl = &pointer_moniker_marshal_vtbl;
612 moniker->refcount = 1;
613 moniker->pObject = object;
614 if (moniker->pObject)
615 IUnknown_AddRef(moniker->pObject);
617 *ret = &moniker->IMoniker_iface;
619 return S_OK;
622 HRESULT WINAPI PointerMoniker_CreateInstance(IClassFactory *iface,
623 IUnknown *pUnk, REFIID riid, void **ppv)
625 IMoniker *pMoniker;
626 HRESULT hr;
628 TRACE("(%p, %s, %p)\n", pUnk, debugstr_guid(riid), ppv);
630 *ppv = NULL;
632 if (pUnk)
633 return CLASS_E_NOAGGREGATION;
635 hr = CreatePointerMoniker(NULL, &pMoniker);
636 if (FAILED(hr))
637 return hr;
639 hr = IMoniker_QueryInterface(pMoniker, riid, ppv);
640 IMoniker_Release(pMoniker);
642 return hr;
645 /* ObjrefMoniker implementation */
647 typedef struct
649 IMoniker IMoniker_iface;
650 IMarshal IMarshal_iface;
652 LONG refcount;
654 IUnknown *pObject;
655 } ObjrefMonikerImpl;
657 static inline ObjrefMonikerImpl *objref_impl_from_IMoniker(IMoniker *iface)
659 return CONTAINING_RECORD(iface, ObjrefMonikerImpl, IMoniker_iface);
662 static ObjrefMonikerImpl *objref_impl_from_IMarshal(IMarshal *iface)
664 return CONTAINING_RECORD(iface, ObjrefMonikerImpl, IMarshal_iface);
667 static HRESULT WINAPI ObjrefMonikerImpl_QueryInterface(IMoniker *iface, REFIID iid, void **obj)
669 ObjrefMonikerImpl *moniker = objref_impl_from_IMoniker(iface);
671 TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), obj);
673 if (!obj)
674 return E_INVALIDARG;
676 *obj = 0;
678 if (IsEqualIID(iid, &IID_IUnknown) ||
679 IsEqualIID(iid, &IID_IPersist) ||
680 IsEqualIID(iid, &IID_IPersistStream) ||
681 IsEqualIID(iid, &IID_IMoniker) ||
682 IsEqualGUID(iid, &CLSID_ObjrefMoniker) ||
683 IsEqualGUID(iid, &CLSID_PointerMoniker))
685 *obj = iface;
687 else if (IsEqualIID(iid, &IID_IMarshal))
688 *obj = &moniker->IMarshal_iface;
689 else
690 return E_NOINTERFACE;
692 IMoniker_AddRef(iface);
694 return S_OK;
697 static ULONG WINAPI ObjrefMonikerImpl_AddRef(IMoniker *iface)
699 ObjrefMonikerImpl *moniker = objref_impl_from_IMoniker(iface);
700 ULONG refcount = InterlockedIncrement(&moniker->refcount);
702 TRACE("%p, refcount %lu\n", iface, refcount);
704 return refcount;
707 static ULONG WINAPI ObjrefMonikerImpl_Release(IMoniker *iface)
709 ObjrefMonikerImpl *moniker = objref_impl_from_IMoniker(iface);
710 ULONG refcount = InterlockedDecrement(&moniker->refcount);
712 TRACE("%p, refcount %lu\n", iface, refcount);
714 if (!refcount)
716 if (moniker->pObject) IUnknown_Release(moniker->pObject);
717 heap_free(moniker);
720 return refcount;
723 static HRESULT WINAPI ObjrefMonikerImpl_GetClassID(IMoniker *iface, CLSID *clsid)
725 TRACE("(%p,%p)\n", iface, clsid);
727 if (!clsid)
728 return E_POINTER;
730 *clsid = CLSID_ObjrefMoniker;
731 return S_OK;
734 static HRESULT WINAPI ObjrefMonikerImpl_IsDirty(IMoniker *iface)
736 FIXME("(%p): stub\n", iface);
737 return S_FALSE;
740 static HRESULT WINAPI ObjrefMonikerImpl_Load(IMoniker *iface, IStream *stream)
742 FIXME("(%p,%p): stub\n", iface, stream);
743 return E_NOTIMPL;
746 static HRESULT WINAPI ObjrefMonikerImpl_Save(IMoniker *iface, IStream *stream, BOOL dirty)
748 FIXME("(%p,%p,%d): stub\n", iface, stream, dirty);
749 return E_NOTIMPL;
752 static HRESULT WINAPI ObjrefMonikerImpl_GetSizeMax(IMoniker *iface, ULARGE_INTEGER *size)
754 FIXME("(%p,%p): stub\n", iface, size);
755 return E_NOTIMPL;
758 static HRESULT WINAPI ObjrefMonikerImpl_BindToObject(IMoniker *iface, IBindCtx *pbc, IMoniker *left,
759 REFIID riid, void **result)
761 FIXME("(%p,%p,%p,%s,%p): stub\n", iface, pbc, left, debugstr_guid(riid), result);
762 return E_NOTIMPL;
765 static HRESULT WINAPI ObjrefMonikerImpl_BindToStorage(IMoniker *iface, IBindCtx *pbc, IMoniker *left,
766 REFIID riid, void **result)
768 FIXME("(%p,%p,%p,%s,%p): stub\n", iface, pbc, left, debugstr_guid(riid), result);
769 return E_NOTIMPL;
772 static HRESULT WINAPI ObjrefMonikerImpl_Reduce(IMoniker *iface, IBindCtx *pbc, DWORD howfar,
773 IMoniker **left, IMoniker **reduced)
775 FIXME("%p, %p, %ld, %p, %p: stub\n", iface, pbc, howfar, left, reduced);
776 return E_NOTIMPL;
779 static HRESULT WINAPI ObjrefMonikerImpl_ComposeWith(IMoniker *iface, IMoniker *right,
780 BOOL only_if_not_generic, IMoniker **result)
782 FIXME("(%p,%p,%d,%p): stub\n", iface, right, only_if_not_generic, result);
783 return E_NOTIMPL;
786 static HRESULT WINAPI ObjrefMonikerImpl_Enum(IMoniker *iface, BOOL forward, IEnumMoniker **enummoniker)
788 TRACE("(%p,%d,%p)\n", iface, forward, enummoniker);
790 if (!enummoniker)
791 return E_POINTER;
793 *enummoniker = NULL;
794 return S_OK;
797 static HRESULT WINAPI ObjrefMonikerImpl_IsEqual(IMoniker *iface, IMoniker *other)
799 FIXME("(%p,%p): stub\n", iface, other);
800 return E_NOTIMPL;
803 static HRESULT WINAPI ObjrefMonikerImpl_Hash(IMoniker *iface, DWORD *hash)
805 ObjrefMonikerImpl *moniker = objref_impl_from_IMoniker(iface);
807 TRACE("(%p,%p)\n", iface, hash);
809 if (!hash)
810 return E_POINTER;
812 *hash = PtrToUlong(moniker->pObject);
814 return S_OK;
817 static HRESULT WINAPI ObjrefMonikerImpl_IsRunning(IMoniker *iface, IBindCtx *pbc, IMoniker *left,
818 IMoniker *running)
820 FIXME("(%p,%p,%p,%p): stub\n", iface, pbc, left, running);
821 return E_NOTIMPL;
824 static HRESULT WINAPI ObjrefMonikerImpl_GetTimeOfLastChange(IMoniker *iface,
825 IBindCtx *pbc, IMoniker *left, FILETIME *time)
827 FIXME("(%p,%p,%p,%p): stub\n", iface, pbc, left, time);
828 return MK_E_UNAVAILABLE;
831 static HRESULT WINAPI ObjrefMonikerImpl_Inverse(IMoniker *iface, IMoniker **moniker)
833 FIXME("(%p,%p): stub\n", iface, moniker);
834 return E_NOTIMPL;
837 static HRESULT WINAPI ObjrefMonikerImpl_CommonPrefixWith(IMoniker *iface, IMoniker *other, IMoniker **prefix)
839 FIXME("(%p,%p,%p): stub\n", iface, other, prefix);
840 return E_NOTIMPL;
843 static HRESULT WINAPI ObjrefMonikerImpl_RelativePathTo(IMoniker *iface, IMoniker *other, IMoniker **result)
845 FIXME("(%p,%p,%p): stub\n", iface, other, result);
846 return E_NOTIMPL;
849 static HRESULT WINAPI ObjrefMonikerImpl_GetDisplayName(IMoniker *iface, IBindCtx *pbc,
850 IMoniker *left, LPOLESTR *name)
852 FIXME("(%p,%p,%p,%p): stub\n", iface, pbc, left, name);
853 return E_NOTIMPL;
856 static HRESULT WINAPI ObjrefMonikerImpl_ParseDisplayName(IMoniker *iface, IBindCtx *pbc,
857 IMoniker *left, LPOLESTR name, ULONG *eaten, IMoniker **out)
859 FIXME("(%p,%p,%p,%p,%p,%p): stub\n", iface, pbc, left, name, eaten, out);
860 return E_NOTIMPL;
863 static HRESULT WINAPI ObjrefMonikerImpl_IsSystemMoniker(IMoniker *iface, DWORD *mksys)
865 TRACE("(%p,%p)\n", iface, mksys);
867 if (!mksys)
868 return E_POINTER;
870 *mksys = MKSYS_OBJREFMONIKER;
871 return S_OK;
874 static const IMonikerVtbl VT_ObjrefMonikerImpl =
876 ObjrefMonikerImpl_QueryInterface,
877 ObjrefMonikerImpl_AddRef,
878 ObjrefMonikerImpl_Release,
879 ObjrefMonikerImpl_GetClassID,
880 ObjrefMonikerImpl_IsDirty,
881 ObjrefMonikerImpl_Load,
882 ObjrefMonikerImpl_Save,
883 ObjrefMonikerImpl_GetSizeMax,
884 ObjrefMonikerImpl_BindToObject,
885 ObjrefMonikerImpl_BindToStorage,
886 ObjrefMonikerImpl_Reduce,
887 ObjrefMonikerImpl_ComposeWith,
888 ObjrefMonikerImpl_Enum,
889 ObjrefMonikerImpl_IsEqual,
890 ObjrefMonikerImpl_Hash,
891 ObjrefMonikerImpl_IsRunning,
892 ObjrefMonikerImpl_GetTimeOfLastChange,
893 ObjrefMonikerImpl_Inverse,
894 ObjrefMonikerImpl_CommonPrefixWith,
895 ObjrefMonikerImpl_RelativePathTo,
896 ObjrefMonikerImpl_GetDisplayName,
897 ObjrefMonikerImpl_ParseDisplayName,
898 ObjrefMonikerImpl_IsSystemMoniker
901 static HRESULT WINAPI objref_moniker_marshal_QueryInterface(IMarshal *iface, REFIID riid, LPVOID *ppv)
903 ObjrefMonikerImpl *moniker = objref_impl_from_IMarshal(iface);
905 TRACE("(%p,%s,%p)\n", iface, debugstr_guid(riid), ppv);
907 return IMoniker_QueryInterface(&moniker->IMoniker_iface, riid, ppv);
910 static ULONG WINAPI objref_moniker_marshal_AddRef(IMarshal *iface)
912 ObjrefMonikerImpl *moniker = objref_impl_from_IMarshal(iface);
914 TRACE("(%p)\n", iface);
916 return IMoniker_AddRef(&moniker->IMoniker_iface);
919 static ULONG WINAPI objref_moniker_marshal_Release(IMarshal *iface)
921 ObjrefMonikerImpl *moniker = objref_impl_from_IMarshal(iface);
923 TRACE("(%p)\n", iface);
925 return IMoniker_Release(&moniker->IMoniker_iface);
928 static HRESULT WINAPI objref_moniker_marshal_GetUnmarshalClass(IMarshal *iface, REFIID riid, void *pv,
929 DWORD dwDestContext, void *pvDestContext, DWORD mshlflags, CLSID *clsid)
931 ObjrefMonikerImpl *moniker = objref_impl_from_IMarshal(iface);
933 TRACE("%p, %s, %p, %#lx, %p, %#lx, %p.\n", iface, debugstr_guid(riid), pv, dwDestContext, pvDestContext,
934 mshlflags, clsid);
936 return IMoniker_GetClassID(&moniker->IMoniker_iface, clsid);
939 static HRESULT WINAPI objref_moniker_marshal_GetMarshalSizeMax(IMarshal *iface, REFIID riid, void *pv,
940 DWORD dwDestContext, void *pvDestContext, DWORD mshlflags, DWORD *size)
942 ObjrefMonikerImpl *moniker = objref_impl_from_IMarshal(iface);
944 TRACE("%p, %s, %p, %#lx, %p, %#lx, %p.\n", iface, debugstr_guid(riid), pv, dwDestContext, pvDestContext,
945 mshlflags, size);
947 return CoGetMarshalSizeMax(size, &IID_IUnknown, moniker->pObject, dwDestContext, pvDestContext, mshlflags);
950 static HRESULT WINAPI objref_moniker_marshal_MarshalInterface(IMarshal *iface, IStream *stream, REFIID riid,
951 void *pv, DWORD dwDestContext, void *pvDestContext, DWORD mshlflags)
953 ObjrefMonikerImpl *moniker = objref_impl_from_IMarshal(iface);
955 TRACE("%p, %s, %p, %#lx, %p, %#lx\n", stream, debugstr_guid(riid), pv, dwDestContext, pvDestContext, mshlflags);
957 return CoMarshalInterface(stream, &IID_IUnknown, moniker->pObject, dwDestContext, pvDestContext, mshlflags);
960 static HRESULT WINAPI objref_moniker_marshal_UnmarshalInterface(IMarshal *iface, IStream *stream,
961 REFIID riid, void **ppv)
963 ObjrefMonikerImpl *moniker = objref_impl_from_IMarshal(iface);
964 IUnknown *object;
965 HRESULT hr;
967 TRACE("(%p,%p,%s,%p)\n", iface, stream, debugstr_guid(riid), ppv);
969 hr = CoUnmarshalInterface(stream, &IID_IUnknown, (void **)&object);
970 if (FAILED(hr))
972 ERR("Couldn't unmarshal moniker, hr = %#lx.\n", hr);
973 return hr;
976 if (moniker->pObject)
977 IUnknown_Release(moniker->pObject);
978 moniker->pObject = object;
980 return IMoniker_QueryInterface(&moniker->IMoniker_iface, riid, ppv);
983 static HRESULT WINAPI objref_moniker_marshal_ReleaseMarshalData(IMarshal *iface, IStream *stream)
985 TRACE("(%p,%p)\n", iface, stream);
986 return S_OK;
989 static HRESULT WINAPI objref_moniker_marshal_DisconnectObject(IMarshal *iface, DWORD reserved)
991 TRACE("%p, %#lx.\n", iface, reserved);
992 return S_OK;
995 static const IMarshalVtbl objref_moniker_marshal_vtbl =
997 objref_moniker_marshal_QueryInterface,
998 objref_moniker_marshal_AddRef,
999 objref_moniker_marshal_Release,
1000 objref_moniker_marshal_GetUnmarshalClass,
1001 objref_moniker_marshal_GetMarshalSizeMax,
1002 objref_moniker_marshal_MarshalInterface,
1003 objref_moniker_marshal_UnmarshalInterface,
1004 objref_moniker_marshal_ReleaseMarshalData,
1005 objref_moniker_marshal_DisconnectObject
1008 /***********************************************************************
1009 * CreateObjrefMoniker (OLE32.@)
1011 HRESULT WINAPI CreateObjrefMoniker(IUnknown *obj, IMoniker **ret)
1013 ObjrefMonikerImpl *moniker;
1015 TRACE("(%p,%p)\n", obj, ret);
1017 if (!ret)
1018 return E_INVALIDARG;
1020 moniker = heap_alloc(sizeof(*moniker));
1021 if (!moniker)
1023 *ret = NULL;
1024 return E_OUTOFMEMORY;
1027 moniker->IMoniker_iface.lpVtbl = &VT_ObjrefMonikerImpl;
1028 moniker->IMarshal_iface.lpVtbl = &objref_moniker_marshal_vtbl;
1029 moniker->refcount = 1;
1030 moniker->pObject = obj;
1031 if (moniker->pObject)
1032 IUnknown_AddRef(moniker->pObject);
1034 *ret = &moniker->IMoniker_iface;
1036 return S_OK;
1039 HRESULT WINAPI ObjrefMoniker_CreateInstance(IClassFactory *iface, IUnknown *unk, REFIID iid, void **obj)
1041 IMoniker *moniker;
1042 HRESULT hr;
1044 TRACE("(%p,%s,%p)\n", unk, debugstr_guid(iid), obj);
1046 *obj = NULL;
1048 if (unk)
1049 return CLASS_E_NOAGGREGATION;
1051 hr = CreateObjrefMoniker(NULL, &moniker);
1052 if (FAILED(hr))
1053 return hr;
1055 hr = IMoniker_QueryInterface(moniker, iid, obj);
1056 IMoniker_Release(moniker);
1058 return hr;