source: trunk/src/ole32/old/compositemoniker.cpp@ 5601

Last change on this file since 5601 was 5601, checked in by sandervl, 24 years ago

created

File size: 58.1 KB
Line 
1/* $Id: compositemoniker.cpp,v 1.1 2001-04-26 19:26:09 sandervl Exp $ */
2/*
3 * CompositeMonikers functions.
4 *
5 * 20/9/99
6 *
7 * Copyright 1999 David J. Raison
8 *
9 * Direct port of Wine Implementation
10 * Copyright 1999 Noomen Hamza
11 */
12
13#include "ole32.h"
14#include "debugtools.h"
15
16DEFAULT_DEBUG_CHANNEL(moniker)
17
18#define BLOCK_TAB_SIZE 5 /* represent the first size table and it's increment block size */
19
20/* CompositeMoniker data structure */
21typedef struct CompositeMonikerImpl{
22
23 ICOM_VTABLE(IMoniker)* lpvtbl1; /* VTable relative to the IMoniker interface.*/
24
25 /* The ROT (RunningObjectTable implementation) uses the IROTData interface to test whether
26 * two monikers are equal. That's whay IROTData interface is implemented by monikers.
27 */
28 ICOM_VTABLE(IROTData)* lpvtbl2; /* VTable relative to the IROTData interface.*/
29
30 ULONG ref; /* reference counter for this object */
31
32 IMoniker** tabMoniker; /* dynamaic table containing all components (monikers) of this composite moniker */
33
34 ULONG tabSize; /* size of tabMoniker */
35
36 ULONG tabLastIndex; /* first free index in tabMoniker */
37
38} CompositeMonikerImpl;
39
40
41/* EnumMoniker data structure */
42typedef struct EnumMonikerImpl{
43
44 ICOM_VFIELD(IEnumMoniker); /* VTable relative to the IEnumMoniker interface.*/
45
46 ULONG ref; /* reference counter for this object */
47
48 IMoniker** tabMoniker; /* dynamic table containing the enumerated monikers */
49
50 ULONG tabSize; /* size of tabMoniker */
51
52 ULONG currentPos; /* index pointer on the current moniker */
53
54} EnumMonikerImpl;
55
56
57/********************************************************************************/
58/* CompositeMoniker prototype functions : */
59
60/* IUnknown prototype functions */
61static HRESULT WINAPI CompositeMonikerImpl_QueryInterface(IMoniker* iface,REFIID riid,void** ppvObject);
62static ULONG WINAPI CompositeMonikerImpl_AddRef(IMoniker* iface);
63static ULONG WINAPI CompositeMonikerImpl_Release(IMoniker* iface);
64
65/* IPersist prototype functions */
66static HRESULT WINAPI CompositeMonikerImpl_GetClassID(IMoniker* iface, CLSID *pClassID);
67
68/* IPersistStream prototype functions */
69static HRESULT WINAPI CompositeMonikerImpl_IsDirty(IMoniker* iface);
70static HRESULT WINAPI CompositeMonikerImpl_Load(IMoniker* iface, IStream* pStm);
71static HRESULT WINAPI CompositeMonikerImpl_Save(IMoniker* iface, IStream* pStm, BOOL fClearDirty);
72static HRESULT WINAPI CompositeMonikerImpl_GetSizeMax(IMoniker* iface, ULARGE_INTEGER* pcbSize);
73
74/* IMoniker prototype functions */
75static HRESULT WINAPI CompositeMonikerImpl_BindToObject(IMoniker* iface,IBindCtx* pbc, IMoniker* pmkToLeft, REFIID riid, VOID** ppvResult);
76static HRESULT WINAPI CompositeMonikerImpl_BindToStorage(IMoniker* iface,IBindCtx* pbc, IMoniker* pmkToLeft, REFIID riid, VOID** ppvResult);
77static HRESULT WINAPI CompositeMonikerImpl_Reduce(IMoniker* iface,IBindCtx* pbc, DWORD dwReduceHowFar,IMoniker** ppmkToLeft, IMoniker** ppmkReduced);
78static HRESULT WINAPI CompositeMonikerImpl_ComposeWith(IMoniker* iface,IMoniker* pmkRight,BOOL fOnlyIfNotGeneric, IMoniker** ppmkComposite);
79static HRESULT WINAPI CompositeMonikerImpl_Enum(IMoniker* iface,BOOL fForward, IEnumMoniker** ppenumMoniker);
80static HRESULT WINAPI CompositeMonikerImpl_IsEqual(IMoniker* iface,IMoniker* pmkOtherMoniker);
81static HRESULT WINAPI CompositeMonikerImpl_Hash(IMoniker* iface,DWORD* pdwHash);
82static HRESULT WINAPI CompositeMonikerImpl_IsRunning(IMoniker* iface,IBindCtx* pbc, IMoniker* pmkToLeft, IMoniker* pmkNewlyRunning);
83static HRESULT WINAPI CompositeMonikerImpl_GetTimeOfLastChange(IMoniker* iface, IBindCtx* pbc, IMoniker* pmkToLeft, FILETIME* pCompositeTime);
84static HRESULT WINAPI CompositeMonikerImpl_Inverse(IMoniker* iface,IMoniker** ppmk);
85static HRESULT WINAPI CompositeMonikerImpl_CommonPrefixWith(IMoniker* iface,IMoniker* pmkOther, IMoniker** ppmkPrefix);
86static HRESULT WINAPI CompositeMonikerImpl_RelativePathTo(IMoniker* iface,IMoniker* pmOther, IMoniker** ppmkRelPath);
87static HRESULT WINAPI CompositeMonikerImpl_GetDisplayName(IMoniker* iface,IBindCtx* pbc, IMoniker* pmkToLeft, LPOLESTR *ppszDisplayName);
88static HRESULT WINAPI CompositeMonikerImpl_ParseDisplayName(IMoniker* iface,IBindCtx* pbc, IMoniker* pmkToLeft, LPOLESTR pszDisplayName, ULONG* pchEaten, IMoniker** ppmkOut);
89static HRESULT WINAPI CompositeMonikerImpl_IsSystemMoniker(IMoniker* iface,DWORD* pwdMksys);
90
91/********************************************************************************/
92/* IROTData prototype functions */
93
94/* IUnknown prototype functions */
95static HRESULT WINAPI CompositeMonikerROTDataImpl_QueryInterface(IROTData* iface,REFIID riid,VOID** ppvObject);
96static ULONG WINAPI CompositeMonikerROTDataImpl_AddRef(IROTData* iface);
97static ULONG WINAPI CompositeMonikerROTDataImpl_Release(IROTData* iface);
98
99/* IROTData prototype function */
100static HRESULT WINAPI CompositeMonikerROTDataImpl_GetComparaisonData(IROTData* iface,BYTE* pbData,ULONG cbMax,ULONG* pcbData);
101
102/* Local function used by CompositeMoniker implementation */
103HRESULT WINAPI CompositeMonikerImpl_Construct(CompositeMonikerImpl* This,LPMONIKER pmkFirst, LPMONIKER pmkRest);
104HRESULT WINAPI CompositeMonikerImpl_Destroy(CompositeMonikerImpl* iface);
105
106/********************************************************************************/
107/* IEnumMoniker prototype functions */
108
109/* IUnknown prototype functions */
110static HRESULT WINAPI EnumMonikerImpl_QueryInterface(IEnumMoniker* iface,REFIID riid,void** ppvObject);
111static ULONG WINAPI EnumMonikerImpl_AddRef(IEnumMoniker* iface);
112static ULONG WINAPI EnumMonikerImpl_Release(IEnumMoniker* iface);
113
114/* IEnumMonker prototype functions */
115static HRESULT WINAPI EnumMonikerImpl_Next(IEnumMoniker* iface,ULONG celt,IMoniker** rgelt,ULONG* pceltFetched);
116static HRESULT WINAPI EnumMonikerImpl_Skip(IEnumMoniker* iface,ULONG celt);
117static HRESULT WINAPI EnumMonikerImpl_Reset(IEnumMoniker* iface);
118static HRESULT WINAPI EnumMonikerImpl_Clone(IEnumMoniker* iface,IEnumMoniker** ppenum);
119
120HRESULT WINAPI EnumMonikerImpl_CreateEnumMoniker(IMoniker** tabMoniker,ULONG tabSize,ULONG currentPos,BOOL leftToRigth,IEnumMoniker ** ppmk);
121
122/********************************************************************************/
123/* Virtual function table for the CompositeMonikerImpl class witch include */
124/* Ipersist, IPersistStream and IMoniker functions. */
125
126static ICOM_VTABLE(IMoniker) VT_CompositeMonikerImpl =
127{
128 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
129 CompositeMonikerImpl_QueryInterface,
130 CompositeMonikerImpl_AddRef,
131 CompositeMonikerImpl_Release,
132 CompositeMonikerImpl_GetClassID,
133 CompositeMonikerImpl_IsDirty,
134 CompositeMonikerImpl_Load,
135 CompositeMonikerImpl_Save,
136 CompositeMonikerImpl_GetSizeMax,
137 CompositeMonikerImpl_BindToObject,
138 CompositeMonikerImpl_BindToStorage,
139 CompositeMonikerImpl_Reduce,
140 CompositeMonikerImpl_ComposeWith,
141 CompositeMonikerImpl_Enum,
142 CompositeMonikerImpl_IsEqual,
143 CompositeMonikerImpl_Hash,
144 CompositeMonikerImpl_IsRunning,
145 CompositeMonikerImpl_GetTimeOfLastChange,
146 CompositeMonikerImpl_Inverse,
147 CompositeMonikerImpl_CommonPrefixWith,
148 CompositeMonikerImpl_RelativePathTo,
149 CompositeMonikerImpl_GetDisplayName,
150 CompositeMonikerImpl_ParseDisplayName,
151 CompositeMonikerImpl_IsSystemMoniker
152};
153
154/********************************************************************************/
155/* Virtual function table for the IROTData class. */
156static ICOM_VTABLE(IROTData) VT_ROTDataImpl =
157{
158 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
159 CompositeMonikerROTDataImpl_QueryInterface,
160 CompositeMonikerROTDataImpl_AddRef,
161 CompositeMonikerROTDataImpl_Release,
162 CompositeMonikerROTDataImpl_GetComparaisonData
163};
164
165/********************************************************************************/
166/* Virtual function table for the IROTData class */
167static ICOM_VTABLE(IEnumMoniker) VT_EnumMonikerImpl =
168{
169 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
170 EnumMonikerImpl_QueryInterface,
171 EnumMonikerImpl_AddRef,
172 EnumMonikerImpl_Release,
173 EnumMonikerImpl_Next,
174 EnumMonikerImpl_Skip,
175 EnumMonikerImpl_Reset,
176 EnumMonikerImpl_Clone
177};
178
179/*******************************************************************************
180 * CompositeMoniker_QueryInterface
181 *******************************************************************************/
182HRESULT WINAPI CompositeMonikerImpl_QueryInterface(IMoniker* iface,REFIID riid,void** ppvObject)
183{
184 ICOM_THIS(CompositeMonikerImpl,iface);
185
186 TRACE("(%p,%p,%p)\n",This,riid,ppvObject);
187
188 /* Perform a sanity check on the parameters.*/
189 if ( (This==0) || (ppvObject==0) )
190 return E_INVALIDARG;
191
192 /* Initialize the return parameter */
193 *ppvObject = 0;
194
195 /* Compare the riid with the interface IDs implemented by this object.*/
196 if (IsEqualIID(&IID_IUnknown, riid) ||
197 IsEqualIID(&IID_IPersist, riid) ||
198 IsEqualIID(&IID_IPersistStream, riid) ||
199 IsEqualIID(&IID_IMoniker, riid)
200 )
201 *ppvObject = iface;
202 else if (IsEqualIID(&IID_IROTData, riid))
203 *ppvObject = (IROTData*)&(This->lpvtbl2);
204
205 /* Check that we obtained an interface.*/
206 if ((*ppvObject)==0)
207 return E_NOINTERFACE;
208
209 /* Query Interface always increases the reference count by one when it is successful */
210 CompositeMonikerImpl_AddRef(iface);
211
212 return S_OK;
213}
214
215/******************************************************************************
216 * CompositeMoniker_AddRef
217 ******************************************************************************/
218ULONG WINAPI CompositeMonikerImpl_AddRef(IMoniker* iface)
219{
220 ICOM_THIS(CompositeMonikerImpl,iface);
221
222 TRACE("(%p)\n",This);
223
224 return ++(This->ref);
225}
226
227/******************************************************************************
228 * CompositeMoniker_Release
229 ******************************************************************************/
230ULONG WINAPI CompositeMonikerImpl_Release(IMoniker* iface)
231{
232 ICOM_THIS(CompositeMonikerImpl,iface);
233 ULONG i;
234
235 TRACE("(%p)\n",This);
236
237 This->ref--;
238
239 /* destroy the object if there's no more reference on it */
240 if (This->ref==0){
241
242 /* release all the components before destroying this object */
243 for (i=0;i<This->tabLastIndex;i++)
244 IMoniker_Release(This->tabMoniker[i]);
245
246 CompositeMonikerImpl_Destroy(This);
247
248 return 0;
249 }
250 return This->ref;;
251}
252
253/******************************************************************************
254 * CompositeMoniker_GetClassID
255 ******************************************************************************/
256HRESULT WINAPI CompositeMonikerImpl_GetClassID(IMoniker* iface,CLSID *pClassID)
257{
258 TRACE("(%p,%p),stub!\n",iface,pClassID);
259
260 if (pClassID==NULL)
261 return E_POINTER;
262
263 *pClassID = CLSID_CompositeMoniker;
264
265 return S_OK;
266}
267
268/******************************************************************************
269 * CompositeMoniker_IsDirty
270 ******************************************************************************/
271HRESULT WINAPI CompositeMonikerImpl_IsDirty(IMoniker* iface)
272{
273 /* Note that the OLE-provided implementations of the IPersistStream::IsDirty
274 method in the OLE-provided moniker interfaces always return S_FALSE because
275 their internal state never changes. */
276
277 TRACE("(%p)\n",iface);
278
279 return S_FALSE;
280}
281
282/******************************************************************************
283 * CompositeMoniker_Load
284 ******************************************************************************/
285HRESULT WINAPI CompositeMonikerImpl_Load(IMoniker* iface,IStream* pStm)
286{
287 HRESULT res;
288 CLSID clsid;
289 WCHAR string[1]={0};
290 ULONG countMoniker;
291
292 ICOM_THIS(CompositeMonikerImpl,iface);
293
294 TRACE("(%p,%p)\n",iface,pStm);
295
296 /* this function call OleLoadFromStream function for each moniker within this object */
297
298 /* read the number of monikers within the composite moniker*/
299 res=IStream_Read(pStm,&countMoniker,sizeof(countMoniker),NULL);
300
301 for(This->tabLastIndex=0; This->tabLastIndex < countMoniker; This->tabLastIndex++)
302 {
303#if 0
304 res=OleLoadFromStream(pStm,&IID_IMoniker,(void**)&This->tabMoniker[This->tabLastIndex]);
305#endif
306 res=ReadClassStm(pStm,&clsid);
307
308 if (FAILED(res))
309 return res;
310
311 if (IsEqualIID(&clsid,&CLSID_FileMoniker))
312 {
313 res=CreateFileMoniker(string,&This->tabMoniker[This->tabLastIndex]);
314 if (FAILED(res))
315 return res;
316 }
317 else if (IsEqualIID(&clsid,&CLSID_ItemMoniker))
318 {
319 CreateItemMoniker(string,string,&This->tabMoniker[This->tabLastIndex]);
320 if (FAILED(res))
321 return res;
322 }
323 else if (IsEqualIID(&clsid,&CLSID_AntiMoniker))
324 {
325 CreateAntiMoniker(&This->tabMoniker[This->tabLastIndex]);
326 if (FAILED(res))
327 return res;
328 }
329 else
330 return E_FAIL;
331
332 res=IMoniker_Load(This->tabMoniker[This->tabLastIndex],pStm);
333 if (FAILED(res))
334 return res;
335
336 /* resize the table if needed */
337 if (This->tabLastIndex==This->tabSize){
338
339 This->tabSize+=BLOCK_TAB_SIZE;
340 This->tabMoniker=(IMoniker**)HeapReAlloc(
341 GetProcessHeap(),0,This->tabMoniker,This->tabSize*sizeof(IMoniker));
342
343 if (This->tabMoniker==NULL)
344 return E_OUTOFMEMORY;
345 }
346 }
347
348 return res;
349}
350
351/******************************************************************************
352 * CompositeMoniker_Save
353 ******************************************************************************/
354HRESULT WINAPI CompositeMonikerImpl_Save(IMoniker* iface,IStream* pStm,BOOL fClearDirty)
355{
356 HRESULT res;
357 IEnumMoniker *enumMk;
358 IMoniker *pmk;
359
360 ICOM_THIS(CompositeMonikerImpl,iface);
361
362 TRACE("(%p,%p,%d)\n",iface,pStm,fClearDirty);
363
364 /* this function call OleSaveToStream function for each moniker within this object */
365
366 /* write the number of monikers within the composite moniker*/
367 res=IStream_Write(pStm,&(This->tabLastIndex),sizeof(This->tabLastIndex),NULL);
368
369 IMoniker_Enum(iface,TRUE,&enumMk);
370
371 while(IEnumMoniker_Next(enumMk,1,&pmk,NULL)==S_OK){
372
373 res=OleSaveToStream((IPersistStream*)pmk,pStm);
374
375 IMoniker_Release(pmk);
376
377 if (FAILED(res)){
378
379 IEnumMoniker_Release(pmk);
380 return res;
381 }
382 }
383
384 IEnumMoniker_Release(enumMk);
385
386 return S_OK;
387}
388
389/******************************************************************************
390 * CompositeMoniker_GetSizeMax
391 ******************************************************************************/
392HRESULT WINAPI CompositeMonikerImpl_GetSizeMax(IMoniker* iface,ULARGE_INTEGER* pcbSize)
393{
394 IEnumMoniker *enumMk;
395 IMoniker *pmk;
396 ULARGE_INTEGER ptmpSize;
397
398 /* the sizeMax of this object is calculated by calling GetSizeMax on each moniker within this object then */
399 /* suming all returned sizemax */
400
401 TRACE("(%p,%p)\n",iface,pcbSize);
402
403 if (pcbSize==NULL)
404 return E_POINTER;
405
406 pcbSize->LowPart =sizeof(DWORD) + 48;
407 pcbSize->HighPart=0;
408
409 IMoniker_Enum(iface,TRUE,&enumMk);
410
411 while(IEnumMoniker_Next(enumMk,1,&pmk,NULL)==TRUE){
412
413 IMoniker_GetSizeMax(pmk,&ptmpSize);
414
415 IMoniker_Release(pmk);
416
417 pcbSize->LowPart +=ptmpSize.LowPart; // FIXME - 64bit Math
418 pcbSize->HighPart+=ptmpSize.HighPart;
419 }
420
421 IEnumMoniker_Release(enumMk);
422
423 return S_OK;
424}
425
426#if 0
427/******************************************************************************
428 * CompositeMonikerImpl_GetSizeToSave (Local)
429 *******************************************************************************/
430HRESULT CompositeMonikerImpl_GetSizeToSave(IMoniker* iface,ULARGE_INTEGER* pcbSize)
431{
432 IEnumMoniker *enumMk;
433 IMoniker *pmk;
434 HRESULT hRes;
435 ULARGE_INTEGER ptmpSize;
436
437 if (pcbSize==NULL)
438 return E_POINTER;
439
440 pcbSize->LowPart = sizeof(DWORD);
441 pcbSize->HighPart=0;
442
443 IMoniker_Enum(iface,TRUE,&enumMk);
444
445 while((hRes = IEnumMoniker_Next(enumMk,1,&pmk,NULL))==S_OK){
446
447 GetSizeToSaveMoniker(pmk,&ptmpSize);
448 IMoniker_Release(pmk);
449
450 pcbSize->LowPart +=ptmpSize.LowPart; // FIXME - 64bit math
451 pcbSize->HighPart+=ptmpSize.HighPart;
452 }
453 IEnumMoniker_Release(enumMk);
454
455 return S_OK;
456}
457#endif
458
459
460/******************************************************************************
461 * Composite-Moniker_Construct (local function)
462 *******************************************************************************/
463HRESULT WINAPI CompositeMonikerImpl_Construct(CompositeMonikerImpl* This,LPMONIKER pmkFirst, LPMONIKER pmkRest)
464{
465 DWORD mkSys;
466 IEnumMoniker *enumMoniker;
467 IMoniker *tempMk;
468 HRESULT res;
469
470 TRACE("(%p,%p,%p)\n",This,pmkFirst,pmkRest);
471
472 /* Initialize the virtual fgunction table. */
473 This->lpvtbl1 = &VT_CompositeMonikerImpl;
474 This->lpvtbl2 = &VT_ROTDataImpl;
475 This->ref = 0;
476
477 This->tabSize=BLOCK_TAB_SIZE;
478 This->tabLastIndex=0;
479
480 This->tabMoniker=(IMoniker**)HeapAlloc(GetProcessHeap(),0,This->tabSize*sizeof(IMoniker));
481 if (This->tabMoniker==NULL)
482 return E_OUTOFMEMORY;
483
484 IMoniker_IsSystemMoniker(pmkFirst,&mkSys);
485
486 /* put the first moniker contents in the begining of the table */
487 if (mkSys!=MKSYS_GENERICCOMPOSITE){
488
489 This->tabMoniker[(This->tabLastIndex)++]=pmkFirst;
490 IMoniker_AddRef(pmkFirst);
491 }
492 else{
493
494 IMoniker_Enum(pmkFirst,TRUE,&enumMoniker);
495
496 while(IEnumMoniker_Next(enumMoniker,1,&This->tabMoniker[This->tabLastIndex],NULL)==S_OK){
497
498
499 if (++This->tabLastIndex==This->tabSize){
500
501 This->tabSize+=BLOCK_TAB_SIZE;
502 This->tabMoniker=(IMoniker**)HeapReAlloc(GetProcessHeap(),0,This->tabMoniker,This->tabSize*sizeof(IMoniker));
503
504 if (This->tabMoniker==NULL)
505 return E_OUTOFMEMORY;
506 }
507 }
508
509 IEnumMoniker_Release(enumMoniker);
510 }
511
512 /* put the rest moniker contents after the first one and make simplification if needed */
513
514 IMoniker_IsSystemMoniker(pmkRest,&mkSys);
515
516 if (mkSys!=MKSYS_GENERICCOMPOSITE){
517
518 /* add a simple moniker to the moniker table */
519
520 res=IMoniker_ComposeWith(This->tabMoniker[This->tabLastIndex-1],pmkRest,TRUE,&tempMk);
521
522 if (res==MK_E_NEEDGENERIC){
523
524 /* there's no simplification in this case */
525 This->tabMoniker[This->tabLastIndex]=pmkRest;
526
527 This->tabLastIndex++;
528
529 IMoniker_AddRef(pmkRest);
530 }
531 else if (tempMk==NULL){
532
533 /* we have an antimoniker after a simple moniker so we can make a simplification in this case */
534 IMoniker_Release(This->tabMoniker[This->tabLastIndex-1]);
535
536 This->tabLastIndex--;
537 }
538 else if (SUCCEEDED(res)){
539
540 /* the non-generic composition was successful so we can make a simplification in this case */
541 IMoniker_Release(This->tabMoniker[This->tabLastIndex-1]);
542
543 This->tabMoniker[This->tabLastIndex-1]=tempMk;
544 } else
545 return res;
546
547 /* resize tabMoniker if needed */
548 if (This->tabLastIndex==This->tabSize){
549
550 This->tabSize+=BLOCK_TAB_SIZE;
551
552 This->tabMoniker=(IMoniker**)HeapReAlloc(GetProcessHeap(),0,This->tabMoniker,This->tabSize*sizeof(IMoniker));
553
554 if (This->tabMoniker==NULL)
555 return E_OUTOFMEMORY;
556 }
557 }
558 else{
559
560 /* add a composite moniker to the moniker table (do the same thing for each moniker within the */
561 /* composite moniker as a simple moniker (see above how to add a simple moniker case) ) */
562 IMoniker_Enum(pmkRest,TRUE,&enumMoniker);
563
564 while(IEnumMoniker_Next(enumMoniker,1,&This->tabMoniker[This->tabLastIndex],NULL)==S_OK){
565
566 res=IMoniker_ComposeWith(This->tabMoniker[This->tabLastIndex-1],This->tabMoniker[This->tabLastIndex],TRUE,&tempMk);
567
568 if (res==MK_E_NEEDGENERIC){
569
570 This->tabLastIndex++;
571 }
572 else if (tempMk==NULL){
573
574 IMoniker_Release(This->tabMoniker[This->tabLastIndex-1]);
575 IMoniker_Release(This->tabMoniker[This->tabLastIndex]);
576 This->tabLastIndex--;
577 }
578 else{
579
580 IMoniker_Release(This->tabMoniker[This->tabLastIndex-1]);
581
582 This->tabMoniker[This->tabLastIndex-1]=tempMk;
583 }
584
585 if (This->tabLastIndex==This->tabSize){
586
587 This->tabSize+=BLOCK_TAB_SIZE;
588
589 This->tabMoniker=(IMoniker**)HeapReAlloc(GetProcessHeap(),0,This->tabMoniker,This->tabSize*sizeof(IMoniker));
590
591 if (This->tabMoniker==NULL)
592 return E_OUTOFMEMORY;
593 }
594 }
595
596 IEnumMoniker_Release(enumMoniker);
597 }
598
599 return S_OK;
600}
601
602/******************************************************************************
603 * CompositeMoniker_Destroy (local function)
604 *******************************************************************************/
605HRESULT WINAPI CompositeMonikerImpl_Destroy(CompositeMonikerImpl* This)
606{
607 TRACE("(%p)\n",This);
608
609 HeapFree(GetProcessHeap(),0,This->tabMoniker);
610
611 HeapFree(GetProcessHeap(),0,This);
612
613 return S_OK;
614}
615
616/******************************************************************************
617 * CompositeMoniker_BindToObject
618 ******************************************************************************/
619HRESULT WINAPI CompositeMonikerImpl_BindToObject(IMoniker* iface,
620 IBindCtx* pbc,
621 IMoniker* pmkToLeft,
622 REFIID riid,
623 VOID** ppvResult)
624{
625 HRESULT res;
626 IRunningObjectTable *prot;
627 IMoniker *tempMk,*antiMk,*mostRigthMk;
628 IEnumMoniker *enumMoniker;
629
630 TRACE("(%p,%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,riid,ppvResult);
631
632 if (ppvResult==NULL)
633 return E_POINTER;
634
635 *ppvResult=0;
636 /* If pmkToLeft is NULL, this method looks for the moniker in the ROT, and if found, queries the retrieved */
637 /* object for the requested interface pointer. */
638 if(pmkToLeft==NULL){
639
640 res=IBindCtx_GetRunningObjectTable(pbc,&prot);
641
642 if (SUCCEEDED(res)){
643
644 /* if the requested class was loaded befor ! we dont need to reload it */
645 res = IRunningObjectTable_GetObject(prot,iface,(IUnknown**)ppvResult);
646
647 if (res==S_OK)
648 return res;
649 }
650 }
651 else{
652 /* If pmkToLeft is not NULL, the method recursively calls IMoniker::BindToObject on the rightmost */
653 /* component of the composite, passing the rest of the composite as the pmkToLeft parameter for that call */
654
655 IMoniker_Enum(iface,FALSE,&enumMoniker);
656 IEnumMoniker_Next(enumMoniker,1,&mostRigthMk,NULL);
657 IEnumMoniker_Release(enumMoniker);
658
659 res=CreateAntiMoniker(&antiMk);
660 res=IMoniker_ComposeWith(iface,antiMk,0,&tempMk);
661 IMoniker_Release(antiMk);
662
663 res=CompositeMonikerImpl_BindToObject(mostRigthMk,pbc,tempMk,riid,ppvResult);
664
665 IMoniker_Release(tempMk);
666 IMoniker_Release(mostRigthMk);
667 }
668
669 return res;
670}
671
672/******************************************************************************
673 * CompositeMoniker_BindToStorage
674 ******************************************************************************/
675HRESULT WINAPI CompositeMonikerImpl_BindToStorage(IMoniker* iface,
676 IBindCtx* pbc,
677 IMoniker* pmkToLeft,
678 REFIID riid,
679 VOID** ppvResult)
680{
681 HRESULT res;
682 IMoniker *tempMk,*antiMk,*mostRigthMk;
683 IEnumMoniker *enumMoniker;
684
685 TRACE("(%p,%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,riid,ppvResult);
686
687 *ppvResult=0;
688
689 /* This method recursively calls BindToStorage on the rightmost component of the composite, */
690 /* passing the rest of the composite as the pmkToLeft parameter for that call. */
691
692 if (pmkToLeft!=NULL){
693
694 IMoniker_Enum(iface,FALSE,&enumMoniker);
695 IEnumMoniker_Next(enumMoniker,1,&mostRigthMk,NULL);
696 IEnumMoniker_Release(enumMoniker);
697
698 res=CreateAntiMoniker(&antiMk);
699 res=IMoniker_ComposeWith(iface,antiMk,0,&tempMk);
700 IMoniker_Release(antiMk);
701
702 res=CompositeMonikerImpl_BindToStorage(mostRigthMk,pbc,tempMk,riid,ppvResult);
703
704 IMoniker_Release(tempMk);
705
706 IMoniker_Release(mostRigthMk);
707
708 return res;
709 }
710 else
711 return IMoniker_BindToStorage(iface,pbc,NULL,riid,ppvResult);
712}
713
714/******************************************************************************
715 * CompositeMoniker_Reduce
716 ******************************************************************************/
717HRESULT WINAPI CompositeMonikerImpl_Reduce(IMoniker* iface,
718 IBindCtx* pbc,
719 DWORD dwReduceHowFar,
720 IMoniker** ppmkToLeft,
721 IMoniker** ppmkReduced)
722{
723 HRESULT res;
724 IMoniker *tempMk,*antiMk,*mostRigthMk,*leftReducedComposedMk,*mostRigthReducedMk;
725 IEnumMoniker *enumMoniker;
726
727 TRACE("(%p,%p,%ld,%p,%p)\n",iface,pbc,dwReduceHowFar,ppmkToLeft,ppmkReduced);
728
729 if (ppmkReduced==NULL)
730 return E_POINTER;
731
732 /* This method recursively calls Reduce for each of its component monikers. */
733
734 if (ppmkToLeft==NULL){
735
736 IMoniker_Enum(iface,FALSE,&enumMoniker);
737 IEnumMoniker_Next(enumMoniker,1,&mostRigthMk,NULL);
738 IEnumMoniker_Release(enumMoniker);
739
740 res=CreateAntiMoniker(&antiMk);
741 res=IMoniker_ComposeWith(iface,antiMk,0,&tempMk);
742 IMoniker_Release(antiMk);
743
744 return CompositeMonikerImpl_Reduce(mostRigthMk,pbc,dwReduceHowFar,&tempMk, ppmkReduced);
745 }
746 else if (*ppmkToLeft==NULL)
747
748 return IMoniker_Reduce(iface,pbc,dwReduceHowFar,NULL,ppmkReduced);
749
750 else{
751
752 /* separate the copmosite moniker in to left and wrigth moniker */
753 IMoniker_Enum(iface,FALSE,&enumMoniker);
754 IEnumMoniker_Next(enumMoniker,1,&mostRigthMk,NULL);
755 IEnumMoniker_Release(enumMoniker);
756
757 res=CreateAntiMoniker(&antiMk);
758 res=IMoniker_ComposeWith(iface,antiMk,0,&tempMk);
759 IMoniker_Release(antiMk);
760
761 /* If any of the components reduces itself, the method returns S_OK and passes back a composite */
762 /* of the reduced components */
763 if (IMoniker_Reduce(mostRigthMk,pbc,dwReduceHowFar,NULL,&mostRigthReducedMk) &&
764 CompositeMonikerImpl_Reduce(mostRigthMk,pbc,dwReduceHowFar,&tempMk,&leftReducedComposedMk)
765 )
766
767 return CreateGenericComposite(leftReducedComposedMk,mostRigthReducedMk,ppmkReduced);
768
769 else{
770 /* If no reduction occurred, the method passes back the same moniker and returns MK_S_REDUCED_TO_SELF.*/
771
772 IMoniker_AddRef(iface);
773
774 *ppmkReduced=iface;
775
776 return MK_S_REDUCED_TO_SELF;
777 }
778 }
779}
780
781/******************************************************************************
782 * CompositeMoniker_ComposeWith
783 ******************************************************************************/
784HRESULT WINAPI CompositeMonikerImpl_ComposeWith(IMoniker* iface,
785 IMoniker* pmkRight,
786 BOOL fOnlyIfNotGeneric,
787 IMoniker** ppmkComposite)
788{
789 TRACE("(%p,%p,%d,%p)\n",iface,pmkRight,fOnlyIfNotGeneric,ppmkComposite);
790
791 if ((ppmkComposite==NULL)||(pmkRight==NULL))
792 return E_POINTER;
793
794 *ppmkComposite=0;
795
796 /* If fOnlyIfNotGeneric is TRUE, this method sets *pmkComposite to NULL and returns MK_E_NEEDGENERIC; */
797 /* otherwise, the method returns the result of combining the two monikers by calling the */
798 /* CreateGenericComposite function */
799
800 if (fOnlyIfNotGeneric)
801 return MK_E_NEEDGENERIC;
802
803 return CreateGenericComposite(iface,pmkRight,ppmkComposite);
804}
805
806/******************************************************************************
807 * CompositeMoniker_Enum
808 ******************************************************************************/
809HRESULT WINAPI CompositeMonikerImpl_Enum(IMoniker* iface,BOOL fForward, IEnumMoniker** ppenumMoniker)
810{
811 ICOM_THIS(CompositeMonikerImpl,iface);
812
813 TRACE("(%p,%d,%p)\n",iface,fForward,ppenumMoniker);
814
815 if (ppenumMoniker == NULL)
816 return E_POINTER;
817
818 return EnumMonikerImpl_CreateEnumMoniker(This->tabMoniker,This->tabLastIndex,0,fForward,ppenumMoniker);
819}
820
821/******************************************************************************
822 * CompositeMoniker_IsEqual
823 ******************************************************************************/
824HRESULT WINAPI CompositeMonikerImpl_IsEqual(IMoniker* iface,IMoniker* pmkOtherMoniker)
825{
826 IEnumMoniker *enumMoniker1,*enumMoniker2;
827 IMoniker *tempMk1,*tempMk2;
828 HRESULT res1,res2,res;
829
830 TRACE("(%p,%p)\n",iface,pmkOtherMoniker);
831
832 if (pmkOtherMoniker==NULL)
833 return S_FALSE;
834
835 /* This method returns S_OK if the components of both monikers are equal when compared in the */
836 /* left-to-right order.*/
837 IMoniker_Enum(pmkOtherMoniker,TRUE,&enumMoniker1);
838
839 if (enumMoniker1==NULL)
840 return S_FALSE;
841
842 IMoniker_Enum(iface,TRUE,&enumMoniker2);
843
844 while(1){
845
846 res1=IEnumMoniker_Next(enumMoniker1,1,&tempMk1,NULL);
847 res2=IEnumMoniker_Next(enumMoniker2,1,&tempMk2,NULL);
848
849 if((res1==S_OK)&&(res2==S_OK)){
850
851 if(IMoniker_IsEqual(tempMk1,tempMk2)==S_FALSE){
852 res= S_FALSE;
853 break;
854 }
855 else
856 continue;
857 }
858 else if ( (res1==S_FALSE) && (res2==S_FALSE) ){
859 res = S_OK;
860 break;
861 }
862 else{
863 res = S_FALSE;
864 break;
865 }
866
867 if (res1==S_OK)
868 IMoniker_Release(tempMk1);
869
870 if (res2==S_OK)
871 IMoniker_Release(tempMk2);
872 }
873
874 IEnumMoniker_Release(enumMoniker1);
875 IEnumMoniker_Release(enumMoniker2);
876
877 return res;
878}
879/******************************************************************************
880 * CompositeMoniker_Hash
881 ******************************************************************************/
882HRESULT WINAPI CompositeMonikerImpl_Hash(IMoniker* iface,DWORD* pdwHash)
883{
884 FIXME("(),stub!\n");
885
886 return E_NOTIMPL;
887}
888
889/******************************************************************************
890 * CompositeMoniker_IsRunning
891 ******************************************************************************/
892HRESULT WINAPI CompositeMonikerImpl_IsRunning(IMoniker* iface,
893 IBindCtx* pbc,
894 IMoniker* pmkToLeft,
895 IMoniker* pmkNewlyRunning)
896{
897 IRunningObjectTable* rot;
898 HRESULT res;
899 IMoniker *tempMk,*antiMk,*mostRigthMk;
900 IEnumMoniker *enumMoniker;
901
902 TRACE("(%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,pmkNewlyRunning);
903
904 /* If pmkToLeft is non-NULL, this method composes pmkToLeft with this moniker and calls IsRunning on the result.*/
905 if (pmkToLeft!=NULL){
906
907 CreateGenericComposite(pmkToLeft,iface,&tempMk);
908
909 res = IMoniker_IsRunning(tempMk,pbc,NULL,pmkNewlyRunning);
910
911 IMoniker_Release(tempMk);
912
913 return res;
914 }
915 else
916 /* If pmkToLeft is NULL, this method returns S_OK if pmkNewlyRunning is non-NULL and is equal */
917 /* to this moniker */
918
919 if (pmkNewlyRunning!=NULL)
920
921 if (IMoniker_IsEqual(iface,pmkNewlyRunning)==S_OK)
922 return S_OK;
923
924 else
925 return S_FALSE;
926
927 else{
928
929 if (pbc==NULL)
930 return E_POINTER;
931
932 /* If pmkToLeft and pmkNewlyRunning are both NULL, this method checks the ROT to see whether */
933 /* the moniker is running. If so, the method returns S_OK; otherwise, it recursively calls */
934 /* IMoniker::IsRunning on the rightmost component of the composite, passing the remainder of */
935 /* the composite as the pmkToLeft parameter for that call. */
936
937 res=IBindCtx_GetRunningObjectTable(pbc,&rot);
938
939 if (FAILED(res))
940 return res;
941
942 res = IRunningObjectTable_IsRunning(rot,iface);
943 IRunningObjectTable_Release(rot);
944
945 if(res==S_OK)
946 return S_OK;
947
948 else{
949
950 IMoniker_Enum(iface,FALSE,&enumMoniker);
951 IEnumMoniker_Next(enumMoniker,1,&mostRigthMk,NULL);
952 IEnumMoniker_Release(enumMoniker);
953
954 res=CreateAntiMoniker(&antiMk);
955 res=IMoniker_ComposeWith(iface,antiMk,0,&tempMk);
956 IMoniker_Release(antiMk);
957
958 res=IMoniker_IsRunning(mostRigthMk,pbc,tempMk,pmkNewlyRunning);
959
960 IMoniker_Release(tempMk);
961 IMoniker_Release(mostRigthMk);
962
963 return res;
964 }
965 }
966}
967
968/******************************************************************************
969 * CompositeMoniker_GetTimeOfLastChange
970 ******************************************************************************/
971HRESULT WINAPI CompositeMonikerImpl_GetTimeOfLastChange(IMoniker* iface,
972 IBindCtx* pbc,
973 IMoniker* pmkToLeft,
974 FILETIME* pCompositeTime)
975{
976 IRunningObjectTable* rot;
977 HRESULT res;
978 IMoniker *tempMk,*antiMk,*mostRigthMk;
979 IEnumMoniker *enumMoniker;
980
981 TRACE("(%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,pCompositeTime);
982
983 if (pCompositeTime==NULL)
984 return E_INVALIDARG;
985
986 /* This method creates a composite of pmkToLeft (if non-NULL) and this moniker and uses the ROT to */
987 /* retrieve the time of last change. If the object is not in the ROT, the method recursively calls */
988 /* IMoniker::GetTimeOfLastChange on the rightmost component of the composite, passing the remainder */
989 /* of the composite as the pmkToLeft parameter for that call. */
990 if (pmkToLeft!=NULL){
991
992 res=CreateGenericComposite(pmkToLeft,iface,&tempMk);
993
994 res=IBindCtx_GetRunningObjectTable(pbc,&rot);
995
996 if (FAILED(res))
997 return res;
998
999 if (IRunningObjectTable_GetTimeOfLastChange(rot,tempMk,pCompositeTime)==S_OK)
1000 return res;
1001 else
1002
1003 IMoniker_Enum(iface,FALSE,&enumMoniker);
1004 IEnumMoniker_Next(enumMoniker,1,&mostRigthMk,NULL);
1005 IEnumMoniker_Release(enumMoniker);
1006
1007 res=CreateAntiMoniker(&antiMk);
1008 res=IMoniker_ComposeWith(iface,antiMk,0,&tempMk);
1009 IMoniker_Release(antiMk);
1010
1011 res=CompositeMonikerImpl_GetTimeOfLastChange(mostRigthMk,pbc,tempMk,pCompositeTime);
1012
1013 IMoniker_Release(tempMk);
1014 IMoniker_Release(mostRigthMk);
1015
1016 return res;
1017 }
1018 else
1019 return IMoniker_GetTimeOfLastChange(iface,pbc,NULL,pCompositeTime);
1020}
1021
1022/******************************************************************************
1023 * CompositeMoniker_Inverse
1024 ******************************************************************************/
1025HRESULT WINAPI CompositeMonikerImpl_Inverse(IMoniker* iface,IMoniker** ppmk)
1026{
1027 HRESULT res;
1028 IMoniker *tempMk,*antiMk,*mostRigthMk,*tempInvMk,*mostRigthInvMk;
1029 IEnumMoniker *enumMoniker;
1030
1031 TRACE("(%p,%p)\n",iface,ppmk);
1032
1033 if (ppmk==NULL)
1034 return E_POINTER;
1035
1036 /* This method returns a composite moniker that consists of the inverses of each of the components */
1037 /* of the original composite, stored in reverse order */
1038
1039 res=CreateAntiMoniker(&antiMk);
1040 res=IMoniker_ComposeWith(iface,antiMk,0,&tempMk);
1041 IMoniker_Release(antiMk);
1042
1043 if (tempMk==NULL)
1044
1045 return IMoniker_Inverse(iface,ppmk);
1046
1047 else{
1048
1049 IMoniker_Enum(iface,FALSE,&enumMoniker);
1050 IEnumMoniker_Next(enumMoniker,1,&mostRigthMk,NULL);
1051 IEnumMoniker_Release(enumMoniker);
1052
1053 IMoniker_Inverse(mostRigthMk,&mostRigthInvMk);
1054 CompositeMonikerImpl_Inverse(tempMk,&tempInvMk);
1055
1056 res=CreateGenericComposite(mostRigthInvMk,tempInvMk,ppmk);
1057
1058 IMoniker_Release(tempMk);
1059 IMoniker_Release(mostRigthMk);
1060 IMoniker_Release(tempInvMk);
1061 IMoniker_Release(mostRigthInvMk);
1062
1063 return res;
1064 }
1065}
1066
1067/******************************************************************************
1068 * CompositeMoniker_CommonPrefixWith
1069 ******************************************************************************/
1070HRESULT WINAPI CompositeMonikerImpl_CommonPrefixWith(IMoniker* iface,IMoniker* pmkOther,IMoniker** ppmkPrefix)
1071{
1072 DWORD mkSys;
1073 HRESULT res1,res2;
1074 IMoniker *tempMk1,*tempMk2,*mostLeftMk1,*mostLeftMk2;
1075 IEnumMoniker *enumMoniker1,*enumMoniker2;
1076 ULONG i,nbCommonMk=0;
1077
1078 /* If the other moniker is a composite, this method compares the components of each composite from left */
1079 /* to right. The returned common prefix moniker might also be a composite moniker, depending on how many */
1080 /* of the leftmost components were common to both monikers. */
1081
1082 if (ppmkPrefix==NULL)
1083 return E_POINTER;
1084
1085 *ppmkPrefix=0;
1086
1087 if (pmkOther==NULL)
1088 return MK_E_NOPREFIX;
1089
1090 IMoniker_IsSystemMoniker(pmkOther,&mkSys);
1091
1092 if((mkSys==MKSYS_GENERICCOMPOSITE)){
1093
1094 IMoniker_Enum(iface,TRUE,&enumMoniker1);
1095 IMoniker_Enum(pmkOther,TRUE,&enumMoniker2);
1096
1097 while(1){
1098
1099 res1=IEnumMoniker_Next(enumMoniker1,1,&mostLeftMk1,NULL);
1100 res2=IEnumMoniker_Next(enumMoniker2,1,&mostLeftMk2,NULL);
1101
1102 if ((res1==S_FALSE) && (res2==S_FALSE)){
1103
1104 /* If the monikers are equal, the method returns MK_S_US and sets ppmkPrefix to this moniker.*/
1105 *ppmkPrefix=iface;
1106 IMoniker_AddRef(iface);
1107 return MK_S_US;
1108 }
1109 else if ((res1==S_OK) && (res2==S_OK)){
1110
1111 if (IMoniker_IsEqual(mostLeftMk1,mostLeftMk2)==S_OK)
1112
1113 nbCommonMk++;
1114
1115 else
1116 break;
1117
1118 }
1119 else if (res1==S_OK){
1120
1121 /* If the other moniker is a prefix of this moniker, the method returns MK_S_HIM and sets */
1122 /* ppmkPrefix to the other moniker. */
1123 *ppmkPrefix=pmkOther;
1124 return MK_S_HIM;
1125 }
1126 else{
1127 /* If this moniker is a prefix of the other, this method returns MK_S_ME and sets ppmkPrefix */
1128 /* to this moniker. */
1129 *ppmkPrefix=iface;
1130 return MK_S_ME;
1131 }
1132 }
1133
1134 IEnumMoniker_Release(enumMoniker1);
1135 IEnumMoniker_Release(enumMoniker2);
1136
1137 /* If there is no common prefix, this method returns MK_E_NOPREFIX and sets ppmkPrefix to NULL. */
1138 if (nbCommonMk==0)
1139 return MK_E_NOPREFIX;
1140
1141 IEnumMoniker_Reset(enumMoniker1);
1142
1143 IEnumMoniker_Next(enumMoniker1,1,&tempMk1,NULL);
1144
1145 /* if we have more than one commun moniker the result will be a composite moniker */
1146 if (nbCommonMk>1){
1147
1148 /* initialize the common prefix moniker with the composite of two first moniker (from the left)*/
1149 IEnumMoniker_Next(enumMoniker1,1,&tempMk2,NULL);
1150 CreateGenericComposite(tempMk1,tempMk2,ppmkPrefix);
1151 IMoniker_Release(tempMk1);
1152 IMoniker_Release(tempMk2);
1153
1154 /* compose all common monikers in a composite moniker */
1155 for(i=0;i<nbCommonMk;i++){
1156
1157 IEnumMoniker_Next(enumMoniker1,1,&tempMk1,NULL);
1158
1159 CreateGenericComposite(*ppmkPrefix,tempMk1,&tempMk2);
1160
1161 IMoniker_Release(*ppmkPrefix);
1162
1163 IMoniker_Release(tempMk1);
1164
1165 *ppmkPrefix=tempMk2;
1166 }
1167 return S_OK;
1168 }
1169 else{
1170 /* if we have only one commun moniker the result will be a simple moniker which is the most-left one*/
1171 *ppmkPrefix=tempMk1;
1172
1173 return S_OK;
1174 }
1175 }
1176 else{
1177 /* If the other moniker is not a composite, the method simply compares it to the leftmost component
1178 of this moniker.*/
1179
1180 IMoniker_Enum(iface,TRUE,&enumMoniker1);
1181
1182 IEnumMoniker_Next(enumMoniker1,1,&mostLeftMk1,NULL);
1183
1184 if (IMoniker_IsEqual(pmkOther,mostLeftMk1)==S_OK){
1185
1186 *ppmkPrefix=pmkOther;
1187
1188 return MK_S_HIM;
1189 }
1190 else
1191 return MK_E_NOPREFIX;
1192 }
1193}
1194/***************************************************************************************************
1195 * GetAfterCommonPrefix (local function)
1196 * This function returns a moniker that consist of the remainder when the common prefix is removed
1197 ***************************************************************************************************/
1198VOID WINAPI GetAfterCommonPrefix(IMoniker* pGenMk,IMoniker* commonMk,IMoniker** restMk)
1199{
1200 IMoniker *tempMk,*tempMk1,*tempMk2;
1201 IEnumMoniker *enumMoniker1,*enumMoniker2,*enumMoniker3;
1202 ULONG nbRestMk=0;
1203 DWORD mkSys;
1204 HRESULT res1,res2;
1205
1206 *restMk=0;
1207
1208 /* to create an enumerator for pGenMk with current position pointed on the first element after common */
1209 /* prefix: enum the two monikers (left-wrigth) then compare these enumerations (left-wrigth) and stop */
1210 /* on the first difference. */
1211 IMoniker_Enum(pGenMk,TRUE,&enumMoniker1);
1212
1213 IMoniker_IsSystemMoniker(commonMk,&mkSys);
1214
1215 if (mkSys==MKSYS_GENERICCOMPOSITE){
1216
1217 IMoniker_Enum(commonMk,TRUE,&enumMoniker2);
1218 while(1){
1219
1220 res1=IEnumMoniker_Next(enumMoniker1,1,&tempMk1,NULL);
1221 res2=IEnumMoniker_Next(enumMoniker2,1,&tempMk2,NULL);
1222
1223 if ((res1==S_FALSE)||(res2==S_FALSE)){
1224
1225 if (res1==S_OK)
1226
1227 nbRestMk++;
1228
1229 IMoniker_Release(tempMk1);
1230 IMoniker_Release(tempMk1);
1231
1232 break;
1233 }
1234 IMoniker_Release(tempMk1);
1235 IMoniker_Release(tempMk1);
1236 }
1237 }
1238 else{
1239 IEnumMoniker_Next(enumMoniker1,1,&tempMk1,NULL);
1240 IMoniker_Release(tempMk1);
1241 }
1242
1243 /* count the number of elements in the enumerator after the common prefix */
1244 IEnumMoniker_Clone(enumMoniker1,&enumMoniker3);
1245
1246 for(;IEnumMoniker_Next(enumMoniker3,1,&tempMk,NULL)==S_OK;nbRestMk++)
1247
1248 IMoniker_Release(tempMk);;
1249
1250 if (nbRestMk==0)
1251 return;
1252
1253 /* create a generic composite moniker with monikers located after the common prefix */
1254 IEnumMoniker_Next(enumMoniker1,1,&tempMk1,NULL);
1255
1256 if (nbRestMk==1){
1257
1258 *restMk= tempMk1;
1259 return;
1260 }
1261 else {
1262
1263 IEnumMoniker_Next(enumMoniker1,1,&tempMk2,NULL);
1264
1265 CreateGenericComposite(tempMk1,tempMk2,restMk);
1266
1267 IMoniker_Release(tempMk1);
1268
1269 IMoniker_Release(tempMk2);
1270
1271 while(IEnumMoniker_Next(enumMoniker1,1,&tempMk1,NULL)==S_OK){
1272
1273 CreateGenericComposite(*restMk,tempMk1,&tempMk2);
1274
1275 IMoniker_Release(tempMk1);
1276
1277 IMoniker_Release(*restMk);
1278
1279 *restMk=tempMk2;
1280 }
1281 }
1282}
1283/******************************************************************************
1284 * CompositeMoniker_RelativePathTo
1285 ******************************************************************************/
1286HRESULT WINAPI CompositeMonikerImpl_RelativePathTo(IMoniker* iface,IMoniker* pmkOther, IMoniker** ppmkRelPath)
1287{
1288 HRESULT res;
1289 IMoniker *restOtherMk=0,*restThisMk=0,*invRestThisMk=0,*commonMk=0;
1290
1291 TRACE("(%p,%p,%p)\n",iface,pmkOther,ppmkRelPath);
1292
1293 if (ppmkRelPath==NULL)
1294 return E_POINTER;
1295
1296 *ppmkRelPath=0;
1297
1298 /* This method finds the common prefix of the two monikers and creates two monikers that consist */
1299 /* of the remainder when the common prefix is removed. Then it creates the inverse for the remainder */
1300 /* of this moniker and composes the remainder of the other moniker on the right of it. */
1301
1302 /* finds the common prefix of the two monikers */
1303 res=IMoniker_CommonPrefixWith(iface,pmkOther,&commonMk);
1304
1305 /* if there's no common prefix or the two moniker are equal the relative is the other moniker */
1306 if ((res== MK_E_NOPREFIX)||(res==MK_S_US)){
1307
1308 *ppmkRelPath=pmkOther;
1309 IMoniker_AddRef(pmkOther);
1310 return MK_S_HIM;
1311 }
1312
1313 GetAfterCommonPrefix(iface,commonMk,&restThisMk);
1314 GetAfterCommonPrefix(pmkOther,commonMk,&restOtherMk);
1315
1316 /* if other is a prefix of this moniker the relative path is the inverse of the remainder path of this */
1317 /* moniker when the common prefix is removed */
1318 if (res==MK_S_HIM){
1319
1320 IMoniker_Inverse(restThisMk,ppmkRelPath);
1321 IMoniker_Release(restThisMk);
1322 }
1323 /* if this moniker is a prefix of other moniker the relative path is the remainder path of other moniker */
1324 /* when the common prefix is removed */
1325 else if (res==MK_S_ME){
1326
1327 *ppmkRelPath=restOtherMk;
1328 IMoniker_AddRef(restOtherMk);
1329 }
1330 /* the relative path is the inverse for the remainder of this moniker and the remainder of the other */
1331 /* moniker on the right of it. */
1332 else if (res==S_OK){
1333
1334 IMoniker_Inverse(restThisMk,&invRestThisMk);
1335 IMoniker_Release(restThisMk);
1336 CreateGenericComposite(invRestThisMk,restOtherMk,ppmkRelPath);
1337 IMoniker_Release(invRestThisMk);
1338 IMoniker_Release(restOtherMk);
1339 }
1340 return S_OK;
1341}
1342
1343/******************************************************************************
1344 * CompositeMoniker_GetDisplayName
1345 ******************************************************************************/
1346HRESULT WINAPI CompositeMonikerImpl_GetDisplayName(IMoniker* iface,
1347 IBindCtx* pbc,
1348 IMoniker* pmkToLeft,
1349 LPOLESTR *ppszDisplayName)
1350{
1351 ULONG lengthStr=1;
1352 IEnumMoniker *enumMoniker;
1353 IMoniker* tempMk;
1354 LPOLESTR tempStr;
1355
1356 TRACE("(%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,ppszDisplayName);
1357
1358 if (ppszDisplayName==NULL)
1359 return E_POINTER;
1360
1361 *ppszDisplayName=(WCHAR*)CoTaskMemAlloc(sizeof(WCHAR));
1362
1363 if (*ppszDisplayName==NULL)
1364 return E_OUTOFMEMORY;
1365
1366 /* This method returns the concatenation of the display names returned by each component moniker of */
1367 /* the composite */
1368
1369 **ppszDisplayName=0;
1370
1371 IMoniker_Enum(iface,TRUE,&enumMoniker);
1372
1373 while(IEnumMoniker_Next(enumMoniker,1,&tempMk,NULL)==S_OK){
1374
1375 IMoniker_GetDisplayName(tempMk,pbc,NULL,&tempStr);
1376
1377 lengthStr+=lstrlenW(tempStr);
1378
1379 *ppszDisplayName=(WCHAR*)CoTaskMemRealloc(*ppszDisplayName,lengthStr * sizeof(WCHAR));
1380
1381 if (*ppszDisplayName==NULL)
1382 return E_OUTOFMEMORY;
1383
1384 lstrcatW(*ppszDisplayName,tempStr);
1385
1386 CoTaskMemFree(tempStr);
1387 IMoniker_Release(tempMk);
1388 }
1389
1390 IEnumMoniker_Release(enumMoniker);
1391
1392 return S_OK;
1393}
1394
1395/******************************************************************************
1396 * CompositeMoniker_ParseDisplayName
1397 ******************************************************************************/
1398HRESULT WINAPI CompositeMonikerImpl_ParseDisplayName(IMoniker* iface,
1399 IBindCtx* pbc,
1400 IMoniker* pmkToLeft,
1401 LPOLESTR pszDisplayName,
1402 ULONG* pchEaten,
1403 IMoniker** ppmkOut)
1404{
1405 IEnumMoniker *enumMoniker;
1406 IMoniker *tempMk,*mostRigthMk,*antiMk;
1407 /* This method recursively calls IMoniker::ParseDisplayName on the rightmost component of the composite,*/
1408 /* passing everything else as the pmkToLeft parameter for that call. */
1409
1410 /* get the most rigth moniker */
1411 IMoniker_Enum(iface,FALSE,&enumMoniker);
1412 IEnumMoniker_Next(enumMoniker,1,&mostRigthMk,NULL);
1413 IEnumMoniker_Release(enumMoniker);
1414
1415 /* get the left moniker */
1416 CreateAntiMoniker(&antiMk);
1417 IMoniker_ComposeWith(iface,antiMk,0,&tempMk);
1418 IMoniker_Release(antiMk);
1419
1420 return IMoniker_ParseDisplayName(mostRigthMk,pbc,tempMk,pszDisplayName,pchEaten,ppmkOut);
1421}
1422
1423/******************************************************************************
1424 * CompositeMoniker_IsSystemMonker
1425 ******************************************************************************/
1426HRESULT WINAPI CompositeMonikerImpl_IsSystemMoniker(IMoniker* iface,DWORD* pwdMksys)
1427{
1428 TRACE("(%p,%p)\n",iface,pwdMksys);
1429
1430 if (!pwdMksys)
1431 return E_POINTER;
1432
1433 (*pwdMksys)=MKSYS_GENERICCOMPOSITE;
1434
1435 return S_OK;
1436}
1437
1438/*******************************************************************************
1439 * CompositeMonikerIROTData_QueryInterface
1440 *******************************************************************************/
1441HRESULT WINAPI CompositeMonikerROTDataImpl_QueryInterface(IROTData *iface,REFIID riid,VOID** ppvObject)
1442{
1443
1444 ICOM_THIS_From_IROTData(IMoniker, iface);
1445
1446 TRACE("(%p,%p,%p)\n",iface,riid,ppvObject);
1447
1448 return CompositeMonikerImpl_QueryInterface(This, riid, ppvObject);
1449}
1450
1451/***********************************************************************
1452 * CompositeMonikerIROTData_AddRef
1453 */
1454ULONG WINAPI CompositeMonikerROTDataImpl_AddRef(IROTData *iface)
1455{
1456 ICOM_THIS_From_IROTData(IMoniker, iface);
1457
1458 TRACE("(%p)\n",iface);
1459
1460 return CompositeMonikerImpl_AddRef(This);
1461}
1462
1463/***********************************************************************
1464 * CompositeMonikerIROTData_Release
1465 */
1466ULONG WINAPI CompositeMonikerROTDataImpl_Release(IROTData* iface)
1467{
1468 ICOM_THIS_From_IROTData(IMoniker, iface);
1469
1470 TRACE("(%p)\n",iface);
1471
1472 return CompositeMonikerImpl_Release(This);
1473}
1474
1475/******************************************************************************
1476 * CompositeMonikerIROTData_GetComparaisonData
1477 ******************************************************************************/
1478HRESULT WINAPI CompositeMonikerROTDataImpl_GetComparaisonData(IROTData* iface,
1479 BYTE* pbData,
1480 ULONG cbMax,
1481 ULONG* pcbData)
1482{
1483 FIXME("(),stub!\n");
1484 return E_NOTIMPL;
1485}
1486
1487/******************************************************************************
1488 * EnumMonikerImpl_QueryInterface
1489 ******************************************************************************/
1490HRESULT WINAPI EnumMonikerImpl_QueryInterface(IEnumMoniker* iface,REFIID riid,void** ppvObject)
1491{
1492 ICOM_THIS(EnumMonikerImpl,iface);
1493
1494 TRACE("(%p,%p,%p)\n",This,riid,ppvObject);
1495
1496 /* Perform a sanity check on the parameters.*/
1497 if ( (This==0) || (ppvObject==0) )
1498 return E_INVALIDARG;
1499
1500 /* Initialize the return parameter */
1501 *ppvObject = 0;
1502
1503 /* Compare the riid with the interface IDs implemented by this object.*/
1504 if (IsEqualIID(&IID_IUnknown, riid) || IsEqualIID(&IID_IEnumMoniker, riid))
1505 *ppvObject = iface;
1506
1507 /* Check that we obtained an interface.*/
1508 if ((*ppvObject)==0)
1509 return E_NOINTERFACE;
1510
1511 /* Query Interface always increases the reference count by one when it is successful */
1512 EnumMonikerImpl_AddRef(iface);
1513
1514 return S_OK;
1515}
1516
1517/******************************************************************************
1518 * EnumMonikerImpl_AddRef
1519 ******************************************************************************/
1520ULONG WINAPI EnumMonikerImpl_AddRef(IEnumMoniker* iface)
1521{
1522 ICOM_THIS(EnumMonikerImpl,iface);
1523
1524 TRACE("(%p)\n",This);
1525
1526 return ++(This->ref);
1527
1528}
1529
1530/******************************************************************************
1531 * EnumMonikerImpl_Release
1532 ******************************************************************************/
1533ULONG WINAPI EnumMonikerImpl_Release(IEnumMoniker* iface)
1534{
1535 ICOM_THIS(EnumMonikerImpl,iface);
1536
1537 ULONG i;
1538
1539 This->ref--;
1540
1541 /* destroy the object if there's no more reference on it */
1542 if (This->ref==0){
1543
1544 for(i=0;i<This->tabSize;i++)
1545 IMoniker_Release(This->tabMoniker[i]);
1546
1547 HeapFree(GetProcessHeap(),0,This->tabMoniker);
1548 HeapFree(GetProcessHeap(),0,This);
1549
1550 return 0;
1551 }
1552 return This->ref;;
1553}
1554
1555/******************************************************************************
1556 * EnumMonikerImpl_Next
1557 ******************************************************************************/
1558HRESULT WINAPI EnumMonikerImpl_Next(IEnumMoniker* iface,ULONG celt, IMoniker** rgelt, ULONG* pceltFethed){
1559
1560 ICOM_THIS(EnumMonikerImpl,iface);
1561 ULONG i;
1562
1563 /* retrieve the requested number of moniker from the current position */
1564 for(i=0;((This->currentPos < This->tabSize) && (i < celt));i++)
1565
1566 rgelt[i]=This->tabMoniker[This->currentPos++];
1567
1568 if (pceltFethed!=NULL)
1569 *pceltFethed= i;
1570
1571 if (i==celt)
1572 return S_OK;
1573 else
1574 return S_FALSE;
1575}
1576
1577/******************************************************************************
1578 * EnumMonikerImpl_Skip
1579 ******************************************************************************/
1580HRESULT WINAPI EnumMonikerImpl_Skip(IEnumMoniker* iface,ULONG celt){
1581
1582 ICOM_THIS(EnumMonikerImpl,iface);
1583
1584 if ((This->currentPos+celt) >= This->tabSize)
1585 return S_FALSE;
1586
1587 This->currentPos+=celt;
1588
1589 return S_OK;
1590}
1591
1592/******************************************************************************
1593 * EnumMonikerImpl_Reset
1594 ******************************************************************************/
1595HRESULT WINAPI EnumMonikerImpl_Reset(IEnumMoniker* iface){
1596
1597 ICOM_THIS(EnumMonikerImpl,iface);
1598
1599 This->currentPos=0;
1600
1601 return S_OK;
1602}
1603
1604/******************************************************************************
1605 * EnumMonikerImpl_Clone
1606 ******************************************************************************/
1607HRESULT WINAPI EnumMonikerImpl_Clone(IEnumMoniker* iface,IEnumMoniker** ppenum){
1608
1609 ICOM_THIS(EnumMonikerImpl,iface);
1610
1611 return EnumMonikerImpl_CreateEnumMoniker(This->tabMoniker,This->tabSize,This->currentPos,TRUE,ppenum);
1612}
1613
1614/******************************************************************************
1615 * EnumMonikerImpl_CreateEnumMoniker
1616 ******************************************************************************/
1617HRESULT WINAPI EnumMonikerImpl_CreateEnumMoniker(IMoniker** tabMoniker,
1618 ULONG tabSize,
1619 ULONG currentPos,
1620 BOOL leftToRigth,
1621 IEnumMoniker ** ppmk)
1622{
1623 EnumMonikerImpl* newEnumMoniker;
1624 int i;
1625
1626
1627 newEnumMoniker = (EnumMonikerImpl*)HeapAlloc(GetProcessHeap(), 0, sizeof(EnumMonikerImpl));
1628
1629 if (newEnumMoniker == 0)
1630 return STG_E_INSUFFICIENTMEMORY;
1631
1632 if (currentPos > tabSize)
1633 return E_INVALIDARG;
1634
1635 /* Initialize the virtual function table. */
1636 ICOM_VTBL(newEnumMoniker) = &VT_EnumMonikerImpl;
1637 newEnumMoniker->ref = 0;
1638
1639 newEnumMoniker->tabSize = tabSize;
1640 newEnumMoniker->currentPos = currentPos;
1641
1642 newEnumMoniker->tabMoniker =(IMoniker**)HeapAlloc(GetProcessHeap(),0,tabSize*sizeof(IMoniker));
1643
1644 if (newEnumMoniker->tabMoniker==NULL)
1645 return E_OUTOFMEMORY;
1646
1647 if (leftToRigth)
1648 for (i=0;i<tabSize;i++){
1649
1650 newEnumMoniker->tabMoniker[i]=tabMoniker[i];
1651 IMoniker_AddRef(tabMoniker[i]);
1652 }
1653 else
1654 for (i=tabSize-1;i>=0;i--){
1655
1656 newEnumMoniker->tabMoniker[tabSize-i-1]=tabMoniker[i];
1657 IMoniker_AddRef(tabMoniker[i]);
1658 }
1659
1660 *ppmk=(IEnumMoniker*)newEnumMoniker;
1661
1662 return S_OK;
1663}
1664
1665/******************************************************************************
1666 * CreateCompositeMoniker [OLE.55]
1667 ******************************************************************************/
1668HRESULT WINAPI CreateGenericComposite(LPMONIKER pmkFirst, LPMONIKER pmkRest, LPMONIKER* ppmkComposite)
1669{
1670 CompositeMonikerImpl* newCompositeMoniker = 0;
1671 HRESULT hr = S_OK;
1672
1673 TRACE("(%p,%p,%p)\n",pmkFirst,pmkRest,ppmkComposite);
1674
1675 if (ppmkComposite==NULL)
1676 return E_POINTER;
1677
1678 *ppmkComposite=0;
1679
1680 if (pmkFirst==NULL && pmkRest!=NULL){
1681
1682 *ppmkComposite=pmkRest;
1683 return S_OK;
1684 }
1685 else if (pmkFirst!=NULL && pmkRest==NULL){
1686 *ppmkComposite=pmkFirst;
1687 return S_OK;
1688 }
1689 else if (pmkFirst==NULL && pmkRest==NULL)
1690 return S_OK;
1691
1692 newCompositeMoniker = (CompositeMonikerImpl*)HeapAlloc(GetProcessHeap(), 0,sizeof(CompositeMonikerImpl));
1693
1694 if (newCompositeMoniker == 0)
1695 return STG_E_INSUFFICIENTMEMORY;
1696
1697 hr = CompositeMonikerImpl_Construct(newCompositeMoniker,pmkFirst,pmkRest);
1698
1699 if (FAILED(hr)){
1700
1701 HeapFree(GetProcessHeap(),0,newCompositeMoniker);
1702 return hr;
1703 }
1704 if (newCompositeMoniker->tabLastIndex==1)
1705
1706 hr = IMoniker_QueryInterface(newCompositeMoniker->tabMoniker[0],&IID_IMoniker,(void**)ppmkComposite);
1707 else
1708
1709 hr = CompositeMonikerImpl_QueryInterface((IMoniker*)newCompositeMoniker,&IID_IMoniker,(void**)ppmkComposite);
1710
1711 return hr;
1712}
1713
1714/******************************************************************************
1715 * MonikerCommonPrefixWith [OLE.55]
1716 ******************************************************************************/
1717HRESULT WINAPI MonikerCommonPrefixWith(IMoniker* pmkThis,IMoniker* pmkOther,IMoniker** ppmkCommon)
1718{
1719 FIXME("(),stub!\n");
1720 return E_NOTIMPL;
1721}
1722
1723
Note: See TracBrowser for help on using the repository browser.