1 /***************************************************************************************
2 * ItemMonikers implementation
4 * Copyright 1999 Noomen Hamza
5 ***************************************************************************************/
10 #include "debugtools.h"
11 #include "wine/winestring.h"
12 #include "wine/obj_base.h"
13 #include "wine/obj_misc.h"
14 #include "wine/obj_storage.h"
15 #include "wine/obj_moniker.h"
16 #include "wine/obj_inplace.h"
17 #include "wine/unicode.h"
19 DEFAULT_DEBUG_CHANNEL(ole
);
21 /* ItemMoniker data structure */
22 typedef struct ItemMonikerImpl
{
24 ICOM_VTABLE(IMoniker
)* lpvtbl1
; /* VTable relative to the IMoniker interface.*/
26 /* The ROT (RunningObjectTable implementation) uses the IROTData interface to test whether
27 * two monikers are equal. That's whay IROTData interface is implemented by monikers.
29 ICOM_VTABLE(IROTData
)* lpvtbl2
; /* VTable relative to the IROTData interface.*/
31 ULONG ref
; /* reference counter for this object */
33 LPOLESTR itemName
; /* item name identified by this ItemMoniker */
35 LPOLESTR itemDelimiter
; /* Delimiter string */
39 /********************************************************************************/
40 /* ItemMoniker prototype functions : */
42 /* IUnknown prototype functions */
43 static HRESULT WINAPI
ItemMonikerImpl_QueryInterface(IMoniker
* iface
,REFIID riid
,void** ppvObject
);
44 static ULONG WINAPI
ItemMonikerImpl_AddRef(IMoniker
* iface
);
45 static ULONG WINAPI
ItemMonikerImpl_Release(IMoniker
* iface
);
47 /* IPersist prototype functions */
48 static HRESULT WINAPI
ItemMonikerImpl_GetClassID(IMoniker
* iface
, CLSID
*pClassID
);
50 /* IPersistStream prototype functions */
51 static HRESULT WINAPI
ItemMonikerImpl_IsDirty(IMoniker
* iface
);
52 static HRESULT WINAPI
ItemMonikerImpl_Load(IMoniker
* iface
, IStream
* pStm
);
53 static HRESULT WINAPI
ItemMonikerImpl_Save(IMoniker
* iface
, IStream
* pStm
, BOOL fClearDirty
);
54 static HRESULT WINAPI
ItemMonikerImpl_GetSizeMax(IMoniker
* iface
, ULARGE_INTEGER
* pcbSize
);
56 /* IMoniker prototype functions */
57 static HRESULT WINAPI
ItemMonikerImpl_BindToObject(IMoniker
* iface
,IBindCtx
* pbc
, IMoniker
* pmkToLeft
, REFIID riid
, VOID
** ppvResult
);
58 static HRESULT WINAPI
ItemMonikerImpl_BindToStorage(IMoniker
* iface
,IBindCtx
* pbc
, IMoniker
* pmkToLeft
, REFIID riid
, VOID
** ppvResult
);
59 static HRESULT WINAPI
ItemMonikerImpl_Reduce(IMoniker
* iface
,IBindCtx
* pbc
, DWORD dwReduceHowFar
,IMoniker
** ppmkToLeft
, IMoniker
** ppmkReduced
);
60 static HRESULT WINAPI
ItemMonikerImpl_ComposeWith(IMoniker
* iface
,IMoniker
* pmkRight
,BOOL fOnlyIfNotGeneric
, IMoniker
** ppmkComposite
);
61 static HRESULT WINAPI
ItemMonikerImpl_Enum(IMoniker
* iface
,BOOL fForward
, IEnumMoniker
** ppenumMoniker
);
62 static HRESULT WINAPI
ItemMonikerImpl_IsEqual(IMoniker
* iface
,IMoniker
* pmkOtherMoniker
);
63 static HRESULT WINAPI
ItemMonikerImpl_Hash(IMoniker
* iface
,DWORD
* pdwHash
);
64 static HRESULT WINAPI
ItemMonikerImpl_IsRunning(IMoniker
* iface
,IBindCtx
* pbc
, IMoniker
* pmkToLeft
, IMoniker
* pmkNewlyRunning
);
65 static HRESULT WINAPI
ItemMonikerImpl_GetTimeOfLastChange(IMoniker
* iface
, IBindCtx
* pbc
, IMoniker
* pmkToLeft
, FILETIME
* pItemTime
);
66 static HRESULT WINAPI
ItemMonikerImpl_Inverse(IMoniker
* iface
,IMoniker
** ppmk
);
67 static HRESULT WINAPI
ItemMonikerImpl_CommonPrefixWith(IMoniker
* iface
,IMoniker
* pmkOther
, IMoniker
** ppmkPrefix
);
68 static HRESULT WINAPI
ItemMonikerImpl_RelativePathTo(IMoniker
* iface
,IMoniker
* pmOther
, IMoniker
** ppmkRelPath
);
69 static HRESULT WINAPI
ItemMonikerImpl_GetDisplayName(IMoniker
* iface
,IBindCtx
* pbc
, IMoniker
* pmkToLeft
, LPOLESTR
*ppszDisplayName
);
70 static HRESULT WINAPI
ItemMonikerImpl_ParseDisplayName(IMoniker
* iface
,IBindCtx
* pbc
, IMoniker
* pmkToLeft
, LPOLESTR pszDisplayName
, ULONG
* pchEaten
, IMoniker
** ppmkOut
);
71 static HRESULT WINAPI
ItemMonikerImpl_IsSystemMoniker(IMoniker
* iface
,DWORD
* pwdMksys
);
73 /* Local function used by ItemMoniker implementation */
74 HRESULT WINAPI
ItemMonikerImpl_Construct(ItemMonikerImpl
* iface
, LPCOLESTR lpszDelim
,LPCOLESTR lpszPathName
);
75 HRESULT WINAPI
ItemMonikerImpl_Destroy(ItemMonikerImpl
* iface
);
77 /********************************************************************************/
78 /* IROTData prototype functions */
80 /* IUnknown prototype functions */
81 static HRESULT WINAPI
ItemMonikerROTDataImpl_QueryInterface(IROTData
* iface
,REFIID riid
,VOID
** ppvObject
);
82 static ULONG WINAPI
ItemMonikerROTDataImpl_AddRef(IROTData
* iface
);
83 static ULONG WINAPI
ItemMonikerROTDataImpl_Release(IROTData
* iface
);
85 /* IROTData prototype function */
86 static HRESULT WINAPI
ItemMonikerROTDataImpl_GetComparaisonData(IROTData
* iface
,BYTE
* pbData
,ULONG cbMax
,ULONG
* pcbData
);
88 /********************************************************************************/
89 /* Virtual function table for the ItemMonikerImpl class witch include Ipersist,*/
90 /* IPersistStream and IMoniker functions. */
91 static ICOM_VTABLE(IMoniker
) VT_ItemMonikerImpl
=
93 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
94 ItemMonikerImpl_QueryInterface
,
95 ItemMonikerImpl_AddRef
,
96 ItemMonikerImpl_Release
,
97 ItemMonikerImpl_GetClassID
,
98 ItemMonikerImpl_IsDirty
,
100 ItemMonikerImpl_Save
,
101 ItemMonikerImpl_GetSizeMax
,
102 ItemMonikerImpl_BindToObject
,
103 ItemMonikerImpl_BindToStorage
,
104 ItemMonikerImpl_Reduce
,
105 ItemMonikerImpl_ComposeWith
,
106 ItemMonikerImpl_Enum
,
107 ItemMonikerImpl_IsEqual
,
108 ItemMonikerImpl_Hash
,
109 ItemMonikerImpl_IsRunning
,
110 ItemMonikerImpl_GetTimeOfLastChange
,
111 ItemMonikerImpl_Inverse
,
112 ItemMonikerImpl_CommonPrefixWith
,
113 ItemMonikerImpl_RelativePathTo
,
114 ItemMonikerImpl_GetDisplayName
,
115 ItemMonikerImpl_ParseDisplayName
,
116 ItemMonikerImpl_IsSystemMoniker
119 /********************************************************************************/
120 /* Virtual function table for the IROTData class. */
121 static ICOM_VTABLE(IROTData
) VT_ROTDataImpl
=
123 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
124 ItemMonikerROTDataImpl_QueryInterface
,
125 ItemMonikerROTDataImpl_AddRef
,
126 ItemMonikerROTDataImpl_Release
,
127 ItemMonikerROTDataImpl_GetComparaisonData
130 /*******************************************************************************
131 * ItemMoniker_QueryInterface
132 *******************************************************************************/
133 HRESULT WINAPI
ItemMonikerImpl_QueryInterface(IMoniker
* iface
,REFIID riid
,void** ppvObject
)
135 ICOM_THIS(ItemMonikerImpl
,iface
);
137 TRACE("(%p,%p,%p)\n",This
,riid
,ppvObject
);
139 /* Perform a sanity check on the parameters.*/
140 if ( (This
==0) || (ppvObject
==0) )
143 /* Initialize the return parameter */
146 /* Compare the riid with the interface IDs implemented by this object.*/
147 if (IsEqualIID(&IID_IUnknown
, riid
) ||
148 IsEqualIID(&IID_IPersist
, riid
) ||
149 IsEqualIID(&IID_IPersistStream
, riid
) ||
150 IsEqualIID(&IID_IMoniker
, riid
)
154 else if (IsEqualIID(&IID_IROTData
, riid
))
155 *ppvObject
= (IROTData
*)&(This
->lpvtbl2
);
157 /* Check that we obtained an interface.*/
159 return E_NOINTERFACE
;
161 /* Query Interface always increases the reference count by one when it is successful */
162 ItemMonikerImpl_AddRef(iface
);
167 /******************************************************************************
169 ******************************************************************************/
170 ULONG WINAPI
ItemMonikerImpl_AddRef(IMoniker
* iface
)
172 ICOM_THIS(ItemMonikerImpl
,iface
);
174 TRACE("(%p)\n",This
);
176 return ++(This
->ref
);
179 /******************************************************************************
180 * ItemMoniker_Release
181 ******************************************************************************/
182 ULONG WINAPI
ItemMonikerImpl_Release(IMoniker
* iface
)
184 ICOM_THIS(ItemMonikerImpl
,iface
);
186 TRACE("(%p)\n",This
);
190 /* destroy the object if there's no more reference on it */
193 ItemMonikerImpl_Destroy(This
);
200 /******************************************************************************
201 * ItemMoniker_GetClassID
202 ******************************************************************************/
203 HRESULT WINAPI
ItemMonikerImpl_GetClassID(IMoniker
* iface
,CLSID
*pClassID
)
205 TRACE("(%p,%p),stub!\n",iface
,pClassID
);
210 *pClassID
= CLSID_ItemMoniker
;
215 /******************************************************************************
216 * ItemMoniker_IsDirty
217 ******************************************************************************/
218 HRESULT WINAPI
ItemMonikerImpl_IsDirty(IMoniker
* iface
)
220 /* Note that the OLE-provided implementations of the IPersistStream::IsDirty
221 method in the OLE-provided moniker interfaces always return S_FALSE because
222 their internal state never changes. */
224 TRACE("(%p)\n",iface
);
229 /******************************************************************************
231 ******************************************************************************/
232 HRESULT WINAPI
ItemMonikerImpl_Load(IMoniker
* iface
,IStream
* pStm
)
235 ICOM_THIS(ItemMonikerImpl
,iface
);
237 DWORD delimiterLength
,nameLength
;
238 CHAR
*itemNameA
,*itemDelimiterA
;
241 /* for more details about data read by this function see coments of ItemMonikerImpl_Save function */
243 /* read item delimiter string length + 1 */
244 res
=IStream_Read(pStm
,&delimiterLength
,sizeof(DWORD
),&bread
);
245 if (bread
!= sizeof(DWORD
))
248 /* read item delimiter string */
249 itemDelimiterA
=HeapAlloc(GetProcessHeap(),0,delimiterLength
);
250 res
=IStream_Read(pStm
,itemDelimiterA
,delimiterLength
,&bread
);
251 if (bread
!= delimiterLength
)
254 This
->itemDelimiter
=HeapReAlloc(GetProcessHeap(),0,This
->itemDelimiter
,delimiterLength
*sizeof(WCHAR
));
255 if (!This
->itemDelimiter
)
256 return E_OUTOFMEMORY
;
258 lstrcpyAtoW(This
->itemDelimiter
,itemDelimiterA
);
260 /* read item name string length + 1*/
261 res
=IStream_Read(pStm
,&nameLength
,sizeof(DWORD
),&bread
);
262 if (bread
!= sizeof(DWORD
))
265 /* read item name string */
266 itemNameA
=HeapAlloc(GetProcessHeap(),0,nameLength
);
267 res
=IStream_Read(pStm
,itemNameA
,nameLength
,&bread
);
268 if (bread
!= nameLength
)
271 This
->itemName
=HeapReAlloc(GetProcessHeap(),0,This
->itemName
,nameLength
*sizeof(WCHAR
));
273 return E_OUTOFMEMORY
;
275 lstrcpyAtoW(This
->itemName
,itemNameA
);
280 /******************************************************************************
282 ******************************************************************************/
283 HRESULT WINAPI
ItemMonikerImpl_Save(IMoniker
* iface
,
284 IStream
* pStm
,/* pointer to the stream where the object is to be saved */
285 BOOL fClearDirty
)/* Specifies whether to clear the dirty flag */
287 ICOM_THIS(ItemMonikerImpl
,iface
);
289 DWORD delimiterLength
=lstrlenW(This
->itemDelimiter
)+1;
290 DWORD nameLength
=lstrlenW(This
->itemName
)+1;
291 CHAR
*itemNameA
,*itemDelimiterA
;
293 /* data writen by this function are : 1) DWORD : size of item delimiter string ('\0' included ) */
294 /* 2) String (type A): item delimiter string ('\0' included) */
295 /* 3) DWORD : size of item name string ('\0' included) */
296 /* 4) String (type A): item name string ('\0' included) */
298 itemNameA
=HeapAlloc(GetProcessHeap(),0,nameLength
);
299 itemDelimiterA
=HeapAlloc(GetProcessHeap(),0,delimiterLength
);
300 lstrcpyWtoA(itemNameA
,This
->itemName
);
301 lstrcpyWtoA(itemDelimiterA
,This
->itemDelimiter
);
303 res
=IStream_Write(pStm
,&delimiterLength
,sizeof(DWORD
),NULL
);
304 res
=IStream_Write(pStm
,itemDelimiterA
,delimiterLength
* sizeof(CHAR
),NULL
);
305 res
=IStream_Write(pStm
,&nameLength
,sizeof(DWORD
),NULL
);
306 res
=IStream_Write(pStm
,itemNameA
,nameLength
* sizeof(CHAR
),NULL
);
311 /******************************************************************************
312 * ItemMoniker_GetSizeMax
313 ******************************************************************************/
314 HRESULT WINAPI
ItemMonikerImpl_GetSizeMax(IMoniker
* iface
,
315 ULARGE_INTEGER
* pcbSize
)/* Pointer to size of stream needed to save object */
317 ICOM_THIS(ItemMonikerImpl
,iface
);
318 DWORD delimiterLength
=lstrlenW(This
->itemDelimiter
)+1;
319 DWORD nameLength
=lstrlenW(This
->itemName
)+1;
321 TRACE("(%p,%p)\n",iface
,pcbSize
);
326 /* for more details see ItemMonikerImpl_Save coments */
328 pcbSize
->s
.LowPart
= sizeof(DWORD
) + /* DWORD witch contains delimiter length */
329 delimiterLength
+ /* item delimiter string */
330 sizeof(DWORD
) + /* DWORD witch contains item name length */
331 nameLength
+ /* item name string */
332 34; /* this constant was added ! because when I tested this function it usually */
333 /* returns 34 bytes more than the number of bytes used by IMoniker::Save function */
334 pcbSize
->s
.HighPart
=0;
339 /******************************************************************************
340 * ItemMoniker_Construct (local function)
341 *******************************************************************************/
342 HRESULT WINAPI
ItemMonikerImpl_Construct(ItemMonikerImpl
* This
, LPCOLESTR lpszDelim
,LPCOLESTR lpszItem
)
345 int sizeStr1
=lstrlenW(lpszItem
);
346 int sizeStr2
=lstrlenW(lpszDelim
);
348 TRACE("(%p,%p)\n",This
,lpszItem
);
350 /* Initialize the virtual fgunction table. */
351 This
->lpvtbl1
= &VT_ItemMonikerImpl
;
352 This
->lpvtbl2
= &VT_ROTDataImpl
;
355 This
->itemName
=HeapAlloc(GetProcessHeap(),0,sizeof(WCHAR
)*(sizeStr1
+1));
356 This
->itemDelimiter
=HeapAlloc(GetProcessHeap(),0,sizeof(WCHAR
)*(sizeStr2
+1));
358 if ((This
->itemName
==NULL
)||(This
->itemDelimiter
==NULL
))
359 return E_OUTOFMEMORY
;
361 strcpyW(This
->itemName
,lpszItem
);
362 strcpyW(This
->itemDelimiter
,lpszDelim
);
367 /******************************************************************************
368 * ItemMoniker_Destroy (local function)
369 *******************************************************************************/
370 HRESULT WINAPI
ItemMonikerImpl_Destroy(ItemMonikerImpl
* This
)
372 TRACE("(%p)\n",This
);
375 HeapFree(GetProcessHeap(),0,This
->itemName
);
377 if (This
->itemDelimiter
)
378 HeapFree(GetProcessHeap(),0,This
->itemDelimiter
);
380 HeapFree(GetProcessHeap(),0,This
);
385 /******************************************************************************
386 * ItemMoniker_BindToObject
387 ******************************************************************************/
388 HRESULT WINAPI
ItemMonikerImpl_BindToObject(IMoniker
* iface
,
394 ICOM_THIS(ItemMonikerImpl
,iface
);
397 IID refid
=IID_IOleItemContainer
;
398 IOleItemContainer
*poic
=0;
400 TRACE("(%p,%p,%p,%p,%p)\n",iface
,pbc
,pmkToLeft
,riid
,ppvResult
);
410 res
=IMoniker_BindToObject(pmkToLeft
,pbc
,NULL
,&refid
,(void**)&poic
);
414 res
=IOleItemContainer_GetObject(poic
,This
->itemName
,BINDSPEED_MODERATE
,pbc
,riid
,ppvResult
);
416 IOleItemContainer_Release(poic
);
422 /******************************************************************************
423 * ItemMoniker_BindToStorage
424 ******************************************************************************/
425 HRESULT WINAPI
ItemMonikerImpl_BindToStorage(IMoniker
* iface
,
431 ICOM_THIS(ItemMonikerImpl
,iface
);
434 IOleItemContainer
*poic
=0;
436 TRACE("(%p,%p,%p,%p,%p)\n",iface
,pbc
,pmkToLeft
,riid
,ppvResult
);
443 res
=IMoniker_BindToObject(pmkToLeft
,pbc
,NULL
,&IID_IOleItemContainer
,(void**)&poic
);
447 res
=IOleItemContainer_GetObjectStorage(poic
,This
->itemName
,pbc
,riid
,ppvResult
);
449 IOleItemContainer_Release(poic
);
455 /******************************************************************************
457 ******************************************************************************/
458 HRESULT WINAPI
ItemMonikerImpl_Reduce(IMoniker
* iface
,
460 DWORD dwReduceHowFar
,
461 IMoniker
** ppmkToLeft
,
462 IMoniker
** ppmkReduced
)
464 TRACE("(%p,%p,%ld,%p,%p)\n",iface
,pbc
,dwReduceHowFar
,ppmkToLeft
,ppmkReduced
);
466 if (ppmkReduced
==NULL
)
469 ItemMonikerImpl_AddRef(iface
);
473 return MK_S_REDUCED_TO_SELF
;
475 /******************************************************************************
476 * ItemMoniker_ComposeWith
477 ******************************************************************************/
478 HRESULT WINAPI
ItemMonikerImpl_ComposeWith(IMoniker
* iface
,
480 BOOL fOnlyIfNotGeneric
,
481 IMoniker
** ppmkComposite
)
485 IEnumMoniker
* penumMk
=0;
486 IMoniker
*pmostLeftMk
=0;
487 IMoniker
* tempMkComposite
=0;
489 TRACE("(%p,%p,%d,%p)\n",iface
,pmkRight
,fOnlyIfNotGeneric
,ppmkComposite
);
491 if ((ppmkComposite
==NULL
)||(pmkRight
==NULL
))
496 IMoniker_IsSystemMoniker(pmkRight
,&mkSys
);
498 /* If pmkRight is an anti-moniker, the returned moniker is NULL */
499 if(mkSys
==MKSYS_ANTIMONIKER
)
503 /* if pmkRight is a composite whose leftmost component is an anti-moniker, */
504 /* the returned moniker is the composite after the leftmost anti-moniker is removed. */
506 if(mkSys
==MKSYS_GENERICCOMPOSITE
){
508 res
=IMoniker_Enum(pmkRight
,TRUE
,&penumMk
);
513 res
=IEnumMoniker_Next(penumMk
,1,&pmostLeftMk
,NULL
);
515 IMoniker_IsSystemMoniker(pmostLeftMk
,&mkSys2
);
517 if(mkSys2
==MKSYS_ANTIMONIKER
){
519 IMoniker_Release(pmostLeftMk
);
521 tempMkComposite
=iface
;
522 IMoniker_AddRef(iface
);
524 while(IEnumMoniker_Next(penumMk
,1,&pmostLeftMk
,NULL
)==S_OK
){
526 res
=CreateGenericComposite(tempMkComposite
,pmostLeftMk
,ppmkComposite
);
528 IMoniker_Release(tempMkComposite
);
529 IMoniker_Release(pmostLeftMk
);
531 tempMkComposite
=*ppmkComposite
;
532 IMoniker_AddRef(tempMkComposite
);
537 return CreateGenericComposite(iface
,pmkRight
,ppmkComposite
);
539 /* If pmkRight is not an anti-moniker, the method combines the two monikers into a generic
540 composite if fOnlyIfNotGeneric is FALSE; if fOnlyIfNotGeneric is TRUE, the method returns
541 a NULL moniker and a return value of MK_E_NEEDGENERIC */
543 if (!fOnlyIfNotGeneric
)
544 return CreateGenericComposite(iface
,pmkRight
,ppmkComposite
);
547 return MK_E_NEEDGENERIC
;
550 /******************************************************************************
552 ******************************************************************************/
553 HRESULT WINAPI
ItemMonikerImpl_Enum(IMoniker
* iface
,BOOL fForward
, IEnumMoniker
** ppenumMoniker
)
555 TRACE("(%p,%d,%p)\n",iface
,fForward
,ppenumMoniker
);
557 if (ppenumMoniker
== NULL
)
560 *ppenumMoniker
= NULL
;
565 /******************************************************************************
566 * ItemMoniker_IsEqual
567 ******************************************************************************/
568 HRESULT WINAPI
ItemMonikerImpl_IsEqual(IMoniker
* iface
,IMoniker
* pmkOtherMoniker
)
572 LPOLESTR dispName1
,dispName2
;
576 TRACE("(%p,%p)\n",iface
,pmkOtherMoniker
);
578 if (pmkOtherMoniker
==NULL
)
581 /* This method returns S_OK if both monikers are item monikers and their display names are */
582 /* identical (using a case-insensitive comparison); otherwise, the method returns S_FALSE. */
584 IMoniker_GetClassID(pmkOtherMoniker
,&clsid
);
586 if (!IsEqualCLSID(&clsid
,&CLSID_ItemMoniker
))
589 res
=CreateBindCtx(0,&bind
);
593 IMoniker_GetDisplayName(iface
,bind
,NULL
,&dispName1
);
594 IMoniker_GetDisplayName(pmkOtherMoniker
,bind
,NULL
,&dispName2
);
596 if (lstrcmpW(dispName1
,dispName2
)!=0)
602 /******************************************************************************
604 ******************************************************************************/
605 HRESULT WINAPI
ItemMonikerImpl_Hash(IMoniker
* iface
,DWORD
* pdwHash
)
607 ICOM_THIS(ItemMonikerImpl
,iface
);
609 int h
= 0,i
,skip
,len
;
616 val
= This
->itemName
;
620 for (i
= len
; i
> 0; i
--) {
621 h
= (h
* 37) + val
[off
++];
624 /* only sample some characters */
626 for (i
= len
; i
> 0; i
-= skip
, off
+= skip
) {
627 h
= (h
* 39) + val
[off
];
636 /******************************************************************************
637 * ItemMoniker_IsRunning
638 ******************************************************************************/
639 HRESULT WINAPI
ItemMonikerImpl_IsRunning(IMoniker
* iface
,
642 IMoniker
* pmkNewlyRunning
)
644 IRunningObjectTable
* rot
;
646 IOleItemContainer
*poic
=0;
647 ICOM_THIS(ItemMonikerImpl
,iface
);
649 TRACE("(%p,%p,%p,%p)\n",iface
,pbc
,pmkToLeft
,pmkNewlyRunning
);
651 /* If pmkToLeft is NULL, this method returns TRUE if pmkNewlyRunning is non-NULL and is equal to this */
652 /* moniker. Otherwise, the method checks the ROT to see whether this moniker is running. */
654 if ((pmkNewlyRunning
!=NULL
)&&(IMoniker_IsEqual(pmkNewlyRunning
,iface
)==S_OK
))
660 res
=IBindCtx_GetRunningObjectTable(pbc
,&rot
);
665 res
= IRunningObjectTable_IsRunning(rot
,iface
);
667 IRunningObjectTable_Release(rot
);
671 /* If pmkToLeft is non-NULL, the method calls IMoniker::BindToObject on the pmkToLeft parameter, */
672 /* requesting an IOleItemContainer interface pointer. The method then calls IOleItemContainer::IsRunning,*/
673 /* passing the string contained within this moniker. */
675 res
=IMoniker_BindToObject(pmkToLeft
,pbc
,NULL
,&IID_IOleItemContainer
,(void**)&poic
);
679 res
=IOleItemContainer_IsRunning(poic
,This
->itemName
);
681 IOleItemContainer_Release(poic
);
688 /******************************************************************************
689 * ItemMoniker_GetTimeOfLastChange
690 ******************************************************************************/
691 HRESULT WINAPI
ItemMonikerImpl_GetTimeOfLastChange(IMoniker
* iface
,
696 IRunningObjectTable
* rot
;
698 IMoniker
*compositeMk
;
700 TRACE("(%p,%p,%p,%p)\n",iface
,pbc
,pmkToLeft
,pItemTime
);
705 /* If pmkToLeft is NULL, this method returns MK_E_NOTBINDABLE */
708 return MK_E_NOTBINDABLE
;
711 /* Otherwise, the method creates a composite of pmkToLeft and this moniker and uses the ROT to access */
712 /* the time of last change. If the object is not in the ROT, the method calls */
713 /* IMoniker::GetTimeOfLastChange on the pmkToLeft parameter. */
715 res
=CreateGenericComposite(pmkToLeft
,iface
,&compositeMk
);
717 res
=IBindCtx_GetRunningObjectTable(pbc
,&rot
);
719 if (IRunningObjectTable_GetTimeOfLastChange(rot
,compositeMk
,pItemTime
)!=S_OK
)
721 res
=IMoniker_GetTimeOfLastChange(pmkToLeft
,pbc
,NULL
,pItemTime
);
723 IMoniker_Release(compositeMk
);
729 /******************************************************************************
730 * ItemMoniker_Inverse
731 ******************************************************************************/
732 HRESULT WINAPI
ItemMonikerImpl_Inverse(IMoniker
* iface
,IMoniker
** ppmk
)
734 TRACE("(%p,%p)\n",iface
,ppmk
);
739 return CreateAntiMoniker(ppmk
);
742 /******************************************************************************
743 * ItemMoniker_CommonPrefixWith
744 ******************************************************************************/
745 HRESULT WINAPI
ItemMonikerImpl_CommonPrefixWith(IMoniker
* iface
,IMoniker
* pmkOther
,IMoniker
** ppmkPrefix
)
748 IMoniker_IsSystemMoniker(pmkOther
,&mkSys
);
749 /* If the other moniker is an item moniker that is equal to this moniker, this method sets *ppmkPrefix */
750 /* to this moniker and returns MK_S_US */
752 if((mkSys
==MKSYS_ITEMMONIKER
) && (IMoniker_IsEqual(iface
,pmkOther
)==S_OK
) ){
756 IMoniker_AddRef(iface
);
761 /* otherwise, the method calls the MonikerCommonPrefixWith function. This function correctly handles */
762 /* the case where the other moniker is a generic composite. */
763 return MonikerCommonPrefixWith(iface
,pmkOther
,ppmkPrefix
);
766 /******************************************************************************
767 * ItemMoniker_RelativePathTo
768 ******************************************************************************/
769 HRESULT WINAPI
ItemMonikerImpl_RelativePathTo(IMoniker
* iface
,IMoniker
* pmOther
, IMoniker
** ppmkRelPath
)
771 TRACE("(%p,%p,%p)\n",iface
,pmOther
,ppmkRelPath
);
773 if (ppmkRelPath
==NULL
)
778 return MK_E_NOTBINDABLE
;
781 /******************************************************************************
782 * ItemMoniker_GetDisplayName
783 ******************************************************************************/
784 HRESULT WINAPI
ItemMonikerImpl_GetDisplayName(IMoniker
* iface
,
787 LPOLESTR
*ppszDisplayName
)
789 ICOM_THIS(ItemMonikerImpl
,iface
);
791 TRACE("(%p,%p,%p,%p)\n",iface
,pbc
,pmkToLeft
,ppszDisplayName
);
793 if (ppszDisplayName
==NULL
)
796 if (pmkToLeft
!=NULL
){
800 *ppszDisplayName
=CoTaskMemAlloc(sizeof(WCHAR
)*(lstrlenW(This
->itemDelimiter
)+lstrlenW(This
->itemName
)+1));
802 if (*ppszDisplayName
==NULL
)
803 return E_OUTOFMEMORY
;
805 strcpyW(*ppszDisplayName
,This
->itemDelimiter
);
806 strcatW(*ppszDisplayName
,This
->itemName
);
811 /******************************************************************************
812 * ItemMoniker_ParseDisplayName
813 ******************************************************************************/
814 HRESULT WINAPI
ItemMonikerImpl_ParseDisplayName(IMoniker
* iface
,
817 LPOLESTR pszDisplayName
,
821 IOleItemContainer
* poic
=0;
822 IParseDisplayName
* ppdn
=0;
823 LPOLESTR displayName
;
825 ICOM_THIS(ItemMonikerImpl
,iface
);
827 /* If pmkToLeft is NULL, this method returns MK_E_SYNTAX */
833 /* Otherwise, the method calls IMoniker::BindToObject on the pmkToLeft parameter, requesting an */
834 /* IParseDisplayName interface pointer to the object identified by the moniker, and passes the display */ /* name to IParseDisplayName::ParseDisplayName */
835 res
=IMoniker_BindToObject(pmkToLeft
,pbc
,NULL
,&IID_IOleItemContainer
,(void**)&poic
);
839 res
=IOleItemContainer_GetObject(poic
,This
->itemName
,BINDSPEED_MODERATE
,pbc
,&IID_IParseDisplayName
,(void**)&ppdn
);
841 res
=IMoniker_GetDisplayName(iface
,pbc
,NULL
,&displayName
);
843 res
=IParseDisplayName_ParseDisplayName(ppdn
,pbc
,displayName
,pchEaten
,ppmkOut
);
845 IOleItemContainer_Release(poic
);
846 IParseDisplayName_Release(ppdn
);
852 /******************************************************************************
853 * ItemMoniker_IsSystemMonker
854 ******************************************************************************/
855 HRESULT WINAPI
ItemMonikerImpl_IsSystemMoniker(IMoniker
* iface
,DWORD
* pwdMksys
)
857 TRACE("(%p,%p)\n",iface
,pwdMksys
);
862 (*pwdMksys
)=MKSYS_ITEMMONIKER
;
867 /*******************************************************************************
868 * ItemMonikerIROTData_QueryInterface
869 *******************************************************************************/
870 HRESULT WINAPI
ItemMonikerROTDataImpl_QueryInterface(IROTData
*iface
,REFIID riid
,VOID
** ppvObject
)
873 ICOM_THIS_From_IROTData(IMoniker
, iface
);
875 TRACE("(%p,%p,%p)\n",iface
,riid
,ppvObject
);
877 return ItemMonikerImpl_QueryInterface(This
, riid
, ppvObject
);
880 /***********************************************************************
881 * ItemMonikerIROTData_AddRef
883 ULONG WINAPI
ItemMonikerROTDataImpl_AddRef(IROTData
*iface
)
885 ICOM_THIS_From_IROTData(IMoniker
, iface
);
887 TRACE("(%p)\n",iface
);
889 return ItemMonikerImpl_AddRef(This
);
892 /***********************************************************************
893 * ItemMonikerIROTData_Release
895 ULONG WINAPI
ItemMonikerROTDataImpl_Release(IROTData
* iface
)
897 ICOM_THIS_From_IROTData(IMoniker
, iface
);
899 TRACE("(%p)\n",iface
);
901 return ItemMonikerImpl_Release(This
);
904 /******************************************************************************
905 * ItemMonikerIROTData_GetComparaisonData
906 ******************************************************************************/
907 HRESULT WINAPI
ItemMonikerROTDataImpl_GetComparaisonData(IROTData
* iface
,
916 /******************************************************************************
917 * CreateItemMoniker16 [OLE2.28]
918 ******************************************************************************/
919 HRESULT WINAPI
CreateItemMoniker16(LPCOLESTR16 lpszDelim
,LPCOLESTR lpszItem
,LPMONIKER
* ppmk
)
922 FIXME("(%s,%p),stub!\n",lpszDelim
,ppmk
);
927 /******************************************************************************
928 * CreateItemMoniker [OLE.55]
929 ******************************************************************************/
930 HRESULT WINAPI
CreateItemMoniker(LPCOLESTR lpszDelim
,LPCOLESTR lpszItem
, LPMONIKER
* ppmk
)
932 ItemMonikerImpl
* newItemMoniker
= 0;
934 IID riid
=IID_IMoniker
;
936 TRACE("(%p,%p,%p)\n",lpszDelim
,lpszItem
,ppmk
);
938 newItemMoniker
= HeapAlloc(GetProcessHeap(), 0, sizeof(ItemMonikerImpl
));
940 if (newItemMoniker
== 0)
941 return STG_E_INSUFFICIENTMEMORY
;
943 hr
= ItemMonikerImpl_Construct(newItemMoniker
,lpszDelim
,lpszItem
);
947 HeapFree(GetProcessHeap(),0,newItemMoniker
);
951 return ItemMonikerImpl_QueryInterface((IMoniker
*)newItemMoniker
,&riid
,(void**)ppmk
);