source: trunk/src/ole32/itemmoniker.cpp@ 1036

Last change on this file since 1036 was 1033, checked in by davidr, 26 years ago

Ported remaining files pertaining to OLE32 from WINE

File size: 33.3 KB
Line 
1/* $Id: itemmoniker.cpp,v 1.1 1999-09-24 21:49:43 davidr Exp $ */
2/*
3 * ItemMonikers implementation
4 *
5 * 21/9/99
6 *
7 * Copyright 1999 David J. Raison
8 *
9 * Direct port of Wine Implementation
10 * Copyright 1999 Noomen Hamza
11 */
12#include "ole32.h"
13#include "heapstring.h"
14#include "debugtools.h"
15#include <assert.h>
16
17DEFAULT_DEBUG_CHANNEL(ole)
18
19/* ItemMoniker data structure */
20typedef struct ItemMonikerImpl{
21
22 ICOM_VTABLE(IMoniker)* lpvtbl1; /* VTable relative to the IMoniker interface.*/
23
24 /* The ROT (RunningObjectTable implementation) uses the IROTData interface to test whether
25 * two monikers are equal. That's whay IROTData interface is implemented by monikers.
26 */
27 ICOM_VTABLE(IROTData)* lpvtbl2; /* VTable relative to the IROTData interface.*/
28
29 ULONG ref; /* reference counter for this object */
30
31 LPOLESTR itemName; /* item name identified by this ItemMoniker */
32
33 LPOLESTR itemDelimiter; /* Delimiter string */
34
35} ItemMonikerImpl;
36
37/********************************************************************************/
38/* ItemMoniker prototype functions : */
39
40/* IUnknown prototype functions */
41static HRESULT WINAPI ItemMonikerImpl_QueryInterface(IMoniker* iface,REFIID riid,void** ppvObject);
42static ULONG WINAPI ItemMonikerImpl_AddRef(IMoniker* iface);
43static ULONG WINAPI ItemMonikerImpl_Release(IMoniker* iface);
44
45/* IPersist prototype functions */
46static HRESULT WINAPI ItemMonikerImpl_GetClassID(IMoniker* iface, CLSID *pClassID);
47
48/* IPersistStream prototype functions */
49static HRESULT WINAPI ItemMonikerImpl_IsDirty(IMoniker* iface);
50static HRESULT WINAPI ItemMonikerImpl_Load(IMoniker* iface, IStream* pStm);
51static HRESULT WINAPI ItemMonikerImpl_Save(IMoniker* iface, IStream* pStm, BOOL fClearDirty);
52static HRESULT WINAPI ItemMonikerImpl_GetSizeMax(IMoniker* iface, ULARGE_INTEGER* pcbSize);
53
54/* IMoniker prototype functions */
55static HRESULT WINAPI ItemMonikerImpl_BindToObject(IMoniker* iface,IBindCtx* pbc, IMoniker* pmkToLeft, REFIID riid, VOID** ppvResult);
56static HRESULT WINAPI ItemMonikerImpl_BindToStorage(IMoniker* iface,IBindCtx* pbc, IMoniker* pmkToLeft, REFIID riid, VOID** ppvResult);
57static HRESULT WINAPI ItemMonikerImpl_Reduce(IMoniker* iface,IBindCtx* pbc, DWORD dwReduceHowFar,IMoniker** ppmkToLeft, IMoniker** ppmkReduced);
58static HRESULT WINAPI ItemMonikerImpl_ComposeWith(IMoniker* iface,IMoniker* pmkRight,BOOL fOnlyIfNotGeneric, IMoniker** ppmkComposite);
59static HRESULT WINAPI ItemMonikerImpl_Enum(IMoniker* iface,BOOL fForward, IEnumMoniker** ppenumMoniker);
60static HRESULT WINAPI ItemMonikerImpl_IsEqual(IMoniker* iface,IMoniker* pmkOtherMoniker);
61static HRESULT WINAPI ItemMonikerImpl_Hash(IMoniker* iface,DWORD* pdwHash);
62static HRESULT WINAPI ItemMonikerImpl_IsRunning(IMoniker* iface,IBindCtx* pbc, IMoniker* pmkToLeft, IMoniker* pmkNewlyRunning);
63static HRESULT WINAPI ItemMonikerImpl_GetTimeOfLastChange(IMoniker* iface, IBindCtx* pbc, IMoniker* pmkToLeft, FILETIME* pItemTime);
64static HRESULT WINAPI ItemMonikerImpl_Inverse(IMoniker* iface,IMoniker** ppmk);
65static HRESULT WINAPI ItemMonikerImpl_CommonPrefixWith(IMoniker* iface,IMoniker* pmkOther, IMoniker** ppmkPrefix);
66static HRESULT WINAPI ItemMonikerImpl_RelativePathTo(IMoniker* iface,IMoniker* pmOther, IMoniker** ppmkRelPath);
67static HRESULT WINAPI ItemMonikerImpl_GetDisplayName(IMoniker* iface,IBindCtx* pbc, IMoniker* pmkToLeft, LPOLESTR *ppszDisplayName);
68static HRESULT WINAPI ItemMonikerImpl_ParseDisplayName(IMoniker* iface,IBindCtx* pbc, IMoniker* pmkToLeft, LPOLESTR pszDisplayName, ULONG* pchEaten, IMoniker** ppmkOut);
69static HRESULT WINAPI ItemMonikerImpl_IsSystemMoniker(IMoniker* iface,DWORD* pwdMksys);
70
71/* Local function used by ItemMoniker implementation */
72HRESULT WINAPI ItemMonikerImpl_Construct(ItemMonikerImpl* iface, LPCOLESTR lpszDelim,LPCOLESTR lpszPathName);
73HRESULT WINAPI ItemMonikerImpl_Destroy(ItemMonikerImpl* iface);
74
75/********************************************************************************/
76/* IROTData prototype functions */
77
78/* IUnknown prototype functions */
79static HRESULT WINAPI ItemMonikerROTDataImpl_QueryInterface(IROTData* iface,REFIID riid,VOID** ppvObject);
80static ULONG WINAPI ItemMonikerROTDataImpl_AddRef(IROTData* iface);
81static ULONG WINAPI ItemMonikerROTDataImpl_Release(IROTData* iface);
82
83/* IROTData prototype function */
84static HRESULT WINAPI ItemMonikerROTDataImpl_GetComparaisonData(IROTData* iface,BYTE* pbData,ULONG cbMax,ULONG* pcbData);
85
86/********************************************************************************/
87/* Virtual function table for the ItemMonikerImpl class witch include Ipersist,*/
88/* IPersistStream and IMoniker functions. */
89static ICOM_VTABLE(IMoniker) VT_ItemMonikerImpl =
90 {
91 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
92 ItemMonikerImpl_QueryInterface,
93 ItemMonikerImpl_AddRef,
94 ItemMonikerImpl_Release,
95 ItemMonikerImpl_GetClassID,
96 ItemMonikerImpl_IsDirty,
97 ItemMonikerImpl_Load,
98 ItemMonikerImpl_Save,
99 ItemMonikerImpl_GetSizeMax,
100 ItemMonikerImpl_BindToObject,
101 ItemMonikerImpl_BindToStorage,
102 ItemMonikerImpl_Reduce,
103 ItemMonikerImpl_ComposeWith,
104 ItemMonikerImpl_Enum,
105 ItemMonikerImpl_IsEqual,
106 ItemMonikerImpl_Hash,
107 ItemMonikerImpl_IsRunning,
108 ItemMonikerImpl_GetTimeOfLastChange,
109 ItemMonikerImpl_Inverse,
110 ItemMonikerImpl_CommonPrefixWith,
111 ItemMonikerImpl_RelativePathTo,
112 ItemMonikerImpl_GetDisplayName,
113 ItemMonikerImpl_ParseDisplayName,
114 ItemMonikerImpl_IsSystemMoniker
115};
116
117/********************************************************************************/
118/* Virtual function table for the IROTData class. */
119static ICOM_VTABLE(IROTData) VT_ROTDataImpl =
120{
121 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
122 ItemMonikerROTDataImpl_QueryInterface,
123 ItemMonikerROTDataImpl_AddRef,
124 ItemMonikerROTDataImpl_Release,
125 ItemMonikerROTDataImpl_GetComparaisonData
126};
127
128/*******************************************************************************
129 * ItemMoniker_QueryInterface
130 *******************************************************************************/
131HRESULT WINAPI ItemMonikerImpl_QueryInterface(IMoniker* iface,REFIID riid,void** ppvObject)
132{
133 ICOM_THIS(ItemMonikerImpl,iface);
134
135 TRACE("(%p,%p,%p)\n",This,riid,ppvObject);
136
137 /* Perform a sanity check on the parameters.*/
138 if ( (This==0) || (ppvObject==0) )
139 return E_INVALIDARG;
140
141 /* Initialize the return parameter */
142 *ppvObject = 0;
143
144 /* Compare the riid with the interface IDs implemented by this object.*/
145 if (IsEqualIID(&IID_IUnknown, riid) ||
146 IsEqualIID(&IID_IPersist, riid) ||
147 IsEqualIID(&IID_IPersistStream, riid) ||
148 IsEqualIID(&IID_IMoniker, riid)
149 )
150 *ppvObject = iface;
151
152 else if (IsEqualIID(&IID_IROTData, riid))
153 *ppvObject = (IROTData*)&(This->lpvtbl2);
154
155 /* Check that we obtained an interface.*/
156 if ((*ppvObject)==0)
157 return E_NOINTERFACE;
158
159 /* Query Interface always increases the reference count by one when it is successful */
160 ItemMonikerImpl_AddRef(iface);
161
162 return S_OK;
163}
164
165/******************************************************************************
166 * ItemMoniker_AddRef
167 ******************************************************************************/
168ULONG WINAPI ItemMonikerImpl_AddRef(IMoniker* iface)
169{
170 ICOM_THIS(ItemMonikerImpl,iface);
171
172 TRACE("(%p)\n",This);
173
174 return ++(This->ref);
175}
176
177/******************************************************************************
178 * ItemMoniker_Release
179 ******************************************************************************/
180ULONG WINAPI ItemMonikerImpl_Release(IMoniker* iface)
181{
182 ICOM_THIS(ItemMonikerImpl,iface);
183
184 TRACE("(%p)\n",This);
185
186 This->ref--;
187
188 /* destroy the object if there's no more reference on it */
189 if (This->ref==0){
190
191 ItemMonikerImpl_Destroy(This);
192
193 return 0;
194 }
195 return This->ref;;
196}
197
198/******************************************************************************
199 * ItemMoniker_GetClassID
200 ******************************************************************************/
201HRESULT WINAPI ItemMonikerImpl_GetClassID(IMoniker* iface,CLSID *pClassID)
202{
203 TRACE("(%p,%p),stub!\n",iface,pClassID);
204
205 if (pClassID==NULL)
206 return E_POINTER;
207
208 *pClassID = CLSID_ItemMoniker;
209
210 return S_OK;
211}
212
213/******************************************************************************
214 * ItemMoniker_IsDirty
215 ******************************************************************************/
216HRESULT WINAPI ItemMonikerImpl_IsDirty(IMoniker* iface)
217{
218 /* Note that the OLE-provided implementations of the IPersistStream::IsDirty
219 method in the OLE-provided moniker interfaces always return S_FALSE because
220 their internal state never changes. */
221
222 TRACE("(%p)\n",iface);
223
224 return S_FALSE;
225}
226
227/******************************************************************************
228 * ItemMoniker_Load
229 ******************************************************************************/
230HRESULT WINAPI ItemMonikerImpl_Load(IMoniker* iface,IStream* pStm)
231{
232
233 ICOM_THIS(ItemMonikerImpl,iface);
234 HRESULT res;
235 DWORD delimiterLength,nameLength;
236 CHAR *itemNameA,*itemDelimiterA;
237 ULONG bread;
238
239 /* for more details about data read by this function see coments of ItemMonikerImpl_Save function */
240
241 /* read item delimiter string length + 1 */
242 res=IStream_Read(pStm,&delimiterLength,sizeof(DWORD),&bread);
243 if (bread != sizeof(DWORD))
244 return E_FAIL;
245
246 /* read item delimiter string */
247 itemDelimiterA= (CHAR *)HeapAlloc(GetProcessHeap(),0,delimiterLength);
248 res=IStream_Read(pStm,itemDelimiterA,delimiterLength,&bread);
249 if (bread != delimiterLength)
250 return E_FAIL;
251
252 This->itemDelimiter= (WCHAR *)HeapReAlloc(GetProcessHeap(),0,This->itemDelimiter,delimiterLength*sizeof(WCHAR));
253 if (!This->itemDelimiter)
254 return E_OUTOFMEMORY;
255
256 lstrcpyAtoW(This->itemDelimiter,itemDelimiterA);
257
258 /* read item name string length + 1*/
259 res=IStream_Read(pStm,&nameLength,sizeof(DWORD),&bread);
260 if (bread != sizeof(DWORD))
261 return E_FAIL;
262
263 /* read item name string */
264 itemNameA= (CHAR *)HeapAlloc(GetProcessHeap(),0,nameLength);
265 res=IStream_Read(pStm,itemNameA,nameLength,&bread);
266 if (bread != nameLength)
267 return E_FAIL;
268
269 This->itemName= (WCHAR *)HeapReAlloc(GetProcessHeap(),0,This->itemName,nameLength*sizeof(WCHAR));
270 if (!This->itemName)
271 return E_OUTOFMEMORY;
272
273 lstrcpyAtoW(This->itemName,itemNameA);
274
275 return res;
276}
277
278/******************************************************************************
279 * ItemMoniker_Save
280 ******************************************************************************/
281HRESULT WINAPI ItemMonikerImpl_Save(IMoniker* iface,
282 IStream* pStm,/* pointer to the stream where the object is to be saved */
283 BOOL fClearDirty)/* Specifies whether to clear the dirty flag */
284{
285 ICOM_THIS(ItemMonikerImpl,iface);
286 HRESULT res;
287 DWORD delimiterLength=lstrlenW(This->itemDelimiter)+1;
288 DWORD nameLength=lstrlenW(This->itemName)+1;
289 CHAR *itemNameA,*itemDelimiterA;
290
291 /* data writen by this function are : 1) DWORD : size of item delimiter string ('\0' included ) */
292 /* 2) String (type A): item delimiter string ('\0' included) */
293 /* 3) DWORD : size of item name string ('\0' included) */
294 /* 4) String (type A): item name string ('\0' included) */
295
296 itemNameA= (CHAR *)HeapAlloc(GetProcessHeap(),0,nameLength);
297 itemDelimiterA= (CHAR *)HeapAlloc(GetProcessHeap(),0,delimiterLength);
298 lstrcpyWtoA(itemNameA,This->itemName);
299 lstrcpyWtoA(itemDelimiterA,This->itemDelimiter);
300
301 res=IStream_Write(pStm,&delimiterLength,sizeof(DWORD),NULL);
302 res=IStream_Write(pStm,itemDelimiterA,delimiterLength * sizeof(CHAR),NULL);
303 res=IStream_Write(pStm,&nameLength,sizeof(DWORD),NULL);
304 res=IStream_Write(pStm,itemNameA,nameLength * sizeof(CHAR),NULL);
305
306 return res;
307}
308
309/******************************************************************************
310 * ItemMoniker_GetSizeMax
311 ******************************************************************************/
312HRESULT WINAPI ItemMonikerImpl_GetSizeMax(IMoniker* iface,
313 ULARGE_INTEGER* pcbSize)/* Pointer to size of stream needed to save object */
314{
315 ICOM_THIS(ItemMonikerImpl,iface);
316 DWORD delimiterLength=lstrlenW(This->itemDelimiter)+1;
317 DWORD nameLength=lstrlenW(This->itemName)+1;
318
319 TRACE("(%p,%p)\n",iface,pcbSize);
320
321 if (pcbSize!=NULL)
322 return E_POINTER;
323
324 /* for more details see ItemMonikerImpl_Save coments */
325
326 pcbSize->LowPart = sizeof(DWORD) + /* DWORD witch contains delimiter length */
327 delimiterLength + /* item delimiter string */
328 sizeof(DWORD) + /* DWORD witch contains item name length */
329 nameLength + /* item name string */
330 34; /* this constant was added ! because when I tested this function it usually */
331 /* returns 34 bytes more than the number of bytes used by IMoniker::Save function */
332 pcbSize->HighPart=0;
333
334 return S_OK;
335}
336
337/******************************************************************************
338 * ItemMoniker_Construct (local function)
339 *******************************************************************************/
340HRESULT WINAPI ItemMonikerImpl_Construct(ItemMonikerImpl* This, LPCOLESTR lpszDelim,LPCOLESTR lpszItem)
341{
342
343 int sizeStr1=lstrlenW(lpszItem);
344 int sizeStr2=lstrlenW(lpszDelim);
345
346 TRACE("(%p,%p)\n",This,lpszItem);
347
348 /* Initialize the virtual fgunction table. */
349 This->lpvtbl1 = &VT_ItemMonikerImpl;
350 This->lpvtbl2 = &VT_ROTDataImpl;
351 This->ref = 0;
352
353 This->itemName= (WCHAR *)HeapAlloc(GetProcessHeap(),0,sizeof(WCHAR)*(sizeStr1+1));
354 This->itemDelimiter= (WCHAR *)HeapAlloc(GetProcessHeap(),0,sizeof(WCHAR)*(sizeStr2+1));
355
356 if ((This->itemName==NULL)||(This->itemDelimiter==NULL))
357 return E_OUTOFMEMORY;
358
359 lstrcpyW(This->itemName,lpszItem);
360 lstrcpyW(This->itemDelimiter,lpszDelim);
361
362 return S_OK;
363}
364
365/******************************************************************************
366 * ItemMoniker_Destroy (local function)
367 *******************************************************************************/
368HRESULT WINAPI ItemMonikerImpl_Destroy(ItemMonikerImpl* This)
369{
370 TRACE("(%p)\n",This);
371
372 if (This->itemName)
373 HeapFree(GetProcessHeap(),0,This->itemName);
374
375 if (This->itemDelimiter)
376 HeapFree(GetProcessHeap(),0,This->itemDelimiter);
377
378 HeapFree(GetProcessHeap(),0,This);
379
380 return S_OK;
381}
382
383/******************************************************************************
384 * ItemMoniker_BindToObject
385 ******************************************************************************/
386HRESULT WINAPI ItemMonikerImpl_BindToObject(IMoniker* iface,
387 IBindCtx* pbc,
388 IMoniker* pmkToLeft,
389 REFIID riid,
390 VOID** ppvResult)
391{
392 ICOM_THIS(ItemMonikerImpl,iface);
393
394 HRESULT res;
395 IID refid=IID_IOleItemContainer;
396 IOleItemContainer *poic=0;
397
398 TRACE("(%p,%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,riid,ppvResult);
399
400 if(ppvResult ==NULL)
401 return E_POINTER;
402
403 if(pmkToLeft==NULL)
404 return E_INVALIDARG;
405
406 *ppvResult=0;
407
408 res=IMoniker_BindToObject(pmkToLeft,pbc,NULL,&refid,(void**)&poic);
409
410 if (SUCCEEDED(res)){
411
412 res=IOleItemContainer_GetObject(poic,This->itemName,BINDSPEED_MODERATE,pbc,riid,ppvResult);
413
414 IOleItemContainer_Release(poic);
415 }
416
417 return res;
418}
419
420/******************************************************************************
421 * ItemMoniker_BindToStorage
422 ******************************************************************************/
423HRESULT WINAPI ItemMonikerImpl_BindToStorage(IMoniker* iface,
424 IBindCtx* pbc,
425 IMoniker* pmkToLeft,
426 REFIID riid,
427 VOID** ppvResult)
428{
429 ICOM_THIS(ItemMonikerImpl,iface);
430
431 HRESULT res;
432 IOleItemContainer *poic=0;
433
434 TRACE("(%p,%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,riid,ppvResult);
435
436 *ppvResult=0;
437
438 if(pmkToLeft==NULL)
439 return E_INVALIDARG;
440
441 res=IMoniker_BindToObject(pmkToLeft,pbc,NULL,&IID_IOleItemContainer,(void**)&poic);
442
443 if (SUCCEEDED(res)){
444
445 res=IOleItemContainer_GetObjectStorage(poic,This->itemName,pbc,riid,ppvResult);
446
447 IOleItemContainer_Release(poic);
448 }
449
450 return res;
451}
452
453/******************************************************************************
454 * ItemMoniker_Reduce
455 ******************************************************************************/
456HRESULT WINAPI ItemMonikerImpl_Reduce(IMoniker* iface,
457 IBindCtx* pbc,
458 DWORD dwReduceHowFar,
459 IMoniker** ppmkToLeft,
460 IMoniker** ppmkReduced)
461{
462 TRACE("(%p,%p,%ld,%p,%p)\n",iface,pbc,dwReduceHowFar,ppmkToLeft,ppmkReduced);
463
464 if (ppmkReduced==NULL)
465 return E_POINTER;
466
467 ItemMonikerImpl_AddRef(iface);
468
469 *ppmkReduced=iface;
470
471 return MK_S_REDUCED_TO_SELF;
472}
473/******************************************************************************
474 * ItemMoniker_ComposeWith
475 ******************************************************************************/
476HRESULT WINAPI ItemMonikerImpl_ComposeWith(IMoniker* iface,
477 IMoniker* pmkRight,
478 BOOL fOnlyIfNotGeneric,
479 IMoniker** ppmkComposite)
480{
481 HRESULT res=S_OK;
482 DWORD mkSys,mkSys2;
483 IEnumMoniker* penumMk=0;
484 IMoniker *pmostLeftMk=0;
485 IMoniker* tempMkComposite=0;
486
487 TRACE("(%p,%p,%d,%p)\n",iface,pmkRight,fOnlyIfNotGeneric,ppmkComposite);
488
489 if ((ppmkComposite==NULL)||(pmkRight==NULL))
490 return E_POINTER;
491
492 *ppmkComposite=0;
493
494 IMoniker_IsSystemMoniker(pmkRight,&mkSys);
495
496 /* If pmkRight is an anti-moniker, the returned moniker is NULL */
497 if(mkSys==MKSYS_ANTIMONIKER)
498 return res;
499
500 else
501 /* if pmkRight is a composite whose leftmost component is an anti-moniker, */
502 /* the returned moniker is the composite after the leftmost anti-moniker is removed. */
503
504 if(mkSys==MKSYS_GENERICCOMPOSITE){
505
506 res=IMoniker_Enum(pmkRight,TRUE,&penumMk);
507
508 if (FAILED(res))
509 return res;
510
511 res=IEnumMoniker_Next(penumMk,1,&pmostLeftMk,NULL);
512
513 IMoniker_IsSystemMoniker(pmostLeftMk,&mkSys2);
514
515 if(mkSys2==MKSYS_ANTIMONIKER){
516
517 IMoniker_Release(pmostLeftMk);
518
519 tempMkComposite=iface;
520 IMoniker_AddRef(iface);
521
522 while(IEnumMoniker_Next(penumMk,1,&pmostLeftMk,NULL)==S_OK){
523
524 res=CreateGenericComposite(tempMkComposite,pmostLeftMk,ppmkComposite);
525
526 IMoniker_Release(tempMkComposite);
527 IMoniker_Release(pmostLeftMk);
528
529 tempMkComposite=*ppmkComposite;
530 IMoniker_AddRef(tempMkComposite);
531}
532 return res;
533 }
534 else
535 return CreateGenericComposite(iface,pmkRight,ppmkComposite);
536 }
537 /* If pmkRight is not an anti-moniker, the method combines the two monikers into a generic
538 composite if fOnlyIfNotGeneric is FALSE; if fOnlyIfNotGeneric is TRUE, the method returns
539 a NULL moniker and a return value of MK_E_NEEDGENERIC */
540 else
541 if (!fOnlyIfNotGeneric)
542 return CreateGenericComposite(iface,pmkRight,ppmkComposite);
543
544 else
545 return MK_E_NEEDGENERIC;
546}
547
548/******************************************************************************
549 * ItemMoniker_Enum
550 ******************************************************************************/
551HRESULT WINAPI ItemMonikerImpl_Enum(IMoniker* iface,BOOL fForward, IEnumMoniker** ppenumMoniker)
552{
553 TRACE("(%p,%d,%p)\n",iface,fForward,ppenumMoniker);
554
555 if (ppenumMoniker == NULL)
556 return E_POINTER;
557
558 *ppenumMoniker = NULL;
559
560 return S_OK;
561}
562
563/******************************************************************************
564 * ItemMoniker_IsEqual
565 ******************************************************************************/
566HRESULT WINAPI ItemMonikerImpl_IsEqual(IMoniker* iface,IMoniker* pmkOtherMoniker)
567{
568
569 CLSID clsid;
570 LPOLESTR dispName1,dispName2;
571 IBindCtx* bind;
572 HRESULT res;
573
574 TRACE("(%p,%p)\n",iface,pmkOtherMoniker);
575
576 if (pmkOtherMoniker==NULL)
577 return S_FALSE;
578
579 /* This method returns S_OK if both monikers are item monikers and their display names are */
580 /* identical (using a case-insensitive comparison); otherwise, the method returns S_FALSE. */
581
582 IMoniker_GetClassID(pmkOtherMoniker,&clsid);
583
584 if (!IsEqualCLSID(&clsid,&CLSID_ItemMoniker))
585 return S_FALSE;
586
587 res=CreateBindCtx(0,&bind);
588 if (FAILED(res))
589 return res;
590
591 IMoniker_GetDisplayName(iface,bind,NULL,&dispName1);
592 IMoniker_GetDisplayName(pmkOtherMoniker,bind,NULL,&dispName2);
593
594 if (lstrcmpW(dispName1,dispName2)!=0)
595 return S_FALSE;
596
597 return S_OK;
598}
599
600/******************************************************************************
601 * ItemMoniker_Hash
602 ******************************************************************************/
603HRESULT WINAPI ItemMonikerImpl_Hash(IMoniker* iface,DWORD* pdwHash)
604{
605 ICOM_THIS(ItemMonikerImpl,iface);
606
607 int h = 0,i,skip,len;
608 int off = 0;
609 LPOLESTR val;
610
611 if (pdwHash==NULL)
612 return E_POINTER;
613
614 val = This->itemName;
615 len = lstrlenW(val);
616
617 if (len < 16) {
618 for (i = len ; i > 0; i--) {
619 h = (h * 37) + val[off++];
620}
621 } else {
622 /* only sample some characters */
623 skip = len / 8;
624 for (i = len ; i > 0; i -= skip, off += skip) {
625 h = (h * 39) + val[off];
626 }
627 }
628
629 *pdwHash=h;
630
631 return S_OK;
632}
633
634/******************************************************************************
635 * ItemMoniker_IsRunning
636 ******************************************************************************/
637HRESULT WINAPI ItemMonikerImpl_IsRunning(IMoniker* iface,
638 IBindCtx* pbc,
639 IMoniker* pmkToLeft,
640 IMoniker* pmkNewlyRunning)
641{
642 IRunningObjectTable* rot;
643 HRESULT res;
644 IOleItemContainer *poic=0;
645 ICOM_THIS(ItemMonikerImpl,iface);
646
647 TRACE("(%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,pmkNewlyRunning);
648
649 /* If pmkToLeft is NULL, this method returns TRUE if pmkNewlyRunning is non-NULL and is equal to this */
650 /* moniker. Otherwise, the method checks the ROT to see whether this moniker is running. */
651 if (pmkToLeft==NULL)
652 if ((pmkNewlyRunning!=NULL)&&(IMoniker_IsEqual(pmkNewlyRunning,iface)==S_OK))
653 return S_OK;
654 else {
655 if (pbc==NULL)
656 return E_POINTER;
657
658 res=IBindCtx_GetRunningObjectTable(pbc,&rot);
659
660 if (FAILED(res))
661 return res;
662
663 res = IRunningObjectTable_IsRunning(rot,iface);
664
665 IRunningObjectTable_Release(rot);
666 }
667 else{
668
669 /* If pmkToLeft is non-NULL, the method calls IMoniker::BindToObject on the pmkToLeft parameter, */
670 /* requesting an IOleItemContainer interface pointer. The method then calls IOleItemContainer::IsRunning,*/
671 /* passing the string contained within this moniker. */
672
673 res=IMoniker_BindToObject(pmkToLeft,pbc,NULL,&IID_IOleItemContainer,(void**)&poic);
674
675 if (SUCCEEDED(res)){
676
677 res=IOleItemContainer_IsRunning(poic,This->itemName);
678
679 IOleItemContainer_Release(poic);
680 }
681 }
682
683 return res;
684}
685
686/******************************************************************************
687 * ItemMoniker_GetTimeOfLastChange
688 ******************************************************************************/
689HRESULT WINAPI ItemMonikerImpl_GetTimeOfLastChange(IMoniker* iface,
690 IBindCtx* pbc,
691 IMoniker* pmkToLeft,
692 FILETIME* pItemTime)
693{
694 IRunningObjectTable* rot;
695 HRESULT res;
696 IMoniker *compositeMk;
697
698 TRACE("(%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,pItemTime);
699
700 if (pItemTime==NULL)
701 return E_INVALIDARG;
702
703 /* If pmkToLeft is NULL, this method returns MK_E_NOTBINDABLE */
704 if (pmkToLeft==NULL)
705
706 return MK_E_NOTBINDABLE;
707 else {
708
709 /* Otherwise, the method creates a composite of pmkToLeft and this moniker and uses the ROT to access */
710 /* the time of last change. If the object is not in the ROT, the method calls */
711 /* IMoniker::GetTimeOfLastChange on the pmkToLeft parameter. */
712
713 res=CreateGenericComposite(pmkToLeft,iface,&compositeMk);
714
715 res=IBindCtx_GetRunningObjectTable(pbc,&rot);
716
717 if (IRunningObjectTable_GetTimeOfLastChange(rot,compositeMk,pItemTime)!=S_OK)
718
719 res=IMoniker_GetTimeOfLastChange(pmkToLeft,pbc,NULL,pItemTime);
720
721 IMoniker_Release(compositeMk);
722}
723
724 return res;
725}
726
727/******************************************************************************
728 * ItemMoniker_Inverse
729 ******************************************************************************/
730HRESULT WINAPI ItemMonikerImpl_Inverse(IMoniker* iface,IMoniker** ppmk)
731{
732 TRACE("(%p,%p)\n",iface,ppmk);
733
734 if (ppmk==NULL)
735 return E_POINTER;
736
737 return CreateAntiMoniker(ppmk);
738}
739
740/******************************************************************************
741 * ItemMoniker_CommonPrefixWith
742 ******************************************************************************/
743HRESULT WINAPI ItemMonikerImpl_CommonPrefixWith(IMoniker* iface,IMoniker* pmkOther,IMoniker** ppmkPrefix)
744{
745 DWORD mkSys;
746 IMoniker_IsSystemMoniker(pmkOther,&mkSys);
747 /* If the other moniker is an item moniker that is equal to this moniker, this method sets *ppmkPrefix */
748 /* to this moniker and returns MK_S_US */
749
750 if((mkSys==MKSYS_ITEMMONIKER) && (IMoniker_IsEqual(iface,pmkOther)==S_OK) ){
751
752 *ppmkPrefix=iface;
753
754 IMoniker_AddRef(iface);
755
756 return MK_S_US;
757 }
758 else
759 /* otherwise, the method calls the MonikerCommonPrefixWith function. This function correctly handles */
760 /* the case where the other moniker is a generic composite. */
761 return MonikerCommonPrefixWith(iface,pmkOther,ppmkPrefix);
762}
763
764/******************************************************************************
765 * ItemMoniker_RelativePathTo
766 ******************************************************************************/
767HRESULT WINAPI ItemMonikerImpl_RelativePathTo(IMoniker* iface,IMoniker* pmOther, IMoniker** ppmkRelPath)
768{
769 TRACE("(%p,%p,%p)\n",iface,pmOther,ppmkRelPath);
770
771 if (ppmkRelPath==NULL)
772 return E_POINTER;
773
774 *ppmkRelPath=0;
775
776 return MK_E_NOTBINDABLE;
777}
778
779/******************************************************************************
780 * ItemMoniker_GetDisplayName
781 ******************************************************************************/
782HRESULT WINAPI ItemMonikerImpl_GetDisplayName(IMoniker* iface,
783 IBindCtx* pbc,
784 IMoniker* pmkToLeft,
785 LPOLESTR *ppszDisplayName)
786{
787 ICOM_THIS(ItemMonikerImpl,iface);
788
789 TRACE("(%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,ppszDisplayName);
790
791 if (ppszDisplayName==NULL)
792 return E_POINTER;
793
794 if (pmkToLeft!=NULL){
795 return E_INVALIDARG;
796 }
797
798 *ppszDisplayName=(WCHAR *)CoTaskMemAlloc(sizeof(WCHAR)*(lstrlenW(This->itemDelimiter)+lstrlenW(This->itemName)+1));
799
800 if (*ppszDisplayName==NULL)
801 return E_OUTOFMEMORY;
802
803 lstrcpyW(*ppszDisplayName,This->itemDelimiter);
804 lstrcatW(*ppszDisplayName,This->itemName);
805
806 return S_OK;
807}
808
809/******************************************************************************
810 * ItemMoniker_ParseDisplayName
811 ******************************************************************************/
812HRESULT WINAPI ItemMonikerImpl_ParseDisplayName(IMoniker* iface,
813 IBindCtx* pbc,
814 IMoniker* pmkToLeft,
815 LPOLESTR pszDisplayName,
816 ULONG* pchEaten,
817 IMoniker** ppmkOut)
818{
819 IOleItemContainer* poic=0;
820 IParseDisplayName* ppdn=0;
821 LPOLESTR displayName;
822 HRESULT res;
823 ICOM_THIS(ItemMonikerImpl,iface);
824
825 /* If pmkToLeft is NULL, this method returns MK_E_SYNTAX */
826 if (pmkToLeft==NULL)
827
828 return MK_E_SYNTAX;
829
830 else{
831 /* Otherwise, the method calls IMoniker::BindToObject on the pmkToLeft parameter, requesting an */
832 /* IParseDisplayName interface pointer to the object identified by the moniker, and passes the display */ /* name to IParseDisplayName::ParseDisplayName */
833 res=IMoniker_BindToObject(pmkToLeft,pbc,NULL,&IID_IOleItemContainer,(void**)&poic);
834
835 if (SUCCEEDED(res)){
836
837 res=IOleItemContainer_GetObject(poic,This->itemName,BINDSPEED_MODERATE,pbc,&IID_IParseDisplayName,(void**)&ppdn);
838
839 res=IMoniker_GetDisplayName(iface,pbc,NULL,&displayName);
840
841 res=IParseDisplayName_ParseDisplayName(ppdn,pbc,displayName,pchEaten,ppmkOut);
842
843 IOleItemContainer_Release(poic);
844 IParseDisplayName_Release(ppdn);
845 }
846}
847 return res;
848}
849
850/******************************************************************************
851 * ItemMoniker_IsSystemMonker
852 ******************************************************************************/
853HRESULT WINAPI ItemMonikerImpl_IsSystemMoniker(IMoniker* iface,DWORD* pwdMksys)
854{
855 TRACE("(%p,%p)\n",iface,pwdMksys);
856
857 if (!pwdMksys)
858 return E_POINTER;
859
860 (*pwdMksys)=MKSYS_ITEMMONIKER;
861
862 return S_OK;
863}
864
865/*******************************************************************************
866 * ItemMonikerIROTData_QueryInterface
867 *******************************************************************************/
868HRESULT WINAPI ItemMonikerROTDataImpl_QueryInterface(IROTData *iface,REFIID riid,VOID** ppvObject)
869{
870
871 ICOM_THIS_From_IROTData(IMoniker, iface);
872
873 TRACE("(%p,%p,%p)\n",iface,riid,ppvObject);
874
875 return ItemMonikerImpl_QueryInterface(This, riid, ppvObject);
876}
877
878/***********************************************************************
879 * ItemMonikerIROTData_AddRef
880 */
881ULONG WINAPI ItemMonikerROTDataImpl_AddRef(IROTData *iface)
882{
883 ICOM_THIS_From_IROTData(IMoniker, iface);
884
885 TRACE("(%p)\n",iface);
886
887 return ItemMonikerImpl_AddRef(This);
888}
889
890/***********************************************************************
891 * ItemMonikerIROTData_Release
892 */
893ULONG WINAPI ItemMonikerROTDataImpl_Release(IROTData* iface)
894{
895 ICOM_THIS_From_IROTData(IMoniker, iface);
896
897 TRACE("(%p)\n",iface);
898
899 return ItemMonikerImpl_Release(This);
900}
901
902/******************************************************************************
903 * ItemMonikerIROTData_GetComparaisonData
904 ******************************************************************************/
905HRESULT WINAPI ItemMonikerROTDataImpl_GetComparaisonData(IROTData* iface,
906 BYTE* pbData,
907 ULONG cbMax,
908 ULONG* pcbData)
909{
910 FIXME("(),stub!\n");
911 return E_NOTIMPL;
912}
913
914/******************************************************************************
915 * CreateItemMoniker16 [OLE2.28]
916 ******************************************************************************/
917HRESULT WINAPI CreateItemMoniker16(LPCOLESTR16 lpszDelim,LPCOLESTR lpszItem,LPMONIKER* ppmk)
918{
919
920 FIXME("(%s,%p),stub!\n",lpszDelim,ppmk);
921 *ppmk = NULL;
922 return E_NOTIMPL;
923}
924
925/******************************************************************************
926 * CreateItemMoniker [OLE.55]
927 ******************************************************************************/
928HRESULT WINAPI CreateItemMoniker(LPCOLESTR lpszDelim,LPCOLESTR lpszItem, LPMONIKER * ppmk)
929{
930 ItemMonikerImpl* newItemMoniker = 0;
931 HRESULT hr = S_OK;
932 IID riid=IID_IMoniker;
933
934 TRACE("(%p,%p,%p)\n",lpszDelim,lpszItem,ppmk);
935
936 newItemMoniker = (ItemMonikerImpl*)HeapAlloc(GetProcessHeap(), 0, sizeof(ItemMonikerImpl));
937
938 if (newItemMoniker == 0)
939 return STG_E_INSUFFICIENTMEMORY;
940
941 hr = ItemMonikerImpl_Construct(newItemMoniker,lpszDelim,lpszItem);
942
943 if (FAILED(hr)){
944
945 HeapFree(GetProcessHeap(),0,newItemMoniker);
946 return hr;
947 }
948
949 return ItemMonikerImpl_QueryInterface((IMoniker*)newItemMoniker,&riid,(void**)ppmk);
950}
Note: See TracBrowser for help on using the repository browser.