Release 0.9.14.
[wine/multimedia.git] / dlls / ole32 / antimoniker.c
blob25007c331b31c16fc86da6acacbe644dd9d99496
1 /*
2 * AntiMonikers implementation
4 * Copyright 1999 Noomen Hamza
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #include <assert.h>
22 #include <stdarg.h>
23 #include <string.h>
25 #define COBJMACROS
26 #define NONAMELESSUNION
27 #define NONAMELESSSTRUCT
29 #include "windef.h"
30 #include "winbase.h"
31 #include "winerror.h"
32 #include "objbase.h"
33 #include "wine/debug.h"
34 #include "moniker.h"
36 WINE_DEFAULT_DEBUG_CHANNEL(ole);
38 const CLSID CLSID_AntiMoniker = {
39 0x305, 0, 0, {0xC0, 0, 0, 0, 0, 0, 0, 0x46}
42 /* AntiMoniker data structure */
43 typedef struct AntiMonikerImpl{
45 const IMonikerVtbl* lpvtbl1; /* VTable relative to the IMoniker interface.*/
47 /* The ROT (RunningObjectTable implementation) uses the IROTData interface to test whether
48 * two monikers are equal. That's whay IROTData interface is implemented by monikers.
50 const IROTDataVtbl* lpvtbl2; /* VTable relative to the IROTData interface.*/
52 LONG ref; /* reference counter for this object */
54 IUnknown *pMarshal; /* custom marshaler */
55 } AntiMonikerImpl;
57 static inline IMoniker *impl_from_IROTData( IROTData *iface )
59 return (IMoniker *)((char*)iface - FIELD_OFFSET(AntiMonikerImpl, lpvtbl2));
63 /*******************************************************************************
64 * AntiMoniker_QueryInterface
65 *******************************************************************************/
66 static HRESULT WINAPI
67 AntiMonikerImpl_QueryInterface(IMoniker* iface,REFIID riid,void** ppvObject)
69 AntiMonikerImpl *This = (AntiMonikerImpl *)iface;
71 TRACE("(%p,%p,%p)\n",This,riid,ppvObject);
73 /* Perform a sanity check on the parameters.*/
74 if ( (This==0) || (ppvObject==0) )
75 return E_INVALIDARG;
77 /* Initialize the return parameter */
78 *ppvObject = 0;
80 /* Compare the riid with the interface IDs implemented by this object.*/
81 if (IsEqualIID(&IID_IUnknown, riid) ||
82 IsEqualIID(&IID_IPersist, riid) ||
83 IsEqualIID(&IID_IPersistStream, riid) ||
84 IsEqualIID(&IID_IMoniker, riid))
85 *ppvObject = iface;
86 else if (IsEqualIID(&IID_IROTData, riid))
87 *ppvObject = (IROTData*)&(This->lpvtbl2);
88 else if (IsEqualIID(&IID_IMarshal, riid))
90 HRESULT hr = S_OK;
91 if (!This->pMarshal)
92 hr = MonikerMarshal_Create(iface, &This->pMarshal);
93 if (hr != S_OK)
94 return hr;
95 return IUnknown_QueryInterface(This->pMarshal, riid, ppvObject);
98 /* Check that we obtained an interface.*/
99 if ((*ppvObject)==0)
100 return E_NOINTERFACE;
102 /* always increase the reference count by one when it is successful */
103 IMoniker_AddRef(iface);
105 return S_OK;
108 /******************************************************************************
109 * AntiMoniker_AddRef
110 ******************************************************************************/
111 static ULONG WINAPI
112 AntiMonikerImpl_AddRef(IMoniker* iface)
114 AntiMonikerImpl *This = (AntiMonikerImpl *)iface;
116 TRACE("(%p)\n",This);
118 return InterlockedIncrement(&This->ref);
121 /******************************************************************************
122 * AntiMoniker_Release
123 ******************************************************************************/
124 static ULONG WINAPI
125 AntiMonikerImpl_Release(IMoniker* iface)
127 AntiMonikerImpl *This = (AntiMonikerImpl *)iface;
128 ULONG ref;
130 TRACE("(%p)\n",This);
132 ref = InterlockedDecrement(&This->ref);
134 /* destroy the object if there's no more reference on it */
135 if (ref == 0)
137 if (This->pMarshal) IUnknown_Release(This->pMarshal);
138 HeapFree(GetProcessHeap(),0,This);
141 return ref;
144 /******************************************************************************
145 * AntiMoniker_GetClassID
146 ******************************************************************************/
147 static HRESULT WINAPI
148 AntiMonikerImpl_GetClassID(IMoniker* iface,CLSID *pClassID)
150 TRACE("(%p,%p)\n",iface,pClassID);
152 if (pClassID==NULL)
153 return E_POINTER;
155 *pClassID = CLSID_AntiMoniker;
157 return S_OK;
160 /******************************************************************************
161 * AntiMoniker_IsDirty
162 ******************************************************************************/
163 static HRESULT WINAPI
164 AntiMonikerImpl_IsDirty(IMoniker* iface)
166 /* Note that the OLE-provided implementations of the IPersistStream::IsDirty
167 method in the OLE-provided moniker interfaces always return S_FALSE because
168 their internal state never changes. */
170 TRACE("(%p)\n",iface);
172 return S_FALSE;
175 /******************************************************************************
176 * AntiMoniker_Load
177 ******************************************************************************/
178 static HRESULT WINAPI
179 AntiMonikerImpl_Load(IMoniker* iface,IStream* pStm)
181 DWORD constant=1,dwbuffer;
182 HRESULT res;
184 /* data read by this function is only a DWORD constant (must be 1) ! */
185 res=IStream_Read(pStm,&dwbuffer,sizeof(DWORD),NULL);
187 if (SUCCEEDED(res)&& dwbuffer!=constant)
188 return E_FAIL;
190 return res;
193 /******************************************************************************
194 * AntiMoniker_Save
195 ******************************************************************************/
196 static HRESULT WINAPI
197 AntiMonikerImpl_Save(IMoniker* iface,IStream* pStm,BOOL fClearDirty)
199 DWORD constant=1;
200 HRESULT res;
202 /* data written by this function is only a DWORD constant set to 1 ! */
203 res=IStream_Write(pStm,&constant,sizeof(constant),NULL);
205 return res;
208 /******************************************************************************
209 * AntiMoniker_GetSizeMax
211 * PARAMS
212 * pcbSize [out] Pointer to size of stream needed to save object
213 ******************************************************************************/
214 static HRESULT WINAPI
215 AntiMonikerImpl_GetSizeMax(IMoniker* iface, ULARGE_INTEGER* pcbSize)
217 TRACE("(%p,%p)\n",iface,pcbSize);
219 if (!pcbSize)
220 return E_POINTER;
222 /* for more details see AntiMonikerImpl_Save coments */
225 * Normally the sizemax must be sizeof DWORD, but
226 * I tested this function it usually return 16 bytes
227 * more than the number of bytes used by AntiMoniker::Save function
229 pcbSize->u.LowPart = sizeof(DWORD)+16;
231 pcbSize->u.HighPart=0;
233 return S_OK;
236 /******************************************************************************
237 * AntiMoniker_BindToObject
238 ******************************************************************************/
239 static HRESULT WINAPI
240 AntiMonikerImpl_BindToObject(IMoniker* iface, IBindCtx* pbc, IMoniker* pmkToLeft,
241 REFIID riid, VOID** ppvResult)
243 TRACE("(%p,%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,riid,ppvResult);
244 return E_NOTIMPL;
247 /******************************************************************************
248 * AntiMoniker_BindToStorage
249 ******************************************************************************/
250 static HRESULT WINAPI
251 AntiMonikerImpl_BindToStorage(IMoniker* iface, IBindCtx* pbc, IMoniker* pmkToLeft,
252 REFIID riid, VOID** ppvResult)
254 TRACE("(%p,%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,riid,ppvResult);
255 return E_NOTIMPL;
258 /******************************************************************************
259 * AntiMoniker_Reduce
260 ******************************************************************************/
261 static HRESULT WINAPI
262 AntiMonikerImpl_Reduce(IMoniker* iface, IBindCtx* pbc, DWORD dwReduceHowFar,
263 IMoniker** ppmkToLeft, IMoniker** ppmkReduced)
265 TRACE("(%p,%p,%ld,%p,%p)\n",iface,pbc,dwReduceHowFar,ppmkToLeft,ppmkReduced);
267 if (ppmkReduced==NULL)
268 return E_POINTER;
270 AntiMonikerImpl_AddRef(iface);
272 *ppmkReduced=iface;
274 return MK_S_REDUCED_TO_SELF;
276 /******************************************************************************
277 * AntiMoniker_ComposeWith
278 ******************************************************************************/
279 static HRESULT WINAPI
280 AntiMonikerImpl_ComposeWith(IMoniker* iface, IMoniker* pmkRight,
281 BOOL fOnlyIfNotGeneric, IMoniker** ppmkComposite)
284 TRACE("(%p,%p,%d,%p)\n",iface,pmkRight,fOnlyIfNotGeneric,ppmkComposite);
286 if ((ppmkComposite==NULL)||(pmkRight==NULL))
287 return E_POINTER;
289 *ppmkComposite=0;
291 if (fOnlyIfNotGeneric)
292 return MK_E_NEEDGENERIC;
293 else
294 return CreateGenericComposite(iface,pmkRight,ppmkComposite);
297 /******************************************************************************
298 * AntiMoniker_Enum
299 ******************************************************************************/
300 static HRESULT WINAPI
301 AntiMonikerImpl_Enum(IMoniker* iface,BOOL fForward, IEnumMoniker** ppenumMoniker)
303 TRACE("(%p,%d,%p)\n",iface,fForward,ppenumMoniker);
305 if (ppenumMoniker == NULL)
306 return E_POINTER;
308 *ppenumMoniker = NULL;
310 return S_OK;
313 /******************************************************************************
314 * AntiMoniker_IsEqual
315 ******************************************************************************/
316 static HRESULT WINAPI
317 AntiMonikerImpl_IsEqual(IMoniker* iface,IMoniker* pmkOtherMoniker)
319 DWORD mkSys;
321 TRACE("(%p,%p)\n",iface,pmkOtherMoniker);
323 if (pmkOtherMoniker==NULL)
324 return S_FALSE;
326 IMoniker_IsSystemMoniker(pmkOtherMoniker,&mkSys);
328 if (mkSys==MKSYS_ANTIMONIKER)
329 return S_OK;
330 else
331 return S_FALSE;
334 /******************************************************************************
335 * AntiMoniker_Hash
336 ******************************************************************************/
337 static HRESULT WINAPI AntiMonikerImpl_Hash(IMoniker* iface,DWORD* pdwHash)
339 if (pdwHash==NULL)
340 return E_POINTER;
342 *pdwHash = 0x80000001;
344 return S_OK;
347 /******************************************************************************
348 * AntiMoniker_IsRunning
349 ******************************************************************************/
350 static HRESULT WINAPI
351 AntiMonikerImpl_IsRunning(IMoniker* iface, IBindCtx* pbc, IMoniker* pmkToLeft,
352 IMoniker* pmkNewlyRunning)
354 IRunningObjectTable* rot;
355 HRESULT res;
357 TRACE("(%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,pmkNewlyRunning);
359 if (pbc==NULL)
360 return E_INVALIDARG;
362 res=IBindCtx_GetRunningObjectTable(pbc,&rot);
364 if (FAILED(res))
365 return res;
367 res = IRunningObjectTable_IsRunning(rot,iface);
369 IRunningObjectTable_Release(rot);
371 return res;
374 /******************************************************************************
375 * AntiMoniker_GetTimeOfLastChange
376 ******************************************************************************/
377 static HRESULT WINAPI AntiMonikerImpl_GetTimeOfLastChange(IMoniker* iface,
378 IBindCtx* pbc,
379 IMoniker* pmkToLeft,
380 FILETIME* pAntiTime)
382 TRACE("(%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,pAntiTime);
383 return E_NOTIMPL;
386 /******************************************************************************
387 * AntiMoniker_Inverse
388 ******************************************************************************/
389 static HRESULT WINAPI
390 AntiMonikerImpl_Inverse(IMoniker* iface,IMoniker** ppmk)
392 TRACE("(%p,%p)\n",iface,ppmk);
394 if (ppmk==NULL)
395 return E_POINTER;
397 *ppmk=0;
399 return MK_E_NOINVERSE;
402 /******************************************************************************
403 * AntiMoniker_CommonPrefixWith
404 ******************************************************************************/
405 static HRESULT WINAPI
406 AntiMonikerImpl_CommonPrefixWith(IMoniker* iface,IMoniker* pmkOther,IMoniker** ppmkPrefix)
408 DWORD mkSys;
410 IMoniker_IsSystemMoniker(pmkOther,&mkSys);
412 if(mkSys==MKSYS_ANTIMONIKER){
414 IMoniker_AddRef(iface);
416 *ppmkPrefix=iface;
418 IMoniker_AddRef(iface);
420 return MK_S_US;
422 else
423 return MonikerCommonPrefixWith(iface,pmkOther,ppmkPrefix);
426 /******************************************************************************
427 * AntiMoniker_RelativePathTo
428 ******************************************************************************/
429 static HRESULT WINAPI
430 AntiMonikerImpl_RelativePathTo(IMoniker* iface,IMoniker* pmOther, IMoniker** ppmkRelPath)
432 TRACE("(%p,%p,%p)\n",iface,pmOther,ppmkRelPath);
434 if (ppmkRelPath==NULL)
435 return E_POINTER;
437 IMoniker_AddRef(pmOther);
439 *ppmkRelPath=pmOther;
441 return MK_S_HIM;
444 /******************************************************************************
445 * AntiMoniker_GetDisplayName
446 ******************************************************************************/
447 static HRESULT WINAPI
448 AntiMonikerImpl_GetDisplayName(IMoniker* iface, IBindCtx* pbc,
449 IMoniker* pmkToLeft, LPOLESTR *ppszDisplayName)
451 static const WCHAR back[]={'\\','.','.',0};
453 TRACE("(%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,ppszDisplayName);
455 if (ppszDisplayName==NULL)
456 return E_POINTER;
458 if (pmkToLeft!=NULL){
459 FIXME("() pmkToLeft!=NULL not implemented\n");
460 return E_NOTIMPL;
463 *ppszDisplayName=CoTaskMemAlloc(sizeof(back));
465 if (*ppszDisplayName==NULL)
466 return E_OUTOFMEMORY;
468 lstrcpyW(*ppszDisplayName,back);
470 return S_OK;
473 /******************************************************************************
474 * AntiMoniker_ParseDisplayName
475 ******************************************************************************/
476 static HRESULT WINAPI
477 AntiMonikerImpl_ParseDisplayName(IMoniker* iface, IBindCtx* pbc,
478 IMoniker* pmkToLeft, LPOLESTR pszDisplayName,
479 ULONG* pchEaten, IMoniker** ppmkOut)
481 TRACE("(%p,%p,%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,pszDisplayName,pchEaten,ppmkOut);
482 return E_NOTIMPL;
485 /******************************************************************************
486 * AntiMoniker_IsSystemMoniker
487 ******************************************************************************/
488 static HRESULT WINAPI
489 AntiMonikerImpl_IsSystemMoniker(IMoniker* iface,DWORD* pwdMksys)
491 TRACE("(%p,%p)\n",iface,pwdMksys);
493 if (!pwdMksys)
494 return E_POINTER;
496 (*pwdMksys)=MKSYS_ANTIMONIKER;
498 return S_OK;
501 /*******************************************************************************
502 * AntiMonikerIROTData_QueryInterface
503 *******************************************************************************/
504 static HRESULT WINAPI
505 AntiMonikerROTDataImpl_QueryInterface(IROTData *iface,REFIID riid,VOID** ppvObject)
507 IMoniker *This = impl_from_IROTData(iface);
509 TRACE("(%p,%p,%p)\n",iface,riid,ppvObject);
511 return AntiMonikerImpl_QueryInterface(This, riid, ppvObject);
514 /***********************************************************************
515 * AntiMonikerIROTData_AddRef
517 static ULONG WINAPI AntiMonikerROTDataImpl_AddRef(IROTData *iface)
519 IMoniker *This = impl_from_IROTData(iface);
521 TRACE("(%p)\n",iface);
523 return AntiMonikerImpl_AddRef(This);
526 /***********************************************************************
527 * AntiMonikerIROTData_Release
529 static ULONG WINAPI AntiMonikerROTDataImpl_Release(IROTData* iface)
531 IMoniker *This = impl_from_IROTData(iface);
533 TRACE("(%p)\n",iface);
535 return AntiMonikerImpl_Release(This);
538 /******************************************************************************
539 * AntiMonikerIROTData_GetComparaisonData
540 ******************************************************************************/
541 static HRESULT WINAPI
542 AntiMonikerROTDataImpl_GetComparisonData(IROTData* iface, BYTE* pbData,
543 ULONG cbMax, ULONG* pcbData)
545 DWORD constant = 1;
547 TRACE("(%p, %lu, %p)\n", pbData, cbMax, pcbData);
549 *pcbData = sizeof(CLSID) + sizeof(DWORD);
550 if (cbMax < *pcbData)
551 return E_OUTOFMEMORY;
553 memcpy(pbData, &CLSID_AntiMoniker, sizeof(CLSID));
554 memcpy(pbData+sizeof(CLSID), &constant, sizeof(DWORD));
556 return S_OK;
559 /********************************************************************************/
560 /* Virtual function table for the AntiMonikerImpl class which include IPersist,*/
561 /* IPersistStream and IMoniker functions. */
562 static const IMonikerVtbl VT_AntiMonikerImpl =
564 AntiMonikerImpl_QueryInterface,
565 AntiMonikerImpl_AddRef,
566 AntiMonikerImpl_Release,
567 AntiMonikerImpl_GetClassID,
568 AntiMonikerImpl_IsDirty,
569 AntiMonikerImpl_Load,
570 AntiMonikerImpl_Save,
571 AntiMonikerImpl_GetSizeMax,
572 AntiMonikerImpl_BindToObject,
573 AntiMonikerImpl_BindToStorage,
574 AntiMonikerImpl_Reduce,
575 AntiMonikerImpl_ComposeWith,
576 AntiMonikerImpl_Enum,
577 AntiMonikerImpl_IsEqual,
578 AntiMonikerImpl_Hash,
579 AntiMonikerImpl_IsRunning,
580 AntiMonikerImpl_GetTimeOfLastChange,
581 AntiMonikerImpl_Inverse,
582 AntiMonikerImpl_CommonPrefixWith,
583 AntiMonikerImpl_RelativePathTo,
584 AntiMonikerImpl_GetDisplayName,
585 AntiMonikerImpl_ParseDisplayName,
586 AntiMonikerImpl_IsSystemMoniker
589 /********************************************************************************/
590 /* Virtual function table for the IROTData class. */
591 static const IROTDataVtbl VT_ROTDataImpl =
593 AntiMonikerROTDataImpl_QueryInterface,
594 AntiMonikerROTDataImpl_AddRef,
595 AntiMonikerROTDataImpl_Release,
596 AntiMonikerROTDataImpl_GetComparisonData
599 /******************************************************************************
600 * AntiMoniker_Construct (local function)
601 *******************************************************************************/
602 static HRESULT AntiMonikerImpl_Construct(AntiMonikerImpl* This)
605 TRACE("(%p)\n",This);
607 /* Initialize the virtual fgunction table. */
608 This->lpvtbl1 = &VT_AntiMonikerImpl;
609 This->lpvtbl2 = &VT_ROTDataImpl;
610 This->ref = 0;
611 This->pMarshal = NULL;
613 return S_OK;
616 /******************************************************************************
617 * CreateAntiMoniker [OLE32.@]
618 ******************************************************************************/
619 HRESULT WINAPI CreateAntiMoniker(LPMONIKER * ppmk)
621 AntiMonikerImpl* newAntiMoniker = 0;
622 HRESULT hr = S_OK;
623 IID riid=IID_IMoniker;
625 TRACE("(%p)\n",ppmk);
627 newAntiMoniker = HeapAlloc(GetProcessHeap(), 0, sizeof(AntiMonikerImpl));
629 if (newAntiMoniker == 0)
630 return STG_E_INSUFFICIENTMEMORY;
632 hr = AntiMonikerImpl_Construct(newAntiMoniker);
633 if (FAILED(hr))
635 HeapFree(GetProcessHeap(),0,newAntiMoniker);
636 return hr;
639 hr = AntiMonikerImpl_QueryInterface((IMoniker*)newAntiMoniker,&riid,(void**)ppmk);
641 return hr;
644 static HRESULT WINAPI AntiMonikerCF_QueryInterface(LPCLASSFACTORY iface,
645 REFIID riid, LPVOID *ppv)
647 *ppv = NULL;
648 if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IClassFactory))
650 *ppv = iface;
651 IUnknown_AddRef(iface);
652 return S_OK;
654 return E_NOINTERFACE;
657 static ULONG WINAPI AntiMonikerCF_AddRef(LPCLASSFACTORY iface)
659 return 2; /* non-heap based object */
662 static ULONG WINAPI AntiMonikerCF_Release(LPCLASSFACTORY iface)
664 return 1; /* non-heap based object */
667 static HRESULT WINAPI AntiMonikerCF_CreateInstance(LPCLASSFACTORY iface,
668 LPUNKNOWN pUnk, REFIID riid, LPVOID *ppv)
670 IMoniker *pMoniker;
671 HRESULT hr;
673 TRACE("(%p, %s, %p)\n", pUnk, debugstr_guid(riid), ppv);
675 *ppv = NULL;
677 if (pUnk)
678 return CLASS_E_NOAGGREGATION;
680 hr = CreateAntiMoniker(&pMoniker);
681 if (FAILED(hr))
682 return hr;
684 hr = IMoniker_QueryInterface(pMoniker, riid, ppv);
686 if (FAILED(hr))
687 IMoniker_Release(pMoniker);
689 return hr;
692 static HRESULT WINAPI AntiMonikerCF_LockServer(LPCLASSFACTORY iface, BOOL fLock)
694 FIXME("(%d), stub!\n",fLock);
695 return S_OK;
698 static const IClassFactoryVtbl AntiMonikerCFVtbl =
700 AntiMonikerCF_QueryInterface,
701 AntiMonikerCF_AddRef,
702 AntiMonikerCF_Release,
703 AntiMonikerCF_CreateInstance,
704 AntiMonikerCF_LockServer
706 static const IClassFactoryVtbl *AntiMonikerCF = &AntiMonikerCFVtbl;
708 HRESULT AntiMonikerCF_Create(REFIID riid, LPVOID *ppv)
710 return IClassFactory_QueryInterface((IClassFactory *)&AntiMonikerCF, riid, ppv);