1 /***************************************************************************************
2 * ItemMonikers implementation
4 * Copyright 1999 Noomen Hamza
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.
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.
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 ***************************************************************************************/
26 #include "wine/debug.h"
28 #include "wine/unicode.h"
31 WINE_DEFAULT_DEBUG_CHANNEL(ole);
33 const CLSID CLSID_ItemMoniker = {
34 0x304, 0, 0, {0xC0, 0, 0, 0, 0, 0, 0, 0x46}
37 /* ItemMoniker data structure */
38 typedef struct ItemMonikerImpl{
40 ICOM_VTABLE(IMoniker)* lpvtbl1; /* VTable relative to the IMoniker interface.*/
42 /* The ROT (RunningObjectTable implementation) uses the IROTData interface to test whether
43 * two monikers are equal. That's whay IROTData interface is implemented by monikers.
45 ICOM_VTABLE(IROTData)* lpvtbl2; /* VTable relative to the IROTData interface.*/
47 ULONG ref; /* reference counter for this object */
49 LPOLESTR itemName; /* item name identified by this ItemMoniker */
51 LPOLESTR itemDelimiter; /* Delimiter string */
55 /********************************************************************************/
56 /* ItemMoniker prototype functions : */
58 /* IUnknown prototype functions */
59 static HRESULT WINAPI ItemMonikerImpl_QueryInterface(IMoniker* iface,REFIID riid,void** ppvObject);
60 static ULONG WINAPI ItemMonikerImpl_AddRef(IMoniker* iface);
61 static ULONG WINAPI ItemMonikerImpl_Release(IMoniker* iface);
63 /* IPersist prototype functions */
64 static HRESULT WINAPI ItemMonikerImpl_GetClassID(IMoniker* iface, CLSID *pClassID);
66 /* IPersistStream prototype functions */
67 static HRESULT WINAPI ItemMonikerImpl_IsDirty(IMoniker* iface);
68 static HRESULT WINAPI ItemMonikerImpl_Load(IMoniker* iface, IStream* pStm);
69 static HRESULT WINAPI ItemMonikerImpl_Save(IMoniker* iface, IStream* pStm, BOOL fClearDirty);
70 static HRESULT WINAPI ItemMonikerImpl_GetSizeMax(IMoniker* iface, ULARGE_INTEGER* pcbSize);
72 /* IMoniker prototype functions */
73 static HRESULT WINAPI ItemMonikerImpl_BindToObject(IMoniker* iface,IBindCtx* pbc, IMoniker* pmkToLeft, REFIID riid, VOID** ppvResult);
74 static HRESULT WINAPI ItemMonikerImpl_BindToStorage(IMoniker* iface,IBindCtx* pbc, IMoniker* pmkToLeft, REFIID riid, VOID** ppvResult);
75 static HRESULT WINAPI ItemMonikerImpl_Reduce(IMoniker* iface,IBindCtx* pbc, DWORD dwReduceHowFar,IMoniker** ppmkToLeft, IMoniker** ppmkReduced);
76 static HRESULT WINAPI ItemMonikerImpl_ComposeWith(IMoniker* iface,IMoniker* pmkRight,BOOL fOnlyIfNotGeneric, IMoniker** ppmkComposite);
77 static HRESULT WINAPI ItemMonikerImpl_Enum(IMoniker* iface,BOOL fForward, IEnumMoniker** ppenumMoniker);
78 static HRESULT WINAPI ItemMonikerImpl_IsEqual(IMoniker* iface,IMoniker* pmkOtherMoniker);
79 static HRESULT WINAPI ItemMonikerImpl_Hash(IMoniker* iface,DWORD* pdwHash);
80 static HRESULT WINAPI ItemMonikerImpl_IsRunning(IMoniker* iface,IBindCtx* pbc, IMoniker* pmkToLeft, IMoniker* pmkNewlyRunning);
81 static HRESULT WINAPI ItemMonikerImpl_GetTimeOfLastChange(IMoniker* iface, IBindCtx* pbc, IMoniker* pmkToLeft, FILETIME* pItemTime);
82 static HRESULT WINAPI ItemMonikerImpl_Inverse(IMoniker* iface,IMoniker** ppmk);
83 static HRESULT WINAPI ItemMonikerImpl_CommonPrefixWith(IMoniker* iface,IMoniker* pmkOther, IMoniker** ppmkPrefix);
84 static HRESULT WINAPI ItemMonikerImpl_RelativePathTo(IMoniker* iface,IMoniker* pmOther, IMoniker** ppmkRelPath);
85 static HRESULT WINAPI ItemMonikerImpl_GetDisplayName(IMoniker* iface,IBindCtx* pbc, IMoniker* pmkToLeft, LPOLESTR *ppszDisplayName);
86 static HRESULT WINAPI ItemMonikerImpl_ParseDisplayName(IMoniker* iface,IBindCtx* pbc, IMoniker* pmkToLeft, LPOLESTR pszDisplayName, ULONG* pchEaten, IMoniker** ppmkOut);
87 static HRESULT WINAPI ItemMonikerImpl_IsSystemMoniker(IMoniker* iface,DWORD* pwdMksys);
89 /* Local function used by ItemMoniker implementation */
90 HRESULT WINAPI ItemMonikerImpl_Construct(ItemMonikerImpl* iface, LPCOLESTR lpszDelim,LPCOLESTR lpszPathName);
91 HRESULT WINAPI ItemMonikerImpl_Destroy(ItemMonikerImpl* iface);
93 /********************************************************************************/
94 /* IROTData prototype functions */
96 /* IUnknown prototype functions */
97 static HRESULT WINAPI ItemMonikerROTDataImpl_QueryInterface(IROTData* iface,REFIID riid,VOID** ppvObject);
98 static ULONG WINAPI ItemMonikerROTDataImpl_AddRef(IROTData* iface);
99 static ULONG WINAPI ItemMonikerROTDataImpl_Release(IROTData* iface);
101 /* IROTData prototype function */
102 static HRESULT WINAPI ItemMonikerROTDataImpl_GetComparaisonData(IROTData* iface,BYTE* pbData,ULONG cbMax,ULONG* pcbData);
104 /********************************************************************************/
105 /* Virtual function table for the ItemMonikerImpl class which include IPersist,*/
106 /* IPersistStream and IMoniker functions. */
107 static ICOM_VTABLE(IMoniker) VT_ItemMonikerImpl =
109 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
110 ItemMonikerImpl_QueryInterface,
111 ItemMonikerImpl_AddRef,
112 ItemMonikerImpl_Release,
113 ItemMonikerImpl_GetClassID,
114 ItemMonikerImpl_IsDirty,
115 ItemMonikerImpl_Load,
116 ItemMonikerImpl_Save,
117 ItemMonikerImpl_GetSizeMax,
118 ItemMonikerImpl_BindToObject,
119 ItemMonikerImpl_BindToStorage,
120 ItemMonikerImpl_Reduce,
121 ItemMonikerImpl_ComposeWith,
122 ItemMonikerImpl_Enum,
123 ItemMonikerImpl_IsEqual,
124 ItemMonikerImpl_Hash,
125 ItemMonikerImpl_IsRunning,
126 ItemMonikerImpl_GetTimeOfLastChange,
127 ItemMonikerImpl_Inverse,
128 ItemMonikerImpl_CommonPrefixWith,
129 ItemMonikerImpl_RelativePathTo,
130 ItemMonikerImpl_GetDisplayName,
131 ItemMonikerImpl_ParseDisplayName,
132 ItemMonikerImpl_IsSystemMoniker
135 /********************************************************************************/
136 /* Virtual function table for the IROTData class. */
137 static ICOM_VTABLE(IROTData) VT_ROTDataImpl =
139 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
140 ItemMonikerROTDataImpl_QueryInterface,
141 ItemMonikerROTDataImpl_AddRef,
142 ItemMonikerROTDataImpl_Release,
143 ItemMonikerROTDataImpl_GetComparaisonData
146 /*******************************************************************************
147 * ItemMoniker_QueryInterface
148 *******************************************************************************/
149 HRESULT WINAPI ItemMonikerImpl_QueryInterface(IMoniker* iface,REFIID riid,void** ppvObject)
151 ICOM_THIS(ItemMonikerImpl,iface);
153 TRACE("(%p,%p,%p)\n",This,riid,ppvObject);
155 /* Perform a sanity check on the parameters.*/
156 if ( (This==0) || (ppvObject==0) )
159 /* Initialize the return parameter */
162 /* Compare the riid with the interface IDs implemented by this object.*/
163 if (IsEqualIID(&IID_IUnknown, riid) ||
164 IsEqualIID(&IID_IPersist, riid) ||
165 IsEqualIID(&IID_IPersistStream, riid) ||
166 IsEqualIID(&IID_IMoniker, riid)
170 else if (IsEqualIID(&IID_IROTData, riid))
171 *ppvObject = (IROTData*)&(This->lpvtbl2);
173 /* Check that we obtained an interface.*/
175 return E_NOINTERFACE;
177 /* Query Interface always increases the reference count by one when it is successful */
178 ItemMonikerImpl_AddRef(iface);
183 /******************************************************************************
185 ******************************************************************************/
186 ULONG WINAPI ItemMonikerImpl_AddRef(IMoniker* iface)
188 ICOM_THIS(ItemMonikerImpl,iface);
190 TRACE("(%p)\n",This);
192 return ++(This->ref);
195 /******************************************************************************
196 * ItemMoniker_Release
197 ******************************************************************************/
198 ULONG WINAPI ItemMonikerImpl_Release(IMoniker* iface)
200 ICOM_THIS(ItemMonikerImpl,iface);
202 TRACE("(%p)\n",This);
206 /* destroy the object if there's no more reference on it */
209 ItemMonikerImpl_Destroy(This);
216 /******************************************************************************
217 * ItemMoniker_GetClassID
218 ******************************************************************************/
219 HRESULT WINAPI ItemMonikerImpl_GetClassID(IMoniker* iface,CLSID *pClassID)
221 TRACE("(%p,%p),stub!\n",iface,pClassID);
226 *pClassID = CLSID_ItemMoniker;
231 /******************************************************************************
232 * ItemMoniker_IsDirty
233 ******************************************************************************/
234 HRESULT WINAPI ItemMonikerImpl_IsDirty(IMoniker* iface)
236 /* Note that the OLE-provided implementations of the IPersistStream::IsDirty
237 method in the OLE-provided moniker interfaces always return S_FALSE because
238 their internal state never changes. */
240 TRACE("(%p)\n",iface);
245 /******************************************************************************
247 ******************************************************************************/
248 HRESULT WINAPI ItemMonikerImpl_Load(IMoniker* iface,IStream* pStm)
251 ICOM_THIS(ItemMonikerImpl,iface);
253 DWORD delimiterLength,nameLength,lenW;
254 CHAR *itemNameA,*itemDelimiterA;
257 /* for more details about data read by this function see coments of ItemMonikerImpl_Save function */
259 /* read item delimiter string length + 1 */
260 res=IStream_Read(pStm,&delimiterLength,sizeof(DWORD),&bread);
261 if (bread != sizeof(DWORD))
264 /* read item delimiter string */
265 if (!(itemDelimiterA=HeapAlloc(GetProcessHeap(),0,delimiterLength)))
266 return E_OUTOFMEMORY;
267 res=IStream_Read(pStm,itemDelimiterA,delimiterLength,&bread);
268 if (bread != delimiterLength)
270 HeapFree( GetProcessHeap(), 0, itemDelimiterA );
274 lenW = MultiByteToWideChar( CP_ACP, 0, itemDelimiterA, -1, NULL, 0 );
275 This->itemDelimiter=HeapReAlloc(GetProcessHeap(),0,This->itemDelimiter,lenW*sizeof(WCHAR));
276 if (!This->itemDelimiter)
278 HeapFree( GetProcessHeap(), 0, itemDelimiterA );
279 return E_OUTOFMEMORY;
281 MultiByteToWideChar( CP_ACP, 0, itemDelimiterA, -1, This->itemDelimiter, lenW );
282 HeapFree( GetProcessHeap(), 0, itemDelimiterA );
284 /* read item name string length + 1*/
285 res=IStream_Read(pStm,&nameLength,sizeof(DWORD),&bread);
286 if (bread != sizeof(DWORD))
289 /* read item name string */
290 if (!(itemNameA=HeapAlloc(GetProcessHeap(),0,nameLength)))
291 return E_OUTOFMEMORY;
292 res=IStream_Read(pStm,itemNameA,nameLength,&bread);
293 if (bread != nameLength)
295 HeapFree( GetProcessHeap(), 0, itemNameA );
299 lenW = MultiByteToWideChar( CP_ACP, 0, itemNameA, -1, NULL, 0 );
300 This->itemName=HeapReAlloc(GetProcessHeap(),0,This->itemName,lenW*sizeof(WCHAR));
303 HeapFree( GetProcessHeap(), 0, itemNameA );
304 return E_OUTOFMEMORY;
306 MultiByteToWideChar( CP_ACP, 0, itemNameA, -1, This->itemName, lenW );
307 HeapFree( GetProcessHeap(), 0, itemNameA );
312 /******************************************************************************
314 ******************************************************************************/
315 HRESULT WINAPI ItemMonikerImpl_Save(IMoniker* iface,
316 IStream* pStm,/* pointer to the stream where the object is to be saved */
317 BOOL fClearDirty)/* Specifies whether to clear the dirty flag */
319 ICOM_THIS(ItemMonikerImpl,iface);
321 CHAR *itemNameA,*itemDelimiterA;
323 /* data writen by this function are : 1) DWORD : size of item delimiter string ('\0' included ) */
324 /* 2) String (type A): item delimiter string ('\0' included) */
325 /* 3) DWORD : size of item name string ('\0' included) */
326 /* 4) String (type A): item name string ('\0' included) */
328 DWORD nameLength = WideCharToMultiByte( CP_ACP, 0, This->itemName, -1, NULL, 0, NULL, NULL);
329 DWORD delimiterLength = WideCharToMultiByte( CP_ACP, 0, This->itemDelimiter, -1, NULL, 0, NULL, NULL);
330 itemNameA=HeapAlloc(GetProcessHeap(),0,nameLength);
331 itemDelimiterA=HeapAlloc(GetProcessHeap(),0,delimiterLength);
332 WideCharToMultiByte( CP_ACP, 0, This->itemName, -1, itemNameA, nameLength, NULL, NULL);
333 WideCharToMultiByte( CP_ACP, 0, This->itemDelimiter, -1, itemDelimiterA, delimiterLength, NULL, NULL);
335 res=IStream_Write(pStm,&delimiterLength,sizeof(DWORD),NULL);
336 res=IStream_Write(pStm,itemDelimiterA,delimiterLength * sizeof(CHAR),NULL);
337 res=IStream_Write(pStm,&nameLength,sizeof(DWORD),NULL);
338 res=IStream_Write(pStm,itemNameA,nameLength * sizeof(CHAR),NULL);
343 /******************************************************************************
344 * ItemMoniker_GetSizeMax
345 ******************************************************************************/
346 HRESULT WINAPI ItemMonikerImpl_GetSizeMax(IMoniker* iface,
347 ULARGE_INTEGER* pcbSize)/* Pointer to size of stream needed to save object */
349 ICOM_THIS(ItemMonikerImpl,iface);
350 DWORD delimiterLength=lstrlenW(This->itemDelimiter)+1;
351 DWORD nameLength=lstrlenW(This->itemName)+1;
353 TRACE("(%p,%p)\n",iface,pcbSize);
358 /* for more details see ItemMonikerImpl_Save coments */
360 pcbSize->s.LowPart = sizeof(DWORD) + /* DWORD which contains delimiter length */
361 delimiterLength + /* item delimiter string */
362 sizeof(DWORD) + /* DWORD which contains item name length */
363 nameLength + /* item name string */
364 34; /* this constant was added ! because when I tested this function it usually */
365 /* returns 34 bytes more than the number of bytes used by IMoniker::Save function */
366 pcbSize->s.HighPart=0;
371 /******************************************************************************
372 * ItemMoniker_Construct (local function)
373 *******************************************************************************/
374 HRESULT WINAPI ItemMonikerImpl_Construct(ItemMonikerImpl* This, LPCOLESTR lpszDelim,LPCOLESTR lpszItem)
377 int sizeStr1=lstrlenW(lpszItem), sizeStr2;
378 static const OLECHAR emptystr[1];
381 TRACE("(%p,%p)\n",This,lpszItem);
383 /* Initialize the virtual fgunction table. */
384 This->lpvtbl1 = &VT_ItemMonikerImpl;
385 This->lpvtbl2 = &VT_ROTDataImpl;
388 This->itemName=HeapAlloc(GetProcessHeap(),0,sizeof(WCHAR)*(sizeStr1+1));
390 return E_OUTOFMEMORY;
391 lstrcpyW(This->itemName,lpszItem);
394 FIXME("lpszDelim is NULL. Using empty string which is possibly wrong.\n");
396 delim = lpszDelim ? lpszDelim : emptystr;
398 sizeStr2=lstrlenW(delim);
399 This->itemDelimiter=HeapAlloc(GetProcessHeap(),0,sizeof(WCHAR)*(sizeStr2+1));
400 if (!This->itemDelimiter) {
401 HeapFree(GetProcessHeap(),0,This->itemName);
402 return E_OUTOFMEMORY;
404 lstrcpyW(This->itemDelimiter,delim);
408 /******************************************************************************
409 * ItemMoniker_Destroy (local function)
410 *******************************************************************************/
411 HRESULT WINAPI ItemMonikerImpl_Destroy(ItemMonikerImpl* This)
413 TRACE("(%p)\n",This);
416 HeapFree(GetProcessHeap(),0,This->itemName);
418 if (This->itemDelimiter)
419 HeapFree(GetProcessHeap(),0,This->itemDelimiter);
421 HeapFree(GetProcessHeap(),0,This);
426 /******************************************************************************
427 * ItemMoniker_BindToObject
428 ******************************************************************************/
429 HRESULT WINAPI ItemMonikerImpl_BindToObject(IMoniker* iface,
435 ICOM_THIS(ItemMonikerImpl,iface);
438 IID refid=IID_IOleItemContainer;
439 IOleItemContainer *poic=0;
441 TRACE("(%p,%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,riid,ppvResult);
451 res=IMoniker_BindToObject(pmkToLeft,pbc,NULL,&refid,(void**)&poic);
455 res=IOleItemContainer_GetObject(poic,This->itemName,BINDSPEED_MODERATE,pbc,riid,ppvResult);
457 IOleItemContainer_Release(poic);
463 /******************************************************************************
464 * ItemMoniker_BindToStorage
465 ******************************************************************************/
466 HRESULT WINAPI ItemMonikerImpl_BindToStorage(IMoniker* iface,
472 ICOM_THIS(ItemMonikerImpl,iface);
475 IOleItemContainer *poic=0;
477 TRACE("(%p,%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,riid,ppvResult);
484 res=IMoniker_BindToObject(pmkToLeft,pbc,NULL,&IID_IOleItemContainer,(void**)&poic);
488 res=IOleItemContainer_GetObjectStorage(poic,This->itemName,pbc,riid,ppvResult);
490 IOleItemContainer_Release(poic);
496 /******************************************************************************
498 ******************************************************************************/
499 HRESULT WINAPI ItemMonikerImpl_Reduce(IMoniker* iface,
501 DWORD dwReduceHowFar,
502 IMoniker** ppmkToLeft,
503 IMoniker** ppmkReduced)
505 TRACE("(%p,%p,%ld,%p,%p)\n",iface,pbc,dwReduceHowFar,ppmkToLeft,ppmkReduced);
507 if (ppmkReduced==NULL)
510 ItemMonikerImpl_AddRef(iface);
514 return MK_S_REDUCED_TO_SELF;
516 /******************************************************************************
517 * ItemMoniker_ComposeWith
518 ******************************************************************************/
519 HRESULT WINAPI ItemMonikerImpl_ComposeWith(IMoniker* iface,
521 BOOL fOnlyIfNotGeneric,
522 IMoniker** ppmkComposite)
526 IEnumMoniker* penumMk=0;
527 IMoniker *pmostLeftMk=0;
528 IMoniker* tempMkComposite=0;
530 TRACE("(%p,%p,%d,%p)\n",iface,pmkRight,fOnlyIfNotGeneric,ppmkComposite);
532 if ((ppmkComposite==NULL)||(pmkRight==NULL))
537 IMoniker_IsSystemMoniker(pmkRight,&mkSys);
539 /* If pmkRight is an anti-moniker, the returned moniker is NULL */
540 if(mkSys==MKSYS_ANTIMONIKER)
544 /* if pmkRight is a composite whose leftmost component is an anti-moniker, */
545 /* the returned moniker is the composite after the leftmost anti-moniker is removed. */
547 if(mkSys==MKSYS_GENERICCOMPOSITE){
549 res=IMoniker_Enum(pmkRight,TRUE,&penumMk);
554 res=IEnumMoniker_Next(penumMk,1,&pmostLeftMk,NULL);
556 IMoniker_IsSystemMoniker(pmostLeftMk,&mkSys2);
558 if(mkSys2==MKSYS_ANTIMONIKER){
560 IMoniker_Release(pmostLeftMk);
562 tempMkComposite=iface;
563 IMoniker_AddRef(iface);
565 while(IEnumMoniker_Next(penumMk,1,&pmostLeftMk,NULL)==S_OK){
567 res=CreateGenericComposite(tempMkComposite,pmostLeftMk,ppmkComposite);
569 IMoniker_Release(tempMkComposite);
570 IMoniker_Release(pmostLeftMk);
572 tempMkComposite=*ppmkComposite;
573 IMoniker_AddRef(tempMkComposite);
578 return CreateGenericComposite(iface,pmkRight,ppmkComposite);
580 /* If pmkRight is not an anti-moniker, the method combines the two monikers into a generic
581 composite if fOnlyIfNotGeneric is FALSE; if fOnlyIfNotGeneric is TRUE, the method returns
582 a NULL moniker and a return value of MK_E_NEEDGENERIC */
584 if (!fOnlyIfNotGeneric)
585 return CreateGenericComposite(iface,pmkRight,ppmkComposite);
588 return MK_E_NEEDGENERIC;
591 /******************************************************************************
593 ******************************************************************************/
594 HRESULT WINAPI ItemMonikerImpl_Enum(IMoniker* iface,BOOL fForward, IEnumMoniker** ppenumMoniker)
596 TRACE("(%p,%d,%p)\n",iface,fForward,ppenumMoniker);
598 if (ppenumMoniker == NULL)
601 *ppenumMoniker = NULL;
606 /******************************************************************************
607 * ItemMoniker_IsEqual
608 ******************************************************************************/
609 HRESULT WINAPI ItemMonikerImpl_IsEqual(IMoniker* iface,IMoniker* pmkOtherMoniker)
613 LPOLESTR dispName1,dispName2;
615 HRESULT res = S_FALSE;
617 TRACE("(%p,%p)\n",iface,pmkOtherMoniker);
619 if (!pmkOtherMoniker) return S_FALSE;
622 /* check if both are ItemMoniker */
623 if(FAILED (IMoniker_GetClassID(pmkOtherMoniker,&clsid))) return S_FALSE;
624 if(!IsEqualCLSID(&clsid,&CLSID_ItemMoniker)) return S_FALSE;
626 /* check if both displaynames are the same */
627 if(SUCCEEDED ((res = CreateBindCtx(0,&bind)))) {
628 if(SUCCEEDED (IMoniker_GetDisplayName(iface,bind,NULL,&dispName1))) {
629 if(SUCCEEDED (IMoniker_GetDisplayName(pmkOtherMoniker,bind,NULL,&dispName2))) {
630 if(lstrcmpW(dispName1,dispName2)==0) res = S_OK;
631 CoTaskMemFree(dispName2);
633 CoTaskMemFree(dispName1);
639 /******************************************************************************
641 ******************************************************************************/
642 HRESULT WINAPI ItemMonikerImpl_Hash(IMoniker* iface,DWORD* pdwHash)
644 ICOM_THIS(ItemMonikerImpl,iface);
646 int h = 0,i,skip,len;
653 val = This->itemName;
657 for (i = len ; i > 0; i--) {
658 h = (h * 37) + val[off++];
661 /* only sample some characters */
663 for (i = len ; i > 0; i -= skip, off += skip) {
664 h = (h * 39) + val[off];
673 /******************************************************************************
674 * ItemMoniker_IsRunning
675 ******************************************************************************/
676 HRESULT WINAPI ItemMonikerImpl_IsRunning(IMoniker* iface,
679 IMoniker* pmkNewlyRunning)
681 IRunningObjectTable* rot;
683 IOleItemContainer *poic=0;
684 ICOM_THIS(ItemMonikerImpl,iface);
686 TRACE("(%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,pmkNewlyRunning);
688 /* If pmkToLeft is NULL, this method returns TRUE if pmkNewlyRunning is non-NULL and is equal to this */
689 /* moniker. Otherwise, the method checks the ROT to see whether this moniker is running. */
691 if ((pmkNewlyRunning!=NULL)&&(IMoniker_IsEqual(pmkNewlyRunning,iface)==S_OK))
697 res=IBindCtx_GetRunningObjectTable(pbc,&rot);
702 res = IRunningObjectTable_IsRunning(rot,iface);
704 IRunningObjectTable_Release(rot);
708 /* If pmkToLeft is non-NULL, the method calls IMoniker::BindToObject on the pmkToLeft parameter, */
709 /* requesting an IOleItemContainer interface pointer. The method then calls IOleItemContainer::IsRunning,*/
710 /* passing the string contained within this moniker. */
712 res=IMoniker_BindToObject(pmkToLeft,pbc,NULL,&IID_IOleItemContainer,(void**)&poic);
716 res=IOleItemContainer_IsRunning(poic,This->itemName);
718 IOleItemContainer_Release(poic);
725 /******************************************************************************
726 * ItemMoniker_GetTimeOfLastChange
727 ******************************************************************************/
728 HRESULT WINAPI ItemMonikerImpl_GetTimeOfLastChange(IMoniker* iface,
733 IRunningObjectTable* rot;
735 IMoniker *compositeMk;
737 TRACE("(%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,pItemTime);
742 /* If pmkToLeft is NULL, this method returns MK_E_NOTBINDABLE */
745 return MK_E_NOTBINDABLE;
748 /* Otherwise, the method creates a composite of pmkToLeft and this moniker and uses the ROT to access */
749 /* the time of last change. If the object is not in the ROT, the method calls */
750 /* IMoniker::GetTimeOfLastChange on the pmkToLeft parameter. */
752 res=CreateGenericComposite(pmkToLeft,iface,&compositeMk);
754 res=IBindCtx_GetRunningObjectTable(pbc,&rot);
756 if (IRunningObjectTable_GetTimeOfLastChange(rot,compositeMk,pItemTime)!=S_OK)
758 res=IMoniker_GetTimeOfLastChange(pmkToLeft,pbc,NULL,pItemTime);
760 IMoniker_Release(compositeMk);
766 /******************************************************************************
767 * ItemMoniker_Inverse
768 ******************************************************************************/
769 HRESULT WINAPI ItemMonikerImpl_Inverse(IMoniker* iface,IMoniker** ppmk)
771 TRACE("(%p,%p)\n",iface,ppmk);
776 return CreateAntiMoniker(ppmk);
779 /******************************************************************************
780 * ItemMoniker_CommonPrefixWith
781 ******************************************************************************/
782 HRESULT WINAPI ItemMonikerImpl_CommonPrefixWith(IMoniker* iface,IMoniker* pmkOther,IMoniker** ppmkPrefix)
785 IMoniker_IsSystemMoniker(pmkOther,&mkSys);
786 /* If the other moniker is an item moniker that is equal to this moniker, this method sets *ppmkPrefix */
787 /* to this moniker and returns MK_S_US */
789 if((mkSys==MKSYS_ITEMMONIKER) && (IMoniker_IsEqual(iface,pmkOther)==S_OK) ){
793 IMoniker_AddRef(iface);
798 /* otherwise, the method calls the MonikerCommonPrefixWith function. This function correctly handles */
799 /* the case where the other moniker is a generic composite. */
800 return MonikerCommonPrefixWith(iface,pmkOther,ppmkPrefix);
803 /******************************************************************************
804 * ItemMoniker_RelativePathTo
805 ******************************************************************************/
806 HRESULT WINAPI ItemMonikerImpl_RelativePathTo(IMoniker* iface,IMoniker* pmOther, IMoniker** ppmkRelPath)
808 TRACE("(%p,%p,%p)\n",iface,pmOther,ppmkRelPath);
810 if (ppmkRelPath==NULL)
815 return MK_E_NOTBINDABLE;
818 /******************************************************************************
819 * ItemMoniker_GetDisplayName
820 ******************************************************************************/
821 HRESULT WINAPI ItemMonikerImpl_GetDisplayName(IMoniker* iface,
824 LPOLESTR *ppszDisplayName)
826 ICOM_THIS(ItemMonikerImpl,iface);
828 TRACE("(%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,ppszDisplayName);
830 if (ppszDisplayName==NULL)
833 if (pmkToLeft!=NULL){
837 *ppszDisplayName=CoTaskMemAlloc(sizeof(WCHAR)*(lstrlenW(This->itemDelimiter)+lstrlenW(This->itemName)+1));
839 if (*ppszDisplayName==NULL)
840 return E_OUTOFMEMORY;
842 lstrcpyW(*ppszDisplayName,This->itemDelimiter);
843 lstrcatW(*ppszDisplayName,This->itemName);
848 /******************************************************************************
849 * ItemMoniker_ParseDisplayName
850 ******************************************************************************/
851 HRESULT WINAPI ItemMonikerImpl_ParseDisplayName(IMoniker* iface,
854 LPOLESTR pszDisplayName,
858 IOleItemContainer* poic=0;
859 IParseDisplayName* ppdn=0;
860 LPOLESTR displayName;
862 ICOM_THIS(ItemMonikerImpl,iface);
864 /* If pmkToLeft is NULL, this method returns MK_E_SYNTAX */
870 /* Otherwise, the method calls IMoniker::BindToObject on the pmkToLeft parameter, requesting an */
871 /* IParseDisplayName interface pointer to the object identified by the moniker, and passes the display */
872 /* name to IParseDisplayName::ParseDisplayName */
873 res=IMoniker_BindToObject(pmkToLeft,pbc,NULL,&IID_IOleItemContainer,(void**)&poic);
877 res=IOleItemContainer_GetObject(poic,This->itemName,BINDSPEED_MODERATE,pbc,&IID_IParseDisplayName,(void**)&ppdn);
879 res=IMoniker_GetDisplayName(iface,pbc,NULL,&displayName);
881 res=IParseDisplayName_ParseDisplayName(ppdn,pbc,displayName,pchEaten,ppmkOut);
883 IOleItemContainer_Release(poic);
884 IParseDisplayName_Release(ppdn);
890 /******************************************************************************
891 * ItemMoniker_IsSystemMoniker
892 ******************************************************************************/
893 HRESULT WINAPI ItemMonikerImpl_IsSystemMoniker(IMoniker* iface,DWORD* pwdMksys)
895 TRACE("(%p,%p)\n",iface,pwdMksys);
900 (*pwdMksys)=MKSYS_ITEMMONIKER;
905 /*******************************************************************************
906 * ItemMonikerIROTData_QueryInterface
907 *******************************************************************************/
908 HRESULT WINAPI ItemMonikerROTDataImpl_QueryInterface(IROTData *iface,REFIID riid,VOID** ppvObject)
911 ICOM_THIS_From_IROTData(IMoniker, iface);
913 TRACE("(%p,%p,%p)\n",iface,riid,ppvObject);
915 return ItemMonikerImpl_QueryInterface(This, riid, ppvObject);
918 /***********************************************************************
919 * ItemMonikerIROTData_AddRef
921 ULONG WINAPI ItemMonikerROTDataImpl_AddRef(IROTData *iface)
923 ICOM_THIS_From_IROTData(IMoniker, iface);
925 TRACE("(%p)\n",iface);
927 return ItemMonikerImpl_AddRef(This);
930 /***********************************************************************
931 * ItemMonikerIROTData_Release
933 ULONG WINAPI ItemMonikerROTDataImpl_Release(IROTData* iface)
935 ICOM_THIS_From_IROTData(IMoniker, iface);
937 TRACE("(%p)\n",iface);
939 return ItemMonikerImpl_Release(This);
942 /******************************************************************************
943 * ItemMonikerIROTData_GetComparaisonData
944 ******************************************************************************/
945 HRESULT WINAPI ItemMonikerROTDataImpl_GetComparaisonData(IROTData* iface,
954 /******************************************************************************
955 * CreateItemMoniker16 [OLE2.28]
956 ******************************************************************************/
957 HRESULT WINAPI CreateItemMoniker16(LPCOLESTR16 lpszDelim,LPCOLESTR lpszItem,LPMONIKER* ppmk)
960 FIXME("(%s,%p),stub!\n",lpszDelim,ppmk);
965 /******************************************************************************
966 * CreateItemMoniker [OLE32.58]
967 ******************************************************************************/
968 HRESULT WINAPI CreateItemMoniker(LPCOLESTR lpszDelim,LPCOLESTR lpszItem, LPMONIKER * ppmk)
970 ItemMonikerImpl* newItemMoniker = 0;
972 IID riid=IID_IMoniker;
974 TRACE("(%p,%p,%p)\n",lpszDelim,lpszItem,ppmk);
976 newItemMoniker = HeapAlloc(GetProcessHeap(), 0, sizeof(ItemMonikerImpl));
978 if (newItemMoniker == 0)
979 return STG_E_INSUFFICIENTMEMORY;
981 hr = ItemMonikerImpl_Construct(newItemMoniker,lpszDelim,lpszItem);
985 HeapFree(GetProcessHeap(),0,newItemMoniker);
989 return ItemMonikerImpl_QueryInterface((IMoniker*)newItemMoniker,&riid,(void**)ppmk);