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