ReactOS  0.4.15-dev-1171-gab82533
itemmoniker.c
Go to the documentation of this file.
1 /*
2  * ItemMonikers implementation
3  *
4  * Copyright 1999 Noomen Hamza
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  */
20 
21 #include <assert.h>
22 #include <stdarg.h>
23 #include <string.h>
24 
25 #define COBJMACROS
26 #define NONAMELESSUNION
27 
28 #include "winerror.h"
29 #include "windef.h"
30 #include "winbase.h"
31 #include "winuser.h"
32 #include "winnls.h"
33 #include "wine/debug.h"
34 #include "ole2.h"
35 #include "moniker.h"
36 
38 
39 /* ItemMoniker data structure */
40 typedef struct ItemMonikerImpl{
41  IMoniker IMoniker_iface; /* VTable relative to the IMoniker interface.*/
42  IROTData IROTData_iface; /* VTable relative to the IROTData interface.*/
44  LPOLESTR itemName; /* item name identified by this ItemMoniker */
45  LPOLESTR itemDelimiter; /* Delimiter string */
46  IUnknown *pMarshal; /* custom marshaler */
48 
50 {
51  return CONTAINING_RECORD(iface, ItemMonikerImpl, IMoniker_iface);
52 }
53 
55 {
56  return CONTAINING_RECORD(iface, ItemMonikerImpl, IROTData_iface);
57 }
58 
60 
61 /*******************************************************************************
62  * ItemMoniker_QueryInterface
63  *******************************************************************************/
65 {
67 
68  TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppvObject);
69 
70  if (!ppvObject)
71  return E_INVALIDARG;
72 
73  /* Compare the riid with the interface IDs implemented by this object.*/
74  if (IsEqualIID(&IID_IUnknown, riid) ||
77  IsEqualIID(&IID_IMoniker, riid))
78  *ppvObject = iface;
79  else if (IsEqualIID(&IID_IROTData, riid))
80  *ppvObject = &This->IROTData_iface;
81  else if (IsEqualIID(&IID_IMarshal, riid))
82  {
83  HRESULT hr = S_OK;
84  if (!This->pMarshal)
85  hr = MonikerMarshal_Create(iface, &This->pMarshal);
86  if (hr != S_OK)
87  return hr;
88  return IUnknown_QueryInterface(This->pMarshal, riid, ppvObject);
89  }
90  else
91  {
92  *ppvObject = NULL;
93  return E_NOINTERFACE;
94  }
95 
96  IMoniker_AddRef(iface);
97  return S_OK;
98 }
99 
100 /******************************************************************************
101  * ItemMoniker_AddRef
102  ******************************************************************************/
104 {
106 
107  TRACE("(%p)\n",This);
108 
109  return InterlockedIncrement(&This->ref);
110 }
111 
112 /******************************************************************************
113  * ItemMoniker_Release
114  ******************************************************************************/
116 {
118  ULONG ref;
119 
120  TRACE("(%p)\n",This);
121 
122  ref = InterlockedDecrement(&This->ref);
123 
124  /* destroy the object if there are no more references to it */
125  if (ref == 0) ItemMonikerImpl_Destroy(This);
126 
127  return ref;
128 }
129 
130 /******************************************************************************
131  * ItemMoniker_GetClassID
132  ******************************************************************************/
134 {
135  TRACE("(%p,%p)\n",iface,pClassID);
136 
137  if (pClassID==NULL)
138  return E_POINTER;
139 
140  *pClassID = CLSID_ItemMoniker;
141 
142  return S_OK;
143 }
144 
145 /******************************************************************************
146  * ItemMoniker_IsDirty
147  ******************************************************************************/
149 {
150  /* Note that the OLE-provided implementations of the IPersistStream::IsDirty
151  method in the OLE-provided moniker interfaces always return S_FALSE because
152  their internal state never changes. */
153 
154  TRACE("(%p)\n",iface);
155 
156  return S_FALSE;
157 }
158 
159 /******************************************************************************
160  * ItemMoniker_Load
161  ******************************************************************************/
163 {
165  HRESULT res;
166  DWORD delimiterLength,nameLength,lenW;
167  CHAR *itemNameA,*itemDelimiterA;
168  ULONG bread;
169 
170  TRACE("\n");
171 
172  /* for more details about data read by this function see comments of ItemMonikerImpl_Save function */
173 
174  /* read item delimiter string length + 1 */
175  res=IStream_Read(pStm,&delimiterLength,sizeof(DWORD),&bread);
176  if (bread != sizeof(DWORD))
177  return E_FAIL;
178 
179  /* read item delimiter string */
180  if (!(itemDelimiterA=HeapAlloc(GetProcessHeap(),0,delimiterLength)))
181  return E_OUTOFMEMORY;
182  res=IStream_Read(pStm,itemDelimiterA,delimiterLength,&bread);
183  if (bread != delimiterLength)
184  {
185  HeapFree( GetProcessHeap(), 0, itemDelimiterA );
186  return E_FAIL;
187  }
188 
189  lenW = MultiByteToWideChar( CP_ACP, 0, itemDelimiterA, -1, NULL, 0 );
190  This->itemDelimiter=HeapReAlloc(GetProcessHeap(),0,This->itemDelimiter,lenW*sizeof(WCHAR));
191  if (!This->itemDelimiter)
192  {
193  HeapFree( GetProcessHeap(), 0, itemDelimiterA );
194  return E_OUTOFMEMORY;
195  }
196  MultiByteToWideChar( CP_ACP, 0, itemDelimiterA, -1, This->itemDelimiter, lenW );
197  HeapFree( GetProcessHeap(), 0, itemDelimiterA );
198 
199  /* read item name string length + 1*/
200  res=IStream_Read(pStm,&nameLength,sizeof(DWORD),&bread);
201  if (bread != sizeof(DWORD))
202  return E_FAIL;
203 
204  /* read item name string */
205  if (!(itemNameA=HeapAlloc(GetProcessHeap(),0,nameLength)))
206  return E_OUTOFMEMORY;
207  res=IStream_Read(pStm,itemNameA,nameLength,&bread);
208  if (bread != nameLength)
209  {
210  HeapFree( GetProcessHeap(), 0, itemNameA );
211  return E_FAIL;
212  }
213 
214  lenW = MultiByteToWideChar( CP_ACP, 0, itemNameA, -1, NULL, 0 );
215  This->itemName=HeapReAlloc(GetProcessHeap(),0,This->itemName,lenW*sizeof(WCHAR));
216  if (!This->itemName)
217  {
218  HeapFree( GetProcessHeap(), 0, itemNameA );
219  return E_OUTOFMEMORY;
220  }
221  MultiByteToWideChar( CP_ACP, 0, itemNameA, -1, This->itemName, lenW );
222  HeapFree( GetProcessHeap(), 0, itemNameA );
223 
224  return res;
225 }
226 
227 /******************************************************************************
228  * ItemMoniker_Save
229  ******************************************************************************/
230 static HRESULT WINAPI ItemMonikerImpl_Save(IMoniker* iface, IStream* pStm, BOOL fClearDirty)
231 {
233  HRESULT res;
234  CHAR *itemNameA,*itemDelimiterA;
235 
236  /* data written by this function are : 1) DWORD : size of item delimiter string ('\0' included ) */
237  /* 2) String (type A): item delimiter string ('\0' included) */
238  /* 3) DWORD : size of item name string ('\0' included) */
239  /* 4) String (type A): item name string ('\0' included) */
240 
241  DWORD nameLength = WideCharToMultiByte( CP_ACP, 0, This->itemName, -1, NULL, 0, NULL, NULL);
242  DWORD delimiterLength = WideCharToMultiByte( CP_ACP, 0, This->itemDelimiter, -1, NULL, 0, NULL, NULL);
243  itemNameA=HeapAlloc(GetProcessHeap(),0,nameLength);
244  itemDelimiterA=HeapAlloc(GetProcessHeap(),0,delimiterLength);
245  WideCharToMultiByte( CP_ACP, 0, This->itemName, -1, itemNameA, nameLength, NULL, NULL);
246  WideCharToMultiByte( CP_ACP, 0, This->itemDelimiter, -1, itemDelimiterA, delimiterLength, NULL, NULL);
247 
248  TRACE("%p, %s\n", pStm, fClearDirty ? "TRUE" : "FALSE");
249 
250  res=IStream_Write(pStm,&delimiterLength,sizeof(DWORD),NULL);
251  res=IStream_Write(pStm,itemDelimiterA,delimiterLength * sizeof(CHAR),NULL);
252  res=IStream_Write(pStm,&nameLength,sizeof(DWORD),NULL);
253  res=IStream_Write(pStm,itemNameA,nameLength * sizeof(CHAR),NULL);
254 
255  HeapFree(GetProcessHeap(), 0, itemNameA);
256  HeapFree(GetProcessHeap(), 0, itemDelimiterA);
257 
258  return res;
259 }
260 
261 /******************************************************************************
262  * ItemMoniker_GetSizeMax
263  ******************************************************************************/
265 {
267  DWORD delimiterLength=lstrlenW(This->itemDelimiter)+1;
268  DWORD nameLength=lstrlenW(This->itemName)+1;
269 
270  TRACE("(%p,%p)\n",iface,pcbSize);
271 
272  if (!pcbSize)
273  return E_POINTER;
274 
275  /* for more details see ItemMonikerImpl_Save comments */
276 
277  pcbSize->u.LowPart = sizeof(DWORD) + /* DWORD which contains delimiter length */
278  delimiterLength*4 + /* item delimiter string */
279  sizeof(DWORD) + /* DWORD which contains item name length */
280  nameLength*4 + /* item name string */
281  18; /* strange, but true */
282  pcbSize->u.HighPart=0;
283 
284  return S_OK;
285 }
286 
287 /******************************************************************************
288  * ItemMoniker_BindToObject
289  ******************************************************************************/
291  IBindCtx* pbc,
292  IMoniker* pmkToLeft,
293  REFIID riid,
294  VOID** ppvResult)
295 {
297  HRESULT res;
299  IOleItemContainer *poic=0;
300 
301  TRACE("(%p,%p,%p,%s,%p)\n",iface,pbc,pmkToLeft,debugstr_guid(riid),ppvResult);
302 
303  if(ppvResult ==NULL)
304  return E_POINTER;
305 
306  if(pmkToLeft==NULL)
307  return E_INVALIDARG;
308 
309  *ppvResult=0;
310 
311  res=IMoniker_BindToObject(pmkToLeft,pbc,NULL,&refid,(void**)&poic);
312 
313  if (SUCCEEDED(res)){
314 
315  res=IOleItemContainer_GetObject(poic,This->itemName,BINDSPEED_MODERATE,pbc,riid,ppvResult);
316 
317  IOleItemContainer_Release(poic);
318  }
319 
320  return res;
321 }
322 
323 /******************************************************************************
324  * ItemMoniker_BindToStorage
325  ******************************************************************************/
327  IBindCtx* pbc,
328  IMoniker* pmkToLeft,
329  REFIID riid,
330  VOID** ppvResult)
331 {
333  HRESULT res;
334  IOleItemContainer *poic=0;
335 
336  TRACE("(%p,%p,%p,%s,%p)\n",iface,pbc,pmkToLeft,debugstr_guid(riid),ppvResult);
337 
338  *ppvResult=0;
339 
340  if(pmkToLeft==NULL)
341  return E_INVALIDARG;
342 
343  res=IMoniker_BindToObject(pmkToLeft,pbc,NULL,&IID_IOleItemContainer,(void**)&poic);
344 
345  if (SUCCEEDED(res)){
346 
347  res=IOleItemContainer_GetObjectStorage(poic,This->itemName,pbc,riid,ppvResult);
348 
349  IOleItemContainer_Release(poic);
350  }
351 
352  return res;
353 }
354 
355 /******************************************************************************
356  * ItemMoniker_Reduce
357  ******************************************************************************/
359  IBindCtx* pbc,
360  DWORD dwReduceHowFar,
361  IMoniker** ppmkToLeft,
362  IMoniker** ppmkReduced)
363 {
364  TRACE("(%p,%p,%d,%p,%p)\n",iface,pbc,dwReduceHowFar,ppmkToLeft,ppmkReduced);
365 
366  if (ppmkReduced==NULL)
367  return E_POINTER;
368 
369  ItemMonikerImpl_AddRef(iface);
370 
371  *ppmkReduced=iface;
372 
373  return MK_S_REDUCED_TO_SELF;
374 }
375 /******************************************************************************
376  * ItemMoniker_ComposeWith
377  ******************************************************************************/
379  IMoniker* pmkRight,
380  BOOL fOnlyIfNotGeneric,
381  IMoniker** ppmkComposite)
382 {
383  HRESULT res=S_OK;
384  DWORD mkSys,mkSys2;
385  IEnumMoniker* penumMk=0;
386  IMoniker *pmostLeftMk=0;
387  IMoniker* tempMkComposite=0;
388 
389  TRACE("(%p,%p,%d,%p)\n",iface,pmkRight,fOnlyIfNotGeneric,ppmkComposite);
390 
391  if ((ppmkComposite==NULL)||(pmkRight==NULL))
392  return E_POINTER;
393 
394  *ppmkComposite=0;
395 
396  IMoniker_IsSystemMoniker(pmkRight,&mkSys);
397 
398  /* If pmkRight is an anti-moniker, the returned moniker is NULL */
399  if(mkSys==MKSYS_ANTIMONIKER)
400  return res;
401 
402  else
403  /* if pmkRight is a composite whose leftmost component is an anti-moniker, */
404  /* the returned moniker is the composite after the leftmost anti-moniker is removed. */
405 
406  if(mkSys==MKSYS_GENERICCOMPOSITE){
407 
408  res=IMoniker_Enum(pmkRight,TRUE,&penumMk);
409 
410  if (FAILED(res))
411  return res;
412 
413  res=IEnumMoniker_Next(penumMk,1,&pmostLeftMk,NULL);
414 
415  IMoniker_IsSystemMoniker(pmostLeftMk,&mkSys2);
416 
417  if(mkSys2==MKSYS_ANTIMONIKER){
418 
419  IMoniker_Release(pmostLeftMk);
420 
421  tempMkComposite=iface;
422  IMoniker_AddRef(iface);
423 
424  while(IEnumMoniker_Next(penumMk,1,&pmostLeftMk,NULL)==S_OK){
425 
426  res=CreateGenericComposite(tempMkComposite,pmostLeftMk,ppmkComposite);
427 
428  IMoniker_Release(tempMkComposite);
429  IMoniker_Release(pmostLeftMk);
430 
431  tempMkComposite=*ppmkComposite;
432  IMoniker_AddRef(tempMkComposite);
433  }
434  return res;
435  }
436  else
437  return CreateGenericComposite(iface,pmkRight,ppmkComposite);
438  }
439  /* If pmkRight is not an anti-moniker, the method combines the two monikers into a generic
440  composite if fOnlyIfNotGeneric is FALSE; if fOnlyIfNotGeneric is TRUE, the method returns
441  a NULL moniker and a return value of MK_E_NEEDGENERIC */
442  else
443  if (!fOnlyIfNotGeneric)
444  return CreateGenericComposite(iface,pmkRight,ppmkComposite);
445 
446  else
447  return MK_E_NEEDGENERIC;
448 }
449 
450 /******************************************************************************
451  * ItemMoniker_Enum
452  ******************************************************************************/
453 static HRESULT WINAPI ItemMonikerImpl_Enum(IMoniker* iface,BOOL fForward, IEnumMoniker** ppenumMoniker)
454 {
455  TRACE("(%p,%d,%p)\n",iface,fForward,ppenumMoniker);
456 
457  if (ppenumMoniker == NULL)
458  return E_POINTER;
459 
460  *ppenumMoniker = NULL;
461 
462  return S_OK;
463 }
464 
465 /******************************************************************************
466  * ItemMoniker_IsEqual
467  ******************************************************************************/
468 static HRESULT WINAPI ItemMonikerImpl_IsEqual(IMoniker* iface,IMoniker* pmkOtherMoniker)
469 {
470 
471  CLSID clsid;
472  LPOLESTR dispName1,dispName2;
473  IBindCtx* bind;
474  HRESULT res = S_FALSE;
475 
476  TRACE("(%p,%p)\n",iface,pmkOtherMoniker);
477 
478  if (!pmkOtherMoniker) return S_FALSE;
479 
480 
481  /* check if both are ItemMoniker */
482  if(FAILED (IMoniker_GetClassID(pmkOtherMoniker,&clsid))) return S_FALSE;
483  if(!IsEqualCLSID(&clsid,&CLSID_ItemMoniker)) return S_FALSE;
484 
485  /* check if both displaynames are the same */
486  if(SUCCEEDED ((res = CreateBindCtx(0,&bind)))) {
487  if(SUCCEEDED (IMoniker_GetDisplayName(iface,bind,NULL,&dispName1))) {
488  if(SUCCEEDED (IMoniker_GetDisplayName(pmkOtherMoniker,bind,NULL,&dispName2))) {
489  if(wcscmp(dispName1,dispName2)==0) res = S_OK;
490  CoTaskMemFree(dispName2);
491  }
492  CoTaskMemFree(dispName1);
493  }
494  }
495  return res;
496 }
497 
498 /******************************************************************************
499  * ItemMoniker_Hash
500  ******************************************************************************/
502 {
504  DWORD h = 0;
505  int i,len;
506  int off = 0;
507  LPOLESTR val;
508 
509  if (pdwHash==NULL)
510  return E_POINTER;
511 
512  val = This->itemName;
513  len = lstrlenW(val);
514 
515  for (i = len ; i > 0; i--)
516  h = (h * 3) ^ towupper(val[off++]);
517 
518  *pdwHash=h;
519 
520  return S_OK;
521 }
522 
523 /******************************************************************************
524  * ItemMoniker_IsRunning
525  ******************************************************************************/
527  IBindCtx* pbc,
528  IMoniker* pmkToLeft,
529  IMoniker* pmkNewlyRunning)
530 {
533  HRESULT res;
534  IOleItemContainer *poic=0;
535 
536  TRACE("(%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,pmkNewlyRunning);
537 
538  /* If pmkToLeft is NULL, this method returns TRUE if pmkNewlyRunning is non-NULL and is equal to this */
539  /* moniker. Otherwise, the method checks the ROT to see whether this moniker is running. */
540  if (pmkToLeft==NULL)
541  if ((pmkNewlyRunning!=NULL)&&(IMoniker_IsEqual(pmkNewlyRunning,iface)==S_OK))
542  return S_OK;
543  else {
544  if (pbc==NULL)
545  return E_INVALIDARG;
546 
547  res=IBindCtx_GetRunningObjectTable(pbc,&rot);
548 
549  if (FAILED(res))
550  return res;
551 
552  res = IRunningObjectTable_IsRunning(rot,iface);
553 
554  IRunningObjectTable_Release(rot);
555  }
556  else{
557 
558  /* If pmkToLeft is non-NULL, the method calls IMoniker::BindToObject on the pmkToLeft parameter, */
559  /* requesting an IOleItemContainer interface pointer. The method then calls IOleItemContainer::IsRunning,*/
560  /* passing the string contained within this moniker. */
561 
562  res=IMoniker_BindToObject(pmkToLeft,pbc,NULL,&IID_IOleItemContainer,(void**)&poic);
563 
564  if (SUCCEEDED(res)){
565 
566  res=IOleItemContainer_IsRunning(poic,This->itemName);
567 
568  IOleItemContainer_Release(poic);
569  }
570  }
571 
572  return res;
573 }
574 
575 /******************************************************************************
576  * ItemMoniker_GetTimeOfLastChange
577  ******************************************************************************/
579  IBindCtx* pbc,
580  IMoniker* pmkToLeft,
581  FILETIME* pItemTime)
582 {
584  HRESULT res;
585  IMoniker *compositeMk;
586 
587  TRACE("(%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,pItemTime);
588 
589  if (pItemTime==NULL)
590  return E_INVALIDARG;
591 
592  /* If pmkToLeft is NULL, this method returns MK_E_NOTBINDABLE */
593  if (pmkToLeft==NULL)
594 
595  return MK_E_NOTBINDABLE;
596  else {
597 
598  /* Otherwise, the method creates a composite of pmkToLeft and this moniker and uses the ROT to access */
599  /* the time of last change. If the object is not in the ROT, the method calls */
600  /* IMoniker::GetTimeOfLastChange on the pmkToLeft parameter. */
601 
602  res=CreateGenericComposite(pmkToLeft,iface,&compositeMk);
603  if (FAILED(res))
604  return res;
605 
606  res=IBindCtx_GetRunningObjectTable(pbc,&rot);
607  if (FAILED(res)) {
608  IMoniker_Release(compositeMk);
609  return res;
610  }
611 
612  if (IRunningObjectTable_GetTimeOfLastChange(rot,compositeMk,pItemTime)!=S_OK)
613 
614  res=IMoniker_GetTimeOfLastChange(pmkToLeft,pbc,NULL,pItemTime);
615 
616  IMoniker_Release(compositeMk);
617  }
618 
619  return res;
620 }
621 
622 /******************************************************************************
623  * ItemMoniker_Inverse
624  ******************************************************************************/
626 {
627  TRACE("(%p,%p)\n",iface,ppmk);
628 
629  if (ppmk==NULL)
630  return E_POINTER;
631 
632  return CreateAntiMoniker(ppmk);
633 }
634 
635 /******************************************************************************
636  * ItemMoniker_CommonPrefixWith
637  ******************************************************************************/
639 {
640  DWORD mkSys;
641 
642  TRACE("(%p,%p)\n", pmkOther, ppmkPrefix);
643 
644  IMoniker_IsSystemMoniker(pmkOther,&mkSys);
645  /* If the other moniker is an item moniker that is equal to this moniker, this method sets *ppmkPrefix */
646  /* to this moniker and returns MK_S_US */
647 
648  if((mkSys==MKSYS_ITEMMONIKER) && (IMoniker_IsEqual(iface,pmkOther)==S_OK) ){
649 
650  *ppmkPrefix=iface;
651 
652  IMoniker_AddRef(iface);
653 
654  return MK_S_US;
655  }
656  else
657  /* otherwise, the method calls the MonikerCommonPrefixWith function. This function correctly handles */
658  /* the case where the other moniker is a generic composite. */
659  return MonikerCommonPrefixWith(iface,pmkOther,ppmkPrefix);
660 }
661 
662 /******************************************************************************
663  * ItemMoniker_RelativePathTo
664  ******************************************************************************/
666 {
667  TRACE("(%p,%p,%p)\n",iface,pmOther,ppmkRelPath);
668 
669  if (ppmkRelPath==NULL)
670  return E_POINTER;
671 
672  *ppmkRelPath=0;
673 
674  return MK_E_NOTBINDABLE;
675 }
676 
677 /******************************************************************************
678  * ItemMoniker_GetDisplayName
679  ******************************************************************************/
681  IBindCtx* pbc,
682  IMoniker* pmkToLeft,
683  LPOLESTR *ppszDisplayName)
684 {
686 
687  TRACE("(%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,ppszDisplayName);
688 
689  if (ppszDisplayName==NULL)
690  return E_POINTER;
691 
692  if (pmkToLeft!=NULL){
693  return E_INVALIDARG;
694  }
695 
696  *ppszDisplayName=CoTaskMemAlloc(sizeof(WCHAR)*(lstrlenW(This->itemDelimiter)+lstrlenW(This->itemName)+1));
697 
698  if (*ppszDisplayName==NULL)
699  return E_OUTOFMEMORY;
700 
701  lstrcpyW(*ppszDisplayName,This->itemDelimiter);
702  lstrcatW(*ppszDisplayName,This->itemName);
703 
704  TRACE("-- %s\n", debugstr_w(*ppszDisplayName));
705 
706  return S_OK;
707 }
708 
709 /******************************************************************************
710  * ItemMoniker_ParseDisplayName
711  ******************************************************************************/
713  IBindCtx* pbc,
714  IMoniker* pmkToLeft,
715  LPOLESTR pszDisplayName,
716  ULONG* pchEaten,
717  IMoniker** ppmkOut)
718 {
720  IOleItemContainer* poic=0;
721  IParseDisplayName* ppdn=0;
723  HRESULT res;
724 
725  TRACE("%s\n", debugstr_w(pszDisplayName));
726 
727  /* If pmkToLeft is NULL, this method returns MK_E_SYNTAX */
728  if (pmkToLeft==NULL)
729 
730  return MK_E_SYNTAX;
731 
732  else{
733  /* Otherwise, the method calls IMoniker::BindToObject on the pmkToLeft parameter, requesting an */
734  /* IParseDisplayName interface pointer to the object identified by the moniker, and passes the display */
735  /* name to IParseDisplayName::ParseDisplayName */
736  res=IMoniker_BindToObject(pmkToLeft,pbc,NULL,&IID_IOleItemContainer,(void**)&poic);
737 
738  if (SUCCEEDED(res)){
739 
740  res=IOleItemContainer_GetObject(poic,This->itemName,BINDSPEED_MODERATE,pbc,&IID_IParseDisplayName,(void**)&ppdn);
741 
742  res=IMoniker_GetDisplayName(iface,pbc,NULL,&displayName);
743 
744  res=IParseDisplayName_ParseDisplayName(ppdn,pbc,displayName,pchEaten,ppmkOut);
745 
746  IOleItemContainer_Release(poic);
747  IParseDisplayName_Release(ppdn);
748  }
749  }
750  return res;
751 }
752 
753 /******************************************************************************
754  * ItemMoniker_IsSystemMoniker
755  ******************************************************************************/
757 {
758  TRACE("(%p,%p)\n",iface,pwdMksys);
759 
760  if (!pwdMksys)
761  return E_POINTER;
762 
763  (*pwdMksys)=MKSYS_ITEMMONIKER;
764 
765  return S_OK;
766 }
767 
768 /*******************************************************************************
769  * ItemMonikerIROTData_QueryInterface
770  *******************************************************************************/
772  void **ppvObject)
773 {
774 
776 
777  TRACE("(%p,%s,%p)\n",iface,debugstr_guid(riid),ppvObject);
778 
779  return ItemMonikerImpl_QueryInterface(&This->IMoniker_iface, riid, ppvObject);
780 }
781 
782 /***********************************************************************
783  * ItemMonikerIROTData_AddRef
784  */
786 {
788 
789  TRACE("(%p)\n",iface);
790 
791  return ItemMonikerImpl_AddRef(&This->IMoniker_iface);
792 }
793 
794 /***********************************************************************
795  * ItemMonikerIROTData_Release
796  */
798 {
800 
801  TRACE("(%p)\n",iface);
802 
803  return ItemMonikerImpl_Release(&This->IMoniker_iface);
804 }
805 
806 /******************************************************************************
807  * ItemMonikerIROTData_GetComparisonData
808  ******************************************************************************/
810  BYTE* pbData,
811  ULONG cbMax,
812  ULONG* pcbData)
813 {
815  int len = (lstrlenW(This->itemName)+1);
816  int i;
817  LPWSTR pszItemName;
818  LPWSTR pszItemDelimiter;
819 
820  TRACE("(%p, %u, %p)\n", pbData, cbMax, pcbData);
821 
822  *pcbData = sizeof(CLSID) + sizeof(WCHAR) + len * sizeof(WCHAR);
823  if (cbMax < *pcbData)
824  return E_OUTOFMEMORY;
825 
826  /* write CLSID */
827  memcpy(pbData, &CLSID_ItemMoniker, sizeof(CLSID));
828  /* write delimiter */
829  pszItemDelimiter = (LPWSTR)(pbData+sizeof(CLSID));
830  *pszItemDelimiter = *This->itemDelimiter;
831  /* write name */
832  pszItemName = pszItemDelimiter + 1;
833  for (i = 0; i < len; i++)
834  pszItemName[i] = towupper(This->itemName[i]);
835 
836  return S_OK;
837 }
838 
839 /********************************************************************************/
840 /* Virtual function table for the ItemMonikerImpl class which include IPersist,*/
841 /* IPersistStream and IMoniker functions. */
842 static const IMonikerVtbl VT_ItemMonikerImpl =
843  {
867 };
868 
869 /********************************************************************************/
870 /* Virtual function table for the IROTData class. */
871 static const IROTDataVtbl VT_ROTDataImpl =
872 {
877 };
878 
879 /******************************************************************************
880  * ItemMoniker_Construct (local function)
881  *******************************************************************************/
882 static HRESULT ItemMonikerImpl_Construct(ItemMonikerImpl* This, LPCOLESTR lpszDelim,LPCOLESTR lpszItem)
883 {
884 
885  int sizeStr1=lstrlenW(lpszItem), sizeStr2;
886  static const OLECHAR emptystr[1];
887  LPCOLESTR delim;
888 
889  TRACE("(%p,%s,%s)\n",This,debugstr_w(lpszDelim),debugstr_w(lpszItem));
890 
891  /* Initialize the virtual function table. */
892  This->IMoniker_iface.lpVtbl = &VT_ItemMonikerImpl;
893  This->IROTData_iface.lpVtbl = &VT_ROTDataImpl;
894  This->ref = 0;
895  This->pMarshal = NULL;
896 
897  This->itemName=HeapAlloc(GetProcessHeap(),0,sizeof(WCHAR)*(sizeStr1+1));
898  if (!This->itemName)
899  return E_OUTOFMEMORY;
900  lstrcpyW(This->itemName,lpszItem);
901 
902  if (!lpszDelim)
903  FIXME("lpszDelim is NULL. Using empty string which is possibly wrong.\n");
904 
905  delim = lpszDelim ? lpszDelim : emptystr;
906 
907  sizeStr2=lstrlenW(delim);
908  This->itemDelimiter=HeapAlloc(GetProcessHeap(),0,sizeof(WCHAR)*(sizeStr2+1));
909  if (!This->itemDelimiter) {
910  HeapFree(GetProcessHeap(),0,This->itemName);
911  return E_OUTOFMEMORY;
912  }
913  lstrcpyW(This->itemDelimiter,delim);
914  return S_OK;
915 }
916 
917 /******************************************************************************
918  * ItemMoniker_Destroy (local function)
919  *******************************************************************************/
921 {
922  TRACE("(%p)\n",This);
923 
924  if (This->pMarshal) IUnknown_Release(This->pMarshal);
925  HeapFree(GetProcessHeap(),0,This->itemName);
926  HeapFree(GetProcessHeap(),0,This->itemDelimiter);
928 
929  return S_OK;
930 }
931 
932 /******************************************************************************
933  * CreateItemMoniker [OLE32.@]
934  ******************************************************************************/
935 HRESULT WINAPI CreateItemMoniker(LPCOLESTR lpszDelim, LPCOLESTR lpszItem, IMoniker **ppmk)
936 {
937  ItemMonikerImpl* newItemMoniker;
938  HRESULT hr;
939 
940  TRACE("(%s,%s,%p)\n",debugstr_w(lpszDelim),debugstr_w(lpszItem),ppmk);
941 
942  newItemMoniker = HeapAlloc(GetProcessHeap(), 0, sizeof(ItemMonikerImpl));
943 
944  if (!newItemMoniker)
946 
947  hr = ItemMonikerImpl_Construct(newItemMoniker,lpszDelim,lpszItem);
948 
949  if (FAILED(hr)){
950  HeapFree(GetProcessHeap(),0,newItemMoniker);
951  return hr;
952  }
953 
954  return ItemMonikerImpl_QueryInterface(&newItemMoniker->IMoniker_iface,&IID_IMoniker,
955  (void**)ppmk);
956 }
957 
959  IUnknown *pUnk, REFIID riid, void **ppv)
960 {
961  ItemMonikerImpl* newItemMoniker;
962  HRESULT hr;
963  static const WCHAR wszEmpty[] = { 0 };
964 
965  TRACE("(%p, %s, %p)\n", pUnk, debugstr_guid(riid), ppv);
966 
967  *ppv = NULL;
968 
969  if (pUnk)
970  return CLASS_E_NOAGGREGATION;
971 
972  newItemMoniker = HeapAlloc(GetProcessHeap(), 0, sizeof(ItemMonikerImpl));
973  if (!newItemMoniker)
974  return E_OUTOFMEMORY;
975 
976  hr = ItemMonikerImpl_Construct(newItemMoniker, wszEmpty, wszEmpty);
977 
978  if (SUCCEEDED(hr))
980  if (FAILED(hr))
981  HeapFree(GetProcessHeap(),0,newItemMoniker);
982 
983  return hr;
984 }
static ItemMonikerImpl * impl_from_IMoniker(IMoniker *iface)
Definition: itemmoniker.c:49
WCHAR OLECHAR
Definition: compat.h:2040
static HRESULT WINAPI ItemMonikerImpl_Reduce(IMoniker *iface, IBindCtx *pbc, DWORD dwReduceHowFar, IMoniker **ppmkToLeft, IMoniker **ppmkReduced)
Definition: itemmoniker.c:358
#define REFIID
Definition: guiddef.h:118
#define MK_S_REDUCED_TO_SELF
Definition: winerror.h:2773
#define E_NOINTERFACE
Definition: winerror.h:2364
HRESULT WINAPI MonikerCommonPrefixWith(IMoniker *pmkThis, IMoniker *pmkOther, IMoniker **ppmkCommon)
VOID WINAPI CoTaskMemFree(LPVOID ptr)
Definition: ifs.c:442
#define WideCharToMultiByte
Definition: compat.h:111
HRESULT hr
Definition: shlfolder.c:183
static ULONG WINAPI ItemMonikerImpl_Release(IMoniker *iface)
Definition: itemmoniker.c:115
#define TRUE
Definition: types.h:120
INT WSAAPI bind(IN SOCKET s, IN CONST struct sockaddr *name, IN INT namelen)
Definition: socklife.c:36
REFIID riid
Definition: precomp.h:44
const GUID IID_IOleItemContainer
#define CP_ACP
Definition: compat.h:109
static HRESULT ItemMonikerImpl_Construct(ItemMonikerImpl *This, LPCOLESTR lpszDelim, LPCOLESTR lpszItem)
Definition: itemmoniker.c:882
const GUID IID_IPersist
Definition: proxy.cpp:14
char CHAR
Definition: xmlstorage.h:175
LPOLESTR itemName
Definition: itemmoniker.c:44
static HRESULT WINAPI ItemMonikerImpl_ComposeWith(IMoniker *iface, IMoniker *pmkRight, BOOL fOnlyIfNotGeneric, IMoniker **ppmkComposite)
Definition: itemmoniker.c:378
static HRESULT WINAPI ItemMonikerImpl_GetTimeOfLastChange(IMoniker *iface, IBindCtx *pbc, IMoniker *pmkToLeft, FILETIME *pItemTime)
Definition: itemmoniker.c:578
IROTData IROTData_iface
Definition: itemmoniker.c:42
REFIID LPVOID * ppv
Definition: atlbase.h:39
#define MK_E_NOTBINDABLE
Definition: winerror.h:2789
static ULONG WINAPI ItemMonikerImpl_AddRef(IMoniker *iface)
Definition: itemmoniker.c:103
WINE_DEFAULT_DEBUG_CHANNEL(ole)
#define STG_E_INSUFFICIENTMEMORY
Definition: winerror.h:2570
static HRESULT WINAPI ItemMonikerImpl_ParseDisplayName(IMoniker *iface, IBindCtx *pbc, IMoniker *pmkToLeft, LPOLESTR pszDisplayName, ULONG *pchEaten, IMoniker **ppmkOut)
Definition: itemmoniker.c:712
char displayName[]
Definition: tftpd.cpp:35
static const IMonikerVtbl VT_ItemMonikerImpl
Definition: itemmoniker.c:842
static LPOLESTR
Definition: stg_prop.c:27
#define lstrlenW
Definition: compat.h:498
#define E_FAIL
Definition: ddrawi.h:102
static ULONG WINAPI ItemMonikerROTDataImpl_AddRef(IROTData *iface)
Definition: itemmoniker.c:785
static HRESULT ItemMonikerImpl_Destroy(ItemMonikerImpl *iface)
Definition: itemmoniker.c:920
#define DWORD
Definition: nt_native.h:44
Definition: send.c:48
struct _ULARGE_INTEGER::@3873 u
GLfloat GLfloat GLfloat GLfloat h
Definition: glext.h:7723
static ULONG WINAPI ItemMonikerROTDataImpl_Release(IROTData *iface)
Definition: itemmoniker.c:797
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
unsigned int BOOL
Definition: ntddk_ex.h:94
long LONG
Definition: pedump.c:60
static HRESULT WINAPI ItemMonikerImpl_IsDirty(IMoniker *iface)
Definition: itemmoniker.c:148
#define debugstr_w
Definition: kernel32.h:32
GLenum GLint ref
Definition: glext.h:6028
#define FIXME(fmt,...)
Definition: debug.h:111
GLfloat rot
Definition: 3dtext.c:36
HRESULT WINAPI CreateItemMoniker(LPCOLESTR lpszDelim, LPCOLESTR lpszItem, IMoniker **ppmk)
Definition: itemmoniker.c:935
#define S_FALSE
Definition: winerror.h:2357
#define E_INVALIDARG
Definition: ddrawi.h:101
smooth NULL
Definition: ftsmooth.c:416
static HRESULT WINAPI ItemMonikerImpl_GetSizeMax(IMoniker *iface, ULARGE_INTEGER *pcbSize)
Definition: itemmoniker.c:264
static HRESULT WINAPI ItemMonikerImpl_QueryInterface(IMoniker *iface, REFIID riid, void **ppvObject)
Definition: itemmoniker.c:64
const GUID IID_IParseDisplayName
#define MK_E_NEEDGENERIC
Definition: winerror.h:2783
static const WCHAR wszEmpty[]
Definition: misc.c:327
#define debugstr_guid
Definition: kernel32.h:35
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
GLuint GLfloat * val
Definition: glext.h:7180
static HRESULT WINAPI ItemMonikerImpl_BindToStorage(IMoniker *iface, IBindCtx *pbc, IMoniker *pmkToLeft, REFIID riid, VOID **ppvResult)
Definition: itemmoniker.c:326
#define TRACE(s)
Definition: solgame.cpp:4
IMoniker IMoniker_iface
Definition: itemmoniker.c:41
static HRESULT WINAPI ItemMonikerImpl_GetDisplayName(IMoniker *iface, IBindCtx *pbc, IMoniker *pmkToLeft, LPOLESTR *ppszDisplayName)
Definition: itemmoniker.c:680
#define GetProcessHeap()
Definition: compat.h:484
static ItemMonikerImpl * impl_from_IROTData(IROTData *iface)
Definition: itemmoniker.c:54
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
HRESULT WINAPI CreateBindCtx(DWORD reserved, LPBC *ppbc)
Definition: bindctx.c:556
__wchar_t WCHAR
Definition: xmlstorage.h:180
LONG HRESULT
Definition: typedefs.h:79
const GUID IID_IUnknown
#define WINAPI
Definition: msvc.h:6
LPOLESTR itemDelimiter
Definition: itemmoniker.c:45
unsigned long DWORD
Definition: ntddk_ex.h:95
const GUID IID_IPersistStream
Definition: proxy.cpp:13
static HRESULT WINAPI ItemMonikerImpl_RelativePathTo(IMoniker *iface, IMoniker *pmOther, IMoniker **ppmkRelPath)
Definition: itemmoniker.c:665
HRESULT WINAPI CreateAntiMoniker(IMoniker **ppmk)
Definition: antimoniker.c:608
REFCLSID clsid
Definition: msctf.c:82
#define InterlockedDecrement
Definition: armddk.h:52
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
GLenum GLsizei len
Definition: glext.h:6722
REFIID LPVOID * ppvObject
Definition: precomp.h:44
#define CLASS_E_NOAGGREGATION
Definition: winerror.h:2662
unsigned char BYTE
Definition: xxhash.c:193
_Check_return_ _CRTIMP int __cdecl wcscmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
static HRESULT WINAPI ItemMonikerImpl_IsRunning(IMoniker *iface, IBindCtx *pbc, IMoniker *pmkToLeft, IMoniker *pmkNewlyRunning)
Definition: itemmoniker.c:526
#define S_OK
Definition: intsafe.h:51
#define MK_S_US
Definition: winerror.h:2776
#define InterlockedIncrement
Definition: armddk.h:53
#define lstrcpyW
Definition: compat.h:497
static HRESULT WINAPI ItemMonikerROTDataImpl_QueryInterface(IROTData *iface, REFIID riid, void **ppvObject)
Definition: itemmoniker.c:771
static HRESULT WINAPI ItemMonikerROTDataImpl_GetComparisonData(IROTData *iface, BYTE *pbData, ULONG cbMax, ULONG *pcbData)
Definition: itemmoniker.c:809
IUnknown * pMarshal
Definition: itemmoniker.c:46
#define HeapReAlloc
Definition: compat.h:482
HRESULT MonikerMarshal_Create(IMoniker *inner, IUnknown **outer)
Definition: moniker.c:1677
static const IROTDataVtbl VT_ROTDataImpl
Definition: itemmoniker.c:871
static HRESULT WINAPI ItemMonikerImpl_GetClassID(IMoniker *iface, CLSID *pClassID)
Definition: itemmoniker.c:133
static HRESULT WINAPI ItemMonikerImpl_Enum(IMoniker *iface, BOOL fForward, IEnumMoniker **ppenumMoniker)
Definition: itemmoniker.c:453
static HRESULT WINAPI ItemMonikerImpl_Inverse(IMoniker *iface, IMoniker **ppmk)
Definition: itemmoniker.c:625
static HRESULT WINAPI ItemMonikerImpl_IsSystemMoniker(IMoniker *iface, DWORD *pwdMksys)
Definition: itemmoniker.c:756
#define MultiByteToWideChar
Definition: compat.h:110
static HRESULT WINAPI ItemMonikerImpl_IsEqual(IMoniker *iface, IMoniker *pmkOtherMoniker)
Definition: itemmoniker.c:468
GLuint res
Definition: glext.h:9613
static HRESULT WINAPI ItemMonikerImpl_Save(IMoniker *iface, IStream *pStm, BOOL fClearDirty)
Definition: itemmoniker.c:230
unsigned int ULONG
Definition: retypes.h:1
struct ItemMonikerImpl ItemMonikerImpl
#define MK_E_SYNTAX
Definition: winerror.h:2785
LPWSTR WINAPI lstrcatW(LPWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:274
#define towupper(c)
Definition: wctype.h:99
HRESULT WINAPI CreateGenericComposite(IMoniker *pmkFirst, IMoniker *pmkRest, IMoniker **ppmkComposite)
static HRESULT WINAPI ItemMonikerImpl_CommonPrefixWith(IMoniker *iface, IMoniker *pmkOther, IMoniker **ppmkPrefix)
Definition: itemmoniker.c:638
WCHAR * LPWSTR
Definition: xmlstorage.h:184
HRESULT WINAPI ItemMoniker_CreateInstance(IClassFactory *iface, IUnknown *pUnk, REFIID riid, void **ppv)
Definition: itemmoniker.c:958
#define E_POINTER
Definition: winerror.h:2365
static HRESULT WINAPI ItemMonikerImpl_Load(IMoniker *iface, IStream *pStm)
Definition: itemmoniker.c:162
#define IsEqualCLSID(rclsid1, rclsid2)
Definition: guiddef.h:96
static HRESULT WINAPI ItemMonikerImpl_Hash(IMoniker *iface, DWORD *pdwHash)
Definition: itemmoniker.c:501
static void *static void *static LPDIRECTPLAY IUnknown * pUnk
Definition: dplayx.c:30
LPVOID WINAPI CoTaskMemAlloc(SIZE_T size)
Definition: ifs.c:426
#define HeapFree(x, y, z)
Definition: compat.h:483
#define IsEqualIID(riid1, riid2)
Definition: guiddef.h:95
#define SUCCEEDED(hr)
Definition: intsafe.h:49
static HRESULT WINAPI ItemMonikerImpl_BindToObject(IMoniker *iface, IBindCtx *pbc, IMoniker *pmkToLeft, REFIID riid, VOID **ppvResult)
Definition: itemmoniker.c:290
_In_ DWORD _Out_writes_bytes_to_opt_ pcbData void _Inout_ DWORD * pcbData
Definition: wincrypt.h:4949
off
Definition: i386-dis.c:3909
_In_ HCRYPTHASH _In_ BOOL _In_ DWORD _Inout_updates_bytes_to_ pdwDataLen BYTE * pbData
Definition: wincrypt.h:4201