Add a few extra fields to HTTP_GetStdHeaderIndex.
[wine.git] / dlls / ole32 / itemmoniker.c
blobec6d5a3d203354436a822856092125327dd35ef0
1 /***************************************************************************************
2 * ItemMonikers implementation
4 * Copyright 1999 Noomen Hamza
5 ***************************************************************************************/
7 #include <assert.h>
8 #include <string.h>
9 #include "winerror.h"
10 #include "winbase.h"
11 #include "winnls.h"
12 #include "debugtools.h"
13 #include "wine/obj_base.h"
14 #include "wine/obj_misc.h"
15 #include "wine/obj_storage.h"
16 #include "wine/obj_moniker.h"
17 #include "wine/obj_inplace.h"
18 #include "wine/unicode.h"
20 DEFAULT_DEBUG_CHANNEL(ole);
22 /* ItemMoniker data structure */
23 typedef struct ItemMonikerImpl{
25 ICOM_VTABLE(IMoniker)* lpvtbl1; /* VTable relative to the IMoniker interface.*/
27 /* The ROT (RunningObjectTable implementation) uses the IROTData interface to test whether
28 * two monikers are equal. That's whay IROTData interface is implemented by monikers.
30 ICOM_VTABLE(IROTData)* lpvtbl2; /* VTable relative to the IROTData interface.*/
32 ULONG ref; /* reference counter for this object */
34 LPOLESTR itemName; /* item name identified by this ItemMoniker */
36 LPOLESTR itemDelimiter; /* Delimiter string */
38 } ItemMonikerImpl;
40 /********************************************************************************/
41 /* ItemMoniker prototype functions : */
43 /* IUnknown prototype functions */
44 static HRESULT WINAPI ItemMonikerImpl_QueryInterface(IMoniker* iface,REFIID riid,void** ppvObject);
45 static ULONG WINAPI ItemMonikerImpl_AddRef(IMoniker* iface);
46 static ULONG WINAPI ItemMonikerImpl_Release(IMoniker* iface);
48 /* IPersist prototype functions */
49 static HRESULT WINAPI ItemMonikerImpl_GetClassID(IMoniker* iface, CLSID *pClassID);
51 /* IPersistStream prototype functions */
52 static HRESULT WINAPI ItemMonikerImpl_IsDirty(IMoniker* iface);
53 static HRESULT WINAPI ItemMonikerImpl_Load(IMoniker* iface, IStream* pStm);
54 static HRESULT WINAPI ItemMonikerImpl_Save(IMoniker* iface, IStream* pStm, BOOL fClearDirty);
55 static HRESULT WINAPI ItemMonikerImpl_GetSizeMax(IMoniker* iface, ULARGE_INTEGER* pcbSize);
57 /* IMoniker prototype functions */
58 static HRESULT WINAPI ItemMonikerImpl_BindToObject(IMoniker* iface,IBindCtx* pbc, IMoniker* pmkToLeft, REFIID riid, VOID** ppvResult);
59 static HRESULT WINAPI ItemMonikerImpl_BindToStorage(IMoniker* iface,IBindCtx* pbc, IMoniker* pmkToLeft, REFIID riid, VOID** ppvResult);
60 static HRESULT WINAPI ItemMonikerImpl_Reduce(IMoniker* iface,IBindCtx* pbc, DWORD dwReduceHowFar,IMoniker** ppmkToLeft, IMoniker** ppmkReduced);
61 static HRESULT WINAPI ItemMonikerImpl_ComposeWith(IMoniker* iface,IMoniker* pmkRight,BOOL fOnlyIfNotGeneric, IMoniker** ppmkComposite);
62 static HRESULT WINAPI ItemMonikerImpl_Enum(IMoniker* iface,BOOL fForward, IEnumMoniker** ppenumMoniker);
63 static HRESULT WINAPI ItemMonikerImpl_IsEqual(IMoniker* iface,IMoniker* pmkOtherMoniker);
64 static HRESULT WINAPI ItemMonikerImpl_Hash(IMoniker* iface,DWORD* pdwHash);
65 static HRESULT WINAPI ItemMonikerImpl_IsRunning(IMoniker* iface,IBindCtx* pbc, IMoniker* pmkToLeft, IMoniker* pmkNewlyRunning);
66 static HRESULT WINAPI ItemMonikerImpl_GetTimeOfLastChange(IMoniker* iface, IBindCtx* pbc, IMoniker* pmkToLeft, FILETIME* pItemTime);
67 static HRESULT WINAPI ItemMonikerImpl_Inverse(IMoniker* iface,IMoniker** ppmk);
68 static HRESULT WINAPI ItemMonikerImpl_CommonPrefixWith(IMoniker* iface,IMoniker* pmkOther, IMoniker** ppmkPrefix);
69 static HRESULT WINAPI ItemMonikerImpl_RelativePathTo(IMoniker* iface,IMoniker* pmOther, IMoniker** ppmkRelPath);
70 static HRESULT WINAPI ItemMonikerImpl_GetDisplayName(IMoniker* iface,IBindCtx* pbc, IMoniker* pmkToLeft, LPOLESTR *ppszDisplayName);
71 static HRESULT WINAPI ItemMonikerImpl_ParseDisplayName(IMoniker* iface,IBindCtx* pbc, IMoniker* pmkToLeft, LPOLESTR pszDisplayName, ULONG* pchEaten, IMoniker** ppmkOut);
72 static HRESULT WINAPI ItemMonikerImpl_IsSystemMoniker(IMoniker* iface,DWORD* pwdMksys);
74 /* Local function used by ItemMoniker implementation */
75 HRESULT WINAPI ItemMonikerImpl_Construct(ItemMonikerImpl* iface, LPCOLESTR lpszDelim,LPCOLESTR lpszPathName);
76 HRESULT WINAPI ItemMonikerImpl_Destroy(ItemMonikerImpl* iface);
78 /********************************************************************************/
79 /* IROTData prototype functions */
81 /* IUnknown prototype functions */
82 static HRESULT WINAPI ItemMonikerROTDataImpl_QueryInterface(IROTData* iface,REFIID riid,VOID** ppvObject);
83 static ULONG WINAPI ItemMonikerROTDataImpl_AddRef(IROTData* iface);
84 static ULONG WINAPI ItemMonikerROTDataImpl_Release(IROTData* iface);
86 /* IROTData prototype function */
87 static HRESULT WINAPI ItemMonikerROTDataImpl_GetComparaisonData(IROTData* iface,BYTE* pbData,ULONG cbMax,ULONG* pcbData);
89 /********************************************************************************/
90 /* Virtual function table for the ItemMonikerImpl class which include IPersist,*/
91 /* IPersistStream and IMoniker functions. */
92 static ICOM_VTABLE(IMoniker) VT_ItemMonikerImpl =
94 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
95 ItemMonikerImpl_QueryInterface,
96 ItemMonikerImpl_AddRef,
97 ItemMonikerImpl_Release,
98 ItemMonikerImpl_GetClassID,
99 ItemMonikerImpl_IsDirty,
100 ItemMonikerImpl_Load,
101 ItemMonikerImpl_Save,
102 ItemMonikerImpl_GetSizeMax,
103 ItemMonikerImpl_BindToObject,
104 ItemMonikerImpl_BindToStorage,
105 ItemMonikerImpl_Reduce,
106 ItemMonikerImpl_ComposeWith,
107 ItemMonikerImpl_Enum,
108 ItemMonikerImpl_IsEqual,
109 ItemMonikerImpl_Hash,
110 ItemMonikerImpl_IsRunning,
111 ItemMonikerImpl_GetTimeOfLastChange,
112 ItemMonikerImpl_Inverse,
113 ItemMonikerImpl_CommonPrefixWith,
114 ItemMonikerImpl_RelativePathTo,
115 ItemMonikerImpl_GetDisplayName,
116 ItemMonikerImpl_ParseDisplayName,
117 ItemMonikerImpl_IsSystemMoniker
120 /********************************************************************************/
121 /* Virtual function table for the IROTData class. */
122 static ICOM_VTABLE(IROTData) VT_ROTDataImpl =
124 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
125 ItemMonikerROTDataImpl_QueryInterface,
126 ItemMonikerROTDataImpl_AddRef,
127 ItemMonikerROTDataImpl_Release,
128 ItemMonikerROTDataImpl_GetComparaisonData
131 /*******************************************************************************
132 * ItemMoniker_QueryInterface
133 *******************************************************************************/
134 HRESULT WINAPI ItemMonikerImpl_QueryInterface(IMoniker* iface,REFIID riid,void** ppvObject)
136 ICOM_THIS(ItemMonikerImpl,iface);
138 TRACE("(%p,%p,%p)\n",This,riid,ppvObject);
140 /* Perform a sanity check on the parameters.*/
141 if ( (This==0) || (ppvObject==0) )
142 return E_INVALIDARG;
144 /* Initialize the return parameter */
145 *ppvObject = 0;
147 /* Compare the riid with the interface IDs implemented by this object.*/
148 if (IsEqualIID(&IID_IUnknown, riid) ||
149 IsEqualIID(&IID_IPersist, riid) ||
150 IsEqualIID(&IID_IPersistStream, riid) ||
151 IsEqualIID(&IID_IMoniker, riid)
153 *ppvObject = iface;
155 else if (IsEqualIID(&IID_IROTData, riid))
156 *ppvObject = (IROTData*)&(This->lpvtbl2);
158 /* Check that we obtained an interface.*/
159 if ((*ppvObject)==0)
160 return E_NOINTERFACE;
162 /* Query Interface always increases the reference count by one when it is successful */
163 ItemMonikerImpl_AddRef(iface);
165 return S_OK;
168 /******************************************************************************
169 * ItemMoniker_AddRef
170 ******************************************************************************/
171 ULONG WINAPI ItemMonikerImpl_AddRef(IMoniker* iface)
173 ICOM_THIS(ItemMonikerImpl,iface);
175 TRACE("(%p)\n",This);
177 return ++(This->ref);
180 /******************************************************************************
181 * ItemMoniker_Release
182 ******************************************************************************/
183 ULONG WINAPI ItemMonikerImpl_Release(IMoniker* iface)
185 ICOM_THIS(ItemMonikerImpl,iface);
187 TRACE("(%p)\n",This);
189 This->ref--;
191 /* destroy the object if there's no more reference on it */
192 if (This->ref==0){
194 ItemMonikerImpl_Destroy(This);
196 return 0;
198 return This->ref;;
201 /******************************************************************************
202 * ItemMoniker_GetClassID
203 ******************************************************************************/
204 HRESULT WINAPI ItemMonikerImpl_GetClassID(IMoniker* iface,CLSID *pClassID)
206 TRACE("(%p,%p),stub!\n",iface,pClassID);
208 if (pClassID==NULL)
209 return E_POINTER;
211 *pClassID = CLSID_ItemMoniker;
213 return S_OK;
216 /******************************************************************************
217 * ItemMoniker_IsDirty
218 ******************************************************************************/
219 HRESULT WINAPI ItemMonikerImpl_IsDirty(IMoniker* iface)
221 /* Note that the OLE-provided implementations of the IPersistStream::IsDirty
222 method in the OLE-provided moniker interfaces always return S_FALSE because
223 their internal state never changes. */
225 TRACE("(%p)\n",iface);
227 return S_FALSE;
230 /******************************************************************************
231 * ItemMoniker_Load
232 ******************************************************************************/
233 HRESULT WINAPI ItemMonikerImpl_Load(IMoniker* iface,IStream* pStm)
236 ICOM_THIS(ItemMonikerImpl,iface);
237 HRESULT res;
238 DWORD delimiterLength,nameLength,lenW;
239 CHAR *itemNameA,*itemDelimiterA;
240 ULONG bread;
242 /* for more details about data read by this function see coments of ItemMonikerImpl_Save function */
244 /* read item delimiter string length + 1 */
245 res=IStream_Read(pStm,&delimiterLength,sizeof(DWORD),&bread);
246 if (bread != sizeof(DWORD))
247 return E_FAIL;
249 /* read item delimiter string */
250 if (!(itemDelimiterA=HeapAlloc(GetProcessHeap(),0,delimiterLength)))
251 return E_OUTOFMEMORY;
252 res=IStream_Read(pStm,itemDelimiterA,delimiterLength,&bread);
253 if (bread != delimiterLength)
255 HeapFree( GetProcessHeap(), 0, itemDelimiterA );
256 return E_FAIL;
259 lenW = MultiByteToWideChar( CP_ACP, 0, itemDelimiterA, -1, NULL, 0 );
260 This->itemDelimiter=HeapReAlloc(GetProcessHeap(),0,This->itemDelimiter,lenW*sizeof(WCHAR));
261 if (!This->itemDelimiter)
263 HeapFree( GetProcessHeap(), 0, itemDelimiterA );
264 return E_OUTOFMEMORY;
266 MultiByteToWideChar( CP_ACP, 0, itemDelimiterA, -1, This->itemDelimiter, lenW );
267 HeapFree( GetProcessHeap(), 0, itemDelimiterA );
269 /* read item name string length + 1*/
270 res=IStream_Read(pStm,&nameLength,sizeof(DWORD),&bread);
271 if (bread != sizeof(DWORD))
272 return E_FAIL;
274 /* read item name string */
275 if (!(itemNameA=HeapAlloc(GetProcessHeap(),0,nameLength)))
276 return E_OUTOFMEMORY;
277 res=IStream_Read(pStm,itemNameA,nameLength,&bread);
278 if (bread != nameLength)
280 HeapFree( GetProcessHeap(), 0, itemNameA );
281 return E_FAIL;
284 lenW = MultiByteToWideChar( CP_ACP, 0, itemNameA, -1, NULL, 0 );
285 This->itemName=HeapReAlloc(GetProcessHeap(),0,This->itemName,lenW*sizeof(WCHAR));
286 if (!This->itemName)
288 HeapFree( GetProcessHeap(), 0, itemNameA );
289 return E_OUTOFMEMORY;
291 MultiByteToWideChar( CP_ACP, 0, itemNameA, -1, This->itemName, lenW );
292 HeapFree( GetProcessHeap(), 0, itemNameA );
294 return res;
297 /******************************************************************************
298 * ItemMoniker_Save
299 ******************************************************************************/
300 HRESULT WINAPI ItemMonikerImpl_Save(IMoniker* iface,
301 IStream* pStm,/* pointer to the stream where the object is to be saved */
302 BOOL fClearDirty)/* Specifies whether to clear the dirty flag */
304 ICOM_THIS(ItemMonikerImpl,iface);
305 HRESULT res;
306 CHAR *itemNameA,*itemDelimiterA;
308 /* data writen by this function are : 1) DWORD : size of item delimiter string ('\0' included ) */
309 /* 2) String (type A): item delimiter string ('\0' included) */
310 /* 3) DWORD : size of item name string ('\0' included) */
311 /* 4) String (type A): item name string ('\0' included) */
313 DWORD nameLength = WideCharToMultiByte( CP_ACP, 0, This->itemName, -1, NULL, 0, NULL, NULL);
314 DWORD delimiterLength = WideCharToMultiByte( CP_ACP, 0, This->itemDelimiter, -1, NULL, 0, NULL, NULL);
315 itemNameA=HeapAlloc(GetProcessHeap(),0,nameLength);
316 itemDelimiterA=HeapAlloc(GetProcessHeap(),0,delimiterLength);
317 WideCharToMultiByte( CP_ACP, 0, This->itemName, -1, itemNameA, nameLength, NULL, NULL);
318 WideCharToMultiByte( CP_ACP, 0, This->itemDelimiter, -1, itemDelimiterA, delimiterLength, NULL, NULL);
320 res=IStream_Write(pStm,&delimiterLength,sizeof(DWORD),NULL);
321 res=IStream_Write(pStm,itemDelimiterA,delimiterLength * sizeof(CHAR),NULL);
322 res=IStream_Write(pStm,&nameLength,sizeof(DWORD),NULL);
323 res=IStream_Write(pStm,itemNameA,nameLength * sizeof(CHAR),NULL);
325 return res;
328 /******************************************************************************
329 * ItemMoniker_GetSizeMax
330 ******************************************************************************/
331 HRESULT WINAPI ItemMonikerImpl_GetSizeMax(IMoniker* iface,
332 ULARGE_INTEGER* pcbSize)/* Pointer to size of stream needed to save object */
334 ICOM_THIS(ItemMonikerImpl,iface);
335 DWORD delimiterLength=lstrlenW(This->itemDelimiter)+1;
336 DWORD nameLength=lstrlenW(This->itemName)+1;
338 TRACE("(%p,%p)\n",iface,pcbSize);
340 if (pcbSize!=NULL)
341 return E_POINTER;
343 /* for more details see ItemMonikerImpl_Save coments */
345 pcbSize->s.LowPart = sizeof(DWORD) + /* DWORD which contains delimiter length */
346 delimiterLength + /* item delimiter string */
347 sizeof(DWORD) + /* DWORD which contains item name length */
348 nameLength + /* item name string */
349 34; /* this constant was added ! because when I tested this function it usually */
350 /* returns 34 bytes more than the number of bytes used by IMoniker::Save function */
351 pcbSize->s.HighPart=0;
353 return S_OK;
356 /******************************************************************************
357 * ItemMoniker_Construct (local function)
358 *******************************************************************************/
359 HRESULT WINAPI ItemMonikerImpl_Construct(ItemMonikerImpl* This, LPCOLESTR lpszDelim,LPCOLESTR lpszItem)
362 int sizeStr1=lstrlenW(lpszItem), sizeStr2;
363 static const OLECHAR emptystr[1];
364 LPCOLESTR delim;
366 TRACE("(%p,%p)\n",This,lpszItem);
368 /* Initialize the virtual fgunction table. */
369 This->lpvtbl1 = &VT_ItemMonikerImpl;
370 This->lpvtbl2 = &VT_ROTDataImpl;
371 This->ref = 0;
373 This->itemName=HeapAlloc(GetProcessHeap(),0,sizeof(WCHAR)*(sizeStr1+1));
374 if (!This->itemName)
375 return E_OUTOFMEMORY;
376 strcpyW(This->itemName,lpszItem);
378 if (!lpszDelim)
379 FIXME("lpszDelim is NULL. Using empty string which is possibly wrong.\n");
381 delim = lpszDelim ? lpszDelim : emptystr;
383 sizeStr2=strlenW(delim);
384 This->itemDelimiter=HeapAlloc(GetProcessHeap(),0,sizeof(WCHAR)*(sizeStr2+1));
385 if (!This->itemDelimiter) {
386 HeapFree(GetProcessHeap(),0,This->itemName);
387 return E_OUTOFMEMORY;
389 strcpyW(This->itemDelimiter,delim);
390 return S_OK;
393 /******************************************************************************
394 * ItemMoniker_Destroy (local function)
395 *******************************************************************************/
396 HRESULT WINAPI ItemMonikerImpl_Destroy(ItemMonikerImpl* This)
398 TRACE("(%p)\n",This);
400 if (This->itemName)
401 HeapFree(GetProcessHeap(),0,This->itemName);
403 if (This->itemDelimiter)
404 HeapFree(GetProcessHeap(),0,This->itemDelimiter);
406 HeapFree(GetProcessHeap(),0,This);
408 return S_OK;
411 /******************************************************************************
412 * ItemMoniker_BindToObject
413 ******************************************************************************/
414 HRESULT WINAPI ItemMonikerImpl_BindToObject(IMoniker* iface,
415 IBindCtx* pbc,
416 IMoniker* pmkToLeft,
417 REFIID riid,
418 VOID** ppvResult)
420 ICOM_THIS(ItemMonikerImpl,iface);
422 HRESULT res;
423 IID refid=IID_IOleItemContainer;
424 IOleItemContainer *poic=0;
426 TRACE("(%p,%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,riid,ppvResult);
428 if(ppvResult ==NULL)
429 return E_POINTER;
431 if(pmkToLeft==NULL)
432 return E_INVALIDARG;
434 *ppvResult=0;
436 res=IMoniker_BindToObject(pmkToLeft,pbc,NULL,&refid,(void**)&poic);
438 if (SUCCEEDED(res)){
440 res=IOleItemContainer_GetObject(poic,This->itemName,BINDSPEED_MODERATE,pbc,riid,ppvResult);
442 IOleItemContainer_Release(poic);
445 return res;
448 /******************************************************************************
449 * ItemMoniker_BindToStorage
450 ******************************************************************************/
451 HRESULT WINAPI ItemMonikerImpl_BindToStorage(IMoniker* iface,
452 IBindCtx* pbc,
453 IMoniker* pmkToLeft,
454 REFIID riid,
455 VOID** ppvResult)
457 ICOM_THIS(ItemMonikerImpl,iface);
459 HRESULT res;
460 IOleItemContainer *poic=0;
462 TRACE("(%p,%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,riid,ppvResult);
464 *ppvResult=0;
466 if(pmkToLeft==NULL)
467 return E_INVALIDARG;
469 res=IMoniker_BindToObject(pmkToLeft,pbc,NULL,&IID_IOleItemContainer,(void**)&poic);
471 if (SUCCEEDED(res)){
473 res=IOleItemContainer_GetObjectStorage(poic,This->itemName,pbc,riid,ppvResult);
475 IOleItemContainer_Release(poic);
478 return res;
481 /******************************************************************************
482 * ItemMoniker_Reduce
483 ******************************************************************************/
484 HRESULT WINAPI ItemMonikerImpl_Reduce(IMoniker* iface,
485 IBindCtx* pbc,
486 DWORD dwReduceHowFar,
487 IMoniker** ppmkToLeft,
488 IMoniker** ppmkReduced)
490 TRACE("(%p,%p,%ld,%p,%p)\n",iface,pbc,dwReduceHowFar,ppmkToLeft,ppmkReduced);
492 if (ppmkReduced==NULL)
493 return E_POINTER;
495 ItemMonikerImpl_AddRef(iface);
497 *ppmkReduced=iface;
499 return MK_S_REDUCED_TO_SELF;
501 /******************************************************************************
502 * ItemMoniker_ComposeWith
503 ******************************************************************************/
504 HRESULT WINAPI ItemMonikerImpl_ComposeWith(IMoniker* iface,
505 IMoniker* pmkRight,
506 BOOL fOnlyIfNotGeneric,
507 IMoniker** ppmkComposite)
509 HRESULT res=S_OK;
510 DWORD mkSys,mkSys2;
511 IEnumMoniker* penumMk=0;
512 IMoniker *pmostLeftMk=0;
513 IMoniker* tempMkComposite=0;
515 TRACE("(%p,%p,%d,%p)\n",iface,pmkRight,fOnlyIfNotGeneric,ppmkComposite);
517 if ((ppmkComposite==NULL)||(pmkRight==NULL))
518 return E_POINTER;
520 *ppmkComposite=0;
522 IMoniker_IsSystemMoniker(pmkRight,&mkSys);
524 /* If pmkRight is an anti-moniker, the returned moniker is NULL */
525 if(mkSys==MKSYS_ANTIMONIKER)
526 return res;
528 else
529 /* if pmkRight is a composite whose leftmost component is an anti-moniker, */
530 /* the returned moniker is the composite after the leftmost anti-moniker is removed. */
532 if(mkSys==MKSYS_GENERICCOMPOSITE){
534 res=IMoniker_Enum(pmkRight,TRUE,&penumMk);
536 if (FAILED(res))
537 return res;
539 res=IEnumMoniker_Next(penumMk,1,&pmostLeftMk,NULL);
541 IMoniker_IsSystemMoniker(pmostLeftMk,&mkSys2);
543 if(mkSys2==MKSYS_ANTIMONIKER){
545 IMoniker_Release(pmostLeftMk);
547 tempMkComposite=iface;
548 IMoniker_AddRef(iface);
550 while(IEnumMoniker_Next(penumMk,1,&pmostLeftMk,NULL)==S_OK){
552 res=CreateGenericComposite(tempMkComposite,pmostLeftMk,ppmkComposite);
554 IMoniker_Release(tempMkComposite);
555 IMoniker_Release(pmostLeftMk);
557 tempMkComposite=*ppmkComposite;
558 IMoniker_AddRef(tempMkComposite);
560 return res;
562 else
563 return CreateGenericComposite(iface,pmkRight,ppmkComposite);
565 /* If pmkRight is not an anti-moniker, the method combines the two monikers into a generic
566 composite if fOnlyIfNotGeneric is FALSE; if fOnlyIfNotGeneric is TRUE, the method returns
567 a NULL moniker and a return value of MK_E_NEEDGENERIC */
568 else
569 if (!fOnlyIfNotGeneric)
570 return CreateGenericComposite(iface,pmkRight,ppmkComposite);
572 else
573 return MK_E_NEEDGENERIC;
576 /******************************************************************************
577 * ItemMoniker_Enum
578 ******************************************************************************/
579 HRESULT WINAPI ItemMonikerImpl_Enum(IMoniker* iface,BOOL fForward, IEnumMoniker** ppenumMoniker)
581 TRACE("(%p,%d,%p)\n",iface,fForward,ppenumMoniker);
583 if (ppenumMoniker == NULL)
584 return E_POINTER;
586 *ppenumMoniker = NULL;
588 return S_OK;
591 /******************************************************************************
592 * ItemMoniker_IsEqual
593 ******************************************************************************/
594 HRESULT WINAPI ItemMonikerImpl_IsEqual(IMoniker* iface,IMoniker* pmkOtherMoniker)
597 CLSID clsid;
598 LPOLESTR dispName1,dispName2;
599 IBindCtx* bind;
600 HRESULT res;
602 TRACE("(%p,%p)\n",iface,pmkOtherMoniker);
604 if (pmkOtherMoniker==NULL)
605 return S_FALSE;
607 /* This method returns S_OK if both monikers are item monikers and their display names are */
608 /* identical (using a case-insensitive comparison); otherwise, the method returns S_FALSE. */
610 IMoniker_GetClassID(pmkOtherMoniker,&clsid);
612 if (!IsEqualCLSID(&clsid,&CLSID_ItemMoniker))
613 return S_FALSE;
615 res=CreateBindCtx(0,&bind);
616 if (FAILED(res))
617 return res;
619 IMoniker_GetDisplayName(iface,bind,NULL,&dispName1);
620 IMoniker_GetDisplayName(pmkOtherMoniker,bind,NULL,&dispName2);
622 if (lstrcmpW(dispName1,dispName2)!=0)
623 return S_FALSE;
625 return S_OK;
628 /******************************************************************************
629 * ItemMoniker_Hash
630 ******************************************************************************/
631 HRESULT WINAPI ItemMonikerImpl_Hash(IMoniker* iface,DWORD* pdwHash)
633 ICOM_THIS(ItemMonikerImpl,iface);
635 int h = 0,i,skip,len;
636 int off = 0;
637 LPOLESTR val;
639 if (pdwHash==NULL)
640 return E_POINTER;
642 val = This->itemName;
643 len = lstrlenW(val);
645 if (len < 16) {
646 for (i = len ; i > 0; i--) {
647 h = (h * 37) + val[off++];
649 } else {
650 /* only sample some characters */
651 skip = len / 8;
652 for (i = len ; i > 0; i -= skip, off += skip) {
653 h = (h * 39) + val[off];
657 *pdwHash=h;
659 return S_OK;
662 /******************************************************************************
663 * ItemMoniker_IsRunning
664 ******************************************************************************/
665 HRESULT WINAPI ItemMonikerImpl_IsRunning(IMoniker* iface,
666 IBindCtx* pbc,
667 IMoniker* pmkToLeft,
668 IMoniker* pmkNewlyRunning)
670 IRunningObjectTable* rot;
671 HRESULT res;
672 IOleItemContainer *poic=0;
673 ICOM_THIS(ItemMonikerImpl,iface);
675 TRACE("(%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,pmkNewlyRunning);
677 /* If pmkToLeft is NULL, this method returns TRUE if pmkNewlyRunning is non-NULL and is equal to this */
678 /* moniker. Otherwise, the method checks the ROT to see whether this moniker is running. */
679 if (pmkToLeft==NULL)
680 if ((pmkNewlyRunning!=NULL)&&(IMoniker_IsEqual(pmkNewlyRunning,iface)==S_OK))
681 return S_OK;
682 else {
683 if (pbc==NULL)
684 return E_POINTER;
686 res=IBindCtx_GetRunningObjectTable(pbc,&rot);
688 if (FAILED(res))
689 return res;
691 res = IRunningObjectTable_IsRunning(rot,iface);
693 IRunningObjectTable_Release(rot);
695 else{
697 /* If pmkToLeft is non-NULL, the method calls IMoniker::BindToObject on the pmkToLeft parameter, */
698 /* requesting an IOleItemContainer interface pointer. The method then calls IOleItemContainer::IsRunning,*/
699 /* passing the string contained within this moniker. */
701 res=IMoniker_BindToObject(pmkToLeft,pbc,NULL,&IID_IOleItemContainer,(void**)&poic);
703 if (SUCCEEDED(res)){
705 res=IOleItemContainer_IsRunning(poic,This->itemName);
707 IOleItemContainer_Release(poic);
711 return res;
714 /******************************************************************************
715 * ItemMoniker_GetTimeOfLastChange
716 ******************************************************************************/
717 HRESULT WINAPI ItemMonikerImpl_GetTimeOfLastChange(IMoniker* iface,
718 IBindCtx* pbc,
719 IMoniker* pmkToLeft,
720 FILETIME* pItemTime)
722 IRunningObjectTable* rot;
723 HRESULT res;
724 IMoniker *compositeMk;
726 TRACE("(%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,pItemTime);
728 if (pItemTime==NULL)
729 return E_INVALIDARG;
731 /* If pmkToLeft is NULL, this method returns MK_E_NOTBINDABLE */
732 if (pmkToLeft==NULL)
734 return MK_E_NOTBINDABLE;
735 else {
737 /* Otherwise, the method creates a composite of pmkToLeft and this moniker and uses the ROT to access */
738 /* the time of last change. If the object is not in the ROT, the method calls */
739 /* IMoniker::GetTimeOfLastChange on the pmkToLeft parameter. */
741 res=CreateGenericComposite(pmkToLeft,iface,&compositeMk);
743 res=IBindCtx_GetRunningObjectTable(pbc,&rot);
745 if (IRunningObjectTable_GetTimeOfLastChange(rot,compositeMk,pItemTime)!=S_OK)
747 res=IMoniker_GetTimeOfLastChange(pmkToLeft,pbc,NULL,pItemTime);
749 IMoniker_Release(compositeMk);
752 return res;
755 /******************************************************************************
756 * ItemMoniker_Inverse
757 ******************************************************************************/
758 HRESULT WINAPI ItemMonikerImpl_Inverse(IMoniker* iface,IMoniker** ppmk)
760 TRACE("(%p,%p)\n",iface,ppmk);
762 if (ppmk==NULL)
763 return E_POINTER;
765 return CreateAntiMoniker(ppmk);
768 /******************************************************************************
769 * ItemMoniker_CommonPrefixWith
770 ******************************************************************************/
771 HRESULT WINAPI ItemMonikerImpl_CommonPrefixWith(IMoniker* iface,IMoniker* pmkOther,IMoniker** ppmkPrefix)
773 DWORD mkSys;
774 IMoniker_IsSystemMoniker(pmkOther,&mkSys);
775 /* If the other moniker is an item moniker that is equal to this moniker, this method sets *ppmkPrefix */
776 /* to this moniker and returns MK_S_US */
778 if((mkSys==MKSYS_ITEMMONIKER) && (IMoniker_IsEqual(iface,pmkOther)==S_OK) ){
780 *ppmkPrefix=iface;
782 IMoniker_AddRef(iface);
784 return MK_S_US;
786 else
787 /* otherwise, the method calls the MonikerCommonPrefixWith function. This function correctly handles */
788 /* the case where the other moniker is a generic composite. */
789 return MonikerCommonPrefixWith(iface,pmkOther,ppmkPrefix);
792 /******************************************************************************
793 * ItemMoniker_RelativePathTo
794 ******************************************************************************/
795 HRESULT WINAPI ItemMonikerImpl_RelativePathTo(IMoniker* iface,IMoniker* pmOther, IMoniker** ppmkRelPath)
797 TRACE("(%p,%p,%p)\n",iface,pmOther,ppmkRelPath);
799 if (ppmkRelPath==NULL)
800 return E_POINTER;
802 *ppmkRelPath=0;
804 return MK_E_NOTBINDABLE;
807 /******************************************************************************
808 * ItemMoniker_GetDisplayName
809 ******************************************************************************/
810 HRESULT WINAPI ItemMonikerImpl_GetDisplayName(IMoniker* iface,
811 IBindCtx* pbc,
812 IMoniker* pmkToLeft,
813 LPOLESTR *ppszDisplayName)
815 ICOM_THIS(ItemMonikerImpl,iface);
817 TRACE("(%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,ppszDisplayName);
819 if (ppszDisplayName==NULL)
820 return E_POINTER;
822 if (pmkToLeft!=NULL){
823 return E_INVALIDARG;
826 *ppszDisplayName=CoTaskMemAlloc(sizeof(WCHAR)*(lstrlenW(This->itemDelimiter)+lstrlenW(This->itemName)+1));
828 if (*ppszDisplayName==NULL)
829 return E_OUTOFMEMORY;
831 strcpyW(*ppszDisplayName,This->itemDelimiter);
832 strcatW(*ppszDisplayName,This->itemName);
834 return S_OK;
837 /******************************************************************************
838 * ItemMoniker_ParseDisplayName
839 ******************************************************************************/
840 HRESULT WINAPI ItemMonikerImpl_ParseDisplayName(IMoniker* iface,
841 IBindCtx* pbc,
842 IMoniker* pmkToLeft,
843 LPOLESTR pszDisplayName,
844 ULONG* pchEaten,
845 IMoniker** ppmkOut)
847 IOleItemContainer* poic=0;
848 IParseDisplayName* ppdn=0;
849 LPOLESTR displayName;
850 HRESULT res;
851 ICOM_THIS(ItemMonikerImpl,iface);
853 /* If pmkToLeft is NULL, this method returns MK_E_SYNTAX */
854 if (pmkToLeft==NULL)
856 return MK_E_SYNTAX;
858 else{
859 /* Otherwise, the method calls IMoniker::BindToObject on the pmkToLeft parameter, requesting an */
860 /* IParseDisplayName interface pointer to the object identified by the moniker, and passes the display */
861 /* name to IParseDisplayName::ParseDisplayName */
862 res=IMoniker_BindToObject(pmkToLeft,pbc,NULL,&IID_IOleItemContainer,(void**)&poic);
864 if (SUCCEEDED(res)){
866 res=IOleItemContainer_GetObject(poic,This->itemName,BINDSPEED_MODERATE,pbc,&IID_IParseDisplayName,(void**)&ppdn);
868 res=IMoniker_GetDisplayName(iface,pbc,NULL,&displayName);
870 res=IParseDisplayName_ParseDisplayName(ppdn,pbc,displayName,pchEaten,ppmkOut);
872 IOleItemContainer_Release(poic);
873 IParseDisplayName_Release(ppdn);
876 return res;
879 /******************************************************************************
880 * ItemMoniker_IsSystemMoniker
881 ******************************************************************************/
882 HRESULT WINAPI ItemMonikerImpl_IsSystemMoniker(IMoniker* iface,DWORD* pwdMksys)
884 TRACE("(%p,%p)\n",iface,pwdMksys);
886 if (!pwdMksys)
887 return E_POINTER;
889 (*pwdMksys)=MKSYS_ITEMMONIKER;
891 return S_OK;
894 /*******************************************************************************
895 * ItemMonikerIROTData_QueryInterface
896 *******************************************************************************/
897 HRESULT WINAPI ItemMonikerROTDataImpl_QueryInterface(IROTData *iface,REFIID riid,VOID** ppvObject)
900 ICOM_THIS_From_IROTData(IMoniker, iface);
902 TRACE("(%p,%p,%p)\n",iface,riid,ppvObject);
904 return ItemMonikerImpl_QueryInterface(This, riid, ppvObject);
907 /***********************************************************************
908 * ItemMonikerIROTData_AddRef
910 ULONG WINAPI ItemMonikerROTDataImpl_AddRef(IROTData *iface)
912 ICOM_THIS_From_IROTData(IMoniker, iface);
914 TRACE("(%p)\n",iface);
916 return ItemMonikerImpl_AddRef(This);
919 /***********************************************************************
920 * ItemMonikerIROTData_Release
922 ULONG WINAPI ItemMonikerROTDataImpl_Release(IROTData* iface)
924 ICOM_THIS_From_IROTData(IMoniker, iface);
926 TRACE("(%p)\n",iface);
928 return ItemMonikerImpl_Release(This);
931 /******************************************************************************
932 * ItemMonikerIROTData_GetComparaisonData
933 ******************************************************************************/
934 HRESULT WINAPI ItemMonikerROTDataImpl_GetComparaisonData(IROTData* iface,
935 BYTE* pbData,
936 ULONG cbMax,
937 ULONG* pcbData)
939 FIXME("(),stub!\n");
940 return E_NOTIMPL;
943 /******************************************************************************
944 * CreateItemMoniker16 [OLE2.28]
945 ******************************************************************************/
946 HRESULT WINAPI CreateItemMoniker16(LPCOLESTR16 lpszDelim,LPCOLESTR lpszItem,LPMONIKER* ppmk)
949 FIXME("(%s,%p),stub!\n",lpszDelim,ppmk);
950 *ppmk = NULL;
951 return E_NOTIMPL;
954 /******************************************************************************
955 * CreateItemMoniker [OLE32.58]
956 ******************************************************************************/
957 HRESULT WINAPI CreateItemMoniker(LPCOLESTR lpszDelim,LPCOLESTR lpszItem, LPMONIKER * ppmk)
959 ItemMonikerImpl* newItemMoniker = 0;
960 HRESULT hr = S_OK;
961 IID riid=IID_IMoniker;
963 TRACE("(%p,%p,%p)\n",lpszDelim,lpszItem,ppmk);
965 newItemMoniker = HeapAlloc(GetProcessHeap(), 0, sizeof(ItemMonikerImpl));
967 if (newItemMoniker == 0)
968 return STG_E_INSUFFICIENTMEMORY;
970 hr = ItemMonikerImpl_Construct(newItemMoniker,lpszDelim,lpszItem);
972 if (FAILED(hr)){
974 HeapFree(GetProcessHeap(),0,newItemMoniker);
975 return hr;
978 return ItemMonikerImpl_QueryInterface((IMoniker*)newItemMoniker,&riid,(void**)ppmk);