1 /***************************************************************************************
2 * CompositeMonikers implementation
4 * Copyright 1999 Noomen Hamza
5 ***************************************************************************************/
9 #include "debugtools.h"
10 #include "wine/obj_inplace.h"
13 DEFAULT_DEBUG_CHANNEL(ole
)
15 #define BLOCK_TAB_SIZE 5 /* represent the first size table and it's increment block size */
17 /* CompositeMoniker data structure */
18 typedef struct CompositeMonikerImpl
{
20 ICOM_VTABLE(IMoniker
)* lpvtbl1
; /* VTable relative to the IMoniker interface.*/
22 /* The ROT (RunningObjectTable implementation) uses the IROTData interface to test whether
23 * two monikers are equal. That's whay IROTData interface is implemented by monikers.
25 ICOM_VTABLE(IROTData
)* lpvtbl2
; /* VTable relative to the IROTData interface.*/
27 ULONG ref
; /* reference counter for this object */
29 IMoniker
** tabMoniker
; /* dynamaic table containing all components (monikers) of this composite moniker */
31 ULONG tabSize
; /* size of tabMoniker */
33 ULONG tabLastIndex
; /* first free index in tabMoniker */
35 } CompositeMonikerImpl
;
38 /* EnumMoniker data structure */
39 typedef struct EnumMonikerImpl
{
41 ICOM_VFIELD(IEnumMoniker
); /* VTable relative to the IEnumMoniker interface.*/
43 ULONG ref
; /* reference counter for this object */
45 IMoniker
** tabMoniker
; /* dynamic table containing the enumerated monikers */
47 ULONG tabSize
; /* size of tabMoniker */
49 ULONG currentPos
; /* index pointer on the current moniker */
54 /********************************************************************************/
55 /* CompositeMoniker prototype functions : */
57 /* IUnknown prototype functions */
58 static HRESULT WINAPI
CompositeMonikerImpl_QueryInterface(IMoniker
* iface
,REFIID riid
,void** ppvObject
);
59 static ULONG WINAPI
CompositeMonikerImpl_AddRef(IMoniker
* iface
);
60 static ULONG WINAPI
CompositeMonikerImpl_Release(IMoniker
* iface
);
62 /* IPersist prototype functions */
63 static HRESULT WINAPI
CompositeMonikerImpl_GetClassID(IMoniker
* iface
, CLSID
*pClassID
);
65 /* IPersistStream prototype functions */
66 static HRESULT WINAPI
CompositeMonikerImpl_IsDirty(IMoniker
* iface
);
67 static HRESULT WINAPI
CompositeMonikerImpl_Load(IMoniker
* iface
, IStream
* pStm
);
68 static HRESULT WINAPI
CompositeMonikerImpl_Save(IMoniker
* iface
, IStream
* pStm
, BOOL fClearDirty
);
69 static HRESULT WINAPI
CompositeMonikerImpl_GetSizeMax(IMoniker
* iface
, ULARGE_INTEGER
* pcbSize
);
71 /* IMoniker prototype functions */
72 static HRESULT WINAPI
CompositeMonikerImpl_BindToObject(IMoniker
* iface
,IBindCtx
* pbc
, IMoniker
* pmkToLeft
, REFIID riid
, VOID
** ppvResult
);
73 static HRESULT WINAPI
CompositeMonikerImpl_BindToStorage(IMoniker
* iface
,IBindCtx
* pbc
, IMoniker
* pmkToLeft
, REFIID riid
, VOID
** ppvResult
);
74 static HRESULT WINAPI
CompositeMonikerImpl_Reduce(IMoniker
* iface
,IBindCtx
* pbc
, DWORD dwReduceHowFar
,IMoniker
** ppmkToLeft
, IMoniker
** ppmkReduced
);
75 static HRESULT WINAPI
CompositeMonikerImpl_ComposeWith(IMoniker
* iface
,IMoniker
* pmkRight
,BOOL fOnlyIfNotGeneric
, IMoniker
** ppmkComposite
);
76 static HRESULT WINAPI
CompositeMonikerImpl_Enum(IMoniker
* iface
,BOOL fForward
, IEnumMoniker
** ppenumMoniker
);
77 static HRESULT WINAPI
CompositeMonikerImpl_IsEqual(IMoniker
* iface
,IMoniker
* pmkOtherMoniker
);
78 static HRESULT WINAPI
CompositeMonikerImpl_Hash(IMoniker
* iface
,DWORD
* pdwHash
);
79 static HRESULT WINAPI
CompositeMonikerImpl_IsRunning(IMoniker
* iface
,IBindCtx
* pbc
, IMoniker
* pmkToLeft
, IMoniker
* pmkNewlyRunning
);
80 static HRESULT WINAPI
CompositeMonikerImpl_GetTimeOfLastChange(IMoniker
* iface
, IBindCtx
* pbc
, IMoniker
* pmkToLeft
, FILETIME
* pCompositeTime
);
81 static HRESULT WINAPI
CompositeMonikerImpl_Inverse(IMoniker
* iface
,IMoniker
** ppmk
);
82 static HRESULT WINAPI
CompositeMonikerImpl_CommonPrefixWith(IMoniker
* iface
,IMoniker
* pmkOther
, IMoniker
** ppmkPrefix
);
83 static HRESULT WINAPI
CompositeMonikerImpl_RelativePathTo(IMoniker
* iface
,IMoniker
* pmOther
, IMoniker
** ppmkRelPath
);
84 static HRESULT WINAPI
CompositeMonikerImpl_GetDisplayName(IMoniker
* iface
,IBindCtx
* pbc
, IMoniker
* pmkToLeft
, LPOLESTR
*ppszDisplayName
);
85 static HRESULT WINAPI
CompositeMonikerImpl_ParseDisplayName(IMoniker
* iface
,IBindCtx
* pbc
, IMoniker
* pmkToLeft
, LPOLESTR pszDisplayName
, ULONG
* pchEaten
, IMoniker
** ppmkOut
);
86 static HRESULT WINAPI
CompositeMonikerImpl_IsSystemMoniker(IMoniker
* iface
,DWORD
* pwdMksys
);
88 /********************************************************************************/
89 /* IROTData prototype functions */
91 /* IUnknown prototype functions */
92 static HRESULT WINAPI
CompositeMonikerROTDataImpl_QueryInterface(IROTData
* iface
,REFIID riid
,VOID
** ppvObject
);
93 static ULONG WINAPI
CompositeMonikerROTDataImpl_AddRef(IROTData
* iface
);
94 static ULONG WINAPI
CompositeMonikerROTDataImpl_Release(IROTData
* iface
);
96 /* IROTData prototype function */
97 static HRESULT WINAPI
CompositeMonikerROTDataImpl_GetComparaisonData(IROTData
* iface
,BYTE
* pbData
,ULONG cbMax
,ULONG
* pcbData
);
99 /* Local function used by CompositeMoniker implementation */
100 HRESULT WINAPI
CompositeMonikerImpl_Construct(CompositeMonikerImpl
* This
,LPMONIKER pmkFirst
, LPMONIKER pmkRest
);
101 HRESULT WINAPI
CompositeMonikerImpl_Destroy(CompositeMonikerImpl
* iface
);
103 /********************************************************************************/
104 /* IEnumMoniker prototype functions */
106 /* IUnknown prototype functions */
107 static HRESULT WINAPI
EnumMonikerImpl_QueryInterface(IEnumMoniker
* iface
,REFIID riid
,void** ppvObject
);
108 static ULONG WINAPI
EnumMonikerImpl_AddRef(IEnumMoniker
* iface
);
109 static ULONG WINAPI
EnumMonikerImpl_Release(IEnumMoniker
* iface
);
111 /* IEnumMonker prototype functions */
112 static HRESULT WINAPI
EnumMonikerImpl_Next(IEnumMoniker
* iface
,ULONG celt
,IMoniker
** rgelt
,ULONG
* pceltFetched
);
113 static HRESULT WINAPI
EnumMonikerImpl_Skip(IEnumMoniker
* iface
,ULONG celt
);
114 static HRESULT WINAPI
EnumMonikerImpl_Reset(IEnumMoniker
* iface
);
115 static HRESULT WINAPI
EnumMonikerImpl_Clone(IEnumMoniker
* iface
,IEnumMoniker
** ppenum
);
117 HRESULT WINAPI
EnumMonikerImpl_CreateEnumMoniker(IMoniker
** tabMoniker
,ULONG tabSize
,ULONG currentPos
,BOOL leftToRigth
,IEnumMoniker
** ppmk
);
119 /********************************************************************************/
120 /* Virtual function table for the CompositeMonikerImpl class witch include */
121 /* Ipersist, IPersistStream and IMoniker functions. */
123 static ICOM_VTABLE(IMoniker
) VT_CompositeMonikerImpl
=
125 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
126 CompositeMonikerImpl_QueryInterface
,
127 CompositeMonikerImpl_AddRef
,
128 CompositeMonikerImpl_Release
,
129 CompositeMonikerImpl_GetClassID
,
130 CompositeMonikerImpl_IsDirty
,
131 CompositeMonikerImpl_Load
,
132 CompositeMonikerImpl_Save
,
133 CompositeMonikerImpl_GetSizeMax
,
134 CompositeMonikerImpl_BindToObject
,
135 CompositeMonikerImpl_BindToStorage
,
136 CompositeMonikerImpl_Reduce
,
137 CompositeMonikerImpl_ComposeWith
,
138 CompositeMonikerImpl_Enum
,
139 CompositeMonikerImpl_IsEqual
,
140 CompositeMonikerImpl_Hash
,
141 CompositeMonikerImpl_IsRunning
,
142 CompositeMonikerImpl_GetTimeOfLastChange
,
143 CompositeMonikerImpl_Inverse
,
144 CompositeMonikerImpl_CommonPrefixWith
,
145 CompositeMonikerImpl_RelativePathTo
,
146 CompositeMonikerImpl_GetDisplayName
,
147 CompositeMonikerImpl_ParseDisplayName
,
148 CompositeMonikerImpl_IsSystemMoniker
151 /********************************************************************************/
152 /* Virtual function table for the IROTData class. */
153 static ICOM_VTABLE(IROTData
) VT_ROTDataImpl
=
155 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
156 CompositeMonikerROTDataImpl_QueryInterface
,
157 CompositeMonikerROTDataImpl_AddRef
,
158 CompositeMonikerROTDataImpl_Release
,
159 CompositeMonikerROTDataImpl_GetComparaisonData
162 /********************************************************************************/
163 /* Virtual function table for the IROTData class */
164 static ICOM_VTABLE(IEnumMoniker
) VT_EnumMonikerImpl
=
166 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
167 EnumMonikerImpl_QueryInterface
,
168 EnumMonikerImpl_AddRef
,
169 EnumMonikerImpl_Release
,
170 EnumMonikerImpl_Next
,
171 EnumMonikerImpl_Skip
,
172 EnumMonikerImpl_Reset
,
173 EnumMonikerImpl_Clone
176 /*******************************************************************************
177 * CompositeMoniker_QueryInterface
178 *******************************************************************************/
179 HRESULT WINAPI
CompositeMonikerImpl_QueryInterface(IMoniker
* iface
,REFIID riid
,void** ppvObject
)
181 ICOM_THIS(CompositeMonikerImpl
,iface
);
183 TRACE("(%p,%p,%p)\n",This
,riid
,ppvObject
);
185 /* Perform a sanity check on the parameters.*/
186 if ( (This
==0) || (ppvObject
==0) )
189 /* Initialize the return parameter */
192 /* Compare the riid with the interface IDs implemented by this object.*/
193 if (IsEqualIID(&IID_IUnknown
, riid
) ||
194 IsEqualIID(&IID_IPersist
, riid
) ||
195 IsEqualIID(&IID_IPersistStream
, riid
) ||
196 IsEqualIID(&IID_IMoniker
, riid
)
199 else if (IsEqualIID(&IID_IROTData
, riid
))
200 *ppvObject
= (IROTData
*)&(This
->lpvtbl2
);
202 /* Check that we obtained an interface.*/
204 return E_NOINTERFACE
;
206 /* Query Interface always increases the reference count by one when it is successful */
207 CompositeMonikerImpl_AddRef(iface
);
212 /******************************************************************************
213 * CompositeMoniker_AddRef
214 ******************************************************************************/
215 ULONG WINAPI
CompositeMonikerImpl_AddRef(IMoniker
* iface
)
217 ICOM_THIS(CompositeMonikerImpl
,iface
);
219 TRACE("(%p)\n",This
);
221 return ++(This
->ref
);
224 /******************************************************************************
225 * CompositeMoniker_Release
226 ******************************************************************************/
227 ULONG WINAPI
CompositeMonikerImpl_Release(IMoniker
* iface
)
229 ICOM_THIS(CompositeMonikerImpl
,iface
);
232 TRACE("(%p)\n",This
);
236 /* destroy the object if there's no more reference on it */
239 /* release all the components before destroying this object */
240 for (i
=0;i
<This
->tabLastIndex
;i
++)
241 IMoniker_Release(This
->tabMoniker
[i
]);
243 CompositeMonikerImpl_Destroy(This
);
250 /******************************************************************************
251 * CompositeMoniker_GetClassID
252 ******************************************************************************/
253 HRESULT WINAPI
CompositeMonikerImpl_GetClassID(IMoniker
* iface
,CLSID
*pClassID
)
255 TRACE("(%p,%p),stub!\n",iface
,pClassID
);
260 *pClassID
= CLSID_CompositeMoniker
;
265 /******************************************************************************
266 * CompositeMoniker_IsDirty
267 ******************************************************************************/
268 HRESULT WINAPI
CompositeMonikerImpl_IsDirty(IMoniker
* iface
)
270 /* Note that the OLE-provided implementations of the IPersistStream::IsDirty
271 method in the OLE-provided moniker interfaces always return S_FALSE because
272 their internal state never changes. */
274 TRACE("(%p)\n",iface
);
279 /******************************************************************************
280 * CompositeMoniker_Load
281 ******************************************************************************/
282 HRESULT WINAPI
CompositeMonikerImpl_Load(IMoniker
* iface
,IStream
* pStm
)
289 ICOM_THIS(CompositeMonikerImpl
,iface
);
291 TRACE("(%p,%p)\n",iface
,pStm
);
293 /* this function call OleLoadFromStream function for each moniker within this object */
295 /* read the a constant writen by CompositeMonikerImpl_Save (see CompositeMonikerImpl_Save for more details)*/
296 res
=IStream_Read(pStm
,&constant
,sizeof(DWORD
),NULL
);
298 if (SUCCEEDED(res
)&& constant
!=3)
303 res
=OleLoadFromStream(pStm
,&IID_IMoniker
,(void**)&This
->tabMoniker
[This
->tabLastIndex
]);
305 res
=ReadClassStm(pStm
,&clsid
);
306 DPRINTF("res=%ld",res
);
310 if (IsEqualIID(&clsid
,&CLSID_FileMoniker
)){
311 res
=CreateFileMoniker(string
,&This
->tabMoniker
[This
->tabLastIndex
]);
314 res
=IMoniker_Load(This
->tabMoniker
[This
->tabLastIndex
],pStm
);
318 else if (IsEqualIID(&clsid
,&CLSID_ItemMoniker
)){
319 CreateItemMoniker(string
,string
,&This
->tabMoniker
[This
->tabLastIndex
]);
322 IMoniker_Load(This
->tabMoniker
[This
->tabLastIndex
],pStm
);
326 else if (IsEqualIID(&clsid
,&CLSID_AntiMoniker
)){
327 CreateAntiMoniker(&This
->tabMoniker
[This
->tabLastIndex
]);
330 IMoniker_Load(This
->tabMoniker
[This
->tabLastIndex
],pStm
);
334 else if (IsEqualIID(&clsid
,&CLSID_CompositeMoniker
))
343 /* resize the table if needed */
344 if (++This
->tabLastIndex
==This
->tabSize
){
346 This
->tabSize
+=BLOCK_TAB_SIZE
;
347 This
->tabMoniker
=HeapReAlloc(GetProcessHeap(),0,This
->tabMoniker
,This
->tabSize
*sizeof(IMoniker
));
349 if (This
->tabMoniker
==NULL
)
350 return E_OUTOFMEMORY
;
357 /******************************************************************************
358 * CompositeMoniker_Save
359 ******************************************************************************/
360 HRESULT WINAPI
CompositeMonikerImpl_Save(IMoniker
* iface
,IStream
* pStm
,BOOL fClearDirty
)
363 IEnumMoniker
*enumMk
;
367 TRACE("(%p,%p,%d)\n",iface
,pStm
,fClearDirty
);
369 /* this function call OleSaveToStream function for each moniker within this object */
371 /* when I tested this function in windows system ! I usually found this constant in the begining of */
372 /* the stream I dont known why (there's no indication in specification) ! */
373 res
=IStream_Write(pStm
,&constant
,sizeof(constant
),NULL
);
375 IMoniker_Enum(iface
,TRUE
,&enumMk
);
377 while(IEnumMoniker_Next(enumMk
,1,&pmk
,NULL
)==S_OK
){
379 res
=OleSaveToStream((IPersistStream
*)pmk
,pStm
);
381 IMoniker_Release(pmk
);
385 IEnumMoniker_Release(pmk
);
390 IEnumMoniker_Release(enumMk
);
395 /******************************************************************************
396 * CompositeMoniker_GetSizeMax
397 ******************************************************************************/
398 HRESULT WINAPI
CompositeMonikerImpl_GetSizeMax(IMoniker
* iface
,ULARGE_INTEGER
* pcbSize
)
400 IEnumMoniker
*enumMk
;
402 ULARGE_INTEGER ptmpSize
;
404 /* the sizeMax of this object is calculated by calling GetSizeMax on each moniker within this object then */
405 /* suming all returned sizemax */
407 TRACE("(%p,%p)\n",iface
,pcbSize
);
412 pcbSize
->s
.LowPart
=0;
413 pcbSize
->s
.HighPart
=0;
415 IMoniker_Enum(iface
,TRUE
,&enumMk
);
417 while(IEnumMoniker_Next(enumMk
,1,&pmk
,NULL
)==TRUE
){
419 IMoniker_GetSizeMax(pmk
,&ptmpSize
);
421 IMoniker_Release(pmk
);
423 pcbSize
->s
.LowPart
+=ptmpSize
.s
.LowPart
;
424 pcbSize
->s
.HighPart
+=ptmpSize
.s
.HighPart
;
427 IEnumMoniker_Release(enumMk
);
432 /******************************************************************************
433 * Composite-Moniker_Construct (local function)
434 *******************************************************************************/
435 HRESULT WINAPI
CompositeMonikerImpl_Construct(CompositeMonikerImpl
* This
,LPMONIKER pmkFirst
, LPMONIKER pmkRest
)
438 IEnumMoniker
*enumMoniker
;
442 TRACE("(%p,%p,%p)\n",This
,pmkFirst
,pmkRest
);
444 /* Initialize the virtual fgunction table. */
445 This
->lpvtbl1
= &VT_CompositeMonikerImpl
;
446 This
->lpvtbl2
= &VT_ROTDataImpl
;
449 This
->tabSize
=BLOCK_TAB_SIZE
;
450 This
->tabLastIndex
=0;
452 This
->tabMoniker
=HeapAlloc(GetProcessHeap(),0,This
->tabSize
*sizeof(IMoniker
));
453 if (This
->tabMoniker
==NULL
)
454 return E_OUTOFMEMORY
;
456 IMoniker_IsSystemMoniker(pmkFirst
,&mkSys
);
458 /* put the first moniker contents in the begining of the table */
459 if (mkSys
!=MKSYS_GENERICCOMPOSITE
){
461 This
->tabMoniker
[(This
->tabLastIndex
)++]=pmkFirst
;
462 IMoniker_AddRef(pmkFirst
);
466 IMoniker_Enum(pmkFirst
,TRUE
,&enumMoniker
);
468 while(IEnumMoniker_Next(enumMoniker
,1,&This
->tabMoniker
[This
->tabLastIndex
],NULL
)==S_OK
){
471 if (++This
->tabLastIndex
==This
->tabSize
){
473 This
->tabSize
+=BLOCK_TAB_SIZE
;
474 This
->tabMoniker
=HeapReAlloc(GetProcessHeap(),0,This
->tabMoniker
,This
->tabSize
*sizeof(IMoniker
));
476 if (This
->tabMoniker
==NULL
)
477 return E_OUTOFMEMORY
;
481 IEnumMoniker_Release(enumMoniker
);
484 /* put the rest moniker contents after the first one and make simplification if needed */
486 IMoniker_IsSystemMoniker(pmkRest
,&mkSys
);
488 if (mkSys
!=MKSYS_GENERICCOMPOSITE
){
490 /* add a simple moniker to the moniker table */
492 res
=IMoniker_ComposeWith(This
->tabMoniker
[This
->tabLastIndex
-1],pmkRest
,TRUE
,&tempMk
);
494 if (res
==MK_E_NEEDGENERIC
){
496 /* there's no simplification in this case */
497 This
->tabMoniker
[This
->tabLastIndex
]=pmkRest
;
499 This
->tabLastIndex
++;
501 IMoniker_AddRef(pmkRest
);
503 else if (tempMk
==NULL
){
505 /* we have an antimoniker after a simple moniker so we can make a simplification in this case */
506 IMoniker_Release(This
->tabMoniker
[This
->tabLastIndex
-1]);
508 This
->tabLastIndex
--;
510 else if (SUCCEEDED(res
)){
512 /* the non-generic composition was successful so we can make a simplification in this case */
513 IMoniker_Release(This
->tabMoniker
[This
->tabLastIndex
-1]);
515 This
->tabMoniker
[This
->tabLastIndex
-1]=tempMk
;
519 /* resize tabMoniker if needed */
520 if (This
->tabLastIndex
==This
->tabSize
){
522 This
->tabSize
+=BLOCK_TAB_SIZE
;
524 This
->tabMoniker
=HeapReAlloc(GetProcessHeap(),0,This
->tabMoniker
,This
->tabSize
*sizeof(IMoniker
));
526 if (This
->tabMoniker
==NULL
)
527 return E_OUTOFMEMORY
;
532 /* add a composite moniker to the moniker table (do the same thing for each moniker within the */
533 /* composite moniker as a simple moniker (see above how to add a simple moniker case) ) */
534 IMoniker_Enum(pmkRest
,TRUE
,&enumMoniker
);
536 while(IEnumMoniker_Next(enumMoniker
,1,&This
->tabMoniker
[This
->tabLastIndex
],NULL
)==S_OK
){
538 res
=IMoniker_ComposeWith(This
->tabMoniker
[This
->tabLastIndex
-1],This
->tabMoniker
[This
->tabLastIndex
],TRUE
,&tempMk
);
540 if (res
==MK_E_NEEDGENERIC
){
542 This
->tabLastIndex
++;
544 else if (tempMk
==NULL
){
546 IMoniker_Release(This
->tabMoniker
[This
->tabLastIndex
-1]);
547 IMoniker_Release(This
->tabMoniker
[This
->tabLastIndex
]);
548 This
->tabLastIndex
--;
552 IMoniker_Release(This
->tabMoniker
[This
->tabLastIndex
-1]);
554 This
->tabMoniker
[This
->tabLastIndex
-1]=tempMk
;
557 if (This
->tabLastIndex
==This
->tabSize
){
559 This
->tabSize
+=BLOCK_TAB_SIZE
;
561 This
->tabMoniker
=HeapReAlloc(GetProcessHeap(),0,This
->tabMoniker
,This
->tabSize
*sizeof(IMoniker
));
563 if (This
->tabMoniker
==NULL
)
564 return E_OUTOFMEMORY
;
568 IEnumMoniker_Release(enumMoniker
);
574 /******************************************************************************
575 * CompositeMoniker_Destroy (local function)
576 *******************************************************************************/
577 HRESULT WINAPI
CompositeMonikerImpl_Destroy(CompositeMonikerImpl
* This
)
579 TRACE("(%p)\n",This
);
581 HeapFree(GetProcessHeap(),0,This
->tabMoniker
);
583 HeapFree(GetProcessHeap(),0,This
);
588 /******************************************************************************
589 * CompositeMoniker_BindToObject
590 ******************************************************************************/
591 HRESULT WINAPI
CompositeMonikerImpl_BindToObject(IMoniker
* iface
,
598 IRunningObjectTable
*prot
;
599 IMoniker
*tempMk
,*antiMk
,*mostRigthMk
;
600 IEnumMoniker
*enumMoniker
;
602 TRACE("(%p,%p,%p,%p,%p)\n",iface
,pbc
,pmkToLeft
,riid
,ppvResult
);
608 /* If pmkToLeft is NULL, this method looks for the moniker in the ROT, and if found, queries the retrieved */
609 /* object for the requested interface pointer. */
612 res
=IBindCtx_GetRunningObjectTable(pbc
,&prot
);
616 /* if the requested class was loaded befor ! we dont need to reload it */
617 res
= IRunningObjectTable_GetObject(prot
,iface
,(IUnknown
**)ppvResult
);
624 /* If pmkToLeft is not NULL, the method recursively calls IMoniker::BindToObject on the rightmost */
625 /* component of the composite, passing the rest of the composite as the pmkToLeft parameter for that call */
627 IMoniker_Enum(iface
,FALSE
,&enumMoniker
);
628 IEnumMoniker_Next(enumMoniker
,1,&mostRigthMk
,NULL
);
629 IEnumMoniker_Release(enumMoniker
);
631 res
=CreateAntiMoniker(&antiMk
);
632 res
=IMoniker_ComposeWith(iface
,antiMk
,0,&tempMk
);
633 IMoniker_Release(antiMk
);
635 res
=CompositeMonikerImpl_BindToObject(mostRigthMk
,pbc
,tempMk
,riid
,ppvResult
);
637 IMoniker_Release(tempMk
);
638 IMoniker_Release(mostRigthMk
);
644 /******************************************************************************
645 * CompositeMoniker_BindToStorage
646 ******************************************************************************/
647 HRESULT WINAPI
CompositeMonikerImpl_BindToStorage(IMoniker
* iface
,
654 IMoniker
*tempMk
,*antiMk
,*mostRigthMk
;
655 IEnumMoniker
*enumMoniker
;
657 TRACE("(%p,%p,%p,%p,%p)\n",iface
,pbc
,pmkToLeft
,riid
,ppvResult
);
661 /* This method recursively calls BindToStorage on the rightmost component of the composite, */
662 /* passing the rest of the composite as the pmkToLeft parameter for that call. */
664 if (pmkToLeft
!=NULL
){
666 IMoniker_Enum(iface
,FALSE
,&enumMoniker
);
667 IEnumMoniker_Next(enumMoniker
,1,&mostRigthMk
,NULL
);
668 IEnumMoniker_Release(enumMoniker
);
670 res
=CreateAntiMoniker(&antiMk
);
671 res
=IMoniker_ComposeWith(iface
,antiMk
,0,&tempMk
);
672 IMoniker_Release(antiMk
);
674 res
=CompositeMonikerImpl_BindToStorage(mostRigthMk
,pbc
,tempMk
,riid
,ppvResult
);
676 IMoniker_Release(tempMk
);
678 IMoniker_Release(mostRigthMk
);
683 return IMoniker_BindToStorage(iface
,pbc
,NULL
,riid
,ppvResult
);
686 /******************************************************************************
687 * CompositeMoniker_Reduce
688 ******************************************************************************/
689 HRESULT WINAPI
CompositeMonikerImpl_Reduce(IMoniker
* iface
,
691 DWORD dwReduceHowFar
,
692 IMoniker
** ppmkToLeft
,
693 IMoniker
** ppmkReduced
)
696 IMoniker
*tempMk
,*antiMk
,*mostRigthMk
,*leftReducedComposedMk
,*mostRigthReducedMk
;
697 IEnumMoniker
*enumMoniker
;
699 TRACE("(%p,%p,%ld,%p,%p)\n",iface
,pbc
,dwReduceHowFar
,ppmkToLeft
,ppmkReduced
);
701 if (ppmkReduced
==NULL
)
704 /* This method recursively calls Reduce for each of its component monikers. */
706 if (ppmkToLeft
==NULL
){
708 IMoniker_Enum(iface
,FALSE
,&enumMoniker
);
709 IEnumMoniker_Next(enumMoniker
,1,&mostRigthMk
,NULL
);
710 IEnumMoniker_Release(enumMoniker
);
712 res
=CreateAntiMoniker(&antiMk
);
713 res
=IMoniker_ComposeWith(iface
,antiMk
,0,&tempMk
);
714 IMoniker_Release(antiMk
);
716 return CompositeMonikerImpl_Reduce(mostRigthMk
,pbc
,dwReduceHowFar
,&tempMk
, ppmkReduced
);
718 else if (*ppmkToLeft
==NULL
)
720 return IMoniker_Reduce(iface
,pbc
,dwReduceHowFar
,NULL
,ppmkReduced
);
724 /* separate the copmosite moniker in to left and wrigth moniker */
725 IMoniker_Enum(iface
,FALSE
,&enumMoniker
);
726 IEnumMoniker_Next(enumMoniker
,1,&mostRigthMk
,NULL
);
727 IEnumMoniker_Release(enumMoniker
);
729 res
=CreateAntiMoniker(&antiMk
);
730 res
=IMoniker_ComposeWith(iface
,antiMk
,0,&tempMk
);
731 IMoniker_Release(antiMk
);
733 /* If any of the components reduces itself, the method returns S_OK and passes back a composite */
734 /* of the reduced components */
735 if (IMoniker_Reduce(mostRigthMk
,pbc
,dwReduceHowFar
,NULL
,&mostRigthReducedMk
) &&
736 CompositeMonikerImpl_Reduce(mostRigthMk
,pbc
,dwReduceHowFar
,&tempMk
,&leftReducedComposedMk
)
739 return CreateGenericComposite(leftReducedComposedMk
,mostRigthReducedMk
,ppmkReduced
);
742 /* If no reduction occurred, the method passes back the same moniker and returns MK_S_REDUCED_TO_SELF.*/
744 IMoniker_AddRef(iface
);
748 return MK_S_REDUCED_TO_SELF
;
753 /******************************************************************************
754 * CompositeMoniker_ComposeWith
755 ******************************************************************************/
756 HRESULT WINAPI
CompositeMonikerImpl_ComposeWith(IMoniker
* iface
,
758 BOOL fOnlyIfNotGeneric
,
759 IMoniker
** ppmkComposite
)
761 TRACE("(%p,%p,%d,%p)\n",iface
,pmkRight
,fOnlyIfNotGeneric
,ppmkComposite
);
763 if ((ppmkComposite
==NULL
)||(pmkRight
==NULL
))
768 /* If fOnlyIfNotGeneric is TRUE, this method sets *pmkComposite to NULL and returns MK_E_NEEDGENERIC; */
769 /* otherwise, the method returns the result of combining the two monikers by calling the */
770 /* CreateGenericComposite function */
772 if (fOnlyIfNotGeneric
)
773 return MK_E_NEEDGENERIC
;
775 return CreateGenericComposite(iface
,pmkRight
,ppmkComposite
);
778 /******************************************************************************
779 * CompositeMoniker_Enum
780 ******************************************************************************/
781 HRESULT WINAPI
CompositeMonikerImpl_Enum(IMoniker
* iface
,BOOL fForward
, IEnumMoniker
** ppenumMoniker
)
783 ICOM_THIS(CompositeMonikerImpl
,iface
);
785 TRACE("(%p,%d,%p)\n",iface
,fForward
,ppenumMoniker
);
787 if (ppenumMoniker
== NULL
)
790 return EnumMonikerImpl_CreateEnumMoniker(This
->tabMoniker
,This
->tabLastIndex
,0,fForward
,ppenumMoniker
);
793 /******************************************************************************
794 * CompositeMoniker_IsEqual
795 ******************************************************************************/
796 HRESULT WINAPI
CompositeMonikerImpl_IsEqual(IMoniker
* iface
,IMoniker
* pmkOtherMoniker
)
798 IEnumMoniker
*enumMoniker1
,*enumMoniker2
;
799 IMoniker
*tempMk1
,*tempMk2
;
800 HRESULT res1
,res2
,res
;
802 TRACE("(%p,%p)\n",iface
,pmkOtherMoniker
);
804 if (pmkOtherMoniker
==NULL
)
807 /* This method returns S_OK if the components of both monikers are equal when compared in the */
808 /* left-to-right order.*/
809 IMoniker_Enum(pmkOtherMoniker
,TRUE
,&enumMoniker1
);
811 if (enumMoniker1
==NULL
)
814 IMoniker_Enum(iface
,TRUE
,&enumMoniker2
);
818 res1
=IEnumMoniker_Next(enumMoniker1
,1,&tempMk1
,NULL
);
819 res2
=IEnumMoniker_Next(enumMoniker2
,1,&tempMk2
,NULL
);
821 if((res1
==S_OK
)&&(res2
==S_OK
)){
823 if(IMoniker_IsEqual(tempMk1
,tempMk2
)==S_FALSE
){
830 else if ( (res1
==S_FALSE
) && (res2
==S_FALSE
) ){
840 IMoniker_Release(tempMk1
);
843 IMoniker_Release(tempMk2
);
846 IEnumMoniker_Release(enumMoniker1
);
847 IEnumMoniker_Release(enumMoniker2
);
851 /******************************************************************************
852 * CompositeMoniker_Hash
853 ******************************************************************************/
854 HRESULT WINAPI
CompositeMonikerImpl_Hash(IMoniker
* iface
,DWORD
* pdwHash
)
861 /******************************************************************************
862 * CompositeMoniker_IsRunning
863 ******************************************************************************/
864 HRESULT WINAPI
CompositeMonikerImpl_IsRunning(IMoniker
* iface
,
867 IMoniker
* pmkNewlyRunning
)
869 IRunningObjectTable
* rot
;
871 IMoniker
*tempMk
,*antiMk
,*mostRigthMk
;
872 IEnumMoniker
*enumMoniker
;
874 TRACE("(%p,%p,%p,%p)\n",iface
,pbc
,pmkToLeft
,pmkNewlyRunning
);
876 /* If pmkToLeft is non-NULL, this method composes pmkToLeft with this moniker and calls IsRunning on the result.*/
877 if (pmkToLeft
!=NULL
){
879 CreateGenericComposite(pmkToLeft
,iface
,&tempMk
);
881 res
= IMoniker_IsRunning(tempMk
,pbc
,NULL
,pmkNewlyRunning
);
883 IMoniker_Release(tempMk
);
888 /* If pmkToLeft is NULL, this method returns S_OK if pmkNewlyRunning is non-NULL and is equal */
889 /* to this moniker */
891 if (pmkNewlyRunning
!=NULL
)
893 if (IMoniker_IsEqual(iface
,pmkNewlyRunning
)==S_OK
)
904 /* If pmkToLeft and pmkNewlyRunning are both NULL, this method checks the ROT to see whether */
905 /* the moniker is running. If so, the method returns S_OK; otherwise, it recursively calls */
906 /* IMoniker::IsRunning on the rightmost component of the composite, passing the remainder of */
907 /* the composite as the pmkToLeft parameter for that call. */
909 res
=IBindCtx_GetRunningObjectTable(pbc
,&rot
);
914 res
= IRunningObjectTable_IsRunning(rot
,iface
);
915 IRunningObjectTable_Release(rot
);
922 IMoniker_Enum(iface
,FALSE
,&enumMoniker
);
923 IEnumMoniker_Next(enumMoniker
,1,&mostRigthMk
,NULL
);
924 IEnumMoniker_Release(enumMoniker
);
926 res
=CreateAntiMoniker(&antiMk
);
927 res
=IMoniker_ComposeWith(iface
,antiMk
,0,&tempMk
);
928 IMoniker_Release(antiMk
);
930 res
=IMoniker_IsRunning(mostRigthMk
,pbc
,tempMk
,pmkNewlyRunning
);
932 IMoniker_Release(tempMk
);
933 IMoniker_Release(mostRigthMk
);
940 /******************************************************************************
941 * CompositeMoniker_GetTimeOfLastChange
942 ******************************************************************************/
943 HRESULT WINAPI
CompositeMonikerImpl_GetTimeOfLastChange(IMoniker
* iface
,
946 FILETIME
* pCompositeTime
)
948 IRunningObjectTable
* rot
;
950 IMoniker
*tempMk
,*antiMk
,*mostRigthMk
;
951 IEnumMoniker
*enumMoniker
;
953 TRACE("(%p,%p,%p,%p)\n",iface
,pbc
,pmkToLeft
,pCompositeTime
);
955 if (pCompositeTime
==NULL
)
958 /* This method creates a composite of pmkToLeft (if non-NULL) and this moniker and uses the ROT to */
959 /* retrieve the time of last change. If the object is not in the ROT, the method recursively calls */
960 /* IMoniker::GetTimeOfLastChange on the rightmost component of the composite, passing the remainder */
961 /* of the composite as the pmkToLeft parameter for that call. */
962 if (pmkToLeft
!=NULL
){
964 res
=CreateGenericComposite(pmkToLeft
,iface
,&tempMk
);
966 res
=IBindCtx_GetRunningObjectTable(pbc
,&rot
);
971 if (IRunningObjectTable_GetTimeOfLastChange(rot
,tempMk
,pCompositeTime
)==S_OK
)
975 IMoniker_Enum(iface
,FALSE
,&enumMoniker
);
976 IEnumMoniker_Next(enumMoniker
,1,&mostRigthMk
,NULL
);
977 IEnumMoniker_Release(enumMoniker
);
979 res
=CreateAntiMoniker(&antiMk
);
980 res
=IMoniker_ComposeWith(iface
,antiMk
,0,&tempMk
);
981 IMoniker_Release(antiMk
);
983 res
=CompositeMonikerImpl_GetTimeOfLastChange(mostRigthMk
,pbc
,tempMk
,pCompositeTime
);
985 IMoniker_Release(tempMk
);
986 IMoniker_Release(mostRigthMk
);
991 return IMoniker_GetTimeOfLastChange(iface
,pbc
,NULL
,pCompositeTime
);
994 /******************************************************************************
995 * CompositeMoniker_Inverse
996 ******************************************************************************/
997 HRESULT WINAPI
CompositeMonikerImpl_Inverse(IMoniker
* iface
,IMoniker
** ppmk
)
1000 IMoniker
*tempMk
,*antiMk
,*mostRigthMk
,*tempInvMk
,*mostRigthInvMk
;
1001 IEnumMoniker
*enumMoniker
;
1003 TRACE("(%p,%p)\n",iface
,ppmk
);
1008 /* This method returns a composite moniker that consists of the inverses of each of the components */
1009 /* of the original composite, stored in reverse order */
1011 res
=CreateAntiMoniker(&antiMk
);
1012 res
=IMoniker_ComposeWith(iface
,antiMk
,0,&tempMk
);
1013 IMoniker_Release(antiMk
);
1017 return IMoniker_Inverse(iface
,ppmk
);
1021 IMoniker_Enum(iface
,FALSE
,&enumMoniker
);
1022 IEnumMoniker_Next(enumMoniker
,1,&mostRigthMk
,NULL
);
1023 IEnumMoniker_Release(enumMoniker
);
1025 IMoniker_Inverse(mostRigthMk
,&mostRigthInvMk
);
1026 CompositeMonikerImpl_Inverse(tempMk
,&tempInvMk
);
1028 res
=CreateGenericComposite(mostRigthInvMk
,tempInvMk
,ppmk
);
1030 IMoniker_Release(tempMk
);
1031 IMoniker_Release(mostRigthMk
);
1032 IMoniker_Release(tempInvMk
);
1033 IMoniker_Release(mostRigthInvMk
);
1039 /******************************************************************************
1040 * CompositeMoniker_CommonPrefixWith
1041 ******************************************************************************/
1042 HRESULT WINAPI
CompositeMonikerImpl_CommonPrefixWith(IMoniker
* iface
,IMoniker
* pmkOther
,IMoniker
** ppmkPrefix
)
1046 IMoniker
*tempMk1
,*tempMk2
,*mostLeftMk1
,*mostLeftMk2
;
1047 IEnumMoniker
*enumMoniker1
,*enumMoniker2
;
1048 ULONG i
,nbCommonMk
=0;
1050 /* If the other moniker is a composite, this method compares the components of each composite from left */
1051 /* to right. The returned common prefix moniker might also be a composite moniker, depending on how many */
1052 /* of the leftmost components were common to both monikers. */
1054 if (ppmkPrefix
==NULL
)
1060 return MK_E_NOPREFIX
;
1062 IMoniker_IsSystemMoniker(pmkOther
,&mkSys
);
1064 if((mkSys
==MKSYS_GENERICCOMPOSITE
)){
1066 IMoniker_Enum(iface
,TRUE
,&enumMoniker1
);
1067 IMoniker_Enum(pmkOther
,TRUE
,&enumMoniker2
);
1071 res1
=IEnumMoniker_Next(enumMoniker1
,1,&mostLeftMk1
,NULL
);
1072 res2
=IEnumMoniker_Next(enumMoniker2
,1,&mostLeftMk2
,NULL
);
1074 if ((res1
==S_FALSE
) && (res2
==S_FALSE
)){
1076 /* If the monikers are equal, the method returns MK_S_US and sets ppmkPrefix to this moniker.*/
1078 IMoniker_AddRef(iface
);
1081 else if ((res1
==S_OK
) && (res2
==S_OK
)){
1083 if (IMoniker_IsEqual(mostLeftMk1
,mostLeftMk2
)==S_OK
)
1091 else if (res1
==S_OK
){
1093 /* If the other moniker is a prefix of this moniker, the method returns MK_S_HIM and sets */
1094 /* ppmkPrefix to the other moniker. */
1095 *ppmkPrefix
=pmkOther
;
1099 /* If this moniker is a prefix of the other, this method returns MK_S_ME and sets ppmkPrefix */
1100 /* to this moniker. */
1106 IEnumMoniker_Release(enumMoniker1
);
1107 IEnumMoniker_Release(enumMoniker2
);
1109 /* If there is no common prefix, this method returns MK_E_NOPREFIX and sets ppmkPrefix to NULL. */
1111 return MK_E_NOPREFIX
;
1113 IEnumMoniker_Reset(enumMoniker1
);
1115 IEnumMoniker_Next(enumMoniker1
,1,&tempMk1
,NULL
);
1117 /* if we have more than one commun moniker the result will be a composite moniker */
1120 /* initialize the common prefix moniker with the composite of two first moniker (from the left)*/
1121 IEnumMoniker_Next(enumMoniker1
,1,&tempMk2
,NULL
);
1122 CreateGenericComposite(tempMk1
,tempMk2
,ppmkPrefix
);
1123 IMoniker_Release(tempMk1
);
1124 IMoniker_Release(tempMk2
);
1126 /* compose all common monikers in a composite moniker */
1127 for(i
=0;i
<nbCommonMk
;i
++){
1129 IEnumMoniker_Next(enumMoniker1
,1,&tempMk1
,NULL
);
1131 CreateGenericComposite(*ppmkPrefix
,tempMk1
,&tempMk2
);
1133 IMoniker_Release(*ppmkPrefix
);
1135 IMoniker_Release(tempMk1
);
1137 *ppmkPrefix
=tempMk2
;
1142 /* if we have only one commun moniker the result will be a simple moniker which is the most-left one*/
1143 *ppmkPrefix
=tempMk1
;
1149 /* If the other moniker is not a composite, the method simply compares it to the leftmost component
1152 IMoniker_Enum(iface
,TRUE
,&enumMoniker1
);
1154 IEnumMoniker_Next(enumMoniker1
,1,&mostLeftMk1
,NULL
);
1156 if (IMoniker_IsEqual(pmkOther
,mostLeftMk1
)==S_OK
){
1158 *ppmkPrefix
=pmkOther
;
1163 return MK_E_NOPREFIX
;
1166 /***************************************************************************************************
1167 * GetAfterCommonPrefix (local function)
1168 * This function returns a moniker that consist of the remainder when the common prefix is removed
1169 ***************************************************************************************************/
1170 VOID WINAPI
GetAfterCommonPrefix(IMoniker
* pGenMk
,IMoniker
* commonMk
,IMoniker
** restMk
)
1172 IMoniker
*tempMk
,*tempMk1
,*tempMk2
;
1173 IEnumMoniker
*enumMoniker1
,*enumMoniker2
,*enumMoniker3
;
1180 /* to create an enumerator for pGenMk with current position pointed on the first element after common */
1181 /* prefix: enum the two monikers (left-wrigth) then compare these enumerations (left-wrigth) and stop */
1182 /* on the first difference. */
1183 IMoniker_Enum(pGenMk
,TRUE
,&enumMoniker1
);
1185 IMoniker_IsSystemMoniker(commonMk
,&mkSys
);
1187 if (mkSys
==MKSYS_GENERICCOMPOSITE
){
1189 IMoniker_Enum(commonMk
,TRUE
,&enumMoniker2
);
1192 res1
=IEnumMoniker_Next(enumMoniker1
,1,&tempMk1
,NULL
);
1193 res2
=IEnumMoniker_Next(enumMoniker2
,1,&tempMk2
,NULL
);
1195 if ((res1
==S_FALSE
)||(res2
==S_FALSE
)){
1201 IMoniker_Release(tempMk1
);
1202 IMoniker_Release(tempMk1
);
1206 IMoniker_Release(tempMk1
);
1207 IMoniker_Release(tempMk1
);
1211 IEnumMoniker_Next(enumMoniker1
,1,&tempMk1
,NULL
);
1212 IMoniker_Release(tempMk1
);
1215 /* count the number of elements in the enumerator after the common prefix */
1216 IEnumMoniker_Clone(enumMoniker1
,&enumMoniker3
);
1218 for(;IEnumMoniker_Next(enumMoniker3
,1,&tempMk
,NULL
)==S_OK
;nbRestMk
++)
1220 IMoniker_Release(tempMk
);;
1225 /* create a generic composite moniker with monikers located after the common prefix */
1226 IEnumMoniker_Next(enumMoniker1
,1,&tempMk1
,NULL
);
1235 IEnumMoniker_Next(enumMoniker1
,1,&tempMk2
,NULL
);
1237 CreateGenericComposite(tempMk1
,tempMk2
,restMk
);
1239 IMoniker_Release(tempMk1
);
1241 IMoniker_Release(tempMk2
);
1243 while(IEnumMoniker_Next(enumMoniker1
,1,&tempMk1
,NULL
)==S_OK
){
1245 CreateGenericComposite(*restMk
,tempMk1
,&tempMk2
);
1247 IMoniker_Release(tempMk1
);
1249 IMoniker_Release(*restMk
);
1255 /******************************************************************************
1256 * CompositeMoniker_RelativePathTo
1257 ******************************************************************************/
1258 HRESULT WINAPI
CompositeMonikerImpl_RelativePathTo(IMoniker
* iface
,IMoniker
* pmkOther
, IMoniker
** ppmkRelPath
)
1261 IMoniker
*restOtherMk
=0,*restThisMk
=0,*invRestThisMk
=0,*commonMk
=0;
1263 TRACE("(%p,%p,%p)\n",iface
,pmkOther
,ppmkRelPath
);
1265 if (ppmkRelPath
==NULL
)
1270 /* This method finds the common prefix of the two monikers and creates two monikers that consist */
1271 /* of the remainder when the common prefix is removed. Then it creates the inverse for the remainder */
1272 /* of this moniker and composes the remainder of the other moniker on the right of it. */
1274 /* finds the common prefix of the two monikers */
1275 res
=IMoniker_CommonPrefixWith(iface
,pmkOther
,&commonMk
);
1277 /* if there's no common prefix or the two moniker are equal the relative is the other moniker */
1278 if ((res
== MK_E_NOPREFIX
)||(res
==MK_S_US
)){
1280 *ppmkRelPath
=pmkOther
;
1281 IMoniker_AddRef(pmkOther
);
1285 GetAfterCommonPrefix(iface
,commonMk
,&restThisMk
);
1286 GetAfterCommonPrefix(pmkOther
,commonMk
,&restOtherMk
);
1288 /* if other is a prefix of this moniker the relative path is the inverse of the remainder path of this */
1289 /* moniker when the common prefix is removed */
1292 IMoniker_Inverse(restThisMk
,ppmkRelPath
);
1293 IMoniker_Release(restThisMk
);
1295 /* if this moniker is a prefix of other moniker the relative path is the remainder path of other moniker */
1296 /* when the common prefix is removed */
1297 else if (res
==MK_S_ME
){
1299 *ppmkRelPath
=restOtherMk
;
1300 IMoniker_AddRef(restOtherMk
);
1302 /* the relative path is the inverse for the remainder of this moniker and the remainder of the other */
1303 /* moniker on the right of it. */
1304 else if (res
==S_OK
){
1306 IMoniker_Inverse(restThisMk
,&invRestThisMk
);
1307 IMoniker_Release(restThisMk
);
1308 CreateGenericComposite(invRestThisMk
,restOtherMk
,ppmkRelPath
);
1309 IMoniker_Release(invRestThisMk
);
1310 IMoniker_Release(restOtherMk
);
1315 /******************************************************************************
1316 * CompositeMoniker_GetDisplayName
1317 ******************************************************************************/
1318 HRESULT WINAPI
CompositeMonikerImpl_GetDisplayName(IMoniker
* iface
,
1320 IMoniker
* pmkToLeft
,
1321 LPOLESTR
*ppszDisplayName
)
1324 IEnumMoniker
*enumMoniker
;
1328 TRACE("(%p,%p,%p,%p)\n",iface
,pbc
,pmkToLeft
,ppszDisplayName
);
1330 if (ppszDisplayName
==NULL
)
1333 *ppszDisplayName
=CoTaskMemAlloc(sizeof(WCHAR
));
1335 if (*ppszDisplayName
==NULL
)
1336 return E_OUTOFMEMORY
;
1338 /* This method returns the concatenation of the display names returned by each component moniker of */
1341 **ppszDisplayName
=0;
1343 IMoniker_Enum(iface
,TRUE
,&enumMoniker
);
1345 while(IEnumMoniker_Next(enumMoniker
,1,&tempMk
,NULL
)==S_OK
){
1347 IMoniker_GetDisplayName(tempMk
,pbc
,NULL
,&tempStr
);
1349 lengthStr
+=lstrlenW(tempStr
);
1351 *ppszDisplayName
=CoTaskMemRealloc(*ppszDisplayName
,lengthStr
* sizeof(WCHAR
));
1353 if (*ppszDisplayName
==NULL
)
1354 return E_OUTOFMEMORY
;
1356 lstrcatW(*ppszDisplayName
,tempStr
);
1358 CoTaskMemFree(tempStr
);
1359 IMoniker_Release(tempMk
);
1362 IEnumMoniker_Release(enumMoniker
);
1367 /******************************************************************************
1368 * CompositeMoniker_ParseDisplayName
1369 ******************************************************************************/
1370 HRESULT WINAPI
CompositeMonikerImpl_ParseDisplayName(IMoniker
* iface
,
1372 IMoniker
* pmkToLeft
,
1373 LPOLESTR pszDisplayName
,
1377 IEnumMoniker
*enumMoniker
;
1378 IMoniker
*tempMk
,*mostRigthMk
,*antiMk
;
1379 /* This method recursively calls IMoniker::ParseDisplayName on the rightmost component of the composite,*/
1380 /* passing everything else as the pmkToLeft parameter for that call. */
1382 /* get the most rigth moniker */
1383 IMoniker_Enum(iface
,FALSE
,&enumMoniker
);
1384 IEnumMoniker_Next(enumMoniker
,1,&mostRigthMk
,NULL
);
1385 IEnumMoniker_Release(enumMoniker
);
1387 /* get the left moniker */
1388 CreateAntiMoniker(&antiMk
);
1389 IMoniker_ComposeWith(iface
,antiMk
,0,&tempMk
);
1390 IMoniker_Release(antiMk
);
1392 return IMoniker_ParseDisplayName(mostRigthMk
,pbc
,tempMk
,pszDisplayName
,pchEaten
,ppmkOut
);
1395 /******************************************************************************
1396 * CompositeMoniker_IsSystemMonker
1397 ******************************************************************************/
1398 HRESULT WINAPI
CompositeMonikerImpl_IsSystemMoniker(IMoniker
* iface
,DWORD
* pwdMksys
)
1400 TRACE("(%p,%p)\n",iface
,pwdMksys
);
1405 (*pwdMksys
)=MKSYS_GENERICCOMPOSITE
;
1410 /*******************************************************************************
1411 * CompositeMonikerIROTData_QueryInterface
1412 *******************************************************************************/
1413 HRESULT WINAPI
CompositeMonikerROTDataImpl_QueryInterface(IROTData
*iface
,REFIID riid
,VOID
** ppvObject
)
1416 ICOM_THIS_From_IROTData(IMoniker
, iface
);
1418 TRACE("(%p,%p,%p)\n",iface
,riid
,ppvObject
);
1420 return CompositeMonikerImpl_QueryInterface(This
, riid
, ppvObject
);
1423 /***********************************************************************
1424 * CompositeMonikerIROTData_AddRef
1426 ULONG WINAPI
CompositeMonikerROTDataImpl_AddRef(IROTData
*iface
)
1428 ICOM_THIS_From_IROTData(IMoniker
, iface
);
1430 TRACE("(%p)\n",iface
);
1432 return CompositeMonikerImpl_AddRef(This
);
1435 /***********************************************************************
1436 * CompositeMonikerIROTData_Release
1438 ULONG WINAPI
CompositeMonikerROTDataImpl_Release(IROTData
* iface
)
1440 ICOM_THIS_From_IROTData(IMoniker
, iface
);
1442 TRACE("(%p)\n",iface
);
1444 return CompositeMonikerImpl_Release(This
);
1447 /******************************************************************************
1448 * CompositeMonikerIROTData_GetComparaisonData
1449 ******************************************************************************/
1450 HRESULT WINAPI
CompositeMonikerROTDataImpl_GetComparaisonData(IROTData
* iface
,
1455 FIXME("(),stub!\n");
1459 /******************************************************************************
1460 * EnumMonikerImpl_QueryInterface
1461 ******************************************************************************/
1462 HRESULT WINAPI
EnumMonikerImpl_QueryInterface(IEnumMoniker
* iface
,REFIID riid
,void** ppvObject
)
1464 ICOM_THIS(EnumMonikerImpl
,iface
);
1466 TRACE("(%p,%p,%p)\n",This
,riid
,ppvObject
);
1468 /* Perform a sanity check on the parameters.*/
1469 if ( (This
==0) || (ppvObject
==0) )
1470 return E_INVALIDARG
;
1472 /* Initialize the return parameter */
1475 /* Compare the riid with the interface IDs implemented by this object.*/
1476 if (IsEqualIID(&IID_IUnknown
, riid
) || IsEqualIID(&IID_IEnumMoniker
, riid
))
1479 /* Check that we obtained an interface.*/
1480 if ((*ppvObject
)==0)
1481 return E_NOINTERFACE
;
1483 /* Query Interface always increases the reference count by one when it is successful */
1484 EnumMonikerImpl_AddRef(iface
);
1489 /******************************************************************************
1490 * EnumMonikerImpl_AddRef
1491 ******************************************************************************/
1492 ULONG WINAPI
EnumMonikerImpl_AddRef(IEnumMoniker
* iface
)
1494 ICOM_THIS(EnumMonikerImpl
,iface
);
1496 TRACE("(%p)\n",This
);
1498 return ++(This
->ref
);
1502 /******************************************************************************
1503 * EnumMonikerImpl_Release
1504 ******************************************************************************/
1505 ULONG WINAPI
EnumMonikerImpl_Release(IEnumMoniker
* iface
)
1507 ICOM_THIS(EnumMonikerImpl
,iface
);
1510 TRACE("(%p)\n",This
);
1514 /* destroy the object if there's no more reference on it */
1517 for(i
=0;i
<This
->tabSize
;i
++)
1518 IMoniker_Release(This
->tabMoniker
[i
]);
1520 HeapFree(GetProcessHeap(),0,This
->tabMoniker
);
1521 HeapFree(GetProcessHeap(),0,This
);
1528 /******************************************************************************
1529 * EnumMonikerImpl_Next
1530 ******************************************************************************/
1531 HRESULT WINAPI
EnumMonikerImpl_Next(IEnumMoniker
* iface
,ULONG celt
, IMoniker
** rgelt
, ULONG
* pceltFethed
){
1533 ICOM_THIS(EnumMonikerImpl
,iface
);
1536 /* retrieve the requested number of moniker from the current position */
1537 for(i
=0;((This
->currentPos
< This
->tabSize
) && (i
< celt
));i
++)
1539 rgelt
[i
]=This
->tabMoniker
[This
->currentPos
++];
1541 if (pceltFethed
!=NULL
)
1550 /******************************************************************************
1551 * EnumMonikerImpl_Skip
1552 ******************************************************************************/
1553 HRESULT WINAPI
EnumMonikerImpl_Skip(IEnumMoniker
* iface
,ULONG celt
){
1555 ICOM_THIS(EnumMonikerImpl
,iface
);
1557 if ((This
->currentPos
+celt
) >= This
->tabSize
)
1560 This
->currentPos
+=celt
;
1565 /******************************************************************************
1566 * EnumMonikerImpl_Reset
1567 ******************************************************************************/
1568 HRESULT WINAPI
EnumMonikerImpl_Reset(IEnumMoniker
* iface
){
1570 ICOM_THIS(EnumMonikerImpl
,iface
);
1577 /******************************************************************************
1578 * EnumMonikerImpl_Clone
1579 ******************************************************************************/
1580 HRESULT WINAPI
EnumMonikerImpl_Clone(IEnumMoniker
* iface
,IEnumMoniker
** ppenum
){
1582 ICOM_THIS(EnumMonikerImpl
,iface
);
1584 return EnumMonikerImpl_CreateEnumMoniker(This
->tabMoniker
,This
->tabSize
,This
->currentPos
,TRUE
,ppenum
);
1587 /******************************************************************************
1588 * EnumMonikerImpl_CreateEnumMoniker
1589 ******************************************************************************/
1590 HRESULT WINAPI
EnumMonikerImpl_CreateEnumMoniker(IMoniker
** tabMoniker
,
1594 IEnumMoniker
** ppmk
)
1596 EnumMonikerImpl
* newEnumMoniker
;
1600 newEnumMoniker
= HeapAlloc(GetProcessHeap(), 0, sizeof(EnumMonikerImpl
));
1602 if (newEnumMoniker
== 0)
1603 return STG_E_INSUFFICIENTMEMORY
;
1605 if (currentPos
> tabSize
)
1606 return E_INVALIDARG
;
1608 /* Initialize the virtual function table. */
1609 ICOM_VTBL(newEnumMoniker
) = &VT_EnumMonikerImpl
;
1610 newEnumMoniker
->ref
= 0;
1612 newEnumMoniker
->tabSize
=tabSize
;
1613 newEnumMoniker
->currentPos
=currentPos
;
1615 newEnumMoniker
->tabMoniker
=HeapAlloc(GetProcessHeap(),0,tabSize
*sizeof(IMoniker
));
1617 if (newEnumMoniker
->tabMoniker
==NULL
)
1618 return E_OUTOFMEMORY
;
1621 for (i
=0;i
<tabSize
;i
++){
1623 newEnumMoniker
->tabMoniker
[i
]=tabMoniker
[i
];
1624 IMoniker_AddRef(tabMoniker
[i
]);
1627 for (i
=tabSize
-1;i
>=0;i
--){
1629 newEnumMoniker
->tabMoniker
[tabSize
-i
-1]=tabMoniker
[i
];
1630 IMoniker_AddRef(tabMoniker
[i
]);
1633 *ppmk
=(IEnumMoniker
*)newEnumMoniker
;
1638 /******************************************************************************
1639 * CreateGenericComposite [OLE.55]
1640 ******************************************************************************/
1641 HRESULT WINAPI
CreateGenericComposite(LPMONIKER pmkFirst
, LPMONIKER pmkRest
, LPMONIKER
* ppmkComposite
)
1643 CompositeMonikerImpl
* newCompositeMoniker
= 0;
1646 TRACE("(%p,%p,%p)\n",pmkFirst
,pmkRest
,ppmkComposite
);
1648 if (ppmkComposite
==NULL
)
1653 if (pmkFirst
==NULL
&& pmkRest
!=NULL
){
1655 *ppmkComposite
=pmkRest
;
1658 else if (pmkFirst
!=NULL
&& pmkRest
==NULL
){
1659 *ppmkComposite
=pmkFirst
;
1662 else if (pmkFirst
==NULL
&& pmkRest
==NULL
)
1665 newCompositeMoniker
= HeapAlloc(GetProcessHeap(), 0,sizeof(CompositeMonikerImpl
));
1667 if (newCompositeMoniker
== 0)
1668 return STG_E_INSUFFICIENTMEMORY
;
1670 hr
= CompositeMonikerImpl_Construct(newCompositeMoniker
,pmkFirst
,pmkRest
);
1674 HeapFree(GetProcessHeap(),0,newCompositeMoniker
);
1677 if (newCompositeMoniker
->tabLastIndex
==1)
1679 hr
= IMoniker_QueryInterface(newCompositeMoniker
->tabMoniker
[0],&IID_IMoniker
,(void**)ppmkComposite
);
1682 hr
= CompositeMonikerImpl_QueryInterface((IMoniker
*)newCompositeMoniker
,&IID_IMoniker
,(void**)ppmkComposite
);
1687 /******************************************************************************
1688 * MonikerCommonPrefixWith [OLE.55]
1689 ******************************************************************************/
1690 HRESULT WINAPI
MonikerCommonPrefixWith(IMoniker
* pmkThis
,IMoniker
* pmkOther
,IMoniker
** ppmkCommon
)
1692 FIXME("(),stub!\n");