ReactOS  0.4.13-dev-99-g7e18b6d
compositemoniker.c
Go to the documentation of this file.
1 /*
2  * CompositeMonikers implementation
3  *
4  * Copyright 1999 Noomen Hamza
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  */
20 
21 #include <assert.h>
22 #include <stdarg.h>
23 #include <string.h>
24 
25 #define COBJMACROS
26 
27 #include "windef.h"
28 #include "winbase.h"
29 #include "winuser.h"
30 #include "winerror.h"
31 #include "wine/debug.h"
32 #include "wine/unicode.h"
33 #include "ole2.h"
34 #include "moniker.h"
35 
37 
38 #define BLOCK_TAB_SIZE 5 /* represent the first size table and its increment block size */
39 
40 /* CompositeMoniker data structure */
41 typedef struct CompositeMonikerImpl{
46  IMoniker** tabMoniker; /* dynamic table containing all components (monikers) of this composite moniker */
47  ULONG tabSize; /* size of tabMoniker */
48  ULONG tabLastIndex; /* first free index in tabMoniker */
50 
52 {
53  return CONTAINING_RECORD(iface, CompositeMonikerImpl, IMoniker_iface);
54 }
55 
57 {
58  return CONTAINING_RECORD(iface, CompositeMonikerImpl, IROTData_iface);
59 }
60 
62 {
63  return CONTAINING_RECORD(iface, CompositeMonikerImpl, IMarshal_iface);
64 }
65 
66 /* EnumMoniker data structure */
67 typedef struct EnumMonikerImpl{
69  LONG ref;
70  IMoniker** tabMoniker; /* dynamic table containing the enumerated monikers */
71  ULONG tabSize; /* size of tabMoniker */
72  ULONG currentPos; /* index pointer on the current moniker */
74 
76 {
77  return CONTAINING_RECORD(iface, EnumMonikerImpl, IEnumMoniker_iface);
78 }
79 
80 static HRESULT EnumMonikerImpl_CreateEnumMoniker(IMoniker** tabMoniker,ULONG tabSize,ULONG currentPos,BOOL leftToRight,IEnumMoniker ** ppmk);
81 
82 /*******************************************************************************
83  * CompositeMoniker_QueryInterface
84  *******************************************************************************/
85 static HRESULT WINAPI
87 {
89 
90  TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppvObject);
91 
92  /* Perform a sanity check on the parameters.*/
93  if ( ppvObject==0 )
94  return E_INVALIDARG;
95 
96  /* Initialize the return parameter */
97  *ppvObject = 0;
98 
99  /* Compare the riid with the interface IDs implemented by this object.*/
100  if (IsEqualIID(&IID_IUnknown, riid) ||
103  IsEqualIID(&IID_IMoniker, riid)
104  )
105  *ppvObject = iface;
106  else if (IsEqualIID(&IID_IROTData, riid))
107  *ppvObject = &This->IROTData_iface;
108  else if (IsEqualIID(&IID_IMarshal, riid))
109  *ppvObject = &This->IMarshal_iface;
110 
111  /* Check that we obtained an interface.*/
112  if ((*ppvObject)==0)
113  return E_NOINTERFACE;
114 
115  /* Query Interface always increases the reference count by one when it is successful */
116  IMoniker_AddRef(iface);
117 
118  return S_OK;
119 }
120 
121 /******************************************************************************
122  * CompositeMoniker_AddRef
123  ******************************************************************************/
124 static ULONG WINAPI
126 {
128 
129  TRACE("(%p)\n",This);
130 
131  return InterlockedIncrement(&This->ref);
132 }
133 
135 {
136  ULONG i;
137 
138  for (i = 0; i < This->tabLastIndex; i++)
139  IMoniker_Release(This->tabMoniker[i]);
140 
141  This->tabLastIndex = 0;
142 }
143 
144 /******************************************************************************
145  * CompositeMoniker_Release
146  ******************************************************************************/
147 static ULONG WINAPI
149 {
151  ULONG ref;
152 
153  TRACE("(%p)\n",This);
154 
155  ref = InterlockedDecrement(&This->ref);
156 
157  /* destroy the object if there are no more references to it */
158  if (ref == 0){
159 
160  /* release all the components before destroying this object */
162 
163  HeapFree(GetProcessHeap(),0,This->tabMoniker);
165  }
166  return ref;
167 }
168 
169 /******************************************************************************
170  * CompositeMoniker_GetClassID
171  ******************************************************************************/
172 static HRESULT WINAPI
174 {
175  TRACE("(%p,%p)\n",iface,pClassID);
176 
177  if (pClassID==NULL)
178  return E_POINTER;
179 
180  *pClassID = CLSID_CompositeMoniker;
181 
182  return S_OK;
183 }
184 
185 /******************************************************************************
186  * CompositeMoniker_IsDirty
187  ******************************************************************************/
188 static HRESULT WINAPI
190 {
191  /* Note that the OLE-provided implementations of the IPersistStream::IsDirty
192  method in the OLE-provided moniker interfaces always return S_FALSE because
193  their internal state never changes. */
194 
195  TRACE("(%p)\n",iface);
196 
197  return S_FALSE;
198 }
199 
200 /******************************************************************************
201  * CompositeMoniker_Load
202  ******************************************************************************/
203 static HRESULT WINAPI
205 {
207  HRESULT res;
208  DWORD moniker_count;
209  DWORD i;
210 
211  TRACE("(%p,%p)\n",iface,pStm);
212 
213  /* this function call OleLoadFromStream function for each moniker within this object */
214 
215  res=IStream_Read(pStm,&moniker_count,sizeof(DWORD),NULL);
216  if (res != S_OK)
217  {
218  ERR("couldn't reading moniker count from stream\n");
219  return E_FAIL;
220  }
221 
223 
224  for (i = 0; i < moniker_count; i++)
225  {
226  res=OleLoadFromStream(pStm,&IID_IMoniker,(void**)&This->tabMoniker[This->tabLastIndex]);
227  if (FAILED(res))
228  {
229  ERR("couldn't load moniker from stream, res = 0x%08x\n", res);
230  break;
231  }
232 
233  /* resize the table if needed */
234  if (++This->tabLastIndex==This->tabSize){
235 
236  This->tabSize+=BLOCK_TAB_SIZE;
237  This->tabMoniker=HeapReAlloc(GetProcessHeap(),0,This->tabMoniker,This->tabSize*sizeof(This->tabMoniker[0]));
238 
239  if (This->tabMoniker==NULL)
240  return E_OUTOFMEMORY;
241  }
242  }
243 
244  return res;
245 }
246 
247 /******************************************************************************
248  * CompositeMoniker_Save
249  ******************************************************************************/
250 static HRESULT WINAPI
252 {
254  HRESULT res;
255  IEnumMoniker *enumMk;
256  IMoniker *pmk;
257  DWORD moniker_count = This->tabLastIndex;
258 
259  TRACE("(%p,%p,%d)\n",iface,pStm,fClearDirty);
260 
261  /* This function calls OleSaveToStream function for each moniker within
262  * this object.
263  * When I tested this function in windows, I usually found this constant
264  * at the beginning of the stream. I don't known why (there's no
265  * indication in the specification) !
266  */
267  res=IStream_Write(pStm,&moniker_count,sizeof(moniker_count),NULL);
268  if (FAILED(res)) return res;
269 
270  IMoniker_Enum(iface,TRUE,&enumMk);
271 
272  while(IEnumMoniker_Next(enumMk,1,&pmk,NULL)==S_OK){
273 
274  res=OleSaveToStream((IPersistStream*)pmk,pStm);
275 
276  IMoniker_Release(pmk);
277 
278  if (FAILED(res)){
279 
280  IEnumMoniker_Release(enumMk);
281  return res;
282  }
283  }
284 
285  IEnumMoniker_Release(enumMk);
286 
287  return S_OK;
288 }
289 
290 /******************************************************************************
291  * CompositeMoniker_GetSizeMax
292  ******************************************************************************/
293 static HRESULT WINAPI
295 {
296  IEnumMoniker *enumMk;
297  IMoniker *pmk;
298  ULARGE_INTEGER ptmpSize;
299 
300  /* The sizeMax of this object is calculated by calling GetSizeMax on
301  * each moniker within this object then summing all returned values
302  */
303 
304  TRACE("(%p,%p)\n",iface,pcbSize);
305 
306  if (!pcbSize)
307  return E_POINTER;
308 
309  pcbSize->QuadPart = sizeof(DWORD);
310 
311  IMoniker_Enum(iface,TRUE,&enumMk);
312 
313  while(IEnumMoniker_Next(enumMk,1,&pmk,NULL)==S_OK){
314 
315  IMoniker_GetSizeMax(pmk,&ptmpSize);
316 
317  IMoniker_Release(pmk);
318 
319  pcbSize->QuadPart = ptmpSize.QuadPart + sizeof(CLSID);
320  }
321 
322  IEnumMoniker_Release(enumMk);
323 
324  return S_OK;
325 }
326 
327 /******************************************************************************
328  * CompositeMoniker_BindToObject
329  ******************************************************************************/
330 static HRESULT WINAPI
332  IMoniker* pmkToLeft, REFIID riid, VOID** ppvResult)
333 {
334  HRESULT res;
335  IRunningObjectTable *prot;
336  IMoniker *tempMk,*antiMk,*rightMostMk;
337  IEnumMoniker *enumMoniker;
338 
339  TRACE("(%p,%p,%p,%s,%p)\n",iface,pbc,pmkToLeft,debugstr_guid(riid),ppvResult);
340 
341  if (ppvResult==NULL)
342  return E_POINTER;
343 
344  *ppvResult=0;
345  /* If pmkToLeft is NULL, this method looks for the moniker in the ROT, and if found, queries the retrieved */
346  /* object for the requested interface pointer. */
347  if(pmkToLeft==NULL){
348 
349  res=IBindCtx_GetRunningObjectTable(pbc,&prot);
350 
351  if (SUCCEEDED(res)){
352 
353  /* if the requested class was loaded before ! we don't need to reload it */
354  res = IRunningObjectTable_GetObject(prot,iface,(IUnknown**)ppvResult);
355 
356  if (res==S_OK)
357  return res;
358  }
359  }
360  else{
361  /* If pmkToLeft is not NULL, the method recursively calls IMoniker::BindToObject on the rightmost */
362  /* component of the composite, passing the rest of the composite as the pmkToLeft parameter for that call */
363 
364  IMoniker_Enum(iface,FALSE,&enumMoniker);
365  IEnumMoniker_Next(enumMoniker,1,&rightMostMk,NULL);
366  IEnumMoniker_Release(enumMoniker);
367 
368  res=CreateAntiMoniker(&antiMk);
369  res=IMoniker_ComposeWith(iface,antiMk,0,&tempMk);
370  IMoniker_Release(antiMk);
371 
372  res=IMoniker_BindToObject(rightMostMk,pbc,tempMk,riid,ppvResult);
373 
374  IMoniker_Release(tempMk);
375  IMoniker_Release(rightMostMk);
376  }
377 
378  return res;
379 }
380 
381 /******************************************************************************
382  * CompositeMoniker_BindToStorage
383  ******************************************************************************/
384 static HRESULT WINAPI
386  IMoniker* pmkToLeft, REFIID riid, VOID** ppvResult)
387 {
388  HRESULT res;
389  IMoniker *tempMk,*antiMk,*rightMostMk,*leftMk;
390  IEnumMoniker *enumMoniker;
391 
392  TRACE("(%p,%p,%p,%s,%p)\n",iface,pbc,pmkToLeft,debugstr_guid(riid),ppvResult);
393 
394  *ppvResult=0;
395 
396  /* This method recursively calls BindToStorage on the rightmost component of the composite, */
397  /* passing the rest of the composite as the pmkToLeft parameter for that call. */
398 
399  if (pmkToLeft)
400  {
401  res = IMoniker_ComposeWith(pmkToLeft, iface, FALSE, &leftMk);
402  if (FAILED(res)) return res;
403  }
404  else
405  leftMk = iface;
406 
407  IMoniker_Enum(iface, FALSE, &enumMoniker);
408  IEnumMoniker_Next(enumMoniker, 1, &rightMostMk, NULL);
409  IEnumMoniker_Release(enumMoniker);
410 
411  res = CreateAntiMoniker(&antiMk);
412  if (FAILED(res)) return res;
413  res = IMoniker_ComposeWith(leftMk, antiMk, 0, &tempMk);
414  if (FAILED(res)) return res;
415  IMoniker_Release(antiMk);
416 
417  res = IMoniker_BindToStorage(rightMostMk, pbc, tempMk, riid, ppvResult);
418 
419  IMoniker_Release(tempMk);
420 
421  IMoniker_Release(rightMostMk);
422 
423  if (pmkToLeft)
424  IMoniker_Release(leftMk);
425 
426  return res;
427 }
428 
429 /******************************************************************************
430  * CompositeMoniker_Reduce
431  ******************************************************************************/
432 static HRESULT WINAPI
433 CompositeMonikerImpl_Reduce(IMoniker* iface, IBindCtx* pbc, DWORD dwReduceHowFar,
434  IMoniker** ppmkToLeft, IMoniker** ppmkReduced)
435 {
436  IMoniker *tempMk,*antiMk,*rightMostMk,*leftReducedComposedMk,*rightMostReducedMk;
437  IEnumMoniker *enumMoniker;
438 
439  TRACE("(%p,%p,%d,%p,%p)\n",iface,pbc,dwReduceHowFar,ppmkToLeft,ppmkReduced);
440 
441  if (ppmkReduced==NULL)
442  return E_POINTER;
443 
444  /* This method recursively calls Reduce for each of its component monikers. */
445 
446  if (ppmkToLeft==NULL){
447 
448  IMoniker_Enum(iface,FALSE,&enumMoniker);
449  IEnumMoniker_Next(enumMoniker,1,&rightMostMk,NULL);
450  IEnumMoniker_Release(enumMoniker);
451 
452  CreateAntiMoniker(&antiMk);
453  IMoniker_ComposeWith(iface,antiMk,0,&tempMk);
454  IMoniker_Release(antiMk);
455 
456  return IMoniker_Reduce(rightMostMk,pbc,dwReduceHowFar,&tempMk, ppmkReduced);
457  }
458  else if (*ppmkToLeft==NULL)
459 
460  return IMoniker_Reduce(iface,pbc,dwReduceHowFar,NULL,ppmkReduced);
461 
462  else{
463 
464  /* separate the composite moniker in to left and right moniker */
465  IMoniker_Enum(iface,FALSE,&enumMoniker);
466  IEnumMoniker_Next(enumMoniker,1,&rightMostMk,NULL);
467  IEnumMoniker_Release(enumMoniker);
468 
469  CreateAntiMoniker(&antiMk);
470  IMoniker_ComposeWith(iface,antiMk,0,&tempMk);
471  IMoniker_Release(antiMk);
472 
473  /* If any of the components reduces itself, the method returns S_OK and passes back a composite */
474  /* of the reduced components */
475  if (IMoniker_Reduce(rightMostMk,pbc,dwReduceHowFar,NULL,&rightMostReducedMk) &&
476  IMoniker_Reduce(rightMostMk,pbc,dwReduceHowFar,&tempMk,&leftReducedComposedMk)
477  )
478 
479  return CreateGenericComposite(leftReducedComposedMk,rightMostReducedMk,ppmkReduced);
480 
481  else{
482  /* If no reduction occurred, the method passes back the same moniker and returns MK_S_REDUCED_TO_SELF.*/
483 
484  IMoniker_AddRef(iface);
485 
486  *ppmkReduced=iface;
487 
488  return MK_S_REDUCED_TO_SELF;
489  }
490  }
491 }
492 
493 /******************************************************************************
494  * CompositeMoniker_ComposeWith
495  ******************************************************************************/
496 static HRESULT WINAPI
498  BOOL fOnlyIfNotGeneric, IMoniker** ppmkComposite)
499 {
500  TRACE("(%p,%p,%d,%p)\n",iface,pmkRight,fOnlyIfNotGeneric,ppmkComposite);
501 
502  if ((ppmkComposite==NULL)||(pmkRight==NULL))
503  return E_POINTER;
504 
505  *ppmkComposite=0;
506 
507  /* If fOnlyIfNotGeneric is TRUE, this method sets *pmkComposite to NULL and returns MK_E_NEEDGENERIC; */
508  /* otherwise, the method returns the result of combining the two monikers by calling the */
509  /* CreateGenericComposite function */
510 
511  if (fOnlyIfNotGeneric)
512  return MK_E_NEEDGENERIC;
513 
514  return CreateGenericComposite(iface,pmkRight,ppmkComposite);
515 }
516 
517 /******************************************************************************
518  * CompositeMoniker_Enum
519  ******************************************************************************/
520 static HRESULT WINAPI
521 CompositeMonikerImpl_Enum(IMoniker* iface,BOOL fForward, IEnumMoniker** ppenumMoniker)
522 {
524 
525  TRACE("(%p,%d,%p)\n",iface,fForward,ppenumMoniker);
526 
527  if (ppenumMoniker == NULL)
528  return E_POINTER;
529 
530  return EnumMonikerImpl_CreateEnumMoniker(This->tabMoniker,This->tabLastIndex,0,fForward,ppenumMoniker);
531 }
532 
533 /******************************************************************************
534  * CompositeMoniker_IsEqual
535  ******************************************************************************/
536 static HRESULT WINAPI
538 {
539  IEnumMoniker *enumMoniker1,*enumMoniker2;
540  IMoniker *tempMk1,*tempMk2;
541  HRESULT res1,res2,res;
542  BOOL done;
543 
544  TRACE("(%p,%p)\n",iface,pmkOtherMoniker);
545 
546  if (pmkOtherMoniker==NULL)
547  return S_FALSE;
548 
549  /* This method returns S_OK if the components of both monikers are equal when compared in the */
550  /* left-to-right order.*/
551  IMoniker_Enum(pmkOtherMoniker,TRUE,&enumMoniker1);
552 
553  if (enumMoniker1==NULL)
554  return S_FALSE;
555 
556  IMoniker_Enum(iface,TRUE,&enumMoniker2);
557 
558  do {
559 
560  res1=IEnumMoniker_Next(enumMoniker1,1,&tempMk1,NULL);
561  res2=IEnumMoniker_Next(enumMoniker2,1,&tempMk2,NULL);
562 
563  if((res1==S_OK)&&(res2==S_OK)){
564  done = (res = IMoniker_IsEqual(tempMk1,tempMk2)) == S_FALSE;
565  }
566  else
567  {
568  res = (res1==S_FALSE) && (res2==S_FALSE);
569  done = TRUE;
570  }
571 
572  if (res1==S_OK)
573  IMoniker_Release(tempMk1);
574 
575  if (res2==S_OK)
576  IMoniker_Release(tempMk2);
577  } while (!done);
578 
579  IEnumMoniker_Release(enumMoniker1);
580  IEnumMoniker_Release(enumMoniker2);
581 
582  return res;
583 }
584 /******************************************************************************
585  * CompositeMoniker_Hash
586  ******************************************************************************/
587 static HRESULT WINAPI
589 {
590  IEnumMoniker *enumMoniker;
591  IMoniker *tempMk;
592  HRESULT res;
593  DWORD tempHash;
594 
595  TRACE("(%p,%p)\n",iface,pdwHash);
596 
597  if (pdwHash==NULL)
598  return E_POINTER;
599 
600  res = IMoniker_Enum(iface,TRUE,&enumMoniker);
601  if(FAILED(res))
602  return res;
603 
604  *pdwHash = 0;
605 
606  while(IEnumMoniker_Next(enumMoniker,1,&tempMk,NULL)==S_OK){
607  res = IMoniker_Hash(tempMk, &tempHash);
608  if(FAILED(res))
609  break;
610  *pdwHash = *pdwHash ^ tempHash;
611 
612  IMoniker_Release(tempMk);
613  }
614 
615  IEnumMoniker_Release(enumMoniker);
616 
617  return res;
618 }
619 
620 /******************************************************************************
621  * CompositeMoniker_IsRunning
622  ******************************************************************************/
623 static HRESULT WINAPI
625  IMoniker* pmkToLeft, IMoniker* pmkNewlyRunning)
626 {
628  HRESULT res;
629  IMoniker *tempMk,*antiMk,*rightMostMk;
630  IEnumMoniker *enumMoniker;
631 
632  TRACE("(%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,pmkNewlyRunning);
633 
634  /* If pmkToLeft is non-NULL, this method composes pmkToLeft with this moniker and calls IsRunning on the result.*/
635  if (pmkToLeft!=NULL){
636 
637  CreateGenericComposite(pmkToLeft,iface,&tempMk);
638 
639  res = IMoniker_IsRunning(tempMk,pbc,NULL,pmkNewlyRunning);
640 
641  IMoniker_Release(tempMk);
642 
643  return res;
644  }
645  else
646  /* If pmkToLeft is NULL, this method returns S_OK if pmkNewlyRunning is non-NULL and is equal */
647  /* to this moniker */
648 
649  if (pmkNewlyRunning!=NULL)
650 
651  if (IMoniker_IsEqual(iface,pmkNewlyRunning)==S_OK)
652  return S_OK;
653 
654  else
655  return S_FALSE;
656 
657  else{
658 
659  if (pbc==NULL)
660  return E_INVALIDARG;
661 
662  /* If pmkToLeft and pmkNewlyRunning are both NULL, this method checks the ROT to see whether */
663  /* the moniker is running. If so, the method returns S_OK; otherwise, it recursively calls */
664  /* IMoniker::IsRunning on the rightmost component of the composite, passing the remainder of */
665  /* the composite as the pmkToLeft parameter for that call. */
666 
667  res=IBindCtx_GetRunningObjectTable(pbc,&rot);
668 
669  if (FAILED(res))
670  return res;
671 
672  res = IRunningObjectTable_IsRunning(rot,iface);
673  IRunningObjectTable_Release(rot);
674 
675  if(res==S_OK)
676  return S_OK;
677 
678  else{
679 
680  IMoniker_Enum(iface,FALSE,&enumMoniker);
681  IEnumMoniker_Next(enumMoniker,1,&rightMostMk,NULL);
682  IEnumMoniker_Release(enumMoniker);
683 
684  res=CreateAntiMoniker(&antiMk);
685  res=IMoniker_ComposeWith(iface,antiMk,0,&tempMk);
686  IMoniker_Release(antiMk);
687 
688  res=IMoniker_IsRunning(rightMostMk,pbc,tempMk,pmkNewlyRunning);
689 
690  IMoniker_Release(tempMk);
691  IMoniker_Release(rightMostMk);
692 
693  return res;
694  }
695  }
696 }
697 
698 /******************************************************************************
699  * CompositeMoniker_GetTimeOfLastChange
700  ******************************************************************************/
701 static HRESULT WINAPI
703  IMoniker* pmkToLeft, FILETIME* pCompositeTime)
704 {
705  HRESULT res;
706  IMoniker *tempMk,*antiMk,*rightMostMk,*leftMk;
707  IEnumMoniker *enumMoniker;
708 
709  TRACE("(%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,pCompositeTime);
710 
711  if (pCompositeTime==NULL)
712  return E_INVALIDARG;
713 
714  /* This method creates a composite of pmkToLeft (if non-NULL) and this moniker and uses the ROT to */
715  /* retrieve the time of last change. If the object is not in the ROT, the method recursively calls */
716  /* IMoniker::GetTimeOfLastChange on the rightmost component of the composite, passing the remainder */
717  /* of the composite as the pmkToLeft parameter for that call. */
718  if (pmkToLeft)
719  {
721 
722  res = IMoniker_ComposeWith(pmkToLeft, iface, FALSE, &leftMk);
723  if (FAILED(res))
724  return res;
725 
726  res = IBindCtx_GetRunningObjectTable(pbc,&rot);
727  if (FAILED(res))
728  {
729  IMoniker_Release(leftMk);
730  return res;
731  }
732 
733  if (IRunningObjectTable_GetTimeOfLastChange(rot,leftMk,pCompositeTime)==S_OK)
734  {
735  IMoniker_Release(leftMk);
736  return res;
737  }
738  }
739  else
740  leftMk = iface;
741 
742  IMoniker_Enum(iface, FALSE, &enumMoniker);
743  IEnumMoniker_Next(enumMoniker, 1, &rightMostMk, NULL);
744  IEnumMoniker_Release(enumMoniker);
745 
746  res = CreateAntiMoniker(&antiMk);
747  res = IMoniker_ComposeWith(leftMk, antiMk, 0, &tempMk);
748  IMoniker_Release(antiMk);
749 
750  res = IMoniker_GetTimeOfLastChange(rightMostMk, pbc, tempMk, pCompositeTime);
751 
752  IMoniker_Release(tempMk);
753  IMoniker_Release(rightMostMk);
754 
755  if (pmkToLeft)
756  IMoniker_Release(leftMk);
757 
758  return res;
759 }
760 
761 /******************************************************************************
762  * CompositeMoniker_Inverse
763  ******************************************************************************/
764 static HRESULT WINAPI
766 {
767  HRESULT res;
768  IMoniker *tempMk,*antiMk,*rightMostMk,*tempInvMk,*rightMostInvMk;
769  IEnumMoniker *enumMoniker;
770 
771  TRACE("(%p,%p)\n",iface,ppmk);
772 
773  if (ppmk==NULL)
774  return E_POINTER;
775 
776  /* This method returns a composite moniker that consists of the inverses of each of the components */
777  /* of the original composite, stored in reverse order */
778 
779  *ppmk = NULL;
780 
781  res=CreateAntiMoniker(&antiMk);
782  if (FAILED(res))
783  return res;
784 
785  res=IMoniker_ComposeWith(iface,antiMk,FALSE,&tempMk);
786  IMoniker_Release(antiMk);
787  if (FAILED(res))
788  return res;
789 
790  if (tempMk==NULL)
791 
792  return IMoniker_Inverse(iface,ppmk);
793 
794  else{
795 
796  IMoniker_Enum(iface,FALSE,&enumMoniker);
797  IEnumMoniker_Next(enumMoniker,1,&rightMostMk,NULL);
798  IEnumMoniker_Release(enumMoniker);
799 
800  IMoniker_Inverse(rightMostMk,&rightMostInvMk);
801  CompositeMonikerImpl_Inverse(tempMk,&tempInvMk);
802 
803  res=CreateGenericComposite(rightMostInvMk,tempInvMk,ppmk);
804 
805  IMoniker_Release(tempMk);
806  IMoniker_Release(rightMostMk);
807  IMoniker_Release(tempInvMk);
808  IMoniker_Release(rightMostInvMk);
809 
810  return res;
811  }
812 }
813 
814 /******************************************************************************
815  * CompositeMoniker_CommonPrefixWith
816  ******************************************************************************/
817 static HRESULT WINAPI
819  IMoniker** ppmkPrefix)
820 {
821  DWORD mkSys;
822  HRESULT res1,res2;
823  IMoniker *tempMk1,*tempMk2,*mostLeftMk1,*mostLeftMk2;
824  IEnumMoniker *enumMoniker1,*enumMoniker2;
825  ULONG i,nbCommonMk=0;
826 
827  /* If the other moniker is a composite, this method compares the components of each composite from left */
828  /* to right. The returned common prefix moniker might also be a composite moniker, depending on how many */
829  /* of the leftmost components were common to both monikers. */
830 
831  if (ppmkPrefix==NULL)
832  return E_POINTER;
833 
834  *ppmkPrefix=0;
835 
836  if (pmkOther==NULL)
837  return MK_E_NOPREFIX;
838 
839  IMoniker_IsSystemMoniker(pmkOther,&mkSys);
840 
841  if(mkSys==MKSYS_GENERICCOMPOSITE){
842 
843  IMoniker_Enum(iface,TRUE,&enumMoniker1);
844  IMoniker_Enum(pmkOther,TRUE,&enumMoniker2);
845 
846  while(1){
847 
848  res1=IEnumMoniker_Next(enumMoniker1,1,&mostLeftMk1,NULL);
849  res2=IEnumMoniker_Next(enumMoniker2,1,&mostLeftMk2,NULL);
850 
851  if ((res1==S_FALSE) && (res2==S_FALSE)){
852 
853  /* If the monikers are equal, the method returns MK_S_US and sets ppmkPrefix to this moniker.*/
854  *ppmkPrefix=iface;
855  IMoniker_AddRef(iface);
856  return MK_S_US;
857  }
858  else if ((res1==S_OK) && (res2==S_OK)){
859 
860  if (IMoniker_IsEqual(mostLeftMk1,mostLeftMk2)==S_OK)
861 
862  nbCommonMk++;
863 
864  else
865  break;
866 
867  }
868  else if (res1==S_OK){
869 
870  /* If the other moniker is a prefix of this moniker, the method returns MK_S_HIM and sets */
871  /* ppmkPrefix to the other moniker. */
872  *ppmkPrefix=pmkOther;
873  return MK_S_HIM;
874  }
875  else{
876  /* If this moniker is a prefix of the other, this method returns MK_S_ME and sets ppmkPrefix */
877  /* to this moniker. */
878  *ppmkPrefix=iface;
879  return MK_S_ME;
880  }
881  }
882 
883  IEnumMoniker_Release(enumMoniker1);
884  IEnumMoniker_Release(enumMoniker2);
885 
886  /* If there is no common prefix, this method returns MK_E_NOPREFIX and sets ppmkPrefix to NULL. */
887  if (nbCommonMk==0)
888  return MK_E_NOPREFIX;
889 
890  IEnumMoniker_Reset(enumMoniker1);
891 
892  IEnumMoniker_Next(enumMoniker1,1,&tempMk1,NULL);
893 
894  /* if we have more than one common moniker the result will be a composite moniker */
895  if (nbCommonMk>1){
896 
897  /* initialize the common prefix moniker with the composite of two first moniker (from the left)*/
898  IEnumMoniker_Next(enumMoniker1,1,&tempMk2,NULL);
899  CreateGenericComposite(tempMk1,tempMk2,ppmkPrefix);
900  IMoniker_Release(tempMk1);
901  IMoniker_Release(tempMk2);
902 
903  /* compose all common monikers in a composite moniker */
904  for(i=0;i<nbCommonMk;i++){
905 
906  IEnumMoniker_Next(enumMoniker1,1,&tempMk1,NULL);
907 
908  CreateGenericComposite(*ppmkPrefix,tempMk1,&tempMk2);
909 
910  IMoniker_Release(*ppmkPrefix);
911 
912  IMoniker_Release(tempMk1);
913 
914  *ppmkPrefix=tempMk2;
915  }
916  return S_OK;
917  }
918  else{
919  /* if we have only one common moniker the result will be a simple moniker which is the most-left one*/
920  *ppmkPrefix=tempMk1;
921 
922  return S_OK;
923  }
924  }
925  else{
926  /* If the other moniker is not a composite, the method simply compares it to the leftmost component
927  of this moniker.*/
928 
929  IMoniker_Enum(iface,TRUE,&enumMoniker1);
930 
931  IEnumMoniker_Next(enumMoniker1,1,&mostLeftMk1,NULL);
932 
933  if (IMoniker_IsEqual(pmkOther,mostLeftMk1)==S_OK){
934 
935  *ppmkPrefix=pmkOther;
936 
937  return MK_S_HIM;
938  }
939  else
940  return MK_E_NOPREFIX;
941  }
942 }
943 
944 /***************************************************************************************************
945  * GetAfterCommonPrefix (local function)
946  * This function returns a moniker that consist of the remainder when the common prefix is removed
947  ***************************************************************************************************/
948 static VOID GetAfterCommonPrefix(IMoniker* pGenMk,IMoniker* commonMk,IMoniker** restMk)
949 {
950  IMoniker *tempMk,*tempMk1,*tempMk2;
951  IEnumMoniker *enumMoniker1,*enumMoniker2,*enumMoniker3;
952  ULONG nbRestMk=0;
953  DWORD mkSys;
954  HRESULT res1,res2;
955 
956  *restMk=0;
957 
958  /* to create an enumerator for pGenMk with current position pointed on the first element after common */
959  /* prefix: enum the two monikers (left-right) then compare these enumerations (left-right) and stop */
960  /* on the first difference. */
961  IMoniker_Enum(pGenMk,TRUE,&enumMoniker1);
962 
963  IMoniker_IsSystemMoniker(commonMk,&mkSys);
964 
965  if (mkSys==MKSYS_GENERICCOMPOSITE){
966 
967  IMoniker_Enum(commonMk,TRUE,&enumMoniker2);
968  while(1){
969 
970  res1=IEnumMoniker_Next(enumMoniker1,1,&tempMk1,NULL);
971  res2=IEnumMoniker_Next(enumMoniker2,1,&tempMk2,NULL);
972 
973  if ((res1==S_FALSE)||(res2==S_FALSE)){
974 
975  if (res1==S_OK)
976 
977  nbRestMk++;
978 
979  IMoniker_Release(tempMk1);
980  IMoniker_Release(tempMk2);
981 
982  break;
983  }
984  IMoniker_Release(tempMk1);
985  IMoniker_Release(tempMk2);
986  }
987  }
988  else{
989  IEnumMoniker_Next(enumMoniker1,1,&tempMk1,NULL);
990  IMoniker_Release(tempMk1);
991  }
992 
993  /* count the number of elements in the enumerator after the common prefix */
994  IEnumMoniker_Clone(enumMoniker1,&enumMoniker3);
995 
996  for(;IEnumMoniker_Next(enumMoniker3,1,&tempMk,NULL)==S_OK;nbRestMk++)
997 
998  IMoniker_Release(tempMk);
999 
1000  if (nbRestMk==0)
1001  return;
1002 
1003  /* create a generic composite moniker with monikers located after the common prefix */
1004  IEnumMoniker_Next(enumMoniker1,1,&tempMk1,NULL);
1005 
1006  if (nbRestMk==1){
1007 
1008  *restMk= tempMk1;
1009  return;
1010  }
1011  else {
1012 
1013  IEnumMoniker_Next(enumMoniker1,1,&tempMk2,NULL);
1014 
1015  CreateGenericComposite(tempMk1,tempMk2,restMk);
1016 
1017  IMoniker_Release(tempMk1);
1018 
1019  IMoniker_Release(tempMk2);
1020 
1021  while(IEnumMoniker_Next(enumMoniker1,1,&tempMk1,NULL)==S_OK){
1022 
1023  CreateGenericComposite(*restMk,tempMk1,&tempMk2);
1024 
1025  IMoniker_Release(tempMk1);
1026 
1027  IMoniker_Release(*restMk);
1028 
1029  *restMk=tempMk2;
1030  }
1031  }
1032 }
1033 
1034 /******************************************************************************
1035  * CompositeMoniker_RelativePathTo
1036  ******************************************************************************/
1037 static HRESULT WINAPI
1039  IMoniker** ppmkRelPath)
1040 {
1041  HRESULT res;
1042  IMoniker *restOtherMk=0,*restThisMk=0,*invRestThisMk=0,*commonMk=0;
1043 
1044  TRACE("(%p,%p,%p)\n",iface,pmkOther,ppmkRelPath);
1045 
1046  if (ppmkRelPath==NULL)
1047  return E_POINTER;
1048 
1049  *ppmkRelPath=0;
1050 
1051  /* This method finds the common prefix of the two monikers and creates two monikers that consist */
1052  /* of the remainder when the common prefix is removed. Then it creates the inverse for the remainder */
1053  /* of this moniker and composes the remainder of the other moniker on the right of it. */
1054 
1055  /* finds the common prefix of the two monikers */
1056  res=IMoniker_CommonPrefixWith(iface,pmkOther,&commonMk);
1057 
1058  /* if there's no common prefix or the two moniker are equal the relative is the other moniker */
1059  if ((res== MK_E_NOPREFIX)||(res==MK_S_US)){
1060 
1061  *ppmkRelPath=pmkOther;
1062  IMoniker_AddRef(pmkOther);
1063  return MK_S_HIM;
1064  }
1065 
1066  GetAfterCommonPrefix(iface,commonMk,&restThisMk);
1067  GetAfterCommonPrefix(pmkOther,commonMk,&restOtherMk);
1068 
1069  /* if other is a prefix of this moniker the relative path is the inverse of the remainder path of this */
1070  /* moniker when the common prefix is removed */
1071  if (res==MK_S_HIM){
1072 
1073  IMoniker_Inverse(restThisMk,ppmkRelPath);
1074  IMoniker_Release(restThisMk);
1075  }
1076  /* if this moniker is a prefix of other moniker the relative path is the remainder path of other moniker */
1077  /* when the common prefix is removed */
1078  else if (res==MK_S_ME){
1079 
1080  *ppmkRelPath=restOtherMk;
1081  IMoniker_AddRef(restOtherMk);
1082  }
1083  /* the relative path is the inverse for the remainder of this moniker and the remainder of the other */
1084  /* moniker on the right of it. */
1085  else if (res==S_OK){
1086 
1087  IMoniker_Inverse(restThisMk,&invRestThisMk);
1088  IMoniker_Release(restThisMk);
1089  CreateGenericComposite(invRestThisMk,restOtherMk,ppmkRelPath);
1090  IMoniker_Release(invRestThisMk);
1091  IMoniker_Release(restOtherMk);
1092  }
1093  return S_OK;
1094 }
1095 
1096 /******************************************************************************
1097  * CompositeMoniker_GetDisplayName
1098  ******************************************************************************/
1099 static HRESULT WINAPI
1101  IMoniker* pmkToLeft, LPOLESTR *ppszDisplayName)
1102 {
1103  ULONG lengthStr=1;
1104  IEnumMoniker *enumMoniker;
1105  IMoniker* tempMk;
1106  LPOLESTR tempStr;
1107 
1108  TRACE("(%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,ppszDisplayName);
1109 
1110  if (ppszDisplayName==NULL)
1111  return E_POINTER;
1112 
1113  *ppszDisplayName=CoTaskMemAlloc(sizeof(WCHAR));
1114 
1115  if (*ppszDisplayName==NULL)
1116  return E_OUTOFMEMORY;
1117 
1118  /* This method returns the concatenation of the display names returned by each component moniker of */
1119  /* the composite */
1120 
1121  **ppszDisplayName=0;
1122 
1123  IMoniker_Enum(iface,TRUE,&enumMoniker);
1124 
1125  while(IEnumMoniker_Next(enumMoniker,1,&tempMk,NULL)==S_OK){
1126 
1127  IMoniker_GetDisplayName(tempMk,pbc,NULL,&tempStr);
1128 
1129  lengthStr+=lstrlenW(tempStr);
1130 
1131  *ppszDisplayName=CoTaskMemRealloc(*ppszDisplayName,lengthStr * sizeof(WCHAR));
1132 
1133  if (*ppszDisplayName==NULL)
1134  return E_OUTOFMEMORY;
1135 
1136  strcatW(*ppszDisplayName,tempStr);
1137 
1138  CoTaskMemFree(tempStr);
1139  IMoniker_Release(tempMk);
1140  }
1141 
1142  IEnumMoniker_Release(enumMoniker);
1143 
1144  return S_OK;
1145 }
1146 
1147 /******************************************************************************
1148  * CompositeMoniker_ParseDisplayName
1149  ******************************************************************************/
1150 static HRESULT WINAPI
1152  IMoniker* pmkToLeft, LPOLESTR pszDisplayName, ULONG* pchEaten,
1153  IMoniker** ppmkOut)
1154 {
1155  IEnumMoniker *enumMoniker;
1156  IMoniker *tempMk,*rightMostMk,*antiMk;
1157  /* This method recursively calls IMoniker::ParseDisplayName on the rightmost component of the composite,*/
1158  /* passing everything else as the pmkToLeft parameter for that call. */
1159 
1160  /* get the most right moniker */
1161  IMoniker_Enum(iface,FALSE,&enumMoniker);
1162  IEnumMoniker_Next(enumMoniker,1,&rightMostMk,NULL);
1163  IEnumMoniker_Release(enumMoniker);
1164 
1165  /* get the left moniker */
1166  CreateAntiMoniker(&antiMk);
1167  IMoniker_ComposeWith(iface,antiMk,0,&tempMk);
1168  IMoniker_Release(antiMk);
1169 
1170  return IMoniker_ParseDisplayName(rightMostMk,pbc,tempMk,pszDisplayName,pchEaten,ppmkOut);
1171 }
1172 
1173 /******************************************************************************
1174  * CompositeMoniker_IsSystemMoniker
1175  ******************************************************************************/
1176 static HRESULT WINAPI
1178 {
1179  TRACE("(%p,%p)\n",iface,pwdMksys);
1180 
1181  if (!pwdMksys)
1182  return E_POINTER;
1183 
1184  (*pwdMksys)=MKSYS_GENERICCOMPOSITE;
1185 
1186  return S_OK;
1187 }
1188 
1189 /*******************************************************************************
1190  * CompositeMonikerIROTData_QueryInterface
1191  *******************************************************************************/
1192 static HRESULT WINAPI
1194  VOID** ppvObject)
1195 {
1197 
1198  TRACE("(%p,%s,%p)\n",iface,debugstr_guid(riid),ppvObject);
1199 
1200  return CompositeMonikerImpl_QueryInterface(&This->IMoniker_iface, riid, ppvObject);
1201 }
1202 
1203 /***********************************************************************
1204  * CompositeMonikerIROTData_AddRef
1205  */
1206 static ULONG WINAPI
1208 {
1210 
1211  TRACE("(%p)\n",iface);
1212 
1213  return IMoniker_AddRef(&This->IMoniker_iface);
1214 }
1215 
1216 /***********************************************************************
1217  * CompositeMonikerIROTData_Release
1218  */
1220 {
1222 
1223  TRACE("(%p)\n",iface);
1224 
1225  return IMoniker_Release(&This->IMoniker_iface);
1226 }
1227 
1228 /******************************************************************************
1229  * CompositeMonikerIROTData_GetComparisonData
1230  ******************************************************************************/
1231 static HRESULT WINAPI
1233  BYTE* pbData, ULONG cbMax, ULONG* pcbData)
1234 {
1236  IEnumMoniker *pEnumMk;
1237  IMoniker *pmk;
1238  HRESULT hr;
1239 
1240  TRACE("(%p, %u, %p)\n", pbData, cbMax, pcbData);
1241 
1242  *pcbData = sizeof(CLSID);
1243 
1244  hr = IMoniker_Enum(&This->IMoniker_iface, TRUE, &pEnumMk);
1245  if (FAILED(hr)) return hr;
1246 
1247  while(IEnumMoniker_Next(pEnumMk, 1, &pmk, NULL) == S_OK)
1248  {
1249  IROTData *pROTData;
1250  hr = IMoniker_QueryInterface(pmk, &IID_IROTData, (void **)&pROTData);
1251  if (FAILED(hr))
1252  ERR("moniker doesn't support IROTData interface\n");
1253 
1254  if (SUCCEEDED(hr))
1255  {
1256  ULONG cbData;
1257  hr = IROTData_GetComparisonData(pROTData, NULL, 0, &cbData);
1258  IROTData_Release(pROTData);
1259  if (SUCCEEDED(hr) || (hr == E_OUTOFMEMORY))
1260  {
1261  *pcbData += cbData;
1262  hr = S_OK;
1263  }
1264  else
1265  ERR("IROTData_GetComparisonData failed with error 0x%08x\n", hr);
1266  }
1267 
1268  IMoniker_Release(pmk);
1269 
1270  if (FAILED(hr))
1271  {
1272  IEnumMoniker_Release(pEnumMk);
1273  return hr;
1274  }
1275  }
1276  if (cbMax < *pcbData)
1277  return E_OUTOFMEMORY;
1278 
1279  IEnumMoniker_Reset(pEnumMk);
1280 
1281  memcpy(pbData, &CLSID_CompositeMoniker, sizeof(CLSID));
1282  pbData += sizeof(CLSID);
1283  cbMax -= sizeof(CLSID);
1284 
1285  while (IEnumMoniker_Next(pEnumMk, 1, &pmk, NULL) == S_OK)
1286  {
1287  IROTData *pROTData;
1288  hr = IMoniker_QueryInterface(pmk, &IID_IROTData, (void **)&pROTData);
1289  if (FAILED(hr))
1290  ERR("moniker doesn't support IROTData interface\n");
1291 
1292  if (SUCCEEDED(hr))
1293  {
1294  ULONG cbData;
1295  hr = IROTData_GetComparisonData(pROTData, pbData, cbMax, &cbData);
1296  IROTData_Release(pROTData);
1297  if (SUCCEEDED(hr))
1298  {
1299  pbData += cbData;
1300  cbMax -= cbData;
1301  }
1302  else
1303  ERR("IROTData_GetComparisonData failed with error 0x%08x\n", hr);
1304  }
1305 
1306  IMoniker_Release(pmk);
1307 
1308  if (FAILED(hr))
1309  {
1310  IEnumMoniker_Release(pEnumMk);
1311  return hr;
1312  }
1313  }
1314 
1315  IEnumMoniker_Release(pEnumMk);
1316 
1317  return S_OK;
1318 }
1319 
1321 {
1323 
1324  TRACE("(%p,%s,%p)\n",iface,debugstr_guid(riid),ppv);
1325 
1326  return CompositeMonikerImpl_QueryInterface(&This->IMoniker_iface, riid, ppv);
1327 }
1328 
1330 {
1332 
1333  TRACE("(%p)\n",iface);
1334 
1335  return CompositeMonikerImpl_AddRef(&This->IMoniker_iface);
1336 }
1337 
1339 {
1341 
1342  TRACE("(%p)\n",iface);
1343 
1344  return CompositeMonikerImpl_Release(&This->IMoniker_iface);
1345 }
1346 
1348  IMarshal *iface, REFIID riid, void *pv, DWORD dwDestContext,
1349  void* pvDestContext, DWORD mshlflags, CLSID* pCid)
1350 {
1352 
1353  TRACE("(%s, %p, %x, %p, %x, %p)\n", debugstr_guid(riid), pv,
1354  dwDestContext, pvDestContext, mshlflags, pCid);
1355 
1356  return IMoniker_GetClassID(&This->IMoniker_iface, pCid);
1357 }
1358 
1360  IMarshal *iface, REFIID riid, void *pv, DWORD dwDestContext,
1361  void* pvDestContext, DWORD mshlflags, DWORD* pSize)
1362 {
1364  IEnumMoniker *pEnumMk;
1365  IMoniker *pmk;
1366  HRESULT hr;
1368 
1369  TRACE("(%s, %p, %x, %p, %x, %p)\n", debugstr_guid(riid), pv,
1370  dwDestContext, pvDestContext, mshlflags, pSize);
1371 
1372  *pSize = 0x10; /* to match native */
1373 
1374  hr = IMoniker_Enum(&This->IMoniker_iface, TRUE, &pEnumMk);
1375  if (FAILED(hr)) return hr;
1376 
1377  hr = IMoniker_GetSizeMax(&This->IMoniker_iface, &size);
1378 
1379  while (IEnumMoniker_Next(pEnumMk, 1, &pmk, NULL) == S_OK)
1380  {
1381  ULONG size;
1382 
1383  hr = CoGetMarshalSizeMax(&size, &IID_IMoniker, (IUnknown *)pmk, dwDestContext, pvDestContext, mshlflags);
1384  if (SUCCEEDED(hr))
1385  *pSize += size;
1386 
1387  IMoniker_Release(pmk);
1388 
1389  if (FAILED(hr))
1390  {
1391  IEnumMoniker_Release(pEnumMk);
1392  return hr;
1393  }
1394  }
1395 
1396  IEnumMoniker_Release(pEnumMk);
1397 
1398  return S_OK;
1399 }
1400 
1402  REFIID riid, void* pv, DWORD dwDestContext,
1403  void* pvDestContext, DWORD mshlflags)
1404 {
1406  IEnumMoniker *pEnumMk;
1407  IMoniker *pmk;
1408  HRESULT hr;
1409  ULONG i = 0;
1410 
1411  TRACE("(%p, %s, %p, %x, %p, %x)\n", pStm, debugstr_guid(riid), pv,
1412  dwDestContext, pvDestContext, mshlflags);
1413 
1414  hr = IMoniker_Enum(&This->IMoniker_iface, TRUE, &pEnumMk);
1415  if (FAILED(hr)) return hr;
1416 
1417  while (IEnumMoniker_Next(pEnumMk, 1, &pmk, NULL) == S_OK)
1418  {
1419  hr = CoMarshalInterface(pStm, &IID_IMoniker, (IUnknown *)pmk, dwDestContext, pvDestContext, mshlflags);
1420 
1421  IMoniker_Release(pmk);
1422 
1423  if (FAILED(hr))
1424  {
1425  IEnumMoniker_Release(pEnumMk);
1426  return hr;
1427  }
1428  i++;
1429  }
1430 
1431  if (i != 2)
1432  FIXME("moniker count of %d not supported\n", i);
1433 
1434  IEnumMoniker_Release(pEnumMk);
1435 
1436  return S_OK;
1437 }
1438 
1440  REFIID riid, void **ppv)
1441 {
1443  HRESULT hr;
1444 
1445  TRACE("(%p, %s, %p)\n", pStm, debugstr_guid(riid), ppv);
1446 
1448 
1449  /* resize the table if needed */
1450  if (This->tabLastIndex + 2 > This->tabSize)
1451  {
1452  This->tabSize += max(BLOCK_TAB_SIZE, 2);
1453  This->tabMoniker=HeapReAlloc(GetProcessHeap(),0,This->tabMoniker,This->tabSize*sizeof(This->tabMoniker[0]));
1454 
1455  if (This->tabMoniker==NULL)
1456  return E_OUTOFMEMORY;
1457  }
1458 
1459  hr = CoUnmarshalInterface(pStm, &IID_IMoniker, (void**)&This->tabMoniker[This->tabLastIndex]);
1460  if (FAILED(hr))
1461  {
1462  ERR("couldn't unmarshal moniker, hr = 0x%08x\n", hr);
1463  return hr;
1464  }
1465  This->tabLastIndex++;
1466  hr = CoUnmarshalInterface(pStm, &IID_IMoniker, (void**)&This->tabMoniker[This->tabLastIndex]);
1467  if (FAILED(hr))
1468  {
1469  ERR("couldn't unmarshal moniker, hr = 0x%08x\n", hr);
1470  return hr;
1471  }
1472  This->tabLastIndex++;
1473 
1474  return IMoniker_QueryInterface(&This->IMoniker_iface, riid, ppv);
1475 }
1476 
1478 {
1479  TRACE("(%p)\n", pStm);
1480  /* can't release a state-based marshal as nothing on server side to
1481  * release */
1482  return S_OK;
1483 }
1484 
1486  DWORD dwReserved)
1487 {
1488  TRACE("(0x%x)\n", dwReserved);
1489  /* can't disconnect a state-based marshal as nothing on server side to
1490  * disconnect from */
1491  return S_OK;
1492 }
1493 
1494 /******************************************************************************
1495  * EnumMonikerImpl_QueryInterface
1496  ******************************************************************************/
1497 static HRESULT WINAPI
1499 {
1501 
1502  TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppvObject);
1503 
1504  /* Perform a sanity check on the parameters.*/
1505  if ( ppvObject==0 )
1506  return E_INVALIDARG;
1507 
1508  /* Initialize the return parameter */
1509  *ppvObject = 0;
1510 
1511  /* Compare the riid with the interface IDs implemented by this object.*/
1513  *ppvObject = iface;
1514 
1515  /* Check that we obtained an interface.*/
1516  if ((*ppvObject)==0)
1517  return E_NOINTERFACE;
1518 
1519  /* Query Interface always increases the reference count by one when it is successful */
1520  IEnumMoniker_AddRef(iface);
1521 
1522  return S_OK;
1523 }
1524 
1525 /******************************************************************************
1526  * EnumMonikerImpl_AddRef
1527  ******************************************************************************/
1528 static ULONG WINAPI
1530 {
1532 
1533  TRACE("(%p)\n",This);
1534 
1535  return InterlockedIncrement(&This->ref);
1536 
1537 }
1538 
1539 /******************************************************************************
1540  * EnumMonikerImpl_Release
1541  ******************************************************************************/
1542 static ULONG WINAPI
1544 {
1546  ULONG i;
1547  ULONG ref;
1548  TRACE("(%p)\n",This);
1549 
1550  ref = InterlockedDecrement(&This->ref);
1551 
1552  /* destroy the object if there are no more references to it */
1553  if (ref == 0) {
1554 
1555  for(i=0;i<This->tabSize;i++)
1556  IMoniker_Release(This->tabMoniker[i]);
1557 
1558  HeapFree(GetProcessHeap(),0,This->tabMoniker);
1560  }
1561  return ref;
1562 }
1563 
1564 /******************************************************************************
1565  * EnumMonikerImpl_Next
1566  ******************************************************************************/
1567 static HRESULT WINAPI
1569  ULONG* pceltFethed)
1570 {
1572  ULONG i;
1573 
1574  /* retrieve the requested number of moniker from the current position */
1575  for(i=0;((This->currentPos < This->tabSize) && (i < celt));i++)
1576  {
1577  rgelt[i]=This->tabMoniker[This->currentPos++];
1578  IMoniker_AddRef(rgelt[i]);
1579  }
1580 
1581  if (pceltFethed!=NULL)
1582  *pceltFethed= i;
1583 
1584  if (i==celt)
1585  return S_OK;
1586  else
1587  return S_FALSE;
1588 }
1589 
1590 /******************************************************************************
1591  * EnumMonikerImpl_Skip
1592  ******************************************************************************/
1593 static HRESULT WINAPI
1595 {
1597 
1598  if ((This->currentPos+celt) >= This->tabSize)
1599  return S_FALSE;
1600 
1601  This->currentPos+=celt;
1602 
1603  return S_OK;
1604 }
1605 
1606 /******************************************************************************
1607  * EnumMonikerImpl_Reset
1608  ******************************************************************************/
1609 static HRESULT WINAPI
1611 {
1613 
1614  This->currentPos=0;
1615 
1616  return S_OK;
1617 }
1618 
1619 /******************************************************************************
1620  * EnumMonikerImpl_Clone
1621  ******************************************************************************/
1622 static HRESULT WINAPI
1624 {
1626 
1627  return EnumMonikerImpl_CreateEnumMoniker(This->tabMoniker,This->tabSize,This->currentPos,TRUE,ppenum);
1628 }
1629 
1630 /********************************************************************************/
1631 /* Virtual function table for the IROTData class */
1632 static const IEnumMonikerVtbl VT_EnumMonikerImpl =
1633 {
1641 };
1642 
1643 /******************************************************************************
1644  * EnumMonikerImpl_CreateEnumMoniker
1645  ******************************************************************************/
1646 static HRESULT
1648  ULONG currentPos, BOOL leftToRight, IEnumMoniker ** ppmk)
1649 {
1650  EnumMonikerImpl* newEnumMoniker;
1651  ULONG i;
1652 
1653  if (currentPos > tabSize)
1654  return E_INVALIDARG;
1655 
1656  newEnumMoniker = HeapAlloc(GetProcessHeap(), 0, sizeof(EnumMonikerImpl));
1657 
1658  if (newEnumMoniker == 0)
1659  return STG_E_INSUFFICIENTMEMORY;
1660 
1661  /* Initialize the virtual function table. */
1662  newEnumMoniker->IEnumMoniker_iface.lpVtbl = &VT_EnumMonikerImpl;
1663  newEnumMoniker->ref = 1;
1664 
1665  newEnumMoniker->tabSize=tabSize;
1666  newEnumMoniker->currentPos=currentPos;
1667 
1668  newEnumMoniker->tabMoniker=HeapAlloc(GetProcessHeap(),0,tabSize*sizeof(newEnumMoniker->tabMoniker[0]));
1669 
1670  if (newEnumMoniker->tabMoniker==NULL) {
1671  HeapFree(GetProcessHeap(), 0, newEnumMoniker);
1672  return E_OUTOFMEMORY;
1673  }
1674 
1675  if (leftToRight)
1676  for (i=0;i<tabSize;i++){
1677 
1678  newEnumMoniker->tabMoniker[i]=tabMoniker[i];
1679  IMoniker_AddRef(tabMoniker[i]);
1680  }
1681  else
1682  for (i = tabSize; i > 0; i--){
1683 
1684  newEnumMoniker->tabMoniker[tabSize-i]=tabMoniker[i - 1];
1685  IMoniker_AddRef(tabMoniker[i - 1]);
1686  }
1687 
1688  *ppmk=&newEnumMoniker->IEnumMoniker_iface;
1689 
1690  return S_OK;
1691 }
1692 
1693 /********************************************************************************/
1694 /* Virtual function table for the CompositeMonikerImpl class which includes */
1695 /* IPersist, IPersistStream and IMoniker functions. */
1696 
1697 static const IMonikerVtbl VT_CompositeMonikerImpl =
1698 {
1722 };
1723 
1724 /********************************************************************************/
1725 /* Virtual function table for the IROTData class. */
1726 static const IROTDataVtbl VT_ROTDataImpl =
1727 {
1732 };
1733 
1734 static const IMarshalVtbl VT_MarshalImpl =
1735 {
1745 };
1746 
1747 /******************************************************************************
1748  * Composite-Moniker_Construct (local function)
1749  *******************************************************************************/
1750 static HRESULT
1752 {
1753  DWORD mkSys;
1754  IEnumMoniker *enumMoniker;
1755  IMoniker *tempMk;
1756  HRESULT res;
1758  int i;
1759 
1760  This = HeapAlloc(GetProcessHeap(), 0, sizeof(*This));
1761 
1762  if (!This)
1763  return E_OUTOFMEMORY;
1764 
1765  TRACE("(%p,%p,%p)\n",This,pmkFirst,pmkRest);
1766 
1767  /* Initialize the virtual function table. */
1768  This->IMoniker_iface.lpVtbl = &VT_CompositeMonikerImpl;
1769  This->IROTData_iface.lpVtbl = &VT_ROTDataImpl;
1770  This->IMarshal_iface.lpVtbl = &VT_MarshalImpl;
1771  This->ref = 1;
1772 
1773  This->tabSize=BLOCK_TAB_SIZE;
1774  This->tabLastIndex=0;
1775 
1776  This->tabMoniker=HeapAlloc(GetProcessHeap(),0,This->tabSize*sizeof(This->tabMoniker[0]));
1777  if (This->tabMoniker==NULL) {
1778  HeapFree(GetProcessHeap(), 0, This);
1779  return E_OUTOFMEMORY;
1780  }
1781 
1782  if (!pmkFirst && !pmkRest)
1783  {
1784  *ppMoniker = &This->IMoniker_iface;
1785  return S_OK;
1786  }
1787 
1788  IMoniker_IsSystemMoniker(pmkFirst,&mkSys);
1789 
1790  /* put the first moniker contents in the beginning of the table */
1791  if (mkSys!=MKSYS_GENERICCOMPOSITE){
1792 
1793  This->tabMoniker[(This->tabLastIndex)++]=pmkFirst;
1794  IMoniker_AddRef(pmkFirst);
1795  }
1796  else{
1797 
1798  IMoniker_Enum(pmkFirst,TRUE,&enumMoniker);
1799 
1800  while(IEnumMoniker_Next(enumMoniker,1,&This->tabMoniker[This->tabLastIndex],NULL)==S_OK){
1801 
1802 
1803  if (++This->tabLastIndex==This->tabSize){
1804  IMoniker **tab_moniker = This->tabMoniker;
1805 
1806  This->tabSize+=BLOCK_TAB_SIZE;
1807  This->tabMoniker=HeapReAlloc(GetProcessHeap(),0,This->tabMoniker,This->tabSize*sizeof(This->tabMoniker[0]));
1808 
1809  if (This->tabMoniker==NULL){
1810  for (i = 0; i < This->tabLastIndex; i++)
1811  IMoniker_Release(tab_moniker[i]);
1812  HeapFree(GetProcessHeap(), 0, tab_moniker);
1813  HeapFree(GetProcessHeap(), 0, This);
1814  return E_OUTOFMEMORY;
1815  }
1816  }
1817  }
1818 
1819  IEnumMoniker_Release(enumMoniker);
1820  }
1821 
1822  /* put the rest moniker contents after the first one and make simplification if needed */
1823 
1824  IMoniker_IsSystemMoniker(pmkRest,&mkSys);
1825 
1826  if (mkSys!=MKSYS_GENERICCOMPOSITE){
1827 
1828  /* add a simple moniker to the moniker table */
1829 
1830  res=IMoniker_ComposeWith(This->tabMoniker[This->tabLastIndex-1],pmkRest,TRUE,&tempMk);
1831 
1832  if (res==MK_E_NEEDGENERIC){
1833 
1834  /* there's no simplification in this case */
1835  This->tabMoniker[This->tabLastIndex]=pmkRest;
1836 
1837  This->tabLastIndex++;
1838 
1839  IMoniker_AddRef(pmkRest);
1840  }
1841  else if (tempMk==NULL){
1842 
1843  /* we have an antimoniker after a simple moniker so we can make a simplification in this case */
1844  IMoniker_Release(This->tabMoniker[This->tabLastIndex-1]);
1845 
1846  This->tabLastIndex--;
1847  }
1848  else if (SUCCEEDED(res)){
1849 
1850  /* the non-generic composition was successful so we can make a simplification in this case */
1851  IMoniker_Release(This->tabMoniker[This->tabLastIndex-1]);
1852 
1853  This->tabMoniker[This->tabLastIndex-1]=tempMk;
1854  } else{
1855  for (i = 0; i < This->tabLastIndex; i++)
1856  IMoniker_Release(This->tabMoniker[i]);
1857  HeapFree(GetProcessHeap(), 0, This->tabMoniker);
1858  HeapFree(GetProcessHeap(), 0, This);
1859  return res;
1860  }
1861 
1862  /* resize tabMoniker if needed */
1863  if (This->tabLastIndex==This->tabSize){
1864  IMoniker **tab_moniker = This->tabMoniker;
1865 
1866  This->tabSize+=BLOCK_TAB_SIZE;
1867 
1868  This->tabMoniker=HeapReAlloc(GetProcessHeap(),0,This->tabMoniker,This->tabSize*sizeof(IMoniker));
1869 
1870  if (This->tabMoniker==NULL){
1871  for (i = 0; i < This->tabLastIndex; i++)
1872  IMoniker_Release(tab_moniker[i]);
1873  HeapFree(GetProcessHeap(), 0, tab_moniker);
1874  HeapFree(GetProcessHeap(), 0, This);
1875  return E_OUTOFMEMORY;
1876  }
1877  }
1878  }
1879  else{
1880 
1881  /* add a composite moniker to the moniker table (do the same thing
1882  * for each moniker within the composite moniker as a simple moniker
1883  * (see above for how to add a simple moniker case) )
1884  */
1885  IMoniker_Enum(pmkRest,TRUE,&enumMoniker);
1886 
1887  while(IEnumMoniker_Next(enumMoniker,1,&This->tabMoniker[This->tabLastIndex],NULL)==S_OK){
1888 
1889  res=IMoniker_ComposeWith(This->tabMoniker[This->tabLastIndex-1],This->tabMoniker[This->tabLastIndex],TRUE,&tempMk);
1890 
1891  if (res==MK_E_NEEDGENERIC){
1892 
1893  This->tabLastIndex++;
1894  }
1895  else if (tempMk==NULL){
1896 
1897  IMoniker_Release(This->tabMoniker[This->tabLastIndex-1]);
1898  IMoniker_Release(This->tabMoniker[This->tabLastIndex]);
1899  This->tabLastIndex--;
1900  }
1901  else{
1902 
1903  IMoniker_Release(This->tabMoniker[This->tabLastIndex-1]);
1904 
1905  This->tabMoniker[This->tabLastIndex-1]=tempMk;
1906  }
1907 
1908  if (This->tabLastIndex==This->tabSize){
1909  IMoniker **tab_moniker = This->tabMoniker;
1910 
1911  This->tabSize+=BLOCK_TAB_SIZE;
1912 
1913  This->tabMoniker=HeapReAlloc(GetProcessHeap(),0,This->tabMoniker,This->tabSize*sizeof(This->tabMoniker[0]));
1914 
1915  if (This->tabMoniker==NULL){
1916  for (i = 0; i < This->tabLastIndex; i++)
1917  IMoniker_Release(tab_moniker[i]);
1918  HeapFree(GetProcessHeap(), 0, tab_moniker);
1919  HeapFree(GetProcessHeap(), 0, This);
1920  return E_OUTOFMEMORY;
1921  }
1922  }
1923  }
1924 
1925  IEnumMoniker_Release(enumMoniker);
1926  }
1927 
1928  /* only one moniker, then just return it */
1929  if (This->tabLastIndex == 1)
1930  {
1931  *ppMoniker = This->tabMoniker[0];
1932  IMoniker_AddRef(*ppMoniker);
1933  IMoniker_Release(&This->IMoniker_iface);
1934  }
1935  else
1936  *ppMoniker = &This->IMoniker_iface;
1937 
1938  return S_OK;
1939 }
1940 
1941 /******************************************************************************
1942  * CreateGenericComposite [OLE32.@]
1943  ******************************************************************************/
1945 CreateGenericComposite(IMoniker *pmkFirst, IMoniker *pmkRest, IMoniker **ppmkComposite)
1946 {
1947  IMoniker* moniker = 0;
1948  HRESULT hr = S_OK;
1949 
1950  TRACE("(%p,%p,%p)\n",pmkFirst,pmkRest,ppmkComposite);
1951 
1952  if (ppmkComposite==NULL)
1953  return E_POINTER;
1954 
1955  *ppmkComposite=0;
1956 
1957  if (pmkFirst==NULL && pmkRest!=NULL){
1958 
1959  *ppmkComposite=pmkRest;
1960  IMoniker_AddRef(pmkRest);
1961  return S_OK;
1962  }
1963  else if (pmkFirst!=NULL && pmkRest==NULL){
1964  *ppmkComposite=pmkFirst;
1965  IMoniker_AddRef(pmkFirst);
1966  return S_OK;
1967  }
1968  else if (pmkFirst==NULL && pmkRest==NULL)
1969  return S_OK;
1970 
1971  hr = CompositeMonikerImpl_Construct(&moniker,pmkFirst,pmkRest);
1972 
1973  if (FAILED(hr))
1974  return hr;
1975 
1976  hr = IMoniker_QueryInterface(moniker,&IID_IMoniker,(void**)ppmkComposite);
1977  IMoniker_Release(moniker);
1978 
1979  return hr;
1980 }
1981 
1982 /******************************************************************************
1983  * MonikerCommonPrefixWith [OLE32.@]
1984  ******************************************************************************/
1986 MonikerCommonPrefixWith(IMoniker* pmkThis,IMoniker* pmkOther,IMoniker** ppmkCommon)
1987 {
1988  FIXME("(),stub!\n");
1989  return E_NOTIMPL;
1990 }
1991 
1993  IUnknown *pUnk, REFIID riid, void **ppv)
1994 {
1995  IMoniker* pMoniker;
1996  HRESULT hr;
1997 
1998  TRACE("(%p, %s, %p)\n", pUnk, debugstr_guid(riid), ppv);
1999 
2000  *ppv = NULL;
2001 
2002  if (pUnk)
2003  return CLASS_E_NOAGGREGATION;
2004 
2005  hr = CompositeMonikerImpl_Construct(&pMoniker, NULL, NULL);
2006 
2007  if (SUCCEEDED(hr))
2008  {
2009  hr = IMoniker_QueryInterface(pMoniker, riid, ppv);
2010  IMoniker_Release(pMoniker);
2011  }
2012 
2013  return hr;
2014 }
static HRESULT WINAPI CompositeMonikerImpl_QueryInterface(IMoniker *iface, REFIID riid, void **ppvObject)
static HRESULT WINAPI CompositeMonikerImpl_IsSystemMoniker(IMoniker *iface, DWORD *pwdMksys)
static const IMarshalVtbl VT_MarshalImpl
HRESULT WINAPI CoUnmarshalInterface(IStream *pStream, REFIID riid, LPVOID *ppv)
Definition: marshal.c:1982
#define max(a, b)
Definition: svc.c:63
#define REFIID
Definition: guiddef.h:113
#define TRUE
Definition: types.h:120
#define MK_S_REDUCED_TO_SELF
Definition: winerror.h:2773
#define E_NOINTERFACE
Definition: winerror.h:2364
HRESULT WINAPI MonikerCommonPrefixWith(IMoniker *pmkThis, IMoniker *pmkOther, IMoniker **ppmkCommon)
VOID WINAPI CoTaskMemFree(LPVOID ptr)
Definition: ifs.c:422
static HRESULT WINAPI CompositeMonikerImpl_ParseDisplayName(IMoniker *iface, IBindCtx *pbc, IMoniker *pmkToLeft, LPOLESTR pszDisplayName, ULONG *pchEaten, IMoniker **ppmkOut)
HRESULT hr
Definition: shlfolder.c:183
static HRESULT WINAPI CompositeMonikerROTDataImpl_QueryInterface(IROTData *iface, REFIID riid, VOID **ppvObject)
static HRESULT WINAPI CompositeMonikerImpl_Enum(IMoniker *iface, BOOL fForward, IEnumMoniker **ppenumMoniker)
REFIID riid
Definition: precomp.h:44
const GUID IID_IPersist
Definition: proxy.cpp:14
const GUID IID_IEnumMoniker
HRESULT WINAPI CompositeMoniker_CreateInstance(IClassFactory *iface, IUnknown *pUnk, REFIID riid, void **ppv)
REFIID LPVOID * ppv
Definition: atlbase.h:39
IMoniker ** tabMoniker
#define BLOCK_TAB_SIZE
#define STG_E_INSUFFICIENTMEMORY
Definition: winerror.h:2570
static HRESULT WINAPI CompositeMonikerROTDataImpl_GetComparisonData(IROTData *iface, BYTE *pbData, ULONG cbMax, ULONG *pcbData)
static HRESULT WINAPI CompositeMonikerMarshalImpl_QueryInterface(IMarshal *iface, REFIID riid, LPVOID *ppv)
#define MK_S_ME
Definition: winerror.h:2774
static HRESULT WINAPI CompositeMonikerMarshalImpl_GetUnmarshalClass(IMarshal *iface, REFIID riid, void *pv, DWORD dwDestContext, void *pvDestContext, DWORD mshlflags, CLSID *pCid)
static LPOLESTR
Definition: stg_prop.c:27
#define lstrlenW
Definition: compat.h:407
#define E_FAIL
Definition: ddrawi.h:102
#define DWORD
Definition: nt_native.h:44
Definition: send.c:47
IEnumMoniker IEnumMoniker_iface
Definition: mediacatenum.c:35
static HRESULT WINAPI CompositeMonikerImpl_ComposeWith(IMoniker *iface, IMoniker *pmkRight, BOOL fOnlyIfNotGeneric, IMoniker **ppmkComposite)
static HRESULT WINAPI CompositeMonikerImpl_Reduce(IMoniker *iface, IBindCtx *pbc, DWORD dwReduceHowFar, IMoniker **ppmkToLeft, IMoniker **ppmkReduced)
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
static ULONG WINAPI CompositeMonikerMarshalImpl_AddRef(IMarshal *iface)
static HRESULT WINAPI CompositeMonikerImpl_IsRunning(IMoniker *iface, IBindCtx *pbc, IMoniker *pmkToLeft, IMoniker *pmkNewlyRunning)
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
ULONGLONG QuadPart
Definition: ms-dtyp.idl:185
_In_ HANDLE _In_ DWORD _In_ DWORD _Inout_opt_ LPOVERLAPPED _In_opt_ LPTRANSMIT_FILE_BUFFERS _In_ DWORD dwReserved
Definition: mswsock.h:90
static void CompositeMonikerImpl_ReleaseMonikersInTable(CompositeMonikerImpl *This)
unsigned int BOOL
Definition: ntddk_ex.h:94
long LONG
Definition: pedump.c:60
GLenum GLint ref
Definition: glext.h:6028
#define FIXME(fmt,...)
Definition: debug.h:110
GLfloat rot
Definition: 3dtext.c:36
#define S_FALSE
Definition: winerror.h:2357
#define E_INVALIDARG
Definition: ddrawi.h:101
static HRESULT WINAPI CompositeMonikerMarshalImpl_GetMarshalSizeMax(IMarshal *iface, REFIID riid, void *pv, DWORD dwDestContext, void *pvDestContext, DWORD mshlflags, DWORD *pSize)
smooth NULL
Definition: ftsmooth.c:416
static HRESULT WINAPI CompositeMonikerImpl_GetTimeOfLastChange(IMoniker *iface, IBindCtx *pbc, IMoniker *pmkToLeft, FILETIME *pCompositeTime)
static HRESULT WINAPI EnumMonikerImpl_Clone(IEnumMoniker *iface, IEnumMoniker **ppenum)
#define MK_E_NEEDGENERIC
Definition: winerror.h:2783
#define debugstr_guid
Definition: kernel32.h:35
static const IROTDataVtbl VT_ROTDataImpl
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
static HRESULT WINAPI EnumMonikerImpl_QueryInterface(IEnumMoniker *iface, REFIID riid, void **ppvObject)
static ULONG WINAPI CompositeMonikerROTDataImpl_Release(IROTData *iface)
static HRESULT EnumMonikerImpl_CreateEnumMoniker(IMoniker **tabMoniker, ULONG tabSize, ULONG currentPos, BOOL leftToRight, IEnumMoniker **ppmk)
#define TRACE(s)
Definition: solgame.cpp:4
static ULONG WINAPI CompositeMonikerMarshalImpl_Release(IMarshal *iface)
GLsizeiptr size
Definition: glext.h:5919
#define GetProcessHeap()
Definition: compat.h:395
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
__wchar_t WCHAR
Definition: xmlstorage.h:180
static HRESULT WINAPI CompositeMonikerImpl_RelativePathTo(IMoniker *iface, IMoniker *pmkOther, IMoniker **ppmkRelPath)
LONG HRESULT
Definition: typedefs.h:77
const GUID IID_IUnknown
static ULONG WINAPI EnumMonikerImpl_AddRef(IEnumMoniker *iface)
static CompositeMonikerImpl * impl_from_IMarshal(IMarshal *iface)
#define WINAPI
Definition: msvc.h:8
static HRESULT WINAPI CompositeMonikerImpl_GetDisplayName(IMoniker *iface, IBindCtx *pbc, IMoniker *pmkToLeft, LPOLESTR *ppszDisplayName)
static HRESULT WINAPI CompositeMonikerImpl_GetClassID(IMoniker *iface, CLSID *pClassID)
unsigned long DWORD
Definition: ntddk_ex.h:95
static CompositeMonikerImpl * impl_from_IMoniker(IMoniker *iface)
HRESULT WINAPI OleSaveToStream(IPersistStream *pPStm, IStream *pStm)
Definition: storage32.c:9165
const GUID IID_IPersistStream
Definition: proxy.cpp:13
static HRESULT WINAPI CompositeMonikerImpl_Load(IMoniker *iface, IStream *pStm)
static HRESULT WINAPI CompositeMonikerImpl_GetSizeMax(IMoniker *iface, ULARGE_INTEGER *pcbSize)
HRESULT WINAPI CreateAntiMoniker(IMoniker **ppmk)
Definition: antimoniker.c:608
static ULONG WINAPI CompositeMonikerROTDataImpl_AddRef(IROTData *iface)
#define InterlockedDecrement
Definition: armddk.h:52
static HRESULT WINAPI CompositeMonikerImpl_Inverse(IMoniker *iface, IMoniker **ppmk)
static VOID GetAfterCommonPrefix(IMoniker *pGenMk, IMoniker *commonMk, IMoniker **restMk)
struct CompositeMonikerImpl CompositeMonikerImpl
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
unsigned char BYTE
Definition: mem.h:68
REFIID LPVOID * ppvObject
Definition: precomp.h:44
#define CLASS_E_NOAGGREGATION
Definition: winerror.h:2662
struct EnumMonikerImpl EnumMonikerImpl
static HRESULT WINAPI EnumMonikerImpl_Skip(IEnumMoniker *iface, ULONG celt)
static ULONG WINAPI EnumMonikerImpl_Release(IEnumMoniker *iface)
#define MK_E_NOPREFIX
Definition: winerror.h:2795
HRESULT WINAPI CoGetMarshalSizeMax(ULONG *pulSize, REFIID riid, IUnknown *pUnk, DWORD dwDestContext, void *pvDestContext, DWORD mshlFlags)
Definition: marshal.c:1801
static HRESULT WINAPI CompositeMonikerImpl_CommonPrefixWith(IMoniker *iface, IMoniker *pmkOther, IMoniker **ppmkPrefix)
static ULONG WINAPI CompositeMonikerImpl_AddRef(IMoniker *iface)
#define ERR(fmt,...)
Definition: debug.h:109
#define S_OK
Definition: intsafe.h:59
#define MK_S_US
Definition: winerror.h:2776
#define InterlockedIncrement
Definition: armddk.h:53
static EnumMonikerImpl * impl_from_IEnumMoniker(IEnumMoniker *iface)
static HRESULT WINAPI CompositeMonikerImpl_IsDirty(IMoniker *iface)
static HRESULT WINAPI CompositeMonikerImpl_BindToStorage(IMoniker *iface, IBindCtx *pbc, IMoniker *pmkToLeft, REFIID riid, VOID **ppvResult)
static ULONG WINAPI CompositeMonikerImpl_Release(IMoniker *iface)
#define HeapReAlloc
Definition: compat.h:393
static HRESULT WINAPI CompositeMonikerMarshalImpl_DisconnectObject(IMarshal *iface, DWORD dwReserved)
#define E_NOTIMPL
Definition: ddrawi.h:99
static HRESULT WINAPI CompositeMonikerMarshalImpl_MarshalInterface(IMarshal *iface, IStream *pStm, REFIID riid, void *pv, DWORD dwDestContext, void *pvDestContext, DWORD mshlflags)
WINE_UNICODE_INLINE WCHAR * strcatW(WCHAR *dst, const WCHAR *src)
Definition: unicode.h:242
static CompositeMonikerImpl * impl_from_IROTData(IROTData *iface)
Definition: main.c:41
static const IMonikerVtbl VT_CompositeMonikerImpl
GLuint res
Definition: glext.h:9613
static HRESULT WINAPI EnumMonikerImpl_Next(IEnumMoniker *iface, ULONG celt, IMoniker **rgelt, ULONG *pceltFethed)
WINE_DEFAULT_DEBUG_CHANNEL(ole)
static HRESULT WINAPI CompositeMonikerImpl_IsEqual(IMoniker *iface, IMoniker *pmkOtherMoniker)
unsigned int ULONG
Definition: retypes.h:1
LPVOID WINAPI CoTaskMemRealloc(LPVOID pvOld, SIZE_T size)
Definition: ifs.c:440
static HRESULT WINAPI CompositeMonikerImpl_BindToObject(IMoniker *iface, IBindCtx *pbc, IMoniker *pmkToLeft, REFIID riid, VOID **ppvResult)
static HRESULT WINAPI CompositeMonikerImpl_Hash(IMoniker *iface, DWORD *pdwHash)
static HRESULT WINAPI EnumMonikerImpl_Reset(IEnumMoniker *iface)
HRESULT WINAPI CreateGenericComposite(IMoniker *pmkFirst, IMoniker *pmkRest, IMoniker **ppmkComposite)
static HRESULT WINAPI CompositeMonikerMarshalImpl_UnmarshalInterface(IMarshal *iface, IStream *pStm, REFIID riid, void **ppv)
HRESULT WINAPI CoMarshalInterface(IStream *pStream, REFIID riid, IUnknown *pUnk, DWORD dwDestContext, void *pvDestContext, DWORD mshlFlags)
Definition: marshal.c:1877
#define E_POINTER
Definition: winerror.h:2365
static HRESULT CompositeMonikerImpl_Construct(IMoniker **ppMoniker, IMoniker *pmkFirst, IMoniker *pmkRest)
static void *static void *static LPDIRECTPLAY IUnknown * pUnk
Definition: dplayx.c:30
LPVOID WINAPI CoTaskMemAlloc(SIZE_T size)
Definition: ifs.c:406
#define HeapFree(x, y, z)
Definition: compat.h:394
#define IsEqualIID(riid1, riid2)
Definition: guiddef.h:90
HRESULT WINAPI OleLoadFromStream(IStream *pStm, REFIID iidInterface, void **ppvObj)
Definition: storage32.c:9130
static HRESULT WINAPI CompositeMonikerImpl_Save(IMoniker *iface, IStream *pStm, BOOL fClearDirty)
static HRESULT WINAPI CompositeMonikerMarshalImpl_ReleaseMarshalData(IMarshal *iface, IStream *pStm)
#define SUCCEEDED(hr)
Definition: intsafe.h:57
static const IEnumMonikerVtbl VT_EnumMonikerImpl
_In_ DWORD _Out_writes_bytes_to_opt_ pcbData void _Inout_ DWORD * pcbData
Definition: wincrypt.h:4953
_In_ HCRYPTHASH _In_ BOOL _In_ DWORD _Inout_updates_bytes_to_ pdwDataLen BYTE * pbData
Definition: wincrypt.h:4201
#define MK_S_HIM
Definition: winerror.h:2775