winevulkan: Update to VK spec version 1.2.195.
[wine.git] / dlls / ole32 / pointermoniker.c
blob051d42aca6d8f35596a0703598601ee51a3a8d4e
1 /*
2 * Pointer Moniker 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 %u.\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 %u.\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,%d,%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, %x, %p, %x, %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, %d, %p, %#x, %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, %x, %p, %x.\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 = %#x.\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, %#x.\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;