1 /***************************************************************************************
2 * ItemMonikers implementation
4 * Copyright 1999 Noomen Hamza
5 ***************************************************************************************/
10 #include <ole32/ole32.h>
12 #include <storage32.h>
17 /* ItemMoniker data structure */
18 typedef struct ItemMonikerImpl{
20 ICOM_VTABLE(IMoniker)* lpvtbl1; /* VTable relative to the IMoniker interface.*/
22 /* The ROT (RunningObjectTable implementation) uses the IROTData interface to test whether
23 * two monikers are equal. That's whay IROTData interface is implemented by monikers.
25 ICOM_VTABLE(IROTData)* lpvtbl2; /* VTable relative to the IROTData interface.*/
27 ULONG ref; /* reference counter for this object */
29 LPOLESTR itemName; /* item name identified by this ItemMoniker */
31 LPOLESTR itemDelimiter; /* Delimiter string */
35 /********************************************************************************/
36 /* ItemMoniker prototype functions : */
38 /* IUnknown prototype functions */
39 static HRESULT WINAPI ItemMonikerImpl_QueryInterface(IMoniker* iface,REFIID riid,void** ppvObject);
40 static ULONG WINAPI ItemMonikerImpl_AddRef(IMoniker* iface);
41 static ULONG WINAPI ItemMonikerImpl_Release(IMoniker* iface);
43 /* IPersist prototype functions */
44 static HRESULT WINAPI ItemMonikerImpl_GetClassID(IMoniker* iface, CLSID *pClassID);
46 /* IPersistStream prototype functions */
47 static HRESULT WINAPI ItemMonikerImpl_IsDirty(IMoniker* iface);
48 static HRESULT WINAPI ItemMonikerImpl_Load(IMoniker* iface, IStream* pStm);
49 static HRESULT WINAPI ItemMonikerImpl_Save(IMoniker* iface, IStream* pStm, BOOL fClearDirty);
50 static HRESULT WINAPI ItemMonikerImpl_GetSizeMax(IMoniker* iface, ULARGE_INTEGER* pcbSize);
52 /* IMoniker prototype functions */
53 static HRESULT WINAPI ItemMonikerImpl_BindToObject(IMoniker* iface,IBindCtx* pbc, IMoniker* pmkToLeft, REFIID riid, VOID** ppvResult);
54 static HRESULT WINAPI ItemMonikerImpl_BindToStorage(IMoniker* iface,IBindCtx* pbc, IMoniker* pmkToLeft, REFIID riid, VOID** ppvResult);
55 static HRESULT WINAPI ItemMonikerImpl_Reduce(IMoniker* iface,IBindCtx* pbc, DWORD dwReduceHowFar,IMoniker** ppmkToLeft, IMoniker** ppmkReduced);
56 static HRESULT WINAPI ItemMonikerImpl_ComposeWith(IMoniker* iface,IMoniker* pmkRight,BOOL fOnlyIfNotGeneric, IMoniker** ppmkComposite);
57 static HRESULT WINAPI ItemMonikerImpl_Enum(IMoniker* iface,BOOL fForward, IEnumMoniker** ppenumMoniker);
58 static HRESULT WINAPI ItemMonikerImpl_IsEqual(IMoniker* iface,IMoniker* pmkOtherMoniker);
59 static HRESULT WINAPI ItemMonikerImpl_Hash(IMoniker* iface,DWORD* pdwHash);
60 static HRESULT WINAPI ItemMonikerImpl_IsRunning(IMoniker* iface,IBindCtx* pbc, IMoniker* pmkToLeft, IMoniker* pmkNewlyRunning);
61 static HRESULT WINAPI ItemMonikerImpl_GetTimeOfLastChange(IMoniker* iface, IBindCtx* pbc, IMoniker* pmkToLeft, FILETIME* pItemTime);
62 static HRESULT WINAPI ItemMonikerImpl_Inverse(IMoniker* iface,IMoniker** ppmk);
63 static HRESULT WINAPI ItemMonikerImpl_CommonPrefixWith(IMoniker* iface,IMoniker* pmkOther, IMoniker** ppmkPrefix);
64 static HRESULT WINAPI ItemMonikerImpl_RelativePathTo(IMoniker* iface,IMoniker* pmOther, IMoniker** ppmkRelPath);
65 static HRESULT WINAPI ItemMonikerImpl_GetDisplayName(IMoniker* iface,IBindCtx* pbc, IMoniker* pmkToLeft, LPOLESTR *ppszDisplayName);
66 static HRESULT WINAPI ItemMonikerImpl_ParseDisplayName(IMoniker* iface,IBindCtx* pbc, IMoniker* pmkToLeft, LPOLESTR pszDisplayName, ULONG* pchEaten, IMoniker** ppmkOut);
67 static HRESULT WINAPI ItemMonikerImpl_IsSystemMoniker(IMoniker* iface,DWORD* pwdMksys);
69 /* Local function used by ItemMoniker implementation */
70 HRESULT WINAPI ItemMonikerImpl_Construct(ItemMonikerImpl* iface, LPCOLESTR lpszDelim,LPCOLESTR lpszPathName);
71 HRESULT WINAPI ItemMonikerImpl_Destroy(ItemMonikerImpl* iface);
73 /********************************************************************************/
74 /* IROTData prototype functions */
76 /* IUnknown prototype functions */
77 static HRESULT WINAPI ItemMonikerROTDataImpl_QueryInterface(IROTData* iface,REFIID riid,VOID** ppvObject);
78 static ULONG WINAPI ItemMonikerROTDataImpl_AddRef(IROTData* iface);
79 static ULONG WINAPI ItemMonikerROTDataImpl_Release(IROTData* iface);
81 /* IROTData prototype function */
82 static HRESULT WINAPI ItemMonikerROTDataImpl_GetComparaisonData(IROTData* iface,BYTE* pbData,ULONG cbMax,ULONG* pcbData);
84 /********************************************************************************/
85 /* Virtual function table for the ItemMonikerImpl class which include IPersist,*/
86 /* IPersistStream and IMoniker functions. */
87 static ICOM_VTABLE(IMoniker) VT_ItemMonikerImpl =
89 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
90 ItemMonikerImpl_QueryInterface,
91 ItemMonikerImpl_AddRef,
92 ItemMonikerImpl_Release,
93 ItemMonikerImpl_GetClassID,
94 ItemMonikerImpl_IsDirty,
97 ItemMonikerImpl_GetSizeMax,
98 ItemMonikerImpl_BindToObject,
99 ItemMonikerImpl_BindToStorage,
100 ItemMonikerImpl_Reduce,
101 ItemMonikerImpl_ComposeWith,
102 ItemMonikerImpl_Enum,
103 ItemMonikerImpl_IsEqual,
104 ItemMonikerImpl_Hash,
105 ItemMonikerImpl_IsRunning,
106 ItemMonikerImpl_GetTimeOfLastChange,
107 ItemMonikerImpl_Inverse,
108 ItemMonikerImpl_CommonPrefixWith,
109 ItemMonikerImpl_RelativePathTo,
110 ItemMonikerImpl_GetDisplayName,
111 ItemMonikerImpl_ParseDisplayName,
112 ItemMonikerImpl_IsSystemMoniker
115 /********************************************************************************/
116 /* Virtual function table for the IROTData class. */
117 static ICOM_VTABLE(IROTData) VT_ROTDataImpl =
119 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
120 ItemMonikerROTDataImpl_QueryInterface,
121 ItemMonikerROTDataImpl_AddRef,
122 ItemMonikerROTDataImpl_Release,
123 ItemMonikerROTDataImpl_GetComparaisonData
126 /*******************************************************************************
127 * ItemMoniker_QueryInterface
128 *******************************************************************************/
129 HRESULT WINAPI ItemMonikerImpl_QueryInterface(IMoniker* iface,REFIID riid,void** ppvObject)
131 ICOM_THIS(ItemMonikerImpl,iface);
133 Print(MAX_TRACE, ("(%p,%p,%p)\n",This,riid,ppvObject));
135 /* Perform a sanity check on the parameters.*/
136 if ( (This==0) || (ppvObject==0) )
139 /* Initialize the return parameter */
142 /* Compare the riid with the interface IDs implemented by this object.*/
143 if (IsEqualIID(&IID_IUnknown, riid) ||
144 IsEqualIID(&IID_IPersist, riid) ||
145 IsEqualIID(&IID_IPersistStream, riid) ||
146 IsEqualIID(&IID_IMoniker, riid)
150 else if (IsEqualIID(&IID_IROTData, riid))
151 *ppvObject = (IROTData*)&(This->lpvtbl2);
153 /* Check that we obtained an interface.*/
155 return E_NOINTERFACE;
157 /* Query Interface always increases the reference count by one when it is successful */
158 ItemMonikerImpl_AddRef(iface);
163 /******************************************************************************
165 ******************************************************************************/
166 ULONG WINAPI ItemMonikerImpl_AddRef(IMoniker* iface)
168 ICOM_THIS(ItemMonikerImpl,iface);
170 Print(MAX_TRACE, ("(%p)\n",This));
172 return ++(This->ref);
175 /******************************************************************************
176 * ItemMoniker_Release
177 ******************************************************************************/
178 ULONG WINAPI ItemMonikerImpl_Release(IMoniker* iface)
180 ICOM_THIS(ItemMonikerImpl,iface);
182 Print(MAX_TRACE, ("(%p)\n",This));
186 /* destroy the object if there's no more reference on it */
189 ItemMonikerImpl_Destroy(This);
196 /******************************************************************************
197 * ItemMoniker_GetClassID
198 ******************************************************************************/
199 HRESULT WINAPI ItemMonikerImpl_GetClassID(IMoniker* iface,CLSID *pClassID)
201 Print(MAX_TRACE, ("(%p,%p),stub!\n",iface,pClassID));
206 *pClassID = CLSID_ItemMoniker;
211 /******************************************************************************
212 * ItemMoniker_IsDirty
213 ******************************************************************************/
214 HRESULT WINAPI ItemMonikerImpl_IsDirty(IMoniker* iface)
216 /* Note that the OLE-provided implementations of the IPersistStream::IsDirty
217 method in the OLE-provided moniker interfaces always return S_FALSE because
218 their internal state never changes. */
220 Print(MAX_TRACE, ("(%p)\n",iface));
225 /******************************************************************************
227 ******************************************************************************/
228 HRESULT WINAPI ItemMonikerImpl_Load(IMoniker* iface,IStream* pStm)
231 ICOM_THIS(ItemMonikerImpl,iface);
233 DWORD delimiterLength,nameLength,lenW;
234 CHAR *itemNameA,*itemDelimiterA;
237 /* for more details about data read by this function see coments of ItemMonikerImpl_Save function */
239 /* read item delimiter string length + 1 */
240 res=IStream_Read(pStm,&delimiterLength,sizeof(DWORD),&bread);
241 if (bread != sizeof(DWORD))
244 /* read item delimiter string */
245 if (!(itemDelimiterA=HeapAlloc(GetProcessHeap(),0,delimiterLength)))
246 return E_OUTOFMEMORY;
247 res=IStream_Read(pStm,itemDelimiterA,delimiterLength,&bread);
248 if (bread != delimiterLength)
250 HeapFree( GetProcessHeap(), 0, itemDelimiterA );
254 lenW = MultiByteToWideChar( CP_ACP, 0, itemDelimiterA, -1, NULL, 0 );
255 This->itemDelimiter=HeapReAlloc(GetProcessHeap(),0,This->itemDelimiter,lenW*sizeof(WCHAR));
256 if (!This->itemDelimiter)
258 HeapFree( GetProcessHeap(), 0, itemDelimiterA );
259 return E_OUTOFMEMORY;
261 MultiByteToWideChar( CP_ACP, 0, itemDelimiterA, -1, This->itemDelimiter, lenW );
262 HeapFree( GetProcessHeap(), 0, itemDelimiterA );
264 /* read item name string length + 1*/
265 res=IStream_Read(pStm,&nameLength,sizeof(DWORD),&bread);
266 if (bread != sizeof(DWORD))
269 /* read item name string */
270 if (!(itemNameA=HeapAlloc(GetProcessHeap(),0,nameLength)))
271 return E_OUTOFMEMORY;
272 res=IStream_Read(pStm,itemNameA,nameLength,&bread);
273 if (bread != nameLength)
275 HeapFree( GetProcessHeap(), 0, itemNameA );
279 lenW = MultiByteToWideChar( CP_ACP, 0, itemNameA, -1, NULL, 0 );
280 This->itemName=HeapReAlloc(GetProcessHeap(),0,This->itemName,lenW*sizeof(WCHAR));
283 HeapFree( GetProcessHeap(), 0, itemNameA );
284 return E_OUTOFMEMORY;
286 MultiByteToWideChar( CP_ACP, 0, itemNameA, -1, This->itemName, lenW );
287 HeapFree( GetProcessHeap(), 0, itemNameA );
292 /******************************************************************************
294 ******************************************************************************/
295 HRESULT WINAPI ItemMonikerImpl_Save(IMoniker* iface,
296 IStream* pStm,/* pointer to the stream where the object is to be saved */
297 BOOL fClearDirty)/* Specifies whether to clear the dirty flag */
299 ICOM_THIS(ItemMonikerImpl,iface);
301 CHAR *itemNameA,*itemDelimiterA;
303 /* data writen by this function are : 1) DWORD : size of item delimiter string ('\0' included ) */
304 /* 2) String (type A): item delimiter string ('\0' included) */
305 /* 3) DWORD : size of item name string ('\0' included) */
306 /* 4) String (type A): item name string ('\0' included) */
308 DWORD nameLength = WideCharToMultiByte( CP_ACP, 0, This->itemName, -1, NULL, 0, NULL, NULL);
309 DWORD delimiterLength = WideCharToMultiByte( CP_ACP, 0, This->itemDelimiter, -1, NULL, 0, NULL, NULL);
310 itemNameA=HeapAlloc(GetProcessHeap(),0,nameLength);
311 itemDelimiterA=HeapAlloc(GetProcessHeap(),0,delimiterLength);
312 WideCharToMultiByte( CP_ACP, 0, This->itemName, -1, itemNameA, nameLength, NULL, NULL);
313 WideCharToMultiByte( CP_ACP, 0, This->itemDelimiter, -1, itemDelimiterA, delimiterLength, NULL, NULL);
315 res=IStream_Write(pStm,&delimiterLength,sizeof(DWORD),NULL);
316 res=IStream_Write(pStm,itemDelimiterA,delimiterLength * sizeof(CHAR),NULL);
317 res=IStream_Write(pStm,&nameLength,sizeof(DWORD),NULL);
318 res=IStream_Write(pStm,itemNameA,nameLength * sizeof(CHAR),NULL);
323 /******************************************************************************
324 * ItemMoniker_GetSizeMax
325 ******************************************************************************/
326 HRESULT WINAPI ItemMonikerImpl_GetSizeMax(IMoniker* iface,
327 ULARGE_INTEGER* pcbSize)/* Pointer to size of stream needed to save object */
329 ICOM_THIS(ItemMonikerImpl,iface);
330 DWORD delimiterLength=lstrlenW(This->itemDelimiter)+1;
331 DWORD nameLength=lstrlenW(This->itemName)+1;
333 Print(MAX_TRACE, ("(%p,%p)\n",iface,pcbSize));
338 /* for more details see ItemMonikerImpl_Save coments */
340 pcbSize->u.LowPart = sizeof(DWORD) + /* DWORD which contains delimiter length */
341 delimiterLength + /* item delimiter string */
342 sizeof(DWORD) + /* DWORD which contains item name length */
343 nameLength + /* item name string */
344 34; /* this constant was added ! because when I tested this function it usually */
345 /* returns 34 bytes more than the number of bytes used by IMoniker::Save function */
346 pcbSize->u.HighPart=0;
351 /******************************************************************************
352 * ItemMoniker_Construct (local function)
353 *******************************************************************************/
354 HRESULT WINAPI ItemMonikerImpl_Construct(ItemMonikerImpl* This, LPCOLESTR lpszDelim,LPCOLESTR lpszItem)
357 int sizeStr1=lstrlenW(lpszItem), sizeStr2;
358 static const OLECHAR emptystr[1];
361 Print(MAX_TRACE, ("(%p,%p)\n",This,lpszItem));
363 /* Initialize the virtual fgunction table. */
364 This->lpvtbl1 = &VT_ItemMonikerImpl;
365 This->lpvtbl2 = &VT_ROTDataImpl;
368 This->itemName=HeapAlloc(GetProcessHeap(),0,sizeof(WCHAR)*(sizeStr1+1));
370 return E_OUTOFMEMORY;
371 lstrcpyW(This->itemName,lpszItem);
374 Print(MIN_TRACE, ("lpszDelim is NULL. Using empty string which is possibly wrong.\n"));
376 delim = lpszDelim ? lpszDelim : emptystr;
378 sizeStr2=lstrlenW(delim);
379 This->itemDelimiter=HeapAlloc(GetProcessHeap(),0,sizeof(WCHAR)*(sizeStr2+1));
380 if (!This->itemDelimiter) {
381 HeapFree(GetProcessHeap(),0,This->itemName);
382 return E_OUTOFMEMORY;
384 lstrcpyW(This->itemDelimiter,delim);
388 /******************************************************************************
389 * ItemMoniker_Destroy (local function)
390 *******************************************************************************/
391 HRESULT WINAPI ItemMonikerImpl_Destroy(ItemMonikerImpl* This)
393 Print(MAX_TRACE, ("(%p)\n",This));
396 HeapFree(GetProcessHeap(),0,This->itemName);
398 if (This->itemDelimiter)
399 HeapFree(GetProcessHeap(),0,This->itemDelimiter);
401 HeapFree(GetProcessHeap(),0,This);
406 /******************************************************************************
407 * ItemMoniker_BindToObject
408 ******************************************************************************/
409 HRESULT WINAPI ItemMonikerImpl_BindToObject(IMoniker* iface,
415 ICOM_THIS(ItemMonikerImpl,iface);
418 IID refid=IID_IOleItemContainer;
419 IOleItemContainer *poic=0;
421 Print(MAX_TRACE, ("(%p,%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,riid,ppvResult));
431 res=IMoniker_BindToObject(pmkToLeft,pbc,NULL,&refid,(void**)&poic);
435 res=IOleItemContainer_GetObject(poic,This->itemName,BINDSPEED_MODERATE,pbc,riid,ppvResult);
437 IOleItemContainer_Release(poic);
443 /******************************************************************************
444 * ItemMoniker_BindToStorage
445 ******************************************************************************/
446 HRESULT WINAPI ItemMonikerImpl_BindToStorage(IMoniker* iface,
452 ICOM_THIS(ItemMonikerImpl,iface);
455 IOleItemContainer *poic=0;
457 Print(MAX_TRACE, ("(%p,%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,riid,ppvResult));
464 res=IMoniker_BindToObject(pmkToLeft,pbc,NULL,&IID_IOleItemContainer,(void**)&poic);
468 res=IOleItemContainer_GetObjectStorage(poic,This->itemName,pbc,riid,ppvResult);
470 IOleItemContainer_Release(poic);
476 /******************************************************************************
478 ******************************************************************************/
479 HRESULT WINAPI ItemMonikerImpl_Reduce(IMoniker* iface,
481 DWORD dwReduceHowFar,
482 IMoniker** ppmkToLeft,
483 IMoniker** ppmkReduced)
485 Print(MAX_TRACE, ("(%p,%p,%ld,%p,%p)\n",iface,pbc,dwReduceHowFar,ppmkToLeft,ppmkReduced));
487 if (ppmkReduced==NULL)
490 ItemMonikerImpl_AddRef(iface);
494 return MK_S_REDUCED_TO_SELF;
496 /******************************************************************************
497 * ItemMoniker_ComposeWith
498 ******************************************************************************/
499 HRESULT WINAPI ItemMonikerImpl_ComposeWith(IMoniker* iface,
501 BOOL fOnlyIfNotGeneric,
502 IMoniker** ppmkComposite)
506 IEnumMoniker* penumMk=0;
507 IMoniker *pmostLeftMk=0;
508 IMoniker* tempMkComposite=0;
510 Print(MAX_TRACE, ("(%p,%p,%d,%p)\n",iface,pmkRight,fOnlyIfNotGeneric,ppmkComposite));
512 if ((ppmkComposite==NULL)||(pmkRight==NULL))
517 IMoniker_IsSystemMoniker(pmkRight,&mkSys);
519 /* If pmkRight is an anti-moniker, the returned moniker is NULL */
520 if(mkSys==MKSYS_ANTIMONIKER)
524 /* if pmkRight is a composite whose leftmost component is an anti-moniker, */
525 /* the returned moniker is the composite after the leftmost anti-moniker is removed. */
527 if(mkSys==MKSYS_GENERICCOMPOSITE){
529 res=IMoniker_Enum(pmkRight,TRUE,&penumMk);
534 res=IEnumMoniker_Next(penumMk,1,&pmostLeftMk,NULL);
536 IMoniker_IsSystemMoniker(pmostLeftMk,&mkSys2);
538 if(mkSys2==MKSYS_ANTIMONIKER){
540 IMoniker_Release(pmostLeftMk);
542 tempMkComposite=iface;
543 IMoniker_AddRef(iface);
545 while(IEnumMoniker_Next(penumMk,1,&pmostLeftMk,NULL)==S_OK){
547 res=CreateGenericComposite(tempMkComposite,pmostLeftMk,ppmkComposite);
549 IMoniker_Release(tempMkComposite);
550 IMoniker_Release(pmostLeftMk);
552 tempMkComposite=*ppmkComposite;
553 IMoniker_AddRef(tempMkComposite);
558 return CreateGenericComposite(iface,pmkRight,ppmkComposite);
560 /* If pmkRight is not an anti-moniker, the method combines the two monikers into a generic
561 composite if fOnlyIfNotGeneric is FALSE; if fOnlyIfNotGeneric is TRUE, the method returns
562 a NULL moniker and a return value of MK_E_NEEDGENERIC */
564 if (!fOnlyIfNotGeneric)
565 return CreateGenericComposite(iface,pmkRight,ppmkComposite);
568 return MK_E_NEEDGENERIC;
571 /******************************************************************************
573 ******************************************************************************/
574 HRESULT WINAPI ItemMonikerImpl_Enum(IMoniker* iface,BOOL fForward, IEnumMoniker** ppenumMoniker)
576 Print(MAX_TRACE, ("(%p,%d,%p)\n",iface,fForward,ppenumMoniker));
578 if (ppenumMoniker == NULL)
581 *ppenumMoniker = NULL;
586 /******************************************************************************
587 * ItemMoniker_IsEqual
588 ******************************************************************************/
589 HRESULT WINAPI ItemMonikerImpl_IsEqual(IMoniker* iface,IMoniker* pmkOtherMoniker)
593 LPOLESTR dispName1,dispName2;
597 Print(MAX_TRACE, ("(%p,%p)\n",iface,pmkOtherMoniker));
599 if (pmkOtherMoniker==NULL)
602 /* This method returns S_OK if both monikers are item monikers and their display names are */
603 /* identical (using a case-insensitive comparison); otherwise, the method returns S_FALSE. */
605 IMoniker_GetClassID(pmkOtherMoniker,&clsid);
607 if (!IsEqualCLSID(&clsid,&CLSID_ItemMoniker))
610 res=CreateBindCtx(0,&bind);
614 IMoniker_GetDisplayName(iface,bind,NULL,&dispName1);
615 IMoniker_GetDisplayName(pmkOtherMoniker,bind,NULL,&dispName2);
617 if (lstrcmpW(dispName1,dispName2)!=0)
623 /******************************************************************************
625 ******************************************************************************/
626 HRESULT WINAPI ItemMonikerImpl_Hash(IMoniker* iface,DWORD* pdwHash)
628 ICOM_THIS(ItemMonikerImpl,iface);
630 int h = 0,i,skip,len;
637 val = This->itemName;
641 for (i = len ; i > 0; i--) {
642 h = (h * 37) + val[off++];
645 /* only sample some characters */
647 for (i = len ; i > 0; i -= skip, off += skip) {
648 h = (h * 39) + val[off];
657 /******************************************************************************
658 * ItemMoniker_IsRunning
659 ******************************************************************************/
660 HRESULT WINAPI ItemMonikerImpl_IsRunning(IMoniker* iface,
663 IMoniker* pmkNewlyRunning)
665 IRunningObjectTable* rot;
667 IOleItemContainer *poic=0;
668 ICOM_THIS(ItemMonikerImpl,iface);
670 Print(MAX_TRACE, ("(%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,pmkNewlyRunning));
672 /* If pmkToLeft is NULL, this method returns TRUE if pmkNewlyRunning is non-NULL and is equal to this */
673 /* moniker. Otherwise, the method checks the ROT to see whether this moniker is running. */
675 if ((pmkNewlyRunning!=NULL)&&(IMoniker_IsEqual(pmkNewlyRunning,iface)==S_OK))
681 res=IBindCtx_GetRunningObjectTable(pbc,&rot);
686 res = IRunningObjectTable_IsRunning(rot,iface);
688 IRunningObjectTable_Release(rot);
692 /* If pmkToLeft is non-NULL, the method calls IMoniker::BindToObject on the pmkToLeft parameter, */
693 /* requesting an IOleItemContainer interface pointer. The method then calls IOleItemContainer::IsRunning,*/
694 /* passing the string contained within this moniker. */
696 res=IMoniker_BindToObject(pmkToLeft,pbc,NULL,&IID_IOleItemContainer,(void**)&poic);
700 res=IOleItemContainer_IsRunning(poic,This->itemName);
702 IOleItemContainer_Release(poic);
709 /******************************************************************************
710 * ItemMoniker_GetTimeOfLastChange
711 ******************************************************************************/
712 HRESULT WINAPI ItemMonikerImpl_GetTimeOfLastChange(IMoniker* iface,
717 IRunningObjectTable* rot;
719 IMoniker *compositeMk;
721 Print(MAX_TRACE, ("(%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,pItemTime));
726 /* If pmkToLeft is NULL, this method returns MK_E_NOTBINDABLE */
729 return MK_E_NOTBINDABLE;
732 /* Otherwise, the method creates a composite of pmkToLeft and this moniker and uses the ROT to access */
733 /* the time of last change. If the object is not in the ROT, the method calls */
734 /* IMoniker::GetTimeOfLastChange on the pmkToLeft parameter. */
736 res=CreateGenericComposite(pmkToLeft,iface,&compositeMk);
738 res=IBindCtx_GetRunningObjectTable(pbc,&rot);
740 if (IRunningObjectTable_GetTimeOfLastChange(rot,compositeMk,pItemTime)!=S_OK)
742 res=IMoniker_GetTimeOfLastChange(pmkToLeft,pbc,NULL,pItemTime);
744 IMoniker_Release(compositeMk);
750 /******************************************************************************
751 * ItemMoniker_Inverse
752 ******************************************************************************/
753 HRESULT WINAPI ItemMonikerImpl_Inverse(IMoniker* iface,IMoniker** ppmk)
755 Print(MAX_TRACE, ("(%p,%p)\n",iface,ppmk));
760 return CreateAntiMoniker(ppmk);
763 /******************************************************************************
764 * ItemMoniker_CommonPrefixWith
765 ******************************************************************************/
766 HRESULT WINAPI ItemMonikerImpl_CommonPrefixWith(IMoniker* iface,IMoniker* pmkOther,IMoniker** ppmkPrefix)
769 IMoniker_IsSystemMoniker(pmkOther,&mkSys);
770 /* If the other moniker is an item moniker that is equal to this moniker, this method sets *ppmkPrefix */
771 /* to this moniker and returns MK_S_US */
773 if((mkSys==MKSYS_ITEMMONIKER) && (IMoniker_IsEqual(iface,pmkOther)==S_OK) ){
777 IMoniker_AddRef(iface);
782 /* otherwise, the method calls the MonikerCommonPrefixWith function. This function correctly handles */
783 /* the case where the other moniker is a generic composite. */
784 return MonikerCommonPrefixWith(iface,pmkOther,ppmkPrefix);
787 /******************************************************************************
788 * ItemMoniker_RelativePathTo
789 ******************************************************************************/
790 HRESULT WINAPI ItemMonikerImpl_RelativePathTo(IMoniker* iface,IMoniker* pmOther, IMoniker** ppmkRelPath)
792 Print(MAX_TRACE, ("(%p,%p,%p)\n",iface,pmOther,ppmkRelPath));
794 if (ppmkRelPath==NULL)
799 return MK_E_NOTBINDABLE;
802 /******************************************************************************
803 * ItemMoniker_GetDisplayName
804 ******************************************************************************/
805 HRESULT WINAPI ItemMonikerImpl_GetDisplayName(IMoniker* iface,
808 LPOLESTR *ppszDisplayName)
810 ICOM_THIS(ItemMonikerImpl,iface);
812 Print(MAX_TRACE, ("(%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,ppszDisplayName));
814 if (ppszDisplayName==NULL)
817 if (pmkToLeft!=NULL){
821 *ppszDisplayName=CoTaskMemAlloc(sizeof(WCHAR)*(lstrlenW(This->itemDelimiter)+lstrlenW(This->itemName)+1));
823 if (*ppszDisplayName==NULL)
824 return E_OUTOFMEMORY;
826 lstrcpyW(*ppszDisplayName,This->itemDelimiter);
827 lstrcatW(*ppszDisplayName,This->itemName);
832 /******************************************************************************
833 * ItemMoniker_ParseDisplayName
834 ******************************************************************************/
835 HRESULT WINAPI ItemMonikerImpl_ParseDisplayName(IMoniker* iface,
838 LPOLESTR pszDisplayName,
842 IOleItemContainer* poic=0;
843 IParseDisplayName* ppdn=0;
844 LPOLESTR displayName;
846 ICOM_THIS(ItemMonikerImpl,iface);
848 /* If pmkToLeft is NULL, this method returns MK_E_SYNTAX */
854 /* Otherwise, the method calls IMoniker::BindToObject on the pmkToLeft parameter, requesting an */
855 /* IParseDisplayName interface pointer to the object identified by the moniker, and passes the display */ /* name to IParseDisplayName::ParseDisplayName */
856 res=IMoniker_BindToObject(pmkToLeft,pbc,NULL,&IID_IOleItemContainer,(void**)&poic);
860 res=IOleItemContainer_GetObject(poic,This->itemName,BINDSPEED_MODERATE,pbc,&IID_IParseDisplayName,(void**)&ppdn);
862 res=IMoniker_GetDisplayName(iface,pbc,NULL,&displayName);
864 res=IParseDisplayName_ParseDisplayName(ppdn,pbc,displayName,pchEaten,ppmkOut);
866 IOleItemContainer_Release(poic);
867 IParseDisplayName_Release(ppdn);
873 /******************************************************************************
874 * ItemMoniker_IsSystemMoniker
875 ******************************************************************************/
876 HRESULT WINAPI ItemMonikerImpl_IsSystemMoniker(IMoniker* iface,DWORD* pwdMksys)
878 Print(MAX_TRACE, ("(%p,%p)\n",iface,pwdMksys));
883 (*pwdMksys)=MKSYS_ITEMMONIKER;
888 /*******************************************************************************
889 * ItemMonikerIROTData_QueryInterface
890 *******************************************************************************/
891 HRESULT WINAPI ItemMonikerROTDataImpl_QueryInterface(IROTData *iface,REFIID riid,VOID** ppvObject)
894 ICOM_THIS_From_IROTData(IMoniker, iface);
896 Print(MAX_TRACE, ("(%p,%p,%p)\n",iface,riid,ppvObject));
898 return ItemMonikerImpl_QueryInterface(This, riid, ppvObject);
901 /***********************************************************************
902 * ItemMonikerIROTData_AddRef
904 ULONG WINAPI ItemMonikerROTDataImpl_AddRef(IROTData *iface)
906 ICOM_THIS_From_IROTData(IMoniker, iface);
908 Print(MAX_TRACE, ("(%p)\n",iface));
910 return ItemMonikerImpl_AddRef(This);
913 /***********************************************************************
914 * ItemMonikerIROTData_Release
916 ULONG WINAPI ItemMonikerROTDataImpl_Release(IROTData* iface)
918 ICOM_THIS_From_IROTData(IMoniker, iface);
920 Print(MAX_TRACE, ("(%p)\n",iface));
922 return ItemMonikerImpl_Release(This);
925 /******************************************************************************
926 * ItemMonikerIROTData_GetComparaisonData
927 ******************************************************************************/
928 HRESULT WINAPI ItemMonikerROTDataImpl_GetComparaisonData(IROTData* iface,
937 /******************************************************************************
938 * CreateItemMoniker16 [OLE2.28]
939 ******************************************************************************/
940 HRESULT WINAPI CreateItemMoniker16(LPCOLESTR16 lpszDelim,LPCOLESTR lpszItem,LPMONIKER* ppmk)
943 Print(MIN_TRACE, ("(%s,%p),stub!\n",lpszDelim,ppmk));
948 /******************************************************************************
949 * CreateItemMoniker [OLE.55]
950 ******************************************************************************/
951 HRESULT WINAPI CreateItemMoniker(LPCOLESTR lpszDelim,LPCOLESTR lpszItem, LPMONIKER * ppmk)
953 ItemMonikerImpl* newItemMoniker = 0;
955 IID riid=IID_IMoniker;
957 Print(MAX_TRACE, ("(%p,%p,%p)\n",lpszDelim,lpszItem,ppmk));
959 newItemMoniker = HeapAlloc(GetProcessHeap(), 0, sizeof(ItemMonikerImpl));
961 if (newItemMoniker == 0)
962 return STG_E_INSUFFICIENTMEMORY;
964 hr = ItemMonikerImpl_Construct(newItemMoniker,lpszDelim,lpszItem);
968 HeapFree(GetProcessHeap(),0,newItemMoniker);
972 return ItemMonikerImpl_QueryInterface((IMoniker*)newItemMoniker,&riid,(void**)ppmk);