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
28 #include "wine/debug.h"
31 WINE_DEFAULT_DEBUG_CHANNEL(ole
);
33 /* AntiMoniker data structure */
34 typedef struct AntiMonikerImpl
{
35 IMoniker IMoniker_iface
;
36 IROTData IROTData_iface
;
38 IUnknown
*pMarshal
; /* custom marshaler */
42 static inline AntiMonikerImpl
*impl_from_IMoniker(IMoniker
*iface
)
44 return CONTAINING_RECORD(iface
, AntiMonikerImpl
, IMoniker_iface
);
47 static inline AntiMonikerImpl
*impl_from_IROTData(IROTData
*iface
)
49 return CONTAINING_RECORD(iface
, AntiMonikerImpl
, IROTData_iface
);
52 static AntiMonikerImpl
*unsafe_impl_from_IMoniker(IMoniker
*iface
);
54 BOOL
is_anti_moniker(IMoniker
*iface
, DWORD
*order
)
56 AntiMonikerImpl
*moniker
= unsafe_impl_from_IMoniker(iface
);
64 *order
= moniker
->count
;
69 /*******************************************************************************
70 * AntiMoniker_QueryInterface
71 *******************************************************************************/
73 AntiMonikerImpl_QueryInterface(IMoniker
* iface
,REFIID riid
,void** ppvObject
)
75 AntiMonikerImpl
*This
= impl_from_IMoniker(iface
);
77 TRACE("(%p,%s,%p)\n",This
,debugstr_guid(riid
),ppvObject
);
84 if (IsEqualIID(&IID_IUnknown
, riid
) ||
85 IsEqualIID(&IID_IPersist
, riid
) ||
86 IsEqualIID(&IID_IPersistStream
, riid
) ||
87 IsEqualIID(&IID_IMoniker
, riid
) ||
88 IsEqualGUID(&CLSID_AntiMoniker
, riid
))
92 else if (IsEqualIID(&IID_IROTData
, riid
))
93 *ppvObject
= &This
->IROTData_iface
;
94 else if (IsEqualIID(&IID_IMarshal
, riid
))
98 hr
= MonikerMarshal_Create(iface
, &This
->pMarshal
);
101 return IUnknown_QueryInterface(This
->pMarshal
, riid
, ppvObject
);
105 return E_NOINTERFACE
;
107 IMoniker_AddRef(iface
);
112 /******************************************************************************
114 ******************************************************************************/
115 static ULONG WINAPI
AntiMonikerImpl_AddRef(IMoniker
*iface
)
117 AntiMonikerImpl
*moniker
= impl_from_IMoniker(iface
);
118 ULONG refcount
= InterlockedIncrement(&moniker
->refcount
);
120 TRACE("%p, refcount %lu.\n", iface
, refcount
);
125 /******************************************************************************
126 * AntiMoniker_Release
127 ******************************************************************************/
128 static ULONG WINAPI
AntiMonikerImpl_Release(IMoniker
*iface
)
130 AntiMonikerImpl
*moniker
= impl_from_IMoniker(iface
);
131 ULONG refcount
= InterlockedDecrement(&moniker
->refcount
);
133 TRACE("%p, refcount %lu.\n", iface
, refcount
);
137 if (moniker
->pMarshal
) IUnknown_Release(moniker
->pMarshal
);
144 /******************************************************************************
145 * AntiMoniker_GetClassID
146 ******************************************************************************/
147 static HRESULT WINAPI
148 AntiMonikerImpl_GetClassID(IMoniker
* iface
,CLSID
*pClassID
)
150 TRACE("(%p,%p)\n",iface
,pClassID
);
155 *pClassID
= CLSID_AntiMoniker
;
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
);
175 /******************************************************************************
177 ******************************************************************************/
178 static HRESULT WINAPI
AntiMonikerImpl_Load(IMoniker
*iface
, IStream
*stream
)
180 AntiMonikerImpl
*moniker
= impl_from_IMoniker(iface
);
184 TRACE("%p, %p.\n", iface
, stream
);
186 if (FAILED(hr
= IStream_Read(stream
, &count
, sizeof(count
), NULL
)))
192 moniker
->count
= count
;
197 /******************************************************************************
199 ******************************************************************************/
200 static HRESULT WINAPI
AntiMonikerImpl_Save(IMoniker
*iface
, IStream
*stream
, BOOL clear_dirty
)
202 AntiMonikerImpl
*moniker
= impl_from_IMoniker(iface
);
204 TRACE("%p, %p, %d.\n", iface
, stream
, clear_dirty
);
206 return IStream_Write(stream
, &moniker
->count
, sizeof(moniker
->count
), NULL
);
209 /******************************************************************************
210 * AntiMoniker_GetSizeMax
213 * pcbSize [out] Pointer to size of stream needed to save object
214 ******************************************************************************/
215 static HRESULT WINAPI
216 AntiMonikerImpl_GetSizeMax(IMoniker
* iface
, ULARGE_INTEGER
* pcbSize
)
218 TRACE("(%p,%p)\n",iface
,pcbSize
);
223 /* for more details see AntiMonikerImpl_Save comments */
226 * Normally the sizemax must be sizeof DWORD, but
227 * I tested this function it usually return 16 bytes
228 * more than the number of bytes used by AntiMoniker::Save function
230 pcbSize
->u
.LowPart
= sizeof(DWORD
)+16;
232 pcbSize
->u
.HighPart
=0;
237 /******************************************************************************
238 * AntiMoniker_BindToObject
239 ******************************************************************************/
240 static HRESULT WINAPI
241 AntiMonikerImpl_BindToObject(IMoniker
* iface
, IBindCtx
* pbc
, IMoniker
* pmkToLeft
,
242 REFIID riid
, VOID
** ppvResult
)
244 TRACE("(%p,%p,%p,%s,%p)\n",iface
,pbc
,pmkToLeft
,debugstr_guid(riid
),ppvResult
);
248 /******************************************************************************
249 * AntiMoniker_BindToStorage
250 ******************************************************************************/
251 static HRESULT WINAPI
252 AntiMonikerImpl_BindToStorage(IMoniker
* iface
, IBindCtx
* pbc
, IMoniker
* pmkToLeft
,
253 REFIID riid
, VOID
** ppvResult
)
255 TRACE("(%p,%p,%p,%s,%p)\n",iface
,pbc
,pmkToLeft
,debugstr_guid(riid
),ppvResult
);
259 static HRESULT WINAPI
260 AntiMonikerImpl_Reduce(IMoniker
* iface
, IBindCtx
* pbc
, DWORD dwReduceHowFar
,
261 IMoniker
** ppmkToLeft
, IMoniker
** ppmkReduced
)
263 TRACE("%p, %p, %ld, %p, %p.\n", iface
, pbc
, dwReduceHowFar
, ppmkToLeft
, ppmkReduced
);
265 if (ppmkReduced
==NULL
)
268 AntiMonikerImpl_AddRef(iface
);
272 return MK_S_REDUCED_TO_SELF
;
274 /******************************************************************************
275 * AntiMoniker_ComposeWith
276 ******************************************************************************/
277 static HRESULT WINAPI
278 AntiMonikerImpl_ComposeWith(IMoniker
* iface
, IMoniker
* pmkRight
,
279 BOOL fOnlyIfNotGeneric
, IMoniker
** ppmkComposite
)
282 TRACE("(%p,%p,%d,%p)\n",iface
,pmkRight
,fOnlyIfNotGeneric
,ppmkComposite
);
284 if ((ppmkComposite
==NULL
)||(pmkRight
==NULL
))
289 if (fOnlyIfNotGeneric
)
290 return MK_E_NEEDGENERIC
;
292 return CreateGenericComposite(iface
,pmkRight
,ppmkComposite
);
295 static HRESULT WINAPI
AntiMonikerImpl_Enum(IMoniker
*iface
, BOOL forward
, IEnumMoniker
**ppenumMoniker
)
297 TRACE("%p, %d, %p.\n", iface
, forward
, ppenumMoniker
);
299 if (ppenumMoniker
== NULL
)
302 *ppenumMoniker
= NULL
;
307 /******************************************************************************
308 * AntiMoniker_IsEqual
309 ******************************************************************************/
310 static HRESULT WINAPI
AntiMonikerImpl_IsEqual(IMoniker
*iface
, IMoniker
*other
)
312 AntiMonikerImpl
*moniker
= impl_from_IMoniker(iface
), *other_moniker
;
314 TRACE("%p, %p.\n", iface
, other
);
319 other_moniker
= unsafe_impl_from_IMoniker(other
);
323 return moniker
->count
== other_moniker
->count
? S_OK
: S_FALSE
;
326 /******************************************************************************
328 ******************************************************************************/
329 static HRESULT WINAPI
AntiMonikerImpl_Hash(IMoniker
*iface
, DWORD
*hash
)
331 AntiMonikerImpl
*moniker
= impl_from_IMoniker(iface
);
333 TRACE("%p, %p.\n", iface
, hash
);
338 *hash
= 0x80000000 | moniker
->count
;
343 /******************************************************************************
344 * AntiMoniker_IsRunning
345 ******************************************************************************/
346 static HRESULT WINAPI
347 AntiMonikerImpl_IsRunning(IMoniker
* iface
, IBindCtx
* pbc
, IMoniker
* pmkToLeft
,
348 IMoniker
* pmkNewlyRunning
)
350 IRunningObjectTable
* rot
;
353 TRACE("(%p,%p,%p,%p)\n",iface
,pbc
,pmkToLeft
,pmkNewlyRunning
);
358 res
=IBindCtx_GetRunningObjectTable(pbc
,&rot
);
363 res
= IRunningObjectTable_IsRunning(rot
,iface
);
365 IRunningObjectTable_Release(rot
);
370 /******************************************************************************
371 * AntiMoniker_GetTimeOfLastChange
372 ******************************************************************************/
373 static HRESULT WINAPI
AntiMonikerImpl_GetTimeOfLastChange(IMoniker
* iface
,
378 TRACE("(%p,%p,%p,%p)\n",iface
,pbc
,pmkToLeft
,pAntiTime
);
382 /******************************************************************************
383 * AntiMoniker_Inverse
384 ******************************************************************************/
385 static HRESULT WINAPI
386 AntiMonikerImpl_Inverse(IMoniker
* iface
,IMoniker
** ppmk
)
388 TRACE("(%p,%p)\n",iface
,ppmk
);
395 return MK_E_NOINVERSE
;
398 /******************************************************************************
399 * AntiMoniker_CommonPrefixWith
400 ******************************************************************************/
401 static HRESULT WINAPI
AntiMonikerImpl_CommonPrefixWith(IMoniker
*iface
, IMoniker
*other
, IMoniker
**prefix
)
403 AntiMonikerImpl
*moniker
= impl_from_IMoniker(iface
), *other_moniker
;
406 TRACE("%p, %p, %p.\n", iface
, other
, prefix
);
408 other_moniker
= unsafe_impl_from_IMoniker(other
);
411 if (moniker
->count
<= other_moniker
->count
)
414 hr
= moniker
->count
== other_moniker
->count
? MK_S_US
: MK_S_ME
;
422 IMoniker_AddRef(*prefix
);
426 return MonikerCommonPrefixWith(iface
, other
, prefix
);
429 static HRESULT WINAPI
AntiMonikerImpl_RelativePathTo(IMoniker
*iface
, IMoniker
*other
, IMoniker
**result
)
431 TRACE("%p, %p, %p.\n", iface
, other
, result
);
433 if (!other
|| !result
)
436 IMoniker_AddRef(other
);
442 /******************************************************************************
443 * AntiMoniker_GetDisplayName
444 ******************************************************************************/
445 static HRESULT WINAPI
446 AntiMonikerImpl_GetDisplayName(IMoniker
*iface
, IBindCtx
*pbc
, IMoniker
*pmkToLeft
, LPOLESTR
*displayname
)
448 AntiMonikerImpl
*moniker
= impl_from_IMoniker(iface
);
449 static const WCHAR nameW
[] = {'\\','.','.'};
453 TRACE("%p, %p, %p, %p.\n", iface
, pbc
, pmkToLeft
, displayname
);
458 if (pmkToLeft
!=NULL
){
459 FIXME("() pmkToLeft!=NULL not implemented\n");
463 *displayname
= ptrW
= CoTaskMemAlloc((moniker
->count
* ARRAY_SIZE(nameW
) + 1) * sizeof(WCHAR
));
465 return E_OUTOFMEMORY
;
467 for (i
= 0; i
< moniker
->count
; ++i
)
468 memcpy(ptrW
+ i
* ARRAY_SIZE(nameW
), nameW
, sizeof(nameW
));
469 ptrW
[moniker
->count
* ARRAY_SIZE(nameW
)] = 0;
474 /******************************************************************************
475 * AntiMoniker_ParseDisplayName
476 ******************************************************************************/
477 static HRESULT WINAPI
478 AntiMonikerImpl_ParseDisplayName(IMoniker
* iface
, IBindCtx
* pbc
,
479 IMoniker
* pmkToLeft
, LPOLESTR pszDisplayName
,
480 ULONG
* pchEaten
, IMoniker
** ppmkOut
)
482 TRACE("(%p,%p,%p,%p,%p,%p)\n",iface
,pbc
,pmkToLeft
,pszDisplayName
,pchEaten
,ppmkOut
);
486 /******************************************************************************
487 * AntiMoniker_IsSystemMoniker
488 ******************************************************************************/
489 static HRESULT WINAPI
490 AntiMonikerImpl_IsSystemMoniker(IMoniker
* iface
,DWORD
* pwdMksys
)
492 TRACE("(%p,%p)\n",iface
,pwdMksys
);
497 (*pwdMksys
)=MKSYS_ANTIMONIKER
;
502 /*******************************************************************************
503 * AntiMonikerIROTData_QueryInterface
504 *******************************************************************************/
505 static HRESULT WINAPI
506 AntiMonikerROTDataImpl_QueryInterface(IROTData
*iface
,REFIID riid
,VOID
** ppvObject
)
508 AntiMonikerImpl
*This
= impl_from_IROTData(iface
);
510 TRACE("(%p,%s,%p)\n",iface
,debugstr_guid(riid
),ppvObject
);
512 return AntiMonikerImpl_QueryInterface(&This
->IMoniker_iface
, riid
, ppvObject
);
515 /***********************************************************************
516 * AntiMonikerIROTData_AddRef
518 static ULONG WINAPI
AntiMonikerROTDataImpl_AddRef(IROTData
*iface
)
520 AntiMonikerImpl
*This
= impl_from_IROTData(iface
);
522 TRACE("(%p)\n",iface
);
524 return AntiMonikerImpl_AddRef(&This
->IMoniker_iface
);
527 /***********************************************************************
528 * AntiMonikerIROTData_Release
530 static ULONG WINAPI
AntiMonikerROTDataImpl_Release(IROTData
* iface
)
532 AntiMonikerImpl
*This
= impl_from_IROTData(iface
);
534 TRACE("(%p)\n",iface
);
536 return AntiMonikerImpl_Release(&This
->IMoniker_iface
);
539 /******************************************************************************
540 * AntiMonikerIROTData_GetComparisonData
541 ******************************************************************************/
542 static HRESULT WINAPI
543 AntiMonikerROTDataImpl_GetComparisonData(IROTData
*iface
, BYTE
*data
, ULONG data_len
, ULONG
*data_req
)
545 AntiMonikerImpl
*moniker
= impl_from_IROTData(iface
);
547 TRACE("%p, %p, %lu, %p.\n", iface
, data
, data_len
, data_req
);
549 *data_req
= sizeof(CLSID
) + sizeof(DWORD
);
550 if (data_len
< *data_req
)
551 return E_OUTOFMEMORY
;
553 memcpy(data
, &CLSID_AntiMoniker
, sizeof(CLSID
));
554 memcpy(data
+ sizeof(CLSID
), &moniker
->count
, sizeof(moniker
->count
));
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 static AntiMonikerImpl
*unsafe_impl_from_IMoniker(IMoniker
*iface
)
591 if (iface
->lpVtbl
!= &VT_AntiMonikerImpl
)
593 return CONTAINING_RECORD(iface
, AntiMonikerImpl
, IMoniker_iface
);
596 /********************************************************************************/
597 /* Virtual function table for the IROTData class. */
598 static const IROTDataVtbl VT_ROTDataImpl
=
600 AntiMonikerROTDataImpl_QueryInterface
,
601 AntiMonikerROTDataImpl_AddRef
,
602 AntiMonikerROTDataImpl_Release
,
603 AntiMonikerROTDataImpl_GetComparisonData
606 HRESULT
create_anti_moniker(DWORD order
, IMoniker
**ret
)
608 AntiMonikerImpl
*moniker
;
610 if (!(moniker
= calloc(1, sizeof(*moniker
))))
611 return E_OUTOFMEMORY
;
613 moniker
->IMoniker_iface
.lpVtbl
= &VT_AntiMonikerImpl
;
614 moniker
->IROTData_iface
.lpVtbl
= &VT_ROTDataImpl
;
615 moniker
->refcount
= 1;
616 moniker
->count
= order
;
618 *ret
= &moniker
->IMoniker_iface
;
623 /******************************************************************************
624 * CreateAntiMoniker [OLE32.@]
625 ******************************************************************************/
626 HRESULT WINAPI
CreateAntiMoniker(IMoniker
**moniker
)
628 TRACE("%p.\n", moniker
);
630 return create_anti_moniker(1, moniker
);
633 HRESULT WINAPI
AntiMoniker_CreateInstance(IClassFactory
*iface
,
634 IUnknown
*pUnk
, REFIID riid
, void **ppv
)
639 TRACE("(%p, %s, %p)\n", pUnk
, debugstr_guid(riid
), ppv
);
644 return CLASS_E_NOAGGREGATION
;
646 hr
= CreateAntiMoniker(&pMoniker
);
650 hr
= IMoniker_QueryInterface(pMoniker
, riid
, ppv
);
651 IMoniker_Release(pMoniker
);