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"
33 #include "wine/heap.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 */
47 static inline AntiMonikerImpl
*impl_from_IMoniker(IMoniker
*iface
)
49 return CONTAINING_RECORD(iface
, AntiMonikerImpl
, IMoniker_iface
);
52 static inline AntiMonikerImpl
*impl_from_IROTData(IROTData
*iface
)
54 return CONTAINING_RECORD(iface
, AntiMonikerImpl
, IROTData_iface
);
57 static AntiMonikerImpl
*unsafe_impl_from_IMoniker(IMoniker
*iface
);
59 BOOL
is_anti_moniker(IMoniker
*iface
, DWORD
*order
)
61 AntiMonikerImpl
*moniker
= unsafe_impl_from_IMoniker(iface
);
69 *order
= moniker
->count
;
74 /*******************************************************************************
75 * AntiMoniker_QueryInterface
76 *******************************************************************************/
78 AntiMonikerImpl_QueryInterface(IMoniker
* iface
,REFIID riid
,void** ppvObject
)
80 AntiMonikerImpl
*This
= impl_from_IMoniker(iface
);
82 TRACE("(%p,%s,%p)\n",This
,debugstr_guid(riid
),ppvObject
);
89 if (IsEqualIID(&IID_IUnknown
, riid
) ||
90 IsEqualIID(&IID_IPersist
, riid
) ||
91 IsEqualIID(&IID_IPersistStream
, riid
) ||
92 IsEqualIID(&IID_IMoniker
, riid
) ||
93 IsEqualGUID(&CLSID_AntiMoniker
, riid
))
97 else if (IsEqualIID(&IID_IROTData
, riid
))
98 *ppvObject
= &This
->IROTData_iface
;
99 else if (IsEqualIID(&IID_IMarshal
, riid
))
103 hr
= MonikerMarshal_Create(iface
, &This
->pMarshal
);
106 return IUnknown_QueryInterface(This
->pMarshal
, riid
, ppvObject
);
110 return E_NOINTERFACE
;
112 IMoniker_AddRef(iface
);
117 /******************************************************************************
119 ******************************************************************************/
120 static ULONG WINAPI
AntiMonikerImpl_AddRef(IMoniker
*iface
)
122 AntiMonikerImpl
*moniker
= impl_from_IMoniker(iface
);
123 ULONG refcount
= InterlockedIncrement(&moniker
->refcount
);
125 TRACE("%p, refcount %u.\n", iface
, refcount
);
130 /******************************************************************************
131 * AntiMoniker_Release
132 ******************************************************************************/
133 static ULONG WINAPI
AntiMonikerImpl_Release(IMoniker
*iface
)
135 AntiMonikerImpl
*moniker
= impl_from_IMoniker(iface
);
136 ULONG refcount
= InterlockedDecrement(&moniker
->refcount
);
138 TRACE("%p, refcount %u.\n", iface
, refcount
);
142 if (moniker
->pMarshal
) IUnknown_Release(moniker
->pMarshal
);
149 /******************************************************************************
150 * AntiMoniker_GetClassID
151 ******************************************************************************/
152 static HRESULT WINAPI
153 AntiMonikerImpl_GetClassID(IMoniker
* iface
,CLSID
*pClassID
)
155 TRACE("(%p,%p)\n",iface
,pClassID
);
160 *pClassID
= CLSID_AntiMoniker
;
165 /******************************************************************************
166 * AntiMoniker_IsDirty
167 ******************************************************************************/
168 static HRESULT WINAPI
169 AntiMonikerImpl_IsDirty(IMoniker
* iface
)
171 /* Note that the OLE-provided implementations of the IPersistStream::IsDirty
172 method in the OLE-provided moniker interfaces always return S_FALSE because
173 their internal state never changes. */
175 TRACE("(%p)\n",iface
);
180 /******************************************************************************
182 ******************************************************************************/
183 static HRESULT WINAPI
AntiMonikerImpl_Load(IMoniker
*iface
, IStream
*stream
)
185 AntiMonikerImpl
*moniker
= impl_from_IMoniker(iface
);
189 TRACE("%p, %p.\n", iface
, stream
);
191 if (FAILED(hr
= IStream_Read(stream
, &count
, sizeof(count
), NULL
)))
197 moniker
->count
= count
;
202 /******************************************************************************
204 ******************************************************************************/
205 static HRESULT WINAPI
AntiMonikerImpl_Save(IMoniker
*iface
, IStream
*stream
, BOOL clear_dirty
)
207 AntiMonikerImpl
*moniker
= impl_from_IMoniker(iface
);
209 TRACE("%p, %p, %d.\n", iface
, stream
, clear_dirty
);
211 return IStream_Write(stream
, &moniker
->count
, sizeof(moniker
->count
), NULL
);
214 /******************************************************************************
215 * AntiMoniker_GetSizeMax
218 * pcbSize [out] Pointer to size of stream needed to save object
219 ******************************************************************************/
220 static HRESULT WINAPI
221 AntiMonikerImpl_GetSizeMax(IMoniker
* iface
, ULARGE_INTEGER
* pcbSize
)
223 TRACE("(%p,%p)\n",iface
,pcbSize
);
228 /* for more details see AntiMonikerImpl_Save comments */
231 * Normally the sizemax must be sizeof DWORD, but
232 * I tested this function it usually return 16 bytes
233 * more than the number of bytes used by AntiMoniker::Save function
235 pcbSize
->u
.LowPart
= sizeof(DWORD
)+16;
237 pcbSize
->u
.HighPart
=0;
242 /******************************************************************************
243 * AntiMoniker_BindToObject
244 ******************************************************************************/
245 static HRESULT WINAPI
246 AntiMonikerImpl_BindToObject(IMoniker
* iface
, IBindCtx
* pbc
, IMoniker
* pmkToLeft
,
247 REFIID riid
, VOID
** ppvResult
)
249 TRACE("(%p,%p,%p,%s,%p)\n",iface
,pbc
,pmkToLeft
,debugstr_guid(riid
),ppvResult
);
253 /******************************************************************************
254 * AntiMoniker_BindToStorage
255 ******************************************************************************/
256 static HRESULT WINAPI
257 AntiMonikerImpl_BindToStorage(IMoniker
* iface
, IBindCtx
* pbc
, IMoniker
* pmkToLeft
,
258 REFIID riid
, VOID
** ppvResult
)
260 TRACE("(%p,%p,%p,%s,%p)\n",iface
,pbc
,pmkToLeft
,debugstr_guid(riid
),ppvResult
);
264 /******************************************************************************
266 ******************************************************************************/
267 static HRESULT WINAPI
268 AntiMonikerImpl_Reduce(IMoniker
* iface
, IBindCtx
* pbc
, DWORD dwReduceHowFar
,
269 IMoniker
** ppmkToLeft
, IMoniker
** ppmkReduced
)
271 TRACE("(%p,%p,%d,%p,%p)\n",iface
,pbc
,dwReduceHowFar
,ppmkToLeft
,ppmkReduced
);
273 if (ppmkReduced
==NULL
)
276 AntiMonikerImpl_AddRef(iface
);
280 return MK_S_REDUCED_TO_SELF
;
282 /******************************************************************************
283 * AntiMoniker_ComposeWith
284 ******************************************************************************/
285 static HRESULT WINAPI
286 AntiMonikerImpl_ComposeWith(IMoniker
* iface
, IMoniker
* pmkRight
,
287 BOOL fOnlyIfNotGeneric
, IMoniker
** ppmkComposite
)
290 TRACE("(%p,%p,%d,%p)\n",iface
,pmkRight
,fOnlyIfNotGeneric
,ppmkComposite
);
292 if ((ppmkComposite
==NULL
)||(pmkRight
==NULL
))
297 if (fOnlyIfNotGeneric
)
298 return MK_E_NEEDGENERIC
;
300 return CreateGenericComposite(iface
,pmkRight
,ppmkComposite
);
303 /******************************************************************************
305 ******************************************************************************/
306 static HRESULT WINAPI
307 AntiMonikerImpl_Enum(IMoniker
* iface
,BOOL fForward
, IEnumMoniker
** ppenumMoniker
)
309 TRACE("(%p,%d,%p)\n",iface
,fForward
,ppenumMoniker
);
311 if (ppenumMoniker
== NULL
)
314 *ppenumMoniker
= NULL
;
319 /******************************************************************************
320 * AntiMoniker_IsEqual
321 ******************************************************************************/
322 static HRESULT WINAPI
AntiMonikerImpl_IsEqual(IMoniker
*iface
, IMoniker
*other
)
324 AntiMonikerImpl
*moniker
= impl_from_IMoniker(iface
), *other_moniker
;
326 TRACE("%p, %p.\n", iface
, other
);
331 other_moniker
= unsafe_impl_from_IMoniker(other
);
335 return moniker
->count
== other_moniker
->count
? S_OK
: S_FALSE
;
338 /******************************************************************************
340 ******************************************************************************/
341 static HRESULT WINAPI
AntiMonikerImpl_Hash(IMoniker
*iface
, DWORD
*hash
)
343 AntiMonikerImpl
*moniker
= impl_from_IMoniker(iface
);
345 TRACE("%p, %p.\n", iface
, hash
);
350 *hash
= 0x80000000 | moniker
->count
;
355 /******************************************************************************
356 * AntiMoniker_IsRunning
357 ******************************************************************************/
358 static HRESULT WINAPI
359 AntiMonikerImpl_IsRunning(IMoniker
* iface
, IBindCtx
* pbc
, IMoniker
* pmkToLeft
,
360 IMoniker
* pmkNewlyRunning
)
362 IRunningObjectTable
* rot
;
365 TRACE("(%p,%p,%p,%p)\n",iface
,pbc
,pmkToLeft
,pmkNewlyRunning
);
370 res
=IBindCtx_GetRunningObjectTable(pbc
,&rot
);
375 res
= IRunningObjectTable_IsRunning(rot
,iface
);
377 IRunningObjectTable_Release(rot
);
382 /******************************************************************************
383 * AntiMoniker_GetTimeOfLastChange
384 ******************************************************************************/
385 static HRESULT WINAPI
AntiMonikerImpl_GetTimeOfLastChange(IMoniker
* iface
,
390 TRACE("(%p,%p,%p,%p)\n",iface
,pbc
,pmkToLeft
,pAntiTime
);
394 /******************************************************************************
395 * AntiMoniker_Inverse
396 ******************************************************************************/
397 static HRESULT WINAPI
398 AntiMonikerImpl_Inverse(IMoniker
* iface
,IMoniker
** ppmk
)
400 TRACE("(%p,%p)\n",iface
,ppmk
);
407 return MK_E_NOINVERSE
;
410 /******************************************************************************
411 * AntiMoniker_CommonPrefixWith
412 ******************************************************************************/
413 static HRESULT WINAPI
AntiMonikerImpl_CommonPrefixWith(IMoniker
*iface
, IMoniker
*other
, IMoniker
**prefix
)
415 AntiMonikerImpl
*moniker
= impl_from_IMoniker(iface
), *other_moniker
;
418 TRACE("%p, %p, %p.\n", iface
, other
, prefix
);
420 other_moniker
= unsafe_impl_from_IMoniker(other
);
423 if (moniker
->count
<= other_moniker
->count
)
426 hr
= moniker
->count
== other_moniker
->count
? MK_S_US
: MK_S_ME
;
434 IMoniker_AddRef(*prefix
);
438 return MonikerCommonPrefixWith(iface
, other
, prefix
);
441 /******************************************************************************
442 * AntiMoniker_RelativePathTo
443 ******************************************************************************/
444 static HRESULT WINAPI
445 AntiMonikerImpl_RelativePathTo(IMoniker
* iface
,IMoniker
* pmOther
, IMoniker
** ppmkRelPath
)
447 TRACE("(%p,%p,%p)\n",iface
,pmOther
,ppmkRelPath
);
449 if (ppmkRelPath
==NULL
)
452 IMoniker_AddRef(pmOther
);
454 *ppmkRelPath
=pmOther
;
459 /******************************************************************************
460 * AntiMoniker_GetDisplayName
461 ******************************************************************************/
462 static HRESULT WINAPI
463 AntiMonikerImpl_GetDisplayName(IMoniker
*iface
, IBindCtx
*pbc
, IMoniker
*pmkToLeft
, LPOLESTR
*displayname
)
465 AntiMonikerImpl
*moniker
= impl_from_IMoniker(iface
);
466 static const WCHAR nameW
[] = {'\\','.','.'};
470 TRACE("%p, %p, %p, %p.\n", iface
, pbc
, pmkToLeft
, displayname
);
475 if (pmkToLeft
!=NULL
){
476 FIXME("() pmkToLeft!=NULL not implemented\n");
480 *displayname
= ptrW
= CoTaskMemAlloc((moniker
->count
* ARRAY_SIZE(nameW
) + 1) * sizeof(WCHAR
));
482 return E_OUTOFMEMORY
;
484 for (i
= 0; i
< moniker
->count
; ++i
)
485 memcpy(ptrW
+ i
* ARRAY_SIZE(nameW
), nameW
, sizeof(nameW
));
486 ptrW
[moniker
->count
* ARRAY_SIZE(nameW
)] = 0;
491 /******************************************************************************
492 * AntiMoniker_ParseDisplayName
493 ******************************************************************************/
494 static HRESULT WINAPI
495 AntiMonikerImpl_ParseDisplayName(IMoniker
* iface
, IBindCtx
* pbc
,
496 IMoniker
* pmkToLeft
, LPOLESTR pszDisplayName
,
497 ULONG
* pchEaten
, IMoniker
** ppmkOut
)
499 TRACE("(%p,%p,%p,%p,%p,%p)\n",iface
,pbc
,pmkToLeft
,pszDisplayName
,pchEaten
,ppmkOut
);
503 /******************************************************************************
504 * AntiMoniker_IsSystemMoniker
505 ******************************************************************************/
506 static HRESULT WINAPI
507 AntiMonikerImpl_IsSystemMoniker(IMoniker
* iface
,DWORD
* pwdMksys
)
509 TRACE("(%p,%p)\n",iface
,pwdMksys
);
514 (*pwdMksys
)=MKSYS_ANTIMONIKER
;
519 /*******************************************************************************
520 * AntiMonikerIROTData_QueryInterface
521 *******************************************************************************/
522 static HRESULT WINAPI
523 AntiMonikerROTDataImpl_QueryInterface(IROTData
*iface
,REFIID riid
,VOID
** ppvObject
)
525 AntiMonikerImpl
*This
= impl_from_IROTData(iface
);
527 TRACE("(%p,%s,%p)\n",iface
,debugstr_guid(riid
),ppvObject
);
529 return AntiMonikerImpl_QueryInterface(&This
->IMoniker_iface
, riid
, ppvObject
);
532 /***********************************************************************
533 * AntiMonikerIROTData_AddRef
535 static ULONG WINAPI
AntiMonikerROTDataImpl_AddRef(IROTData
*iface
)
537 AntiMonikerImpl
*This
= impl_from_IROTData(iface
);
539 TRACE("(%p)\n",iface
);
541 return AntiMonikerImpl_AddRef(&This
->IMoniker_iface
);
544 /***********************************************************************
545 * AntiMonikerIROTData_Release
547 static ULONG WINAPI
AntiMonikerROTDataImpl_Release(IROTData
* iface
)
549 AntiMonikerImpl
*This
= impl_from_IROTData(iface
);
551 TRACE("(%p)\n",iface
);
553 return AntiMonikerImpl_Release(&This
->IMoniker_iface
);
556 /******************************************************************************
557 * AntiMonikerIROTData_GetComparisonData
558 ******************************************************************************/
559 static HRESULT WINAPI
560 AntiMonikerROTDataImpl_GetComparisonData(IROTData
*iface
, BYTE
*data
, ULONG data_len
, ULONG
*data_req
)
562 AntiMonikerImpl
*moniker
= impl_from_IROTData(iface
);
564 TRACE("%p, %p, %u, %p.\n", iface
, data
, data_len
, data_req
);
566 *data_req
= sizeof(CLSID
) + sizeof(DWORD
);
567 if (data_len
< *data_req
)
568 return E_OUTOFMEMORY
;
570 memcpy(data
, &CLSID_AntiMoniker
, sizeof(CLSID
));
571 memcpy(data
+ sizeof(CLSID
), &moniker
->count
, sizeof(moniker
->count
));
576 /********************************************************************************/
577 /* Virtual function table for the AntiMonikerImpl class which include IPersist,*/
578 /* IPersistStream and IMoniker functions. */
579 static const IMonikerVtbl VT_AntiMonikerImpl
=
581 AntiMonikerImpl_QueryInterface
,
582 AntiMonikerImpl_AddRef
,
583 AntiMonikerImpl_Release
,
584 AntiMonikerImpl_GetClassID
,
585 AntiMonikerImpl_IsDirty
,
586 AntiMonikerImpl_Load
,
587 AntiMonikerImpl_Save
,
588 AntiMonikerImpl_GetSizeMax
,
589 AntiMonikerImpl_BindToObject
,
590 AntiMonikerImpl_BindToStorage
,
591 AntiMonikerImpl_Reduce
,
592 AntiMonikerImpl_ComposeWith
,
593 AntiMonikerImpl_Enum
,
594 AntiMonikerImpl_IsEqual
,
595 AntiMonikerImpl_Hash
,
596 AntiMonikerImpl_IsRunning
,
597 AntiMonikerImpl_GetTimeOfLastChange
,
598 AntiMonikerImpl_Inverse
,
599 AntiMonikerImpl_CommonPrefixWith
,
600 AntiMonikerImpl_RelativePathTo
,
601 AntiMonikerImpl_GetDisplayName
,
602 AntiMonikerImpl_ParseDisplayName
,
603 AntiMonikerImpl_IsSystemMoniker
606 static AntiMonikerImpl
*unsafe_impl_from_IMoniker(IMoniker
*iface
)
608 if (iface
->lpVtbl
!= &VT_AntiMonikerImpl
)
610 return CONTAINING_RECORD(iface
, AntiMonikerImpl
, IMoniker_iface
);
613 /********************************************************************************/
614 /* Virtual function table for the IROTData class. */
615 static const IROTDataVtbl VT_ROTDataImpl
=
617 AntiMonikerROTDataImpl_QueryInterface
,
618 AntiMonikerROTDataImpl_AddRef
,
619 AntiMonikerROTDataImpl_Release
,
620 AntiMonikerROTDataImpl_GetComparisonData
623 HRESULT
create_anti_moniker(DWORD order
, IMoniker
**ret
)
625 AntiMonikerImpl
*moniker
;
627 moniker
= heap_alloc_zero(sizeof(*moniker
));
629 return E_OUTOFMEMORY
;
631 moniker
->IMoniker_iface
.lpVtbl
= &VT_AntiMonikerImpl
;
632 moniker
->IROTData_iface
.lpVtbl
= &VT_ROTDataImpl
;
633 moniker
->refcount
= 1;
634 moniker
->count
= order
;
636 *ret
= &moniker
->IMoniker_iface
;
641 /******************************************************************************
642 * CreateAntiMoniker [OLE32.@]
643 ******************************************************************************/
644 HRESULT WINAPI
CreateAntiMoniker(IMoniker
**moniker
)
646 TRACE("%p.\n", moniker
);
648 return create_anti_moniker(1, moniker
);
651 HRESULT WINAPI
AntiMoniker_CreateInstance(IClassFactory
*iface
,
652 IUnknown
*pUnk
, REFIID riid
, void **ppv
)
657 TRACE("(%p, %s, %p)\n", pUnk
, debugstr_guid(riid
), ppv
);
662 return CLASS_E_NOAGGREGATION
;
664 hr
= CreateAntiMoniker(&pMoniker
);
668 hr
= IMoniker_QueryInterface(pMoniker
, riid
, ppv
);
669 IMoniker_Release(pMoniker
);