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
26 #define NONAMELESSUNION
27 #define NONAMELESSSTRUCT
33 #include "wine/debug.h"
36 WINE_DEFAULT_DEBUG_CHANNEL(ole
);
38 /* AntiMoniker data structure */
39 typedef struct AntiMonikerImpl
{
40 IMoniker IMoniker_iface
;
41 IROTData IROTData_iface
;
43 IUnknown
*pMarshal
; /* custom marshaler */
46 static inline AntiMonikerImpl
*impl_from_IMoniker(IMoniker
*iface
)
48 return CONTAINING_RECORD(iface
, AntiMonikerImpl
, IMoniker_iface
);
51 static inline AntiMonikerImpl
*impl_from_IROTData(IROTData
*iface
)
53 return CONTAINING_RECORD(iface
, AntiMonikerImpl
, IROTData_iface
);
57 /*******************************************************************************
58 * AntiMoniker_QueryInterface
59 *******************************************************************************/
61 AntiMonikerImpl_QueryInterface(IMoniker
* iface
,REFIID riid
,void** ppvObject
)
63 AntiMonikerImpl
*This
= impl_from_IMoniker(iface
);
65 TRACE("(%p,%p,%p)\n",This
,riid
,ppvObject
);
67 /* Perform a sanity check on the parameters.*/
71 /* Initialize the return parameter */
74 /* Compare the riid with the interface IDs implemented by this object.*/
75 if (IsEqualIID(&IID_IUnknown
, riid
) ||
76 IsEqualIID(&IID_IPersist
, riid
) ||
77 IsEqualIID(&IID_IPersistStream
, riid
) ||
78 IsEqualIID(&IID_IMoniker
, riid
))
80 else if (IsEqualIID(&IID_IROTData
, riid
))
81 *ppvObject
= &This
->IROTData_iface
;
82 else if (IsEqualIID(&IID_IMarshal
, riid
))
86 hr
= MonikerMarshal_Create(iface
, &This
->pMarshal
);
89 return IUnknown_QueryInterface(This
->pMarshal
, riid
, ppvObject
);
92 /* Check that we obtained an interface.*/
96 /* always increase the reference count by one when it is successful */
97 IMoniker_AddRef(iface
);
102 /******************************************************************************
104 ******************************************************************************/
106 AntiMonikerImpl_AddRef(IMoniker
* iface
)
108 AntiMonikerImpl
*This
= impl_from_IMoniker(iface
);
110 TRACE("(%p)\n",This
);
112 return InterlockedIncrement(&This
->ref
);
115 /******************************************************************************
116 * AntiMoniker_Release
117 ******************************************************************************/
119 AntiMonikerImpl_Release(IMoniker
* iface
)
121 AntiMonikerImpl
*This
= impl_from_IMoniker(iface
);
124 TRACE("(%p)\n",This
);
126 ref
= InterlockedDecrement(&This
->ref
);
128 /* destroy the object if there's no more reference on it */
131 if (This
->pMarshal
) IUnknown_Release(This
->pMarshal
);
132 HeapFree(GetProcessHeap(),0,This
);
138 /******************************************************************************
139 * AntiMoniker_GetClassID
140 ******************************************************************************/
141 static HRESULT WINAPI
142 AntiMonikerImpl_GetClassID(IMoniker
* iface
,CLSID
*pClassID
)
144 TRACE("(%p,%p)\n",iface
,pClassID
);
149 *pClassID
= CLSID_AntiMoniker
;
154 /******************************************************************************
155 * AntiMoniker_IsDirty
156 ******************************************************************************/
157 static HRESULT WINAPI
158 AntiMonikerImpl_IsDirty(IMoniker
* iface
)
160 /* Note that the OLE-provided implementations of the IPersistStream::IsDirty
161 method in the OLE-provided moniker interfaces always return S_FALSE because
162 their internal state never changes. */
164 TRACE("(%p)\n",iface
);
169 /******************************************************************************
171 ******************************************************************************/
172 static HRESULT WINAPI
173 AntiMonikerImpl_Load(IMoniker
* iface
,IStream
* pStm
)
175 DWORD constant
=1,dwbuffer
;
178 /* data read by this function is only a DWORD constant (must be 1) ! */
179 res
=IStream_Read(pStm
,&dwbuffer
,sizeof(DWORD
),NULL
);
181 if (SUCCEEDED(res
)&& dwbuffer
!=constant
)
187 /******************************************************************************
189 ******************************************************************************/
190 static HRESULT WINAPI
191 AntiMonikerImpl_Save(IMoniker
* iface
,IStream
* pStm
,BOOL fClearDirty
)
193 static const DWORD constant
= 1;
194 /* data written by this function is only a DWORD constant set to 1 ! */
195 return IStream_Write(pStm
,&constant
,sizeof(constant
),NULL
);
198 /******************************************************************************
199 * AntiMoniker_GetSizeMax
202 * pcbSize [out] Pointer to size of stream needed to save object
203 ******************************************************************************/
204 static HRESULT WINAPI
205 AntiMonikerImpl_GetSizeMax(IMoniker
* iface
, ULARGE_INTEGER
* pcbSize
)
207 TRACE("(%p,%p)\n",iface
,pcbSize
);
212 /* for more details see AntiMonikerImpl_Save comments */
215 * Normally the sizemax must be sizeof DWORD, but
216 * I tested this function it usually return 16 bytes
217 * more than the number of bytes used by AntiMoniker::Save function
219 pcbSize
->u
.LowPart
= sizeof(DWORD
)+16;
221 pcbSize
->u
.HighPart
=0;
226 /******************************************************************************
227 * AntiMoniker_BindToObject
228 ******************************************************************************/
229 static HRESULT WINAPI
230 AntiMonikerImpl_BindToObject(IMoniker
* iface
, IBindCtx
* pbc
, IMoniker
* pmkToLeft
,
231 REFIID riid
, VOID
** ppvResult
)
233 TRACE("(%p,%p,%p,%p,%p)\n",iface
,pbc
,pmkToLeft
,riid
,ppvResult
);
237 /******************************************************************************
238 * AntiMoniker_BindToStorage
239 ******************************************************************************/
240 static HRESULT WINAPI
241 AntiMonikerImpl_BindToStorage(IMoniker
* iface
, IBindCtx
* pbc
, IMoniker
* pmkToLeft
,
242 REFIID riid
, VOID
** ppvResult
)
244 TRACE("(%p,%p,%p,%p,%p)\n",iface
,pbc
,pmkToLeft
,riid
,ppvResult
);
248 /******************************************************************************
250 ******************************************************************************/
251 static HRESULT WINAPI
252 AntiMonikerImpl_Reduce(IMoniker
* iface
, IBindCtx
* pbc
, DWORD dwReduceHowFar
,
253 IMoniker
** ppmkToLeft
, IMoniker
** ppmkReduced
)
255 TRACE("(%p,%p,%d,%p,%p)\n",iface
,pbc
,dwReduceHowFar
,ppmkToLeft
,ppmkReduced
);
257 if (ppmkReduced
==NULL
)
260 AntiMonikerImpl_AddRef(iface
);
264 return MK_S_REDUCED_TO_SELF
;
266 /******************************************************************************
267 * AntiMoniker_ComposeWith
268 ******************************************************************************/
269 static HRESULT WINAPI
270 AntiMonikerImpl_ComposeWith(IMoniker
* iface
, IMoniker
* pmkRight
,
271 BOOL fOnlyIfNotGeneric
, IMoniker
** ppmkComposite
)
274 TRACE("(%p,%p,%d,%p)\n",iface
,pmkRight
,fOnlyIfNotGeneric
,ppmkComposite
);
276 if ((ppmkComposite
==NULL
)||(pmkRight
==NULL
))
281 if (fOnlyIfNotGeneric
)
282 return MK_E_NEEDGENERIC
;
284 return CreateGenericComposite(iface
,pmkRight
,ppmkComposite
);
287 /******************************************************************************
289 ******************************************************************************/
290 static HRESULT WINAPI
291 AntiMonikerImpl_Enum(IMoniker
* iface
,BOOL fForward
, IEnumMoniker
** ppenumMoniker
)
293 TRACE("(%p,%d,%p)\n",iface
,fForward
,ppenumMoniker
);
295 if (ppenumMoniker
== NULL
)
298 *ppenumMoniker
= NULL
;
303 /******************************************************************************
304 * AntiMoniker_IsEqual
305 ******************************************************************************/
306 static HRESULT WINAPI
307 AntiMonikerImpl_IsEqual(IMoniker
* iface
,IMoniker
* pmkOtherMoniker
)
311 TRACE("(%p,%p)\n",iface
,pmkOtherMoniker
);
313 if (pmkOtherMoniker
==NULL
)
316 IMoniker_IsSystemMoniker(pmkOtherMoniker
,&mkSys
);
318 if (mkSys
==MKSYS_ANTIMONIKER
)
324 /******************************************************************************
326 ******************************************************************************/
327 static HRESULT WINAPI
AntiMonikerImpl_Hash(IMoniker
* iface
,DWORD
* pdwHash
)
332 *pdwHash
= 0x80000001;
337 /******************************************************************************
338 * AntiMoniker_IsRunning
339 ******************************************************************************/
340 static HRESULT WINAPI
341 AntiMonikerImpl_IsRunning(IMoniker
* iface
, IBindCtx
* pbc
, IMoniker
* pmkToLeft
,
342 IMoniker
* pmkNewlyRunning
)
344 IRunningObjectTable
* rot
;
347 TRACE("(%p,%p,%p,%p)\n",iface
,pbc
,pmkToLeft
,pmkNewlyRunning
);
352 res
=IBindCtx_GetRunningObjectTable(pbc
,&rot
);
357 res
= IRunningObjectTable_IsRunning(rot
,iface
);
359 IRunningObjectTable_Release(rot
);
364 /******************************************************************************
365 * AntiMoniker_GetTimeOfLastChange
366 ******************************************************************************/
367 static HRESULT WINAPI
AntiMonikerImpl_GetTimeOfLastChange(IMoniker
* iface
,
372 TRACE("(%p,%p,%p,%p)\n",iface
,pbc
,pmkToLeft
,pAntiTime
);
376 /******************************************************************************
377 * AntiMoniker_Inverse
378 ******************************************************************************/
379 static HRESULT WINAPI
380 AntiMonikerImpl_Inverse(IMoniker
* iface
,IMoniker
** ppmk
)
382 TRACE("(%p,%p)\n",iface
,ppmk
);
389 return MK_E_NOINVERSE
;
392 /******************************************************************************
393 * AntiMoniker_CommonPrefixWith
394 ******************************************************************************/
395 static HRESULT WINAPI
396 AntiMonikerImpl_CommonPrefixWith(IMoniker
* iface
,IMoniker
* pmkOther
,IMoniker
** ppmkPrefix
)
400 IMoniker_IsSystemMoniker(pmkOther
,&mkSys
);
402 if(mkSys
==MKSYS_ANTIMONIKER
){
404 IMoniker_AddRef(iface
);
408 IMoniker_AddRef(iface
);
413 return MonikerCommonPrefixWith(iface
,pmkOther
,ppmkPrefix
);
416 /******************************************************************************
417 * AntiMoniker_RelativePathTo
418 ******************************************************************************/
419 static HRESULT WINAPI
420 AntiMonikerImpl_RelativePathTo(IMoniker
* iface
,IMoniker
* pmOther
, IMoniker
** ppmkRelPath
)
422 TRACE("(%p,%p,%p)\n",iface
,pmOther
,ppmkRelPath
);
424 if (ppmkRelPath
==NULL
)
427 IMoniker_AddRef(pmOther
);
429 *ppmkRelPath
=pmOther
;
434 /******************************************************************************
435 * AntiMoniker_GetDisplayName
436 ******************************************************************************/
437 static HRESULT WINAPI
438 AntiMonikerImpl_GetDisplayName(IMoniker
* iface
, IBindCtx
* pbc
,
439 IMoniker
* pmkToLeft
, LPOLESTR
*ppszDisplayName
)
441 static const WCHAR back
[]={'\\','.','.',0};
443 TRACE("(%p,%p,%p,%p)\n",iface
,pbc
,pmkToLeft
,ppszDisplayName
);
445 if (ppszDisplayName
==NULL
)
448 if (pmkToLeft
!=NULL
){
449 FIXME("() pmkToLeft!=NULL not implemented\n");
453 *ppszDisplayName
=CoTaskMemAlloc(sizeof(back
));
455 if (*ppszDisplayName
==NULL
)
456 return E_OUTOFMEMORY
;
458 lstrcpyW(*ppszDisplayName
,back
);
463 /******************************************************************************
464 * AntiMoniker_ParseDisplayName
465 ******************************************************************************/
466 static HRESULT WINAPI
467 AntiMonikerImpl_ParseDisplayName(IMoniker
* iface
, IBindCtx
* pbc
,
468 IMoniker
* pmkToLeft
, LPOLESTR pszDisplayName
,
469 ULONG
* pchEaten
, IMoniker
** ppmkOut
)
471 TRACE("(%p,%p,%p,%p,%p,%p)\n",iface
,pbc
,pmkToLeft
,pszDisplayName
,pchEaten
,ppmkOut
);
475 /******************************************************************************
476 * AntiMoniker_IsSystemMoniker
477 ******************************************************************************/
478 static HRESULT WINAPI
479 AntiMonikerImpl_IsSystemMoniker(IMoniker
* iface
,DWORD
* pwdMksys
)
481 TRACE("(%p,%p)\n",iface
,pwdMksys
);
486 (*pwdMksys
)=MKSYS_ANTIMONIKER
;
491 /*******************************************************************************
492 * AntiMonikerIROTData_QueryInterface
493 *******************************************************************************/
494 static HRESULT WINAPI
495 AntiMonikerROTDataImpl_QueryInterface(IROTData
*iface
,REFIID riid
,VOID
** ppvObject
)
497 AntiMonikerImpl
*This
= impl_from_IROTData(iface
);
499 TRACE("(%p,%p,%p)\n",iface
,riid
,ppvObject
);
501 return AntiMonikerImpl_QueryInterface(&This
->IMoniker_iface
, riid
, ppvObject
);
504 /***********************************************************************
505 * AntiMonikerIROTData_AddRef
507 static ULONG WINAPI
AntiMonikerROTDataImpl_AddRef(IROTData
*iface
)
509 AntiMonikerImpl
*This
= impl_from_IROTData(iface
);
511 TRACE("(%p)\n",iface
);
513 return AntiMonikerImpl_AddRef(&This
->IMoniker_iface
);
516 /***********************************************************************
517 * AntiMonikerIROTData_Release
519 static ULONG WINAPI
AntiMonikerROTDataImpl_Release(IROTData
* iface
)
521 AntiMonikerImpl
*This
= impl_from_IROTData(iface
);
523 TRACE("(%p)\n",iface
);
525 return AntiMonikerImpl_Release(&This
->IMoniker_iface
);
528 /******************************************************************************
529 * AntiMonikerIROTData_GetComparisonData
530 ******************************************************************************/
531 static HRESULT WINAPI
532 AntiMonikerROTDataImpl_GetComparisonData(IROTData
* iface
, BYTE
* pbData
,
533 ULONG cbMax
, ULONG
* pcbData
)
537 TRACE("(%p, %u, %p)\n", pbData
, cbMax
, pcbData
);
539 *pcbData
= sizeof(CLSID
) + sizeof(DWORD
);
540 if (cbMax
< *pcbData
)
541 return E_OUTOFMEMORY
;
543 memcpy(pbData
, &CLSID_AntiMoniker
, sizeof(CLSID
));
544 memcpy(pbData
+sizeof(CLSID
), &constant
, sizeof(DWORD
));
549 /********************************************************************************/
550 /* Virtual function table for the AntiMonikerImpl class which include IPersist,*/
551 /* IPersistStream and IMoniker functions. */
552 static const IMonikerVtbl VT_AntiMonikerImpl
=
554 AntiMonikerImpl_QueryInterface
,
555 AntiMonikerImpl_AddRef
,
556 AntiMonikerImpl_Release
,
557 AntiMonikerImpl_GetClassID
,
558 AntiMonikerImpl_IsDirty
,
559 AntiMonikerImpl_Load
,
560 AntiMonikerImpl_Save
,
561 AntiMonikerImpl_GetSizeMax
,
562 AntiMonikerImpl_BindToObject
,
563 AntiMonikerImpl_BindToStorage
,
564 AntiMonikerImpl_Reduce
,
565 AntiMonikerImpl_ComposeWith
,
566 AntiMonikerImpl_Enum
,
567 AntiMonikerImpl_IsEqual
,
568 AntiMonikerImpl_Hash
,
569 AntiMonikerImpl_IsRunning
,
570 AntiMonikerImpl_GetTimeOfLastChange
,
571 AntiMonikerImpl_Inverse
,
572 AntiMonikerImpl_CommonPrefixWith
,
573 AntiMonikerImpl_RelativePathTo
,
574 AntiMonikerImpl_GetDisplayName
,
575 AntiMonikerImpl_ParseDisplayName
,
576 AntiMonikerImpl_IsSystemMoniker
579 /********************************************************************************/
580 /* Virtual function table for the IROTData class. */
581 static const IROTDataVtbl VT_ROTDataImpl
=
583 AntiMonikerROTDataImpl_QueryInterface
,
584 AntiMonikerROTDataImpl_AddRef
,
585 AntiMonikerROTDataImpl_Release
,
586 AntiMonikerROTDataImpl_GetComparisonData
589 /******************************************************************************
590 * AntiMoniker_Construct (local function)
591 *******************************************************************************/
592 static HRESULT
AntiMonikerImpl_Construct(AntiMonikerImpl
* This
)
595 TRACE("(%p)\n",This
);
597 /* Initialize the virtual function table. */
598 This
->IMoniker_iface
.lpVtbl
= &VT_AntiMonikerImpl
;
599 This
->IROTData_iface
.lpVtbl
= &VT_ROTDataImpl
;
601 This
->pMarshal
= NULL
;
606 /******************************************************************************
607 * CreateAntiMoniker [OLE32.@]
608 ******************************************************************************/
609 HRESULT WINAPI
CreateAntiMoniker(IMoniker
**ppmk
)
611 AntiMonikerImpl
* newAntiMoniker
;
614 TRACE("(%p)\n",ppmk
);
616 newAntiMoniker
= HeapAlloc(GetProcessHeap(), 0, sizeof(AntiMonikerImpl
));
618 if (newAntiMoniker
== 0)
619 return STG_E_INSUFFICIENTMEMORY
;
621 hr
= AntiMonikerImpl_Construct(newAntiMoniker
);
624 HeapFree(GetProcessHeap(),0,newAntiMoniker
);
628 return AntiMonikerImpl_QueryInterface(&newAntiMoniker
->IMoniker_iface
, &IID_IMoniker
,
632 static HRESULT WINAPI
AntiMonikerCF_QueryInterface(IClassFactory
*iface
, REFIID riid
, void **ppv
)
635 if (IsEqualIID(riid
, &IID_IUnknown
) || IsEqualIID(riid
, &IID_IClassFactory
))
638 IClassFactory_AddRef(iface
);
641 return E_NOINTERFACE
;
644 static ULONG WINAPI
AntiMonikerCF_AddRef(LPCLASSFACTORY iface
)
646 return 2; /* non-heap based object */
649 static ULONG WINAPI
AntiMonikerCF_Release(LPCLASSFACTORY iface
)
651 return 1; /* non-heap based object */
654 static HRESULT WINAPI
AntiMonikerCF_CreateInstance(LPCLASSFACTORY iface
,
655 LPUNKNOWN pUnk
, REFIID riid
, LPVOID
*ppv
)
660 TRACE("(%p, %s, %p)\n", pUnk
, debugstr_guid(riid
), ppv
);
665 return CLASS_E_NOAGGREGATION
;
667 hr
= CreateAntiMoniker(&pMoniker
);
671 hr
= IMoniker_QueryInterface(pMoniker
, riid
, ppv
);
674 IMoniker_Release(pMoniker
);
679 static HRESULT WINAPI
AntiMonikerCF_LockServer(LPCLASSFACTORY iface
, BOOL fLock
)
681 FIXME("(%d), stub!\n",fLock
);
685 static const IClassFactoryVtbl AntiMonikerCFVtbl
=
687 AntiMonikerCF_QueryInterface
,
688 AntiMonikerCF_AddRef
,
689 AntiMonikerCF_Release
,
690 AntiMonikerCF_CreateInstance
,
691 AntiMonikerCF_LockServer
693 static const IClassFactoryVtbl
*AntiMonikerCF
= &AntiMonikerCFVtbl
;
695 HRESULT
AntiMonikerCF_Create(REFIID riid
, LPVOID
*ppv
)
697 return IClassFactory_QueryInterface((IClassFactory
*)&AntiMonikerCF
, riid
, ppv
);