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 %lu.\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 %lu.\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 static HRESULT WINAPI
265 AntiMonikerImpl_Reduce(IMoniker
* iface
, IBindCtx
* pbc
, DWORD dwReduceHowFar
,
266 IMoniker
** ppmkToLeft
, IMoniker
** ppmkReduced
)
268 TRACE("%p, %p, %ld, %p, %p.\n", iface
, pbc
, dwReduceHowFar
, ppmkToLeft
, ppmkReduced
);
270 if (ppmkReduced
==NULL
)
273 AntiMonikerImpl_AddRef(iface
);
277 return MK_S_REDUCED_TO_SELF
;
279 /******************************************************************************
280 * AntiMoniker_ComposeWith
281 ******************************************************************************/
282 static HRESULT WINAPI
283 AntiMonikerImpl_ComposeWith(IMoniker
* iface
, IMoniker
* pmkRight
,
284 BOOL fOnlyIfNotGeneric
, IMoniker
** ppmkComposite
)
287 TRACE("(%p,%p,%d,%p)\n",iface
,pmkRight
,fOnlyIfNotGeneric
,ppmkComposite
);
289 if ((ppmkComposite
==NULL
)||(pmkRight
==NULL
))
294 if (fOnlyIfNotGeneric
)
295 return MK_E_NEEDGENERIC
;
297 return CreateGenericComposite(iface
,pmkRight
,ppmkComposite
);
300 /******************************************************************************
302 ******************************************************************************/
303 static HRESULT WINAPI
304 AntiMonikerImpl_Enum(IMoniker
* iface
,BOOL fForward
, IEnumMoniker
** ppenumMoniker
)
306 TRACE("(%p,%d,%p)\n",iface
,fForward
,ppenumMoniker
);
308 if (ppenumMoniker
== NULL
)
311 *ppenumMoniker
= NULL
;
316 /******************************************************************************
317 * AntiMoniker_IsEqual
318 ******************************************************************************/
319 static HRESULT WINAPI
AntiMonikerImpl_IsEqual(IMoniker
*iface
, IMoniker
*other
)
321 AntiMonikerImpl
*moniker
= impl_from_IMoniker(iface
), *other_moniker
;
323 TRACE("%p, %p.\n", iface
, other
);
328 other_moniker
= unsafe_impl_from_IMoniker(other
);
332 return moniker
->count
== other_moniker
->count
? S_OK
: S_FALSE
;
335 /******************************************************************************
337 ******************************************************************************/
338 static HRESULT WINAPI
AntiMonikerImpl_Hash(IMoniker
*iface
, DWORD
*hash
)
340 AntiMonikerImpl
*moniker
= impl_from_IMoniker(iface
);
342 TRACE("%p, %p.\n", iface
, hash
);
347 *hash
= 0x80000000 | moniker
->count
;
352 /******************************************************************************
353 * AntiMoniker_IsRunning
354 ******************************************************************************/
355 static HRESULT WINAPI
356 AntiMonikerImpl_IsRunning(IMoniker
* iface
, IBindCtx
* pbc
, IMoniker
* pmkToLeft
,
357 IMoniker
* pmkNewlyRunning
)
359 IRunningObjectTable
* rot
;
362 TRACE("(%p,%p,%p,%p)\n",iface
,pbc
,pmkToLeft
,pmkNewlyRunning
);
367 res
=IBindCtx_GetRunningObjectTable(pbc
,&rot
);
372 res
= IRunningObjectTable_IsRunning(rot
,iface
);
374 IRunningObjectTable_Release(rot
);
379 /******************************************************************************
380 * AntiMoniker_GetTimeOfLastChange
381 ******************************************************************************/
382 static HRESULT WINAPI
AntiMonikerImpl_GetTimeOfLastChange(IMoniker
* iface
,
387 TRACE("(%p,%p,%p,%p)\n",iface
,pbc
,pmkToLeft
,pAntiTime
);
391 /******************************************************************************
392 * AntiMoniker_Inverse
393 ******************************************************************************/
394 static HRESULT WINAPI
395 AntiMonikerImpl_Inverse(IMoniker
* iface
,IMoniker
** ppmk
)
397 TRACE("(%p,%p)\n",iface
,ppmk
);
404 return MK_E_NOINVERSE
;
407 /******************************************************************************
408 * AntiMoniker_CommonPrefixWith
409 ******************************************************************************/
410 static HRESULT WINAPI
AntiMonikerImpl_CommonPrefixWith(IMoniker
*iface
, IMoniker
*other
, IMoniker
**prefix
)
412 AntiMonikerImpl
*moniker
= impl_from_IMoniker(iface
), *other_moniker
;
415 TRACE("%p, %p, %p.\n", iface
, other
, prefix
);
417 other_moniker
= unsafe_impl_from_IMoniker(other
);
420 if (moniker
->count
<= other_moniker
->count
)
423 hr
= moniker
->count
== other_moniker
->count
? MK_S_US
: MK_S_ME
;
431 IMoniker_AddRef(*prefix
);
435 return MonikerCommonPrefixWith(iface
, other
, prefix
);
438 static HRESULT WINAPI
AntiMonikerImpl_RelativePathTo(IMoniker
*iface
, IMoniker
*other
, IMoniker
**result
)
440 TRACE("%p, %p, %p.\n", iface
, other
, result
);
442 if (!other
|| !result
)
445 IMoniker_AddRef(other
);
451 /******************************************************************************
452 * AntiMoniker_GetDisplayName
453 ******************************************************************************/
454 static HRESULT WINAPI
455 AntiMonikerImpl_GetDisplayName(IMoniker
*iface
, IBindCtx
*pbc
, IMoniker
*pmkToLeft
, LPOLESTR
*displayname
)
457 AntiMonikerImpl
*moniker
= impl_from_IMoniker(iface
);
458 static const WCHAR nameW
[] = {'\\','.','.'};
462 TRACE("%p, %p, %p, %p.\n", iface
, pbc
, pmkToLeft
, displayname
);
467 if (pmkToLeft
!=NULL
){
468 FIXME("() pmkToLeft!=NULL not implemented\n");
472 *displayname
= ptrW
= CoTaskMemAlloc((moniker
->count
* ARRAY_SIZE(nameW
) + 1) * sizeof(WCHAR
));
474 return E_OUTOFMEMORY
;
476 for (i
= 0; i
< moniker
->count
; ++i
)
477 memcpy(ptrW
+ i
* ARRAY_SIZE(nameW
), nameW
, sizeof(nameW
));
478 ptrW
[moniker
->count
* ARRAY_SIZE(nameW
)] = 0;
483 /******************************************************************************
484 * AntiMoniker_ParseDisplayName
485 ******************************************************************************/
486 static HRESULT WINAPI
487 AntiMonikerImpl_ParseDisplayName(IMoniker
* iface
, IBindCtx
* pbc
,
488 IMoniker
* pmkToLeft
, LPOLESTR pszDisplayName
,
489 ULONG
* pchEaten
, IMoniker
** ppmkOut
)
491 TRACE("(%p,%p,%p,%p,%p,%p)\n",iface
,pbc
,pmkToLeft
,pszDisplayName
,pchEaten
,ppmkOut
);
495 /******************************************************************************
496 * AntiMoniker_IsSystemMoniker
497 ******************************************************************************/
498 static HRESULT WINAPI
499 AntiMonikerImpl_IsSystemMoniker(IMoniker
* iface
,DWORD
* pwdMksys
)
501 TRACE("(%p,%p)\n",iface
,pwdMksys
);
506 (*pwdMksys
)=MKSYS_ANTIMONIKER
;
511 /*******************************************************************************
512 * AntiMonikerIROTData_QueryInterface
513 *******************************************************************************/
514 static HRESULT WINAPI
515 AntiMonikerROTDataImpl_QueryInterface(IROTData
*iface
,REFIID riid
,VOID
** ppvObject
)
517 AntiMonikerImpl
*This
= impl_from_IROTData(iface
);
519 TRACE("(%p,%s,%p)\n",iface
,debugstr_guid(riid
),ppvObject
);
521 return AntiMonikerImpl_QueryInterface(&This
->IMoniker_iface
, riid
, ppvObject
);
524 /***********************************************************************
525 * AntiMonikerIROTData_AddRef
527 static ULONG WINAPI
AntiMonikerROTDataImpl_AddRef(IROTData
*iface
)
529 AntiMonikerImpl
*This
= impl_from_IROTData(iface
);
531 TRACE("(%p)\n",iface
);
533 return AntiMonikerImpl_AddRef(&This
->IMoniker_iface
);
536 /***********************************************************************
537 * AntiMonikerIROTData_Release
539 static ULONG WINAPI
AntiMonikerROTDataImpl_Release(IROTData
* iface
)
541 AntiMonikerImpl
*This
= impl_from_IROTData(iface
);
543 TRACE("(%p)\n",iface
);
545 return AntiMonikerImpl_Release(&This
->IMoniker_iface
);
548 /******************************************************************************
549 * AntiMonikerIROTData_GetComparisonData
550 ******************************************************************************/
551 static HRESULT WINAPI
552 AntiMonikerROTDataImpl_GetComparisonData(IROTData
*iface
, BYTE
*data
, ULONG data_len
, ULONG
*data_req
)
554 AntiMonikerImpl
*moniker
= impl_from_IROTData(iface
);
556 TRACE("%p, %p, %lu, %p.\n", iface
, data
, data_len
, data_req
);
558 *data_req
= sizeof(CLSID
) + sizeof(DWORD
);
559 if (data_len
< *data_req
)
560 return E_OUTOFMEMORY
;
562 memcpy(data
, &CLSID_AntiMoniker
, sizeof(CLSID
));
563 memcpy(data
+ sizeof(CLSID
), &moniker
->count
, sizeof(moniker
->count
));
568 /********************************************************************************/
569 /* Virtual function table for the AntiMonikerImpl class which include IPersist,*/
570 /* IPersistStream and IMoniker functions. */
571 static const IMonikerVtbl VT_AntiMonikerImpl
=
573 AntiMonikerImpl_QueryInterface
,
574 AntiMonikerImpl_AddRef
,
575 AntiMonikerImpl_Release
,
576 AntiMonikerImpl_GetClassID
,
577 AntiMonikerImpl_IsDirty
,
578 AntiMonikerImpl_Load
,
579 AntiMonikerImpl_Save
,
580 AntiMonikerImpl_GetSizeMax
,
581 AntiMonikerImpl_BindToObject
,
582 AntiMonikerImpl_BindToStorage
,
583 AntiMonikerImpl_Reduce
,
584 AntiMonikerImpl_ComposeWith
,
585 AntiMonikerImpl_Enum
,
586 AntiMonikerImpl_IsEqual
,
587 AntiMonikerImpl_Hash
,
588 AntiMonikerImpl_IsRunning
,
589 AntiMonikerImpl_GetTimeOfLastChange
,
590 AntiMonikerImpl_Inverse
,
591 AntiMonikerImpl_CommonPrefixWith
,
592 AntiMonikerImpl_RelativePathTo
,
593 AntiMonikerImpl_GetDisplayName
,
594 AntiMonikerImpl_ParseDisplayName
,
595 AntiMonikerImpl_IsSystemMoniker
598 static AntiMonikerImpl
*unsafe_impl_from_IMoniker(IMoniker
*iface
)
600 if (iface
->lpVtbl
!= &VT_AntiMonikerImpl
)
602 return CONTAINING_RECORD(iface
, AntiMonikerImpl
, IMoniker_iface
);
605 /********************************************************************************/
606 /* Virtual function table for the IROTData class. */
607 static const IROTDataVtbl VT_ROTDataImpl
=
609 AntiMonikerROTDataImpl_QueryInterface
,
610 AntiMonikerROTDataImpl_AddRef
,
611 AntiMonikerROTDataImpl_Release
,
612 AntiMonikerROTDataImpl_GetComparisonData
615 HRESULT
create_anti_moniker(DWORD order
, IMoniker
**ret
)
617 AntiMonikerImpl
*moniker
;
619 moniker
= heap_alloc_zero(sizeof(*moniker
));
621 return E_OUTOFMEMORY
;
623 moniker
->IMoniker_iface
.lpVtbl
= &VT_AntiMonikerImpl
;
624 moniker
->IROTData_iface
.lpVtbl
= &VT_ROTDataImpl
;
625 moniker
->refcount
= 1;
626 moniker
->count
= order
;
628 *ret
= &moniker
->IMoniker_iface
;
633 /******************************************************************************
634 * CreateAntiMoniker [OLE32.@]
635 ******************************************************************************/
636 HRESULT WINAPI
CreateAntiMoniker(IMoniker
**moniker
)
638 TRACE("%p.\n", moniker
);
640 return create_anti_moniker(1, moniker
);
643 HRESULT WINAPI
AntiMoniker_CreateInstance(IClassFactory
*iface
,
644 IUnknown
*pUnk
, REFIID riid
, void **ppv
)
649 TRACE("(%p, %s, %p)\n", pUnk
, debugstr_guid(riid
), ppv
);
654 return CLASS_E_NOAGGREGATION
;
656 hr
= CreateAntiMoniker(&pMoniker
);
660 hr
= IMoniker_QueryInterface(pMoniker
, riid
, ppv
);
661 IMoniker_Release(pMoniker
);