source: trunk/src/ole32/old/itemmoniker.cpp@ 5601

Last change on this file since 5601 was 5601, checked in by sandervl, 24 years ago

created

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