1 /***************************************************************************************
2 * ItemMonikers implementation
4 * Copyright 1999 Noomen Hamza
5 ***************************************************************************************/
11 #include "debugtools.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,lenW;
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 if (!(itemDelimiterA=HeapAlloc(GetProcessHeap(),0,delimiterLength)))
250 return E_OUTOFMEMORY;
251 res=IStream_Read(pStm,itemDelimiterA,delimiterLength,&bread);
252 if (bread != delimiterLength)
254 HeapFree( GetProcessHeap(), 0, itemDelimiterA );
258 lenW = MultiByteToWideChar( CP_ACP, 0, itemDelimiterA, -1, NULL, 0 );
259 This->itemDelimiter=HeapReAlloc(GetProcessHeap(),0,This->itemDelimiter,lenW*sizeof(WCHAR));
260 if (!This->itemDelimiter)
262 HeapFree( GetProcessHeap(), 0, itemDelimiterA );
263 return E_OUTOFMEMORY;
265 MultiByteToWideChar( CP_ACP, 0, itemDelimiterA, -1, This->itemDelimiter, lenW );
266 HeapFree( GetProcessHeap(), 0, itemDelimiterA );
268 /* read item name string length + 1*/
269 res=IStream_Read(pStm,&nameLength,sizeof(DWORD),&bread);
270 if (bread != sizeof(DWORD))
273 /* read item name string */
274 if (!(itemNameA=HeapAlloc(GetProcessHeap(),0,nameLength)))
275 return E_OUTOFMEMORY;
276 res=IStream_Read(pStm,itemNameA,nameLength,&bread);
277 if (bread != nameLength)
279 HeapFree( GetProcessHeap(), 0, itemNameA );
283 lenW = MultiByteToWideChar( CP_ACP, 0, itemNameA, -1, NULL, 0 );
284 This->itemName=HeapReAlloc(GetProcessHeap(),0,This->itemName,lenW*sizeof(WCHAR));
287 HeapFree( GetProcessHeap(), 0, itemNameA );
288 return E_OUTOFMEMORY;
290 MultiByteToWideChar( CP_ACP, 0, itemNameA, -1, This->itemName, lenW );
291 HeapFree( GetProcessHeap(), 0, itemNameA );
296 /******************************************************************************
298 ******************************************************************************/
299 HRESULT WINAPI ItemMonikerImpl_Save(IMoniker* iface,
300 IStream* pStm,/* pointer to the stream where the object is to be saved */
301 BOOL fClearDirty)/* Specifies whether to clear the dirty flag */
303 ICOM_THIS(ItemMonikerImpl,iface);
305 CHAR *itemNameA,*itemDelimiterA;
307 /* data writen by this function are : 1) DWORD : size of item delimiter string ('\0' included ) */
308 /* 2) String (type A): item delimiter string ('\0' included) */
309 /* 3) DWORD : size of item name string ('\0' included) */
310 /* 4) String (type A): item name string ('\0' included) */
312 DWORD nameLength = WideCharToMultiByte( CP_ACP, 0, This->itemName, -1, NULL, 0, NULL, NULL);
313 DWORD delimiterLength = WideCharToMultiByte( CP_ACP, 0, This->itemDelimiter, -1, NULL, 0, NULL, NULL);
314 itemNameA=HeapAlloc(GetProcessHeap(),0,nameLength);
315 itemDelimiterA=HeapAlloc(GetProcessHeap(),0,delimiterLength);
316 WideCharToMultiByte( CP_ACP, 0, This->itemName, -1, itemNameA, nameLength, NULL, NULL);
317 WideCharToMultiByte( CP_ACP, 0, This->itemDelimiter, -1, itemDelimiterA, delimiterLength, NULL, NULL);
319 res=IStream_Write(pStm,&delimiterLength,sizeof(DWORD),NULL);
320 res=IStream_Write(pStm,itemDelimiterA,delimiterLength * sizeof(CHAR),NULL);
321 res=IStream_Write(pStm,&nameLength,sizeof(DWORD),NULL);
322 res=IStream_Write(pStm,itemNameA,nameLength * sizeof(CHAR),NULL);
327 /******************************************************************************
328 * ItemMoniker_GetSizeMax
329 ******************************************************************************/
330 HRESULT WINAPI ItemMonikerImpl_GetSizeMax(IMoniker* iface,
331 ULARGE_INTEGER* pcbSize)/* Pointer to size of stream needed to save object */
333 ICOM_THIS(ItemMonikerImpl,iface);
334 DWORD delimiterLength=lstrlenW(This->itemDelimiter)+1;
335 DWORD nameLength=lstrlenW(This->itemName)+1;
337 TRACE("(%p,%p)\n",iface,pcbSize);
342 /* for more details see ItemMonikerImpl_Save coments */
344 pcbSize->s.LowPart = sizeof(DWORD) + /* DWORD witch contains delimiter length */
345 delimiterLength + /* item delimiter string */
346 sizeof(DWORD) + /* DWORD witch contains item name length */
347 nameLength + /* item name string */
348 34; /* this constant was added ! because when I tested this function it usually */
349 /* returns 34 bytes more than the number of bytes used by IMoniker::Save function */
350 pcbSize->s.HighPart=0;
355 /******************************************************************************
356 * ItemMoniker_Construct (local function)
357 *******************************************************************************/
358 HRESULT WINAPI ItemMonikerImpl_Construct(ItemMonikerImpl* This, LPCOLESTR lpszDelim,LPCOLESTR lpszItem)
361 int sizeStr1=lstrlenW(lpszItem), sizeStr2;
362 static const OLECHAR emptystr[1];
365 TRACE("(%p,%p)\n",This,lpszItem);
367 /* Initialize the virtual fgunction table. */
368 This->lpvtbl1 = &VT_ItemMonikerImpl;
369 This->lpvtbl2 = &VT_ROTDataImpl;
372 This->itemName=HeapAlloc(GetProcessHeap(),0,sizeof(WCHAR)*(sizeStr1+1));
374 return E_OUTOFMEMORY;
375 strcpyW(This->itemName,lpszItem);
378 FIXME("lpszDelim is NULL. Using empty string which is possibly wrong.\n");
380 delim = lpszDelim ? lpszDelim : emptystr;
382 sizeStr2=strlenW(delim);
383 This->itemDelimiter=HeapAlloc(GetProcessHeap(),0,sizeof(WCHAR)*(sizeStr2+1));
384 if (!This->itemDelimiter) {
385 HeapFree(GetProcessHeap(),0,This->itemName);
386 return E_OUTOFMEMORY;
388 strcpyW(This->itemDelimiter,delim);
392 /******************************************************************************
393 * ItemMoniker_Destroy (local function)
394 *******************************************************************************/
395 HRESULT WINAPI ItemMonikerImpl_Destroy(ItemMonikerImpl* This)
397 TRACE("(%p)\n",This);
400 HeapFree(GetProcessHeap(),0,This->itemName);
402 if (This->itemDelimiter)
403 HeapFree(GetProcessHeap(),0,This->itemDelimiter);
405 HeapFree(GetProcessHeap(),0,This);
410 /******************************************************************************
411 * ItemMoniker_BindToObject
412 ******************************************************************************/
413 HRESULT WINAPI ItemMonikerImpl_BindToObject(IMoniker* iface,
419 ICOM_THIS(ItemMonikerImpl,iface);
422 IID refid=IID_IOleItemContainer;
423 IOleItemContainer *poic=0;
425 TRACE("(%p,%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,riid,ppvResult);
435 res=IMoniker_BindToObject(pmkToLeft,pbc,NULL,&refid,(void**)&poic);
439 res=IOleItemContainer_GetObject(poic,This->itemName,BINDSPEED_MODERATE,pbc,riid,ppvResult);
441 IOleItemContainer_Release(poic);
447 /******************************************************************************
448 * ItemMoniker_BindToStorage
449 ******************************************************************************/
450 HRESULT WINAPI ItemMonikerImpl_BindToStorage(IMoniker* iface,
456 ICOM_THIS(ItemMonikerImpl,iface);
459 IOleItemContainer *poic=0;
461 TRACE("(%p,%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,riid,ppvResult);
468 res=IMoniker_BindToObject(pmkToLeft,pbc,NULL,&IID_IOleItemContainer,(void**)&poic);
472 res=IOleItemContainer_GetObjectStorage(poic,This->itemName,pbc,riid,ppvResult);
474 IOleItemContainer_Release(poic);
480 /******************************************************************************
482 ******************************************************************************/
483 HRESULT WINAPI ItemMonikerImpl_Reduce(IMoniker* iface,
485 DWORD dwReduceHowFar,
486 IMoniker** ppmkToLeft,
487 IMoniker** ppmkReduced)
489 TRACE("(%p,%p,%ld,%p,%p)\n",iface,pbc,dwReduceHowFar,ppmkToLeft,ppmkReduced);
491 if (ppmkReduced==NULL)
494 ItemMonikerImpl_AddRef(iface);
498 return MK_S_REDUCED_TO_SELF;
500 /******************************************************************************
501 * ItemMoniker_ComposeWith
502 ******************************************************************************/
503 HRESULT WINAPI ItemMonikerImpl_ComposeWith(IMoniker* iface,
505 BOOL fOnlyIfNotGeneric,
506 IMoniker** ppmkComposite)
510 IEnumMoniker* penumMk=0;
511 IMoniker *pmostLeftMk=0;
512 IMoniker* tempMkComposite=0;
514 TRACE("(%p,%p,%d,%p)\n",iface,pmkRight,fOnlyIfNotGeneric,ppmkComposite);
516 if ((ppmkComposite==NULL)||(pmkRight==NULL))
521 IMoniker_IsSystemMoniker(pmkRight,&mkSys);
523 /* If pmkRight is an anti-moniker, the returned moniker is NULL */
524 if(mkSys==MKSYS_ANTIMONIKER)
528 /* if pmkRight is a composite whose leftmost component is an anti-moniker, */
529 /* the returned moniker is the composite after the leftmost anti-moniker is removed. */
531 if(mkSys==MKSYS_GENERICCOMPOSITE){
533 res=IMoniker_Enum(pmkRight,TRUE,&penumMk);
538 res=IEnumMoniker_Next(penumMk,1,&pmostLeftMk,NULL);
540 IMoniker_IsSystemMoniker(pmostLeftMk,&mkSys2);
542 if(mkSys2==MKSYS_ANTIMONIKER){
544 IMoniker_Release(pmostLeftMk);
546 tempMkComposite=iface;
547 IMoniker_AddRef(iface);
549 while(IEnumMoniker_Next(penumMk,1,&pmostLeftMk,NULL)==S_OK){
551 res=CreateGenericComposite(tempMkComposite,pmostLeftMk,ppmkComposite);
553 IMoniker_Release(tempMkComposite);
554 IMoniker_Release(pmostLeftMk);
556 tempMkComposite=*ppmkComposite;
557 IMoniker_AddRef(tempMkComposite);
562 return CreateGenericComposite(iface,pmkRight,ppmkComposite);
564 /* If pmkRight is not an anti-moniker, the method combines the two monikers into a generic
565 composite if fOnlyIfNotGeneric is FALSE; if fOnlyIfNotGeneric is TRUE, the method returns
566 a NULL moniker and a return value of MK_E_NEEDGENERIC */
568 if (!fOnlyIfNotGeneric)
569 return CreateGenericComposite(iface,pmkRight,ppmkComposite);
572 return MK_E_NEEDGENERIC;
575 /******************************************************************************
577 ******************************************************************************/
578 HRESULT WINAPI ItemMonikerImpl_Enum(IMoniker* iface,BOOL fForward, IEnumMoniker** ppenumMoniker)
580 TRACE("(%p,%d,%p)\n",iface,fForward,ppenumMoniker);
582 if (ppenumMoniker == NULL)
585 *ppenumMoniker = NULL;
590 /******************************************************************************
591 * ItemMoniker_IsEqual
592 ******************************************************************************/
593 HRESULT WINAPI ItemMonikerImpl_IsEqual(IMoniker* iface,IMoniker* pmkOtherMoniker)
597 LPOLESTR dispName1,dispName2;
601 TRACE("(%p,%p)\n",iface,pmkOtherMoniker);
603 if (pmkOtherMoniker==NULL)
606 /* This method returns S_OK if both monikers are item monikers and their display names are */
607 /* identical (using a case-insensitive comparison); otherwise, the method returns S_FALSE. */
609 IMoniker_GetClassID(pmkOtherMoniker,&clsid);
611 if (!IsEqualCLSID(&clsid,&CLSID_ItemMoniker))
614 res=CreateBindCtx(0,&bind);
618 IMoniker_GetDisplayName(iface,bind,NULL,&dispName1);
619 IMoniker_GetDisplayName(pmkOtherMoniker,bind,NULL,&dispName2);
621 if (lstrcmpW(dispName1,dispName2)!=0)
627 /******************************************************************************
629 ******************************************************************************/
630 HRESULT WINAPI ItemMonikerImpl_Hash(IMoniker* iface,DWORD* pdwHash)
632 ICOM_THIS(ItemMonikerImpl,iface);
634 int h = 0,i,skip,len;
641 val = This->itemName;
645 for (i = len ; i > 0; i--) {
646 h = (h * 37) + val[off++];
649 /* only sample some characters */
651 for (i = len ; i > 0; i -= skip, off += skip) {
652 h = (h * 39) + val[off];
661 /******************************************************************************
662 * ItemMoniker_IsRunning
663 ******************************************************************************/
664 HRESULT WINAPI ItemMonikerImpl_IsRunning(IMoniker* iface,
667 IMoniker* pmkNewlyRunning)
669 IRunningObjectTable* rot;
671 IOleItemContainer *poic=0;
672 ICOM_THIS(ItemMonikerImpl,iface);
674 TRACE("(%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,pmkNewlyRunning);
676 /* If pmkToLeft is NULL, this method returns TRUE if pmkNewlyRunning is non-NULL and is equal to this */
677 /* moniker. Otherwise, the method checks the ROT to see whether this moniker is running. */
679 if ((pmkNewlyRunning!=NULL)&&(IMoniker_IsEqual(pmkNewlyRunning,iface)==S_OK))
685 res=IBindCtx_GetRunningObjectTable(pbc,&rot);
690 res = IRunningObjectTable_IsRunning(rot,iface);
692 IRunningObjectTable_Release(rot);
696 /* If pmkToLeft is non-NULL, the method calls IMoniker::BindToObject on the pmkToLeft parameter, */
697 /* requesting an IOleItemContainer interface pointer. The method then calls IOleItemContainer::IsRunning,*/
698 /* passing the string contained within this moniker. */
700 res=IMoniker_BindToObject(pmkToLeft,pbc,NULL,&IID_IOleItemContainer,(void**)&poic);
704 res=IOleItemContainer_IsRunning(poic,This->itemName);
706 IOleItemContainer_Release(poic);
713 /******************************************************************************
714 * ItemMoniker_GetTimeOfLastChange
715 ******************************************************************************/
716 HRESULT WINAPI ItemMonikerImpl_GetTimeOfLastChange(IMoniker* iface,
721 IRunningObjectTable* rot;
723 IMoniker *compositeMk;
725 TRACE("(%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,pItemTime);
730 /* If pmkToLeft is NULL, this method returns MK_E_NOTBINDABLE */
733 return MK_E_NOTBINDABLE;
736 /* Otherwise, the method creates a composite of pmkToLeft and this moniker and uses the ROT to access */
737 /* the time of last change. If the object is not in the ROT, the method calls */
738 /* IMoniker::GetTimeOfLastChange on the pmkToLeft parameter. */
740 res=CreateGenericComposite(pmkToLeft,iface,&compositeMk);
742 res=IBindCtx_GetRunningObjectTable(pbc,&rot);
744 if (IRunningObjectTable_GetTimeOfLastChange(rot,compositeMk,pItemTime)!=S_OK)
746 res=IMoniker_GetTimeOfLastChange(pmkToLeft,pbc,NULL,pItemTime);
748 IMoniker_Release(compositeMk);
754 /******************************************************************************
755 * ItemMoniker_Inverse
756 ******************************************************************************/
757 HRESULT WINAPI ItemMonikerImpl_Inverse(IMoniker* iface,IMoniker** ppmk)
759 TRACE("(%p,%p)\n",iface,ppmk);
764 return CreateAntiMoniker(ppmk);
767 /******************************************************************************
768 * ItemMoniker_CommonPrefixWith
769 ******************************************************************************/
770 HRESULT WINAPI ItemMonikerImpl_CommonPrefixWith(IMoniker* iface,IMoniker* pmkOther,IMoniker** ppmkPrefix)
773 IMoniker_IsSystemMoniker(pmkOther,&mkSys);
774 /* If the other moniker is an item moniker that is equal to this moniker, this method sets *ppmkPrefix */
775 /* to this moniker and returns MK_S_US */
777 if((mkSys==MKSYS_ITEMMONIKER) && (IMoniker_IsEqual(iface,pmkOther)==S_OK) ){
781 IMoniker_AddRef(iface);
786 /* otherwise, the method calls the MonikerCommonPrefixWith function. This function correctly handles */
787 /* the case where the other moniker is a generic composite. */
788 return MonikerCommonPrefixWith(iface,pmkOther,ppmkPrefix);
791 /******************************************************************************
792 * ItemMoniker_RelativePathTo
793 ******************************************************************************/
794 HRESULT WINAPI ItemMonikerImpl_RelativePathTo(IMoniker* iface,IMoniker* pmOther, IMoniker** ppmkRelPath)
796 TRACE("(%p,%p,%p)\n",iface,pmOther,ppmkRelPath);
798 if (ppmkRelPath==NULL)
803 return MK_E_NOTBINDABLE;
806 /******************************************************************************
807 * ItemMoniker_GetDisplayName
808 ******************************************************************************/
809 HRESULT WINAPI ItemMonikerImpl_GetDisplayName(IMoniker* iface,
812 LPOLESTR *ppszDisplayName)
814 ICOM_THIS(ItemMonikerImpl,iface);
816 TRACE("(%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,ppszDisplayName);
818 if (ppszDisplayName==NULL)
821 if (pmkToLeft!=NULL){
825 *ppszDisplayName=CoTaskMemAlloc(sizeof(WCHAR)*(lstrlenW(This->itemDelimiter)+lstrlenW(This->itemName)+1));
827 if (*ppszDisplayName==NULL)
828 return E_OUTOFMEMORY;
830 strcpyW(*ppszDisplayName,This->itemDelimiter);
831 strcatW(*ppszDisplayName,This->itemName);
836 /******************************************************************************
837 * ItemMoniker_ParseDisplayName
838 ******************************************************************************/
839 HRESULT WINAPI ItemMonikerImpl_ParseDisplayName(IMoniker* iface,
842 LPOLESTR pszDisplayName,
846 IOleItemContainer* poic=0;
847 IParseDisplayName* ppdn=0;
848 LPOLESTR displayName;
850 ICOM_THIS(ItemMonikerImpl,iface);
852 /* If pmkToLeft is NULL, this method returns MK_E_SYNTAX */
858 /* Otherwise, the method calls IMoniker::BindToObject on the pmkToLeft parameter, requesting an */
859 /* IParseDisplayName interface pointer to the object identified by the moniker, and passes the display */ /* name to IParseDisplayName::ParseDisplayName */
860 res=IMoniker_BindToObject(pmkToLeft,pbc,NULL,&IID_IOleItemContainer,(void**)&poic);
864 res=IOleItemContainer_GetObject(poic,This->itemName,BINDSPEED_MODERATE,pbc,&IID_IParseDisplayName,(void**)&ppdn);
866 res=IMoniker_GetDisplayName(iface,pbc,NULL,&displayName);
868 res=IParseDisplayName_ParseDisplayName(ppdn,pbc,displayName,pchEaten,ppmkOut);
870 IOleItemContainer_Release(poic);
871 IParseDisplayName_Release(ppdn);
877 /******************************************************************************
878 * ItemMoniker_IsSystemMonker
879 ******************************************************************************/
880 HRESULT WINAPI ItemMonikerImpl_IsSystemMoniker(IMoniker* iface,DWORD* pwdMksys)
882 TRACE("(%p,%p)\n",iface,pwdMksys);
887 (*pwdMksys)=MKSYS_ITEMMONIKER;
892 /*******************************************************************************
893 * ItemMonikerIROTData_QueryInterface
894 *******************************************************************************/
895 HRESULT WINAPI ItemMonikerROTDataImpl_QueryInterface(IROTData *iface,REFIID riid,VOID** ppvObject)
898 ICOM_THIS_From_IROTData(IMoniker, iface);
900 TRACE("(%p,%p,%p)\n",iface,riid,ppvObject);
902 return ItemMonikerImpl_QueryInterface(This, riid, ppvObject);
905 /***********************************************************************
906 * ItemMonikerIROTData_AddRef
908 ULONG WINAPI ItemMonikerROTDataImpl_AddRef(IROTData *iface)
910 ICOM_THIS_From_IROTData(IMoniker, iface);
912 TRACE("(%p)\n",iface);
914 return ItemMonikerImpl_AddRef(This);
917 /***********************************************************************
918 * ItemMonikerIROTData_Release
920 ULONG WINAPI ItemMonikerROTDataImpl_Release(IROTData* iface)
922 ICOM_THIS_From_IROTData(IMoniker, iface);
924 TRACE("(%p)\n",iface);
926 return ItemMonikerImpl_Release(This);
929 /******************************************************************************
930 * ItemMonikerIROTData_GetComparaisonData
931 ******************************************************************************/
932 HRESULT WINAPI ItemMonikerROTDataImpl_GetComparaisonData(IROTData* iface,
941 /******************************************************************************
942 * CreateItemMoniker16 [OLE2.28]
943 ******************************************************************************/
944 HRESULT WINAPI CreateItemMoniker16(LPCOLESTR16 lpszDelim,LPCOLESTR lpszItem,LPMONIKER* ppmk)
947 FIXME("(%s,%p),stub!\n",lpszDelim,ppmk);
952 /******************************************************************************
953 * CreateItemMoniker [OLE.55]
954 ******************************************************************************/
955 HRESULT WINAPI CreateItemMoniker(LPCOLESTR lpszDelim,LPCOLESTR lpszItem, LPMONIKER * ppmk)
957 ItemMonikerImpl* newItemMoniker = 0;
959 IID riid=IID_IMoniker;
961 TRACE("(%p,%p,%p)\n",lpszDelim,lpszItem,ppmk);
963 newItemMoniker = HeapAlloc(GetProcessHeap(), 0, sizeof(ItemMonikerImpl));
965 if (newItemMoniker == 0)
966 return STG_E_INSUFFICIENTMEMORY;
968 hr = ItemMonikerImpl_Construct(newItemMoniker,lpszDelim,lpszItem);
972 HeapFree(GetProcessHeap(),0,newItemMoniker);
976 return ItemMonikerImpl_QueryInterface((IMoniker*)newItemMoniker,&riid,(void**)ppmk);