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
32 #include "wine/debug.h"
35 WINE_DEFAULT_DEBUG_CHANNEL(ole
);
37 /* AntiMoniker data structure */
38 typedef struct AntiMonikerImpl
{
39 IMoniker IMoniker_iface
;
40 IROTData IROTData_iface
;
42 IUnknown
*pMarshal
; /* custom marshaler */
45 static inline AntiMonikerImpl
*impl_from_IMoniker(IMoniker
*iface
)
47 return CONTAINING_RECORD(iface
, AntiMonikerImpl
, IMoniker_iface
);
50 static inline AntiMonikerImpl
*impl_from_IROTData(IROTData
*iface
)
52 return CONTAINING_RECORD(iface
, AntiMonikerImpl
, IROTData_iface
);
56 /*******************************************************************************
57 * AntiMoniker_QueryInterface
58 *******************************************************************************/
60 AntiMonikerImpl_QueryInterface(IMoniker
* iface
,REFIID riid
,void** ppvObject
)
62 AntiMonikerImpl
*This
= impl_from_IMoniker(iface
);
64 TRACE("(%p,%s,%p)\n",This
,debugstr_guid(riid
),ppvObject
);
66 /* Perform a sanity check on the parameters.*/
70 /* Initialize the return parameter */
73 /* Compare the riid with the interface IDs implemented by this object.*/
74 if (IsEqualIID(&IID_IUnknown
, riid
) ||
75 IsEqualIID(&IID_IPersist
, riid
) ||
76 IsEqualIID(&IID_IPersistStream
, riid
) ||
77 IsEqualIID(&IID_IMoniker
, riid
))
79 else if (IsEqualIID(&IID_IROTData
, riid
))
80 *ppvObject
= &This
->IROTData_iface
;
81 else if (IsEqualIID(&IID_IMarshal
, riid
))
85 hr
= MonikerMarshal_Create(iface
, &This
->pMarshal
);
88 return IUnknown_QueryInterface(This
->pMarshal
, riid
, ppvObject
);
91 /* Check that we obtained an interface.*/
95 /* always increase the reference count by one when it is successful */
96 IMoniker_AddRef(iface
);
101 /******************************************************************************
103 ******************************************************************************/
105 AntiMonikerImpl_AddRef(IMoniker
* iface
)
107 AntiMonikerImpl
*This
= impl_from_IMoniker(iface
);
109 TRACE("(%p)\n",This
);
111 return InterlockedIncrement(&This
->ref
);
114 /******************************************************************************
115 * AntiMoniker_Release
116 ******************************************************************************/
118 AntiMonikerImpl_Release(IMoniker
* iface
)
120 AntiMonikerImpl
*This
= impl_from_IMoniker(iface
);
123 TRACE("(%p)\n",This
);
125 ref
= InterlockedDecrement(&This
->ref
);
127 /* destroy the object if there are no more references to it */
130 if (This
->pMarshal
) IUnknown_Release(This
->pMarshal
);
131 HeapFree(GetProcessHeap(),0,This
);
137 /******************************************************************************
138 * AntiMoniker_GetClassID
139 ******************************************************************************/
140 static HRESULT WINAPI
141 AntiMonikerImpl_GetClassID(IMoniker
* iface
,CLSID
*pClassID
)
143 TRACE("(%p,%p)\n",iface
,pClassID
);
148 *pClassID
= CLSID_AntiMoniker
;
153 /******************************************************************************
154 * AntiMoniker_IsDirty
155 ******************************************************************************/
156 static HRESULT WINAPI
157 AntiMonikerImpl_IsDirty(IMoniker
* iface
)
159 /* Note that the OLE-provided implementations of the IPersistStream::IsDirty
160 method in the OLE-provided moniker interfaces always return S_FALSE because
161 their internal state never changes. */
163 TRACE("(%p)\n",iface
);
168 /******************************************************************************
170 ******************************************************************************/
171 static HRESULT WINAPI
172 AntiMonikerImpl_Load(IMoniker
* iface
,IStream
* pStm
)
174 DWORD constant
=1,dwbuffer
;
177 /* data read by this function is only a DWORD constant (must be 1) ! */
178 res
=IStream_Read(pStm
,&dwbuffer
,sizeof(DWORD
),NULL
);
180 if (SUCCEEDED(res
)&& dwbuffer
!=constant
)
186 /******************************************************************************
188 ******************************************************************************/
189 static HRESULT WINAPI
190 AntiMonikerImpl_Save(IMoniker
* iface
,IStream
* pStm
,BOOL fClearDirty
)
192 static const DWORD constant
= 1;
193 /* data written by this function is only a DWORD constant set to 1 ! */
194 return IStream_Write(pStm
,&constant
,sizeof(constant
),NULL
);
197 /******************************************************************************
198 * AntiMoniker_GetSizeMax
201 * pcbSize [out] Pointer to size of stream needed to save object
202 ******************************************************************************/
203 static HRESULT WINAPI
204 AntiMonikerImpl_GetSizeMax(IMoniker
* iface
, ULARGE_INTEGER
* pcbSize
)
206 TRACE("(%p,%p)\n",iface
,pcbSize
);
211 /* for more details see AntiMonikerImpl_Save comments */
214 * Normally the sizemax must be sizeof DWORD, but
215 * I tested this function it usually return 16 bytes
216 * more than the number of bytes used by AntiMoniker::Save function
218 pcbSize
->u
.LowPart
= sizeof(DWORD
)+16;
220 pcbSize
->u
.HighPart
=0;
225 /******************************************************************************
226 * AntiMoniker_BindToObject
227 ******************************************************************************/
228 static HRESULT WINAPI
229 AntiMonikerImpl_BindToObject(IMoniker
* iface
, IBindCtx
* pbc
, IMoniker
* pmkToLeft
,
230 REFIID riid
, VOID
** ppvResult
)
232 TRACE("(%p,%p,%p,%s,%p)\n",iface
,pbc
,pmkToLeft
,debugstr_guid(riid
),ppvResult
);
236 /******************************************************************************
237 * AntiMoniker_BindToStorage
238 ******************************************************************************/
239 static HRESULT WINAPI
240 AntiMonikerImpl_BindToStorage(IMoniker
* iface
, IBindCtx
* pbc
, IMoniker
* pmkToLeft
,
241 REFIID riid
, VOID
** ppvResult
)
243 TRACE("(%p,%p,%p,%s,%p)\n",iface
,pbc
,pmkToLeft
,debugstr_guid(riid
),ppvResult
);
247 /******************************************************************************
249 ******************************************************************************/
250 static HRESULT WINAPI
251 AntiMonikerImpl_Reduce(IMoniker
* iface
, IBindCtx
* pbc
, DWORD dwReduceHowFar
,
252 IMoniker
** ppmkToLeft
, IMoniker
** ppmkReduced
)
254 TRACE("(%p,%p,%d,%p,%p)\n",iface
,pbc
,dwReduceHowFar
,ppmkToLeft
,ppmkReduced
);
256 if (ppmkReduced
==NULL
)
259 AntiMonikerImpl_AddRef(iface
);
263 return MK_S_REDUCED_TO_SELF
;
265 /******************************************************************************
266 * AntiMoniker_ComposeWith
267 ******************************************************************************/
268 static HRESULT WINAPI
269 AntiMonikerImpl_ComposeWith(IMoniker
* iface
, IMoniker
* pmkRight
,
270 BOOL fOnlyIfNotGeneric
, IMoniker
** ppmkComposite
)
273 TRACE("(%p,%p,%d,%p)\n",iface
,pmkRight
,fOnlyIfNotGeneric
,ppmkComposite
);
275 if ((ppmkComposite
==NULL
)||(pmkRight
==NULL
))
280 if (fOnlyIfNotGeneric
)
281 return MK_E_NEEDGENERIC
;
283 return CreateGenericComposite(iface
,pmkRight
,ppmkComposite
);
286 /******************************************************************************
288 ******************************************************************************/
289 static HRESULT WINAPI
290 AntiMonikerImpl_Enum(IMoniker
* iface
,BOOL fForward
, IEnumMoniker
** ppenumMoniker
)
292 TRACE("(%p,%d,%p)\n",iface
,fForward
,ppenumMoniker
);
294 if (ppenumMoniker
== NULL
)
297 *ppenumMoniker
= NULL
;
302 /******************************************************************************
303 * AntiMoniker_IsEqual
304 ******************************************************************************/
305 static HRESULT WINAPI
306 AntiMonikerImpl_IsEqual(IMoniker
* iface
,IMoniker
* pmkOtherMoniker
)
310 TRACE("(%p,%p)\n",iface
,pmkOtherMoniker
);
312 if (pmkOtherMoniker
==NULL
)
315 IMoniker_IsSystemMoniker(pmkOtherMoniker
,&mkSys
);
317 if (mkSys
==MKSYS_ANTIMONIKER
)
323 /******************************************************************************
325 ******************************************************************************/
326 static HRESULT WINAPI
AntiMonikerImpl_Hash(IMoniker
* iface
,DWORD
* pdwHash
)
331 *pdwHash
= 0x80000001;
336 /******************************************************************************
337 * AntiMoniker_IsRunning
338 ******************************************************************************/
339 static HRESULT WINAPI
340 AntiMonikerImpl_IsRunning(IMoniker
* iface
, IBindCtx
* pbc
, IMoniker
* pmkToLeft
,
341 IMoniker
* pmkNewlyRunning
)
343 IRunningObjectTable
* rot
;
346 TRACE("(%p,%p,%p,%p)\n",iface
,pbc
,pmkToLeft
,pmkNewlyRunning
);
351 res
=IBindCtx_GetRunningObjectTable(pbc
,&rot
);
356 res
= IRunningObjectTable_IsRunning(rot
,iface
);
358 IRunningObjectTable_Release(rot
);
363 /******************************************************************************
364 * AntiMoniker_GetTimeOfLastChange
365 ******************************************************************************/
366 static HRESULT WINAPI
AntiMonikerImpl_GetTimeOfLastChange(IMoniker
* iface
,
371 TRACE("(%p,%p,%p,%p)\n",iface
,pbc
,pmkToLeft
,pAntiTime
);
375 /******************************************************************************
376 * AntiMoniker_Inverse
377 ******************************************************************************/
378 static HRESULT WINAPI
379 AntiMonikerImpl_Inverse(IMoniker
* iface
,IMoniker
** ppmk
)
381 TRACE("(%p,%p)\n",iface
,ppmk
);
388 return MK_E_NOINVERSE
;
391 /******************************************************************************
392 * AntiMoniker_CommonPrefixWith
393 ******************************************************************************/
394 static HRESULT WINAPI
395 AntiMonikerImpl_CommonPrefixWith(IMoniker
* iface
,IMoniker
* pmkOther
,IMoniker
** ppmkPrefix
)
399 IMoniker_IsSystemMoniker(pmkOther
,&mkSys
);
401 if(mkSys
==MKSYS_ANTIMONIKER
){
403 IMoniker_AddRef(iface
);
407 IMoniker_AddRef(iface
);
412 return MonikerCommonPrefixWith(iface
,pmkOther
,ppmkPrefix
);
415 /******************************************************************************
416 * AntiMoniker_RelativePathTo
417 ******************************************************************************/
418 static HRESULT WINAPI
419 AntiMonikerImpl_RelativePathTo(IMoniker
* iface
,IMoniker
* pmOther
, IMoniker
** ppmkRelPath
)
421 TRACE("(%p,%p,%p)\n",iface
,pmOther
,ppmkRelPath
);
423 if (ppmkRelPath
==NULL
)
426 IMoniker_AddRef(pmOther
);
428 *ppmkRelPath
=pmOther
;
433 /******************************************************************************
434 * AntiMoniker_GetDisplayName
435 ******************************************************************************/
436 static HRESULT WINAPI
437 AntiMonikerImpl_GetDisplayName(IMoniker
* iface
, IBindCtx
* pbc
,
438 IMoniker
* pmkToLeft
, LPOLESTR
*ppszDisplayName
)
440 static const WCHAR back
[]={'\\','.','.',0};
442 TRACE("(%p,%p,%p,%p)\n",iface
,pbc
,pmkToLeft
,ppszDisplayName
);
444 if (ppszDisplayName
==NULL
)
447 if (pmkToLeft
!=NULL
){
448 FIXME("() pmkToLeft!=NULL not implemented\n");
452 *ppszDisplayName
=CoTaskMemAlloc(sizeof(back
));
454 if (*ppszDisplayName
==NULL
)
455 return E_OUTOFMEMORY
;
457 lstrcpyW(*ppszDisplayName
,back
);
462 /******************************************************************************
463 * AntiMoniker_ParseDisplayName
464 ******************************************************************************/
465 static HRESULT WINAPI
466 AntiMonikerImpl_ParseDisplayName(IMoniker
* iface
, IBindCtx
* pbc
,
467 IMoniker
* pmkToLeft
, LPOLESTR pszDisplayName
,
468 ULONG
* pchEaten
, IMoniker
** ppmkOut
)
470 TRACE("(%p,%p,%p,%p,%p,%p)\n",iface
,pbc
,pmkToLeft
,pszDisplayName
,pchEaten
,ppmkOut
);
474 /******************************************************************************
475 * AntiMoniker_IsSystemMoniker
476 ******************************************************************************/
477 static HRESULT WINAPI
478 AntiMonikerImpl_IsSystemMoniker(IMoniker
* iface
,DWORD
* pwdMksys
)
480 TRACE("(%p,%p)\n",iface
,pwdMksys
);
485 (*pwdMksys
)=MKSYS_ANTIMONIKER
;
490 /*******************************************************************************
491 * AntiMonikerIROTData_QueryInterface
492 *******************************************************************************/
493 static HRESULT WINAPI
494 AntiMonikerROTDataImpl_QueryInterface(IROTData
*iface
,REFIID riid
,VOID
** ppvObject
)
496 AntiMonikerImpl
*This
= impl_from_IROTData(iface
);
498 TRACE("(%p,%s,%p)\n",iface
,debugstr_guid(riid
),ppvObject
);
500 return AntiMonikerImpl_QueryInterface(&This
->IMoniker_iface
, riid
, ppvObject
);
503 /***********************************************************************
504 * AntiMonikerIROTData_AddRef
506 static ULONG WINAPI
AntiMonikerROTDataImpl_AddRef(IROTData
*iface
)
508 AntiMonikerImpl
*This
= impl_from_IROTData(iface
);
510 TRACE("(%p)\n",iface
);
512 return AntiMonikerImpl_AddRef(&This
->IMoniker_iface
);
515 /***********************************************************************
516 * AntiMonikerIROTData_Release
518 static ULONG WINAPI
AntiMonikerROTDataImpl_Release(IROTData
* iface
)
520 AntiMonikerImpl
*This
= impl_from_IROTData(iface
);
522 TRACE("(%p)\n",iface
);
524 return AntiMonikerImpl_Release(&This
->IMoniker_iface
);
527 /******************************************************************************
528 * AntiMonikerIROTData_GetComparisonData
529 ******************************************************************************/
530 static HRESULT WINAPI
531 AntiMonikerROTDataImpl_GetComparisonData(IROTData
* iface
, BYTE
* pbData
,
532 ULONG cbMax
, ULONG
* pcbData
)
536 TRACE("(%p, %u, %p)\n", pbData
, cbMax
, pcbData
);
538 *pcbData
= sizeof(CLSID
) + sizeof(DWORD
);
539 if (cbMax
< *pcbData
)
540 return E_OUTOFMEMORY
;
542 memcpy(pbData
, &CLSID_AntiMoniker
, sizeof(CLSID
));
543 memcpy(pbData
+sizeof(CLSID
), &constant
, sizeof(DWORD
));
548 /********************************************************************************/
549 /* Virtual function table for the AntiMonikerImpl class which include IPersist,*/
550 /* IPersistStream and IMoniker functions. */
551 static const IMonikerVtbl VT_AntiMonikerImpl
=
553 AntiMonikerImpl_QueryInterface
,
554 AntiMonikerImpl_AddRef
,
555 AntiMonikerImpl_Release
,
556 AntiMonikerImpl_GetClassID
,
557 AntiMonikerImpl_IsDirty
,
558 AntiMonikerImpl_Load
,
559 AntiMonikerImpl_Save
,
560 AntiMonikerImpl_GetSizeMax
,
561 AntiMonikerImpl_BindToObject
,
562 AntiMonikerImpl_BindToStorage
,
563 AntiMonikerImpl_Reduce
,
564 AntiMonikerImpl_ComposeWith
,
565 AntiMonikerImpl_Enum
,
566 AntiMonikerImpl_IsEqual
,
567 AntiMonikerImpl_Hash
,
568 AntiMonikerImpl_IsRunning
,
569 AntiMonikerImpl_GetTimeOfLastChange
,
570 AntiMonikerImpl_Inverse
,
571 AntiMonikerImpl_CommonPrefixWith
,
572 AntiMonikerImpl_RelativePathTo
,
573 AntiMonikerImpl_GetDisplayName
,
574 AntiMonikerImpl_ParseDisplayName
,
575 AntiMonikerImpl_IsSystemMoniker
578 /********************************************************************************/
579 /* Virtual function table for the IROTData class. */
580 static const IROTDataVtbl VT_ROTDataImpl
=
582 AntiMonikerROTDataImpl_QueryInterface
,
583 AntiMonikerROTDataImpl_AddRef
,
584 AntiMonikerROTDataImpl_Release
,
585 AntiMonikerROTDataImpl_GetComparisonData
588 /******************************************************************************
589 * AntiMoniker_Construct (local function)
590 *******************************************************************************/
591 static HRESULT
AntiMonikerImpl_Construct(AntiMonikerImpl
* This
)
594 TRACE("(%p)\n",This
);
596 /* Initialize the virtual function table. */
597 This
->IMoniker_iface
.lpVtbl
= &VT_AntiMonikerImpl
;
598 This
->IROTData_iface
.lpVtbl
= &VT_ROTDataImpl
;
600 This
->pMarshal
= NULL
;
605 /******************************************************************************
606 * CreateAntiMoniker [OLE32.@]
607 ******************************************************************************/
608 HRESULT WINAPI
CreateAntiMoniker(IMoniker
**ppmk
)
610 AntiMonikerImpl
* newAntiMoniker
;
613 TRACE("(%p)\n",ppmk
);
615 newAntiMoniker
= HeapAlloc(GetProcessHeap(), 0, sizeof(AntiMonikerImpl
));
617 if (newAntiMoniker
== 0)
618 return STG_E_INSUFFICIENTMEMORY
;
620 hr
= AntiMonikerImpl_Construct(newAntiMoniker
);
623 HeapFree(GetProcessHeap(),0,newAntiMoniker
);
627 return AntiMonikerImpl_QueryInterface(&newAntiMoniker
->IMoniker_iface
, &IID_IMoniker
,
631 HRESULT WINAPI
AntiMoniker_CreateInstance(IClassFactory
*iface
,
632 IUnknown
*pUnk
, REFIID riid
, void **ppv
)
637 TRACE("(%p, %s, %p)\n", pUnk
, debugstr_guid(riid
), ppv
);
642 return CLASS_E_NOAGGREGATION
;
644 hr
= CreateAntiMoniker(&pMoniker
);
648 hr
= IMoniker_QueryInterface(pMoniker
, riid
, ppv
);
651 IMoniker_Release(pMoniker
);